From 413eeb0b04fd8fb2192479aea866296340cda64c Mon Sep 17 00:00:00 2001 From: Bhadram Varka Date: Mon, 13 Feb 2023 19:42:06 +0530 Subject: [PATCH 001/458] Delete nvethernetrm to move the history from dev-main to rel-35 Bug 3918941 Change-Id: Iddf8b0f6d343490407dfafc8914dca01b4b84b4b --- Makefile.umbrella.tmk | 34 - docs/license.txt | 19 - include/ivc_core.h | 199 - include/mmc.h | 634 --- include/osi_common.h | 328 -- include/osi_core.h | 2871 ------------ include/osi_dma.h | 1550 ------- include/osi_dma_txrx.h | 59 - include/osi_macsec.h | 818 ---- osi/common/common.h | 351 -- osi/common/eqos_common.c | 73 - osi/common/eqos_common.h | 83 - osi/common/include/local_common.h | 105 - osi/common/mgbe_common.c | 85 - osi/common/mgbe_common.h | 43 - osi/common/osi_common.c | 76 - osi/common/type.h | 70 - osi/core/Makefile.interface.tmk | 38 - osi/core/Makefile.tmk | 75 - osi/core/core_common.c | 228 - osi/core/core_common.h | 61 - osi/core/core_local.h | 484 -- osi/core/debug.c | 148 - osi/core/debug.h | 34 - osi/core/eqos_core.c | 6936 ---------------------------- osi/core/eqos_core.h | 1128 ----- osi/core/eqos_mmc.c | 403 -- osi/core/eqos_mmc.h | 126 - osi/core/frp.c | 836 ---- osi/core/frp.h | 84 - osi/core/ivc_core.c | 689 --- osi/core/libnvethernetrm.export | 49 - osi/core/macsec.c | 5883 ------------------------ osi/core/macsec.h | 446 -- osi/core/mgbe_core.c | 6284 ------------------------- osi/core/mgbe_core.h | 1146 ----- osi/core/mgbe_mmc.c | 559 --- osi/core/mgbe_mmc.h | 236 - osi/core/osi_core.c | 306 -- osi/core/osi_hal.c | 2096 --------- osi/core/vlan_filter.c | 474 -- osi/core/vlan_filter.h | 76 - osi/core/xpcs.c | 638 --- osi/core/xpcs.h | 203 - osi/dma/Makefile.interface.tmk | 39 - osi/dma/Makefile.tmk | 61 - osi/dma/debug.c | 256 -- osi/dma/debug.h | 50 - osi/dma/dma_local.h | 272 -- osi/dma/eqos_desc.c | 245 - osi/dma/eqos_dma.c | 988 ---- osi/dma/eqos_dma.h | 200 - osi/dma/hw_common.h | 36 - osi/dma/hw_desc.h | 145 - osi/dma/libnvethernetcl.export | 42 - osi/dma/mgbe_desc.c | 230 - osi/dma/mgbe_desc.h | 37 - osi/dma/mgbe_dma.c | 743 --- osi/dma/mgbe_dma.h | 165 - osi/dma/osi_dma.c | 922 ---- osi/dma/osi_dma_txrx.c | 1395 ------ scripts/checkpatch.pl | 7101 ----------------------------- scripts/const_structs.checkpatch | 68 - scripts/spelling.txt | 1536 ------- 64 files changed, 51595 deletions(-) delete mode 100644 Makefile.umbrella.tmk delete mode 100644 docs/license.txt delete mode 100644 include/ivc_core.h delete mode 100644 include/mmc.h delete mode 100644 include/osi_common.h delete mode 100644 include/osi_core.h delete mode 100644 include/osi_dma.h delete mode 100644 include/osi_dma_txrx.h delete mode 100644 include/osi_macsec.h delete mode 100644 osi/common/common.h delete mode 100644 osi/common/eqos_common.c delete mode 100644 osi/common/eqos_common.h delete mode 100644 osi/common/include/local_common.h delete mode 100644 osi/common/mgbe_common.c delete mode 100644 osi/common/mgbe_common.h delete mode 100644 osi/common/osi_common.c delete mode 100644 osi/common/type.h delete mode 100644 osi/core/Makefile.interface.tmk delete mode 100644 osi/core/Makefile.tmk delete mode 100644 osi/core/core_common.c delete mode 100644 osi/core/core_common.h delete mode 100644 osi/core/core_local.h delete mode 100644 osi/core/debug.c delete mode 100644 osi/core/debug.h delete mode 100644 osi/core/eqos_core.c delete mode 100644 osi/core/eqos_core.h delete mode 100644 osi/core/eqos_mmc.c delete mode 100644 osi/core/eqos_mmc.h delete mode 100644 osi/core/frp.c delete mode 100644 osi/core/frp.h delete mode 100644 osi/core/ivc_core.c delete mode 100644 osi/core/libnvethernetrm.export delete mode 100644 osi/core/macsec.c delete mode 100644 osi/core/macsec.h delete mode 100644 osi/core/mgbe_core.c delete mode 100644 osi/core/mgbe_core.h delete mode 100644 osi/core/mgbe_mmc.c delete mode 100644 osi/core/mgbe_mmc.h delete mode 100644 osi/core/osi_core.c delete mode 100644 osi/core/osi_hal.c delete mode 100644 osi/core/vlan_filter.c delete mode 100644 osi/core/vlan_filter.h delete mode 100644 osi/core/xpcs.c delete mode 100644 osi/core/xpcs.h delete mode 100644 osi/dma/Makefile.interface.tmk delete mode 100644 osi/dma/Makefile.tmk delete mode 100644 osi/dma/debug.c delete mode 100644 osi/dma/debug.h delete mode 100644 osi/dma/dma_local.h delete mode 100644 osi/dma/eqos_desc.c delete mode 100644 osi/dma/eqos_dma.c delete mode 100644 osi/dma/eqos_dma.h delete mode 100644 osi/dma/hw_common.h delete mode 100644 osi/dma/hw_desc.h delete mode 100644 osi/dma/libnvethernetcl.export delete mode 100644 osi/dma/mgbe_desc.c delete mode 100644 osi/dma/mgbe_desc.h delete mode 100644 osi/dma/mgbe_dma.c delete mode 100644 osi/dma/mgbe_dma.h delete mode 100644 osi/dma/osi_dma.c delete mode 100644 osi/dma/osi_dma_txrx.c delete mode 100755 scripts/checkpatch.pl delete mode 100644 scripts/const_structs.checkpatch delete mode 100644 scripts/spelling.txt 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 From 304e5a0e9919dfef8477694875e72e2c39d43827 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Sat, 2 Feb 2019 21:51:39 +0530 Subject: [PATCH 002/458] nvethernetrm: osi code for EQOS Bug 200507585 Change-Id: I70ce3d013eeb109ebf323e732820fb51c360e313 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> --- include/osd.h | 36 ++ include/osi_common.h | 364 +++++++++++++++++++ include/osi_core.h | 323 ++++++++++++++++ include/osi_dma.h | 436 ++++++++++++++++++++++ include/osi_dma_txrx.h | 55 +++ osi/eqos_core.c | 808 +++++++++++++++++++++++++++++++++++++++++ osi/eqos_core.h | 129 +++++++ osi/eqos_dma.c | 433 ++++++++++++++++++++++ osi/eqos_dma.h | 72 ++++ osi/osi_common.c | 118 ++++++ osi/osi_core.c | 227 ++++++++++++ osi/osi_dma.c | 81 +++++ osi/osi_dma_txrx.c | 332 +++++++++++++++++ 13 files changed, 3414 insertions(+) create mode 100644 include/osd.h create mode 100644 include/osi_common.h create mode 100644 include/osi_core.h create mode 100644 include/osi_dma.h create mode 100644 include/osi_dma_txrx.h create mode 100644 osi/eqos_core.c create mode 100644 osi/eqos_core.h create mode 100644 osi/eqos_dma.c create mode 100644 osi/eqos_dma.h create mode 100644 osi/osi_common.c create mode 100644 osi/osi_core.c create mode 100644 osi/osi_dma.c create mode 100644 osi/osi_dma_txrx.c diff --git a/include/osd.h b/include/osd.h new file mode 100644 index 0000000..e4de417 --- /dev/null +++ b/include/osd.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef OSD_H +#define OSD_H + +void osd_usleep_range(unsigned long umin, unsigned long umax); +void osd_msleep(unsigned int msec); +void osd_udelay(unsigned long usec); +void osd_info(void *priv, const char *fmt, ...); +void osd_err(void *priv, const char *fmt, ...); +void osd_receive_packet(void *priv, void *rx_ring, + unsigned int chan, unsigned int dma_buf_len, + unsigned int rx_pkt_len); +void osd_transmit_complete(void *priv, void *buffer, unsigned long dmaaddr, + unsigned int len); +#endif diff --git a/include/osi_common.h b/include/osi_common.h new file mode 100644 index 0000000..9773de6 --- /dev/null +++ b/include/osi_common.h @@ -0,0 +1,364 @@ +/* + * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef OSI_COMMON_H +#define OSI_COMMON_H + +#define EQOS_DMA_CHX_STATUS(x) ((0x0080U * (x)) + 0x1160U) +#define EQOS_DMA_CHX_IER(x) ((0x0080U * (x)) + 0x1134U) + +#define MAC_VERSION 0x110 +#define MAC_VERSION_SNVER_MASK 0x7FU + +#define OSI_MAC_HW_EQOS 0U +#define OSI_ETH_ALEN 6U + +#define OSI_NULL ((void *)0) + +#define OSI_EQOS_MAX_NUM_CHANS 4U + +#define OSI_BIT(nr) ((unsigned int)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_SPEED_10 10 +#define OSI_SPEED_100 100 +#define OSI_SPEED_1000 1000 + +#define OSI_FULL_DUPLEX 1 +#define OSI_HALF_DUPLEX 0 + +#define NV_ETH_FRAME_LEN 1514U +#define NV_ETH_FCS_LEN 0x4U +#define NV_VLAN_HLEN 0x4U + +#define MAX_ETH_FRAME_LEN_DEFAULT \ + (NV_ETH_FRAME_LEN + NV_ETH_FCS_LEN + NV_VLAN_HLEN) + +#define L32(data) ((data) & 0xFFFFFFFFUL) +#define H32(data) (((data) & 0xFFFFFFFF00000000UL) >> 32UL) + +#define OSI_INVALID_CHAN_NUM 0xFFU + +#define TX_DESC_CNT 256U +#define RX_DESC_CNT 256U + +#define EQOS_MAC_HFR0 0x11c +#define EQOS_MAC_HFR1 0x120 +#define EQOS_MAC_HFR2 0x124 + +#define EQOS_MAC_HFR0_MIISEL_MASK 0x1U +#define EQOS_MAC_HFR0_GMIISEL_MASK 0x1U +#define EQOS_MAC_HFR0_HDSEL_MASK 0x1U +#define EQOS_MAC_HFR0_PCSSEL_MASK 0x1U +#define EQOS_MAC_HFR0_SMASEL_MASK 0x1U +#define EQOS_MAC_HFR0_RWKSEL_MASK 0x1U +#define EQOS_MAC_HFR0_MGKSEL_MASK 0x1U +#define EQOS_MAC_HFR0_MMCSEL_MASK 0x1U +#define EQOS_MAC_HFR0_ARPOFFLDEN_MASK 0x1U +#define EQOS_MAC_HFR0_TSSSEL_MASK 0x1U +#define EQOS_MAC_HFR0_EEESEL_MASK 0x1U +#define EQOS_MAC_HFR0_TXCOESEL_MASK 0x1U +#define EQOS_MAC_HFR0_RXCOE_MASK 0x1U +#define EQOS_MAC_HFR0_ADDMACADRSEL_MASK 0x1fU +#define EQOS_MAC_HFR0_MACADR32SEL_MASK 0x1U +#define EQOS_MAC_HFR0_MACADR64SEL_MASK 0x1U +#define EQOS_MAC_HFR0_TSINTSEL_MASK 0x3U +#define EQOS_MAC_HFR0_SAVLANINS_MASK 0x1U +#define EQOS_MAC_HFR0_ACTPHYSEL_MASK 0x7U +#define EQOS_MAC_HFR1_RXFIFOSIZE_MASK 0x1fU +#define EQOS_MAC_HFR1_TXFIFOSIZE_MASK 0x1fU +#define EQOS_MAC_HFR1_ADVTHWORD_MASK 0x1U +#define EQOS_MAC_HFR1_DCBEN_MASK 0x1U +#define EQOS_MAC_HFR1_SPHEN_MASK 0x1U +#define EQOS_MAC_HFR1_TSOEN_MASK 0x1U +#define EQOS_MAC_HFR1_DMADEBUGEN_MASK 0x1U +#define EQOS_MAC_HFR1_AVSEL_MASK 0x1U +#define EQOS_MAC_HFR1_LPMODEEN_MASK 0x1U +#define EQOS_MAC_HFR1_HASHTBLSZ_MASK 0x3U +#define EQOS_MAC_HFR1_L3L4FILTERNUM_MASK 0xfU +#define EQOS_MAC_HFR2_RXQCNT_MASK 0xfU +#define EQOS_MAC_HFR2_TXQCNT_MASK 0xfU +#define EQOS_MAC_HFR2_RXCHCNT_MASK 0xfU +#define EQOS_MAC_HFR2_TXCHCNT_MASK 0xfU +#define EQOS_MAC_HFR2_PPSOUTNUM_MASK 0x7U +#define EQOS_MAC_HFR2_AUXSNAPNUM_MASK 0x7U + +/** + * struct osi_hw_features - MAC HW supported features. + * @mii_sel: It sets to 1 when 10/100 Mbps is selected as the Mode of + * Operation + * @gmii_sel: It sets to 1 when 1000 Mbps is selected as the Mode of + * Operation. + * @hd_sel: It sets to 1 when the half-duplex mode is selected. + * @pcs_sel: It sets to 1 when the TBI, SGMII, or RTBI PHY interface + * option is selected. + * @vlan_hash_en: It sets to 1 when the Enable VLAN Hash Table Based + * Filtering option is selected. + * @sma_sel: It sets to 1 when the Enable Station Management + * (MDIO Interface) option is selected. + * @rwk_sel: It sets to 1 when the Enable Remote Wake-Up Packet Detection + * option is selected. + * @mgk_sel: It sets to 1 when the Enable Magic Packet Detection option is + * selected. + * @mmc_sel: It sets to 1 when the Enable MAC Management Counters (MMC) + * option is selected. + * @arp_offld_en: It sets to 1 when the Enable IPv4 ARP Offload option is + * selected. + * @ts_sel: It sets to 1 when the Enable IEEE 1588 Timestamp Support + * option is selected. + * @eee_sel: It sets to 1 when the Enable Energy Efficient Ethernet (EEE) + * option is selected. + * @tx_coe_sel: It sets to 1 when the Enable Transmit TCP/IP Checksum + * Insertion option is selected. + * @rx_coe_sel: It sets to 1 when the Enable Receive TCP/IP Checksum Check + * option is selected. + * @mac_addr16_sel: It sets to 1 when the Enable Additional 1-31 MAC + * Address Registers option is selected. + * @mac_addr32_sel: It sets to 1 when the Enable Additional 32 MAC + * Address Registers (32-63) option is selected + * @mac_addr64_sel: It sets to 1 when the Enable Additional 64 MAC + * Address Registers (64-127) option is selected. + * @tsstssel: It sets to 1 when the Enable IEEE 1588 Timestamp Support + * option is selected. + * @sa_vlan_ins: It sets to 1 when the Enable SA and VLAN Insertion on Tx + * option is selected. + * @act_phy_sel: 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. + * @rx_fifo_size: 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. + * @tx_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. + * @adv_ts_hword: It set to 1 when Advance timestamping High Word selected. + * @dcb_en: It sets to 1 when DCB Feature Enable. + * @sph_en: It sets to 1 when Split Header Feature Enable. + * @tso_en: It sets to 1 when TCP Segmentation Offload Enable. + * @dma_debug_gen: It seys to 1 when DMA debug registers are enabled. + * @av_sel: It sets to 1 AV Feature Enabled. + * @hash_tbl_sz: This field indicates the size of the hash table: + * 00: No hash table + * 01: 64 + * 10: 128 + * 11: 256. + * @l3l4_filter_num: 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. + * @rx_q_cnt: It holds number of MTL Receive Queues. + * @tx_q_cnt: It holds number of MTL Transmit Queues. + * @rx_ch_cnt: It holds number of DMA Receive channels. + * @tx_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. + * @pps_out_num: 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 + * @aux_snap_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 + */ +struct osi_hw_features { + /* HW Feature Register0 */ + unsigned int mii_sel; + unsigned int gmii_sel; + unsigned int hd_sel; + unsigned int pcs_sel; + unsigned int vlan_hash_en; + unsigned int sma_sel; + unsigned int rwk_sel; + unsigned int mgk_sel; + unsigned int mmc_sel; + unsigned int arp_offld_en; + unsigned int ts_sel; + unsigned int eee_sel; + unsigned int tx_coe_sel; + unsigned int rx_coe_sel; + unsigned int mac_addr16_sel; + unsigned int mac_addr32_sel; + unsigned int mac_addr64_sel; + unsigned int tsstssel; + unsigned int sa_vlan_ins; + unsigned int act_phy_sel; + /* HW Feature Register1 */ + unsigned int rx_fifo_size; + unsigned int tx_fifo_size; + unsigned int adv_ts_hword; + unsigned int dcb_en; + unsigned int sph_en; + unsigned int tso_en; + unsigned int dma_debug_gen; + unsigned int av_sel; + unsigned int hash_tbl_sz; + unsigned int l3l4_filter_num; + /* HW Feature Register2 */ + unsigned int rx_q_cnt; + unsigned int tx_q_cnt; + unsigned int rx_ch_cnt; + unsigned int tx_ch_cnt; + unsigned int pps_out_num; + unsigned int aux_snap_num; +}; + +/** + * osi_readl - Read a memory mapped regsiter. + * @addr: Memory mapped address. + * + * Algorithm: None. + * + * Dependencies: Physical address has to be memmory mapped. + * + * Protection: None. + * + * Return: Data from memory mapped register - success. + */ +static inline unsigned int osi_readl(void *addr) +{ + return *(volatile unsigned int *)addr; +} + +/** + * osi_writel - Write to a memory mapped regsiter. + * @val: Value to be written. + * @addr: Memory mapped address. + * + * Algorithm: None. + * + * Dependencies: Physical address has to be memmory mapped. + * + * Protection: None. + * + * Return: None. + */ +static inline void osi_writel(unsigned int val, void *addr) +{ + *(volatile unsigned int *)addr = val; +} + +/** + * is_valid_mac_version - Check if read MAC IP is valid or not. + * @mac_ver: MAC version read. + * + * Algorithm: None. + * + * Dependencies: MAC has to be out of reset. + * + * Protection: None. + * + * Return: 0 - for not Valid MAC, 1 - for Valid MAC + */ +static int is_valid_mac_version(unsigned int mac_ver) +{ + if ((mac_ver == OSI_EQOS_MAC_4_10) || + (mac_ver == OSI_EQOS_MAC_5_00) || + (mac_ver == OSI_EQOS_MAC_5_10)) { + return 1; + } + + return 0; +} + +/** + * osi_get_mac_version - Reading MAC version + * @addr: io-remap MAC base address. + * @mac_ver: holds mac version. + * + * Algorithm: Reads MAC version and check whether its valid or not. + * + * Dependencies: MAC has to be out of reset. + * + * Protection: None + * + * Return: 0 - success, -1 - failure + */ +static inline int osi_get_mac_version(void *addr, unsigned int *mac_ver) +{ + unsigned int macver; + int ret = 0; + + macver = osi_readl((unsigned char *)addr + MAC_VERSION) & MAC_VERSION_SNVER_MASK; + if (is_valid_mac_version(macver) == 0) { + return -1; + } + + *mac_ver = macver; + return ret; +} + +void osi_get_hw_features(void *base, struct osi_hw_features *hw_feat); +#endif /* OSI_COMMON_H */ diff --git a/include/osi_core.h b/include/osi_core.h new file mode 100644 index 0000000..65eaffb --- /dev/null +++ b/include/osi_core.h @@ -0,0 +1,323 @@ +/* + * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef OSI_CORE_H +#define OSI_CORE_H + +#include "osi_common.h" + +struct osi_core_priv_data; + +/** + * struct osi_core_ops - Core (MAC & MTL) operations. + * @poll_for_swr: Called to poll for software reset bit. + * @core_init: Called to initialize MAC and MTL registers. + * @start_mac: Called to start MAC Tx and Rx engine. + * @stop_mac: Called to stop MAC Tx and Rx engine. + * @handle_common_intr: Called to handle common interrupt. + * @set_mode: Called to set the mode at MAC (full/duplex). + * @set_speed: Called to set the speed (10/100/1000) at MAC. + * @pad_calibrate: Called to do pad caliberation. + * @set_mdc_clk_rate: Called to set MDC clock rate for MDIO operation. + * @flush_mtl_tx_queue: Called to flush MTL Tx queue. + */ +struct osi_core_ops { + /* initialize MAC/MTL/DMA Common registers */ + int (*poll_for_swr)(void *ioaddr); + int (*core_init)(struct osi_core_priv_data *osi_core, + unsigned int tx_fifo_size, + unsigned int rx_fifo_size); + void (*start_mac)(void *addr); + void (*stop_mac)(void *addr); + void (*handle_common_intr)(struct osi_core_priv_data *osi_core); + void (*set_mode)(void *ioaddr, int mode); + void (*set_speed)(void *ioaddr, int speed); + int (*pad_calibrate)(void *ioaddr); + void (*set_mdc_clk_rate)(struct osi_core_priv_data *osi_core, + unsigned long csr_clk_rate); + int (*flush_mtl_tx_queue)(void *ioaddr, unsigned int qinx); +}; + +/** + * struct osi_core_priv_data - The OSI Core (MAC & MTL) private data + structure. + * @base: Memory mapped base address of MAC IP. + * @osd: Pointer to OSD private data structure. + * @ops: Address of HW Core operations structure. + * @num_mtl_queues: Number of MTL queues enabled in MAC. + * @mtl_queues: Array of MTL queues. + * @rxq_ctrl: List of MTL Rx queue mode that need to be enabled + * @mac: MAC HW type EQOS based on DT compatible. + * @mac_ver: MAC version. + * @mdc_cr: MDC clock rate. + * @mac_addr: Ethernet MAC address. + */ +struct osi_core_priv_data { + void *base; + void *osd; + struct osi_core_ops *ops; + unsigned int num_mtl_queues; + unsigned int mtl_queues[OSI_EQOS_MAX_NUM_CHANS]; + unsigned int rxq_ctrl[OSI_EQOS_MAX_NUM_CHANS]; + unsigned int mac; + unsigned int mac_ver; + unsigned int mdc_cr; + unsigned char mac_addr[OSI_ETH_ALEN]; +}; + +/** + * osi_poll_for_swr - Poll Software reset bit in MAC HW + * @osi: OSI Core private data structure. + * + * Algorithm: Invokes EQOS routine to check for SWR (software reset) + * bit in DMA Basic mooe register to make sure IP reset was successful. + * + * Dependencies: MAC needs to be reset with Soft or hardreset. + * + * Protection: None + * + * Return: 0 - success, -1 - failure + */ + +static inline int osi_poll_for_swr(struct osi_core_priv_data *osi_core) +{ + int ret = 0; + + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->poll_for_swr != OSI_NULL)) { + ret = osi_core->ops->poll_for_swr(osi_core->base); + } + + return ret; +} + +/** + * osi_set_mdc_clk_rate - Derive MDC clock based on provided AXI_CBB clk. + * @osi: OSI core private data structure. + * @csr_clk_rate: CSR (AXI CBB) clock rate. + * + * Algorithm: MDC clock rate will be populated in OSI core private data + * structure based on AXI_CBB clock rate. + * + * Dependencies: OSD layer needs get the AXI CBB clock rate with OSD clock + * API (ex - clk_get_rate()) + * + * Return: None + */ +static inline void osi_set_mdc_clk_rate(struct osi_core_priv_data *osi_core, + unsigned long csr_clk_rate) +{ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->set_mdc_clk_rate != OSI_NULL)) { + osi_core->ops->set_mdc_clk_rate(osi_core, csr_clk_rate); + } +} + +/** + * osi_hw_core_init - EQOS MAC, MTL and common DMA initialization. + * @osi: OSI core private data structure. + * + * Algorithm: Invokes EQOS MAC, MTL and common DMA register init code. + * + * Dependencies: MAC has to be out of reset. + * + * Protection: None + * + * Return: 0 - success, -1 - failure + */ +static inline int osi_hw_core_init(struct osi_core_priv_data *osi_core, + unsigned int tx_fifo_size, + unsigned int rx_fifo_size) +{ + int ret = 0; + + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->core_init != OSI_NULL)) { + ret = osi_core->ops->core_init(osi_core, tx_fifo_size, + rx_fifo_size); + } + + return ret; +} + +/** + * osi_start_mac - Start MAC Tx/Rx engine + * @osi_core: OSI core private data. + * + * Algorimthm: Enable MAC Tx and Rx engine. + * Dependencies: None + * Protection: None + * Return: None + */ +static inline void osi_start_mac(struct osi_core_priv_data *osi_core) +{ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->start_mac != OSI_NULL)) { + osi_core->ops->start_mac(osi_core->base); + } +} + +/** + * osi_stop_mac - Stop MAC Tx/Rx engine + * @osi_core: OSI core private data. + * + * Algorimthm: Stop MAC Tx and Rx engine + * Dependencies: None + * Protection: None + * Return: None + */ +static inline void osi_stop_mac(struct osi_core_priv_data *osi_core) +{ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->stop_mac != OSI_NULL)) { + osi_core->ops->stop_mac(osi_core->base); + } +} + +/** + * osi_common_isr - Common ISR. + * @osi_core: OSI core private data structure. + * + * Algorithm: Takes care of handling the + * common interrupts accordingly as per the + * MAC IP + * + * Dependencies: MAC IP should be out of reset + * and need to be initialized as the requirements + * + * Protection: None + * + * Return: 0 - success, -1 - failure + */ +static inline void osi_common_isr(struct osi_core_priv_data *osi_core) +{ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->handle_common_intr != OSI_NULL)) { + osi_core->ops->handle_common_intr(osi_core); + } +} + +/** + * osi_set_mode - Set FD/HD mode. + * @osi: OSI private data structure. + * @mode: Operating mode. + * + * Algorithm: Takes care of setting HD or FD mode + * accordingly as per the MAC IP. + * + * Dependencies: MAC IP should be out of reset + * and need to be initialized as the requirements + * + * Protection: None + * + * Return: NONE + */ +static inline void osi_set_mode(struct osi_core_priv_data *osi_core, int mode) +{ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->set_mode != OSI_NULL)) { + osi_core->ops->set_mode(osi_core->base, mode); + } +} + +/** + * osi_set_speed - Set operating speed. + * @osi: OSI private data structure. + * @speed: Operating speed. + * + * Algorithm: Takes care of setting the operating + * speed accordingly as per the MAC IP. + * + * Dependencies: MAC IP should be out of reset + * and need to be initialized as the requirements + * + * Protection: None + * + * Return: NONE + */ +static inline void osi_set_speed(struct osi_core_priv_data *osi_core, int speed) +{ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->set_speed != OSI_NULL)) { + osi_core->ops->set_speed(osi_core->base, speed); + } +} + +/** + * osi_pad_calibrate - PAD calibration + * @osi: OSI core private data structure. + * + * Algorithm: Takes care of doing the pad calibration + * accordingly as per the MAC IP. + * + * Dependencies: RGMII and MDIO interface needs to be IDLE + * before performing PAD calibration. + * + * Protection: None + * + * Return: 0 - success, -1 - failure + */ +static inline int osi_pad_calibrate(struct osi_core_priv_data *osi_core) +{ + int ret = 0; + + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->pad_calibrate != OSI_NULL)) { + ret = osi_core->ops->pad_calibrate(osi_core); + } + + return ret; +} + +/** + * osi_flush_mtl_tx_queue - Flushing a MTL Tx Queue. + * @osi_core: OSI private data structure. + * @qinx: MTL queue index. + * + * Algorithm: Invokes EQOS flush Tx queue routine. + * + * Dependencies: MAC IP should be out of reset + * and need to be initialized as the requirements + * + * Protection: None + * + * Return: 0 - success, -1 - failure. + */ +static inline int osi_flush_mtl_tx_queue(struct osi_core_priv_data *osi_core, + unsigned int qinx) +{ + int ret = 0; + + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->flush_mtl_tx_queue != OSI_NULL)) { + ret = osi_core->ops->flush_mtl_tx_queue(osi_core->base, qinx); + } + + return ret; +} + +int osi_write_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, + unsigned int phyreg, unsigned short phydata); +int osi_read_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, + unsigned int phyreg); +void osi_init_core_ops(struct osi_core_priv_data *osi_core); +#endif /* OSI_CORE_H */ diff --git a/include/osi_dma.h b/include/osi_dma.h new file mode 100644 index 0000000..8a7c0b2 --- /dev/null +++ b/include/osi_dma.h @@ -0,0 +1,436 @@ +/* + * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef OSI_DMA_H +#define OSI_DMA_H + +#include "osi_common.h" +#include "osi_dma_txrx.h" + +/** + * struct osi_rx_desc - Receive Descriptor + * @rdes0: Receive Descriptor 0 + * @rdes1: Receive Descriptor 1 + * @rdes2: Receive Descriptor 2 + * @rdes3: Receive Descriptor 3 + */ +struct osi_rx_desc { + unsigned int rdes0; + unsigned int rdes1; + unsigned int rdes2; + unsigned int rdes3; +}; + +/** + * struct osi_rx_swcx - Receive descriptor software context + * @buf_phy_addr: DMA buffer physical address + * @buf_virt_addr: DMA buffer virtual address + * @len: Length of buffer + */ +struct osi_rx_swcx { + unsigned long buf_phy_addr; + void *buf_virt_addr; + unsigned int len; +}; + +/** + * struct osi_rx_ring - DMA Rx channel ring + * @rx_desc: Pointer to Rx DMA descriptor + * @rx_swcx: Pointer to Rx DMA descriptor software context information + * @dma_rx_desc: Physical address of Rx DMA descriptor + * @cur_rx_idx: Descriptor index current reception. + * @refill_idx: Descriptor index for descriptor re-allocation. + */ +struct osi_rx_ring { + struct osi_rx_desc *rx_desc; + struct osi_rx_swcx *rx_swcx; + unsigned long rx_desc_phy_addr; + unsigned int cur_rx_idx; + unsigned int refill_idx; +}; + +/** + * struct osi_tx_swcx - Transmit descriptor software context + * @buf_phy_addr: Physical address of DMA mapped buffer. + * @buf_virt_addr: Virtual address of DMA buffer. + * @len: Length of buffer + */ +struct osi_tx_swcx { + unsigned long buf_phy_addr; + void *buf_virt_addr; + unsigned int len; +}; + +/** + * struct osi_tx_desc - Transmit descriptor + * @tdes0: Transmit descriptor 0 + * @tdes1: Transmit descriptor 1 + * @tdes2: Transmit descriptor 2 + * @tdes3: Transmit descriptor 3 + */ +struct osi_tx_desc { + unsigned int tdes0; + unsigned int tdes1; + unsigned int tdes2; + unsigned int tdes3; +}; + +/** + * struct osi_tx_ring - DMA channel Tx ring + * @tx_desc: Pointer to tx dma descriptor + * @tx_swcx: Pointer to tx dma descriptor software context information + * @tx_desc_phy_addr: Physical address of Tx descriptor. + * @cur_tx_idx: Descriptor index current transmission. + * @clean_idx: Descriptor index for descriptor cleanup. + */ +struct osi_tx_ring { + struct osi_tx_desc *tx_desc; + struct osi_tx_swcx *tx_swcx; + unsigned long tx_desc_phy_addr; + unsigned int cur_tx_idx; + unsigned int clean_idx; +}; + +struct osi_dma_priv_data; +/** + * struct osi_dma_chan_ops - MAC Hardware operations + * @set_tx_ring_len: Called to set Transmit Ring length. + * @set_tx_ring_start_addr: Called to set Transmit Ring Base address. + * @update_tx_tailptr: Called to update Tx Ring tail pointer. + * @set_rx_ring_len: Called to set Receive channel ring length. + * @set_rx_ring_start_addr: Called to set receive channel ring base address + * @update_rx_tailptr: Called to update Rx ring tail pointer. + * @clear_tx_intr: Invoked by OSD layer to clear Tx interrupt source. + * @clear_rx_intr: Invoked by OSD layer to clear Rx interrupt source. + * @disable_chan_tx_intr: Called to disable DMA tx channel interrupts at + * wrapper level. + * @enable_chan_tx_intr: Called to enable DMA tx channel interrupts at + * wrapper level. + * @disable_chan_rx_intr: Called to disable DMA Rx channel interrupts at + * wrapper level. + * @enable_chan_rx_intr: Called to enable DMA rx channel interrupts at + * wrapper level. + * @start_dma: Called to start the Tx/Rx DMA. + */ +struct osi_dma_chan_ops { + void (*set_tx_ring_len)(void *addr, unsigned int chan, + unsigned int len); + void (*set_tx_ring_start_addr)(void *addr, unsigned int chan, + unsigned long base_addr); + void (*update_tx_tailptr)(void *addr, unsigned int chan, + unsigned long tailptr); + void (*set_rx_ring_len)(void *addr, unsigned int chan, + unsigned int len); + void (*set_rx_ring_start_addr)(void *addr, unsigned int chan, + unsigned long base_addr); + void (*update_rx_tailptr)(void *addr, unsigned int chan, + unsigned long tailptr); + void (*clear_tx_intr)(void *addr, unsigned int chan); + void (*clear_rx_intr)(void *addr, unsigned int chan); + void (*disable_chan_tx_intr)(void *addr, unsigned int chan); + void (*enable_chan_tx_intr)(void *addr, unsigned int chan); + void (*disable_chan_rx_intr)(void *addr, unsigned int chan); + void (*enable_chan_rx_intr)(void *addr, unsigned int chan); + void (*start_dma)(void *addr, unsigned int chan); + void (*stop_dma)(void *addr, unsigned int chan); + void (*init_dma_channel) (struct osi_dma_priv_data *osi_dma); +}; + +/** + * struct osi_dma_priv_data - The OSI private data structure. + * @tx_ring: Array of pointers to DMA Tx channel Ring. + * @rx_ring: Array of pointers to DMA Rx channel Ring. + * @base: Memory mapped base address of MAC IP. + * @ops: Address of HW operations structure. + * @num_chans: Number of channels enabled in MAC. + * @mac: MAC HW type (EQOS). + * @osd: Pointer to OSD private data structure. + * @mdc_cr: MDC clock rate. + * @mac_addr: Ethernet MAC address. + * @phy_reset: PHY reset GPIO pin number. + * @chans: List of channels enabled in MAC. + * @rxq_ctrl: List if RxQs that need to be enabled + * @rx_buf_len: DMA Rx channel buffer length at HW level. + * @hw_feat: HW features associated with MAC. + */ +struct osi_dma_priv_data { + struct osi_tx_ring *tx_ring[OSI_EQOS_MAX_NUM_CHANS]; + struct osi_rx_ring *rx_ring[OSI_EQOS_MAX_NUM_CHANS]; + void *base; + void *osd; + struct osi_dma_chan_ops *ops; + unsigned int mac; + unsigned int num_dma_chans; + unsigned int dma_chans[OSI_EQOS_MAX_NUM_CHANS]; + unsigned int rx_buf_len; +}; + +/** + * osi_disable_chan_tx_intr - Disables DMA Tx channel interrupts. + * @osi_dma: DMA private data. + * @chan: DMA Tx channel number. + * + * Algorithm: Disables Tx interrupts at wrapper level. + * + * Dependencies: osi_dma_chan_ops needs to be assigned based on MAC. + * + * Protection: None. + * + * Return: None. + */ +static inline void osi_disable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, + unsigned int chan) +{ + if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && + (osi_dma->ops->disable_chan_tx_intr != OSI_NULL)) { + osi_dma->ops->disable_chan_tx_intr(osi_dma->base, chan); + } +} + +/** + * osi_enable_chan_tx_intr - Enable DMA Tx channel interrupts. + * @osi_dma: DMA private data. + * @chan: DMA Tx channel number. + * + * Algorithm: Enables Tx interrupts at wrapper level. + * + * Dependencies: osi_dma_chan_ops needs to be assigned based on MAC. + * + * Protection: None. + * + * Return: None. + */ +static inline void osi_enable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, + unsigned int chan) +{ + if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && + (osi_dma->ops->enable_chan_tx_intr != OSI_NULL)) { + osi_dma->ops->enable_chan_tx_intr(osi_dma->base, chan); + } +} + +/** + * osi_disable_chan_rx_intr - Disable DMA Rx channel interrupts. + * @osi_dma: DMA private data. + * @chan: DMA rx channel number. + * + * Algorithm: Disables Tx interrupts at wrapper level. + * + * Dependencies: osi_dma_chan_ops needs to be assigned based on MAC. + * + * Protection: None. + * + * Return: None. + */ +static inline void osi_disable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, + unsigned int chan) +{ + if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && + (osi_dma->ops->disable_chan_rx_intr != OSI_NULL)) { + osi_dma->ops->disable_chan_rx_intr(osi_dma->base, chan); + } +} + +/** + * osi_enable_chan_rx_intr - Enable DMA Rx channel interrupts. + * @osi_dma: DMA private data. + * @chan: DMA rx channel number. + * + * Algorithm: Enables Tx interrupts at wrapper level. + * + * Dependencies: osi_dma_chan_ops needs to be assigned based on MAC. + * + * Protection: None. + * + * Return: None. + */ +static inline void osi_enable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, + unsigned int chan) +{ + if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && + (osi_dma->ops->enable_chan_rx_intr != OSI_NULL)) { + osi_dma->ops->enable_chan_rx_intr(osi_dma->base, chan); + } +} + +/** + * osi_clear_tx_intr - Handles Tx interrupt source. + * @osi_dma: DMA private data. + * @chan: DMA tx channel number. + * + * Algorithm: Clear Tx interrupt source at wrapper level and DMA level. + * + * Dependencies: osi_dma_chan_ops needs to be assigned based on MAC. + * + * Protection: None. + * + * Return: None. + */ +static inline void osi_clear_tx_intr(struct osi_dma_priv_data *osi_dma, + unsigned int chan) +{ + if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && + (osi_dma->ops->clear_tx_intr != OSI_NULL)) { + osi_dma->ops->clear_tx_intr(osi_dma->base, chan); + } +} + +/** + * osi_clear_rx_intr - Handles Rx interrupt source. + * @osi_dma: DMA private data. + * @chan: DMA rx channel number. + * + * Algorithm: Clear Rx interrupt source at wrapper level and DMA level. + * + * Dependencies: osi_dma_chan_ops needs to be assigned based on MAC. + * + * Protection: None. + * + * Return: None. + */ +static inline void osi_clear_rx_intr(struct osi_dma_priv_data *osi_dma, + unsigned int chan) +{ + if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && + (osi_dma->ops->clear_rx_intr != OSI_NULL)) { + osi_dma->ops->clear_rx_intr(osi_dma->base, chan); + } +} + +/** + * osi_start_dma - Start DMA + * @osi_dma: DMA private data. + * @chan: DMA Tx/Rx channel number + * + * Algorimthm: Start the DMA for specific MAC + * Dependencies: None + * Protection: None + * Return: None + */ +static inline void osi_start_dma(struct osi_dma_priv_data *osi_dma, + unsigned int chan) +{ + if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && + (osi_dma->ops->start_dma != OSI_NULL)) { + osi_dma->ops->start_dma(osi_dma->base, chan); + } +} + +/** + * osi_stop_dma - Stop DMA + * @osi_dma: DMA private data. + * @chan: DMA Tx/Rx channel number + * + * Algorimthm: Stop the DMA for specific MAC + * Dependencies: None + * Protection: None + * Return: None + */ +static inline void osi_stop_dma(struct osi_dma_priv_data *osi_dma, + unsigned int chan) +{ + if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && + (osi_dma->ops->stop_dma != OSI_NULL)) { + osi_dma->ops->stop_dma(osi_dma->base, chan); + } +} + +/** + * osi_get_refill_rx_desc_cnt - Rx descriptors count that needs to refill. + * @rx_ring: DMA channel Rx ring. + * + * Algorithm: subtract current index with fill (need to cleanup) + * to get Rx descriptors count that needs to refill. + * + * Dependencies: None. + * + * Protection: None. + * + * Return: Number of available free descriptors. + */ +static inline unsigned int osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring) +{ + return (rx_ring->cur_rx_idx - rx_ring->refill_idx) & (RX_DESC_CNT - 1U); +} + +/** + * osi_rx_dma_desc_init - DMA Rx descriptor init + * @rx_swcx: OSI DMA Rx ring software context + * @rx_desc: OSI DMA Rx ring descriptor + * + * Algorithm: Initialise a Rx DMA descriptor. + * + * Dependencies: None. + * + * Protection: None. + * + * Return: None. + */ +static inline void osi_rx_dma_desc_init(struct osi_rx_swcx *rx_swcx, + struct osi_rx_desc *rx_desc) +{ + rx_desc->rdes0 = (unsigned int)L32(rx_swcx->buf_phy_addr); + rx_desc->rdes1 = (unsigned int)H32(rx_swcx->buf_phy_addr); + rx_desc->rdes2 = 0; + rx_desc->rdes3 = (RDES3_OWN | RDES3_IOC | RDES3_B1V); +} + +/** + * osi_update_rx_tailptr - Updates DMA Rx ring tail pointer + * @osi_dma: OSI DMA private data struture. + * @rx_ring: Pointer to DMA Rx ring. + * @chan: DMA channel number. + * + * Algorithm: Updates DMA Rx ring tail pointer. + * + * Dependencies: None. + * + * Protection: None. + * + * Return: None. + */ +static inline void osi_update_rx_tailptr(struct osi_dma_priv_data *osi_dma, + struct osi_rx_ring *rx_ring, + unsigned int chan) +{ + unsigned long tailptr = 0; + unsigned int refill_idx = rx_ring->refill_idx; + + DECR_RX_DESC_INDEX(refill_idx, 1U); + tailptr = rx_ring->rx_desc_phy_addr + + (refill_idx * sizeof(struct osi_rx_desc)); + + if (osi_dma->ops != OSI_NULL && + osi_dma->ops->update_rx_tailptr != OSI_NULL) { + osi_dma->ops->update_rx_tailptr(osi_dma->base, chan, tailptr); + } +} + +void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan); +int osi_process_tx_completions(struct osi_dma_priv_data *osi, + unsigned int chan); +int osi_process_rx_completions(struct osi_dma_priv_data *osi, + unsigned int chan, int budget); +int osi_hw_dma_init(struct osi_dma_priv_data *osi_dma); +void osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma); +void osi_init_dma_ops(struct osi_dma_priv_data *osi_dma); +#endif /* OSI_DMA_H */ diff --git a/include/osi_dma_txrx.h b/include/osi_dma_txrx.h new file mode 100644 index 0000000..2833856 --- /dev/null +++ b/include/osi_dma_txrx.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef OSI_DMA_TXRX_H +#define OSI_DMA_TXRX_H + +#define TX_DESC_CNT 256U +#define RX_DESC_CNT 256U + +#define INCR_TX_DESC_INDEX(idx, i) ((idx) = ((idx) + (i)) & (TX_DESC_CNT - 1U)) +#define INCR_RX_DESC_INDEX(idx, i) ((idx) = ((idx) + (i)) & (RX_DESC_CNT - 1U)) +#define DECR_RX_DESC_INDEX(idx, i) ((idx) = ((idx) - (i)) & (RX_DESC_CNT - 1U)) + +#define RDES3_OWN OSI_BIT(31) +#define RDES3_IOC OSI_BIT(30) +#define RDES3_B1V OSI_BIT(24) +#define RDES3_LD OSI_BIT(28) +#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_ES_BITS \ + (RDES3_ERR_CRC | RDES3_ERR_GP | RDES3_ERR_WD | \ + RDES3_ERR_ORUN | RDES3_ERR_RE | RDES3_ERR_DRIB) + +#define TDES2_IOC OSI_BIT(31) +#define TDES3_OWN OSI_BIT(31) +#define TDES3_CTX OSI_BIT(30) +#define TDES3_FD OSI_BIT(29) +#define TDES3_LD OSI_BIT(28) + +#endif /* OSI_DMA_TXRX_H */ diff --git a/osi/eqos_core.c b/osi/eqos_core.c new file mode 100644 index 0000000..fc03e8a --- /dev/null +++ b/osi/eqos_core.c @@ -0,0 +1,808 @@ +/* + * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <osi_common.h> +#include <osi_core.h> +#include <osd.h> +#include "eqos_core.h" + +struct osi_core_ops *eqos_get_hw_core_ops(void); + +/** + * eqos_poll_for_swr - Poll for software reset (SWR bit in DMA Mode) + * @addr: EQOS virtual base address. + * + * Algorithm: CAR reset will be issued through MAC reset pin. + * Waits for SWR reset to be cleared in DMA Mode register. + * + * Dependencies: None + * + * Protection: None + * + * Return: 0 - success, -1 - failure + */ +static int eqos_poll_for_swr(void *addr) +{ + unsigned int retry = 1000; + unsigned int count; + unsigned int dma_bmr = 0; + int cond = 1; + + /* add delay of 10 usec */ + osd_usleep_range(9, 11); + + /* Poll Until Poll Condition */ + count = 0; + while (cond == 1) { + if (count > retry) { + return -1; + } + + count++; + osd_msleep(1U); + + dma_bmr = osi_readl((unsigned char *)addr + EQOS_DMA_BMR); + + if ((dma_bmr & EQOS_DMA_BMR_SWR) == 0U) { + cond = 0; + } + } + + return 0; +} + +/** + * eqos_set_mdc_clk_rate - Derive MDC clock based on provided AXI_CBB clk. + * @osi_core: OSI core private data structure. + * @csr_clk_rate: CSR (AXI CBB) clock rate. + * + * Algorithm: MDC clock rate will be polulated OSI private data structure + * based on AXI_CBB clock rate. + * + * Dependencies: OSD layer needs get the AXI CBB clock rate with OSD clock + * API (ex - clk_get_rate()) + * + * Return: None + */ +static void eqos_set_mdc_clk_rate(struct osi_core_priv_data *osi_core, + unsigned long csr_clk_rate) +{ + unsigned int csr_clk_speed = (unsigned int)(csr_clk_rate / 1000000U); + + if (csr_clk_speed > 500U) { + osi_core->mdc_cr = EQOS_CSR_500_800M; + } else if (csr_clk_speed > 300U) { + osi_core->mdc_cr = EQOS_CSR_300_500M; + } else if (csr_clk_speed > 250U) { + osi_core->mdc_cr = EQOS_CSR_250_300M; + } else if (csr_clk_speed > 150U) { + osi_core->mdc_cr = EQOS_CSR_150_250M; + } else if (csr_clk_speed > 100U) { + osi_core->mdc_cr = EQOS_CSR_100_150M; + } else if (csr_clk_speed > 60U) { + osi_core->mdc_cr = EQOS_CSR_60_100M; + } else if (csr_clk_speed > 35U) { + osi_core->mdc_cr = EQOS_CSR_35_60M; + } else { + /* for CSR < 35mhz */ + osi_core->mdc_cr = EQOS_CSR_20_35M; + } +} + +/** + * eqos_set_speed - Set operating speed + * @base: EQOS virtual base address. + * @speed: Operating speed. + * + * Algorithm: Based on the speed (10/100/1000Mbps) MAC will be configured + * accordingly. + * + * Dependencies: MAC has to be out of reset. + * + * Protection: None + * + * Return: None + */ +static void eqos_set_speed(void *base, int speed) +{ + unsigned int mcr_val; + + mcr_val = osi_readl((unsigned char *)base + EQOS_MAC_MCR); + switch (speed) { + default: + 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; + } + + osi_writel(mcr_val, (unsigned char *)base + EQOS_MAC_MCR); +} + +/** + * eqos_set_mode - Set operating mode + * @base: EQOS virtual base address + * @mode: Operating mode. + * + * Algorithm: Based on the mode (HALF/FULL Duplex) MAC will be configured + * accordingly. + * + * Dependencies: MAC has to be out of reset. + * + * Protection: None + * + * Return: None + */ +static void eqos_set_mode(void *base, int mode) +{ + unsigned int mcr_val; + + mcr_val = osi_readl((unsigned char *)base + EQOS_MAC_MCR); + if (mode == OSI_FULL_DUPLEX) { + mcr_val |= (0x00002000U); + } else if (mode == OSI_HALF_DUPLEX) { + mcr_val &= ~(0x00002000U); + } else { + /* Nothing here */ + } + osi_writel(mcr_val, (unsigned char *)base + EQOS_MAC_MCR); +} + +/** + * eqos_calculate_per_queue_fifo - Calculate per queue FIFO size + * @fifo_size: Total Tx/RX HW FIFO size. + * @queue_count: Total number of Queues configured. + * + * Algorithm: Total Tx/Rx FIFO size which is read from + * MAC HW is being shared equally among the queues that are + * configured. + * + * Dependencies: MAC has to be out of reset. + * + * Protection: None + * + * Return: Queue size that need to be programmed + */ +static unsigned int eqos_calculate_per_queue_fifo(unsigned int fifo_size, + unsigned int queue_count) +{ + unsigned int q_fifo_size = 0; /* calculated fifo size per queue */ + unsigned int p_fifo = EQOS_256; /* per queue fifo size program value */ + + /* 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: + 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; +} + +/** + * eqos_pad_calibrate - PAD calibration + * @ioaddr: Base address of the MAC HW. + * + * Algorithm: + * 1) Set field PAD_E_INPUT_OR_E_PWRD in reg ETHER_QOS_SDMEMCOMPPADCTRL_0 + * 2) Delay for 1 usec. + * 3)Set AUTO_CAL_ENABLE and AUTO_CAL_START in reg + * ETHER_QOS_AUTO_CAL_CONFIG_0 + * 4) Wait on AUTO_CAL_ACTIVE until it is 0 + * 5) Re-program the value PAD_E_INPUT_OR_E_PWRD in + * ETHER_QOS_SDMEMCOMPPADCTRL_0 to save power + * + * Dependencies: RGMII and MDIO interface needs to be IDLE + * before performing PAD calibration. + * + * Protection: None + * + * Return: 0 - success, -1 - failure + */ +static int eqos_pad_calibrate(void *ioaddr) +{ + unsigned int retry = 1000; + unsigned int count; + int cond = 1; + unsigned int value; + + /* 1. Set field PAD_E_INPUT_OR_E_PWRD in + * reg ETHER_QOS_SDMEMCOMPPADCTRL_0 + */ + value = osi_readl((unsigned char *)ioaddr + EQOS_PAD_CRTL); + value |= EQOS_PAD_CRTL_E_INPUT_OR_E_PWRD; + osi_writel(value, (unsigned char *)ioaddr + EQOS_PAD_CRTL); + + /* 2. delay for 1 usec */ + osd_usleep_range(1, 3); + + /* 3. Set AUTO_CAL_ENABLE and AUTO_CAL_START in + * reg ETHER_QOS_AUTO_CAL_CONFIG_0. + */ + value = osi_readl((unsigned char *)ioaddr + EQOS_PAD_AUTO_CAL_CFG); + value |= EQOS_PAD_AUTO_CAL_CFG_START | + EQOS_PAD_AUTO_CAL_CFG_ENABLE; + osi_writel(value, (unsigned char *)ioaddr + EQOS_PAD_AUTO_CAL_CFG); + + /* 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 == 1) { + if (count > retry) { + return -1; + } + count++; + osd_usleep_range(10, 12); + value = osi_readl((unsigned char *)ioaddr + EQOS_PAD_AUTO_CAL_STAT); + /* calibration done when CAL_STAT_ACTIVE is zero */ + if ((value & EQOS_PAD_AUTO_CAL_STAT_ACTIVE) == 0U) { + cond = 0; + } + } + + /* 6. Re-program the value PAD_E_INPUT_OR_E_PWRD in + * ETHER_QOS_SDMEMCOMPPADCTRL_0 to save power + */ + value = osi_readl((unsigned char *)ioaddr + EQOS_PAD_CRTL); + value &= ~EQOS_PAD_CRTL_E_INPUT_OR_E_PWRD; + osi_writel(value, (unsigned char *)ioaddr + EQOS_PAD_CRTL); + + return 0; +} + +/** + * eqos_flush_mtl_tx_queue - Flush MTL Tx queue + * @addr: OSI core private data structure. + * @qinx: MTL queue index. + * + * Algorithm: Flush a MTL Tx queue. + * + * Dependencies: None. + * + * Protection: None. + * + * Return: None. + */ +static int eqos_flush_mtl_tx_queue(void *addr, unsigned int qinx) +{ + unsigned int retry = 1000; + unsigned int count; + unsigned int value; + int cond = 1; + + /* Read Tx Q Operating Mode Register and flush TxQ */ + value = osi_readl((unsigned char *)addr + EQOS_MTL_CHX_TX_OP_MODE(qinx)); + value |= EQOS_MTL_QTOMR_FTQ; + osi_writel(value, (unsigned char *)addr + EQOS_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++; + osd_msleep(1); + + value = osi_readl((unsigned char *)addr + EQOS_MTL_CHX_TX_OP_MODE(qinx)); + + if ((value & EQOS_MTL_QTOMR_FTQ_LPOS) == 0U) { + cond = 0; + } + } + + return 0; +} + +/** + * eqos_configure_mtl_queue - Configure MTL Queue + * @qinx: Queue number that need to be configured. + * @osi_core: OSI core private data. + * @tx_fifo: MTL TX queue size for a MTL queue. + * @rx_fifo: MTL RX queue size for a 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 + * + * Dependencies: MAC has to be out of reset. + * + * Protection: None + * + * Return: 0 - success, -1 - failure + */ +static int eqos_configure_mtl_queue(unsigned int qinx, + struct osi_core_priv_data *osi_core, + unsigned int tx_fifo, + unsigned int rx_fifo) +{ + unsigned int value = 0; + int ret = 0; + + ret = eqos_flush_mtl_tx_queue(osi_core->base, 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; + osi_writel(value, (unsigned char *)osi_core->base + EQOS_MTL_CHX_TX_OP_MODE(qinx)); + + /* read RX Q0 Operating Mode Register */ + value = osi_readl((unsigned char *)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; + osi_writel(value, (unsigned char *)osi_core->base + EQOS_MTL_CHX_RX_OP_MODE(qinx)); + + /* Transmit Queue weight */ + value = osi_readl((unsigned char *)osi_core->base + EQOS_MTL_TXQ_QW(qinx)); + value |= (EQOS_MTL_TXQ_QW_ISCQW + qinx); + osi_writel(value, (unsigned char *)osi_core->base + EQOS_MTL_TXQ_QW(qinx)); + + /* Enable Rx Queue Control */ + value = osi_readl((unsigned char *)osi_core->base + EQOS_MAC_RQC0R); + value |= ((osi_core->rxq_ctrl[qinx] & 0x3U) << (qinx * 2U)); + osi_writel(value, (unsigned char *)osi_core->base + EQOS_MAC_RQC0R); + + return 0; +} + +/** + * eqos_configure_mac - Configure MAC + * @osi_core: OSI private data structure. + * + * 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 interrupts and Configure the MMC counters + * 5) Enable required MAC interrupts + * + * Dependencies: MAC has to be out of reset. + * + * Protection: None + * + * Return: NONE + */ +static void eqos_configure_mac(struct osi_core_priv_data *osi_core) +{ + unsigned int value; + /* Update MAC address 0 high */ + osi_writel((((unsigned int)osi_core->mac_addr[5] << 8U) | + (unsigned int)(osi_core->mac_addr[4])), + (unsigned char *)osi_core->base + EQOS_MAC_MA0HR); + /* Update MAC address 0 Low */ + osi_writel((((unsigned int)osi_core->mac_addr[3] << 24U) | + ((unsigned int)osi_core->mac_addr[2] << 16U) | + ((unsigned int)osi_core->mac_addr[1] << 8U) | + ((unsigned int)osi_core->mac_addr[0])), + (unsigned char *)osi_core->base + EQOS_MAC_MA0LR); + + /* Read MAC Configuration Register */ + value = osi_readl((unsigned char *)osi_core->base + EQOS_MAC_MCR); + /* Enable Automatic Pad or CRC Stripping */ + /* Enable CRC stripping for Type packets */ + /* Enable Full Duplex mode */ + value |= EQOS_MCR_ACS | EQOS_MCR_CST | EQOS_MCR_DM; + osi_writel(value, (unsigned char *)osi_core->base + EQOS_MAC_MCR); + + /* Enable Multicast and Broadcast Queue, default is Q0 */ + value = osi_readl((unsigned char *)osi_core->base + EQOS_MAC_RQC1R); + value |= EQOS_MAC_RQC1R_MCBCQEN; + osi_writel(value, (unsigned char *)osi_core->base + EQOS_MAC_RQC1R); + + /* Disable all MMC interrupts */ + /* Disable all MMC Tx Interrupts */ + osi_writel(0xFFFFFFFFU, (unsigned char *)osi_core->base + EQOS_MMC_TX_INTR_MASK); + /* Disable all MMC RX interrupts */ + osi_writel(0xFFFFFFFFU, (unsigned char *)osi_core->base + EQOS_MMC_RX_INTR_MASK); + /* Disable MMC Rx interrupts for IPC */ + osi_writel(0xFFFFFFFFU, (unsigned char *)osi_core->base + EQOS_MMC_IPC_RX_INTR_MASK); + + /* Configure MMC counters */ + value = osi_readl((unsigned char *)osi_core->base + EQOS_MMC_CNTRL); + value |= EQOS_MMC_CNTRL_CNTRST | EQOS_MMC_CNTRL_RSTONRD | + EQOS_MMC_CNTRL_CNTPRST | EQOS_MMC_CNTRL_CNTPRSTLVL; + osi_writel(value, (unsigned char *)osi_core->base + EQOS_MMC_CNTRL); + + /* Enable MAC interrupts */ + /* Read MAC IMR Register */ + value = osi_readl((unsigned char *)osi_core->base + EQOS_MAC_IMR); + /* RGSMIIIM - RGMII/SMII interrupt Enable */ + /* TODO: LPI need to be enabled during EEE implementation */ + value |= EQOS_IMR_RGSMIIIE; + + osi_writel(value, (unsigned char *)osi_core->base + EQOS_MAC_IMR); +} + +/** + * eqos_configure_dma - Configure DMA + * @base: EQOS virtual base address. + * + * 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 + * + * Dependencies: MAC has to be out of reset. + * + * Protection: None + * + * Return: NONE + */ +static void eqos_configure_dma(void *base) +{ + unsigned int value = 0; + + /* 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; + + osi_writel(value, (unsigned char *)base + EQOS_DMA_SBUS); + + value = osi_readl((unsigned char *)base + EQOS_DMA_BMR); + value |= EQOS_DMA_BMR_DPSW; + osi_writel(value, (unsigned char *)base + EQOS_DMA_BMR); +} + +/** + * eqos_core_init - EQOS MAC, MTL and common DMA Initialization + * @osi_core: OSI core private data structure. + * @tx_fifo_size: MTL TX FIFO size + * @rx_fifo_size: MTL RX FIFO size + * + * Algorithm: This function will take care of initializing MAC, MTL and + * common DMA registers. + * + * Dependencies: Required clks and resets has to be enabled + * + * Protection: None + * + * Return: 0 - success, -1 - failure + */ +static int eqos_core_init(struct osi_core_priv_data *osi_core, + unsigned int tx_fifo_size, + unsigned int rx_fifo_size) +{ + int ret = 0; + unsigned int qinx = 0; + unsigned int value = 0; + unsigned int tx_fifo = 0; + unsigned int rx_fifo = 0; + + /* PAD calibration */ + ret = eqos_pad_calibrate(osi_core->base); + if (ret < 0) { + return ret; + } + + /* reset mmc counters */ + osi_writel(EQOS_MMC_CNTRL_CNTRST, (unsigned char *)osi_core->base + EQOS_MMC_CNTRL); + + /* Mapping MTL Rx queue and DMA Rx channel */ + /* TODO: Need to add EQOS_MTL_RXQ_DMA_MAP1 for EQOS */ + value = osi_readl((unsigned char *)osi_core->base + EQOS_MTL_RXQ_DMA_MAP0); + value |= EQOS_RXQ_TO_DMA_CHAN_MAP; + osi_writel(value, (unsigned char *)osi_core->base + EQOS_MTL_RXQ_DMA_MAP0); + + /* Calculate value of Transmit queue fifo size to be programmed */ + tx_fifo = eqos_calculate_per_queue_fifo(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(rx_fifo_size, + osi_core->num_mtl_queues); + + /* Configure MTL Queues */ + for (qinx = 0; qinx < osi_core->num_mtl_queues; qinx++) { + 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->base); + + return ret; +} + +/** + * eqos_handle_mac_intrs - Hanle MAC interrupts + * @osi_core: OSI core private data structure. + * @dma_isr: DMA ISR register read value. + * + * Algorithm: This function takes care of handling the + * MAC interrupts which includes speed, mode detection. + * + * Dependencies: MAC interrupts need to be enabled + * + * Protection: None + * + * Return: NONE + */ +static void eqos_handle_mac_intrs(struct osi_core_priv_data *osi_core, + unsigned int dma_isr) +{ + unsigned int mac_imr = 0; + unsigned int mac_pcs = 0; + unsigned int mac_isr = 0; + + mac_isr = osi_readl((unsigned char *)osi_core->base + EQOS_MAC_ISR); + + /* 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_readl((unsigned char *)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) { + return; + } + + mac_pcs = osi_readl((unsigned char *)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) { + eqos_set_mode(osi_core->base, OSI_FULL_DUPLEX); + } else { + eqos_set_mode(osi_core->base, OSI_HALF_DUPLEX); + } + + /* 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->base, OSI_SPEED_10); + } else if ((mac_pcs & EQOS_MAC_PCS_LNKSPEED) == EQOS_MAC_PCS_LNKSPEED_100) { + eqos_set_speed(osi_core->base, OSI_SPEED_100); + } else if ((mac_pcs & EQOS_MAC_PCS_LNKSPEED) == EQOS_MAC_PCS_LNKSPEED_1000) { + eqos_set_speed(osi_core->base, OSI_SPEED_1000); + } else { + /* Nothing here */ + } +} + +/** + * eqos_handle_common_intr - Handles common interrupt. + * @osi_core: OSI core private data structure. + * + * Algorithm: Clear common interrupt source. + * + * Dependencies: None. + * + * Protection: None. + * + * Return: None. + */ +static void eqos_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; + + dma_isr = osi_readl((unsigned char *)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 & 0xFU) != 0U) { + /* Handle Non-TI/RI interrupts */ + for (i = 0; i < osi_core->num_mtl_queues; i++) { + qinx = osi_core->mtl_queues[i]; + + /* read dma channel status register */ + dma_sr = osi_readl((unsigned char *)base + EQOS_DMA_CHX_STATUS(qinx)); + /* read dma channel interrupt enable register */ + dma_ier = osi_readl((unsigned char *)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) { + return; + } + + /* ack non ti/ri ints */ + osi_writel(dma_sr, (unsigned char *)base + EQOS_DMA_CHX_STATUS(qinx)); + } + } + + eqos_handle_mac_intrs(osi_core, dma_isr); +} + +/** + * eqos_start_mac - Start MAC Tx/Rx engine + * @addr: EQOS virtual base address. + * + * Algorithm: Enable MAC Transmitter and Receiver + * + * Dependencies: None. + * + * Protection: None. + * + * Return: None. + */ +static void eqos_start_mac(void *addr) +{ + unsigned int value; + + value = osi_readl((unsigned char *)addr + EQOS_MAC_MCR); + /* Enable MAC Transmit */ + /* Enable MAC Receive */ + value |= EQOS_MCR_TE | EQOS_MCR_RE; + osi_writel(value, (unsigned char *)addr + EQOS_MAC_MCR); +} + +/** + * eqos_stop_mac - Stop MAC Tx/Rx engine + * @addr: EQOS virtual base address. + * + * Algorithm: Disables MAC Transmitter and Receiver + * + * Dependencies: None. + * + * Protection: None. + * + * Return: None. + */ +static void eqos_stop_mac(void *addr) +{ + unsigned int value; + + value = osi_readl((unsigned char *)addr + EQOS_MAC_MCR); + /* Disable MAC Transmit */ + /* Disable MAC Receive */ + value &= ~EQOS_MCR_TE; + value &= ~EQOS_MCR_RE; + osi_writel(value, (unsigned char *)addr + EQOS_MAC_MCR); +} + +static struct osi_core_ops eqos_core_ops = { + .poll_for_swr = eqos_poll_for_swr, + .core_init = eqos_core_init, + .start_mac = eqos_start_mac, + .stop_mac = eqos_stop_mac, + .handle_common_intr = eqos_handle_common_intr, + .set_mode = eqos_set_mode, + .set_speed = eqos_set_speed, + .pad_calibrate = eqos_pad_calibrate, + .set_mdc_clk_rate = eqos_set_mdc_clk_rate, + .flush_mtl_tx_queue = eqos_flush_mtl_tx_queue, +}; + +struct osi_core_ops *eqos_get_hw_core_ops(void) +{ + return &eqos_core_ops; +} diff --git a/osi/eqos_core.h b/osi/eqos_core.h new file mode 100644 index 0000000..21d625a --- /dev/null +++ b/osi/eqos_core.h @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef EQOS_CORE_H_ +#define EQOS_CORE_H_ + +/* MDC Clock Selection define*/ +#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 */ + +#define FIFO_SIZE_B(x) (x) +#define FIFO_SIZE_KB(x) ((x) * 1024U) + +/* per queue fifo size programmable value */ +#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 + +/* EQOS HW Registers */ +#define EQOS_DMA_SBUS 0x1004 +#define EQOS_DMA_BMR 0x1000 +#define EQOS_MMC_CNTRL 0x0700 +#define EQOS_MAC_MA0HR 0x0300 +#define EQOS_MAC_MA0LR 0x0304 +#define EQOS_MAC_MCR 0x0000 +#define EQOS_MAC_IMR 0x00B4 +#define EQOS_DMA_ISR 0x1008 +#define EQOS_MAC_ISR 0x00B0 +#define EQOS_MAC_RQC1R 0x00A4 +#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_RQC0R 0x00A0 +#define EQOS_MAC_PMTCSR 0x00C0 +#define EQOS_MAC_PCS 0x00F8 +#define EQOS_MAC_ANS 0x00E4 +#define EQOS_RXQ_TO_DMA_CHAN_MAP 0x03020100U + +/* EQOS MTL registers*/ +#define EQOS_MTL_CHX_TX_OP_MODE(x) ((0x0040U * (x)) + 0x0D00U) +#define EQOS_MTL_TXQ_QW(x) ((0x0040U * (x)) + 0x0D18U) +#define EQOS_MTL_CHX_RX_OP_MODE(x) ((0x0040U * (x)) + 0x0D30U) +#define EQOS_MTL_RXQ_DMA_MAP0 0x0C30 + +/* EQOS Wrapper registers*/ +#define EQOS_PAD_AUTO_CAL_CFG 0x8804U +#define EQOS_PAD_AUTO_CAL_STAT 0x880CU +#define EQOS_PAD_CRTL 0x8800U + +/* EQOS Register BIT Masks */ +#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_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_TE OSI_BIT(0) +#define EQOS_MCR_RE OSI_BIT(1) +#define EQOS_MCR_DM OSI_BIT(13) +#define EQOS_MCR_FES OSI_BIT(14) +#define EQOS_MCR_PS OSI_BIT(15) +#define EQOS_MCR_ACS OSI_BIT(20) +#define EQOS_MCR_CST OSI_BIT(21) +#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_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_DMA_SBUS_BLEN4 OSI_BIT(1) +#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_MCBCQEN OSI_BIT(20) +#define EQOS_MTL_QTOMR_FTQ_LPOS OSI_BIT(0) +#define EQOS_DMA_ISR_MACIS OSI_BIT(17) +#define EQOS_MAC_ISR_RGSMIIS OSI_BIT(0) +#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 + +#endif diff --git a/osi/eqos_dma.c b/osi/eqos_dma.c new file mode 100644 index 0000000..3a1f523 --- /dev/null +++ b/osi/eqos_dma.c @@ -0,0 +1,433 @@ +/* + * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <osi_common.h> +#include <osi_dma.h> +#include "eqos_dma.h" + +struct osi_dma_chan_ops *eqos_get_dma_chan_ops(void); + +/** + * eqos_disable_chan_tx_intr - Disable Tx channel interrupts. + * @addr: MAC base address. + * @chan: DMA Tx channel number. + * + * Algorithm: Disables EQOS DMA tx channel interrupts. + * + * Dependencies: None. + * Protection: None. + * Return: None. + */ +static void eqos_disable_chan_tx_intr(void *addr, unsigned int chan) +{ + unsigned int cntrl; + + cntrl = osi_readl((unsigned char *)addr + EQOS_VIRT_INTR_CHX_CNTRL(chan)); + cntrl &= ~EQOS_VIRT_INTR_CHX_CNTRL_TX; + osi_writel(cntrl, (unsigned char *)addr + EQOS_VIRT_INTR_CHX_CNTRL(chan)); +} + +/** + * eqos_enable_chan_tx_intr - Enable Tx channel interrupts. + * @addr: MAC base address. + * @chan: DMA Tx channel number. + * + * Algorithm: Enables EQOS DMA tx channel interrupts. + * + * Dependencies: None. + * Protection: None. + * Return: None. + */ +static void eqos_enable_chan_tx_intr(void *addr, unsigned int chan) +{ + unsigned int cntrl; + + cntrl = osi_readl((unsigned char *)addr + EQOS_VIRT_INTR_CHX_CNTRL(chan)); + cntrl |= EQOS_VIRT_INTR_CHX_CNTRL_TX; + osi_writel(cntrl, (unsigned char *)addr + EQOS_VIRT_INTR_CHX_CNTRL(chan)); +} + +/** + * eqos_disable_chan_rx_intr - Disable Rx channel interrupts. + * @addr: MAC base address. + * @chan: DMA Rx channel number. + * + * Algorithm: Disables EQOS DMA rx channel interrupts. + * + * Dependencies: None. + * Protection: None. + * Return: None. + */ +static void eqos_disable_chan_rx_intr(void *addr, unsigned int chan) +{ + unsigned int cntrl; + + cntrl = osi_readl((unsigned char *)addr + EQOS_VIRT_INTR_CHX_CNTRL(chan)); + cntrl &= ~EQOS_VIRT_INTR_CHX_CNTRL_RX; + osi_writel(cntrl, (unsigned char *)addr + EQOS_VIRT_INTR_CHX_CNTRL(chan)); +} + +/** + * eqos_enable_chan_rx_intr - Enable Rx channel interrupts. + * @addr: MAC base address. + * @chan: DMA Rx channel number. + * + * Algorithm: Enables EQOS DMA Rx channel interrupts. + * + * Dependencies: None. + * Protection: None. + * Return: None. + */ +static void eqos_enable_chan_rx_intr(void *addr, unsigned int chan) +{ + unsigned int cntrl; + + cntrl = osi_readl((unsigned char *)addr + EQOS_VIRT_INTR_CHX_CNTRL(chan)); + cntrl |= EQOS_VIRT_INTR_CHX_CNTRL_RX; + osi_writel(cntrl, (unsigned char *)addr + EQOS_VIRT_INTR_CHX_CNTRL(chan)); +} + +/** + * eqos_clear_tx_intr - Handle EQOS DMA Tx channel interrupts. + * @addr: MAC base address. + * @chan: DMA Tx channel number. + * + * Algorithm: Clear DMA Tx interrupt source at wrapper and DMA level. + * + * Dependencies: None. + * Protection: None. + * Return: None. + */ +static void eqos_clear_tx_intr(void *addr, unsigned int chan) +{ + unsigned int status; + + status = osi_readl((unsigned char *)addr + EQOS_VIRT_INTR_CHX_STATUS(chan)); + if ((status & EQOS_VIRT_INTR_CHX_STATUS_TX) == 1U) { + osi_writel(EQOS_DMA_CHX_STATUS_CLEAR_TX, + (unsigned char *)addr + EQOS_DMA_CHX_STATUS(chan)); + osi_writel(EQOS_VIRT_INTR_CHX_STATUS_TX, + (unsigned char *)addr + EQOS_VIRT_INTR_CHX_STATUS(chan)); + } +} + +/** + * eqos_clear_rx_intr - Handles DMA Rx channel interrupts. + * @addr: MAC base address. + * @chan: DMA Rx channel number. + * + * Algorithm: Clear DMA Rx interrupt source at wrapper and DMA level. + * + * Dependencies: None. + * Protection: None. + * Return: None. + */ +static void eqos_clear_rx_intr(void *addr, unsigned int chan) +{ + unsigned int status; + + status = osi_readl((unsigned char *)addr + EQOS_VIRT_INTR_CHX_STATUS(chan)); + if ((status & EQOS_VIRT_INTR_CHX_STATUS_RX) == 2U) { + osi_writel(EQOS_DMA_CHX_STATUS_CLEAR_RX, + (unsigned char *)addr + EQOS_DMA_CHX_STATUS(chan)); + osi_writel(EQOS_VIRT_INTR_CHX_STATUS_RX, + (unsigned char *)addr + EQOS_VIRT_INTR_CHX_STATUS(chan)); + } +} + +/** + * eqos_set_tx_ring_len - Set DMA Tx ring length. + * @addr: MAC base address. + * @chan: DMA Tx channel number. + * @len: Length. + * + * Algorithm: Set DMA Tx channel ring length for specific channel. + * + * Dependencies: None. + * Protection: None. + * Return: None. + */ +static void eqos_set_tx_ring_len(void *addr, unsigned int chan, + unsigned int len) +{ + osi_writel(len, (unsigned char *)addr + EQOS_DMA_CHX_TDRL(chan)); +} + +/** + * eqos_set_tx_ring_start_addr - Set DMA Tx ring base address. + * @addr: MAC base address. + * @chan: DMA Tx channel number. + * @tx_desc: Tx desc base addess. + * + * Algorithm: Sets DMA Tx ring base address for specific channel. + * + * Dependencies: None. + * Protection: None. + * Return: None. + */ +static void eqos_set_tx_ring_start_addr(void *addr, unsigned int chan, + unsigned long tx_desc) +{ + osi_writel((unsigned int)H32(tx_desc), (unsigned char *)addr + EQOS_DMA_CHX_TDLH(chan)); + osi_writel((unsigned int)L32(tx_desc), (unsigned char *)addr + EQOS_DMA_CHX_TDLA(chan)); +} + +/** + * eqos_update_tx_tailptr - Updates DMA Tx ring tail pointer. + * @addr: MAC base address. + * @chan: DMA Tx channel number. + * @tailptr: DMA Tx ring tail pointer. + * + * Algorithm: Updates DMA Tx ring tail pointer for specific channel. + * + * Dependencies: None. + * Protection: None. + * Return: None. + */ +static void eqos_update_tx_tailptr(void *addr, unsigned int chan, + unsigned long tailptr) +{ + osi_writel((unsigned int)L32(tailptr), (unsigned char *)addr + EQOS_DMA_CHX_TDTP(chan)); +} + +/** + * eqos_set_rx_ring_len - Set Rx channel ring length. + * @addr: MAC base address. + * @chan: DMA Rx channel number. + * @len: Length + * + * Algorithm: Sets DMA Rx channel ring length for specific DMA channel. + * + * Dependencies: None. + * Protection: None. + * Return: None. + */ +static void eqos_set_rx_ring_len(void *addr, unsigned int chan, + unsigned int len) +{ + osi_writel(len, (unsigned char *)addr + EQOS_DMA_CHX_RDRL(chan)); +} + +/** + * eqos_set_rx_ring_start_addr - Set DMA Rx ring base address. + * @addr: MAC base address. + * @chan: DMA Rx channel number. + * @tx_desc: DMA Rx desc base address. + * + * Algorithm: Sets DMA Rx channel ring base address. + * + * Dependencies: None. + * Protection: None. + * Return: None. + */ +static void eqos_set_rx_ring_start_addr(void *addr, unsigned int chan, + unsigned long tx_desc) +{ + osi_writel((unsigned int)H32(tx_desc), (unsigned char *)addr + EQOS_DMA_CHX_RDLH(chan)); + osi_writel((unsigned int)L32(tx_desc), (unsigned char *)addr + EQOS_DMA_CHX_RDLA(chan)); +} + +/** + * eqos_update_rx_tailptr - Update Rx ring tail pointer + * @addr: MAC base address. + * @chan: DMA Rx channel number. + * @tailptr: Tail pointer + * + * Algorithm: Updates DMA Rx channel tail pointer for specific channel. + * + * Dependencies: None. + * Protection: None. + * Return: None. + */ +static void eqos_update_rx_tailptr(void *addr, unsigned int chan, + unsigned long tailptr) +{ + osi_writel((unsigned int)L32(tailptr), (unsigned char *)addr + EQOS_DMA_CHX_RDTP(chan)); +} + +/** + * eqos_start_dma - Start DMA. + * @addr: MAC base address. + * @chan: DMA Tx/Rx channel number. + * + * Algorithm: Start Tx and Rx DMA for specific channel. + * + * Dependencies: None. + * Protection: None. + * Return: None. + */ +static void eqos_start_dma(void *addr, unsigned int chan) +{ + unsigned int val; + + /* start Tx DMA */ + val = osi_readl((unsigned char *)addr + EQOS_DMA_CHX_TX_CTRL(chan)); + val |= OSI_BIT(0); + osi_writel(val, (unsigned char *)addr + EQOS_DMA_CHX_TX_CTRL(chan)); + + /* start Rx DMA */ + val = osi_readl((unsigned char *)addr + EQOS_DMA_CHX_RX_CTRL(chan)); + val |= OSI_BIT(0); + osi_writel(val, (unsigned char *)addr + EQOS_DMA_CHX_RX_CTRL(chan)); +} + +/** + * eqos_stop_dma - Stop DMA. + * @addr: MAC base address. + * @chan: DMA Tx/Rx channel number. + * + * Algorithm: Start Tx and Rx DMA for specific channel. + * + * Dependencies: None. + * Protection: None. + * Return: None. + */ +static void eqos_stop_dma(void *addr, unsigned int chan) +{ + unsigned int val; + + /* stop Tx DMA */ + val = osi_readl((unsigned char *)addr + EQOS_DMA_CHX_TX_CTRL(chan)); + val &= ~OSI_BIT(0); + osi_writel(val, (unsigned char *)addr + EQOS_DMA_CHX_TX_CTRL(chan)); + + /* stop Rx DMA */ + val = osi_readl((unsigned char *)addr + EQOS_DMA_CHX_RX_CTRL(chan)); + val &= ~OSI_BIT(0); + osi_writel(val, (unsigned char *)addr + EQOS_DMA_CHX_RX_CTRL(chan)); +} + +/** + * eqos_configure_dma_channel - Configure DMA channel + * @chan: DMA channel number that need to be configured. + * @osi_dma: OSI DMA private data structure. + * + * 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 + * + * Dependencies: MAC has to be out of reset. + * + * Protection: None + * + * Return: NONE + */ +static void eqos_configure_dma_channel(unsigned int chan, + struct osi_dma_priv_data *osi_dma) +{ + unsigned int value; + + /* 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((unsigned char *)osi_dma->base + EQOS_DMA_CHX_INTR_ENA(chan)); + value |= EQOS_DMA_CHX_INTR_TIE | EQOS_DMA_CHX_INTR_TBUE | + EQOS_DMA_CHX_INTR_RIE | EQOS_DMA_CHX_INTR_RBUE | + 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); + osi_writel(value, (unsigned char *)osi_dma->base + EQOS_DMA_CHX_INTR_ENA(chan)); + + /* Enable 8xPBL mode */ + value = osi_readl((unsigned char *)osi_dma->base + EQOS_DMA_CHX_CTRL(chan)); + value |= EQOS_DMA_CHX_CTRL_PBLX8; + osi_writel(value, (unsigned char *)osi_dma->base + EQOS_DMA_CHX_CTRL(chan)); + + /* Configure DMA channel Transmit control register */ + value = osi_readl((unsigned char *)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; + + osi_writel(value, (unsigned char *)osi_dma->base + EQOS_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((unsigned char *)osi_dma->base + EQOS_DMA_CHX_RX_CTRL(chan)); + osi_dma->rx_buf_len = ((MAX_ETH_FRAME_LEN_DEFAULT + + (EQOS_AXI_BUS_WIDTH - 1U)) & + ~(EQOS_AXI_BUS_WIDTH - 1U)); + value |= (osi_dma->rx_buf_len << EQOS_DMA_CHX_RBSZ_SHIFT); + /* RXPBL = 12 */ + value |= EQOS_DMA_CHX_RX_CTRL_RXPBL_RECOMMENDED; + osi_writel(value, (unsigned char *)osi_dma->base + EQOS_DMA_CHX_RX_CTRL(chan)); +} + +/** + * eqos_init_dma_channel - DMA channel INIT + * @osi_dma: OSI DMA private data structure. + * + * Description: Initialise all DMA channels. + * + * Dependencies: None. + * Protection: None. + * Return: None. + */ +static void eqos_init_dma_channel(struct osi_dma_priv_data *osi_dma) +{ + unsigned int chinx; + + /* 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); + } +} + +static struct osi_dma_chan_ops eqos_dma_chan_ops = { + .set_tx_ring_len = eqos_set_tx_ring_len, + .set_rx_ring_len = eqos_set_rx_ring_len, + .set_tx_ring_start_addr = eqos_set_tx_ring_start_addr, + .set_rx_ring_start_addr = eqos_set_rx_ring_start_addr, + .update_tx_tailptr = eqos_update_tx_tailptr, + .update_rx_tailptr = eqos_update_rx_tailptr, + .clear_tx_intr = eqos_clear_tx_intr, + .clear_rx_intr = eqos_clear_rx_intr, + .disable_chan_tx_intr = eqos_disable_chan_tx_intr, + .enable_chan_tx_intr = eqos_enable_chan_tx_intr, + .disable_chan_rx_intr = eqos_disable_chan_rx_intr, + .enable_chan_rx_intr = eqos_enable_chan_rx_intr, + .start_dma = eqos_start_dma, + .stop_dma = eqos_stop_dma, + .init_dma_channel = eqos_init_dma_channel, +}; + +struct osi_dma_chan_ops *eqos_get_dma_chan_ops(void) +{ + return &eqos_dma_chan_ops; +} diff --git a/osi/eqos_dma.h b/osi/eqos_dma.h new file mode 100644 index 0000000..39bd892 --- /dev/null +++ b/osi/eqos_dma.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef EQOS_H_ +#define EQOS_H_ + +#define EQOS_AXI_BUS_WIDTH 0x10U + +/* EQOS DMA channel registers */ +#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) + +#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_CHX_STATUS(x) (0x8604U + ((x) * 8U)) +#define EQOS_VIRT_INTR_CHX_CNTRL(x) (0x8600U + ((x) * 8U)) +#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_SHIFT 1U +#define EQOS_DMA_CHX_TX_CTRL_TXPBL_RECOMMENDED 0x200000U +#define EQOS_DMA_CHX_RX_CTRL_RXPBL_RECOMMENDED 0xC0000U + +#endif diff --git a/osi/osi_common.c b/osi/osi_common.c new file mode 100644 index 0000000..b51ba7c --- /dev/null +++ b/osi/osi_common.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <osi_core.h> +#include <osd.h> + +/** + * osi_get_hw_features: Get MAC Hardware features from features registers + * @osi: OSI private data structure. + * + * Algorithm: Reads HW features from HW registers and populate those + * in hw features structure. + * + * Dependencies: CAR reset should be success before calling this function + * + * Return: None + */ +void osi_get_hw_features(void *base, struct osi_hw_features *hw_feat) +{ + unsigned int mac_hfr0; + unsigned int mac_hfr1; + unsigned int mac_hfr2; + + /* TODO: need to add HFR3 */ + mac_hfr0 = osi_readl((unsigned char *)base + EQOS_MAC_HFR0); + mac_hfr1 = osi_readl((unsigned char *)base + EQOS_MAC_HFR1); + mac_hfr2 = osi_readl((unsigned char *)base + EQOS_MAC_HFR2); + + hw_feat->mii_sel = + ((mac_hfr0 >> 0) & EQOS_MAC_HFR0_MIISEL_MASK); + hw_feat->gmii_sel = + ((mac_hfr0 >> 1U) & EQOS_MAC_HFR0_GMIISEL_MASK); + hw_feat->hd_sel = + ((mac_hfr0 >> 2U) & EQOS_MAC_HFR0_HDSEL_MASK); + hw_feat->pcs_sel = + ((mac_hfr0 >> 3U) & EQOS_MAC_HFR0_PCSSEL_MASK); + hw_feat->sma_sel = + ((mac_hfr0 >> 5U) & EQOS_MAC_HFR0_SMASEL_MASK); + hw_feat->rwk_sel = + ((mac_hfr0 >> 6U) & EQOS_MAC_HFR0_RWKSEL_MASK); + hw_feat->mgk_sel = + ((mac_hfr0 >> 7U) & EQOS_MAC_HFR0_MGKSEL_MASK); + hw_feat->mmc_sel = + ((mac_hfr0 >> 8U) & EQOS_MAC_HFR0_MMCSEL_MASK); + hw_feat->arp_offld_en = + ((mac_hfr0 >> 9U) & EQOS_MAC_HFR0_ARPOFFLDEN_MASK); + hw_feat->ts_sel = + ((mac_hfr0 >> 12U) & EQOS_MAC_HFR0_TSSSEL_MASK); + hw_feat->eee_sel = + ((mac_hfr0 >> 13U) & EQOS_MAC_HFR0_EEESEL_MASK); + hw_feat->tx_coe_sel = + ((mac_hfr0 >> 14U) & EQOS_MAC_HFR0_TXCOESEL_MASK); + hw_feat->rx_coe_sel = + ((mac_hfr0 >> 16U) & EQOS_MAC_HFR0_RXCOE_MASK); + hw_feat->mac_addr16_sel = + ((mac_hfr0 >> 18U) & EQOS_MAC_HFR0_ADDMACADRSEL_MASK); + hw_feat->mac_addr32_sel = + ((mac_hfr0 >> 23U) & EQOS_MAC_HFR0_MACADR32SEL_MASK); + hw_feat->mac_addr64_sel = + ((mac_hfr0 >> 24U) & EQOS_MAC_HFR0_MACADR64SEL_MASK); + hw_feat->tsstssel = + ((mac_hfr0 >> 25U) & EQOS_MAC_HFR0_TSINTSEL_MASK); + hw_feat->sa_vlan_ins = + ((mac_hfr0 >> 27U) & EQOS_MAC_HFR0_SAVLANINS_MASK); + hw_feat->act_phy_sel = + ((mac_hfr0 >> 28U) & EQOS_MAC_HFR0_ACTPHYSEL_MASK); + hw_feat->rx_fifo_size = + ((mac_hfr1 >> 0) & EQOS_MAC_HFR1_RXFIFOSIZE_MASK); + hw_feat->tx_fifo_size = + ((mac_hfr1 >> 6U) & EQOS_MAC_HFR1_TXFIFOSIZE_MASK); + hw_feat->adv_ts_hword = + ((mac_hfr1 >> 13U) & EQOS_MAC_HFR1_ADVTHWORD_MASK); + hw_feat->dcb_en = + ((mac_hfr1 >> 16U) & EQOS_MAC_HFR1_DCBEN_MASK); + hw_feat->sph_en = + ((mac_hfr1 >> 17U) & EQOS_MAC_HFR1_SPHEN_MASK); + hw_feat->tso_en = + ((mac_hfr1 >> 18U) & EQOS_MAC_HFR1_TSOEN_MASK); + hw_feat->dma_debug_gen = + ((mac_hfr1 >> 19U) & EQOS_MAC_HFR1_DMADEBUGEN_MASK); + hw_feat->av_sel = + ((mac_hfr1 >> 20U) & EQOS_MAC_HFR1_AVSEL_MASK); + hw_feat->hash_tbl_sz = + ((mac_hfr1 >> 24U) & EQOS_MAC_HFR1_HASHTBLSZ_MASK); + hw_feat->l3l4_filter_num = + ((mac_hfr1 >> 27U) & EQOS_MAC_HFR1_L3L4FILTERNUM_MASK); + hw_feat->rx_q_cnt = + ((mac_hfr2 >> 0) & EQOS_MAC_HFR2_RXQCNT_MASK); + hw_feat->tx_q_cnt = + ((mac_hfr2 >> 6U) & EQOS_MAC_HFR2_TXQCNT_MASK); + hw_feat->rx_ch_cnt = + ((mac_hfr2 >> 12U) & EQOS_MAC_HFR2_RXCHCNT_MASK); + hw_feat->tx_ch_cnt = + ((mac_hfr2 >> 18U) & EQOS_MAC_HFR2_TXCHCNT_MASK); + hw_feat->pps_out_num = + ((mac_hfr2 >> 24U) & EQOS_MAC_HFR2_PPSOUTNUM_MASK); + hw_feat->aux_snap_num = + ((mac_hfr2 >> 28U) & EQOS_MAC_HFR2_AUXSNAPNUM_MASK); +} diff --git a/osi/osi_core.c b/osi/osi_core.c new file mode 100644 index 0000000..6e290af --- /dev/null +++ b/osi/osi_core.c @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <osi_core.h> +#include <osd.h> + +#define MAC_MDIO_ADDRESS 0x200 +#define MAC_GMII_BUSY 0x00000001U + +#define MAC_MDIO_DATA 0x204 + +#define MAC_GMIIDR_GD_WR_MASK 0xffff0000U +#define MAC_GMIIDR_GD_MASK 0xffffU + +#define MDIO_PHY_ADDR_SHIFT 21U +#define MDIO_PHY_REG_SHIFT 16U +#define MDIO_MII_WRITE OSI_BIT(2) + +extern struct osi_core_ops *eqos_get_hw_core_ops(void); + +/** + * osi_write_phy_reg - Write to a PHY register through MAC over MDIO bus. + * @osi: OSI private data structure. + * @phyaddr: PHY address (PHY ID) associated with PHY + * @phyreg: Register which needs to be write to PHY. + * @phydata: Data to write to a PHY register. + * + * Algorithm: + * 1) Before proceding for reading for PHY register check whether any MII + * operation going on MDIO bus by polling MAC_GMII_BUSY bit. + * 2) Program data into MAC MDIO data register. + * 3) 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. + * 4) Write into MAC MDIO address register poll for GMII busy for MDIO + * operation to complete. + * + * Dependencies: MAC IP should be out of reset + * + * Return: 0 - success, -1 - failure + */ +int osi_write_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, + unsigned int phyreg, unsigned short phydata) +{ + unsigned int retry = 1000; + unsigned int count; + unsigned int mac_gmiiar; + unsigned int mac_gmiidr; + int cond = 1; + + /* wait for any previous MII read/write operation to complete */ + count = 0; + while (cond == 1) { + if (count > retry) { + return -1; + } + + count++; + osd_msleep(1U); + + mac_gmiiar = osi_readl((unsigned char *)osi_core->base + MAC_MDIO_ADDRESS); + + if ((mac_gmiiar & MAC_GMII_BUSY) == 0U) { + cond = 0; + } + } + + mac_gmiidr = osi_readl((unsigned char *)osi_core->base + MAC_MDIO_DATA); + + mac_gmiidr = ((mac_gmiidr & MAC_GMIIDR_GD_WR_MASK) | + (((phydata) & MAC_GMIIDR_GD_MASK) << 0)); + + osi_writel(mac_gmiidr, (unsigned char *)osi_core->base + 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_readl((unsigned char *)osi_core->base + MAC_MDIO_ADDRESS); + mac_gmiiar = (mac_gmiiar & 0x12U); + mac_gmiiar = (mac_gmiiar | ((phyaddr) << MDIO_PHY_ADDR_SHIFT) | + ((phyreg) << MDIO_PHY_REG_SHIFT) | + ((osi_core->mdc_cr) << 8U) | + MDIO_MII_WRITE | MAC_GMII_BUSY); + + osi_writel(mac_gmiiar, (unsigned char *)osi_core->base + MAC_MDIO_ADDRESS); + + osd_usleep_range(9, 11); + + /* wait for MII write operation to complete */ + cond = 1; + count = 0; + while (cond == 1) { + if (count > retry) { + return -1; + } + + count++; + osd_msleep(1U); + + mac_gmiiar = osi_readl((unsigned char *)osi_core->base + MAC_MDIO_ADDRESS); + + if ((mac_gmiiar & MAC_GMII_BUSY) == 0U) { + cond = 0; + } + } + + return 0; +} + +/** + * osi_read_phy_reg - Read from a PHY register through MAC over MDIO bus. + * @osi: OSI private data structure. + * @phyaddr: PHY address (PHY ID) associated with PHY + * @phyreg: Register which needs to be read from PHY. + * + * Algorithm: + * 1) Before proceding for reading for PHY register check whether any MII + * operation going on MDIO bus by polling MAC_GMII_BUSY bit. + * 2) 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. + * 3) 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. + * + * Dependencies: MAC IP should be out of reset + * + * Return: data from PHY register - success, -1 - failure + */ + +int osi_read_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, + unsigned int phyreg) +{ + unsigned int retry = 1000; + unsigned int count; + unsigned int mac_gmiiar; + unsigned int mac_gmiidr; + unsigned int data; + int cond = 1; + + /* wait for any previous MII read/write operation to complete */ + /*Poll Until Poll Condition */ + count = 0; + while (cond == 1) { + if (count > retry) { + return -1; + } + + count++; + osd_msleep(1U); + + mac_gmiiar = osi_readl((unsigned char *)osi_core->base + MAC_MDIO_ADDRESS); + + if ((mac_gmiiar & MAC_GMII_BUSY) == 0U) { + cond = 0; + } + } + + mac_gmiiar = osi_readl((unsigned char *)osi_core->base + 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 & 0x12U); + mac_gmiiar = mac_gmiiar | ((phyaddr) << MDIO_PHY_ADDR_SHIFT) | + ((phyreg) << MDIO_PHY_REG_SHIFT) | + (osi_core->mdc_cr) << 8U | ((0x3U) << 2U) | MAC_GMII_BUSY; + osi_writel(mac_gmiiar, (unsigned char *)osi_core->base + MAC_MDIO_ADDRESS); + + osd_usleep_range(9, 11); + + /* wait for MII write operation to complete */ + /*Poll Until Poll Condition */ + cond = 1; + count = 0; + while (cond == 1) { + if (count > retry) { + return -1; + } + + count++; + osd_msleep(1U); + + mac_gmiiar = osi_readl((unsigned char *)osi_core->base + MAC_MDIO_ADDRESS); + + if ((mac_gmiiar & MAC_GMII_BUSY) == 0U) { + cond = 0; + } + } + + mac_gmiidr = osi_readl((unsigned char *)osi_core->base + MAC_MDIO_DATA); + data = (mac_gmiidr & 0x0000FFFFU); + + return (int)data; +} + +void osi_init_core_ops(struct osi_core_priv_data *osi_core) +{ + if (osi_core->mac == OSI_MAC_HW_EQOS) { + /* Get EQOS HW ops */ + osi_core->ops = eqos_get_hw_core_ops(); + } +} diff --git a/osi/osi_dma.c b/osi/osi_dma.c new file mode 100644 index 0000000..6ad8e39 --- /dev/null +++ b/osi/osi_dma.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <osi_dma.h> + +extern int dma_desc_init(struct osi_dma_priv_data *osi_dma); +extern struct osi_dma_chan_ops *eqos_get_dma_chan_ops(void); + +void osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) +{ + if (osi_dma->mac == OSI_MAC_HW_EQOS) { + /* Get EQOS HW ops */ + osi_dma->ops = eqos_get_dma_chan_ops(); + } +} + +int osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) +{ + unsigned int i, chan; + int ret; + + if (osi_dma->ops->init_dma_channel != OSI_NULL) { + osi_dma->ops->init_dma_channel(osi_dma); + } + + ret = dma_desc_init(osi_dma); + if (ret != 0) { + return ret; + } + + /* 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]; + + osi_enable_chan_tx_intr(osi_dma, chan); + osi_enable_chan_rx_intr(osi_dma, chan); + osi_start_dma(osi_dma, chan); + } + + return 0; +} + +/** + * osi_hw_deinit - De-init the HW + * @osi: OSI private data structure. + * + * Algorithm: + * 1) Stop the DMA + * 2) free all allocated resources. + * + * Dependencies: None + * Protection: None + * Return: None + */ +void osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma) +{ + unsigned int i; + + for (i = 0; i < osi_dma->num_dma_chans; i++) { + osi_stop_dma(osi_dma, osi_dma->dma_chans[i]); + } +} diff --git a/osi/osi_dma_txrx.c b/osi/osi_dma_txrx.c new file mode 100644 index 0000000..1c9b3b4 --- /dev/null +++ b/osi/osi_dma_txrx.c @@ -0,0 +1,332 @@ +/* + * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <osd.h> +#include <osi_dma.h> +#include <osi_dma_txrx.h> + +/** + * osi_process_rx_completions - Read data from receive channel descriptors + * @osi: OSI private data structure. + * @chan: Rx DMA channel number + * @budget: Threshould for reading the packets at a time. + * + * Algorimthm: This routine will be invoked by OSD layer to get the + * data from Rx descriptors and deliver the packet to the stack. + * 1) Checks descriptor owned by DMA or not. + * 2) Get the length from Rx descriptor + * 3) Invokes OSD layer to deliver the packet to network stack. + * 4) Re-allocate the receive buffers, populate Rx descriptor and + * handover to DMA. + * + * Dependencies: None. + * + * Protection: None. + * + * Return: None. + */ +int osi_process_rx_completions(struct osi_dma_priv_data *osi, + unsigned int chan, int budget) +{ + struct osi_rx_ring *rx_ring = osi->rx_ring[chan]; + struct osi_rx_desc *rx_desc = OSI_NULL; + unsigned int pkt_len = 0; + int received = 0; + + while (received < budget) { + rx_desc = rx_ring->rx_desc + rx_ring->cur_rx_idx; + + /* check for data availability */ + if ((rx_desc->rdes3 & RDES3_OWN) == RDES3_OWN) { + break; + } + + /* get the length of the packet */ + pkt_len = rx_desc->rdes3 & RDES3_PKT_LEN; + + if (((rx_desc->rdes3 & RDES3_ES_BITS) == 0U) && + ((rx_desc->rdes3 & RDES3_LD) == RDES3_LD)) { + osd_receive_packet(osi->osd, rx_ring, chan, + osi->rx_buf_len, pkt_len); + } + + received++; + } + + return received; +} + +/** + * osi_process_tx_completions - Process Tx complete on DMA channel ring. + * @osi: OSI private data structure. + * @chan: Channel number on which Tx complete need to be done. + * + * Algorithm: This function will be invoked by OSD layer to process Tx + * complete interrupt. + * 1) First checks whether descriptor owned by DMA or not. + * 2) Invokes OSD layer to release DMA address and Tx buffer which are + * updated as part of transmit routine. + * + * Dependencies: None. + * + * Protection: None + * + * Return: Number of decriptors (buffers) proccessed. + */ +int osi_process_tx_completions(struct osi_dma_priv_data *osi, + unsigned int chan) +{ + struct osi_tx_ring *tx_ring = osi->tx_ring[chan]; + struct osi_tx_swcx *tx_swcx = OSI_NULL; + struct osi_tx_desc *tx_desc = OSI_NULL; + unsigned int entry = tx_ring->clean_idx; + int processed = 0; + + while (entry != tx_ring->cur_tx_idx) { + tx_desc = tx_ring->tx_desc + entry; + tx_swcx = tx_ring->tx_swcx + entry; + + if ((tx_desc->tdes3 & TDES3_OWN) == TDES3_OWN) { + break; + } + + osd_transmit_complete(osi->osd, tx_swcx->buf_virt_addr, + tx_swcx->buf_phy_addr, tx_swcx->len); + + 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; + INCR_TX_DESC_INDEX(entry, 1U); + processed++; + } + + tx_ring->clean_idx = entry; + + return processed; +} + +/** + * osi_hw_transmit - Initialize Tx DMA descriptors for a channel + * @osi: OSI private data structure. + * @chan: DMA Tx channel number + * + * Algorithm: Initialize Transmit descriptors with DMA mappabled buffers, + * set OWN bit, Tx ring length and set starting address of Tx DMA channel. + * Tx ring base address in Tx DMA registers. + * + * Dependencies: Transmit routine of OSD needs to map Tx buffer + * to dma mappable address and update in the software context descriptors. + * + * Protection: None. + * + * Return: None. + */ +void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan) +{ + struct osi_tx_ring *tx_ring = osi->tx_ring[chan]; + struct osi_dma_chan_ops *ops = osi->ops; + unsigned int entry = tx_ring->cur_tx_idx; + struct osi_tx_desc *tx_desc = tx_ring->tx_desc + entry; + struct osi_tx_swcx *tx_swcx = tx_ring->tx_swcx + entry; + unsigned long tailptr; + + /* update the first buffer pointer and length */ + tx_desc->tdes0 = (unsigned int)L32(tx_swcx->buf_phy_addr); + tx_desc->tdes1 = (unsigned int)H32(tx_swcx->buf_phy_addr); + tx_desc->tdes2 = tx_swcx->len; + /* Mark it as First descriptor */ + tx_desc->tdes3 |= TDES3_FD; + /* Mark it as LAST descriptor */ + tx_desc->tdes3 |= TDES3_LD; + /* set Interrupt on Completion*/ + tx_desc->tdes2 |= TDES2_IOC; + /* set HW OWN bit for descriptor*/ + tx_desc->tdes3 |= TDES3_OWN; + + INCR_TX_DESC_INDEX(entry, 1U); + + tailptr = tx_ring->tx_desc_phy_addr + + (entry * sizeof(struct osi_tx_desc)); + + ops->update_tx_tailptr(osi->base, chan, tailptr); + tx_ring->cur_tx_idx = entry; +} + +/** + * rx_dma_desc_initialization - Initialize DMA Receive descriptors for Rx. + * @osi: OSI private data structure. + * @chan: Rx channel number. + * + * 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. + * + * Dependencies: None. + * + * Protection: None. + * + * Return: 0 - success, -1 - failure. + */ +static int rx_dma_desc_initialization(struct osi_dma_priv_data *osi, + unsigned int chan) +{ + struct osi_rx_ring *rx_ring = osi->rx_ring[chan]; + struct osi_rx_desc *rx_desc = OSI_NULL; + struct osi_rx_swcx *rx_swcx = OSI_NULL; + struct osi_dma_chan_ops *ops = osi->ops; + unsigned long tailptr = 0; + unsigned int i; + int ret = 0; + + rx_ring->cur_rx_idx = 0; + rx_ring->refill_idx = 0; + + for (i = 0; i < RX_DESC_CNT; i++) { + rx_swcx = rx_ring->rx_swcx + i; + rx_desc = rx_ring->rx_desc + i; + + rx_desc->rdes0 = (unsigned int)L32(rx_swcx->buf_phy_addr); + rx_desc->rdes1 = (unsigned int)H32(rx_swcx->buf_phy_addr); + rx_desc->rdes2 = 0; + //TODO: RDES3_IOC needs to be reset for Rx watchdog + rx_desc->rdes3 = (RDES3_OWN | RDES3_IOC | RDES3_B1V); + } + + tailptr = rx_ring->rx_desc_phy_addr + + sizeof(struct osi_rx_desc) * (RX_DESC_CNT - 1U); + + ops->set_rx_ring_len(osi->base, chan, (RX_DESC_CNT - 1U)); + ops->update_rx_tailptr(osi->base, chan, tailptr); + ops->set_rx_ring_start_addr(osi->base, chan, rx_ring->rx_desc_phy_addr); + + return ret; +} + +/** + * rx_dma_desc_init - Initialize DMA Receive descriptors for Rx channel. + * @osi: OSI private data structure. + * + * Algorithm: Initialize Receive descriptors with DMA mappabled buffers, + * set OWN bit, Rx ring length and set starting address of Rx DMA channel. + * Tx ring base address in Tx DMA registers. + * + * Dependencies: None. + * + * Protection: None. + * + * Return: 0 - success, -1 - failure. + */ +static int rx_dma_desc_init(struct osi_dma_priv_data *osi) +{ + unsigned int chan = 0; + unsigned int i; + int ret = 0; + + for (i = 0; i < osi->num_dma_chans; i++) { + chan = osi->dma_chans[i]; + + ret = rx_dma_desc_initialization(osi, chan); + if (ret != 0) { + return ret; + } + } + + return ret; +} + +/** + * tx_dma_desc_init - Initialize DMA Transmit descriptors. + * @osi: OSI private data structure. + * + * Algorithm: Initialize Trannsmit descriptors and set Tx ring length, + * Tx ring base address in Tx DMA registers. + * + * Dependencies: None. + * + * Protection: None. + * + * Return: None. + */ +static void tx_dma_desc_init(struct osi_dma_priv_data *osi_dma) +{ + struct osi_tx_ring *tx_ring = OSI_NULL; + struct osi_tx_desc *tx_desc = OSI_NULL; + struct osi_tx_swcx *tx_swcx = OSI_NULL; + struct osi_dma_chan_ops *ops = osi_dma->ops; + unsigned int chan = 0; + unsigned int i; + + for (i = 0; i < osi_dma->num_dma_chans; i++) { + chan = osi_dma->dma_chans[i]; + + tx_ring = osi_dma->tx_ring[chan]; + tx_desc = tx_ring->tx_desc; + tx_swcx = tx_ring->tx_swcx; + + /* FIXME: does it require */ + tx_desc->tdes0 = 0; + tx_desc->tdes1 = 0; + tx_desc->tdes2 = 0; + tx_desc->tdes3 = 0; + + tx_ring->cur_tx_idx = 0; + tx_ring->clean_idx = 0; + + ops->set_tx_ring_len(osi_dma->base, chan, + (TX_DESC_CNT - 1U)); + ops->set_tx_ring_start_addr(osi_dma->base, chan, + tx_ring->tx_desc_phy_addr); + } +} + +/** + * dma_desc_init - Initialize DMA Tx/Rx descriptors + * @osi: OSI private data structure. + * + * Algorithm: Transmit and Receive desctiptors will be initialized with + * required values so that MAC DMA can understand and act accordingly. + * + * Dependencies: None. + * + * Protection: None. + * + * Return: 0 - success, -1 - failure. + */ +int dma_desc_init(struct osi_dma_priv_data *osi_dma) +{ + int ret = 0; + + tx_dma_desc_init(osi_dma); + + ret = rx_dma_desc_init(osi_dma); + if (ret != 0) { + return ret; + } + + return ret; +} + From 58db7892f572693e63e5f8e80c26275d6bebf7bd Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Wed, 20 Mar 2019 10:11:42 +0530 Subject: [PATCH 003/458] nvethernetrm: support for VLAN This patch introduce Tx/Rx packet context information so that VLAN info can be passed from OSI to OSD in Receive path and OSD to OSI in Transmit path. Bug 200511721 Change-Id: I0ca21300aee2f25f9bc48006421c441abe1586f6 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2077036 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osd.h | 5 +- include/osi_dma.h | 40 +++++++++++++-- include/osi_dma_txrx.h | 12 ++++- osi/eqos_core.c | 20 ++++++++ osi/eqos_core.h | 9 ++++ osi/osi_dma_txrx.c | 107 +++++++++++++++++++++++++++++++++++++---- 6 files changed, 175 insertions(+), 18 deletions(-) diff --git a/include/osd.h b/include/osd.h index e4de417..bf1f527 100644 --- a/include/osd.h +++ b/include/osd.h @@ -28,9 +28,8 @@ void osd_msleep(unsigned int msec); void osd_udelay(unsigned long usec); void osd_info(void *priv, const char *fmt, ...); void osd_err(void *priv, const char *fmt, ...); -void osd_receive_packet(void *priv, void *rx_ring, - unsigned int chan, unsigned int dma_buf_len, - unsigned int rx_pkt_len); +void osd_receive_packet(void *priv, void *rxring, unsigned int chan, + unsigned int dma_buf_len, void *rxpkt_cx); void osd_transmit_complete(void *priv, void *buffer, unsigned long dmaaddr, unsigned int len); #endif diff --git a/include/osi_dma.h b/include/osi_dma.h index 8a7c0b2..f620be8 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -26,6 +26,8 @@ #include "osi_common.h" #include "osi_dma_txrx.h" +#define OSI_PKT_CX_VLAN OSI_BIT(0) + /** * struct osi_rx_desc - Receive Descriptor * @rdes0: Receive Descriptor 0 @@ -52,6 +54,18 @@ struct osi_rx_swcx { unsigned int len; }; +/** + * struct osi_rx_pkt_cx - Received packet context. + * @flags: Bit map which holds the features that rx packets supports. + * @vlan_tag: Stores the VLAN tag ID in received packet. + * @pkt_len: Length of received packet. + */ +struct osi_rx_pkt_cx { + unsigned int flags; + unsigned int vlan_tag; + unsigned int pkt_len; +}; + /** * struct osi_rx_ring - DMA Rx channel ring * @rx_desc: Pointer to Rx DMA descriptor @@ -59,6 +73,7 @@ struct osi_rx_swcx { * @dma_rx_desc: Physical address of Rx DMA descriptor * @cur_rx_idx: Descriptor index current reception. * @refill_idx: Descriptor index for descriptor re-allocation. + * @rx_pkt_cx: Received packet context. */ struct osi_rx_ring { struct osi_rx_desc *rx_desc; @@ -66,6 +81,7 @@ struct osi_rx_ring { unsigned long rx_desc_phy_addr; unsigned int cur_rx_idx; unsigned int refill_idx; + struct osi_rx_pkt_cx rx_pkt_cx; }; /** @@ -94,13 +110,26 @@ struct osi_tx_desc { unsigned int tdes3; }; +/** + * struct osi_tx_pkt_cx - Transmit packet context for a packet + * @flags: Holds the features which a Tx packets supports. + * @vtag_id: Stores the VLAN tag ID. + * @desc_cnt: Descriptor count + */ +struct osi_tx_pkt_cx { + unsigned int flags; + unsigned int vtag_id; + unsigned int desc_cnt; +}; + /** * struct osi_tx_ring - DMA channel Tx ring - * @tx_desc: Pointer to tx dma descriptor - * @tx_swcx: Pointer to tx dma descriptor software context information - * @tx_desc_phy_addr: Physical address of Tx descriptor. - * @cur_tx_idx: Descriptor index current transmission. - * @clean_idx: Descriptor index for descriptor cleanup. + * @tx_desc: Pointer to tx dma descriptor + * @tx_swcx: Pointer to tx dma descriptor software context information + * @tx_desc_phy_addr: Physical address of Tx descriptor. + * @cur_tx_idx: Descriptor index current transmission. + * @clean_idx: Descriptor index for descriptor cleanup. + * @tx_pkt_cx: Transmit packet context. */ struct osi_tx_ring { struct osi_tx_desc *tx_desc; @@ -108,6 +137,7 @@ struct osi_tx_ring { unsigned long tx_desc_phy_addr; unsigned int cur_tx_idx; unsigned int clean_idx; + struct osi_tx_pkt_cx tx_pkt_cx; }; struct osi_dma_priv_data; diff --git a/include/osi_dma_txrx.h b/include/osi_dma_txrx.h index 2833856..8fd9993 100644 --- a/include/osi_dma_txrx.h +++ b/include/osi_dma_txrx.h @@ -41,6 +41,11 @@ #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 RDES0_OVT 0x0000FFFFU #define RDES3_ES_BITS \ (RDES3_ERR_CRC | RDES3_ERR_GP | RDES3_ERR_WD | \ @@ -48,8 +53,13 @@ #define TDES2_IOC OSI_BIT(31) #define TDES3_OWN OSI_BIT(31) -#define TDES3_CTX OSI_BIT(30) +#define TDES3_CTXT OSI_BIT(30) #define TDES3_FD OSI_BIT(29) #define TDES3_LD OSI_BIT(28) +#define TDES3_VLTV OSI_BIT(16) +/* VTIR = 0x2 (Insert a VLAN tag with the tag value programmed in the + * MAC_VLAN_Incl register or context descriptor.) +*/ +#define TDES2_VTIR ((unsigned int)0x2 << 14U) #endif /* OSI_DMA_TXRX_H */ diff --git a/osi/eqos_core.c b/osi/eqos_core.c index fc03e8a..6ccca68 100644 --- a/osi/eqos_core.c +++ b/osi/eqos_core.c @@ -516,6 +516,26 @@ static void eqos_configure_mac(struct osi_core_priv_data *osi_core) value |= EQOS_IMR_RGSMIIIE; osi_writel(value, (unsigned char *)osi_core->base + EQOS_MAC_IMR); + + /* Enable VLAN configuration */ + value = osi_readl((unsigned char *)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 + */ + value |= EQOS_MAC_VLANTR_EVLS_ALWAYS_STRIP | EQOS_MAC_VLANTR_EVLRXS | + EQOS_MAC_VLANTR_DOVLTC; + value &= ~EQOS_MAC_VLANTR_ERIVLT; + osi_writel(value, (unsigned char *)osi_core->base + EQOS_MAC_VLAN_TAG); + + value = osi_readl((unsigned char *)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_writel(value, (unsigned char *)osi_core->base + EQOS_MAC_VLANTIR); } /** diff --git a/osi/eqos_core.h b/osi/eqos_core.h index 21d625a..008c3a2 100644 --- a/osi/eqos_core.h +++ b/osi/eqos_core.h @@ -55,6 +55,8 @@ #define EQOS_MAC_MA0HR 0x0300 #define EQOS_MAC_MA0LR 0x0304 #define EQOS_MAC_MCR 0x0000 +#define EQOS_MAC_VLAN_TAG 0x0050 +#define EQOS_MAC_VLANTIR 0x0060 #define EQOS_MAC_IMR 0x00B4 #define EQOS_DMA_ISR 0x1008 #define EQOS_MAC_ISR 0x00B0 @@ -110,6 +112,13 @@ #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 ((unsigned int)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_VLTI OSI_BIT(20) +#define EQOS_MAC_VLANTIRR_CSVL OSI_BIT(19) #define EQOS_DMA_SBUS_BLEN4 OSI_BIT(1) #define EQOS_DMA_SBUS_BLEN8 OSI_BIT(2) #define EQOS_DMA_SBUS_BLEN16 OSI_BIT(3) diff --git a/osi/osi_dma_txrx.c b/osi/osi_dma_txrx.c index 1c9b3b4..9f4c2ab 100644 --- a/osi/osi_dma_txrx.c +++ b/osi/osi_dma_txrx.c @@ -24,6 +24,37 @@ #include <osi_dma.h> #include <osi_dma_txrx.h> +static inline void osi_memset(void *s, int c, unsigned long count) +{ + char *xs = s; + int brk = 1; + + while (brk != 0) { + *xs++ = (char)c; + count--; + + if (count == 0U) { + brk = 0; + } + } +} + +static inline void get_rx_vlan_from_desc(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; + } + } +} + /** * osi_process_rx_completions - Read data from receive channel descriptors * @osi: OSI private data structure. @@ -48,10 +79,12 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, unsigned int chan, int budget) { struct osi_rx_ring *rx_ring = osi->rx_ring[chan]; + struct osi_rx_pkt_cx *rx_pkt_cx = &rx_ring->rx_pkt_cx; struct osi_rx_desc *rx_desc = OSI_NULL; - unsigned int pkt_len = 0; int received = 0; + osi_memset(rx_pkt_cx, 0, sizeof(*rx_pkt_cx)); + while (received < budget) { rx_desc = rx_ring->rx_desc + rx_ring->cur_rx_idx; @@ -61,12 +94,13 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, } /* get the length of the packet */ - pkt_len = rx_desc->rdes3 & RDES3_PKT_LEN; + rx_pkt_cx->pkt_len = rx_desc->rdes3 & RDES3_PKT_LEN; if (((rx_desc->rdes3 & RDES3_ES_BITS) == 0U) && ((rx_desc->rdes3 & RDES3_LD) == RDES3_LD)) { + get_rx_vlan_from_desc(rx_desc, rx_pkt_cx); osd_receive_packet(osi->osd, rx_ring, chan, - osi->rx_buf_len, pkt_len); + osi->rx_buf_len, rx_pkt_cx); } received++; @@ -152,7 +186,31 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan) unsigned int entry = tx_ring->cur_tx_idx; struct osi_tx_desc *tx_desc = tx_ring->tx_desc + entry; struct osi_tx_swcx *tx_swcx = tx_ring->tx_swcx + entry; + struct osi_tx_pkt_cx *tx_pkt_cx = &tx_ring->tx_pkt_cx; + unsigned int desc_cnt = tx_pkt_cx->desc_cnt; + struct osi_tx_desc *last_desc = OSI_NULL; + struct osi_tx_desc *first_desc = OSI_NULL; + struct osi_tx_desc *cx_desc = OSI_NULL; unsigned long tailptr; + unsigned int i; + + /* Context decriptor for VLAN */ + 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; + + INCR_TX_DESC_INDEX(entry, 1U); + + /* 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--; + } /* update the first buffer pointer and length */ tx_desc->tdes0 = (unsigned int)L32(tx_swcx->buf_phy_addr); @@ -160,15 +218,46 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan) tx_desc->tdes2 = tx_swcx->len; /* Mark it as First descriptor */ tx_desc->tdes3 |= TDES3_FD; - /* Mark it as LAST descriptor */ - tx_desc->tdes3 |= TDES3_LD; - /* set Interrupt on Completion*/ - tx_desc->tdes2 |= TDES2_IOC; - /* set HW OWN bit for descriptor*/ - tx_desc->tdes3 |= TDES3_OWN; + + /* 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; + } INCR_TX_DESC_INDEX(entry, 1U); + first_desc = tx_desc; + last_desc = tx_desc; + tx_desc = tx_ring->tx_desc + entry; + tx_swcx = tx_ring->tx_swcx + entry; + desc_cnt--; + + for (i = 0; i < desc_cnt; i++) { + tx_desc->tdes0 = (unsigned int)L32(tx_swcx->buf_phy_addr); + tx_desc->tdes1 = (unsigned int)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, 1U); + 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; + + /* Set OWN bit for first and context descriptors + * at the end to avoid race condition + */ + first_desc->tdes3 |= TDES3_OWN; + if ((tx_pkt_cx->flags & OSI_PKT_CX_VLAN) == OSI_PKT_CX_VLAN) { + cx_desc->tdes3 |= TDES3_OWN; + } + tailptr = tx_ring->tx_desc_phy_addr + (entry * sizeof(struct osi_tx_desc)); From f1ea1e87191a2bdf74305ef3210de399289ed0bd Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Wed, 17 Apr 2019 16:21:40 +0530 Subject: [PATCH 004/458] nvethernetrm: add adress width read support Add support for reading the Address Width from the MAC_HW_Feature1 register Bug 200458098 Change-Id: I32ae42f536fbac781584425dcccd91155542b579 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2099488 Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_common.h | 12 ++++++++++++ osi/osi_common.c | 2 ++ 2 files changed, 14 insertions(+) diff --git a/include/osi_common.h b/include/osi_common.h index 9773de6..504be08 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -23,6 +23,10 @@ #ifndef OSI_COMMON_H #define OSI_COMMON_H +#define OSI_ADDRESS_32BIT 0 +#define OSI_ADDRESS_40BIT 1 +#define OSI_ADDRESS_48BIT 2 + #define EQOS_DMA_CHX_STATUS(x) ((0x0080U * (x)) + 0x1160U) #define EQOS_DMA_CHX_IER(x) ((0x0080U * (x)) + 0x1134U) @@ -90,6 +94,7 @@ #define EQOS_MAC_HFR1_RXFIFOSIZE_MASK 0x1fU #define EQOS_MAC_HFR1_TXFIFOSIZE_MASK 0x1fU #define EQOS_MAC_HFR1_ADVTHWORD_MASK 0x1U +#define EQOS_MAC_HFR1_ADDR64_MASK 0x3U #define EQOS_MAC_HFR1_DCBEN_MASK 0x1U #define EQOS_MAC_HFR1_SPHEN_MASK 0x1U #define EQOS_MAC_HFR1_TSOEN_MASK 0x1U @@ -192,6 +197,12 @@ * 01010: 128 KB * 01011-11111: Reserved. * @adv_ts_hword: It set to 1 when Advance timestamping High Word selected. + * @addr_64: Address Width. + * This field indicates the configured address width: + * 00: 32 + * 01: 40 + * 10: 48 + * 11: Reserved * @dcb_en: It sets to 1 when DCB Feature Enable. * @sph_en: It sets to 1 when Split Header Feature Enable. * @tso_en: It sets to 1 when TCP Segmentation Offload Enable. @@ -259,6 +270,7 @@ struct osi_hw_features { unsigned int rx_fifo_size; unsigned int tx_fifo_size; unsigned int adv_ts_hword; + unsigned int addr_64; unsigned int dcb_en; unsigned int sph_en; unsigned int tso_en; diff --git a/osi/osi_common.c b/osi/osi_common.c index b51ba7c..ffa5209 100644 --- a/osi/osi_common.c +++ b/osi/osi_common.c @@ -89,6 +89,8 @@ void osi_get_hw_features(void *base, struct osi_hw_features *hw_feat) ((mac_hfr1 >> 6U) & EQOS_MAC_HFR1_TXFIFOSIZE_MASK); hw_feat->adv_ts_hword = ((mac_hfr1 >> 13U) & EQOS_MAC_HFR1_ADVTHWORD_MASK); + hw_feat->addr_64 = + ((mac_hfr1 >> 14U) & EQOS_MAC_HFR1_ADDR64_MASK); hw_feat->dcb_en = ((mac_hfr1 >> 16U) & EQOS_MAC_HFR1_DCBEN_MASK); hw_feat->sph_en = From a26d9d7152cb87bec2258fecac4540cd66496811 Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Wed, 3 Apr 2019 22:01:52 +0530 Subject: [PATCH 005/458] nvethernetrm: MAC loopback support When MAC HW loopback is enabled, MAC receives back all the packets that is being sent by it. Packets which were sent are looped inside the MAC and it is not being sent to PHY. Bug 200512681 Change-Id: Iec42e937824424c46eb15a281fb0c33e92ea2056 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2088985 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_common.h | 2 ++ include/osi_core.h | 32 +++++++++++++++++++++++++ osi/eqos_core.c | 56 ++++++++++++++++++++++++++++++++++++++++++++ osi/eqos_core.h | 3 +++ 4 files changed, 93 insertions(+) diff --git a/include/osi_common.h b/include/osi_common.h index 504be08..81f760d 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -37,6 +37,8 @@ #define OSI_ETH_ALEN 6U #define OSI_NULL ((void *)0) +#define OSI_ENABLE 1U +#define OSI_DISABLE 0U #define OSI_EQOS_MAX_NUM_CHANS 4U diff --git a/include/osi_core.h b/include/osi_core.h index 65eaffb..3643457 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -39,6 +39,7 @@ struct osi_core_priv_data; * @pad_calibrate: Called to do pad caliberation. * @set_mdc_clk_rate: Called to set MDC clock rate for MDIO operation. * @flush_mtl_tx_queue: Called to flush MTL Tx queue. + * @config_mac_loopback: Called to configure MAC in loopback mode. */ struct osi_core_ops { /* initialize MAC/MTL/DMA Common registers */ @@ -55,6 +56,7 @@ struct osi_core_ops { void (*set_mdc_clk_rate)(struct osi_core_priv_data *osi_core, unsigned long csr_clk_rate); int (*flush_mtl_tx_queue)(void *ioaddr, unsigned int qinx); + int (*config_mac_loopback)(void *addr, unsigned int lb_mode); }; /** @@ -315,6 +317,36 @@ static inline int osi_flush_mtl_tx_queue(struct osi_core_priv_data *osi_core, return ret; } +/** + * osi_config_mac_loopback - Configure MAC loopback + * @osi: OSI private data structure. + * @lb_mode: Enable or disable MAC loopback + * + * Algorithm: Configure the MAC to support the loopback. + * + * Dependencies: MAC IP should be out of reset + * and need to be initialized as the requirements + * + * Protection: None + * + * Return: 0 - success, -1 - failure. + */ +static inline int osi_config_mac_loopback(struct osi_core_priv_data *osi_core, + unsigned int lb_mode) +{ + int ret = -1; + + /* Configure MAC LoopBack */ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->config_mac_loopback != OSI_NULL)) { + ret = osi_core->ops->config_mac_loopback(osi_core->base, + lb_mode); + } + + return ret; +} + + int osi_write_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, unsigned int phyreg, unsigned short phydata); int osi_read_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, diff --git a/osi/eqos_core.c b/osi/eqos_core.c index 6ccca68..7d57ed0 100644 --- a/osi/eqos_core.c +++ b/osi/eqos_core.c @@ -27,6 +27,58 @@ struct osi_core_ops *eqos_get_hw_core_ops(void); +/** + * eqos_config_mac_loopback - Configure MAC to support loopback + * @addr: MAC base address. + * @lb_mode: Enable or Disable MAC loopback mode + * + * Algorithm: Configure MAC to enable or disable loopback + * + * Dependencies: MAC has to be out of reset. + * + * Protection: None. + * + * Return: 0 - success, -1 - failure + */ +static int eqos_config_mac_loopback(void *addr, unsigned int lb_mode) +{ + unsigned int clk_ctrl_val; + unsigned int mcr_val; + + /* 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 */ + mcr_val = osi_readl((unsigned char *)addr + EQOS_MAC_MCR); + + /* Read EQOS wrapper clock control 0 register */ + clk_ctrl_val = osi_readl((unsigned char *)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_writel(clk_ctrl_val, (unsigned char *)addr + EQOS_CLOCK_CTRL_0); + + /* Write to MAC Configuration Register */ + osi_writel(mcr_val, (unsigned char *)addr + EQOS_MAC_MCR); + + return 0; +} + /** * eqos_poll_for_swr - Poll for software reset (SWR bit in DMA Mode) * @addr: EQOS virtual base address. @@ -129,6 +181,9 @@ static void eqos_set_speed(void *base, int speed) mcr_val = osi_readl((unsigned char *)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; @@ -820,6 +875,7 @@ static struct osi_core_ops eqos_core_ops = { .pad_calibrate = eqos_pad_calibrate, .set_mdc_clk_rate = eqos_set_mdc_clk_rate, .flush_mtl_tx_queue = eqos_flush_mtl_tx_queue, + .config_mac_loopback = eqos_config_mac_loopback, }; struct osi_core_ops *eqos_get_hw_core_ops(void) diff --git a/osi/eqos_core.h b/osi/eqos_core.h index 008c3a2..a66e0a9 100644 --- a/osi/eqos_core.h +++ b/osi/eqos_core.h @@ -80,6 +80,7 @@ #define EQOS_PAD_AUTO_CAL_CFG 0x8804U #define EQOS_PAD_AUTO_CAL_STAT 0x880CU #define EQOS_PAD_CRTL 0x8800U +#define EQOS_CLOCK_CTRL_0 0x8000U /* EQOS Register BIT Masks */ #define EQOS_PAD_AUTO_CAL_CFG_ENABLE OSI_BIT(29) @@ -134,5 +135,7 @@ #define EQOS_DMA_SBUS_WR_OSR_LMT 0x1F000000U #define EQOS_MTL_TXQ_SIZE_SHIFT 16U #define EQOS_MTL_RXQ_SIZE_SHIFT 20U +#define EQOS_MAC_ENABLE_LM OSI_BIT(12) +#define EQOS_RX_CLK_SEL OSI_BIT(8) #endif From af9704c28171674f8ee7000d029c3ad0e536eafa Mon Sep 17 00:00:00 2001 From: Neil Patel <neilp@nvidia.com> Date: Mon, 22 Apr 2019 19:35:43 -0700 Subject: [PATCH 006/458] scripts: add checkpatch files This is needed to enable ACVU to run kernel checkpatch per commit. Jira COMTOOL-6 Change-Id: Iaaf951720cee59c4b530c36e20533729af5734b7 Signed-off-by: Neil Patel <neilp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2103095 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- scripts/checkpatch.pl | 6486 ++++++++++++++++++++++++++++++ scripts/const_structs.checkpatch | 64 + scripts/spelling.txt | 1250 ++++++ 3 files changed, 7800 insertions(+) create mode 100755 scripts/checkpatch.pl create mode 100644 scripts/const_structs.checkpatch create mode 100644 scripts/spelling.txt diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl new file mode 100755 index 0000000..fcb0dd1 --- /dev/null +++ b/scripts/checkpatch.pl @@ -0,0 +1,6486 @@ +#!/usr/bin/env perl +# (c) 2001, Dave Jones. (the file handling bit) +# (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit) +# (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite) +# (c) 2008-2010 Andy Whitcroft <apw@canonical.com> +# Licensed under the terms of the GNU GPL License version 2 + +use strict; +use warnings; +use POSIX; +use File::Basename; +use Cwd 'abs_path'; +use Term::ANSIColor qw(:constants); + +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 %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 = 80; +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; + +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: + <rev> + <rev>^ + <rev>~n + multiple git commits with: + <rev1>..<rev2> + <rev1>...<rev2> + <rev>-<count> + 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, if exceeded, warn + --min-conf-desc-length=n set the min description length, if shorter, warn + --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 + "<inputfile>.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'. + -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, + '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 + '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; + +my $exit = 0; + +if ($^V && $^V lt $minimum_perl_version) { + printf "$P: requires at least perl version %vd\n", $minimum_perl_version; + if (!$ignore_perl_version) { + exit(1); + } +} + +#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 "Invalid color mode: $color\n"; +} + +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| + __init_refok| + __kprobes| + __ref| + __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| + __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|)| + WARN(?:_RATELIMIT|_ONCE|)| + panic| + MODULE_[A-Z_]+| + seq_vprintf|seq_printf|seq_puts +)}; + +our $signature_tags = qr{(?xi: + Signed-off-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], +); + +#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]; +} + +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 $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 ($$wordsRef ne ""); + $$wordsRef .= $line; + } + close($file); + return 1; + } + + return 0; +} + +my $const_structs = ""; +read_words(\$const_structs, $conststructsfile) + or warn "No structs that should be const will be found - file '$conststructsfile': $!\n"; + +my $typeOtherTypedefs = ""; +if (length($typedefsfile)) { + read_words(\$typeOtherTypedefs, $typedefsfile) + or warn "No additional types will be considered - file '$typedefsfile': $!\n"; +} +$typeTypedefs .= '|' . $typeOtherTypedefs if ($typeOtherTypedefs ne ""); + +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*\])+)? + (?:\s+$Inline|\s+$Modifier)* + }x; + $TypeMisordered = qr{ + $NonptrTypeMisordered + (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)? + (?:\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*\(| + (?:$Storage\s+)?${Type}\s+uninitialized_var\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; + } + } +} + +sub is_maintained_obsolete { + my ($filename) = @_; + + return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl")); + + my $status = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`; + + return $status =~ /obsolete/i; +} + +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 ".git") { + my $git_last_include_commit = `git 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 ".git") { + $files = `git 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_commit_info { + my ($commit, $id, $desc) = @_; + + return ($id, $desc) if ((which("git") eq "") || !(-e ".git")); + + my $output = `git 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 ".git"); + +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 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; +for my $filename (@ARGV) { + my $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, $_); + } + 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(); +} + +if (!$quiet) { + hash_show_words(\%use_type, "Used"); + hash_show_words(\%ignore_type, "Ignored"); + + if ($^V lt 5.10.0) { + print << "EOM" + +NOTE: perl $^V is not modern enough to detect all possible issues. + An upgrade to at least perl v5.10.0 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 $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/$address.*$//; + $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 <joe@smith.com" bad + if ($name ne "" && $address !~ /^<[^>]+>$/) { + $name = ""; + $address = ""; + $comment = ""; + } + } + + $name = trim($name); + $name =~ s/^\"|\"$//g; + $address = trim($address); + $address =~ s/^\<|\>$//g; + + if ($name =~ /[^\w \-]/i) { ##has "must quote" chars + $name =~ s/(?<!\\)"/\\"/g; ##escape quotes + $name = "\"$name\""; + } + + return ($name, $address, $comment); +} + +sub format_email { + my ($name, $address) = @_; + + my $formatted_email; + + $name = trim($name); + $name =~ s/^\"|\"$//g; + $address = trim($address); + + if ($name =~ /[^\w \-]/i) { ##has "must quote" chars + $name =~ s/(?<!\\)"/\\"/g; ##escape quotes + $name = "\"$name\""; + } + + if ("$name" eq "") { + $formatted_email = "$address"; + } else { + $formatted_email = "$name <$address>"; + } + + return $formatted_email; +} + +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 % 8) != 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 wacking completly 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 ($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) = @_; + + # Catch a comment on the end of the line itself. + my ($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 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 = 8; + 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 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 $is_patch = 0; + my $in_header_lines = $file ? 0 : 1; + my $in_commit_log = 0; #Scanning lines before patch + my $has_commit_log = 0; #Encountered lines before patch + 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; + + 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.rst$@) { + $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]; + +#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-<architecture>\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; + } + 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); + +# 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 signoff: + if ($line =~ /^\s*signed-off-by:/i) { + $signoff++; + $in_commit_log = 0; + } + +# 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 + 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, $email_address, $comment) = parse_email($email); + my $suggested_email = format_email(($email_name, $email_address)); + if ($suggested_email eq "") { + ERROR("BAD_SIGN_OFF", + "Unrecognized email address: '$email'\n" . $herecurr); + } else { + my $dequoted = $suggested_email; + $dequoted =~ s/^"//; + $dequoted =~ s/" </ </; + # Don't force email to have quotes + # Allow just an angle bracketed address + if ("$dequoted$comment" ne $email && + "<$email_address>$comment" ne $email && + "$suggested_email$comment" ne $email) { + WARN("BAD_SIGN_OFF", + "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr); + } + } + +# Check for duplicate signatures + my $sig_nospace = $line; + $sig_nospace =~ s/\s//g; + $sig_nospace = lc($sig_nospace); + if (defined $signatures{$sig_nospace}) { + WARN("BAD_SIGN_OFF", + "Duplicate signature\n" . $herecurr); + } else { + $signatures{$sig_nospace} = 1; + } + } + +# Check email subject for common tools that don't need to be mentioned + if ($in_header_lines && + $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) { + WARN("EMAIL_SUBJECT", + "A patch subject line should describe the change not the tool that found it\n" . $herecurr); + } + +# Check for old stable address + if ($line =~ /^\s*cc:\s*.*<?\bstable\@kernel\.org\b>?.*$/i) { + ERROR("STABLE_ADDRESS", + "The 'stable' address should be 'stable\@vger.kernel.org'\n" . $herecurr); + } + +# Check for unwanted Gerrit info + if ($in_commit_log && !$ignore_changeid && $line =~ /^\s*change-id:/i) { + ERROR("GERRIT_CHANGE_ID", + "Remove Gerrit Change-Id's before submitting upstream.\n" . $herecurr); + } + +# Check if the commit log is in a possible stack dump + if ($in_commit_log && !$commit_log_possible_stack_dump && + ($line =~ /^\s*(?:WARNING:|BUG:)/ || + $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ || + # timestamp + $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/)) { + # stack dump address + $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):/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> (\"<title line>\")' - 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 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/; + } + } + } + +# 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/ && + $line =~ /^\+\s*config\s+/) { + 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)\s*\"/) { + $is_start = 1; + } elsif ($lines[$ln - 1] =~ /^\+\s*(?:---)?help(?:---)?$/) { + $length = -1; + } + + $f =~ s/^.//; + $f =~ s/#.*//; + $f =~ s/^\s+//; + next if ($f =~ /^$/); + if ($f =~ /^\s*config\s/) { + $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 for MAINTAINERS entries that don't have the right form + if ($realfile =~ /^MAINTAINERS$/ && + $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/; + } + } + +# 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.txt"; + + 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 "^$vendor\\b" $vp_file`; + if ( $? >> 8 ) { + WARN("UNDOCUMENTED_DT_STRING", + "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_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)$/); + +# 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 +# +# 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 = ""; + + # EFI_GUID is another special case + } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/) { + $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))) { + WARN($msg_type, + "line over $max_line_length characters\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); + } + +# Blackfin: use hi/lo macros + if ($realfile =~ m@arch/blackfin/.*\.S$@) { + if ($line =~ /\.[lL][[:space:]]*=.*&[[:space:]]*0x[fF][fF][fF][fF]/) { + my $herevet = "$here\n" . cat_vet($line) . "\n"; + ERROR("LO_MACRO", + "use the LO() macro, not (... & 0xFFFF)\n" . $herevet); + } + if ($line =~ /\.[hH][[:space:]]*=.*>>[[:space:]]*16/) { + my $herevet = "$here\n" . cat_vet($line) . "\n"; + ERROR("HI_MACRO", + "use the HI() macro, not (... >> 16)\n" . $herevet); + } + } + +# 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 8 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/(^\+.*) {8,8}\t/$1\t\t/) {} + while ($fixed[$fixlinenr] =~ + s/(^\+.*) +\t/$1\t/) {} + } + } + +# 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 ($^V && $^V ge 5.10.0 && + $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$))/) { + my $indent = length($1); + if ($indent % 8) { + if (WARN("TABSTOP", + "Statements should start on a tabstop\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/8)@e; + } + } + } + +# check multi-line statement indentation matches previous line + if ($^V && $^V ge 5.10.0 && + $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 / 8) . + " " x ($pos % 8); + 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 > 2) { + 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*__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+(?: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 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); + } + +# Blackfin: don't use __builtin_bfin_[cs]sync + if ($line =~ /__builtin_bfin_csync/) { + my $herevet = "$here\n" . cat_vet($line) . "\n"; + ERROR("CSYNC", + "use the CSYNC() macro in asm/blackfin.h\n" . $herevet); + } + if ($line =~ /__builtin_bfin_ssync/) { + my $herevet = "$here\n" . cat_vet($line) . "\n"; + ERROR("SSYNC", + "use the SSYNC() macro in asm/blackfin.h\n" . $herevet); + } + +# 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 % 8) != 0 || + ($sindent < $indent) || + ($sindent == $indent && + ($s !~ /^\s*(?:\}|\{|else\b)/)) || + ($sindent > $indent + 8))) { + 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 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 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 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. Note that follow on printk's on the +# same line do not need a level, so we use the current block context +# to try and find and validate the current printk. In summary the current +# printk includes all preceding printk's which have no newline on the end. +# we assume the first bad printk is the one to report. + if ($line =~ /\bprintk\((?!KERN_)\s*"/) { + my $ok = 0; + for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) { + #print "CHECK<$lines[$ln - 1]\n"; + # we have a preceding printk if it ends + # with "\n" ignore it, else it is to blame + if ($lines[$ln - 1] =~ m{\bprintk\(}) { + if ($rawlines[$ln - 1] !~ m{\\n"}) { + $ok = 1; + } + last; + } + } + if ($ok == 0) { + WARN("PRINTK_WITHOUT_KERN_LEVEL", + "printk() should include KERN_ 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 =~ /\bpr_warning\s*\(/) { + if (WARN("PREFER_PR_LEVEL", + "Prefer pr_warn(... to pr_warning(...\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ + s/\bpr_warning\b/pr_warn/; + } + } + + 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); + } + +# 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); + } + +# function brace can't be on same line, except for #defines of do while, +# or if closed on same line + if (($line=~/$Type\s*$Ident\(.*\).*\s*{/) and + !($line=~/\#\s*define.*do\s\{/) and !($line=~/}/)) { + if (ERROR("OPEN_BRACE", + "open brace '{' following function declarations 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 =~ /do\{/) { + if (ERROR("SPACING", + "space required before the open brace '{'\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/^(\+.*(?:do|\)))\{/$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 + if ($^V && $^V ge 5.10.0 && 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/; + } + } + +# return is not a function + if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) { + my $spacing = $1; + if ($^V && $^V ge 5.10.0 && + $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 ($^V && $^V ge 5.10.0 && + $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 ($^V && $^V ge 5.10.0 && + $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) { + ERROR("ASSIGN_IN_IF", + "do not use assignment in if condition\n" . $herecurr); + } + + # 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; + +#gcc binary extension + if ($var =~ /^$Binary$/) { + if (WARN("GCC_BINARY_CONSTANT", + "Avoid gcc v4.3+ binary constant extension: <$var>\n" . $herecurr) && + $fix) { + my $hexval = sprintf("0x%x", oct($var)); + $fixed[$fixlinenr] =~ + s/\b$var\b/$hexval/; + } + } + +#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) + $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_[a-z_]+)?$/ && +#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; + @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/\([^\(\)]*\)/1/ || + $dstat =~ s/\{[^\{\}]*\}/1/ || + $dstat =~ s/.\[[^\[\]]*\]/1/) + { + } + + # Flatten any obvious string concatentation. + 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 $herectx = $here . "\n"; + my $stmt_cnt = statement_rawlines($ctx); + + for (my $n = 0; $n < $stmt_cnt; $n++) { + $herectx .= raw_line($linenr, $n) . "\n"; + } + + 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 !~ /^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(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 =~ s/\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 $herectx = $here . "\n"; + my $cnt = statement_rawlines($ctx); + + for (my $n = 0; $n < $cnt; $n++) { + $herectx .= raw_line($linenr, $n) . "\n"; + } + 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 ($^V && $^V ge 5.10.0 && + $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 = $here . "\n"; + + for (my $n = 0; $n < $cnt; $n++) { + $herectx .= raw_line($linenr, $n) . "\n"; + } + + 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 = $here . "\n"; + + for (my $n = 0; $n < $cnt; $n++) { + $herectx .= raw_line($linenr, $n) . "\n"; + } + + WARN("TRAILING_SEMICOLON", + "macros should not use a trailing semicolon\n" . "$herectx"); + } + } + +# make sure symbols are always wrapped with VMLINUX_SYMBOL() ... +# all assignments may have only one of the following with an assignment: +# . +# ALIGN(...) +# VMLINUX_SYMBOL(...) + if ($realfile eq 'vmlinux.lds.h' && $line =~ /(?:(?:^|\s)$Ident\s*=|=\s*$Ident(?:\s|$))/) { + WARN("MISSING_VMLINUX_SYMBOL", + "vmlinux.lds.h needs VMLINUX_SYMBOL() around C-visible symbols\n" . $herecurr); + } + +# 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 $herectx = $here . "\n"; + my $cnt = statement_rawlines($block); + + for (my $n = 0; $n < $cnt; $n++) { + $herectx .= raw_line($linenr, $n) . "\n"; + } + + 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-Z_]/ || $line =~ /[A-Za-z0-9_]$String/) { + CHK("CONCATENATED_STRING", + "Concatenated strings should use spaces between elements\n" . $herecurr); + } + +# uncoalesced string fragments + if ($line =~ /$String\s*"/) { + WARN("STRING_FRAGMENTS", + "Consecutive strings are generally better as a single string\n" . $herecurr); + } + +# 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 =~ /\\$/ && $rawline =~ 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/) { + CHK("REDUNDANT_CODE", + "if this code is redundant consider removing it\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*(?:devm_)?(?:[kv][czm]alloc(?:_node|_array)?\b|kstrdup|kmemdup|(?:dev_)?alloc_skb)/) { + 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 ($^V && $^V ge 5.10.0 && + $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 ($^V && $^V ge 5.10.0) { + 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.txt\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.txt\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| + read_barrier_depends + }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 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__ 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 ($^V && $^V ge 5.10.0 && + $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 ($^V && $^V ge 5.10.0 && + defined $stat && + $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s && + $1 !~ /^_*volatile_*$/) { + my $bad_extension = ""; + my $lc = $stat =~ tr@\n@@; + $lc = $lc + $linenr; + for (my $count = $linenr; $count <= $lc; $count++) { + my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0)); + $fmt =~ s/%%//g; + if ($fmt =~ /(\%[\*\d\.]*p(?![\WFfSsBKRraEhMmIiUDdgVCbGNO]).)/) { + $bad_extension = $1; + last; + } + } + if ($bad_extension ne "") { + my $stat_real = raw_line($linenr, 0); + for (my $count = $linenr + 1; $count <= $lc; $count++) { + $stat_real = $stat_real . "\n" . raw_line($count, 0); + } + WARN("VSPRINTF_POINTER_EXTENSION", + "Invalid vsprintf pointer extension '$bad_extension'\n" . "$here\n$stat_real\n"); + } + } + +# Check for misused memsets + if ($^V && $^V ge 5.10.0 && + 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 ($^V && $^V ge 5.10.0 && +# 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 ($^V && $^V ge 5.10.0 && +# 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 ($^V && $^V ge 5.10.0 && +# 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 ($^V && $^V ge 5.10.0 && + 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 ($^V && $^V ge 5.10.0 && + 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.txt\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.txt\n" . "$here\n$stat\n"); + } + } + +# check for naked sscanf + if ($^V && $^V ge 5.10.0 && + 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 = raw_line($linenr, 0); + for (my $count = $linenr + 1; $count <= $lc; $count++) { + $stat_real = $stat_real . "\n" . raw_line($count, 0); + } + WARN("NAKED_SSCANF", + "unchecked sscanf return value\n" . "$here\n$stat_real\n"); + } + +# check for simple sscanf that should be kstrto<foo> + if ($^V && $^V ge 5.10.0 && + defined $stat && + $line =~ /\bsscanf\b/) { + my $lc = $stat =~ tr@\n@@; + $lc = $lc + $linenr; + my $stat_real = raw_line($linenr, 0); + for (my $count = $linenr + 1; $count <= $lc; $count++) { + $stat_real = $stat_real . "\n" . raw_line($count, 0); + } + 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*;/ && + $function_name ne 'uninitialized_var') + { + 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*([^{]+)\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 ($^V && $^V ge 5.10.0 && + 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.rst\n" . $herecurr); + } + } + +# check for pointless casting of kmalloc return + if ($line =~ /\*\s*\)\s*[kv][czm]alloc(_node){0,1}\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 ($^V && $^V ge 5.10.0 && + $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*([kv][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 ($^V && $^V ge 5.10.0 && + 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 $ctx = ''; + my $herectx = $here . "\n"; + my $cnt = statement_rawlines($stat); + for (my $n = 0; $n < $cnt; $n++) { + $herectx .= raw_line($linenr, $n) . "\n"; + } + 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 ($^V && $^V ge 5.10.0 && + $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*\1\s*,/) { + 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 #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 case / default statements not preceded by break/fallthrough/switch + if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) { + my $has_break = 0; + my $has_statement = 0; + my $count = 0; + my $prevline = $linenr; + while ($prevline > 1 && ($file || $count < 3) && !$has_break) { + $prevline--; + my $rline = $rawlines[$prevline - 1]; + my $fline = $lines[$prevline - 1]; + last if ($fline =~ /^\@\@/); + next if ($fline =~ /^\-/); + next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/); + $has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i); + next if ($fline =~ /^.[\s$;]*$/); + $has_statement = 1; + $count++; + $has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|return\b|goto\b|continue\b)/); + } + if (!$has_break && $has_statement) { + WARN("MISSING_BREAK", + "Possible switch case/default not preceded by break or fallthrough comment\n" . $herecurr); + } + } + +# check for switch/default statements without a break; + if ($^V && $^V ge 5.10.0 && + defined $stat && + $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) { + my $ctx = ''; + my $herectx = $here . "\n"; + my $cnt = statement_rawlines($stat); + for (my $n = 0; $n < $cnt; $n++) { + $herectx .= raw_line($linenr, $n) . "\n"; + } + 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 various structs that are normally const (ops, kgdb, device_tree) +# and avoid what seem like struct definitions 'struct foo {' + if ($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 ($^V && $^V ge 5.10.0 && + $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) { + WARN("LIKELY_MISUSE", + "Using $1 should generally have parentheses around the comparison\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); + } + } + +# whine about ACCESS_ONCE + if ($^V && $^V ge 5.10.0 && + $line =~ /\bACCESS_ONCE\s*$balanced_parens\s*(=(?!=))?\s*($FuncArg)?/) { + my $par = $1; + my $eq = $2; + my $fun = $3; + $par =~ s/^\(\s*(.*)\s*\)$/$1/; + if (defined($eq)) { + if (WARN("PREFER_WRITE_ONCE", + "Prefer WRITE_ONCE(<FOO>, <BAR>) over ACCESS_ONCE(<FOO>) = <BAR>\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)\s*$eq\s*\Q$fun\E/WRITE_ONCE($par, $fun)/; + } + } else { + if (WARN("PREFER_READ_ONCE", + "Prefer READ_ONCE(<FOO>) over ACCESS_ONCE(<FOO>)\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)/READ_ONCE($par)/; + } + } + } + +# 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); + } + +# Mode permission misuses where it seems decimal should be octal +# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop + if ($^V && $^V ge 5.10.0 && + 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 = raw_line($linenr, 0); + for (my $count = $linenr + 1; $count <= $lc; $count++) { + $stat_real = $stat_real . "\n" . raw_line($count, 0); + } + + 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 (($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 + if ($line =~ /\b$mode_perms_string_search\b/) { + my $val = ""; + my $oval = ""; + my $to = 0; + my $curpos = 0; + my $lastpos = 0; + while ($line =~ /\b(($mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) { + $curpos = pos($line); + 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*$//; + my $octal = sprintf("%04o", $to); + if (WARN("SYMBOLIC_PERMS", + "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/$val/$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); + } + } + } + + # 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 && $signoff == 0) { + ERROR("MISSING_SIGN_OFF", + "Missing Signed-off-by: line(s)\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 new file mode 100644 index 0000000..ac5f126 --- /dev/null +++ b/scripts/const_structs.checkpatch @@ -0,0 +1,64 @@ +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 +pipe_buf_operations +platform_hibernation_ops +platform_suspend_ops +proto_ops +regmap_access_table +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 new file mode 100644 index 0000000..aa0cc49 --- /dev/null +++ b/scripts/spelling.txt @@ -0,0 +1,1250 @@ +# 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 +abitrate||arbitrate +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 +accoding||according +accomodate||accommodate +accomodates||accommodates +accordign||according +accoring||according +accout||account +accquire||acquire +accquired||acquired +accross||across +acessable||accessible +acess||access +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 +acumulator||accumulator +adapater||adapter +addional||additional +additionaly||additionally +additonal||additional +addres||address +adddress||address +addreses||addresses +addresss||address +aditional||additional +aditionally||additionally +aditionaly||additionally +adminstrative||administrative +adress||address +adresses||addresses +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 +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 +altough||although +alue||value +ambigious||ambiguous +amoung||among +amout||amount +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 +aritmetic||arithmetic +arne't||aren't +arraival||arrival +artifical||artificial +artillary||artillery +asign||assign +asser||assert +assertation||assertion +assiged||assigned +assigment||assignment +assigments||assignments +assistent||assistant +assocation||association +associcated||associated +assotiated||associated +assum||assume +assumtpion||assumption +asuming||assuming +asycronous||asynchronous +asynchnous||asynchronous +atomatically||automatically +atomicly||atomically +atempt||attempt +attachement||attachment +attched||attached +attemps||attempts +attemping||attempting +attruibutes||attributes +authentification||authentication +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 +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 +broadcat||broadcast +cacluated||calculated +caculation||calculation +calender||calendar +calescing||coalescing +calle||called +callibration||calibration +calucate||calculate +calulate||calculate +cancelation||cancellation +cancle||cancel +capabilites||capabilities +capabilty||capability +capabitilies||capabilities +capatibilities||capabilities +capapbilities||capabilities +carefuly||carefully +cariage||carriage +catagory||category +cehck||check +challange||challenge +challanges||challenges +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 +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 +coexistance||coexistence +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 +compatability||compatibility +compatable||compatible +compatibiliy||compatibility +compatibilty||compatibility +compatiblity||compatibility +competion||completion +compilant||compliant +compleatly||completely +completition||completion +completly||completely +complient||compliant +componnents||components +compoment||component +compres||compress +compresion||compression +comression||compression +comunication||communication +conbination||combination +conditionaly||conditionally +conected||connected +connecetd||connected +configuartion||configuration +configuratoin||configuration +configuraton||configuration +configuretion||configuration +configutation||configuration +conider||consider +conjuction||conjunction +connectinos||connections +connnection||connection +connnections||connections +consistancy||consistency +consistant||consistent +containes||contains +containts||contains +contaisn||contains +contant||contact +contence||contents +continious||continuous +continous||continuous +continously||continuously +continueing||continuing +contraints||constraints +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 +decompres||decompress +decription||description +dectected||detected +defailt||default +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 +demodualtor||demodulator +demension||dimension +dependancies||dependencies +dependancy||dependency +dependant||dependent +depreacted||deprecated +depreacte||deprecate +desactivate||deactivate +desciptor||descriptor +desciptors||descriptors +descripton||description +descrition||description +descritptor||descriptor +desctiptor||descriptor +desriptor||descriptor +desriptors||descriptors +destionation||destination +destory||destroy +destoryed||destroyed +destorys||destroys +destroied||destroyed +detabase||database +deteced||detected +develope||develop +developement||development +developped||developed +developpement||development +developper||developer +developpment||development +deveolpment||development +devided||divided +deviece||device +diable||disable +dictionnary||dictionary +didnt||didn't +diferent||different +differrence||difference +diffrent||different +diffrentiate||differentiate +difinition||definition +dimesions||dimensions +diplay||display +direectly||directly +disassocation||disassociation +disapear||disappear +disapeared||disappeared +disappared||disappeared +disble||disable +disbled||disabled +disconnet||disconnect +discontinous||discontinuous +dispertion||dispersion +dissapears||disappears +distiction||distinction +docuentation||documentation +documantation||documentation +documentaion||documentation +documment||document +doesnt||doesn't +dorp||drop +dosen||doesn +downlad||download +downlads||downloads +druing||during +dynmaic||dynamic +easilly||easily +ecspecially||especially +edditable||editable +editting||editing +efective||effective +efficently||efficiently +ehther||ether +eigth||eight +elementry||elementary +eletronic||electronic +embeded||embedded +enabledi||enabled +enchanced||enhanced +encorporating||incorporating +encrupted||encrypted +encrypiton||encryption +encryptio||encryption +endianess||endianness +enhaced||enhanced +enlightnment||enlightenment +entrys||entries +enocded||encoded +enterily||entirely +enviroiment||environment +enviroment||environment +environement||environment +environent||environment +eqivalent||equivalent +equiped||equipped +equivelant||equivalent +equivilant||equivalent +eror||error +errorr||error +estbalishment||establishment +etsablishment||establishment +etsbalishment||establishment +excecutable||executable +exceded||exceeded +excellant||excellent +exeed||exceed +existance||existence +existant||existent +exixt||exist +exlcude||exclude +exlcusive||exclusive +exmaple||example +expecially||especially +explicite||explicit +explicitely||explicitly +explict||explicit +explictely||explicitly +explictly||explicitly +expresion||expression +exprimental||experimental +extened||extended +extensability||extensibility +extention||extension +extracter||extractor +falied||failed +faild||failed +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 +fimware||firmware +firware||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 +framming||framing +framwork||framework +frequncy||frequency +frome||from +fucntion||function +fuction||function +fuctions||functions +funcion||function +functionallity||functionality +functionaly||functionally +functionnality||functionality +functonality||functionality +funtion||function +funtions||functions +furthur||further +futhermore||furthermore +futrue||future +gaurenteed||guaranteed +generiously||generously +genereate||generate +genric||generic +globel||global +grabing||grabbing +grahical||graphical +grahpical||graphical +grapic||graphic +grranted||granted +guage||gauge +guarenteed||guaranteed +guarentee||guarantee +halfs||halves +hander||handler +handfull||handful +hanled||handled +happend||happened +harware||hardware +heirarchically||hierarchically +helpfull||helpful +hybernate||hibernate +hierachy||hierarchy +hierarchie||hierarchy +howver||however +hsould||should +hypervior||hypervisor +hypter||hyper +identidier||identifier +iligal||illegal +illigal||illegal +imblance||imbalance +immeadiately||immediately +immedaite||immediate +immediatelly||immediately +immediatly||immediately +immidiate||immediate +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 +inconsistant||inconsistent +increas||increase +incremeted||incremented +incrment||increment +indendation||indentation +indended||intended +independant||independent +independantly||independently +independed||independent +indiate||indicate +indicat||indicate +inexpect||inexpected +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 +initializiation||initialization +initialzed||initialized +initilization||initialization +initilize||initialize +inofficial||unofficial +insititute||institute +instal||install +instanciated||instantiated +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 +interrface||interface +interrrupt||interrupt +interrup||interrupt +interrups||interrupts +interruptted||interrupted +interupted||interrupted +interupt||interrupt +intial||initial +intialisation||initialisation +intialised||initialised +intialise||initialise +intialization||initialization +intialized||initialized +intialize||initialize +intregral||integral +intrrupt||interrupt +intterrupt||interrupt +intuative||intuitive +invaid||invalid +invald||invalid +invalde||invalid +invalide||invalid +invalidiate||invalidate +invalud||invalid +invididual||individual +invokation||invocation +invokations||invocations +irrelevent||irrelevant +isnt||isn't +isssue||issue +iternations||iterations +itertation||iteration +itslef||itself +jave||java +jeffies||jiffies +juse||just +jus||just +kown||known +langage||language +langauage||language +langauge||language +langugage||language +lauch||launch +layed||laid +leightweight||lightweight +lengh||length +lenght||length +lenth||length +lesstiff||lesstif +libaries||libraries +libary||library +librairies||libraries +libraris||libraries +licenceing||licencing +loggging||logging +loggin||login +logile||logfile +loosing||losing +losted||lost +machinary||machinery +maintainance||maintenance +maintainence||maintenance +maintan||maintain +makeing||making +malplaced||misplaced +malplace||misplace +managable||manageable +managment||management +mangement||management +manoeuvering||maneuvering +mappping||mapping +mathimatical||mathematical +mathimatic||mathematic +mathimatics||mathematics +maxium||maximum +mechamism||mechanism +meetign||meeting +ment||meant +mergable||mergeable +mesage||message +messags||messages +messgaes||messages +messsage||message +messsages||messages +micropone||microphone +microprocesspr||microprocessor +milliseonds||milliseconds +minium||minimum +minimam||minimum +minumum||minimum +misalinged||misaligned +miscelleneous||miscellaneous +misformed||malformed +mispelled||misspelled +mispelt||misspelt +mising||missing +mismactch||mismatch +missmanaged||mismanaged +missmatch||mismatch +miximum||maximum +mmnemonic||mnemonic +mnay||many +modulues||modules +momery||memory +memomry||memory +monochorome||monochrome +monochromo||monochrome +monocrome||monochrome +mopdule||module +mroe||more +mulitplied||multiplied +multidimensionnal||multidimensional +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 +notications||notifications +notifed||notified +numebr||number +numner||number +obtaion||obtain +occassionally||occasionally +occationally||occasionally +occurance||occurrence +occurances||occurrences +occured||occurred +occurence||occurrence +occure||occurred +occured||occurred +occuring||occurring +offet||offset +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 +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 +pallette||palette +paln||plan +paramameters||parameters +paramaters||parameters +paramater||parameter +parametes||parameters +parametised||parametrised +paramter||parameter +paramters||parameters +particuarly||particularly +particularily||particularly +partiton||partition +pased||passed +passin||passing +pathes||paths +pecularities||peculiarities +peformance||performance +peice||piece +pendantic||pedantic +peprocessor||preprocessor +perfoming||performing +permissons||permissions +peroid||period +persistance||persistence +persistant||persistent +plalform||platform +platfrom||platform +plattform||platform +pleaes||please +ploting||plotting +plugable||pluggable +poinnter||pointer +pointeur||pointer +poiter||pointer +posible||possible +positon||position +possibilites||possibilities +powerfull||powerful +preample||preamble +preapre||prepare +preceeded||preceded +preceeding||preceding +preceed||precede +precendence||precedence +precission||precision +preemptable||preemptible +prefered||preferred +prefferably||preferably +premption||preemption +prepaired||prepared +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 +progams||programs +progess||progress +programers||programmers +programm||program +programms||programs +progresss||progress +promiscous||promiscuous +promps||prompts +pronnounced||pronounced +prononciation||pronunciation +pronouce||pronounce +pronunce||pronounce +propery||property +propigate||propagate +propigation||propagation +propogate||propagate +prosess||process +protable||portable +protcol||protocol +protecion||protection +protocoll||protocol +promixity||proximity +psudo||pseudo +psuedo||pseudo +psychadelic||psychedelic +pwoer||power +quering||querying +randomally||randomly +raoming||roaming +reasearcher||researcher +reasearchers||researchers +reasearch||research +recepient||recipient +receving||receiving +recieved||received +recieve||receive +reciever||receiver +recieves||receives +recogniced||recognised +recognizeable||recognizable +recommanded||recommended +recyle||recycle +redircet||redirect +redirectrion||redirection +reename||rename +refcounf||refcount +refence||reference +refered||referred +referenace||reference +refering||referring +refernces||references +refernnce||reference +refrence||reference +registerd||registered +registeresd||registered +registerred||registered +registes||registers +registraration||registration +regsiter||register +regster||register +regualar||regular +reguator||regulator +regulamentations||regulations +reigstration||registration +releated||related +relevent||relevant +remoote||remote +remore||remote +removeable||removable +repectively||respectively +replacable||replaceable +replacments||replacements +replys||replies +reponse||response +representaion||representation +reqeust||request +requestied||requested +requiere||require +requirment||requirement +requred||required +requried||required +requst||request +reseting||resetting +resizeable||resizable +resouce||resource +resouces||resources +resoures||resources +responce||response +ressizes||resizes +ressource||resource +ressources||resources +retransmited||retransmitted +retreived||retrieved +retreive||retrieve +retrive||retrieve +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 +scaned||scanned +scaning||scanning +scarch||search +seach||search +searchs||searches +secquence||sequence +secund||second +segement||segment +senarios||scenarios +sentivite||sensitive +separatly||separately +sepcify||specify +sepc||spec +seperated||separated +seperately||separately +seperate||separate +seperatly||separately +seperator||separator +sepperate||separate +sequece||sequence +sequencial||sequential +serveral||several +setts||sets +settting||setting +shotdown||shutdown +shoud||should +shouldnt||shouldn't +shoule||should +shrinked||shrunk +siginificantly||significantly +signabl||signal +similary||similarly +similiar||similar +simlar||similar +simliar||similar +simpified||simplified +singaled||signaled +singal||signal +singed||signed +sleeped||slept +softwares||software +speach||speech +specfic||specific +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 +staticly||statically +stoped||stopped +stoppped||stopped +straming||streaming +struc||struct +structres||structures +stuct||struct +strucuture||structure +stucture||structure +sturcture||structure +subdirectoires||subdirectories +suble||subtle +substract||subtract +submition||submission +succesfully||successfully +succesful||successful +successed||succeeded +successfull||successful +successfuly||successfully +sucessfully||successfully +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 +suspicously||suspiciously +swaping||swapping +switchs||switches +swith||switch +swithable||switchable +swithc||switch +swithced||switched +swithcing||switching +swithed||switched +swithing||switching +swtich||switch +symetric||symmetric +synax||syntax +synchonized||synchronized +syncronize||synchronize +syncronized||synchronized +syncronizing||synchronizing +syncronus||synchronous +syste||system +sytem||system +sythesis||synthesis +taht||that +targetted||targeted +targetting||targeting +teh||the +temorary||temporary +temproarily||temporarily +therfore||therefore +thier||their +threds||threads +threshhold||threshold +thresold||threshold +throught||through +troughput||throughput +thses||these +tiggered||triggered +tipically||typically +timout||timeout +tmis||this +torerable||tolerable +tramsmitted||transmitted +tramsmit||transmit +tranasction||transaction +tranfer||transfer +transciever||transceiver +transferd||transferred +transfered||transferred +transfering||transferring +transision||transition +transmittd||transmitted +transormed||transformed +trasfer||transfer +trasmission||transmission +treshold||threshold +trigerring||triggering +trun||turn +tunning||tuning +ture||true +tyep||type +udpate||update +uesd||used +uncommited||uncommitted +unconditionaly||unconditionally +underun||underrun +unecessary||unnecessary +unexecpted||unexpected +unexepected||unexpected +unexpcted||unexpected +unexpectd||unexpected +unexpeted||unexpected +unexpexted||unexpected +unfortunatelly||unfortunately +unifiy||unify +unintialized||uninitialized +unkmown||unknown +unknonw||unknown +unknow||unknown +unkown||unknown +unneded||unneeded +unneedingly||unnecessarily +unnsupported||unsupported +unmached||unmatched +unregester||unregister +unresgister||unregister +unrgesiter||unregister +unsinged||unsigned +unstabel||unstable +unsolicitied||unsolicited +unsuccessfull||unsuccessful +unsuported||unsupported +untill||until +unuseful||useless +upate||update +usefule||useful +usefull||useful +usege||usage +usera||users +usualy||usually +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 +verisons||versions +verison||version +verson||version +vicefersa||vice-versa +virtal||virtual +virtaul||virtual +virtiual||virtual +visiters||visitors +vitual||virtual +wakeus||wakeups +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 +zombe||zombie +zomebie||zombie From 92bb6a6418f580bfd83378cff5e19daceef6dd63 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Mon, 8 Apr 2019 15:07:10 +0530 Subject: [PATCH 007/458] nvethernetrm: support for jumbo frames Bug 200513783 Change-Id: Ie0fccc6a1cbdf2e6417d78f616fcec71ba6f3ebf Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2094021 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_common.h | 8 ++++++++ include/osi_core.h | 2 ++ include/osi_dma.h | 40 ++++++++++++++++++++++++++++++---------- osi/eqos_core.c | 10 ++++++++++ osi/eqos_core.h | 3 +++ osi/eqos_dma.c | 40 +++++++++++++++++++++++++++++++++++++--- 6 files changed, 90 insertions(+), 13 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index 81f760d..0be4e60 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -27,6 +27,14 @@ #define OSI_ADDRESS_40BIT 1 #define OSI_ADDRESS_48BIT 2 +/* Default maximum Gaint Packet Size Limit */ +#define OSI_MAX_MTU_SIZE 9000U +#define OSI_DFLT_MTU_SIZE 1500U +#define OSI_MTU_SIZE_2K 2048U +#define OSI_MTU_SIZE_4K 4096U +#define OSI_MTU_SIZE_8K 8192U +#define OSI_MTU_SIZE_16K 16384U + #define EQOS_DMA_CHX_STATUS(x) ((0x0080U * (x)) + 0x1160U) #define EQOS_DMA_CHX_IER(x) ((0x0080U * (x)) + 0x1134U) diff --git a/include/osi_core.h b/include/osi_core.h index 3643457..efcd7ae 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -71,6 +71,7 @@ struct osi_core_ops { * @mac: MAC HW type EQOS based on DT compatible. * @mac_ver: MAC version. * @mdc_cr: MDC clock rate. + * @mtu: MTU size * @mac_addr: Ethernet MAC address. */ struct osi_core_priv_data { @@ -83,6 +84,7 @@ struct osi_core_priv_data { unsigned int mac; unsigned int mac_ver; unsigned int mdc_cr; + unsigned int mtu; unsigned char mac_addr[OSI_ETH_ALEN]; }; diff --git a/include/osi_dma.h b/include/osi_dma.h index f620be8..d9a42a9 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -160,6 +160,7 @@ struct osi_dma_priv_data; * @enable_chan_rx_intr: Called to enable DMA rx channel interrupts at * wrapper level. * @start_dma: Called to start the Tx/Rx DMA. + * @set_rx_buf_len: Called to set Rx buffer length. */ struct osi_dma_chan_ops { void (*set_tx_ring_len)(void *addr, unsigned int chan, @@ -183,6 +184,7 @@ struct osi_dma_chan_ops { void (*start_dma)(void *addr, unsigned int chan); void (*stop_dma)(void *addr, unsigned int chan); void (*init_dma_channel) (struct osi_dma_priv_data *osi_dma); + void (*set_rx_buf_len)(struct osi_dma_priv_data *osi_dma); }; /** @@ -190,17 +192,13 @@ struct osi_dma_chan_ops { * @tx_ring: Array of pointers to DMA Tx channel Ring. * @rx_ring: Array of pointers to DMA Rx channel Ring. * @base: Memory mapped base address of MAC IP. - * @ops: Address of HW operations structure. - * @num_chans: Number of channels enabled in MAC. - * @mac: MAC HW type (EQOS). * @osd: Pointer to OSD private data structure. - * @mdc_cr: MDC clock rate. - * @mac_addr: Ethernet MAC address. - * @phy_reset: PHY reset GPIO pin number. - * @chans: List of channels enabled in MAC. - * @rxq_ctrl: List if RxQs that need to be enabled + * @ops: Address of HW operations structure. + * @mac: MAC HW type (EQOS). + * @num_dma_chans: Number of channels enabled in MAC. + * @dma_chans[]: Array of supported DMA channels * @rx_buf_len: DMA Rx channel buffer length at HW level. - * @hw_feat: HW features associated with MAC. + * @mtu: MTU size */ struct osi_dma_priv_data { struct osi_tx_ring *tx_ring[OSI_EQOS_MAX_NUM_CHANS]; @@ -212,6 +210,7 @@ struct osi_dma_priv_data { unsigned int num_dma_chans; unsigned int dma_chans[OSI_EQOS_MAX_NUM_CHANS]; unsigned int rx_buf_len; + unsigned int mtu; }; /** @@ -449,12 +448,33 @@ static inline void osi_update_rx_tailptr(struct osi_dma_priv_data *osi_dma, tailptr = rx_ring->rx_desc_phy_addr + (refill_idx * sizeof(struct osi_rx_desc)); - if (osi_dma->ops != OSI_NULL && + if (osi_dma != OSI_NULL && osi_dma->ops != OSI_NULL && osi_dma->ops->update_rx_tailptr != OSI_NULL) { osi_dma->ops->update_rx_tailptr(osi_dma->base, chan, tailptr); } } +/** + * osi_set_rx_buf_len - Updates rx buffer length. + * @osi_dma: OSI DMA private data struture. + * + * Algorithm: Updates Rx buffer length. + * + * Dependencies: None. + * + * Protection: None. + * + * Return: None. + */ + +static inline void osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) +{ + if (osi_dma != OSI_NULL && osi_dma->ops != OSI_NULL && + osi_dma->ops->set_rx_buf_len != OSI_NULL) { + osi_dma->ops->set_rx_buf_len(osi_dma); + } +} + void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan); int osi_process_tx_completions(struct osi_dma_priv_data *osi, unsigned int chan); diff --git a/osi/eqos_core.c b/osi/eqos_core.c index 7d57ed0..0fe5e81 100644 --- a/osi/eqos_core.c +++ b/osi/eqos_core.c @@ -542,6 +542,16 @@ static void eqos_configure_mac(struct osi_core_priv_data *osi_core) /* Enable CRC stripping for Type packets */ /* Enable Full Duplex mode */ value |= EQOS_MCR_ACS | EQOS_MCR_CST | EQOS_MCR_DM; + + if (osi_core->mtu > OSI_DFLT_MTU_SIZE) { + value |= EQOS_MCR_S2KP; + } + + if (osi_core->mtu > OSI_MTU_SIZE_2K) { + value |= EQOS_MCR_JE; + value |= EQOS_MCR_JD; + } + osi_writel(value, (unsigned char *)osi_core->base + EQOS_MAC_MCR); /* Enable Multicast and Broadcast Queue, default is Q0 */ diff --git a/osi/eqos_core.h b/osi/eqos_core.h index a66e0a9..886c72c 100644 --- a/osi/eqos_core.h +++ b/osi/eqos_core.h @@ -100,8 +100,11 @@ #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_ACS OSI_BIT(20) #define EQOS_MCR_CST OSI_BIT(21) +#define EQOS_MCR_S2KP OSI_BIT(22) #define EQOS_IMR_RGSMIIIE OSI_BIT(0) #define EQOS_IMR_PCSLCHGIE OSI_BIT(1) #define EQOS_IMR_PCSANCIE OSI_BIT(2) diff --git a/osi/eqos_dma.c b/osi/eqos_dma.c index 3a1f523..1968eb0 100644 --- a/osi/eqos_dma.c +++ b/osi/eqos_dma.c @@ -380,9 +380,7 @@ static void eqos_configure_dma_channel(unsigned int chan, * bus width */ value = osi_readl((unsigned char *)osi_dma->base + EQOS_DMA_CHX_RX_CTRL(chan)); - osi_dma->rx_buf_len = ((MAX_ETH_FRAME_LEN_DEFAULT + - (EQOS_AXI_BUS_WIDTH - 1U)) & - ~(EQOS_AXI_BUS_WIDTH - 1U)); + value |= (osi_dma->rx_buf_len << EQOS_DMA_CHX_RBSZ_SHIFT); /* RXPBL = 12 */ value |= EQOS_DMA_CHX_RX_CTRL_RXPBL_RECOMMENDED; @@ -396,7 +394,9 @@ static void eqos_configure_dma_channel(unsigned int chan, * Description: Initialise all DMA channels. * * Dependencies: None. + * * Protection: None. + * * Return: None. */ static void eqos_init_dma_channel(struct osi_dma_priv_data *osi_dma) @@ -409,6 +409,39 @@ static void eqos_init_dma_channel(struct osi_dma_priv_data *osi_dma) } } +/** + * eqos_set_rx_buf_len - Set Rx buffer length + * @osi_dma: OSI DMA private data structure. + * + * Description: Sets the Rx buffer lenght based on the new MTU size set. + * + * Dependencies: None. + * + * Protection: None. + * + * Return: None. + */ +static void eqos_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) +{ + unsigned int rx_buf_len; + + if (osi_dma->mtu >= OSI_MTU_SIZE_8K) { + rx_buf_len = OSI_MTU_SIZE_16K; + } else if (osi_dma->mtu >= OSI_MTU_SIZE_4K) { + rx_buf_len = OSI_MTU_SIZE_8K; + } else if (osi_dma->mtu >= OSI_MTU_SIZE_2K) { + rx_buf_len = OSI_MTU_SIZE_4K; + } else if (osi_dma->mtu > MAX_ETH_FRAME_LEN_DEFAULT) { + rx_buf_len = OSI_MTU_SIZE_2K; + } else { + rx_buf_len = MAX_ETH_FRAME_LEN_DEFAULT; + } + + /* Buffer alignment */ + osi_dma->rx_buf_len = ((rx_buf_len + (EQOS_AXI_BUS_WIDTH - 1U)) & + ~(EQOS_AXI_BUS_WIDTH - 1U)); +} + static struct osi_dma_chan_ops eqos_dma_chan_ops = { .set_tx_ring_len = eqos_set_tx_ring_len, .set_rx_ring_len = eqos_set_rx_ring_len, @@ -425,6 +458,7 @@ static struct osi_dma_chan_ops eqos_dma_chan_ops = { .start_dma = eqos_start_dma, .stop_dma = eqos_stop_dma, .init_dma_channel = eqos_init_dma_channel, + .set_rx_buf_len = eqos_set_rx_buf_len, }; struct osi_dma_chan_ops *eqos_get_dma_chan_ops(void) From ebdfdb601fe1e104346452ddf0c8e734c1b05b1a Mon Sep 17 00:00:00 2001 From: Srinivas Ramachandran <srinivasra@nvidia.com> Date: Wed, 24 Apr 2019 16:35:56 -0700 Subject: [PATCH 008/458] nvethernetrm: docs: Include license used for this repo License taken from IP Audit wiki https://nv/ipaudit/Licenses/MIT Bug 200507585 Change-Id: I2b902b011e3f68d869c022dd7f2f57c5674ab895 Signed-off-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2104614 Reviewed-by: Matthew Pedro <mapedro@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- docs/license.txt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 docs/license.txt diff --git a/docs/license.txt b/docs/license.txt new file mode 100644 index 0000000..390aecc --- /dev/null +++ b/docs/license.txt @@ -0,0 +1,19 @@ +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. From a86d93af9f2539c4ad8681052d42887051adcbaa Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Sun, 10 Mar 2019 17:52:39 +0530 Subject: [PATCH 009/458] nvethernetrm: add support for CBS (802.1Qav) The MTL Queue Scheduler uses the credit-based shaper algorithm to arbitrate the AV traffic in all queues and the legacy Ethernet traffic in Queue 0. Tests are done using kunit framework as well as custom IOCTL app for linux. Bug 200512771 Change-Id: Ie05b2adbd2b62208d4f35220daebd635f049e7b0 Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2108316 Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Narayan Reddy <narayanr@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_core.h | 83 +++++++++++++++++++++ osi/eqos_core.c | 177 +++++++++++++++++++++++++++++++++++++++++++++ osi/eqos_core.h | 30 +++++++- 3 files changed, 289 insertions(+), 1 deletion(-) diff --git a/include/osi_core.h b/include/osi_core.h index efcd7ae..41cc270 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -27,6 +27,32 @@ struct osi_core_priv_data; +/** + * struct osi_core_avb_algorithm - The OSI Core avb data sctructure per + * queue. + * @qindex: TX Queue/TC index + * @algo: AVB algorithm 1:CBS + * @credit_control: credit control 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 + * @idle_slope: idleSlopeCredit value required for CBS + * @send_slope: sendSlopeCredit value required for CBS + * @hi_credit: hiCredit value required for CBS + * @low_credit: lowCredit value required for CBS + * @oper_mode: Transmit queue enable 01: avb 10: enable 00: disable + */ +struct osi_core_avb_algorithm { + unsigned int qindex; + unsigned int algo; + unsigned int credit_control; + unsigned int idle_slope; + unsigned int send_slope; + unsigned int hi_credit; + unsigned int low_credit; + unsigned int oper_mode; +}; + /** * struct osi_core_ops - Core (MAC & MTL) operations. * @poll_for_swr: Called to poll for software reset bit. @@ -40,6 +66,8 @@ struct osi_core_priv_data; * @set_mdc_clk_rate: Called to set MDC clock rate for MDIO operation. * @flush_mtl_tx_queue: Called to flush MTL Tx queue. * @config_mac_loopback: Called to configure MAC in loopback mode. + * @set_avb_algorithm: Called to set av parameter. + * @get_avb_algorithm: Called to get av parameter, */ struct osi_core_ops { /* initialize MAC/MTL/DMA Common registers */ @@ -57,6 +85,10 @@ struct osi_core_ops { unsigned long csr_clk_rate); int (*flush_mtl_tx_queue)(void *ioaddr, unsigned int qinx); int (*config_mac_loopback)(void *addr, unsigned int lb_mode); + int (*set_avb_algorithm)(struct osi_core_priv_data *osi_core, + struct osi_core_avb_algorithm *avb); + int (*get_avb_algorithm)(struct osi_core_priv_data *osi_core, + struct osi_core_avb_algorithm *avb); }; /** @@ -348,6 +380,57 @@ static inline int osi_config_mac_loopback(struct osi_core_priv_data *osi_core, return ret; } +/** + * osi_set_avb - Set CBS algo and parameters + * @osi: OSI core private data structure. + * @avb: osi core avb data structure. + * + * Algorithm: Set AVB algo and populated parameter from osi_core_avb + * structure for TC/TQ + * + * Dependencies: MAC IP should be out of reset and need to be initialized + * as the requirements + * + * Return: Success = 0; failure = -1; + */ +static inline int osi_set_avb(struct osi_core_priv_data *osi_core, + struct osi_core_avb_algorithm *avb) +{ + int ret = -1; + + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->set_avb_algorithm != OSI_NULL)) { + ret = osi_core->ops->set_avb_algorithm(osi_core, avb); + } + + return ret; +} + +/** + * osi_get_avb - Set CBS algo and parameters + * @osi: OSI core private data structure. + * @avb: osi core avb data structure. + * + * Algorithm: get AVB algo and populated parameter from osi_core_avb + * structure for TC/TQ + * + * Dependencies: MAC IP should be out of reset and need to be initialized + * as the requirements + * + * Return: Success = 0; failure = -1; + */ +static inline int osi_get_avb(struct osi_core_priv_data *osi_core, + struct osi_core_avb_algorithm *avb) +{ + int ret = -1; + + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->get_avb_algorithm != OSI_NULL)) { + ret = osi_core->ops->get_avb_algorithm(osi_core, avb); + } + + return ret; +} int osi_write_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, unsigned int phyreg, unsigned short phydata); diff --git a/osi/eqos_core.c b/osi/eqos_core.c index 0fe5e81..161e358 100644 --- a/osi/eqos_core.c +++ b/osi/eqos_core.c @@ -874,6 +874,181 @@ static void eqos_stop_mac(void *addr) osi_writel(value, (unsigned char *)addr + EQOS_MAC_MCR); } +/** + * eqos_set_avb_algorithm - Set TxQ/TC avb config + * @osi_core: osi core priv data structure + * @avb: structure having configuration for avb algorithm + * + * 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 + * + * Dependencies: MAC has to be out of reset. + * + * Protection: None. + * + * Return: 0: success, -1: error. + */ +static int eqos_set_avb_algorithm(struct osi_core_priv_data *osi_core, + struct osi_core_avb_algorithm *avb) +{ + unsigned int value; + int ret = -1; + unsigned int qinx; + + if (avb == OSI_NULL) { + osd_err(osi_core->osd, "avb structure is NULL\n"); + return ret; + } + + /* queue index in range */ + if (avb->qindex >= EQOS_MAX_TC) { + osd_err(osi_core->osd, "Invalid Queue index (%d)\n" + , avb->qindex); + return ret; + } + + /* can't set AVB mode for queue 0 */ + if ((avb->qindex == 0U) && (avb->oper_mode == EQOS_MTL_QUEUE_AVB)) { + osd_err(osi_core->osd, + "Not allowed to set CBS for Q0\n", avb->qindex); + return ret; + } + + qinx = avb->qindex; + value = osi_readl((unsigned char *)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; + osi_writel(value, (unsigned char *)osi_core->base + + EQOS_MTL_CHX_TX_OP_MODE(qinx)); + + /* Set Algo and Credit control */ + 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_writel(value, (unsigned char *)osi_core->base + + EQOS_MTL_TXQ_ETS_CR(qinx)); + + /* Set Send slope credit */ + value = avb->send_slope & EQOS_MTL_TXQ_ETS_SSCR_SSC_MASK; + osi_writel(value, (unsigned char *)osi_core->base + + EQOS_MTL_TXQ_ETS_SSCR(qinx)); + + /* Set Idle slope credit*/ + value = osi_readl((unsigned char *)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; + osi_writel(value, (unsigned char *)osi_core->base + + EQOS_MTL_TXQ_QW(qinx)); + + /* Set Hi credit */ + value = avb->hi_credit & EQOS_MTL_TXQ_ETS_HCR_HC_MASK; + osi_writel(value, (unsigned char *)osi_core->base + + EQOS_MTL_TXQ_ETS_HCR(qinx)); + + /* low credit is -ve number, osi_write need a unsigned int + * take only 28:0 bits from avb->low_credit + */ + value = avb->low_credit & EQOS_MTL_TXQ_ETS_LCR_LC_MASK; + osi_writel(value, (unsigned char *)osi_core->base + + EQOS_MTL_TXQ_ETS_LCR(qinx)); + + return 0; +} + +/** + * eqos_get_avb_algorithm - Get TxQ/TC avb config + * @osi_core: osi core priv data structure + * @avb: structure pointer having configuration for avb algorithm + * + * 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 + * + * Dependencies: MAC has to be out of reset. + * + * Protection: None. + * + * Return: 0: Success -1: Failure + */ + +static int eqos_get_avb_algorithm(struct osi_core_priv_data *osi_core, + struct osi_core_avb_algorithm *avb) +{ + unsigned int value; + int ret = -1; + unsigned int qinx = 0U; + + if (avb == OSI_NULL) { + osd_err(osi_core->osd, "avb structure is NULL\n"); + return ret; + } + + if (avb->qindex >= EQOS_MAX_TC) { + osd_err(osi_core->osd, "Invalid Queue index (%d)\n" + , avb->qindex); + return ret; + } + + qinx = avb->qindex; + value = osi_readl((unsigned char *)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) >> EQOS_MTL_TXQEN_MASK_SHIFT; + avb->oper_mode = value; + + /* Get Algo and Credit control */ + value = osi_readl((unsigned char *)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_readl(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_readl((unsigned char *)osi_core->base + + EQOS_MTL_TXQ_QW(qinx)); + avb->idle_slope = value & EQOS_MTL_TXQ_ETS_QW_ISCQW_MASK; + + /* Get Hi credit */ + value = osi_readl((unsigned char *)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_readl((unsigned char *)osi_core->base + + EQOS_MTL_TXQ_ETS_LCR(qinx)); + avb->low_credit = value & EQOS_MTL_TXQ_ETS_LCR_LC_MASK; + + return 0; +} + static struct osi_core_ops eqos_core_ops = { .poll_for_swr = eqos_poll_for_swr, .core_init = eqos_core_init, @@ -886,6 +1061,8 @@ static struct osi_core_ops eqos_core_ops = { .set_mdc_clk_rate = eqos_set_mdc_clk_rate, .flush_mtl_tx_queue = eqos_flush_mtl_tx_queue, .config_mac_loopback = eqos_config_mac_loopback, + .set_avb_algorithm = eqos_set_avb_algorithm, + .get_avb_algorithm = eqos_get_avb_algorithm, }; struct osi_core_ops *eqos_get_hw_core_ops(void) diff --git a/osi/eqos_core.h b/osi/eqos_core.h index 886c72c..27d8b5d 100644 --- a/osi/eqos_core.h +++ b/osi/eqos_core.h @@ -23,6 +23,18 @@ #ifndef EQOS_CORE_H_ #define EQOS_CORE_H_ +/** + * MTL queue operation mode + * EQOS_MTL_QUEUE_DISABLED - queue disabled + * EQOS_MTL_QUEUE_QAVB - queue in AVB mode + * EQOS_MTL_QUEUE_QDCB - queue in DCB mode + * EQOS_MTL_QUEUE_QGENERIC - queue in gerneric mode + */ +#define EQOS_MTL_QUEUE_DISABLED 0x0U +#define EQOS_MTL_QUEUE_AVB 0x1U +#define EQOS_MTL_QUEUE_DCB 0x2U +#define EQOS_MTL_QUEUE_GENERIC 0x3U + /* MDC Clock Selection define*/ #define EQOS_CSR_60_100M 0x0 /* MDC = clk_csr/42 */ #define EQOS_CSR_100_150M 0x1 /* MDC = clk_csr/62 */ @@ -74,6 +86,10 @@ #define EQOS_MTL_CHX_TX_OP_MODE(x) ((0x0040U * (x)) + 0x0D00U) #define EQOS_MTL_TXQ_QW(x) ((0x0040U * (x)) + 0x0D18U) #define EQOS_MTL_CHX_RX_OP_MODE(x) ((0x0040U * (x)) + 0x0D30U) +#define EQOS_MTL_TXQ_ETS_CR(x) ((0x0040U * (x)) + 0x0D10U) +#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_RXQ_DMA_MAP0 0x0C30 /* EQOS Wrapper registers*/ @@ -140,5 +156,17 @@ #define EQOS_MTL_RXQ_SIZE_SHIFT 20U #define EQOS_MAC_ENABLE_LM OSI_BIT(12) #define EQOS_RX_CLK_SEL OSI_BIT(8) - +#define EQOS_MAX_TC 8U +#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_TXQ_ETS_QW_ISCQW_MASK 0x000FFFFFU +#define EQOS_MTL_TXQ_ETS_SSCR_SSC_MASK 0x00003FFFU +#define EQOS_MTL_TXQ_ETS_HCR_HC_MASK 0x1FFFFFFFU +#define EQOS_MTL_TXQ_ETS_LCR_LC_MASK 0x1FFFFFFFU +#define EQOS_MTL_TXQEN_MASK (OSI_BIT(3) | OSI_BIT(2)) +#define EQOS_MTL_TXQEN_MASK_SHIFT 2U #endif From 185699a5ac711aa8dccfb011f51e7b42cf783735 Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Tue, 23 Apr 2019 23:57:12 +0530 Subject: [PATCH 010/458] nvethernetrm: Add support to forward error pkts Added support to configure Rx MTL Queue to drop or forward the error packets to DMA or application Bug 200515518 Change-Id: I699435aaf5dcfaf4cfced799eaac78cdee65f063 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2108561 Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_core.h | 33 ++++++++++++++++++++++++++++ osi/eqos_core.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++ osi/eqos_core.h | 1 + 3 files changed, 89 insertions(+) diff --git a/include/osi_core.h b/include/osi_core.h index 41cc270..3ad9edf 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -68,6 +68,7 @@ struct osi_core_avb_algorithm { * @config_mac_loopback: Called to configure MAC in loopback mode. * @set_avb_algorithm: Called to set av parameter. * @get_avb_algorithm: Called to get av parameter, + * @config_fw_err_pkts: Called to configure MTL RxQ to forward the err pkt. */ struct osi_core_ops { /* initialize MAC/MTL/DMA Common registers */ @@ -89,6 +90,8 @@ struct osi_core_ops { struct osi_core_avb_algorithm *avb); int (*get_avb_algorithm)(struct osi_core_priv_data *osi_core, struct osi_core_avb_algorithm *avb); + int (*config_fw_err_pkts)(void *addr, unsigned int qinx, + unsigned int fw_err); }; /** @@ -432,6 +435,36 @@ static inline int osi_get_avb(struct osi_core_priv_data *osi_core, return ret; } +/** + * osi_config_fw_err_pkts - Configure forwarding of error packets + * @osi_core: OSI core private data structure. + * @qinx: Q index + * @fw_err: Enable or disable forwarding of error packets + * + * Algorithm: Configure MAC to enable/disable forwarding of error packets. + * + * Dependencies: MAC IP should be out of reset and need to be initialized + * as per the requirements + * + * Protection: None + * + * Return: 0 - success, -1 - failure. + */ +static inline int osi_config_fw_err_pkts(struct osi_core_priv_data *osi_core, + unsigned int qinx, unsigned int fw_err) +{ + int ret = -1; + + /* Configure Forwarding of Error packets */ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->config_fw_err_pkts != OSI_NULL)) { + ret = osi_core->ops->config_fw_err_pkts(osi_core->base, + qinx, fw_err); + } + + return ret; +} + int osi_write_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, unsigned int phyreg, unsigned short phydata); int osi_read_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, diff --git a/osi/eqos_core.c b/osi/eqos_core.c index 161e358..4e5d326 100644 --- a/osi/eqos_core.c +++ b/osi/eqos_core.c @@ -27,6 +27,60 @@ struct osi_core_ops *eqos_get_hw_core_ops(void); +/** + * eqos_config_fw_err_pkts - Configure forwarding of error packets + * @addr: MAC base address. + * @qinx: Q index + * @fw_err: Enable or Disable the forwarding of error packets + * + * Algorithm: When this bit is reset, the Rx queue drops packets with error + * status (CRC error, GMII_ER, watchdog timeout, or overflow). + * When this bit is set, all packets except the runt error packets + * are forwarded to the application or DMA. + * + * Dependencies: MAC has to be out of reset. + * + * Protection: None. + * + * Return: 0 - success, -1 - failure + */ +static int eqos_config_fw_err_pkts(void *addr, unsigned int qinx, + unsigned int fw_err) +{ + unsigned int val; + + /* Check for valid fw_err and qinx values */ + if ((fw_err != OSI_ENABLE && fw_err != OSI_DISABLE) || + (qinx >= OSI_EQOS_MAX_NUM_CHANS)) { + return -1; + } + + /* Read MTL RXQ Operation_Mode Register */ + val = osi_readl((unsigned char *)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. + */ + osi_writel(val, (unsigned char *)addr + EQOS_MTL_CHX_RX_OP_MODE(qinx)); + + return 0; +} + /** * eqos_config_mac_loopback - Configure MAC to support loopback * @addr: MAC base address. @@ -1063,6 +1117,7 @@ static struct osi_core_ops eqos_core_ops = { .config_mac_loopback = eqos_config_mac_loopback, .set_avb_algorithm = eqos_set_avb_algorithm, .get_avb_algorithm = eqos_get_avb_algorithm, + .config_fw_err_pkts = eqos_config_fw_err_pkts, }; struct osi_core_ops *eqos_get_hw_core_ops(void) diff --git a/osi/eqos_core.h b/osi/eqos_core.h index 27d8b5d..940e607 100644 --- a/osi/eqos_core.h +++ b/osi/eqos_core.h @@ -169,4 +169,5 @@ #define EQOS_MTL_TXQ_ETS_LCR_LC_MASK 0x1FFFFFFFU #define EQOS_MTL_TXQEN_MASK (OSI_BIT(3) | OSI_BIT(2)) #define EQOS_MTL_TXQEN_MASK_SHIFT 2U +#define EQOS_MTL_RXQ_OP_MODE_FEP OSI_BIT(4) #endif From 1c2dbcfd785ad46a7240910f639a820c12c96315 Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Tue, 23 Apr 2019 22:33:55 +0530 Subject: [PATCH 011/458] nvethernetrm: Enable Tx packet status reporting Added support for configuring the MTL to drop or forward the Tx packet status to application. Added API to clear the tx packet error stats Bug 200515518 Change-Id: I818b4581b8bcbe84d0ca065010c60dd93726a385 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2108560 Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osd.h | 2 +- include/osi_common.h | 2 + include/osi_core.h | 32 ++++++++++ include/osi_dma.h | 30 +++++++++ include/osi_dma_txrx.h | 23 +++++++ osi/eqos_core.c | 53 +++++++++++++++- osi/eqos_core.h | 2 + osi/osi_dma_txrx.c | 135 ++++++++++++++++++++++++++++++++++++++++- 8 files changed, 275 insertions(+), 4 deletions(-) diff --git a/include/osd.h b/include/osd.h index bf1f527..6caaedf 100644 --- a/include/osd.h +++ b/include/osd.h @@ -31,5 +31,5 @@ void osd_err(void *priv, const char *fmt, ...); void osd_receive_packet(void *priv, void *rxring, unsigned int chan, unsigned int dma_buf_len, void *rxpkt_cx); void osd_transmit_complete(void *priv, void *buffer, unsigned long dmaaddr, - unsigned int len); + unsigned int len, int pkt_valid); #endif diff --git a/include/osi_common.h b/include/osi_common.h index 0be4e60..c14f2a2 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -27,6 +27,8 @@ #define OSI_ADDRESS_40BIT 1 #define OSI_ADDRESS_48BIT 2 +#define ULONG_MAX (~0UL) + /* Default maximum Gaint Packet Size Limit */ #define OSI_MAX_MTU_SIZE 9000U #define OSI_DFLT_MTU_SIZE 1500U diff --git a/include/osi_core.h b/include/osi_core.h index 3ad9edf..85f45d5 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -69,6 +69,7 @@ struct osi_core_avb_algorithm { * @set_avb_algorithm: Called to set av parameter. * @get_avb_algorithm: Called to get av parameter, * @config_fw_err_pkts: Called to configure MTL RxQ to forward the err pkt. + * @config_tx_status: Called to configure the MTL to forward/drop tx status */ struct osi_core_ops { /* initialize MAC/MTL/DMA Common registers */ @@ -92,6 +93,7 @@ struct osi_core_ops { struct osi_core_avb_algorithm *avb); int (*config_fw_err_pkts)(void *addr, unsigned int qinx, unsigned int fw_err); + int (*config_tx_status)(void *addr, unsigned int tx_status); }; /** @@ -435,6 +437,36 @@ static inline int osi_get_avb(struct osi_core_priv_data *osi_core, return ret; } +/** + * osi_configure_txstatus - Configure Tx packet status reporting + * @osi_core: OSI private data structure. + * @tx_status: Enable or disable tx packet status reporting + * + * Algorithm: Configure MAC to enable/disable Tx status error + * reporting. + * + * Dependencies: MAC IP should be out of reset and need to be initialized + * as per the requirements + * + * Protection: None + * + * Return: 0 - success, -1 - failure. + */ +static inline int osi_configure_txstatus(struct osi_core_priv_data *osi_core, + unsigned int tx_status) +{ + int ret = -1; + + /* Configure Drop Transmit Status */ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->config_tx_status != OSI_NULL)) { + ret = osi_core->ops->config_tx_status(osi_core->base, + tx_status); + } + + return ret; +} + /** * osi_config_fw_err_pkts - Configure forwarding of error packets * @osi_core: OSI core private data structure. diff --git a/include/osi_dma.h b/include/osi_dma.h index d9a42a9..0c95a02 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -28,6 +28,33 @@ #define OSI_PKT_CX_VLAN OSI_BIT(0) +/** + * struct osi_pkt_err_stats: OSI packet error stats + * @ip_header_error: IP Header Error + * @jabber_timeout_error: Jabber time out Error + * @pkt_flush_error: Packet Flush Error + * @payload_cs_error: Payload Checksum Error + * @loss_of_carrier_error: Loss of Carrier Error + * @no_carrier_error: No Carrier Error + * @late_collision_error: Late Collision Error + * @excessive_collision_error: Excessive Collision Error + * @excessive_deferal_error: Excessive Deferal Error + * @underflow_error: Under Flow Error + */ +struct osi_pkt_err_stats { + /* Transmit errors */ + unsigned long ip_header_error; + unsigned long jabber_timeout_error; + unsigned long pkt_flush_error; + unsigned long payload_cs_error; + unsigned long loss_of_carrier_error; + unsigned long no_carrier_error; + unsigned long late_collision_error; + unsigned long excessive_collision_error; + unsigned long excessive_deferal_error; + unsigned long underflow_error; +}; + /** * struct osi_rx_desc - Receive Descriptor * @rdes0: Receive Descriptor 0 @@ -199,6 +226,7 @@ struct osi_dma_chan_ops { * @dma_chans[]: Array of supported DMA channels * @rx_buf_len: DMA Rx channel buffer length at HW level. * @mtu: MTU size + * @osi_pkt_err_stats: Packet error stats */ struct osi_dma_priv_data { struct osi_tx_ring *tx_ring[OSI_EQOS_MAX_NUM_CHANS]; @@ -211,6 +239,7 @@ struct osi_dma_priv_data { unsigned int dma_chans[OSI_EQOS_MAX_NUM_CHANS]; unsigned int rx_buf_len; unsigned int mtu; + struct osi_pkt_err_stats pkt_err_stats; }; /** @@ -483,4 +512,5 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, int osi_hw_dma_init(struct osi_dma_priv_data *osi_dma); void osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma); void osi_init_dma_ops(struct osi_dma_priv_data *osi_dma); +void osi_clear_tx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); #endif /* OSI_DMA_H */ diff --git a/include/osi_dma_txrx.h b/include/osi_dma_txrx.h index 8fd9993..41feca4 100644 --- a/include/osi_dma_txrx.h +++ b/include/osi_dma_txrx.h @@ -57,9 +57,32 @@ #define TDES3_FD OSI_BIT(29) #define TDES3_LD OSI_BIT(28) #define TDES3_VLTV OSI_BIT(16) + +/* 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 ((unsigned int)0x2 << 14U) +#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 /* OSI_DMA_TXRX_H */ diff --git a/osi/eqos_core.c b/osi/eqos_core.c index 4e5d326..3ce0a2a 100644 --- a/osi/eqos_core.c +++ b/osi/eqos_core.c @@ -58,7 +58,7 @@ static int eqos_config_fw_err_pkts(void *addr, unsigned int qinx, /* Read MTL RXQ Operation_Mode Register */ val = osi_readl((unsigned char *)addr + EQOS_MTL_CHX_RX_OP_MODE(qinx)); - /* fw_err 1 is for enable and 0 is for disable */ + /* 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. @@ -81,6 +81,56 @@ static int eqos_config_fw_err_pkts(void *addr, unsigned int qinx, return 0; } +/** + * eqos_config_tx_status - Configure MAC to forward the tx pkt status + * @addr: MAC base address. + * @tx_status: Enable or Disable the forwarding of tx pkt status + * + * 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. + * + * Dependencies: MAC has to be out of reset. + * + * Protection: None. + * + * Return: 0 - success, -1 - failure + */ +static int eqos_config_tx_status(void *addr, unsigned int tx_status) +{ + unsigned int val; + + /* don't allow if tx_status is other than 0 or 1 */ + if (tx_status != OSI_ENABLE && tx_status != OSI_DISABLE) { + return -1; + } + + /* Read MTL Operation Mode Register */ + val = osi_readl((unsigned char *)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_writel(val, (unsigned char *)addr + EQOS_MTL_OP_MODE); + + return 0; +} + /** * eqos_config_mac_loopback - Configure MAC to support loopback * @addr: MAC base address. @@ -1118,6 +1168,7 @@ static struct osi_core_ops eqos_core_ops = { .set_avb_algorithm = eqos_set_avb_algorithm, .get_avb_algorithm = eqos_get_avb_algorithm, .config_fw_err_pkts = eqos_config_fw_err_pkts, + .config_tx_status = eqos_config_tx_status, }; struct osi_core_ops *eqos_get_hw_core_ops(void) diff --git a/osi/eqos_core.h b/osi/eqos_core.h index 940e607..6718ebf 100644 --- a/osi/eqos_core.h +++ b/osi/eqos_core.h @@ -91,6 +91,7 @@ #define EQOS_MTL_TXQ_ETS_HCR(x) ((0x0040U * (x)) + 0x0D20U) #define EQOS_MTL_TXQ_ETS_LCR(x) ((0x0040U * (x)) + 0x0D24U) #define EQOS_MTL_RXQ_DMA_MAP0 0x0C30 +#define EQOS_MTL_OP_MODE 0x0C00 /* EQOS Wrapper registers*/ #define EQOS_PAD_AUTO_CAL_CFG 0x8804U @@ -170,4 +171,5 @@ #define EQOS_MTL_TXQEN_MASK (OSI_BIT(3) | OSI_BIT(2)) #define EQOS_MTL_TXQEN_MASK_SHIFT 2U #define EQOS_MTL_RXQ_OP_MODE_FEP OSI_BIT(4) +#define EQOS_MTL_OP_MODE_DTXSTS OSI_BIT(1) #endif diff --git a/osi/osi_dma_txrx.c b/osi/osi_dma_txrx.c index 9f4c2ab..e5d6844 100644 --- a/osi/osi_dma_txrx.c +++ b/osi/osi_dma_txrx.c @@ -109,6 +109,127 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, return received; } +/** + * get_tx_err_stats - Detect Errors from Tx Status + * @tx_desc: Tx Descriptor. + * @pkt_err_stats: Pakcet error stats which stores the errors reported + * + * Algorimthm: This routine will be invoked by OSI layer itself which + * checks for the Last Descriptor and updates the transmit status errors + * accordingly. + * + * Dependencies: None. + * + * Protection: None. + * + * Return: None. + */ +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) { + if (pkt_err_stats.ip_header_error < ULONG_MAX) { + pkt_err_stats.ip_header_error++; + } + } + + /* Jabber timeout Error */ + if ((tx_desc->tdes3 & TDES3_JABBER_TIMEO_ERR) == + TDES3_JABBER_TIMEO_ERR) { + if (pkt_err_stats.jabber_timeout_error < ULONG_MAX) { + pkt_err_stats.jabber_timeout_error++; + } + } + + /* Packet Flush Error */ + if ((tx_desc->tdes3 & TDES3_PKT_FLUSH_ERR) == TDES3_PKT_FLUSH_ERR) { + if (pkt_err_stats.pkt_flush_error < ULONG_MAX) { + pkt_err_stats.pkt_flush_error++; + } + } + + /* Payload Checksum Error */ + if ((tx_desc->tdes3 & TDES3_PL_CHK_SUM_ERR) == TDES3_PL_CHK_SUM_ERR) { + if (pkt_err_stats.payload_cs_error < ULONG_MAX) { + pkt_err_stats.payload_cs_error++; + } + } + + /* Loss of Carrier Error */ + if ((tx_desc->tdes3 & TDES3_LOSS_CARRIER_ERR) == + TDES3_LOSS_CARRIER_ERR) { + if (pkt_err_stats.loss_of_carrier_error < ULONG_MAX) { + pkt_err_stats.loss_of_carrier_error++; + } + } + + /* No Carrier Error */ + if ((tx_desc->tdes3 & TDES3_NO_CARRIER_ERR) == TDES3_NO_CARRIER_ERR) { + if (pkt_err_stats.no_carrier_error < ULONG_MAX) { + pkt_err_stats.no_carrier_error++; + } + } + + /* Late Collision Error */ + if ((tx_desc->tdes3 & TDES3_LATE_COL_ERR) == TDES3_LATE_COL_ERR) { + if (pkt_err_stats.late_collision_error < ULONG_MAX) { + pkt_err_stats.late_collision_error++; + } + } + + /* Execessive Collision Error */ + if ((tx_desc->tdes3 & TDES3_EXCESSIVE_COL_ERR) == + TDES3_EXCESSIVE_COL_ERR) { + if (pkt_err_stats.excessive_collision_error < ULONG_MAX) { + pkt_err_stats.excessive_collision_error++; + } + } + + /* Excessive Deferal Error */ + if ((tx_desc->tdes3 & TDES3_EXCESSIVE_DEF_ERR) == + TDES3_EXCESSIVE_DEF_ERR) { + if (pkt_err_stats.excessive_deferal_error < ULONG_MAX) { + pkt_err_stats.excessive_deferal_error++; + } + } + + /* Under Flow Error */ + if ((tx_desc->tdes3 & TDES3_UNDER_FLOW_ERR) == TDES3_UNDER_FLOW_ERR) { + if (pkt_err_stats.underflow_error < ULONG_MAX) { + pkt_err_stats.underflow_error++; + } + } +} + +/** + * osi_clear_tx_pkt_err_stats - Clear tx packet error stats. + * @osi: OSI dma private data structure. + * + * Algorithm: This function will be invoked by OSD layer to clear the + * tx packet error stats + * + * Dependencies: None. + * + * Protection: None + * + * Return: None + */ +void osi_clear_tx_pkt_err_stats(struct osi_dma_priv_data *osi_dma) +{ + /* Reset tx packet errors */ + osi_dma->pkt_err_stats.ip_header_error = 0U; + osi_dma->pkt_err_stats.jabber_timeout_error = 0U; + osi_dma->pkt_err_stats.pkt_flush_error = 0U; + osi_dma->pkt_err_stats.payload_cs_error = 0U; + osi_dma->pkt_err_stats.loss_of_carrier_error = 0U; + osi_dma->pkt_err_stats.no_carrier_error = 0U; + osi_dma->pkt_err_stats.late_collision_error = 0U; + osi_dma->pkt_err_stats.excessive_collision_error = 0U; + osi_dma->pkt_err_stats.excessive_deferal_error = 0U; + osi_dma->pkt_err_stats.underflow_error = 0U; +} + /** * osi_process_tx_completions - Process Tx complete on DMA channel ring. * @osi: OSI private data structure. @@ -133,7 +254,7 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi, struct osi_tx_swcx *tx_swcx = OSI_NULL; struct osi_tx_desc *tx_desc = OSI_NULL; unsigned int entry = tx_ring->clean_idx; - int processed = 0; + int processed = 0, pkt_valid = 1; while (entry != tx_ring->cur_tx_idx) { tx_desc = tx_ring->tx_desc + entry; @@ -143,8 +264,18 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi, break; } + /* check for Last Descriptor */ + if ((tx_desc->tdes3 & TDES3_LD) == TDES3_LD) { + if ((tx_desc->tdes3 & TDES3_ES_BITS) != 0U) { + pkt_valid = 0; + /* fill packet error stats */ + get_tx_err_stats(tx_desc, osi->pkt_err_stats); + } + } + osd_transmit_complete(osi->osd, tx_swcx->buf_virt_addr, - tx_swcx->buf_phy_addr, tx_swcx->len); + tx_swcx->buf_phy_addr, tx_swcx->len, + pkt_valid); tx_desc->tdes3 = 0; tx_desc->tdes2 = 0; From 2d15bfc152fdf51600dde7b8153ff6ac184a8c07 Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Wed, 24 Apr 2019 21:20:00 +0530 Subject: [PATCH 012/458] nvethernetrm: CRC Checking for Rx Packets Added support for configuring MAC to check or skip the CRC field in the received packets. Added API to clear the Rx error pkt stats Bug 200515518 Change-Id: Idc6a9f91c48b60434db9f62d90fb825258db67e7 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2108562 GVS: Gerrit_Virtual_Submit Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_core.h | 33 ++++++++++++++++++++++++++ include/osi_dma.h | 5 ++++ osi/eqos_core.c | 45 +++++++++++++++++++++++++++++++++++ osi/eqos_core.h | 2 ++ osi/osi_dma_txrx.c | 58 ++++++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 141 insertions(+), 2 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 85f45d5..9d828d2 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -70,6 +70,7 @@ struct osi_core_avb_algorithm { * @get_avb_algorithm: Called to get av parameter, * @config_fw_err_pkts: Called to configure MTL RxQ to forward the err pkt. * @config_tx_status: Called to configure the MTL to forward/drop tx status + * @config_rx_crc_check: Called to configure the MAC rx crc. */ struct osi_core_ops { /* initialize MAC/MTL/DMA Common registers */ @@ -94,6 +95,7 @@ struct osi_core_ops { int (*config_fw_err_pkts)(void *addr, unsigned int qinx, unsigned int fw_err); int (*config_tx_status)(void *addr, unsigned int tx_status); + int (*config_rx_crc_check)(void *addr, unsigned int crc_chk); }; /** @@ -497,6 +499,37 @@ static inline int osi_config_fw_err_pkts(struct osi_core_priv_data *osi_core, return ret; } +/** + * osi_config_rx_crc_check - Configure CRC Checking for Received Packets + * @osi_core: OSI core private data structure. + * @crc_chk: Enable or disable checking of CRC field in received packets + * + * 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. + * + * Dependencies: MAC IP should be out of reset and need to be initialized + * as per the requirements + * + * Protection: None + * + * Return: 0 - success, -1 - failure. + */ +static inline int osi_config_rx_crc_check(struct osi_core_priv_data *osi_core, + unsigned int crc_chk) +{ + int ret = -1; + + /* Configure CRC Checking for Received Packets */ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->config_rx_crc_check != OSI_NULL)) { + ret = osi_core->ops->config_rx_crc_check(osi_core->base, + crc_chk); + } + + return ret; +} + int osi_write_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, unsigned int phyreg, unsigned short phydata); int osi_read_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, diff --git a/include/osi_dma.h b/include/osi_dma.h index 0c95a02..a06df16 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -27,6 +27,7 @@ #include "osi_dma_txrx.h" #define OSI_PKT_CX_VLAN OSI_BIT(0) +#define OSI_PKT_CX_VALID OSI_BIT(10) /** * struct osi_pkt_err_stats: OSI packet error stats @@ -40,6 +41,7 @@ * @excessive_collision_error: Excessive Collision Error * @excessive_deferal_error: Excessive Deferal Error * @underflow_error: Under Flow Error + * @rx_crc_error: Rx CRC Error */ struct osi_pkt_err_stats { /* Transmit errors */ @@ -53,6 +55,8 @@ struct osi_pkt_err_stats { unsigned long excessive_collision_error; unsigned long excessive_deferal_error; unsigned long underflow_error; + /* Receive Errors */ + unsigned long rx_crc_error; }; /** @@ -513,4 +517,5 @@ int osi_hw_dma_init(struct osi_dma_priv_data *osi_dma); void osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma); void osi_init_dma_ops(struct osi_dma_priv_data *osi_dma); void osi_clear_tx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); +void osi_clear_rx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); #endif /* OSI_DMA_H */ diff --git a/osi/eqos_core.c b/osi/eqos_core.c index 3ce0a2a..9903eca 100644 --- a/osi/eqos_core.c +++ b/osi/eqos_core.c @@ -27,6 +27,50 @@ struct osi_core_ops *eqos_get_hw_core_ops(void); +/** + * eqos_osi_config_rx_crc_check - Configure CRC Checking for Rx Packets + * @addr: MAC base address. + * @crc_chk: Enable or disable checking of CRC field in received packets + * + * 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. + * + * Dependencies: MAC has to be out of reset. + * + * Protection: None. + * + * Return: 0 - success, -1 - failure + */ +static int eqos_config_rx_crc_check(void *addr, unsigned int crc_chk) +{ + unsigned int val; + + /* return on invalid argument */ + if (crc_chk != OSI_ENABLE && crc_chk != OSI_DISABLE) { + return -1; + } + + /* Read MAC Extension Register */ + val = osi_readl((unsigned char *)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_writel(val, (unsigned char *)addr + EQOS_MAC_EXTR); + + return 0; +} + /** * eqos_config_fw_err_pkts - Configure forwarding of error packets * @addr: MAC base address. @@ -1169,6 +1213,7 @@ static struct osi_core_ops eqos_core_ops = { .get_avb_algorithm = eqos_get_avb_algorithm, .config_fw_err_pkts = eqos_config_fw_err_pkts, .config_tx_status = eqos_config_tx_status, + .config_rx_crc_check = eqos_config_rx_crc_check, }; struct osi_core_ops *eqos_get_hw_core_ops(void) diff --git a/osi/eqos_core.h b/osi/eqos_core.h index 6718ebf..fca6a53 100644 --- a/osi/eqos_core.h +++ b/osi/eqos_core.h @@ -81,6 +81,7 @@ #define EQOS_MAC_PCS 0x00F8 #define EQOS_MAC_ANS 0x00E4 #define EQOS_RXQ_TO_DMA_CHAN_MAP 0x03020100U +#define EQOS_MAC_EXTR 0x0004 /* EQOS MTL registers*/ #define EQOS_MTL_CHX_TX_OP_MODE(x) ((0x0040U * (x)) + 0x0D00U) @@ -172,4 +173,5 @@ #define EQOS_MTL_TXQEN_MASK_SHIFT 2U #define EQOS_MTL_RXQ_OP_MODE_FEP OSI_BIT(4) #define EQOS_MTL_OP_MODE_DTXSTS OSI_BIT(1) +#define EQOS_MAC_EXTR_DCRCC OSI_BIT(16) #endif diff --git a/osi/osi_dma_txrx.c b/osi/osi_dma_txrx.c index e5d6844..5220929 100644 --- a/osi/osi_dma_txrx.c +++ b/osi/osi_dma_txrx.c @@ -55,6 +55,32 @@ static inline void get_rx_vlan_from_desc(struct osi_rx_desc *rx_desc, } } +/** + * get_rx_err_stats - Detect Errors from Rx Descriptor + * @rx_desc: Rx Descriptor. + * @pkt_err_stats: Packet error stats which stores the errors reported + * + * Algorimthm: This routine will be invoked by OSI layer itself which + * checks for the Last Descriptor and updates the receive status errors + * accordingly. + * + * Dependencies: None. + * + * Protection: None. + * + * Return: None. + */ +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) { + if (pkt_err_stats.rx_crc_error < ULONG_MAX) { + pkt_err_stats.rx_crc_error++; + } + } +} + /** * osi_process_rx_completions - Read data from receive channel descriptors * @osi: OSI private data structure. @@ -96,8 +122,17 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, /* get the length of the packet */ rx_pkt_cx->pkt_len = rx_desc->rdes3 & RDES3_PKT_LEN; - if (((rx_desc->rdes3 & RDES3_ES_BITS) == 0U) && - ((rx_desc->rdes3 & RDES3_LD) == RDES3_LD)) { + /* 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 & RDES3_ES_BITS) != 0U) { + /* reset validity if any of the error bits + * are set + */ + rx_pkt_cx->flags &= ~OSI_PKT_CX_VALID; + get_rx_err_stats(rx_desc, osi->pkt_err_stats); + } get_rx_vlan_from_desc(rx_desc, rx_pkt_cx); osd_receive_packet(osi->osd, rx_ring, chan, osi->rx_buf_len, rx_pkt_cx); @@ -230,6 +265,25 @@ void osi_clear_tx_pkt_err_stats(struct osi_dma_priv_data *osi_dma) osi_dma->pkt_err_stats.underflow_error = 0U; } +/** + * osi_clear_rx_pkt_err_stats - Clear rx packet error stats. + * @osi: OSI dma private data structure. + * + * Algorithm: This function will be invoked by OSD layer to clear the + * rx packet error stats + * + * Dependencies: None. + * + * Protection: None + * + * Return: None + */ +void osi_clear_rx_pkt_err_stats(struct osi_dma_priv_data *osi_dma) +{ + /* Reset Rx packet errors */ + osi_dma->pkt_err_stats.rx_crc_error = 0U; +} + /** * osi_process_tx_completions - Process Tx complete on DMA channel ring. * @osi: OSI private data structure. From 8bf40a85da9dd960368fdbea0e5ccd1e09beb632 Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Tue, 7 May 2019 19:06:04 +0530 Subject: [PATCH 013/458] nvethernetrm: fix bitmask for handling avb IOCTL Correcting bit mask to get correct operation mode when user ask for current avb setting using ETHER_GET_AVB_ALGORITHM IOCTL Bug 200512422 Change-Id: I884ab8666437110f2306f0542cc99948ad7c8874 Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2113782 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/eqos_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osi/eqos_core.c b/osi/eqos_core.c index 9903eca..911274e 100644 --- a/osi/eqos_core.c +++ b/osi/eqos_core.c @@ -1162,7 +1162,7 @@ static int eqos_get_avb_algorithm(struct osi_core_priv_data *osi_core, 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) >> EQOS_MTL_TXQEN_MASK_SHIFT; + value = (value & EQOS_MTL_TXQEN_MASK) >> EQOS_MTL_TXQEN_MASK_SHIFT; avb->oper_mode = value; /* Get Algo and Credit control */ From 1ad5a7338354ecda58e9de2b3c770bef6f80eca6 Mon Sep 17 00:00:00 2001 From: Mohit Dhingra <mdhingra@nvidia.com> Date: Mon, 18 Mar 2019 17:26:18 +0530 Subject: [PATCH 014/458] nvethernetrm: add tmake support - Split files into core and dma directories to add separate tmake files for creating separate RM and DMA channel libraries. ESQC-7634 Change-Id: Id9a2431bbee73a29b4a3565d8aa2bc0d8e7f0c78 Signed-off-by: Mohit Dhingra <mdhingra@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2109978 Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- Makefile.umbrella.tmk | 34 ++++++ include/osi_common.h | 16 +-- include/osi_core.h | 197 +++++--------------------------- include/osi_dma.h | 123 ++++---------------- osi/core/Makefile.interface.tmk | 38 ++++++ osi/core/Makefile.tmk | 49 ++++++++ osi/{ => core}/eqos_core.c | 3 +- osi/{ => core}/eqos_core.h | 0 osi/core/libnvethernetrm.export | 45 ++++++++ osi/{ => core}/osi_common.c | 15 +++ osi/{ => core}/osi_core.c | 172 ++++++++++++++++++++++++++++ osi/dma/Makefile.interface.tmk | 39 +++++++ osi/dma/Makefile.tmk | 50 ++++++++ osi/{ => dma}/eqos_dma.c | 0 osi/{ => dma}/eqos_dma.h | 4 +- osi/dma/libnvethernetcl.export | 43 +++++++ osi/dma/osi_dma.c | 192 +++++++++++++++++++++++++++++++ osi/{ => dma}/osi_dma_txrx.c | 2 + osi/osi_dma.c | 81 ------------- 19 files changed, 734 insertions(+), 369 deletions(-) create mode 100644 Makefile.umbrella.tmk create mode 100644 osi/core/Makefile.interface.tmk create mode 100644 osi/core/Makefile.tmk rename osi/{ => core}/eqos_core.c (99%) rename osi/{ => core}/eqos_core.h (100%) create mode 100644 osi/core/libnvethernetrm.export rename osi/{ => core}/osi_common.c (94%) rename osi/{ => core}/osi_core.c (60%) create mode 100644 osi/dma/Makefile.interface.tmk create mode 100644 osi/dma/Makefile.tmk rename osi/{ => dma}/eqos_dma.c (100%) rename osi/{ => dma}/eqos_dma.h (98%) create mode 100644 osi/dma/libnvethernetcl.export create mode 100644 osi/dma/osi_dma.c rename osi/{ => dma}/osi_dma_txrx.c (99%) delete mode 100644 osi/osi_dma.c diff --git a/Makefile.umbrella.tmk b/Makefile.umbrella.tmk new file mode 100644 index 0000000..5dc0f13 --- /dev/null +++ b/Makefile.umbrella.tmk @@ -0,0 +1,34 @@ +################################### 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/include/osi_common.h b/include/osi_common.h index c14f2a2..ab7a86e 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -346,7 +346,7 @@ static inline void osi_writel(unsigned int val, void *addr) * * Return: 0 - for not Valid MAC, 1 - for Valid MAC */ -static int is_valid_mac_version(unsigned int mac_ver) +static inline int is_valid_mac_version(unsigned int mac_ver) { if ((mac_ver == OSI_EQOS_MAC_4_10) || (mac_ver == OSI_EQOS_MAC_5_00) || @@ -370,19 +370,7 @@ static int is_valid_mac_version(unsigned int mac_ver) * * Return: 0 - success, -1 - failure */ -static inline int osi_get_mac_version(void *addr, unsigned int *mac_ver) -{ - unsigned int macver; - int ret = 0; - - macver = osi_readl((unsigned char *)addr + MAC_VERSION) & MAC_VERSION_SNVER_MASK; - if (is_valid_mac_version(macver) == 0) { - return -1; - } - - *mac_ver = macver; - return ret; -} +int osi_get_mac_version(void *addr, unsigned int *mac_ver); void osi_get_hw_features(void *base, struct osi_hw_features *hw_feat); #endif /* OSI_COMMON_H */ diff --git a/include/osi_core.h b/include/osi_core.h index 9d828d2..3994801 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -141,17 +141,7 @@ struct osi_core_priv_data { * Return: 0 - success, -1 - failure */ -static inline int osi_poll_for_swr(struct osi_core_priv_data *osi_core) -{ - int ret = 0; - - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->poll_for_swr != OSI_NULL)) { - ret = osi_core->ops->poll_for_swr(osi_core->base); - } - - return ret; -} +int osi_poll_for_swr(struct osi_core_priv_data *osi_core); /** * osi_set_mdc_clk_rate - Derive MDC clock based on provided AXI_CBB clk. @@ -166,14 +156,8 @@ static inline int osi_poll_for_swr(struct osi_core_priv_data *osi_core) * * Return: None */ -static inline void osi_set_mdc_clk_rate(struct osi_core_priv_data *osi_core, - unsigned long csr_clk_rate) -{ - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->set_mdc_clk_rate != OSI_NULL)) { - osi_core->ops->set_mdc_clk_rate(osi_core, csr_clk_rate); - } -} +void osi_set_mdc_clk_rate(struct osi_core_priv_data *osi_core, + unsigned long csr_clk_rate); /** * osi_hw_core_init - EQOS MAC, MTL and common DMA initialization. @@ -187,20 +171,9 @@ static inline void osi_set_mdc_clk_rate(struct osi_core_priv_data *osi_core, * * Return: 0 - success, -1 - failure */ -static inline int osi_hw_core_init(struct osi_core_priv_data *osi_core, - unsigned int tx_fifo_size, - unsigned int rx_fifo_size) -{ - int ret = 0; - - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->core_init != OSI_NULL)) { - ret = osi_core->ops->core_init(osi_core, tx_fifo_size, - rx_fifo_size); - } - - return ret; -} +int osi_hw_core_init(struct osi_core_priv_data *osi_core, + unsigned int tx_fifo_size, + unsigned int rx_fifo_size); /** * osi_start_mac - Start MAC Tx/Rx engine @@ -211,13 +184,7 @@ static inline int osi_hw_core_init(struct osi_core_priv_data *osi_core, * Protection: None * Return: None */ -static inline void osi_start_mac(struct osi_core_priv_data *osi_core) -{ - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->start_mac != OSI_NULL)) { - osi_core->ops->start_mac(osi_core->base); - } -} +void osi_start_mac(struct osi_core_priv_data *osi_core); /** * osi_stop_mac - Stop MAC Tx/Rx engine @@ -228,13 +195,7 @@ static inline void osi_start_mac(struct osi_core_priv_data *osi_core) * Protection: None * Return: None */ -static inline void osi_stop_mac(struct osi_core_priv_data *osi_core) -{ - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->stop_mac != OSI_NULL)) { - osi_core->ops->stop_mac(osi_core->base); - } -} +void osi_stop_mac(struct osi_core_priv_data *osi_core); /** * osi_common_isr - Common ISR. @@ -251,13 +212,7 @@ static inline void osi_stop_mac(struct osi_core_priv_data *osi_core) * * Return: 0 - success, -1 - failure */ -static inline void osi_common_isr(struct osi_core_priv_data *osi_core) -{ - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->handle_common_intr != OSI_NULL)) { - osi_core->ops->handle_common_intr(osi_core); - } -} +void osi_common_isr(struct osi_core_priv_data *osi_core); /** * osi_set_mode - Set FD/HD mode. @@ -274,13 +229,7 @@ static inline void osi_common_isr(struct osi_core_priv_data *osi_core) * * Return: NONE */ -static inline void osi_set_mode(struct osi_core_priv_data *osi_core, int mode) -{ - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->set_mode != OSI_NULL)) { - osi_core->ops->set_mode(osi_core->base, mode); - } -} +void osi_set_mode(struct osi_core_priv_data *osi_core, int mode); /** * osi_set_speed - Set operating speed. @@ -297,13 +246,7 @@ static inline void osi_set_mode(struct osi_core_priv_data *osi_core, int mode) * * Return: NONE */ -static inline void osi_set_speed(struct osi_core_priv_data *osi_core, int speed) -{ - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->set_speed != OSI_NULL)) { - osi_core->ops->set_speed(osi_core->base, speed); - } -} +void osi_set_speed(struct osi_core_priv_data *osi_core, int speed); /** * osi_pad_calibrate - PAD calibration @@ -319,17 +262,7 @@ static inline void osi_set_speed(struct osi_core_priv_data *osi_core, int speed) * * Return: 0 - success, -1 - failure */ -static inline int osi_pad_calibrate(struct osi_core_priv_data *osi_core) -{ - int ret = 0; - - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->pad_calibrate != OSI_NULL)) { - ret = osi_core->ops->pad_calibrate(osi_core); - } - - return ret; -} +int osi_pad_calibrate(struct osi_core_priv_data *osi_core); /** * osi_flush_mtl_tx_queue - Flushing a MTL Tx Queue. @@ -345,18 +278,8 @@ static inline int osi_pad_calibrate(struct osi_core_priv_data *osi_core) * * Return: 0 - success, -1 - failure. */ -static inline int osi_flush_mtl_tx_queue(struct osi_core_priv_data *osi_core, - unsigned int qinx) -{ - int ret = 0; - - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->flush_mtl_tx_queue != OSI_NULL)) { - ret = osi_core->ops->flush_mtl_tx_queue(osi_core->base, qinx); - } - - return ret; -} +int osi_flush_mtl_tx_queue(struct osi_core_priv_data *osi_core, + unsigned int qinx); /** * osi_config_mac_loopback - Configure MAC loopback @@ -372,20 +295,8 @@ static inline int osi_flush_mtl_tx_queue(struct osi_core_priv_data *osi_core, * * Return: 0 - success, -1 - failure. */ -static inline int osi_config_mac_loopback(struct osi_core_priv_data *osi_core, - unsigned int lb_mode) -{ - int ret = -1; - - /* Configure MAC LoopBack */ - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->config_mac_loopback != OSI_NULL)) { - ret = osi_core->ops->config_mac_loopback(osi_core->base, - lb_mode); - } - - return ret; -} +int osi_config_mac_loopback(struct osi_core_priv_data *osi_core, + unsigned int lb_mode); /** * osi_set_avb - Set CBS algo and parameters @@ -400,18 +311,8 @@ static inline int osi_config_mac_loopback(struct osi_core_priv_data *osi_core, * * Return: Success = 0; failure = -1; */ -static inline int osi_set_avb(struct osi_core_priv_data *osi_core, - struct osi_core_avb_algorithm *avb) -{ - int ret = -1; - - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->set_avb_algorithm != OSI_NULL)) { - ret = osi_core->ops->set_avb_algorithm(osi_core, avb); - } - - return ret; -} +int osi_set_avb(struct osi_core_priv_data *osi_core, + struct osi_core_avb_algorithm *avb); /** * osi_get_avb - Set CBS algo and parameters @@ -426,18 +327,8 @@ static inline int osi_set_avb(struct osi_core_priv_data *osi_core, * * Return: Success = 0; failure = -1; */ -static inline int osi_get_avb(struct osi_core_priv_data *osi_core, - struct osi_core_avb_algorithm *avb) -{ - int ret = -1; - - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->get_avb_algorithm != OSI_NULL)) { - ret = osi_core->ops->get_avb_algorithm(osi_core, avb); - } - - return ret; -} +int osi_get_avb(struct osi_core_priv_data *osi_core, + struct osi_core_avb_algorithm *avb); /** * osi_configure_txstatus - Configure Tx packet status reporting @@ -454,20 +345,8 @@ static inline int osi_get_avb(struct osi_core_priv_data *osi_core, * * Return: 0 - success, -1 - failure. */ -static inline int osi_configure_txstatus(struct osi_core_priv_data *osi_core, - unsigned int tx_status) -{ - int ret = -1; - - /* Configure Drop Transmit Status */ - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->config_tx_status != OSI_NULL)) { - ret = osi_core->ops->config_tx_status(osi_core->base, - tx_status); - } - - return ret; -} +int osi_configure_txstatus(struct osi_core_priv_data *osi_core, + unsigned int tx_status); /** * osi_config_fw_err_pkts - Configure forwarding of error packets @@ -484,20 +363,8 @@ static inline int osi_configure_txstatus(struct osi_core_priv_data *osi_core, * * Return: 0 - success, -1 - failure. */ -static inline int osi_config_fw_err_pkts(struct osi_core_priv_data *osi_core, - unsigned int qinx, unsigned int fw_err) -{ - int ret = -1; - - /* Configure Forwarding of Error packets */ - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->config_fw_err_pkts != OSI_NULL)) { - ret = osi_core->ops->config_fw_err_pkts(osi_core->base, - qinx, fw_err); - } - - return ret; -} +int osi_config_fw_err_pkts(struct osi_core_priv_data *osi_core, + unsigned int qinx, unsigned int fw_err); /** * osi_config_rx_crc_check - Configure CRC Checking for Received Packets @@ -515,20 +382,8 @@ static inline int osi_config_fw_err_pkts(struct osi_core_priv_data *osi_core, * * Return: 0 - success, -1 - failure. */ -static inline int osi_config_rx_crc_check(struct osi_core_priv_data *osi_core, - unsigned int crc_chk) -{ - int ret = -1; - - /* Configure CRC Checking for Received Packets */ - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->config_rx_crc_check != OSI_NULL)) { - ret = osi_core->ops->config_rx_crc_check(osi_core->base, - crc_chk); - } - - return ret; -} +int osi_config_rx_crc_check(struct osi_core_priv_data *osi_core, + unsigned int crc_chk); int osi_write_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, unsigned int phyreg, unsigned short phydata); diff --git a/include/osi_dma.h b/include/osi_dma.h index a06df16..ef98906 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -259,14 +259,8 @@ struct osi_dma_priv_data { * * Return: None. */ -static inline void osi_disable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, - unsigned int chan) -{ - if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && - (osi_dma->ops->disable_chan_tx_intr != OSI_NULL)) { - osi_dma->ops->disable_chan_tx_intr(osi_dma->base, chan); - } -} +void osi_disable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, + unsigned int chan); /** * osi_enable_chan_tx_intr - Enable DMA Tx channel interrupts. @@ -281,14 +275,8 @@ static inline void osi_disable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, * * Return: None. */ -static inline void osi_enable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, - unsigned int chan) -{ - if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && - (osi_dma->ops->enable_chan_tx_intr != OSI_NULL)) { - osi_dma->ops->enable_chan_tx_intr(osi_dma->base, chan); - } -} +void osi_enable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, + unsigned int chan); /** * osi_disable_chan_rx_intr - Disable DMA Rx channel interrupts. @@ -303,14 +291,8 @@ static inline void osi_enable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, * * Return: None. */ -static inline void osi_disable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, - unsigned int chan) -{ - if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && - (osi_dma->ops->disable_chan_rx_intr != OSI_NULL)) { - osi_dma->ops->disable_chan_rx_intr(osi_dma->base, chan); - } -} +void osi_disable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, + unsigned int chan); /** * osi_enable_chan_rx_intr - Enable DMA Rx channel interrupts. @@ -325,14 +307,8 @@ static inline void osi_disable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, * * Return: None. */ -static inline void osi_enable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, - unsigned int chan) -{ - if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && - (osi_dma->ops->enable_chan_rx_intr != OSI_NULL)) { - osi_dma->ops->enable_chan_rx_intr(osi_dma->base, chan); - } -} +void osi_enable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, + unsigned int chan); /** * osi_clear_tx_intr - Handles Tx interrupt source. @@ -347,14 +323,8 @@ static inline void osi_enable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, * * Return: None. */ -static inline void osi_clear_tx_intr(struct osi_dma_priv_data *osi_dma, - unsigned int chan) -{ - if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && - (osi_dma->ops->clear_tx_intr != OSI_NULL)) { - osi_dma->ops->clear_tx_intr(osi_dma->base, chan); - } -} +void osi_clear_tx_intr(struct osi_dma_priv_data *osi_dma, + unsigned int chan); /** * osi_clear_rx_intr - Handles Rx interrupt source. @@ -369,14 +339,8 @@ static inline void osi_clear_tx_intr(struct osi_dma_priv_data *osi_dma, * * Return: None. */ -static inline void osi_clear_rx_intr(struct osi_dma_priv_data *osi_dma, - unsigned int chan) -{ - if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && - (osi_dma->ops->clear_rx_intr != OSI_NULL)) { - osi_dma->ops->clear_rx_intr(osi_dma->base, chan); - } -} +void osi_clear_rx_intr(struct osi_dma_priv_data *osi_dma, + unsigned int chan); /** * osi_start_dma - Start DMA @@ -388,14 +352,8 @@ static inline void osi_clear_rx_intr(struct osi_dma_priv_data *osi_dma, * Protection: None * Return: None */ -static inline void osi_start_dma(struct osi_dma_priv_data *osi_dma, - unsigned int chan) -{ - if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && - (osi_dma->ops->start_dma != OSI_NULL)) { - osi_dma->ops->start_dma(osi_dma->base, chan); - } -} +void osi_start_dma(struct osi_dma_priv_data *osi_dma, + unsigned int chan); /** * osi_stop_dma - Stop DMA @@ -407,14 +365,8 @@ static inline void osi_start_dma(struct osi_dma_priv_data *osi_dma, * Protection: None * Return: None */ -static inline void osi_stop_dma(struct osi_dma_priv_data *osi_dma, - unsigned int chan) -{ - if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && - (osi_dma->ops->stop_dma != OSI_NULL)) { - osi_dma->ops->stop_dma(osi_dma->base, chan); - } -} +void osi_stop_dma(struct osi_dma_priv_data *osi_dma, + unsigned int chan); /** * osi_get_refill_rx_desc_cnt - Rx descriptors count that needs to refill. @@ -429,10 +381,7 @@ static inline void osi_stop_dma(struct osi_dma_priv_data *osi_dma, * * Return: Number of available free descriptors. */ -static inline unsigned int osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring) -{ - return (rx_ring->cur_rx_idx - rx_ring->refill_idx) & (RX_DESC_CNT - 1U); -} +unsigned int osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring); /** * osi_rx_dma_desc_init - DMA Rx descriptor init @@ -447,14 +396,8 @@ static inline unsigned int osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_rin * * Return: None. */ -static inline void osi_rx_dma_desc_init(struct osi_rx_swcx *rx_swcx, - struct osi_rx_desc *rx_desc) -{ - rx_desc->rdes0 = (unsigned int)L32(rx_swcx->buf_phy_addr); - rx_desc->rdes1 = (unsigned int)H32(rx_swcx->buf_phy_addr); - rx_desc->rdes2 = 0; - rx_desc->rdes3 = (RDES3_OWN | RDES3_IOC | RDES3_B1V); -} +void osi_rx_dma_desc_init(struct osi_rx_swcx *rx_swcx, + struct osi_rx_desc *rx_desc); /** * osi_update_rx_tailptr - Updates DMA Rx ring tail pointer @@ -470,22 +413,9 @@ static inline void osi_rx_dma_desc_init(struct osi_rx_swcx *rx_swcx, * * Return: None. */ -static inline void osi_update_rx_tailptr(struct osi_dma_priv_data *osi_dma, - struct osi_rx_ring *rx_ring, - unsigned int chan) -{ - unsigned long tailptr = 0; - unsigned int refill_idx = rx_ring->refill_idx; - - DECR_RX_DESC_INDEX(refill_idx, 1U); - tailptr = rx_ring->rx_desc_phy_addr + - (refill_idx * sizeof(struct osi_rx_desc)); - - if (osi_dma != OSI_NULL && osi_dma->ops != OSI_NULL && - osi_dma->ops->update_rx_tailptr != OSI_NULL) { - osi_dma->ops->update_rx_tailptr(osi_dma->base, chan, tailptr); - } -} +void osi_update_rx_tailptr(struct osi_dma_priv_data *osi_dma, + struct osi_rx_ring *rx_ring, + unsigned int chan); /** * osi_set_rx_buf_len - Updates rx buffer length. @@ -499,14 +429,7 @@ static inline void osi_update_rx_tailptr(struct osi_dma_priv_data *osi_dma, * * Return: None. */ - -static inline void osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) -{ - if (osi_dma != OSI_NULL && osi_dma->ops != OSI_NULL && - osi_dma->ops->set_rx_buf_len != OSI_NULL) { - osi_dma->ops->set_rx_buf_len(osi_dma); - } -} +void osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma); void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan); int osi_process_tx_completions(struct osi_dma_priv_data *osi, diff --git a/osi/core/Makefile.interface.tmk b/osi/core/Makefile.interface.tmk new file mode 100644 index 0000000..4637979 --- /dev/null +++ b/osi/core/Makefile.interface.tmk @@ -0,0 +1,38 @@ +################################### 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 new file mode 100644 index 0000000..516063b --- /dev/null +++ b/osi/core/Makefile.tmk @@ -0,0 +1,49 @@ +################################### 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. +# +############################################################################### + +ifdef NV_COMPONENT_FLAG_SHARED_LIBRARY_SECTION +include $(NV_BUILD_START_COMPONENT) + +NV_COMPONENT_NAME := nvethernetrm +NV_COMPONENT_OWN_INTERFACE_DIR := . +NV_COMPONENT_SOURCES := \ + eqos_core.c \ + osi_common.c \ + osi_core.c + +NV_COMPONENT_NEEDED_INTERFACE_DIRS := \ + $(NV_SOURCE)/qnx/src/libs/nvethernet/osi_dependencies + +NV_COMPONENT_INCLUDES := \ + $(NV_SOURCE)/nvethernetrm/include \ + $(NV_SOURCE)/core/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/eqos_core.c b/osi/core/eqos_core.c similarity index 99% rename from osi/eqos_core.c rename to osi/core/eqos_core.c index 911274e..2db301f 100644 --- a/osi/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1174,7 +1174,8 @@ static int eqos_get_avb_algorithm(struct osi_core_priv_data *osi_core, EQOS_MTL_TXQ_ETS_CR_AVALG_SHIFT; /* Get Send slope credit */ - value = osi_readl(osi_core->base + EQOS_MTL_TXQ_ETS_SSCR(qinx)); + value = osi_readl((unsigned char *)osi_core->base + + EQOS_MTL_TXQ_ETS_SSCR(qinx)); avb->send_slope = value & EQOS_MTL_TXQ_ETS_SSCR_SSC_MASK; /* Get Idle slope credit*/ diff --git a/osi/eqos_core.h b/osi/core/eqos_core.h similarity index 100% rename from osi/eqos_core.h rename to osi/core/eqos_core.h diff --git a/osi/core/libnvethernetrm.export b/osi/core/libnvethernetrm.export new file mode 100644 index 0000000..fbdc186 --- /dev/null +++ b/osi/core/libnvethernetrm.export @@ -0,0 +1,45 @@ +################################### 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 export +# +############################################################################### +osi_init_core_ops +osi_write_phy_reg +osi_read_phy_reg +osi_poll_for_swr +osi_set_mdc_clk_rate +osi_hw_core_init +osi_start_mac +osi_stop_mac +osi_common_isr +osi_set_mode +osi_set_speed +osi_pad_calibrate +osi_flush_mtl_tx_queue +osi_config_mac_loopback +osi_set_avb +osi_get_avb +osi_configure_txstatus +osi_config_rx_crc_check +osi_get_mac_version +osi_get_hw_features diff --git a/osi/osi_common.c b/osi/core/osi_common.c similarity index 94% rename from osi/osi_common.c rename to osi/core/osi_common.c index ffa5209..ba8da0a 100644 --- a/osi/osi_common.c +++ b/osi/core/osi_common.c @@ -118,3 +118,18 @@ void osi_get_hw_features(void *base, struct osi_hw_features *hw_feat) hw_feat->aux_snap_num = ((mac_hfr2 >> 28U) & EQOS_MAC_HFR2_AUXSNAPNUM_MASK); } + +int osi_get_mac_version(void *addr, unsigned int *mac_ver) +{ + unsigned int macver; + int ret = 0; + + macver = osi_readl((unsigned char *)addr + MAC_VERSION) & + MAC_VERSION_SNVER_MASK; + if (is_valid_mac_version(macver) == 0) { + return -1; + } + + *mac_ver = macver; + return ret; +} diff --git a/osi/osi_core.c b/osi/core/osi_core.c similarity index 60% rename from osi/osi_core.c rename to osi/core/osi_core.c index 6e290af..79a975a 100644 --- a/osi/osi_core.c +++ b/osi/core/osi_core.c @@ -225,3 +225,175 @@ void osi_init_core_ops(struct osi_core_priv_data *osi_core) osi_core->ops = eqos_get_hw_core_ops(); } } + +int osi_poll_for_swr(struct osi_core_priv_data *osi_core) +{ + int ret = 0; + + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->poll_for_swr != OSI_NULL)) { + ret = osi_core->ops->poll_for_swr(osi_core->base); + } + + return ret; +} + +void osi_set_mdc_clk_rate(struct osi_core_priv_data *osi_core, + unsigned long csr_clk_rate) +{ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->set_mdc_clk_rate != OSI_NULL)) { + osi_core->ops->set_mdc_clk_rate(osi_core, csr_clk_rate); + } +} + +int osi_hw_core_init(struct osi_core_priv_data *osi_core, + unsigned int tx_fifo_size, + unsigned int rx_fifo_size) +{ + int ret = 0; + + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->core_init != OSI_NULL)) { + ret = osi_core->ops->core_init(osi_core, tx_fifo_size, + rx_fifo_size); + } + + return ret; +} + +void osi_start_mac(struct osi_core_priv_data *osi_core) +{ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->start_mac != OSI_NULL)) { + osi_core->ops->start_mac(osi_core->base); + } +} + +void osi_stop_mac(struct osi_core_priv_data *osi_core) +{ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->stop_mac != OSI_NULL)) { + osi_core->ops->stop_mac(osi_core->base); + } +} + +void osi_common_isr(struct osi_core_priv_data *osi_core) +{ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->handle_common_intr != OSI_NULL)) { + osi_core->ops->handle_common_intr(osi_core); + } +} + +void osi_set_mode(struct osi_core_priv_data *osi_core, int mode) +{ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->set_mode != OSI_NULL)) { + osi_core->ops->set_mode(osi_core->base, mode); + } +} + +void osi_set_speed(struct osi_core_priv_data *osi_core, int speed) +{ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->set_speed != OSI_NULL)) { + osi_core->ops->set_speed(osi_core->base, speed); + } +} + +int osi_pad_calibrate(struct osi_core_priv_data *osi_core) +{ + int ret = 0; + + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->pad_calibrate != OSI_NULL)) { + ret = osi_core->ops->pad_calibrate(osi_core); + } + + return ret; +} + +int osi_flush_mtl_tx_queue(struct osi_core_priv_data *osi_core, + unsigned int qinx) +{ + int ret = 0; + + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->flush_mtl_tx_queue != OSI_NULL)) { + ret = osi_core->ops->flush_mtl_tx_queue(osi_core->base, qinx); + } + + return ret; +} + +int osi_config_mac_loopback(struct osi_core_priv_data *osi_core, + unsigned int lb_mode) +{ + int ret = -1; + + /* Configure MAC LoopBack */ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->config_mac_loopback != OSI_NULL)) { + ret = osi_core->ops->config_mac_loopback(osi_core->base, + lb_mode); + } + + return ret; +} + +int osi_set_avb(struct osi_core_priv_data *osi_core, + struct osi_core_avb_algorithm *avb) +{ + int ret = -1; + + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->set_avb_algorithm != OSI_NULL)) { + ret = osi_core->ops->set_avb_algorithm(osi_core, avb); + } + + return ret; +} + +int osi_get_avb(struct osi_core_priv_data *osi_core, + struct osi_core_avb_algorithm *avb) +{ + int ret = -1; + + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->get_avb_algorithm != OSI_NULL)) { + ret = osi_core->ops->get_avb_algorithm(osi_core, avb); + } + + return ret; +} + +int osi_configure_txstatus(struct osi_core_priv_data *osi_core, + unsigned int tx_status) +{ + int ret = -1; + + /* Configure Drop Transmit Status */ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->config_tx_status != OSI_NULL)) { + ret = osi_core->ops->config_tx_status(osi_core->base, + tx_status); + } + + return ret; +} + +int osi_config_rx_crc_check(struct osi_core_priv_data *osi_core, + unsigned int crc_chk) +{ + int ret = -1; + + /* Configure CRC Checking for Received Packets */ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->config_rx_crc_check != OSI_NULL)) { + ret = osi_core->ops->config_rx_crc_check(osi_core->base, + crc_chk); + } + + return ret; +} diff --git a/osi/dma/Makefile.interface.tmk b/osi/dma/Makefile.interface.tmk new file mode 100644 index 0000000..c12901e --- /dev/null +++ b/osi/dma/Makefile.interface.tmk @@ -0,0 +1,39 @@ +################################### 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 new file mode 100644 index 0000000..e61be7b --- /dev/null +++ b/osi/dma/Makefile.tmk @@ -0,0 +1,50 @@ +################################### 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. +# +############################################################################### + +ifdef NV_COMPONENT_FLAG_SHARED_LIBRARY_SECTION +include $(NV_BUILD_START_COMPONENT) + +NV_COMPONENT_NAME := nvethernetcl +NV_COMPONENT_OWN_INTERFACE_DIR := . +NV_COMPONENT_SOURCES := \ + eqos_dma.c \ + osi_dma.c \ + osi_dma_txrx.c + +NV_COMPONENT_NEEDED_INTERFACE_DIRS := \ + $(NV_SOURCE)/qnx/src/libs/nvethernet/osi_dependencies + +NV_COMPONENT_INCLUDES := \ + $(NV_SOURCE)/nvethernetrm/include \ + $(NV_SOURCE)/core/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/eqos_dma.c b/osi/dma/eqos_dma.c similarity index 100% rename from osi/eqos_dma.c rename to osi/dma/eqos_dma.c diff --git a/osi/eqos_dma.h b/osi/dma/eqos_dma.h similarity index 98% rename from osi/eqos_dma.h rename to osi/dma/eqos_dma.h index 39bd892..322acc2 100644 --- a/osi/eqos_dma.h +++ b/osi/dma/eqos_dma.h @@ -20,8 +20,8 @@ * DEALINGS IN THE SOFTWARE. */ -#ifndef EQOS_H_ -#define EQOS_H_ +#ifndef EQOS_DMA_H_ +#define EQOS_DMA_H_ #define EQOS_AXI_BUS_WIDTH 0x10U diff --git a/osi/dma/libnvethernetcl.export b/osi/dma/libnvethernetcl.export new file mode 100644 index 0000000..d9bbb0c --- /dev/null +++ b/osi/dma/libnvethernetcl.export @@ -0,0 +1,43 @@ +################################### 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 export +# +############################################################################### +osi_disable_chan_tx_intr +osi_enable_chan_tx_intr +osi_disable_chan_rx_intr +osi_enable_chan_rx_intr +osi_clear_tx_intr +osi_clear_rx_intr +osi_start_dma +osi_stop_dma +osi_get_refill_rx_desc_cnt +osi_rx_dma_desc_init +osi_update_rx_tailptr +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 diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c new file mode 100644 index 0000000..f62de65 --- /dev/null +++ b/osi/dma/osi_dma.c @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <osi_dma.h> + +extern int dma_desc_init(struct osi_dma_priv_data *osi_dma); +extern struct osi_dma_chan_ops *eqos_get_dma_chan_ops(void); + +void osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) +{ + if (osi_dma->mac == OSI_MAC_HW_EQOS) { + /* Get EQOS HW ops */ + osi_dma->ops = eqos_get_dma_chan_ops(); + } +} + +int osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) +{ + unsigned int i, chan; + int ret; + + if (osi_dma->ops->init_dma_channel != OSI_NULL) { + osi_dma->ops->init_dma_channel(osi_dma); + } + + ret = dma_desc_init(osi_dma); + if (ret != 0) { + return ret; + } + + /* 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]; + + osi_enable_chan_tx_intr(osi_dma, chan); + osi_enable_chan_rx_intr(osi_dma, chan); + osi_start_dma(osi_dma, chan); + } + + return 0; +} + +/** + * osi_hw_deinit - De-init the HW + * @osi: OSI private data structure. + * + * Algorithm: + * 1) Stop the DMA + * 2) free all allocated resources. + * + * Dependencies: None + * Protection: None + * Return: None + */ +void osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma) +{ + unsigned int i; + + for (i = 0; i < osi_dma->num_dma_chans; i++) { + osi_stop_dma(osi_dma, osi_dma->dma_chans[i]); + } +} + +void osi_disable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, + unsigned int chan) +{ + if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && + (osi_dma->ops->disable_chan_tx_intr != OSI_NULL)) { + osi_dma->ops->disable_chan_tx_intr(osi_dma->base, chan); + } +} + +void osi_enable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, + unsigned int chan) +{ + if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && + (osi_dma->ops->enable_chan_tx_intr != OSI_NULL)) { + osi_dma->ops->enable_chan_tx_intr(osi_dma->base, chan); + } +} + +void osi_disable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, + unsigned int chan) +{ + if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && + (osi_dma->ops->disable_chan_rx_intr != OSI_NULL)) { + osi_dma->ops->disable_chan_rx_intr(osi_dma->base, chan); + } +} + +void osi_enable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, + unsigned int chan) +{ + if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && + (osi_dma->ops->enable_chan_rx_intr != OSI_NULL)) { + osi_dma->ops->enable_chan_rx_intr(osi_dma->base, chan); + } +} + +void osi_clear_tx_intr(struct osi_dma_priv_data *osi_dma, + unsigned int chan) +{ + if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && + (osi_dma->ops->clear_tx_intr != OSI_NULL)) { + osi_dma->ops->clear_tx_intr(osi_dma->base, chan); + } +} + +void osi_clear_rx_intr(struct osi_dma_priv_data *osi_dma, + unsigned int chan) +{ + if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && + (osi_dma->ops->clear_rx_intr != OSI_NULL)) { + osi_dma->ops->clear_rx_intr(osi_dma->base, chan); + } +} + +void osi_start_dma(struct osi_dma_priv_data *osi_dma, + unsigned int chan) +{ + if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && + (osi_dma->ops->start_dma != OSI_NULL)) { + osi_dma->ops->start_dma(osi_dma->base, chan); + } +} + +void osi_stop_dma(struct osi_dma_priv_data *osi_dma, + unsigned int chan) +{ + if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && + (osi_dma->ops->stop_dma != OSI_NULL)) { + osi_dma->ops->stop_dma(osi_dma->base, chan); + } +} + +unsigned int osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring) +{ + return (rx_ring->cur_rx_idx - rx_ring->refill_idx) & (RX_DESC_CNT - 1U); +} + +void osi_rx_dma_desc_init(struct osi_rx_swcx *rx_swcx, + struct osi_rx_desc *rx_desc) +{ + rx_desc->rdes0 = (unsigned int)L32(rx_swcx->buf_phy_addr); + rx_desc->rdes1 = (unsigned int)H32(rx_swcx->buf_phy_addr); + rx_desc->rdes2 = 0; + rx_desc->rdes3 = (RDES3_OWN | RDES3_IOC | RDES3_B1V); +} + +void osi_update_rx_tailptr(struct osi_dma_priv_data *osi_dma, + struct osi_rx_ring *rx_ring, + unsigned int chan) +{ + unsigned long tailptr = 0; + unsigned int refill_idx = rx_ring->refill_idx; + + DECR_RX_DESC_INDEX(refill_idx, 1U); + tailptr = rx_ring->rx_desc_phy_addr + + (refill_idx * sizeof(struct osi_rx_desc)); + + if (osi_dma != OSI_NULL && osi_dma->ops != OSI_NULL && + osi_dma->ops->update_rx_tailptr != OSI_NULL) { + osi_dma->ops->update_rx_tailptr(osi_dma->base, chan, tailptr); + } +} + +void osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) +{ + if (osi_dma != OSI_NULL && osi_dma->ops != OSI_NULL && + osi_dma->ops->set_rx_buf_len != OSI_NULL) { + osi_dma->ops->set_rx_buf_len(osi_dma); + } +} diff --git a/osi/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c similarity index 99% rename from osi/osi_dma_txrx.c rename to osi/dma/osi_dma_txrx.c index 5220929..ec55c8d 100644 --- a/osi/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -24,6 +24,8 @@ #include <osi_dma.h> #include <osi_dma_txrx.h> +int dma_desc_init(struct osi_dma_priv_data *osi_dma); + static inline void osi_memset(void *s, int c, unsigned long count) { char *xs = s; diff --git a/osi/osi_dma.c b/osi/osi_dma.c deleted file mode 100644 index 6ad8e39..0000000 --- a/osi/osi_dma.c +++ /dev/null @@ -1,81 +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. - */ - -#include <osi_dma.h> - -extern int dma_desc_init(struct osi_dma_priv_data *osi_dma); -extern struct osi_dma_chan_ops *eqos_get_dma_chan_ops(void); - -void osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) -{ - if (osi_dma->mac == OSI_MAC_HW_EQOS) { - /* Get EQOS HW ops */ - osi_dma->ops = eqos_get_dma_chan_ops(); - } -} - -int osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) -{ - unsigned int i, chan; - int ret; - - if (osi_dma->ops->init_dma_channel != OSI_NULL) { - osi_dma->ops->init_dma_channel(osi_dma); - } - - ret = dma_desc_init(osi_dma); - if (ret != 0) { - return ret; - } - - /* 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]; - - osi_enable_chan_tx_intr(osi_dma, chan); - osi_enable_chan_rx_intr(osi_dma, chan); - osi_start_dma(osi_dma, chan); - } - - return 0; -} - -/** - * osi_hw_deinit - De-init the HW - * @osi: OSI private data structure. - * - * Algorithm: - * 1) Stop the DMA - * 2) free all allocated resources. - * - * Dependencies: None - * Protection: None - * Return: None - */ -void osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma) -{ - unsigned int i; - - for (i = 0; i < osi_dma->num_dma_chans; i++) { - osi_stop_dma(osi_dma, osi_dma->dma_chans[i]); - } -} From c5fb6ad4b392b5c6e45f8ade598dc2155c2c69cd Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Sat, 4 May 2019 19:28:58 +0530 Subject: [PATCH 015/458] nvethernetrm: add pause frame support Pause frame is a flow control mechanism for temporarily stopping the transmission of data on Ethernet. The goal of this mechanism is to ensure zero packet loss in case of network congestion. Bug 200516459 Change-Id: Ideaaecd346bc7f509fbe2fc8e915b9e1fc45c958 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2111934 Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_common.h | 14 ++- include/osi_core.h | 25 +++++ osi/core/eqos_core.c | 249 +++++++++++++++++++++++++++++++++++++++---- osi/core/eqos_core.h | 25 +++++ osi/core/osi_core.c | 30 ++++++ 5 files changed, 316 insertions(+), 27 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index ab7a86e..8ce17ba 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -23,11 +23,17 @@ #ifndef OSI_COMMON_H #define OSI_COMMON_H -#define OSI_ADDRESS_32BIT 0 -#define OSI_ADDRESS_40BIT 1 -#define OSI_ADDRESS_48BIT 2 +#define OSI_PAUSE_FRAMES_ENABLE 0U +#define OSI_PAUSE_FRAMES_DISABLE 1U +#define OSI_FLOW_CTRL_TX OSI_BIT(0) +#define OSI_FLOW_CTRL_RX OSI_BIT(1) +#define OSI_FLOW_CTRL_DISABLE 0U -#define ULONG_MAX (~0UL) +#define OSI_ADDRESS_32BIT 0 +#define OSI_ADDRESS_40BIT 1 +#define OSI_ADDRESS_48BIT 2 + +#define ULONG_MAX (~0UL) /* Default maximum Gaint Packet Size Limit */ #define OSI_MAX_MTU_SIZE 9000U diff --git a/include/osi_core.h b/include/osi_core.h index 3994801..3066313 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -71,6 +71,7 @@ struct osi_core_avb_algorithm { * @config_fw_err_pkts: Called to configure MTL RxQ to forward the err pkt. * @config_tx_status: Called to configure the MTL to forward/drop tx status * @config_rx_crc_check: Called to configure the MAC rx crc. + * @config_flow_control: Called to configure the MAC flow control. */ struct osi_core_ops { /* initialize MAC/MTL/DMA Common registers */ @@ -96,6 +97,7 @@ struct osi_core_ops { unsigned int fw_err); int (*config_tx_status)(void *addr, unsigned int tx_status); int (*config_rx_crc_check)(void *addr, unsigned int crc_chk); + int (*config_flow_control)(void *addr, unsigned int flw_ctrl); }; /** @@ -112,6 +114,8 @@ struct osi_core_ops { * @mdc_cr: MDC clock rate. * @mtu: MTU size * @mac_addr: Ethernet MAC address. + * @pause_frames: DT entry to enable(0) or disable(1) pause frame support + * @flow_ctrl: Current flow control settings */ struct osi_core_priv_data { void *base; @@ -125,6 +129,8 @@ struct osi_core_priv_data { unsigned int mdc_cr; unsigned int mtu; unsigned char mac_addr[OSI_ETH_ALEN]; + unsigned int pause_frames; + unsigned int flow_ctrl; }; /** @@ -385,6 +391,25 @@ int osi_config_fw_err_pkts(struct osi_core_priv_data *osi_core, int osi_config_rx_crc_check(struct osi_core_priv_data *osi_core, unsigned int crc_chk); +/** + * osi_configure_flow_ctrl - Configure flow control settings + * @osi_core: OSI core private data structure. + * @crc_chk: Enable or disable flow control settings + * + * Algorithm: This will enable or disable the flow control. + * flw_ctrl BIT0 is for tx flow ctrl enable/disable + * flw_ctrl BIT1 is for rx flow ctrl enable/disable + * + * Dependencies: MAC IP should be out of reset and need to be initialized + * as per the requirements + * + * Protection: None + * + * Return: 0 - success, -1 - failure. + */ +int osi_configure_flow_control(struct osi_core_priv_data *osi_core, + unsigned int flw_ctrl); + int osi_write_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, unsigned int phyreg, unsigned short phydata); int osi_read_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 2db301f..55a9244 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -28,7 +28,71 @@ struct osi_core_ops *eqos_get_hw_core_ops(void); /** - * eqos_osi_config_rx_crc_check - Configure CRC Checking for Rx Packets + * eqos_config_flow_control - Configure MAC flow control settings + * @addr: MAC base address. + * @flw_ctrl: flw_ctrl settings + * + * Algorithm: + * + * Dependencies: MAC has to be out of reset. + * + * Protection: None. + * + * Return: 0 - success, -1 - failure + */ +static int eqos_config_flow_control(void *addr, unsigned int flw_ctrl) +{ + unsigned int val; + + /* 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_readl((unsigned char *)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 */ + osi_writel(val, (unsigned char *)addr + EQOS_MAC_QX_TX_FLW_CTRL(0U)); + + /* Configure MAC Rx Flow control*/ + /* Read MAC Rx Flow control Register */ + val = osi_readl((unsigned char *)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_writel(val, (unsigned char *)addr + EQOS_MAC_RX_FLW_CTRL); + + return 0; +} + +/** + * eqos_config_rx_crc_check - Configure CRC Checking for Rx Packets * @addr: MAC base address. * @crc_chk: Enable or disable checking of CRC field in received packets * @@ -528,7 +592,8 @@ static int eqos_pad_calibrate(void *ioaddr) } count++; osd_usleep_range(10, 12); - value = osi_readl((unsigned char *)ioaddr + EQOS_PAD_AUTO_CAL_STAT); + value = osi_readl((unsigned char *)ioaddr + + EQOS_PAD_AUTO_CAL_STAT); /* calibration done when CAL_STAT_ACTIVE is zero */ if ((value & EQOS_PAD_AUTO_CAL_STAT_ACTIVE) == 0U) { cond = 0; @@ -566,9 +631,11 @@ static int eqos_flush_mtl_tx_queue(void *addr, unsigned int qinx) int cond = 1; /* Read Tx Q Operating Mode Register and flush TxQ */ - value = osi_readl((unsigned char *)addr + EQOS_MTL_CHX_TX_OP_MODE(qinx)); + value = osi_readl((unsigned char *)addr + + EQOS_MTL_CHX_TX_OP_MODE(qinx)); value |= EQOS_MTL_QTOMR_FTQ; - osi_writel(value, (unsigned char *)addr + EQOS_MTL_CHX_TX_OP_MODE(qinx)); + osi_writel(value, (unsigned char *)addr + + EQOS_MTL_CHX_TX_OP_MODE(qinx)); /* Poll Until FTQ bit resets for Successful Tx Q flush */ count = 0; @@ -580,7 +647,8 @@ static int eqos_flush_mtl_tx_queue(void *addr, unsigned int qinx) count++; osd_msleep(1); - value = osi_readl((unsigned char *)addr + EQOS_MTL_CHX_TX_OP_MODE(qinx)); + value = osi_readl((unsigned char *)addr + + EQOS_MTL_CHX_TX_OP_MODE(qinx)); if ((value & EQOS_MTL_QTOMR_FTQ_LPOS) == 0U) { cond = 0; @@ -590,6 +658,105 @@ static int eqos_flush_mtl_tx_queue(void *addr, unsigned int qinx) return 0; } +/** + * update_ehfc_rfa_rfd - Update EHFC, RFD and RSA values + * @rx_fifo: Rx FIFO size. + * @value: Stores 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 and also enables HW flow control + * + * Dependencies: None. + * + * Protection: None. + * + * Return: None. + */ +void update_ehfc_rfa_rfd(unsigned int rx_fifo, unsigned int *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; + } + } +} + /** * eqos_configure_mtl_queue - Configure MTL Queue * @qinx: Queue number that need to be configured. @@ -630,24 +797,37 @@ static int eqos_configure_mtl_queue(unsigned int qinx, value |= EQOS_MTL_TSF; /* Enable TxQ */ value |= EQOS_MTL_TXQEN; - osi_writel(value, (unsigned char *)osi_core->base + EQOS_MTL_CHX_TX_OP_MODE(qinx)); + osi_writel(value, (unsigned char *)osi_core->base + + EQOS_MTL_CHX_TX_OP_MODE(qinx)); /* read RX Q0 Operating Mode Register */ - value = osi_readl((unsigned char *)osi_core->base + EQOS_MTL_CHX_RX_OP_MODE(qinx)); + value = osi_readl((unsigned char *)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; - osi_writel(value, (unsigned char *)osi_core->base + EQOS_MTL_CHX_RX_OP_MODE(qinx)); + /* 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); + osi_writel(value, (unsigned char *)osi_core->base + + EQOS_MTL_CHX_RX_OP_MODE(qinx)); /* Transmit Queue weight */ - value = osi_readl((unsigned char *)osi_core->base + EQOS_MTL_TXQ_QW(qinx)); + value = osi_readl((unsigned char *)osi_core->base + + EQOS_MTL_TXQ_QW(qinx)); value |= (EQOS_MTL_TXQ_QW_ISCQW + qinx); - osi_writel(value, (unsigned char *)osi_core->base + EQOS_MTL_TXQ_QW(qinx)); + osi_writel(value, (unsigned char *)osi_core->base + + EQOS_MTL_TXQ_QW(qinx)); /* Enable Rx Queue Control */ - value = osi_readl((unsigned char *)osi_core->base + EQOS_MAC_RQC0R); + value = osi_readl((unsigned char *)osi_core->base + + EQOS_MAC_RQC0R); value |= ((osi_core->rxq_ctrl[qinx] & 0x3U) << (qinx * 2U)); - osi_writel(value, (unsigned char *)osi_core->base + EQOS_MAC_RQC0R); + osi_writel(value, (unsigned char *)osi_core->base + + EQOS_MAC_RQC0R); return 0; } @@ -673,6 +853,7 @@ static int eqos_configure_mtl_queue(unsigned int qinx, static void eqos_configure_mac(struct osi_core_priv_data *osi_core) { unsigned int value; + /* Update MAC address 0 high */ osi_writel((((unsigned int)osi_core->mac_addr[5] << 8U) | (unsigned int)(osi_core->mac_addr[4])), @@ -709,11 +890,14 @@ static void eqos_configure_mac(struct osi_core_priv_data *osi_core) /* Disable all MMC interrupts */ /* Disable all MMC Tx Interrupts */ - osi_writel(0xFFFFFFFFU, (unsigned char *)osi_core->base + EQOS_MMC_TX_INTR_MASK); + osi_writel(0xFFFFFFFFU, (unsigned char *)osi_core->base + + EQOS_MMC_TX_INTR_MASK); /* Disable all MMC RX interrupts */ - osi_writel(0xFFFFFFFFU, (unsigned char *)osi_core->base + EQOS_MMC_RX_INTR_MASK); + osi_writel(0xFFFFFFFFU, (unsigned char *)osi_core->base + + EQOS_MMC_RX_INTR_MASK); /* Disable MMC Rx interrupts for IPC */ - osi_writel(0xFFFFFFFFU, (unsigned char *)osi_core->base + EQOS_MMC_IPC_RX_INTR_MASK); + osi_writel(0xFFFFFFFFU, (unsigned char *)osi_core->base + + EQOS_MMC_IPC_RX_INTR_MASK); /* Configure MMC counters */ value = osi_readl((unsigned char *)osi_core->base + EQOS_MMC_CNTRL); @@ -749,6 +933,16 @@ static void eqos_configure_mac(struct osi_core_priv_data *osi_core) /* insert/replace C_VLAN in 13th & 14th bytes of transmitted frames */ value &= ~EQOS_MAC_VLANTIRR_CSVL; osi_writel(value, (unsigned char *)osi_core->base + EQOS_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 (eqos_config_flow_control(osi_core->base, + osi_core->flow_ctrl) != 0) { + osd_err(osi_core->osd, "Failed to set flow control" + " configuration\n"); + } + } } /** @@ -821,13 +1015,16 @@ static int eqos_core_init(struct osi_core_priv_data *osi_core, } /* reset mmc counters */ - osi_writel(EQOS_MMC_CNTRL_CNTRST, (unsigned char *)osi_core->base + EQOS_MMC_CNTRL); + osi_writel(EQOS_MMC_CNTRL_CNTRST, (unsigned char *)osi_core->base + + EQOS_MMC_CNTRL); /* Mapping MTL Rx queue and DMA Rx channel */ /* TODO: Need to add EQOS_MTL_RXQ_DMA_MAP1 for EQOS */ - value = osi_readl((unsigned char *)osi_core->base + EQOS_MTL_RXQ_DMA_MAP0); + value = osi_readl((unsigned char *)osi_core->base + + EQOS_MTL_RXQ_DMA_MAP0); value |= EQOS_RXQ_TO_DMA_CHAN_MAP; - osi_writel(value, (unsigned char *)osi_core->base + EQOS_MTL_RXQ_DMA_MAP0); + osi_writel(value, (unsigned char *)osi_core->base + + EQOS_MTL_RXQ_DMA_MAP0); /* Calculate value of Transmit queue fifo size to be programmed */ tx_fifo = eqos_calculate_per_queue_fifo(tx_fifo_size, @@ -909,9 +1106,11 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *osi_core, /* Maybe through workqueue for QNX */ if ((mac_pcs & EQOS_MAC_PCS_LNKSPEED) == EQOS_MAC_PCS_LNKSPEED_10) { eqos_set_speed(osi_core->base, OSI_SPEED_10); - } else if ((mac_pcs & EQOS_MAC_PCS_LNKSPEED) == EQOS_MAC_PCS_LNKSPEED_100) { + } else if ((mac_pcs & EQOS_MAC_PCS_LNKSPEED) == + EQOS_MAC_PCS_LNKSPEED_100) { eqos_set_speed(osi_core->base, OSI_SPEED_100); - } else if ((mac_pcs & EQOS_MAC_PCS_LNKSPEED) == EQOS_MAC_PCS_LNKSPEED_1000) { + } else if ((mac_pcs & EQOS_MAC_PCS_LNKSPEED) == + EQOS_MAC_PCS_LNKSPEED_1000) { eqos_set_speed(osi_core->base, OSI_SPEED_1000); } else { /* Nothing here */ @@ -952,9 +1151,11 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *osi_core) qinx = osi_core->mtl_queues[i]; /* read dma channel status register */ - dma_sr = osi_readl((unsigned char *)base + EQOS_DMA_CHX_STATUS(qinx)); + dma_sr = osi_readl((unsigned char *)base + + EQOS_DMA_CHX_STATUS(qinx)); /* read dma channel interrupt enable register */ - dma_ier = osi_readl((unsigned char *)base + EQOS_DMA_CHX_IER(qinx)); + dma_ier = osi_readl((unsigned char *)base + + EQOS_DMA_CHX_IER(qinx)); /* process only those interrupts which we * have enabled. @@ -968,7 +1169,8 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *osi_core) } /* ack non ti/ri ints */ - osi_writel(dma_sr, (unsigned char *)base + EQOS_DMA_CHX_STATUS(qinx)); + osi_writel(dma_sr, (unsigned char *)base + + EQOS_DMA_CHX_STATUS(qinx)); } } @@ -1215,6 +1417,7 @@ static struct osi_core_ops eqos_core_ops = { .config_fw_err_pkts = eqos_config_fw_err_pkts, .config_tx_status = eqos_config_tx_status, .config_rx_crc_check = eqos_config_rx_crc_check, + .config_flow_control = eqos_config_flow_control, }; struct osi_core_ops *eqos_get_hw_core_ops(void) diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index fca6a53..2e51cae 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -23,6 +23,18 @@ #ifndef EQOS_CORE_H_ #define EQOS_CORE_H_ +/* 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_16_K (unsigned int)30 + /** * MTL queue operation mode * EQOS_MTL_QUEUE_DISABLED - queue disabled @@ -82,6 +94,8 @@ #define EQOS_MAC_ANS 0x00E4 #define EQOS_RXQ_TO_DMA_CHAN_MAP 0x03020100U #define EQOS_MAC_EXTR 0x0004 +#define EQOS_MAC_RX_FLW_CTRL 0x0090 +#define EQOS_MAC_QX_TX_FLW_CTRL(x) ((0x0004U * (x)) + 0x0070U) /* EQOS MTL registers*/ #define EQOS_MTL_CHX_TX_OP_MODE(x) ((0x0040U * (x)) + 0x0D00U) @@ -174,4 +188,15 @@ #define EQOS_MTL_RXQ_OP_MODE_FEP OSI_BIT(4) #define EQOS_MTL_OP_MODE_DTXSTS OSI_BIT(1) #define EQOS_MAC_EXTR_DCRCC OSI_BIT(16) +#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 + +void update_ehfc_rfa_rfd(unsigned int rx_fifo, unsigned int *value); #endif diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 79a975a..15fee37 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -383,6 +383,21 @@ int osi_configure_txstatus(struct osi_core_priv_data *osi_core, return ret; } +int osi_config_fw_err_pkts(struct osi_core_priv_data *osi_core, + unsigned int qinx, unsigned int fw_err) +{ + int ret = -1; + + /* Configure Forwarding of Error packets */ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->config_fw_err_pkts != OSI_NULL)) { + ret = osi_core->ops->config_fw_err_pkts(osi_core->base, + qinx, fw_err); + } + + return ret; +} + int osi_config_rx_crc_check(struct osi_core_priv_data *osi_core, unsigned int crc_chk) { @@ -397,3 +412,18 @@ int osi_config_rx_crc_check(struct osi_core_priv_data *osi_core, return ret; } + +int osi_configure_flow_control(struct osi_core_priv_data *osi_core, + unsigned int flw_ctrl) +{ + int ret = -1; + + /* Configure Flow control settings */ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->config_flow_control != OSI_NULL)) { + ret = osi_core->ops->config_flow_control(osi_core->base, + flw_ctrl); + } + + return ret; +} From 1418786032347a9e685069dcb703364464ed348d Mon Sep 17 00:00:00 2001 From: Srinivas Ramachandran <srinivasra@nvidia.com> Date: Fri, 19 Apr 2019 13:42:26 -0700 Subject: [PATCH 016/458] nvethernetrm: Add support for HW offloads 1. ARP offload can be configured private ioctl. The IP address to be configured for ARP offload needs to be provided by application as unsigned char array. Refer to struct ether_ifr_data and struct arp_offload_param for details. 2. Tx/Rx checksum offload. Enabled by default (can be toggled using ethtool) 3. TCP Segmentation offload. Enabled by default (can be toggled using ethtool) Bug 2571001 Change-Id: Ifcf2982557e80655e3cd7ebf3c70f49c538133b5 Signed-off-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2109677 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osd.h | 2 +- include/osi_common.h | 3 - include/osi_core.h | 44 ++++++- include/osi_dma.h | 49 +++++++- include/osi_dma_txrx.h | 16 +++ osi/core/eqos_core.c | 103 +++++++++++++++- osi/core/eqos_core.h | 4 + osi/core/libnvethernetrm.export | 2 + osi/core/osi_core.c | 30 +++++ osi/dma/osi_dma_txrx.c | 203 +++++++++++++++++++++++++++----- 10 files changed, 416 insertions(+), 40 deletions(-) diff --git a/include/osd.h b/include/osd.h index 6caaedf..0f87379 100644 --- a/include/osd.h +++ b/include/osd.h @@ -31,5 +31,5 @@ void osd_err(void *priv, const char *fmt, ...); void osd_receive_packet(void *priv, void *rxring, unsigned int chan, unsigned int dma_buf_len, void *rxpkt_cx); void osd_transmit_complete(void *priv, void *buffer, unsigned long dmaaddr, - unsigned int len, int pkt_valid); + unsigned int len, void *txdone_pkt_cx); #endif diff --git a/include/osi_common.h b/include/osi_common.h index 8ce17ba..84b3f6b 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -83,9 +83,6 @@ #define OSI_INVALID_CHAN_NUM 0xFFU -#define TX_DESC_CNT 256U -#define RX_DESC_CNT 256U - #define EQOS_MAC_HFR0 0x11c #define EQOS_MAC_HFR1 0x120 #define EQOS_MAC_HFR2 0x124 diff --git a/include/osi_core.h b/include/osi_core.h index 3066313..8aa2b0b 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -72,6 +72,8 @@ struct osi_core_avb_algorithm { * @config_tx_status: Called to configure the MTL to forward/drop tx status * @config_rx_crc_check: Called to configure the MAC rx crc. * @config_flow_control: Called to configure the MAC flow control. + * @config_arp_offload: Called to enable/disable HW ARP offload feature. + * @config_rxcsum_offload: Called to configure Rx Checksum offload engine. */ struct osi_core_ops { /* initialize MAC/MTL/DMA Common registers */ @@ -98,6 +100,9 @@ struct osi_core_ops { int (*config_tx_status)(void *addr, unsigned int tx_status); int (*config_rx_crc_check)(void *addr, unsigned int crc_chk); int (*config_flow_control)(void *addr, unsigned int flw_ctrl); + int (*config_arp_offload)(unsigned int mac_ver, void *addr, + unsigned int enable, unsigned char *ip_addr); + int (*config_rxcsum_offload)(void *addr, unsigned int enabled); }; /** @@ -320,8 +325,7 @@ int osi_config_mac_loopback(struct osi_core_priv_data *osi_core, int osi_set_avb(struct osi_core_priv_data *osi_core, struct osi_core_avb_algorithm *avb); -/** - * osi_get_avb - Set CBS algo and parameters +/** osi_get_avb - Get CBS algo and parameters * @osi: OSI core private data structure. * @avb: osi core avb data structure. * @@ -410,6 +414,42 @@ int osi_config_rx_crc_check(struct osi_core_priv_data *osi_core, int osi_configure_flow_control(struct osi_core_priv_data *osi_core, unsigned int flw_ctrl); +/** osi_config_arp_offload - Configure ARP offload in MAC. + * @osi_core: OSI private data structure. + * @flags: Enable/disable flag. + * @ip_addr: Char array representation of IP address + * to be set in HW to compare with ARP requests received. + * + * Algorithm: Invokes EQOS config ARP offload routine. + * + * Dependencies: MAC IP should be out of reset and initialized. + * IP address passed to this function is not validated. + * Caller has to perform IP address validation. + * + * Protection: None + * + * Return: 0 - success, -1 - failure + */ +int osi_config_arp_offload(struct osi_core_priv_data *osi_core, + unsigned int flags, + unsigned char *ip_addr); + +/* + * osi_config_rxcsum_offload - Configure RX checksum offload in MAC. + * @osi_core: OSI private data structure. + * @enable: Enable/disable flag. + * + * Algorithm: Invokes EQOS config RX checksum offload routine. + * + * Dependencies: MAC IP should be out of reset and initialized. + * + * Protection: None + * + * Return: 0 - success, -1 - failure + */ +int osi_config_rxcsum_offload(struct osi_core_priv_data *osi_core, + unsigned int enable); + int osi_write_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, unsigned int phyreg, unsigned short phydata); int osi_read_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, diff --git a/include/osi_dma.h b/include/osi_dma.h index ef98906..d5d549c 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -26,8 +26,21 @@ #include "osi_common.h" #include "osi_dma_txrx.h" -#define OSI_PKT_CX_VLAN OSI_BIT(0) -#define OSI_PKT_CX_VALID OSI_BIT(10) +#define OSI_PKT_CX_VLAN OSI_BIT(0) +#define OSI_PKT_CX_VALID OSI_BIT(10) +#define OSI_PKT_CX_CSUM OSI_BIT(1) +#define OSI_PKT_CX_TSO OSI_BIT(2) + +/* 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) + +/* Checksum offload result flags */ +#define OSI_CHECKSUM_NONE 0x0U +#define OSI_CHECKSUM_UNNECESSARY 0x1U /** * struct osi_pkt_err_stats: OSI packet error stats @@ -88,11 +101,13 @@ struct osi_rx_swcx { /** * struct osi_rx_pkt_cx - Received packet context. * @flags: Bit map which holds the features that rx packets supports. + * @rxcsum: Stores the Rx csum * @vlan_tag: Stores the VLAN tag ID in received packet. * @pkt_len: Length of received packet. */ struct osi_rx_pkt_cx { unsigned int flags; + unsigned int rxcsum; unsigned int vlan_tag; unsigned int pkt_len; }; @@ -116,15 +131,18 @@ struct osi_rx_ring { }; /** - * struct osi_tx_swcx - Transmit descriptor software context - * @buf_phy_addr: Physical address of DMA mapped buffer. - * @buf_virt_addr: Virtual address of DMA buffer. - * @len: Length of buffer + * struct osi_tx_swcx - Transmit descriptor software context + * @buf_phy_addr: Physical address of DMA mapped buffer. + * @buf_virt_addr: Virtual address of DMA buffer. + * @len: Length of buffer + * @is_paged_buf: Flag to keep track of whether buffer pointed + * by buf_phy_addr is a paged buffer/linear buffer. */ struct osi_tx_swcx { unsigned long buf_phy_addr; void *buf_virt_addr; unsigned int len; + unsigned int is_paged_buf; }; /** @@ -146,11 +164,28 @@ struct osi_tx_desc { * @flags: Holds the features which a Tx packets supports. * @vtag_id: Stores the VLAN tag ID. * @desc_cnt: Descriptor count + * @mss: Max. segment size for TSO/USO/GSO/LSO packet + * @payload_len: Length of application payload + * @tcp_udp_hdrlen: Length of transport layer tcp/udp header + * @total_hdrlen: Length of all headers (ethernet/ip/tcp/udp) */ struct osi_tx_pkt_cx { unsigned int flags; unsigned int vtag_id; unsigned int desc_cnt; + unsigned int mss; + unsigned int payload_len; + unsigned int tcp_udp_hdrlen; + unsigned int total_hdrlen; +}; + +/** + * struct osi_txdone_pkt_cx - Transmit done packet context for a packet + * @flags: Indicates status flags for Tx complete (tx error occured, or + * indicate whether desc. had buf mapped from paged/linear memory etc.) + */ +struct osi_txdone_pkt_cx { + unsigned int flags; }; /** @@ -161,6 +196,7 @@ struct osi_tx_pkt_cx { * @cur_tx_idx: Descriptor index current transmission. * @clean_idx: Descriptor index for descriptor cleanup. * @tx_pkt_cx: Transmit packet context. + * @txdone_pkt_cx: Transmit complete packet context information. */ struct osi_tx_ring { struct osi_tx_desc *tx_desc; @@ -169,6 +205,7 @@ struct osi_tx_ring { unsigned int cur_tx_idx; unsigned int clean_idx; struct osi_tx_pkt_cx tx_pkt_cx; + struct osi_txdone_pkt_cx txdone_pkt_cx; }; struct osi_dma_priv_data; diff --git a/include/osi_dma_txrx.h b/include/osi_dma_txrx.h index 41feca4..40e69ec 100644 --- a/include/osi_dma_txrx.h +++ b/include/osi_dma_txrx.h @@ -26,7 +26,10 @@ #define TX_DESC_CNT 256U #define RX_DESC_CNT 256U +#define OSI_TSO_HDR_LEN_DIVISOR 4U + #define INCR_TX_DESC_INDEX(idx, i) ((idx) = ((idx) + (i)) & (TX_DESC_CNT - 1U)) +#define DECR_TX_DESC_INDEX(idx, i) ((idx) = ((idx) - (i)) & (TX_DESC_CNT - 1U)) #define INCR_RX_DESC_INDEX(idx, i) ((idx) = ((idx) + (i)) & (RX_DESC_CNT - 1U)) #define DECR_RX_DESC_INDEX(idx, i) ((idx) = ((idx) - (i)) & (RX_DESC_CNT - 1U)) @@ -45,17 +48,30 @@ #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 RDES0_OVT 0x0000FFFFU +#define RDES1_IPCE OSI_BIT(7) +#define RDES1_IPCB OSI_BIT(6) +#define RDES1_IPHE OSI_BIT(3) + #define RDES3_ES_BITS \ (RDES3_ERR_CRC | RDES3_ERR_GP | RDES3_ERR_WD | \ RDES3_ERR_ORUN | RDES3_ERR_RE | RDES3_ERR_DRIB) #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_TSE OSI_BIT(18) +#define TDES3_HW_CIC (OSI_BIT(16) | OSI_BIT(17)) +#define TDES3_VT_MASK 0xFFFFU +#define TDES3_THL_MASK 0xFU +#define TDES3_TPL_MASK 0x3FFFFU +#define TDES3_THL_SHIFT 19U #define TDES3_VLTV OSI_BIT(16) /* Tx Errors */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 55a9244..5cb2992 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -832,6 +832,43 @@ static int eqos_configure_mtl_queue(unsigned int qinx, return 0; } +/** + * eqos_config_rxcsum_offload - Enable/Disale rx checksum offload in HW + * @addr: EQOS virtual base address. + * @enabled: Flag to indicate feature is to be enabled/disabled. + * + * Algorithm: + * 1) Read the MAC configuration register. + * 2) Enable the IP checksum offload engine COE in MAC receiver. + * 3) Update the MAC configuration register. + * + * Dependencies: MAC has to be out of reset. + * + * Protection: None. + * + * Return: 0 - success, -1 - failure. + */ +static int eqos_config_rxcsum_offload(void *addr, unsigned int enabled) +{ + unsigned int mac_mcr; + + if (enabled != OSI_ENABLE && enabled != OSI_DISABLE) { + return -1; + } + + mac_mcr = osi_readl((unsigned char *)addr + EQOS_MAC_MCR); + + if (enabled == OSI_ENABLE) { + mac_mcr |= EQOS_MCR_IPC; + } else { + mac_mcr &= ~EQOS_MCR_IPC; + } + + osi_writel(mac_mcr, (unsigned char *)addr + EQOS_MAC_MCR); + + return 0; +} + /** * eqos_configure_mac - Configure MAC * @osi_core: OSI private data structure. @@ -870,7 +907,8 @@ static void eqos_configure_mac(struct osi_core_priv_data *osi_core) /* Enable Automatic Pad or CRC Stripping */ /* Enable CRC stripping for Type packets */ /* Enable Full Duplex mode */ - value |= EQOS_MCR_ACS | EQOS_MCR_CST | EQOS_MCR_DM; + /* 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) { value |= EQOS_MCR_S2KP; @@ -1400,6 +1438,67 @@ static int eqos_get_avb_algorithm(struct osi_core_priv_data *osi_core, return 0; } +/** + * eqos_config_arp_offload - Enable/Disable ARP offload + * @mac_ver: MAC version number (different MAC HW version + * need different register offset/fields for ARP offload. + * @addr: EQOS virtual base address. + * @enable: Flag variable to enable/disable ARP offload + * @ip_addr: IP address of device to be programmed in HW. + * HW will use this IP address to respond to ARP requests. + * + * 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. + * + * Dependencies: None. + * + * Protection: None. + * + * Return: 0 - success, -1 - failure. + */ +static int eqos_config_arp_offload(unsigned int mac_ver, void *addr, + unsigned int enable, + unsigned char *ip_addr) +{ + unsigned int mac_mcr; + unsigned int val; + + if (enable != OSI_ENABLE && enable != OSI_DISABLE) { + return -1; + } + + mac_mcr = osi_readl((unsigned char *)addr + EQOS_MAC_MCR); + + 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])); + + if (mac_ver == OSI_EQOS_MAC_4_10) { + osi_writel(val, (unsigned char *)addr + + EQOS_4_10_MAC_ARPPA); + } else if (mac_ver == OSI_EQOS_MAC_5_00) { + osi_writel(val, (unsigned char *)addr + + EQOS_5_00_MAC_ARPPA); + } else { + /* Unsupported MAC ver */ + return -1; + } + + mac_mcr |= EQOS_MCR_ARPEN; + } else { + mac_mcr &= ~EQOS_MCR_ARPEN; + } + + osi_writel(mac_mcr, (unsigned char *)addr + EQOS_MAC_MCR); + + return 0; +} + static struct osi_core_ops eqos_core_ops = { .poll_for_swr = eqos_poll_for_swr, .core_init = eqos_core_init, @@ -1418,6 +1517,8 @@ static struct osi_core_ops eqos_core_ops = { .config_tx_status = eqos_config_tx_status, .config_rx_crc_check = eqos_config_rx_crc_check, .config_flow_control = eqos_config_flow_control, + .config_arp_offload = eqos_config_arp_offload, + .config_rxcsum_offload = eqos_config_rxcsum_offload, }; struct osi_core_ops *eqos_get_hw_core_ops(void) diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 2e51cae..43afce9 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -73,6 +73,8 @@ #define EQOS_36K 0x8FU /* EQOS HW Registers */ +#define EQOS_5_00_MAC_ARPPA 0x0210 +#define EQOS_4_10_MAC_ARPPA 0x0AE0 #define EQOS_DMA_SBUS 0x1004 #define EQOS_DMA_BMR 0x1000 #define EQOS_MMC_CNTRL 0x0700 @@ -119,6 +121,8 @@ #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_ARPEN OSI_BIT(31) +#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) diff --git a/osi/core/libnvethernetrm.export b/osi/core/libnvethernetrm.export index fbdc186..ace98f9 100644 --- a/osi/core/libnvethernetrm.export +++ b/osi/core/libnvethernetrm.export @@ -43,3 +43,5 @@ osi_configure_txstatus osi_config_rx_crc_check osi_get_mac_version osi_get_hw_features +osi_config_arp_offload +osi_config_rxcsum_offload diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 15fee37..aae9ef4 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -427,3 +427,33 @@ int osi_configure_flow_control(struct osi_core_priv_data *osi_core, return ret; } + +int osi_config_arp_offload(struct osi_core_priv_data *osi_core, + unsigned int flags, + unsigned char *ip_addr) +{ + int ret = -1; + + if (osi_core != OSI_NULL && osi_core->ops != OSI_NULL && + osi_core->ops->config_arp_offload != OSI_NULL) { + ret = osi_core->ops->config_arp_offload(osi_core->mac_ver, + osi_core->base, + flags, ip_addr); + } + + return ret; +} + +int osi_config_rxcsum_offload(struct osi_core_priv_data *osi_core, + unsigned int enable) +{ + int ret = -1; + + if (osi_core != OSI_NULL && osi_core->ops != OSI_NULL && + osi_core->ops->config_rxcsum_offload != OSI_NULL) { + ret = osi_core->ops->config_rxcsum_offload(osi_core->base, + enable); + } + + return ret; +} diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index ec55c8d..45f609d 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -41,6 +41,41 @@ static inline void osi_memset(void *s, int c, unsigned long count) } } +/** + * get_rx_csum - Get the Rx checksum from descriptor if valid + * @rx_desc: Rx descriptor + * @rx_pkt_cx: Per-Rx packet context structure + * + * 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. + * + * Dependencies: None + * + * Protection: None + * + * Return: None. + */ +static inline void get_rx_csum(struct osi_rx_desc *rx_desc, + struct osi_rx_pkt_cx *rx_pkt_cx) +{ + /* Always include either checksum none/unnecessary + * depending on status fields in desc. + * Hence no need to explicitly add OSI_PKT_CX_CSUM flag. + */ + if ((rx_desc->rdes3 & RDES3_RS1V) == RDES3_RS1V) { + /* Check if no checksum errors reported in status */ + if ((rx_desc->rdes1 & + (RDES1_IPCE | RDES1_IPCB | RDES1_IPHE)) == 0U) { + rx_pkt_cx->rxcsum |= OSI_CHECKSUM_UNNECESSARY; + } + } +} + static inline void get_rx_vlan_from_desc(struct osi_rx_desc *rx_desc, struct osi_rx_pkt_cx *rx_pkt_cx) { @@ -111,9 +146,8 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, struct osi_rx_desc *rx_desc = OSI_NULL; int received = 0; - osi_memset(rx_pkt_cx, 0, sizeof(*rx_pkt_cx)); - while (received < budget) { + osi_memset(rx_pkt_cx, 0, sizeof(*rx_pkt_cx)); rx_desc = rx_ring->rx_desc + rx_ring->cur_rx_idx; /* check for data availability */ @@ -135,6 +169,10 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, rx_pkt_cx->flags &= ~OSI_PKT_CX_VALID; get_rx_err_stats(rx_desc, osi->pkt_err_stats); } + + /* Check if COE Rx checksum is valid */ + get_rx_csum(rx_desc, rx_pkt_cx); + get_rx_vlan_from_desc(rx_desc, rx_pkt_cx); osd_receive_packet(osi->osd, rx_ring, chan, osi->rx_buf_len, rx_pkt_cx); @@ -307,12 +345,15 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi, unsigned int chan) { struct osi_tx_ring *tx_ring = osi->tx_ring[chan]; + struct osi_txdone_pkt_cx *txdone_pkt_cx = &tx_ring->txdone_pkt_cx; struct osi_tx_swcx *tx_swcx = OSI_NULL; struct osi_tx_desc *tx_desc = OSI_NULL; unsigned int entry = tx_ring->clean_idx; - int processed = 0, pkt_valid = 1; + int processed = 0; while (entry != tx_ring->cur_tx_idx) { + osi_memset(txdone_pkt_cx, 0, sizeof(*txdone_pkt_cx)); + tx_desc = tx_ring->tx_desc + entry; tx_swcx = tx_ring->tx_swcx + entry; @@ -323,15 +364,19 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi, /* check for Last Descriptor */ if ((tx_desc->tdes3 & TDES3_LD) == TDES3_LD) { if ((tx_desc->tdes3 & TDES3_ES_BITS) != 0U) { - pkt_valid = 0; + txdone_pkt_cx->flags |= OSI_TXDONE_CX_ERROR; /* fill packet error stats */ get_tx_err_stats(tx_desc, osi->pkt_err_stats); } } + if (tx_swcx->is_paged_buf == 1U) { + txdone_pkt_cx->flags |= OSI_TXDONE_CX_PAGED_BUF; + } + osd_transmit_complete(osi->osd, tx_swcx->buf_virt_addr, tx_swcx->buf_phy_addr, tx_swcx->len, - pkt_valid); + txdone_pkt_cx); tx_desc->tdes3 = 0; tx_desc->tdes2 = 0; @@ -341,15 +386,131 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi, tx_swcx->buf_virt_addr = OSI_NULL; tx_swcx->buf_phy_addr = 0; + tx_swcx->is_paged_buf = 0; INCR_TX_DESC_INDEX(entry, 1U); processed++; + + /* 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 inturn be used to + * wake the corresponding transmit queue in OS layer. + */ + tx_ring->clean_idx = entry; } - tx_ring->clean_idx = entry; - return processed; } +/** + * need_cntx_desc - Helper function to check if context desc is needed. + * @tx_pkt_cx: Pointer to transmit packet context structure + * @tx_desc: Pointer to tranmit descriptor to be filled. + * + * Algorithm: + * 1) Check if transmit packet context flags are set + * 2) If set, set the context descriptor bit along + * with other context information in the transmit descriptor. + * + * Dependencies: None. + * + * Protection: None + * + * Return: 0 - cntx desc not used, 1 - cntx desc used. + */ +static inline int need_cntx_desc(struct osi_tx_pkt_cx *tx_pkt_cx, + struct osi_tx_desc *tx_desc) +{ + int 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)) { + /* Set context type */ + tx_desc->tdes3 |= TDES3_CTXT; + + if ((tx_pkt_cx->flags & OSI_PKT_CX_VLAN) == OSI_PKT_CX_VLAN) { + /* Remove any overflow bits. VT field is 16bit field */ + tx_pkt_cx->vtag_id &= TDES3_VT_MASK; + /* Fill VLAN Tag ID */ + tx_desc->tdes3 |= tx_pkt_cx->vtag_id; + /* Set VLAN TAG Valid */ + tx_desc->tdes3 |= TDES3_VLTV; + } + + if ((tx_pkt_cx->flags & OSI_PKT_CX_TSO) == OSI_PKT_CX_TSO) { + /* Remove any overflow bits. MSS is 13bit field */ + tx_pkt_cx->mss &= TDES2_MSS_MASK; + /* Fill MSS */ + tx_desc->tdes2 |= tx_pkt_cx->mss; + /* Set MSS valid */ + tx_desc->tdes3 |= TDES3_TCMSSV; + } + + ret = 1; + } + + return ret; +} + +/** + * fill_first_desc - Helper function to fill the first transmit descriptor. + * @tx_pkt_cx: Pointer to transmit packet context structure + * @tx_desc: Pointer to tranmit descriptor to be filled. + * @tx_swcx: Pointer to corresponding tranmit descriptor software context. + * + * Algorithm: + * 1) Update the buffer address and length of buffer in first desc. + * 2) Check if any features like HW checksum offload, TSO, VLAN insertion + * etc. are flagged in transmit packet context. If so, set the fiels in + * first desc corresponding to those features. + * + * Dependencies: None. + * + * Protection: None + * + * Return: None. + */ +static inline void fill_first_desc(struct osi_tx_pkt_cx *tx_pkt_cx, + struct osi_tx_desc *tx_desc, + struct osi_tx_swcx *tx_swcx) +{ + /* update the first buffer pointer and length */ + tx_desc->tdes0 = (unsigned int)L32(tx_swcx->buf_phy_addr); + tx_desc->tdes1 = (unsigned int)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; + } + + /* 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; + } + + /* 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; + /* Remove any overflow bits. THL field is only 4 bit wide */ + tx_pkt_cx->tcp_udp_hdrlen &= TDES3_THL_MASK; + /* Update hdr len in desc */ + tx_desc->tdes3 |= (tx_pkt_cx->tcp_udp_hdrlen << + TDES3_THL_SHIFT); + /* Remove any overflow bits. TPL field is 18 bit wide */ + tx_pkt_cx->payload_len &= TDES3_TPL_MASK; + /* Update TCP payload len in desc */ + tx_desc->tdes3 |= tx_pkt_cx->payload_len; + } +} + /** * osi_hw_transmit - Initialize Tx DMA descriptors for a channel * @osi: OSI private data structure. @@ -380,16 +541,11 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan) struct osi_tx_desc *cx_desc = OSI_NULL; unsigned long tailptr; unsigned int i; + int cntx_desc_consumed; - /* Context decriptor for VLAN */ - 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; - + /* Context decriptor for VLAN/TSO */ + cntx_desc_consumed = need_cntx_desc(tx_pkt_cx, tx_desc); + if (cntx_desc_consumed == 1) { INCR_TX_DESC_INDEX(entry, 1U); /* Storing context descriptor to set DMA_OWN at last */ @@ -399,17 +555,9 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan) desc_cnt--; } - /* update the first buffer pointer and length */ - tx_desc->tdes0 = (unsigned int)L32(tx_swcx->buf_phy_addr); - tx_desc->tdes1 = (unsigned int)H32(tx_swcx->buf_phy_addr); - tx_desc->tdes2 = tx_swcx->len; - /* Mark it as First descriptor */ - tx_desc->tdes3 |= TDES3_FD; + /* Fill first descriptor */ + fill_first_desc(tx_pkt_cx, tx_desc, tx_swcx); - /* 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; - } INCR_TX_DESC_INDEX(entry, 1U); @@ -419,6 +567,7 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan) tx_swcx = tx_ring->tx_swcx + entry; desc_cnt--; + /* Fill remaining descriptors */ for (i = 0; i < desc_cnt; i++) { tx_desc->tdes0 = (unsigned int)L32(tx_swcx->buf_phy_addr); tx_desc->tdes1 = (unsigned int)H32(tx_swcx->buf_phy_addr); @@ -441,7 +590,7 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan) * at the end to avoid race condition */ first_desc->tdes3 |= TDES3_OWN; - if ((tx_pkt_cx->flags & OSI_PKT_CX_VLAN) == OSI_PKT_CX_VLAN) { + if (cntx_desc_consumed == 1) { cx_desc->tdes3 |= TDES3_OWN; } From d265861eb4ccdb3a086db0f5cd968457fd3f0d3d Mon Sep 17 00:00:00 2001 From: Mohit Dhingra <mdhingra@nvidia.com> Date: Thu, 23 May 2019 13:05:57 +0530 Subject: [PATCH 017/458] nvethernetrm: avoid redefining macro ULONG_MAX For QNX, macro ULONG_MAX is already defined in the toolchain. Define the macro only when not defined earlier. ESQC-9836 Change-Id: I3afcb5ec0933ec31816e8b6602a5a99260e00e04 Signed-off-by: Mohit Dhingra <mdhingra@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2124114 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Narayan Reddy <narayanr@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_common.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/osi_common.h b/include/osi_common.h index 84b3f6b..a96791b 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -33,7 +33,9 @@ #define OSI_ADDRESS_40BIT 1 #define OSI_ADDRESS_48BIT 2 +#ifndef ULONG_MAX #define ULONG_MAX (~0UL) +#endif /* Default maximum Gaint Packet Size Limit */ #define OSI_MAX_MTU_SIZE 9000U From de3f0b83858a0171dce39289bdcf60b1db3fb49c Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Fri, 12 Apr 2019 15:47:35 +0530 Subject: [PATCH 018/458] nvethernetrm: enable mac filter Code to configure and program register for L2/L3/L4/VLAN Filter Bug 200512993 Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Change-Id: I469e25aeb2a31878d2fd7384cbe5f63c63d3b924 Reviewed-on: https://git-master.nvidia.com/r/2111083 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_common.h | 13 + include/osi_core.h | 350 +++++++++++++++- osi/core/eqos_core.c | 685 +++++++++++++++++++++++++++++++- osi/core/eqos_core.h | 75 ++++ osi/core/libnvethernetrm.export | 12 + osi/core/osi_core.c | 177 +++++++++ 6 files changed, 1310 insertions(+), 2 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index a96791b..6e312b1 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -48,6 +48,10 @@ #define EQOS_DMA_CHX_STATUS(x) ((0x0080U * (x)) + 0x1160U) #define EQOS_DMA_CHX_IER(x) ((0x0080U * (x)) + 0x1134U) +/* FIXME add logic based on HW version */ +#define EQOS_MAX_MAC_ADDRESS_FILTER 128U +#define EQOS_MAX_L3_L4_FILTER 8U + #define MAC_VERSION 0x110 #define MAC_VERSION_SNVER_MASK 0x7FU @@ -58,6 +62,15 @@ #define OSI_ENABLE 1U #define OSI_DISABLE 0U +#define OSI_HASH_FILTER_MODE 1U +#define OSI_PERFECT_FILTER_MODE 0U + +#define OSI_L4_FILTER_TCP 0U +#define OSI_L4_FILTER_UDP 1U + +#define OSI_IP4_FILTER 0U +#define OSI_IP6_FILTER 1U + #define OSI_EQOS_MAX_NUM_CHANS 4U #define OSI_BIT(nr) ((unsigned int)1 << (nr)) diff --git a/include/osi_core.h b/include/osi_core.h index 8aa2b0b..fef16ba 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -28,7 +28,68 @@ struct osi_core_priv_data; /** - * struct osi_core_avb_algorithm - The OSI Core avb data sctructure per + * struct osi_filter - The OSI core structure for filters + * @pr_mode: promiscuous mode + * @huc_mode: hash unicast + * @hmc_mode: hash milticast + * @pm_mode: pass all multicast + * @hpf_mode: hash or perfact filter + */ +struct osi_filter { + unsigned int pr_mode; + unsigned int huc_mode; + unsigned int hmc_mode; + unsigned int pm_mode; + unsigned int hpf_mode; +}; + +/** + * Structure osi_l3_l4_filter - L3/L4 filter Function dependent + * parameter + * + * @filter_no: filter index 0- 7 + * @filter_enb_dis: enable/disable + * @src_dst_addr_match: source(0) or destination(1) + * @perfect_inverse_match: perfect(0) or inverse(1) + * @ip4_addr: ipv4 address + * @ip6_addr: ipv6 address + * @port_no: Port number + */ +struct osi_l3_l4_filter { + unsigned int filter_no; + unsigned int filter_enb_dis; + unsigned int src_dst_addr_match; + unsigned int perfect_inverse_match; + unsigned char ip4_addr[4]; + unsigned short ip6_addr[8]; + unsigned short port_no; +}; + +/** + * Structure osi_vlan_filter - Vlan filter Function dependent parameter + * + * @filter_enb_dis: enable/disable + * @perfect_hash: perfect(0) or hash(1) + * @perfect_inverse_match: perfect(0) or inverse(1) + */ +struct osi_vlan_filter { + unsigned int filter_enb_dis; + unsigned int perfect_hash; + unsigned int perfect_inverse_match; +}; + +/** + * Struct osi_l2_da_filter - L2 filter function depedent parameter + * @perfect_hash: perfect(0) or hash(1) + * @perfect_inverse_match: perfect(0) or hash(1) + */ +struct osi_l2_da_filter { + unsigned int perfect_hash; + unsigned int perfect_inverse_match; +}; + +/** + * struct osi_core_avb_algorithm - The OSI Core avb data structure per * queue. * @qindex: TX Queue/TC index * @algo: AVB algorithm 1:CBS @@ -74,6 +135,17 @@ struct osi_core_avb_algorithm { * @config_flow_control: Called to configure the MAC flow control. * @config_arp_offload: Called to enable/disable HW ARP offload feature. * @config_rxcsum_offload: Called to configure Rx Checksum offload engine. + * @config_mac_pkt_filter_reg: Called to config mac packet filter. + * @update_mac_addr_low_high_reg: Called to update MAC address 1-127. + * @config_l3_l4_filter_enable: Called to configure l3/L4 filter. + * @config_l2_da_perfect_inverse_match: Called to configure L2 DA filter. + * @config_l3_filters: Called to configure L3 filter. + * @update_ip4_addr: Called to update ip4 src or desc address. + * @update_ip6_addr: Called to update ip6 address. + * @config_l4_filters: Called to configure L4 filter. + * @update_l4_port_no: Called to update L4 Port for filter packet. + * @config_vlan_filtering: Called to configure VLAN filtering. + * @update_vlan_id: called to update VLAN id. */ struct osi_core_ops { /* initialize MAC/MTL/DMA Common registers */ @@ -103,6 +175,40 @@ struct osi_core_ops { int (*config_arp_offload)(unsigned int mac_ver, void *addr, unsigned int enable, unsigned char *ip_addr); int (*config_rxcsum_offload)(void *addr, unsigned int enabled); + void (*config_mac_pkt_filter_reg)(struct osi_core_priv_data *osi_core, + struct osi_filter filter); + int (*update_mac_addr_low_high_reg)( + struct osi_core_priv_data *osi_core, + unsigned int index, + unsigned char value[]); + int (*config_l3_l4_filter_enable)(void *base, unsigned int enable); + int (*config_l2_da_perfect_inverse_match)(void *base, unsigned int + perfect_inverse_match); + int (*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); + int (*update_ip4_addr)(struct osi_core_priv_data *osi_core, + unsigned int filter_no, unsigned char addr[], + unsigned int src_dst_addr_match); + int (*update_ip6_addr)(struct osi_core_priv_data *osi_core, + unsigned int filter_no, unsigned short addr[]); + int (*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); + int (*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); + + /* for VLAN filtering */ + int (*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); + int (*update_vlan_id)(void *base, unsigned int vid); }; /** @@ -114,6 +220,7 @@ struct osi_core_ops { * @num_mtl_queues: Number of MTL queues enabled in MAC. * @mtl_queues: Array of MTL queues. * @rxq_ctrl: List of MTL Rx queue mode that need to be enabled + * @rxq_prio: Rx MTl Queue mapping based on User Priority field * @mac: MAC HW type EQOS based on DT compatible. * @mac_ver: MAC version. * @mdc_cr: MDC clock rate. @@ -129,6 +236,7 @@ struct osi_core_priv_data { unsigned int num_mtl_queues; unsigned int mtl_queues[OSI_EQOS_MAX_NUM_CHANS]; unsigned int rxq_ctrl[OSI_EQOS_MAX_NUM_CHANS]; + unsigned int rxq_prio[OSI_EQOS_MAX_NUM_CHANS]; unsigned int mac; unsigned int mac_ver; unsigned int mdc_cr; @@ -450,6 +558,246 @@ int osi_config_arp_offload(struct osi_core_priv_data *osi_core, int osi_config_rxcsum_offload(struct osi_core_priv_data *osi_core, unsigned int enable); +/** + * osi_config_mac_pkt_filter_reg - configure mac filter register. + * @osi_core: OSI private data structure. + * @pfilter: OSI filter structure. + * + * Algorithm: This sequence is used to configure MAC in differnet pkt + * processing modes like promiscuous, multicast, unicast, + * hash unicast/multicast. + * + * Dependencies: MAC IP should be out of reset + * and need to be initialized as the requirements + * + * Protection: None + * + * Return: 0 - success, -1 - failure. + */ +int osi_config_mac_pkt_filter_reg(struct osi_core_priv_data *osi_core, + struct osi_filter pfilter); + +/** + * osi_update_mac_addr_low_high_reg- invoke API to update L2 address + * in filter register + * + * @osi_core: OSI private data structure. + * @index: filter index + * @value: address to write + * + * Algorithm: this routine update MAC address to register + * + * Dependencies: MAC IP should be out of reset + * and need to be initialized as the requirements + * + * Protection: None + * + * Return: 0 - success, -1 - failure. + */ +int osi_update_mac_addr_low_high_reg(struct osi_core_priv_data *osi_core, + unsigned int index, + unsigned char value[]); + +/** + * osi_config_l3_l4_filter_enable - invoke OSI call to eanble L3/L4 + * filters. + * + * @osi_core: OSI private data structure. + * @enable: enable/disable + * + * Algorithm: This routine to enable/disable L4/l4 filter + * + * Dependencies: MAC IP should be out of reset + * and need to be initialized as the requirements + * + * Protection: None + * + * Return: 0 - success, -1 - failure. + */ +int osi_config_l3_l4_filter_enable(struct osi_core_priv_data *osi_core, + unsigned int enable); + +/** + * osi_config_l3_filters - invoke OSI call config_l3_filters. + * + * @osi_core: OSI private data structure. + * @filter_no: filter index + * @enb_dis: enable/disable L3 filter + * @ipv4_ipv6_match: 1 - IPv6, 0 - IPv4 + * @src_dst_addr_match: ip address matching enable/disable + * @perfect_inverse_match: normal match(0) or inverse map(1) + * + * Algorithm: This sequence is used to configure L3((IPv4/IPv6) filters for + * address matching. + * + * Dependencies: MAC IP should be out of reset + * and need to be initialized as the requirements + * + * Protection: None + * + * Return: 0 - success, -1 - failure. + */ +int osi_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); + +/** + * osi_update_ip4_addr - invoke OSI call update_ip4_addr. + * @osi_core: OSI private data structure. + * @filter_no: filter index + * @addr: ipv4 address + * @src_dst_addr_match: 0- source(addr0) 1- dest (addr1) + * + * Algorithm: This sequence is used to update IPv4 source/destination + * Address for L3 layer filtering + * + * Dependencies: MAC IP should be out of reset + * and need to be initialized as the requirements + * + * Protection: None + * + * Return: 0 - success, -1 - failure. + */ +int osi_update_ip4_addr(struct osi_core_priv_data *osi_core, + unsigned int filter_no, + unsigned char addr[], + unsigned int src_dst_addr_match); + +/** + * osi_update_ip6_addr - invoke OSI call update_ip6_addr. + * @osi_core: OSI private data structure. + * @filter_no: filter index + * @addr: ipv6 adderss + * + * Algorithm: This sequence is used to update IPv6 source/destination + * Address for L3 layer filtering + * + * Dependencies: MAC IP should be out of reset + * and need to be initialized as the requirements + * + * Protection: None + * + * Return: 0 - success, -1 - failure. + */ +int osi_update_ip6_addr(struct osi_core_priv_data *osi_core, + unsigned int filter_no, + unsigned short addr[]); + +/** + * osi_config_l4_filters - invoke OSI call config_l4_filters. + * + * @osi_core: OSI private data structure. + * @filter_no: filter index + * @enb_dis: enable/disable L4 filter + * @tcp_udp_match: 1 - udp, 0 - tcp + * @src_dst_port_match: port matching enable/disable + * @perfect_inverse_match: normal match(0) or inverse map(1) + * + * Algorithm: This sequence is used to configure L4(TCP/UDP) filters for + * SA and DA Port Number matching + * + * Dependencies: MAC IP should be out of reset + * and need to be initialized as the requirements + * + * Protection: None + * + * Return: 0 - success, -1 - failure. + */ +int osi_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); + +/** + * osi_update_l4_port_no - invoke OSI call for + * update_l4_port_no. + * + * @osi_core: OSI private data structure. + * @filter_no: filter index + * @port_no: port number + * @src_dst_port_match: source port - 0, dest port - 1 + * + * Algoriths sequence is used to update Source Port Number for + * L4(TCP/UDP) layer filtering. + * + * Dependencies: MAC IP should be out of reset + * and need to be initialized as the requirements + * + * Protection: None + * + * Return: 0 - success, -1 - failure. + */ +int osi_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); + +/** + * osi_config_vlan_filter_reg - invoke OSI call for + * config_vlan_filtering. + * + * @osi_core: OSI private data structure. + * @filter_enb_dis: vlan filter enable/disable + * @perfect_hash_filtering: perfect or hash filter + * @perfect_inverse_match: normal or inverse filter + * + * Algorithm: This sequence is used to enable/disable VLAN filtering and + * also selects VLAN filtering mode- perfect/hash + * + * Dependencies: MAC IP should be out of reset + * and need to be initialized as the requirements + * + * Protection: None + * + * Return: 0 - success, -1 - failure. + */ +int osi_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); + +/** + * osi_config_l2_da_perfect_inverse_match - trigger OSI call for + * config_l2_da_perfect_inverse_match. + * + * @osi_core: OSI private data structure. + * @perfect_inverse_match: 1 - inverse mode 0- normal mode + * + * Algorithm: This sequence is used to select perfect/inverse matching + * for L2 DA + * + * Dependencies: MAC IP should be out of reset + * and need to be initialized as the requirements + * + * Protection: None + * + * Return: 0 - success, -1 - failure. + */ +int osi_config_l2_da_perfect_inverse_match(struct osi_core_priv_data *osi_core, + unsigned int perfect_inverse_match); + +/** + * osi_update_vlan_id - invoke osi call to get VLAn ID + * + * @osi_core: OSI private data structure. + * @vid: VLAN ID + * + * Algorithm: return 16 bit VLAN ID + * + * Dependencies: MAC IP should be out of reset and need to be initialized + * as the requirements + * + * Protection: None + * + * Return: 0 - success, -1 - failure. + */ +int osi_update_vlan_id(struct osi_core_priv_data *osi_core, + unsigned int vid); + int osi_write_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, unsigned int phyreg, unsigned short phydata); int osi_read_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 5cb2992..7dcca11 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -869,6 +869,60 @@ static int eqos_config_rxcsum_offload(void *addr, unsigned int enabled) return 0; } +/** + * eqos_configure_rxq_priority - Configure RxQ priority + * @osi_core: OSI private data structure. + * + * Algorithm: This takes care of configuring the RxQ priority + * based on the User priority field of the received packets.we + * Don't have any fix mapping between RXQ and channel. We also don't + * control MTL queue enable/disable in current SW. + * + * Dependencies: MAC has to be out of reset. + * + * Protection: None + * + * Return: None + */ +static void eqos_configure_rxq_priority(struct osi_core_priv_data *osi_core) +{ + unsigned int qinx; + unsigned int val; + unsigned int temp; + /* to avoid Misra-C error */ + unsigned int mybit = 0x1U; + unsigned int mfix_var1, mfix_var2; + + for (qinx = 0; qinx < OSI_EQOS_MAX_NUM_CHANS; qinx++) { + /* check for invalid priority which is set when either rxq_prio + * not defined or duplicate priority given + */ + if (osi_core->rxq_prio[qinx] != 0xFFU) { + temp = (mybit << osi_core->rxq_prio[qinx]); + } else { + osd_err(osi_core->osd, + "Invalid rxq Priority for Q(%d)\n", + qinx); + continue; + } + + val = osi_readl((unsigned char *)osi_core->base + + EQOS_MAC_RQC2R); + mfix_var1 = qinx * (unsigned int)EQOS_MAC_RQC2_PSRQ_SHIFT; + mfix_var2 = (unsigned int)EQOS_MAC_RQC2_PSRQ_MASK; + mfix_var2 <<= mfix_var1; + val &= ~mfix_var2; + temp = temp << (qinx * EQOS_MAC_RQC2_PSRQ_SHIFT); + mfix_var1 = qinx * (unsigned int)EQOS_MAC_RQC2_PSRQ_SHIFT; + mfix_var2 = (unsigned int)EQOS_MAC_RQC2_PSRQ_MASK; + mfix_var2 <<= mfix_var1; + val |= (temp & mfix_var2); + /* Priorities Selected in the Receive Queue 0 */ + osi_writel(val, (unsigned char *)osi_core->base + + EQOS_MAC_RQC2R); + } +} + /** * eqos_configure_mac - Configure MAC * @osi_core: OSI private data structure. @@ -981,6 +1035,8 @@ static void eqos_configure_mac(struct osi_core_priv_data *osi_core) " configuration\n"); } } + /* USP (user Priority) to RxQ Mapping */ + eqos_configure_rxq_priority(osi_core); } /** @@ -1356,6 +1412,88 @@ static int eqos_set_avb_algorithm(struct osi_core_priv_data *osi_core, return 0; } +/* + * eqos_config_mac_pkt_filter_reg - configure mac filter register. + * @osi_core: OSI private data structure. + * @filter: OSI filter structure. + * + * Algorithm: This sequence is used to configure MAC in differnet pkt + * processing modes like promiscuous, multicast, unicast, + * hash unicast/multicast. + * + * Dependencies: MAC IP should be out of reset + * and need to be initialized as the requirements + * + * Protection: None + * + * Return: None + */ +static void eqos_config_mac_pkt_filter_reg(struct osi_core_priv_data *osi_core, + struct osi_filter pfilter) +{ + unsigned int value = 0U; + + value = osi_readl((unsigned char *)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); + value |= (pfilter.pr_mode & EQOS_MAC_PFR_PR) | + ((pfilter.huc_mode << EQOS_MAC_PFR_HUC_SHIFT) & + EQOS_MAC_PFR_HUC) | + ((pfilter.hmc_mode << EQOS_MAC_PFR_HMC_SHIFT) & + EQOS_MAC_PFR_HMC) | + ((pfilter.pm_mode << EQOS_MAC_PFR_PM_SHIFT) & + EQOS_MAC_PFR_PM) | + ((pfilter.hpf_mode << EQOS_MAC_PFR_HPF_SHIFT) & + EQOS_MAC_PFR_HPF); + + osi_writel(value, (unsigned char *)osi_core->base + EQOS_MAC_PFR); +} + +/** + * eqos_update_mac_addr_low_high_reg- Update L2 address + * in filter register + * + * @osi_core: OSI private data structure. + * @index: filter index + * @value: MAC address to write + * + * Algorithm: this routine update MAC address to register + * + * Dependencies: MAC IP should be out of reset + * and need to be initialized as the requirements + * + * Protection: None + * + * Return: 0 - success, -1 - failure. + */ +static int eqos_update_mac_addr_low_high_reg( + struct osi_core_priv_data *osi_core, + unsigned int idx, unsigned char addr[]) +{ + if (idx > EQOS_MAX_MAC_ADDRESS_FILTER) { + osd_err(osi_core->osd, "invalid MAC filter index\n"); + return -1; + } + + if (idx >= 0x1U && addr == OSI_NULL) { + osi_writel((unsigned int)0x0, (unsigned char *)osi_core->base + + EQOS_MAC_ADDRH((idx))); + return 0; + } + + osi_writel(((unsigned int)addr[4] | ((unsigned int)addr[5] << 8) | + OSI_BIT(31)), (unsigned char *)osi_core->base + + EQOS_MAC_ADDRH((idx))); + osi_writel(((unsigned int)addr[0] | ((unsigned int)addr[1] << 8) | + ((unsigned int)addr[2] << 16) | + ((unsigned int)addr[3] << 24)), + (unsigned char *)osi_core->base + EQOS_MAC_ADDRL((idx))); + + return 0; +} + /** * eqos_get_avb_algorithm - Get TxQ/TC avb config * @osi_core: osi core priv data structure @@ -1378,7 +1516,6 @@ static int eqos_set_avb_algorithm(struct osi_core_priv_data *osi_core, * * Return: 0: Success -1: Failure */ - static int eqos_get_avb_algorithm(struct osi_core_priv_data *osi_core, struct osi_core_avb_algorithm *avb) { @@ -1499,6 +1636,540 @@ static int eqos_config_arp_offload(unsigned int mac_ver, void *addr, return 0; } +/* + * eqos_config_l3_l4_filter_enable - register write to eanble L3/L4 + * filters. + * + * @base: Base address from OSI private data structure. + * @enable: enable/disable + * + * Algorithm: This routine to enable/disable L4/l4 filter + * + * Dependencies: MAC IP should be out of reset + * and need to be initialized as the requirements + * + * Protection: None + * + * Return: 0 - success, -1 - failure. + */ +static int eqos_config_l3_l4_filter_enable(void *base, + unsigned int filter_enb_dis) +{ + unsigned int value = 0U; + + value = osi_readl((unsigned char *)base + EQOS_MAC_PFR); + value &= ~(EQOS_MAC_PFR_IPFE); + value |= ((filter_enb_dis << 20) & EQOS_MAC_PFR_IPFE); + osi_writel(value, (unsigned char *)base + EQOS_MAC_PFR); + + return 0; +} + +/** + * eqos_config_l2_da_perfect_inverse_match - configure register for inverse + * or perfect match. + * + * @base: Base address from OSI private data structure. + * @perfect_inverse_match: 1 - inverse mode 0- normal mode + * + * Algorithm: This sequence is used to select perfect/inverse matching + * for L2 DA + * + * Dependencies: MAC IP should be out of reset + * and need to be initialized as the requirements + * + * Protection: None + * + * Return: 0 - success, -1 - failure. + */ +static int eqos_config_l2_da_perfect_inverse_match(void *base, unsigned int + perfect_inverse_match) +{ + unsigned int value = 0U; + + value = osi_readl((unsigned char *)base + EQOS_MAC_PFR); + value &= ~EQOS_MAC_PFR_DAIF; + value |= ((perfect_inverse_match << EQOS_MAC_PFR_DAIF_SHIFT) & + EQOS_MAC_PFR_DAIF); + osi_writel(value, (unsigned char *)base + EQOS_MAC_PFR); + + return 0; +} + +/** + * eqos_update_ip4_addr + * @osi_core: OSI private data structure. + * @filter_no: filter index + * @addr: ipv4 address + * + * Algorithm: This sequence is used to update IPv4 source/destination + * Address for L3 layer filtering + * + * Dependencies: MAC IP should be out of reset + * and need to be initialized as the requirements + * + * Protection: None + * + * Return: 0 - success, -1 - failure. + */ +static int eqos_update_ip4_addr(struct osi_core_priv_data *osi_core, + unsigned int filter_no, + unsigned char addr[], + unsigned int src_dst_addr_match) +{ + void *base = osi_core->base; + unsigned int value = 0U; + unsigned int temp = 0U; + + if (filter_no > EQOS_MAX_L3_L4_FILTER) { + osd_err(osi_core->osd, "filter index %d > %d for L3/L4 filter\n" + , filter_no, EQOS_MAX_L3_L4_FILTER); + return -1; + } + + if (src_dst_addr_match != 0U && src_dst_addr_match != 1U) { + osd_err(osi_core->osd, "invalid src_dst_addr_match %d parameter\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 == 0U) { + osi_writel(value, (unsigned char *)base + + EQOS_MAC_L3_AD0R(filter_no)); + } else { + osi_writel(value, (unsigned char *)base + + EQOS_MAC_L3_AD1R(filter_no)); + } + + return 0; +} + +/** + * eqos_update_ip6_addr - add ipv6 address in register + * + * @osi_core: OSI private data structure. + * @filter_no: filter index + * @addr: ipv6 adderss + * + * Algorithm: This sequence is used to update IPv6 source/destination + * Address for L3 layer filtering + * + * Dependencies: MAC IP should be out of reset + * and need to be initialized as the requirements + * + * Protection: None + * + * Return: 0 - success, -1 - failure. + */ +static int eqos_update_ip6_addr(struct osi_core_priv_data *osi_core, + unsigned int filter_no, unsigned short addr[]) +{ + void *base = osi_core->base; + unsigned int value = 0U; + unsigned int temp = 0U; + + if (filter_no > EQOS_MAX_L3_L4_FILTER) { + osd_err(osi_core->osd, "filter index %d > %d for L3/L4 filter\n" + , filter_no, EQOS_MAX_L3_L4_FILTER); + return -1; + } + + /* update Bits[31:0] of 128-bit IP addr */ + value = addr[7]; + temp = (unsigned int)addr[6] << 16; + value |= temp; + osi_writel(value, (unsigned char *)base + + EQOS_MAC_L3_AD0R(filter_no)); + /* update Bits[63:32] of 128-bit IP addr */ + value = addr[5]; + temp = (unsigned int)addr[4] << 16; + value |= temp; + osi_writel(value, (unsigned char *)base + + EQOS_MAC_L3_AD1R(filter_no)); + /* update Bits[95:64] of 128-bit IP addr */ + value = addr[3]; + temp = (unsigned int)addr[2] << 16; + value |= temp; + osi_writel(value, (unsigned char *)base + + EQOS_MAC_L3_AD2R(filter_no)); + /* update Bits[127:96] of 128-bit IP addr */ + value = addr[1]; + temp = (unsigned int)addr[0] << 16; + value |= temp; + osi_writel(value, (unsigned char *)base + + EQOS_MAC_L3_AD3R(filter_no)); + + return 0; +} + +/** + * eqos_update_l4_port_no -program source port no + * + * @osi_core: OSI private data structure. + * @filter_no: filter index + * @port_no: port number + * @src_dst_port_match: 0 - source port, otherwise - dest port + * + * Algorithm: sequence is used to update Source Port Number for + * L4(TCP/UDP) layer filtering. + * + * Dependencies: MAC IP should be out of reset + * and need to be initialized as the requirements + * + * Protection: None + * + * Return: 0 - success, -1 - failure. + */ +static int eqos_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) +{ + void *base = osi_core->base; + unsigned int value = 0U; + unsigned int temp = 0U; + + if (filter_no > EQOS_MAX_L3_L4_FILTER) { + osd_err(osi_core->osd, "filter index %d > %d for L3/L4 filter\n" + , filter_no, EQOS_MAX_L3_L4_FILTER); + return -1; + } + + value = osi_readl((unsigned char *)base + EQOS_MAC_L4_ADR(filter_no)); + if (src_dst_port_match == 0U) { + value &= ~EQOS_MAC_L4_SP_MASK; + value |= ((unsigned int)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_writel(value, (unsigned char *)base + EQOS_MAC_L4_ADR(filter_no)); + + return 0; +} + +/** + * eqos_config_l3_filters - config L3 filters. + * + * @osi_core: OSI private data structure. + * @filter_no: filter index + * @enb_dis: 1 - enable otherwise - disable L3 filter + * @ipv4_ipv6_match: 1 - IPv6, otherwise - IPv4 + * @src_dst_addr_match: 0 - source, otherwise - destination + * @perfect_inverse_match: normal match(0) or inverse map(1) + * + * Algorithm: This sequence is used to configure L3((IPv4/IPv6) filters for + * address matching. + * + * Dependencies: MAC IP should be out of reset + * and need to be initialized as the requirements + * + * Protection: None + * + * Return: 0 - success, -1 - failure. + */ +static int eqos_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 value = 0U; + void *base = osi_core->base; + + if (filter_no > EQOS_MAX_L3_L4_FILTER) { + osd_err(osi_core->osd, "filter index %d > %d for L3/L4 filter\n" + , filter_no, EQOS_MAX_L3_L4_FILTER); + return -1; + } + + value = osi_readl((unsigned char *)base + + EQOS_MAC_L3L4_CTR(filter_no)); + value &= ~EQOS_MAC_L3L4_CTR_L3PEN0; + value |= (ipv4_ipv6_match & EQOS_MAC_L3L4_CTR_L3PEN0); + osi_writel(value, (unsigned char *)base + + EQOS_MAC_L3L4_CTR(filter_no)); + + /* For IPv6 either SA/DA can be checked not both */ + if (ipv4_ipv6_match == 1U) { + if (enb_dis == 1U) { + if (src_dst_addr_match == 0U) { + /* Enable L3 filters for IPv6 SOURCE addr + * matching + */ + value = osi_readl((unsigned char *)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))); + osi_writel(value, (unsigned char *)base + + EQOS_MAC_L3L4_CTR(filter_no)); + + } else { + /* Enable L3 filters for IPv6 DESTINATION addr + * matching + */ + value = osi_readl((unsigned char *)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))); + osi_writel(value, (unsigned char *)base + + EQOS_MAC_L3L4_CTR(filter_no)); + } + } else { + /* Disable L3 filters for IPv6 SOURCE/DESTINATION addr + * matching + */ + value = osi_readl((unsigned char *)base + + EQOS_MAC_L3L4_CTR(filter_no)); + value &= ~(EQOS_MAC_L3_IP6_CTRL_CLEAR | + EQOS_MAC_L3L4_CTR_L3PEN0); + osi_writel(value, (unsigned char *)base + + EQOS_MAC_L3L4_CTR(filter_no)); + } + } else { + if (src_dst_addr_match == 0U) { + if (enb_dis == 1U) { + /* Enable L3 filters for IPv4 SOURCE addr + * matching + */ + value = osi_readl((unsigned char *)base + + EQOS_MAC_L3L4_CTR(filter_no)); + value &= ~(EQOS_MAC_L3L4_CTR_L3SAM0 | + EQOS_MAC_L3L4_CTR_L3SAIM0); + 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))); + osi_writel(value, (unsigned char *)base + + EQOS_MAC_L3L4_CTR(filter_no)); + } else { + /* Disable L3 filters for IPv4 SOURCE addr + * matching + */ + value = osi_readl((unsigned char *)base + + EQOS_MAC_L3L4_CTR(filter_no)); + value &= ~(EQOS_MAC_L3L4_CTR_L3SAM0 | + EQOS_MAC_L3L4_CTR_L3SAIM0); + osi_writel(value, (unsigned char *)base + + EQOS_MAC_L3L4_CTR(filter_no)); + } + } else { + if (enb_dis == 1U) { + /* Enable L3 filters for IPv4 DESTINATION addr + * matching + */ + value = osi_readl((unsigned char *)base + + EQOS_MAC_L3L4_CTR(filter_no)); + value &= ~(EQOS_MAC_L3L4_CTR_L3DAM0 | + EQOS_MAC_L3L4_CTR_L3DAIM0); + 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))); + osi_writel(value, (unsigned char *)base + + EQOS_MAC_L3L4_CTR(filter_no)); + } else { + /* Disable L3 filters for IPv4 DESTINATION addr + * matching + */ + value = osi_readl((unsigned char *)base + + EQOS_MAC_L3L4_CTR(filter_no)); + value &= ~(EQOS_MAC_L3L4_CTR_L3DAM0 | + EQOS_MAC_L3L4_CTR_L3DAIM0); + osi_writel(value, (unsigned char *)base + + EQOS_MAC_L3L4_CTR(filter_no)); + } + } + } + + return 0; +} + +/** + * osi_config_l4_filters - Config L4 filters. + * + * @osi_core: OSI private data structure. + * @filter_no: filter index + * @enb_dis: 1 - enable, otherwise - disable L4 filter + * @tcp_udp_match: 1 - udp, 0 - tcp + * @src_dst_port_match: 0 - source port, otherwise - dest port + * @perfect_inverse_match: normal match(0) or inverse map(1) + * + * Algorithm: This sequence is used to configure L4(TCP/UDP) filters for + * SA and DA Port Number matching + * + * Dependencies: MAC IP should be out of reset + * and need to be initialized as the requirements + * + * Protection: None + * + * Return: 0 - success, -1 - failure. + */ +static int eqos_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) +{ + void *base = osi_core->base; + unsigned int value = 0U; + + if (filter_no > EQOS_MAX_L3_L4_FILTER) { + osd_err(osi_core->osd, "filter index %d > %d for L3/L4 filter\n" + , filter_no, EQOS_MAX_L3_L4_FILTER); + return -1; + } + + value = osi_readl((unsigned char *)base + EQOS_MAC_L3L4_CTR(filter_no)); + value &= ~EQOS_MAC_L3L4_CTR_L4PEN0; + value |= ((tcp_udp_match << 16) & EQOS_MAC_L3L4_CTR_L4PEN0); + osi_writel(value, (unsigned char *)base + + EQOS_MAC_L3L4_CTR(filter_no)); + + if (src_dst_port_match == 0U) { + if (enb_dis == 1U) { + /* Enable L4 filters for SOURCE Port No matching */ + value = osi_readl((unsigned char *)base + + EQOS_MAC_L3L4_CTR(filter_no)); + value &= ~(EQOS_MAC_L3L4_CTR_L4SPM0 | + EQOS_MAC_L3L4_CTR_L4SPIM0); + 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)); + osi_writel(value, (unsigned char *)base + + EQOS_MAC_L3L4_CTR(filter_no)); + } else { + /* Disable L4 filters for SOURCE Port No matching */ + value = osi_readl((unsigned char *)base + + EQOS_MAC_L3L4_CTR(filter_no)); + value &= ~(EQOS_MAC_L3L4_CTR_L4SPM0 | + EQOS_MAC_L3L4_CTR_L4SPIM0); + osi_writel(value, (unsigned char *)base + + EQOS_MAC_L3L4_CTR(filter_no)); + } + } else { + if (enb_dis == 1U) { + /* Enable L4 filters for DESTINATION port No + * matching + */ + value = osi_readl((unsigned char *)base + + EQOS_MAC_L3L4_CTR(filter_no)); + value &= ~(EQOS_MAC_L3L4_CTR_L4DPM0 | + EQOS_MAC_L3L4_CTR_L4DPIM0); + 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)); + osi_writel(value, (unsigned char *)base + + EQOS_MAC_L3L4_CTR(filter_no)); + } else { + /* Disable L4 filters for DESTINATION port No + * matching + */ + value = osi_readl((unsigned char *)base + + EQOS_MAC_L3L4_CTR(filter_no)); + value &= ~(EQOS_MAC_L3L4_CTR_L4DPM0 | + EQOS_MAC_L3L4_CTR_L4DPIM0); + osi_writel(value, (unsigned char *)base + + EQOS_MAC_L3L4_CTR(filter_no)); + } + } + + return 0; +} + +/** + * eqos_config_vlan_filter_reg - config vlan filter register + * + * @base: Base address from OSI private data structure. + * @filter_enb_dis: vlan filter enable/disable + * @perfect_hash_filtering: perfect or hash filter + * @perfect_inverse_match: normal or inverse filter + * + * Algorithm: This sequence is used to enable/disable VLAN filtering and + * also selects VLAN filtering mode- perfect/hash + * + * Dependencies: MAC IP should be out of reset + * and need to be initialized as the requirements + * + * Protection: None + * + * Return: 0 - success, -1 - failure. + */ +static int eqos_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; + void *base = osi_core->base; + + value = osi_readl((unsigned char *)base + EQOS_MAC_PFR); + value &= ~(EQOS_MAC_PFR_VTFE); + value |= ((filter_enb_dis << EQOS_MAC_PFR_SHIFT) & EQOS_MAC_PFR_VTFE); + osi_writel(value, (unsigned char *)base + EQOS_MAC_PFR); + + value = osi_readl((unsigned char *)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) { + osd_err(osi_core->osd, "VLAN hash filter is not supported not updating VTHM\n"); + } + osi_writel(value, (unsigned char *)base + EQOS_MAC_VLAN_TR); + return 0; +} + +/** + * eqos_update_vlan_id - + * + * @base: Base address from OSI private data structure. + * + * Algorithm: update vid at VLAN tag register + * + * Dependencies: MAC IP should be out of reset and need to be initialized + * as the requirements + * + * Protection: None + * + * Return: 0 - success, -1 - failure. + */ +static inline int eqos_update_vlan_id(void *base, unsigned int vid) +{ + unsigned int value; + + value = osi_readl((unsigned char *)base + EQOS_MAC_VLAN_TR); + /* 0:15 of register */ + value &= ~EQOS_MAC_VLAN_TR_VL; + value |= vid & EQOS_MAC_VLAN_TR_VL; + osi_writel(value, (unsigned char *)base + EQOS_MAC_VLAN_TR); + + return 0; +} + static struct osi_core_ops eqos_core_ops = { .poll_for_swr = eqos_poll_for_swr, .core_init = eqos_core_init, @@ -1519,6 +2190,18 @@ static struct osi_core_ops eqos_core_ops = { .config_flow_control = eqos_config_flow_control, .config_arp_offload = eqos_config_arp_offload, .config_rxcsum_offload = eqos_config_rxcsum_offload, + .config_mac_pkt_filter_reg = eqos_config_mac_pkt_filter_reg, + .update_mac_addr_low_high_reg = eqos_update_mac_addr_low_high_reg, + .config_l3_l4_filter_enable = eqos_config_l3_l4_filter_enable, + .config_l2_da_perfect_inverse_match = + eqos_config_l2_da_perfect_inverse_match, + .config_l3_filters = eqos_config_l3_filters, + .update_ip4_addr = eqos_update_ip4_addr, + .update_ip6_addr = eqos_update_ip6_addr, + .config_l4_filters = eqos_config_l4_filters, + .update_l4_port_no = eqos_update_l4_port_no, + .config_vlan_filtering = eqos_config_vlan_filtering, + .update_vlan_id = eqos_update_vlan_id, }; struct osi_core_ops *eqos_get_hw_core_ops(void) diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 43afce9..4aefc30 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -87,6 +87,7 @@ #define EQOS_DMA_ISR 0x1008 #define EQOS_MAC_ISR 0x00B0 #define EQOS_MAC_RQC1R 0x00A4 +#define EQOS_MAC_RQC2R 0x00A8 #define EQOS_MMC_TX_INTR_MASK 0x0710 #define EQOS_MMC_RX_INTR_MASK 0x070C #define EQOS_MMC_IPC_RX_INTR_MASK 0x0800 @@ -98,6 +99,18 @@ #define EQOS_MAC_EXTR 0x0004 #define EQOS_MAC_RX_FLW_CTRL 0x0090 #define EQOS_MAC_QX_TX_FLW_CTRL(x) ((0x0004U * (x)) + 0x0070U) +/*MAC Filtering*/ +#define EQOS_MAC_HTR_REG(x) ((0x0004U * (x)) + 0x0010U) +/* x will be index from 0 to 127 to write*/ +#define EQOS_MAC_ADDRH(x) ((0x0008U * (x)) + 0x0300U) +#define EQOS_MAC_ADDRL(x) ((0x0008U * (x)) + 0x0304U) +#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_MAC_PFR 0x0008U /* EQOS MTL registers*/ #define EQOS_MTL_CHX_TX_OP_MODE(x) ((0x0040U * (x)) + 0x0D00U) @@ -201,6 +214,68 @@ #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_HUC OSI_BIT(1) +#define EQOS_MAC_PFR_HMC OSI_BIT(2) +#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_SHIFT 16 +#define EQOS_MAC_PFR_IPFE OSI_BIT(20) +#define EQOS_MAC_PFR_DNTU OSI_BIT(21) +#define EQOS_MAC_PFR_RA OSI_BIT(31) +#define EQOS_MAC_PFR_HUC_SHIFT 1 +#define EQOS_MAC_PFR_HMC_SHIFT 2 +#define EQOS_MAC_PFR_DAIF_SHIFT 3 +#define EQOS_MAC_PFR_PM_SHIFT 4 +#define EQOS_MAC_PFR_HPF_SHIFT 10 +#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_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_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_L3_IP6_CTRL_CLEAR (EQOS_MAC_L3L4_CTR_L3SAM0 | \ + EQOS_MAC_L3L4_CTR_L3SAIM0 | \ + EQOS_MAC_L3L4_CTR_L3DAM0 | \ + EQOS_MAC_L3L4_CTR_L3DAIM0) +#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_RQC2_PSRQ_MASK ((unsigned int)0xFF) +#define EQOS_MAC_RQC2_PSRQ_SHIFT 8U +#define EQOS_MAC_VLAN_TR_ETV_SHIFT 16U +#define EQOS_MAC_MAX_HTR_REG_LEN 8U void update_ehfc_rfa_rfd(unsigned int rx_fifo, unsigned int *value); #endif diff --git a/osi/core/libnvethernetrm.export b/osi/core/libnvethernetrm.export index ace98f9..ac692ce 100644 --- a/osi/core/libnvethernetrm.export +++ b/osi/core/libnvethernetrm.export @@ -45,3 +45,15 @@ osi_get_mac_version osi_get_hw_features osi_config_arp_offload osi_config_rxcsum_offload +osi_configure_flow_control +osi_config_mac_pkt_filter_reg +osi_update_mac_addr_low_high_reg +osi_config_l3_l4_filter_enable +osi_config_l3_filters +osi_update_ip4_addr +osi_update_ip6_addr +osi_config_l4_filters +osi_update_l4_port_no +osi_config_vlan_filtering +osi_config_l2_da_perfect_inverse_match +osi_update_vlan_id diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index aae9ef4..51d8d8b 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -444,6 +444,169 @@ int osi_config_arp_offload(struct osi_core_priv_data *osi_core, return ret; } +int osi_config_mac_pkt_filter_reg(struct osi_core_priv_data *osi_core, + struct osi_filter pfilter) +{ + int ret = -1; + + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->config_mac_pkt_filter_reg != OSI_NULL)) { + osi_core->ops->config_mac_pkt_filter_reg(osi_core, + pfilter); + ret = 0; + } + + return ret; +} + +int osi_update_mac_addr_low_high_reg(struct osi_core_priv_data *osi_core, + unsigned int index, unsigned char value[]) +{ + int ret = -1; + + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->update_mac_addr_low_high_reg != OSI_NULL)) { + ret = osi_core->ops->update_mac_addr_low_high_reg( + osi_core, + index, + value); + } + + return ret; +} + +int osi_config_l3_l4_filter_enable(struct osi_core_priv_data *osi_core, + unsigned int enable) +{ + int ret = -1; + + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->config_l3_l4_filter_enable != OSI_NULL)) { + ret = osi_core->ops->config_l3_l4_filter_enable(osi_core->base, + enable); + } + + return ret; +} + +int osi_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) +{ + int ret = -1; + + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->config_l3_filters != OSI_NULL)) { + ret = osi_core->ops->config_l3_filters(osi_core, filter_no, + enb_dis, ipv4_ipv6_match, + src_dst_addr_match, + perfect_inverse_match); + } + + return ret; +} + +int osi_update_ip4_addr(struct osi_core_priv_data *osi_core, + unsigned int filter_no, + unsigned char addr[], + unsigned int src_dst_addr_match) +{ + int ret = -1; + + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->update_ip4_addr != OSI_NULL)) { + ret = osi_core->ops->update_ip4_addr(osi_core, filter_no, + addr, src_dst_addr_match); + } + + return ret; +} + +int osi_update_ip6_addr(struct osi_core_priv_data *osi_core, + unsigned int filter_no, + unsigned short addr[]) +{ + int ret = -1; + + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->update_ip6_addr != OSI_NULL)) { + ret = osi_core->ops->update_ip6_addr(osi_core, filter_no, addr); + } + return ret; +} + +int osi_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) +{ + int ret = -1; + + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->config_l4_filters != OSI_NULL)) { + ret = osi_core->ops->config_l4_filters(osi_core, filter_no, + enb_dis, tcp_udp_match, + src_dst_port_match, + perfect_inverse_match); + } + + return ret; +} + +int osi_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) +{ + int ret = -1; + + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->update_l4_port_no != OSI_NULL)) { + ret = osi_core->ops->update_l4_port_no(osi_core, filter_no, + port_no, + src_dst_port_match); + } + + return ret; +} + +int osi_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) +{ + int ret = -1; + + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->config_vlan_filtering != OSI_NULL)) { + ret = osi_core->ops->config_vlan_filtering(osi_core, + filter_enb_dis, + perfect_hash_filtering, + perfect_inverse_match); + } + + return ret; +} + +int osi_config_l2_da_perfect_inverse_match(struct osi_core_priv_data *osi_core, + unsigned int perfect_inverse_match) +{ + int ret = -1; + + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->config_l2_da_perfect_inverse_match != OSI_NULL)) { + ret = osi_core->ops->config_l2_da_perfect_inverse_match( + osi_core->base, + perfect_inverse_match); + } + + return ret; +} + int osi_config_rxcsum_offload(struct osi_core_priv_data *osi_core, unsigned int enable) { @@ -457,3 +620,17 @@ int osi_config_rxcsum_offload(struct osi_core_priv_data *osi_core, return ret; } + +int osi_update_vlan_id(struct osi_core_priv_data *osi_core, + unsigned int vid) +{ + int ret = -1; + + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->update_vlan_id != OSI_NULL && vid != 0U)) { + ret = osi_core->ops->update_vlan_id(osi_core->base, + vid); + } + + return ret; +} From ceba1867d0ef0a873a304a59387ab44859aa4abb Mon Sep 17 00:00:00 2001 From: Mohit Dhingra <mdhingra@nvidia.com> Date: Mon, 3 Jun 2019 17:09:20 +0530 Subject: [PATCH 019/458] nvethernetrm: add missing api in export file ESQC-9386 Change-Id: I9b603f9c04c539ba1fdc7d78fd7eb117a96184d8 Signed-off-by: Mohit Dhingra <mdhingra@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2129526 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Narayan Reddy <narayanr@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/libnvethernetrm.export | 1 + 1 file changed, 1 insertion(+) diff --git a/osi/core/libnvethernetrm.export b/osi/core/libnvethernetrm.export index ac692ce..0a6daa7 100644 --- a/osi/core/libnvethernetrm.export +++ b/osi/core/libnvethernetrm.export @@ -57,3 +57,4 @@ osi_update_l4_port_no osi_config_vlan_filtering osi_config_l2_da_perfect_inverse_match osi_update_vlan_id +osi_config_fw_err_pkts From 69991bbd135cb796a4df20b72dedfcd66fedc55c Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Thu, 6 Jun 2019 12:47:24 +0530 Subject: [PATCH 020/458] nvethernetrm: replace numeric values with Macros As general practice we have replaced numeric value with Macro for MAC Filter. This will help to make it readable and scalable. Bug 200512993 Change-Id: I4bbc676eabc85be5f0b8285328a3a91e1a7c61ee Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2131537 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_common.h | 3 +++ include/osi_core.h | 4 ++-- osi/core/eqos_core.c | 31 +++++++++++++------------------ 3 files changed, 18 insertions(+), 20 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index 6e312b1..0bbf743 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -64,6 +64,9 @@ #define OSI_HASH_FILTER_MODE 1U #define OSI_PERFECT_FILTER_MODE 0U +#define OSI_IPV6_MATCH 1U +#define OSI_SOURCE_MATCH 0U + #define OSI_L4_FILTER_TCP 0U #define OSI_L4_FILTER_UDP 1U diff --git a/include/osi_core.h b/include/osi_core.h index fef16ba..6f5af66 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -81,7 +81,7 @@ struct osi_vlan_filter { /** * Struct osi_l2_da_filter - L2 filter function depedent parameter * @perfect_hash: perfect(0) or hash(1) - * @perfect_inverse_match: perfect(0) or hash(1) + * @perfect_inverse_match: perfect(0) or inverse(1) */ struct osi_l2_da_filter { unsigned int perfect_hash; @@ -781,7 +781,7 @@ int osi_config_l2_da_perfect_inverse_match(struct osi_core_priv_data *osi_core, unsigned int perfect_inverse_match); /** - * osi_update_vlan_id - invoke osi call to get VLAn ID + * osi_update_vlan_id - invoke osi call to update VLAN ID * * @osi_core: OSI private data structure. * @vid: VLAN ID diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 7dcca11..d8b810e 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1701,6 +1701,7 @@ static int eqos_config_l2_da_perfect_inverse_match(void *base, unsigned int * @osi_core: OSI private data structure. * @filter_no: filter index * @addr: ipv4 address + * @src_dst_addr_match: 0 - source addr otherwise - dest addr * * Algorithm: This sequence is used to update IPv4 source/destination * Address for L3 layer filtering @@ -1727,12 +1728,6 @@ static int eqos_update_ip4_addr(struct osi_core_priv_data *osi_core, return -1; } - if (src_dst_addr_match != 0U && src_dst_addr_match != 1U) { - osd_err(osi_core->osd, "invalid src_dst_addr_match %d parameter\n" - , src_dst_addr_match); - return -1; - } - value = addr[3]; temp = (unsigned int)addr[2] << 8; value |= temp; @@ -1740,7 +1735,7 @@ static int eqos_update_ip4_addr(struct osi_core_priv_data *osi_core, value |= temp; temp = (unsigned int)addr[0] << 24; value |= temp; - if (src_dst_addr_match == 0U) { + if (src_dst_addr_match == OSI_SOURCE_MATCH) { osi_writel(value, (unsigned char *)base + EQOS_MAC_L3_AD0R(filter_no)); } else { @@ -1843,7 +1838,7 @@ static int eqos_update_l4_port_no(struct osi_core_priv_data *osi_core, } value = osi_readl((unsigned char *)base + EQOS_MAC_L4_ADR(filter_no)); - if (src_dst_port_match == 0U) { + if (src_dst_port_match == OSI_SOURCE_MATCH) { value &= ~EQOS_MAC_L4_SP_MASK; value |= ((unsigned int)port_no & EQOS_MAC_L4_SP_MASK); } else { @@ -1900,9 +1895,9 @@ static int eqos_config_l3_filters(struct osi_core_priv_data *osi_core, EQOS_MAC_L3L4_CTR(filter_no)); /* For IPv6 either SA/DA can be checked not both */ - if (ipv4_ipv6_match == 1U) { - if (enb_dis == 1U) { - if (src_dst_addr_match == 0U) { + 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 */ @@ -1944,8 +1939,8 @@ static int eqos_config_l3_filters(struct osi_core_priv_data *osi_core, EQOS_MAC_L3L4_CTR(filter_no)); } } else { - if (src_dst_addr_match == 0U) { - if (enb_dis == 1U) { + if (src_dst_addr_match == OSI_SOURCE_MATCH) { + if (enb_dis == OSI_ENABLE) { /* Enable L3 filters for IPv4 SOURCE addr * matching */ @@ -1972,7 +1967,7 @@ static int eqos_config_l3_filters(struct osi_core_priv_data *osi_core, EQOS_MAC_L3L4_CTR(filter_no)); } } else { - if (enb_dis == 1U) { + if (enb_dis == OSI_ENABLE) { /* Enable L3 filters for IPv4 DESTINATION addr * matching */ @@ -2046,8 +2041,8 @@ static int eqos_config_l4_filters(struct osi_core_priv_data *osi_core, osi_writel(value, (unsigned char *)base + EQOS_MAC_L3L4_CTR(filter_no)); - if (src_dst_port_match == 0U) { - if (enb_dis == 1U) { + if (src_dst_port_match == OSI_SOURCE_MATCH) { + if (enb_dis == OSI_ENABLE) { /* Enable L4 filters for SOURCE Port No matching */ value = osi_readl((unsigned char *)base + EQOS_MAC_L3L4_CTR(filter_no)); @@ -2070,7 +2065,7 @@ static int eqos_config_l4_filters(struct osi_core_priv_data *osi_core, EQOS_MAC_L3L4_CTR(filter_no)); } } else { - if (enb_dis == 1U) { + if (enb_dis == OSI_ENABLE) { /* Enable L4 filters for DESTINATION port No * matching */ @@ -2144,7 +2139,7 @@ static int eqos_config_vlan_filtering(struct osi_core_priv_data *osi_core, } /** - * eqos_update_vlan_id - + * eqos_update_vlan_id - update VLAN ID in Tag register * * @base: Base address from OSI private data structure. * From b3ed543b2c2ded24a5dc2cc6461ae95b46faf7fd Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Wed, 29 May 2019 13:33:51 +0530 Subject: [PATCH 021/458] nvethernetrm: add PTP support This takes care of implementing the PTP support which includes PTP V1/V2 over IPV4,IPV6,Ethernet,gPTP. Bug 200524751 Change-Id: Ieb680d818be81c1a1a8349ddd9ff02bba1896b08 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2127117 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osd.h | 3 +- include/osi_common.h | 28 ++ include/osi_core.h | 201 +++++++++++++- include/osi_dma.h | 7 + include/osi_dma_txrx.h | 5 + osi/core/eqos_core.c | 464 +++++++++++++++++++++++++++++++- osi/core/eqos_core.h | 17 +- osi/core/libnvethernetrm.export | 5 + osi/core/osi_core.c | 274 ++++++++++++++++--- osi/dma/osi_dma_txrx.c | 127 ++++++++- 10 files changed, 1084 insertions(+), 47 deletions(-) diff --git a/include/osd.h b/include/osd.h index 0f87379..6096d2d 100644 --- a/include/osd.h +++ b/include/osd.h @@ -29,7 +29,8 @@ void osd_udelay(unsigned long usec); void osd_info(void *priv, const char *fmt, ...); void osd_err(void *priv, const char *fmt, ...); void osd_receive_packet(void *priv, void *rxring, unsigned int chan, - unsigned int dma_buf_len, void *rxpkt_cx); + unsigned int dma_buf_len, void *rxpkt_cx, + void *rx_pkt_swcx); void osd_transmit_complete(void *priv, void *buffer, unsigned long dmaaddr, unsigned int len, void *txdone_pkt_cx); #endif diff --git a/include/osi_common.h b/include/osi_common.h index 0bbf743..a4b5a5c 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -23,6 +23,15 @@ #ifndef OSI_COMMON_H #define OSI_COMMON_H +#define TEN_POWER_9 0x3B9ACA00U +#define TWO_POWER_32 0x100000000ULL +#define TWO_POWER_31 0x80000000U +#define OSI_NSEC_PER_SEC 1000000000ULL +#define OSI_INVALID_VALUE 0xFFFFFFFFU + +/* System clock is 62.5MHz */ +#define OSI_ETHER_SYSCLOCK 62500000ULL + #define OSI_PAUSE_FRAMES_ENABLE 0U #define OSI_PAUSE_FRAMES_DISABLE 1U #define OSI_FLOW_CTRL_TX OSI_BIT(0) @@ -36,6 +45,25 @@ #ifndef ULONG_MAX #define ULONG_MAX (~0UL) #endif +#ifndef UNIT_MAX +#define UINT_MAX (~0U) +#endif + +/* MAC Time stamp contorl 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_SNAPTYPSEL_3 (OSI_BIT(16) | OSI_BIT(17)) +#define OSI_MAC_TCR_AV8021ASMEN OSI_BIT(28) /* Default maximum Gaint Packet Size Limit */ #define OSI_MAX_MTU_SIZE 9000U diff --git a/include/osi_core.h b/include/osi_core.h index 6f5af66..d911b23 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -146,6 +146,12 @@ struct osi_core_avb_algorithm { * @update_l4_port_no: Called to update L4 Port for filter packet. * @config_vlan_filtering: Called to configure VLAN filtering. * @update_vlan_id: called to update VLAN id. + * @set_systime_to_mac: Called to set current system time to MAC. + * @config_addend: Called to set the addend value to adjust the time. + * @adjust_systime: Called to adjust the system time. + * @get_systime_from_mac: Called to get the current time from MAC. + * @config_tscr: Called to configure the TimeStampControl register. + * @config_ssir: Called to configure the sub second increment register. */ struct osi_core_ops { /* initialize MAC/MTL/DMA Common registers */ @@ -209,6 +215,48 @@ struct osi_core_ops { unsigned int perfect_hash_filtering, unsigned int perfect_inverse_match); int (*update_vlan_id)(void *base, unsigned int vid); + int (*set_systime_to_mac)(void *addr, unsigned int sec, + unsigned int nsec); + int (*config_addend)(void *addr, unsigned int addend); + int (*adjust_systime)(void *addr, unsigned int sec, unsigned int nsec, + unsigned int neg_adj, + unsigned int one_nsec_accuracy); + unsigned long long (*get_systime_from_mac)(void *addr); + void (*config_tscr)(void *addr, unsigned int ptp_filter); + void (*config_ssir)(void *addr, unsigned int ptp_clock); +}; + +/** + * struct osi_ptp_config - PTP configuration + * @ptp_filter: PTP filter parameters bit fields. + * Enable Time stamp,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_fitler is set to Zero then Time stamping is disabled. + * @sec: Seconds + * @nsec: Nano seconds + * @ptp_ref_clk_rate: PTP reference clock read from DT + * @one_nsec_accuracy: Use one nsec accuracy (need to set 1) + * @ptp_clock: PTP system clock which is 62500000Hz + */ +struct osi_ptp_config { + unsigned int ptp_filter; + unsigned int sec; + unsigned int nsec; + unsigned int ptp_ref_clk_rate; + unsigned int one_nsec_accuracy; + unsigned int ptp_clock; }; /** @@ -228,6 +276,8 @@ struct osi_core_ops { * @mac_addr: Ethernet MAC address. * @pause_frames: DT entry to enable(0) or disable(1) pause frame support * @flow_ctrl: Current flow control settings + * @ptp_config: PTP configuration settings. + * @default_addend: Default addend value. */ struct osi_core_priv_data { void *base; @@ -244,6 +294,8 @@ struct osi_core_priv_data { unsigned char mac_addr[OSI_ETH_ALEN]; unsigned int pause_frames; unsigned int flow_ctrl; + struct osi_ptp_config ptp_config; + unsigned int default_addend; }; /** @@ -797,10 +849,157 @@ int osi_config_l2_da_perfect_inverse_match(struct osi_core_priv_data *osi_core, */ int osi_update_vlan_id(struct osi_core_priv_data *osi_core, unsigned int vid); - +/** + * osi_write_phy_reg - Write to a PHY register through MAC over MDIO bus. + * @osi_core: OSI private data structure. + * @phyaddr: PHY address (PHY ID) associated with PHY + * @phyreg: Register which needs to be write to PHY. + * @phydata: Data to write to a PHY register. + * + * Algorithm: + * 1) Before proceding for reading for PHY register check whether any MII + * operation going on MDIO bus by polling MAC_GMII_BUSY bit. + * 2) Program data into MAC MDIO data register. + * 3) 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. + * 4) Write into MAC MDIO address register poll for GMII busy for MDIO + * operation to complete. + * + * Dependencies: MAC IP should be out of reset + * + * Protection: None + * + * Return: 0 - success, -1 - failure + */ int osi_write_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, unsigned int phyreg, unsigned short phydata); + +/** + * osi_read_phy_reg - Read from a PHY register through MAC over MDIO bus. + * @osi_core: OSI private data structure. + * @phyaddr: PHY address (PHY ID) associated with PHY + * @phyreg: Register which needs to be read from PHY. + * + * Algorithm: + * 1) Before proceding for reading for PHY register check whether any MII + * operation going on MDIO bus by polling MAC_GMII_BUSY bit. + * 2) 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. + * 3) 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. + * + * Dependencies: MAC IP should be out of reset + * + * Protection: None + * + * Return: data from PHY register - success, -1 - failure + */ int osi_read_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, unsigned int phyreg); void osi_init_core_ops(struct osi_core_priv_data *osi_core); + +/** + * osi_set_systime_to_mac - Handles setting of system time. + * @osi_core: OSI private data structure. + * @sec: Seconds to be configured. + * @nsec: Nano seconds to be configured. + * + * Algorithm: Set current system time to MAC. + * + * Dependencies: MAC init should be complete. See osi_hw_core_init() and + * osi_hw_dma_init() + * + * Protection: None. + * + * Return: 0 - success, -1 - failure. + */ +int osi_set_systime_to_mac(struct osi_core_priv_data *osi_core, + unsigned int sec, unsigned int nsec); +/** + * osi_adjust_freq - Adjust frequency + * @osi: OSI private data structure. + * @ppb: Parts per Billion + * + * 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. + * + * Dependencies: MAC IP should be out of reset and need to be + * initialized as the requirements + * + * Protection: None + * + * Return: 0 - success, -1 - failure + */ +int osi_adjust_freq(struct osi_core_priv_data *osi_core, int ppb); + +/** + * + * osi_adjust_time - Adjust time + * @osi_core: OSI private data structure. + * @delta: Delta time + * + * Algorithm: Adjust/update the MAC system time (delta passed in + * nanoseconds, can be + or -). + * + * Dependencies: MAC IP should be out of reset + * and need to be initialized as the requirements + * 1) osi_core->ptp_config.one_nsec_accuracy need to be set to 1 + * + * Protection: None + * + * Return: 0 - success, -1 - failure + */ +int osi_adjust_time(struct osi_core_priv_data *osi_core, long delta); + +/** + * osi_get_systime - Get system time + * @osi: OSI private data structure. + * @sec: Value read in Seconds + * @nsec: Value read in Nano seconds + * + * Algorithm: Gets the current system time + * + * Dependencies: MAC IP should be out of reset and need to be + * initialized as the requirements. + * + * Protection: None + * + * Return: None (sec and nsec stores the read seconds and nanoseconds + * values from MAC) + */ +void osi_get_systime_from_mac(struct osi_core_priv_data *osi_core, + unsigned int *sec, + unsigned int *nsec); +/** + * osi_ptp_configuration - Configure PTP + * @osi: OSI private data structure. + * @enable: Enable or disable Time Stamping. + * 0: Disable 1: Enable + * + * Algorithm: Configure the PTP registers that are required for PTP. + * + * Dependencies: MAC IP should be out of reset and need to be initialized + * as the requirements. + * 1) 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. + * 2) osi->ptp_config.ptp_clock need to be filled with the ptp system clk. + * Currently it is set to 62500000Hz. + * 3) osi->ptp_config.ptp_ref_clk_rate need to be filled with the ptp + * reference clock that platform supports. + * 4) osi->ptp_config.sec need to be filled with current time of seconds + * 5) osi->ptp_config.nsec need to be filled with current time of nseconds + * 6) osi->base need to be filled with the ioremapped base address + * + * Protection: None + * + * Return: None + */ + +void osi_ptp_configuration(struct osi_core_priv_data *osi_core, + unsigned int enable); #endif /* OSI_CORE_H */ diff --git a/include/osi_dma.h b/include/osi_dma.h index d5d549c..d1eb05a 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -30,6 +30,7 @@ #define OSI_PKT_CX_VALID OSI_BIT(10) #define OSI_PKT_CX_CSUM OSI_BIT(1) #define OSI_PKT_CX_TSO OSI_BIT(2) +#define OSI_PKT_CX_PTP OSI_BIT(3) /* Flag to indicate if buffer programmed in desc. is DMA map'd from * linear/Paged buffer from OS layer. @@ -37,6 +38,7 @@ #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) +#define OSI_TXDONE_CX_TS OSI_BIT(2) /* Checksum offload result flags */ #define OSI_CHECKSUM_NONE 0x0U @@ -104,12 +106,14 @@ struct osi_rx_swcx { * @rxcsum: Stores the Rx csum * @vlan_tag: Stores the VLAN tag ID in received packet. * @pkt_len: Length of received packet. + * @ns: TS in nsec for the received packet */ struct osi_rx_pkt_cx { unsigned int flags; unsigned int rxcsum; unsigned int vlan_tag; unsigned int pkt_len; + unsigned long long ns; }; /** @@ -183,9 +187,12 @@ struct osi_tx_pkt_cx { * struct osi_txdone_pkt_cx - Transmit done packet context for a packet * @flags: Indicates status flags for Tx complete (tx error occured, or * indicate whether desc. had buf mapped from paged/linear memory etc.) + * @ns: TS captured for the tx packet and this is valid only when the PTP + * bit is set in fields */ struct osi_txdone_pkt_cx { unsigned int flags; + unsigned long long ns; }; /** diff --git a/include/osi_dma_txrx.h b/include/osi_dma_txrx.h index 40e69ec..da0c56b 100644 --- a/include/osi_dma_txrx.h +++ b/include/osi_dma_txrx.h @@ -34,6 +34,7 @@ #define DECR_RX_DESC_INDEX(idx, i) ((idx) = ((idx) - (i)) & (RX_DESC_CNT - 1U)) #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_LD OSI_BIT(28) @@ -50,6 +51,8 @@ #define RDES3_RS0V OSI_BIT(25) #define RDES3_RS1V OSI_BIT(26) #define RDES0_OVT 0x0000FFFFU +#define RDES1_TSA OSI_BIT(14) /* Timestamp available */ +#define RDES1_TD OSI_BIT(15) /* Timestamp Dropped */ #define RDES1_IPCE OSI_BIT(7) #define RDES1_IPCB OSI_BIT(6) @@ -73,6 +76,7 @@ #define TDES3_TPL_MASK 0x3FFFFU #define TDES3_THL_SHIFT 19U #define TDES3_VLTV OSI_BIT(16) +#define TDES3_TTSS OSI_BIT(17) /* Tx Errors */ #define TDES3_IP_HEADER_ERR OSI_BIT(0) @@ -90,6 +94,7 @@ * MAC_VLAN_Incl register or context descriptor.) */ #define TDES2_VTIR ((unsigned int)0x2 << 14U) +#define TDES2_TTSE ((unsigned int)0x1 << 30U) #define TDES3_ES_BITS (TDES3_IP_HEADER_ERR | \ TDES3_UNDER_FLOW_ERR | \ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index d8b810e..39b83f9 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -977,7 +977,9 @@ static void eqos_configure_mac(struct osi_core_priv_data *osi_core) /* Enable Multicast and Broadcast Queue, default is Q0 */ value = osi_readl((unsigned char *)osi_core->base + EQOS_MAC_RQC1R); - value |= EQOS_MAC_RQC1R_MCBCQEN; + value |= EQOS_MAC_RQC1R_MCBCQEN; + /* Routing Multicast and Broadcast to Q1 */ + value |= EQOS_MAC_RQC1R_MCBCQ1; osi_writel(value, (unsigned char *)osi_core->base + EQOS_MAC_RQC1R); /* Disable all MMC interrupts */ @@ -2165,6 +2167,460 @@ static inline int eqos_update_vlan_id(void *base, unsigned int vid) return 0; } +/** + * eqos_poll_for_tsinit_complete - Poll for time stamp init complete + * @addr: MAC base address. + * @mac_tcr: Address to store time stamp control register read value + * + * Algorithm: Read TSINIT value from MAC TCR register until it is + * equal to zero. + * + * Dependencies: None. + * + * Protection: None. + * + * Return: 0 - success, -1 - failure + */ +static inline int eqos_poll_for_tsinit_complete(void *addr, + unsigned int *mac_tcr) +{ + unsigned int retry = 1000; + unsigned int count; + int cond = 1; + + /* Wait for previous(if any) Initialize Timestamp value + * update to complete + */ + count = 0; + while (cond == 1) { + if (count > retry) { + return -1; + } + /* Read and Check TSINIT in MAC_Timestamp_Control register */ + *mac_tcr = osi_readl((unsigned char *)addr + EQOS_MAC_TCR); + if ((*mac_tcr & EQOS_MAC_TCR_TSINIT) == 0U) { + cond = 0; + } + count++; + osd_msleep(1U); + } + + return 0; +} + +/** + * eqos_set_systime - Set system time + * @addr: MAC base address. + * @sec: Seconds to be configured + * @nsec: Nano Seconds to be configured + * + * Algorithm: Updates system time (seconds and nano seconds) + * in hardware registers + * + * Dependencies: None. + * + * Protection: None. + * + * Return: 0 - success, -1 - failure + */ +static int eqos_set_systime_to_mac(void *addr, unsigned int sec, + unsigned int nsec) +{ + unsigned int mac_tcr; + int ret; + + ret = eqos_poll_for_tsinit_complete(addr, &mac_tcr); + if (ret == -1) { + return -1; + } + + /* write seconds value to MAC_System_Time_Seconds_Update register */ + osi_writel(sec, (unsigned char *)addr + EQOS_MAC_STSUR); + + /* write nano seconds value to MAC_System_Time_Nanoseconds_Update + * register + */ + osi_writel(nsec, (unsigned char *)addr + EQOS_MAC_STNSUR); + + /* issue command to update the configured secs and nsecs values */ + mac_tcr |= EQOS_MAC_TCR_TSINIT; + osi_writel(mac_tcr, (unsigned char *)addr + EQOS_MAC_TCR); + + ret = eqos_poll_for_tsinit_complete(addr, &mac_tcr); + if (ret == -1) { + return -1; + } + + return 0; +} + +/** + * eqos_poll_for_tsinit_complete - Poll for addend value write complete + * @addr: MAC base address. + * @mac_tcr: Address to store time stamp control register read value + * + * Algorithm: Read TSADDREG value from MAC TCR register until it is + * equal to zero. + * + * Dependencies: None. + * + * Protection: None. + * + * Return: 0 - success, -1 - failure + */ +static inline int eqos_poll_for_addend_complete(void *addr, + unsigned int *mac_tcr) +{ + unsigned int retry = 1000; + unsigned int count; + int cond = 1; + + /* Wait for previous(if any) addend value update to complete */ + /* Poll */ + count = 0; + while (cond == 1) { + if (count > retry) { + return -1; + } + /* Read and Check TSADDREG in MAC_Timestamp_Control register */ + *mac_tcr = osi_readl((unsigned char *)addr + EQOS_MAC_TCR); + if ((*mac_tcr & EQOS_MAC_TCR_TSADDREG) == 0U) { + cond = 0; + } + count++; + osd_msleep(1U); + } + + return 0; +} + +/** + * eqos_config_addend - Configure addend + * @addr: MAC base address. + * @addend: Addend value to be configured + * + * Algorithm: Updates the Addend value in HW register + * + * Dependencies: None. + * + * Protection: None. + * + * Return: 0 - success, -1 - failure + */ +static int eqos_config_addend(void *addr, unsigned int addend) +{ + unsigned int mac_tcr; + int ret; + + ret = eqos_poll_for_addend_complete(addr, &mac_tcr); + if (ret == -1) { + return -1; + } + + /* write addend value to MAC_Timestamp_Addend register */ + osi_writel(addend, (unsigned char *)addr + EQOS_MAC_TAR); + + /* issue command to update the configured addend value */ + mac_tcr |= EQOS_MAC_TCR_TSADDREG; + osi_writel(mac_tcr, (unsigned char *)addr + EQOS_MAC_TCR); + + ret = eqos_poll_for_addend_complete(addr, &mac_tcr); + if (ret == -1) { + return -1; + } + + return 0; +} + +/** + * eqos_poll_for_update_ts_complete - Poll for update time stamp + * @addr: MAC base address. + * @mac_tcr: Address to store time stamp control register read value + * + * Algorithm: Read time stamp update value from TCR register until it is + * equal to zero. + * + * Dependencies: None. + * + * Protection: None. + * + * Return: 0 - success, -1 - failure + */ +static inline int eqos_poll_for_update_ts_complete(void *addr, + unsigned int *mac_tcr) +{ + unsigned int retry = 1000; + unsigned int count; + int cond = 1; + + /* Wait for previous(if any) time stamp value update to complete */ + count = 0; + while (cond == 1) { + if (count > retry) { + return -1; + } + /* Read and Check TSUPDT in MAC_Timestamp_Control register */ + *mac_tcr = osi_readl((unsigned char *)addr + EQOS_MAC_TCR); + if ((*mac_tcr & EQOS_MAC_TCR_TSUPDT) == 0U) { + cond = 0; + } + count++; + osd_msleep(1U); + } + + return 0; + +} + +/** + * eqos_adjust_systime - Adjust system time + * @addr: MAC base address. + * @sec: Seconds to be configured + * @nsec: Nano seconds to be configured + * @add_sub: To decide on add/sub with system time + * @one_nsec_accuracy: One nano second accuracy + * + * Algorithm: Update the system time + * + * Dependencies: None. + * + * Protection: None. + * + * Return: 0 - success, -1 - failure + */ +static int eqos_adjust_systime(void *addr, unsigned int sec, unsigned int nsec, + unsigned int add_sub, + unsigned int one_nsec_accuracy) +{ + unsigned int mac_tcr; + unsigned int value = 0; + unsigned long long temp = 0; + int ret; + + ret = eqos_poll_for_update_ts_complete(addr, &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 – <new_sec_value>) + */ + 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 - <new_nsec_value>) if + * MAC_TCR.TSCTRLSSR is set or + * (2^32 - <new_nsec_value> 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_writel(sec, (unsigned char *)addr + EQOS_MAC_STSUR); + + /* write nano seconds value and add_sub to + * MAC_System_Time_Nanoseconds_Update register + */ + value |= nsec; + value |= add_sub << EQOS_MAC_STNSUR_ADDSUB_SHIFT; + osi_writel(value, (unsigned char *)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; + osi_writel(mac_tcr, (unsigned char *)addr + EQOS_MAC_TCR); + + ret = eqos_poll_for_update_ts_complete(addr, &mac_tcr); + if (ret == -1) { + return -1; + } + + return 0; +} + +/** + * eqos_get_systime - Get system time from MAC + * @addr: MAC base address. + * + * Algorithm: Get current system time + * + * Dependencies: None. + * + * Protection: None. + * + * Return: 0 - success, -1 - failure + */ +static unsigned long long eqos_get_systime_from_mac(void *addr) +{ + unsigned long long ns1, ns2, ns = 0; + unsigned int varmac_stnsr, temp1; + unsigned int varmac_stsr; + + varmac_stnsr = osi_readl((unsigned char *)addr + EQOS_MAC_STNSR); + temp1 = (varmac_stnsr & EQOS_MAC_STNSR_TSSS_MASK); + ns1 = (unsigned long long)temp1; + + varmac_stsr = osi_readl((unsigned char *)addr + EQOS_MAC_STSR); + + varmac_stnsr = osi_readl((unsigned char *)addr + EQOS_MAC_STNSR); + temp1 = (varmac_stnsr & EQOS_MAC_STNSR_TSSS_MASK); + ns2 = (unsigned long long)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((unsigned char *)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; +} + +/** + * eqos_config_tscr - Configure Time Stamp Register + * @addr: MAC base address. + * @ptp_filter: PTP rx filter parameters + * + * Algorithm: Configure Time Stamp Register + * + * Dependencies: None. + * + * Protection: None. + * + * Return: None. + **/ +static void eqos_config_tscr(void *addr, unsigned int ptp_filter) +{ + unsigned int mac_tcr = 0; + + 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; + } + } else { + /* Disabling the MAC time stamping */ + mac_tcr = OSI_DISABLE; + } + + osi_writel(mac_tcr, (unsigned char *)addr + EQOS_MAC_TCR); +} + +/** + * eqos_config_ssir - Configure SSIR + * @addr: MAC base address. + * @ptp_clock: PTP clock + * + * Algorithm: Configure Sub Second Increment Register + * + * Dependencies: None. + * + * Protection: None. + * + * Return: None. + */ +static void eqos_config_ssir(void *addr, unsigned int ptp_clock) +{ + unsigned int val; + unsigned int mac_tcr; + + mac_tcr = osi_readl((unsigned char *)addr + EQOS_MAC_TCR); + + /* convert the PTP_CLOCK to nano second. + * formula is : ((1/ptp_clock) * 1000000000) + * where, ptp_clock = 50MHz if FINE correction + * and ptp_clock = EQOS_SYSCLOCK if COARSE correction + */ + + if ((mac_tcr & EQOS_MAC_TCR_TSCFUPDT) == EQOS_MAC_TCR_TSCFUPDT) { + val = ((1U * (unsigned int)OSI_NSEC_PER_SEC) / + (unsigned int)OSI_ETHER_SYSCLOCK); + } else { + val = ((1U * (unsigned int)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 */ + osi_writel(val, (unsigned char *)addr + EQOS_MAC_SSIR); +} + static struct osi_core_ops eqos_core_ops = { .poll_for_swr = eqos_poll_for_swr, .core_init = eqos_core_init, @@ -2197,6 +2653,12 @@ static struct osi_core_ops eqos_core_ops = { .update_l4_port_no = eqos_update_l4_port_no, .config_vlan_filtering = eqos_config_vlan_filtering, .update_vlan_id = eqos_update_vlan_id, + .set_systime_to_mac = eqos_set_systime_to_mac, + .config_addend = eqos_config_addend, + .adjust_systime = eqos_adjust_systime, + .get_systime_from_mac = eqos_get_systime_from_mac, + .config_tscr = eqos_config_tscr, + .config_ssir = eqos_config_ssir, }; struct osi_core_ops *eqos_get_hw_core_ops(void) diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 4aefc30..1dec605 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -111,6 +111,13 @@ #define EQOS_MAC_L3_AD2R(x) ((0x0030U * (x)) + 0x0918U) #define EQOS_MAC_L3_AD3R(x) ((0x0030U * (x)) + 0x091CU) #define EQOS_MAC_PFR 0x0008U +#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 /* EQOS MTL registers*/ #define EQOS_MTL_CHX_TX_OP_MODE(x) ((0x0040U * (x)) + 0x0D00U) @@ -178,6 +185,7 @@ #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_MCBCQ1 OSI_BIT(16) #define EQOS_MAC_RQC1R_MCBCQEN OSI_BIT(20) #define EQOS_MTL_QTOMR_FTQ_LPOS OSI_BIT(0) #define EQOS_DMA_ISR_MACIS OSI_BIT(17) @@ -276,6 +284,13 @@ #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_TSADDREG OSI_BIT(5) +#define EQOS_MAC_TCR_TSINIT OSI_BIT(2) +#define EQOS_MAC_TCR_TSUPDT OSI_BIT(3) +#define EQOS_MAC_STNSUR_ADDSUB_SHIFT 31U +#define EQOS_MAC_TCR_TSCFUPDT OSI_BIT(1) +#define EQOS_MAC_TCR_TSCTRLSSR OSI_BIT(9) +#define EQOS_MAC_SSIR_SSINC_SHIFT 16U +#define EQOS_MAC_STNSR_TSSS_MASK 0x7FFFFFFFU void update_ehfc_rfa_rfd(unsigned int rx_fifo, unsigned int *value); #endif diff --git a/osi/core/libnvethernetrm.export b/osi/core/libnvethernetrm.export index 0a6daa7..74829fa 100644 --- a/osi/core/libnvethernetrm.export +++ b/osi/core/libnvethernetrm.export @@ -58,3 +58,8 @@ osi_config_vlan_filtering osi_config_l2_da_perfect_inverse_match osi_update_vlan_id osi_config_fw_err_pkts +osi_ptp_configuration +osi_get_systime_from_mac +osi_adjust_time +osi_adjust_freq +osi_set_systime_to_mac diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 51d8d8b..8473c8e 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -37,27 +37,6 @@ extern struct osi_core_ops *eqos_get_hw_core_ops(void); -/** - * osi_write_phy_reg - Write to a PHY register through MAC over MDIO bus. - * @osi: OSI private data structure. - * @phyaddr: PHY address (PHY ID) associated with PHY - * @phyreg: Register which needs to be write to PHY. - * @phydata: Data to write to a PHY register. - * - * Algorithm: - * 1) Before proceding for reading for PHY register check whether any MII - * operation going on MDIO bus by polling MAC_GMII_BUSY bit. - * 2) Program data into MAC MDIO data register. - * 3) 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. - * 4) Write into MAC MDIO address register poll for GMII busy for MDIO - * operation to complete. - * - * Dependencies: MAC IP should be out of reset - * - * Return: 0 - success, -1 - failure - */ int osi_write_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, unsigned int phyreg, unsigned short phydata) { @@ -129,27 +108,6 @@ int osi_write_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, return 0; } -/** - * osi_read_phy_reg - Read from a PHY register through MAC over MDIO bus. - * @osi: OSI private data structure. - * @phyaddr: PHY address (PHY ID) associated with PHY - * @phyreg: Register which needs to be read from PHY. - * - * Algorithm: - * 1) Before proceding for reading for PHY register check whether any MII - * operation going on MDIO bus by polling MAC_GMII_BUSY bit. - * 2) 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. - * 3) 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. - * - * Dependencies: MAC IP should be out of reset - * - * Return: data from PHY register - success, -1 - failure - */ - int osi_read_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, unsigned int phyreg) { @@ -634,3 +592,235 @@ int osi_update_vlan_id(struct osi_core_priv_data *osi_core, return ret; } + +int osi_set_systime_to_mac(struct osi_core_priv_data *osi_core, + unsigned int sec, unsigned int nsec) +{ + int ret = -1; + + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->set_systime_to_mac != OSI_NULL)) { + ret = osi_core->ops->set_systime_to_mac(osi_core->base, + sec, + nsec); + } + + return ret; +} + +/** + * div_u64_rem - updates remainder and returns Quotient + * @dividend: Dividend value + * @divisor: Divisor value + * @remainder: Remainder + * + * Algorithm: Dividend will be divided by divisor and stores the + * remainder value and returns quotient + * + * Dependencies: MAC IP should be out of reset + * and need to be initialized as the requirements + * + * Protection: None + * + * Return: Quotient + */ +static inline unsigned long div_u64_rem(unsigned long dividend, + unsigned long divisor, + unsigned long *remain) +{ + unsigned long ret = 0; + + if (divisor != 0U) { + *remain = dividend % divisor; + ret = dividend / divisor; + } else { + ret = 0; + } + return ret; +} + +/** + * div_u64 - Calls a function which returns quotient + * @dividend: Dividend + * @divisor: Divisor + * + * Algorithm: Calls a function which returns quotient. + * + * Dependencies: MAC IP should be out of reset + * and need to be initialized as the requirements. + * + * Protection: None + * + * Return: Quotient + */ +static inline unsigned long div_u64(unsigned long dividend, + unsigned long divisor) +{ + unsigned long remain; + + return div_u64_rem(dividend, divisor, &remain); +} + +int osi_adjust_freq(struct osi_core_priv_data *osi_core, int ppb) +{ + unsigned long adj; + unsigned long temp; + unsigned int diff = 0; + unsigned int addend; + unsigned int neg_adj = 0; + int ret = -1; + + if (ppb < 0) { + neg_adj = 1U; + ppb = -ppb; + } + + if (osi_core == OSI_NULL) { + return ret; + } + + addend = osi_core->default_addend; + adj = (unsigned long)addend * (unsigned int)ppb; + + /* + * 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 = (unsigned int)temp; + } else { + /* do nothing here */ + } + + if (neg_adj == 0U) { + if (addend <= UINT_MAX - diff) { + addend = (addend + diff); + } else { + /* do nothing here */ + } + } else { + if (addend > diff) { + addend = addend - diff; + } else if (addend < diff) { + addend = diff - addend; + } else { + /* do nothing here */ + } + } + + if ((osi_core->ops != OSI_NULL) && + (osi_core->ops->config_addend != OSI_NULL)) { + ret = osi_core->ops->config_addend(osi_core->base, addend); + } + + return ret; +} + +int osi_adjust_time(struct osi_core_priv_data *osi_core, long delta) +{ + unsigned int neg_adj = 0; + unsigned int sec = 0, nsec = 0; + unsigned long quotient; + unsigned long reminder = 0; + unsigned long udelta = 0; + int ret = -1; + + if (delta < 0) { + neg_adj = 1; + delta = -delta; + } + udelta = (unsigned long) delta; + quotient = div_u64_rem(udelta, OSI_NSEC_PER_SEC, &reminder); + if (quotient <= UINT_MAX) { + sec = (unsigned int)quotient; + } else { + /* do nothing */ + } + if (reminder <= UINT_MAX) { + nsec = (unsigned int)reminder; + } else { + /* do nothing here */ + } + + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->adjust_systime != OSI_NULL)) { + ret = osi_core->ops->adjust_systime(osi_core->base, sec, nsec, + neg_adj, + osi_core->ptp_config.one_nsec_accuracy); + } + + return ret; +} + +void osi_get_systime_from_mac(struct osi_core_priv_data *osi_core, + unsigned int *sec, + unsigned int *nsec) +{ + unsigned long long ns = 0; + unsigned long long temp = 0; + unsigned long remain = 0; + + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->adjust_systime != OSI_NULL)) { + ns = osi_core->ops->get_systime_from_mac(osi_core->base); + } + + temp = div_u64_rem((unsigned long)ns, OSI_NSEC_PER_SEC, &remain); + if (temp < UINT_MAX) { + *sec = (unsigned int) temp; + } else { + /* do nothing here */ + } + if (remain < UINT_MAX) { + *nsec = (unsigned int)remain; + } else { + /* do nothing here */ + } +} + +void osi_ptp_configuration(struct osi_core_priv_data *osi_core, + unsigned int enable) +{ + int ret = 0; + unsigned long temp = 0, temp1 = 0; + + if (enable == OSI_DISABLE) { + /* disable hw time stamping */ + /* Program MAC_Timestamp_Control Register */ + osi_core->ops->config_tscr(osi_core->base, OSI_DISABLE); + } else { + /* Program MAC_Timestamp_Control Register */ + osi_core->ops->config_tscr(osi_core->base, + osi_core->ptp_config.ptp_filter); + + /* Program Sub Second Increment Register */ + osi_core->ops->config_ssir(osi_core->base, + osi_core->ptp_config.ptp_clock); + + /* formula for calculating addend value is + * addend = 2^32/freq_div_ratio; + * where, freq_div_ratio = EQOS_SYSCLOCK/50MHz + * hence, addend = ((2^32) * 50MHz)/EQOS_SYSCLOCK; + * NOTE: EQOS_SYSCLOCK must be >= 50MHz to achive 20ns accuracy. + * 2^x * y == (y << x), hence + * 2^32 * 6250000 ==> (6250000 << 32) + */ + temp = (unsigned long)(OSI_ETHER_SYSCLOCK << 32); + temp1 = div_u64(temp, + (unsigned long)osi_core->ptp_config.ptp_ref_clk_rate); + if (temp1 < UINT_MAX) { + osi_core->default_addend = (unsigned int) temp1; + } else { + /* do nothing here */ + } + /* Program addend value */ + ret = osi_core->ops->config_addend(osi_core->base, + osi_core->default_addend); + + /* Set current time */ + ret = osi_core->ops->set_systime_to_mac(osi_core->base, + osi_core->ptp_config.sec, + osi_core->ptp_config.nsec); + } +} diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 45f609d..286f616 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -92,6 +92,92 @@ static inline void get_rx_vlan_from_desc(struct osi_rx_desc *rx_desc, } } +/** + * get_rx_tstamp_status - Get Tx Time stamp status + * @context_desc: Rx context descriptor + * + * Algorithm: + * 1) Check if the received descriptor is a context descriptor. + * 2) If yes, check whether the time stamp is valid or not. + * + * Dependencies: None + * + * Protection: None + * + * Return: -1 if TS is not valid and 0 if TS is valid. + */ +static inline int get_rx_tstamp_status(struct osi_rx_desc *context_desc) +{ + 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))) { + /* Invalid time stamp */ + return -1; + } + /* tstamp can be read */ + return 0; + } + /* Busy */ + return -2; +} + +/** + * get_rx_hwstamp - Get Rx HW Time stamp + * @rx_desc: Rx descriptor + * @context_desc: Rx context descriptor + * @rx_pkt_cx: Rx packet context + * + * 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. + * + * Dependencies: None + * + * Protection: None + * + * Return: -1 if TS is not available and 0 if TS is available. + */ +static int get_rx_hwstamp(struct osi_rx_desc *rx_desc, + struct osi_rx_desc *context_desc, + struct osi_rx_pkt_cx *rx_pkt_cx) +{ + int retry, ret = -1; + + /* 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++) { + ret = get_rx_tstamp_status(context_desc); + if (ret == 0) { + /* Update rx pkt context flags to indicate PTP */ + rx_pkt_cx->flags |= OSI_PKT_CX_PTP; + /* Time Stamp can be read */ + break; + } else if (ret != -2) { + /* Failed to get Rx timestamp */ + return ret; + } else { + /* Do nothing here */ + } + /* TS not available yet, so retrying */ + } + if (ret != 0) { + /* Timed out waiting for Rx timestamp */ + return ret; + } + + rx_pkt_cx->ns = context_desc->rdes0 + + (OSI_NSEC_PER_SEC * context_desc->rdes1); + } + return ret; +} + + /** * get_rx_err_stats - Detect Errors from Rx Descriptor * @rx_desc: Rx Descriptor. @@ -144,17 +230,23 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, struct osi_rx_ring *rx_ring = osi->rx_ring[chan]; struct osi_rx_pkt_cx *rx_pkt_cx = &rx_ring->rx_pkt_cx; struct osi_rx_desc *rx_desc = OSI_NULL; + struct osi_rx_swcx *rx_swcx = OSI_NULL; + struct osi_rx_desc *context_desc = OSI_NULL; int received = 0; + int ret = 0; while (received < budget) { osi_memset(rx_pkt_cx, 0, 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; } + INCR_RX_DESC_INDEX(rx_ring->cur_rx_idx, 1U); + /* get the length of the packet */ rx_pkt_cx->pkt_len = rx_desc->rdes3 & RDES3_PKT_LEN; @@ -174,8 +266,17 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, get_rx_csum(rx_desc, rx_pkt_cx); get_rx_vlan_from_desc(rx_desc, rx_pkt_cx); + context_desc = rx_ring->rx_desc + rx_ring->cur_rx_idx; + /* Get rx time stamp */ + ret = get_rx_hwstamp(rx_desc, context_desc, rx_pkt_cx); + if (ret == 0) { + /* Context descriptor was consumed. Its skb + * and DMA mapping will be recycled + */ + INCR_RX_DESC_INDEX(rx_ring->cur_rx_idx, 1U); + } osd_receive_packet(osi->osd, rx_ring, chan, - osi->rx_buf_len, rx_pkt_cx); + osi->rx_buf_len, rx_pkt_cx, rx_swcx); } received++; @@ -349,6 +450,8 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi, struct osi_tx_swcx *tx_swcx = OSI_NULL; struct osi_tx_desc *tx_desc = OSI_NULL; unsigned int entry = tx_ring->clean_idx; + unsigned long vartdes1; + unsigned long long ns; int processed = 0; while (entry != tx_ring->cur_tx_idx) { @@ -370,6 +473,23 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi, } } + if (((tx_desc->tdes3 & TDES3_LD) == TDES3_LD) && + ((tx_desc->tdes3 & TDES3_CTXT) == 0U)) { + /* check tx tstamp status */ + if ((tx_desc->tdes3 & TDES3_TTSS) != 0U) { + txdone_pkt_cx->flags |= OSI_TXDONE_CX_TS; + /* tx timestamp captured for this packet */ + ns = tx_desc->tdes0; + vartdes1 = tx_desc->tdes1; + if (vartdes1 < UINT_MAX) { + ns = ns + (vartdes1 * OSI_NSEC_PER_SEC); + } + txdone_pkt_cx->ns = ns; + } else { + /* Do nothing here */ + } + } + if (tx_swcx->is_paged_buf == 1U) { txdone_pkt_cx->flags |= OSI_TXDONE_CX_PAGED_BUF; } @@ -490,6 +610,11 @@ static inline void fill_first_desc(struct osi_tx_pkt_cx *tx_pkt_cx, 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; + } + /* 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; From 64b887395d15241952f107c32efd5e9999326963 Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Wed, 8 May 2019 06:24:10 +0530 Subject: [PATCH 022/458] nvethernetrm: add HW and SW counters' support These stats are read from MAC HW RMON counters as well as from Core and DMA path. ethtool -S <interface> is used to get statistics. There are 3 stats captured currently 1) ether_mmc_counters: EQOS HW RMON counters 2) ether_xtra_stat_counters: SW counters from osi/core 3) ether_xtra_dma_stat_counters: SW counters from osi/dma Bug 200519211 Change-Id: I5bbeb340cf2ffccb6399687b254f79c67f480179 Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2114208 GVS: Gerrit_Virtual_Submit Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/mmc.h | 385 ++++++++++++++++++++++++++++++ include/osi_common.h | 34 +++ include/osi_core.h | 47 +++- include/osi_dma.h | 5 +- osi/{core => common}/osi_common.c | 18 ++ osi/core/Makefile.tmk | 5 +- osi/core/eqos_core.c | 55 +++++ osi/core/eqos_core.h | 8 + osi/core/eqos_mmc.c | 351 +++++++++++++++++++++++++++ osi/core/eqos_mmc.h | 109 +++++++++ osi/core/libnvethernetrm.export | 2 + osi/core/osi_core.c | 26 ++ osi/dma/Makefile.tmk | 3 +- osi/dma/eqos_dma.h | 1 - osi/dma/osi_dma_txrx.c | 44 ++-- 15 files changed, 1069 insertions(+), 24 deletions(-) create mode 100644 include/mmc.h rename osi/{core => common}/osi_common.c (94%) create mode 100644 osi/core/eqos_mmc.c create mode 100644 osi/core/eqos_mmc.h diff --git a/include/mmc.h b/include/mmc.h new file mode 100644 index 0000000..d75d096 --- /dev/null +++ b/include/mmc.h @@ -0,0 +1,385 @@ +/* + * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef MMC_H +#define MMC_H +/** + * osi_mmc_counters - The structure to hold RMON counter values + * + * mmc_tx_octetcount_gb: This counter provides the number of bytes + * transmitted, exclusive of preamble and retried bytes, in good and + * bad packets. + * mmc_tx_framecount_gb: This counter provides the number of good and + * bad packets transmitted, exclusive of retried packets. + * mmc_tx_broadcastframe_g: This counter provides the number of good + * broadcast packets transmitted + * mmc_tx_multicastframe_g: This counter provides the number of good + * multicast packets transmitted + * mmc_tx_64_octets_gb: This counter provides the number of good and bad + * packets transmitted with length 64 bytes, exclusive of preamble and + * retried packets + * mmc_tx_65_to_127_octets_gb: This counter provides the number of good + * and bad packets transmitted with length 65-127 bytes, exclusive of + * preamble and retried packets + * mmc_tx_128_to_255_octets_gb: This counter provides the number of good + * and bad packets transmitted with length 128-255 bytes, exclusive of + * preamble and retried packets + * mmc_tx_256_to_511_octets_gb: This counter provides the number of good + * and bad packets transmitted with length 256-511 bytes, exclusive of + * preamble and retried packets + * mmc_tx_512_to_1023_octets_gb: This counter provides the number of good + * and bad packets transmitted with length 512-1023 bytes, exclusive of + * preamble and retried packets + * mmc_tx_1024_to_max_octets_gb: This counter provides the number of good + * and bad packets transmitted with length 1024-max bytes, exclusive of + * preamble and retried packets + * mmc_tx_unicast_gb: This counter provides the number of good and bad + * unicast packets + * mmc_tx_multicast_gb: This counter provides the number of good and bad + * multicast packets + * mmc_tx_broadcast_gb: This counter provides the number of good and bad + * braodcast packets + * mmc_tx_underflow_error: This counter provides the number of abort + * packets due to underflow error + * mmc_tx_singlecol_g: This counter provides the number of successfully + * transmitted packets after a single collision in the half-duplex mode + * mmc_tx_multicol_g: This counter provides the number of successfully + * transmitted packets after a multiple collision in the half-duplex mode + * mmc_tx_deferred: This counter provides the number of successfully + * transmitted after a deferral in the half-duplex mode + * mmc_tx_latecol: This counter provides the number of packets aborted + * because of late collision error + * mmc_tx_exesscol: This counter provides the number of packets aborted + * because of excessive (16) collision errors + * mmc_tx_carrier_error: This counter provides the number of packets + * aborted because of carrier sense error (no carrier or loss of carrier) + * mmc_tx_octetcount_g: This counter provides the number of bytes + * transmitted, exclusive of preamble, only in good packets. + * mmc_tx_framecount_g: This counter provides the number of good packets + * transmitted . + * mmc_tx_excessdef: This counter provides the number of packets aborted + * because of excessive deferral error (deferred for more than two + * max-sized packet times). + * mmc_tx_pause_frame: This counter provides the number of good Pause + * packets transmitted. + * mmc_tx_vlan_frame_g: This counter provides the number of good + * VLAN packets transmitted + * mmc_tx_osize_frame_g: This counter provides the number of packets + * transmitted without errors and with length greater than the maxsize + * (1,518 or 1,522 bytes for VLAN tagged packets; 2000 bytes. + * mmc_rx_framecount_gb: This counter provides the number of good and bad + * packets received + * mmc_rx_octetcount_gb: This counter provides the number of bytes + * received by DWC_ther_qos, exclusive of preamble, in good and bad packets + * mmc_rx_octetcount_g: This counter provides the number of bytes + * received by DWC_ther_qos, exclusive of preamble, in good and bad packets + * mmc_rx_broadcastframe_g: This counter provides the number of good + * broadcast packets received + * mmc_rx_multicastframe_g: This counter provides the number of good + * multicast packets received + * mmc_rx_crc_error: This counter provides the number of packets received + * with CRC error + * mmc_rx_align_error: This counter provides the number of packets + * received with alignment (dribble) error. It is valid only in 10/100 + * mode. + * mmc_rx_runt_error: This counter provides the number of packets + * received with runt (length less than 64 bytes and CRC error) error + * mmc_rx_jabber_error: This counter provides the number of giant packets + * received with length (including CRC) greater than 1,518 bytes + * (1,522 bytes for VLAN tagged) and with CRC error. + * mmc_rx_undersize_g: This counter provides the number of packets + * received with length less than 64 bytes, without any errors + * mmc_rx_oversize_g: This counter provides the number of packets + * received without errors, with length greater than the maxsize + * mmc_rx_64_octets_gb: This counter provides the number of good and bad + * packets received with length 64 bytes, exclusive of the preamble. + * mmc_rx_65_to_127_octets_gb: This counter provides the number of good + * and bad packets received with length 65-127 bytes, exclusive of the + * preamble. + * mmc_rx_128_to_255_octets_gb: This counter provides the number of good + * and bad packets received with length 128-255 bytes, exclusive of the + * preamble. + * mmc_rx_256_to_511_octets_gb: This counter provides the number of good + * and bad packets received with length 256-511 bytes, exclusive of the + * preamble. + * mmc_rx_512_to_1023_octets_gb: This counter provides the number of good + * and bad packets received with length 512-1023 bytes, exclusive of the + * preamble. + * mmc_rx_1024_to_max_octets_gb: This counter provides the number of good + * and bad packets received with length 1024-max bytes, exclusive of the + * preamble. + * mmc_rx_unicast_g: This counter provides the number of good unicast + * packets received mmc_rx_length_error: This counter provides the + * number of packets received with length error (Length Type field + * not equal to packet size), for all packets with valid length field. + * mmc_rx_outofrangetype: This counter provides the number of packets + * received with length field not equal to the + * valid packet size (greater than 1,500 but less than 1,536). + * mmc_rx_pause_frames: This counter provides the number of good and + * valid Pause packets received + * mmc_rx_fifo_overflow: This counter provides the number of missed + * received packets because of FIFO overflow in DWC_ether_qos + * mmc_rx_vlan_frames_gb: This counter provides the number of good and + * bad VLAN packets received + * mmc_rx_watchdog_error: This counter provides the number of packets + * received with error because of watchdog timeout error + * mmc_rx_receive_error: This counter provides the number of packets + * received with Receive error or Packet Extension error on the GMII or + * MII interface + * mmc_rx_ctrl_frames_g: This counter provides the number of packets + * received with Receive error or Packet Extension error on the GMII + * or MII interface + * mmc_rx_ipv4_gd: This counter provides the number of good IPv4 + * datagrams received with the TCP, UDP, or ICMP payload + * mmc_rx_ipv4_hderr: RxIPv4 Header Error Packets + * mmc_rx_ipv4_nopay: This counter provides the number of IPv4 datagram + * packets received that did not have a TCP, UDP, or ICMP payload + * mmc_rx_ipv4_frag: This counter provides the number of good IPv4 + * datagrams received with fragmentation. + * mmc_rx_ipv4_udsbl: This counter provides the number of good IPv4 + * datagrams received that had a UDP payload with checksum disabled + * mmc_rx_ipv6_gd_octets: This counter provides the number of good IPv6 + * datagrams received with the TCP, UDP, or ICMP payload + * mmc_rx_ipv6_hderr_octets: This counter provides the number of IPv6 + * datagrams received with header (length or version mismatch) errors + * mmc_rx_ipv6_nopay_octets: This counter provides the number of IPv6 + * datagram packets received that did not have a TCP, UDP, or ICMP + * payload + * mmc_rx_udp_gd: This counter provides the number of good IP datagrams + * received by DWC_ether_qos with a good UDP payload. + * mmc_rx_udp_err: This counter provides the number of good IP datagrams + * received by DWC_ether_qos with a good UDP payload. This counter is not + * updated when the RxIPv4_UDP_Checksum_Disabled_Packets counter is + * incremented. + * mmc_rx_tcp_gd: This counter provides the number of good IP datagrams + * received with a good TCP payload + * mmc_rx_tcp_err: This counter provides the number of good IP datagrams + * received with a good TCP payload + * mmc_rx_icmp_gd: This counter provides the number of good IP datagrams + * received with a good ICMP payload + * mmc_rx_icmp_err: This counter provides the number of good IP + * datagrams received whose ICMP payload has a checksum error + * mmc_rx_ipv4_gd_octets: This counter provides the number of bytes + * received by DWC_ether_qos in good IPv4 datagrams encapsulating TCP, + * UDP, or ICMP data. (Ethernet header, FCS, pad, or IP pad bytes are + * not included in this counter + * mmc_rx_ipv4_hderr_octets: This counter provides the number of bytes + * received in IPv4 datagrams with header errors (checksum, length, + * version mismatch). The value in the Length field of IPv4 header is + * used to update this counter. (Ethernet header, FCS, pad, + * or IP pad bytes are not included in this counter + * mmc_rx_ipv4_nopay_octets: This counter provides the number of bytes + * received in IPv4 datagrams that did not have a TCP, UDP, or + * ICMP payload. The value in the Length field of IPv4 header is used + * to update this counter. (Ethernet header, FCS, pad, or IP pad bytes + * are not included in this counter. + * mmc_rx_ipv4_frag_octets: This counter provides the number of bytes + * received in fragmented IPv4 datagrams. The value in the Length + * field of IPv4 header is used to update this counter. (Ethernet header, + * FCS, pad, or IP pad bytes are not included in this counter + * mmc_rx_ipv4_udsbl_octets: This counter provides the number of bytes + * received in a UDP segment that had the UDP checksum disabled. This + * counter does not count IP Header bytes. (Ethernet header, FCS, pad, + * or IP pad bytes are not included in this counter. + * mmc_rx_ipv6_gd: This counter provides the number of bytes received + * in good IPv6 datagrams encapsulating TCP, UDP, or ICMP data. + * (Ethernet header, FCS, pad, or IP pad bytes are not included in + * this counter + * mmc_rx_ipv6_hderr: This counter provides the number of bytes received + * in IPv6 datagrams with header errors (length, version mismatch). The + * value in the Length field of IPv6 header is used to update this + * counter. (Ethernet header, FCS, pad, or IP pad bytes are not included + * in this counter. + * mmc_rx_ipv6_nopay: This counter provides the number of bytes received + * in IPv6 datagrams that did not have a TCP, UDP, or ICMP payload. The + * value in the Length field of IPv6 header is used to update this + * counter. (Ethernet header, FCS, pad, or IP pad bytes are not included + * in this counter + * mmc_rx_udp_gd_octets: This counter provides the number of bytes + * received in a good UDP segment. This counter does not count IP header + * bytes. + * mmc_rx_udp_err_octets: This counter provides the number of bytes + * received in a UDP segment that had checksum errors. This counter + * does not count IP header bytes + * mmc_rx_tcp_gd_octets: This counter provides the number of bytes + * received in a good TCP segment. This counter does not count IP + * header bytes + * mmc_rx_tcp_err_octets: This counter provides the number of bytes + * received in a TCP segment that had checksum errors. This counter + * does not count IP header bytes + * mmc_rx_icmp_gd_octets: This counter provides the number of bytes + * received in a good ICMP segment. This counter does not count + * IP header bytes + * mmc_rx_icmp_err_octets: This counter provides the number of bytes + * received in a ICMP segment that had checksum errors. + * This counter does not count IP header bytes + */ +struct osi_mmc_counters { + /* MMC TX counters */ + unsigned long mmc_tx_octetcount_gb; + unsigned long mmc_tx_framecount_gb; + unsigned long mmc_tx_broadcastframe_g; + unsigned long mmc_tx_multicastframe_g; + unsigned long mmc_tx_64_octets_gb; + unsigned long mmc_tx_65_to_127_octets_gb; + unsigned long mmc_tx_128_to_255_octets_gb; + unsigned long mmc_tx_256_to_511_octets_gb; + unsigned long mmc_tx_512_to_1023_octets_gb; + unsigned long mmc_tx_1024_to_max_octets_gb; + unsigned long mmc_tx_unicast_gb; + unsigned long mmc_tx_multicast_gb; + unsigned long mmc_tx_broadcast_gb; + unsigned long mmc_tx_underflow_error; + unsigned long mmc_tx_singlecol_g; + unsigned long mmc_tx_multicol_g; + unsigned long mmc_tx_deferred; + unsigned long mmc_tx_latecol; + unsigned long mmc_tx_exesscol; + unsigned long mmc_tx_carrier_error; + unsigned long mmc_tx_octetcount_g; + unsigned long mmc_tx_framecount_g; + unsigned long mmc_tx_excessdef; + unsigned long mmc_tx_pause_frame; + unsigned long mmc_tx_vlan_frame_g; + unsigned long mmc_tx_osize_frame_g; + + /* MMC RX counters */ + unsigned long mmc_rx_framecount_gb; + unsigned long mmc_rx_octetcount_gb; + unsigned long mmc_rx_octetcount_g; + unsigned long mmc_rx_broadcastframe_g; + unsigned long mmc_rx_multicastframe_g; + unsigned long mmc_rx_crc_error; + unsigned long mmc_rx_align_error; + unsigned long mmc_rx_runt_error; + unsigned long mmc_rx_jabber_error; + unsigned long mmc_rx_undersize_g; + unsigned long mmc_rx_oversize_g; + unsigned long mmc_rx_64_octets_gb; + unsigned long mmc_rx_65_to_127_octets_gb; + unsigned long mmc_rx_128_to_255_octets_gb; + unsigned long mmc_rx_256_to_511_octets_gb; + unsigned long mmc_rx_512_to_1023_octets_gb; + unsigned long mmc_rx_1024_to_max_octets_gb; + unsigned long mmc_rx_unicast_g; + unsigned long mmc_rx_length_error; + unsigned long mmc_rx_outofrangetype; + unsigned long mmc_rx_pause_frames; + unsigned long mmc_rx_fifo_overflow; + unsigned long mmc_rx_vlan_frames_gb; + unsigned long mmc_rx_watchdog_error; + unsigned long mmc_rx_receive_error; + unsigned long mmc_rx_ctrl_frames_g; + + /* IPv4 */ + unsigned long mmc_rx_ipv4_gd; + unsigned long mmc_rx_ipv4_hderr; + unsigned long mmc_rx_ipv4_nopay; + unsigned long mmc_rx_ipv4_frag; + unsigned long mmc_rx_ipv4_udsbl; + + /* IPV6 */ + unsigned long mmc_rx_ipv6_gd_octets; + unsigned long mmc_rx_ipv6_hderr_octets; + unsigned long mmc_rx_ipv6_nopay_octets; + + /* Protocols */ + unsigned long mmc_rx_udp_gd; + unsigned long mmc_rx_udp_err; + unsigned long mmc_rx_tcp_gd; + unsigned long mmc_rx_tcp_err; + unsigned long mmc_rx_icmp_gd; + unsigned long mmc_rx_icmp_err; + + /* IPv4 */ + unsigned long mmc_rx_ipv4_gd_octets; + unsigned long mmc_rx_ipv4_hderr_octets; + unsigned long mmc_rx_ipv4_nopay_octets; + unsigned long mmc_rx_ipv4_frag_octets; + unsigned long mmc_rx_ipv4_udsbl_octets; + + /* IPV6 */ + unsigned long mmc_rx_ipv6_gd; + unsigned long mmc_rx_ipv6_hderr; + unsigned long mmc_rx_ipv6_nopay; + + /* Protocols */ + unsigned long mmc_rx_udp_gd_octets; + unsigned long mmc_rx_udp_err_octets; + unsigned long mmc_rx_tcp_gd_octets; + unsigned long mmc_rx_tcp_err_octets; + unsigned long mmc_rx_icmp_gd_octets; + unsigned long mmc_rx_icmp_err_octets; +}; + +/** + * osi_xtra_stat_counters - OSI core extra stat counters + * + * rx_buf_unavail_irq_n: RX buffer unavailable irq count + * tx_proc_stopped_irq_n: Transmit Process Stopped irq count + * tx_buf_unavail_irq_n: Transmit Buffer Unavailable irq count + * rx_proc_stopped_irq_n: Receive Process Stopped irq count + * rx_watchdog_irq_n: Receive Watchdog Timeout irq count + * fatal_bus_error_irq_n: Fatal Bus Error irq count + * q_re_alloc_rx_buf_failed: rx sbk allocation failure count + * tx_normal_irq_n: TX per channel interrupt count + * rx_normal_irq_n: RX per cannel interrupt count + * link_connect_count: link disconnect count + * link_disconnect_count: link connect count + */ +struct osi_xtra_stat_counters { + unsigned long rx_buf_unavail_irq_n[OSI_EQOS_MAX_NUM_QUEUES]; + unsigned long tx_proc_stopped_irq_n[OSI_EQOS_MAX_NUM_QUEUES]; + unsigned long tx_buf_unavail_irq_n[OSI_EQOS_MAX_NUM_QUEUES]; + unsigned long rx_proc_stopped_irq_n[OSI_EQOS_MAX_NUM_QUEUES]; + unsigned long rx_watchdog_irq_n; + unsigned long fatal_bus_error_irq_n; + unsigned long re_alloc_rxbuf_failed[OSI_EQOS_MAX_NUM_QUEUES]; + unsigned long tx_normal_irq_n[OSI_EQOS_MAX_NUM_QUEUES]; + unsigned long rx_normal_irq_n[OSI_EQOS_MAX_NUM_QUEUES]; + unsigned long link_connect_count; + unsigned long link_disconnect_count; +}; + +/** + * osi_xtra_dma_stat_counters - OSI dma extra stats counters + * q_tx_pkt_n: Per Q TX packet count + * q_rx_pkt_n: Per Q RX packet count + * tx_clean_n: Per Q TX complete call count + * tx_pkt_n: Total number of tx packets count + * rx_pkt_n: Total number of rx packet count + * rx_vlan_pkt_n: Total number of VLAN RX packet count + * tx_vlan_pkt_n: Total number of VLAN TX packet count + * tx_tso_pkt_n: Total number of TSO packet count + */ +struct osi_xtra_dma_stat_counters { + unsigned long q_tx_pkt_n[OSI_EQOS_MAX_NUM_QUEUES]; + unsigned long q_rx_pkt_n[OSI_EQOS_MAX_NUM_QUEUES]; + unsigned long tx_clean_n[OSI_EQOS_MAX_NUM_QUEUES]; + unsigned long tx_pkt_n; + unsigned long rx_pkt_n; + unsigned long rx_vlan_pkt_n; + unsigned long tx_vlan_pkt_n; + unsigned long tx_tso_pkt_n; +}; + +#endif diff --git a/include/osi_common.h b/include/osi_common.h index a4b5a5c..7b30d89 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -65,6 +65,8 @@ #define OSI_MAC_TCR_SNAPTYPSEL_3 (OSI_BIT(16) | OSI_BIT(17)) #define OSI_MAC_TCR_AV8021ASMEN OSI_BIT(28) +#define OSI_UCHAR_MAX 0xFFU + /* Default maximum Gaint Packet Size Limit */ #define OSI_MAX_MTU_SIZE 9000U #define OSI_DFLT_MTU_SIZE 1500U @@ -102,7 +104,9 @@ #define OSI_IP4_FILTER 0U #define OSI_IP6_FILTER 1U +/* FIXME add logic based on HW version */ #define OSI_EQOS_MAX_NUM_CHANS 4U +#define OSI_EQOS_MAX_NUM_QUEUES 4U #define OSI_BIT(nr) ((unsigned int)1 << (nr)) @@ -406,6 +410,35 @@ static inline int is_valid_mac_version(unsigned int mac_ver) return 0; } +/** + * osi_update_stats_counter - update value by increment passed as parameter + * @last_value: last value of stat counter + * @incr: increment value + * + * Algorithm: Check for boundary and return sum + * + * Dependencies: Input parameter should be only unsigned long type + * + * Protection: None + * + * Return: unsigned long value + */ +static inline unsigned long osi_update_stats_counter(unsigned long last_value, + unsigned long incr) +{ + unsigned long long temp; + + temp = (unsigned long long)last_value; + temp = temp + incr; + if (temp > ULONG_MAX) { + /* Do nothing */ + } else { + return (unsigned long)temp; + } + + return last_value; +} + /** * osi_get_mac_version - Reading MAC version * @addr: io-remap MAC base address. @@ -422,4 +455,5 @@ static inline int is_valid_mac_version(unsigned int mac_ver) int osi_get_mac_version(void *addr, unsigned int *mac_ver); void osi_get_hw_features(void *base, struct osi_hw_features *hw_feat); +void osi_memset(void *s, unsigned int c, unsigned long count); #endif /* OSI_COMMON_H */ diff --git a/include/osi_core.h b/include/osi_core.h index d911b23..6066f13 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -24,6 +24,7 @@ #define OSI_CORE_H #include "osi_common.h" +#include "mmc.h" struct osi_core_priv_data; @@ -152,6 +153,8 @@ struct osi_core_avb_algorithm { * @get_systime_from_mac: Called to get the current time from MAC. * @config_tscr: Called to configure the TimeStampControl register. * @config_ssir: Called to configure the sub second increment register. + * @read_mmc: called to update MMC counter from HW register + * @reset_mmc: called to reset MMC HW counter and Structure */ struct osi_core_ops { /* initialize MAC/MTL/DMA Common registers */ @@ -224,6 +227,8 @@ struct osi_core_ops { unsigned long long (*get_systime_from_mac)(void *addr); void (*config_tscr)(void *addr, unsigned int ptp_filter); void (*config_ssir)(void *addr, unsigned int ptp_clock); + void (*read_mmc)(struct osi_core_priv_data *osi_core); + void (*reset_mmc)(struct osi_core_priv_data *osi_core); }; /** @@ -278,6 +283,8 @@ struct osi_ptp_config { * @flow_ctrl: Current flow control settings * @ptp_config: PTP configuration settings. * @default_addend: Default addend value. + * @mmc: mmc counter structure + * @xstats: xtra sw error counters */ struct osi_core_priv_data { void *base; @@ -296,6 +303,8 @@ struct osi_core_priv_data { unsigned int flow_ctrl; struct osi_ptp_config ptp_config; unsigned int default_addend; + struct osi_mmc_counters mmc; + struct osi_xtra_stat_counters xstats; }; /** @@ -849,6 +858,7 @@ int osi_config_l2_da_perfect_inverse_match(struct osi_core_priv_data *osi_core, */ int osi_update_vlan_id(struct osi_core_priv_data *osi_core, unsigned int vid); + /** * osi_write_phy_reg - Write to a PHY register through MAC over MDIO bus. * @osi_core: OSI private data structure. @@ -875,6 +885,41 @@ int osi_update_vlan_id(struct osi_core_priv_data *osi_core, int osi_write_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, unsigned int phyreg, unsigned short phydata); +/** + * osi_read_mmc - invoke function to read actual registers and update + * structure variable mmc + * + * @osi_core: OSI core private data structure. + * + * Algorithm: Read the registers, mask reserve bits if requied, update + * structure. + * + * Dependencies: MAC IP should be out of reset and need to be initialized + * as per the requirements + * + * Protection: None + * + * Return: 0 - success, -1 - failure. + */ +int osi_read_mmc(struct osi_core_priv_data *osi_core); + +/** + * osi_reset_mmc - invoke function to rest MMC counter and data structure + * + * @osi_core: OSI core private data structure. + * + * Algorithm: Read the registers, mask reserve bits if requied, update + * structure. + * + * Dependencies: MAC IP should be out of reset and need to be initialized + * as per the requirements + * + * Protection: None + * + * Return: 0 - success, -1 - failure. + */ +int osi_reset_mmc(struct osi_core_priv_data *osi_core); + /** * osi_read_phy_reg - Read from a PHY register through MAC over MDIO bus. * @osi_core: OSI private data structure. @@ -999,7 +1044,7 @@ void osi_get_systime_from_mac(struct osi_core_priv_data *osi_core, * * Return: None */ - void osi_ptp_configuration(struct osi_core_priv_data *osi_core, unsigned int enable); + #endif /* OSI_CORE_H */ diff --git a/include/osi_dma.h b/include/osi_dma.h index d1eb05a..b3b4a4a 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -25,6 +25,7 @@ #include "osi_common.h" #include "osi_dma_txrx.h" +#include "mmc.h" #define OSI_PKT_CX_VLAN OSI_BIT(0) #define OSI_PKT_CX_VALID OSI_BIT(10) @@ -274,7 +275,8 @@ struct osi_dma_chan_ops { * @dma_chans[]: Array of supported DMA channels * @rx_buf_len: DMA Rx channel buffer length at HW level. * @mtu: MTU size - * @osi_pkt_err_stats: Packet error stats + * @pkt_err_stats: Packet error stats + * @dstats: Extra DMA stats */ struct osi_dma_priv_data { struct osi_tx_ring *tx_ring[OSI_EQOS_MAX_NUM_CHANS]; @@ -288,6 +290,7 @@ struct osi_dma_priv_data { unsigned int rx_buf_len; unsigned int mtu; struct osi_pkt_err_stats pkt_err_stats; + struct osi_xtra_dma_stat_counters dstats; }; /** diff --git a/osi/core/osi_common.c b/osi/common/osi_common.c similarity index 94% rename from osi/core/osi_common.c rename to osi/common/osi_common.c index ba8da0a..df137b4 100644 --- a/osi/core/osi_common.c +++ b/osi/common/osi_common.c @@ -133,3 +133,21 @@ int osi_get_mac_version(void *addr, unsigned int *mac_ver) *mac_ver = macver; return ret; } + +void osi_memset(void *s, unsigned int c, unsigned long count) +{ + unsigned char *xs = s; + int brk = 1; + + while (brk != 0) { + if (c < OSI_UCHAR_MAX) { + *xs++ = (unsigned char)c; + } + if (count > 0U) { + count--; + } + if (count == 0U) { + brk = 0; + } + } +} diff --git a/osi/core/Makefile.tmk b/osi/core/Makefile.tmk index 516063b..f322e53 100644 --- a/osi/core/Makefile.tmk +++ b/osi/core/Makefile.tmk @@ -29,8 +29,9 @@ NV_COMPONENT_NAME := nvethernetrm NV_COMPONENT_OWN_INTERFACE_DIR := . NV_COMPONENT_SOURCES := \ eqos_core.c \ - osi_common.c \ - osi_core.c + eqos_mmc.c \ + osi_core.c \ + $(NV_SOURCE)/nvethernetrm/osi/common/osi_common.c NV_COMPONENT_NEEDED_INTERFACE_DIRS := \ $(NV_SOURCE)/qnx/src/libs/nvethernet/osi_dependencies diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 39b83f9..90d38d7 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -24,6 +24,7 @@ #include <osi_core.h> #include <osd.h> #include "eqos_core.h" +#include "eqos_mmc.h" struct osi_core_ops *eqos_get_hw_core_ops(void); @@ -1213,6 +1214,57 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *osi_core, } } +/** + * update_dma_sr_stats - stats for dma_status error + * @osi_core: OSI core private data structure. + * @dma_sr: Dma status register read value + * @qinx: Queue index + * + * Algorithm: increament error stats based on corresponding bit filed. + * + * Dependencies: None + * + * Protection: None. + * + * Return: None. + */ +static inline void update_dma_sr_stats(struct osi_core_priv_data *osi_core, + unsigned int dma_sr, unsigned int qinx) +{ + unsigned long val; + + if ((dma_sr & EQOS_DMA_CHX_STATUS_RBU) == EQOS_DMA_CHX_STATUS_RBU) { + val = osi_core->xstats.rx_buf_unavail_irq_n[qinx]; + osi_core->xstats.rx_buf_unavail_irq_n[qinx] = + osi_update_stats_counter(val, 1U); + } + if ((dma_sr & EQOS_DMA_CHX_STATUS_TPS) == EQOS_DMA_CHX_STATUS_TPS) { + val = osi_core->xstats.tx_proc_stopped_irq_n[qinx]; + osi_core->xstats.tx_proc_stopped_irq_n[qinx] = + osi_update_stats_counter(val, 1U); + } + if ((dma_sr & EQOS_DMA_CHX_STATUS_TBU) == EQOS_DMA_CHX_STATUS_TBU) { + val = osi_core->xstats.tx_buf_unavail_irq_n[qinx]; + osi_core->xstats.tx_buf_unavail_irq_n[qinx] = + osi_update_stats_counter(val, 1U); + } + if ((dma_sr & EQOS_DMA_CHX_STATUS_RPS) == EQOS_DMA_CHX_STATUS_RPS) { + val = osi_core->xstats.rx_proc_stopped_irq_n[qinx]; + osi_core->xstats.rx_proc_stopped_irq_n[qinx] = + osi_update_stats_counter(val, 1U); + } + if ((dma_sr & EQOS_DMA_CHX_STATUS_RWT) == EQOS_DMA_CHX_STATUS_RWT) { + val = osi_core->xstats.rx_watchdog_irq_n; + osi_core->xstats.rx_watchdog_irq_n = + osi_update_stats_counter(val, 1U); + } + if ((dma_sr & EQOS_DMA_CHX_STATUS_FBE) == EQOS_DMA_CHX_STATUS_FBE) { + val = osi_core->xstats.fatal_bus_error_irq_n; + osi_core->xstats.fatal_bus_error_irq_n = + osi_update_stats_counter(val, 1U); + } +} + /** * eqos_handle_common_intr - Handles common interrupt. * @osi_core: OSI core private data structure. @@ -1267,6 +1319,7 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *osi_core) /* ack non ti/ri ints */ osi_writel(dma_sr, (unsigned char *)base + EQOS_DMA_CHX_STATUS(qinx)); + update_dma_sr_stats(osi_core, dma_sr, qinx); } } @@ -2659,6 +2712,8 @@ static struct osi_core_ops eqos_core_ops = { .get_systime_from_mac = eqos_get_systime_from_mac, .config_tscr = eqos_config_tscr, .config_ssir = eqos_config_ssir, + .read_mmc = eqos_read_mmc, + .reset_mmc = eqos_reset_mmc, }; struct osi_core_ops *eqos_get_hw_core_ops(void) diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 1dec605..f5e9483 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -292,5 +292,13 @@ #define EQOS_MAC_TCR_TSCTRLSSR OSI_BIT(9) #define EQOS_MAC_SSIR_SSINC_SHIFT 16U #define EQOS_MAC_STNSR_TSSS_MASK 0x7FFFFFFFU + +#define EQOS_DMA_CHX_STATUS_TPS OSI_BIT(1) +#define EQOS_DMA_CHX_STATUS_TBU OSI_BIT(2) +#define EQOS_DMA_CHX_STATUS_RBU OSI_BIT(7) +#define EQOS_DMA_CHX_STATUS_RPS OSI_BIT(8) +#define EQOS_DMA_CHX_STATUS_RWT OSI_BIT(9) +#define EQOS_DMA_CHX_STATUS_FBE OSI_BIT(10) + void update_ehfc_rfa_rfd(unsigned int rx_fifo, unsigned int *value); #endif diff --git a/osi/core/eqos_mmc.c b/osi/core/eqos_mmc.c new file mode 100644 index 0000000..7dadf16 --- /dev/null +++ b/osi/core/eqos_mmc.c @@ -0,0 +1,351 @@ +/* + * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <osi_common.h> +#include <osi_core.h> +#include <osd.h> +#include "eqos_mmc.h" +#include "eqos_core.h" + +/** + * update_mmc_val - function to read resgister and return vlaue to callee + * + * @osi_core: OSI core private data structure. + * @last_vlaue: previous value of stats variable. + * @offset: HW register offset + * + * Algorithm: Read the registers, check for boundary, if more, reset + * counters else return same to caller. + * + * Dependencies: MAC IP should be out of reset and need to be initialized + * as per the requirements + * + * Protection: None + * + * Return: unsigned value + */ +static inline unsigned long update_mmc_val(struct osi_core_priv_data *osi_core, + unsigned long last_value, + unsigned long offset) +{ + unsigned long long temp; + unsigned int value = osi_readl((unsigned char *)osi_core->base + + offset); + + temp = (unsigned long long)last_value; + temp = temp + (unsigned long long)value; + if (temp > ULONG_MAX) { + osd_err(osi_core->osd, "Value overflow for offset = 0x%x resetting all counters\n", + offset); + eqos_reset_mmc(osi_core); + } else { + return (unsigned long)temp; + } + + return 0; +} + +/** + * eqos_reset_mmc - To reset MMC registers and ether_mmc_counter structure + * variable + * @osi_core: OSI core private data structure. + * + * Algorithm: reset HW counter and structure variable value. + * + * Dependencies: MAC IP should be out of reset and need to be initialized + * as per the requirements. + * + * Protection: None + * + * Return: None + */ +void eqos_reset_mmc(struct osi_core_priv_data *osi_core) +{ + unsigned int value; + + value = osi_readl((unsigned char *)osi_core->base + EQOS_MMC_CNTRL); + /* self-clear bit in one clock cycle */ + value |= EQOS_MMC_CNTRL_CNTRST; + osi_writel(value, (unsigned char *)osi_core->base + EQOS_MMC_CNTRL); + osi_memset(&osi_core->mmc, 0U, sizeof(struct osi_mmc_counters)); +} + +/** + * eqos_read_mmc - To read MMC registers and ether_mmc_counter structure + * variable + * @osi_core: OSI core private data structure. + * + * Algorithm: Pass register offset and old value to helper function and + * update structure. + * + * Dependencies: MAC IP should be out of reset and need to be initialized + * as per the requirements + * + * Protection: None + * + * Return: None + */ +void eqos_read_mmc(struct osi_core_priv_data *osi_core) +{ + struct osi_mmc_counters *mmc = &osi_core->mmc; + + mmc->mmc_tx_octetcount_gb = + update_mmc_val(osi_core, mmc->mmc_tx_octetcount_gb, + MMC_TXOCTETCOUNT_GB); + mmc->mmc_tx_framecount_gb = + update_mmc_val(osi_core, mmc->mmc_tx_framecount_gb, + MMC_TXPACKETCOUNT_GB); + mmc->mmc_tx_broadcastframe_g = + update_mmc_val(osi_core, mmc->mmc_tx_broadcastframe_g, + MMC_TXBROADCASTPACKETS_G); + mmc->mmc_tx_multicastframe_g = + update_mmc_val(osi_core, mmc->mmc_tx_multicastframe_g, + MMC_TXMULTICASTPACKETS_G); + mmc->mmc_tx_64_octets_gb = + update_mmc_val(osi_core, mmc->mmc_tx_64_octets_gb, + MMC_TX64OCTETS_GB); + mmc->mmc_tx_65_to_127_octets_gb = + update_mmc_val(osi_core, mmc->mmc_tx_65_to_127_octets_gb, + MMC_TX65TO127OCTETS_GB); + mmc->mmc_tx_128_to_255_octets_gb = + update_mmc_val(osi_core, mmc->mmc_tx_128_to_255_octets_gb, + MMC_TX128TO255OCTETS_GB); + mmc->mmc_tx_256_to_511_octets_gb = + update_mmc_val(osi_core, mmc->mmc_tx_256_to_511_octets_gb, + MMC_TX256TO511OCTETS_GB); + mmc->mmc_tx_512_to_1023_octets_gb = + update_mmc_val(osi_core, mmc->mmc_tx_512_to_1023_octets_gb, + MMC_TX512TO1023OCTETS_GB); + mmc->mmc_tx_1024_to_max_octets_gb = + update_mmc_val(osi_core, mmc->mmc_tx_1024_to_max_octets_gb, + MMC_TX1024TOMAXOCTETS_GB); + mmc->mmc_tx_unicast_gb = + update_mmc_val(osi_core, mmc->mmc_tx_unicast_gb, + MMC_TXUNICASTPACKETS_GB); + mmc->mmc_tx_multicast_gb = + update_mmc_val(osi_core, mmc->mmc_tx_multicast_gb, + MMC_TXMULTICASTPACKETS_GB); + mmc->mmc_tx_broadcast_gb = + update_mmc_val(osi_core, mmc->mmc_tx_broadcast_gb, + MMC_TXBROADCASTPACKETS_GB); + mmc->mmc_tx_underflow_error = + update_mmc_val(osi_core, mmc->mmc_tx_underflow_error, + MMC_TXUNDERFLOWERROR); + mmc->mmc_tx_singlecol_g = + update_mmc_val(osi_core, mmc->mmc_tx_singlecol_g, + MMC_TXSINGLECOL_G); + mmc->mmc_tx_multicol_g = + update_mmc_val(osi_core, mmc->mmc_tx_multicol_g, + MMC_TXMULTICOL_G); + mmc->mmc_tx_deferred = + update_mmc_val(osi_core, mmc->mmc_tx_deferred, + MMC_TXDEFERRED); + mmc->mmc_tx_latecol = + update_mmc_val(osi_core, mmc->mmc_tx_latecol, + MMC_TXLATECOL); + mmc->mmc_tx_exesscol = + update_mmc_val(osi_core, mmc->mmc_tx_exesscol, + MMC_TXEXESSCOL); + mmc->mmc_tx_carrier_error = + update_mmc_val(osi_core, mmc->mmc_tx_exesscol, + MMC_TXCARRIERERROR); + mmc->mmc_tx_octetcount_g = + update_mmc_val(osi_core, mmc->mmc_tx_octetcount_g, + MMC_TXOCTETCOUNT_G); + mmc->mmc_tx_framecount_g = + update_mmc_val(osi_core, mmc->mmc_tx_framecount_g, + MMC_TXPACKETSCOUNT_G); + mmc->mmc_tx_excessdef = + update_mmc_val(osi_core, mmc->mmc_tx_excessdef, + MMC_TXEXCESSDEF); + mmc->mmc_tx_pause_frame = + update_mmc_val(osi_core, mmc->mmc_tx_pause_frame, + MMC_TXPAUSEPACKETS); + mmc->mmc_tx_vlan_frame_g = + update_mmc_val(osi_core, mmc->mmc_tx_vlan_frame_g, + MMC_TXVLANPACKETS_G); + mmc->mmc_tx_osize_frame_g = + update_mmc_val(osi_core, mmc->mmc_tx_osize_frame_g, + MMC_TXOVERSIZE_G); + mmc->mmc_rx_framecount_gb = + update_mmc_val(osi_core, mmc->mmc_rx_framecount_gb, + MMC_RXPACKETCOUNT_GB); + mmc->mmc_rx_octetcount_gb = + update_mmc_val(osi_core, mmc->mmc_rx_octetcount_gb, + MMC_RXOCTETCOUNT_GB); + mmc->mmc_rx_octetcount_g = + update_mmc_val(osi_core, mmc->mmc_rx_octetcount_g, + MMC_RXOCTETCOUNT_G); + mmc->mmc_rx_broadcastframe_g = + update_mmc_val(osi_core, mmc->mmc_rx_broadcastframe_g, + MMC_RXBROADCASTPACKETS_G); + mmc->mmc_rx_multicastframe_g = + update_mmc_val(osi_core, mmc->mmc_rx_multicastframe_g, + MMC_RXMULTICASTPACKETS_G); + mmc->mmc_rx_crc_error = + update_mmc_val(osi_core, mmc->mmc_rx_crc_error, + MMC_RXCRCERROR); + mmc->mmc_rx_align_error = + update_mmc_val(osi_core, mmc->mmc_rx_align_error, + MMC_RXALIGNMENTERROR); + mmc->mmc_rx_runt_error = + update_mmc_val(osi_core, mmc->mmc_rx_runt_error, + MMC_RXRUNTERROR); + mmc->mmc_rx_jabber_error = + update_mmc_val(osi_core, mmc->mmc_rx_jabber_error, + MMC_RXJABBERERROR); + mmc->mmc_rx_undersize_g = + update_mmc_val(osi_core, mmc->mmc_rx_undersize_g, + MMC_RXUNDERSIZE_G); + mmc->mmc_rx_oversize_g = + update_mmc_val(osi_core, mmc->mmc_rx_oversize_g, + MMC_RXOVERSIZE_G); + mmc->mmc_rx_64_octets_gb = + update_mmc_val(osi_core, mmc->mmc_rx_64_octets_gb, + MMC_RX64OCTETS_GB); + mmc->mmc_rx_65_to_127_octets_gb = + update_mmc_val(osi_core, mmc->mmc_rx_65_to_127_octets_gb, + MMC_RX65TO127OCTETS_GB); + mmc->mmc_rx_128_to_255_octets_gb = + update_mmc_val(osi_core, mmc->mmc_rx_128_to_255_octets_gb, + MMC_RX128TO255OCTETS_GB); + mmc->mmc_rx_256_to_511_octets_gb = + update_mmc_val(osi_core, mmc->mmc_rx_256_to_511_octets_gb, + MMC_RX256TO511OCTETS_GB); + mmc->mmc_rx_512_to_1023_octets_gb = + update_mmc_val(osi_core, mmc->mmc_rx_512_to_1023_octets_gb, + MMC_RX512TO1023OCTETS_GB); + mmc->mmc_rx_1024_to_max_octets_gb = + update_mmc_val(osi_core, mmc->mmc_rx_1024_to_max_octets_gb, + MMC_RX1024TOMAXOCTETS_GB); + mmc->mmc_rx_unicast_g = + update_mmc_val(osi_core, mmc->mmc_rx_unicast_g, + MMC_RXUNICASTPACKETS_G); + mmc->mmc_rx_length_error = + update_mmc_val(osi_core, mmc->mmc_rx_length_error, + MMC_RXLENGTHERROR); + mmc->mmc_rx_outofrangetype = + update_mmc_val(osi_core, mmc->mmc_rx_outofrangetype, + MMC_RXOUTOFRANGETYPE); + mmc->mmc_rx_pause_frames = + update_mmc_val(osi_core, mmc->mmc_rx_pause_frames, + MMC_RXPAUSEPACKETS); + mmc->mmc_rx_fifo_overflow = + update_mmc_val(osi_core, mmc->mmc_rx_fifo_overflow, + MMC_RXFIFOOVERFLOW); + mmc->mmc_rx_vlan_frames_gb = + update_mmc_val(osi_core, mmc->mmc_rx_vlan_frames_gb, + MMC_RXVLANPACKETS_GB); + mmc->mmc_rx_watchdog_error = + update_mmc_val(osi_core, mmc->mmc_rx_watchdog_error, + MMC_RXWATCHDOGERROR); + mmc->mmc_rx_receive_error = + update_mmc_val(osi_core, mmc->mmc_rx_receive_error, + MMC_RXRCVERROR); + mmc->mmc_rx_ctrl_frames_g = + update_mmc_val(osi_core, mmc->mmc_rx_ctrl_frames_g, + MMC_RXCTRLPACKETS_G); + mmc->mmc_rx_ipv4_gd = + update_mmc_val(osi_core, mmc->mmc_rx_ipv4_gd, + MMC_RXIPV4_GD_PKTS); + mmc->mmc_rx_ipv4_hderr = + update_mmc_val(osi_core, mmc->mmc_rx_ipv4_hderr, + MMC_RXIPV4_HDRERR_PKTS); + mmc->mmc_rx_ipv4_nopay = + update_mmc_val(osi_core, mmc->mmc_rx_ipv4_nopay, + MMC_RXIPV4_NOPAY_PKTS); + mmc->mmc_rx_ipv4_frag = + update_mmc_val(osi_core, mmc->mmc_rx_ipv4_frag, + MMC_RXIPV4_FRAG_PKTS); + mmc->mmc_rx_ipv4_udsbl = + update_mmc_val(osi_core, mmc->mmc_rx_ipv4_udsbl, + MMC_RXIPV4_UBSBL_PKTS); + mmc->mmc_rx_ipv6_gd_octets = + update_mmc_val(osi_core, mmc->mmc_rx_ipv6_gd_octets, + MMC_RXIPV6_GD_PKTS); + mmc->mmc_rx_ipv6_hderr_octets = + update_mmc_val(osi_core, mmc->mmc_rx_ipv6_hderr_octets, + MMC_RXIPV6_HDRERR_PKTS); + mmc->mmc_rx_ipv6_nopay_octets = + update_mmc_val(osi_core, mmc->mmc_rx_ipv6_nopay_octets, + MMC_RXIPV6_NOPAY_PKTS); + mmc->mmc_rx_udp_gd = + update_mmc_val(osi_core, mmc->mmc_rx_udp_gd, + MMC_RXUDP_GD_PKTS); + mmc->mmc_rx_udp_err = + update_mmc_val(osi_core, mmc->mmc_rx_udp_err, + MMC_RXUDP_ERR_PKTS); + mmc->mmc_rx_tcp_gd = + update_mmc_val(osi_core, mmc->mmc_rx_tcp_gd, + MMC_RXTCP_GD_PKTS); + mmc->mmc_rx_tcp_err = + update_mmc_val(osi_core, mmc->mmc_rx_tcp_err, + MMC_RXTCP_ERR_PKTS); + mmc->mmc_rx_icmp_gd = + update_mmc_val(osi_core, mmc->mmc_rx_icmp_gd, + MMC_RXICMP_GD_PKTS); + mmc->mmc_rx_icmp_err = + update_mmc_val(osi_core, mmc->mmc_rx_icmp_err, + MMC_RXICMP_ERR_PKTS); + mmc->mmc_rx_ipv4_gd_octets = + update_mmc_val(osi_core, mmc->mmc_rx_ipv4_gd_octets, + MMC_RXIPV4_GD_OCTETS); + mmc->mmc_rx_ipv4_hderr_octets = + update_mmc_val(osi_core, mmc->mmc_rx_ipv4_hderr_octets, + MMC_RXIPV4_HDRERR_OCTETS); + mmc->mmc_rx_ipv4_nopay_octets = + update_mmc_val(osi_core, mmc->mmc_rx_ipv4_nopay_octets, + MMC_RXIPV4_NOPAY_OCTETS); + mmc->mmc_rx_ipv4_frag_octets = + update_mmc_val(osi_core, mmc->mmc_rx_ipv4_frag_octets, + MMC_RXIPV4_FRAG_OCTETS); + mmc->mmc_rx_ipv4_udsbl_octets = + update_mmc_val(osi_core, mmc->mmc_rx_ipv4_udsbl_octets, + MMC_RXIPV4_UDSBL_OCTETS); + mmc->mmc_rx_udp_gd_octets = + update_mmc_val(osi_core, mmc->mmc_rx_udp_gd_octets, + MMC_RXIPV6_GD_OCTETS); + mmc->mmc_rx_ipv6_hderr = + update_mmc_val(osi_core, mmc->mmc_rx_ipv6_hderr, + MMC_RXIPV6_HDRERR_OCTETS); + mmc->mmc_rx_ipv6_nopay = + update_mmc_val(osi_core, mmc->mmc_rx_ipv6_nopay, + MMC_RXIPV6_NOPAY_OCTETS); + mmc->mmc_rx_udp_gd_octets = + update_mmc_val(osi_core, mmc->mmc_rx_udp_gd_octets, + MMC_RXUDP_GD_OCTETS); + mmc->mmc_rx_udp_err_octets = + update_mmc_val(osi_core, mmc->mmc_rx_udp_err_octets, + MMC_RXUDP_ERR_OCTETS); + mmc->mmc_rx_tcp_gd_octets = + update_mmc_val(osi_core, mmc->mmc_rx_tcp_gd_octets, + MMC_RXTCP_GD_OCTETS); + mmc->mmc_rx_tcp_err_octets = + update_mmc_val(osi_core, mmc->mmc_rx_tcp_err_octets, + MMC_RXTCP_ERR_OCTETS); + mmc->mmc_rx_icmp_gd_octets = + update_mmc_val(osi_core, mmc->mmc_rx_icmp_gd_octets, + MMC_RXICMP_GD_OCTETS); + mmc->mmc_rx_icmp_err_octets = + update_mmc_val(osi_core, mmc->mmc_rx_icmp_err_octets, + MMC_RXICMP_ERR_OCTETS); +} diff --git a/osi/core/eqos_mmc.h b/osi/core/eqos_mmc.h new file mode 100644 index 0000000..d581792 --- /dev/null +++ b/osi/core/eqos_mmc.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef EQOS_MMC_H_ +#define EQOS_MMC_H_ + +#define MMC_TXOCTETCOUNT_GB 0x00714 +#define MMC_TXPACKETCOUNT_GB 0x00718 +#define MMC_TXBROADCASTPACKETS_G 0x0071c +#define MMC_TXMULTICASTPACKETS_G 0x00720 +#define MMC_TX64OCTETS_GB 0x00724 +#define MMC_TX65TO127OCTETS_GB 0x00728 +#define MMC_TX128TO255OCTETS_GB 0x0072c +#define MMC_TX256TO511OCTETS_GB 0x00730 +#define MMC_TX512TO1023OCTETS_GB 0x00734 +#define MMC_TX1024TOMAXOCTETS_GB 0x00738 +#define MMC_TXUNICASTPACKETS_GB 0x0073c +#define MMC_TXMULTICASTPACKETS_GB 0x00740 +#define MMC_TXBROADCASTPACKETS_GB 0x00744 +#define MMC_TXUNDERFLOWERROR 0x00748 +#define MMC_TXSINGLECOL_G 0x0074c +#define MMC_TXMULTICOL_G 0x00750 +#define MMC_TXDEFERRED 0x00754 +#define MMC_TXLATECOL 0x00758 +#define MMC_TXEXESSCOL 0x0075c +#define MMC_TXCARRIERERROR 0x00760 +#define MMC_TXOCTETCOUNT_G 0x00764 +#define MMC_TXPACKETSCOUNT_G 0x00768 +#define MMC_TXEXCESSDEF 0x0076c +#define MMC_TXPAUSEPACKETS 0x00770 +#define MMC_TXVLANPACKETS_G 0x00774 +#define MMC_TXOVERSIZE_G 0x00778 +#define MMC_RXPACKETCOUNT_GB 0x00780 +#define MMC_RXOCTETCOUNT_GB 0x00784 +#define MMC_RXOCTETCOUNT_G 0x00788 +#define MMC_RXBROADCASTPACKETS_G 0x0078c +#define MMC_RXMULTICASTPACKETS_G 0x00790 +#define MMC_RXCRCERROR 0x00794 +#define MMC_RXALIGNMENTERROR 0x00798 +#define MMC_RXRUNTERROR 0x0079c +#define MMC_RXJABBERERROR 0x007a0 +#define MMC_RXUNDERSIZE_G 0x007a4 +#define MMC_RXOVERSIZE_G 0x007a8 +#define MMC_RX64OCTETS_GB 0x007ac +#define MMC_RX65TO127OCTETS_GB 0x007b0 +#define MMC_RX128TO255OCTETS_GB 0x007b4 +#define MMC_RX256TO511OCTETS_GB 0x007b8 +#define MMC_RX512TO1023OCTETS_GB 0x007bc +#define MMC_RX1024TOMAXOCTETS_GB 0x007c0 +#define MMC_RXUNICASTPACKETS_G 0x007c4 +#define MMC_RXLENGTHERROR 0x007c8 +#define MMC_RXOUTOFRANGETYPE 0x007cc +#define MMC_RXPAUSEPACKETS 0x007d0 +#define MMC_RXFIFOOVERFLOW 0x007d4 +#define MMC_RXVLANPACKETS_GB 0x007d8 +#define MMC_RXWATCHDOGERROR 0x007dc +#define MMC_RXRCVERROR 0x007e0 +#define MMC_RXCTRLPACKETS_G 0x007e4 +#define MMC_RXIPV4_GD_PKTS 0x00810 +#define MMC_RXIPV4_HDRERR_PKTS 0x00814 +#define MMC_RXIPV4_NOPAY_PKTS 0x00818 +#define MMC_RXIPV4_FRAG_PKTS 0x0081c +#define MMC_RXIPV4_UBSBL_PKTS 0x00820 +#define MMC_RXIPV6_GD_PKTS 0x00824 +#define MMC_RXIPV6_HDRERR_PKTS 0x00828 +#define MMC_RXIPV6_NOPAY_PKTS 0x0082c +#define MMC_RXUDP_GD_PKTS 0x00830 +#define MMC_RXUDP_ERR_PKTS 0x00834 +#define MMC_RXTCP_GD_PKTS 0x00838 +#define MMC_RXTCP_ERR_PKTS 0x0083c +#define MMC_RXICMP_GD_PKTS 0x00840 +#define MMC_RXICMP_ERR_PKTS 0x00844 +#define MMC_RXIPV4_GD_OCTETS 0x00850 +#define MMC_RXIPV4_HDRERR_OCTETS 0x00854 +#define MMC_RXIPV4_NOPAY_OCTETS 0x00858 +#define MMC_RXIPV4_FRAG_OCTETS 0x0085c +#define MMC_RXIPV4_UDSBL_OCTETS 0x00860 +#define MMC_RXIPV6_GD_OCTETS 0x00864 +#define MMC_RXIPV6_HDRERR_OCTETS 0x00868 +#define MMC_RXIPV6_NOPAY_OCTETS 0x0086c +#define MMC_RXUDP_GD_OCTETS 0x00870 +#define MMC_RXUDP_ERR_OCTETS 0x00874 +#define MMC_RXTCP_GD_OCTETS 0x00878 +#define MMC_RXTCP_ERR_OCTETS 0x0087c +#define MMC_RXICMP_GD_OCTETS 0x00880 +#define MMC_RXICMP_ERR_OCTETS 0x00884 + +void eqos_read_mmc(struct osi_core_priv_data *osi_core); +void eqos_reset_mmc(struct osi_core_priv_data *osi_core); +#endif diff --git a/osi/core/libnvethernetrm.export b/osi/core/libnvethernetrm.export index 74829fa..cc158d5 100644 --- a/osi/core/libnvethernetrm.export +++ b/osi/core/libnvethernetrm.export @@ -63,3 +63,5 @@ osi_get_systime_from_mac osi_adjust_time osi_adjust_freq osi_set_systime_to_mac +osi_read_mmc +osi_reset_mmc diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 8473c8e..b2b3065 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -824,3 +824,29 @@ void osi_ptp_configuration(struct osi_core_priv_data *osi_core, osi_core->ptp_config.nsec); } } + +int osi_read_mmc(struct osi_core_priv_data *osi_core) +{ + int ret = -1; + + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->read_mmc != OSI_NULL)) { + osi_core->ops->read_mmc(osi_core); + ret = 0; + } + + return ret; +} + +int osi_reset_mmc(struct osi_core_priv_data *osi_core) +{ + int ret = -1; + + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->reset_mmc != OSI_NULL)) { + osi_core->ops->reset_mmc(osi_core); + ret = 0; + } + + return ret; +} diff --git a/osi/dma/Makefile.tmk b/osi/dma/Makefile.tmk index e61be7b..da32328 100644 --- a/osi/dma/Makefile.tmk +++ b/osi/dma/Makefile.tmk @@ -30,7 +30,8 @@ NV_COMPONENT_OWN_INTERFACE_DIR := . NV_COMPONENT_SOURCES := \ eqos_dma.c \ osi_dma.c \ - osi_dma_txrx.c + osi_dma_txrx.c \ + $(NV_SOURCE)/nvethernetrm/osi/common/osi_common.c NV_COMPONENT_NEEDED_INTERFACE_DIRS := \ $(NV_SOURCE)/qnx/src/libs/nvethernet/osi_dependencies diff --git a/osi/dma/eqos_dma.h b/osi/dma/eqos_dma.h index 322acc2..aab8ce8 100644 --- a/osi/dma/eqos_dma.h +++ b/osi/dma/eqos_dma.h @@ -68,5 +68,4 @@ #define EQOS_DMA_CHX_RBSZ_SHIFT 1U #define EQOS_DMA_CHX_TX_CTRL_TXPBL_RECOMMENDED 0x200000U #define EQOS_DMA_CHX_RX_CTRL_RXPBL_RECOMMENDED 0xC0000U - #endif diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 286f616..638626f 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -26,21 +26,6 @@ int dma_desc_init(struct osi_dma_priv_data *osi_dma); -static inline void osi_memset(void *s, int c, unsigned long count) -{ - char *xs = s; - int brk = 1; - - while (brk != 0) { - *xs++ = (char)c; - count--; - - if (count == 0U) { - brk = 0; - } - } -} - /** * get_rx_csum - Get the Rx checksum from descriptor if valid * @rx_desc: Rx descriptor @@ -236,7 +221,7 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, int ret = 0; while (received < budget) { - osi_memset(rx_pkt_cx, 0, sizeof(*rx_pkt_cx)); + osi_memset(rx_pkt_cx, 0U, sizeof(*rx_pkt_cx)); rx_desc = rx_ring->rx_desc + rx_ring->cur_rx_idx; rx_swcx = rx_ring->rx_swcx + rx_ring->cur_rx_idx; @@ -278,7 +263,11 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, osd_receive_packet(osi->osd, rx_ring, chan, osi->rx_buf_len, rx_pkt_cx, rx_swcx); } - + osi->dstats.q_rx_pkt_n[chan] = + osi_update_stats_counter(osi->dstats.q_rx_pkt_n[chan], + 1UL); + osi->dstats.rx_pkt_n = + osi_update_stats_counter(osi->dstats.rx_pkt_n, 1UL); received++; } @@ -454,8 +443,11 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi, unsigned long long ns; int processed = 0; + osi->dstats.tx_clean_n[chan] = + osi_update_stats_counter(osi->dstats.tx_clean_n[chan], 1U); + while (entry != tx_ring->cur_tx_idx) { - osi_memset(txdone_pkt_cx, 0, sizeof(*txdone_pkt_cx)); + osi_memset(txdone_pkt_cx, 0U, sizeof(*txdone_pkt_cx)); tx_desc = tx_ring->tx_desc + entry; tx_swcx = tx_ring->tx_swcx + entry; @@ -516,6 +508,11 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi, * wake the corresponding transmit queue in OS layer. */ tx_ring->clean_idx = entry; + osi->dstats.q_tx_pkt_n[chan] = + osi_update_stats_counter(osi->dstats.q_tx_pkt_n[chan], + 1UL); + osi->dstats.tx_pkt_n = + osi_update_stats_counter(osi->dstats.tx_pkt_n, 1UL); } return processed; @@ -669,6 +666,17 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan) int cntx_desc_consumed; /* Context decriptor for VLAN/TSO */ + if ((tx_pkt_cx->flags & OSI_PKT_CX_VLAN) == OSI_PKT_CX_VLAN) { + osi->dstats.tx_vlan_pkt_n = + osi_update_stats_counter(osi->dstats.tx_vlan_pkt_n, + 1UL); + } + + if ((tx_pkt_cx->flags & OSI_PKT_CX_TSO) == OSI_PKT_CX_TSO) { + osi->dstats.tx_tso_pkt_n = + osi_update_stats_counter(osi->dstats.tx_tso_pkt_n, 1UL); + } + cntx_desc_consumed = need_cntx_desc(tx_pkt_cx, tx_desc); if (cntx_desc_consumed == 1) { INCR_TX_DESC_INDEX(entry, 1U); From e5ed68368d919ee7377c1ff214d112c0ca992e0b Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Mon, 10 Jun 2019 00:48:55 +0530 Subject: [PATCH 023/458] nvethernetrm: add L2/L3/L4 filter based dma routing code With this feature filtered Rx packet will be redirect to corresponding DMA channel based on register configuration. Function driver code need to pass 2 extra parameters enable/disable and dma channel number within the valid range to utilize this functionality. For L2 filtering, function driver code can also pass address mask and src_dest for filter index 1-31. Bug 200525721 Change-Id: Ibf3fb93cdd4c3b7c0384a0e36e7bbe467bb41e04 Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2133197 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: Sachin Nikam <snikam@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_common.h | 4 + include/osi_core.h | 70 ++++++++++---- osi/core/eqos_core.c | 221 +++++++++++++++++++++++++++++++++++-------- osi/core/eqos_core.h | 44 ++++++++- osi/core/osi_core.c | 32 +++++-- 5 files changed, 300 insertions(+), 71 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index 7b30d89..d9d8b6f 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -91,12 +91,16 @@ #define OSI_NULL ((void *)0) #define OSI_ENABLE 1U #define OSI_DISABLE 0U +#define OSI_AMASK_DISABLE 0U #define OSI_HASH_FILTER_MODE 1U #define OSI_PERFECT_FILTER_MODE 0U #define OSI_IPV6_MATCH 1U #define OSI_SOURCE_MATCH 0U +#define OSI_SA_MATCH 1U +#define OSI_DA_MATCH 0U + #define OSI_L4_FILTER_TCP 0U #define OSI_L4_FILTER_UDP 1U diff --git a/include/osi_core.h b/include/osi_core.h index 6066f13..ffa875c 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -189,7 +189,11 @@ struct osi_core_ops { int (*update_mac_addr_low_high_reg)( struct osi_core_priv_data *osi_core, unsigned int index, - unsigned char value[]); + unsigned char value[], + unsigned int dma_routing_enable, + unsigned int dma_chan, + unsigned int addr_mask, + unsigned int src_dest); int (*config_l3_l4_filter_enable)(void *base, unsigned int enable); int (*config_l2_da_perfect_inverse_match)(void *base, unsigned int perfect_inverse_match); @@ -197,7 +201,9 @@ struct osi_core_ops { 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 perfect_inverse_match, + unsigned int dma_routing_enable, + unsigned int dma_chan); int (*update_ip4_addr)(struct osi_core_priv_data *osi_core, unsigned int filter_no, unsigned char addr[], unsigned int src_dst_addr_match); @@ -207,7 +213,9 @@ struct osi_core_ops { 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 perfect_inverse_match, + unsigned int dma_routing_enable, + unsigned int dma_chan); int (*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); @@ -285,6 +293,7 @@ struct osi_ptp_config { * @default_addend: Default addend value. * @mmc: mmc counter structure * @xstats: xtra sw error counters + * @dcs_en: DMA channel selection enable (1) */ struct osi_core_priv_data { void *base; @@ -305,6 +314,7 @@ struct osi_core_priv_data { unsigned int default_addend; struct osi_mmc_counters mmc; struct osi_xtra_stat_counters xstats; + unsigned int dcs_en; }; /** @@ -644,9 +654,21 @@ int osi_config_mac_pkt_filter_reg(struct osi_core_priv_data *osi_core, * * @osi_core: OSI private data structure. * @index: filter index - * @value: address to write + * @value: MAC address to write + * @dma_routing_enable: dma channel routing enable(1) + * @dma_chan: dma channel number + * @addr_mask: filter will not consider byte in comparison + * Bit 29: MAC_Address${i}_High[15:8] + * Bit 28: MAC_Address${i}_High[7:0] + * Bit 27: MAC_Address${i}_Low[31:24] + * .. + * Bit 24: MAC_Address${i}_Low[7:0] + * @src_dest: SA(1) or DA(0) * - * Algorithm: this routine update MAC address to 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. * * Dependencies: MAC IP should be out of reset * and need to be initialized as the requirements @@ -657,7 +679,11 @@ int osi_config_mac_pkt_filter_reg(struct osi_core_priv_data *osi_core, */ int osi_update_mac_addr_low_high_reg(struct osi_core_priv_data *osi_core, unsigned int index, - unsigned char value[]); + unsigned char value[], + unsigned int dma_routing_enable, + unsigned int dma_chan, + unsigned int addr_mask, + unsigned int src_dest); /** * osi_config_l3_l4_filter_enable - invoke OSI call to eanble L3/L4 @@ -683,16 +709,22 @@ int osi_config_l3_l4_filter_enable(struct osi_core_priv_data *osi_core, * * @osi_core: OSI private data structure. * @filter_no: filter index - * @enb_dis: enable/disable L3 filter - * @ipv4_ipv6_match: 1 - IPv6, 0 - IPv4 - * @src_dst_addr_match: ip address matching enable/disable + * @enb_dis: 1 - enable otherwise - disable L3 filter + * @ipv4_ipv6_match: 1 - IPv6, otherwise - IPv4 + * @src_dst_addr_match: 0 - source, otherwise - destination * @perfect_inverse_match: normal match(0) or inverse map(1) + * @dma_routing_enable: filter based dma routing enable(1) + * @dma_chan: dma channel for routing based on filter * - * Algorithm: This sequence is used to configure L3((IPv4/IPv6) filters for - * address matching. + * 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. * - * Dependencies: MAC IP should be out of reset - * and need to be initialized as the requirements + * Dependencies: + * 1) MAC IP should be out of reset and need to be initialized + * as the requirements + * 2) DCS bits should be enabled in RXQ to DMA map register * * Protection: None * @@ -703,7 +735,9 @@ int osi_config_l3_filters(struct osi_core_priv_data *osi_core, unsigned int enb_dis, unsigned int ipv4_ipv6_match, unsigned int src_dst_addr_match, - unsigned int perfect_inverse_match); + unsigned int perfect_inverse_match, + unsigned int dma_routing_enable, + unsigned int dma_chan); /** * osi_update_ip4_addr - invoke OSI call update_ip4_addr. @@ -756,6 +790,8 @@ int osi_update_ip6_addr(struct osi_core_priv_data *osi_core, * @tcp_udp_match: 1 - udp, 0 - tcp * @src_dst_port_match: port matching enable/disable * @perfect_inverse_match: normal match(0) or inverse map(1) + * @dma_routing_enable: filter based dma routing enable(1) + * @dma_chan: dma channel for routing based on filter * * Algorithm: This sequence is used to configure L4(TCP/UDP) filters for * SA and DA Port Number matching @@ -772,7 +808,9 @@ int osi_config_l4_filters(struct osi_core_priv_data *osi_core, unsigned int enb_dis, unsigned int tcp_udp_match, unsigned int src_dst_port_match, - unsigned int perfect_inverse_match); + unsigned int perfect_inverse_match, + unsigned int dma_routing_enable, + unsigned int dma_chan); /** * osi_update_l4_port_no - invoke OSI call for @@ -904,7 +942,7 @@ int osi_write_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, int osi_read_mmc(struct osi_core_priv_data *osi_core); /** - * osi_reset_mmc - invoke function to rest MMC counter and data structure + * osi_reset_mmc - invoke function to reset MMC counter and data structure * * @osi_core: OSI core private data structure. * diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 90d38d7..45900ef 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -871,13 +871,17 @@ static int eqos_config_rxcsum_offload(void *addr, unsigned int enabled) } /** - * eqos_configure_rxq_priority - Configure RxQ priority + * eqos_configure_rxq_priority - Configure Priorities Selected in + * the Receive Queue + * * @osi_core: OSI private data structure. * - * Algorithm: This takes care of configuring the RxQ priority - * based on the User priority field of the received packets.we - * Don't have any fix mapping between RXQ and channel. We also don't - * control MTL queue enable/disable in current SW. + * 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. * * Dependencies: MAC has to be out of reset. * @@ -890,21 +894,32 @@ static void eqos_configure_rxq_priority(struct osi_core_priv_data *osi_core) unsigned int qinx; unsigned int val; unsigned int temp; - /* to avoid Misra-C error */ - unsigned int mybit = 0x1U; + unsigned int pmask = 0x0U; unsigned int mfix_var1, mfix_var2; + if (osi_core->dcs_en == OSI_ENABLE) { + osd_err(osi_core->osd, + "Invalid combination of DCS and RxQ-UP mapping, exiting %s()\n", + __func__); + return; + } + /* make sure EQOS_MAC_RQC2R is reset before programming */ + osi_writel(OSI_DISABLE, (unsigned char *)osi_core->base + + EQOS_MAC_RQC2R); + for (qinx = 0; qinx < OSI_EQOS_MAX_NUM_CHANS; qinx++) { - /* check for invalid priority which is set when either rxq_prio - * not defined or duplicate priority given - */ - if (osi_core->rxq_prio[qinx] != 0xFFU) { - temp = (mybit << osi_core->rxq_prio[qinx]); + /* check for PSRQ field mutual exclusive for all queues */ + if ((osi_core->rxq_prio[qinx] <= 0xFFU) && + (osi_core->rxq_prio[qinx] > 0x0U) && + ((pmask & osi_core->rxq_prio[qinx]) == 0U)) { + pmask |= osi_core->rxq_prio[qinx]; + temp = osi_core->rxq_prio[qinx]; } else { osd_err(osi_core->osd, "Invalid rxq Priority for Q(%d)\n", qinx); continue; + } val = osi_readl((unsigned char *)osi_core->base + @@ -1119,7 +1134,12 @@ static int eqos_core_init(struct osi_core_priv_data *osi_core, /* TODO: Need to add EQOS_MTL_RXQ_DMA_MAP1 for EQOS */ value = osi_readl((unsigned char *)osi_core->base + EQOS_MTL_RXQ_DMA_MAP0); - value |= EQOS_RXQ_TO_DMA_CHAN_MAP; + if (osi_core->dcs_en == OSI_ENABLE) { + value |= EQOS_RXQ_TO_DMA_CHAN_MAP_DCS_EN; + } else { + value |= EQOS_RXQ_TO_DMA_CHAN_MAP; + } + osi_writel(value, (unsigned char *)osi_core->base + EQOS_MTL_RXQ_DMA_MAP0); @@ -1513,8 +1533,20 @@ static void eqos_config_mac_pkt_filter_reg(struct osi_core_priv_data *osi_core, * @osi_core: OSI private data structure. * @index: filter index * @value: MAC address to write + * @dma_routing_enable: dma channel routing enable(1) + * @dma_chan: dma channel number + * @addr_mask: filter will not consider byte in comparison + * Bit 29: MAC_Address${i}_High[15:8] + * Bit 28: MAC_Address${i}_High[7:0] + * Bit 27: MAC_Address${i}_Low[31:24] + * .. + * Bit 24: MAC_Address${i}_Low[7:0] + * @src_dest: SA(1) or DA(0) * - * Algorithm: this routine update MAC address to 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. * * Dependencies: MAC IP should be out of reset * and need to be initialized as the requirements @@ -1525,22 +1557,58 @@ static void eqos_config_mac_pkt_filter_reg(struct osi_core_priv_data *osi_core, */ static int eqos_update_mac_addr_low_high_reg( struct osi_core_priv_data *osi_core, - unsigned int idx, unsigned char addr[]) + unsigned int idx, unsigned char addr[], + unsigned int dma_routing_enable, + unsigned int dma_chan, + unsigned int addr_mask, unsigned int src_dest) { + unsigned int value = 0x0U; + if (idx > EQOS_MAX_MAC_ADDRESS_FILTER) { osd_err(osi_core->osd, "invalid MAC filter index\n"); return -1; } + /* High address clean should happen for filter index > 0 */ if (idx >= 0x1U && addr == OSI_NULL) { osi_writel((unsigned int)0x0, (unsigned char *)osi_core->base + EQOS_MAC_ADDRH((idx))); return 0; } - osi_writel(((unsigned int)addr[4] | ((unsigned int)addr[5] << 8) | - OSI_BIT(31)), (unsigned char *)osi_core->base + - EQOS_MAC_ADDRH((idx))); + /* PDC bit of MAC_Ext_Configuration register is not set so binary + * value representation. + */ + if ((dma_routing_enable == OSI_ENABLE) && + (dma_chan < OSI_EQOS_MAX_NUM_CHANS) && + (osi_core->dcs_en == OSI_ENABLE)) { + value = ((dma_chan << EQOS_MAC_ADDRH_DCS_SHIFT) & + EQOS_MAC_ADDRH_DCS); + } else if ((dma_routing_enable == OSI_ENABLE) && + (dma_chan < OSI_EQOS_MAX_NUM_CHANS) && + (osi_core->dcs_en != OSI_ENABLE)) { + osd_err(osi_core->osd, "DCS disabled, please update DT\n"); + } else { + /* Do nothing */ + } + + /* Address mask is valid for address 1 to 31 index only */ + if ((addr_mask <= 0x3FU && addr_mask > 0U) && (idx > 0U && idx < 32U)) { + value = (value | ((addr_mask << EQOS_MAC_ADDRH_MBC_SHIFT) & + EQOS_MAC_ADDRH_MBC)); + } + + /* Setting Source/Destination Address match valid for 1 to 32 index */ + if ((idx > 0U && idx < 32U) && (src_dest == OSI_SA_MATCH || + src_dest == OSI_DA_MATCH)) { + value = (value | ((src_dest << EQOS_MAC_ADDRH_SA_SHIFT) & + EQOS_MAC_ADDRH_SA)); + } + + osi_writel(((unsigned int)addr[4] | + ((unsigned int)addr[5] << 8) | OSI_BIT(31) | value), + (unsigned char *)osi_core->base + EQOS_MAC_ADDRH((idx))); + osi_writel(((unsigned int)addr[0] | ((unsigned int)addr[1] << 8) | ((unsigned int)addr[2] << 16) | ((unsigned int)addr[3] << 24)), @@ -1870,8 +1938,10 @@ static int eqos_update_ip6_addr(struct osi_core_priv_data *osi_core, * Algorithm: sequence is used to update Source Port Number for * L4(TCP/UDP) layer filtering. * - * Dependencies: MAC IP should be out of reset - * and need to be initialized as the requirements + * Dependencies: + * 1) MAC IP should be out of reset and need to be initialized + * as the requirements + * 2) DCS bits should be enabled in RXQ to DMA mapping register * * Protection: None * @@ -1906,6 +1976,51 @@ static int eqos_update_l4_port_no(struct osi_core_priv_data *osi_core, return 0; } +/** + * eqos_set_dcs - check and update dma routing register + * + * @osi_core: OSI private data structure. + * @value: unsigned int value for caller + * @dma_routing_enable: filter based dma routing enable(1) + * @dma_chan: dma channel for routing based on filter + * + * 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. + * + * Dependencies: + * 1) MAC IP should be out of reset and need to be initialized + * as the requirements. + * 2) DCS bits should be enabled in RXQ to DMA mapping register + * + * Protection: None + * + * Return: updated unsigned int value + */ +static inline unsigned int eqos_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_EQOS_MAX_NUM_CHANS) && (osi_core->dcs_en == + OSI_ENABLE)) { + value |= ((dma_routing_enable << + EQOS_MAC_L3L4_CTR_DMCHEN0_SHIFT) & + EQOS_MAC_L3L4_CTR_DMCHEN0); + value |= ((dma_chan << + EQOS_MAC_L3L4_CTR_DMCHN0_SHIFT) & + EQOS_MAC_L3L4_CTR_DMCHN0); + } else if ((dma_routing_enable == OSI_ENABLE) && (dma_chan < + OSI_EQOS_MAX_NUM_CHANS) && (osi_core->dcs_en != + OSI_ENABLE)) { + osd_err(osi_core->osd, "DCS disabled, please update DT\n"); + } else { + /* do noting */ + } + + return value; +} /** * eqos_config_l3_filters - config L3 filters. * @@ -1915,12 +2030,18 @@ static int eqos_update_l4_port_no(struct osi_core_priv_data *osi_core, * @ipv4_ipv6_match: 1 - IPv6, otherwise - IPv4 * @src_dst_addr_match: 0 - source, otherwise - destination * @perfect_inverse_match: normal match(0) or inverse map(1) + * @dma_routing_enable: filter based dma routing enable(1) + * @dma_chan: dma channel for routing based on filter * - * Algorithm: This sequence is used to configure L3((IPv4/IPv6) filters for - * address matching. + * 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. * - * Dependencies: MAC IP should be out of reset - * and need to be initialized as the requirements + * Dependencies: + * 1) MAC IP should be out of reset and need to be initialized + * as the requirements + * 2) DCS bits should be enabled in RXQ to DMA map register * * Protection: None * @@ -1931,7 +2052,9 @@ static int eqos_config_l3_filters(struct osi_core_priv_data *osi_core, unsigned int enb_dis, unsigned int ipv4_ipv6_match, unsigned int src_dst_addr_match, - unsigned int perfect_inverse_match) + unsigned int perfect_inverse_match, + unsigned int dma_routing_enable, + unsigned int dma_chan) { unsigned int value = 0U; void *base = osi_core->base; @@ -1964,6 +2087,9 @@ static int eqos_config_l3_filters(struct osi_core_priv_data *osi_core, 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_writel(value, (unsigned char *)base + EQOS_MAC_L3L4_CTR(filter_no)); @@ -1979,6 +2105,9 @@ static int eqos_config_l3_filters(struct osi_core_priv_data *osi_core, 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_writel(value, (unsigned char *)base + EQOS_MAC_L3L4_CTR(filter_no)); } @@ -2001,13 +2130,15 @@ static int eqos_config_l3_filters(struct osi_core_priv_data *osi_core, */ value = osi_readl((unsigned char *)base + EQOS_MAC_L3L4_CTR(filter_no)); - value &= ~(EQOS_MAC_L3L4_CTR_L3SAM0 | - EQOS_MAC_L3L4_CTR_L3SAIM0); + 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_writel(value, (unsigned char *)base + EQOS_MAC_L3L4_CTR(filter_no)); } else { @@ -2016,8 +2147,7 @@ static int eqos_config_l3_filters(struct osi_core_priv_data *osi_core, */ value = osi_readl((unsigned char *)base + EQOS_MAC_L3L4_CTR(filter_no)); - value &= ~(EQOS_MAC_L3L4_CTR_L3SAM0 | - EQOS_MAC_L3L4_CTR_L3SAIM0); + value &= ~EQOS_MAC_L3_IP4_SA_CTRL_CLEAR; osi_writel(value, (unsigned char *)base + EQOS_MAC_L3L4_CTR(filter_no)); } @@ -2028,13 +2158,15 @@ static int eqos_config_l3_filters(struct osi_core_priv_data *osi_core, */ value = osi_readl((unsigned char *)base + EQOS_MAC_L3L4_CTR(filter_no)); - value &= ~(EQOS_MAC_L3L4_CTR_L3DAM0 | - EQOS_MAC_L3L4_CTR_L3DAIM0); + 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_writel(value, (unsigned char *)base + EQOS_MAC_L3L4_CTR(filter_no)); } else { @@ -2043,8 +2175,7 @@ static int eqos_config_l3_filters(struct osi_core_priv_data *osi_core, */ value = osi_readl((unsigned char *)base + EQOS_MAC_L3L4_CTR(filter_no)); - value &= ~(EQOS_MAC_L3L4_CTR_L3DAM0 | - EQOS_MAC_L3L4_CTR_L3DAIM0); + value &= ~EQOS_MAC_L3_IP4_DA_CTRL_CLEAR; osi_writel(value, (unsigned char *)base + EQOS_MAC_L3L4_CTR(filter_no)); } @@ -2063,6 +2194,8 @@ static int eqos_config_l3_filters(struct osi_core_priv_data *osi_core, * @tcp_udp_match: 1 - udp, 0 - tcp * @src_dst_port_match: 0 - source port, otherwise - dest port * @perfect_inverse_match: normal match(0) or inverse map(1) + * @dma_routing_enable: filter based dma routing enable(1) + * @dma_chan: dma channel for routing based on filter * * Algorithm: This sequence is used to configure L4(TCP/UDP) filters for * SA and DA Port Number matching @@ -2079,7 +2212,9 @@ static int eqos_config_l4_filters(struct osi_core_priv_data *osi_core, unsigned int enb_dis, unsigned int tcp_udp_match, unsigned int src_dst_port_match, - unsigned int perfect_inverse_match) + unsigned int perfect_inverse_match, + unsigned int dma_routing_enable, + unsigned int dma_chan) { void *base = osi_core->base; unsigned int value = 0U; @@ -2101,21 +2236,22 @@ static int eqos_config_l4_filters(struct osi_core_priv_data *osi_core, /* Enable L4 filters for SOURCE Port No matching */ value = osi_readl((unsigned char *)base + EQOS_MAC_L3L4_CTR(filter_no)); - value &= ~(EQOS_MAC_L3L4_CTR_L4SPM0 | - EQOS_MAC_L3L4_CTR_L4SPIM0); + 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_writel(value, (unsigned char *)base + EQOS_MAC_L3L4_CTR(filter_no)); } else { /* Disable L4 filters for SOURCE Port No matching */ value = osi_readl((unsigned char *)base + EQOS_MAC_L3L4_CTR(filter_no)); - value &= ~(EQOS_MAC_L3L4_CTR_L4SPM0 | - EQOS_MAC_L3L4_CTR_L4SPIM0); + value &= ~EQOS_MAC_L4_SP_CTRL_CLEAR; osi_writel(value, (unsigned char *)base + EQOS_MAC_L3L4_CTR(filter_no)); } @@ -2126,13 +2262,15 @@ static int eqos_config_l4_filters(struct osi_core_priv_data *osi_core, */ value = osi_readl((unsigned char *)base + EQOS_MAC_L3L4_CTR(filter_no)); - value &= ~(EQOS_MAC_L3L4_CTR_L4DPM0 | - EQOS_MAC_L3L4_CTR_L4DPIM0); + 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_writel(value, (unsigned char *)base + EQOS_MAC_L3L4_CTR(filter_no)); } else { @@ -2141,8 +2279,7 @@ static int eqos_config_l4_filters(struct osi_core_priv_data *osi_core, */ value = osi_readl((unsigned char *)base + EQOS_MAC_L3L4_CTR(filter_no)); - value &= ~(EQOS_MAC_L3L4_CTR_L4DPM0 | - EQOS_MAC_L3L4_CTR_L4DPIM0); + value &= ~EQOS_MAC_L4_DP_CTRL_CLEAR; osi_writel(value, (unsigned char *)base + EQOS_MAC_L3L4_CTR(filter_no)); } diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index f5e9483..07e2ffa 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -95,7 +95,9 @@ #define EQOS_MAC_PMTCSR 0x00C0 #define EQOS_MAC_PCS 0x00F8 #define EQOS_MAC_ANS 0x00E4 +/* 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_MAP_DCS_EN 0x13121110U #define EQOS_MAC_EXTR 0x0004 #define EQOS_MAC_RX_FLW_CTRL 0x0090 #define EQOS_MAC_QX_TX_FLW_CTRL(x) ((0x0004U * (x)) + 0x0070U) @@ -262,15 +264,47 @@ #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_L3_IP6_CTRL_CLEAR (EQOS_MAC_L3L4_CTR_L3SAM0 | \ +#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_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_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_MAC_ADDRH_SA OSI_BIT(30) +#define EQOS_MAC_ADDRH_SA_SHIFT 30 #define EQOS_MAC_VLAN_TR 0x0050U #define EQOS_MAC_VLAN_TFR 0x0054U #define EQOS_MAC_VLAN_HTR 0x0058U diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index b2b3065..b1babe2 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -418,16 +418,24 @@ int osi_config_mac_pkt_filter_reg(struct osi_core_priv_data *osi_core, } int osi_update_mac_addr_low_high_reg(struct osi_core_priv_data *osi_core, - unsigned int index, unsigned char value[]) + unsigned int index, unsigned char value[], + unsigned int dma_routing_enable, + unsigned int dma_chan, + unsigned int addr_mask, + unsigned int src_dest) { int ret = -1; if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->update_mac_addr_low_high_reg != OSI_NULL)) { ret = osi_core->ops->update_mac_addr_low_high_reg( - osi_core, - index, - value); + osi_core, + index, + value, + dma_routing_enable, + dma_chan, + addr_mask, + src_dest); } return ret; @@ -452,7 +460,9 @@ int osi_config_l3_filters(struct osi_core_priv_data *osi_core, unsigned int enb_dis, unsigned int ipv4_ipv6_match, unsigned int src_dst_addr_match, - unsigned int perfect_inverse_match) + unsigned int perfect_inverse_match, + unsigned int dma_routing_enable, + unsigned int dma_chan) { int ret = -1; @@ -461,7 +471,9 @@ int osi_config_l3_filters(struct osi_core_priv_data *osi_core, ret = osi_core->ops->config_l3_filters(osi_core, filter_no, enb_dis, ipv4_ipv6_match, src_dst_addr_match, - perfect_inverse_match); + perfect_inverse_match, + dma_routing_enable, + dma_chan); } return ret; @@ -501,7 +513,9 @@ int osi_config_l4_filters(struct osi_core_priv_data *osi_core, unsigned int enb_dis, unsigned int tcp_udp_match, unsigned int src_dst_port_match, - unsigned int perfect_inverse_match) + unsigned int perfect_inverse_match, + unsigned int dma_routing_enable, + unsigned int dma_chan) { int ret = -1; @@ -510,7 +524,9 @@ int osi_config_l4_filters(struct osi_core_priv_data *osi_core, ret = osi_core->ops->config_l4_filters(osi_core, filter_no, enb_dis, tcp_udp_match, src_dst_port_match, - perfect_inverse_match); + perfect_inverse_match, + dma_routing_enable, + dma_chan); } return ret; From 54814d6b21280f9e87842dc1a2bc4b153cebe042 Mon Sep 17 00:00:00 2001 From: Srinivas Ramachandran <srinivasra@nvidia.com> Date: Tue, 18 Jun 2019 15:16:36 -0700 Subject: [PATCH 024/458] nvethernetrm: Use inline function to poll for MII idle Issue: PHY register read/write operation through MDIO needs to wait for MII idle before placing next read/write request. This polling logic is replicated in multiple places. Fix: Move polling logic as an inline function so that it can be reused where needed. Bug 200512422 Change-Id: Id202f01a13a6296e4fe98361c657767ee09201ea Signed-off-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2138396 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/osi_core.c | 88 +++++++++++++++++---------------------------- 1 file changed, 32 insertions(+), 56 deletions(-) diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index b1babe2..b34b82e 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -37,32 +37,47 @@ extern struct osi_core_ops *eqos_get_hw_core_ops(void); -int osi_write_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, - unsigned int phyreg, unsigned short phydata) +static inline int poll_for_mii_idle(struct osi_core_priv_data *osi_core) { unsigned int retry = 1000; - unsigned int count; unsigned int mac_gmiiar; - unsigned int mac_gmiidr; + unsigned int count; int cond = 1; - /* wait for any previous MII read/write operation to complete */ count = 0; while (cond == 1) { if (count > retry) { + osd_err(osi_core->osd, "MII operation timed out\n"); return -1; } count++; osd_msleep(1U); - mac_gmiiar = osi_readl((unsigned char *)osi_core->base + MAC_MDIO_ADDRESS); + mac_gmiiar = osi_readl((unsigned char *)osi_core->base + + MAC_MDIO_ADDRESS); if ((mac_gmiiar & MAC_GMII_BUSY) == 0U) { cond = 0; } } + return 0; +} + +int osi_write_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, + unsigned int phyreg, unsigned short phydata) +{ + unsigned int mac_gmiiar; + unsigned int mac_gmiidr; + int ret = 0; + + /* wait for any previous MII read/write operation to complete */ + ret = poll_for_mii_idle(osi_core); + if (ret < 0) { + return ret; + } + mac_gmiidr = osi_readl((unsigned char *)osi_core->base + MAC_MDIO_DATA); mac_gmiidr = ((mac_gmiidr & MAC_GMIIDR_GD_WR_MASK) | @@ -88,52 +103,26 @@ int osi_write_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, osd_usleep_range(9, 11); /* wait for MII write operation to complete */ - cond = 1; - count = 0; - while (cond == 1) { - if (count > retry) { - return -1; - } - - count++; - osd_msleep(1U); - - mac_gmiiar = osi_readl((unsigned char *)osi_core->base + MAC_MDIO_ADDRESS); - - if ((mac_gmiiar & MAC_GMII_BUSY) == 0U) { - cond = 0; - } + ret = poll_for_mii_idle(osi_core); + if (ret < 0) { + return ret; } - return 0; + return ret; } int osi_read_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, unsigned int phyreg) { - unsigned int retry = 1000; - unsigned int count; unsigned int mac_gmiiar; unsigned int mac_gmiidr; unsigned int data; - int cond = 1; + int ret = 0; /* wait for any previous MII read/write operation to complete */ - /*Poll Until Poll Condition */ - count = 0; - while (cond == 1) { - if (count > retry) { - return -1; - } - - count++; - osd_msleep(1U); - - mac_gmiiar = osi_readl((unsigned char *)osi_core->base + MAC_MDIO_ADDRESS); - - if ((mac_gmiiar & MAC_GMII_BUSY) == 0U) { - cond = 0; - } + ret = poll_for_mii_idle(osi_core); + if (ret < 0) { + return ret; } mac_gmiiar = osi_readl((unsigned char *)osi_core->base + MAC_MDIO_ADDRESS); @@ -152,22 +141,9 @@ int osi_read_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, osd_usleep_range(9, 11); /* wait for MII write operation to complete */ - /*Poll Until Poll Condition */ - cond = 1; - count = 0; - while (cond == 1) { - if (count > retry) { - return -1; - } - - count++; - osd_msleep(1U); - - mac_gmiiar = osi_readl((unsigned char *)osi_core->base + MAC_MDIO_ADDRESS); - - if ((mac_gmiiar & MAC_GMII_BUSY) == 0U) { - cond = 0; - } + ret = poll_for_mii_idle(osi_core); + if (ret < 0) { + return ret; } mac_gmiidr = osi_readl((unsigned char *)osi_core->base + MAC_MDIO_DATA); From 8c25c188bcd7a1f50d241aa0e53e324c32ada58e Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Tue, 18 Jun 2019 18:34:12 +0530 Subject: [PATCH 025/458] nvethernetrm: add support for RIWT This support enables the configuration of Receive Interrupt Watchdog Timer register which indicates the watchdog timeout for Receive Interrupt (RI) from the DMA. Bug 200512422 Bug 2624476 Change-Id: I66830a47c34845af06e318ba6069935d51d15af8 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2138153 Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_common.h | 3 +++ include/osi_dma.h | 8 +++++++- osi/dma/eqos_dma.c | 22 ++++++++++++++++++++++ osi/dma/eqos_dma.h | 2 ++ osi/dma/osi_dma.c | 8 +++++++- osi/dma/osi_dma_txrx.c | 5 ++++- 6 files changed, 45 insertions(+), 3 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index d9d8b6f..5f9d46a 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -31,6 +31,9 @@ /* System clock is 62.5MHz */ #define OSI_ETHER_SYSCLOCK 62500000ULL +#define OSI_ONE_MEGA_HZ 1000000U +#define OSI_MAX_RX_COALESCE_USEC 1020U +#define OSI_MIN_RX_COALESCE_USEC 3U #define OSI_PAUSE_FRAMES_ENABLE 0U #define OSI_PAUSE_FRAMES_DISABLE 1U diff --git a/include/osi_dma.h b/include/osi_dma.h index b3b4a4a..cd0e9b2 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -277,6 +277,8 @@ struct osi_dma_chan_ops { * @mtu: MTU size * @pkt_err_stats: Packet error stats * @dstats: Extra DMA stats + * @rx_riwt: Receive Interrupt Watchdog Timer Count Units + * @use_riwt: Flag which decides riwt is enabled(1) or disabled(0) */ struct osi_dma_priv_data { struct osi_tx_ring *tx_ring[OSI_EQOS_MAX_NUM_CHANS]; @@ -291,6 +293,8 @@ struct osi_dma_priv_data { unsigned int mtu; struct osi_pkt_err_stats pkt_err_stats; struct osi_xtra_dma_stat_counters dstats; + unsigned int rx_riwt; + unsigned int use_riwt; }; /** @@ -434,6 +438,7 @@ unsigned int osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring); * osi_rx_dma_desc_init - DMA Rx descriptor init * @rx_swcx: OSI DMA Rx ring software context * @rx_desc: OSI DMA Rx ring descriptor + * @use_riwt: to enable Rx WDT and disable IOC * * Algorithm: Initialise a Rx DMA descriptor. * @@ -444,7 +449,8 @@ unsigned int osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring); * Return: None. */ void osi_rx_dma_desc_init(struct osi_rx_swcx *rx_swcx, - struct osi_rx_desc *rx_desc); + struct osi_rx_desc *rx_desc, + unsigned int use_riwt); /** * osi_update_rx_tailptr - Updates DMA Rx ring tail pointer diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index 1968eb0..2773844 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -385,6 +385,28 @@ static void eqos_configure_dma_channel(unsigned int chan, /* RXPBL = 12 */ value |= EQOS_DMA_CHX_RX_CTRL_RXPBL_RECOMMENDED; osi_writel(value, (unsigned char *)osi_dma->base + EQOS_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 + */ + if (osi_dma->use_riwt == OSI_ENABLE && chan <= OSI_EQOS_MAX_NUM_CHANS && + osi_dma->rx_riwt < UINT_MAX) { + value = osi_readl((unsigned char *)osi_dma->base + + EQOS_DMA_CHX_RX_WDT(chan)); + /* Mask the RWT value */ + value &= ~EQOS_DMA_CHX_RX_WDT_RWT_MASK; + /* Conversion of usec to Rx Interrupt Watchdog Timer Count */ + value |= ((osi_dma->rx_riwt * + ((unsigned int)OSI_ETHER_SYSCLOCK / OSI_ONE_MEGA_HZ)) / + EQOS_DMA_CHX_RX_WDT_RWTU) & + EQOS_DMA_CHX_RX_WDT_RWT_MASK; + osi_writel(value, (unsigned char *)osi_dma->base + + EQOS_DMA_CHX_RX_WDT(chan)); + } } /** diff --git a/osi/dma/eqos_dma.h b/osi/dma/eqos_dma.h index aab8ce8..2c8f9d8 100644 --- a/osi/dma/eqos_dma.h +++ b/osi/dma/eqos_dma.h @@ -68,4 +68,6 @@ #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 256U #endif diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index f62de65..76a47a3 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -158,12 +158,18 @@ unsigned int osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring) } void osi_rx_dma_desc_init(struct osi_rx_swcx *rx_swcx, - struct osi_rx_desc *rx_desc) + struct osi_rx_desc *rx_desc, + unsigned int use_riwt) { rx_desc->rdes0 = (unsigned int)L32(rx_swcx->buf_phy_addr); rx_desc->rdes1 = (unsigned int)H32(rx_swcx->buf_phy_addr); rx_desc->rdes2 = 0; rx_desc->rdes3 = (RDES3_OWN | RDES3_IOC | RDES3_B1V); + + /* reset IOC bit if RWIT is enabled */ + if (use_riwt == OSI_ENABLE) { + rx_desc->rdes3 &= ~RDES3_IOC; + } } void osi_update_rx_tailptr(struct osi_dma_priv_data *osi_dma, diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 638626f..9c79304 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -770,8 +770,11 @@ static int rx_dma_desc_initialization(struct osi_dma_priv_data *osi, rx_desc->rdes0 = (unsigned int)L32(rx_swcx->buf_phy_addr); rx_desc->rdes1 = (unsigned int)H32(rx_swcx->buf_phy_addr); rx_desc->rdes2 = 0; - //TODO: RDES3_IOC needs to be reset for Rx watchdog rx_desc->rdes3 = (RDES3_OWN | RDES3_IOC | RDES3_B1V); + /* reconfigure INTE bit if RX watchdog timer is enabled */ + if (osi->use_riwt == OSI_ENABLE) { + rx_desc->rdes3 &= ~RDES3_IOC; + } } tailptr = rx_ring->rx_desc_phy_addr + From ebd573efff25710630792c69ac46fc4b4ef75579 Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Fri, 28 Jun 2019 15:58:59 +0530 Subject: [PATCH 026/458] nvethernetrm: add RxQ UP for enabled queue Issue: SW Set RxQ UP for all MTL queues (OSI_EQOS_MAX_NUM_QUEUES) Fix: set only for Rx queues which are enabled Bug 200512422 Change-Id: Ifb99288e0245c1876526a7195f17a87b610b9a1b Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2145184 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/eqos_core.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 45900ef..581eaa1 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -891,9 +891,9 @@ static int eqos_config_rxcsum_offload(void *addr, unsigned int enabled) */ static void eqos_configure_rxq_priority(struct osi_core_priv_data *osi_core) { - unsigned int qinx; unsigned int val; unsigned int temp; + unsigned int qinx, mtlq; unsigned int pmask = 0x0U; unsigned int mfix_var1, mfix_var2; @@ -907,29 +907,30 @@ static void eqos_configure_rxq_priority(struct osi_core_priv_data *osi_core) osi_writel(OSI_DISABLE, (unsigned char *)osi_core->base + EQOS_MAC_RQC2R); - for (qinx = 0; qinx < OSI_EQOS_MAX_NUM_CHANS; qinx++) { + 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[qinx] <= 0xFFU) && - (osi_core->rxq_prio[qinx] > 0x0U) && - ((pmask & osi_core->rxq_prio[qinx]) == 0U)) { - pmask |= osi_core->rxq_prio[qinx]; - temp = osi_core->rxq_prio[qinx]; + 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 { osd_err(osi_core->osd, "Invalid rxq Priority for Q(%d)\n", - qinx); + mtlq); continue; } val = osi_readl((unsigned char *)osi_core->base + EQOS_MAC_RQC2R); - mfix_var1 = qinx * (unsigned int)EQOS_MAC_RQC2_PSRQ_SHIFT; + mfix_var1 = mtlq * (unsigned int)EQOS_MAC_RQC2_PSRQ_SHIFT; mfix_var2 = (unsigned int)EQOS_MAC_RQC2_PSRQ_MASK; mfix_var2 <<= mfix_var1; val &= ~mfix_var2; - temp = temp << (qinx * EQOS_MAC_RQC2_PSRQ_SHIFT); - mfix_var1 = qinx * (unsigned int)EQOS_MAC_RQC2_PSRQ_SHIFT; + temp = temp << (mtlq * EQOS_MAC_RQC2_PSRQ_SHIFT); + mfix_var1 = mtlq * (unsigned int)EQOS_MAC_RQC2_PSRQ_SHIFT; mfix_var2 = (unsigned int)EQOS_MAC_RQC2_PSRQ_MASK; mfix_var2 <<= mfix_var1; val |= (temp & mfix_var2); From 6369a1fe20f6ba8c76e0255a7670e5fdb9935394 Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Wed, 5 Jun 2019 10:30:04 +0530 Subject: [PATCH 027/458] nvethernetrm: update dependencies in function header Update osi_core and osi_dma function header with dependency information for osd Bug 200512422 Change-Id: I9ea647c1728ef4d48d38ec7e0d381ec1ef88f3f7 Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2130747 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osd.h | 57 ++++++++ include/osi_core.h | 321 +++++++++++++++++++++++------------------ include/osi_dma.h | 258 +++++++++++++++++++++++++++++---- osi/core/eqos_core.c | 161 ++++++++++++++------- osi/core/eqos_mmc.c | 15 +- osi/dma/eqos_dma.c | 86 +++++++++-- osi/dma/osi_dma.c | 12 -- osi/dma/osi_dma_txrx.c | 36 ++++- 8 files changed, 689 insertions(+), 257 deletions(-) diff --git a/include/osd.h b/include/osd.h index 6096d2d..f216e5d 100644 --- a/include/osd.h +++ b/include/osd.h @@ -28,9 +28,66 @@ void osd_msleep(unsigned int msec); void osd_udelay(unsigned long usec); void osd_info(void *priv, const char *fmt, ...); void osd_err(void *priv, const char *fmt, ...); + +/** + * osd_receive_packet - Handover received packet to network stack. + * @priv: OSD private data structure. + * @rxring: Pointer to DMA channel Rx ring. + * @chan: DMA Rx channel number. + * @dma_buf_len: Rx DMA buffer length. + * @rxpkt_cx: Received packet context. + * @rx_pkt_swcx: Received packet sw context. + * + * Algorithm: + * 1) Unmap the DMA buffer address. + * 2) Updates socket buffer with len and ether type and handover to + * OS network stack. + * 3) Refill the Rx ring based on threshold. + * 4) Fills the rxpkt_cx->flags with the below bit fields accordingly + * OSI_PKT_CX_VLAN + * OSI_PKT_CX_VALID + * OSI_PKT_CX_CSUM + * OSI_PKT_CX_TSO + * OSI_PKT_CX_PTP + * + * Dependencies: Rx completion need to make sure that Rx descriptors + * processed properly. + * + * Protection: None. + * + * Return: None. + */ void osd_receive_packet(void *priv, void *rxring, unsigned int chan, unsigned int dma_buf_len, void *rxpkt_cx, void *rx_pkt_swcx); + +/** + * osd_transmit_complete - Transmit completion routine. + * @priv: OSD private data structure. + * @buffer: Buffer address to free. + * @dmaaddr: DMA address to unmap. + * @len: Length of data. + * @tx_done_pkt_cx: Pointer to struct which has tx done status info. + * This struct has flags to indicate tx error, whether DMA address + * is mapped from paged/linear buffer, Time stamp availability, + * if TS available txdone_pkt_cx->ns stores the time stamp. + * Below are the valid bit maps set for txdone_pkt_cx->flags + * #define OSI_TXDONE_CX_PAGED_BUF OSI_BIT(0) + * #define OSI_TXDONE_CX_ERROR OSI_BIT(1) + * #define OSI_TXDONE_CX_TS OSI_BIT(2) + * + * Algorithm: + * 1) Updates stats for linux network stack. + * 2) unmap and free the buffer DMA address and buffer. + * 3) Time stamp will be updated to stack if available. + * + * Dependencies: Tx completion need to make sure that Tx descriptors + * processed properly. + * + * Protection: None. + * + * Return: None. + */ void osd_transmit_complete(void *priv, void *buffer, unsigned long dmaaddr, unsigned int len, void *txdone_pkt_cx); #endif diff --git a/include/osi_core.h b/include/osi_core.h index ffa875c..ac0392a 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -324,7 +324,8 @@ struct osi_core_priv_data { * Algorithm: Invokes EQOS routine to check for SWR (software reset) * bit in DMA Basic mooe register to make sure IP reset was successful. * - * Dependencies: MAC needs to be reset with Soft or hardreset. + * Dependencies: + * 1) MAC needs to be out of reset and proper clock configured. * * Protection: None * @@ -334,139 +335,156 @@ struct osi_core_priv_data { int osi_poll_for_swr(struct osi_core_priv_data *osi_core); /** - * osi_set_mdc_clk_rate - Derive MDC clock based on provided AXI_CBB clk. - * @osi: OSI core private data structure. - * @csr_clk_rate: CSR (AXI CBB) clock rate. + * osi_set_mdc_clk_rate - Derive MDC clock based on provided AXI_CBB clk. + * @osi: OSI core private data structure. + * @csr_clk_rate: CSR (AXI CBB) clock rate. * - * Algorithm: MDC clock rate will be populated in OSI core private data + * Algorithm: MDC clock rate will be populated in OSI core private data * structure based on AXI_CBB clock rate. * - * Dependencies: OSD layer needs get the AXI CBB clock rate with OSD clock - * API (ex - clk_get_rate()) + * Dependencies: + * 1) OSD layer needs get the AXI CBB clock rate with OSD clock API + * (ex - clk_get_rate()) * - * Return: None + * Return: None */ void osi_set_mdc_clk_rate(struct osi_core_priv_data *osi_core, unsigned long csr_clk_rate); /** - * osi_hw_core_init - EQOS MAC, MTL and common DMA initialization. - * @osi: OSI core private data structure. + * osi_hw_core_init - EQOS MAC, MTL and common DMA initialization. + * @osi: OSI core private data structure. * - * Algorithm: Invokes EQOS MAC, MTL and common DMA register init code. + * Algorithm: Invokes EQOS MAC, MTL and common DMA register init code. * - * Dependencies: MAC has to be out of reset. + * Dependencies: + * 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. * - * Protection: None + * Protection: None * - * Return: 0 - success, -1 - failure + * Return: 0 - success, -1 - failure */ int osi_hw_core_init(struct osi_core_priv_data *osi_core, unsigned int tx_fifo_size, unsigned int rx_fifo_size); /** - * osi_start_mac - Start MAC Tx/Rx engine - * @osi_core: OSI core private data. + * osi_start_mac - Start MAC Tx/Rx engine + * @osi_core: OSI core private data. * - * Algorimthm: Enable MAC Tx and Rx engine. - * Dependencies: None - * Protection: None - * Return: None + * Algorimthm: Enable MAC Tx and Rx engine. + * + * Dependencies: + * 1) MAC init should be complete. See osi_hw_core_init() and + * osi_hw_dma_init() + * + * Protection: None + * + * Return: None */ void osi_start_mac(struct osi_core_priv_data *osi_core); /** - * osi_stop_mac - Stop MAC Tx/Rx engine - * @osi_core: OSI core private data. + * osi_stop_mac - Stop MAC Tx/Rx engine + * @osi_core: OSI core private data. * - * Algorimthm: Stop MAC Tx and Rx engine - * Dependencies: None - * Protection: None - * Return: None + * Algorimthm: Stop MAC Tx and Rx engine + * + * Dependencies: + * 1) MAC DMA deinit should be complete. See osi_hw_dma_deinit() + * + * Protection: None + * + * Return: None */ void osi_stop_mac(struct osi_core_priv_data *osi_core); /** - * osi_common_isr - Common ISR. - * @osi_core: OSI core private data structure. + * osi_common_isr - Common ISR. + * @osi_core: OSI core private data structure. * - * Algorithm: Takes care of handling the - * common interrupts accordingly as per the - * MAC IP + * Algorithm: Takes care of handling the + * common interrupts accordingly as per the + * MAC IP * - * Dependencies: MAC IP should be out of reset - * and need to be initialized as the requirements + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() * - * Protection: None + * Protection: None * - * Return: 0 - success, -1 - failure + * Return: 0 - success, -1 - failure */ void osi_common_isr(struct osi_core_priv_data *osi_core); /** - * osi_set_mode - Set FD/HD mode. - * @osi: OSI private data structure. - * @mode: Operating mode. + * osi_set_mode - Set FD/HD mode. + * @osi: OSI private data structure. + * @mode: Operating mode. * - * Algorithm: Takes care of setting HD or FD mode - * accordingly as per the MAC IP. + * Algorithm: Takes care of setting HD or FD mode + * accordingly as per the MAC IP. * - * Dependencies: MAC IP should be out of reset - * and need to be initialized as the requirements + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() * - * Protection: None + * Protection: None * - * Return: NONE + * Return: NONE */ void osi_set_mode(struct osi_core_priv_data *osi_core, int mode); /** - * osi_set_speed - Set operating speed. - * @osi: OSI private data structure. - * @speed: Operating speed. + * osi_set_speed - Set operating speed. + * @osi: OSI private data structure. + * @speed: Operating speed. * - * Algorithm: Takes care of setting the operating - * speed accordingly as per the MAC IP. + * Algorithm: Takes care of setting the operating + * speed accordingly as per the MAC IP. * - * Dependencies: MAC IP should be out of reset - * and need to be initialized as the requirements + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() * - * Protection: None + * Protection: None * - * Return: NONE + * Return: NONE */ void osi_set_speed(struct osi_core_priv_data *osi_core, int speed); /** - * osi_pad_calibrate - PAD calibration - * @osi: OSI core private data structure. + * osi_pad_calibrate - PAD calibration + * @osi: OSI core private data structure. * - * Algorithm: Takes care of doing the pad calibration - * accordingly as per the MAC IP. + * Algorithm: Takes care of doing the pad calibration + * accordingly as per the MAC IP. * - * Dependencies: RGMII and MDIO interface needs to be IDLE - * before performing PAD calibration. + * Dependencies: + * 1) MAC should out of reset and clocks enabled. + * 2) RGMII and MDIO interface needs to be IDLE before performing PAD + * calibration. * - * Protection: None + * Protection: None * - * Return: 0 - success, -1 - failure + * Return: 0 - success, -1 - failure */ int osi_pad_calibrate(struct osi_core_priv_data *osi_core); /** - * osi_flush_mtl_tx_queue - Flushing a MTL Tx Queue. - * @osi_core: OSI private data structure. - * @qinx: MTL queue index. + * osi_flush_mtl_tx_queue - Flushing a MTL Tx Queue. + * @osi_core: OSI private data structure. + * @qinx: MTL queue index. * - * Algorithm: Invokes EQOS flush Tx queue routine. + * Algorithm: Invokes EQOS flush Tx queue routine. * - * Dependencies: MAC IP should be out of reset - * and need to be initialized as the requirements + * Dependencies: + * 1) MAC should out of reset and clocks enabled. + * 2) hw core initialized. see osi_hw_core_init(). * - * Protection: None + * Protection: None * - * Return: 0 - success, -1 - failure. + * Return: 0 - success, -1 - failure. */ int osi_flush_mtl_tx_queue(struct osi_core_priv_data *osi_core, unsigned int qinx); @@ -478,12 +496,12 @@ int osi_flush_mtl_tx_queue(struct osi_core_priv_data *osi_core, * * Algorithm: Configure the MAC to support the loopback. * - * Dependencies: MAC IP should be out of reset - * and need to be initialized as the requirements + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() * * Protection: None * - * Return: 0 - success, -1 - failure. + * Return: 0 - success, -1 - failure. */ int osi_config_mac_loopback(struct osi_core_priv_data *osi_core, unsigned int lb_mode); @@ -496,8 +514,9 @@ int osi_config_mac_loopback(struct osi_core_priv_data *osi_core, * Algorithm: Set AVB algo and populated parameter from osi_core_avb * structure for TC/TQ * - * Dependencies: MAC IP should be out of reset and need to be initialized - * as the requirements + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() + * 2) osi_core->osd should be populated. * * Return: Success = 0; failure = -1; */ @@ -511,8 +530,9 @@ int osi_set_avb(struct osi_core_priv_data *osi_core, * Algorithm: get AVB algo and populated parameter from osi_core_avb * structure for TC/TQ * - * Dependencies: MAC IP should be out of reset and need to be initialized - * as the requirements + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() + * 2) osi_core->osd should be populated. * * Return: Success = 0; failure = -1; */ @@ -527,12 +547,12 @@ int osi_get_avb(struct osi_core_priv_data *osi_core, * Algorithm: Configure MAC to enable/disable Tx status error * reporting. * - * Dependencies: MAC IP should be out of reset and need to be initialized - * as per the requirements + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() * * Protection: None * - * Return: 0 - success, -1 - failure. + * Return: 0 - success, -1 - failure. */ int osi_configure_txstatus(struct osi_core_priv_data *osi_core, unsigned int tx_status); @@ -545,12 +565,12 @@ int osi_configure_txstatus(struct osi_core_priv_data *osi_core, * * Algorithm: Configure MAC to enable/disable forwarding of error packets. * - * Dependencies: MAC IP should be out of reset and need to be initialized - * as per the requirements + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() * * Protection: None * - * Return: 0 - success, -1 - failure. + * Return: 0 - success, -1 - failure. */ int osi_config_fw_err_pkts(struct osi_core_priv_data *osi_core, unsigned int qinx, unsigned int fw_err); @@ -564,12 +584,12 @@ int osi_config_fw_err_pkts(struct osi_core_priv_data *osi_core, * field in the received packets. When this bit is reset, the MAC receiver * always checks the CRC field in the received packets. * - * Dependencies: MAC IP should be out of reset and need to be initialized - * as per the requirements + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() * * Protection: None * - * Return: 0 - success, -1 - failure. + * Return: 0 - success, -1 - failure. */ int osi_config_rx_crc_check(struct osi_core_priv_data *osi_core, unsigned int crc_chk); @@ -583,12 +603,12 @@ int osi_config_rx_crc_check(struct osi_core_priv_data *osi_core, * flw_ctrl BIT0 is for tx flow ctrl enable/disable * flw_ctrl BIT1 is for rx flow ctrl enable/disable * - * Dependencies: MAC IP should be out of reset and need to be initialized - * as per the requirements + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() * * Protection: None * - * Return: 0 - success, -1 - failure. + * Return: 0 - success, -1 - failure. */ int osi_configure_flow_control(struct osi_core_priv_data *osi_core, unsigned int flw_ctrl); @@ -601,9 +621,9 @@ int osi_configure_flow_control(struct osi_core_priv_data *osi_core, * * Algorithm: Invokes EQOS config ARP offload routine. * - * Dependencies: MAC IP should be out of reset and initialized. - * IP address passed to this function is not validated. - * Caller has to perform IP address validation. + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() + * 2) Valid 4 byte IP address as argument @ip_addr * * Protection: None * @@ -620,7 +640,8 @@ int osi_config_arp_offload(struct osi_core_priv_data *osi_core, * * Algorithm: Invokes EQOS config RX checksum offload routine. * - * Dependencies: MAC IP should be out of reset and initialized. + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() * * Protection: None * @@ -638,8 +659,10 @@ int osi_config_rxcsum_offload(struct osi_core_priv_data *osi_core, * processing modes like promiscuous, multicast, unicast, * hash unicast/multicast. * - * Dependencies: MAC IP should be out of reset - * and need to be initialized as the requirements + * Dependencies: + * 1) MAC should be initialized and started. see osi_start_mac() + * 2) MAC addresses should be configured in HW registers. see + * osi_update_mac_addr_low_high_reg(). * * Protection: None * @@ -670,8 +693,9 @@ int osi_config_mac_pkt_filter_reg(struct osi_core_priv_data *osi_core, * dma_chan as well as DCS bit enabled in RXQ to DMA mapping register * performed before updating DCS bits. * - * Dependencies: MAC IP should be out of reset - * and need to be initialized as the requirements + * Dependencies: + * 1) MAC should be initialized and stated. see osi_start_mac() + * 2) osi_core->osd should be populated. * * Protection: None * @@ -694,8 +718,8 @@ int osi_update_mac_addr_low_high_reg(struct osi_core_priv_data *osi_core, * * Algorithm: This routine to enable/disable L4/l4 filter * - * Dependencies: MAC IP should be out of reset - * and need to be initialized as the requirements + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() * * Protection: None * @@ -722,9 +746,11 @@ int osi_config_l3_l4_filter_enable(struct osi_core_priv_data *osi_core, * for address matching. * * Dependencies: - * 1) MAC IP should be out of reset and need to be initialized - * as the requirements - * 2) DCS bits should be enabled in RXQ to DMA map register + * 1) MAC should be init and started. see osi_start_mac() + * 2) L3/L4 filtering should be enabled in MAC PFR register. See + * osi_config_l3_l4_filter_enable() + * 3) osi_core->osd should be populated + * 4) DCS bits should be enabled in RXQ to DMA map register * * Protection: None * @@ -749,8 +775,10 @@ int osi_config_l3_filters(struct osi_core_priv_data *osi_core, * Algorithm: This sequence is used to update IPv4 source/destination * Address for L3 layer filtering * - * Dependencies: MAC IP should be out of reset - * and need to be initialized as the requirements + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() + * 2) L3/L4 filtering should be enabled in MAC PFR register. See + * osi_config_l3_l4_filter_enable() * * Protection: None * @@ -770,8 +798,10 @@ int osi_update_ip4_addr(struct osi_core_priv_data *osi_core, * Algorithm: This sequence is used to update IPv6 source/destination * Address for L3 layer filtering * - * Dependencies: MAC IP should be out of reset - * and need to be initialized as the requirements + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() + * 2) L3/L4 filtering should be enabled in MAC PFR register. See + * osi_config_l3_l4_filter_enable() * * Protection: None * @@ -796,8 +826,11 @@ int osi_update_ip6_addr(struct osi_core_priv_data *osi_core, * Algorithm: This sequence is used to configure L4(TCP/UDP) filters for * SA and DA Port Number matching * - * Dependencies: MAC IP should be out of reset - * and need to be initialized as the requirements + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() + * 2) L3/L4 filtering should be enabled in MAC PFR register. See + * osi_config_l3_l4_filter_enable() + * 3) osi_core->osd should be populated * * Protection: None * @@ -814,7 +847,7 @@ int osi_config_l4_filters(struct osi_core_priv_data *osi_core, /** * osi_update_l4_port_no - invoke OSI call for - * update_l4_port_no. + * update_l4_port_no. * * @osi_core: OSI private data structure. * @filter_no: filter index @@ -824,8 +857,11 @@ int osi_config_l4_filters(struct osi_core_priv_data *osi_core, * Algoriths sequence is used to update Source Port Number for * L4(TCP/UDP) layer filtering. * - * Dependencies: MAC IP should be out of reset - * and need to be initialized as the requirements + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() + * 2) L3/L4 filtering should be enabled in MAC PFR register. See + * osi_config_l3_l4_filter_enable() + * 3) osi_core->osd should be populated * * Protection: None * @@ -847,8 +883,9 @@ int osi_update_l4_port_no(struct osi_core_priv_data *osi_core, * Algorithm: This sequence is used to enable/disable VLAN filtering and * also selects VLAN filtering mode- perfect/hash * - * Dependencies: MAC IP should be out of reset - * and need to be initialized as the requirements + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() + * 2) osi_core->osd should be populated * * Protection: None * @@ -869,8 +906,8 @@ int osi_config_vlan_filtering(struct osi_core_priv_data *osi_core, * Algorithm: This sequence is used to select perfect/inverse matching * for L2 DA * - * Dependencies: MAC IP should be out of reset - * and need to be initialized as the requirements + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() * * Protection: None * @@ -887,8 +924,8 @@ int osi_config_l2_da_perfect_inverse_match(struct osi_core_priv_data *osi_core, * * Algorithm: return 16 bit VLAN ID * - * Dependencies: MAC IP should be out of reset and need to be initialized - * as the requirements + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() * * Protection: None * @@ -914,7 +951,8 @@ int osi_update_vlan_id(struct osi_core_priv_data *osi_core, * 4) Write into MAC MDIO address register poll for GMII busy for MDIO * operation to complete. * - * Dependencies: MAC IP should be out of reset + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() * * Protection: None * @@ -932,8 +970,9 @@ int osi_write_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, * Algorithm: Read the registers, mask reserve bits if requied, update * structure. * - * Dependencies: MAC IP should be out of reset and need to be initialized - * as per the requirements + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() + * 2) osi_core->osd should be populated * * Protection: None * @@ -949,8 +988,9 @@ int osi_read_mmc(struct osi_core_priv_data *osi_core); * Algorithm: Read the registers, mask reserve bits if requied, update * structure. * - * Dependencies: MAC IP should be out of reset and need to be initialized - * as per the requirements + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() + * 2) osi_core->osd should be populated * * Protection: None * @@ -974,7 +1014,8 @@ int osi_reset_mmc(struct osi_core_priv_data *osi_core); * operation to complete. After this data will be available at MAC MDIO * data register. * - * Dependencies: MAC IP should be out of reset + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() * * Protection: None * @@ -992,8 +1033,8 @@ void osi_init_core_ops(struct osi_core_priv_data *osi_core); * * Algorithm: Set current system time to MAC. * - * Dependencies: MAC init should be complete. See osi_hw_core_init() and - * osi_hw_dma_init() + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() * * Protection: None. * @@ -1010,8 +1051,8 @@ int osi_set_systime_to_mac(struct osi_core_priv_data *osi_core, * "Compensation" is the difference in frequency between * the master and slave clocks in Parts Per Billion. * - * Dependencies: MAC IP should be out of reset and need to be - * initialized as the requirements + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() * * Protection: None * @@ -1028,9 +1069,9 @@ int osi_adjust_freq(struct osi_core_priv_data *osi_core, int ppb); * Algorithm: Adjust/update the MAC system time (delta passed in * nanoseconds, can be + or -). * - * Dependencies: MAC IP should be out of reset - * and need to be initialized as the requirements - * 1) osi_core->ptp_config.one_nsec_accuracy need to be set to 1 + * Dependencies: + * 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 * * Protection: None * @@ -1039,15 +1080,15 @@ int osi_adjust_freq(struct osi_core_priv_data *osi_core, int ppb); int osi_adjust_time(struct osi_core_priv_data *osi_core, long delta); /** - * osi_get_systime - Get system time + * osi_get_systime_from_mac - Get system time * @osi: OSI private data structure. * @sec: Value read in Seconds * @nsec: Value read in Nano seconds * * Algorithm: Gets the current system time * - * Dependencies: MAC IP should be out of reset and need to be - * initialized as the requirements. + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() * * Protection: None * @@ -1065,18 +1106,18 @@ void osi_get_systime_from_mac(struct osi_core_priv_data *osi_core, * * Algorithm: Configure the PTP registers that are required for PTP. * - * Dependencies: MAC IP should be out of reset and need to be initialized - * as the requirements. - * 1) osi->ptp_config.ptp_filter need to be filled accordingly to the + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() + * 2) 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. - * 2) osi->ptp_config.ptp_clock need to be filled with the ptp system clk. + * 3) osi->ptp_config.ptp_clock need to be filled with the ptp system clk. * Currently it is set to 62500000Hz. - * 3) osi->ptp_config.ptp_ref_clk_rate need to be filled with the ptp + * 4) osi->ptp_config.ptp_ref_clk_rate need to be filled with the ptp * reference clock that platform supports. - * 4) osi->ptp_config.sec need to be filled with current time of seconds - * 5) osi->ptp_config.nsec need to be filled with current time of nseconds - * 6) osi->base need to be filled with the ioremapped base address + * 5) osi->ptp_config.sec need to be filled with current time of seconds + * 6) osi->ptp_config.nsec need to be filled with current time of nseconds + * 7) osi->base need to be filled with the ioremapped base address * * Protection: None * diff --git a/include/osi_dma.h b/include/osi_dma.h index cd0e9b2..f09d0ee 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -151,11 +151,11 @@ struct osi_tx_swcx { }; /** - * struct osi_tx_desc - Transmit descriptor - * @tdes0: Transmit descriptor 0 - * @tdes1: Transmit descriptor 1 - * @tdes2: Transmit descriptor 2 - * @tdes3: Transmit descriptor 3 + * struct osi_tx_desc - Transmit descriptor + * @tdes0: Transmit descriptor 0 + * @tdes1: Transmit descriptor 1 + * @tdes2: Transmit descriptor 2 + * @tdes3: Transmit descriptor 3 */ struct osi_tx_desc { unsigned int tdes0; @@ -197,7 +197,7 @@ struct osi_txdone_pkt_cx { }; /** - * struct osi_tx_ring - DMA channel Tx ring + * struct osi_tx_ring - DMA channel Tx ring * @tx_desc: Pointer to tx dma descriptor * @tx_swcx: Pointer to tx dma descriptor software context information * @tx_desc_phy_addr: Physical address of Tx descriptor. @@ -304,7 +304,11 @@ struct osi_dma_priv_data { * * Algorithm: Disables Tx interrupts at wrapper level. * - * Dependencies: osi_dma_chan_ops needs to be assigned based on MAC. + * Dependencies: + * 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. * * Protection: None. * @@ -320,7 +324,11 @@ void osi_disable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, * * Algorithm: Enables Tx interrupts at wrapper level. * - * Dependencies: osi_dma_chan_ops needs to be assigned based on MAC. + * Dependencies: + * 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. * * Protection: None. * @@ -334,9 +342,13 @@ void osi_enable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, * @osi_dma: DMA private data. * @chan: DMA rx channel number. * - * Algorithm: Disables Tx interrupts at wrapper level. + * Algorithm: Disables Rx interrupts at wrapper level. * - * Dependencies: osi_dma_chan_ops needs to be assigned based on MAC. + * Dependencies: + * 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. * * Protection: None. * @@ -350,9 +362,13 @@ void osi_disable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, * @osi_dma: DMA private data. * @chan: DMA rx channel number. * - * Algorithm: Enables Tx interrupts at wrapper level. + * Algorithm: Enables Rx interrupts at wrapper level. * - * Dependencies: osi_dma_chan_ops needs to be assigned based on MAC. + * Dependencies: + * 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. * * Protection: None. * @@ -368,7 +384,9 @@ void osi_enable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, * * Algorithm: Clear Tx interrupt source at wrapper level and DMA level. * - * Dependencies: osi_dma_chan_ops needs to be assigned based on MAC. + * Dependencies: + * 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 * * Protection: None. * @@ -384,7 +402,11 @@ void osi_clear_tx_intr(struct osi_dma_priv_data *osi_dma, * * Algorithm: Clear Rx interrupt source at wrapper level and DMA level. * - * Dependencies: osi_dma_chan_ops needs to be assigned based on MAC. + * Dependencies: + * 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. * * Protection: None. * @@ -399,8 +421,13 @@ void osi_clear_rx_intr(struct osi_dma_priv_data *osi_dma, * @chan: DMA Tx/Rx channel number * * Algorimthm: Start the DMA for specific MAC - * Dependencies: None + * + * Dependencies: + * 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 + * * Protection: None + * * Return: None */ void osi_start_dma(struct osi_dma_priv_data *osi_dma, @@ -412,7 +439,11 @@ void osi_start_dma(struct osi_dma_priv_data *osi_dma, * @chan: DMA Tx/Rx channel number * * Algorimthm: Stop the DMA for specific MAC - * Dependencies: None + * + * Dependencies: + * 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 + * * Protection: None * Return: None */ @@ -420,17 +451,17 @@ void osi_stop_dma(struct osi_dma_priv_data *osi_dma, unsigned int chan); /** - * osi_get_refill_rx_desc_cnt - Rx descriptors count that needs to refill. - * @rx_ring: DMA channel Rx ring. + * osi_get_refill_rx_desc_cnt - Rx descriptors count that needs to refill. + * @rx_ring: DMA channel Rx ring. * - * Algorithm: subtract current index with fill (need to cleanup) - * to get Rx descriptors count that needs to refill. + * Algorithm: subtract current index with fill (need to cleanup) + * to get Rx descriptors count that needs to refill. * - * Dependencies: None. + * Dependencies: None. * - * Protection: None. + * Protection: None. * - * Return: Number of available free descriptors. + * Return: Number of available free descriptors. */ unsigned int osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring); @@ -442,7 +473,10 @@ unsigned int osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring); * * Algorithm: Initialise a Rx DMA descriptor. * - * Dependencies: None. + * Dependencies: + * 1) MAC needs to be out of reset and proper clocks need to be configured. + * 2) rx_swcx->buf_phy_addr need to be filled with DMA mapped address + * 2) DMA HW init need to be completed successfully, see osi_hw_dma_init * * Protection: None. * @@ -460,7 +494,9 @@ void osi_rx_dma_desc_init(struct osi_rx_swcx *rx_swcx, * * Algorithm: Updates DMA Rx ring tail pointer. * - * Dependencies: None. + * Dependencies: + * 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 * * Protection: None. * @@ -476,7 +512,10 @@ void osi_update_rx_tailptr(struct osi_dma_priv_data *osi_dma, * * Algorithm: Updates Rx buffer length. * - * Dependencies: None. + * Dependencies: + * 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 * * Protection: None. * @@ -484,14 +523,181 @@ void osi_update_rx_tailptr(struct osi_dma_priv_data *osi_dma, */ void osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma); +/** + * osi_hw_transmit - Initialize Tx DMA descriptors for a channel + * @osi_dma: DMA private data. + * @chan: DMA Tx channel number. + * + * Algorithm: Initialize Transmit descriptors with DMA mappabled buffers, + * set OWN bit, Tx ring length and set starting address of Tx DMA channel. + * Tx ring base address in Tx DMA registers. + * + * Dependencies: + * 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) DMA channel need to be started, see osi_start_dma + * 4) Need to set update tx_pkt_cx->flags accordingly as per the + * requirements + * #define OSI_PKT_CX_VLAN OSI_BIT(0) + * #define OSI_PKT_CX_CSUM OSI_BIT(1) + * #define OSI_PKT_CX_TSO OSI_BIT(2) + * #define OSI_PKT_CX_PTP OSI_BIT(3) + * 5) tx_pkt_cx->desc_cnt need to be populated which holds the number + * of swcx descriptors allocated for that packet + * 6) 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 + * + * Protection: None. + * + * Return: None. + */ void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan); + +/** + * osi_process_tx_completions - Process Tx complete on DMA channel ring. + * @osi: OSI private data structure. + * @chan: Channel number on which Tx complete need to be done. + * + * Algorithm: This function will be invoked by OSD layer to process Tx + * complete interrupt. + * 1) First checks whether descriptor owned by DMA or not. + * 2) Invokes OSD layer to release DMA address and Tx buffer which are + * updated as part of transmit routine. + * + * Dependencies: + * 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) DMA need to be started, see osi_start_dma + * + * Protection: None + * + * Return: Number of decriptors (buffers) proccessed. + */ int osi_process_tx_completions(struct osi_dma_priv_data *osi, unsigned int chan); + +/** + * osi_process_rx_completions - Read data from receive channel descriptors + * @osi: OSI private data structure. + * @chan: Rx DMA channel number + * @budget: Threshould for reading the packets at a time. + * + * Algorimthm: This routine will be invoked by OSD layer to get the + * data from Rx descriptors and deliver the packet to the stack. + * 1) Checks descriptor owned by DMA or not. + * 2) Get the length from Rx descriptor + * 3) Invokes OSD layer to deliver the packet to network stack. + * 4) Re-allocate the receive buffers, populate Rx descriptor and + * handover to DMA. + * + * Dependencies: + * 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) DMA need to be started, see osi_start_dma + * + * Protection: None. + * + * Return: None. + */ int osi_process_rx_completions(struct osi_dma_priv_data *osi, unsigned int chan, int budget); + +/** + * osi_hw_dma_init - Initialize DMA + * @osi_dma: DMA private data. + * + * Algorithm: Takes care of initializing the tx, rx ring and descriptors + * based on the number of channels selected. + * + * Dependencies: + * 1) Allocate memory for osi_dma + * 2) MAC needs to be out of reset and proper clocks need to be configured. + * 3) Numer of dma channels osi_dma->num_dma_chans + * 4) channel list osi_dma->dma_chan + * 5) base address osi_dma->base + * 6) allocate tx ring osi_dma->tx_ring[chan] for each channel + * based on TX_DESC_CNT (256) + * 7) allocate tx descriptors osi_dma->tx_ring[chan]->tx_desc for all + * channels and dma map it. + * 8) allocate tx sw descriptors osi_dma->tx_ring[chan]->tx_swcx for all + * channels + * 9) allocate rx ring osi_dma->rx_ring[chan] for each channel + * based on RX_DESC_CNT (256) + * 10) allocate rx descriptors osi_dma->rx_ring[chan]->rx_desc for all + * channels and dma map it. + * 11) allocate rx sw descriptors osi_dma->rx_ring[chan]->rx_swcx for all + * channels + * 12) osi_dma->use_riwt ==> OSI_DISABLE/OSI_ENABLE + * 13) osi_dma->rx_riwt ===> Actual value read from DT + * + * Protection: None. + * + * Return: None. + */ int osi_hw_dma_init(struct osi_dma_priv_data *osi_dma); + +/** + * osi_hw_dma_deinit - Deinitialize DMA + * @osi_dma: DMA private data. + * + * Algorithm: Takes care of stopping the MAC + * + * Dependencies: + * 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 + * + * Protection: None. + * + * Return: None. + */ void osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma); + +/** + * osi_init_dma_ops - Initialize DMA operations + * @osi_dma: DMA private data. + * + * Algorithm: Takes care of initializing the DMA operations + * + * Dependencies: None. + * + * Protection: None. + * + * Return: None. + */ void osi_init_dma_ops(struct osi_dma_priv_data *osi_dma); + +/** + * osi_clear_tx_pkt_err_stats - Clear tx packet error stats. + * @osi: OSI dma private data structure. + * + * Algorithm: This function will be invoked by OSD layer to clear the + * tx stats mentioned in osi_dma->pkt_err_stats structure + + * Dependencies: + * 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 + * + * Protection: None + * + * Return: None + */ void osi_clear_tx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); + +/** + * osi_clear_rx_pkt_err_stats - Clear rx packet error stats. + * @osi: OSI dma private data structure. + * + * Algorithm: This function will be invoked by OSD layer to clear the + * rx_crc_error mentioned in osi_dma->pkt_err_stats structure. + * + * Dependencies: + * 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 + * + * Protection: None + * + * Return: None + */ void osi_clear_rx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); #endif /* OSI_DMA_H */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 581eaa1..df8f283 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -35,7 +35,8 @@ struct osi_core_ops *eqos_get_hw_core_ops(void); * * Algorithm: * - * Dependencies: MAC has to be out of reset. + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() * * Protection: None. * @@ -101,7 +102,8 @@ static int eqos_config_flow_control(void *addr, unsigned int flw_ctrl) * field in the received packets. When this bit is reset, the MAC receiver * always checks the CRC field in the received packets. * - * Dependencies: MAC has to be out of reset. + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() * * Protection: None. * @@ -147,7 +149,8 @@ static int eqos_config_rx_crc_check(void *addr, unsigned int crc_chk) * When this bit is set, all packets except the runt error packets * are forwarded to the application or DMA. * - * Dependencies: MAC has to be out of reset. + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() * * Protection: None. * @@ -200,7 +203,8 @@ static int eqos_config_fw_err_pkts(void *addr, unsigned int qinx, * When DTXSTS bit is set, the Tx packet status received from the MAC * are dropped in MTL. * - * Dependencies: MAC has to be out of reset. + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() * * Protection: None. * @@ -247,7 +251,8 @@ static int eqos_config_tx_status(void *addr, unsigned int tx_status) * * Algorithm: Configure MAC to enable or disable loopback * - * Dependencies: MAC has to be out of reset. + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() * * Protection: None. * @@ -299,7 +304,8 @@ static int eqos_config_mac_loopback(void *addr, unsigned int lb_mode) * Algorithm: CAR reset will be issued through MAC reset pin. * Waits for SWR reset to be cleared in DMA Mode register. * - * Dependencies: None + * Dependencies: + * 1) MAC needs to be out of reset and proper clock configured. * * Protection: None * @@ -343,8 +349,9 @@ static int eqos_poll_for_swr(void *addr) * Algorithm: MDC clock rate will be polulated OSI private data structure * based on AXI_CBB clock rate. * - * Dependencies: OSD layer needs get the AXI CBB clock rate with OSD clock - * API (ex - clk_get_rate()) + * Dependencies: + * 1) OSD layer needs get the AXI CBB clock rate with OSD clock API + * (ex - clk_get_rate()) * * Return: None */ @@ -381,7 +388,8 @@ static void eqos_set_mdc_clk_rate(struct osi_core_priv_data *osi_core, * Algorithm: Based on the speed (10/100/1000Mbps) MAC will be configured * accordingly. * - * Dependencies: MAC has to be out of reset. + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() * * Protection: None * @@ -422,7 +430,8 @@ static void eqos_set_speed(void *base, int speed) * Algorithm: Based on the mode (HALF/FULL Duplex) MAC will be configured * accordingly. * - * Dependencies: MAC has to be out of reset. + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() * * Protection: None * @@ -549,8 +558,10 @@ static unsigned int eqos_calculate_per_queue_fifo(unsigned int fifo_size, * 5) Re-program the value PAD_E_INPUT_OR_E_PWRD in * ETHER_QOS_SDMEMCOMPPADCTRL_0 to save power * - * Dependencies: RGMII and MDIO interface needs to be IDLE - * before performing PAD calibration. + * Dependencies: + * 1) MAC should out of reset and clocks enabled. + * 2) RGMII and MDIO interface needs to be IDLE before performing PAD + * calibration. * * Protection: None * @@ -618,7 +629,9 @@ static int eqos_pad_calibrate(void *ioaddr) * * Algorithm: Flush a MTL Tx queue. * - * Dependencies: None. + * Dependencies: + * 1) MAC should out of reset and clocks enabled. + * 2) hw core initialized. see osi_hw_core_init(). * * Protection: None. * @@ -843,7 +856,8 @@ static int eqos_configure_mtl_queue(unsigned int qinx, * 2) Enable the IP checksum offload engine COE in MAC receiver. * 3) Update the MAC configuration register. * - * Dependencies: MAC has to be out of reset. + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() * * Protection: None. * @@ -1105,7 +1119,11 @@ static void eqos_configure_dma(void *base) * Algorithm: This function will take care of initializing MAC, MTL and * common DMA registers. * - * Dependencies: Required clks and resets has to be enabled + * Dependencies: + * 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. * * Protection: None * @@ -1292,7 +1310,8 @@ static inline void update_dma_sr_stats(struct osi_core_priv_data *osi_core, * * Algorithm: Clear common interrupt source. * - * Dependencies: None. + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() * * Protection: None. * @@ -1353,7 +1372,9 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *osi_core) * * Algorithm: Enable MAC Transmitter and Receiver * - * Dependencies: None. + * Dependencies: + * 1) MAC init should be complete. See osi_hw_core_init() and + * osi_hw_dma_init() * * Protection: None. * @@ -1376,7 +1397,8 @@ static void eqos_start_mac(void *addr) * * Algorithm: Disables MAC Transmitter and Receiver * - * Dependencies: None. + * Dependencies: + * 1) MAC DMA deinit should be complete. See osi_hw_dma_deinit() * * Protection: None. * @@ -1410,7 +1432,9 @@ static void eqos_stop_mac(void *addr) * 2f) Set low credit * 3) Update register values * - * Dependencies: MAC has to be out of reset. + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() + * 2) osi_core->osd should be populated. * * Protection: None. * @@ -1497,8 +1521,10 @@ static int eqos_set_avb_algorithm(struct osi_core_priv_data *osi_core, * processing modes like promiscuous, multicast, unicast, * hash unicast/multicast. * - * Dependencies: MAC IP should be out of reset - * and need to be initialized as the requirements + * Dependencies: + * 1) MAC should be initialized and started. see osi_start_mac() + * 2) MAC addresses should be configured in HW registers. see + * osi_update_mac_addr_low_high_reg(). * * Protection: None * @@ -1549,8 +1575,9 @@ static void eqos_config_mac_pkt_filter_reg(struct osi_core_priv_data *osi_core, * dma_chan as well as DCS bit enabled in RXQ to DMA mapping register * performed before updating DCS bits. * - * Dependencies: MAC IP should be out of reset - * and need to be initialized as the requirements + * Dependencies: + * 1) MAC should be initialized and stated. see osi_start_mac() + * 2) osi_core->osd should be populated. * * Protection: None * @@ -1634,7 +1661,9 @@ static int eqos_update_mac_addr_low_high_reg( * 2f) read low credit * 3) updated pointer * - * Dependencies: MAC has to be out of reset. + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() + * 2) osi_core->osd should be populated. * * Protection: None. * @@ -1714,7 +1743,9 @@ static int eqos_get_avb_algorithm(struct osi_core_priv_data *osi_core, * ARPPA register * 3) Enable/disable the ARPEN bit in MCR and write back to the MCR. * - * Dependencies: None. + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() + * 2) Valid 4 byte IP address as argument @ip_addr * * Protection: None. * @@ -1769,8 +1800,8 @@ static int eqos_config_arp_offload(unsigned int mac_ver, void *addr, * * Algorithm: This routine to enable/disable L4/l4 filter * - * Dependencies: MAC IP should be out of reset - * and need to be initialized as the requirements + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() * * Protection: None * @@ -1799,8 +1830,8 @@ static int eqos_config_l3_l4_filter_enable(void *base, * Algorithm: This sequence is used to select perfect/inverse matching * for L2 DA * - * Dependencies: MAC IP should be out of reset - * and need to be initialized as the requirements + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() * * Protection: None * @@ -1830,8 +1861,10 @@ static int eqos_config_l2_da_perfect_inverse_match(void *base, unsigned int * Algorithm: This sequence is used to update IPv4 source/destination * Address for L3 layer filtering * - * Dependencies: MAC IP should be out of reset - * and need to be initialized as the requirements + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() + * 2) L3/L4 filtering should be enabled in MAC PFR register. See + * osi_config_l3_l4_filter_enable() * * Protection: None * @@ -1880,8 +1913,10 @@ static int eqos_update_ip4_addr(struct osi_core_priv_data *osi_core, * Algorithm: This sequence is used to update IPv6 source/destination * Address for L3 layer filtering * - * Dependencies: MAC IP should be out of reset - * and need to be initialized as the requirements + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() + * 2) L3/L4 filtering should be enabled in MAC PFR register. See + * osi_config_l3_l4_filter_enable() * * Protection: None * @@ -1940,9 +1975,11 @@ static int eqos_update_ip6_addr(struct osi_core_priv_data *osi_core, * L4(TCP/UDP) layer filtering. * * Dependencies: - * 1) MAC IP should be out of reset and need to be initialized - * as the requirements - * 2) DCS bits should be enabled in RXQ to DMA mapping register + * 1) MAC should be init and started. see osi_start_mac() + * 2) L3/L4 filtering should be enabled in MAC PFR register. See + * osi_config_l3_l4_filter_enable() + * 3) osi_core->osd should be populated + * 4) DCS bits should be enabled in RXQ to DMA mapping register * * Protection: None * @@ -2040,9 +2077,11 @@ static inline unsigned int eqos_set_dcs(struct osi_core_priv_data *osi_core, * for address matching. * * Dependencies: - * 1) MAC IP should be out of reset and need to be initialized - * as the requirements - * 2) DCS bits should be enabled in RXQ to DMA map register + * 1) MAC should be init and started. see osi_start_mac() + * 2) L3/L4 filtering should be enabled in MAC PFR register. See + * osi_config_l3_l4_filter_enable() + * 3) osi_core->osd should be populated + * 4) DCS bits should be enabled in RXQ to DMA map register * * Protection: None * @@ -2201,8 +2240,11 @@ static int eqos_config_l3_filters(struct osi_core_priv_data *osi_core, * Algorithm: This sequence is used to configure L4(TCP/UDP) filters for * SA and DA Port Number matching * - * Dependencies: MAC IP should be out of reset - * and need to be initialized as the requirements + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() + * 2) L3/L4 filtering should be enabled in MAC PFR register. See + * osi_config_l3_l4_filter_enable() + * 3) osi_core->osd should be populated * * Protection: None * @@ -2300,8 +2342,9 @@ static int eqos_config_l4_filters(struct osi_core_priv_data *osi_core, * Algorithm: This sequence is used to enable/disable VLAN filtering and * also selects VLAN filtering mode- perfect/hash * - * Dependencies: MAC IP should be out of reset - * and need to be initialized as the requirements + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() + * 2) osi_core->osd should be populated * * Protection: None * @@ -2338,8 +2381,8 @@ static int eqos_config_vlan_filtering(struct osi_core_priv_data *osi_core, * * Algorithm: update vid at VLAN tag register * - * Dependencies: MAC IP should be out of reset and need to be initialized - * as the requirements + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() * * Protection: None * @@ -2366,7 +2409,8 @@ static inline int eqos_update_vlan_id(void *base, unsigned int vid) * Algorithm: Read TSINIT value from MAC TCR register until it is * equal to zero. * - * Dependencies: None. + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() * * Protection: None. * @@ -2408,7 +2452,8 @@ static inline int eqos_poll_for_tsinit_complete(void *addr, * Algorithm: Updates system time (seconds and nano seconds) * in hardware registers * - * Dependencies: None. + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() * * Protection: None. * @@ -2453,7 +2498,8 @@ static int eqos_set_systime_to_mac(void *addr, unsigned int sec, * Algorithm: Read TSADDREG value from MAC TCR register until it is * equal to zero. * - * Dependencies: None. + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() * * Protection: None. * @@ -2492,7 +2538,8 @@ static inline int eqos_poll_for_addend_complete(void *addr, * * Algorithm: Updates the Addend value in HW register * - * Dependencies: None. + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() * * Protection: None. * @@ -2531,7 +2578,8 @@ static int eqos_config_addend(void *addr, unsigned int addend) * Algorithm: Read time stamp update value from TCR register until it is * equal to zero. * - * Dependencies: None. + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() * * Protection: None. * @@ -2573,7 +2621,9 @@ static inline int eqos_poll_for_update_ts_complete(void *addr, * * Algorithm: Update the system time * - * Dependencies: None. + * Dependencies: + * 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 * * Protection: None. * @@ -2652,7 +2702,8 @@ static int eqos_adjust_systime(void *addr, unsigned int sec, unsigned int nsec, * * Algorithm: Get current system time * - * Dependencies: None. + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() * * Protection: None. * @@ -2700,7 +2751,8 @@ static unsigned long long eqos_get_systime_from_mac(void *addr) * * Algorithm: Configure Time Stamp Register * - * Dependencies: None. + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() * * Protection: None. * @@ -2774,7 +2826,8 @@ static void eqos_config_tscr(void *addr, unsigned int ptp_filter) * * Algorithm: Configure Sub Second Increment Register * - * Dependencies: None. + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() * * Protection: None. * diff --git a/osi/core/eqos_mmc.c b/osi/core/eqos_mmc.c index 7dadf16..51975cd 100644 --- a/osi/core/eqos_mmc.c +++ b/osi/core/eqos_mmc.c @@ -36,8 +36,9 @@ * Algorithm: Read the registers, check for boundary, if more, reset * counters else return same to caller. * - * Dependencies: MAC IP should be out of reset and need to be initialized - * as per the requirements + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() + * 2) osi_core->osd should be populated * * Protection: None * @@ -71,8 +72,9 @@ static inline unsigned long update_mmc_val(struct osi_core_priv_data *osi_core, * * Algorithm: reset HW counter and structure variable value. * - * Dependencies: MAC IP should be out of reset and need to be initialized - * as per the requirements. + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() + * 2) osi_core->osd should be populated * * Protection: None * @@ -97,8 +99,9 @@ void eqos_reset_mmc(struct osi_core_priv_data *osi_core) * Algorithm: Pass register offset and old value to helper function and * update structure. * - * Dependencies: MAC IP should be out of reset and need to be initialized - * as per the requirements + * Dependencies: + * 1) MAC should be init and started. see osi_start_mac() + * 2) osi_core->osd should be populated * * Protection: None * diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index 2773844..8c3fd7d 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -27,14 +27,20 @@ struct osi_dma_chan_ops *eqos_get_dma_chan_ops(void); /** - * eqos_disable_chan_tx_intr - Disable Tx channel interrupts. + * eqos_disable_chan_tx_intr - Disables DMA Tx channel interrupts. * @addr: MAC base address. * @chan: DMA Tx channel number. * - * Algorithm: Disables EQOS DMA tx channel interrupts. + * Algorithm: Disables Tx interrupts at wrapper level. + * + * Dependencies: + * 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. * - * Dependencies: None. * Protection: None. + * * Return: None. */ static void eqos_disable_chan_tx_intr(void *addr, unsigned int chan) @@ -53,8 +59,14 @@ static void eqos_disable_chan_tx_intr(void *addr, unsigned int chan) * * Algorithm: Enables EQOS DMA tx channel interrupts. * - * Dependencies: None. + * Dependencies: + * 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. + * * Protection: None. + * * Return: None. */ static void eqos_enable_chan_tx_intr(void *addr, unsigned int chan) @@ -73,7 +85,11 @@ static void eqos_enable_chan_tx_intr(void *addr, unsigned int chan) * * Algorithm: Disables EQOS DMA rx channel interrupts. * - * Dependencies: None. + * Dependencies: + * 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. * Protection: None. * Return: None. */ @@ -93,8 +109,12 @@ static void eqos_disable_chan_rx_intr(void *addr, unsigned int chan) * * Algorithm: Enables EQOS DMA Rx channel interrupts. * - * Dependencies: None. + * Dependencies: + * 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 + * * Protection: None. + * * Return: None. */ static void eqos_enable_chan_rx_intr(void *addr, unsigned int chan) @@ -113,8 +133,14 @@ static void eqos_enable_chan_rx_intr(void *addr, unsigned int chan) * * Algorithm: Clear DMA Tx interrupt source at wrapper and DMA level. * - * Dependencies: None. + * Dependencies: + * 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. + * * Protection: None. + * * Return: None. */ static void eqos_clear_tx_intr(void *addr, unsigned int chan) @@ -137,8 +163,14 @@ static void eqos_clear_tx_intr(void *addr, unsigned int chan) * * Algorithm: Clear DMA Rx interrupt source at wrapper and DMA level. * - * Dependencies: None. + * Dependencies: + * 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. + * * Protection: None. + * * Return: None. */ static void eqos_clear_rx_intr(void *addr, unsigned int chan) @@ -163,7 +195,9 @@ static void eqos_clear_rx_intr(void *addr, unsigned int chan) * Algorithm: Set DMA Tx channel ring length for specific channel. * * Dependencies: None. + * * Protection: None. + * * Return: None. */ static void eqos_set_tx_ring_len(void *addr, unsigned int chan, @@ -181,7 +215,9 @@ static void eqos_set_tx_ring_len(void *addr, unsigned int chan, * Algorithm: Sets DMA Tx ring base address for specific channel. * * Dependencies: None. + * * Protection: None. + * * Return: None. */ static void eqos_set_tx_ring_start_addr(void *addr, unsigned int chan, @@ -199,8 +235,12 @@ static void eqos_set_tx_ring_start_addr(void *addr, unsigned int chan, * * Algorithm: Updates DMA Tx ring tail pointer for specific channel. * - * Dependencies: None. + * Dependencies: + * 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 + * * Protection: None. + * * Return: None. */ static void eqos_update_tx_tailptr(void *addr, unsigned int chan, @@ -218,7 +258,9 @@ static void eqos_update_tx_tailptr(void *addr, unsigned int chan, * Algorithm: Sets DMA Rx channel ring length for specific DMA channel. * * Dependencies: None. + * * Protection: None. + * * Return: None. */ static void eqos_set_rx_ring_len(void *addr, unsigned int chan, @@ -236,7 +278,9 @@ static void eqos_set_rx_ring_len(void *addr, unsigned int chan, * Algorithm: Sets DMA Rx channel ring base address. * * Dependencies: None. + * * Protection: None. + * * Return: None. */ static void eqos_set_rx_ring_start_addr(void *addr, unsigned int chan, @@ -254,8 +298,12 @@ static void eqos_set_rx_ring_start_addr(void *addr, unsigned int chan, * * Algorithm: Updates DMA Rx channel tail pointer for specific channel. * - * Dependencies: None. + * Dependencies: + * 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 + * * Protection: None. + * * Return: None. */ static void eqos_update_rx_tailptr(void *addr, unsigned int chan, @@ -271,8 +319,12 @@ static void eqos_update_rx_tailptr(void *addr, unsigned int chan, * * Algorithm: Start Tx and Rx DMA for specific channel. * - * Dependencies: None. + * Dependencies: + * 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 + * * Protection: None. + * * Return: None. */ static void eqos_start_dma(void *addr, unsigned int chan) @@ -297,8 +349,12 @@ static void eqos_start_dma(void *addr, unsigned int chan) * * Algorithm: Start Tx and Rx DMA for specific channel. * - * Dependencies: None. + * Dependencies: + * 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 + * * Protection: None. + * * Return: None. */ static void eqos_stop_dma(void *addr, unsigned int chan) @@ -437,7 +493,11 @@ static void eqos_init_dma_channel(struct osi_dma_priv_data *osi_dma) * * Description: Sets the Rx buffer lenght based on the new MTU size set. * - * Dependencies: None. + * Dependencies: + * 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 + * * * Protection: None. * diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 76a47a3..8093e9f 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -59,18 +59,6 @@ int osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) return 0; } -/** - * osi_hw_deinit - De-init the HW - * @osi: OSI private data structure. - * - * Algorithm: - * 1) Stop the DMA - * 2) free all allocated resources. - * - * Dependencies: None - * Protection: None - * Return: None - */ void osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma) { unsigned int i; diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 9c79304..b83a30f 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -203,7 +203,10 @@ static inline void get_rx_err_stats(struct osi_rx_desc *rx_desc, * 4) Re-allocate the receive buffers, populate Rx descriptor and * handover to DMA. * - * Dependencies: None. + * Dependencies: + * 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) DMA need to be started, see osi_start_dma * * Protection: None. * @@ -374,7 +377,9 @@ static inline void get_tx_err_stats(struct osi_tx_desc *tx_desc, * Algorithm: This function will be invoked by OSD layer to clear the * tx packet error stats * - * Dependencies: None. + * Dependencies: + * 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 * * Protection: None * @@ -402,7 +407,9 @@ void osi_clear_tx_pkt_err_stats(struct osi_dma_priv_data *osi_dma) * Algorithm: This function will be invoked by OSD layer to clear the * rx packet error stats * - * Dependencies: None. + * Dependencies: + * 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 * * Protection: None * @@ -425,7 +432,11 @@ void osi_clear_rx_pkt_err_stats(struct osi_dma_priv_data *osi_dma) * 2) Invokes OSD layer to release DMA address and Tx buffer which are * updated as part of transmit routine. * - * Dependencies: None. + * Dependencies: + * 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) DMA need to be started, see osi_start_dma + * * * Protection: None * @@ -642,8 +653,21 @@ static inline void fill_first_desc(struct osi_tx_pkt_cx *tx_pkt_cx, * set OWN bit, Tx ring length and set starting address of Tx DMA channel. * Tx ring base address in Tx DMA registers. * - * Dependencies: Transmit routine of OSD needs to map Tx buffer - * to dma mappable address and update in the software context descriptors. + * Dependencies: + * 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) DMA channel need to be started, see osi_start_dma + * 4) Need to set update tx_pkt_cx->flags accordingly as per the + * requirements + * #define OSI_PKT_CX_VLAN OSI_BIT(0) + * #define OSI_PKT_CX_CSUM OSI_BIT(1) + * #define OSI_PKT_CX_TSO OSI_BIT(2) + * #define OSI_PKT_CX_PTP OSI_BIT(3) + * 5) tx_pkt_cx->desc_cnt need to be populated which holds the number + * of swcx descriptors allocated for that packet + * 6) 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 * * Protection: None. * From f89bb66d34a170feab1d09dbabb82620d172e290 Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Mon, 1 Jul 2019 17:25:02 +0530 Subject: [PATCH 028/458] nvethernetrm: check index boundary Issue: index parameter validation for MAX_index, where it should be MAX_index - 1 as valid values are from (0 to MAX_index - 1). Fix: update boundary check condition Bug 200512422 Change-Id: I6af77a90988967cf834530a7aadcea3090b837d5 Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2146247 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/eqos_core.c | 148 ++++++++++++++++++++++++++++++++----------- osi/core/eqos_core.h | 2 + osi/core/osi_core.c | 18 ++++++ 3 files changed, 130 insertions(+), 38 deletions(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index df8f283..f761ad3 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1553,6 +1553,75 @@ static void eqos_config_mac_pkt_filter_reg(struct osi_core_priv_data *osi_core, osi_writel(value, (unsigned char *)osi_core->base + EQOS_MAC_PFR); } +/** + * eqos_update_mac_addr_helper - Function to update DCS and MBC + * + * @osi_core: OSI private data structure. + * @*value: unsigned int pointer which has value read from register. + * @index: filter index + * @value: MAC address to write + * @dma_routing_enable: dma channel routing enable(1) + * @dma_chan: dma channel number + * @addr_mask: filter will not consider byte in comparison + * Bit 29: MAC_Address${i}_High[15:8] + * Bit 28: MAC_Address${i}_High[7:0] + * Bit 27: MAC_Address${i}_Low[31:24] + * .. + * Bit 24: MAC_Address${i}_Low[7:0] + * + * Algorithm: This helper routine is to update passed prameter value + * based on DCS and MBC parameter. Validation of dma_chan as well as + * dsc_en status performed before updating DCS bits. + * + * Dependencies: + * 1) MAC should be initialized and stated. see osi_start_mac() + * 2) osi_core->osd should be populated. + * + * Protection: None + * + * Return: 0 - success, -1 - failure. + */ +static inline int eqos_update_mac_addr_helper( + struct osi_core_priv_data *osi_core, + unsigned int *value, + unsigned int idx, + unsigned int dma_routing_enable, + unsigned int dma_chan, unsigned int addr_mask) +{ + int ret = 0; + /* PDC bit of MAC_Ext_Configuration register is not set so binary + * value representation. + */ + if (dma_routing_enable == OSI_ENABLE) { + if ((dma_chan < OSI_EQOS_MAX_NUM_CHANS) && + (osi_core->dcs_en == OSI_ENABLE)) { + *value = ((dma_chan << EQOS_MAC_ADDRH_DCS_SHIFT) & + EQOS_MAC_ADDRH_DCS); + } else if (dma_chan > OSI_EQOS_MAX_NUM_CHANS - 0x1U) { + osd_err(osi_core->osd, "invalid dma channel\n"); + ret = -1; + goto err_dma_chan; + } else { + /* Do nothing */ + } + } + + /* Address mask is valid for address 1 to 31 index only */ + if (addr_mask <= EQOS_MAX_MASK_BYTE && addr_mask > 0U) { + if (idx > 0U && idx < EQOS_MAX_MAC_ADDR_REG) { + *value = (*value | + ((addr_mask << EQOS_MAC_ADDRH_MBC_SHIFT) & + EQOS_MAC_ADDRH_MBC)); + } else { + osd_err(osi_core->osd, "invalid address index for MBC\n"); + ret = -1; + } + } + +err_dma_chan: + return ret; +} + /** * eqos_update_mac_addr_low_high_reg- Update L2 address * in filter register @@ -1591,44 +1660,31 @@ static int eqos_update_mac_addr_low_high_reg( unsigned int addr_mask, unsigned int src_dest) { unsigned int value = 0x0U; + int ret = 0; - if (idx > EQOS_MAX_MAC_ADDRESS_FILTER) { + if (idx > (EQOS_MAX_MAC_ADDRESS_FILTER - 0x1U)) { osd_err(osi_core->osd, "invalid MAC filter index\n"); return -1; } - /* High address clean should happen for filter index > 0 */ - if (idx >= 0x1U && addr == OSI_NULL) { - osi_writel((unsigned int)0x0, (unsigned char *)osi_core->base + + /* High address clean should happen for filter index >= 0 */ + if (addr == OSI_NULL) { + osi_writel(0x0U, (unsigned char *)osi_core->base + EQOS_MAC_ADDRH((idx))); return 0; } - /* PDC bit of MAC_Ext_Configuration register is not set so binary - * value representation. - */ - if ((dma_routing_enable == OSI_ENABLE) && - (dma_chan < OSI_EQOS_MAX_NUM_CHANS) && - (osi_core->dcs_en == OSI_ENABLE)) { - value = ((dma_chan << EQOS_MAC_ADDRH_DCS_SHIFT) & - EQOS_MAC_ADDRH_DCS); - } else if ((dma_routing_enable == OSI_ENABLE) && - (dma_chan < OSI_EQOS_MAX_NUM_CHANS) && - (osi_core->dcs_en != OSI_ENABLE)) { - osd_err(osi_core->osd, "DCS disabled, please update DT\n"); - } else { - /* Do nothing */ - } - - /* Address mask is valid for address 1 to 31 index only */ - if ((addr_mask <= 0x3FU && addr_mask > 0U) && (idx > 0U && idx < 32U)) { - value = (value | ((addr_mask << EQOS_MAC_ADDRH_MBC_SHIFT) & - EQOS_MAC_ADDRH_MBC)); + ret = eqos_update_mac_addr_helper(osi_core, &value, idx, + dma_routing_enable, dma_chan, + addr_mask); + /* Check return value from helper code */ + if (ret == -1) { + return ret; } /* Setting Source/Destination Address match valid for 1 to 32 index */ - if ((idx > 0U && idx < 32U) && (src_dest == OSI_SA_MATCH || - src_dest == OSI_DA_MATCH)) { + if ((idx > 0U && idx < EQOS_MAX_MAC_ADDR_REG) && + (src_dest == OSI_SA_MATCH || src_dest == OSI_DA_MATCH)) { value = (value | ((src_dest << EQOS_MAC_ADDRH_SA_SHIFT) & EQOS_MAC_ADDRH_SA)); } @@ -1642,7 +1698,7 @@ static int eqos_update_mac_addr_low_high_reg( ((unsigned int)addr[3] << 24)), (unsigned char *)osi_core->base + EQOS_MAC_ADDRL((idx))); - return 0; + return ret; } /** @@ -1879,7 +1935,12 @@ static int eqos_update_ip4_addr(struct osi_core_priv_data *osi_core, unsigned int value = 0U; unsigned int temp = 0U; - if (filter_no > EQOS_MAX_L3_L4_FILTER) { + if (addr == OSI_NULL) { + osd_err(osi_core->osd, "%s() invalid address\n", __func__); + return -1; + } + + if (filter_no > (EQOS_MAX_L3_L4_FILTER - 0x1U)) { osd_err(osi_core->osd, "filter index %d > %d for L3/L4 filter\n" , filter_no, EQOS_MAX_L3_L4_FILTER); return -1; @@ -1929,7 +1990,12 @@ static int eqos_update_ip6_addr(struct osi_core_priv_data *osi_core, unsigned int value = 0U; unsigned int temp = 0U; - if (filter_no > EQOS_MAX_L3_L4_FILTER) { + if (addr == OSI_NULL) { + osd_err(osi_core->osd, "%s() invalid address\n", __func__); + return -1; + } + + if (filter_no > (EQOS_MAX_L3_L4_FILTER - 0x1U)) { osd_err(osi_core->osd, "filter index %d > %d for L3/L4 filter\n" , filter_no, EQOS_MAX_L3_L4_FILTER); return -1; @@ -1994,7 +2060,7 @@ static int eqos_update_l4_port_no(struct osi_core_priv_data *osi_core, unsigned int value = 0U; unsigned int temp = 0U; - if (filter_no > EQOS_MAX_L3_L4_FILTER) { + if (filter_no > (EQOS_MAX_L3_L4_FILTER - 0x1U)) { osd_err(osi_core->osd, "filter index %d > %d for L3/L4 filter\n" , filter_no, EQOS_MAX_L3_L4_FILTER); return -1; @@ -2049,12 +2115,6 @@ static inline unsigned int eqos_set_dcs(struct osi_core_priv_data *osi_core, value |= ((dma_chan << EQOS_MAC_L3L4_CTR_DMCHN0_SHIFT) & EQOS_MAC_L3L4_CTR_DMCHN0); - } else if ((dma_routing_enable == OSI_ENABLE) && (dma_chan < - OSI_EQOS_MAX_NUM_CHANS) && (osi_core->dcs_en != - OSI_ENABLE)) { - osd_err(osi_core->osd, "DCS disabled, please update DT\n"); - } else { - /* do noting */ } return value; @@ -2099,12 +2159,18 @@ static int eqos_config_l3_filters(struct osi_core_priv_data *osi_core, unsigned int value = 0U; void *base = osi_core->base; - if (filter_no > EQOS_MAX_L3_L4_FILTER) { + if (filter_no > (EQOS_MAX_L3_L4_FILTER - 0x1U)) { osd_err(osi_core->osd, "filter index %d > %d for L3/L4 filter\n" , filter_no, EQOS_MAX_L3_L4_FILTER); return -1; } + if ((dma_routing_enable == OSI_ENABLE) && + (dma_chan > OSI_EQOS_MAX_NUM_CHANS - 1U)) { + osd_err(osi_core->osd, "Wrong DMA channel %d\n", dma_chan); + return -1; + } + value = osi_readl((unsigned char *)base + EQOS_MAC_L3L4_CTR(filter_no)); value &= ~EQOS_MAC_L3L4_CTR_L3PEN0; @@ -2262,12 +2328,18 @@ static int eqos_config_l4_filters(struct osi_core_priv_data *osi_core, void *base = osi_core->base; unsigned int value = 0U; - if (filter_no > EQOS_MAX_L3_L4_FILTER) { + if (filter_no > (EQOS_MAX_L3_L4_FILTER - 0x1U)) { osd_err(osi_core->osd, "filter index %d > %d for L3/L4 filter\n" , filter_no, EQOS_MAX_L3_L4_FILTER); return -1; } + if ((dma_routing_enable == OSI_ENABLE) && + (dma_chan > OSI_EQOS_MAX_NUM_CHANS - 1U)) { + osd_err(osi_core->osd, "Wrong DMA channel %d\n", dma_chan); + return -1; + } + value = osi_readl((unsigned char *)base + EQOS_MAC_L3L4_CTR(filter_no)); value &= ~EQOS_MAC_L3L4_CTR_L4PEN0; value |= ((tcp_udp_match << 16) & EQOS_MAC_L3L4_CTR_L4PEN0); diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 07e2ffa..8519064 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -303,6 +303,8 @@ 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_VLAN_TR 0x0050U diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index b34b82e..ceac067 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -402,6 +402,12 @@ int osi_update_mac_addr_low_high_reg(struct osi_core_priv_data *osi_core, { int ret = -1; + if ((dma_routing_enable == OSI_ENABLE) && + (osi_core->dcs_en != OSI_ENABLE)) { + osd_err(osi_core->osd, "dma routing enabled but dcs disabled in DT\n"); + return ret; + } + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->update_mac_addr_low_high_reg != OSI_NULL)) { ret = osi_core->ops->update_mac_addr_low_high_reg( @@ -442,6 +448,12 @@ int osi_config_l3_filters(struct osi_core_priv_data *osi_core, { int ret = -1; + if ((dma_routing_enable == OSI_ENABLE) && + (osi_core->dcs_en != OSI_ENABLE)) { + osd_err(osi_core->osd, "dma routing enabled but dcs disabled in DT\n"); + return ret; + } + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->config_l3_filters != OSI_NULL)) { ret = osi_core->ops->config_l3_filters(osi_core, filter_no, @@ -495,6 +507,12 @@ int osi_config_l4_filters(struct osi_core_priv_data *osi_core, { int ret = -1; + if ((dma_routing_enable == OSI_ENABLE) && + (osi_core->dcs_en != OSI_ENABLE)) { + osd_err(osi_core->osd, "dma routing enabled but dcs disabled in DT\n"); + return ret; + } + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->config_l4_filters != OSI_NULL)) { ret = osi_core->ops->config_l4_filters(osi_core, filter_no, From cd46b808db01f94f75f601a86ded9e3905dafd64 Mon Sep 17 00:00:00 2001 From: Mohit Dhingra <mdhingra@nvidia.com> Date: Fri, 12 Jul 2019 15:09:43 +0530 Subject: [PATCH 029/458] nvethernetrm: fix macro name ESQC-9844 Change-Id: If0b0311962c2bf0b676aa464aed44183dabc058f Signed-off-by: Mohit Dhingra <mdhingra@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2152300 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/osi_common.h b/include/osi_common.h index 5f9d46a..4798024 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -48,7 +48,7 @@ #ifndef ULONG_MAX #define ULONG_MAX (~0UL) #endif -#ifndef UNIT_MAX +#ifndef UINT_MAX #define UINT_MAX (~0U) #endif From c70f77ed2ea47ad8f0811580f9fbb2e74373ef62 Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Thu, 20 Jun 2019 20:55:51 +0530 Subject: [PATCH 030/458] Nvethernetrm: update OSI interface APIs Issue: Some OSI interface function return void Fix: All OSI interface functions should return -1 if argument validation failed Bug 200512422 Change-Id: I7dead9b69a3853d815549959c9a14723ccfdc131 Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2140378 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_core.h | 41 ++++--- include/osi_dma.h | 83 ++++++------- osi/core/osi_core.c | 272 +++++++++++++++++++---------------------- osi/dma/osi_dma.c | 132 +++++++++++++++----- osi/dma/osi_dma_txrx.c | 48 +++++--- 5 files changed, 326 insertions(+), 250 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index ac0392a..c2cb041 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -346,10 +346,10 @@ int osi_poll_for_swr(struct osi_core_priv_data *osi_core); * 1) OSD layer needs get the AXI CBB clock rate with OSD clock API * (ex - clk_get_rate()) * - * Return: None + * Return: 0 - success, -1 - failure */ -void osi_set_mdc_clk_rate(struct osi_core_priv_data *osi_core, - unsigned long csr_clk_rate); +int osi_set_mdc_clk_rate(struct osi_core_priv_data *osi_core, + unsigned long csr_clk_rate); /** * osi_hw_core_init - EQOS MAC, MTL and common DMA initialization. @@ -383,9 +383,9 @@ int osi_hw_core_init(struct osi_core_priv_data *osi_core, * * Protection: None * - * Return: None + * Return: 0 - success, -1 - failure */ -void osi_start_mac(struct osi_core_priv_data *osi_core); +int osi_start_mac(struct osi_core_priv_data *osi_core); /** * osi_stop_mac - Stop MAC Tx/Rx engine @@ -398,9 +398,9 @@ void osi_start_mac(struct osi_core_priv_data *osi_core); * * Protection: None * - * Return: None + * Return: 0 - success, -1 - failure */ -void osi_stop_mac(struct osi_core_priv_data *osi_core); +int osi_stop_mac(struct osi_core_priv_data *osi_core); /** * osi_common_isr - Common ISR. @@ -417,7 +417,7 @@ void osi_stop_mac(struct osi_core_priv_data *osi_core); * * Return: 0 - success, -1 - failure */ -void osi_common_isr(struct osi_core_priv_data *osi_core); +int osi_common_isr(struct osi_core_priv_data *osi_core); /** * osi_set_mode - Set FD/HD mode. @@ -432,9 +432,9 @@ void osi_common_isr(struct osi_core_priv_data *osi_core); * * Protection: None * - * Return: NONE + * Return: 0 - success, -1 - failure */ -void osi_set_mode(struct osi_core_priv_data *osi_core, int mode); +int osi_set_mode(struct osi_core_priv_data *osi_core, int mode); /** * osi_set_speed - Set operating speed. @@ -449,9 +449,9 @@ void osi_set_mode(struct osi_core_priv_data *osi_core, int mode); * * Protection: None * - * Return: NONE + * Return: 0 - success, -1 - failure */ -void osi_set_speed(struct osi_core_priv_data *osi_core, int speed); +int osi_set_speed(struct osi_core_priv_data *osi_core, int speed); /** * osi_pad_calibrate - PAD calibration @@ -1092,12 +1092,13 @@ int osi_adjust_time(struct osi_core_priv_data *osi_core, long delta); * * Protection: None * - * Return: None (sec and nsec stores the read seconds and nanoseconds - * values from MAC) + * Return: 0 - success, -1 - failure + * (sec and nsec stores the read seconds and nanoseconds + * values from MAC if success) */ -void osi_get_systime_from_mac(struct osi_core_priv_data *osi_core, - unsigned int *sec, - unsigned int *nsec); +int osi_get_systime_from_mac(struct osi_core_priv_data *osi_core, + unsigned int *sec, + unsigned int *nsec); /** * osi_ptp_configuration - Configure PTP * @osi: OSI private data structure. @@ -1121,9 +1122,9 @@ void osi_get_systime_from_mac(struct osi_core_priv_data *osi_core, * * Protection: None * - * Return: None + * Return: 0 - success, -1 - failure */ -void osi_ptp_configuration(struct osi_core_priv_data *osi_core, - unsigned int enable); +int osi_ptp_configuration(struct osi_core_priv_data *osi_core, + unsigned int enable); #endif /* OSI_CORE_H */ diff --git a/include/osi_dma.h b/include/osi_dma.h index f09d0ee..4e3ca32 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -312,10 +312,10 @@ struct osi_dma_priv_data { * * Protection: None. * - * Return: None. + * Return: 0 - success , -1 - failure */ -void osi_disable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, - unsigned int chan); +int osi_disable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, + unsigned int chan); /** * osi_enable_chan_tx_intr - Enable DMA Tx channel interrupts. @@ -332,10 +332,10 @@ void osi_disable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, * * Protection: None. * - * Return: None. + * Return: 0 - success , -1 - failure */ -void osi_enable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, - unsigned int chan); +int osi_enable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, + unsigned int chan); /** * osi_disable_chan_rx_intr - Disable DMA Rx channel interrupts. @@ -352,10 +352,10 @@ void osi_enable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, * * Protection: None. * - * Return: None. + * Return: 0 - success , -1 - failure */ -void osi_disable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, - unsigned int chan); +int osi_disable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, + unsigned int chan); /** * osi_enable_chan_rx_intr - Enable DMA Rx channel interrupts. @@ -372,10 +372,10 @@ void osi_disable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, * * Protection: None. * - * Return: None. + * Return: 0 - success , -1 - failure */ -void osi_enable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, - unsigned int chan); +int osi_enable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, + unsigned int chan); /** * osi_clear_tx_intr - Handles Tx interrupt source. @@ -390,10 +390,10 @@ void osi_enable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, * * Protection: None. * - * Return: None. + * Return: 0 - success , -1 - failure */ -void osi_clear_tx_intr(struct osi_dma_priv_data *osi_dma, - unsigned int chan); +int osi_clear_tx_intr(struct osi_dma_priv_data *osi_dma, + unsigned int chan); /** * osi_clear_rx_intr - Handles Rx interrupt source. @@ -410,10 +410,10 @@ void osi_clear_tx_intr(struct osi_dma_priv_data *osi_dma, * * Protection: None. * - * Return: None. + * Return: 0 - success , -1 - failure */ -void osi_clear_rx_intr(struct osi_dma_priv_data *osi_dma, - unsigned int chan); +int osi_clear_rx_intr(struct osi_dma_priv_data *osi_dma, + unsigned int chan); /** * osi_start_dma - Start DMA @@ -428,10 +428,10 @@ void osi_clear_rx_intr(struct osi_dma_priv_data *osi_dma, * * Protection: None * - * Return: None + * Return: 0 - success , -1 - failure */ -void osi_start_dma(struct osi_dma_priv_data *osi_dma, - unsigned int chan); +int osi_start_dma(struct osi_dma_priv_data *osi_dma, + unsigned int chan); /** * osi_stop_dma - Stop DMA @@ -445,10 +445,11 @@ void osi_start_dma(struct osi_dma_priv_data *osi_dma, * 2) DMA HW init need to be completed successfully, see osi_hw_dma_init * * Protection: None - * Return: None + * + * Return: 0 - success , -1 - failure */ -void osi_stop_dma(struct osi_dma_priv_data *osi_dma, - unsigned int chan); +int osi_stop_dma(struct osi_dma_priv_data *osi_dma, + unsigned int chan); /** * osi_get_refill_rx_desc_cnt - Rx descriptors count that needs to refill. @@ -480,11 +481,11 @@ unsigned int osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring); * * Protection: None. * - * Return: None. + * Return: 0 - success , -1 - failure */ -void osi_rx_dma_desc_init(struct osi_rx_swcx *rx_swcx, - struct osi_rx_desc *rx_desc, - unsigned int use_riwt); +int osi_rx_dma_desc_init(struct osi_rx_swcx *rx_swcx, + struct osi_rx_desc *rx_desc, + unsigned int use_riwt); /** * osi_update_rx_tailptr - Updates DMA Rx ring tail pointer @@ -500,11 +501,11 @@ void osi_rx_dma_desc_init(struct osi_rx_swcx *rx_swcx, * * Protection: None. * - * Return: None. + * Return: 0 - success , -1 - failure */ -void osi_update_rx_tailptr(struct osi_dma_priv_data *osi_dma, - struct osi_rx_ring *rx_ring, - unsigned int chan); +int osi_update_rx_tailptr(struct osi_dma_priv_data *osi_dma, + struct osi_rx_ring *rx_ring, + unsigned int chan); /** * osi_set_rx_buf_len - Updates rx buffer length. @@ -519,9 +520,9 @@ void osi_update_rx_tailptr(struct osi_dma_priv_data *osi_dma, * * Protection: None. * - * Return: None. + * Return: 0 - success , -1 - failure */ -void osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma); +int osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma); /** * osi_hw_transmit - Initialize Tx DMA descriptors for a channel @@ -633,7 +634,7 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, * * Protection: None. * - * Return: None. + * Return: 0 - success, -1 - failure */ int osi_hw_dma_init(struct osi_dma_priv_data *osi_dma); @@ -649,9 +650,9 @@ int osi_hw_dma_init(struct osi_dma_priv_data *osi_dma); * * Protection: None. * - * Return: None. + * Return: 0 - success, -1 - failure */ -void osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma); +int osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma); /** * osi_init_dma_ops - Initialize DMA operations @@ -680,9 +681,9 @@ void osi_init_dma_ops(struct osi_dma_priv_data *osi_dma); * * Protection: None * - * Return: None + * Return: 0 - success, -1 - failure */ -void osi_clear_tx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); +int osi_clear_tx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); /** * osi_clear_rx_pkt_err_stats - Clear rx packet error stats. @@ -697,7 +698,7 @@ void osi_clear_tx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); * * Protection: None * - * Return: None + * Return: 0 - success, -1 - failure */ -void osi_clear_rx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); +int osi_clear_rx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); #endif /* OSI_DMA_H */ diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index ceac067..3cac35a 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -162,235 +162,226 @@ void osi_init_core_ops(struct osi_core_priv_data *osi_core) int osi_poll_for_swr(struct osi_core_priv_data *osi_core) { - int ret = 0; - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->poll_for_swr != OSI_NULL)) { - ret = osi_core->ops->poll_for_swr(osi_core->base); + return osi_core->ops->poll_for_swr(osi_core->base); } - - return ret; + return -1; } -void osi_set_mdc_clk_rate(struct osi_core_priv_data *osi_core, - unsigned long csr_clk_rate) +int osi_set_mdc_clk_rate(struct osi_core_priv_data *osi_core, + unsigned long csr_clk_rate) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->set_mdc_clk_rate != OSI_NULL)) { osi_core->ops->set_mdc_clk_rate(osi_core, csr_clk_rate); + return 0; } + + return -1; } int osi_hw_core_init(struct osi_core_priv_data *osi_core, unsigned int tx_fifo_size, unsigned int rx_fifo_size) { - int ret = 0; - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->core_init != OSI_NULL)) { - ret = osi_core->ops->core_init(osi_core, tx_fifo_size, - rx_fifo_size); + return osi_core->ops->core_init(osi_core, tx_fifo_size, + rx_fifo_size); } - return ret; + return -1; } -void osi_start_mac(struct osi_core_priv_data *osi_core) +int osi_start_mac(struct osi_core_priv_data *osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->start_mac != OSI_NULL)) { osi_core->ops->start_mac(osi_core->base); + return 0; } + + return -1; } -void osi_stop_mac(struct osi_core_priv_data *osi_core) +int osi_stop_mac(struct osi_core_priv_data *osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->stop_mac != OSI_NULL)) { osi_core->ops->stop_mac(osi_core->base); + return 0; } + + return -1; } -void osi_common_isr(struct osi_core_priv_data *osi_core) +int osi_common_isr(struct osi_core_priv_data *osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->handle_common_intr != OSI_NULL)) { osi_core->ops->handle_common_intr(osi_core); + return 0; } + + return -1; } -void osi_set_mode(struct osi_core_priv_data *osi_core, int mode) +int osi_set_mode(struct osi_core_priv_data *osi_core, int mode) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->set_mode != OSI_NULL)) { osi_core->ops->set_mode(osi_core->base, mode); + return 0; } + + return -1; } -void osi_set_speed(struct osi_core_priv_data *osi_core, int speed) +int osi_set_speed(struct osi_core_priv_data *osi_core, int speed) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->set_speed != OSI_NULL)) { osi_core->ops->set_speed(osi_core->base, speed); + return 0; } + + return -1; } int osi_pad_calibrate(struct osi_core_priv_data *osi_core) { - int ret = 0; - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->pad_calibrate != OSI_NULL)) { - ret = osi_core->ops->pad_calibrate(osi_core); + return osi_core->ops->pad_calibrate(osi_core); } - return ret; + return -1; } int osi_flush_mtl_tx_queue(struct osi_core_priv_data *osi_core, unsigned int qinx) { - int ret = 0; - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->flush_mtl_tx_queue != OSI_NULL)) { - ret = osi_core->ops->flush_mtl_tx_queue(osi_core->base, qinx); + return osi_core->ops->flush_mtl_tx_queue(osi_core->base, qinx); } - return ret; + return -1; } int osi_config_mac_loopback(struct osi_core_priv_data *osi_core, unsigned int lb_mode) { - int ret = -1; - /* Configure MAC LoopBack */ if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->config_mac_loopback != OSI_NULL)) { - ret = osi_core->ops->config_mac_loopback(osi_core->base, - lb_mode); + return osi_core->ops->config_mac_loopback(osi_core->base, + lb_mode); } - return ret; + return -1; } int osi_set_avb(struct osi_core_priv_data *osi_core, struct osi_core_avb_algorithm *avb) { - int ret = -1; - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->set_avb_algorithm != OSI_NULL)) { - ret = osi_core->ops->set_avb_algorithm(osi_core, avb); + return osi_core->ops->set_avb_algorithm(osi_core, avb); } - return ret; + return -1; } int osi_get_avb(struct osi_core_priv_data *osi_core, struct osi_core_avb_algorithm *avb) { - int ret = -1; - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->get_avb_algorithm != OSI_NULL)) { - ret = osi_core->ops->get_avb_algorithm(osi_core, avb); + return osi_core->ops->get_avb_algorithm(osi_core, avb); } - return ret; + return -1; } int osi_configure_txstatus(struct osi_core_priv_data *osi_core, unsigned int tx_status) { - int ret = -1; - /* Configure Drop Transmit Status */ if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->config_tx_status != OSI_NULL)) { - ret = osi_core->ops->config_tx_status(osi_core->base, - tx_status); + return osi_core->ops->config_tx_status(osi_core->base, + tx_status); } - return ret; + return -1; } int osi_config_fw_err_pkts(struct osi_core_priv_data *osi_core, unsigned int qinx, unsigned int fw_err) { - int ret = -1; - /* Configure Forwarding of Error packets */ if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->config_fw_err_pkts != OSI_NULL)) { - ret = osi_core->ops->config_fw_err_pkts(osi_core->base, - qinx, fw_err); + return osi_core->ops->config_fw_err_pkts(osi_core->base, + qinx, fw_err); } - return ret; + return -1; } int osi_config_rx_crc_check(struct osi_core_priv_data *osi_core, unsigned int crc_chk) { - int ret = -1; - /* Configure CRC Checking for Received Packets */ if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->config_rx_crc_check != OSI_NULL)) { - ret = osi_core->ops->config_rx_crc_check(osi_core->base, - crc_chk); + return osi_core->ops->config_rx_crc_check(osi_core->base, + crc_chk); } - return ret; + return -1; } int osi_configure_flow_control(struct osi_core_priv_data *osi_core, unsigned int flw_ctrl) { - int ret = -1; - /* Configure Flow control settings */ if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->config_flow_control != OSI_NULL)) { - ret = osi_core->ops->config_flow_control(osi_core->base, - flw_ctrl); + return osi_core->ops->config_flow_control(osi_core->base, + flw_ctrl); } - return ret; + return -1; } int osi_config_arp_offload(struct osi_core_priv_data *osi_core, unsigned int flags, unsigned char *ip_addr) { - int ret = -1; - if (osi_core != OSI_NULL && osi_core->ops != OSI_NULL && osi_core->ops->config_arp_offload != OSI_NULL) { - ret = osi_core->ops->config_arp_offload(osi_core->mac_ver, - osi_core->base, - flags, ip_addr); + return osi_core->ops->config_arp_offload(osi_core->mac_ver, + osi_core->base, + flags, ip_addr); } - return ret; + return -1; } int osi_config_mac_pkt_filter_reg(struct osi_core_priv_data *osi_core, struct osi_filter pfilter) { - int ret = -1; - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->config_mac_pkt_filter_reg != OSI_NULL)) { osi_core->ops->config_mac_pkt_filter_reg(osi_core, pfilter); - ret = 0; + return 0; } - return ret; + return -1; } int osi_update_mac_addr_low_high_reg(struct osi_core_priv_data *osi_core, @@ -410,7 +401,7 @@ int osi_update_mac_addr_low_high_reg(struct osi_core_priv_data *osi_core, if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->update_mac_addr_low_high_reg != OSI_NULL)) { - ret = osi_core->ops->update_mac_addr_low_high_reg( + return osi_core->ops->update_mac_addr_low_high_reg( osi_core, index, value, @@ -420,21 +411,19 @@ int osi_update_mac_addr_low_high_reg(struct osi_core_priv_data *osi_core, src_dest); } - return ret; + return -1; } int osi_config_l3_l4_filter_enable(struct osi_core_priv_data *osi_core, unsigned int enable) { - int ret = -1; - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->config_l3_l4_filter_enable != OSI_NULL)) { - ret = osi_core->ops->config_l3_l4_filter_enable(osi_core->base, - enable); + return osi_core->ops->config_l3_l4_filter_enable(osi_core->base, + enable); } - return ret; + return -1; } int osi_config_l3_filters(struct osi_core_priv_data *osi_core, @@ -456,15 +445,16 @@ int osi_config_l3_filters(struct osi_core_priv_data *osi_core, if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->config_l3_filters != OSI_NULL)) { - ret = osi_core->ops->config_l3_filters(osi_core, filter_no, - enb_dis, ipv4_ipv6_match, - src_dst_addr_match, - perfect_inverse_match, - dma_routing_enable, - dma_chan); + return osi_core->ops->config_l3_filters(osi_core, filter_no, + enb_dis, + ipv4_ipv6_match, + src_dst_addr_match, + perfect_inverse_match, + dma_routing_enable, + dma_chan); } - return ret; + return -1; } int osi_update_ip4_addr(struct osi_core_priv_data *osi_core, @@ -472,28 +462,25 @@ int osi_update_ip4_addr(struct osi_core_priv_data *osi_core, unsigned char addr[], unsigned int src_dst_addr_match) { - int ret = -1; - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->update_ip4_addr != OSI_NULL)) { - ret = osi_core->ops->update_ip4_addr(osi_core, filter_no, - addr, src_dst_addr_match); + return osi_core->ops->update_ip4_addr(osi_core, filter_no, + addr, src_dst_addr_match); } - return ret; + return -1; } int osi_update_ip6_addr(struct osi_core_priv_data *osi_core, unsigned int filter_no, unsigned short addr[]) { - int ret = -1; - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->update_ip6_addr != OSI_NULL)) { - ret = osi_core->ops->update_ip6_addr(osi_core, filter_no, addr); + return osi_core->ops->update_ip6_addr(osi_core, filter_no, + addr); } - return ret; + return -1; } int osi_config_l4_filters(struct osi_core_priv_data *osi_core, @@ -515,31 +502,29 @@ int osi_config_l4_filters(struct osi_core_priv_data *osi_core, if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->config_l4_filters != OSI_NULL)) { - ret = osi_core->ops->config_l4_filters(osi_core, filter_no, - enb_dis, tcp_udp_match, - src_dst_port_match, - perfect_inverse_match, - dma_routing_enable, - dma_chan); + return osi_core->ops->config_l4_filters(osi_core, filter_no, + enb_dis, tcp_udp_match, + src_dst_port_match, + perfect_inverse_match, + dma_routing_enable, + dma_chan); } - return ret; + return -1; } int osi_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) { - int ret = -1; - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->update_l4_port_no != OSI_NULL)) { - ret = osi_core->ops->update_l4_port_no(osi_core, filter_no, - port_no, - src_dst_port_match); + return osi_core->ops->update_l4_port_no(osi_core, filter_no, + port_no, + src_dst_port_match); } - return ret; + return -1; } int osi_config_vlan_filtering(struct osi_core_priv_data *osi_core, @@ -547,75 +532,66 @@ int osi_config_vlan_filtering(struct osi_core_priv_data *osi_core, unsigned int perfect_hash_filtering, unsigned int perfect_inverse_match) { - int ret = -1; - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->config_vlan_filtering != OSI_NULL)) { - ret = osi_core->ops->config_vlan_filtering(osi_core, - filter_enb_dis, + return osi_core->ops->config_vlan_filtering( + osi_core, + filter_enb_dis, perfect_hash_filtering, perfect_inverse_match); } - return ret; + return -1; } int osi_config_l2_da_perfect_inverse_match(struct osi_core_priv_data *osi_core, unsigned int perfect_inverse_match) { - int ret = -1; - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->config_l2_da_perfect_inverse_match != OSI_NULL)) { - ret = osi_core->ops->config_l2_da_perfect_inverse_match( + return osi_core->ops->config_l2_da_perfect_inverse_match( osi_core->base, perfect_inverse_match); } - return ret; + return -1; } int osi_config_rxcsum_offload(struct osi_core_priv_data *osi_core, unsigned int enable) { - int ret = -1; - if (osi_core != OSI_NULL && osi_core->ops != OSI_NULL && osi_core->ops->config_rxcsum_offload != OSI_NULL) { - ret = osi_core->ops->config_rxcsum_offload(osi_core->base, - enable); + return osi_core->ops->config_rxcsum_offload(osi_core->base, + enable); } - return ret; + return -1; } int osi_update_vlan_id(struct osi_core_priv_data *osi_core, unsigned int vid) { - int ret = -1; - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->update_vlan_id != OSI_NULL && vid != 0U)) { - ret = osi_core->ops->update_vlan_id(osi_core->base, + return osi_core->ops->update_vlan_id(osi_core->base, vid); } - return ret; + return -1; } int osi_set_systime_to_mac(struct osi_core_priv_data *osi_core, unsigned int sec, unsigned int nsec) { - int ret = -1; - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->set_systime_to_mac != OSI_NULL)) { - ret = osi_core->ops->set_systime_to_mac(osi_core->base, - sec, - nsec); + (osi_core->ops->set_systime_to_mac != OSI_NULL)) { + return osi_core->ops->set_systime_to_mac(osi_core->base, + sec, + nsec); } - return ret; + return -1; } /** @@ -763,17 +739,19 @@ int osi_adjust_time(struct osi_core_priv_data *osi_core, long delta) return ret; } -void osi_get_systime_from_mac(struct osi_core_priv_data *osi_core, - unsigned int *sec, - unsigned int *nsec) +int osi_get_systime_from_mac(struct osi_core_priv_data *osi_core, + unsigned int *sec, + unsigned int *nsec) { unsigned long long ns = 0; unsigned long long temp = 0; unsigned long remain = 0; if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->adjust_systime != OSI_NULL)) { + (osi_core->ops->get_systime_from_mac != OSI_NULL)) { ns = osi_core->ops->get_systime_from_mac(osi_core->base); + } else { + return -1; } temp = div_u64_rem((unsigned long)ns, OSI_NSEC_PER_SEC, &remain); @@ -787,14 +765,24 @@ void osi_get_systime_from_mac(struct osi_core_priv_data *osi_core, } else { /* do nothing here */ } + + return 0; } -void osi_ptp_configuration(struct osi_core_priv_data *osi_core, - unsigned int enable) +int osi_ptp_configuration(struct osi_core_priv_data *osi_core, + unsigned int enable) { int ret = 0; unsigned long temp = 0, temp1 = 0; + if ((osi_core == OSI_NULL) || (osi_core->ops == OSI_NULL) || + (osi_core->ops->config_tscr == OSI_NULL) || + (osi_core->ops->config_ssir == OSI_NULL) || + (osi_core->ops->config_addend == OSI_NULL) || + (osi_core->ops->set_systime_to_mac == OSI_NULL)) { + return -1; + } + if (enable == OSI_DISABLE) { /* disable hw time stamping */ /* Program MAC_Timestamp_Control Register */ @@ -833,30 +821,28 @@ void osi_ptp_configuration(struct osi_core_priv_data *osi_core, osi_core->ptp_config.sec, osi_core->ptp_config.nsec); } + + return ret; } int osi_read_mmc(struct osi_core_priv_data *osi_core) { - int ret = -1; - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->read_mmc != OSI_NULL)) { osi_core->ops->read_mmc(osi_core); - ret = 0; + return 0; } - return ret; + return -1; } int osi_reset_mmc(struct osi_core_priv_data *osi_core) { - int ret = -1; - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->reset_mmc != OSI_NULL)) { osi_core->ops->reset_mmc(osi_core); - ret = 0; + return 0; } - return ret; + return -1; } diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 8093e9f..23e314e 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -38,8 +38,11 @@ int osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) unsigned int i, chan; int ret; - if (osi_dma->ops->init_dma_channel != OSI_NULL) { + if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && + osi_dma->ops->init_dma_channel != OSI_NULL) { osi_dma->ops->init_dma_channel(osi_dma); + } else { + return -1; } ret = dma_desc_init(osi_dma); @@ -56,88 +59,132 @@ int osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) osi_start_dma(osi_dma, chan); } - return 0; + return ret; } -void osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma) +/** + * osi_hw_deinit - De-init the HW + * @osi: OSI private data structure. + * + * Algorithm: + * 1) Stop the DMA + * 2) free all allocated resources. + * + * Dependencies: None + * + * Protection: None + * + * Return: 0 - Success, -ve - failure + */ +int osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma) { unsigned int i; + if (osi_dma == OSI_NULL) { + return -1; + } + for (i = 0; i < osi_dma->num_dma_chans; i++) { osi_stop_dma(osi_dma, osi_dma->dma_chans[i]); } + + return 0; } -void osi_disable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, - unsigned int chan) +int osi_disable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, + unsigned int chan) { if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && (osi_dma->ops->disable_chan_tx_intr != OSI_NULL)) { osi_dma->ops->disable_chan_tx_intr(osi_dma->base, chan); + return 0; } + + return -1; } -void osi_enable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, - unsigned int chan) +int osi_enable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, + unsigned int chan) { if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && (osi_dma->ops->enable_chan_tx_intr != OSI_NULL)) { osi_dma->ops->enable_chan_tx_intr(osi_dma->base, chan); + return 0; } + + return -1; } -void osi_disable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, - unsigned int chan) +int osi_disable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, + unsigned int chan) { if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && (osi_dma->ops->disable_chan_rx_intr != OSI_NULL)) { osi_dma->ops->disable_chan_rx_intr(osi_dma->base, chan); + return 0; } + + return -1; } -void osi_enable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, - unsigned int chan) +int osi_enable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, + unsigned int chan) { if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && (osi_dma->ops->enable_chan_rx_intr != OSI_NULL)) { osi_dma->ops->enable_chan_rx_intr(osi_dma->base, chan); + return 0; } + + return -1; } -void osi_clear_tx_intr(struct osi_dma_priv_data *osi_dma, - unsigned int chan) +int osi_clear_tx_intr(struct osi_dma_priv_data *osi_dma, + unsigned int chan) { if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && (osi_dma->ops->clear_tx_intr != OSI_NULL)) { osi_dma->ops->clear_tx_intr(osi_dma->base, chan); + return 0; } + + return -1; } -void osi_clear_rx_intr(struct osi_dma_priv_data *osi_dma, - unsigned int chan) +int osi_clear_rx_intr(struct osi_dma_priv_data *osi_dma, + unsigned int chan) { if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && (osi_dma->ops->clear_rx_intr != OSI_NULL)) { osi_dma->ops->clear_rx_intr(osi_dma->base, chan); + return 0; } + + return -1; } -void osi_start_dma(struct osi_dma_priv_data *osi_dma, +int osi_start_dma(struct osi_dma_priv_data *osi_dma, unsigned int chan) { if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && (osi_dma->ops->start_dma != OSI_NULL)) { osi_dma->ops->start_dma(osi_dma->base, chan); + return 0; } + + return -1; } -void osi_stop_dma(struct osi_dma_priv_data *osi_dma, - unsigned int chan) +int osi_stop_dma(struct osi_dma_priv_data *osi_dma, + unsigned int chan) { if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && (osi_dma->ops->stop_dma != OSI_NULL)) { osi_dma->ops->stop_dma(osi_dma->base, chan); + return 0; } + + return -1; } unsigned int osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring) @@ -145,24 +192,43 @@ unsigned int osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring) return (rx_ring->cur_rx_idx - rx_ring->refill_idx) & (RX_DESC_CNT - 1U); } -void osi_rx_dma_desc_init(struct osi_rx_swcx *rx_swcx, - struct osi_rx_desc *rx_desc, - unsigned int use_riwt) +int osi_rx_dma_desc_init(struct osi_rx_swcx *rx_swcx, + struct osi_rx_desc *rx_desc, + unsigned int use_riwt) { - rx_desc->rdes0 = (unsigned int)L32(rx_swcx->buf_phy_addr); - rx_desc->rdes1 = (unsigned int)H32(rx_swcx->buf_phy_addr); - rx_desc->rdes2 = 0; - rx_desc->rdes3 = (RDES3_OWN | RDES3_IOC | RDES3_B1V); + /* for CERT-C error */ + unsigned long temp; + if (rx_swcx != OSI_NULL && rx_desc != OSI_NULL) { + temp = L32(rx_swcx->buf_phy_addr); + if (temp > UINT_MAX) { + /* error case do nothing */ + } else { + rx_desc->rdes0 = (unsigned int)temp; + } + + temp = H32(rx_swcx->buf_phy_addr); + if (temp > UINT_MAX) { + /* error case do nothing */ + } else { + rx_desc->rdes1 = (unsigned int)temp; + } + rx_desc->rdes2 = 0; + rx_desc->rdes3 = (RDES3_OWN | RDES3_IOC | RDES3_B1V); + } else { + return -1; + } /* reset IOC bit if RWIT is enabled */ if (use_riwt == OSI_ENABLE) { rx_desc->rdes3 &= ~RDES3_IOC; } + + return 0; } -void osi_update_rx_tailptr(struct osi_dma_priv_data *osi_dma, - struct osi_rx_ring *rx_ring, - unsigned int chan) +int osi_update_rx_tailptr(struct osi_dma_priv_data *osi_dma, + struct osi_rx_ring *rx_ring, + unsigned int chan) { unsigned long tailptr = 0; unsigned int refill_idx = rx_ring->refill_idx; @@ -174,13 +240,21 @@ void osi_update_rx_tailptr(struct osi_dma_priv_data *osi_dma, if (osi_dma != OSI_NULL && osi_dma->ops != OSI_NULL && osi_dma->ops->update_rx_tailptr != OSI_NULL) { osi_dma->ops->update_rx_tailptr(osi_dma->base, chan, tailptr); + } else { + return -1; } + + return 0; } -void osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) +int osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) { if (osi_dma != OSI_NULL && osi_dma->ops != OSI_NULL && osi_dma->ops->set_rx_buf_len != OSI_NULL) { osi_dma->ops->set_rx_buf_len(osi_dma); + } else { + return -1; } + + return 0; } diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index b83a30f..84a05ef 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -383,21 +383,28 @@ static inline void get_tx_err_stats(struct osi_tx_desc *tx_desc, * * Protection: None * - * Return: None + * Return: 0 - success, -1 - failure. */ -void osi_clear_tx_pkt_err_stats(struct osi_dma_priv_data *osi_dma) +int osi_clear_tx_pkt_err_stats(struct osi_dma_priv_data *osi_dma) { - /* Reset tx packet errors */ - osi_dma->pkt_err_stats.ip_header_error = 0U; - osi_dma->pkt_err_stats.jabber_timeout_error = 0U; - osi_dma->pkt_err_stats.pkt_flush_error = 0U; - osi_dma->pkt_err_stats.payload_cs_error = 0U; - osi_dma->pkt_err_stats.loss_of_carrier_error = 0U; - osi_dma->pkt_err_stats.no_carrier_error = 0U; - osi_dma->pkt_err_stats.late_collision_error = 0U; - osi_dma->pkt_err_stats.excessive_collision_error = 0U; - osi_dma->pkt_err_stats.excessive_deferal_error = 0U; - osi_dma->pkt_err_stats.underflow_error = 0U; + int ret = -1; + + if (osi_dma != OSI_NULL) { + /* Reset tx packet errors */ + osi_dma->pkt_err_stats.ip_header_error = 0U; + osi_dma->pkt_err_stats.jabber_timeout_error = 0U; + osi_dma->pkt_err_stats.pkt_flush_error = 0U; + osi_dma->pkt_err_stats.payload_cs_error = 0U; + osi_dma->pkt_err_stats.loss_of_carrier_error = 0U; + osi_dma->pkt_err_stats.no_carrier_error = 0U; + osi_dma->pkt_err_stats.late_collision_error = 0U; + osi_dma->pkt_err_stats.excessive_collision_error = 0U; + osi_dma->pkt_err_stats.excessive_deferal_error = 0U; + osi_dma->pkt_err_stats.underflow_error = 0U; + ret = 0; + } + + return ret; } /** @@ -413,12 +420,19 @@ void osi_clear_tx_pkt_err_stats(struct osi_dma_priv_data *osi_dma) * * Protection: None * - * Return: None + * Return: 0 - success, -1 - failure. */ -void osi_clear_rx_pkt_err_stats(struct osi_dma_priv_data *osi_dma) +int osi_clear_rx_pkt_err_stats(struct osi_dma_priv_data *osi_dma) { - /* Reset Rx packet errors */ - osi_dma->pkt_err_stats.rx_crc_error = 0U; + int ret = -1; + + if (osi_dma != OSI_NULL) { + /* Reset Rx packet errors */ + osi_dma->pkt_err_stats.rx_crc_error = 0U; + ret = 0; + } + + return ret; } /** From 4b34e446de855125437316afbe4787c68d227ee3 Mon Sep 17 00:00:00 2001 From: Poojan Shah <poojans@nvidia.com> Date: Tue, 16 Jul 2019 10:44:02 -0700 Subject: [PATCH 031/458] osi: Fix warnings for unused variable Also enable NV_COMPONENT_STRICT_WARNINGS_qnx_64 tmake flag to impose warnings as errors. Bug 2331640 Change-Id: Ideaf179dde9c78bc0dd90a3c4dc947525ab834f3 Reviewed-on: https://git-master.nvidia.com/r/2154253 Tested-by: Poojan Shah <poojans@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/Makefile.tmk | 2 ++ osi/dma/Makefile.tmk | 2 ++ osi/dma/osi_dma_txrx.c | 2 -- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/osi/core/Makefile.tmk b/osi/core/Makefile.tmk index f322e53..b883bd8 100644 --- a/osi/core/Makefile.tmk +++ b/osi/core/Makefile.tmk @@ -25,6 +25,8 @@ 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 := \ diff --git a/osi/dma/Makefile.tmk b/osi/dma/Makefile.tmk index da32328..a4bd2cd 100644 --- a/osi/dma/Makefile.tmk +++ b/osi/dma/Makefile.tmk @@ -25,6 +25,8 @@ 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 := \ diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 84a05ef..16ac2b7 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -874,7 +874,6 @@ static void tx_dma_desc_init(struct osi_dma_priv_data *osi_dma) { struct osi_tx_ring *tx_ring = OSI_NULL; struct osi_tx_desc *tx_desc = OSI_NULL; - struct osi_tx_swcx *tx_swcx = OSI_NULL; struct osi_dma_chan_ops *ops = osi_dma->ops; unsigned int chan = 0; unsigned int i; @@ -884,7 +883,6 @@ static void tx_dma_desc_init(struct osi_dma_priv_data *osi_dma) tx_ring = osi_dma->tx_ring[chan]; tx_desc = tx_ring->tx_desc; - tx_swcx = tx_ring->tx_swcx; /* FIXME: does it require */ tx_desc->tdes0 = 0; From a7c9ae737de46b55f3eca6bd20a7d1109d23e15d Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Sat, 29 Jun 2019 23:38:04 +0530 Subject: [PATCH 032/458] nvethernetrm: add MAC deinit support Add support to de-initialize the MAC Bug 200512422 Change-Id: I7d9f21aed773f3b06043892fb9a68ce042abcf1c Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2145725 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_core.h | 20 ++++++++++++++++++-- osi/core/eqos_core.c | 19 +++++++++++++++++++ osi/core/libnvethernetrm.export | 1 + osi/core/osi_core.c | 11 +++++++++++ 4 files changed, 49 insertions(+), 2 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index c2cb041..98a2f8e 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -119,6 +119,7 @@ struct osi_core_avb_algorithm { * struct osi_core_ops - Core (MAC & MTL) operations. * @poll_for_swr: Called to poll for software reset bit. * @core_init: Called to initialize MAC and MTL registers. + * @core_deinit: Called to deinitialize MAC and MTL registers. * @start_mac: Called to start MAC Tx and Rx engine. * @stop_mac: Called to stop MAC Tx and Rx engine. * @handle_common_intr: Called to handle common interrupt. @@ -162,6 +163,7 @@ struct osi_core_ops { int (*core_init)(struct osi_core_priv_data *osi_core, unsigned int tx_fifo_size, unsigned int rx_fifo_size); + void (*core_deinit)(struct osi_core_priv_data *osi_core); void (*start_mac)(void *addr); void (*stop_mac)(void *addr); void (*handle_common_intr)(struct osi_core_priv_data *osi_core); @@ -372,8 +374,22 @@ int osi_hw_core_init(struct osi_core_priv_data *osi_core, unsigned int rx_fifo_size); /** - * osi_start_mac - Start MAC Tx/Rx engine - * @osi_core: OSI core private data. + * osi_hw_core_deinit - EQOS MAC deinitialization. + * @osi: OSI core private data structure. + * + * Algorithm: Stops MAC transmisson and reception. + * + * Dependencies: MAC has to be out of reset. + * + * Protection: None + * + * Return: 0 - success, -1 - failure + */ +int osi_hw_core_deinit(struct osi_core_priv_data *osi_core); + +/** + * osi_start_mac - Start MAC Tx/Rx engine + * @osi_core: OSI core private data. * * Algorimthm: Enable MAC Tx and Rx engine. * diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index f761ad3..6d4965c 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -2937,9 +2937,28 @@ static void eqos_config_ssir(void *addr, unsigned int ptp_clock) osi_writel(val, (unsigned char *)addr + EQOS_MAC_SSIR); } +/** + * eqos_core_deinit - EQOS MAC core deinitialization + * @osi_core: OSI core private data structure. + * + * Algorithm: This function will take care of deinitializing MAC + * + * Dependencies: Required clks and resets has to be enabled + * + * Protection: None + * + * Return: None + */ +static void eqos_core_deinit(struct osi_core_priv_data *osi_core) +{ + /* Stop the MAC by disabling both MAC Tx and Rx */ + eqos_stop_mac(osi_core->base); +} + static struct osi_core_ops eqos_core_ops = { .poll_for_swr = eqos_poll_for_swr, .core_init = eqos_core_init, + .core_deinit = eqos_core_deinit, .start_mac = eqos_start_mac, .stop_mac = eqos_stop_mac, .handle_common_intr = eqos_handle_common_intr, diff --git a/osi/core/libnvethernetrm.export b/osi/core/libnvethernetrm.export index cc158d5..39faedd 100644 --- a/osi/core/libnvethernetrm.export +++ b/osi/core/libnvethernetrm.export @@ -29,6 +29,7 @@ osi_read_phy_reg osi_poll_for_swr osi_set_mdc_clk_rate osi_hw_core_init +osi_hw_core_deinit osi_start_mac osi_stop_mac osi_common_isr diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 3cac35a..c4236b6 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -194,6 +194,17 @@ int osi_hw_core_init(struct osi_core_priv_data *osi_core, return -1; } +int osi_hw_core_deinit(struct osi_core_priv_data *osi_core) +{ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->core_deinit != OSI_NULL)) { + osi_core->ops->core_deinit(osi_core); + return 0; + } + + return -1; +} + int osi_start_mac(struct osi_core_priv_data *osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && From c1fabf78cc4c53610096774513c885a5549aed29 Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Fri, 19 Jul 2019 14:52:29 +0530 Subject: [PATCH 033/458] nvethernetrm: use correct macro OSI_EQOS_MAX_NUM_QUEUES should be used instead of OSI_EQOS_MAX_NUM_CHANS Bug 200512422 Change-Id: Ie20515991a628fa6c4c0a17033a6bac7facbfff3 Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2156971 Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_core.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 98a2f8e..061fb29 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -302,9 +302,9 @@ struct osi_core_priv_data { void *osd; struct osi_core_ops *ops; unsigned int num_mtl_queues; - unsigned int mtl_queues[OSI_EQOS_MAX_NUM_CHANS]; - unsigned int rxq_ctrl[OSI_EQOS_MAX_NUM_CHANS]; - unsigned int rxq_prio[OSI_EQOS_MAX_NUM_CHANS]; + unsigned int mtl_queues[OSI_EQOS_MAX_NUM_QUEUES]; + unsigned int rxq_ctrl[OSI_EQOS_MAX_NUM_QUEUES]; + unsigned int rxq_prio[OSI_EQOS_MAX_NUM_QUEUES]; unsigned int mac; unsigned int mac_ver; unsigned int mdc_cr; From e729268516e844e88273a10eb0576c45e7964a68 Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Tue, 23 Jul 2019 17:26:32 +0530 Subject: [PATCH 034/458] nvethernetrm: fix null pointer check Issue: osi_core NULL pointer not validated before dereferencing Fix: check for valid osi_core pointer. Bug 200512422 Change-Id: Ie23f6d3c01d2967738ca048475e1046d3d856efd Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2159532 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_core.h | 2 +- include/osi_dma.h | 4 ++-- osi/core/osi_core.c | 31 +++++++++++++++++++++++++++---- osi/dma/osi_dma.c | 5 ++++- 4 files changed, 34 insertions(+), 8 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 061fb29..5394ff3 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -1039,7 +1039,7 @@ int osi_reset_mmc(struct osi_core_priv_data *osi_core); */ int osi_read_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, unsigned int phyreg); -void osi_init_core_ops(struct osi_core_priv_data *osi_core); +int osi_init_core_ops(struct osi_core_priv_data *osi_core); /** * osi_set_systime_to_mac - Handles setting of system time. diff --git a/include/osi_dma.h b/include/osi_dma.h index 4e3ca32..6825ba8 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -664,9 +664,9 @@ int osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma); * * Protection: None. * - * Return: None. + * Return: 0 - success, -1 - failure */ -void osi_init_dma_ops(struct osi_dma_priv_data *osi_dma); +int osi_init_dma_ops(struct osi_dma_priv_data *osi_dma); /** * osi_clear_tx_pkt_err_stats - Clear tx packet error stats. diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index c4236b6..95fde05 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -72,6 +72,10 @@ int osi_write_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, unsigned int mac_gmiidr; int ret = 0; + if (osi_core == OSI_NULL) { + return -1; + } + /* wait for any previous MII read/write operation to complete */ ret = poll_for_mii_idle(osi_core); if (ret < 0) { @@ -119,6 +123,10 @@ int osi_read_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, unsigned int data; int ret = 0; + if (osi_core == OSI_NULL) { + return -1; + } + /* wait for any previous MII read/write operation to complete */ ret = poll_for_mii_idle(osi_core); if (ret < 0) { @@ -152,12 +160,15 @@ int osi_read_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, return (int)data; } -void osi_init_core_ops(struct osi_core_priv_data *osi_core) +int osi_init_core_ops(struct osi_core_priv_data *osi_core) { if (osi_core->mac == OSI_MAC_HW_EQOS) { /* Get EQOS HW ops */ osi_core->ops = eqos_get_hw_core_ops(); + return 0; } + + return -1; } int osi_poll_for_swr(struct osi_core_priv_data *osi_core) @@ -404,13 +415,17 @@ int osi_update_mac_addr_low_high_reg(struct osi_core_priv_data *osi_core, { int ret = -1; + if (osi_core == OSI_NULL) { + return ret; + } + if ((dma_routing_enable == OSI_ENABLE) && (osi_core->dcs_en != OSI_ENABLE)) { osd_err(osi_core->osd, "dma routing enabled but dcs disabled in DT\n"); return ret; } - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + if ((osi_core->ops != OSI_NULL) && (osi_core->ops->update_mac_addr_low_high_reg != OSI_NULL)) { return osi_core->ops->update_mac_addr_low_high_reg( osi_core, @@ -448,13 +463,17 @@ int osi_config_l3_filters(struct osi_core_priv_data *osi_core, { int ret = -1; + if (osi_core == OSI_NULL) { + return ret; + } + if ((dma_routing_enable == OSI_ENABLE) && (osi_core->dcs_en != OSI_ENABLE)) { osd_err(osi_core->osd, "dma routing enabled but dcs disabled in DT\n"); return ret; } - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + if ((osi_core->ops != OSI_NULL) && (osi_core->ops->config_l3_filters != OSI_NULL)) { return osi_core->ops->config_l3_filters(osi_core, filter_no, enb_dis, @@ -505,13 +524,17 @@ int osi_config_l4_filters(struct osi_core_priv_data *osi_core, { int ret = -1; + if (osi_core == OSI_NULL) { + return ret; + } + if ((dma_routing_enable == OSI_ENABLE) && (osi_core->dcs_en != OSI_ENABLE)) { osd_err(osi_core->osd, "dma routing enabled but dcs disabled in DT\n"); return ret; } - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + if ((osi_core->ops != OSI_NULL) && (osi_core->ops->config_l4_filters != OSI_NULL)) { return osi_core->ops->config_l4_filters(osi_core, filter_no, enb_dis, tcp_udp_match, diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 23e314e..669be99 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -25,12 +25,15 @@ extern int dma_desc_init(struct osi_dma_priv_data *osi_dma); extern struct osi_dma_chan_ops *eqos_get_dma_chan_ops(void); -void osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) +int osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) { if (osi_dma->mac == OSI_MAC_HW_EQOS) { /* Get EQOS HW ops */ osi_dma->ops = eqos_get_dma_chan_ops(); + return 0; } + + return -1; } int osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) From abbd5785a0c0ddd70e16f5ff620121f0cdfda510 Mon Sep 17 00:00:00 2001 From: Srinivas Ramachandran <srinivasra@nvidia.com> Date: Mon, 29 Jul 2019 22:31:31 -0700 Subject: [PATCH 035/458] nvethernetrm: core: Fix argument passed for pad calibration Issue: Pad calibration failed when the OSI API function osi_pad_calibrate is invoked, but works when pad calibration is triggered internally in osi_hw_core_init. Issue is the OSI API passes incorrect argument for base address. Fix: Provide the correct base address in OSI interface API. Bug 200512422 Change-Id: I625f3269452e31e89fef07f960c80a2fd2024634 Signed-off-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2163995 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/osi_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 95fde05..e1f93be 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -275,7 +275,7 @@ int osi_pad_calibrate(struct osi_core_priv_data *osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->pad_calibrate != OSI_NULL)) { - return osi_core->ops->pad_calibrate(osi_core); + return osi_core->ops->pad_calibrate(osi_core->base); } return -1; From 176f049abdf001ddce84448ef162f19bcf3b4420 Mon Sep 17 00:00:00 2001 From: Srinivas Ramachandran <srinivasra@nvidia.com> Date: Fri, 14 Jun 2019 15:24:19 -0700 Subject: [PATCH 036/458] nvethernetrm: Implement external safety mechanism EQoS MAC version < 5.10 is not safety certified. To ensure some basic error handling situations, implement external error handling mechanism in the driver to periodically read and verify the current register content for certain critical registers, against the last written value. Bug 2594911 Change-Id: I1d7c01f89ad838ffe3ab1efd15126640ae9df775 Signed-off-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2136607 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_common.h | 76 +++++++++- include/osi_core.h | 33 +++++ include/osi_dma.h | 30 ++++ osi/core/eqos_core.c | 345 ++++++++++++++++++++++++++++++++++++------- osi/core/eqos_core.h | 78 ++++++++++ osi/core/osi_core.c | 20 ++- osi/dma/eqos_dma.c | 203 +++++++++++++++++++++++-- osi/dma/eqos_dma.h | 57 +++++++ osi/dma/osi_dma.c | 18 ++- 9 files changed, 788 insertions(+), 72 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index 4798024..0ff3b42 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -23,6 +23,9 @@ #ifndef OSI_COMMON_H #define OSI_COMMON_H +#define OSI_UNLOCKED 0x0U +#define OSI_LOCKED 0x1U + #define TEN_POWER_9 0x3B9ACA00U #define TWO_POWER_32 0x100000000ULL #define TWO_POWER_31 0x80000000U @@ -84,6 +87,11 @@ /* FIXME add logic based on HW version */ #define EQOS_MAX_MAC_ADDRESS_FILTER 128U #define EQOS_MAX_L3_L4_FILTER 8U +#define OSI_EQOS_MAX_NUM_CHANS 4U +#define OSI_EQOS_MAX_NUM_QUEUES 4U +/* 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 @@ -111,10 +119,6 @@ #define OSI_IP4_FILTER 0U #define OSI_IP6_FILTER 1U -/* FIXME add logic based on HW version */ -#define OSI_EQOS_MAX_NUM_CHANS 4U -#define OSI_EQOS_MAX_NUM_QUEUES 4U - #define OSI_BIT(nr) ((unsigned int)1 << (nr)) #define OSI_EQOS_MAC_4_10 0x41U @@ -359,6 +363,70 @@ struct osi_hw_features { unsigned int aux_snap_num; }; +/** + * osi_lock_init - Initialize lock to unlocked state. + * @lock - Pointer to lock to be initialized + * + * Algorithm: Set lock to unlocked state. + * + * Dependencies: None. + * + * Protection: None. + * + * Return: None. + */ +static inline void osi_lock_init(unsigned int *lock) +{ + *lock = OSI_UNLOCKED; +} + +/** + * osi_lock_irq_enabled - Spin lock. Busy loop till lock is acquired. + * @lock - Pointer to lock to be acquired. + * + * Algorithm: Atomic compare and swap operation till lock is held. + * + * Dependencies: 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. + * + * Protection: None. + * + * Return: None. + */ +static inline void osi_lock_irq_enabled(unsigned int *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. + */ + } +} + +/** + * osi_unlock_irq_enabled - Release lock. + * @lock - Pointer to lock to be released. + * + * Algorithm: Atomic compare and swap operation to release lock. + * + * Dependencies: Does not disable irq. Do not call this API to release any + * lock that is shared between top/bottom half. + * + * Protection: None. + * + * Return: None. + */ +static inline void osi_unlock_irq_enabled(unsigned int *lock) +{ + if (__sync_val_compare_and_swap(lock, OSI_LOCKED, OSI_UNLOCKED) != + OSI_LOCKED) { + /* Do nothing. Already unlocked */ + } +} + /** * osi_readl - Read a memory mapped regsiter. * @addr: Memory mapped address. diff --git a/include/osi_core.h b/include/osi_core.h index 5394ff3..c2e899d 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -120,6 +120,8 @@ struct osi_core_avb_algorithm { * @poll_for_swr: Called to poll for software reset bit. * @core_init: Called to initialize MAC and MTL registers. * @core_deinit: Called to deinitialize MAC and MTL registers. + * @validate_regs: Called periodically to read and validate safety critical + * registers against last written value. * @start_mac: Called to start MAC Tx and Rx engine. * @stop_mac: Called to stop MAC Tx and Rx engine. * @handle_common_intr: Called to handle common interrupt. @@ -164,6 +166,7 @@ struct osi_core_ops { unsigned int tx_fifo_size, unsigned int rx_fifo_size); void (*core_deinit)(struct osi_core_priv_data *osi_core); + int (*validate_regs)(struct osi_core_priv_data *osi_core); void (*start_mac)(void *addr); void (*stop_mac)(void *addr); void (*handle_common_intr)(struct osi_core_priv_data *osi_core); @@ -296,6 +299,8 @@ struct osi_ptp_config { * @mmc: mmc counter structure * @xstats: xtra sw error counters * @dcs_en: DMA channel selection enable (1) + * @safety_config: Functional safety config to do periodic read-verify of + * certain safety critical registers. */ struct osi_core_priv_data { void *base; @@ -317,6 +322,7 @@ struct osi_core_priv_data { struct osi_mmc_counters mmc; struct osi_xtra_stat_counters xstats; unsigned int dcs_en; + void *safety_config; }; /** @@ -387,6 +393,26 @@ int osi_hw_core_init(struct osi_core_priv_data *osi_core, */ int osi_hw_core_deinit(struct osi_core_priv_data *osi_core); +/** + * osi_validate_core_regs - Read-validate HW registers for func safety. + * @osi_core: OSI core private data structure. + * + * Algorithm: Reads pre-configured list of MAC/MTL configuration registers + * and compares with last written value for any modifications. + * + * Dependencies: + * 1) MAC has to be out of reset. + * 2) 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. + * 3) Invoke this call iff (osi_core_priv_data->safety_config != OSI_NULL) + * + * Protection: None + * + * Return: 0 - success, -1 - failure (reg value has changed) + */ +int osi_validate_core_regs(struct osi_core_priv_data *osi_core); + /** * osi_start_mac - Start MAC Tx/Rx engine * @osi_core: OSI core private data. @@ -1143,4 +1169,11 @@ int osi_get_systime_from_mac(struct osi_core_priv_data *osi_core, int osi_ptp_configuration(struct osi_core_priv_data *osi_core, unsigned int 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. + */ +struct osi_core_ops *eqos_get_hw_core_ops(void); +void *eqos_get_core_safety_config(void); #endif /* OSI_CORE_H */ diff --git a/include/osi_dma.h b/include/osi_dma.h index 6825ba8..d076a6b 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -237,6 +237,8 @@ struct osi_dma_priv_data; * wrapper level. * @start_dma: Called to start the Tx/Rx DMA. * @set_rx_buf_len: Called to set Rx buffer length. + * @validate_regs: Called periodically to read and validate safety critical + * registers against last written value. */ struct osi_dma_chan_ops { void (*set_tx_ring_len)(void *addr, unsigned int chan, @@ -261,6 +263,7 @@ struct osi_dma_chan_ops { void (*stop_dma)(void *addr, unsigned int chan); void (*init_dma_channel) (struct osi_dma_priv_data *osi_dma); void (*set_rx_buf_len)(struct osi_dma_priv_data *osi_dma); + int (*validate_regs)(struct osi_dma_priv_data *osi_dma); }; /** @@ -279,6 +282,8 @@ struct osi_dma_chan_ops { * @dstats: Extra DMA stats * @rx_riwt: Receive Interrupt Watchdog Timer Count Units * @use_riwt: Flag which decides riwt is enabled(1) or disabled(0) + * @safety_config: Functional safety config to do periodic read-verify of + * certain safety critical dma registers. */ struct osi_dma_priv_data { struct osi_tx_ring *tx_ring[OSI_EQOS_MAX_NUM_CHANS]; @@ -295,8 +300,29 @@ struct osi_dma_priv_data { struct osi_xtra_dma_stat_counters dstats; unsigned int rx_riwt; unsigned int use_riwt; + void *safety_config; }; +/** + * osi_validate_dma_regs - Read-validate HW registers for func safety. + * @osi_dma: OSI dma private data structure. + * + * Algorithm: Reads pre-configured list of DMA configuration registers + * and compares with last written value for any modifications. + * + * Dependencies: + * 1) MAC has to be out of reset. + * 2) 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. + * 3) Invoke this call iff (osi_dma_priv_data->safety_config != OSI_NULL) + * + * Protection: None + * + * Return: 0 - success, -1 - failure (reg value has changed) + */ +int osi_validate_dma_regs(struct osi_dma_priv_data *osi_dma); + /** * osi_disable_chan_tx_intr - Disables DMA Tx channel interrupts. * @osi_dma: DMA private data. @@ -701,4 +727,8 @@ int osi_clear_tx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); * Return: 0 - success, -1 - failure */ int osi_clear_rx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); + +/* Function prototype needed for misra */ +struct osi_dma_chan_ops *eqos_get_dma_chan_ops(void); +void *eqos_get_dma_safety_config(void); #endif /* OSI_DMA_H */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 6d4965c..0f8d88c 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -26,7 +26,197 @@ #include "eqos_core.h" #include "eqos_mmc.h" -struct osi_core_ops *eqos_get_hw_core_ops(void); +static struct core_func_safety eqos_core_safety_config; + +/** + * eqos_core_safety_writel - Write to safety critical register. + * @val: Value to be written. + * @addr: memory mapped register address to be written to. + * @idx: Index of register corresponding to enum func_safety_core_regs. + * + * Algorithm: + * 1) Acquire RW lock, so that eqos_validate_core_regs does not run while + * updating the safety critical register. + * 2) call osi_writel() to actually update the memory mapped register. + * 3) 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. + * + * Dependencies: + * 1) MAC has to be out of reset, and clocks supplied. + * + * Protection: None. + * + * Return: None. + */ +static inline void eqos_core_safety_writel(unsigned int val, void *addr, + unsigned int idx) +{ + struct core_func_safety *config = &eqos_core_safety_config; + + osi_lock_irq_enabled(&config->core_safety_lock); + osi_writel(val, addr); + config->reg_val[idx] = (val & config->reg_mask[idx]); + osi_unlock_irq_enabled(&config->core_safety_lock); +} + +/** + * eqos_core_safety_init - Initialize the eqos_core_safety_config. + * @base_addr: Base address of memory mapped register space. + * + * Algorithm: Populate the list of safety critical registers and provide + * 1) the address of the register + * 2) Register mask (to ignore reserved/self-critical bits in the reg). + * See @eqos_validate_core_regs which can be ivoked periodically to compare + * the last written value to this register vs the actual value read when + * eqos_validate_core_regs is scheduled. + * + * Dependencies: None + * + * Protection: None + * + * Return: None + */ +static void eqos_core_safety_init(struct osi_core_priv_data *osi_core) +{ + struct core_func_safety *config = &eqos_core_safety_config; + unsigned char *base = (unsigned char *)osi_core->base; + unsigned int val; + unsigned int 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]; + 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]; + 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_readl((unsigned char *)config->reg_addr[i]); + config->reg_val[i] = val & config->reg_mask[i]; + } + + osi_lock_init(&config->core_safety_lock); +} + +/** + * eqos_validate_core_regs - Read-validate HW registers for functional safety. + * @osi: OSI core private data structure. + * Algorithm: Reads pre-configured list of MAC/MTL configuration registers + * and compares with last written value for any modifications. + * + * Dependencies: + * 1) MAC has to be out of reset. + * 2) 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. + * 3) Invoke this call iff (osi_core_priv_data->safety_config != OSI_NULL) + * + * Protection: None + * + * Return: 0 - success, -1 - failure + */ +static int eqos_validate_core_regs(struct osi_core_priv_data *osi_core) +{ + struct core_func_safety *config = + (struct core_func_safety *)osi_core->safety_config; + unsigned int cur_val; + unsigned int 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_readl((unsigned char *)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); + return -1; + } + } + osi_unlock_irq_enabled(&config->core_safety_lock); + + return 0; +} /** * eqos_config_flow_control - Configure MAC flow control settings @@ -70,7 +260,9 @@ static int eqos_config_flow_control(void *addr, unsigned int flw_ctrl) } /* Write to MAC Tx Flow control Register of Q0 */ - osi_writel(val, (unsigned char *)addr + EQOS_MAC_QX_TX_FLW_CTRL(0U)); + eqos_core_safety_writel(val, (unsigned char *)addr + + EQOS_MAC_QX_TX_FLW_CTRL(0U), + EQOS_MAC_Q0_TXFC_IDX); /* Configure MAC Rx Flow control*/ /* Read MAC Rx Flow control Register */ @@ -188,7 +380,9 @@ static int eqos_config_fw_err_pkts(void *addr, unsigned int qinx, /* Write to FEP bit of MTL RXQ Operation Mode Register to enable or * disable the forwarding of error packets to DMA or application. */ - osi_writel(val, (unsigned char *)addr + EQOS_MTL_CHX_RX_OP_MODE(qinx)); + eqos_core_safety_writel(val, (unsigned char *)addr + + EQOS_MTL_CHX_RX_OP_MODE(qinx), + EQOS_MTL_CH0_RX_OP_MODE_IDX + qinx); return 0; } @@ -292,7 +486,8 @@ static int eqos_config_mac_loopback(void *addr, unsigned int lb_mode) osi_writel(clk_ctrl_val, (unsigned char *)addr + EQOS_CLOCK_CTRL_0); /* Write to MAC Configuration Register */ - osi_writel(mcr_val, (unsigned char *)addr + EQOS_MAC_MCR); + eqos_core_safety_writel(mcr_val, (unsigned char *)addr + EQOS_MAC_MCR, + EQOS_MAC_MCR_IDX); return 0; } @@ -419,7 +614,8 @@ static void eqos_set_speed(void *base, int speed) break; } - osi_writel(mcr_val, (unsigned char *)base + EQOS_MAC_MCR); + eqos_core_safety_writel(mcr_val, (unsigned char *)base + EQOS_MAC_MCR, + EQOS_MAC_MCR_IDX); } /** @@ -449,7 +645,8 @@ static void eqos_set_mode(void *base, int mode) } else { /* Nothing here */ } - osi_writel(mcr_val, (unsigned char *)base + EQOS_MAC_MCR); + eqos_core_safety_writel(mcr_val, (unsigned char *)base + EQOS_MAC_MCR, + EQOS_MAC_MCR_IDX); } /** @@ -571,7 +768,7 @@ static int eqos_pad_calibrate(void *ioaddr) { unsigned int retry = 1000; unsigned int count; - int cond = 1; + int cond = 1, ret = 0; unsigned int value; /* 1. Set field PAD_E_INPUT_OR_E_PWRD in @@ -590,7 +787,9 @@ static int eqos_pad_calibrate(void *ioaddr) value = osi_readl((unsigned char *)ioaddr + EQOS_PAD_AUTO_CAL_CFG); value |= EQOS_PAD_AUTO_CAL_CFG_START | EQOS_PAD_AUTO_CAL_CFG_ENABLE; - osi_writel(value, (unsigned char *)ioaddr + EQOS_PAD_AUTO_CAL_CFG); + eqos_core_safety_writel(value, (unsigned char *)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. @@ -600,7 +799,8 @@ static int eqos_pad_calibrate(void *ioaddr) count = 0; while (cond == 1) { if (count > retry) { - return -1; + ret = -1; + goto calibration_failed; } count++; osd_usleep_range(10, 12); @@ -612,6 +812,7 @@ static int eqos_pad_calibrate(void *ioaddr) } } +calibration_failed: /* 6. Re-program the value PAD_E_INPUT_OR_E_PWRD in * ETHER_QOS_SDMEMCOMPPADCTRL_0 to save power */ @@ -619,7 +820,7 @@ static int eqos_pad_calibrate(void *ioaddr) value &= ~EQOS_PAD_CRTL_E_INPUT_OR_E_PWRD; osi_writel(value, (unsigned char *)ioaddr + EQOS_PAD_CRTL); - return 0; + return ret; } /** @@ -648,8 +849,9 @@ static int eqos_flush_mtl_tx_queue(void *addr, unsigned int qinx) value = osi_readl((unsigned char *)addr + EQOS_MTL_CHX_TX_OP_MODE(qinx)); value |= EQOS_MTL_QTOMR_FTQ; - osi_writel(value, (unsigned char *)addr + - EQOS_MTL_CHX_TX_OP_MODE(qinx)); + eqos_core_safety_writel(value, (unsigned char *)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; @@ -811,8 +1013,9 @@ static int eqos_configure_mtl_queue(unsigned int qinx, value |= EQOS_MTL_TSF; /* Enable TxQ */ value |= EQOS_MTL_TXQEN; - osi_writel(value, (unsigned char *)osi_core->base + - EQOS_MTL_CHX_TX_OP_MODE(qinx)); + eqos_core_safety_writel(value, (unsigned char *)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_readl((unsigned char *)osi_core->base + @@ -826,22 +1029,24 @@ static int eqos_configure_mtl_queue(unsigned int qinx, * RFD: Threshold for Deactivating Flow Control */ update_ehfc_rfa_rfd(rx_fifo, &value); - osi_writel(value, (unsigned char *)osi_core->base + - EQOS_MTL_CHX_RX_OP_MODE(qinx)); + eqos_core_safety_writel(value, (unsigned char *)osi_core->base + + EQOS_MTL_CHX_RX_OP_MODE(qinx), + EQOS_MTL_CH0_RX_OP_MODE_IDX + qinx); /* Transmit Queue weight */ value = osi_readl((unsigned char *)osi_core->base + EQOS_MTL_TXQ_QW(qinx)); value |= (EQOS_MTL_TXQ_QW_ISCQW + qinx); - osi_writel(value, (unsigned char *)osi_core->base + - EQOS_MTL_TXQ_QW(qinx)); + eqos_core_safety_writel(value, (unsigned char *)osi_core->base + + EQOS_MTL_TXQ_QW(qinx), + EQOS_MTL_TXQ0_QW_IDX + qinx); /* Enable Rx Queue Control */ value = osi_readl((unsigned char *)osi_core->base + EQOS_MAC_RQC0R); value |= ((osi_core->rxq_ctrl[qinx] & 0x3U) << (qinx * 2U)); - osi_writel(value, (unsigned char *)osi_core->base + - EQOS_MAC_RQC0R); + eqos_core_safety_writel(value, (unsigned char *)osi_core->base + + EQOS_MAC_RQC0R, EQOS_MAC_RQC0R_IDX); return 0; } @@ -879,7 +1084,8 @@ static int eqos_config_rxcsum_offload(void *addr, unsigned int enabled) mac_mcr &= ~EQOS_MCR_IPC; } - osi_writel(mac_mcr, (unsigned char *)addr + EQOS_MAC_MCR); + eqos_core_safety_writel(mac_mcr, (unsigned char *)addr + EQOS_MAC_MCR, + EQOS_MAC_MCR_IDX); return 0; } @@ -949,8 +1155,8 @@ static void eqos_configure_rxq_priority(struct osi_core_priv_data *osi_core) mfix_var2 <<= mfix_var1; val |= (temp & mfix_var2); /* Priorities Selected in the Receive Queue 0 */ - osi_writel(val, (unsigned char *)osi_core->base + - EQOS_MAC_RQC2R); + eqos_core_safety_writel(val, (unsigned char *)osi_core->base + + EQOS_MAC_RQC2R, EQOS_MAC_RQC2R_IDX); } } @@ -977,15 +1183,18 @@ static void eqos_configure_mac(struct osi_core_priv_data *osi_core) unsigned int value; /* Update MAC address 0 high */ - osi_writel((((unsigned int)osi_core->mac_addr[5] << 8U) | - (unsigned int)(osi_core->mac_addr[4])), - (unsigned char *)osi_core->base + EQOS_MAC_MA0HR); + value = (((unsigned int)osi_core->mac_addr[5] << 8U) | + ((unsigned int)osi_core->mac_addr[4])); + eqos_core_safety_writel(value, (unsigned char *)osi_core->base + + EQOS_MAC_MA0HR, EQOS_MAC_MA0HR_IDX); + /* Update MAC address 0 Low */ - osi_writel((((unsigned int)osi_core->mac_addr[3] << 24U) | - ((unsigned int)osi_core->mac_addr[2] << 16U) | - ((unsigned int)osi_core->mac_addr[1] << 8U) | - ((unsigned int)osi_core->mac_addr[0])), - (unsigned char *)osi_core->base + EQOS_MAC_MA0LR); + value = (((unsigned int)osi_core->mac_addr[3] << 24U) | + ((unsigned int)osi_core->mac_addr[2] << 16U) | + ((unsigned int)osi_core->mac_addr[1] << 8U) | + ((unsigned int)osi_core->mac_addr[0])); + eqos_core_safety_writel(value, (unsigned char *)osi_core->base + + EQOS_MAC_MA0LR, EQOS_MAC_MA0LR_IDX); /* Read MAC Configuration Register */ value = osi_readl((unsigned char *)osi_core->base + EQOS_MAC_MCR); @@ -1004,14 +1213,16 @@ static void eqos_configure_mac(struct osi_core_priv_data *osi_core) value |= EQOS_MCR_JD; } - osi_writel(value, (unsigned char *)osi_core->base + EQOS_MAC_MCR); + eqos_core_safety_writel(value, (unsigned char *)osi_core->base + + EQOS_MAC_MCR, EQOS_MAC_MCR_IDX); /* Enable Multicast and Broadcast Queue, default is Q0 */ value = osi_readl((unsigned char *)osi_core->base + EQOS_MAC_RQC1R); value |= EQOS_MAC_RQC1R_MCBCQEN; /* Routing Multicast and Broadcast to Q1 */ value |= EQOS_MAC_RQC1R_MCBCQ1; - osi_writel(value, (unsigned char *)osi_core->base + EQOS_MAC_RQC1R); + eqos_core_safety_writel(value, (unsigned char *)osi_core->base + + EQOS_MAC_RQC1R, EQOS_MAC_RQC1R_IDX); /* Disable all MMC interrupts */ /* Disable all MMC Tx Interrupts */ @@ -1037,7 +1248,8 @@ static void eqos_configure_mac(struct osi_core_priv_data *osi_core) /* TODO: LPI need to be enabled during EEE implementation */ value |= EQOS_IMR_RGSMIIIE; - osi_writel(value, (unsigned char *)osi_core->base + EQOS_MAC_IMR); + eqos_core_safety_writel(value, (unsigned char *)osi_core->base + + EQOS_MAC_IMR, EQOS_MAC_IMR_IDX); /* Enable VLAN configuration */ value = osi_readl((unsigned char *)osi_core->base + EQOS_MAC_VLAN_TAG); @@ -1103,7 +1315,8 @@ static void eqos_configure_dma(void *base) /* AXI Maximum Write Outstanding Request Limit = 31 */ value |= EQOS_DMA_SBUS_WR_OSR_LMT; - osi_writel(value, (unsigned char *)base + EQOS_DMA_SBUS); + eqos_core_safety_writel(value, (unsigned char *)base + EQOS_DMA_SBUS, + EQOS_DMA_SBUS_IDX); value = osi_readl((unsigned char *)base + EQOS_DMA_BMR); value |= EQOS_DMA_BMR_DPSW; @@ -1139,6 +1352,8 @@ static int eqos_core_init(struct osi_core_priv_data *osi_core, unsigned int tx_fifo = 0; unsigned int rx_fifo = 0; + eqos_core_safety_init(osi_core); + /* PAD calibration */ ret = eqos_pad_calibrate(osi_core->base); if (ret < 0) { @@ -1159,8 +1374,9 @@ static int eqos_core_init(struct osi_core_priv_data *osi_core, value |= EQOS_RXQ_TO_DMA_CHAN_MAP; } - osi_writel(value, (unsigned char *)osi_core->base + - EQOS_MTL_RXQ_DMA_MAP0); + eqos_core_safety_writel(value, (unsigned char *)osi_core->base + + EQOS_MTL_RXQ_DMA_MAP0, + EQOS_MTL_RXQ_DMA_MAP0_IDX); /* Calculate value of Transmit queue fifo size to be programmed */ tx_fifo = eqos_calculate_per_queue_fifo(tx_fifo_size, @@ -1388,7 +1604,8 @@ static void eqos_start_mac(void *addr) /* Enable MAC Transmit */ /* Enable MAC Receive */ value |= EQOS_MCR_TE | EQOS_MCR_RE; - osi_writel(value, (unsigned char *)addr + EQOS_MAC_MCR); + eqos_core_safety_writel(value, (unsigned char *)addr + EQOS_MAC_MCR, + EQOS_MAC_MCR_IDX); } /** @@ -1413,7 +1630,8 @@ static void eqos_stop_mac(void *addr) /* Disable MAC Receive */ value &= ~EQOS_MCR_TE; value &= ~EQOS_MCR_RE; - osi_writel(value, (unsigned char *)addr + EQOS_MAC_MCR); + eqos_core_safety_writel(value, (unsigned char *)addr + EQOS_MAC_MCR, + EQOS_MAC_MCR_IDX); } /** @@ -1473,8 +1691,9 @@ static int eqos_set_avb_algorithm(struct osi_core_priv_data *osi_core, /* 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; - osi_writel(value, (unsigned char *)osi_core->base + - EQOS_MTL_CHX_TX_OP_MODE(qinx)); + eqos_core_safety_writel(value, (unsigned char *)osi_core->base + + EQOS_MTL_CHX_TX_OP_MODE(qinx), + EQOS_MTL_CH0_TX_OP_MODE_IDX + qinx); /* Set Algo and Credit control */ value = (avb->credit_control << EQOS_MTL_TXQ_ETS_CR_CC_SHIFT) & @@ -1494,8 +1713,9 @@ static int eqos_set_avb_algorithm(struct osi_core_priv_data *osi_core, EQOS_MTL_TXQ_QW(qinx)); value &= ~EQOS_MTL_TXQ_ETS_QW_ISCQW_MASK; value |= avb->idle_slope & EQOS_MTL_TXQ_ETS_QW_ISCQW_MASK; - osi_writel(value, (unsigned char *)osi_core->base + - EQOS_MTL_TXQ_QW(qinx)); + eqos_core_safety_writel(value, (unsigned char *)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; @@ -1550,7 +1770,8 @@ static void eqos_config_mac_pkt_filter_reg(struct osi_core_priv_data *osi_core, ((pfilter.hpf_mode << EQOS_MAC_PFR_HPF_SHIFT) & EQOS_MAC_PFR_HPF); - osi_writel(value, (unsigned char *)osi_core->base + EQOS_MAC_PFR); + eqos_core_safety_writel(value, (unsigned char *)osi_core->base + + EQOS_MAC_PFR, EQOS_MAC_PFR_IDX); } /** @@ -1842,7 +2063,8 @@ static int eqos_config_arp_offload(unsigned int mac_ver, void *addr, mac_mcr &= ~EQOS_MCR_ARPEN; } - osi_writel(mac_mcr, (unsigned char *)addr + EQOS_MAC_MCR); + eqos_core_safety_writel(mac_mcr, (unsigned char *)addr + EQOS_MAC_MCR, + EQOS_MAC_MCR_IDX); return 0; } @@ -1871,7 +2093,8 @@ static int eqos_config_l3_l4_filter_enable(void *base, value = osi_readl((unsigned char *)base + EQOS_MAC_PFR); value &= ~(EQOS_MAC_PFR_IPFE); value |= ((filter_enb_dis << 20) & EQOS_MAC_PFR_IPFE); - osi_writel(value, (unsigned char *)base + EQOS_MAC_PFR); + eqos_core_safety_writel(value, (unsigned char *)base + EQOS_MAC_PFR, + EQOS_MAC_PFR_IDX); return 0; } @@ -1902,7 +2125,8 @@ static int eqos_config_l2_da_perfect_inverse_match(void *base, unsigned int value &= ~EQOS_MAC_PFR_DAIF; value |= ((perfect_inverse_match << EQOS_MAC_PFR_DAIF_SHIFT) & EQOS_MAC_PFR_DAIF); - osi_writel(value, (unsigned char *)base + EQOS_MAC_PFR); + eqos_core_safety_writel(value, (unsigned char *)base + EQOS_MAC_PFR, + EQOS_MAC_PFR_IDX); return 0; } @@ -2433,7 +2657,8 @@ static int eqos_config_vlan_filtering(struct osi_core_priv_data *osi_core, value = osi_readl((unsigned char *)base + EQOS_MAC_PFR); value &= ~(EQOS_MAC_PFR_VTFE); value |= ((filter_enb_dis << EQOS_MAC_PFR_SHIFT) & EQOS_MAC_PFR_VTFE); - osi_writel(value, (unsigned char *)base + EQOS_MAC_PFR); + eqos_core_safety_writel(value, (unsigned char *)base + EQOS_MAC_PFR, + EQOS_MAC_PFR_IDX); value = osi_readl((unsigned char *)base + EQOS_MAC_VLAN_TR); value &= ~(EQOS_MAC_VLAN_TR_VTIM | EQOS_MAC_VLAN_TR_VTHM); @@ -2552,7 +2777,8 @@ static int eqos_set_systime_to_mac(void *addr, unsigned int sec, /* issue command to update the configured secs and nsecs values */ mac_tcr |= EQOS_MAC_TCR_TSINIT; - osi_writel(mac_tcr, (unsigned char *)addr + EQOS_MAC_TCR); + eqos_core_safety_writel(mac_tcr, (unsigned char *)addr + EQOS_MAC_TCR, + EQOS_MAC_TCR_IDX); ret = eqos_poll_for_tsinit_complete(addr, &mac_tcr); if (ret == -1) { @@ -2628,11 +2854,13 @@ static int eqos_config_addend(void *addr, unsigned int addend) } /* write addend value to MAC_Timestamp_Addend register */ - osi_writel(addend, (unsigned char *)addr + EQOS_MAC_TAR); + eqos_core_safety_writel(addend, (unsigned char *)addr + EQOS_MAC_TAR, + EQOS_MAC_TAR_IDX); /* issue command to update the configured addend value */ mac_tcr |= EQOS_MAC_TCR_TSADDREG; - osi_writel(mac_tcr, (unsigned char *)addr + EQOS_MAC_TCR); + eqos_core_safety_writel(mac_tcr, (unsigned char *)addr + EQOS_MAC_TCR, + EQOS_MAC_TCR_IDX); ret = eqos_poll_for_addend_complete(addr, &mac_tcr); if (ret == -1) { @@ -2758,7 +2986,8 @@ static int eqos_adjust_systime(void *addr, unsigned int sec, unsigned int nsec, * specified in MAC_STSUR and MAC_STNSUR */ mac_tcr |= EQOS_MAC_TCR_TSUPDT; - osi_writel(mac_tcr, (unsigned char *)addr + EQOS_MAC_TCR); + eqos_core_safety_writel(mac_tcr, (unsigned char *)addr + EQOS_MAC_TCR, + EQOS_MAC_TCR_IDX); ret = eqos_poll_for_update_ts_complete(addr, &mac_tcr); if (ret == -1) { @@ -2888,7 +3117,8 @@ static void eqos_config_tscr(void *addr, unsigned int ptp_filter) mac_tcr = OSI_DISABLE; } - osi_writel(mac_tcr, (unsigned char *)addr + EQOS_MAC_TCR); + eqos_core_safety_writel(mac_tcr, (unsigned char *)addr + EQOS_MAC_TCR, + EQOS_MAC_TCR_IDX); } /** @@ -2934,7 +3164,8 @@ static void eqos_config_ssir(void *addr, unsigned int ptp_clock) val |= val << EQOS_MAC_SSIR_SSINC_SHIFT; /* update Sub-second Increment Value */ - osi_writel(val, (unsigned char *)addr + EQOS_MAC_SSIR); + eqos_core_safety_writel(val, (unsigned char *)addr + EQOS_MAC_SSIR, + EQOS_MAC_SSIR_IDX); } /** @@ -2959,6 +3190,7 @@ static struct osi_core_ops eqos_core_ops = { .poll_for_swr = eqos_poll_for_swr, .core_init = eqos_core_init, .core_deinit = eqos_core_deinit, + .validate_regs = eqos_validate_core_regs, .start_mac = eqos_start_mac, .stop_mac = eqos_stop_mac, .handle_common_intr = eqos_handle_common_intr, @@ -2998,6 +3230,11 @@ static struct osi_core_ops eqos_core_ops = { .reset_mmc = eqos_reset_mmc, }; +void *eqos_get_core_safety_config(void) +{ + return &eqos_core_safety_config; +} + struct osi_core_ops *eqos_get_hw_core_ops(void) { return &eqos_core_ops; diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 8519064..93b7851 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -337,4 +337,82 @@ #define EQOS_DMA_CHX_STATUS_FBE OSI_BIT(10) void update_ehfc_rfa_rfd(unsigned int rx_fifo, unsigned int *value); + +/* Below macros are used for periodic reg validation for functional safety. + * HW register mask - to mask reserved and self-clearing bits + */ +#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 0x47039U +#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_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_TXQ0_QW_IDX 22U +#define EQOS_MTL_TXQ1_QW_IDX 23U +#define EQOS_MTL_TXQ2_QW_IDX 24U +#define EQOS_MTL_TXQ3_QW_IDX 25U +#define EQOS_MTL_CH0_RX_OP_MODE_IDX 26U +#define EQOS_MTL_CH1_RX_OP_MODE_IDX 27U +#define EQOS_MTL_CH2_RX_OP_MODE_IDX 28U +#define EQOS_MTL_CH3_RX_OP_MODE_IDX 29U +#define EQOS_DMA_SBUS_IDX 30U +#define EQOS_MAX_CORE_SAFETY_REGS 31U + +/** + * struct core_func_safety - Struct used to store last written values of + * critical core HW registers. + * @reg_addr: Array of reg MMIO addresses (base of EQoS + offset of reg) + * @reg_mask: Array of bit-mask value of each corresponding reg (used to + * ignore self-clearing/reserved bits in reg). + * @reg_val: Array of value stored in each corresponding register. + * @core_safety_lock: OSI lock variable used to protect writes to reg while + * validation is in-progress. + */ +struct core_func_safety { + void *reg_addr[EQOS_MAX_CORE_SAFETY_REGS]; + unsigned int reg_mask[EQOS_MAX_CORE_SAFETY_REGS]; + unsigned int reg_val[EQOS_MAX_CORE_SAFETY_REGS]; + unsigned int core_safety_lock; +}; #endif diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index e1f93be..5523816 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -35,8 +35,6 @@ #define MDIO_PHY_REG_SHIFT 16U #define MDIO_MII_WRITE OSI_BIT(2) -extern struct osi_core_ops *eqos_get_hw_core_ops(void); - static inline int poll_for_mii_idle(struct osi_core_priv_data *osi_core) { unsigned int retry = 1000; @@ -165,6 +163,11 @@ int osi_init_core_ops(struct osi_core_priv_data *osi_core) if (osi_core->mac == OSI_MAC_HW_EQOS) { /* Get EQOS HW ops */ osi_core->ops = eqos_get_hw_core_ops(); + /* Explicitly set osi_core->safety_config = OSI_NULL if + * a particular MAC version does not need SW safety mechanisms + * like periodic read-verify. + */ + osi_core->safety_config = (void *)eqos_get_core_safety_config(); return 0; } @@ -216,6 +219,19 @@ int osi_hw_core_deinit(struct osi_core_priv_data *osi_core) return -1; } +int osi_validate_core_regs(struct osi_core_priv_data *osi_core) +{ + int ret = -1; + + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->validate_regs != OSI_NULL) && + (osi_core->safety_config != OSI_NULL)) { + ret = osi_core->ops->validate_regs(osi_core); + } + + return ret; +} + int osi_start_mac(struct osi_core_priv_data *osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index 8c3fd7d..1d270fb 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -24,7 +24,160 @@ #include <osi_dma.h> #include "eqos_dma.h" -struct osi_dma_chan_ops *eqos_get_dma_chan_ops(void); +static struct dma_func_safety eqos_dma_safety_config; + +/** + * eqos_dma_safety_writel - Write to safety critical register. + * @val: Value to be written. + * @addr: memory mapped register address to be written to. + * @idx: Index of register corresponding to enum func_safety_dma_regs. + * + * Algorithm: + * 1) Acquire RW lock, so that eqos_validate_dma_regs does not run while + * updating the safety critical register. + * 2) call osi_writel() to actually update the memory mapped register. + * 3) 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. + * + * Dependencies: + * 1) MAC has to be out of reset, and clocks supplied. + * + * Protection: None. + * + * Return: None. + */ +static inline void eqos_dma_safety_writel(unsigned int val, void *addr, + unsigned int idx) +{ + struct dma_func_safety *config = &eqos_dma_safety_config; + + osi_lock_irq_enabled(&config->dma_safety_lock); + osi_writel(val, addr); + config->reg_val[idx] = (val & config->reg_mask[idx]); + osi_unlock_irq_enabled(&config->dma_safety_lock); +} + +/** + * eqos_dma_safety_init - Initialize the eqos_dma_safety_config. + * @base_addr: Base address of memory mapped register space. + * + * Algorithm: Populate the list of safety critical registers and provide + * 1) the address of the register + * 2) Register mask (to ignore reserved/self-critical bits in the reg). + * See @eqos_validate_dma_regs which can be ivoked periodically to compare + * the last written value to this register vs the actual value read when + * eqos_validate_dma_regs is scheduled. + * + * Dependencies: None + * + * Protection: None + * + * Return: None + */ +static void eqos_dma_safety_init(struct osi_dma_priv_data *osi_dma) +{ + struct dma_func_safety *config = &eqos_dma_safety_config; + unsigned char *base = (unsigned char *)osi_dma->base; + unsigned int val; + unsigned int 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]; + 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((unsigned char *)config->reg_addr[i]); + config->reg_val[i] = val & config->reg_mask[i]; + } + + osi_lock_init(&config->dma_safety_lock); +} + +/** + * eqos_validate_dma_regs - Read-validate HW registers for functional safety. + * @osi_dma: OSI dma private data structure. + * Algorithm: Reads pre-configured list of MAC/MTL configuration registers + * and compares with last written value for any modifications. + * + * Dependencies: + * 1) MAC has to be out of reset. + * 2) 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. + * 3) Invoke this call iff (osi_dma_priv_data->safety_config != OSI_NULL) + * + * Protection: None + * + * Return: 0 - success, -1 - failure + */ +static int eqos_validate_dma_regs(struct osi_dma_priv_data *osi_dma) +{ + struct dma_func_safety *config = + (struct dma_func_safety *)osi_dma->safety_config; + unsigned int cur_val; + unsigned int 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((unsigned char *)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; +} /** * eqos_disable_chan_tx_intr - Disables DMA Tx channel interrupts. @@ -203,7 +356,9 @@ static void eqos_clear_rx_intr(void *addr, unsigned int chan) static void eqos_set_tx_ring_len(void *addr, unsigned int chan, unsigned int len) { - osi_writel(len, (unsigned char *)addr + EQOS_DMA_CHX_TDRL(chan)); + eqos_dma_safety_writel(len, (unsigned char *)addr + + EQOS_DMA_CHX_TDRL(chan), + EQOS_DMA_CH0_TDRL_IDX + chan); } /** @@ -266,7 +421,9 @@ static void eqos_update_tx_tailptr(void *addr, unsigned int chan, static void eqos_set_rx_ring_len(void *addr, unsigned int chan, unsigned int len) { - osi_writel(len, (unsigned char *)addr + EQOS_DMA_CHX_RDRL(chan)); + eqos_dma_safety_writel(len, (unsigned char *)addr + + EQOS_DMA_CHX_RDRL(chan), + EQOS_DMA_CH0_RDRL_IDX + chan); } /** @@ -334,12 +491,16 @@ static void eqos_start_dma(void *addr, unsigned int chan) /* start Tx DMA */ val = osi_readl((unsigned char *)addr + EQOS_DMA_CHX_TX_CTRL(chan)); val |= OSI_BIT(0); - osi_writel(val, (unsigned char *)addr + EQOS_DMA_CHX_TX_CTRL(chan)); + eqos_dma_safety_writel(val, (unsigned char *)addr + + EQOS_DMA_CHX_TX_CTRL(chan), + EQOS_DMA_CH0_TX_CTRL_IDX + chan); /* start Rx DMA */ val = osi_readl((unsigned char *)addr + EQOS_DMA_CHX_RX_CTRL(chan)); val |= OSI_BIT(0); - osi_writel(val, (unsigned char *)addr + EQOS_DMA_CHX_RX_CTRL(chan)); + eqos_dma_safety_writel(val, (unsigned char *)addr + + EQOS_DMA_CHX_RX_CTRL(chan), + EQOS_DMA_CH0_RX_CTRL_IDX + chan); } /** @@ -364,12 +525,16 @@ static void eqos_stop_dma(void *addr, unsigned int chan) /* stop Tx DMA */ val = osi_readl((unsigned char *)addr + EQOS_DMA_CHX_TX_CTRL(chan)); val &= ~OSI_BIT(0); - osi_writel(val, (unsigned char *)addr + EQOS_DMA_CHX_TX_CTRL(chan)); + eqos_dma_safety_writel(val, (unsigned char *)addr + + EQOS_DMA_CHX_TX_CTRL(chan), + EQOS_DMA_CH0_TX_CTRL_IDX + chan); /* stop Rx DMA */ val = osi_readl((unsigned char *)addr + EQOS_DMA_CHX_RX_CTRL(chan)); val &= ~OSI_BIT(0); - osi_writel(val, (unsigned char *)addr + EQOS_DMA_CHX_RX_CTRL(chan)); + eqos_dma_safety_writel(val, (unsigned char *)addr + + EQOS_DMA_CHX_RX_CTRL(chan), + EQOS_DMA_CH0_RX_CTRL_IDX + chan); } /** @@ -413,12 +578,16 @@ static void eqos_configure_dma_channel(unsigned int chan, /* For multi-irqs to work nie needs to be disabled */ value &= ~(EQOS_DMA_CHX_INTR_NIE); - osi_writel(value, (unsigned char *)osi_dma->base + EQOS_DMA_CHX_INTR_ENA(chan)); + eqos_dma_safety_writel(value, (unsigned char *)osi_dma->base + + EQOS_DMA_CHX_INTR_ENA(chan), + EQOS_DMA_CH0_INTR_ENA_IDX + chan); /* Enable 8xPBL mode */ value = osi_readl((unsigned char *)osi_dma->base + EQOS_DMA_CHX_CTRL(chan)); value |= EQOS_DMA_CHX_CTRL_PBLX8; - osi_writel(value, (unsigned char *)osi_dma->base + EQOS_DMA_CHX_CTRL(chan)); + eqos_dma_safety_writel(value, (unsigned char *)osi_dma->base + + EQOS_DMA_CHX_CTRL(chan), + EQOS_DMA_CH0_CTRL_IDX + chan); /* Configure DMA channel Transmit control register */ value = osi_readl((unsigned char *)osi_dma->base + EQOS_DMA_CHX_TX_CTRL(chan)); @@ -429,7 +598,9 @@ static void eqos_configure_dma_channel(unsigned int chan, /* enable TSO by default if HW supports */ value |= EQOS_DMA_CHX_TX_CTRL_TSE; - osi_writel(value, (unsigned char *)osi_dma->base + EQOS_DMA_CHX_TX_CTRL(chan)); + eqos_dma_safety_writel(value, (unsigned char *)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 @@ -440,7 +611,9 @@ static void eqos_configure_dma_channel(unsigned int chan, value |= (osi_dma->rx_buf_len << EQOS_DMA_CHX_RBSZ_SHIFT); /* RXPBL = 12 */ value |= EQOS_DMA_CHX_RX_CTRL_RXPBL_RECOMMENDED; - osi_writel(value, (unsigned char *)osi_dma->base + EQOS_DMA_CHX_RX_CTRL(chan)); + eqos_dma_safety_writel(value, (unsigned char *)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 @@ -481,6 +654,8 @@ static void eqos_init_dma_channel(struct osi_dma_priv_data *osi_dma) { unsigned int 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); @@ -541,8 +716,14 @@ static struct osi_dma_chan_ops eqos_dma_chan_ops = { .stop_dma = eqos_stop_dma, .init_dma_channel = eqos_init_dma_channel, .set_rx_buf_len = eqos_set_rx_buf_len, + .validate_regs = eqos_validate_dma_regs, }; +void *eqos_get_dma_safety_config(void) +{ + return &eqos_dma_safety_config; +} + struct osi_dma_chan_ops *eqos_get_dma_chan_ops(void) { return &eqos_dma_chan_ops; diff --git a/osi/dma/eqos_dma.h b/osi/dma/eqos_dma.h index 2c8f9d8..405a2bd 100644 --- a/osi/dma/eqos_dma.h +++ b/osi/dma/eqos_dma.h @@ -70,4 +70,61 @@ #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 256U + +/* 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 + +/* 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_CH0_TX_CTRL_IDX 4U +#define EQOS_DMA_CH1_TX_CTRL_IDX 5U +#define EQOS_DMA_CH2_TX_CTRL_IDX 6U +#define EQOS_DMA_CH3_TX_CTRL_IDX 7U +#define EQOS_DMA_CH0_RX_CTRL_IDX 8U +#define EQOS_DMA_CH1_RX_CTRL_IDX 9U +#define EQOS_DMA_CH2_RX_CTRL_IDX 10U +#define EQOS_DMA_CH3_RX_CTRL_IDX 11U +#define EQOS_DMA_CH0_TDRL_IDX 12U +#define EQOS_DMA_CH1_TDRL_IDX 13U +#define EQOS_DMA_CH2_TDRL_IDX 14U +#define EQOS_DMA_CH3_TDRL_IDX 15U +#define EQOS_DMA_CH0_RDRL_IDX 16U +#define EQOS_DMA_CH1_RDRL_IDX 17U +#define EQOS_DMA_CH2_RDRL_IDX 18U +#define EQOS_DMA_CH3_RDRL_IDX 19U +#define EQOS_DMA_CH0_INTR_ENA_IDX 20U +#define EQOS_DMA_CH1_INTR_ENA_IDX 21U +#define EQOS_DMA_CH2_INTR_ENA_IDX 22U +#define EQOS_DMA_CH3_INTR_ENA_IDX 23U +#define EQOS_MAX_DMA_SAFETY_REGS 24U + +/** + * struct dma_func_safety - Struct used to store last written values of + * critical DMA HW registers. + * @reg_addr: Array of reg MMIO addresses (base of EQoS + offset of reg) + * @reg_mask: Array of bit-mask value of each corresponding reg (used to + * ignore self-clearing/reserved bits in reg). + * @reg_val: Array of value stored in each corresponding register. + * @dma_safety_lock: OSI lock variable used to protect writes to reg while + * validation is in-progress. + */ +struct dma_func_safety { + void *reg_addr[EQOS_MAX_DMA_SAFETY_REGS]; + unsigned int reg_mask[EQOS_MAX_DMA_SAFETY_REGS]; + unsigned int reg_val[EQOS_MAX_DMA_SAFETY_REGS]; + unsigned int dma_safety_lock; +}; #endif diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 669be99..2ac3192 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -23,13 +23,17 @@ #include <osi_dma.h> extern int dma_desc_init(struct osi_dma_priv_data *osi_dma); -extern struct osi_dma_chan_ops *eqos_get_dma_chan_ops(void); int osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) { if (osi_dma->mac == OSI_MAC_HW_EQOS) { /* Get EQOS HW ops */ osi_dma->ops = eqos_get_dma_chan_ops(); + /* Explicitly set osi_dma->safety_config = OSI_NULL if + * a particular MAC version does not need SW safety mechanisms + * like periodic read-verify. + */ + osi_dma->safety_config = (void *)eqos_get_dma_safety_config(); return 0; } @@ -261,3 +265,15 @@ int osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) return 0; } + +int osi_validate_dma_regs(struct osi_dma_priv_data *osi_dma) +{ + int ret = -1; + if (osi_dma != OSI_NULL && osi_dma->ops != OSI_NULL && + osi_dma->ops->validate_regs != OSI_NULL && + osi_dma->safety_config != OSI_NULL) { + ret = osi_dma->ops->validate_regs(osi_dma); + } + + return ret; +} From bac6dd9ca06f5d3c69ee646220962e4a29cd8707 Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Wed, 31 Jul 2019 15:09:09 +0530 Subject: [PATCH 037/458] nvethernetrm: use delay instead of sleep we are making use of spinlock in functional driver to avoid the race on reading the PTP registers, so use delay instead of sleep. Bug 200512422 Change-Id: Ide1b4e8555eab88076e5de46ab919b50d16e4f6b Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2164976 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/eqos_core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 0f8d88c..9b5f89e 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -2734,7 +2734,7 @@ static inline int eqos_poll_for_tsinit_complete(void *addr, cond = 0; } count++; - osd_msleep(1U); + osd_udelay(1000U); } return 0; @@ -2823,7 +2823,7 @@ static inline int eqos_poll_for_addend_complete(void *addr, cond = 0; } count++; - osd_msleep(1U); + osd_udelay(1000U); } return 0; @@ -2904,7 +2904,7 @@ static inline int eqos_poll_for_update_ts_complete(void *addr, cond = 0; } count++; - osd_msleep(1U); + osd_udelay(1000U); } return 0; From ae6f4415a9b7374b43e4d4d63bcc5cc1e933ab62 Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Tue, 16 Jul 2019 23:08:50 +0530 Subject: [PATCH 038/458] nvethernetrm: Update comments with Doxygen style replace kernel doc comments with Doxygen style comments Bug 200512422 Change-Id: I2e8e1f395674ab9e1b66bf40c1f6cc0551608163 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2154252 GVS: Gerrit_Virtual_Submit Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/mmc.h | 451 ++++++++-------- include/osd.h | 111 ++-- include/osi_common.h | 393 +++++++------- include/osi_core.h | 1099 +++++++++++++++++++-------------------- include/osi_dma.h | 646 ++++++++++++----------- include/osi_dma_txrx.h | 43 +- osi/common/osi_common.c | 11 - osi/core/eqos_core.c | 1005 ++++++++++++++++------------------- osi/core/eqos_core.h | 104 +++- osi/core/eqos_mmc.c | 49 +- osi/core/eqos_mmc.h | 31 ++ osi/core/osi_core.c | 50 +- osi/dma/eqos_dma.c | 355 ++++++------- osi/dma/eqos_dma.h | 33 +- osi/dma/osi_dma.c | 14 - osi/dma/osi_dma_txrx.c | 269 +++------- 16 files changed, 2258 insertions(+), 2406 deletions(-) diff --git a/include/mmc.h b/include/mmc.h index d75d096..3d064ad 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -23,362 +23,333 @@ #ifndef MMC_H #define MMC_H /** - * osi_mmc_counters - The structure to hold RMON counter values - * - * mmc_tx_octetcount_gb: This counter provides the number of bytes - * transmitted, exclusive of preamble and retried bytes, in good and - * bad packets. - * mmc_tx_framecount_gb: This counter provides the number of good and - * bad packets transmitted, exclusive of retried packets. - * mmc_tx_broadcastframe_g: This counter provides the number of good - * broadcast packets transmitted - * mmc_tx_multicastframe_g: This counter provides the number of good - * multicast packets transmitted - * mmc_tx_64_octets_gb: This counter provides the number of good and bad - * packets transmitted with length 64 bytes, exclusive of preamble and - * retried packets - * mmc_tx_65_to_127_octets_gb: This counter provides the number of good - * and bad packets transmitted with length 65-127 bytes, exclusive of - * preamble and retried packets - * mmc_tx_128_to_255_octets_gb: This counter provides the number of good - * and bad packets transmitted with length 128-255 bytes, exclusive of - * preamble and retried packets - * mmc_tx_256_to_511_octets_gb: This counter provides the number of good - * and bad packets transmitted with length 256-511 bytes, exclusive of - * preamble and retried packets - * mmc_tx_512_to_1023_octets_gb: This counter provides the number of good - * and bad packets transmitted with length 512-1023 bytes, exclusive of - * preamble and retried packets - * mmc_tx_1024_to_max_octets_gb: This counter provides the number of good - * and bad packets transmitted with length 1024-max bytes, exclusive of - * preamble and retried packets - * mmc_tx_unicast_gb: This counter provides the number of good and bad - * unicast packets - * mmc_tx_multicast_gb: This counter provides the number of good and bad - * multicast packets - * mmc_tx_broadcast_gb: This counter provides the number of good and bad - * braodcast packets - * mmc_tx_underflow_error: This counter provides the number of abort - * packets due to underflow error - * mmc_tx_singlecol_g: This counter provides the number of successfully - * transmitted packets after a single collision in the half-duplex mode - * mmc_tx_multicol_g: This counter provides the number of successfully - * transmitted packets after a multiple collision in the half-duplex mode - * mmc_tx_deferred: This counter provides the number of successfully - * transmitted after a deferral in the half-duplex mode - * mmc_tx_latecol: This counter provides the number of packets aborted - * because of late collision error - * mmc_tx_exesscol: This counter provides the number of packets aborted - * because of excessive (16) collision errors - * mmc_tx_carrier_error: This counter provides the number of packets - * aborted because of carrier sense error (no carrier or loss of carrier) - * mmc_tx_octetcount_g: This counter provides the number of bytes - * transmitted, exclusive of preamble, only in good packets. - * mmc_tx_framecount_g: This counter provides the number of good packets - * transmitted . - * mmc_tx_excessdef: This counter provides the number of packets aborted - * because of excessive deferral error (deferred for more than two - * max-sized packet times). - * mmc_tx_pause_frame: This counter provides the number of good Pause - * packets transmitted. - * mmc_tx_vlan_frame_g: This counter provides the number of good - * VLAN packets transmitted - * mmc_tx_osize_frame_g: This counter provides the number of packets - * transmitted without errors and with length greater than the maxsize - * (1,518 or 1,522 bytes for VLAN tagged packets; 2000 bytes. - * mmc_rx_framecount_gb: This counter provides the number of good and bad - * packets received - * mmc_rx_octetcount_gb: This counter provides the number of bytes - * received by DWC_ther_qos, exclusive of preamble, in good and bad packets - * mmc_rx_octetcount_g: This counter provides the number of bytes - * received by DWC_ther_qos, exclusive of preamble, in good and bad packets - * mmc_rx_broadcastframe_g: This counter provides the number of good - * broadcast packets received - * mmc_rx_multicastframe_g: This counter provides the number of good - * multicast packets received - * mmc_rx_crc_error: This counter provides the number of packets received - * with CRC error - * mmc_rx_align_error: This counter provides the number of packets - * received with alignment (dribble) error. It is valid only in 10/100 - * mode. - * mmc_rx_runt_error: This counter provides the number of packets - * received with runt (length less than 64 bytes and CRC error) error - * mmc_rx_jabber_error: This counter provides the number of giant packets - * received with length (including CRC) greater than 1,518 bytes - * (1,522 bytes for VLAN tagged) and with CRC error. - * mmc_rx_undersize_g: This counter provides the number of packets - * received with length less than 64 bytes, without any errors - * mmc_rx_oversize_g: This counter provides the number of packets - * received without errors, with length greater than the maxsize - * mmc_rx_64_octets_gb: This counter provides the number of good and bad - * packets received with length 64 bytes, exclusive of the preamble. - * mmc_rx_65_to_127_octets_gb: This counter provides the number of good - * and bad packets received with length 65-127 bytes, exclusive of the - * preamble. - * mmc_rx_128_to_255_octets_gb: This counter provides the number of good - * and bad packets received with length 128-255 bytes, exclusive of the - * preamble. - * mmc_rx_256_to_511_octets_gb: This counter provides the number of good - * and bad packets received with length 256-511 bytes, exclusive of the - * preamble. - * mmc_rx_512_to_1023_octets_gb: This counter provides the number of good - * and bad packets received with length 512-1023 bytes, exclusive of the - * preamble. - * mmc_rx_1024_to_max_octets_gb: This counter provides the number of good - * and bad packets received with length 1024-max bytes, exclusive of the - * preamble. - * mmc_rx_unicast_g: This counter provides the number of good unicast - * packets received mmc_rx_length_error: This counter provides the - * number of packets received with length error (Length Type field - * not equal to packet size), for all packets with valid length field. - * mmc_rx_outofrangetype: This counter provides the number of packets - * received with length field not equal to the - * valid packet size (greater than 1,500 but less than 1,536). - * mmc_rx_pause_frames: This counter provides the number of good and - * valid Pause packets received - * mmc_rx_fifo_overflow: This counter provides the number of missed - * received packets because of FIFO overflow in DWC_ether_qos - * mmc_rx_vlan_frames_gb: This counter provides the number of good and - * bad VLAN packets received - * mmc_rx_watchdog_error: This counter provides the number of packets - * received with error because of watchdog timeout error - * mmc_rx_receive_error: This counter provides the number of packets - * received with Receive error or Packet Extension error on the GMII or - * MII interface - * mmc_rx_ctrl_frames_g: This counter provides the number of packets - * received with Receive error or Packet Extension error on the GMII - * or MII interface - * mmc_rx_ipv4_gd: This counter provides the number of good IPv4 - * datagrams received with the TCP, UDP, or ICMP payload - * mmc_rx_ipv4_hderr: RxIPv4 Header Error Packets - * mmc_rx_ipv4_nopay: This counter provides the number of IPv4 datagram - * packets received that did not have a TCP, UDP, or ICMP payload - * mmc_rx_ipv4_frag: This counter provides the number of good IPv4 - * datagrams received with fragmentation. - * mmc_rx_ipv4_udsbl: This counter provides the number of good IPv4 - * datagrams received that had a UDP payload with checksum disabled - * mmc_rx_ipv6_gd_octets: This counter provides the number of good IPv6 - * datagrams received with the TCP, UDP, or ICMP payload - * mmc_rx_ipv6_hderr_octets: This counter provides the number of IPv6 - * datagrams received with header (length or version mismatch) errors - * mmc_rx_ipv6_nopay_octets: This counter provides the number of IPv6 - * datagram packets received that did not have a TCP, UDP, or ICMP - * payload - * mmc_rx_udp_gd: This counter provides the number of good IP datagrams - * received by DWC_ether_qos with a good UDP payload. - * mmc_rx_udp_err: This counter provides the number of good IP datagrams - * received by DWC_ether_qos with a good UDP payload. This counter is not - * updated when the RxIPv4_UDP_Checksum_Disabled_Packets counter is - * incremented. - * mmc_rx_tcp_gd: This counter provides the number of good IP datagrams - * received with a good TCP payload - * mmc_rx_tcp_err: This counter provides the number of good IP datagrams - * received with a good TCP payload - * mmc_rx_icmp_gd: This counter provides the number of good IP datagrams - * received with a good ICMP payload - * mmc_rx_icmp_err: This counter provides the number of good IP - * datagrams received whose ICMP payload has a checksum error - * mmc_rx_ipv4_gd_octets: This counter provides the number of bytes - * received by DWC_ether_qos in good IPv4 datagrams encapsulating TCP, - * UDP, or ICMP data. (Ethernet header, FCS, pad, or IP pad bytes are - * not included in this counter - * mmc_rx_ipv4_hderr_octets: This counter provides the number of bytes - * received in IPv4 datagrams with header errors (checksum, length, - * version mismatch). The value in the Length field of IPv4 header is - * used to update this counter. (Ethernet header, FCS, pad, - * or IP pad bytes are not included in this counter - * mmc_rx_ipv4_nopay_octets: This counter provides the number of bytes - * received in IPv4 datagrams that did not have a TCP, UDP, or - * ICMP payload. The value in the Length field of IPv4 header is used - * to update this counter. (Ethernet header, FCS, pad, or IP pad bytes - * are not included in this counter. - * mmc_rx_ipv4_frag_octets: This counter provides the number of bytes - * received in fragmented IPv4 datagrams. The value in the Length - * field of IPv4 header is used to update this counter. (Ethernet header, - * FCS, pad, or IP pad bytes are not included in this counter - * mmc_rx_ipv4_udsbl_octets: This counter provides the number of bytes - * received in a UDP segment that had the UDP checksum disabled. This - * counter does not count IP Header bytes. (Ethernet header, FCS, pad, - * or IP pad bytes are not included in this counter. - * mmc_rx_ipv6_gd: This counter provides the number of bytes received - * in good IPv6 datagrams encapsulating TCP, UDP, or ICMP data. - * (Ethernet header, FCS, pad, or IP pad bytes are not included in - * this counter - * mmc_rx_ipv6_hderr: This counter provides the number of bytes received - * in IPv6 datagrams with header errors (length, version mismatch). The - * value in the Length field of IPv6 header is used to update this - * counter. (Ethernet header, FCS, pad, or IP pad bytes are not included - * in this counter. - * mmc_rx_ipv6_nopay: This counter provides the number of bytes received - * in IPv6 datagrams that did not have a TCP, UDP, or ICMP payload. The - * value in the Length field of IPv6 header is used to update this - * counter. (Ethernet header, FCS, pad, or IP pad bytes are not included - * in this counter - * mmc_rx_udp_gd_octets: This counter provides the number of bytes - * received in a good UDP segment. This counter does not count IP header - * bytes. - * mmc_rx_udp_err_octets: This counter provides the number of bytes - * received in a UDP segment that had checksum errors. This counter - * does not count IP header bytes - * mmc_rx_tcp_gd_octets: This counter provides the number of bytes - * received in a good TCP segment. This counter does not count IP - * header bytes - * mmc_rx_tcp_err_octets: This counter provides the number of bytes - * received in a TCP segment that had checksum errors. This counter - * does not count IP header bytes - * mmc_rx_icmp_gd_octets: This counter provides the number of bytes - * received in a good ICMP segment. This counter does not count - * IP header bytes - * mmc_rx_icmp_err_octets: This counter provides the number of bytes - * received in a ICMP segment that had checksum errors. - * This counter does not count IP header bytes + * @brief osi_mmc_counters - The structure to hold RMON counter values */ struct osi_mmc_counters { - /* MMC TX counters */ + /** This counter provides the number of bytes transmitted, exclusive of + * preamble and retried bytes, in good and bad packets */ unsigned long mmc_tx_octetcount_gb; + /** This counter provides the number of good and + * bad packets transmitted, exclusive of retried packets */ unsigned long mmc_tx_framecount_gb; + /** This counter provides number of good broadcast + * packets transmitted */ unsigned long mmc_tx_broadcastframe_g; + /** This counter provides number of good multicast + * packets transmitted */ unsigned long mmc_tx_multicastframe_g; + /** This counter provides the number of good and bad packets + * transmitted with length 64 bytes, exclusive of preamble and + * retried packets */ unsigned long mmc_tx_64_octets_gb; + /** This counter provides the number of good and bad packets + * transmitted with length 65-127 bytes, exclusive of preamble and + * retried packets */ unsigned long mmc_tx_65_to_127_octets_gb; + /** This counter provides the number of good and bad packets + * transmitted with length 128-255 bytes, exclusive of preamble and + * retried packets */ unsigned long mmc_tx_128_to_255_octets_gb; + /** This counter provides the number of good and bad packets + * transmitted with length 256-511 bytes, exclusive of preamble and + * retried packets */ unsigned long mmc_tx_256_to_511_octets_gb; + /** This counter provides the number of good and bad packets + * transmitted with length 512-1023 bytes, exclusive of preamble and + * retried packets */ unsigned long mmc_tx_512_to_1023_octets_gb; + /** This counter provides the number of good and bad packets + * transmitted with length 1024-max bytes, exclusive of preamble and + * retried packets */ unsigned long mmc_tx_1024_to_max_octets_gb; + /** This counter provides the number of good and bad unicast packets */ unsigned long mmc_tx_unicast_gb; + /** This counter provides the number of good and bad + * multicast packets */ unsigned long mmc_tx_multicast_gb; + /** This counter provides the number of good and bad + * broadcast packets */ unsigned long mmc_tx_broadcast_gb; + /** mmc_tx_underflow_error: This counter provides the number of abort + * packets due to underflow error */ unsigned long mmc_tx_underflow_error; + /** This counter provides the number of successfully transmitted + * packets after a single collision in the half-duplex mode */ unsigned long mmc_tx_singlecol_g; + /** This counter provides the number of successfully transmitted + * packets after a multi collision in the half-duplex mode */ unsigned long mmc_tx_multicol_g; + /** This counter provides the number of successfully transmitted + * after a deferral in the half-duplex mode */ unsigned long mmc_tx_deferred; + /** This counter provides the number of packets aborted because of + * late collision error */ unsigned long mmc_tx_latecol; + /** This counter provides the number of packets aborted because of + * excessive (16) collision errors */ unsigned long mmc_tx_exesscol; + /** This counter provides the number of packets aborted because of + * carrier sense error (no carrier or loss of carrier) */ unsigned long mmc_tx_carrier_error; + /** This counter provides the number of bytes transmitted, + * exclusive of preamble, only in good packets */ unsigned long mmc_tx_octetcount_g; + /** This counter provides the number of good packets transmitted */ unsigned long mmc_tx_framecount_g; + /** This counter provides the number of packets aborted because of + * excessive deferral error + * (deferred for more than two max-sized packet times) */ unsigned long mmc_tx_excessdef; + /** This counter provides the number of good Pause + * packets transmitted */ unsigned long mmc_tx_pause_frame; + /** This counter provides the number of good VLAN packets transmitted */ unsigned long mmc_tx_vlan_frame_g; + /** This counter provides the number of packets transmitted without + * errors and with length greater than the maxsize (1,518 or 1,522 bytes + * for VLAN tagged packets; 2000 bytes */ unsigned long mmc_tx_osize_frame_g; - - /* MMC RX counters */ + /** This counter provides the number of good and bad packets received */ unsigned long mmc_rx_framecount_gb; + /** This counter provides the number of bytes received by DWC_ther_qos, + * exclusive of preamble, in good and bad packets */ unsigned long mmc_rx_octetcount_gb; + /** This counter provides the number of bytes received by DWC_ther_qos, + * exclusive of preamble, in good and bad packets */ unsigned long mmc_rx_octetcount_g; + /** This counter provides the number of good + * broadcast packets received */ unsigned long mmc_rx_broadcastframe_g; + /** This counter provides the number of good + * multicast packets received */ unsigned long mmc_rx_multicastframe_g; + /** This counter provides the number of packets + * received with CRC error */ unsigned long mmc_rx_crc_error; + /** This counter provides the number of packets received with + * alignment (dribble) error. It is valid only in 10/100 mode */ unsigned long mmc_rx_align_error; + /** This counter provides the number of packets received with + * runt (length less than 64 bytes and CRC error) error */ unsigned long 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 */ unsigned long mmc_rx_jabber_error; + /** This counter provides the number of packets received with length + * less than 64 bytes, without any errors */ unsigned long mmc_rx_undersize_g; + /** This counter provides the number of packets received without error, + * with length greater than the maxsize */ unsigned long mmc_rx_oversize_g; + /** This counter provides the number of good and bad packets received + * with length 64 bytes, exclusive of the preamble */ unsigned long mmc_rx_64_octets_gb; + /** This counter provides the number of good and bad packets received + * with length 65-127 bytes, exclusive of the preamble */ unsigned long mmc_rx_65_to_127_octets_gb; + /** This counter provides the number of good and bad packets received + * with length 128-255 bytes, exclusive of the preamble */ unsigned long mmc_rx_128_to_255_octets_gb; + /** This counter provides the number of good and bad packets received + * with length 256-511 bytes, exclusive of the preamble */ unsigned long mmc_rx_256_to_511_octets_gb; + /** This counter provides the number of good and bad packets received + * with length 512-1023 bytes, exclusive of the preamble */ unsigned long mmc_rx_512_to_1023_octets_gb; + /** This counter provides the number of good and bad packets received + * with length 1024-maxbytes, exclusive of the preamble */ unsigned long mmc_rx_1024_to_max_octets_gb; + /** This counter provides the number of good unicast packets received */ unsigned long mmc_rx_unicast_g; + /** 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 */ unsigned long mmc_rx_length_error; + /** 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) */ unsigned long mmc_rx_outofrangetype; + /** This counter provides the number of good and valid Pause packets + * received */ unsigned long mmc_rx_pause_frames; + /** This counter provides the number of missed received packets + * because of FIFO overflow in DWC_ether_qos */ unsigned long mmc_rx_fifo_overflow; + /** This counter provides the number of good and bad VLAN packets + * received */ unsigned long mmc_rx_vlan_frames_gb; + /** This counter provides the number of packets received with error + * because of watchdog timeout error */ unsigned long 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 */ unsigned long 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 */ unsigned long mmc_rx_ctrl_frames_g; - /* IPv4 */ + /** This counter provides the number of good IPv4 datagrams received + * with the TCP, UDP, or ICMP payload */ unsigned long mmc_rx_ipv4_gd; + /** RxIPv4 Header Error Packets */ unsigned long mmc_rx_ipv4_hderr; + /** This counter provides the number of IPv4 datagram packets received + * that did not have a TCP, UDP, or ICMP payload */ unsigned long mmc_rx_ipv4_nopay; + /** This counter provides the number of good IPv4 datagrams received + * with fragmentation */ unsigned long mmc_rx_ipv4_frag; + /** This counter provides the number of good IPv4 datagrams received + * that had a UDP payload with checksum disabled */ unsigned long mmc_rx_ipv4_udsbl; - /* IPV6 */ + /** This counter provides the number of good IPv6 datagrams received + * with the TCP, UDP, or ICMP payload */ unsigned long mmc_rx_ipv6_gd_octets; + /** This counter provides the number of IPv6 datagrams received + * with header (length or version mismatch) errors */ unsigned long mmc_rx_ipv6_hderr_octets; + /** This counter provides the number of IPv6 datagram packets received + * that did not have a TCP, UDP, or ICMP payload */ unsigned long mmc_rx_ipv6_nopay_octets; - /* Protocols */ + /** This counter provides the number of good IP datagrams received by + * DWC_ether_qos with a good UDP payload */ unsigned long mmc_rx_udp_gd; + /** 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 */ unsigned long mmc_rx_udp_err; + /** This counter provides the number of good IP datagrams received + * with a good TCP payload */ unsigned long mmc_rx_tcp_gd; + /** This counter provides the number of good IP datagrams received + * with a good TCP payload */ unsigned long mmc_rx_tcp_err; + /** This counter provides the number of good IP datagrams received + * with a good ICMP payload */ unsigned long mmc_rx_icmp_gd; + /** This counter provides the number of good IP datagrams received + * whose ICMP payload has a checksum error */ unsigned long mmc_rx_icmp_err; - /* IPv4 */ + /** 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 */ unsigned long mmc_rx_ipv4_gd_octets; + /** 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 */ unsigned long mmc_rx_ipv4_hderr_octets; + /** 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 */ unsigned long mmc_rx_ipv4_nopay_octets; + /** This counter provides the number of bytes received in fragmented + * IPv4 datagrams. The value in the Length field of IPv4 header is + * used to update this counter. (Ethernet header, FCS, pad, or IP pad + * bytes are not included in this counter */ unsigned long mmc_rx_ipv4_frag_octets; + /** This counter provides the number of bytes received in a UDP segment + * that had the UDP checksum disabled. This counter does not count IP + * Header bytes. (Ethernet header, FCS, pad, or IP pad bytes are not + * included in this counter */ unsigned long mmc_rx_ipv4_udsbl_octets; - - /* IPV6 */ + /** 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 */ unsigned long mmc_rx_ipv6_gd; + /** 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 */ unsigned long mmc_rx_ipv6_hderr; + /** 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 */ unsigned long mmc_rx_ipv6_nopay; /* Protocols */ + /** This counter provides the number of bytes received in a good UDP + * segment. This counter does not count IP header bytes */ unsigned long mmc_rx_udp_gd_octets; + /** This counter provides the number of bytes received in a UDP + * segment that had checksum errors. This counter does not count + * IP header bytes */ unsigned long mmc_rx_udp_err_octets; + /** This counter provides the number of bytes received in a good + * TCP segment. This counter does not count IP header bytes */ unsigned long mmc_rx_tcp_gd_octets; + /** This counter provides the number of bytes received in a TCP + * segment that had checksum errors. This counter does not count + * IP header bytes */ unsigned long mmc_rx_tcp_err_octets; + /** This counter provides the number of bytes received in a good + * ICMP segment. This counter does not count IP header bytes */ unsigned long mmc_rx_icmp_gd_octets; + /** This counter provides the number of bytes received in a ICMP + * segment that had checksum errors. This counter does not count + * IP header bytes */ unsigned long mmc_rx_icmp_err_octets; }; /** - * osi_xtra_stat_counters - OSI core extra stat counters - * - * rx_buf_unavail_irq_n: RX buffer unavailable irq count - * tx_proc_stopped_irq_n: Transmit Process Stopped irq count - * tx_buf_unavail_irq_n: Transmit Buffer Unavailable irq count - * rx_proc_stopped_irq_n: Receive Process Stopped irq count - * rx_watchdog_irq_n: Receive Watchdog Timeout irq count - * fatal_bus_error_irq_n: Fatal Bus Error irq count - * q_re_alloc_rx_buf_failed: rx sbk allocation failure count - * tx_normal_irq_n: TX per channel interrupt count - * rx_normal_irq_n: RX per cannel interrupt count - * link_connect_count: link disconnect count - * link_disconnect_count: link connect count + * @brief osi_xtra_stat_counters - OSI core extra stat counters */ struct osi_xtra_stat_counters { + /** RX buffer unavailable irq count */ unsigned long rx_buf_unavail_irq_n[OSI_EQOS_MAX_NUM_QUEUES]; + /** Transmit Process Stopped irq count */ unsigned long tx_proc_stopped_irq_n[OSI_EQOS_MAX_NUM_QUEUES]; + /** Transmit Buffer Unavailable irq count */ unsigned long tx_buf_unavail_irq_n[OSI_EQOS_MAX_NUM_QUEUES]; + /** Receive Process Stopped irq count */ unsigned long rx_proc_stopped_irq_n[OSI_EQOS_MAX_NUM_QUEUES]; + /** Receive Watchdog Timeout irq count */ unsigned long rx_watchdog_irq_n; + /** Fatal Bus Error irq count */ unsigned long fatal_bus_error_irq_n; + /** rx skb allocation failure count */ unsigned long re_alloc_rxbuf_failed[OSI_EQOS_MAX_NUM_QUEUES]; + /** TX per channel interrupt count */ unsigned long tx_normal_irq_n[OSI_EQOS_MAX_NUM_QUEUES]; + /** RX per channel interrupt count */ unsigned long rx_normal_irq_n[OSI_EQOS_MAX_NUM_QUEUES]; + /** link connect count */ unsigned long link_connect_count; + /** link disconnect count */ unsigned long link_disconnect_count; }; /** - * osi_xtra_dma_stat_counters - OSI dma extra stats counters - * q_tx_pkt_n: Per Q TX packet count - * q_rx_pkt_n: Per Q RX packet count - * tx_clean_n: Per Q TX complete call count - * tx_pkt_n: Total number of tx packets count - * rx_pkt_n: Total number of rx packet count - * rx_vlan_pkt_n: Total number of VLAN RX packet count - * tx_vlan_pkt_n: Total number of VLAN TX packet count - * tx_tso_pkt_n: Total number of TSO packet count + * @brief osi_xtra_dma_stat_counters - OSI DMA extra stats counters */ struct osi_xtra_dma_stat_counters { + /** Per Q TX packet count */ unsigned long q_tx_pkt_n[OSI_EQOS_MAX_NUM_QUEUES]; + /** Per Q RX packet count */ unsigned long q_rx_pkt_n[OSI_EQOS_MAX_NUM_QUEUES]; + /** Per Q TX complete call count */ unsigned long tx_clean_n[OSI_EQOS_MAX_NUM_QUEUES]; + /** Total number of tx packets count */ unsigned long tx_pkt_n; + /** Total number of rx packet count */ unsigned long rx_pkt_n; + /** Total number of VLAN RX packet count */ unsigned long rx_vlan_pkt_n; + /** Total number of VLAN TX packet count */ unsigned long tx_vlan_pkt_n; + /** Total number of TSO packet count */ unsigned long tx_tso_pkt_n; }; diff --git a/include/osd.h b/include/osd.h index f216e5d..beb70fe 100644 --- a/include/osd.h +++ b/include/osd.h @@ -23,70 +23,91 @@ #ifndef OSD_H #define OSD_H +/** + * @brief osd_usleep_range - sleep in micro seconds + * + * @param[in] umin: Minimum time in usecs to sleep + * @param[in] umax: Maximum time in usecs to sleep + */ void osd_usleep_range(unsigned long umin, unsigned long umax); +/** + * @brief osd_msleep - sleep in milli seconds + * + * @param[in] msec: time in milli seconds + */ void osd_msleep(unsigned int msec); +/** + * @brief osd_udelay - delay in micro seconds + * + * @param[in] usec: time in usec + */ void osd_udelay(unsigned long usec); +/** + * @brief osd_info - logging function + * + * @param[in] priv: OSD private data + * @param[in] fmt: fragments + */ void osd_info(void *priv, const char *fmt, ...); + +/** + * @brief osd_err - logging function + * + * @param[in] priv: OSD private data + * @param[in] fmt: fragments + */ void osd_err(void *priv, const char *fmt, ...); /** - * osd_receive_packet - Handover received packet to network stack. - * @priv: OSD private data structure. - * @rxring: Pointer to DMA channel Rx ring. - * @chan: DMA Rx channel number. - * @dma_buf_len: Rx DMA buffer length. - * @rxpkt_cx: Received packet context. - * @rx_pkt_swcx: Received packet sw context. + * @brief osd_receive_packet - Handover received packet to network stack. * - * Algorithm: - * 1) Unmap the DMA buffer address. - * 2) Updates socket buffer with len and ether type and handover to - * OS network stack. - * 3) Refill the Rx ring based on threshold. - * 4) Fills the rxpkt_cx->flags with the below bit fields accordingly - * OSI_PKT_CX_VLAN - * OSI_PKT_CX_VALID - * OSI_PKT_CX_CSUM - * OSI_PKT_CX_TSO - * OSI_PKT_CX_PTP + * Algorithm: + * 1) Unmap the DMA buffer address. + * 2) Updates socket buffer with len and ether type and handover to + * OS network stack. + * 3) Refill the Rx ring based on threshold. + * 4) Fills the rxpkt_cx->flags with the below bit fields accordingly + * OSI_PKT_CX_VLAN + * OSI_PKT_CX_VALID + * OSI_PKT_CX_CSUM + * OSI_PKT_CX_TSO + * OSI_PKT_CX_PTP * - * Dependencies: Rx completion need to make sure that Rx descriptors - * processed properly. + * @param[in] priv: OSD private data structure. + * @param[in] rxring: Pointer to DMA channel Rx ring. + * @param[in] chan: DMA Rx channel number. + * @param[in] dma_buf_len: Rx DMA buffer length. + * @param[in] rxpkt_cx: Received packet context. + * @param[in] rx_pkt_swcx: Received packet sw context. * - * Protection: None. - * - * Return: None. + * @note Rx completion need to make sure that Rx descriptors processed properly. */ void osd_receive_packet(void *priv, void *rxring, unsigned int chan, unsigned int dma_buf_len, void *rxpkt_cx, void *rx_pkt_swcx); /** - * osd_transmit_complete - Transmit completion routine. - * @priv: OSD private data structure. - * @buffer: Buffer address to free. - * @dmaaddr: DMA address to unmap. - * @len: Length of data. - * @tx_done_pkt_cx: Pointer to struct which has tx done status info. - * This struct has flags to indicate tx error, whether DMA address - * is mapped from paged/linear buffer, Time stamp availability, - * if TS available txdone_pkt_cx->ns stores the time stamp. - * Below are the valid bit maps set for txdone_pkt_cx->flags - * #define OSI_TXDONE_CX_PAGED_BUF OSI_BIT(0) - * #define OSI_TXDONE_CX_ERROR OSI_BIT(1) - * #define OSI_TXDONE_CX_TS OSI_BIT(2) + * @brief osd_transmit_complete - Transmit completion routine. * - * Algorithm: - * 1) Updates stats for linux network stack. - * 2) unmap and free the buffer DMA address and buffer. - * 3) Time stamp will be updated to stack if available. + * Algorithm: + * 1) Updates stats for Linux network stack. + * 2) unmap and free the buffer DMA address and buffer. + * 3) Time stamp will be updated to stack if available. * - * Dependencies: Tx completion need to make sure that Tx descriptors - * processed properly. + * @param[in] priv: OSD private data structure. + * @param[in] buffer: Buffer address to free. + * @param[in] dmaaddr: DMA address to unmap. + * @param[in] len: Length of data. + * @param[in] txdone_pkt_cx: Pointer to struct which has tx done status info. + * This struct has flags to indicate tx error, whether DMA address + * is mapped from paged/linear buffer, Time stamp availability, + * if TS available txdone_pkt_cx->ns stores the time stamp. + * Below are the valid bit maps set for txdone_pkt_cx->flags + * OSI_TXDONE_CX_PAGED_BUF OSI_BIT(0) + * OSI_TXDONE_CX_ERROR OSI_BIT(1) + * OSI_TXDONE_CX_TS OSI_BIT(2) * - * Protection: None. - * - * Return: None. + * @note Tx completion need to make sure that Tx descriptors processed properly. */ void osd_transmit_complete(void *priv, void *buffer, unsigned long dmaaddr, unsigned int len, void *txdone_pkt_cx); diff --git a/include/osi_common.h b/include/osi_common.h index 0ff3b42..b926b4b 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -23,9 +23,12 @@ #ifndef OSI_COMMON_H #define OSI_COMMON_H +/** + * @addtogroup EQOS-Helper Helper MACROS + * @{ + */ #define OSI_UNLOCKED 0x0U #define OSI_LOCKED 0x1U - #define TEN_POWER_9 0x3B9ACA00U #define TWO_POWER_32 0x100000000ULL #define TWO_POWER_31 0x80000000U @@ -143,7 +146,14 @@ #define H32(data) (((data) & 0xFFFFFFFF00000000UL) >> 32UL) #define OSI_INVALID_CHAN_NUM 0xFFU +/** @} */ +/** + * @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 @@ -185,195 +195,184 @@ #define EQOS_MAC_HFR2_TXCHCNT_MASK 0xfU #define EQOS_MAC_HFR2_PPSOUTNUM_MASK 0x7U #define EQOS_MAC_HFR2_AUXSNAPNUM_MASK 0x7U +/** @} */ /** - * struct osi_hw_features - MAC HW supported features. - * @mii_sel: It sets to 1 when 10/100 Mbps is selected as the Mode of - * Operation - * @gmii_sel: It sets to 1 when 1000 Mbps is selected as the Mode of - * Operation. - * @hd_sel: It sets to 1 when the half-duplex mode is selected. - * @pcs_sel: It sets to 1 when the TBI, SGMII, or RTBI PHY interface - * option is selected. - * @vlan_hash_en: It sets to 1 when the Enable VLAN Hash Table Based - * Filtering option is selected. - * @sma_sel: It sets to 1 when the Enable Station Management - * (MDIO Interface) option is selected. - * @rwk_sel: It sets to 1 when the Enable Remote Wake-Up Packet Detection - * option is selected. - * @mgk_sel: It sets to 1 when the Enable Magic Packet Detection option is - * selected. - * @mmc_sel: It sets to 1 when the Enable MAC Management Counters (MMC) - * option is selected. - * @arp_offld_en: It sets to 1 when the Enable IPv4 ARP Offload option is - * selected. - * @ts_sel: It sets to 1 when the Enable IEEE 1588 Timestamp Support - * option is selected. - * @eee_sel: It sets to 1 when the Enable Energy Efficient Ethernet (EEE) - * option is selected. - * @tx_coe_sel: It sets to 1 when the Enable Transmit TCP/IP Checksum - * Insertion option is selected. - * @rx_coe_sel: It sets to 1 when the Enable Receive TCP/IP Checksum Check - * option is selected. - * @mac_addr16_sel: It sets to 1 when the Enable Additional 1-31 MAC - * Address Registers option is selected. - * @mac_addr32_sel: It sets to 1 when the Enable Additional 32 MAC - * Address Registers (32-63) option is selected - * @mac_addr64_sel: It sets to 1 when the Enable Additional 64 MAC - * Address Registers (64-127) option is selected. - * @tsstssel: It sets to 1 when the Enable IEEE 1588 Timestamp Support - * option is selected. - * @sa_vlan_ins: It sets to 1 when the Enable SA and VLAN Insertion on Tx - * option is selected. - * @act_phy_sel: 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. - * @rx_fifo_size: 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. - * @tx_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. - * @adv_ts_hword: It set to 1 when Advance timestamping High Word selected. - * @addr_64: Address Width. - * This field indicates the configured address width: - * 00: 32 - * 01: 40 - * 10: 48 - * 11: Reserved - * @dcb_en: It sets to 1 when DCB Feature Enable. - * @sph_en: It sets to 1 when Split Header Feature Enable. - * @tso_en: It sets to 1 when TCP Segmentation Offload Enable. - * @dma_debug_gen: It seys to 1 when DMA debug registers are enabled. - * @av_sel: It sets to 1 AV Feature Enabled. - * @hash_tbl_sz: This field indicates the size of the hash table: - * 00: No hash table - * 01: 64 - * 10: 128 - * 11: 256. - * @l3l4_filter_num: 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. - * @rx_q_cnt: It holds number of MTL Receive Queues. - * @tx_q_cnt: It holds number of MTL Transmit Queues. - * @rx_ch_cnt: It holds number of DMA Receive channels. - * @tx_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. - * @pps_out_num: 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 - * @aux_snap_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 + * @brief struct osi_hw_features - MAC HW supported features. */ struct osi_hw_features { - /* HW Feature Register0 */ + /** It is set to 1 when 10/100 Mbps is selected as the Mode of + * Operation */ unsigned int mii_sel; + /** It sets to 1 when 1000 Mbps is selected as the Mode of Operation */ unsigned int gmii_sel; + /** It sets to 1 when the half-duplex mode is selected */ unsigned int hd_sel; + /** It sets to 1 when the TBI, SGMII, or RTBI PHY interface + * option is selected */ unsigned int pcs_sel; + /** It sets to 1 when the Enable VLAN Hash Table Based Filtering + * option is selected */ unsigned int vlan_hash_en; + /** It sets to 1 when the Enable Station Management (MDIO Interface) + * option is selected */ unsigned int sma_sel; + /** It sets to 1 when the Enable Remote Wake-Up Packet Detection + * option is selected */ unsigned int rwk_sel; + /** It sets to 1 when the Enable Magic Packet Detection option is + * selected */ unsigned int mgk_sel; + /** It sets to 1 when the Enable MAC Management Counters (MMC) option + * is selected */ unsigned int mmc_sel; + /** It sets to 1 when the Enable IPv4 ARP Offload option is selected */ unsigned int arp_offld_en; + /** It sets to 1 when the Enable IEEE 1588 Timestamp Support option + * is selected */ unsigned int ts_sel; + /** It sets to 1 when the Enable Energy Efficient Ethernet (EEE) option + * is selected */ unsigned int eee_sel; + /** It sets to 1 when the Enable Transmit TCP/IP Checksum Insertion + * option is selected */ unsigned int tx_coe_sel; + /** It sets to 1 when the Enable Receive TCP/IP Checksum Check option + * is selected */ unsigned int rx_coe_sel; + /** It sets to 1 when the Enable Additional 1-31 MAC Address Registers + * option is selected */ unsigned int mac_addr16_sel; + /** It sets to 1 when the Enable Additional 32-63 MAC Address Registers + * option is selected */ unsigned int mac_addr32_sel; + /** It sets to 1 when the Enable Additional 64-127 MAC Address Registers + * option is selected */ unsigned int mac_addr64_sel; + /** It sets to 1 when the Enable IEEE 1588 Timestamp Support option + * is selected */ unsigned int tsstssel; + /** It sets to 1 when the Enable SA and VLAN Insertion on Tx option + * is selected */ unsigned int 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 */ unsigned int act_phy_sel; - /* HW Feature Register1 */ + /** 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 */ unsigned int 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 */ unsigned int tx_fifo_size; + /** It set to 1 when Advance timestamping High Word selected */ unsigned int adv_ts_hword; + /** Address Width. + * This field indicates the configured address width: + * 00: 32 + * 01: 40 + * 10: 48 + * 11: Reserved */ unsigned int addr_64; + /** It sets to 1 when DCB Feature Enable */ unsigned int dcb_en; + /** It sets to 1 when Split Header Feature Enable */ unsigned int sph_en; + /** It sets to 1 when TCP Segmentation Offload Enable */ unsigned int tso_en; + /** It sets to 1 when DMA debug registers are enabled */ unsigned int dma_debug_gen; + /** It sets to 1 if AV Feature Enabled */ unsigned int av_sel; + /** This field indicates the size of the hash table: + * 00: No hash table + * 01: 64 + * 10: 128 + * 11: 256 */ unsigned int 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 */ unsigned int l3l4_filter_num; - /* HW Feature Register2 */ + /** It holds number of MTL Receive Queues */ unsigned int rx_q_cnt; + /** It holds number of MTL Transmit Queues */ unsigned int tx_q_cnt; + /** It holds number of DMA Receive channels */ unsigned int 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 */ unsigned int 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 */ unsigned int 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 */ unsigned int aux_snap_num; }; /** - * osi_lock_init - Initialize lock to unlocked state. - * @lock - Pointer to lock to be initialized + * @brief osi_lock_init - Initialize lock to unlocked state. * - * Algorithm: Set lock to unlocked state. + * Algorithm: Set lock to unlocked state. * - * Dependencies: None. - * - * Protection: None. - * - * Return: None. + * @param[in] lock - Pointer to lock to be initialized */ static inline void osi_lock_init(unsigned int *lock) { @@ -381,17 +380,14 @@ static inline void osi_lock_init(unsigned int *lock) } /** - * osi_lock_irq_enabled - Spin lock. Busy loop till lock is acquired. - * @lock - Pointer to lock to be acquired. + * @brief osi_lock_irq_enabled - Spin lock. Busy loop till lock is acquired. * - * Algorithm: Atomic compare and swap operation till lock is held. + * Algorithm: Atomic compare and swap operation till lock is held. * - * Dependencies: Does not disable irq. Do not call this API to acquire any + * @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. - * - * Protection: None. - * - * Return: None. */ static inline void osi_lock_irq_enabled(unsigned int *lock) { @@ -407,17 +403,14 @@ static inline void osi_lock_irq_enabled(unsigned int *lock) } /** - * osi_unlock_irq_enabled - Release lock. - * @lock - Pointer to lock to be released. + * @brief osi_unlock_irq_enabled - Release lock. * - * Algorithm: Atomic compare and swap operation to release lock. + * Algorithm: Atomic compare and swap operation to release lock. * - * Dependencies: Does not disable irq. Do not call this API to release any + * @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. - * - * Protection: None. - * - * Return: None. */ static inline void osi_unlock_irq_enabled(unsigned int *lock) { @@ -428,16 +421,13 @@ static inline void osi_unlock_irq_enabled(unsigned int *lock) } /** - * osi_readl - Read a memory mapped regsiter. - * @addr: Memory mapped address. + * @brief osi_readl - Read a memory mapped register. * - * Algorithm: None. + * @param[in] addr: Memory mapped address. * - * Dependencies: Physical address has to be memmory mapped. + * @note Physical address has to be memmory mapped. * - * Protection: None. - * - * Return: Data from memory mapped register - success. + * @return Data from memory mapped register - success. */ static inline unsigned int osi_readl(void *addr) { @@ -445,17 +435,12 @@ static inline unsigned int osi_readl(void *addr) } /** - * osi_writel - Write to a memory mapped regsiter. - * @val: Value to be written. - * @addr: Memory mapped address. + * @brief osi_writel - Write to a memory mapped register. * - * Algorithm: None. + * @param[in] val: Value to be written. + * @param[in] addr: Memory mapped address. * - * Dependencies: Physical address has to be memmory mapped. - * - * Protection: None. - * - * Return: None. + * @note Physical address has to be memmory mapped. */ static inline void osi_writel(unsigned int val, void *addr) { @@ -463,16 +448,14 @@ static inline void osi_writel(unsigned int val, void *addr) } /** - * is_valid_mac_version - Check if read MAC IP is valid or not. - * @mac_ver: MAC version read. + * @brief is_valid_mac_version - Check if read MAC IP is valid or not. * - * Algorithm: None. + * @param[in] mac_ver: MAC version read. * - * Dependencies: MAC has to be out of reset. + * @note MAC has to be out of reset. * - * Protection: None. - * - * Return: 0 - for not Valid MAC, 1 - for Valid MAC + * @retval 0 - for not Valid MAC + * @retval 1 - for Valid MAC */ static inline int is_valid_mac_version(unsigned int mac_ver) { @@ -486,17 +469,17 @@ static inline int is_valid_mac_version(unsigned int mac_ver) } /** - * osi_update_stats_counter - update value by increment passed as parameter - * @last_value: last value of stat counter - * @incr: increment value + * @brief osi_update_stats_counter - update value by increment passed + * as parameter * - * Algorithm: Check for boundary and return sum + * Algorithm: Check for boundary and return sum * - * Dependencies: Input parameter should be only unsigned long type + * @param[in] last_value: last value of stat counter + * @param[in] incr: increment value * - * Protection: None + * @note Input parameter should be only unsigned long type * - * Return: unsigned long value + * @return unsigned long value */ static inline unsigned long osi_update_stats_counter(unsigned long last_value, unsigned long incr) @@ -515,20 +498,36 @@ static inline unsigned long osi_update_stats_counter(unsigned long last_value, } /** - * osi_get_mac_version - Reading MAC version - * @addr: io-remap MAC base address. - * @mac_ver: holds mac version. + * @brief osi_get_mac_version - Reading MAC version * - * Algorithm: Reads MAC version and check whether its valid or not. + * Algorithm: Reads MAC version and check whether its valid or not. * - * Dependencies: MAC has to be out of reset. + * @param[in] addr: io-remap MAC base address. + * @param[in] mac_ver: holds mac version. * - * Protection: None + * @note MAC has to be out of reset. * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ int osi_get_mac_version(void *addr, unsigned int *mac_ver); +/** + * @brief osi_get_hw_features - Reading MAC HW features + * + * @param[in] base: io-remap MAC base address. + * @param[in] hw_feat: holds the supported features of the hardware. + * + * @note MAC has to be out of reset. + */ void osi_get_hw_features(void *base, struct osi_hw_features *hw_feat); +/** + * @brief osi_memset - osi memset + * + * @param[in] s: source that need to be set + * @param[in] c: value to fill in source + * @param[in] count: first n bytes of source + * + */ void osi_memset(void *s, unsigned int c, unsigned long count); #endif /* OSI_COMMON_H */ diff --git a/include/osi_core.h b/include/osi_core.h index c2e899d..c9e8b70 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -29,179 +29,170 @@ struct osi_core_priv_data; /** - * struct osi_filter - The OSI core structure for filters - * @pr_mode: promiscuous mode - * @huc_mode: hash unicast - * @hmc_mode: hash milticast - * @pm_mode: pass all multicast - * @hpf_mode: hash or perfact filter + * @brief OSI core structure for filters */ struct osi_filter { + /** promiscuous mode enable(1) or disable(0) */ unsigned int pr_mode; + /** hash unicast enable(1) or disable(0) */ unsigned int huc_mode; + /** hash multicast enable(1) or disable(0) */ unsigned int hmc_mode; + /** pass all multicast enable(1) or disable(0) */ unsigned int pm_mode; + /** 0x0 (DISABLE): Hash or Perfect Filter is disabled + * + * 0x1 (ENABLE): Hash or Perfect Filter is enabled */ unsigned int hpf_mode; }; /** - * Structure osi_l3_l4_filter - L3/L4 filter Function dependent - * parameter - * - * @filter_no: filter index 0- 7 - * @filter_enb_dis: enable/disable - * @src_dst_addr_match: source(0) or destination(1) - * @perfect_inverse_match: perfect(0) or inverse(1) - * @ip4_addr: ipv4 address - * @ip6_addr: ipv6 address - * @port_no: Port number + * @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 */ unsigned int filter_no; + /** filter enable(1) or disable(0) */ unsigned int filter_enb_dis; + /** source(0) or destination(1) */ unsigned int src_dst_addr_match; + /** perfect(0) or inverse(1) */ unsigned int perfect_inverse_match; + /** ipv4 address */ unsigned char ip4_addr[4]; + /** ipv6 address */ unsigned short ip6_addr[8]; + /** Port number */ unsigned short port_no; }; /** - * Structure osi_vlan_filter - Vlan filter Function dependent parameter - * - * @filter_enb_dis: enable/disable - * @perfect_hash: perfect(0) or hash(1) - * @perfect_inverse_match: perfect(0) or inverse(1) + * @brief Vlan filter Function dependent parameter */ struct osi_vlan_filter { + /** vlan filter enable(1) or disable(0) */ unsigned int filter_enb_dis; + /** perfect(0) or hash(1) */ unsigned int perfect_hash; + /** perfect(0) or inverse(1) */ unsigned int perfect_inverse_match; }; /** - * Struct osi_l2_da_filter - L2 filter function depedent parameter - * @perfect_hash: perfect(0) or hash(1) - * @perfect_inverse_match: perfect(0) or inverse(1) + * @brief L2 filter function dependent parameter */ struct osi_l2_da_filter { + /** perfect(0) or hash(1) */ unsigned int perfect_hash; + /** perfect(0) or inverse(1) */ unsigned int perfect_inverse_match; }; /** - * struct osi_core_avb_algorithm - The OSI Core avb data structure per - * queue. - * @qindex: TX Queue/TC index - * @algo: AVB algorithm 1:CBS - * @credit_control: credit control 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 - * @idle_slope: idleSlopeCredit value required for CBS - * @send_slope: sendSlopeCredit value required for CBS - * @hi_credit: hiCredit value required for CBS - * @low_credit: lowCredit value required for CBS - * @oper_mode: Transmit queue enable 01: avb 10: enable 00: disable + * @brief OSI Core avb data structure per queue. */ struct osi_core_avb_algorithm { + /** TX Queue/TC index */ unsigned int qindex; + /** CBS Algorithm enable(1) or disable(0) */ unsigned int 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) */ unsigned int credit_control; - unsigned int idle_slope; + /** idleSlopeCredit value required for CBS */ + unsigned int idle_slope; + /** sendSlopeCredit value required for CBS */ unsigned int send_slope; + /** hiCredit value required for CBS */ unsigned int hi_credit; + /** lowCredit value required for CBS */ unsigned int low_credit; + /** Transmit queue operating mode + * + * 00: disable + * + * 01: avb + * + * 10: enable */ unsigned int oper_mode; }; /** - * struct osi_core_ops - Core (MAC & MTL) operations. - * @poll_for_swr: Called to poll for software reset bit. - * @core_init: Called to initialize MAC and MTL registers. - * @core_deinit: Called to deinitialize MAC and MTL registers. - * @validate_regs: Called periodically to read and validate safety critical - * registers against last written value. - * @start_mac: Called to start MAC Tx and Rx engine. - * @stop_mac: Called to stop MAC Tx and Rx engine. - * @handle_common_intr: Called to handle common interrupt. - * @set_mode: Called to set the mode at MAC (full/duplex). - * @set_speed: Called to set the speed (10/100/1000) at MAC. - * @pad_calibrate: Called to do pad caliberation. - * @set_mdc_clk_rate: Called to set MDC clock rate for MDIO operation. - * @flush_mtl_tx_queue: Called to flush MTL Tx queue. - * @config_mac_loopback: Called to configure MAC in loopback mode. - * @set_avb_algorithm: Called to set av parameter. - * @get_avb_algorithm: Called to get av parameter, - * @config_fw_err_pkts: Called to configure MTL RxQ to forward the err pkt. - * @config_tx_status: Called to configure the MTL to forward/drop tx status - * @config_rx_crc_check: Called to configure the MAC rx crc. - * @config_flow_control: Called to configure the MAC flow control. - * @config_arp_offload: Called to enable/disable HW ARP offload feature. - * @config_rxcsum_offload: Called to configure Rx Checksum offload engine. - * @config_mac_pkt_filter_reg: Called to config mac packet filter. - * @update_mac_addr_low_high_reg: Called to update MAC address 1-127. - * @config_l3_l4_filter_enable: Called to configure l3/L4 filter. - * @config_l2_da_perfect_inverse_match: Called to configure L2 DA filter. - * @config_l3_filters: Called to configure L3 filter. - * @update_ip4_addr: Called to update ip4 src or desc address. - * @update_ip6_addr: Called to update ip6 address. - * @config_l4_filters: Called to configure L4 filter. - * @update_l4_port_no: Called to update L4 Port for filter packet. - * @config_vlan_filtering: Called to configure VLAN filtering. - * @update_vlan_id: called to update VLAN id. - * @set_systime_to_mac: Called to set current system time to MAC. - * @config_addend: Called to set the addend value to adjust the time. - * @adjust_systime: Called to adjust the system time. - * @get_systime_from_mac: Called to get the current time from MAC. - * @config_tscr: Called to configure the TimeStampControl register. - * @config_ssir: Called to configure the sub second increment register. - * @read_mmc: called to update MMC counter from HW register - * @reset_mmc: called to reset MMC HW counter and Structure + * @brief Initialize MAC & MTL core operations. */ struct osi_core_ops { - /* initialize MAC/MTL/DMA Common registers */ + /** Called to poll for software reset bit */ int (*poll_for_swr)(void *ioaddr); + /** Called to initialize MAC and MTL registers */ int (*core_init)(struct osi_core_priv_data *osi_core, unsigned int tx_fifo_size, unsigned int rx_fifo_size); + /** Called to deinitialize MAC and MTL registers */ void (*core_deinit)(struct osi_core_priv_data *osi_core); + /** Called periodically to read and validate safety critical + * registers against last written value */ int (*validate_regs)(struct osi_core_priv_data *osi_core); + /** Called to start MAC Tx and Rx engine */ void (*start_mac)(void *addr); + /** Called to stop MAC Tx and Rx engine */ void (*stop_mac)(void *addr); + /** Called to handle common interrupt */ void (*handle_common_intr)(struct osi_core_priv_data *osi_core); + /** Called to set the mode at MAC (full/duplex) */ void (*set_mode)(void *ioaddr, int mode); + /** Called to set the speed (10/100/1000) at MAC */ void (*set_speed)(void *ioaddr, int speed); + /** Called to do pad caliberation */ int (*pad_calibrate)(void *ioaddr); + /** Called to set MDC clock rate for MDIO operation */ void (*set_mdc_clk_rate)(struct osi_core_priv_data *osi_core, unsigned long csr_clk_rate); + /** Called to flush MTL Tx queue */ int (*flush_mtl_tx_queue)(void *ioaddr, unsigned int qinx); + /** Called to configure MAC in loopback mode */ int (*config_mac_loopback)(void *addr, unsigned int lb_mode); + /** Called to set av parameter */ int (*set_avb_algorithm)(struct osi_core_priv_data *osi_core, struct osi_core_avb_algorithm *avb); + /** Called to get av parameter */ int (*get_avb_algorithm)(struct osi_core_priv_data *osi_core, struct osi_core_avb_algorithm *avb); + /** Called to configure MTL RxQ to forward the err pkt */ int (*config_fw_err_pkts)(void *addr, unsigned int qinx, unsigned int fw_err); + /** Called to configure the MTL to forward/drop tx status */ int (*config_tx_status)(void *addr, unsigned int tx_status); + /** Called to configure the MAC rx crc */ int (*config_rx_crc_check)(void *addr, unsigned int crc_chk); + /** Called to configure the MAC flow control */ int (*config_flow_control)(void *addr, unsigned int flw_ctrl); + /** Called to enable/disable HW ARP offload feature */ int (*config_arp_offload)(unsigned int mac_ver, void *addr, unsigned int enable, unsigned char *ip_addr); + /** Called to configure Rx Checksum offload engine */ int (*config_rxcsum_offload)(void *addr, unsigned int enabled); + /** Called to config mac packet filter */ void (*config_mac_pkt_filter_reg)(struct osi_core_priv_data *osi_core, struct osi_filter filter); + /** Called to update MAC address 1-127 */ int (*update_mac_addr_low_high_reg)( - struct osi_core_priv_data *osi_core, + struct osi_core_priv_data *osi_core, unsigned int index, unsigned char value[], unsigned int dma_routing_enable, unsigned int dma_chan, unsigned int addr_mask, unsigned int src_dest); + /** Called to configure l3/L4 filter */ int (*config_l3_l4_filter_enable)(void *base, unsigned int enable); + /** Called to configure L2 DA filter */ int (*config_l2_da_perfect_inverse_match)(void *base, unsigned int perfect_inverse_match); + /** Called to configure L3 filter */ int (*config_l3_filters)(struct osi_core_priv_data *osi_core, unsigned int filter_no, unsigned int enb_dis, unsigned int ipv4_ipv6_match, @@ -209,11 +200,14 @@ struct osi_core_ops { unsigned int perfect_inverse_match, unsigned int dma_routing_enable, unsigned int dma_chan); + /** Called to update ip4 src or desc address */ int (*update_ip4_addr)(struct osi_core_priv_data *osi_core, unsigned int filter_no, unsigned char addr[], unsigned int src_dst_addr_match); + /** Called to update ip6 address */ int (*update_ip6_addr)(struct osi_core_priv_data *osi_core, unsigned int filter_no, unsigned short addr[]); + /** Called to configure L4 filter */ int (*config_l4_filters)(struct osi_core_priv_data *osi_core, unsigned int filter_no, unsigned int enb_dis, unsigned int tcp_udp_match, @@ -221,527 +215,543 @@ struct osi_core_ops { unsigned int perfect_inverse_match, unsigned int dma_routing_enable, unsigned int dma_chan); + /** Called to update L4 Port for filter packet */ int (*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); - /* for VLAN filtering */ - int (*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); + /** Called to configure VLAN filtering */ + int (*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); + /** called to update VLAN id */ int (*update_vlan_id)(void *base, unsigned int vid); + /** Called to set current system time to MAC */ int (*set_systime_to_mac)(void *addr, unsigned int sec, unsigned int nsec); + /** Called to set the addend value to adjust the time */ int (*config_addend)(void *addr, unsigned int addend); + /** Called to adjust the system time */ int (*adjust_systime)(void *addr, unsigned int sec, unsigned int nsec, unsigned int neg_adj, unsigned int one_nsec_accuracy); + /** Called to get the current time from MAC */ unsigned long long (*get_systime_from_mac)(void *addr); + /** Called to configure the TimeStampControl register */ void (*config_tscr)(void *addr, unsigned int ptp_filter); + /** Called to configure the sub second increment register */ void (*config_ssir)(void *addr, unsigned int ptp_clock); + /** Called to update MMC counter from HW register */ void (*read_mmc)(struct osi_core_priv_data *osi_core); + /** Called to reset MMC HW counter structure */ void (*reset_mmc)(struct osi_core_priv_data *osi_core); }; /** - * struct osi_ptp_config - PTP configuration - * @ptp_filter: PTP filter parameters bit fields. - * Enable Time stamp,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_fitler is set to Zero then Time stamping is disabled. - * @sec: Seconds - * @nsec: Nano seconds - * @ptp_ref_clk_rate: PTP reference clock read from DT - * @one_nsec_accuracy: Use one nsec accuracy (need to set 1) - * @ptp_clock: PTP system clock which is 62500000Hz + * @brief PTP configuration structure */ struct osi_ptp_config { + /** PTP filter parameters bit fields. + * + * Enable Time stamp,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_fitler is set to Zero then Time stamping is disabled */ unsigned int ptp_filter; + /** seconds to be updated to MAC */ unsigned int sec; + /** nano seconds to be updated to MAC */ unsigned int nsec; + /** PTP reference clock read from DT */ unsigned int ptp_ref_clk_rate; + /** Use one nsec accuracy (need to set 1) */ unsigned int one_nsec_accuracy; + /** PTP system clock which is 62500000Hz */ unsigned int ptp_clock; }; /** - * struct osi_core_priv_data - The OSI Core (MAC & MTL) private data - structure. - * @base: Memory mapped base address of MAC IP. - * @osd: Pointer to OSD private data structure. - * @ops: Address of HW Core operations structure. - * @num_mtl_queues: Number of MTL queues enabled in MAC. - * @mtl_queues: Array of MTL queues. - * @rxq_ctrl: List of MTL Rx queue mode that need to be enabled - * @rxq_prio: Rx MTl Queue mapping based on User Priority field - * @mac: MAC HW type EQOS based on DT compatible. - * @mac_ver: MAC version. - * @mdc_cr: MDC clock rate. - * @mtu: MTU size - * @mac_addr: Ethernet MAC address. - * @pause_frames: DT entry to enable(0) or disable(1) pause frame support - * @flow_ctrl: Current flow control settings - * @ptp_config: PTP configuration settings. - * @default_addend: Default addend value. - * @mmc: mmc counter structure - * @xstats: xtra sw error counters - * @dcs_en: DMA channel selection enable (1) - * @safety_config: Functional safety config to do periodic read-verify of - * certain safety critical registers. + * @brief The OSI Core (MAC & MTL) private data structure. */ struct osi_core_priv_data { + /** Memory mapped base address of MAC IP */ void *base; + /** Pointer to OSD private data structure */ void *osd; + /** Address of HW Core operations structure */ struct osi_core_ops *ops; + /** Number of MTL queues enabled in MAC */ unsigned int num_mtl_queues; - unsigned int mtl_queues[OSI_EQOS_MAX_NUM_QUEUES]; - unsigned int rxq_ctrl[OSI_EQOS_MAX_NUM_QUEUES]; - unsigned int rxq_prio[OSI_EQOS_MAX_NUM_QUEUES]; + /** Array of MTL queues */ + unsigned int mtl_queues[OSI_EQOS_MAX_NUM_CHANS]; + /** List of MTL Rx queue mode that need to be enabled */ + unsigned int rxq_ctrl[OSI_EQOS_MAX_NUM_CHANS]; + /** Rx MTl Queue mapping based on User Priority field */ + unsigned int rxq_prio[OSI_EQOS_MAX_NUM_CHANS]; + /** MAC HW type EQOS based on DT compatible */ unsigned int mac; + /** MAC version */ unsigned int mac_ver; + /** MDC clock rate */ unsigned int mdc_cr; + /** MTU size */ unsigned int mtu; + /** Ethernet MAC address */ unsigned char mac_addr[OSI_ETH_ALEN]; + /** DT entry to enable(0) or disable(1) pause frame support */ unsigned int pause_frames; + /** Current flow control settings */ unsigned int flow_ctrl; + /** PTP configuration settings */ struct osi_ptp_config ptp_config; + /** Default addend value */ unsigned int 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) */ unsigned int dcs_en; + /** Functional safety config to do periodic read-verify of + * certain safety critical registers */ void *safety_config; }; /** - * osi_poll_for_swr - Poll Software reset bit in MAC HW - * @osi: OSI Core private data structure. + * @brief osi_poll_for_swr - Poll Software reset bit in MAC HW * - * Algorithm: Invokes EQOS routine to check for SWR (software reset) - * bit in DMA Basic mooe register to make sure IP reset was successful. + * Algorithm: Invokes EQOS routine to check for SWR (software reset) + * bit in DMA Basic mode register to make sure IP reset was successful. * - * Dependencies: - * 1) MAC needs to be out of reset and proper clock configured. + * @param[in] osi_core: OSI Core private data structure. * - * Protection: None + * @note MAC needs to be out of reset and proper clock configured. * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ int osi_poll_for_swr(struct osi_core_priv_data *osi_core); /** - * osi_set_mdc_clk_rate - Derive MDC clock based on provided AXI_CBB clk. - * @osi: OSI core private data structure. - * @csr_clk_rate: CSR (AXI CBB) clock rate. + * @brief osi_set_mdc_clk_rate - Derive MDC clock based on provided AXI_CBB clk. * - * Algorithm: MDC clock rate will be populated in OSI core private data - * structure based on AXI_CBB clock rate. + * Algorithm: MDC clock rate will be populated in OSI core private data + * structure based on AXI_CBB clock rate. * - * Dependencies: - * 1) OSD layer needs get the AXI CBB clock rate with OSD clock API + * @param[in] osi_core: OSI core private data structure. + * @param[in] csr_clk_rate: CSR (AXI CBB) clock rate. + * + * @note OSD layer needs get the AXI CBB clock rate with OSD clock API * (ex - clk_get_rate()) * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ int osi_set_mdc_clk_rate(struct osi_core_priv_data *osi_core, unsigned long csr_clk_rate); /** - * osi_hw_core_init - EQOS MAC, MTL and common DMA initialization. - * @osi: OSI core private data structure. + * @brief osi_hw_core_init - EQOS MAC, MTL and common DMA initialization. + * + * Algorithm: Invokes EQOS MAC, MTL and common DMA register init code. * - * Algorithm: Invokes EQOS MAC, MTL and common DMA register init code. + * @param[in] 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. * - * Dependencies: - * 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. + * @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. * - * Protection: None - * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ int osi_hw_core_init(struct osi_core_priv_data *osi_core, unsigned int tx_fifo_size, unsigned int rx_fifo_size); /** - * osi_hw_core_deinit - EQOS MAC deinitialization. - * @osi: OSI core private data structure. + * @brief osi_hw_core_deinit - EQOS MAC deinitialization. + * + * Algorithm: Stops MAC transmisson and reception. * - * Algorithm: Stops MAC transmisson and reception. + * @param[in] osi_core: OSI core private data structure. * - * Dependencies: MAC has to be out of reset. + * @note MAC has to be out of reset. * - * Protection: None - * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ int osi_hw_core_deinit(struct osi_core_priv_data *osi_core); /** - * osi_validate_core_regs - Read-validate HW registers for func safety. - * @osi_core: OSI core private data structure. + * @brief osi_validate_core_regs - Read-validate HW registers for func safety. * - * Algorithm: Reads pre-configured list of MAC/MTL configuration registers + * Algorithm: Reads pre-configured list of MAC/MTL configuration registers * and compares with last written value for any modifications. * - * Dependencies: + * @param[in] osi_core: OSI core private data structure. + * + * @note * 1) MAC has to be out of reset. * 2) 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 + * the safety_config (see osi_core_priv_data) based on MAC version and * which specific registers needs to be validated periodically. * 3) Invoke this call iff (osi_core_priv_data->safety_config != OSI_NULL) * - * Protection: None - * - * Return: 0 - success, -1 - failure (reg value has changed) + * @retval 0 on success + * @retval -1 on failure. */ int osi_validate_core_regs(struct osi_core_priv_data *osi_core); /** - * osi_start_mac - Start MAC Tx/Rx engine - * @osi_core: OSI core private data. + * @brief osi_start_mac - Start MAC Tx/Rx engine + * + * Algorithm: Enable MAC Tx and Rx engine. * - * Algorimthm: Enable MAC Tx and Rx engine. + * @param[in] osi_core: OSI core private data structure. * - * Dependencies: - * 1) MAC init should be complete. See osi_hw_core_init() and - * osi_hw_dma_init() + * @note MAC init should be complete. See osi_hw_core_init() and + * osi_hw_dma_init() * - * Protection: None - * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ int osi_start_mac(struct osi_core_priv_data *osi_core); /** - * osi_stop_mac - Stop MAC Tx/Rx engine - * @osi_core: OSI core private data. + * @brief osi_stop_mac - Stop MAC Tx/Rx engine + * + * Algorithm: Stop MAC Tx and Rx engine * - * Algorimthm: Stop MAC Tx and Rx engine + * @param[in] osi_core: OSI core private data structure. * - * Dependencies: - * 1) MAC DMA deinit should be complete. See osi_hw_dma_deinit() + * @note MAC DMA deinit should be complete. See osi_hw_dma_deinit() * - * Protection: None - * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ int osi_stop_mac(struct osi_core_priv_data *osi_core); /** - * osi_common_isr - Common ISR. - * @osi_core: OSI core private data structure. + * @brief osi_common_isr - Common ISR. + * + * Algorithm: Takes care of handling the common interrupts accordingly as per + * the MAC IP * - * Algorithm: Takes care of handling the - * common interrupts accordingly as per the - * MAC IP + * @param[in] osi_core: OSI core private data structure. * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() + * @note MAC should be init and started. see osi_start_mac() * - * Protection: None - * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ int osi_common_isr(struct osi_core_priv_data *osi_core); /** - * osi_set_mode - Set FD/HD mode. - * @osi: OSI private data structure. - * @mode: Operating mode. + * @brief osi_set_mode - Set FD/HD mode. * - * Algorithm: Takes care of setting HD or FD mode - * accordingly as per the MAC IP. + * Algorithm: Takes care of setting HD or FD mode accordingly as per the MAC IP * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() + * @param[in] osi_core: OSI core private data structure. + * @param[in] mode: Operating mode. * - * Protection: None + * @note MAC should be init and started. see osi_start_mac() * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ int osi_set_mode(struct osi_core_priv_data *osi_core, int mode); /** - * osi_set_speed - Set operating speed. - * @osi: OSI private data structure. - * @speed: Operating speed. + * @brief osi_set_speed - Set operating speed. + * + * Algorithm: Takes care of setting the operating speed accordingly as per + * the MAC IP. * - * 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. * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() + * @note MAC should be init and started. see osi_start_mac() * - * Protection: None - * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ int osi_set_speed(struct osi_core_priv_data *osi_core, int speed); /** - * osi_pad_calibrate - PAD calibration - * @osi: OSI core private data structure. + * @brief osi_pad_calibrate - PAD calibration * - * Algorithm: Takes care of doing the pad calibration - * accordingly as per the MAC IP. + * Algorithm: Takes care of doing the pad calibration + * accordingly as per the MAC IP. * - * Dependencies: + * @param[in] osi_core: OSI core private data structure. + * + * @note * 1) MAC should out of reset and clocks enabled. * 2) RGMII and MDIO interface needs to be IDLE before performing PAD * calibration. * - * Protection: None - * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ int osi_pad_calibrate(struct osi_core_priv_data *osi_core); /** - * osi_flush_mtl_tx_queue - Flushing a MTL Tx Queue. - * @osi_core: OSI private data structure. - * @qinx: MTL queue index. + * @brief osi_flush_mtl_tx_queue - Flushing a MTL Tx Queue. * - * Algorithm: Invokes EQOS flush Tx queue routine. + * Algorithm: Invokes EQOS flush Tx queue routine. * - * Dependencies: + * @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(). * - * Protection: None - * - * Return: 0 - success, -1 - failure. + * @retval 0 on success + * @retval -1 on failure. */ int osi_flush_mtl_tx_queue(struct osi_core_priv_data *osi_core, unsigned int qinx); /** - * osi_config_mac_loopback - Configure MAC loopback - * @osi: OSI private data structure. - * @lb_mode: Enable or disable MAC loopback + * @brief osi_config_mac_loopback - Configure MAC loopback * - * Algorithm: Configure the MAC to support the loopback. + * Algorithm: Configure the MAC to support the loopback. * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() + * @param[in] osi_core: OSI core private data structure. + * @param[in] lb_mode: Enable or disable MAC loopback * - * Protection: None + * @note MAC should be init and started. see osi_start_mac() * - * Return: 0 - success, -1 - failure. + * @retval 0 on success + * @retval -1 on failure. */ int osi_config_mac_loopback(struct osi_core_priv_data *osi_core, unsigned int lb_mode); /** - * osi_set_avb - Set CBS algo and parameters - * @osi: OSI core private data structure. - * @avb: osi core avb data structure. + * @brief osi_set_avb - Set CBS algo and parameters * - * Algorithm: Set AVB algo and populated parameter from osi_core_avb - * structure for TC/TQ + * Algorithm: Set AVB algo and populated parameter from osi_core_avb + * structure for TC/TQ * - * Dependencies: + * @param[in] osi_core: OSI core private data structure. + * @param[in] avb: osi core avb data structure. + * + * @note * 1) MAC should be init and started. see osi_start_mac() * 2) osi_core->osd should be populated. * - * Return: Success = 0; failure = -1; + * @retval 0 on success + * @retval -1 on failure. */ int osi_set_avb(struct osi_core_priv_data *osi_core, struct osi_core_avb_algorithm *avb); -/** osi_get_avb - Get CBS algo and parameters - * @osi: OSI core private data structure. - * @avb: osi core avb data structure. +/** + * @brief osi_get_avb - Get CBS algo and parameters * - * Algorithm: get AVB algo and populated parameter from osi_core_avb - * structure for TC/TQ + * Algorithm: get AVB algo and populated parameter from osi_core_avb + * structure for TC/TQ * - * Dependencies: + * @param[in] osi_core: OSI core private data structure. + * @param[out] avb: osi core avb data structure. + * + * @note * 1) MAC should be init and started. see osi_start_mac() * 2) osi_core->osd should be populated. * - * Return: Success = 0; failure = -1; + * @retval 0 on success + * @retval -1 on failure. */ int osi_get_avb(struct osi_core_priv_data *osi_core, struct osi_core_avb_algorithm *avb); /** - * osi_configure_txstatus - Configure Tx packet status reporting - * @osi_core: OSI private data structure. - * @tx_status: Enable or disable tx packet status reporting + * @brief osi_configure_txstatus - Configure Tx packet status reporting * - * Algorithm: Configure MAC to enable/disable Tx status error - * reporting. + * Algorithm: Configure MAC to enable/disable Tx status error + * reporting. * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() + * @param[in] osi_core: OSI core private data structure. + * @param[in] tx_status: Enable or disable tx packet status reporting * - * Protection: None + * @note MAC should be init and started. see osi_start_mac() * - * Return: 0 - success, -1 - failure. + * @retval 0 on success + * @retval -1 on failure. */ int osi_configure_txstatus(struct osi_core_priv_data *osi_core, unsigned int tx_status); /** - * osi_config_fw_err_pkts - Configure forwarding of error packets - * @osi_core: OSI core private data structure. - * @qinx: Q index - * @fw_err: Enable or disable forwarding of error packets + * @brief osi_config_fw_err_pkts - Configure forwarding of error packets * - * Algorithm: Configure MAC to enable/disable forwarding of error packets. + * Algorithm: Configure MAC to enable/disable forwarding of error packets. * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() + * @param[in] osi_core: OSI core private data structure. + * @param[in] qinx: Q index + * @param[in] fw_err: Enable or disable forwarding of error packets * - * Protection: None + * @note MAC should be init and started. see osi_start_mac() * - * Return: 0 - success, -1 - failure. + * @retval 0 on success + * @retval -1 on failure. */ int osi_config_fw_err_pkts(struct osi_core_priv_data *osi_core, unsigned int qinx, unsigned int fw_err); /** - * osi_config_rx_crc_check - Configure CRC Checking for Received Packets - * @osi_core: OSI core private data structure. - * @crc_chk: Enable or disable checking of CRC field in received packets + * @brief osi_config_rx_crc_check - Configure CRC Checking for Received Packets * - * 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. + * 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. * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() + * @param[in] osi_core: OSI core private data structure. + * @param[in] crc_chk: Enable or disable checking of CRC field in received pkts * - * Protection: None + * @note MAC should be init and started. see osi_start_mac() * - * Return: 0 - success, -1 - failure. + * @retval 0 on success + * @retval -1 on failure. */ int osi_config_rx_crc_check(struct osi_core_priv_data *osi_core, unsigned int crc_chk); /** - * osi_configure_flow_ctrl - Configure flow control settings - * @osi_core: OSI core private data structure. - * @crc_chk: Enable or disable flow control settings + * @brief osi_configure_flow_ctrl - Configure flow control settings * - * Algorithm: This will enable or disable the flow control. - * flw_ctrl BIT0 is for tx flow ctrl enable/disable - * flw_ctrl BIT1 is for rx flow ctrl enable/disable + * Algorithm: This will enable or disable the flow control. + * flw_ctrl BIT0 is for tx flow ctrl enable/disable + * flw_ctrl BIT1 is for rx flow ctrl enable/disable * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() + * @param[in] osi_core: OSI core private data structure. + * @param[in] flw_ctrl: Enable or disable flow control settings * - * Protection: None + * @note MAC should be init and started. see osi_start_mac() * - * Return: 0 - success, -1 - failure. + * @retval 0 on success + * @retval -1 on failure. */ int osi_configure_flow_control(struct osi_core_priv_data *osi_core, unsigned int flw_ctrl); -/** osi_config_arp_offload - Configure ARP offload in MAC. - * @osi_core: OSI private data structure. - * @flags: Enable/disable flag. - * @ip_addr: Char array representation of IP address - * to be set in HW to compare with ARP requests received. +/** + * @brief osi_config_arp_offload - Configure ARP offload in MAC. * - * Algorithm: Invokes EQOS config ARP offload routine. + * Algorithm: Invokes EQOS config ARP offload routine. * - * Dependencies: + * @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 + * + * @note * 1) MAC should be init and started. see osi_start_mac() - * 2) Valid 4 byte IP address as argument @ip_addr + * 2) Valid 4 byte IP address as argument ip_addr * - * Protection: None - * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ int osi_config_arp_offload(struct osi_core_priv_data *osi_core, unsigned int flags, unsigned char *ip_addr); -/* - * osi_config_rxcsum_offload - Configure RX checksum offload in MAC. - * @osi_core: OSI private data structure. - * @enable: Enable/disable flag. +/** + * @brief osi_config_rxcsum_offload - Configure RX checksum offload in MAC. * - * Algorithm: Invokes EQOS config RX checksum offload routine. + * Algorithm: Invokes EQOS config RX checksum offload routine. * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() + * @param[in] osi_core: OSI core private data structure. + * @param[in] enable: Enable/disable flag. * - * Protection: None + * @note MAC should be init and started. see osi_start_mac() * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ int osi_config_rxcsum_offload(struct osi_core_priv_data *osi_core, unsigned int enable); /** - * osi_config_mac_pkt_filter_reg - configure mac filter register. - * @osi_core: OSI private data structure. - * @pfilter: OSI filter structure. + * @brief osi_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. + * Algorithm: This sequence is used to configure MAC in differnet packet + * processing modes like promiscuous, multicast, unicast, + * hash unicast/multicast. * - * Dependencies: + * @param[in] osi_core: OSI core private data structure. + * @param[in] pfilter: OSI filter structure. + * + * @note * 1) MAC should be initialized and started. see osi_start_mac() * 2) MAC addresses should be configured in HW registers. see * osi_update_mac_addr_low_high_reg(). * - * Protection: None - * - * Return: 0 - success, -1 - failure. + * @retval 0 on success + * @retval -1 on failure. */ int osi_config_mac_pkt_filter_reg(struct osi_core_priv_data *osi_core, struct osi_filter pfilter); /** - * osi_update_mac_addr_low_high_reg- invoke API to update L2 address + * @brief osi_update_mac_addr_low_high_reg- invoke API to update L2 address * in filter register * - * @osi_core: OSI private data structure. - * @index: filter index - * @value: MAC address to write - * @dma_routing_enable: dma channel routing enable(1) - * @dma_chan: dma channel number - * @addr_mask: filter will not consider byte in comparison + * 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] index: filter index + * @param[in] value: MAC address to write + * @param[in] dma_routing_enable: dma channel routing enable(1) + * @param[in] dma_chan: dma channel number + * @param[in] addr_mask: filter will not consider byte in comparison * Bit 29: MAC_Address${i}_High[15:8] * Bit 28: MAC_Address${i}_High[7:0] * Bit 27: MAC_Address${i}_Low[31:24] * .. * Bit 24: MAC_Address${i}_Low[7:0] - * @src_dest: SA(1) or DA(0) + * @param[in] src_dest: SA(1) or DA(0) * - * 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. - * - * Dependencies: + * @note * 1) MAC should be initialized and stated. see osi_start_mac() * 2) osi_core->osd should be populated. * - * Protection: None - * - * Return: 0 - success, -1 - failure. + * @retval 0 on success + * @retval -1 on failure. */ int osi_update_mac_addr_low_high_reg(struct osi_core_priv_data *osi_core, unsigned int index, @@ -752,51 +762,48 @@ int osi_update_mac_addr_low_high_reg(struct osi_core_priv_data *osi_core, unsigned int src_dest); /** - * osi_config_l3_l4_filter_enable - invoke OSI call to eanble L3/L4 + * @brief osi_config_l3_l4_filter_enable - invoke OSI call to enable L3/L4 * filters. * - * @osi_core: OSI private data structure. - * @enable: enable/disable + * Algorithm: This routine to enable/disable L4/l4 filter * - * Algorithm: This routine to enable/disable L4/l4 filter + * @param[in] osi_core: OSI core private data structure. + * @param[in] enable: enable/disable * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() + * @note MAC should be init and started. see osi_start_mac() * - * Protection: None - * - * Return: 0 - success, -1 - failure. + * @retval 0 on success + * @retval -1 on failure. */ int osi_config_l3_l4_filter_enable(struct osi_core_priv_data *osi_core, unsigned int enable); /** - * osi_config_l3_filters - invoke OSI call config_l3_filters. + * @brief osi_config_l3_filters - invoke OSI call config_l3_filters. * - * @osi_core: OSI private data structure. - * @filter_no: filter index - * @enb_dis: 1 - enable otherwise - disable L3 filter - * @ipv4_ipv6_match: 1 - IPv6, otherwise - IPv4 - * @src_dst_addr_match: 0 - source, otherwise - destination - * @perfect_inverse_match: normal match(0) or inverse map(1) - * @dma_routing_enable: filter based dma routing enable(1) - * @dma_chan: dma channel for routing based on filter + * 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. * - * 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 * - * Dependencies: + * @note * 1) MAC should be init and started. see osi_start_mac() * 2) L3/L4 filtering should be enabled in MAC PFR register. See * osi_config_l3_l4_filter_enable() * 3) osi_core->osd should be populated * 4) DCS bits should be enabled in RXQ to DMA map register * - * Protection: None - * - * Return: 0 - success, -1 - failure. + * @retval 0 on success + * @retval -1 on failure. */ int osi_config_l3_filters(struct osi_core_priv_data *osi_core, unsigned int filter_no, @@ -808,23 +815,23 @@ int osi_config_l3_filters(struct osi_core_priv_data *osi_core, unsigned int dma_chan); /** - * osi_update_ip4_addr - invoke OSI call update_ip4_addr. - * @osi_core: OSI private data structure. - * @filter_no: filter index - * @addr: ipv4 address - * @src_dst_addr_match: 0- source(addr0) 1- dest (addr1) + * @brief osi_update_ip4_addr - invoke OSI call update_ip4_addr. * - * Algorithm: This sequence is used to update IPv4 source/destination - * Address for L3 layer filtering + * Algorithm: This sequence is used to update IPv4 source/destination + * Address for L3 layer filtering * - * Dependencies: + * @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(addr0) 1- dest (addr1) + * + * @note * 1) MAC should be init and started. see osi_start_mac() * 2) L3/L4 filtering should be enabled in MAC PFR register. See * osi_config_l3_l4_filter_enable() * - * Protection: None - * - * Return: 0 - success, -1 - failure. + * @retval 0 on success + * @retval -1 on failure. */ int osi_update_ip4_addr(struct osi_core_priv_data *osi_core, unsigned int filter_no, @@ -832,51 +839,50 @@ int osi_update_ip4_addr(struct osi_core_priv_data *osi_core, unsigned int src_dst_addr_match); /** - * osi_update_ip6_addr - invoke OSI call update_ip6_addr. - * @osi_core: OSI private data structure. - * @filter_no: filter index - * @addr: ipv6 adderss + * @brief osi_update_ip6_addr - invoke OSI call update_ip6_addr. * - * Algorithm: This sequence is used to update IPv6 source/destination - * Address for L3 layer filtering + * Algorithm: This sequence is used to update IPv6 source/destination + * Address for L3 layer filtering * - * Dependencies: + * @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() * 2) L3/L4 filtering should be enabled in MAC PFR register. See * osi_config_l3_l4_filter_enable() * - * Protection: None - * - * Return: 0 - success, -1 - failure. + * @retval 0 on success + * @retval -1 on failure. */ int osi_update_ip6_addr(struct osi_core_priv_data *osi_core, unsigned int filter_no, unsigned short addr[]); /** - * osi_config_l4_filters - invoke OSI call config_l4_filters. + * @brief osi_config_l4_filters - invoke OSI call config_l4_filters. * - * @osi_core: OSI private data structure. - * @filter_no: filter index - * @enb_dis: enable/disable L4 filter - * @tcp_udp_match: 1 - udp, 0 - tcp - * @src_dst_port_match: port matching enable/disable - * @perfect_inverse_match: normal match(0) or inverse map(1) - * @dma_routing_enable: filter based dma routing enable(1) - * @dma_chan: dma channel for routing based on filter + * Algorithm: This sequence is used to configure L4(TCP/UDP) filters for + * SA and DA Port Number matching * - * 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: enable/disable L4 filter + * @param[in] tcp_udp_match: 1 - udp, 0 - tcp + * @param[in] src_dst_port_match: port matching enable/disable + * @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 * - * Dependencies: + * @note * 1) MAC should be init and started. see osi_start_mac() * 2) L3/L4 filtering should be enabled in MAC PFR register. See * osi_config_l3_l4_filter_enable() * 3) osi_core->osd should be populated * - * Protection: None - * - * Return: 0 - success, -1 - failure. + * @retval 0 on success + * @retval -1 on failure. */ int osi_config_l4_filters(struct osi_core_priv_data *osi_core, unsigned int filter_no, @@ -888,50 +894,45 @@ int osi_config_l4_filters(struct osi_core_priv_data *osi_core, unsigned int dma_chan); /** - * osi_update_l4_port_no - invoke OSI call for - * update_l4_port_no. + * @brief osi_update_l4_port_no - invoke OSI call for update_l4_port_no. + * Algoriths sequence is used to update Source Port Number for + * L4(TCP/UDP) layer filtering. * - * @osi_core: OSI private data structure. - * @filter_no: filter index - * @port_no: port number - * @src_dst_port_match: source port - 0, dest port - 1 + * @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: source port - 0, dest port - 1 * - * Algoriths sequence is used to update Source Port Number for - * L4(TCP/UDP) layer filtering. - * - * Dependencies: + * @note * 1) MAC should be init and started. see osi_start_mac() * 2) L3/L4 filtering should be enabled in MAC PFR register. See * osi_config_l3_l4_filter_enable() * 3) osi_core->osd should be populated * - * Protection: None - * - * Return: 0 - success, -1 - failure. + * @retval 0 on success + * @retval -1 on failure. */ int osi_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); /** - * osi_config_vlan_filter_reg - invoke OSI call for - * config_vlan_filtering. + * @brief osi_config_vlan_filtering - OSI call for configuring VLAN filter * - * @osi_core: OSI private data structure. - * @filter_enb_dis: vlan filter enable/disable - * @perfect_hash_filtering: perfect or hash filter - * @perfect_inverse_match: normal or inverse filter + * Algorithm: This sequence is used to enable/disable VLAN filtering and + * also selects VLAN filtering mode- perfect/hash * - * Algorithm: This sequence is used to enable/disable VLAN filtering and - * also selects VLAN filtering mode- perfect/hash + * @param[in] osi_core: OSI core private data structure. + * @param[in] filter_enb_dis: vlan filter enable(1) disable(0) + * @param[in] perfect_hash_filtering: perfect(0) or hash filter(1) + * @param[in] perfect_inverse_match: normal(0) or inverse filter(1) * - * Dependencies: + * @note * 1) MAC should be init and started. see osi_start_mac() * 2) osi_core->osd should be populated * - * Protection: None - * - * Return: 0 - success, -1 - failure. + * @retval 0 on success + * @retval -1 on failure. */ int osi_config_vlan_filtering(struct osi_core_priv_data *osi_core, unsigned int filter_enb_dis, @@ -939,217 +940,214 @@ int osi_config_vlan_filtering(struct osi_core_priv_data *osi_core, unsigned int perfect_inverse_match); /** - * osi_config_l2_da_perfect_inverse_match - trigger OSI call for - * config_l2_da_perfect_inverse_match. + * @brief osi_config_l2_da_perfect_inverse_match - + * trigger OSI call for config_l2_da_perfect_inverse_match. * - * @osi_core: OSI private data structure. - * @perfect_inverse_match: 1 - inverse mode 0- normal mode + * Algorithm: This sequence is used to select perfect/inverse matching + * for L2 DA * - * 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- normal mode * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() + * @note MAC should be init and started. see osi_start_mac() * - * Protection: None - * - * Return: 0 - success, -1 - failure. + * @retval 0 on success + * @retval -1 on failure. */ int osi_config_l2_da_perfect_inverse_match(struct osi_core_priv_data *osi_core, unsigned int perfect_inverse_match); /** - * osi_update_vlan_id - invoke osi call to update VLAN ID + * @brief osi_update_vlan_id - invoke osi call to update VLAN ID * - * @osi_core: OSI private data structure. - * @vid: VLAN ID + * Algorithm: return 16 bit VLAN ID * - * Algorithm: return 16 bit VLAN ID + * @param[in] osi_core: OSI core private data structure. + * @param[in] vid: VLAN ID * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() + * @note MAC should be init and started. see osi_start_mac() * - * Protection: None - * - * Return: 0 - success, -1 - failure. + * @retval 0 on success + * @retval -1 on failure. */ int osi_update_vlan_id(struct osi_core_priv_data *osi_core, unsigned int vid); /** - * osi_write_phy_reg - Write to a PHY register through MAC over MDIO bus. - * @osi_core: OSI private data structure. - * @phyaddr: PHY address (PHY ID) associated with PHY - * @phyreg: Register which needs to be write to PHY. - * @phydata: Data to write to a PHY register. + * @brief osi_write_phy_reg - Write to a PHY register through MAC over MDIO bus. * - * Algorithm: - * 1) Before proceding for reading for PHY register check whether any MII - * operation going on MDIO bus by polling MAC_GMII_BUSY bit. - * 2) Program data into MAC MDIO data register. - * 3) Populate required parameters like phy address, phy register etc,, + * Algorithm: + * 1) Before proceeding for reading for PHY register check whether any MII + * operation going on MDIO bus by polling MAC_GMII_BUSY bit. + * 2) Program data into MAC MDIO data register. + * 3) 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. - * 4) Write into MAC MDIO address register poll for GMII busy for MDIO + * 4) Write into MAC MDIO address register poll for GMII busy for MDIO * operation to complete. * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() + * @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. * - * Protection: None + * @note MAC should be init and started. see osi_start_mac() * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ int osi_write_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, unsigned int phyreg, unsigned short phydata); /** - * osi_read_mmc - invoke function to read actual registers and update - * structure variable mmc + * @brief osi_read_mmc - invoke function to read actual registers and update + * structure variable mmc + * + * Algorithm: Read the registers, mask reserve bits if required, update + * structure. * - * @osi_core: OSI core private data structure. + * @param[in] osi_core: OSI core private data structure. * - * Algorithm: Read the registers, mask reserve bits if requied, update - * structure. - * - * Dependencies: + * @note * 1) MAC should be init and started. see osi_start_mac() * 2) osi_core->osd should be populated * - * Protection: None - * - * Return: 0 - success, -1 - failure. + * @retval 0 on success + * @retval -1 on failure. */ int osi_read_mmc(struct osi_core_priv_data *osi_core); /** - * osi_reset_mmc - invoke function to reset MMC counter and data structure + * @brief osi_reset_mmc - invoke function to reset MMC counter and data + * structure * - * @osi_core: OSI core private data structure. + * Algorithm: Read the registers, mask reserve bits if required, update + * structure. * - * Algorithm: Read the registers, mask reserve bits if requied, update - * structure. + * @param[in] osi_core: OSI core private data structure. * - * Dependencies: + * @note * 1) MAC should be init and started. see osi_start_mac() * 2) osi_core->osd should be populated * - * Protection: None - * - * Return: 0 - success, -1 - failure. + * @retval 0 on success + * @retval -1 on failure. */ int osi_reset_mmc(struct osi_core_priv_data *osi_core); /** - * osi_read_phy_reg - Read from a PHY register through MAC over MDIO bus. - * @osi_core: OSI private data structure. - * @phyaddr: PHY address (PHY ID) associated with PHY - * @phyreg: Register which needs to be read from PHY. + * @brief osi_read_phy_reg - Read from a PHY register through MAC over MDIO bus. * - * Algorithm: - * 1) Before proceding for reading for PHY register check whether any MII - * operation going on MDIO bus by polling MAC_GMII_BUSY bit. - * 2) 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. - * 3) 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. + * Algorithm: + * 1) Before proceeding for reading for PHY register check whether any MII + * operation going on MDIO bus by polling MAC_GMII_BUSY bit. + * 2) 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. + * 3) 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. * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() + * @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. * - * Protection: None + * @note MAC should be init and started. see osi_start_mac() * - * Return: data from PHY register - success, -1 - failure + * @retval data from PHY register on success + * @retval -1 on failure */ int osi_read_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, unsigned int 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 + */ int osi_init_core_ops(struct osi_core_priv_data *osi_core); /** - * osi_set_systime_to_mac - Handles setting of system time. - * @osi_core: OSI private data structure. - * @sec: Seconds to be configured. - * @nsec: Nano seconds to be configured. + * @brief osi_set_systime_to_mac - Handles setting of system time. * - * Algorithm: Set current system time to MAC. + * Algorithm: Set current system time to MAC. * - * Dependencies: - * 1) MAC should be init and started. see osi_start_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. * - * Protection: None. + * @note MAC should be init and started. see osi_start_mac() * - * Return: 0 - success, -1 - failure. + * @retval 0 on success + * @retval -1 on failure. */ int osi_set_systime_to_mac(struct osi_core_priv_data *osi_core, unsigned int sec, unsigned int nsec); + /** - * osi_adjust_freq - Adjust frequency - * @osi: OSI private data structure. - * @ppb: Parts per Billion + * @brief osi_adjust_freq - Adjust frequency * - * 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. + * 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. * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() + * @param[in] osi_core: OSI core private data structure. + * @param[in] ppb: Parts per Billion * - * Protection: None + * @note MAC should be init and started. see osi_start_mac() * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ int osi_adjust_freq(struct osi_core_priv_data *osi_core, int ppb); /** + * @brief osi_adjust_time - Adjust time * - * osi_adjust_time - Adjust time - * @osi_core: OSI private data structure. - * @delta: Delta time + * Algorithm: Adjust/update the MAC time (delta time from MAC to system time + * passed in nanoseconds, can be + or -). * - * Algorithm: Adjust/update the MAC system time (delta passed in - * nanoseconds, can be + or -). + * @param[in] osi_core: OSI core private data structure. + * @param[in] delta: Delta time * - * Dependencies: + * @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 * - * Protection: None - * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ int osi_adjust_time(struct osi_core_priv_data *osi_core, long delta); /** - * osi_get_systime_from_mac - Get system time - * @osi: OSI private data structure. - * @sec: Value read in Seconds - * @nsec: Value read in Nano seconds + * @brief osi_get_systime_from_mac - Get system time * - * Algorithm: Gets the current system time + * Algorithm: Gets the current system time * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() + * @param[in] osi_core: OSI core private data structure. + * @param[out] sec: Value read in Seconds + * @param[out] nsec: Value read in Nano seconds * - * Protection: None + * @note MAC should be init and started. see osi_start_mac() * - * Return: 0 - success, -1 - failure - * (sec and nsec stores the read seconds and nanoseconds - * values from MAC if success) + * @retval 0 on success + * @retval -1 on failure. */ int osi_get_systime_from_mac(struct osi_core_priv_data *osi_core, unsigned int *sec, unsigned int *nsec); /** - * osi_ptp_configuration - Configure PTP - * @osi: OSI private data structure. - * @enable: Enable or disable Time Stamping. - * 0: Disable 1: Enable + * @brief osi_ptp_configuration - Configure PTP * - * Algorithm: Configure the PTP registers that are required for PTP. + * Algorithm: Configure the PTP registers that are required for PTP. * - * Dependencies: + * @param[in] osi_core: OSI core private data structure. + * @param[in] enable: Enable or disable Time Stamping. 0: Disable 1: Enable + * + * @note * 1) MAC should be init and started. see osi_start_mac() * 2) 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 @@ -1162,9 +1160,8 @@ int osi_get_systime_from_mac(struct osi_core_priv_data *osi_core, * 6) osi->ptp_config.nsec need to be filled with current time of nseconds * 7) osi->base need to be filled with the ioremapped base address * - * Protection: None - * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ int osi_ptp_configuration(struct osi_core_priv_data *osi_core, unsigned int enable); diff --git a/include/osi_dma.h b/include/osi_dma.h index d076a6b..7b1fc68 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -27,617 +27,647 @@ #include "osi_dma_txrx.h" #include "mmc.h" -#define OSI_PKT_CX_VLAN OSI_BIT(0) -#define OSI_PKT_CX_VALID OSI_BIT(10) -#define OSI_PKT_CX_CSUM OSI_BIT(1) -#define OSI_PKT_CX_TSO OSI_BIT(2) -#define OSI_PKT_CX_PTP OSI_BIT(3) - -/* Flag to indicate if buffer programmed in desc. is DMA map'd from - * linear/Paged buffer from OS layer. +/** + * @addtogroup EQOS-PKT Packet context fields + * + * @brief These flags are used to convey context information about a packet + * between HW and SW. 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 TCP segmentation offload is to be enabled for the packet, + * whether the HW should timestamp transmit/arrival of a packet respectively + * @{ */ -#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) -#define OSI_TXDONE_CX_TS OSI_BIT(2) +/** VLAN packet */ +#define OSI_PKT_CX_VLAN OSI_BIT(0) +/** Valid packet */ +#define OSI_PKT_CX_VALID OSI_BIT(10) +/** 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) +/** @} */ +/** + * @addtogroup EQOS-TX Tx done packet context fields + * + * @brief These flags used to convey transmit done packet context information, + * whether transmitted packet used a pagged buffer, whether transmitted packet + * has an tx error, whether tranmitted 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) +/** @} */ + +/** + * @addtogroup EQOS-CHK Checksum offload results + * + * @brief Flag to indicate the result from checksum offload engine + * to SW network stack in receive path + * @{ + */ /* Checksum offload result flags */ #define OSI_CHECKSUM_NONE 0x0U #define OSI_CHECKSUM_UNNECESSARY 0x1U +/** @} */ /** - * struct osi_pkt_err_stats: OSI packet error stats - * @ip_header_error: IP Header Error - * @jabber_timeout_error: Jabber time out Error - * @pkt_flush_error: Packet Flush Error - * @payload_cs_error: Payload Checksum Error - * @loss_of_carrier_error: Loss of Carrier Error - * @no_carrier_error: No Carrier Error - * @late_collision_error: Late Collision Error - * @excessive_collision_error: Excessive Collision Error - * @excessive_deferal_error: Excessive Deferal Error - * @underflow_error: Under Flow Error - * @rx_crc_error: Rx CRC Error + * @brief OSI packet error stats */ struct osi_pkt_err_stats { - /* Transmit errors */ + /** IP Header Error */ unsigned long ip_header_error; + /** Jabber time out Error */ unsigned long jabber_timeout_error; + /** Packet Flush Error */ unsigned long pkt_flush_error; + /** Payload Checksum Error */ unsigned long payload_cs_error; + /** Loss of Carrier Error */ unsigned long loss_of_carrier_error; + /** No Carrier Error */ unsigned long no_carrier_error; + /** Late Collision Error */ unsigned long late_collision_error; + /** Excessive Collision Error */ unsigned long excessive_collision_error; + /** Excessive Deferal Error */ unsigned long excessive_deferal_error; + /** Under Flow Error */ unsigned long underflow_error; - /* Receive Errors */ + /** Rx CRC Error */ unsigned long rx_crc_error; }; /** - * struct osi_rx_desc - Receive Descriptor - * @rdes0: Receive Descriptor 0 - * @rdes1: Receive Descriptor 1 - * @rdes2: Receive Descriptor 2 - * @rdes3: Receive Descriptor 3 + * @brief Receive Descriptor */ struct osi_rx_desc { + /** Receive Descriptor 0 */ unsigned int rdes0; + /** Receive Descriptor 1 */ unsigned int rdes1; + /** Receive Descriptor 2 */ unsigned int rdes2; + /** Receive Descriptor 3 */ unsigned int rdes3; }; /** - * struct osi_rx_swcx - Receive descriptor software context - * @buf_phy_addr: DMA buffer physical address - * @buf_virt_addr: DMA buffer virtual address - * @len: Length of buffer + * @brief Receive descriptor software context */ struct osi_rx_swcx { + /** DMA buffer physical address */ unsigned long buf_phy_addr; + /** DMA buffer virtual address */ void *buf_virt_addr; + /** Length of buffer */ unsigned int len; }; /** - * struct osi_rx_pkt_cx - Received packet context. - * @flags: Bit map which holds the features that rx packets supports. - * @rxcsum: Stores the Rx csum - * @vlan_tag: Stores the VLAN tag ID in received packet. - * @pkt_len: Length of received packet. - * @ns: TS in nsec for the received packet + * @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 */ unsigned int flags; + /** Stores the Rx csum */ unsigned int rxcsum; + /** Stores the VLAN tag ID in received packet */ unsigned int vlan_tag; + /** Length of received packet */ unsigned int pkt_len; + /** TS in nsec for the received packet */ unsigned long long ns; }; /** - * struct osi_rx_ring - DMA Rx channel ring - * @rx_desc: Pointer to Rx DMA descriptor - * @rx_swcx: Pointer to Rx DMA descriptor software context information - * @dma_rx_desc: Physical address of Rx DMA descriptor - * @cur_rx_idx: Descriptor index current reception. - * @refill_idx: Descriptor index for descriptor re-allocation. - * @rx_pkt_cx: Received packet context. + * @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 */ unsigned long rx_desc_phy_addr; + /** Descriptor index current reception */ unsigned int cur_rx_idx; + /** Descriptor index for descriptor re-allocation */ unsigned int refill_idx; + /** Receive packet context */ struct osi_rx_pkt_cx rx_pkt_cx; }; /** - * struct osi_tx_swcx - Transmit descriptor software context - * @buf_phy_addr: Physical address of DMA mapped buffer. - * @buf_virt_addr: Virtual address of DMA buffer. - * @len: Length of buffer - * @is_paged_buf: Flag to keep track of whether buffer pointed - * by buf_phy_addr is a paged buffer/linear buffer. + *@brief Transmit descriptor software context */ struct osi_tx_swcx { + /** Physical address of DMA mapped buffer */ unsigned long buf_phy_addr; + /** Virtual address of DMA buffer */ void *buf_virt_addr; + /** Length of buffer */ unsigned int len; + /** Flag to keep track of whether buffer pointed by buf_phy_addr + * is a paged buffer/linear buffer */ unsigned int is_paged_buf; }; /** - * struct osi_tx_desc - Transmit descriptor - * @tdes0: Transmit descriptor 0 - * @tdes1: Transmit descriptor 1 - * @tdes2: Transmit descriptor 2 - * @tdes3: Transmit descriptor 3 + * @brief Transmit descriptor */ struct osi_tx_desc { + /** Transmit descriptor 0 */ unsigned int tdes0; + /** Transmit descriptor 1 */ unsigned int tdes1; + /** Transmit descriptor 2 */ unsigned int tdes2; + /** Transmit descriptor 3 */ unsigned int tdes3; }; /** - * struct osi_tx_pkt_cx - Transmit packet context for a packet - * @flags: Holds the features which a Tx packets supports. - * @vtag_id: Stores the VLAN tag ID. - * @desc_cnt: Descriptor count - * @mss: Max. segment size for TSO/USO/GSO/LSO packet - * @payload_len: Length of application payload - * @tcp_udp_hdrlen: Length of transport layer tcp/udp header - * @total_hdrlen: Length of all headers (ethernet/ip/tcp/udp) + * @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 */ unsigned int flags; + /** Stores the VLAN tag ID */ unsigned int vtag_id; + /** Descriptor count */ unsigned int desc_cnt; + /** Max. segment size for TSO/USO/GSO/LSO packet */ unsigned int mss; + /** Length of application payload */ unsigned int payload_len; + /** Length of transport layer tcp/udp header */ unsigned int tcp_udp_hdrlen; + /** Length of all headers (ethernet/ip/tcp/udp) */ unsigned int total_hdrlen; }; /** - * struct osi_txdone_pkt_cx - Transmit done packet context for a packet - * @flags: Indicates status flags for Tx complete (tx error occured, or - * indicate whether desc. had buf mapped from paged/linear memory etc.) - * @ns: TS captured for the tx packet and this is valid only when the PTP - * bit is set in fields + * @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) */ unsigned int flags; + /** TS captured for the tx packet and this is valid only when the PTP + * bit is set in fields */ unsigned long long ns; }; /** - * struct osi_tx_ring - DMA channel Tx ring - * @tx_desc: Pointer to tx dma descriptor - * @tx_swcx: Pointer to tx dma descriptor software context information - * @tx_desc_phy_addr: Physical address of Tx descriptor. - * @cur_tx_idx: Descriptor index current transmission. - * @clean_idx: Descriptor index for descriptor cleanup. - * @tx_pkt_cx: Transmit packet context. - * @txdone_pkt_cx: Transmit complete packet context information. + * @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 */ unsigned long tx_desc_phy_addr; + /** Descriptor index current transmission */ unsigned int cur_tx_idx; + /** Descriptor index for descriptor cleanup */ unsigned int clean_idx; + /** Transmit packet context */ struct osi_tx_pkt_cx tx_pkt_cx; + /** Transmit complete packet context information */ struct osi_txdone_pkt_cx txdone_pkt_cx; }; struct osi_dma_priv_data; + /** - * struct osi_dma_chan_ops - MAC Hardware operations - * @set_tx_ring_len: Called to set Transmit Ring length. - * @set_tx_ring_start_addr: Called to set Transmit Ring Base address. - * @update_tx_tailptr: Called to update Tx Ring tail pointer. - * @set_rx_ring_len: Called to set Receive channel ring length. - * @set_rx_ring_start_addr: Called to set receive channel ring base address - * @update_rx_tailptr: Called to update Rx ring tail pointer. - * @clear_tx_intr: Invoked by OSD layer to clear Tx interrupt source. - * @clear_rx_intr: Invoked by OSD layer to clear Rx interrupt source. - * @disable_chan_tx_intr: Called to disable DMA tx channel interrupts at - * wrapper level. - * @enable_chan_tx_intr: Called to enable DMA tx channel interrupts at - * wrapper level. - * @disable_chan_rx_intr: Called to disable DMA Rx channel interrupts at - * wrapper level. - * @enable_chan_rx_intr: Called to enable DMA rx channel interrupts at - * wrapper level. - * @start_dma: Called to start the Tx/Rx DMA. - * @set_rx_buf_len: Called to set Rx buffer length. - * @validate_regs: Called periodically to read and validate safety critical - * registers against last written value. + *@brief MAC DMA Channel operations */ struct osi_dma_chan_ops { + /** Called to set Transmit Ring length */ void (*set_tx_ring_len)(void *addr, unsigned int chan, unsigned int len); + /** Called to set Transmit Ring Base address */ void (*set_tx_ring_start_addr)(void *addr, unsigned int chan, unsigned long base_addr); + /** Called to update Tx Ring tail pointer */ void (*update_tx_tailptr)(void *addr, unsigned int chan, unsigned long tailptr); + /** Called to set Receive channel ring length */ void (*set_rx_ring_len)(void *addr, unsigned int chan, unsigned int len); + /** Called to set receive channel ring base address */ void (*set_rx_ring_start_addr)(void *addr, unsigned int chan, unsigned long base_addr); + /** Called to update Rx ring tail pointer */ void (*update_rx_tailptr)(void *addr, unsigned int chan, unsigned long tailptr); + /** Called to clear Tx interrupt source */ void (*clear_tx_intr)(void *addr, unsigned int chan); + /** Called to clear Rx interrupt source */ void (*clear_rx_intr)(void *addr, unsigned int chan); + /** Called to disable DMA Tx channel interrupts at wrapper level */ void (*disable_chan_tx_intr)(void *addr, unsigned int chan); + /** Called to enable DMA Tx channel interrupts at wrapper level */ void (*enable_chan_tx_intr)(void *addr, unsigned int chan); + /** Called to disable DMA Rx channel interrupts at wrapper level */ void (*disable_chan_rx_intr)(void *addr, unsigned int chan); + /** Called to enable DMA Rx channel interrupts at wrapper level */ void (*enable_chan_rx_intr)(void *addr, unsigned int chan); + /** Called to start the Tx/Rx DMA */ void (*start_dma)(void *addr, unsigned int chan); + /** Called to stop the Tx/Rx DMA */ void (*stop_dma)(void *addr, unsigned int chan); + /** Called to initialize the DMA channel */ void (*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); + /** Called periodically to read and validate safety critical + * registers against last written value */ int (*validate_regs)(struct osi_dma_priv_data *osi_dma); }; /** - * struct osi_dma_priv_data - The OSI private data structure. - * @tx_ring: Array of pointers to DMA Tx channel Ring. - * @rx_ring: Array of pointers to DMA Rx channel Ring. - * @base: Memory mapped base address of MAC IP. - * @osd: Pointer to OSD private data structure. - * @ops: Address of HW operations structure. - * @mac: MAC HW type (EQOS). - * @num_dma_chans: Number of channels enabled in MAC. - * @dma_chans[]: Array of supported DMA channels - * @rx_buf_len: DMA Rx channel buffer length at HW level. - * @mtu: MTU size - * @pkt_err_stats: Packet error stats - * @dstats: Extra DMA stats - * @rx_riwt: Receive Interrupt Watchdog Timer Count Units - * @use_riwt: Flag which decides riwt is enabled(1) or disabled(0) - * @safety_config: Functional safety config to do periodic read-verify of - * certain safety critical dma registers. + * @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_EQOS_MAX_NUM_CHANS]; + /** Array of pointers to DMA Rx channel Ring */ struct osi_rx_ring *rx_ring[OSI_EQOS_MAX_NUM_CHANS]; + /** Memory mapped base address of MAC IP */ void *base; + /** Pointer to OSD private data structure */ void *osd; + /** Address of HW operations structure */ struct osi_dma_chan_ops *ops; + /** MAC HW type (EQOS) */ unsigned int mac; + /** Number of channels enabled in MAC */ unsigned int num_dma_chans; + /** Array of supported DMA channels */ unsigned int dma_chans[OSI_EQOS_MAX_NUM_CHANS]; + /** DMA Rx channel buffer length at HW level */ unsigned int rx_buf_len; + /** MTU size */ unsigned int 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 */ unsigned int rx_riwt; + /** Flag which decides riwt is enabled(1) or disabled(0) */ unsigned int use_riwt; + /** Functional safety config to do periodic read-verify of + * certain safety critical dma registers */ void *safety_config; }; /** - * osi_validate_dma_regs - Read-validate HW registers for func safety. - * @osi_dma: OSI dma private data structure. + * @brief - Read-validate HW registers for func safety. * - * Algorithm: Reads pre-configured list of DMA configuration registers + * Algorithm: Reads pre-configured list of DMA configuration registers * and compares with last written value for any modifications. * - * Dependencies: + * @param[in] osi_dma: OSI DMA private data structure. + * + * @note * 1) MAC has to be out of reset. * 2) 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 + * the safety_config (see osi_dma_priv_data) based on MAC version and * which specific registers needs to be validated periodically. * 3) Invoke this call iff (osi_dma_priv_data->safety_config != OSI_NULL) * - * Protection: None - * - * Return: 0 - success, -1 - failure (reg value has changed) + * @retval 0 on success + * @retval -1 on failure. */ int osi_validate_dma_regs(struct osi_dma_priv_data *osi_dma); /** - * osi_disable_chan_tx_intr - Disables DMA Tx channel interrupts. - * @osi_dma: DMA private data. - * @chan: DMA Tx channel number. + * @brief osi_disable_chan_tx_intr - Disables DMA Tx channel interrupts. * - * Algorithm: Disables Tx interrupts at wrapper level. + * Algorithm: Disables Tx interrupts at wrapper level. * - * Dependencies: + * @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 * 3) Mapping of physical IRQ line to DMA channel need to be maintained at - * OSDependent layer and pass corresponding channel number. + * OS Dependent layer and pass corresponding channel number. * - * Protection: None. - * - * Return: 0 - success , -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ int osi_disable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, unsigned int chan); /** - * osi_enable_chan_tx_intr - Enable DMA Tx channel interrupts. - * @osi_dma: DMA private data. - * @chan: DMA Tx channel number. + * @brief osi_enable_chan_tx_intr - Enable DMA Tx channel interrupts. * - * Algorithm: Enables Tx interrupts at wrapper level. + * Algorithm: Enables Tx interrupts at wrapper level. * - * Dependencies: + * @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 * 3) Mapping of physical IRQ line to DMA channel need to be maintained at - * OSDependent layer and pass corresponding channel number. + * OS Dependent layer and pass corresponding channel number. * - * Protection: None. - * - * Return: 0 - success , -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ int osi_enable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, unsigned int chan); /** - * osi_disable_chan_rx_intr - Disable DMA Rx channel interrupts. - * @osi_dma: DMA private data. - * @chan: DMA rx channel number. + * @brief osi_disable_chan_rx_intr - Disable DMA Rx channel interrupts. * - * Algorithm: Disables Rx interrupts at wrapper level. + * Algorithm: Disables Rx interrupts at wrapper level. * - * Dependencies: + * @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 - * OSDependent layer and pass corresponding channel number. + * OS Dependent layer and pass corresponding channel number. * - * Protection: None. - * - * Return: 0 - success , -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ int osi_disable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, unsigned int chan); /** - * osi_enable_chan_rx_intr - Enable DMA Rx channel interrupts. - * @osi_dma: DMA private data. - * @chan: DMA rx channel number. + * @brief osi_enable_chan_rx_intr - Enable DMA Rx channel interrupts. * - * Algorithm: Enables Rx interrupts at wrapper level. + * Algorithm: Enables Rx interrupts at wrapper level. * - * Dependencies: + * @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 - * OSDependent layer and pass corresponding channel number. + * OS Dependent layer and pass corresponding channel number. * - * Protection: None. - * - * Return: 0 - success , -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ int osi_enable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, unsigned int chan); /** - * osi_clear_tx_intr - Handles Tx interrupt source. - * @osi_dma: DMA private data. - * @chan: DMA tx channel number. + * @brief osi_clear_tx_intr - Handles Tx interrupt source. * - * Algorithm: Clear Tx interrupt source at wrapper level and DMA level. + * Algorithm: Clear Tx interrupt source at wrapper level and DMA level. * - * Dependencies: + * @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 * - * Protection: None. - * - * Return: 0 - success , -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ int osi_clear_tx_intr(struct osi_dma_priv_data *osi_dma, unsigned int chan); /** - * osi_clear_rx_intr - Handles Rx interrupt source. - * @osi_dma: DMA private data. - * @chan: DMA rx channel number. + * @brief osi_clear_rx_intr - Handles Rx interrupt source. * - * Algorithm: Clear Rx interrupt source at wrapper level and DMA level. + * Algorithm: Clear Rx interrupt source at wrapper level and DMA level. * - * Dependencies: + * @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 - * OSDependent layer and pass corresponding channel number. + * OS Dependent layer and pass corresponding channel number. * - * Protection: None. - * - * Return: 0 - success , -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ int osi_clear_rx_intr(struct osi_dma_priv_data *osi_dma, unsigned int chan); /** - * osi_start_dma - Start DMA - * @osi_dma: DMA private data. - * @chan: DMA Tx/Rx channel number + * @brief Start DMA * - * Algorimthm: Start the DMA for specific MAC + * Algorithm: Start the DMA for specific MAC * - * Dependencies: + * @param[in] osi_dma: DMA private data. + * @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 * - * Protection: None - * - * Return: 0 - success , -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ int osi_start_dma(struct osi_dma_priv_data *osi_dma, unsigned int chan); /** - * osi_stop_dma - Stop DMA - * @osi_dma: DMA private data. - * @chan: DMA Tx/Rx channel number + * @brief osi_stop_dma - Stop DMA * - * Algorimthm: Stop the DMA for specific MAC + * Algorithm: Stop the DMA for specific MAC * - * Dependencies: + * @param[in] osi_dma: DMA private data. + * @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 * - * Protection: None - * - * Return: 0 - success , -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ int osi_stop_dma(struct osi_dma_priv_data *osi_dma, unsigned int chan); /** - * osi_get_refill_rx_desc_cnt - Rx descriptors count that needs to refill. - * @rx_ring: DMA channel Rx ring. + * @brief osi_get_refill_rx_desc_cnt - Rx descriptors count that needs to refill * - * Algorithm: subtract current index with fill (need to cleanup) - * to get Rx descriptors count that needs to refill. + * Algorithm: subtract current index with fill (need to cleanup) + * to get Rx descriptors count that needs to refill. * - * Dependencies: None. + * @param[in] rx_ring: DMA channel Rx ring. * - * Protection: None. + * @note None. * - * Return: Number of available free descriptors. + * @retval "Number of available free descriptors." */ unsigned int osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring); /** - * osi_rx_dma_desc_init - DMA Rx descriptor init - * @rx_swcx: OSI DMA Rx ring software context - * @rx_desc: OSI DMA Rx ring descriptor - * @use_riwt: to enable Rx WDT and disable IOC + * @brief osi_rx_dma_desc_init - DMA Rx descriptor init * - * Algorithm: Initialise a Rx DMA descriptor. + * Algorithm: Initialise a Rx DMA descriptor. * - * Dependencies: + * @param[in] rx_swcx: OSI DMA Rx ring software context + * @param[in] rx_desc: OSI DMA Rx ring descriptor + * @param[in] use_riwt: to enable Rx WDT and disable IOC + * + * @note * 1) MAC needs to be out of reset and proper clocks need to be configured. * 2) rx_swcx->buf_phy_addr need to be filled with DMA mapped address - * 2) DMA HW init need to be completed successfully, see osi_hw_dma_init + * 3) DMA HW init need to be completed successfully, see osi_hw_dma_init * - * Protection: None. - * - * Return: 0 - success , -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ int osi_rx_dma_desc_init(struct osi_rx_swcx *rx_swcx, struct osi_rx_desc *rx_desc, unsigned int use_riwt); /** - * osi_update_rx_tailptr - Updates DMA Rx ring tail pointer - * @osi_dma: OSI DMA private data struture. - * @rx_ring: Pointer to DMA Rx ring. - * @chan: DMA channel number. + * @brief osi_update_rx_tailptr - Updates DMA Rx ring tail pointer * - * Algorithm: Updates DMA Rx ring tail pointer. + * @param[in] osi_dma: OSI DMA private data struture. + * @param[in] rx_ring: Pointer to DMA Rx ring. + * @param[in] chan: DMA channel number. * - * Dependencies: + * @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 * - * Protection: None. - * - * Return: 0 - success , -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ int osi_update_rx_tailptr(struct osi_dma_priv_data *osi_dma, struct osi_rx_ring *rx_ring, unsigned int chan); /** - * osi_set_rx_buf_len - Updates rx buffer length. - * @osi_dma: OSI DMA private data struture. + * @brief Updates rx buffer length. * - * Algorithm: Updates Rx buffer length. + * @param[in] osi_dma: OSI DMA private data struture. * - * Dependencies: + * @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 * - * Protection: None. - * - * Return: 0 - success , -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ int osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma); /** - * osi_hw_transmit - Initialize Tx DMA descriptors for a channel - * @osi_dma: DMA private data. - * @chan: DMA Tx channel number. + * @brief osi_hw_transmit - Initialize Tx DMA descriptors for a channel * - * Algorithm: Initialize Transmit descriptors with DMA mappabled buffers, - * set OWN bit, Tx ring length and set starting address of Tx DMA channel. - * Tx ring base address in Tx DMA registers. + * 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. * - * Dependencies: + * @param[in] osi: 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 * 3) DMA channel need to be started, see osi_start_dma * 4) Need to set update tx_pkt_cx->flags accordingly as per the * requirements - * #define OSI_PKT_CX_VLAN OSI_BIT(0) - * #define OSI_PKT_CX_CSUM OSI_BIT(1) - * #define OSI_PKT_CX_TSO OSI_BIT(2) - * #define OSI_PKT_CX_PTP OSI_BIT(3) + * 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) * 5) tx_pkt_cx->desc_cnt need to be populated which holds the number * of swcx descriptors allocated for that packet * 6) 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 - * - * Protection: None. - * - * Return: None. */ void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan); /** - * osi_process_tx_completions - Process Tx complete on DMA channel ring. - * @osi: OSI private data structure. - * @chan: Channel number on which Tx complete need to be done. + * @brief osi_process_tx_completions - Process Tx complete on DMA channel ring. * - * Algorithm: This function will be invoked by OSD layer to process Tx - * complete interrupt. - * 1) First checks whether descriptor owned by DMA or not. - * 2) Invokes OSD layer to release DMA address and Tx buffer which are - * updated as part of transmit routine. + * Algorithm: This function will be invoked by OSD layer to process Tx + * complete interrupt. + * 1) First checks whether descriptor owned by DMA or not. + * 2) Invokes OSD layer to release DMA address and Tx buffer which are + * updated as part of transmit routine. * - * Dependencies: + * @param[in] osi: OSI private data structure. + * @param[in] chan: Channel number on which Tx complete need to be done. + * + * @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) DMA need to be started, see osi_start_dma * - * Protection: None - * - * Return: Number of decriptors (buffers) proccessed. + * @returns Number of decriptors (buffers) proccessed. */ int osi_process_tx_completions(struct osi_dma_priv_data *osi, unsigned int chan); /** - * osi_process_rx_completions - Read data from receive channel descriptors - * @osi: OSI private data structure. - * @chan: Rx DMA channel number - * @budget: Threshould for reading the packets at a time. + * @brief osi_process_rx_completions - Read data from rx channel descriptors * - * Algorimthm: This routine will be invoked by OSD layer to get the - * data from Rx descriptors and deliver the packet to the stack. - * 1) Checks descriptor owned by DMA or not. - * 2) Get the length from Rx descriptor - * 3) Invokes OSD layer to deliver the packet to network stack. - * 4) Re-allocate the receive buffers, populate Rx descriptor and - * handover to DMA. + * Algorithm: This routine will be invoked by OSD layer to get the + * data from Rx descriptors and deliver the packet to the stack. + * 1) Checks descriptor owned by DMA or not. + * 2) Get the length from Rx descriptor + * 3) Invokes OSD layer to deliver the packet to network stack. + * 4) Re-allocate the receive buffers, populate Rx descriptor and + * handover to DMA. * - * Dependencies: + * @param[in] osi: OSI private data structure. + * @param[in] chan: Rx DMA channel number + * @param[in] budget: Threshould for reading the packets at a time. + * + * @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) DMA need to be started, see osi_start_dma * - * Protection: None. - * - * Return: None. + * @returns Number of decriptors (buffers) proccessed. */ int osi_process_rx_completions(struct osi_dma_priv_data *osi, unsigned int chan, int budget); /** - * osi_hw_dma_init - Initialize DMA - * @osi_dma: DMA private data. + * @brief osi_hw_dma_init - Initialize DMA * - * Algorithm: Takes care of initializing the tx, rx ring and descriptors - * based on the number of channels selected. + * Algorithm: Takes care of initializing the tx, rx ring and descriptors + * based on the number of channels selected. * - * Dependencies: + * @param[in] osi_dma: DMA private data. + * + * + * @note * 1) Allocate memory for osi_dma * 2) MAC needs to be out of reset and proper clocks need to be configured. * 3) Numer of dma channels osi_dma->num_dma_chans @@ -658,73 +688,71 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, * 12) osi_dma->use_riwt ==> OSI_DISABLE/OSI_ENABLE * 13) osi_dma->rx_riwt ===> Actual value read from DT * - * Protection: None. - * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ int osi_hw_dma_init(struct osi_dma_priv_data *osi_dma); /** - * osi_hw_dma_deinit - Deinitialize DMA - * @osi_dma: DMA private data. + * @brief osi_hw_dma_deinit - De initialize DMA * - * Algorithm: Takes care of stopping the MAC + * Algorithm: Takes care of stopping the MAC * - * Dependencies: + * @param[in] osi_dma: DMA private data. + * + * @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 * - * Protection: None. - * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ int osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma); /** - * osi_init_dma_ops - Initialize DMA operations - * @osi_dma: DMA private data. + * @brief osi_init_dma_ops - Initialize DMA operations * - * Algorithm: Takes care of initializing the DMA operations + * @param[in] osi_dma: DMA private data. * - * Dependencies: None. + * @note None * - * Protection: None. - * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ int osi_init_dma_ops(struct osi_dma_priv_data *osi_dma); /** - * osi_clear_tx_pkt_err_stats - Clear tx packet error stats. - * @osi: OSI dma private data structure. + * @brief osi_clear_tx_pkt_err_stats - Clear tx packet error stats. * - * Algorithm: This function will be invoked by OSD layer to clear the - * tx stats mentioned in osi_dma->pkt_err_stats structure - - * Dependencies: + * Algorithm: This function will be invoked by OSD layer to clear the + * tx stats mentioned in osi_dma->pkt_err_stats structure + * + * @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 * - * Protection: None - * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ int osi_clear_tx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); /** - * osi_clear_rx_pkt_err_stats - Clear rx packet error stats. - * @osi: OSI dma private data structure. + * @brief osi_clear_rx_pkt_err_stats - Clear rx packet error stats. * - * Algorithm: This function will be invoked by OSD layer to clear the - * rx_crc_error mentioned in osi_dma->pkt_err_stats structure. + * Algorithm: This function will be invoked by OSD layer to clear the + * rx_crc_error mentioned in osi_dma->pkt_err_stats structure. * - * Dependencies: + * @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 * - * Protection: None - * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ int osi_clear_rx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); diff --git a/include/osi_dma_txrx.h b/include/osi_dma_txrx.h index da0c56b..97c0c5c 100644 --- a/include/osi_dma_txrx.h +++ b/include/osi_dma_txrx.h @@ -23,16 +23,43 @@ #ifndef OSI_DMA_TXRX_H #define OSI_DMA_TXRX_H +/** + * @addtogroup EQOS_Help Descriptor Helper MACROS + * + * @brief Helper macros for defining Tx/Rx descriptor count + * @{ + */ #define TX_DESC_CNT 256U #define RX_DESC_CNT 256U +/** @} */ +/** 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, i) ((idx) = ((idx) + (i)) & (TX_DESC_CNT - 1U)) +/** Decrement the tx descriptor index */ #define DECR_TX_DESC_INDEX(idx, i) ((idx) = ((idx) - (i)) & (TX_DESC_CNT - 1U)) +/** Increment the rx descriptor index */ #define INCR_RX_DESC_INDEX(idx, i) ((idx) = ((idx) + (i)) & (RX_DESC_CNT - 1U)) +/** Decrement the rx descriptor index */ #define DECR_RX_DESC_INDEX(idx, i) ((idx) = ((idx) - (i)) & (RX_DESC_CNT - 1U)) +/** @} */ +/** + * @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) @@ -51,17 +78,27 @@ #define RDES3_RS0V OSI_BIT(25) #define RDES3_RS1V OSI_BIT(26) #define RDES0_OVT 0x0000FFFFU -#define RDES1_TSA OSI_BIT(14) /* Timestamp available */ -#define RDES1_TD OSI_BIT(15) /* Timestamp Dropped */ +#define RDES1_TSA OSI_BIT(14) +#define RDES1_TD OSI_BIT(15) #define RDES1_IPCE OSI_BIT(7) #define RDES1_IPCB OSI_BIT(6) #define RDES1_IPHE OSI_BIT(3) +/** @} */ +/** 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) +/** + * @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) @@ -95,7 +132,9 @@ */ #define TDES2_VTIR ((unsigned int)0x2 << 14U) #define TDES2_TTSE ((unsigned int)0x1 << 30U) +/** @} */ +/** Error Summary bits for Transmitted packet */ #define TDES3_ES_BITS (TDES3_IP_HEADER_ERR | \ TDES3_UNDER_FLOW_ERR | \ TDES3_EXCESSIVE_DEF_ERR | \ diff --git a/osi/common/osi_common.c b/osi/common/osi_common.c index df137b4..d371f04 100644 --- a/osi/common/osi_common.c +++ b/osi/common/osi_common.c @@ -23,17 +23,6 @@ #include <osi_core.h> #include <osd.h> -/** - * osi_get_hw_features: Get MAC Hardware features from features registers - * @osi: OSI private data structure. - * - * Algorithm: Reads HW features from HW registers and populate those - * in hw features structure. - * - * Dependencies: CAR reset should be success before calling this function - * - * Return: None - */ void osi_get_hw_features(void *base, struct osi_hw_features *hw_feat) { unsigned int mac_hfr0; diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 9b5f89e..3782332 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -26,15 +26,15 @@ #include "eqos_core.h" #include "eqos_mmc.h" +/** + * @brief eqos_core_safety_config - EQOS MAC core safety configuration + */ static struct core_func_safety eqos_core_safety_config; /** - * eqos_core_safety_writel - Write to safety critical register. - * @val: Value to be written. - * @addr: memory mapped register address to be written to. - * @idx: Index of register corresponding to enum func_safety_core_regs. + * @brief eqos_core_safety_writel - Write to safety critical register. * - * Algorithm: + * Algorithm: * 1) Acquire RW lock, so that eqos_validate_core_regs does not run while * updating the safety critical register. * 2) call osi_writel() to actually update the memory mapped register. @@ -42,12 +42,11 @@ static struct core_func_safety eqos_core_safety_config; * so that this latest value will be compared when eqos_validate_core_regs * is scheduled. * - * Dependencies: - * 1) MAC has to be out of reset, and clocks supplied. + * @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. * - * Protection: None. - * - * Return: None. + * @note MAC has to be out of reset, and clocks supplied. */ static inline void eqos_core_safety_writel(unsigned int val, void *addr, unsigned int idx) @@ -61,21 +60,16 @@ static inline void eqos_core_safety_writel(unsigned int val, void *addr, } /** - * eqos_core_safety_init - Initialize the eqos_core_safety_config. - * @base_addr: Base address of memory mapped register space. + * @brief Initialize the eqos_core_safety_config. * - * Algorithm: Populate the list of safety critical registers and provide + * Algorithm: Populate the list of safety critical registers and provide * 1) the address of the register * 2) Register mask (to ignore reserved/self-critical bits in the reg). - * See @eqos_validate_core_regs which can be ivoked periodically to compare + * See eqos_validate_core_regs which can be ivoked periodically to compare * the last written value to this register vs the actual value read when * eqos_validate_core_regs is scheduled. * - * Dependencies: None - * - * Protection: None - * - * Return: None + * @param[in] osi_core: OSI core private data structure. */ static void eqos_core_safety_init(struct osi_core_priv_data *osi_core) { @@ -171,21 +165,22 @@ static void eqos_core_safety_init(struct osi_core_priv_data *osi_core) } /** - * eqos_validate_core_regs - Read-validate HW registers for functional safety. - * @osi: OSI core private data structure. - * Algorithm: Reads pre-configured list of MAC/MTL configuration registers + * @brief Read-validate HW registers for functional safety. + * + * Algorithm: Reads pre-configured list of MAC/MTL configuration registers * and compares with last written value for any modifications. * - * Dependencies: + * @param[in] osi_core: OSI core private data structure. + * + * @note * 1) MAC has to be out of reset. * 2) 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 + * the safety_config (see osi_core_priv_data) based on MAC version and * which specific registers needs to be validated periodically. * 3) Invoke this call iff (osi_core_priv_data->safety_config != OSI_NULL) * - * Protection: None - * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ static int eqos_validate_core_regs(struct osi_core_priv_data *osi_core) { @@ -219,18 +214,16 @@ static int eqos_validate_core_regs(struct osi_core_priv_data *osi_core) } /** - * eqos_config_flow_control - Configure MAC flow control settings - * @addr: MAC base address. - * @flw_ctrl: flw_ctrl settings + * @brief eqos_config_flow_control - Configure MAC flow control settings * - * Algorithm: + * @param[in] addr: Base address indicating the start of + * memory mapped IO region of the MAC. + * @param[in] flw_ctrl: flw_ctrl settings * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() + * @note MAC should be init and started. see osi_start_mac() * - * Protection: None. - * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ static int eqos_config_flow_control(void *addr, unsigned int flw_ctrl) { @@ -286,20 +279,20 @@ static int eqos_config_flow_control(void *addr, unsigned int flw_ctrl) } /** - * eqos_config_rx_crc_check - Configure CRC Checking for Rx Packets - * @addr: MAC base address. - * @crc_chk: Enable or disable checking of CRC field in received packets + * @brief eqos_config_rx_crc_check - Configure CRC Checking for Rx Packets * - * Algorithm: When this bit is set, the MAC receiver does not check the CRC + * 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. * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() + * @param[in] addr: Base address indicating the start of + * memory mapped IO region of the MAC. + * @param[in] crc_chk: Enable or disable checking of CRC field in received pkts * - * Protection: None. - * - * Return: 0 - success, -1 - failure + * @note MAC should be init and started. see osi_start_mac() + * + * @retval 0 on success + * @retval -1 on failure. */ static int eqos_config_rx_crc_check(void *addr, unsigned int crc_chk) { @@ -331,22 +324,22 @@ static int eqos_config_rx_crc_check(void *addr, unsigned int crc_chk) } /** - * eqos_config_fw_err_pkts - Configure forwarding of error packets - * @addr: MAC base address. - * @qinx: Q index - * @fw_err: Enable or Disable the forwarding of error packets + * @brief eqos_config_fw_err_pkts - Configure forwarding of error packets * - * Algorithm: When this bit is reset, the Rx queue drops packets with error - * status (CRC error, GMII_ER, watchdog timeout, or overflow). - * When this bit is set, all packets except the runt error packets - * are forwarded to the application or DMA. + * Algorithm: When this bit is reset, the Rx queue drops packets with + * error status (CRC error, GMII_ER, watchdog timeout, or overflow). + * When this bit is set, all packets except the runt error packets + * are forwarded to the application or DMA. * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() + * @param[in] addr: Base address indicating the start of + * memory mapped IO region of the MAC. + * @param[in] qinx: Q index + * @param[in] fw_err: Enable or Disable the forwarding of error packets * - * Protection: None. + * @note MAC should be init and started. see osi_start_mac() * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ static int eqos_config_fw_err_pkts(void *addr, unsigned int qinx, unsigned int fw_err) @@ -388,21 +381,21 @@ static int eqos_config_fw_err_pkts(void *addr, unsigned int qinx, } /** - * eqos_config_tx_status - Configure MAC to forward the tx pkt status - * @addr: MAC base address. - * @tx_status: Enable or Disable the forwarding of tx pkt status + * @brief eqos_config_tx_status - Configure MAC to forward the tx pkt status * - * 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. + * 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. * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() + * @param[in] addr: Base address indicating the start of + * memory mapped IO region of the MAC. + * @param[in] tx_status: Enable or Disable the forwarding of tx pkt status * - * Protection: None. + * @note MAC should be init and started. see osi_start_mac() * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ static int eqos_config_tx_status(void *addr, unsigned int tx_status) { @@ -439,18 +432,16 @@ static int eqos_config_tx_status(void *addr, unsigned int tx_status) } /** - * eqos_config_mac_loopback - Configure MAC to support loopback - * @addr: MAC base address. - * @lb_mode: Enable or Disable MAC loopback mode + * @brief eqos_config_mac_loopback - Configure MAC to support loopback * - * Algorithm: Configure MAC to enable or disable 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 * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() + * @note MAC should be init and started. see osi_start_mac() * - * Protection: None. - * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ static int eqos_config_mac_loopback(void *addr, unsigned int lb_mode) { @@ -493,18 +484,17 @@ static int eqos_config_mac_loopback(void *addr, unsigned int lb_mode) } /** - * eqos_poll_for_swr - Poll for software reset (SWR bit in DMA Mode) - * @addr: EQOS virtual base address. + * @brief eqos_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. + * Algorithm: CAR reset will be issued through MAC reset pin. + * Waits for SWR reset to be cleared in DMA Mode register. * - * Dependencies: - * 1) MAC needs to be out of reset and proper clock configured. + * @param[in] addr: EQOS virtual base address. * - * Protection: None + * @note MAC needs to be out of reset and proper clock configured. * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ static int eqos_poll_for_swr(void *addr) { @@ -537,18 +527,16 @@ static int eqos_poll_for_swr(void *addr) } /** - * eqos_set_mdc_clk_rate - Derive MDC clock based on provided AXI_CBB clk. - * @osi_core: OSI core private data structure. - * @csr_clk_rate: CSR (AXI CBB) clock rate. + * @brief eqos_set_mdc_clk_rate - Derive MDC clock based on provided AXI_CBB clk * - * Algorithm: MDC clock rate will be polulated OSI private data structure - * based on AXI_CBB clock rate. + * Algorithm: MDC clock rate will be polulated OSI core private data structure + * based on AXI_CBB clock rate. * - * Dependencies: - * 1) OSD layer needs get the AXI CBB clock rate with OSD clock API - * (ex - clk_get_rate()) + * @param[in] osi_core: OSI core private data structure. + * @param[in] csr_clk_rate: CSR (AXI CBB) clock rate. * - * Return: None + * @note OSD layer needs get the AXI CBB clock rate with OSD clock API + * (ex - clk_get_rate()) */ static void eqos_set_mdc_clk_rate(struct osi_core_priv_data *osi_core, unsigned long csr_clk_rate) @@ -576,19 +564,15 @@ static void eqos_set_mdc_clk_rate(struct osi_core_priv_data *osi_core, } /** - * eqos_set_speed - Set operating speed - * @base: EQOS virtual base address. - * @speed: Operating speed. + * @brief eqos_set_speed - Set operating speed * - * Algorithm: Based on the speed (10/100/1000Mbps) MAC will be configured - * accordingly. + * Algorithm: Based on the speed (10/100/1000Mbps) MAC will be configured + * accordingly. * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() + * @param[in] base: EQOS virtual base address. + * @param[in] speed: Operating speed. * - * Protection: None - * - * Return: None + * @note MAC should be init and started. see osi_start_mac() */ static void eqos_set_speed(void *base, int speed) { @@ -619,19 +603,15 @@ static void eqos_set_speed(void *base, int speed) } /** - * eqos_set_mode - Set operating mode - * @base: EQOS virtual base address - * @mode: Operating mode. + * @brief eqos_set_mode - Set operating mode * - * Algorithm: Based on the mode (HALF/FULL Duplex) MAC will be configured - * accordingly. + * Algorithm: Based on the mode (HALF/FULL Duplex) MAC will be configured + * accordingly. * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() + * @param[in] base: EQOS virtual base address + * @param[in] mode: Operating mode. * - * Protection: None - * - * Return: None + * @note MAC should be init and started. see osi_start_mac() */ static void eqos_set_mode(void *base, int mode) { @@ -650,19 +630,18 @@ static void eqos_set_mode(void *base, int mode) } /** - * eqos_calculate_per_queue_fifo - Calculate per queue FIFO size - * @fifo_size: Total Tx/RX HW FIFO size. - * @queue_count: Total number of Queues configured. + * @brief eqos_calculate_per_queue_fifo - Calculate per queue FIFO size * - * Algorithm: Total Tx/Rx FIFO size which is read from + * Algorithm: Total Tx/Rx FIFO size which is read from * MAC HW is being shared equally among the queues that are * configured. * - * Dependencies: MAC has to be out of reset. + * @param[in] fifo_size: Total Tx/RX HW FIFO size. + * @param[in] queue_count: Total number of Queues configured. * - * Protection: None + * @note MAC has to be out of reset. * - * Return: Queue size that need to be programmed + * @retval Queue size that need to be programmed. */ static unsigned int eqos_calculate_per_queue_fifo(unsigned int fifo_size, unsigned int queue_count) @@ -743,10 +722,9 @@ static unsigned int eqos_calculate_per_queue_fifo(unsigned int fifo_size, } /** - * eqos_pad_calibrate - PAD calibration - * @ioaddr: Base address of the MAC HW. + * @brief eqos_pad_calibrate - PAD calibration * - * Algorithm: + * Algorithm: * 1) Set field PAD_E_INPUT_OR_E_PWRD in reg ETHER_QOS_SDMEMCOMPPADCTRL_0 * 2) Delay for 1 usec. * 3)Set AUTO_CAL_ENABLE and AUTO_CAL_START in reg @@ -755,14 +733,14 @@ static unsigned int eqos_calculate_per_queue_fifo(unsigned int fifo_size, * 5) Re-program the value PAD_E_INPUT_OR_E_PWRD in * ETHER_QOS_SDMEMCOMPPADCTRL_0 to save power * - * Dependencies: - * 1) MAC should out of reset and clocks enabled. - * 2) RGMII and MDIO interface needs to be IDLE before performing PAD - * calibration. + * @param[in] ioaddr: Base address of the MAC HW. * - * Protection: None + * @note 1) MAC should out of reset and clocks enabled. + * 2) RGMII and MDIO interface needs to be IDLE before performing PAD + * calibration. * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ static int eqos_pad_calibrate(void *ioaddr) { @@ -824,19 +802,16 @@ calibration_failed: } /** - * eqos_flush_mtl_tx_queue - Flush MTL Tx queue - * @addr: OSI core private data structure. - * @qinx: MTL queue index. + * @brief eqos_flush_mtl_tx_queue - Flush MTL Tx queue * - * Algorithm: Flush a MTL Tx queue. + * @param[in] addr: OSI core private data structure. + * @param[in] qinx: MTL queue index. * - * Dependencies: - * 1) MAC should out of reset and clocks enabled. - * 2) hw core initialized. see osi_hw_core_init(). - * - * Protection: None. - * - * Return: None. + * @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 int eqos_flush_mtl_tx_queue(void *addr, unsigned int qinx) { @@ -875,19 +850,14 @@ static int eqos_flush_mtl_tx_queue(void *addr, unsigned int qinx) } /** - * update_ehfc_rfa_rfd - Update EHFC, RFD and RSA values - * @rx_fifo: Rx FIFO size. - * @value: Stores RFD and RSA values + * @brief update_ehfc_rfa_rfd - Update EHFC, 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 and also enables HW flow control + * 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 and also enables HW flow control * - * Dependencies: None. - * - * Protection: None. - * - * Return: None. + * @param[in] rx_fifo: Rx FIFO size. + * @param[in] value: Stores RFD and RSA values */ void update_ehfc_rfa_rfd(unsigned int rx_fifo, unsigned int *value) { @@ -974,13 +944,9 @@ void update_ehfc_rfa_rfd(unsigned int rx_fifo, unsigned int *value) } /** - * eqos_configure_mtl_queue - Configure MTL Queue - * @qinx: Queue number that need to be configured. - * @osi_core: OSI core private data. - * @tx_fifo: MTL TX queue size for a MTL queue. - * @rx_fifo: MTL RX queue size for a MTL queue. + * @brief eqos_configure_mtl_queue - Configure MTL Queue * - * Algorithm: This takes care of configuring the below + * 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 @@ -989,11 +955,15 @@ void update_ehfc_rfa_rfd(unsigned int rx_fifo, unsigned int *value) * 5) Configure TxQ weight * 6) Enable Rx Queues * - * Dependencies: MAC has to be out of reset. + * @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. * - * Protection: None - * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ static int eqos_configure_mtl_queue(unsigned int qinx, struct osi_core_priv_data *osi_core, @@ -1052,21 +1022,20 @@ static int eqos_configure_mtl_queue(unsigned int qinx, } /** - * eqos_config_rxcsum_offload - Enable/Disale rx checksum offload in HW - * @addr: EQOS virtual base address. - * @enabled: Flag to indicate feature is to be enabled/disabled. + * @brief eqos_config_rxcsum_offload - Enable/Disale rx checksum offload in HW * - * Algorithm: + * Algorithm: * 1) Read the MAC configuration register. * 2) Enable the IP checksum offload engine COE in MAC receiver. * 3) Update the MAC configuration register. * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() + * @param[in] addr: EQOS virtual base address. + * @param[in] enabled: Flag to indicate feature is to be enabled/disabled. * - * Protection: None. + * @note MAC should be init and started. see osi_start_mac() * - * Return: 0 - success, -1 - failure. + * @retval 0 on success + * @retval -1 on failure. */ static int eqos_config_rxcsum_offload(void *addr, unsigned int enabled) { @@ -1091,23 +1060,19 @@ static int eqos_config_rxcsum_offload(void *addr, unsigned int enabled) } /** - * eqos_configure_rxq_priority - Configure Priorities Selected in - * the Receive Queue + * @brief eqos_configure_rxq_priority - Configure Priorities Selected in + * the Receive Queue * - * @osi_core: OSI private data structure. - * - * Algorithm: This takes care of mapping user priority to Rx queue. + * 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. * - * Dependencies: MAC has to be out of reset. + * @param[in] osi_core: OSI core private data structure. * - * Protection: None - * - * Return: None + * @note MAC has to be out of reset. */ static void eqos_configure_rxq_priority(struct osi_core_priv_data *osi_core) { @@ -1161,10 +1126,9 @@ static void eqos_configure_rxq_priority(struct osi_core_priv_data *osi_core) } /** - * eqos_configure_mac - Configure MAC - * @osi_core: OSI private data structure. + * @brief eqos_configure_mac - Configure MAC * - * Algorithm: This takes care of configuring the below + * 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 @@ -1172,11 +1136,9 @@ static void eqos_configure_rxq_priority(struct osi_core_priv_data *osi_core) * 4) Disable MMC interrupts and Configure the MMC counters * 5) Enable required MAC interrupts * - * Dependencies: MAC has to be out of reset. + * @param[in] osi_core: OSI core private data structure. * - * Protection: None - * - * Return: NONE + * @note MAC has to be out of reset. */ static void eqos_configure_mac(struct osi_core_priv_data *osi_core) { @@ -1285,20 +1247,17 @@ static void eqos_configure_mac(struct osi_core_priv_data *osi_core) } /** - * eqos_configure_dma - Configure DMA - * @base: EQOS virtual base address. + * @brief eqos_configure_dma - Configure DMA * - * Algorithm: This takes care of configuring the below + * 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 * - * Dependencies: MAC has to be out of reset. + * @param[in] base: EQOS virtual base address. * - * Protection: None - * - * Return: NONE + * @note MAC has to be out of reset. */ static void eqos_configure_dma(void *base) { @@ -1324,23 +1283,22 @@ static void eqos_configure_dma(void *base) } /** - * eqos_core_init - EQOS MAC, MTL and common DMA Initialization - * @osi_core: OSI core private data structure. - * @tx_fifo_size: MTL TX FIFO size - * @rx_fifo_size: MTL RX FIFO size + * @brief eqos_core_init - EQOS MAC, MTL and common DMA Initialization * - * Algorithm: This function will take care of initializing MAC, MTL and + * Algorithm: This function will take care of initializing MAC, MTL and * common DMA registers. * - * Dependencies: - * 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. + * @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 * - * Protection: None + * @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. * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ static int eqos_core_init(struct osi_core_priv_data *osi_core, unsigned int tx_fifo_size, @@ -1405,18 +1363,15 @@ static int eqos_core_init(struct osi_core_priv_data *osi_core, } /** - * eqos_handle_mac_intrs - Hanle MAC interrupts - * @osi_core: OSI core private data structure. - * @dma_isr: DMA ISR register read value. + * @brief eqos_handle_mac_intrs - Handle MAC interrupts * - * Algorithm: This function takes care of handling the + * Algorithm: This function takes care of handling the * MAC interrupts which includes speed, mode detection. * - * Dependencies: MAC interrupts need to be enabled + * @param[in] osi_core: OSI core private data structure. + * @param[in] dma_isr: DMA ISR register read value. * - * Protection: None - * - * Return: NONE + * @note MAC interrupts need to be enabled */ static void eqos_handle_mac_intrs(struct osi_core_priv_data *osi_core, unsigned int dma_isr) @@ -1470,18 +1425,13 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *osi_core, } /** - * update_dma_sr_stats - stats for dma_status error - * @osi_core: OSI core private data structure. - * @dma_sr: Dma status register read value - * @qinx: Queue index + * @brief update_dma_sr_stats - stats for dma_status error * - * Algorithm: increament error stats based on corresponding bit filed. + * Algorithm: increament error stats based on corresponding bit filed. * - * Dependencies: None - * - * Protection: None. - * - * Return: None. + * @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 update_dma_sr_stats(struct osi_core_priv_data *osi_core, unsigned int dma_sr, unsigned int qinx) @@ -1521,17 +1471,13 @@ static inline void update_dma_sr_stats(struct osi_core_priv_data *osi_core, } /** - * eqos_handle_common_intr - Handles common interrupt. - * @osi_core: OSI core private data structure. + * @brief eqos_handle_common_intr - Handles common interrupt. * - * Algorithm: Clear common interrupt source. + * Algorithm: Clear common interrupt source. * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() + * @param[in] osi_core: OSI core private data structure. * - * Protection: None. - * - * Return: None. + * @note MAC should be init and started. see osi_start_mac() */ static void eqos_handle_common_intr(struct osi_core_priv_data *osi_core) { @@ -1583,18 +1529,14 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *osi_core) } /** - * eqos_start_mac - Start MAC Tx/Rx engine - * @addr: EQOS virtual base address. + * @brief eqos_start_mac - Start MAC Tx/Rx engine * - * Algorithm: Enable MAC Transmitter and Receiver + * Algorithm: Enable MAC Transmitter and Receiver * - * Dependencies: - * 1) MAC init should be complete. See osi_hw_core_init() and - * osi_hw_dma_init() + * @param[in] addr: EQOS virtual base address. * - * Protection: None. - * - * Return: None. + * @note 1) MAC init should be complete. See osi_hw_core_init() and + * osi_hw_dma_init() */ static void eqos_start_mac(void *addr) { @@ -1609,17 +1551,13 @@ static void eqos_start_mac(void *addr) } /** - * eqos_stop_mac - Stop MAC Tx/Rx engine - * @addr: EQOS virtual base address. + * @brief eqos_stop_mac - Stop MAC Tx/Rx engine * - * Algorithm: Disables MAC Transmitter and Receiver + * Algorithm: Disables MAC Transmitter and Receiver * - * Dependencies: - * 1) MAC DMA deinit should be complete. See osi_hw_dma_deinit() + * @param[in] addr: EQOS virtual base address. * - * Protection: None. - * - * Return: None. + * @note MAC DMA deinit should be complete. See osi_hw_dma_deinit() */ static void eqos_stop_mac(void *addr) { @@ -1635,11 +1573,9 @@ static void eqos_stop_mac(void *addr) } /** - * eqos_set_avb_algorithm - Set TxQ/TC avb config - * @osi_core: osi core priv data structure - * @avb: structure having configuration for avb algorithm + * @brief eqos_set_avb_algorithm - Set TxQ/TC avb config * - * Algorithm: + * Algorithm: * 1) Check if queue index is valid * 2) Update operation mode of TxQ/TC * 2a) Set TxQ operation mode @@ -1650,13 +1586,14 @@ static void eqos_stop_mac(void *addr) * 2f) Set low credit * 3) Update register values * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() - * 2) osi_core->osd should be populated. + * @param[in] osi_core: osi core priv data structure + * @param[in] avb: structure having configuration for avb algorithm * - * Protection: None. + * @note 1) MAC should be init and started. see osi_start_mac() + * 2) osi_core->osd should be populated. * - * Return: 0: success, -1: error. + * @retval 0 on success + * @retval -1 on failure. */ static int eqos_set_avb_algorithm(struct osi_core_priv_data *osi_core, struct osi_core_avb_algorithm *avb) @@ -1732,23 +1669,19 @@ static int eqos_set_avb_algorithm(struct osi_core_priv_data *osi_core, return 0; } -/* - * eqos_config_mac_pkt_filter_reg - configure mac filter register. - * @osi_core: OSI private data structure. - * @filter: OSI filter structure. +/** + * @brief eqos_config_mac_pkt_filter_reg - configure mac filter register. * - * Algorithm: This sequence is used to configure MAC in differnet pkt + * Algorithm: This sequence is used to configure MAC in differnet pkt * processing modes like promiscuous, multicast, unicast, * hash unicast/multicast. * - * Dependencies: - * 1) MAC should be initialized and started. see osi_start_mac() - * 2) MAC addresses should be configured in HW registers. see - * osi_update_mac_addr_low_high_reg(). + * @param[in] osi_core: OSI core private data structure. + * @param[in] pfilter: OSI filter structure. * - * Protection: None - * - * Return: None + * @note 1) MAC should be initialized and started. see osi_start_mac() + * 2) MAC addresses should be configured in HW registers. see + * osi_update_mac_addr_low_high_reg(). */ static void eqos_config_mac_pkt_filter_reg(struct osi_core_priv_data *osi_core, struct osi_filter pfilter) @@ -1775,32 +1708,29 @@ static void eqos_config_mac_pkt_filter_reg(struct osi_core_priv_data *osi_core, } /** - * eqos_update_mac_addr_helper - Function to update DCS and MBC + * @brief eqos_update_mac_addr_helper - Function to update DCS and MBC * - * @osi_core: OSI private data structure. - * @*value: unsigned int pointer which has value read from register. - * @index: filter index - * @value: MAC address to write - * @dma_routing_enable: dma channel routing enable(1) - * @dma_chan: dma channel number - * @addr_mask: filter will not consider byte in comparison - * Bit 29: MAC_Address${i}_High[15:8] - * Bit 28: MAC_Address${i}_High[7:0] - * Bit 27: MAC_Address${i}_Low[31:24] - * .. - * Bit 24: MAC_Address${i}_Low[7:0] - * - * Algorithm: This helper routine is to update passed prameter value + * Algorithm: This helper routine is to update passed prameter value * based on DCS and MBC parameter. Validation of dma_chan as well as * dsc_en status performed before updating DCS bits. * - * Dependencies: - * 1) MAC should be initialized and stated. see osi_start_mac() - * 2) osi_core->osd should be populated. + * @param[in] osi_core: OSI core private data structure. + * @param[out] value: unsigned int 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 + * @param[in] addr_mask: filter will not consider byte in comparison + * Bit 29: MAC_Address${i}_High[15:8] + * Bit 28: MAC_Address${i}_High[7:0] + * Bit 27: MAC_Address${i}_Low[31:24] + * .. + * Bit 24: MAC_Address${i}_Low[7:0] * - * Protection: None + * @note 1) MAC should be initialized and stated. see osi_start_mac() + * 2) osi_core->osd should be populated. * - * Return: 0 - success, -1 - failure. + * @retval 0 on success + * @retval -1 on failure. */ static inline int eqos_update_mac_addr_helper( struct osi_core_priv_data *osi_core, @@ -1844,34 +1774,32 @@ err_dma_chan: } /** - * eqos_update_mac_addr_low_high_reg- Update L2 address - * in filter register + * @brief eqos_update_mac_addr_low_high_reg- Update L2 address in filter + * register * - * @osi_core: OSI private data structure. - * @index: filter index - * @value: MAC address to write - * @dma_routing_enable: dma channel routing enable(1) - * @dma_chan: dma channel number - * @addr_mask: filter will not consider byte in comparison - * Bit 29: MAC_Address${i}_High[15:8] - * Bit 28: MAC_Address${i}_High[7:0] - * Bit 27: MAC_Address${i}_Low[31:24] - * .. - * Bit 24: MAC_Address${i}_Low[7:0] - * @src_dest: SA(1) or DA(0) - * - * Algorithm: This routine update MAC address to register for filtering + * 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. * - * Dependencies: - * 1) MAC should be initialized and stated. see osi_start_mac() - * 2) osi_core->osd should be populated. + * @param[in] osi_core: OSI core private data structure. + * @param[in] idx: filter index + * @param[in] addr: MAC address to write + * @param[in] dma_routing_enable: dma channel routing enable(1) + * @param[in] dma_chan: dma channel number + * @param[in] addr_mask: filter will not consider byte in comparison + * Bit 29: MAC_Address${i}_High[15:8] + * Bit 28: MAC_Address${i}_High[7:0] + * Bit 27: MAC_Address${i}_Low[31:24] + * .. + * Bit 24: MAC_Address${i}_Low[7:0] + * @param[in] src_dest: SA(1) or DA(0) * - * Protection: None + * @note 1) MAC should be initialized and stated. see osi_start_mac() + * 2) osi_core->osd should be populated. * - * Return: 0 - success, -1 - failure. + * @retval 0 on success + * @retval -1 on failure. */ static int eqos_update_mac_addr_low_high_reg( struct osi_core_priv_data *osi_core, @@ -1923,11 +1851,9 @@ static int eqos_update_mac_addr_low_high_reg( } /** - * eqos_get_avb_algorithm - Get TxQ/TC avb config - * @osi_core: osi core priv data structure - * @avb: structure pointer having configuration for avb algorithm + * @brief eqos_get_avb_algorithm - Get TxQ/TC avb config * - * Algorithm: + * Algorithm: * 1) Check if queue index is valid * 2) read operation mode of TxQ/TC * 2a) read TxQ operation mode @@ -1938,13 +1864,14 @@ static int eqos_update_mac_addr_low_high_reg( * 2f) read low credit * 3) updated pointer * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() - * 2) osi_core->osd should be populated. + * @param[in] osi_core: osi core priv data structure + * @param[out] avb: structure pointer having configuration for avb algorithm * - * Protection: None. + * @note 1) MAC should be init and started. see osi_start_mac() + * 2) osi_core->osd should be populated. * - * Return: 0: Success -1: Failure + * @retval 0 on success + * @retval -1 on failure. */ static int eqos_get_avb_algorithm(struct osi_core_priv_data *osi_core, struct osi_core_avb_algorithm *avb) @@ -2006,27 +1933,26 @@ static int eqos_get_avb_algorithm(struct osi_core_priv_data *osi_core, } /** - * eqos_config_arp_offload - Enable/Disable ARP offload - * @mac_ver: MAC version number (different MAC HW version - * need different register offset/fields for ARP offload. - * @addr: EQOS virtual base address. - * @enable: Flag variable to enable/disable ARP offload - * @ip_addr: IP address of device to be programmed in HW. - * HW will use this IP address to respond to ARP requests. + * @brief eqos_config_arp_offload - Enable/Disable ARP offload * - * Algorithm: + * 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. * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() - * 2) Valid 4 byte IP address as argument @ip_addr + * @param[in] mac_ver: MAC version number (different MAC HW version + * need different register offset/fields for ARP offload. + * @param[in] addr: EQOS 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. * - * Protection: None. + * @note 1) MAC should be init and started. see osi_start_mac() + * 2) Valid 4 byte IP address as argument ip_addr * - * Return: 0 - success, -1 - failure. + * @retval 0 on success + * @retval -1 on failure. */ static int eqos_config_arp_offload(unsigned int mac_ver, void *addr, unsigned int enable, @@ -2069,21 +1995,19 @@ static int eqos_config_arp_offload(unsigned int mac_ver, void *addr, return 0; } -/* - * eqos_config_l3_l4_filter_enable - register write to eanble L3/L4 +/** + * @brief eqos_config_l3_l4_filter_enable - register write to enable L3/L4 * filters. * - * @base: Base address from OSI private data structure. - * @enable: enable/disable + * Algorithm: This routine to enable/disable L4/l4 filter * - * Algorithm: This routine to enable/disable L4/l4 filter + * @param[in] base: Base address from OSI core private data structure. + * @param[in] filter_enb_dis: enable/disable * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() + * @note MAC should be init and started. see osi_start_mac() * - * Protection: None - * - * Return: 0 - success, -1 - failure. + * @retval 0 on success + * @retval -1 on failure. */ static int eqos_config_l3_l4_filter_enable(void *base, unsigned int filter_enb_dis) @@ -2100,21 +2024,19 @@ static int eqos_config_l3_l4_filter_enable(void *base, } /** - * eqos_config_l2_da_perfect_inverse_match - configure register for inverse - * or perfect match. + * @brief eqos_config_l2_da_perfect_inverse_match - configure register for + * inverse or perfect match. * - * @base: Base address from OSI private data structure. - * @perfect_inverse_match: 1 - inverse mode 0- normal mode - * - * Algorithm: This sequence is used to select perfect/inverse matching + * Algorithm: This sequence is used to select perfect/inverse matching * for L2 DA * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() + * @param[in] base: Base address from OSI core private data structure. + * @param[in] perfect_inverse_match: 1 - inverse mode 0- normal mode * - * Protection: None + * @note MAC should be init and started. see osi_start_mac() * - * Return: 0 - success, -1 - failure. + * @retval 0 on success + * @retval -1 on failure. */ static int eqos_config_l2_da_perfect_inverse_match(void *base, unsigned int perfect_inverse_match) @@ -2132,23 +2054,22 @@ static int eqos_config_l2_da_perfect_inverse_match(void *base, unsigned int } /** - * eqos_update_ip4_addr - * @osi_core: OSI private data structure. - * @filter_no: filter index - * @addr: ipv4 address - * @src_dst_addr_match: 0 - source addr otherwise - dest addr + * @brief eqos_update_ip4_addr - configure register for IPV4 address filtering * - * Algorithm: This sequence is used to update IPv4 source/destination + * Algorithm: This sequence is used to update IPv4 source/destination * Address for L3 layer filtering * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() - * 2) L3/L4 filtering should be enabled in MAC PFR register. See - * osi_config_l3_l4_filter_enable() + * @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 * - * Protection: None + * @note 1) MAC should be init and started. see osi_start_mac() + * 2) L3/L4 filtering should be enabled in MAC PFR register. See + * osi_config_l3_l4_filter_enable() * - * Return: 0 - success, -1 - failure. + * @retval 0 on success + * @retval -1 on failure. */ static int eqos_update_ip4_addr(struct osi_core_priv_data *osi_core, unsigned int filter_no, @@ -2189,23 +2110,21 @@ static int eqos_update_ip4_addr(struct osi_core_priv_data *osi_core, } /** - * eqos_update_ip6_addr - add ipv6 address in register + * @brief eqos_update_ip6_addr - add ipv6 address in register * - * @osi_core: OSI private data structure. - * @filter_no: filter index - * @addr: ipv6 adderss + * Algorithm: This sequence is used to update IPv6 source/destination + * Address for L3 layer filtering * - * 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 * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() - * 2) L3/L4 filtering should be enabled in MAC PFR register. See - * osi_config_l3_l4_filter_enable() + * @note 1) MAC should be init and started. see osi_start_mac() + * 2) L3/L4 filtering should be enabled in MAC PFR register. See + * osi_config_l3_l4_filter_enable() * - * Protection: None - * - * Return: 0 - success, -1 - failure. + * @retval 0 on success + * @retval -1 on failure. */ static int eqos_update_ip6_addr(struct osi_core_priv_data *osi_core, unsigned int filter_no, unsigned short addr[]) @@ -2254,26 +2173,24 @@ static int eqos_update_ip6_addr(struct osi_core_priv_data *osi_core, } /** - * eqos_update_l4_port_no -program source port no + * @brief eqos_update_l4_port_no -program source port no * - * @osi_core: OSI private data structure. - * @filter_no: filter index - * @port_no: port number - * @src_dst_port_match: 0 - source port, otherwise - dest port - * - * Algorithm: sequence is used to update Source Port Number for + * Algorithm: sequence is used to update Source Port Number for * L4(TCP/UDP) layer filtering. * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() - * 2) L3/L4 filtering should be enabled in MAC PFR register. See - * osi_config_l3_l4_filter_enable() - * 3) osi_core->osd should be populated - * 4) DCS bits should be enabled in RXQ to DMA mapping register + * @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 * - * Protection: None + * @note 1) MAC should be init and started. see osi_start_mac() + * 2) L3/L4 filtering should be enabled in MAC PFR register. See + * osi_config_l3_l4_filter_enable() + * 3) osi_core->osd should be populated + * 4) DCS bits should be enabled in RXQ to DMA mapping register * - * Return: 0 - success, -1 - failure. + * @retval 0 on success + * @retval -1 on failure. */ static int eqos_update_l4_port_no(struct osi_core_priv_data *osi_core, unsigned int filter_no, @@ -2305,25 +2222,22 @@ static int eqos_update_l4_port_no(struct osi_core_priv_data *osi_core, } /** - * eqos_set_dcs - check and update dma routing register + * @brief eqos_set_dcs - check and update dma routing register * - * @osi_core: OSI private data structure. - * @value: unsigned int value for caller - * @dma_routing_enable: filter based dma routing enable(1) - * @dma_chan: dma channel for routing based on filter - * - * Algorithm: Check for request for DCS_enable as well as validate chan + * 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. * - * Dependencies: - * 1) MAC IP should be out of reset and need to be initialized - * as the requirements. - * 2) DCS bits should be enabled in RXQ to DMA mapping register + * @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 * - * Protection: None + * @note 1) MAC IP should be out of reset and need to be initialized + * as the requirements. + * 2) DCS bits should be enabled in RXQ to DMA mapping register * - * Return: updated unsigned int value + *@return updated unsigned int value */ static inline unsigned int eqos_set_dcs(struct osi_core_priv_data *osi_core, unsigned int value, @@ -2344,32 +2258,30 @@ static inline unsigned int eqos_set_dcs(struct osi_core_priv_data *osi_core, return value; } /** - * eqos_config_l3_filters - config L3 filters. + * @brief eqos_config_l3_filters - config L3 filters. * - * @osi_core: OSI private data structure. - * @filter_no: filter index - * @enb_dis: 1 - enable otherwise - disable L3 filter - * @ipv4_ipv6_match: 1 - IPv6, otherwise - IPv4 - * @src_dst_addr_match: 0 - source, otherwise - destination - * @perfect_inverse_match: normal match(0) or inverse map(1) - * @dma_routing_enable: filter based dma routing enable(1) - * @dma_chan: dma channel for routing based on filter - * - * Algorithm: Check for DCS_enable as well as validate channel + * 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. * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() - * 2) L3/L4 filtering should be enabled in MAC PFR register. See - * osi_config_l3_l4_filter_enable() - * 3) osi_core->osd should be populated - * 4) DCS bits should be enabled in RXQ to DMA map register + * @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 * - * Protection: None + * @note 1) MAC should be init and started. see osi_start_mac() + * 2) L3/L4 filtering should be enabled in MAC PFR register. See + * osi_config_l3_l4_filter_enable() + * 3) osi_core->osd should be populated + * 4) DCS bits should be enabled in RXQ to DMA map register * - * Return: 0 - success, -1 - failure. + * @retval 0 on success + * @retval -1 on failure. */ static int eqos_config_l3_filters(struct osi_core_priv_data *osi_core, unsigned int filter_no, @@ -2516,29 +2428,27 @@ static int eqos_config_l3_filters(struct osi_core_priv_data *osi_core, } /** - * osi_config_l4_filters - Config L4 filters. + * @brief osi_config_l4_filters - Config L4 filters. * - * @osi_core: OSI private data structure. - * @filter_no: filter index - * @enb_dis: 1 - enable, otherwise - disable L4 filter - * @tcp_udp_match: 1 - udp, 0 - tcp - * @src_dst_port_match: 0 - source port, otherwise - dest port - * @perfect_inverse_match: normal match(0) or inverse map(1) - * @dma_routing_enable: filter based dma routing enable(1) - * @dma_chan: dma channel for routing based on filter - * - * Algorithm: This sequence is used to configure L4(TCP/UDP) filters for + * Algorithm: This sequence is used to configure L4(TCP/UDP) filters for * SA and DA Port Number matching * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() - * 2) L3/L4 filtering should be enabled in MAC PFR register. See - * osi_config_l3_l4_filter_enable() - * 3) osi_core->osd should be populated + * @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 * - * Protection: None + * @note 1) MAC should be init and started. see osi_start_mac() + * 2) L3/L4 filtering should be enabled in MAC PFR register. See + * osi_config_l3_l4_filter_enable() + * 3) osi_core->osd should be populated * - * Return: 0 - success, -1 - failure. + * @retval 0 on success + * @retval -1 on failure. */ static int eqos_config_l4_filters(struct osi_core_priv_data *osi_core, unsigned int filter_no, @@ -2628,23 +2538,21 @@ static int eqos_config_l4_filters(struct osi_core_priv_data *osi_core, } /** - * eqos_config_vlan_filter_reg - config vlan filter register + * @brief eqos_config_vlan_filter_reg - config vlan filter register * - * @base: Base address from OSI private data structure. - * @filter_enb_dis: vlan filter enable/disable - * @perfect_hash_filtering: perfect or hash filter - * @perfect_inverse_match: normal or inverse filter - * - * Algorithm: This sequence is used to enable/disable VLAN filtering and + * Algorithm: This sequence is used to enable/disable VLAN filtering and * also selects VLAN filtering mode- perfect/hash * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() - * 2) osi_core->osd should be populated + * @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 * - * Protection: None + * @note 1) MAC should be init and started. see osi_start_mac() + * 2) osi_core->osd should be populated * - * Return: 0 - success, -1 - failure. + * @retval 0 on success + * @retval -1 on failure. */ static int eqos_config_vlan_filtering(struct osi_core_priv_data *osi_core, unsigned int filter_enb_dis, @@ -2672,20 +2580,17 @@ static int eqos_config_vlan_filtering(struct osi_core_priv_data *osi_core, } /** - * eqos_update_vlan_id - update VLAN ID in Tag register + * @brief eqos_update_vlan_id - update VLAN ID in Tag register * - * @base: Base address from OSI private data structure. + * @param[in] base: Base address from OSI core private data structure. + * @param[in] vid: VLAN ID to be programmed. * - * Algorithm: update vid at VLAN tag register + * @note MAC should be init and started. see osi_start_mac() * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() - * - * Protection: None - * - * Return: 0 - success, -1 - failure. + * @retval 0 on success + * @retval -1 on failure. */ -static inline int eqos_update_vlan_id(void *base, unsigned int vid) +static inline int eqos_update_vlan_id(void *base, unsigned int vid) { unsigned int value; @@ -2699,19 +2604,19 @@ static inline int eqos_update_vlan_id(void *base, unsigned int vid) } /** - * eqos_poll_for_tsinit_complete - Poll for time stamp init complete - * @addr: MAC base address. - * @mac_tcr: Address to store time stamp control register read value + * @brief eqos_poll_for_tsinit_complete - Poll for time stamp init complete * - * Algorithm: Read TSINIT value from MAC TCR register until it is + * Algorithm: Read TSINIT value from MAC TCR register until it is * equal to zero. * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() + * @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 * - * Protection: None. + * @note MAC should be init and started. see osi_start_mac() * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ static inline int eqos_poll_for_tsinit_complete(void *addr, unsigned int *mac_tcr) @@ -2741,20 +2646,20 @@ static inline int eqos_poll_for_tsinit_complete(void *addr, } /** - * eqos_set_systime - Set system time - * @addr: MAC base address. - * @sec: Seconds to be configured - * @nsec: Nano Seconds to be configured + * @brief eqos_set_systime - Set system time * - * Algorithm: Updates system time (seconds and nano seconds) + * Algorithm: Updates system time (seconds and nano seconds) * in hardware registers * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() + * @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 * - * Protection: None. + * @note MAC should be init and started. see osi_start_mac() * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ static int eqos_set_systime_to_mac(void *addr, unsigned int sec, unsigned int nsec) @@ -2789,19 +2694,19 @@ static int eqos_set_systime_to_mac(void *addr, unsigned int sec, } /** - * eqos_poll_for_tsinit_complete - Poll for addend value write complete - * @addr: MAC base address. - * @mac_tcr: Address to store time stamp control register read value + * @brief eqos_poll_for_tsinit_complete - Poll for addend value write complete * - * Algorithm: Read TSADDREG value from MAC TCR register until it is + * Algorithm: Read TSADDREG value from MAC TCR register until it is * equal to zero. * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() + * @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 * - * Protection: None. + * @note MAC should be init and started. see osi_start_mac() * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ static inline int eqos_poll_for_addend_complete(void *addr, unsigned int *mac_tcr) @@ -2830,18 +2735,18 @@ static inline int eqos_poll_for_addend_complete(void *addr, } /** - * eqos_config_addend - Configure addend - * @addr: MAC base address. - * @addend: Addend value to be configured + * @brief eqos_config_addend - Configure addend * - * Algorithm: Updates the Addend value in HW register + * Algorithm: Updates the Addend value in HW register * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() + * @param[in] addr: Base address indicating the start of + * memory mapped IO region of the MAC. + * @param[in] addend: Addend value to be configured * - * Protection: None. + * @note MAC should be init and started. see osi_start_mac() * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ static int eqos_config_addend(void *addr, unsigned int addend) { @@ -2871,19 +2776,19 @@ static int eqos_config_addend(void *addr, unsigned int addend) } /** - * eqos_poll_for_update_ts_complete - Poll for update time stamp - * @addr: MAC base address. - * @mac_tcr: Address to store time stamp control register read value + * @brief eqos_poll_for_update_ts_complete - Poll for update time stamp * - * Algorithm: Read time stamp update value from TCR register until it is + * Algorithm: Read time stamp update value from TCR register until it is * equal to zero. * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() + * @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 * - * Protection: None. + * @note MAC should be init and started. see osi_start_mac() * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ static inline int eqos_poll_for_update_ts_complete(void *addr, unsigned int *mac_tcr) @@ -2912,22 +2817,22 @@ static inline int eqos_poll_for_update_ts_complete(void *addr, } /** - * eqos_adjust_systime - Adjust system time - * @addr: MAC base address. - * @sec: Seconds to be configured - * @nsec: Nano seconds to be configured - * @add_sub: To decide on add/sub with system time - * @one_nsec_accuracy: One nano second accuracy + * @brief eqos_adjust_systime - Adjust system time * - * Algorithm: Update the system time + * Algorithm: Update the system time * - * Dependencies: - * 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 + * @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 * - * Protection: None. + * @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 * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ static int eqos_adjust_systime(void *addr, unsigned int sec, unsigned int nsec, unsigned int add_sub, @@ -2998,17 +2903,17 @@ static int eqos_adjust_systime(void *addr, unsigned int sec, unsigned int nsec, } /** - * eqos_get_systime - Get system time from MAC - * @addr: MAC base address. + * @brief eqos_get_systime - Get system time from MAC * - * Algorithm: Get current system time + * Algorithm: Get current system time * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() + * @param[in] addr: Base address indicating the start of + * memory mapped IO region of the MAC. * - * Protection: None. + * @note MAC should be init and started. see osi_start_mac() * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ static unsigned long long eqos_get_systime_from_mac(void *addr) { @@ -3046,19 +2951,14 @@ static unsigned long long eqos_get_systime_from_mac(void *addr) } /** - * eqos_config_tscr - Configure Time Stamp Register - * @addr: MAC base address. - * @ptp_filter: PTP rx filter parameters + * @brief eqos_config_tscr - Configure Time Stamp Register * - * Algorithm: 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 * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() - * - * Protection: None. - * - * Return: None. - **/ + * @note MAC should be init and started. see osi_start_mac() + */ static void eqos_config_tscr(void *addr, unsigned int ptp_filter) { unsigned int mac_tcr = 0; @@ -3122,18 +3022,13 @@ static void eqos_config_tscr(void *addr, unsigned int ptp_filter) } /** - * eqos_config_ssir - Configure SSIR - * @addr: MAC base address. - * @ptp_clock: PTP clock + * @brief eqos_config_ssir - Configure SSIR * - * Algorithm: Configure Sub Second Increment Register + * @param[in] addr: Base address indicating the start of + * memory mapped IO region of the MAC. + * @param[in] ptp_clock: PTP clock * - * Dependencies: - * 1) MAC should be init and started. see osi_start_mac() - * - * Protection: None. - * - * Return: None. + * @note MAC should be init and started. see osi_start_mac() */ static void eqos_config_ssir(void *addr, unsigned int ptp_clock) { @@ -3169,16 +3064,13 @@ static void eqos_config_ssir(void *addr, unsigned int ptp_clock) } /** - * eqos_core_deinit - EQOS MAC core deinitialization - * @osi_core: OSI core private data structure. + * @brief eqos_core_deinit - EQOS MAC core deinitialization * - * Algorithm: This function will take care of deinitializing MAC + * Algorithm: This function will take care of deinitializing MAC * - * Dependencies: Required clks and resets has to be enabled + * @param[in] osi_core: OSI core private data structure. * - * Protection: None - * - * Return: None + * @note Required clks and resets has to be enabled */ static void eqos_core_deinit(struct osi_core_priv_data *osi_core) { @@ -3186,6 +3078,9 @@ static void eqos_core_deinit(struct osi_core_priv_data *osi_core) eqos_stop_mac(osi_core->base); } +/** + * @brief eqos_core_ops - EQOS MAC core operations + */ static struct osi_core_ops eqos_core_ops = { .poll_for_swr = eqos_poll_for_swr, .core_init = eqos_core_init, @@ -3230,11 +3125,17 @@ static struct osi_core_ops eqos_core_ops = { .reset_mmc = eqos_reset_mmc, }; +/** + * @brief eqos_get_core_safety_config - EQOS MAC safety configuration + */ void *eqos_get_core_safety_config(void) { return &eqos_core_safety_config; } +/** + * @brief eqos_get_hw_core_ops - EQOS MAC get core operations + */ struct osi_core_ops *eqos_get_hw_core_ops(void) { return &eqos_core_ops; diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 93b7851..0d49f5b 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -23,8 +23,12 @@ #ifndef EQOS_CORE_H_ #define EQOS_CORE_H_ -/* These bits control the threshold (fill-level of Rx queue) at which +/** + * @addtogroup EQOS-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 @@ -34,20 +38,26 @@ #define FULL_MINUS_6_K (unsigned int)10 #define FULL_MINUS_10_K (unsigned int)18 #define FULL_MINUS_16_K (unsigned int)30 +/** @} */ /** - * MTL queue operation mode - * EQOS_MTL_QUEUE_DISABLED - queue disabled - * EQOS_MTL_QUEUE_QAVB - queue in AVB mode - * EQOS_MTL_QUEUE_QDCB - queue in DCB mode - * EQOS_MTL_QUEUE_QGENERIC - queue in gerneric mode + * @addtogroup EQOS-MTLQ MTL queue operation mode + * + * @brief MTL queue operation mode options + * @{ */ #define EQOS_MTL_QUEUE_DISABLED 0x0U #define EQOS_MTL_QUEUE_AVB 0x1U #define EQOS_MTL_QUEUE_DCB 0x2U #define EQOS_MTL_QUEUE_GENERIC 0x3U +/** @} */ -/* MDC Clock Selection define*/ +/** + * @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 */ @@ -56,11 +66,24 @@ #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 */ +/** @} */ +/** + * @addtogroup EQOS-SIZE SIZE calculation helper Macros + * + * @brief SIZE calculation defines + * @{ + */ #define FIFO_SIZE_B(x) (x) #define FIFO_SIZE_KB(x) ((x) * 1024U) +/** @} */ -/* per queue fifo size programmable value */ +/** + * @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 @@ -71,8 +94,14 @@ #define EQOS_16K 0x3FU #define EQOS_32K 0x7FU #define EQOS_36K 0x8FU +/** @} */ -/* EQOS HW Registers */ +/** + * @addtogroup EQOS-HW Hardware Register offsets + * + * @brief EQOS HW register offsets + * @{ + */ #define EQOS_5_00_MAC_ARPPA 0x0210 #define EQOS_4_10_MAC_ARPPA 0x0AE0 #define EQOS_DMA_SBUS 0x1004 @@ -120,8 +149,14 @@ #define EQOS_MAC_STSUR 0x0B10 #define EQOS_MAC_STNSUR 0x0B14 #define EQOS_MAC_TAR 0x0B18 +/** @} */ -/* EQOS MTL registers*/ +/** + * @addtogroup EQOS-MTL MTL HW Register offsets + * + * @brief EQOS MTL HW Register offsets + * @{ + */ #define EQOS_MTL_CHX_TX_OP_MODE(x) ((0x0040U * (x)) + 0x0D00U) #define EQOS_MTL_TXQ_QW(x) ((0x0040U * (x)) + 0x0D18U) #define EQOS_MTL_CHX_RX_OP_MODE(x) ((0x0040U * (x)) + 0x0D30U) @@ -131,14 +166,26 @@ #define EQOS_MTL_TXQ_ETS_LCR(x) ((0x0040U * (x)) + 0x0D24U) #define EQOS_MTL_RXQ_DMA_MAP0 0x0C30 #define EQOS_MTL_OP_MODE 0x0C00 +/** @} */ -/* EQOS Wrapper registers*/ +/** + * @addtogroup EQOS-Wrapper EQOS Wrapper HW Register offsets + * + * @brief EQOS Wrapper register offsets + * @{ + */ #define EQOS_PAD_AUTO_CAL_CFG 0x8804U #define EQOS_PAD_AUTO_CAL_STAT 0x880CU #define EQOS_PAD_CRTL 0x8800U #define EQOS_CLOCK_CTRL_0 0x8000U +/** @} */ -/* EQOS Register BIT Masks */ +/** + * @addtogroup HW Register BIT values + * + * @brief consists of corresponding EQOS MAC, MTL register bit values + * @{ + */ #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) @@ -335,11 +382,25 @@ #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) +/** @} */ +/** + * @brief update_ehfc_rfa_rfd - Update EHFC, RFD and RSA values + * + * Algorithm: Calculates 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 + * + * @param[in] rx_fifo: Rx FIFO size. + * @param[in] value: Stores RFD and RSA values + */ void update_ehfc_rfa_rfd(unsigned int rx_fifo, unsigned int *value); -/* Below macros are used for periodic reg validation for functional safety. - * HW register mask - to mask reserved and self-clearing bits +/** + * @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 @@ -398,21 +459,22 @@ void update_ehfc_rfa_rfd(unsigned int rx_fifo, unsigned int *value); #define EQOS_MTL_CH3_RX_OP_MODE_IDX 29U #define EQOS_DMA_SBUS_IDX 30U #define EQOS_MAX_CORE_SAFETY_REGS 31U +/** @} */ /** - * struct core_func_safety - Struct used to store last written values of + * @brief core_func_safety - Struct used to store last written values of * critical core HW registers. - * @reg_addr: Array of reg MMIO addresses (base of EQoS + offset of reg) - * @reg_mask: Array of bit-mask value of each corresponding reg (used to - * ignore self-clearing/reserved bits in reg). - * @reg_val: Array of value stored in each corresponding register. - * @core_safety_lock: OSI lock variable used to protect writes to reg while - * validation is in-progress. */ 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) */ unsigned int reg_mask[EQOS_MAX_CORE_SAFETY_REGS]; + /** Array of value stored in each corresponding register */ unsigned int reg_val[EQOS_MAX_CORE_SAFETY_REGS]; + /** OSI lock variable used to protect writes to reg while + * validation is in-progress */ unsigned int core_safety_lock; }; #endif diff --git a/osi/core/eqos_mmc.c b/osi/core/eqos_mmc.c index 51975cd..2e5c8da 100644 --- a/osi/core/eqos_mmc.c +++ b/osi/core/eqos_mmc.c @@ -27,22 +27,21 @@ #include "eqos_core.h" /** - * update_mmc_val - function to read resgister and return vlaue to callee + * @brief update_mmc_val - function to read register and return value to callee * - * @osi_core: OSI core private data structure. - * @last_vlaue: previous value of stats variable. - * @offset: HW register offset + * Algorithm: Read the registers, check for boundary, if more, reset + * counters else return same to caller. * - * 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 * - * Dependencies: + * @note * 1) MAC should be init and started. see osi_start_mac() * 2) osi_core->osd should be populated * - * Protection: None - * - * Return: unsigned value + * @retval 0 on success + * @retval -1 on failure */ static inline unsigned long update_mmc_val(struct osi_core_priv_data *osi_core, unsigned long last_value, @@ -66,19 +65,14 @@ static inline unsigned long update_mmc_val(struct osi_core_priv_data *osi_core, } /** - * eqos_reset_mmc - To reset MMC registers and ether_mmc_counter structure - * variable - * @osi_core: OSI core private data structure. + * @brief eqos_reset_mmc - To reset MMC registers and ether_mmc_counter + * structure variable * - * Algorithm: reset HW counter and structure variable value. + * @param[in] osi_core: OSI core private data structure. * - * Dependencies: + * @note * 1) MAC should be init and started. see osi_start_mac() * 2) osi_core->osd should be populated - * - * Protection: None - * - * Return: None */ void eqos_reset_mmc(struct osi_core_priv_data *osi_core) { @@ -92,20 +86,17 @@ void eqos_reset_mmc(struct osi_core_priv_data *osi_core) } /** - * eqos_read_mmc - To read MMC registers and ether_mmc_counter structure - * variable - * @osi_core: OSI core private data structure. + * @brief eqos_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. + * Algorithm: Pass register offset and old value to helper function and + * update structure. * - * Dependencies: + * @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 - * - * Protection: None - * - * Return: None */ void eqos_read_mmc(struct osi_core_priv_data *osi_core) { diff --git a/osi/core/eqos_mmc.h b/osi/core/eqos_mmc.h index d581792..8c293fa 100644 --- a/osi/core/eqos_mmc.h +++ b/osi/core/eqos_mmc.h @@ -23,6 +23,12 @@ #ifndef EQOS_MMC_H_ #define EQOS_MMC_H_ +/** + * @addtogroup EQOS-MMC MMC HW register offsets + * + * @brief MMC HW register offsets + * @{ + */ #define MMC_TXOCTETCOUNT_GB 0x00714 #define MMC_TXPACKETCOUNT_GB 0x00718 #define MMC_TXBROADCASTPACKETS_G 0x0071c @@ -103,7 +109,32 @@ #define MMC_RXTCP_ERR_OCTETS 0x0087c #define MMC_RXICMP_GD_OCTETS 0x00880 #define MMC_RXICMP_ERR_OCTETS 0x00884 +/** @} */ +/** + * @brief eqos_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 eqos_read_mmc(struct osi_core_priv_data *osi_core); + +/** + * @brief eqos_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 eqos_reset_mmc(struct osi_core_priv_data *osi_core); #endif diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 5523816..165aece 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -23,6 +23,11 @@ #include <osi_core.h> #include <osd.h> +/** + * @addtogroup MDIO Macros + * @brief Helper MACROS for MDIO + * @{ + */ #define MAC_MDIO_ADDRESS 0x200 #define MAC_GMII_BUSY 0x00000001U @@ -34,7 +39,18 @@ #define MDIO_PHY_ADDR_SHIFT 21U #define MDIO_PHY_REG_SHIFT 16U #define MDIO_MII_WRITE OSI_BIT(2) +/** @} */ +/** + * @brief poll_for_mii_idle Query the status of an ongoing DMA transfer + * + * @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 inline int poll_for_mii_idle(struct osi_core_priv_data *osi_core) { unsigned int retry = 1000; @@ -645,20 +661,19 @@ int osi_set_systime_to_mac(struct osi_core_priv_data *osi_core, } /** - * div_u64_rem - updates remainder and returns Quotient - * @dividend: Dividend value - * @divisor: Divisor value - * @remainder: Remainder + *@brief div_u64_rem - updates remainder and returns Quotient * - * Algorithm: Dividend will be divided by divisor and stores the - * remainder value and returns quotient + * Algorithm: Dividend will be divided by divisor and stores the + * remainder value and returns quotient * - * Dependencies: MAC IP should be out of reset - * and need to be initialized as the requirements + * @param[in] dividend: Dividend value + * @param[in] divisor: Divisor value + * @param[out] remain: Remainder * - * Protection: None + * @note MAC IP should be out of reset and need to be initialized as the + * requirements * - * Return: Quotient + * @returns Quotient */ static inline unsigned long div_u64_rem(unsigned long dividend, unsigned long divisor, @@ -676,18 +691,15 @@ static inline unsigned long div_u64_rem(unsigned long dividend, } /** - * div_u64 - Calls a function which returns quotient - * @dividend: Dividend - * @divisor: Divisor + * @brief div_u64 - Calls a function which returns quotient * - * Algorithm: Calls a function which returns quotient. + * @param[in] dividend: Dividend + * @param[in] divisor: Divisor * - * Dependencies: MAC IP should be out of reset - * and need to be initialized as the requirements. + * @note MAC IP should be out of reset and need to be initialized as the + * requirements. * - * Protection: None - * - * Return: Quotient + * @returns Quotient */ static inline unsigned long div_u64(unsigned long dividend, unsigned long divisor) diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index 1d270fb..e7e501b 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -24,15 +24,15 @@ #include <osi_dma.h> #include "eqos_dma.h" +/** + * @brief eqos_dma_safety_config - EQOS MAC DMA safety configuration + */ static struct dma_func_safety eqos_dma_safety_config; /** - * eqos_dma_safety_writel - Write to safety critical register. - * @val: Value to be written. - * @addr: memory mapped register address to be written to. - * @idx: Index of register corresponding to enum func_safety_dma_regs. + * @brief Write to safety critical register. * - * Algorithm: + * Algorithm: * 1) Acquire RW lock, so that eqos_validate_dma_regs does not run while * updating the safety critical register. * 2) call osi_writel() to actually update the memory mapped register. @@ -40,12 +40,11 @@ static struct dma_func_safety eqos_dma_safety_config; * this latest value will be compared when eqos_validate_dma_regs is * scheduled. * - * Dependencies: - * 1) MAC has to be out of reset, and clocks supplied. + * @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. * - * Protection: None. - * - * Return: None. + * @note MAC has to be out of reset, and clocks supplied. */ static inline void eqos_dma_safety_writel(unsigned int val, void *addr, unsigned int idx) @@ -59,21 +58,16 @@ static inline void eqos_dma_safety_writel(unsigned int val, void *addr, } /** - * eqos_dma_safety_init - Initialize the eqos_dma_safety_config. - * @base_addr: Base address of memory mapped register space. + * @brief Initialize the eqos_dma_safety_config. * - * Algorithm: Populate the list of safety critical registers and provide + * @param[in] osi_dma: OSI DMA private data structure. + * + * Algorithm: Populate the list of safety critical registers and provide * 1) the address of the register * 2) Register mask (to ignore reserved/self-critical bits in the reg). - * See @eqos_validate_dma_regs which can be ivoked periodically to compare + * See eqos_validate_dma_regs which can be ivoked periodically to compare * the last written value to this register vs the actual value read when * eqos_validate_dma_regs is scheduled. - * - * Dependencies: None - * - * Protection: None - * - * Return: None */ static void eqos_dma_safety_init(struct osi_dma_priv_data *osi_dma) { @@ -131,21 +125,22 @@ static void eqos_dma_safety_init(struct osi_dma_priv_data *osi_dma) } /** - * eqos_validate_dma_regs - Read-validate HW registers for functional safety. - * @osi_dma: OSI dma private data structure. - * Algorithm: Reads pre-configured list of MAC/MTL configuration registers + * @brief Read-validate HW registers for functional safety. + * + * Algorithm: Reads pre-configured list of MAC/MTL configuration registers * and compares with last written value for any modifications. * - * Dependencies: + * @param[in] osi_dma: OSI DMA private data structure. + * + * @note * 1) MAC has to be out of reset. * 2) 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 + * the safety_config (see osi_dma_priv_data) based on MAC version and * which specific registers needs to be validated periodically. * 3) Invoke this call iff (osi_dma_priv_data->safety_config != OSI_NULL) * - * Protection: None - * - * Return: 0 - success, -1 - failure + * @retval 0 on success + * @retval -1 on failure. */ static int eqos_validate_dma_regs(struct osi_dma_priv_data *osi_dma) { @@ -180,21 +175,16 @@ static int eqos_validate_dma_regs(struct osi_dma_priv_data *osi_dma) } /** - * eqos_disable_chan_tx_intr - Disables DMA Tx channel interrupts. - * @addr: MAC base address. - * @chan: DMA Tx channel number. + * @brief eqos_disable_chan_tx_intr - Disables DMA Tx channel interrupts. * - * Algorithm: Disables Tx interrupts at wrapper level. + * @param[in] addr: Base address indicating the start of + * memory mapped IO region of the MAC. + * @param[in] chan: DMA Tx channel number. * - * Dependencies: - * 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. - * - * Protection: None. - * - * Return: None. + * @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 eqos_disable_chan_tx_intr(void *addr, unsigned int chan) { @@ -206,21 +196,16 @@ static void eqos_disable_chan_tx_intr(void *addr, unsigned int chan) } /** - * eqos_enable_chan_tx_intr - Enable Tx channel interrupts. - * @addr: MAC base address. - * @chan: DMA Tx channel number. + * @brief eqos_enable_chan_tx_intr - Enable Tx channel interrupts. * - * Algorithm: Enables EQOS 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. * - * Dependencies: - * 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. - * - * Protection: None. - * - * Return: None. + * @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 eqos_enable_chan_tx_intr(void *addr, unsigned int chan) { @@ -232,19 +217,16 @@ static void eqos_enable_chan_tx_intr(void *addr, unsigned int chan) } /** - * eqos_disable_chan_rx_intr - Disable Rx channel interrupts. - * @addr: MAC base address. - * @chan: DMA Rx channel number. + * @brief eqos_disable_chan_rx_intr - Disable Rx channel interrupts. * - * Algorithm: Disables EQOS DMA 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. * - * Dependencies: - * 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. - * Protection: None. - * Return: None. + * @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 eqos_disable_chan_rx_intr(void *addr, unsigned int chan) { @@ -256,19 +238,14 @@ static void eqos_disable_chan_rx_intr(void *addr, unsigned int chan) } /** - * eqos_enable_chan_rx_intr - Enable Rx channel interrupts. - * @addr: MAC base address. - * @chan: DMA Rx channel number. + * @brief eqos_enable_chan_rx_intr - Enable Rx channel interrupts. * - * Algorithm: Enables EQOS DMA 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. * - * Dependencies: - * 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 - * - * Protection: None. - * - * Return: None. + * @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 eqos_enable_chan_rx_intr(void *addr, unsigned int chan) { @@ -280,21 +257,18 @@ static void eqos_enable_chan_rx_intr(void *addr, unsigned int chan) } /** - * eqos_clear_tx_intr - Handle EQOS DMA Tx channel interrupts. - * @addr: MAC base address. - * @chan: DMA Tx channel number. + * @brief eqos_clear_tx_intr - Handle EQOS DMA Tx channel interrupts. * - * Algorithm: Clear DMA Tx interrupt source at wrapper and DMA level. + * Algorithm: Clear DMA Tx interrupt source at wrapper and DMA level. * - * Dependencies: - * 1) MAC needs to be out of reset and proper clocks need to be configured. + * @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. - * - * Protection: None. - * - * Return: None. */ static void eqos_clear_tx_intr(void *addr, unsigned int chan) { @@ -310,21 +284,18 @@ static void eqos_clear_tx_intr(void *addr, unsigned int chan) } /** - * eqos_clear_rx_intr - Handles DMA Rx channel interrupts. - * @addr: MAC base address. - * @chan: DMA Rx channel number. + * @brief eqos_clear_rx_intr - Handles DMA Rx channel interrupts. * - * Algorithm: Clear DMA Rx interrupt source at wrapper and DMA level. + * Algorithm: Clear DMA Rx interrupt source at wrapper and DMA level. * - * Dependencies: - * 1) MAC needs to be out of reset and proper clocks need to be configured. + * @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. - * - * Protection: None. - * - * Return: None. */ static void eqos_clear_rx_intr(void *addr, unsigned int chan) { @@ -340,18 +311,14 @@ static void eqos_clear_rx_intr(void *addr, unsigned int chan) } /** - * eqos_set_tx_ring_len - Set DMA Tx ring length. - * @addr: MAC base address. - * @chan: DMA Tx channel number. - * @len: Length. + * @brief eqos_set_tx_ring_len - Set DMA Tx ring length. * - * Algorithm: Set DMA Tx channel ring length for specific channel. + * Algorithm: Set DMA Tx channel ring length for specific channel. * - * Dependencies: None. - * - * Protection: None. - * - * Return: None. + * @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] len: Length. */ static void eqos_set_tx_ring_len(void *addr, unsigned int chan, unsigned int len) @@ -362,18 +329,14 @@ static void eqos_set_tx_ring_len(void *addr, unsigned int chan, } /** - * eqos_set_tx_ring_start_addr - Set DMA Tx ring base address. - * @addr: MAC base address. - * @chan: DMA Tx channel number. - * @tx_desc: Tx desc base addess. + * @brief eqos_set_tx_ring_start_addr - Set DMA Tx ring base address. * - * Algorithm: Sets DMA Tx ring base address for specific channel. + * Algorithm: Sets DMA Tx ring base address for specific channel. * - * Dependencies: None. - * - * Protection: None. - * - * Return: None. + * @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 eqos_set_tx_ring_start_addr(void *addr, unsigned int chan, unsigned long tx_desc) @@ -383,20 +346,18 @@ static void eqos_set_tx_ring_start_addr(void *addr, unsigned int chan, } /** - * eqos_update_tx_tailptr - Updates DMA Tx ring tail pointer. - * @addr: MAC base address. - * @chan: DMA Tx channel number. - * @tailptr: DMA Tx ring tail pointer. + * @brief eqos_update_tx_tailptr - Updates DMA Tx ring tail pointer. * - * Algorithm: Updates DMA Tx ring tail pointer for specific channel. + * Algorithm: Updates DMA Tx ring tail pointer for specific channel. * - * Dependencies: - * 1) MAC needs to be out of reset and proper clocks need to be configured. + * @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 - * - * Protection: None. - * - * Return: None. */ static void eqos_update_tx_tailptr(void *addr, unsigned int chan, unsigned long tailptr) @@ -405,18 +366,14 @@ static void eqos_update_tx_tailptr(void *addr, unsigned int chan, } /** - * eqos_set_rx_ring_len - Set Rx channel ring length. - * @addr: MAC base address. - * @chan: DMA Rx channel number. - * @len: Length + * @brief eqos_set_rx_ring_len - Set Rx channel ring length. * - * Algorithm: Sets DMA Rx channel ring length for specific DMA channel. + * Algorithm: Sets DMA Rx channel ring length for specific DMA channel. * - * Dependencies: None. - * - * Protection: None. - * - * Return: None. + * @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] len: Length */ static void eqos_set_rx_ring_len(void *addr, unsigned int chan, unsigned int len) @@ -427,18 +384,14 @@ static void eqos_set_rx_ring_len(void *addr, unsigned int chan, } /** - * eqos_set_rx_ring_start_addr - Set DMA Rx ring base address. - * @addr: MAC base address. - * @chan: DMA Rx channel number. - * @tx_desc: DMA Rx desc base address. + * @brief eqos_set_rx_ring_start_addr - Set DMA Rx ring base address. * - * Algorithm: Sets DMA Rx channel ring base address. + * Algorithm: Sets DMA Rx channel ring base address. * - * Dependencies: None. - * - * Protection: None. - * - * Return: None. + * @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 eqos_set_rx_ring_start_addr(void *addr, unsigned int chan, unsigned long tx_desc) @@ -448,41 +401,36 @@ static void eqos_set_rx_ring_start_addr(void *addr, unsigned int chan, } /** - * eqos_update_rx_tailptr - Update Rx ring tail pointer - * @addr: MAC base address. - * @chan: DMA Rx channel number. - * @tailptr: Tail pointer + * @brief eqos_update_rx_tailptr - Update Rx ring tail pointer * - * Algorithm: Updates DMA Rx channel tail pointer for specific channel. + * Algorithm: Updates DMA Rx channel tail pointer for specific channel. * - * Dependencies: - * 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 + * @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 * - * Protection: None. - * - * Return: None. + * @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 eqos_update_rx_tailptr(void *addr, unsigned int chan, unsigned long tailptr) { - osi_writel((unsigned int)L32(tailptr), (unsigned char *)addr + EQOS_DMA_CHX_RDTP(chan)); + osi_writel((unsigned int)L32(tailptr), (unsigned char *)addr + + EQOS_DMA_CHX_RDTP(chan)); } /** - * eqos_start_dma - Start DMA. - * @addr: MAC base address. - * @chan: DMA Tx/Rx channel number. + * @brief eqos_start_dma - Start DMA. * - * Algorithm: Start Tx and Rx DMA for specific channel. + * Algorithm: Start Tx and Rx DMA for specific channel. * - * Dependencies: - * 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 + * @param[in] addr: Base address indicating the start of + * memory mapped IO region of the MAC. + * @param[in] chan: DMA Tx/Rx channel number. * - * Protection: None. - * - * Return: None. + * @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 eqos_start_dma(void *addr, unsigned int chan) { @@ -504,19 +452,16 @@ static void eqos_start_dma(void *addr, unsigned int chan) } /** - * eqos_stop_dma - Stop DMA. - * @addr: MAC base address. - * @chan: DMA Tx/Rx channel number. + * @brief eqos_stop_dma - Stop DMA. * - * Algorithm: Start Tx and Rx DMA for specific channel. + * Algorithm: Start Tx and Rx DMA for specific channel. * - * Dependencies: - * 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 + * @param[in] addr: Base address indicating the start of + * memory mapped IO region of the MAC. + * @param[in] chan: DMA Tx/Rx channel number. * - * Protection: None. - * - * Return: None. + * @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 eqos_stop_dma(void *addr, unsigned int chan) { @@ -538,11 +483,9 @@ static void eqos_stop_dma(void *addr, unsigned int chan) } /** - * eqos_configure_dma_channel - Configure DMA channel - * @chan: DMA channel number that need to be configured. - * @osi_dma: OSI DMA private data structure. + * @brief eqos_configure_dma_channel - Configure DMA channel * - * Algorithm: This takes care of configuring the below + * Algorithm: This takes care of configuring the below * parameters for the DMA channel * 1) Enabling DMA channel interrupts * 2) Enable 8xPBL mode @@ -550,11 +493,10 @@ static void eqos_stop_dma(void *addr, unsigned int chan) * 4) Enable TSO if HW supports * 5) Program Rx Watchdog timer * - * Dependencies: MAC has to be out of reset. + * @param[in] chan: DMA channel number that need to be configured. + * @param[in] osi_dma: OSI DMA private data structure. * - * Protection: None - * - * Return: NONE + * @note MAC has to be out of reset. */ static void eqos_configure_dma_channel(unsigned int chan, struct osi_dma_priv_data *osi_dma) @@ -639,16 +581,9 @@ static void eqos_configure_dma_channel(unsigned int chan, } /** - * eqos_init_dma_channel - DMA channel INIT - * @osi_dma: OSI DMA private data structure. + * @brief eqos_init_dma_channel - DMA channel INIT * - * Description: Initialise all DMA channels. - * - * Dependencies: None. - * - * Protection: None. - * - * Return: None. + * @param[in] osi_dma: OSI DMA private data structure. */ static void eqos_init_dma_channel(struct osi_dma_priv_data *osi_dma) { @@ -663,20 +598,14 @@ static void eqos_init_dma_channel(struct osi_dma_priv_data *osi_dma) } /** - * eqos_set_rx_buf_len - Set Rx buffer length - * @osi_dma: OSI DMA private data structure. + * @brief eqos_set_rx_buf_len - Set Rx buffer length + * Sets the Rx buffer length based on the new MTU size set. * - * Description: Sets the Rx buffer lenght based on the new MTU size set. + * @param[in] osi_dma: OSI DMA private data structure. * - * Dependencies: - * 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 - * - * - * Protection: None. - * - * Return: None. + * @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 eqos_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) { @@ -699,6 +628,10 @@ static void eqos_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) ~(EQOS_AXI_BUS_WIDTH - 1U)); } +/** + * @brief eqos_dma_chan_ops - EQOS DMA operations + * + */ static struct osi_dma_chan_ops eqos_dma_chan_ops = { .set_tx_ring_len = eqos_set_tx_ring_len, .set_rx_ring_len = eqos_set_rx_ring_len, @@ -719,11 +652,17 @@ static struct osi_dma_chan_ops eqos_dma_chan_ops = { .validate_regs = eqos_validate_dma_regs, }; +/** + * @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_get_dma_chan_ops - EQOS get DMA channel operations + */ struct osi_dma_chan_ops *eqos_get_dma_chan_ops(void) { return &eqos_dma_chan_ops; diff --git a/osi/dma/eqos_dma.h b/osi/dma/eqos_dma.h index 405a2bd..571faf3 100644 --- a/osi/dma/eqos_dma.h +++ b/osi/dma/eqos_dma.h @@ -23,9 +23,12 @@ #ifndef EQOS_DMA_H_ #define EQOS_DMA_H_ -#define EQOS_AXI_BUS_WIDTH 0x10U - -/* EQOS DMA channel registers */ +/** + * @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) @@ -42,6 +45,14 @@ #define EQOS_DMA_CHX_TDRL(x) ((0x0080U * (x)) + 0x112CU) #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) @@ -110,21 +121,23 @@ #define EQOS_DMA_CH2_INTR_ENA_IDX 22U #define EQOS_DMA_CH3_INTR_ENA_IDX 23U #define EQOS_MAX_DMA_SAFETY_REGS 24U +#define EQOS_AXI_BUS_WIDTH 0x10U +/** @} */ /** - * struct dma_func_safety - Struct used to store last written values of + * @brief dma_func_safety - Struct used to store last written values of * critical DMA HW registers. - * @reg_addr: Array of reg MMIO addresses (base of EQoS + offset of reg) - * @reg_mask: Array of bit-mask value of each corresponding reg (used to - * ignore self-clearing/reserved bits in reg). - * @reg_val: Array of value stored in each corresponding register. - * @dma_safety_lock: OSI lock variable used to protect writes to reg while - * validation is in-progress. */ 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) */ unsigned int reg_mask[EQOS_MAX_DMA_SAFETY_REGS]; + /** Array of value stored in each corresponding register */ unsigned int reg_val[EQOS_MAX_DMA_SAFETY_REGS]; + /** OSI lock variable used to protect writes to reg + * while validation is in-progress */ unsigned int dma_safety_lock; }; #endif diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 2ac3192..ec8f323 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -69,20 +69,6 @@ int osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) return ret; } -/** - * osi_hw_deinit - De-init the HW - * @osi: OSI private data structure. - * - * Algorithm: - * 1) Stop the DMA - * 2) free all allocated resources. - * - * Dependencies: None - * - * Protection: None - * - * Return: 0 - Success, -ve - failure - */ int osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma) { unsigned int i; diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 16ac2b7..6e938f7 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -27,11 +27,9 @@ int dma_desc_init(struct osi_dma_priv_data *osi_dma); /** - * get_rx_csum - Get the Rx checksum from descriptor if valid - * @rx_desc: Rx descriptor - * @rx_pkt_cx: Per-Rx packet context structure + * @brief get_rx_csum - Get the Rx checksum from descriptor if valid * - * Algorithm: + * 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 @@ -39,11 +37,8 @@ int dma_desc_init(struct osi_dma_priv_data *osi_dma); * IP/TCP/UDP checksum validation in software based on whether * COE is enabled for the device. * - * Dependencies: None - * - * Protection: None - * - * Return: None. + * @param[in] rx_desc: Rx descriptor + * @param[in] rx_pkt_cx: Per-Rx packet context structure */ static inline void get_rx_csum(struct osi_rx_desc *rx_desc, struct osi_rx_pkt_cx *rx_pkt_cx) @@ -61,6 +56,18 @@ static inline void get_rx_csum(struct osi_rx_desc *rx_desc, } } +/** + * @brief get_rx_vlan_from_desc - 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 get_rx_vlan_from_desc(struct osi_rx_desc *rx_desc, struct osi_rx_pkt_cx *rx_pkt_cx) { @@ -78,18 +85,16 @@ static inline void get_rx_vlan_from_desc(struct osi_rx_desc *rx_desc, } /** - * get_rx_tstamp_status - Get Tx Time stamp status - * @context_desc: Rx context descriptor + * @brief get_rx_tstamp_status - Get Tx Time stamp status * - * Algorithm: + * Algorithm: * 1) Check if the received descriptor is a context descriptor. * 2) If yes, check whether the time stamp is valid or not. * - * Dependencies: None + * @param[in] context_desc: Rx context descriptor * - * Protection: None - * - * Return: -1 if TS is not valid and 0 if TS is valid. + * @retval -1 if TimeStamp is not valid + * @retval 0 if TimeStamp is valid. */ static inline int get_rx_tstamp_status(struct osi_rx_desc *context_desc) { @@ -108,22 +113,20 @@ static inline int get_rx_tstamp_status(struct osi_rx_desc *context_desc) } /** - * get_rx_hwstamp - Get Rx HW Time stamp - * @rx_desc: Rx descriptor - * @context_desc: Rx context descriptor - * @rx_pkt_cx: Rx packet context + * @brief get_rx_hwstamp - Get Rx HW Time stamp * - * Algorithm: + * 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. * - * Dependencies: None + * @param[in] rx_desc: Rx descriptor + * @param[in] context_desc: Rx context descriptor + * @param[in] rx_pkt_cx: Rx packet context * - * Protection: None - * - * Return: -1 if TS is not available and 0 if TS is available. + * @retval -1 if TimeStamp is not available + * @retval 0 if TimeStamp is available. */ static int get_rx_hwstamp(struct osi_rx_desc *rx_desc, struct osi_rx_desc *context_desc, @@ -164,19 +167,14 @@ static int get_rx_hwstamp(struct osi_rx_desc *rx_desc, /** - * get_rx_err_stats - Detect Errors from Rx Descriptor - * @rx_desc: Rx Descriptor. - * @pkt_err_stats: Packet error stats which stores the errors reported + * @brief get_rx_err_stats - Detect Errors from Rx Descriptor * - * Algorimthm: This routine will be invoked by OSI layer itself which + * Algorithm: This routine will be invoked by OSI layer itself which * checks for the Last Descriptor and updates the receive status errors * accordingly. * - * Dependencies: None. - * - * Protection: None. - * - * Return: None. + * @param[in] rx_desc: Rx Descriptor. + * @param[in] 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) @@ -189,29 +187,6 @@ static inline void get_rx_err_stats(struct osi_rx_desc *rx_desc, } } -/** - * osi_process_rx_completions - Read data from receive channel descriptors - * @osi: OSI private data structure. - * @chan: Rx DMA channel number - * @budget: Threshould for reading the packets at a time. - * - * Algorimthm: This routine will be invoked by OSD layer to get the - * data from Rx descriptors and deliver the packet to the stack. - * 1) Checks descriptor owned by DMA or not. - * 2) Get the length from Rx descriptor - * 3) Invokes OSD layer to deliver the packet to network stack. - * 4) Re-allocate the receive buffers, populate Rx descriptor and - * handover to DMA. - * - * Dependencies: - * 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) DMA need to be started, see osi_start_dma - * - * Protection: None. - * - * Return: None. - */ int osi_process_rx_completions(struct osi_dma_priv_data *osi, unsigned int chan, int budget) { @@ -278,19 +253,14 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, } /** - * get_tx_err_stats - Detect Errors from Tx Status - * @tx_desc: Tx Descriptor. - * @pkt_err_stats: Pakcet error stats which stores the errors reported + * @brief get_tx_err_stats - Detect Errors from Tx Status * - * Algorimthm: This routine will be invoked by OSI layer itself which + * Algorithm: This routine will be invoked by OSI layer itself which * checks for the Last Descriptor and updates the transmit status errors * accordingly. * - * Dependencies: None. - * - * Protection: None. - * - * Return: None. + * @param[in] tx_desc: Tx Descriptor. + * @param[in] pkt_err_stats: Pakcet 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) @@ -370,21 +340,6 @@ static inline void get_tx_err_stats(struct osi_tx_desc *tx_desc, } } -/** - * osi_clear_tx_pkt_err_stats - Clear tx packet error stats. - * @osi: OSI dma private data structure. - * - * Algorithm: This function will be invoked by OSD layer to clear the - * tx packet error stats - * - * Dependencies: - * 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 - * - * Protection: None - * - * Return: 0 - success, -1 - failure. - */ int osi_clear_tx_pkt_err_stats(struct osi_dma_priv_data *osi_dma) { int ret = -1; @@ -407,21 +362,6 @@ int osi_clear_tx_pkt_err_stats(struct osi_dma_priv_data *osi_dma) return ret; } -/** - * osi_clear_rx_pkt_err_stats - Clear rx packet error stats. - * @osi: OSI dma private data structure. - * - * Algorithm: This function will be invoked by OSD layer to clear the - * rx packet error stats - * - * Dependencies: - * 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 - * - * Protection: None - * - * Return: 0 - success, -1 - failure. - */ int osi_clear_rx_pkt_err_stats(struct osi_dma_priv_data *osi_dma) { int ret = -1; @@ -435,27 +375,6 @@ int osi_clear_rx_pkt_err_stats(struct osi_dma_priv_data *osi_dma) return ret; } -/** - * osi_process_tx_completions - Process Tx complete on DMA channel ring. - * @osi: OSI private data structure. - * @chan: Channel number on which Tx complete need to be done. - * - * Algorithm: This function will be invoked by OSD layer to process Tx - * complete interrupt. - * 1) First checks whether descriptor owned by DMA or not. - * 2) Invokes OSD layer to release DMA address and Tx buffer which are - * updated as part of transmit routine. - * - * Dependencies: - * 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) DMA need to be started, see osi_start_dma - * - * - * Protection: None - * - * Return: Number of decriptors (buffers) proccessed. - */ int osi_process_tx_completions(struct osi_dma_priv_data *osi, unsigned int chan) { @@ -544,20 +463,18 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi, } /** - * need_cntx_desc - Helper function to check if context desc is needed. - * @tx_pkt_cx: Pointer to transmit packet context structure - * @tx_desc: Pointer to tranmit descriptor to be filled. + * @brief need_cntx_desc - Helper function to check if context desc is needed. * - * Algorithm: + * Algorithm: * 1) Check if transmit packet context flags are set * 2) If set, set the context descriptor bit along * with other context information in the transmit descriptor. * - * Dependencies: None. + * @param[in] tx_pkt_cx: Pointer to transmit packet context structure + * @param[in] tx_desc: Pointer to tranmit descriptor to be filled. * - * Protection: None - * - * Return: 0 - cntx desc not used, 1 - cntx desc used. + * @retval 0 - cntx desc not used + * @retval 1 - cntx desc used. */ static inline int need_cntx_desc(struct osi_tx_pkt_cx *tx_pkt_cx, struct osi_tx_desc *tx_desc) @@ -594,22 +511,18 @@ static inline int need_cntx_desc(struct osi_tx_pkt_cx *tx_pkt_cx, } /** - * fill_first_desc - Helper function to fill the first transmit descriptor. - * @tx_pkt_cx: Pointer to transmit packet context structure - * @tx_desc: Pointer to tranmit descriptor to be filled. - * @tx_swcx: Pointer to corresponding tranmit descriptor software context. + * @brief fill_first_desc - Helper function to fill the first transmit + * descriptor. * - * Algorithm: - * 1) Update the buffer address and length of buffer in first desc. - * 2) Check if any features like HW checksum offload, TSO, VLAN insertion - * etc. are flagged in transmit packet context. If so, set the fiels in - * first desc corresponding to those features. + * Algorithm: + * 1) Update the buffer address and length of buffer in first desc. + * 2) Check if any features like HW checksum offload, TSO, VLAN insertion + * etc. are flagged in transmit packet context. If so, set the fiels in + * first desc corresponding to those features. * - * Dependencies: None. - * - * Protection: None - * - * Return: None. + * @param[in] tx_pkt_cx: Pointer to transmit packet context structure + * @param[in] tx_desc: Pointer to tranmit descriptor to be filled. + * @param[in] tx_swcx: Pointer to corresponding tx descriptor software context. */ static inline void fill_first_desc(struct osi_tx_pkt_cx *tx_pkt_cx, struct osi_tx_desc *tx_desc, @@ -658,35 +571,6 @@ static inline void fill_first_desc(struct osi_tx_pkt_cx *tx_pkt_cx, } } -/** - * osi_hw_transmit - Initialize Tx DMA descriptors for a channel - * @osi: OSI private data structure. - * @chan: DMA Tx channel number - * - * Algorithm: Initialize Transmit descriptors with DMA mappabled buffers, - * set OWN bit, Tx ring length and set starting address of Tx DMA channel. - * Tx ring base address in Tx DMA registers. - * - * Dependencies: - * 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) DMA channel need to be started, see osi_start_dma - * 4) Need to set update tx_pkt_cx->flags accordingly as per the - * requirements - * #define OSI_PKT_CX_VLAN OSI_BIT(0) - * #define OSI_PKT_CX_CSUM OSI_BIT(1) - * #define OSI_PKT_CX_TSO OSI_BIT(2) - * #define OSI_PKT_CX_PTP OSI_BIT(3) - * 5) tx_pkt_cx->desc_cnt need to be populated which holds the number - * of swcx descriptors allocated for that packet - * 6) 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 - * - * Protection: None. - * - * Return: None. - */ void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan) { struct osi_tx_ring *tx_ring = osi->tx_ring[chan]; @@ -773,19 +657,17 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan) } /** - * rx_dma_desc_initialization - Initialize DMA Receive descriptors for Rx. - * @osi: OSI private data structure. - * @chan: Rx channel number. + * @brief rx_dma_desc_initialization - Initialize DMA Receive descriptors for Rx * - * Algorithm: Initialize Receive descriptors with DMA mappable buffers, + * 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. * - * Dependencies: None. + * @param[in] osi: OSI private data structure. + * @param[in] chan: Rx channel number. * - * Protection: None. - * - * Return: 0 - success, -1 - failure. + * @retval 0 on success + * @retval -1 on failure. */ static int rx_dma_desc_initialization(struct osi_dma_priv_data *osi, unsigned int chan) @@ -826,18 +708,16 @@ static int rx_dma_desc_initialization(struct osi_dma_priv_data *osi, } /** - * rx_dma_desc_init - Initialize DMA Receive descriptors for Rx channel. - * @osi: OSI private data structure. + * @brief rx_dma_desc_init - Initialize DMA Receive descriptors for Rx channel. * - * Algorithm: Initialize Receive descriptors with DMA mappabled buffers, + * Algorithm: Initialize Receive descriptors with DMA mappabled buffers, * set OWN bit, Rx ring length and set starting address of Rx DMA channel. * Tx ring base address in Tx DMA registers. * - * Dependencies: None. + * @param[in] osi: OSI private data structure. * - * Protection: None. - * - * Return: 0 - success, -1 - failure. + * @retval 0 on success + * @retval -1 on failure. */ static int rx_dma_desc_init(struct osi_dma_priv_data *osi) { @@ -858,17 +738,12 @@ static int rx_dma_desc_init(struct osi_dma_priv_data *osi) } /** - * tx_dma_desc_init - Initialize DMA Transmit descriptors. - * @osi: OSI private data structure. + * @brief tx_dma_desc_init - Initialize DMA Transmit descriptors. * - * Algorithm: Initialize Trannsmit descriptors and set Tx ring length, + * Algorithm: Initialize Trannsmit descriptors and set Tx ring length, * Tx ring base address in Tx DMA registers. * - * Dependencies: None. - * - * Protection: None. - * - * Return: None. + * @param[in] osi_dma: OSI DMA private data structure. */ static void tx_dma_desc_init(struct osi_dma_priv_data *osi_dma) { @@ -901,17 +776,15 @@ static void tx_dma_desc_init(struct osi_dma_priv_data *osi_dma) } /** - * dma_desc_init - Initialize DMA Tx/Rx descriptors - * @osi: OSI private data structure. + * @brief dma_desc_init - Initialize DMA Tx/Rx descriptors * - * Algorithm: Transmit and Receive desctiptors will be initialized with + * Algorithm: Transmit and Receive desctiptors will be initialized with * required values so that MAC DMA can understand and act accordingly. * - * Dependencies: None. + * @param[in] osi_dma: OSI DMA private data structure. * - * Protection: None. - * - * Return: 0 - success, -1 - failure. + * @retval 0 on success + * @retval -1 on failure. */ int dma_desc_init(struct osi_dma_priv_data *osi_dma) { From 719e73b2ef51fe82eaa0349878e567a6af6f3151 Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Fri, 16 Aug 2019 15:49:23 +0530 Subject: [PATCH 039/458] nvethernetrm: Fix MISRA issues Issues: Observed below MISRA defects: MISRA C-2012 Rule 17.4: 4 MISRA C-2012 Rule 8.5: 1 Fix Info: - Handled the return values to clear MISRA 17.7 issues - Properly defined dma_desc_init function declaration to fix 8.5 MISRA issue Bug 200512422 Change-Id: I6f5c5f2ad989d9c180d067018bc50ed325012375 Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2176714 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_dma.h | 3 --- osi/dma/eqos_dma.c | 2 +- osi/dma/eqos_dma.h | 18 +++++++++++++++++ osi/dma/osi_dma.c | 29 +++++++++++++++++++-------- osi/dma/osi_dma_local.h | 44 +++++++++++++++++++++++++++++++++++++++++ osi/dma/osi_dma_txrx.c | 19 +++--------------- 6 files changed, 87 insertions(+), 28 deletions(-) create mode 100644 osi/dma/osi_dma_local.h diff --git a/include/osi_dma.h b/include/osi_dma.h index 7b1fc68..da30edc 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -756,7 +756,4 @@ int osi_clear_tx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); */ int osi_clear_rx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); -/* Function prototype needed for misra */ -struct osi_dma_chan_ops *eqos_get_dma_chan_ops(void); -void *eqos_get_dma_safety_config(void); #endif /* OSI_DMA_H */ diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index e7e501b..9dc0885 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -21,7 +21,7 @@ */ #include <osi_common.h> -#include <osi_dma.h> +#include "osi_dma_local.h" #include "eqos_dma.h" /** diff --git a/osi/dma/eqos_dma.h b/osi/dma/eqos_dma.h index 571faf3..5d5f0d8 100644 --- a/osi/dma/eqos_dma.h +++ b/osi/dma/eqos_dma.h @@ -140,4 +140,22 @@ struct dma_func_safety { * while validation is in-progress */ unsigned int dma_safety_lock; }; + +/** + * @brief eqos_get_dma_safety_config - EQOS get DMA safety configuration + * + * Algorithm: Returns pointer DMA safety configuration. + * + * @returns Pointer to DMA safety configuration + */ +void *eqos_get_dma_safety_config(void); + +/** + * @brief eqos_get_dma_chan_ops - EQOS get DMA channel operations + * + * Algorithm: Returns pointer DMA channel operations structure. + * + * @returns Pointer to DMA channel operations structure + */ +struct osi_dma_chan_ops *eqos_get_dma_chan_ops(void); #endif diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index ec8f323..3de5db0 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -20,9 +20,7 @@ * DEALINGS IN THE SOFTWARE. */ -#include <osi_dma.h> - -extern int dma_desc_init(struct osi_dma_priv_data *osi_dma); +#include "osi_dma_local.h" int osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) { @@ -61,9 +59,20 @@ int osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) for (i = 0; i < osi_dma->num_dma_chans; i++) { chan = osi_dma->dma_chans[i]; - osi_enable_chan_tx_intr(osi_dma, chan); - osi_enable_chan_rx_intr(osi_dma, chan); - osi_start_dma(osi_dma, chan); + ret = osi_enable_chan_tx_intr(osi_dma, chan); + if (ret != 0) { + return ret; + } + + ret = osi_enable_chan_rx_intr(osi_dma, chan); + if (ret != 0) { + return ret; + } + + ret = osi_start_dma(osi_dma, chan); + if (ret != 0) { + return ret; + } } return ret; @@ -72,16 +81,20 @@ int osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) int osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma) { unsigned int i; + int ret = 0; if (osi_dma == OSI_NULL) { return -1; } for (i = 0; i < osi_dma->num_dma_chans; i++) { - osi_stop_dma(osi_dma, osi_dma->dma_chans[i]); + ret = osi_stop_dma(osi_dma, osi_dma->dma_chans[i]); + if (ret != 0) { + return ret; + } } - return 0; + return ret; } int osi_disable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, diff --git a/osi/dma/osi_dma_local.h b/osi/dma/osi_dma_local.h new file mode 100644 index 0000000..5c43e1a --- /dev/null +++ b/osi/dma/osi_dma_local.h @@ -0,0 +1,44 @@ +/* + * 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. + */ + + +#ifndef OSI_DMA_LOCAL_H +#define OSI_DMA_LOCAL_H + +#include <osi_dma.h> +#include "eqos_dma.h" + +/* Function prototype needed for misra */ + +/** + * @brief dma_desc_init - Initialize DMA Tx/Rx descriptors + * + * Algorithm: Transmit and Receive desctiptors will be initialized with + * required values so that MAC DMA can understand and act accordingly. + * + * @param[in] osi_dma: OSI DMA private data structure. + * + * @retval 0 on success + * @retval -1 on failure. + */ +int dma_desc_init(struct osi_dma_priv_data *osi_dma); +#endif /* OSI_DMA_LOCAL_H */ diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 6e938f7..db068c2 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -21,11 +21,9 @@ */ #include <osd.h> -#include <osi_dma.h> +#include "osi_dma_local.h" #include <osi_dma_txrx.h> -int dma_desc_init(struct osi_dma_priv_data *osi_dma); - /** * @brief get_rx_csum - Get the Rx checksum from descriptor if valid * @@ -57,11 +55,11 @@ static inline void get_rx_csum(struct osi_rx_desc *rx_desc, } /** - * @brief get_rx_vlan_from_desc - Get Rx VLAN from descriptor + * @brief get_rx_vlan_from_desc - 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 + * 2) If set, set a per packet context flag indicating packet is VLAN * tagged. * 3) Extract VLAN tag ID from the descriptor * @@ -775,17 +773,6 @@ static void tx_dma_desc_init(struct osi_dma_priv_data *osi_dma) } } -/** - * @brief dma_desc_init - Initialize DMA Tx/Rx descriptors - * - * Algorithm: Transmit and Receive desctiptors will be initialized with - * required values so that MAC DMA can understand and act accordingly. - * - * @param[in] osi_dma: OSI DMA private data structure. - * - * @retval 0 on success - * @retval -1 on failure. - */ int dma_desc_init(struct osi_dma_priv_data *osi_dma) { int ret = 0; From a25d7132858bf202c83ea141702a2b5cb2501a09 Mon Sep 17 00:00:00 2001 From: Mohit Dhingra <mdhingra@nvidia.com> Date: Wed, 4 Sep 2019 16:41:48 +0530 Subject: [PATCH 040/458] nvethernetrm: export register readback apis ESQC-10925 Change-Id: I35e582eb22d732765f621c811eff4a7b9bb1acaf Signed-off-by: Mohit Dhingra <mdhingra@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2189883 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Narayan Reddy <narayanr@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/libnvethernetrm.export | 1 + osi/dma/libnvethernetcl.export | 1 + 2 files changed, 2 insertions(+) diff --git a/osi/core/libnvethernetrm.export b/osi/core/libnvethernetrm.export index 39faedd..ebf9ce7 100644 --- a/osi/core/libnvethernetrm.export +++ b/osi/core/libnvethernetrm.export @@ -66,3 +66,4 @@ osi_adjust_freq osi_set_systime_to_mac osi_read_mmc osi_reset_mmc +osi_validate_core_regs diff --git a/osi/dma/libnvethernetcl.export b/osi/dma/libnvethernetcl.export index d9bbb0c..342397e 100644 --- a/osi/dma/libnvethernetcl.export +++ b/osi/dma/libnvethernetcl.export @@ -41,3 +41,4 @@ osi_process_rx_completions osi_hw_dma_init osi_hw_dma_deinit osi_init_dma_ops +osi_validate_dma_regs From b9db974817aaaa48d5bc93753e8f8d42d0ee1a77 Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Fri, 23 Aug 2019 10:09:36 +0530 Subject: [PATCH 041/458] Fix CERT-C errors INT30-C, INT31-C, INT32-C Issue: Observed 177 CERT issue: CERT INT30-C 158 CERT INT31-C 17 CERT INT32-C 1 CERT INT33-C 1 Fix: Fix existing defects for above cert-C errors as per recommended practices. Bug 200546468 Bug 200512422 Change-Id: I54d6ee35566da1985f2aea83d8c4b10f71309fed Signed-off-by: Srinivas Ramachandran <srinivasra@nvidia.com> Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2123080 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_common.h | 17 +++++- osi/common/osi_common.c | 10 +--- osi/core/eqos_core.c | 49 ++++++++++----- osi/core/osi_core.c | 2 +- osi/dma/eqos_dma.c | 129 ++++++++++++++++++++++++++++++++-------- osi/dma/osi_dma.c | 12 ++++ osi/dma/osi_dma_txrx.c | 85 +++++++++++++++++++++----- 7 files changed, 238 insertions(+), 66 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index b926b4b..fd149b0 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -36,7 +36,7 @@ #define OSI_INVALID_VALUE 0xFFFFFFFFU /* System clock is 62.5MHz */ -#define OSI_ETHER_SYSCLOCK 62500000ULL +#define OSI_ETHER_SYSCLOCK 62500000U #define OSI_ONE_MEGA_HZ 1000000U #define OSI_MAX_RX_COALESCE_USEC 1020U #define OSI_MIN_RX_COALESCE_USEC 3U @@ -57,6 +57,9 @@ #ifndef UINT_MAX #define UINT_MAX (~0U) #endif +#ifndef INT_MAX +#define INT_MAX (0x7FFFFFFF) +#endif /* MAC Time stamp contorl reg bit fields */ #define OSI_MAC_TCR_TSENA OSI_BIT(0) @@ -74,7 +77,8 @@ #define OSI_MAC_TCR_SNAPTYPSEL_3 (OSI_BIT(16) | OSI_BIT(17)) #define OSI_MAC_TCR_AV8021ASMEN OSI_BIT(28) -#define OSI_UCHAR_MAX 0xFFU +#define OSI_ULLONG_MAX (~0ULL) +#define OSI_UCHAR_MAX (0xFFU) /* Default maximum Gaint Packet Size Limit */ #define OSI_MAX_MTU_SIZE 9000U @@ -122,6 +126,13 @@ #define OSI_IP4_FILTER 0U #define OSI_IP6_FILTER 1U +#define CHECK_CHAN_BOUND(chan) \ + { \ + if ((chan) >= OSI_EQOS_MAX_NUM_CHANS) { \ + return; \ + } \ + } \ + #define OSI_BIT(nr) ((unsigned int)1 << (nr)) #define OSI_EQOS_MAC_4_10 0x41U @@ -142,7 +153,7 @@ #define MAX_ETH_FRAME_LEN_DEFAULT \ (NV_ETH_FRAME_LEN + NV_ETH_FCS_LEN + NV_VLAN_HLEN) -#define L32(data) ((data) & 0xFFFFFFFFUL) +#define L32(data) ((data) & 0xFFFFFFFFU) #define H32(data) (((data) & 0xFFFFFFFF00000000UL) >> 32UL) #define OSI_INVALID_CHAN_NUM 0xFFU diff --git a/osi/common/osi_common.c b/osi/common/osi_common.c index d371f04..8d50f93 100644 --- a/osi/common/osi_common.c +++ b/osi/common/osi_common.c @@ -126,17 +126,11 @@ int osi_get_mac_version(void *addr, unsigned int *mac_ver) void osi_memset(void *s, unsigned int c, unsigned long count) { unsigned char *xs = s; - int brk = 1; - while (brk != 0) { + while (count != 0UL) { if (c < OSI_UCHAR_MAX) { *xs++ = (unsigned char)c; } - if (count > 0U) { - count--; - } - if (count == 0U) { - brk = 0; - } + count--; } } diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 3782332..7a4b2c9 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -109,6 +109,10 @@ static void eqos_core_safety_init(struct osi_core_priv_data *osi_core) 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 + @@ -142,6 +146,10 @@ static void eqos_core_safety_init(struct osi_core_priv_data *osi_core) 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] = @@ -541,21 +549,21 @@ static int eqos_poll_for_swr(void *addr) static void eqos_set_mdc_clk_rate(struct osi_core_priv_data *osi_core, unsigned long csr_clk_rate) { - unsigned int csr_clk_speed = (unsigned int)(csr_clk_rate / 1000000U); + unsigned long csr_clk_speed = csr_clk_rate / 1000000UL; - if (csr_clk_speed > 500U) { + if (csr_clk_speed > 500UL) { osi_core->mdc_cr = EQOS_CSR_500_800M; - } else if (csr_clk_speed > 300U) { + } else if (csr_clk_speed > 300UL) { osi_core->mdc_cr = EQOS_CSR_300_500M; - } else if (csr_clk_speed > 250U) { + } else if (csr_clk_speed > 250UL) { osi_core->mdc_cr = EQOS_CSR_250_300M; - } else if (csr_clk_speed > 150U) { + } else if (csr_clk_speed > 150UL) { osi_core->mdc_cr = EQOS_CSR_150_250M; - } else if (csr_clk_speed > 100U) { + } else if (csr_clk_speed > 100UL) { osi_core->mdc_cr = EQOS_CSR_100_150M; - } else if (csr_clk_speed > 60U) { + } else if (csr_clk_speed > 60UL) { osi_core->mdc_cr = EQOS_CSR_60_100M; - } else if (csr_clk_speed > 35U) { + } else if (csr_clk_speed > 35UL) { osi_core->mdc_cr = EQOS_CSR_35_60M; } else { /* for CSR < 35mhz */ @@ -649,6 +657,10 @@ static unsigned int eqos_calculate_per_queue_fifo(unsigned int fifo_size, unsigned int q_fifo_size = 0; /* calculated fifo size per queue */ unsigned int 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: @@ -820,6 +832,10 @@ static int eqos_flush_mtl_tx_queue(void *addr, unsigned int qinx) unsigned int value; int cond = 1; + if (qinx >= OSI_EQOS_MAX_NUM_CHANS) { + return -1; + } + /* Read Tx Q Operating Mode Register and flush TxQ */ value = osi_readl((unsigned char *)addr + EQOS_MTL_CHX_TX_OP_MODE(qinx)); @@ -1499,6 +1515,9 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *osi_core) /* 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_readl((unsigned char *)base + @@ -3032,7 +3051,7 @@ static void eqos_config_tscr(void *addr, unsigned int ptp_filter) */ static void eqos_config_ssir(void *addr, unsigned int ptp_clock) { - unsigned int val; + unsigned long long val; unsigned int mac_tcr; mac_tcr = osi_readl((unsigned char *)addr + EQOS_MAC_TCR); @@ -3044,10 +3063,9 @@ static void eqos_config_ssir(void *addr, unsigned int ptp_clock) */ if ((mac_tcr & EQOS_MAC_TCR_TSCFUPDT) == EQOS_MAC_TCR_TSCFUPDT) { - val = ((1U * (unsigned int)OSI_NSEC_PER_SEC) / - (unsigned int)OSI_ETHER_SYSCLOCK); + val = ((1U * OSI_NSEC_PER_SEC) / OSI_ETHER_SYSCLOCK); } else { - val = ((1U * (unsigned int)OSI_NSEC_PER_SEC) / ptp_clock); + val = ((1U * OSI_NSEC_PER_SEC) / ptp_clock); } /* 0.465ns accurecy */ @@ -3059,8 +3077,11 @@ static void eqos_config_ssir(void *addr, unsigned int ptp_clock) val |= val << EQOS_MAC_SSIR_SSINC_SHIFT; /* update Sub-second Increment Value */ - eqos_core_safety_writel(val, (unsigned char *)addr + EQOS_MAC_SSIR, - EQOS_MAC_SSIR_IDX); + if (val < UINT_MAX) { + eqos_core_safety_writel((unsigned int)val, + (unsigned char *)addr + EQOS_MAC_SSIR, + EQOS_MAC_SSIR_IDX); + } } /** diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 165aece..86cf5b6 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -866,7 +866,7 @@ int osi_ptp_configuration(struct osi_core_priv_data *osi_core, * 2^x * y == (y << x), hence * 2^32 * 6250000 ==> (6250000 << 32) */ - temp = (unsigned long)(OSI_ETHER_SYSCLOCK << 32); + temp = ((unsigned long)OSI_ETHER_SYSCLOCK << 32); temp1 = div_u64(temp, (unsigned long)osi_core->ptp_config.ptp_ref_clk_rate); if (temp1 < UINT_MAX) { diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index 9dc0885..fdfc698 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -85,6 +85,7 @@ static void eqos_dma_safety_init(struct osi_dma_priv_data *osi_dma) for (i = 0U; i < osi_dma->num_dma_chans; i++) { idx = osi_dma->dma_chans[i]; + CHECK_CHAN_BOUND(idx); 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 + @@ -190,9 +191,13 @@ static void eqos_disable_chan_tx_intr(void *addr, unsigned int chan) { unsigned int cntrl; - cntrl = osi_readl((unsigned char *)addr + EQOS_VIRT_INTR_CHX_CNTRL(chan)); + CHECK_CHAN_BOUND(chan); + + cntrl = osi_readl((unsigned char *)addr + + EQOS_VIRT_INTR_CHX_CNTRL(chan)); cntrl &= ~EQOS_VIRT_INTR_CHX_CNTRL_TX; - osi_writel(cntrl, (unsigned char *)addr + EQOS_VIRT_INTR_CHX_CNTRL(chan)); + osi_writel(cntrl, (unsigned char *)addr + + EQOS_VIRT_INTR_CHX_CNTRL(chan)); } /** @@ -211,9 +216,13 @@ static void eqos_enable_chan_tx_intr(void *addr, unsigned int chan) { unsigned int cntrl; - cntrl = osi_readl((unsigned char *)addr + EQOS_VIRT_INTR_CHX_CNTRL(chan)); + CHECK_CHAN_BOUND(chan); + + cntrl = osi_readl((unsigned char *)addr + + EQOS_VIRT_INTR_CHX_CNTRL(chan)); cntrl |= EQOS_VIRT_INTR_CHX_CNTRL_TX; - osi_writel(cntrl, (unsigned char *)addr + EQOS_VIRT_INTR_CHX_CNTRL(chan)); + osi_writel(cntrl, (unsigned char *)addr + + EQOS_VIRT_INTR_CHX_CNTRL(chan)); } /** @@ -232,9 +241,13 @@ static void eqos_disable_chan_rx_intr(void *addr, unsigned int chan) { unsigned int cntrl; - cntrl = osi_readl((unsigned char *)addr + EQOS_VIRT_INTR_CHX_CNTRL(chan)); + CHECK_CHAN_BOUND(chan); + + cntrl = osi_readl((unsigned char *)addr + + EQOS_VIRT_INTR_CHX_CNTRL(chan)); cntrl &= ~EQOS_VIRT_INTR_CHX_CNTRL_RX; - osi_writel(cntrl, (unsigned char *)addr + EQOS_VIRT_INTR_CHX_CNTRL(chan)); + osi_writel(cntrl, (unsigned char *)addr + + EQOS_VIRT_INTR_CHX_CNTRL(chan)); } /** @@ -251,9 +264,13 @@ static void eqos_enable_chan_rx_intr(void *addr, unsigned int chan) { unsigned int cntrl; - cntrl = osi_readl((unsigned char *)addr + EQOS_VIRT_INTR_CHX_CNTRL(chan)); + CHECK_CHAN_BOUND(chan); + + cntrl = osi_readl((unsigned char *)addr + + EQOS_VIRT_INTR_CHX_CNTRL(chan)); cntrl |= EQOS_VIRT_INTR_CHX_CNTRL_RX; - osi_writel(cntrl, (unsigned char *)addr + EQOS_VIRT_INTR_CHX_CNTRL(chan)); + osi_writel(cntrl, (unsigned char *)addr + + EQOS_VIRT_INTR_CHX_CNTRL(chan)); } /** @@ -274,12 +291,16 @@ static void eqos_clear_tx_intr(void *addr, unsigned int chan) { unsigned int status; - status = osi_readl((unsigned char *)addr + EQOS_VIRT_INTR_CHX_STATUS(chan)); + CHECK_CHAN_BOUND(chan); + + status = osi_readl((unsigned char *)addr + + EQOS_VIRT_INTR_CHX_STATUS(chan)); if ((status & EQOS_VIRT_INTR_CHX_STATUS_TX) == 1U) { osi_writel(EQOS_DMA_CHX_STATUS_CLEAR_TX, (unsigned char *)addr + EQOS_DMA_CHX_STATUS(chan)); osi_writel(EQOS_VIRT_INTR_CHX_STATUS_TX, - (unsigned char *)addr + EQOS_VIRT_INTR_CHX_STATUS(chan)); + (unsigned char *)addr + + EQOS_VIRT_INTR_CHX_STATUS(chan)); } } @@ -301,12 +322,16 @@ static void eqos_clear_rx_intr(void *addr, unsigned int chan) { unsigned int status; - status = osi_readl((unsigned char *)addr + EQOS_VIRT_INTR_CHX_STATUS(chan)); + CHECK_CHAN_BOUND(chan); + + status = osi_readl((unsigned char *)addr + + EQOS_VIRT_INTR_CHX_STATUS(chan)); if ((status & EQOS_VIRT_INTR_CHX_STATUS_RX) == 2U) { osi_writel(EQOS_DMA_CHX_STATUS_CLEAR_RX, (unsigned char *)addr + EQOS_DMA_CHX_STATUS(chan)); osi_writel(EQOS_VIRT_INTR_CHX_STATUS_RX, - (unsigned char *)addr + EQOS_VIRT_INTR_CHX_STATUS(chan)); + (unsigned char *)addr + + EQOS_VIRT_INTR_CHX_STATUS(chan)); } } @@ -323,6 +348,7 @@ static void eqos_clear_rx_intr(void *addr, unsigned int chan) static void eqos_set_tx_ring_len(void *addr, unsigned int chan, unsigned int len) { + CHECK_CHAN_BOUND(chan); eqos_dma_safety_writel(len, (unsigned char *)addr + EQOS_DMA_CHX_TDRL(chan), EQOS_DMA_CH0_TDRL_IDX + chan); @@ -341,8 +367,21 @@ static void eqos_set_tx_ring_len(void *addr, unsigned int chan, static void eqos_set_tx_ring_start_addr(void *addr, unsigned int chan, unsigned long tx_desc) { - osi_writel((unsigned int)H32(tx_desc), (unsigned char *)addr + EQOS_DMA_CHX_TDLH(chan)); - osi_writel((unsigned int)L32(tx_desc), (unsigned char *)addr + EQOS_DMA_CHX_TDLA(chan)); + unsigned long tmp; + + CHECK_CHAN_BOUND(chan); + + tmp = H32(tx_desc); + if (tmp < UINT_MAX) { + osi_writel((unsigned int)tmp, (unsigned char *)addr + + EQOS_DMA_CHX_TDLH(chan)); + } + + tmp = L32(tx_desc); + if (tmp < UINT_MAX) { + osi_writel((unsigned int)tmp, (unsigned char *)addr + + EQOS_DMA_CHX_TDLA(chan)); + } } /** @@ -362,7 +401,15 @@ static void eqos_set_tx_ring_start_addr(void *addr, unsigned int chan, static void eqos_update_tx_tailptr(void *addr, unsigned int chan, unsigned long tailptr) { - osi_writel((unsigned int)L32(tailptr), (unsigned char *)addr + EQOS_DMA_CHX_TDTP(chan)); + unsigned long tmp; + + CHECK_CHAN_BOUND(chan); + + tmp = L32(tailptr); + if (tmp < UINT_MAX) { + osi_writel((unsigned int)tmp, (unsigned char *)addr + + EQOS_DMA_CHX_TDTP(chan)); + } } /** @@ -378,6 +425,7 @@ static void eqos_update_tx_tailptr(void *addr, unsigned int chan, static void eqos_set_rx_ring_len(void *addr, unsigned int chan, unsigned int len) { + CHECK_CHAN_BOUND(chan); eqos_dma_safety_writel(len, (unsigned char *)addr + EQOS_DMA_CHX_RDRL(chan), EQOS_DMA_CH0_RDRL_IDX + chan); @@ -396,8 +444,21 @@ static void eqos_set_rx_ring_len(void *addr, unsigned int chan, static void eqos_set_rx_ring_start_addr(void *addr, unsigned int chan, unsigned long tx_desc) { - osi_writel((unsigned int)H32(tx_desc), (unsigned char *)addr + EQOS_DMA_CHX_RDLH(chan)); - osi_writel((unsigned int)L32(tx_desc), (unsigned char *)addr + EQOS_DMA_CHX_RDLA(chan)); + unsigned long tmp; + + CHECK_CHAN_BOUND(chan); + + tmp = H32(tx_desc); + if (tmp < UINT_MAX) { + osi_writel((unsigned int)tmp, (unsigned char *)addr + + EQOS_DMA_CHX_RDLH(chan)); + } + + tmp = L32(tx_desc); + if (tmp < UINT_MAX) { + osi_writel((unsigned int)tmp, (unsigned char *)addr + + EQOS_DMA_CHX_RDLA(chan)); + } } /** @@ -416,8 +477,15 @@ static void eqos_set_rx_ring_start_addr(void *addr, unsigned int chan, static void eqos_update_rx_tailptr(void *addr, unsigned int chan, unsigned long tailptr) { - osi_writel((unsigned int)L32(tailptr), (unsigned char *)addr + - EQOS_DMA_CHX_RDTP(chan)); + unsigned long tmp; + + CHECK_CHAN_BOUND(chan); + + tmp = L32(tailptr); + if (tmp < UINT_MAX) { + osi_writel((unsigned int)tmp, (unsigned char *)addr + + EQOS_DMA_CHX_RDTP(chan)); + } } /** @@ -436,6 +504,8 @@ static void eqos_start_dma(void *addr, unsigned int chan) { unsigned int val; + CHECK_CHAN_BOUND(chan); + /* start Tx DMA */ val = osi_readl((unsigned char *)addr + EQOS_DMA_CHX_TX_CTRL(chan)); val |= OSI_BIT(0); @@ -467,6 +537,8 @@ static void eqos_stop_dma(void *addr, unsigned int chan) { unsigned int val; + CHECK_CHAN_BOUND(chan); + /* stop Tx DMA */ val = osi_readl((unsigned char *)addr + EQOS_DMA_CHX_TX_CTRL(chan)); val &= ~OSI_BIT(0); @@ -503,6 +575,8 @@ static void eqos_configure_dma_channel(unsigned int chan, { unsigned int value; + CHECK_CHAN_BOUND(chan); + /* enable DMA channel interrupts */ /* Enable TIE and TBUE */ /* TIE - Transmit Interrupt Enable */ @@ -512,7 +586,8 @@ static void eqos_configure_dma_channel(unsigned int chan, /* AIE - Abnormal Interrupt Summary Enable */ /* NIE - Normal Interrupt Summary Enable */ /* FBE - Fatal Bus Error Enable */ - value = osi_readl((unsigned char *)osi_dma->base + EQOS_DMA_CHX_INTR_ENA(chan)); + value = osi_readl((unsigned char *)osi_dma->base + + EQOS_DMA_CHX_INTR_ENA(chan)); value |= EQOS_DMA_CHX_INTR_TIE | EQOS_DMA_CHX_INTR_TBUE | EQOS_DMA_CHX_INTR_RIE | EQOS_DMA_CHX_INTR_RBUE | EQOS_DMA_CHX_INTR_FBEE | EQOS_DMA_CHX_INTR_AIE | @@ -525,14 +600,16 @@ static void eqos_configure_dma_channel(unsigned int chan, EQOS_DMA_CH0_INTR_ENA_IDX + chan); /* Enable 8xPBL mode */ - value = osi_readl((unsigned char *)osi_dma->base + EQOS_DMA_CHX_CTRL(chan)); + value = osi_readl((unsigned char *)osi_dma->base + + EQOS_DMA_CHX_CTRL(chan)); value |= EQOS_DMA_CHX_CTRL_PBLX8; eqos_dma_safety_writel(value, (unsigned char *)osi_dma->base + EQOS_DMA_CHX_CTRL(chan), EQOS_DMA_CH0_CTRL_IDX + chan); /* Configure DMA channel Transmit control register */ - value = osi_readl((unsigned char *)osi_dma->base + EQOS_DMA_CHX_TX_CTRL(chan)); + value = osi_readl((unsigned char *)osi_dma->base + + EQOS_DMA_CHX_TX_CTRL(chan)); /* Enable OSF mode */ value |= EQOS_DMA_CHX_TX_CTRL_OSF; /* TxPBL = 32*/ @@ -548,7 +625,8 @@ static void eqos_configure_dma_channel(unsigned int chan, /* Select Rx Buffer size. Needs to be rounded up to next multiple of * bus width */ - value = osi_readl((unsigned char *)osi_dma->base + EQOS_DMA_CHX_RX_CTRL(chan)); + value = osi_readl((unsigned char *)osi_dma->base + + EQOS_DMA_CHX_RX_CTRL(chan)); value |= (osi_dma->rx_buf_len << EQOS_DMA_CHX_RBSZ_SHIFT); /* RXPBL = 12 */ @@ -564,15 +642,14 @@ static void eqos_configure_dma_channel(unsigned int chan, * ie, (16ns x 256) => 4.096us (rounding off to 4us) * So formula with above values is,ret = usec/4 */ - if (osi_dma->use_riwt == OSI_ENABLE && chan <= OSI_EQOS_MAX_NUM_CHANS && - osi_dma->rx_riwt < UINT_MAX) { + if (osi_dma->use_riwt == OSI_ENABLE && osi_dma->rx_riwt < UINT_MAX) { value = osi_readl((unsigned char *)osi_dma->base + EQOS_DMA_CHX_RX_WDT(chan)); /* Mask the RWT value */ value &= ~EQOS_DMA_CHX_RX_WDT_RWT_MASK; /* Conversion of usec to Rx Interrupt Watchdog Timer Count */ value |= ((osi_dma->rx_riwt * - ((unsigned int)OSI_ETHER_SYSCLOCK / OSI_ONE_MEGA_HZ)) / + (OSI_ETHER_SYSCLOCK / OSI_ONE_MEGA_HZ)) / EQOS_DMA_CHX_RX_WDT_RWTU) & EQOS_DMA_CHX_RX_WDT_RWT_MASK; osi_writel(value, (unsigned char *)osi_dma->base + diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 3de5db0..594f49c 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -195,6 +195,11 @@ int osi_stop_dma(struct osi_dma_priv_data *osi_dma, unsigned int osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring) { + if (rx_ring->cur_rx_idx >= RX_DESC_CNT || + rx_ring->refill_idx >= RX_DESC_CNT) { + return 0; + } + return (rx_ring->cur_rx_idx - rx_ring->refill_idx) & (RX_DESC_CNT - 1U); } @@ -239,9 +244,16 @@ int osi_update_rx_tailptr(struct osi_dma_priv_data *osi_dma, unsigned long tailptr = 0; unsigned int refill_idx = rx_ring->refill_idx; + if (refill_idx >= RX_DESC_CNT) { + return -1; + } + DECR_RX_DESC_INDEX(refill_idx, 1U); tailptr = rx_ring->rx_desc_phy_addr + (refill_idx * sizeof(struct osi_rx_desc)); + if (tailptr < rx_ring->rx_desc_phy_addr) { + return -1; + } if (osi_dma != OSI_NULL && osi_dma->ops != OSI_NULL && osi_dma->ops->update_rx_tailptr != OSI_NULL) { diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index db068c2..a8b3267 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -159,6 +159,10 @@ static int get_rx_hwstamp(struct osi_rx_desc *rx_desc, 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 ret; } @@ -196,6 +200,10 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, int received = 0; int ret = 0; + if (rx_ring->cur_rx_idx >= RX_DESC_CNT) { + return -1; + } + while (received < budget) { osi_memset(rx_pkt_cx, 0U, sizeof(*rx_pkt_cx)); rx_desc = rx_ring->rx_desc + rx_ring->cur_rx_idx; @@ -411,14 +419,21 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi, ((tx_desc->tdes3 & TDES3_CTXT) == 0U)) { /* check tx tstamp status */ if ((tx_desc->tdes3 & TDES3_TTSS) != 0U) { - txdone_pkt_cx->flags |= OSI_TXDONE_CX_TS; /* tx timestamp captured for this packet */ ns = tx_desc->tdes0; vartdes1 = tx_desc->tdes1; - if (vartdes1 < UINT_MAX) { - ns = ns + (vartdes1 * OSI_NSEC_PER_SEC); + 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); } - txdone_pkt_cx->ns = ns; } else { /* Do nothing here */ } @@ -442,7 +457,9 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi, tx_swcx->buf_phy_addr = 0; tx_swcx->is_paged_buf = 0; INCR_TX_DESC_INDEX(entry, 1U); - processed++; + if (processed < INT_MAX) { + processed++; + } /* Don't wait to update tx_ring->clean-idx. It will * be used by OSD layer to determine the num. of available @@ -526,9 +543,19 @@ static inline void fill_first_desc(struct osi_tx_pkt_cx *tx_pkt_cx, struct osi_tx_desc *tx_desc, struct osi_tx_swcx *tx_swcx) { + unsigned long tmp; + /* update the first buffer pointer and length */ - tx_desc->tdes0 = (unsigned int)L32(tx_swcx->buf_phy_addr); - tx_desc->tdes1 = (unsigned int)H32(tx_swcx->buf_phy_addr); + tmp = L32(tx_swcx->buf_phy_addr); + if (tmp < UINT_MAX) { + tx_desc->tdes0 = (unsigned int)tmp; + } + + tmp = H32(tx_swcx->buf_phy_addr); + if (tmp < UINT_MAX) { + tx_desc->tdes1 = (unsigned int)tmp; + } + tx_desc->tdes2 = tx_swcx->len; /* Mark it as First descriptor */ tx_desc->tdes3 |= TDES3_FD; @@ -581,10 +608,18 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan) struct osi_tx_desc *last_desc = OSI_NULL; struct osi_tx_desc *first_desc = OSI_NULL; struct osi_tx_desc *cx_desc = OSI_NULL; - unsigned long tailptr; + unsigned long tailptr, tmp; unsigned int i; int cntx_desc_consumed; + if (entry >= TX_DESC_CNT) { + return; + } + if (desc_cnt == 0U) { + /* Will not hit this case */ + return; + } + /* Context decriptor for VLAN/TSO */ if ((tx_pkt_cx->flags & OSI_PKT_CX_VLAN) == OSI_PKT_CX_VLAN) { osi->dstats.tx_vlan_pkt_n = @@ -611,7 +646,6 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan) /* Fill first descriptor */ fill_first_desc(tx_pkt_cx, tx_desc, tx_swcx); - INCR_TX_DESC_INDEX(entry, 1U); first_desc = tx_desc; @@ -622,8 +656,15 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan) /* Fill remaining descriptors */ for (i = 0; i < desc_cnt; i++) { - tx_desc->tdes0 = (unsigned int)L32(tx_swcx->buf_phy_addr); - tx_desc->tdes1 = (unsigned int)H32(tx_swcx->buf_phy_addr); + tmp = L32(tx_swcx->buf_phy_addr); + if (tmp < UINT_MAX) { + tx_desc->tdes0 = (unsigned int)tmp; + } + + tmp = H32(tx_swcx->buf_phy_addr); + if (tmp < UINT_MAX) { + tx_desc->tdes1 = (unsigned int)tmp; + } tx_desc->tdes2 = tx_swcx->len; /* set HW OWN bit for descriptor*/ tx_desc->tdes3 |= TDES3_OWN; @@ -649,6 +690,10 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan) tailptr = tx_ring->tx_desc_phy_addr + (entry * sizeof(struct osi_tx_desc)); + if (tailptr < tx_ring->tx_desc_phy_addr) { + /* Will not hit this case */ + return; + } ops->update_tx_tailptr(osi->base, chan, tailptr); tx_ring->cur_tx_idx = entry; @@ -674,7 +719,7 @@ static int rx_dma_desc_initialization(struct osi_dma_priv_data *osi, struct osi_rx_desc *rx_desc = OSI_NULL; struct osi_rx_swcx *rx_swcx = OSI_NULL; struct osi_dma_chan_ops *ops = osi->ops; - unsigned long tailptr = 0; + unsigned long tailptr = 0, tmp; unsigned int i; int ret = 0; @@ -685,8 +730,16 @@ static int rx_dma_desc_initialization(struct osi_dma_priv_data *osi, rx_swcx = rx_ring->rx_swcx + i; rx_desc = rx_ring->rx_desc + i; - rx_desc->rdes0 = (unsigned int)L32(rx_swcx->buf_phy_addr); - rx_desc->rdes1 = (unsigned int)H32(rx_swcx->buf_phy_addr); + tmp = L32(rx_swcx->buf_phy_addr); + if (tmp < UINT_MAX) { + rx_desc->rdes0 = (unsigned int)tmp; + } + + tmp = H32(rx_swcx->buf_phy_addr); + if (tmp < UINT_MAX) { + rx_desc->rdes1 = (unsigned int)tmp; + } + rx_desc->rdes2 = 0; rx_desc->rdes3 = (RDES3_OWN | RDES3_IOC | RDES3_B1V); /* reconfigure INTE bit if RX watchdog timer is enabled */ @@ -697,6 +750,10 @@ static int rx_dma_desc_initialization(struct osi_dma_priv_data *osi, tailptr = rx_ring->rx_desc_phy_addr + sizeof(struct osi_rx_desc) * (RX_DESC_CNT - 1U); + if (tailptr < rx_ring->rx_desc_phy_addr) { + /* Will not hit this case */ + return -1; + } ops->set_rx_ring_len(osi->base, chan, (RX_DESC_CNT - 1U)); ops->update_rx_tailptr(osi->base, chan, tailptr); From 0667438475ca20cf80be5aeecf0b58c06e15727a Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Fri, 6 Sep 2019 14:59:42 +0530 Subject: [PATCH 042/458] nvethernetrm: add vlan tag stripping control Provide a control to enable or disable VLAN tag stripping Bug 200549370 Change-Id: I0b7f59493cb6504edc1f94239b730c03e4444af6 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2191631 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_core.h | 2 ++ osi/core/eqos_core.c | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index c9e8b70..77697bf 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -340,6 +340,8 @@ struct osi_core_priv_data { /** Functional safety config to do periodic read-verify of * certain safety critical registers */ void *safety_config; + /** VLAN tag stripping enable(1) or disable(0) */ + unsigned int strip_vlan_tag; }; /** diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 7a4b2c9..c1b9165 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1237,8 +1237,10 @@ static void eqos_configure_mac(struct osi_core_priv_data *osi_core) * Enable VLAN Tag in RX Status * Disable VLAN Type Check */ - value |= EQOS_MAC_VLANTR_EVLS_ALWAYS_STRIP | EQOS_MAC_VLANTR_EVLRXS | - EQOS_MAC_VLANTR_DOVLTC; + 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_writel(value, (unsigned char *)osi_core->base + EQOS_MAC_VLAN_TAG); From 16afb9d2775cbe40dcd053dfbbe97047c98db4f4 Mon Sep 17 00:00:00 2001 From: Mohit Dhingra <mdhingra@nvidia.com> Date: Tue, 10 Sep 2019 16:30:13 +0530 Subject: [PATCH 043/458] nvethernetrm: add WAR to not validate few regs WAR to get validate_regs API working until QNX OSD completely moves to this nvethernetrm library. ESQC-10891 Change-Id: I9b46b86e53f6a8095d483811d4df76b735081443 Signed-off-by: Mohit Dhingra <mdhingra@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2194226 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/eqos_core.c | 14 ++++++++++++++ osi/dma/eqos_dma.c | 12 ++++++++++++ 2 files changed, 26 insertions(+) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index c1b9165..3b23cb3 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -202,6 +202,20 @@ static int eqos_validate_core_regs(struct osi_core_priv_data *osi_core) if (config->reg_addr[i] == OSI_NULL) { continue; } + /* FIXME + * QNX OSD currently overwrites following registers and + * therefore validation fails using this API. Add an + * exception for following registers until QNX OSD completely + * moves to common library. + */ + if ((i == EQOS_MAC_PFR_IDX) || (i == EQOS_MAC_HTR0_IDX) + || (i == EQOS_MAC_HTR1_IDX) || (i == EQOS_MAC_HTR2_IDX) + || (i == EQOS_MAC_HTR3_IDX) || (i == EQOS_MAC_TCR_IDX) + || (i == EQOS_MAC_SSIR_IDX) || (i == EQOS_MAC_TAR_IDX)) + { + continue; + } + cur_val = osi_readl((unsigned char *)config->reg_addr[i]); cur_val &= config->reg_mask[i]; diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index fdfc698..e86f957 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -156,6 +156,18 @@ static int eqos_validate_dma_regs(struct osi_dma_priv_data *osi_dma) continue; } + /* FIXME + * QNX OSD currently overwrites following registers and + * therefore validation fails using this API. Add an + * exception for following registers until QNX OSD completely + * moves to common library. + */ + if ((i == EQOS_DMA_CH0_TDRL_IDX) || + (i == EQOS_DMA_CH0_RDRL_IDX)) + { + continue; + } + cur_val = osi_readl((unsigned char *)config->reg_addr[i]); cur_val &= config->reg_mask[i]; From 1ef8478afeb18f292a52fbff03726875cbd4909e Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Wed, 18 Sep 2019 12:04:30 +0530 Subject: [PATCH 044/458] nvethernetrm: Fix CERT-C casting string issue Issue: Observed casting string literal pointer casting to non-const issue in nvethernetmcal repo. Fix: Declare mac input parameter as constant in osi_update_mac_addr_low_high_reg function definition. Bug 200551115 Change-Id: Ie5c182a33056d99ba58227226d3c4c6908165d5b Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2200347 Tested-by: Praveen Mallaiah <pmallaiah@nvidia.com> Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_core.h | 4 ++-- osi/core/eqos_core.c | 3 ++- osi/core/osi_core.c | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 77697bf..864777a 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -182,7 +182,7 @@ struct osi_core_ops { int (*update_mac_addr_low_high_reg)( struct osi_core_priv_data *osi_core, unsigned int index, - unsigned char value[], + const unsigned char value[], unsigned int dma_routing_enable, unsigned int dma_chan, unsigned int addr_mask, @@ -757,7 +757,7 @@ int osi_config_mac_pkt_filter_reg(struct osi_core_priv_data *osi_core, */ int osi_update_mac_addr_low_high_reg(struct osi_core_priv_data *osi_core, unsigned int index, - unsigned char value[], + const unsigned char value[], unsigned int dma_routing_enable, unsigned int dma_chan, unsigned int addr_mask, diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 3b23cb3..bb4f983 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1838,7 +1838,8 @@ err_dma_chan: */ static int eqos_update_mac_addr_low_high_reg( struct osi_core_priv_data *osi_core, - unsigned int idx, unsigned char addr[], + unsigned int idx, + const unsigned char addr[], unsigned int dma_routing_enable, unsigned int dma_chan, unsigned int addr_mask, unsigned int src_dest) diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 86cf5b6..f023a24 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -439,7 +439,8 @@ int osi_config_mac_pkt_filter_reg(struct osi_core_priv_data *osi_core, } int osi_update_mac_addr_low_high_reg(struct osi_core_priv_data *osi_core, - unsigned int index, unsigned char value[], + unsigned int index, + const unsigned char value[], unsigned int dma_routing_enable, unsigned int dma_chan, unsigned int addr_mask, From fff3e1947ef414a5db3c8b526505a89fa5dcd6ed Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Wed, 21 Aug 2019 18:02:58 +0530 Subject: [PATCH 045/458] nvethernetrm: eqos: Allow to add VLAN tag 0 Issue: Current sw allows only non-zero VLAN tag to be added in register. Fix: 1) Allow adding VLAN id 0 in VLAN tag register. By this all VLAN tag packets are allowed even filter enable. 2) Don't update VLAN ID to VLAN TR register for eqos so it set to default 0x0. Bug 200544722 Change-Id: Icbc89a8318cc2acd5a346da802244c213dcc15e6 Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2180240 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/eqos_core.c | 15 ++++----------- osi/core/osi_core.c | 2 +- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index bb4f983..30a8255 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -2621,20 +2621,13 @@ static int eqos_config_vlan_filtering(struct osi_core_priv_data *osi_core, * @param[in] base: Base address from OSI core private data structure. * @param[in] vid: VLAN ID to be programmed. * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. + * @retval 0 always */ static inline int eqos_update_vlan_id(void *base, unsigned int vid) { - unsigned int value; - - value = osi_readl((unsigned char *)base + EQOS_MAC_VLAN_TR); - /* 0:15 of register */ - value &= ~EQOS_MAC_VLAN_TR_VL; - value |= vid & EQOS_MAC_VLAN_TR_VL; - osi_writel(value, (unsigned char *)base + EQOS_MAC_VLAN_TR); + /* Don't add VLAN ID to TR register which is eventually set TR + * to 0x0 and allow all tagged packets + */ return 0; } diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index f023a24..fab6750 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -640,7 +640,7 @@ int osi_update_vlan_id(struct osi_core_priv_data *osi_core, unsigned int vid) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->update_vlan_id != OSI_NULL && vid != 0U)) { + (osi_core->ops->update_vlan_id != OSI_NULL)) { return osi_core->ops->update_vlan_id(osi_core->base, vid); } From c570626ca4d798c8800cb88c4e05388d130063a2 Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Thu, 26 Sep 2019 01:52:11 +0530 Subject: [PATCH 046/458] nvethernetrm: Fix MISRA violation with ULONG_MAX Issues: Observed MISRA Rule 14.3 violations due to ULONG_MAX comparison. Fix: Redesign this code by removing the ULONG_MAX comparison logic and handle CERT-C wrap violations. Bug 200544430 Change-Id: I05e0dc03356ae19a0dcb895d35ef679f96575ac0 Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2206001 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_common.h | 16 +++------ osi/core/eqos_mmc.c | 9 +++--- osi/dma/osi_dma_txrx.c | 73 +++++++++++++++++++++++------------------- 3 files changed, 49 insertions(+), 49 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index fd149b0..ecca395 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -51,9 +51,6 @@ #define OSI_ADDRESS_40BIT 1 #define OSI_ADDRESS_48BIT 2 -#ifndef ULONG_MAX -#define ULONG_MAX (~0UL) -#endif #ifndef UINT_MAX #define UINT_MAX (~0U) #endif @@ -495,17 +492,14 @@ static inline int is_valid_mac_version(unsigned int mac_ver) static inline unsigned long osi_update_stats_counter(unsigned long last_value, unsigned long incr) { - unsigned long long temp; + unsigned long temp = last_value + incr; - temp = (unsigned long long)last_value; - temp = temp + incr; - if (temp > ULONG_MAX) { - /* Do nothing */ - } else { - return (unsigned long)temp; + if (temp < last_value) { + /* Stats overflow, so reset it to zero */ + return 0UL; } - return last_value; + return temp; } /** diff --git a/osi/core/eqos_mmc.c b/osi/core/eqos_mmc.c index 2e5c8da..fffdd2e 100644 --- a/osi/core/eqos_mmc.c +++ b/osi/core/eqos_mmc.c @@ -47,18 +47,17 @@ static inline unsigned long update_mmc_val(struct osi_core_priv_data *osi_core, unsigned long last_value, unsigned long offset) { - unsigned long long temp; + unsigned long temp; unsigned int value = osi_readl((unsigned char *)osi_core->base + offset); - temp = (unsigned long long)last_value; - temp = temp + (unsigned long long)value; - if (temp > ULONG_MAX) { + temp = last_value + value; + if (temp < last_value) { osd_err(osi_core->osd, "Value overflow for offset = 0x%x resetting all counters\n", offset); eqos_reset_mmc(osi_core); } else { - return (unsigned long)temp; + return temp; } return 0; diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index a8b3267..1a6a7e4 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -183,9 +183,10 @@ static inline void get_rx_err_stats(struct osi_rx_desc *rx_desc, { /* increment rx crc if we see CE bit set */ if ((rx_desc->rdes3 & RDES3_ERR_CRC) == RDES3_ERR_CRC) { - if (pkt_err_stats.rx_crc_error < ULONG_MAX) { - pkt_err_stats.rx_crc_error++; - } + pkt_err_stats.rx_crc_error = + osi_update_stats_counter( + pkt_err_stats.rx_crc_error, + 1UL); } } @@ -273,76 +274,82 @@ static inline void get_tx_err_stats(struct osi_tx_desc *tx_desc, { /* IP Header Error */ if ((tx_desc->tdes3 & TDES3_IP_HEADER_ERR) == TDES3_IP_HEADER_ERR) { - if (pkt_err_stats.ip_header_error < ULONG_MAX) { - pkt_err_stats.ip_header_error++; - } + 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) { - if (pkt_err_stats.jabber_timeout_error < ULONG_MAX) { - pkt_err_stats.jabber_timeout_error++; - } + 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) { - if (pkt_err_stats.pkt_flush_error < ULONG_MAX) { - pkt_err_stats.pkt_flush_error++; - } + 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) { - if (pkt_err_stats.payload_cs_error < ULONG_MAX) { - pkt_err_stats.payload_cs_error++; - } + 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) { - if (pkt_err_stats.loss_of_carrier_error < ULONG_MAX) { - pkt_err_stats.loss_of_carrier_error++; - } + 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) { - if (pkt_err_stats.no_carrier_error < ULONG_MAX) { - pkt_err_stats.no_carrier_error++; - } + 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) { - if (pkt_err_stats.late_collision_error < ULONG_MAX) { - pkt_err_stats.late_collision_error++; - } + pkt_err_stats.late_collision_error = + osi_update_stats_counter( + pkt_err_stats.late_collision_error, + 1UL); } /* Execessive Collision Error */ if ((tx_desc->tdes3 & TDES3_EXCESSIVE_COL_ERR) == TDES3_EXCESSIVE_COL_ERR) { - if (pkt_err_stats.excessive_collision_error < ULONG_MAX) { - pkt_err_stats.excessive_collision_error++; - } + 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) { - if (pkt_err_stats.excessive_deferal_error < ULONG_MAX) { - pkt_err_stats.excessive_deferal_error++; - } + 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) { - if (pkt_err_stats.underflow_error < ULONG_MAX) { - pkt_err_stats.underflow_error++; - } + pkt_err_stats.underflow_error = + osi_update_stats_counter(pkt_err_stats.underflow_error, + 1UL); } } From 0fb9e5fd5acfc626f14d39063c429d0818d8c7e7 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Thu, 10 Oct 2019 11:58:53 +0530 Subject: [PATCH 047/458] nvethernetrm: fix map/unmap of Rx timestamp descriptor Receive timestamp for a received packet will be in context descriptor which is immediate of normal descriptor (has valid packet data) In current case nvethernet driver only unmap normal descriptor buffer address and provide the buffer to the network stack for data processing. Context descriptor buffer is not unmapped which leads to running out of IOVA space for the new buffers. Context descriptor buffer can be used as is since that is not provided to the network stack. So this change to a flag for context descriptor. Based on this flag OSD can skip new buffer allocation and mapping for the context descriptor and use already allocated buffer. Bug 2700522 Change-Id: I18c8ebe39bf2eaaaeb13a9de3c9595cbe2ada45d Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2214726 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_dma.h | 2 ++ osi/dma/osi_dma_txrx.c | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/include/osi_dma.h b/include/osi_dma.h index da30edc..fed57f4 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -133,6 +133,8 @@ struct osi_rx_swcx { void *buf_virt_addr; /** Length of buffer */ unsigned int len; + /** PTP software context */ + unsigned int ptp_swcx; }; /** diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 1a6a7e4..ff508e1 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -197,6 +197,7 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, struct osi_rx_pkt_cx *rx_pkt_cx = &rx_ring->rx_pkt_cx; 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; int received = 0; int ret = 0; @@ -240,6 +241,15 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, /* Get rx time stamp */ ret = get_rx_hwstamp(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->ptp_swcx = 1; /* Context descriptor was consumed. Its skb * and DMA mapping will be recycled */ @@ -753,6 +763,8 @@ static int rx_dma_desc_initialization(struct osi_dma_priv_data *osi, if (osi->use_riwt == OSI_ENABLE) { rx_desc->rdes3 &= ~RDES3_IOC; } + + rx_swcx->ptp_swcx = 0; } tailptr = rx_ring->rx_desc_phy_addr + From eb5ead1bc5d30790d5860066d7f72eda29949fc1 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Wed, 9 Oct 2019 17:27:08 +0530 Subject: [PATCH 048/458] nvethernetrm: delay only if SWR is not reset Issue: eqos_poll_for_swr() function sleep for one millisecond and then read DMA Basic Mode register to check on SWR bit for reset or set. Because of this there would be atleast one millisecond delay. Fix: One millisecond sleep only if SWR bit not reset in DMA Basic Mode register. Bug 2715328 Change-Id: I690df18190f4ad2f4630b5aeddd35c07c161fd25 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2214195 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/eqos_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 30a8255..7b5202f 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -536,12 +536,12 @@ static int eqos_poll_for_swr(void *addr) } count++; - osd_msleep(1U); dma_bmr = osi_readl((unsigned char *)addr + EQOS_DMA_BMR); - if ((dma_bmr & EQOS_DMA_BMR_SWR) == 0U) { cond = 0; + } else { + osd_msleep(1U); } } From 8979c000385411612a878bcba983171bd16cc5aa Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Mon, 14 Oct 2019 17:50:43 +0530 Subject: [PATCH 049/458] nvethernetrm: eqos: bug fix in eqos_handle_common_intr Issue: In eqos_handle_common_intr(), SW exit for loop without checking all DMA based on DMA0 common interrupt status. Fix: SW shall check for all dma channels. Bug 2713320 Change-Id: I164ba1063860232a3067621524ec5fa6e52e4c65 Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2217558 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/eqos_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 7b5202f..74d8dbe 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1550,7 +1550,7 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *osi_core) /* mask off RI and TI */ dma_sr &= ~(OSI_BIT(6) | OSI_BIT(0)); if (dma_sr == 0U) { - return; + continue; } /* ack non ti/ri ints */ From a1c67e912b2e74bb3188f8594e619840c7d315a6 Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Wed, 9 Oct 2019 16:41:01 +0530 Subject: [PATCH 050/458] nvethernet: Remove variable args API's for MISRA Issue: Variable arguments not allowed in misra/certc. Fix: Remove variable arguments API's and add fixed arguments API Bug 200553611 Change-Id: I5566683a01e1e65654c25f779ea96f68d9de8555 Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2214093 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osd.h | 35 ++++++++-------- include/osi_common.h | 47 +++++++++++++++++++++ osi/core/eqos_core.c | 97 ++++++++++++++++++++++++++++---------------- osi/core/eqos_mmc.c | 6 ++- osi/core/osi_core.c | 20 +++++++-- 5 files changed, 149 insertions(+), 56 deletions(-) diff --git a/include/osd.h b/include/osd.h index beb70fe..b5574fe 100644 --- a/include/osd.h +++ b/include/osd.h @@ -42,22 +42,6 @@ void osd_msleep(unsigned int msec); * @param[in] usec: time in usec */ void osd_udelay(unsigned long usec); -/** - * @brief osd_info - logging function - * - * @param[in] priv: OSD private data - * @param[in] fmt: fragments - */ -void osd_info(void *priv, const char *fmt, ...); - -/** - * @brief osd_err - logging function - * - * @param[in] priv: OSD private data - * @param[in] fmt: fragments - */ -void osd_err(void *priv, const char *fmt, ...); - /** * @brief osd_receive_packet - Handover received packet to network stack. * @@ -111,4 +95,23 @@ void osd_receive_packet(void *priv, void *rxring, unsigned int chan, */ void osd_transmit_complete(void *priv, void *buffer, unsigned long dmaaddr, unsigned int len, void *txdone_pkt_cx); +/** + * @brief osd_log - OSD logging function + * + * @param[in] priv: OSD private data + * @param[in] func: function name + * @param[in] line: line number + * @param[in] level: log level + * @param[in] type: error type + * @param[in] err: error string + * @param[in] loga: error additional information + * + */ +void osd_log(void *priv, + const char *func, + unsigned int line, + unsigned int level, + unsigned int type, + const char *err, + unsigned long long loga); #endif diff --git a/include/osi_common.h b/include/osi_common.h index ecca395..883bda9 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -77,6 +77,53 @@ #define OSI_ULLONG_MAX (~0ULL) #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_OPNOTSUPP 3U +#define OSI_LOG_ARG_HW_FAIL 4U +/** + * 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_ERR(priv, type, err, loga) \ + { \ + osd_log(priv, __func__, __LINE__, \ + OSI_LOG_ERR, type, err, loga); \ + } +/** + * 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_INFO(priv, type, err, loga) \ + { \ + osd_log(priv, __func__, __LINE__, \ + OSI_LOG_INFO, type, err, loga); \ + } +/** + * OSI warning 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_WARN(priv, type, err, loga) \ + { \ + osd_log(priv, __func__, __LINE__, \ + OSI_LOG_WARN, type, err, loga); \ + } + /* Default maximum Gaint Packet Size Limit */ #define OSI_MAX_MTU_SIZE 9000U #define OSI_DFLT_MTU_SIZE 1500U diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 74d8dbe..0c42706 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1113,9 +1113,9 @@ static void eqos_configure_rxq_priority(struct osi_core_priv_data *osi_core) unsigned int mfix_var1, mfix_var2; if (osi_core->dcs_en == OSI_ENABLE) { - osd_err(osi_core->osd, - "Invalid combination of DCS and RxQ-UP mapping, exiting %s()\n", - __func__); + OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "Invalid combination of DCS and RxQ-UP mapping\n", + 0ULL); return; } /* make sure EQOS_MAC_RQC2R is reset before programming */ @@ -1131,9 +1131,9 @@ static void eqos_configure_rxq_priority(struct osi_core_priv_data *osi_core) pmask |= osi_core->rxq_prio[mtlq]; temp = osi_core->rxq_prio[mtlq]; } else { - osd_err(osi_core->osd, - "Invalid rxq Priority for Q(%d)\n", - mtlq); + OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "Invalid rxq Priority for Q\n", + (unsigned long long)mtlq); continue; } @@ -1270,8 +1270,9 @@ static void eqos_configure_mac(struct osi_core_priv_data *osi_core) osi_core->flow_ctrl = (OSI_FLOW_CTRL_TX | OSI_FLOW_CTRL_RX); if (eqos_config_flow_control(osi_core->base, osi_core->flow_ctrl) != 0) { - osd_err(osi_core->osd, "Failed to set flow control" - " configuration\n"); + OSI_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Failed to set flow control configuration\n", + 0ULL); } } /* USP (user Priority) to RxQ Mapping */ @@ -1638,21 +1639,25 @@ static int eqos_set_avb_algorithm(struct osi_core_priv_data *osi_core, unsigned int qinx; if (avb == OSI_NULL) { - osd_err(osi_core->osd, "avb structure is NULL\n"); + OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "avb structure is NULL\n", + 0ULL); return ret; } /* queue index in range */ if (avb->qindex >= EQOS_MAX_TC) { - osd_err(osi_core->osd, "Invalid Queue index (%d)\n" - , avb->qindex); + OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "Invalid Queue index\n", + (unsigned long long)avb->qindex); return ret; } /* can't set AVB mode for queue 0 */ if ((avb->qindex == 0U) && (avb->oper_mode == EQOS_MTL_QUEUE_AVB)) { - osd_err(osi_core->osd, - "Not allowed to set CBS for Q0\n", avb->qindex); + OSI_ERR(osi_core->osd, OSI_LOG_ARG_OPNOTSUPP, + "Not allowed to set CBS for Q0\n", + (unsigned long long)avb->qindex); return ret; } @@ -1784,7 +1789,9 @@ static inline int eqos_update_mac_addr_helper( *value = ((dma_chan << EQOS_MAC_ADDRH_DCS_SHIFT) & EQOS_MAC_ADDRH_DCS); } else if (dma_chan > OSI_EQOS_MAX_NUM_CHANS - 0x1U) { - osd_err(osi_core->osd, "invalid dma channel\n"); + OSI_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, + "invalid dma channel\n", + (unsigned long long)dma_chan); ret = -1; goto err_dma_chan; } else { @@ -1799,7 +1806,9 @@ static inline int eqos_update_mac_addr_helper( ((addr_mask << EQOS_MAC_ADDRH_MBC_SHIFT) & EQOS_MAC_ADDRH_MBC)); } else { - osd_err(osi_core->osd, "invalid address index for MBC\n"); + OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "invalid address index for MBC\n", + 0ULL); ret = -1; } } @@ -1848,7 +1857,9 @@ static int eqos_update_mac_addr_low_high_reg( int ret = 0; if (idx > (EQOS_MAX_MAC_ADDRESS_FILTER - 0x1U)) { - osd_err(osi_core->osd, "invalid MAC filter index\n"); + OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "invalid MAC filter index\n", + 0ULL); return -1; } @@ -1917,13 +1928,16 @@ static int eqos_get_avb_algorithm(struct osi_core_priv_data *osi_core, unsigned int qinx = 0U; if (avb == OSI_NULL) { - osd_err(osi_core->osd, "avb structure is NULL\n"); + OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "avb structure is NULL\n", + 0ULL); return ret; } if (avb->qindex >= EQOS_MAX_TC) { - osd_err(osi_core->osd, "Invalid Queue index (%d)\n" - , avb->qindex); + OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "Invalid Queue index\n", + (unsigned long long)avb->qindex); return ret; } @@ -2117,13 +2131,16 @@ static int eqos_update_ip4_addr(struct osi_core_priv_data *osi_core, unsigned int temp = 0U; if (addr == OSI_NULL) { - osd_err(osi_core->osd, "%s() invalid address\n", __func__); + OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "invalid address\n", + 0ULL); return -1; } if (filter_no > (EQOS_MAX_L3_L4_FILTER - 0x1U)) { - osd_err(osi_core->osd, "filter index %d > %d for L3/L4 filter\n" - , filter_no, EQOS_MAX_L3_L4_FILTER); + OSI_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, + "invalid filter index for L3/L4 filter\n", + (unsigned long long)filter_no); return -1; } @@ -2170,13 +2187,16 @@ static int eqos_update_ip6_addr(struct osi_core_priv_data *osi_core, unsigned int temp = 0U; if (addr == OSI_NULL) { - osd_err(osi_core->osd, "%s() invalid address\n", __func__); + OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "invalid address\n", + 0ULL); return -1; } if (filter_no > (EQOS_MAX_L3_L4_FILTER - 0x1U)) { - osd_err(osi_core->osd, "filter index %d > %d for L3/L4 filter\n" - , filter_no, EQOS_MAX_L3_L4_FILTER); + OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "invalid filter index for L3/L4 filter\n", + (unsigned long long)filter_no); return -1; } @@ -2238,8 +2258,9 @@ static int eqos_update_l4_port_no(struct osi_core_priv_data *osi_core, unsigned int temp = 0U; if (filter_no > (EQOS_MAX_L3_L4_FILTER - 0x1U)) { - osd_err(osi_core->osd, "filter index %d > %d for L3/L4 filter\n" - , filter_no, EQOS_MAX_L3_L4_FILTER); + OSI_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, + "invalid filter index for L3/L4 filter\n", + (unsigned long long)filter_no); return -1; } @@ -2332,14 +2353,17 @@ static int eqos_config_l3_filters(struct osi_core_priv_data *osi_core, void *base = osi_core->base; if (filter_no > (EQOS_MAX_L3_L4_FILTER - 0x1U)) { - osd_err(osi_core->osd, "filter index %d > %d for L3/L4 filter\n" - , filter_no, EQOS_MAX_L3_L4_FILTER); + OSI_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, + "invalid filter index for L3/L4 filter\n", + (unsigned long long)filter_no); return -1; } if ((dma_routing_enable == OSI_ENABLE) && (dma_chan > OSI_EQOS_MAX_NUM_CHANS - 1U)) { - osd_err(osi_core->osd, "Wrong DMA channel %d\n", dma_chan); + OSI_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, + "Wrong DMA channel\n", + (unsigned long long)dma_chan); return -1; } @@ -2499,14 +2523,17 @@ static int eqos_config_l4_filters(struct osi_core_priv_data *osi_core, unsigned int value = 0U; if (filter_no > (EQOS_MAX_L3_L4_FILTER - 0x1U)) { - osd_err(osi_core->osd, "filter index %d > %d for L3/L4 filter\n" - , filter_no, EQOS_MAX_L3_L4_FILTER); + OSI_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, + "invalid filter index for L3/L4 filter\n", + (unsigned long long)filter_no); return -1; } if ((dma_routing_enable == OSI_ENABLE) && (dma_chan > OSI_EQOS_MAX_NUM_CHANS - 1U)) { - osd_err(osi_core->osd, "Wrong DMA channel %d\n", dma_chan); + OSI_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, + "Wrong DMA channel\n", + (unsigned int)dma_chan); return -1; } @@ -2609,7 +2636,9 @@ static int eqos_config_vlan_filtering(struct osi_core_priv_data *osi_core, value |= ((perfect_inverse_match << EQOS_MAC_VLAN_TR_VTIM_SHIFT) & EQOS_MAC_VLAN_TR_VTIM); if (perfect_hash_filtering == OSI_HASH_FILTER_MODE) { - osd_err(osi_core->osd, "VLAN hash filter is not supported not updating VTHM\n"); + OSI_ERR(osi_core->osd, OSI_LOG_ARG_OPNOTSUPP, + "VLAN hash filter is not supported, no updat of VTHM\n", + 0ULL); } osi_writel(value, (unsigned char *)base + EQOS_MAC_VLAN_TR); return 0; diff --git a/osi/core/eqos_mmc.c b/osi/core/eqos_mmc.c index fffdd2e..af9337d 100644 --- a/osi/core/eqos_mmc.c +++ b/osi/core/eqos_mmc.c @@ -53,8 +53,10 @@ static inline unsigned long update_mmc_val(struct osi_core_priv_data *osi_core, temp = last_value + value; if (temp < last_value) { - osd_err(osi_core->osd, "Value overflow for offset = 0x%x resetting all counters\n", - offset); + OSI_ERR(osi_core->osd, + OSI_LOG_ARG_OUTOFBOUND, + "Value overflow resetting all counters\n", + (unsigned long long)offset); eqos_reset_mmc(osi_core); } else { return temp; diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index fab6750..6891895 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -61,7 +61,10 @@ static inline int poll_for_mii_idle(struct osi_core_priv_data *osi_core) count = 0; while (cond == 1) { if (count > retry) { - osd_err(osi_core->osd, "MII operation timed out\n"); + OSI_ERR(osi_core->osd, + OSI_LOG_ARG_HW_FAIL, + "MII operation timed out\n", + 0ULL); return -1; } @@ -454,7 +457,10 @@ int osi_update_mac_addr_low_high_reg(struct osi_core_priv_data *osi_core, if ((dma_routing_enable == OSI_ENABLE) && (osi_core->dcs_en != OSI_ENABLE)) { - osd_err(osi_core->osd, "dma routing enabled but dcs disabled in DT\n"); + OSI_ERR(osi_core->osd, + OSI_LOG_ARG_INVALID, + "dma routing enabled but dcs disabled in DT\n", + 0ULL); return ret; } @@ -502,7 +508,10 @@ int osi_config_l3_filters(struct osi_core_priv_data *osi_core, if ((dma_routing_enable == OSI_ENABLE) && (osi_core->dcs_en != OSI_ENABLE)) { - osd_err(osi_core->osd, "dma routing enabled but dcs disabled in DT\n"); + OSI_ERR(osi_core->osd, + OSI_LOG_ARG_INVALID, + "dma routing enabled but dcs disabled in DT\n", + 0ULL); return ret; } @@ -563,7 +572,10 @@ int osi_config_l4_filters(struct osi_core_priv_data *osi_core, if ((dma_routing_enable == OSI_ENABLE) && (osi_core->dcs_en != OSI_ENABLE)) { - osd_err(osi_core->osd, "dma routing enabled but dcs disabled in DT\n"); + OSI_ERR(osi_core->osd, + OSI_LOG_ARG_INVALID, + "dma routing enabled but dcs disabled in DT\n", + 0ULL); return ret; } From 219140b8bc636d8b21ab4a5a72e353625bcaea35 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Wed, 16 Oct 2019 23:01:38 +0530 Subject: [PATCH 051/458] nvethernetrm: fix race in Tx ring current tx index Issue: Ethernet transmit routine called with a Tx packet then OSI layer invoked with osi_hw_transmit() routine to update the descriptor with packet details. As part of this process Tx ring cur_tx_idx not updated actual entry before updating Tx ring tail pointer. Programming Tx ring tail pointer will initiate the transmission. Here transmit routine got preempted because of Tx done interrupt. As part of ISR Tx NAPI got scheduled - osi_process_tx_completions. In Tx completions cur_tx_idx used for processing of the transmit completion ring. Since cur_tx_idx has some old value its not entering into the loop for packets processing. Actually entered into loop for next Tx interrupt and processed the Tx ring. This leads to tx timeout in handling of timestamped packets from the application point of view. Fix: Update Tx ring current tx index before updating Tx ring tail pointer. Bug 200443762 Change-Id: I27e07b17c0c8a8c32913236a3aaa97803c50b2a9 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2219894 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/dma/osi_dma_txrx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index ff508e1..263ce6d 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -712,8 +712,8 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan) return; } - ops->update_tx_tailptr(osi->base, chan, tailptr); tx_ring->cur_tx_idx = entry; + ops->update_tx_tailptr(osi->base, chan, tailptr); } /** From 8eb1bc4eb138f0ca2d046c0cbec5222c15534277 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Thu, 17 Oct 2019 16:21:06 +0530 Subject: [PATCH 052/458] nvethernetrm: fix check for rx timestamp available Issue: For every normal descriptor which has RS1V (RDES1 valid) set current code will go and check for timestamp in next descriptor. Fix: Check rx timestamp status in context descriptor if normal descriptor have RS1V (RDES1 valid) and TSA (Timestamp available) bits are set and TD (timestamp dropped) is reset. Bug 200443762 Change-Id: If910c462f7c306facba95ec37f860395fb3bacd4 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2220139 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/dma/osi_dma_txrx.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 263ce6d..b317028 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -133,10 +133,9 @@ static int get_rx_hwstamp(struct osi_rx_desc *rx_desc, int retry, ret = -1; /* Check for RS1V/TSA/TD valid */ - if (((rx_desc->rdes3 & RDES3_RS1V) == RDES3_RS1V) || - ((rx_desc->rdes1 & RDES1_TSA) == RDES1_TSA) || + 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++) { ret = get_rx_tstamp_status(context_desc); if (ret == 0) { From afb329721d91573ee024ce153c2b74c0cfa8a5df Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Fri, 25 Oct 2019 10:28:38 +0530 Subject: [PATCH 053/458] nvethernetrm: add 1usec delay for reading the TS issue: Currently when TSA is set in normal descriptor, SW will poll for OWN bit in context descriptor to fetch the time stamp. In long run scenario OWN bit is not reset in context descriptor even though the driver polls for 10 iterations. After maximum iterations driver returns timeout and hence only PTP data which is there normal descriptor will be delivered to NW stack without timestamp and hence the application results in throwing "received a PTP packet without timestamp" message. fix: add a 1usec delay between the iterations so that hardware can get enough time to reset the OWN bit of context descriptor. Bug 200560728 Change-Id: I6b94ebc4ac0e52c6887999b7183ac60dda2cc005 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2225571 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Bibek Basu <bbasu@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/dma/osi_dma_txrx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index b317028..7092bc6 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -150,6 +150,7 @@ static int get_rx_hwstamp(struct osi_rx_desc *rx_desc, /* Do nothing here */ } /* TS not available yet, so retrying */ + osd_udelay(1U); } if (ret != 0) { /* Timed out waiting for Rx timestamp */ From c69028a353a3d4de115afa789964e3c8e7cf4aaf Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Sat, 12 Oct 2019 01:03:49 +0530 Subject: [PATCH 054/458] nvethernetrm: eqos: Use single API to enable/configure filter Configuring L3/L4 filter: osi_l3l4_filter() shall be called Configuring L2 filter: osi_l2_filter() shall be called Bug 2715384 Change-Id: Id5598b43a3723de4535b5595e019f6fced6c56ab Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2216068 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_common.h | 31 ++- include/osi_core.h | 311 +++++++----------------------- osi/core/eqos_core.c | 221 +++++++++++++--------- osi/core/eqos_core.h | 10 +- osi/core/libnvethernetrm.export | 11 +- osi/core/osi_core.c | 324 ++++++++++++++++---------------- 6 files changed, 396 insertions(+), 512 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index 883bda9..061c63e 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -136,13 +136,28 @@ #define EQOS_DMA_CHX_IER(x) ((0x0080U * (x)) + 0x1134U) /* FIXME add logic based on HW version */ -#define EQOS_MAX_MAC_ADDRESS_FILTER 128U -#define EQOS_MAX_L3_L4_FILTER 8U -#define OSI_EQOS_MAX_NUM_CHANS 4U -#define OSI_EQOS_MAX_NUM_QUEUES 4U -/* HW supports 8 Hash table regs, but eqos_validate_core_regs only checks 4 */ -#define OSI_EQOS_MAX_HASH_REGS 4U +#define EQOS_MAX_MAC_ADDRESS_FILTER 128U +#define EQOS_MAX_L3_L4_FILTER 8U +#define OSI_EQOS_MAX_NUM_CHANS 4U +#define OSI_EQOS_MAX_NUM_QUEUES 4U +#define OSI_L2_FILTER_INDEX_ANY 127U +#define OSI_CHAN_ANY 0xFFU +/* HW supports 8 Hash table regs, but eqos_validate_core_regs only checks 4 */ +#define OSI_EQOS_MAX_HASH_REGS 4U + +/* 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 MAC_VERSION 0x110 #define MAC_VERSION_SNVER_MASK 0x7FU @@ -152,6 +167,7 @@ #define OSI_NULL ((void *)0) #define OSI_ENABLE 1U +#define OSI_NONE 0U #define OSI_DISABLE 0U #define OSI_AMASK_DISABLE 0U @@ -159,11 +175,12 @@ #define OSI_PERFECT_FILTER_MODE 0U #define OSI_IPV6_MATCH 1U #define OSI_SOURCE_MATCH 0U +#define OSI_INV_MATCH 1U +#define OSI_PFT_MATCH 0U #define OSI_SA_MATCH 1U #define OSI_DA_MATCH 0U - #define OSI_L4_FILTER_TCP 0U #define OSI_L4_FILTER_UDP 1U diff --git a/include/osi_core.h b/include/osi_core.h index 864777a..f13f786 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -32,18 +32,26 @@ struct osi_core_priv_data; * @brief OSI core structure for filters */ struct osi_filter { - /** promiscuous mode enable(1) or disable(0) */ - unsigned int pr_mode; - /** hash unicast enable(1) or disable(0) */ - unsigned int huc_mode; - /** hash multicast enable(1) or disable(0) */ - unsigned int hmc_mode; - /** pass all multicast enable(1) or disable(0) */ - unsigned int pm_mode; - /** 0x0 (DISABLE): Hash or Perfect Filter is disabled - * - * 0x1 (ENABLE): Hash or Perfect Filter is enabled */ - unsigned int hpf_mode; + /** indicates operation needs to perform. refer to OSI_OPER_* */ + unsigned int oper_mode; + /** Indicates the index of the filter to be modified. + * Filter index must be between 0 - 127 */ + unsigned int index; + /** Ethernet MAC address to be added */ + const unsigned char *mac_address; + /** Indicates dma channel routing enable(1) disable (0) */ + unsigned int dma_routing; + /** indicates dma channel number to program */ + unsigned int 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] */ + unsigned int addr_mask; + /** src_dest: SA(1) or DA(0) */ + unsigned int src_dest; }; /** @@ -176,22 +184,13 @@ struct osi_core_ops { /** Called to configure Rx Checksum offload engine */ int (*config_rxcsum_offload)(void *addr, unsigned int enabled); /** Called to config mac packet filter */ - void (*config_mac_pkt_filter_reg)(struct osi_core_priv_data *osi_core, - struct osi_filter filter); + int (*config_mac_pkt_filter_reg)(struct osi_core_priv_data *osi_core, + struct osi_filter *filter); /** Called to update MAC address 1-127 */ - int (*update_mac_addr_low_high_reg)( - struct osi_core_priv_data *osi_core, - unsigned int index, - const unsigned char value[], - unsigned int dma_routing_enable, - unsigned int dma_chan, - unsigned int addr_mask, - unsigned int src_dest); + int (*update_mac_addr_low_high_reg)(struct osi_core_priv_data *osi_core, + struct osi_filter *filter); /** Called to configure l3/L4 filter */ int (*config_l3_l4_filter_enable)(void *base, unsigned int enable); - /** Called to configure L2 DA filter */ - int (*config_l2_da_perfect_inverse_match)(void *base, unsigned int - perfect_inverse_match); /** Called to configure L3 filter */ int (*config_l3_filters)(struct osi_core_priv_data *osi_core, unsigned int filter_no, unsigned int enb_dis, @@ -342,6 +341,9 @@ struct osi_core_priv_data { void *safety_config; /** VLAN tag stripping enable(1) or disable(0) */ unsigned int strip_vlan_tag; + /** L3L4 filter bit bask, set index corresponding bit for + * filter if filter enabled */ + unsigned int l3l4_filter_bitmask; }; /** @@ -706,217 +708,23 @@ int osi_config_rxcsum_offload(struct osi_core_priv_data *osi_core, unsigned int enable); /** - * @brief osi_config_mac_pkt_filter_reg - configure mac filter register. + * @brief osi_l2_filter - configure L2 mac filter. * - * Algorithm: This sequence is used to configure MAC in differnet packet + * Algorithm: This sequence is used to configure MAC in different packet * processing modes like promiscuous, multicast, unicast, - * hash unicast/multicast. + * hash unicast/multicast and perfect/inverse matching for L2 DA * * @param[in] osi_core: OSI core private data structure. - * @param[in] pfilter: OSI filter structure. + * @param[in] filter: OSI filter structure. * * @note * 1) MAC should be initialized and started. see osi_start_mac() - * 2) MAC addresses should be configured in HW registers. see - * osi_update_mac_addr_low_high_reg(). * * @retval 0 on success * @retval -1 on failure. */ -int osi_config_mac_pkt_filter_reg(struct osi_core_priv_data *osi_core, - struct osi_filter pfilter); - -/** - * @brief osi_update_mac_addr_low_high_reg- invoke API to 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] index: filter index - * @param[in] value: MAC address to write - * @param[in] dma_routing_enable: dma channel routing enable(1) - * @param[in] dma_chan: dma channel number - * @param[in] addr_mask: filter will not consider byte in comparison - * Bit 29: MAC_Address${i}_High[15:8] - * Bit 28: MAC_Address${i}_High[7:0] - * Bit 27: MAC_Address${i}_Low[31:24] - * .. - * Bit 24: MAC_Address${i}_Low[7:0] - * @param[in] src_dest: SA(1) or DA(0) - * - * @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. - */ -int osi_update_mac_addr_low_high_reg(struct osi_core_priv_data *osi_core, - unsigned int index, - const unsigned char value[], - unsigned int dma_routing_enable, - unsigned int dma_chan, - unsigned int addr_mask, - unsigned int src_dest); - -/** - * @brief osi_config_l3_l4_filter_enable - invoke OSI call to enable L3/L4 - * filters. - * - * Algorithm: This routine to enable/disable L4/l4 filter - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] enable: enable/disable - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -int osi_config_l3_l4_filter_enable(struct osi_core_priv_data *osi_core, - unsigned int enable); - -/** - * @brief osi_config_l3_filters - invoke OSI call 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) L3/L4 filtering should be enabled in MAC PFR register. See - * osi_config_l3_l4_filter_enable() - * 3) osi_core->osd should be populated - * 4) DCS bits should be enabled in RXQ to DMA map register - * - * @retval 0 on success - * @retval -1 on failure. - */ -int osi_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); - -/** - * @brief osi_update_ip4_addr - invoke OSI call update_ip4_addr. - * - * 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(addr0) 1- dest (addr1) - * - * @note - * 1) MAC should be init and started. see osi_start_mac() - * 2) L3/L4 filtering should be enabled in MAC PFR register. See - * osi_config_l3_l4_filter_enable() - * - * @retval 0 on success - * @retval -1 on failure. - */ -int osi_update_ip4_addr(struct osi_core_priv_data *osi_core, - unsigned int filter_no, - unsigned char addr[], - unsigned int src_dst_addr_match); - -/** - * @brief osi_update_ip6_addr - invoke OSI call update_ip6_addr. - * - * 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() - * 2) L3/L4 filtering should be enabled in MAC PFR register. See - * osi_config_l3_l4_filter_enable() - * - * @retval 0 on success - * @retval -1 on failure. - */ -int osi_update_ip6_addr(struct osi_core_priv_data *osi_core, - unsigned int filter_no, - unsigned short addr[]); - -/** - * @brief osi_config_l4_filters - invoke OSI call 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: enable/disable L4 filter - * @param[in] tcp_udp_match: 1 - udp, 0 - tcp - * @param[in] src_dst_port_match: port matching enable/disable - * @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) L3/L4 filtering should be enabled in MAC PFR register. See - * osi_config_l3_l4_filter_enable() - * 3) osi_core->osd should be populated - * - * @retval 0 on success - * @retval -1 on failure. - */ -int osi_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); - -/** - * @brief osi_update_l4_port_no - invoke OSI call for update_l4_port_no. - * Algoriths 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: source port - 0, dest port - 1 - * - * @note - * 1) MAC should be init and started. see osi_start_mac() - * 2) L3/L4 filtering should be enabled in MAC PFR register. See - * osi_config_l3_l4_filter_enable() - * 3) osi_core->osd should be populated - * - * @retval 0 on success - * @retval -1 on failure. - */ -int osi_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); +int osi_l2_filter(struct osi_core_priv_data *osi_core, + struct osi_filter *filter); /** * @brief osi_config_vlan_filtering - OSI call for configuring VLAN filter @@ -941,24 +749,6 @@ int osi_config_vlan_filtering(struct osi_core_priv_data *osi_core, unsigned int perfect_hash_filtering, unsigned int perfect_inverse_match); -/** - * @brief osi_config_l2_da_perfect_inverse_match - - * trigger OSI call for config_l2_da_perfect_inverse_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- normal mode - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -int osi_config_l2_da_perfect_inverse_match(struct osi_core_priv_data *osi_core, - unsigned int perfect_inverse_match); - /** * @brief osi_update_vlan_id - invoke osi call to update VLAN ID * @@ -1175,4 +965,39 @@ int osi_ptp_configuration(struct osi_core_priv_data *osi_core, */ struct osi_core_ops *eqos_get_hw_core_ops(void); void *eqos_get_core_safety_config(void); + +/** + * @brief osi_l3l4_filter - invoke OSI call to add L3/L4 + * filters. + * + * 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] 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 + * @param[in] is_l4_filter: API call for L3 filter(0) or L4 filter(1) + * + * @note + * 1) MAC should be init and started. see osi_start_mac() + * 2) Concurrent invocations to configure filters is not supported. + * OSD driver shall serialize calls. + * + * @retval 0 on success + * @retval -1 on failure. + */ +int osi_l3l4_filter(struct osi_core_priv_data *osi_core, + struct osi_l3_l4_filter l_filter, + unsigned int type, + unsigned int dma_routing_enable, unsigned int dma_chan, + unsigned int is_l4_filter); + #endif /* OSI_CORE_H */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 0c42706..cb759a0 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1392,6 +1392,9 @@ static int eqos_core_init(struct osi_core_priv_data *osi_core, /* configure EQOS DMA */ eqos_configure_dma(osi_core->base); + /* initialize L3L4 Filters variable */ + osi_core->l3l4_filter_bitmask = OSI_NONE; + return ret; } @@ -1709,6 +1712,37 @@ static int eqos_set_avb_algorithm(struct osi_core_priv_data *osi_core, return 0; } +/** + * @brief eqos_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] base: Base address from 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() + * + * @retval 0 always + */ +static inline int eqos_config_l2_da_perfect_inverse_match(void *base, + unsigned int + perfect_inverse_match) +{ + unsigned int value = 0U; + + value = osi_readl((unsigned char *)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(value, (unsigned char *)base + EQOS_MAC_PFR, + EQOS_MAC_PFR_IDX); + + return 0; +} + /** * @brief eqos_config_mac_pkt_filter_reg - configure mac filter register. * @@ -1717,34 +1751,63 @@ static int eqos_set_avb_algorithm(struct osi_core_priv_data *osi_core, * hash unicast/multicast. * * @param[in] osi_core: OSI core private data structure. - * @param[in] pfilter: OSI filter structure. + * @param[in] filter: OSI filter structure. * * @note 1) MAC should be initialized and started. see osi_start_mac() - * 2) MAC addresses should be configured in HW registers. see - * osi_update_mac_addr_low_high_reg(). + * + * @retval 0 always */ -static void eqos_config_mac_pkt_filter_reg(struct osi_core_priv_data *osi_core, - struct osi_filter pfilter) +static int eqos_config_mac_pkt_filter_reg(struct osi_core_priv_data *osi_core, + struct osi_filter *filter) { unsigned int value = 0U; + int ret = 0; value = osi_readl((unsigned char *)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); - value |= (pfilter.pr_mode & EQOS_MAC_PFR_PR) | - ((pfilter.huc_mode << EQOS_MAC_PFR_HUC_SHIFT) & - EQOS_MAC_PFR_HUC) | - ((pfilter.hmc_mode << EQOS_MAC_PFR_HMC_SHIFT) & - EQOS_MAC_PFR_HMC) | - ((pfilter.pm_mode << EQOS_MAC_PFR_PM_SHIFT) & - EQOS_MAC_PFR_PM) | - ((pfilter.hpf_mode << EQOS_MAC_PFR_HPF_SHIFT) & - EQOS_MAC_PFR_HPF); + + 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(value, (unsigned char *)osi_core->base + - EQOS_MAC_PFR, EQOS_MAC_PFR_IDX); + EQOS_MAC_PFR, EQOS_MAC_PFR_IDX); + + if ((filter->oper_mode & OSI_OPER_EN_L2_DA_INV) != 0x0U) { + ret = eqos_config_l2_da_perfect_inverse_match(osi_core->base, + OSI_INV_MATCH); + } + + if ((filter->oper_mode & OSI_OPER_DIS_L2_DA_INV) != 0x0U) { + ret = eqos_config_l2_da_perfect_inverse_match(osi_core->base, + OSI_PFT_MATCH); + } + + return ret; } /** @@ -1760,11 +1823,11 @@ static void eqos_config_mac_pkt_filter_reg(struct osi_core_priv_data *osi_core, * @param[in] dma_routing_enable: dma channel routing enable(1) * @param[in] dma_chan: dma channel number * @param[in] addr_mask: filter will not consider byte in comparison - * Bit 29: MAC_Address${i}_High[15:8] - * Bit 28: MAC_Address${i}_High[7:0] - * Bit 27: MAC_Address${i}_Low[31:24] + * 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 24: MAC_Address${i}_Low[7:0] + * Bit 0: MAC_Address${i}_Low[7:0] * * @note 1) MAC should be initialized and stated. see osi_start_mac() * 2) osi_core->osd should be populated. @@ -1827,17 +1890,7 @@ err_dma_chan: * performed before updating DCS bits. * * @param[in] osi_core: OSI core private data structure. - * @param[in] idx: filter index - * @param[in] addr: MAC address to write - * @param[in] dma_routing_enable: dma channel routing enable(1) - * @param[in] dma_chan: dma channel number - * @param[in] addr_mask: filter will not consider byte in comparison - * Bit 29: MAC_Address${i}_High[15:8] - * Bit 28: MAC_Address${i}_High[7:0] - * Bit 27: MAC_Address${i}_Low[31:24] - * .. - * Bit 24: MAC_Address${i}_Low[7:0] - * @param[in] src_dest: SA(1) or DA(0) + * @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. @@ -1847,12 +1900,14 @@ err_dma_chan: */ static int eqos_update_mac_addr_low_high_reg( struct osi_core_priv_data *osi_core, - unsigned int idx, - const unsigned char addr[], - unsigned int dma_routing_enable, - unsigned int dma_chan, - unsigned int addr_mask, unsigned int src_dest) + struct osi_filter *filter) { + unsigned int idx = filter->index; + unsigned int dma_routing_enable = filter->dma_routing; + unsigned int dma_chan = filter->dma_chan; + unsigned int addr_mask = filter->addr_mask; + unsigned int src_dest = filter->src_dest; + const unsigned char *addr = filter->mac_address; unsigned int value = 0x0U; int ret = 0; @@ -2073,36 +2128,6 @@ static int eqos_config_l3_l4_filter_enable(void *base, return 0; } -/** - * @brief eqos_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] base: Base address from OSI core private data structure. - * @param[in] perfect_inverse_match: 1 - inverse mode 0- normal mode - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int eqos_config_l2_da_perfect_inverse_match(void *base, unsigned int - perfect_inverse_match) -{ - unsigned int value = 0U; - - value = osi_readl((unsigned char *)base + EQOS_MAC_PFR); - value &= ~EQOS_MAC_PFR_DAIF; - value |= ((perfect_inverse_match << EQOS_MAC_PFR_DAIF_SHIFT) & - EQOS_MAC_PFR_DAIF); - eqos_core_safety_writel(value, (unsigned char *)base + EQOS_MAC_PFR, - EQOS_MAC_PFR_IDX); - - return 0; -} - /** * @brief eqos_update_ip4_addr - configure register for IPV4 address filtering * @@ -2115,8 +2140,6 @@ static int eqos_config_l2_da_perfect_inverse_match(void *base, unsigned int * @param[in] src_dst_addr_match: 0 - source addr otherwise - dest addr * * @note 1) MAC should be init and started. see osi_start_mac() - * 2) L3/L4 filtering should be enabled in MAC PFR register. See - * osi_config_l3_l4_filter_enable() * * @retval 0 on success * @retval -1 on failure. @@ -2173,8 +2196,6 @@ static int eqos_update_ip4_addr(struct osi_core_priv_data *osi_core, * @param[in] addr: ipv6 adderss * * @note 1) MAC should be init and started. see osi_start_mac() - * 2) L3/L4 filtering should be enabled in MAC PFR register. See - * osi_config_l3_l4_filter_enable() * * @retval 0 on success * @retval -1 on failure. @@ -2240,10 +2261,8 @@ static int eqos_update_ip6_addr(struct osi_core_priv_data *osi_core, * @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) L3/L4 filtering should be enabled in MAC PFR register. See - * osi_config_l3_l4_filter_enable() - * 3) osi_core->osd should be populated - * 4) DCS bits should be enabled in RXQ to DMA mapping register + * 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. @@ -2292,7 +2311,8 @@ static int eqos_update_l4_port_no(struct osi_core_priv_data *osi_core, * * @note 1) MAC IP should be out of reset and need to be initialized * as the requirements. - * 2) DCS bits should be enabled in RXQ to DMA mapping register + * 2) DCS bit of RxQ should be enabled for dynamic channel selection + * in filter support * *@return updated unsigned int value */ @@ -2314,6 +2334,37 @@ static inline unsigned int eqos_set_dcs(struct osi_core_priv_data *osi_core, return value; } + +/** + * @brief eqos_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 eqos_helper_l3l4_bitmask(unsigned int *bitmask, + unsigned int filter_no, + unsigned int value) +{ + unsigned int 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; + } +} + /** * @brief eqos_config_l3_filters - config L3 filters. * @@ -2332,10 +2383,9 @@ static inline unsigned int eqos_set_dcs(struct osi_core_priv_data *osi_core, * @param[in] dma_chan: dma channel for routing based on filter * * @note 1) MAC should be init and started. see osi_start_mac() - * 2) L3/L4 filtering should be enabled in MAC PFR register. See - * osi_config_l3_l4_filter_enable() - * 3) osi_core->osd should be populated - * 4) DCS bits should be enabled in RXQ to DMA map register + * 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. @@ -2484,11 +2534,15 @@ static int eqos_config_l3_filters(struct osi_core_priv_data *osi_core, } } + /* 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 osi_config_l4_filters - Config L4 filters. + * @brief eqos_config_l4_filters - Config L4 filters. * * Algorithm: This sequence is used to configure L4(TCP/UDP) filters for * SA and DA Port Number matching @@ -2503,9 +2557,7 @@ static int eqos_config_l3_filters(struct osi_core_priv_data *osi_core, * @param[in] dma_chan: dma channel for routing based on filter * * @note 1) MAC should be init and started. see osi_start_mac() - * 2) L3/L4 filtering should be enabled in MAC PFR register. See - * osi_config_l3_l4_filter_enable() - * 3) osi_core->osd should be populated + * 2) osi_core->osd should be populated * * @retval 0 on success * @retval -1 on failure. @@ -2596,6 +2648,9 @@ static int eqos_config_l4_filters(struct osi_core_priv_data *osi_core, 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; } @@ -3166,8 +3221,6 @@ static struct osi_core_ops eqos_core_ops = { .config_mac_pkt_filter_reg = eqos_config_mac_pkt_filter_reg, .update_mac_addr_low_high_reg = eqos_update_mac_addr_low_high_reg, .config_l3_l4_filter_enable = eqos_config_l3_l4_filter_enable, - .config_l2_da_perfect_inverse_match = - eqos_config_l2_da_perfect_inverse_match, .config_l3_filters = eqos_config_l3_filters, .update_ip4_addr = eqos_update_ip4_addr, .update_ip6_addr = eqos_update_ip6_addr, diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 0d49f5b..ed63283 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -286,11 +286,6 @@ #define EQOS_MAC_PFR_IPFE OSI_BIT(20) #define EQOS_MAC_PFR_DNTU OSI_BIT(21) #define EQOS_MAC_PFR_RA OSI_BIT(31) -#define EQOS_MAC_PFR_HUC_SHIFT 1 -#define EQOS_MAC_PFR_HMC_SHIFT 2 -#define EQOS_MAC_PFR_DAIF_SHIFT 3 -#define EQOS_MAC_PFR_PM_SHIFT 4 -#define EQOS_MAC_PFR_HPF_SHIFT 10 #define EQOS_MAC_L4_SP_MASK 0x0000FFFFU #define EQOS_MAC_L4_DP_MASK 0xFFFF0000U #define EQOS_MAC_L4_DP_SHIFT 16 @@ -341,6 +336,11 @@ 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) | \ diff --git a/osi/core/libnvethernetrm.export b/osi/core/libnvethernetrm.export index ebf9ce7..78c1fe6 100644 --- a/osi/core/libnvethernetrm.export +++ b/osi/core/libnvethernetrm.export @@ -47,16 +47,9 @@ osi_get_hw_features osi_config_arp_offload osi_config_rxcsum_offload osi_configure_flow_control -osi_config_mac_pkt_filter_reg -osi_update_mac_addr_low_high_reg -osi_config_l3_l4_filter_enable -osi_config_l3_filters -osi_update_ip4_addr -osi_update_ip6_addr -osi_config_l4_filters -osi_update_l4_port_no +osi_l2_filter +osi_l3l4_filter osi_config_vlan_filtering -osi_config_l2_da_perfect_inverse_match osi_update_vlan_id osi_config_fw_err_pkts osi_ptp_configuration diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 6891895..57eed58 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -428,182 +428,191 @@ int osi_config_arp_offload(struct osi_core_priv_data *osi_core, return -1; } -int osi_config_mac_pkt_filter_reg(struct osi_core_priv_data *osi_core, - struct osi_filter pfilter) +int osi_l2_filter(struct osi_core_priv_data *osi_core, + struct osi_filter *filter) { - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->config_mac_pkt_filter_reg != OSI_NULL)) { - osi_core->ops->config_mac_pkt_filter_reg(osi_core, - pfilter); - return 0; + struct osi_core_ops *op; + int ret = -1; + + if (osi_core == OSI_NULL || osi_core->ops == OSI_NULL || + filter == OSI_NULL) { + return ret; } - return -1; + op = osi_core->ops; + + if ((op->config_mac_pkt_filter_reg != OSI_NULL)) { + ret = op->config_mac_pkt_filter_reg(osi_core, filter); + } else { + OSI_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "op->config_mac_pkt_filter_reg is null\n", 0ULL); + return ret; + } + + if ((filter->oper_mode & OSI_OPER_ADDR_UPDATE) != OSI_NONE) { + ret = -1; + + if ((filter->dma_routing == OSI_ENABLE) && + (osi_core->dcs_en != OSI_ENABLE)) { + OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "DCS requested. Conflicts with DT config\n", + 0ULL); + return ret; + } + + if ((op->update_mac_addr_low_high_reg != OSI_NULL)) { + ret = op->update_mac_addr_low_high_reg(osi_core, + filter); + } else { + OSI_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "op->update_mac_addr_low_high_reg is null\n", + 0ULL); + } + } + + return ret; } -int osi_update_mac_addr_low_high_reg(struct osi_core_priv_data *osi_core, - unsigned int index, - const unsigned char value[], - unsigned int dma_routing_enable, - unsigned int dma_chan, - unsigned int addr_mask, - unsigned int src_dest) +static inline int helper_l4_filter(struct osi_core_priv_data *osi_core, + struct osi_l3_l4_filter l_filter, + unsigned int type, + unsigned int dma_routing_enable, + unsigned int dma_chan) +{ + struct osi_core_ops *op = osi_core->ops; + + if (op->config_l4_filters != OSI_NULL) { + if (op->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) < 0) { + return -1; + } + } else { + OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "op->config_l4_filters is NULL\n", 0ULL); + return -1; + } + + if (op->update_l4_port_no != OSI_NULL) { + return op->update_l4_port_no(osi_core, + l_filter.filter_no, + l_filter.port_no, + l_filter.src_dst_addr_match); + } else { + OSI_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "op->update_l4_port_no is NULL\n", 0ULL); + return -1; + } + +} + +static inline int helper_l3_filter(struct osi_core_priv_data *osi_core, + struct osi_l3_l4_filter l_filter, + unsigned int type, + unsigned int dma_routing_enable, + unsigned int dma_chan) +{ + struct osi_core_ops *op = osi_core->ops; + + if ((op->config_l3_filters != OSI_NULL)) { + if (op->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) < 0) { + return -1; + } + } else { + OSI_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "op->config_l3_filters is NULL\n", 0ULL); + return -1; + } + + if (type == OSI_IP6_FILTER) { + if (op->update_ip6_addr != OSI_NULL) { + return op->update_ip6_addr(osi_core, l_filter.filter_no, + l_filter.ip6_addr); + } else { + OSI_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "op->update_ip6_addr is NULL\n", 0ULL); + return -1; + } + } else if (type == OSI_IP4_FILTER) { + if (op->update_ip4_addr != OSI_NULL) { + return op->update_ip4_addr(osi_core, + l_filter.filter_no, + l_filter.ip4_addr, + l_filter.src_dst_addr_match); + } else { + OSI_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "op->update_ip4_addr is NULL\n", + 0ULL); + return -1; + } + } else { + return -1; + } +} + +int osi_l3l4_filter(struct osi_core_priv_data *osi_core, + struct osi_l3_l4_filter l_filter, unsigned int type, + unsigned int dma_routing_enable, unsigned int dma_chan, + unsigned int is_l4_filter) { int ret = -1; - if (osi_core == OSI_NULL) { + if ((osi_core == OSI_NULL) || (osi_core->ops == OSI_NULL)) { return ret; } if ((dma_routing_enable == OSI_ENABLE) && (osi_core->dcs_en != OSI_ENABLE)) { - OSI_ERR(osi_core->osd, - OSI_LOG_ARG_INVALID, + OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "dma routing enabled but dcs disabled in DT\n", 0ULL); return ret; } - if ((osi_core->ops != OSI_NULL) && - (osi_core->ops->update_mac_addr_low_high_reg != OSI_NULL)) { - return osi_core->ops->update_mac_addr_low_high_reg( - osi_core, - index, - value, - dma_routing_enable, - dma_chan, - addr_mask, - src_dest); + if (is_l4_filter == OSI_ENABLE) { + ret = helper_l4_filter(osi_core, l_filter, type, + dma_routing_enable, dma_chan); + } else { + ret = helper_l3_filter(osi_core, l_filter, type, + dma_routing_enable, dma_chan); } - return -1; -} - -int osi_config_l3_l4_filter_enable(struct osi_core_priv_data *osi_core, - unsigned int enable) -{ - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->config_l3_l4_filter_enable != OSI_NULL)) { - return osi_core->ops->config_l3_l4_filter_enable(osi_core->base, - enable); - } - - return -1; -} - -int osi_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) -{ - int ret = -1; - - if (osi_core == OSI_NULL) { + if (ret < 0) { + OSI_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "L3/L4 helper function failed\n", 0ULL); return ret; } - if ((dma_routing_enable == OSI_ENABLE) && - (osi_core->dcs_en != OSI_ENABLE)) { - OSI_ERR(osi_core->osd, - OSI_LOG_ARG_INVALID, - "dma routing enabled but dcs disabled in DT\n", - 0ULL); - return ret; + if (osi_core->ops->config_l3_l4_filter_enable != OSI_NULL) { + if (osi_core->l3l4_filter_bitmask != OSI_DISABLE) { + ret = osi_core->ops->config_l3_l4_filter_enable( + osi_core->base, + OSI_ENABLE); + } else { + ret = osi_core->ops->config_l3_l4_filter_enable( + osi_core->base, + OSI_DISABLE); + } + + } else { + OSI_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "op->config_l3_l4_filter_enable is NULL\n", 0ULL); + ret = -1; } - if ((osi_core->ops != OSI_NULL) && - (osi_core->ops->config_l3_filters != OSI_NULL)) { - return osi_core->ops->config_l3_filters(osi_core, filter_no, - enb_dis, - ipv4_ipv6_match, - src_dst_addr_match, - perfect_inverse_match, - dma_routing_enable, - dma_chan); - } - - return -1; -} - -int osi_update_ip4_addr(struct osi_core_priv_data *osi_core, - unsigned int filter_no, - unsigned char addr[], - unsigned int src_dst_addr_match) -{ - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->update_ip4_addr != OSI_NULL)) { - return osi_core->ops->update_ip4_addr(osi_core, filter_no, - addr, src_dst_addr_match); - } - - return -1; -} - -int osi_update_ip6_addr(struct osi_core_priv_data *osi_core, - unsigned int filter_no, - unsigned short addr[]) -{ - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->update_ip6_addr != OSI_NULL)) { - return osi_core->ops->update_ip6_addr(osi_core, filter_no, - addr); - } - return -1; -} - -int osi_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) -{ - int ret = -1; - - if (osi_core == OSI_NULL) { - return ret; - } - - if ((dma_routing_enable == OSI_ENABLE) && - (osi_core->dcs_en != OSI_ENABLE)) { - OSI_ERR(osi_core->osd, - OSI_LOG_ARG_INVALID, - "dma routing enabled but dcs disabled in DT\n", - 0ULL); - return ret; - } - - if ((osi_core->ops != OSI_NULL) && - (osi_core->ops->config_l4_filters != OSI_NULL)) { - return osi_core->ops->config_l4_filters(osi_core, filter_no, - enb_dis, tcp_udp_match, - src_dst_port_match, - perfect_inverse_match, - dma_routing_enable, - dma_chan); - } - - return -1; -} - -int osi_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) -{ - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->update_l4_port_no != OSI_NULL)) { - return osi_core->ops->update_l4_port_no(osi_core, filter_no, - port_no, - src_dst_port_match); - } - - return -1; + return ret; } int osi_config_vlan_filtering(struct osi_core_priv_data *osi_core, @@ -623,19 +632,6 @@ int osi_config_vlan_filtering(struct osi_core_priv_data *osi_core, return -1; } -int osi_config_l2_da_perfect_inverse_match(struct osi_core_priv_data *osi_core, - unsigned int perfect_inverse_match) -{ - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->config_l2_da_perfect_inverse_match != OSI_NULL)) { - return osi_core->ops->config_l2_da_perfect_inverse_match( - osi_core->base, - perfect_inverse_match); - } - - return -1; -} - int osi_config_rxcsum_offload(struct osi_core_priv_data *osi_core, unsigned int enable) { From 5eb4c4acdee8b5011da9d1f7c6785265db2e8a6f Mon Sep 17 00:00:00 2001 From: Srinivas Ramachandran <srinivasra@nvidia.com> Date: Thu, 3 Oct 2019 12:15:44 -0700 Subject: [PATCH 055/458] nvethernetrm: Remove APIs that micro-manage the controller Issue: APIs like osi_clear_tx/rx_intr, osi_update_rx_tailptr are redundant. The operations that are done in these functions can be included as part of other existing OSD-OSI interface API. OSD need not micro-manage the hardware controller by using such fine grain APIs. Fix: Remove the redundant APIs and implement their functionality as part of existing APIs. Bug 2715391 Change-Id: I47851c204988475cac1cadf6fe678d7d446a3cc3 Signed-off-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2211093 Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_dma.h | 87 ++++++--------------------- osi/dma/eqos_dma.c | 94 +++++++++-------------------- osi/dma/libnvethernetcl.export | 3 - osi/dma/osi_dma.c | 106 ++++++++++++++++----------------- osi/dma/osi_dma_txrx.c | 6 +- 5 files changed, 100 insertions(+), 196 deletions(-) diff --git a/include/osi_dma.h b/include/osi_dma.h index fed57f4..85fe779 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -81,6 +81,18 @@ #define OSI_CHECKSUM_UNNECESSARY 0x1U /** @} */ +/** + * @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_PTP OSI_BIT(0) +#define OSI_RX_SWCX_BUF_VALID OSI_BIT(1) +/** @} */ + /** * @brief OSI packet error stats */ @@ -133,8 +145,8 @@ struct osi_rx_swcx { void *buf_virt_addr; /** Length of buffer */ unsigned int len; - /** PTP software context */ - unsigned int ptp_swcx; + /** Flags to share info about Rx swcx between OSD and OSI */ + unsigned int flags; }; /** @@ -280,10 +292,6 @@ struct osi_dma_chan_ops { /** Called to update Rx ring tail pointer */ void (*update_rx_tailptr)(void *addr, unsigned int chan, unsigned long tailptr); - /** Called to clear Tx interrupt source */ - void (*clear_tx_intr)(void *addr, unsigned int chan); - /** Called to clear Rx interrupt source */ - void (*clear_rx_intr)(void *addr, unsigned int chan); /** Called to disable DMA Tx channel interrupts at wrapper level */ void (*disable_chan_tx_intr)(void *addr, unsigned int chan); /** Called to enable DMA Tx channel interrupts at wrapper level */ @@ -442,44 +450,6 @@ int osi_disable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, int osi_enable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, unsigned int chan); -/** - * @brief osi_clear_tx_intr - Handles 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. - */ -int osi_clear_tx_intr(struct osi_dma_priv_data *osi_dma, - unsigned int chan); - -/** - * @brief osi_clear_rx_intr - Handles 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. - */ -int osi_clear_rx_intr(struct osi_dma_priv_data *osi_dma, - unsigned int chan); - /** * @brief Start DMA * @@ -535,9 +505,9 @@ unsigned int osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring); * * Algorithm: Initialise a Rx DMA descriptor. * - * @param[in] rx_swcx: OSI DMA Rx ring software context - * @param[in] rx_desc: OSI DMA Rx ring descriptor - * @param[in] use_riwt: to enable Rx WDT and disable IOC + * @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 * 1) MAC needs to be out of reset and proper clocks need to be configured. @@ -547,27 +517,8 @@ unsigned int osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring); * @retval 0 on success * @retval -1 on failure. */ -int osi_rx_dma_desc_init(struct osi_rx_swcx *rx_swcx, - struct osi_rx_desc *rx_desc, - unsigned int use_riwt); - -/** - * @brief osi_update_rx_tailptr - Updates DMA Rx ring tail pointer - * - * @param[in] osi_dma: OSI DMA private data struture. - * @param[in] rx_ring: Pointer to DMA Rx ring. - * @param[in] chan: DMA 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. - */ -int osi_update_rx_tailptr(struct osi_dma_priv_data *osi_dma, - struct osi_rx_ring *rx_ring, - unsigned int chan); +int osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, + struct osi_rx_ring *rx_ring, unsigned int chan); /** * @brief Updates rx buffer length. diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index e86f957..913546d 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -201,10 +201,23 @@ static int eqos_validate_dma_regs(struct osi_dma_priv_data *osi_dma) */ static void eqos_disable_chan_tx_intr(void *addr, unsigned int chan) { - unsigned int cntrl; + unsigned int cntrl, status; CHECK_CHAN_BOUND(chan); + /* Clear irq before disabling */ + status = osi_readl((unsigned char *)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, + (unsigned char *)addr + EQOS_DMA_CHX_STATUS(chan)); + osi_writel(EQOS_VIRT_INTR_CHX_STATUS_TX, + (unsigned char *)addr + + EQOS_VIRT_INTR_CHX_STATUS(chan)); + } + + /* Disable the irq */ cntrl = osi_readl((unsigned char *)addr + EQOS_VIRT_INTR_CHX_CNTRL(chan)); cntrl &= ~EQOS_VIRT_INTR_CHX_CNTRL_TX; @@ -251,10 +264,23 @@ static void eqos_enable_chan_tx_intr(void *addr, unsigned int chan) */ static void eqos_disable_chan_rx_intr(void *addr, unsigned int chan) { - unsigned int cntrl; + unsigned int cntrl, status; CHECK_CHAN_BOUND(chan); + /* Clear irq before disabling */ + status = osi_readl((unsigned char *)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, + (unsigned char *)addr + EQOS_DMA_CHX_STATUS(chan)); + osi_writel(EQOS_VIRT_INTR_CHX_STATUS_RX, + (unsigned char *)addr + + EQOS_VIRT_INTR_CHX_STATUS(chan)); + } + + /* Disable irq */ cntrl = osi_readl((unsigned char *)addr + EQOS_VIRT_INTR_CHX_CNTRL(chan)); cntrl &= ~EQOS_VIRT_INTR_CHX_CNTRL_RX; @@ -285,68 +311,6 @@ static void eqos_enable_chan_rx_intr(void *addr, unsigned int chan) EQOS_VIRT_INTR_CHX_CNTRL(chan)); } -/** - * @brief eqos_clear_tx_intr - Handle EQOS DMA Tx channel interrupts. - * - * Algorithm: Clear DMA Tx interrupt source at wrapper and DMA level. - * - * @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 eqos_clear_tx_intr(void *addr, unsigned int chan) -{ - unsigned int status; - - CHECK_CHAN_BOUND(chan); - - status = osi_readl((unsigned char *)addr + - EQOS_VIRT_INTR_CHX_STATUS(chan)); - if ((status & EQOS_VIRT_INTR_CHX_STATUS_TX) == 1U) { - osi_writel(EQOS_DMA_CHX_STATUS_CLEAR_TX, - (unsigned char *)addr + EQOS_DMA_CHX_STATUS(chan)); - osi_writel(EQOS_VIRT_INTR_CHX_STATUS_TX, - (unsigned char *)addr + - EQOS_VIRT_INTR_CHX_STATUS(chan)); - } -} - -/** - * @brief eqos_clear_rx_intr - Handles DMA Rx channel interrupts. - * - * Algorithm: Clear DMA Rx interrupt source at wrapper and DMA level. - * - * @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 eqos_clear_rx_intr(void *addr, unsigned int chan) -{ - unsigned int status; - - CHECK_CHAN_BOUND(chan); - - status = osi_readl((unsigned char *)addr + - EQOS_VIRT_INTR_CHX_STATUS(chan)); - if ((status & EQOS_VIRT_INTR_CHX_STATUS_RX) == 2U) { - osi_writel(EQOS_DMA_CHX_STATUS_CLEAR_RX, - (unsigned char *)addr + EQOS_DMA_CHX_STATUS(chan)); - osi_writel(EQOS_VIRT_INTR_CHX_STATUS_RX, - (unsigned char *)addr + - EQOS_VIRT_INTR_CHX_STATUS(chan)); - } -} - /** * @brief eqos_set_tx_ring_len - Set DMA Tx ring length. * @@ -728,8 +692,6 @@ static struct osi_dma_chan_ops eqos_dma_chan_ops = { .set_rx_ring_start_addr = eqos_set_rx_ring_start_addr, .update_tx_tailptr = eqos_update_tx_tailptr, .update_rx_tailptr = eqos_update_rx_tailptr, - .clear_tx_intr = eqos_clear_tx_intr, - .clear_rx_intr = eqos_clear_rx_intr, .disable_chan_tx_intr = eqos_disable_chan_tx_intr, .enable_chan_tx_intr = eqos_enable_chan_tx_intr, .disable_chan_rx_intr = eqos_disable_chan_rx_intr, diff --git a/osi/dma/libnvethernetcl.export b/osi/dma/libnvethernetcl.export index 342397e..b4f009a 100644 --- a/osi/dma/libnvethernetcl.export +++ b/osi/dma/libnvethernetcl.export @@ -27,13 +27,10 @@ osi_disable_chan_tx_intr osi_enable_chan_tx_intr osi_disable_chan_rx_intr osi_enable_chan_rx_intr -osi_clear_tx_intr -osi_clear_rx_intr osi_start_dma osi_stop_dma osi_get_refill_rx_desc_cnt osi_rx_dma_desc_init -osi_update_rx_tailptr osi_set_rx_buf_len osi_hw_transmit osi_process_tx_completions diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 594f49c..9fee4bb 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -145,30 +145,6 @@ int osi_enable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, return -1; } -int osi_clear_tx_intr(struct osi_dma_priv_data *osi_dma, - unsigned int chan) -{ - if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && - (osi_dma->ops->clear_tx_intr != OSI_NULL)) { - osi_dma->ops->clear_tx_intr(osi_dma->base, chan); - return 0; - } - - return -1; -} - -int osi_clear_rx_intr(struct osi_dma_priv_data *osi_dma, - unsigned int chan) -{ - if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && - (osi_dma->ops->clear_rx_intr != OSI_NULL)) { - osi_dma->ops->clear_rx_intr(osi_dma->base, chan); - return 0; - } - - return -1; -} - int osi_start_dma(struct osi_dma_priv_data *osi_dma, unsigned int chan) { @@ -203,14 +179,43 @@ unsigned int osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring) return (rx_ring->cur_rx_idx - rx_ring->refill_idx) & (RX_DESC_CNT - 1U); } -int osi_rx_dma_desc_init(struct osi_rx_swcx *rx_swcx, - struct osi_rx_desc *rx_desc, - unsigned int use_riwt) +int osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, + struct osi_rx_ring *rx_ring, unsigned int chan) { /* for CERT-C error */ unsigned long temp; + unsigned long tailptr = 0; + struct osi_rx_swcx *rx_swcx = OSI_NULL; + struct osi_rx_desc *rx_desc = OSI_NULL; - if (rx_swcx != OSI_NULL && rx_desc != OSI_NULL) { + /* Validate args */ + if (!(osi_dma != OSI_NULL && osi_dma->ops != OSI_NULL && + osi_dma->ops->update_rx_tailptr != OSI_NULL)) { + return -1; + } + + if (!(rx_ring != OSI_NULL && rx_ring->rx_swcx != OSI_NULL && + rx_ring->rx_desc != OSI_NULL)) { + return -1; + } + + if (chan >= OSI_EQOS_MAX_NUM_CHANS) { + return -1; + } + + /* Refill buffers */ + while (rx_ring->refill_idx != rx_ring->cur_rx_idx) { + 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 */ temp = L32(rx_swcx->buf_phy_addr); if (temp > UINT_MAX) { /* error case do nothing */ @@ -224,43 +229,32 @@ int osi_rx_dma_desc_init(struct osi_rx_swcx *rx_swcx, } else { rx_desc->rdes1 = (unsigned int)temp; } + rx_desc->rdes2 = 0; rx_desc->rdes3 = (RDES3_OWN | RDES3_IOC | RDES3_B1V); - } else { - return -1; - } - /* reset IOC bit if RWIT is enabled */ - if (use_riwt == OSI_ENABLE) { - rx_desc->rdes3 &= ~RDES3_IOC; + + /* reset IOC bit if RWIT is enabled */ + if (osi_dma->use_riwt == OSI_ENABLE) { + rx_desc->rdes3 &= ~RDES3_IOC; + } + + INCR_RX_DESC_INDEX(rx_ring->refill_idx, 1U); } - return 0; -} - -int osi_update_rx_tailptr(struct osi_dma_priv_data *osi_dma, - struct osi_rx_ring *rx_ring, - unsigned int chan) -{ - unsigned long tailptr = 0; - unsigned int refill_idx = rx_ring->refill_idx; - - if (refill_idx >= RX_DESC_CNT) { - return -1; - } - - DECR_RX_DESC_INDEX(refill_idx, 1U); + /* 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 + - (refill_idx * sizeof(struct osi_rx_desc)); + (sizeof(struct osi_rx_desc) * (RX_DESC_CNT)); + if (tailptr < rx_ring->rx_desc_phy_addr) { + /* Will not hit this case, used for CERT-C compliance */ return -1; } - if (osi_dma != OSI_NULL && osi_dma->ops != OSI_NULL && - osi_dma->ops->update_rx_tailptr != OSI_NULL) { - osi_dma->ops->update_rx_tailptr(osi_dma->base, chan, tailptr); - } else { - return -1; - } + osi_dma->ops->update_rx_tailptr(osi_dma->base, chan, tailptr); return 0; } diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 7092bc6..daab896 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -249,7 +249,7 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, * software context addresses directly since * those are valid. */ - ptp_rx_swcx->ptp_swcx = 1; + ptp_rx_swcx->flags |= OSI_RX_SWCX_PTP; /* Context descriptor was consumed. Its skb * and DMA mapping will be recycled */ @@ -764,11 +764,11 @@ static int rx_dma_desc_initialization(struct osi_dma_priv_data *osi, rx_desc->rdes3 &= ~RDES3_IOC; } - rx_swcx->ptp_swcx = 0; + rx_swcx->flags = 0; } tailptr = rx_ring->rx_desc_phy_addr + - sizeof(struct osi_rx_desc) * (RX_DESC_CNT - 1U); + sizeof(struct osi_rx_desc) * (RX_DESC_CNT); if (tailptr < rx_ring->rx_desc_phy_addr) { /* Will not hit this case */ return -1; From 9e8691aa3d1a48bec2523915c497b6ef6b9e8a1d Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Mon, 21 Oct 2019 11:27:50 +0530 Subject: [PATCH 056/458] nvethernetrm: Add slot function support Issue: Data packets sent via EQOS hardware are not following any packet gaping. The AVB use-cases have different timing requirements for class A data packets. For example, the time difference between two class A data packets are supposed to be 125 microseconds for audio data of frequency 48 kHz. Fix: Add slot function support to schedule the data fetching from the system memory by the DMA. This will help the AVB SW stack timing requirements for class A data. Bug 200545374 Change-Id: Id7c606f7491a423051667811bd6d459ee58f6700 Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2222282 Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_common.h | 22 +++++++++++ include/osi_dma.h | 40 ++++++++++++++++++++ osi/core/eqos_core.c | 68 ++++++++++++++++++++-------------- osi/core/eqos_core.h | 13 ------- osi/dma/eqos_dma.c | 48 ++++++++++++++++++++++++ osi/dma/eqos_dma.h | 4 ++ osi/dma/libnvethernetcl.export | 1 + osi/dma/osi_dma.c | 65 ++++++++++++++++++++++++++++++++ osi/dma/osi_dma_txrx.c | 19 +++++++++- 9 files changed, 237 insertions(+), 43 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index 061c63e..d1f5ede 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -269,6 +269,28 @@ #define EQOS_MAC_HFR2_AUXSNAPNUM_MASK 0x7U /** @} */ +/** + * @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 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 +/** @} */ + /** * @brief struct osi_hw_features - MAC HW supported features. */ diff --git a/include/osi_dma.h b/include/osi_dma.h index 85fe779..74144e7 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -51,6 +51,17 @@ #define OSI_PKT_CX_PTP OSI_BIT(3) /** @} */ +/** + * @addtogroup SLOT function context fields + * + * @brief These flags are used for DMA channel Slot context configuration + * @{ + */ +#define OSI_SLOT_INTVL_DEFAULT 125U +#define OSI_SLOT_INTVL_MAX 4095U +#define OSI_SLOT_NUM_MAX 16U +/** @} */ + /** * @addtogroup EQOS-TX Tx done packet context fields * @@ -262,6 +273,10 @@ struct osi_tx_ring { unsigned int cur_tx_idx; /** Descriptor index for descriptor cleanup */ unsigned int clean_idx; + /** Slot function check */ + unsigned int slot_check; + /** Slot number */ + unsigned int slot_number; /** Transmit packet context */ struct osi_tx_pkt_cx tx_pkt_cx; /** Transmit complete packet context information */ @@ -311,6 +326,11 @@ struct osi_dma_chan_ops { /** Called periodically to read and validate safety critical * registers against last written value */ int (*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, + unsigned int chan, + unsigned int set, + unsigned int interval); }; /** @@ -348,6 +368,10 @@ struct osi_dma_priv_data { /** 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 */ + unsigned int slot_interval[OSI_EQOS_MAX_NUM_CHANS]; + /** Array of DMA channel slot enabled status from DT*/ + unsigned int slot_enabled[OSI_EQOS_MAX_NUM_CHANS]; }; /** @@ -691,6 +715,22 @@ int osi_init_dma_ops(struct osi_dma_priv_data *osi_dma); */ int osi_clear_tx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); +/** + * @brief osi_config_slot_function - Configure slot function + * + * Algorithm: Set or reset the slot function based on set input + * + * @param[in] osi_dma: OSI DMA private data structure. + * @param[in] set: Flag to set with OSI_ENABLE and reset with OSI_DISABLE + * + * @note MAC should be init and started. see osi_start_mac() + * + * @retval 0 on success + * @retval -1 on failure. + */ +int osi_config_slot_function(struct osi_dma_priv_data *osi_dma, + unsigned int set); + /** * @brief osi_clear_rx_pkt_err_stats - Clear rx packet error stats. * diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index cb759a0..7e21c28 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1649,17 +1649,25 @@ static int eqos_set_avb_algorithm(struct osi_core_priv_data *osi_core, } /* queue index in range */ - if (avb->qindex >= EQOS_MAX_TC) { + if (avb->qindex >= OSI_EQOS_MAX_NUM_QUEUES) { OSI_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_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "Invalid Queue mode\n", + (unsigned long long)avb->qindex); + return ret; + } + /* can't set AVB mode for queue 0 */ - if ((avb->qindex == 0U) && (avb->oper_mode == EQOS_MTL_QUEUE_AVB)) { + if ((avb->qindex == 0U) && (avb->oper_mode == OSI_MTL_QUEUE_AVB)) { OSI_ERR(osi_core->osd, OSI_LOG_ARG_OPNOTSUPP, - "Not allowed to set CBS for Q0\n", + "Not allowed to set AVB for Q0\n", (unsigned long long)avb->qindex); return ret; } @@ -1676,38 +1684,42 @@ static int eqos_set_avb_algorithm(struct osi_core_priv_data *osi_core, EQOS_MTL_CH0_TX_OP_MODE_IDX + qinx); /* Set Algo and Credit control */ - value = (avb->credit_control << EQOS_MTL_TXQ_ETS_CR_CC_SHIFT) & - EQOS_MTL_TXQ_ETS_CR_CC; + 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_writel(value, (unsigned char *)osi_core->base + EQOS_MTL_TXQ_ETS_CR(qinx)); - /* Set Send slope credit */ - value = avb->send_slope & EQOS_MTL_TXQ_ETS_SSCR_SSC_MASK; - osi_writel(value, (unsigned char *)osi_core->base + - EQOS_MTL_TXQ_ETS_SSCR(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_writel(value, (unsigned char *)osi_core->base + + EQOS_MTL_TXQ_ETS_SSCR(qinx)); - /* Set Idle slope credit*/ - value = osi_readl((unsigned char *)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(value, (unsigned char *)osi_core->base + - EQOS_MTL_TXQ_QW(qinx), - EQOS_MTL_TXQ0_QW_IDX + qinx); + /* Set Idle slope credit*/ + value = osi_readl((unsigned char *)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(value, (unsigned char *)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_writel(value, (unsigned char *)osi_core->base + - EQOS_MTL_TXQ_ETS_HCR(qinx)); + /* Set Hi credit */ + value = avb->hi_credit & EQOS_MTL_TXQ_ETS_HCR_HC_MASK; + osi_writel(value, (unsigned char *)osi_core->base + + EQOS_MTL_TXQ_ETS_HCR(qinx)); - /* low credit is -ve number, osi_write need a unsigned int - * take only 28:0 bits from avb->low_credit - */ - value = avb->low_credit & EQOS_MTL_TXQ_ETS_LCR_LC_MASK; - osi_writel(value, (unsigned char *)osi_core->base + - EQOS_MTL_TXQ_ETS_LCR(qinx)); + /* low credit is -ve number, osi_write need a unsigned int + * take only 28:0 bits from avb->low_credit + */ + value = avb->low_credit & EQOS_MTL_TXQ_ETS_LCR_LC_MASK; + osi_writel(value, (unsigned char *)osi_core->base + + EQOS_MTL_TXQ_ETS_LCR(qinx)); + } return 0; } @@ -1989,7 +2001,7 @@ static int eqos_get_avb_algorithm(struct osi_core_priv_data *osi_core, return ret; } - if (avb->qindex >= EQOS_MAX_TC) { + if (avb->qindex >= OSI_EQOS_MAX_NUM_QUEUES) { OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid Queue index\n", (unsigned long long)avb->qindex); diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index ed63283..98ef5a2 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -40,18 +40,6 @@ #define FULL_MINUS_16_K (unsigned int)30 /** @} */ -/** - * @addtogroup EQOS-MTLQ MTL queue operation mode - * - * @brief MTL queue operation mode options - * @{ - */ -#define EQOS_MTL_QUEUE_DISABLED 0x0U -#define EQOS_MTL_QUEUE_AVB 0x1U -#define EQOS_MTL_QUEUE_DCB 0x2U -#define EQOS_MTL_QUEUE_GENERIC 0x3U -/** @} */ - /** * @addtogroup EQOS-MDC MDC Clock Selection defines * @@ -246,7 +234,6 @@ #define EQOS_MTL_RXQ_SIZE_SHIFT 20U #define EQOS_MAC_ENABLE_LM OSI_BIT(12) #define EQOS_RX_CLK_SEL OSI_BIT(8) -#define EQOS_MAX_TC 8U #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) diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index 913546d..3d9f768 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -530,6 +530,53 @@ static void eqos_stop_dma(void *addr, unsigned int chan) EQOS_DMA_CH0_RX_CTRL_IDX + chan); } +/** + * @brief eqos_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 from 0usec to 4095usec + * + * @note 1)MAC should be init and started. see osi_start_mac() + * 2)OSD should be initialized + * + * @retval none + */ +static void eqos_config_slot(struct osi_dma_priv_data *osi_dma, + unsigned int chan, + unsigned int set, + unsigned int interval) +{ + unsigned int value; + + CHECK_CHAN_BOUND(chan); + + if (set == OSI_ENABLE) { + /* Program SLOT CTRL register SIV and set ESC bit */ + value = osi_readl((unsigned char *)osi_dma->base + + EQOS_DMA_CHX_SLOT_CTRL(chan)); + value &= ~EQOS_DMA_CHX_SLOT_SIV_MASK; + /* remove overflow bits of interval */ + interval &= EQOS_DMA_CHX_SLOT_SIV_MASK; + value |= (interval << EQOS_DMA_CHX_SLOT_SIV_SHIFT); + /* Set ESC bit */ + value |= EQOS_DMA_CHX_SLOT_ESC; + osi_writel(value, (unsigned char *)osi_dma->base + + EQOS_DMA_CHX_SLOT_CTRL(chan)); + + } else { + /* Clear ESC bit of SLOT CTRL register */ + value = osi_readl((unsigned char *)osi_dma->base + + EQOS_DMA_CHX_SLOT_CTRL(chan)); + value &= ~EQOS_DMA_CHX_SLOT_ESC; + osi_writel(value, (unsigned char *)osi_dma->base + + EQOS_DMA_CHX_SLOT_CTRL(chan)); + } +} + /** * @brief eqos_configure_dma_channel - Configure DMA channel * @@ -701,6 +748,7 @@ static struct osi_dma_chan_ops eqos_dma_chan_ops = { .init_dma_channel = eqos_init_dma_channel, .set_rx_buf_len = eqos_set_rx_buf_len, .validate_regs = eqos_validate_dma_regs, + .config_slot = eqos_config_slot, }; /** diff --git a/osi/dma/eqos_dma.h b/osi/dma/eqos_dma.h index 5d5f0d8..93a66ab 100644 --- a/osi/dma/eqos_dma.h +++ b/osi/dma/eqos_dma.h @@ -34,6 +34,7 @@ #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) +#define EQOS_DMA_CHX_SLOT_CTRL(x) ((0x0080U * (x)) + 0x113CU) #define EQOS_DMA_CHX_RDTP(x) ((0x0080U * (x)) + 0x1128U) #define EQOS_DMA_CHX_RDLH(x) ((0x0080U * (x)) + 0x1118U) @@ -91,6 +92,9 @@ #define EQOS_DMA_CHX_TDRL_MASK 0x3FFU #define EQOS_DMA_CHX_RDRL_MASK 0x3FFU #define EQOS_DMA_CHX_INTR_ENA_MASK 0xFFC7U +#define EQOS_DMA_CHX_SLOT_SIV_MASK 0xFFFU +#define EQOS_DMA_CHX_SLOT_SIV_SHIFT 4U +#define EQOS_DMA_CHX_SLOT_ESC 0x1U /* To add new registers to validate,append at end of below macro list and * increment EQOS_MAX_DMA_SAFETY_REGS. diff --git a/osi/dma/libnvethernetcl.export b/osi/dma/libnvethernetcl.export index b4f009a..5e029d3 100644 --- a/osi/dma/libnvethernetcl.export +++ b/osi/dma/libnvethernetcl.export @@ -39,3 +39,4 @@ osi_hw_dma_init osi_hw_dma_deinit osi_init_dma_ops osi_validate_dma_regs +osi_config_slot_function diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 9fee4bb..5dfa797 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -21,6 +21,7 @@ */ #include "osi_dma_local.h" +#include <osd.h> int osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) { @@ -271,6 +272,70 @@ int osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) return 0; } +int osi_config_slot_function(struct osi_dma_priv_data *osi_dma, + unsigned int set) +{ + int ret = -1; + unsigned int i = 0U, chan = 0U, interval = 0U; + struct osi_tx_ring *tx_ring = OSI_NULL; + + /* return on invalid set argument */ + if ((set != OSI_ENABLE) && (set != OSI_DISABLE)) { + OSI_ERR(osi_dma->osd, + OSI_LOG_ARG_INVALID, + "Invalid set argument\n", + set); + return -1; + } + + /* Configure slot Checking for Tranmit */ + if (osi_dma == OSI_NULL || osi_dma->ops == OSI_NULL || + osi_dma->ops->config_slot == OSI_NULL) { + OSI_ERR(OSI_NULL, + OSI_LOG_ARG_INVALID, + "Invalid set argument\n", 0ULL); + 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 >= OSI_EQOS_MAX_NUM_CHANS)) { + /* Ignore 0 and invalid channels */ + continue; + } + /* Check for slot enbale */ + 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_ERR(osi_dma->osd, + OSI_LOG_ARG_INVALID, + "Invalid interval arguments\n", + interval); + return -1; + } + + tx_ring = osi_dma->tx_ring[chan]; + if (tx_ring == OSI_NULL) { + OSI_ERR(osi_dma->osd, + OSI_LOG_ARG_INVALID, + "tx_ring is null\n", + chan); + return -1; + } + tx_ring->slot_check = set; + osi_dma->ops->config_slot(osi_dma, + chan, + set, + interval); + } + } + + return ret; +} + int osi_validate_dma_regs(struct osi_dma_priv_data *osi_dma) { int ret = -1; diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index daab896..4a0f222 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -552,11 +552,13 @@ static inline int need_cntx_desc(struct osi_tx_pkt_cx *tx_pkt_cx, * etc. are flagged in transmit packet context. If so, set the fiels in * first desc corresponding to those features. * + * @param[in] tx_ring: DMA channel TX ring. * @param[in] tx_pkt_cx: Pointer to transmit packet context structure * @param[in] tx_desc: Pointer to tranmit descriptor to be filled. * @param[in] tx_swcx: Pointer to corresponding tx descriptor software context. */ -static inline void fill_first_desc(struct osi_tx_pkt_cx *tx_pkt_cx, +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) { @@ -610,6 +612,15 @@ static inline void fill_first_desc(struct osi_tx_pkt_cx *tx_pkt_cx, tx_pkt_cx->payload_len &= TDES3_TPL_MASK; /* Update TCP payload len in desc */ 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); + } } } @@ -661,7 +672,7 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan) } /* Fill first descriptor */ - fill_first_desc(tx_pkt_cx, tx_desc, tx_swcx); + fill_first_desc(tx_ring, tx_pkt_cx, tx_desc, tx_swcx); INCR_TX_DESC_INDEX(entry, 1U); @@ -842,6 +853,10 @@ static void tx_dma_desc_init(struct osi_dma_priv_data *osi_dma) 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->base, chan, (TX_DESC_CNT - 1U)); ops->set_tx_ring_start_addr(osi_dma->base, chan, From 954609aba11c3d97e7b1f297545f4582887a790d Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Thu, 7 Nov 2019 14:22:06 +0530 Subject: [PATCH 057/458] nvethernetrm: change required clock freq to 250MHz increase required clock frequency from 62.5MHz to 250MHz for better PTP time stamping accuracy.Switching to 250 MHz will increase the accuracy of the PTP timestamp by ~22ns Bug 200565215 Change-Id: I1dab385ade30df4864c1477685f39d4374700932 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2234039 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_common.h | 1 + osi/core/eqos_core.c | 10 +++++----- osi/core/osi_core.c | 10 +++++----- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index d1f5ede..f050c52 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -37,6 +37,7 @@ /* System clock is 62.5MHz */ #define OSI_ETHER_SYSCLOCK 62500000U +#define OSI_PTP_REQ_CLK_FREQ 250000000U #define OSI_ONE_MEGA_HZ 1000000U #define OSI_MAX_RX_COALESCE_USEC 1020U #define OSI_MIN_RX_COALESCE_USEC 3U diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 7e21c28..c8626bc 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -3151,7 +3151,7 @@ static void eqos_config_tscr(void *addr, unsigned int ptp_filter) * * @param[in] addr: Base address indicating the start of * memory mapped IO region of the MAC. - * @param[in] ptp_clock: PTP clock + * @param[in] ptp_clock: PTP required clock frequency * * @note MAC should be init and started. see osi_start_mac() */ @@ -3162,14 +3162,14 @@ static void eqos_config_ssir(void *addr, unsigned int ptp_clock) mac_tcr = osi_readl((unsigned char *)addr + EQOS_MAC_TCR); - /* convert the PTP_CLOCK to nano second. + /* convert the PTP required clock frequency to nano second. * formula is : ((1/ptp_clock) * 1000000000) - * where, ptp_clock = 50MHz if FINE correction - * and ptp_clock = EQOS_SYSCLOCK if COARSE correction + * where, ptp_clock = OSI_PTP_REQ_CLK_FREQ if FINE correction + * and ptp_clock = PTP reference clock if COARSE correction */ if ((mac_tcr & EQOS_MAC_TCR_TSCFUPDT) == EQOS_MAC_TCR_TSCFUPDT) { - val = ((1U * OSI_NSEC_PER_SEC) / OSI_ETHER_SYSCLOCK); + val = ((1U * OSI_NSEC_PER_SEC) / OSI_PTP_REQ_CLK_FREQ); } else { val = ((1U * OSI_NSEC_PER_SEC) / ptp_clock); } diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 57eed58..dc40d89 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -869,13 +869,13 @@ int osi_ptp_configuration(struct osi_core_priv_data *osi_core, /* formula for calculating addend value is * addend = 2^32/freq_div_ratio; - * where, freq_div_ratio = EQOS_SYSCLOCK/50MHz - * hence, addend = ((2^32) * 50MHz)/EQOS_SYSCLOCK; - * NOTE: EQOS_SYSCLOCK must be >= 50MHz to achive 20ns accuracy. + * where, freq_div_ratio = ptp_ref_clk_rate/OSI_PTP_REQ_CLK_FREQ * 2^x * y == (y << x), hence - * 2^32 * 6250000 ==> (6250000 << 32) + * 2^32 * OSI_PTP_REQ_CLK_FREQ == (OSI_PTP_REQ_CLK_FREQ << 32) + * so addend = (2^32 * OSI_PTP_REQ_CLK_FREQ)/ptp_ref_clk_rate; + * which is (OSI_PTP_REQ_CLK_FREQ << 32)/ptp_ref_clk_rate; */ - temp = ((unsigned long)OSI_ETHER_SYSCLOCK << 32); + temp = ((unsigned long)OSI_PTP_REQ_CLK_FREQ << 32); temp1 = div_u64(temp, (unsigned long)osi_core->ptp_config.ptp_ref_clk_rate); if (temp1 < UINT_MAX) { From 5e044a89f95f83c2456628ef1222d55ad9f002a5 Mon Sep 17 00:00:00 2001 From: nannaiah <nannaiah@nvidia.com> Date: Thu, 3 Oct 2019 13:23:07 -0700 Subject: [PATCH 058/458] nvethernetrm: Configure AXI ASID Control Issue:To enable ethernet virtualization the default MC override needs to be disabled to config different EQOS SID's for each OS. Virtualization case ethernet server handles programming of SID's but non virtualization case if AXI is not configured then EQOS doesn't work. Fix: Ethernet Non virtualization case add fix to config default SID. Bug 2694285 Signed-off-by: Nagaraj Annaiah <nannaiah@nvidia.com> Change-Id: Ifa3181f0f0fffed970b45f8c20ad7c0bd0deea37 Reviewed-on: https://git-master.nvidia.com/r/2211148 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Tested-by: Nagaraj Annaiah <nannaiah@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/eqos_core.c | 4 ++++ osi/core/eqos_core.h | 14 ++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index c8626bc..38b3416 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1355,6 +1355,10 @@ static int eqos_core_init(struct osi_core_priv_data *osi_core, osi_writel(EQOS_MMC_CNTRL_CNTRST, (unsigned char *)osi_core->base + EQOS_MMC_CNTRL); + /* AXI ASID CTRL */ + osi_writel(EQOS_AXI_ASID_CTRL_VAL, + (unsigned char *)osi_core->base + EQOS_AXI_ASID_CTRL); + /* Mapping MTL Rx queue and DMA Rx channel */ /* TODO: Need to add EQOS_MTL_RXQ_DMA_MAP1 for EQOS */ value = osi_readl((unsigned char *)osi_core->base + diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 98ef5a2..e602fef 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -166,6 +166,7 @@ #define EQOS_PAD_AUTO_CAL_STAT 0x880CU #define EQOS_PAD_CRTL 0x8800U #define EQOS_CLOCK_CTRL_0 0x8000U +#define EQOS_AXI_ASID_CTRL 0x8400U /** @} */ /** @@ -369,6 +370,19 @@ #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_AXI_ASID_CTRL_CH3_SHIFT 24 +#define EQOS_AXI_ASID_CTRL_CH2_SHIFT 16 +#define EQOS_AXI_ASID_CTRL_CH1_SHIFT 8 + +#define TEGRA_SID_EQOS (unsigned int)20 +#define TEGRA_SID_EQOS_CH3 ((TEGRA_SID_EQOS) << EQOS_AXI_ASID_CTRL_CH3_SHIFT) +#define TEGRA_SID_EQOS_CH2 ((TEGRA_SID_EQOS) << EQOS_AXI_ASID_CTRL_CH2_SHIFT) +#define TEGRA_SID_EQOS_CH1 ((TEGRA_SID_EQOS) << EQOS_AXI_ASID_CTRL_CH1_SHIFT) +#define EQOS_AXI_ASID_CTRL_VAL ((TEGRA_SID_EQOS_CH3) |\ + (TEGRA_SID_EQOS_CH2) |\ + (TEGRA_SID_EQOS_CH1) |\ + (TEGRA_SID_EQOS)) /** @} */ /** From 084cb779c3b21f1c49072659ac7dc602100e66a2 Mon Sep 17 00:00:00 2001 From: Ajay Gupta <ajayg@nvidia.com> Date: Thu, 31 Oct 2019 11:23:32 -0700 Subject: [PATCH 059/458] nvethernetrm: fix AXI clock to 125MHz Fixes incorrect number of rx interrupt triggered with rx coalescing (rx-usecs in ethtool) parameter. Bug 200529168 Change-Id: I49ea2c469667e05f7e12f2741984f609127f395c Signed-off-by: Ajay Gupta <ajayg@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2229564 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_common.h | 2 -- osi/dma/eqos_dma.c | 15 +++++++++------ osi/dma/eqos_dma.h | 13 ++++++++++++- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index f050c52..d1fab0d 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -35,8 +35,6 @@ #define OSI_NSEC_PER_SEC 1000000000ULL #define OSI_INVALID_VALUE 0xFFFFFFFFU -/* System clock is 62.5MHz */ -#define OSI_ETHER_SYSCLOCK 62500000U #define OSI_PTP_REQ_CLK_FREQ 250000000U #define OSI_ONE_MEGA_HZ 1000000U #define OSI_MAX_RX_COALESCE_USEC 1020U diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index 3d9f768..540bf7a 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -660,21 +660,24 @@ static void eqos_configure_dma_channel(unsigned int 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) + * 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((unsigned char *)osi_dma->base + EQOS_DMA_CHX_RX_WDT(chan)); - /* Mask the RWT value */ - value &= ~EQOS_DMA_CHX_RX_WDT_RWT_MASK; + /* 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 * - (OSI_ETHER_SYSCLOCK / OSI_ONE_MEGA_HZ)) / + (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, (unsigned char *)osi_dma->base + EQOS_DMA_CHX_RX_WDT(chan)); } diff --git a/osi/dma/eqos_dma.h b/osi/dma/eqos_dma.h index 93a66ab..766c586 100644 --- a/osi/dma/eqos_dma.h +++ b/osi/dma/eqos_dma.h @@ -23,6 +23,15 @@ #ifndef EQOS_DMA_H_ #define EQOS_DMA_H_ +/** + * @addtogroup EQOS AXI Clock defines + * + * @brief AXI Clock defines + * @{ + */ +#define EQOS_AXI_CLK_FREQ 125000000U +/** @} */ + /** * @addtogroup EQOS1 DMA Channel Register offsets * @@ -81,7 +90,9 @@ #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 256U +#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 From 7c374d6cfbb57c56bdeedab6b177be35c3d7f361 Mon Sep 17 00:00:00 2001 From: Ajay Gupta <ajayg@nvidia.com> Date: Mon, 4 Nov 2019 15:02:10 -0800 Subject: [PATCH 060/458] nvethernetrm: enable rx frame based interrupt coalescing Rx frame based coalescing can be enabled only when Rx timer based coalescing is also enabled. This is to avoid no rx interrupt issue for applications which send only limited frames and expects reply. Bug 200529168 Change-Id: If20ec8322d6597f0a018c5668a9d632e456f60cd Signed-off-by: Ajay Gupta <ajayg@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2233501 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_common.h | 1 + include/osi_dma.h | 6 ++++++ osi/dma/osi_dma.c | 9 +++++++++ osi/dma/osi_dma_txrx.c | 7 +++++++ 4 files changed, 23 insertions(+) diff --git a/include/osi_common.h b/include/osi_common.h index d1fab0d..301eb48 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -39,6 +39,7 @@ #define OSI_ONE_MEGA_HZ 1000000U #define OSI_MAX_RX_COALESCE_USEC 1020U #define OSI_MIN_RX_COALESCE_USEC 3U +#define OSI_MIN_RX_COALESCE_FRAMES 1U #define OSI_PAUSE_FRAMES_ENABLE 0U #define OSI_PAUSE_FRAMES_DISABLE 1U diff --git a/include/osi_dma.h b/include/osi_dma.h index 74144e7..40db561 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -365,6 +365,10 @@ struct osi_dma_priv_data { unsigned int rx_riwt; /** Flag which decides riwt is enabled(1) or disabled(0) */ unsigned int use_riwt; + /** Max no of pkts to be received before triggering Rx interrupt */ + unsigned int rx_frames; + /** Flag which decides rx_frames is enabled(1) or disabled(0) */ + unsigned int use_rx_frames; /** Functional safety config to do periodic read-verify of * certain safety critical dma registers */ void *safety_config; @@ -664,6 +668,8 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, * channels * 12) osi_dma->use_riwt ==> OSI_DISABLE/OSI_ENABLE * 13) osi_dma->rx_riwt ===> Actual value read from DT + * 14) osi_dma->use_rx_frames ==> OSI_DISABLE/OSI_ENABLE + * 15) osi_dma->rx_frames ===> Actual value read from DT * * @retval 0 on success * @retval -1 on failure. diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 5dfa797..5583777 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -237,6 +237,15 @@ int osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, /* 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; + } + } } INCR_RX_DESC_INDEX(rx_ring->refill_idx, 1U); diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 4a0f222..2b1cb0f 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -773,6 +773,13 @@ static int rx_dma_desc_initialization(struct osi_dma_priv_data *osi, /* reconfigure INTE bit if RX watchdog timer is enabled */ if (osi->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->use_rx_frames == OSI_ENABLE) { + if ((i % osi->rx_frames) == OSI_NONE) + rx_desc->rdes3 |= RDES3_IOC; + } } rx_swcx->flags = 0; From f48b89022b49488dbc562279ee6690e30521e982 Mon Sep 17 00:00:00 2001 From: Ajay Gupta <ajayg@nvidia.com> Date: Mon, 4 Nov 2019 15:02:10 -0800 Subject: [PATCH 061/458] nvethernetrm: enable tx interrupt coalescing Tx frame count and software timer based interrupt coalescing is enabled. Tx frame based coalescing can be enabled only when tx software timer based interrupt coalescing is also enabled. Bug 200529168 Change-Id: Icd5e2ff3a6b9ad1d1793842b607a93ad779955d7 Signed-off-by: Ajay Gupta <ajayg@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2234609 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/mmc.h | 2 ++ include/osi_common.h | 3 +++ include/osi_dma.h | 27 +++++++++++++++++++++++++++ osi/dma/osi_dma.c | 7 +++++++ osi/dma/osi_dma_txrx.c | 24 ++++++++++++++++++++++++ 5 files changed, 63 insertions(+) diff --git a/include/mmc.h b/include/mmc.h index 3d064ad..9b91606 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -323,6 +323,8 @@ struct osi_xtra_stat_counters { unsigned long re_alloc_rxbuf_failed[OSI_EQOS_MAX_NUM_QUEUES]; /** TX per channel interrupt count */ unsigned long tx_normal_irq_n[OSI_EQOS_MAX_NUM_QUEUES]; + /** TX per channel SW timer callback count */ + unsigned long tx_usecs_swtimer_n[OSI_EQOS_MAX_NUM_QUEUES]; /** RX per channel interrupt count */ unsigned long rx_normal_irq_n[OSI_EQOS_MAX_NUM_QUEUES]; /** link connect count */ diff --git a/include/osi_common.h b/include/osi_common.h index 301eb48..5c68c32 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -40,6 +40,9 @@ #define OSI_MAX_RX_COALESCE_USEC 1020U #define OSI_MIN_RX_COALESCE_USEC 3U #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 #define OSI_PAUSE_FRAMES_ENABLE 0U #define OSI_PAUSE_FRAMES_DISABLE 1U diff --git a/include/osi_dma.h b/include/osi_dma.h index 40db561..a4566f6 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -281,6 +281,8 @@ struct osi_tx_ring { 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 */ + unsigned int frame_cnt; }; struct osi_dma_priv_data; @@ -369,6 +371,14 @@ struct osi_dma_priv_data { unsigned int rx_frames; /** Flag which decides rx_frames is enabled(1) or disabled(0) */ unsigned int use_rx_frames; + /** Transmit Interrupt Software Timer Count Units */ + unsigned int tx_usecs; + /** Flag which decides Tx timer is enabled(1) or disabled(0) */ + unsigned int use_tx_usecs; + /** Max no of pkts to transfer before triggering Tx interrupt */ + unsigned int tx_frames; + /** Flag which decides tx_frames is enabled(1) or disabled(0) */ + unsigned int use_tx_frames; /** Functional safety config to do periodic read-verify of * certain safety critical dma registers */ void *safety_config; @@ -755,4 +765,21 @@ int osi_config_slot_function(struct osi_dma_priv_data *osi_dma, */ int osi_clear_rx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); +/** + * @brief osi_txring_empty - Check if Txring is empty. + * + * 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. + * + * @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 1 if ring is empty. + * @retval 0 if ring has outstanding packets. + */ +int osi_txring_empty(struct osi_dma_priv_data *osi_dma, unsigned int chan); #endif /* OSI_DMA_H */ diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 5583777..6d731e2 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -356,3 +356,10 @@ int osi_validate_dma_regs(struct osi_dma_priv_data *osi_dma) return ret; } + +int osi_txring_empty(struct osi_dma_priv_data *osi_dma, unsigned int chan) +{ + struct osi_tx_ring *tx_ring = osi_dma->tx_ring[chan]; + + return (tx_ring->clean_idx == tx_ring->cur_tx_idx) ? 1 : 0; +} diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 2b1cb0f..5bb0e1a 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -708,6 +708,30 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan) /* set Interrupt on Completion*/ last_desc->tdes2 |= TDES2_IOC; + if (tx_ring->frame_cnt < UINT_MAX) { + tx_ring->frame_cnt++; + } else if (osi->use_tx_frames == OSI_ENABLE && + (tx_ring->frame_cnt % osi->tx_frames) < UINT_MAX) { + /* make sure count for tx_frame interrupt logic is retained */ + tx_ring->frame_cnt = (tx_ring->frame_cnt % osi->tx_frames) + + 1U; + } else { + tx_ring->frame_cnt = 1U; + } + + /* clear IOC bit if tx SW timer based coalescing is enabled */ + if (osi->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->use_tx_frames == OSI_ENABLE) { + if ((tx_ring->frame_cnt % osi->tx_frames) == OSI_NONE) { + last_desc->tdes2 |= TDES2_IOC; + } + } + } /* Set OWN bit for first and context descriptors * at the end to avoid race condition */ From a9c4b8474df3004cd98d56e28e51d0e2b05f7725 Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Wed, 13 Nov 2019 13:41:29 +0530 Subject: [PATCH 062/458] nvethernetrm: Remove sleep on MDIO PHY read/write Issue: C6 exit latency tests are failing due to NvEthernet driver sleep in MDIO read and write calls. Fix: Remove sleep from poll_for_mii_idle function and convert it to incremental delay up to 0.5 seconds. Bug 200545651 Change-Id: I2a03f21686444862f2f48b64f1f812be878c459b Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2238178 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/osi_core.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index dc40d89..576a494 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -53,7 +53,8 @@ */ static inline int poll_for_mii_idle(struct osi_core_priv_data *osi_core) { - unsigned int retry = 1000; + /* half sec timeout */ + unsigned int retry = 50000; unsigned int mac_gmiiar; unsigned int count; int cond = 1; @@ -69,13 +70,15 @@ static inline int poll_for_mii_idle(struct osi_core_priv_data *osi_core) } count++; - osd_msleep(1U); mac_gmiiar = osi_readl((unsigned char *)osi_core->base + MAC_MDIO_ADDRESS); if ((mac_gmiiar & MAC_GMII_BUSY) == 0U) { cond = 0; + } else { + /* wait on GMII Busy set */ + osd_udelay(10U); } } @@ -121,8 +124,6 @@ int osi_write_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, osi_writel(mac_gmiiar, (unsigned char *)osi_core->base + MAC_MDIO_ADDRESS); - osd_usleep_range(9, 11); - /* wait for MII write operation to complete */ ret = poll_for_mii_idle(osi_core); if (ret < 0) { @@ -163,8 +164,6 @@ int osi_read_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, (osi_core->mdc_cr) << 8U | ((0x3U) << 2U) | MAC_GMII_BUSY; osi_writel(mac_gmiiar, (unsigned char *)osi_core->base + MAC_MDIO_ADDRESS); - osd_usleep_range(9, 11); - /* wait for MII write operation to complete */ ret = poll_for_mii_idle(osi_core); if (ret < 0) { From 8bdca63446c518ce686a2d3a4884c7d6386e20f2 Mon Sep 17 00:00:00 2001 From: Srinivas Ramachandran <srinivasra@nvidia.com> Date: Tue, 10 Dec 2019 12:13:23 -0800 Subject: [PATCH 063/458] nvethernetrm: Zero initialize all descriptors Issue: Tx/Rx DMA initialization in OSI does not actually zero initialize all the descriptors. This inherently assumes that the OSD layer would already zero initialize the memory allocated for descriptors, which need not be the case for all OSD's as this requirement isn't called out. Fix: Instead of relying on OSD to zero initialize the descriptors, perform initialization in OSI during DMA init operation. It is one time cost at init, so no performance penalty in data path. Bug 2779959 Change-Id: I39431184980fceeb836eca872491ac8d7ee029ca Signed-off-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2259541 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/dma/osi_dma_txrx.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 5bb0e1a..50d1a51 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -782,6 +782,12 @@ static int rx_dma_desc_initialization(struct osi_dma_priv_data *osi, 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; + tmp = L32(rx_swcx->buf_phy_addr); if (tmp < UINT_MAX) { rx_desc->rdes0 = (unsigned int)tmp; @@ -867,19 +873,20 @@ static void tx_dma_desc_init(struct osi_dma_priv_data *osi_dma) struct osi_tx_desc *tx_desc = OSI_NULL; struct osi_dma_chan_ops *ops = osi_dma->ops; unsigned int chan = 0; - unsigned int i; + unsigned int 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]; - tx_desc = tx_ring->tx_desc; - /* FIXME: does it require */ - tx_desc->tdes0 = 0; - tx_desc->tdes1 = 0; - tx_desc->tdes2 = 0; - tx_desc->tdes3 = 0; + for (j = 0; j < TX_DESC_CNT; j++) { + tx_desc = tx_ring->tx_desc + j; + + tx_desc->tdes0 = 0; + tx_desc->tdes1 = 0; + tx_desc->tdes2 = 0; + tx_desc->tdes3 = 0; + } tx_ring->cur_tx_idx = 0; tx_ring->clean_idx = 0; From df29f010ab08660e365548662de8491123a02fe4 Mon Sep 17 00:00:00 2001 From: Srinivas Ramachandran <srinivasra@nvidia.com> Date: Thu, 8 Aug 2019 10:46:16 +0530 Subject: [PATCH 064/458] nvethernetrm: Add support for EEE LPI Add an API to configure the EEE LPI mode. Tx LPI is enabled with a default entry time of 1sec. The MAC controller has capability to automatically enter LPI mode when all transmissions are complete. Bug 2594864 Change-Id: I765ddfda908b1922abd46c11fa217a35fe6190f1 Signed-off-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2160787 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/mmc.h | 13 ++++- include/osi_common.h | 39 ++++++++++++++ include/osi_core.h | 22 ++++++++ osi/core/eqos_core.c | 95 ++++++++++++++++++++++++++++++++- osi/core/eqos_core.h | 8 +++ osi/core/eqos_mmc.c | 12 +++++ osi/core/eqos_mmc.h | 4 ++ osi/core/libnvethernetrm.export | 1 + osi/core/osi_core.c | 16 ++++++ 9 files changed, 207 insertions(+), 3 deletions(-) diff --git a/include/mmc.h b/include/mmc.h index 9b91606..5e401dd 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -188,7 +188,18 @@ struct osi_mmc_counters { /** This counter provides the number of packets received with Receive * error or Packet Extension error on the GMII or MII interface */ unsigned long mmc_rx_ctrl_frames_g; - + /** This counter provides the number of microseconds Tx LPI is asserted + * in the MAC controller */ + unsigned long mmc_tx_lpi_usec_cntr; + /** This counter provides the number of times MAC controller has + * entered Tx LPI. */ + unsigned long mmc_tx_lpi_tran_cntr; + /** This counter provides the number of microseconds Rx LPI is asserted + * in the MAC controller */ + unsigned long mmc_rx_lpi_usec_cntr; + /** This counter provides the number of times MAC controller has + * entered Rx LPI.*/ + unsigned long mmc_rx_lpi_tran_cntr; /** This counter provides the number of good IPv4 datagrams received * with the TCP, UDP, or ICMP payload */ unsigned long mmc_rx_ipv4_gd; diff --git a/include/osi_common.h b/include/osi_common.h index 5c68c32..7bd8aed 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -44,6 +44,45 @@ #define OSI_MIN_TX_COALESCE_USEC 32U #define OSI_MIN_TX_COALESCE_FRAMES 1U +/** + * @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 (unsigned int)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 +/** @} */ + #define OSI_PAUSE_FRAMES_ENABLE 0U #define OSI_PAUSE_FRAMES_DISABLE 1U #define OSI_FLOW_CTRL_TX OSI_BIT(0) diff --git a/include/osi_core.h b/include/osi_core.h index f13f786..d28f2d6 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -245,6 +245,9 @@ struct osi_core_ops { void (*read_mmc)(struct osi_core_priv_data *osi_core); /** Called to reset MMC HW counter structure */ void (*reset_mmc)(struct osi_core_priv_data *osi_core); + void (*configure_eee)(struct osi_core_priv_data *osi_core, + unsigned int tx_lpi_enabled, + unsigned int tx_lpi_timer); }; /** @@ -1000,4 +1003,23 @@ int osi_l3l4_filter(struct osi_core_priv_data *osi_core, unsigned int dma_routing_enable, unsigned int dma_chan, unsigned int is_l4_filter); +/** + * @brief osi_configure_eee - Configure EEE LPI in MAC. + * + * 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) + * + * @note + * 1) MAC and PHY should be init and started. see osi_start_mac() + * + * @retval 0 on success + * @retval -1 on failure. + */ +int osi_configure_eee(struct osi_core_priv_data *osi_core, + unsigned int tx_lpi_enabled, + unsigned int tx_lpi_timer); #endif /* OSI_CORE_H */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 38b3416..edadd7c 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1236,8 +1236,8 @@ static void eqos_configure_mac(struct osi_core_priv_data *osi_core) /* Enable MAC interrupts */ /* Read MAC IMR Register */ value = osi_readl((unsigned char *)osi_core->base + EQOS_MAC_IMR); - /* RGSMIIIM - RGMII/SMII interrupt Enable */ - /* TODO: LPI need to be enabled during EEE implementation */ + /* RGSMIIIE - RGMII/SMII interrupt Enable. + * LPIIE is not enabled. MMC LPI counters is maintained in HW */ value |= EQOS_IMR_RGSMIIIE; eqos_core_safety_writel(value, (unsigned char *)osi_core->base + @@ -3209,6 +3209,96 @@ static void eqos_core_deinit(struct osi_core_priv_data *osi_core) eqos_stop_mac(osi_core->base); } +/** + * @brief eqos_disable_tx_lpi - Helper function to disable Tx LPI. + * + * Algorithm: + * 1) 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] addr: base address of memory mapped register space of MAC. + * + * @note MAC has to be out of reset, and clocks supplied. + */ +static inline void eqos_disable_tx_lpi(void *addr) +{ + unsigned int lpi_csr = 0; + + /* Disable LPI control bits */ + lpi_csr = osi_readl((unsigned char *)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_writel(lpi_csr, (unsigned char *)addr + EQOS_MAC_LPI_CSR); +} + +/** + * @brief eqos_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 eqos_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 char *addr = (unsigned char *)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_writel(lpi_timer_ctrl, addr + EQOS_MAC_LPI_TIMER_CTRL); + + lpi_entry_timer |= (tx_lpi_timer & + OSI_LPI_ENTRY_TIMER_MASK); + osi_writel(lpi_entry_timer, addr + EQOS_MAC_LPI_EN_TIMER); + + /* 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_readl(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_writel(lpi_csr, addr + EQOS_MAC_LPI_CSR); + } else { + /* Disable LPI control bits */ + eqos_disable_tx_lpi(osi_core->base); + } +} + /** * @brief eqos_core_ops - EQOS MAC core operations */ @@ -3252,6 +3342,7 @@ static struct osi_core_ops eqos_core_ops = { .config_ssir = eqos_config_ssir, .read_mmc = eqos_read_mmc, .reset_mmc = eqos_reset_mmc, + .configure_eee = eqos_configure_eee, }; /** diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index e602fef..e8cf23f 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -103,6 +103,9 @@ #define EQOS_MAC_IMR 0x00B4 #define EQOS_DMA_ISR 0x1008 #define EQOS_MAC_ISR 0x00B0 +#define EQOS_MAC_LPI_CSR 0x00D0 +#define EQOS_MAC_LPI_TIMER_CTRL 0x00D4 +#define EQOS_MAC_LPI_EN_TIMER 0x00D8 #define EQOS_MAC_RQC1R 0x00A4 #define EQOS_MAC_RQC2R 0x00A8 #define EQOS_MMC_TX_INTR_MASK 0x0710 @@ -228,6 +231,11 @@ #define EQOS_MTL_QTOMR_FTQ_LPOS OSI_BIT(0) #define EQOS_DMA_ISR_MACIS OSI_BIT(17) #define EQOS_MAC_ISR_RGSMIIS OSI_BIT(0) +#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_MTL_TXQ_QW_ISCQW OSI_BIT(4) #define EQOS_DMA_SBUS_RD_OSR_LMT 0x001F0000U #define EQOS_DMA_SBUS_WR_OSR_LMT 0x1F000000U diff --git a/osi/core/eqos_mmc.c b/osi/core/eqos_mmc.c index af9337d..0ded1bd 100644 --- a/osi/core/eqos_mmc.c +++ b/osi/core/eqos_mmc.c @@ -259,6 +259,18 @@ void eqos_read_mmc(struct osi_core_priv_data *osi_core) 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); diff --git a/osi/core/eqos_mmc.h b/osi/core/eqos_mmc.h index 8c293fa..bab9016 100644 --- a/osi/core/eqos_mmc.h +++ b/osi/core/eqos_mmc.h @@ -81,6 +81,10 @@ #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 diff --git a/osi/core/libnvethernetrm.export b/osi/core/libnvethernetrm.export index 78c1fe6..9808256 100644 --- a/osi/core/libnvethernetrm.export +++ b/osi/core/libnvethernetrm.export @@ -60,3 +60,4 @@ osi_set_systime_to_mac osi_read_mmc osi_reset_mmc osi_validate_core_regs +osi_configure_eee diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 576a494..07384c1 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -916,3 +916,19 @@ int osi_reset_mmc(struct osi_core_priv_data *osi_core) return -1; } + +int osi_configure_eee(struct osi_core_priv_data *osi_core, + unsigned int tx_lpi_enabled, unsigned int tx_lpi_timer) +{ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->core_init != OSI_NULL) && + (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->ops->configure_eee(osi_core, tx_lpi_enabled, + tx_lpi_timer); + return 0; + } + + return -1; +} From eeb8a049428f51469dd6093badde11a027258bbc Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Thu, 31 Oct 2019 14:27:18 +0530 Subject: [PATCH 065/458] nvethernetrm: add rx error stats add rx frame error stats Bug 200561724 Change-Id: I284fde9c26559627832f6df5c059a9e201e967ec Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2229248 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_dma.h | 2 ++ osi/dma/libnvethernetcl.export | 1 + osi/dma/osi_dma_txrx.c | 8 ++++++++ 3 files changed, 11 insertions(+) diff --git a/include/osi_dma.h b/include/osi_dma.h index a4566f6..94768c7 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -130,6 +130,8 @@ struct osi_pkt_err_stats { unsigned long underflow_error; /** Rx CRC Error */ unsigned long rx_crc_error; + /** Rx Frame Error */ + unsigned long rx_frame_error; }; /** diff --git a/osi/dma/libnvethernetcl.export b/osi/dma/libnvethernetcl.export index 5e029d3..2a553d2 100644 --- a/osi/dma/libnvethernetcl.export +++ b/osi/dma/libnvethernetcl.export @@ -40,3 +40,4 @@ osi_hw_dma_deinit osi_init_dma_ops osi_validate_dma_regs osi_config_slot_function +osi_clear_tx_pkt_err_stats diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 50d1a51..fc5506f 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -188,6 +188,14 @@ static inline void get_rx_err_stats(struct osi_rx_desc *rx_desc, 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); + } } int osi_process_rx_completions(struct osi_dma_priv_data *osi, From 3bd145fc0e8dc260bfcfa093ed630b8703f064fa Mon Sep 17 00:00:00 2001 From: Mahesh Patil <maheshp@nvidia.com> Date: Thu, 21 Nov 2019 14:29:08 -0800 Subject: [PATCH 066/458] nvethernetrm: Harden while loops Issue: Unsigned int variable in loop condition can be stuck forever if variable becomes uint_max-1 for unknown reason Fix: Add acceptable range condition check for loops Bug 2715343 Change-Id: Ic9b6d1c7753ffca98d152e8dc9ea3b1805c2392d Signed-off-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2244768 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/dma/osi_dma.c | 3 ++- osi/dma/osi_dma_txrx.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 6d731e2..35dfa5f 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -205,7 +205,8 @@ int osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, } /* Refill buffers */ - while (rx_ring->refill_idx != rx_ring->cur_rx_idx) { + while (rx_ring->refill_idx != rx_ring->cur_rx_idx && + rx_ring->refill_idx < RX_DESC_CNT) { rx_swcx = rx_ring->rx_swcx + rx_ring->refill_idx; rx_desc = rx_ring->rx_desc + rx_ring->refill_idx; diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index fc5506f..8096e12 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -421,7 +421,7 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi, osi->dstats.tx_clean_n[chan] = osi_update_stats_counter(osi->dstats.tx_clean_n[chan], 1U); - while (entry != tx_ring->cur_tx_idx) { + while (entry != tx_ring->cur_tx_idx && entry < TX_DESC_CNT) { osi_memset(txdone_pkt_cx, 0U, sizeof(*txdone_pkt_cx)); tx_desc = tx_ring->tx_desc + entry; From fa3aa812a9154262c63e44500147140d444b16dd Mon Sep 17 00:00:00 2001 From: Srinivas Ramachandran <srinivasra@nvidia.com> Date: Thu, 26 Dec 2019 12:23:54 -0800 Subject: [PATCH 067/458] nvethernetrm: Fix validation of incorrect func. pointer Issue: The OSI interface API osi_configure_eee validates function pointer osi_core_ops->core_init instead of osi_core_ops->configure_eee. This is a copy paste error. Fix: Validate the correct function pointer osi_core_ops->configure_eee. Bug 2594864 Change-Id: I9e291f03debf508c80cff0a9d63af872faa7856b Signed-off-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2269269 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/osi_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 07384c1..7893876 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -921,7 +921,7 @@ int osi_configure_eee(struct osi_core_priv_data *osi_core, unsigned int tx_lpi_enabled, unsigned int tx_lpi_timer) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->core_init != OSI_NULL) && + (osi_core->ops->configure_eee != OSI_NULL) && (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)) { From 39d93d0f9234b990e126c0a62aa7966015844fa9 Mon Sep 17 00:00:00 2001 From: Mahesh Patil <maheshp@nvidia.com> Date: Tue, 1 Oct 2019 16:20:32 -0700 Subject: [PATCH 068/458] nvethernetrm: Rename functions to match close functionality Issue: rename functions to match close functionality Fix: 1) Renamed osi_poll_for_swr() to osi_poll_for_mac_reset_complete() 2) Renamed adjust_systime() to adjust_mactime() 3) Renamed eqos_adjust_systime() to eqos_adjust_mactime() 3) Updated ether_adjust_time() description Bug 2715276 Change-Id: I6c86b6f8e0b50607acbaaf9689757dcfc683a75d Signed-off-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2209751 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_core.h | 17 +++++++++-------- osi/core/eqos_core.c | 11 ++++++----- osi/core/libnvethernetrm.export | 2 +- osi/core/osi_core.c | 14 +++++++------- 4 files changed, 23 insertions(+), 21 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index d28f2d6..2d2c54b 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -231,8 +231,8 @@ struct osi_core_ops { unsigned int nsec); /** Called to set the addend value to adjust the time */ int (*config_addend)(void *addr, unsigned int addend); - /** Called to adjust the system time */ - int (*adjust_systime)(void *addr, unsigned int sec, unsigned int nsec, + /** Called to adjust the mac time */ + int (*adjust_mactime)(void *addr, unsigned int sec, unsigned int nsec, unsigned int neg_adj, unsigned int one_nsec_accuracy); /** Called to get the current time from MAC */ @@ -350,7 +350,7 @@ struct osi_core_priv_data { }; /** - * @brief osi_poll_for_swr - Poll Software reset bit in MAC HW + * @brief osi_poll_for_mac_reset_complete - Poll Software reset bit in MAC HW * * Algorithm: Invokes EQOS routine to check for SWR (software reset) * bit in DMA Basic mode register to make sure IP reset was successful. @@ -363,7 +363,7 @@ struct osi_core_priv_data { * @retval -1 on failure. */ -int osi_poll_for_swr(struct osi_core_priv_data *osi_core); +int osi_poll_for_mac_reset_complete(struct osi_core_priv_data *osi_core); /** * @brief osi_set_mdc_clk_rate - Derive MDC clock based on provided AXI_CBB clk. @@ -393,7 +393,8 @@ int osi_set_mdc_clk_rate(struct osi_core_priv_data *osi_core, * @param[in] rx_fifo_size: OSI core private data structure. * * @note - * 1) MAC should be out of reset. See osi_poll_for_swr() for details. + * 1) MAC should be out of reset. See osi_poll_for_mac_reset_complete() + * 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. @@ -900,13 +901,13 @@ int osi_set_systime_to_mac(struct osi_core_priv_data *osi_core, int osi_adjust_freq(struct osi_core_priv_data *osi_core, int ppb); /** - * @brief osi_adjust_time - Adjust time + * @brief osi_adjust_time - Adjust MAC time with system time * * 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] delta: Delta time + * @param[in] nsec_delta: Delta time in nano seconds * * @note * 1) MAC should be init and started. see osi_start_mac() @@ -915,7 +916,7 @@ int osi_adjust_freq(struct osi_core_priv_data *osi_core, int ppb); * @retval 0 on success * @retval -1 on failure. */ -int osi_adjust_time(struct osi_core_priv_data *osi_core, long delta); +int osi_adjust_time(struct osi_core_priv_data *osi_core, long long nsec_delta); /** * @brief osi_get_systime_from_mac - Get system time diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index edadd7c..9d380ee 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1325,7 +1325,8 @@ static void eqos_configure_dma(void *base) * @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. + * @note 1) MAC should be out of reset. See osi_poll_for_mac_reset_complete() + * 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. @@ -2946,9 +2947,9 @@ static inline int eqos_poll_for_update_ts_complete(void *addr, } /** - * @brief eqos_adjust_systime - Adjust system time + * @brief eqos_adjust_mactime - Adjust MAC time with system time * - * Algorithm: Update the 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. @@ -2963,7 +2964,7 @@ static inline int eqos_poll_for_update_ts_complete(void *addr, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_adjust_systime(void *addr, unsigned int sec, unsigned int nsec, +static int eqos_adjust_mactime(void *addr, unsigned int sec, unsigned int nsec, unsigned int add_sub, unsigned int one_nsec_accuracy) { @@ -3336,7 +3337,7 @@ static struct osi_core_ops eqos_core_ops = { .update_vlan_id = eqos_update_vlan_id, .set_systime_to_mac = eqos_set_systime_to_mac, .config_addend = eqos_config_addend, - .adjust_systime = eqos_adjust_systime, + .adjust_mactime = eqos_adjust_mactime, .get_systime_from_mac = eqos_get_systime_from_mac, .config_tscr = eqos_config_tscr, .config_ssir = eqos_config_ssir, diff --git a/osi/core/libnvethernetrm.export b/osi/core/libnvethernetrm.export index 9808256..9fe8f2e 100644 --- a/osi/core/libnvethernetrm.export +++ b/osi/core/libnvethernetrm.export @@ -26,7 +26,7 @@ osi_init_core_ops osi_write_phy_reg osi_read_phy_reg -osi_poll_for_swr +osi_poll_for_mac_reset_complete osi_set_mdc_clk_rate osi_hw_core_init osi_hw_core_deinit diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 7893876..d626287 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -192,7 +192,7 @@ int osi_init_core_ops(struct osi_core_priv_data *osi_core) return -1; } -int osi_poll_for_swr(struct osi_core_priv_data *osi_core) +int osi_poll_for_mac_reset_complete(struct osi_core_priv_data *osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->poll_for_swr != OSI_NULL)) { @@ -773,7 +773,7 @@ int osi_adjust_freq(struct osi_core_priv_data *osi_core, int ppb) return ret; } -int osi_adjust_time(struct osi_core_priv_data *osi_core, long delta) +int osi_adjust_time(struct osi_core_priv_data *osi_core, long long nsec_delta) { unsigned int neg_adj = 0; unsigned int sec = 0, nsec = 0; @@ -782,11 +782,11 @@ int osi_adjust_time(struct osi_core_priv_data *osi_core, long delta) unsigned long udelta = 0; int ret = -1; - if (delta < 0) { + if (nsec_delta < 0) { neg_adj = 1; - delta = -delta; + nsec_delta = -nsec_delta; } - udelta = (unsigned long) delta; + udelta = (unsigned long long) nsec_delta; quotient = div_u64_rem(udelta, OSI_NSEC_PER_SEC, &reminder); if (quotient <= UINT_MAX) { sec = (unsigned int)quotient; @@ -800,8 +800,8 @@ int osi_adjust_time(struct osi_core_priv_data *osi_core, long delta) } if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->adjust_systime != OSI_NULL)) { - ret = osi_core->ops->adjust_systime(osi_core->base, sec, nsec, + (osi_core->ops->adjust_mactime != OSI_NULL)) { + ret = osi_core->ops->adjust_mactime(osi_core->base, sec, nsec, neg_adj, osi_core->ptp_config.one_nsec_accuracy); } From dd9542ab9ae6cf8bd354b3295a7b520f4479e199 Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Fri, 3 Jan 2020 12:17:03 +0530 Subject: [PATCH 069/458] nvethernetrm: Fix invalid return for slot function Handle OSI slot function API return value properly on success case. Bug 200580967 Change-Id: Ibb5715d9d0943fa81e0a2ff9efef27782d15feaa Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2272788 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Narayan Reddy <narayanr@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/dma/osi_dma.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 35dfa5f..c66ca3a 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -285,7 +285,6 @@ int osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) int osi_config_slot_function(struct osi_dma_priv_data *osi_dma, unsigned int set) { - int ret = -1; unsigned int i = 0U, chan = 0U, interval = 0U; struct osi_tx_ring *tx_ring = OSI_NULL; @@ -343,7 +342,7 @@ int osi_config_slot_function(struct osi_dma_priv_data *osi_dma, } } - return ret; + return 0; } int osi_validate_dma_regs(struct osi_dma_priv_data *osi_dma) From cc7dcd40bd05fd167aac569a886de69cd41a30e3 Mon Sep 17 00:00:00 2001 From: Srinivas Ramachandran <srinivasra@nvidia.com> Date: Tue, 12 Nov 2019 14:10:12 -0800 Subject: [PATCH 070/458] nvethernetrm: Honor budget for processing tx completions Issue: osi_process_tx_completions is run in the BH for processing Tx done irq. This function always loops till the Tx status for all packets that are Tx'd so far is processed. 1) The NAPI budget for this Tx completions handler is not honored. 2) The variable 'processed' is expected to keep track of Tx'd packets. Currently it is counting Tx'd descriptors. There can be multiple Tx descriptors consumed for one packet. Fix: 1) Add budget parameter to osi_process_tx_completions() API. 2) Break out of loop in this API if packets to process exceeds budget 3) Increment the processed count variable only after checking last descriptor for a packet. Bug 2756439 Change-Id: Id538343f6853881ea41109b8b46c8d0e82dce98a Signed-off-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2237822 Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Praveen Mallaiah <pmallaiah@nvidia.com> Tested-by: Praveen Mallaiah <pmallaiah@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_dma.h | 3 ++- osi/dma/osi_dma_txrx.c | 37 +++++++++++++++++++++++++++---------- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/include/osi_dma.h b/include/osi_dma.h index 94768c7..bd1d791 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -615,6 +615,7 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan); * * @param[in] osi: OSI private data structure. * @param[in] chan: Channel number on which Tx complete need to be done. + * @param[in] budget: Threshold for reading the packets at a time. * * @note * 1) MAC needs to be out of reset and proper clocks need to be configured. @@ -624,7 +625,7 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan); * @returns Number of decriptors (buffers) proccessed. */ int osi_process_tx_completions(struct osi_dma_priv_data *osi, - unsigned int chan); + unsigned int chan, int budget); /** * @brief osi_process_rx_completions - Read data from rx channel descriptors diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 8096e12..fe9c080 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -277,6 +277,24 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, return received; } +/** + * @brief inc_tx_pkt_stats - Increment Tx packet count Stats + * + * Algorithm: This routine will be invoked by OSI layer internally to increment + * stats for successfully transmitted packets on certain DMA channel. + * + * @param[in] osi: 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, + unsigned int chan) +{ + osi->dstats.q_tx_pkt_n[chan] = + osi_update_stats_counter(osi->dstats.q_tx_pkt_n[chan], 1UL); + osi->dstats.tx_pkt_n = + osi_update_stats_counter(osi->dstats.tx_pkt_n, 1UL); +} + /** * @brief get_tx_err_stats - Detect Errors from Tx Status * @@ -407,7 +425,7 @@ int osi_clear_rx_pkt_err_stats(struct osi_dma_priv_data *osi_dma) } int osi_process_tx_completions(struct osi_dma_priv_data *osi, - unsigned int chan) + unsigned int chan, int budget) { struct osi_tx_ring *tx_ring = osi->tx_ring[chan]; struct osi_txdone_pkt_cx *txdone_pkt_cx = &tx_ring->txdone_pkt_cx; @@ -421,7 +439,8 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi, osi->dstats.tx_clean_n[chan] = osi_update_stats_counter(osi->dstats.tx_clean_n[chan], 1U); - while (entry != tx_ring->cur_tx_idx && entry < TX_DESC_CNT) { + while (entry != tx_ring->cur_tx_idx && entry < TX_DESC_CNT && + processed < budget) { osi_memset(txdone_pkt_cx, 0U, sizeof(*txdone_pkt_cx)); tx_desc = tx_ring->tx_desc + entry; @@ -437,6 +456,12 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi, txdone_pkt_cx->flags |= OSI_TXDONE_CX_ERROR; /* fill packet error stats */ get_tx_err_stats(tx_desc, osi->pkt_err_stats); + } else { + inc_tx_pkt_stats(osi, chan); + } + + if (processed < INT_MAX) { + processed++; } } @@ -482,9 +507,6 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi, tx_swcx->buf_phy_addr = 0; tx_swcx->is_paged_buf = 0; INCR_TX_DESC_INDEX(entry, 1U); - if (processed < INT_MAX) { - processed++; - } /* Don't wait to update tx_ring->clean-idx. It will * be used by OSD layer to determine the num. of available @@ -492,11 +514,6 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi, * wake the corresponding transmit queue in OS layer. */ tx_ring->clean_idx = entry; - osi->dstats.q_tx_pkt_n[chan] = - osi_update_stats_counter(osi->dstats.q_tx_pkt_n[chan], - 1UL); - osi->dstats.tx_pkt_n = - osi_update_stats_counter(osi->dstats.tx_pkt_n, 1UL); } return processed; From aca1f7230c715eaf85c44b7e894610de29c4aeab Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Wed, 8 Jan 2020 16:23:00 +0530 Subject: [PATCH 071/458] nvethernetrm: Fix MISRA 15.6 violation Issue: Observed MISRA 15.6 rule violation on rx_dma_desc_initialization Fix: Address this violation properly Bug 200580977 Change-Id: Ie652a213c0990fd26ce8aaee95ca07c1ca3f1361 Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2275781 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/dma/osi_dma_txrx.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index fe9c080..aaf50eb 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -828,12 +828,14 @@ static int rx_dma_desc_initialization(struct osi_dma_priv_data *osi, /* reconfigure INTE bit if RX watchdog timer is enabled */ if (osi->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->use_rx_frames == OSI_ENABLE) { - if ((i % osi->rx_frames) == OSI_NONE) + if ((i % osi->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; + } } } From ebe0c832041fa7d741a83a0b2dc9ff165b1579f4 Mon Sep 17 00:00:00 2001 From: Srinivas Ramachandran <srinivasra@nvidia.com> Date: Sun, 22 Dec 2019 21:47:57 -0800 Subject: [PATCH 072/458] nvethernetrm: Add API to backup/restore registers Issue: During SOC suspend, the MAC is placed in reset. This causes all dynamic configurations done by SW on the MAC core registers is lost. When SOC resumes, MAC is initialized to power-on-default configuration, while other SW components still have previously set configuration. This results in mismatch between HW/SW configuration. Fix: Add APIs osi_save_registers(), osi_restore_registers() to backup and restore the MAC core configuration registers before suspend and after resume respectively. Bug 200561046 Change-Id: I6d7b39d39a6f3fa882cfd905bc49a5850163ea4c Signed-off-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2267390 Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Tested-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_common.h | 3 +- include/osi_core.h | 38 +++++++- osi/core/eqos_core.c | 179 ++++++++++++++++++++++++++++++++++++- osi/core/eqos_core.h | 206 ++++++++++++++++++++++++++++++++++--------- osi/core/osi_core.c | 25 +++++- 5 files changed, 405 insertions(+), 46 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index 7bd8aed..5363c43 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -180,6 +180,7 @@ /* FIXME add logic based on HW version */ #define EQOS_MAX_MAC_ADDRESS_FILTER 128U #define EQOS_MAX_L3_L4_FILTER 8U +#define EQOS_MAX_HTR_REGS 8U #define OSI_EQOS_MAX_NUM_CHANS 4U #define OSI_EQOS_MAX_NUM_QUEUES 4U #define OSI_L2_FILTER_INDEX_ANY 127U diff --git a/include/osi_core.h b/include/osi_core.h index 2d2c54b..f4043da 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -245,9 +245,14 @@ struct osi_core_ops { void (*read_mmc)(struct osi_core_priv_data *osi_core); /** Called to reset MMC HW counter structure */ void (*reset_mmc)(struct osi_core_priv_data *osi_core); + /** Called to configure EEE Tx LPI */ void (*configure_eee)(struct osi_core_priv_data *osi_core, unsigned int tx_lpi_enabled, unsigned int tx_lpi_timer); + /** Called to save MAC register space during SOC suspend */ + void (*save_registers)(struct osi_core_priv_data *osi_core); + /** Called to restore MAC control registers during SOC resume */ + void (*restore_registers)(struct osi_core_priv_data *osi_core); }; /** @@ -342,6 +347,8 @@ struct osi_core_priv_data { /** 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 */ + void *backup_config; /** VLAN tag stripping enable(1) or disable(0) */ unsigned int strip_vlan_tag; /** L3L4 filter bit bask, set index corresponding bit for @@ -969,6 +976,7 @@ int osi_ptp_configuration(struct osi_core_priv_data *osi_core, */ struct osi_core_ops *eqos_get_hw_core_ops(void); void *eqos_get_core_safety_config(void); +void *eqos_get_core_backup_config(void); /** * @brief osi_l3l4_filter - invoke OSI call to add L3/L4 @@ -1023,4 +1031,32 @@ int osi_l3l4_filter(struct osi_core_priv_data *osi_core, int osi_configure_eee(struct osi_core_priv_data *osi_core, unsigned int tx_lpi_enabled, unsigned int tx_lpi_timer); + +/** + * @brief osi_save_registers - Take backup of MAC MMIO address space + * + * @param[in] osi_core: OSI core private data structure. + * + * @note + * 1) MAC and PHY should be init and started. see osi_start_mac() + * 2) No further configuration change in MAC shall be done after invoking + * this API + * + * @retval 0 on success + * @retval -1 on failure. + */ +int osi_save_registers(struct osi_core_priv_data *osi_core); + +/** + * @brief osi_restore_registers - Restore backup of MAC MMIO address space + * + * @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. + */ +int osi_restore_registers(struct osi_core_priv_data *osi_core); #endif /* OSI_CORE_H */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 9d380ee..3f72d7d 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -31,6 +31,11 @@ */ static struct core_func_safety eqos_core_safety_config; +/** + * @brief eqos_core_backup_config - EQOS MAC core registers backup config + */ +static struct core_backup eqos_core_backup_config; + /** * @brief eqos_core_safety_writel - Write to safety critical register. * @@ -172,6 +177,123 @@ static void eqos_core_safety_init(struct osi_core_priv_data *osi_core) osi_lock_init(&config->core_safety_lock); } + +/** + * @brief Initialize the eqos_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 eqos_core_backup_init(struct osi_core_priv_data *osi_core) +{ + struct core_backup *config = &eqos_core_backup_config; + unsigned char *base = (unsigned char *)osi_core->base; + unsigned int 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 Read-validate HW registers for functional safety. * @@ -1345,6 +1467,7 @@ static int eqos_core_init(struct osi_core_priv_data *osi_core, unsigned int rx_fifo = 0; eqos_core_safety_init(osi_core); + eqos_core_backup_init(osi_core); /* PAD calibration */ ret = eqos_pad_calibrate(osi_core->base); @@ -3300,6 +3423,50 @@ static void eqos_configure_eee(struct osi_core_priv_data *osi_core, } } +/* + * @brief 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 none + */ +static inline void eqos_save_registers(struct osi_core_priv_data *osi_core) +{ + unsigned int 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_readl(config->reg_addr[i]); + } + } +} + +/** + * @brief Function to restore the backup of MAC registers during SOC resume. + * + * Algorithm: Restore the register values from the in memory backup taken using + * eqos_save_registers(). + * + * @param[in] osi_core: OSI core private data structure. + * + * @retval none + */ +static inline void eqos_restore_registers(struct osi_core_priv_data *osi_core) +{ + unsigned int 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_writel(config->reg_val[i], config->reg_addr[i]); + } + } +} + /** * @brief eqos_core_ops - EQOS MAC core operations */ @@ -3344,8 +3511,18 @@ static struct osi_core_ops eqos_core_ops = { .read_mmc = eqos_read_mmc, .reset_mmc = eqos_reset_mmc, .configure_eee = eqos_configure_eee, + .save_registers = eqos_save_registers, + .restore_registers = eqos_restore_registers, }; +/** + * @brief eqos_get_core_backup_config - EQOS MAC backup configuration + */ +void *eqos_get_core_backup_config(void) +{ + return &eqos_core_backup_config; +} + /** * @brief eqos_get_core_safety_config - EQOS MAC safety configuration */ diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index e8cf23f..64b1797 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -90,49 +90,41 @@ * @brief EQOS HW register offsets * @{ */ -#define EQOS_5_00_MAC_ARPPA 0x0210 -#define EQOS_4_10_MAC_ARPPA 0x0AE0 -#define EQOS_DMA_SBUS 0x1004 -#define EQOS_DMA_BMR 0x1000 -#define EQOS_MMC_CNTRL 0x0700 -#define EQOS_MAC_MA0HR 0x0300 -#define EQOS_MAC_MA0LR 0x0304 -#define EQOS_MAC_MCR 0x0000 -#define EQOS_MAC_VLAN_TAG 0x0050 -#define EQOS_MAC_VLANTIR 0x0060 -#define EQOS_MAC_IMR 0x00B4 -#define EQOS_DMA_ISR 0x1008 -#define EQOS_MAC_ISR 0x00B0 -#define EQOS_MAC_LPI_CSR 0x00D0 -#define EQOS_MAC_LPI_TIMER_CTRL 0x00D4 -#define EQOS_MAC_LPI_EN_TIMER 0x00D8 -#define EQOS_MAC_RQC1R 0x00A4 -#define EQOS_MAC_RQC2R 0x00A8 -#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_RQC0R 0x00A0 -#define EQOS_MAC_PMTCSR 0x00C0 -#define EQOS_MAC_PCS 0x00F8 -#define EQOS_MAC_ANS 0x00E4 -/* 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_MAP_DCS_EN 0x13121110U -#define EQOS_MAC_EXTR 0x0004 -#define EQOS_MAC_RX_FLW_CTRL 0x0090 -#define EQOS_MAC_QX_TX_FLW_CTRL(x) ((0x0004U * (x)) + 0x0070U) -/*MAC Filtering*/ +#define EQOS_MAC_MCR 0x0000 +#define EQOS_MAC_EXTR 0x0004 +#define EQOS_MAC_PFR 0x0008U #define EQOS_MAC_HTR_REG(x) ((0x0004U * (x)) + 0x0010U) -/* x will be index from 0 to 127 to write*/ +#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 +#define EQOS_MAC_ANS 0x00E4 +#define EQOS_MAC_PCS 0x00F8 +#define EQOS_5_00_MAC_ARPPA 0x0210 +#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_MAC_PFR 0x0008U +#define EQOS_4_10_MAC_ARPPA 0x0AE0 #define EQOS_MAC_TCR 0x0B00 #define EQOS_MAC_SSIR 0x0B04 #define EQOS_MAC_STSR 0x0B08 @@ -140,6 +132,9 @@ #define EQOS_MAC_STSUR 0x0B10 #define EQOS_MAC_STNSUR 0x0B14 #define EQOS_MAC_TAR 0x0B18 +#define EQOS_DMA_BMR 0x1000 +#define EQOS_DMA_SBUS 0x1004 +#define EQOS_DMA_ISR 0x1008 /** @} */ /** @@ -148,15 +143,15 @@ * @brief EQOS MTL HW Register offsets * @{ */ +#define EQOS_MTL_OP_MODE 0x0C00 +#define EQOS_MTL_RXQ_DMA_MAP0 0x0C30 #define EQOS_MTL_CHX_TX_OP_MODE(x) ((0x0040U * (x)) + 0x0D00U) -#define EQOS_MTL_TXQ_QW(x) ((0x0040U * (x)) + 0x0D18U) -#define EQOS_MTL_CHX_RX_OP_MODE(x) ((0x0040U * (x)) + 0x0D30U) #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_RXQ_DMA_MAP0 0x0C30 -#define EQOS_MTL_OP_MODE 0x0C00 +#define EQOS_MTL_CHX_RX_OP_MODE(x) ((0x0040U * (x)) + 0x0D30U) /** @} */ /** @@ -165,11 +160,11 @@ * @brief EQOS Wrapper register offsets * @{ */ -#define EQOS_PAD_AUTO_CAL_CFG 0x8804U -#define EQOS_PAD_AUTO_CAL_STAT 0x880CU -#define EQOS_PAD_CRTL 0x8800U #define EQOS_CLOCK_CTRL_0 0x8000U #define EQOS_AXI_ASID_CTRL 0x8400U +#define EQOS_PAD_CRTL 0x8800U +#define EQOS_PAD_AUTO_CAL_CFG 0x8804U +#define EQOS_PAD_AUTO_CAL_STAT 0x880CU /** @} */ /** @@ -178,6 +173,9 @@ * @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_MAP_DCS_EN 0x13121110U #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) @@ -486,4 +484,128 @@ struct core_func_safety { * validation is in-progress */ unsigned int core_safety_lock; }; + +/** + * @addtogroup EQOS-HW-BACKUP + * + * @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. + */ +#define EQOS_MAX_BAK_IDX ((EQOS_PAD_AUTO_CAL_CFG_BAK_IDX + 1U)) + +/** + * @brief core_backup - Struct used to store backup of core HW registers. + */ +struct core_backup { + /** Array of reg MMIO addresses (base of EQoS + offset of reg) */ + void *reg_addr[EQOS_MAX_BAK_IDX]; + /** Array of value stored in each corresponding register */ + unsigned int reg_val[EQOS_MAX_BAK_IDX]; +}; + +/** @} */ #endif diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index d626287..50a135a 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -186,6 +186,7 @@ int osi_init_core_ops(struct osi_core_priv_data *osi_core) * like periodic read-verify. */ osi_core->safety_config = (void *)eqos_get_core_safety_config(); + osi_core->backup_config = (void *)eqos_get_core_backup_config(); return 0; } @@ -932,3 +933,25 @@ int osi_configure_eee(struct osi_core_priv_data *osi_core, return -1; } + +int osi_save_registers(struct osi_core_priv_data *osi_core) +{ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->save_registers != OSI_NULL)) { + osi_core->ops->save_registers(osi_core); + return 0; + } + + return -1; +} + +int osi_restore_registers(struct osi_core_priv_data *osi_core) +{ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->restore_registers != OSI_NULL)) { + osi_core->ops->restore_registers(osi_core); + return 0; + } + + return -1; +} From 5e55e6a77b18c5e8fb2953b6a3324db12d5812bc Mon Sep 17 00:00:00 2001 From: narayanr <narayanr@nvidia.com> Date: Sun, 12 Jan 2020 14:01:25 +0530 Subject: [PATCH 073/458] nvethernetrm: fix doxygen comments Bug 200577839 Bug 200580977 Change-Id: I99e93a2b216f57e1877418ce4fe1d89088a618fe Signed-off-by: narayanr <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2277959 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_dma.h | 6 +++++- osi/core/eqos_core.c | 2 +- osi/core/eqos_core.h | 10 ---------- osi/core/osi_core.c | 28 ++++++++++++++++++++++++++++ 4 files changed, 34 insertions(+), 12 deletions(-) diff --git a/include/osi_dma.h b/include/osi_dma.h index bd1d791..76bf6a9 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -84,7 +84,11 @@ * @addtogroup EQOS-CHK Checksum offload results * * @brief Flag to indicate the result from checksum offload engine - * to SW network stack in receive path + * 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 */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 3f72d7d..61d2c9b 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -3366,7 +3366,7 @@ static inline void eqos_disable_tx_lpi(void *addr) * 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_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. * diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 64b1797..baf55da 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -391,16 +391,6 @@ (TEGRA_SID_EQOS)) /** @} */ -/** - * @brief update_ehfc_rfa_rfd - Update EHFC, RFD and RSA values - * - * Algorithm: Calculates 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 - * - * @param[in] rx_fifo: Rx FIFO size. - * @param[in] value: Stores RFD and RSA values - */ void update_ehfc_rfa_rfd(unsigned int rx_fifo, unsigned int *value); /** diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 50a135a..e092b39 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -473,6 +473,20 @@ int osi_l2_filter(struct osi_core_priv_data *osi_core, 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 + * + * @note MAC needs to be out of reset and proper clock configured. + * + * @retval 0 on Success + * @retval -1 on Failure + */ static inline int helper_l4_filter(struct osi_core_priv_data *osi_core, struct osi_l3_l4_filter l_filter, unsigned int type, @@ -511,6 +525,20 @@ static inline int helper_l4_filter(struct osi_core_priv_data *osi_core, } +/** + * @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 + * + * @note MAC needs to be out of reset and proper clock configured. + * + * @retval 0 on Success + * @retval -1 on Failure + */ static inline int helper_l3_filter(struct osi_core_priv_data *osi_core, struct osi_l3_l4_filter l_filter, unsigned int type, From 34b0ed05300bbb53ccc3d3a0f314fad874369161 Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Mon, 13 Jan 2020 14:57:01 +0530 Subject: [PATCH 074/458] nvethernetrm: Add PHY MDIO read/write callbacks Adds support for MDIO read/write callbacks and moves EQOS specific code from OSI layer to EQOS layer. Bug 200565891 Change-Id: I44d875ab88d8802266954c6d6362a795d22e89bb Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2223424 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: Bibek Basu <bbasu@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_core.h | 9 +++ osi/core/eqos_core.c | 156 +++++++++++++++++++++++++++++++++++++++++++ osi/core/eqos_core.h | 12 ++++ osi/core/osi_core.c | 148 +++------------------------------------- 4 files changed, 186 insertions(+), 139 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index f4043da..a56e814 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -253,6 +253,15 @@ struct osi_core_ops { void (*save_registers)(struct osi_core_priv_data *osi_core); /** Called to restore MAC control registers during SOC resume */ void (*restore_registers)(struct osi_core_priv_data *osi_core); + /** Called to write into a PHY reg over MDIO bus */ + int (*write_phy_reg)(struct osi_core_priv_data *osi_core, + unsigned int phyaddr, + unsigned int phyreg, + unsigned short phydata); + /** Called to read from a PHY reg over MDIO bus */ + int (*read_phy_reg)(struct osi_core_priv_data *osi_core, + unsigned int phyaddr, + unsigned int phyreg); }; /** diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 61d2c9b..971d4c9 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -3467,6 +3467,160 @@ static inline void eqos_restore_registers(struct osi_core_priv_data *osi_core) } } +/** + * @brief poll_for_mii_idle Query the status of an ongoing DMA transfer + * + * @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 inline int poll_for_mii_idle(struct osi_core_priv_data *osi_core) +{ + /* half sec timeout */ + unsigned int retry = 50000; + unsigned int mac_gmiiar; + unsigned int count; + int cond = 1; + + count = 0; + while (cond == 1) { + if (count > retry) { + OSI_ERR(osi_core->osd, + OSI_LOG_ARG_HW_FAIL, + "MII operation timed out\n", + 0ULL); + return -1; + } + count++; + + mac_gmiiar = osi_readl((unsigned char *)osi_core->base + + EQOS_MAC_MDIO_ADDRESS); + if ((mac_gmiiar & EQOS_MAC_GMII_BUSY) == 0U) { + /* exit loop */ + cond = 0; + } else { + /* wait on GMII Busy set */ + osd_udelay(10U); + } + } + + return 0; +} + +static int eqos_write_phy_reg(struct osi_core_priv_data *osi_core, + unsigned int phyaddr, + unsigned int phyreg, + unsigned short phydata) +{ + unsigned int mac_gmiiar; + unsigned int mac_gmiidr; + int ret = 0; + + if (osi_core == OSI_NULL) { + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "osi_core is NULL\n", + 0ULL); + return -1; + } + + /* 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; + } + + mac_gmiidr = osi_readl((unsigned char *)osi_core->base + + EQOS_MAC_MDIO_DATA); + mac_gmiidr = ((mac_gmiidr & EQOS_MAC_GMIIDR_GD_WR_MASK) | + ((phydata) & EQOS_MAC_GMIIDR_GD_MASK)); + + osi_writel(mac_gmiidr, (unsigned char *)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_readl((unsigned char *)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_writel(mac_gmiiar, (unsigned char *)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; + } + + return ret; +} + +static int eqos_read_phy_reg(struct osi_core_priv_data *osi_core, + unsigned int phyaddr, + unsigned int phyreg) +{ + unsigned int mac_gmiiar; + unsigned int mac_gmiidr; + unsigned int data; + int ret = 0; + + if (osi_core == OSI_NULL) { + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "osi_core is NULL\n", + 0ULL); + return -1; + } + + /* 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; + } + + mac_gmiiar = osi_readl((unsigned char *)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_writel(mac_gmiiar, (unsigned char *)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_readl((unsigned char *)osi_core->base + + EQOS_MAC_MDIO_DATA); + data = (mac_gmiidr & EQOS_MAC_GMIIDR_GD_MASK); + + return (int)data; +} + /** * @brief eqos_core_ops - EQOS MAC core operations */ @@ -3513,6 +3667,8 @@ static struct osi_core_ops eqos_core_ops = { .configure_eee = eqos_configure_eee, .save_registers = eqos_save_registers, .restore_registers = eqos_restore_registers, + .write_phy_reg = eqos_write_phy_reg, + .read_phy_reg = eqos_read_phy_reg, }; /** diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index baf55da..9f8f8cb 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -109,6 +109,8 @@ #define EQOS_MAC_LPI_EN_TIMER 0x00D8 #define EQOS_MAC_ANS 0x00E4 #define EQOS_MAC_PCS 0x00F8 +#define EQOS_MAC_MDIO_ADDRESS 0x0200 +#define EQOS_MAC_MDIO_DATA 0x0204 #define EQOS_5_00_MAC_ARPPA 0x0210 #define EQOS_MAC_MA0HR 0x0300 #define EQOS_MAC_ADDRH(x) ((0x0008U * (x)) + 0x0300U) @@ -369,6 +371,16 @@ #define EQOS_MAC_TCR_TSCTRLSSR OSI_BIT(9) #define EQOS_MAC_SSIR_SSINC_SHIFT 16U #define EQOS_MAC_STNSR_TSSS_MASK 0x7FFFFFFFU +#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_DMA_CHX_STATUS_TPS OSI_BIT(1) #define EQOS_DMA_CHX_STATUS_TBU OSI_BIT(2) diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index e092b39..45790b4 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -23,157 +23,27 @@ #include <osi_core.h> #include <osd.h> -/** - * @addtogroup MDIO Macros - * @brief Helper MACROS for MDIO - * @{ - */ -#define MAC_MDIO_ADDRESS 0x200 -#define MAC_GMII_BUSY 0x00000001U - -#define MAC_MDIO_DATA 0x204 - -#define MAC_GMIIDR_GD_WR_MASK 0xffff0000U -#define MAC_GMIIDR_GD_MASK 0xffffU - -#define MDIO_PHY_ADDR_SHIFT 21U -#define MDIO_PHY_REG_SHIFT 16U -#define MDIO_MII_WRITE OSI_BIT(2) -/** @} */ - -/** - * @brief poll_for_mii_idle Query the status of an ongoing DMA transfer - * - * @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 inline int poll_for_mii_idle(struct osi_core_priv_data *osi_core) -{ - /* half sec timeout */ - unsigned int retry = 50000; - unsigned int mac_gmiiar; - unsigned int count; - int cond = 1; - - count = 0; - while (cond == 1) { - if (count > retry) { - OSI_ERR(osi_core->osd, - OSI_LOG_ARG_HW_FAIL, - "MII operation timed out\n", - 0ULL); - return -1; - } - - count++; - - mac_gmiiar = osi_readl((unsigned char *)osi_core->base + - MAC_MDIO_ADDRESS); - - if ((mac_gmiiar & MAC_GMII_BUSY) == 0U) { - cond = 0; - } else { - /* wait on GMII Busy set */ - osd_udelay(10U); - } - } - - return 0; -} - int osi_write_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, unsigned int phyreg, unsigned short phydata) { - unsigned int mac_gmiiar; - unsigned int mac_gmiidr; - int ret = 0; - - if (osi_core == OSI_NULL) { - return -1; + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->write_phy_reg != OSI_NULL)) { + return osi_core->ops->write_phy_reg(osi_core, + phyaddr, phyreg, phydata); } - /* wait for any previous MII read/write operation to complete */ - ret = poll_for_mii_idle(osi_core); - if (ret < 0) { - return ret; - } - - mac_gmiidr = osi_readl((unsigned char *)osi_core->base + MAC_MDIO_DATA); - - mac_gmiidr = ((mac_gmiidr & MAC_GMIIDR_GD_WR_MASK) | - (((phydata) & MAC_GMIIDR_GD_MASK) << 0)); - - osi_writel(mac_gmiidr, (unsigned char *)osi_core->base + 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_readl((unsigned char *)osi_core->base + MAC_MDIO_ADDRESS); - mac_gmiiar = (mac_gmiiar & 0x12U); - mac_gmiiar = (mac_gmiiar | ((phyaddr) << MDIO_PHY_ADDR_SHIFT) | - ((phyreg) << MDIO_PHY_REG_SHIFT) | - ((osi_core->mdc_cr) << 8U) | - MDIO_MII_WRITE | MAC_GMII_BUSY); - - osi_writel(mac_gmiiar, (unsigned char *)osi_core->base + MAC_MDIO_ADDRESS); - - /* wait for MII write operation to complete */ - ret = poll_for_mii_idle(osi_core); - if (ret < 0) { - return ret; - } - - return ret; + return -1; } int osi_read_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, unsigned int phyreg) { - unsigned int mac_gmiiar; - unsigned int mac_gmiidr; - unsigned int data; - int ret = 0; - - if (osi_core == OSI_NULL) { - return -1; + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->read_phy_reg != OSI_NULL)) { + return osi_core->ops->read_phy_reg(osi_core, phyaddr, phyreg); } - /* wait for any previous MII read/write operation to complete */ - ret = poll_for_mii_idle(osi_core); - if (ret < 0) { - return ret; - } - - mac_gmiiar = osi_readl((unsigned char *)osi_core->base + 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 & 0x12U); - mac_gmiiar = mac_gmiiar | ((phyaddr) << MDIO_PHY_ADDR_SHIFT) | - ((phyreg) << MDIO_PHY_REG_SHIFT) | - (osi_core->mdc_cr) << 8U | ((0x3U) << 2U) | MAC_GMII_BUSY; - osi_writel(mac_gmiiar, (unsigned char *)osi_core->base + MAC_MDIO_ADDRESS); - - /* wait for MII write operation to complete */ - ret = poll_for_mii_idle(osi_core); - if (ret < 0) { - return ret; - } - - mac_gmiidr = osi_readl((unsigned char *)osi_core->base + MAC_MDIO_DATA); - data = (mac_gmiidr & 0x0000FFFFU); - - return (int)data; + return -1; } int osi_init_core_ops(struct osi_core_priv_data *osi_core) From db80beb30312a58304621a756c93d16833ed2252 Mon Sep 17 00:00:00 2001 From: Mahesh Patil <maheshp@nvidia.com> Date: Thu, 7 Nov 2019 12:24:47 -0800 Subject: [PATCH 075/458] nvethernetrm: Add const to unmodfied arguments Issue: Avoid accidental modification of func call arguments in OSI layer Fix: Add const keyword to func parameter unmodified by OSI layer Bug 2715405 Change-Id: I6fc60c5e2b52e638f3dd6acc1f065622ead4b658 Signed-off-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2234454 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Ajay Gupta <ajayg@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_core.h | 317 +++++++++++++++++++++++-------------------- osi/core/eqos_core.c | 210 +++++++++++++++------------- osi/core/osi_core.c | 138 ++++++++++--------- 3 files changed, 360 insertions(+), 305 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index a56e814..82bd47d 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -136,132 +136,142 @@ struct osi_core_ops { /** Called to poll for software reset bit */ int (*poll_for_swr)(void *ioaddr); /** Called to initialize MAC and MTL registers */ - int (*core_init)(struct osi_core_priv_data *osi_core, - unsigned int tx_fifo_size, - unsigned int rx_fifo_size); + int (*core_init)(struct osi_core_priv_data *const osi_core, + const unsigned int tx_fifo_size, + const unsigned int rx_fifo_size); /** Called to deinitialize MAC and MTL registers */ - void (*core_deinit)(struct osi_core_priv_data *osi_core); + void (*core_deinit)(struct osi_core_priv_data *const osi_core); /** Called periodically to read and validate safety critical * registers against last written value */ - int (*validate_regs)(struct osi_core_priv_data *osi_core); + int (*validate_regs)(struct osi_core_priv_data *const osi_core); /** Called to start MAC Tx and Rx engine */ void (*start_mac)(void *addr); /** Called to stop MAC Tx and Rx engine */ void (*stop_mac)(void *addr); /** Called to handle common interrupt */ - void (*handle_common_intr)(struct osi_core_priv_data *osi_core); + void (*handle_common_intr)(struct osi_core_priv_data *const osi_core); /** Called to set the mode at MAC (full/duplex) */ - void (*set_mode)(void *ioaddr, int mode); + void (*set_mode)(void *ioaddr, const int mode); /** Called to set the speed (10/100/1000) at MAC */ - void (*set_speed)(void *ioaddr, int speed); + void (*set_speed)(void *ioaddr, const int speed); /** Called to do pad caliberation */ int (*pad_calibrate)(void *ioaddr); /** Called to set MDC clock rate for MDIO operation */ - void (*set_mdc_clk_rate)(struct osi_core_priv_data *osi_core, - unsigned long csr_clk_rate); + void (*set_mdc_clk_rate)(struct osi_core_priv_data *const osi_core, + const unsigned long csr_clk_rate); /** Called to flush MTL Tx queue */ - int (*flush_mtl_tx_queue)(void *ioaddr, unsigned int qinx); + int (*flush_mtl_tx_queue)(void *ioaddr, const unsigned int qinx); /** Called to configure MAC in loopback mode */ - int (*config_mac_loopback)(void *addr, unsigned int lb_mode); + int (*config_mac_loopback)(void *addr, const unsigned int lb_mode); /** Called to set av parameter */ - int (*set_avb_algorithm)(struct osi_core_priv_data *osi_core, - struct osi_core_avb_algorithm *avb); + int (*set_avb_algorithm)(struct osi_core_priv_data *const osi_core, + const struct osi_core_avb_algorithm *const avb); /** Called to get av parameter */ - int (*get_avb_algorithm)(struct osi_core_priv_data *osi_core, - struct osi_core_avb_algorithm *avb); + int (*get_avb_algorithm)(struct osi_core_priv_data *const osi_core, + struct osi_core_avb_algorithm *const avb); /** Called to configure MTL RxQ to forward the err pkt */ - int (*config_fw_err_pkts)(void *addr, unsigned int qinx, - unsigned int fw_err); + int (*config_fw_err_pkts)(void *addr, const unsigned int qinx, + const unsigned int fw_err); /** Called to configure the MTL to forward/drop tx status */ - int (*config_tx_status)(void *addr, unsigned int tx_status); + int (*config_tx_status)(void *addr, const unsigned int tx_status); /** Called to configure the MAC rx crc */ - int (*config_rx_crc_check)(void *addr, unsigned int crc_chk); + int (*config_rx_crc_check)(void *addr, const unsigned int crc_chk); /** Called to configure the MAC flow control */ - int (*config_flow_control)(void *addr, unsigned int flw_ctrl); + int (*config_flow_control)(void *addr, const unsigned int flw_ctrl); /** Called to enable/disable HW ARP offload feature */ - int (*config_arp_offload)(unsigned int mac_ver, void *addr, - unsigned int enable, unsigned char *ip_addr); + int (*config_arp_offload)(const unsigned int mac_ver, void *addr, + const unsigned int enable, + const unsigned char *ip_addr); /** Called to configure Rx Checksum offload engine */ - int (*config_rxcsum_offload)(void *addr, unsigned int enabled); + int (*config_rxcsum_offload)(void *addr, const unsigned int enabled); /** Called to config mac packet filter */ - int (*config_mac_pkt_filter_reg)(struct osi_core_priv_data *osi_core, - struct osi_filter *filter); + int (*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 */ - int (*update_mac_addr_low_high_reg)(struct osi_core_priv_data *osi_core, - struct osi_filter *filter); + int (*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 */ - int (*config_l3_l4_filter_enable)(void *base, unsigned int enable); + int (*config_l3_l4_filter_enable)(void *base, + const unsigned int enable); /** Called to configure L3 filter */ - int (*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); + int (*config_l3_filters)(struct osi_core_priv_data *const osi_core, + const unsigned int filter_no, + const unsigned int enb_dis, + const unsigned int ipv4_ipv6_match, + const unsigned int src_dst_addr_match, + const unsigned int perfect_inverse_match, + const unsigned int dma_routing_enable, + const unsigned int dma_chan); /** Called to update ip4 src or desc address */ - int (*update_ip4_addr)(struct osi_core_priv_data *osi_core, - unsigned int filter_no, unsigned char addr[], - unsigned int src_dst_addr_match); + int (*update_ip4_addr)(struct osi_core_priv_data *const osi_core, + const unsigned int filter_no, + const unsigned char addr[], + const unsigned int src_dst_addr_match); /** Called to update ip6 address */ - int (*update_ip6_addr)(struct osi_core_priv_data *osi_core, - unsigned int filter_no, unsigned short addr[]); + int (*update_ip6_addr)(struct osi_core_priv_data *const osi_core, + const unsigned int filter_no, + const unsigned short addr[]); /** Called to configure L4 filter */ - int (*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); + int (*config_l4_filters)(struct osi_core_priv_data *const osi_core, + const unsigned int filter_no, + const unsigned int enb_dis, + const unsigned int tcp_udp_match, + const unsigned int src_dst_port_match, + const unsigned int perfect_inverse_match, + const unsigned int dma_routing_enable, + const unsigned int dma_chan); /** Called to update L4 Port for filter packet */ - int (*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); + int (*update_l4_port_no)(struct osi_core_priv_data *const osi_core, + const unsigned int filter_no, + const unsigned short port_no, + const unsigned int src_dst_port_match); /** Called to configure VLAN filtering */ - int (*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); + int (*config_vlan_filtering)(struct osi_core_priv_data *const osi_core, + const unsigned int filter_enb_dis, + const unsigned int perfect_hash_filtering, + const unsigned int perfect_inverse_match); /** called to update VLAN id */ - int (*update_vlan_id)(void *base, unsigned int vid); + int (*update_vlan_id)(void *base, const unsigned int vid); /** Called to set current system time to MAC */ - int (*set_systime_to_mac)(void *addr, unsigned int sec, - unsigned int nsec); + int (*set_systime_to_mac)(void *addr, const unsigned int sec, + const unsigned int nsec); /** Called to set the addend value to adjust the time */ - int (*config_addend)(void *addr, unsigned int addend); + int (*config_addend)(void *addr, const unsigned int addend); /** Called to adjust the mac time */ - int (*adjust_mactime)(void *addr, unsigned int sec, unsigned int nsec, - unsigned int neg_adj, - unsigned int one_nsec_accuracy); + int (*adjust_mactime)(void *addr, const unsigned int sec, + const unsigned int nsec, + const unsigned int neg_adj, + const unsigned int one_nsec_accuracy); /** Called to get the current time from MAC */ unsigned long long (*get_systime_from_mac)(void *addr); /** Called to configure the TimeStampControl register */ - void (*config_tscr)(void *addr, unsigned int ptp_filter); + void (*config_tscr)(void *addr, const unsigned int ptp_filter); /** Called to configure the sub second increment register */ - void (*config_ssir)(void *addr, unsigned int ptp_clock); + void (*config_ssir)(void *addr, const unsigned int ptp_clock); /** Called to update MMC counter from HW register */ - void (*read_mmc)(struct osi_core_priv_data *osi_core); + void (*read_mmc)(struct osi_core_priv_data *const osi_core); /** Called to reset MMC HW counter structure */ - void (*reset_mmc)(struct osi_core_priv_data *osi_core); + 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 *osi_core, - unsigned int tx_lpi_enabled, - unsigned int tx_lpi_timer); + void (*configure_eee)(struct osi_core_priv_data *const osi_core, + const unsigned int tx_lpi_enabled, + const unsigned int tx_lpi_timer); /** Called to save MAC register space during SOC suspend */ - void (*save_registers)(struct osi_core_priv_data *osi_core); + void (*save_registers)(struct osi_core_priv_data *const osi_core); /** Called to restore MAC control registers during SOC resume */ - void (*restore_registers)(struct osi_core_priv_data *osi_core); + void (*restore_registers)(struct osi_core_priv_data *const osi_core); /** Called to write into a PHY reg over MDIO bus */ - int (*write_phy_reg)(struct osi_core_priv_data *osi_core, - unsigned int phyaddr, - unsigned int phyreg, - unsigned short phydata); + int (*write_phy_reg)(struct osi_core_priv_data *const osi_core, + const unsigned int phyaddr, + const unsigned int phyreg, + const unsigned short phydata); /** Called to read from a PHY reg over MDIO bus */ - int (*read_phy_reg)(struct osi_core_priv_data *osi_core, - unsigned int phyaddr, - unsigned int phyreg); + int (*read_phy_reg)(struct osi_core_priv_data *const osi_core, + const unsigned int phyaddr, + const unsigned int phyreg); }; /** @@ -379,7 +389,8 @@ struct osi_core_priv_data { * @retval -1 on failure. */ -int osi_poll_for_mac_reset_complete(struct osi_core_priv_data *osi_core); +int osi_poll_for_mac_reset_complete( + struct osi_core_priv_data *const osi_core); /** * @brief osi_set_mdc_clk_rate - Derive MDC clock based on provided AXI_CBB clk. @@ -396,8 +407,8 @@ int osi_poll_for_mac_reset_complete(struct osi_core_priv_data *osi_core); * @retval 0 on success * @retval -1 on failure. */ -int osi_set_mdc_clk_rate(struct osi_core_priv_data *osi_core, - unsigned long csr_clk_rate); +int osi_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, + const unsigned long csr_clk_rate); /** * @brief osi_hw_core_init - EQOS MAC, MTL and common DMA initialization. @@ -418,7 +429,7 @@ int osi_set_mdc_clk_rate(struct osi_core_priv_data *osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_hw_core_init(struct osi_core_priv_data *osi_core, +int osi_hw_core_init(struct osi_core_priv_data *const osi_core, unsigned int tx_fifo_size, unsigned int rx_fifo_size); @@ -434,7 +445,7 @@ int osi_hw_core_init(struct osi_core_priv_data *osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_hw_core_deinit(struct osi_core_priv_data *osi_core); +int osi_hw_core_deinit(struct osi_core_priv_data *const osi_core); /** * @brief osi_validate_core_regs - Read-validate HW registers for func safety. @@ -454,7 +465,7 @@ int osi_hw_core_deinit(struct osi_core_priv_data *osi_core); * @retval 0 on success * @retval -1 on failure. */ -int osi_validate_core_regs(struct osi_core_priv_data *osi_core); +int osi_validate_core_regs(struct osi_core_priv_data *const osi_core); /** * @brief osi_start_mac - Start MAC Tx/Rx engine @@ -469,7 +480,7 @@ int osi_validate_core_regs(struct osi_core_priv_data *osi_core); * @retval 0 on success * @retval -1 on failure. */ -int osi_start_mac(struct osi_core_priv_data *osi_core); +int osi_start_mac(struct osi_core_priv_data *const osi_core); /** * @brief osi_stop_mac - Stop MAC Tx/Rx engine @@ -483,7 +494,7 @@ int osi_start_mac(struct osi_core_priv_data *osi_core); * @retval 0 on success * @retval -1 on failure. */ -int osi_stop_mac(struct osi_core_priv_data *osi_core); +int osi_stop_mac(struct osi_core_priv_data *const osi_core); /** * @brief osi_common_isr - Common ISR. @@ -498,7 +509,7 @@ int osi_stop_mac(struct osi_core_priv_data *osi_core); * @retval 0 on success * @retval -1 on failure. */ -int osi_common_isr(struct osi_core_priv_data *osi_core); +int osi_common_isr(struct osi_core_priv_data *const osi_core); /** * @brief osi_set_mode - Set FD/HD mode. @@ -513,7 +524,8 @@ int osi_common_isr(struct osi_core_priv_data *osi_core); * @retval 0 on success * @retval -1 on failure. */ -int osi_set_mode(struct osi_core_priv_data *osi_core, int mode); +int osi_set_mode(struct osi_core_priv_data *const osi_core, + const int mode); /** * @brief osi_set_speed - Set operating speed. @@ -529,7 +541,8 @@ int osi_set_mode(struct osi_core_priv_data *osi_core, int mode); * @retval 0 on success * @retval -1 on failure. */ -int osi_set_speed(struct osi_core_priv_data *osi_core, int speed); +int osi_set_speed(struct osi_core_priv_data *const osi_core, + const int speed); /** * @brief osi_pad_calibrate - PAD calibration @@ -547,7 +560,7 @@ int osi_set_speed(struct osi_core_priv_data *osi_core, int speed); * @retval 0 on success * @retval -1 on failure. */ -int osi_pad_calibrate(struct osi_core_priv_data *osi_core); +int osi_pad_calibrate(struct osi_core_priv_data *const osi_core); /** * @brief osi_flush_mtl_tx_queue - Flushing a MTL Tx Queue. @@ -564,8 +577,8 @@ int osi_pad_calibrate(struct osi_core_priv_data *osi_core); * @retval 0 on success * @retval -1 on failure. */ -int osi_flush_mtl_tx_queue(struct osi_core_priv_data *osi_core, - unsigned int qinx); +int osi_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, + const unsigned int qinx); /** * @brief osi_config_mac_loopback - Configure MAC loopback @@ -580,8 +593,8 @@ int osi_flush_mtl_tx_queue(struct osi_core_priv_data *osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_config_mac_loopback(struct osi_core_priv_data *osi_core, - unsigned int lb_mode); +int osi_config_mac_loopback(struct osi_core_priv_data *const osi_core, + const unsigned int lb_mode); /** * @brief osi_set_avb - Set CBS algo and parameters @@ -599,8 +612,8 @@ int osi_config_mac_loopback(struct osi_core_priv_data *osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_set_avb(struct osi_core_priv_data *osi_core, - struct osi_core_avb_algorithm *avb); +int osi_set_avb(struct osi_core_priv_data *const osi_core, + const struct osi_core_avb_algorithm *avb); /** * @brief osi_get_avb - Get CBS algo and parameters @@ -618,7 +631,7 @@ int osi_set_avb(struct osi_core_priv_data *osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_get_avb(struct osi_core_priv_data *osi_core, +int osi_get_avb(struct osi_core_priv_data *const osi_core, struct osi_core_avb_algorithm *avb); /** @@ -635,8 +648,8 @@ int osi_get_avb(struct osi_core_priv_data *osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_configure_txstatus(struct osi_core_priv_data *osi_core, - unsigned int tx_status); +int osi_configure_txstatus(struct osi_core_priv_data *const osi_core, + const unsigned int tx_status); /** * @brief osi_config_fw_err_pkts - Configure forwarding of error packets @@ -652,8 +665,8 @@ int osi_configure_txstatus(struct osi_core_priv_data *osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_config_fw_err_pkts(struct osi_core_priv_data *osi_core, - unsigned int qinx, unsigned int fw_err); +int osi_config_fw_err_pkts(struct osi_core_priv_data *const osi_core, + const unsigned int qinx, const unsigned int fw_err); /** * @brief osi_config_rx_crc_check - Configure CRC Checking for Received Packets @@ -670,8 +683,8 @@ int osi_config_fw_err_pkts(struct osi_core_priv_data *osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_config_rx_crc_check(struct osi_core_priv_data *osi_core, - unsigned int crc_chk); +int osi_config_rx_crc_check(struct osi_core_priv_data *const osi_core, + const unsigned int crc_chk); /** * @brief osi_configure_flow_ctrl - Configure flow control settings @@ -688,8 +701,9 @@ int osi_config_rx_crc_check(struct osi_core_priv_data *osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_configure_flow_control(struct osi_core_priv_data *osi_core, - unsigned int flw_ctrl); +int osi_configure_flow_control( + struct osi_core_priv_data *const osi_core, + const unsigned int flw_ctrl); /** * @brief osi_config_arp_offload - Configure ARP offload in MAC. @@ -707,9 +721,9 @@ int osi_configure_flow_control(struct osi_core_priv_data *osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_config_arp_offload(struct osi_core_priv_data *osi_core, - unsigned int flags, - unsigned char *ip_addr); +int osi_config_arp_offload(struct osi_core_priv_data *const osi_core, + const unsigned int flags, + const unsigned char *ip_addr); /** * @brief osi_config_rxcsum_offload - Configure RX checksum offload in MAC. @@ -724,8 +738,9 @@ int osi_config_arp_offload(struct osi_core_priv_data *osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_config_rxcsum_offload(struct osi_core_priv_data *osi_core, - unsigned int enable); +int osi_config_rxcsum_offload( + struct osi_core_priv_data *const osi_core, + const unsigned int enable); /** * @brief osi_l2_filter - configure L2 mac filter. @@ -743,8 +758,8 @@ int osi_config_rxcsum_offload(struct osi_core_priv_data *osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_l2_filter(struct osi_core_priv_data *osi_core, - struct osi_filter *filter); +int osi_l2_filter(struct osi_core_priv_data *const osi_core, + const struct osi_filter *filter); /** * @brief osi_config_vlan_filtering - OSI call for configuring VLAN filter @@ -764,10 +779,11 @@ int osi_l2_filter(struct osi_core_priv_data *osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_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); +int osi_config_vlan_filtering( + struct osi_core_priv_data *const osi_core, + const unsigned int filter_enb_dis, + const unsigned int perfect_hash_filtering, + const unsigned int perfect_inverse_match); /** * @brief osi_update_vlan_id - invoke osi call to update VLAN ID @@ -782,8 +798,8 @@ int osi_config_vlan_filtering(struct osi_core_priv_data *osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_update_vlan_id(struct osi_core_priv_data *osi_core, - unsigned int vid); +int osi_update_vlan_id(struct osi_core_priv_data *const osi_core, + const unsigned int vid); /** * @brief osi_write_phy_reg - Write to a PHY register through MAC over MDIO bus. @@ -808,8 +824,9 @@ int osi_update_vlan_id(struct osi_core_priv_data *osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_write_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, - unsigned int phyreg, unsigned short phydata); +int osi_write_phy_reg(struct osi_core_priv_data *const osi_core, + const unsigned int phyaddr, const unsigned int phyreg, + const unsigned short phydata); /** * @brief osi_read_mmc - invoke function to read actual registers and update @@ -827,7 +844,7 @@ int osi_write_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, * @retval 0 on success * @retval -1 on failure. */ -int osi_read_mmc(struct osi_core_priv_data *osi_core); +int osi_read_mmc(struct osi_core_priv_data *const osi_core); /** * @brief osi_reset_mmc - invoke function to reset MMC counter and data @@ -845,20 +862,20 @@ int osi_read_mmc(struct osi_core_priv_data *osi_core); * @retval 0 on success * @retval -1 on failure. */ -int osi_reset_mmc(struct osi_core_priv_data *osi_core); +int osi_reset_mmc(struct osi_core_priv_data *const osi_core); /** * @brief osi_read_phy_reg - Read from a PHY register through MAC over MDIO bus. * * Algorithm: - * 1) Before proceeding for reading for PHY register check whether any MII - * operation going on MDIO bus by polling MAC_GMII_BUSY bit. - * 2) 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. - * 3) 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. + * 1) Before proceeding for reading for PHY register check whether any MII + * operation going on MDIO bus by polling MAC_GMII_BUSY bit. + * 2) 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. + * 3) 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 @@ -869,8 +886,9 @@ int osi_reset_mmc(struct osi_core_priv_data *osi_core); * @retval data from PHY register on success * @retval -1 on failure */ -int osi_read_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, - unsigned int phyreg); +int osi_read_phy_reg(struct osi_core_priv_data *const osi_core, + const unsigned int phyaddr, + const unsigned int phyreg); /** * @brief initializing the core operations @@ -880,7 +898,7 @@ int osi_read_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, * @retval data from PHY register on success * @retval -1 on failure */ -int osi_init_core_ops(struct osi_core_priv_data *osi_core); +int osi_init_core_ops(struct osi_core_priv_data *const osi_core); /** * @brief osi_set_systime_to_mac - Handles setting of system time. @@ -896,8 +914,8 @@ int osi_init_core_ops(struct osi_core_priv_data *osi_core); * @retval 0 on success * @retval -1 on failure. */ -int osi_set_systime_to_mac(struct osi_core_priv_data *osi_core, - unsigned int sec, unsigned int nsec); +int osi_set_systime_to_mac(struct osi_core_priv_data *const osi_core, + const unsigned int sec, const unsigned int nsec); /** * @brief osi_adjust_freq - Adjust frequency @@ -914,7 +932,7 @@ int osi_set_systime_to_mac(struct osi_core_priv_data *osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_adjust_freq(struct osi_core_priv_data *osi_core, int ppb); +int osi_adjust_freq(struct osi_core_priv_data *const osi_core, int ppb); /** * @brief osi_adjust_time - Adjust MAC time with system time @@ -932,7 +950,8 @@ int osi_adjust_freq(struct osi_core_priv_data *osi_core, int ppb); * @retval 0 on success * @retval -1 on failure. */ -int osi_adjust_time(struct osi_core_priv_data *osi_core, long long nsec_delta); +int osi_adjust_time(struct osi_core_priv_data *const osi_core, + long long nsec_delta); /** * @brief osi_get_systime_from_mac - Get system time @@ -948,7 +967,8 @@ int osi_adjust_time(struct osi_core_priv_data *osi_core, long long nsec_delta); * @retval 0 on success * @retval -1 on failure. */ -int osi_get_systime_from_mac(struct osi_core_priv_data *osi_core, +int osi_get_systime_from_mac( + struct osi_core_priv_data *const osi_core, unsigned int *sec, unsigned int *nsec); /** @@ -975,8 +995,8 @@ int osi_get_systime_from_mac(struct osi_core_priv_data *osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_ptp_configuration(struct osi_core_priv_data *osi_core, - unsigned int enable); +int osi_ptp_configuration(struct osi_core_priv_data *const osi_core, + const unsigned int enable); /* MAC version specific implementation function prototypes added here * for misra compliance to have @@ -1015,11 +1035,12 @@ void *eqos_get_core_backup_config(void); * @retval 0 on success * @retval -1 on failure. */ -int osi_l3l4_filter(struct osi_core_priv_data *osi_core, - struct osi_l3_l4_filter l_filter, - unsigned int type, - unsigned int dma_routing_enable, unsigned int dma_chan, - unsigned int is_l4_filter); +int osi_l3l4_filter(struct osi_core_priv_data *const osi_core, + const struct osi_l3_l4_filter l_filter, + const unsigned int type, + const unsigned int dma_routing_enable, + const unsigned int dma_chan, + const unsigned int is_l4_filter); /** * @brief osi_configure_eee - Configure EEE LPI in MAC. @@ -1037,7 +1058,7 @@ int osi_l3l4_filter(struct osi_core_priv_data *osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_configure_eee(struct osi_core_priv_data *osi_core, +int osi_configure_eee(struct osi_core_priv_data *const osi_core, unsigned int tx_lpi_enabled, unsigned int tx_lpi_timer); @@ -1054,7 +1075,7 @@ int osi_configure_eee(struct osi_core_priv_data *osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_save_registers(struct osi_core_priv_data *osi_core); +int osi_save_registers(struct osi_core_priv_data *const osi_core); /** * @brief osi_restore_registers - Restore backup of MAC MMIO address space @@ -1067,5 +1088,5 @@ int osi_save_registers(struct osi_core_priv_data *osi_core); * @retval 0 on success * @retval -1 on failure. */ -int osi_restore_registers(struct osi_core_priv_data *osi_core); +int osi_restore_registers(struct osi_core_priv_data *const osi_core); #endif /* OSI_CORE_H */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 971d4c9..ffe8292 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -76,7 +76,7 @@ static inline void eqos_core_safety_writel(unsigned int val, void *addr, * * @param[in] osi_core: OSI core private data structure. */ -static void eqos_core_safety_init(struct osi_core_priv_data *osi_core) +static void eqos_core_safety_init(struct osi_core_priv_data *const osi_core) { struct core_func_safety *config = &eqos_core_safety_config; unsigned char *base = (unsigned char *)osi_core->base; @@ -188,7 +188,7 @@ static void eqos_core_safety_init(struct osi_core_priv_data *osi_core) * * @retval none */ -static void eqos_core_backup_init(struct osi_core_priv_data *osi_core) +static void eqos_core_backup_init(struct osi_core_priv_data *const osi_core) { struct core_backup *config = &eqos_core_backup_config; unsigned char *base = (unsigned char *)osi_core->base; @@ -312,7 +312,7 @@ static void eqos_core_backup_init(struct osi_core_priv_data *osi_core) * @retval 0 on success * @retval -1 on failure. */ -static int eqos_validate_core_regs(struct osi_core_priv_data *osi_core) +static int 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; @@ -369,7 +369,8 @@ static int eqos_validate_core_regs(struct osi_core_priv_data *osi_core) * @retval 0 on success * @retval -1 on failure. */ -static int eqos_config_flow_control(void *addr, unsigned int flw_ctrl) +static int eqos_config_flow_control(void *addr, + const unsigned int flw_ctrl) { unsigned int val; @@ -438,7 +439,8 @@ static int eqos_config_flow_control(void *addr, unsigned int flw_ctrl) * @retval 0 on success * @retval -1 on failure. */ -static int eqos_config_rx_crc_check(void *addr, unsigned int crc_chk) +static int eqos_config_rx_crc_check(void *addr, + const unsigned int crc_chk) { unsigned int val; @@ -485,8 +487,9 @@ static int eqos_config_rx_crc_check(void *addr, unsigned int crc_chk) * @retval 0 on success * @retval -1 on failure. */ -static int eqos_config_fw_err_pkts(void *addr, unsigned int qinx, - unsigned int fw_err) +static int eqos_config_fw_err_pkts(void *addr, + const unsigned int qinx, + const unsigned int fw_err) { unsigned int val; @@ -541,7 +544,8 @@ static int eqos_config_fw_err_pkts(void *addr, unsigned int qinx, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_config_tx_status(void *addr, unsigned int tx_status) +static int eqos_config_tx_status(void *addr, + const unsigned int tx_status) { unsigned int val; @@ -587,7 +591,8 @@ static int eqos_config_tx_status(void *addr, unsigned int tx_status) * @retval 0 on success * @retval -1 on failure. */ -static int eqos_config_mac_loopback(void *addr, unsigned int lb_mode) +static int eqos_config_mac_loopback(void *addr, + const unsigned int lb_mode) { unsigned int clk_ctrl_val; unsigned int mcr_val; @@ -682,8 +687,8 @@ static int eqos_poll_for_swr(void *addr) * @note OSD layer needs get the AXI CBB clock rate with OSD clock API * (ex - clk_get_rate()) */ -static void eqos_set_mdc_clk_rate(struct osi_core_priv_data *osi_core, - unsigned long csr_clk_rate) +static void eqos_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, + const unsigned long csr_clk_rate) { unsigned long csr_clk_speed = csr_clk_rate / 1000000UL; @@ -718,7 +723,7 @@ static void eqos_set_mdc_clk_rate(struct osi_core_priv_data *osi_core, * * @note MAC should be init and started. see osi_start_mac() */ -static void eqos_set_speed(void *base, int speed) +static void eqos_set_speed(void *base, const int speed) { unsigned int mcr_val; @@ -757,7 +762,7 @@ static void eqos_set_speed(void *base, int speed) * * @note MAC should be init and started. see osi_start_mac() */ -static void eqos_set_mode(void *base, int mode) +static void eqos_set_mode(void *base, const int mode) { unsigned int mcr_val; @@ -961,7 +966,8 @@ calibration_failed: * @retval 0 on success * @retval -1 on failure. */ -static int eqos_flush_mtl_tx_queue(void *addr, unsigned int qinx) +static int eqos_flush_mtl_tx_queue(void *addr, + const unsigned int qinx) { unsigned int retry = 1000; unsigned int count; @@ -1118,7 +1124,7 @@ void update_ehfc_rfa_rfd(unsigned int rx_fifo, unsigned int *value) * @retval -1 on failure. */ static int eqos_configure_mtl_queue(unsigned int qinx, - struct osi_core_priv_data *osi_core, + struct osi_core_priv_data *const osi_core, unsigned int tx_fifo, unsigned int rx_fifo) { @@ -1189,7 +1195,8 @@ static int eqos_configure_mtl_queue(unsigned int qinx, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_config_rxcsum_offload(void *addr, unsigned int enabled) +static int eqos_config_rxcsum_offload(void *addr, + const unsigned int enabled) { unsigned int mac_mcr; @@ -1226,7 +1233,8 @@ static int eqos_config_rxcsum_offload(void *addr, unsigned int enabled) * * @note MAC has to be out of reset. */ -static void eqos_configure_rxq_priority(struct osi_core_priv_data *osi_core) +static void eqos_configure_rxq_priority( + struct osi_core_priv_data *const osi_core) { unsigned int val; unsigned int temp; @@ -1292,7 +1300,7 @@ static void eqos_configure_rxq_priority(struct osi_core_priv_data *osi_core) * * @note MAC has to be out of reset. */ -static void eqos_configure_mac(struct osi_core_priv_data *osi_core) +static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) { unsigned int value; @@ -1456,9 +1464,9 @@ static void eqos_configure_dma(void *base) * @retval 0 on success * @retval -1 on failure. */ -static int eqos_core_init(struct osi_core_priv_data *osi_core, - unsigned int tx_fifo_size, - unsigned int rx_fifo_size) +static int eqos_core_init(struct osi_core_priv_data *const osi_core, + const unsigned int tx_fifo_size, + const unsigned int rx_fifo_size) { int ret = 0; unsigned int qinx = 0; @@ -1537,7 +1545,7 @@ static int eqos_core_init(struct osi_core_priv_data *osi_core, * * @note MAC interrupts need to be enabled */ -static void eqos_handle_mac_intrs(struct osi_core_priv_data *osi_core, +static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, unsigned int dma_isr) { unsigned int mac_imr = 0; @@ -1597,8 +1605,9 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *osi_core, * @param[in] dma_sr: Dma status register read value * @param[in] qinx: Queue index */ -static inline void update_dma_sr_stats(struct osi_core_priv_data *osi_core, - unsigned int dma_sr, unsigned int qinx) +static inline void update_dma_sr_stats( + struct osi_core_priv_data *const osi_core, + unsigned int dma_sr, unsigned int qinx) { unsigned long val; @@ -1643,7 +1652,7 @@ static inline void update_dma_sr_stats(struct osi_core_priv_data *osi_core, * * @note MAC should be init and started. see osi_start_mac() */ -static void eqos_handle_common_intr(struct osi_core_priv_data *osi_core) +static void eqos_handle_common_intr(struct osi_core_priv_data *const osi_core) { void *base = osi_core->base; unsigned int dma_isr = 0; @@ -1762,8 +1771,9 @@ static void eqos_stop_mac(void *addr) * @retval 0 on success * @retval -1 on failure. */ -static int eqos_set_avb_algorithm(struct osi_core_priv_data *osi_core, - struct osi_core_avb_algorithm *avb) +static int eqos_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; @@ -1897,8 +1907,9 @@ static inline int eqos_config_l2_da_perfect_inverse_match(void *base, * * @retval 0 always */ -static int eqos_config_mac_pkt_filter_reg(struct osi_core_priv_data *osi_core, - struct osi_filter *filter) +static int eqos_config_mac_pkt_filter_reg( + struct osi_core_priv_data *const osi_core, + const struct osi_filter *filter) { unsigned int value = 0U; int ret = 0; @@ -1976,11 +1987,12 @@ static int eqos_config_mac_pkt_filter_reg(struct osi_core_priv_data *osi_core, * @retval -1 on failure. */ static inline int eqos_update_mac_addr_helper( - struct osi_core_priv_data *osi_core, + struct osi_core_priv_data *const osi_core, unsigned int *value, - unsigned int idx, - unsigned int dma_routing_enable, - unsigned int dma_chan, unsigned int addr_mask) + const unsigned int idx, + const unsigned int dma_routing_enable, + const unsigned int dma_chan, + const unsigned int addr_mask) { int ret = 0; /* PDC bit of MAC_Ext_Configuration register is not set so binary @@ -2039,8 +2051,8 @@ err_dma_chan: * @retval -1 on failure. */ static int eqos_update_mac_addr_low_high_reg( - struct osi_core_priv_data *osi_core, - struct osi_filter *filter) + struct osi_core_priv_data *const osi_core, + const struct osi_filter *filter) { unsigned int idx = filter->index; unsigned int dma_routing_enable = filter->dma_routing; @@ -2115,8 +2127,9 @@ static int eqos_update_mac_addr_low_high_reg( * @retval 0 on success * @retval -1 on failure. */ -static int eqos_get_avb_algorithm(struct osi_core_priv_data *osi_core, - struct osi_core_avb_algorithm *avb) +static int eqos_get_avb_algorithm( + struct osi_core_priv_data *const osi_core, + struct osi_core_avb_algorithm *const avb) { unsigned int value; int ret = -1; @@ -2199,9 +2212,9 @@ static int eqos_get_avb_algorithm(struct osi_core_priv_data *osi_core, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_config_arp_offload(unsigned int mac_ver, void *addr, - unsigned int enable, - unsigned char *ip_addr) +static int eqos_config_arp_offload(const unsigned int mac_ver, void *addr, + const unsigned int enable, + const unsigned char *ip_addr) { unsigned int mac_mcr; unsigned int val; @@ -2255,7 +2268,7 @@ static int eqos_config_arp_offload(unsigned int mac_ver, void *addr, * @retval -1 on failure. */ static int eqos_config_l3_l4_filter_enable(void *base, - unsigned int filter_enb_dis) + const unsigned int filter_enb_dis) { unsigned int value = 0U; @@ -2284,10 +2297,11 @@ static int eqos_config_l3_l4_filter_enable(void *base, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_update_ip4_addr(struct osi_core_priv_data *osi_core, - unsigned int filter_no, - unsigned char addr[], - unsigned int src_dst_addr_match) +static int eqos_update_ip4_addr( + struct osi_core_priv_data *const osi_core, + const unsigned int filter_no, + const unsigned char addr[], + const unsigned int src_dst_addr_match) { void *base = osi_core->base; unsigned int value = 0U; @@ -2340,8 +2354,10 @@ static int eqos_update_ip4_addr(struct osi_core_priv_data *osi_core, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_update_ip6_addr(struct osi_core_priv_data *osi_core, - unsigned int filter_no, unsigned short addr[]) +static int eqos_update_ip6_addr( + struct osi_core_priv_data *const osi_core, + const unsigned int filter_no, + const unsigned short addr[]) { void *base = osi_core->base; unsigned int value = 0U; @@ -2407,10 +2423,11 @@ static int eqos_update_ip6_addr(struct osi_core_priv_data *osi_core, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_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) +static int eqos_update_l4_port_no( + struct osi_core_priv_data *const osi_core, + const unsigned int filter_no, + const unsigned short port_no, + const unsigned int src_dst_port_match) { void *base = osi_core->base; unsigned int value = 0U; @@ -2456,10 +2473,11 @@ static int eqos_update_l4_port_no(struct osi_core_priv_data *osi_core, * *@return updated unsigned int value */ -static inline unsigned int eqos_set_dcs(struct osi_core_priv_data *osi_core, - unsigned int value, - unsigned int dma_routing_enable, - unsigned int dma_chan) +static inline unsigned int eqos_set_dcs( + struct osi_core_priv_data *const osi_core, + unsigned int value, + unsigned int dma_routing_enable, + unsigned int dma_chan) { if ((dma_routing_enable == OSI_ENABLE) && (dma_chan < OSI_EQOS_MAX_NUM_CHANS) && (osi_core->dcs_en == @@ -2530,14 +2548,15 @@ static inline void eqos_helper_l3l4_bitmask(unsigned int *bitmask, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_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) +static int eqos_config_l3_filters( + struct osi_core_priv_data *const osi_core, + const unsigned int filter_no, + const unsigned int enb_dis, + const unsigned int ipv4_ipv6_match, + const unsigned int src_dst_addr_match, + const unsigned int perfect_inverse_match, + const unsigned int dma_routing_enable, + const unsigned int dma_chan) { unsigned int value = 0U; void *base = osi_core->base; @@ -2702,14 +2721,15 @@ static int eqos_config_l3_filters(struct osi_core_priv_data *osi_core, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_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) +static int eqos_config_l4_filters( + struct osi_core_priv_data *const osi_core, + const unsigned int filter_no, + const unsigned int enb_dis, + const unsigned int tcp_udp_match, + const unsigned int src_dst_port_match, + const unsigned int perfect_inverse_match, + const unsigned int dma_routing_enable, + const unsigned int dma_chan) { void *base = osi_core->base; unsigned int value = 0U; @@ -2812,10 +2832,11 @@ static int eqos_config_l4_filters(struct osi_core_priv_data *osi_core, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_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) +static int eqos_config_vlan_filtering( + struct osi_core_priv_data *const osi_core, + const unsigned int filter_enb_dis, + const unsigned int perfect_hash_filtering, + const unsigned int perfect_inverse_match) { unsigned int value; void *base = osi_core->base; @@ -2914,8 +2935,8 @@ static inline int eqos_poll_for_tsinit_complete(void *addr, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_set_systime_to_mac(void *addr, unsigned int sec, - unsigned int nsec) +static int eqos_set_systime_to_mac(void *addr, const unsigned int sec, + const unsigned int nsec) { unsigned int mac_tcr; int ret; @@ -3001,7 +3022,7 @@ static inline int eqos_poll_for_addend_complete(void *addr, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_config_addend(void *addr, unsigned int addend) +static int eqos_config_addend(void *addr, const unsigned int addend) { unsigned int mac_tcr; int ret; @@ -3212,7 +3233,7 @@ static unsigned long long eqos_get_systime_from_mac(void *addr) * * @note MAC should be init and started. see osi_start_mac() */ -static void eqos_config_tscr(void *addr, unsigned int ptp_filter) +static void eqos_config_tscr(void *addr, const unsigned int ptp_filter) { unsigned int mac_tcr = 0; @@ -3283,7 +3304,7 @@ static void eqos_config_tscr(void *addr, unsigned int ptp_filter) * * @note MAC should be init and started. see osi_start_mac() */ -static void eqos_config_ssir(void *addr, unsigned int ptp_clock) +static void eqos_config_ssir(void *addr, const unsigned int ptp_clock) { unsigned long long val; unsigned int mac_tcr; @@ -3327,7 +3348,7 @@ static void eqos_config_ssir(void *addr, unsigned int ptp_clock) * * @note Required clks and resets has to be enabled */ -static void eqos_core_deinit(struct osi_core_priv_data *osi_core) +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->base); @@ -3374,9 +3395,10 @@ static inline void eqos_disable_tx_lpi(void *addr) * Required clks and resets has to be enabled. * MAC/PHY should be initialized */ -static void eqos_configure_eee(struct osi_core_priv_data *osi_core, - unsigned int tx_lpi_enabled, - unsigned int tx_lpi_timer) +static void eqos_configure_eee( + struct osi_core_priv_data *const osi_core, + const unsigned int tx_lpi_enabled, + const unsigned int tx_lpi_timer) { unsigned int lpi_csr = 0; unsigned int lpi_timer_ctrl = 0; @@ -3433,7 +3455,8 @@ static void eqos_configure_eee(struct osi_core_priv_data *osi_core, * * @retval none */ -static inline void eqos_save_registers(struct osi_core_priv_data *osi_core) +static inline void eqos_save_registers( + struct osi_core_priv_data *const osi_core) { unsigned int i; struct core_backup *config = osi_core->backup_config; @@ -3455,7 +3478,8 @@ static inline void eqos_save_registers(struct osi_core_priv_data *osi_core) * * @retval none */ -static inline void eqos_restore_registers(struct osi_core_priv_data *osi_core) +static inline void eqos_restore_registers( + struct osi_core_priv_data *const osi_core) { unsigned int i; struct core_backup *config = osi_core->backup_config; @@ -3510,10 +3534,10 @@ static inline int poll_for_mii_idle(struct osi_core_priv_data *osi_core) return 0; } -static int eqos_write_phy_reg(struct osi_core_priv_data *osi_core, - unsigned int phyaddr, - unsigned int phyreg, - unsigned short phydata) +static int eqos_write_phy_reg(struct osi_core_priv_data *const osi_core, + const unsigned int phyaddr, + const unsigned int phyreg, + const unsigned short phydata) { unsigned int mac_gmiiar; unsigned int mac_gmiidr; @@ -3568,9 +3592,9 @@ static int eqos_write_phy_reg(struct osi_core_priv_data *osi_core, return ret; } -static int eqos_read_phy_reg(struct osi_core_priv_data *osi_core, - unsigned int phyaddr, - unsigned int phyreg) +static int eqos_read_phy_reg(struct osi_core_priv_data *const osi_core, + const unsigned int phyaddr, + const unsigned int phyreg) { unsigned int mac_gmiiar; unsigned int mac_gmiidr; diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 45790b4..9c7cdab 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -23,8 +23,9 @@ #include <osi_core.h> #include <osd.h> -int osi_write_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, - unsigned int phyreg, unsigned short phydata) +int osi_write_phy_reg(struct osi_core_priv_data *const osi_core, + const unsigned int phyaddr, const unsigned int phyreg, + const unsigned short phydata) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->write_phy_reg != OSI_NULL)) { @@ -35,8 +36,8 @@ int osi_write_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, return -1; } -int osi_read_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, - unsigned int phyreg) +int osi_read_phy_reg(struct osi_core_priv_data *const osi_core, + const unsigned int phyaddr, const unsigned int phyreg) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->read_phy_reg != OSI_NULL)) { @@ -46,7 +47,7 @@ int osi_read_phy_reg(struct osi_core_priv_data *osi_core, unsigned int phyaddr, return -1; } -int osi_init_core_ops(struct osi_core_priv_data *osi_core) +int osi_init_core_ops(struct osi_core_priv_data *const osi_core) { if (osi_core->mac == OSI_MAC_HW_EQOS) { /* Get EQOS HW ops */ @@ -63,7 +64,8 @@ int osi_init_core_ops(struct osi_core_priv_data *osi_core) return -1; } -int osi_poll_for_mac_reset_complete(struct osi_core_priv_data *osi_core) +int osi_poll_for_mac_reset_complete( + struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->poll_for_swr != OSI_NULL)) { @@ -72,8 +74,8 @@ int osi_poll_for_mac_reset_complete(struct osi_core_priv_data *osi_core) return -1; } -int osi_set_mdc_clk_rate(struct osi_core_priv_data *osi_core, - unsigned long csr_clk_rate) +int osi_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, + const unsigned long csr_clk_rate) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->set_mdc_clk_rate != OSI_NULL)) { @@ -84,7 +86,7 @@ int osi_set_mdc_clk_rate(struct osi_core_priv_data *osi_core, return -1; } -int osi_hw_core_init(struct osi_core_priv_data *osi_core, +int osi_hw_core_init(struct osi_core_priv_data *const osi_core, unsigned int tx_fifo_size, unsigned int rx_fifo_size) { @@ -97,7 +99,7 @@ int osi_hw_core_init(struct osi_core_priv_data *osi_core, return -1; } -int osi_hw_core_deinit(struct osi_core_priv_data *osi_core) +int osi_hw_core_deinit(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->core_deinit != OSI_NULL)) { @@ -108,7 +110,7 @@ int osi_hw_core_deinit(struct osi_core_priv_data *osi_core) return -1; } -int osi_validate_core_regs(struct osi_core_priv_data *osi_core) +int osi_validate_core_regs(struct osi_core_priv_data *const osi_core) { int ret = -1; @@ -121,7 +123,7 @@ int osi_validate_core_regs(struct osi_core_priv_data *osi_core) return ret; } -int osi_start_mac(struct osi_core_priv_data *osi_core) +int osi_start_mac(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->start_mac != OSI_NULL)) { @@ -132,7 +134,7 @@ int osi_start_mac(struct osi_core_priv_data *osi_core) return -1; } -int osi_stop_mac(struct osi_core_priv_data *osi_core) +int osi_stop_mac(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->stop_mac != OSI_NULL)) { @@ -143,7 +145,7 @@ int osi_stop_mac(struct osi_core_priv_data *osi_core) return -1; } -int osi_common_isr(struct osi_core_priv_data *osi_core) +int osi_common_isr(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->handle_common_intr != OSI_NULL)) { @@ -154,7 +156,7 @@ int osi_common_isr(struct osi_core_priv_data *osi_core) return -1; } -int osi_set_mode(struct osi_core_priv_data *osi_core, int mode) +int osi_set_mode(struct osi_core_priv_data *const osi_core, const int mode) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->set_mode != OSI_NULL)) { @@ -165,7 +167,8 @@ int osi_set_mode(struct osi_core_priv_data *osi_core, int mode) return -1; } -int osi_set_speed(struct osi_core_priv_data *osi_core, int speed) +int osi_set_speed(struct osi_core_priv_data *const osi_core, + const int speed) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->set_speed != OSI_NULL)) { @@ -176,7 +179,7 @@ int osi_set_speed(struct osi_core_priv_data *osi_core, int speed) return -1; } -int osi_pad_calibrate(struct osi_core_priv_data *osi_core) +int osi_pad_calibrate(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->pad_calibrate != OSI_NULL)) { @@ -186,8 +189,8 @@ int osi_pad_calibrate(struct osi_core_priv_data *osi_core) return -1; } -int osi_flush_mtl_tx_queue(struct osi_core_priv_data *osi_core, - unsigned int qinx) +int osi_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, + const unsigned int qinx) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->flush_mtl_tx_queue != OSI_NULL)) { @@ -197,8 +200,8 @@ int osi_flush_mtl_tx_queue(struct osi_core_priv_data *osi_core, return -1; } -int osi_config_mac_loopback(struct osi_core_priv_data *osi_core, - unsigned int lb_mode) +int osi_config_mac_loopback(struct osi_core_priv_data *const osi_core, + const unsigned int lb_mode) { /* Configure MAC LoopBack */ if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && @@ -210,8 +213,8 @@ int osi_config_mac_loopback(struct osi_core_priv_data *osi_core, return -1; } -int osi_set_avb(struct osi_core_priv_data *osi_core, - struct osi_core_avb_algorithm *avb) +int osi_set_avb(struct osi_core_priv_data *const osi_core, + const struct osi_core_avb_algorithm *avb) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->set_avb_algorithm != OSI_NULL)) { @@ -221,7 +224,7 @@ int osi_set_avb(struct osi_core_priv_data *osi_core, return -1; } -int osi_get_avb(struct osi_core_priv_data *osi_core, +int osi_get_avb(struct osi_core_priv_data *const osi_core, struct osi_core_avb_algorithm *avb) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && @@ -232,8 +235,8 @@ int osi_get_avb(struct osi_core_priv_data *osi_core, return -1; } -int osi_configure_txstatus(struct osi_core_priv_data *osi_core, - unsigned int tx_status) +int osi_configure_txstatus(struct osi_core_priv_data *const osi_core, + const unsigned int tx_status) { /* Configure Drop Transmit Status */ if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && @@ -245,8 +248,8 @@ int osi_configure_txstatus(struct osi_core_priv_data *osi_core, return -1; } -int osi_config_fw_err_pkts(struct osi_core_priv_data *osi_core, - unsigned int qinx, unsigned int fw_err) +int osi_config_fw_err_pkts(struct osi_core_priv_data *const osi_core, + const unsigned int qinx, const unsigned int fw_err) { /* Configure Forwarding of Error packets */ if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && @@ -258,8 +261,8 @@ int osi_config_fw_err_pkts(struct osi_core_priv_data *osi_core, return -1; } -int osi_config_rx_crc_check(struct osi_core_priv_data *osi_core, - unsigned int crc_chk) +int osi_config_rx_crc_check(struct osi_core_priv_data *const osi_core, + const unsigned int crc_chk) { /* Configure CRC Checking for Received Packets */ if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && @@ -271,8 +274,9 @@ int osi_config_rx_crc_check(struct osi_core_priv_data *osi_core, return -1; } -int osi_configure_flow_control(struct osi_core_priv_data *osi_core, - unsigned int flw_ctrl) +int osi_configure_flow_control( + struct osi_core_priv_data *const osi_core, + const unsigned int flw_ctrl) { /* Configure Flow control settings */ if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && @@ -284,9 +288,9 @@ int osi_configure_flow_control(struct osi_core_priv_data *osi_core, return -1; } -int osi_config_arp_offload(struct osi_core_priv_data *osi_core, - unsigned int flags, - unsigned char *ip_addr) +int osi_config_arp_offload(struct osi_core_priv_data *const osi_core, + const unsigned int flags, + const unsigned char *ip_addr) { if (osi_core != OSI_NULL && osi_core->ops != OSI_NULL && osi_core->ops->config_arp_offload != OSI_NULL) { @@ -298,8 +302,8 @@ int osi_config_arp_offload(struct osi_core_priv_data *osi_core, return -1; } -int osi_l2_filter(struct osi_core_priv_data *osi_core, - struct osi_filter *filter) +int osi_l2_filter(struct osi_core_priv_data *const osi_core, + const struct osi_filter *filter) { struct osi_core_ops *op; int ret = -1; @@ -357,7 +361,8 @@ int osi_l2_filter(struct osi_core_priv_data *osi_core, * @retval 0 on Success * @retval -1 on Failure */ -static inline int helper_l4_filter(struct osi_core_priv_data *osi_core, +static inline int helper_l4_filter( + struct osi_core_priv_data *const osi_core, struct osi_l3_l4_filter l_filter, unsigned int type, unsigned int dma_routing_enable, @@ -409,7 +414,8 @@ static inline int helper_l4_filter(struct osi_core_priv_data *osi_core, * @retval 0 on Success * @retval -1 on Failure */ -static inline int helper_l3_filter(struct osi_core_priv_data *osi_core, +static inline int helper_l3_filter( + struct osi_core_priv_data *const osi_core, struct osi_l3_l4_filter l_filter, unsigned int type, unsigned int dma_routing_enable, @@ -460,10 +466,10 @@ static inline int helper_l3_filter(struct osi_core_priv_data *osi_core, } } -int osi_l3l4_filter(struct osi_core_priv_data *osi_core, - struct osi_l3_l4_filter l_filter, unsigned int type, - unsigned int dma_routing_enable, unsigned int dma_chan, - unsigned int is_l4_filter) +int osi_l3l4_filter(struct osi_core_priv_data *const osi_core, + const struct osi_l3_l4_filter l_filter, const unsigned int type, + const unsigned int dma_routing_enable, const unsigned int dma_chan, + const unsigned int is_l4_filter) { int ret = -1; @@ -513,10 +519,11 @@ int osi_l3l4_filter(struct osi_core_priv_data *osi_core, return ret; } -int osi_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) +int osi_config_vlan_filtering( + struct osi_core_priv_data *const osi_core, + const unsigned int filter_enb_dis, + const unsigned int perfect_hash_filtering, + const unsigned int perfect_inverse_match) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->config_vlan_filtering != OSI_NULL)) { @@ -530,8 +537,9 @@ int osi_config_vlan_filtering(struct osi_core_priv_data *osi_core, return -1; } -int osi_config_rxcsum_offload(struct osi_core_priv_data *osi_core, - unsigned int enable) +int osi_config_rxcsum_offload( + struct osi_core_priv_data *const osi_core, + const unsigned int enable) { if (osi_core != OSI_NULL && osi_core->ops != OSI_NULL && osi_core->ops->config_rxcsum_offload != OSI_NULL) { @@ -542,8 +550,8 @@ int osi_config_rxcsum_offload(struct osi_core_priv_data *osi_core, return -1; } -int osi_update_vlan_id(struct osi_core_priv_data *osi_core, - unsigned int vid) +int osi_update_vlan_id(struct osi_core_priv_data *const osi_core, + const unsigned int vid) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->update_vlan_id != OSI_NULL)) { @@ -554,8 +562,8 @@ int osi_update_vlan_id(struct osi_core_priv_data *osi_core, return -1; } -int osi_set_systime_to_mac(struct osi_core_priv_data *osi_core, - unsigned int sec, unsigned int nsec) +int osi_set_systime_to_mac(struct osi_core_priv_data *const osi_core, + const unsigned int sec, const unsigned int nsec) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->set_systime_to_mac != OSI_NULL)) { @@ -616,7 +624,7 @@ static inline unsigned long div_u64(unsigned long dividend, return div_u64_rem(dividend, divisor, &remain); } -int osi_adjust_freq(struct osi_core_priv_data *osi_core, int ppb) +int osi_adjust_freq(struct osi_core_priv_data *const osi_core, int ppb) { unsigned long adj; unsigned long temp; @@ -672,7 +680,8 @@ int osi_adjust_freq(struct osi_core_priv_data *osi_core, int ppb) return ret; } -int osi_adjust_time(struct osi_core_priv_data *osi_core, long long nsec_delta) +int osi_adjust_time(struct osi_core_priv_data *const osi_core, + long long nsec_delta) { unsigned int neg_adj = 0; unsigned int sec = 0, nsec = 0; @@ -708,7 +717,8 @@ int osi_adjust_time(struct osi_core_priv_data *osi_core, long long nsec_delta) return ret; } -int osi_get_systime_from_mac(struct osi_core_priv_data *osi_core, +int osi_get_systime_from_mac( + struct osi_core_priv_data *const osi_core, unsigned int *sec, unsigned int *nsec) { @@ -738,8 +748,8 @@ int osi_get_systime_from_mac(struct osi_core_priv_data *osi_core, return 0; } -int osi_ptp_configuration(struct osi_core_priv_data *osi_core, - unsigned int enable) +int osi_ptp_configuration(struct osi_core_priv_data *const osi_core, + const unsigned int enable) { int ret = 0; unsigned long temp = 0, temp1 = 0; @@ -794,7 +804,7 @@ int osi_ptp_configuration(struct osi_core_priv_data *osi_core, return ret; } -int osi_read_mmc(struct osi_core_priv_data *osi_core) +int osi_read_mmc(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->read_mmc != OSI_NULL)) { @@ -805,7 +815,7 @@ int osi_read_mmc(struct osi_core_priv_data *osi_core) return -1; } -int osi_reset_mmc(struct osi_core_priv_data *osi_core) +int osi_reset_mmc(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->reset_mmc != OSI_NULL)) { @@ -816,8 +826,8 @@ int osi_reset_mmc(struct osi_core_priv_data *osi_core) return -1; } -int osi_configure_eee(struct osi_core_priv_data *osi_core, - unsigned int tx_lpi_enabled, unsigned int tx_lpi_timer) +int osi_configure_eee(struct osi_core_priv_data *const osi_core, + unsigned int tx_lpi_enabled, unsigned int tx_lpi_timer) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->configure_eee != OSI_NULL) && @@ -832,7 +842,7 @@ int osi_configure_eee(struct osi_core_priv_data *osi_core, return -1; } -int osi_save_registers(struct osi_core_priv_data *osi_core) +int osi_save_registers(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->save_registers != OSI_NULL)) { @@ -843,7 +853,7 @@ int osi_save_registers(struct osi_core_priv_data *osi_core) return -1; } -int osi_restore_registers(struct osi_core_priv_data *osi_core) +int osi_restore_registers(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->restore_registers != OSI_NULL)) { From 1e5dd8d2a143a4ee862f2abbb117c42d4cd78572 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Mon, 10 Feb 2020 10:21:55 +0530 Subject: [PATCH 076/458] nvethernetrm: Add MMC counters Adds MMC counters for which hold higher values. Bug 200565915 Change-Id: I8803a60d97b0235911df177f820b8c66cfb0b1bb Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2292221 Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/mmc.h | 226 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 219 insertions(+), 7 deletions(-) diff --git a/include/mmc.h b/include/mmc.h index 5e401dd..60921f3 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -29,50 +29,91 @@ struct osi_mmc_counters { /** This counter provides the number of bytes transmitted, exclusive of * preamble and retried bytes, in good and bad packets */ unsigned long mmc_tx_octetcount_gb; + /** This counter provides upper 32 bits of transmitted octet count */ + unsigned long mmc_tx_octetcount_gb_h; /** This counter provides the number of good and * bad packets transmitted, exclusive of retried packets */ unsigned long mmc_tx_framecount_gb; + /** This counter provides upper 32 bits of transmitted good and bad + * packets count */ + unsigned long mmc_tx_framecount_gb_h; /** This counter provides number of good broadcast * packets transmitted */ unsigned long mmc_tx_broadcastframe_g; + /** This counter provides upper 32 bits of transmitted good broadcast + * packets count */ + unsigned long mmc_tx_broadcastframe_g_h; /** This counter provides number of good multicast * packets transmitted */ unsigned long mmc_tx_multicastframe_g; + /** This counter provides upper 32 bits of transmitted good multicast + * packet count */ + unsigned long 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 */ unsigned long mmc_tx_64_octets_gb; + /** This counter provides upper 32 bits of transmitted 64 octet size + * good and bad packets count */ + unsigned long 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 */ unsigned long mmc_tx_65_to_127_octets_gb; + /** Provides upper 32 bits of transmitted 65-to-127 octet size good and + * bad packets count */ + unsigned long 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 */ unsigned long 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 */ + unsigned long 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 */ unsigned long 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. */ + unsigned long 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 */ unsigned long 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.*/ + unsigned long 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 */ unsigned long mmc_tx_1024_to_max_octets_gb; + /** This counter provides upper 32 bits of transmitted 1024-tomaxsize + * octet size good and bad packets count. */ + unsigned long mmc_tx_1024_to_max_octets_gb_h; /** This counter provides the number of good and bad unicast packets */ unsigned long mmc_tx_unicast_gb; + /** This counter provides upper 32 bits of transmitted good bad + * unicast packets count */ + unsigned long mmc_tx_unicast_gb_h; /** This counter provides the number of good and bad * multicast packets */ unsigned long mmc_tx_multicast_gb; + /** This counter provides upper 32 bits of transmitted good bad + * multicast packets count */ + unsigned long mmc_tx_multicast_gb_h; /** This counter provides the number of good and bad * broadcast packets */ unsigned long mmc_tx_broadcast_gb; - /** mmc_tx_underflow_error: This counter provides the number of abort - * packets due to underflow error */ + /** This counter provides upper 32 bits of transmitted good bad + * broadcast packets count */ + unsigned long mmc_tx_broadcast_gb_h; + /** This counter provides the number of abort packets due to + * underflow error */ unsigned long mmc_tx_underflow_error; + /** This counter provides upper 32 bits of abort packets due to + * underflow error */ + unsigned long mmc_tx_underflow_error_h; /** This counter provides the number of successfully transmitted * packets after a single collision in the half-duplex mode */ unsigned long mmc_tx_singlecol_g; @@ -94,8 +135,13 @@ struct osi_mmc_counters { /** This counter provides the number of bytes transmitted, * exclusive of preamble, only in good packets */ unsigned long mmc_tx_octetcount_g; + /** This counter provides upper 32 bytes of bytes transmitted, + * exclusive of preamble, only in good packets */ + unsigned long mmc_tx_octetcount_g_h; /** This counter provides the number of good packets transmitted */ unsigned long mmc_tx_framecount_g; + /** This counter provides upper 32 bytes of good packets transmitted */ + unsigned long 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) */ @@ -103,29 +149,53 @@ struct osi_mmc_counters { /** This counter provides the number of good Pause * packets transmitted */ unsigned long mmc_tx_pause_frame; + /** This counter provides upper 32 bytes of good Pause + * packets transmitted */ + unsigned long mmc_tx_pause_frame_h; /** This counter provides the number of good VLAN packets transmitted */ unsigned long mmc_tx_vlan_frame_g; + /** This counter provides upper 32 bytes of good VLAN packets + * transmitted */ + unsigned long 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 */ unsigned long mmc_tx_osize_frame_g; /** This counter provides the number of good and bad packets received */ unsigned long mmc_rx_framecount_gb; + /** This counter provides upper 32 bytes of good and bad packets + * received */ + unsigned long 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 */ unsigned long mmc_rx_octetcount_gb; - /** This counter provides the number of bytes received by DWC_ther_qos, + /** This counter provides upper 32 bytes of bytes received by + * DWC_ether_qos, exclusive of preamble, in good and bad packets */ + unsigned long 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 */ unsigned long 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 */ + unsigned long mmc_rx_octetcount_g_h; /** This counter provides the number of good * broadcast packets received */ unsigned long mmc_rx_broadcastframe_g; + /** This counter provides upper 32 bytes of good + * broadcast packets received */ + unsigned long mmc_rx_broadcastframe_g_h; /** This counter provides the number of good * multicast packets received */ unsigned long mmc_rx_multicastframe_g; + /** This counter provides upper 32 bytes of good + * multicast packets received */ + unsigned long mmc_rx_multicastframe_g_h; /** This counter provides the number of packets * received with CRC error */ unsigned long mmc_rx_crc_error; + /** This counter provides upper 32 bytes of packets + * received with CRC error */ + unsigned long 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 */ unsigned long mmc_rx_align_error; @@ -145,40 +215,78 @@ struct osi_mmc_counters { /** This counter provides the number of good and bad packets received * with length 64 bytes, exclusive of the preamble */ unsigned long 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 */ + unsigned long 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 */ unsigned long 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 */ + unsigned long 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 */ unsigned long 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 */ + unsigned long 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 */ unsigned long 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 */ + unsigned long 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 */ unsigned long 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 */ + unsigned long 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 */ unsigned long 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 */ + unsigned long mmc_rx_1024_to_max_octets_gb_h; /** This counter provides the number of good unicast packets received */ unsigned long mmc_rx_unicast_g; + /** This counter provides upper 32 bytes of good unicast packets + * received */ + unsigned long 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 */ unsigned long 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 */ + unsigned long 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) */ unsigned long 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) */ + unsigned long mmc_rx_outofrangetype_h; /** This counter provides the number of good and valid Pause packets * received */ unsigned long mmc_rx_pause_frames; + /** This counter provides upper 32 bytes of good and valid Pause packets + * received */ + unsigned long mmc_rx_pause_frames_h; /** This counter provides the number of missed received packets * because of FIFO overflow in DWC_ether_qos */ unsigned long mmc_rx_fifo_overflow; + /** This counter provides upper 32 bytes of missed received packets + * because of FIFO overflow in DWC_ether_qos */ + unsigned long mmc_rx_fifo_overflow_h; /** This counter provides the number of good and bad VLAN packets * received */ unsigned long mmc_rx_vlan_frames_gb; + /** This counter provides upper 32 bytes of good and bad VLAN packets + * received */ + unsigned long mmc_rx_vlan_frames_gb_h; /** This counter provides the number of packets received with error * because of watchdog timeout error */ unsigned long mmc_rx_watchdog_error; @@ -203,115 +311,219 @@ struct osi_mmc_counters { /** This counter provides the number of good IPv4 datagrams received * with the TCP, UDP, or ICMP payload */ unsigned long mmc_rx_ipv4_gd; + /** This counter provides upper 32 bytes of good IPv4 datagrams received + * with the TCP, UDP, or ICMP payload */ + unsigned long mmc_rx_ipv4_gd_h; /** RxIPv4 Header Error Packets */ unsigned long mmc_rx_ipv4_hderr; + /** RxIPv4 of upper 32 bytes of Header Error Packets */ + unsigned long 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 */ unsigned long 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 */ + unsigned long mmc_rx_ipv4_nopay_h; /** This counter provides the number of good IPv4 datagrams received * with fragmentation */ unsigned long mmc_rx_ipv4_frag; + /** This counter provides upper 32 bytes of good IPv4 datagrams received + * with fragmentation */ + unsigned long mmc_rx_ipv4_frag_h; /** This counter provides the number of good IPv4 datagrams received * that had a UDP payload with checksum disabled */ unsigned long mmc_rx_ipv4_udsbl; - + /** This counter provides upper 32 bytes of good IPv4 datagrams received + * that had a UDP payload with checksum disabled */ + unsigned long mmc_rx_ipv4_udsbl_h; /** This counter provides the number of good IPv6 datagrams received * with the TCP, UDP, or ICMP payload */ unsigned long mmc_rx_ipv6_gd_octets; + /** This counter provides upper 32 bytes of good IPv6 datagrams received + * with the TCP, UDP, or ICMP payload */ + unsigned long mmc_rx_ipv6_gd_octets_h; /** This counter provides the number of IPv6 datagrams received * with header (length or version mismatch) errors */ unsigned long mmc_rx_ipv6_hderr_octets; + /** This counter provides the number of IPv6 datagrams received + * with header (length or version mismatch) errors */ + unsigned long 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 */ unsigned long 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 */ + unsigned long 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 */ unsigned long mmc_rx_udp_gd; + /** This counter provides upper 32 bytes of good IP datagrams received + * by DWC_ether_qos with a good UDP payload */ + unsigned long 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 */ unsigned long 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 */ + unsigned long mmc_rx_udp_err_h; /** This counter provides the number of good IP datagrams received * with a good TCP payload */ unsigned long mmc_rx_tcp_gd; /** This counter provides the number of good IP datagrams received * with a good TCP payload */ + unsigned long mmc_rx_tcp_gd_h; + /** This counter provides upper 32 bytes of good IP datagrams received + * with a good TCP payload */ unsigned long mmc_rx_tcp_err; + /** This counter provides upper 32 bytes of good IP datagrams received + * with a good TCP payload */ + unsigned long mmc_rx_tcp_err_h; /** This counter provides the number of good IP datagrams received * with a good ICMP payload */ unsigned long mmc_rx_icmp_gd; + /** This counter provides upper 32 bytes of good IP datagrams received + * with a good ICMP payload */ + unsigned long mmc_rx_icmp_gd_h; /** This counter provides the number of good IP datagrams received * whose ICMP payload has a checksum error */ unsigned long mmc_rx_icmp_err; - + /** This counter provides upper 32 bytes of good IP datagrams received + * whose ICMP payload has a checksum error */ + unsigned long 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 */ unsigned long 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 */ + unsigned long 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 */ unsigned long 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 */ + unsigned long 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 */ unsigned long 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 */ + unsigned long 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 */ unsigned long 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 */ + unsigned long 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 */ unsigned long 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 */ + unsigned long 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 */ unsigned long 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 */ + unsigned long 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 */ unsigned long 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 */ + unsigned long 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 */ unsigned long 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 */ + unsigned long 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 */ unsigned long 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 */ + unsigned long 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 */ unsigned long 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 */ + unsigned long 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 */ unsigned long 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 */ + unsigned long 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 */ unsigned long 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 */ + unsigned long 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 */ unsigned long 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 */ + unsigned long 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 */ unsigned long 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 */ + unsigned long mmc_rx_icmp_err_octets_h; }; /** From 1aead3166e0519a44ef87c466803a67364cc3242 Mon Sep 17 00:00:00 2001 From: Mahesh Patil <maheshp@nvidia.com> Date: Tue, 28 Jan 2020 13:14:57 -0800 Subject: [PATCH 077/458] nvethernetrm: move core_backup to osi_common.h Issue: RFE: move struct core_backup to osi_common.h Fix: 1. Moved core_backup to osi_common.h 2. Added generic osi_mac_restore_registers() and osi_mac_save_registers() Api's in osi_common.c Bug 2804631 Change-Id: I5bc71666e104f2e729024e096bd51ce350f2a1f0 Signed-off-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2286642 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Ajay Gupta <ajayg@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_common.h | 42 ++++++++++++++++++++++++++++++++ include/osi_core.h | 4 ---- osi/common/osi_common.c | 53 ++++++++++++++++++++++++++++++++++++++++- osi/core/eqos_core.c | 48 ------------------------------------- osi/core/eqos_core.h | 10 -------- osi/core/osi_core.c | 8 +++---- 6 files changed, 98 insertions(+), 67 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index 5363c43..d497431 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -263,6 +263,12 @@ #define OSI_INVALID_CHAN_NUM 0xFFU /** @} */ +/** + * @brief Max num of MAC core registers to backup. It should be max of or >= + * (EQOS_MAX_BAK_IDX=380, MGBE_MAX_BAK_IDX, coreX,...etc) backup registers. + */ +#define CORE_MAX_BAK_IDX 400U + /** * @addtogroup EQOS-MAC EQOS MAC HW supported features * @@ -504,6 +510,16 @@ struct osi_hw_features { unsigned int aux_snap_num; }; +/** + * @brief core_backup - Struct used to store backup of core HW registers. + */ +struct core_backup { + /** Array of reg MMIO addresses (base of MAC core + offset of reg) */ + void *reg_addr[CORE_MAX_BAK_IDX]; + /** Array of value stored in each corresponding register */ + unsigned int reg_val[CORE_MAX_BAK_IDX]; +}; + /** * @brief osi_lock_init - Initialize lock to unlocked state. * @@ -664,4 +680,30 @@ void osi_get_hw_features(void *base, struct osi_hw_features *hw_feat); * */ void osi_memset(void *s, unsigned int c, unsigned long count); + +/* + * @brief 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] config: Pointer to core_backup structure. + * @param[in] max_regs: Max num of registers to backup. + * + * @retval none + */ +void mac_save_registers(struct core_backup *const config); + +/** + * @brief Function to restore the backup of MAC registers during SOC resume. + * + * Algorithm: Restore the register values from the in memory backup taken using + * osi_save_registers(). + * + * @param[in] config: Pointer to core_backup structure. + * @param[in] max_regs: Max num of registers to restore. + * + * @retval none + */ +void mac_restore_registers(struct core_backup *const config); #endif /* OSI_COMMON_H */ diff --git a/include/osi_core.h b/include/osi_core.h index 82bd47d..23bb206 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -259,10 +259,6 @@ struct osi_core_ops { void (*configure_eee)(struct osi_core_priv_data *const osi_core, const unsigned int tx_lpi_enabled, const unsigned int tx_lpi_timer); - /** Called to save MAC register space during SOC suspend */ - void (*save_registers)(struct osi_core_priv_data *const osi_core); - /** Called to restore MAC control registers during SOC resume */ - void (*restore_registers)(struct osi_core_priv_data *const osi_core); /** Called to write into a PHY reg over MDIO bus */ int (*write_phy_reg)(struct osi_core_priv_data *const osi_core, const unsigned int phyaddr, diff --git a/osi/common/osi_common.c b/osi/common/osi_common.c index 8d50f93..c85377a 100644 --- a/osi/common/osi_common.c +++ b/osi/common/osi_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -134,3 +134,54 @@ void osi_memset(void *s, unsigned int c, unsigned long count) count--; } } + +/* + * @brief 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] config: Pointer to core_backup structure. + * @param[in] max_regs: Max num of registers to backup. + * + * @retval none + */ +void mac_save_registers(struct core_backup *const config) +{ + unsigned int i; + + if (config == OSI_NULL) { + return; + } + for (i = 0; i < CORE_MAX_BAK_IDX; i++) { + if (config->reg_addr[i] != OSI_NULL) { + config->reg_val[i] = osi_readl(config->reg_addr[i]); + } + } + +} + +/** + * @brief Function to restore the backup of MAC registers during SOC resume. + * + * Algorithm: Restore the register values from the in memory backup taken using + * osi_save_registers(). + * + * @param[in] config: Pointer to core_backup structure. + * @param[in] max_regs: Max num of registers to restore. + * + * @retval none + */ +void mac_restore_registers(struct core_backup *const config) +{ + unsigned int i; + + if (config == OSI_NULL) { + return; + } + for (i = 0; i < CORE_MAX_BAK_IDX; i++) { + if (config->reg_addr[i] != OSI_NULL) { + osi_writel(config->reg_val[i], config->reg_addr[i]); + } + } +} diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index ffe8292..ebe9872 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -3445,52 +3445,6 @@ static void eqos_configure_eee( } } -/* - * @brief 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 none - */ -static inline void eqos_save_registers( - struct osi_core_priv_data *const osi_core) -{ - unsigned int 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_readl(config->reg_addr[i]); - } - } -} - -/** - * @brief Function to restore the backup of MAC registers during SOC resume. - * - * Algorithm: Restore the register values from the in memory backup taken using - * eqos_save_registers(). - * - * @param[in] osi_core: OSI core private data structure. - * - * @retval none - */ -static inline void eqos_restore_registers( - struct osi_core_priv_data *const osi_core) -{ - unsigned int 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_writel(config->reg_val[i], config->reg_addr[i]); - } - } -} - /** * @brief poll_for_mii_idle Query the status of an ongoing DMA transfer * @@ -3689,8 +3643,6 @@ static struct osi_core_ops eqos_core_ops = { .read_mmc = eqos_read_mmc, .reset_mmc = eqos_reset_mmc, .configure_eee = eqos_configure_eee, - .save_registers = eqos_save_registers, - .restore_registers = eqos_restore_registers, .write_phy_reg = eqos_write_phy_reg, .read_phy_reg = eqos_read_phy_reg, }; diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 9f8f8cb..e7066dd 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -599,15 +599,5 @@ struct core_func_safety { */ #define EQOS_MAX_BAK_IDX ((EQOS_PAD_AUTO_CAL_CFG_BAK_IDX + 1U)) -/** - * @brief core_backup - Struct used to store backup of core HW registers. - */ -struct core_backup { - /** Array of reg MMIO addresses (base of EQoS + offset of reg) */ - void *reg_addr[EQOS_MAX_BAK_IDX]; - /** Array of value stored in each corresponding register */ - unsigned int reg_val[EQOS_MAX_BAK_IDX]; -}; - /** @} */ #endif diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 9c7cdab..a3885ab 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -845,8 +845,8 @@ int osi_configure_eee(struct osi_core_priv_data *const osi_core, int osi_save_registers(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->save_registers != OSI_NULL)) { - osi_core->ops->save_registers(osi_core); + (osi_core->backup_config != OSI_NULL)) { + mac_save_registers(osi_core->backup_config); return 0; } @@ -856,8 +856,8 @@ int osi_save_registers(struct osi_core_priv_data *const osi_core) int osi_restore_registers(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->restore_registers != OSI_NULL)) { - osi_core->ops->restore_registers(osi_core); + (osi_core->backup_config != OSI_NULL)) { + mac_restore_registers(osi_core->backup_config); return 0; } From e3fc29b01d7d1cd8f60f2bd35ded68989bf9658d Mon Sep 17 00:00:00 2001 From: Srinivas Ramachandran <srinivasra@nvidia.com> Date: Mon, 27 Jan 2020 11:57:09 -0800 Subject: [PATCH 078/458] nvethernetrm: Set DO bit in MCR for HD mode Issue: As per databook, the DO bit needs to be set in HD mode to prevent reception of packets sent by DUT itself. Fix: Set the DO bit in MCR register for HD mode Bug 2804169 Change-Id: I8f5bf4be5deb3607786319196bd8633ff122b759 Signed-off-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2285885 Tested-by: Mahesh Patil <maheshp@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/eqos_core.c | 8 ++++++-- osi/core/eqos_core.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index ebe9872..2a5dce3 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -768,9 +768,13 @@ static void eqos_set_mode(void *base, const int mode) mcr_val = osi_readl((unsigned char *)base + EQOS_MAC_MCR); if (mode == OSI_FULL_DUPLEX) { - mcr_val |= (0x00002000U); + 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 &= ~(0x00002000U); + mcr_val &= ~EQOS_MCR_DM; + /* Set DO (disable receive own) bit */ + mcr_val |= EQOS_MCR_DO; } else { /* Nothing here */ } diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index e7066dd..61fffb9 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -194,6 +194,7 @@ #define EQOS_MTL_RSF OSI_BIT(5) #define EQOS_MCR_TE OSI_BIT(0) #define EQOS_MCR_RE 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) From 3e40ffdc9e32746da05926594710896cc5cc3d69 Mon Sep 17 00:00:00 2001 From: narayanr <narayanr@nvidia.com> Date: Thu, 27 Feb 2020 14:22:16 +0530 Subject: [PATCH 079/458] nvethernetrm: enable GPSLCE Enable Gaint Packet Size Limit Control when MTU size is greater than 9000 Bug 200512422 Change-Id: I458b561298760cbb4945195a86daed43ba69d1c6 Signed-off-by: narayanr <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2303736 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_common.h | 15 +++++++-------- osi/core/eqos_core.c | 22 +++++++++++++++++----- osi/core/eqos_core.h | 4 +++- osi/dma/eqos_dma.c | 21 +++++++++------------ osi/dma/eqos_dma.h | 3 ++- 5 files changed, 38 insertions(+), 27 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index d497431..2df4765 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -166,13 +166,10 @@ OSI_LOG_WARN, type, err, loga); \ } -/* Default maximum Gaint Packet Size Limit */ -#define OSI_MAX_MTU_SIZE 9000U +/* Default maximum Gaint Packet Size Limit is 16K */ +#define OSI_MAX_MTU_SIZE 16383U +#define OSI_MTU_SIZE_9000 9000U #define OSI_DFLT_MTU_SIZE 1500U -#define OSI_MTU_SIZE_2K 2048U -#define OSI_MTU_SIZE_4K 4096U -#define OSI_MTU_SIZE_8K 8192U -#define OSI_MTU_SIZE_16K 16384U #define EQOS_DMA_CHX_STATUS(x) ((0x0080U * (x)) + 0x1160U) #define EQOS_DMA_CHX_IER(x) ((0x0080U * (x)) + 0x1134U) @@ -250,9 +247,11 @@ #define OSI_FULL_DUPLEX 1 #define OSI_HALF_DUPLEX 0 -#define NV_ETH_FRAME_LEN 1514U -#define NV_ETH_FCS_LEN 0x4U +#define NV_ETH_FRAME_LEN 1514U +#define NV_ETH_FCS_LEN 0x4U #define NV_VLAN_HLEN 0x4U +#define OSI_ETH_HLEN 0xEU +#define OSI_NET_IP_ALIGN 0x2U #define MAX_ETH_FRAME_LEN_DEFAULT \ (NV_ETH_FRAME_LEN + NV_ETH_FCS_LEN + NV_VLAN_HLEN) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 2a5dce3..c3a6db5 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1307,6 +1307,7 @@ static void eqos_configure_rxq_priority( static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) { unsigned int value; + unsigned int mac_ext; /* Update MAC address 0 high */ value = (((unsigned int)osi_core->mac_addr[5] << 8U) | @@ -1330,13 +1331,24 @@ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) /* 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) { - value |= EQOS_MCR_S2KP; - } - - if (osi_core->mtu > OSI_MTU_SIZE_2K) { + 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 MTU greater 9K use GPSLCE */ + value |= EQOS_MCR_JD | EQOS_MCR_WD; + value |= EQOS_MCR_GPSLCE; + /* Read MAC Extenstion Register */ + mac_ext = osi_readl((unsigned char *)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 Extenstion Register */ + osi_writel(mac_ext, (unsigned char *)osi_core->base + + EQOS_MAC_EXTR); } eqos_core_safety_writel(value, (unsigned char *)osi_core->base + diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 61fffb9..4849ce0 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -200,9 +200,10 @@ #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_S2KP OSI_BIT(22) +#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) @@ -382,6 +383,7 @@ #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_DMA_CHX_STATUS_TPS OSI_BIT(1) #define EQOS_DMA_CHX_STATUS_TBU OSI_BIT(2) diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index 540bf7a..b7cc345 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -651,6 +651,9 @@ static void eqos_configure_dma_channel(unsigned int chan, value = osi_readl((unsigned char *)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; @@ -712,18 +715,12 @@ static void eqos_init_dma_channel(struct osi_dma_priv_data *osi_dma) */ static void eqos_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) { - unsigned int rx_buf_len; + unsigned int rx_buf_len = 0U; - if (osi_dma->mtu >= OSI_MTU_SIZE_8K) { - rx_buf_len = OSI_MTU_SIZE_16K; - } else if (osi_dma->mtu >= OSI_MTU_SIZE_4K) { - rx_buf_len = OSI_MTU_SIZE_8K; - } else if (osi_dma->mtu >= OSI_MTU_SIZE_2K) { - rx_buf_len = OSI_MTU_SIZE_4K; - } else if (osi_dma->mtu > MAX_ETH_FRAME_LEN_DEFAULT) { - rx_buf_len = OSI_MTU_SIZE_2K; - } else { - rx_buf_len = MAX_ETH_FRAME_LEN_DEFAULT; + /* Add Ethernet header + VLAN header + NET IP align size to MTU */ + if (osi_dma->mtu < UINT_MAX) { + rx_buf_len = osi_dma->mtu + OSI_ETH_HLEN + NV_VLAN_HLEN + + OSI_NET_IP_ALIGN; } /* Buffer alignment */ diff --git a/osi/dma/eqos_dma.h b/osi/dma/eqos_dma.h index 766c586..3d8f50f 100644 --- a/osi/dma/eqos_dma.h +++ b/osi/dma/eqos_dma.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -86,6 +86,7 @@ #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 From be1c1e41462bec0525cedcde97c95afe39638b97 Mon Sep 17 00:00:00 2001 From: narayanr <narayanr@nvidia.com> Date: Tue, 3 Mar 2020 21:00:24 +0530 Subject: [PATCH 080/458] nveternetrm: fix doxygen comments Bug 2804631 Bug 2804169 Bug 200561709 Change-Id: I6d61c8b8a911ae3847049c534e6d19e0aec65209 Signed-off-by: narayanr <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2306568 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_common.h | 32 ++++++++++++++++++++----- osi/common/osi_common.c | 22 ----------------- osi/core/eqos_core.c | 52 ++++++++++++++++++++++++++++++++++++++--- osi/core/eqos_core.h | 2 +- 4 files changed, 76 insertions(+), 32 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index 2df4765..8a105ea 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -24,7 +24,9 @@ #define OSI_COMMON_H /** - * @addtogroup EQOS-Helper Helper MACROS + * @addtogroup Helper Helper MACROS + * + * @brief EQOS generic helper MACROS. * @{ */ #define OSI_UNLOCKED 0x0U @@ -43,6 +45,7 @@ #define OSI_MAX_TX_COALESCE_USEC 1020U #define OSI_MIN_TX_COALESCE_USEC 32U #define OSI_MIN_TX_COALESCE_FRAMES 1U +/** @} */ /** * @addtogroup - LPI-Timers LPI configuration macros @@ -83,6 +86,12 @@ #define OSI_MIN_TX_LPI_TIMER 0x8U /** @} */ +/** + * @addtogroup Helper Helper MACROS + * + * @brief EQOS generic helper MACROS. + * @{ + */ #define OSI_PAUSE_FRAMES_ENABLE 0U #define OSI_PAUSE_FRAMES_DISABLE 1U #define OSI_FLOW_CTRL_TX OSI_BIT(0) @@ -99,8 +108,14 @@ #ifndef INT_MAX #define INT_MAX (0x7FFFFFFF) #endif +/** @} */ -/* MAC Time stamp contorl reg bit fields */ +/** + * @addtogroup EQOS_PTP PTP Helper MACROS + * + * @brief EQOS PTP MAC Time stamp contorl 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) @@ -115,7 +130,14 @@ #define OSI_MAC_TCR_SNAPTYPSEL_2 OSI_BIT(17) #define OSI_MAC_TCR_SNAPTYPSEL_3 (OSI_BIT(16) | OSI_BIT(17)) #define OSI_MAC_TCR_AV8021ASMEN OSI_BIT(28) +/** @} */ +/** + * @addtogroup Helper Helper MACROS + * + * @brief EQOS generic helper MACROS. + * @{ + */ #define OSI_ULLONG_MAX (~0ULL) #define OSI_UCHAR_MAX (0xFFU) @@ -330,7 +352,7 @@ /** @} */ /** - * @addtogroup MTL queue AVB algorithm mode + * @addtogroup EQOS_MTL MTL queue AVB algorithm mode * * @brief MTL AVB queue algorithm type * @{ @@ -680,14 +702,13 @@ void osi_get_hw_features(void *base, struct osi_hw_features *hw_feat); */ void osi_memset(void *s, unsigned int c, unsigned long count); -/* +/** * @brief 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] config: Pointer to core_backup structure. - * @param[in] max_regs: Max num of registers to backup. * * @retval none */ @@ -700,7 +721,6 @@ void mac_save_registers(struct core_backup *const config); * osi_save_registers(). * * @param[in] config: Pointer to core_backup structure. - * @param[in] max_regs: Max num of registers to restore. * * @retval none */ diff --git a/osi/common/osi_common.c b/osi/common/osi_common.c index c85377a..46dae88 100644 --- a/osi/common/osi_common.c +++ b/osi/common/osi_common.c @@ -135,17 +135,6 @@ void osi_memset(void *s, unsigned int c, unsigned long count) } } -/* - * @brief 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] config: Pointer to core_backup structure. - * @param[in] max_regs: Max num of registers to backup. - * - * @retval none - */ void mac_save_registers(struct core_backup *const config) { unsigned int i; @@ -161,17 +150,6 @@ void mac_save_registers(struct core_backup *const config) } -/** - * @brief Function to restore the backup of MAC registers during SOC resume. - * - * Algorithm: Restore the register values from the in memory backup taken using - * osi_save_registers(). - * - * @param[in] config: Pointer to core_backup structure. - * @param[in] max_regs: Max num of registers to restore. - * - * @retval none - */ void mac_restore_registers(struct core_backup *const config) { unsigned int i; diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index c3a6db5..3d9f08b 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1296,9 +1296,10 @@ static void eqos_configure_rxq_priority( * 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 interrupts and Configure the MMC counters - * 5) Enable required MAC interrupts + * 3) Enable JE/JD/WD/GPSLCE based on the MTU size + * 4) Enable Multicast and Broadcast Queue + * 5) Disable MMC interrupts and Configure the MMC counters + * 6) Enable required MAC interrupts * * @param[in] osi_core: OSI core private data structure. * @@ -3504,6 +3505,29 @@ static inline int poll_for_mii_idle(struct osi_core_priv_data *osi_core) return 0; } +/** + * @brief eqos_write_phy_reg - Write to a PHY register through MAC over MDIO bus + * + * Algorithm: + * 1) Before proceeding for reading for PHY register check whether any MII + * operation going on MDIO bus by polling MAC_GMII_BUSY bit. + * 2) Program data into MAC MDIO data register. + * 3) 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. + * 4) 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. + * + * @note MAC should be init and started. see osi_start_mac() + * + * @retval 0 on success + * @retval -1 on failure. + */ static int eqos_write_phy_reg(struct osi_core_priv_data *const osi_core, const unsigned int phyaddr, const unsigned int phyreg, @@ -3562,6 +3586,28 @@ static int eqos_write_phy_reg(struct osi_core_priv_data *const osi_core, return ret; } +/** + * @brief eqos_read_phy_reg - Read from a PHY register through MAC over MDIO bus + * + * Algorithm: + * 1) Before proceeding for reading for PHY register check whether any MII + * operation going on MDIO bus by polling MAC_GMII_BUSY bit. + * 2) 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. + * 3) 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. + * + * @note MAC should be init and started. see osi_start_mac() + * + * @retval data from PHY register on success + * @retval -1 on failure + */ static int eqos_read_phy_reg(struct osi_core_priv_data *const osi_core, const unsigned int phyaddr, const unsigned int phyreg) diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 4849ce0..54223e7 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -491,7 +491,7 @@ struct core_func_safety { }; /** - * @addtogroup EQOS-HW-BACKUP + * @addtogroup EQOS_HW EQOS HW BACKUP registers * * @brief Definitions related to taking backup of EQOS core registers. * @{ From 065bc38a7678a12870f771d6c18882138abf225b Mon Sep 17 00:00:00 2001 From: rakesh goyal <rgoyal@nvidia.com> Date: Fri, 28 Feb 2020 16:04:53 +0530 Subject: [PATCH 081/458] nvethernetrm: add counter for pkt_err stats cleared MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add counter for how many times pkt_err stats got cleared using osi_clear_tx_pkt_err_stats and osi_clear_rx_pkt_err_stats call. Bug 200548007 Change-Id: I19b796131ac6bb43a52aad9bc3211426da4fe4ae Signed-off-by: rakesh goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2304567 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_dma.h | 6 +++++- osi/dma/osi_dma_txrx.c | 32 +++++++++++++++++++++----------- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/include/osi_dma.h b/include/osi_dma.h index 76bf6a9..9f4af2c 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -136,6 +136,10 @@ struct osi_pkt_err_stats { unsigned long rx_crc_error; /** Rx Frame Error */ unsigned long rx_frame_error; + /** clear_tx_pkt_err_stats() API invoked */ + unsigned long clear_tx_err; + /** clear_rx_pkt_err_stats() API invoked */ + unsigned long clear_rx_err; }; /** diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index aaf50eb..9c6210f 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -392,19 +392,24 @@ static inline void get_tx_err_stats(struct osi_tx_desc *tx_desc, int osi_clear_tx_pkt_err_stats(struct osi_dma_priv_data *osi_dma) { int 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 */ - osi_dma->pkt_err_stats.ip_header_error = 0U; - osi_dma->pkt_err_stats.jabber_timeout_error = 0U; - osi_dma->pkt_err_stats.pkt_flush_error = 0U; - osi_dma->pkt_err_stats.payload_cs_error = 0U; - osi_dma->pkt_err_stats.loss_of_carrier_error = 0U; - osi_dma->pkt_err_stats.no_carrier_error = 0U; - osi_dma->pkt_err_stats.late_collision_error = 0U; - osi_dma->pkt_err_stats.excessive_collision_error = 0U; - osi_dma->pkt_err_stats.excessive_deferal_error = 0U; - osi_dma->pkt_err_stats.underflow_error = 0U; + 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; } @@ -414,10 +419,15 @@ int osi_clear_tx_pkt_err_stats(struct osi_dma_priv_data *osi_dma) int osi_clear_rx_pkt_err_stats(struct osi_dma_priv_data *osi_dma) { int 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 */ - osi_dma->pkt_err_stats.rx_crc_error = 0U; + 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; } From acbb40e98fe1083dc4f1ce6416cb9b68b8593b3a Mon Sep 17 00:00:00 2001 From: narayanr <narayanr@nvidia.com> Date: Fri, 6 Mar 2020 10:33:59 +0530 Subject: [PATCH 082/458] nvethernetrm: drop rx packets longer than current MTU Issue: 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. Fix: Drop Rx packets which are longer than currently set MTU since HW cannot drop them. Bug 2870545 Signed-off-by: narayanr <narayanr@nvidia.com> Change-Id: I869f4858f8d2b502a3965dc2ca40cda8805f9886 Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2308379 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_common.h | 1 + include/osi_dma.h | 2 +- include/osi_dma_txrx.h | 3 ++- osi/dma/osi_dma_txrx.c | 20 +++++++++++++++++++- 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index 8a105ea..76eacfb 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -227,6 +227,7 @@ #define OSI_MAC_HW_EQOS 0U #define OSI_ETH_ALEN 6U +#define BOOLEAN_FALSE (0U != 0U) #define OSI_NULL ((void *)0) #define OSI_ENABLE 1U #define OSI_NONE 0U diff --git a/include/osi_dma.h b/include/osi_dma.h index 9f4af2c..efc9726 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -104,7 +104,7 @@ * @{ */ /* Rx swcx flags */ -#define OSI_RX_SWCX_PTP OSI_BIT(0) +#define OSI_RX_SWCX_REUSE OSI_BIT(0) #define OSI_RX_SWCX_BUF_VALID OSI_BIT(1) /** @} */ diff --git a/include/osi_dma_txrx.h b/include/osi_dma_txrx.h index 97c0c5c..4eabb09 100644 --- a/include/osi_dma_txrx.h +++ b/include/osi_dma_txrx.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -65,6 +65,7 @@ #define RDES3_IOC OSI_BIT(30) #define RDES3_B1V OSI_BIT(24) #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) diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 9c6210f..bd09416 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -226,6 +226,24 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, INCR_RX_DESC_INDEX(rx_ring->cur_rx_idx, 1U); + /* 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; @@ -257,7 +275,7 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, * software context addresses directly since * those are valid. */ - ptp_rx_swcx->flags |= OSI_RX_SWCX_PTP; + ptp_rx_swcx->flags |= OSI_RX_SWCX_REUSE; /* Context descriptor was consumed. Its skb * and DMA mapping will be recycled */ From 884fac730e3b18c141808ceb203d4aeb748737dc Mon Sep 17 00:00:00 2001 From: Mahesh Patil <maheshp@nvidia.com> Date: Thu, 20 Feb 2020 12:41:05 -0800 Subject: [PATCH 083/458] nvethernetrm: Program LPI 1us tic counter register Issue: In GVS farm, SSH logging fails randomly after enabling EEE feature Fix: Program LPI 1usec tic counter register with correct APB clock(clk_pclk) frequency as per databook requirement. Bug 2813867 Bug 2850086 Change-Id: Ice2e130a808e763841945cb7a2d4e3552ee31498 Signed-off-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2300343 Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Ajay Gupta <ajayg@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_common.h | 8 ++++++++ include/osi_core.h | 4 ++++ osi/core/eqos_core.c | 16 ++++++++++++++++ osi/core/eqos_core.h | 1 + 4 files changed, 29 insertions(+) diff --git a/include/osi_common.h b/include/osi_common.h index 76eacfb..b11f665 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -84,6 +84,14 @@ /* 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 + /** @} */ /** diff --git a/include/osi_core.h b/include/osi_core.h index 23bb206..e128d59 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -369,6 +369,10 @@ struct osi_core_priv_data { /** L3L4 filter bit bask, set index corresponding bit for * filter if filter enabled */ unsigned int l3l4_filter_bitmask; + /** csr clock is to program LPI 1 us tick timer register. + * Value stored in MHz + */ + unsigned int csr_clk_speed; }; /** diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 3d9f08b..0f7fa04 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -692,6 +692,12 @@ static void eqos_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, { unsigned long 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 = (unsigned int)csr_clk_speed; + } if (csr_clk_speed > 500UL) { osi_core->mdc_cr = EQOS_CSR_500_800M; } else if (csr_clk_speed > 300UL) { @@ -3420,6 +3426,7 @@ static void eqos_configure_eee( unsigned int lpi_csr = 0; unsigned int lpi_timer_ctrl = 0; unsigned int lpi_entry_timer = 0; + unsigned int lpi_1US_tic_counter = OSI_LPI_1US_TIC_COUNTER_DEFAULT; unsigned char *addr = (unsigned char *)osi_core->base; if (tx_lpi_enabled != OSI_DISABLE) { @@ -3445,6 +3452,15 @@ static void eqos_configure_eee( lpi_entry_timer |= (tx_lpi_timer & OSI_LPI_ENTRY_TIMER_MASK); osi_writel(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_writel(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. diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 54223e7..3e10492 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -107,6 +107,7 @@ #define EQOS_MAC_LPI_CSR 0x00D0 #define EQOS_MAC_LPI_TIMER_CTRL 0x00D4 #define EQOS_MAC_LPI_EN_TIMER 0x00D8 +#define EQOS_MAC_1US_TIC_CNTR 0x00DC #define EQOS_MAC_ANS 0x00E4 #define EQOS_MAC_PCS 0x00F8 #define EQOS_MAC_MDIO_ADDRESS 0x0200 From 7d14557449bd0062603b9483f98303647a65c503 Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Mon, 16 Mar 2020 19:05:40 +0530 Subject: [PATCH 084/458] Revert "nvethernetrm: move core_backup to osi_common.h" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reverting this change to support IP based indirect addressing registers save and restore. Bug 200596517 Bug 2804631 This reverts commit 962ca78215e8070c78cd74e33823053dadfda7a2. Change-Id: Ia6ec230243cfb58a64e4f9fc4dbb9e3079a58cae Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2315794 Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_common.h | 40 ---------------------------------- include/osi_core.h | 4 ++++ osi/common/osi_common.c | 29 ------------------------- osi/core/eqos_core.c | 48 +++++++++++++++++++++++++++++++++++++++++ osi/core/eqos_core.h | 10 +++++++++ osi/core/osi_core.c | 8 +++---- 6 files changed, 66 insertions(+), 73 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index b11f665..046889b 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -293,12 +293,6 @@ #define OSI_INVALID_CHAN_NUM 0xFFU /** @} */ -/** - * @brief Max num of MAC core registers to backup. It should be max of or >= - * (EQOS_MAX_BAK_IDX=380, MGBE_MAX_BAK_IDX, coreX,...etc) backup registers. - */ -#define CORE_MAX_BAK_IDX 400U - /** * @addtogroup EQOS-MAC EQOS MAC HW supported features * @@ -540,16 +534,6 @@ struct osi_hw_features { unsigned int aux_snap_num; }; -/** - * @brief core_backup - Struct used to store backup of core HW registers. - */ -struct core_backup { - /** Array of reg MMIO addresses (base of MAC core + offset of reg) */ - void *reg_addr[CORE_MAX_BAK_IDX]; - /** Array of value stored in each corresponding register */ - unsigned int reg_val[CORE_MAX_BAK_IDX]; -}; - /** * @brief osi_lock_init - Initialize lock to unlocked state. * @@ -710,28 +694,4 @@ void osi_get_hw_features(void *base, struct osi_hw_features *hw_feat); * */ void osi_memset(void *s, unsigned int c, unsigned long count); - -/** - * @brief 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] config: Pointer to core_backup structure. - * - * @retval none - */ -void mac_save_registers(struct core_backup *const config); - -/** - * @brief Function to restore the backup of MAC registers during SOC resume. - * - * Algorithm: Restore the register values from the in memory backup taken using - * osi_save_registers(). - * - * @param[in] config: Pointer to core_backup structure. - * - * @retval none - */ -void mac_restore_registers(struct core_backup *const config); #endif /* OSI_COMMON_H */ diff --git a/include/osi_core.h b/include/osi_core.h index e128d59..b15fbf5 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -259,6 +259,10 @@ struct osi_core_ops { void (*configure_eee)(struct osi_core_priv_data *const osi_core, const unsigned int tx_lpi_enabled, const unsigned int tx_lpi_timer); + /** Called to save MAC register space during SoC suspend */ + void (*save_registers)(struct osi_core_priv_data *const osi_core); + /** Called to restore MAC control registers during SoC resume */ + void (*restore_registers)(struct osi_core_priv_data *const osi_core); /** Called to write into a PHY reg over MDIO bus */ int (*write_phy_reg)(struct osi_core_priv_data *const osi_core, const unsigned int phyaddr, diff --git a/osi/common/osi_common.c b/osi/common/osi_common.c index 46dae88..b2e5c92 100644 --- a/osi/common/osi_common.c +++ b/osi/common/osi_common.c @@ -134,32 +134,3 @@ void osi_memset(void *s, unsigned int c, unsigned long count) count--; } } - -void mac_save_registers(struct core_backup *const config) -{ - unsigned int i; - - if (config == OSI_NULL) { - return; - } - for (i = 0; i < CORE_MAX_BAK_IDX; i++) { - if (config->reg_addr[i] != OSI_NULL) { - config->reg_val[i] = osi_readl(config->reg_addr[i]); - } - } - -} - -void mac_restore_registers(struct core_backup *const config) -{ - unsigned int i; - - if (config == OSI_NULL) { - return; - } - for (i = 0; i < CORE_MAX_BAK_IDX; i++) { - if (config->reg_addr[i] != OSI_NULL) { - osi_writel(config->reg_val[i], config->reg_addr[i]); - } - } -} diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 0f7fa04..addb13c 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -3478,6 +3478,52 @@ static void eqos_configure_eee( } } +/* + * @brief 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 none + */ +static inline void eqos_save_registers( + struct osi_core_priv_data *const osi_core) +{ + unsigned int 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_readl(config->reg_addr[i]); + } + } +} + +/** + * @brief Function to restore the backup of MAC registers during SOC resume. + * + * Algorithm: Restore the register values from the in memory backup taken using + * eqos_save_registers(). + * + * @param[in] osi_core: OSI core private data structure. + * + * @retval none + */ +static inline void eqos_restore_registers( + struct osi_core_priv_data *const osi_core) +{ + unsigned int 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_writel(config->reg_val[i], config->reg_addr[i]); + } + } +} + /** * @brief poll_for_mii_idle Query the status of an ongoing DMA transfer * @@ -3721,6 +3767,8 @@ static struct osi_core_ops eqos_core_ops = { .read_mmc = eqos_read_mmc, .reset_mmc = eqos_reset_mmc, .configure_eee = eqos_configure_eee, + .save_registers = eqos_save_registers, + .restore_registers = eqos_restore_registers, .write_phy_reg = eqos_write_phy_reg, .read_phy_reg = eqos_read_phy_reg, }; diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 3e10492..8449086 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -603,5 +603,15 @@ struct core_func_safety { */ #define EQOS_MAX_BAK_IDX ((EQOS_PAD_AUTO_CAL_CFG_BAK_IDX + 1U)) +/** + * @brief core_backup - Struct used to store backup of core HW registers. + */ +struct core_backup { + /** Array of reg MMIO addresses (base of EQoS + offset of reg) */ + void *reg_addr[EQOS_MAX_BAK_IDX]; + /** Array of value stored in each corresponding register */ + unsigned int reg_val[EQOS_MAX_BAK_IDX]; +}; + /** @} */ #endif diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index a3885ab..9c7cdab 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -845,8 +845,8 @@ int osi_configure_eee(struct osi_core_priv_data *const osi_core, int osi_save_registers(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->backup_config != OSI_NULL)) { - mac_save_registers(osi_core->backup_config); + (osi_core->ops->save_registers != OSI_NULL)) { + osi_core->ops->save_registers(osi_core); return 0; } @@ -856,8 +856,8 @@ int osi_save_registers(struct osi_core_priv_data *const osi_core) int osi_restore_registers(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->backup_config != OSI_NULL)) { - mac_restore_registers(osi_core->backup_config); + (osi_core->ops->restore_registers != OSI_NULL)) { + osi_core->ops->restore_registers(osi_core); return 0; } From 632888fbad47cf55131d2641bf493e4e06efa660 Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Tue, 17 Mar 2020 12:47:31 +0530 Subject: [PATCH 085/458] nvethernetrm: Remove core_backup static variable - Define core_backup structure in osi_core file and convert osi_core_private_data structure backup_config variable as core_backup type. - Remove the global eqos_core_backup_config static variable. Bug 200596517 Change-Id: Ice38e1a8724c1da722eda7eb4e63e79674b27b0d Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2315795 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_core.h | 22 +++++++++++++++++++--- osi/core/eqos_core.c | 33 ++++++++++++--------------------- osi/core/eqos_core.h | 10 ---------- osi/core/osi_core.c | 9 ++++----- 4 files changed, 35 insertions(+), 39 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index b15fbf5..17ad599 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -260,9 +260,9 @@ struct osi_core_ops { const unsigned int tx_lpi_enabled, const unsigned int tx_lpi_timer); /** Called to save MAC register space during SoC suspend */ - void (*save_registers)(struct osi_core_priv_data *const osi_core); + int (*save_registers)(struct osi_core_priv_data *const osi_core); /** Called to restore MAC control registers during SoC resume */ - void (*restore_registers)(struct osi_core_priv_data *const osi_core); + int (*restore_registers)(struct osi_core_priv_data *const osi_core); /** Called to write into a PHY reg over MDIO bus */ int (*write_phy_reg)(struct osi_core_priv_data *const osi_core, const unsigned int phyaddr, @@ -321,6 +321,22 @@ struct osi_ptp_config { unsigned int ptp_clock; }; +/** + * @brief Max num of MAC core registers to backup. It should be max of or >= + * (EQOS_MAX_BAK_IDX=380, MGBE_MAX_BAK_IDX, 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 */ + unsigned int reg_val[CORE_MAX_BAK_IDX]; +}; + /** * @brief The OSI Core (MAC & MTL) private data structure. */ @@ -367,7 +383,7 @@ struct osi_core_priv_data { * certain safety critical registers */ void *safety_config; /** Backup config to save/restore registers during suspend/resume */ - void *backup_config; + struct core_backup backup_config; /** VLAN tag stripping enable(1) or disable(0) */ unsigned int strip_vlan_tag; /** L3L4 filter bit bask, set index corresponding bit for diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index addb13c..c6fcc46 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -31,11 +31,6 @@ */ static struct core_func_safety eqos_core_safety_config; -/** - * @brief eqos_core_backup_config - EQOS MAC core registers backup config - */ -static struct core_backup eqos_core_backup_config; - /** * @brief eqos_core_safety_writel - Write to safety critical register. * @@ -179,7 +174,7 @@ static void eqos_core_safety_init(struct osi_core_priv_data *const osi_core) /** - * @brief Initialize the eqos_core_backup_config. + * @brief Initialize the OSI core private data backup config array * * Algorithm: Populate the list of core registers to be saved during suspend. * Fill the address of each register in structure. @@ -190,7 +185,7 @@ static void eqos_core_safety_init(struct osi_core_priv_data *const osi_core) */ static void eqos_core_backup_init(struct osi_core_priv_data *const osi_core) { - struct core_backup *config = &eqos_core_backup_config; + struct core_backup *config = &osi_core->backup_config; unsigned char *base = (unsigned char *)osi_core->base; unsigned int i; @@ -3486,19 +3481,21 @@ static void eqos_configure_eee( * * @param[in] osi_core: OSI core private data structure. * - * @retval none + * @retval 0 on Success */ -static inline void eqos_save_registers( +static inline int eqos_save_registers( struct osi_core_priv_data *const osi_core) { unsigned int i; - struct core_backup *config = osi_core->backup_config; + 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_readl(config->reg_addr[i]); } } + + return 0; } /** @@ -3509,19 +3506,21 @@ static inline void eqos_save_registers( * * @param[in] osi_core: OSI core private data structure. * - * @retval none + * @retval 0 on Success */ -static inline void eqos_restore_registers( +static inline int eqos_restore_registers( struct osi_core_priv_data *const osi_core) { unsigned int i; - struct core_backup *config = osi_core->backup_config; + 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_writel(config->reg_val[i], config->reg_addr[i]); } } + + return 0; } /** @@ -3773,14 +3772,6 @@ static struct osi_core_ops eqos_core_ops = { .read_phy_reg = eqos_read_phy_reg, }; -/** - * @brief eqos_get_core_backup_config - EQOS MAC backup configuration - */ -void *eqos_get_core_backup_config(void) -{ - return &eqos_core_backup_config; -} - /** * @brief eqos_get_core_safety_config - EQOS MAC safety configuration */ diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 8449086..3e10492 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -603,15 +603,5 @@ struct core_func_safety { */ #define EQOS_MAX_BAK_IDX ((EQOS_PAD_AUTO_CAL_CFG_BAK_IDX + 1U)) -/** - * @brief core_backup - Struct used to store backup of core HW registers. - */ -struct core_backup { - /** Array of reg MMIO addresses (base of EQoS + offset of reg) */ - void *reg_addr[EQOS_MAX_BAK_IDX]; - /** Array of value stored in each corresponding register */ - unsigned int reg_val[EQOS_MAX_BAK_IDX]; -}; - /** @} */ #endif diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 9c7cdab..2429c7e 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -57,7 +57,6 @@ int osi_init_core_ops(struct osi_core_priv_data *const osi_core) * like periodic read-verify. */ osi_core->safety_config = (void *)eqos_get_core_safety_config(); - osi_core->backup_config = (void *)eqos_get_core_backup_config(); return 0; } @@ -846,8 +845,8 @@ int osi_save_registers(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->save_registers != OSI_NULL)) { - osi_core->ops->save_registers(osi_core); - return 0; + /* Call MAC save registers callback and return the value */ + return osi_core->ops->save_registers(osi_core); } return -1; @@ -857,8 +856,8 @@ int osi_restore_registers(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->restore_registers != OSI_NULL)) { - osi_core->ops->restore_registers(osi_core); - return 0; + /* Call MAC restore registers callback and return the value */ + return osi_core->ops->restore_registers(osi_core); } return -1; From 774fcfd2e54aa4c77b777ef4042752b03c0348c0 Mon Sep 17 00:00:00 2001 From: Praveen Mallaiah <pmallaiah@nvidia.com> Date: Tue, 24 Mar 2020 09:56:44 +0530 Subject: [PATCH 086/458] nvethernet: updated osd function documentation Updated osd_transmit_complete, osd_receive_packet algorithm documentation Bug 200574645 Bug 2855341 Bug 200598869 Change-Id: I1ab0f21cc39b39bf755b4ea19703b2875279c77a Signed-off-by: Praveen Mallaiah <pmallaiah@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2320522 (cherry picked from commit 50490d3bfc12089a3e1ee2d82d9c6729b9b5d853) Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2317409 Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: Sandeep Trasi <strasi@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osd.h | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/include/osd.h b/include/osd.h index b5574fe..9543f67 100644 --- a/include/osd.h +++ b/include/osd.h @@ -46,16 +46,9 @@ void osd_udelay(unsigned long usec); * @brief osd_receive_packet - Handover received packet to network stack. * * Algorithm: - * 1) Unmap the DMA buffer address. - * 2) Updates socket buffer with len and ether type and handover to - * OS network stack. - * 3) Refill the Rx ring based on threshold. - * 4) Fills the rxpkt_cx->flags with the below bit fields accordingly - * OSI_PKT_CX_VLAN - * OSI_PKT_CX_VALID - * OSI_PKT_CX_CSUM - * OSI_PKT_CX_TSO - * OSI_PKT_CX_PTP + * 1) Unmap the DMA buffer address (not needed if buffers are allocated statically). + * 2) Refill the Rx ring based on threshold. + * 3) Consume the flag information and take decision to hand over the packet and related information to OS network stack. * * @param[in] priv: OSD private data structure. * @param[in] rxring: Pointer to DMA channel Rx ring. @@ -74,9 +67,8 @@ void osd_receive_packet(void *priv, void *rxring, unsigned int chan, * @brief osd_transmit_complete - Transmit completion routine. * * Algorithm: - * 1) Updates stats for Linux network stack. - * 2) unmap and free the buffer DMA address and buffer. - * 3) Time stamp will be updated to stack if available. + * 1) Unmap and free the buffer DMA address and buffer (not needed if buffers are allocated statically). + * 2) Time stamp will be updated to stack if available. * * @param[in] priv: OSD private data structure. * @param[in] buffer: Buffer address to free. From 6eed8c0ee625554c2066ef495e76d74ddbb06d21 Mon Sep 17 00:00:00 2001 From: narayanr <narayanr@nvidia.com> Date: Mon, 6 Apr 2020 15:17:18 +0530 Subject: [PATCH 087/458] nvethernetrm: eqos: Fix GPSLCE programming Issue: By default GPSLCE is enabled for default MTU size and hence SW is receiving bigger packets greater than the current MTU size. Fix: Limit GPSLCE only to mtu size greater than 9000 Bug 2897105 Change-Id: Ica3a495b8a931a88d03f00625e71b69cc6704d6b Signed-off-by: narayanr <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2324369 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/eqos_core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index c6fcc46..15dc40c 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1338,7 +1338,7 @@ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) /* if MTU less than or equal to 9K use JE */ value |= EQOS_MCR_JE; value |= EQOS_MCR_JD; - } else { + } 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; @@ -1351,6 +1351,8 @@ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) /* Write MAC Extenstion Register */ osi_writel(mac_ext, (unsigned char *)osi_core->base + EQOS_MAC_EXTR); + } else { + /* do nothing for default mtu size */ } eqos_core_safety_writel(value, (unsigned char *)osi_core->base + From c3b97632e459a6f97a1326d2f0d09d5bc8678ac2 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Mon, 6 Apr 2020 14:14:34 +0530 Subject: [PATCH 088/458] nvethernetrm: fix descriptor err stats update Issue: Packets stats not updated since osi_pkt_err_stats variable passed by value. Fix: Pass osi_pkt_err_stats variable as reference so that stats updated in called function will be updated. Change-Id: I23f71ebc0dc463a925b2b576285a5558aa6da815 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2324335 Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/dma/osi_dma_txrx.c | 56 +++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index bd09416..b93320d 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -179,21 +179,21 @@ static int get_rx_hwstamp(struct osi_rx_desc *rx_desc, * @param[in] 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) + 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 = + pkt_err_stats->rx_crc_error = osi_update_stats_counter( - pkt_err_stats.rx_crc_error, + 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 = + pkt_err_stats->rx_frame_error = osi_update_stats_counter( - pkt_err_stats.rx_frame_error, + pkt_err_stats->rx_frame_error, 1UL); } } @@ -256,7 +256,7 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, * are set */ rx_pkt_cx->flags &= ~OSI_PKT_CX_VALID; - get_rx_err_stats(rx_desc, osi->pkt_err_stats); + get_rx_err_stats(rx_desc, &osi->pkt_err_stats); } /* Check if COE Rx checksum is valid */ @@ -324,85 +324,85 @@ static inline void inc_tx_pkt_stats(struct osi_dma_priv_data *osi, * @param[in] pkt_err_stats: Pakcet 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) + 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 = + pkt_err_stats->ip_header_error = osi_update_stats_counter( - pkt_err_stats.ip_header_error, + 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 = + pkt_err_stats->jabber_timeout_error = osi_update_stats_counter( - pkt_err_stats.jabber_timeout_error, + 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 = + pkt_err_stats->pkt_flush_error = osi_update_stats_counter( - pkt_err_stats.pkt_flush_error, 1UL); + 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 = + pkt_err_stats->payload_cs_error = osi_update_stats_counter( - pkt_err_stats.payload_cs_error, 1UL); + 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 = + pkt_err_stats->loss_of_carrier_error = osi_update_stats_counter( - pkt_err_stats.loss_of_carrier_error, + 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 = + pkt_err_stats->no_carrier_error = osi_update_stats_counter( - pkt_err_stats.no_carrier_error, 1UL); + 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 = + pkt_err_stats->late_collision_error = osi_update_stats_counter( - pkt_err_stats.late_collision_error, + pkt_err_stats->late_collision_error, 1UL); } /* Execessive Collision Error */ if ((tx_desc->tdes3 & TDES3_EXCESSIVE_COL_ERR) == TDES3_EXCESSIVE_COL_ERR) { - pkt_err_stats.excessive_collision_error = + pkt_err_stats->excessive_collision_error = osi_update_stats_counter( - pkt_err_stats.excessive_collision_error, + 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 = + pkt_err_stats->excessive_deferal_error = osi_update_stats_counter( - pkt_err_stats.excessive_deferal_error, + 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, + pkt_err_stats->underflow_error = + osi_update_stats_counter(pkt_err_stats->underflow_error, 1UL); } } @@ -483,7 +483,7 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi, if ((tx_desc->tdes3 & TDES3_ES_BITS) != 0U) { txdone_pkt_cx->flags |= OSI_TXDONE_CX_ERROR; /* fill packet error stats */ - get_tx_err_stats(tx_desc, osi->pkt_err_stats); + get_tx_err_stats(tx_desc, &osi->pkt_err_stats); } else { inc_tx_pkt_stats(osi, chan); } From 4efa1ebe0ba36fed772b70ddca55a6df49ea97c0 Mon Sep 17 00:00:00 2001 From: rakesh goyal <rgoyal@nvidia.com> Date: Thu, 26 Mar 2020 11:14:39 +0530 Subject: [PATCH 089/458] nvethernetrm: add osi_likely() and osi_unlikely() Adding osi_unlikely and osi_likely using compiler built-in macros which give compiler hints for branch prediction. Bug 200599872 Change-Id: I64be9a53285bdc11015a2efb565e2addac531c5c Signed-off-by: rakesh goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2318771 Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_common.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/osi_common.h b/include/osi_common.h index 046889b..2d786c1 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -45,6 +45,10 @@ #define OSI_MAX_TX_COALESCE_USEC 1020U #define OSI_MIN_TX_COALESCE_USEC 32U #define OSI_MIN_TX_COALESCE_FRAMES 1U + +/* Compiler hints for branch prediction */ +#define osi_likely(x) __builtin_expect(!!(x), 1) +#define osi_unlikely(x) __builtin_expect(!!(x), 0) /** @} */ /** From 94a0f45cf04890aa1c65eff91dc28712b43d8692 Mon Sep 17 00:00:00 2001 From: nannaiah <nannaiah@nvidia.com> Date: Thu, 16 Apr 2020 15:40:37 -0700 Subject: [PATCH 090/458] nvethernetrm: Add flag for virtualization & stats Issue: When virtualization is enabled and registers are accessed during UDP line rate transfer or receive then spurious common interrupts gets generated for buffer unavailable which hangs the ethernet server. Fix: 1. Add Flag which decides virtualization is enabled(1) or disabled(0) 2. If virtualization is enabled then disable receive and transmit buffer Unavailable interrupts. Bug 2694285 Change-Id: I2c65b724c15abf5d4f0101d96b067ad9f4f3d99e Signed-off-by: Nagaraj Annaiah <nannaiah@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2330034 Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_dma.h | 2 ++ osi/dma/eqos_dma.c | 9 ++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/include/osi_dma.h b/include/osi_dma.h index efc9726..e6e1667 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -389,6 +389,8 @@ struct osi_dma_priv_data { unsigned int tx_frames; /** Flag which decides tx_frames is enabled(1) or disabled(0) */ unsigned int use_tx_frames; + /** Flag which decides virtualization is enabled(1) or disabled(0) */ + unsigned int use_virtualization; /** Functional safety config to do periodic read-verify of * certain safety critical dma registers */ void *safety_config; diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index b7cc345..5abd4ba 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -611,11 +611,14 @@ static void eqos_configure_dma_channel(unsigned int chan, /* FBE - Fatal Bus Error Enable */ value = osi_readl((unsigned char *)osi_dma->base + EQOS_DMA_CHX_INTR_ENA(chan)); - value |= EQOS_DMA_CHX_INTR_TIE | EQOS_DMA_CHX_INTR_TBUE | - EQOS_DMA_CHX_INTR_RIE | EQOS_DMA_CHX_INTR_RBUE | + if (!osi_dma->use_virtualization) { + 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(value, (unsigned char *)osi_dma->base + From c5e5760fc1abd8d4721c3cd7693448a52f79cd1a Mon Sep 17 00:00:00 2001 From: Nagarjuna Kristam <nkristam@nvidia.com> Date: Mon, 13 Apr 2020 10:03:05 +0530 Subject: [PATCH 091/458] osi: dma: Clear TX SWCX during DMA init Issue: In QNX, DMA ring params are initialized during interface only. When interface is is stop and re-inited, DMA ring params are not re-allocated but re-used again. During this process, TX software context is not cleared. This results in presense of any stale value, that causes failure. Fix info: Clean TX software context during DMA init. Bug 200603660 Change-Id: I96c967a676c7fcdeb22b0a235301dee9d1d2b4c7 Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2327716 Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Gaurav Asati <gasati@nvidia.com> Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/dma/osi_dma_txrx.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index b93320d..67a1a6c 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -926,6 +926,7 @@ static void tx_dma_desc_init(struct osi_dma_priv_data *osi_dma) { struct osi_tx_ring *tx_ring = OSI_NULL; struct osi_tx_desc *tx_desc = OSI_NULL; + struct osi_tx_swcx *tx_swcx = OSI_NULL; struct osi_dma_chan_ops *ops = osi_dma->ops; unsigned int chan = 0; unsigned int i, j; @@ -936,11 +937,17 @@ static void tx_dma_desc_init(struct osi_dma_priv_data *osi_dma) for (j = 0; j < TX_DESC_CNT; 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->is_paged_buf = 0; } tx_ring->cur_tx_idx = 0; From 54c279c48e35c3d52e33fc6a3328989317f7544b Mon Sep 17 00:00:00 2001 From: Nagarjuna Kristam <nkristam@nvidia.com> Date: Mon, 13 Apr 2020 10:28:16 +0530 Subject: [PATCH 092/458] osi: dma: Add TX SWCX flags for payload length Issue: In QNX OS, IP packets are split and sent to ethernet driver. This requires packet length update needed in DMA descriptor. Fix info: Add a TX SWCX flag to update payload length to DMA descriptor. Bug 200603660 Change-Id: I3a6a2fb96d645d6ccf5c0e616ded220ed7742bc9 Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2323286 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_dma.h | 6 +++++- include/osi_dma_txrx.h | 1 + osi/dma/osi_dma_txrx.c | 9 +++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/include/osi_dma.h b/include/osi_dma.h index e6e1667..297c30d 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -36,7 +36,8 @@ * whether a received packet is valid, * whether 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 the HW should timestamp transmit/arrival of a packet respectively, + * whether tx payload length to be updated * @{ */ /** VLAN packet */ @@ -49,6 +50,9 @@ #define OSI_PKT_CX_TSO OSI_BIT(2) /** PTP packet */ #define OSI_PKT_CX_PTP OSI_BIT(3) +/** Update Packet Length in Tx Desc3 */ +#define OSI_PKT_CX_LEN OSI_BIT(11) + /** @} */ /** diff --git a/include/osi_dma_txrx.h b/include/osi_dma_txrx.h index 4eabb09..908ed27 100644 --- a/include/osi_dma_txrx.h +++ b/include/osi_dma_txrx.h @@ -112,6 +112,7 @@ #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) diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 67a1a6c..5774e26 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -647,6 +647,14 @@ static inline void fill_first_desc(struct osi_tx_ring *tx_ring, 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) { + /* Remove any overflow bits. PL field is 15 bit wide */ + tx_pkt_cx->payload_len &= ~TDES3_PL_MASK; + /* 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; @@ -664,6 +672,7 @@ static inline void fill_first_desc(struct osi_tx_ring *tx_ring, /* Remove any overflow bits. TPL field is 18 bit wide */ tx_pkt_cx->payload_len &= TDES3_TPL_MASK; /* 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) && From c7706f984681e8fec9f5d0043d75e73847743780 Mon Sep 17 00:00:00 2001 From: Nagarjuna Kristam <nkristam@nvidia.com> Date: Mon, 13 Apr 2020 10:29:49 +0530 Subject: [PATCH 093/458] osi: dma: Add TX SWCX flags for IP checksum Issue: In QNX OS, some data packets needs only IP checksum to be enabled. Fix info: Add a TX SWCX flag to update IP checksum bit to DMA descriptor. Bug 200603660 Change-Id: I1dd6b0a0a4e8da7af548fd7640912fc3248c4da5 Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2327717 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_dma.h | 3 +++ include/osi_dma_txrx.h | 3 ++- osi/dma/osi_dma_txrx.c | 6 +++++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/include/osi_dma.h b/include/osi_dma.h index 297c30d..e957c7c 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -35,6 +35,7 @@ * 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 tx payload length to be updated @@ -46,6 +47,8 @@ #define OSI_PKT_CX_VALID OSI_BIT(10) /** CSUM packet */ #define OSI_PKT_CX_CSUM OSI_BIT(1) +/** IP CSUM packet */ +#define OSI_PKT_CX_IP_CSUM OSI_BIT(12) /** TSO packet */ #define OSI_PKT_CX_TSO OSI_BIT(2) /** PTP packet */ diff --git a/include/osi_dma_txrx.h b/include/osi_dma_txrx.h index 908ed27..2bbc61f 100644 --- a/include/osi_dma_txrx.h +++ b/include/osi_dma_txrx.h @@ -108,7 +108,8 @@ #define TDES3_FD OSI_BIT(29) #define TDES3_LD OSI_BIT(28) #define TDES3_TSE OSI_BIT(18) -#define TDES3_HW_CIC (OSI_BIT(16) | OSI_BIT(17)) +#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 diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 5774e26..c7329eb 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -634,7 +634,11 @@ static inline void fill_first_desc(struct osi_tx_ring *tx_ring, /* 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; + 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 */ From 6605b6e76f29a3ea4ee3ca56b000397048f44456 Mon Sep 17 00:00:00 2001 From: Nagarjuna Kristam <nkristam@nvidia.com> Date: Wed, 22 Apr 2020 14:34:33 +0530 Subject: [PATCH 094/458] osi: dma: Add flags for rx checksum. Issue: - Current values for checksum flags are too generic for QNX requirements. Fix: - Add specific flags for TCP/UDP, IP v4/v6 - Update value for OSI_CHECKSUM_UNNECESSARY to use it as a flag instead of value. Bug 200610815 Change-Id: I7ce266594cb5bb5b1bd86ff9ab28a89d778146c1 Signed-off-by: Gaurav Asati <gasati@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2331560 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_dma.h | 17 +++++++++++++- include/osi_dma_txrx.h | 4 ++++ osi/dma/osi_dma_txrx.c | 51 +++++++++++++++++++++++++++++++++++------- 3 files changed, 63 insertions(+), 9 deletions(-) diff --git a/include/osi_dma.h b/include/osi_dma.h index e957c7c..6b7f78f 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -100,7 +100,22 @@ */ /* Checksum offload result flags */ #define OSI_CHECKSUM_NONE 0x0U -#define OSI_CHECKSUM_UNNECESSARY 0x1U +/* 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) /** @} */ /** diff --git a/include/osi_dma_txrx.h b/include/osi_dma_txrx.h index 2bbc61f..bac82f0 100644 --- a/include/osi_dma_txrx.h +++ b/include/osi_dma_txrx.h @@ -84,7 +84,11 @@ #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_TCP OSI_BIT(1) +#define RDES1_PT_UDP OSI_BIT(0) /** @} */ /** Error Summary bits for Received packet */ diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index c7329eb..fab43c7 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -41,16 +41,51 @@ static inline void get_rx_csum(struct osi_rx_desc *rx_desc, struct osi_rx_pkt_cx *rx_pkt_cx) { - /* Always include either checksum none/unnecessary - * depending on status fields in desc. - * Hence no need to explicitly add OSI_PKT_CX_CSUM flag. + /* 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) { - /* Check if no checksum errors reported in status */ - if ((rx_desc->rdes1 & - (RDES1_IPCE | RDES1_IPCB | RDES1_IPHE)) == 0U) { - rx_pkt_cx->rxcsum |= OSI_CHECKSUM_UNNECESSARY; + 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; + } + + if ((rx_desc->rdes1 & RDES1_PT_UDP) == RDES1_PT_UDP) { + if ((rx_desc->rdes1 & RDES1_IPV4) == RDES1_IPV4) { + rx_pkt_cx->rxcsum |= OSI_CHECKSUM_UDPv4; + } else if ((rx_desc->rdes1 & RDES1_IPV6) == RDES1_IPV6) { + rx_pkt_cx->rxcsum |= OSI_CHECKSUM_UDPv6; + } else { + /* Do nothing here */ } + } else if ((rx_desc->rdes1 & RDES1_PT_TCP) == RDES1_PT_TCP) { + if ((rx_desc->rdes1 & RDES1_IPV4) == RDES1_IPV4) { + rx_pkt_cx->rxcsum |= OSI_CHECKSUM_TCPv4; + } else if ((rx_desc->rdes1 & RDES1_IPV6) == RDES1_IPV6) { + rx_pkt_cx->rxcsum |= OSI_CHECKSUM_TCPv6; + } else { + /* Do nothing here */ + } + } else { + /* Do nothing here */ + } + + if ((rx_desc->rdes1 & RDES1_IPCE) == RDES1_IPCE) { + rx_pkt_cx->rxcsum |= OSI_CHECKSUM_TCP_UDP_BAD; } } From 65f54fb5decc9e4d8902033671d5d708222dea5e Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Fri, 27 Dec 2019 19:49:32 +0530 Subject: [PATCH 095/458] nvethernetrm: eqos: add Software reset for VDK Bug 200546379 Change-Id: I40cf003311926e6b0a1685c0443d64ccf59c5325 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2270371 Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2274311 Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_core.h | 4 +++- osi/core/eqos_core.c | 6 +++++- osi/core/osi_core.c | 3 ++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 17ad599..79ac7d3 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -134,7 +134,7 @@ struct osi_core_avb_algorithm { */ struct osi_core_ops { /** Called to poll for software reset bit */ - int (*poll_for_swr)(void *ioaddr); + int (*poll_for_swr)(void *ioaddr, unsigned int pre_si); /** Called to initialize MAC and MTL registers */ int (*core_init)(struct osi_core_priv_data *const osi_core, const unsigned int tx_fifo_size, @@ -393,6 +393,8 @@ struct osi_core_priv_data { * Value stored in MHz */ unsigned int csr_clk_speed; + /** Tegra Pre-si platform info */ + unsigned int pre_si; }; /** diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 15dc40c..9998480 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -634,19 +634,23 @@ static int eqos_config_mac_loopback(void *addr, * Waits for SWR reset to be cleared in DMA Mode register. * * @param[in] addr: EQOS virtual base address. + * @param[in] pre_si: Sets whether platform is Pre-silicon or not. * * @note MAC needs to be out of reset and proper clock configured. * * @retval 0 on success * @retval -1 on failure. */ -static int eqos_poll_for_swr(void *addr) +static int eqos_poll_for_swr(void *addr, unsigned int pre_si) { unsigned int retry = 1000; unsigned int count; unsigned int dma_bmr = 0; int cond = 1; + if (pre_si == OSI_ENABLE) { + osi_writel(0x1U, (unsigned char *)addr + EQOS_DMA_BMR); + } /* add delay of 10 usec */ osd_usleep_range(9, 11); diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 2429c7e..d3f020d 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -68,7 +68,8 @@ int osi_poll_for_mac_reset_complete( { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->poll_for_swr != OSI_NULL)) { - return osi_core->ops->poll_for_swr(osi_core->base); + return osi_core->ops->poll_for_swr(osi_core->base, + osi_core->pre_si); } return -1; } From e9caa9fdad979468033f4304905a585f7b9dba60 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Wed, 26 Jun 2019 20:23:44 +0530 Subject: [PATCH 096/458] nvethernetrm: add support for EQOS VM interrupts Adds VM IRQ handling support at OSI layer and adds corresponding support for EQOS as well. Need to pass below parameters from DT - o Number of VM IRQ's assigned per OS/VM. o Number of VM channels assigned to a VM IRQ. o List of DMA channels assigned to a VM IRQ. Below is the sample DT representation - vm_irq_config: vm-irq-config { nvidia,num-vm-irqs = <4>; vm_irq1 { nvidia,num-vm-channels = <2>; nvidia,vm-channels = <0 1>; }; vm_irq2 { nvidia,num-vm-channels = <2>; nvidia,vm-channels = <2 3>; }; vm_irq3 { nvidia,num-vm-channels = <2>; nvidia,vm-channels = <4 5>; }; vm_irq4 { nvidia,num-vm-channels = <2>; nvidia,vm-channels = <6 7>; }; }; ethernet@<base_addr> { [...] nvidia,vm-irq-config = <&vm_irq_config>; [...] } Bug 200546379 Change-Id: Id20780d573aa70baf42b003728ba416ed61832d2 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2250403 Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2198595 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_common.h | 5 ++- include/osi_dma.h | 75 ++++++++++++++++++++++++++++++- osi/core/eqos_core.c | 9 +++- osi/core/eqos_core.h | 20 ++++++--- osi/dma/eqos_dma.c | 102 ++++++++++++++++++++++++++++++++++++++++++- osi/dma/eqos_dma.h | 44 ++++++++++--------- osi/dma/osi_dma.c | 34 +++++++++++++++ 7 files changed, 257 insertions(+), 32 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index 2d786c1..1667263 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -212,8 +212,8 @@ #define EQOS_MAX_MAC_ADDRESS_FILTER 128U #define EQOS_MAX_L3_L4_FILTER 8U #define EQOS_MAX_HTR_REGS 8U -#define OSI_EQOS_MAX_NUM_CHANS 4U -#define OSI_EQOS_MAX_NUM_QUEUES 4U +#define OSI_EQOS_MAX_NUM_CHANS 8U +#define OSI_EQOS_MAX_NUM_QUEUES 8U #define OSI_L2_FILTER_INDEX_ANY 127U #define OSI_CHAN_ANY 0xFFU @@ -238,6 +238,7 @@ #define OSI_MAC_HW_EQOS 0U #define OSI_ETH_ALEN 6U +#define OSI_MAX_VM_IRQS 5U #define BOOLEAN_FALSE (0U != 0U) #define OSI_NULL ((void *)0) diff --git a/include/osi_dma.h b/include/osi_dma.h index 6b7f78f..b4ddce7 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -320,7 +320,7 @@ struct osi_tx_ring { struct osi_dma_priv_data; /** - *@brief MAC DMA Channel operations + * @brief MAC DMA Channel operations */ struct osi_dma_chan_ops { /** Called to set Transmit Ring length */ @@ -365,6 +365,22 @@ struct osi_dma_chan_ops { unsigned int chan, unsigned int set, unsigned int interval); + /** Called to get Global DMA status */ + unsigned int (*get_global_dma_status)(void *addr); + /** Called to clear VM Tx interrupt */ + void (*clear_vm_tx_intr)(void *addr, unsigned int chan); + /** Called to clear VM Rx interrupt */ + void (*clear_vm_rx_intr)(void *addr, unsigned int chan); +}; + +/** + * @brief OSI VM IRQ data + */ +struct osi_vm_irq_data { + /** Number of VM channels per VM IRQ */ + unsigned int num_vm_chans; + /** Array of VM channel list */ + unsigned int vm_chans[OSI_EQOS_MAX_NUM_CHANS]; }; /** @@ -420,6 +436,10 @@ struct osi_dma_priv_data { unsigned int slot_interval[OSI_EQOS_MAX_NUM_CHANS]; /** Array of DMA channel slot enabled status from DT*/ unsigned int slot_enabled[OSI_EQOS_MAX_NUM_CHANS]; + /** number of VM IRQ's */ + unsigned int num_vm_irqs; + /** Array of VM IRQ's */ + struct osi_vm_irq_data irq_data[OSI_MAX_VM_IRQS]; }; /** @@ -522,6 +542,44 @@ int osi_disable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, int osi_enable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, unsigned int chan); +/** + * @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. + */ +int osi_clear_vm_tx_intr(struct osi_dma_priv_data *osi_dma, + unsigned int 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. + */ +int osi_clear_vm_rx_intr(struct osi_dma_priv_data *osi_dma, + unsigned int chan); + /** * @brief Start DMA * @@ -817,4 +875,19 @@ int osi_clear_rx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); * @retval 0 if ring has outstanding packets. */ int osi_txring_empty(struct osi_dma_priv_data *osi_dma, unsigned int chan); + +/** + * @brief osi_get_global_dma_status - Gets DMA status. + * + * Algorithm: Returns global DMA Tx/Rx interrupt status + * + * @param[in] osi_dma: OSI DMA private data structure. + * + * @note + * Dependencies: None. + * Protection: None. + * + * @retval status + */ +unsigned int osi_get_global_dma_status(struct osi_dma_priv_data *osi_dma); #endif /* OSI_DMA_H */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 9998480..97e5288 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1511,10 +1511,17 @@ static int eqos_core_init(struct osi_core_priv_data *const osi_core, osi_writel(EQOS_MMC_CNTRL_CNTRST, (unsigned char *)osi_core->base + EQOS_MMC_CNTRL); - /* AXI ASID CTRL */ + /* AXI ASID CTRL for channel 0 to 3 */ osi_writel(EQOS_AXI_ASID_CTRL_VAL, (unsigned char *)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_writel(EQOS_AXI_ASID1_CTRL_VAL, + (unsigned char *)osi_core->base + + EQOS_AXI_ASID1_CTRL); + } + /* Mapping MTL Rx queue and DMA Rx channel */ /* TODO: Need to add EQOS_MTL_RXQ_DMA_MAP1 for EQOS */ value = osi_readl((unsigned char *)osi_core->base + diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 3e10492..168db02 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -165,6 +165,7 @@ */ #define EQOS_CLOCK_CTRL_0 0x8000U #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 @@ -393,18 +394,25 @@ #define EQOS_DMA_CHX_STATUS_RWT OSI_BIT(9) #define EQOS_DMA_CHX_STATUS_FBE OSI_BIT(10) -#define EQOS_AXI_ASID_CTRL_CH3_SHIFT 24 -#define EQOS_AXI_ASID_CTRL_CH2_SHIFT 16 -#define EQOS_AXI_ASID_CTRL_CH1_SHIFT 8 +#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 (unsigned int)20 -#define TEGRA_SID_EQOS_CH3 ((TEGRA_SID_EQOS) << EQOS_AXI_ASID_CTRL_CH3_SHIFT) -#define TEGRA_SID_EQOS_CH2 ((TEGRA_SID_EQOS) << EQOS_AXI_ASID_CTRL_CH2_SHIFT) -#define TEGRA_SID_EQOS_CH1 ((TEGRA_SID_EQOS) << EQOS_AXI_ASID_CTRL_CH1_SHIFT) +#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)) /** @} */ void update_ehfc_rfa_rfd(unsigned int rx_fifo, unsigned int *value); diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index 5abd4ba..5828646 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -689,6 +689,40 @@ static void eqos_configure_dma_channel(unsigned int chan, } } +/** + * @brief eqos_dma_chan_to_vmirq_map - Map DMA channels to a specific VM IRQ. + * + * @param[in] osi_dma: OSI private data structure. + * + * Algorithm: Programs HW to map DMA channels to specific VM. + * + * @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_dma_priv_data *osi_dma) +{ + struct osi_vm_irq_data *irq_data; + unsigned int i, j; + unsigned int chan; + + for (i = 0; i < osi_dma->num_vm_irqs; i++) { + irq_data = &osi_dma->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(i), + (unsigned char *)osi_dma->base + + EQOS_VIRT_INTR_APB_CHX_CNTRL(chan)); + } + } +} + /** * @brief eqos_init_dma_channel - DMA channel INIT * @@ -704,6 +738,8 @@ static void eqos_init_dma_channel(struct osi_dma_priv_data *osi_dma) for (chinx = 0; chinx < osi_dma->num_dma_chans; chinx++) { eqos_configure_dma_channel(osi_dma->dma_chans[chinx], osi_dma); } + + eqos_dma_chan_to_vmirq_map(osi_dma); } /** @@ -732,9 +768,70 @@ static void eqos_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) } /** - * @brief eqos_dma_chan_ops - EQOS DMA operations + * @brief eqos_get_global_dma_status - Gets DMA status. * + * Algorithm: Returns global DMA Tx/Rx interrupt status + * + * @param[in] addr: MAC base address. + * + * @note + * Dependencies: None. + * Protection: None. + * + * @retval status */ +static unsigned int eqos_get_global_dma_status(void *addr) +{ + return osi_readl((unsigned char *)addr + EQOS_GLOBAL_DMA_STATUS); +} + +/** + * @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, unsigned int chan) +{ + CHECK_CHAN_BOUND(chan); + + osi_writel(EQOS_DMA_CHX_STATUS_CLEAR_TX, + (unsigned char *)addr + EQOS_DMA_CHX_STATUS(chan)); + osi_writel(EQOS_VIRT_INTR_CHX_STATUS_TX, + (unsigned char *)addr + EQOS_VIRT_INTR_CHX_STATUS(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, unsigned int chan) +{ + CHECK_CHAN_BOUND(chan); + + osi_writel(EQOS_DMA_CHX_STATUS_CLEAR_RX, + (unsigned char *)addr + EQOS_DMA_CHX_STATUS(chan)); + osi_writel(EQOS_VIRT_INTR_CHX_STATUS_RX, + (unsigned char *)addr + EQOS_VIRT_INTR_CHX_STATUS(chan)); +} + static struct osi_dma_chan_ops eqos_dma_chan_ops = { .set_tx_ring_len = eqos_set_tx_ring_len, .set_rx_ring_len = eqos_set_rx_ring_len, @@ -752,6 +849,9 @@ static struct osi_dma_chan_ops eqos_dma_chan_ops = { .set_rx_buf_len = eqos_set_rx_buf_len, .validate_regs = eqos_validate_dma_regs, .config_slot = eqos_config_slot, + .get_global_dma_status = eqos_get_global_dma_status, + .clear_vm_tx_intr = eqos_clear_vm_tx_intr, + .clear_vm_rx_intr = eqos_clear_vm_rx_intr, }; /** diff --git a/osi/dma/eqos_dma.h b/osi/dma/eqos_dma.h index 3d8f50f..e528375 100644 --- a/osi/dma/eqos_dma.h +++ b/osi/dma/eqos_dma.h @@ -38,23 +38,25 @@ * @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) -#define EQOS_DMA_CHX_SLOT_CTRL(x) ((0x0080U * (x)) + 0x113CU) +#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) +#define EQOS_DMA_CHX_SLOT_CTRL(x) ((0x0080U * (x)) + 0x113CU) -#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_CHX_STATUS(x) (0x8604U + ((x) * 8U)) -#define EQOS_VIRT_INTR_CHX_CNTRL(x) (0x8600U + ((x) * 8U)) +#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)) +#define EQOS_GLOBAL_DMA_STATUS (0x8700U) /** @} */ /** @@ -63,11 +65,11 @@ * @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_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 \ diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index c66ca3a..4fea528 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -146,6 +146,40 @@ int osi_enable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, return -1; } +int osi_clear_vm_tx_intr(struct osi_dma_priv_data *osi_dma, + unsigned int chan) +{ + if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && + (osi_dma->ops->clear_vm_tx_intr != OSI_NULL)) { + osi_dma->ops->clear_vm_tx_intr(osi_dma->base, chan); + return 0; + } + + return -1; +} + +int osi_clear_vm_rx_intr(struct osi_dma_priv_data *osi_dma, + unsigned int chan) +{ + if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && + (osi_dma->ops->clear_vm_rx_intr != OSI_NULL)) { + osi_dma->ops->clear_vm_rx_intr(osi_dma->base, chan); + return 0; + } + + return -1; +} + +unsigned int osi_get_global_dma_status(struct osi_dma_priv_data *osi_dma) +{ + if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && + (osi_dma->ops->get_global_dma_status != OSI_NULL)) { + return osi_dma->ops->get_global_dma_status(osi_dma->base); + } + + return 0; +} + int osi_start_dma(struct osi_dma_priv_data *osi_dma, unsigned int chan) { From efd9a6032a87cbc294f2380e1576a015e88ebb31 Mon Sep 17 00:00:00 2001 From: Nagarjuna Kritam <nkristam@nvidia.com> Date: Thu, 23 Jan 2020 04:27:42 +0530 Subject: [PATCH 097/458] nvethernetrm: Use SSINC for SSIR and ADDEND calculations Use MAC version based SSINC value and use it to configure SSIR and addend registers. Bug 200605211 Change-Id: I8ac4e5fbfb9c64db35a3c33417dee5ca34a1c61d Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2341203 Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_core.h | 12 +++++++++++- osi/core/eqos_core.c | 23 +++++++++++++---------- osi/core/osi_core.c | 35 +++++++++++++++++++++++------------ 3 files changed, 47 insertions(+), 23 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 79ac7d3..ced7000 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -26,6 +26,16 @@ #include "osi_common.h" #include "mmc.h" +/** + * @addtogroup PTP related information + * + * @brief PTP SSINC values + * @{ + */ +#define OSI_PTP_SSINC_16 16U +#define OSI_PTP_SSINC_4 4U +/** @} */ + struct osi_core_priv_data; /** @@ -250,7 +260,7 @@ struct osi_core_ops { /** Called to configure the TimeStampControl register */ void (*config_tscr)(void *addr, const unsigned int ptp_filter); /** Called to configure the sub second increment register */ - void (*config_ssir)(void *addr, const unsigned int ptp_clock); + void (*config_ssir)(struct osi_core_priv_data *const osi_core); /** Called to update MMC counter from HW register */ void (*read_mmc)(struct osi_core_priv_data *const osi_core); /** Called to reset MMC HW counter structure */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 97e5288..9a26c71 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -3329,28 +3329,31 @@ static void eqos_config_tscr(void *addr, const unsigned int ptp_filter) /** * @brief eqos_config_ssir - Configure SSIR * - * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. - * @param[in] ptp_clock: PTP required clock frequency + * @param[in] osi_core: OSI core private data structure. * * @note MAC should be init and started. see osi_start_mac() */ -static void eqos_config_ssir(void *addr, const unsigned int ptp_clock) +static void eqos_config_ssir(struct osi_core_priv_data *const osi_core) { unsigned long long val; unsigned int mac_tcr; + void *addr = osi_core->base; + unsigned int ptp_clock = osi_core->ptp_config.ptp_clock; mac_tcr = osi_readl((unsigned char *)addr + EQOS_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 & EQOS_MAC_TCR_TSCFUPDT) == EQOS_MAC_TCR_TSCFUPDT) { - val = ((1U * OSI_NSEC_PER_SEC) / OSI_PTP_REQ_CLK_FREQ); + if (osi_core->mac_ver <= OSI_EQOS_MAC_4_10) { + val = OSI_PTP_SSINC_16; + } 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); } diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index d3f020d..b50c4f0 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -752,7 +752,8 @@ int osi_ptp_configuration(struct osi_core_priv_data *const osi_core, const unsigned int enable) { int ret = 0; - unsigned long temp = 0, temp1 = 0; + unsigned long temp = 0, temp1 = 0, temp2 = 0; + unsigned long ssinc = 0; if ((osi_core == OSI_NULL) || (osi_core->ops == OSI_NULL) || (osi_core->ops->config_tscr == OSI_NULL) || @@ -772,25 +773,35 @@ int osi_ptp_configuration(struct osi_core_priv_data *const osi_core, osi_core->ptp_config.ptp_filter); /* Program Sub Second Increment Register */ - osi_core->ops->config_ssir(osi_core->base, - osi_core->ptp_config.ptp_clock); + osi_core->ops->config_ssir(osi_core); /* formula for calculating addend value is - * addend = 2^32/freq_div_ratio; - * where, freq_div_ratio = ptp_ref_clk_rate/OSI_PTP_REQ_CLK_FREQ + * TSAR = (2^32 * 1000) / (ptp_ref_clk_rate in MHz * SSINC) * 2^x * y == (y << x), hence - * 2^32 * OSI_PTP_REQ_CLK_FREQ == (OSI_PTP_REQ_CLK_FREQ << 32) - * so addend = (2^32 * OSI_PTP_REQ_CLK_FREQ)/ptp_ref_clk_rate; - * which is (OSI_PTP_REQ_CLK_FREQ << 32)/ptp_ref_clk_rate; + * 2^32 * 1000 == (1000 << 32) + * so addend = (2^32 * 1000)/(ptp_ref_clk_rate in MHZ * SSINC); */ - temp = ((unsigned long)OSI_PTP_REQ_CLK_FREQ << 32); + + if (osi_core->mac_ver <= OSI_EQOS_MAC_4_10) { + ssinc = OSI_PTP_SSINC_16; + } else { + ssinc = OSI_PTP_SSINC_4; + } + + temp = ((unsigned long)1000 << 32); + temp = (unsigned long)temp * 1000000U; + temp1 = div_u64(temp, - (unsigned long)osi_core->ptp_config.ptp_ref_clk_rate); - if (temp1 < UINT_MAX) { - osi_core->default_addend = (unsigned int) temp1; + (unsigned long)osi_core->ptp_config.ptp_ref_clk_rate); + + temp2 = div_u64(temp1, (unsigned long)ssinc); + + if (temp2 < UINT_MAX) { + osi_core->default_addend = (unsigned int)temp2; } else { /* do nothing here */ } + /* Program addend value */ ret = osi_core->ops->config_addend(osi_core->base, osi_core->default_addend); From 19e69df63349dbeccde02b0413c2aea67727ac5a Mon Sep 17 00:00:00 2001 From: narayanr <narayanr@nvidia.com> Date: Wed, 22 Jan 2020 20:02:24 +0530 Subject: [PATCH 098/458] nvethernetrm: eqos: allow arp offload allow arp offload for mac version greater than or equal to 5 Bug 200585972 Change-Id: I6cefc16f0c8362a26619489f25e2636618eb0761 Signed-off-by: narayanr <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2283676 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/eqos_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 9a26c71..ad6766e 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -2265,7 +2265,7 @@ static int eqos_config_arp_offload(const unsigned int mac_ver, void *addr, if (mac_ver == OSI_EQOS_MAC_4_10) { osi_writel(val, (unsigned char *)addr + EQOS_4_10_MAC_ARPPA); - } else if (mac_ver == OSI_EQOS_MAC_5_00) { + } else if (mac_ver >= OSI_EQOS_MAC_5_00) { osi_writel(val, (unsigned char *)addr + EQOS_5_00_MAC_ARPPA); } else { From 177ddb16b069830f8c5047907d87279db63a99ab Mon Sep 17 00:00:00 2001 From: Mahesh Patil <maheshp@nvidia.com> Date: Mon, 4 May 2020 14:51:05 -0700 Subject: [PATCH 099/458] nvethernetrm: Check Rx packets processed or not Issue: If buffer allocation fails in Rx refill, cur_rx_idx overlaps and can result in crash in osi_process_rx_completions() Fix: Track Rx packet processed or not. If pkt is already processed skip further rx packet processing in osi_process_rx_completions() Bug 2945319 Change-Id: Ieaed3aadf3d29aaa0e9d29d074f1f0f54f77e620 Signed-off-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2338920 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: Ajay Gupta <ajayg@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_dma.h | 11 +++++++---- osi/dma/osi_dma_txrx.c | 6 ++++++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/include/osi_dma.h b/include/osi_dma.h index b4ddce7..ad932c2 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -43,18 +43,18 @@ */ /** VLAN packet */ #define OSI_PKT_CX_VLAN OSI_BIT(0) -/** Valid packet */ -#define OSI_PKT_CX_VALID OSI_BIT(10) /** CSUM packet */ #define OSI_PKT_CX_CSUM OSI_BIT(1) -/** IP CSUM packet */ -#define OSI_PKT_CX_IP_CSUM OSI_BIT(12) /** TSO packet */ #define OSI_PKT_CX_TSO OSI_BIT(2) /** PTP packet */ #define OSI_PKT_CX_PTP OSI_BIT(3) +/** 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) /** @} */ @@ -128,6 +128,9 @@ /* 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) + /** @} */ /** diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index fab43c7..1a84e1d 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -261,6 +261,12 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, INCR_RX_DESC_INDEX(rx_ring->cur_rx_idx, 1U); + /* 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 From d0972392aeb7082e46fb550a36889687bce5614e Mon Sep 17 00:00:00 2001 From: Nagarjuna Kristam <nkristam@nvidia.com> Date: Thu, 14 May 2020 12:49:36 +0530 Subject: [PATCH 100/458] osi:dma: Add barrier before updating Tx tail pointer Issue: There is chance that descriptor is updated before Tail pointer is updated, as former is memory operation and later is register operation and sequence may no go in sync every time. Fix: Add memory barrier for stores to complete, after updating descriptor to ensure that descriptor is indeed updated before register is written. Bug 200603660 Bug 2945566 Change-Id: I59918c2f949db28da76beb1ab43cd5420e54c59b Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2340534 (cherry picked from commit 3a7b4256924818243e9d36383ebc6e9b1209a94e) Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2341201 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/dma/osi_dma_txrx.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 1a84e1d..1164187 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -731,6 +731,14 @@ static inline void fill_first_desc(struct osi_tx_ring *tx_ring, } } +/** + * @brief dma_wmb- Helper function to add memory write barrier + */ +static inline void dma_wmb(void) +{ + asm volatile("dmb oshst" : : : "memory"); +} + void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan) { struct osi_tx_ring *tx_ring = osi->tx_ring[chan]; @@ -855,6 +863,12 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan) } tx_ring->cur_tx_idx = entry; + + /* + * We need to make sure Tx descriptor updated above is really updated + * before setting up the DMA, hence add memory write barrier here. + */ + dma_wmb(); ops->update_tx_tailptr(osi->base, chan, tailptr); } From 5a0ecd1f6bfcbbb7a1ec049a12daf78601addcc0 Mon Sep 17 00:00:00 2001 From: Nagarjuna Kristam <nkristam@nvidia.com> Date: Thu, 14 May 2020 14:59:54 +0530 Subject: [PATCH 101/458] osi: dma: Add callback for osd data path Issue: When 2 OSD's are part of single compilation process, only one OSD can be linked at compile time. This causes issues in handling TX and RX communication from OSI to OSD. Fix: Add callbacks for TX and RX communication which can be registered by OSD to receive callback communication from OSI for TX and RX. Use existing API's if OSD doesn't register a callback. Bug 200603660 Change-Id: I0b246a78a3d1bc4bb690e1ad7dac82108500b625 Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2343967 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_dma.h | 16 ++++++++++++++++ osi/dma/osi_dma.c | 14 ++++++++++++++ osi/dma/osi_dma_txrx.c | 11 ++++++----- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/include/osi_dma.h b/include/osi_dma.h index ad932c2..0b80ba4 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -386,6 +386,20 @@ struct osi_vm_irq_data { unsigned int vm_chans[OSI_EQOS_MAX_NUM_CHANS]; }; +/** + *@brief OSD DMA callbacks + */ +struct osd_dma_ops { + /** DMA transmit complete callback */ + void (*transmit_complete)(void *priv, void *buffer, + unsigned long dmaaddr, unsigned int len, + void *txdone_pkt_cx); + /** DMA receive packet callback */ + void (*receive_packet)(void *priv, void *rxring, + unsigned int chan, unsigned int dma_buf_len, + void *rxpkt_cx, void *rx_pkt_swcx); +}; + /** * @brief The OSI DMA private data structure. */ @@ -443,6 +457,8 @@ struct osi_dma_priv_data { unsigned int num_vm_irqs; /** Array of VM IRQ's */ struct osi_vm_irq_data irq_data[OSI_MAX_VM_IRQS]; + /** DMA callback ops structure */ + struct osd_dma_ops osd_ops; }; /** diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 4fea528..56e18a0 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -25,6 +25,20 @@ int osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) { + /* + * Currently these osd_ops are optional to be filled in the OSD layer. + * If OSD updates these pointers, use the same. If not, fall back to the + * exisitng way of using osd_* API's. + * TODO: Once These API's are mandatory, return errors instead of + * default API usage. + */ + if (osi_dma->osd_ops.transmit_complete == OSI_NULL) { + osi_dma->osd_ops.transmit_complete = osd_transmit_complete; + } + if (osi_dma->osd_ops.receive_packet == OSI_NULL) { + osi_dma->osd_ops.receive_packet = osd_receive_packet; + } + if (osi_dma->mac == OSI_MAC_HW_EQOS) { /* Get EQOS HW ops */ osi_dma->ops = eqos_get_dma_chan_ops(); diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 1164187..3a35619 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -322,8 +322,9 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, */ INCR_RX_DESC_INDEX(rx_ring->cur_rx_idx, 1U); } - osd_receive_packet(osi->osd, rx_ring, chan, - osi->rx_buf_len, rx_pkt_cx, rx_swcx); + osi->osd_ops.receive_packet(osi->osd, rx_ring, chan, + osi->rx_buf_len, rx_pkt_cx, + rx_swcx); } osi->dstats.q_rx_pkt_n[chan] = osi_update_stats_counter(osi->dstats.q_rx_pkt_n[chan], @@ -562,9 +563,9 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi, txdone_pkt_cx->flags |= OSI_TXDONE_CX_PAGED_BUF; } - osd_transmit_complete(osi->osd, tx_swcx->buf_virt_addr, - tx_swcx->buf_phy_addr, tx_swcx->len, - txdone_pkt_cx); + osi->osd_ops.transmit_complete(osi->osd, tx_swcx->buf_virt_addr, + tx_swcx->buf_phy_addr, + tx_swcx->len, txdone_pkt_cx); tx_desc->tdes3 = 0; tx_desc->tdes2 = 0; From 9efbaa64d16a5c0b4427722fbc43fcad24e2d9e9 Mon Sep 17 00:00:00 2001 From: rakesh goyal <rgoyal@nvidia.com> Date: Sat, 2 May 2020 15:09:35 +0530 Subject: [PATCH 102/458] nvethernetrm: osi private structure update update OSI HW feature registers Bug 200563382 Change-Id: Ia30176bcf9dc1080489caa52bd0c67ac05a17ef1 Signed-off-by: rakesh goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2338042 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_common.h | 142 +++++++++++++++++++++++++++++++++++++++- osi/common/osi_common.c | 2 +- 2 files changed, 142 insertions(+), 2 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index 1667263..8a2efdc 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -376,6 +376,10 @@ struct osi_hw_features { /** It is set to 1 when 10/100 Mbps is selected as the Mode of * Operation */ unsigned int mii_sel; + /** It is set to 1 when the RGMII Interface option is selected */ + unsigned int rgmii_sel; + /** It is set to 1 when the RMII Interface option is selected */ + unsigned int rmii_sel; /** It sets to 1 when 1000 Mbps is selected as the Mode of Operation */ unsigned int gmii_sel; /** It sets to 1 when the half-duplex mode is selected */ @@ -414,7 +418,7 @@ struct osi_hw_features { unsigned int rx_coe_sel; /** It sets to 1 when the Enable Additional 1-31 MAC Address Registers * option is selected */ - unsigned int mac_addr16_sel; + unsigned int mac_addr_sel; /** It sets to 1 when the Enable Additional 32-63 MAC Address Registers * option is selected */ unsigned int mac_addr32_sel; @@ -495,6 +499,8 @@ struct osi_hw_features { unsigned int dma_debug_gen; /** It sets to 1 if AV Feature Enabled */ unsigned int av_sel; + /** It sets to 1 if Receive side AV Feature Enabled */ + unsigned int rav_sel; /** This field indicates the size of the hash table: * 00: No hash table * 01: 64 @@ -537,6 +543,140 @@ struct osi_hw_features { * 100: 4 auxiliary inputs * 101-111: Reserved */ unsigned int aux_snap_num; + /** VxLAN/NVGRE Support */ + unsigned int vxn; + /** Enhanced DMA. + * This bit is set to 1 when the "Enhanced DMA" option is + * selected. */ + unsigned int edma; + /** Different Descriptor Cache + * When set to 1, then EDMA mode Separate Memory is + * selected for the Descriptor Cache.*/ + unsigned int ediffc; + /** PFC Enable + * This bit is set to 1 when the Enable PFC Feature is selected */ + unsigned int pfc_en; + /** One-Step Timestamping Enable */ + unsigned int ost_en; + /** PTO Offload Enable */ + unsigned int pto_en; + /** Receive Side Scaling Enable */ + unsigned int rss_en; + /** Number of Traffic Classes */ + unsigned int num_tc; + /** Number of Extended VLAN Tag Filters Enabled */ + unsigned int num_vlan_filters; + /** Supported Flexible Receive Parser. + * This bit is set to 1 when the Enable Flexible Programmable + * Receive Parser option is selected */ + unsigned int 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. */ + unsigned int cbti_sel; + /** Supported Parallel Instruction Processor Engines (PIPEs) + * This field indicates the maximum number of Instruction + * Processors supported by flexible receive parser. */ + unsigned int 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 */ + unsigned int 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 */ + unsigned int max_frp_bytes; + /** Supported Flexible Receive Parser Instructions + * This field indicates the Max Number of Parser Instructions + * supported by Flexible Receive Parser */ + unsigned int max_frp_entries; + /** Double VLAN Processing Enabled + * This bit is set to 1 when the Enable Double VLAN Processing + * feature is selected */ + unsigned int 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 */ + unsigned int auto_safety_pkg; + /** Tx Timestamp FIFO Depth + * This value indicates the depth of the Tx Timetamp 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 */ + unsigned int 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 */ + unsigned int 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 */ + unsigned int 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 */ + unsigned int 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 */ + unsigned int 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 */ + unsigned int 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 */ + unsigned int num_tbs_ch; }; /** diff --git a/osi/common/osi_common.c b/osi/common/osi_common.c index b2e5c92..290570d 100644 --- a/osi/common/osi_common.c +++ b/osi/common/osi_common.c @@ -60,7 +60,7 @@ void osi_get_hw_features(void *base, struct osi_hw_features *hw_feat) ((mac_hfr0 >> 14U) & EQOS_MAC_HFR0_TXCOESEL_MASK); hw_feat->rx_coe_sel = ((mac_hfr0 >> 16U) & EQOS_MAC_HFR0_RXCOE_MASK); - hw_feat->mac_addr16_sel = + hw_feat->mac_addr_sel = ((mac_hfr0 >> 18U) & EQOS_MAC_HFR0_ADDMACADRSEL_MASK); hw_feat->mac_addr32_sel = ((mac_hfr0 >> 23U) & EQOS_MAC_HFR0_MACADR32SEL_MASK); From d5c4c3dd57bd6fbdb0bb316df50d4ece144605af Mon Sep 17 00:00:00 2001 From: rakesh goyal <rgoyal@nvidia.com> Date: Wed, 27 May 2020 11:58:59 +0530 Subject: [PATCH 103/458] nvethernetrm: clear AE bit in L2 filter for delete Issue: Currently we make L2 Address High register 0x0 to invalidate L2 filter address. Further feature implementation need to preserve Address value to compare with. Fix: clear only AE bit in L2 Address High register. Bug 2653790 Change-Id: Ica8a55b30889bee1f584cb8826fdbbf702d56f66 Signed-off-by: rakesh goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2351020 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/eqos_core.c | 7 +++++-- osi/core/eqos_core.h | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index ad6766e..7f625ab 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -2103,7 +2103,10 @@ static int eqos_update_mac_addr_low_high_reg( /* High address clean should happen for filter index >= 0 */ if (addr == OSI_NULL) { - osi_writel(0x0U, (unsigned char *)osi_core->base + + value = osi_readl((unsigned char *)osi_core->base + + EQOS_MAC_ADDRH((idx))); + value &= ~EQOS_MAC_ADDRH_AE; + osi_writel(value, (unsigned char *)osi_core->base + EQOS_MAC_ADDRH((idx))); return 0; } @@ -2124,7 +2127,7 @@ static int eqos_update_mac_addr_low_high_reg( } osi_writel(((unsigned int)addr[4] | - ((unsigned int)addr[5] << 8) | OSI_BIT(31) | value), + ((unsigned int)addr[5] << 8) | EQOS_MAC_ADDRH_AE | value), (unsigned char *)osi_core->base + EQOS_MAC_ADDRH((idx))); osi_writel(((unsigned int)addr[0] | ((unsigned int)addr[1] << 8) | diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 168db02..8532ebd 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -354,6 +354,7 @@ #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_VLAN_TR 0x0050U #define EQOS_MAC_VLAN_TFR 0x0054U #define EQOS_MAC_VLAN_HTR 0x0058U From 309e6f9e2012082b599b41ae1446d50f4661e9e5 Mon Sep 17 00:00:00 2001 From: Nagarjuna Kristam <nkristam@nvidia.com> Date: Wed, 27 May 2020 10:36:10 +0530 Subject: [PATCH 104/458] osi: core: Perform RxQ mapping only if DCS is disabled Issue: RxQ priority API is called without any checks for DCS and when DCS is enabled, an error log is printed while handling RxQ priority config. Fix: Perform RxQ priority only when DCS is not enabled. Bug 2989724 Change-Id: I8649daa8f9a1165bcfd99850420b01987cf61be0 Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2350964 (cherry picked from commit 4f2d270a867466c0608d61e9339cec7a494dd1cf) Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2352153 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/eqos_core.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 7f625ab..471dfc7 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1251,12 +1251,6 @@ static void eqos_configure_rxq_priority( unsigned int pmask = 0x0U; unsigned int mfix_var1, mfix_var2; - if (osi_core->dcs_en == OSI_ENABLE) { - OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid combination of DCS and RxQ-UP mapping\n", - 0ULL); - return; - } /* make sure EQOS_MAC_RQC2R is reset before programming */ osi_writel(OSI_DISABLE, (unsigned char *)osi_core->base + EQOS_MAC_RQC2R); @@ -1429,8 +1423,10 @@ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) 0ULL); } } - /* USP (user Priority) to RxQ Mapping */ - eqos_configure_rxq_priority(osi_core); + /* USP (user Priority) to RxQ Mapping, only if DCS not enabled */ + if (osi_core->dcs_en != OSI_ENABLE) { + eqos_configure_rxq_priority(osi_core); + } } /** From 54745524937442629d49c5a47d54c36b8b490100 Mon Sep 17 00:00:00 2001 From: rakesh goyal <rgoyal@nvidia.com> Date: Fri, 12 Jun 2020 12:28:05 +0530 Subject: [PATCH 105/458] nvethernetrm: eqos: handle filter operation flag Issue: RM server is not aware of what L2 address should be removed from local list and register as index passed by OSD/OSI_Core may mis-match in case multi FD instance usecase. Fix: As RM server finds index/offset on its own corresponding to MAC address, Core software should reset AE bit and pass other user provided argument as it is. Legacy way of removing L2 address is still supported. Bug 200626200 Change-Id: I43919827422d176334198ee09e822047b606da79 Signed-off-by: rakesh goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2359969 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_common.h | 1 + osi/core/eqos_core.c | 8 +++++++- osi/core/osi_core.c | 3 ++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index 8a2efdc..d41dfa9 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -232,6 +232,7 @@ #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 MAC_VERSION 0x110 #define MAC_VERSION_SNVER_MASK 0x7FU diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 471dfc7..afa11d6 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -2122,8 +2122,14 @@ static int eqos_update_mac_addr_low_high_reg( EQOS_MAC_ADDRH_SA)); } + /* 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; + } + osi_writel(((unsigned int)addr[4] | - ((unsigned int)addr[5] << 8) | EQOS_MAC_ADDRH_AE | value), + ((unsigned int)addr[5] << 8) | value), (unsigned char *)osi_core->base + EQOS_MAC_ADDRH((idx))); osi_writel(((unsigned int)addr[0] | ((unsigned int)addr[1] << 8) | diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index b50c4f0..8e2630b 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -323,7 +323,8 @@ int osi_l2_filter(struct osi_core_priv_data *const osi_core, return ret; } - if ((filter->oper_mode & OSI_OPER_ADDR_UPDATE) != OSI_NONE) { + 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) && From cb0ba53d5ce97a29c71b848e56555ce8fc983641 Mon Sep 17 00:00:00 2001 From: rakesh goyal <rgoyal@nvidia.com> Date: Wed, 17 Jun 2020 18:21:02 +0530 Subject: [PATCH 106/458] nvethernetrm: eqos: correct mmc register read for ipv6 Issue: Wrong MMC registers are read for IPV6 Fix: Update correct register address read for IPV6 Bug 200519211 Change-Id: Ib377b28721a5596c2adfe1b6a61476a271e3c036 Signed-off-by: rakesh goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2362390 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/eqos_mmc.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/osi/core/eqos_mmc.c b/osi/core/eqos_mmc.c index 0ded1bd..f7c41dd 100644 --- a/osi/core/eqos_mmc.c +++ b/osi/core/eqos_mmc.c @@ -286,14 +286,14 @@ void eqos_read_mmc(struct osi_core_priv_data *osi_core) mmc->mmc_rx_ipv4_udsbl = update_mmc_val(osi_core, mmc->mmc_rx_ipv4_udsbl, MMC_RXIPV4_UBSBL_PKTS); - mmc->mmc_rx_ipv6_gd_octets = - update_mmc_val(osi_core, mmc->mmc_rx_ipv6_gd_octets, + mmc->mmc_rx_ipv6_gd = + update_mmc_val(osi_core, mmc->mmc_rx_ipv6_gd, MMC_RXIPV6_GD_PKTS); - mmc->mmc_rx_ipv6_hderr_octets = - update_mmc_val(osi_core, mmc->mmc_rx_ipv6_hderr_octets, + mmc->mmc_rx_ipv6_hderr = + update_mmc_val(osi_core, mmc->mmc_rx_ipv6_hderr, MMC_RXIPV6_HDRERR_PKTS); - mmc->mmc_rx_ipv6_nopay_octets = - update_mmc_val(osi_core, mmc->mmc_rx_ipv6_nopay_octets, + 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, @@ -330,12 +330,15 @@ void eqos_read_mmc(struct osi_core_priv_data *osi_core) 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 = - update_mmc_val(osi_core, mmc->mmc_rx_ipv6_hderr, + 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 = - update_mmc_val(osi_core, mmc->mmc_rx_ipv6_nopay, + 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, From 442b17dca93df045b16e7e7cdeaa17534ffaaa25 Mon Sep 17 00:00:00 2001 From: Srinivas Ramachandran <srinivasra@nvidia.com> Date: Mon, 15 Jun 2020 11:02:36 -0700 Subject: [PATCH 107/458] nvethernetrm: Indicate more Rx frames pending Issue: The function osi_process_rx_completions does not provide indication whether there are more Rx frames in the HW ring to be processed by SW. This indication is needed in OSD layers like AUTOSAR MCAL driver as per the spec. Fix: Check the next descriptor in the ring and indicate if it has a valid new Rx packet that is pending to be processed. Bug 3019362 Change-Id: I4b4b8ac7b741dedbe979156e44f442cbb0e67590 Signed-off-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2361176 Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: Mahesh Patil <maheshp@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_dma.h | 5 ++++- osi/dma/osi_dma_txrx.c | 25 +++++++++++++++++++++++-- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/include/osi_dma.h b/include/osi_dma.h index 0b80ba4..59cf44b 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -750,6 +750,8 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi, * @param[in] osi: OSI private data structure. * @param[in] chan: Rx DMA channel number * @param[in] budget: Threshould for reading the packets at a time. + * @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). * * @note * 1) MAC needs to be out of reset and proper clocks need to be configured. @@ -759,7 +761,8 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi, * @returns Number of decriptors (buffers) proccessed. */ int osi_process_rx_completions(struct osi_dma_priv_data *osi, - unsigned int chan, int budget); + unsigned int chan, int budget, + unsigned int *more_data_avail); /** * @brief osi_hw_dma_init - Initialize DMA diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 3a35619..d97bb1e 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -234,7 +234,8 @@ static inline void get_rx_err_stats(struct osi_rx_desc *rx_desc, } int osi_process_rx_completions(struct osi_dma_priv_data *osi, - unsigned int chan, int budget) + unsigned int chan, int budget, + unsigned int *more_data_avail) { struct osi_rx_ring *rx_ring = osi->rx_ring[chan]; struct osi_rx_pkt_cx *rx_pkt_cx = &rx_ring->rx_pkt_cx; @@ -245,10 +246,13 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, int received = 0; int ret = 0; - if (rx_ring->cur_rx_idx >= RX_DESC_CNT) { + if (rx_ring->cur_rx_idx >= RX_DESC_CNT || more_data_avail == OSI_NULL) { return -1; } + /* Reset flag to indicate if more Rx frames available to OSD layer */ + *more_data_avail = OSI_NONE; + while (received < budget) { osi_memset(rx_pkt_cx, 0U, sizeof(*rx_pkt_cx)); rx_desc = rx_ring->rx_desc + rx_ring->cur_rx_idx; @@ -332,6 +336,23 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, osi->dstats.rx_pkt_n = osi_update_stats_counter(osi->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 == 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 desciptor has owned by SW + * So set more data avail flag here. + */ + *more_data_avail = OSI_ENABLE; + } + } } return received; From 84437998989e276b3f2c94ca5f008c0ca6107f3c Mon Sep 17 00:00:00 2001 From: Nagarjuna Kristam <nkristam@nvidia.com> Date: Fri, 26 Jun 2020 15:56:07 +0530 Subject: [PATCH 108/458] osi: dma: Add support to read PTP time over DMA base Issue: RFE to support PTP time read from OSI DMA. Fix: Add OSI DMA API to read PTP time from DMA base. Move PTP time read code to OSI common. Bug 200630996 Change-Id: Ic65a042d23318f93ecf23b481ab7a898cf88d360 Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2367295 (cherry picked from commit 7379669ef23507e0f50f1517e819c552ea359300) Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2374403 Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: Gaurav Asati <gasati@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_dma.h | 20 +++++++++++ osi/common/eqos_common.c | 58 ++++++++++++++++++++++++++++++ osi/common/eqos_common.h | 52 +++++++++++++++++++++++++++ osi/common/include/local_common.h | 46 ++++++++++++++++++++++++ osi/common/osi_common.c | 59 ++++++++++++++++++++++++++++++- osi/core/Makefile.tmk | 6 ++-- osi/core/eqos_core.c | 49 ------------------------- osi/core/osi_core.c | 23 +++--------- osi/dma/Makefile.tmk | 6 ++-- osi/dma/libnvethernetcl.export | 3 +- osi/dma/osi_dma.c | 15 ++++++++ 11 files changed, 263 insertions(+), 74 deletions(-) create mode 100644 osi/common/eqos_common.c create mode 100644 osi/common/eqos_common.h create mode 100644 osi/common/include/local_common.h diff --git a/include/osi_dma.h b/include/osi_dma.h index 59cf44b..6a517c9 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -912,4 +912,24 @@ int osi_txring_empty(struct osi_dma_priv_data *osi_dma, unsigned int chan); * @retval status */ unsigned int osi_get_global_dma_status(struct osi_dma_priv_data *osi_dma); + +/** + * @brief osi_dma_get_systime_from_mac - Get system time + * + * 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 + * + * @note MAC should be init and started. see osi_start_mac() + * + * @retval 0 on success + * @retval -1 on failure. + */ +int osi_dma_get_systime_from_mac( + struct osi_dma_priv_data *const osi_dma, + unsigned int *sec, + unsigned int *nsec); + #endif /* OSI_DMA_H */ diff --git a/osi/common/eqos_common.c b/osi/common/eqos_common.c new file mode 100644 index 0000000..6c07cb9 --- /dev/null +++ b/osi/common/eqos_common.c @@ -0,0 +1,58 @@ +/* + * 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" + +unsigned long long eqos_get_systime_from_mac(void *addr) +{ + unsigned long long ns1, ns2, ns = 0; + unsigned int varmac_stnsr, temp1; + unsigned int varmac_stsr; + + varmac_stnsr = osi_readl((unsigned char *)addr + EQOS_MAC_STNSR); + temp1 = (varmac_stnsr & EQOS_MAC_STNSR_TSSS_MASK); + ns1 = (unsigned long long)temp1; + + varmac_stsr = osi_readl((unsigned char *)addr + EQOS_MAC_STSR); + + varmac_stnsr = osi_readl((unsigned char *)addr + EQOS_MAC_STNSR); + temp1 = (varmac_stnsr & EQOS_MAC_STNSR_TSSS_MASK); + ns2 = (unsigned long long)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((unsigned char *)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; +} diff --git a/osi/common/eqos_common.h b/osi/common/eqos_common.h new file mode 100644 index 0000000..98a96ec --- /dev/null +++ b/osi/common/eqos_common.h @@ -0,0 +1,52 @@ +/* + * 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 EQOS_COMMON_H +#define EQOS_COMMON_H + +#include <local_common.h> + +/** + * @brief PTP Time read registers + * @{ + */ +#define EQOS_MAC_STSR 0x0B08 +#define EQOS_MAC_STNSR 0x0B0C +#define EQOS_MAC_STNSR_TSSS_MASK 0x7FFFFFFFU +/** @} */ + +/** + * @brief eqos_get_systime - 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. + */ +unsigned long long eqos_get_systime_from_mac(void *addr); + +#endif /* EQOS_COMMON_H */ diff --git a/osi/common/include/local_common.h b/osi/common/include/local_common.h new file mode 100644 index 0000000..a2dbdbe --- /dev/null +++ b/osi/common/include/local_common.h @@ -0,0 +1,46 @@ +/* + * 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 LOCAL_COMMON_H +#define LOCAL_COMMON_H + +#include <osi_core.h> + +/** + * @brief common_get_systime_from_mac - Get system time + * + * Algorithm: Gets the current 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. + * + * @note MAC should be init and started. see osi_start_mac() + * + * @retval 0 on success + * @retval -1 on failure. + */ +void common_get_systime_from_mac(void *addr, unsigned int mac, + unsigned int *sec, unsigned int *nsec); + +#endif /* LOCAL_COMMON_H */ diff --git a/osi/common/osi_common.c b/osi/common/osi_common.c index 290570d..80cf1d5 100644 --- a/osi/common/osi_common.c +++ b/osi/common/osi_common.c @@ -20,8 +20,8 @@ * DEALINGS IN THE SOFTWARE. */ -#include <osi_core.h> #include <osd.h> +#include "eqos_common.h" void osi_get_hw_features(void *base, struct osi_hw_features *hw_feat) { @@ -134,3 +134,60 @@ void osi_memset(void *s, unsigned int c, unsigned long count) count--; } } + +/** + *@brief div_u64_rem - updates remainder and returns Quotient + * + * 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 + * + * @note MAC IP should be out of reset and need to be initialized as the + * requirements + * + * @returns Quotient + */ +static inline unsigned long div_u64_rem(unsigned long dividend, + unsigned long divisor, + unsigned long *remain) +{ + unsigned long ret = 0; + + if (divisor != 0U) { + *remain = dividend % divisor; + ret = dividend / divisor; + } else { + ret = 0; + } + return ret; +} + +void common_get_systime_from_mac(void *addr, unsigned int mac, + unsigned int *sec, unsigned int *nsec) +{ + unsigned long temp; + unsigned long remain; + unsigned long long ns; + + if (mac == OSI_MAC_HW_EQOS) { + ns = eqos_get_systime_from_mac(addr); + } else { + /* Non EQOS HW is supported yet */ + return; + } + + temp = div_u64_rem((unsigned long)ns, OSI_NSEC_PER_SEC, &remain); + if (temp < UINT_MAX) { + *sec = (unsigned int) temp; + } else { + /* do nothing here */ + } + if (remain < UINT_MAX) { + *nsec = (unsigned int)remain; + } else { + /* do nothing here */ + } +} diff --git a/osi/core/Makefile.tmk b/osi/core/Makefile.tmk index b883bd8..86762b4 100644 --- a/osi/core/Makefile.tmk +++ b/osi/core/Makefile.tmk @@ -1,6 +1,6 @@ ################################### tell Emacs this is a -*- makefile-gmake -*- # -# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2019-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"), @@ -33,13 +33,15 @@ NV_COMPONENT_SOURCES := \ eqos_core.c \ eqos_mmc.c \ osi_core.c \ - $(NV_SOURCE)/nvethernetrm/osi/common/osi_common.c + $(NV_SOURCE)/nvethernetrm/osi/common/osi_common.c \ + $(NV_SOURCE)/nvethernetrm/osi/common/eqos_common.c NV_COMPONENT_NEEDED_INTERFACE_DIRS := \ $(NV_SOURCE)/qnx/src/libs/nvethernet/osi_dependencies NV_COMPONENT_INCLUDES := \ $(NV_SOURCE)/nvethernetrm/include \ + $(NV_SOURCE)/nvethernetrm/osi/common/include \ $(NV_SOURCE)/core/include include $(NV_BUILD_SHARED_LIBRARY) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index afa11d6..b3fb982 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -3212,54 +3212,6 @@ static int eqos_adjust_mactime(void *addr, unsigned int sec, unsigned int nsec, return 0; } -/** - * @brief eqos_get_systime - 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. - */ -static unsigned long long eqos_get_systime_from_mac(void *addr) -{ - unsigned long long ns1, ns2, ns = 0; - unsigned int varmac_stnsr, temp1; - unsigned int varmac_stsr; - - varmac_stnsr = osi_readl((unsigned char *)addr + EQOS_MAC_STNSR); - temp1 = (varmac_stnsr & EQOS_MAC_STNSR_TSSS_MASK); - ns1 = (unsigned long long)temp1; - - varmac_stsr = osi_readl((unsigned char *)addr + EQOS_MAC_STSR); - - varmac_stnsr = osi_readl((unsigned char *)addr + EQOS_MAC_STNSR); - temp1 = (varmac_stnsr & EQOS_MAC_STNSR_TSSS_MASK); - ns2 = (unsigned long long)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((unsigned char *)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; -} - /** * @brief eqos_config_tscr - Configure Time Stamp Register * @@ -3781,7 +3733,6 @@ static struct osi_core_ops eqos_core_ops = { .set_systime_to_mac = eqos_set_systime_to_mac, .config_addend = eqos_config_addend, .adjust_mactime = eqos_adjust_mactime, - .get_systime_from_mac = eqos_get_systime_from_mac, .config_tscr = eqos_config_tscr, .config_ssir = eqos_config_ssir, .read_mmc = eqos_read_mmc, diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 8e2630b..4e119a7 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -22,6 +22,7 @@ #include <osi_core.h> #include <osd.h> +#include <local_common.h> int osi_write_phy_reg(struct osi_core_priv_data *const osi_core, const unsigned int phyaddr, const unsigned int phyreg, @@ -723,29 +724,13 @@ int osi_get_systime_from_mac( unsigned int *sec, unsigned int *nsec) { - unsigned long long ns = 0; - unsigned long long temp = 0; - unsigned long remain = 0; - - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->get_systime_from_mac != OSI_NULL)) { - ns = osi_core->ops->get_systime_from_mac(osi_core->base); + if ((osi_core != OSI_NULL) && (osi_core->base != OSI_NULL)) { + common_get_systime_from_mac(osi_core->base, osi_core->mac, sec, + nsec); } else { return -1; } - temp = div_u64_rem((unsigned long)ns, OSI_NSEC_PER_SEC, &remain); - if (temp < UINT_MAX) { - *sec = (unsigned int) temp; - } else { - /* do nothing here */ - } - if (remain < UINT_MAX) { - *nsec = (unsigned int)remain; - } else { - /* do nothing here */ - } - return 0; } diff --git a/osi/dma/Makefile.tmk b/osi/dma/Makefile.tmk index a4bd2cd..b076c52 100644 --- a/osi/dma/Makefile.tmk +++ b/osi/dma/Makefile.tmk @@ -1,6 +1,6 @@ ################################### tell Emacs this is a -*- makefile-gmake -*- # -# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2019-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"), @@ -33,13 +33,15 @@ NV_COMPONENT_SOURCES := \ eqos_dma.c \ osi_dma.c \ osi_dma_txrx.c \ - $(NV_SOURCE)/nvethernetrm/osi/common/osi_common.c + $(NV_SOURCE)/nvethernetrm/osi/common/osi_common.c \ + $(NV_SOURCE)/nvethernetrm/osi/common/eqos_common.c NV_COMPONENT_NEEDED_INTERFACE_DIRS := \ $(NV_SOURCE)/qnx/src/libs/nvethernet/osi_dependencies NV_COMPONENT_INCLUDES := \ $(NV_SOURCE)/nvethernetrm/include \ + $(NV_SOURCE)/nvethernetrm/osi/common/include \ $(NV_SOURCE)/core/include include $(NV_BUILD_SHARED_LIBRARY) diff --git a/osi/dma/libnvethernetcl.export b/osi/dma/libnvethernetcl.export index 2a553d2..e54e368 100644 --- a/osi/dma/libnvethernetcl.export +++ b/osi/dma/libnvethernetcl.export @@ -1,6 +1,6 @@ ################################### tell Emacs this is a -*- makefile-gmake -*- # -# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2019-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"), @@ -41,3 +41,4 @@ osi_init_dma_ops osi_validate_dma_regs osi_config_slot_function osi_clear_tx_pkt_err_stats +osi_dma_get_systime_from_mac diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 56e18a0..200efc1 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -22,6 +22,7 @@ #include "osi_dma_local.h" #include <osd.h> +#include <local_common.h> int osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) { @@ -411,3 +412,17 @@ int osi_txring_empty(struct osi_dma_priv_data *osi_dma, unsigned int chan) return (tx_ring->clean_idx == tx_ring->cur_tx_idx) ? 1 : 0; } + +int osi_dma_get_systime_from_mac(struct osi_dma_priv_data *const osi_dma, + unsigned int *sec, + unsigned int *nsec) +{ + if ((osi_dma != OSI_NULL) && (osi_dma->base != OSI_NULL)) { + common_get_systime_from_mac(osi_dma->base, osi_dma->mac, sec, + nsec); + } else { + return -1; + } + + return 0; +} From 09d1011452403239cf284e01c776e6fd6ac78b5e Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Mon, 29 Jun 2020 11:09:23 +0530 Subject: [PATCH 109/458] nvethernetrm: MISRA fixes for QNX PLC Issue: Observed three MISRA/CERT-C issue with QNX PLC configuration. Fix: Fix observed MISRA issues. Bug 200624259 Change-Id: Iafd0f2694b4506bee12b15f899cf2201cad92925 Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2368010 (cherry picked from commit 61310ea022e525d88d9d9def8eebee2b96770e27) Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2375768 Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Gaurav Asati <gasati@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_core.h | 1 - osi/dma/eqos_dma.c | 5 ++++- osi/dma/osi_dma_txrx.c | 8 +++++--- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index ced7000..756f599 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -1037,7 +1037,6 @@ int osi_ptp_configuration(struct osi_core_priv_data *const osi_core, */ struct osi_core_ops *eqos_get_hw_core_ops(void); void *eqos_get_core_safety_config(void); -void *eqos_get_core_backup_config(void); /** * @brief osi_l3l4_filter - invoke OSI call to add L3/L4 diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index 5828646..4ab9090 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -757,9 +757,12 @@ static void eqos_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) unsigned int rx_buf_len = 0U; /* Add Ethernet header + VLAN header + NET IP align size to MTU */ - if (osi_dma->mtu < UINT_MAX) { + 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 */ diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index d97bb1e..6ba46d9 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -698,10 +698,12 @@ static inline void fill_first_desc(struct osi_tx_ring *tx_ring, /* 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) == + } 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; + /* 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 */ From 461ddc9e82af27089775911344f6b004d7eddd25 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Mon, 10 Aug 2020 09:10:43 +0530 Subject: [PATCH 110/458] nvethernetrm: rename static API name for dma_wmb() Issue: For debugging purpose sometimes developers will include OS header files to add the debug prints. When Linux include <linux/printk.h> which includes other header files and those header files defines dma_wmb() which results in compilation error. Fix: Rename OSI static API dma_wmb() to dmb_oshst() which matches the memory barrier operation. Change-Id: I4ceb53d4ad317c0f86b82ed07ad930ce14287c11 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2396495 Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/dma/osi_dma_txrx.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 6ba46d9..8fcbf14 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -756,9 +756,10 @@ static inline void fill_first_desc(struct osi_tx_ring *tx_ring, } /** - * @brief dma_wmb- Helper function to add memory write barrier + * @brief dmb_oshst() - Data memory barrier operation that waits only + * for stores to complete, and only to the outer shareable domain. */ -static inline void dma_wmb(void) +static inline void dmb_oshst(void) { asm volatile("dmb oshst" : : : "memory"); } @@ -892,7 +893,7 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan) * We need to make sure Tx descriptor updated above is really updated * before setting up the DMA, hence add memory write barrier here. */ - dma_wmb(); + dmb_oshst(); ops->update_tx_tailptr(osi->base, chan, tailptr); } From f62ba1dd293a8e4763c811d5c1e41e12be74c43e Mon Sep 17 00:00:00 2001 From: nannaiah <nannaiah@nvidia.com> Date: Fri, 22 May 2020 08:50:44 -0700 Subject: [PATCH 111/458] nvethernet: Add to read PTP registers from DMA base. Issue: Virtualization introduces read delay due to trap mechanism. Fix: Move time critical PTP timestamp registers to use alternate HW MMIO window/page that is not trapped to read PTP timestamp registers. Bug 2694285 Change-Id: I52340ae1f136a1a921b9c4a669c398e5d23ded73 Signed-off-by: Nagaraj Annaiah <nannaiah@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2360103 (cherry picked from commit e2ad2ff5b43532c2d5f9165f0311c59f1c6e9a4c) Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2347314 Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: Gaurav Asati <gasati@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit Tested-by: Gaurav Asati <gasati@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_core.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/osi_core.h b/include/osi_core.h index 756f599..f8cc854 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -353,6 +353,8 @@ struct core_backup { struct osi_core_priv_data { /** Memory mapped base address of MAC IP */ void *base; + /** Memory mapped base address of DMA window of MAC IP */ + void *dma_base; /** Pointer to OSD private data structure */ void *osd; /** Address of HW Core operations structure */ From 407991cb962e75d72b81e0ba8022109ef112046d Mon Sep 17 00:00:00 2001 From: rakesh goyal <rgoyal@nvidia.com> Date: Fri, 14 Aug 2020 22:12:56 +0530 Subject: [PATCH 112/458] dma: fix Rx DMA suspend issue Issue: DMA will be in suspend state if there is no buffer allocation happen to HW. If DMA is in suspend state, no interrupt will occur for channel which leads to not calling of osd_receive_packet(). Fix: Whenever there is rx buffer kernel memory allocation failure, desc will be updated with reserve rx buffer. This reserved buffer is already allocated at the time of ether_open. Aim of same to make sure rx DMA always have buffer and not go in suspend state. Bug 200650229 Change-Id: If8ff5f2dbfb631e8d1bc2383f958ed389643d7a4 Signed-off-by: rakesh goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2399010 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_dma.h | 14 ++++++++++--- osi/dma/osi_dma_txrx.c | 46 +++++++++++++++++++++++++++--------------- 2 files changed, 41 insertions(+), 19 deletions(-) diff --git a/include/osi_dma.h b/include/osi_dma.h index 6a517c9..9379303 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -398,6 +398,8 @@ struct osd_dma_ops { void (*receive_packet)(void *priv, void *rxring, unsigned int chan, unsigned int dma_buf_len, void *rxpkt_cx, void *rx_pkt_swcx); + /** RX buffer reallocation callback */ + void (*realloc_buf)(void *priv, void *rxring, unsigned int chan); }; /** @@ -459,6 +461,10 @@ struct osi_dma_priv_data { struct osi_vm_irq_data irq_data[OSI_MAX_VM_IRQS]; /** 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 */ + unsigned long resv_buf_phy_addr; }; /** @@ -742,9 +748,11 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi, * Algorithm: This routine will be invoked by OSD layer to get the * data from Rx descriptors and deliver the packet to the stack. * 1) Checks descriptor owned by DMA or not. - * 2) Get the length from Rx descriptor - * 3) Invokes OSD layer to deliver the packet to network stack. - * 4) Re-allocate the receive buffers, populate Rx descriptor and + * 2) If rx buffer is reserve buffer, reallocate receive buffer and + read next descriptor. + * 3) Get the length from Rx descriptor + * 4) Invokes OSD layer to deliver the packet to network stack. + * 5) Re-allocate the receive buffers, populate Rx descriptor and * handover to DMA. * * @param[in] osi: OSI private data structure. diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 8fcbf14..e9649af 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -244,6 +244,7 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, struct osi_rx_swcx *ptp_rx_swcx = OSI_NULL; struct osi_rx_desc *context_desc = OSI_NULL; int received = 0; + int received_resv = 0; int ret = 0; if (rx_ring->cur_rx_idx >= RX_DESC_CNT || more_data_avail == OSI_NULL) { @@ -253,7 +254,7 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, /* Reset flag to indicate if more Rx frames available to OSD layer */ *more_data_avail = OSI_NONE; - while (received < budget) { + 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; @@ -265,6 +266,19 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, INCR_RX_DESC_INDEX(rx_ring->cur_rx_idx, 1U); + if (osi_unlikely(rx_swcx->buf_virt_addr == + osi->resv_buf_virt_addr)) { + rx_swcx->buf_virt_addr = OSI_NULL; + rx_swcx->buf_phy_addr = 0; + /* Reservered buffer used */ + received_resv++; + if (osi->osd_ops.realloc_buf != OSI_NULL) { + osi->osd_ops.realloc_buf(osi->osd, + rx_ring, chan); + } + continue; + } + /* packet already processed */ if ((rx_swcx->flags & OSI_RX_SWCX_PROCESSED) == OSI_RX_SWCX_PROCESSED) { @@ -336,22 +350,22 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, osi->dstats.rx_pkt_n = osi_update_stats_counter(osi->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 == 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 desciptor has owned by SW - * So set more data avail flag here. - */ - *more_data_avail = OSI_ENABLE; - } + /* 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; } } From c7ad3e0e9f9e504c7f69c47b66e4ad42ccd624b3 Mon Sep 17 00:00:00 2001 From: Mahesh Patil <maheshp@nvidia.com> Date: Mon, 29 Jun 2020 15:11:56 -0700 Subject: [PATCH 113/458] nvethernetrm: qnx sdk makefiles Bug 200618758 Change-Id: Iac768d6821d533a9d4e6d7d734d94998b40d8bf3 Signed-off-by: Mahesh Patil <maheshp@nvidia.com> (cherry picked from commit a83c7aeaf567021ad78c19165a4c8b10127e5de7) Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2368398 Reviewed-by: Praveen Mallaiah <pmallaiah@nvidia.com> Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: Sumeet Gupta <sumeetg@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: Praveen Mallaiah <pmallaiah@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/Makefile.sdk | 37 +++++++++++++++++++++++++++++++++++++ osi/dma/Makefile.sdk | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 osi/core/Makefile.sdk create mode 100644 osi/dma/Makefile.sdk diff --git a/osi/core/Makefile.sdk b/osi/core/Makefile.sdk new file mode 100644 index 0000000..40e4b73 --- /dev/null +++ b/osi/core/Makefile.sdk @@ -0,0 +1,37 @@ +# Copyright (c) 2020 NVIDIA CORPORATION. All Rights Reserved. +# +# NVIDIA CORPORATION and its licensors retain all intellectual property +# and proprietary rights in and to this software, related documentation +# and any modifications thereto. Any use, reproduction, disclosure or +# distribution of this software and related documentation without an express +# license agreement from NVIDIA CORPORATION is strictly prohibited. + +include ../../../../../../../../../drive-t186ref-qnx/make/nvdefs.mk + +TARGETS = libnvethernetrm.so + +CFLAGS += -g -Wall $(NV_PLATFORM_OPT) $(NV_PLATFORM_CFLAGS) +CPPFLAGS = $(NV_PLATFORM_SDK_INC) $(NV_PLATFORM_CPPFLAGS) -I../../../include -I../dma -I../common/include +CPPFLAGS += -DNV_IS_SAFETY=$(NV_PLATFORM_SAFETY) +LDFLAGS := \ + $(NV_PLATFORM_SDK_LIB) \ + $(NV_PLATFORM_LDFLAGS) +LDFLAGS += -shared + +OBJS := eqos_core.o +OBJS += eqos_mmc.o +OBJS += osi_core.o +OBJS += ./../common/osi_common.o +OBJS += ./../common/eqos_common.o + +LDLIBS += -lnvethernetcl +LDLIBS += -lnvos_s3_safety + +CFLAGS += -D_FILE_OFFSET_BITS=64 + +$(TARGETS): $(OBJS) + $(LD) $(LDFLAGS) -o $@ $^ $(LDLIBS) + $(STRIP) --strip-unneeded -R .comment -R .GCC.command.line $@ + +clean clobber: + rm -rf $(OBJS) $(TARGETS) diff --git a/osi/dma/Makefile.sdk b/osi/dma/Makefile.sdk new file mode 100644 index 0000000..55ac311 --- /dev/null +++ b/osi/dma/Makefile.sdk @@ -0,0 +1,37 @@ +# Copyright (c) 2020 NVIDIA CORPORATION. All Rights Reserved. +# +# NVIDIA CORPORATION and its licensors retain all intellectual property +# and proprietary rights in and to this software, related documentation +# and any modifications thereto. Any use, reproduction, disclosure or +# distribution of this software and related documentation without an express +# license agreement from NVIDIA CORPORATION is strictly prohibited. + +include ../../../../../../../../../drive-t186ref-qnx/make/nvdefs.mk + +TARGETS = libnvethernetcl.so + +CFLAGS += -g -Wall $(NV_PLATFORM_OPT) $(NV_PLATFORM_CFLAGS) +CPPFLAGS = $(NV_PLATFORM_SDK_INC) $(NV_PLATFORM_CPPFLAGS) -I../../../include -I../core -I../common/include +CPPFLAGS += -DNV_IS_SAFETY=$(NV_PLATFORM_SAFETY) +LDFLAGS := \ + $(NV_PLATFORM_SDK_LIB) \ + $(NV_PLATFORM_LDFLAGS) +LDFLAGS += -shared + +OBJS := eqos_dma.o +OBJS += osi_dma.o +OBJS += osi_dma_txrx.o +OBJS += ./../common/osi_common.o +OBJS += ./../common/eqos_common.o + +LDLIBS += -lnvethernetrm +LDLIBS += -lnvos_s3_safety + +CFLAGS += -D_FILE_OFFSET_BITS=64 + +$(TARGETS): $(OBJS) + $(LD) $(LDFLAGS) -o $@ $^ $(LDLIBS) + $(STRIP) --strip-unneeded -R .comment -R .GCC.command.line $@ + +clean clobber: + rm -rf $(OBJS) $(TARGETS) From 64073750443cc7cf01b2a18a7fa28c8468cfca8c Mon Sep 17 00:00:00 2001 From: Nagarjuna Kristam <nkristam@nvidia.com> Date: Wed, 12 Aug 2020 17:17:07 +0530 Subject: [PATCH 114/458] osi: common: Add API to check if MAC is enabled Issue: RFE to check MAC enable status. Fix: Export osi_is_mac_enabled API to check for MAC status. Bug 200646286 Bug 200671362 Change-Id: I26575c7c26095de3598197f5b800d3f1610a8bc9 Signed-off-by: Gaurav Asati <gasati@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2397918 (cherry picked from commit a1b24b2524150aa4b3f60cdd00c08f97de875f1c) Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2405293 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_core.h | 2 +- include/osi_dma.h | 13 +++++++++++++ osi/common/eqos_common.c | 14 ++++++++++++++ osi/common/eqos_common.h | 23 +++++++++++++++++++++++ osi/common/include/local_common.h | 14 ++++++++++++++ osi/common/osi_common.c | 10 ++++++++++ osi/dma/libnvethernetcl.export | 1 + osi/dma/osi_dma.c | 9 +++++++++ 8 files changed, 85 insertions(+), 1 deletion(-) diff --git a/include/osi_core.h b/include/osi_core.h index f8cc854..317b15e 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -333,7 +333,7 @@ struct osi_ptp_config { /** * @brief Max num of MAC core registers to backup. It should be max of or >= - * (EQOS_MAX_BAK_IDX=380, MGBE_MAX_BAK_IDX, coreX,...etc) backup registers. + * (EQOS_MAX_BAK_IDX=380, coreX,...etc) backup registers. */ #define CORE_MAX_BAK_IDX 700U diff --git a/include/osi_dma.h b/include/osi_dma.h index 9379303..0f459c5 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -940,4 +940,17 @@ int osi_dma_get_systime_from_mac( unsigned int *sec, unsigned int *nsec); +/** + * @brief osi_is_mac_enabled - Checks if MAC is enabled. + * + * Algorithm: Reads MAC MCR register for Tx and Rx enabled bits. + * + * @param[in] osi_dma: OSI DMA private data structure. + * + * @note MAC should be init and started. see osi_start_mac() + * + * @retval OSI_ENABLE if MAC enabled. + * @retval OSI_DISABLE otherwise. + */ +unsigned int osi_is_mac_enabled(struct osi_dma_priv_data *const osi_dma); #endif /* OSI_DMA_H */ diff --git a/osi/common/eqos_common.c b/osi/common/eqos_common.c index 6c07cb9..9403c06 100644 --- a/osi/common/eqos_common.c +++ b/osi/common/eqos_common.c @@ -56,3 +56,17 @@ unsigned long long eqos_get_systime_from_mac(void *addr) return ns; } + +unsigned int eqos_is_mac_enabled(void *addr) +{ + unsigned int enable = OSI_DISABLE; + unsigned int reg; + + reg = osi_readl((unsigned char *)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 index 98a96ec..c3124e6 100644 --- a/osi/common/eqos_common.h +++ b/osi/common/eqos_common.h @@ -34,6 +34,15 @@ #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 * @@ -49,4 +58,18 @@ */ unsigned long long eqos_get_systime_from_mac(void *addr); +/** + * @brief eqos_is_mac_enabled - Checks if MAC is enabled or not. + * + * Algorithm: Reads MAC MCR register for Tx and Rx enabled bits. + * + * @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 OSI_ENABLE if MAC enabled. + * @retval OSI_DISABLE otherwise. + */ +unsigned int eqos_is_mac_enabled(void *addr); #endif /* EQOS_COMMON_H */ diff --git a/osi/common/include/local_common.h b/osi/common/include/local_common.h index a2dbdbe..9339b31 100644 --- a/osi/common/include/local_common.h +++ b/osi/common/include/local_common.h @@ -43,4 +43,18 @@ void common_get_systime_from_mac(void *addr, unsigned int mac, unsigned int *sec, unsigned int *nsec); +/** + * @brief common_is_mac_enabled - Checks if MAC is enabled or not. + * + * Algorithm: Reads MAC register for Tx and Rx enabled bits. + * + * @param[in] addr: Address of base register. + * @param[in] mac: MAC HW type. + * + * @note MAC should be init and started. see osi_start_mac() + * + * @retval OSI_ENABLE if MAC enabled. + * @retval OSI_DISABLE otherwise. + */ +unsigned int common_is_mac_enabled(void *addr, unsigned int mac); #endif /* LOCAL_COMMON_H */ diff --git a/osi/common/osi_common.c b/osi/common/osi_common.c index 80cf1d5..c17c36f 100644 --- a/osi/common/osi_common.c +++ b/osi/common/osi_common.c @@ -191,3 +191,13 @@ void common_get_systime_from_mac(void *addr, unsigned int mac, /* do nothing here */ } } + +unsigned int common_is_mac_enabled(void *addr, unsigned int mac) +{ + if (mac == OSI_MAC_HW_EQOS) { + return eqos_is_mac_enabled(addr); + } else { + /* Non EQOS HW is supported yet */ + return OSI_DISABLE; + } +} diff --git a/osi/dma/libnvethernetcl.export b/osi/dma/libnvethernetcl.export index e54e368..e66a979 100644 --- a/osi/dma/libnvethernetcl.export +++ b/osi/dma/libnvethernetcl.export @@ -42,3 +42,4 @@ osi_validate_dma_regs osi_config_slot_function osi_clear_tx_pkt_err_stats osi_dma_get_systime_from_mac +osi_is_mac_enabled diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 200efc1..9c9485b 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -426,3 +426,12 @@ int osi_dma_get_systime_from_mac(struct osi_dma_priv_data *const osi_dma, return 0; } + +unsigned int osi_is_mac_enabled(struct osi_dma_priv_data *const osi_dma) +{ + if ((osi_dma != OSI_NULL) && (osi_dma->base != OSI_NULL)) { + return common_is_mac_enabled(osi_dma->base, osi_dma->mac); + } else { + return OSI_DISABLE; + } +} From ae58a6993c1132d338a23a1677899a9a8518ff6a Mon Sep 17 00:00:00 2001 From: Nagarjuna Kristam <nkristam@nvidia.com> Date: Wed, 9 Sep 2020 15:24:20 +0530 Subject: [PATCH 115/458] osi: update function headers Update doxygen comments for functions with below info - Use Algorithm inside @note - All numberical usages(like 1),2)..) with '-' - Add API group, Classification and Traceability note sections for all external interface functions. Bug 200671362 Change-Id: I762df388659f4be75952b7050c7ae03489a086b8 Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2407423 Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2422284 Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: Rakesh Goyal <rgoyal@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osd.h | 35 +- include/osi_common.h | 73 ++- include/osi_core.h | 981 +++++++++++++++++++++++++----- include/osi_dma.h | 633 +++++++++++++++---- osi/common/eqos_common.h | 12 +- osi/common/include/local_common.h | 8 +- osi/common/osi_common.c | 10 +- osi/core/eqos_core.c | 667 +++++++++++--------- osi/core/eqos_mmc.c | 36 +- osi/core/eqos_mmc.h | 26 +- osi/core/osi_core.c | 18 +- osi/dma/eqos_dma.c | 169 +++-- osi/dma/eqos_dma.h | 4 - osi/dma/osi_dma_local.h | 8 +- osi/dma/osi_dma_txrx.c | 102 ++-- 15 files changed, 2016 insertions(+), 766 deletions(-) diff --git a/include/osd.h b/include/osd.h index 9543f67..6671501 100644 --- a/include/osd.h +++ b/include/osd.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -45,10 +45,13 @@ void osd_udelay(unsigned long usec); /** * @brief osd_receive_packet - Handover received packet to network stack. * + * @note * Algorithm: - * 1) Unmap the DMA buffer address (not needed if buffers are allocated statically). - * 2) Refill the Rx ring based on threshold. - * 3) Consume the flag information and take decision to hand over the packet and related information to OS network stack. + * - Unmap the DMA buffer address (not needed if buffers are + * allocated statically). + * - Refill the Rx ring based on threshold. + * - Consume the flag information and take decision to hand over the packet + * and related information to OS network stack. * * @param[in] priv: OSD private data structure. * @param[in] rxring: Pointer to DMA channel Rx ring. @@ -57,7 +60,7 @@ void osd_udelay(unsigned long usec); * @param[in] rxpkt_cx: Received packet context. * @param[in] rx_pkt_swcx: Received packet sw context. * - * @note Rx completion need to make sure that Rx descriptors processed properly. + * @pre Rx completion need to make sure that Rx descriptors processed properly. */ void osd_receive_packet(void *priv, void *rxring, unsigned int chan, unsigned int dma_buf_len, void *rxpkt_cx, @@ -66,24 +69,26 @@ void osd_receive_packet(void *priv, void *rxring, unsigned int chan, /** * @brief osd_transmit_complete - Transmit completion routine. * + * @note * Algorithm: - * 1) Unmap and free the buffer DMA address and buffer (not needed if buffers are allocated statically). - * 2) Time stamp will be updated to stack if available. + * - Unmap and free the buffer DMA address and buffer (not needed if buffers + * are allocated statically). + * - Time stamp will be updated to stack if available. * * @param[in] priv: OSD private data structure. * @param[in] buffer: Buffer address to free. * @param[in] dmaaddr: DMA address to unmap. * @param[in] len: Length of data. * @param[in] txdone_pkt_cx: Pointer to struct which has tx done status info. - * This struct has flags to indicate tx error, whether DMA address - * is mapped from paged/linear buffer, Time stamp availability, - * if TS available txdone_pkt_cx->ns stores the time stamp. - * Below are the valid bit maps set for txdone_pkt_cx->flags - * OSI_TXDONE_CX_PAGED_BUF OSI_BIT(0) - * OSI_TXDONE_CX_ERROR OSI_BIT(1) - * OSI_TXDONE_CX_TS OSI_BIT(2) + * This struct has flags to indicate tx error, whether DMA address + * is mapped from paged/linear buffer, Time stamp availability, + * if TS available txdone_pkt_cx->ns stores the time stamp. + * Below are the valid bit maps set for txdone_pkt_cx->flags + * OSI_TXDONE_CX_PAGED_BUF OSI_BIT(0) + * OSI_TXDONE_CX_ERROR OSI_BIT(1) + * OSI_TXDONE_CX_TS OSI_BIT(2) * - * @note Tx completion need to make sure that Tx descriptors processed properly. + * @pre Tx completion need to make sure that Tx descriptors processed properly. */ void osd_transmit_complete(void *priv, void *buffer, unsigned long dmaaddr, unsigned int len, void *txdone_pkt_cx); diff --git a/include/osi_common.h b/include/osi_common.h index d41dfa9..4a83e83 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -683,7 +683,9 @@ struct osi_hw_features { /** * @brief osi_lock_init - Initialize lock to unlocked state. * - * Algorithm: Set lock to unlocked state. + * @note + * Algorithm: + * - Set lock to unlocked state. * * @param[in] lock - Pointer to lock to be initialized */ @@ -695,12 +697,15 @@ static inline void osi_lock_init(unsigned int *lock) /** * @brief osi_lock_irq_enabled - Spin lock. Busy loop till lock is acquired. * - * Algorithm: Atomic compare and swap operation till lock is held. + * @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 + * - 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. */ static inline void osi_lock_irq_enabled(unsigned int *lock) { @@ -718,12 +723,15 @@ static inline void osi_lock_irq_enabled(unsigned int *lock) /** * @brief osi_unlock_irq_enabled - Release lock. * - * Algorithm: Atomic compare and swap operation to 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 + * - Does not disable irq. Do not call this API to release any + * lock that is shared between top/bottom half. */ static inline void osi_unlock_irq_enabled(unsigned int *lock) { @@ -738,7 +746,7 @@ static inline void osi_unlock_irq_enabled(unsigned int *lock) * * @param[in] addr: Memory mapped address. * - * @note Physical address has to be memmory mapped. + * @pre Physical address has to be memmory mapped. * * @return Data from memory mapped register - success. */ @@ -753,7 +761,7 @@ static inline unsigned int osi_readl(void *addr) * @param[in] val: Value to be written. * @param[in] addr: Memory mapped address. * - * @note Physical address has to be memmory mapped. + * @pre Physical address has to be memmory mapped. */ static inline void osi_writel(unsigned int val, void *addr) { @@ -785,7 +793,9 @@ static inline int is_valid_mac_version(unsigned int mac_ver) * @brief osi_update_stats_counter - update value by increment passed * as parameter * - * Algorithm: Check for boundary and return sum + * @note + * Algorithm: + * - Check for boundary and return sum * * @param[in] last_value: last value of stat counter * @param[in] incr: increment value @@ -810,12 +820,31 @@ static inline unsigned long osi_update_stats_counter(unsigned long last_value, /** * @brief osi_get_mac_version - Reading MAC version * - * Algorithm: Reads MAC version and check whether its valid or not. + * @note + * Algorithm: + * - Reads MAC version and check whether its valid or not. * * @param[in] addr: io-remap MAC base address. * @param[in] mac_ver: holds mac version. * - * @note MAC has to be out of reset. + * @pre MAC has to be out of reset. + * + * @note + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_020 + * + * @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. @@ -828,7 +857,25 @@ int osi_get_mac_version(void *addr, unsigned int *mac_ver); * @param[in] base: io-remap MAC base address. * @param[in] hw_feat: holds the supported features of the hardware. * - * @note MAC has to be out of reset. + * @pre MAC has to be out of reset. + * + * @note + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_021 + * + * @note + * Classification: + * - Interrupt: No + * - Signal handler: No + * - Thread safe: No + * - Required Privileges: None + * + * @note + * API Group: + * - Initialization: No + * - Run time: Yes + * - De-initialization: No + * */ void osi_get_hw_features(void *base, struct osi_hw_features *hw_feat); /** diff --git a/include/osi_core.h b/include/osi_core.h index 317b15e..0fa01c5 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -412,12 +412,31 @@ struct osi_core_priv_data { /** * @brief osi_poll_for_mac_reset_complete - Poll Software reset bit in MAC HW * - * Algorithm: Invokes EQOS routine to check for SWR (software reset) - * bit in DMA Basic mode register to make sure IP reset was successful. + * @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. * - * @note MAC needs to be out of reset and proper clock configured. + * @pre MAC needs to be out of reset and proper clock configured. + * + * @note + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_004 + * + * @note + * Classification: + * - Interrupt: No + * - Signal handler: No + * - Thread safe: No + * - Required Privileges: None + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: No + * - De-initialization: No * * @retval 0 on success * @retval -1 on failure. @@ -429,8 +448,10 @@ int osi_poll_for_mac_reset_complete( /** * @brief osi_set_mdc_clk_rate - Derive MDC clock based on provided AXI_CBB clk. * - * Algorithm: MDC clock rate will be populated in OSI core private data - * structure based on AXI_CBB clock rate. + * @note + * Algorithm: + * - MDC clock rate will be populated in OSI core private data + * structure based on AXI_CBB clock rate. * * @param[in] osi_core: OSI core private data structure. * @param[in] csr_clk_rate: CSR (AXI CBB) clock rate. @@ -438,6 +459,23 @@ int osi_poll_for_mac_reset_complete( * @note OSD layer needs get the AXI CBB clock rate with OSD clock API * (ex - clk_get_rate()) * + * @note + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_005 + * + * @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. */ @@ -447,18 +485,37 @@ int osi_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, /** * @brief osi_hw_core_init - EQOS MAC, MTL and common DMA initialization. * - * Algorithm: Invokes EQOS MAC, MTL and common DMA register init code. + * @note + * Algorithm: + * - Invokes EQOS MAC, MTL and common DMA register init code. * * @param[in] 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 - * 1) MAC should be out of reset. See osi_poll_for_mac_reset_complete() - * 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. + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_006 + * + * @note + * Classification: + * - Interrupt: No + * - Signal handler: No + * - Thread safe: No + * - Required Privileges: None + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: No + * - De-initialization: No * * @retval 0 on success * @retval -1 on failure. @@ -469,12 +526,31 @@ int osi_hw_core_init(struct osi_core_priv_data *const osi_core, /** * @brief osi_hw_core_deinit - EQOS MAC deinitialization. - * - * Algorithm: Stops MAC transmisson and reception. + * + * @note + * Algorithm: + * - Stops MAC transmission and reception. * * @param[in] osi_core: OSI core private data structure. * - * @note MAC has to be out of reset. + * @pre MAC has to be out of reset. + * + * @note + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_007 + * + * @note + * Classification: + * - Interrupt: No + * - Signal handler: No + * - Thread safe: No + * - Required Privileges: None + * + * @note + * API Group: + * - Initialization: No + * - Run time: No + * - De-initialization: Yes * * @retval 0 on success * @retval -1 on failure. @@ -484,17 +560,36 @@ int osi_hw_core_deinit(struct osi_core_priv_data *const osi_core); /** * @brief osi_validate_core_regs - Read-validate HW registers for func safety. * - * Algorithm: Reads pre-configured list of MAC/MTL configuration registers - * and compares with last written value for any modifications. + * @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 iff (osi_core_priv_data->safety_config != OSI_NULL) + * * @note - * 1) MAC has to be out of reset. - * 2) 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. - * 3) Invoke this call iff (osi_core_priv_data->safety_config != OSI_NULL) + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_037 + * + * @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. @@ -504,12 +599,31 @@ int osi_validate_core_regs(struct osi_core_priv_data *const osi_core); /** * @brief osi_start_mac - Start MAC Tx/Rx engine * - * Algorithm: Enable MAC Tx and Rx engine. + * @note + * Algorithm: + * - Enable MAC Tx and Rx engine. * * @param[in] osi_core: OSI core private data structure. * - * @note MAC init should be complete. See osi_hw_core_init() and - * osi_hw_dma_init() + * @pre MAC init should be complete. See osi_hw_core_init() and + * osi_hw_dma_init() + * + * @note + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_008 + * + * @note + * Classification: + * - Interrupt: No + * - Signal handler: No + * - Thread safe: No + * - Required Privileges: None + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: No + * - De-initialization: No * * @retval 0 on success * @retval -1 on failure. @@ -519,11 +633,30 @@ int osi_start_mac(struct osi_core_priv_data *const osi_core); /** * @brief osi_stop_mac - Stop MAC Tx/Rx engine * - * Algorithm: Stop MAC Tx and Rx engine + * @note + * Algorithm: + * - Stop MAC Tx and Rx engine * * @param[in] osi_core: OSI core private data structure. * - * @note MAC DMA deinit should be complete. See osi_hw_dma_deinit() + * @pre MAC DMA deinit should be complete. See osi_hw_dma_deinit() + * + * @note + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_009 + * + * @note + * Classification: + * - Interrupt: No + * - Signal handler: No + * - Thread safe: No + * - Required Privileges: None + * + * @note + * API Group: + * - Initialization: No + * - Run time: No + * - De-initialization: Yes * * @retval 0 on success * @retval -1 on failure. @@ -533,12 +666,31 @@ int osi_stop_mac(struct osi_core_priv_data *const osi_core); /** * @brief osi_common_isr - Common ISR. * - * Algorithm: Takes care of handling the common interrupts accordingly as per - * the MAC IP + * @note + * Algorithm: + * - Takes care of handling the common interrupts accordingly as per + * the MAC IP * * @param[in] osi_core: OSI core private data structure. * - * @note MAC should be init and started. see osi_start_mac() + * @pre MAC should be init and started. see osi_start_mac() + * + * @note + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_010 + * + * @note + * Classification: + * - Interrupt: Yes + * - Signal handler: Yes + * - 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. @@ -548,12 +700,31 @@ int osi_common_isr(struct osi_core_priv_data *const osi_core); /** * @brief osi_set_mode - Set FD/HD mode. * - * Algorithm: Takes care of setting HD or FD mode accordingly as per the MAC IP + * @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. * - * @note MAC should be init and started. see osi_start_mac() + * @pre MAC should be init and started. see osi_start_mac() + * + * @note + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_011 + * + * @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. @@ -564,13 +735,32 @@ int osi_set_mode(struct osi_core_priv_data *const osi_core, /** * @brief osi_set_speed - Set operating speed. * - * Algorithm: Takes care of setting the operating speed accordingly as per - * the MAC IP. + * @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. * - * @note MAC should be init and started. see osi_start_mac() + * @pre MAC should be init and started. see osi_start_mac() + * + * @note + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_012 + * + * @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. @@ -581,15 +771,34 @@ int osi_set_speed(struct osi_core_priv_data *const osi_core, /** * @brief osi_pad_calibrate - PAD calibration * - * Algorithm: Takes care of doing the pad calibration - * accordingly as per the MAC IP. + * @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. + * - RGMII and MDIO interface needs to be IDLE before performing PAD + * calibration. + * * @note - * 1) MAC should out of reset and clocks enabled. - * 2) RGMII and MDIO interface needs to be IDLE before performing PAD - * calibration. + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_013 + * + * @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. @@ -599,14 +808,33 @@ int osi_pad_calibrate(struct osi_core_priv_data *const osi_core); /** * @brief osi_flush_mtl_tx_queue - Flushing a MTL Tx Queue. * - * Algorithm: Invokes EQOS flush Tx queue routine. + * @note + * Algorithm: + * - Invokes EQOS flush Tx queue routine. * * @param[in] osi_core: OSI core private data structure. * @param[in] qinx: MTL queue index. * + * @pre + * - MAC should out of reset and clocks enabled. + * - hw core initialized. see osi_hw_core_init(). + * * @note - * 1) MAC should out of reset and clocks enabled. - * 2) hw core initialized. see osi_hw_core_init(). + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_014 + * + * @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. @@ -617,12 +845,31 @@ int osi_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, /** * @brief osi_config_mac_loopback - Configure MAC loopback * - * Algorithm: Configure the MAC to support the 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 * - * @note MAC should be init and started. see osi_start_mac() + * @pre MAC should be init and started. see osi_start_mac() + * + * @note + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_015 + * + * @note + * Classification: + * - Interrupt: No + * - Signal handler: No + * - Thread safe: No + * - Required Privileges: None + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: No + * - De-initialization: No * * @retval 0 on success * @retval -1 on failure. @@ -633,15 +880,34 @@ int osi_config_mac_loopback(struct osi_core_priv_data *const osi_core, /** * @brief osi_set_avb - Set CBS algo and parameters * - * Algorithm: Set AVB algo and populated parameter from osi_core_avb - * structure for TC/TQ + * @note + * Algorithm: + * - Set AVB algo and populated parameter from osi_core_avb + * structure for TC/TQ * * @param[in] osi_core: OSI core private data structure. * @param[in] avb: osi core avb data structure. * + * @pre + * - MAC should be init and started. see osi_start_mac() + * - osi_core->osd should be populated. + * * @note - * 1) MAC should be init and started. see osi_start_mac() - * 2) osi_core->osd should be populated. + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_016 + * + * @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. @@ -652,15 +918,34 @@ int osi_set_avb(struct osi_core_priv_data *const osi_core, /** * @brief osi_get_avb - Get CBS algo and parameters * - * Algorithm: get AVB algo and populated parameter from osi_core_avb - * structure for TC/TQ + * @note + * Algorithm: + * - get AVB algo and populated parameter from osi_core_avb + * structure for TC/TQ * * @param[in] osi_core: OSI core private data structure. * @param[out] avb: osi core avb data structure. * + * @pre + * - MAC should be init and started. see osi_start_mac() + * - osi_core->osd should be populated. + * * @note - * 1) MAC should be init and started. see osi_start_mac() - * 2) osi_core->osd should be populated. + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_017 + * + * @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. @@ -671,13 +956,32 @@ int osi_get_avb(struct osi_core_priv_data *const osi_core, /** * @brief osi_configure_txstatus - Configure Tx packet status reporting * - * Algorithm: Configure MAC to enable/disable Tx status error - * reporting. + * @note + * Algorithm: + * - Configure MAC to enable/disable Tx status error + * reporting. * * @param[in] osi_core: OSI core private data structure. * @param[in] tx_status: Enable or disable tx packet status reporting * - * @note MAC should be init and started. see osi_start_mac() + * @pre MAC should be init and started. see osi_start_mac() + * + * @note + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_018 + * + * @note + * Classification: + * - Interrupt: No + * - Signal handler: No + * - Thread safe: No + * - Required Privileges: None + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: No + * - De-initialization: No * * @retval 0 on success * @retval -1 on failure. @@ -688,13 +992,32 @@ int osi_configure_txstatus(struct osi_core_priv_data *const osi_core, /** * @brief osi_config_fw_err_pkts - Configure forwarding of error packets * - * Algorithm: Configure MAC to enable/disable 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 * @param[in] fw_err: Enable or disable forwarding of error packets * - * @note MAC should be init and started. see osi_start_mac() + * @pre MAC should be init and started. see osi_start_mac() + * + * @note + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_029 + * + * @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. @@ -705,14 +1028,33 @@ int osi_config_fw_err_pkts(struct osi_core_priv_data *const osi_core, /** * @brief osi_config_rx_crc_check - Configure CRC Checking for Received Packets * - * 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. + * @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 * - * @note MAC should be init and started. see osi_start_mac() + * @pre MAC should be init and started. see osi_start_mac() + * + * @note + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_019 + * + * @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. @@ -723,14 +1065,33 @@ int osi_config_rx_crc_check(struct osi_core_priv_data *const osi_core, /** * @brief osi_configure_flow_ctrl - Configure flow control settings * - * Algorithm: This will enable or disable the flow control. - * flw_ctrl BIT0 is for tx flow ctrl enable/disable - * flw_ctrl BIT1 is for rx flow ctrl enable/disable + * @note + * Algorithm: + * - This will enable or disable the flow control. + * flw_ctrl BIT0 is for tx flow ctrl enable/disable + * flw_ctrl BIT1 is for rx flow ctrl enable/disable * * @param[in] osi_core: OSI core private data structure. * @param[in] flw_ctrl: Enable or disable flow control settings * - * @note MAC should be init and started. see osi_start_mac() + * @pre MAC should be init and started. see osi_start_mac() + * + * @note + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_024 + * + * @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. @@ -742,15 +1103,34 @@ int osi_configure_flow_control( /** * @brief osi_config_arp_offload - Configure ARP offload in MAC. * - * Algorithm: Invokes EQOS config ARP offload routine. + * @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 - * 1) MAC should be init and started. see osi_start_mac() - * 2) Valid 4 byte IP address as argument ip_addr + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_022 + * + * @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. @@ -762,12 +1142,31 @@ int osi_config_arp_offload(struct osi_core_priv_data *const osi_core, /** * @brief osi_config_rxcsum_offload - Configure RX checksum offload in MAC. * - * Algorithm: Invokes EQOS config RX checksum offload routine. + * @note + * Algorithm: + * - Invokes EQOS config RX checksum offload routine. * * @param[in] osi_core: OSI core private data structure. * @param[in] enable: Enable/disable flag. * - * @note MAC should be init and started. see osi_start_mac() + * @pre MAC should be init and started. see osi_start_mac() + * + * @note + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_023 + * + * @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. @@ -779,15 +1178,34 @@ int osi_config_rxcsum_offload( /** * @brief osi_l2_filter - configure L2 mac filter. * - * 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 + * @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 - * 1) MAC should be initialized and started. see osi_start_mac() + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_025 + * + * @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. @@ -798,17 +1216,36 @@ int osi_l2_filter(struct osi_core_priv_data *const osi_core, /** * @brief osi_config_vlan_filtering - OSI call for configuring VLAN filter * - * Algorithm: This sequence is used to enable/disable VLAN filtering and - * also selects VLAN filtering mode- perfect/hash + * @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 private data structure. * @param[in] filter_enb_dis: vlan filter enable(1) disable(0) * @param[in] perfect_hash_filtering: perfect(0) or hash filter(1) * @param[in] perfect_inverse_match: normal(0) or inverse filter(1) * + * @pre + * - MAC should be init and started. see osi_start_mac() + * - osi_core->osd should be populated + * * @note - * 1) MAC should be init and started. see osi_start_mac() - * 2) osi_core->osd should be populated + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_027 + * + * @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. @@ -822,12 +1259,31 @@ int osi_config_vlan_filtering( /** * @brief osi_update_vlan_id - invoke osi call to update VLAN ID * - * Algorithm: return 16 bit VLAN ID + * @note + * Algorithm: + * - return 16 bit VLAN ID * * @param[in] osi_core: OSI core private data structure. * @param[in] vid: VLAN ID * - * @note MAC should be init and started. see osi_start_mac() + * @pre MAC should be init and started. see osi_start_mac() + * + * @note + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_028 + * + * @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. @@ -838,22 +1294,40 @@ int osi_update_vlan_id(struct osi_core_priv_data *const osi_core, /** * @brief osi_write_phy_reg - Write to a PHY register through MAC over MDIO bus. * + * @note * Algorithm: - * 1) Before proceeding for reading for PHY register check whether any MII - * operation going on MDIO bus by polling MAC_GMII_BUSY bit. - * 2) Program data into MAC MDIO data register. - * 3) 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. - * 4) Write into MAC MDIO address register poll for GMII busy for MDIO - * operation to complete. + * - 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. * - * @note MAC should be init and started. see osi_start_mac() + * @pre MAC should be init and started. see osi_start_mac() + * + * @note + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_002 + * + * @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. @@ -866,14 +1340,33 @@ int osi_write_phy_reg(struct osi_core_priv_data *const osi_core, * @brief osi_read_mmc - invoke function to read actual registers and update * structure variable mmc * - * Algorithm: Read the registers, mask reserve bits if required, update - * structure. + * @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 - * 1) MAC should be init and started. see osi_start_mac() - * 2) osi_core->osd should be populated + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_035 + * + * @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. @@ -884,14 +1377,33 @@ int osi_read_mmc(struct osi_core_priv_data *const osi_core); * @brief osi_reset_mmc - invoke function to reset MMC counter and data * structure * - * Algorithm: Read the registers, mask reserve bits if required, update - * structure. + * @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 - * 1) MAC should be init and started. see osi_start_mac() - * 2) osi_core->osd should be populated + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_036 + * + * @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. @@ -901,21 +1413,39 @@ int osi_reset_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: - * 1) Before proceeding for reading for PHY register check whether any MII - * operation going on MDIO bus by polling MAC_GMII_BUSY bit. - * 2) 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. - * 3) 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. + * - 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. * - * @note MAC should be init and started. see osi_start_mac() + * @pre MAC should be init and started. see osi_start_mac() + * + * @note + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_003 + * + * @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 data from PHY register on success * @retval -1 on failure @@ -931,19 +1461,56 @@ int osi_read_phy_reg(struct osi_core_priv_data *const osi_core, * * @retval data from PHY register on success * @retval -1 on failure + * + * @note + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_001 + * + * @note + * Classification: + * - Interrupt: No + * - Signal handler: No + * - Thread safe: No + * - Required Privileges: None + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: No + * - De-initialization: No + * */ int osi_init_core_ops(struct osi_core_priv_data *const osi_core); /** * @brief osi_set_systime_to_mac - Handles setting of system time. * - * Algorithm: Set current system time to MAC. + * @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. * - * @note MAC should be init and started. see osi_start_mac() + * @pre MAC should be init and started. see osi_start_mac() + * + * @note + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_034 + * + * @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. @@ -954,14 +1521,33 @@ int osi_set_systime_to_mac(struct osi_core_priv_data *const osi_core, /** * @brief osi_adjust_freq - Adjust frequency * - * 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. + * @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 * - * @note MAC should be init and started. see osi_start_mac() + * @pre MAC should be init and started. see osi_start_mac() + * + * @note + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_033 + * + * @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. @@ -971,15 +1557,34 @@ int osi_adjust_freq(struct osi_core_priv_data *const osi_core, int ppb); /** * @brief osi_adjust_time - Adjust MAC time with system time * - * Algorithm: Adjust/update the MAC time (delta time from MAC to system time - * passed in nanoseconds, can be + or -). + * @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 - * 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 + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_032 + * + * @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. @@ -990,13 +1595,32 @@ int osi_adjust_time(struct osi_core_priv_data *const osi_core, /** * @brief osi_get_systime_from_mac - Get system time * - * Algorithm: Gets the current system time + * @note + * Algorithm: + * - Gets the current system time * * @param[in] osi_core: OSI core private data structure. * @param[out] sec: Value read in Seconds * @param[out] nsec: Value read in Nano seconds * - * @note MAC should be init and started. see osi_start_mac() + * @pre MAC should be init and started. see osi_start_mac() + * + * @note + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_031 + * + * @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. @@ -1008,23 +1632,42 @@ int osi_get_systime_from_mac( /** * @brief osi_ptp_configuration - Configure PTP * - * Algorithm: Configure the PTP registers that are required for 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 - * 1) MAC should be init and started. see osi_start_mac() - * 2) 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. - * 3) osi->ptp_config.ptp_clock need to be filled with the ptp system clk. - * Currently it is set to 62500000Hz. - * 4) osi->ptp_config.ptp_ref_clk_rate need to be filled with the ptp - * reference clock that platform supports. - * 5) osi->ptp_config.sec need to be filled with current time of seconds - * 6) osi->ptp_config.nsec need to be filled with current time of nseconds - * 7) osi->base need to be filled with the ioremapped base address + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_030 + * + * @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. @@ -1044,26 +1687,45 @@ void *eqos_get_core_safety_config(void); * @brief osi_l3l4_filter - invoke OSI call to add L3/L4 * filters. * - * 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. + * @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] 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)) + * 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 * @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 - * 1) MAC should be init and started. see osi_start_mac() - * 2) Concurrent invocations to configure filters is not supported. - * OSD driver shall serialize calls. + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_026 + * + * @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. @@ -1078,15 +1740,34 @@ int osi_l3l4_filter(struct osi_core_priv_data *const osi_core, /** * @brief osi_configure_eee - Configure EEE LPI in MAC. * - * Algorithm: This routine invokes configuration of EEE LPI in the 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) + * OSI_MAX_TX_LPI_TIMER (in steps of 8usec) + * + * @pre + * - MAC and PHY should be init and started. see osi_start_mac() * * @note - * 1) MAC and PHY should be init and started. see osi_start_mac() + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_038 + * + * @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. @@ -1100,10 +1781,10 @@ int osi_configure_eee(struct osi_core_priv_data *const osi_core, * * @param[in] osi_core: OSI core private data structure. * - * @note - * 1) MAC and PHY should be init and started. see osi_start_mac() - * 2) No further configuration change in MAC shall be done after invoking - * this API + * @pre + * - MAC and PHY should be init and started. see osi_start_mac() + * - No further configuration change in MAC shall be done after invoking + * this API * * @retval 0 on success * @retval -1 on failure. @@ -1115,8 +1796,8 @@ int osi_save_registers(struct osi_core_priv_data *const osi_core); * * @param[in] osi_core: OSI core private data structure. * - * @note - * 1) MAC and PHY should be init and started. see osi_start_mac() + * @pre + * - MAC and PHY should be init and started. see osi_start_mac() * * @retval 0 on success * @retval -1 on failure. diff --git a/include/osi_dma.h b/include/osi_dma.h index 0f459c5..3ee9bd8 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -470,17 +470,36 @@ struct osi_dma_priv_data { /** * @brief - Read-validate HW registers for func safety. * - * Algorithm: Reads pre-configured list of DMA configuration registers - * and compares with last written value for any modifications. + * @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 iff (osi_dma_priv_data->safety_config != OSI_NULL) + * * @note - * 1) MAC has to be out of reset. - * 2) 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. - * 3) Invoke this call iff (osi_dma_priv_data->safety_config != OSI_NULL) + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETCL_016 + * + * @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. @@ -490,16 +509,35 @@ int osi_validate_dma_regs(struct osi_dma_priv_data *osi_dma); /** * @brief osi_disable_chan_tx_intr - Disables DMA Tx channel interrupts. * - * Algorithm: Disables Tx interrupts at wrapper level. + * @note + * Algorithm: + * - Disables Tx interrupts at wrapper level. * * @param[in] osi_dma: DMA private data. * @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 + * OS Dependent layer and pass corresponding 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. + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETCL_001 + * + * @note + * Classification: + * - Interrupt: No + * - Signal handler: No + * - Thread safe: No + * - Required Privileges: None + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: Yes + * - De-initialization: Yes * * @retval 0 on success * @retval -1 on failure. @@ -510,16 +548,35 @@ int osi_disable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, /** * @brief osi_enable_chan_tx_intr - Enable DMA Tx channel interrupts. * - * Algorithm: Enables Tx interrupts at wrapper level. + * @note + * Algorithm: + * - Enables Tx interrupts at wrapper level. * * @param[in] osi_dma: DMA private data. * @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 + * OS Dependent layer and pass corresponding 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. + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETCL_002 + * + * @note + * Classification: + * - Interrupt: No + * - Signal handler: No + * - Thread safe: No + * - Required Privileges: None + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: Yes + * - De-initialization: Yes * * @retval 0 on success * @retval -1 on failure. @@ -530,16 +587,35 @@ int osi_enable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, /** * @brief osi_disable_chan_rx_intr - Disable DMA Rx channel interrupts. * - * Algorithm: Disables Rx interrupts at wrapper level. + * @note + * Algorithm: + * - Disables Rx interrupts at wrapper level. * * @param[in] osi_dma: DMA private data. * @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 + * OS Dependent layer and pass corresponding 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. + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETCL_003 + * + * @note + * Classification: + * - Interrupt: No + * - Signal handler: No + * - Thread safe: No + * - Required Privileges: None + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: Yes + * - De-initialization: Yes * * @retval 0 on success * @retval -1 on failure. @@ -550,16 +626,35 @@ int osi_disable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, /** * @brief osi_enable_chan_rx_intr - Enable DMA Rx channel interrupts. * - * Algorithm: Enables Rx interrupts at wrapper level. + * @note + * Algorithm: + * - Enables Rx interrupts at wrapper level. * * @param[in] osi_dma: DMA private data. * @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 + * OS Dependent layer and pass corresponding 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. + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETCL_004 + * + * @note + * Classification: + * - Interrupt: No + * - Signal handler: No + * - Thread safe: No + * - Required Privileges: None + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: Yes + * - De-initialization: Yes * * @retval 0 on success * @retval -1 on failure. @@ -608,14 +703,33 @@ int osi_clear_vm_rx_intr(struct osi_dma_priv_data *osi_dma, /** * @brief Start DMA * - * Algorithm: Start the DMA for specific MAC + * @note + * Algorithm: + * - Start the DMA for specific MAC * * @param[in] osi_dma: DMA private data. * @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 - * 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 + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETCL_005 + * + * @note + * Classification: + * - Interrupt: No + * - Signal handler: No + * - Thread safe: No + * - Required Privileges: None + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: No + * - De-initialization: No * * @retval 0 on success * @retval -1 on failure. @@ -626,14 +740,33 @@ int osi_start_dma(struct osi_dma_priv_data *osi_dma, /** * @brief osi_stop_dma - Stop DMA * - * Algorithm: Stop the DMA for specific MAC + * @note + * Algorithm: + * - Stop the DMA for specific MAC * * @param[in] osi_dma: DMA private data. * @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 - * 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 + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETCL_006 + * + * @note + * Classification: + * - Interrupt: No + * - Signal handler: No + * - Thread safe: No + * - Required Privileges: None + * + * @note + * API Group: + * - Initialization: No + * - Run time: No + * - De-initialization: Yes * * @retval 0 on success * @retval -1 on failure. @@ -644,12 +777,29 @@ int osi_stop_dma(struct osi_dma_priv_data *osi_dma, /** * @brief osi_get_refill_rx_desc_cnt - Rx descriptors count that needs to refill * - * Algorithm: subtract current index with fill (need to cleanup) - * to get 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 None. + * @note + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETCL_008 + * + * @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 "Number of available free descriptors." */ @@ -658,16 +808,35 @@ unsigned int osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring); /** * @brief osi_rx_dma_desc_init - DMA Rx descriptor init * - * Algorithm: Initialise a Rx DMA descriptor. + * @note + * Algorithm: + * - Initialise a Rx DMA descriptor. * * @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 * + * @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 - * 1) MAC needs to be out of reset and proper clocks need to be configured. - * 2) rx_swcx->buf_phy_addr need to be filled with DMA mapped address - * 3) DMA HW init need to be completed successfully, see osi_hw_dma_init + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETCL_007 + * + * @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. @@ -680,10 +849,27 @@ int osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, * * @param[in] osi_dma: OSI DMA private data struture. * + * @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 - * 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 + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETCL_009 + * + * @note + * Classification: + * - Interrupt: No + * - Signal handler: No + * - Thread safe: No + * - Required Privileges: None + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: No + * - De-initialization: No * * @retval 0 on success * @retval -1 on failure. @@ -693,49 +879,87 @@ int osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma); /** * @brief osi_hw_transmit - Initialize Tx DMA descriptors for a channel * - * 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. + * @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] osi: DMA private data. * @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 + * - 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 - * 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) DMA channel need to be started, see osi_start_dma - * 4) 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) - * 5) tx_pkt_cx->desc_cnt need to be populated which holds the number - * of swcx descriptors allocated for that packet - * 6) 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 + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETCL_010 + * + * @note + * Classification: + * - Interrupt: No + * - Signal handler: No + * - Thread safe: No + * - Required Privileges: None + * + * @note + * API Group: + * - Initialization: No + * - Run time: Yes + * - De-initialization: No + * */ void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan); /** * @brief osi_process_tx_completions - Process Tx complete on DMA channel ring. * - * Algorithm: This function will be invoked by OSD layer to process Tx - * complete interrupt. - * 1) First checks whether descriptor owned by DMA or not. - * 2) Invokes OSD layer to release DMA address and Tx buffer which are - * updated as part of transmit routine. + * @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] osi: OSI private data structure. * @param[in] chan: Channel number on which Tx complete need to be done. * @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 - * 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) DMA need to be started, see osi_start_dma + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETCL_011 + * + * @note + * Classification: + * - Interrupt: Yes + * - Signal handler: Yes + * - Thread safe: No + * - Required Privileges: None + * + * @note + * API Group: + * - Initialization: No + * - Run time: Yes + * - De-initialization: No * * @returns Number of decriptors (buffers) proccessed. */ @@ -745,26 +969,45 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi, /** * @brief osi_process_rx_completions - Read data from rx channel descriptors * - * Algorithm: This routine will be invoked by OSD layer to get the - * data from Rx descriptors and deliver the packet to the stack. - * 1) Checks descriptor owned by DMA or not. - * 2) If rx buffer is reserve buffer, reallocate receive buffer and - read next descriptor. - * 3) Get the length from Rx descriptor - * 4) Invokes OSD layer to deliver the packet to network stack. - * 5) Re-allocate the receive buffers, populate Rx descriptor and - * handover to DMA. + * @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] osi: OSI private data structure. * @param[in] chan: Rx DMA channel number * @param[in] budget: Threshould for reading the packets at a time. * @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). + * 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 - * 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) DMA need to be started, see osi_start_dma + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETCL_012 + * + * @note + * Classification: + * - Interrupt: Yes + * - Signal handler: Yes + * - Thread safe: No + * - Required Privileges: None + * + * @note + * API Group: + * - Initialization: No + * - Run time: Yes + * - De-initialization: No * * @returns Number of decriptors (buffers) proccessed. */ @@ -775,34 +1018,53 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, /** * @brief osi_hw_dma_init - Initialize DMA * - * Algorithm: Takes care of initializing the tx, rx ring and descriptors - * based on the number of channels selected. + * @note + * Algorithm: + * - Takes care of initializing the tx, rx ring and descriptors + * based on the number of channels selected. * * @param[in] osi_dma: DMA private data. * * + * @pre + * - Allocate memory for osi_dma + * - MAC needs to be out of reset and proper clocks need to be configured. + * - Numer 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 - * 1) Allocate memory for osi_dma - * 2) MAC needs to be out of reset and proper clocks need to be configured. - * 3) Numer of dma channels osi_dma->num_dma_chans - * 4) channel list osi_dma->dma_chan - * 5) base address osi_dma->base - * 6) allocate tx ring osi_dma->tx_ring[chan] for each channel - * based on TX_DESC_CNT (256) - * 7) allocate tx descriptors osi_dma->tx_ring[chan]->tx_desc for all - * channels and dma map it. - * 8) allocate tx sw descriptors osi_dma->tx_ring[chan]->tx_swcx for all - * channels - * 9) allocate rx ring osi_dma->rx_ring[chan] for each channel - * based on RX_DESC_CNT (256) - * 10) allocate rx descriptors osi_dma->rx_ring[chan]->rx_desc for all - * channels and dma map it. - * 11) allocate rx sw descriptors osi_dma->rx_ring[chan]->rx_swcx for all - * channels - * 12) osi_dma->use_riwt ==> OSI_DISABLE/OSI_ENABLE - * 13) osi_dma->rx_riwt ===> Actual value read from DT - * 14) osi_dma->use_rx_frames ==> OSI_DISABLE/OSI_ENABLE - * 15) osi_dma->rx_frames ===> Actual value read from DT + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETCL_013 + * + * @note + * Classification: + * - Interrupt: No + * - Signal handler: No + * - Thread safe: No + * - Required Privileges: None + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: No + * - De-initialization: No * * @retval 0 on success * @retval -1 on failure. @@ -812,13 +1074,32 @@ int osi_hw_dma_init(struct osi_dma_priv_data *osi_dma); /** * @brief osi_hw_dma_deinit - De initialize DMA * - * Algorithm: Takes care of stopping the MAC + * @note + * Algorithm: + * - Takes care of stopping the MAC * * @param[in] osi_dma: 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 - * 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 + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETCL_014 + * + * @note + * Classification: + * - Interrupt: No + * - Signal handler: No + * - Thread safe: No + * - Required Privileges: None + * + * @note + * API Group: + * - Initialization: No + * - Run time: No + * - De-initialization: Yes * * @retval 0 on success * @retval -1 on failure. @@ -830,7 +1111,23 @@ int osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma); * * @param[in] osi_dma: DMA private data. * - * @note None + * @note + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETCL_015 + * + * @note + * Classification: + * - Interrupt: No + * - Signal handler: No + * - Thread safe: No + * - Required Privileges: None + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: No + * - De-initialization: No + * * * @retval 0 on success * @retval -1 on failure. @@ -840,14 +1137,33 @@ int osi_init_dma_ops(struct osi_dma_priv_data *osi_dma); /** * @brief osi_clear_tx_pkt_err_stats - Clear tx packet error stats. * - * Algorithm: This function will be invoked by OSD layer to clear the - * tx stats mentioned in osi_dma->pkt_err_stats structure + * @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] 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 - * 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 + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETCL_018 + * + * @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. @@ -857,12 +1173,31 @@ int osi_clear_tx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); /** * @brief osi_config_slot_function - Configure slot function * - * Algorithm: Set or reset the slot function based on set input + * @note + * Algorithm: + * - Set or reset the slot function based on set input * * @param[in] osi_dma: OSI DMA private data structure. * @param[in] set: Flag to set with OSI_ENABLE and reset with OSI_DISABLE * - * @note MAC should be init and started. see osi_start_mac() + * @pre MAC should be init and started. see osi_start_mac() + * + * @note + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETCL_017 + * + * @note + * Classification: + * - Interrupt: No + * - Signal handler: No + * - Thread safe: No + * - Required Privileges: None + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: No + * - De-initialization: No * * @retval 0 on success * @retval -1 on failure. @@ -873,15 +1208,17 @@ int osi_config_slot_function(struct osi_dma_priv_data *osi_dma, /** * @brief osi_clear_rx_pkt_err_stats - Clear rx packet error stats. * - * Algorithm: This function will be invoked by OSD layer to clear the - * rx_crc_error mentioned in osi_dma->pkt_err_stats structure. + * @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] 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 + * @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 * * @retval 0 on success * @retval -1 on failure. @@ -891,15 +1228,17 @@ int osi_clear_rx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); /** * @brief osi_txring_empty - Check if Txring is empty. * - * 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. + * @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. * - * @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 + * @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 * * @retval 1 if ring is empty. * @retval 0 if ring has outstanding packets. @@ -924,13 +1263,32 @@ unsigned int osi_get_global_dma_status(struct osi_dma_priv_data *osi_dma); /** * @brief osi_dma_get_systime_from_mac - Get system time * - * Algorithm: Gets the current 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 * - * @note MAC should be init and started. see osi_start_mac() + * @pre MAC should be init and started. see osi_start_mac() + * + * @note + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETCL_019 + * + * @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. @@ -943,11 +1301,30 @@ int osi_dma_get_systime_from_mac( /** * @brief osi_is_mac_enabled - Checks if MAC is enabled. * - * Algorithm: Reads MAC MCR register for Tx and Rx enabled bits. + * @note + * Algorithm: + * - Reads MAC MCR register for Tx and Rx enabled bits. * * @param[in] osi_dma: OSI DMA private data structure. * - * @note MAC should be init and started. see osi_start_mac() + * @pre MAC should be init and started. see osi_start_mac() + * + * @note + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETCL_020 + * + * @note + * Classification: + * - Interrupt: No + * - Signal handler: No + * - Thread safe: No + * - Required Privileges: None + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: No + * - De-initialization: No * * @retval OSI_ENABLE if MAC enabled. * @retval OSI_DISABLE otherwise. diff --git a/osi/common/eqos_common.h b/osi/common/eqos_common.h index c3124e6..0b374f9 100644 --- a/osi/common/eqos_common.h +++ b/osi/common/eqos_common.h @@ -46,12 +46,10 @@ /** * @brief eqos_get_systime - 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. + * memory mapped IO region of the MAC. * - * @note MAC should be init and started. see osi_start_mac() + * @pre MAC should be init and started. see osi_start_mac() * * @retval 0 on success * @retval -1 on failure. @@ -61,12 +59,10 @@ unsigned long long eqos_get_systime_from_mac(void *addr); /** * @brief eqos_is_mac_enabled - Checks if MAC is enabled or not. * - * Algorithm: Reads MAC MCR register for Tx and Rx enabled bits. - * * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. + * memory mapped IO region of the MAC. * - * @note MAC should be init and started. see osi_start_mac() + * @pre MAC should be init and started. see osi_start_mac() * * @retval OSI_ENABLE if MAC enabled. * @retval OSI_DISABLE otherwise. diff --git a/osi/common/include/local_common.h b/osi/common/include/local_common.h index 9339b31..0f5b496 100644 --- a/osi/common/include/local_common.h +++ b/osi/common/include/local_common.h @@ -28,14 +28,12 @@ /** * @brief common_get_systime_from_mac - Get system time * - * Algorithm: Gets the current 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. * - * @note MAC should be init and started. see osi_start_mac() + * @pre MAC should be init and started. see osi_start_mac() * * @retval 0 on success * @retval -1 on failure. @@ -46,12 +44,10 @@ void common_get_systime_from_mac(void *addr, unsigned int mac, /** * @brief common_is_mac_enabled - Checks if MAC is enabled or not. * - * Algorithm: Reads MAC register for Tx and Rx enabled bits. - * * @param[in] addr: Address of base register. * @param[in] mac: MAC HW type. * - * @note MAC should be init and started. see osi_start_mac() + * @pre MAC should be init and started. see osi_start_mac() * * @retval OSI_ENABLE if MAC enabled. * @retval OSI_DISABLE otherwise. diff --git a/osi/common/osi_common.c b/osi/common/osi_common.c index c17c36f..4cca200 100644 --- a/osi/common/osi_common.c +++ b/osi/common/osi_common.c @@ -138,15 +138,17 @@ void osi_memset(void *s, unsigned int c, unsigned long count) /** *@brief div_u64_rem - updates remainder and returns Quotient * - * Algorithm: Dividend will be divided by divisor and stores the - * remainder value 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 * - * @note MAC IP should be out of reset and need to be initialized as the - * requirements + * @pre MAC IP should be out of reset and need to be initialized as the + * requirements * * @returns Quotient */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index b3fb982..5751acf 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -34,19 +34,20 @@ static struct core_func_safety eqos_core_safety_config; /** * @brief eqos_core_safety_writel - Write to safety critical register. * + * @note * Algorithm: - * 1) Acquire RW lock, so that eqos_validate_core_regs does not run while - * updating the safety critical register. - * 2) call osi_writel() to actually update the memory mapped register. - * 3) 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. + * - Acquire RW lock, so that eqos_validate_core_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_core_safety_config->reg_val[idx], + * so that this latest value will be compared when eqos_validate_core_regs + * is scheduled. * * @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. * - * @note MAC has to be out of reset, and clocks supplied. + * @pre MAC has to be out of reset, and clocks supplied. */ static inline void eqos_core_safety_writel(unsigned int val, void *addr, unsigned int idx) @@ -62,12 +63,14 @@ static inline void eqos_core_safety_writel(unsigned int val, void *addr, /** * @brief Initialize the eqos_core_safety_config. * - * Algorithm: Populate the list of safety critical registers and provide - * 1) the address of the register - * 2) Register mask (to ignore reserved/self-critical bits in the reg). - * See eqos_validate_core_regs which can be ivoked periodically to compare - * the last written value to this register vs the actual value read when - * eqos_validate_core_regs is scheduled. + * @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 ivoked 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. */ @@ -176,8 +179,10 @@ static void eqos_core_safety_init(struct osi_core_priv_data *const osi_core) /** * @brief Initialize the OSI core private data backup config array * - * Algorithm: Populate the list of core registers to be saved during suspend. - * Fill the address of each register in structure. + * @note + * 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. * @@ -292,17 +297,19 @@ static void eqos_core_backup_init(struct osi_core_priv_data *const osi_core) /** * @brief Read-validate HW registers for functional safety. * - * Algorithm: Reads pre-configured list of MAC/MTL configuration registers - * and compares with last written value for any modifications. + * @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. * - * @note - * 1) MAC has to be out of reset. - * 2) 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. - * 3) Invoke this call iff (osi_core_priv_data->safety_config != OSI_NULL) + * @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 iff (osi_core_priv_data->safety_config != OSI_NULL) * * @retval 0 on success * @retval -1 on failure. @@ -359,7 +366,7 @@ static int eqos_validate_core_regs(struct osi_core_priv_data *const osi_core) * memory mapped IO region of the MAC. * @param[in] flw_ctrl: flw_ctrl settings * - * @note MAC should be init and started. see osi_start_mac() + * @pre MAC should be initialized and started. see osi_start_mac() * * @retval 0 on success * @retval -1 on failure. @@ -421,15 +428,17 @@ static int eqos_config_flow_control(void *addr, /** * @brief eqos_config_rx_crc_check - Configure CRC Checking for Rx Packets * - * 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. + * @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] addr: Base address indicating the start of * memory mapped IO region of the MAC. * @param[in] crc_chk: Enable or disable checking of CRC field in received pkts * - * @note MAC should be init and started. see osi_start_mac() + * @pre MAC should be initialized and started. see osi_start_mac() * * @retval 0 on success * @retval -1 on failure. @@ -467,17 +476,19 @@ static int eqos_config_rx_crc_check(void *addr, /** * @brief eqos_config_fw_err_pkts - Configure forwarding of error packets * - * Algorithm: When this bit is reset, the Rx queue drops packets with - * error status (CRC error, GMII_ER, watchdog timeout, or overflow). - * When this bit is set, all packets except the runt error packets - * are forwarded to the application or DMA. + * @note + * Algorithm: + * - When this bit is reset, the Rx queue drops packets with + * error status (CRC error, GMII_ER, watchdog timeout, or overflow). + * When this 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] fw_err: Enable or Disable the forwarding of error packets * - * @note MAC should be init and started. see osi_start_mac() + * @pre MAC should be initialized and started. see osi_start_mac() * * @retval 0 on success * @retval -1 on failure. @@ -525,16 +536,18 @@ static int eqos_config_fw_err_pkts(void *addr, /** * @brief eqos_config_tx_status - Configure MAC to forward the tx pkt status * - * 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. + * @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] addr: Base address indicating the start of * memory mapped IO region of the MAC. * @param[in] tx_status: Enable or Disable the forwarding of tx pkt status * - * @note MAC should be init and started. see osi_start_mac() + * @pre MAC should be initialized and started. see osi_start_mac() * * @retval 0 on success * @retval -1 on failure. @@ -581,7 +594,7 @@ static int eqos_config_tx_status(void *addr, * 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() + * @pre MAC should be initialized and started. see osi_start_mac() * * @retval 0 on success * @retval -1 on failure. @@ -630,13 +643,15 @@ static int eqos_config_mac_loopback(void *addr, /** * @brief eqos_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. + * @note + * Algorithm: + * - CAR reset will be issued through MAC reset pin. + * Waits for SWR reset to be cleared in DMA Mode register. * * @param[in] addr: EQOS virtual base address. * @param[in] pre_si: Sets whether platform is Pre-silicon or not. * - * @note MAC needs to be out of reset and proper clock configured. + * @pre MAC needs to be out of reset and proper clock configured. * * @retval 0 on success * @retval -1 on failure. @@ -677,14 +692,16 @@ static int eqos_poll_for_swr(void *addr, unsigned int pre_si) /** * @brief eqos_set_mdc_clk_rate - Derive MDC clock based on provided AXI_CBB clk * - * Algorithm: MDC clock rate will be polulated OSI core private data structure - * based on AXI_CBB clock rate. + * @note + * Algorithm: + * - MDC clock rate will be polulated OSI core private data structure + * based on AXI_CBB clock rate. * * @param[in] osi_core: OSI core private data structure. * @param[in] csr_clk_rate: CSR (AXI CBB) clock rate. * - * @note OSD layer needs get the AXI CBB clock rate with OSD clock API - * (ex - clk_get_rate()) + * @pre OSD layer needs get the AXI CBB clock rate with OSD clock API + * (ex - clk_get_rate()) */ static void eqos_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, const unsigned long csr_clk_rate) @@ -720,13 +737,15 @@ static void eqos_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, /** * @brief eqos_set_speed - Set operating speed * - * Algorithm: Based on the speed (10/100/1000Mbps) MAC will be configured - * accordingly. + * @note + * Algorithm: + * - Based on the speed (10/100/1000Mbps) MAC will be configured + * accordingly. * * @param[in] base: EQOS virtual base address. * @param[in] speed: Operating speed. * - * @note MAC should be init and started. see osi_start_mac() + * @pre MAC should be initialized and started. see osi_start_mac() */ static void eqos_set_speed(void *base, const int speed) { @@ -759,13 +778,15 @@ static void eqos_set_speed(void *base, const int speed) /** * @brief eqos_set_mode - Set operating mode * - * Algorithm: Based on the mode (HALF/FULL Duplex) MAC will be configured - * accordingly. + * @note + * Algorithm: + * - Based on the mode (HALF/FULL Duplex) MAC will be configured + * accordingly. * * @param[in] base: EQOS virtual base address * @param[in] mode: Operating mode. * - * @note MAC should be init and started. see osi_start_mac() + * @pre MAC should be initialized and started. see osi_start_mac() */ static void eqos_set_mode(void *base, const int mode) { @@ -790,14 +811,16 @@ static void eqos_set_mode(void *base, const int mode) /** * @brief eqos_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. + * @note + * 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. + * @pre MAC has to be out of reset. * * @retval Queue size that need to be programmed. */ @@ -886,20 +909,22 @@ static unsigned int eqos_calculate_per_queue_fifo(unsigned int fifo_size, /** * @brief eqos_pad_calibrate - PAD calibration * + * @note * Algorithm: - * 1) Set field PAD_E_INPUT_OR_E_PWRD in reg ETHER_QOS_SDMEMCOMPPADCTRL_0 - * 2) Delay for 1 usec. - * 3)Set AUTO_CAL_ENABLE and AUTO_CAL_START in reg - * ETHER_QOS_AUTO_CAL_CONFIG_0 - * 4) Wait on AUTO_CAL_ACTIVE until it is 0 - * 5) Re-program the value PAD_E_INPUT_OR_E_PWRD in - * ETHER_QOS_SDMEMCOMPPADCTRL_0 to save power + * - 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] ioaddr: Base address of the MAC HW. * - * @note 1) MAC should out of reset and clocks enabled. - * 2) RGMII and MDIO interface needs to be IDLE before performing PAD - * calibration. + * @note + * - MAC should out of reset and clocks enabled. + * - RGMII and MDIO interface needs to be IDLE before performing PAD + * calibration. * * @retval 0 on success * @retval -1 on failure. @@ -969,9 +994,10 @@ calibration_failed: * @param[in] addr: 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(). - * + * @note + * - MAC should out of reset and clocks enabled. + * - hw core initialized. see osi_hw_core_init(). + * * @retval 0 on success * @retval -1 on failure. */ @@ -1019,9 +1045,11 @@ static int eqos_flush_mtl_tx_queue(void *addr, /** * @brief update_ehfc_rfa_rfd - Update EHFC, 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 and also enables HW flow control + * @note + * 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 and also enables HW flow control * * @param[in] rx_fifo: Rx FIFO size. * @param[in] value: Stores RFD and RSA values @@ -1113,21 +1141,23 @@ void update_ehfc_rfa_rfd(unsigned int rx_fifo, unsigned int *value) /** * @brief eqos_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 + * @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. - * - * @note MAC has to be out of reset. + * + * @pre MAC has to be out of reset. * * @retval 0 on success * @retval -1 on failure. @@ -1191,15 +1221,16 @@ static int eqos_configure_mtl_queue(unsigned int qinx, /** * @brief eqos_config_rxcsum_offload - Enable/Disale rx checksum offload in HW * + * @note * Algorithm: - * 1) Read the MAC configuration register. - * 2) Enable the IP checksum offload engine COE in MAC receiver. - * 3) Update the MAC configuration register. + * - Read the MAC configuration register. + * - Enable the IP checksum offload engine COE in MAC receiver. + * - Update the MAC configuration register. * * @param[in] addr: EQOS 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() + * @pre MAC should be initialized and started. see osi_start_mac() * * @retval 0 on success * @retval -1 on failure. @@ -1229,18 +1260,20 @@ static int eqos_config_rxcsum_offload(void *addr, /** * @brief eqos_configure_rxq_priority - Configure Priorities Selected in - * the Receive Queue + * the Receive Queue * - * 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. + * @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. * - * @note MAC has to be out of reset. + * @pre MAC has to be out of reset. */ static void eqos_configure_rxq_priority( struct osi_core_priv_data *const osi_core) @@ -1291,18 +1324,20 @@ static void eqos_configure_rxq_priority( /** * @brief eqos_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 JE/JD/WD/GPSLCE based on the MTU size - * 4) Enable Multicast and Broadcast Queue - * 5) Disable MMC interrupts and Configure the MMC counters - * 6) Enable required MAC interrupts + * @note + * Algorithm: + * - This takes care of configuring the below + * parameters for the MAC + * - Programming the MAC address + * - 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] osi_core: OSI core private data structure. * - * @note MAC has to be out of reset. + * @pre MAC has to be out of reset. */ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) { @@ -1432,15 +1467,17 @@ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) /** * @brief eqos_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 + * @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] base: EQOS virtual base address. * - * @note MAC has to be out of reset. + * @pre MAC has to be out of reset. */ static void eqos_configure_dma(void *base) { @@ -1468,18 +1505,21 @@ static void eqos_configure_dma(void *base) /** * @brief eqos_core_init - EQOS MAC, MTL and common DMA Initialization * - * Algorithm: This function will take care of initializing MAC, MTL and - * common DMA registers. + * @note + * 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_mac_reset_complete() + * @pre + * - MAC should be out of reset. See osi_poll_for_mac_reset_complete() * 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. + * - 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. * * @retval 0 on success * @retval -1 on failure. @@ -1564,13 +1604,15 @@ static int eqos_core_init(struct osi_core_priv_data *const osi_core, /** * @brief eqos_handle_mac_intrs - Handle MAC interrupts * - * Algorithm: This function takes care of handling the - * MAC interrupts which includes speed, mode detection. + * @note + * Algorithm: + * - This function takes care of handling the + * MAC interrupts 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 interrupts need to be enabled + * @pre MAC interrupts need to be enabled */ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, unsigned int dma_isr) @@ -1626,7 +1668,9 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, /** * @brief update_dma_sr_stats - stats for dma_status error * - * Algorithm: increament error stats based on corresponding bit filed. + * @note + * Algorithm: + * - increment 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 @@ -1673,11 +1717,13 @@ static inline void update_dma_sr_stats( /** * @brief eqos_handle_common_intr - Handles common interrupt. * - * Algorithm: Clear common interrupt source. + * @note + * Algorithm: + * - Clear common interrupt source. * * @param[in] osi_core: OSI core private data structure. * - * @note MAC should be init and started. see osi_start_mac() + * @pre MAC should be initialized and started. see osi_start_mac() */ static void eqos_handle_common_intr(struct osi_core_priv_data *const osi_core) { @@ -1734,12 +1780,15 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *const osi_core) /** * @brief eqos_start_mac - Start MAC Tx/Rx engine * - * Algorithm: Enable MAC Transmitter and Receiver + * @note + * Algorithm: + * - Enable MAC Transmitter and Receiver * * @param[in] addr: EQOS virtual base address. * - * @note 1) MAC init should be complete. See osi_hw_core_init() and - * osi_hw_dma_init() + * @pre + * - MAC init should be complete. See osi_hw_core_init() and + * osi_hw_dma_init() */ static void eqos_start_mac(void *addr) { @@ -1756,11 +1805,13 @@ static void eqos_start_mac(void *addr) /** * @brief eqos_stop_mac - Stop MAC Tx/Rx engine * - * Algorithm: Disables MAC Transmitter and Receiver + * @note + * Algorithm: + * - Disables MAC Transmitter and Receiver * * @param[in] addr: EQOS virtual base address. * - * @note MAC DMA deinit should be complete. See osi_hw_dma_deinit() + * @pre MAC DMA deinit should be complete. See osi_hw_dma_deinit() */ static void eqos_stop_mac(void *addr) { @@ -1778,22 +1829,24 @@ static void eqos_stop_mac(void *addr) /** * @brief eqos_set_avb_algorithm - Set TxQ/TC avb config * + * @note * 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 + * - Check if queue index is valid + * - Update operation mode of TxQ/TC + * - Set TxQ operation mode + * - Set Algo and Credit contro + * - 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 * - * @note 1) MAC should be init and started. see osi_start_mac() - * 2) osi_core->osd should be populated. + * @pre + * - MAC should be initialized and started. see osi_start_mac() + * - osi_core->osd should be populated. * * @retval 0 on success * @retval -1 on failure. @@ -1891,15 +1944,17 @@ static int eqos_set_avb_algorithm( /** * @brief eqos_config_l2_da_perfect_inverse_match - configure register for - * inverse or perfect match. + * inverse or perfect match. * - * Algorithm: This sequence is used to select perfect/inverse matching - * for L2 DA + * @note + * Algorithm: + * - This sequence is used to select perfect/inverse matching + * for L2 DA * * @param[in] base: Base address from 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() + * @pre MAC should be initialized and started. see osi_start_mac() * * @retval 0 always */ @@ -1923,14 +1978,16 @@ static inline int eqos_config_l2_da_perfect_inverse_match(void *base, /** * @brief eqos_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. + * @note + * 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() + * @pre MAC should be initialized and started. see osi_start_mac() * * @retval 0 always */ @@ -1991,9 +2048,11 @@ static int eqos_config_mac_pkt_filter_reg( /** * @brief eqos_update_mac_addr_helper - Function to update DCS and MBC * - * Algorithm: This helper routine is to update passed prameter value - * based on DCS and MBC parameter. Validation of dma_chan as well as - * dsc_en status performed before updating DCS bits. + * @note + * Algorithm: + * - This helper routine is to update passed prameter value + * based on DCS and MBC parameter. Validation of dma_chan as well as + * dsc_en status performed before updating DCS bits. * * @param[in] osi_core: OSI core private data structure. * @param[out] value: unsigned int pointer which has value read from register. @@ -2001,14 +2060,15 @@ static int eqos_config_mac_pkt_filter_reg( * @param[in] dma_routing_enable: dma channel routing enable(1) * @param[in] dma_chan: dma channel number * @param[in] addr_mask: 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] + * 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] * - * @note 1) MAC should be initialized and stated. see osi_start_mac() - * 2) osi_core->osd should be populated. + * @pre + * - MAC should be initialized and started. see osi_start_mac() + * - osi_core->osd should be populated. * * @retval 0 on success * @retval -1 on failure. @@ -2061,18 +2121,21 @@ err_dma_chan: /** * @brief eqos_update_mac_addr_low_high_reg- Update L2 address in filter - * register + * 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. + * @note + * 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. + * @pre + * - MAC should be initialized and started. see osi_start_mac() + * - osi_core->osd should be populated. * * @retval 0 on success * @retval -1 on failure. @@ -2143,22 +2206,24 @@ static int eqos_update_mac_addr_low_high_reg( /** * @brief eqos_get_avb_algorithm - Get TxQ/TC avb config * + * @note * 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 + * - Check if queue index is valid + * - read operation mode of TxQ/TC + * - read TxQ operation mode + * - read Algo and Credit contro + * - 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 * - * @note 1) MAC should be init and started. see osi_start_mac() - * 2) osi_core->osd should be populated. + * @pre + * - MAC should be initialized and started. see osi_start_mac() + * - osi_core->osd should be populated. * * @retval 0 on success * @retval -1 on failure. @@ -2229,21 +2294,23 @@ static int eqos_get_avb_algorithm( /** * @brief eqos_config_arp_offload - Enable/Disable ARP offload * + * @note * 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. + * - 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] mac_ver: MAC version number (different MAC HW version - * need different register offset/fields for ARP offload. + * need different register offset/fields for ARP offload. * @param[in] addr: EQOS 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. + * 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 + * @pre + * - MAC should be initialized and started. see osi_start_mac() + * - Valid 4 byte IP address as argument ip_addr * * @retval 0 on success * @retval -1 on failure. @@ -2291,14 +2358,16 @@ static int eqos_config_arp_offload(const unsigned int mac_ver, void *addr, /** * @brief eqos_config_l3_l4_filter_enable - register write to enable L3/L4 - * filters. + * filters. * - * Algorithm: This routine to enable/disable L4/l4 filter + * @note + * Algorithm: + * - This routine to enable/disable L4/l4 filter * * @param[in] base: Base address from OSI core private data structure. * @param[in] filter_enb_dis: enable/disable * - * @note MAC should be init and started. see osi_start_mac() + * @pre MAC should be initialized and started. see osi_start_mac() * * @retval 0 on success * @retval -1 on failure. @@ -2320,15 +2389,17 @@ static int eqos_config_l3_l4_filter_enable(void *base, /** * @brief eqos_update_ip4_addr - configure register for IPV4 address filtering * - * Algorithm: This sequence is used to update IPv4 source/destination - * Address for L3 layer filtering + * @note + * 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() + * @pre 1) MAC should be initialized and started. see osi_start_mac() * * @retval 0 on success * @retval -1 on failure. @@ -2378,14 +2449,16 @@ static int eqos_update_ip4_addr( /** * @brief eqos_update_ip6_addr - add ipv6 address in register * - * Algorithm: This sequence is used to update IPv6 source/destination - * Address for L3 layer filtering + * @note + * 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() + * @pre MAC should be initialized and started. see osi_start_mac() * * @retval 0 on success * @retval -1 on failure. @@ -2444,17 +2517,20 @@ static int eqos_update_ip6_addr( /** * @brief eqos_update_l4_port_no -program source port no * - * Algorithm: sequence is used to update Source Port Number for - * L4(TCP/UDP) layer filtering. + * @note + * 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 + * @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 * * @retval 0 on success * @retval -1 on failure. @@ -2493,19 +2569,21 @@ static int eqos_update_l4_port_no( /** * @brief eqos_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. + * @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: 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 + * @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 * *@return updated unsigned int value */ @@ -2533,13 +2611,15 @@ static inline unsigned int eqos_set_dcs( * @brief eqos_helper_l3l4_bitmask - helper function to set L3L4 * bitmask. * - * Algorithm: set bit corresponding to L3l4 filter index + * @note + * 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() + * @pre MAC should be initialized and started. see osi_start_mac() * */ static inline void eqos_helper_l3l4_bitmask(unsigned int *bitmask, @@ -2562,10 +2642,12 @@ static inline void eqos_helper_l3l4_bitmask(unsigned int *bitmask, /** * @brief eqos_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. + * @note + * 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 @@ -2576,10 +2658,11 @@ static inline void eqos_helper_l3l4_bitmask(unsigned int *bitmask, * @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 + * @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 * * @retval 0 on success * @retval -1 on failure. @@ -2739,8 +2822,10 @@ static int eqos_config_l3_filters( /** * @brief eqos_config_l4_filters - Config L4 filters. * - * Algorithm: This sequence is used to configure L4(TCP/UDP) filters for - * SA and DA Port Number matching + * @note + * 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 @@ -2751,8 +2836,9 @@ static int eqos_config_l3_filters( * @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 + * @pre + * - MAC should be initialized and started. see osi_start_mac() + * - osi_core->osd should be populated. * * @retval 0 on success * @retval -1 on failure. @@ -2854,16 +2940,19 @@ static int eqos_config_l4_filters( /** * @brief eqos_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 + * @note + * 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 + * @pre + * - MAC should be initialized and started. see osi_start_mac() + * - osi_core->osd should be populated. * * @retval 0 on success * @retval -1 on failure. @@ -2916,14 +3005,16 @@ static inline int eqos_update_vlan_id(void *base, unsigned int vid) /** * @brief eqos_poll_for_tsinit_complete - Poll for time stamp init complete * - * Algorithm: Read TSINIT value from MAC TCR register until it is - * equal to zero. + * @note + * 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() + * @pre MAC should be initialized and started. see osi_start_mac() * * @retval 0 on success * @retval -1 on failure. @@ -2958,15 +3049,17 @@ static inline int eqos_poll_for_tsinit_complete(void *addr, /** * @brief eqos_set_systime - Set system time * - * Algorithm: Updates system time (seconds and nano seconds) - * in hardware registers + * @note + * 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() + * @pre MAC should be initialized and started. see osi_start_mac() * * @retval 0 on success * @retval -1 on failure. @@ -3006,14 +3099,16 @@ static int eqos_set_systime_to_mac(void *addr, const unsigned int sec, /** * @brief eqos_poll_for_tsinit_complete - Poll for addend value write complete * - * Algorithm: Read TSADDREG value from MAC TCR register until it is - * equal to zero. + * @note + * 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() + * @pre MAC should be initialized and started. see osi_start_mac() * * @retval 0 on success * @retval -1 on failure. @@ -3047,13 +3142,15 @@ static inline int eqos_poll_for_addend_complete(void *addr, /** * @brief eqos_config_addend - Configure addend * - * Algorithm: Updates the Addend value in HW register + * @note + * 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() + * @pre MAC should be initialized and started. see osi_start_mac() * * @retval 0 on success * @retval -1 on failure. @@ -3088,14 +3185,16 @@ static int eqos_config_addend(void *addr, const unsigned int addend) /** * @brief eqos_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. + * @note + * 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() + * @pre MAC should be initialized and started. see osi_start_mac() * * @retval 0 on success * @retval -1 on failure. @@ -3129,7 +3228,9 @@ static inline int eqos_poll_for_update_ts_complete(void *addr, /** * @brief eqos_adjust_mactime - Adjust MAC time with system time * - * Algorithm: Update MAC time with system time + * @note + * Algorithm: + * - Update MAC time with system time * * @param[in] addr: Base address indicating the start of * memory mapped IO region of the MAC. @@ -3138,8 +3239,9 @@ static inline int eqos_poll_for_update_ts_complete(void *addr, * @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 + * @pre + * - MAC should be initialized and started. see osi_start_mac() + * - osi_core->ptp_config.one_nsec_accuracy need to be set to 1 * * @retval 0 on success * @retval -1 on failure. @@ -3219,7 +3321,7 @@ static int eqos_adjust_mactime(void *addr, unsigned int sec, unsigned int nsec, * 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() + * @pre MAC should be initialized and started. see osi_start_mac() */ static void eqos_config_tscr(void *addr, const unsigned int ptp_filter) { @@ -3288,7 +3390,7 @@ static void eqos_config_tscr(void *addr, const unsigned int ptp_filter) * * @param[in] osi_core: OSI core private data structure. * - * @note MAC should be init and started. see osi_start_mac() + * @pre MAC should be initialized and started. see osi_start_mac() */ static void eqos_config_ssir(struct osi_core_priv_data *const osi_core) { @@ -3333,11 +3435,13 @@ static void eqos_config_ssir(struct osi_core_priv_data *const osi_core) /** * @brief eqos_core_deinit - EQOS MAC core deinitialization * - * Algorithm: This function will take care of deinitializing MAC + * @note + * 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 + * @pre Required clks and resets has to be enabled */ static void eqos_core_deinit(struct osi_core_priv_data *const osi_core) { @@ -3348,13 +3452,14 @@ static void eqos_core_deinit(struct osi_core_priv_data *const osi_core) /** * @brief eqos_disable_tx_lpi - Helper function to disable Tx LPI. * + * @note * Algorithm: - * 1) Clear the bits to enable Tx LPI, Tx LPI automate, LPI Tx Timer and - * PHY Link status in the LPI control/status register + * - 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] addr: base address of memory mapped register space of MAC. * - * @note MAC has to be out of reset, and clocks supplied. + * @pre MAC has to be out of reset, and clocks supplied. */ static inline void eqos_disable_tx_lpi(void *addr) { @@ -3370,21 +3475,23 @@ static inline void eqos_disable_tx_lpi(void *addr) /** * @brief eqos_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. + * @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. + * OSI_MAX_TX_LPI_TIMER in steps of 8usec. * - * @note - * Required clks and resets has to be enabled. - * MAC/PHY should be initialized + * @pre + * - Required clks and resets has to be enabled. + * - MAC/PHY should be initialized */ static void eqos_configure_eee( struct osi_core_priv_data *const osi_core, @@ -3446,11 +3553,13 @@ static void eqos_configure_eee( } } -/* +/** * @brief 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. + * @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. * @@ -3474,8 +3583,10 @@ static inline int eqos_save_registers( /** * @brief Function to restore the backup of MAC registers during SOC resume. * - * Algorithm: Restore the register values from the in memory backup taken using - * eqos_save_registers(). + * @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. * @@ -3501,7 +3612,7 @@ static inline int eqos_restore_registers( * * @param[in] osi_core: OSI Core private data structure. * - * @note MAC needs to be out of reset and proper clock configured. + * @pre MAC needs to be out of reset and proper clock configured. * * @retval 0 on Success * @retval -1 on Failure @@ -3542,22 +3653,23 @@ static inline int poll_for_mii_idle(struct osi_core_priv_data *osi_core) /** * @brief eqos_write_phy_reg - Write to a PHY register through MAC over MDIO bus * + * @note * Algorithm: - * 1) Before proceeding for reading for PHY register check whether any MII + * - Before proceeding for reading for PHY register check whether any MII * operation going on MDIO bus by polling MAC_GMII_BUSY bit. - * 2) Program data into MAC MDIO data register. - * 3) 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. - * 4) Write into MAC MDIO address register poll for GMII busy for MDIO - * operation to complete. + * - 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. * - * @note MAC should be init and started. see osi_start_mac() + * @pre MAC should be initialized and started. see osi_start_mac() * * @retval 0 on success * @retval -1 on failure. @@ -3623,21 +3735,22 @@ static int eqos_write_phy_reg(struct osi_core_priv_data *const osi_core, /** * @brief eqos_read_phy_reg - Read from a PHY register through MAC over MDIO bus * + * @note * Algorithm: - * 1) Before proceeding for reading for PHY register check whether any MII - * operation going on MDIO bus by polling MAC_GMII_BUSY bit. - * 2) 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. - * 3) 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. + * - 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. * - * @note MAC should be init and started. see osi_start_mac() + * @pre MAC should be initialized and started. see osi_start_mac() * * @retval data from PHY register on success * @retval -1 on failure diff --git a/osi/core/eqos_mmc.c b/osi/core/eqos_mmc.c index f7c41dd..3c766ec 100644 --- a/osi/core/eqos_mmc.c +++ b/osi/core/eqos_mmc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -29,16 +29,18 @@ /** * @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. + * @note + * 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 + * @pre + * - MAC should be init and started. see osi_start_mac() + * - osi_core->osd should be populated * * @retval 0 on success * @retval -1 on failure @@ -67,13 +69,13 @@ static inline unsigned long update_mmc_val(struct osi_core_priv_data *osi_core, /** * @brief eqos_reset_mmc - To reset MMC registers and ether_mmc_counter - * structure variable + * 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 + * @pre + * - MAC should be init and started. see osi_start_mac() + * - osi_core->osd should be populated */ void eqos_reset_mmc(struct osi_core_priv_data *osi_core) { @@ -88,16 +90,18 @@ void eqos_reset_mmc(struct osi_core_priv_data *osi_core) /** * @brief eqos_read_mmc - To read MMC registers and ether_mmc_counter structure - * variable + * variable * - * Algorithm: Pass register offset and old value to helper function and - * update structure. + * @note + * 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 + * @pre + * - MAC should be init and started. see osi_start_mac() + * - osi_core->osd should be populated */ void eqos_read_mmc(struct osi_core_priv_data *osi_core) { diff --git a/osi/core/eqos_mmc.h b/osi/core/eqos_mmc.h index bab9016..fe6f0e3 100644 --- a/osi/core/eqos_mmc.h +++ b/osi/core/eqos_mmc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -115,30 +115,6 @@ #define MMC_RXICMP_ERR_OCTETS 0x00884 /** @} */ -/** - * @brief eqos_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 eqos_read_mmc(struct osi_core_priv_data *osi_core); - -/** - * @brief eqos_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 eqos_reset_mmc(struct osi_core_priv_data *osi_core); #endif diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 4e119a7..382efa8 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -358,7 +358,7 @@ int osi_l2_filter(struct osi_core_priv_data *const osi_core, * @param[in] dma_routing_enable: dma routing enable (1) or disable (0) * @param[in] dma_chan: dma channel * - * @note MAC needs to be out of reset and proper clock configured. + * @pre MAC needs to be out of reset and proper clock configured. * * @retval 0 on Success * @retval -1 on Failure @@ -411,7 +411,7 @@ static inline int helper_l4_filter( * @param[in] dma_routing_enable: dma routing enable (1) or disable (0) * @param[in] dma_chan: dma channel * - * @note MAC needs to be out of reset and proper clock configured. + * @pre MAC needs to be out of reset and proper clock configured. * * @retval 0 on Success * @retval -1 on Failure @@ -580,15 +580,17 @@ int osi_set_systime_to_mac(struct osi_core_priv_data *const osi_core, /** *@brief div_u64_rem - updates remainder and returns Quotient * - * Algorithm: Dividend will be divided by divisor and stores the - * remainder value 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 * - * @note MAC IP should be out of reset and need to be initialized as the - * requirements + * @pre MAC IP should be out of reset and need to be initialized as the + * requirements * * @returns Quotient */ @@ -613,8 +615,8 @@ static inline unsigned long div_u64_rem(unsigned long dividend, * @param[in] dividend: Dividend * @param[in] divisor: Divisor * - * @note MAC IP should be out of reset and need to be initialized as the - * requirements. + * @pre MAC IP should be out of reset and need to be initialized as the + * requirements. * * @returns Quotient */ diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index 4ab9090..b38d8b3 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -32,19 +32,20 @@ static struct dma_func_safety eqos_dma_safety_config; /** * @brief Write to safety critical register. * + * @note * Algorithm: - * 1) Acquire RW lock, so that eqos_validate_dma_regs does not run while - * updating the safety critical register. - * 2) call osi_writel() to actually update the memory mapped register. - * 3) 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. + * - 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] 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. * - * @note MAC has to be out of reset, and clocks supplied. + * @pre MAC has to be out of reset, and clocks supplied. */ static inline void eqos_dma_safety_writel(unsigned int val, void *addr, unsigned int idx) @@ -62,12 +63,14 @@ static inline void eqos_dma_safety_writel(unsigned int val, void *addr, * * @param[in] osi_dma: OSI DMA private data structure. * - * Algorithm: Populate the list of safety critical registers and provide - * 1) the address of the register - * 2) Register mask (to ignore reserved/self-critical bits in the reg). - * See eqos_validate_dma_regs which can be ivoked periodically to compare - * the last written value to this register vs the actual value read when - * eqos_validate_dma_regs is scheduled. + * @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 ivoked periodically to compare + * the last written value to this register vs the actual value read when + * eqos_validate_dma_regs is scheduled. */ static void eqos_dma_safety_init(struct osi_dma_priv_data *osi_dma) { @@ -128,17 +131,19 @@ static void eqos_dma_safety_init(struct osi_dma_priv_data *osi_dma) /** * @brief Read-validate HW registers for functional safety. * - * Algorithm: Reads pre-configured list of MAC/MTL configuration registers - * and compares with last written value for any modifications. + * @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. * - * @note - * 1) MAC has to be out of reset. - * 2) 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. - * 3) Invoke this call iff (osi_dma_priv_data->safety_config != OSI_NULL) + * @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 iff (osi_dma_priv_data->safety_config != OSI_NULL) * * @retval 0 on success * @retval -1 on failure. @@ -191,13 +196,14 @@ static int eqos_validate_dma_regs(struct osi_dma_priv_data *osi_dma) * @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. + * 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. + * @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. */ static void eqos_disable_chan_tx_intr(void *addr, unsigned int chan) { @@ -232,10 +238,11 @@ static void eqos_disable_chan_tx_intr(void *addr, unsigned int chan) * 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. + * @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. */ static void eqos_enable_chan_tx_intr(void *addr, unsigned int chan) { @@ -257,10 +264,11 @@ static void eqos_enable_chan_tx_intr(void *addr, unsigned int chan) * 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. + * @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. */ static void eqos_disable_chan_rx_intr(void *addr, unsigned int chan) { @@ -295,8 +303,9 @@ static void eqos_disable_chan_rx_intr(void *addr, unsigned int chan) * 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 + * @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 */ static void eqos_enable_chan_rx_intr(void *addr, unsigned int chan) { @@ -314,7 +323,9 @@ static void eqos_enable_chan_rx_intr(void *addr, unsigned int chan) /** * @brief eqos_set_tx_ring_len - Set DMA Tx ring length. * - * Algorithm: Set DMA Tx channel ring length for specific channel. + * @note + * Algorithm: + * - Set DMA Tx channel ring length for specific channel. * * @param[in] addr: Base address indicating the start of * memory mapped IO region of the MAC. @@ -333,7 +344,9 @@ static void eqos_set_tx_ring_len(void *addr, unsigned int chan, /** * @brief eqos_set_tx_ring_start_addr - Set DMA Tx ring base address. * - * Algorithm: Sets DMA Tx ring base address for specific channel. + * @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. @@ -363,7 +376,9 @@ static void eqos_set_tx_ring_start_addr(void *addr, unsigned int chan, /** * @brief eqos_update_tx_tailptr - Updates DMA Tx ring tail pointer. * - * Algorithm: Updates DMA Tx ring tail pointer for specific channel. + * @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. @@ -371,8 +386,9 @@ static void eqos_set_tx_ring_start_addr(void *addr, unsigned int chan, * @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 + * @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 */ static void eqos_update_tx_tailptr(void *addr, unsigned int chan, unsigned long tailptr) @@ -391,7 +407,9 @@ static void eqos_update_tx_tailptr(void *addr, unsigned int chan, /** * @brief eqos_set_rx_ring_len - Set Rx channel ring length. * - * Algorithm: Sets DMA Rx channel ring length for specific DMA channel. + * @note + * Algorithm: + * - Sets DMA Rx channel ring length for specific DMA channel. * * @param[in] addr: Base address indicating the start of * memory mapped IO region of the MAC. @@ -410,7 +428,9 @@ static void eqos_set_rx_ring_len(void *addr, unsigned int chan, /** * @brief eqos_set_rx_ring_start_addr - Set DMA Rx ring base address. * - * Algorithm: Sets DMA Rx channel 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. @@ -440,15 +460,18 @@ static void eqos_set_rx_ring_start_addr(void *addr, unsigned int chan, /** * @brief eqos_update_rx_tailptr - Update Rx ring tail pointer * - * Algorithm: Updates DMA Rx channel tail pointer for specific channel. + * @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 * - * @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 + * @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 */ static void eqos_update_rx_tailptr(void *addr, unsigned int chan, unsigned long tailptr) @@ -467,14 +490,17 @@ static void eqos_update_rx_tailptr(void *addr, unsigned int chan, /** * @brief eqos_start_dma - Start DMA. * - * Algorithm: Start Tx and Rx DMA for specific channel. + * @note + * Algorithm: + * - Start Tx and Rx DMA for specific channel. * * @param[in] addr: Base address indicating the start of * memory mapped IO region of the MAC. * @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 + * @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 */ static void eqos_start_dma(void *addr, unsigned int chan) { @@ -500,14 +526,17 @@ static void eqos_start_dma(void *addr, unsigned int chan) /** * @brief eqos_stop_dma - Stop DMA. * - * Algorithm: Start Tx and Rx DMA for specific channel. + * @note + * Algorithm: + * - Start Tx and Rx DMA for specific channel. * * @param[in] addr: Base address indicating the start of * memory mapped IO region of the MAC. * @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 + * @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 */ static void eqos_stop_dma(void *addr, unsigned int chan) { @@ -533,15 +562,18 @@ static void eqos_stop_dma(void *addr, unsigned int chan) /** * @brief eqos_config_slot - Configure slot Checking for DMA channel * - * Algorithm: Set/Reset the slot function of DMA channel based on given inputs + * @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 * - * @note 1)MAC should be init and started. see osi_start_mac() - * 2)OSD should be initialized + * @pre + & - MAC should be init and started. see osi_start_mac() + * - OSD should be initialized * * @retval none */ @@ -580,18 +612,20 @@ static void eqos_config_slot(struct osi_dma_priv_data *osi_dma, /** * @brief eqos_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 + * @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. * - * @note MAC has to be out of reset. + * @pre MAC has to be out of reset. */ static void eqos_configure_dma_channel(unsigned int chan, struct osi_dma_priv_data *osi_dma) @@ -744,13 +778,14 @@ static void eqos_init_dma_channel(struct osi_dma_priv_data *osi_dma) /** * @brief eqos_set_rx_buf_len - Set Rx buffer length - * Sets the Rx buffer length based on the new MTU size set. + * 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 + * @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 */ static void eqos_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) { diff --git a/osi/dma/eqos_dma.h b/osi/dma/eqos_dma.h index e528375..40a36f3 100644 --- a/osi/dma/eqos_dma.h +++ b/osi/dma/eqos_dma.h @@ -162,8 +162,6 @@ struct dma_func_safety { /** * @brief eqos_get_dma_safety_config - EQOS get DMA safety configuration * - * Algorithm: Returns pointer DMA safety configuration. - * * @returns Pointer to DMA safety configuration */ void *eqos_get_dma_safety_config(void); @@ -171,8 +169,6 @@ void *eqos_get_dma_safety_config(void); /** * @brief eqos_get_dma_chan_ops - EQOS get DMA channel operations * - * Algorithm: Returns pointer DMA channel operations structure. - * * @returns Pointer to DMA channel operations structure */ struct osi_dma_chan_ops *eqos_get_dma_chan_ops(void); diff --git a/osi/dma/osi_dma_local.h b/osi/dma/osi_dma_local.h index 5c43e1a..531612e 100644 --- a/osi/dma/osi_dma_local.h +++ b/osi/dma/osi_dma_local.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2019-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"), @@ -32,8 +32,10 @@ /** * @brief dma_desc_init - Initialize DMA Tx/Rx descriptors * - * Algorithm: Transmit and Receive desctiptors will be initialized with - * required values so that MAC DMA can understand and act accordingly. + * @note + * Algorithm: + * - Transmit and Receive descriptors will be initialized with + * required values so that MAC DMA can understand and act accordingly. * * @param[in] osi_dma: OSI DMA private data structure. * diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index e9649af..b429939 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -27,13 +27,14 @@ /** * @brief get_rx_csum - Get the Rx checksum from descriptor if valid * + * @note * 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. + * - 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. * * @param[in] rx_desc: Rx descriptor * @param[in] rx_pkt_cx: Per-Rx packet context structure @@ -92,11 +93,12 @@ static inline void get_rx_csum(struct osi_rx_desc *rx_desc, /** * @brief get_rx_vlan_from_desc - Get Rx VLAN from descriptor * + * @note * 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 + * - Check if the descriptor has any type set. + * - If set, set a per packet context flag indicating packet is VLAN + * tagged. + * - Extract VLAN tag ID from the descriptor * * @param[in] rx_desc: Rx descriptor * @param[in] rx_pkt_cx: Per-Rx packet context structure @@ -120,9 +122,10 @@ static inline void get_rx_vlan_from_desc(struct osi_rx_desc *rx_desc, /** * @brief get_rx_tstamp_status - Get Tx Time stamp status * + * @note * Algorithm: - * 1) Check if the received descriptor is a context descriptor. - * 2) If yes, check whether the time stamp is valid or not. + * - Check if the received descriptor is a context descriptor. + * - If yes, check whether the time stamp is valid or not. * * @param[in] context_desc: Rx context descriptor * @@ -148,11 +151,12 @@ static inline int get_rx_tstamp_status(struct osi_rx_desc *context_desc) /** * @brief get_rx_hwstamp - Get Rx HW Time stamp * + * @note * 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. + * - Check for TS availability. + * - call get_tx_tstamp_status if TS is valid or not. + * - 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 @@ -206,9 +210,11 @@ static int get_rx_hwstamp(struct osi_rx_desc *rx_desc, /** * @brief 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. + * @note + * 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 @@ -375,8 +381,10 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, /** * @brief inc_tx_pkt_stats - Increment Tx packet count Stats * - * Algorithm: This routine will be invoked by OSI layer internally to increment - * stats for successfully transmitted packets on certain DMA channel. + * @note + * Algorithm: + * - This routine will be invoked by OSI layer internally to increment + * stats for successfully transmitted packets on certain DMA channel. * * @param[in] osi: Pointer to OSI DMA private data structure. * @param[in] chan: DMA channel number for which stats should be incremented. @@ -393,12 +401,14 @@ static inline void inc_tx_pkt_stats(struct osi_dma_priv_data *osi, /** * @brief get_tx_err_stats - Detect Errors from Tx Status * - * Algorithm: This routine will be invoked by OSI layer itself which - * checks for the Last Descriptor and updates the transmit status errors - * accordingly. + * @note + * Algorithm: + * - This routine will be invoked by OSI layer itself which + * checks for the Last Descriptor and updates the transmit status errors + * accordingly. * * @param[in] tx_desc: Tx Descriptor. - * @param[in] pkt_err_stats: Pakcet error stats which stores the errors reported + * @param[in] 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) @@ -627,13 +637,14 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi, /** * @brief need_cntx_desc - Helper function to check if context desc is needed. * + * @note * Algorithm: - * 1) Check if transmit packet context flags are set - * 2) If set, set the context descriptor bit along - * with other context information in the transmit descriptor. + * - 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] tx_pkt_cx: Pointer to transmit packet context structure - * @param[in] tx_desc: Pointer to tranmit descriptor to be filled. + * @param[in] tx_desc: Pointer to transmit descriptor to be filled. * * @retval 0 - cntx desc not used * @retval 1 - cntx desc used. @@ -676,15 +687,16 @@ static inline int need_cntx_desc(struct osi_tx_pkt_cx *tx_pkt_cx, * @brief fill_first_desc - Helper function to fill the first transmit * descriptor. * + * @note * Algorithm: - * 1) Update the buffer address and length of buffer in first desc. - * 2) Check if any features like HW checksum offload, TSO, VLAN insertion - * etc. are flagged in transmit packet context. If so, set the fiels in - * first desc corresponding to those features. + * - 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. * * @param[in] tx_ring: DMA channel TX ring. * @param[in] tx_pkt_cx: Pointer to transmit packet context structure - * @param[in] tx_desc: Pointer to tranmit descriptor to be filled. + * @param[in] 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, @@ -914,9 +926,11 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan) /** * @brief rx_dma_desc_initialization - Initialize DMA Receive descriptors for Rx * - * 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. + * @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] osi: OSI private data structure. * @param[in] chan: Rx channel number. @@ -994,9 +1008,11 @@ static int rx_dma_desc_initialization(struct osi_dma_priv_data *osi, /** * @brief rx_dma_desc_init - Initialize DMA Receive descriptors for Rx channel. * - * Algorithm: Initialize Receive descriptors with DMA mappabled buffers, - * set OWN bit, Rx ring length and set starting address of Rx DMA channel. - * Tx ring base address in Tx DMA registers. + * @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] osi: OSI private data structure. * @@ -1024,8 +1040,10 @@ static int rx_dma_desc_init(struct osi_dma_priv_data *osi) /** * @brief tx_dma_desc_init - Initialize DMA Transmit descriptors. * - * Algorithm: Initialize Trannsmit descriptors and set Tx ring length, - * Tx ring base address in Tx DMA registers. + * @note + * Algorithm: + * - Initialize Transmit descriptors and set Tx ring length, + * Tx ring base address in Tx DMA registers. * * @param[in] osi_dma: OSI DMA private data structure. */ From 228703f6cfde521eb8c22df42f62835f8845c3c8 Mon Sep 17 00:00:00 2001 From: rakesh goyal <rgoyal@nvidia.com> Date: Wed, 9 Sep 2020 15:29:22 +0530 Subject: [PATCH 116/458] osi: create stripped library for MCAL/QNX Update common library to export only API used in QNX/MCAL driver if OSI_STRIPPED_LIB is defined. Bug 200671362 Change-Id: Ide3a5d9a60228b5d07355b58e26f509245db4144 Signed-off-by: rakesh goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2410877 Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2422285 Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_common.h | 14 +- include/osi_core.h | 1019 ++++++++++++----------- include/osi_dma.h | 278 +++---- osi/core/Makefile.tmk | 1 + osi/core/eqos_core.c | 1351 +++++++++++++++---------------- osi/core/libnvethernetrm.export | 15 +- osi/core/osi_core.c | 294 +++---- osi/dma/Makefile.tmk | 1 + osi/dma/eqos_dma.c | 226 +++--- osi/dma/libnvethernetcl.export | 3 - osi/dma/osi_dma.c | 7 +- osi/dma/osi_dma_txrx.c | 10 +- 12 files changed, 1591 insertions(+), 1628 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index 4a83e83..d5fe781 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -125,7 +125,7 @@ /** * @addtogroup EQOS_PTP PTP Helper MACROS * - * @brief EQOS PTP MAC Time stamp contorl reg bit fields + * @brief EQOS PTP MAC Time stamp control reg bit fields * @{ */ #define OSI_MAC_TCR_TSENA OSI_BIT(0) @@ -200,7 +200,7 @@ OSI_LOG_WARN, type, err, loga); \ } -/* Default maximum Gaint Packet Size Limit is 16K */ +/* Default maximum Giant Packet Size Limit is 16K */ #define OSI_MAX_MTU_SIZE 16383U #define OSI_MTU_SIZE_9000 9000U #define OSI_DFLT_MTU_SIZE 1500U @@ -609,7 +609,7 @@ struct osi_hw_features { * feature */ unsigned int auto_safety_pkg; /** Tx Timestamp FIFO Depth - * This value indicates the depth of the Tx Timetamp FIFO + * This value indicates the depth of the Tx Timestamp FIFO * 3'b000: Reserved * 3'b001: 1 * 3'b010: 2 @@ -746,7 +746,7 @@ static inline void osi_unlock_irq_enabled(unsigned int *lock) * * @param[in] addr: Memory mapped address. * - * @pre Physical address has to be memmory mapped. + * @pre Physical address has to be memory mapped. * * @return Data from memory mapped register - success. */ @@ -761,7 +761,7 @@ static inline unsigned int osi_readl(void *addr) * @param[in] val: Value to be written. * @param[in] addr: Memory mapped address. * - * @pre Physical address has to be memmory mapped. + * @pre Physical address has to be memory mapped. */ static inline void osi_writel(unsigned int val, void *addr) { @@ -831,7 +831,7 @@ static inline unsigned long osi_update_stats_counter(unsigned long last_value, * * @note * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_020 + * - SWUD_ID: ETHERNET_NVETHERNETRM_015 * * @note * Classification: @@ -861,7 +861,7 @@ int osi_get_mac_version(void *addr, unsigned int *mac_ver); * * @note * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_021 + * - SWUD_ID: ETHERNET_NVETHERNETRM_016 * * @note * Classification: diff --git a/include/osi_core.h b/include/osi_core.h index 0fa01c5..daaa019 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -107,6 +107,7 @@ struct osi_l2_da_filter { unsigned int perfect_inverse_match; }; +#ifndef OSI_STRIPPED_LIB /** * @brief OSI Core avb data structure per queue. */ @@ -118,7 +119,7 @@ struct osi_core_avb_algorithm { /** 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) */ unsigned int credit_control; /** idleSlopeCredit value required for CBS */ @@ -132,12 +133,13 @@ struct osi_core_avb_algorithm { /** Transmit queue operating mode * * 00: disable - * - * 01: avb - * + * + * 01: avb + * * 10: enable */ unsigned int oper_mode; }; +#endif /* !OSI_STRIPPED_LIB */ /** * @brief Initialize MAC & MTL core operations. @@ -151,9 +153,6 @@ struct osi_core_ops { const unsigned int rx_fifo_size); /** Called to deinitialize MAC and MTL registers */ void (*core_deinit)(struct osi_core_priv_data *const osi_core); - /** Called periodically to read and validate safety critical - * registers against last written value */ - int (*validate_regs)(struct osi_core_priv_data *const osi_core); /** Called to start MAC Tx and Rx engine */ void (*start_mac)(void *addr); /** Called to stop MAC Tx and Rx engine */ @@ -169,29 +168,11 @@ struct osi_core_ops { /** Called to set MDC clock rate for MDIO operation */ void (*set_mdc_clk_rate)(struct osi_core_priv_data *const osi_core, const unsigned long csr_clk_rate); - /** Called to flush MTL Tx queue */ - int (*flush_mtl_tx_queue)(void *ioaddr, const unsigned int qinx); /** Called to configure MAC in loopback mode */ int (*config_mac_loopback)(void *addr, const unsigned int lb_mode); - /** Called to set av parameter */ - int (*set_avb_algorithm)(struct osi_core_priv_data *const osi_core, - const struct osi_core_avb_algorithm *const avb); - /** Called to get av parameter */ - int (*get_avb_algorithm)(struct osi_core_priv_data *const osi_core, - struct osi_core_avb_algorithm *const avb); /** Called to configure MTL RxQ to forward the err pkt */ int (*config_fw_err_pkts)(void *addr, const unsigned int qinx, const unsigned int fw_err); - /** Called to configure the MTL to forward/drop tx status */ - int (*config_tx_status)(void *addr, const unsigned int tx_status); - /** Called to configure the MAC rx crc */ - int (*config_rx_crc_check)(void *addr, const unsigned int crc_chk); - /** Called to configure the MAC flow control */ - int (*config_flow_control)(void *addr, const unsigned int flw_ctrl); - /** Called to enable/disable HW ARP offload feature */ - int (*config_arp_offload)(const unsigned int mac_ver, void *addr, - const unsigned int enable, - const unsigned char *ip_addr); /** Called to configure Rx Checksum offload engine */ int (*config_rxcsum_offload)(void *addr, const unsigned int enabled); /** Called to config mac packet filter */ @@ -237,17 +218,6 @@ struct osi_core_ops { const unsigned int filter_no, const unsigned short port_no, const unsigned int src_dst_port_match); - - /** Called to configure VLAN filtering */ - int (*config_vlan_filtering)(struct osi_core_priv_data *const osi_core, - const unsigned int filter_enb_dis, - const unsigned int perfect_hash_filtering, - const unsigned int perfect_inverse_match); - /** called to update VLAN id */ - int (*update_vlan_id)(void *base, const unsigned int vid); - /** Called to set current system time to MAC */ - int (*set_systime_to_mac)(void *addr, const unsigned int sec, - const unsigned int nsec); /** Called to set the addend value to adjust the time */ int (*config_addend)(void *addr, const unsigned int addend); /** Called to adjust the mac time */ @@ -255,14 +225,55 @@ struct osi_core_ops { const unsigned int nsec, const unsigned int neg_adj, const unsigned int one_nsec_accuracy); - /** Called to get the current time from MAC */ - unsigned long long (*get_systime_from_mac)(void *addr); + /** Called to set current system time to MAC */ + int (*set_systime_to_mac)(void *addr, const unsigned int sec, + const unsigned int nsec); /** Called to configure the TimeStampControl register */ void (*config_tscr)(void *addr, const unsigned int ptp_filter); /** Called to configure the sub second increment register */ void (*config_ssir)(struct osi_core_priv_data *const osi_core); /** 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 */ + int (*write_phy_reg)(struct osi_core_priv_data *const osi_core, + const unsigned int phyaddr, + const unsigned int phyreg, + const unsigned short phydata); + /** Called to read from a PHY reg over MDIO bus */ + int (*read_phy_reg)(struct osi_core_priv_data *const osi_core, + const unsigned int phyaddr, + const unsigned int phyreg); +#ifndef OSI_STRIPPED_LIB + /** Called periodically to read and validate safety critical + * registers against last written value */ + int (*validate_regs)(struct osi_core_priv_data *const osi_core); + /** Called to flush MTL Tx queue */ + int (*flush_mtl_tx_queue)(void *ioaddr, const unsigned int qinx); + /** Called to set av parameter */ + int (*set_avb_algorithm)(struct osi_core_priv_data *const osi_core, + const struct osi_core_avb_algorithm *const avb); + /** Called to get av parameter */ + int (*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 */ + int (*config_tx_status)(void *addr, const unsigned int tx_status); + /** Called to configure the MAC rx crc */ + int (*config_rx_crc_check)(void *addr, const unsigned int crc_chk); + /** Called to configure the MAC flow control */ + int (*config_flow_control)(void *addr, const unsigned int flw_ctrl); + /** Called to enable/disable HW ARP offload feature */ + int (*config_arp_offload)(const unsigned int mac_ver, void *addr, + const unsigned int enable, + const unsigned char *ip_addr); + /** Called to configure VLAN filtering */ + int (*config_vlan_filtering)(struct osi_core_priv_data *const osi_core, + const unsigned int filter_enb_dis, + const unsigned int perfect_hash_filtering, + const unsigned int perfect_inverse_match); + /** called to update VLAN id */ + int (*update_vlan_id)(void *base, const unsigned int vid); + /** Called to get the current time from MAC */ + unsigned long long (*get_systime_from_mac)(void *addr); /** Called to reset MMC HW counter structure */ void (*reset_mmc)(struct osi_core_priv_data *const osi_core); /** Called to configure EEE Tx LPI */ @@ -273,15 +284,7 @@ struct osi_core_ops { int (*save_registers)(struct osi_core_priv_data *const osi_core); /** Called to restore MAC control registers during SoC resume */ int (*restore_registers)(struct osi_core_priv_data *const osi_core); - /** Called to write into a PHY reg over MDIO bus */ - int (*write_phy_reg)(struct osi_core_priv_data *const osi_core, - const unsigned int phyaddr, - const unsigned int phyreg, - const unsigned short phydata); - /** Called to read from a PHY reg over MDIO bus */ - int (*read_phy_reg)(struct osi_core_priv_data *const osi_core, - const unsigned int phyaddr, - const unsigned int phyreg); +#endif /* !OSI_STRIPPED_LIB */ }; /** @@ -290,7 +293,7 @@ struct osi_core_ops { struct osi_ptp_config { /** PTP filter parameters bit fields. * - * Enable Time stamp,Fine Timestamp,1 nanosecond accuracy + * Enable Timestamp, Fine Timestamp, 1 nanosecond accuracy * are enabled by default. * * Need to set below bit fields accordingly as per the requirements. @@ -317,7 +320,7 @@ struct osi_ptp_config { * * AV 802.1AS Mode Enable OSI_BIT(28) * - * if ptp_fitler is set to Zero then Time stamping is disabled */ + * if ptp_filter is set to Zero then Time stamping is disabled */ unsigned int ptp_filter; /** seconds to be updated to MAC */ unsigned int sec; @@ -557,45 +560,6 @@ int osi_hw_core_init(struct osi_core_priv_data *const osi_core, */ int osi_hw_core_deinit(struct osi_core_priv_data *const osi_core); -/** - * @brief osi_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_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 iff (osi_core_priv_data->safety_config != OSI_NULL) - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_037 - * - * @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. - */ -int osi_validate_core_regs(struct osi_core_priv_data *const osi_core); - /** * @brief osi_start_mac - Start MAC Tx/Rx engine * @@ -805,43 +769,6 @@ int osi_set_speed(struct osi_core_priv_data *const osi_core, */ int osi_pad_calibrate(struct osi_core_priv_data *const osi_core); -/** - * @brief osi_flush_mtl_tx_queue - Flushing a MTL Tx Queue. - * - * @note - * Algorithm: - * - Invokes EQOS flush Tx queue routine. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] qinx: MTL queue index. - * - * @pre - * - MAC should out of reset and clocks enabled. - * - hw core initialized. see osi_hw_core_init(). - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_014 - * - * @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. - */ -int osi_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, - const unsigned int qinx); - /** * @brief osi_config_mac_loopback - Configure MAC loopback * @@ -856,7 +783,7 @@ int osi_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, * * @note * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_015 + * - SWUD_ID: ETHERNET_NVETHERNETRM_014 * * @note * Classification: @@ -877,118 +804,6 @@ int osi_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, int osi_config_mac_loopback(struct osi_core_priv_data *const osi_core, const unsigned int lb_mode); -/** - * @brief osi_set_avb - Set CBS algo and parameters - * - * @note - * Algorithm: - * - Set AVB algo and populated parameter from osi_core_avb - * structure for TC/TQ - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] avb: osi core avb 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_016 - * - * @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. - */ -int osi_set_avb(struct osi_core_priv_data *const osi_core, - const struct osi_core_avb_algorithm *avb); - -/** - * @brief osi_get_avb - Get CBS algo and parameters - * - * @note - * Algorithm: - * - get AVB algo and populated parameter from osi_core_avb - * structure for TC/TQ - * - * @param[in] osi_core: OSI core private data structure. - * @param[out] avb: osi core avb 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_017 - * - * @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. - */ -int osi_get_avb(struct osi_core_priv_data *const osi_core, - struct osi_core_avb_algorithm *avb); - -/** - * @brief osi_configure_txstatus - Configure Tx packet status reporting - * - * @note - * Algorithm: - * - Configure MAC to enable/disable Tx status error - * reporting. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] tx_status: Enable or disable tx packet status reporting - * - * @pre MAC should be init and started. see osi_start_mac() - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_018 - * - * @note - * Classification: - * - Interrupt: No - * - Signal handler: No - * - Thread safe: No - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -int osi_configure_txstatus(struct osi_core_priv_data *const osi_core, - const unsigned int tx_status); - /** * @brief osi_config_fw_err_pkts - Configure forwarding of error packets * @@ -1004,7 +819,7 @@ int osi_configure_txstatus(struct osi_core_priv_data *const osi_core, * * @note * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_029 + * - SWUD_ID: ETHERNET_NVETHERNETRM_020 * * @note * Classification: @@ -1025,120 +840,6 @@ int osi_configure_txstatus(struct osi_core_priv_data *const osi_core, int osi_config_fw_err_pkts(struct osi_core_priv_data *const osi_core, const unsigned int qinx, const unsigned int fw_err); -/** - * @brief osi_config_rx_crc_check - Configure CRC Checking for Received 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 init and started. see osi_start_mac() - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_019 - * - * @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. - */ -int osi_config_rx_crc_check(struct osi_core_priv_data *const osi_core, - const unsigned int crc_chk); - -/** - * @brief osi_configure_flow_ctrl - Configure flow control settings - * - * @note - * Algorithm: - * - This will enable or disable the flow control. - * flw_ctrl BIT0 is for tx flow ctrl enable/disable - * flw_ctrl BIT1 is for rx flow ctrl enable/disable - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] flw_ctrl: Enable or disable flow control settings - * - * @pre MAC should be init and started. see osi_start_mac() - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_024 - * - * @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. - */ -int osi_configure_flow_control( - struct osi_core_priv_data *const osi_core, - const unsigned int flw_ctrl); - -/** - * @brief osi_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: - * - SWUD_ID: ETHERNET_NVETHERNETRM_022 - * - * @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. - */ -int osi_config_arp_offload(struct osi_core_priv_data *const osi_core, - const unsigned int flags, - const unsigned char *ip_addr); - /** * @brief osi_config_rxcsum_offload - Configure RX checksum offload in MAC. * @@ -1153,7 +854,7 @@ int osi_config_arp_offload(struct osi_core_priv_data *const osi_core, * * @note * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_023 + * - SWUD_ID: ETHERNET_NVETHERNETRM_017 * * @note * Classification: @@ -1192,7 +893,7 @@ int osi_config_rxcsum_offload( * * @note * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_025 + * - SWUD_ID: ETHERNET_NVETHERNETRM_018 * * @note * Classification: @@ -1213,84 +914,6 @@ int osi_config_rxcsum_offload( int osi_l2_filter(struct osi_core_priv_data *const osi_core, const struct osi_filter *filter); -/** - * @brief osi_config_vlan_filtering - OSI call for configuring VLAN filter - * - * @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 private data structure. - * @param[in] filter_enb_dis: vlan filter enable(1) disable(0) - * @param[in] perfect_hash_filtering: perfect(0) or hash filter(1) - * @param[in] perfect_inverse_match: normal(0) or inverse filter(1) - * - * @pre - * - MAC should be init and started. see osi_start_mac() - * - osi_core->osd should be populated - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_027 - * - * @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. - */ -int osi_config_vlan_filtering( - struct osi_core_priv_data *const osi_core, - const unsigned int filter_enb_dis, - const unsigned int perfect_hash_filtering, - const unsigned int perfect_inverse_match); - -/** - * @brief osi_update_vlan_id - 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: - * - SWUD_ID: ETHERNET_NVETHERNETRM_028 - * - * @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. - */ -int osi_update_vlan_id(struct osi_core_priv_data *const osi_core, - const unsigned int vid); - /** * @brief osi_write_phy_reg - Write to a PHY register through MAC over MDIO bus. * @@ -1339,7 +962,7 @@ int osi_write_phy_reg(struct osi_core_priv_data *const osi_core, /** * @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 @@ -1353,7 +976,7 @@ int osi_write_phy_reg(struct osi_core_priv_data *const osi_core, * * @note * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_035 + * - SWUD_ID: ETHERNET_NVETHERNETRM_025 * * @note * Classification: @@ -1373,43 +996,6 @@ int osi_write_phy_reg(struct osi_core_priv_data *const osi_core, */ int osi_read_mmc(struct osi_core_priv_data *const osi_core); -/** - * @brief osi_reset_mmc - invoke function to reset MMC counter and data - * structure - * - * @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_036 - * - * @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. - */ -int osi_reset_mmc(struct osi_core_priv_data *const osi_core); - /** * @brief osi_read_phy_reg - Read from a PHY register through MAC over MDIO bus. * @@ -1497,7 +1083,7 @@ int osi_init_core_ops(struct osi_core_priv_data *const osi_core); * * @note * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_034 + * - SWUD_ID: ETHERNET_NVETHERNETRM_024 * * @note * Classification: @@ -1534,7 +1120,7 @@ int osi_set_systime_to_mac(struct osi_core_priv_data *const osi_core, * * @note * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_033 + * - SWUD_ID: ETHERNET_NVETHERNETRM_023 * * @note * Classification: @@ -1571,7 +1157,7 @@ int osi_adjust_freq(struct osi_core_priv_data *const osi_core, int ppb); * * @note * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_032 + * - SWUD_ID: ETHERNET_NVETHERNETRM_022 * * @note * Classification: @@ -1592,43 +1178,6 @@ int osi_adjust_freq(struct osi_core_priv_data *const osi_core, int ppb); int osi_adjust_time(struct osi_core_priv_data *const osi_core, long long nsec_delta); -/** - * @brief osi_get_systime_from_mac - Get system time - * - * @note - * Algorithm: - * - Gets the current system time - * - * @param[in] osi_core: OSI core 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_NVETHERNETRM_031 - * - * @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. - */ -int osi_get_systime_from_mac( - struct osi_core_priv_data *const osi_core, - unsigned int *sec, - unsigned int *nsec); /** * @brief osi_ptp_configuration - Configure PTP * @@ -1654,7 +1203,7 @@ int osi_get_systime_from_mac( * * @note * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_030 + * - SWUD_ID: ETHERNET_NVETHERNETRM_021 * * @note * Classification: @@ -1712,7 +1261,7 @@ void *eqos_get_core_safety_config(void); * * @note * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_026 + * - SWUD_ID: ETHERNET_NVETHERNETRM_019 * * @note * Classification: @@ -1737,6 +1286,446 @@ int osi_l3l4_filter(struct osi_core_priv_data *const osi_core, const unsigned int dma_chan, const unsigned int is_l4_filter); +#ifndef OSI_STRIPPED_LIB +/** + * @brief osi_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_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. + */ +int osi_validate_core_regs(struct osi_core_priv_data *const osi_core); + +/** + * @brief osi_flush_mtl_tx_queue - Flushing a MTL Tx Queue. + * + * @note + * Algorithm: + * - Invokes EQOS flush Tx queue routine. + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] qinx: MTL queue index. + * + * @pre + * - MAC should out of reset and clocks enabled. + * - hw core initialized. see osi_hw_core_init(). + * + * @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. + */ +int osi_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, + const unsigned int qinx); + +/** + * @brief osi_set_avb - Set CBS algo and parameters + * + * @note + * Algorithm: + * - Set AVB algo and populated parameter from osi_core_avb + * structure for TC/TQ + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] avb: osi core avb data structure. + * + * @pre + * - MAC should be init and started. see osi_start_mac() + * - osi_core->osd should be populated. + * + * @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. + */ +int osi_set_avb(struct osi_core_priv_data *const osi_core, + const struct osi_core_avb_algorithm *avb); + +/** + * @brief osi_get_avb - Get CBS algo and parameters + * + * @note + * Algorithm: + * - get AVB algo and populated parameter from osi_core_avb + * structure for TC/TQ + * + * @param[in] osi_core: OSI core private data structure. + * @param[out] avb: osi core avb data structure. + * + * @pre + * - MAC should be init and started. see osi_start_mac() + * - osi_core->osd should be populated. + * + * @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. + */ +int osi_get_avb(struct osi_core_priv_data *const osi_core, + struct osi_core_avb_algorithm *avb); + +/** + * @brief osi_configure_txstatus - Configure Tx packet status reporting + * + * @note + * Algorithm: + * - Configure MAC to enable/disable Tx status error + * reporting. + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] tx_status: Enable or disable tx packet status reporting + * + * @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: No + * - De-initialization: No + * + * @retval 0 on success + * @retval -1 on failure. + */ +int osi_configure_txstatus(struct osi_core_priv_data *const osi_core, + const unsigned int tx_status); + +/** + * @brief osi_config_rx_crc_check - Configure CRC Checking for Received 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 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. + */ +int osi_config_rx_crc_check(struct osi_core_priv_data *const osi_core, + const unsigned int crc_chk); + +/** + * @brief osi_configure_flow_ctrl - Configure flow control settings + * + * @note + * Algorithm: + * - This will enable or disable the flow control. + * flw_ctrl BIT0 is for tx flow ctrl enable/disable + * flw_ctrl BIT1 is for rx flow ctrl enable/disable + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] flw_ctrl: Enable or disable flow control settings + * + * @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. + */ +int osi_configure_flow_control(struct osi_core_priv_data *const osi_core, + const unsigned int flw_ctrl); + +/** + * @brief osi_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: Yes + * - Run time: Yes + * - De-initialization: No + * + * @retval 0 on success + * @retval -1 on failure. + */ +int osi_config_arp_offload(struct osi_core_priv_data *const osi_core, + const unsigned int flags, + const unsigned char *ip_addr); +/** + * @brief osi_config_vlan_filtering - OSI call for configuring VLAN filter + * + * @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 private data structure. + * @param[in] filter_enb_dis: vlan filter enable(1) disable(0) + * @param[in] perfect_hash_filtering: perfect(0) or hash filter(1) + * @param[in] perfect_inverse_match: normal(0) or inverse filter(1) + * + * @pre + * - MAC should be init and started. see osi_start_mac() + * - osi_core->osd should be populated + * + * @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. + */ +int osi_config_vlan_filtering(struct osi_core_priv_data *const osi_core, + const unsigned int filter_enb_dis, + const unsigned int perfect_hash_filtering, + const unsigned int perfect_inverse_match); + +/** + * @brief osi_update_vlan_id - 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. + */ +int osi_update_vlan_id(struct osi_core_priv_data *const osi_core, + const unsigned int vid); + +/** + * @brief osi_reset_mmc - invoke function to reset MMC counter and data + * structure + * + * @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: + * + * @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. + */ +int osi_reset_mmc(struct osi_core_priv_data *const osi_core); + +/** + * @brief osi_get_systime_from_mac - Get system time + * + * @note + * Algorithm: + * - Gets the current system time + * + * @param[in] osi_core: OSI core 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: + * + * @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. + */ +int osi_get_systime_from_mac(struct osi_core_priv_data *const osi_core, + unsigned int *sec, + unsigned int *nsec); + /** * @brief osi_configure_eee - Configure EEE LPI in MAC. * @@ -1754,7 +1743,6 @@ int osi_l3l4_filter(struct osi_core_priv_data *const osi_core, * * @note * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_038 * * @note * Classification: @@ -1803,4 +1791,5 @@ int osi_save_registers(struct osi_core_priv_data *const osi_core); * @retval -1 on failure. */ int osi_restore_registers(struct osi_core_priv_data *const osi_core); +#endif /* !OSI_STRIPPED_LIB */ #endif /* OSI_CORE_H */ diff --git a/include/osi_dma.h b/include/osi_dma.h index 3ee9bd8..c8031fa 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -73,8 +73,8 @@ * @addtogroup EQOS-TX Tx done packet context fields * * @brief These flags used to convey transmit done packet context information, - * whether transmitted packet used a pagged buffer, whether transmitted packet - * has an tx error, whether tranmitted packet has an TS + * whether transmitted packet used a paged buffer, whether transmitted packet + * has an tx error, whether transmitted packet has an TS * * @{ */ @@ -360,6 +360,7 @@ struct osi_dma_chan_ops { void (*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 */ int (*validate_regs)(struct osi_dma_priv_data *osi_dma); @@ -368,6 +369,7 @@ struct osi_dma_chan_ops { unsigned int chan, unsigned int set, unsigned int interval); +#endif /* !OSI_STRIPPED_LIB */ /** Called to get Global DMA status */ unsigned int (*get_global_dma_status)(void *addr); /** Called to clear VM Tx interrupt */ @@ -467,44 +469,6 @@ struct osi_dma_priv_data { unsigned long resv_buf_phy_addr; }; -/** - * @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 iff (osi_dma_priv_data->safety_config != OSI_NULL) - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETCL_016 - * - * @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. - */ -int osi_validate_dma_regs(struct osi_dma_priv_data *osi_dma); /** * @brief osi_disable_chan_tx_intr - Disables DMA Tx channel interrupts. @@ -662,6 +626,22 @@ int osi_disable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, int osi_enable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, unsigned int 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. + * @param[in] chan: DMA tx channel number. + * + * @note + * Dependencies: None. + * Protection: None. + * + * @retval status + */ +unsigned int osi_get_global_dma_status(struct osi_dma_priv_data *osi_dma); + /** * @brief osi_clear_vm_tx_intr - Handles VM Tx interrupt source. * @@ -786,7 +766,7 @@ int osi_stop_dma(struct osi_dma_priv_data *osi_dma, * * @note * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETCL_008 + * - SWUD_ID: ETHERNET_NVETHERNETCL_007 * * @note * Classification: @@ -810,9 +790,9 @@ unsigned int osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring); * * @note * Algorithm: - * - Initialise a Rx DMA descriptor. + * - Initialize a Rx DMA descriptor. * - * @param[in] osi_dma: OSI DMA private data struture. + * @param[in] osi_dma: OSI DMA private data structure. * @param[in] rx_ring: HW ring corresponding to Rx DMA channel. * @param[in] chan: Rx DMA channel number * @@ -823,7 +803,7 @@ unsigned int osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring); * * @note * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETCL_007 + * - SWUD_ID: ETHERNET_NVETHERNETCL_008 * * @note * Classification: @@ -847,7 +827,7 @@ int osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, /** * @brief Updates rx buffer length. * - * @param[in] osi_dma: OSI DMA private data struture. + * @param[in] osi_dma: OSI DMA private data structure. * * @pre * - MAC needs to be out of reset and proper clocks need to be configured. @@ -961,7 +941,7 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan); * - Run time: Yes * - De-initialization: No * - * @returns Number of decriptors (buffers) proccessed. + * @returns Number of descriptors (buffers) processed. */ int osi_process_tx_completions(struct osi_dma_priv_data *osi, unsigned int chan, int budget); @@ -983,7 +963,7 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi, * * @param[in] osi: OSI private data structure. * @param[in] chan: Rx DMA channel number - * @param[in] budget: Threshould for reading the packets at a time. + * @param[in] budget: Threshold for reading the packets at a time. * @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). * @@ -1009,7 +989,7 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi, * - Run time: Yes * - De-initialization: No * - * @returns Number of decriptors (buffers) proccessed. + * @returns Number of descriptors (buffers) processed. */ int osi_process_rx_completions(struct osi_dma_priv_data *osi, unsigned int chan, int budget, @@ -1029,7 +1009,7 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, * @pre * - Allocate memory for osi_dma * - MAC needs to be out of reset and proper clocks need to be configured. - * - Numer of dma channels osi_dma->num_dma_chans + * - 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 @@ -1134,6 +1114,116 @@ int osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma); */ int 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 + * + * @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. + */ +int osi_dma_get_systime_from_mac( + struct osi_dma_priv_data *const osi_dma, + unsigned int *sec, + unsigned int *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 + * + * @note + * Classification: + * - Interrupt: No + * - Signal handler: No + * - Thread safe: No + * - Required Privileges: None + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: No + * - De-initialization: No + * + * @retval OSI_ENABLE if MAC enabled. + * @retval OSI_DISABLE otherwise. + */ +unsigned int osi_is_mac_enabled(struct osi_dma_priv_data *const 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: + * + * @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. + */ +int osi_validate_dma_regs(struct osi_dma_priv_data *osi_dma); + /** * @brief osi_clear_tx_pkt_err_stats - Clear tx packet error stats. * @@ -1150,7 +1240,6 @@ int osi_init_dma_ops(struct osi_dma_priv_data *osi_dma); * * @note * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETCL_018 * * @note * Classification: @@ -1184,7 +1273,6 @@ int osi_clear_tx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); * * @note * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETCL_017 * * @note * Classification: @@ -1204,7 +1292,6 @@ int osi_clear_tx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); */ int osi_config_slot_function(struct osi_dma_priv_data *osi_dma, unsigned int set); - /** * @brief osi_clear_rx_pkt_err_stats - Clear rx packet error stats. * @@ -1244,90 +1331,5 @@ int osi_clear_rx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); * @retval 0 if ring has outstanding packets. */ int osi_txring_empty(struct osi_dma_priv_data *osi_dma, unsigned int chan); - -/** - * @brief osi_get_global_dma_status - Gets DMA status. - * - * Algorithm: Returns global DMA Tx/Rx interrupt status - * - * @param[in] osi_dma: OSI DMA private data structure. - * - * @note - * Dependencies: None. - * Protection: None. - * - * @retval status - */ -unsigned int osi_get_global_dma_status(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_019 - * - * @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. - */ -int osi_dma_get_systime_from_mac( - struct osi_dma_priv_data *const osi_dma, - unsigned int *sec, - unsigned int *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_020 - * - * @note - * Classification: - * - Interrupt: No - * - Signal handler: No - * - Thread safe: No - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @retval OSI_ENABLE if MAC enabled. - * @retval OSI_DISABLE otherwise. - */ -unsigned int osi_is_mac_enabled(struct osi_dma_priv_data *const osi_dma); +#endif /* !OSI_STRIPPED_LIB */ #endif /* OSI_DMA_H */ diff --git a/osi/core/Makefile.tmk b/osi/core/Makefile.tmk index 86762b4..197724a 100644 --- a/osi/core/Makefile.tmk +++ b/osi/core/Makefile.tmk @@ -26,6 +26,7 @@ ifdef NV_COMPONENT_FLAG_SHARED_LIBRARY_SECTION include $(NV_BUILD_START_COMPONENT) NV_COMPONENT_STRICT_WARNINGS_qnx_64 := 1 +NV_COMPONENT_CFLAGS := -DOSI_STRIPPED_LIB NV_COMPONENT_NAME := nvethernetrm NV_COMPONENT_OWN_INTERFACE_DIR := . diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 5751acf..a428e8d 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -68,7 +68,7 @@ static inline void eqos_core_safety_writel(unsigned int val, void *addr, * - 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 ivoked periodically to compare + * 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. * @@ -294,71 +294,6 @@ static void eqos_core_backup_init(struct osi_core_priv_data *const osi_core) EQOS_PAD_AUTO_CAL_CFG; } -/** - * @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 iff (osi_core_priv_data->safety_config != OSI_NULL) - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int 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; - unsigned int cur_val; - unsigned int 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; - } - /* FIXME - * QNX OSD currently overwrites following registers and - * therefore validation fails using this API. Add an - * exception for following registers until QNX OSD completely - * moves to common library. - */ - if ((i == EQOS_MAC_PFR_IDX) || (i == EQOS_MAC_HTR0_IDX) - || (i == EQOS_MAC_HTR1_IDX) || (i == EQOS_MAC_HTR2_IDX) - || (i == EQOS_MAC_HTR3_IDX) || (i == EQOS_MAC_TCR_IDX) - || (i == EQOS_MAC_SSIR_IDX) || (i == EQOS_MAC_TAR_IDX)) - { - continue; - } - - cur_val = osi_readl((unsigned char *)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); - return -1; - } - } - osi_unlock_irq_enabled(&config->core_safety_lock); - - return 0; -} - /** * @brief eqos_config_flow_control - Configure MAC flow control settings * @@ -425,54 +360,6 @@ static int eqos_config_flow_control(void *addr, 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] addr: Base address indicating the start of - * memory mapped IO region of the MAC. - * @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() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int eqos_config_rx_crc_check(void *addr, - const unsigned int crc_chk) -{ - unsigned int val; - - /* return on invalid argument */ - if (crc_chk != OSI_ENABLE && crc_chk != OSI_DISABLE) { - return -1; - } - - /* Read MAC Extension Register */ - val = osi_readl((unsigned char *)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_writel(val, (unsigned char *)addr + EQOS_MAC_EXTR); - - return 0; -} - /** * @brief eqos_config_fw_err_pkts - Configure forwarding of error packets * @@ -523,7 +410,7 @@ static int eqos_config_fw_err_pkts(void *addr, /* Nothing here */ } - /* Write to FEP bit of MTL RXQ Operation Mode Register to enable or + /* 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(val, (unsigned char *)addr + @@ -533,60 +420,6 @@ static int eqos_config_fw_err_pkts(void *addr, 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] addr: Base address indicating the start of - * memory mapped IO region of the MAC. - * @param[in] tx_status: Enable or Disable the forwarding of tx pkt status - * - * @pre MAC should be initialized and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int eqos_config_tx_status(void *addr, - const unsigned int tx_status) -{ - unsigned int val; - - /* don't allow if tx_status is other than 0 or 1 */ - if (tx_status != OSI_ENABLE && tx_status != OSI_DISABLE) { - return -1; - } - - /* Read MTL Operation Mode Register */ - val = osi_readl((unsigned char *)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_writel(val, (unsigned char *)addr + EQOS_MTL_OP_MODE); - - return 0; -} - /** * @brief eqos_config_mac_loopback - Configure MAC to support loopback * @@ -694,7 +527,7 @@ static int eqos_poll_for_swr(void *addr, unsigned int pre_si) * * @note * Algorithm: - * - MDC clock rate will be polulated OSI core private data structure + * - MDC clock rate will be populated OSI core private data structure * based on AXI_CBB clock rate. * * @param[in] osi_core: OSI core private data structure. @@ -1047,7 +880,7 @@ static int eqos_flush_mtl_tx_queue(void *addr, * * @note * Algorithm: - * - Calulates and stores the RSD (Threshold for Dectivating + * - 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 * @@ -1219,7 +1052,7 @@ static int eqos_configure_mtl_queue(unsigned int qinx, } /** - * @brief eqos_config_rxcsum_offload - Enable/Disale rx checksum offload in HW + * @brief eqos_config_rxcsum_offload - Enable/Disable rx checksum offload in HW * * @note * Algorithm: @@ -1375,13 +1208,13 @@ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) /* if MTU greater 9K use GPSLCE */ value |= EQOS_MCR_JD | EQOS_MCR_WD; value |= EQOS_MCR_GPSLCE; - /* Read MAC Extenstion Register */ + /* Read MAC Extension Register */ mac_ext = osi_readl((unsigned char *)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 Extenstion Register */ + /* Write MAC Extension Register */ osi_writel(mac_ext, (unsigned char *)osi_core->base + EQOS_MAC_EXTR); } else { @@ -1826,122 +1659,6 @@ static void eqos_stop_mac(void *addr) EQOS_MAC_MCR_IDX); } -/** - * @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 contro - * - 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. - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int eqos_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; - - if (avb == OSI_NULL) { - OSI_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_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_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid Queue mode\n", - (unsigned long long)avb->qindex); - return ret; - } - - /* can't set AVB mode for queue 0 */ - if ((avb->qindex == 0U) && (avb->oper_mode == OSI_MTL_QUEUE_AVB)) { - OSI_ERR(osi_core->osd, OSI_LOG_ARG_OPNOTSUPP, - "Not allowed to set AVB for Q0\n", - (unsigned long long)avb->qindex); - return ret; - } - - qinx = avb->qindex; - value = osi_readl((unsigned char *)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(value, (unsigned char *)osi_core->base + - EQOS_MTL_CHX_TX_OP_MODE(qinx), - EQOS_MTL_CH0_TX_OP_MODE_IDX + qinx); - - /* Set Algo and Credit control */ - 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_writel(value, (unsigned char *)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_writel(value, (unsigned char *)osi_core->base + - EQOS_MTL_TXQ_ETS_SSCR(qinx)); - - /* Set Idle slope credit*/ - value = osi_readl((unsigned char *)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(value, (unsigned char *)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_writel(value, (unsigned char *)osi_core->base + - EQOS_MTL_TXQ_ETS_HCR(qinx)); - - /* low credit is -ve number, osi_write need a unsigned int - * take only 28:0 bits from avb->low_credit - */ - value = avb->low_credit & EQOS_MTL_TXQ_ETS_LCR_LC_MASK; - osi_writel(value, (unsigned char *)osi_core->base + - EQOS_MTL_TXQ_ETS_LCR(qinx)); - } - - return 0; -} - /** * @brief eqos_config_l2_da_perfect_inverse_match - configure register for * inverse or perfect match. @@ -1980,7 +1697,7 @@ static inline int eqos_config_l2_da_perfect_inverse_match(void *base, * * @note * Algorithm: - * - This sequence is used to configure MAC in differnet pkt + * - This sequence is used to configure MAC in different pkt * processing modes like promiscuous, multicast, unicast, * hash unicast/multicast. * @@ -2050,7 +1767,7 @@ static int eqos_config_mac_pkt_filter_reg( * * @note * Algorithm: - * - This helper routine is to update passed prameter value + * - This helper routine is to update passed parameter value * based on DCS and MBC parameter. Validation of dma_chan as well as * dsc_en status performed before updating DCS bits. * @@ -2203,159 +1920,6 @@ static int eqos_update_mac_addr_low_high_reg( return ret; } -/** - * @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 contro - * - 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. - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int eqos_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; - - if (avb == OSI_NULL) { - OSI_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_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid Queue index\n", - (unsigned long long)avb->qindex); - return ret; - } - - qinx = avb->qindex; - value = osi_readl((unsigned char *)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_readl((unsigned char *)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_readl((unsigned char *)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_readl((unsigned char *)osi_core->base + - EQOS_MTL_TXQ_QW(qinx)); - avb->idle_slope = value & EQOS_MTL_TXQ_ETS_QW_ISCQW_MASK; - - /* Get Hi credit */ - value = osi_readl((unsigned char *)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_readl((unsigned char *)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] mac_ver: MAC version number (different MAC HW version - * need different register offset/fields for ARP offload. - * @param[in] addr: EQOS 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. - * - * @pre - * - MAC should be initialized and started. see osi_start_mac() - * - Valid 4 byte IP address as argument ip_addr - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int eqos_config_arp_offload(const unsigned int mac_ver, void *addr, - const unsigned int enable, - const unsigned char *ip_addr) -{ - unsigned int mac_mcr; - unsigned int val; - - if (enable != OSI_ENABLE && enable != OSI_DISABLE) { - return -1; - } - - mac_mcr = osi_readl((unsigned char *)addr + EQOS_MAC_MCR); - - 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])); - - if (mac_ver == OSI_EQOS_MAC_4_10) { - osi_writel(val, (unsigned char *)addr + - EQOS_4_10_MAC_ARPPA); - } else if (mac_ver >= OSI_EQOS_MAC_5_00) { - osi_writel(val, (unsigned char *)addr + - EQOS_5_00_MAC_ARPPA); - } else { - /* Unsupported MAC ver */ - return -1; - } - - mac_mcr |= EQOS_MCR_ARPEN; - } else { - mac_mcr &= ~EQOS_MCR_ARPEN; - } - - eqos_core_safety_writel(mac_mcr, (unsigned char *)addr + EQOS_MAC_MCR, - EQOS_MAC_MCR_IDX); - - return 0; -} - /** * @brief eqos_config_l3_l4_filter_enable - register write to enable L3/L4 * filters. @@ -2456,7 +2020,7 @@ static int eqos_update_ip4_addr( * * @param[in] osi_core: OSI core private data structure. * @param[in] filter_no: filter index - * @param[in] addr: ipv6 adderss + * @param[in] addr: ipv6 address * * @pre MAC should be initialized and started. see osi_start_mac() * @@ -2937,71 +2501,6 @@ static int eqos_config_l4_filters( 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: 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 - * - * @pre - * - MAC should be initialized and started. see osi_start_mac() - * - osi_core->osd should be populated. - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int eqos_config_vlan_filtering( - struct osi_core_priv_data *const osi_core, - const unsigned int filter_enb_dis, - const unsigned int perfect_hash_filtering, - const unsigned int perfect_inverse_match) -{ - unsigned int value; - void *base = osi_core->base; - - value = osi_readl((unsigned char *)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(value, (unsigned char *)base + EQOS_MAC_PFR, - EQOS_MAC_PFR_IDX); - - value = osi_readl((unsigned char *)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_ERR(osi_core->osd, OSI_LOG_ARG_OPNOTSUPP, - "VLAN hash filter is not supported, no updat of VTHM\n", - 0ULL); - } - osi_writel(value, (unsigned char *)base + EQOS_MAC_VLAN_TR); - return 0; -} - -/** - * @brief eqos_update_vlan_id - update VLAN ID in Tag register - * - * @param[in] base: Base address from OSI core private data structure. - * @param[in] vid: VLAN ID to be programmed. - * - * @retval 0 always - */ -static inline int eqos_update_vlan_id(void *base, unsigned int vid) -{ - /* Don't add VLAN ID to TR register which is eventually set TR - * to 0x0 and allow all tagged packets - */ - - return 0; -} - /** * @brief eqos_poll_for_tsinit_complete - Poll for time stamp init complete * @@ -3449,164 +2948,6 @@ static void eqos_core_deinit(struct osi_core_priv_data *const osi_core) eqos_stop_mac(osi_core->base); } -/** - * @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] addr: base address of memory mapped register space of MAC. - * - * @pre MAC has to be out of reset, and clocks supplied. - */ -static inline void eqos_disable_tx_lpi(void *addr) -{ - unsigned int lpi_csr = 0; - - /* Disable LPI control bits */ - lpi_csr = osi_readl((unsigned char *)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_writel(lpi_csr, (unsigned char *)addr + EQOS_MAC_LPI_CSR); -} - -/** - * @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 - */ -static void eqos_configure_eee( - struct osi_core_priv_data *const osi_core, - const unsigned int tx_lpi_enabled, - const unsigned int tx_lpi_timer) -{ - unsigned int lpi_csr = 0; - unsigned int lpi_timer_ctrl = 0; - unsigned int lpi_entry_timer = 0; - unsigned int lpi_1US_tic_counter = OSI_LPI_1US_TIC_COUNTER_DEFAULT; - unsigned char *addr = (unsigned char *)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_writel(lpi_timer_ctrl, addr + EQOS_MAC_LPI_TIMER_CTRL); - - lpi_entry_timer |= (tx_lpi_timer & - OSI_LPI_ENTRY_TIMER_MASK); - osi_writel(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_writel(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_readl(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_writel(lpi_csr, addr + EQOS_MAC_LPI_CSR); - } else { - /* Disable LPI control bits */ - eqos_disable_tx_lpi(osi_core->base); - } -} - -/** - * @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. - * - * @retval 0 on Success - */ -static inline int eqos_save_registers( - struct osi_core_priv_data *const osi_core) -{ - unsigned int 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_readl(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. - * - * @retval 0 on Success - */ -static inline int eqos_restore_registers( - struct osi_core_priv_data *const osi_core) -{ - unsigned int 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_writel(config->reg_val[i], config->reg_addr[i]); - } - } - - return 0; -} - /** * @brief poll_for_mii_idle Query the status of an ongoing DMA transfer * @@ -3808,6 +3149,652 @@ static int eqos_read_phy_reg(struct osi_core_priv_data *const osi_core, return (int)data; } +#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] addr: base address of memory mapped register space of MAC. + * + * @pre MAC has to be out of reset, and clocks supplied. + */ +static inline void eqos_disable_tx_lpi(void *addr) +{ + unsigned int lpi_csr = 0; + + /* Disable LPI control bits */ + lpi_csr = osi_readl((unsigned char *)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_writel(lpi_csr, (unsigned char *)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) + * + * @retval 0 on success + * @retval -1 on failure. + */ +static int 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; + unsigned int cur_val; + unsigned int 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_readl((unsigned char *)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); + 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] addr: Base address indicating the start of + * memory mapped IO region of the MAC. + * @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() + * + * @retval 0 on success + * @retval -1 on failure. + */ +static int eqos_config_rx_crc_check(void *addr, + const unsigned int crc_chk) +{ + unsigned int val; + + /* return on invalid argument */ + if (crc_chk != OSI_ENABLE && crc_chk != OSI_DISABLE) { + return -1; + } + + /* Read MAC Extension Register */ + val = osi_readl((unsigned char *)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_writel(val, (unsigned char *)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] addr: Base address indicating the start of + * memory mapped IO region of the MAC. + * @param[in] tx_status: Enable or Disable the forwarding of tx pkt status + * + * @pre MAC should be initialized and started. see osi_start_mac() + * + * @retval 0 on success + * @retval -1 on failure. + */ +static int eqos_config_tx_status(void *addr, + const unsigned int tx_status) +{ + unsigned int val; + + /* don't allow if tx_status is other than 0 or 1 */ + if (tx_status != OSI_ENABLE && tx_status != OSI_DISABLE) { + return -1; + } + + /* Read MTL Operation Mode Register */ + val = osi_readl((unsigned char *)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_writel(val, (unsigned char *)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. + * + * @retval 0 on success + * @retval -1 on failure. + */ +static int eqos_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; + + if (avb == OSI_NULL) { + OSI_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_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_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "Invalid Queue mode\n", + (unsigned long long)avb->qindex); + return ret; + } + + /* can't set AVB mode for queue 0 */ + if ((avb->qindex == 0U) && (avb->oper_mode == OSI_MTL_QUEUE_AVB)) { + OSI_ERR(osi_core->osd, OSI_LOG_ARG_OPNOTSUPP, + "Not allowed to set AVB for Q0\n", + (unsigned long long)avb->qindex); + return ret; + } + + qinx = avb->qindex; + value = osi_readl((unsigned char *)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(value, (unsigned char *)osi_core->base + + EQOS_MTL_CHX_TX_OP_MODE(qinx), + EQOS_MTL_CH0_TX_OP_MODE_IDX + qinx); + + /* Set Algo and Credit control */ + 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_writel(value, (unsigned char *)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_writel(value, (unsigned char *)osi_core->base + + EQOS_MTL_TXQ_ETS_SSCR(qinx)); + + /* Set Idle slope credit*/ + value = osi_readl((unsigned char *)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(value, (unsigned char *)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_writel(value, (unsigned char *)osi_core->base + + EQOS_MTL_TXQ_ETS_HCR(qinx)); + + /* low credit is -ve number, osi_write need a unsigned int + * take only 28:0 bits from avb->low_credit + */ + value = avb->low_credit & EQOS_MTL_TXQ_ETS_LCR_LC_MASK; + osi_writel(value, (unsigned char *)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. + * + * @retval 0 on success + * @retval -1 on failure. + */ +static int eqos_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; + + if (avb == OSI_NULL) { + OSI_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_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "Invalid Queue index\n", + (unsigned long long)avb->qindex); + return ret; + } + + qinx = avb->qindex; + value = osi_readl((unsigned char *)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_readl((unsigned char *)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_readl((unsigned char *)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_readl((unsigned char *)osi_core->base + + EQOS_MTL_TXQ_QW(qinx)); + avb->idle_slope = value & EQOS_MTL_TXQ_ETS_QW_ISCQW_MASK; + + /* Get Hi credit */ + value = osi_readl((unsigned char *)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_readl((unsigned char *)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] mac_ver: MAC version number (different MAC HW version + * need different register offset/fields for ARP offload. + * @param[in] addr: EQOS 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. + * + * @pre + * - MAC should be initialized and started. see osi_start_mac() + * - Valid 4 byte IP address as argument ip_addr + * + * @retval 0 on success + * @retval -1 on failure. + */ +static int eqos_config_arp_offload(const unsigned int mac_ver, void *addr, + const unsigned int enable, + const unsigned char *ip_addr) +{ + unsigned int mac_mcr; + unsigned int val; + + if (enable != OSI_ENABLE && enable != OSI_DISABLE) { + return -1; + } + + mac_mcr = osi_readl((unsigned char *)addr + EQOS_MAC_MCR); + + 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])); + + if (mac_ver == OSI_EQOS_MAC_4_10) { + osi_writel(val, (unsigned char *)addr + + EQOS_4_10_MAC_ARPPA); + } else if (mac_ver == OSI_EQOS_MAC_5_00) { + osi_writel(val, (unsigned char *)addr + + EQOS_5_00_MAC_ARPPA); + } else { + /* Unsupported MAC ver */ + return -1; + } + + mac_mcr |= EQOS_MCR_ARPEN; + } else { + mac_mcr &= ~EQOS_MCR_ARPEN; + } + + eqos_core_safety_writel(mac_mcr, (unsigned char *)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: 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 + * + * @pre + * - MAC should be initialized and started. see osi_start_mac() + * - osi_core->osd should be populated. + * + * @retval 0 on success + * @retval -1 on failure. + */ +static int eqos_config_vlan_filtering( + struct osi_core_priv_data *const osi_core, + const unsigned int filter_enb_dis, + const unsigned int perfect_hash_filtering, + const unsigned int perfect_inverse_match) +{ + unsigned int value; + void *base = osi_core->base; + + value = osi_readl((unsigned char *)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(value, (unsigned char *)base + EQOS_MAC_PFR, + EQOS_MAC_PFR_IDX); + + value = osi_readl((unsigned char *)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_ERR(osi_core->osd, OSI_LOG_ARG_OPNOTSUPP, + "VLAN hash filter is not supported, no updat of VTHM\n", + 0ULL); + } + osi_writel(value, (unsigned char *)base + EQOS_MAC_VLAN_TR); + return 0; +} + +/** + * @brief eqos_update_vlan_id - update VLAN ID in Tag register + * + * @param[in] base: Base address from OSI core private data structure. + * @param[in] vid: VLAN ID to be programmed. + * + * @retval 0 always + */ +static inline int eqos_update_vlan_id(void *base, unsigned int vid) +{ + /* Don't add VLAN ID to TR register which is eventually set TR + * to 0x0 and allow all tagged packets + */ + + 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 + */ +static void eqos_configure_eee( + struct osi_core_priv_data *const osi_core, + const unsigned int tx_lpi_enabled, + const unsigned int tx_lpi_timer) +{ + unsigned int lpi_csr = 0; + unsigned int lpi_timer_ctrl = 0; + unsigned int lpi_entry_timer = 0; + unsigned int lpi_1US_tic_counter = OSI_LPI_1US_TIC_COUNTER_DEFAULT; + unsigned char *addr = (unsigned char *)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_writel(lpi_timer_ctrl, addr + EQOS_MAC_LPI_TIMER_CTRL); + + lpi_entry_timer |= (tx_lpi_timer & + OSI_LPI_ENTRY_TIMER_MASK); + osi_writel(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_writel(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_readl(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_writel(lpi_csr, addr + EQOS_MAC_LPI_CSR); + } else { + /* Disable LPI control bits */ + eqos_disable_tx_lpi(osi_core->base); + } +} + +/** + * @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. + * + * @retval 0 on Success + */ +static inline int eqos_save_registers( + struct osi_core_priv_data *const osi_core) +{ + unsigned int 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_readl(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. + * + * @retval 0 on Success + */ +static inline int eqos_restore_registers( + struct osi_core_priv_data *const osi_core) +{ + unsigned int 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_writel(config->reg_val[i], config->reg_addr[i]); + } + } + + return 0; +} +#endif /* !OSI_STRIPPED_LIB */ + /** * @brief eqos_core_ops - EQOS MAC core operations */ @@ -3815,7 +3802,6 @@ static struct osi_core_ops eqos_core_ops = { .poll_for_swr = eqos_poll_for_swr, .core_init = eqos_core_init, .core_deinit = eqos_core_deinit, - .validate_regs = eqos_validate_core_regs, .start_mac = eqos_start_mac, .stop_mac = eqos_stop_mac, .handle_common_intr = eqos_handle_common_intr, @@ -3823,15 +3809,8 @@ static struct osi_core_ops eqos_core_ops = { .set_speed = eqos_set_speed, .pad_calibrate = eqos_pad_calibrate, .set_mdc_clk_rate = eqos_set_mdc_clk_rate, - .flush_mtl_tx_queue = eqos_flush_mtl_tx_queue, .config_mac_loopback = eqos_config_mac_loopback, - .set_avb_algorithm = eqos_set_avb_algorithm, - .get_avb_algorithm = eqos_get_avb_algorithm, .config_fw_err_pkts = eqos_config_fw_err_pkts, - .config_tx_status = eqos_config_tx_status, - .config_rx_crc_check = eqos_config_rx_crc_check, - .config_flow_control = eqos_config_flow_control, - .config_arp_offload = eqos_config_arp_offload, .config_rxcsum_offload = eqos_config_rxcsum_offload, .config_mac_pkt_filter_reg = eqos_config_mac_pkt_filter_reg, .update_mac_addr_low_high_reg = eqos_update_mac_addr_low_high_reg, @@ -3841,20 +3820,30 @@ static struct osi_core_ops eqos_core_ops = { .update_ip6_addr = eqos_update_ip6_addr, .config_l4_filters = eqos_config_l4_filters, .update_l4_port_no = eqos_update_l4_port_no, - .config_vlan_filtering = eqos_config_vlan_filtering, - .update_vlan_id = eqos_update_vlan_id, .set_systime_to_mac = eqos_set_systime_to_mac, .config_addend = eqos_config_addend, .adjust_mactime = eqos_adjust_mactime, .config_tscr = eqos_config_tscr, .config_ssir = eqos_config_ssir, .read_mmc = eqos_read_mmc, + .write_phy_reg = eqos_write_phy_reg, + .read_phy_reg = eqos_read_phy_reg, +#ifndef OSI_STRIPPED_LIB + .config_tx_status = eqos_config_tx_status, + .config_rx_crc_check = eqos_config_rx_crc_check, + .config_flow_control = eqos_config_flow_control, + .config_arp_offload = eqos_config_arp_offload, + .validate_regs = eqos_validate_core_regs, + .flush_mtl_tx_queue = eqos_flush_mtl_tx_queue, + .set_avb_algorithm = eqos_set_avb_algorithm, + .get_avb_algorithm = eqos_get_avb_algorithm, + .config_vlan_filtering = eqos_config_vlan_filtering, + .update_vlan_id = eqos_update_vlan_id, .reset_mmc = eqos_reset_mmc, .configure_eee = eqos_configure_eee, .save_registers = eqos_save_registers, .restore_registers = eqos_restore_registers, - .write_phy_reg = eqos_write_phy_reg, - .read_phy_reg = eqos_read_phy_reg, +#endif /* !OSI_STRIPPED_LIB */ }; /** diff --git a/osi/core/libnvethernetrm.export b/osi/core/libnvethernetrm.export index 9fe8f2e..aa7b0a1 100644 --- a/osi/core/libnvethernetrm.export +++ b/osi/core/libnvethernetrm.export @@ -1,6 +1,6 @@ ################################### tell Emacs this is a -*- makefile-gmake -*- # -# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2019-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"), @@ -36,28 +36,15 @@ osi_common_isr osi_set_mode osi_set_speed osi_pad_calibrate -osi_flush_mtl_tx_queue osi_config_mac_loopback -osi_set_avb -osi_get_avb -osi_configure_txstatus -osi_config_rx_crc_check osi_get_mac_version osi_get_hw_features -osi_config_arp_offload osi_config_rxcsum_offload -osi_configure_flow_control osi_l2_filter osi_l3l4_filter -osi_config_vlan_filtering -osi_update_vlan_id osi_config_fw_err_pkts osi_ptp_configuration -osi_get_systime_from_mac osi_adjust_time osi_adjust_freq osi_set_systime_to_mac osi_read_mmc -osi_reset_mmc -osi_validate_core_regs -osi_configure_eee diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 382efa8..d375e31 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -111,19 +111,6 @@ int osi_hw_core_deinit(struct osi_core_priv_data *const osi_core) return -1; } -int osi_validate_core_regs(struct osi_core_priv_data *const osi_core) -{ - int ret = -1; - - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->validate_regs != OSI_NULL) && - (osi_core->safety_config != OSI_NULL)) { - ret = osi_core->ops->validate_regs(osi_core); - } - - return ret; -} - int osi_start_mac(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && @@ -190,21 +177,10 @@ int osi_pad_calibrate(struct osi_core_priv_data *const osi_core) return -1; } -int osi_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, - const unsigned int qinx) -{ - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->flush_mtl_tx_queue != OSI_NULL)) { - return osi_core->ops->flush_mtl_tx_queue(osi_core->base, qinx); - } - - return -1; -} - int osi_config_mac_loopback(struct osi_core_priv_data *const osi_core, const unsigned int lb_mode) { - /* Configure MAC LoopBack */ + /* Configure MAC loopback */ if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->config_mac_loopback != OSI_NULL)) { return osi_core->ops->config_mac_loopback(osi_core->base, @@ -214,41 +190,6 @@ int osi_config_mac_loopback(struct osi_core_priv_data *const osi_core, return -1; } -int osi_set_avb(struct osi_core_priv_data *const osi_core, - const struct osi_core_avb_algorithm *avb) -{ - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->set_avb_algorithm != OSI_NULL)) { - return osi_core->ops->set_avb_algorithm(osi_core, avb); - } - - return -1; -} - -int osi_get_avb(struct osi_core_priv_data *const osi_core, - struct osi_core_avb_algorithm *avb) -{ - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->get_avb_algorithm != OSI_NULL)) { - return osi_core->ops->get_avb_algorithm(osi_core, avb); - } - - return -1; -} - -int osi_configure_txstatus(struct osi_core_priv_data *const osi_core, - const unsigned int tx_status) -{ - /* Configure Drop Transmit Status */ - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->config_tx_status != OSI_NULL)) { - return osi_core->ops->config_tx_status(osi_core->base, - tx_status); - } - - return -1; -} - int osi_config_fw_err_pkts(struct osi_core_priv_data *const osi_core, const unsigned int qinx, const unsigned int fw_err) { @@ -262,47 +203,6 @@ int osi_config_fw_err_pkts(struct osi_core_priv_data *const osi_core, return -1; } -int osi_config_rx_crc_check(struct osi_core_priv_data *const osi_core, - const unsigned int crc_chk) -{ - /* Configure CRC Checking for Received Packets */ - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->config_rx_crc_check != OSI_NULL)) { - return osi_core->ops->config_rx_crc_check(osi_core->base, - crc_chk); - } - - return -1; -} - -int osi_configure_flow_control( - struct osi_core_priv_data *const osi_core, - const unsigned int flw_ctrl) -{ - /* Configure Flow control settings */ - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->config_flow_control != OSI_NULL)) { - return osi_core->ops->config_flow_control(osi_core->base, - flw_ctrl); - } - - return -1; -} - -int osi_config_arp_offload(struct osi_core_priv_data *const osi_core, - const unsigned int flags, - const unsigned char *ip_addr) -{ - if (osi_core != OSI_NULL && osi_core->ops != OSI_NULL && - osi_core->ops->config_arp_offload != OSI_NULL) { - return osi_core->ops->config_arp_offload(osi_core->mac_ver, - osi_core->base, - flags, ip_addr); - } - - return -1; -} - int osi_l2_filter(struct osi_core_priv_data *const osi_core, const struct osi_filter *filter) { @@ -521,24 +421,6 @@ int osi_l3l4_filter(struct osi_core_priv_data *const osi_core, return ret; } -int osi_config_vlan_filtering( - struct osi_core_priv_data *const osi_core, - const unsigned int filter_enb_dis, - const unsigned int perfect_hash_filtering, - const unsigned int perfect_inverse_match) -{ - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->config_vlan_filtering != OSI_NULL)) { - return osi_core->ops->config_vlan_filtering( - osi_core, - filter_enb_dis, - perfect_hash_filtering, - perfect_inverse_match); - } - - return -1; -} - int osi_config_rxcsum_offload( struct osi_core_priv_data *const osi_core, const unsigned int enable) @@ -552,18 +434,6 @@ int osi_config_rxcsum_offload( return -1; } -int osi_update_vlan_id(struct osi_core_priv_data *const osi_core, - const unsigned int vid) -{ - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->update_vlan_id != OSI_NULL)) { - return osi_core->ops->update_vlan_id(osi_core->base, - vid); - } - - return -1; -} - int osi_set_systime_to_mac(struct osi_core_priv_data *const osi_core, const unsigned int sec, const unsigned int nsec) { @@ -721,21 +591,6 @@ int osi_adjust_time(struct osi_core_priv_data *const osi_core, return ret; } -int osi_get_systime_from_mac( - struct osi_core_priv_data *const osi_core, - unsigned int *sec, - unsigned int *nsec) -{ - if ((osi_core != OSI_NULL) && (osi_core->base != OSI_NULL)) { - common_get_systime_from_mac(osi_core->base, osi_core->mac, sec, - nsec); - } else { - return -1; - } - - return 0; -} - int osi_ptp_configuration(struct osi_core_priv_data *const osi_core, const unsigned int enable) { @@ -814,6 +669,124 @@ int osi_read_mmc(struct osi_core_priv_data *const osi_core) return -1; } +#ifndef OSI_STRIPPED_LIB +int osi_validate_core_regs(struct osi_core_priv_data *const osi_core) +{ + int ret = -1; + + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->validate_regs != OSI_NULL) && + (osi_core->safety_config != OSI_NULL)) { + ret = osi_core->ops->validate_regs(osi_core); + } + + return ret; +} + +int osi_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, + const unsigned int qinx) +{ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->flush_mtl_tx_queue != OSI_NULL)) { + return osi_core->ops->flush_mtl_tx_queue(osi_core->base, qinx); + } + + return -1; +} + +int osi_set_avb(struct osi_core_priv_data *const osi_core, + const struct osi_core_avb_algorithm *avb) +{ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->set_avb_algorithm != OSI_NULL)) { + return osi_core->ops->set_avb_algorithm(osi_core, avb); + } + + return -1; +} + +int osi_get_avb(struct osi_core_priv_data *const osi_core, + struct osi_core_avb_algorithm *avb) +{ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->get_avb_algorithm != OSI_NULL)) { + return osi_core->ops->get_avb_algorithm(osi_core, avb); + } + + return -1; +} + +int osi_configure_txstatus(struct osi_core_priv_data *const osi_core, + const unsigned int tx_status) +{ + /* Configure Drop Transmit Status */ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->config_tx_status != OSI_NULL)) { + return osi_core->ops->config_tx_status(osi_core->base, + tx_status); + } + + return -1; +} + +int osi_config_rx_crc_check(struct osi_core_priv_data *const osi_core, + const unsigned int crc_chk) +{ + /* Configure CRC Checking for Received Packets */ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->config_rx_crc_check != OSI_NULL)) { + return osi_core->ops->config_rx_crc_check(osi_core->base, + crc_chk); + } + + return -1; +} + +int osi_config_vlan_filtering( + struct osi_core_priv_data *const osi_core, + const unsigned int filter_enb_dis, + const unsigned int perfect_hash_filtering, + const unsigned int perfect_inverse_match) +{ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->config_vlan_filtering != OSI_NULL)) { + return osi_core->ops->config_vlan_filtering( + osi_core, + filter_enb_dis, + perfect_hash_filtering, + perfect_inverse_match); + } + + return -1; +} + +int osi_update_vlan_id(struct osi_core_priv_data *const osi_core, + const unsigned int vid) +{ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->update_vlan_id != OSI_NULL)) { + return osi_core->ops->update_vlan_id(osi_core->base, + vid); + } + + return -1; +} + +int osi_get_systime_from_mac( + struct osi_core_priv_data *const osi_core, + unsigned int *sec, + unsigned int *nsec) +{ + if ((osi_core != OSI_NULL) && (osi_core->base != OSI_NULL)) { + common_get_systime_from_mac(osi_core->base, osi_core->mac, sec, + nsec); + } else { + return -1; + } + + return 0; +} + int osi_reset_mmc(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && @@ -862,3 +835,32 @@ int osi_restore_registers(struct osi_core_priv_data *const osi_core) return -1; } + +int osi_configure_flow_control( + struct osi_core_priv_data *const osi_core, + const unsigned int flw_ctrl) +{ + /* Configure Flow control settings */ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->config_flow_control != OSI_NULL)) { + return osi_core->ops->config_flow_control(osi_core->base, + flw_ctrl); + } + + return -1; +} + +int osi_config_arp_offload(struct osi_core_priv_data *const osi_core, + const unsigned int flags, + const unsigned char *ip_addr) +{ + if (osi_core != OSI_NULL && osi_core->ops != OSI_NULL && + osi_core->ops->config_arp_offload != OSI_NULL) { + return osi_core->ops->config_arp_offload(osi_core->mac_ver, + osi_core->base, + flags, ip_addr); + } + + return -1; +} +#endif /* !OSI_STRIPPED_LIB */ diff --git a/osi/dma/Makefile.tmk b/osi/dma/Makefile.tmk index b076c52..5651581 100644 --- a/osi/dma/Makefile.tmk +++ b/osi/dma/Makefile.tmk @@ -26,6 +26,7 @@ ifdef NV_COMPONENT_FLAG_SHARED_LIBRARY_SECTION include $(NV_BUILD_START_COMPONENT) NV_COMPONENT_STRICT_WARNINGS_qnx_64 := 1 +NV_COMPONENT_CFLAGS := -DOSI_STRIPPED_LIB NV_COMPONENT_NAME := nvethernetcl NV_COMPONENT_OWN_INTERFACE_DIR := . diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index b38d8b3..68045a2 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -68,7 +68,7 @@ static inline void eqos_dma_safety_writel(unsigned int val, void *addr, * - 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 ivoked periodically to compare + * 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. */ @@ -128,70 +128,6 @@ static void eqos_dma_safety_init(struct osi_dma_priv_data *osi_dma) osi_lock_init(&config->dma_safety_lock); } -/** - * @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 iff (osi_dma_priv_data->safety_config != OSI_NULL) - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int eqos_validate_dma_regs(struct osi_dma_priv_data *osi_dma) -{ - struct dma_func_safety *config = - (struct dma_func_safety *)osi_dma->safety_config; - unsigned int cur_val; - unsigned int 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; - } - - /* FIXME - * QNX OSD currently overwrites following registers and - * therefore validation fails using this API. Add an - * exception for following registers until QNX OSD completely - * moves to common library. - */ - if ((i == EQOS_DMA_CH0_TDRL_IDX) || - (i == EQOS_DMA_CH0_RDRL_IDX)) - { - continue; - } - - cur_val = osi_readl((unsigned char *)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_disable_chan_tx_intr - Disables DMA Tx channel interrupts. * @@ -351,7 +287,7 @@ static void eqos_set_tx_ring_len(void *addr, unsigned int chan, * @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. + * @param[in] tx_desc: Tx desc base address. */ static void eqos_set_tx_ring_start_addr(void *addr, unsigned int chan, unsigned long tx_desc) @@ -559,56 +495,6 @@ static void eqos_stop_dma(void *addr, unsigned int chan) EQOS_DMA_CH0_RX_CTRL_IDX + chan); } -/** - * @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 - * - * @retval none - */ -static void eqos_config_slot(struct osi_dma_priv_data *osi_dma, - unsigned int chan, - unsigned int set, - unsigned int interval) -{ - unsigned int value; - - CHECK_CHAN_BOUND(chan); - - if (set == OSI_ENABLE) { - /* Program SLOT CTRL register SIV and set ESC bit */ - value = osi_readl((unsigned char *)osi_dma->base + - EQOS_DMA_CHX_SLOT_CTRL(chan)); - value &= ~EQOS_DMA_CHX_SLOT_SIV_MASK; - /* remove overflow bits of interval */ - interval &= EQOS_DMA_CHX_SLOT_SIV_MASK; - value |= (interval << EQOS_DMA_CHX_SLOT_SIV_SHIFT); - /* Set ESC bit */ - value |= EQOS_DMA_CHX_SLOT_ESC; - osi_writel(value, (unsigned char *)osi_dma->base + - EQOS_DMA_CHX_SLOT_CTRL(chan)); - - } else { - /* Clear ESC bit of SLOT CTRL register */ - value = osi_readl((unsigned char *)osi_dma->base + - EQOS_DMA_CHX_SLOT_CTRL(chan)); - value &= ~EQOS_DMA_CHX_SLOT_ESC; - osi_writel(value, (unsigned char *)osi_dma->base + - EQOS_DMA_CHX_SLOT_CTRL(chan)); - } -} - /** * @brief eqos_configure_dma_channel - Configure DMA channel * @@ -700,7 +586,7 @@ static void eqos_configure_dma_channel(unsigned int 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 + * 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) @@ -805,6 +691,110 @@ static void eqos_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) ~(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) + * + * @retval 0 on success + * @retval -1 on failure. + */ +static int eqos_validate_dma_regs(struct osi_dma_priv_data *osi_dma) +{ + struct dma_func_safety *config = + (struct dma_func_safety *)osi_dma->safety_config; + unsigned int cur_val; + unsigned int 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((unsigned char *)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 + * + * @retval none + */ +static void eqos_config_slot(struct osi_dma_priv_data *osi_dma, + unsigned int chan, + unsigned int set, + unsigned int interval) +{ + unsigned int value; + + CHECK_CHAN_BOUND(chan); + + if (set == OSI_ENABLE) { + /* Program SLOT CTRL register SIV and set ESC bit */ + value = osi_readl((unsigned char *)osi_dma->base + + EQOS_DMA_CHX_SLOT_CTRL(chan)); + value &= ~EQOS_DMA_CHX_SLOT_SIV_MASK; + /* remove overflow bits of interval */ + interval &= EQOS_DMA_CHX_SLOT_SIV_MASK; + value |= (interval << EQOS_DMA_CHX_SLOT_SIV_SHIFT); + /* Set ESC bit */ + value |= EQOS_DMA_CHX_SLOT_ESC; + osi_writel(value, (unsigned char *)osi_dma->base + + EQOS_DMA_CHX_SLOT_CTRL(chan)); + + } else { + /* Clear ESC bit of SLOT CTRL register */ + value = osi_readl((unsigned char *)osi_dma->base + + EQOS_DMA_CHX_SLOT_CTRL(chan)); + value &= ~EQOS_DMA_CHX_SLOT_ESC; + osi_writel(value, (unsigned char *)osi_dma->base + + EQOS_DMA_CHX_SLOT_CTRL(chan)); + } +} +#endif /* !OSI_STRIPPED_LIB */ + /** * @brief eqos_get_global_dma_status - Gets DMA status. * @@ -885,8 +875,10 @@ static struct osi_dma_chan_ops eqos_dma_chan_ops = { .stop_dma = eqos_stop_dma, .init_dma_channel = eqos_init_dma_channel, .set_rx_buf_len = eqos_set_rx_buf_len, +#ifndef OSI_STRIPPED_LIB .validate_regs = eqos_validate_dma_regs, .config_slot = eqos_config_slot, +#endif /* !OSI_STRIPPED_LIB */ .get_global_dma_status = eqos_get_global_dma_status, .clear_vm_tx_intr = eqos_clear_vm_tx_intr, .clear_vm_rx_intr = eqos_clear_vm_rx_intr, diff --git a/osi/dma/libnvethernetcl.export b/osi/dma/libnvethernetcl.export index e66a979..2cc1dbe 100644 --- a/osi/dma/libnvethernetcl.export +++ b/osi/dma/libnvethernetcl.export @@ -38,8 +38,5 @@ osi_process_rx_completions osi_hw_dma_init osi_hw_dma_deinit osi_init_dma_ops -osi_validate_dma_regs -osi_config_slot_function -osi_clear_tx_pkt_err_stats osi_dma_get_systime_from_mac osi_is_mac_enabled diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 9c9485b..3f21edd 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -29,7 +29,7 @@ int osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) /* * Currently these osd_ops are optional to be filled in the OSD layer. * If OSD updates these pointers, use the same. If not, fall back to the - * exisitng way of using osd_* API's. + * existing way of using osd_* API's. * TODO: Once These API's are mandatory, return errors instead of * default API usage. */ @@ -331,6 +331,7 @@ int osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) return 0; } +#ifndef OSI_STRIPPED_LIB int osi_config_slot_function(struct osi_dma_priv_data *osi_dma, unsigned int set) { @@ -346,7 +347,6 @@ int osi_config_slot_function(struct osi_dma_priv_data *osi_dma, return -1; } - /* Configure slot Checking for Tranmit */ if (osi_dma == OSI_NULL || osi_dma->ops == OSI_NULL || osi_dma->ops->config_slot == OSI_NULL) { OSI_ERR(OSI_NULL, @@ -363,7 +363,7 @@ int osi_config_slot_function(struct osi_dma_priv_data *osi_dma, /* Ignore 0 and invalid channels */ continue; } - /* Check for slot enbale */ + /* Check for slot enable */ if (osi_dma->slot_enabled[chan] == OSI_ENABLE) { /* Get DMA slot interval and validate */ interval = osi_dma->slot_interval[chan]; @@ -412,6 +412,7 @@ int osi_txring_empty(struct osi_dma_priv_data *osi_dma, unsigned int chan) return (tx_ring->clean_idx == tx_ring->cur_tx_idx) ? 1 : 0; } +#endif /* !OSI_STRIPPED_LIB */ int osi_dma_get_systime_from_mac(struct osi_dma_priv_data *const osi_dma, unsigned int *sec, diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index b429939..9c6d00d 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -291,7 +291,7 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, break; } - /* WHen JE is set, HW will accept any valid packet on Rx upto + /* 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 @@ -468,7 +468,7 @@ static inline void get_tx_err_stats(struct osi_tx_desc *tx_desc, 1UL); } - /* Execessive Collision Error */ + /* Excessive Collision Error */ if ((tx_desc->tdes3 & TDES3_EXCESSIVE_COL_ERR) == TDES3_EXCESSIVE_COL_ERR) { pkt_err_stats->excessive_collision_error = @@ -494,6 +494,7 @@ static inline void get_tx_err_stats(struct osi_tx_desc *tx_desc, } } +#ifndef OSI_STRIPPED_LIB int osi_clear_tx_pkt_err_stats(struct osi_dma_priv_data *osi_dma) { int ret = -1; @@ -538,6 +539,7 @@ int osi_clear_rx_pkt_err_stats(struct osi_dma_priv_data *osi_dma) return ret; } +#endif /* !OSI_STRIPPED_LIB */ int osi_process_tx_completions(struct osi_dma_priv_data *osi, unsigned int chan, int budget) @@ -625,7 +627,7 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi, /* 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 inturn be used to + * descriptors in the ring, which will in turn be used to * wake the corresponding transmit queue in OS layer. */ tx_ring->clean_idx = entry; @@ -814,7 +816,7 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan) return; } - /* Context decriptor for VLAN/TSO */ + /* Context descriptor for VLAN/TSO */ if ((tx_pkt_cx->flags & OSI_PKT_CX_VLAN) == OSI_PKT_CX_VLAN) { osi->dstats.tx_vlan_pkt_n = osi_update_stats_counter(osi->dstats.tx_vlan_pkt_n, From e781d85668903dd845784e7bc644ef89eef6196b Mon Sep 17 00:00:00 2001 From: rakesh goyal <rgoyal@nvidia.com> Date: Wed, 7 Oct 2020 13:41:02 +0530 Subject: [PATCH 117/458] osi: create stripped library for MCAL/QNX Update .sdk for common library to export only API used in QNX/MCAL driver if OSI_STRIPPED_LIB is defined. Bug 200671362 Signed-off-by: rakesh goyal <rgoyal@nvidia.com> Change-Id: I5f755895c5e053bab41a29e89aed65defbc48e54 Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2424577 Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/Makefile.sdk | 2 +- osi/dma/Makefile.sdk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osi/core/Makefile.sdk b/osi/core/Makefile.sdk index 40e4b73..9b2162b 100644 --- a/osi/core/Makefile.sdk +++ b/osi/core/Makefile.sdk @@ -10,7 +10,7 @@ include ../../../../../../../../../drive-t186ref-qnx/make/nvdefs.mk TARGETS = libnvethernetrm.so -CFLAGS += -g -Wall $(NV_PLATFORM_OPT) $(NV_PLATFORM_CFLAGS) +CFLAGS += -g -Wall $(NV_PLATFORM_OPT) $(NV_PLATFORM_CFLAGS) -DOSI_STRIPPED_LIB CPPFLAGS = $(NV_PLATFORM_SDK_INC) $(NV_PLATFORM_CPPFLAGS) -I../../../include -I../dma -I../common/include CPPFLAGS += -DNV_IS_SAFETY=$(NV_PLATFORM_SAFETY) LDFLAGS := \ diff --git a/osi/dma/Makefile.sdk b/osi/dma/Makefile.sdk index 55ac311..f5072d1 100644 --- a/osi/dma/Makefile.sdk +++ b/osi/dma/Makefile.sdk @@ -10,7 +10,7 @@ include ../../../../../../../../../drive-t186ref-qnx/make/nvdefs.mk TARGETS = libnvethernetcl.so -CFLAGS += -g -Wall $(NV_PLATFORM_OPT) $(NV_PLATFORM_CFLAGS) +CFLAGS += -g -Wall $(NV_PLATFORM_OPT) $(NV_PLATFORM_CFLAGS) -DOSI_STRIPPED_LIB CPPFLAGS = $(NV_PLATFORM_SDK_INC) $(NV_PLATFORM_CPPFLAGS) -I../../../include -I../core -I../common/include CPPFLAGS += -DNV_IS_SAFETY=$(NV_PLATFORM_SAFETY) LDFLAGS := \ From 4c166469925556a7af34f90358562c8c042c8667 Mon Sep 17 00:00:00 2001 From: Mahesh Patil <maheshp@nvidia.com> Date: Wed, 16 Sep 2020 22:36:57 -0700 Subject: [PATCH 118/458] nvethernetrm: Add PDK_TOP variable to makefile - Add export PDK_TOP variable to standard makefiles Bug 3127605 Change-Id: I77b27ae96c5fad04f1e6561f1e86310d7c59d206 Signed-off-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2414940 (cherry picked from commit 885be52a74803115aceb60955449d89b6f18c961) Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2422900 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/Makefile.sdk | 2 +- osi/dma/Makefile.sdk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osi/core/Makefile.sdk b/osi/core/Makefile.sdk index 9b2162b..fdf637c 100644 --- a/osi/core/Makefile.sdk +++ b/osi/core/Makefile.sdk @@ -6,7 +6,7 @@ # distribution of this software and related documentation without an express # license agreement from NVIDIA CORPORATION is strictly prohibited. -include ../../../../../../../../../drive-t186ref-qnx/make/nvdefs.mk +include $(PDK_TOP)/drive-t186ref-qnx/make/nvdefs.mk TARGETS = libnvethernetrm.so diff --git a/osi/dma/Makefile.sdk b/osi/dma/Makefile.sdk index f5072d1..94aceaa 100644 --- a/osi/dma/Makefile.sdk +++ b/osi/dma/Makefile.sdk @@ -6,7 +6,7 @@ # distribution of this software and related documentation without an express # license agreement from NVIDIA CORPORATION is strictly prohibited. -include ../../../../../../../../../drive-t186ref-qnx/make/nvdefs.mk +include $(PDK_TOP)/drive-t186ref-qnx/make/nvdefs.mk TARGETS = libnvethernetcl.so From be473360bb263941e46c523674db93ae2947621a Mon Sep 17 00:00:00 2001 From: Nagarjuna Kristam <nkristam@nvidia.com> Date: Thu, 24 Sep 2020 16:32:29 +0530 Subject: [PATCH 119/458] osi: replace osd_* API with osd_ops callbacks Issue: OSI calls OSD functionality using a direct API callback. When multiple OSD's are present in single build system, only one OSD can be linked to OSI for OSD functionality. Fix: Replace direct osd_* API calls by registered osd_ops callback. Bug 200620687 Change-Id: I967565286fd9334fea6b34436267649f1af671c0 Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2419132 (cherry picked from commit 0340c55df5741f73717e7a97e937bc4fdd6f02ef) Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2438837 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_common.h | 36 ---------- include/osi_core.h | 65 ++++++++++++++++-- include/osi_dma.h | 35 ++++++++++ osi/common/include/local_common.h | 2 +- osi/common/osd_dummy.c | 56 +++++++++++++++ osi/core/Makefile.tmk | 6 +- osi/core/eqos_core.c | 110 +++++++++++++++--------------- osi/core/osi_core.c | 36 +++++++--- osi/dma/Makefile.tmk | 6 +- osi/dma/osi_dma.c | 6 ++ osi/dma/osi_dma_txrx.c | 9 ++- 11 files changed, 249 insertions(+), 118 deletions(-) create mode 100644 osi/common/osd_dummy.c diff --git a/include/osi_common.h b/include/osi_common.h index d5fe781..d97c690 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -163,42 +163,6 @@ #define OSI_LOG_ARG_INVALID 2U #define OSI_LOG_ARG_OPNOTSUPP 3U #define OSI_LOG_ARG_HW_FAIL 4U -/** - * 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_ERR(priv, type, err, loga) \ - { \ - osd_log(priv, __func__, __LINE__, \ - OSI_LOG_ERR, type, err, loga); \ - } -/** - * 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_INFO(priv, type, err, loga) \ - { \ - osd_log(priv, __func__, __LINE__, \ - OSI_LOG_INFO, type, err, loga); \ - } -/** - * OSI warning 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_WARN(priv, type, err, loga) \ - { \ - osd_log(priv, __func__, __LINE__, \ - OSI_LOG_WARN, type, err, loga); \ - } /* Default maximum Giant Packet Size Limit is 16K */ #define OSI_MAX_MTU_SIZE 16383U diff --git a/include/osi_core.h b/include/osi_core.h index daaa019..7b6bcfe 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -36,6 +36,36 @@ #define OSI_PTP_SSINC_4 4U /** @} */ +/* to avoid re definition when both core and dma headers are included */ +#undef OSI_ERR +#undef OSI_INFO + +/** + * @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_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_INFO(priv, type, err, loga) \ +{ \ + osi_core->osd_ops.ops_log(priv, __func__, __LINE__, \ + OSI_LOG_INFO, type, err, loga); \ +} + struct osi_core_priv_data; /** @@ -146,7 +176,8 @@ struct osi_core_avb_algorithm { */ struct osi_core_ops { /** Called to poll for software reset bit */ - int (*poll_for_swr)(void *ioaddr, unsigned int pre_si); + int (*poll_for_swr)(struct osi_core_priv_data *const osi_core, + unsigned int pre_si); /** Called to initialize MAC and MTL registers */ int (*core_init)(struct osi_core_priv_data *const osi_core, const unsigned int tx_fifo_size, @@ -164,7 +195,7 @@ struct osi_core_ops { /** Called to set the speed (10/100/1000) at MAC */ void (*set_speed)(void *ioaddr, const int speed); /** Called to do pad caliberation */ - int (*pad_calibrate)(void *ioaddr); + int (*pad_calibrate)(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 unsigned long csr_clk_rate); @@ -219,14 +250,17 @@ struct osi_core_ops { const unsigned short port_no, const unsigned int src_dst_port_match); /** Called to set the addend value to adjust the time */ - int (*config_addend)(void *addr, const unsigned int addend); + int (*config_addend)(struct osi_core_priv_data *const osi_core, + const unsigned int addend); /** Called to adjust the mac time */ - int (*adjust_mactime)(void *addr, const unsigned int sec, + int (*adjust_mactime)(struct osi_core_priv_data *const osi_core, + const unsigned int sec, const unsigned int nsec, const unsigned int neg_adj, const unsigned int one_nsec_accuracy); /** Called to set current system time to MAC */ - int (*set_systime_to_mac)(void *addr, const unsigned int sec, + int (*set_systime_to_mac)(struct osi_core_priv_data *const osi_core, + const unsigned int sec, const unsigned int nsec); /** Called to configure the TimeStampControl register */ void (*config_tscr)(void *addr, const unsigned int ptp_filter); @@ -248,7 +282,8 @@ struct osi_core_ops { * registers against last written value */ int (*validate_regs)(struct osi_core_priv_data *const osi_core); /** Called to flush MTL Tx queue */ - int (*flush_mtl_tx_queue)(void *ioaddr, const unsigned int qinx); + int (*flush_mtl_tx_queue)(struct osi_core_priv_data *const osi_core, + const unsigned int qinx); /** Called to set av parameter */ int (*set_avb_algorithm)(struct osi_core_priv_data *const osi_core, const struct osi_core_avb_algorithm *const avb); @@ -350,6 +385,22 @@ struct core_backup { unsigned int reg_val[CORE_MAX_BAK_IDX]; }; +/** + *@brief OSD Core callbacks + */ +struct osd_core_ops { + /** logging callback */ + void (*ops_log)(void *priv, const char *func, unsigned int line, + unsigned int level, unsigned int type, const char *err, + unsigned long long loga); + /** udelay callback */ + void (*udelay)(unsigned long usec); + /** usleep range callback */ + void (*usleep_range)(unsigned long umin, unsigned long umax); + /** msleep callback */ + void (*msleep)(unsigned int msec); +}; + /** * @brief The OSI Core (MAC & MTL) private data structure. */ @@ -362,6 +413,8 @@ struct osi_core_priv_data { void *osd; /** Address of HW Core operations structure */ struct osi_core_ops *ops; + /** OSD callback ops structure */ + struct osd_core_ops osd_ops; /** Number of MTL queues enabled in MAC */ unsigned int num_mtl_queues; /** Array of MTL queues */ diff --git a/include/osi_dma.h b/include/osi_dma.h index c8031fa..f0f8bff 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -27,6 +27,35 @@ #include "osi_dma_txrx.h" #include "mmc.h" +/* to avoid re definition when both core and dma headers are included */ +#undef OSI_ERR +#undef OSI_INFO + +/** + * 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_ERR(priv, type, err, loga) \ +{ \ + osi_dma->osd_ops.ops_log(priv, __func__, __LINE__, \ + OSI_LOG_ERR, type, err, loga); \ +} +/** + * 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_INFO(priv, type, err, loga) \ +{ \ + osi_dma->osd_ops.ops_log(priv, __func__, __LINE__, \ + OSI_LOG_INFO, type, err, loga);\ +} + /** * @addtogroup EQOS-PKT Packet context fields * @@ -402,6 +431,12 @@ struct osd_dma_ops { void *rxpkt_cx, void *rx_pkt_swcx); /** RX buffer reallocation callback */ void (*realloc_buf)(void *priv, void *rxring, unsigned int chan); + /**.ops_log function callback */ + void (*ops_log)(void *priv, const char *func, unsigned int line, + unsigned int level, unsigned int type, const char *err, + unsigned long long loga); + /**.ops_log function callback */ + void (*udelay)(unsigned long usec); }; /** diff --git a/osi/common/include/local_common.h b/osi/common/include/local_common.h index 0f5b496..6f9f209 100644 --- a/osi/common/include/local_common.h +++ b/osi/common/include/local_common.h @@ -23,7 +23,7 @@ #ifndef LOCAL_COMMON_H #define LOCAL_COMMON_H -#include <osi_core.h> +#include <osi_common.h> /** * @brief common_get_systime_from_mac - Get system time diff --git a/osi/common/osd_dummy.c b/osi/common/osd_dummy.c new file mode 100644 index 0000000..a02bd9d --- /dev/null +++ b/osi/common/osd_dummy.c @@ -0,0 +1,56 @@ +/* + * 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. + */ +#ifdef OSD_DUMMY +#include <osd.h> + +void osd_usleep_range(unsigned long umin, unsigned long umax) +{ +} + +void osd_msleep(unsigned int msec) +{ +} + +void osd_udelay(unsigned long usec) +{ +} + +void osd_receive_packet(void *priv, void *rxring, unsigned int chan, + unsigned int dma_buf_len, void *rxpkt_cx, + void *rx_pkt_swcx) +{ +} +void osd_transmit_complete(void *priv, void *buffer, unsigned long dmaaddr, + unsigned int len, void *txdone_pkt_cx) +{ +} + +void osd_log(void *priv, + const char *func, + unsigned int line, + unsigned int level, + unsigned int type, + const char *err, + unsigned long long loga) +{ +} +#endif diff --git a/osi/core/Makefile.tmk b/osi/core/Makefile.tmk index 197724a..0055aa6 100644 --- a/osi/core/Makefile.tmk +++ b/osi/core/Makefile.tmk @@ -26,7 +26,7 @@ ifdef NV_COMPONENT_FLAG_SHARED_LIBRARY_SECTION include $(NV_BUILD_START_COMPONENT) NV_COMPONENT_STRICT_WARNINGS_qnx_64 := 1 -NV_COMPONENT_CFLAGS := -DOSI_STRIPPED_LIB +NV_COMPONENT_CFLAGS := -DOSI_STRIPPED_LIB -DOSD_DUMMY NV_COMPONENT_NAME := nvethernetrm NV_COMPONENT_OWN_INTERFACE_DIR := . @@ -35,11 +35,9 @@ NV_COMPONENT_SOURCES := \ eqos_mmc.c \ osi_core.c \ $(NV_SOURCE)/nvethernetrm/osi/common/osi_common.c \ + $(NV_SOURCE)/nvethernetrm/osi/common/osd_dummy.c \ $(NV_SOURCE)/nvethernetrm/osi/common/eqos_common.c -NV_COMPONENT_NEEDED_INTERFACE_DIRS := \ - $(NV_SOURCE)/qnx/src/libs/nvethernet/osi_dependencies - NV_COMPONENT_INCLUDES := \ $(NV_SOURCE)/nvethernetrm/include \ $(NV_SOURCE)/nvethernetrm/osi/common/include \ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index a428e8d..e26be6c 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -481,7 +481,7 @@ static int eqos_config_mac_loopback(void *addr, * - CAR reset will be issued through MAC reset pin. * Waits for SWR reset to be cleared in DMA Mode register. * - * @param[in] addr: EQOS virtual base address. + * @param[in] osi_core: OSI core private data structure. * @param[in] pre_si: Sets whether platform is Pre-silicon or not. * * @pre MAC needs to be out of reset and proper clock configured. @@ -489,8 +489,10 @@ static int eqos_config_mac_loopback(void *addr, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_poll_for_swr(void *addr, unsigned int pre_si) +static int eqos_poll_for_swr(struct osi_core_priv_data *const osi_core, + unsigned int pre_si) { + void *addr = osi_core->base; unsigned int retry = 1000; unsigned int count; unsigned int dma_bmr = 0; @@ -500,7 +502,7 @@ static int eqos_poll_for_swr(void *addr, unsigned int pre_si) osi_writel(0x1U, (unsigned char *)addr + EQOS_DMA_BMR); } /* add delay of 10 usec */ - osd_usleep_range(9, 11); + osi_core->osd_ops.usleep_range(9, 11); /* Poll Until Poll Condition */ count = 0; @@ -515,7 +517,7 @@ static int eqos_poll_for_swr(void *addr, unsigned int pre_si) if ((dma_bmr & EQOS_DMA_BMR_SWR) == 0U) { cond = 0; } else { - osd_msleep(1U); + osi_core->osd_ops.msleep(1U); } } @@ -752,7 +754,7 @@ static unsigned int eqos_calculate_per_queue_fifo(unsigned int fifo_size, * - Re-program the value PAD_E_INPUT_OR_E_PWRD in * ETHER_QOS_SDMEMCOMPPADCTRL_0 to save power * - * @param[in] ioaddr: Base address of the MAC HW. + * @param[in] osi_core: OSI core private data structure. * * @note * - MAC should out of reset and clocks enabled. @@ -762,8 +764,9 @@ static unsigned int eqos_calculate_per_queue_fifo(unsigned int fifo_size, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_pad_calibrate(void *ioaddr) +static int eqos_pad_calibrate(struct osi_core_priv_data *const osi_core) { + void *ioaddr = osi_core->base; unsigned int retry = 1000; unsigned int count; int cond = 1, ret = 0; @@ -777,7 +780,7 @@ static int eqos_pad_calibrate(void *ioaddr) osi_writel(value, (unsigned char *)ioaddr + EQOS_PAD_CRTL); /* 2. delay for 1 usec */ - osd_usleep_range(1, 3); + 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. @@ -801,7 +804,7 @@ static int eqos_pad_calibrate(void *ioaddr) goto calibration_failed; } count++; - osd_usleep_range(10, 12); + osi_core->osd_ops.usleep_range(10, 12); value = osi_readl((unsigned char *)ioaddr + EQOS_PAD_AUTO_CAL_STAT); /* calibration done when CAL_STAT_ACTIVE is zero */ @@ -824,7 +827,7 @@ calibration_failed: /** * @brief eqos_flush_mtl_tx_queue - Flush MTL Tx queue * - * @param[in] addr: OSI core private data structure. + * @param[in] osi_core: OSI core private data structure. * @param[in] qinx: MTL queue index. * * @note @@ -834,9 +837,10 @@ calibration_failed: * @retval 0 on success * @retval -1 on failure. */ -static int eqos_flush_mtl_tx_queue(void *addr, +static int eqos_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, const unsigned int qinx) { + void *addr = osi_core->base; unsigned int retry = 1000; unsigned int count; unsigned int value; @@ -862,7 +866,7 @@ static int eqos_flush_mtl_tx_queue(void *addr, } count++; - osd_msleep(1); + osi_core->osd_ops.msleep(1); value = osi_readl((unsigned char *)addr + EQOS_MTL_CHX_TX_OP_MODE(qinx)); @@ -1003,7 +1007,7 @@ static int eqos_configure_mtl_queue(unsigned int qinx, unsigned int value = 0; int ret = 0; - ret = eqos_flush_mtl_tx_queue(osi_core->base, qinx); + ret = eqos_flush_mtl_tx_queue(osi_core, qinx); if (ret < 0) { return ret; } @@ -1371,7 +1375,7 @@ static int eqos_core_init(struct osi_core_priv_data *const osi_core, eqos_core_backup_init(osi_core); /* PAD calibration */ - ret = eqos_pad_calibrate(osi_core->base); + ret = eqos_pad_calibrate(osi_core); if (ret < 0) { return ret; } @@ -2509,8 +2513,7 @@ static int eqos_config_l4_filters( * - 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] osi_core: OSI core private data structure. * @param[in] mac_tcr: Address to store time stamp control register read value * * @pre MAC should be initialized and started. see osi_start_mac() @@ -2518,9 +2521,11 @@ static int eqos_config_l4_filters( * @retval 0 on success * @retval -1 on failure. */ -static inline int eqos_poll_for_tsinit_complete(void *addr, - unsigned int *mac_tcr) +static inline int eqos_poll_for_tsinit_complete( + struct osi_core_priv_data *const osi_core, + unsigned int *mac_tcr) { + void *addr = osi_core->base; unsigned int retry = 1000; unsigned int count; int cond = 1; @@ -2539,7 +2544,7 @@ static inline int eqos_poll_for_tsinit_complete(void *addr, cond = 0; } count++; - osd_udelay(1000U); + osi_core->osd_ops.udelay(1000U); } return 0; @@ -2553,8 +2558,7 @@ static inline int eqos_poll_for_tsinit_complete(void *addr, * - 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] osi_core: OSI core private data structure. * @param[in] sec: Seconds to be configured * @param[in] nsec: Nano Seconds to be configured * @@ -2563,13 +2567,15 @@ static inline int eqos_poll_for_tsinit_complete(void *addr, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_set_systime_to_mac(void *addr, const unsigned int sec, +static int eqos_set_systime_to_mac(struct osi_core_priv_data *const osi_core, + const unsigned int sec, const unsigned int nsec) { + void *addr = osi_core->base; unsigned int mac_tcr; int ret; - ret = eqos_poll_for_tsinit_complete(addr, &mac_tcr); + ret = eqos_poll_for_tsinit_complete(osi_core, &mac_tcr); if (ret == -1) { return -1; } @@ -2587,7 +2593,7 @@ static int eqos_set_systime_to_mac(void *addr, const unsigned int sec, eqos_core_safety_writel(mac_tcr, (unsigned char *)addr + EQOS_MAC_TCR, EQOS_MAC_TCR_IDX); - ret = eqos_poll_for_tsinit_complete(addr, &mac_tcr); + ret = eqos_poll_for_tsinit_complete(osi_core, &mac_tcr); if (ret == -1) { return -1; } @@ -2603,8 +2609,7 @@ static int eqos_set_systime_to_mac(void *addr, const unsigned int sec, * - 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] osi_core: OSI core private data structure. * @param[in] mac_tcr: Address to store time stamp control register read value * * @pre MAC should be initialized and started. see osi_start_mac() @@ -2612,9 +2617,11 @@ static int eqos_set_systime_to_mac(void *addr, const unsigned int sec, * @retval 0 on success * @retval -1 on failure. */ -static inline int eqos_poll_for_addend_complete(void *addr, - unsigned int *mac_tcr) +static inline int eqos_poll_for_addend_complete( + struct osi_core_priv_data *const osi_core, + unsigned int *mac_tcr) { + void *addr = osi_core->base; unsigned int retry = 1000; unsigned int count; int cond = 1; @@ -2632,7 +2639,7 @@ static inline int eqos_poll_for_addend_complete(void *addr, cond = 0; } count++; - osd_udelay(1000U); + osi_core->osd_ops.udelay(1000U); } return 0; @@ -2645,8 +2652,7 @@ static inline int eqos_poll_for_addend_complete(void *addr, * 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] osi_core: OSI core private data structure. * @param[in] addend: Addend value to be configured * * @pre MAC should be initialized and started. see osi_start_mac() @@ -2654,12 +2660,14 @@ static inline int eqos_poll_for_addend_complete(void *addr, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_config_addend(void *addr, const unsigned int addend) +static int eqos_config_addend(struct osi_core_priv_data *const osi_core, + const unsigned int addend) { + void *addr = osi_core->base; unsigned int mac_tcr; int ret; - ret = eqos_poll_for_addend_complete(addr, &mac_tcr); + ret = eqos_poll_for_addend_complete(osi_core, &mac_tcr); if (ret == -1) { return -1; } @@ -2673,7 +2681,7 @@ static int eqos_config_addend(void *addr, const unsigned int addend) eqos_core_safety_writel(mac_tcr, (unsigned char *)addr + EQOS_MAC_TCR, EQOS_MAC_TCR_IDX); - ret = eqos_poll_for_addend_complete(addr, &mac_tcr); + ret = eqos_poll_for_addend_complete(osi_core, &mac_tcr); if (ret == -1) { return -1; } @@ -2689,8 +2697,7 @@ static int eqos_config_addend(void *addr, const unsigned int addend) * - 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] osi_core: OSI core private data structure. * @param[in] mac_tcr: Address to store time stamp control register read value * * @pre MAC should be initialized and started. see osi_start_mac() @@ -2698,9 +2705,11 @@ static int eqos_config_addend(void *addr, const unsigned int addend) * @retval 0 on success * @retval -1 on failure. */ -static inline int eqos_poll_for_update_ts_complete(void *addr, - unsigned int *mac_tcr) +static inline int eqos_poll_for_update_ts_complete( + struct osi_core_priv_data *const osi_core, + unsigned int *mac_tcr) { + void *addr = osi_core->base; unsigned int retry = 1000; unsigned int count; int cond = 1; @@ -2717,7 +2726,7 @@ static inline int eqos_poll_for_update_ts_complete(void *addr, cond = 0; } count++; - osd_udelay(1000U); + osi_core->osd_ops.udelay(1000U); } return 0; @@ -2731,8 +2740,7 @@ static inline int eqos_poll_for_update_ts_complete(void *addr, * 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] osi_core: OSI core private data structure. * @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 @@ -2745,16 +2753,18 @@ static inline int eqos_poll_for_update_ts_complete(void *addr, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_adjust_mactime(void *addr, unsigned int sec, unsigned int nsec, +static int eqos_adjust_mactime(struct osi_core_priv_data *const 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; - ret = eqos_poll_for_update_ts_complete(addr, &mac_tcr); + ret = eqos_poll_for_update_ts_complete(osi_core, &mac_tcr); if (ret == -1) { return -1; } @@ -2805,7 +2815,7 @@ static int eqos_adjust_mactime(void *addr, unsigned int sec, unsigned int nsec, eqos_core_safety_writel(mac_tcr, (unsigned char *)addr + EQOS_MAC_TCR, EQOS_MAC_TCR_IDX); - ret = eqos_poll_for_update_ts_complete(addr, &mac_tcr); + ret = eqos_poll_for_update_ts_complete(osi_core, &mac_tcr); if (ret == -1) { return -1; } @@ -2984,7 +2994,7 @@ static inline int poll_for_mii_idle(struct osi_core_priv_data *osi_core) cond = 0; } else { /* wait on GMII Busy set */ - osd_udelay(10U); + osi_core->osd_ops.udelay(10U); } } @@ -3024,12 +3034,6 @@ static int eqos_write_phy_reg(struct osi_core_priv_data *const osi_core, unsigned int mac_gmiidr; int ret = 0; - if (osi_core == OSI_NULL) { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "osi_core is NULL\n", - 0ULL); - return -1; - } - /* Wait for any previous MII read/write operation to complete */ ret = poll_for_mii_idle(osi_core); if (ret < 0) { @@ -3105,12 +3109,6 @@ static int eqos_read_phy_reg(struct osi_core_priv_data *const osi_core, unsigned int data; int ret = 0; - if (osi_core == OSI_NULL) { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "osi_core is NULL\n", - 0ULL); - return -1; - } - /* wait for any previous MII read/write operation to complete */ ret = poll_for_mii_idle(osi_core); if (ret < 0) { diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index d375e31..997a07f 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -50,6 +50,26 @@ int osi_read_phy_reg(struct osi_core_priv_data *const osi_core, int osi_init_core_ops(struct osi_core_priv_data *const osi_core) { + /* + * Currently these osd_ops are optional to be filled in the OSD layer. + * If OSD updates these pointers, use the same. If not, fall back to the + * existing way of using osd_* API's. + * TODO: Once These API's are mandatory, return errors instead of + * default API usage. + */ + if (osi_core->osd_ops.ops_log == OSI_NULL) { + osi_core->osd_ops.ops_log = osd_log; + } + if (osi_core->osd_ops.udelay == OSI_NULL) { + osi_core->osd_ops.udelay = osd_udelay; + } + if (osi_core->osd_ops.msleep == OSI_NULL) { + osi_core->osd_ops.msleep = osd_msleep; + } + if (osi_core->osd_ops.usleep_range == OSI_NULL) { + osi_core->osd_ops.usleep_range = osd_usleep_range; + } + if (osi_core->mac == OSI_MAC_HW_EQOS) { /* Get EQOS HW ops */ osi_core->ops = eqos_get_hw_core_ops(); @@ -69,7 +89,7 @@ int osi_poll_for_mac_reset_complete( { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->poll_for_swr != OSI_NULL)) { - return osi_core->ops->poll_for_swr(osi_core->base, + return osi_core->ops->poll_for_swr(osi_core, osi_core->pre_si); } return -1; @@ -171,7 +191,7 @@ int osi_pad_calibrate(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->pad_calibrate != OSI_NULL)) { - return osi_core->ops->pad_calibrate(osi_core->base); + return osi_core->ops->pad_calibrate(osi_core); } return -1; @@ -439,7 +459,7 @@ int osi_set_systime_to_mac(struct osi_core_priv_data *const osi_core, { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->set_systime_to_mac != OSI_NULL)) { - return osi_core->ops->set_systime_to_mac(osi_core->base, + return osi_core->ops->set_systime_to_mac(osi_core, sec, nsec); } @@ -548,7 +568,7 @@ int osi_adjust_freq(struct osi_core_priv_data *const osi_core, int ppb) if ((osi_core->ops != OSI_NULL) && (osi_core->ops->config_addend != OSI_NULL)) { - ret = osi_core->ops->config_addend(osi_core->base, addend); + ret = osi_core->ops->config_addend(osi_core, addend); } return ret; @@ -583,7 +603,7 @@ int osi_adjust_time(struct osi_core_priv_data *const osi_core, if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->adjust_mactime != OSI_NULL)) { - ret = osi_core->ops->adjust_mactime(osi_core->base, sec, nsec, + ret = osi_core->ops->adjust_mactime(osi_core, sec, nsec, neg_adj, osi_core->ptp_config.one_nsec_accuracy); } @@ -646,11 +666,11 @@ int osi_ptp_configuration(struct osi_core_priv_data *const osi_core, } /* Program addend value */ - ret = osi_core->ops->config_addend(osi_core->base, + ret = osi_core->ops->config_addend(osi_core, osi_core->default_addend); /* Set current time */ - ret = osi_core->ops->set_systime_to_mac(osi_core->base, + ret = osi_core->ops->set_systime_to_mac(osi_core, osi_core->ptp_config.sec, osi_core->ptp_config.nsec); } @@ -688,7 +708,7 @@ int osi_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->flush_mtl_tx_queue != OSI_NULL)) { - return osi_core->ops->flush_mtl_tx_queue(osi_core->base, qinx); + return osi_core->ops->flush_mtl_tx_queue(osi_core, qinx); } return -1; diff --git a/osi/dma/Makefile.tmk b/osi/dma/Makefile.tmk index 5651581..2a61e70 100644 --- a/osi/dma/Makefile.tmk +++ b/osi/dma/Makefile.tmk @@ -26,7 +26,7 @@ ifdef NV_COMPONENT_FLAG_SHARED_LIBRARY_SECTION include $(NV_BUILD_START_COMPONENT) NV_COMPONENT_STRICT_WARNINGS_qnx_64 := 1 -NV_COMPONENT_CFLAGS := -DOSI_STRIPPED_LIB +NV_COMPONENT_CFLAGS := -DOSI_STRIPPED_LIB -DOSD_DUMMY NV_COMPONENT_NAME := nvethernetcl NV_COMPONENT_OWN_INTERFACE_DIR := . @@ -35,11 +35,9 @@ NV_COMPONENT_SOURCES := \ osi_dma.c \ osi_dma_txrx.c \ $(NV_SOURCE)/nvethernetrm/osi/common/osi_common.c \ + $(NV_SOURCE)/nvethernetrm/osi/common/osd_dummy.c \ $(NV_SOURCE)/nvethernetrm/osi/common/eqos_common.c -NV_COMPONENT_NEEDED_INTERFACE_DIRS := \ - $(NV_SOURCE)/qnx/src/libs/nvethernet/osi_dependencies - NV_COMPONENT_INCLUDES := \ $(NV_SOURCE)/nvethernetrm/include \ $(NV_SOURCE)/nvethernetrm/osi/common/include \ diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 3f21edd..acae151 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -39,6 +39,12 @@ int osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) if (osi_dma->osd_ops.receive_packet == OSI_NULL) { osi_dma->osd_ops.receive_packet = osd_receive_packet; } + if (osi_dma->osd_ops.ops_log == OSI_NULL) { + osi_dma->osd_ops.ops_log = osd_log; + } + if (osi_dma->osd_ops.udelay == OSI_NULL) { + osi_dma->osd_ops.udelay = osd_udelay; + } if (osi_dma->mac == OSI_MAC_HW_EQOS) { /* Get EQOS HW ops */ diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 9c6d00d..fb34a97 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -158,6 +158,7 @@ static inline int get_rx_tstamp_status(struct osi_rx_desc *context_desc) * - 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] osi: OSI private data structure. * @param[in] rx_desc: Rx descriptor * @param[in] context_desc: Rx context descriptor * @param[in] rx_pkt_cx: Rx packet context @@ -165,7 +166,8 @@ static inline int get_rx_tstamp_status(struct osi_rx_desc *context_desc) * @retval -1 if TimeStamp is not available * @retval 0 if TimeStamp is available. */ -static int get_rx_hwstamp(struct osi_rx_desc *rx_desc, +static int get_rx_hwstamp(struct osi_dma_priv_data *osi, + struct osi_rx_desc *rx_desc, struct osi_rx_desc *context_desc, struct osi_rx_pkt_cx *rx_pkt_cx) { @@ -189,7 +191,7 @@ static int get_rx_hwstamp(struct osi_rx_desc *rx_desc, /* Do nothing here */ } /* TS not available yet, so retrying */ - osd_udelay(1U); + osi->osd_ops.udelay(1U); } if (ret != 0) { /* Timed out waiting for Rx timestamp */ @@ -330,7 +332,8 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, get_rx_vlan_from_desc(rx_desc, rx_pkt_cx); context_desc = rx_ring->rx_desc + rx_ring->cur_rx_idx; /* Get rx time stamp */ - ret = get_rx_hwstamp(rx_desc, context_desc, rx_pkt_cx); + ret = get_rx_hwstamp(osi, rx_desc, context_desc, + rx_pkt_cx); if (ret == 0) { ptp_rx_swcx = rx_ring->rx_swcx + rx_ring->cur_rx_idx; From 1ccd62b99b98b7b4093a01b0ec5bb9f896aacdb8 Mon Sep 17 00:00:00 2001 From: Nagarjuna Kristam <nkristam@nvidia.com> Date: Tue, 20 Oct 2020 09:27:17 +0530 Subject: [PATCH 120/458] osi: dma: Update classification for DMA API's Mark API's that can be called form interrupt/signal handler to Yes. Bug 200620687 Change-Id: I105c9e6672f823249c1dea36e1891560861a7d07 Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2430293 (cherry picked from commit b71a7d4fda87145f33a858bd68392308f09f07b5) Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2438838 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_dma.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/include/osi_dma.h b/include/osi_dma.h index f0f8bff..01aba49 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -527,8 +527,8 @@ struct osi_dma_priv_data { * * @note * Classification: - * - Interrupt: No - * - Signal handler: No + * - Interrupt: Yes + * - Signal handler: Yes * - Thread safe: No * - Required Privileges: None * @@ -566,8 +566,8 @@ int osi_disable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, * * @note * Classification: - * - Interrupt: No - * - Signal handler: No + * - Interrupt: Yes + * - Signal handler: Yes * - Thread safe: No * - Required Privileges: None * @@ -605,8 +605,8 @@ int osi_enable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, * * @note * Classification: - * - Interrupt: No - * - Signal handler: No + * - Interrupt: Yes + * - Signal handler: Yes * - Thread safe: No * - Required Privileges: None * @@ -644,8 +644,8 @@ int osi_disable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, * * @note * Classification: - * - Interrupt: No - * - Signal handler: No + * - Interrupt: Yes + * - Signal handler: Yes * - Thread safe: No * - Required Privileges: None * @@ -805,8 +805,8 @@ int osi_stop_dma(struct osi_dma_priv_data *osi_dma, * * @note * Classification: - * - Interrupt: No - * - Signal handler: No + * - Interrupt: Yes + * - Signal handler: Yes * - Thread safe: No * - Required Privileges: None * @@ -842,8 +842,8 @@ unsigned int osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring); * * @note * Classification: - * - Interrupt: No - * - Signal handler: No + * - Interrupt: Yes + * - Signal handler: Yes * - Thread safe: No * - Required Privileges: None * From 6112bd69492a094f3a646a27d247109ffd58410e Mon Sep 17 00:00:00 2001 From: Mahesh Patil <maheshp@nvidia.com> Date: Tue, 8 Sep 2020 17:26:41 -0700 Subject: [PATCH 121/458] autosar: mcal: remove mcal libs header files Fix standard makefile build error after removing autosar mcal libs Bug 200652357 Signed-off-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2410610 (cherry picked from commit ac3c07f7a5d0fd3cdff4fac3245bd2cb4e7dc4d7) Change-Id: Ie796cedab3f9454f0784f691be02430f8029df4e Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2422903 Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Praveen Mallaiah <pmallaiah@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: Mahesh Patil <maheshp@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/Makefile.sdk | 3 --- osi/dma/Makefile.sdk | 3 --- 2 files changed, 6 deletions(-) diff --git a/osi/core/Makefile.sdk b/osi/core/Makefile.sdk index fdf637c..521be39 100644 --- a/osi/core/Makefile.sdk +++ b/osi/core/Makefile.sdk @@ -24,9 +24,6 @@ OBJS += osi_core.o OBJS += ./../common/osi_common.o OBJS += ./../common/eqos_common.o -LDLIBS += -lnvethernetcl -LDLIBS += -lnvos_s3_safety - CFLAGS += -D_FILE_OFFSET_BITS=64 $(TARGETS): $(OBJS) diff --git a/osi/dma/Makefile.sdk b/osi/dma/Makefile.sdk index 94aceaa..39ff0b0 100644 --- a/osi/dma/Makefile.sdk +++ b/osi/dma/Makefile.sdk @@ -24,9 +24,6 @@ OBJS += osi_dma_txrx.o OBJS += ./../common/osi_common.o OBJS += ./../common/eqos_common.o -LDLIBS += -lnvethernetrm -LDLIBS += -lnvos_s3_safety - CFLAGS += -D_FILE_OFFSET_BITS=64 $(TARGETS): $(OBJS) From d8bc21061f4a715f75f1f69769b82c36cc835cad Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Tue, 21 Jul 2020 15:16:11 +0530 Subject: [PATCH 122/458] osi: dma: Fix osi_rx_dma_desc_init code complexity Issue: The nvethernetrm osi_rx_dma_desc_init function code complexity is more than the PLC process required to target 10. Fix: Update osi_rx_dma_desc_init function to meet PLC code complexity target. Bug 200634728 Change-Id: I6c0f068f464c64a3e58a8490ed5110a17b3ca42f Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2382930 (cherry picked from commit c320bc06a0841fd029deb1294239453171950a91) Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2455437 Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: Rakesh Goyal <rgoyal@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/dma/osi_dma.c | 92 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 68 insertions(+), 24 deletions(-) diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index acae151..89977bc 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -235,15 +235,22 @@ unsigned int osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring) return (rx_ring->cur_rx_idx - rx_ring->refill_idx) & (RX_DESC_CNT - 1U); } -int osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, - struct osi_rx_ring *rx_ring, unsigned int chan) +/** + * @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 + * + * @retval 0 on success + * @retval -1 on failure. + */ +static inline int rx_dma_desc_validate_args(struct osi_dma_priv_data *osi_dma, + struct osi_rx_ring *rx_ring, + unsigned int chan) { - /* for CERT-C error */ - unsigned long temp; - unsigned long tailptr = 0; - struct osi_rx_swcx *rx_swcx = OSI_NULL; - struct osi_rx_desc *rx_desc = OSI_NULL; - /* Validate args */ if (!(osi_dma != OSI_NULL && osi_dma->ops != OSI_NULL && osi_dma->ops->update_rx_tailptr != OSI_NULL)) { @@ -259,6 +266,54 @@ int osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, 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] rx_desc: Rx Rx descriptor. + * + */ +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; + } + } + } +} + +int osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, + struct osi_rx_ring *rx_ring, unsigned int chan) +{ + /* for CERT-C error */ + unsigned long temp; + unsigned long 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, 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 < RX_DESC_CNT) { @@ -277,32 +332,21 @@ int osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, if (temp > UINT_MAX) { /* error case do nothing */ } else { + /* Store Receive Descriptor 0 */ rx_desc->rdes0 = (unsigned int)temp; } temp = H32(rx_swcx->buf_phy_addr); - if (temp > UINT_MAX) { - /* error case do nothing */ - } else { + if (temp <= UINT_MAX) { + /* Store Receive Descriptor 1 */ rx_desc->rdes1 = (unsigned int)temp; } rx_desc->rdes2 = 0; rx_desc->rdes3 = (RDES3_OWN | RDES3_IOC | RDES3_B1V); - /* 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; - } - } - } + /* Reset IOC bit if RWIT is enabled */ + rx_dma_handle_ioc(osi_dma, rx_ring, rx_desc); INCR_RX_DESC_INDEX(rx_ring->refill_idx, 1U); } From 1247c6586a496a53e1a30d4d6d8246807d23d4cc Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Tue, 21 Jul 2020 11:53:04 +0530 Subject: [PATCH 123/458] =?UTF-8?q?osi:=20core:=20Fix=C2=A0eqos=5Fconfig?= =?UTF-8?q?=5Ftscr=20code=20complexity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issue: The nvethernetrm eqos_config_tscr function code complexity is more than the PLC process required to target 10. Fix: Update eqos_config_tscr function to meet PLC code complexity target. Bug 200634728 Change-Id: I774e94c9a6893e01e2bd6e935ae34c96be8e0f38 Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2382806 (cherry picked from commit a37d9984606a6e9eb99aff59858276ef7d5ca1c8) Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2448831 Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: Rakesh Goyal <rgoyal@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/eqos_core.c | 105 ++++++++++++++++++++++--------------------- 1 file changed, 54 insertions(+), 51 deletions(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index e26be6c..5d300af 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -2834,60 +2834,63 @@ static int eqos_adjust_mactime(struct osi_core_priv_data *const osi_core, */ static void eqos_config_tscr(void *addr, const unsigned int ptp_filter) { - unsigned int mac_tcr = 0; + unsigned int mac_tcr = 0U, i = 0U, temp = 0U; - 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; - } - } else { + if (ptp_filter == OSI_DISABLE) { /* Disabling the MAC time stamping */ mac_tcr = OSI_DISABLE; + eqos_core_safety_writel(mac_tcr, + (unsigned char *)addr + EQOS_MAC_TCR, + EQOS_MAC_TCR_IDX); + return; + } + + 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_SNAPTYPSEL_3: + mac_tcr |= OSI_MAC_TCR_SNAPTYPSEL_3; + 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; + default: + /* To avoid MISRA violation */ + mac_tcr |= mac_tcr; + break; + } } eqos_core_safety_writel(mac_tcr, (unsigned char *)addr + EQOS_MAC_TCR, From 7a83eedcd442aae656dfe050841b7757852b7e37 Mon Sep 17 00:00:00 2001 From: rakesh goyal <rgoyal@nvidia.com> Date: Thu, 22 Oct 2020 09:31:27 +0530 Subject: [PATCH 124/458] core: Remove unused code for QNX from compilation Update common library code to remove following 2 APIs as these are not used anymore by QNX. osi_config_mac_loopback() osi_set_mdc_clk_rate() Bug 200669603 Change-Id: Ice364bfb3fd95f3f846677b80668eb2b0b0b2918 Signed-off-by: rakesh goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2434886 (cherry picked from commit 9f69b25b1368b76fd7caa4b55a15e7a5947d3b9c) Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2448820 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_core.h | 156 ++++++++++++------------- osi/core/eqos_core.c | 200 ++++++++++++++++---------------- osi/core/libnvethernetrm.export | 2 - osi/core/osi_core.c | 50 ++++---- 4 files changed, 202 insertions(+), 206 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 7b6bcfe..28d5f8c 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -196,11 +196,6 @@ struct osi_core_ops { void (*set_speed)(void *ioaddr, const int speed); /** Called to do pad caliberation */ int (*pad_calibrate)(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 unsigned long csr_clk_rate); - /** Called to configure MAC in loopback mode */ - int (*config_mac_loopback)(void *addr, const unsigned int lb_mode); /** Called to configure MTL RxQ to forward the err pkt */ int (*config_fw_err_pkts)(void *addr, const unsigned int qinx, const unsigned int fw_err); @@ -319,6 +314,11 @@ struct osi_core_ops { int (*save_registers)(struct osi_core_priv_data *const osi_core); /** Called to restore MAC control registers during SoC resume */ int (*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 unsigned long csr_clk_rate); + /** Called to configure MAC in loopback mode */ + int (*config_mac_loopback)(void *addr, const unsigned int lb_mode); #endif /* !OSI_STRIPPED_LIB */ }; @@ -501,43 +501,6 @@ struct osi_core_priv_data { int osi_poll_for_mac_reset_complete( struct osi_core_priv_data *const osi_core); -/** - * @brief osi_set_mdc_clk_rate - Derive MDC clock based on provided AXI_CBB clk. - * - * @note - * Algorithm: - * - MDC clock rate will be populated in OSI core private data - * structure based on AXI_CBB clock rate. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] csr_clk_rate: CSR (AXI CBB) clock rate. - * - * @note OSD layer needs get the AXI CBB clock rate with OSD clock API - * (ex - clk_get_rate()) - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_005 - * - * @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. - */ -int osi_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, - const unsigned long csr_clk_rate); - /** * @brief osi_hw_core_init - EQOS MAC, MTL and common DMA initialization. * @@ -822,41 +785,6 @@ int osi_set_speed(struct osi_core_priv_data *const osi_core, */ int osi_pad_calibrate(struct osi_core_priv_data *const osi_core); -/** - * @brief osi_config_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: - * - SWUD_ID: ETHERNET_NVETHERNETRM_014 - * - * @note - * Classification: - * - Interrupt: No - * - Signal handler: No - * - Thread safe: No - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -int osi_config_mac_loopback(struct osi_core_priv_data *const osi_core, - const unsigned int lb_mode); - /** * @brief osi_config_fw_err_pkts - Configure forwarding of error packets * @@ -1029,7 +957,7 @@ int osi_write_phy_reg(struct osi_core_priv_data *const osi_core, * * @note * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_025 + * - SWUD_ID: ETHERNET_NVETHERNETRM_014 * * @note * Classification: @@ -1136,7 +1064,7 @@ int osi_init_core_ops(struct osi_core_priv_data *const osi_core); * * @note * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_024 + * - SWUD_ID: ETHERNET_NVETHERNETRM_005 * * @note * Classification: @@ -1844,5 +1772,75 @@ int osi_save_registers(struct osi_core_priv_data *const osi_core); * @retval -1 on failure. */ int osi_restore_registers(struct osi_core_priv_data *const osi_core); + +/** + * @brief osi_set_mdc_clk_rate - Derive MDC clock based on provided AXI_CBB clk. + * + * @note + * Algorithm: + * - MDC clock rate will be populated in OSI core private data + * structure based on AXI_CBB clock rate. + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] csr_clk_rate: CSR (AXI CBB) clock rate. + * + * @note OSD layer needs get the AXI CBB clock rate with OSD clock API + * (ex - clk_get_rate()) + * + * @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. + */ +int osi_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, + const unsigned long csr_clk_rate); + +/** + * @brief osi_config_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: Yes + * - Run time: No + * - De-initialization: No + * + * @retval 0 on success + * @retval -1 on failure. + */ +int osi_config_mac_loopback(struct osi_core_priv_data *const osi_core, + const unsigned int lb_mode); #endif /* !OSI_STRIPPED_LIB */ #endif /* OSI_CORE_H */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 5d300af..62d9e4f 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -420,59 +420,6 @@ static int eqos_config_fw_err_pkts(void *addr, return 0; } -/** - * @brief eqos_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 - * - * @pre MAC should be initialized and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int eqos_config_mac_loopback(void *addr, - const unsigned int lb_mode) -{ - unsigned int clk_ctrl_val; - unsigned int mcr_val; - - /* 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 */ - mcr_val = osi_readl((unsigned char *)addr + EQOS_MAC_MCR); - - /* Read EQOS wrapper clock control 0 register */ - clk_ctrl_val = osi_readl((unsigned char *)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_writel(clk_ctrl_val, (unsigned char *)addr + EQOS_CLOCK_CTRL_0); - - /* Write to MAC Configuration Register */ - eqos_core_safety_writel(mcr_val, (unsigned char *)addr + EQOS_MAC_MCR, - EQOS_MAC_MCR_IDX); - - return 0; -} - /** * @brief eqos_poll_for_swr - Poll for software reset (SWR bit in DMA Mode) * @@ -524,51 +471,6 @@ static int eqos_poll_for_swr(struct osi_core_priv_data *const osi_core, 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] 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()) - */ -static void eqos_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, - const unsigned long csr_clk_rate) -{ - unsigned long 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 = (unsigned int)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_set_speed - Set operating speed * @@ -3794,6 +3696,104 @@ static inline int eqos_restore_registers( 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] 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()) + */ +static void eqos_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, + const unsigned long csr_clk_rate) +{ + unsigned long 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 = (unsigned int)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] addr: Base address indicating the start of + * memory mapped IO region of the MAC. + * @param[in] lb_mode: Enable or Disable MAC loopback mode + * + * @pre MAC should be initialized and started. see osi_start_mac() + * + * @retval 0 on success + * @retval -1 on failure. + */ +static int eqos_config_mac_loopback(void *addr, + const unsigned int lb_mode) +{ + unsigned int clk_ctrl_val; + unsigned int mcr_val; + + /* 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 */ + mcr_val = osi_readl((unsigned char *)addr + EQOS_MAC_MCR); + + /* Read EQOS wrapper clock control 0 register */ + clk_ctrl_val = osi_readl((unsigned char *)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_writel(clk_ctrl_val, (unsigned char *)addr + EQOS_CLOCK_CTRL_0); + + /* Write to MAC Configuration Register */ + eqos_core_safety_writel(mcr_val, (unsigned char *)addr + EQOS_MAC_MCR, + EQOS_MAC_MCR_IDX); + + return 0; +} #endif /* !OSI_STRIPPED_LIB */ /** @@ -3809,8 +3809,6 @@ static struct osi_core_ops eqos_core_ops = { .set_mode = eqos_set_mode, .set_speed = eqos_set_speed, .pad_calibrate = eqos_pad_calibrate, - .set_mdc_clk_rate = eqos_set_mdc_clk_rate, - .config_mac_loopback = eqos_config_mac_loopback, .config_fw_err_pkts = eqos_config_fw_err_pkts, .config_rxcsum_offload = eqos_config_rxcsum_offload, .config_mac_pkt_filter_reg = eqos_config_mac_pkt_filter_reg, @@ -3844,6 +3842,8 @@ static struct osi_core_ops eqos_core_ops = { .configure_eee = eqos_configure_eee, .save_registers = eqos_save_registers, .restore_registers = eqos_restore_registers, + .set_mdc_clk_rate = eqos_set_mdc_clk_rate, + .config_mac_loopback = eqos_config_mac_loopback, #endif /* !OSI_STRIPPED_LIB */ }; diff --git a/osi/core/libnvethernetrm.export b/osi/core/libnvethernetrm.export index aa7b0a1..294f242 100644 --- a/osi/core/libnvethernetrm.export +++ b/osi/core/libnvethernetrm.export @@ -27,7 +27,6 @@ osi_init_core_ops osi_write_phy_reg osi_read_phy_reg osi_poll_for_mac_reset_complete -osi_set_mdc_clk_rate osi_hw_core_init osi_hw_core_deinit osi_start_mac @@ -36,7 +35,6 @@ osi_common_isr osi_set_mode osi_set_speed osi_pad_calibrate -osi_config_mac_loopback osi_get_mac_version osi_get_hw_features osi_config_rxcsum_offload diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 997a07f..dc96c00 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -95,18 +95,6 @@ int osi_poll_for_mac_reset_complete( return -1; } -int osi_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, - const unsigned long csr_clk_rate) -{ - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->set_mdc_clk_rate != OSI_NULL)) { - osi_core->ops->set_mdc_clk_rate(osi_core, csr_clk_rate); - return 0; - } - - return -1; -} - int osi_hw_core_init(struct osi_core_priv_data *const osi_core, unsigned int tx_fifo_size, unsigned int rx_fifo_size) @@ -197,19 +185,6 @@ int osi_pad_calibrate(struct osi_core_priv_data *const osi_core) return -1; } -int osi_config_mac_loopback(struct osi_core_priv_data *const osi_core, - const unsigned int lb_mode) -{ - /* Configure MAC loopback */ - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->config_mac_loopback != OSI_NULL)) { - return osi_core->ops->config_mac_loopback(osi_core->base, - lb_mode); - } - - return -1; -} - int osi_config_fw_err_pkts(struct osi_core_priv_data *const osi_core, const unsigned int qinx, const unsigned int fw_err) { @@ -883,4 +858,29 @@ int osi_config_arp_offload(struct osi_core_priv_data *const osi_core, return -1; } + +int osi_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, + const unsigned long csr_clk_rate) +{ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->set_mdc_clk_rate != OSI_NULL)) { + osi_core->ops->set_mdc_clk_rate(osi_core, csr_clk_rate); + return 0; + } + + return -1; +} + +int osi_config_mac_loopback(struct osi_core_priv_data *const osi_core, + const unsigned int lb_mode) +{ + /* Configure MAC loopback */ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->config_mac_loopback != OSI_NULL)) { + return osi_core->ops->config_mac_loopback(osi_core->base, + lb_mode); + } + + return -1; +} #endif /* !OSI_STRIPPED_LIB */ From bd02282f684c8d6b5e05c54cccf07130e3dd7083 Mon Sep 17 00:00:00 2001 From: rakesh goyal <rgoyal@nvidia.com> Date: Fri, 23 Oct 2020 11:54:59 +0530 Subject: [PATCH 125/458] core: move API form common/ to core/ Issue: As per unit design following APIs are part of NvEthernetRm but in current implementation is it getting compile with NvEthernetCl also - osi_get_mac_version() - osi_get_hw_features() Fix: move APIs to NvEthernetRm Bug 200669603 Change-Id: I27f5f304a586f40693d700e9bdb40b553d591544 Signed-off-by: rakesh goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2435473 (cherry picked from commit 2d74a69dd1fd0c2567a506ae0f8e797924650e28) Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2448708 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_common.h | 43 +++------------------------- include/osi_core.h | 62 +++++++++++++++++++++++++++++++++++++++++ osi/common/osi_common.c | 4 +-- osi/core/osi_core.c | 20 +++++++++++++ 4 files changed, 88 insertions(+), 41 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index d97c690..a0d8430 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -782,7 +782,7 @@ static inline unsigned long osi_update_stats_counter(unsigned long last_value, } /** - * @brief osi_get_mac_version - Reading MAC version + * @brief common_get_mac_version - Reading MAC version * * @note * Algorithm: @@ -793,55 +793,20 @@ static inline unsigned long osi_update_stats_counter(unsigned long last_value, * * @pre MAC has to be out of reset. * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_015 - * - * @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. */ -int osi_get_mac_version(void *addr, unsigned int *mac_ver); +int common_get_mac_version(void *addr, unsigned int *mac_ver); /** - * @brief osi_get_hw_features - Reading MAC HW features + * @brief comon_get_hw_features - Reading MAC HW features * * @param[in] base: io-remap MAC base address. * @param[in] 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 - * - * @note - * Classification: - * - Interrupt: No - * - Signal handler: No - * - Thread safe: No - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * */ -void osi_get_hw_features(void *base, struct osi_hw_features *hw_feat); +void common_get_hw_features(void *base, struct osi_hw_features *hw_feat); /** * @brief osi_memset - osi memset * diff --git a/include/osi_core.h b/include/osi_core.h index 28d5f8c..5ac0a28 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -1267,6 +1267,68 @@ int osi_l3l4_filter(struct osi_core_priv_data *const osi_core, const unsigned int dma_chan, const unsigned int 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] addr: io-remap MAC base address. + * @param[in] mac_ver: holds mac version. + * + * @pre MAC has to be out of reset. + * + * @note + * Traceability Details: + * - SWUD_ID: ETHERNET_NVETHERNETRM_015 + * + * @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. + */ +int osi_get_mac_version(void *addr, unsigned int *mac_ver); + +/** + * @brief osi_get_hw_features - Reading MAC HW features + * + * @param[in] base: io-remap MAC base address. + * @param[in] 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 + * + * @note + * Classification: + * - Interrupt: No + * - Signal handler: No + * - Thread safe: No + * - Required Privileges: None + * + * @note + * API Group: + * - Initialization: No + * - Run time: Yes + * - De-initialization: No + * + */ +void osi_get_hw_features(void *base, struct osi_hw_features *hw_feat); + #ifndef OSI_STRIPPED_LIB /** * @brief osi_validate_core_regs - Read-validate HW registers for func safety. diff --git a/osi/common/osi_common.c b/osi/common/osi_common.c index 4cca200..c52a3c6 100644 --- a/osi/common/osi_common.c +++ b/osi/common/osi_common.c @@ -23,7 +23,7 @@ #include <osd.h> #include "eqos_common.h" -void osi_get_hw_features(void *base, struct osi_hw_features *hw_feat) +void common_get_hw_features(void *base, struct osi_hw_features *hw_feat) { unsigned int mac_hfr0; unsigned int mac_hfr1; @@ -108,7 +108,7 @@ void osi_get_hw_features(void *base, struct osi_hw_features *hw_feat) ((mac_hfr2 >> 28U) & EQOS_MAC_HFR2_AUXSNAPNUM_MASK); } -int osi_get_mac_version(void *addr, unsigned int *mac_ver) +int common_get_mac_version(void *addr, unsigned int *mac_ver) { unsigned int macver; int ret = 0; diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index dc96c00..74952fd 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -664,6 +664,26 @@ int osi_read_mmc(struct osi_core_priv_data *const osi_core) return -1; } +void osi_get_hw_features(void *base, struct osi_hw_features *hw_feat) +{ + if ((base != OSI_NULL) && (hw_feat != OSI_NULL)) { + common_get_hw_features(base, hw_feat); + } + + return; +} + +int osi_get_mac_version(void *addr, unsigned int *mac_ver) +{ + int ret = -1; + + if ((addr != OSI_NULL) && (mac_ver != OSI_NULL)) { + return common_get_mac_version(addr, mac_ver); + } + + return ret; +} + #ifndef OSI_STRIPPED_LIB int osi_validate_core_regs(struct osi_core_priv_data *const osi_core) { From 84543e939f930084530278021c18c1c7e63a9625 Mon Sep 17 00:00:00 2001 From: rakesh goyal <rgoyal@nvidia.com> Date: Wed, 30 Sep 2020 19:59:00 +0530 Subject: [PATCH 126/458] osi: address code inspection comments Issue: 1) Code inspection comments for validation base address argument, channel out of bound check and pointer validation missing. 2) Missing debug prints before return. Fix: 1) Fix bugs/issues as per code inspection. check for base address, channel and pointers. 2) Add debug prints to identify error. Bug 200669603 Change-Id: I7e1a235c9aa9249c25a4a02927a9ea13ec3cadf8 Signed-off-by: rakesh goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2436154 Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2455383 Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_core.h | 25 +-- include/osi_dma.h | 33 ++-- osi/common/osi_common.c | 6 +- osi/core/eqos_core.c | 169 ++++++++++++----- osi/core/osi_core.c | 110 +++++++++--- osi/dma/eqos_dma.c | 22 ++- osi/dma/osi_dma.c | 151 +++++++++++----- osi/dma/osi_dma_txrx.c | 390 +++++++++++++++++++++++++++++++--------- 8 files changed, 665 insertions(+), 241 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 5ac0a28..c6645ae 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -191,16 +191,19 @@ struct osi_core_ops { /** 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) */ - void (*set_mode)(void *ioaddr, const int mode); + int (*set_mode)(struct osi_core_priv_data *const osi_core, + const int mode); /** Called to set the speed (10/100/1000) at MAC */ void (*set_speed)(void *ioaddr, const int speed); /** Called to do pad caliberation */ int (*pad_calibrate)(struct osi_core_priv_data *const osi_core); /** Called to configure MTL RxQ to forward the err pkt */ - int (*config_fw_err_pkts)(void *addr, const unsigned int qinx, - const unsigned int fw_err); + int (*config_fw_err_pkts)(struct osi_core_priv_data *const osi_core, + const unsigned int qinx, + const unsigned int fw_err); /** Called to configure Rx Checksum offload engine */ - int (*config_rxcsum_offload)(void *addr, const unsigned int enabled); + int (*config_rxcsum_offload)(struct osi_core_priv_data *const osi_core, + const unsigned int enabled); /** Called to config mac packet filter */ int (*config_mac_pkt_filter_reg)( struct osi_core_priv_data *const osi_core, @@ -286,13 +289,17 @@ struct osi_core_ops { int (*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 */ - int (*config_tx_status)(void *addr, const unsigned int tx_status); + int (*config_tx_status)(struct osi_core_priv_data *const osi_core, + const unsigned int tx_status); /** Called to configure the MAC rx crc */ - int (*config_rx_crc_check)(void *addr, const unsigned int crc_chk); + int (*config_rx_crc_check)(struct osi_core_priv_data *const osi_core, + const unsigned int crc_chk); /** Called to configure the MAC flow control */ - int (*config_flow_control)(void *addr, const unsigned int flw_ctrl); + int (*config_flow_control)(struct osi_core_priv_data *const osi_core, + const unsigned int flw_ctrl); /** Called to enable/disable HW ARP offload feature */ - int (*config_arp_offload)(const unsigned int mac_ver, void *addr, + int (*config_arp_offload)(const unsigned int mac_ver, + struct osi_core_priv_data *const osi_core, const unsigned int enable, const unsigned char *ip_addr); /** Called to configure VLAN filtering */ @@ -302,8 +309,6 @@ struct osi_core_ops { const unsigned int perfect_inverse_match); /** called to update VLAN id */ int (*update_vlan_id)(void *base, const unsigned int vid); - /** Called to get the current time from MAC */ - unsigned long long (*get_systime_from_mac)(void *addr); /** Called to reset MMC HW counter structure */ void (*reset_mmc)(struct osi_core_priv_data *const osi_core); /** Called to configure EEE Tx LPI */ diff --git a/include/osi_dma.h b/include/osi_dma.h index 01aba49..fb025f3 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -386,7 +386,7 @@ struct osi_dma_chan_ops { /** Called to stop the Tx/Rx DMA */ void (*stop_dma)(void *addr, unsigned int chan); /** Called to initialize the DMA channel */ - void (*init_dma_channel) (struct osi_dma_priv_data *osi_dma); + int (*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 @@ -512,7 +512,7 @@ struct osi_dma_priv_data { * Algorithm: * - Disables Tx interrupts at wrapper level. * - * @param[in] osi_dma: DMA private data. + * @param[in] osi_dma: OSI DMA private data. * @param[in] chan: DMA Tx channel number. * * @pre @@ -551,7 +551,7 @@ int osi_disable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, * Algorithm: * - Enables Tx interrupts at wrapper level. * - * @param[in] osi_dma: DMA private data. + * @param[in] osi_dma: OSI DMA private data. * @param[in] chan: DMA Tx channel number. * * @pre @@ -590,7 +590,7 @@ int osi_enable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, * Algorithm: * - Disables Rx interrupts at wrapper level. * - * @param[in] osi_dma: DMA private data. + * @param[in] osi_dma: OSI DMA private data. * @param[in] chan: DMA rx channel number. * * @pre @@ -629,7 +629,7 @@ int osi_disable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, * Algorithm: * - Enables Rx interrupts at wrapper level. * - * @param[in] osi_dma: DMA private data. + * @param[in] osi_dma: OSI DMA private data. * @param[in] chan: DMA rx channel number. * * @pre @@ -722,7 +722,7 @@ int osi_clear_vm_rx_intr(struct osi_dma_priv_data *osi_dma, * Algorithm: * - Start the DMA for specific MAC * - * @param[in] osi_dma: DMA private data. + * @param[in] osi_dma: OSI DMA private data. * @param[in] chan: DMA Tx/Rx channel number * * @pre @@ -759,7 +759,7 @@ int osi_start_dma(struct osi_dma_priv_data *osi_dma, * Algorithm: * - Stop the DMA for specific MAC * - * @param[in] osi_dma: DMA private data. + * @param[in] osi_dma: OSI DMA private data. * @param[in] chan: DMA Tx/Rx channel number * * @pre @@ -900,7 +900,7 @@ int osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma); * set OWN bit, Tx ring length and set starting address of Tx DMA channel * Tx ring base address in Tx DMA registers. * - * @param[in] osi: DMA private data. + * @param[in] osi_dma: OSI DMA private data. * @param[in] chan: DMA Tx channel number. * * @pre @@ -937,7 +937,7 @@ int osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma); * - De-initialization: No * */ -void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan); +void osi_hw_transmit(struct osi_dma_priv_data *osi_dma, unsigned int chan); /** * @brief osi_process_tx_completions - Process Tx complete on DMA channel ring. @@ -950,7 +950,7 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan); * - Invokes OSD layer to release DMA address and Tx buffer which are * updated as part of transmit routine. * - * @param[in] osi: OSI private data structure. + * @param[in] osi_dma: OSI dma private data structure. * @param[in] chan: Channel number on which Tx complete need to be done. * @param[in] budget: Threshold for reading the packets at a time. * @@ -978,7 +978,7 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan); * * @returns Number of descriptors (buffers) processed. */ -int osi_process_tx_completions(struct osi_dma_priv_data *osi, +int osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, unsigned int chan, int budget); /** @@ -996,7 +996,7 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi, * - Re-allocate the receive buffers, populate Rx descriptor and * handover to DMA. * - * @param[in] osi: OSI private data structure. + * @param[in] osi_dma: OSI DMA private data structure. * @param[in] chan: Rx DMA channel number * @param[in] budget: Threshold for reading the packets at a time. * @param[in] more_data_avail: Pointer to more data available flag. OSI fills @@ -1026,7 +1026,7 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi, * * @returns Number of descriptors (buffers) processed. */ -int osi_process_rx_completions(struct osi_dma_priv_data *osi, +int osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, unsigned int chan, int budget, unsigned int *more_data_avail); @@ -1038,8 +1038,7 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, * - Takes care of initializing the tx, rx ring and descriptors * based on the number of channels selected. * - * @param[in] osi_dma: DMA private data. - * + * @param[in] osi_dma: OSI DMA private data. * * @pre * - Allocate memory for osi_dma @@ -1093,7 +1092,7 @@ int osi_hw_dma_init(struct osi_dma_priv_data *osi_dma); * Algorithm: * - Takes care of stopping the MAC * - * @param[in] osi_dma: DMA private data. + * @param[in] osi_dma: OSI DMA private data. * * @pre * - MAC needs to be out of reset and proper clocks need to be configured. @@ -1124,7 +1123,7 @@ int osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma); /** * @brief osi_init_dma_ops - Initialize DMA operations * - * @param[in] osi_dma: DMA private data. + * @param[in] osi_dma: OSI DMA private data. * * @note * Traceability Details: diff --git a/osi/common/osi_common.c b/osi/common/osi_common.c index c52a3c6..abe3df6 100644 --- a/osi/common/osi_common.c +++ b/osi/common/osi_common.c @@ -125,8 +125,12 @@ int common_get_mac_version(void *addr, unsigned int *mac_ver) void osi_memset(void *s, unsigned int c, unsigned long count) { - unsigned char *xs = s; + unsigned char *xs = OSI_NULL; + if (s == OSI_NULL) { + return; + } + xs = (unsigned char *)s; while (count != 0UL) { if (c < OSI_UCHAR_MAX) { *xs++ = (unsigned char)c; diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 62d9e4f..3bc3e22 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -175,7 +175,6 @@ static void eqos_core_safety_init(struct osi_core_priv_data *const osi_core) osi_lock_init(&config->core_safety_lock); } - /** * @brief Initialize the OSI core private data backup config array * @@ -297,8 +296,7 @@ static void eqos_core_backup_init(struct osi_core_priv_data *const osi_core) /** * @brief eqos_config_flow_control - Configure MAC flow control settings * - * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. + * @param[in] osi_core: OSI core private data structure. * @param[in] flw_ctrl: flw_ctrl settings * * @pre MAC should be initialized and started. see osi_start_mac() @@ -306,13 +304,16 @@ static void eqos_core_backup_init(struct osi_core_priv_data *const osi_core) * @retval 0 on success * @retval -1 on failure. */ -static int eqos_config_flow_control(void *addr, +static int eqos_config_flow_control(struct osi_core_priv_data *const osi_core, const unsigned int 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)) { + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "flw_ctr: invalid input\n", 0ULL); return -1; } @@ -370,8 +371,7 @@ static int eqos_config_flow_control(void *addr, * When this 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] osi_core: OSI core private data structure. * @param[in] qinx: Q index * @param[in] fw_err: Enable or Disable the forwarding of error packets * @@ -380,15 +380,18 @@ static int eqos_config_flow_control(void *addr, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_config_fw_err_pkts(void *addr, +static int eqos_config_fw_err_pkts(struct osi_core_priv_data *const osi_core, const unsigned int qinx, const unsigned int fw_err) { + void *addr = osi_core->base; unsigned int 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_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "config_fw_err: invalid input\n", 0ULL); return -1; } @@ -455,6 +458,8 @@ static int eqos_poll_for_swr(struct osi_core_priv_data *const osi_core, count = 0; while (cond == 1) { if (count > retry) { + OSI_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + "poll_for_swr: timeout\n", 0ULL); return -1; } @@ -479,7 +484,7 @@ static int eqos_poll_for_swr(struct osi_core_priv_data *const osi_core, * - Based on the speed (10/100/1000Mbps) MAC will be configured * accordingly. * - * @param[in] base: EQOS virtual base address. + * @param[in] base: EQOS virtual base address. * @param[in] speed: Operating speed. * * @pre MAC should be initialized and started. see osi_start_mac() @@ -520,13 +525,18 @@ static void eqos_set_speed(void *base, const int speed) * - Based on the mode (HALF/FULL Duplex) MAC will be configured * accordingly. * - * @param[in] base: EQOS virtual base address + * @param[in] osi_core: OSI core private data structure. * @param[in] mode: Operating mode. * * @pre MAC should be initialized and started. see osi_start_mac() + * + * @retval 0 on success + * @retval -1 on failure. */ -static void eqos_set_mode(void *base, const int mode) +static int eqos_set_mode(struct osi_core_priv_data *const osi_core, + const int mode) { + void *base = osi_core->base; unsigned int mcr_val; mcr_val = osi_readl((unsigned char *)base + EQOS_MAC_MCR); @@ -539,10 +549,14 @@ static void eqos_set_mode(void *base, const int mode) /* Set DO (disable receive own) bit */ mcr_val |= EQOS_MCR_DO; } else { + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "set_mode: invalid mode\n", 0ULL); + return -1; /* Nothing here */ } eqos_core_safety_writel(mcr_val, (unsigned char *)base + EQOS_MAC_MCR, EQOS_MAC_MCR_IDX); + return 0; } /** @@ -748,7 +762,9 @@ static int eqos_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, unsigned int value; int cond = 1; - if (qinx >= OSI_EQOS_MAX_NUM_CHANS) { + if (qinx >= OSI_EQOS_MAX_NUM_QUEUES) { + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "flush_mtl_tx_queue: invalid input\n", 0ULL); return -1; } @@ -764,7 +780,9 @@ static int eqos_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, count = 0; while (cond == 1) { if (count > retry) { - return -1; + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "Poll FTQ bit timeout\n", 0ULL); + return -1; } count++; @@ -966,7 +984,7 @@ static int eqos_configure_mtl_queue(unsigned int qinx, * - Enable the IP checksum offload engine COE in MAC receiver. * - Update the MAC configuration register. * - * @param[in] addr: EQOS virtual base address. + * @param[in] osi_core: OSI core private data structure. * @param[in] enabled: Flag to indicate feature is to be enabled/disabled. * * @pre MAC should be initialized and started. see osi_start_mac() @@ -974,12 +992,15 @@ static int eqos_configure_mtl_queue(unsigned int qinx, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_config_rxcsum_offload(void *addr, +static int eqos_config_rxcsum_offload(struct osi_core_priv_data *const osi_core, const unsigned int enabled) { + void *addr = osi_core->base; unsigned int mac_mcr; if (enabled != OSI_ENABLE && enabled != OSI_DISABLE) { + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "rxsum_offload: invalid input\n", 0ULL); return -1; } @@ -1190,8 +1211,8 @@ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) /* 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 (eqos_config_flow_control(osi_core->base, - osi_core->flow_ctrl) != 0) { + if (eqos_config_flow_control(osi_core, osi_core->flow_ctrl) != + 0) { OSI_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Failed to set flow control configuration\n", 0ULL); @@ -1279,6 +1300,9 @@ static int eqos_core_init(struct osi_core_priv_data *const osi_core, /* PAD calibration */ ret = eqos_pad_calibrate(osi_core); if (ret < 0) { + OSI_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + "eqos pad calibration failed\n", + 0ULL); return ret; } @@ -1299,28 +1323,37 @@ static int eqos_core_init(struct osi_core_priv_data *const osi_core, /* Mapping MTL Rx queue and DMA Rx channel */ /* TODO: Need to add EQOS_MTL_RXQ_DMA_MAP1 for EQOS */ - value = osi_readl((unsigned char *)osi_core->base + - EQOS_MTL_RXQ_DMA_MAP0); if (osi_core->dcs_en == OSI_ENABLE) { - value |= EQOS_RXQ_TO_DMA_CHAN_MAP_DCS_EN; + value = EQOS_RXQ_TO_DMA_CHAN_MAP_DCS_EN; } else { - value |= EQOS_RXQ_TO_DMA_CHAN_MAP; + value = EQOS_RXQ_TO_DMA_CHAN_MAP; } eqos_core_safety_writel(value, (unsigned char *)osi_core->base + EQOS_MTL_RXQ_DMA_MAP0, EQOS_MTL_RXQ_DMA_MAP0_IDX); + if (osi_unlikely(osi_core->num_mtl_queues > OSI_EQOS_MAX_NUM_QUEUES)) { + OSI_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(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(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_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) { @@ -1359,6 +1392,7 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, unsigned int mac_imr = 0; unsigned int mac_pcs = 0; unsigned int mac_isr = 0; + int ret = 0; mac_isr = osi_readl((unsigned char *)osi_core->base + EQOS_MAC_ISR); @@ -1383,9 +1417,17 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, /* check for Link mode (full/half duplex) */ if ((mac_pcs & EQOS_MAC_PCS_LNKMOD) == EQOS_MAC_PCS_LNKMOD) { - eqos_set_mode(osi_core->base, OSI_FULL_DUPLEX); + ret = eqos_set_mode(osi_core, OSI_FULL_DUPLEX); + if (osi_unlikely(ret < 0)) { + OSI_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + "set mode in full duplex failed\n", 0ULL); + } } else { - eqos_set_mode(osi_core->base, OSI_HALF_DUPLEX); + ret = eqos_set_mode(osi_core, OSI_HALF_DUPLEX); + if (osi_unlikely(ret < 0)) { + OSI_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + "set mode in half duplex failed\n", 0ULL); + } } /* set speed at MAC level */ @@ -1834,7 +1876,7 @@ static int eqos_update_mac_addr_low_high_reg( * Algorithm: * - This routine to enable/disable L4/l4 filter * - * @param[in] base: Base address from OSI core private data structure. + * @param[in] base: Base address from OSI core private data structure. * @param[in] filter_enb_dis: enable/disable * * @pre MAC should be initialized and started. see osi_start_mac() @@ -1874,8 +1916,7 @@ static int eqos_config_l3_l4_filter_enable(void *base, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_update_ip4_addr( - struct osi_core_priv_data *const osi_core, +static int eqos_update_ip4_addr(struct osi_core_priv_data *const osi_core, const unsigned int filter_no, const unsigned char addr[], const unsigned int src_dst_addr_match) @@ -1885,8 +1926,7 @@ static int eqos_update_ip4_addr( unsigned int temp = 0U; if (addr == OSI_NULL) { - OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "invalid address\n", + OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "invalid address\n", 0ULL); return -1; } @@ -1933,8 +1973,7 @@ static int eqos_update_ip4_addr( * @retval 0 on success * @retval -1 on failure. */ -static int eqos_update_ip6_addr( - struct osi_core_priv_data *const osi_core, +static int eqos_update_ip6_addr(struct osi_core_priv_data *const osi_core, const unsigned int filter_no, const unsigned short addr[]) { @@ -1943,8 +1982,7 @@ static int eqos_update_ip6_addr( unsigned int temp = 0U; if (addr == OSI_NULL) { - OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "invalid address\n", + OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "invalid address\n", 0ULL); return -1; } @@ -2438,6 +2476,8 @@ static inline int eqos_poll_for_tsinit_complete( count = 0; while (cond == 1) { if (count > retry) { + OSI_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 */ @@ -2453,7 +2493,7 @@ static inline int eqos_poll_for_tsinit_complete( } /** - * @brief eqos_set_systime - Set system time + * @brief eqos_set_systime_to_mac - Set system time * * @note * Algorithm: @@ -2533,6 +2573,8 @@ static inline int eqos_poll_for_addend_complete( count = 0; while (cond == 1) { if (count > retry) { + OSI_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 */ @@ -2620,6 +2662,8 @@ static inline int eqos_poll_for_update_ts_complete( count = 0; while (cond == 1) { if (count > retry) { + OSI_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 */ @@ -2729,7 +2773,7 @@ static int eqos_adjust_mactime(struct osi_core_priv_data *const osi_core, * @brief eqos_config_tscr - Configure Time Stamp Register * * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. + * memory mapped IO region of the MAC. * @param[in] ptp_filter: PTP rx filter parameters * * @pre MAC should be initialized and started. see osi_start_mac() @@ -2884,8 +2928,7 @@ static inline int poll_for_mii_idle(struct osi_core_priv_data *osi_core) count = 0; while (cond == 1) { if (count > retry) { - OSI_ERR(osi_core->osd, - OSI_LOG_ARG_HW_FAIL, + OSI_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "MII operation timed out\n", 0ULL); return -1; @@ -3119,6 +3162,8 @@ static int eqos_validate_core_regs(struct osi_core_priv_data *const osi_core) * take care of corrective action. */ osi_unlock_irq_enabled(&config->core_safety_lock); + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "register mismatch\n", 0ULL); return -1; } } @@ -3136,8 +3181,7 @@ static int eqos_validate_core_regs(struct osi_core_priv_data *const osi_core) * field in the received packets. When this bit is reset, the MAC receiver * always checks the CRC field in the received packets. * - * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. + * @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() @@ -3145,13 +3189,16 @@ static int eqos_validate_core_regs(struct osi_core_priv_data *const osi_core) * @retval 0 on success * @retval -1 on failure. */ -static int eqos_config_rx_crc_check(void *addr, +static int eqos_config_rx_crc_check(struct osi_core_priv_data *const osi_core, const unsigned int crc_chk) { + void *addr = osi_core->base; unsigned int val; /* return on invalid argument */ if (crc_chk != OSI_ENABLE && crc_chk != OSI_DISABLE) { + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "rx_crc: invalid input\n", 0ULL); return -1; } @@ -3185,8 +3232,7 @@ static int eqos_config_rx_crc_check(void *addr, * When DTXSTS bit is set, the Tx packet status received from the MAC * are dropped in MTL. * - * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. + * @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() @@ -3194,13 +3240,16 @@ static int eqos_config_rx_crc_check(void *addr, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_config_tx_status(void *addr, +static int eqos_config_tx_status(struct osi_core_priv_data *const osi_core, const unsigned int tx_status) { + void *addr = osi_core->base; unsigned int val; /* don't allow if tx_status is other than 0 or 1 */ if (tx_status != OSI_ENABLE && tx_status != OSI_DISABLE) { + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "tx_status: invalid input\n", 0ULL); return -1; } @@ -3244,7 +3293,7 @@ static int eqos_config_tx_status(void *addr, * - Set low credit * - Update register values * - * @param[in] osi_core: osi core priv data structure + * @param[in] osi_core: OSI core priv data structure * @param[in] avb: structure having configuration for avb algorithm * * @pre @@ -3360,7 +3409,7 @@ static int eqos_set_avb_algorithm( * - read low credit * - updated pointer * - * @param[in] osi_core: osi core priv data structure + * @param[in] osi_core: OSI core priv data structure * @param[out] avb: structure pointer having configuration for avb algorithm * * @pre @@ -3444,7 +3493,7 @@ static int eqos_get_avb_algorithm(struct osi_core_priv_data *const osi_core, * * @param[in] mac_ver: MAC version number (different MAC HW version * need different register offset/fields for ARP offload. - * @param[in] addr: EQOS virtual base address. + * @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. @@ -3456,14 +3505,18 @@ static int eqos_get_avb_algorithm(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_config_arp_offload(const unsigned int mac_ver, void *addr, +static int eqos_config_arp_offload(const unsigned int mac_ver, + struct osi_core_priv_data *const osi_core, const unsigned int enable, const unsigned char *ip_addr) { + void *addr = osi_core->base; unsigned int mac_mcr; unsigned int val; if (enable != OSI_ENABLE && enable != OSI_DISABLE) { + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "arp_offload: invalid input\n", 0ULL); return -1; } @@ -3483,6 +3536,8 @@ static int eqos_config_arp_offload(const unsigned int mac_ver, void *addr, EQOS_5_00_MAC_ARPPA); } else { /* Unsupported MAC ver */ + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "arp_offload: invalid HW\n", 0ULL); return -1; } @@ -3505,7 +3560,7 @@ static int eqos_config_arp_offload(const unsigned int mac_ver, void *addr, * - 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] 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 @@ -3526,6 +3581,26 @@ static int eqos_config_vlan_filtering( unsigned int value; void *base = osi_core->base; + if (filter_enb_dis != OSI_ENABLE && filter_enb_dis != OSI_DISABLE) { + OSI_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_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_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "vlan_filter: invalid input\n", 0ULL); + return -1; + } + value = osi_readl((unsigned char *)base + EQOS_MAC_PFR); value &= ~(EQOS_MAC_PFR_VTFE); value |= ((filter_enb_dis << EQOS_MAC_PFR_SHIFT) & EQOS_MAC_PFR_VTFE); diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 74952fd..fcd5024 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -29,11 +29,11 @@ int osi_write_phy_reg(struct osi_core_priv_data *const osi_core, const unsigned short phydata) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->base != OSI_NULL) && (osi_core->ops->write_phy_reg != OSI_NULL)) { return osi_core->ops->write_phy_reg(osi_core, phyaddr, phyreg, phydata); } - return -1; } @@ -41,6 +41,7 @@ int osi_read_phy_reg(struct osi_core_priv_data *const osi_core, const unsigned int phyaddr, const unsigned int phyreg) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->base != OSI_NULL) && (osi_core->ops->read_phy_reg != OSI_NULL)) { return osi_core->ops->read_phy_reg(osi_core, phyaddr, phyreg); } @@ -57,6 +58,9 @@ int osi_init_core_ops(struct osi_core_priv_data *const osi_core) * TODO: Once These API's are mandatory, return errors instead of * default API usage. */ + if (osi_core == OSI_NULL) { + return -1; + } if (osi_core->osd_ops.ops_log == OSI_NULL) { osi_core->osd_ops.ops_log = osd_log; } @@ -88,10 +92,12 @@ int osi_poll_for_mac_reset_complete( struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->base != OSI_NULL) && (osi_core->ops->poll_for_swr != OSI_NULL)) { return osi_core->ops->poll_for_swr(osi_core, osi_core->pre_si); } + return -1; } @@ -100,6 +106,7 @@ int osi_hw_core_init(struct osi_core_priv_data *const osi_core, unsigned int rx_fifo_size) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->base != OSI_NULL) && (osi_core->ops->core_init != OSI_NULL)) { return osi_core->ops->core_init(osi_core, tx_fifo_size, rx_fifo_size); @@ -111,6 +118,7 @@ int osi_hw_core_init(struct osi_core_priv_data *const osi_core, int osi_hw_core_deinit(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->base != OSI_NULL) && (osi_core->ops->core_deinit != OSI_NULL)) { osi_core->ops->core_deinit(osi_core); return 0; @@ -122,6 +130,7 @@ int osi_hw_core_deinit(struct osi_core_priv_data *const osi_core) int osi_start_mac(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->base != OSI_NULL) && (osi_core->ops->start_mac != OSI_NULL)) { osi_core->ops->start_mac(osi_core->base); return 0; @@ -133,6 +142,7 @@ int osi_start_mac(struct osi_core_priv_data *const osi_core) int osi_stop_mac(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->base != OSI_NULL) && (osi_core->ops->stop_mac != OSI_NULL)) { osi_core->ops->stop_mac(osi_core->base); return 0; @@ -144,6 +154,7 @@ int osi_stop_mac(struct osi_core_priv_data *const osi_core) int osi_common_isr(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->base != OSI_NULL) && (osi_core->ops->handle_common_intr != OSI_NULL)) { osi_core->ops->handle_common_intr(osi_core); return 0; @@ -155,9 +166,9 @@ int osi_common_isr(struct osi_core_priv_data *const osi_core) int osi_set_mode(struct osi_core_priv_data *const osi_core, const int mode) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->base != OSI_NULL) && (osi_core->ops->set_mode != OSI_NULL)) { - osi_core->ops->set_mode(osi_core->base, mode); - return 0; + return osi_core->ops->set_mode(osi_core, mode); } return -1; @@ -167,6 +178,7 @@ int osi_set_speed(struct osi_core_priv_data *const osi_core, const int speed) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->base != OSI_NULL) && (osi_core->ops->set_speed != OSI_NULL)) { osi_core->ops->set_speed(osi_core->base, speed); return 0; @@ -178,7 +190,8 @@ int osi_set_speed(struct osi_core_priv_data *const osi_core, int osi_pad_calibrate(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->pad_calibrate != OSI_NULL)) { + (osi_core->ops->pad_calibrate != OSI_NULL) && + (osi_core->base != OSI_NULL)) { return osi_core->ops->pad_calibrate(osi_core); } @@ -190,8 +203,9 @@ int osi_config_fw_err_pkts(struct osi_core_priv_data *const osi_core, { /* Configure Forwarding of Error packets */ if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->base != OSI_NULL) && (osi_core->ops->config_fw_err_pkts != OSI_NULL)) { - return osi_core->ops->config_fw_err_pkts(osi_core->base, + return osi_core->ops->config_fw_err_pkts(osi_core, qinx, fw_err); } @@ -205,7 +219,7 @@ int osi_l2_filter(struct osi_core_priv_data *const osi_core, int ret = -1; if (osi_core == OSI_NULL || osi_core->ops == OSI_NULL || - filter == OSI_NULL) { + osi_core->base == OSI_NULL || filter == OSI_NULL) { return ret; } @@ -370,7 +384,8 @@ int osi_l3l4_filter(struct osi_core_priv_data *const osi_core, { int ret = -1; - if ((osi_core == OSI_NULL) || (osi_core->ops == OSI_NULL)) { + if (osi_core == OSI_NULL || osi_core->ops == OSI_NULL || + osi_core->base == OSI_NULL) { return ret; } @@ -421,8 +436,9 @@ int osi_config_rxcsum_offload( const unsigned int enable) { if (osi_core != OSI_NULL && osi_core->ops != OSI_NULL && + osi_core->base != OSI_NULL && osi_core->ops->config_rxcsum_offload != OSI_NULL) { - return osi_core->ops->config_rxcsum_offload(osi_core->base, + return osi_core->ops->config_rxcsum_offload(osi_core, enable); } @@ -433,6 +449,7 @@ int osi_set_systime_to_mac(struct osi_core_priv_data *const osi_core, const unsigned int sec, const unsigned int nsec) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->base != OSI_NULL) && (osi_core->ops->set_systime_to_mac != OSI_NULL)) { return osi_core->ops->set_systime_to_mac(osi_core, sec, @@ -522,14 +539,18 @@ int osi_adjust_freq(struct osi_core_priv_data *const osi_core, int ppb) if (temp < UINT_MAX) { diff = (unsigned int)temp; } else { - /* do nothing here */ + OSI_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 { - /* do nothing here */ + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "addend > UINT_MAX\n", 0ULL); + return -1; } } else { if (addend > diff) { @@ -537,15 +558,20 @@ int osi_adjust_freq(struct osi_core_priv_data *const osi_core, int ppb) } else if (addend < diff) { addend = diff - addend; } else { - /* do nothing here */ + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "quotient > UINT_MAX\n", 0ULL); + return -1; } } - if ((osi_core->ops != OSI_NULL) && + if (osi_core->ops != OSI_NULL && osi_core->base != OSI_NULL && (osi_core->ops->config_addend != OSI_NULL)) { - ret = osi_core->ops->config_addend(osi_core, addend); + return osi_core->ops->config_addend(osi_core, addend); } + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "core: Invalid argument\n", + 0ULL); + return ret; } @@ -559,6 +585,10 @@ int osi_adjust_time(struct osi_core_priv_data *const osi_core, unsigned long udelta = 0; int ret = -1; + if (osi_core == OSI_NULL) { + return ret; + } + if (nsec_delta < 0) { neg_adj = 1; nsec_delta = -nsec_delta; @@ -568,21 +598,28 @@ int osi_adjust_time(struct osi_core_priv_data *const osi_core, if (quotient <= UINT_MAX) { sec = (unsigned int)quotient; } else { - /* do nothing */ + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "quotient > UINT_MAX\n", + 0ULL); + return ret; } if (reminder <= UINT_MAX) { nsec = (unsigned int)reminder; } else { - /* do nothing here */ + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "reminder > UINT_MAX\n", + 0ULL); + return ret; } - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + if ((osi_core->ops != OSI_NULL) && (osi_core->base != OSI_NULL) && (osi_core->ops->adjust_mactime != OSI_NULL)) { - ret = osi_core->ops->adjust_mactime(osi_core, sec, nsec, + return osi_core->ops->adjust_mactime(osi_core, sec, nsec, neg_adj, osi_core->ptp_config.one_nsec_accuracy); } + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "core: Invalid argument\n", + 0ULL); + return ret; } @@ -594,6 +631,7 @@ int osi_ptp_configuration(struct osi_core_priv_data *const osi_core, unsigned long ssinc = 0; if ((osi_core == OSI_NULL) || (osi_core->ops == OSI_NULL) || + (osi_core->base == OSI_NULL) || (osi_core->ops->config_tscr == OSI_NULL) || (osi_core->ops->config_ssir == OSI_NULL) || (osi_core->ops->config_addend == OSI_NULL) || @@ -637,7 +675,9 @@ int osi_ptp_configuration(struct osi_core_priv_data *const osi_core, if (temp2 < UINT_MAX) { osi_core->default_addend = (unsigned int)temp2; } else { - /* do nothing here */ + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "core: temp2 >= UINT_MAX\n", 0ULL); + return -1; } /* Program addend value */ @@ -656,6 +696,7 @@ int osi_ptp_configuration(struct osi_core_priv_data *const osi_core, int osi_read_mmc(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->base != OSI_NULL) && (osi_core->ops->read_mmc != OSI_NULL)) { osi_core->ops->read_mmc(osi_core); return 0; @@ -690,9 +731,11 @@ int osi_validate_core_regs(struct osi_core_priv_data *const osi_core) int ret = -1; if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->base != OSI_NULL) && (osi_core->ops->validate_regs != OSI_NULL) && (osi_core->safety_config != OSI_NULL)) { ret = osi_core->ops->validate_regs(osi_core); + return ret; } return ret; @@ -702,6 +745,7 @@ int osi_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, const unsigned int qinx) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->base != OSI_NULL) && (osi_core->ops->flush_mtl_tx_queue != OSI_NULL)) { return osi_core->ops->flush_mtl_tx_queue(osi_core, qinx); } @@ -713,6 +757,7 @@ int osi_set_avb(struct osi_core_priv_data *const osi_core, const struct osi_core_avb_algorithm *avb) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->base != OSI_NULL) && (osi_core->ops->set_avb_algorithm != OSI_NULL)) { return osi_core->ops->set_avb_algorithm(osi_core, avb); } @@ -724,6 +769,7 @@ int osi_get_avb(struct osi_core_priv_data *const osi_core, struct osi_core_avb_algorithm *avb) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->base != OSI_NULL) && (osi_core->ops->get_avb_algorithm != OSI_NULL)) { return osi_core->ops->get_avb_algorithm(osi_core, avb); } @@ -736,8 +782,9 @@ int osi_configure_txstatus(struct osi_core_priv_data *const osi_core, { /* Configure Drop Transmit Status */ if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->base != OSI_NULL) && (osi_core->ops->config_tx_status != OSI_NULL)) { - return osi_core->ops->config_tx_status(osi_core->base, + return osi_core->ops->config_tx_status(osi_core, tx_status); } @@ -749,21 +796,22 @@ int osi_config_rx_crc_check(struct osi_core_priv_data *const osi_core, { /* Configure CRC Checking for Received Packets */ if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->base != OSI_NULL) && (osi_core->ops->config_rx_crc_check != OSI_NULL)) { - return osi_core->ops->config_rx_crc_check(osi_core->base, + return osi_core->ops->config_rx_crc_check(osi_core, crc_chk); } return -1; } -int osi_config_vlan_filtering( - struct osi_core_priv_data *const osi_core, +int osi_config_vlan_filtering(struct osi_core_priv_data *const osi_core, const unsigned int filter_enb_dis, const unsigned int perfect_hash_filtering, const unsigned int perfect_inverse_match) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->base != OSI_NULL) && (osi_core->ops->config_vlan_filtering != OSI_NULL)) { return osi_core->ops->config_vlan_filtering( osi_core, @@ -787,8 +835,7 @@ int osi_update_vlan_id(struct osi_core_priv_data *const osi_core, return -1; } -int osi_get_systime_from_mac( - struct osi_core_priv_data *const osi_core, +int osi_get_systime_from_mac(struct osi_core_priv_data *const osi_core, unsigned int *sec, unsigned int *nsec) { @@ -805,6 +852,7 @@ int osi_get_systime_from_mac( int osi_reset_mmc(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->base != OSI_NULL) && (osi_core->ops->reset_mmc != OSI_NULL)) { osi_core->ops->reset_mmc(osi_core); return 0; @@ -817,6 +865,7 @@ int osi_configure_eee(struct osi_core_priv_data *const osi_core, unsigned int tx_lpi_enabled, unsigned int tx_lpi_timer) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->base != OSI_NULL) && (osi_core->ops->configure_eee != OSI_NULL) && (tx_lpi_timer <= OSI_MAX_TX_LPI_TIMER) && (tx_lpi_timer >= OSI_MIN_TX_LPI_TIMER) && @@ -832,6 +881,7 @@ int osi_configure_eee(struct osi_core_priv_data *const osi_core, int osi_save_registers(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->base != OSI_NULL) && (osi_core->ops->save_registers != OSI_NULL)) { /* Call MAC save registers callback and return the value */ return osi_core->ops->save_registers(osi_core); @@ -843,6 +893,7 @@ int osi_save_registers(struct osi_core_priv_data *const osi_core) int osi_restore_registers(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->base != OSI_NULL) && (osi_core->ops->restore_registers != OSI_NULL)) { /* Call MAC restore registers callback and return the value */ return osi_core->ops->restore_registers(osi_core); @@ -851,14 +902,14 @@ int osi_restore_registers(struct osi_core_priv_data *const osi_core) return -1; } -int osi_configure_flow_control( - struct osi_core_priv_data *const osi_core, +int osi_configure_flow_control(struct osi_core_priv_data *const osi_core, const unsigned int flw_ctrl) { /* Configure Flow control settings */ if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->base != OSI_NULL) && (osi_core->ops->config_flow_control != OSI_NULL)) { - return osi_core->ops->config_flow_control(osi_core->base, + return osi_core->ops->config_flow_control(osi_core, flw_ctrl); } @@ -870,9 +921,10 @@ int osi_config_arp_offload(struct osi_core_priv_data *const osi_core, const unsigned char *ip_addr) { if (osi_core != OSI_NULL && osi_core->ops != OSI_NULL && - osi_core->ops->config_arp_offload != OSI_NULL) { + (osi_core->base != OSI_NULL) && (ip_addr != OSI_NULL) && + (osi_core->ops->config_arp_offload != OSI_NULL)) { return osi_core->ops->config_arp_offload(osi_core->mac_ver, - osi_core->base, + osi_core, flags, ip_addr); } diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index 68045a2..0d5e2c3 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -371,22 +371,22 @@ static void eqos_set_rx_ring_len(void *addr, unsigned int chan, * @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. + * @param[in] rx_desc: DMA Rx desc base address. */ static void eqos_set_rx_ring_start_addr(void *addr, unsigned int chan, - unsigned long tx_desc) + unsigned long rx_desc) { unsigned long tmp; CHECK_CHAN_BOUND(chan); - tmp = H32(tx_desc); + tmp = H32(rx_desc); if (tmp < UINT_MAX) { osi_writel((unsigned int)tmp, (unsigned char *)addr + EQOS_DMA_CHX_RDLH(chan)); } - tmp = L32(tx_desc); + tmp = L32(rx_desc); if (tmp < UINT_MAX) { osi_writel((unsigned int)tmp, (unsigned char *)addr + EQOS_DMA_CHX_RDLA(chan)); @@ -518,8 +518,6 @@ static void eqos_configure_dma_channel(unsigned int chan, { unsigned int value; - CHECK_CHAN_BOUND(chan); - /* enable DMA channel interrupts */ /* Enable TIE and TBUE */ /* TIE - Transmit Interrupt Enable */ @@ -647,8 +645,11 @@ static void eqos_dma_chan_to_vmirq_map(struct osi_dma_priv_data *osi_dma) * @brief eqos_init_dma_channel - DMA channel INIT * * @param[in] osi_dma: OSI DMA private data structure. + * + * @retval 0 on success + * @retval -1 on failure. */ -static void eqos_init_dma_channel(struct osi_dma_priv_data *osi_dma) +static int eqos_init_dma_channel(struct osi_dma_priv_data *osi_dma) { unsigned int chinx; @@ -656,10 +657,17 @@ static void eqos_init_dma_channel(struct osi_dma_priv_data *osi_dma) /* configure EQOS DMA channels */ for (chinx = 0; chinx < osi_dma->num_dma_chans; chinx++) { + if (osi_dma->dma_chans[chinx] >= OSI_EQOS_MAX_NUM_CHANS) { + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma: invalid channel number\n", 0ULL); + return -1; + } eqos_configure_dma_channel(osi_dma->dma_chans[chinx], osi_dma); } eqos_dma_chan_to_vmirq_map(osi_dma); + + return 0; } /** diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 89977bc..5414ae7 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -26,6 +26,9 @@ int osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) { + if (osi_dma == OSI_NULL) { + return -1; + } /* * Currently these osd_ops are optional to be filled in the OSD layer. * If OSD updates these pointers, use the same. If not, fall back to the @@ -57,17 +60,26 @@ int osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) return 0; } + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "dma: Invalid argument\n", + 0ULL); return -1; } int osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) { unsigned int i, chan; - int ret; + int ret = -1; if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && - osi_dma->ops->init_dma_channel != OSI_NULL) { - osi_dma->ops->init_dma_channel(osi_dma); + (osi_dma->base != OSI_NULL) && + (osi_dma->ops->init_dma_channel != OSI_NULL) && + (osi_dma->num_dma_chans <= OSI_EQOS_MAX_NUM_CHANS)) { + ret = osi_dma->ops->init_dma_channel(osi_dma); + if (ret < 0) { + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma: init dma channel failed\n", 0ULL); + return ret; + } } else { return -1; } @@ -83,16 +95,22 @@ int osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) ret = osi_enable_chan_tx_intr(osi_dma, chan); if (ret != 0) { + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma: enable tx intr failed\n", 0ULL); return ret; } ret = osi_enable_chan_rx_intr(osi_dma, chan); if (ret != 0) { + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma: enable rx intr failed\n", 0ULL); return ret; } ret = osi_start_dma(osi_dma, chan); if (ret != 0) { + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma: start dma failed\n", 0ULL); return ret; } } @@ -105,7 +123,8 @@ int osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma) unsigned int i; int ret = 0; - if (osi_dma == OSI_NULL) { + if ((osi_dma == OSI_NULL) || + (osi_dma->num_dma_chans > OSI_EQOS_MAX_NUM_CHANS)) { return -1; } @@ -123,6 +142,7 @@ int osi_disable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, unsigned int chan) { if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && + (osi_dma->base != OSI_NULL) && (chan < OSI_EQOS_MAX_NUM_CHANS) && (osi_dma->ops->disable_chan_tx_intr != OSI_NULL)) { osi_dma->ops->disable_chan_tx_intr(osi_dma->base, chan); return 0; @@ -135,6 +155,7 @@ int osi_enable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, unsigned int chan) { if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && + (osi_dma->base != OSI_NULL) && (chan < OSI_EQOS_MAX_NUM_CHANS) && (osi_dma->ops->enable_chan_tx_intr != OSI_NULL)) { osi_dma->ops->enable_chan_tx_intr(osi_dma->base, chan); return 0; @@ -147,6 +168,7 @@ int osi_disable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, unsigned int chan) { if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && + (osi_dma->base != OSI_NULL) && (chan < OSI_EQOS_MAX_NUM_CHANS) && (osi_dma->ops->disable_chan_rx_intr != OSI_NULL)) { osi_dma->ops->disable_chan_rx_intr(osi_dma->base, chan); return 0; @@ -159,6 +181,7 @@ int osi_enable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, unsigned int chan) { if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && + (osi_dma->base != OSI_NULL) && (chan < OSI_EQOS_MAX_NUM_CHANS) && (osi_dma->ops->enable_chan_rx_intr != OSI_NULL)) { osi_dma->ops->enable_chan_rx_intr(osi_dma->base, chan); return 0; @@ -205,6 +228,7 @@ int osi_start_dma(struct osi_dma_priv_data *osi_dma, unsigned int chan) { if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && + (osi_dma->base != OSI_NULL) && (chan < OSI_EQOS_MAX_NUM_CHANS) && (osi_dma->ops->start_dma != OSI_NULL)) { osi_dma->ops->start_dma(osi_dma->base, chan); return 0; @@ -217,6 +241,7 @@ int osi_stop_dma(struct osi_dma_priv_data *osi_dma, unsigned int chan) { if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && + (osi_dma->base != OSI_NULL) && (chan < OSI_EQOS_MAX_NUM_CHANS) && (osi_dma->ops->stop_dma != OSI_NULL)) { osi_dma->ops->stop_dma(osi_dma->base, chan); return 0; @@ -259,10 +284,14 @@ static inline int rx_dma_desc_validate_args(struct osi_dma_priv_data *osi_dma, if (!(rx_ring != OSI_NULL && rx_ring->rx_swcx != OSI_NULL && rx_ring->rx_desc != OSI_NULL)) { + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma: Invalid pointers\n", 0ULL); return -1; } if (chan >= OSI_EQOS_MAX_NUM_CHANS) { + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "dma: Invalid channel\n", + 0ULL); return -1; } @@ -330,6 +359,8 @@ int osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, /* Populate the newly allocated buffer address */ temp = L32(rx_swcx->buf_phy_addr); if (temp > UINT_MAX) { + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma: Invalid buf_phy_addr\n", 0ULL); /* error case do nothing */ } else { /* Store Receive Descriptor 0 */ @@ -338,8 +369,10 @@ int osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, temp = H32(rx_swcx->buf_phy_addr); if (temp <= UINT_MAX) { - /* Store Receive Descriptor 1 */ rx_desc->rdes1 = (unsigned int)temp; + } else { + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma: Invalid buf_phy_addr\n", 0ULL); } rx_desc->rdes2 = 0; @@ -359,8 +392,10 @@ int osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, tailptr = rx_ring->rx_desc_phy_addr + (sizeof(struct osi_rx_desc) * (RX_DESC_CNT)); - if (tailptr < rx_ring->rx_desc_phy_addr) { + if (osi_unlikely(tailptr < rx_ring->rx_desc_phy_addr)) { /* Will not hit this case, used for CERT-C compliance */ + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "dma: Invalid tailptr\n", + 0ULL); return -1; } @@ -381,27 +416,78 @@ int osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) return 0; } +int osi_dma_get_systime_from_mac(struct osi_dma_priv_data *const osi_dma, + unsigned int *sec, unsigned int *nsec) +{ + if ((osi_dma != OSI_NULL) && (osi_dma->base != OSI_NULL)) { + common_get_systime_from_mac(osi_dma->base, osi_dma->mac, sec, + nsec); + } else { + return -1; + } + + return 0; +} + +unsigned int osi_is_mac_enabled(struct osi_dma_priv_data *const osi_dma) +{ + if ((osi_dma != OSI_NULL) && (osi_dma->base != OSI_NULL)) { + return common_is_mac_enabled(osi_dma->base, osi_dma->mac); + } else { + return OSI_DISABLE; + } +} #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() + * + * @retval 0 on success + * @retval -1 on failure. + */ +static inline int osi_slot_args_validate(struct osi_dma_priv_data *osi_dma, + unsigned int set) +{ + if (osi_dma == OSI_NULL) { + return -1; + } + + /* return on invalid set argument */ + if ((set != OSI_ENABLE) && (set != OSI_DISABLE)) { + OSI_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, + "dma: Invalid set argument\n", + set); + return -1; + } + + /* NULL check for osi_dma, osi_dma->ops and osi_dma->ops->config_slot */ + if (osi_dma->ops == OSI_NULL || osi_dma->ops->config_slot == OSI_NULL) { + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma: Invalid set argument\n", 0ULL); + return -1; + } + + return 0; +} + int osi_config_slot_function(struct osi_dma_priv_data *osi_dma, unsigned int set) { unsigned int i = 0U, chan = 0U, interval = 0U; struct osi_tx_ring *tx_ring = OSI_NULL; - /* return on invalid set argument */ - if ((set != OSI_ENABLE) && (set != OSI_DISABLE)) { - OSI_ERR(osi_dma->osd, - OSI_LOG_ARG_INVALID, - "Invalid set argument\n", - set); - return -1; - } - - if (osi_dma == OSI_NULL || osi_dma->ops == OSI_NULL || - osi_dma->ops->config_slot == OSI_NULL) { - OSI_ERR(OSI_NULL, - OSI_LOG_ARG_INVALID, - "Invalid set argument\n", 0ULL); + /* Validate arguments */ + if (osi_slot_args_validate(osi_dma, set) < 0) { return -1; } @@ -420,7 +506,7 @@ int osi_config_slot_function(struct osi_dma_priv_data *osi_dma, if (interval > OSI_SLOT_INTVL_MAX) { OSI_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, - "Invalid interval arguments\n", + "dma: Invalid interval arguments\n", interval); return -1; } @@ -463,26 +549,3 @@ int osi_txring_empty(struct osi_dma_priv_data *osi_dma, unsigned int chan) return (tx_ring->clean_idx == tx_ring->cur_tx_idx) ? 1 : 0; } #endif /* !OSI_STRIPPED_LIB */ - -int osi_dma_get_systime_from_mac(struct osi_dma_priv_data *const osi_dma, - unsigned int *sec, - unsigned int *nsec) -{ - if ((osi_dma != OSI_NULL) && (osi_dma->base != OSI_NULL)) { - common_get_systime_from_mac(osi_dma->base, osi_dma->mac, sec, - nsec); - } else { - return -1; - } - - return 0; -} - -unsigned int osi_is_mac_enabled(struct osi_dma_priv_data *const osi_dma) -{ - if ((osi_dma != OSI_NULL) && (osi_dma->base != OSI_NULL)) { - return common_is_mac_enabled(osi_dma->base, osi_dma->mac); - } else { - return OSI_DISABLE; - } -} diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index fb34a97..db4a9bf 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -166,7 +166,7 @@ static inline int get_rx_tstamp_status(struct osi_rx_desc *context_desc) * @retval -1 if TimeStamp is not available * @retval 0 if TimeStamp is available. */ -static int get_rx_hwstamp(struct osi_dma_priv_data *osi, +static 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) @@ -191,7 +191,7 @@ static int get_rx_hwstamp(struct osi_dma_priv_data *osi, /* Do nothing here */ } /* TS not available yet, so retrying */ - osi->osd_ops.udelay(1U); + osi_dma->osd_ops.udelay(1U); } if (ret != 0) { /* Timed out waiting for Rx timestamp */ @@ -208,7 +208,6 @@ static int get_rx_hwstamp(struct osi_dma_priv_data *osi, return ret; } - /** * @brief get_rx_err_stats - Detect Errors from Rx Descriptor * @@ -241,12 +240,59 @@ static inline void get_rx_err_stats(struct osi_rx_desc *rx_desc, } } -int osi_process_rx_completions(struct osi_dma_priv_data *osi, +/** + * @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[in] rx_ring: OSI DMA channel Rx ring + * @param[in] rx_pkt_cx: OSI DMA receive packet context + * + * @retval 0 on success + * @retval -1 on failure. + */ +static inline int validate_rx_completions_arg(struct osi_dma_priv_data *osi_dma, + unsigned int chan, + unsigned int *more_data_avail, + struct osi_rx_ring **rx_ring, + struct osi_rx_pkt_cx **rx_pkt_cx) +{ + if (osi_unlikely(osi_dma == OSI_NULL || more_data_avail == OSI_NULL || + chan >= OSI_EQOS_MAX_NUM_CHANS)) { + return -1; + } + + *rx_ring = osi_dma->rx_ring[chan]; + if (osi_unlikely(*rx_ring == OSI_NULL)) { + OSI_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 || + (*rx_ring)->cur_rx_idx >= RX_DESC_CNT)) { + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "validate_input_rx_completions: Invalid pointers\n", + 0ULL); + return -1; + } + + return 0; +} + +int osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, unsigned int chan, int budget, unsigned int *more_data_avail) { - struct osi_rx_ring *rx_ring = osi->rx_ring[chan]; - struct osi_rx_pkt_cx *rx_pkt_cx = &rx_ring->rx_pkt_cx; + 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; @@ -255,8 +301,10 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, int received_resv = 0; int ret = 0; - if (rx_ring->cur_rx_idx >= RX_DESC_CNT || more_data_avail == OSI_NULL) { - return -1; + ret = validate_rx_completions_arg(osi_dma, chan, more_data_avail, + &rx_ring, &rx_pkt_cx); + if (osi_unlikely(ret < 0)) { + return ret; } /* Reset flag to indicate if more Rx frames available to OSD layer */ @@ -275,14 +323,14 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, INCR_RX_DESC_INDEX(rx_ring->cur_rx_idx, 1U); if (osi_unlikely(rx_swcx->buf_virt_addr == - osi->resv_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->osd_ops.realloc_buf != OSI_NULL) { - osi->osd_ops.realloc_buf(osi->osd, - rx_ring, chan); + if (osi_dma->osd_ops.realloc_buf != OSI_NULL) { + osi_dma->osd_ops.realloc_buf(osi_dma->osd, + rx_ring, chan); } continue; } @@ -323,7 +371,8 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, * are set */ rx_pkt_cx->flags &= ~OSI_PKT_CX_VALID; - get_rx_err_stats(rx_desc, &osi->pkt_err_stats); + get_rx_err_stats(rx_desc, + &osi_dma->pkt_err_stats); } /* Check if COE Rx checksum is valid */ @@ -332,7 +381,7 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, get_rx_vlan_from_desc(rx_desc, rx_pkt_cx); context_desc = rx_ring->rx_desc + rx_ring->cur_rx_idx; /* Get rx time stamp */ - ret = get_rx_hwstamp(osi, rx_desc, context_desc, + ret = get_rx_hwstamp(osi_dma, rx_desc, context_desc, rx_pkt_cx); if (ret == 0) { ptp_rx_swcx = rx_ring->rx_swcx + @@ -349,15 +398,25 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, */ INCR_RX_DESC_INDEX(rx_ring->cur_rx_idx, 1U); } - osi->osd_ops.receive_packet(osi->osd, rx_ring, chan, - osi->rx_buf_len, rx_pkt_cx, - rx_swcx); + 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_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma_txrx: Invalid function pointer\n", + 0ULL); + return -1; + } } - osi->dstats.q_rx_pkt_n[chan] = - osi_update_stats_counter(osi->dstats.q_rx_pkt_n[chan], - 1UL); - osi->dstats.rx_pkt_n = - osi_update_stats_counter(osi->dstats.rx_pkt_n, 1UL); + 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++; } @@ -389,16 +448,16 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi, * - This routine will be invoked by OSI layer internally to increment * stats for successfully transmitted packets on certain DMA channel. * - * @param[in] osi: Pointer to OSI DMA private data structure. + * @param[in] 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, +static inline void inc_tx_pkt_stats(struct osi_dma_priv_data *osi_dma, unsigned int chan) { - osi->dstats.q_tx_pkt_n[chan] = - osi_update_stats_counter(osi->dstats.q_tx_pkt_n[chan], 1UL); - osi->dstats.tx_pkt_n = - osi_update_stats_counter(osi->dstats.tx_pkt_n, 1UL); + 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); } /** @@ -544,20 +603,64 @@ int osi_clear_rx_pkt_err_stats(struct osi_dma_priv_data *osi_dma) } #endif /* !OSI_STRIPPED_LIB */ -int osi_process_tx_completions(struct osi_dma_priv_data *osi, +/** + * @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[in] tx_ring: OSI DMA channel Rx ring + * + * @retval 0 on success + * @retval -1 on failure. + */ +static inline int validate_tx_completions_arg(struct osi_dma_priv_data *osi_dma, + unsigned int chan, + struct osi_tx_ring **tx_ring) +{ + if (osi_unlikely(osi_dma == OSI_NULL || + chan >= OSI_EQOS_MAX_NUM_CHANS)) { + return -1; + } + + *tx_ring = osi_dma->tx_ring[chan]; + + if (osi_unlikely(*tx_ring == OSI_NULL)) { + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "validate_tx_completions_arg: Invalid pointers\n", + 0ULL); + return -1; + } + + return 0; +} + +int osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, unsigned int chan, int budget) { - struct osi_tx_ring *tx_ring = osi->tx_ring[chan]; - struct osi_txdone_pkt_cx *txdone_pkt_cx = &tx_ring->txdone_pkt_cx; + 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; - unsigned int entry = tx_ring->clean_idx; + unsigned int entry = 0U; unsigned long vartdes1; unsigned long long ns; int processed = 0; + int ret; - osi->dstats.tx_clean_n[chan] = - osi_update_stats_counter(osi->dstats.tx_clean_n[chan], 1U); + 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 < TX_DESC_CNT && processed < budget) { @@ -575,9 +678,10 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi, if ((tx_desc->tdes3 & TDES3_ES_BITS) != 0U) { txdone_pkt_cx->flags |= OSI_TXDONE_CX_ERROR; /* fill packet error stats */ - get_tx_err_stats(tx_desc, &osi->pkt_err_stats); + get_tx_err_stats(tx_desc, + &osi_dma->pkt_err_stats); } else { - inc_tx_pkt_stats(osi, chan); + inc_tx_pkt_stats(osi_dma, chan); } if (processed < INT_MAX) { @@ -613,9 +717,18 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi, txdone_pkt_cx->flags |= OSI_TXDONE_CX_PAGED_BUF; } - osi->osd_ops.transmit_complete(osi->osd, tx_swcx->buf_virt_addr, - tx_swcx->buf_phy_addr, - tx_swcx->len, txdone_pkt_cx); + if (osi_likely(osi_dma->osd_ops.transmit_complete != + OSI_NULL)) { + osi_dma->osd_ops.transmit_complete(osi_dma->osd, + tx_swcx->buf_virt_addr, + tx_swcx->buf_phy_addr, + tx_swcx->len, + txdone_pkt_cx); + } else { + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma_txrx: Invalid function pointer\n", 0ULL); + return -1; + } tx_desc->tdes3 = 0; tx_desc->tdes2 = 0; @@ -795,40 +908,94 @@ static inline void dmb_oshst(void) asm volatile("dmb oshst" : : : "memory"); } -void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan) +/** + * @brief validate_hw_transmit_arg- Validate input argument of hw_transmit + * + * @note + * Algorithm: + * - This routine validate input arguments to osi_hw_transmit() + * + * @param[in] osi_dma: OSI DMA private data structure. + * @param[in] chan: Tx DMA channel number + * @param[in] ops: OSI DMA Channel operations + * @param[in] tx_ring: OSI DMA channel Tx ring + * + * @retval 0 on success + * @retval -1 on failure. + */ +static inline int validate_hw_transmit_arg(struct osi_dma_priv_data *osi_dma, + unsigned int chan, + struct osi_dma_chan_ops **ops, + struct osi_tx_ring **tx_ring) { - struct osi_tx_ring *tx_ring = osi->tx_ring[chan]; - struct osi_dma_chan_ops *ops = osi->ops; - unsigned int entry = tx_ring->cur_tx_idx; - struct osi_tx_desc *tx_desc = tx_ring->tx_desc + entry; - struct osi_tx_swcx *tx_swcx = tx_ring->tx_swcx + entry; - struct osi_tx_pkt_cx *tx_pkt_cx = &tx_ring->tx_pkt_cx; - unsigned int desc_cnt = tx_pkt_cx->desc_cnt; + if (osi_unlikely(osi_dma == OSI_NULL || + chan >= OSI_EQOS_MAX_NUM_CHANS)) { + return -1; + } + + *tx_ring = osi_dma->tx_ring[chan]; + *ops = osi_dma->ops; + + if (osi_unlikely(*tx_ring == OSI_NULL || *ops == OSI_NULL)) { + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "validate_hw_transmit_arg: Invalid pointers\n", 0ULL); + return -1; + } + + return 0; +} + +void osi_hw_transmit(struct osi_dma_priv_data *osi_dma, unsigned int chan) +{ + struct osi_tx_ring *tx_ring = OSI_NULL; + struct osi_dma_chan_ops *ops = OSI_NULL; + unsigned int entry = 0U; + struct osi_tx_desc *tx_desc = OSI_NULL; + struct osi_tx_swcx *tx_swcx = OSI_NULL; + struct osi_tx_pkt_cx *tx_pkt_cx = OSI_NULL; + unsigned int desc_cnt = 0U; struct osi_tx_desc *last_desc = OSI_NULL; struct osi_tx_desc *first_desc = OSI_NULL; struct osi_tx_desc *cx_desc = OSI_NULL; unsigned long tailptr, tmp; - unsigned int i; int cntx_desc_consumed; + unsigned int i; + int ret = 0; + ret = validate_hw_transmit_arg(osi_dma, chan, &ops, &tx_ring); + if (osi_unlikely(ret < 0)) { + return; + } + + entry = tx_ring->cur_tx_idx; if (entry >= TX_DESC_CNT) { - return; - } - if (desc_cnt == 0U) { - /* Will not hit this case */ + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma_txrx: Invalid pointers\n", 0ULL); return; } + 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_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma_txrx: Invalid value\n", 0ULL); + return; + } /* Context descriptor for VLAN/TSO */ if ((tx_pkt_cx->flags & OSI_PKT_CX_VLAN) == OSI_PKT_CX_VLAN) { - osi->dstats.tx_vlan_pkt_n = - osi_update_stats_counter(osi->dstats.tx_vlan_pkt_n, + 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->dstats.tx_tso_pkt_n = - osi_update_stats_counter(osi->dstats.tx_tso_pkt_n, 1UL); + 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_desc); @@ -881,24 +1048,25 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan) if (tx_ring->frame_cnt < UINT_MAX) { tx_ring->frame_cnt++; - } else if (osi->use_tx_frames == OSI_ENABLE && - (tx_ring->frame_cnt % osi->tx_frames) < UINT_MAX) { + } 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->tx_frames) + 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->use_tx_usecs == OSI_ENABLE) { + 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->use_tx_frames == OSI_ENABLE) { - if ((tx_ring->frame_cnt % osi->tx_frames) == OSI_NONE) { + if (osi_dma->use_tx_frames == OSI_ENABLE) { + if ((tx_ring->frame_cnt % osi_dma->tx_frames) == + OSI_NONE) { last_desc->tdes2 |= TDES2_IOC; } } @@ -913,8 +1081,10 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan) tailptr = tx_ring->tx_desc_phy_addr + (entry * sizeof(struct osi_tx_desc)); - if (tailptr < tx_ring->tx_desc_phy_addr) { + if (osi_unlikely(tailptr < tx_ring->tx_desc_phy_addr)) { /* Will not hit this case */ + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma_txrx: Invalid argument\n", 0ULL); return; } @@ -925,7 +1095,12 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan) * before setting up the DMA, hence add memory write barrier here. */ dmb_oshst(); - ops->update_tx_tailptr(osi->base, chan, tailptr); + if (osi_unlikely(ops->update_tx_tailptr == OSI_NULL)) { + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma_txrx: Invalid argument\n", 0ULL); + return; + } + ops->update_tx_tailptr(osi_dma->base, chan, tailptr); } /** @@ -937,23 +1112,30 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi, unsigned int chan) * set OWN bit, Rx ring length and set starting address of Rx DMA channel. * Tx ring base address in Tx DMA registers. * - * @param[in] osi: OSI private data structure. + * @param[in] osi_dma: OSI private data structure. * @param[in] chan: Rx channel number. * * @retval 0 on success * @retval -1 on failure. */ -static int rx_dma_desc_initialization(struct osi_dma_priv_data *osi, +static int rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, unsigned int chan) { - struct osi_rx_ring *rx_ring = osi->rx_ring[chan]; + struct osi_rx_ring *rx_ring = OSI_NULL; struct osi_rx_desc *rx_desc = OSI_NULL; struct osi_rx_swcx *rx_swcx = OSI_NULL; - struct osi_dma_chan_ops *ops = osi->ops; + struct osi_dma_chan_ops *ops = osi_dma->ops; unsigned long tailptr = 0, tmp; unsigned int i; int ret = 0; + rx_ring = osi_dma->rx_ring[chan]; + if (osi_unlikely(rx_ring == OSI_NULL)) { + OSI_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; @@ -970,20 +1152,28 @@ static int rx_dma_desc_initialization(struct osi_dma_priv_data *osi, tmp = L32(rx_swcx->buf_phy_addr); if (tmp < UINT_MAX) { rx_desc->rdes0 = (unsigned int)tmp; + } else { + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma_txrx: Invalid buf_phy_addr\n", 0ULL); + return -1; } tmp = H32(rx_swcx->buf_phy_addr); if (tmp < UINT_MAX) { rx_desc->rdes1 = (unsigned int)tmp; + } else { + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma_txrx: Invalid buf_phy_addr\n", 0ULL); + return -1; } rx_desc->rdes2 = 0; rx_desc->rdes3 = (RDES3_OWN | RDES3_IOC | RDES3_B1V); /* reconfigure INTE bit if RX watchdog timer is enabled */ - if (osi->use_riwt == OSI_ENABLE) { + if (osi_dma->use_riwt == OSI_ENABLE) { rx_desc->rdes3 &= ~RDES3_IOC; - if (osi->use_rx_frames == OSI_ENABLE) { - if ((i % osi->rx_frames) == OSI_NONE) { + 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. @@ -998,14 +1188,21 @@ static int rx_dma_desc_initialization(struct osi_dma_priv_data *osi, tailptr = rx_ring->rx_desc_phy_addr + sizeof(struct osi_rx_desc) * (RX_DESC_CNT); - if (tailptr < rx_ring->rx_desc_phy_addr) { + + if (osi_unlikely(tailptr < rx_ring->rx_desc_phy_addr || + ops->set_rx_ring_len == OSI_NULL || + ops->update_rx_tailptr == OSI_NULL || + ops->set_rx_ring_start_addr == OSI_NULL)) { /* Will not hit this case */ + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma_txrx: Invalid pointers\n", 0ULL); return -1; } - ops->set_rx_ring_len(osi->base, chan, (RX_DESC_CNT - 1U)); - ops->update_rx_tailptr(osi->base, chan, tailptr); - ops->set_rx_ring_start_addr(osi->base, chan, rx_ring->rx_desc_phy_addr); + ops->set_rx_ring_len(osi_dma->base, chan, (RX_DESC_CNT - 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; } @@ -1019,21 +1216,21 @@ static int rx_dma_desc_initialization(struct osi_dma_priv_data *osi, * set OWN bit, Rx ring length and set starting address of Rx DMA channel. * Tx ring base address in Tx DMA registers. * - * @param[in] osi: OSI private data structure. + * @param[in] osi_dma: OSI private data structure. * * @retval 0 on success * @retval -1 on failure. */ -static int rx_dma_desc_init(struct osi_dma_priv_data *osi) +static int rx_dma_desc_init(struct osi_dma_priv_data *osi_dma) { unsigned int chan = 0; unsigned int i; int ret = 0; - for (i = 0; i < osi->num_dma_chans; i++) { - chan = osi->dma_chans[i]; + for (i = 0; i < osi_dma->num_dma_chans; i++) { + chan = osi_dma->dma_chans[i]; - ret = rx_dma_desc_initialization(osi, chan); + ret = rx_dma_desc_initialization(osi_dma, chan); if (ret != 0) { return ret; } @@ -1051,8 +1248,11 @@ static int rx_dma_desc_init(struct osi_dma_priv_data *osi) * Tx ring base address in Tx DMA registers. * * @param[in] osi_dma: OSI DMA private data structure. + * + * @retval 0 on success + * @retval -1 on failure. */ -static void tx_dma_desc_init(struct osi_dma_priv_data *osi_dma) +static int tx_dma_desc_init(struct osi_dma_priv_data *osi_dma) { struct osi_tx_ring *tx_ring = OSI_NULL; struct osi_tx_desc *tx_desc = OSI_NULL; @@ -1063,7 +1263,13 @@ static void tx_dma_desc_init(struct osi_dma_priv_data *osi_dma) 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_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma_txrx: Invalid pointers\n", 0ULL); + return -1; + } for (j = 0; j < TX_DESC_CNT; j++) { tx_desc = tx_ring->tx_desc + j; @@ -1087,18 +1293,30 @@ static void tx_dma_desc_init(struct osi_dma_priv_data *osi_dma) tx_ring->slot_number = 0U; tx_ring->slot_check = OSI_DISABLE; - ops->set_tx_ring_len(osi_dma->base, chan, - (TX_DESC_CNT - 1U)); - ops->set_tx_ring_start_addr(osi_dma->base, chan, - tx_ring->tx_desc_phy_addr); + if (osi_likely(ops->set_tx_ring_len != OSI_NULL || + ops->set_tx_ring_start_addr != OSI_NULL)) { + ops->set_tx_ring_len(osi_dma->base, chan, + (TX_DESC_CNT - 1U)); + ops->set_tx_ring_start_addr(osi_dma->base, chan, + tx_ring->tx_desc_phy_addr); + } else { + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma_txrx: Invalid pointers\n", 0ULL); + return -1; + } } + + return 0; } int dma_desc_init(struct osi_dma_priv_data *osi_dma) { int ret = 0; - tx_dma_desc_init(osi_dma); + ret = tx_dma_desc_init(osi_dma); + if (ret != 0) { + return ret; + } ret = rx_dma_desc_init(osi_dma); if (ret != 0) { From d56c3e8ece6aa7b9c874b61b1e3c47c081360ab0 Mon Sep 17 00:00:00 2001 From: rakesh goyal <rgoyal@nvidia.com> Date: Wed, 11 Nov 2020 16:57:05 +0530 Subject: [PATCH 127/458] osi: dma: Fix CERT INT30-C Issue: Cert issue introduced when removed unused check Fix: add code back as it is required for cert-C Bug 200669603 Change-Id: Ie35f6fc8a9e5436484d75af3506d3ee6cb35ebba Signed-off-by: rakesh goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2444585 (cherry picked from commit a6fae4610640469ff9b406b7e909d8cde2c1786c) Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2455384 Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/dma/eqos_dma.c | 2 ++ osi/dma/osi_dma_txrx.c | 9 +++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index 0d5e2c3..cf31b20 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -518,6 +518,8 @@ static void eqos_configure_dma_channel(unsigned int chan, { unsigned int value; + CHECK_CHAN_BOUND(chan); + /* enable DMA channel interrupts */ /* Enable TIE and TBUE */ /* TIE - Transmit Interrupt Enable */ diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index db4a9bf..d385a01 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -276,8 +276,7 @@ static inline int validate_rx_completions_arg(struct osi_dma_priv_data *osi_dma, return -1; } *rx_pkt_cx = &(*rx_ring)->rx_pkt_cx; - if (osi_unlikely(*rx_pkt_cx == OSI_NULL || - (*rx_ring)->cur_rx_idx >= RX_DESC_CNT)) { + if (osi_unlikely(*rx_pkt_cx == OSI_NULL)) { OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "validate_input_rx_completions: Invalid pointers\n", 0ULL); @@ -307,6 +306,12 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, return ret; } + if (rx_ring->cur_rx_idx >= RX_DESC_CNT) { + OSI_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; From 650b5f40d3f589394049d0dc3209fab42bd3e0c2 Mon Sep 17 00:00:00 2001 From: Nagarjuna Kristam <nkristam@nvidia.com> Date: Tue, 3 Nov 2020 16:12:07 +0530 Subject: [PATCH 128/458] osi: dma: Address review feedback - Use OSI and OSD reference instead of HW and SW for packet context fields. - Update doxygen comments. Bug 200673381 Change-Id: I10fac8476657bdf7048673f24d41271651fd200b Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2440621 (cherry picked from commit 687e36d5a58ffa9d34267994c04da296495be28c) Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2455385 Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: Rakesh Goyal <rgoyal@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_dma.h | 2 +- osi/dma/osi_dma_txrx.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/osi_dma.h b/include/osi_dma.h index fb025f3..5381dea 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -60,7 +60,7 @@ * @addtogroup EQOS-PKT Packet context fields * * @brief These flags are used to convey context information about a packet - * between HW and SW. The context information includes + * 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, diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index d385a01..d9eda28 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -158,7 +158,7 @@ static inline int get_rx_tstamp_status(struct osi_rx_desc *context_desc) * - 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] osi: OSI private data structure. + * @param[in] osi_dma: OSI private data structure. * @param[in] rx_desc: Rx descriptor * @param[in] context_desc: Rx context descriptor * @param[in] rx_pkt_cx: Rx packet context From 999d5d6820b9d091a00b98b9ccbfd0eb101bc98a Mon Sep 17 00:00:00 2001 From: rakesh goyal <rgoyal@nvidia.com> Date: Tue, 1 Dec 2020 14:19:46 +0530 Subject: [PATCH 129/458] osi: update API group Issue: Need to add "API Group" for all APIs. Fix: Add "API Group" to all APIs Bug 200681427 Change-Id: Iea2a77943c61dc166dd885f556454c63e4f6c716 Signed-off-by: rakesh goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2453124 (cherry picked from commit b914e618d1ee70b92d60314f7614b20c34772fbc) Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2455386 Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osd.h | 39 ++- include/osi_common.h | 65 ++++- include/osi_core.h | 24 +- include/osi_dma.h | 22 +- osi/common/eqos_common.h | 12 + osi/common/include/local_common.h | 12 + osi/common/osi_common.c | 8 +- osi/core/eqos_core.c | 393 +++++++++++++++++++++++++++++- osi/core/eqos_mmc.c | 18 ++ osi/core/osi_core.c | 24 ++ osi/dma/eqos_dma.c | 116 ++++++++- osi/dma/eqos_dma.h | 12 + osi/dma/osi_dma.c | 18 ++ osi/dma/osi_dma_local.h | 6 + osi/dma/osi_dma_txrx.c | 96 ++++++++ 15 files changed, 841 insertions(+), 24 deletions(-) diff --git a/include/osd.h b/include/osd.h index 6671501..e2791d5 100644 --- a/include/osd.h +++ b/include/osd.h @@ -28,18 +28,36 @@ * * @param[in] umin: Minimum time in usecs to sleep * @param[in] umax: Maximum time in usecs to sleep + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: Yes + * - De-initialization: No */ void osd_usleep_range(unsigned long umin, unsigned long umax); /** * @brief osd_msleep - sleep in milli seconds * * @param[in] msec: time in milli seconds + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: Yes + * - De-initialization: No */ void osd_msleep(unsigned int msec); /** * @brief osd_udelay - delay in micro seconds * * @param[in] usec: time in usec + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: Yes + * - De-initialization: No */ void osd_udelay(unsigned long usec); /** @@ -58,9 +76,15 @@ void osd_udelay(unsigned long usec); * @param[in] chan: DMA Rx channel number. * @param[in] dma_buf_len: Rx DMA buffer length. * @param[in] rxpkt_cx: Received packet context. - * @param[in] rx_pkt_swcx: Received packet sw context. + * @param[out] rx_pkt_swcx: Received packet sw context. * * @pre Rx completion need to make sure that Rx descriptors processed properly. + * + * @note + * API Group: + * - Initialization: No + * - Run time: Yes + * - De-initialization: No */ void osd_receive_packet(void *priv, void *rxring, unsigned int chan, unsigned int dma_buf_len, void *rxpkt_cx, @@ -79,7 +103,7 @@ void osd_receive_packet(void *priv, void *rxring, unsigned int chan, * @param[in] buffer: Buffer address to free. * @param[in] dmaaddr: DMA address to unmap. * @param[in] len: Length of data. - * @param[in] txdone_pkt_cx: Pointer to struct which has tx done status info. + * @param[out] txdone_pkt_cx: Pointer to struct which has tx done status info. * This struct has flags to indicate tx error, whether DMA address * is mapped from paged/linear buffer, Time stamp availability, * if TS available txdone_pkt_cx->ns stores the time stamp. @@ -89,6 +113,12 @@ void osd_receive_packet(void *priv, void *rxring, unsigned int chan, * OSI_TXDONE_CX_TS OSI_BIT(2) * * @pre Tx completion need to make sure that Tx descriptors processed properly. + * + * @note + * API Group: + * - Initialization: No + * - Run time: Yes + * - De-initialization: No */ void osd_transmit_complete(void *priv, void *buffer, unsigned long dmaaddr, unsigned int len, void *txdone_pkt_cx); @@ -103,6 +133,11 @@ void osd_transmit_complete(void *priv, void *buffer, unsigned long dmaaddr, * @param[in] err: error string * @param[in] loga: error additional information * + * @note + * API Group: + * - Initialization: Yes + * - Run time: Yes + * - De-initialization: Yes */ void osd_log(void *priv, const char *func, diff --git a/include/osi_common.h b/include/osi_common.h index a0d8430..ed410ca 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -652,6 +652,12 @@ struct osi_hw_features { * - 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(unsigned int *lock) { @@ -670,6 +676,12 @@ static inline void osi_lock_init(unsigned int *lock) * @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(unsigned int *lock) { @@ -696,6 +708,12 @@ static inline void osi_lock_irq_enabled(unsigned int *lock) * @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(unsigned int *lock) { @@ -713,6 +731,12 @@ static inline void osi_unlock_irq_enabled(unsigned int *lock) * @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 unsigned int osi_readl(void *addr) { @@ -726,6 +750,12 @@ static inline unsigned int osi_readl(void *addr) * @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(unsigned int val, void *addr) { @@ -739,6 +769,12 @@ static inline void osi_writel(unsigned int val, void *addr) * * @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 */ @@ -766,6 +802,12 @@ static inline int is_valid_mac_version(unsigned int mac_ver) * * @note Input parameter should be only unsigned long type * + * @note + * API Group: + * - Initialization: No + * - Run time: Yes + * - De-initialization: No + * * @return unsigned long value */ static inline unsigned long osi_update_stats_counter(unsigned long last_value, @@ -789,10 +831,16 @@ static inline unsigned long osi_update_stats_counter(unsigned long last_value, * - Reads MAC version and check whether its valid or not. * * @param[in] addr: io-remap MAC base address. - * @param[in] mac_ver: holds mac version. + * @param[out] mac_ver: holds mac version. * * @pre MAC has to be out of reset. * + * @note + * API Group: + * - Initialization: Yes + * - Run time: Yes + * - De-initialization: No + * * @retval 0 on success * @retval -1 on failure. */ @@ -802,7 +850,13 @@ int common_get_mac_version(void *addr, unsigned int *mac_ver); * @brief comon_get_hw_features - Reading MAC HW features * * @param[in] base: io-remap MAC base address. - * @param[in] hw_feat: holds the supported features of the hardware. + * @param[out] hw_feat: holds the supported features of the hardware. + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: No + * - De-initialization: No * * @pre MAC has to be out of reset. */ @@ -810,10 +864,15 @@ void common_get_hw_features(void *base, struct osi_hw_features *hw_feat); /** * @brief osi_memset - osi memset * - * @param[in] s: source that need to be set + * @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 */ void osi_memset(void *s, unsigned int c, unsigned long count); #endif /* OSI_COMMON_H */ diff --git a/include/osi_core.h b/include/osi_core.h index c6645ae..e8405b6 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -1280,7 +1280,7 @@ int osi_l3l4_filter(struct osi_core_priv_data *const osi_core, * - Reads MAC version and check whether its valid or not. * * @param[in] addr: io-remap MAC base address. - * @param[in] mac_ver: holds mac version. + * @param[out] mac_ver: holds mac version. * * @pre MAC has to be out of reset. * @@ -1310,7 +1310,7 @@ int osi_get_mac_version(void *addr, unsigned int *mac_ver); * @brief osi_get_hw_features - Reading MAC HW features * * @param[in] base: io-remap MAC base address. - * @param[in] hw_feat: holds the supported features of the hardware. + * @param[out] hw_feat: holds the supported features of the hardware. * * @pre MAC has to be out of reset. * @@ -1617,7 +1617,7 @@ int osi_configure_flow_control(struct osi_core_priv_data *const osi_core, * * @note * API Group: - * - Initialization: Yes + * - Initialization: No * - Run time: Yes * - De-initialization: No * @@ -1822,6 +1822,12 @@ int osi_configure_eee(struct osi_core_priv_data *const osi_core, * - No further configuration change in MAC shall be done after invoking * this API * + * @note + * API Group: + * - Initialization: No + * - Run time: Yes + * - De-initialization: No + * * @retval 0 on success * @retval -1 on failure. */ @@ -1835,6 +1841,12 @@ int osi_save_registers(struct osi_core_priv_data *const osi_core); * @pre * - MAC and PHY 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. */ @@ -1867,7 +1879,7 @@ int osi_restore_registers(struct osi_core_priv_data *const osi_core); * @note * API Group: * - Initialization: Yes - * - Run time: Yes + * - Run time: No * - De-initialization: No * * @retval 0 on success @@ -1900,8 +1912,8 @@ int osi_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, * * @note * API Group: - * - Initialization: Yes - * - Run time: No + * - Initialization: No + * - Run time: Yes * - De-initialization: No * * @retval 0 on success diff --git a/include/osi_dma.h b/include/osi_dma.h index 5381dea..4116821 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -534,7 +534,7 @@ struct osi_dma_priv_data { * * @note * API Group: - * - Initialization: Yes + * - Initialization: No * - Run time: Yes * - De-initialization: Yes * @@ -575,7 +575,7 @@ int osi_disable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, * API Group: * - Initialization: Yes * - Run time: Yes - * - De-initialization: Yes + * - De-initialization: No * * @retval 0 on success * @retval -1 on failure. @@ -612,7 +612,7 @@ int osi_enable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, * * @note * API Group: - * - Initialization: Yes + * - Initialization: No * - Run time: Yes * - De-initialization: Yes * @@ -653,7 +653,7 @@ int osi_disable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, * API Group: * - Initialization: Yes * - Run time: Yes - * - De-initialization: Yes + * - De-initialization: No * * @retval 0 on success * @retval -1 on failure. @@ -1318,7 +1318,7 @@ int osi_clear_tx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); * @note * API Group: * - Initialization: Yes - * - Run time: No + * - Run time: Yes * - De-initialization: No * * @retval 0 on success @@ -1341,6 +1341,12 @@ int osi_config_slot_function(struct osi_dma_priv_data *osi_dma, * - 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 + * * @retval 0 on success * @retval -1 on failure. */ @@ -1361,6 +1367,12 @@ int osi_clear_rx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); * - 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 + * * @retval 1 if ring is empty. * @retval 0 if ring has outstanding packets. */ diff --git a/osi/common/eqos_common.h b/osi/common/eqos_common.h index 0b374f9..4f9a2d4 100644 --- a/osi/common/eqos_common.h +++ b/osi/common/eqos_common.h @@ -51,6 +51,12 @@ * * @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. */ @@ -64,6 +70,12 @@ unsigned long long eqos_get_systime_from_mac(void *addr); * * @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. */ diff --git a/osi/common/include/local_common.h b/osi/common/include/local_common.h index 6f9f209..73f1e8a 100644 --- a/osi/common/include/local_common.h +++ b/osi/common/include/local_common.h @@ -35,6 +35,12 @@ * * @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. */ @@ -49,6 +55,12 @@ void common_get_systime_from_mac(void *addr, unsigned int 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. */ diff --git a/osi/common/osi_common.c b/osi/common/osi_common.c index abe3df6..ea75442 100644 --- a/osi/common/osi_common.c +++ b/osi/common/osi_common.c @@ -154,7 +154,13 @@ void osi_memset(void *s, unsigned int c, unsigned long count) * @pre MAC IP should be out of reset and need to be initialized as the * requirements * - * @returns Quotient + * @note + * API Group: + * - Initialization: No + * - Run time: Yes + * - De-initialization: No + * + * @retval Quotient */ static inline unsigned long div_u64_rem(unsigned long dividend, unsigned long divisor, diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 3bc3e22..9eeaa95 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -48,6 +48,12 @@ static struct core_func_safety eqos_core_safety_config; * @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(unsigned int val, void *addr, unsigned int idx) @@ -73,6 +79,12 @@ static inline void eqos_core_safety_writel(unsigned int val, void *addr, * 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) { @@ -183,6 +195,12 @@ static void eqos_core_safety_init(struct osi_core_priv_data *const osi_core) * - 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. * * @retval none @@ -301,6 +319,12 @@ static void eqos_core_backup_init(struct osi_core_priv_data *const osi_core) * * @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. */ @@ -372,11 +396,17 @@ static int eqos_config_flow_control(struct osi_core_priv_data *const osi_core, * are forwarded to the application or DMA. * * @param[in] osi_core: OSI core private data structure. - * @param[in] qinx: Q index + * @param[in] qinx: Queue index * @param[in] fw_err: Enable or 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. */ @@ -436,6 +466,12 @@ static int eqos_config_fw_err_pkts(struct osi_core_priv_data *const osi_core, * * @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 * @retval -1 on failure. */ @@ -487,6 +523,12 @@ static int eqos_poll_for_swr(struct osi_core_priv_data *const osi_core, * @param[in] base: EQOS virtual base address. * @param[in] speed: Operating speed. * + * @note + * API Group: + * - Initialization: Yes + * - Run time: Yes + * - De-initialization: No + * * @pre MAC should be initialized and started. see osi_start_mac() */ static void eqos_set_speed(void *base, const int speed) @@ -530,6 +572,12 @@ static void eqos_set_speed(void *base, const int speed) * * @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. */ @@ -573,6 +621,12 @@ static int eqos_set_mode(struct osi_core_priv_data *const osi_core, * * @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 unsigned int eqos_calculate_per_queue_fifo(unsigned int fifo_size, @@ -677,6 +731,12 @@ static unsigned int eqos_calculate_per_queue_fifo(unsigned int fifo_size, * - 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. */ @@ -750,6 +810,12 @@ calibration_failed: * - 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. */ @@ -808,8 +874,14 @@ static int eqos_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, * Flow control) and RSA (Threshold for Activating Flow Control) values * based on the Rx FIFO size and also enables HW flow control * + * @note + * API Group: + * - Initialization: Yes + * - Run time: No + * - De-initialization: No + * * @param[in] rx_fifo: Rx FIFO size. - * @param[in] value: Stores RFD and RSA values + * @param[out] value: Stores RFD and RSA values */ void update_ehfc_rfa_rfd(unsigned int rx_fifo, unsigned int *value) { @@ -916,6 +988,12 @@ void update_ehfc_rfa_rfd(unsigned int rx_fifo, unsigned int *value) * * @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. */ @@ -989,6 +1067,12 @@ static int eqos_configure_mtl_queue(unsigned int qinx, * * @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. */ @@ -1034,6 +1118,12 @@ static int eqos_config_rxcsum_offload(struct osi_core_priv_data *const osi_core, * @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) @@ -1098,6 +1188,12 @@ static void eqos_configure_rxq_priority( * @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_mac(struct osi_core_priv_data *const osi_core) { @@ -1238,6 +1334,12 @@ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) * @param[in] base: EQOS virtual base address. * * @pre MAC has to be out of reset. + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: No + * - De-initialization: No */ static void eqos_configure_dma(void *base) { @@ -1281,6 +1383,12 @@ static void eqos_configure_dma(void *base) * - 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. */ @@ -1385,6 +1493,12 @@ static int eqos_core_init(struct osi_core_priv_data *const osi_core, * @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, unsigned int dma_isr) @@ -1456,6 +1570,12 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, * @param[in] 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, @@ -1505,6 +1625,12 @@ static inline void update_dma_sr_stats( * @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) { @@ -1570,6 +1696,12 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *const osi_core) * @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(void *addr) { @@ -1593,6 +1725,12 @@ static void eqos_start_mac(void *addr) * @param[in] addr: EQOS virtual base address. * * @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(void *addr) { @@ -1621,6 +1759,12 @@ static void eqos_stop_mac(void *addr) * * @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 int eqos_config_l2_da_perfect_inverse_match(void *base, @@ -1654,6 +1798,12 @@ static inline int eqos_config_l2_da_perfect_inverse_match(void *base, * * @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 int eqos_config_mac_pkt_filter_reg( @@ -1735,6 +1885,12 @@ static int eqos_config_mac_pkt_filter_reg( * - 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. */ @@ -1802,6 +1958,12 @@ err_dma_chan: * - 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. */ @@ -1881,6 +2043,12 @@ static int eqos_update_mac_addr_low_high_reg( * * @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. */ @@ -1913,6 +2081,12 @@ static int eqos_config_l3_l4_filter_enable(void *base, * * @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. */ @@ -1970,6 +2144,12 @@ static int eqos_update_ip4_addr(struct osi_core_priv_data *const osi_core, * * @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. */ @@ -2040,6 +2220,12 @@ static int eqos_update_ip6_addr(struct osi_core_priv_data *const osi_core, * - 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. */ @@ -2093,6 +2279,12 @@ static int eqos_update_l4_port_no( * - 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 unsigned int value */ static inline unsigned int eqos_set_dcs( @@ -2123,10 +2315,16 @@ static inline unsigned int eqos_set_dcs( * Algorithm: * - set bit corresponding to L3l4 filter index * - * @param[in] bitmask: bit mask OSI core private data structure. + * @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() * */ @@ -2172,6 +2370,12 @@ static inline void eqos_helper_l3l4_bitmask(unsigned int *bitmask, * - 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. */ @@ -2348,6 +2552,12 @@ static int eqos_config_l3_filters( * - 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. */ @@ -2454,10 +2664,17 @@ static int eqos_config_l4_filters( * equal to zero. * * @param[in] osi_core: OSI core private data structure. - * @param[in] mac_tcr: Address to store time stamp control register read value + * @param[inout] 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. */ @@ -2506,6 +2723,12 @@ static inline int eqos_poll_for_tsinit_complete( * * @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. */ @@ -2552,10 +2775,17 @@ static int eqos_set_systime_to_mac(struct osi_core_priv_data *const osi_core, * equal to zero. * * @param[in] osi_core: OSI core private data structure. - * @param[in] mac_tcr: Address to store time stamp control register read value + * @param[inout] 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. */ @@ -2601,6 +2831,12 @@ static inline int eqos_poll_for_addend_complete( * * @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. */ @@ -2642,10 +2878,17 @@ static int eqos_config_addend(struct osi_core_priv_data *const osi_core, * equal to zero. * * @param[in] osi_core: OSI core private data structure. - * @param[in] mac_tcr: Address to store time stamp control register read value + * @param[inout] 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. */ @@ -2696,6 +2939,12 @@ static inline int eqos_poll_for_update_ts_complete( * - 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. */ @@ -2777,6 +3026,12 @@ static int eqos_adjust_mactime(struct osi_core_priv_data *const osi_core, * @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(void *addr, const unsigned int ptp_filter) { @@ -2849,6 +3104,12 @@ static void eqos_config_tscr(void *addr, const unsigned int ptp_filter) * @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_config_ssir(struct osi_core_priv_data *const osi_core) { @@ -2900,6 +3161,12 @@ static void eqos_config_ssir(struct osi_core_priv_data *const osi_core) * @param[in] osi_core: OSI core private data structure. * * @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) { @@ -2914,6 +3181,12 @@ static void eqos_core_deinit(struct osi_core_priv_data *const osi_core) * * @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 */ @@ -2970,6 +3243,12 @@ static inline int poll_for_mii_idle(struct osi_core_priv_data *osi_core) * * @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. */ @@ -3045,6 +3324,12 @@ static int eqos_write_phy_reg(struct osi_core_priv_data *const osi_core, * * @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 */ @@ -3107,6 +3392,12 @@ static int eqos_read_phy_reg(struct osi_core_priv_data *const osi_core, * @param[in] addr: base address of memory mapped register space of MAC. * * @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(void *addr) { @@ -3136,6 +3427,12 @@ static inline void eqos_disable_tx_lpi(void *addr) * 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. */ @@ -3186,6 +3483,12 @@ static int eqos_validate_core_regs(struct osi_core_priv_data *const osi_core) * * @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. */ @@ -3237,6 +3540,12 @@ static int eqos_config_rx_crc_check(struct osi_core_priv_data *const osi_core, * * @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. */ @@ -3300,6 +3609,12 @@ static int eqos_config_tx_status(struct osi_core_priv_data *const osi_core, * - 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. */ @@ -3416,6 +3731,12 @@ static int eqos_set_avb_algorithm( * - 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. */ @@ -3502,6 +3823,12 @@ static int eqos_get_avb_algorithm(struct osi_core_priv_data *const osi_core, * - 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. */ @@ -3569,6 +3896,12 @@ static int eqos_config_arp_offload(const unsigned int mac_ver, * - 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. */ @@ -3626,6 +3959,12 @@ static int eqos_config_vlan_filtering( * @param[in] base: Base address from OSI core private data structure. * @param[in] vid: VLAN ID to be programmed. * + * @note + * API Group: + * - Initialization: No + * - Run time: Yes + * - De-initialization: No + * * @retval 0 always */ static inline int eqos_update_vlan_id(void *base, unsigned int vid) @@ -3657,6 +3996,12 @@ static inline int eqos_update_vlan_id(void *base, unsigned int vid) * @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, @@ -3728,6 +4073,12 @@ static void eqos_configure_eee( * * @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 int eqos_save_registers( @@ -3755,6 +4106,12 @@ static inline int 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 int eqos_restore_registers( @@ -3785,6 +4142,12 @@ static inline int eqos_restore_registers( * * @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 unsigned long csr_clk_rate) @@ -3826,6 +4189,12 @@ static void eqos_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, * * @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. */ @@ -3924,6 +4293,12 @@ static struct osi_core_ops eqos_core_ops = { /** * @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) { @@ -3932,6 +4307,12 @@ void *eqos_get_core_safety_config(void) /** * @brief eqos_get_hw_core_ops - EQOS MAC get core operations + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: No + * - De-initialization: No */ struct osi_core_ops *eqos_get_hw_core_ops(void) { diff --git a/osi/core/eqos_mmc.c b/osi/core/eqos_mmc.c index 3c766ec..6e0ab4d 100644 --- a/osi/core/eqos_mmc.c +++ b/osi/core/eqos_mmc.c @@ -42,6 +42,12 @@ * - 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 */ @@ -76,6 +82,12 @@ static inline unsigned long update_mmc_val(struct osi_core_priv_data *osi_core, * @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 *osi_core) { @@ -102,6 +114,12 @@ void eqos_reset_mmc(struct osi_core_priv_data *osi_core) * @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 *osi_core) { diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index fcd5024..49532ce 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -269,6 +269,12 @@ int osi_l2_filter(struct osi_core_priv_data *const osi_core, * * @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 */ @@ -322,6 +328,12 @@ static inline int helper_l4_filter( * * @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 */ @@ -474,6 +486,12 @@ int osi_set_systime_to_mac(struct osi_core_priv_data *const osi_core, * @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 unsigned long div_u64_rem(unsigned long dividend, @@ -500,6 +518,12 @@ static inline unsigned long div_u64_rem(unsigned long dividend, * @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 unsigned long div_u64(unsigned long dividend, diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index cf31b20..febb711 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -46,6 +46,12 @@ static struct dma_func_safety eqos_dma_safety_config; * @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(unsigned int val, void *addr, unsigned int idx) @@ -71,6 +77,12 @@ static inline void eqos_dma_safety_writel(unsigned int val, void *addr, * 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) { @@ -140,6 +152,12 @@ static void eqos_dma_safety_init(struct osi_dma_priv_data *osi_dma) * - 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, unsigned int chan) { @@ -179,6 +197,12 @@ static void eqos_disable_chan_tx_intr(void *addr, unsigned int chan) * - 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, unsigned int chan) { @@ -205,6 +229,12 @@ static void eqos_enable_chan_tx_intr(void *addr, unsigned int chan) * - 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, unsigned int chan) { @@ -242,6 +272,12 @@ static void eqos_disable_chan_rx_intr(void *addr, unsigned int chan) * @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, unsigned int chan) { @@ -267,6 +303,12 @@ static void eqos_enable_chan_rx_intr(void *addr, unsigned int chan) * memory mapped IO region of the MAC. * @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(void *addr, unsigned int chan, unsigned int len) @@ -288,6 +330,12 @@ static void eqos_set_tx_ring_len(void *addr, unsigned int chan, * 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, unsigned int chan, unsigned long tx_desc) @@ -325,6 +373,12 @@ static void eqos_set_tx_ring_start_addr(void *addr, unsigned int chan, * @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, unsigned int chan, unsigned long tailptr) @@ -351,6 +405,12 @@ static void eqos_update_tx_tailptr(void *addr, unsigned int chan, * memory mapped IO region of the MAC. * @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(void *addr, unsigned int chan, unsigned int len) @@ -372,6 +432,12 @@ static void eqos_set_rx_ring_len(void *addr, unsigned int chan, * 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, unsigned int chan, unsigned long rx_desc) @@ -408,6 +474,12 @@ static void eqos_set_rx_ring_start_addr(void *addr, unsigned int chan, * @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, unsigned int chan, unsigned long tailptr) @@ -437,6 +509,12 @@ static void eqos_update_rx_tailptr(void *addr, unsigned int chan, * @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(void *addr, unsigned int chan) { @@ -473,6 +551,12 @@ static void eqos_start_dma(void *addr, unsigned int chan) * @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(void *addr, unsigned int chan) { @@ -512,6 +596,12 @@ static void eqos_stop_dma(void *addr, unsigned int chan) * @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(unsigned int chan, struct osi_dma_priv_data *osi_dma) @@ -648,6 +738,12 @@ static void eqos_dma_chan_to_vmirq_map(struct osi_dma_priv_data *osi_dma) * * @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. */ @@ -682,6 +778,12 @@ static int eqos_init_dma_channel(struct osi_dma_priv_data *osi_dma) * - 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) { @@ -719,6 +821,12 @@ static void eqos_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) * 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. */ @@ -767,9 +875,15 @@ static int eqos_validate_dma_regs(struct osi_dma_priv_data *osi_dma) * @param[in] interval: slot interval from 0usec to 4095usec * * @pre - & - MAC should be init and started. see osi_start_mac() + * - 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 + * * @retval none */ static void eqos_config_slot(struct osi_dma_priv_data *osi_dma, diff --git a/osi/dma/eqos_dma.h b/osi/dma/eqos_dma.h index 40a36f3..96b7755 100644 --- a/osi/dma/eqos_dma.h +++ b/osi/dma/eqos_dma.h @@ -162,6 +162,12 @@ struct dma_func_safety { /** * @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); @@ -169,6 +175,12 @@ void *eqos_get_dma_safety_config(void); /** * @brief eqos_get_dma_chan_ops - EQOS get DMA channel operations * + * @note + * API Group: + * - Initialization: Yes + * - Run time: No + * - De-initialization: No + * * @returns Pointer to DMA channel operations structure */ struct osi_dma_chan_ops *eqos_get_dma_chan_ops(void); diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 5414ae7..131b188 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -269,6 +269,12 @@ unsigned int osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring) * @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. */ @@ -309,6 +315,12 @@ static inline int rx_dma_desc_validate_args(struct osi_dma_priv_data *osi_dma, * @param[in] rx_ring: HW ring corresponding to Rx DMA channel. * @param[in] 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, @@ -452,6 +464,12 @@ unsigned int osi_is_mac_enabled(struct osi_dma_priv_data *const osi_dma) * * @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. */ diff --git a/osi/dma/osi_dma_local.h b/osi/dma/osi_dma_local.h index 531612e..77a5005 100644 --- a/osi/dma/osi_dma_local.h +++ b/osi/dma/osi_dma_local.h @@ -39,6 +39,12 @@ * * @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. */ diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index d9eda28..f6b2347 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -36,6 +36,12 @@ * 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] rx_desc: Rx descriptor * @param[in] rx_pkt_cx: Per-Rx packet context structure */ @@ -100,6 +106,12 @@ static inline void get_rx_csum(struct osi_rx_desc *rx_desc, * tagged. * - Extract VLAN tag ID from the descriptor * + * @note + * API Group: + * - Initialization: No + * - Run time: Yes + * - De-initialization: No + * * @param[in] rx_desc: Rx descriptor * @param[in] rx_pkt_cx: Per-Rx packet context structure */ @@ -129,6 +141,12 @@ static inline void get_rx_vlan_from_desc(struct osi_rx_desc *rx_desc, * * @param[in] context_desc: Rx context descriptor * + * @note + * API Group: + * - Initialization: No + * - Run time: Yes + * - De-initialization: No + * * @retval -1 if TimeStamp is not valid * @retval 0 if TimeStamp is valid. */ @@ -163,6 +181,12 @@ static inline int get_rx_tstamp_status(struct osi_rx_desc *context_desc) * @param[in] context_desc: Rx context descriptor * @param[in] rx_pkt_cx: Rx packet context * + * @note + * API Group: + * - Initialization: No + * - Run time: Yes + * - De-initialization: No + * * @retval -1 if TimeStamp is not available * @retval 0 if TimeStamp is available. */ @@ -217,6 +241,12 @@ static int get_rx_hwstamp(struct osi_dma_priv_data *osi_dma, * 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] pkt_err_stats: Packet error stats which stores the errors reported */ @@ -254,6 +284,12 @@ static inline void get_rx_err_stats(struct osi_rx_desc *rx_desc, * @param[in] rx_ring: OSI DMA channel Rx ring * @param[in] 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. */ @@ -453,6 +489,12 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, * - 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] osi_dma: Pointer to OSI DMA private data structure. * @param[in] chan: DMA channel number for which stats should be incremented. */ @@ -474,6 +516,12 @@ static inline void inc_tx_pkt_stats(struct osi_dma_priv_data *osi_dma, * 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] pkt_err_stats: Packet error stats which stores the errors reported */ @@ -619,6 +667,12 @@ int osi_clear_rx_pkt_err_stats(struct osi_dma_priv_data *osi_dma) * @param[in] chan: Tx DMA channel number * @param[in] 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. */ @@ -769,6 +823,12 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, * @param[in] tx_pkt_cx: Pointer to transmit packet context structure * @param[in] tx_desc: Pointer to transmit descriptor to be filled. * + * @note + * API Group: + * - Initialization: No + * - Run time: Yes + * - De-initialization: No + * * @retval 0 - cntx desc not used * @retval 1 - cntx desc used. */ @@ -817,6 +877,12 @@ static inline int need_cntx_desc(struct osi_tx_pkt_cx *tx_pkt_cx, * 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] tx_ring: DMA channel TX ring. * @param[in] tx_pkt_cx: Pointer to transmit packet context structure * @param[in] tx_desc: Pointer to transmit descriptor to be filled. @@ -907,6 +973,12 @@ static inline void fill_first_desc(struct osi_tx_ring *tx_ring, /** * @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) { @@ -925,6 +997,12 @@ static inline void dmb_oshst(void) * @param[in] ops: OSI DMA Channel operations * @param[in] tx_ring: OSI DMA channel Tx ring * + * @note + * API Group: + * - Initialization: No + * - Run time: Yes + * - De-initialization: No + * * @retval 0 on success * @retval -1 on failure. */ @@ -1120,6 +1198,12 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi_dma, unsigned int chan) * @param[in] osi_dma: OSI private data structure. * @param[in] chan: Rx channel number. * + * @note + * API Group: + * - Initialization: Yes + * - Run time: No + * - De-initialization: No + * * @retval 0 on success * @retval -1 on failure. */ @@ -1223,6 +1307,12 @@ static int rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, * * @param[in] osi_dma: OSI private data structure. * + * @note + * API Group: + * - Initialization: Yes + * - Run time: No + * - De-initialization: No + * * @retval 0 on success * @retval -1 on failure. */ @@ -1254,6 +1344,12 @@ static int rx_dma_desc_init(struct osi_dma_priv_data *osi_dma) * * @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. */ From 5650ee6ab6d83c8ef01be014fa01e2be1aba71a3 Mon Sep 17 00:00:00 2001 From: rakesh goyal <rgoyal@nvidia.com> Date: Wed, 2 Dec 2020 13:02:50 +0530 Subject: [PATCH 130/458] nvethernetrm: fix for Misra-C 4.6 - Fix Misra-C Rule 4.6 Bug 200682334 Change-Id: I56b1effa4e1a2f0707a26d11358de60d9d12e4f9 Signed-off-by: rakesh goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2453789 Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2457303 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/mmc.h | 336 +++++------ include/osd.h | 28 +- include/osi_common.h | 163 ++--- include/osi_core.h | 451 +++++++------- include/osi_dma.h | 286 +++++---- include/osi_dma_txrx.h | 4 +- osi/common/eqos_common.c | 28 +- osi/common/eqos_common.h | 4 +- osi/common/include/local_common.h | 7 +- osi/common/osd_dummy.c | 28 +- osi/common/osi_common.c | 53 +- osi/common/type.h | 47 ++ osi/core/eqos_core.c | 965 +++++++++++++++--------------- osi/core/eqos_core.h | 30 +- osi/core/eqos_mmc.c | 18 +- osi/core/osi_core.c | 231 ++++--- osi/dma/eqos_dma.c | 205 +++---- osi/dma/eqos_dma.h | 6 +- osi/dma/osi_dma.c | 92 +-- osi/dma/osi_dma_local.h | 2 +- osi/dma/osi_dma_txrx.c | 130 ++-- 21 files changed, 1589 insertions(+), 1525 deletions(-) create mode 100644 osi/common/type.h diff --git a/include/mmc.h b/include/mmc.h index 60921f3..ea33aad 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -28,502 +28,502 @@ struct osi_mmc_counters { /** This counter provides the number of bytes transmitted, exclusive of * preamble and retried bytes, in good and bad packets */ - unsigned long mmc_tx_octetcount_gb; + nveu64_t mmc_tx_octetcount_gb; /** This counter provides upper 32 bits of transmitted octet count */ - unsigned long mmc_tx_octetcount_gb_h; + nveu64_t mmc_tx_octetcount_gb_h; /** This counter provides the number of good and * bad packets transmitted, exclusive of retried packets */ - unsigned long mmc_tx_framecount_gb; + nveu64_t mmc_tx_framecount_gb; /** This counter provides upper 32 bits of transmitted good and bad * packets count */ - unsigned long mmc_tx_framecount_gb_h; + nveu64_t mmc_tx_framecount_gb_h; /** This counter provides number of good broadcast * packets transmitted */ - unsigned long mmc_tx_broadcastframe_g; + nveu64_t mmc_tx_broadcastframe_g; /** This counter provides upper 32 bits of transmitted good broadcast * packets count */ - unsigned long mmc_tx_broadcastframe_g_h; + nveu64_t mmc_tx_broadcastframe_g_h; /** This counter provides number of good multicast * packets transmitted */ - unsigned long mmc_tx_multicastframe_g; + nveu64_t mmc_tx_multicastframe_g; /** This counter provides upper 32 bits of transmitted good multicast * packet count */ - unsigned long mmc_tx_multicastframe_g_h; + 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 */ - unsigned long mmc_tx_64_octets_gb; + nveu64_t mmc_tx_64_octets_gb; /** This counter provides upper 32 bits of transmitted 64 octet size * good and bad packets count */ - unsigned long mmc_tx_64_octets_gb_h; + 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 */ - unsigned long mmc_tx_65_to_127_octets_gb; + 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 */ - unsigned long mmc_tx_65_to_127_octets_gb_h; + 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 */ - unsigned long mmc_tx_128_to_255_octets_gb; + 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 */ - unsigned long mmc_tx_128_to_255_octets_gb_h; + 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 */ - unsigned long mmc_tx_256_to_511_octets_gb; + 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. */ - unsigned long mmc_tx_256_to_511_octets_gb_h; + 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 */ - unsigned long mmc_tx_512_to_1023_octets_gb; + 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.*/ - unsigned long mmc_tx_512_to_1023_octets_gb_h; + 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 */ - unsigned long mmc_tx_1024_to_max_octets_gb; + 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. */ - unsigned long mmc_tx_1024_to_max_octets_gb_h; + nveu64_t mmc_tx_1024_to_max_octets_gb_h; /** This counter provides the number of good and bad unicast packets */ - unsigned long mmc_tx_unicast_gb; + nveu64_t mmc_tx_unicast_gb; /** This counter provides upper 32 bits of transmitted good bad * unicast packets count */ - unsigned long mmc_tx_unicast_gb_h; + nveu64_t mmc_tx_unicast_gb_h; /** This counter provides the number of good and bad * multicast packets */ - unsigned long mmc_tx_multicast_gb; + nveu64_t mmc_tx_multicast_gb; /** This counter provides upper 32 bits of transmitted good bad * multicast packets count */ - unsigned long mmc_tx_multicast_gb_h; + nveu64_t mmc_tx_multicast_gb_h; /** This counter provides the number of good and bad * broadcast packets */ - unsigned long mmc_tx_broadcast_gb; + nveu64_t mmc_tx_broadcast_gb; /** This counter provides upper 32 bits of transmitted good bad * broadcast packets count */ - unsigned long mmc_tx_broadcast_gb_h; + nveu64_t mmc_tx_broadcast_gb_h; /** This counter provides the number of abort packets due to * underflow error */ - unsigned long mmc_tx_underflow_error; + nveu64_t mmc_tx_underflow_error; /** This counter provides upper 32 bits of abort packets due to * underflow error */ - unsigned long mmc_tx_underflow_error_h; + 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 */ - unsigned long mmc_tx_singlecol_g; + nveu64_t mmc_tx_singlecol_g; /** This counter provides the number of successfully transmitted * packets after a multi collision in the half-duplex mode */ - unsigned long mmc_tx_multicol_g; + nveu64_t mmc_tx_multicol_g; /** This counter provides the number of successfully transmitted * after a deferral in the half-duplex mode */ - unsigned long mmc_tx_deferred; + nveu64_t mmc_tx_deferred; /** This counter provides the number of packets aborted because of * late collision error */ - unsigned long mmc_tx_latecol; + nveu64_t mmc_tx_latecol; /** This counter provides the number of packets aborted because of * excessive (16) collision errors */ - unsigned long mmc_tx_exesscol; + nveu64_t mmc_tx_exesscol; /** This counter provides the number of packets aborted because of * carrier sense error (no carrier or loss of carrier) */ - unsigned long mmc_tx_carrier_error; + nveu64_t mmc_tx_carrier_error; /** This counter provides the number of bytes transmitted, * exclusive of preamble, only in good packets */ - unsigned long mmc_tx_octetcount_g; + nveu64_t mmc_tx_octetcount_g; /** This counter provides upper 32 bytes of bytes transmitted, * exclusive of preamble, only in good packets */ - unsigned long mmc_tx_octetcount_g_h; + nveu64_t mmc_tx_octetcount_g_h; /** This counter provides the number of good packets transmitted */ - unsigned long mmc_tx_framecount_g; + nveu64_t mmc_tx_framecount_g; /** This counter provides upper 32 bytes of good packets transmitted */ - unsigned long mmc_tx_framecount_g_h; + 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) */ - unsigned long mmc_tx_excessdef; + nveu64_t mmc_tx_excessdef; /** This counter provides the number of good Pause * packets transmitted */ - unsigned long mmc_tx_pause_frame; + nveu64_t mmc_tx_pause_frame; /** This counter provides upper 32 bytes of good Pause * packets transmitted */ - unsigned long mmc_tx_pause_frame_h; + nveu64_t mmc_tx_pause_frame_h; /** This counter provides the number of good VLAN packets transmitted */ - unsigned long mmc_tx_vlan_frame_g; + nveu64_t mmc_tx_vlan_frame_g; /** This counter provides upper 32 bytes of good VLAN packets * transmitted */ - unsigned long mmc_tx_vlan_frame_g_h; + 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 */ - unsigned long mmc_tx_osize_frame_g; + nveu64_t mmc_tx_osize_frame_g; /** This counter provides the number of good and bad packets received */ - unsigned long mmc_rx_framecount_gb; + nveu64_t mmc_rx_framecount_gb; /** This counter provides upper 32 bytes of good and bad packets * received */ - unsigned long mmc_rx_framecount_gb_h; + 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 */ - unsigned long mmc_rx_octetcount_gb; + 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 */ - unsigned long mmc_rx_octetcount_gb_h; + 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 */ - unsigned long mmc_rx_octetcount_g; + 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 */ - unsigned long mmc_rx_octetcount_g_h; + nveu64_t mmc_rx_octetcount_g_h; /** This counter provides the number of good * broadcast packets received */ - unsigned long mmc_rx_broadcastframe_g; + nveu64_t mmc_rx_broadcastframe_g; /** This counter provides upper 32 bytes of good * broadcast packets received */ - unsigned long mmc_rx_broadcastframe_g_h; + nveu64_t mmc_rx_broadcastframe_g_h; /** This counter provides the number of good * multicast packets received */ - unsigned long mmc_rx_multicastframe_g; + nveu64_t mmc_rx_multicastframe_g; /** This counter provides upper 32 bytes of good * multicast packets received */ - unsigned long mmc_rx_multicastframe_g_h; + nveu64_t mmc_rx_multicastframe_g_h; /** This counter provides the number of packets * received with CRC error */ - unsigned long mmc_rx_crc_error; + nveu64_t mmc_rx_crc_error; /** This counter provides upper 32 bytes of packets * received with CRC error */ - unsigned long mmc_rx_crc_error_h; + 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 */ - unsigned long mmc_rx_align_error; + 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 */ - unsigned long mmc_rx_runt_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 */ - unsigned long mmc_rx_jabber_error; + nveu64_t mmc_rx_jabber_error; /** This counter provides the number of packets received with length * less than 64 bytes, without any errors */ - unsigned long mmc_rx_undersize_g; + nveu64_t mmc_rx_undersize_g; /** This counter provides the number of packets received without error, * with length greater than the maxsize */ - unsigned long mmc_rx_oversize_g; + 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 */ - unsigned long mmc_rx_64_octets_gb; + 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 */ - unsigned long mmc_rx_64_octets_gb_h; + 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 */ - unsigned long mmc_rx_65_to_127_octets_gb; + 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 */ - unsigned long mmc_rx_65_to_127_octets_gb_h; + 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 */ - unsigned long mmc_rx_128_to_255_octets_gb; + 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 */ - unsigned long mmc_rx_128_to_255_octets_gb_h; + 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 */ - unsigned long mmc_rx_256_to_511_octets_gb; + 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 */ - unsigned long mmc_rx_256_to_511_octets_gb_h; + 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 */ - unsigned long mmc_rx_512_to_1023_octets_gb; + 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 */ - unsigned long mmc_rx_512_to_1023_octets_gb_h; + 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 */ - unsigned long mmc_rx_1024_to_max_octets_gb; + 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 */ - unsigned long mmc_rx_1024_to_max_octets_gb_h; + nveu64_t mmc_rx_1024_to_max_octets_gb_h; /** This counter provides the number of good unicast packets received */ - unsigned long mmc_rx_unicast_g; + nveu64_t mmc_rx_unicast_g; /** This counter provides upper 32 bytes of good unicast packets * received */ - unsigned long mmc_rx_unicast_g_h; + 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 */ - unsigned long mmc_rx_length_error; + 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 */ - unsigned long mmc_rx_length_error_h; + 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) */ - unsigned long mmc_rx_outofrangetype; + 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) */ - unsigned long mmc_rx_outofrangetype_h; + nveu64_t mmc_rx_outofrangetype_h; /** This counter provides the number of good and valid Pause packets * received */ - unsigned long mmc_rx_pause_frames; + nveu64_t mmc_rx_pause_frames; /** This counter provides upper 32 bytes of good and valid Pause packets * received */ - unsigned long mmc_rx_pause_frames_h; + nveu64_t mmc_rx_pause_frames_h; /** This counter provides the number of missed received packets * because of FIFO overflow in DWC_ether_qos */ - unsigned long mmc_rx_fifo_overflow; + nveu64_t mmc_rx_fifo_overflow; /** This counter provides upper 32 bytes of missed received packets * because of FIFO overflow in DWC_ether_qos */ - unsigned long mmc_rx_fifo_overflow_h; + nveu64_t mmc_rx_fifo_overflow_h; /** This counter provides the number of good and bad VLAN packets * received */ - unsigned long mmc_rx_vlan_frames_gb; + nveu64_t mmc_rx_vlan_frames_gb; /** This counter provides upper 32 bytes of good and bad VLAN packets * received */ - unsigned long mmc_rx_vlan_frames_gb_h; + nveu64_t mmc_rx_vlan_frames_gb_h; /** This counter provides the number of packets received with error * because of watchdog timeout error */ - unsigned long mmc_rx_watchdog_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 */ - unsigned long mmc_rx_receive_error; + 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 */ - unsigned long mmc_rx_ctrl_frames_g; + nveu64_t mmc_rx_ctrl_frames_g; /** This counter provides the number of microseconds Tx LPI is asserted * in the MAC controller */ - unsigned long mmc_tx_lpi_usec_cntr; + nveu64_t mmc_tx_lpi_usec_cntr; /** This counter provides the number of times MAC controller has * entered Tx LPI. */ - unsigned long mmc_tx_lpi_tran_cntr; + nveu64_t mmc_tx_lpi_tran_cntr; /** This counter provides the number of microseconds Rx LPI is asserted * in the MAC controller */ - unsigned long mmc_rx_lpi_usec_cntr; + nveu64_t mmc_rx_lpi_usec_cntr; /** This counter provides the number of times MAC controller has * entered Rx LPI.*/ - unsigned long mmc_rx_lpi_tran_cntr; + nveu64_t mmc_rx_lpi_tran_cntr; /** This counter provides the number of good IPv4 datagrams received * with the TCP, UDP, or ICMP payload */ - unsigned long mmc_rx_ipv4_gd; + nveu64_t mmc_rx_ipv4_gd; /** This counter provides upper 32 bytes of good IPv4 datagrams received * with the TCP, UDP, or ICMP payload */ - unsigned long mmc_rx_ipv4_gd_h; + nveu64_t mmc_rx_ipv4_gd_h; /** RxIPv4 Header Error Packets */ - unsigned long mmc_rx_ipv4_hderr; + nveu64_t mmc_rx_ipv4_hderr; /** RxIPv4 of upper 32 bytes of Header Error Packets */ - unsigned long mmc_rx_ipv4_hderr_h; + 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 */ - unsigned long mmc_rx_ipv4_nopay; + 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 */ - unsigned long mmc_rx_ipv4_nopay_h; + nveu64_t mmc_rx_ipv4_nopay_h; /** This counter provides the number of good IPv4 datagrams received * with fragmentation */ - unsigned long mmc_rx_ipv4_frag; + nveu64_t mmc_rx_ipv4_frag; /** This counter provides upper 32 bytes of good IPv4 datagrams received * with fragmentation */ - unsigned long mmc_rx_ipv4_frag_h; + 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 */ - unsigned long mmc_rx_ipv4_udsbl; + 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 */ - unsigned long mmc_rx_ipv4_udsbl_h; + nveu64_t mmc_rx_ipv4_udsbl_h; /** This counter provides the number of good IPv6 datagrams received * with the TCP, UDP, or ICMP payload */ - unsigned long mmc_rx_ipv6_gd_octets; + 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 */ - unsigned long mmc_rx_ipv6_gd_octets_h; + nveu64_t mmc_rx_ipv6_gd_octets_h; /** This counter provides the number of IPv6 datagrams received * with header (length or version mismatch) errors */ - unsigned long mmc_rx_ipv6_hderr_octets; + nveu64_t mmc_rx_ipv6_hderr_octets; /** This counter provides the number of IPv6 datagrams received * with header (length or version mismatch) errors */ - unsigned long mmc_rx_ipv6_hderr_octets_h; + 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 */ - unsigned long mmc_rx_ipv6_nopay_octets; + 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 */ - unsigned long mmc_rx_ipv6_nopay_octets_h; + 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 */ - unsigned long mmc_rx_udp_gd; + 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 */ - unsigned long mmc_rx_udp_gd_h; + 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 */ - unsigned long mmc_rx_udp_err; + 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 */ - unsigned long mmc_rx_udp_err_h; + nveu64_t mmc_rx_udp_err_h; /** This counter provides the number of good IP datagrams received * with a good TCP payload */ - unsigned long mmc_rx_tcp_gd; + nveu64_t mmc_rx_tcp_gd; /** This counter provides the number of good IP datagrams received * with a good TCP payload */ - unsigned long mmc_rx_tcp_gd_h; + nveu64_t mmc_rx_tcp_gd_h; /** This counter provides upper 32 bytes of good IP datagrams received * with a good TCP payload */ - unsigned long mmc_rx_tcp_err; + nveu64_t mmc_rx_tcp_err; /** This counter provides upper 32 bytes of good IP datagrams received * with a good TCP payload */ - unsigned long mmc_rx_tcp_err_h; + nveu64_t mmc_rx_tcp_err_h; /** This counter provides the number of good IP datagrams received * with a good ICMP payload */ - unsigned long mmc_rx_icmp_gd; + nveu64_t mmc_rx_icmp_gd; /** This counter provides upper 32 bytes of good IP datagrams received * with a good ICMP payload */ - unsigned long mmc_rx_icmp_gd_h; + nveu64_t mmc_rx_icmp_gd_h; /** This counter provides the number of good IP datagrams received * whose ICMP payload has a checksum error */ - unsigned long mmc_rx_icmp_err; + nveu64_t mmc_rx_icmp_err; /** This counter provides upper 32 bytes of good IP datagrams received * whose ICMP payload has a checksum error */ - unsigned long mmc_rx_icmp_err_h; + 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 */ - unsigned long mmc_rx_ipv4_gd_octets; + 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 */ - unsigned long mmc_rx_ipv4_gd_octets_h; + 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 */ - unsigned long mmc_rx_ipv4_hderr_octets; + 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 */ - unsigned long mmc_rx_ipv4_hderr_octets_h; + 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 */ - unsigned long mmc_rx_ipv4_nopay_octets; + 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 */ - unsigned long mmc_rx_ipv4_nopay_octets_h; + 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 */ - unsigned long mmc_rx_ipv4_frag_octets; + 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 */ - unsigned long mmc_rx_ipv4_frag_octets_h; + 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 */ - unsigned long mmc_rx_ipv4_udsbl_octets; + 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 */ - unsigned long mmc_rx_ipv4_udsbl_octets_h; + 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 */ - unsigned long mmc_rx_ipv6_gd; + 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 */ - unsigned long mmc_rx_ipv6_gd_h; + 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 */ - unsigned long mmc_rx_ipv6_hderr; + 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 */ - unsigned long mmc_rx_ipv6_hderr_h; + 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 */ - unsigned long mmc_rx_ipv6_nopay; + 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 */ - unsigned long mmc_rx_ipv6_nopay_h; + 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 */ - unsigned long mmc_rx_udp_gd_octets; + 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 */ - unsigned long mmc_rx_udp_gd_octets_h; + 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 */ - unsigned long mmc_rx_udp_err_octets; + 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 */ - unsigned long mmc_rx_udp_err_octets_h; + 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 */ - unsigned long mmc_rx_tcp_gd_octets; + 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 */ - unsigned long mmc_rx_tcp_gd_octets_h; + 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 */ - unsigned long mmc_rx_tcp_err_octets; + 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 */ - unsigned long mmc_rx_tcp_err_octets_h; + 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 */ - unsigned long mmc_rx_icmp_gd_octets; + 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 */ - unsigned long mmc_rx_icmp_gd_octets_h; + 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 */ - unsigned long mmc_rx_icmp_err_octets; + 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 */ - unsigned long mmc_rx_icmp_err_octets_h; + nveu64_t mmc_rx_icmp_err_octets_h; }; /** @@ -531,29 +531,29 @@ struct osi_mmc_counters { */ struct osi_xtra_stat_counters { /** RX buffer unavailable irq count */ - unsigned long rx_buf_unavail_irq_n[OSI_EQOS_MAX_NUM_QUEUES]; + nveu64_t rx_buf_unavail_irq_n[OSI_EQOS_MAX_NUM_QUEUES]; /** Transmit Process Stopped irq count */ - unsigned long tx_proc_stopped_irq_n[OSI_EQOS_MAX_NUM_QUEUES]; + nveu64_t tx_proc_stopped_irq_n[OSI_EQOS_MAX_NUM_QUEUES]; /** Transmit Buffer Unavailable irq count */ - unsigned long tx_buf_unavail_irq_n[OSI_EQOS_MAX_NUM_QUEUES]; + nveu64_t tx_buf_unavail_irq_n[OSI_EQOS_MAX_NUM_QUEUES]; /** Receive Process Stopped irq count */ - unsigned long rx_proc_stopped_irq_n[OSI_EQOS_MAX_NUM_QUEUES]; + nveu64_t rx_proc_stopped_irq_n[OSI_EQOS_MAX_NUM_QUEUES]; /** Receive Watchdog Timeout irq count */ - unsigned long rx_watchdog_irq_n; + nveu64_t rx_watchdog_irq_n; /** Fatal Bus Error irq count */ - unsigned long fatal_bus_error_irq_n; + nveu64_t fatal_bus_error_irq_n; /** rx skb allocation failure count */ - unsigned long re_alloc_rxbuf_failed[OSI_EQOS_MAX_NUM_QUEUES]; + nveu64_t re_alloc_rxbuf_failed[OSI_EQOS_MAX_NUM_QUEUES]; /** TX per channel interrupt count */ - unsigned long tx_normal_irq_n[OSI_EQOS_MAX_NUM_QUEUES]; + nveu64_t tx_normal_irq_n[OSI_EQOS_MAX_NUM_QUEUES]; /** TX per channel SW timer callback count */ - unsigned long tx_usecs_swtimer_n[OSI_EQOS_MAX_NUM_QUEUES]; + nveu64_t tx_usecs_swtimer_n[OSI_EQOS_MAX_NUM_QUEUES]; /** RX per channel interrupt count */ - unsigned long rx_normal_irq_n[OSI_EQOS_MAX_NUM_QUEUES]; + nveu64_t rx_normal_irq_n[OSI_EQOS_MAX_NUM_QUEUES]; /** link connect count */ - unsigned long link_connect_count; + nveu64_t link_connect_count; /** link disconnect count */ - unsigned long link_disconnect_count; + nveu64_t link_disconnect_count; }; /** @@ -561,21 +561,21 @@ struct osi_xtra_stat_counters { */ struct osi_xtra_dma_stat_counters { /** Per Q TX packet count */ - unsigned long q_tx_pkt_n[OSI_EQOS_MAX_NUM_QUEUES]; + nveu64_t q_tx_pkt_n[OSI_EQOS_MAX_NUM_QUEUES]; /** Per Q RX packet count */ - unsigned long q_rx_pkt_n[OSI_EQOS_MAX_NUM_QUEUES]; + nveu64_t q_rx_pkt_n[OSI_EQOS_MAX_NUM_QUEUES]; /** Per Q TX complete call count */ - unsigned long tx_clean_n[OSI_EQOS_MAX_NUM_QUEUES]; + nveu64_t tx_clean_n[OSI_EQOS_MAX_NUM_QUEUES]; /** Total number of tx packets count */ - unsigned long tx_pkt_n; + nveu64_t tx_pkt_n; /** Total number of rx packet count */ - unsigned long rx_pkt_n; + nveu64_t rx_pkt_n; /** Total number of VLAN RX packet count */ - unsigned long rx_vlan_pkt_n; + nveu64_t rx_vlan_pkt_n; /** Total number of VLAN TX packet count */ - unsigned long tx_vlan_pkt_n; + nveu64_t tx_vlan_pkt_n; /** Total number of TSO packet count */ - unsigned long tx_tso_pkt_n; + nveu64_t tx_tso_pkt_n; }; #endif diff --git a/include/osd.h b/include/osd.h index e2791d5..1214122 100644 --- a/include/osd.h +++ b/include/osd.h @@ -23,6 +23,8 @@ #ifndef OSD_H #define OSD_H +#include "../osi/common/type.h" + /** * @brief osd_usleep_range - sleep in micro seconds * @@ -35,7 +37,7 @@ * - Run time: Yes * - De-initialization: No */ -void osd_usleep_range(unsigned long umin, unsigned long umax); +void osd_usleep_range(nveu64_t umin, nveu64_t umax); /** * @brief osd_msleep - sleep in milli seconds * @@ -47,7 +49,7 @@ void osd_usleep_range(unsigned long umin, unsigned long umax); * - Run time: Yes * - De-initialization: No */ -void osd_msleep(unsigned int msec); +void osd_msleep(nveu32_t msec); /** * @brief osd_udelay - delay in micro seconds * @@ -59,7 +61,7 @@ void osd_msleep(unsigned int msec); * - Run time: Yes * - De-initialization: No */ -void osd_udelay(unsigned long usec); +void osd_udelay(nveu64_t usec); /** * @brief osd_receive_packet - Handover received packet to network stack. * @@ -86,8 +88,8 @@ void osd_udelay(unsigned long usec); * - Run time: Yes * - De-initialization: No */ -void osd_receive_packet(void *priv, void *rxring, unsigned int chan, - unsigned int dma_buf_len, void *rxpkt_cx, +void osd_receive_packet(void *priv, void *rxring, nveu32_t chan, + nveu32_t dma_buf_len, void *rxpkt_cx, void *rx_pkt_swcx); /** @@ -120,8 +122,8 @@ void osd_receive_packet(void *priv, void *rxring, unsigned int chan, * - Run time: Yes * - De-initialization: No */ -void osd_transmit_complete(void *priv, void *buffer, unsigned long dmaaddr, - unsigned int len, void *txdone_pkt_cx); +void osd_transmit_complete(void *priv, void *buffer, nveu64_t dmaaddr, + nveu32_t len, void *txdone_pkt_cx); /** * @brief osd_log - OSD logging function * @@ -140,10 +142,10 @@ void osd_transmit_complete(void *priv, void *buffer, unsigned long dmaaddr, * - De-initialization: Yes */ void osd_log(void *priv, - const char *func, - unsigned int line, - unsigned int level, - unsigned int type, - const char *err, - unsigned long long loga); + const nve8_t *func, + nveu32_t line, + nveu32_t level, + nveu32_t type, + const nve8_t *err, + nveul64_t loga); #endif diff --git a/include/osi_common.h b/include/osi_common.h index ed410ca..d4faab1 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -23,6 +23,7 @@ #ifndef OSI_COMMON_H #define OSI_COMMON_H +#include "../osi/common/type.h" /** * @addtogroup Helper Helper MACROS * @@ -61,7 +62,7 @@ * PHY should be up before the LPI pattern can be transmitted to the PHY. * Default 1sec. */ -#define OSI_DEFAULT_LPI_LS_TIMER (unsigned int)1000 +#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 @@ -235,7 +236,7 @@ } \ } \ -#define OSI_BIT(nr) ((unsigned int)1 << (nr)) +#define OSI_BIT(nr) ((nveu32_t)1 << (nr)) #define OSI_EQOS_MAC_4_10 0x41U #define OSI_EQOS_MAC_5_00 0x50U @@ -340,62 +341,62 @@ struct osi_hw_features { /** It is set to 1 when 10/100 Mbps is selected as the Mode of * Operation */ - unsigned int mii_sel; + nveu32_t mii_sel; /** It is set to 1 when the RGMII Interface option is selected */ - unsigned int rgmii_sel; + nveu32_t rgmii_sel; /** It is set to 1 when the RMII Interface option is selected */ - unsigned int rmii_sel; + nveu32_t rmii_sel; /** It sets to 1 when 1000 Mbps is selected as the Mode of Operation */ - unsigned int gmii_sel; + nveu32_t gmii_sel; /** It sets to 1 when the half-duplex mode is selected */ - unsigned int hd_sel; + nveu32_t hd_sel; /** It sets to 1 when the TBI, SGMII, or RTBI PHY interface * option is selected */ - unsigned int pcs_sel; + nveu32_t pcs_sel; /** It sets to 1 when the Enable VLAN Hash Table Based Filtering * option is selected */ - unsigned int vlan_hash_en; + nveu32_t vlan_hash_en; /** It sets to 1 when the Enable Station Management (MDIO Interface) * option is selected */ - unsigned int sma_sel; + nveu32_t sma_sel; /** It sets to 1 when the Enable Remote Wake-Up Packet Detection * option is selected */ - unsigned int rwk_sel; + nveu32_t rwk_sel; /** It sets to 1 when the Enable Magic Packet Detection option is * selected */ - unsigned int mgk_sel; + nveu32_t mgk_sel; /** It sets to 1 when the Enable MAC Management Counters (MMC) option * is selected */ - unsigned int mmc_sel; + nveu32_t mmc_sel; /** It sets to 1 when the Enable IPv4 ARP Offload option is selected */ - unsigned int arp_offld_en; + nveu32_t arp_offld_en; /** It sets to 1 when the Enable IEEE 1588 Timestamp Support option * is selected */ - unsigned int ts_sel; + nveu32_t ts_sel; /** It sets to 1 when the Enable Energy Efficient Ethernet (EEE) option * is selected */ - unsigned int eee_sel; + nveu32_t eee_sel; /** It sets to 1 when the Enable Transmit TCP/IP Checksum Insertion * option is selected */ - unsigned int tx_coe_sel; + nveu32_t tx_coe_sel; /** It sets to 1 when the Enable Receive TCP/IP Checksum Check option * is selected */ - unsigned int rx_coe_sel; + nveu32_t rx_coe_sel; /** It sets to 1 when the Enable Additional 1-31 MAC Address Registers * option is selected */ - unsigned int mac_addr_sel; + nveu32_t mac_addr_sel; /** It sets to 1 when the Enable Additional 32-63 MAC Address Registers * option is selected */ - unsigned int mac_addr32_sel; + nveu32_t mac_addr32_sel; /** It sets to 1 when the Enable Additional 64-127 MAC Address Registers * option is selected */ - unsigned int mac_addr64_sel; + nveu32_t mac_addr64_sel; /** It sets to 1 when the Enable IEEE 1588 Timestamp Support option * is selected */ - unsigned int tsstssel; + nveu32_t tsstssel; /** It sets to 1 when the Enable SA and VLAN Insertion on Tx option * is selected */ - unsigned int sa_vlan_ins; + 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 @@ -409,7 +410,7 @@ struct osi_hw_features { * 110: SMII * 111: RevMII * All Others: Reserved */ - unsigned int act_phy_sel; + 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: @@ -427,7 +428,7 @@ struct osi_hw_features { * 01010: 128 KB * 01011: 256 KB * 01100-11111: Reserved */ - unsigned int rx_fifo_size; + 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, @@ -444,53 +445,53 @@ struct osi_hw_features { * 01001: 64 KB * 01010: 128 KB * 01011-11111: Reserved */ - unsigned int tx_fifo_size; + nveu32_t tx_fifo_size; /** It set to 1 when Advance timestamping High Word selected */ - unsigned int adv_ts_hword; + nveu32_t adv_ts_hword; /** Address Width. * This field indicates the configured address width: * 00: 32 * 01: 40 * 10: 48 * 11: Reserved */ - unsigned int addr_64; + nveu32_t addr_64; /** It sets to 1 when DCB Feature Enable */ - unsigned int dcb_en; + nveu32_t dcb_en; /** It sets to 1 when Split Header Feature Enable */ - unsigned int sph_en; + nveu32_t sph_en; /** It sets to 1 when TCP Segmentation Offload Enable */ - unsigned int tso_en; + nveu32_t tso_en; /** It sets to 1 when DMA debug registers are enabled */ - unsigned int dma_debug_gen; + nveu32_t dma_debug_gen; /** It sets to 1 if AV Feature Enabled */ - unsigned int av_sel; + nveu32_t av_sel; /** It sets to 1 if Receive side AV Feature Enabled */ - unsigned int rav_sel; + nveu32_t rav_sel; /** This field indicates the size of the hash table: * 00: No hash table * 01: 64 * 10: 128 * 11: 256 */ - unsigned int hash_tbl_sz; + 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 */ - unsigned int l3l4_filter_num; + nveu32_t l3l4_filter_num; /** It holds number of MTL Receive Queues */ - unsigned int rx_q_cnt; + nveu32_t rx_q_cnt; /** It holds number of MTL Transmit Queues */ - unsigned int tx_q_cnt; + nveu32_t tx_q_cnt; /** It holds number of DMA Receive channels */ - unsigned int rx_ch_cnt; + 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 */ - unsigned int tx_ch_cnt; + nveu32_t tx_ch_cnt; /** This field indicates the number of PPS outputs: * 000: No PPS output * 001: 1 PPS output @@ -498,7 +499,7 @@ struct osi_hw_features { * 011: 3 PPS outputs * 100: 4 PPS outputs * 101-111: Reserved */ - unsigned int pps_out_num; + nveu32_t pps_out_num; /** Number of Auxiliary Snapshot Inputs * This field indicates the number of auxiliary snapshot inputs: * 000: No auxiliary input @@ -507,58 +508,58 @@ struct osi_hw_features { * 011: 3 auxiliary inputs * 100: 4 auxiliary inputs * 101-111: Reserved */ - unsigned int aux_snap_num; + nveu32_t aux_snap_num; /** VxLAN/NVGRE Support */ - unsigned int vxn; + nveu32_t vxn; /** Enhanced DMA. * This bit is set to 1 when the "Enhanced DMA" option is * selected. */ - unsigned int edma; + nveu32_t edma; /** Different Descriptor Cache * When set to 1, then EDMA mode Separate Memory is * selected for the Descriptor Cache.*/ - unsigned int ediffc; + nveu32_t ediffc; /** PFC Enable * This bit is set to 1 when the Enable PFC Feature is selected */ - unsigned int pfc_en; + nveu32_t pfc_en; /** One-Step Timestamping Enable */ - unsigned int ost_en; + nveu32_t ost_en; /** PTO Offload Enable */ - unsigned int pto_en; + nveu32_t pto_en; /** Receive Side Scaling Enable */ - unsigned int rss_en; + nveu32_t rss_en; /** Number of Traffic Classes */ - unsigned int num_tc; + nveu32_t num_tc; /** Number of Extended VLAN Tag Filters Enabled */ - unsigned int num_vlan_filters; + 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 */ - unsigned int frp_sel; + 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. */ - unsigned int cbti_sel; + nveu32_t cbti_sel; /** Supported Parallel Instruction Processor Engines (PIPEs) * This field indicates the maximum number of Instruction * Processors supported by flexible receive parser. */ - unsigned int num_frp_pipes; + 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 */ - unsigned int ost_over_udp; + 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 */ - unsigned int max_frp_bytes; + nveu32_t max_frp_bytes; /** Supported Flexible Receive Parser Instructions * This field indicates the Max Number of Parser Instructions * supported by Flexible Receive Parser */ - unsigned int max_frp_entries; + nveu32_t max_frp_entries; /** Double VLAN Processing Enabled * This bit is set to 1 when the Enable Double VLAN Processing * feature is selected */ - unsigned int double_vlan_en; + nveu32_t double_vlan_en; /** Automotive Safety Package * Following are the encoding for the different Safety features * Values: @@ -571,7 +572,7 @@ struct osi_hw_features { * 0x3 (AS_PPE): All the Automotive Safety features are * selected with the "Parity Port Enable for external interface" * feature */ - unsigned int auto_safety_pkg; + nveu32_t auto_safety_pkg; /** Tx Timestamp FIFO Depth * This value indicates the depth of the Tx Timestamp FIFO * 3'b000: Reserved @@ -582,7 +583,7 @@ struct osi_hw_features { * 3'b101: 16 * 3'b110: Reserved * 3'b111: Reserved */ - unsigned int tts_fifo_depth; + 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. @@ -591,7 +592,7 @@ struct osi_hw_features { * Traffic feature is not selected * 0x1 (ACTIVE): Enable Enhancements to Scheduling * Traffic feature is selected */ - unsigned int est_sel; + 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 @@ -603,7 +604,7 @@ struct osi_hw_features { * 0x4 (DEPTH512): 512 * 0x5 (DEPTH1024): 1024 * 0x6 (RSVD): Reserved */ - unsigned int gcl_depth; + 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 @@ -612,7 +613,7 @@ struct osi_hw_features { * 0x1 (WIDTH16): 16 * 0x2 (WIDTH20): 20 * 0x3 (WIDTH24): 24 */ - unsigned int gcl_width; + nveu32_t gcl_width; /** Frame Preemption Enable * This bit is set to 1 when the Enable Frame preemption feature * is selected. @@ -621,7 +622,7 @@ struct osi_hw_features { * selected * 0x1 (ACTIVE): Frame Preemption Enable feature is * selected */ - unsigned int fpe_sel; + nveu32_t fpe_sel; /** Time Based Scheduling Enable * This bit is set to 1 when the Time Based Scheduling feature is * selected. @@ -630,7 +631,7 @@ struct osi_hw_features { * not selected * 0x1 (ACTIVE): Time Based Scheduling Enable feature is * selected */ - unsigned int tbs_sel; + 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 @@ -641,7 +642,7 @@ struct osi_hw_features { * 0010: 3 DMA Tx Channels enabled for TBS * ... * 1111: 16 DMA Tx Channels enabled for TBS */ - unsigned int num_tbs_ch; + nveu32_t num_tbs_ch; }; /** @@ -659,7 +660,7 @@ struct osi_hw_features { * - Run time: No * - De-initialization: No */ -static inline void osi_lock_init(unsigned int *lock) +static inline void osi_lock_init(nveu32_t *lock) { *lock = OSI_UNLOCKED; } @@ -683,7 +684,7 @@ static inline void osi_lock_init(unsigned int *lock) * - Run time: Yes * - De-initialization: No */ -static inline void osi_lock_irq_enabled(unsigned int *lock) +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. @@ -715,7 +716,7 @@ static inline void osi_lock_irq_enabled(unsigned int *lock) * - Run time: Yes * - De-initialization: No */ -static inline void osi_unlock_irq_enabled(unsigned int *lock) +static inline void osi_unlock_irq_enabled(nveu32_t *lock) { if (__sync_val_compare_and_swap(lock, OSI_LOCKED, OSI_UNLOCKED) != OSI_LOCKED) { @@ -738,9 +739,9 @@ static inline void osi_unlock_irq_enabled(unsigned int *lock) * - Run time: Yes * - De-initialization: Yes */ -static inline unsigned int osi_readl(void *addr) +static inline nveu32_t osi_readl(void *addr) { - return *(volatile unsigned int *)addr; + return *(volatile nveu32_t *)addr; } /** @@ -757,9 +758,9 @@ static inline unsigned int osi_readl(void *addr) * - Run time: Yes * - De-initialization: Yes */ -static inline void osi_writel(unsigned int val, void *addr) +static inline void osi_writel(nveu32_t val, void *addr) { - *(volatile unsigned int *)addr = val; + *(volatile nveu32_t *)addr = val; } /** @@ -778,7 +779,7 @@ static inline void osi_writel(unsigned int val, void *addr) * @retval 0 - for not Valid MAC * @retval 1 - for Valid MAC */ -static inline int is_valid_mac_version(unsigned int mac_ver) +static inline nve32_t is_valid_mac_version(nveu32_t mac_ver) { if ((mac_ver == OSI_EQOS_MAC_4_10) || (mac_ver == OSI_EQOS_MAC_5_00) || @@ -800,7 +801,7 @@ static inline int is_valid_mac_version(unsigned int mac_ver) * @param[in] last_value: last value of stat counter * @param[in] incr: increment value * - * @note Input parameter should be only unsigned long type + * @note Input parameter should be only nveu64_t type * * @note * API Group: @@ -808,12 +809,12 @@ static inline int is_valid_mac_version(unsigned int mac_ver) * - Run time: Yes * - De-initialization: No * - * @return unsigned long value + * @return nveu64_t value */ -static inline unsigned long osi_update_stats_counter(unsigned long last_value, - unsigned long incr) +static inline nveu64_t osi_update_stats_counter(nveu64_t last_value, + nveu64_t incr) { - unsigned long temp = last_value + incr; + nveu64_t temp = last_value + incr; if (temp < last_value) { /* Stats overflow, so reset it to zero */ @@ -844,7 +845,7 @@ static inline unsigned long osi_update_stats_counter(unsigned long last_value, * @retval 0 on success * @retval -1 on failure. */ -int common_get_mac_version(void *addr, unsigned int *mac_ver); +nve32_t common_get_mac_version(void *addr, nveu32_t *mac_ver); /** * @brief comon_get_hw_features - Reading MAC HW features @@ -874,5 +875,5 @@ void common_get_hw_features(void *base, struct osi_hw_features *hw_feat); * - Run time: Yes * - De-initialization: No */ -void osi_memset(void *s, unsigned int c, unsigned long count); +void osi_memset(void *s, nveu32_t c, nveu64_t count); #endif /* OSI_COMMON_H */ diff --git a/include/osi_core.h b/include/osi_core.h index e8405b6..17f755d 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -25,6 +25,7 @@ #include "osi_common.h" #include "mmc.h" +#include "../osi/common/type.h" /** * @addtogroup PTP related information @@ -73,25 +74,25 @@ struct osi_core_priv_data; */ struct osi_filter { /** indicates operation needs to perform. refer to OSI_OPER_* */ - unsigned int oper_mode; + nveu32_t oper_mode; /** Indicates the index of the filter to be modified. * Filter index must be between 0 - 127 */ - unsigned int index; + nveu32_t index; /** Ethernet MAC address to be added */ - const unsigned char *mac_address; + const nveu8_t *mac_address; /** Indicates dma channel routing enable(1) disable (0) */ - unsigned int dma_routing; + nveu32_t dma_routing; /** indicates dma channel number to program */ - unsigned int dma_chan; + 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] */ - unsigned int addr_mask; + nveu32_t addr_mask; /** src_dest: SA(1) or DA(0) */ - unsigned int src_dest; + nveu32_t src_dest; }; /** @@ -100,19 +101,19 @@ struct osi_filter { struct osi_l3_l4_filter { /** Indicates the index of the filter to be modified. * Filter index must be between 0 - 7 */ - unsigned int filter_no; + nveu32_t filter_no; /** filter enable(1) or disable(0) */ - unsigned int filter_enb_dis; + nveu32_t filter_enb_dis; /** source(0) or destination(1) */ - unsigned int src_dst_addr_match; + nveu32_t src_dst_addr_match; /** perfect(0) or inverse(1) */ - unsigned int perfect_inverse_match; + nveu32_t perfect_inverse_match; /** ipv4 address */ - unsigned char ip4_addr[4]; + nveu8_t ip4_addr[4]; /** ipv6 address */ - unsigned short ip6_addr[8]; + nveu16_t ip6_addr[8]; /** Port number */ - unsigned short port_no; + nveu16_t port_no; }; /** @@ -120,11 +121,11 @@ struct osi_l3_l4_filter { */ struct osi_vlan_filter { /** vlan filter enable(1) or disable(0) */ - unsigned int filter_enb_dis; + nveu32_t filter_enb_dis; /** perfect(0) or hash(1) */ - unsigned int perfect_hash; + nveu32_t perfect_hash; /** perfect(0) or inverse(1) */ - unsigned int perfect_inverse_match; + nveu32_t perfect_inverse_match; }; /** @@ -132,9 +133,9 @@ struct osi_vlan_filter { */ struct osi_l2_da_filter { /** perfect(0) or hash(1) */ - unsigned int perfect_hash; + nveu32_t perfect_hash; /** perfect(0) or inverse(1) */ - unsigned int perfect_inverse_match; + nveu32_t perfect_inverse_match; }; #ifndef OSI_STRIPPED_LIB @@ -143,23 +144,23 @@ struct osi_l2_da_filter { */ struct osi_core_avb_algorithm { /** TX Queue/TC index */ - unsigned int qindex; + nveu32_t qindex; /** CBS Algorithm enable(1) or disable(0) */ - unsigned int algo; + 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) */ - unsigned int credit_control; + nveu32_t credit_control; /** idleSlopeCredit value required for CBS */ - unsigned int idle_slope; + nveu32_t idle_slope; /** sendSlopeCredit value required for CBS */ - unsigned int send_slope; + nveu32_t send_slope; /** hiCredit value required for CBS */ - unsigned int hi_credit; + nveu32_t hi_credit; /** lowCredit value required for CBS */ - unsigned int low_credit; + nveu32_t low_credit; /** Transmit queue operating mode * * 00: disable @@ -167,7 +168,7 @@ struct osi_core_avb_algorithm { * 01: avb * * 10: enable */ - unsigned int oper_mode; + nveu32_t oper_mode; }; #endif /* !OSI_STRIPPED_LIB */ @@ -176,12 +177,12 @@ struct osi_core_avb_algorithm { */ struct osi_core_ops { /** Called to poll for software reset bit */ - int (*poll_for_swr)(struct osi_core_priv_data *const osi_core, - unsigned int pre_si); + nve32_t (*poll_for_swr)(struct osi_core_priv_data *const osi_core, + nve32_t pre_si); /** Called to initialize MAC and MTL registers */ - int (*core_init)(struct osi_core_priv_data *const osi_core, - const unsigned int tx_fifo_size, - const unsigned int rx_fifo_size); + 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 */ @@ -191,139 +192,143 @@ struct osi_core_ops { /** 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) */ - int (*set_mode)(struct osi_core_priv_data *const osi_core, - const int mode); + nve32_t (*set_mode)(struct osi_core_priv_data *const osi_core, + const nve32_t mode); /** Called to set the speed (10/100/1000) at MAC */ - void (*set_speed)(void *ioaddr, const int speed); + void (*set_speed)(void *ioaddr, const nve32_t speed); /** Called to do pad caliberation */ - int (*pad_calibrate)(struct osi_core_priv_data *const osi_core); + nve32_t (*pad_calibrate)(struct osi_core_priv_data *const osi_core); /** Called to configure MTL RxQ to forward the err pkt */ - int (*config_fw_err_pkts)(struct osi_core_priv_data *const osi_core, - const unsigned int qinx, - const unsigned int fw_err); + 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 */ - int (*config_rxcsum_offload)(struct osi_core_priv_data *const osi_core, - const unsigned int enabled); + nve32_t (*config_rxcsum_offload)( + struct osi_core_priv_data *const osi_core, + const nveu32_t enabled); /** Called to config mac packet filter */ - int (*config_mac_pkt_filter_reg)( + 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 */ - int (*update_mac_addr_low_high_reg)( + 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 */ - int (*config_l3_l4_filter_enable)(void *base, - const unsigned int enable); + nve32_t (*config_l3_l4_filter_enable)(void *base, + const nveu32_t enable); /** Called to configure L3 filter */ - int (*config_l3_filters)(struct osi_core_priv_data *const osi_core, - const unsigned int filter_no, - const unsigned int enb_dis, - const unsigned int ipv4_ipv6_match, - const unsigned int src_dst_addr_match, - const unsigned int perfect_inverse_match, - const unsigned int dma_routing_enable, - const unsigned int dma_chan); + 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 */ - int (*update_ip4_addr)(struct osi_core_priv_data *const osi_core, - const unsigned int filter_no, - const unsigned char addr[], - const unsigned int src_dst_addr_match); + 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 */ - int (*update_ip6_addr)(struct osi_core_priv_data *const osi_core, - const unsigned int filter_no, - const unsigned short addr[]); + 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 */ - int (*config_l4_filters)(struct osi_core_priv_data *const osi_core, - const unsigned int filter_no, - const unsigned int enb_dis, - const unsigned int tcp_udp_match, - const unsigned int src_dst_port_match, - const unsigned int perfect_inverse_match, - const unsigned int dma_routing_enable, - const unsigned int dma_chan); + 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 */ - int (*update_l4_port_no)(struct osi_core_priv_data *const osi_core, - const unsigned int filter_no, - const unsigned short port_no, - const unsigned int src_dst_port_match); + 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 */ - int (*config_addend)(struct osi_core_priv_data *const osi_core, - const unsigned int addend); + nve32_t (*config_addend)(struct osi_core_priv_data *const osi_core, + const nveu32_t addend); /** Called to adjust the mac time */ - int (*adjust_mactime)(struct osi_core_priv_data *const osi_core, - const unsigned int sec, - const unsigned int nsec, - const unsigned int neg_adj, - const unsigned int one_nsec_accuracy); + 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 */ - int (*set_systime_to_mac)(struct osi_core_priv_data *const osi_core, - const unsigned int sec, - const unsigned int nsec); + 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)(void *addr, const unsigned int ptp_filter); + void (*config_tscr)(void *addr, const nveu32_t ptp_filter); /** Called to configure the sub second increment register */ void (*config_ssir)(struct osi_core_priv_data *const osi_core); /** 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 */ - int (*write_phy_reg)(struct osi_core_priv_data *const osi_core, - const unsigned int phyaddr, - const unsigned int phyreg, - const unsigned short phydata); + 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 */ - int (*read_phy_reg)(struct osi_core_priv_data *const osi_core, - const unsigned int phyaddr, - const unsigned int phyreg); + nve32_t (*read_phy_reg)(struct osi_core_priv_data *const osi_core, + const nveu32_t phyaddr, + const nveu32_t phyreg); #ifndef OSI_STRIPPED_LIB /** Called periodically to read and validate safety critical * registers against last written value */ - int (*validate_regs)(struct osi_core_priv_data *const osi_core); + nve32_t (*validate_regs)(struct osi_core_priv_data *const osi_core); /** Called to flush MTL Tx queue */ - int (*flush_mtl_tx_queue)(struct osi_core_priv_data *const osi_core, - const unsigned int qinx); + nve32_t (*flush_mtl_tx_queue)(struct osi_core_priv_data *const osi_core, + const nveu32_t qinx); /** Called to set av parameter */ - int (*set_avb_algorithm)(struct osi_core_priv_data *const osi_core, + 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 */ - int (*get_avb_algorithm)(struct osi_core_priv_data *const osi_core, - struct osi_core_avb_algorithm *const avb); + 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 */ - int (*config_tx_status)(struct osi_core_priv_data *const osi_core, - const unsigned int 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 */ - int (*config_rx_crc_check)(struct osi_core_priv_data *const osi_core, - const unsigned int crc_chk); + 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 */ - int (*config_flow_control)(struct osi_core_priv_data *const osi_core, - const unsigned int flw_ctrl); + 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 */ - int (*config_arp_offload)(const unsigned int mac_ver, - struct osi_core_priv_data *const osi_core, - const unsigned int enable, - const unsigned char *ip_addr); + nve32_t (*config_arp_offload)(const nveu32_t mac_ver, + struct osi_core_priv_data *const osi_core, + const nveu32_t enable, + const nveu8_t *ip_addr); /** Called to configure VLAN filtering */ - int (*config_vlan_filtering)(struct osi_core_priv_data *const osi_core, - const unsigned int filter_enb_dis, - const unsigned int perfect_hash_filtering, - const unsigned int perfect_inverse_match); + 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 update VLAN id */ - int (*update_vlan_id)(void *base, const unsigned int vid); + nve32_t (*update_vlan_id)(void *base, const nveu32_t vid); /** 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 unsigned int tx_lpi_enabled, - const unsigned int tx_lpi_timer); + const nveu32_t tx_lpi_enabled, + const nveu32_t tx_lpi_timer); /** Called to save MAC register space during SoC suspend */ - int (*save_registers)(struct osi_core_priv_data *const osi_core); + nve32_t (*save_registers)(struct osi_core_priv_data *const osi_core); /** Called to restore MAC control registers during SoC resume */ - int (*restore_registers)(struct osi_core_priv_data *const osi_core); + 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 unsigned long csr_clk_rate); + const nveu64_t csr_clk_rate); /** Called to configure MAC in loopback mode */ - int (*config_mac_loopback)(void *addr, const unsigned int lb_mode); + nve32_t (*config_mac_loopback)(void *addr, const nveu32_t lb_mode); #endif /* !OSI_STRIPPED_LIB */ }; @@ -361,17 +366,17 @@ struct osi_ptp_config { * AV 802.1AS Mode Enable OSI_BIT(28) * * if ptp_filter is set to Zero then Time stamping is disabled */ - unsigned int ptp_filter; + nveu32_t ptp_filter; /** seconds to be updated to MAC */ - unsigned int sec; + nveu32_t sec; /** nano seconds to be updated to MAC */ - unsigned int nsec; + nveu32_t nsec; /** PTP reference clock read from DT */ - unsigned int ptp_ref_clk_rate; + nveu32_t ptp_ref_clk_rate; /** Use one nsec accuracy (need to set 1) */ - unsigned int one_nsec_accuracy; + nveu32_t one_nsec_accuracy; /** PTP system clock which is 62500000Hz */ - unsigned int ptp_clock; + nveu32_t ptp_clock; }; /** @@ -387,7 +392,7 @@ 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 */ - unsigned int reg_val[CORE_MAX_BAK_IDX]; + nveu32_t reg_val[CORE_MAX_BAK_IDX]; }; /** @@ -395,15 +400,15 @@ struct core_backup { */ struct osd_core_ops { /** logging callback */ - void (*ops_log)(void *priv, const char *func, unsigned int line, - unsigned int level, unsigned int type, const char *err, - unsigned long long loga); + 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)(unsigned long usec); + void (*udelay)(nveu64_t usec); /** usleep range callback */ - void (*usleep_range)(unsigned long umin, unsigned long umax); + void (*usleep_range)(nveu64_t umin, nveu64_t umax); /** msleep callback */ - void (*msleep)(unsigned int msec); + void (*msleep)(nveu32_t msec); }; /** @@ -421,53 +426,53 @@ struct osi_core_priv_data { /** OSD callback ops structure */ struct osd_core_ops osd_ops; /** Number of MTL queues enabled in MAC */ - unsigned int num_mtl_queues; + nveu32_t num_mtl_queues; /** Array of MTL queues */ - unsigned int mtl_queues[OSI_EQOS_MAX_NUM_CHANS]; + nveu32_t mtl_queues[OSI_EQOS_MAX_NUM_CHANS]; /** List of MTL Rx queue mode that need to be enabled */ - unsigned int rxq_ctrl[OSI_EQOS_MAX_NUM_CHANS]; + nveu32_t rxq_ctrl[OSI_EQOS_MAX_NUM_CHANS]; /** Rx MTl Queue mapping based on User Priority field */ - unsigned int rxq_prio[OSI_EQOS_MAX_NUM_CHANS]; + nveu32_t rxq_prio[OSI_EQOS_MAX_NUM_CHANS]; /** MAC HW type EQOS based on DT compatible */ - unsigned int mac; + nveu32_t mac; /** MAC version */ - unsigned int mac_ver; + nveu32_t mac_ver; /** MDC clock rate */ - unsigned int mdc_cr; + nveu32_t mdc_cr; /** MTU size */ - unsigned int mtu; + nveu32_t mtu; /** Ethernet MAC address */ - unsigned char mac_addr[OSI_ETH_ALEN]; + nveu8_t mac_addr[OSI_ETH_ALEN]; /** DT entry to enable(0) or disable(1) pause frame support */ - unsigned int pause_frames; + nveu32_t pause_frames; /** Current flow control settings */ - unsigned int flow_ctrl; + nveu32_t flow_ctrl; /** PTP configuration settings */ struct osi_ptp_config ptp_config; /** Default addend value */ - unsigned int default_addend; + 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) */ - unsigned int dcs_en; + 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) */ - unsigned int strip_vlan_tag; + nveu32_t strip_vlan_tag; /** L3L4 filter bit bask, set index corresponding bit for * filter if filter enabled */ - unsigned int l3l4_filter_bitmask; + nveu32_t l3l4_filter_bitmask; /** csr clock is to program LPI 1 us tick timer register. * Value stored in MHz */ - unsigned int csr_clk_speed; + nveu32_t csr_clk_speed; /** Tegra Pre-si platform info */ - unsigned int pre_si; + nve32_t pre_si; }; /** @@ -503,7 +508,7 @@ struct osi_core_priv_data { * @retval -1 on failure. */ -int osi_poll_for_mac_reset_complete( +nve32_t osi_poll_for_mac_reset_complete( struct osi_core_priv_data *const osi_core); /** @@ -544,9 +549,8 @@ int osi_poll_for_mac_reset_complete( * @retval 0 on success * @retval -1 on failure. */ -int osi_hw_core_init(struct osi_core_priv_data *const osi_core, - unsigned int tx_fifo_size, - unsigned int rx_fifo_size); +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. @@ -579,7 +583,7 @@ int osi_hw_core_init(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_hw_core_deinit(struct osi_core_priv_data *const osi_core); +nve32_t osi_hw_core_deinit(struct osi_core_priv_data *const osi_core); /** * @brief osi_start_mac - Start MAC Tx/Rx engine @@ -613,7 +617,7 @@ int osi_hw_core_deinit(struct osi_core_priv_data *const osi_core); * @retval 0 on success * @retval -1 on failure. */ -int osi_start_mac(struct osi_core_priv_data *const osi_core); +nve32_t osi_start_mac(struct osi_core_priv_data *const osi_core); /** * @brief osi_stop_mac - Stop MAC Tx/Rx engine @@ -646,7 +650,7 @@ int osi_start_mac(struct osi_core_priv_data *const osi_core); * @retval 0 on success * @retval -1 on failure. */ -int osi_stop_mac(struct osi_core_priv_data *const osi_core); +nve32_t osi_stop_mac(struct osi_core_priv_data *const osi_core); /** * @brief osi_common_isr - Common ISR. @@ -680,7 +684,7 @@ int osi_stop_mac(struct osi_core_priv_data *const osi_core); * @retval 0 on success * @retval -1 on failure. */ -int osi_common_isr(struct osi_core_priv_data *const osi_core); +nve32_t osi_common_isr(struct osi_core_priv_data *const osi_core); /** * @brief osi_set_mode - Set FD/HD mode. @@ -714,8 +718,8 @@ int osi_common_isr(struct osi_core_priv_data *const osi_core); * @retval 0 on success * @retval -1 on failure. */ -int osi_set_mode(struct osi_core_priv_data *const osi_core, - const int mode); +nve32_t osi_set_mode(struct osi_core_priv_data *const osi_core, + const nve32_t mode); /** * @brief osi_set_speed - Set operating speed. @@ -750,8 +754,8 @@ int osi_set_mode(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_set_speed(struct osi_core_priv_data *const osi_core, - const int speed); +nve32_t osi_set_speed(struct osi_core_priv_data *const osi_core, + const nve32_t speed); /** * @brief osi_pad_calibrate - PAD calibration @@ -788,7 +792,7 @@ int osi_set_speed(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_pad_calibrate(struct osi_core_priv_data *const osi_core); +nve32_t osi_pad_calibrate(struct osi_core_priv_data *const osi_core); /** * @brief osi_config_fw_err_pkts - Configure forwarding of error packets @@ -823,8 +827,8 @@ int osi_pad_calibrate(struct osi_core_priv_data *const osi_core); * @retval 0 on success * @retval -1 on failure. */ -int osi_config_fw_err_pkts(struct osi_core_priv_data *const osi_core, - const unsigned int qinx, const unsigned int fw_err); +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. @@ -858,9 +862,8 @@ int osi_config_fw_err_pkts(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_config_rxcsum_offload( - struct osi_core_priv_data *const osi_core, - const unsigned int enable); +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. @@ -897,8 +900,8 @@ int osi_config_rxcsum_offload( * @retval 0 on success * @retval -1 on failure. */ -int osi_l2_filter(struct osi_core_priv_data *const osi_core, - const struct osi_filter *filter); +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. @@ -941,9 +944,9 @@ int osi_l2_filter(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_write_phy_reg(struct osi_core_priv_data *const osi_core, - const unsigned int phyaddr, const unsigned int phyreg, - const unsigned short phydata); +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 @@ -980,7 +983,7 @@ int osi_write_phy_reg(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_read_mmc(struct osi_core_priv_data *const osi_core); +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. @@ -1022,9 +1025,9 @@ int osi_read_mmc(struct osi_core_priv_data *const osi_core); * @retval data from PHY register on success * @retval -1 on failure */ -int osi_read_phy_reg(struct osi_core_priv_data *const osi_core, - const unsigned int phyaddr, - const unsigned int phyreg); +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 @@ -1052,7 +1055,7 @@ int osi_read_phy_reg(struct osi_core_priv_data *const osi_core, * - De-initialization: No * */ -int osi_init_core_ops(struct osi_core_priv_data *const osi_core); +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. @@ -1087,8 +1090,8 @@ int osi_init_core_ops(struct osi_core_priv_data *const osi_core); * @retval 0 on success * @retval -1 on failure. */ -int osi_set_systime_to_mac(struct osi_core_priv_data *const osi_core, - const unsigned int sec, const unsigned int nsec); +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 @@ -1124,7 +1127,7 @@ int osi_set_systime_to_mac(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_adjust_freq(struct osi_core_priv_data *const osi_core, int ppb); +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 @@ -1161,8 +1164,8 @@ int osi_adjust_freq(struct osi_core_priv_data *const osi_core, int ppb); * @retval 0 on success * @retval -1 on failure. */ -int osi_adjust_time(struct osi_core_priv_data *const osi_core, - long long nsec_delta); +nve32_t osi_adjust_time(struct osi_core_priv_data *const osi_core, + nvel64_t nsec_delta); /** * @brief osi_ptp_configuration - Configure PTP @@ -1207,8 +1210,8 @@ int osi_adjust_time(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_ptp_configuration(struct osi_core_priv_data *const osi_core, - const unsigned int enable); +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 @@ -1265,12 +1268,12 @@ void *eqos_get_core_safety_config(void); * @retval 0 on success * @retval -1 on failure. */ -int osi_l3l4_filter(struct osi_core_priv_data *const osi_core, - const struct osi_l3_l4_filter l_filter, - const unsigned int type, - const unsigned int dma_routing_enable, - const unsigned int dma_chan, - const unsigned int is_l4_filter); +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 @@ -1304,7 +1307,7 @@ int osi_l3l4_filter(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_get_mac_version(void *addr, unsigned int *mac_ver); +nve32_t osi_get_mac_version(void *addr, nveu32_t *mac_ver); /** * @brief osi_get_hw_features - Reading MAC HW features @@ -1371,7 +1374,7 @@ void osi_get_hw_features(void *base, struct osi_hw_features *hw_feat); * @retval 0 on success * @retval -1 on failure. */ -int osi_validate_core_regs(struct osi_core_priv_data *const osi_core); +nve32_t osi_validate_core_regs(struct osi_core_priv_data *const osi_core); /** * @brief osi_flush_mtl_tx_queue - Flushing a MTL Tx Queue. @@ -1406,8 +1409,8 @@ int osi_validate_core_regs(struct osi_core_priv_data *const osi_core); * @retval 0 on success * @retval -1 on failure. */ -int osi_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, - const unsigned int qinx); +nve32_t osi_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, + const nveu32_t qinx); /** * @brief osi_set_avb - Set CBS algo and parameters @@ -1443,8 +1446,8 @@ int osi_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_set_avb(struct osi_core_priv_data *const osi_core, - const struct osi_core_avb_algorithm *avb); +nve32_t osi_set_avb(struct osi_core_priv_data *const osi_core, + const struct osi_core_avb_algorithm *avb); /** * @brief osi_get_avb - Get CBS algo and parameters @@ -1480,8 +1483,8 @@ int osi_set_avb(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_get_avb(struct osi_core_priv_data *const osi_core, - struct osi_core_avb_algorithm *avb); +nve32_t osi_get_avb(struct osi_core_priv_data *const osi_core, + struct osi_core_avb_algorithm *avb); /** * @brief osi_configure_txstatus - Configure Tx packet status reporting @@ -1515,8 +1518,8 @@ int osi_get_avb(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_configure_txstatus(struct osi_core_priv_data *const osi_core, - const unsigned int tx_status); +nve32_t osi_configure_txstatus(struct osi_core_priv_data *const osi_core, + const nveu32_t tx_status); /** * @brief osi_config_rx_crc_check - Configure CRC Checking for Received Packets @@ -1551,8 +1554,8 @@ int osi_configure_txstatus(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_config_rx_crc_check(struct osi_core_priv_data *const osi_core, - const unsigned int crc_chk); +nve32_t osi_config_rx_crc_check(struct osi_core_priv_data *const osi_core, + const nveu32_t crc_chk); /** * @brief osi_configure_flow_ctrl - Configure flow control settings @@ -1587,8 +1590,8 @@ int osi_config_rx_crc_check(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_configure_flow_control(struct osi_core_priv_data *const osi_core, - const unsigned int flw_ctrl); +nve32_t osi_configure_flow_control(struct osi_core_priv_data *const osi_core, + const nveu32_t flw_ctrl); /** * @brief osi_config_arp_offload - Configure ARP offload in MAC. @@ -1624,9 +1627,9 @@ int osi_configure_flow_control(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_config_arp_offload(struct osi_core_priv_data *const osi_core, - const unsigned int flags, - const unsigned char *ip_addr); +nve32_t osi_config_arp_offload(struct osi_core_priv_data *const osi_core, + const nveu32_t flags, + const nveu8_t *ip_addr); /** * @brief osi_config_vlan_filtering - OSI call for configuring VLAN filter * @@ -1663,10 +1666,10 @@ int osi_config_arp_offload(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_config_vlan_filtering(struct osi_core_priv_data *const osi_core, - const unsigned int filter_enb_dis, - const unsigned int perfect_hash_filtering, - const unsigned int perfect_inverse_match); +nve32_t osi_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); /** * @brief osi_update_vlan_id - invoke osi call to update VLAN ID @@ -1699,8 +1702,8 @@ int osi_config_vlan_filtering(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_update_vlan_id(struct osi_core_priv_data *const osi_core, - const unsigned int vid); +nve32_t osi_update_vlan_id(struct osi_core_priv_data *const osi_core, + const nveu32_t vid); /** * @brief osi_reset_mmc - invoke function to reset MMC counter and data @@ -1736,7 +1739,7 @@ int osi_update_vlan_id(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_reset_mmc(struct osi_core_priv_data *const osi_core); +nve32_t osi_reset_mmc(struct osi_core_priv_data *const osi_core); /** * @brief osi_get_systime_from_mac - Get system time @@ -1770,9 +1773,9 @@ int osi_reset_mmc(struct osi_core_priv_data *const osi_core); * @retval 0 on success * @retval -1 on failure. */ -int osi_get_systime_from_mac(struct osi_core_priv_data *const osi_core, - unsigned int *sec, - unsigned int *nsec); +nve32_t osi_get_systime_from_mac(struct osi_core_priv_data *const osi_core, + nveu32_t *sec, + nveu32_t *nsec); /** * @brief osi_configure_eee - Configure EEE LPI in MAC. @@ -1808,9 +1811,9 @@ int osi_get_systime_from_mac(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_configure_eee(struct osi_core_priv_data *const osi_core, - unsigned int tx_lpi_enabled, - unsigned int tx_lpi_timer); +nve32_t osi_configure_eee(struct osi_core_priv_data *const osi_core, + nveu32_t tx_lpi_enabled, + nveu32_t tx_lpi_timer); /** * @brief osi_save_registers - Take backup of MAC MMIO address space @@ -1831,7 +1834,7 @@ int osi_configure_eee(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_save_registers(struct osi_core_priv_data *const osi_core); +nve32_t osi_save_registers(struct osi_core_priv_data *const osi_core); /** * @brief osi_restore_registers - Restore backup of MAC MMIO address space @@ -1850,7 +1853,7 @@ int osi_save_registers(struct osi_core_priv_data *const osi_core); * @retval 0 on success * @retval -1 on failure. */ -int osi_restore_registers(struct osi_core_priv_data *const osi_core); +nve32_t osi_restore_registers(struct osi_core_priv_data *const osi_core); /** * @brief osi_set_mdc_clk_rate - Derive MDC clock based on provided AXI_CBB clk. @@ -1885,8 +1888,8 @@ int osi_restore_registers(struct osi_core_priv_data *const osi_core); * @retval 0 on success * @retval -1 on failure. */ -int osi_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, - const unsigned long csr_clk_rate); +nve32_t osi_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, + const nveu64_t csr_clk_rate); /** * @brief osi_config_mac_loopback - Configure MAC loopback @@ -1919,7 +1922,7 @@ int osi_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -int osi_config_mac_loopback(struct osi_core_priv_data *const osi_core, - const unsigned int lb_mode); +nve32_t osi_config_mac_loopback(struct osi_core_priv_data *const osi_core, + const nveu32_t lb_mode); #endif /* !OSI_STRIPPED_LIB */ #endif /* OSI_CORE_H */ diff --git a/include/osi_dma.h b/include/osi_dma.h index 4116821..244439d 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -167,33 +167,33 @@ */ struct osi_pkt_err_stats { /** IP Header Error */ - unsigned long ip_header_error; + nveu64_t ip_header_error; /** Jabber time out Error */ - unsigned long jabber_timeout_error; + nveu64_t jabber_timeout_error; /** Packet Flush Error */ - unsigned long pkt_flush_error; + nveu64_t pkt_flush_error; /** Payload Checksum Error */ - unsigned long payload_cs_error; + nveu64_t payload_cs_error; /** Loss of Carrier Error */ - unsigned long loss_of_carrier_error; + nveu64_t loss_of_carrier_error; /** No Carrier Error */ - unsigned long no_carrier_error; + nveu64_t no_carrier_error; /** Late Collision Error */ - unsigned long late_collision_error; + nveu64_t late_collision_error; /** Excessive Collision Error */ - unsigned long excessive_collision_error; + nveu64_t excessive_collision_error; /** Excessive Deferal Error */ - unsigned long excessive_deferal_error; + nveu64_t excessive_deferal_error; /** Under Flow Error */ - unsigned long underflow_error; + nveu64_t underflow_error; /** Rx CRC Error */ - unsigned long rx_crc_error; + nveu64_t rx_crc_error; /** Rx Frame Error */ - unsigned long rx_frame_error; + nveu64_t rx_frame_error; /** clear_tx_pkt_err_stats() API invoked */ - unsigned long clear_tx_err; + nveu64_t clear_tx_err; /** clear_rx_pkt_err_stats() API invoked */ - unsigned long clear_rx_err; + nveu64_t clear_rx_err; }; /** @@ -201,13 +201,13 @@ struct osi_pkt_err_stats { */ struct osi_rx_desc { /** Receive Descriptor 0 */ - unsigned int rdes0; + nveu32_t rdes0; /** Receive Descriptor 1 */ - unsigned int rdes1; + nveu32_t rdes1; /** Receive Descriptor 2 */ - unsigned int rdes2; + nveu32_t rdes2; /** Receive Descriptor 3 */ - unsigned int rdes3; + nveu32_t rdes3; }; /** @@ -215,13 +215,13 @@ struct osi_rx_desc { */ struct osi_rx_swcx { /** DMA buffer physical address */ - unsigned long buf_phy_addr; + nveu64_t buf_phy_addr; /** DMA buffer virtual address */ void *buf_virt_addr; /** Length of buffer */ - unsigned int len; + nveu32_t len; /** Flags to share info about Rx swcx between OSD and OSI */ - unsigned int flags; + nveu32_t flags; }; /** @@ -230,15 +230,15 @@ struct osi_rx_swcx { */ struct osi_rx_pkt_cx { /** Bit map which holds the features that rx packets supports */ - unsigned int flags; + nveu32_t flags; /** Stores the Rx csum */ - unsigned int rxcsum; + nveu32_t rxcsum; /** Stores the VLAN tag ID in received packet */ - unsigned int vlan_tag; + nveu32_t vlan_tag; /** Length of received packet */ - unsigned int pkt_len; + nveu32_t pkt_len; /** TS in nsec for the received packet */ - unsigned long long ns; + nveul64_t ns; }; /** @@ -251,11 +251,11 @@ struct osi_rx_ring { /** Pointer to Rx DMA descriptor software context information */ struct osi_rx_swcx *rx_swcx; /** Physical address of Rx DMA descriptor */ - unsigned long rx_desc_phy_addr; + nveu64_t rx_desc_phy_addr; /** Descriptor index current reception */ - unsigned int cur_rx_idx; + nveu32_t cur_rx_idx; /** Descriptor index for descriptor re-allocation */ - unsigned int refill_idx; + nveu32_t refill_idx; /** Receive packet context */ struct osi_rx_pkt_cx rx_pkt_cx; }; @@ -265,14 +265,14 @@ struct osi_rx_ring { */ struct osi_tx_swcx { /** Physical address of DMA mapped buffer */ - unsigned long buf_phy_addr; + nveu64_t buf_phy_addr; /** Virtual address of DMA buffer */ void *buf_virt_addr; /** Length of buffer */ - unsigned int len; + nveu32_t len; /** Flag to keep track of whether buffer pointed by buf_phy_addr * is a paged buffer/linear buffer */ - unsigned int is_paged_buf; + nveu32_t is_paged_buf; }; /** @@ -280,13 +280,13 @@ struct osi_tx_swcx { */ struct osi_tx_desc { /** Transmit descriptor 0 */ - unsigned int tdes0; + nveu32_t tdes0; /** Transmit descriptor 1 */ - unsigned int tdes1; + nveu32_t tdes1; /** Transmit descriptor 2 */ - unsigned int tdes2; + nveu32_t tdes2; /** Transmit descriptor 3 */ - unsigned int tdes3; + nveu32_t tdes3; }; /** @@ -295,19 +295,19 @@ struct osi_tx_desc { */ struct osi_tx_pkt_cx { /** Holds the features which a Tx packets supports */ - unsigned int flags; + nveu32_t flags; /** Stores the VLAN tag ID */ - unsigned int vtag_id; + nveu32_t vtag_id; /** Descriptor count */ - unsigned int desc_cnt; + nveu32_t desc_cnt; /** Max. segment size for TSO/USO/GSO/LSO packet */ - unsigned int mss; + nveu32_t mss; /** Length of application payload */ - unsigned int payload_len; + nveu32_t payload_len; /** Length of transport layer tcp/udp header */ - unsigned int tcp_udp_hdrlen; + nveu32_t tcp_udp_hdrlen; /** Length of all headers (ethernet/ip/tcp/udp) */ - unsigned int total_hdrlen; + nveu32_t total_hdrlen; }; /** @@ -316,10 +316,10 @@ struct osi_tx_pkt_cx { 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) */ - unsigned int flags; + nveu32_t flags; /** TS captured for the tx packet and this is valid only when the PTP * bit is set in fields */ - unsigned long long ns; + nveul64_t ns; }; /** @@ -332,21 +332,21 @@ struct osi_tx_ring { /** Pointer to tx dma descriptor software context information */ struct osi_tx_swcx *tx_swcx; /** Physical address of Tx descriptor */ - unsigned long tx_desc_phy_addr; + nveu64_t tx_desc_phy_addr; /** Descriptor index current transmission */ - unsigned int cur_tx_idx; + nveu32_t cur_tx_idx; /** Descriptor index for descriptor cleanup */ - unsigned int clean_idx; + nveu32_t clean_idx; /** Slot function check */ - unsigned int slot_check; + nveu32_t slot_check; /** Slot number */ - unsigned int 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 */ - unsigned int frame_cnt; + nveu32_t frame_cnt; }; struct osi_dma_priv_data; @@ -356,55 +356,55 @@ struct osi_dma_priv_data; */ struct osi_dma_chan_ops { /** Called to set Transmit Ring length */ - void (*set_tx_ring_len)(void *addr, unsigned int chan, - unsigned int len); + void (*set_tx_ring_len)(void *addr, nveu32_t chan, + nveu32_t len); /** Called to set Transmit Ring Base address */ - void (*set_tx_ring_start_addr)(void *addr, unsigned int chan, - unsigned long base_addr); + 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, unsigned int chan, - unsigned long tailptr); + void (*update_tx_tailptr)(void *addr, nveu32_t chan, + nveu64_t tailptr); /** Called to set Receive channel ring length */ - void (*set_rx_ring_len)(void *addr, unsigned int chan, - unsigned int len); + void (*set_rx_ring_len)(void *addr, nveu32_t chan, + nveu32_t len); /** Called to set receive channel ring base address */ - void (*set_rx_ring_start_addr)(void *addr, unsigned int chan, - unsigned long base_addr); + 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, unsigned int chan, - unsigned long tailptr); + 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, unsigned int chan); + 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, unsigned int chan); + 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, unsigned int chan); + 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, unsigned int chan); + void (*enable_chan_rx_intr)(void *addr, nveu32_t chan); /** Called to start the Tx/Rx DMA */ - void (*start_dma)(void *addr, unsigned int chan); + void (*start_dma)(void *addr, nveu32_t chan); /** Called to stop the Tx/Rx DMA */ - void (*stop_dma)(void *addr, unsigned int chan); + void (*stop_dma)(void *addr, nveu32_t chan); /** Called to initialize the DMA channel */ - int (*init_dma_channel)(struct osi_dma_priv_data *osi_dma); + 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 */ - int (*validate_regs)(struct osi_dma_priv_data *osi_dma); + 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, - unsigned int chan, - unsigned int set, - unsigned int interval); + nveu32_t chan, + nveu32_t set, + nveu32_t interval); #endif /* !OSI_STRIPPED_LIB */ /** Called to get Global DMA status */ - unsigned int (*get_global_dma_status)(void *addr); + nveu32_t (*get_global_dma_status)(void *addr); /** Called to clear VM Tx interrupt */ - void (*clear_vm_tx_intr)(void *addr, unsigned int chan); + void (*clear_vm_tx_intr)(void *addr, nveu32_t chan); /** Called to clear VM Rx interrupt */ - void (*clear_vm_rx_intr)(void *addr, unsigned int chan); + void (*clear_vm_rx_intr)(void *addr, nveu32_t chan); }; /** @@ -412,9 +412,9 @@ struct osi_dma_chan_ops { */ struct osi_vm_irq_data { /** Number of VM channels per VM IRQ */ - unsigned int num_vm_chans; + nveu32_t num_vm_chans; /** Array of VM channel list */ - unsigned int vm_chans[OSI_EQOS_MAX_NUM_CHANS]; + nveu32_t vm_chans[OSI_EQOS_MAX_NUM_CHANS]; }; /** @@ -423,20 +423,20 @@ struct osi_vm_irq_data { struct osd_dma_ops { /** DMA transmit complete callback */ void (*transmit_complete)(void *priv, void *buffer, - unsigned long dmaaddr, unsigned int len, + nveu64_t dmaaddr, nveu32_t len, void *txdone_pkt_cx); /** DMA receive packet callback */ void (*receive_packet)(void *priv, void *rxring, - unsigned int chan, unsigned int dma_buf_len, + nveu32_t chan, nveu32_t dma_buf_len, void *rxpkt_cx, void *rx_pkt_swcx); /** RX buffer reallocation callback */ - void (*realloc_buf)(void *priv, void *rxring, unsigned int chan); + void (*realloc_buf)(void *priv, void *rxring, nveu32_t chan); /**.ops_log function callback */ - void (*ops_log)(void *priv, const char *func, unsigned int line, - unsigned int level, unsigned int type, const char *err, - unsigned long long loga); + 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)(unsigned long usec); + void (*udelay)(nveu64_t usec); }; /** @@ -454,46 +454,46 @@ struct osi_dma_priv_data { /** Address of HW operations structure */ struct osi_dma_chan_ops *ops; /** MAC HW type (EQOS) */ - unsigned int mac; + nveu32_t mac; /** Number of channels enabled in MAC */ - unsigned int num_dma_chans; + nveu32_t num_dma_chans; /** Array of supported DMA channels */ - unsigned int dma_chans[OSI_EQOS_MAX_NUM_CHANS]; + nveu32_t dma_chans[OSI_EQOS_MAX_NUM_CHANS]; /** DMA Rx channel buffer length at HW level */ - unsigned int rx_buf_len; + nveu32_t rx_buf_len; /** MTU size */ - unsigned int mtu; + 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 */ - unsigned int rx_riwt; + nveu32_t rx_riwt; /** Flag which decides riwt is enabled(1) or disabled(0) */ - unsigned int use_riwt; + nveu32_t use_riwt; /** Max no of pkts to be received before triggering Rx interrupt */ - unsigned int rx_frames; + nveu32_t rx_frames; /** Flag which decides rx_frames is enabled(1) or disabled(0) */ - unsigned int use_rx_frames; + nveu32_t use_rx_frames; /** Transmit Interrupt Software Timer Count Units */ - unsigned int tx_usecs; + nveu32_t tx_usecs; /** Flag which decides Tx timer is enabled(1) or disabled(0) */ - unsigned int use_tx_usecs; + nveu32_t use_tx_usecs; /** Max no of pkts to transfer before triggering Tx interrupt */ - unsigned int tx_frames; + nveu32_t tx_frames; /** Flag which decides tx_frames is enabled(1) or disabled(0) */ - unsigned int use_tx_frames; + nveu32_t use_tx_frames; /** Flag which decides virtualization is enabled(1) or disabled(0) */ - unsigned int use_virtualization; + 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 */ - unsigned int slot_interval[OSI_EQOS_MAX_NUM_CHANS]; + nveu32_t slot_interval[OSI_EQOS_MAX_NUM_CHANS]; /** Array of DMA channel slot enabled status from DT*/ - unsigned int slot_enabled[OSI_EQOS_MAX_NUM_CHANS]; + nveu32_t slot_enabled[OSI_EQOS_MAX_NUM_CHANS]; /** number of VM IRQ's */ - unsigned int num_vm_irqs; + nveu32_t num_vm_irqs; /** Array of VM IRQ's */ struct osi_vm_irq_data irq_data[OSI_MAX_VM_IRQS]; /** DMA callback ops structure */ @@ -501,7 +501,7 @@ struct osi_dma_priv_data { /** Virtual address of reserved DMA buffer */ void *resv_buf_virt_addr; /** Physical address of reserved DMA buffer */ - unsigned long resv_buf_phy_addr; + nveu64_t resv_buf_phy_addr; }; @@ -541,8 +541,8 @@ struct osi_dma_priv_data { * @retval 0 on success * @retval -1 on failure. */ -int osi_disable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, - unsigned int chan); +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. @@ -580,8 +580,8 @@ int osi_disable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, * @retval 0 on success * @retval -1 on failure. */ -int osi_enable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, - unsigned int chan); +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. @@ -619,8 +619,8 @@ int osi_enable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, * @retval 0 on success * @retval -1 on failure. */ -int osi_disable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, - unsigned int chan); +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. @@ -658,8 +658,8 @@ int osi_disable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, * @retval 0 on success * @retval -1 on failure. */ -int osi_enable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, - unsigned int chan); +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. @@ -675,7 +675,7 @@ int osi_enable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, * * @retval status */ -unsigned int osi_get_global_dma_status(struct osi_dma_priv_data *osi_dma); +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. @@ -692,8 +692,8 @@ unsigned int osi_get_global_dma_status(struct osi_dma_priv_data *osi_dma); * @retval 0 on success * @retval -1 on failure. */ -int osi_clear_vm_tx_intr(struct osi_dma_priv_data *osi_dma, - unsigned int chan); +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. @@ -712,8 +712,8 @@ int osi_clear_vm_tx_intr(struct osi_dma_priv_data *osi_dma, * @retval 0 on success * @retval -1 on failure. */ -int osi_clear_vm_rx_intr(struct osi_dma_priv_data *osi_dma, - unsigned int chan); +nve32_t osi_clear_vm_rx_intr(struct osi_dma_priv_data *osi_dma, + nveu32_t chan); /** * @brief Start DMA @@ -749,8 +749,7 @@ int osi_clear_vm_rx_intr(struct osi_dma_priv_data *osi_dma, * @retval 0 on success * @retval -1 on failure. */ -int osi_start_dma(struct osi_dma_priv_data *osi_dma, - unsigned int chan); +nve32_t osi_start_dma(struct osi_dma_priv_data *osi_dma, nveu32_t chan); /** * @brief osi_stop_dma - Stop DMA @@ -786,8 +785,7 @@ int osi_start_dma(struct osi_dma_priv_data *osi_dma, * @retval 0 on success * @retval -1 on failure. */ -int osi_stop_dma(struct osi_dma_priv_data *osi_dma, - unsigned int chan); +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 @@ -818,7 +816,7 @@ int osi_stop_dma(struct osi_dma_priv_data *osi_dma, * * @retval "Number of available free descriptors." */ -unsigned int osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring); +nveu32_t osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring); /** * @brief osi_rx_dma_desc_init - DMA Rx descriptor init @@ -856,8 +854,8 @@ unsigned int osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring); * @retval 0 on success * @retval -1 on failure. */ -int osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, - struct osi_rx_ring *rx_ring, unsigned int chan); +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. @@ -889,7 +887,7 @@ int osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, * @retval 0 on success * @retval -1 on failure. */ -int osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma); +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 @@ -937,7 +935,7 @@ int osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma); * - De-initialization: No * */ -void osi_hw_transmit(struct osi_dma_priv_data *osi_dma, unsigned int chan); +void 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. @@ -978,8 +976,8 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi_dma, unsigned int chan); * * @returns Number of descriptors (buffers) processed. */ -int osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, - unsigned int chan, int budget); +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 @@ -1026,9 +1024,9 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, * * @returns Number of descriptors (buffers) processed. */ -int osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, - unsigned int chan, int budget, - unsigned int *more_data_avail); +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 @@ -1083,7 +1081,7 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, * @retval 0 on success * @retval -1 on failure. */ -int osi_hw_dma_init(struct osi_dma_priv_data *osi_dma); +nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma); /** * @brief osi_hw_dma_deinit - De initialize DMA @@ -1118,7 +1116,7 @@ int osi_hw_dma_init(struct osi_dma_priv_data *osi_dma); * @retval 0 on success * @retval -1 on failure. */ -int osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma); +nve32_t osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma); /** * @brief osi_init_dma_ops - Initialize DMA operations @@ -1146,7 +1144,7 @@ int osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma); * @retval 0 on success * @retval -1 on failure. */ -int osi_init_dma_ops(struct osi_dma_priv_data *osi_dma); +nve32_t osi_init_dma_ops(struct osi_dma_priv_data *osi_dma); /** * @brief osi_dma_get_systime_from_mac - Get system time @@ -1181,10 +1179,8 @@ int osi_init_dma_ops(struct osi_dma_priv_data *osi_dma); * @retval 0 on success * @retval -1 on failure. */ -int osi_dma_get_systime_from_mac( - struct osi_dma_priv_data *const osi_dma, - unsigned int *sec, - unsigned int *nsec); +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. @@ -1217,7 +1213,7 @@ int osi_dma_get_systime_from_mac( * @retval OSI_ENABLE if MAC enabled. * @retval OSI_DISABLE otherwise. */ -unsigned int osi_is_mac_enabled(struct osi_dma_priv_data *const osi_dma); +nveu32_t osi_is_mac_enabled(struct osi_dma_priv_data *const osi_dma); #ifndef OSI_STRIPPED_LIB /** @@ -1256,7 +1252,7 @@ unsigned int osi_is_mac_enabled(struct osi_dma_priv_data *const osi_dma); * @retval 0 on success * @retval -1 on failure. */ -int osi_validate_dma_regs(struct osi_dma_priv_data *osi_dma); +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. @@ -1291,7 +1287,7 @@ int osi_validate_dma_regs(struct osi_dma_priv_data *osi_dma); * @retval 0 on success * @retval -1 on failure. */ -int osi_clear_tx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); +nve32_t osi_clear_tx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); /** * @brief osi_config_slot_function - Configure slot function @@ -1324,8 +1320,8 @@ int osi_clear_tx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); * @retval 0 on success * @retval -1 on failure. */ -int osi_config_slot_function(struct osi_dma_priv_data *osi_dma, - unsigned int set); +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. * @@ -1350,7 +1346,7 @@ int osi_config_slot_function(struct osi_dma_priv_data *osi_dma, * @retval 0 on success * @retval -1 on failure. */ -int osi_clear_rx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); +nve32_t osi_clear_rx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); /** * @brief osi_txring_empty - Check if Txring is empty. @@ -1376,6 +1372,6 @@ int osi_clear_rx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); * @retval 1 if ring is empty. * @retval 0 if ring has outstanding packets. */ -int osi_txring_empty(struct osi_dma_priv_data *osi_dma, unsigned int chan); +nve32_t osi_txring_empty(struct osi_dma_priv_data *osi_dma, nveu32_t chan); #endif /* !OSI_STRIPPED_LIB */ #endif /* OSI_DMA_H */ diff --git a/include/osi_dma_txrx.h b/include/osi_dma_txrx.h index bac82f0..39605b6 100644 --- a/include/osi_dma_txrx.h +++ b/include/osi_dma_txrx.h @@ -137,8 +137,8 @@ /* VTIR = 0x2 (Insert a VLAN tag with the tag value programmed in the * MAC_VLAN_Incl register or context descriptor.) */ -#define TDES2_VTIR ((unsigned int)0x2 << 14U) -#define TDES2_TTSE ((unsigned int)0x1 << 30U) +#define TDES2_VTIR ((nveu32_t)0x2 << 14U) +#define TDES2_TTSE ((nveu32_t)0x1 << 30U) /** @} */ /** Error Summary bits for Transmitted packet */ diff --git a/osi/common/eqos_common.c b/osi/common/eqos_common.c index 9403c06..5530258 100644 --- a/osi/common/eqos_common.c +++ b/osi/common/eqos_common.c @@ -22,27 +22,27 @@ #include "eqos_common.h" -unsigned long long eqos_get_systime_from_mac(void *addr) +nveul64_t eqos_get_systime_from_mac(void *addr) { - unsigned long long ns1, ns2, ns = 0; - unsigned int varmac_stnsr, temp1; - unsigned int varmac_stsr; + nveul64_t ns1, ns2, ns = 0; + nveu32_t varmac_stnsr, temp1; + nveu32_t varmac_stsr; - varmac_stnsr = osi_readl((unsigned char *)addr + EQOS_MAC_STNSR); + varmac_stnsr = osi_readl((nveu8_t *)addr + EQOS_MAC_STNSR); temp1 = (varmac_stnsr & EQOS_MAC_STNSR_TSSS_MASK); - ns1 = (unsigned long long)temp1; + ns1 = (nveul64_t)temp1; - varmac_stsr = osi_readl((unsigned char *)addr + EQOS_MAC_STSR); + varmac_stsr = osi_readl((nveu8_t *)addr + EQOS_MAC_STSR); - varmac_stnsr = osi_readl((unsigned char *)addr + EQOS_MAC_STNSR); + varmac_stnsr = osi_readl((nveu8_t *)addr + EQOS_MAC_STNSR); temp1 = (varmac_stnsr & EQOS_MAC_STNSR_TSSS_MASK); - ns2 = (unsigned long long)temp1; + 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((unsigned char *)addr + EQOS_MAC_STSR); + 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); @@ -57,12 +57,12 @@ unsigned long long eqos_get_systime_from_mac(void *addr) return ns; } -unsigned int eqos_is_mac_enabled(void *addr) +nveu32_t eqos_is_mac_enabled(void *addr) { - unsigned int enable = OSI_DISABLE; - unsigned int reg; + nveu32_t enable = OSI_DISABLE; + nveu32_t reg; - reg = osi_readl((unsigned char *)addr + EQOS_MAC_MCR); + 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; diff --git a/osi/common/eqos_common.h b/osi/common/eqos_common.h index 4f9a2d4..8d0d0ff 100644 --- a/osi/common/eqos_common.h +++ b/osi/common/eqos_common.h @@ -60,7 +60,7 @@ * @retval 0 on success * @retval -1 on failure. */ -unsigned long long eqos_get_systime_from_mac(void *addr); +nveul64_t eqos_get_systime_from_mac(void *addr); /** * @brief eqos_is_mac_enabled - Checks if MAC is enabled or not. @@ -79,5 +79,5 @@ unsigned long long eqos_get_systime_from_mac(void *addr); * @retval OSI_ENABLE if MAC enabled. * @retval OSI_DISABLE otherwise. */ -unsigned int eqos_is_mac_enabled(void *addr); +nveu32_t eqos_is_mac_enabled(void *addr); #endif /* EQOS_COMMON_H */ diff --git a/osi/common/include/local_common.h b/osi/common/include/local_common.h index 73f1e8a..674777e 100644 --- a/osi/common/include/local_common.h +++ b/osi/common/include/local_common.h @@ -24,6 +24,7 @@ #define LOCAL_COMMON_H #include <osi_common.h> +#include "../osi/common/type.h" /** * @brief common_get_systime_from_mac - Get system time @@ -44,8 +45,8 @@ * @retval 0 on success * @retval -1 on failure. */ -void common_get_systime_from_mac(void *addr, unsigned int mac, - unsigned int *sec, unsigned int *nsec); +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. @@ -64,5 +65,5 @@ void common_get_systime_from_mac(void *addr, unsigned int mac, * @retval OSI_ENABLE if MAC enabled. * @retval OSI_DISABLE otherwise. */ -unsigned int common_is_mac_enabled(void *addr, unsigned int mac); +nveu32_t common_is_mac_enabled(void *addr, nveu32_t mac); #endif /* LOCAL_COMMON_H */ diff --git a/osi/common/osd_dummy.c b/osi/common/osd_dummy.c index a02bd9d..49bde82 100644 --- a/osi/common/osd_dummy.c +++ b/osi/common/osd_dummy.c @@ -21,36 +21,38 @@ */ #ifdef OSD_DUMMY #include <osd.h> +#include "../osi/common/type.h" -void osd_usleep_range(unsigned long umin, unsigned long umax) +void osd_usleep_range(nveu64_t umin, nveu64_t umax) { } -void osd_msleep(unsigned int msec) +void osd_msleep(nveu32_t msec) { } -void osd_udelay(unsigned long usec) +void osd_udelay(nveu64_t usec) { } -void osd_receive_packet(void *priv, void *rxring, unsigned int chan, - unsigned int dma_buf_len, void *rxpkt_cx, +void osd_receive_packet(void *priv, void *rxring, nveu32_t chan, + nveu32_t dma_buf_len, void *rxpkt_cx, void *rx_pkt_swcx) { } -void osd_transmit_complete(void *priv, void *buffer, unsigned long dmaaddr, - unsigned int len, void *txdone_pkt_cx) + +void osd_transmit_complete(void *priv, void *buffer, nveu64_t dmaaddr, + nveu32_t len, void *txdone_pkt_cx) { } void osd_log(void *priv, - const char *func, - unsigned int line, - unsigned int level, - unsigned int type, - const char *err, - unsigned long long loga) + const nve8_t *func, + nveu32_t line, + nveu32_t level, + nveu32_t type, + const nve8_t *err, + nveul64_t loga) { } #endif diff --git a/osi/common/osi_common.c b/osi/common/osi_common.c index ea75442..8346083 100644 --- a/osi/common/osi_common.c +++ b/osi/common/osi_common.c @@ -25,14 +25,14 @@ void common_get_hw_features(void *base, struct osi_hw_features *hw_feat) { - unsigned int mac_hfr0; - unsigned int mac_hfr1; - unsigned int mac_hfr2; + nveu32_t mac_hfr0; + nveu32_t mac_hfr1; + nveu32_t mac_hfr2; /* TODO: need to add HFR3 */ - mac_hfr0 = osi_readl((unsigned char *)base + EQOS_MAC_HFR0); - mac_hfr1 = osi_readl((unsigned char *)base + EQOS_MAC_HFR1); - mac_hfr2 = osi_readl((unsigned char *)base + EQOS_MAC_HFR2); + mac_hfr0 = osi_readl((nveu8_t *)base + EQOS_MAC_HFR0); + mac_hfr1 = osi_readl((nveu8_t *)base + EQOS_MAC_HFR1); + mac_hfr2 = osi_readl((nveu8_t *)base + EQOS_MAC_HFR2); hw_feat->mii_sel = ((mac_hfr0 >> 0) & EQOS_MAC_HFR0_MIISEL_MASK); @@ -108,12 +108,12 @@ void common_get_hw_features(void *base, struct osi_hw_features *hw_feat) ((mac_hfr2 >> 28U) & EQOS_MAC_HFR2_AUXSNAPNUM_MASK); } -int common_get_mac_version(void *addr, unsigned int *mac_ver) +nve32_t common_get_mac_version(void *addr, nveu32_t *mac_ver) { - unsigned int macver; - int ret = 0; + nveu32_t macver; + nve32_t ret = 0; - macver = osi_readl((unsigned char *)addr + MAC_VERSION) & + macver = osi_readl((nveu8_t *)addr + MAC_VERSION) & MAC_VERSION_SNVER_MASK; if (is_valid_mac_version(macver) == 0) { return -1; @@ -123,17 +123,17 @@ int common_get_mac_version(void *addr, unsigned int *mac_ver) return ret; } -void osi_memset(void *s, unsigned int c, unsigned long count) +void osi_memset(void *s, nveu32_t c, nveu64_t count) { - unsigned char *xs = OSI_NULL; + nveu8_t *xs = OSI_NULL; if (s == OSI_NULL) { return; } - xs = (unsigned char *)s; + xs = (nveu8_t *)s; while (count != 0UL) { if (c < OSI_UCHAR_MAX) { - *xs++ = (unsigned char)c; + *xs++ = (nveu8_t)c; } count--; } @@ -162,11 +162,10 @@ void osi_memset(void *s, unsigned int c, unsigned long count) * * @retval Quotient */ -static inline unsigned long div_u64_rem(unsigned long dividend, - unsigned long divisor, - unsigned long *remain) +static inline nveu64_t div_u64_rem(nveu64_t dividend, nveu64_t divisor, + nveu64_t *remain) { - unsigned long ret = 0; + nveu64_t ret = 0; if (divisor != 0U) { *remain = dividend % divisor; @@ -177,12 +176,12 @@ static inline unsigned long div_u64_rem(unsigned long dividend, return ret; } -void common_get_systime_from_mac(void *addr, unsigned int mac, - unsigned int *sec, unsigned int *nsec) +void common_get_systime_from_mac(void *addr, nveu32_t mac, nveu32_t *sec, + nveu32_t *nsec) { - unsigned long temp; - unsigned long remain; - unsigned long long ns; + nveu64_t temp; + nveu64_t remain; + nveul64_t ns; if (mac == OSI_MAC_HW_EQOS) { ns = eqos_get_systime_from_mac(addr); @@ -191,20 +190,20 @@ void common_get_systime_from_mac(void *addr, unsigned int mac, return; } - temp = div_u64_rem((unsigned long)ns, OSI_NSEC_PER_SEC, &remain); + temp = div_u64_rem((nveu64_t)ns, OSI_NSEC_PER_SEC, &remain); if (temp < UINT_MAX) { - *sec = (unsigned int) temp; + *sec = (nveu32_t)temp; } else { /* do nothing here */ } if (remain < UINT_MAX) { - *nsec = (unsigned int)remain; + *nsec = (nveu32_t)remain; } else { /* do nothing here */ } } -unsigned int common_is_mac_enabled(void *addr, unsigned int mac) +nveu32_t common_is_mac_enabled(void *addr, nveu32_t mac) { if (mac == OSI_MAC_HW_EQOS) { return eqos_is_mac_enabled(addr); diff --git a/osi/common/type.h b/osi/common/type.h new file mode 100644 index 0000000..da558bd --- /dev/null +++ b/osi/common/type.h @@ -0,0 +1,47 @@ +/* + * 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 + +/* Following added to avoid misraC 4.6 + * Here we are defining intermediate type + */ +typedef unsigned int my_uint32_t; +typedef int my_int32_t; +typedef char my_int8_t; +typedef unsigned char my_uint8_t; +typedef unsigned short my_uint16_t; +typedef unsigned long long my_ulint_64; +typedef long long my_lint_64; +typedef unsigned long my_uint64_t; + +/* Actual type used in code */ +typedef my_uint32_t nveu32_t; +typedef my_int32_t nve32_t; +typedef my_int8_t nve8_t; +typedef my_uint8_t nveu8_t; +typedef my_uint16_t nveu16_t; +typedef my_ulint_64 nveul64_t; +typedef my_lint_64 nvel64_t; +typedef my_uint64_t nveu64_t; +#endif diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 9eeaa95..63b5da0 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -55,8 +55,8 @@ static struct core_func_safety eqos_core_safety_config; * - Run time: Yes * - De-initialization: Yes */ -static inline void eqos_core_safety_writel(unsigned int val, void *addr, - unsigned int idx) +static inline void eqos_core_safety_writel(nveu32_t val, void *addr, + nveu32_t idx) { struct core_func_safety *config = &eqos_core_safety_config; @@ -89,9 +89,9 @@ static inline void eqos_core_safety_writel(unsigned int val, void *addr, static void eqos_core_safety_init(struct osi_core_priv_data *const osi_core) { struct core_func_safety *config = &eqos_core_safety_config; - unsigned char *base = (unsigned char *)osi_core->base; - unsigned int val; - unsigned int i, idx; + 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. @@ -104,7 +104,8 @@ static void eqos_core_safety_init(struct osi_core_priv_data *const osi_core) 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_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); @@ -180,7 +181,7 @@ static void eqos_core_safety_init(struct osi_core_priv_data *const osi_core) if (config->reg_addr[i] == OSI_NULL) { continue; } - val = osi_readl((unsigned char *)config->reg_addr[i]); + val = osi_readl((nveu8_t *)config->reg_addr[i]); config->reg_val[i] = val & config->reg_mask[i]; } @@ -208,8 +209,8 @@ static void eqos_core_safety_init(struct osi_core_priv_data *const osi_core) static void eqos_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; + 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; @@ -328,10 +329,11 @@ static void eqos_core_backup_init(struct osi_core_priv_data *const osi_core) * @retval 0 on success * @retval -1 on failure. */ -static int eqos_config_flow_control(struct osi_core_priv_data *const osi_core, - const unsigned int flw_ctrl) +static nve32_t eqos_config_flow_control( + struct osi_core_priv_data *const osi_core, + const nveu32_t flw_ctrl) { - unsigned int val; + nveu32_t val; void *addr = osi_core->base; /* return on invalid argument */ @@ -343,7 +345,7 @@ static int eqos_config_flow_control(struct osi_core_priv_data *const osi_core, /* Configure MAC Tx Flow control */ /* Read MAC Tx Flow control Register of Q0 */ - val = osi_readl((unsigned char *)addr + EQOS_MAC_QX_TX_FLW_CTRL(0U)); + val = osi_readl((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 @@ -360,13 +362,13 @@ static int eqos_config_flow_control(struct osi_core_priv_data *const osi_core, } /* Write to MAC Tx Flow control Register of Q0 */ - eqos_core_safety_writel(val, (unsigned char *)addr + + eqos_core_safety_writel(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_readl((unsigned char *)addr + EQOS_MAC_RX_FLW_CTRL); + val = osi_readl((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 @@ -380,7 +382,7 @@ static int eqos_config_flow_control(struct osi_core_priv_data *const osi_core, } /* Write to MAC Rx Flow control Register */ - osi_writel(val, (unsigned char *)addr + EQOS_MAC_RX_FLW_CTRL); + osi_writel(val, (nveu8_t *)addr + EQOS_MAC_RX_FLW_CTRL); return 0; } @@ -410,12 +412,13 @@ static int eqos_config_flow_control(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_config_fw_err_pkts(struct osi_core_priv_data *const osi_core, - const unsigned int qinx, - const unsigned int fw_err) +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; - unsigned int val; + nveu32_t val; /* Check for valid fw_err and qinx values */ if ((fw_err != OSI_ENABLE && fw_err != OSI_DISABLE) || @@ -426,7 +429,7 @@ static int eqos_config_fw_err_pkts(struct osi_core_priv_data *const osi_core, } /* Read MTL RXQ Operation_Mode Register */ - val = osi_readl((unsigned char *)addr + EQOS_MTL_CHX_RX_OP_MODE(qinx)); + val = osi_readl((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) { @@ -446,7 +449,7 @@ static int eqos_config_fw_err_pkts(struct osi_core_priv_data *const osi_core, /* 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(val, (unsigned char *)addr + + eqos_core_safety_writel(val, (nveu8_t *)addr + EQOS_MTL_CHX_RX_OP_MODE(qinx), EQOS_MTL_CH0_RX_OP_MODE_IDX + qinx); @@ -475,17 +478,17 @@ static int eqos_config_fw_err_pkts(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_poll_for_swr(struct osi_core_priv_data *const osi_core, - unsigned int pre_si) +static nve32_t eqos_poll_for_swr(struct osi_core_priv_data *const osi_core, + nve32_t pre_si) { void *addr = osi_core->base; - unsigned int retry = 1000; - unsigned int count; - unsigned int dma_bmr = 0; - int cond = 1; + nveu32_t retry = 1000; + nveu32_t count; + nveu32_t dma_bmr = 0; + nve32_t cond = 1; if (pre_si == OSI_ENABLE) { - osi_writel(0x1U, (unsigned char *)addr + EQOS_DMA_BMR); + osi_writel(0x1U, (nveu8_t *)addr + EQOS_DMA_BMR); } /* add delay of 10 usec */ osi_core->osd_ops.usleep_range(9, 11); @@ -501,7 +504,7 @@ static int eqos_poll_for_swr(struct osi_core_priv_data *const osi_core, count++; - dma_bmr = osi_readl((unsigned char *)addr + EQOS_DMA_BMR); + dma_bmr = osi_readl((nveu8_t *)addr + EQOS_DMA_BMR); if ((dma_bmr & EQOS_DMA_BMR_SWR) == 0U) { cond = 0; } else { @@ -531,11 +534,11 @@ static int eqos_poll_for_swr(struct osi_core_priv_data *const osi_core, * * @pre MAC should be initialized and started. see osi_start_mac() */ -static void eqos_set_speed(void *base, const int speed) +static void eqos_set_speed(void *base, const nve32_t speed) { - unsigned int mcr_val; + nveu32_t mcr_val; - mcr_val = osi_readl((unsigned char *)base + EQOS_MAC_MCR); + mcr_val = osi_readl((nveu8_t *)base + EQOS_MAC_MCR); switch (speed) { default: mcr_val &= ~EQOS_MCR_PS; @@ -555,7 +558,7 @@ static void eqos_set_speed(void *base, const int speed) break; } - eqos_core_safety_writel(mcr_val, (unsigned char *)base + EQOS_MAC_MCR, + eqos_core_safety_writel(mcr_val, (nveu8_t *)base + EQOS_MAC_MCR, EQOS_MAC_MCR_IDX); } @@ -581,13 +584,13 @@ static void eqos_set_speed(void *base, const int speed) * @retval 0 on success * @retval -1 on failure. */ -static int eqos_set_mode(struct osi_core_priv_data *const osi_core, - const int mode) +static nve32_t eqos_set_mode(struct osi_core_priv_data *const osi_core, + const nve32_t mode) { void *base = osi_core->base; - unsigned int mcr_val; + nveu32_t mcr_val; - mcr_val = osi_readl((unsigned char *)base + EQOS_MAC_MCR); + mcr_val = osi_readl((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 */ @@ -602,7 +605,7 @@ static int eqos_set_mode(struct osi_core_priv_data *const osi_core, return -1; /* Nothing here */ } - eqos_core_safety_writel(mcr_val, (unsigned char *)base + EQOS_MAC_MCR, + eqos_core_safety_writel(mcr_val, (nveu8_t *)base + EQOS_MAC_MCR, EQOS_MAC_MCR_IDX); return 0; } @@ -629,11 +632,11 @@ static int eqos_set_mode(struct osi_core_priv_data *const osi_core, * * @retval Queue size that need to be programmed. */ -static unsigned int eqos_calculate_per_queue_fifo(unsigned int fifo_size, - unsigned int queue_count) +static nveu32_t eqos_calculate_per_queue_fifo(nveu32_t fifo_size, + nveu32_t queue_count) { - unsigned int q_fifo_size = 0; /* calculated fifo size per queue */ - unsigned int p_fifo = EQOS_256; /* per queue fifo size program value */ + 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; @@ -740,20 +743,20 @@ static unsigned int eqos_calculate_per_queue_fifo(unsigned int fifo_size, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_pad_calibrate(struct osi_core_priv_data *const osi_core) +static nve32_t eqos_pad_calibrate(struct osi_core_priv_data *const osi_core) { void *ioaddr = osi_core->base; - unsigned int retry = 1000; - unsigned int count; - int cond = 1, ret = 0; - unsigned int value; + nveu32_t retry = 1000; + nveu32_t count; + nve32_t cond = 1, ret = 0; + nveu32_t value; /* 1. Set field PAD_E_INPUT_OR_E_PWRD in * reg ETHER_QOS_SDMEMCOMPPADCTRL_0 */ - value = osi_readl((unsigned char *)ioaddr + EQOS_PAD_CRTL); + value = osi_readl((nveu8_t *)ioaddr + EQOS_PAD_CRTL); value |= EQOS_PAD_CRTL_E_INPUT_OR_E_PWRD; - osi_writel(value, (unsigned char *)ioaddr + EQOS_PAD_CRTL); + osi_writel(value, (nveu8_t *)ioaddr + EQOS_PAD_CRTL); /* 2. delay for 1 usec */ osi_core->osd_ops.usleep_range(1, 3); @@ -761,10 +764,10 @@ static int eqos_pad_calibrate(struct osi_core_priv_data *const osi_core) /* 3. Set AUTO_CAL_ENABLE and AUTO_CAL_START in * reg ETHER_QOS_AUTO_CAL_CONFIG_0. */ - value = osi_readl((unsigned char *)ioaddr + EQOS_PAD_AUTO_CAL_CFG); + value = osi_readl((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(value, (unsigned char *)ioaddr + + eqos_core_safety_writel(value, (nveu8_t *)ioaddr + EQOS_PAD_AUTO_CAL_CFG, EQOS_PAD_AUTO_CAL_CFG_IDX); @@ -781,7 +784,7 @@ static int eqos_pad_calibrate(struct osi_core_priv_data *const osi_core) } count++; osi_core->osd_ops.usleep_range(10, 12); - value = osi_readl((unsigned char *)ioaddr + + value = osi_readl((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) { @@ -793,9 +796,9 @@ calibration_failed: /* 6. Re-program the value PAD_E_INPUT_OR_E_PWRD in * ETHER_QOS_SDMEMCOMPPADCTRL_0 to save power */ - value = osi_readl((unsigned char *)ioaddr + EQOS_PAD_CRTL); + value = osi_readl((nveu8_t *)ioaddr + EQOS_PAD_CRTL); value &= ~EQOS_PAD_CRTL_E_INPUT_OR_E_PWRD; - osi_writel(value, (unsigned char *)ioaddr + EQOS_PAD_CRTL); + osi_writel(value, (nveu8_t *)ioaddr + EQOS_PAD_CRTL); return ret; } @@ -819,14 +822,15 @@ calibration_failed: * @retval 0 on success * @retval -1 on failure. */ -static int eqos_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, - const unsigned int qinx) +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; - unsigned int retry = 1000; - unsigned int count; - unsigned int value; - int cond = 1; + nveu32_t retry = 1000; + nveu32_t count; + nveu32_t value; + nve32_t cond = 1; if (qinx >= OSI_EQOS_MAX_NUM_QUEUES) { OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, @@ -835,10 +839,10 @@ static int eqos_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, } /* Read Tx Q Operating Mode Register and flush TxQ */ - value = osi_readl((unsigned char *)addr + + value = osi_readl((nveu8_t *)addr + EQOS_MTL_CHX_TX_OP_MODE(qinx)); value |= EQOS_MTL_QTOMR_FTQ; - eqos_core_safety_writel(value, (unsigned char *)addr + + eqos_core_safety_writel(value, (nveu8_t *)addr + EQOS_MTL_CHX_TX_OP_MODE(qinx), EQOS_MTL_CH0_TX_OP_MODE_IDX + qinx); @@ -854,7 +858,7 @@ static int eqos_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, count++; osi_core->osd_ops.msleep(1); - value = osi_readl((unsigned char *)addr + + value = osi_readl((nveu8_t *)addr + EQOS_MTL_CHX_TX_OP_MODE(qinx)); if ((value & EQOS_MTL_QTOMR_FTQ_LPOS) == 0U) { @@ -883,7 +887,7 @@ static int eqos_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, * @param[in] rx_fifo: Rx FIFO size. * @param[out] value: Stores RFD and RSA values */ -void update_ehfc_rfa_rfd(unsigned int rx_fifo, unsigned int *value) +void update_ehfc_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value) { if (rx_fifo >= EQOS_4K) { /* Enable HW Flow Control */ @@ -997,13 +1001,13 @@ void update_ehfc_rfa_rfd(unsigned int rx_fifo, unsigned int *value) * @retval 0 on success * @retval -1 on failure. */ -static int eqos_configure_mtl_queue(unsigned int qinx, +static nve32_t eqos_configure_mtl_queue(nveu32_t qinx, struct osi_core_priv_data *const osi_core, - unsigned int tx_fifo, - unsigned int rx_fifo) + nveu32_t tx_fifo, + nveu32_t rx_fifo) { - unsigned int value = 0; - int ret = 0; + nveu32_t value = 0; + nve32_t ret = 0; ret = eqos_flush_mtl_tx_queue(osi_core, qinx); if (ret < 0) { @@ -1015,12 +1019,12 @@ static int eqos_configure_mtl_queue(unsigned int qinx, value |= EQOS_MTL_TSF; /* Enable TxQ */ value |= EQOS_MTL_TXQEN; - eqos_core_safety_writel(value, (unsigned char *)osi_core->base + + eqos_core_safety_writel(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_readl((unsigned char *)osi_core->base + + value = osi_readl((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 */ @@ -1031,23 +1035,23 @@ static int eqos_configure_mtl_queue(unsigned int qinx, * RFD: Threshold for Deactivating Flow Control */ update_ehfc_rfa_rfd(rx_fifo, &value); - eqos_core_safety_writel(value, (unsigned char *)osi_core->base + + eqos_core_safety_writel(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_readl((unsigned char *)osi_core->base + + value = osi_readl((nveu8_t *)osi_core->base + EQOS_MTL_TXQ_QW(qinx)); value |= (EQOS_MTL_TXQ_QW_ISCQW + qinx); - eqos_core_safety_writel(value, (unsigned char *)osi_core->base + + eqos_core_safety_writel(value, (nveu8_t *)osi_core->base + EQOS_MTL_TXQ_QW(qinx), EQOS_MTL_TXQ0_QW_IDX + qinx); /* Enable Rx Queue Control */ - value = osi_readl((unsigned char *)osi_core->base + + value = osi_readl((nveu8_t *)osi_core->base + EQOS_MAC_RQC0R); value |= ((osi_core->rxq_ctrl[qinx] & 0x3U) << (qinx * 2U)); - eqos_core_safety_writel(value, (unsigned char *)osi_core->base + + eqos_core_safety_writel(value, (nveu8_t *)osi_core->base + EQOS_MAC_RQC0R, EQOS_MAC_RQC0R_IDX); return 0; @@ -1076,11 +1080,12 @@ static int eqos_configure_mtl_queue(unsigned int qinx, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_config_rxcsum_offload(struct osi_core_priv_data *const osi_core, - const unsigned int enabled) +static nve32_t eqos_config_rxcsum_offload( + struct osi_core_priv_data *const osi_core, + const nveu32_t enabled) { void *addr = osi_core->base; - unsigned int mac_mcr; + nveu32_t mac_mcr; if (enabled != OSI_ENABLE && enabled != OSI_DISABLE) { OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, @@ -1088,7 +1093,7 @@ static int eqos_config_rxcsum_offload(struct osi_core_priv_data *const osi_core, return -1; } - mac_mcr = osi_readl((unsigned char *)addr + EQOS_MAC_MCR); + mac_mcr = osi_readl((nveu8_t *)addr + EQOS_MAC_MCR); if (enabled == OSI_ENABLE) { mac_mcr |= EQOS_MCR_IPC; @@ -1096,7 +1101,7 @@ static int eqos_config_rxcsum_offload(struct osi_core_priv_data *const osi_core, mac_mcr &= ~EQOS_MCR_IPC; } - eqos_core_safety_writel(mac_mcr, (unsigned char *)addr + EQOS_MAC_MCR, + eqos_core_safety_writel(mac_mcr, (nveu8_t *)addr + EQOS_MAC_MCR, EQOS_MAC_MCR_IDX); return 0; @@ -1126,16 +1131,16 @@ static int eqos_config_rxcsum_offload(struct osi_core_priv_data *const osi_core, * - De-initialization: No */ static void eqos_configure_rxq_priority( - struct osi_core_priv_data *const osi_core) + struct osi_core_priv_data *const osi_core) { - unsigned int val; - unsigned int temp; - unsigned int qinx, mtlq; - unsigned int pmask = 0x0U; - unsigned int mfix_var1, mfix_var2; + 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_writel(OSI_DISABLE, (unsigned char *)osi_core->base + + osi_writel(OSI_DISABLE, (nveu8_t *)osi_core->base + EQOS_MAC_RQC2R); for (qinx = 0; qinx < osi_core->num_mtl_queues; qinx++) { @@ -1149,24 +1154,24 @@ static void eqos_configure_rxq_priority( } else { OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid rxq Priority for Q\n", - (unsigned long long)mtlq); + (nveul64_t)mtlq); continue; } - val = osi_readl((unsigned char *)osi_core->base + + val = osi_readl((nveu8_t *)osi_core->base + EQOS_MAC_RQC2R); - mfix_var1 = mtlq * (unsigned int)EQOS_MAC_RQC2_PSRQ_SHIFT; - mfix_var2 = (unsigned int)EQOS_MAC_RQC2_PSRQ_MASK; + 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 * (unsigned int)EQOS_MAC_RQC2_PSRQ_SHIFT; - mfix_var2 = (unsigned int)EQOS_MAC_RQC2_PSRQ_MASK; + 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(val, (unsigned char *)osi_core->base + + eqos_core_safety_writel(val, (nveu8_t *)osi_core->base + EQOS_MAC_RQC2R, EQOS_MAC_RQC2R_IDX); } } @@ -1197,25 +1202,25 @@ static void eqos_configure_rxq_priority( */ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) { - unsigned int value; - unsigned int mac_ext; + nveu32_t value; + nveu32_t mac_ext; /* Update MAC address 0 high */ - value = (((unsigned int)osi_core->mac_addr[5] << 8U) | - ((unsigned int)osi_core->mac_addr[4])); - eqos_core_safety_writel(value, (unsigned char *)osi_core->base + + value = (((nveu32_t)osi_core->mac_addr[5] << 8U) | + ((nveu32_t)osi_core->mac_addr[4])); + eqos_core_safety_writel(value, (nveu8_t *)osi_core->base + EQOS_MAC_MA0HR, EQOS_MAC_MA0HR_IDX); /* Update MAC address 0 Low */ - value = (((unsigned int)osi_core->mac_addr[3] << 24U) | - ((unsigned int)osi_core->mac_addr[2] << 16U) | - ((unsigned int)osi_core->mac_addr[1] << 8U) | - ((unsigned int)osi_core->mac_addr[0])); - eqos_core_safety_writel(value, (unsigned char *)osi_core->base + + value = (((nveu32_t)osi_core->mac_addr[3] << 24U) | + ((nveu32_t)osi_core->mac_addr[2] << 16U) | + ((nveu32_t)osi_core->mac_addr[1] << 8U) | + ((nveu32_t)osi_core->mac_addr[0])); + eqos_core_safety_writel(value, (nveu8_t *)osi_core->base + EQOS_MAC_MA0LR, EQOS_MAC_MA0LR_IDX); /* Read MAC Configuration Register */ - value = osi_readl((unsigned char *)osi_core->base + EQOS_MAC_MCR); + value = osi_readl((nveu8_t *)osi_core->base + EQOS_MAC_MCR); /* Enable Automatic Pad or CRC Stripping */ /* Enable CRC stripping for Type packets */ /* Enable Full Duplex mode */ @@ -1232,58 +1237,58 @@ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) value |= EQOS_MCR_JD | EQOS_MCR_WD; value |= EQOS_MCR_GPSLCE; /* Read MAC Extension Register */ - mac_ext = osi_readl((unsigned char *)osi_core->base + + mac_ext = osi_readl((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_writel(mac_ext, (unsigned char *)osi_core->base + + osi_writel(mac_ext, (nveu8_t *)osi_core->base + EQOS_MAC_EXTR); } else { /* do nothing for default mtu size */ } - eqos_core_safety_writel(value, (unsigned char *)osi_core->base + + eqos_core_safety_writel(value, (nveu8_t *)osi_core->base + EQOS_MAC_MCR, EQOS_MAC_MCR_IDX); /* Enable Multicast and Broadcast Queue, default is Q0 */ - value = osi_readl((unsigned char *)osi_core->base + EQOS_MAC_RQC1R); + value = osi_readl((nveu8_t *)osi_core->base + EQOS_MAC_RQC1R); value |= EQOS_MAC_RQC1R_MCBCQEN; /* Routing Multicast and Broadcast to Q1 */ value |= EQOS_MAC_RQC1R_MCBCQ1; - eqos_core_safety_writel(value, (unsigned char *)osi_core->base + + eqos_core_safety_writel(value, (nveu8_t *)osi_core->base + EQOS_MAC_RQC1R, EQOS_MAC_RQC1R_IDX); /* Disable all MMC interrupts */ /* Disable all MMC Tx Interrupts */ - osi_writel(0xFFFFFFFFU, (unsigned char *)osi_core->base + + osi_writel(0xFFFFFFFFU, (nveu8_t *)osi_core->base + EQOS_MMC_TX_INTR_MASK); /* Disable all MMC RX interrupts */ - osi_writel(0xFFFFFFFFU, (unsigned char *)osi_core->base + + osi_writel(0xFFFFFFFFU, (nveu8_t *)osi_core->base + EQOS_MMC_RX_INTR_MASK); /* Disable MMC Rx interrupts for IPC */ - osi_writel(0xFFFFFFFFU, (unsigned char *)osi_core->base + + osi_writel(0xFFFFFFFFU, (nveu8_t *)osi_core->base + EQOS_MMC_IPC_RX_INTR_MASK); /* Configure MMC counters */ - value = osi_readl((unsigned char *)osi_core->base + EQOS_MMC_CNTRL); + value = osi_readl((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_writel(value, (unsigned char *)osi_core->base + EQOS_MMC_CNTRL); + osi_writel(value, (nveu8_t *)osi_core->base + EQOS_MMC_CNTRL); /* Enable MAC interrupts */ /* Read MAC IMR Register */ - value = osi_readl((unsigned char *)osi_core->base + EQOS_MAC_IMR); + value = osi_readl((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(value, (unsigned char *)osi_core->base + + eqos_core_safety_writel(value, (nveu8_t *)osi_core->base + EQOS_MAC_IMR, EQOS_MAC_IMR_IDX); /* Enable VLAN configuration */ - value = osi_readl((unsigned char *)osi_core->base + EQOS_MAC_VLAN_TAG); + value = osi_readl((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 @@ -1295,14 +1300,14 @@ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) } value |= EQOS_MAC_VLANTR_EVLRXS | EQOS_MAC_VLANTR_DOVLTC; value &= ~EQOS_MAC_VLANTR_ERIVLT; - osi_writel(value, (unsigned char *)osi_core->base + EQOS_MAC_VLAN_TAG); + osi_writel(value, (nveu8_t *)osi_core->base + EQOS_MAC_VLAN_TAG); - value = osi_readl((unsigned char *)osi_core->base + EQOS_MAC_VLANTIR); + value = osi_readl((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_writel(value, (unsigned char *)osi_core->base + EQOS_MAC_VLANTIR); + osi_writel(value, (nveu8_t *)osi_core->base + EQOS_MAC_VLANTIR); /* Configure default flow control settings */ if (osi_core->pause_frames == OSI_PAUSE_FRAMES_ENABLE) { @@ -1343,7 +1348,7 @@ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) */ static void eqos_configure_dma(void *base) { - unsigned int value = 0; + nveu32_t value = 0; /* AXI Burst Length 8*/ value |= EQOS_DMA_SBUS_BLEN8; @@ -1356,12 +1361,12 @@ static void eqos_configure_dma(void *base) /* AXI Maximum Write Outstanding Request Limit = 31 */ value |= EQOS_DMA_SBUS_WR_OSR_LMT; - eqos_core_safety_writel(value, (unsigned char *)base + EQOS_DMA_SBUS, + eqos_core_safety_writel(value, (nveu8_t *)base + EQOS_DMA_SBUS, EQOS_DMA_SBUS_IDX); - value = osi_readl((unsigned char *)base + EQOS_DMA_BMR); + value = osi_readl((nveu8_t *)base + EQOS_DMA_BMR); value |= EQOS_DMA_BMR_DPSW; - osi_writel(value, (unsigned char *)base + EQOS_DMA_BMR); + osi_writel(value, (nveu8_t *)base + EQOS_DMA_BMR); } /** @@ -1392,15 +1397,15 @@ static void eqos_configure_dma(void *base) * @retval 0 on success * @retval -1 on failure. */ -static int eqos_core_init(struct osi_core_priv_data *const osi_core, - const unsigned int tx_fifo_size, - const unsigned int rx_fifo_size) +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) { - int ret = 0; - unsigned int qinx = 0; - unsigned int value = 0; - unsigned int tx_fifo = 0; - unsigned int rx_fifo = 0; + nve32_t ret = 0; + nveu32_t qinx = 0; + nveu32_t value = 0; + nveu32_t tx_fifo = 0; + nveu32_t rx_fifo = 0; eqos_core_safety_init(osi_core); eqos_core_backup_init(osi_core); @@ -1415,17 +1420,17 @@ static int eqos_core_init(struct osi_core_priv_data *const osi_core, } /* reset mmc counters */ - osi_writel(EQOS_MMC_CNTRL_CNTRST, (unsigned char *)osi_core->base + + osi_writel(EQOS_MMC_CNTRL_CNTRST, (nveu8_t *)osi_core->base + EQOS_MMC_CNTRL); /* AXI ASID CTRL for channel 0 to 3 */ osi_writel(EQOS_AXI_ASID_CTRL_VAL, - (unsigned char *)osi_core->base + EQOS_AXI_ASID_CTRL); + (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_writel(EQOS_AXI_ASID1_CTRL_VAL, - (unsigned char *)osi_core->base + + (nveu8_t *)osi_core->base + EQOS_AXI_ASID1_CTRL); } @@ -1437,7 +1442,7 @@ static int eqos_core_init(struct osi_core_priv_data *const osi_core, value = EQOS_RXQ_TO_DMA_CHAN_MAP; } - eqos_core_safety_writel(value, (unsigned char *)osi_core->base + + eqos_core_safety_writel(value, (nveu8_t *)osi_core->base + EQOS_MTL_RXQ_DMA_MAP0, EQOS_MTL_RXQ_DMA_MAP0_IDX); @@ -1501,14 +1506,14 @@ static int eqos_core_init(struct osi_core_priv_data *const osi_core, * - De-initialization: No */ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, - unsigned int dma_isr) + nveu32_t dma_isr) { - unsigned int mac_imr = 0; - unsigned int mac_pcs = 0; - unsigned int mac_isr = 0; - int ret = 0; + nveu32_t mac_imr = 0; + nveu32_t mac_pcs = 0; + nveu32_t mac_isr = 0; + nve32_t ret = 0; - mac_isr = osi_readl((unsigned char *)osi_core->base + EQOS_MAC_ISR); + mac_isr = osi_readl((nveu8_t *)osi_core->base + EQOS_MAC_ISR); /* Handle MAC interrupts */ if ((dma_isr & EQOS_DMA_ISR_MACIS) != EQOS_DMA_ISR_MACIS) { @@ -1516,14 +1521,14 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, } /* handle only those MAC interrupts which are enabled */ - mac_imr = osi_readl((unsigned char *)osi_core->base + EQOS_MAC_IMR); + mac_imr = osi_readl((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) { return; } - mac_pcs = osi_readl((unsigned char *)osi_core->base + EQOS_MAC_PCS); + mac_pcs = osi_readl((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; @@ -1578,10 +1583,10 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, * - De-initialization: No */ static inline void update_dma_sr_stats( - struct osi_core_priv_data *const osi_core, - unsigned int dma_sr, unsigned int qinx) + struct osi_core_priv_data *const osi_core, + nveu32_t dma_sr, nveu32_t qinx) { - unsigned long val; + 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]; @@ -1635,13 +1640,13 @@ static inline void update_dma_sr_stats( static void eqos_handle_common_intr(struct osi_core_priv_data *const 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; + nveu32_t dma_isr = 0; + nveu32_t qinx = 0; + nveu32_t i = 0; + nveu32_t dma_sr = 0; + nveu32_t dma_ier = 0; - dma_isr = osi_readl((unsigned char *)base + EQOS_DMA_ISR); + dma_isr = osi_readl((nveu8_t *)base + EQOS_DMA_ISR); if (dma_isr == 0U) { return; } @@ -1657,10 +1662,10 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *const osi_core) } /* read dma channel status register */ - dma_sr = osi_readl((unsigned char *)base + + dma_sr = osi_readl((nveu8_t *)base + EQOS_DMA_CHX_STATUS(qinx)); /* read dma channel interrupt enable register */ - dma_ier = osi_readl((unsigned char *)base + + dma_ier = osi_readl((nveu8_t *)base + EQOS_DMA_CHX_IER(qinx)); /* process only those interrupts which we @@ -1675,7 +1680,7 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *const osi_core) } /* ack non ti/ri ints */ - osi_writel(dma_sr, (unsigned char *)base + + osi_writel(dma_sr, (nveu8_t *)base + EQOS_DMA_CHX_STATUS(qinx)); update_dma_sr_stats(osi_core, dma_sr, qinx); } @@ -1705,13 +1710,13 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *const osi_core) */ static void eqos_start_mac(void *addr) { - unsigned int value; + nveu32_t value; - value = osi_readl((unsigned char *)addr + EQOS_MAC_MCR); + value = osi_readl((nveu8_t *)addr + EQOS_MAC_MCR); /* Enable MAC Transmit */ /* Enable MAC Receive */ value |= EQOS_MCR_TE | EQOS_MCR_RE; - eqos_core_safety_writel(value, (unsigned char *)addr + EQOS_MAC_MCR, + eqos_core_safety_writel(value, (nveu8_t *)addr + EQOS_MAC_MCR, EQOS_MAC_MCR_IDX); } @@ -1734,14 +1739,14 @@ static void eqos_start_mac(void *addr) */ static void eqos_stop_mac(void *addr) { - unsigned int value; + nveu32_t value; - value = osi_readl((unsigned char *)addr + EQOS_MAC_MCR); + value = osi_readl((nveu8_t *)addr + EQOS_MAC_MCR); /* Disable MAC Transmit */ /* Disable MAC Receive */ value &= ~EQOS_MCR_TE; value &= ~EQOS_MCR_RE; - eqos_core_safety_writel(value, (unsigned char *)addr + EQOS_MAC_MCR, + eqos_core_safety_writel(value, (nveu8_t *)addr + EQOS_MAC_MCR, EQOS_MAC_MCR_IDX); } @@ -1767,18 +1772,18 @@ static void eqos_stop_mac(void *addr) * * @retval 0 always */ -static inline int eqos_config_l2_da_perfect_inverse_match(void *base, - unsigned int +static inline nve32_t eqos_config_l2_da_perfect_inverse_match(void *base, + nveu32_t perfect_inverse_match) { - unsigned int value = 0U; + nveu32_t value = 0U; - value = osi_readl((unsigned char *)base + EQOS_MAC_PFR); + value = osi_readl((nveu8_t *)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(value, (unsigned char *)base + EQOS_MAC_PFR, + eqos_core_safety_writel(value, (nveu8_t *)base + EQOS_MAC_PFR, EQOS_MAC_PFR_IDX); return 0; @@ -1806,14 +1811,14 @@ static inline int eqos_config_l2_da_perfect_inverse_match(void *base, * * @retval 0 always */ -static int eqos_config_mac_pkt_filter_reg( +static nve32_t eqos_config_mac_pkt_filter_reg( struct osi_core_priv_data *const osi_core, const struct osi_filter *filter) { - unsigned int value = 0U; - int ret = 0; + nveu32_t value = 0U; + nve32_t ret = 0; - value = osi_readl((unsigned char *)osi_core->base + EQOS_MAC_PFR); + value = osi_readl((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 | @@ -1844,7 +1849,7 @@ static int eqos_config_mac_pkt_filter_reg( } - eqos_core_safety_writel(value, (unsigned char *)osi_core->base + + eqos_core_safety_writel(value, (nveu8_t *)osi_core->base + EQOS_MAC_PFR, EQOS_MAC_PFR_IDX); if ((filter->oper_mode & OSI_OPER_EN_L2_DA_INV) != 0x0U) { @@ -1870,7 +1875,7 @@ static int eqos_config_mac_pkt_filter_reg( * dsc_en status performed before updating DCS bits. * * @param[in] osi_core: OSI core private data structure. - * @param[out] value: unsigned int pointer which has value read from register. + * @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 @@ -1894,15 +1899,15 @@ static int eqos_config_mac_pkt_filter_reg( * @retval 0 on success * @retval -1 on failure. */ -static inline int eqos_update_mac_addr_helper( +static inline nve32_t eqos_update_mac_addr_helper( struct osi_core_priv_data *const osi_core, - unsigned int *value, - const unsigned int idx, - const unsigned int dma_routing_enable, - const unsigned int dma_chan, - const unsigned int addr_mask) + nveu32_t *value, + const nveu32_t idx, + const nveu32_t dma_routing_enable, + const nveu32_t dma_chan, + const nveu32_t addr_mask) { - int ret = 0; + nve32_t ret = 0; /* PDC bit of MAC_Ext_Configuration register is not set so binary * value representation. */ @@ -1914,7 +1919,7 @@ static inline int eqos_update_mac_addr_helper( } else if (dma_chan > OSI_EQOS_MAX_NUM_CHANS - 0x1U) { OSI_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, "invalid dma channel\n", - (unsigned long long)dma_chan); + (nveul64_t)dma_chan); ret = -1; goto err_dma_chan; } else { @@ -1967,18 +1972,18 @@ err_dma_chan: * @retval 0 on success * @retval -1 on failure. */ -static int eqos_update_mac_addr_low_high_reg( +static nve32_t eqos_update_mac_addr_low_high_reg( struct osi_core_priv_data *const osi_core, const struct osi_filter *filter) { - unsigned int idx = filter->index; - unsigned int dma_routing_enable = filter->dma_routing; - unsigned int dma_chan = filter->dma_chan; - unsigned int addr_mask = filter->addr_mask; - unsigned int src_dest = filter->src_dest; - const unsigned char *addr = filter->mac_address; - unsigned int value = 0x0U; - int ret = 0; + 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; + const nveu8_t *addr = filter->mac_address; + nveu32_t value = 0x0U; + nve32_t ret = 0; if (idx > (EQOS_MAX_MAC_ADDRESS_FILTER - 0x1U)) { OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, @@ -1989,10 +1994,10 @@ static int eqos_update_mac_addr_low_high_reg( /* High address clean should happen for filter index >= 0 */ if (addr == OSI_NULL) { - value = osi_readl((unsigned char *)osi_core->base + + value = osi_readl((nveu8_t *)osi_core->base + EQOS_MAC_ADDRH((idx))); value &= ~EQOS_MAC_ADDRH_AE; - osi_writel(value, (unsigned char *)osi_core->base + + osi_writel(value, (nveu8_t *)osi_core->base + EQOS_MAC_ADDRH((idx))); return 0; } @@ -2018,14 +2023,14 @@ static int eqos_update_mac_addr_low_high_reg( value |= EQOS_MAC_ADDRH_AE; } - osi_writel(((unsigned int)addr[4] | - ((unsigned int)addr[5] << 8) | value), - (unsigned char *)osi_core->base + EQOS_MAC_ADDRH((idx))); + osi_writel(((nveu32_t)addr[4] | + ((nveu32_t)addr[5] << 8) | value), + (nveu8_t *)osi_core->base + EQOS_MAC_ADDRH((idx))); - osi_writel(((unsigned int)addr[0] | ((unsigned int)addr[1] << 8) | - ((unsigned int)addr[2] << 16) | - ((unsigned int)addr[3] << 24)), - (unsigned char *)osi_core->base + EQOS_MAC_ADDRL((idx))); + osi_writel(((nveu32_t)addr[0] | ((nveu32_t)addr[1] << 8) | + ((nveu32_t)addr[2] << 16) | + ((nveu32_t)addr[3] << 24)), + (nveu8_t *)osi_core->base + EQOS_MAC_ADDRL((idx))); return ret; } @@ -2052,15 +2057,15 @@ static int eqos_update_mac_addr_low_high_reg( * @retval 0 on success * @retval -1 on failure. */ -static int eqos_config_l3_l4_filter_enable(void *base, - const unsigned int filter_enb_dis) +static nve32_t eqos_config_l3_l4_filter_enable(void *base, + const nveu32_t filter_enb_dis) { - unsigned int value = 0U; + nveu32_t value = 0U; - value = osi_readl((unsigned char *)base + EQOS_MAC_PFR); + value = osi_readl((nveu8_t *)base + EQOS_MAC_PFR); value &= ~(EQOS_MAC_PFR_IPFE); value |= ((filter_enb_dis << 20) & EQOS_MAC_PFR_IPFE); - eqos_core_safety_writel(value, (unsigned char *)base + EQOS_MAC_PFR, + eqos_core_safety_writel(value, (nveu8_t *)base + EQOS_MAC_PFR, EQOS_MAC_PFR_IDX); return 0; @@ -2090,14 +2095,14 @@ static int eqos_config_l3_l4_filter_enable(void *base, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_update_ip4_addr(struct osi_core_priv_data *const osi_core, - const unsigned int filter_no, - const unsigned char addr[], - const unsigned int src_dst_addr_match) +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; - unsigned int value = 0U; - unsigned int temp = 0U; + nveu32_t value = 0U; + nveu32_t temp = 0U; if (addr == OSI_NULL) { OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "invalid address\n", @@ -2108,22 +2113,22 @@ static int eqos_update_ip4_addr(struct osi_core_priv_data *const osi_core, if (filter_no > (EQOS_MAX_L3_L4_FILTER - 0x1U)) { OSI_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, "invalid filter index for L3/L4 filter\n", - (unsigned long long)filter_no); + (nveul64_t)filter_no); return -1; } value = addr[3]; - temp = (unsigned int)addr[2] << 8; + temp = (nveu32_t)addr[2] << 8; value |= temp; - temp = (unsigned int)addr[1] << 16; + temp = (nveu32_t)addr[1] << 16; value |= temp; - temp = (unsigned int)addr[0] << 24; + temp = (nveu32_t)addr[0] << 24; value |= temp; if (src_dst_addr_match == OSI_SOURCE_MATCH) { - osi_writel(value, (unsigned char *)base + + osi_writel(value, (nveu8_t *)base + EQOS_MAC_L3_AD0R(filter_no)); } else { - osi_writel(value, (unsigned char *)base + + osi_writel(value, (nveu8_t *)base + EQOS_MAC_L3_AD1R(filter_no)); } @@ -2153,13 +2158,13 @@ static int eqos_update_ip4_addr(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_update_ip6_addr(struct osi_core_priv_data *const osi_core, - const unsigned int filter_no, - const unsigned short addr[]) +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; - unsigned int value = 0U; - unsigned int temp = 0U; + nveu32_t value = 0U; + nveu32_t temp = 0U; if (addr == OSI_NULL) { OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "invalid address\n", @@ -2170,33 +2175,33 @@ static int eqos_update_ip6_addr(struct osi_core_priv_data *const osi_core, if (filter_no > (EQOS_MAX_L3_L4_FILTER - 0x1U)) { OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "invalid filter index for L3/L4 filter\n", - (unsigned long long)filter_no); + (nveul64_t)filter_no); return -1; } /* update Bits[31:0] of 128-bit IP addr */ value = addr[7]; - temp = (unsigned int)addr[6] << 16; + temp = (nveu32_t)addr[6] << 16; value |= temp; - osi_writel(value, (unsigned char *)base + + osi_writel(value, (nveu8_t *)base + EQOS_MAC_L3_AD0R(filter_no)); /* update Bits[63:32] of 128-bit IP addr */ value = addr[5]; - temp = (unsigned int)addr[4] << 16; + temp = (nveu32_t)addr[4] << 16; value |= temp; - osi_writel(value, (unsigned char *)base + + osi_writel(value, (nveu8_t *)base + EQOS_MAC_L3_AD1R(filter_no)); /* update Bits[95:64] of 128-bit IP addr */ value = addr[3]; - temp = (unsigned int)addr[2] << 16; + temp = (nveu32_t)addr[2] << 16; value |= temp; - osi_writel(value, (unsigned char *)base + + osi_writel(value, (nveu8_t *)base + EQOS_MAC_L3_AD2R(filter_no)); /* update Bits[127:96] of 128-bit IP addr */ value = addr[1]; - temp = (unsigned int)addr[0] << 16; + temp = (nveu32_t)addr[0] << 16; value |= temp; - osi_writel(value, (unsigned char *)base + + osi_writel(value, (nveu8_t *)base + EQOS_MAC_L3_AD3R(filter_no)); return 0; @@ -2229,33 +2234,33 @@ static int eqos_update_ip6_addr(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_update_l4_port_no( +static nve32_t eqos_update_l4_port_no( struct osi_core_priv_data *const osi_core, - const unsigned int filter_no, - const unsigned short port_no, - const unsigned int src_dst_port_match) + const nveu32_t filter_no, + const nveu16_t port_no, + const nveu32_t src_dst_port_match) { void *base = osi_core->base; - unsigned int value = 0U; - unsigned int temp = 0U; + nveu32_t value = 0U; + nveu32_t temp = 0U; if (filter_no > (EQOS_MAX_L3_L4_FILTER - 0x1U)) { OSI_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, "invalid filter index for L3/L4 filter\n", - (unsigned long long)filter_no); + (nveul64_t)filter_no); return -1; } - value = osi_readl((unsigned char *)base + EQOS_MAC_L4_ADR(filter_no)); + value = osi_readl((nveu8_t *)base + EQOS_MAC_L4_ADR(filter_no)); if (src_dst_port_match == OSI_SOURCE_MATCH) { value &= ~EQOS_MAC_L4_SP_MASK; - value |= ((unsigned int)port_no & 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_writel(value, (unsigned char *)base + EQOS_MAC_L4_ADR(filter_no)); + osi_writel(value, (nveu8_t *)base + EQOS_MAC_L4_ADR(filter_no)); return 0; } @@ -2270,7 +2275,7 @@ static int eqos_update_l4_port_no( * 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] 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 * @@ -2285,13 +2290,13 @@ static int eqos_update_l4_port_no( * - Run time: Yes * - De-initialization: No * - *@return updated unsigned int value + *@return updated nveu32_t value */ -static inline unsigned int eqos_set_dcs( +static inline nveu32_t eqos_set_dcs( struct osi_core_priv_data *const osi_core, - unsigned int value, - unsigned int dma_routing_enable, - unsigned int dma_chan) + nveu32_t value, + nveu32_t dma_routing_enable, + nveu32_t dma_chan) { if ((dma_routing_enable == OSI_ENABLE) && (dma_chan < OSI_EQOS_MAX_NUM_CHANS) && (osi_core->dcs_en == @@ -2328,11 +2333,11 @@ static inline unsigned int eqos_set_dcs( * @pre MAC should be initialized and started. see osi_start_mac() * */ -static inline void eqos_helper_l3l4_bitmask(unsigned int *bitmask, - unsigned int filter_no, - unsigned int value) +static inline void eqos_helper_l3l4_bitmask(nveu32_t *bitmask, + nveu32_t filter_no, + nveu32_t value) { - unsigned int temp; + nveu32_t temp; /* Set bit mask for index */ temp = OSI_ENABLE; @@ -2379,23 +2384,23 @@ static inline void eqos_helper_l3l4_bitmask(unsigned int *bitmask, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_config_l3_filters( +static nve32_t eqos_config_l3_filters( struct osi_core_priv_data *const osi_core, - const unsigned int filter_no, - const unsigned int enb_dis, - const unsigned int ipv4_ipv6_match, - const unsigned int src_dst_addr_match, - const unsigned int perfect_inverse_match, - const unsigned int dma_routing_enable, - const unsigned int dma_chan) + 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) { - unsigned int value = 0U; + nveu32_t value = 0U; void *base = osi_core->base; if (filter_no > (EQOS_MAX_L3_L4_FILTER - 0x1U)) { OSI_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, "invalid filter index for L3/L4 filter\n", - (unsigned long long)filter_no); + (nveul64_t)filter_no); return -1; } @@ -2403,15 +2408,15 @@ static int eqos_config_l3_filters( (dma_chan > OSI_EQOS_MAX_NUM_CHANS - 1U)) { OSI_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, "Wrong DMA channel\n", - (unsigned long long)dma_chan); + (nveul64_t)dma_chan); return -1; } - value = osi_readl((unsigned char *)base + + value = osi_readl((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_writel(value, (unsigned char *)base + + osi_writel(value, (nveu8_t *)base + EQOS_MAC_L3L4_CTR(filter_no)); /* For IPv6 either SA/DA can be checked not both */ @@ -2421,7 +2426,7 @@ static int eqos_config_l3_filters( /* Enable L3 filters for IPv6 SOURCE addr * matching */ - value = osi_readl((unsigned char *)base + + value = osi_readl((nveu8_t *)base + EQOS_MAC_L3L4_CTR(filter_no)); value &= ~EQOS_MAC_L3_IP6_CTRL_CLEAR; value |= ((EQOS_MAC_L3L4_CTR_L3SAM0 | @@ -2432,14 +2437,14 @@ static int eqos_config_l3_filters( value |= eqos_set_dcs(osi_core, value, dma_routing_enable, dma_chan); - osi_writel(value, (unsigned char *)base + + osi_writel(value, (nveu8_t *)base + EQOS_MAC_L3L4_CTR(filter_no)); } else { /* Enable L3 filters for IPv6 DESTINATION addr * matching */ - value = osi_readl((unsigned char *)base + + value = osi_readl((nveu8_t *)base + EQOS_MAC_L3L4_CTR(filter_no)); value &= ~EQOS_MAC_L3_IP6_CTRL_CLEAR; value |= ((EQOS_MAC_L3L4_CTR_L3DAM0 | @@ -2450,18 +2455,18 @@ static int eqos_config_l3_filters( value |= eqos_set_dcs(osi_core, value, dma_routing_enable, dma_chan); - osi_writel(value, (unsigned char *)base + + osi_writel(value, (nveu8_t *)base + EQOS_MAC_L3L4_CTR(filter_no)); } } else { /* Disable L3 filters for IPv6 SOURCE/DESTINATION addr * matching */ - value = osi_readl((unsigned char *)base + + value = osi_readl((nveu8_t *)base + EQOS_MAC_L3L4_CTR(filter_no)); value &= ~(EQOS_MAC_L3_IP6_CTRL_CLEAR | EQOS_MAC_L3L4_CTR_L3PEN0); - osi_writel(value, (unsigned char *)base + + osi_writel(value, (nveu8_t *)base + EQOS_MAC_L3L4_CTR(filter_no)); } } else { @@ -2470,7 +2475,7 @@ static int eqos_config_l3_filters( /* Enable L3 filters for IPv4 SOURCE addr * matching */ - value = osi_readl((unsigned char *)base + + value = osi_readl((nveu8_t *)base + EQOS_MAC_L3L4_CTR(filter_no)); value &= ~EQOS_MAC_L3_IP4_SA_CTRL_CLEAR; value |= ((EQOS_MAC_L3L4_CTR_L3SAM0 | @@ -2481,16 +2486,16 @@ static int eqos_config_l3_filters( value |= eqos_set_dcs(osi_core, value, dma_routing_enable, dma_chan); - osi_writel(value, (unsigned char *)base + + osi_writel(value, (nveu8_t *)base + EQOS_MAC_L3L4_CTR(filter_no)); } else { /* Disable L3 filters for IPv4 SOURCE addr * matching */ - value = osi_readl((unsigned char *)base + + value = osi_readl((nveu8_t *)base + EQOS_MAC_L3L4_CTR(filter_no)); value &= ~EQOS_MAC_L3_IP4_SA_CTRL_CLEAR; - osi_writel(value, (unsigned char *)base + + osi_writel(value, (nveu8_t *)base + EQOS_MAC_L3L4_CTR(filter_no)); } } else { @@ -2498,7 +2503,7 @@ static int eqos_config_l3_filters( /* Enable L3 filters for IPv4 DESTINATION addr * matching */ - value = osi_readl((unsigned char *)base + + value = osi_readl((nveu8_t *)base + EQOS_MAC_L3L4_CTR(filter_no)); value &= ~EQOS_MAC_L3_IP4_DA_CTRL_CLEAR; value |= ((EQOS_MAC_L3L4_CTR_L3DAM0 | @@ -2509,16 +2514,16 @@ static int eqos_config_l3_filters( value |= eqos_set_dcs(osi_core, value, dma_routing_enable, dma_chan); - osi_writel(value, (unsigned char *)base + + osi_writel(value, (nveu8_t *)base + EQOS_MAC_L3L4_CTR(filter_no)); } else { /* Disable L3 filters for IPv4 DESTINATION addr * matching */ - value = osi_readl((unsigned char *)base + + value = osi_readl((nveu8_t *)base + EQOS_MAC_L3L4_CTR(filter_no)); value &= ~EQOS_MAC_L3_IP4_DA_CTRL_CLEAR; - osi_writel(value, (unsigned char *)base + + osi_writel(value, (nveu8_t *)base + EQOS_MAC_L3L4_CTR(filter_no)); } } @@ -2561,23 +2566,23 @@ static int eqos_config_l3_filters( * @retval 0 on success * @retval -1 on failure. */ -static int eqos_config_l4_filters( +static nve32_t eqos_config_l4_filters( struct osi_core_priv_data *const osi_core, - const unsigned int filter_no, - const unsigned int enb_dis, - const unsigned int tcp_udp_match, - const unsigned int src_dst_port_match, - const unsigned int perfect_inverse_match, - const unsigned int dma_routing_enable, - const unsigned int dma_chan) + 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; - unsigned int value = 0U; + nveu32_t value = 0U; if (filter_no > (EQOS_MAX_L3_L4_FILTER - 0x1U)) { OSI_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, "invalid filter index for L3/L4 filter\n", - (unsigned long long)filter_no); + (nveul64_t)filter_no); return -1; } @@ -2585,20 +2590,20 @@ static int eqos_config_l4_filters( (dma_chan > OSI_EQOS_MAX_NUM_CHANS - 1U)) { OSI_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, "Wrong DMA channel\n", - (unsigned int)dma_chan); + (nveu32_t)dma_chan); return -1; } - value = osi_readl((unsigned char *)base + EQOS_MAC_L3L4_CTR(filter_no)); + value = osi_readl((nveu8_t *)base + EQOS_MAC_L3L4_CTR(filter_no)); value &= ~EQOS_MAC_L3L4_CTR_L4PEN0; value |= ((tcp_udp_match << 16) & EQOS_MAC_L3L4_CTR_L4PEN0); - osi_writel(value, (unsigned char *)base + + osi_writel(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_readl((unsigned char *)base + + value = osi_readl((nveu8_t *)base + EQOS_MAC_L3L4_CTR(filter_no)); value &= ~EQOS_MAC_L4_SP_CTRL_CLEAR; value |= ((EQOS_MAC_L3L4_CTR_L4SPM0 | @@ -2609,14 +2614,14 @@ static int eqos_config_l4_filters( value |= eqos_set_dcs(osi_core, value, dma_routing_enable, dma_chan); - osi_writel(value, (unsigned char *)base + + osi_writel(value, (nveu8_t *)base + EQOS_MAC_L3L4_CTR(filter_no)); } else { /* Disable L4 filters for SOURCE Port No matching */ - value = osi_readl((unsigned char *)base + + value = osi_readl((nveu8_t *)base + EQOS_MAC_L3L4_CTR(filter_no)); value &= ~EQOS_MAC_L4_SP_CTRL_CLEAR; - osi_writel(value, (unsigned char *)base + + osi_writel(value, (nveu8_t *)base + EQOS_MAC_L3L4_CTR(filter_no)); } } else { @@ -2624,7 +2629,7 @@ static int eqos_config_l4_filters( /* Enable L4 filters for DESTINATION port No * matching */ - value = osi_readl((unsigned char *)base + + value = osi_readl((nveu8_t *)base + EQOS_MAC_L3L4_CTR(filter_no)); value &= ~EQOS_MAC_L4_DP_CTRL_CLEAR; value |= ((EQOS_MAC_L3L4_CTR_L4DPM0 | @@ -2635,16 +2640,16 @@ static int eqos_config_l4_filters( value |= eqos_set_dcs(osi_core, value, dma_routing_enable, dma_chan); - osi_writel(value, (unsigned char *)base + + osi_writel(value, (nveu8_t *)base + EQOS_MAC_L3L4_CTR(filter_no)); } else { /* Disable L4 filters for DESTINATION port No * matching */ - value = osi_readl((unsigned char *)base + + value = osi_readl((nveu8_t *)base + EQOS_MAC_L3L4_CTR(filter_no)); value &= ~EQOS_MAC_L4_DP_CTRL_CLEAR; - osi_writel(value, (unsigned char *)base + + osi_writel(value, (nveu8_t *)base + EQOS_MAC_L3L4_CTR(filter_no)); } } @@ -2678,14 +2683,14 @@ static int eqos_config_l4_filters( * @retval 0 on success * @retval -1 on failure. */ -static inline int eqos_poll_for_tsinit_complete( - struct osi_core_priv_data *const osi_core, - unsigned int *mac_tcr) +static inline nve32_t eqos_poll_for_tsinit_complete( + struct osi_core_priv_data *const osi_core, + nveu32_t *mac_tcr) { void *addr = osi_core->base; - unsigned int retry = 1000; - unsigned int count; - int cond = 1; + nveu32_t retry = 1000; + nveu32_t count; + nve32_t cond = 1; /* Wait for previous(if any) Initialize Timestamp value * update to complete @@ -2698,7 +2703,7 @@ static inline int eqos_poll_for_tsinit_complete( return -1; } /* Read and Check TSINIT in MAC_Timestamp_Control register */ - *mac_tcr = osi_readl((unsigned char *)addr + EQOS_MAC_TCR); + *mac_tcr = osi_readl((nveu8_t *)addr + EQOS_MAC_TCR); if ((*mac_tcr & EQOS_MAC_TCR_TSINIT) == 0U) { cond = 0; } @@ -2732,13 +2737,14 @@ static inline int eqos_poll_for_tsinit_complete( * @retval 0 on success * @retval -1 on failure. */ -static int eqos_set_systime_to_mac(struct osi_core_priv_data *const osi_core, - const unsigned int sec, - const unsigned int nsec) +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; - unsigned int mac_tcr; - int ret; + nveu32_t mac_tcr; + nve32_t ret; ret = eqos_poll_for_tsinit_complete(osi_core, &mac_tcr); if (ret == -1) { @@ -2746,16 +2752,16 @@ static int eqos_set_systime_to_mac(struct osi_core_priv_data *const osi_core, } /* write seconds value to MAC_System_Time_Seconds_Update register */ - osi_writel(sec, (unsigned char *)addr + EQOS_MAC_STSUR); + osi_writel(sec, (nveu8_t *)addr + EQOS_MAC_STSUR); /* write nano seconds value to MAC_System_Time_Nanoseconds_Update * register */ - osi_writel(nsec, (unsigned char *)addr + EQOS_MAC_STNSUR); + osi_writel(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(mac_tcr, (unsigned char *)addr + EQOS_MAC_TCR, + eqos_core_safety_writel(mac_tcr, (nveu8_t *)addr + EQOS_MAC_TCR, EQOS_MAC_TCR_IDX); ret = eqos_poll_for_tsinit_complete(osi_core, &mac_tcr); @@ -2789,14 +2795,14 @@ static int eqos_set_systime_to_mac(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -static inline int eqos_poll_for_addend_complete( - struct osi_core_priv_data *const osi_core, - unsigned int *mac_tcr) +static inline nve32_t eqos_poll_for_addend_complete( + struct osi_core_priv_data *const osi_core, + nveu32_t *mac_tcr) { void *addr = osi_core->base; - unsigned int retry = 1000; - unsigned int count; - int cond = 1; + nveu32_t retry = 1000; + nveu32_t count; + nve32_t cond = 1; /* Wait for previous(if any) addend value update to complete */ /* Poll */ @@ -2808,7 +2814,7 @@ static inline int eqos_poll_for_addend_complete( return -1; } /* Read and Check TSADDREG in MAC_Timestamp_Control register */ - *mac_tcr = osi_readl((unsigned char *)addr + EQOS_MAC_TCR); + *mac_tcr = osi_readl((nveu8_t *)addr + EQOS_MAC_TCR); if ((*mac_tcr & EQOS_MAC_TCR_TSADDREG) == 0U) { cond = 0; } @@ -2840,12 +2846,12 @@ static inline int eqos_poll_for_addend_complete( * @retval 0 on success * @retval -1 on failure. */ -static int eqos_config_addend(struct osi_core_priv_data *const osi_core, - const unsigned int addend) +static nve32_t eqos_config_addend(struct osi_core_priv_data *const osi_core, + const nveu32_t addend) { void *addr = osi_core->base; - unsigned int mac_tcr; - int ret; + nveu32_t mac_tcr; + nve32_t ret; ret = eqos_poll_for_addend_complete(osi_core, &mac_tcr); if (ret == -1) { @@ -2853,12 +2859,12 @@ static int eqos_config_addend(struct osi_core_priv_data *const osi_core, } /* write addend value to MAC_Timestamp_Addend register */ - eqos_core_safety_writel(addend, (unsigned char *)addr + EQOS_MAC_TAR, + eqos_core_safety_writel(addend, (nveu8_t *)addr + 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(mac_tcr, (unsigned char *)addr + EQOS_MAC_TCR, + eqos_core_safety_writel(mac_tcr, (nveu8_t *)addr + EQOS_MAC_TCR, EQOS_MAC_TCR_IDX); ret = eqos_poll_for_addend_complete(osi_core, &mac_tcr); @@ -2892,14 +2898,14 @@ static int eqos_config_addend(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -static inline int eqos_poll_for_update_ts_complete( - struct osi_core_priv_data *const osi_core, - unsigned int *mac_tcr) +static inline nve32_t eqos_poll_for_update_ts_complete( + struct osi_core_priv_data *const osi_core, + nveu32_t *mac_tcr) { void *addr = osi_core->base; - unsigned int retry = 1000; - unsigned int count; - int cond = 1; + nveu32_t retry = 1000; + nveu32_t count; + nve32_t cond = 1; /* Wait for previous(if any) time stamp value update to complete */ count = 0; @@ -2910,7 +2916,7 @@ static inline int eqos_poll_for_update_ts_complete( return -1; } /* Read and Check TSUPDT in MAC_Timestamp_Control register */ - *mac_tcr = osi_readl((unsigned char *)addr + EQOS_MAC_TCR); + *mac_tcr = osi_readl((nveu8_t *)addr + EQOS_MAC_TCR); if ((*mac_tcr & EQOS_MAC_TCR_TSUPDT) == 0U) { cond = 0; } @@ -2948,16 +2954,16 @@ static inline int eqos_poll_for_update_ts_complete( * @retval 0 on success * @retval -1 on failure. */ -static int eqos_adjust_mactime(struct osi_core_priv_data *const osi_core, - unsigned int sec, unsigned int nsec, - unsigned int add_sub, - unsigned int one_nsec_accuracy) +static nve32_t eqos_adjust_mactime(struct osi_core_priv_data *const osi_core, + nveu32_t sec, nveu32_t nsec, + nveu32_t add_sub, + nveu32_t one_nsec_accuracy) { void *addr = osi_core->base; - unsigned int mac_tcr; - unsigned int value = 0; - unsigned long long temp = 0; - int ret; + nveu32_t mac_tcr; + nveu32_t value = 0; + nveul64_t temp = 0; + nve32_t ret; ret = eqos_poll_for_update_ts_complete(osi_core, &mac_tcr); if (ret == -1) { @@ -2971,7 +2977,7 @@ static int eqos_adjust_mactime(struct osi_core_priv_data *const osi_core, */ temp = (TWO_POWER_32 - sec); if (temp < UINT_MAX) { - sec = (unsigned int)temp; + sec = (nveu32_t)temp; } else { /* do nothing here */ } @@ -2994,20 +3000,20 @@ static int eqos_adjust_mactime(struct osi_core_priv_data *const osi_core, } /* write seconds value to MAC_System_Time_Seconds_Update register */ - osi_writel(sec, (unsigned char *)addr + EQOS_MAC_STSUR); + osi_writel(sec, (nveu8_t *)addr + EQOS_MAC_STSUR); /* write nano seconds value and add_sub to * MAC_System_Time_Nanoseconds_Update register */ value |= nsec; value |= add_sub << EQOS_MAC_STNSUR_ADDSUB_SHIFT; - osi_writel(value, (unsigned char *)addr + EQOS_MAC_STNSUR); + osi_writel(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(mac_tcr, (unsigned char *)addr + EQOS_MAC_TCR, + eqos_core_safety_writel(mac_tcr, (nveu8_t *)addr + EQOS_MAC_TCR, EQOS_MAC_TCR_IDX); ret = eqos_poll_for_update_ts_complete(osi_core, &mac_tcr); @@ -3033,15 +3039,15 @@ static int eqos_adjust_mactime(struct osi_core_priv_data *const osi_core, * - Run time: Yes * - De-initialization: No */ -static void eqos_config_tscr(void *addr, const unsigned int ptp_filter) +static void eqos_config_tscr(void *addr, const nveu32_t ptp_filter) { - unsigned int mac_tcr = 0U, i = 0U, temp = 0U; + nveu32_t mac_tcr = 0U, i = 0U, temp = 0U; if (ptp_filter == OSI_DISABLE) { /* Disabling the MAC time stamping */ mac_tcr = OSI_DISABLE; eqos_core_safety_writel(mac_tcr, - (unsigned char *)addr + EQOS_MAC_TCR, + (nveu8_t *)addr + EQOS_MAC_TCR, EQOS_MAC_TCR_IDX); return; } @@ -3094,7 +3100,7 @@ static void eqos_config_tscr(void *addr, const unsigned int ptp_filter) } } - eqos_core_safety_writel(mac_tcr, (unsigned char *)addr + EQOS_MAC_TCR, + eqos_core_safety_writel(mac_tcr, (nveu8_t *)addr + EQOS_MAC_TCR, EQOS_MAC_TCR_IDX); } @@ -3113,12 +3119,12 @@ static void eqos_config_tscr(void *addr, const unsigned int ptp_filter) */ static void eqos_config_ssir(struct osi_core_priv_data *const osi_core) { - unsigned long long val; - unsigned int mac_tcr; + nveul64_t val; + nveu32_t mac_tcr; void *addr = osi_core->base; - unsigned int ptp_clock = osi_core->ptp_config.ptp_clock; + nveu32_t ptp_clock = osi_core->ptp_config.ptp_clock; - mac_tcr = osi_readl((unsigned char *)addr + EQOS_MAC_TCR); + mac_tcr = osi_readl((nveu8_t *)addr + EQOS_MAC_TCR); if ((mac_tcr & EQOS_MAC_TCR_TSCFUPDT) == EQOS_MAC_TCR_TSCFUPDT) { @@ -3145,8 +3151,8 @@ static void eqos_config_ssir(struct osi_core_priv_data *const osi_core) val |= val << EQOS_MAC_SSIR_SSINC_SHIFT; /* update Sub-second Increment Value */ if (val < UINT_MAX) { - eqos_core_safety_writel((unsigned int)val, - (unsigned char *)addr + EQOS_MAC_SSIR, + eqos_core_safety_writel((nveu32_t)val, + (nveu8_t *)addr + EQOS_MAC_SSIR, EQOS_MAC_SSIR_IDX); } } @@ -3190,13 +3196,13 @@ static void eqos_core_deinit(struct osi_core_priv_data *const osi_core) * @retval 0 on Success * @retval -1 on Failure */ -static inline int poll_for_mii_idle(struct osi_core_priv_data *osi_core) +static inline nve32_t poll_for_mii_idle(struct osi_core_priv_data *osi_core) { /* half sec timeout */ - unsigned int retry = 50000; - unsigned int mac_gmiiar; - unsigned int count; - int cond = 1; + nveu32_t retry = 50000; + nveu32_t mac_gmiiar; + nveu32_t count; + nve32_t cond = 1; count = 0; while (cond == 1) { @@ -3208,7 +3214,7 @@ static inline int poll_for_mii_idle(struct osi_core_priv_data *osi_core) } count++; - mac_gmiiar = osi_readl((unsigned char *)osi_core->base + + mac_gmiiar = osi_readl((nveu8_t *)osi_core->base + EQOS_MAC_MDIO_ADDRESS); if ((mac_gmiiar & EQOS_MAC_GMII_BUSY) == 0U) { /* exit loop */ @@ -3252,14 +3258,14 @@ static inline int poll_for_mii_idle(struct osi_core_priv_data *osi_core) * @retval 0 on success * @retval -1 on failure. */ -static int eqos_write_phy_reg(struct osi_core_priv_data *const osi_core, - const unsigned int phyaddr, - const unsigned int phyreg, - const unsigned short phydata) +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) { - unsigned int mac_gmiiar; - unsigned int mac_gmiidr; - int ret = 0; + nveu32_t mac_gmiiar; + nveu32_t mac_gmiidr; + nve32_t ret = 0; /* Wait for any previous MII read/write operation to complete */ ret = poll_for_mii_idle(osi_core); @@ -3268,12 +3274,12 @@ static int eqos_write_phy_reg(struct osi_core_priv_data *const osi_core, return ret; } - mac_gmiidr = osi_readl((unsigned char *)osi_core->base + + mac_gmiidr = osi_readl((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_writel(mac_gmiidr, (unsigned char *)osi_core->base + + osi_writel(mac_gmiidr, (nveu8_t *)osi_core->base + EQOS_MAC_MDIO_DATA); /* initiate the MII write operation by updating desired */ @@ -3282,7 +3288,7 @@ static int eqos_write_phy_reg(struct osi_core_priv_data *const osi_core, /* CSR Clock Range (20 - 35MHz) */ /* Select write operation */ /* set busy bit */ - mac_gmiiar = osi_readl((unsigned char *)osi_core->base + + mac_gmiiar = osi_readl((nveu8_t *)osi_core->base + EQOS_MAC_MDIO_ADDRESS); mac_gmiiar = (mac_gmiiar & (EQOS_MDIO_PHY_REG_SKAP | EQOS_MDIO_PHY_REG_C45E)); @@ -3291,7 +3297,7 @@ static int eqos_write_phy_reg(struct osi_core_priv_data *const osi_core, ((osi_core->mdc_cr) << EQOS_MDIO_PHY_REG_CR_SHIF) | (EQOS_MDIO_PHY_REG_WRITE) | EQOS_MAC_GMII_BUSY); - osi_writel(mac_gmiiar, (unsigned char *)osi_core->base + + osi_writel(mac_gmiiar, (nveu8_t *)osi_core->base + EQOS_MAC_MDIO_ADDRESS); /* wait for MII write operation to complete */ @@ -3333,14 +3339,14 @@ static int eqos_write_phy_reg(struct osi_core_priv_data *const osi_core, * @retval data from PHY register on success * @retval -1 on failure */ -static int eqos_read_phy_reg(struct osi_core_priv_data *const osi_core, - const unsigned int phyaddr, - const unsigned int phyreg) +static nve32_t eqos_read_phy_reg(struct osi_core_priv_data *const osi_core, + const nveu32_t phyaddr, + const nveu32_t phyreg) { - unsigned int mac_gmiiar; - unsigned int mac_gmiidr; - unsigned int data; - int ret = 0; + nveu32_t mac_gmiiar; + nveu32_t mac_gmiidr; + nveu32_t data; + nve32_t ret = 0; /* wait for any previous MII read/write operation to complete */ ret = poll_for_mii_idle(osi_core); @@ -3349,7 +3355,7 @@ static int eqos_read_phy_reg(struct osi_core_priv_data *const osi_core, return ret; } - mac_gmiiar = osi_readl((unsigned char *)osi_core->base + + mac_gmiiar = osi_readl((nveu8_t *)osi_core->base + EQOS_MAC_MDIO_ADDRESS); /* initiate the MII read operation by updating desired */ /* phy address/id (0 - 31) */ @@ -3363,7 +3369,7 @@ static int eqos_read_phy_reg(struct osi_core_priv_data *const osi_core, ((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_writel(mac_gmiiar, (unsigned char *)osi_core->base + + osi_writel(mac_gmiiar, (nveu8_t *)osi_core->base + EQOS_MAC_MDIO_ADDRESS); /* wait for MII write operation to complete */ @@ -3373,11 +3379,11 @@ static int eqos_read_phy_reg(struct osi_core_priv_data *const osi_core, return ret; } - mac_gmiidr = osi_readl((unsigned char *)osi_core->base + + mac_gmiidr = osi_readl((nveu8_t *)osi_core->base + EQOS_MAC_MDIO_DATA); data = (mac_gmiidr & EQOS_MAC_GMIIDR_GD_MASK); - return (int)data; + return (nve32_t)data; } #ifndef OSI_STRIPPED_LIB @@ -3401,13 +3407,13 @@ static int eqos_read_phy_reg(struct osi_core_priv_data *const osi_core, */ static inline void eqos_disable_tx_lpi(void *addr) { - unsigned int lpi_csr = 0; + nveu32_t lpi_csr = 0; /* Disable LPI control bits */ - lpi_csr = osi_readl((unsigned char *)addr + EQOS_MAC_LPI_CSR); + lpi_csr = osi_readl((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_writel(lpi_csr, (unsigned char *)addr + EQOS_MAC_LPI_CSR); + osi_writel(lpi_csr, (nveu8_t *)addr + EQOS_MAC_LPI_CSR); } /** @@ -3436,19 +3442,20 @@ static inline void eqos_disable_tx_lpi(void *addr) * @retval 0 on success * @retval -1 on failure. */ -static int eqos_validate_core_regs(struct osi_core_priv_data *const osi_core) +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; - unsigned int cur_val; - unsigned int i; + 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_readl((unsigned char *)config->reg_addr[i]); + cur_val = osi_readl((nveu8_t *)config->reg_addr[i]); cur_val &= config->reg_mask[i]; if (cur_val == config->reg_val[i]) { @@ -3492,11 +3499,12 @@ static int eqos_validate_core_regs(struct osi_core_priv_data *const osi_core) * @retval 0 on success * @retval -1 on failure. */ -static int eqos_config_rx_crc_check(struct osi_core_priv_data *const osi_core, - const unsigned int crc_chk) +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; - unsigned int val; + nveu32_t val; /* return on invalid argument */ if (crc_chk != OSI_ENABLE && crc_chk != OSI_DISABLE) { @@ -3506,7 +3514,7 @@ static int eqos_config_rx_crc_check(struct osi_core_priv_data *const osi_core, } /* Read MAC Extension Register */ - val = osi_readl((unsigned char *)addr + EQOS_MAC_EXTR); + val = osi_readl((nveu8_t *)addr + EQOS_MAC_EXTR); /* crc_chk: 1 is for enable and 0 is for disable */ if (crc_chk == OSI_ENABLE) { @@ -3520,7 +3528,7 @@ static int eqos_config_rx_crc_check(struct osi_core_priv_data *const osi_core, } /* Write to MAC Extension Register */ - osi_writel(val, (unsigned char *)addr + EQOS_MAC_EXTR); + osi_writel(val, (nveu8_t *)addr + EQOS_MAC_EXTR); return 0; } @@ -3549,11 +3557,11 @@ static int eqos_config_rx_crc_check(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_config_tx_status(struct osi_core_priv_data *const osi_core, - const unsigned int tx_status) +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; - unsigned int val; + nveu32_t val; /* don't allow if tx_status is other than 0 or 1 */ if (tx_status != OSI_ENABLE && tx_status != OSI_DISABLE) { @@ -3563,7 +3571,7 @@ static int eqos_config_tx_status(struct osi_core_priv_data *const osi_core, } /* Read MTL Operation Mode Register */ - val = osi_readl((unsigned char *)addr + EQOS_MTL_OP_MODE); + val = osi_readl((nveu8_t *)addr + EQOS_MTL_OP_MODE); if (tx_status == OSI_ENABLE) { /* When DTXSTS bit is reset, the Tx packet status received @@ -3582,7 +3590,7 @@ static int eqos_config_tx_status(struct osi_core_priv_data *const osi_core, /* Write to DTXSTS bit of MTL Operation Mode Register to enable or * disable the Tx packet status */ - osi_writel(val, (unsigned char *)addr + EQOS_MTL_OP_MODE); + osi_writel(val, (nveu8_t *)addr + EQOS_MTL_OP_MODE); return 0; } @@ -3618,13 +3626,13 @@ static int eqos_config_tx_status(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_set_avb_algorithm( +static nve32_t eqos_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; + nveu32_t value; + nve32_t ret = -1; + nveu32_t qinx; if (avb == OSI_NULL) { OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, @@ -3637,7 +3645,7 @@ static int eqos_set_avb_algorithm( if (avb->qindex >= OSI_EQOS_MAX_NUM_QUEUES) { OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid Queue index\n", - (unsigned long long)avb->qindex); + (nveul64_t)avb->qindex); return ret; } @@ -3645,7 +3653,7 @@ static int eqos_set_avb_algorithm( if (avb->oper_mode >= OSI_MTL_QUEUE_MODEMAX) { OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid Queue mode\n", - (unsigned long long)avb->qindex); + (nveul64_t)avb->qindex); return ret; } @@ -3653,18 +3661,18 @@ static int eqos_set_avb_algorithm( if ((avb->qindex == 0U) && (avb->oper_mode == OSI_MTL_QUEUE_AVB)) { OSI_ERR(osi_core->osd, OSI_LOG_ARG_OPNOTSUPP, "Not allowed to set AVB for Q0\n", - (unsigned long long)avb->qindex); + (nveul64_t)avb->qindex); return ret; } qinx = avb->qindex; - value = osi_readl((unsigned char *)osi_core->base + + value = osi_readl((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(value, (unsigned char *)osi_core->base + + eqos_core_safety_writel(value, (nveu8_t *)osi_core->base + EQOS_MTL_CHX_TX_OP_MODE(qinx), EQOS_MTL_CH0_TX_OP_MODE_IDX + qinx); @@ -3675,34 +3683,34 @@ static int eqos_set_avb_algorithm( } value |= (avb->algo << EQOS_MTL_TXQ_ETS_CR_AVALG_SHIFT) & EQOS_MTL_TXQ_ETS_CR_AVALG; - osi_writel(value, (unsigned char *)osi_core->base + + osi_writel(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_writel(value, (unsigned char *)osi_core->base + + osi_writel(value, (nveu8_t *)osi_core->base + EQOS_MTL_TXQ_ETS_SSCR(qinx)); /* Set Idle slope credit*/ - value = osi_readl((unsigned char *)osi_core->base + + value = osi_readl((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(value, (unsigned char *)osi_core->base + + eqos_core_safety_writel(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_writel(value, (unsigned char *)osi_core->base + + osi_writel(value, (nveu8_t *)osi_core->base + EQOS_MTL_TXQ_ETS_HCR(qinx)); - /* low credit is -ve number, osi_write need a unsigned int + /* 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_writel(value, (unsigned char *)osi_core->base + + osi_writel(value, (nveu8_t *)osi_core->base + EQOS_MTL_TXQ_ETS_LCR(qinx)); } @@ -3740,12 +3748,12 @@ static int eqos_set_avb_algorithm( * @retval 0 on success * @retval -1 on failure. */ -static int eqos_get_avb_algorithm(struct osi_core_priv_data *const osi_core, - struct osi_core_avb_algorithm *const avb) +static nve32_t eqos_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; + nveu32_t value; + nve32_t ret = -1; + nveu32_t qinx = 0U; if (avb == OSI_NULL) { OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, @@ -3757,12 +3765,12 @@ static int eqos_get_avb_algorithm(struct osi_core_priv_data *const osi_core, if (avb->qindex >= OSI_EQOS_MAX_NUM_QUEUES) { OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid Queue index\n", - (unsigned long long)avb->qindex); + (nveul64_t)avb->qindex); return ret; } qinx = avb->qindex; - value = osi_readl((unsigned char *)osi_core->base + + value = osi_readl((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 */ @@ -3770,7 +3778,7 @@ static int eqos_get_avb_algorithm(struct osi_core_priv_data *const osi_core, avb->oper_mode = value; /* Get Algo and Credit control */ - value = osi_readl((unsigned char *)osi_core->base + + value = osi_readl((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; @@ -3778,24 +3786,24 @@ static int eqos_get_avb_algorithm(struct osi_core_priv_data *const osi_core, EQOS_MTL_TXQ_ETS_CR_AVALG_SHIFT; /* Get Send slope credit */ - value = osi_readl((unsigned char *)osi_core->base + + value = osi_readl((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_readl((unsigned char *)osi_core->base + + value = osi_readl((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_readl((unsigned char *)osi_core->base + + value = osi_readl((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_readl((unsigned char *)osi_core->base + + value = osi_readl((nveu8_t *)osi_core->base + EQOS_MTL_TXQ_ETS_LCR(qinx)); avb->low_credit = value & EQOS_MTL_TXQ_ETS_LCR_LC_MASK; @@ -3832,14 +3840,14 @@ static int eqos_get_avb_algorithm(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_config_arp_offload(const unsigned int mac_ver, - struct osi_core_priv_data *const osi_core, - const unsigned int enable, - const unsigned char *ip_addr) +static nve32_t eqos_config_arp_offload(const nveu32_t mac_ver, + struct osi_core_priv_data *const osi_core, + const nveu32_t enable, + const nveu8_t *ip_addr) { void *addr = osi_core->base; - unsigned int mac_mcr; - unsigned int val; + nveu32_t mac_mcr; + nveu32_t val; if (enable != OSI_ENABLE && enable != OSI_DISABLE) { OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, @@ -3847,19 +3855,19 @@ static int eqos_config_arp_offload(const unsigned int mac_ver, return -1; } - mac_mcr = osi_readl((unsigned char *)addr + EQOS_MAC_MCR); + mac_mcr = osi_readl((nveu8_t *)addr + EQOS_MAC_MCR); 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])); + 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_writel(val, (unsigned char *)addr + + osi_writel(val, (nveu8_t *)addr + EQOS_4_10_MAC_ARPPA); } else if (mac_ver == OSI_EQOS_MAC_5_00) { - osi_writel(val, (unsigned char *)addr + + osi_writel(val, (nveu8_t *)addr + EQOS_5_00_MAC_ARPPA); } else { /* Unsupported MAC ver */ @@ -3873,7 +3881,7 @@ static int eqos_config_arp_offload(const unsigned int mac_ver, mac_mcr &= ~EQOS_MCR_ARPEN; } - eqos_core_safety_writel(mac_mcr, (unsigned char *)addr + EQOS_MAC_MCR, + eqos_core_safety_writel(mac_mcr, (nveu8_t *)addr + EQOS_MAC_MCR, EQOS_MAC_MCR_IDX); return 0; @@ -3905,13 +3913,13 @@ static int eqos_config_arp_offload(const unsigned int mac_ver, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_config_vlan_filtering( +static nve32_t eqos_config_vlan_filtering( struct osi_core_priv_data *const osi_core, - const unsigned int filter_enb_dis, - const unsigned int perfect_hash_filtering, - const unsigned int perfect_inverse_match) + const nveu32_t filter_enb_dis, + const nveu32_t perfect_hash_filtering, + const nveu32_t perfect_inverse_match) { - unsigned int value; + nveu32_t value; void *base = osi_core->base; if (filter_enb_dis != OSI_ENABLE && filter_enb_dis != OSI_DISABLE) { @@ -3934,13 +3942,13 @@ static int eqos_config_vlan_filtering( return -1; } - value = osi_readl((unsigned char *)base + EQOS_MAC_PFR); + value = osi_readl((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(value, (unsigned char *)base + EQOS_MAC_PFR, + eqos_core_safety_writel(value, (nveu8_t *)base + EQOS_MAC_PFR, EQOS_MAC_PFR_IDX); - value = osi_readl((unsigned char *)base + EQOS_MAC_VLAN_TR); + value = osi_readl((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); @@ -3949,7 +3957,7 @@ static int eqos_config_vlan_filtering( "VLAN hash filter is not supported, no updat of VTHM\n", 0ULL); } - osi_writel(value, (unsigned char *)base + EQOS_MAC_VLAN_TR); + osi_writel(value, (nveu8_t *)base + EQOS_MAC_VLAN_TR); return 0; } @@ -3967,7 +3975,7 @@ static int eqos_config_vlan_filtering( * * @retval 0 always */ -static inline int eqos_update_vlan_id(void *base, unsigned int vid) +static inline nve32_t eqos_update_vlan_id(void *base, nveu32_t vid) { /* Don't add VLAN ID to TR register which is eventually set TR * to 0x0 and allow all tagged packets @@ -4003,16 +4011,15 @@ static inline int eqos_update_vlan_id(void *base, unsigned int vid) * - Run time: Yes * - De-initialization: No */ -static void eqos_configure_eee( - struct osi_core_priv_data *const osi_core, - const unsigned int tx_lpi_enabled, - const unsigned int tx_lpi_timer) +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) { - unsigned int lpi_csr = 0; - unsigned int lpi_timer_ctrl = 0; - unsigned int lpi_entry_timer = 0; - unsigned int lpi_1US_tic_counter = OSI_LPI_1US_TIC_COUNTER_DEFAULT; - unsigned char *addr = (unsigned char *)osi_core->base; + 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. @@ -4081,10 +4088,10 @@ static void eqos_configure_eee( * * @retval 0 on Success */ -static inline int eqos_save_registers( +static inline nve32_t eqos_save_registers( struct osi_core_priv_data *const osi_core) { - unsigned int i; + nveu32_t i; struct core_backup *config = &osi_core->backup_config; for (i = 0; i < EQOS_MAX_BAK_IDX; i++) { @@ -4114,10 +4121,10 @@ static inline int eqos_save_registers( * * @retval 0 on Success */ -static inline int eqos_restore_registers( +static inline nve32_t eqos_restore_registers( struct osi_core_priv_data *const osi_core) { - unsigned int i; + nveu32_t i; struct core_backup *config = &osi_core->backup_config; for (i = 0; i < EQOS_MAX_BAK_IDX; i++) { @@ -4150,15 +4157,15 @@ static inline int eqos_restore_registers( * - De-initialization: No */ static void eqos_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, - const unsigned long csr_clk_rate) + const nveu64_t csr_clk_rate) { - unsigned long csr_clk_speed = csr_clk_rate / 1000000UL; + 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 = (unsigned int)csr_clk_speed; + osi_core->csr_clk_speed = (nveu32_t)csr_clk_speed; } if (csr_clk_speed > 500UL) { osi_core->mdc_cr = EQOS_CSR_500_800M; @@ -4198,11 +4205,11 @@ static void eqos_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_config_mac_loopback(void *addr, - const unsigned int lb_mode) +static nve32_t eqos_config_mac_loopback(void *addr, + const nveu32_t lb_mode) { - unsigned int clk_ctrl_val; - unsigned int mcr_val; + nveu32_t clk_ctrl_val; + nveu32_t mcr_val; /* don't allow only if loopback mode is other than 0 or 1 */ if (lb_mode != OSI_ENABLE && lb_mode != OSI_DISABLE) { @@ -4210,10 +4217,10 @@ static int eqos_config_mac_loopback(void *addr, } /* Read MAC Configuration Register */ - mcr_val = osi_readl((unsigned char *)addr + EQOS_MAC_MCR); + mcr_val = osi_readl((nveu8_t *)addr + EQOS_MAC_MCR); /* Read EQOS wrapper clock control 0 register */ - clk_ctrl_val = osi_readl((unsigned char *)addr + EQOS_CLOCK_CTRL_0); + clk_ctrl_val = osi_readl((nveu8_t *)addr + EQOS_CLOCK_CTRL_0); if (lb_mode == OSI_ENABLE) { /* Enable Loopback Mode */ @@ -4230,10 +4237,10 @@ static int eqos_config_mac_loopback(void *addr, } /* Write to EQOS wrapper clock control 0 register */ - osi_writel(clk_ctrl_val, (unsigned char *)addr + EQOS_CLOCK_CTRL_0); + osi_writel(clk_ctrl_val, (nveu8_t *)addr + EQOS_CLOCK_CTRL_0); /* Write to MAC Configuration Register */ - eqos_core_safety_writel(mcr_val, (unsigned char *)addr + EQOS_MAC_MCR, + eqos_core_safety_writel(mcr_val, (nveu8_t *)addr + EQOS_MAC_MCR, EQOS_MAC_MCR_IDX); return 0; diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 8532ebd..11b6df4 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -30,14 +30,14 @@ * 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_16_K (unsigned int)30 +#define FULL_MINUS_1_5K (nveu32_t)1 +#define FULL_MINUS_2_K (nveu32_t)2 +#define FULL_MINUS_2_5K (nveu32_t)3 +#define FULL_MINUS_3_K (nveu32_t)4 +#define FULL_MINUS_4_K (nveu32_t)6 +#define FULL_MINUS_6_K (nveu32_t)10 +#define FULL_MINUS_10_K (nveu32_t)18 +#define FULL_MINUS_16_K (nveu32_t)30 /** @} */ /** @@ -218,7 +218,7 @@ #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 ((unsigned int)0x3 << 21U) +#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) @@ -364,7 +364,7 @@ #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_RQC2_PSRQ_MASK ((unsigned int)0xFF) +#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 @@ -399,7 +399,7 @@ #define EQOS_ASID_CTRL_SHIFT_16 16U #define EQOS_ASID_CTRL_SHIFT_8 8U -#define TEGRA_SID_EQOS (unsigned int)20 +#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) @@ -416,7 +416,7 @@ (TEGRA_SID_EQOS)) /** @} */ -void update_ehfc_rfa_rfd(unsigned int rx_fifo, unsigned int *value); +void update_ehfc_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value); /** * @addtogroup EQOS-Safety-Register EQOS Safety Register Mask @@ -492,12 +492,12 @@ struct core_func_safety { 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) */ - unsigned int reg_mask[EQOS_MAX_CORE_SAFETY_REGS]; + nveu32_t reg_mask[EQOS_MAX_CORE_SAFETY_REGS]; /** Array of value stored in each corresponding register */ - unsigned int reg_val[EQOS_MAX_CORE_SAFETY_REGS]; + nveu32_t reg_val[EQOS_MAX_CORE_SAFETY_REGS]; /** OSI lock variable used to protect writes to reg while * validation is in-progress */ - unsigned int core_safety_lock; + nveu32_t core_safety_lock; }; /** diff --git a/osi/core/eqos_mmc.c b/osi/core/eqos_mmc.c index 6e0ab4d..f397717 100644 --- a/osi/core/eqos_mmc.c +++ b/osi/core/eqos_mmc.c @@ -51,12 +51,12 @@ * @retval 0 on success * @retval -1 on failure */ -static inline unsigned long update_mmc_val(struct osi_core_priv_data *osi_core, - unsigned long last_value, - unsigned long offset) +static inline nveu64_t update_mmc_val(struct osi_core_priv_data *osi_core, + nveu64_t last_value, + nveu64_t offset) { - unsigned long temp; - unsigned int value = osi_readl((unsigned char *)osi_core->base + + nveu64_t temp; + nveu32_t value = osi_readl((nveu8_t *)osi_core->base + offset); temp = last_value + value; @@ -64,7 +64,7 @@ static inline unsigned long update_mmc_val(struct osi_core_priv_data *osi_core, OSI_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, "Value overflow resetting all counters\n", - (unsigned long long)offset); + (nveul64_t)offset); eqos_reset_mmc(osi_core); } else { return temp; @@ -91,12 +91,12 @@ static inline unsigned long update_mmc_val(struct osi_core_priv_data *osi_core, */ void eqos_reset_mmc(struct osi_core_priv_data *osi_core) { - unsigned int value; + nveu32_t value; - value = osi_readl((unsigned char *)osi_core->base + EQOS_MMC_CNTRL); + value = osi_readl((nveu8_t *)osi_core->base + EQOS_MMC_CNTRL); /* self-clear bit in one clock cycle */ value |= EQOS_MMC_CNTRL_CNTRST; - osi_writel(value, (unsigned char *)osi_core->base + EQOS_MMC_CNTRL); + osi_writel(value, (nveu8_t *)osi_core->base + EQOS_MMC_CNTRL); osi_memset(&osi_core->mmc, 0U, sizeof(struct osi_mmc_counters)); } diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 49532ce..cae0fa5 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -24,9 +24,9 @@ #include <osd.h> #include <local_common.h> -int osi_write_phy_reg(struct osi_core_priv_data *const osi_core, - const unsigned int phyaddr, const unsigned int phyreg, - const unsigned short phydata) +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) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->base != OSI_NULL) && @@ -37,8 +37,8 @@ int osi_write_phy_reg(struct osi_core_priv_data *const osi_core, return -1; } -int osi_read_phy_reg(struct osi_core_priv_data *const osi_core, - const unsigned int phyaddr, const unsigned int phyreg) +nve32_t osi_read_phy_reg(struct osi_core_priv_data *const osi_core, + const nveu32_t phyaddr, const nveu32_t phyreg) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->base != OSI_NULL) && @@ -49,7 +49,7 @@ int osi_read_phy_reg(struct osi_core_priv_data *const osi_core, return -1; } -int osi_init_core_ops(struct osi_core_priv_data *const osi_core) +nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core) { /* * Currently these osd_ops are optional to be filled in the OSD layer. @@ -88,7 +88,7 @@ int osi_init_core_ops(struct osi_core_priv_data *const osi_core) return -1; } -int osi_poll_for_mac_reset_complete( +nve32_t osi_poll_for_mac_reset_complete( struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && @@ -101,9 +101,8 @@ int osi_poll_for_mac_reset_complete( return -1; } -int osi_hw_core_init(struct osi_core_priv_data *const osi_core, - unsigned int tx_fifo_size, - unsigned int rx_fifo_size) +nve32_t osi_hw_core_init(struct osi_core_priv_data *const osi_core, + nveu32_t tx_fifo_size, nveu32_t rx_fifo_size) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->base != OSI_NULL) && @@ -115,7 +114,7 @@ int osi_hw_core_init(struct osi_core_priv_data *const osi_core, return -1; } -int osi_hw_core_deinit(struct osi_core_priv_data *const osi_core) +nve32_t osi_hw_core_deinit(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->base != OSI_NULL) && @@ -127,7 +126,7 @@ int osi_hw_core_deinit(struct osi_core_priv_data *const osi_core) return -1; } -int osi_start_mac(struct osi_core_priv_data *const osi_core) +nve32_t osi_start_mac(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->base != OSI_NULL) && @@ -139,7 +138,7 @@ int osi_start_mac(struct osi_core_priv_data *const osi_core) return -1; } -int osi_stop_mac(struct osi_core_priv_data *const osi_core) +nve32_t osi_stop_mac(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->base != OSI_NULL) && @@ -151,7 +150,7 @@ int osi_stop_mac(struct osi_core_priv_data *const osi_core) return -1; } -int osi_common_isr(struct osi_core_priv_data *const osi_core) +nve32_t osi_common_isr(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->base != OSI_NULL) && @@ -163,7 +162,8 @@ int osi_common_isr(struct osi_core_priv_data *const osi_core) return -1; } -int osi_set_mode(struct osi_core_priv_data *const osi_core, const int mode) +nve32_t osi_set_mode(struct osi_core_priv_data *const osi_core, + const nve32_t mode) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->base != OSI_NULL) && @@ -174,8 +174,8 @@ int osi_set_mode(struct osi_core_priv_data *const osi_core, const int mode) return -1; } -int osi_set_speed(struct osi_core_priv_data *const osi_core, - const int speed) +nve32_t osi_set_speed(struct osi_core_priv_data *const osi_core, + const nve32_t speed) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->base != OSI_NULL) && @@ -187,7 +187,7 @@ int osi_set_speed(struct osi_core_priv_data *const osi_core, return -1; } -int osi_pad_calibrate(struct osi_core_priv_data *const osi_core) +nve32_t osi_pad_calibrate(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->pad_calibrate != OSI_NULL) && @@ -198,8 +198,8 @@ int osi_pad_calibrate(struct osi_core_priv_data *const osi_core) return -1; } -int osi_config_fw_err_pkts(struct osi_core_priv_data *const osi_core, - const unsigned int qinx, const unsigned int fw_err) +nve32_t osi_config_fw_err_pkts(struct osi_core_priv_data *const osi_core, + const nveu32_t qinx, const nveu32_t fw_err) { /* Configure Forwarding of Error packets */ if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && @@ -212,11 +212,11 @@ int osi_config_fw_err_pkts(struct osi_core_priv_data *const osi_core, return -1; } -int osi_l2_filter(struct osi_core_priv_data *const osi_core, - const struct osi_filter *filter) +nve32_t osi_l2_filter(struct osi_core_priv_data *const osi_core, + const struct osi_filter *filter) { struct osi_core_ops *op; - int ret = -1; + nve32_t ret = -1; if (osi_core == OSI_NULL || osi_core->ops == OSI_NULL || osi_core->base == OSI_NULL || filter == OSI_NULL) { @@ -278,12 +278,12 @@ int osi_l2_filter(struct osi_core_priv_data *const osi_core, * @retval 0 on Success * @retval -1 on Failure */ -static inline int helper_l4_filter( +static inline nve32_t helper_l4_filter( struct osi_core_priv_data *const osi_core, struct osi_l3_l4_filter l_filter, - unsigned int type, - unsigned int dma_routing_enable, - unsigned int dma_chan) + nveu32_t type, + nveu32_t dma_routing_enable, + nveu32_t dma_chan) { struct osi_core_ops *op = osi_core->ops; @@ -337,12 +337,12 @@ static inline int helper_l4_filter( * @retval 0 on Success * @retval -1 on Failure */ -static inline int helper_l3_filter( +static inline nve32_t helper_l3_filter( struct osi_core_priv_data *const osi_core, struct osi_l3_l4_filter l_filter, - unsigned int type, - unsigned int dma_routing_enable, - unsigned int dma_chan) + nveu32_t type, + nveu32_t dma_routing_enable, + nveu32_t dma_chan) { struct osi_core_ops *op = osi_core->ops; @@ -389,12 +389,12 @@ static inline int helper_l3_filter( } } -int osi_l3l4_filter(struct osi_core_priv_data *const osi_core, - const struct osi_l3_l4_filter l_filter, const unsigned int type, - const unsigned int dma_routing_enable, const unsigned int dma_chan, - const unsigned int is_l4_filter) +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) { - int ret = -1; + nve32_t ret = -1; if (osi_core == OSI_NULL || osi_core->ops == OSI_NULL || osi_core->base == OSI_NULL) { @@ -443,9 +443,8 @@ int osi_l3l4_filter(struct osi_core_priv_data *const osi_core, return ret; } -int osi_config_rxcsum_offload( - struct osi_core_priv_data *const osi_core, - const unsigned int enable) +nve32_t osi_config_rxcsum_offload(struct osi_core_priv_data *const osi_core, + const nveu32_t enable) { if (osi_core != OSI_NULL && osi_core->ops != OSI_NULL && osi_core->base != OSI_NULL && @@ -457,8 +456,8 @@ int osi_config_rxcsum_offload( return -1; } -int osi_set_systime_to_mac(struct osi_core_priv_data *const osi_core, - const unsigned int sec, const unsigned int nsec) +nve32_t osi_set_systime_to_mac(struct osi_core_priv_data *const osi_core, + const nveu32_t sec, const nveu32_t nsec) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->base != OSI_NULL) && @@ -494,11 +493,11 @@ int osi_set_systime_to_mac(struct osi_core_priv_data *const osi_core, * * @returns Quotient */ -static inline unsigned long div_u64_rem(unsigned long dividend, - unsigned long divisor, - unsigned long *remain) +static inline nveu64_t div_u64_rem(nveu64_t dividend, + nveu64_t divisor, + nveu64_t *remain) { - unsigned long ret = 0; + nveu64_t ret = 0; if (divisor != 0U) { *remain = dividend % divisor; @@ -526,22 +525,22 @@ static inline unsigned long div_u64_rem(unsigned long dividend, * - De-initialization: No * @returns Quotient */ -static inline unsigned long div_u64(unsigned long dividend, - unsigned long divisor) +static inline nveu64_t div_u64(nveu64_t dividend, + nveu64_t divisor) { - unsigned long remain; + nveu64_t remain; return div_u64_rem(dividend, divisor, &remain); } -int osi_adjust_freq(struct osi_core_priv_data *const osi_core, int ppb) +nve32_t osi_adjust_freq(struct osi_core_priv_data *const osi_core, nve32_t ppb) { - unsigned long adj; - unsigned long temp; - unsigned int diff = 0; - unsigned int addend; - unsigned int neg_adj = 0; - int ret = -1; + nveu64_t adj; + nveu64_t temp; + nveu32_t diff = 0; + nveu32_t addend; + nveu32_t neg_adj = 0; + nve32_t ret = -1; if (ppb < 0) { neg_adj = 1U; @@ -553,7 +552,7 @@ int osi_adjust_freq(struct osi_core_priv_data *const osi_core, int ppb) } addend = osi_core->default_addend; - adj = (unsigned long)addend * (unsigned int)ppb; + adj = (nveu64_t)addend * (nveu32_t)ppb; /* * div_u64 will divide the "adj" by "1000000000ULL" @@ -561,7 +560,7 @@ int osi_adjust_freq(struct osi_core_priv_data *const osi_core, int ppb) */ temp = div_u64(adj, OSI_NSEC_PER_SEC); if (temp < UINT_MAX) { - diff = (unsigned int)temp; + diff = (nveu32_t)temp; } else { OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "temp > UINT_MAX\n", 0ULL); @@ -599,15 +598,15 @@ int osi_adjust_freq(struct osi_core_priv_data *const osi_core, int ppb) return ret; } -int osi_adjust_time(struct osi_core_priv_data *const osi_core, - long long nsec_delta) +nve32_t osi_adjust_time(struct osi_core_priv_data *const osi_core, + nvel64_t nsec_delta) { - unsigned int neg_adj = 0; - unsigned int sec = 0, nsec = 0; - unsigned long quotient; - unsigned long reminder = 0; - unsigned long udelta = 0; - int ret = -1; + 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; if (osi_core == OSI_NULL) { return ret; @@ -617,17 +616,17 @@ int osi_adjust_time(struct osi_core_priv_data *const osi_core, neg_adj = 1; nsec_delta = -nsec_delta; } - udelta = (unsigned long long) nsec_delta; + udelta = (nveul64_t)nsec_delta; quotient = div_u64_rem(udelta, OSI_NSEC_PER_SEC, &reminder); if (quotient <= UINT_MAX) { - sec = (unsigned int)quotient; + sec = (nveu32_t)quotient; } else { OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "quotient > UINT_MAX\n", 0ULL); return ret; } if (reminder <= UINT_MAX) { - nsec = (unsigned int)reminder; + nsec = (nveu32_t)reminder; } else { OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "reminder > UINT_MAX\n", 0ULL); @@ -647,12 +646,12 @@ int osi_adjust_time(struct osi_core_priv_data *const osi_core, return ret; } -int osi_ptp_configuration(struct osi_core_priv_data *const osi_core, - const unsigned int enable) +nve32_t osi_ptp_configuration(struct osi_core_priv_data *const osi_core, + const nveu32_t enable) { - int ret = 0; - unsigned long temp = 0, temp1 = 0, temp2 = 0; - unsigned long ssinc = 0; + nve32_t ret = 0; + nveu64_t temp = 0, temp1 = 0, temp2 = 0; + nveu64_t ssinc = 0; if ((osi_core == OSI_NULL) || (osi_core->ops == OSI_NULL) || (osi_core->base == OSI_NULL) || @@ -688,16 +687,16 @@ int osi_ptp_configuration(struct osi_core_priv_data *const osi_core, ssinc = OSI_PTP_SSINC_4; } - temp = ((unsigned long)1000 << 32); - temp = (unsigned long)temp * 1000000U; + temp = ((nveu64_t)1000 << 32); + temp = (nveu64_t)temp * 1000000U; temp1 = div_u64(temp, - (unsigned long)osi_core->ptp_config.ptp_ref_clk_rate); + (nveu64_t)osi_core->ptp_config.ptp_ref_clk_rate); - temp2 = div_u64(temp1, (unsigned long)ssinc); + temp2 = div_u64(temp1, (nveu64_t)ssinc); if (temp2 < UINT_MAX) { - osi_core->default_addend = (unsigned int)temp2; + osi_core->default_addend = (nveu32_t)temp2; } else { OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "core: temp2 >= UINT_MAX\n", 0ULL); @@ -717,7 +716,7 @@ int osi_ptp_configuration(struct osi_core_priv_data *const osi_core, return ret; } -int osi_read_mmc(struct osi_core_priv_data *const osi_core) +nve32_t osi_read_mmc(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->base != OSI_NULL) && @@ -738,9 +737,9 @@ void osi_get_hw_features(void *base, struct osi_hw_features *hw_feat) return; } -int osi_get_mac_version(void *addr, unsigned int *mac_ver) +nve32_t osi_get_mac_version(void *addr, nveu32_t *mac_ver) { - int ret = -1; + nve32_t ret = -1; if ((addr != OSI_NULL) && (mac_ver != OSI_NULL)) { return common_get_mac_version(addr, mac_ver); @@ -750,9 +749,9 @@ int osi_get_mac_version(void *addr, unsigned int *mac_ver) } #ifndef OSI_STRIPPED_LIB -int osi_validate_core_regs(struct osi_core_priv_data *const osi_core) +nve32_t osi_validate_core_regs(struct osi_core_priv_data *const osi_core) { - int ret = -1; + nve32_t ret = -1; if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->base != OSI_NULL) && @@ -765,8 +764,8 @@ int osi_validate_core_regs(struct osi_core_priv_data *const osi_core) return ret; } -int osi_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, - const unsigned int qinx) +nve32_t osi_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, + const nveu32_t qinx) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->base != OSI_NULL) && @@ -777,8 +776,8 @@ int osi_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, return -1; } -int osi_set_avb(struct osi_core_priv_data *const osi_core, - const struct osi_core_avb_algorithm *avb) +nve32_t osi_set_avb(struct osi_core_priv_data *const osi_core, + const struct osi_core_avb_algorithm *avb) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->base != OSI_NULL) && @@ -789,8 +788,8 @@ int osi_set_avb(struct osi_core_priv_data *const osi_core, return -1; } -int osi_get_avb(struct osi_core_priv_data *const osi_core, - struct osi_core_avb_algorithm *avb) +nve32_t osi_get_avb(struct osi_core_priv_data *const osi_core, + struct osi_core_avb_algorithm *avb) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->base != OSI_NULL) && @@ -801,8 +800,8 @@ int osi_get_avb(struct osi_core_priv_data *const osi_core, return -1; } -int osi_configure_txstatus(struct osi_core_priv_data *const osi_core, - const unsigned int tx_status) +nve32_t osi_configure_txstatus(struct osi_core_priv_data *const osi_core, + const nveu32_t tx_status) { /* Configure Drop Transmit Status */ if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && @@ -815,8 +814,8 @@ int osi_configure_txstatus(struct osi_core_priv_data *const osi_core, return -1; } -int osi_config_rx_crc_check(struct osi_core_priv_data *const osi_core, - const unsigned int crc_chk) +nve32_t osi_config_rx_crc_check(struct osi_core_priv_data *const osi_core, + const nveu32_t crc_chk) { /* Configure CRC Checking for Received Packets */ if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && @@ -829,10 +828,10 @@ int osi_config_rx_crc_check(struct osi_core_priv_data *const osi_core, return -1; } -int osi_config_vlan_filtering(struct osi_core_priv_data *const osi_core, - const unsigned int filter_enb_dis, - const unsigned int perfect_hash_filtering, - const unsigned int perfect_inverse_match) +nve32_t osi_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) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->base != OSI_NULL) && @@ -847,8 +846,8 @@ int osi_config_vlan_filtering(struct osi_core_priv_data *const osi_core, return -1; } -int osi_update_vlan_id(struct osi_core_priv_data *const osi_core, - const unsigned int vid) +nve32_t osi_update_vlan_id(struct osi_core_priv_data *const osi_core, + const nveu32_t vid) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->update_vlan_id != OSI_NULL)) { @@ -859,9 +858,9 @@ int osi_update_vlan_id(struct osi_core_priv_data *const osi_core, return -1; } -int osi_get_systime_from_mac(struct osi_core_priv_data *const osi_core, - unsigned int *sec, - unsigned int *nsec) +nve32_t osi_get_systime_from_mac(struct osi_core_priv_data *const osi_core, + nveu32_t *sec, + nveu32_t *nsec) { if ((osi_core != OSI_NULL) && (osi_core->base != OSI_NULL)) { common_get_systime_from_mac(osi_core->base, osi_core->mac, sec, @@ -873,7 +872,7 @@ int osi_get_systime_from_mac(struct osi_core_priv_data *const osi_core, return 0; } -int osi_reset_mmc(struct osi_core_priv_data *const osi_core) +nve32_t osi_reset_mmc(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->base != OSI_NULL) && @@ -885,8 +884,8 @@ int osi_reset_mmc(struct osi_core_priv_data *const osi_core) return -1; } -int osi_configure_eee(struct osi_core_priv_data *const osi_core, - unsigned int tx_lpi_enabled, unsigned int tx_lpi_timer) +nve32_t osi_configure_eee(struct osi_core_priv_data *const osi_core, + nveu32_t tx_lpi_enabled, nveu32_t tx_lpi_timer) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->base != OSI_NULL) && @@ -902,7 +901,7 @@ int osi_configure_eee(struct osi_core_priv_data *const osi_core, return -1; } -int osi_save_registers(struct osi_core_priv_data *const osi_core) +nve32_t osi_save_registers(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->base != OSI_NULL) && @@ -914,7 +913,7 @@ int osi_save_registers(struct osi_core_priv_data *const osi_core) return -1; } -int osi_restore_registers(struct osi_core_priv_data *const osi_core) +nve32_t osi_restore_registers(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->base != OSI_NULL) && @@ -926,8 +925,8 @@ int osi_restore_registers(struct osi_core_priv_data *const osi_core) return -1; } -int osi_configure_flow_control(struct osi_core_priv_data *const osi_core, - const unsigned int flw_ctrl) +nve32_t osi_configure_flow_control(struct osi_core_priv_data *const osi_core, + const nveu32_t flw_ctrl) { /* Configure Flow control settings */ if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && @@ -940,9 +939,9 @@ int osi_configure_flow_control(struct osi_core_priv_data *const osi_core, return -1; } -int osi_config_arp_offload(struct osi_core_priv_data *const osi_core, - const unsigned int flags, - const unsigned char *ip_addr) +nve32_t osi_config_arp_offload(struct osi_core_priv_data *const osi_core, + const nveu32_t flags, + const nveu8_t *ip_addr) { if (osi_core != OSI_NULL && osi_core->ops != OSI_NULL && (osi_core->base != OSI_NULL) && (ip_addr != OSI_NULL) && @@ -955,8 +954,8 @@ int osi_config_arp_offload(struct osi_core_priv_data *const osi_core, return -1; } -int osi_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, - const unsigned long csr_clk_rate) +nve32_t osi_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, + const nveu64_t csr_clk_rate) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->set_mdc_clk_rate != OSI_NULL)) { @@ -967,8 +966,8 @@ int osi_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, return -1; } -int osi_config_mac_loopback(struct osi_core_priv_data *const osi_core, - const unsigned int lb_mode) +nve32_t osi_config_mac_loopback(struct osi_core_priv_data *const osi_core, + const nveu32_t lb_mode) { /* Configure MAC loopback */ if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index febb711..369ac1c 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -23,6 +23,7 @@ #include <osi_common.h> #include "osi_dma_local.h" #include "eqos_dma.h" +#include "../osi/common/type.h" /** * @brief eqos_dma_safety_config - EQOS MAC DMA safety configuration @@ -53,8 +54,8 @@ static struct dma_func_safety eqos_dma_safety_config; * - Run time: Yes * - De-initialization: Yes */ -static inline void eqos_dma_safety_writel(unsigned int val, void *addr, - unsigned int idx) +static inline void eqos_dma_safety_writel(nveu32_t val, void *addr, + nveu32_t idx) { struct dma_func_safety *config = &eqos_dma_safety_config; @@ -87,9 +88,9 @@ static inline void eqos_dma_safety_writel(unsigned int val, void *addr, static void eqos_dma_safety_init(struct osi_dma_priv_data *osi_dma) { struct dma_func_safety *config = &eqos_dma_safety_config; - unsigned char *base = (unsigned char *)osi_dma->base; - unsigned int val; - unsigned int i, idx; + 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. @@ -133,7 +134,7 @@ static void eqos_dma_safety_init(struct osi_dma_priv_data *osi_dma) if (config->reg_addr[i] == OSI_NULL) { continue; } - val = osi_readl((unsigned char *)config->reg_addr[i]); + val = osi_readl((nveu8_t *)config->reg_addr[i]); config->reg_val[i] = val & config->reg_mask[i]; } @@ -159,29 +160,29 @@ static void eqos_dma_safety_init(struct osi_dma_priv_data *osi_dma) * - Run time: Yes * - De-initialization: Yes */ -static void eqos_disable_chan_tx_intr(void *addr, unsigned int chan) +static void eqos_disable_chan_tx_intr(void *addr, nveu32_t chan) { - unsigned int cntrl, status; + nveu32_t cntrl, status; CHECK_CHAN_BOUND(chan); /* Clear irq before disabling */ - status = osi_readl((unsigned char *)addr + + 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, - (unsigned char *)addr + EQOS_DMA_CHX_STATUS(chan)); + (nveu8_t *)addr + EQOS_DMA_CHX_STATUS(chan)); osi_writel(EQOS_VIRT_INTR_CHX_STATUS_TX, - (unsigned char *)addr + + (nveu8_t *)addr + EQOS_VIRT_INTR_CHX_STATUS(chan)); } /* Disable the irq */ - cntrl = osi_readl((unsigned char *)addr + + cntrl = osi_readl((nveu8_t *)addr + EQOS_VIRT_INTR_CHX_CNTRL(chan)); cntrl &= ~EQOS_VIRT_INTR_CHX_CNTRL_TX; - osi_writel(cntrl, (unsigned char *)addr + + osi_writel(cntrl, (nveu8_t *)addr + EQOS_VIRT_INTR_CHX_CNTRL(chan)); } @@ -204,16 +205,16 @@ static void eqos_disable_chan_tx_intr(void *addr, unsigned int chan) * - Run time: Yes * - De-initialization: No */ -static void eqos_enable_chan_tx_intr(void *addr, unsigned int chan) +static void eqos_enable_chan_tx_intr(void *addr, nveu32_t chan) { - unsigned int cntrl; + nveu32_t cntrl; CHECK_CHAN_BOUND(chan); - cntrl = osi_readl((unsigned char *)addr + + cntrl = osi_readl((nveu8_t *)addr + EQOS_VIRT_INTR_CHX_CNTRL(chan)); cntrl |= EQOS_VIRT_INTR_CHX_CNTRL_TX; - osi_writel(cntrl, (unsigned char *)addr + + osi_writel(cntrl, (nveu8_t *)addr + EQOS_VIRT_INTR_CHX_CNTRL(chan)); } @@ -236,29 +237,29 @@ static void eqos_enable_chan_tx_intr(void *addr, unsigned int chan) * - Run time: Yes * - De-initialization: Yes */ -static void eqos_disable_chan_rx_intr(void *addr, unsigned int chan) +static void eqos_disable_chan_rx_intr(void *addr, nveu32_t chan) { - unsigned int cntrl, status; + nveu32_t cntrl, status; CHECK_CHAN_BOUND(chan); /* Clear irq before disabling */ - status = osi_readl((unsigned char *)addr + + 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, - (unsigned char *)addr + EQOS_DMA_CHX_STATUS(chan)); + (nveu8_t *)addr + EQOS_DMA_CHX_STATUS(chan)); osi_writel(EQOS_VIRT_INTR_CHX_STATUS_RX, - (unsigned char *)addr + + (nveu8_t *)addr + EQOS_VIRT_INTR_CHX_STATUS(chan)); } /* Disable irq */ - cntrl = osi_readl((unsigned char *)addr + + cntrl = osi_readl((nveu8_t *)addr + EQOS_VIRT_INTR_CHX_CNTRL(chan)); cntrl &= ~EQOS_VIRT_INTR_CHX_CNTRL_RX; - osi_writel(cntrl, (unsigned char *)addr + + osi_writel(cntrl, (nveu8_t *)addr + EQOS_VIRT_INTR_CHX_CNTRL(chan)); } @@ -279,16 +280,16 @@ static void eqos_disable_chan_rx_intr(void *addr, unsigned int chan) * - Run time: Yes * - De-initialization: No */ -static void eqos_enable_chan_rx_intr(void *addr, unsigned int chan) +static void eqos_enable_chan_rx_intr(void *addr, nveu32_t chan) { - unsigned int cntrl; + nveu32_t cntrl; CHECK_CHAN_BOUND(chan); - cntrl = osi_readl((unsigned char *)addr + + cntrl = osi_readl((nveu8_t *)addr + EQOS_VIRT_INTR_CHX_CNTRL(chan)); cntrl |= EQOS_VIRT_INTR_CHX_CNTRL_RX; - osi_writel(cntrl, (unsigned char *)addr + + osi_writel(cntrl, (nveu8_t *)addr + EQOS_VIRT_INTR_CHX_CNTRL(chan)); } @@ -310,11 +311,11 @@ static void eqos_enable_chan_rx_intr(void *addr, unsigned int chan) * - Run time: No * - De-initialization: No */ -static void eqos_set_tx_ring_len(void *addr, unsigned int chan, - unsigned int len) +static void eqos_set_tx_ring_len(void *addr, nveu32_t chan, + nveu32_t len) { CHECK_CHAN_BOUND(chan); - eqos_dma_safety_writel(len, (unsigned char *)addr + + eqos_dma_safety_writel(len, (nveu8_t *)addr + EQOS_DMA_CHX_TDRL(chan), EQOS_DMA_CH0_TDRL_IDX + chan); } @@ -337,22 +338,22 @@ static void eqos_set_tx_ring_len(void *addr, unsigned int chan, * - Run time: No * - De-initialization: No */ -static void eqos_set_tx_ring_start_addr(void *addr, unsigned int chan, - unsigned long tx_desc) +static void eqos_set_tx_ring_start_addr(void *addr, nveu32_t chan, + nveu64_t tx_desc) { - unsigned long tmp; + nveu64_t tmp; CHECK_CHAN_BOUND(chan); tmp = H32(tx_desc); if (tmp < UINT_MAX) { - osi_writel((unsigned int)tmp, (unsigned char *)addr + + osi_writel((nveu32_t)tmp, (nveu8_t *)addr + EQOS_DMA_CHX_TDLH(chan)); } tmp = L32(tx_desc); if (tmp < UINT_MAX) { - osi_writel((unsigned int)tmp, (unsigned char *)addr + + osi_writel((nveu32_t)tmp, (nveu8_t *)addr + EQOS_DMA_CHX_TDLA(chan)); } } @@ -380,16 +381,16 @@ static void eqos_set_tx_ring_start_addr(void *addr, unsigned int chan, * - Run time: Yes * - De-initialization: No */ -static void eqos_update_tx_tailptr(void *addr, unsigned int chan, - unsigned long tailptr) +static void eqos_update_tx_tailptr(void *addr, nveu32_t chan, + nveu64_t tailptr) { - unsigned long tmp; + nveu64_t tmp; CHECK_CHAN_BOUND(chan); tmp = L32(tailptr); if (tmp < UINT_MAX) { - osi_writel((unsigned int)tmp, (unsigned char *)addr + + osi_writel((nveu32_t)tmp, (nveu8_t *)addr + EQOS_DMA_CHX_TDTP(chan)); } } @@ -412,11 +413,11 @@ static void eqos_update_tx_tailptr(void *addr, unsigned int chan, * - Run time: No * - De-initialization: No */ -static void eqos_set_rx_ring_len(void *addr, unsigned int chan, - unsigned int len) +static void eqos_set_rx_ring_len(void *addr, nveu32_t chan, + nveu32_t len) { CHECK_CHAN_BOUND(chan); - eqos_dma_safety_writel(len, (unsigned char *)addr + + eqos_dma_safety_writel(len, (nveu8_t *)addr + EQOS_DMA_CHX_RDRL(chan), EQOS_DMA_CH0_RDRL_IDX + chan); } @@ -439,22 +440,22 @@ static void eqos_set_rx_ring_len(void *addr, unsigned int chan, * - Run time: No * - De-initialization: No */ -static void eqos_set_rx_ring_start_addr(void *addr, unsigned int chan, - unsigned long rx_desc) +static void eqos_set_rx_ring_start_addr(void *addr, nveu32_t chan, + nveu64_t rx_desc) { - unsigned long tmp; + nveu64_t tmp; CHECK_CHAN_BOUND(chan); tmp = H32(rx_desc); if (tmp < UINT_MAX) { - osi_writel((unsigned int)tmp, (unsigned char *)addr + + osi_writel((nveu32_t)tmp, (nveu8_t *)addr + EQOS_DMA_CHX_RDLH(chan)); } tmp = L32(rx_desc); if (tmp < UINT_MAX) { - osi_writel((unsigned int)tmp, (unsigned char *)addr + + osi_writel((nveu32_t)tmp, (nveu8_t *)addr + EQOS_DMA_CHX_RDLA(chan)); } } @@ -481,16 +482,16 @@ static void eqos_set_rx_ring_start_addr(void *addr, unsigned int chan, * - Run time: Yes * - De-initialization: No */ -static void eqos_update_rx_tailptr(void *addr, unsigned int chan, - unsigned long tailptr) +static void eqos_update_rx_tailptr(void *addr, nveu32_t chan, + nveu64_t tailptr) { - unsigned long tmp; + nveu64_t tmp; CHECK_CHAN_BOUND(chan); tmp = L32(tailptr); if (tmp < UINT_MAX) { - osi_writel((unsigned int)tmp, (unsigned char *)addr + + osi_writel((nveu32_t)tmp, (nveu8_t *)addr + EQOS_DMA_CHX_RDTP(chan)); } } @@ -516,23 +517,23 @@ static void eqos_update_rx_tailptr(void *addr, unsigned int chan, * - Run time: No * - De-initialization: No */ -static void eqos_start_dma(void *addr, unsigned int chan) +static void eqos_start_dma(void *addr, nveu32_t chan) { - unsigned int val; + nveu32_t val; CHECK_CHAN_BOUND(chan); /* start Tx DMA */ - val = osi_readl((unsigned char *)addr + EQOS_DMA_CHX_TX_CTRL(chan)); + val = osi_readl((nveu8_t *)addr + EQOS_DMA_CHX_TX_CTRL(chan)); val |= OSI_BIT(0); - eqos_dma_safety_writel(val, (unsigned char *)addr + + eqos_dma_safety_writel(val, (nveu8_t *)addr + EQOS_DMA_CHX_TX_CTRL(chan), EQOS_DMA_CH0_TX_CTRL_IDX + chan); /* start Rx DMA */ - val = osi_readl((unsigned char *)addr + EQOS_DMA_CHX_RX_CTRL(chan)); + val = osi_readl((nveu8_t *)addr + EQOS_DMA_CHX_RX_CTRL(chan)); val |= OSI_BIT(0); - eqos_dma_safety_writel(val, (unsigned char *)addr + + eqos_dma_safety_writel(val, (nveu8_t *)addr + EQOS_DMA_CHX_RX_CTRL(chan), EQOS_DMA_CH0_RX_CTRL_IDX + chan); } @@ -558,23 +559,23 @@ static void eqos_start_dma(void *addr, unsigned int chan) * - Run time: No * - De-initialization: Yes */ -static void eqos_stop_dma(void *addr, unsigned int chan) +static void eqos_stop_dma(void *addr, nveu32_t chan) { - unsigned int val; + nveu32_t val; CHECK_CHAN_BOUND(chan); /* stop Tx DMA */ - val = osi_readl((unsigned char *)addr + EQOS_DMA_CHX_TX_CTRL(chan)); + val = osi_readl((nveu8_t *)addr + EQOS_DMA_CHX_TX_CTRL(chan)); val &= ~OSI_BIT(0); - eqos_dma_safety_writel(val, (unsigned char *)addr + + eqos_dma_safety_writel(val, (nveu8_t *)addr + EQOS_DMA_CHX_TX_CTRL(chan), EQOS_DMA_CH0_TX_CTRL_IDX + chan); /* stop Rx DMA */ - val = osi_readl((unsigned char *)addr + EQOS_DMA_CHX_RX_CTRL(chan)); + val = osi_readl((nveu8_t *)addr + EQOS_DMA_CHX_RX_CTRL(chan)); val &= ~OSI_BIT(0); - eqos_dma_safety_writel(val, (unsigned char *)addr + + eqos_dma_safety_writel(val, (nveu8_t *)addr + EQOS_DMA_CHX_RX_CTRL(chan), EQOS_DMA_CH0_RX_CTRL_IDX + chan); } @@ -603,10 +604,10 @@ static void eqos_stop_dma(void *addr, unsigned int chan) * - Run time: No * - De-initialization: No */ -static void eqos_configure_dma_channel(unsigned int chan, +static void eqos_configure_dma_channel(nveu32_t chan, struct osi_dma_priv_data *osi_dma) { - unsigned int value; + nveu32_t value; CHECK_CHAN_BOUND(chan); @@ -619,7 +620,7 @@ static void eqos_configure_dma_channel(unsigned int chan, /* AIE - Abnormal Interrupt Summary Enable */ /* NIE - Normal Interrupt Summary Enable */ /* FBE - Fatal Bus Error Enable */ - value = osi_readl((unsigned char *)osi_dma->base + + value = osi_readl((nveu8_t *)osi_dma->base + EQOS_DMA_CHX_INTR_ENA(chan)); if (!osi_dma->use_virtualization) { value |= EQOS_DMA_CHX_INTR_TBUE | @@ -631,20 +632,20 @@ static void eqos_configure_dma_channel(unsigned int chan, 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(value, (unsigned char *)osi_dma->base + + eqos_dma_safety_writel(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((unsigned char *)osi_dma->base + + value = osi_readl((nveu8_t *)osi_dma->base + EQOS_DMA_CHX_CTRL(chan)); value |= EQOS_DMA_CHX_CTRL_PBLX8; - eqos_dma_safety_writel(value, (unsigned char *)osi_dma->base + + eqos_dma_safety_writel(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((unsigned char *)osi_dma->base + + value = osi_readl((nveu8_t *)osi_dma->base + EQOS_DMA_CHX_TX_CTRL(chan)); /* Enable OSF mode */ value |= EQOS_DMA_CHX_TX_CTRL_OSF; @@ -653,7 +654,7 @@ static void eqos_configure_dma_channel(unsigned int chan, /* enable TSO by default if HW supports */ value |= EQOS_DMA_CHX_TX_CTRL_TSE; - eqos_dma_safety_writel(value, (unsigned char *)osi_dma->base + + eqos_dma_safety_writel(value, (nveu8_t *)osi_dma->base + EQOS_DMA_CHX_TX_CTRL(chan), EQOS_DMA_CH0_TX_CTRL_IDX + chan); @@ -661,7 +662,7 @@ static void eqos_configure_dma_channel(unsigned int chan, /* Select Rx Buffer size. Needs to be rounded up to next multiple of * bus width */ - value = osi_readl((unsigned char *)osi_dma->base + + value = osi_readl((nveu8_t *)osi_dma->base + EQOS_DMA_CHX_RX_CTRL(chan)); /* clear previous Rx buffer size */ @@ -670,7 +671,7 @@ static void eqos_configure_dma_channel(unsigned int chan, 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(value, (unsigned char *)osi_dma->base + + eqos_dma_safety_writel(value, (nveu8_t *)osi_dma->base + EQOS_DMA_CHX_RX_CTRL(chan), EQOS_DMA_CH0_RX_CTRL_IDX + chan); @@ -683,7 +684,7 @@ static void eqos_configure_dma_channel(unsigned int chan, * 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((unsigned char *)osi_dma->base + + 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 | @@ -694,7 +695,7 @@ static void eqos_configure_dma_channel(unsigned int chan, 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, (unsigned char *)osi_dma->base + + osi_writel(value, (nveu8_t *)osi_dma->base + EQOS_DMA_CHX_RX_WDT(chan)); } } @@ -716,8 +717,8 @@ static void eqos_configure_dma_channel(unsigned int chan, static void eqos_dma_chan_to_vmirq_map(struct osi_dma_priv_data *osi_dma) { struct osi_vm_irq_data *irq_data; - unsigned int i, j; - unsigned int chan; + nveu32_t i, j; + nveu32_t chan; for (i = 0; i < osi_dma->num_vm_irqs; i++) { irq_data = &osi_dma->irq_data[i]; @@ -727,7 +728,7 @@ static void eqos_dma_chan_to_vmirq_map(struct osi_dma_priv_data *osi_dma) continue; } osi_writel(OSI_BIT(i), - (unsigned char *)osi_dma->base + + (nveu8_t *)osi_dma->base + EQOS_VIRT_INTR_APB_CHX_CNTRL(chan)); } } @@ -747,9 +748,9 @@ static void eqos_dma_chan_to_vmirq_map(struct osi_dma_priv_data *osi_dma) * @retval 0 on success * @retval -1 on failure. */ -static int eqos_init_dma_channel(struct osi_dma_priv_data *osi_dma) +static nve32_t eqos_init_dma_channel(struct osi_dma_priv_data *osi_dma) { - unsigned int chinx; + nveu32_t chinx; eqos_dma_safety_init(osi_dma); @@ -787,7 +788,7 @@ static int eqos_init_dma_channel(struct osi_dma_priv_data *osi_dma) */ static void eqos_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) { - unsigned int rx_buf_len = 0U; + 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) { @@ -830,12 +831,12 @@ static void eqos_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) * @retval 0 on success * @retval -1 on failure. */ -static int eqos_validate_dma_regs(struct osi_dma_priv_data *osi_dma) +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; - unsigned int cur_val; - unsigned int i; + 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++) { @@ -843,7 +844,7 @@ static int eqos_validate_dma_regs(struct osi_dma_priv_data *osi_dma) continue; } - cur_val = osi_readl((unsigned char *)config->reg_addr[i]); + cur_val = osi_readl((nveu8_t *)config->reg_addr[i]); cur_val &= config->reg_mask[i]; if (cur_val == config->reg_val[i]) { @@ -887,17 +888,17 @@ static int eqos_validate_dma_regs(struct osi_dma_priv_data *osi_dma) * @retval none */ static void eqos_config_slot(struct osi_dma_priv_data *osi_dma, - unsigned int chan, - unsigned int set, - unsigned int interval) + nveu32_t chan, + nveu32_t set, + nveu32_t interval) { - unsigned int value; + nveu32_t value; CHECK_CHAN_BOUND(chan); if (set == OSI_ENABLE) { /* Program SLOT CTRL register SIV and set ESC bit */ - value = osi_readl((unsigned char *)osi_dma->base + + 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 */ @@ -905,15 +906,15 @@ static void eqos_config_slot(struct osi_dma_priv_data *osi_dma, value |= (interval << EQOS_DMA_CHX_SLOT_SIV_SHIFT); /* Set ESC bit */ value |= EQOS_DMA_CHX_SLOT_ESC; - osi_writel(value, (unsigned char *)osi_dma->base + + 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((unsigned char *)osi_dma->base + + value = osi_readl((nveu8_t *)osi_dma->base + EQOS_DMA_CHX_SLOT_CTRL(chan)); value &= ~EQOS_DMA_CHX_SLOT_ESC; - osi_writel(value, (unsigned char *)osi_dma->base + + osi_writel(value, (nveu8_t *)osi_dma->base + EQOS_DMA_CHX_SLOT_CTRL(chan)); } } @@ -932,9 +933,9 @@ static void eqos_config_slot(struct osi_dma_priv_data *osi_dma, * * @retval status */ -static unsigned int eqos_get_global_dma_status(void *addr) +static nveu32_t eqos_get_global_dma_status(void *addr) { - return osi_readl((unsigned char *)addr + EQOS_GLOBAL_DMA_STATUS); + return osi_readl((nveu8_t *)addr + EQOS_GLOBAL_DMA_STATUS); } /** @@ -950,14 +951,14 @@ static unsigned int eqos_get_global_dma_status(void *addr) * Protection: None. * @retval None. */ -static void eqos_clear_vm_tx_intr(void *addr, unsigned int chan) +static void eqos_clear_vm_tx_intr(void *addr, nveu32_t chan) { CHECK_CHAN_BOUND(chan); osi_writel(EQOS_DMA_CHX_STATUS_CLEAR_TX, - (unsigned char *)addr + EQOS_DMA_CHX_STATUS(chan)); + (nveu8_t *)addr + EQOS_DMA_CHX_STATUS(chan)); osi_writel(EQOS_VIRT_INTR_CHX_STATUS_TX, - (unsigned char *)addr + EQOS_VIRT_INTR_CHX_STATUS(chan)); + (nveu8_t *)addr + EQOS_VIRT_INTR_CHX_STATUS(chan)); } /** @@ -974,14 +975,14 @@ static void eqos_clear_vm_tx_intr(void *addr, unsigned int chan) * * @retval None. */ -static void eqos_clear_vm_rx_intr(void *addr, unsigned int chan) +static void eqos_clear_vm_rx_intr(void *addr, nveu32_t chan) { CHECK_CHAN_BOUND(chan); osi_writel(EQOS_DMA_CHX_STATUS_CLEAR_RX, - (unsigned char *)addr + EQOS_DMA_CHX_STATUS(chan)); + (nveu8_t *)addr + EQOS_DMA_CHX_STATUS(chan)); osi_writel(EQOS_VIRT_INTR_CHX_STATUS_RX, - (unsigned char *)addr + EQOS_VIRT_INTR_CHX_STATUS(chan)); + (nveu8_t *)addr + EQOS_VIRT_INTR_CHX_STATUS(chan)); } static struct osi_dma_chan_ops eqos_dma_chan_ops = { diff --git a/osi/dma/eqos_dma.h b/osi/dma/eqos_dma.h index 96b7755..9715194 100644 --- a/osi/dma/eqos_dma.h +++ b/osi/dma/eqos_dma.h @@ -151,12 +151,12 @@ struct dma_func_safety { 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) */ - unsigned int reg_mask[EQOS_MAX_DMA_SAFETY_REGS]; + nveu32_t reg_mask[EQOS_MAX_DMA_SAFETY_REGS]; /** Array of value stored in each corresponding register */ - unsigned int reg_val[EQOS_MAX_DMA_SAFETY_REGS]; + nveu32_t reg_val[EQOS_MAX_DMA_SAFETY_REGS]; /** OSI lock variable used to protect writes to reg * while validation is in-progress */ - unsigned int dma_safety_lock; + nveu32_t dma_safety_lock; }; /** diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 131b188..415b2df 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -24,7 +24,7 @@ #include <osd.h> #include <local_common.h> -int osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) +nve32_t osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) { if (osi_dma == OSI_NULL) { return -1; @@ -65,10 +65,10 @@ int osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) return -1; } -int osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) +nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) { - unsigned int i, chan; - int ret = -1; + nveu32_t i, chan; + nve32_t ret = -1; if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && (osi_dma->base != OSI_NULL) && @@ -118,10 +118,10 @@ int osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) return ret; } -int osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma) +nve32_t osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma) { - unsigned int i; - int ret = 0; + nveu32_t i; + nve32_t ret = 0; if ((osi_dma == OSI_NULL) || (osi_dma->num_dma_chans > OSI_EQOS_MAX_NUM_CHANS)) { @@ -138,8 +138,8 @@ int osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma) return ret; } -int osi_disable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, - unsigned int chan) +nve32_t osi_disable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, + nveu32_t chan) { if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && (osi_dma->base != OSI_NULL) && (chan < OSI_EQOS_MAX_NUM_CHANS) && @@ -151,8 +151,8 @@ int osi_disable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, return -1; } -int osi_enable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, - unsigned int chan) +nve32_t osi_enable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, + nveu32_t chan) { if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && (osi_dma->base != OSI_NULL) && (chan < OSI_EQOS_MAX_NUM_CHANS) && @@ -164,8 +164,8 @@ int osi_enable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, return -1; } -int osi_disable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, - unsigned int chan) +nve32_t osi_disable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, + nveu32_t chan) { if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && (osi_dma->base != OSI_NULL) && (chan < OSI_EQOS_MAX_NUM_CHANS) && @@ -177,8 +177,8 @@ int osi_disable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, return -1; } -int osi_enable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, - unsigned int chan) +nve32_t osi_enable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, + nveu32_t chan) { if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && (osi_dma->base != OSI_NULL) && (chan < OSI_EQOS_MAX_NUM_CHANS) && @@ -190,8 +190,8 @@ int osi_enable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, return -1; } -int osi_clear_vm_tx_intr(struct osi_dma_priv_data *osi_dma, - unsigned int chan) +nve32_t osi_clear_vm_tx_intr(struct osi_dma_priv_data *osi_dma, + nveu32_t chan) { if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && (osi_dma->ops->clear_vm_tx_intr != OSI_NULL)) { @@ -202,8 +202,8 @@ int osi_clear_vm_tx_intr(struct osi_dma_priv_data *osi_dma, return -1; } -int osi_clear_vm_rx_intr(struct osi_dma_priv_data *osi_dma, - unsigned int chan) +nve32_t osi_clear_vm_rx_intr(struct osi_dma_priv_data *osi_dma, + nveu32_t chan) { if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && (osi_dma->ops->clear_vm_rx_intr != OSI_NULL)) { @@ -214,7 +214,7 @@ int osi_clear_vm_rx_intr(struct osi_dma_priv_data *osi_dma, return -1; } -unsigned int osi_get_global_dma_status(struct osi_dma_priv_data *osi_dma) +nveu32_t osi_get_global_dma_status(struct osi_dma_priv_data *osi_dma) { if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && (osi_dma->ops->get_global_dma_status != OSI_NULL)) { @@ -224,8 +224,8 @@ unsigned int osi_get_global_dma_status(struct osi_dma_priv_data *osi_dma) return 0; } -int osi_start_dma(struct osi_dma_priv_data *osi_dma, - unsigned int chan) +nve32_t osi_start_dma(struct osi_dma_priv_data *osi_dma, + nveu32_t chan) { if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && (osi_dma->base != OSI_NULL) && (chan < OSI_EQOS_MAX_NUM_CHANS) && @@ -237,8 +237,8 @@ int osi_start_dma(struct osi_dma_priv_data *osi_dma, return -1; } -int osi_stop_dma(struct osi_dma_priv_data *osi_dma, - unsigned int chan) +nve32_t osi_stop_dma(struct osi_dma_priv_data *osi_dma, + nveu32_t chan) { if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && (osi_dma->base != OSI_NULL) && (chan < OSI_EQOS_MAX_NUM_CHANS) && @@ -250,7 +250,7 @@ int osi_stop_dma(struct osi_dma_priv_data *osi_dma, return -1; } -unsigned int osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring) +nveu32_t osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring) { if (rx_ring->cur_rx_idx >= RX_DESC_CNT || rx_ring->refill_idx >= RX_DESC_CNT) { @@ -278,9 +278,10 @@ unsigned int osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring) * @retval 0 on success * @retval -1 on failure. */ -static inline int rx_dma_desc_validate_args(struct osi_dma_priv_data *osi_dma, +static inline nve32_t rx_dma_desc_validate_args( + struct osi_dma_priv_data *osi_dma, struct osi_rx_ring *rx_ring, - unsigned int chan) + nveu32_t chan) { /* Validate args */ if (!(osi_dma != OSI_NULL && osi_dma->ops != OSI_NULL && @@ -341,12 +342,12 @@ static inline void rx_dma_handle_ioc(struct osi_dma_priv_data *osi_dma, } } -int osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, - struct osi_rx_ring *rx_ring, unsigned int chan) +nve32_t osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, + struct osi_rx_ring *rx_ring, nveu32_t chan) { /* for CERT-C error */ - unsigned long temp; - unsigned long tailptr = 0; + nveu64_t temp; + nveu64_t tailptr = 0; struct osi_rx_swcx *rx_swcx = OSI_NULL; struct osi_rx_desc *rx_desc = OSI_NULL; @@ -376,12 +377,13 @@ int osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, /* error case do nothing */ } else { /* Store Receive Descriptor 0 */ - rx_desc->rdes0 = (unsigned int)temp; + rx_desc->rdes0 = (nveu32_t)temp; } temp = H32(rx_swcx->buf_phy_addr); if (temp <= UINT_MAX) { - rx_desc->rdes1 = (unsigned int)temp; + /* Store Receive Descriptor 1 */ + rx_desc->rdes1 = (nveu32_t)temp; } else { OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "dma: Invalid buf_phy_addr\n", 0ULL); @@ -416,7 +418,7 @@ int osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, return 0; } -int osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) +nve32_t osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) { if (osi_dma != OSI_NULL && osi_dma->ops != OSI_NULL && osi_dma->ops->set_rx_buf_len != OSI_NULL) { @@ -428,8 +430,8 @@ int osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) return 0; } -int osi_dma_get_systime_from_mac(struct osi_dma_priv_data *const osi_dma, - unsigned int *sec, unsigned int *nsec) +nve32_t osi_dma_get_systime_from_mac(struct osi_dma_priv_data *const osi_dma, + nveu32_t *sec, nveu32_t *nsec) { if ((osi_dma != OSI_NULL) && (osi_dma->base != OSI_NULL)) { common_get_systime_from_mac(osi_dma->base, osi_dma->mac, sec, @@ -441,7 +443,7 @@ int osi_dma_get_systime_from_mac(struct osi_dma_priv_data *const osi_dma, return 0; } -unsigned int osi_is_mac_enabled(struct osi_dma_priv_data *const osi_dma) +nveu32_t osi_is_mac_enabled(struct osi_dma_priv_data *const osi_dma) { if ((osi_dma != OSI_NULL) && (osi_dma->base != OSI_NULL)) { return common_is_mac_enabled(osi_dma->base, osi_dma->mac); @@ -473,8 +475,8 @@ unsigned int osi_is_mac_enabled(struct osi_dma_priv_data *const osi_dma) * @retval 0 on success * @retval -1 on failure. */ -static inline int osi_slot_args_validate(struct osi_dma_priv_data *osi_dma, - unsigned int set) +static inline nve32_t osi_slot_args_validate(struct osi_dma_priv_data *osi_dma, + nveu32_t set) { if (osi_dma == OSI_NULL) { return -1; @@ -498,10 +500,10 @@ static inline int osi_slot_args_validate(struct osi_dma_priv_data *osi_dma, return 0; } -int osi_config_slot_function(struct osi_dma_priv_data *osi_dma, - unsigned int set) +nve32_t osi_config_slot_function(struct osi_dma_priv_data *osi_dma, + nveu32_t set) { - unsigned int i = 0U, chan = 0U, interval = 0U; + nveu32_t i = 0U, chan = 0U, interval = 0U; struct osi_tx_ring *tx_ring = OSI_NULL; /* Validate arguments */ @@ -548,9 +550,9 @@ int osi_config_slot_function(struct osi_dma_priv_data *osi_dma, return 0; } -int osi_validate_dma_regs(struct osi_dma_priv_data *osi_dma) +nve32_t osi_validate_dma_regs(struct osi_dma_priv_data *osi_dma) { - int ret = -1; + nve32_t ret = -1; if (osi_dma != OSI_NULL && osi_dma->ops != OSI_NULL && osi_dma->ops->validate_regs != OSI_NULL && osi_dma->safety_config != OSI_NULL) { @@ -560,7 +562,7 @@ int osi_validate_dma_regs(struct osi_dma_priv_data *osi_dma) return ret; } -int osi_txring_empty(struct osi_dma_priv_data *osi_dma, unsigned int chan) +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]; diff --git a/osi/dma/osi_dma_local.h b/osi/dma/osi_dma_local.h index 77a5005..c4ba9f8 100644 --- a/osi/dma/osi_dma_local.h +++ b/osi/dma/osi_dma_local.h @@ -48,5 +48,5 @@ * @retval 0 on success * @retval -1 on failure. */ -int dma_desc_init(struct osi_dma_priv_data *osi_dma); +nve32_t dma_desc_init(struct osi_dma_priv_data *osi_dma); #endif /* OSI_DMA_LOCAL_H */ diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index f6b2347..125ea00 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -23,6 +23,7 @@ #include <osd.h> #include "osi_dma_local.h" #include <osi_dma_txrx.h> +#include "../osi/common/type.h" /** * @brief get_rx_csum - Get the Rx checksum from descriptor if valid @@ -118,7 +119,7 @@ static inline void get_rx_csum(struct osi_rx_desc *rx_desc, static inline void get_rx_vlan_from_desc(struct osi_rx_desc *rx_desc, struct osi_rx_pkt_cx *rx_pkt_cx) { - unsigned int lt; + nveu32_t lt; /* Check for Receive Status rdes0 */ if ((rx_desc->rdes3 & RDES3_RS0V) == RDES3_RS0V) { @@ -150,7 +151,7 @@ static inline void get_rx_vlan_from_desc(struct osi_rx_desc *rx_desc, * @retval -1 if TimeStamp is not valid * @retval 0 if TimeStamp is valid. */ -static inline int get_rx_tstamp_status(struct osi_rx_desc *context_desc) +static inline nve32_t get_rx_tstamp_status(struct osi_rx_desc *context_desc) { if (((context_desc->rdes3 & RDES3_OWN) == 0U) && ((context_desc->rdes3 & RDES3_CTXT) == RDES3_CTXT)) { @@ -190,12 +191,12 @@ static inline int get_rx_tstamp_status(struct osi_rx_desc *context_desc) * @retval -1 if TimeStamp is not available * @retval 0 if TimeStamp is available. */ -static 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) +static nve32_t 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, ret = -1; + nve32_t retry, ret = -1; /* Check for RS1V/TSA/TD valid */ if (((rx_desc->rdes3 & RDES3_RS1V) == RDES3_RS1V) && @@ -293,9 +294,10 @@ static inline void get_rx_err_stats(struct osi_rx_desc *rx_desc, * @retval 0 on success * @retval -1 on failure. */ -static inline int validate_rx_completions_arg(struct osi_dma_priv_data *osi_dma, - unsigned int chan, - unsigned int *more_data_avail, +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) { @@ -322,9 +324,9 @@ static inline int validate_rx_completions_arg(struct osi_dma_priv_data *osi_dma, return 0; } -int osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, - unsigned int chan, int budget, - unsigned int *more_data_avail) +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; @@ -332,9 +334,9 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, 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; - int received = 0; - int received_resv = 0; - int ret = 0; + 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); @@ -499,7 +501,7 @@ int osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, * @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, - unsigned int chan) + nveu32_t chan) { osi_dma->dstats.q_tx_pkt_n[chan] = osi_update_stats_counter(osi_dma->dstats.q_tx_pkt_n[chan], 1UL); @@ -610,9 +612,9 @@ static inline void get_tx_err_stats(struct osi_tx_desc *tx_desc, } #ifndef OSI_STRIPPED_LIB -int osi_clear_tx_pkt_err_stats(struct osi_dma_priv_data *osi_dma) +nve32_t osi_clear_tx_pkt_err_stats(struct osi_dma_priv_data *osi_dma) { - int ret = -1; + nve32_t ret = -1; struct osi_pkt_err_stats *pkt_err_stats; if (osi_dma != OSI_NULL) { @@ -637,9 +639,9 @@ int osi_clear_tx_pkt_err_stats(struct osi_dma_priv_data *osi_dma) return ret; } -int osi_clear_rx_pkt_err_stats(struct osi_dma_priv_data *osi_dma) +nve32_t osi_clear_rx_pkt_err_stats(struct osi_dma_priv_data *osi_dma) { - int ret = -1; + nve32_t ret = -1; struct osi_pkt_err_stats *pkt_err_stats; if (osi_dma != OSI_NULL) { @@ -676,8 +678,9 @@ int osi_clear_rx_pkt_err_stats(struct osi_dma_priv_data *osi_dma) * @retval 0 on success * @retval -1 on failure. */ -static inline int validate_tx_completions_arg(struct osi_dma_priv_data *osi_dma, - unsigned int chan, +static inline nve32_t validate_tx_completions_arg( + struct osi_dma_priv_data *osi_dma, + nveu32_t chan, struct osi_tx_ring **tx_ring) { if (osi_unlikely(osi_dma == OSI_NULL || @@ -697,18 +700,18 @@ static inline int validate_tx_completions_arg(struct osi_dma_priv_data *osi_dma, return 0; } -int osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, - unsigned int chan, int budget) +nve32_t osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, + nveu32_t chan, nve32_t 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; - unsigned int entry = 0U; - unsigned long vartdes1; - unsigned long long ns; - int processed = 0; - int ret; + 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)) { @@ -832,10 +835,10 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, * @retval 0 - cntx desc not used * @retval 1 - cntx desc used. */ -static inline int need_cntx_desc(struct osi_tx_pkt_cx *tx_pkt_cx, - struct osi_tx_desc *tx_desc) +static inline nve32_t need_cntx_desc(struct osi_tx_pkt_cx *tx_pkt_cx, + struct osi_tx_desc *tx_desc) { - int ret = 0; + 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)) { @@ -893,17 +896,17 @@ static inline void fill_first_desc(struct osi_tx_ring *tx_ring, struct osi_tx_desc *tx_desc, struct osi_tx_swcx *tx_swcx) { - unsigned long tmp; + nveu64_t tmp; /* update the first buffer pointer and length */ tmp = L32(tx_swcx->buf_phy_addr); if (tmp < UINT_MAX) { - tx_desc->tdes0 = (unsigned int)tmp; + tx_desc->tdes0 = (nveu32_t)tmp; } tmp = H32(tx_swcx->buf_phy_addr); if (tmp < UINT_MAX) { - tx_desc->tdes1 = (unsigned int)tmp; + tx_desc->tdes1 = (nveu32_t)tmp; } tx_desc->tdes2 = tx_swcx->len; @@ -1006,8 +1009,9 @@ static inline void dmb_oshst(void) * @retval 0 on success * @retval -1 on failure. */ -static inline int validate_hw_transmit_arg(struct osi_dma_priv_data *osi_dma, - unsigned int chan, +static inline nve32_t validate_hw_transmit_arg( + struct osi_dma_priv_data *osi_dma, + nveu32_t chan, struct osi_dma_chan_ops **ops, struct osi_tx_ring **tx_ring) { @@ -1028,22 +1032,22 @@ static inline int validate_hw_transmit_arg(struct osi_dma_priv_data *osi_dma, return 0; } -void osi_hw_transmit(struct osi_dma_priv_data *osi_dma, unsigned int chan) +void osi_hw_transmit(struct osi_dma_priv_data *osi_dma, nveu32_t chan) { struct osi_tx_ring *tx_ring = OSI_NULL; struct osi_dma_chan_ops *ops = OSI_NULL; - unsigned int entry = 0U; + nveu32_t entry = 0U; struct osi_tx_desc *tx_desc = OSI_NULL; struct osi_tx_swcx *tx_swcx = OSI_NULL; struct osi_tx_pkt_cx *tx_pkt_cx = OSI_NULL; - unsigned int desc_cnt = 0U; + nveu32_t desc_cnt = 0U; struct osi_tx_desc *last_desc = OSI_NULL; struct osi_tx_desc *first_desc = OSI_NULL; struct osi_tx_desc *cx_desc = OSI_NULL; - unsigned long tailptr, tmp; - int cntx_desc_consumed; - unsigned int i; - int ret = 0; + nveu64_t tailptr, tmp; + nve32_t cntx_desc_consumed; + nveu32_t i; + nve32_t ret = 0; ret = validate_hw_transmit_arg(osi_dma, chan, &ops, &tx_ring); if (osi_unlikely(ret < 0)) { @@ -1107,12 +1111,12 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi_dma, unsigned int chan) for (i = 0; i < desc_cnt; i++) { tmp = L32(tx_swcx->buf_phy_addr); if (tmp < UINT_MAX) { - tx_desc->tdes0 = (unsigned int)tmp; + tx_desc->tdes0 = (nveu32_t)tmp; } tmp = H32(tx_swcx->buf_phy_addr); if (tmp < UINT_MAX) { - tx_desc->tdes1 = (unsigned int)tmp; + tx_desc->tdes1 = (nveu32_t)tmp; } tx_desc->tdes2 = tx_swcx->len; /* set HW OWN bit for descriptor*/ @@ -1207,16 +1211,16 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi_dma, unsigned int chan) * @retval 0 on success * @retval -1 on failure. */ -static int rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, - unsigned int chan) +static nve32_t rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, + nveu32_t chan) { struct osi_rx_ring *rx_ring = OSI_NULL; struct osi_rx_desc *rx_desc = OSI_NULL; struct osi_rx_swcx *rx_swcx = OSI_NULL; struct osi_dma_chan_ops *ops = osi_dma->ops; - unsigned long tailptr = 0, tmp; - unsigned int i; - int ret = 0; + nveu64_t tailptr = 0, tmp; + nveu32_t i; + nve32_t ret = 0; rx_ring = osi_dma->rx_ring[chan]; if (osi_unlikely(rx_ring == OSI_NULL)) { @@ -1240,7 +1244,7 @@ static int rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, tmp = L32(rx_swcx->buf_phy_addr); if (tmp < UINT_MAX) { - rx_desc->rdes0 = (unsigned int)tmp; + rx_desc->rdes0 = (nveu32_t)tmp; } else { OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "dma_txrx: Invalid buf_phy_addr\n", 0ULL); @@ -1249,7 +1253,7 @@ static int rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, tmp = H32(rx_swcx->buf_phy_addr); if (tmp < UINT_MAX) { - rx_desc->rdes1 = (unsigned int)tmp; + rx_desc->rdes1 = (nveu32_t)tmp; } else { OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "dma_txrx: Invalid buf_phy_addr\n", 0ULL); @@ -1316,11 +1320,11 @@ static int rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, * @retval 0 on success * @retval -1 on failure. */ -static int rx_dma_desc_init(struct osi_dma_priv_data *osi_dma) +static nve32_t rx_dma_desc_init(struct osi_dma_priv_data *osi_dma) { - unsigned int chan = 0; - unsigned int i; - int ret = 0; + 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]; @@ -1353,14 +1357,14 @@ static int rx_dma_desc_init(struct osi_dma_priv_data *osi_dma) * @retval 0 on success * @retval -1 on failure. */ -static int tx_dma_desc_init(struct osi_dma_priv_data *osi_dma) +static nve32_t tx_dma_desc_init(struct osi_dma_priv_data *osi_dma) { struct osi_tx_ring *tx_ring = OSI_NULL; struct osi_tx_desc *tx_desc = OSI_NULL; struct osi_tx_swcx *tx_swcx = OSI_NULL; struct osi_dma_chan_ops *ops = osi_dma->ops; - unsigned int chan = 0; - unsigned int i, j; + nveu32_t chan = 0; + nveu32_t i, j; for (i = 0; i < osi_dma->num_dma_chans; i++) { chan = osi_dma->dma_chans[i]; @@ -1410,9 +1414,9 @@ static int tx_dma_desc_init(struct osi_dma_priv_data *osi_dma) return 0; } -int dma_desc_init(struct osi_dma_priv_data *osi_dma) +nve32_t dma_desc_init(struct osi_dma_priv_data *osi_dma) { - int ret = 0; + nve32_t ret = 0; ret = tx_dma_desc_init(osi_dma); if (ret != 0) { From b61cec1c6d6416d857b10ada8d53244d5378d82d Mon Sep 17 00:00:00 2001 From: rakesh goyal <rgoyal@nvidia.com> Date: Wed, 2 Dec 2020 19:57:18 +0530 Subject: [PATCH 131/458] nvethernetrm: Misra-C 4.5, 13.3 and 12.1 fix - Fix MISRA C-2012 Rule 12.1 - Fix MISRA C-2012 Rule 4.5 - Fix MISRA C-2012 Rule 13.3 Bug 200682334 Change-Id: I7af71cb25cf7f202aca586cf7bde6d02813997ec Signed-off-by: rakesh goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2453875 (cherry picked from commit 9d5ad9db6d30472289aa05fed577035bdecd6381) Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2457304 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/common/osi_common.c | 11 +++++----- osi/core/eqos_core.c | 48 ++++++++++++++++++++--------------------- osi/core/osi_core.c | 18 ++++++++-------- osi/dma/eqos_dma.c | 3 ++- osi/dma/osi_dma.c | 30 ++++++++++++++------------ osi/dma/osi_dma_txrx.c | 48 +++++++++++++++++++++-------------------- 6 files changed, 82 insertions(+), 76 deletions(-) diff --git a/osi/common/osi_common.c b/osi/common/osi_common.c index 8346083..33e0788 100644 --- a/osi/common/osi_common.c +++ b/osi/common/osi_common.c @@ -110,16 +110,16 @@ void common_get_hw_features(void *base, struct osi_hw_features *hw_feat) nve32_t common_get_mac_version(void *addr, nveu32_t *mac_ver) { - nveu32_t macver; + nveu32_t version; nve32_t ret = 0; - macver = osi_readl((nveu8_t *)addr + MAC_VERSION) & + version = osi_readl((nveu8_t *)addr + MAC_VERSION) & MAC_VERSION_SNVER_MASK; - if (is_valid_mac_version(macver) == 0) { + if (is_valid_mac_version(version) == 0) { return -1; } - *mac_ver = macver; + *mac_ver = version; return ret; } @@ -133,7 +133,8 @@ void osi_memset(void *s, nveu32_t c, nveu64_t count) xs = (nveu8_t *)s; while (count != 0UL) { if (c < OSI_UCHAR_MAX) { - *xs++ = (nveu8_t)c; + *xs = (nveu8_t)c; + xs++; } count--; } diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 63b5da0..0ea9120 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -421,7 +421,7 @@ static nve32_t eqos_config_fw_err_pkts( nveu32_t val; /* Check for valid fw_err and qinx values */ - if ((fw_err != OSI_ENABLE && fw_err != OSI_DISABLE) || + if (((fw_err != OSI_ENABLE) && (fw_err != OSI_DISABLE)) || (qinx >= OSI_EQOS_MAX_NUM_CHANS)) { OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "config_fw_err: invalid input\n", 0ULL); @@ -1087,7 +1087,7 @@ static nve32_t eqos_config_rxcsum_offload( void *addr = osi_core->base; nveu32_t mac_mcr; - if (enabled != OSI_ENABLE && enabled != OSI_DISABLE) { + if ((enabled != OSI_ENABLE) && (enabled != OSI_DISABLE)) { OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "rxsum_offload: invalid input\n", 0ULL); return -1; @@ -1227,8 +1227,8 @@ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) /* 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 ((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; @@ -1916,7 +1916,7 @@ static inline nve32_t eqos_update_mac_addr_helper( (osi_core->dcs_en == OSI_ENABLE)) { *value = ((dma_chan << EQOS_MAC_ADDRH_DCS_SHIFT) & EQOS_MAC_ADDRH_DCS); - } else if (dma_chan > OSI_EQOS_MAX_NUM_CHANS - 0x1U) { + } else if (dma_chan > (OSI_EQOS_MAX_NUM_CHANS - 0x1U)) { OSI_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, "invalid dma channel\n", (nveul64_t)dma_chan); @@ -1928,8 +1928,8 @@ static inline nve32_t eqos_update_mac_addr_helper( } /* Address mask is valid for address 1 to 31 index only */ - if (addr_mask <= EQOS_MAX_MASK_BYTE && addr_mask > 0U) { - if (idx > 0U && idx < EQOS_MAX_MAC_ADDR_REG) { + if ((addr_mask <= EQOS_MAX_MASK_BYTE) && (addr_mask > 0U)) { + if ((idx > 0U) && (idx < EQOS_MAX_MAC_ADDR_REG)) { *value = (*value | ((addr_mask << EQOS_MAC_ADDRH_MBC_SHIFT) & EQOS_MAC_ADDRH_MBC)); @@ -2011,8 +2011,8 @@ static nve32_t eqos_update_mac_addr_low_high_reg( } /* 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 || src_dest == OSI_DA_MATCH)) { + if (((idx > 0U) && (idx < EQOS_MAX_MAC_ADDR_REG)) && + ((src_dest == OSI_SA_MATCH) || (src_dest == OSI_DA_MATCH))) { value = (value | ((src_dest << EQOS_MAC_ADDRH_SA_SHIFT) & EQOS_MAC_ADDRH_SA)); } @@ -2405,7 +2405,7 @@ static nve32_t eqos_config_l3_filters( } if ((dma_routing_enable == OSI_ENABLE) && - (dma_chan > OSI_EQOS_MAX_NUM_CHANS - 1U)) { + (dma_chan > (OSI_EQOS_MAX_NUM_CHANS - 1U))) { OSI_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, "Wrong DMA channel\n", (nveul64_t)dma_chan); @@ -2430,8 +2430,8 @@ static nve32_t eqos_config_l3_filters( 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) & + (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, @@ -2448,8 +2448,8 @@ static nve32_t eqos_config_l3_filters( 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) & + (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, @@ -2479,8 +2479,8 @@ static nve32_t eqos_config_l3_filters( 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) & + (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, @@ -2507,8 +2507,8 @@ static nve32_t eqos_config_l3_filters( 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) & + (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, @@ -2587,7 +2587,7 @@ static nve32_t eqos_config_l4_filters( } if ((dma_routing_enable == OSI_ENABLE) && - (dma_chan > OSI_EQOS_MAX_NUM_CHANS - 1U)) { + (dma_chan > (OSI_EQOS_MAX_NUM_CHANS - 1U))) { OSI_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, "Wrong DMA channel\n", (nveu32_t)dma_chan); @@ -2607,8 +2607,8 @@ static nve32_t eqos_config_l4_filters( 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) & + (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, @@ -2633,8 +2633,8 @@ static nve32_t eqos_config_l4_filters( 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) & + (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, @@ -3367,7 +3367,7 @@ static nve32_t eqos_read_phy_reg(struct osi_core_priv_data *const osi_core, 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 | + ((osi_core->mdc_cr) << EQOS_MDIO_PHY_REG_CR_SHIF) | (EQOS_MDIO_PHY_REG_GOC_READ) | EQOS_MAC_GMII_BUSY; osi_writel(mac_gmiiar, (nveu8_t *)osi_core->base + EQOS_MAC_MDIO_ADDRESS); diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index cae0fa5..31a92db 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -218,8 +218,8 @@ nve32_t osi_l2_filter(struct osi_core_priv_data *const osi_core, struct osi_core_ops *op; nve32_t ret = -1; - if (osi_core == OSI_NULL || osi_core->ops == OSI_NULL || - osi_core->base == OSI_NULL || filter == OSI_NULL) { + if ((osi_core == OSI_NULL) || (osi_core->ops == OSI_NULL) || + (osi_core->base == OSI_NULL) || (filter == OSI_NULL)) { return ret; } @@ -396,8 +396,8 @@ nve32_t osi_l3l4_filter(struct osi_core_priv_data *const osi_core, { nve32_t ret = -1; - if (osi_core == OSI_NULL || osi_core->ops == OSI_NULL || - osi_core->base == OSI_NULL) { + if ((osi_core == OSI_NULL) || (osi_core->ops == OSI_NULL) || + (osi_core->base == OSI_NULL)) { return ret; } @@ -446,9 +446,9 @@ nve32_t osi_l3l4_filter(struct osi_core_priv_data *const osi_core, nve32_t osi_config_rxcsum_offload(struct osi_core_priv_data *const osi_core, const nveu32_t enable) { - if (osi_core != OSI_NULL && osi_core->ops != OSI_NULL && - osi_core->base != OSI_NULL && - osi_core->ops->config_rxcsum_offload != OSI_NULL) { + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->base != OSI_NULL) && + (osi_core->ops->config_rxcsum_offload != OSI_NULL)) { return osi_core->ops->config_rxcsum_offload(osi_core, enable); } @@ -568,7 +568,7 @@ nve32_t osi_adjust_freq(struct osi_core_priv_data *const osi_core, nve32_t ppb) } if (neg_adj == 0U) { - if (addend <= UINT_MAX - diff) { + if (addend <= (UINT_MAX - diff)) { addend = (addend + diff); } else { OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, @@ -587,7 +587,7 @@ nve32_t osi_adjust_freq(struct osi_core_priv_data *const osi_core, nve32_t ppb) } } - if (osi_core->ops != OSI_NULL && osi_core->base != OSI_NULL && + if ((osi_core->ops != OSI_NULL) && (osi_core->base != OSI_NULL) && (osi_core->ops->config_addend != OSI_NULL)) { return osi_core->ops->config_addend(osi_core, addend); } diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index 369ac1c..4685717 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -683,7 +683,8 @@ static void eqos_configure_dma_channel(nveu32_t chan, * 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) { + 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 */ diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 415b2df..c23e346 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -252,8 +252,8 @@ nve32_t osi_stop_dma(struct osi_dma_priv_data *osi_dma, nveu32_t osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring) { - if (rx_ring->cur_rx_idx >= RX_DESC_CNT || - rx_ring->refill_idx >= RX_DESC_CNT) { + if ((rx_ring->cur_rx_idx >= RX_DESC_CNT) || + (rx_ring->refill_idx >= RX_DESC_CNT)) { return 0; } @@ -284,13 +284,13 @@ static inline nve32_t rx_dma_desc_validate_args( nveu32_t chan) { /* Validate args */ - if (!(osi_dma != OSI_NULL && osi_dma->ops != OSI_NULL && - osi_dma->ops->update_rx_tailptr != OSI_NULL)) { + if (!((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && + (osi_dma->ops->update_rx_tailptr != OSI_NULL))) { return -1; } - if (!(rx_ring != OSI_NULL && rx_ring->rx_swcx != OSI_NULL && - rx_ring->rx_desc != OSI_NULL)) { + if (!((rx_ring != OSI_NULL) && (rx_ring->rx_swcx != OSI_NULL) && + (rx_ring->rx_desc != OSI_NULL))) { OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "dma: Invalid pointers\n", 0ULL); return -1; @@ -357,8 +357,8 @@ nve32_t osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, } /* Refill buffers */ - while (rx_ring->refill_idx != rx_ring->cur_rx_idx && - rx_ring->refill_idx < RX_DESC_CNT) { + while ((rx_ring->refill_idx != rx_ring->cur_rx_idx) && + (rx_ring->refill_idx < RX_DESC_CNT)) { rx_swcx = rx_ring->rx_swcx + rx_ring->refill_idx; rx_desc = rx_ring->rx_desc + rx_ring->refill_idx; @@ -420,8 +420,8 @@ nve32_t osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, nve32_t osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) { - if (osi_dma != OSI_NULL && osi_dma->ops != OSI_NULL && - osi_dma->ops->set_rx_buf_len != OSI_NULL) { + if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && + (osi_dma->ops->set_rx_buf_len != OSI_NULL)) { osi_dma->ops->set_rx_buf_len(osi_dma); } else { return -1; @@ -491,7 +491,8 @@ static inline nve32_t osi_slot_args_validate(struct osi_dma_priv_data *osi_dma, } /* NULL check for osi_dma, osi_dma->ops and osi_dma->ops->config_slot */ - if (osi_dma->ops == OSI_NULL || osi_dma->ops->config_slot == OSI_NULL) { + if ((osi_dma->ops == OSI_NULL) || + (osi_dma->ops->config_slot == OSI_NULL)) { OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "dma: Invalid set argument\n", 0ULL); return -1; @@ -553,9 +554,10 @@ nve32_t osi_config_slot_function(struct osi_dma_priv_data *osi_dma, nve32_t osi_validate_dma_regs(struct osi_dma_priv_data *osi_dma) { nve32_t ret = -1; - if (osi_dma != OSI_NULL && osi_dma->ops != OSI_NULL && - osi_dma->ops->validate_regs != OSI_NULL && - osi_dma->safety_config != OSI_NULL) { + + if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && + (osi_dma->ops->validate_regs != OSI_NULL) && + (osi_dma->safety_config != OSI_NULL)) { ret = osi_dma->ops->validate_regs(osi_dma); } diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 125ea00..d8312d1 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -125,7 +125,7 @@ static inline void get_rx_vlan_from_desc(struct osi_rx_desc *rx_desc, 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) { + 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; } @@ -301,8 +301,9 @@ static inline nve32_t validate_rx_completions_arg( struct osi_rx_ring **rx_ring, struct osi_rx_pkt_cx **rx_pkt_cx) { - if (osi_unlikely(osi_dma == OSI_NULL || more_data_avail == OSI_NULL || - chan >= OSI_EQOS_MAX_NUM_CHANS)) { + if (osi_unlikely((osi_dma == OSI_NULL) || + (more_data_avail == OSI_NULL) || + (chan >= OSI_EQOS_MAX_NUM_CHANS))) { return -1; } @@ -353,7 +354,7 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, /* Reset flag to indicate if more Rx frames available to OSD layer */ *more_data_avail = OSI_NONE; - while (received < budget && received_resv < budget) { + 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; @@ -397,7 +398,8 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, * 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_desc->rdes3 & RDES3_LD) == RDES3_LD)) == + BOOLEAN_FALSE) { rx_swcx->flags |= OSI_RX_SWCX_REUSE; continue; } @@ -683,8 +685,8 @@ static inline nve32_t validate_tx_completions_arg( nveu32_t chan, struct osi_tx_ring **tx_ring) { - if (osi_unlikely(osi_dma == OSI_NULL || - chan >= OSI_EQOS_MAX_NUM_CHANS)) { + if (osi_unlikely((osi_dma == OSI_NULL) || + (chan >= OSI_EQOS_MAX_NUM_CHANS))) { return -1; } @@ -724,8 +726,8 @@ nve32_t osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, 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 < TX_DESC_CNT && - processed < budget) { + while ((entry != tx_ring->cur_tx_idx) && (entry < TX_DESC_CNT) && + (processed < budget)) { osi_memset(txdone_pkt_cx, 0U, sizeof(*txdone_pkt_cx)); tx_desc = tx_ring->tx_desc + entry; @@ -761,8 +763,8 @@ nve32_t osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, 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) { + } else if ((OSI_ULLONG_MAX - + (vartdes1 * OSI_NSEC_PER_SEC)) < ns) { /* Will not hit this case */ } else { txdone_pkt_cx->flags |= @@ -1015,15 +1017,15 @@ static inline nve32_t validate_hw_transmit_arg( struct osi_dma_chan_ops **ops, struct osi_tx_ring **tx_ring) { - if (osi_unlikely(osi_dma == OSI_NULL || - chan >= OSI_EQOS_MAX_NUM_CHANS)) { + if (osi_unlikely((osi_dma == OSI_NULL) || + (chan >= OSI_EQOS_MAX_NUM_CHANS))) { return -1; } *tx_ring = osi_dma->tx_ring[chan]; *ops = osi_dma->ops; - if (osi_unlikely(*tx_ring == OSI_NULL || *ops == OSI_NULL)) { + if (osi_unlikely((*tx_ring == OSI_NULL) || (*ops == OSI_NULL))) { OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "validate_hw_transmit_arg: Invalid pointers\n", 0ULL); return -1; @@ -1135,8 +1137,8 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi_dma, nveu32_t chan) 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) { + } 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; @@ -1280,12 +1282,12 @@ static nve32_t rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, } tailptr = rx_ring->rx_desc_phy_addr + - sizeof(struct osi_rx_desc) * (RX_DESC_CNT); + (sizeof(struct osi_rx_desc) * (RX_DESC_CNT)); - if (osi_unlikely(tailptr < rx_ring->rx_desc_phy_addr || - ops->set_rx_ring_len == OSI_NULL || - ops->update_rx_tailptr == OSI_NULL || - ops->set_rx_ring_start_addr == OSI_NULL)) { + if (osi_unlikely((tailptr < rx_ring->rx_desc_phy_addr) || + (ops->set_rx_ring_len == OSI_NULL) || + (ops->update_rx_tailptr == OSI_NULL) || + (ops->set_rx_ring_start_addr == OSI_NULL))) { /* Will not hit this case */ OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "dma_txrx: Invalid pointers\n", 0ULL); @@ -1398,8 +1400,8 @@ static nve32_t tx_dma_desc_init(struct osi_dma_priv_data *osi_dma) tx_ring->slot_number = 0U; tx_ring->slot_check = OSI_DISABLE; - if (osi_likely(ops->set_tx_ring_len != OSI_NULL || - ops->set_tx_ring_start_addr != OSI_NULL)) { + if (osi_likely((ops->set_tx_ring_len != OSI_NULL) || + (ops->set_tx_ring_start_addr != OSI_NULL))) { ops->set_tx_ring_len(osi_dma->base, chan, (TX_DESC_CNT - 1U)); ops->set_tx_ring_start_addr(osi_dma->base, chan, From 38aa49eb4e650af4a424ff1736ddfac1014a9d3f Mon Sep 17 00:00:00 2001 From: rakesh goyal <rgoyal@nvidia.com> Date: Thu, 3 Dec 2020 10:47:46 +0530 Subject: [PATCH 132/458] nvethernetrm: fix MISRA C-2012 Rule 17.8 Fix MISRA C-2012 Rule 17.8 Bug 200682334 Change-Id: Ic43649050381599eab735a96da63b75519fde3bc Signed-off-by: rakesh goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2454282 (cherry picked from commit 1babde35e2e8bcea64b8c57ce6730a5aed050425) Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2457305 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/common/osi_common.c | 5 +++-- osi/core/eqos_core.c | 26 +++++++++++++++----------- osi/core/osi_core.c | 29 +++++++++++++++++++++++------ 3 files changed, 41 insertions(+), 19 deletions(-) diff --git a/osi/common/osi_common.c b/osi/common/osi_common.c index 33e0788..ab1ce1b 100644 --- a/osi/common/osi_common.c +++ b/osi/common/osi_common.c @@ -126,17 +126,18 @@ nve32_t common_get_mac_version(void *addr, nveu32_t *mac_ver) 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 (count != 0UL) { + while (temp != 0UL) { if (c < OSI_UCHAR_MAX) { *xs = (nveu8_t)c; xs++; } - count--; + temp--; } } diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 0ea9120..c0511f9 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -2298,18 +2298,20 @@ static inline nveu32_t eqos_set_dcs( 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)) { - value |= ((dma_routing_enable << + t_val |= ((dma_routing_enable << EQOS_MAC_L3L4_CTR_DMCHEN0_SHIFT) & EQOS_MAC_L3L4_CTR_DMCHEN0); - value |= ((dma_chan << + t_val |= ((dma_chan << EQOS_MAC_L3L4_CTR_DMCHN0_SHIFT) & EQOS_MAC_L3L4_CTR_DMCHN0); } - return value; + return t_val; } /** @@ -2963,6 +2965,8 @@ static nve32_t eqos_adjust_mactime(struct osi_core_priv_data *const osi_core, 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); @@ -2975,9 +2979,9 @@ static nve32_t eqos_adjust_mactime(struct osi_core_priv_data *const osi_core, * the system time, then MAC_STSUR reg should be * programmed with (2^32 – <new_sec_value>) */ - temp = (TWO_POWER_32 - sec); + temp = (TWO_POWER_32 - sec1); if (temp < UINT_MAX) { - sec = (nveu32_t)temp; + sec1 = (nveu32_t)temp; } else { /* do nothing here */ } @@ -2989,23 +2993,23 @@ static nve32_t eqos_adjust_mactime(struct osi_core_priv_data *const osi_core, * (2^32 - <new_nsec_value> if MAC_TCR.TSCTRLSSR is reset) */ if (one_nsec_accuracy == OSI_ENABLE) { - if (nsec < UINT_MAX) { - nsec = (TEN_POWER_9 - nsec); + if (nsec1 < UINT_MAX) { + nsec1 = (TEN_POWER_9 - nsec1); } } else { - if (nsec < UINT_MAX) { - nsec = (TWO_POWER_31 - nsec); + if (nsec1 < UINT_MAX) { + nsec1 = (TWO_POWER_31 - nsec1); } } } /* write seconds value to MAC_System_Time_Seconds_Update register */ - osi_writel(sec, (nveu8_t *)addr + EQOS_MAC_STSUR); + osi_writel(sec1, (nveu8_t *)addr + EQOS_MAC_STSUR); /* write nano seconds value and add_sub to * MAC_System_Time_Nanoseconds_Update register */ - value |= nsec; + value |= nsec1; value |= add_sub << EQOS_MAC_STNSUR_ADDSUB_SHIFT; osi_writel(value, (nveu8_t *)addr + EQOS_MAC_STNSUR); diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 31a92db..716c027 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -541,10 +541,11 @@ nve32_t osi_adjust_freq(struct osi_core_priv_data *const osi_core, nve32_t ppb) nveu32_t addend; nveu32_t neg_adj = 0; nve32_t ret = -1; + nve32_t ppb1 = ppb; - if (ppb < 0) { + if (ppb1 < 0) { neg_adj = 1U; - ppb = -ppb; + ppb1 = -ppb1; } if (osi_core == OSI_NULL) { @@ -552,7 +553,13 @@ nve32_t osi_adjust_freq(struct osi_core_priv_data *const osi_core, nve32_t ppb) } addend = osi_core->default_addend; - adj = (nveu64_t)addend * (nveu32_t)ppb; + if ((UINT_MAX - ppb1) > 0) { + adj = (nveu64_t)addend * (nveu32_t)ppb1; + } else { + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "ppb1 > UINT_MAX\n", + 0ULL); + return ret; + } /* * div_u64 will divide the "adj" by "1000000000ULL" @@ -607,16 +614,26 @@ nve32_t osi_adjust_time(struct osi_core_priv_data *const osi_core, nveu64_t reminder = 0; nveu64_t udelta = 0; nve32_t ret = -1; + nvel64_t nsec_delta1 = nsec_delta; if (osi_core == OSI_NULL) { return ret; } - if (nsec_delta < 0) { + if (nsec_delta1 < 0) { neg_adj = 1; - nsec_delta = -nsec_delta; + nsec_delta1 = -nsec_delta1; } - udelta = (nveul64_t)nsec_delta; + + if ((nsec_delta1 >= 0) && + ((OSI_ULLONG_MAX - nsec_delta1) > 0)) { + udelta = (nveul64_t)nsec_delta1; + } else { + OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "nsec_delta1 > OSI_ULLONG_MAX\n", 0ULL); + return ret; + } + quotient = div_u64_rem(udelta, OSI_NSEC_PER_SEC, &reminder); if (quotient <= UINT_MAX) { sec = (nveu32_t)quotient; From 01dd86e594f717934defca6674b6ebfa79d630af Mon Sep 17 00:00:00 2001 From: rakesh goyal <rgoyal@nvidia.com> Date: Sat, 5 Dec 2020 18:27:56 +0530 Subject: [PATCH 133/458] nvethernetrm: fix Misra-C 2.x, 5.9 and 8.9 Fix MISRA C-2012 Rule 2.3 Fix MISRA C-2012 Rule 2.4 Fix MISRA C-2012 Rule 2.5 Fix MISRA C-2012 Rule 5.9 Fix MISRA C-2012 Rule 8.9 Bug 200682334 Change-Id: Ie95e2f9d346d952fac1cf28f241522f35648be38 Signed-off-by: rakesh goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2455622 Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2457306 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/mmc.h | 23 ------ include/osi_common.h | 132 ++++++------------------------ include/osi_core.h | 97 +++++++++++++++++++++- include/osi_dma.h | 47 ++++++++++- include/osi_dma_txrx.h | 6 +- osi/common/include/local_common.h | 26 ++++++ osi/common/osi_common.c | 51 ++++-------- osi/common/type.h | 4 - osi/core/eqos_core.c | 107 ++++++++++++------------ osi/core/eqos_core.h | 99 ++++++++++++---------- osi/core/osi_core.c | 38 --------- osi/dma/eqos_dma.c | 48 +++++------ osi/dma/eqos_dma.h | 17 ++-- osi/dma/osi_dma_local.h | 16 ++++ 14 files changed, 374 insertions(+), 337 deletions(-) diff --git a/include/mmc.h b/include/mmc.h index ea33aad..fd41868 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -555,27 +555,4 @@ struct osi_xtra_stat_counters { /** link disconnect count */ nveu64_t link_disconnect_count; }; - -/** - * @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_EQOS_MAX_NUM_QUEUES]; - /** Per Q RX packet count */ - nveu64_t q_rx_pkt_n[OSI_EQOS_MAX_NUM_QUEUES]; - /** Per Q TX complete call count */ - nveu64_t tx_clean_n[OSI_EQOS_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; -}; - #endif diff --git a/include/osi_common.h b/include/osi_common.h index d4faab1..1b4241a 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -32,26 +32,22 @@ */ #define OSI_UNLOCKED 0x0U #define OSI_LOCKED 0x1U -#define TEN_POWER_9 0x3B9ACA00U -#define TWO_POWER_32 0x100000000ULL -#define TWO_POWER_31 0x80000000U #define OSI_NSEC_PER_SEC 1000000000ULL -#define OSI_INVALID_VALUE 0xFFFFFFFFU -#define OSI_PTP_REQ_CLK_FREQ 250000000U -#define OSI_ONE_MEGA_HZ 1000000U +#ifndef OSI_STRIPPED_LIB #define OSI_MAX_RX_COALESCE_USEC 1020U #define OSI_MIN_RX_COALESCE_USEC 3U #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_likely(x) __builtin_expect(!!(x), 1) #define osi_unlikely(x) __builtin_expect(!!(x), 0) /** @} */ +#ifndef OSI_STRIPPED_LIB /** * @addtogroup - LPI-Timers LPI configuration macros * @@ -96,8 +92,8 @@ */ #define OSI_LPI_1US_TIC_COUNTER_DEFAULT 0xCBU #define OSI_LPI_1US_TIC_COUNTER_MASK 0xFFFU - /** @} */ +#endif /* !OSI_STRIPPED_LIB */ /** * @addtogroup Helper Helper MACROS @@ -105,15 +101,15 @@ * @brief EQOS generic helper MACROS. * @{ */ +#ifndef OSI_STRIPPED_LIB #define OSI_PAUSE_FRAMES_ENABLE 0U -#define OSI_PAUSE_FRAMES_DISABLE 1U -#define OSI_FLOW_CTRL_TX OSI_BIT(0) -#define OSI_FLOW_CTRL_RX OSI_BIT(1) +#define OSI_PTP_REQ_CLK_FREQ 250000000U #define OSI_FLOW_CTRL_DISABLE 0U #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) @@ -123,27 +119,6 @@ #endif /** @} */ -/** - * @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_SNAPTYPSEL_3 (OSI_BIT(16) | OSI_BIT(17)) -#define OSI_MAC_TCR_AV8021ASMEN OSI_BIT(28) -/** @} */ /** * @addtogroup Helper Helper MACROS @@ -151,117 +126,60 @@ * @brief EQOS generic helper MACROS. * @{ */ -#define OSI_ULLONG_MAX (~0ULL) #define OSI_UCHAR_MAX (0xFFU) +#define OSI_ULLONG_MAX (~0ULL) /* 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 +#ifndef OSI_STRIPPED_LIB +#define OSI_LOG_WARN 2U #define OSI_LOG_ARG_OPNOTSUPP 3U -#define OSI_LOG_ARG_HW_FAIL 4U - +#endif /* !OSI_STRIPPED_LIB */ /* Default maximum Giant Packet Size Limit is 16K */ #define OSI_MAX_MTU_SIZE 16383U -#define OSI_MTU_SIZE_9000 9000U -#define OSI_DFLT_MTU_SIZE 1500U #define EQOS_DMA_CHX_STATUS(x) ((0x0080U * (x)) + 0x1160U) -#define EQOS_DMA_CHX_IER(x) ((0x0080U * (x)) + 0x1134U) /* FIXME add logic based on HW version */ -#define EQOS_MAX_MAC_ADDRESS_FILTER 128U -#define EQOS_MAX_L3_L4_FILTER 8U -#define EQOS_MAX_HTR_REGS 8U -#define OSI_EQOS_MAX_NUM_CHANS 8U -#define OSI_EQOS_MAX_NUM_QUEUES 8U -#define OSI_L2_FILTER_INDEX_ANY 127U -#define OSI_CHAN_ANY 0xFFU - -/* HW supports 8 Hash table regs, but eqos_validate_core_regs only checks 4 */ -#define OSI_EQOS_MAX_HASH_REGS 4U - -/* 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_EQOS_MAX_NUM_CHANS 4U +#define OSI_EQOS_MAX_NUM_QUEUES 4U #define MAC_VERSION 0x110 #define MAC_VERSION_SNVER_MASK 0x7FU #define OSI_MAC_HW_EQOS 0U -#define OSI_ETH_ALEN 6U -#define OSI_MAX_VM_IRQS 5U -#define BOOLEAN_FALSE (0U != 0U) #define OSI_NULL ((void *)0) #define OSI_ENABLE 1U #define OSI_NONE 0U #define OSI_DISABLE 0U -#define OSI_AMASK_DISABLE 0U -#define OSI_HASH_FILTER_MODE 1U -#define OSI_PERFECT_FILTER_MODE 0U -#define OSI_IPV6_MATCH 1U -#define OSI_SOURCE_MATCH 0U -#define OSI_INV_MATCH 1U -#define OSI_PFT_MATCH 0U - -#define OSI_SA_MATCH 1U -#define OSI_DA_MATCH 0U - -#define OSI_L4_FILTER_TCP 0U -#define OSI_L4_FILTER_UDP 1U - -#define OSI_IP4_FILTER 0U -#define OSI_IP6_FILTER 1U - -#define CHECK_CHAN_BOUND(chan) \ - { \ - if ((chan) >= OSI_EQOS_MAX_NUM_CHANS) { \ - return; \ - } \ - } \ #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_MAX_VM_IRQS 5U -#define OSI_SPEED_10 10 -#define OSI_SPEED_100 100 -#define OSI_SPEED_1000 1000 +#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 OSI_FULL_DUPLEX 1 -#define OSI_HALF_DUPLEX 0 - -#define NV_ETH_FRAME_LEN 1514U #define NV_ETH_FCS_LEN 0x4U -#define NV_VLAN_HLEN 0x4U -#define OSI_ETH_HLEN 0xEU -#define OSI_NET_IP_ALIGN 0x2U +#define NV_ETH_FRAME_LEN 1514U #define MAX_ETH_FRAME_LEN_DEFAULT \ (NV_ETH_FRAME_LEN + NV_ETH_FCS_LEN + NV_VLAN_HLEN) - -#define L32(data) ((data) & 0xFFFFFFFFU) -#define H32(data) (((data) & 0xFFFFFFFF00000000UL) >> 32UL) - #define OSI_INVALID_CHAN_NUM 0xFFU +#endif /* OSI_STRIPPED_LIB */ + /** @} */ /** @@ -302,7 +220,9 @@ #define EQOS_MAC_HFR1_TSOEN_MASK 0x1U #define EQOS_MAC_HFR1_DMADEBUGEN_MASK 0x1U #define EQOS_MAC_HFR1_AVSEL_MASK 0x1U +#ifndef OSI_STRIPPED_LIB #define EQOS_MAC_HFR1_LPMODEEN_MASK 0x1U +#endif /* OSI_STRIPPED_LIB */ #define EQOS_MAC_HFR1_HASHTBLSZ_MASK 0x3U #define EQOS_MAC_HFR1_L3L4FILTERNUM_MASK 0xfU #define EQOS_MAC_HFR2_RXQCNT_MASK 0xfU @@ -313,6 +233,7 @@ #define EQOS_MAC_HFR2_AUXSNAPNUM_MASK 0x7U /** @} */ +#ifndef OSI_STRIPPED_LIB /** * @addtogroup MTL queue operation mode * @@ -334,6 +255,7 @@ #define OSI_MTL_TXQ_AVALG_CBS 1U #define OSI_MTL_TXQ_AVALG_SP 0U /** @} */ +#endif /* OSI_STRIPPED_LIB */ /** * @brief struct osi_hw_features - MAC HW supported features. diff --git a/include/osi_core.h b/include/osi_core.h index 17f755d..40318ba 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -27,6 +27,16 @@ #include "mmc.h" #include "../osi/common/type.h" +/* Following added to avoid misraC 4.6 + * Here we are defining intermediate type + */ +typedef unsigned short my_uint16_t; +typedef long long my_lint_64; + +/* Actual type used in code */ +typedef my_uint16_t nveu16_t; +typedef my_lint_64 nvel64_t; + /** * @addtogroup PTP related information * @@ -35,6 +45,91 @@ */ #define OSI_PTP_SSINC_16 16U #define OSI_PTP_SSINC_4 4U + +/** @} */ + +/** + * @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_SNAPTYPSEL_3 (OSI_BIT(16) | OSI_BIT(17)) +#define OSI_MAC_TCR_AV8021ASMEN OSI_BIT(28) +/** @} */ + +/** + * @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_DA_MATCH 0U +#define OSI_INV_MATCH 1U +#define OSI_AMASK_DISABLE 0U +#define OSI_CHAN_ANY 0xFFU +#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_LOG_INFO 1U +#define OSI_LOG_ARG_HW_FAIL 4U +#define OSI_LOG_ARG_OUTOFBOUND 1U + +/* 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 TEN_POWER_9 0x3B9ACA00U +#define TWO_POWER_32 0x100000000ULL +#define TWO_POWER_31 0x80000000U /** @} */ /* to avoid re definition when both core and dma headers are included */ @@ -116,6 +211,7 @@ struct osi_l3_l4_filter { nveu16_t port_no; }; +#ifndef OSI_STRIPPED_LIB /** * @brief Vlan filter Function dependent parameter */ @@ -138,7 +234,6 @@ struct osi_l2_da_filter { nveu32_t perfect_inverse_match; }; -#ifndef OSI_STRIPPED_LIB /** * @brief OSI Core avb data structure per queue. */ diff --git a/include/osi_dma.h b/include/osi_dma.h index 244439d..acaf870 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -25,7 +25,24 @@ #include "osi_common.h" #include "osi_dma_txrx.h" -#include "mmc.h" + +/** + * @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 + +/* Compiler hints for branch prediction */ +#define osi_likely(x) __builtin_expect(!!(x), 1) +/** @} */ /* to avoid re definition when both core and dma headers are included */ #undef OSI_ERR @@ -93,8 +110,10 @@ * @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 /** @} */ @@ -121,14 +140,18 @@ * * @brief Flag to indicate the result from checksum offload engine * to SW network stack in receive path. +#ifndef OSI_STRIPPED_LIB * OSI_CHECKSUM_NONE indicates that HW checksum offload * engine did not verify the checksum, SW network stack has to do it. +#endif * 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 */ @@ -349,6 +372,28 @@ struct osi_tx_ring { 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_EQOS_MAX_NUM_QUEUES]; + /** Per Q RX packet count */ + nveu64_t q_rx_pkt_n[OSI_EQOS_MAX_NUM_QUEUES]; + /** Per Q TX complete call count */ + nveu64_t tx_clean_n[OSI_EQOS_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; /** diff --git a/include/osi_dma_txrx.h b/include/osi_dma_txrx.h index 39605b6..a4fe23c 100644 --- a/include/osi_dma_txrx.h +++ b/include/osi_dma_txrx.h @@ -44,12 +44,14 @@ */ /** Increment the tx descriptor index */ #define INCR_TX_DESC_INDEX(idx, i) ((idx) = ((idx) + (i)) & (TX_DESC_CNT - 1U)) -/** Decrement the tx descriptor index */ -#define DECR_TX_DESC_INDEX(idx, i) ((idx) = ((idx) - (i)) & (TX_DESC_CNT - 1U)) /** Increment the rx descriptor index */ #define INCR_RX_DESC_INDEX(idx, i) ((idx) = ((idx) + (i)) & (RX_DESC_CNT - 1U)) +#ifndef OSI_STRIPPED_LIB +/** Decrement the tx descriptor index */ +#define DECR_TX_DESC_INDEX(idx, i) ((idx) = ((idx) - (i)) & (TX_DESC_CNT - 1U)) /** Decrement the rx descriptor index */ #define DECR_RX_DESC_INDEX(idx, i) ((idx) = ((idx) - (i)) & (RX_DESC_CNT - 1U)) +#endif /* !OSI_STRIPPED_LIB */ /** @} */ /** diff --git a/osi/common/include/local_common.h b/osi/common/include/local_common.h index 674777e..903af66 100644 --- a/osi/common/include/local_common.h +++ b/osi/common/include/local_common.h @@ -26,6 +26,32 @@ #include <osi_common.h> #include "../osi/common/type.h" +/** + *@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 * diff --git a/osi/common/osi_common.c b/osi/common/osi_common.c index ab1ce1b..45a83b1 100644 --- a/osi/common/osi_common.c +++ b/osi/common/osi_common.c @@ -22,6 +22,7 @@ #include <osd.h> #include "eqos_common.h" +#include "local_common.h" void common_get_hw_features(void *base, struct osi_hw_features *hw_feat) { @@ -141,42 +142,7 @@ void osi_memset(void *s, nveu32_t c, nveu64_t count) } } -/** - *@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 - */ -static inline 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; -} void common_get_systime_from_mac(void *addr, nveu32_t mac, nveu32_t *sec, nveu32_t *nsec) @@ -214,3 +180,18 @@ nveu32_t common_is_mac_enabled(void *addr, nveu32_t mac) return OSI_DISABLE; } } + +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 index da558bd..e14ff66 100644 --- a/osi/common/type.h +++ b/osi/common/type.h @@ -30,9 +30,7 @@ typedef unsigned int my_uint32_t; typedef int my_int32_t; typedef char my_int8_t; typedef unsigned char my_uint8_t; -typedef unsigned short my_uint16_t; typedef unsigned long long my_ulint_64; -typedef long long my_lint_64; typedef unsigned long my_uint64_t; /* Actual type used in code */ @@ -40,8 +38,6 @@ typedef my_uint32_t nveu32_t; typedef my_int32_t nve32_t; typedef my_int8_t nve8_t; typedef my_uint8_t nveu8_t; -typedef my_uint16_t nveu16_t; typedef my_ulint_64 nveul64_t; -typedef my_lint_64 nvel64_t; typedef my_uint64_t nveu64_t; #endif diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index c0511f9..5c87980 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1310,7 +1310,7 @@ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) osi_writel(value, (nveu8_t *)osi_core->base + EQOS_MAC_VLANTIR); /* Configure default flow control settings */ - if (osi_core->pause_frames == OSI_PAUSE_FRAMES_ENABLE) { + 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) { @@ -1916,7 +1916,8 @@ static inline nve32_t eqos_update_mac_addr_helper( (osi_core->dcs_en == OSI_ENABLE)) { *value = ((dma_chan << EQOS_MAC_ADDRH_DCS_SHIFT) & EQOS_MAC_ADDRH_DCS); - } else if (dma_chan > (OSI_EQOS_MAX_NUM_CHANS - 0x1U)) { + } else if ((dma_chan == OSI_CHAN_ANY) || + (dma_chan > (OSI_EQOS_MAX_NUM_CHANS - 0x1U))) { OSI_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, "invalid dma channel\n", (nveul64_t)dma_chan); @@ -1928,7 +1929,8 @@ static inline nve32_t eqos_update_mac_addr_helper( } /* Address mask is valid for address 1 to 31 index only */ - if ((addr_mask <= EQOS_MAX_MASK_BYTE) && (addr_mask > 0U)) { + 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) & @@ -4251,56 +4253,6 @@ static nve32_t eqos_config_mac_loopback(void *addr, } #endif /* !OSI_STRIPPED_LIB */ -/** - * @brief eqos_core_ops - EQOS MAC core operations - */ -static struct osi_core_ops eqos_core_ops = { - .poll_for_swr = eqos_poll_for_swr, - .core_init = eqos_core_init, - .core_deinit = eqos_core_deinit, - .start_mac = eqos_start_mac, - .stop_mac = eqos_stop_mac, - .handle_common_intr = eqos_handle_common_intr, - .set_mode = eqos_set_mode, - .set_speed = eqos_set_speed, - .pad_calibrate = eqos_pad_calibrate, - .config_fw_err_pkts = eqos_config_fw_err_pkts, - .config_rxcsum_offload = eqos_config_rxcsum_offload, - .config_mac_pkt_filter_reg = eqos_config_mac_pkt_filter_reg, - .update_mac_addr_low_high_reg = eqos_update_mac_addr_low_high_reg, - .config_l3_l4_filter_enable = eqos_config_l3_l4_filter_enable, - .config_l3_filters = eqos_config_l3_filters, - .update_ip4_addr = eqos_update_ip4_addr, - .update_ip6_addr = eqos_update_ip6_addr, - .config_l4_filters = eqos_config_l4_filters, - .update_l4_port_no = eqos_update_l4_port_no, - .set_systime_to_mac = eqos_set_systime_to_mac, - .config_addend = eqos_config_addend, - .adjust_mactime = eqos_adjust_mactime, - .config_tscr = eqos_config_tscr, - .config_ssir = eqos_config_ssir, - .read_mmc = eqos_read_mmc, - .write_phy_reg = eqos_write_phy_reg, - .read_phy_reg = eqos_read_phy_reg, -#ifndef OSI_STRIPPED_LIB - .config_tx_status = eqos_config_tx_status, - .config_rx_crc_check = eqos_config_rx_crc_check, - .config_flow_control = eqos_config_flow_control, - .config_arp_offload = eqos_config_arp_offload, - .validate_regs = eqos_validate_core_regs, - .flush_mtl_tx_queue = eqos_flush_mtl_tx_queue, - .set_avb_algorithm = eqos_set_avb_algorithm, - .get_avb_algorithm = eqos_get_avb_algorithm, - .config_vlan_filtering = eqos_config_vlan_filtering, - .update_vlan_id = eqos_update_vlan_id, - .reset_mmc = eqos_reset_mmc, - .configure_eee = eqos_configure_eee, - .save_registers = eqos_save_registers, - .restore_registers = eqos_restore_registers, - .set_mdc_clk_rate = eqos_set_mdc_clk_rate, - .config_mac_loopback = eqos_config_mac_loopback, -#endif /* !OSI_STRIPPED_LIB */ -}; /** * @brief eqos_get_core_safety_config - EQOS MAC safety configuration @@ -4327,5 +4279,54 @@ void *eqos_get_core_safety_config(void) */ struct osi_core_ops *eqos_get_hw_core_ops(void) { + static struct osi_core_ops eqos_core_ops = { + .poll_for_swr = eqos_poll_for_swr, + .core_init = eqos_core_init, + .core_deinit = eqos_core_deinit, + .start_mac = eqos_start_mac, + .stop_mac = eqos_stop_mac, + .handle_common_intr = eqos_handle_common_intr, + .set_mode = eqos_set_mode, + .set_speed = eqos_set_speed, + .pad_calibrate = eqos_pad_calibrate, + .config_fw_err_pkts = eqos_config_fw_err_pkts, + .config_rxcsum_offload = eqos_config_rxcsum_offload, + .config_mac_pkt_filter_reg = eqos_config_mac_pkt_filter_reg, + .update_mac_addr_low_high_reg = + eqos_update_mac_addr_low_high_reg, + .config_l3_l4_filter_enable = eqos_config_l3_l4_filter_enable, + .config_l3_filters = eqos_config_l3_filters, + .update_ip4_addr = eqos_update_ip4_addr, + .update_ip6_addr = eqos_update_ip6_addr, + .config_l4_filters = eqos_config_l4_filters, + .update_l4_port_no = eqos_update_l4_port_no, + .set_systime_to_mac = eqos_set_systime_to_mac, + .config_addend = eqos_config_addend, + .adjust_mactime = eqos_adjust_mactime, + .config_tscr = eqos_config_tscr, + .config_ssir = eqos_config_ssir, + .read_mmc = eqos_read_mmc, + .write_phy_reg = eqos_write_phy_reg, + .read_phy_reg = eqos_read_phy_reg, +#ifndef OSI_STRIPPED_LIB + .config_tx_status = eqos_config_tx_status, + .config_rx_crc_check = eqos_config_rx_crc_check, + .config_flow_control = eqos_config_flow_control, + .config_arp_offload = eqos_config_arp_offload, + .validate_regs = eqos_validate_core_regs, + .flush_mtl_tx_queue = eqos_flush_mtl_tx_queue, + .set_avb_algorithm = eqos_set_avb_algorithm, + .get_avb_algorithm = eqos_get_avb_algorithm, + .config_vlan_filtering = eqos_config_vlan_filtering, + .update_vlan_id = eqos_update_vlan_id, + .reset_mmc = eqos_reset_mmc, + .configure_eee = eqos_configure_eee, + .save_registers = eqos_save_registers, + .restore_registers = eqos_restore_registers, + .set_mdc_clk_rate = eqos_set_mdc_clk_rate, + .config_mac_loopback = eqos_config_mac_loopback, +#endif /* !OSI_STRIPPED_LIB */ + }; + return &eqos_core_ops; } diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 11b6df4..0c52e81 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -40,6 +40,7 @@ #define FULL_MINUS_16_K (nveu32_t)30 /** @} */ +#ifndef OSI_STRIPPED_LIB /** * @addtogroup EQOS-MDC MDC Clock Selection defines * @@ -55,7 +56,7 @@ #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 * @@ -107,7 +108,9 @@ #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_MDIO_ADDRESS 0x0200 @@ -184,7 +187,6 @@ #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_ARPEN OSI_BIT(31) #define EQOS_MCR_IPC OSI_BIT(27) #define EQOS_MMC_CNTRL_CNTRST OSI_BIT(0) #define EQOS_MMC_CNTRL_RSTONRD OSI_BIT(2) @@ -207,10 +209,6 @@ #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_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)) @@ -222,9 +220,7 @@ #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_VLTI OSI_BIT(20) #define EQOS_MAC_VLANTIRR_CSVL OSI_BIT(19) -#define EQOS_DMA_SBUS_BLEN4 OSI_BIT(1) #define EQOS_DMA_SBUS_BLEN8 OSI_BIT(2) #define EQOS_DMA_SBUS_BLEN16 OSI_BIT(3) #define EQOS_DMA_SBUS_EAME OSI_BIT(11) @@ -235,33 +231,63 @@ #define EQOS_MTL_QTOMR_FTQ_LPOS OSI_BIT(0) #define EQOS_DMA_ISR_MACIS OSI_BIT(17) #define EQOS_MAC_ISR_RGSMIIS OSI_BIT(0) -#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_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_TXQ_ETS_QW_ISCQW_MASK 0x000FFFFFU -#define EQOS_MTL_TXQ_ETS_SSCR_SSC_MASK 0x00003FFFU -#define EQOS_MTL_TXQ_ETS_HCR_HC_MASK 0x1FFFFFFFU -#define EQOS_MTL_TXQ_ETS_LCR_LC_MASK 0x1FFFFFFFU #define EQOS_MTL_TXQEN_MASK (OSI_BIT(3) | OSI_BIT(2)) #define EQOS_MTL_TXQEN_MASK_SHIFT 2U -#define EQOS_MTL_RXQ_OP_MODE_FEP OSI_BIT(4) #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_MAC_EXTR_DCRCC OSI_BIT(16) +#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 @@ -272,8 +298,6 @@ #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_HUC OSI_BIT(1) -#define EQOS_MAC_PFR_HMC OSI_BIT(2) #define EQOS_MAC_PFR_DAIF OSI_BIT(3) #define EQOS_MAC_PFR_PM OSI_BIT(4) #define EQOS_MAC_PFR_DBF OSI_BIT(5) @@ -282,7 +306,6 @@ #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_SHIFT 16 #define EQOS_MAC_PFR_IPFE OSI_BIT(20) #define EQOS_MAC_PFR_DNTU OSI_BIT(21) #define EQOS_MAC_PFR_RA OSI_BIT(31) @@ -303,12 +326,6 @@ #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_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_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) | \ @@ -355,19 +372,8 @@ #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_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_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_TSADDREG OSI_BIT(5) #define EQOS_MAC_TCR_TSINIT OSI_BIT(2) #define EQOS_MAC_TCR_TSUPDT OSI_BIT(3) @@ -375,7 +381,6 @@ #define EQOS_MAC_TCR_TSCFUPDT OSI_BIT(1) #define EQOS_MAC_TCR_TSCTRLSSR OSI_BIT(9) #define EQOS_MAC_SSIR_SSINC_SHIFT 16U -#define EQOS_MAC_STNSR_TSSS_MASK 0x7FFFFFFFU #define EQOS_MAC_GMIIDR_GD_WR_MASK 0xFFFF0000U #define EQOS_MAC_GMIIDR_GD_MASK 0xFFFFU #define EQOS_MDIO_PHY_ADDR_SHIFT 21U @@ -452,9 +457,6 @@ void update_ehfc_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value); #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 @@ -468,17 +470,22 @@ void update_ehfc_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value); #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_TXQ0_QW_IDX 22U +#ifndef OSI_STRIPPED_LIB +#define EQOS_MAC_HTR1_IDX 3U +#define EQOS_MAC_HTR2_IDX 4U +#define EQOS_MAC_HTR3_IDX 5U #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_TXQ0_QW_IDX 22U #define EQOS_MTL_TXQ1_QW_IDX 23U #define EQOS_MTL_TXQ2_QW_IDX 24U #define EQOS_MTL_TXQ3_QW_IDX 25U -#define EQOS_MTL_CH0_RX_OP_MODE_IDX 26U #define EQOS_MTL_CH1_RX_OP_MODE_IDX 27U #define EQOS_MTL_CH2_RX_OP_MODE_IDX 28U #define EQOS_MTL_CH3_RX_OP_MODE_IDX 29U +#endif /* !OSI_STRIPPED_LIB */ +#define EQOS_MTL_CH0_RX_OP_MODE_IDX 26U #define EQOS_DMA_SBUS_IDX 30U #define EQOS_MAX_CORE_SAFETY_REGS 31U /** @} */ @@ -610,7 +617,9 @@ struct core_func_safety { /* To add new registers to backup during suspend, and restore during resume * add it before this line, and increment EQOS_MAC_BAK_IDX accordingly. */ -#define EQOS_MAX_BAK_IDX ((EQOS_PAD_AUTO_CAL_CFG_BAK_IDX + 1U)) +#ifndef OSI_STRIPPED_LIB +#define EQOS_MAX_BAK_IDX ((EQOS_PAD_AUTO_CAL_CFG_BAK_IDX + 1U)) +#endif /* !OSI_STRIPPED_LIB */ /** @} */ #endif diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 716c027..2cbe6e5 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -470,44 +470,6 @@ nve32_t osi_set_systime_to_mac(struct osi_core_priv_data *const osi_core, return -1; } -/** - *@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 - * - * @returns Quotient - */ -static inline 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; -} - /** * @brief div_u64 - Calls a function which returns quotient * diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index 4685717..23e9aac 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -986,30 +986,6 @@ static void eqos_clear_vm_rx_intr(void *addr, nveu32_t chan) (nveu8_t *)addr + EQOS_VIRT_INTR_CHX_STATUS(chan)); } -static struct osi_dma_chan_ops eqos_dma_chan_ops = { - .set_tx_ring_len = eqos_set_tx_ring_len, - .set_rx_ring_len = eqos_set_rx_ring_len, - .set_tx_ring_start_addr = eqos_set_tx_ring_start_addr, - .set_rx_ring_start_addr = eqos_set_rx_ring_start_addr, - .update_tx_tailptr = eqos_update_tx_tailptr, - .update_rx_tailptr = eqos_update_rx_tailptr, - .disable_chan_tx_intr = eqos_disable_chan_tx_intr, - .enable_chan_tx_intr = eqos_enable_chan_tx_intr, - .disable_chan_rx_intr = eqos_disable_chan_rx_intr, - .enable_chan_rx_intr = eqos_enable_chan_rx_intr, - .start_dma = eqos_start_dma, - .stop_dma = eqos_stop_dma, - .init_dma_channel = eqos_init_dma_channel, - .set_rx_buf_len = eqos_set_rx_buf_len, -#ifndef OSI_STRIPPED_LIB - .validate_regs = eqos_validate_dma_regs, - .config_slot = eqos_config_slot, -#endif /* !OSI_STRIPPED_LIB */ - .get_global_dma_status = eqos_get_global_dma_status, - .clear_vm_tx_intr = eqos_clear_vm_tx_intr, - .clear_vm_rx_intr = eqos_clear_vm_rx_intr, -}; - /** * @brief eqos_get_dma_safety_config - EQOS get DMA safety configuration */ @@ -1023,5 +999,29 @@ void *eqos_get_dma_safety_config(void) */ struct osi_dma_chan_ops *eqos_get_dma_chan_ops(void) { + static struct osi_dma_chan_ops eqos_dma_chan_ops = { + .set_tx_ring_len = eqos_set_tx_ring_len, + .set_rx_ring_len = eqos_set_rx_ring_len, + .set_tx_ring_start_addr = eqos_set_tx_ring_start_addr, + .set_rx_ring_start_addr = eqos_set_rx_ring_start_addr, + .update_tx_tailptr = eqos_update_tx_tailptr, + .update_rx_tailptr = eqos_update_rx_tailptr, + .disable_chan_tx_intr = eqos_disable_chan_tx_intr, + .enable_chan_tx_intr = eqos_enable_chan_tx_intr, + .disable_chan_rx_intr = eqos_disable_chan_rx_intr, + .enable_chan_rx_intr = eqos_enable_chan_rx_intr, + .start_dma = eqos_start_dma, + .stop_dma = eqos_stop_dma, + .init_dma_channel = eqos_init_dma_channel, + .set_rx_buf_len = eqos_set_rx_buf_len, +#ifndef OSI_STRIPPED_LIB + .validate_regs = eqos_validate_dma_regs, + .config_slot = eqos_config_slot, +#endif /* !OSI_STRIPPED_LIB */ + .get_global_dma_status = eqos_get_global_dma_status, + .clear_vm_tx_intr = eqos_clear_vm_tx_intr, + .clear_vm_rx_intr = eqos_clear_vm_rx_intr, + }; + return &eqos_dma_chan_ops; } diff --git a/osi/dma/eqos_dma.h b/osi/dma/eqos_dma.h index 9715194..fc61f81 100644 --- a/osi/dma/eqos_dma.h +++ b/osi/dma/eqos_dma.h @@ -43,7 +43,9 @@ #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) @@ -106,38 +108,41 @@ #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_CH0_TX_CTRL_IDX 4U +#define EQOS_DMA_CH0_RX_CTRL_IDX 8U +#define EQOS_DMA_CH0_RDRL_IDX 16U +#define EQOS_DMA_CH0_TDRL_IDX 12U +#define EQOS_DMA_CH0_INTR_ENA_IDX 20U +#ifndef OSI_STRIPPED_LIB #define EQOS_DMA_CH1_CTRL_IDX 1U #define EQOS_DMA_CH2_CTRL_IDX 2U #define EQOS_DMA_CH3_CTRL_IDX 3U -#define EQOS_DMA_CH0_TX_CTRL_IDX 4U #define EQOS_DMA_CH1_TX_CTRL_IDX 5U #define EQOS_DMA_CH2_TX_CTRL_IDX 6U #define EQOS_DMA_CH3_TX_CTRL_IDX 7U -#define EQOS_DMA_CH0_RX_CTRL_IDX 8U #define EQOS_DMA_CH1_RX_CTRL_IDX 9U #define EQOS_DMA_CH2_RX_CTRL_IDX 10U #define EQOS_DMA_CH3_RX_CTRL_IDX 11U -#define EQOS_DMA_CH0_TDRL_IDX 12U #define EQOS_DMA_CH1_TDRL_IDX 13U #define EQOS_DMA_CH2_TDRL_IDX 14U #define EQOS_DMA_CH3_TDRL_IDX 15U -#define EQOS_DMA_CH0_RDRL_IDX 16U #define EQOS_DMA_CH1_RDRL_IDX 17U #define EQOS_DMA_CH2_RDRL_IDX 18U #define EQOS_DMA_CH3_RDRL_IDX 19U -#define EQOS_DMA_CH0_INTR_ENA_IDX 20U #define EQOS_DMA_CH1_INTR_ENA_IDX 21U #define EQOS_DMA_CH2_INTR_ENA_IDX 22U #define EQOS_DMA_CH3_INTR_ENA_IDX 23U +#endif /* OSI_STRIPPED_LIB */ #define EQOS_MAX_DMA_SAFETY_REGS 24U #define EQOS_AXI_BUS_WIDTH 0x10U /** @} */ diff --git a/osi/dma/osi_dma_local.h b/osi/dma/osi_dma_local.h index c4ba9f8..7fb80ee 100644 --- a/osi/dma/osi_dma_local.h +++ b/osi/dma/osi_dma_local.h @@ -49,4 +49,20 @@ * @retval -1 on failure. */ nve32_t dma_desc_init(struct osi_dma_priv_data *osi_dma); + +#define CHECK_CHAN_BOUND(chan) \ + { \ + if ((chan) >= OSI_EQOS_MAX_NUM_CHANS) { \ + return; \ + } \ + } \ +/** + * @addtogroup Helper Helper MACROS + * + * @brief EQOS DMA generic helper MACROS. + * @{ + */ +#define BOOLEAN_FALSE (0U != 0U) +#define L32(data) ((data) & 0xFFFFFFFFU) +#define H32(data) (((data) & 0xFFFFFFFF00000000UL) >> 32UL) #endif /* OSI_DMA_LOCAL_H */ From e47a928225b26fa49cdde70e607b299f0855bd66 Mon Sep 17 00:00:00 2001 From: rakesh goyal <rgoyal@nvidia.com> Date: Fri, 4 Dec 2020 13:14:20 +0530 Subject: [PATCH 134/458] nvethernetrm: fix review CG and DG comments - Include header gaurds using INCLUDED_ - Move static inline function to private header file. - Move private macro to private header Bug 200681427 Change-Id: I810184e077a5642f727e47b9280d3fb9659abd74 Signed-off-by: rakesh goyal <rgoyal@nvidia.com>> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2455014 (cherry picked from commit b3afc7a112460d7f92d8ef0fbe8727c7acd9ec44) Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2457307 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/mmc.h | 4 +- include/osd.h | 6 +- include/osi_common.h | 187 +---------------------------------- include/osi_core.h | 8 +- include/osi_dma.h | 8 +- include/osi_dma_txrx.h | 107 +------------------- osi/common/common.h | 205 +++++++++++++++++++++++++++++++++++++++ osi/common/eqos_common.c | 1 + osi/common/eqos_common.h | 6 +- osi/common/osi_common.c | 2 +- osi/common/type.h | 2 +- osi/core/eqos_core.c | 8 +- osi/core/eqos_core.h | 6 +- osi/core/eqos_mmc.c | 2 +- osi/core/eqos_mmc.h | 6 +- osi/dma/eqos_dma.c | 2 +- osi/dma/eqos_dma.h | 6 +- osi/dma/hw_desc.h | 126 ++++++++++++++++++++++++ osi/dma/osi_dma.c | 1 + osi/dma/osi_dma_local.h | 6 +- osi/dma/osi_dma_txrx.c | 12 ++- 21 files changed, 387 insertions(+), 324 deletions(-) create mode 100644 osi/common/common.h create mode 100644 osi/dma/hw_desc.h diff --git a/include/mmc.h b/include/mmc.h index fd41868..461569e 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -20,8 +20,8 @@ * DEALINGS IN THE SOFTWARE. */ -#ifndef MMC_H -#define MMC_H +#ifndef INCLUDED_MMC_H +#define INCLUDED_MMC_H /** * @brief osi_mmc_counters - The structure to hold RMON counter values */ diff --git a/include/osd.h b/include/osd.h index 1214122..3bed0f3 100644 --- a/include/osd.h +++ b/include/osd.h @@ -20,8 +20,8 @@ * DEALINGS IN THE SOFTWARE. */ -#ifndef OSD_H -#define OSD_H +#ifndef INCLUDED_OSD_H +#define INCLUDED_OSD_H #include "../osi/common/type.h" @@ -148,4 +148,4 @@ void osd_log(void *priv, nveu32_t type, const nve8_t *err, nveul64_t loga); -#endif +#endif /* INCLUDED_OSD_H */ diff --git a/include/osi_common.h b/include/osi_common.h index 1b4241a..cfa6b19 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -20,10 +20,11 @@ * DEALINGS IN THE SOFTWARE. */ -#ifndef OSI_COMMON_H -#define OSI_COMMON_H +#ifndef INCLUDED_OSI_COMMON_H +#define INCLUDED_OSI_COMMON_H #include "../osi/common/type.h" + /** * @addtogroup Helper Helper MACROS * @@ -157,7 +158,6 @@ #define OSI_NONE 0U #define OSI_DISABLE 0U - #define OSI_BIT(nr) ((nveu32_t)1 << (nr)) #define OSI_EQOS_MAC_4_10 0x41U @@ -567,185 +567,6 @@ struct osi_hw_features { nveu32_t num_tbs_ch; }; -/** - * @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 is_valid_mac_version - Check if read MAC IP is valid or not. - * - * @param[in] mac_ver: MAC version read. - * - * @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 is_valid_mac_version(nveu32_t mac_ver) -{ - if ((mac_ver == OSI_EQOS_MAC_4_10) || - (mac_ver == OSI_EQOS_MAC_5_00) || - (mac_ver == OSI_EQOS_MAC_5_10)) { - return 1; - } - - return 0; -} - -/** - * @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 - * - * @return nveu64_t value - */ -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; -} - /** * @brief common_get_mac_version - Reading MAC version * @@ -798,4 +619,4 @@ void common_get_hw_features(void *base, struct osi_hw_features *hw_feat); * - De-initialization: No */ void osi_memset(void *s, nveu32_t c, nveu64_t count); -#endif /* OSI_COMMON_H */ +#endif /* INCLUDED_OSI_COMMON_H */ diff --git a/include/osi_core.h b/include/osi_core.h index 40318ba..82797d3 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -20,10 +20,10 @@ * DEALINGS IN THE SOFTWARE. */ -#ifndef OSI_CORE_H -#define OSI_CORE_H +#ifndef INCLUDED_OSI_CORE_H +#define INCLUDED_OSI_CORE_H -#include "osi_common.h" +#include "../osi/common/common.h" #include "mmc.h" #include "../osi/common/type.h" @@ -2020,4 +2020,4 @@ nve32_t osi_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, nve32_t osi_config_mac_loopback(struct osi_core_priv_data *const osi_core, const nveu32_t lb_mode); #endif /* !OSI_STRIPPED_LIB */ -#endif /* OSI_CORE_H */ +#endif /* INCLUDED_OSI_CORE_H */ diff --git a/include/osi_dma.h b/include/osi_dma.h index acaf870..ca65c87 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -20,10 +20,10 @@ * DEALINGS IN THE SOFTWARE. */ -#ifndef OSI_DMA_H -#define OSI_DMA_H +#ifndef INCLUDED_OSI_DMA_H +#define INCLUDED_OSI_DMA_H -#include "osi_common.h" +#include "../osi/common/common.h" #include "osi_dma_txrx.h" /** @@ -1419,4 +1419,4 @@ nve32_t osi_clear_rx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); */ nve32_t osi_txring_empty(struct osi_dma_priv_data *osi_dma, nveu32_t chan); #endif /* !OSI_STRIPPED_LIB */ -#endif /* OSI_DMA_H */ +#endif /* INCLUDED_OSI_DMA_H */ diff --git a/include/osi_dma_txrx.h b/include/osi_dma_txrx.h index a4fe23c..b690667 100644 --- a/include/osi_dma_txrx.h +++ b/include/osi_dma_txrx.h @@ -20,8 +20,8 @@ * DEALINGS IN THE SOFTWARE. */ -#ifndef OSI_DMA_TXRX_H -#define OSI_DMA_TXRX_H +#ifndef INCLUDED_OSI_DMA_TXRX_H +#define INCLUDED_OSI_DMA_TXRX_H /** * @addtogroup EQOS_Help Descriptor Helper MACROS @@ -53,105 +53,4 @@ #define DECR_RX_DESC_INDEX(idx, i) ((idx) = ((idx) - (i)) & (RX_DESC_CNT - 1U)) #endif /* !OSI_STRIPPED_LIB */ /** @} */ - -/** - * @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_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 RDES0_OVT 0x0000FFFFU -#define RDES1_TSA OSI_BIT(14) -#define RDES1_TD OSI_BIT(15) - -#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_TCP OSI_BIT(1) -#define RDES1_PT_UDP OSI_BIT(0) -/** @} */ - -/** 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) - -/** - * @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_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) - -/* 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 /* OSI_DMA_TXRX_H */ +#endif /* INCLUDED_OSI_DMA_TXRX_H */ diff --git a/osi/common/common.h b/osi/common/common.h new file mode 100644 index 0000000..86451c2 --- /dev/null +++ b/osi/common/common.h @@ -0,0 +1,205 @@ +/* + * 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_COMMON_H +#define INCLUDED_COMMON_H + +#include <osi_common.h> + +/** + * @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 is_valid_mac_version - Check if read MAC IP is valid or not. + * + * @param[in] mac_ver: MAC version read. + * + * @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 is_valid_mac_version(nveu32_t mac_ver) +{ + if ((mac_ver == OSI_EQOS_MAC_4_10) || + (mac_ver == OSI_EQOS_MAC_5_00) || + (mac_ver == OSI_EQOS_MAC_5_10)) { + return 1; + } + + return 0; +} + +/** + * @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 + * + * @return nveu64_t value + */ +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 diff --git a/osi/common/eqos_common.c b/osi/common/eqos_common.c index 5530258..0feb73f 100644 --- a/osi/common/eqos_common.c +++ b/osi/common/eqos_common.c @@ -21,6 +21,7 @@ */ #include "eqos_common.h" +#include "../osi/common/common.h" nveul64_t eqos_get_systime_from_mac(void *addr) { diff --git a/osi/common/eqos_common.h b/osi/common/eqos_common.h index 8d0d0ff..6e982ec 100644 --- a/osi/common/eqos_common.h +++ b/osi/common/eqos_common.h @@ -20,8 +20,8 @@ * DEALINGS IN THE SOFTWARE. */ -#ifndef EQOS_COMMON_H -#define EQOS_COMMON_H +#ifndef INCLUDED_EQOS_COMMON_H +#define INCLUDED_EQOS_COMMON_H #include <local_common.h> @@ -80,4 +80,4 @@ nveul64_t eqos_get_systime_from_mac(void *addr); * @retval OSI_DISABLE otherwise. */ nveu32_t eqos_is_mac_enabled(void *addr); -#endif /* EQOS_COMMON_H */ +#endif /* INCLUDED_EQOS_COMMON_H */ diff --git a/osi/common/osi_common.c b/osi/common/osi_common.c index 45a83b1..bf82a23 100644 --- a/osi/common/osi_common.c +++ b/osi/common/osi_common.c @@ -22,7 +22,7 @@ #include <osd.h> #include "eqos_common.h" -#include "local_common.h" +#include "../osi/common/common.h" void common_get_hw_features(void *base, struct osi_hw_features *hw_feat) { diff --git a/osi/common/type.h b/osi/common/type.h index e14ff66..2c6a2e1 100644 --- a/osi/common/type.h +++ b/osi/common/type.h @@ -40,4 +40,4 @@ typedef my_int8_t nve8_t; typedef my_uint8_t nveu8_t; typedef my_ulint_64 nveul64_t; typedef my_uint64_t nveu64_t; -#endif +#endif /* INCLUDED_TYPE_H */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 5c87980..f785dda 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -20,7 +20,7 @@ * DEALINGS IN THE SOFTWARE. */ -#include <osi_common.h> +#include "../osi/common/common.h" #include <osi_core.h> #include <osd.h> #include "eqos_core.h" @@ -2673,7 +2673,7 @@ static nve32_t eqos_config_l4_filters( * equal to zero. * * @param[in] osi_core: OSI core private data structure. - * @param[inout] mac_tcr: Address to store time stamp control register read + * @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() @@ -2785,7 +2785,7 @@ static nve32_t eqos_set_systime_to_mac( * equal to zero. * * @param[in] osi_core: OSI core private data structure. - * @param[inout] mac_tcr: Address to store time stamp control register read + * @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() @@ -2888,7 +2888,7 @@ static nve32_t eqos_config_addend(struct osi_core_priv_data *const osi_core, * equal to zero. * * @param[in] osi_core: OSI core private data structure. - * @param[inout] mac_tcr: Address to store time stamp control register read + * @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() diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 0c52e81..2aaa37b 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -20,8 +20,8 @@ * DEALINGS IN THE SOFTWARE. */ -#ifndef EQOS_CORE_H_ -#define EQOS_CORE_H_ +#ifndef INCLUDED_EQOS_CORE_H +#define INCLUDED_EQOS_CORE_H /** * @addtogroup EQOS-FC Flow Control Threshold Macros @@ -622,4 +622,4 @@ struct core_func_safety { #define EQOS_MAX_BAK_IDX ((EQOS_PAD_AUTO_CAL_CFG_BAK_IDX + 1U)) #endif /* !OSI_STRIPPED_LIB */ /** @} */ -#endif +#endif /* INCLUDED_EQOS_CORE_H */ diff --git a/osi/core/eqos_mmc.c b/osi/core/eqos_mmc.c index f397717..cc748c7 100644 --- a/osi/core/eqos_mmc.c +++ b/osi/core/eqos_mmc.c @@ -20,7 +20,7 @@ * DEALINGS IN THE SOFTWARE. */ -#include <osi_common.h> +#include "../osi/common/common.h" #include <osi_core.h> #include <osd.h> #include "eqos_mmc.h" diff --git a/osi/core/eqos_mmc.h b/osi/core/eqos_mmc.h index fe6f0e3..1a17758 100644 --- a/osi/core/eqos_mmc.h +++ b/osi/core/eqos_mmc.h @@ -20,8 +20,8 @@ * DEALINGS IN THE SOFTWARE. */ -#ifndef EQOS_MMC_H_ -#define EQOS_MMC_H_ +#ifndef INCLUDED_EQOS_MMC_H +#define INCLUDED_EQOS_MMC_H /** * @addtogroup EQOS-MMC MMC HW register offsets @@ -117,4 +117,4 @@ void eqos_read_mmc(struct osi_core_priv_data *osi_core); void eqos_reset_mmc(struct osi_core_priv_data *osi_core); -#endif +#endif /* INCLUDED_EQOS_MMC_H */ diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index 23e9aac..1a03094 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -20,7 +20,7 @@ * DEALINGS IN THE SOFTWARE. */ -#include <osi_common.h> +#include "../osi/common/common.h" #include "osi_dma_local.h" #include "eqos_dma.h" #include "../osi/common/type.h" diff --git a/osi/dma/eqos_dma.h b/osi/dma/eqos_dma.h index fc61f81..6b4400d 100644 --- a/osi/dma/eqos_dma.h +++ b/osi/dma/eqos_dma.h @@ -20,8 +20,8 @@ * DEALINGS IN THE SOFTWARE. */ -#ifndef EQOS_DMA_H_ -#define EQOS_DMA_H_ +#ifndef INCLUDED_EQOS_DMA_H +#define INCLUDED_EQOS_DMA_H /** * @addtogroup EQOS AXI Clock defines @@ -189,4 +189,4 @@ void *eqos_get_dma_safety_config(void); * @returns Pointer to DMA channel operations structure */ struct osi_dma_chan_ops *eqos_get_dma_chan_ops(void); -#endif +#endif /* INCLUDED_EQOS_DMA_H */ diff --git a/osi/dma/hw_desc.h b/osi/dma/hw_desc.h new file mode 100644 index 0000000..adadbcb --- /dev/null +++ b/osi/dma/hw_desc.h @@ -0,0 +1,126 @@ +/* + * 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_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 RDES0_OVT 0x0000FFFFU +#define RDES1_TSA OSI_BIT(14) +#define RDES1_TD OSI_BIT(15) + +#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_TCP OSI_BIT(1) +#define RDES1_PT_UDP OSI_BIT(0) +/** @} */ + +/** 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) + +/** + * @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_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) + +/* 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/osi_dma.c b/osi/dma/osi_dma.c index c23e346..f2d9d4f 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -23,6 +23,7 @@ #include "osi_dma_local.h" #include <osd.h> #include <local_common.h> +#include "hw_desc.h" nve32_t osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) { diff --git a/osi/dma/osi_dma_local.h b/osi/dma/osi_dma_local.h index 7fb80ee..3e6656d 100644 --- a/osi/dma/osi_dma_local.h +++ b/osi/dma/osi_dma_local.h @@ -21,8 +21,8 @@ */ -#ifndef OSI_DMA_LOCAL_H -#define OSI_DMA_LOCAL_H +#ifndef INCLUDED_OSI_DMA_LOCAL_H +#define INCLUDED_OSI_DMA_LOCAL_H #include <osi_dma.h> #include "eqos_dma.h" @@ -65,4 +65,4 @@ nve32_t dma_desc_init(struct osi_dma_priv_data *osi_dma); #define BOOLEAN_FALSE (0U != 0U) #define L32(data) ((data) & 0xFFFFFFFFU) #define H32(data) (((data) & 0xFFFFFFFF00000000UL) >> 32UL) -#endif /* OSI_DMA_LOCAL_H */ +#endif /* INCLUDED_OSI_DMA_LOCAL_H */ diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index d8312d1..99e3a70 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -24,6 +24,7 @@ #include "osi_dma_local.h" #include <osi_dma_txrx.h> #include "../osi/common/type.h" +#include "hw_desc.h" /** * @brief get_rx_csum - Get the Rx checksum from descriptor if valid @@ -223,8 +224,17 @@ static nve32_t get_rx_hwstamp(struct osi_dma_priv_data *osi_dma, return ret; } - rx_pkt_cx->ns = context_desc->rdes0 + + if (OSI_NSEC_PER_SEC > (OSI_ULLONG_MAX / context_desc->rdes1)) { + /* Will not hit this case */ + } else if ((OSI_ULLONG_MAX - + (context_desc->rdes1 * OSI_NSEC_PER_SEC)) < + context_desc->rdes0) { + /* Will not hit this case */ + } else { + 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; From d1b2b92b6d5d8a57a801b085ac7cf1ef6ece66f6 Mon Sep 17 00:00:00 2001 From: rakesh goyal <rgoyal@nvidia.com> Date: Fri, 4 Dec 2020 20:17:47 +0530 Subject: [PATCH 135/458] core: dma: fix doxygen comment as per review comment Issue: Doxygen comments needs to be fixed for all units where pointer passed to a function and structure members updated through that pointer. Fix: corrected doxygen comments Bug 200681427 Change-Id: I026ae30dc587234e8491d4764a5a3511042d3b9f Signed-off-by: rakesh goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2455185 (cherry picked from commit f09df9984ab5ff52cfaade8f994e2e63cb0256e0) Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2457308 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_core.h | 6 +++--- include/osi_dma.h | 22 ++++++++++----------- osi/core/eqos_core.c | 10 +++++----- osi/core/eqos_mmc.c | 6 +++--- osi/dma/eqos_dma.c | 2 +- osi/dma/osi_dma.c | 2 +- osi/dma/osi_dma_local.h | 2 +- osi/dma/osi_dma_txrx.c | 42 +++++++++++++++++++++-------------------- 8 files changed, 47 insertions(+), 45 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 82797d3..ce88ccb 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -613,7 +613,7 @@ nve32_t osi_poll_for_mac_reset_complete( * Algorithm: * - Invokes EQOS MAC, MTL and common DMA register init code. * - * @param[in] osi_core: OSI core private data structure. + * @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. * @@ -1330,7 +1330,7 @@ void *eqos_get_core_safety_config(void); * destination Port Number for L4(TCP/UDP) layer * filtering. * - * @param[in] osi_core: OSI core private data structure. + * @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)) @@ -1958,7 +1958,7 @@ nve32_t osi_restore_registers(struct osi_core_priv_data *const osi_core); * - MDC clock rate will be populated in OSI core private data * structure based on AXI_CBB clock rate. * - * @param[in] osi_core: OSI core private data structure. + * @param[in, out] osi_core: OSI core private data structure. * @param[in] csr_clk_rate: CSR (AXI CBB) clock rate. * * @note OSD layer needs get the AXI CBB clock rate with OSD clock API diff --git a/include/osi_dma.h b/include/osi_dma.h index ca65c87..4d97c45 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -871,7 +871,7 @@ nveu32_t osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring); * - Initialize a Rx DMA descriptor. * * @param[in] osi_dma: OSI DMA private data structure. - * @param[in] rx_ring: HW ring corresponding to Rx DMA channel. + * @param[in, out] rx_ring: HW ring corresponding to Rx DMA channel. * @param[in] chan: Rx DMA channel number * * @pre @@ -905,7 +905,7 @@ nve32_t osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, /** * @brief Updates rx buffer length. * - * @param[in] osi_dma: OSI DMA private data 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. @@ -943,7 +943,7 @@ nve32_t osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma); * set OWN bit, Tx ring length and set starting address of Tx DMA channel * Tx ring base address in Tx DMA registers. * - * @param[in] osi_dma: OSI DMA private data. + * @param[in, out] osi_dma: OSI DMA private data. * @param[in] chan: DMA Tx channel number. * * @pre @@ -993,7 +993,7 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi_dma, nveu32_t chan); * - Invokes OSD layer to release DMA address and Tx buffer which are * updated as part of transmit routine. * - * @param[in] osi_dma: OSI dma private data structure. + * @param[in, out] osi_dma: OSI dma private data structure. * @param[in] chan: Channel number on which Tx complete need to be done. * @param[in] budget: Threshold for reading the packets at a time. * @@ -1039,10 +1039,10 @@ nve32_t osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, * - Re-allocate the receive buffers, populate Rx descriptor and * handover to DMA. * - * @param[in] osi_dma: OSI DMA private data structure. + * @param[in, out] osi_dma: OSI DMA private data structure. * @param[in] chan: Rx DMA channel number * @param[in] budget: Threshold for reading the packets at a time. - * @param[in] more_data_avail: Pointer to more data available flag. OSI fills + * @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 @@ -1081,7 +1081,7 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, * - Takes care of initializing the tx, rx ring and descriptors * based on the number of channels selected. * - * @param[in] osi_dma: OSI DMA private data. + * @param[in, out] osi_dma: OSI DMA private data. * * @pre * - Allocate memory for osi_dma @@ -1166,7 +1166,7 @@ nve32_t osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma); /** * @brief osi_init_dma_ops - Initialize DMA operations * - * @param[in] osi_dma: OSI DMA private data. + * @param[in, out] osi_dma: OSI DMA private data. * * @note * Traceability Details: @@ -1307,7 +1307,7 @@ nve32_t osi_validate_dma_regs(struct osi_dma_priv_data *osi_dma); * - This function will be invoked by OSD layer to clear the * tx stats mentioned in osi_dma->pkt_err_stats structure * - * @param[in] osi_dma: OSI DMA private data 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. @@ -1341,7 +1341,7 @@ nve32_t osi_clear_tx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); * Algorithm: * - Set or reset the slot function based on set input * - * @param[in] osi_dma: OSI DMA private data structure. + * @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() @@ -1375,7 +1375,7 @@ nve32_t osi_config_slot_function(struct osi_dma_priv_data *osi_dma, * - This function will be invoked by OSD layer to clear the * rx_crc_error mentioned in osi_dma->pkt_err_stats structure. * - * @param[in] osi_dma: OSI DMA private data structure. + * @param[in, out] osi_dma: OSI DMA private data structure. * * * @pre diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index f785dda..e8a4fb5 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1190,7 +1190,7 @@ static void eqos_configure_rxq_priority( * - Disable MMC interrupts and Configure the MMC counters * - Enable required MAC interrupts * - * @param[in] osi_core: OSI core private data structure. + * @param[in, out] osi_core: OSI core private data structure. * * @pre MAC has to be out of reset. * @@ -1572,7 +1572,7 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, * Algorithm: * - increment error stats based on corresponding bit filed. * - * @param[in] osi_core: OSI core private data structure. + * @param[in, out] osi_core: OSI core private data structure. * @param[in] dma_sr: Dma status register read value * @param[in] qinx: Queue index * @@ -2364,7 +2364,7 @@ static inline void eqos_helper_l3l4_bitmask(nveu32_t *bitmask, * is used to configure L3((IPv4/IPv6) filters resister * for address matching. * - * @param[in] osi_core: OSI core private data structure. + * @param[in, out] 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 @@ -2548,7 +2548,7 @@ static nve32_t eqos_config_l3_filters( * - 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, out] 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 @@ -4150,7 +4150,7 @@ static inline nve32_t eqos_restore_registers( * - MDC clock rate will be populated OSI core private data structure * based on AXI_CBB clock rate. * - * @param[in] osi_core: OSI core private data structure. + * @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 diff --git a/osi/core/eqos_mmc.c b/osi/core/eqos_mmc.c index cc748c7..88a35e7 100644 --- a/osi/core/eqos_mmc.c +++ b/osi/core/eqos_mmc.c @@ -34,7 +34,7 @@ * - 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, out] osi_core: OSI core private data structure. * @param[in] last_value: previous value of stats variable. * @param[in] offset: HW register offset * @@ -77,7 +77,7 @@ static inline nveu64_t update_mmc_val(struct osi_core_priv_data *osi_core, * @brief eqos_reset_mmc - To reset MMC registers and ether_mmc_counter * structure variable * - * @param[in] osi_core: OSI core private data structure. + * @param[in, out] osi_core: OSI core private data structure. * * @pre * - MAC should be init and started. see osi_start_mac() @@ -109,7 +109,7 @@ void eqos_reset_mmc(struct osi_core_priv_data *osi_core) * - Pass register offset and old value to helper function and * update structure. * - * @param[in] osi_core: OSI core private data structure. + * @param[in, out] osi_core: OSI core private data structure. * * @pre * - MAC should be init and started. see osi_start_mac() diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index 1a03094..dd4bdd8 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -774,7 +774,7 @@ static nve32_t eqos_init_dma_channel(struct osi_dma_priv_data *osi_dma) * @brief eqos_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. + * @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 diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index f2d9d4f..a25c986 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -315,7 +315,7 @@ static inline nve32_t rx_dma_desc_validate_args( * * @param[in] osi_dma: OSI DMA private data struture. * @param[in] rx_ring: HW ring corresponding to Rx DMA channel. - * @param[in] rx_desc: Rx Rx descriptor. + * @param[in, out] rx_desc: Rx Rx descriptor. * * @note * API Group: diff --git a/osi/dma/osi_dma_local.h b/osi/dma/osi_dma_local.h index 3e6656d..e4a92d6 100644 --- a/osi/dma/osi_dma_local.h +++ b/osi/dma/osi_dma_local.h @@ -37,7 +37,7 @@ * - Transmit and Receive descriptors will be initialized with * required values so that MAC DMA can understand and act accordingly. * - * @param[in] osi_dma: OSI DMA private data structure. + * @param[in, out] osi_dma: OSI DMA private data structure. * * @note * API Group: diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 99e3a70..c01081e 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -44,8 +44,8 @@ * - Run time: Yes * - De-initialization: No * - * @param[in] rx_desc: Rx descriptor - * @param[in] rx_pkt_cx: Per-Rx packet context structure + * @param[in, out] rx_desc: Rx descriptor + * @param[in, out] rx_pkt_cx: Per-Rx packet context structure */ static inline void get_rx_csum(struct osi_rx_desc *rx_desc, struct osi_rx_pkt_cx *rx_pkt_cx) @@ -115,7 +115,7 @@ static inline void get_rx_csum(struct osi_rx_desc *rx_desc, * - De-initialization: No * * @param[in] rx_desc: Rx descriptor - * @param[in] rx_pkt_cx: Per-Rx packet context structure + * @param[in, out] rx_pkt_cx: Per-Rx packet context structure */ static inline void get_rx_vlan_from_desc(struct osi_rx_desc *rx_desc, struct osi_rx_pkt_cx *rx_pkt_cx) @@ -181,7 +181,7 @@ static inline nve32_t get_rx_tstamp_status(struct osi_rx_desc *context_desc) * @param[in] osi_dma: OSI private data structure. * @param[in] rx_desc: Rx descriptor * @param[in] context_desc: Rx context descriptor - * @param[in] rx_pkt_cx: Rx packet context + * @param[in, out] rx_pkt_cx: Rx packet context * * @note * API Group: @@ -259,7 +259,8 @@ static nve32_t get_rx_hwstamp(struct osi_dma_priv_data *osi_dma, * - De-initialization: No * * @param[in] rx_desc: Rx Descriptor. - * @param[in] pkt_err_stats: Packet error stats which stores the errors reported + * @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) @@ -292,8 +293,8 @@ static inline void get_rx_err_stats(struct osi_rx_desc *rx_desc, * @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[in] rx_ring: OSI DMA channel Rx ring - * @param[in] rx_pkt_cx: OSI DMA receive packet context + * @param[out] rx_ring: OSI DMA channel Rx ring + * @param[out] rx_pkt_cx: OSI DMA receive packet context * * @note * API Group: @@ -509,7 +510,7 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, * - Run time: Yes * - De-initialization: No * - * @param[in] osi_dma: Pointer to OSI DMA private data structure. + * @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, @@ -537,7 +538,8 @@ static inline void inc_tx_pkt_stats(struct osi_dma_priv_data *osi_dma, * - De-initialization: No * * @param[in] tx_desc: Tx Descriptor. - * @param[in] pkt_err_stats: Packet error stats which stores the errors reported + * @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) @@ -679,7 +681,7 @@ nve32_t osi_clear_rx_pkt_err_stats(struct osi_dma_priv_data *osi_dma) * * @param[in] osi_dma: OSI DMA private data structure. * @param[in] chan: Tx DMA channel number - * @param[in] tx_ring: OSI DMA channel Rx ring + * @param[out] tx_ring: OSI DMA channel Rx ring * * @note * API Group: @@ -835,8 +837,8 @@ nve32_t osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, * - If set, set the context descriptor bit along * with other context information in the transmit descriptor. * - * @param[in] tx_pkt_cx: Pointer to transmit packet context structure - * @param[in] tx_desc: Pointer to transmit descriptor to be filled. + * @param[in, out] tx_pkt_cx: Pointer to transmit packet context structure + * @param[in, out] tx_desc: Pointer to transmit descriptor to be filled. * * @note * API Group: @@ -898,9 +900,9 @@ static inline nve32_t need_cntx_desc(struct osi_tx_pkt_cx *tx_pkt_cx, * - Run time: Yes * - De-initialization: No * - * @param[in] tx_ring: DMA channel TX ring. - * @param[in] tx_pkt_cx: Pointer to transmit packet context structure - * @param[in] tx_desc: Pointer to transmit descriptor to be filled. + * @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, @@ -1009,8 +1011,8 @@ static inline void dmb_oshst(void) * * @param[in] osi_dma: OSI DMA private data structure. * @param[in] chan: Tx DMA channel number - * @param[in] ops: OSI DMA Channel operations - * @param[in] tx_ring: OSI DMA channel Tx ring + * @param[out] ops: OSI DMA Channel operations + * @param[out] tx_ring: OSI DMA channel Tx ring * * @note * API Group: @@ -1211,7 +1213,7 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi_dma, nveu32_t chan) * set OWN bit, Rx ring length and set starting address of Rx DMA channel. * Tx ring base address in Tx DMA registers. * - * @param[in] osi_dma: OSI private data structure. + * @param[in, out] osi_dma: OSI private data structure. * @param[in] chan: Rx channel number. * * @note @@ -1321,7 +1323,7 @@ static nve32_t rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, * set OWN bit, Rx ring length and set starting address of Rx DMA channel. * Tx ring base address in Tx DMA registers. * - * @param[in] osi_dma: OSI private data structure. + * @param[in, out] osi_dma: OSI private data structure. * * @note * API Group: @@ -1358,7 +1360,7 @@ static nve32_t rx_dma_desc_init(struct osi_dma_priv_data *osi_dma) * - Initialize Transmit descriptors and set Tx ring length, * Tx ring base address in Tx DMA registers. * - * @param[in] osi_dma: OSI DMA private data structure. + * @param[in, out] osi_dma: OSI DMA private data structure. * * @note * API Group: From d0f2add540e9eda7887f73d5cad1b36e62236861 Mon Sep 17 00:00:00 2001 From: rakesh goyal <rgoyal@nvidia.com> Date: Mon, 7 Dec 2020 16:20:24 +0530 Subject: [PATCH 136/458] nvethernetrm: fix Misra-C 20.5 Fix MISRA C-2012 Rule 20.5 Bug 200682334 Change-Id: I53856a1ec497f432fd3358ffdc16f36d8ca75d40 Signed-off-by: rakesh goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2456032 (cherry picked from commit 6b2ca2be82458187318ba51d40166b0d9e437514) Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2457309 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_core.h | 8 +- include/osi_dma.h | 12 +-- osi/core/eqos_core.c | 212 ++++++++++++++++++++--------------------- osi/core/eqos_mmc.c | 8 +- osi/core/osi_core.c | 91 +++++++++--------- osi/dma/eqos_dma.c | 4 +- osi/dma/osi_dma.c | 63 ++++++------ osi/dma/osi_dma_txrx.c | 78 +++++++-------- 8 files changed, 229 insertions(+), 247 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index ce88ccb..814382c 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -132,10 +132,6 @@ typedef my_lint_64 nvel64_t; #define TWO_POWER_31 0x80000000U /** @} */ -/* to avoid re definition when both core and dma headers are included */ -#undef OSI_ERR -#undef OSI_INFO - /** * @brief OSI error macro definition, * @param[in] priv: OSD private data OR NULL @@ -143,7 +139,7 @@ typedef my_lint_64 nvel64_t; * @param[in] err: error string * @param[in] loga: error additional information */ -#define OSI_ERR(priv, type, err, loga) \ +#define OSI_CORE_ERR(priv, type, err, loga) \ { \ osi_core->osd_ops.ops_log(priv, __func__, __LINE__, \ OSI_LOG_ERR, type, err, loga);\ @@ -156,7 +152,7 @@ typedef my_lint_64 nvel64_t; * @param[in] err: error string * @param[in] loga: error additional information */ -#define OSI_INFO(priv, type, err, loga) \ +#define OSI_CORE_INFO(priv, type, err, loga) \ { \ osi_core->osd_ops.ops_log(priv, __func__, __LINE__, \ OSI_LOG_INFO, type, err, loga); \ diff --git a/include/osi_dma.h b/include/osi_dma.h index 4d97c45..68a3cf5 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -44,10 +44,6 @@ #define osi_likely(x) __builtin_expect(!!(x), 1) /** @} */ -/* to avoid re definition when both core and dma headers are included */ -#undef OSI_ERR -#undef OSI_INFO - /** * OSI error macro definition, * @param[in] priv: OSD private data OR NULL @@ -55,11 +51,13 @@ * @param[in] err: error string * @param[in] loga: error additional information */ -#define OSI_ERR(priv, type, err, loga) \ +#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 @@ -67,12 +65,12 @@ * @param[in] err: error string * @param[in] loga: error additional information */ -#define OSI_INFO(priv, type, err, loga) \ +#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 * diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index e8a4fb5..197db66 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -338,8 +338,8 @@ static nve32_t eqos_config_flow_control( /* return on invalid argument */ if (flw_ctrl > (OSI_FLOW_CTRL_RX | OSI_FLOW_CTRL_TX)) { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "flw_ctr: invalid input\n", 0ULL); + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "flw_ctr: invalid input\n", 0ULL); return -1; } @@ -423,8 +423,8 @@ static nve32_t eqos_config_fw_err_pkts( /* Check for valid fw_err and qinx values */ if (((fw_err != OSI_ENABLE) && (fw_err != OSI_DISABLE)) || (qinx >= OSI_EQOS_MAX_NUM_CHANS)) { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "config_fw_err: invalid input\n", 0ULL); + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "config_fw_err: invalid input\n", 0ULL); return -1; } @@ -497,8 +497,8 @@ static nve32_t eqos_poll_for_swr(struct osi_core_priv_data *const osi_core, count = 0; while (cond == 1) { if (count > retry) { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "poll_for_swr: timeout\n", 0ULL); + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + "poll_for_swr: timeout\n", 0ULL); return -1; } @@ -600,8 +600,8 @@ static nve32_t eqos_set_mode(struct osi_core_priv_data *const osi_core, /* Set DO (disable receive own) bit */ mcr_val |= EQOS_MCR_DO; } else { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "set_mode: invalid mode\n", 0ULL); + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "set_mode: invalid mode\n", 0ULL); return -1; /* Nothing here */ } @@ -833,8 +833,8 @@ static nve32_t eqos_flush_mtl_tx_queue( nve32_t cond = 1; if (qinx >= OSI_EQOS_MAX_NUM_QUEUES) { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "flush_mtl_tx_queue: invalid input\n", 0ULL); + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "flush_mtl_tx_queue: invalid input\n", 0ULL); return -1; } @@ -850,8 +850,8 @@ static nve32_t eqos_flush_mtl_tx_queue( count = 0; while (cond == 1) { if (count > retry) { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "Poll FTQ bit timeout\n", 0ULL); + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "Poll FTQ bit timeout\n", 0ULL); return -1; } @@ -1088,8 +1088,8 @@ static nve32_t eqos_config_rxcsum_offload( nveu32_t mac_mcr; if ((enabled != OSI_ENABLE) && (enabled != OSI_DISABLE)) { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "rxsum_offload: invalid input\n", 0ULL); + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "rxsum_offload: invalid input\n", 0ULL); return -1; } @@ -1152,9 +1152,9 @@ static void eqos_configure_rxq_priority( pmask |= osi_core->rxq_prio[mtlq]; temp = osi_core->rxq_prio[mtlq]; } else { - OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid rxq Priority for Q\n", - (nveul64_t)mtlq); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "Invalid rxq Priority for Q\n", + (nveul64_t)mtlq); continue; } @@ -1314,9 +1314,9 @@ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) 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_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Failed to set flow control configuration\n", - 0ULL); + 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 */ @@ -1413,9 +1413,8 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core, /* PAD calibration */ ret = eqos_pad_calibrate(osi_core); if (ret < 0) { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "eqos pad calibration failed\n", - 0ULL); + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + "eqos pad calibration failed\n", 0ULL); return ret; } @@ -1447,8 +1446,8 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core, EQOS_MTL_RXQ_DMA_MAP0_IDX); if (osi_unlikely(osi_core->num_mtl_queues > OSI_EQOS_MAX_NUM_QUEUES)) { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "Number of queues is incorrect\n", 0ULL); + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "Number of queues is incorrect\n", 0ULL); return -1; } @@ -1463,8 +1462,8 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core, for (qinx = 0; qinx < osi_core->num_mtl_queues; qinx++) { if (osi_unlikely(osi_core->mtl_queues[qinx] >= OSI_EQOS_MAX_NUM_QUEUES)) { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "Incorrect queues number\n", 0ULL); + 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], @@ -1538,14 +1537,14 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, 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_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "set mode in full duplex failed\n", 0ULL); + 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_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "set mode in half duplex failed\n", 0ULL); + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + "set mode in half duplex failed\n", 0ULL); } } @@ -1918,9 +1917,9 @@ static inline nve32_t eqos_update_mac_addr_helper( EQOS_MAC_ADDRH_DCS); } else if ((dma_chan == OSI_CHAN_ANY) || (dma_chan > (OSI_EQOS_MAX_NUM_CHANS - 0x1U))) { - OSI_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, - "invalid dma channel\n", - (nveul64_t)dma_chan); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, + "invalid dma channel\n", + (nveul64_t)dma_chan); ret = -1; goto err_dma_chan; } else { @@ -1936,9 +1935,9 @@ static inline nve32_t eqos_update_mac_addr_helper( ((addr_mask << EQOS_MAC_ADDRH_MBC_SHIFT) & EQOS_MAC_ADDRH_MBC)); } else { - OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "invalid address index for MBC\n", - 0ULL); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "invalid address index for MBC\n", + 0ULL); ret = -1; } } @@ -1988,9 +1987,8 @@ static nve32_t eqos_update_mac_addr_low_high_reg( nve32_t ret = 0; if (idx > (EQOS_MAX_MAC_ADDRESS_FILTER - 0x1U)) { - OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "invalid MAC filter index\n", - 0ULL); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "invalid MAC filter index\n", 0ULL); return -1; } @@ -2107,15 +2105,15 @@ static nve32_t eqos_update_ip4_addr(struct osi_core_priv_data *const osi_core, nveu32_t temp = 0U; if (addr == OSI_NULL) { - OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "invalid address\n", - 0ULL); + 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_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, - "invalid filter index for L3/L4 filter\n", - (nveul64_t)filter_no); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, + "invalid filter index for L3/L4 filter\n", + (nveul64_t)filter_no); return -1; } @@ -2169,15 +2167,15 @@ static nve32_t eqos_update_ip6_addr(struct osi_core_priv_data *const osi_core, nveu32_t temp = 0U; if (addr == OSI_NULL) { - OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "invalid address\n", - 0ULL); + 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_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "invalid filter index for L3/L4 filter\n", - (nveul64_t)filter_no); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "invalid filter index for L3/L4 filter\n", + (nveul64_t)filter_no); return -1; } @@ -2247,9 +2245,9 @@ static nve32_t eqos_update_l4_port_no( nveu32_t temp = 0U; if (filter_no > (EQOS_MAX_L3_L4_FILTER - 0x1U)) { - OSI_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, - "invalid filter index for L3/L4 filter\n", - (nveul64_t)filter_no); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, + "invalid filter index for L3/L4 filter\n", + (nveul64_t)filter_no); return -1; } @@ -2402,17 +2400,16 @@ static nve32_t eqos_config_l3_filters( void *base = osi_core->base; if (filter_no > (EQOS_MAX_L3_L4_FILTER - 0x1U)) { - OSI_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, - "invalid filter index for L3/L4 filter\n", - (nveul64_t)filter_no); + 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_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, - "Wrong DMA channel\n", - (nveul64_t)dma_chan); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, + "Wrong DMA channel\n", (nveul64_t)dma_chan); return -1; } @@ -2584,17 +2581,16 @@ static nve32_t eqos_config_l4_filters( nveu32_t value = 0U; if (filter_no > (EQOS_MAX_L3_L4_FILTER - 0x1U)) { - OSI_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, - "invalid filter index for L3/L4 filter\n", - (nveul64_t)filter_no); + 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_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, - "Wrong DMA channel\n", - (nveu32_t)dma_chan); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, + "Wrong DMA channel\n", (nveu32_t)dma_chan); return -1; } @@ -2702,8 +2698,8 @@ static inline nve32_t eqos_poll_for_tsinit_complete( count = 0; while (cond == 1) { if (count > retry) { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "poll_for_tsinit: timeout\n", 0ULL); + 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 */ @@ -2813,8 +2809,8 @@ static inline nve32_t eqos_poll_for_addend_complete( count = 0; while (cond == 1) { if (count > retry) { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "poll_for_addend: timeout\n", 0ULL); + 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 */ @@ -2915,8 +2911,8 @@ static inline nve32_t eqos_poll_for_update_ts_complete( count = 0; while (cond == 1) { if (count > retry) { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "poll_for_update_ts: timeout\n", 0ULL); + 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 */ @@ -3213,9 +3209,8 @@ static inline nve32_t poll_for_mii_idle(struct osi_core_priv_data *osi_core) count = 0; while (cond == 1) { if (count > retry) { - OSI_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "MII operation timed out\n", - 0ULL); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "MII operation timed out\n", 0ULL); return -1; } count++; @@ -3472,8 +3467,8 @@ static nve32_t eqos_validate_core_regs( * take care of corrective action. */ osi_unlock_irq_enabled(&config->core_safety_lock); - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "register mismatch\n", 0ULL); + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "register mismatch\n", 0ULL); return -1; } } @@ -3514,8 +3509,8 @@ static nve32_t eqos_config_rx_crc_check( /* return on invalid argument */ if (crc_chk != OSI_ENABLE && crc_chk != OSI_DISABLE) { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "rx_crc: invalid input\n", 0ULL); + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "rx_crc: invalid input\n", 0ULL); return -1; } @@ -3571,8 +3566,8 @@ static nve32_t eqos_config_tx_status(struct osi_core_priv_data *const osi_core, /* don't allow if tx_status is other than 0 or 1 */ if (tx_status != OSI_ENABLE && tx_status != OSI_DISABLE) { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "tx_status: invalid input\n", 0ULL); + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "tx_status: invalid input\n", 0ULL); return -1; } @@ -3641,33 +3636,30 @@ static nve32_t eqos_set_avb_algorithm( nveu32_t qinx; if (avb == OSI_NULL) { - OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "avb structure is NULL\n", - 0ULL); + 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_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid Queue index\n", - (nveul64_t)avb->qindex); + 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_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid Queue mode\n", - (nveul64_t)avb->qindex); + 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_ERR(osi_core->osd, OSI_LOG_ARG_OPNOTSUPP, - "Not allowed to set AVB for Q0\n", - (nveul64_t)avb->qindex); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OPNOTSUPP, + "Not allowed to set AVB for Q0\n", + (nveul64_t)avb->qindex); return ret; } @@ -3762,16 +3754,14 @@ static nve32_t eqos_get_avb_algorithm(struct osi_core_priv_data *const osi_core, nveu32_t qinx = 0U; if (avb == OSI_NULL) { - OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "avb structure is NULL\n", - 0ULL); + 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_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid Queue index\n", - (nveul64_t)avb->qindex); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "Invalid Queue index\n", (nveul64_t)avb->qindex); return ret; } @@ -3856,8 +3846,8 @@ static nve32_t eqos_config_arp_offload(const nveu32_t mac_ver, nveu32_t val; if (enable != OSI_ENABLE && enable != OSI_DISABLE) { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "arp_offload: invalid input\n", 0ULL); + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "arp_offload: invalid input\n", 0ULL); return -1; } @@ -3877,8 +3867,8 @@ static nve32_t eqos_config_arp_offload(const nveu32_t mac_ver, EQOS_5_00_MAC_ARPPA); } else { /* Unsupported MAC ver */ - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "arp_offload: invalid HW\n", 0ULL); + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "arp_offload: invalid HW\n", 0ULL); return -1; } @@ -3929,22 +3919,22 @@ static nve32_t eqos_config_vlan_filtering( void *base = osi_core->base; if (filter_enb_dis != OSI_ENABLE && filter_enb_dis != OSI_DISABLE) { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "vlan_filter: invalid input\n", 0ULL); + 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_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "vlan_filter: invalid input\n", 0ULL); + 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_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "vlan_filter: invalid input\n", 0ULL); + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "vlan_filter: invalid input\n", 0ULL); return -1; } @@ -3959,9 +3949,9 @@ static nve32_t eqos_config_vlan_filtering( value |= ((perfect_inverse_match << EQOS_MAC_VLAN_TR_VTIM_SHIFT) & EQOS_MAC_VLAN_TR_VTIM); if (perfect_hash_filtering == OSI_HASH_FILTER_MODE) { - OSI_ERR(osi_core->osd, OSI_LOG_ARG_OPNOTSUPP, - "VLAN hash filter is not supported, no updat of VTHM\n", - 0ULL); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OPNOTSUPP, + "VLAN hash filter is not supported, no update of VTHM\n", + 0ULL); } osi_writel(value, (nveu8_t *)base + EQOS_MAC_VLAN_TR); return 0; diff --git a/osi/core/eqos_mmc.c b/osi/core/eqos_mmc.c index 88a35e7..f023f2a 100644 --- a/osi/core/eqos_mmc.c +++ b/osi/core/eqos_mmc.c @@ -61,10 +61,10 @@ static inline nveu64_t update_mmc_val(struct osi_core_priv_data *osi_core, temp = last_value + value; if (temp < last_value) { - OSI_ERR(osi_core->osd, - OSI_LOG_ARG_OUTOFBOUND, - "Value overflow resetting all counters\n", - (nveul64_t)offset); + 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; diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 2cbe6e5..7803e1d 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -228,8 +228,8 @@ nve32_t osi_l2_filter(struct osi_core_priv_data *const osi_core, if ((op->config_mac_pkt_filter_reg != OSI_NULL)) { ret = op->config_mac_pkt_filter_reg(osi_core, filter); } else { - OSI_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "op->config_mac_pkt_filter_reg is null\n", 0ULL); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "op->config_mac_pkt_filter_reg is null\n", 0ULL); return ret; } @@ -239,9 +239,9 @@ nve32_t osi_l2_filter(struct osi_core_priv_data *const osi_core, if ((filter->dma_routing == OSI_ENABLE) && (osi_core->dcs_en != OSI_ENABLE)) { - OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "DCS requested. Conflicts with DT config\n", - 0ULL); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "DCS requested. Conflicts with DT config\n", + 0ULL); return ret; } @@ -249,9 +249,9 @@ nve32_t osi_l2_filter(struct osi_core_priv_data *const osi_core, ret = op->update_mac_addr_low_high_reg(osi_core, filter); } else { - OSI_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "op->update_mac_addr_low_high_reg is null\n", - 0ULL); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "op->update_mac_addr_low_high_reg is null\n", + 0ULL); } } @@ -299,8 +299,8 @@ static inline nve32_t helper_l4_filter( return -1; } } else { - OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "op->config_l4_filters is NULL\n", 0ULL); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "op->config_l4_filters is NULL\n", 0ULL); return -1; } @@ -310,8 +310,8 @@ static inline nve32_t helper_l4_filter( l_filter.port_no, l_filter.src_dst_addr_match); } else { - OSI_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "op->update_l4_port_no is NULL\n", 0ULL); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "op->update_l4_port_no is NULL\n", 0ULL); return -1; } @@ -358,8 +358,8 @@ static inline nve32_t helper_l3_filter( return -1; } } else { - OSI_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "op->config_l3_filters is NULL\n", 0ULL); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "op->config_l3_filters is NULL\n", 0ULL); return -1; } @@ -368,8 +368,8 @@ static inline nve32_t helper_l3_filter( return op->update_ip6_addr(osi_core, l_filter.filter_no, l_filter.ip6_addr); } else { - OSI_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "op->update_ip6_addr is NULL\n", 0ULL); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "op->update_ip6_addr is NULL\n", 0ULL); return -1; } } else if (type == OSI_IP4_FILTER) { @@ -379,9 +379,8 @@ static inline nve32_t helper_l3_filter( l_filter.ip4_addr, l_filter.src_dst_addr_match); } else { - OSI_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "op->update_ip4_addr is NULL\n", - 0ULL); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "op->update_ip4_addr is NULL\n", 0ULL); return -1; } } else { @@ -403,9 +402,9 @@ nve32_t osi_l3l4_filter(struct osi_core_priv_data *const osi_core, if ((dma_routing_enable == OSI_ENABLE) && (osi_core->dcs_en != OSI_ENABLE)) { - OSI_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "dma routing enabled but dcs disabled in DT\n", - 0ULL); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "dma routing enabled but dcs disabled in DT\n", + 0ULL); return ret; } @@ -418,8 +417,8 @@ nve32_t osi_l3l4_filter(struct osi_core_priv_data *const osi_core, } if (ret < 0) { - OSI_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "L3/L4 helper function failed\n", 0ULL); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "L3/L4 helper function failed\n", 0ULL); return ret; } @@ -435,8 +434,8 @@ nve32_t osi_l3l4_filter(struct osi_core_priv_data *const osi_core, } } else { - OSI_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "op->config_l3_l4_filter_enable is NULL\n", 0ULL); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "op->config_l3_l4_filter_enable is NULL\n", 0ULL); ret = -1; } @@ -518,8 +517,8 @@ nve32_t osi_adjust_freq(struct osi_core_priv_data *const osi_core, nve32_t ppb) if ((UINT_MAX - ppb1) > 0) { adj = (nveu64_t)addend * (nveu32_t)ppb1; } else { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "ppb1 > UINT_MAX\n", - 0ULL); + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "ppb1 > UINT_MAX\n", + 0ULL); return ret; } @@ -531,8 +530,8 @@ nve32_t osi_adjust_freq(struct osi_core_priv_data *const osi_core, nve32_t ppb) if (temp < UINT_MAX) { diff = (nveu32_t)temp; } else { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "temp > UINT_MAX\n", - 0ULL); + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "temp > UINT_MAX\n", + 0ULL); return ret; } @@ -540,8 +539,8 @@ nve32_t osi_adjust_freq(struct osi_core_priv_data *const osi_core, nve32_t ppb) if (addend <= (UINT_MAX - diff)) { addend = (addend + diff); } else { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "addend > UINT_MAX\n", 0ULL); + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "addend > UINT_MAX\n", 0ULL); return -1; } } else { @@ -550,8 +549,8 @@ nve32_t osi_adjust_freq(struct osi_core_priv_data *const osi_core, nve32_t ppb) } else if (addend < diff) { addend = diff - addend; } else { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "quotient > UINT_MAX\n", 0ULL); + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "quotient > UINT_MAX\n", 0ULL); return -1; } } @@ -561,8 +560,8 @@ nve32_t osi_adjust_freq(struct osi_core_priv_data *const osi_core, nve32_t ppb) return osi_core->ops->config_addend(osi_core, addend); } - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "core: Invalid argument\n", - 0ULL); + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "core: Invalid argument\n", + 0ULL); return ret; } @@ -591,8 +590,8 @@ nve32_t osi_adjust_time(struct osi_core_priv_data *const osi_core, ((OSI_ULLONG_MAX - nsec_delta1) > 0)) { udelta = (nveul64_t)nsec_delta1; } else { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "nsec_delta1 > OSI_ULLONG_MAX\n", 0ULL); + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "nsec_delta1 > OSI_ULLONG_MAX\n", 0ULL); return ret; } @@ -600,15 +599,15 @@ nve32_t osi_adjust_time(struct osi_core_priv_data *const osi_core, if (quotient <= UINT_MAX) { sec = (nveu32_t)quotient; } else { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "quotient > UINT_MAX\n", - 0ULL); + 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_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "reminder > UINT_MAX\n", - 0ULL); + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "reminder > UINT_MAX\n", 0ULL); return ret; } @@ -619,8 +618,8 @@ nve32_t osi_adjust_time(struct osi_core_priv_data *const osi_core, osi_core->ptp_config.one_nsec_accuracy); } - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "core: Invalid argument\n", - 0ULL); + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "core: Invalid argument\n", + 0ULL); return ret; } @@ -677,8 +676,8 @@ nve32_t osi_ptp_configuration(struct osi_core_priv_data *const osi_core, if (temp2 < UINT_MAX) { osi_core->default_addend = (nveu32_t)temp2; } else { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "core: temp2 >= UINT_MAX\n", 0ULL); + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "core: temp2 >= UINT_MAX\n", 0ULL); return -1; } diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index dd4bdd8..436ebc1 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -758,8 +758,8 @@ static nve32_t eqos_init_dma_channel(struct osi_dma_priv_data *osi_dma) /* configure EQOS DMA channels */ for (chinx = 0; chinx < osi_dma->num_dma_chans; chinx++) { if (osi_dma->dma_chans[chinx] >= OSI_EQOS_MAX_NUM_CHANS) { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma: invalid channel number\n", 0ULL); + OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma: invalid channel number\n", 0ULL); return -1; } eqos_configure_dma_channel(osi_dma->dma_chans[chinx], osi_dma); diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index a25c986..a4911fa 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -61,8 +61,8 @@ nve32_t osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) return 0; } - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "dma: Invalid argument\n", - 0ULL); + OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "dma: Invalid argument\n", + 0ULL); return -1; } @@ -77,8 +77,8 @@ nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) (osi_dma->num_dma_chans <= OSI_EQOS_MAX_NUM_CHANS)) { ret = osi_dma->ops->init_dma_channel(osi_dma); if (ret < 0) { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma: init dma channel failed\n", 0ULL); + OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma: init dma channel failed\n", 0ULL); return ret; } } else { @@ -96,22 +96,22 @@ nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) ret = osi_enable_chan_tx_intr(osi_dma, chan); if (ret != 0) { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma: enable tx intr failed\n", 0ULL); + OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma: enable tx intr failed\n", 0ULL); return ret; } ret = osi_enable_chan_rx_intr(osi_dma, chan); if (ret != 0) { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma: enable rx intr failed\n", 0ULL); + OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma: enable rx intr failed\n", 0ULL); return ret; } ret = osi_start_dma(osi_dma, chan); if (ret != 0) { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma: start dma failed\n", 0ULL); + OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma: start dma failed\n", 0ULL); return ret; } } @@ -292,14 +292,14 @@ static inline nve32_t rx_dma_desc_validate_args( if (!((rx_ring != OSI_NULL) && (rx_ring->rx_swcx != OSI_NULL) && (rx_ring->rx_desc != OSI_NULL))) { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma: Invalid pointers\n", 0ULL); + OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma: Invalid pointers\n", 0ULL); return -1; } if (chan >= OSI_EQOS_MAX_NUM_CHANS) { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "dma: Invalid channel\n", - 0ULL); + OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma: Invalid channel\n", 0ULL); return -1; } @@ -373,8 +373,8 @@ nve32_t osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, /* Populate the newly allocated buffer address */ temp = L32(rx_swcx->buf_phy_addr); if (temp > UINT_MAX) { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma: Invalid buf_phy_addr\n", 0ULL); + OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma: Invalid buf_phy_addr\n", 0ULL); /* error case do nothing */ } else { /* Store Receive Descriptor 0 */ @@ -386,8 +386,8 @@ nve32_t osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, /* Store Receive Descriptor 1 */ rx_desc->rdes1 = (nveu32_t)temp; } else { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma: Invalid buf_phy_addr\n", 0ULL); + OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma: Invalid buf_phy_addr\n", 0ULL); } rx_desc->rdes2 = 0; @@ -409,8 +409,8 @@ nve32_t osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, if (osi_unlikely(tailptr < rx_ring->rx_desc_phy_addr)) { /* Will not hit this case, used for CERT-C compliance */ - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "dma: Invalid tailptr\n", - 0ULL); + OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma: Invalid tailptr\n", 0ULL); return -1; } @@ -485,17 +485,16 @@ static inline nve32_t osi_slot_args_validate(struct osi_dma_priv_data *osi_dma, /* return on invalid set argument */ if ((set != OSI_ENABLE) && (set != OSI_DISABLE)) { - OSI_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, - "dma: Invalid set argument\n", - set); + OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, + "dma: Invalid set argument\n", set); return -1; } /* NULL check for osi_dma, osi_dma->ops and osi_dma->ops->config_slot */ if ((osi_dma->ops == OSI_NULL) || (osi_dma->ops->config_slot == OSI_NULL)) { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma: Invalid set argument\n", 0ULL); + OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma: Invalid set argument\n", 0ULL); return -1; } @@ -526,19 +525,17 @@ nve32_t osi_config_slot_function(struct osi_dma_priv_data *osi_dma, /* Get DMA slot interval and validate */ interval = osi_dma->slot_interval[chan]; if (interval > OSI_SLOT_INTVL_MAX) { - OSI_ERR(osi_dma->osd, - OSI_LOG_ARG_INVALID, - "dma: Invalid interval arguments\n", - interval); + 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_ERR(osi_dma->osd, - OSI_LOG_ARG_INVALID, - "tx_ring is null\n", - chan); + OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, + "tx_ring is null\n", chan); return -1; } tx_ring->slot_check = set; diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index c01081e..1af47b2 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -320,16 +320,16 @@ static inline nve32_t validate_rx_completions_arg( *rx_ring = osi_dma->rx_ring[chan]; if (osi_unlikely(*rx_ring == OSI_NULL)) { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "validate_input_rx_completions: Invalid pointers\n", - 0ULL); + 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_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "validate_input_rx_completions: Invalid pointers\n", - 0ULL); + OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "validate_input_rx_completions: Invalid pointers\n", + 0ULL); return -1; } @@ -357,8 +357,8 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, } if (rx_ring->cur_rx_idx >= RX_DESC_CNT) { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma_txrx: Invalid cur_rx_idx\n", 0ULL); + OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma_txrx: Invalid cur_rx_idx\n", 0ULL); return -1; } @@ -461,9 +461,9 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, osi_dma->rx_buf_len, rx_pkt_cx, rx_swcx); } else { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma_txrx: Invalid function pointer\n", - 0ULL); + OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma_txrx: Invalid function pointer\n", + 0ULL); return -1; } } @@ -705,9 +705,9 @@ static inline nve32_t validate_tx_completions_arg( *tx_ring = osi_dma->tx_ring[chan]; if (osi_unlikely(*tx_ring == OSI_NULL)) { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "validate_tx_completions_arg: Invalid pointers\n", - 0ULL); + OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "validate_tx_completions_arg: Invalid pointers\n", + 0ULL); return -1; } @@ -801,8 +801,9 @@ nve32_t osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, tx_swcx->len, txdone_pkt_cx); } else { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma_txrx: Invalid function pointer\n", 0ULL); + OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma_txrx: Invalid function pointer\n", + 0ULL); return -1; } @@ -1038,8 +1039,9 @@ static inline nve32_t validate_hw_transmit_arg( *ops = osi_dma->ops; if (osi_unlikely((*tx_ring == OSI_NULL) || (*ops == OSI_NULL))) { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "validate_hw_transmit_arg: Invalid pointers\n", 0ULL); + OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "validate_hw_transmit_arg: Invalid pointers\n", + 0ULL); return -1; } @@ -1070,8 +1072,8 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi_dma, nveu32_t chan) entry = tx_ring->cur_tx_idx; if (entry >= TX_DESC_CNT) { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma_txrx: Invalid pointers\n", 0ULL); + OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma_txrx: Invalid pointers\n", 0ULL); return; } @@ -1082,8 +1084,8 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi_dma, nveu32_t chan) desc_cnt = tx_pkt_cx->desc_cnt; if (osi_unlikely(desc_cnt == 0U)) { /* Will not hit this case */ - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma_txrx: Invalid value\n", 0ULL); + OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma_txrx: Invalid value\n", 0ULL); return; } /* Context descriptor for VLAN/TSO */ @@ -1184,8 +1186,8 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi_dma, nveu32_t chan) (entry * sizeof(struct osi_tx_desc)); if (osi_unlikely(tailptr < tx_ring->tx_desc_phy_addr)) { /* Will not hit this case */ - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma_txrx: Invalid argument\n", 0ULL); + OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma_txrx: Invalid argument\n", 0ULL); return; } @@ -1197,8 +1199,8 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi_dma, nveu32_t chan) */ dmb_oshst(); if (osi_unlikely(ops->update_tx_tailptr == OSI_NULL)) { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma_txrx: Invalid argument\n", 0ULL); + OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma_txrx: Invalid argument\n", 0ULL); return; } ops->update_tx_tailptr(osi_dma->base, chan, tailptr); @@ -1238,8 +1240,8 @@ static nve32_t rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, rx_ring = osi_dma->rx_ring[chan]; if (osi_unlikely(rx_ring == OSI_NULL)) { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma_txrx: Invalid argument\n", 0ULL); + OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma_txrx: Invalid argument\n", 0ULL); return -1; }; @@ -1260,8 +1262,8 @@ static nve32_t rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, if (tmp < UINT_MAX) { rx_desc->rdes0 = (nveu32_t)tmp; } else { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma_txrx: Invalid buf_phy_addr\n", 0ULL); + OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma_txrx: Invalid buf_phy_addr\n", 0ULL); return -1; } @@ -1269,8 +1271,8 @@ static nve32_t rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, if (tmp < UINT_MAX) { rx_desc->rdes1 = (nveu32_t)tmp; } else { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma_txrx: Invalid buf_phy_addr\n", 0ULL); + OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma_txrx: Invalid buf_phy_addr\n", 0ULL); return -1; } @@ -1301,8 +1303,8 @@ static nve32_t rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, (ops->update_rx_tailptr == OSI_NULL) || (ops->set_rx_ring_start_addr == OSI_NULL))) { /* Will not hit this case */ - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma_txrx: Invalid pointers\n", 0ULL); + OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma_txrx: Invalid pointers\n", 0ULL); return -1; } @@ -1385,8 +1387,8 @@ static nve32_t tx_dma_desc_init(struct osi_dma_priv_data *osi_dma) tx_ring = osi_dma->tx_ring[chan]; if (osi_unlikely(tx_ring == OSI_NULL)) { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma_txrx: Invalid pointers\n", 0ULL); + OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma_txrx: Invalid pointers\n", 0ULL); return -1; } @@ -1419,8 +1421,8 @@ static nve32_t tx_dma_desc_init(struct osi_dma_priv_data *osi_dma) ops->set_tx_ring_start_addr(osi_dma->base, chan, tx_ring->tx_desc_phy_addr); } else { - OSI_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma_txrx: Invalid pointers\n", 0ULL); + OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "dma_txrx: Invalid pointers\n", 0ULL); return -1; } } From 53feb3970488efcf52afc4670144c26314c24490 Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Sun, 13 Dec 2020 18:04:32 +0530 Subject: [PATCH 137/458] osi: common: change eqos MAC version to 0x53 Bug 200681386 Change-Id: I034e8bde53a957916113812adc937ae3f0dc5825 Signed-off-by: narayanr <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2454879 GVS: Gerrit_Virtual_Submit Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Sachin Nikam <snikam@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_common.h | 2 +- osi/common/common.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index cfa6b19..054a3c1 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -162,7 +162,7 @@ #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_MAX_VM_IRQS 5U #ifndef OSI_STRIPPED_LIB diff --git a/osi/common/common.h b/osi/common/common.h index 86451c2..2b0ce20 100644 --- a/osi/common/common.h +++ b/osi/common/common.h @@ -162,7 +162,7 @@ static inline nve32_t is_valid_mac_version(nveu32_t mac_ver) { if ((mac_ver == OSI_EQOS_MAC_4_10) || (mac_ver == OSI_EQOS_MAC_5_00) || - (mac_ver == OSI_EQOS_MAC_5_10)) { + (mac_ver == OSI_EQOS_MAC_5_30)) { return 1; } From ee77dabe88eb49d0bae884b475a7e03f9571664c Mon Sep 17 00:00:00 2001 From: Michael Hsu <mhsu@nvidia.com> Date: Wed, 11 Nov 2020 01:38:48 -0800 Subject: [PATCH 138/458] osi: increase rx/tx descriptor count Increase number of rx/tx descriptors for better network performance. Bug 3175332 Change-Id: I053143b3512518c6c2dbdbe0d6480ddd5bc013cc Signed-off-by: Michael Hsu <mhsu@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2444522 (cherry picked from commit 6810ca53b294bedb27e8cb275134a143a36b2e68) Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2458848 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_dma_txrx.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/osi_dma_txrx.h b/include/osi_dma_txrx.h index b690667..f142d48 100644 --- a/include/osi_dma_txrx.h +++ b/include/osi_dma_txrx.h @@ -29,8 +29,8 @@ * @brief Helper macros for defining Tx/Rx descriptor count * @{ */ -#define TX_DESC_CNT 256U -#define RX_DESC_CNT 256U +#define TX_DESC_CNT 1024U +#define RX_DESC_CNT 1024U /** @} */ /** TSO Header length divisor */ From 02bc2f6e6441ecf2e214a10deab1ba73c9abfc8f Mon Sep 17 00:00:00 2001 From: rakesh goyal <rgoyal@nvidia.com> Date: Thu, 10 Dec 2020 21:07:38 +0530 Subject: [PATCH 139/458] osi: fix doxygen comments and advisory error 11.1 Issue: - incorrect doxygen comment for new file added - Misra error 11.1 due to mismatch in defination and Diclariation Fix: - Fix doxygen comments - Fix MisraC errors Bug 200682334 Change-Id: Ia9a5fd71cc41906169dd0d83d9e4d2cdb5163745 Signed-off-by: rakesh goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2458315 Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2459446 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_core.h | 11 +++++++++++ include/osi_dma.h | 2 -- osi/common/type.h | 21 ++++++++++++++++++++- osi/core/eqos_core.c | 8 +++----- osi/core/eqos_mmc.c | 6 +++--- osi/core/eqos_mmc.h | 4 ++-- osi/dma/eqos_dma.c | 2 -- osi/dma/osi_dma_local.h | 15 +++++++++------ 8 files changed, 48 insertions(+), 21 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 814382c..9ea144e 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -27,15 +27,26 @@ #include "mmc.h" #include "../osi/common/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 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; +/** @} */ /** * @addtogroup PTP related information diff --git a/include/osi_dma.h b/include/osi_dma.h index 68a3cf5..b2208f6 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -138,10 +138,8 @@ * * @brief Flag to indicate the result from checksum offload engine * to SW network stack in receive path. -#ifndef OSI_STRIPPED_LIB * OSI_CHECKSUM_NONE indicates that HW checksum offload * engine did not verify the checksum, SW network stack has to do it. -#endif * OSI_CHECKSUM_UNNECESSARY indicates that HW validated the * checksum already, network stack can skip validation. * @{ diff --git a/osi/common/type.h b/osi/common/type.h index 2c6a2e1..035c69f 100644 --- a/osi/common/type.h +++ b/osi/common/type.h @@ -22,22 +22,41 @@ #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 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 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/eqos_core.c b/osi/core/eqos_core.c index 197db66..d9761d5 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -203,8 +203,6 @@ static void eqos_core_safety_init(struct osi_core_priv_data *const osi_core) * - De-initialization: No * * @param[in] osi_core: OSI core private data structure. - * - * @retval none */ static void eqos_core_backup_init(struct osi_core_priv_data *const osi_core) { @@ -2955,9 +2953,9 @@ static inline nve32_t eqos_poll_for_update_ts_complete( * @retval -1 on failure. */ static nve32_t eqos_adjust_mactime(struct osi_core_priv_data *const osi_core, - nveu32_t sec, nveu32_t nsec, - nveu32_t add_sub, - nveu32_t one_nsec_accuracy) + 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; diff --git a/osi/core/eqos_mmc.c b/osi/core/eqos_mmc.c index f023f2a..b0fc915 100644 --- a/osi/core/eqos_mmc.c +++ b/osi/core/eqos_mmc.c @@ -51,7 +51,7 @@ * @retval 0 on success * @retval -1 on failure */ -static inline nveu64_t update_mmc_val(struct osi_core_priv_data *osi_core, +static inline nveu64_t update_mmc_val(struct osi_core_priv_data *const osi_core, nveu64_t last_value, nveu64_t offset) { @@ -89,7 +89,7 @@ static inline nveu64_t update_mmc_val(struct osi_core_priv_data *osi_core, * - Run time: Yes * - De-initialization: No */ -void eqos_reset_mmc(struct osi_core_priv_data *osi_core) +void eqos_reset_mmc(struct osi_core_priv_data *const osi_core) { nveu32_t value; @@ -121,7 +121,7 @@ void eqos_reset_mmc(struct osi_core_priv_data *osi_core) * - Run time: Yes * - De-initialization: No */ -void eqos_read_mmc(struct osi_core_priv_data *osi_core) +void eqos_read_mmc(struct osi_core_priv_data *const osi_core) { struct osi_mmc_counters *mmc = &osi_core->mmc; diff --git a/osi/core/eqos_mmc.h b/osi/core/eqos_mmc.h index 1a17758..45b5dd1 100644 --- a/osi/core/eqos_mmc.h +++ b/osi/core/eqos_mmc.h @@ -115,6 +115,6 @@ #define MMC_RXICMP_ERR_OCTETS 0x00884 /** @} */ -void eqos_read_mmc(struct osi_core_priv_data *osi_core); -void eqos_reset_mmc(struct osi_core_priv_data *osi_core); +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/dma/eqos_dma.c b/osi/dma/eqos_dma.c index 436ebc1..65ca548 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -885,8 +885,6 @@ static nve32_t eqos_validate_dma_regs(struct osi_dma_priv_data *osi_dma) * - Initialization: Yes * - Run time: Yes * - De-initialization: No - * - * @retval none */ static void eqos_config_slot(struct osi_dma_priv_data *osi_dma, nveu32_t chan, diff --git a/osi/dma/osi_dma_local.h b/osi/dma/osi_dma_local.h index e4a92d6..671c2ae 100644 --- a/osi/dma/osi_dma_local.h +++ b/osi/dma/osi_dma_local.h @@ -50,19 +50,22 @@ */ nve32_t dma_desc_init(struct osi_dma_priv_data *osi_dma); +/** + * @addtogroup Helper Helper MACROS + * + * @brief EQOS generic helper MACROS. + * @{ + */ #define CHECK_CHAN_BOUND(chan) \ { \ if ((chan) >= OSI_EQOS_MAX_NUM_CHANS) { \ return; \ } \ } \ -/** - * @addtogroup Helper Helper MACROS - * - * @brief EQOS DMA generic helper MACROS. - * @{ - */ + #define BOOLEAN_FALSE (0U != 0U) #define L32(data) ((data) & 0xFFFFFFFFU) #define H32(data) (((data) & 0xFFFFFFFF00000000UL) >> 32UL) +/** @} */ + #endif /* INCLUDED_OSI_DMA_LOCAL_H */ From 0a1138f8794e8ff42d5994111126026132b1e53a Mon Sep 17 00:00:00 2001 From: rakesh goyal <rgoyal@nvidia.com> Date: Mon, 14 Dec 2020 19:19:00 +0530 Subject: [PATCH 140/458] osi: core: dma: fix issue identified in unit testing Issue: - rx_ring pointer validation missing in interface API - Misra-C issue introduced while fixing Advisory error. - if addend = diff, osi_adjut_freq return -1 - OSI_MAC_TCR_SNAPTYPSEL_3 unused macro Fix: - add check for rx_ring pointer validation - Fix Misra C error - proceed further instead of returning -1 - Hide OSI_MAC_TCR_SNAPTYPSEL_3 for QNX Bug 200686220 Change-Id: I806b4f33b86ee08c96ddb76fbfb91bf394206d70 Signed-off-by: rakesh goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2459580 (cherry picked from commit fabc231aa387a74158b6efe926659c33c1abf0c6) Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2460837 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_common.h | 1 - include/osi_core.h | 4 +++- include/osi_dma.h | 3 ++- osi/core/eqos_core.c | 5 +---- osi/core/osi_core.c | 24 ++++++------------------ osi/dma/osi_dma.c | 3 ++- 6 files changed, 14 insertions(+), 26 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index 054a3c1..4cef517 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -128,7 +128,6 @@ * @{ */ #define OSI_UCHAR_MAX (0xFFU) -#define OSI_ULLONG_MAX (~0ULL) /* Logging defines */ /* log levels */ diff --git a/include/osi_core.h b/include/osi_core.h index 9ea144e..aea4545 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -77,8 +77,10 @@ typedef my_lint_64 nvel64_t; #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_SNAPTYPSEL_3 (OSI_BIT(16) | OSI_BIT(17)) #define OSI_MAC_TCR_AV8021ASMEN OSI_BIT(28) +#ifndef OSI_STRIPPED_LIB +#define OSI_MAC_TCR_SNAPTYPSEL_3 (OSI_BIT(16) | OSI_BIT(17)) +#endif /* !OSI_STRIPPED_LIB */ /** @} */ /** diff --git a/include/osi_dma.h b/include/osi_dma.h index b2208f6..cf76b7b 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -38,7 +38,8 @@ #define OSI_INVALID_VALUE 0xFFFFFFFFU -#define OSI_ONE_MEGA_HZ 1000000U +#define OSI_ONE_MEGA_HZ 1000000U +#define OSI_ULLONG_MAX (~0ULL) /* Compiler hints for branch prediction */ #define osi_likely(x) __builtin_expect(!!(x), 1) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index d9761d5..21307e8 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -2771,7 +2771,7 @@ static nve32_t eqos_set_systime_to_mac( } /** - * @brief eqos_poll_for_tsinit_complete - Poll for addend value write complete + * @brief eqos_poll_for_addend_complete - Poll for addend value write complete * * @note * Algorithm: @@ -3066,9 +3066,6 @@ static void eqos_config_tscr(void *addr, const nveu32_t ptp_filter) case OSI_MAC_TCR_SNAPTYPSEL_2: mac_tcr |= OSI_MAC_TCR_SNAPTYPSEL_2; break; - case OSI_MAC_TCR_SNAPTYPSEL_3: - mac_tcr |= OSI_MAC_TCR_SNAPTYPSEL_3; - break; case OSI_MAC_TCR_TSIPV4ENA: mac_tcr |= OSI_MAC_TCR_TSIPV4ENA; break; diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 7803e1d..8f41774 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -504,22 +504,17 @@ nve32_t osi_adjust_freq(struct osi_core_priv_data *const osi_core, nve32_t ppb) nve32_t ret = -1; nve32_t ppb1 = ppb; - if (ppb1 < 0) { - neg_adj = 1U; - ppb1 = -ppb1; - } - if (osi_core == OSI_NULL) { return ret; } addend = osi_core->default_addend; - if ((UINT_MAX - ppb1) > 0) { + if (ppb1 < 0) { + neg_adj = 1U; + ppb1 = -ppb1; adj = (nveu64_t)addend * (nveu32_t)ppb1; } else { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "ppb1 > UINT_MAX\n", - 0ULL); - return ret; + adj = (nveu64_t)addend * (nveu32_t)ppb1; } /* @@ -550,8 +545,7 @@ nve32_t osi_adjust_freq(struct osi_core_priv_data *const osi_core, nve32_t ppb) addend = diff - addend; } else { OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "quotient > UINT_MAX\n", 0ULL); - return -1; + "addend = diff\n", 0ULL); } } @@ -584,15 +578,9 @@ nve32_t osi_adjust_time(struct osi_core_priv_data *const osi_core, if (nsec_delta1 < 0) { neg_adj = 1; nsec_delta1 = -nsec_delta1; - } - - if ((nsec_delta1 >= 0) && - ((OSI_ULLONG_MAX - nsec_delta1) > 0)) { udelta = (nveul64_t)nsec_delta1; } else { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "nsec_delta1 > OSI_ULLONG_MAX\n", 0ULL); - return ret; + udelta = (nveul64_t)nsec_delta1; } quotient = div_u64_rem(udelta, OSI_NSEC_PER_SEC, &reminder); diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index a4911fa..000a564 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -253,7 +253,8 @@ nve32_t osi_stop_dma(struct osi_dma_priv_data *osi_dma, nveu32_t osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring) { - if ((rx_ring->cur_rx_idx >= RX_DESC_CNT) || + if ((rx_ring == OSI_NULL) || + (rx_ring->cur_rx_idx >= RX_DESC_CNT) || (rx_ring->refill_idx >= RX_DESC_CNT)) { return 0; } From 2a873b3f3dade8cc59b81c564d3f760c150e9df1 Mon Sep 17 00:00:00 2001 From: nannaiah <nannaiah@nvidia.com> Date: Thu, 22 Oct 2020 13:20:56 -0700 Subject: [PATCH 141/458] nvthernetrm: Add IVC support for OSI In case of virtualization the OSI functions will be handled at Ethernet Server. Add IVC support where OSD can send IVC packets to ethernet server. Ethernet Server parses the messages and calls the corresponding OSI API. OSI and few DMA API's are updated to support osi_core as an argument. Bug 2694285 Change-Id: Ic56b8e9f5f9cd70cc70239b61d756bfa2e998588 Signed-off-by: Nagaraj Annaiah <nannaiah@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2435281 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/ivc_core.h | 204 ++++++ include/osi_common.h | 55 +- include/osi_core.h | 53 +- include/osi_dma.h | 10 +- osi/common/common.h | 104 +++ osi/common/osi_common.c | 110 +-- osi/core/eqos_core.c | 724 +++++++++++-------- osi/core/eqos_core.h | 2 + osi/core/ivc_core.c | 1492 +++++++++++++++++++++++++++++++++++++++ osi/core/osi_core.c | 188 ++++- osi/dma/eqos_dma.c | 64 +- osi/dma/osi_dma.c | 4 +- osi/dma/osi_dma_txrx.c | 6 +- 13 files changed, 2478 insertions(+), 538 deletions(-) create mode 100644 include/ivc_core.h create mode 100644 osi/core/ivc_core.c diff --git a/include/ivc_core.h b/include/ivc_core.h new file mode 100644 index 0000000..0dcef0f --- /dev/null +++ b/include/ivc_core.h @@ -0,0 +1,204 @@ +/* + * 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 IVC_CORE_H +#define IVC_CORE_H + +#include "osi_core.h" +/** + * @brief Ethernet Maximum IVC BUF + */ +#define ETHER_MAX_IVC_BUF 1024 + +/** + * @brief IVC maximum arguments + */ +#define MAX_ARGS 10 + +/** + * @brief IVC commands between OSD & OSI. + */ +enum ivc_cmd { + poll_for_swr = 1, + core_init, + core_deinit, + start_mac, + stop_mac, + handle_common_intr, + set_mode, + set_speed, + pad_calibrate, + config_fw_err_pkts, + config_rxcsum_offload, + config_mac_pkt_filter_reg, + update_mac_addr_low_high_reg, + config_l3_l4_filter_enable, + config_l3_filters, + update_ip4_addr, + update_ip6_addr, + config_l4_filters, + update_l4_port_no, + set_systime_to_mac, + config_addend, + adjust_mactime, + config_tscr, + config_ssir, + read_mmc, + write_phy_reg, + read_phy_reg, + reg_read, + reg_write, +#ifndef OSI_STRIPPED_LIB + config_tx_status, + config_rx_crc_check, + config_flow_control, + config_arp_offload, + validate_regs, + flush_mtl_tx_queue, + set_avb_algorithm, + get_avb_algorithm, + config_vlan_filtering, + update_vlan_id, + reset_mmc, + configure_eee, + save_registers, + restore_registers, + set_mdc_clk_rate, + config_mac_loopback, +#endif /* !OSI_STRIPPED_LIB */ +}; + +/** + * @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 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. + */ + nveu32_t status; + /** + * ID of the CMD. + */ + nveu32_t 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; + /** + * core argument structure + */ + ivc_core_args init_args; + }data; +} ivc_msg_common; + +/** + * @brief osd_ivc_send_cmd - OSD ivc send cmd + * + * @param[in] priv: OSD private data + * @param[in] data: data + * @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, void *data, 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); + +/** + * @brief ivc_get_hw_core_ops - Get hw core operations + * + * API Group: + * - Initialization: Yes + * - Run time: Yes + * - De-initialization: Yes + */ +struct osi_core_ops *ivc_get_hw_core_ops(void); +#endif /* IVC_CORE_H */ diff --git a/include/osi_common.h b/include/osi_common.h index 4cef517..a9bd520 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -566,44 +566,6 @@ struct osi_hw_features { nveu32_t num_tbs_ch; }; -/** - * @brief common_get_mac_version - Reading MAC version - * - * @note - * Algorithm: - * - Reads MAC version and check whether its valid or not. - * - * @param[in] addr: io-remap MAC base address. - * @param[out] mac_ver: holds mac version. - * - * @pre MAC has to be out of reset. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t common_get_mac_version(void *addr, nveu32_t *mac_ver); - -/** - * @brief comon_get_hw_features - Reading MAC HW features - * - * @param[in] base: io-remap MAC base address. - * @param[out] hw_feat: holds the supported features of the hardware. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @pre MAC has to be out of reset. - */ -void common_get_hw_features(void *base, struct osi_hw_features *hw_feat); /** * @brief osi_memset - osi memset * @@ -618,4 +580,19 @@ void common_get_hw_features(void *base, struct osi_hw_features *hw_feat); * - De-initialization: No */ void osi_memset(void *s, nveu32_t c, nveu64_t count); -#endif /* INCLUDED_OSI_COMMON_H */ + +/** + * @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 + */ +void osi_memcpy(void *dest, void *src, int n); +#endif /* OSI_COMMON_H */ diff --git a/include/osi_core.h b/include/osi_core.h index aea4545..9a8e3c3 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -183,7 +183,7 @@ struct osi_filter { * Filter index must be between 0 - 127 */ nveu32_t index; /** Ethernet MAC address to be added */ - const nveu8_t *mac_address; + 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 */ @@ -281,8 +281,7 @@ struct osi_core_avb_algorithm { */ struct osi_core_ops { /** Called to poll for software reset bit */ - nve32_t (*poll_for_swr)(struct osi_core_priv_data *const osi_core, - nve32_t pre_si); + 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, @@ -290,16 +289,17 @@ struct osi_core_ops { /** 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)(void *addr); + void (*start_mac)(struct osi_core_priv_data *const osi_core); /** Called to stop MAC Tx and Rx engine */ - void (*stop_mac)(void *addr); + 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 (10/100/1000) at MAC */ - void (*set_speed)(void *ioaddr, const nve32_t speed); + void (*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 */ @@ -319,8 +319,9 @@ struct osi_core_ops { 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)(void *base, - const nveu32_t enable); + 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, @@ -367,7 +368,8 @@ struct osi_core_ops { const nveu32_t sec, const nveu32_t nsec); /** Called to configure the TimeStampControl register */ - void (*config_tscr)(void *addr, const nveu32_t ptp_filter); + 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); /** Called to update MMC counter from HW register */ @@ -381,6 +383,13 @@ struct osi_core_ops { 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); #ifndef OSI_STRIPPED_LIB /** Called periodically to read and validate safety critical * registers against last written value */ @@ -406,8 +415,7 @@ struct osi_core_ops { 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)(const nveu32_t mac_ver, - struct osi_core_priv_data *const osi_core, + 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 */ @@ -417,7 +425,8 @@ struct osi_core_ops { const nveu32_t perfect_hash_filtering, const nveu32_t perfect_inverse_match); /** called to update VLAN id */ - nve32_t (*update_vlan_id)(void *base, const nveu32_t vid); + nve32_t (*update_vlan_id)(struct osi_core_priv_data *const osi_core, + const nveu32_t vid); /** Called to reset MMC HW counter structure */ void (*reset_mmc)(struct osi_core_priv_data *const osi_core); /** Called to configure EEE Tx LPI */ @@ -432,7 +441,9 @@ struct osi_core_ops { 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)(void *addr, const nveu32_t lb_mode); + nve32_t (*config_mac_loopback)( + struct osi_core_priv_data *const osi_core, + const nveu32_t lb_mode); #endif /* !OSI_STRIPPED_LIB */ }; @@ -513,6 +524,8 @@ struct osd_core_ops { void (*usleep_range)(nveu64_t umin, nveu64_t umax); /** msleep callback */ void (*msleep)(nveu32_t msec); + /** ivcsend callback*/ + nve32_t (*ivc_send)(void *priv, void *data, nveu32_t len); }; /** @@ -576,7 +589,9 @@ struct osi_core_priv_data { */ nveu32_t csr_clk_speed; /** Tegra Pre-si platform info */ - nve32_t pre_si; + nveu32_t pre_si; + /** Flag which decides virtualization is enabled(1) or disabled(0) */ + nveu32_t use_virtualization; }; /** @@ -1386,7 +1401,7 @@ nve32_t osi_l3l4_filter(struct osi_core_priv_data *const osi_core, * Algorithm: * - Reads MAC version and check whether its valid or not. * - * @param[in] addr: io-remap MAC base address. + * @param[in] osi_core: OSI core private data structure. * @param[out] mac_ver: holds mac version. * * @pre MAC has to be out of reset. @@ -1411,12 +1426,13 @@ nve32_t osi_l3l4_filter(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -nve32_t osi_get_mac_version(void *addr, nveu32_t *mac_ver); +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] base: io-remap MAC base address. + * @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. @@ -1439,7 +1455,8 @@ nve32_t osi_get_mac_version(void *addr, nveu32_t *mac_ver); * - De-initialization: No * */ -void osi_get_hw_features(void *base, struct osi_hw_features *hw_feat); +void osi_get_hw_features(struct osi_core_priv_data *const osi_core, + struct osi_hw_features *hw_feat); #ifndef OSI_STRIPPED_LIB /** diff --git a/include/osi_dma.h b/include/osi_dma.h index cf76b7b..dbf42f0 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -398,7 +398,8 @@ struct osi_dma_priv_data; */ struct osi_dma_chan_ops { /** Called to set Transmit Ring length */ - void (*set_tx_ring_len)(void *addr, nveu32_t chan, + 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, @@ -407,7 +408,8 @@ struct osi_dma_chan_ops { void (*update_tx_tailptr)(void *addr, nveu32_t chan, nveu64_t tailptr); /** Called to set Receive channel ring length */ - void (*set_rx_ring_len)(void *addr, nveu32_t chan, + 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, @@ -424,9 +426,9 @@ struct osi_dma_chan_ops { /** 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)(void *addr, nveu32_t chan); + void (*start_dma)(struct osi_dma_priv_data *osi_dma, nveu32_t chan); /** Called to stop the Tx/Rx DMA */ - void (*stop_dma)(void *addr, nveu32_t chan); + 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 */ diff --git a/osi/common/common.h b/osi/common/common.h index 2b0ce20..8b3a962 100644 --- a/osi/common/common.h +++ b/osi/common/common.h @@ -24,6 +24,8 @@ #include <osi_common.h> +struct osi_core_priv_data; + /** * @brief osi_lock_init - Initialize lock to unlocked state. * @@ -142,6 +144,108 @@ static inline void osi_writel(nveu32_t val, void *addr) *(volatile nveu32_t *)addr = val; } +/** + * @brief osi_read_reg - Read a MAC register. + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] addr: MAC register + * + * @note + * Traceability Details: TODO + * + * @note + * Classification: + * - Interrupt: No + * - Signal handler: No + * - Thread safe: No + * - Required Privileges: None + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: Yes + * - De-initialization: Yes + * + * @retval data from MAC register on success + * @retval -1 on failure + */ +nveu32_t osi_read_reg(struct osi_core_priv_data *const osi_core, + const nve32_t addr); + +/** + * @brief osi_write_reg - Write a MAC register. + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] val: MAC register value + * @param[in] addr: MAC register + * + * @note + * Traceability Details: TODO + * + * @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 data from MAC register on success + * @retval -1 on failure + */ +nveu32_t osi_write_reg(struct osi_core_priv_data *const osi_core, + const nveu32_t val, const nve32_t addr); + +#ifdef ETHERNET_SERVER +nveu32_t osi_readla(void *priv, void *addr); + +void osi_writela(void *priv, nveu32_t val, void *addr); +#else +/** + * @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(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(void *priv, nveu32_t val, void *addr) +{ + *(volatile nveu32_t *)addr = val; +} +#endif + /** * @brief is_valid_mac_version - Check if read MAC IP is valid or not. * diff --git a/osi/common/osi_common.c b/osi/common/osi_common.c index bf82a23..e932a10 100644 --- a/osi/common/osi_common.c +++ b/osi/common/osi_common.c @@ -24,105 +24,7 @@ #include "eqos_common.h" #include "../osi/common/common.h" -void common_get_hw_features(void *base, struct osi_hw_features *hw_feat) -{ - nveu32_t mac_hfr0; - nveu32_t mac_hfr1; - nveu32_t mac_hfr2; - /* TODO: need to add HFR3 */ - mac_hfr0 = osi_readl((nveu8_t *)base + EQOS_MAC_HFR0); - mac_hfr1 = osi_readl((nveu8_t *)base + EQOS_MAC_HFR1); - mac_hfr2 = osi_readl((nveu8_t *)base + EQOS_MAC_HFR2); - - hw_feat->mii_sel = - ((mac_hfr0 >> 0) & EQOS_MAC_HFR0_MIISEL_MASK); - hw_feat->gmii_sel = - ((mac_hfr0 >> 1U) & EQOS_MAC_HFR0_GMIISEL_MASK); - hw_feat->hd_sel = - ((mac_hfr0 >> 2U) & EQOS_MAC_HFR0_HDSEL_MASK); - hw_feat->pcs_sel = - ((mac_hfr0 >> 3U) & EQOS_MAC_HFR0_PCSSEL_MASK); - hw_feat->sma_sel = - ((mac_hfr0 >> 5U) & EQOS_MAC_HFR0_SMASEL_MASK); - hw_feat->rwk_sel = - ((mac_hfr0 >> 6U) & EQOS_MAC_HFR0_RWKSEL_MASK); - hw_feat->mgk_sel = - ((mac_hfr0 >> 7U) & EQOS_MAC_HFR0_MGKSEL_MASK); - hw_feat->mmc_sel = - ((mac_hfr0 >> 8U) & EQOS_MAC_HFR0_MMCSEL_MASK); - hw_feat->arp_offld_en = - ((mac_hfr0 >> 9U) & EQOS_MAC_HFR0_ARPOFFLDEN_MASK); - hw_feat->ts_sel = - ((mac_hfr0 >> 12U) & EQOS_MAC_HFR0_TSSSEL_MASK); - hw_feat->eee_sel = - ((mac_hfr0 >> 13U) & EQOS_MAC_HFR0_EEESEL_MASK); - hw_feat->tx_coe_sel = - ((mac_hfr0 >> 14U) & EQOS_MAC_HFR0_TXCOESEL_MASK); - hw_feat->rx_coe_sel = - ((mac_hfr0 >> 16U) & EQOS_MAC_HFR0_RXCOE_MASK); - hw_feat->mac_addr_sel = - ((mac_hfr0 >> 18U) & EQOS_MAC_HFR0_ADDMACADRSEL_MASK); - hw_feat->mac_addr32_sel = - ((mac_hfr0 >> 23U) & EQOS_MAC_HFR0_MACADR32SEL_MASK); - hw_feat->mac_addr64_sel = - ((mac_hfr0 >> 24U) & EQOS_MAC_HFR0_MACADR64SEL_MASK); - hw_feat->tsstssel = - ((mac_hfr0 >> 25U) & EQOS_MAC_HFR0_TSINTSEL_MASK); - hw_feat->sa_vlan_ins = - ((mac_hfr0 >> 27U) & EQOS_MAC_HFR0_SAVLANINS_MASK); - hw_feat->act_phy_sel = - ((mac_hfr0 >> 28U) & EQOS_MAC_HFR0_ACTPHYSEL_MASK); - hw_feat->rx_fifo_size = - ((mac_hfr1 >> 0) & EQOS_MAC_HFR1_RXFIFOSIZE_MASK); - hw_feat->tx_fifo_size = - ((mac_hfr1 >> 6U) & EQOS_MAC_HFR1_TXFIFOSIZE_MASK); - hw_feat->adv_ts_hword = - ((mac_hfr1 >> 13U) & EQOS_MAC_HFR1_ADVTHWORD_MASK); - hw_feat->addr_64 = - ((mac_hfr1 >> 14U) & EQOS_MAC_HFR1_ADDR64_MASK); - hw_feat->dcb_en = - ((mac_hfr1 >> 16U) & EQOS_MAC_HFR1_DCBEN_MASK); - hw_feat->sph_en = - ((mac_hfr1 >> 17U) & EQOS_MAC_HFR1_SPHEN_MASK); - hw_feat->tso_en = - ((mac_hfr1 >> 18U) & EQOS_MAC_HFR1_TSOEN_MASK); - hw_feat->dma_debug_gen = - ((mac_hfr1 >> 19U) & EQOS_MAC_HFR1_DMADEBUGEN_MASK); - hw_feat->av_sel = - ((mac_hfr1 >> 20U) & EQOS_MAC_HFR1_AVSEL_MASK); - hw_feat->hash_tbl_sz = - ((mac_hfr1 >> 24U) & EQOS_MAC_HFR1_HASHTBLSZ_MASK); - hw_feat->l3l4_filter_num = - ((mac_hfr1 >> 27U) & EQOS_MAC_HFR1_L3L4FILTERNUM_MASK); - hw_feat->rx_q_cnt = - ((mac_hfr2 >> 0) & EQOS_MAC_HFR2_RXQCNT_MASK); - hw_feat->tx_q_cnt = - ((mac_hfr2 >> 6U) & EQOS_MAC_HFR2_TXQCNT_MASK); - hw_feat->rx_ch_cnt = - ((mac_hfr2 >> 12U) & EQOS_MAC_HFR2_RXCHCNT_MASK); - hw_feat->tx_ch_cnt = - ((mac_hfr2 >> 18U) & EQOS_MAC_HFR2_TXCHCNT_MASK); - hw_feat->pps_out_num = - ((mac_hfr2 >> 24U) & EQOS_MAC_HFR2_PPSOUTNUM_MASK); - hw_feat->aux_snap_num = - ((mac_hfr2 >> 28U) & EQOS_MAC_HFR2_AUXSNAPNUM_MASK); -} - -nve32_t common_get_mac_version(void *addr, nveu32_t *mac_ver) -{ - nveu32_t version; - nve32_t ret = 0; - - version = osi_readl((nveu8_t *)addr + MAC_VERSION) & - MAC_VERSION_SNVER_MASK; - if (is_valid_mac_version(version) == 0) { - return -1; - } - - *mac_ver = version; - return ret; -} void osi_memset(void *s, nveu32_t c, nveu64_t count) { @@ -142,7 +44,19 @@ void osi_memset(void *s, nveu32_t c, nveu64_t count) } } +void osi_memcpy(void *dest, void *src, int n) +{ + char *csrc = (char *)src; + char *cdest = (char *)dest; + int i = 0; + if (src == OSI_NULL || dest == OSI_NULL) { + return; + } + for (i = 0; i < n; i++) { + cdest[i] = csrc[i]; + } +} void common_get_systime_from_mac(void *addr, nveu32_t mac, nveu32_t *sec, nveu32_t *nsec) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 21307e8..4444522 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -43,6 +43,7 @@ static struct core_func_safety eqos_core_safety_config; * 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. @@ -55,13 +56,15 @@ static struct core_func_safety eqos_core_safety_config; * - Run time: Yes * - De-initialization: Yes */ -static inline void eqos_core_safety_writel(nveu32_t val, void *addr, - nveu32_t idx) +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_writel(val, addr); + osi_writela(osi_core, val, addr); config->reg_val[idx] = (val & config->reg_mask[idx]); osi_unlock_irq_enabled(&config->core_safety_lock); } @@ -181,7 +184,9 @@ static void eqos_core_safety_init(struct osi_core_priv_data *const osi_core) if (config->reg_addr[i] == OSI_NULL) { continue; } - val = osi_readl((nveu8_t *)config->reg_addr[i]); + + val = osi_readla(osi_core, + (nveu8_t *)config->reg_addr[i]); config->reg_val[i] = val & config->reg_mask[i]; } @@ -343,7 +348,8 @@ static nve32_t eqos_config_flow_control( /* Configure MAC Tx Flow control */ /* Read MAC Tx Flow control Register of Q0 */ - val = osi_readl((nveu8_t *)addr + EQOS_MAC_QX_TX_FLW_CTRL(0U)); + 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 @@ -360,13 +366,14 @@ static nve32_t eqos_config_flow_control( } /* Write to MAC Tx Flow control Register of Q0 */ - eqos_core_safety_writel(val, (nveu8_t *)addr + + 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_readl((nveu8_t *)addr + EQOS_MAC_RX_FLW_CTRL); + 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 @@ -380,7 +387,8 @@ static nve32_t eqos_config_flow_control( } /* Write to MAC Rx Flow control Register */ - osi_writel(val, (nveu8_t *)addr + EQOS_MAC_RX_FLW_CTRL); + osi_writela(osi_core, val, + (nveu8_t *)addr + EQOS_MAC_RX_FLW_CTRL); return 0; } @@ -427,7 +435,8 @@ static nve32_t eqos_config_fw_err_pkts( } /* Read MTL RXQ Operation_Mode Register */ - val = osi_readl((nveu8_t *)addr + EQOS_MTL_CHX_RX_OP_MODE(qinx)); + 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) { @@ -447,7 +456,7 @@ static nve32_t eqos_config_fw_err_pkts( /* 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(val, (nveu8_t *)addr + + 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); @@ -463,7 +472,6 @@ static nve32_t eqos_config_fw_err_pkts( * Waits for SWR reset to be cleared in DMA Mode register. * * @param[in] osi_core: OSI core private data structure. - * @param[in] pre_si: Sets whether platform is Pre-silicon or not. * * @pre MAC needs to be out of reset and proper clock configured. * @@ -476,17 +484,18 @@ static nve32_t eqos_config_fw_err_pkts( * @retval 0 on success * @retval -1 on failure. */ -static nve32_t eqos_poll_for_swr(struct osi_core_priv_data *const osi_core, - nve32_t pre_si) +static nve32_t eqos_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; if (pre_si == OSI_ENABLE) { - osi_writel(0x1U, (nveu8_t *)addr + EQOS_DMA_BMR); + osi_writela(osi_core, 0x1U, + (nveu32_t *)addr + EQOS_DMA_BMR); } /* add delay of 10 usec */ osi_core->osd_ops.usleep_range(9, 11); @@ -502,7 +511,9 @@ static nve32_t eqos_poll_for_swr(struct osi_core_priv_data *const osi_core, count++; - dma_bmr = osi_readl((nveu8_t *)addr + EQOS_DMA_BMR); + + dma_bmr = osi_readla(osi_core, + (nveu8_t *)addr + EQOS_DMA_BMR); if ((dma_bmr & EQOS_DMA_BMR_SWR) == 0U) { cond = 0; } else { @@ -521,7 +532,7 @@ static nve32_t eqos_poll_for_swr(struct osi_core_priv_data *const osi_core, * - Based on the speed (10/100/1000Mbps) MAC will be configured * accordingly. * - * @param[in] base: EQOS virtual base address. + * @param[in] osi_core: OSI core private data structure. * @param[in] speed: Operating speed. * * @note @@ -532,11 +543,13 @@ static nve32_t eqos_poll_for_swr(struct osi_core_priv_data *const osi_core, * * @pre MAC should be initialized and started. see osi_start_mac() */ -static void eqos_set_speed(void *base, const nve32_t speed) +static void eqos_set_speed(struct osi_core_priv_data *const osi_core, + const nve32_t speed) { - nveu32_t mcr_val; + nveu32_t mcr_val; + void *base = osi_core->base; - mcr_val = osi_readl((nveu8_t *)base + EQOS_MAC_MCR); + mcr_val = osi_readla(osi_core, (nveu8_t *)base + EQOS_MAC_MCR); switch (speed) { default: mcr_val &= ~EQOS_MCR_PS; @@ -556,7 +569,8 @@ static void eqos_set_speed(void *base, const nve32_t speed) break; } - eqos_core_safety_writel(mcr_val, (nveu8_t *)base + EQOS_MAC_MCR, + eqos_core_safety_writel(osi_core, mcr_val, + (nveu8_t *)base + EQOS_MAC_MCR, EQOS_MAC_MCR_IDX); } @@ -588,7 +602,7 @@ static nve32_t eqos_set_mode(struct osi_core_priv_data *const osi_core, void *base = osi_core->base; nveu32_t mcr_val; - mcr_val = osi_readl((nveu8_t *)base + EQOS_MAC_MCR); + 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 */ @@ -603,7 +617,8 @@ static nve32_t eqos_set_mode(struct osi_core_priv_data *const osi_core, return -1; /* Nothing here */ } - eqos_core_safety_writel(mcr_val, (nveu8_t *)base + EQOS_MAC_MCR, + eqos_core_safety_writel(osi_core, mcr_val, + (nveu8_t *)base + EQOS_MAC_MCR, EQOS_MAC_MCR_IDX); return 0; } @@ -752,9 +767,9 @@ static nve32_t eqos_pad_calibrate(struct osi_core_priv_data *const osi_core) /* 1. Set field PAD_E_INPUT_OR_E_PWRD in * reg ETHER_QOS_SDMEMCOMPPADCTRL_0 */ - value = osi_readl((nveu8_t *)ioaddr + EQOS_PAD_CRTL); + value = osi_readla(osi_core, (nveu8_t *)ioaddr + EQOS_PAD_CRTL); value |= EQOS_PAD_CRTL_E_INPUT_OR_E_PWRD; - osi_writel(value, (nveu8_t *)ioaddr + EQOS_PAD_CRTL); + osi_writela(osi_core, value, (nveu8_t *)ioaddr + EQOS_PAD_CRTL); /* 2. delay for 1 usec */ osi_core->osd_ops.usleep_range(1, 3); @@ -762,10 +777,11 @@ static nve32_t eqos_pad_calibrate(struct osi_core_priv_data *const osi_core) /* 3. Set AUTO_CAL_ENABLE and AUTO_CAL_START in * reg ETHER_QOS_AUTO_CAL_CONFIG_0. */ - value = osi_readl((nveu8_t *)ioaddr + EQOS_PAD_AUTO_CAL_CFG); + 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(value, (nveu8_t *)ioaddr + + eqos_core_safety_writel(osi_core, value, (nveu8_t *)ioaddr + EQOS_PAD_AUTO_CAL_CFG, EQOS_PAD_AUTO_CAL_CFG_IDX); @@ -782,8 +798,8 @@ static nve32_t eqos_pad_calibrate(struct osi_core_priv_data *const osi_core) } count++; osi_core->osd_ops.usleep_range(10, 12); - value = osi_readl((nveu8_t *)ioaddr + - EQOS_PAD_AUTO_CAL_STAT); + 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 = 0; @@ -794,9 +810,9 @@ calibration_failed: /* 6. Re-program the value PAD_E_INPUT_OR_E_PWRD in * ETHER_QOS_SDMEMCOMPPADCTRL_0 to save power */ - value = osi_readl((nveu8_t *)ioaddr + EQOS_PAD_CRTL); + value = osi_readla(osi_core, (nveu8_t *)ioaddr + EQOS_PAD_CRTL); value &= ~EQOS_PAD_CRTL_E_INPUT_OR_E_PWRD; - osi_writel(value, (nveu8_t *)ioaddr + EQOS_PAD_CRTL); + osi_writela(osi_core, value, (nveu8_t *)ioaddr + EQOS_PAD_CRTL); return ret; } @@ -837,10 +853,10 @@ static nve32_t eqos_flush_mtl_tx_queue( } /* Read Tx Q Operating Mode Register and flush TxQ */ - value = osi_readl((nveu8_t *)addr + - EQOS_MTL_CHX_TX_OP_MODE(qinx)); + value = osi_readla(osi_core, (nveu8_t *)addr + + EQOS_MTL_CHX_TX_OP_MODE(qinx)); value |= EQOS_MTL_QTOMR_FTQ; - eqos_core_safety_writel(value, (nveu8_t *)addr + + 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); @@ -856,8 +872,8 @@ static nve32_t eqos_flush_mtl_tx_queue( count++; osi_core->osd_ops.msleep(1); - value = osi_readl((nveu8_t *)addr + - EQOS_MTL_CHX_TX_OP_MODE(qinx)); + value = osi_readla(osi_core, (nveu8_t *)addr + + EQOS_MTL_CHX_TX_OP_MODE(qinx)); if ((value & EQOS_MTL_QTOMR_FTQ_LPOS) == 0U) { cond = 0; @@ -1017,13 +1033,13 @@ static nve32_t eqos_configure_mtl_queue(nveu32_t qinx, value |= EQOS_MTL_TSF; /* Enable TxQ */ value |= EQOS_MTL_TXQEN; - eqos_core_safety_writel(value, (nveu8_t *)osi_core->base + + 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_readl((nveu8_t *)osi_core->base + - EQOS_MTL_CHX_RX_OP_MODE(qinx)); + 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; @@ -1033,23 +1049,23 @@ static nve32_t eqos_configure_mtl_queue(nveu32_t qinx, * RFD: Threshold for Deactivating Flow Control */ update_ehfc_rfa_rfd(rx_fifo, &value); - eqos_core_safety_writel(value, (nveu8_t *)osi_core->base + + 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_readl((nveu8_t *)osi_core->base + - EQOS_MTL_TXQ_QW(qinx)); + 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(value, (nveu8_t *)osi_core->base + + 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_readl((nveu8_t *)osi_core->base + + value = osi_readla(osi_core, (nveu8_t *)osi_core->base + EQOS_MAC_RQC0R); value |= ((osi_core->rxq_ctrl[qinx] & 0x3U) << (qinx * 2U)); - eqos_core_safety_writel(value, (nveu8_t *)osi_core->base + + eqos_core_safety_writel(osi_core, value, (nveu8_t *)osi_core->base + EQOS_MAC_RQC0R, EQOS_MAC_RQC0R_IDX); return 0; @@ -1091,7 +1107,7 @@ static nve32_t eqos_config_rxcsum_offload( return -1; } - mac_mcr = osi_readl((nveu8_t *)addr + EQOS_MAC_MCR); + mac_mcr = osi_readla(osi_core, (nveu8_t *)addr + EQOS_MAC_MCR); if (enabled == OSI_ENABLE) { mac_mcr |= EQOS_MCR_IPC; @@ -1099,7 +1115,8 @@ static nve32_t eqos_config_rxcsum_offload( mac_mcr &= ~EQOS_MCR_IPC; } - eqos_core_safety_writel(mac_mcr, (nveu8_t *)addr + EQOS_MAC_MCR, + eqos_core_safety_writel(osi_core, mac_mcr, + (nveu8_t *)addr + EQOS_MAC_MCR, EQOS_MAC_MCR_IDX); return 0; @@ -1138,8 +1155,8 @@ static void eqos_configure_rxq_priority( nveu32_t mfix_var1, mfix_var2; /* make sure EQOS_MAC_RQC2R is reset before programming */ - osi_writel(OSI_DISABLE, (nveu8_t *)osi_core->base + - EQOS_MAC_RQC2R); + 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]; @@ -1157,8 +1174,8 @@ static void eqos_configure_rxq_priority( } - val = osi_readl((nveu8_t *)osi_core->base + - EQOS_MAC_RQC2R); + 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; @@ -1169,7 +1186,8 @@ static void eqos_configure_rxq_priority( mfix_var2 <<= mfix_var1; val |= (temp & mfix_var2); /* Priorities Selected in the Receive Queue 0 */ - eqos_core_safety_writel(val, (nveu8_t *)osi_core->base + + eqos_core_safety_writel(osi_core, val, + (nveu8_t *)osi_core->base + EQOS_MAC_RQC2R, EQOS_MAC_RQC2R_IDX); } } @@ -1206,7 +1224,8 @@ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) /* Update MAC address 0 high */ value = (((nveu32_t)osi_core->mac_addr[5] << 8U) | ((nveu32_t)osi_core->mac_addr[4])); - eqos_core_safety_writel(value, (nveu8_t *)osi_core->base + + eqos_core_safety_writel(osi_core, value, + (nveu8_t *)osi_core->base + EQOS_MAC_MA0HR, EQOS_MAC_MA0HR_IDX); /* Update MAC address 0 Low */ @@ -1214,11 +1233,12 @@ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) ((nveu32_t)osi_core->mac_addr[2] << 16U) | ((nveu32_t)osi_core->mac_addr[1] << 8U) | ((nveu32_t)osi_core->mac_addr[0])); - eqos_core_safety_writel(value, (nveu8_t *)osi_core->base + + eqos_core_safety_writel(osi_core, value, (nveu8_t *)osi_core->base + EQOS_MAC_MA0LR, EQOS_MAC_MA0LR_IDX); /* Read MAC Configuration Register */ - value = osi_readl((nveu8_t *)osi_core->base + EQOS_MAC_MCR); + 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 */ @@ -1235,58 +1255,63 @@ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) value |= EQOS_MCR_JD | EQOS_MCR_WD; value |= EQOS_MCR_GPSLCE; /* Read MAC Extension Register */ - mac_ext = osi_readl((nveu8_t *)osi_core->base + - EQOS_MAC_EXTR); + 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_writel(mac_ext, (nveu8_t *)osi_core->base + - EQOS_MAC_EXTR); + 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(value, (nveu8_t *)osi_core->base + + eqos_core_safety_writel(osi_core, value, (nveu8_t *)osi_core->base + EQOS_MAC_MCR, EQOS_MAC_MCR_IDX); /* Enable Multicast and Broadcast Queue, default is Q0 */ - value = osi_readl((nveu8_t *)osi_core->base + EQOS_MAC_RQC1R); + value = osi_readla(osi_core, + (nveu32_t *)osi_core->base + EQOS_MAC_RQC1R); value |= EQOS_MAC_RQC1R_MCBCQEN; /* Routing Multicast and Broadcast to Q1 */ value |= EQOS_MAC_RQC1R_MCBCQ1; - eqos_core_safety_writel(value, (nveu8_t *)osi_core->base + + 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_writel(0xFFFFFFFFU, (nveu8_t *)osi_core->base + + osi_writela(osi_core, 0xFFFFFFFFU, (nveu8_t *)osi_core->base + EQOS_MMC_TX_INTR_MASK); /* Disable all MMC RX interrupts */ - osi_writel(0xFFFFFFFFU, (nveu8_t *)osi_core->base + - EQOS_MMC_RX_INTR_MASK); + osi_writela(osi_core, 0xFFFFFFFFU, (nveu8_t *)osi_core->base + + EQOS_MMC_RX_INTR_MASK); /* Disable MMC Rx interrupts for IPC */ - osi_writel(0xFFFFFFFFU, (nveu8_t *)osi_core->base + - EQOS_MMC_IPC_RX_INTR_MASK); + osi_writela(osi_core, 0xFFFFFFFFU, (nveu8_t *)osi_core->base + + EQOS_MMC_IPC_RX_INTR_MASK); /* Configure MMC counters */ - value = osi_readl((nveu8_t *)osi_core->base + EQOS_MMC_CNTRL); + 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_writel(value, (nveu8_t *)osi_core->base + EQOS_MMC_CNTRL); + osi_writela(osi_core, value, + (nveu8_t *)osi_core->base + EQOS_MMC_CNTRL); /* Enable MAC interrupts */ /* Read MAC IMR Register */ - value = osi_readl((nveu8_t *)osi_core->base + EQOS_MAC_IMR); + 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(value, (nveu8_t *)osi_core->base + + eqos_core_safety_writel(osi_core, value, (nveu8_t *)osi_core->base + EQOS_MAC_IMR, EQOS_MAC_IMR_IDX); /* Enable VLAN configuration */ - value = osi_readl((nveu8_t *)osi_core->base + EQOS_MAC_VLAN_TAG); + 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 @@ -1298,20 +1323,23 @@ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) } value |= EQOS_MAC_VLANTR_EVLRXS | EQOS_MAC_VLANTR_DOVLTC; value &= ~EQOS_MAC_VLANTR_ERIVLT; - osi_writel(value, (nveu8_t *)osi_core->base + EQOS_MAC_VLAN_TAG); + osi_writela(osi_core, value, + (nveu8_t *)osi_core->base + EQOS_MAC_VLAN_TAG); - value = osi_readl((nveu8_t *)osi_core->base + EQOS_MAC_VLANTIR); + 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_writel(value, (nveu8_t *)osi_core->base + EQOS_MAC_VLANTIR); + 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) { + 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); @@ -1334,7 +1362,7 @@ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) * - Enable enhanced Address mode * - Programming max read outstanding request limit * - * @param[in] base: EQOS virtual base address. + * @param[in] osi_core: OSI core private data structure. * * @pre MAC has to be out of reset. * @@ -1344,9 +1372,10 @@ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) * - Run time: No * - De-initialization: No */ -static void eqos_configure_dma(void *base) +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; @@ -1359,12 +1388,13 @@ static void eqos_configure_dma(void *base) /* AXI Maximum Write Outstanding Request Limit = 31 */ value |= EQOS_DMA_SBUS_WR_OSR_LMT; - eqos_core_safety_writel(value, (nveu8_t *)base + EQOS_DMA_SBUS, + eqos_core_safety_writel(osi_core, value, + (nveu8_t *)base + EQOS_DMA_SBUS, EQOS_DMA_SBUS_IDX); - value = osi_readl((nveu8_t *)base + EQOS_DMA_BMR); + value = osi_readla(osi_core, (nveu8_t *)base + EQOS_DMA_BMR); value |= EQOS_DMA_BMR_DPSW; - osi_writel(value, (nveu8_t *)base + EQOS_DMA_BMR); + osi_writela(osi_core, value, (nveu8_t *)base + EQOS_DMA_BMR); } /** @@ -1417,18 +1447,18 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core, } /* reset mmc counters */ - osi_writel(EQOS_MMC_CNTRL_CNTRST, (nveu8_t *)osi_core->base + - EQOS_MMC_CNTRL); + osi_writela(osi_core, EQOS_MMC_CNTRL_CNTRST, + (nveu8_t *)osi_core->base + EQOS_MMC_CNTRL); /* AXI ASID CTRL for channel 0 to 3 */ - osi_writel(EQOS_AXI_ASID_CTRL_VAL, - (nveu8_t *)osi_core->base + EQOS_AXI_ASID_CTRL); + 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_writel(EQOS_AXI_ASID1_CTRL_VAL, - (nveu8_t *)osi_core->base + - EQOS_AXI_ASID1_CTRL); + 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 */ @@ -1439,7 +1469,7 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core, value = EQOS_RXQ_TO_DMA_CHAN_MAP; } - eqos_core_safety_writel(value, (nveu8_t *)osi_core->base + + eqos_core_safety_writel(osi_core, value, (nveu8_t *)osi_core->base + EQOS_MTL_RXQ_DMA_MAP0, EQOS_MTL_RXQ_DMA_MAP0_IDX); @@ -1475,7 +1505,7 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core, eqos_configure_mac(osi_core); /* configure EQOS DMA */ - eqos_configure_dma(osi_core->base); + eqos_configure_dma(osi_core); /* initialize L3L4 Filters variable */ osi_core->l3l4_filter_bitmask = OSI_NONE; @@ -1510,7 +1540,8 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, nveu32_t mac_isr = 0; nve32_t ret = 0; - mac_isr = osi_readl((nveu8_t *)osi_core->base + EQOS_MAC_ISR); + mac_isr = osi_readla(osi_core, + (nveu8_t *)osi_core->base + EQOS_MAC_ISR); /* Handle MAC interrupts */ if ((dma_isr & EQOS_DMA_ISR_MACIS) != EQOS_DMA_ISR_MACIS) { @@ -1518,14 +1549,16 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, } /* handle only those MAC interrupts which are enabled */ - mac_imr = osi_readl((nveu8_t *)osi_core->base + EQOS_MAC_IMR); + 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) { return; } - mac_pcs = osi_readl((nveu8_t *)osi_core->base + EQOS_MAC_PCS); + 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; @@ -1550,13 +1583,13 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, /* 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->base, OSI_SPEED_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->base, OSI_SPEED_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->base, OSI_SPEED_1000); + eqos_set_speed(osi_core, OSI_SPEED_1000); } else { /* Nothing here */ } @@ -1643,7 +1676,7 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *const osi_core) nveu32_t dma_sr = 0; nveu32_t dma_ier = 0; - dma_isr = osi_readl((nveu8_t *)base + EQOS_DMA_ISR); + dma_isr = osi_readla(osi_core, (nveu8_t *)base + EQOS_DMA_ISR); if (dma_isr == 0U) { return; } @@ -1659,11 +1692,11 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *const osi_core) } /* read dma channel status register */ - dma_sr = osi_readl((nveu8_t *)base + - EQOS_DMA_CHX_STATUS(qinx)); + dma_sr = osi_readla(osi_core, (nveu8_t *)base + + EQOS_DMA_CHX_STATUS(qinx)); /* read dma channel interrupt enable register */ - dma_ier = osi_readl((nveu8_t *)base + - EQOS_DMA_CHX_IER(qinx)); + dma_ier = osi_readla(osi_core, (nveu8_t *)base + + EQOS_DMA_CHX_IER(qinx)); /* process only those interrupts which we * have enabled. @@ -1677,8 +1710,8 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *const osi_core) } /* ack non ti/ri ints */ - osi_writel(dma_sr, (nveu8_t *)base + - EQOS_DMA_CHX_STATUS(qinx)); + osi_writela(osi_core, dma_sr, (nveu8_t *)base + + EQOS_DMA_CHX_STATUS(qinx)); update_dma_sr_stats(osi_core, dma_sr, qinx); } } @@ -1693,7 +1726,7 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *const osi_core) * Algorithm: * - Enable MAC Transmitter and Receiver * - * @param[in] addr: EQOS virtual base address. + * @param[in] osi_core: OSI core private data structure. * * @pre * - MAC init should be complete. See osi_hw_core_init() and @@ -1705,15 +1738,17 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *const osi_core) * - Run time: No * - De-initialization: No */ -static void eqos_start_mac(void *addr) +static void eqos_start_mac(struct osi_core_priv_data *const osi_core) { nveu32_t value; + void *addr = osi_core->base; - value = osi_readl((nveu8_t *)addr + EQOS_MAC_MCR); + 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(value, (nveu8_t *)addr + EQOS_MAC_MCR, + eqos_core_safety_writel(osi_core, value, + (nveu8_t *)addr + EQOS_MAC_MCR, EQOS_MAC_MCR_IDX); } @@ -1724,7 +1759,7 @@ static void eqos_start_mac(void *addr) * Algorithm: * - Disables MAC Transmitter and Receiver * - * @param[in] addr: EQOS virtual base address. + * @param[in] osi_core: OSI core private data structure. * * @pre MAC DMA deinit should be complete. See osi_hw_dma_deinit() * @@ -1734,16 +1769,18 @@ static void eqos_start_mac(void *addr) * - Run time: No * - De-initialization: Yes */ -static void eqos_stop_mac(void *addr) +static void eqos_stop_mac(struct osi_core_priv_data *const osi_core) { nveu32_t value; + void *addr = osi_core->base; - value = osi_readl((nveu8_t *)addr + EQOS_MAC_MCR); + 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(value, (nveu8_t *)addr + EQOS_MAC_MCR, + eqos_core_safety_writel(osi_core, value, + (nveu8_t *)addr + EQOS_MAC_MCR, EQOS_MAC_MCR_IDX); } @@ -1756,7 +1793,7 @@ static void eqos_stop_mac(void *addr) * - This sequence is used to select perfect/inverse matching * for L2 DA * - * @param[in] base: Base address from OSI core private data structure. + * @param[in] osi_core: OSI core private data structure. * @param[in] perfect_inverse_match: 1 - inverse mode 0- perfect mode * * @pre MAC should be initialized and started. see osi_start_mac() @@ -1769,18 +1806,20 @@ static void eqos_stop_mac(void *addr) * * @retval 0 always */ -static inline nve32_t eqos_config_l2_da_perfect_inverse_match(void *base, - nveu32_t - perfect_inverse_match) +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_readl((nveu8_t *)base + EQOS_MAC_PFR); + 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(value, (nveu8_t *)base + EQOS_MAC_PFR, + eqos_core_safety_writel(osi_core, value, + (nveu8_t *)osi_core->base + EQOS_MAC_PFR, EQOS_MAC_PFR_IDX); return 0; @@ -1815,7 +1854,8 @@ static nve32_t eqos_config_mac_pkt_filter_reg( nveu32_t value = 0U; nve32_t ret = 0; - value = osi_readl((nveu8_t *)osi_core->base + EQOS_MAC_PFR); + 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 | @@ -1846,16 +1886,16 @@ static nve32_t eqos_config_mac_pkt_filter_reg( } - eqos_core_safety_writel(value, (nveu8_t *)osi_core->base + - EQOS_MAC_PFR, EQOS_MAC_PFR_IDX); + 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) != 0x0U) { - ret = eqos_config_l2_da_perfect_inverse_match(osi_core->base, + ret = eqos_config_l2_da_perfect_inverse_match(osi_core, OSI_INV_MATCH); } if ((filter->oper_mode & OSI_OPER_DIS_L2_DA_INV) != 0x0U) { - ret = eqos_config_l2_da_perfect_inverse_match(osi_core->base, + ret = eqos_config_l2_da_perfect_inverse_match(osi_core, OSI_PFT_MATCH); } @@ -1980,7 +2020,6 @@ static nve32_t eqos_update_mac_addr_low_high_reg( 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 value = 0x0U; nve32_t ret = 0; @@ -1990,16 +2029,6 @@ static nve32_t eqos_update_mac_addr_low_high_reg( return -1; } - /* High address clean should happen for filter index >= 0 */ - if (addr == OSI_NULL) { - value = osi_readl((nveu8_t *)osi_core->base + - EQOS_MAC_ADDRH((idx))); - value &= ~EQOS_MAC_ADDRH_AE; - osi_writel(value, (nveu8_t *)osi_core->base + - EQOS_MAC_ADDRH((idx))); - return 0; - } - ret = eqos_update_mac_addr_helper(osi_core, &value, idx, dma_routing_enable, dma_chan, addr_mask); @@ -2021,14 +2050,15 @@ static nve32_t eqos_update_mac_addr_low_high_reg( value |= EQOS_MAC_ADDRH_AE; } - osi_writel(((nveu32_t)addr[4] | - ((nveu32_t)addr[5] << 8) | value), - (nveu8_t *)osi_core->base + EQOS_MAC_ADDRH((idx))); + 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_writel(((nveu32_t)addr[0] | ((nveu32_t)addr[1] << 8) | - ((nveu32_t)addr[2] << 16) | - ((nveu32_t)addr[3] << 24)), - (nveu8_t *)osi_core->base + EQOS_MAC_ADDRL((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; } @@ -2055,15 +2085,16 @@ static nve32_t eqos_update_mac_addr_low_high_reg( * @retval 0 on success * @retval -1 on failure. */ -static nve32_t eqos_config_l3_l4_filter_enable(void *base, - const nveu32_t filter_enb_dis) +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; - - value = osi_readl((nveu8_t *)base + EQOS_MAC_PFR); + 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 << 20) & EQOS_MAC_PFR_IPFE); - eqos_core_safety_writel(value, (nveu8_t *)base + EQOS_MAC_PFR, + eqos_core_safety_writel(osi_core, value, (nveu8_t *)base + EQOS_MAC_PFR, EQOS_MAC_PFR_IDX); return 0; @@ -2123,11 +2154,11 @@ static nve32_t eqos_update_ip4_addr(struct osi_core_priv_data *const osi_core, temp = (nveu32_t)addr[0] << 24; value |= temp; if (src_dst_addr_match == OSI_SOURCE_MATCH) { - osi_writel(value, (nveu8_t *)base + - EQOS_MAC_L3_AD0R(filter_no)); + osi_writela(osi_core, value, (nveu8_t *)base + + EQOS_MAC_L3_AD0R(filter_no)); } else { - osi_writel(value, (nveu8_t *)base + - EQOS_MAC_L3_AD1R(filter_no)); + osi_writela(osi_core, value, (nveu8_t *)base + + EQOS_MAC_L3_AD1R(filter_no)); } return 0; @@ -2181,26 +2212,26 @@ static nve32_t eqos_update_ip6_addr(struct osi_core_priv_data *const osi_core, value = addr[7]; temp = (nveu32_t)addr[6] << 16; value |= temp; - osi_writel(value, (nveu8_t *)base + + 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_writel(value, (nveu8_t *)base + + 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_writel(value, (nveu8_t *)base + - EQOS_MAC_L3_AD2R(filter_no)); + 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_writel(value, (nveu8_t *)base + - EQOS_MAC_L3_AD3R(filter_no)); + osi_writela(osi_core, value, (nveu8_t *)base + + EQOS_MAC_L3_AD3R(filter_no)); return 0; } @@ -2249,7 +2280,8 @@ static nve32_t eqos_update_l4_port_no( return -1; } - value = osi_readl((nveu8_t *)base + EQOS_MAC_L4_ADR(filter_no)); + 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); @@ -2258,7 +2290,8 @@ static nve32_t eqos_update_l4_port_no( temp = port_no; value |= ((temp << EQOS_MAC_L4_DP_SHIFT) & EQOS_MAC_L4_DP_MASK); } - osi_writel(value, (nveu8_t *)base + EQOS_MAC_L4_ADR(filter_no)); + osi_writela(osi_core, value, + (nveu8_t *)base + EQOS_MAC_L4_ADR(filter_no)); return 0; } @@ -2411,12 +2444,12 @@ static nve32_t eqos_config_l3_filters( return -1; } - value = osi_readl((nveu8_t *)base + + 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_writel(value, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); + 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) { @@ -2425,7 +2458,7 @@ static nve32_t eqos_config_l3_filters( /* Enable L3 filters for IPv6 SOURCE addr * matching */ - value = osi_readl((nveu8_t *)base + + 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 | @@ -2436,15 +2469,15 @@ static nve32_t eqos_config_l3_filters( value |= eqos_set_dcs(osi_core, value, dma_routing_enable, dma_chan); - osi_writel(value, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); + 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_readl((nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); + 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 << @@ -2454,18 +2487,18 @@ static nve32_t eqos_config_l3_filters( value |= eqos_set_dcs(osi_core, value, dma_routing_enable, dma_chan); - osi_writel(value, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); + 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_readl((nveu8_t *)base + + 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_writel(value, (nveu8_t *)base + + osi_writela(osi_core, value, (nveu8_t *)base + EQOS_MAC_L3L4_CTR(filter_no)); } } else { @@ -2474,8 +2507,8 @@ static nve32_t eqos_config_l3_filters( /* Enable L3 filters for IPv4 SOURCE addr * matching */ - value = osi_readl((nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); + 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 << @@ -2485,25 +2518,25 @@ static nve32_t eqos_config_l3_filters( value |= eqos_set_dcs(osi_core, value, dma_routing_enable, dma_chan); - osi_writel(value, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); + 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_readl((nveu8_t *)base + + value = osi_readla(osi_core, (nveu8_t *)base + EQOS_MAC_L3L4_CTR(filter_no)); value &= ~EQOS_MAC_L3_IP4_SA_CTRL_CLEAR; - osi_writel(value, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); + 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_readl((nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); + 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 << @@ -2513,17 +2546,17 @@ static nve32_t eqos_config_l3_filters( value |= eqos_set_dcs(osi_core, value, dma_routing_enable, dma_chan); - osi_writel(value, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); + 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_readl((nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); + value = osi_readla(osi_core, (nveu8_t *)base + + EQOS_MAC_L3L4_CTR(filter_no)); value &= ~EQOS_MAC_L3_IP4_DA_CTRL_CLEAR; - osi_writel(value, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); + osi_writela(osi_core, value, (nveu8_t *)base + + EQOS_MAC_L3L4_CTR(filter_no)); } } } @@ -2592,17 +2625,18 @@ static nve32_t eqos_config_l4_filters( return -1; } - value = osi_readl((nveu8_t *)base + EQOS_MAC_L3L4_CTR(filter_no)); + value = osi_readla(osi_core, (nveu8_t *)base + + EQOS_MAC_L3L4_CTR(filter_no)); value &= ~EQOS_MAC_L3L4_CTR_L4PEN0; value |= ((tcp_udp_match << 16) & EQOS_MAC_L3L4_CTR_L4PEN0); - osi_writel(value, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); + 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_readl((nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); + 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 << @@ -2612,23 +2646,23 @@ static nve32_t eqos_config_l4_filters( value |= eqos_set_dcs(osi_core, value, dma_routing_enable, dma_chan); - osi_writel(value, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); + 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_readl((nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); + value = osi_readla(osi_core, (nveu8_t *)base + + EQOS_MAC_L3L4_CTR(filter_no)); value &= ~EQOS_MAC_L4_SP_CTRL_CLEAR; - osi_writel(value, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); + 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_readl((nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); + 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 << @@ -2638,17 +2672,17 @@ static nve32_t eqos_config_l4_filters( value |= eqos_set_dcs(osi_core, value, dma_routing_enable, dma_chan); - osi_writel(value, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); + 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_readl((nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); + value = osi_readla(osi_core, (nveu8_t *)base + + EQOS_MAC_L3L4_CTR(filter_no)); value &= ~EQOS_MAC_L4_DP_CTRL_CLEAR; - osi_writel(value, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); + 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 */ @@ -2685,7 +2719,6 @@ static inline nve32_t eqos_poll_for_tsinit_complete( struct osi_core_priv_data *const osi_core, nveu32_t *mac_tcr) { - void *addr = osi_core->base; nveu32_t retry = 1000; nveu32_t count; nve32_t cond = 1; @@ -2701,7 +2734,8 @@ static inline nve32_t eqos_poll_for_tsinit_complete( return -1; } /* Read and Check TSINIT in MAC_Timestamp_Control register */ - *mac_tcr = osi_readl((nveu8_t *)addr + EQOS_MAC_TCR); + *mac_tcr = osi_readla(osi_core, (nveu8_t *)osi_core->base + + EQOS_MAC_TCR); if ((*mac_tcr & EQOS_MAC_TCR_TSINIT) == 0U) { cond = 0; } @@ -2750,16 +2784,17 @@ static nve32_t eqos_set_systime_to_mac( } /* write seconds value to MAC_System_Time_Seconds_Update register */ - osi_writel(sec, (nveu8_t *)addr + EQOS_MAC_STSUR); + osi_writela(osi_core, sec, (nveu8_t *)addr + EQOS_MAC_STSUR); /* write nano seconds value to MAC_System_Time_Nanoseconds_Update * register */ - osi_writel(nsec, (nveu8_t *)addr + EQOS_MAC_STNSUR); + 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(mac_tcr, (nveu8_t *)addr + EQOS_MAC_TCR, + 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); @@ -2797,7 +2832,6 @@ static inline nve32_t eqos_poll_for_addend_complete( struct osi_core_priv_data *const osi_core, nveu32_t *mac_tcr) { - void *addr = osi_core->base; nveu32_t retry = 1000; nveu32_t count; nve32_t cond = 1; @@ -2812,7 +2846,8 @@ static inline nve32_t eqos_poll_for_addend_complete( return -1; } /* Read and Check TSADDREG in MAC_Timestamp_Control register */ - *mac_tcr = osi_readl((nveu8_t *)addr + EQOS_MAC_TCR); + *mac_tcr = osi_readla(osi_core, + (nveu8_t *)osi_core->base + EQOS_MAC_TCR); if ((*mac_tcr & EQOS_MAC_TCR_TSADDREG) == 0U) { cond = 0; } @@ -2847,7 +2882,6 @@ static inline nve32_t eqos_poll_for_addend_complete( static nve32_t eqos_config_addend(struct osi_core_priv_data *const osi_core, const nveu32_t addend) { - void *addr = osi_core->base; nveu32_t mac_tcr; nve32_t ret; @@ -2857,12 +2891,14 @@ static nve32_t eqos_config_addend(struct osi_core_priv_data *const osi_core, } /* write addend value to MAC_Timestamp_Addend register */ - eqos_core_safety_writel(addend, (nveu8_t *)addr + EQOS_MAC_TAR, + 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(mac_tcr, (nveu8_t *)addr + EQOS_MAC_TCR, + 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); @@ -2900,7 +2936,6 @@ static inline nve32_t eqos_poll_for_update_ts_complete( struct osi_core_priv_data *const osi_core, nveu32_t *mac_tcr) { - void *addr = osi_core->base; nveu32_t retry = 1000; nveu32_t count; nve32_t cond = 1; @@ -2914,7 +2949,8 @@ static inline nve32_t eqos_poll_for_update_ts_complete( return -1; } /* Read and Check TSUPDT in MAC_Timestamp_Control register */ - *mac_tcr = osi_readl((nveu8_t *)addr + EQOS_MAC_TCR); + *mac_tcr = osi_readla(osi_core, (nveu8_t *)osi_core->base + + EQOS_MAC_TCR); if ((*mac_tcr & EQOS_MAC_TCR_TSUPDT) == 0U) { cond = 0; } @@ -3000,20 +3036,21 @@ static nve32_t eqos_adjust_mactime(struct osi_core_priv_data *const osi_core, } /* write seconds value to MAC_System_Time_Seconds_Update register */ - osi_writel(sec1, (nveu8_t *)addr + EQOS_MAC_STSUR); + osi_writela(osi_core, sec, (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_writel(value, (nveu8_t *)addr + EQOS_MAC_STNSUR); + 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(mac_tcr, (nveu8_t *)addr + EQOS_MAC_TCR, + 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); @@ -3027,8 +3064,7 @@ static nve32_t eqos_adjust_mactime(struct osi_core_priv_data *const osi_core, /** * @brief eqos_config_tscr - Configure Time Stamp Register * - * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. + * @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() @@ -3039,14 +3075,16 @@ static nve32_t eqos_adjust_mactime(struct osi_core_priv_data *const osi_core, * - Run time: Yes * - De-initialization: No */ -static void eqos_config_tscr(void *addr, const nveu32_t ptp_filter) +static void eqos_config_tscr(struct osi_core_priv_data *const osi_core, + const nveu32_t ptp_filter) { + void *addr = osi_core->base; nveu32_t mac_tcr = 0U, i = 0U, temp = 0U; if (ptp_filter == OSI_DISABLE) { /* Disabling the MAC time stamping */ mac_tcr = OSI_DISABLE; - eqos_core_safety_writel(mac_tcr, + eqos_core_safety_writel(osi_core, mac_tcr, (nveu8_t *)addr + EQOS_MAC_TCR, EQOS_MAC_TCR_IDX); return; @@ -3097,7 +3135,8 @@ static void eqos_config_tscr(void *addr, const nveu32_t ptp_filter) } } - eqos_core_safety_writel(mac_tcr, (nveu8_t *)addr + EQOS_MAC_TCR, + eqos_core_safety_writel(osi_core, mac_tcr, + (nveu8_t *)addr + EQOS_MAC_TCR, EQOS_MAC_TCR_IDX); } @@ -3121,7 +3160,7 @@ static void eqos_config_ssir(struct osi_core_priv_data *const osi_core) void *addr = osi_core->base; nveu32_t ptp_clock = osi_core->ptp_config.ptp_clock; - mac_tcr = osi_readl((nveu8_t *)addr + EQOS_MAC_TCR); + mac_tcr = osi_readla(osi_core, (nveu8_t *)addr + EQOS_MAC_TCR); if ((mac_tcr & EQOS_MAC_TCR_TSCFUPDT) == EQOS_MAC_TCR_TSCFUPDT) { @@ -3148,7 +3187,7 @@ static void eqos_config_ssir(struct osi_core_priv_data *const osi_core) val |= val << EQOS_MAC_SSIR_SSINC_SHIFT; /* update Sub-second Increment Value */ if (val < UINT_MAX) { - eqos_core_safety_writel((nveu32_t)val, + eqos_core_safety_writel(osi_core, (nveu32_t)val, (nveu8_t *)addr + EQOS_MAC_SSIR, EQOS_MAC_SSIR_IDX); } @@ -3174,7 +3213,7 @@ static void eqos_config_ssir(struct osi_core_priv_data *const osi_core) 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->base); + eqos_stop_mac(osi_core); } /** @@ -3210,8 +3249,8 @@ static inline nve32_t poll_for_mii_idle(struct osi_core_priv_data *osi_core) } count++; - mac_gmiiar = osi_readl((nveu8_t *)osi_core->base + - EQOS_MAC_MDIO_ADDRESS); + 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 = 0; @@ -3270,13 +3309,13 @@ static nve32_t eqos_write_phy_reg(struct osi_core_priv_data *const osi_core, return ret; } - mac_gmiidr = osi_readl((nveu8_t *)osi_core->base + - EQOS_MAC_MDIO_DATA); + 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_writel(mac_gmiidr, (nveu8_t *)osi_core->base + - EQOS_MAC_MDIO_DATA); + 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) */ @@ -3284,8 +3323,8 @@ static nve32_t eqos_write_phy_reg(struct osi_core_priv_data *const osi_core, /* CSR Clock Range (20 - 35MHz) */ /* Select write operation */ /* set busy bit */ - mac_gmiiar = osi_readl((nveu8_t *)osi_core->base + - EQOS_MAC_MDIO_ADDRESS); + 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) | @@ -3293,8 +3332,8 @@ static nve32_t eqos_write_phy_reg(struct osi_core_priv_data *const osi_core, ((osi_core->mdc_cr) << EQOS_MDIO_PHY_REG_CR_SHIF) | (EQOS_MDIO_PHY_REG_WRITE) | EQOS_MAC_GMII_BUSY); - osi_writel(mac_gmiiar, (nveu8_t *)osi_core->base + - EQOS_MAC_MDIO_ADDRESS); + 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); @@ -3351,8 +3390,8 @@ static nve32_t eqos_read_phy_reg(struct osi_core_priv_data *const osi_core, return ret; } - mac_gmiiar = osi_readl((nveu8_t *)osi_core->base + - EQOS_MAC_MDIO_ADDRESS); + 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 */ @@ -3365,8 +3404,8 @@ static nve32_t eqos_read_phy_reg(struct osi_core_priv_data *const osi_core, ((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_writel(mac_gmiiar, (nveu8_t *)osi_core->base + - EQOS_MAC_MDIO_ADDRESS); + 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); @@ -3375,13 +3414,52 @@ static nve32_t eqos_read_phy_reg(struct osi_core_priv_data *const osi_core, return ret; } - mac_gmiidr = osi_readl((nveu8_t *)osi_core->base + - EQOS_MAC_MDIO_DATA); + 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; +} + #ifndef OSI_STRIPPED_LIB /** * @brief eqos_disable_tx_lpi - Helper function to disable Tx LPI. @@ -3391,7 +3469,7 @@ static nve32_t eqos_read_phy_reg(struct osi_core_priv_data *const osi_core, * - 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] addr: base address of memory mapped register space of MAC. + * @param[in] osi_core: OSI core private data structure. * * @pre MAC has to be out of reset, and clocks supplied. * @@ -3401,15 +3479,19 @@ static nve32_t eqos_read_phy_reg(struct osi_core_priv_data *const osi_core, * - Run time: Yes * - De-initialization: No */ -static inline void eqos_disable_tx_lpi(void *addr) +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_readl((nveu8_t *)addr + EQOS_MAC_LPI_CSR); + 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_writel(lpi_csr, (nveu8_t *)addr + EQOS_MAC_LPI_CSR); + osi_writela(osi_core, lpi_csr, + (nveu8_t *)addr + EQOS_MAC_LPI_CSR); } /** @@ -3451,7 +3533,8 @@ static nve32_t eqos_validate_core_regs( if (config->reg_addr[i] == OSI_NULL) { continue; } - cur_val = osi_readl((nveu8_t *)config->reg_addr[i]); + 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]) { @@ -3510,7 +3593,7 @@ static nve32_t eqos_config_rx_crc_check( } /* Read MAC Extension Register */ - val = osi_readl((nveu8_t *)addr + EQOS_MAC_EXTR); + 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) { @@ -3524,7 +3607,7 @@ static nve32_t eqos_config_rx_crc_check( } /* Write to MAC Extension Register */ - osi_writel(val, (nveu8_t *)addr + EQOS_MAC_EXTR); + osi_writela(osi_core, val, (nveu8_t *)addr + EQOS_MAC_EXTR); return 0; } @@ -3567,7 +3650,7 @@ static nve32_t eqos_config_tx_status(struct osi_core_priv_data *const osi_core, } /* Read MTL Operation Mode Register */ - val = osi_readl((nveu8_t *)addr + EQOS_MTL_OP_MODE); + 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 @@ -3586,7 +3669,7 @@ static nve32_t eqos_config_tx_status(struct osi_core_priv_data *const osi_core, /* Write to DTXSTS bit of MTL Operation Mode Register to enable or * disable the Tx packet status */ - osi_writel(val, (nveu8_t *)addr + EQOS_MTL_OP_MODE); + osi_writela(osi_core, val, (nveu8_t *)addr + EQOS_MTL_OP_MODE); return 0; } @@ -3659,13 +3742,13 @@ static nve32_t eqos_set_avb_algorithm( } qinx = avb->qindex; - value = osi_readl((nveu8_t *)osi_core->base + - EQOS_MTL_CHX_TX_OP_MODE(qinx)); + 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(value, (nveu8_t *)osi_core->base + + 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); @@ -3676,35 +3759,36 @@ static nve32_t eqos_set_avb_algorithm( } value |= (avb->algo << EQOS_MTL_TXQ_ETS_CR_AVALG_SHIFT) & EQOS_MTL_TXQ_ETS_CR_AVALG; - osi_writel(value, (nveu8_t *)osi_core->base + - EQOS_MTL_TXQ_ETS_CR(qinx)); + 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_writel(value, (nveu8_t *)osi_core->base + - EQOS_MTL_TXQ_ETS_SSCR(qinx)); + osi_writela(osi_core, value, (nveu8_t *)osi_core->base + + EQOS_MTL_TXQ_ETS_SSCR(qinx)); /* Set Idle slope credit*/ - value = osi_readl((nveu8_t *)osi_core->base + - EQOS_MTL_TXQ_QW(qinx)); + 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(value, (nveu8_t *)osi_core->base + + 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_writel(value, (nveu8_t *)osi_core->base + - EQOS_MTL_TXQ_ETS_HCR(qinx)); + 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_writel(value, (nveu8_t *)osi_core->base + - EQOS_MTL_TXQ_ETS_LCR(qinx)); + osi_writela(osi_core, value, (nveu8_t *)osi_core->base + + EQOS_MTL_TXQ_ETS_LCR(qinx)); } return 0; @@ -3761,41 +3845,41 @@ static nve32_t eqos_get_avb_algorithm(struct osi_core_priv_data *const osi_core, } qinx = avb->qindex; - value = osi_readl((nveu8_t *)osi_core->base + - EQOS_MTL_CHX_TX_OP_MODE(qinx)); + 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_readl((nveu8_t *)osi_core->base + - EQOS_MTL_TXQ_ETS_CR(qinx)); + 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_readl((nveu8_t *)osi_core->base + - EQOS_MTL_TXQ_ETS_SSCR(qinx)); + 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_readl((nveu8_t *)osi_core->base + - EQOS_MTL_TXQ_QW(qinx)); + 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_readl((nveu8_t *)osi_core->base + - EQOS_MTL_TXQ_ETS_HCR(qinx)); + 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_readl((nveu8_t *)osi_core->base + - EQOS_MTL_TXQ_ETS_LCR(qinx)); + 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; @@ -3811,8 +3895,6 @@ static nve32_t eqos_get_avb_algorithm(struct osi_core_priv_data *const osi_core, * ARPPA register * - Enable/disable the ARPEN bit in MCR and write back to the MCR. * - * @param[in] mac_ver: MAC version number (different MAC HW version - * need different register offset/fields for ARP offload. * @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. @@ -3831,14 +3913,15 @@ static nve32_t eqos_get_avb_algorithm(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -static nve32_t eqos_config_arp_offload(const nveu32_t mac_ver, - struct osi_core_priv_data *const osi_core, - const nveu32_t enable, - const nveu8_t *ip_addr) +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_mcr; - nveu32_t val; + nve32_t mac_ver = osi_core->mac_ver; + nve32_t mac_mcr; + nve32_t val; if (enable != OSI_ENABLE && enable != OSI_DISABLE) { OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, @@ -3846,7 +3929,7 @@ static nve32_t eqos_config_arp_offload(const nveu32_t mac_ver, return -1; } - mac_mcr = osi_readl((nveu8_t *)addr + EQOS_MAC_MCR); + mac_mcr = osi_readla(osi_core, (nveu8_t *)addr + EQOS_MAC_MCR); if (enable == OSI_ENABLE) { val = (((nveu32_t)ip_addr[0]) << 24) | @@ -3855,11 +3938,11 @@ static nve32_t eqos_config_arp_offload(const nveu32_t mac_ver, (((nveu32_t)ip_addr[3])); if (mac_ver == OSI_EQOS_MAC_4_10) { - osi_writel(val, (nveu8_t *)addr + - EQOS_4_10_MAC_ARPPA); + osi_writela(osi_core, val, (nveu8_t *)addr + + EQOS_4_10_MAC_ARPPA); } else if (mac_ver == OSI_EQOS_MAC_5_00) { - osi_writel(val, (nveu8_t *)addr + - EQOS_5_00_MAC_ARPPA); + 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, @@ -3872,7 +3955,8 @@ static nve32_t eqos_config_arp_offload(const nveu32_t mac_ver, mac_mcr &= ~EQOS_MCR_ARPEN; } - eqos_core_safety_writel(mac_mcr, (nveu8_t *)addr + EQOS_MAC_MCR, + eqos_core_safety_writel(osi_core, mac_mcr, + (nveu8_t *)addr + EQOS_MAC_MCR, EQOS_MAC_MCR_IDX); return 0; @@ -3933,13 +4017,13 @@ static nve32_t eqos_config_vlan_filtering( return -1; } - value = osi_readl((nveu8_t *)base + EQOS_MAC_PFR); + 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(value, (nveu8_t *)base + EQOS_MAC_PFR, + eqos_core_safety_writel(osi_core, value, (nveu8_t *)base + EQOS_MAC_PFR, EQOS_MAC_PFR_IDX); - value = osi_readl((nveu8_t *)base + EQOS_MAC_VLAN_TR); + 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); @@ -3948,14 +4032,15 @@ static nve32_t eqos_config_vlan_filtering( "VLAN hash filter is not supported, no update of VTHM\n", 0ULL); } - osi_writel(value, (nveu8_t *)base + EQOS_MAC_VLAN_TR); + + osi_writela(osi_core, value, (nveu8_t *)base + EQOS_MAC_VLAN_TR); return 0; } /** * @brief eqos_update_vlan_id - update VLAN ID in Tag register * - * @param[in] base: Base address from OSI core private data structure. + * @param[in] osi_core: OSI core priv data structure * @param[in] vid: VLAN ID to be programmed. * * @note @@ -3966,7 +4051,9 @@ static nve32_t eqos_config_vlan_filtering( * * @retval 0 always */ -static inline nve32_t eqos_update_vlan_id(void *base, nveu32_t vid) +static inline nve32_t eqos_update_vlan_id( + struct osi_core_priv_data *const osi_core, + nveu32_t vid) { /* Don't add VLAN ID to TR register which is eventually set TR * to 0x0 and allow all tagged packets @@ -4030,11 +4117,13 @@ static void eqos_configure_eee(struct osi_core_priv_data *const osi_core, OSI_LPI_LS_TIMER_SHIFT); lpi_timer_ctrl |= (OSI_DEFAULT_LPI_TW_TIMER & OSI_LPI_TW_TIMER_MASK); - osi_writel(lpi_timer_ctrl, addr + EQOS_MAC_LPI_TIMER_CTRL); + 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_writel(lpi_entry_timer, addr + EQOS_MAC_LPI_EN_TIMER); + 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 */ @@ -4043,21 +4132,22 @@ static void eqos_configure_eee(struct osi_core_priv_data *const osi_core, lpi_1US_tic_counter = ((osi_core->csr_clk_speed - 1U) & OSI_LPI_1US_TIC_COUNTER_MASK); } - osi_writel(lpi_1US_tic_counter, addr + EQOS_MAC_1US_TIC_CNTR); + 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_readl(addr + EQOS_MAC_LPI_CSR); + 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_writel(lpi_csr, addr + EQOS_MAC_LPI_CSR); + osi_writela(osi_core, lpi_csr, addr + EQOS_MAC_LPI_CSR); } else { /* Disable LPI control bits */ - eqos_disable_tx_lpi(osi_core->base); + eqos_disable_tx_lpi(osi_core); } } @@ -4087,7 +4177,8 @@ static inline nve32_t eqos_save_registers( for (i = 0; i < EQOS_MAX_BAK_IDX; i++) { if (config->reg_addr[i] != OSI_NULL) { - config->reg_val[i] = osi_readl(config->reg_addr[i]); + config->reg_val[i] = osi_readla(osi_core, + config->reg_addr[i]); } } @@ -4120,7 +4211,8 @@ static inline nve32_t eqos_restore_registers( for (i = 0; i < EQOS_MAX_BAK_IDX; i++) { if (config->reg_addr[i] != OSI_NULL) { - osi_writel(config->reg_val[i], config->reg_addr[i]); + osi_writela(osi_core, config->reg_val[i], + config->reg_addr[i]); } } @@ -4181,8 +4273,7 @@ static void eqos_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, /** * @brief eqos_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] 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() @@ -4196,11 +4287,13 @@ static void eqos_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -static nve32_t eqos_config_mac_loopback(void *addr, - const nveu32_t lb_mode) +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; /* don't allow only if loopback mode is other than 0 or 1 */ if (lb_mode != OSI_ENABLE && lb_mode != OSI_DISABLE) { @@ -4208,10 +4301,11 @@ static nve32_t eqos_config_mac_loopback(void *addr, } /* Read MAC Configuration Register */ - mcr_val = osi_readl((nveu8_t *)addr + EQOS_MAC_MCR); + mcr_val = osi_readla(osi_core, (nveu32_t *)addr + EQOS_MAC_MCR); /* Read EQOS wrapper clock control 0 register */ - clk_ctrl_val = osi_readl((nveu8_t *)addr + EQOS_CLOCK_CTRL_0); + clk_ctrl_val = osi_readla(osi_core, + (nveu32_t *)addr + EQOS_CLOCK_CTRL_0); if (lb_mode == OSI_ENABLE) { /* Enable Loopback Mode */ @@ -4228,10 +4322,12 @@ static nve32_t eqos_config_mac_loopback(void *addr, } /* Write to EQOS wrapper clock control 0 register */ - osi_writel(clk_ctrl_val, (nveu8_t *)addr + EQOS_CLOCK_CTRL_0); + osi_writela(osi_core, clk_ctrl_val, + (nveu8_t *)addr + EQOS_CLOCK_CTRL_0); /* Write to MAC Configuration Register */ - eqos_core_safety_writel(mcr_val, (nveu8_t *)addr + EQOS_MAC_MCR, + eqos_core_safety_writel(osi_core, mcr_val, + (nveu8_t *)addr + EQOS_MAC_MCR, EQOS_MAC_MCR_IDX); return 0; @@ -4293,6 +4389,8 @@ struct osi_core_ops *eqos_get_hw_core_ops(void) .read_mmc = eqos_read_mmc, .write_phy_reg = eqos_write_phy_reg, .read_phy_reg = eqos_read_phy_reg, + .read_reg = eqos_read_reg, + .write_reg = eqos_write_reg, #ifndef OSI_STRIPPED_LIB .config_tx_status = eqos_config_tx_status, .config_rx_crc_check = eqos_config_rx_crc_check, diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 2aaa37b..38c361a 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -94,6 +94,7 @@ #define EQOS_MAC_MCR 0x0000 #define EQOS_MAC_EXTR 0x0004 #define EQOS_MAC_PFR 0x0008U +#define EQOS_MAC_WATCH 0x000CU #define EQOS_MAC_HTR_REG(x) ((0x0004U * (x)) + 0x0010U) #define EQOS_MAC_VLAN_TAG 0x0050 #define EQOS_MAC_VLANTIR 0x0060 @@ -167,6 +168,7 @@ * @{ */ #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 diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c new file mode 100644 index 0000000..23cf04f --- /dev/null +++ b/osi/core/ivc_core.c @@ -0,0 +1,1492 @@ +/* + * 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.h> +#include <osi_core.h> +#include <osd.h> +#include <ivc_core.h> +#include "eqos_core.h" +#include "eqos_mmc.h" + +/** + * @brief ivc_safety_config - EQOS MAC core safety configuration + */ +static struct core_func_safety ivc_safety_config; + +/** + * @brief ivc_config_fw_err_pkts - Configure forwarding of error packets + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] qinx: Queue index + * @param[in] fw_err: Enable or 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 ivc_config_fw_err_pkts( + struct osi_core_priv_data *const osi_core, + const nveu32_t qinx, + const nveu32_t fw_err) + +{ + ivc_msg_common msg_common; + nve32_t index = 0; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = config_fw_err_pkts; + msg_common.data.args.arguments[index++] = qinx; + msg_common.data.args.arguments[index++] = fw_err; + msg_common.data.args.count = index; + + return osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + +/** + * @brief ivc_poll_for_swr - Poll for software reset (SWR bit in DMA Mode) + * + * @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: No + * - De-initialization: No + * + * @retval 0 on success + * @retval -1 on failure. + */ +static nve32_t ivc_poll_for_swr(struct osi_core_priv_data *const osi_core) +{ + ivc_msg_common msg_common; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = poll_for_swr; + + return osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + +/** + * @brief ivc_set_speed - Set operating speed + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] speed: Operating speed. + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: Yes + * - De-initialization: No + * + * @pre MAC should be initialized and started. see osi_start_mac() + */ +static void ivc_set_speed(struct osi_core_priv_data *const osi_core, + const nve32_t speed) +{ + ivc_msg_common msg_common; + nve32_t index = 0; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = set_speed; + msg_common.data.args.arguments[index++] = speed; + msg_common.data.args.count = index; + + osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + +/** + * @brief ivc_set_mode - Set operating mode + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] mode: Operating 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 on success + * @retval -1 on failure. + */ +static nve32_t ivc_set_mode(struct osi_core_priv_data *const osi_core, + const nve32_t mode) +{ + ivc_msg_common msg_common; + nve32_t index = 0; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = set_mode; + msg_common.data.args.arguments[index++] = mode; + msg_common.data.args.count = index; + + return osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + +/** + * @brief ivc_pad_calibrate - PAD calibration + * + * @param[in] osi_core: OSI core private data structure. + * + * @note + * - MAC should out of reset and clocks enabled. + * - RGMII and MDIO nve32_terface 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 ivc_pad_calibrate(struct osi_core_priv_data *const osi_core) +{ + ivc_msg_common msg_common; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = pad_calibrate; + + return osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + +/** + * @brief ivc_flush_mtl_tx_queue - Flush MTL Tx queue + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] qinx: MTL queue index. + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: No + * - De-initialization: No + * + * @retval 0 on success + * @retval -1 on failure. + */ +static nve32_t ivc_flush_mtl_tx_queue( + struct osi_core_priv_data *const osi_core, + const nveu32_t qinx) +{ + ivc_msg_common msg_common; + nve32_t index = 0; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = flush_mtl_tx_queue; + msg_common.data.args.arguments[index++] = qinx; + msg_common.data.args.count = index; + + return osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + +/** + * @brief ivc_config_rxcsum_offload - Enable/Disale rx checksum offload in HW + * + * @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() + * @note + * API Group: + * - Initialization: Yes + * - Run time: Yes + * - De-initialization: No + * + * @retval 0 on success + * @retval -1 on failure. + */ +static nve32_t ivc_config_rxcsum_offload( + struct osi_core_priv_data *const osi_core, + const nveu32_t enabled) +{ + ivc_msg_common msg_common; + nve32_t index = 0; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = config_rxcsum_offload; + msg_common.data.args.arguments[index++] = enabled; + msg_common.data.args.count = index; + + return osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + +/** + * @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, + const nveu32_t tx_fifo_size, + const nveu32_t rx_fifo_size) +{ + ivc_msg_common msg_common; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = core_init; + msg_common.data.init_args.tx_fifo_size = tx_fifo_size; + msg_common.data.init_args.rx_fifo_size = rx_fifo_size; + msg_common.data.init_args.strip_vlan_tag = osi_core->strip_vlan_tag; + msg_common.data.init_args.pause_frames = osi_core->pause_frames; + msg_common.data.init_args.flow_ctrl = osi_core->flow_ctrl; + msg_common.data.init_args.num_mtl_queues = osi_core->num_mtl_queues; + msg_common.data.init_args.pre_si = osi_core->pre_si; + osi_memcpy(&msg_common.data.init_args.mtl_queues, + &osi_core->mtl_queues, sizeof(osi_core->mtl_queues)); + osi_memcpy(&msg_common.data.init_args.rxq_ctrl, + &osi_core->rxq_ctrl, sizeof(osi_core->rxq_ctrl)); + osi_memcpy(&msg_common.data.init_args.rxq_prio, + &osi_core->rxq_prio, sizeof(osi_core->rxq_prio)); + osi_memcpy(&msg_common.data.init_args.mac_addr, + &osi_core->mac_addr, OSI_ETH_ALEN); + + return osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + +/** + * @brief ivc_handle_common_nve32_tr - Handles common nve32_terrupt. + * + * @param[in] osi_core: OSI core private data structure. + * + * @note MAC should be init and started. see osi_start_mac() + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: Yes + * - De-initialization: No + * + */ +static void ivc_handle_common_intr( + struct osi_core_priv_data *const osi_core) +{ + ivc_msg_common msg_common; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = handle_common_intr; + + osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + +/** + * @brief ivc_start_mac - Start MAC Tx/Rx engine + * + * @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() + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: Yes + * - De-initialization: No + * + */ +static void ivc_start_mac(struct osi_core_priv_data *const osi_core) +{ + ivc_msg_common msg_common; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = start_mac; + + osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + +/** + * @brief ivc_stop_mac - Stop MAC Tx/Rx engine + * + * @param[in] osi_core: OSI core private data structure. + * + * @note MAC DMA deinit should be complete. See osi_hw_dma_deinit() + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: Yes + * - De-initialization: No + * + */ +static void ivc_stop_mac(struct osi_core_priv_data *const osi_core) +{ + ivc_msg_common msg_common; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = stop_mac; + + osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + +/** + * @brief ivc_config_mac_pkt_filter_reg - configure mac filter register. + * + * @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() + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: Yes + * - De-initialization: No + * + * @retval 0 always + */ +static nve32_t ivc_config_mac_pkt_filter_reg( + struct osi_core_priv_data *const osi_core, + const struct osi_filter *filter) +{ + ivc_msg_common msg_filter; + + osi_memset(&msg_filter, 0, sizeof(msg_filter)); + + msg_filter.cmd = config_mac_pkt_filter_reg; + osi_memcpy((void *)&msg_filter.data.filter, + (void *)filter, sizeof(struct osi_filter)); + + return osi_core->osd_ops.ivc_send(osi_core, (char *)&msg_filter, + sizeof(msg_filter)); +} + +/** + * @brief ivc_update_mac_addr_low_high_reg- Update L2 address in filter + * register + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] filter: OSI filter structure. + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: Yes + * - De-initialization: No + * + * @retval 0 on success + * @retval -1 on failure. + */ +static nve32_t ivc_update_mac_addr_low_high_reg( + struct osi_core_priv_data *const osi_core, + const struct osi_filter *filter) +{ + ivc_msg_common msg_filter; + + osi_memset(&msg_filter, 0, sizeof(msg_filter)); + + msg_filter.cmd = update_mac_addr_low_high_reg; + osi_memcpy((void *) &msg_filter.data.filter, + (void *) filter, sizeof(struct osi_filter)); + + return osi_core->osd_ops.ivc_send(osi_core, (char *)&msg_filter, + sizeof(msg_filter)); +} + +/** + * @brief ivc_config_l3_l4_filter_enable - register write to enable L3/L4 + * filters. + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] filter_enb_dis: enable/disable + * + * @note MAC should be init 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 ivc_config_l3_l4_filter_enable( + struct osi_core_priv_data *const osi_core, + const nveu32_t filter_enb_dis) +{ + ivc_msg_common msg_common; + nve32_t index = 0; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = config_l3_l4_filter_enable; + msg_common.data.args.arguments[index++] = filter_enb_dis; + msg_common.data.args.count = index; + + return osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + +/** + * @brief ivc_update_ip4_addr - configure register for IPV4 address 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() + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: Yes + * - De-initialization: No + * + * @retval 0 on success + * @retval -1 on failure. + */ +static nve32_t ivc_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) +{ + ivc_msg_common msg_common; + nve32_t index = 0; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = update_ip4_addr; + msg_common.data.args.arguments[index++] = filter_no; + osi_memcpy((void *)(nveu8_t *)&msg_common.data.args.arguments[index++], + (void *)addr, 4); + msg_common.data.args.arguments[index++] = src_dst_addr_match; + msg_common.data.args.count = index; + + return osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + +/** + * @brief ivc_update_ip6_addr - add ipv6 address in register + * + * @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() + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: Yes + * - De-initialization: No + * + * @retval 0 on success + * @retval -1 on failure. + */ +static nve32_t ivc_update_ip6_addr( + struct osi_core_priv_data *const osi_core, + const nveu32_t filter_no, + const nveu16_t addr[]) +{ + ivc_msg_common msg_common; + nve32_t index = 0; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = update_ip6_addr; + msg_common.data.args.arguments[index++] = filter_no; + msg_common.data.args.arguments[index++] = addr[0]; + msg_common.data.args.arguments[index++] = addr[1]; + msg_common.data.args.arguments[index++] = addr[2]; + msg_common.data.args.arguments[index++] = addr[3]; + msg_common.data.args.arguments[index++] = addr[4]; + msg_common.data.args.arguments[index++] = addr[5]; + msg_common.data.args.arguments[index++] = addr[6]; + msg_common.data.args.arguments[index++] = addr[7]; + msg_common.data.args.count = index; + + return osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + +/** + * @brief ivc_update_l4_port_no -program source port no + * + * @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 + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: Yes + * - De-initialization: No + * + * @retval 0 on success + * @retval -1 on failure. + */ +static nve32_t ivc_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) +{ + ivc_msg_common msg_common; + nve32_t index = 0; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = update_l4_port_no; + msg_common.data.args.arguments[index++] = filter_no; + msg_common.data.args.arguments[index++] = port_no; + msg_common.data.args.arguments[index++] = src_dst_port_match; + msg_common.data.args.count = index; + + return osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + +/** + * @brief ivc_config_l3_filters - config L3 filters. + * + * @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 + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: Yes + * - De-initialization: No + * + * @retval 0 on success + * @retval -1 on failure. + */ +static nve32_t ivc_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) +{ + ivc_msg_common msg_common; + nve32_t index = 0; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = config_l3_filters; + msg_common.data.args.arguments[index++] = filter_no; + msg_common.data.args.arguments[index++] = enb_dis; + msg_common.data.args.arguments[index++] = ipv4_ipv6_match; + msg_common.data.args.arguments[index++] = src_dst_addr_match; + msg_common.data.args.arguments[index++] = perfect_inverse_match; + msg_common.data.args.arguments[index++] = dma_routing_enable; + msg_common.data.args.arguments[index++] = dma_chan; + msg_common.data.args.count = index; + + return osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + +/** + * @brief ivc_config_l4_filters - Config L4 filters. + * + * @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 + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: Yes + * - De-initialization: No + * + * @retval 0 on success + * @retval -1 on failure. + */ +static nve32_t ivc_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) +{ + ivc_msg_common msg_common; + nve32_t index = 0; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = config_l4_filters; + msg_common.data.args.arguments[index++] = filter_no; + msg_common.data.args.arguments[index++] = enb_dis; + msg_common.data.args.arguments[index++] = tcp_udp_match; + msg_common.data.args.arguments[index++] = src_dst_port_match; + msg_common.data.args.arguments[index++] = perfect_inverse_match; + msg_common.data.args.arguments[index++] = dma_routing_enable; + msg_common.data.args.arguments[index++] = dma_chan; + msg_common.data.args.count = index; + + return osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + +/** + * @brief ivc_set_systime_to_mac - Set system time + * + * @param[in] osi_core: OSI core private data structure. + * @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() + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: Yes + * - De-initialization: No + * + * @retval 0 on success + * @retval -1 on failure. + */ +static nve32_t ivc_set_systime_to_mac( + struct osi_core_priv_data *const osi_core, + const nveu32_t sec, + const nveu32_t nsec) +{ + ivc_msg_common msg_common; + nve32_t index = 0; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = set_systime_to_mac; + msg_common.data.args.arguments[index++] = sec; + msg_common.data.args.arguments[index++] = nsec; + msg_common.data.args.count = index; + + return osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + +/** + * @brief ivc_config_addend - Configure addend + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] addend: Addend value to be configured + * + * @note MAC should be init 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 ivc_config_addend(struct osi_core_priv_data *const osi_core, + const nveu32_t addend) +{ + ivc_msg_common msg_common; + nve32_t index = 0; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = config_addend; + msg_common.data.args.arguments[index++] = addend; + msg_common.data.args.count = index; + + return osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + +/** + * @brief ivc_adjust_mactime - Adjust MAC time with system time + * + * @param[in] osi_core: OSI core private data structure. + * @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 nve32_t ivc_adjust_mactime(struct osi_core_priv_data *const osi_core, + nveu32_t sec, nveu32_t nsec, + nveu32_t add_sub, nveu32_t one_nsec_accuracy) +{ + ivc_msg_common msg_common; + nve32_t index = 0; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = adjust_mactime; + msg_common.data.args.arguments[index++] = sec; + msg_common.data.args.arguments[index++] = nsec; + msg_common.data.args.arguments[index++] = add_sub; + msg_common.data.args.arguments[index++] = one_nsec_accuracy; + msg_common.data.args.count = index; + + return osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + +/** + * @brief ivc_config_tscr - Configure Time Stamp Register + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] ptp_filter: PTP rx filter parameters + * + * @note MAC should be init and started. see osi_start_mac() + */ +static void ivc_config_tscr(struct osi_core_priv_data *const osi_core, + const nveu32_t ptp_filter) +{ + ivc_msg_common msg_common; + nve32_t index = 0; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = config_tscr; + msg_common.data.args.arguments[index++] = ptp_filter; + msg_common.data.args.count = index; + + osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + +/** + * @brief ivc_config_ssir - Configure SSIR + * + * @param[in] osi_core: OSI core private data structure. + * + * @note MAC should be init and started. see osi_start_mac() + */ +static void ivc_config_ssir(struct osi_core_priv_data *const osi_core) +{ + nveu32_t ptp_clock = osi_core->ptp_config.ptp_clock; + ivc_msg_common msg_common; + nve32_t index = 0; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = config_ssir; + msg_common.data.args.arguments[index++] = ptp_clock; + msg_common.data.args.count = index; + + osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + +/** + * @brief ivc_read_mmc - To read 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 ivc_read_mmc(struct osi_core_priv_data *osi_core) +{ + ivc_msg_common msg_common; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = read_mmc; + + osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); + +} + +/** + * @brief ivc_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 ivc_reset_mmc(struct osi_core_priv_data *osi_core) +{ + ivc_msg_common msg_common; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = reset_mmc; + + osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + + +/** + * @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) +{ + /* Stop the MAC by disabling both MAC Tx and Rx */ + ivc_stop_mac(osi_core); +} + +/** + * @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 msg_common; + nve32_t index = 0; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = write_phy_reg; + msg_common.data.args.arguments[index++] = phyaddr; + msg_common.data.args.arguments[index++] = phyreg; + msg_common.data.args.arguments[index++] = phydata; + msg_common.data.args.count = index; + + return osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + +/** + * @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 msg_common; + nve32_t index = 0; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = read_phy_reg; + msg_common.data.args.arguments[index++] = phyaddr; + msg_common.data.args.arguments[index++] = phyreg; + msg_common.data.args.count = index; + + return osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + +/** + * @brief ivc_read_reg - Read a reg + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] reg: Register. + * + * @retval data from register on success + * @retval -1 on failure + */ +static nveu32_t ivc_read_reg(struct osi_core_priv_data *const osi_core, + const nve32_t reg) { + ivc_msg_common msg_common; + nve32_t index = 0; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = reg_read; + msg_common.data.args.arguments[index++] = reg; + msg_common.data.args.count = index; + + return osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + +/** + * @brief ivc_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. + * + * @retval data from register on success + * @retval -1 on failure + */ +static nveu32_t ivc_write_reg(struct osi_core_priv_data *const osi_core, + const nveu32_t val, const nve32_t reg) { + ivc_msg_common msg_common; + nve32_t index = 0; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = reg_write; + msg_common.data.args.arguments[index++] = val; + msg_common.data.args.arguments[index++] = reg; + msg_common.data.args.count = index; + + return osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + +#ifndef OSI_STRIPPED_LIB +/** + * @brief ivc_config_flow_control - Configure MAC flow control settings + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] flw_ctrl: flw_ctrl settings + * + * @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 ivc_config_flow_control( + struct osi_core_priv_data *const osi_core, + const nveu32_t flw_ctrl) +{ + ivc_msg_common msg_common; + nve32_t index = 0; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = config_flow_control; + msg_common.data.args.arguments[index++] = flw_ctrl; + msg_common.data.args.count = index; + + return osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + +/** + * @brief Read-validate HW registers for functional safety. + * + * @param[in] osi_core: OSI core private data structure. + * + * @retval 0 on success + * @retval -1 on failure. + */ +static nve32_t ivc_validate_core_regs(struct osi_core_priv_data *const osi_core) +{ + ivc_msg_common msg_common; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = validate_regs; + + return osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + +/** + * @brief ivc_config_rx_crc_check - Configure CRC Checking for Rx Packets + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] crc_chk: Enable or disable checking of CRC field in received pkts + * + * @note MAC should be init and started. see osi_start_mac() + * + * @retval 0 on success + * @retval -1 on failure. + */ +static nve32_t ivc_config_rx_crc_check( + struct osi_core_priv_data *const osi_core, + const nveu32_t crc_chk) +{ + ivc_msg_common msg_common; + nve32_t index = 0; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + msg_common.cmd = config_rx_crc_check; + msg_common.data.args.arguments[index++] = crc_chk; + msg_common.data.args.count = index; + + return osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + +/** + * @brief ivc_config_tx_status - Configure MAC to forward the tx pkt status + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] tx_status: Enable or Disable the forwarding of tx pkt status + * + * @note MAC should be init and started. see osi_start_mac() + * + * @retval 0 on success + * @retval -1 on failure. + */ +static nve32_t ivc_config_tx_status(struct osi_core_priv_data *const osi_core, + const nveu32_t tx_status) +{ + ivc_msg_common msg_common; + nve32_t index = 0; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = config_tx_status; + msg_common.data.args.arguments[index++] = tx_status; + msg_common.data.args.count = index; + + return osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + +/** + * @brief ivc_set_avb_algorithm - Set TxQ/TC avb config + * + * @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 nve32_t ivc_set_avb_algorithm( + struct osi_core_priv_data *const osi_core, + const struct osi_core_avb_algorithm *const avb) +{ + ivc_msg_common msg_avb; + + osi_memset(&msg_avb, 0, sizeof(msg_avb)); + + msg_avb.cmd = set_avb_algorithm; + osi_memcpy((void *)&msg_avb.data.avb_algo, (void *)avb, + sizeof(struct osi_core_avb_algorithm)); + + return osi_core->osd_ops.ivc_send(osi_core, (char *)&msg_avb, + sizeof(msg_avb)); +} + +/** + * @brief ivc_get_avb_algorithm - Get TxQ/TC avb config + * + * @param[in] osi_core: osi core priv data structure + * @param[out] avb: structure ponve32_ter 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 nve32_t ivc_get_avb_algorithm(struct osi_core_priv_data *const osi_core, + struct osi_core_avb_algorithm *const avb) +{ + ivc_msg_common msg_avb; + + osi_memset(&msg_avb, 0, sizeof(msg_avb)); + + msg_avb.cmd = get_avb_algorithm; + osi_memcpy((void *) &msg_avb.data.avb_algo, + (void *)avb, sizeof(struct osi_core_avb_algorithm)); + + return osi_core->osd_ops.ivc_send(osi_core, (char *)&msg_avb, + sizeof(msg_avb)); +} + +/** + * @brief ivc_config_arp_offload - Enable/Disable ARP offload + * + * @param[in] osi_core: OSI core private 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. + * + * @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 nve32_t ivc_config_arp_offload( + struct osi_core_priv_data *const osi_core, + const nveu32_t enable, + const nveu8_t *ip_addr) +{ + ivc_msg_common msg_common; + nve32_t index = 0; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = config_arp_offload; + msg_common.data.args.arguments[index++] = enable; + osi_memcpy((void *)(nveu8_t *)&msg_common.data.args.arguments[index++], + (void *)ip_addr, 4); + msg_common.data.args.count = index; + + return osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + +/** + * @brief ivc_config_vlan_filter_reg - config vlan filter register + * + * @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 nve32_t ivc_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) +{ + ivc_msg_common msg_common; + nve32_t index = 0; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = config_vlan_filtering; + msg_common.data.args.arguments[index++] = filter_enb_dis; + msg_common.data.args.arguments[index++] = perfect_hash_filtering; + msg_common.data.args.arguments[index++] = perfect_inverse_match; + msg_common.data.args.count = index; + + return osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + +/** + * @brief ivc_update_vlan_id - update VLAN ID in Tag register + * + * @param[in] base: Base address from OSI core private data structure. + * @param[in] vid: VLAN ID to be programmed. + * + * @retval 0 always + */ +static inline nve32_t ivc_update_vlan_id( + struct osi_core_priv_data *const osi_core, + nveu32_t vid) +{ + /* Don't add VLAN ID to TR register which is eventually set TR + * to 0x0 and allow all tagged packets + */ + ivc_msg_common msg_common; + nve32_t index = 0; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = update_vlan_id; + msg_common.data.args.arguments[index++] = vid; + msg_common.data.args.count = index; + + return osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + +/** + * @brief ivc_configure_eee - Configure the EEE LPI mode + * + * @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. + * + * @note + * Required clks and resets has to be enabled. + * MAC/PHY should be initialized + */ +static void ivc_configure_eee(struct osi_core_priv_data *const osi_core, + const nveu32_t tx_lpi_enabled, + const nveu32_t tx_lpi_timer) +{ + ivc_msg_common msg_common; + nve32_t index = 0; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = configure_eee; + msg_common.data.args.arguments[index++] = tx_lpi_enabled; + msg_common.data.args.arguments[index++] = tx_lpi_timer; + msg_common.data.args.count = index; + + osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + +/* + * @brief Function to store a backup of MAC register space during SOC suspend. + * + * @param[in] osi_core: OSI core private data structure. + * + * @retval 0 on Success + */ +static inline nve32_t ivc_save_registers( + struct osi_core_priv_data *const osi_core) +{ + ivc_msg_common msg_common; + nve32_t index = 0; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = save_registers; + msg_common.data.args.count = index; + + return osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + +/** + * @brief Function to restore the backup of MAC registers during SOC resume. + * + * @param[in] osi_core: OSI core private data structure. + * + * @retval 0 on Success + */ +static inline nve32_t ivc_restore_registers( + struct osi_core_priv_data *const osi_core) +{ + ivc_msg_common msg_common; + nve32_t index = 0; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = restore_registers; + msg_common.data.args.count = index; + + return osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + +/** + * @brief ivc_set_mdc_clk_rate - Derive MDC clock based on provided AXI_CBB clk + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] csr_clk_rate: CSR (AXI CBB) clock rate. + * + * @note OSD layer needs get the AXI CBB clock rate with OSD clock API + * (ex - clk_get_rate()) + */ +static void ivc_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, + const nveu64_t csr_clk_rate) +{ + ivc_msg_common msg_common; + nve32_t index = 0; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = set_mdc_clk_rate; + msg_common.data.args.arguments[index++] = csr_clk_rate; + msg_common.data.args.count = index; + + osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + +/** + * @brief ivc_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 + * + * @note MAC should be init and started. see osi_start_mac() + * + * @retval 0 on success + * @retval -1 on failure. + */ +static nve32_t ivc_config_mac_loopback( + struct osi_core_priv_data *const osi_core, + const nveu32_t lb_mode) +{ + ivc_msg_common msg_common; + nve32_t index = 0; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = config_mac_loopback; + msg_common.data.args.arguments[index++] = lb_mode; + msg_common.data.args.count = index; + + return osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} +#endif +/** + * @brief ivc_ops - EQOS MAC core operations + */ +static struct osi_core_ops ivc_ops = { + .poll_for_swr = ivc_poll_for_swr, + .core_init = ivc_core_init, + .core_deinit = ivc_core_deinit, + .start_mac = ivc_start_mac, + .stop_mac = ivc_stop_mac, + .handle_common_intr = ivc_handle_common_intr, + .set_mode = ivc_set_mode, + .set_speed = ivc_set_speed, + .pad_calibrate = ivc_pad_calibrate, + .config_fw_err_pkts = ivc_config_fw_err_pkts, + .config_rxcsum_offload = ivc_config_rxcsum_offload, + .config_mac_pkt_filter_reg = ivc_config_mac_pkt_filter_reg, + .update_mac_addr_low_high_reg = ivc_update_mac_addr_low_high_reg, + .config_l3_l4_filter_enable = ivc_config_l3_l4_filter_enable, + .config_l3_filters = ivc_config_l3_filters, + .update_ip4_addr = ivc_update_ip4_addr, + .update_ip6_addr = ivc_update_ip6_addr, + .config_l4_filters = ivc_config_l4_filters, + .update_l4_port_no = ivc_update_l4_port_no, + .set_systime_to_mac = ivc_set_systime_to_mac, + .config_addend = ivc_config_addend, + .adjust_mactime = ivc_adjust_mactime, + .config_tscr = ivc_config_tscr, + .config_ssir = ivc_config_ssir, + .read_mmc = ivc_read_mmc, + .write_phy_reg = ivc_write_phy_reg, + .read_phy_reg = ivc_read_phy_reg, + .read_reg = ivc_read_reg, + .write_reg = ivc_write_reg, +#ifndef OSI_STRIPPED_LIB + .config_tx_status = ivc_config_tx_status, + .config_rx_crc_check = ivc_config_rx_crc_check, + .config_flow_control = ivc_config_flow_control, + .config_arp_offload = ivc_config_arp_offload, + .validate_regs = ivc_validate_core_regs, + .flush_mtl_tx_queue = ivc_flush_mtl_tx_queue, + .set_avb_algorithm = ivc_set_avb_algorithm, + .get_avb_algorithm = ivc_get_avb_algorithm, + .config_vlan_filtering = ivc_config_vlan_filtering, + .update_vlan_id = ivc_update_vlan_id, + .reset_mmc = ivc_reset_mmc, + .configure_eee = ivc_configure_eee, + .save_registers = ivc_save_registers, + .restore_registers = ivc_restore_registers, + .set_mdc_clk_rate = ivc_set_mdc_clk_rate, + .config_mac_loopback = ivc_config_mac_loopback, +#endif /* !OSI_STRIPPED_LIB */ +}; + +/** + * @brief ivc_get_core_safety_config - EQOS MAC safety configuration + */ +void *ivc_get_core_safety_config(void) +{ + return &ivc_safety_config; +} + +/** + * @brief ivc_get_hw_core_ops - EQOS MAC get core operations + */ +struct osi_core_ops *ivc_get_hw_core_ops(void) +{ + return &ivc_ops; +} diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 8f41774..42cf9d0 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -23,6 +23,7 @@ #include <osi_core.h> #include <osd.h> #include <local_common.h> +#include <ivc_core.h> nve32_t osi_write_phy_reg(struct osi_core_priv_data *const osi_core, const nveu32_t phyaddr, const nveu32_t phyreg, @@ -75,13 +76,27 @@ nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core) } if (osi_core->mac == OSI_MAC_HW_EQOS) { - /* Get EQOS HW ops */ - osi_core->ops = eqos_get_hw_core_ops(); - /* Explicitly set osi_core->safety_config = OSI_NULL if - * a particular MAC version does not need SW safety mechanisms - * like periodic read-verify. - */ - osi_core->safety_config = (void *)eqos_get_core_safety_config(); + if (osi_core->use_virtualization == OSI_DISABLE) { + /* Get EQOS HW ops */ + osi_core->ops = eqos_get_hw_core_ops(); + /* Explicitly set osi_core->safety_config = OSI_NULL if + * a particular MAC version does not need SW safety + * mechanisms like periodic read-verify. + */ + osi_core->safety_config = + (void *)eqos_get_core_safety_config(); + } else { +#ifdef LINUX_IVC + /* Get IVC HW ops */ + osi_core->ops = ivc_get_hw_core_ops(); + /* Explicitly set osi_core->safety_config = OSI_NULL if + * a particular MAC version does not need SW safety + * mechanisms like periodic read-verify. + */ + osi_core->safety_config = + (void *)ivc_get_core_safety_config(); +#endif + } return 0; } @@ -94,8 +109,7 @@ nve32_t osi_poll_for_mac_reset_complete( if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->base != OSI_NULL) && (osi_core->ops->poll_for_swr != OSI_NULL)) { - return osi_core->ops->poll_for_swr(osi_core, - osi_core->pre_si); + return osi_core->ops->poll_for_swr(osi_core); } return -1; @@ -131,7 +145,7 @@ nve32_t osi_start_mac(struct osi_core_priv_data *const osi_core) if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->base != OSI_NULL) && (osi_core->ops->start_mac != OSI_NULL)) { - osi_core->ops->start_mac(osi_core->base); + osi_core->ops->start_mac(osi_core); return 0; } @@ -143,7 +157,7 @@ nve32_t osi_stop_mac(struct osi_core_priv_data *const osi_core) if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->base != OSI_NULL) && (osi_core->ops->stop_mac != OSI_NULL)) { - osi_core->ops->stop_mac(osi_core->base); + osi_core->ops->stop_mac(osi_core); return 0; } @@ -180,7 +194,7 @@ nve32_t osi_set_speed(struct osi_core_priv_data *const osi_core, if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->base != OSI_NULL) && (osi_core->ops->set_speed != OSI_NULL)) { - osi_core->ops->set_speed(osi_core->base, speed); + osi_core->ops->set_speed(osi_core, speed); return 0; } @@ -425,11 +439,11 @@ nve32_t osi_l3l4_filter(struct osi_core_priv_data *const osi_core, if (osi_core->ops->config_l3_l4_filter_enable != OSI_NULL) { if (osi_core->l3l4_filter_bitmask != OSI_DISABLE) { ret = osi_core->ops->config_l3_l4_filter_enable( - osi_core->base, + osi_core, OSI_ENABLE); } else { ret = osi_core->ops->config_l3_l4_filter_enable( - osi_core->base, + osi_core, OSI_DISABLE); } @@ -631,10 +645,10 @@ nve32_t osi_ptp_configuration(struct osi_core_priv_data *const osi_core, if (enable == OSI_DISABLE) { /* disable hw time stamping */ /* Program MAC_Timestamp_Control Register */ - osi_core->ops->config_tscr(osi_core->base, OSI_DISABLE); + osi_core->ops->config_tscr(osi_core, OSI_DISABLE); } else { /* Program MAC_Timestamp_Control Register */ - osi_core->ops->config_tscr(osi_core->base, + osi_core->ops->config_tscr(osi_core, osi_core->ptp_config.ptp_filter); /* Program Sub Second Increment Register */ @@ -694,24 +708,132 @@ nve32_t osi_read_mmc(struct osi_core_priv_data *const osi_core) return -1; } -void osi_get_hw_features(void *base, struct osi_hw_features *hw_feat) +nveu32_t osi_read_reg(struct osi_core_priv_data *const osi_core, + const nve32_t addr) { - if ((base != OSI_NULL) && (hw_feat != OSI_NULL)) { - common_get_hw_features(base, hw_feat); + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->read_reg != OSI_NULL) && + (osi_core->base != OSI_NULL)) { + return osi_core->ops->read_reg(osi_core, addr); } - return; + return 0; } -nve32_t osi_get_mac_version(void *addr, nveu32_t *mac_ver) -{ - nve32_t ret = -1; - if ((addr != OSI_NULL) && (mac_ver != OSI_NULL)) { - return common_get_mac_version(addr, mac_ver); +nveu32_t osi_write_reg(struct osi_core_priv_data *const osi_core, + const nveu32_t val, const nve32_t addr) +{ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->write_reg != OSI_NULL) && + (osi_core->base != OSI_NULL)) { + return osi_core->ops->write_reg(osi_core, val, addr); } - return ret; + return 0; +} + +nve32_t osi_get_mac_version(struct osi_core_priv_data *const osi_core, + nveu32_t *mac_ver) +{ + nveu32_t macver; + + macver = osi_read_reg(osi_core, (nve32_t) MAC_VERSION) & + MAC_VERSION_SNVER_MASK; + if (is_valid_mac_version(macver) == 0) { + return -1; + } + + *mac_ver = macver; + return 0; +} + +void osi_get_hw_features(struct osi_core_priv_data *const osi_core, + struct osi_hw_features *hw_feat) +{ + nveu32_t mac_hfr0; + nveu32_t mac_hfr1; + nveu32_t mac_hfr2; + + if (hw_feat != OSI_NULL) { + /* TODO: need to add HFR3 */ + mac_hfr0 = osi_read_reg(osi_core, EQOS_MAC_HFR0); + mac_hfr1 = osi_read_reg(osi_core, EQOS_MAC_HFR1); + mac_hfr2 = osi_read_reg(osi_core, EQOS_MAC_HFR2); + + hw_feat->mii_sel = + ((mac_hfr0 >> 0) & EQOS_MAC_HFR0_MIISEL_MASK); + hw_feat->gmii_sel = + ((mac_hfr0 >> 1U) & EQOS_MAC_HFR0_GMIISEL_MASK); + hw_feat->hd_sel = + ((mac_hfr0 >> 2U) & EQOS_MAC_HFR0_HDSEL_MASK); + hw_feat->pcs_sel = + ((mac_hfr0 >> 3U) & EQOS_MAC_HFR0_PCSSEL_MASK); + hw_feat->sma_sel = + ((mac_hfr0 >> 5U) & EQOS_MAC_HFR0_SMASEL_MASK); + hw_feat->rwk_sel = + ((mac_hfr0 >> 6U) & EQOS_MAC_HFR0_RWKSEL_MASK); + hw_feat->mgk_sel = + ((mac_hfr0 >> 7U) & EQOS_MAC_HFR0_MGKSEL_MASK); + hw_feat->mmc_sel = + ((mac_hfr0 >> 8U) & EQOS_MAC_HFR0_MMCSEL_MASK); + hw_feat->arp_offld_en = + ((mac_hfr0 >> 9U) & EQOS_MAC_HFR0_ARPOFFLDEN_MASK); + hw_feat->ts_sel = + ((mac_hfr0 >> 12U) & EQOS_MAC_HFR0_TSSSEL_MASK); + hw_feat->eee_sel = + ((mac_hfr0 >> 13U) & EQOS_MAC_HFR0_EEESEL_MASK); + hw_feat->tx_coe_sel = + ((mac_hfr0 >> 14U) & EQOS_MAC_HFR0_TXCOESEL_MASK); + hw_feat->rx_coe_sel = + ((mac_hfr0 >> 16U) & EQOS_MAC_HFR0_RXCOE_MASK); + hw_feat->mac_addr_sel = + ((mac_hfr0 >> 18U) & EQOS_MAC_HFR0_ADDMACADRSEL_MASK); + hw_feat->mac_addr32_sel = + ((mac_hfr0 >> 23U) & EQOS_MAC_HFR0_MACADR32SEL_MASK); + hw_feat->mac_addr64_sel = + ((mac_hfr0 >> 24U) & EQOS_MAC_HFR0_MACADR64SEL_MASK); + hw_feat->tsstssel = + ((mac_hfr0 >> 25U) & EQOS_MAC_HFR0_TSINTSEL_MASK); + hw_feat->sa_vlan_ins = + ((mac_hfr0 >> 27U) & EQOS_MAC_HFR0_SAVLANINS_MASK); + hw_feat->act_phy_sel = + ((mac_hfr0 >> 28U) & EQOS_MAC_HFR0_ACTPHYSEL_MASK); + hw_feat->rx_fifo_size = + ((mac_hfr1 >> 0) & EQOS_MAC_HFR1_RXFIFOSIZE_MASK); + hw_feat->tx_fifo_size = + ((mac_hfr1 >> 6U) & EQOS_MAC_HFR1_TXFIFOSIZE_MASK); + hw_feat->adv_ts_hword = + ((mac_hfr1 >> 13U) & EQOS_MAC_HFR1_ADVTHWORD_MASK); + hw_feat->addr_64 = + ((mac_hfr1 >> 14U) & EQOS_MAC_HFR1_ADDR64_MASK); + hw_feat->dcb_en = + ((mac_hfr1 >> 16U) & EQOS_MAC_HFR1_DCBEN_MASK); + hw_feat->sph_en = + ((mac_hfr1 >> 17U) & EQOS_MAC_HFR1_SPHEN_MASK); + hw_feat->tso_en = + ((mac_hfr1 >> 18U) & EQOS_MAC_HFR1_TSOEN_MASK); + hw_feat->dma_debug_gen = + ((mac_hfr1 >> 19U) & EQOS_MAC_HFR1_DMADEBUGEN_MASK); + hw_feat->av_sel = + ((mac_hfr1 >> 20U) & EQOS_MAC_HFR1_AVSEL_MASK); + hw_feat->hash_tbl_sz = + ((mac_hfr1 >> 24U) & EQOS_MAC_HFR1_HASHTBLSZ_MASK); + hw_feat->l3l4_filter_num = + ((mac_hfr1 >> 27U) & EQOS_MAC_HFR1_L3L4FILTERNUM_MASK); + hw_feat->rx_q_cnt = + ((mac_hfr2 >> 0) & EQOS_MAC_HFR2_RXQCNT_MASK); + hw_feat->tx_q_cnt = + ((mac_hfr2 >> 6U) & EQOS_MAC_HFR2_TXQCNT_MASK); + hw_feat->rx_ch_cnt = + ((mac_hfr2 >> 12U) & EQOS_MAC_HFR2_RXCHCNT_MASK); + hw_feat->tx_ch_cnt = + ((mac_hfr2 >> 18U) & EQOS_MAC_HFR2_TXCHCNT_MASK); + hw_feat->pps_out_num = + ((mac_hfr2 >> 24U) & EQOS_MAC_HFR2_PPSOUTNUM_MASK); + hw_feat->aux_snap_num = + ((mac_hfr2 >> 28U) & EQOS_MAC_HFR2_AUXSNAPNUM_MASK); + } } #ifndef OSI_STRIPPED_LIB @@ -817,8 +939,8 @@ nve32_t osi_update_vlan_id(struct osi_core_priv_data *const osi_core, { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->update_vlan_id != OSI_NULL)) { - return osi_core->ops->update_vlan_id(osi_core->base, - vid); + return osi_core->ops->update_vlan_id(osi_core, + vid); } return -1; @@ -828,8 +950,9 @@ nve32_t osi_get_systime_from_mac(struct osi_core_priv_data *const osi_core, nveu32_t *sec, nveu32_t *nsec) { - if ((osi_core != OSI_NULL) && (osi_core->base != OSI_NULL)) { - common_get_systime_from_mac(osi_core->base, osi_core->mac, sec, + if ((osi_core != OSI_NULL) && (osi_core->dma_base != OSI_NULL)) { + common_get_systime_from_mac(osi_core->dma_base, + osi_core->mac, sec, nsec); } else { return -1; @@ -912,8 +1035,7 @@ nve32_t osi_config_arp_offload(struct osi_core_priv_data *const osi_core, if (osi_core != OSI_NULL && osi_core->ops != OSI_NULL && (osi_core->base != OSI_NULL) && (ip_addr != OSI_NULL) && (osi_core->ops->config_arp_offload != OSI_NULL)) { - return osi_core->ops->config_arp_offload(osi_core->mac_ver, - osi_core, + return osi_core->ops->config_arp_offload(osi_core, flags, ip_addr); } @@ -938,7 +1060,7 @@ nve32_t osi_config_mac_loopback(struct osi_core_priv_data *const osi_core, /* Configure MAC loopback */ if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && (osi_core->ops->config_mac_loopback != OSI_NULL)) { - return osi_core->ops->config_mac_loopback(osi_core->base, + return osi_core->ops->config_mac_loopback(osi_core, lb_mode); } diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index 65ca548..5ed0c7d 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -42,6 +42,7 @@ static struct dma_func_safety eqos_dma_safety_config; * 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. @@ -54,13 +55,14 @@ static struct dma_func_safety eqos_dma_safety_config; * - Run time: Yes * - De-initialization: Yes */ -static inline void eqos_dma_safety_writel(nveu32_t val, void *addr, +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_writel(val, addr); + osi_writela(osi_dma->osd, val, addr); config->reg_val[idx] = (val & config->reg_mask[idx]); osi_unlock_irq_enabled(&config->dma_safety_lock); } @@ -300,8 +302,7 @@ static void eqos_enable_chan_rx_intr(void *addr, nveu32_t chan) * Algorithm: * - Set DMA Tx channel ring length for specific channel. * - * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. + * @param[in] osi_dma: OSI DMA private data structure. * @param[in] chan: DMA Tx channel number. * @param[in] len: Length. * @@ -311,11 +312,13 @@ static void eqos_enable_chan_rx_intr(void *addr, nveu32_t chan) * - Run time: No * - De-initialization: No */ -static void eqos_set_tx_ring_len(void *addr, nveu32_t chan, +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; CHECK_CHAN_BOUND(chan); - eqos_dma_safety_writel(len, (nveu8_t *)addr + + eqos_dma_safety_writel(osi_dma, len, (nveu8_t *)addr + EQOS_DMA_CHX_TDRL(chan), EQOS_DMA_CH0_TDRL_IDX + chan); } @@ -402,8 +405,7 @@ static void eqos_update_tx_tailptr(void *addr, nveu32_t chan, * Algorithm: * - Sets DMA Rx channel ring length for specific DMA channel. * - * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. + * @param[in] osi_dma: OSI DMA private data structure. * @param[in] chan: DMA Rx channel number. * @param[in] len: Length * @@ -413,11 +415,13 @@ static void eqos_update_tx_tailptr(void *addr, nveu32_t chan, * - Run time: No * - De-initialization: No */ -static void eqos_set_rx_ring_len(void *addr, nveu32_t chan, +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; CHECK_CHAN_BOUND(chan); - eqos_dma_safety_writel(len, (nveu8_t *)addr + + eqos_dma_safety_writel(osi_dma, len, (nveu8_t *)addr + EQOS_DMA_CHX_RDRL(chan), EQOS_DMA_CH0_RDRL_IDX + chan); } @@ -503,8 +507,7 @@ static void eqos_update_rx_tailptr(void *addr, nveu32_t chan, * Algorithm: * - Start Tx and Rx DMA for specific channel. * - * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. + * @param[in] osi_dma: OSI DMA private data structure. * @param[in] chan: DMA Tx/Rx channel number. * * @pre @@ -517,23 +520,26 @@ static void eqos_update_rx_tailptr(void *addr, nveu32_t chan, * - Run time: No * - De-initialization: No */ -static void eqos_start_dma(void *addr, nveu32_t chan) +static void eqos_start_dma(struct osi_dma_priv_data *osi_dma, nveu32_t chan) { nveu32_t val; + void *addr = osi_dma->base; CHECK_CHAN_BOUND(chan); /* start Tx DMA */ - val = osi_readl((nveu8_t *)addr + EQOS_DMA_CHX_TX_CTRL(chan)); + val = osi_readla(osi_dma->osd, + (nveu8_t *)addr + EQOS_DMA_CHX_TX_CTRL(chan)); val |= OSI_BIT(0); - eqos_dma_safety_writel(val, (nveu8_t *)addr + + 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_readl((nveu8_t *)addr + EQOS_DMA_CHX_RX_CTRL(chan)); + val = osi_readla(osi_dma->osd, + (nveu8_t *)addr + EQOS_DMA_CHX_RX_CTRL(chan)); val |= OSI_BIT(0); - eqos_dma_safety_writel(val, (nveu8_t *)addr + + eqos_dma_safety_writel(osi_dma, val, (nveu8_t *)addr + EQOS_DMA_CHX_RX_CTRL(chan), EQOS_DMA_CH0_RX_CTRL_IDX + chan); } @@ -545,8 +551,7 @@ static void eqos_start_dma(void *addr, nveu32_t chan) * Algorithm: * - Start Tx and Rx DMA for specific channel. * - * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. + * @param[in] osi_dma: OSI DMA private data structure. * @param[in] chan: DMA Tx/Rx channel number. * * @pre @@ -559,23 +564,26 @@ static void eqos_start_dma(void *addr, nveu32_t chan) * - Run time: No * - De-initialization: Yes */ -static void eqos_stop_dma(void *addr, nveu32_t chan) +static void eqos_stop_dma(struct osi_dma_priv_data *osi_dma, nveu32_t chan) { nveu32_t val; + void *addr = osi_dma->base; CHECK_CHAN_BOUND(chan); /* stop Tx DMA */ - val = osi_readl((nveu8_t *)addr + EQOS_DMA_CHX_TX_CTRL(chan)); + val = osi_readla(osi_dma->osd, + (nveu8_t *)addr + EQOS_DMA_CHX_TX_CTRL(chan)); val &= ~OSI_BIT(0); - eqos_dma_safety_writel(val, (nveu8_t *)addr + + 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_readl((nveu8_t *)addr + EQOS_DMA_CHX_RX_CTRL(chan)); + val = osi_readla(osi_dma->osd, + (nveu8_t *)addr + EQOS_DMA_CHX_RX_CTRL(chan)); val &= ~OSI_BIT(0); - eqos_dma_safety_writel(val, (nveu8_t *)addr + + eqos_dma_safety_writel(osi_dma, val, (nveu8_t *)addr + EQOS_DMA_CHX_RX_CTRL(chan), EQOS_DMA_CH0_RX_CTRL_IDX + chan); } @@ -632,7 +640,7 @@ static void eqos_configure_dma_channel(nveu32_t chan, 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(value, (nveu8_t *)osi_dma->base + + 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); @@ -640,7 +648,7 @@ static void eqos_configure_dma_channel(nveu32_t chan, value = osi_readl((nveu8_t *)osi_dma->base + EQOS_DMA_CHX_CTRL(chan)); value |= EQOS_DMA_CHX_CTRL_PBLX8; - eqos_dma_safety_writel(value, (nveu8_t *)osi_dma->base + + eqos_dma_safety_writel(osi_dma, value, (nveu8_t *)osi_dma->base + EQOS_DMA_CHX_CTRL(chan), EQOS_DMA_CH0_CTRL_IDX + chan); @@ -654,7 +662,7 @@ static void eqos_configure_dma_channel(nveu32_t chan, /* enable TSO by default if HW supports */ value |= EQOS_DMA_CHX_TX_CTRL_TSE; - eqos_dma_safety_writel(value, (nveu8_t *)osi_dma->base + + 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); @@ -671,7 +679,7 @@ static void eqos_configure_dma_channel(nveu32_t chan, 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(value, (nveu8_t *)osi_dma->base + + 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); diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 000a564..d68a288 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -231,7 +231,7 @@ nve32_t osi_start_dma(struct osi_dma_priv_data *osi_dma, if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && (osi_dma->base != OSI_NULL) && (chan < OSI_EQOS_MAX_NUM_CHANS) && (osi_dma->ops->start_dma != OSI_NULL)) { - osi_dma->ops->start_dma(osi_dma->base, chan); + osi_dma->ops->start_dma(osi_dma, chan); return 0; } @@ -244,7 +244,7 @@ nve32_t osi_stop_dma(struct osi_dma_priv_data *osi_dma, if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && (osi_dma->base != OSI_NULL) && (chan < OSI_EQOS_MAX_NUM_CHANS) && (osi_dma->ops->stop_dma != OSI_NULL)) { - osi_dma->ops->stop_dma(osi_dma->base, chan); + osi_dma->ops->stop_dma(osi_dma, chan); return 0; } diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 1af47b2..56ccd1a 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -1308,7 +1308,7 @@ static nve32_t rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, return -1; } - ops->set_rx_ring_len(osi_dma->base, chan, (RX_DESC_CNT - 1U)); + ops->set_rx_ring_len(osi_dma, chan, (RX_DESC_CNT - 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); @@ -1415,8 +1415,8 @@ static nve32_t tx_dma_desc_init(struct osi_dma_priv_data *osi_dma) tx_ring->slot_check = OSI_DISABLE; if (osi_likely((ops->set_tx_ring_len != OSI_NULL) || - (ops->set_tx_ring_start_addr != OSI_NULL))) { - ops->set_tx_ring_len(osi_dma->base, chan, + ops->set_tx_ring_start_addr != OSI_NULL)) { + ops->set_tx_ring_len(osi_dma, chan, (TX_DESC_CNT - 1U)); ops->set_tx_ring_start_addr(osi_dma->base, chan, tx_ring->tx_desc_phy_addr); From c4060a4edef2634eb783a84ebdf260505fa29ced Mon Sep 17 00:00:00 2001 From: nannaiah <nannaiah@nvidia.com> Date: Tue, 12 Jan 2021 20:34:36 -0800 Subject: [PATCH 142/458] nvthernetrm: Fix wrong typecast in eqos core. Issue: Few functions as wrong typecasts for base addr. Fix: Fix wrong typecasts from uint32_t to uint8_t. Bug 3191816 Change-Id: I7a850b775a92038a30297449e2d463e29702b554 Signed-off-by: Nagaraj Annaiah <nannaiah@nvidia.com> Change-Id: I7a850b775a92038a30297449e2d463e29702b554 Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2469680 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/eqos_core.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 4444522..8b325c7 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -495,7 +495,7 @@ static nve32_t eqos_poll_for_swr(struct osi_core_priv_data *const osi_core) if (pre_si == OSI_ENABLE) { osi_writela(osi_core, 0x1U, - (nveu32_t *)addr + EQOS_DMA_BMR); + (nveu8_t *)addr + EQOS_DMA_BMR); } /* add delay of 10 usec */ osi_core->osd_ops.usleep_range(9, 11); @@ -1272,7 +1272,7 @@ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) /* Enable Multicast and Broadcast Queue, default is Q0 */ value = osi_readla(osi_core, - (nveu32_t *)osi_core->base + EQOS_MAC_RQC1R); + (nveu8_t *)osi_core->base + EQOS_MAC_RQC1R); value |= EQOS_MAC_RQC1R_MCBCQEN; /* Routing Multicast and Broadcast to Q1 */ value |= EQOS_MAC_RQC1R_MCBCQ1; @@ -4301,11 +4301,11 @@ static nve32_t eqos_config_mac_loopback( } /* Read MAC Configuration Register */ - mcr_val = osi_readla(osi_core, (nveu32_t *)addr + EQOS_MAC_MCR); + 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, - (nveu32_t *)addr + EQOS_CLOCK_CTRL_0); + (nveu8_t *)addr + EQOS_CLOCK_CTRL_0); if (lb_mode == OSI_ENABLE) { /* Enable Loopback Mode */ From 17284df32ed4fed17c912162d2ba90aed6449d18 Mon Sep 17 00:00:00 2001 From: rakesh goyal <rgoyal@nvidia.com> Date: Wed, 6 Jan 2021 14:36:40 +0530 Subject: [PATCH 143/458] osi: dma: core: fix static analysis errors Issue: Introduced Coverity and Cert errors which are identified with 2020.06 config file Fix: Coverity and Cert errors fixed Bug 200689877 Change-Id: I1bc6278162692468bfb67cf61c144ed2f81bc72f Signed-off-by: rakesh goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2466677 Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2468656 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/osi_core.c | 6 ++++-- osi/dma/osi_dma.c | 4 ++-- osi/dma/osi_dma_txrx.c | 6 +++--- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 42cf9d0..118d7f6 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -688,9 +688,11 @@ nve32_t osi_ptp_configuration(struct osi_core_priv_data *const osi_core, osi_core->default_addend); /* Set current time */ - ret = osi_core->ops->set_systime_to_mac(osi_core, + if (ret == 0) { + ret = osi_core->ops->set_systime_to_mac(osi_core, osi_core->ptp_config.sec, osi_core->ptp_config.nsec); + } } return ret; diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index d68a288..d213f27 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -82,7 +82,7 @@ nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) return ret; } } else { - return -1; + return ret; } ret = dma_desc_init(osi_dma); diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 56ccd1a..12e3968 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -1414,8 +1414,8 @@ static nve32_t tx_dma_desc_init(struct osi_dma_priv_data *osi_dma) tx_ring->slot_number = 0U; tx_ring->slot_check = OSI_DISABLE; - if (osi_likely((ops->set_tx_ring_len != OSI_NULL) || - ops->set_tx_ring_start_addr != OSI_NULL)) { + if (osi_likely((ops->set_tx_ring_len != OSI_NULL) && + (ops->set_tx_ring_start_addr != OSI_NULL))) { ops->set_tx_ring_len(osi_dma, chan, (TX_DESC_CNT - 1U)); ops->set_tx_ring_start_addr(osi_dma->base, chan, From 44041fcf245b1038db86723c2287112965c57d55 Mon Sep 17 00:00:00 2001 From: Nagarjuna Kristam <nkristam@nvidia.com> Date: Wed, 20 Jan 2021 15:41:22 +0530 Subject: [PATCH 144/458] osi: update input arguments with boundary values Issue: Verification checklist requests input params with boundaries for external interfaces to be documented. Fix: Add boundaries for input argument which has boundaries implemented. Bug 200673381 Change-Id: I4ffac5dcabf836038cf9b2c4e448ec1f881ef271 Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2472860 (cherry picked from commit a84e13325795fb63ad567c95c10813875604e26a) Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2474894 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Gaurav Asati <gasati@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_core.h | 14 ++++++++------ include/osi_dma.h | 21 +++++++++++---------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 9a8e3c3..38d8f33 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -813,7 +813,7 @@ nve32_t osi_common_isr(struct osi_core_priv_data *const osi_core); * - 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. + * @param[in] mode: Operating mode. (OSI_FULL_DUPLEX/OSI_HALF_DUPLEX) * * @pre MAC should be init and started. see osi_start_mac() * @@ -921,8 +921,9 @@ nve32_t osi_pad_calibrate(struct osi_core_priv_data *const osi_core); * - Configure MAC to enable/disable forwarding of error packets. * * @param[in] osi_core: OSI core private data structure. - * @param[in] qinx: Q index - * @param[in] fw_err: Enable or disable forwarding of error packets + * @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() * @@ -957,7 +958,7 @@ nve32_t osi_config_fw_err_pkts(struct osi_core_priv_data *const osi_core, * - Invokes EQOS config RX checksum offload routine. * * @param[in] osi_core: OSI core private data structure. - * @param[in] enable: Enable/disable flag. + * @param[in] enable: Enable/disable flag. 0: Disable 1: Enable * * @pre MAC should be init and started. see osi_start_mac() * @@ -1359,7 +1360,8 @@ void *eqos_get_core_safety_config(void); * @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 + * @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 diff --git a/include/osi_dma.h b/include/osi_dma.h index dbf42f0..6d78ba0 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -557,7 +557,7 @@ struct osi_dma_priv_data { * - Disables Tx interrupts at wrapper level. * * @param[in] osi_dma: OSI DMA private data. - * @param[in] chan: DMA Tx channel number. + * @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. @@ -596,7 +596,7 @@ nve32_t osi_disable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, * - Enables Tx interrupts at wrapper level. * * @param[in] osi_dma: OSI DMA private data. - * @param[in] chan: DMA Tx channel number. + * @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. @@ -635,7 +635,7 @@ nve32_t osi_enable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, * - Disables Rx interrupts at wrapper level. * * @param[in] osi_dma: OSI DMA private data. - * @param[in] chan: DMA rx channel number. + * @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. @@ -674,7 +674,7 @@ nve32_t osi_disable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, * - Enables Rx interrupts at wrapper level. * * @param[in] osi_dma: OSI DMA private data. - * @param[in] chan: DMA rx channel number. + * @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. @@ -767,7 +767,7 @@ nve32_t osi_clear_vm_rx_intr(struct osi_dma_priv_data *osi_dma, * - Start the DMA for specific MAC * * @param[in] osi_dma: OSI DMA private data. - * @param[in] chan: DMA Tx/Rx channel number + * @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. @@ -803,7 +803,7 @@ nve32_t osi_start_dma(struct osi_dma_priv_data *osi_dma, nveu32_t chan); * - Stop the DMA for specific MAC * * @param[in] osi_dma: OSI DMA private data. - * @param[in] chan: DMA Tx/Rx channel number + * @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. @@ -871,7 +871,7 @@ nveu32_t osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring); * * @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 + * @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. @@ -943,7 +943,7 @@ nve32_t osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma); * Tx ring base address in Tx DMA registers. * * @param[in, out] osi_dma: OSI DMA private data. - * @param[in] chan: DMA Tx channel number. + * @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. @@ -994,6 +994,7 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi_dma, nveu32_t chan); * * @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 @@ -1039,7 +1040,7 @@ nve32_t osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, * handover to DMA. * * @param[in, out] osi_dma: OSI DMA private data structure. - * @param[in] chan: Rx DMA channel number + * @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). From 4a1ef5b96077d7430b7425f8c3af9c7d239d8c5e Mon Sep 17 00:00:00 2001 From: Srinivas Ramachandran <srinivasra@nvidia.com> Date: Thu, 11 Feb 2021 09:44:35 -0800 Subject: [PATCH 145/458] nvethernetrm: Do not touch descriptor after setting OWN bit Issue: Rx descriptor is being modified after setting OWN bit to HW. This is resulting in race conditions with HW, where HW opens the descriptor and SW is also writing to it, resulting in corruption of the descriptor due to which HW tries to access an invalid buffer address. This leads to SMMU fault prints observed in the debug uart, and eventually results in Rx DMA getting hung during long hour test. Fix: Move the OWN bit setting to the very last step in Rx descriptor handling. Do not touch the descriptor from SW after this point until Rx irq processing. Bug 3194355 Change-Id: I07fc68f49123947a126e6a2fdb9433a871d75999 Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2483737 Tested-by: Srinivas Ramachandran <srinivasra@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: Ajay Gupta <ajayg@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/dma/osi_dma.c | 3 ++- osi/dma/osi_dma_txrx.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index d213f27..42f53fc 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -392,10 +392,11 @@ nve32_t osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, } rx_desc->rdes2 = 0; - rx_desc->rdes3 = (RDES3_OWN | RDES3_IOC | RDES3_B1V); + rx_desc->rdes3 = (RDES3_IOC | 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, 1U); } diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 12e3968..3e4ce75 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -1277,7 +1277,7 @@ static nve32_t rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, } rx_desc->rdes2 = 0; - rx_desc->rdes3 = (RDES3_OWN | RDES3_IOC | RDES3_B1V); + rx_desc->rdes3 = (RDES3_IOC | RDES3_B1V); /* reconfigure INTE bit if RX watchdog timer is enabled */ if (osi_dma->use_riwt == OSI_ENABLE) { rx_desc->rdes3 &= ~RDES3_IOC; @@ -1291,6 +1291,7 @@ static nve32_t rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, } } } + rx_desc->rdes3 |= RDES3_OWN; rx_swcx->flags = 0; } From fe81827eee5262ae70effd5d52f8b844f320098b Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Mon, 22 Feb 2021 16:50:53 +0530 Subject: [PATCH 146/458] osi: remove core API to get MAC time Issue: dma_base pointer being checked in osi_get_systime_from_mac() API which will be not populated OSD which resulted in PTP time sync issues. Fix: Use DMA API inside OSD to get MAC time and remove dma_base usage. Bug 200696375 Change-Id: I807a99b6af82a12eddd830f5b010c4a83e8b7b92 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2487698 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: Nagarjuna Kristam <nkristam@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_core.h | 38 -------------------------------------- osi/core/osi_core.c | 15 --------------- 2 files changed, 53 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 38d8f33..f3fb1f7 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -534,8 +534,6 @@ struct osd_core_ops { struct osi_core_priv_data { /** Memory mapped base address of MAC IP */ void *base; - /** Memory mapped base address of DMA window of MAC IP */ - void *dma_base; /** Pointer to OSD private data structure */ void *osd; /** Address of HW Core operations structure */ @@ -1864,42 +1862,6 @@ nve32_t osi_update_vlan_id(struct osi_core_priv_data *const osi_core, */ nve32_t osi_reset_mmc(struct osi_core_priv_data *const osi_core); -/** - * @brief osi_get_systime_from_mac - Get system time - * - * @note - * Algorithm: - * - Gets the current system time - * - * @param[in] osi_core: OSI core 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: - * - * @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. - */ -nve32_t osi_get_systime_from_mac(struct osi_core_priv_data *const osi_core, - nveu32_t *sec, - nveu32_t *nsec); - /** * @brief osi_configure_eee - Configure EEE LPI in MAC. * diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 118d7f6..fa47831 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -948,21 +948,6 @@ nve32_t osi_update_vlan_id(struct osi_core_priv_data *const osi_core, return -1; } -nve32_t osi_get_systime_from_mac(struct osi_core_priv_data *const osi_core, - nveu32_t *sec, - nveu32_t *nsec) -{ - if ((osi_core != OSI_NULL) && (osi_core->dma_base != OSI_NULL)) { - common_get_systime_from_mac(osi_core->dma_base, - osi_core->mac, sec, - nsec); - } else { - return -1; - } - - return 0; -} - nve32_t osi_reset_mmc(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && From 10d38c6d1b80469a1129dc469daa93a7f701b79e Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Wed, 10 Feb 2021 20:51:03 +0530 Subject: [PATCH 147/458] osi: delete osd_ops functions Bug 200620687 Change-Id: I1b3d46b86e3d9679a5b4db780aa8ea17a0349c8a Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2483072 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osd.h | 151 ---------------------------------------- osi/common/osd_dummy.c | 58 --------------- osi/common/osi_common.c | 3 +- osi/core/Makefile.tmk | 5 +- osi/core/eqos_core.c | 1 - osi/core/eqos_mmc.c | 3 +- osi/core/ivc_core.c | 3 +- osi/core/osi_core.c | 27 +++---- osi/dma/Makefile.tmk | 5 +- osi/dma/osi_dma.c | 27 +++---- osi/dma/osi_dma_txrx.c | 1 - 11 files changed, 23 insertions(+), 261 deletions(-) delete mode 100644 include/osd.h delete mode 100644 osi/common/osd_dummy.c diff --git a/include/osd.h b/include/osd.h deleted file mode 100644 index 3bed0f3..0000000 --- a/include/osd.h +++ /dev/null @@ -1,151 +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_OSD_H -#define INCLUDED_OSD_H - -#include "../osi/common/type.h" - -/** - * @brief osd_usleep_range - sleep in micro seconds - * - * @param[in] umin: Minimum time in usecs to sleep - * @param[in] umax: Maximum time in usecs to sleep - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - */ -void osd_usleep_range(nveu64_t umin, nveu64_t umax); -/** - * @brief osd_msleep - sleep in milli seconds - * - * @param[in] msec: time in milli seconds - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - */ -void osd_msleep(nveu32_t msec); -/** - * @brief osd_udelay - delay in micro seconds - * - * @param[in] usec: time in usec - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - */ -void osd_udelay(nveu64_t usec); -/** - * @brief osd_receive_packet - Handover received packet to network stack. - * - * @note - * Algorithm: - * - Unmap the DMA buffer address (not needed if buffers are - * allocated statically). - * - Refill the Rx ring based on threshold. - * - Consume the flag information and take decision to hand over the packet - * and related information to OS network stack. - * - * @param[in] priv: OSD private data structure. - * @param[in] rxring: Pointer to DMA channel Rx ring. - * @param[in] chan: DMA Rx channel number. - * @param[in] dma_buf_len: Rx DMA buffer length. - * @param[in] rxpkt_cx: Received packet context. - * @param[out] rx_pkt_swcx: Received packet sw context. - * - * @pre Rx completion need to make sure that Rx descriptors processed properly. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -void osd_receive_packet(void *priv, void *rxring, nveu32_t chan, - nveu32_t dma_buf_len, void *rxpkt_cx, - void *rx_pkt_swcx); - -/** - * @brief osd_transmit_complete - Transmit completion routine. - * - * @note - * Algorithm: - * - Unmap and free the buffer DMA address and buffer (not needed if buffers - * are allocated statically). - * - Time stamp will be updated to stack if available. - * - * @param[in] priv: OSD private data structure. - * @param[in] buffer: Buffer address to free. - * @param[in] dmaaddr: DMA address to unmap. - * @param[in] len: Length of data. - * @param[out] txdone_pkt_cx: Pointer to struct which has tx done status info. - * This struct has flags to indicate tx error, whether DMA address - * is mapped from paged/linear buffer, Time stamp availability, - * if TS available txdone_pkt_cx->ns stores the time stamp. - * Below are the valid bit maps set for txdone_pkt_cx->flags - * OSI_TXDONE_CX_PAGED_BUF OSI_BIT(0) - * OSI_TXDONE_CX_ERROR OSI_BIT(1) - * OSI_TXDONE_CX_TS OSI_BIT(2) - * - * @pre Tx completion need to make sure that Tx descriptors processed properly. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -void osd_transmit_complete(void *priv, void *buffer, nveu64_t dmaaddr, - nveu32_t len, void *txdone_pkt_cx); -/** - * @brief osd_log - OSD logging function - * - * @param[in] priv: OSD private data - * @param[in] func: function name - * @param[in] line: line number - * @param[in] level: log level - * @param[in] type: error type - * @param[in] err: error string - * @param[in] loga: error additional information - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: Yes - */ -void osd_log(void *priv, - const nve8_t *func, - nveu32_t line, - nveu32_t level, - nveu32_t type, - const nve8_t *err, - nveul64_t loga); -#endif /* INCLUDED_OSD_H */ diff --git a/osi/common/osd_dummy.c b/osi/common/osd_dummy.c deleted file mode 100644 index 49bde82..0000000 --- a/osi/common/osd_dummy.c +++ /dev/null @@ -1,58 +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. - */ -#ifdef OSD_DUMMY -#include <osd.h> -#include "../osi/common/type.h" - -void osd_usleep_range(nveu64_t umin, nveu64_t umax) -{ -} - -void osd_msleep(nveu32_t msec) -{ -} - -void osd_udelay(nveu64_t usec) -{ -} - -void osd_receive_packet(void *priv, void *rxring, nveu32_t chan, - nveu32_t dma_buf_len, void *rxpkt_cx, - void *rx_pkt_swcx) -{ -} - -void osd_transmit_complete(void *priv, void *buffer, nveu64_t dmaaddr, - nveu32_t len, void *txdone_pkt_cx) -{ -} - -void osd_log(void *priv, - const nve8_t *func, - nveu32_t line, - nveu32_t level, - nveu32_t type, - const nve8_t *err, - nveul64_t loga) -{ -} -#endif diff --git a/osi/common/osi_common.c b/osi/common/osi_common.c index e932a10..65c55a6 100644 --- a/osi/common/osi_common.c +++ b/osi/common/osi_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -20,7 +20,6 @@ * DEALINGS IN THE SOFTWARE. */ -#include <osd.h> #include "eqos_common.h" #include "../osi/common/common.h" diff --git a/osi/core/Makefile.tmk b/osi/core/Makefile.tmk index 0055aa6..3083f2d 100644 --- a/osi/core/Makefile.tmk +++ b/osi/core/Makefile.tmk @@ -1,6 +1,6 @@ ################################### tell Emacs this is a -*- makefile-gmake -*- # -# Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2019-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"), @@ -26,7 +26,7 @@ ifdef NV_COMPONENT_FLAG_SHARED_LIBRARY_SECTION include $(NV_BUILD_START_COMPONENT) NV_COMPONENT_STRICT_WARNINGS_qnx_64 := 1 -NV_COMPONENT_CFLAGS := -DOSI_STRIPPED_LIB -DOSD_DUMMY +NV_COMPONENT_CFLAGS := -DOSI_STRIPPED_LIB NV_COMPONENT_NAME := nvethernetrm NV_COMPONENT_OWN_INTERFACE_DIR := . @@ -35,7 +35,6 @@ NV_COMPONENT_SOURCES := \ eqos_mmc.c \ osi_core.c \ $(NV_SOURCE)/nvethernetrm/osi/common/osi_common.c \ - $(NV_SOURCE)/nvethernetrm/osi/common/osd_dummy.c \ $(NV_SOURCE)/nvethernetrm/osi/common/eqos_common.c NV_COMPONENT_INCLUDES := \ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 8b325c7..b29ab4c 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -22,7 +22,6 @@ #include "../osi/common/common.h" #include <osi_core.h> -#include <osd.h> #include "eqos_core.h" #include "eqos_mmc.h" diff --git a/osi/core/eqos_mmc.c b/osi/core/eqos_mmc.c index b0fc915..24e1a6d 100644 --- a/osi/core/eqos_mmc.c +++ b/osi/core/eqos_mmc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -22,7 +22,6 @@ #include "../osi/common/common.h" #include <osi_core.h> -#include <osd.h> #include "eqos_mmc.h" #include "eqos_core.h" diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index 23cf04f..01f5065 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -22,7 +22,6 @@ #include <osi_common.h> #include <osi_core.h> -#include <osd.h> #include <ivc_core.h> #include "eqos_core.h" #include "eqos_mmc.h" diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index fa47831..fdd529c 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -21,7 +21,6 @@ */ #include <osi_core.h> -#include <osd.h> #include <local_common.h> #include <ivc_core.h> @@ -52,27 +51,17 @@ nve32_t osi_read_phy_reg(struct osi_core_priv_data *const osi_core, nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core) { - /* - * Currently these osd_ops are optional to be filled in the OSD layer. - * If OSD updates these pointers, use the same. If not, fall back to the - * existing way of using osd_* API's. - * TODO: Once These API's are mandatory, return errors instead of - * default API usage. - */ if (osi_core == OSI_NULL) { return -1; } - if (osi_core->osd_ops.ops_log == OSI_NULL) { - osi_core->osd_ops.ops_log = osd_log; - } - if (osi_core->osd_ops.udelay == OSI_NULL) { - osi_core->osd_ops.udelay = osd_udelay; - } - if (osi_core->osd_ops.msleep == OSI_NULL) { - osi_core->osd_ops.msleep = osd_msleep; - } - if (osi_core->osd_ops.usleep_range == OSI_NULL) { - osi_core->osd_ops.usleep_range = osd_usleep_range; + + if ((osi_core->osd_ops.ops_log == OSI_NULL) || + (osi_core->osd_ops.udelay == OSI_NULL) || + (osi_core->osd_ops.msleep == OSI_NULL) || + (osi_core->osd_ops.usleep_range == OSI_NULL)) { + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "CORE OSD ops not assigned\n", 0ULL); + return -1; } if (osi_core->mac == OSI_MAC_HW_EQOS) { diff --git a/osi/dma/Makefile.tmk b/osi/dma/Makefile.tmk index 2a61e70..99677cf 100644 --- a/osi/dma/Makefile.tmk +++ b/osi/dma/Makefile.tmk @@ -1,6 +1,6 @@ ################################### tell Emacs this is a -*- makefile-gmake -*- # -# Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2019-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"), @@ -26,7 +26,7 @@ ifdef NV_COMPONENT_FLAG_SHARED_LIBRARY_SECTION include $(NV_BUILD_START_COMPONENT) NV_COMPONENT_STRICT_WARNINGS_qnx_64 := 1 -NV_COMPONENT_CFLAGS := -DOSI_STRIPPED_LIB -DOSD_DUMMY +NV_COMPONENT_CFLAGS := -DOSI_STRIPPED_LIB NV_COMPONENT_NAME := nvethernetcl NV_COMPONENT_OWN_INTERFACE_DIR := . @@ -35,7 +35,6 @@ NV_COMPONENT_SOURCES := \ osi_dma.c \ osi_dma_txrx.c \ $(NV_SOURCE)/nvethernetrm/osi/common/osi_common.c \ - $(NV_SOURCE)/nvethernetrm/osi/common/osd_dummy.c \ $(NV_SOURCE)/nvethernetrm/osi/common/eqos_common.c NV_COMPONENT_INCLUDES := \ diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 42f53fc..ad1227a 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -21,7 +21,6 @@ */ #include "osi_dma_local.h" -#include <osd.h> #include <local_common.h> #include "hw_desc.h" @@ -30,24 +29,14 @@ nve32_t osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) if (osi_dma == OSI_NULL) { return -1; } - /* - * Currently these osd_ops are optional to be filled in the OSD layer. - * If OSD updates these pointers, use the same. If not, fall back to the - * existing way of using osd_* API's. - * TODO: Once These API's are mandatory, return errors instead of - * default API usage. - */ - if (osi_dma->osd_ops.transmit_complete == OSI_NULL) { - osi_dma->osd_ops.transmit_complete = osd_transmit_complete; - } - if (osi_dma->osd_ops.receive_packet == OSI_NULL) { - osi_dma->osd_ops.receive_packet = osd_receive_packet; - } - if (osi_dma->osd_ops.ops_log == OSI_NULL) { - osi_dma->osd_ops.ops_log = osd_log; - } - if (osi_dma->osd_ops.udelay == OSI_NULL) { - osi_dma->osd_ops.udelay = osd_udelay; + + 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) || + (osi_dma->osd_ops.udelay == OSI_NULL)) { + OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "DMA OSD ops not assigned\n", 0ULL); + return -1; } if (osi_dma->mac == OSI_MAC_HW_EQOS) { diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 3e4ce75..edae81d 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -20,7 +20,6 @@ * DEALINGS IN THE SOFTWARE. */ -#include <osd.h> #include "osi_dma_local.h" #include <osi_dma_txrx.h> #include "../osi/common/type.h" From 1c462d30deb34adc9f487b65c7b2a5a5f0f495e9 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Mon, 1 Mar 2021 15:27:12 +0530 Subject: [PATCH 148/458] osi: rename osi_dma_local.h to dma_local.h osi_dma_local.h is not shared with OSD so renaming it to dma_local.h. Bug 200671160 Change-Id: I73feb883b1628e638c3175033e5810dc3044c870 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2491204 Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/dma/{osi_dma_local.h => dma_local.h} | 8 ++++---- osi/dma/eqos_dma.c | 4 ++-- osi/dma/osi_dma.c | 2 +- osi/dma/osi_dma_txrx.c | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) rename osi/dma/{osi_dma_local.h => dma_local.h} (92%) diff --git a/osi/dma/osi_dma_local.h b/osi/dma/dma_local.h similarity index 92% rename from osi/dma/osi_dma_local.h rename to osi/dma/dma_local.h index 671c2ae..7d3195b 100644 --- a/osi/dma/osi_dma_local.h +++ b/osi/dma/dma_local.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2019-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"), @@ -21,8 +21,8 @@ */ -#ifndef INCLUDED_OSI_DMA_LOCAL_H -#define INCLUDED_OSI_DMA_LOCAL_H +#ifndef INCLUDED_DMA_LOCAL_H +#define INCLUDED_DMA_LOCAL_H #include <osi_dma.h> #include "eqos_dma.h" @@ -68,4 +68,4 @@ nve32_t dma_desc_init(struct osi_dma_priv_data *osi_dma); #define H32(data) (((data) & 0xFFFFFFFF00000000UL) >> 32UL) /** @} */ -#endif /* INCLUDED_OSI_DMA_LOCAL_H */ +#endif /* INCLUDED_DMA_LOCAL_H */ diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index 5ed0c7d..7d26f0b 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -21,7 +21,7 @@ */ #include "../osi/common/common.h" -#include "osi_dma_local.h" +#include "dma_local.h" #include "eqos_dma.h" #include "../osi/common/type.h" diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index ad1227a..be92b35 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -20,7 +20,7 @@ * DEALINGS IN THE SOFTWARE. */ -#include "osi_dma_local.h" +#include "dma_local.h" #include <local_common.h> #include "hw_desc.h" diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index edae81d..bbf2183 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -20,7 +20,7 @@ * DEALINGS IN THE SOFTWARE. */ -#include "osi_dma_local.h" +#include "dma_local.h" #include <osi_dma_txrx.h> #include "../osi/common/type.h" #include "hw_desc.h" From 14f927318aec3d9e42c547fdbb9bb1bf09eb0fea Mon Sep 17 00:00:00 2001 From: nannaiah <nannaiah@nvidia.com> Date: Tue, 26 Jan 2021 16:38:09 -0800 Subject: [PATCH 149/458] Enable IVC core functionality for QNX 1. Enable IVC core. 2. Move ivc_flush_mtl_tx_queue and ivc_reset_mmc under macro to fix build failures. Bug 2694285 Change-Id: Id090831bc3f8150bb381fba70537beb34aa9ccc0 Signed-off-by: Nagaraj Annaiah <nannaiah@nvidia.com> Change-Id: Id090831bc3f8150bb381fba70537beb34aa9ccc0 Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2475827 GVS: Gerrit_Virtual_Submit Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/Makefile.sdk | 3 +- osi/core/Makefile.tmk | 1 + osi/core/ivc_core.c | 111 +++++++++++++++++++++--------------------- osi/core/osi_core.c | 2 - 4 files changed, 58 insertions(+), 59 deletions(-) diff --git a/osi/core/Makefile.sdk b/osi/core/Makefile.sdk index 521be39..d3fa4a2 100644 --- a/osi/core/Makefile.sdk +++ b/osi/core/Makefile.sdk @@ -1,4 +1,4 @@ -# Copyright (c) 2020 NVIDIA CORPORATION. All Rights Reserved. +# Copyright (c) 2020-2021 NVIDIA CORPORATION. All Rights Reserved. # # NVIDIA CORPORATION and its licensors retain all intellectual property # and proprietary rights in and to this software, related documentation @@ -21,6 +21,7 @@ LDFLAGS += -shared OBJS := eqos_core.o OBJS += eqos_mmc.o OBJS += osi_core.o +OBJS += ivc_core.o OBJS += ./../common/osi_common.o OBJS += ./../common/eqos_common.o diff --git a/osi/core/Makefile.tmk b/osi/core/Makefile.tmk index 3083f2d..cc1d181 100644 --- a/osi/core/Makefile.tmk +++ b/osi/core/Makefile.tmk @@ -34,6 +34,7 @@ NV_COMPONENT_SOURCES := \ eqos_core.c \ eqos_mmc.c \ osi_core.c \ + ivc_core.c \ $(NV_SOURCE)/nvethernetrm/osi/common/osi_common.c \ $(NV_SOURCE)/nvethernetrm/osi/common/eqos_common.c diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index 01f5065..9900d52 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -191,38 +191,6 @@ static nve32_t ivc_pad_calibrate(struct osi_core_priv_data *const osi_core) sizeof(msg_common)); } -/** - * @brief ivc_flush_mtl_tx_queue - Flush MTL Tx queue - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] qinx: MTL queue index. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t ivc_flush_mtl_tx_queue( - struct osi_core_priv_data *const osi_core, - const nveu32_t qinx) -{ - ivc_msg_common msg_common; - nve32_t index = 0; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - msg_common.cmd = flush_mtl_tx_queue; - msg_common.data.args.arguments[index++] = qinx; - msg_common.data.args.count = index; - - return osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); -} - /** * @brief ivc_config_rxcsum_offload - Enable/Disale rx checksum offload in HW * @@ -871,7 +839,7 @@ static void ivc_config_ssir(struct osi_core_priv_data *const osi_core) * 1) MAC should be init and started. see osi_start_mac() * 2) osi_core->osd should be populated */ -void ivc_read_mmc(struct osi_core_priv_data *osi_core) +static void ivc_read_mmc(struct osi_core_priv_data *osi_core) { ivc_msg_common msg_common; @@ -884,29 +852,6 @@ void ivc_read_mmc(struct osi_core_priv_data *osi_core) } -/** - * @brief ivc_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 ivc_reset_mmc(struct osi_core_priv_data *osi_core) -{ - ivc_msg_common msg_common; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - msg_common.cmd = reset_mmc; - - osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); -} - - /** * @brief ivc_core_deinit - EQOS MAC core deinitialization * @@ -1115,6 +1060,38 @@ static nve32_t ivc_config_rx_crc_check( sizeof(msg_common)); } +/** + * @brief ivc_flush_mtl_tx_queue - Flush MTL Tx queue + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] qinx: MTL queue index. + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: No + * - De-initialization: No + * + * @retval 0 on success + * @retval -1 on failure. + */ +static nve32_t ivc_flush_mtl_tx_queue( + struct osi_core_priv_data *const osi_core, + const nveu32_t qinx) +{ + ivc_msg_common msg_common; + nve32_t index = 0; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = flush_mtl_tx_queue; + msg_common.data.args.arguments[index++] = qinx; + msg_common.data.args.count = index; + + return osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + /** * @brief ivc_config_tx_status - Configure MAC to forward the tx pkt status * @@ -1294,6 +1271,28 @@ static inline nve32_t ivc_update_vlan_id( sizeof(msg_common)); } +/** + * @brief ivc_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 + */ +static void ivc_reset_mmc(struct osi_core_priv_data *osi_core) +{ + ivc_msg_common msg_common; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = reset_mmc; + + osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); +} + /** * @brief ivc_configure_eee - Configure the EEE LPI mode * diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index fdd529c..3f4fba7 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -75,7 +75,6 @@ nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core) osi_core->safety_config = (void *)eqos_get_core_safety_config(); } else { -#ifdef LINUX_IVC /* Get IVC HW ops */ osi_core->ops = ivc_get_hw_core_ops(); /* Explicitly set osi_core->safety_config = OSI_NULL if @@ -84,7 +83,6 @@ nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core) */ osi_core->safety_config = (void *)ivc_get_core_safety_config(); -#endif } return 0; } From 96bc09db1f6005b3f47d0b18f4368a711f5db678 Mon Sep 17 00:00:00 2001 From: nannaiah <nannaiah@nvidia.com> Date: Thu, 18 Feb 2021 08:18:19 -0800 Subject: [PATCH 150/458] Add fix to misra & cert errors for ethernet server Bug 2694285 Change-Id: I6b899538ed92f67351cc21ccbb900d842e91ad5d Signed-off-by: Nagaraj annaiah <nannaiah@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2486524 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/ivc_core.h | 8 ++++---- osi/core/eqos_core.h | 4 ++-- osi/core/eqos_mmc.h | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/ivc_core.h b/include/ivc_core.h index 0dcef0f..3f73133 100644 --- a/include/ivc_core.h +++ b/include/ivc_core.h @@ -37,7 +37,7 @@ /** * @brief IVC commands between OSD & OSI. */ -enum ivc_cmd { +typedef enum ivc_cmd { poll_for_swr = 1, core_init, core_deinit, @@ -85,7 +85,7 @@ enum ivc_cmd { set_mdc_clk_rate, config_mac_loopback, #endif /* !OSI_STRIPPED_LIB */ -}; +}ivc_cmd; /** * @brief IVC arguments structure. @@ -133,11 +133,11 @@ 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. */ - nveu32_t status; + nve32_t status; /** * ID of the CMD. */ - nveu32_t cmd; + ivc_cmd cmd; /** * message count, used for debug */ diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 38c361a..ef7f51c 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -93,8 +93,8 @@ */ #define EQOS_MAC_MCR 0x0000 #define EQOS_MAC_EXTR 0x0004 -#define EQOS_MAC_PFR 0x0008U -#define EQOS_MAC_WATCH 0x000CU +#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 diff --git a/osi/core/eqos_mmc.h b/osi/core/eqos_mmc.h index 45b5dd1..a76630d 100644 --- a/osi/core/eqos_mmc.h +++ b/osi/core/eqos_mmc.h @@ -29,7 +29,7 @@ * @brief MMC HW register offsets * @{ */ -#define MMC_TXOCTETCOUNT_GB 0x00714 +#define MMC_TXOCTETCOUNT_GB 0x00714U #define MMC_TXPACKETCOUNT_GB 0x00718 #define MMC_TXBROADCASTPACKETS_G 0x0071c #define MMC_TXMULTICASTPACKETS_G 0x00720 @@ -112,7 +112,7 @@ #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_RXICMP_ERR_OCTETS 0x00884U /** @} */ void eqos_read_mmc(struct osi_core_priv_data *const osi_core); From 61ae5e8674d9bded67d1bae8286a41d2a59bfe94 Mon Sep 17 00:00:00 2001 From: rakesh goyal <rgoyal@nvidia.com> Date: Tue, 16 Feb 2021 14:42:22 +0530 Subject: [PATCH 151/458] core: move get_hw_feat to osi_core No api from osi_common should be direclty accessible from OSD code. moving osi_get_hw_feat to osi core. Moving following API to common/common.h osi_memset() osi_memcpy() Bug 200671160 Change-Id: Idd6269b01ee8ec21c7f3c5b7f3376cf9a91bb661 Signed-off-by: rakesh goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2488875 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_common.h | 392 +--------------------------------------- include/osi_core.h | 319 +++++++++++++++++++++++++++++++- osi/common/common.h | 117 ++++++------ osi/common/osi_common.c | 34 ---- osi/core/core_local.h | 101 +++++++++++ osi/core/eqos_core.c | 128 +++++++++++++ osi/core/eqos_core.h | 184 ++++++++++++++++++- osi/core/osi_core.c | 134 ++------------ 8 files changed, 809 insertions(+), 600 deletions(-) create mode 100644 osi/core/core_local.h diff --git a/include/osi_common.h b/include/osi_common.h index a9bd520..4a0b42b 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -181,57 +181,6 @@ /** @} */ -/** - * @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_HFR0_MIISEL_MASK 0x1U -#define EQOS_MAC_HFR0_GMIISEL_MASK 0x1U -#define EQOS_MAC_HFR0_HDSEL_MASK 0x1U -#define EQOS_MAC_HFR0_PCSSEL_MASK 0x1U -#define EQOS_MAC_HFR0_SMASEL_MASK 0x1U -#define EQOS_MAC_HFR0_RWKSEL_MASK 0x1U -#define EQOS_MAC_HFR0_MGKSEL_MASK 0x1U -#define EQOS_MAC_HFR0_MMCSEL_MASK 0x1U -#define EQOS_MAC_HFR0_ARPOFFLDEN_MASK 0x1U -#define EQOS_MAC_HFR0_TSSSEL_MASK 0x1U -#define EQOS_MAC_HFR0_EEESEL_MASK 0x1U -#define EQOS_MAC_HFR0_TXCOESEL_MASK 0x1U -#define EQOS_MAC_HFR0_RXCOE_MASK 0x1U -#define EQOS_MAC_HFR0_ADDMACADRSEL_MASK 0x1fU -#define EQOS_MAC_HFR0_MACADR32SEL_MASK 0x1U -#define EQOS_MAC_HFR0_MACADR64SEL_MASK 0x1U -#define EQOS_MAC_HFR0_TSINTSEL_MASK 0x3U -#define EQOS_MAC_HFR0_SAVLANINS_MASK 0x1U -#define EQOS_MAC_HFR0_ACTPHYSEL_MASK 0x7U -#define EQOS_MAC_HFR1_RXFIFOSIZE_MASK 0x1fU -#define EQOS_MAC_HFR1_TXFIFOSIZE_MASK 0x1fU -#define EQOS_MAC_HFR1_ADVTHWORD_MASK 0x1U -#define EQOS_MAC_HFR1_ADDR64_MASK 0x3U -#define EQOS_MAC_HFR1_DCBEN_MASK 0x1U -#define EQOS_MAC_HFR1_SPHEN_MASK 0x1U -#define EQOS_MAC_HFR1_TSOEN_MASK 0x1U -#define EQOS_MAC_HFR1_DMADEBUGEN_MASK 0x1U -#define EQOS_MAC_HFR1_AVSEL_MASK 0x1U -#ifndef OSI_STRIPPED_LIB -#define EQOS_MAC_HFR1_LPMODEEN_MASK 0x1U -#endif /* OSI_STRIPPED_LIB */ -#define EQOS_MAC_HFR1_HASHTBLSZ_MASK 0x3U -#define EQOS_MAC_HFR1_L3L4FILTERNUM_MASK 0xfU -#define EQOS_MAC_HFR2_RXQCNT_MASK 0xfU -#define EQOS_MAC_HFR2_TXQCNT_MASK 0xfU -#define EQOS_MAC_HFR2_RXCHCNT_MASK 0xfU -#define EQOS_MAC_HFR2_TXCHCNT_MASK 0xfU -#define EQOS_MAC_HFR2_PPSOUTNUM_MASK 0x7U -#define EQOS_MAC_HFR2_AUXSNAPNUM_MASK 0x7U -/** @} */ - #ifndef OSI_STRIPPED_LIB /** * @addtogroup MTL queue operation mode @@ -256,343 +205,4 @@ /** @} */ #endif /* OSI_STRIPPED_LIB */ -/** - * @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; -}; - -/** - * @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 - */ -void osi_memset(void *s, nveu32_t c, nveu64_t count); - -/** - * @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 - */ -void osi_memcpy(void *dest, void *src, int n); #endif /* OSI_COMMON_H */ diff --git a/include/osi_core.h b/include/osi_core.h index f3fb1f7..38023b3 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -220,6 +220,316 @@ struct osi_l3_l4_filter { 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 @@ -445,6 +755,9 @@ struct osi_core_ops { 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); }; /** @@ -1454,9 +1767,11 @@ nve32_t osi_get_mac_version(struct osi_core_priv_data *const osi_core, * - Run time: Yes * - De-initialization: No * + * @retval 0 on success + * @retval -1 on failure. */ -void osi_get_hw_features(struct osi_core_priv_data *const osi_core, - struct osi_hw_features *hw_feat); +nve32_t osi_get_hw_features(struct osi_core_priv_data *const osi_core, + struct osi_hw_features *hw_feat); #ifndef OSI_STRIPPED_LIB /** diff --git a/osi/common/common.h b/osi/common/common.h index 8b3a962..f13f357 100644 --- a/osi/common/common.h +++ b/osi/common/common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -144,63 +144,6 @@ static inline void osi_writel(nveu32_t val, void *addr) *(volatile nveu32_t *)addr = val; } -/** - * @brief osi_read_reg - Read a MAC register. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] addr: MAC register - * - * @note - * Traceability Details: TODO - * - * @note - * Classification: - * - Interrupt: No - * - Signal handler: No - * - Thread safe: No - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: Yes - * - * @retval data from MAC register on success - * @retval -1 on failure - */ -nveu32_t osi_read_reg(struct osi_core_priv_data *const osi_core, - const nve32_t addr); - -/** - * @brief osi_write_reg - Write a MAC register. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] val: MAC register value - * @param[in] addr: MAC register - * - * @note - * Traceability Details: TODO - * - * @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 data from MAC register on success - * @retval -1 on failure - */ -nveu32_t osi_write_reg(struct osi_core_priv_data *const osi_core, - const nveu32_t val, const nve32_t addr); - #ifdef ETHERNET_SERVER nveu32_t osi_readla(void *priv, void *addr); @@ -306,4 +249,62 @@ static inline nveu64_t osi_update_stats_counter(nveu64_t last_value, return temp; } + +/** + * @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 void osi_memcpy(void *dest, void *src, int n) +{ + char *csrc = (char *)src; + char *cdest = (char *)dest; + int i = 0; + + if (src == OSI_NULL || dest == OSI_NULL) { + return; + } + for (i = 0; i < n; i++) { + cdest[i] = csrc[i]; + } +} #endif diff --git a/osi/common/osi_common.c b/osi/common/osi_common.c index 65c55a6..d06dc7b 100644 --- a/osi/common/osi_common.c +++ b/osi/common/osi_common.c @@ -23,40 +23,6 @@ #include "eqos_common.h" #include "../osi/common/common.h" - - -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--; - } -} - -void osi_memcpy(void *dest, void *src, int n) -{ - char *csrc = (char *)src; - char *cdest = (char *)dest; - int i = 0; - - if (src == OSI_NULL || dest == OSI_NULL) { - return; - } - for (i = 0; i < n; i++) { - cdest[i] = csrc[i]; - } -} - void common_get_systime_from_mac(void *addr, nveu32_t mac, nveu32_t *sec, nveu32_t *nsec) { diff --git a/osi/core/core_local.h b/osi/core/core_local.h new file mode 100644 index 0000000..f91a8ad --- /dev/null +++ b/osi/core/core_local.h @@ -0,0 +1,101 @@ +/* + * 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 CORE_LOCAL_INCLUDED +#define CORE_LOCAL_INCLUDED +#include <osi_core.h> + +/** + * @brief osi_read_reg - Read a MAC register. + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] addr: MAC register + * + * @note + * Traceability Details: TODO + * + * @note + * Classification: + * - Interrupt: No + * - Signal handler: No + * - Thread safe: No + * - Required Privileges: None + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: Yes + * - De-initialization: Yes + * + * @retval data from MAC register on success + * @retval -1 on failure + */ +static inline nveu32_t osi_read_reg(struct osi_core_priv_data *const osi_core, + const nve32_t addr) +{ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->read_reg != OSI_NULL) && + (osi_core->base != OSI_NULL)) { + return osi_core->ops->read_reg(osi_core, addr); + } + + return 0; +} + +/** + * @brief osi_write_reg - Write a MAC register. + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] val: MAC register value + * @param[in] addr: MAC register + * + * @note + * Traceability Details: TODO + * + * @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 data from MAC register on success + * @retval -1 on failure + */ +static inline nveu32_t osi_write_reg(struct osi_core_priv_data *const osi_core, + const nveu32_t val, const nve32_t addr) +{ + if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && + (osi_core->ops->write_reg != OSI_NULL) && + (osi_core->base != OSI_NULL)) { + return osi_core->ops->write_reg(osi_core, val, addr); + } + + return 0; +} +#endif /* CORE_LOCAL_INCLUDED */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index b29ab4c..3d0a555 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -4333,6 +4333,133 @@ static nve32_t eqos_config_mac_loopback( } #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; +} /** * @brief eqos_get_core_safety_config - EQOS MAC safety configuration @@ -4390,6 +4517,7 @@ struct osi_core_ops *eqos_get_hw_core_ops(void) .read_phy_reg = eqos_read_phy_reg, .read_reg = eqos_read_reg, .write_reg = eqos_write_reg, + .get_hw_features = eqos_get_hw_features, #ifndef OSI_STRIPPED_LIB .config_tx_status = eqos_config_tx_status, .config_rx_crc_check = eqos_config_rx_crc_check, diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index ef7f51c..710a99e 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -624,4 +624,186 @@ struct core_func_safety { #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 +/** @} */ + #endif /* INCLUDED_EQOS_CORE_H */ diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 3f4fba7..4d95505 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -20,9 +20,9 @@ * DEALINGS IN THE SOFTWARE. */ -#include <osi_core.h> #include <local_common.h> #include <ivc_core.h> +#include "core_local.h" nve32_t osi_write_phy_reg(struct osi_core_priv_data *const osi_core, const nveu32_t phyaddr, const nveu32_t phyreg, @@ -697,38 +697,21 @@ nve32_t osi_read_mmc(struct osi_core_priv_data *const osi_core) return -1; } -nveu32_t osi_read_reg(struct osi_core_priv_data *const osi_core, - const nve32_t addr) -{ - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->read_reg != OSI_NULL) && - (osi_core->base != OSI_NULL)) { - return osi_core->ops->read_reg(osi_core, addr); - } - return 0; -} - - -nveu32_t osi_write_reg(struct osi_core_priv_data *const osi_core, - const nveu32_t val, const nve32_t addr) -{ - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->write_reg != OSI_NULL) && - (osi_core->base != OSI_NULL)) { - return osi_core->ops->write_reg(osi_core, val, addr); - } - - return 0; -} nve32_t osi_get_mac_version(struct osi_core_priv_data *const osi_core, nveu32_t *mac_ver) { nveu32_t macver; - macver = osi_read_reg(osi_core, (nve32_t) MAC_VERSION) & - MAC_VERSION_SNVER_MASK; + if ((osi_core == OSI_NULL) || (osi_core->ops == OSI_NULL) || + (osi_core->ops->read_reg == OSI_NULL) || + (osi_core->base == OSI_NULL)) { + return -1; + } + macver = ((osi_core->ops->read_reg(osi_core, (nve32_t)MAC_VERSION)) & + MAC_VERSION_SNVER_MASK); + if (is_valid_mac_version(macver) == 0) { return -1; } @@ -737,94 +720,6 @@ nve32_t osi_get_mac_version(struct osi_core_priv_data *const osi_core, return 0; } -void osi_get_hw_features(struct osi_core_priv_data *const osi_core, - struct osi_hw_features *hw_feat) -{ - nveu32_t mac_hfr0; - nveu32_t mac_hfr1; - nveu32_t mac_hfr2; - - if (hw_feat != OSI_NULL) { - /* TODO: need to add HFR3 */ - mac_hfr0 = osi_read_reg(osi_core, EQOS_MAC_HFR0); - mac_hfr1 = osi_read_reg(osi_core, EQOS_MAC_HFR1); - mac_hfr2 = osi_read_reg(osi_core, EQOS_MAC_HFR2); - - hw_feat->mii_sel = - ((mac_hfr0 >> 0) & EQOS_MAC_HFR0_MIISEL_MASK); - hw_feat->gmii_sel = - ((mac_hfr0 >> 1U) & EQOS_MAC_HFR0_GMIISEL_MASK); - hw_feat->hd_sel = - ((mac_hfr0 >> 2U) & EQOS_MAC_HFR0_HDSEL_MASK); - hw_feat->pcs_sel = - ((mac_hfr0 >> 3U) & EQOS_MAC_HFR0_PCSSEL_MASK); - hw_feat->sma_sel = - ((mac_hfr0 >> 5U) & EQOS_MAC_HFR0_SMASEL_MASK); - hw_feat->rwk_sel = - ((mac_hfr0 >> 6U) & EQOS_MAC_HFR0_RWKSEL_MASK); - hw_feat->mgk_sel = - ((mac_hfr0 >> 7U) & EQOS_MAC_HFR0_MGKSEL_MASK); - hw_feat->mmc_sel = - ((mac_hfr0 >> 8U) & EQOS_MAC_HFR0_MMCSEL_MASK); - hw_feat->arp_offld_en = - ((mac_hfr0 >> 9U) & EQOS_MAC_HFR0_ARPOFFLDEN_MASK); - hw_feat->ts_sel = - ((mac_hfr0 >> 12U) & EQOS_MAC_HFR0_TSSSEL_MASK); - hw_feat->eee_sel = - ((mac_hfr0 >> 13U) & EQOS_MAC_HFR0_EEESEL_MASK); - hw_feat->tx_coe_sel = - ((mac_hfr0 >> 14U) & EQOS_MAC_HFR0_TXCOESEL_MASK); - hw_feat->rx_coe_sel = - ((mac_hfr0 >> 16U) & EQOS_MAC_HFR0_RXCOE_MASK); - hw_feat->mac_addr_sel = - ((mac_hfr0 >> 18U) & EQOS_MAC_HFR0_ADDMACADRSEL_MASK); - hw_feat->mac_addr32_sel = - ((mac_hfr0 >> 23U) & EQOS_MAC_HFR0_MACADR32SEL_MASK); - hw_feat->mac_addr64_sel = - ((mac_hfr0 >> 24U) & EQOS_MAC_HFR0_MACADR64SEL_MASK); - hw_feat->tsstssel = - ((mac_hfr0 >> 25U) & EQOS_MAC_HFR0_TSINTSEL_MASK); - hw_feat->sa_vlan_ins = - ((mac_hfr0 >> 27U) & EQOS_MAC_HFR0_SAVLANINS_MASK); - hw_feat->act_phy_sel = - ((mac_hfr0 >> 28U) & EQOS_MAC_HFR0_ACTPHYSEL_MASK); - hw_feat->rx_fifo_size = - ((mac_hfr1 >> 0) & EQOS_MAC_HFR1_RXFIFOSIZE_MASK); - hw_feat->tx_fifo_size = - ((mac_hfr1 >> 6U) & EQOS_MAC_HFR1_TXFIFOSIZE_MASK); - hw_feat->adv_ts_hword = - ((mac_hfr1 >> 13U) & EQOS_MAC_HFR1_ADVTHWORD_MASK); - hw_feat->addr_64 = - ((mac_hfr1 >> 14U) & EQOS_MAC_HFR1_ADDR64_MASK); - hw_feat->dcb_en = - ((mac_hfr1 >> 16U) & EQOS_MAC_HFR1_DCBEN_MASK); - hw_feat->sph_en = - ((mac_hfr1 >> 17U) & EQOS_MAC_HFR1_SPHEN_MASK); - hw_feat->tso_en = - ((mac_hfr1 >> 18U) & EQOS_MAC_HFR1_TSOEN_MASK); - hw_feat->dma_debug_gen = - ((mac_hfr1 >> 19U) & EQOS_MAC_HFR1_DMADEBUGEN_MASK); - hw_feat->av_sel = - ((mac_hfr1 >> 20U) & EQOS_MAC_HFR1_AVSEL_MASK); - hw_feat->hash_tbl_sz = - ((mac_hfr1 >> 24U) & EQOS_MAC_HFR1_HASHTBLSZ_MASK); - hw_feat->l3l4_filter_num = - ((mac_hfr1 >> 27U) & EQOS_MAC_HFR1_L3L4FILTERNUM_MASK); - hw_feat->rx_q_cnt = - ((mac_hfr2 >> 0) & EQOS_MAC_HFR2_RXQCNT_MASK); - hw_feat->tx_q_cnt = - ((mac_hfr2 >> 6U) & EQOS_MAC_HFR2_TXQCNT_MASK); - hw_feat->rx_ch_cnt = - ((mac_hfr2 >> 12U) & EQOS_MAC_HFR2_RXCHCNT_MASK); - hw_feat->tx_ch_cnt = - ((mac_hfr2 >> 18U) & EQOS_MAC_HFR2_TXCHCNT_MASK); - hw_feat->pps_out_num = - ((mac_hfr2 >> 24U) & EQOS_MAC_HFR2_PPSOUTNUM_MASK); - hw_feat->aux_snap_num = - ((mac_hfr2 >> 28U) & EQOS_MAC_HFR2_AUXSNAPNUM_MASK); - } -} - #ifndef OSI_STRIPPED_LIB nve32_t osi_validate_core_regs(struct osi_core_priv_data *const osi_core) { @@ -1041,3 +936,14 @@ nve32_t osi_config_mac_loopback(struct osi_core_priv_data *const osi_core, return -1; } #endif /* !OSI_STRIPPED_LIB */ + +nve32_t osi_get_hw_features(struct osi_core_priv_data *const osi_core, + struct osi_hw_features *hw_feat) +{ + if ((hw_feat == OSI_NULL) || (osi_core == OSI_NULL) || + (osi_core->ops->get_hw_features == OSI_NULL)) { + return -1; + } + + return osi_core->ops->get_hw_features(osi_core, hw_feat); +} From cdd961c165dfe6fe25faba45698cbeaf5c890583 Mon Sep 17 00:00:00 2001 From: Srinivas Ramachandran <srinivasra@nvidia.com> Date: Thu, 25 Feb 2021 22:42:43 -0800 Subject: [PATCH 152/458] nvethernetrm: Mask packet type before setting Rx pkt flags Issue: Packet type is a multi-bit field and the value of certain bits should be compared for direct decimal value across all bits, rather than selectively checking that bit alone. Fix: Mask the entire bit field length before setting the Rx pkt context flags. Bug 3266454 Change-Id: I739ad1a23abfcde5db516f00bcbe88085b405d82 Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2489996 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/dma/hw_desc.h | 1 + osi/dma/osi_dma_txrx.c | 32 +++++++++++++++++++------------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/osi/dma/hw_desc.h b/osi/dma/hw_desc.h index adadbcb..e8cb6b5 100644 --- a/osi/dma/hw_desc.h +++ b/osi/dma/hw_desc.h @@ -58,6 +58,7 @@ #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) /** @} */ diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index bbf2183..49d02a8 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -49,6 +49,8 @@ static inline void 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 @@ -72,24 +74,28 @@ static inline void get_rx_csum(struct osi_rx_desc *rx_desc, rx_pkt_cx->rxcsum |= OSI_CHECKSUM_IPv4_BAD; } - if ((rx_desc->rdes1 & RDES1_PT_UDP) == RDES1_PT_UDP) { - if ((rx_desc->rdes1 & RDES1_IPV4) == RDES1_IPV4) { + 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 ((rx_desc->rdes1 & RDES1_IPV6) == RDES1_IPV6) { - rx_pkt_cx->rxcsum |= OSI_CHECKSUM_UDPv6; - } else { - /* Do nothing here */ - } - } else if ((rx_desc->rdes1 & RDES1_PT_TCP) == RDES1_PT_TCP) { - if ((rx_desc->rdes1 & RDES1_IPV4) == RDES1_IPV4) { + } else if (pkt_type == RDES1_PT_TCP) { rx_pkt_cx->rxcsum |= OSI_CHECKSUM_TCPv4; - } else if ((rx_desc->rdes1 & RDES1_IPV6) == RDES1_IPV6) { - rx_pkt_cx->rxcsum |= OSI_CHECKSUM_TCPv6; + } else { - /* Do nothing here */ + /* 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 here */ + /* Do nothing */ } if ((rx_desc->rdes1 & RDES1_IPCE) == RDES1_IPCE) { From 2980e1b0e2c30f9b798dce38b9cb7288e3d5c3fa Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Wed, 24 Feb 2021 23:42:21 +0530 Subject: [PATCH 153/458] osi: don't expose core_ops to OSD Issue: Currently OSD has access to osi_core_ops so these operations can be changed by OSD. Also each entry funnction has checks for validating these function pointers which would increase the unit tests and complexity as well. Fix: Move dma_ops to inside OSI and set a flag indicate that CORE software init done. Each entry function needs to check only flag Bug 200671160 Change-Id: I6def9e5c39f90a08eb4f48a124a1c2c8c65175a4 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2435991 Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/ivc_core.h | 12 +- include/osi_core.h | 177 ----------- osi/core/core_local.h | 261 ++++++++++++---- osi/core/eqos_core.c | 120 +++---- osi/core/ivc_core.c | 111 +++---- osi/core/osi_core.c | 708 +++++++++++++++++++++--------------------- 6 files changed, 652 insertions(+), 737 deletions(-) diff --git a/include/ivc_core.h b/include/ivc_core.h index 3f73133..c825be6 100644 --- a/include/ivc_core.h +++ b/include/ivc_core.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -191,14 +191,4 @@ nve32_t osd_ivc_send_cmd(void *priv, void *data, nveu32_t len); * - De-initialization: Yes */ void *ivc_get_core_safety_config(void); - -/** - * @brief ivc_get_hw_core_ops - Get hw core operations - * - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: Yes - */ -struct osi_core_ops *ivc_get_hw_core_ops(void); #endif /* IVC_CORE_H */ diff --git a/include/osi_core.h b/include/osi_core.h index 38023b3..04d2a52 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -586,180 +586,6 @@ struct osi_core_avb_algorithm { }; #endif /* !OSI_STRIPPED_LIB */ -/** - * @brief Initialize MAC & MTL core operations. - */ -struct osi_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 (10/100/1000) at MAC */ - void (*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); - /** 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); -#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 update VLAN id */ - nve32_t (*update_vlan_id)(struct osi_core_priv_data *const osi_core, - const nveu32_t vid); - /** 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); -}; - /** * @brief PTP configuration structure */ @@ -849,8 +675,6 @@ struct osi_core_priv_data { void *base; /** Pointer to OSD private data structure */ void *osd; - /** Address of HW Core operations structure */ - struct osi_core_ops *ops; /** OSD callback ops structure */ struct osd_core_ops osd_ops; /** Number of MTL queues enabled in MAC */ @@ -1649,7 +1473,6 @@ nve32_t osi_ptp_configuration(struct osi_core_priv_data *const osi_core, * 1. Visible prototype for all functions. * 2. Only one prototype for all function. */ -struct osi_core_ops *eqos_get_hw_core_ops(void); void *eqos_get_core_safety_config(void); /** diff --git a/osi/core/core_local.h b/osi/core/core_local.h index f91a8ad..36faec2 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -20,82 +20,219 @@ * DEALINGS IN THE SOFTWARE. */ -#ifndef CORE_LOCAL_INCLUDED -#define CORE_LOCAL_INCLUDED +#ifndef INCLUDED_CORE_LOCAL_H +#define INCLUDED_CORE_LOCAL_H + #include <osi_core.h> /** - * @brief osi_read_reg - Read a MAC register. + * @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 (10/100/1000) at MAC */ + void (*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); + /** 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); +#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 update VLAN id */ + nve32_t (*update_vlan_id)(struct osi_core_priv_data *const osi_core, + const nveu32_t vid); + /** 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); +}; + + +/** + * @brief Core local data structure. + */ +struct core_local { + /** Core local operations variable */ + struct core_ops ops; + /** Flag to represent initialization done or not */ + unsigned int init_done; +}; + +/** + * @brief eqos_init_core_ops - Initialize EQOS core operations. * - * @param[in] osi_core: OSI core private data structure. - * @param[in] addr: MAC register - * - * @note - * Traceability Details: TODO - * - * @note - * Classification: - * - Interrupt: No - * - Signal handler: No - * - Thread safe: No - * - Required Privileges: None + * @param[in] ops: Core operations pointer. * * @note * API Group: * - Initialization: Yes - * - Run time: Yes - * - De-initialization: Yes - * - * @retval data from MAC register on success - * @retval -1 on failure + * - Run time: No + * - De-initialization: No */ -static inline nveu32_t osi_read_reg(struct osi_core_priv_data *const osi_core, - const nve32_t addr) -{ - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->read_reg != OSI_NULL) && - (osi_core->base != OSI_NULL)) { - return osi_core->ops->read_reg(osi_core, addr); - } - - return 0; -} +void eqos_init_core_ops(struct core_ops *ops); /** - * @brief osi_write_reg - Write a MAC register. + * @brief ivc_init_core_ops - Initialize IVC core operations. * - * @param[in] osi_core: OSI core private data structure. - * @param[in] val: MAC register value - * @param[in] addr: MAC register - * - * @note - * Traceability Details: TODO - * - * @note - * Classification: - * - Interrupt: No - * - Signal handler: No - * - Thread safe: No - * - Required Privileges: None + * @param[in] ops: Core operations pointer. * * @note * API Group: - * - Initialization: No - * - Run time: Yes + * - Initialization: Yes + * - Run time: No * - De-initialization: No - * - * @retval data from MAC register on success - * @retval -1 on failure */ -static inline nveu32_t osi_write_reg(struct osi_core_priv_data *const osi_core, - const nveu32_t val, const nve32_t addr) -{ - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->write_reg != OSI_NULL) && - (osi_core->base != OSI_NULL)) { - return osi_core->ops->write_reg(osi_core, val, addr); - } - - return 0; -} -#endif /* CORE_LOCAL_INCLUDED */ +void ivc_init_core_ops(struct core_ops *ops); +#endif /* INCLUDED_CORE_LOCAL_H */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 3d0a555..e7dd783 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -24,6 +24,7 @@ #include <osi_core.h> #include "eqos_core.h" #include "eqos_mmc.h" +#include "core_local.h" /** * @brief eqos_core_safety_config - EQOS MAC core safety configuration @@ -3922,12 +3923,6 @@ static nve32_t eqos_config_arp_offload( nve32_t mac_mcr; nve32_t val; - if (enable != OSI_ENABLE && enable != OSI_DISABLE) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "arp_offload: invalid input\n", 0ULL); - return -1; - } - mac_mcr = osi_readla(osi_core, (nveu8_t *)addr + EQOS_MAC_MCR); if (enable == OSI_ENABLE) { @@ -4294,11 +4289,6 @@ static nve32_t eqos_config_mac_loopback( nveu32_t mcr_val; 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 */ mcr_val = osi_readla(osi_core, (nveu8_t *)addr + EQOS_MAC_MCR); @@ -4475,68 +4465,54 @@ void *eqos_get_core_safety_config(void) return &eqos_core_safety_config; } -/** - * @brief eqos_get_hw_core_ops - EQOS MAC get core operations - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - */ -struct osi_core_ops *eqos_get_hw_core_ops(void) +void eqos_init_core_ops(struct core_ops *ops) { - static struct osi_core_ops eqos_core_ops = { - .poll_for_swr = eqos_poll_for_swr, - .core_init = eqos_core_init, - .core_deinit = eqos_core_deinit, - .start_mac = eqos_start_mac, - .stop_mac = eqos_stop_mac, - .handle_common_intr = eqos_handle_common_intr, - .set_mode = eqos_set_mode, - .set_speed = eqos_set_speed, - .pad_calibrate = eqos_pad_calibrate, - .config_fw_err_pkts = eqos_config_fw_err_pkts, - .config_rxcsum_offload = eqos_config_rxcsum_offload, - .config_mac_pkt_filter_reg = eqos_config_mac_pkt_filter_reg, - .update_mac_addr_low_high_reg = - eqos_update_mac_addr_low_high_reg, - .config_l3_l4_filter_enable = eqos_config_l3_l4_filter_enable, - .config_l3_filters = eqos_config_l3_filters, - .update_ip4_addr = eqos_update_ip4_addr, - .update_ip6_addr = eqos_update_ip6_addr, - .config_l4_filters = eqos_config_l4_filters, - .update_l4_port_no = eqos_update_l4_port_no, - .set_systime_to_mac = eqos_set_systime_to_mac, - .config_addend = eqos_config_addend, - .adjust_mactime = eqos_adjust_mactime, - .config_tscr = eqos_config_tscr, - .config_ssir = eqos_config_ssir, - .read_mmc = eqos_read_mmc, - .write_phy_reg = eqos_write_phy_reg, - .read_phy_reg = eqos_read_phy_reg, - .read_reg = eqos_read_reg, - .write_reg = eqos_write_reg, - .get_hw_features = eqos_get_hw_features, + 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; + ops->get_hw_features = eqos_get_hw_features; #ifndef OSI_STRIPPED_LIB - .config_tx_status = eqos_config_tx_status, - .config_rx_crc_check = eqos_config_rx_crc_check, - .config_flow_control = eqos_config_flow_control, - .config_arp_offload = eqos_config_arp_offload, - .validate_regs = eqos_validate_core_regs, - .flush_mtl_tx_queue = eqos_flush_mtl_tx_queue, - .set_avb_algorithm = eqos_set_avb_algorithm, - .get_avb_algorithm = eqos_get_avb_algorithm, - .config_vlan_filtering = eqos_config_vlan_filtering, - .update_vlan_id = eqos_update_vlan_id, - .reset_mmc = eqos_reset_mmc, - .configure_eee = eqos_configure_eee, - .save_registers = eqos_save_registers, - .restore_registers = eqos_restore_registers, - .set_mdc_clk_rate = eqos_set_mdc_clk_rate, - .config_mac_loopback = eqos_config_mac_loopback, + 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->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->update_vlan_id = eqos_update_vlan_id; + 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 */ - }; - - return &eqos_core_ops; } diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index 9900d52..6753e7a 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -25,6 +25,7 @@ #include <ivc_core.h> #include "eqos_core.h" #include "eqos_mmc.h" +#include "core_local.h" /** * @brief ivc_safety_config - EQOS MAC core safety configuration @@ -1420,56 +1421,64 @@ static nve32_t ivc_config_mac_loopback( sizeof(msg_common)); } #endif + /** - * @brief ivc_ops - EQOS MAC core operations + * @brief ivc_init_core_ops - Initialize IVC core operations. + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: No + * - De-initialization: No */ -static struct osi_core_ops ivc_ops = { - .poll_for_swr = ivc_poll_for_swr, - .core_init = ivc_core_init, - .core_deinit = ivc_core_deinit, - .start_mac = ivc_start_mac, - .stop_mac = ivc_stop_mac, - .handle_common_intr = ivc_handle_common_intr, - .set_mode = ivc_set_mode, - .set_speed = ivc_set_speed, - .pad_calibrate = ivc_pad_calibrate, - .config_fw_err_pkts = ivc_config_fw_err_pkts, - .config_rxcsum_offload = ivc_config_rxcsum_offload, - .config_mac_pkt_filter_reg = ivc_config_mac_pkt_filter_reg, - .update_mac_addr_low_high_reg = ivc_update_mac_addr_low_high_reg, - .config_l3_l4_filter_enable = ivc_config_l3_l4_filter_enable, - .config_l3_filters = ivc_config_l3_filters, - .update_ip4_addr = ivc_update_ip4_addr, - .update_ip6_addr = ivc_update_ip6_addr, - .config_l4_filters = ivc_config_l4_filters, - .update_l4_port_no = ivc_update_l4_port_no, - .set_systime_to_mac = ivc_set_systime_to_mac, - .config_addend = ivc_config_addend, - .adjust_mactime = ivc_adjust_mactime, - .config_tscr = ivc_config_tscr, - .config_ssir = ivc_config_ssir, - .read_mmc = ivc_read_mmc, - .write_phy_reg = ivc_write_phy_reg, - .read_phy_reg = ivc_read_phy_reg, - .read_reg = ivc_read_reg, - .write_reg = ivc_write_reg, +void ivc_init_core_ops(struct core_ops *ops) +{ + ops->poll_for_swr = ivc_poll_for_swr; + ops->core_init = ivc_core_init; + ops->core_deinit = ivc_core_deinit; + ops->start_mac = ivc_start_mac; + ops->stop_mac = ivc_stop_mac; + ops->handle_common_intr = ivc_handle_common_intr; + ops->set_mode = ivc_set_mode; + ops->set_speed = ivc_set_speed; + ops->pad_calibrate = ivc_pad_calibrate; + ops->config_fw_err_pkts = ivc_config_fw_err_pkts; + ops->config_rxcsum_offload = ivc_config_rxcsum_offload; + ops->config_mac_pkt_filter_reg = ivc_config_mac_pkt_filter_reg; + ops->update_mac_addr_low_high_reg = ivc_update_mac_addr_low_high_reg; + ops->config_l3_l4_filter_enable = ivc_config_l3_l4_filter_enable; + ops->config_l3_filters = ivc_config_l3_filters; + ops->update_ip4_addr = ivc_update_ip4_addr; + ops->update_ip6_addr = ivc_update_ip6_addr; + ops->config_l4_filters = ivc_config_l4_filters; + ops->update_l4_port_no = ivc_update_l4_port_no; + ops->set_systime_to_mac = ivc_set_systime_to_mac; + ops->config_addend = ivc_config_addend; + ops->adjust_mactime = ivc_adjust_mactime; + ops->config_tscr = ivc_config_tscr; + ops->config_ssir = ivc_config_ssir; + ops->read_mmc = ivc_read_mmc; + ops->write_phy_reg = ivc_write_phy_reg; + ops->read_phy_reg = ivc_read_phy_reg; + ops->read_reg = ivc_read_reg; + ops->write_reg = ivc_write_reg; #ifndef OSI_STRIPPED_LIB - .config_tx_status = ivc_config_tx_status, - .config_rx_crc_check = ivc_config_rx_crc_check, - .config_flow_control = ivc_config_flow_control, - .config_arp_offload = ivc_config_arp_offload, - .validate_regs = ivc_validate_core_regs, - .flush_mtl_tx_queue = ivc_flush_mtl_tx_queue, - .set_avb_algorithm = ivc_set_avb_algorithm, - .get_avb_algorithm = ivc_get_avb_algorithm, - .config_vlan_filtering = ivc_config_vlan_filtering, - .update_vlan_id = ivc_update_vlan_id, - .reset_mmc = ivc_reset_mmc, - .configure_eee = ivc_configure_eee, - .save_registers = ivc_save_registers, - .restore_registers = ivc_restore_registers, - .set_mdc_clk_rate = ivc_set_mdc_clk_rate, - .config_mac_loopback = ivc_config_mac_loopback, + ops->config_tx_status = ivc_config_tx_status; + ops->config_rx_crc_check = ivc_config_rx_crc_check; + ops->config_flow_control = ivc_config_flow_control; + ops->config_arp_offload = ivc_config_arp_offload; + ops->validate_regs = ivc_validate_core_regs; + ops->flush_mtl_tx_queue = ivc_flush_mtl_tx_queue; + ops->set_avb_algorithm = ivc_set_avb_algorithm; + ops->get_avb_algorithm = ivc_get_avb_algorithm; + ops->config_vlan_filtering = ivc_config_vlan_filtering; + ops->update_vlan_id = ivc_update_vlan_id; + ops->reset_mmc = ivc_reset_mmc; + ops->configure_eee = ivc_configure_eee; + ops->save_registers = ivc_save_registers; + ops->restore_registers = ivc_restore_registers; + ops->set_mdc_clk_rate = ivc_set_mdc_clk_rate; + ops->config_mac_loopback = ivc_config_mac_loopback; #endif /* !OSI_STRIPPED_LIB */ }; @@ -1480,11 +1489,3 @@ void *ivc_get_core_safety_config(void) { return &ivc_safety_config; } - -/** - * @brief ivc_get_hw_core_ops - EQOS MAC get core operations - */ -struct osi_core_ops *ivc_get_hw_core_ops(void) -{ - return &ivc_ops; -} diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 4d95505..6a0e7f6 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -24,29 +24,99 @@ #include <ivc_core.h> #include "core_local.h" +/** + * @brief g_core - Static core local data variable + */ +static struct core_local g_core = { + .init_done = OSI_DISABLE, +}; + +/** + * @brief ops_p - Pointer local core operations. + */ +static struct core_ops *ops_p = &g_core.ops; + +/** + * @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_args(struct osi_core_priv_data *const osi_core) +{ + if ((osi_core == OSI_NULL) || (osi_core->base == OSI_NULL) || + (g_core.init_done == OSI_DISABLE)) { + return -1; + } + + return 0; +} + +/** + * @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_func_ptrs(struct osi_core_priv_data *const osi_core) +{ + nveu32_t i = 0; +#if __SIZEOF_POINTER__ == 8 + nveu64_t *l_ops = (nveu64_t *)ops_p; +#elif __SIZEOF_POINTER__ == 4 + nveu32_t *l_ops = (nveu32_t *)ops_p; +#else + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "Undefined architecture\n", 0ULL); + return -1; +#endif + + for (i = 0; i < (sizeof(*ops_p) / __SIZEOF_POINTER__); i++) { + if (*l_ops == 0) { + return -1; + } + + l_ops++; + } + + return 0; +} + 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) { - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->base != OSI_NULL) && - (osi_core->ops->write_phy_reg != OSI_NULL)) { - return osi_core->ops->write_phy_reg(osi_core, - phyaddr, phyreg, phydata); + if (validate_args(osi_core) < 0) { + return -1; } - return -1; + + return ops_p->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) { - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->base != OSI_NULL) && - (osi_core->ops->read_phy_reg != OSI_NULL)) { - return osi_core->ops->read_phy_reg(osi_core, phyaddr, phyreg); + if (validate_args(osi_core) < 0) { + return -1; } - return -1; + return ops_p->read_phy_reg(osi_core, phyaddr, phyreg); } nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core) @@ -64,173 +134,170 @@ nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core) return -1; } - if (osi_core->mac == OSI_MAC_HW_EQOS) { - if (osi_core->use_virtualization == OSI_DISABLE) { - /* Get EQOS HW ops */ - osi_core->ops = eqos_get_hw_core_ops(); - /* Explicitly set osi_core->safety_config = OSI_NULL if - * a particular MAC version does not need SW safety - * mechanisms like periodic read-verify. - */ - osi_core->safety_config = - (void *)eqos_get_core_safety_config(); - } else { - /* Get IVC HW ops */ - osi_core->ops = ivc_get_hw_core_ops(); - /* Explicitly set osi_core->safety_config = OSI_NULL if - * a particular MAC version does not need SW safety - * mechanisms like periodic read-verify. - */ - osi_core->safety_config = - (void *)ivc_get_core_safety_config(); - } - return 0; + if (osi_core->mac != OSI_MAC_HW_EQOS) { + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "Invalid MAC HW type\n", 0ULL); + return -1; } - return -1; + if (osi_core->use_virtualization == OSI_DISABLE) { + /* Get EQOS HW core ops */ + eqos_init_core_ops(ops_p); + /* Explicitly set osi_core->safety_config = OSI_NULL if + * a particular MAC version does not need SW safety + * mechanisms like periodic read-verify. + */ + osi_core->safety_config = + (void *)eqos_get_core_safety_config(); + } else { + /* Get IVC HW core ops */ + ivc_init_core_ops(ops_p); + /* Explicitly set osi_core->safety_config = OSI_NULL if + * a particular MAC version does not need SW safety + * mechanisms like periodic read-verify. + */ + osi_core->safety_config = + (void *)ivc_get_core_safety_config(); + } + + if (validate_func_ptrs(osi_core) < 0) { + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "core: function ptrs validation failed\n", 0ULL); + return -1; + } + + g_core.init_done = OSI_ENABLE; + + return 0; + } nve32_t osi_poll_for_mac_reset_complete( struct osi_core_priv_data *const osi_core) { - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->base != OSI_NULL) && - (osi_core->ops->poll_for_swr != OSI_NULL)) { - return osi_core->ops->poll_for_swr(osi_core); + if (validate_args(osi_core) < 0) { + return -1; } - return -1; + return ops_p->poll_for_swr(osi_core); } nve32_t osi_hw_core_init(struct osi_core_priv_data *const osi_core, nveu32_t tx_fifo_size, nveu32_t rx_fifo_size) { - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->base != OSI_NULL) && - (osi_core->ops->core_init != OSI_NULL)) { - return osi_core->ops->core_init(osi_core, tx_fifo_size, - rx_fifo_size); + if (validate_args(osi_core) < 0) { + return -1; } - return -1; + return ops_p->core_init(osi_core, tx_fifo_size, rx_fifo_size); } nve32_t osi_hw_core_deinit(struct osi_core_priv_data *const osi_core) { - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->base != OSI_NULL) && - (osi_core->ops->core_deinit != OSI_NULL)) { - osi_core->ops->core_deinit(osi_core); - return 0; + if (validate_args(osi_core) < 0) { + return -1; } - return -1; + ops_p->core_deinit(osi_core); + + return 0; } nve32_t osi_start_mac(struct osi_core_priv_data *const osi_core) { - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->base != OSI_NULL) && - (osi_core->ops->start_mac != OSI_NULL)) { - osi_core->ops->start_mac(osi_core); - return 0; + if (validate_args(osi_core) < 0) { + return -1; } - return -1; + ops_p->start_mac(osi_core); + + return 0; } nve32_t osi_stop_mac(struct osi_core_priv_data *const osi_core) { - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->base != OSI_NULL) && - (osi_core->ops->stop_mac != OSI_NULL)) { - osi_core->ops->stop_mac(osi_core); - return 0; + if (validate_args(osi_core) < 0) { + return -1; } - return -1; + ops_p->stop_mac(osi_core); + + return 0; } nve32_t osi_common_isr(struct osi_core_priv_data *const osi_core) { - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->base != OSI_NULL) && - (osi_core->ops->handle_common_intr != OSI_NULL)) { - osi_core->ops->handle_common_intr(osi_core); - return 0; + if (validate_args(osi_core) < 0) { + return -1; } - return -1; + 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) { - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->base != OSI_NULL) && - (osi_core->ops->set_mode != OSI_NULL)) { - return osi_core->ops->set_mode(osi_core, mode); + if (validate_args(osi_core) < 0) { + return -1; } - return -1; + return ops_p->set_mode(osi_core, mode); } nve32_t osi_set_speed(struct osi_core_priv_data *const osi_core, const nve32_t speed) { - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->base != OSI_NULL) && - (osi_core->ops->set_speed != OSI_NULL)) { - osi_core->ops->set_speed(osi_core, speed); - return 0; + if (validate_args(osi_core) < 0) { + return -1; } - return -1; + ops_p->set_speed(osi_core, speed); + + return 0; } nve32_t osi_pad_calibrate(struct osi_core_priv_data *const osi_core) { - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->pad_calibrate != OSI_NULL) && - (osi_core->base != OSI_NULL)) { - return osi_core->ops->pad_calibrate(osi_core); + if (validate_args(osi_core) < 0) { + return -1; } - return -1; + return 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) { - /* Configure Forwarding of Error packets */ - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->base != OSI_NULL) && - (osi_core->ops->config_fw_err_pkts != OSI_NULL)) { - return osi_core->ops->config_fw_err_pkts(osi_core, - qinx, fw_err); + if (validate_args(osi_core) < 0) { + return -1; } - return -1; + /* Configure Forwarding of Error packets */ + return ops_p->config_fw_err_pkts(osi_core, qinx, fw_err); } nve32_t osi_l2_filter(struct osi_core_priv_data *const osi_core, const struct osi_filter *filter) { - struct osi_core_ops *op; nve32_t ret = -1; - if ((osi_core == OSI_NULL) || (osi_core->ops == OSI_NULL) || - (osi_core->base == OSI_NULL) || (filter == OSI_NULL)) { - return ret; + if ((validate_args(osi_core) < 0) || (filter == OSI_NULL)) { + return -1; } - op = osi_core->ops; + if (filter == OSI_NULL) { + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "CORE: filter is NULL\n", 0ULL); + return -1; + } - if ((op->config_mac_pkt_filter_reg != OSI_NULL)) { - ret = op->config_mac_pkt_filter_reg(osi_core, filter); - } else { - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "op->config_mac_pkt_filter_reg is null\n", 0ULL); + ret = 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; } @@ -246,14 +313,7 @@ nve32_t osi_l2_filter(struct osi_core_priv_data *const osi_core, return ret; } - if ((op->update_mac_addr_low_high_reg != OSI_NULL)) { - ret = op->update_mac_addr_low_high_reg(osi_core, - filter); - } else { - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "op->update_mac_addr_low_high_reg is null\n", - 0ULL); - } + ret = ops_p->update_mac_addr_low_high_reg(osi_core, filter); } return ret; @@ -286,36 +346,26 @@ static inline nve32_t helper_l4_filter( nveu32_t dma_routing_enable, nveu32_t dma_chan) { - struct osi_core_ops *op = osi_core->ops; + nve32_t ret = 0; - if (op->config_l4_filters != OSI_NULL) { - if (op->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) < 0) { - return -1; - } - } else { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "op->config_l4_filters is NULL\n", 0ULL); - return -1; - } - - if (op->update_l4_port_no != OSI_NULL) { - return op->update_l4_port_no(osi_core, - l_filter.filter_no, - l_filter.port_no, - l_filter.src_dst_addr_match); - } else { - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "op->update_l4_port_no is NULL\n", 0ULL); - return -1; + 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); } /** @@ -345,48 +395,32 @@ static inline nve32_t helper_l3_filter( nveu32_t dma_routing_enable, nveu32_t dma_chan) { - struct osi_core_ops *op = osi_core->ops; + nve32_t ret = 0; - if ((op->config_l3_filters != OSI_NULL)) { - if (op->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) < 0) { - return -1; - } - } else { - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "op->config_l3_filters is NULL\n", 0ULL); - return -1; + 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) { - if (op->update_ip6_addr != OSI_NULL) { - return op->update_ip6_addr(osi_core, l_filter.filter_no, + ret = ops_p->update_ip6_addr(osi_core, l_filter.filter_no, l_filter.ip6_addr); - } else { - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "op->update_ip6_addr is NULL\n", 0ULL); - return -1; - } } else if (type == OSI_IP4_FILTER) { - if (op->update_ip4_addr != OSI_NULL) { - return op->update_ip4_addr(osi_core, - l_filter.filter_no, - l_filter.ip4_addr, - l_filter.src_dst_addr_match); - } else { - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "op->update_ip4_addr is NULL\n", 0ULL); - return -1; - } - } else { - return -1; + ret = ops_p->update_ip4_addr(osi_core, l_filter.filter_no, + l_filter.ip4_addr, + l_filter.src_dst_addr_match); } + + return ret; } nve32_t osi_l3l4_filter(struct osi_core_priv_data *const osi_core, @@ -396,9 +430,8 @@ nve32_t osi_l3l4_filter(struct osi_core_priv_data *const osi_core, { nve32_t ret = -1; - if ((osi_core == OSI_NULL) || (osi_core->ops == OSI_NULL) || - (osi_core->base == OSI_NULL)) { - return ret; + if (validate_args(osi_core) < 0) { + return -1; } if ((dma_routing_enable == OSI_ENABLE) && @@ -423,21 +456,10 @@ nve32_t osi_l3l4_filter(struct osi_core_priv_data *const osi_core, return ret; } - if (osi_core->ops->config_l3_l4_filter_enable != OSI_NULL) { - if (osi_core->l3l4_filter_bitmask != OSI_DISABLE) { - ret = osi_core->ops->config_l3_l4_filter_enable( - osi_core, - OSI_ENABLE); - } else { - ret = osi_core->ops->config_l3_l4_filter_enable( - osi_core, - OSI_DISABLE); - } - + if (osi_core->l3l4_filter_bitmask != OSI_DISABLE) { + ret = ops_p->config_l3_l4_filter_enable(osi_core, OSI_ENABLE); } else { - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "op->config_l3_l4_filter_enable is NULL\n", 0ULL); - ret = -1; + ret = ops_p->config_l3_l4_filter_enable(osi_core, OSI_DISABLE); } return ret; @@ -446,28 +468,21 @@ nve32_t osi_l3l4_filter(struct osi_core_priv_data *const osi_core, nve32_t osi_config_rxcsum_offload(struct osi_core_priv_data *const osi_core, const nveu32_t enable) { - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->base != OSI_NULL) && - (osi_core->ops->config_rxcsum_offload != OSI_NULL)) { - return osi_core->ops->config_rxcsum_offload(osi_core, - enable); + if (validate_args(osi_core) < 0) { + return -1; } - return -1; + return 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) { - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->base != OSI_NULL) && - (osi_core->ops->set_systime_to_mac != OSI_NULL)) { - return osi_core->ops->set_systime_to_mac(osi_core, - sec, - nsec); + if (validate_args(osi_core) < 0) { + return -1; } - return -1; + return ops_p->set_systime_to_mac(osi_core, sec, nsec); } /** @@ -505,8 +520,8 @@ nve32_t osi_adjust_freq(struct osi_core_priv_data *const osi_core, nve32_t ppb) nve32_t ret = -1; nve32_t ppb1 = ppb; - if (osi_core == OSI_NULL) { - return ret; + if (validate_args(osi_core) < 0) { + return -1; } addend = osi_core->default_addend; @@ -550,15 +565,7 @@ nve32_t osi_adjust_freq(struct osi_core_priv_data *const osi_core, nve32_t ppb) } } - if ((osi_core->ops != OSI_NULL) && (osi_core->base != OSI_NULL) && - (osi_core->ops->config_addend != OSI_NULL)) { - return osi_core->ops->config_addend(osi_core, addend); - } - - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "core: Invalid argument\n", - 0ULL); - - return ret; + return ops_p->config_addend(osi_core, addend); } nve32_t osi_adjust_time(struct osi_core_priv_data *const osi_core, @@ -572,8 +579,8 @@ nve32_t osi_adjust_time(struct osi_core_priv_data *const osi_core, nve32_t ret = -1; nvel64_t nsec_delta1 = nsec_delta; - if (osi_core == OSI_NULL) { - return ret; + if (validate_args(osi_core) < 0) { + return -1; } if (nsec_delta1 < 0) { @@ -592,6 +599,7 @@ nve32_t osi_adjust_time(struct osi_core_priv_data *const osi_core, "quotient > UINT_MAX\n", 0ULL); return ret; } + if (reminder <= UINT_MAX) { nsec = (nveu32_t)reminder; } else { @@ -600,17 +608,8 @@ nve32_t osi_adjust_time(struct osi_core_priv_data *const osi_core, return ret; } - if ((osi_core->ops != OSI_NULL) && (osi_core->base != OSI_NULL) && - (osi_core->ops->adjust_mactime != OSI_NULL)) { - return osi_core->ops->adjust_mactime(osi_core, sec, nsec, - neg_adj, - osi_core->ptp_config.one_nsec_accuracy); - } - - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "core: Invalid argument\n", - 0ULL); - - return ret; + return 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, @@ -620,26 +619,20 @@ nve32_t osi_ptp_configuration(struct osi_core_priv_data *const osi_core, nveu64_t temp = 0, temp1 = 0, temp2 = 0; nveu64_t ssinc = 0; - if ((osi_core == OSI_NULL) || (osi_core->ops == OSI_NULL) || - (osi_core->base == OSI_NULL) || - (osi_core->ops->config_tscr == OSI_NULL) || - (osi_core->ops->config_ssir == OSI_NULL) || - (osi_core->ops->config_addend == OSI_NULL) || - (osi_core->ops->set_systime_to_mac == OSI_NULL)) { + if (validate_args(osi_core) < 0) { return -1; } if (enable == OSI_DISABLE) { /* disable hw time stamping */ /* Program MAC_Timestamp_Control Register */ - osi_core->ops->config_tscr(osi_core, OSI_DISABLE); + ops_p->config_tscr(osi_core, OSI_DISABLE); } else { /* Program MAC_Timestamp_Control Register */ - osi_core->ops->config_tscr(osi_core, - osi_core->ptp_config.ptp_filter); + ops_p->config_tscr(osi_core, osi_core->ptp_config.ptp_filter); /* Program Sub Second Increment Register */ - osi_core->ops->config_ssir(osi_core); + ops_p->config_ssir(osi_core); /* formula for calculating addend value is * TSAR = (2^32 * 1000) / (ptp_ref_clk_rate in MHz * SSINC) @@ -671,14 +664,13 @@ nve32_t osi_ptp_configuration(struct osi_core_priv_data *const osi_core, } /* Program addend value */ - ret = osi_core->ops->config_addend(osi_core, - osi_core->default_addend); + ret = ops_p->config_addend(osi_core, osi_core->default_addend); /* Set current time */ if (ret == 0) { - ret = osi_core->ops->set_systime_to_mac(osi_core, - osi_core->ptp_config.sec, - osi_core->ptp_config.nsec); + ret = ops_p->set_systime_to_mac(osi_core, + osi_core->ptp_config.sec, + osi_core->ptp_config.nsec); } } @@ -687,16 +679,14 @@ nve32_t osi_ptp_configuration(struct osi_core_priv_data *const osi_core, nve32_t osi_read_mmc(struct osi_core_priv_data *const osi_core) { - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->base != OSI_NULL) && - (osi_core->ops->read_mmc != OSI_NULL)) { - osi_core->ops->read_mmc(osi_core); - return 0; + if (validate_args(osi_core) < 0) { + return -1; } - return -1; -} + ops_p->read_mmc(osi_core); + return 0; +} nve32_t osi_get_mac_version(struct osi_core_priv_data *const osi_core, @@ -704,15 +694,16 @@ nve32_t osi_get_mac_version(struct osi_core_priv_data *const osi_core, { nveu32_t macver; - if ((osi_core == OSI_NULL) || (osi_core->ops == OSI_NULL) || - (osi_core->ops->read_reg == OSI_NULL) || - (osi_core->base == OSI_NULL)) { + if (validate_args(osi_core) < 0) { return -1; } - macver = ((osi_core->ops->read_reg(osi_core, (nve32_t)MAC_VERSION)) & + + macver = ((ops_p->read_reg(osi_core, (nve32_t)MAC_VERSION)) & MAC_VERSION_SNVER_MASK); if (is_valid_mac_version(macver) == 0) { + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "Invalid MAC version\n", (nveu64_t)macver) return -1; } @@ -723,81 +714,69 @@ nve32_t osi_get_mac_version(struct osi_core_priv_data *const osi_core, #ifndef OSI_STRIPPED_LIB nve32_t osi_validate_core_regs(struct osi_core_priv_data *const osi_core) { - nve32_t ret = -1; - - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->base != OSI_NULL) && - (osi_core->ops->validate_regs != OSI_NULL) && - (osi_core->safety_config != OSI_NULL)) { - ret = osi_core->ops->validate_regs(osi_core); - return ret; + if (validate_args(osi_core) < 0) { + return -1; } - return ret; + 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 ops_p->validate_regs(osi_core); } nve32_t osi_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, const nveu32_t qinx) { - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->base != OSI_NULL) && - (osi_core->ops->flush_mtl_tx_queue != OSI_NULL)) { - return osi_core->ops->flush_mtl_tx_queue(osi_core, qinx); + if (validate_args(osi_core) < 0) { + return -1; } - return -1; + return ops_p->flush_mtl_tx_queue(osi_core, qinx); } nve32_t osi_set_avb(struct osi_core_priv_data *const osi_core, const struct osi_core_avb_algorithm *avb) { - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->base != OSI_NULL) && - (osi_core->ops->set_avb_algorithm != OSI_NULL)) { - return osi_core->ops->set_avb_algorithm(osi_core, avb); + if (validate_args(osi_core) < 0) { + return -1; } - return -1; + return ops_p->set_avb_algorithm(osi_core, avb); } nve32_t osi_get_avb(struct osi_core_priv_data *const osi_core, struct osi_core_avb_algorithm *avb) { - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->base != OSI_NULL) && - (osi_core->ops->get_avb_algorithm != OSI_NULL)) { - return osi_core->ops->get_avb_algorithm(osi_core, avb); + if (validate_args(osi_core) < 0) { + return -1; } - return -1; + return ops_p->get_avb_algorithm(osi_core, avb); } nve32_t osi_configure_txstatus(struct osi_core_priv_data *const osi_core, const nveu32_t tx_status) { - /* Configure Drop Transmit Status */ - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->base != OSI_NULL) && - (osi_core->ops->config_tx_status != OSI_NULL)) { - return osi_core->ops->config_tx_status(osi_core, - tx_status); + if (validate_args(osi_core) < 0) { + return -1; } - return -1; + /* Configure Drop Transmit Status */ + return ops_p->config_tx_status(osi_core, tx_status); } nve32_t osi_config_rx_crc_check(struct osi_core_priv_data *const osi_core, const nveu32_t crc_chk) { - /* Configure CRC Checking for Received Packets */ - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->base != OSI_NULL) && - (osi_core->ops->config_rx_crc_check != OSI_NULL)) { - return osi_core->ops->config_rx_crc_check(osi_core, - crc_chk); + if (validate_args(osi_core) < 0) { + return -1; } - return -1; + /* Configure CRC Checking for Received Packets */ + return ops_p->config_rx_crc_check(osi_core, crc_chk); } nve32_t osi_config_vlan_filtering(struct osi_core_priv_data *const osi_core, @@ -805,145 +784,154 @@ nve32_t osi_config_vlan_filtering(struct osi_core_priv_data *const osi_core, const nveu32_t perfect_hash_filtering, const nveu32_t perfect_inverse_match) { - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->base != OSI_NULL) && - (osi_core->ops->config_vlan_filtering != OSI_NULL)) { - return osi_core->ops->config_vlan_filtering( - osi_core, - filter_enb_dis, - perfect_hash_filtering, - perfect_inverse_match); + if (validate_args(osi_core) < 0) { + return -1; } - return -1; + return ops_p->config_vlan_filtering(osi_core, filter_enb_dis, + perfect_hash_filtering, + perfect_inverse_match); } -nve32_t osi_update_vlan_id(struct osi_core_priv_data *const osi_core, - const nveu32_t vid) +nve32_t osi_update_vlan_id(struct osi_core_priv_data *const osi_core, + const nveu32_t vid) { - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->update_vlan_id != OSI_NULL)) { - return osi_core->ops->update_vlan_id(osi_core, - vid); + if (validate_args(osi_core) < 0) { + return -1; } - return -1; + return ops_p->update_vlan_id(osi_core, vid); } nve32_t osi_reset_mmc(struct osi_core_priv_data *const osi_core) { - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->base != OSI_NULL) && - (osi_core->ops->reset_mmc != OSI_NULL)) { - osi_core->ops->reset_mmc(osi_core); - return 0; + if (validate_args(osi_core) < 0) { + return -1; } - return -1; + ops_p->reset_mmc(osi_core); + + return 0; } nve32_t osi_configure_eee(struct osi_core_priv_data *const osi_core, nveu32_t tx_lpi_enabled, nveu32_t tx_lpi_timer) { - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->base != OSI_NULL) && - (osi_core->ops->configure_eee != OSI_NULL) && - (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->ops->configure_eee(osi_core, tx_lpi_enabled, - tx_lpi_timer); - return 0; + if (validate_args(osi_core) < 0) { + return -1; } - return -1; + 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; + } + + ops_p->configure_eee(osi_core, tx_lpi_enabled, tx_lpi_timer); + + return 0; } nve32_t osi_save_registers(struct osi_core_priv_data *const osi_core) { - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->base != OSI_NULL) && - (osi_core->ops->save_registers != OSI_NULL)) { - /* Call MAC save registers callback and return the value */ - return osi_core->ops->save_registers(osi_core); + if (validate_args(osi_core) < 0) { + return -1; } - return -1; + /* Call MAC save registers callback and return the value */ + return ops_p->save_registers(osi_core); } nve32_t osi_restore_registers(struct osi_core_priv_data *const osi_core) { - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->base != OSI_NULL) && - (osi_core->ops->restore_registers != OSI_NULL)) { - /* Call MAC restore registers callback and return the value */ - return osi_core->ops->restore_registers(osi_core); + if (validate_args(osi_core) < 0) { + return -1; } - return -1; + /* Call MAC restore registers callback and return the value */ + return ops_p->restore_registers(osi_core); } nve32_t osi_configure_flow_control(struct osi_core_priv_data *const osi_core, const nveu32_t flw_ctrl) { - /* Configure Flow control settings */ - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->base != OSI_NULL) && - (osi_core->ops->config_flow_control != OSI_NULL)) { - return osi_core->ops->config_flow_control(osi_core, - flw_ctrl); + if (validate_args(osi_core) < 0) { + return -1; } - return -1; + /* Configure Flow control settings */ + return ops_p->config_flow_control(osi_core, flw_ctrl); } nve32_t osi_config_arp_offload(struct osi_core_priv_data *const osi_core, const nveu32_t flags, const nveu8_t *ip_addr) { - if (osi_core != OSI_NULL && osi_core->ops != OSI_NULL && - (osi_core->base != OSI_NULL) && (ip_addr != OSI_NULL) && - (osi_core->ops->config_arp_offload != OSI_NULL)) { - return osi_core->ops->config_arp_offload(osi_core, - flags, ip_addr); + if ((validate_args(osi_core) < 0)) { + return -1; } - return -1; + 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 ops_p->config_arp_offload(osi_core, flags, ip_addr); } nve32_t osi_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, const nveu64_t csr_clk_rate) { - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->set_mdc_clk_rate != OSI_NULL)) { - osi_core->ops->set_mdc_clk_rate(osi_core, csr_clk_rate); - return 0; + if (validate_args(osi_core) < 0) { + return -1; } - return -1; + ops_p->set_mdc_clk_rate(osi_core, csr_clk_rate); + + return 0; } nve32_t osi_config_mac_loopback(struct osi_core_priv_data *const osi_core, const nveu32_t lb_mode) { - /* Configure MAC loopback */ - if ((osi_core != OSI_NULL) && (osi_core->ops != OSI_NULL) && - (osi_core->ops->config_mac_loopback != OSI_NULL)) { - return osi_core->ops->config_mac_loopback(osi_core, - lb_mode); + if (validate_args(osi_core) < 0) { + return -1; } - return -1; + /* 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; + } + + /* Configure MAC loopback */ + return ops_p->config_mac_loopback(osi_core, lb_mode); } #endif /* !OSI_STRIPPED_LIB */ nve32_t osi_get_hw_features(struct osi_core_priv_data *const osi_core, struct osi_hw_features *hw_feat) { - if ((hw_feat == OSI_NULL) || (osi_core == OSI_NULL) || - (osi_core->ops->get_hw_features == OSI_NULL)) { + if (validate_args(osi_core) < 0) { return -1; } - return osi_core->ops->get_hw_features(osi_core, hw_feat); + if (hw_feat == OSI_NULL) { + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "CORE: Invalid hw_feat\n", 0ULL); + return -1; + } + + return ops_p->get_hw_features(osi_core, hw_feat); } From c85079081bdac228e8a5cda858826327f2bcb980 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Tue, 9 Mar 2021 14:22:12 +0530 Subject: [PATCH 154/458] osi: ivc: support for get_hw_features Issue: Recently get_hw_features function pointer added to get the HW features. This pointer is missing for IVC operations which resulted in kernel panic. Fix: Add support for IVC get_hw_features Bug 200671160 Change-Id: I95aa82b157790d6fbf4626000c318d52f3d248ee Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2495585 Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Nagaraj Annaiah <nannaiah@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/ivc_core.h | 3 +++ osi/core/ivc_core.c | 23 +++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/include/ivc_core.h b/include/ivc_core.h index c825be6..7fa69fc 100644 --- a/include/ivc_core.h +++ b/include/ivc_core.h @@ -67,6 +67,7 @@ typedef enum ivc_cmd { read_phy_reg, reg_read, reg_write, + get_hw_features, #ifndef OSI_STRIPPED_LIB config_tx_status, config_rx_crc_check, @@ -158,6 +159,8 @@ typedef struct ivc_msg_common { * OSI filter structure */ struct osi_filter filter; + /** OSI HW features */ + struct osi_hw_features hw_feat; /** * core argument structure */ diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index 6753e7a..5614e84 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -979,6 +979,28 @@ static nveu32_t ivc_write_reg(struct osi_core_priv_data *const osi_core, sizeof(msg_common)); } +static nve32_t ivc_get_hw_features(struct osi_core_priv_data *const osi_core, + struct osi_hw_features *hw_feat) +{ + ivc_msg_common msg_hw_feat; + nve32_t ret = 0; + + osi_memset(&msg_hw_feat, 0, sizeof(msg_hw_feat)); + + msg_hw_feat.cmd = get_hw_features; + + ret = osi_core->osd_ops.ivc_send(osi_core, (char *)&msg_hw_feat, + sizeof(msg_hw_feat)); + if (ret != 0) { + return ret; + } + + osi_memcpy((void *)hw_feat, (void *)&msg_hw_feat.data.hw_feat, + sizeof(struct osi_hw_features)); + + return ret; +} + #ifndef OSI_STRIPPED_LIB /** * @brief ivc_config_flow_control - Configure MAC flow control settings @@ -1462,6 +1484,7 @@ void ivc_init_core_ops(struct core_ops *ops) ops->read_phy_reg = ivc_read_phy_reg; ops->read_reg = ivc_read_reg; ops->write_reg = ivc_write_reg; + ops->get_hw_features = ivc_get_hw_features; #ifndef OSI_STRIPPED_LIB ops->config_tx_status = ivc_config_tx_status; ops->config_rx_crc_check = ivc_config_rx_crc_check; From bf99d248c205f029f932b99ad93a10d5b55d9dfb Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Fri, 26 Feb 2021 00:36:23 +0530 Subject: [PATCH 155/458] osi: don't expose DMA ops to OSD Issue: Currently OSD has access to osi_dma_ops so these operations can be changed by OSD. Also each entry funnction has checks for validating these function pointers which would increase the unit tests as well. Fix: Move dma_ops to inside OSI and set a flag indicate that DMA software init done. Each entry function needs to check only flag. It also fixes couple of doxygen comments issues. Bug 200671160 Change-Id: I675e24cbfca8f4023fd31709f246230d2070d716 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2490156 Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_dma.h | 65 +---- osi/core/eqos_core.c | 2 +- osi/dma/dma_local.h | 99 ++++++- osi/dma/eqos_dma.c | 48 ++-- osi/dma/osi_dma.c | 570 ++++++++++++++++++++++++++--------------- osi/dma/osi_dma_txrx.c | 135 +++------- 6 files changed, 531 insertions(+), 388 deletions(-) diff --git a/include/osi_dma.h b/include/osi_dma.h index 6d78ba0..f9d6df6 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -393,64 +393,6 @@ struct osi_xtra_dma_stat_counters { struct osi_dma_priv_data; -/** - * @brief MAC DMA Channel operations - */ -struct osi_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 get Global DMA status */ - nveu32_t (*get_global_dma_status)(void *addr); - /** 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 OSI VM IRQ data */ @@ -495,8 +437,6 @@ struct osi_dma_priv_data { void *base; /** Pointer to OSD private data structure */ void *osd; - /** Address of HW operations structure */ - struct osi_dma_chan_ops *ops; /** MAC HW type (EQOS) */ nveu32_t mac; /** Number of channels enabled in MAC */ @@ -711,7 +651,6 @@ nve32_t osi_enable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, * Algorithm: Returns global DMA Tx/Rx interrupt status * * @param[in] osi_dma: DMA private data. - * @param[in] chan: DMA tx channel number. * * @note * Dependencies: None. @@ -978,8 +917,10 @@ nve32_t osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma); * - Run time: Yes * - De-initialization: No * + * @retval 0 on success + * @retval -1 on failure. */ -void osi_hw_transmit(struct osi_dma_priv_data *osi_dma, nveu32_t chan); +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. diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index e7dd783..942013f 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -2071,7 +2071,7 @@ static nve32_t eqos_update_mac_addr_low_high_reg( * Algorithm: * - This routine to enable/disable L4/l4 filter * - * @param[in] base: Base address from OSI core private data structure. + * @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() diff --git a/osi/dma/dma_local.h b/osi/dma/dma_local.h index 7d3195b..4e301fb 100644 --- a/osi/dma/dma_local.h +++ b/osi/dma/dma_local.h @@ -27,6 +27,101 @@ #include <osi_dma.h> #include "eqos_dma.h" +/** + * @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 get Global DMA status */ + nveu32_t (*get_global_dma_status)(void *addr); + /** 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 OSI DMA private data. + */ +struct dma_local { + /** DMA channel operations */ + struct dma_chan_ops ops; + /** Flag to represent OSI DMA software init done */ + unsigned int init_done; +}; + +void eqos_init_dma_chan_ops(struct dma_chan_ops *ops); + +/** + * @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 */ /** @@ -38,6 +133,7 @@ * 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: @@ -48,7 +144,8 @@ * @retval 0 on success * @retval -1 on failure. */ -nve32_t dma_desc_init(struct osi_dma_priv_data *osi_dma); +nve32_t dma_desc_init(struct osi_dma_priv_data *osi_dma, + struct dma_chan_ops *ops); /** * @addtogroup Helper Helper MACROS diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index 7d26f0b..1ef19ae 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -1001,33 +1001,31 @@ void *eqos_get_dma_safety_config(void) } /** - * @brief eqos_get_dma_chan_ops - EQOS get DMA channel operations + * @brief eqos_init_dma_chan_ops - Initialize EQOS DMA operations. + * + * @param[in] ops: DMA channel operations pointer. */ -struct osi_dma_chan_ops *eqos_get_dma_chan_ops(void) +void eqos_init_dma_chan_ops(struct dma_chan_ops *ops) { - static struct osi_dma_chan_ops eqos_dma_chan_ops = { - .set_tx_ring_len = eqos_set_tx_ring_len, - .set_rx_ring_len = eqos_set_rx_ring_len, - .set_tx_ring_start_addr = eqos_set_tx_ring_start_addr, - .set_rx_ring_start_addr = eqos_set_rx_ring_start_addr, - .update_tx_tailptr = eqos_update_tx_tailptr, - .update_rx_tailptr = eqos_update_rx_tailptr, - .disable_chan_tx_intr = eqos_disable_chan_tx_intr, - .enable_chan_tx_intr = eqos_enable_chan_tx_intr, - .disable_chan_rx_intr = eqos_disable_chan_rx_intr, - .enable_chan_rx_intr = eqos_enable_chan_rx_intr, - .start_dma = eqos_start_dma, - .stop_dma = eqos_stop_dma, - .init_dma_channel = eqos_init_dma_channel, - .set_rx_buf_len = eqos_set_rx_buf_len, + 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 - .validate_regs = eqos_validate_dma_regs, - .config_slot = eqos_config_slot, + ops->validate_regs = eqos_validate_dma_regs; + ops->config_slot = eqos_config_slot; #endif /* !OSI_STRIPPED_LIB */ - .get_global_dma_status = eqos_get_global_dma_status, - .clear_vm_tx_intr = eqos_clear_vm_tx_intr, - .clear_vm_rx_intr = eqos_clear_vm_rx_intr, - }; - - return &eqos_dma_chan_ops; + ops->get_global_dma_status = eqos_get_global_dma_status; + 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/osi_dma.c b/osi/dma/osi_dma.c index be92b35..282c78c 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -24,6 +24,135 @@ #include <local_common.h> #include "hw_desc.h" +/** + * @brief g_dma - DMA local data variable + */ +static struct dma_local g_dma = { + .init_done = OSI_DISABLE, +}; + +/** + * @brief ops_p - Pointer to local DMA HW operations. + */ +static struct dma_chan_ops *ops_p = &g_dma.ops; + +/** + * @brief Function to validate input arguments of API. + * + * @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_args(struct osi_dma_priv_data *osi_dma) +{ + if ((osi_dma == OSI_NULL) || (osi_dma->base == OSI_NULL) || + (g_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, + unsigned int chan) +{ + if (chan >= OSI_EQOS_MAX_NUM_CHANS) { + OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "Invalid DMA channel number\n", 0ULL); + 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) +{ + nveu32_t i = 0; + + for (i = 0; i < osi_dma->num_dma_chans; i++) { + if (validate_dma_chan_num(osi_dma, + osi_dma->dma_chans[i]) < 0) { + return -1; + } + } + + return 0; +} + +/** + * @brief Function to validate function pointers. + * + * @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 validate_func_ptrs(struct osi_dma_priv_data *osi_dma) +{ + nveu32_t i = 0; +#if __SIZEOF_POINTER__ == 8 + nveu64_t *l_ops = (nveu64_t *)ops_p; +#elif __SIZEOF_POINTER__ == 4 + nveu32_t *l_ops = (nveu32_t *)ops_p; +#else + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "DMA: Undefined architecture\n", 0ULL); + return -1; +#endif + + for (i = 0; i < (sizeof(*ops_p) / __SIZEOF_POINTER__); i++) { + if (*l_ops == 0) { + return -1; + } + + l_ops++; + } + + return 0; +} + nve32_t osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) { if (osi_dma == OSI_NULL) { @@ -35,24 +164,34 @@ nve32_t osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) (osi_dma->osd_ops.ops_log == OSI_NULL) || (osi_dma->osd_ops.udelay == OSI_NULL)) { OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "DMA OSD ops not assigned\n", 0ULL); + "DMA OSD ops not assigned\n", 0ULL); return -1; } - if (osi_dma->mac == OSI_MAC_HW_EQOS) { - /* Get EQOS HW ops */ - osi_dma->ops = eqos_get_dma_chan_ops(); - /* Explicitly set osi_dma->safety_config = OSI_NULL if - * a particular MAC version does not need SW safety mechanisms - * like periodic read-verify. - */ - osi_dma->safety_config = (void *)eqos_get_dma_safety_config(); - return 0; + if (osi_dma->mac != OSI_MAC_HW_EQOS) { + OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "DMA: Invalid MAC HW type\n", 0ULL); + return -1; } - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "dma: Invalid argument\n", - 0ULL); - return -1; + /* Get EQOS HW DMA operations */ + eqos_init_dma_chan_ops(ops_p); + + /* Explicitly set osi_dma->safety_config = OSI_NULL if + * a particular MAC version does not need SW safety mechanisms + * like periodic read-verify. + */ + osi_dma->safety_config = (void *)eqos_get_dma_safety_config(); + + if (validate_func_ptrs(osi_dma) < 0) { + OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "DMA ops validation failed\n", 0ULL); + return -1; + } + + g_dma.init_done = OSI_ENABLE; + + return 0; } nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) @@ -60,21 +199,30 @@ nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) nveu32_t i, chan; nve32_t ret = -1; - if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && - (osi_dma->base != OSI_NULL) && - (osi_dma->ops->init_dma_channel != OSI_NULL) && - (osi_dma->num_dma_chans <= OSI_EQOS_MAX_NUM_CHANS)) { - ret = osi_dma->ops->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; - } - } else { + if (validate_args(osi_dma) < 0) { + return -1; + } + + if (osi_dma->num_dma_chans > OSI_EQOS_MAX_NUM_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 = 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); + ret = dma_desc_init(osi_dma, ops_p); if (ret != 0) { return ret; } @@ -83,161 +231,176 @@ nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) for (i = 0; i < osi_dma->num_dma_chans; i++) { chan = osi_dma->dma_chans[i]; - ret = osi_enable_chan_tx_intr(osi_dma, chan); - if (ret != 0) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma: enable tx intr failed\n", 0ULL); - return ret; - } - - ret = osi_enable_chan_rx_intr(osi_dma, chan); - if (ret != 0) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma: enable rx intr failed\n", 0ULL); - return ret; - } - - ret = osi_start_dma(osi_dma, chan); - if (ret != 0) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma: start dma failed\n", 0ULL); - return ret; - } - } - - return ret; -} - -nve32_t osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma) -{ - nveu32_t i; - nve32_t ret = 0; - - if ((osi_dma == OSI_NULL) || - (osi_dma->num_dma_chans > OSI_EQOS_MAX_NUM_CHANS)) { - return -1; - } - - for (i = 0; i < osi_dma->num_dma_chans; i++) { - ret = osi_stop_dma(osi_dma, osi_dma->dma_chans[i]); - if (ret != 0) { - return ret; - } - } - - return ret; -} - -nve32_t osi_disable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, - nveu32_t chan) -{ - if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && - (osi_dma->base != OSI_NULL) && (chan < OSI_EQOS_MAX_NUM_CHANS) && - (osi_dma->ops->disable_chan_tx_intr != OSI_NULL)) { - osi_dma->ops->disable_chan_tx_intr(osi_dma->base, chan); - return 0; - } - - return -1; -} - -nve32_t osi_enable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, - nveu32_t chan) -{ - if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && - (osi_dma->base != OSI_NULL) && (chan < OSI_EQOS_MAX_NUM_CHANS) && - (osi_dma->ops->enable_chan_tx_intr != OSI_NULL)) { - osi_dma->ops->enable_chan_tx_intr(osi_dma->base, chan); - return 0; - } - - return -1; -} - -nve32_t osi_disable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, - nveu32_t chan) -{ - if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && - (osi_dma->base != OSI_NULL) && (chan < OSI_EQOS_MAX_NUM_CHANS) && - (osi_dma->ops->disable_chan_rx_intr != OSI_NULL)) { - osi_dma->ops->disable_chan_rx_intr(osi_dma->base, chan); - return 0; - } - - return -1; -} - -nve32_t osi_enable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, - nveu32_t chan) -{ - if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && - (osi_dma->base != OSI_NULL) && (chan < OSI_EQOS_MAX_NUM_CHANS) && - (osi_dma->ops->enable_chan_rx_intr != OSI_NULL)) { - osi_dma->ops->enable_chan_rx_intr(osi_dma->base, chan); - return 0; - } - - return -1; -} - -nve32_t osi_clear_vm_tx_intr(struct osi_dma_priv_data *osi_dma, - nveu32_t chan) -{ - if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && - (osi_dma->ops->clear_vm_tx_intr != OSI_NULL)) { - osi_dma->ops->clear_vm_tx_intr(osi_dma->base, chan); - return 0; - } - - return -1; -} - -nve32_t osi_clear_vm_rx_intr(struct osi_dma_priv_data *osi_dma, - nveu32_t chan) -{ - if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && - (osi_dma->ops->clear_vm_rx_intr != OSI_NULL)) { - osi_dma->ops->clear_vm_rx_intr(osi_dma->base, chan); - return 0; - } - - return -1; -} - -nveu32_t osi_get_global_dma_status(struct osi_dma_priv_data *osi_dma) -{ - if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && - (osi_dma->ops->get_global_dma_status != OSI_NULL)) { - return osi_dma->ops->get_global_dma_status(osi_dma->base); + ops_p->enable_chan_tx_intr(osi_dma->base, chan); + ops_p->enable_chan_rx_intr(osi_dma->base, chan); + ops_p->start_dma(osi_dma, chan); } return 0; } -nve32_t osi_start_dma(struct osi_dma_priv_data *osi_dma, - nveu32_t chan) +nve32_t osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma) { - if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && - (osi_dma->base != OSI_NULL) && (chan < OSI_EQOS_MAX_NUM_CHANS) && - (osi_dma->ops->start_dma != OSI_NULL)) { - osi_dma->ops->start_dma(osi_dma, chan); + nveu32_t i; + + if (validate_args(osi_dma) < 0) { + return -1; + } + + if (osi_dma->num_dma_chans > OSI_EQOS_MAX_NUM_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++) { + ops_p->stop_dma(osi_dma, osi_dma->dma_chans[i]); + } + + return 0; +} + +nve32_t osi_disable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, + nveu32_t chan) +{ + if (validate_args(osi_dma) < 0) { + return -1; + } + + if (validate_dma_chan_num(osi_dma, chan) < 0) { + return -1; + } + + 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) +{ + if (validate_args(osi_dma) < 0) { + return -1; + } + + if (validate_dma_chan_num(osi_dma, chan) < 0) { + return -1; + } + + 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) +{ + if (validate_args(osi_dma) < 0) { + return -1; + } + + if (validate_dma_chan_num(osi_dma, chan) < 0) { + return -1; + } + + 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) +{ + if (validate_args(osi_dma) < 0) { + return -1; + } + + if (validate_dma_chan_num(osi_dma, chan) < 0) { + return -1; + } + + 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) +{ + if (validate_args(osi_dma) < 0) { + return -1; + } + + if (validate_dma_chan_num(osi_dma, chan) < 0) { + return -1; + } + + 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) +{ + if (validate_args(osi_dma) < 0) { + return -1; + } + + if (validate_dma_chan_num(osi_dma, chan) < 0) { + return -1; + } + + 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) +{ + if (validate_args(osi_dma) < 0) { return 0; } - return -1; + return ops_p->get_global_dma_status(osi_dma->base); +} + +nve32_t osi_start_dma(struct osi_dma_priv_data *osi_dma, + nveu32_t chan) +{ + if (validate_args(osi_dma) < 0) { + return -1; + } + + if (validate_dma_chan_num(osi_dma, chan) < 0) { + return -1; + } + + ops_p->start_dma(osi_dma, chan); + + return 0; } nve32_t osi_stop_dma(struct osi_dma_priv_data *osi_dma, nveu32_t chan) { - if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && - (osi_dma->base != OSI_NULL) && (chan < OSI_EQOS_MAX_NUM_CHANS) && - (osi_dma->ops->stop_dma != OSI_NULL)) { - osi_dma->ops->stop_dma(osi_dma, chan); - return 0; + if (validate_args(osi_dma) < 0) { + return -1; } - return -1; + if (validate_dma_chan_num(osi_dma, chan) < 0) { + return -1; + } + + ops_p->stop_dma(osi_dma, chan); + + return 0; } nveu32_t osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring) @@ -274,9 +437,7 @@ static inline nve32_t rx_dma_desc_validate_args( struct osi_rx_ring *rx_ring, nveu32_t chan) { - /* Validate args */ - if (!((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && - (osi_dma->ops->update_rx_tailptr != OSI_NULL))) { + if (validate_args(osi_dma) < 0) { return -1; } @@ -287,9 +448,7 @@ static inline nve32_t rx_dma_desc_validate_args( return -1; } - if (chan >= OSI_EQOS_MAX_NUM_CHANS) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma: Invalid channel\n", 0ULL); + if (validate_dma_chan_num(osi_dma, chan) < 0) { return -1; } @@ -405,44 +564,62 @@ nve32_t osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, return -1; } - osi_dma->ops->update_rx_tailptr(osi_dma->base, chan, tailptr); + 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) { - if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && - (osi_dma->ops->set_rx_buf_len != OSI_NULL)) { - osi_dma->ops->set_rx_buf_len(osi_dma); - } else { + if (validate_args(osi_dma) < 0) { return -1; } + 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) { - if ((osi_dma != OSI_NULL) && (osi_dma->base != OSI_NULL)) { - common_get_systime_from_mac(osi_dma->base, osi_dma->mac, sec, - nsec); - } else { + if (validate_args(osi_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) { - if ((osi_dma != OSI_NULL) && (osi_dma->base != OSI_NULL)) { - return common_is_mac_enabled(osi_dma->base, osi_dma->mac); - } else { - return OSI_DISABLE; + if (validate_args(osi_dma) < 0) { + return -1; } + + 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) +{ + if (osi_unlikely(validate_args(osi_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], ops_p, chan); +} + #ifndef OSI_STRIPPED_LIB /** @@ -470,7 +647,7 @@ nveu32_t osi_is_mac_enabled(struct osi_dma_priv_data *const osi_dma) static inline nve32_t osi_slot_args_validate(struct osi_dma_priv_data *osi_dma, nveu32_t set) { - if (osi_dma == OSI_NULL) { + if (validate_args(osi_dma) < 0) { return -1; } @@ -481,14 +658,6 @@ static inline nve32_t osi_slot_args_validate(struct osi_dma_priv_data *osi_dma, return -1; } - /* NULL check for osi_dma, osi_dma->ops and osi_dma->ops->config_slot */ - if ((osi_dma->ops == OSI_NULL) || - (osi_dma->ops->config_slot == OSI_NULL)) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma: Invalid set argument\n", 0ULL); - return -1; - } - return 0; } @@ -506,11 +675,13 @@ nve32_t osi_config_slot_function(struct osi_dma_priv_data *osi_dma, 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 >= OSI_EQOS_MAX_NUM_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 */ @@ -530,10 +701,7 @@ nve32_t osi_config_slot_function(struct osi_dma_priv_data *osi_dma, return -1; } tx_ring->slot_check = set; - osi_dma->ops->config_slot(osi_dma, - chan, - set, - interval); + ops_p->config_slot(osi_dma, chan, set, interval); } } @@ -542,15 +710,11 @@ nve32_t osi_config_slot_function(struct osi_dma_priv_data *osi_dma, nve32_t osi_validate_dma_regs(struct osi_dma_priv_data *osi_dma) { - nve32_t ret = -1; - - if ((osi_dma != OSI_NULL) && (osi_dma->ops != OSI_NULL) && - (osi_dma->ops->validate_regs != OSI_NULL) && - (osi_dma->safety_config != OSI_NULL)) { - ret = osi_dma->ops->validate_regs(osi_dma); + if (validate_args(osi_dma) < 0) { + return -1; } - return ret; + return ops_p->validate_regs(osi_dma); } nve32_t osi_txring_empty(struct osi_dma_priv_data *osi_dma, nveu32_t chan) diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 49d02a8..7131cec 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -1008,78 +1008,28 @@ static inline void dmb_oshst(void) asm volatile("dmb oshst" : : : "memory"); } -/** - * @brief validate_hw_transmit_arg- Validate input argument of hw_transmit - * - * @note - * Algorithm: - * - This routine validate input arguments to osi_hw_transmit() - * - * @param[in] osi_dma: OSI DMA private data structure. - * @param[in] chan: Tx DMA channel number - * @param[out] ops: OSI DMA Channel operations - * @param[out] tx_ring: OSI DMA channel Tx 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_hw_transmit_arg( - struct osi_dma_priv_data *osi_dma, - nveu32_t chan, - struct osi_dma_chan_ops **ops, - struct osi_tx_ring **tx_ring) +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) { - if (osi_unlikely((osi_dma == OSI_NULL) || - (chan >= OSI_EQOS_MAX_NUM_CHANS))) { - return -1; - } - - *tx_ring = osi_dma->tx_ring[chan]; - *ops = osi_dma->ops; - - if (osi_unlikely((*tx_ring == OSI_NULL) || (*ops == OSI_NULL))) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "validate_hw_transmit_arg: Invalid pointers\n", - 0ULL); - return -1; - } - - return 0; -} - -void osi_hw_transmit(struct osi_dma_priv_data *osi_dma, nveu32_t chan) -{ - struct osi_tx_ring *tx_ring = OSI_NULL; - struct osi_dma_chan_ops *ops = OSI_NULL; - nveu32_t entry = 0U; + 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_pkt_cx *tx_pkt_cx = OSI_NULL; - nveu32_t desc_cnt = 0U; - struct osi_tx_desc *last_desc = OSI_NULL; - struct osi_tx_desc *first_desc = OSI_NULL; struct osi_tx_desc *cx_desc = OSI_NULL; - nveu64_t tailptr, tmp; nve32_t cntx_desc_consumed; + nveu32_t desc_cnt = 0U; + nveu64_t tailptr, tmp; + nveu32_t entry = 0U; nveu32_t i; - nve32_t ret = 0; - - ret = validate_hw_transmit_arg(osi_dma, chan, &ops, &tx_ring); - if (osi_unlikely(ret < 0)) { - return; - } entry = tx_ring->cur_tx_idx; if (entry >= TX_DESC_CNT) { OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma_txrx: Invalid pointers\n", 0ULL); - return; + "dma_txrx: Invalid cur_tx_idx\n", 0ULL); + return -1; } tx_desc = tx_ring->tx_desc + entry; @@ -1090,8 +1040,8 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi_dma, nveu32_t chan) if (osi_unlikely(desc_cnt == 0U)) { /* Will not hit this case */ OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma_txrx: Invalid value\n", 0ULL); - return; + "dma_txrx: Invalid desc_cnt\n", 0ULL); + return -1; } /* Context descriptor for VLAN/TSO */ if ((tx_pkt_cx->flags & OSI_PKT_CX_VLAN) == OSI_PKT_CX_VLAN) { @@ -1192,8 +1142,8 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi_dma, nveu32_t chan) 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 argument\n", 0ULL); - return; + "dma_txrx: Invalid tx_desc_phy_addr\n", 0ULL); + return -1; } tx_ring->cur_tx_idx = entry; @@ -1203,12 +1153,10 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi_dma, nveu32_t chan) * before setting up the DMA, hence add memory write barrier here. */ dmb_oshst(); - if (osi_unlikely(ops->update_tx_tailptr == OSI_NULL)) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma_txrx: Invalid argument\n", 0ULL); - return; - } + ops->update_tx_tailptr(osi_dma->base, chan, tailptr); + + return 0; } /** @@ -1222,6 +1170,7 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi_dma, nveu32_t chan) * * @param[in, out] osi_dma: OSI private data structure. * @param[in] chan: Rx channel number. + * @param[in] ops: DMA channel operations. * * @note * API Group: @@ -1233,12 +1182,12 @@ void osi_hw_transmit(struct osi_dma_priv_data *osi_dma, nveu32_t chan) * @retval -1 on failure. */ static nve32_t rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, - nveu32_t chan) + 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; - struct osi_dma_chan_ops *ops = osi_dma->ops; nveu64_t tailptr = 0, tmp; nveu32_t i; nve32_t ret = 0; @@ -1304,13 +1253,10 @@ static nve32_t rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, tailptr = rx_ring->rx_desc_phy_addr + (sizeof(struct osi_rx_desc) * (RX_DESC_CNT)); - if (osi_unlikely((tailptr < rx_ring->rx_desc_phy_addr) || - (ops->set_rx_ring_len == OSI_NULL) || - (ops->update_rx_tailptr == OSI_NULL) || - (ops->set_rx_ring_start_addr == OSI_NULL))) { + 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 pointers\n", 0ULL); + "dma_txrx: Invalid phys address\n", 0ULL); return -1; } @@ -1332,6 +1278,7 @@ static nve32_t rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, * 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: @@ -1342,7 +1289,8 @@ static nve32_t rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, * @retval 0 on success * @retval -1 on failure. */ -static nve32_t rx_dma_desc_init(struct osi_dma_priv_data *osi_dma) +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; @@ -1351,7 +1299,7 @@ static nve32_t rx_dma_desc_init(struct osi_dma_priv_data *osi_dma) for (i = 0; i < osi_dma->num_dma_chans; i++) { chan = osi_dma->dma_chans[i]; - ret = rx_dma_desc_initialization(osi_dma, chan); + ret = rx_dma_desc_initialization(osi_dma, chan, ops); if (ret != 0) { return ret; } @@ -1369,6 +1317,7 @@ static nve32_t rx_dma_desc_init(struct osi_dma_priv_data *osi_dma) * 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: @@ -1379,12 +1328,12 @@ static nve32_t rx_dma_desc_init(struct osi_dma_priv_data *osi_dma) * @retval 0 on success * @retval -1 on failure. */ -static nve32_t tx_dma_desc_init(struct osi_dma_priv_data *osi_dma) +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; - struct osi_dma_chan_ops *ops = osi_dma->ops; nveu32_t chan = 0; nveu32_t i, j; @@ -1420,32 +1369,26 @@ static nve32_t tx_dma_desc_init(struct osi_dma_priv_data *osi_dma) tx_ring->slot_number = 0U; tx_ring->slot_check = OSI_DISABLE; - if (osi_likely((ops->set_tx_ring_len != OSI_NULL) && - (ops->set_tx_ring_start_addr != OSI_NULL))) { - ops->set_tx_ring_len(osi_dma, chan, - (TX_DESC_CNT - 1U)); - ops->set_tx_ring_start_addr(osi_dma->base, chan, - tx_ring->tx_desc_phy_addr); - } else { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma_txrx: Invalid pointers\n", 0ULL); - return -1; - } + ops->set_tx_ring_len(osi_dma, chan, + (TX_DESC_CNT - 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) +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); + ret = tx_dma_desc_init(osi_dma, ops); if (ret != 0) { return ret; } - ret = rx_dma_desc_init(osi_dma); + ret = rx_dma_desc_init(osi_dma, ops); if (ret != 0) { return ret; } From 8829d1a4e55c9aac8c39c327dba03945e671652c Mon Sep 17 00:00:00 2001 From: rakesh goyal <rgoyal@nvidia.com> Date: Fri, 5 Mar 2021 20:57:38 +0530 Subject: [PATCH 156/458] osi: eqos: only interface APIs accessible form OSD Issue: Many non API functions are accessible from OSD code which can be used to update/access HW registers. Fix: Move non API function to local files and remove header files from code shared with OSD so these function can be accessible only within OSI code Bug 200671160 Change-Id: Ic396b3b34e20cd8ee6b252e745df12f4532d0e10 Signed-off-by: rakesh goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2494297 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/mmc.h | 5 ++++- include/osi_common.h | 33 +++++++++++++++++++++++++++++ include/osi_core.h | 3 +-- include/osi_dma.h | 2 +- osi/common/common.h | 35 +------------------------------ osi/common/include/local_common.h | 3 +-- osi/core/ivc_core.c | 1 + osi/core/osi_core.c | 1 + osi/dma/osi_dma_txrx.c | 1 + 9 files changed, 44 insertions(+), 40 deletions(-) diff --git a/include/mmc.h b/include/mmc.h index 461569e..e82b6b7 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -22,6 +22,9 @@ #ifndef INCLUDED_MMC_H #define INCLUDED_MMC_H + +#include "../osi/common/type.h" + /** * @brief osi_mmc_counters - The structure to hold RMON counter values */ diff --git a/include/osi_common.h b/include/osi_common.h index 4a0b42b..ba8d006 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -205,4 +205,37 @@ /** @} */ #endif /* OSI_STRIPPED_LIB */ +/** + * @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 + * + * @return nveu64_t value + */ +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 index 04d2a52..289b298 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -23,9 +23,8 @@ #ifndef INCLUDED_OSI_CORE_H #define INCLUDED_OSI_CORE_H -#include "../osi/common/common.h" +#include <osi_common.h> #include "mmc.h" -#include "../osi/common/type.h" /** * @addtogroup typedef related info diff --git a/include/osi_dma.h b/include/osi_dma.h index f9d6df6..d365946 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -23,7 +23,7 @@ #ifndef INCLUDED_OSI_DMA_H #define INCLUDED_OSI_DMA_H -#include "../osi/common/common.h" +#include <osi_common.h> #include "osi_dma_txrx.h" /** diff --git a/osi/common/common.h b/osi/common/common.h index f13f357..0864669 100644 --- a/osi/common/common.h +++ b/osi/common/common.h @@ -22,6 +22,7 @@ #ifndef INCLUDED_COMMON_H #define INCLUDED_COMMON_H +#include "../osi/common/type.h" #include <osi_common.h> struct osi_core_priv_data; @@ -216,40 +217,6 @@ static inline nve32_t is_valid_mac_version(nveu32_t mac_ver) return 0; } -/** - * @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 - * - * @return nveu64_t value - */ -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; -} - /** * @brief osi_memset - osi memset * diff --git a/osi/common/include/local_common.h b/osi/common/include/local_common.h index 903af66..9251d95 100644 --- a/osi/common/include/local_common.h +++ b/osi/common/include/local_common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -24,7 +24,6 @@ #define LOCAL_COMMON_H #include <osi_common.h> -#include "../osi/common/type.h" /** *@brief div_u64_rem - updates remainder and returns Quotient diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index 5614e84..30ee0b3 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -26,6 +26,7 @@ #include "eqos_core.h" #include "eqos_mmc.h" #include "core_local.h" +#include "../osi/common/common.h" /** * @brief ivc_safety_config - EQOS MAC core safety configuration diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 6a0e7f6..52be9c0 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -23,6 +23,7 @@ #include <local_common.h> #include <ivc_core.h> #include "core_local.h" +#include "../osi/common/common.h" /** * @brief g_core - Static core local data variable diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 7131cec..7a28171 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -24,6 +24,7 @@ #include <osi_dma_txrx.h> #include "../osi/common/type.h" #include "hw_desc.h" +#include "../osi/common/common.h" /** * @brief get_rx_csum - Get the Rx checksum from descriptor if valid From 22f0539c22df0823c6440a3935ff323e9ac2db7a Mon Sep 17 00:00:00 2001 From: Nagarjuna Kristam <nkristam@nvidia.com> Date: Wed, 3 Mar 2021 11:42:58 +0530 Subject: [PATCH 157/458] osi: Update numberic literal usage to MACROS Issue: Need to use MACRO's wherever possible for numeric literals. Fix: Update numeric literal usage to MACROS. Bug 200684454 Change-Id: I340342a8680f3caee0856440e9f03aacd85e48ac Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2492366 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/common/common.h | 10 ++++++ osi/core/eqos_core.c | 82 +++++++++++++++++++++--------------------- osi/core/eqos_core.h | 5 +++ osi/dma/osi_dma_txrx.c | 8 ++--- 4 files changed, 61 insertions(+), 44 deletions(-) diff --git a/osi/common/common.h b/osi/common/common.h index 0864669..8177d49 100644 --- a/osi/common/common.h +++ b/osi/common/common.h @@ -25,6 +25,16 @@ #include "../osi/common/type.h" #include <osi_common.h> +/** + * @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 +/** @} */ struct osi_core_priv_data; /** diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 942013f..6aa2ec1 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -487,14 +487,14 @@ static nve32_t eqos_config_fw_err_pkts( static nve32_t eqos_poll_for_swr(struct osi_core_priv_data *const osi_core) { void *addr = osi_core->base; - nveu32_t retry = 1000; + nveu32_t retry = RETRY_COUNT; nveu32_t count; nveu32_t dma_bmr = 0; - nve32_t cond = 1; + nve32_t cond = COND_NOT_MET; nveu32_t pre_si = osi_core->pre_si; if (pre_si == OSI_ENABLE) { - osi_writela(osi_core, 0x1U, + osi_writela(osi_core, OSI_ENABLE, (nveu8_t *)addr + EQOS_DMA_BMR); } /* add delay of 10 usec */ @@ -502,7 +502,7 @@ static nve32_t eqos_poll_for_swr(struct osi_core_priv_data *const osi_core) /* Poll Until Poll Condition */ count = 0; - while (cond == 1) { + while (cond == COND_NOT_MET) { if (count > retry) { OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, "poll_for_swr: timeout\n", 0ULL); @@ -514,8 +514,8 @@ static nve32_t eqos_poll_for_swr(struct osi_core_priv_data *const osi_core) dma_bmr = osi_readla(osi_core, (nveu8_t *)addr + EQOS_DMA_BMR); - if ((dma_bmr & EQOS_DMA_BMR_SWR) == 0U) { - cond = 0; + if ((dma_bmr & EQOS_DMA_BMR_SWR) != EQOS_DMA_BMR_SWR) { + cond = COND_MET; } else { osi_core->osd_ops.msleep(1U); } @@ -759,9 +759,9 @@ static nveu32_t eqos_calculate_per_queue_fifo(nveu32_t fifo_size, static nve32_t eqos_pad_calibrate(struct osi_core_priv_data *const osi_core) { void *ioaddr = osi_core->base; - nveu32_t retry = 1000; + nveu32_t retry = RETRY_COUNT; nveu32_t count; - nve32_t cond = 1, ret = 0; + nve32_t cond = COND_NOT_MET, ret = 0; nveu32_t value; /* 1. Set field PAD_E_INPUT_OR_E_PWRD in @@ -791,7 +791,7 @@ static nve32_t eqos_pad_calibrate(struct osi_core_priv_data *const osi_core) /* 5. Wait on AUTO_CAL_ACTIVE until it is 0. 10ms is the timeout */ count = 0; - while (cond == 1) { + while (cond == COND_NOT_MET) { if (count > retry) { ret = -1; goto calibration_failed; @@ -802,7 +802,7 @@ static nve32_t eqos_pad_calibrate(struct osi_core_priv_data *const osi_core) EQOS_PAD_AUTO_CAL_STAT); /* calibration done when CAL_STAT_ACTIVE is zero */ if ((value & EQOS_PAD_AUTO_CAL_STAT_ACTIVE) == 0U) { - cond = 0; + cond = COND_MET; } } @@ -841,10 +841,10 @@ static nve32_t eqos_flush_mtl_tx_queue( const nveu32_t qinx) { void *addr = osi_core->base; - nveu32_t retry = 1000; + nveu32_t retry = RETRY_COUNT; nveu32_t count; nveu32_t value; - nve32_t cond = 1; + nve32_t cond = COND_NOT_MET; if (qinx >= OSI_EQOS_MAX_NUM_QUEUES) { OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, @@ -862,7 +862,7 @@ static nve32_t eqos_flush_mtl_tx_queue( /* Poll Until FTQ bit resets for Successful Tx Q flush */ count = 0; - while (cond == 1) { + while (cond == COND_NOT_MET) { if (count > retry) { OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "Poll FTQ bit timeout\n", 0ULL); @@ -876,7 +876,7 @@ static nve32_t eqos_flush_mtl_tx_queue( EQOS_MTL_CHX_TX_OP_MODE(qinx)); if ((value & EQOS_MTL_QTOMR_FTQ_LPOS) == 0U) { - cond = 0; + cond = COND_MET; } } @@ -1064,7 +1064,7 @@ static nve32_t eqos_configure_mtl_queue(nveu32_t qinx, /* Enable Rx Queue Control */ value = osi_readla(osi_core, (nveu8_t *)osi_core->base + EQOS_MAC_RQC0R); - value |= ((osi_core->rxq_ctrl[qinx] & 0x3U) << (qinx * 2U)); + 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); @@ -1163,7 +1163,7 @@ static void eqos_configure_rxq_priority( /* 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]) == 0)) { pmask |= osi_core->rxq_prio[mtlq]; temp = osi_core->rxq_prio[mtlq]; } else { @@ -1281,13 +1281,13 @@ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) /* Disable all MMC interrupts */ /* Disable all MMC Tx Interrupts */ - osi_writela(osi_core, 0xFFFFFFFFU, (nveu8_t *)osi_core->base + + 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, 0xFFFFFFFFU, (nveu8_t *)osi_core->base + + 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, 0xFFFFFFFFU, (nveu8_t *)osi_core->base + + osi_writela(osi_core, EQOS_MMC_INTR_DISABLE, (nveu8_t *)osi_core->base + EQOS_MMC_IPC_RX_INTR_MASK); /* Configure MMC counters */ @@ -1683,7 +1683,7 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *const osi_core) //FIXME Need to check how we can get the DMA channel here instead of //MTL Queues - if ((dma_isr & 0xFU) != 0U) { + 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]; @@ -1889,12 +1889,12 @@ static nve32_t eqos_config_mac_pkt_filter_reg( 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) != 0x0U) { + 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) != 0x0U) { + 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); } @@ -2093,7 +2093,8 @@ static nve32_t eqos_config_l3_l4_filter_enable( 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 << 20) & 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); @@ -2628,7 +2629,8 @@ static nve32_t eqos_config_l4_filters( value = osi_readla(osi_core, (nveu8_t *)base + EQOS_MAC_L3L4_CTR(filter_no)); value &= ~EQOS_MAC_L3L4_CTR_L4PEN0; - value |= ((tcp_udp_match << 16) & 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)); @@ -2719,15 +2721,15 @@ static inline nve32_t eqos_poll_for_tsinit_complete( struct osi_core_priv_data *const osi_core, nveu32_t *mac_tcr) { - nveu32_t retry = 1000; + nveu32_t retry = RETRY_COUNT; nveu32_t count; - nve32_t cond = 1; + nve32_t cond = COND_NOT_MET; /* Wait for previous(if any) Initialize Timestamp value * update to complete */ count = 0; - while (cond == 1) { + while (cond == COND_NOT_MET) { if (count > retry) { OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, "poll_for_tsinit: timeout\n", 0ULL); @@ -2737,7 +2739,7 @@ static inline nve32_t eqos_poll_for_tsinit_complete( *mac_tcr = osi_readla(osi_core, (nveu8_t *)osi_core->base + EQOS_MAC_TCR); if ((*mac_tcr & EQOS_MAC_TCR_TSINIT) == 0U) { - cond = 0; + cond = COND_MET; } count++; osi_core->osd_ops.udelay(1000U); @@ -2832,14 +2834,14 @@ static inline nve32_t eqos_poll_for_addend_complete( struct osi_core_priv_data *const osi_core, nveu32_t *mac_tcr) { - nveu32_t retry = 1000; + nveu32_t retry = RETRY_COUNT; nveu32_t count; - nve32_t cond = 1; + nve32_t cond = COND_NOT_MET; /* Wait for previous(if any) addend value update to complete */ /* Poll */ count = 0; - while (cond == 1) { + while (cond == COND_NOT_MET) { if (count > retry) { OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, "poll_for_addend: timeout\n", 0ULL); @@ -2849,7 +2851,7 @@ static inline nve32_t eqos_poll_for_addend_complete( *mac_tcr = osi_readla(osi_core, (nveu8_t *)osi_core->base + EQOS_MAC_TCR); if ((*mac_tcr & EQOS_MAC_TCR_TSADDREG) == 0U) { - cond = 0; + cond = COND_MET; } count++; osi_core->osd_ops.udelay(1000U); @@ -2936,13 +2938,13 @@ 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 = 1000; + nveu32_t retry = RETRY_COUNT; nveu32_t count; - nve32_t cond = 1; + nve32_t cond = COND_NOT_MET; /* Wait for previous(if any) time stamp value update to complete */ count = 0; - while (cond == 1) { + 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); @@ -2952,7 +2954,7 @@ static inline nve32_t eqos_poll_for_update_ts_complete( *mac_tcr = osi_readla(osi_core, (nveu8_t *)osi_core->base + EQOS_MAC_TCR); if ((*mac_tcr & EQOS_MAC_TCR_TSUPDT) == 0U) { - cond = 0; + cond = COND_MET; } count++; osi_core->osd_ops.udelay(1000U); @@ -3235,13 +3237,13 @@ static void eqos_core_deinit(struct osi_core_priv_data *const osi_core) static inline nve32_t poll_for_mii_idle(struct osi_core_priv_data *osi_core) { /* half sec timeout */ - nveu32_t retry = 50000; + nveu32_t retry = ((RETRY_COUNT) * 50U); nveu32_t mac_gmiiar; nveu32_t count; - nve32_t cond = 1; + nve32_t cond = COND_NOT_MET; count = 0; - while (cond == 1) { + 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); @@ -3253,7 +3255,7 @@ static inline nve32_t poll_for_mii_idle(struct osi_core_priv_data *osi_core) EQOS_MAC_MDIO_ADDRESS); if ((mac_gmiiar & EQOS_MAC_GMII_BUSY) == 0U) { /* exit loop */ - cond = 0; + cond = COND_MET; } else { /* wait on GMII Busy set */ osi_core->osd_ops.udelay(10U); diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 710a99e..42beca2 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -309,6 +309,7 @@ #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 @@ -321,6 +322,7 @@ #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) @@ -395,6 +397,7 @@ #define EQOS_MAC_GMII_BUSY 0x00000001U #define EQOS_MAC_EXTR_GPSL_MSK 0x00003FFFU +#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) @@ -421,6 +424,7 @@ (TEGRA_SID_EQOS_CH6) |\ (TEGRA_SID_EQOS_CH5) |\ (TEGRA_SID_EQOS)) +#define EQOS_MMC_INTR_DISABLE 0xFFFFFFFFU /** @} */ void update_ehfc_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value); @@ -445,6 +449,7 @@ void update_ehfc_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value); #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 diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 7a28171..a09eb64 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -160,7 +160,7 @@ static inline void get_rx_vlan_from_desc(struct osi_rx_desc *rx_desc, */ static inline nve32_t get_rx_tstamp_status(struct osi_rx_desc *context_desc) { - if (((context_desc->rdes3 & RDES3_OWN) == 0U) && + if (((context_desc->rdes3 & RDES3_OWN) != RDES3_OWN) && ((context_desc->rdes3 & RDES3_CTXT) == RDES3_CTXT)) { if (((context_desc->rdes0 == OSI_INVALID_VALUE) && (context_desc->rdes1 == OSI_INVALID_VALUE))) { @@ -208,7 +208,7 @@ static nve32_t get_rx_hwstamp(struct osi_dma_priv_data *osi_dma, /* 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)) { + ((rx_desc->rdes1 & RDES1_TD) != RDES1_TD)) { for (retry = 0; retry < 10; retry++) { ret = get_rx_tstamp_status(context_desc); if (ret == 0) { @@ -772,9 +772,9 @@ nve32_t osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, } if (((tx_desc->tdes3 & TDES3_LD) == TDES3_LD) && - ((tx_desc->tdes3 & TDES3_CTXT) == 0U)) { + ((tx_desc->tdes3 & TDES3_CTXT) != TDES3_CTXT)) { /* check tx tstamp status */ - if ((tx_desc->tdes3 & TDES3_TTSS) != 0U) { + if ((tx_desc->tdes3 & TDES3_TTSS) == TDES3_TTSS) { /* tx timestamp captured for this packet */ ns = tx_desc->tdes0; vartdes1 = tx_desc->tdes1; From cf04dbff29e3a4e27b9ad11881b8113e28fd978a Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Fri, 12 Mar 2021 13:40:38 +0530 Subject: [PATCH 158/458] osi: single API to handle DMA interrupts Issue: Currently there are multiple API's for handling DMA interrupts. Fix: Creating single API to handle DMA interrupts. Bug 200671160 Change-Id: I9385e8fb0ca044c7a01d38483226e2e83f76f5b9 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2497610 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_dma.h | 56 +++++++++++++++++++++++++++++++++++++++++++++ osi/dma/dma_local.h | 4 ++++ osi/dma/eqos_dma.c | 4 ++++ osi/dma/osi_dma.c | 45 ++++++++++++++++++++++++++++++++++++ 4 files changed, 109 insertions(+) diff --git a/include/osi_dma.h b/include/osi_dma.h index d365946..62668ee 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -182,6 +182,19 @@ /** @} */ +/** + * @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 +/** @} */ + /** * @brief OSI packet error stats */ @@ -1201,6 +1214,49 @@ nve32_t osi_dma_get_systime_from_mac(struct osi_dma_priv_data *const osi_dma, */ 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 + * + * @note + * Classification: + * - Interrupt: Yes + * - Signal handler: Yes + * - 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. + */ +nve32_t osi_handle_dma_intr(struct osi_dma_priv_data *osi_dma, + nveu32_t chan, nveu32_t tx_rx, nveu32_t en_dis); #ifndef OSI_STRIPPED_LIB /** * @brief - Read-validate HW registers for func safety. diff --git a/osi/dma/dma_local.h b/osi/dma/dma_local.h index 4e301fb..5351157 100644 --- a/osi/dma/dma_local.h +++ b/osi/dma/dma_local.h @@ -93,6 +93,10 @@ struct dma_local { struct dma_chan_ops ops; /** Flag to represent OSI DMA software init done */ unsigned int 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; }; void eqos_init_dma_chan_ops(struct dma_chan_ops *ops); diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index 1ef19ae..53b4581 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -966,6 +966,8 @@ static void eqos_clear_vm_tx_intr(void *addr, nveu32_t chan) (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); } /** @@ -990,6 +992,8 @@ static void eqos_clear_vm_rx_intr(void *addr, nveu32_t chan) (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); } /** diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 282c78c..3bc2f44 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -23,6 +23,7 @@ #include "dma_local.h" #include <local_common.h> #include "hw_desc.h" +#include "../osi/common/common.h" /** * @brief g_dma - DMA local data variable @@ -227,6 +228,19 @@ nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) return ret; } + g_dma.mac_ver = osi_readl((unsigned char *)osi_dma->base + MAC_VERSION) & + MAC_VERSION_SNVER_MASK; + if (is_valid_mac_version(g_dma.mac_ver) == 0) { + OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "Invalid MAC version\n", (nveu64_t)g_dma.mac_ver); + return -1; + } + + if ((g_dma.mac_ver != OSI_EQOS_MAC_4_10) && + (g_dma.mac_ver != OSI_EQOS_MAC_5_00)) { + g_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]; @@ -371,6 +385,37 @@ nveu32_t osi_get_global_dma_status(struct osi_dma_priv_data *osi_dma) return ops_p->get_global_dma_status(osi_dma->base); } +nve32_t osi_handle_dma_intr(struct osi_dma_priv_data *osi_dma, + nveu32_t chan, + nveu32_t tx_rx, + nveu32_t en_dis) +{ + typedef void (*dma_intr_fn)(void *, nveu32_t); + dma_intr_fn fn[2][2][2] = { + { { ops_p->disable_chan_tx_intr, ops_p->enable_chan_tx_intr }, + { ops_p->disable_chan_rx_intr, ops_p->enable_chan_rx_intr } }, + { { ops_p->clear_vm_tx_intr, ops_p->enable_chan_tx_intr }, + { ops_p->clear_vm_rx_intr, ops_p->enable_chan_rx_intr } } + }; + + if (validate_args(osi_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[g_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) { From e69d2b2ad45b3372bb7720bc0db8ab122f9aaac8 Mon Sep 17 00:00:00 2001 From: rakesh goyal <rgoyal@nvidia.com> Date: Thu, 18 Feb 2021 21:49:59 +0530 Subject: [PATCH 159/458] core: handle ioctl in single API To reduce number of external interface APIs, consolidate all IOCTL API to one interface API. Bug 200671160 Change-Id: I324bf794b66f6267b9cf4c64059bdd07b90579d4 Signed-off-by: rakesh goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2493164 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_core.h | 706 ++++++++++++-------------------------------- osi/core/osi_core.c | 474 +++++++++++++++++++---------- 2 files changed, 502 insertions(+), 678 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 289b298..cd6dc35 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -144,6 +144,47 @@ typedef my_lint_64 nvel64_t; #define TWO_POWER_31 0x80000000U /** @} */ +/** + * @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 +/** @} */ + /** * @brief OSI error macro definition, * @param[in] priv: OSD private data OR NULL @@ -666,6 +707,42 @@ struct osd_core_ops { nve32_t (*ivc_send)(void *priv, void *data, nveu32_t len); }; +/** + * @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 */ +}; + /** * @brief The OSI Core (MAC & MTL) private data structure. */ @@ -1595,533 +1672,117 @@ nve32_t osi_get_mac_version(struct osi_core_priv_data *const osi_core, nve32_t osi_get_hw_features(struct osi_core_priv_data *const osi_core, struct osi_hw_features *hw_feat); -#ifndef OSI_STRIPPED_LIB /** - * @brief osi_validate_core_regs - Read-validate HW registers for func safety. + * @brief osi_handle_ioctl - API to handle runtime command * * @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 - * 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. - */ -nve32_t osi_validate_core_regs(struct osi_core_priv_data *const osi_core); - -/** - * @brief osi_flush_mtl_tx_queue - Flushing a MTL Tx Queue. - * - * @note - * Algorithm: - * - Invokes EQOS flush Tx queue routine. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] qinx: MTL queue index. - * - * @pre - * - MAC should out of reset and clocks enabled. - * - hw core initialized. see osi_hw_core_init(). - * - * @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. - */ -nve32_t osi_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, - const nveu32_t qinx); - -/** - * @brief osi_set_avb - Set CBS algo and parameters - * - * @note - * Algorithm: - * - Set AVB algo and populated parameter from osi_core_avb - * structure for TC/TQ - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] avb: osi core avb data structure. - * - * @pre - * - MAC should be init and started. see osi_start_mac() - * - osi_core->osd should be populated. - * - * @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. - */ -nve32_t osi_set_avb(struct osi_core_priv_data *const osi_core, - const struct osi_core_avb_algorithm *avb); - -/** - * @brief osi_get_avb - Get CBS algo and parameters - * - * @note - * Algorithm: - * - get AVB algo and populated parameter from osi_core_avb - * structure for TC/TQ - * - * @param[in] osi_core: OSI core private data structure. - * @param[out] avb: osi core avb data structure. - * - * @pre - * - MAC should be init and started. see osi_start_mac() - * - osi_core->osd should be populated. - * - * @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. - */ -nve32_t osi_get_avb(struct osi_core_priv_data *const osi_core, - struct osi_core_avb_algorithm *avb); - -/** - * @brief osi_configure_txstatus - Configure Tx packet status reporting - * - * @note - * Algorithm: - * - Configure MAC to enable/disable Tx status error - * reporting. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] tx_status: Enable or disable tx packet status reporting - * - * @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: No - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_configure_txstatus(struct osi_core_priv_data *const osi_core, - const nveu32_t tx_status); - -/** - * @brief osi_config_rx_crc_check - Configure CRC Checking for Received 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 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. - */ -nve32_t osi_config_rx_crc_check(struct osi_core_priv_data *const osi_core, - const nveu32_t crc_chk); - -/** - * @brief osi_configure_flow_ctrl - Configure flow control settings - * - * @note - * Algorithm: - * - This will enable or disable the flow control. - * flw_ctrl BIT0 is for tx flow ctrl enable/disable - * flw_ctrl BIT1 is for rx flow ctrl enable/disable - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] flw_ctrl: Enable or disable flow control settings - * - * @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. - */ -nve32_t osi_configure_flow_control(struct osi_core_priv_data *const osi_core, - const nveu32_t flw_ctrl); - -/** - * @brief osi_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. - */ -nve32_t osi_config_arp_offload(struct osi_core_priv_data *const osi_core, - const nveu32_t flags, - const nveu8_t *ip_addr); -/** - * @brief osi_config_vlan_filtering - OSI call for configuring VLAN filter - * - * @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 private data structure. - * @param[in] filter_enb_dis: vlan filter enable(1) disable(0) - * @param[in] perfect_hash_filtering: perfect(0) or hash filter(1) - * @param[in] perfect_inverse_match: normal(0) or inverse filter(1) - * - * @pre - * - MAC should be init and started. see osi_start_mac() - * - osi_core->osd should be populated - * - * @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. - */ -nve32_t osi_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); - -/** - * @brief osi_update_vlan_id - 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. - */ -nve32_t osi_update_vlan_id(struct osi_core_priv_data *const osi_core, - const nveu32_t vid); - -/** - * @brief osi_reset_mmc - invoke function to reset MMC counter and data - * structure - * - * @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: - * - * @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. - */ -nve32_t osi_reset_mmc(struct osi_core_priv_data *const osi_core); - -/** - * @brief osi_configure_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 + * - 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) - * - * @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. - */ -nve32_t osi_configure_eee(struct osi_core_priv_data *const osi_core, - nveu32_t tx_lpi_enabled, - nveu32_t tx_lpi_timer); - -/** - * @brief osi_save_registers - Take backup of MAC MMIO address space + * - 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 * * @param[in] osi_core: OSI core private data structure. - * - * @pre - * - MAC and PHY should be init and started. see osi_start_mac() - * - No further configuration change in MAC shall be done after invoking - * this API - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_save_registers(struct osi_core_priv_data *const osi_core); - -/** - * @brief osi_restore_registers - Restore backup of MAC MMIO address space - * - * @param[in] osi_core: OSI core private data structure. - * - * @pre - * - MAC and PHY 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. - */ -nve32_t osi_restore_registers(struct osi_core_priv_data *const osi_core); - -/** - * @brief osi_set_mdc_clk_rate - Derive MDC clock based on provided AXI_CBB clk. - * - * @note - * Algorithm: - * - MDC clock rate will be populated in 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. - * - * @note OSD layer needs get the AXI CBB clock rate with OSD clock API - * (ex - clk_get_rate()) - * - * @note - * Traceability Details: - * - * @note - * Classification: - * - Interrupt: No - * - Signal handler: No - * - Thread safe: No - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, - const nveu64_t csr_clk_rate); - -/** - * @brief osi_config_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 + * @param[in] data: void pointer pointing to osi_ioctl * * @pre MAC should be init and started. see osi_start_mac() * @@ -2144,7 +1805,6 @@ nve32_t osi_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -nve32_t osi_config_mac_loopback(struct osi_core_priv_data *const osi_core, - const nveu32_t lb_mode); -#endif /* !OSI_STRIPPED_LIB */ +nve32_t osi_handle_ioctl(struct osi_core_priv_data *osi_core, + struct osi_ioctl *data); #endif /* INCLUDED_OSI_CORE_H */ diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 52be9c0..c1a486f 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -553,7 +553,7 @@ nve32_t osi_adjust_freq(struct osi_core_priv_data *const osi_core, nve32_t ppb) } else { OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "addend > UINT_MAX\n", 0ULL); - return -1; + return ret; } } else { if (addend > diff) { @@ -713,12 +713,44 @@ nve32_t osi_get_mac_version(struct osi_core_priv_data *const osi_core, } #ifndef OSI_STRIPPED_LIB -nve32_t osi_validate_core_regs(struct osi_core_priv_data *const osi_core) +/** + * @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_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) { - if (validate_args(osi_core) < 0) { - return -1; - } - if (osi_core->safety_config == OSI_NULL) { OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "CORE: Safety config is NULL\n", 0ULL); @@ -728,100 +760,43 @@ nve32_t osi_validate_core_regs(struct osi_core_priv_data *const osi_core) return ops_p->validate_regs(osi_core); } -nve32_t osi_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, - const nveu32_t qinx) +/** + * @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) { - if (validate_args(osi_core) < 0) { - return -1; - } - - return ops_p->flush_mtl_tx_queue(osi_core, qinx); -} - -nve32_t osi_set_avb(struct osi_core_priv_data *const osi_core, - const struct osi_core_avb_algorithm *avb) -{ - if (validate_args(osi_core) < 0) { - return -1; - } - - return ops_p->set_avb_algorithm(osi_core, avb); -} - -nve32_t osi_get_avb(struct osi_core_priv_data *const osi_core, - struct osi_core_avb_algorithm *avb) -{ - if (validate_args(osi_core) < 0) { - return -1; - } - - return ops_p->get_avb_algorithm(osi_core, avb); -} - -nve32_t osi_configure_txstatus(struct osi_core_priv_data *const osi_core, - const nveu32_t tx_status) -{ - if (validate_args(osi_core) < 0) { - return -1; - } - - /* Configure Drop Transmit Status */ - return ops_p->config_tx_status(osi_core, tx_status); -} - -nve32_t osi_config_rx_crc_check(struct osi_core_priv_data *const osi_core, - const nveu32_t crc_chk) -{ - if (validate_args(osi_core) < 0) { - return -1; - } - - /* Configure CRC Checking for Received Packets */ - return ops_p->config_rx_crc_check(osi_core, crc_chk); -} - -nve32_t osi_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) -{ - if (validate_args(osi_core) < 0) { - return -1; - } - - return ops_p->config_vlan_filtering(osi_core, filter_enb_dis, - perfect_hash_filtering, - perfect_inverse_match); -} - -nve32_t osi_update_vlan_id(struct osi_core_priv_data *const osi_core, - const nveu32_t vid) -{ - if (validate_args(osi_core) < 0) { - return -1; - } - - return ops_p->update_vlan_id(osi_core, vid); -} - -nve32_t osi_reset_mmc(struct osi_core_priv_data *const osi_core) -{ - if (validate_args(osi_core) < 0) { - return -1; - } - - ops_p->reset_mmc(osi_core); - - return 0; -} - -nve32_t osi_configure_eee(struct osi_core_priv_data *const osi_core, - nveu32_t tx_lpi_enabled, nveu32_t tx_lpi_timer) -{ - if (validate_args(osi_core) < 0) { - return -1; - } - 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)) { @@ -836,45 +811,44 @@ nve32_t osi_configure_eee(struct osi_core_priv_data *const osi_core, return 0; } -nve32_t osi_save_registers(struct osi_core_priv_data *const osi_core) +/** + * @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) { - if (validate_args(osi_core) < 0) { - return -1; - } - - /* Call MAC save registers callback and return the value */ - return ops_p->save_registers(osi_core); -} - -nve32_t osi_restore_registers(struct osi_core_priv_data *const osi_core) -{ - if (validate_args(osi_core) < 0) { - return -1; - } - - /* Call MAC restore registers callback and return the value */ - return ops_p->restore_registers(osi_core); -} - -nve32_t osi_configure_flow_control(struct osi_core_priv_data *const osi_core, - const nveu32_t flw_ctrl) -{ - if (validate_args(osi_core) < 0) { - return -1; - } - - /* Configure Flow control settings */ - return ops_p->config_flow_control(osi_core, flw_ctrl); -} - -nve32_t osi_config_arp_offload(struct osi_core_priv_data *const osi_core, - const nveu32_t flags, - const nveu8_t *ip_addr) -{ - if ((validate_args(osi_core) < 0)) { - return -1; - } - if (ip_addr == OSI_NULL) { OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "CORE: ip_addr is NULL\n", 0ULL); @@ -890,25 +864,40 @@ nve32_t osi_config_arp_offload(struct osi_core_priv_data *const osi_core, return ops_p->config_arp_offload(osi_core, flags, ip_addr); } -nve32_t osi_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, - const nveu64_t csr_clk_rate) +/** + * @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) { - if (validate_args(osi_core) < 0) { - return -1; - } - - ops_p->set_mdc_clk_rate(osi_core, csr_clk_rate); - - return 0; -} - -nve32_t osi_config_mac_loopback(struct osi_core_priv_data *const osi_core, - const nveu32_t lb_mode) -{ - if (validate_args(osi_core) < 0) { - return -1; - } - /* 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, @@ -921,6 +910,181 @@ nve32_t osi_config_mac_loopback(struct osi_core_priv_data *const osi_core, } #endif /* !OSI_STRIPPED_LIB */ +nve32_t osi_handle_ioctl(struct osi_core_priv_data *osi_core, + struct osi_ioctl *data) +{ + nve32_t ret = -1; + + if (validate_args(osi_core) < 0) { + return ret; + } + + if (data == OSI_NULL) { + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "CORE: Invalid argument\n", 0ULL); + return ret; + } + + 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 = ops_p->update_vlan_id(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: + ops_p->set_speed(osi_core, data->arg6_32); + ret = 0; + 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); + break; + + case OSI_CMD_ADJ_TIME: + ret = osi_adjust_time(osi_core, data->arg8_64); + break; + + case OSI_CMD_CONFIG_PTP: + ret = osi_ptp_configuration(osi_core, data->arg1_u32); + 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); + break; + + 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) { From d2a5a525586f8b58ead21da2e5548c2d1892e248 Mon Sep 17 00:00:00 2001 From: nannaiah <nannaiah@nvidia.com> Date: Mon, 15 Mar 2021 22:57:58 -0700 Subject: [PATCH 160/458] nvethernetrm: Add IVC support to read mmc counters. Bug 2694285 Change-Id: I4d88b99968a90108fcb218eb607318da14875834 Signed-off-by: Nagaraj Annaiah <nannaiah@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2499175 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: Ajay Gupta <ajayg@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/ivc_core.h | 4 +++- osi/core/eqos_mmc.c | 10 ++++++---- osi/core/ivc_core.c | 2 ++ 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/include/ivc_core.h b/include/ivc_core.h index 7fa69fc..109162d 100644 --- a/include/ivc_core.h +++ b/include/ivc_core.h @@ -27,7 +27,7 @@ /** * @brief Ethernet Maximum IVC BUF */ -#define ETHER_MAX_IVC_BUF 1024 +#define ETHER_MAX_IVC_BUF 2048 /** * @brief IVC maximum arguments @@ -161,6 +161,8 @@ typedef struct ivc_msg_common { struct osi_filter filter; /** OSI HW features */ struct osi_hw_features hw_feat; + /** MMC counters */ + struct osi_mmc_counters mmc; /** * core argument structure */ diff --git a/osi/core/eqos_mmc.c b/osi/core/eqos_mmc.c index 24e1a6d..a9cb69d 100644 --- a/osi/core/eqos_mmc.c +++ b/osi/core/eqos_mmc.c @@ -55,8 +55,8 @@ static inline nveu64_t update_mmc_val(struct osi_core_priv_data *const osi_core, nveu64_t offset) { nveu64_t temp; - nveu32_t value = osi_readl((nveu8_t *)osi_core->base + - offset); + nveu32_t value = osi_readla(osi_core, + (nveu8_t *)osi_core->base + offset); temp = last_value + value; if (temp < last_value) { @@ -92,10 +92,12 @@ void eqos_reset_mmc(struct osi_core_priv_data *const osi_core) { nveu32_t value; - value = osi_readl((nveu8_t *)osi_core->base + EQOS_MMC_CNTRL); + 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_writel(value, (nveu8_t *)osi_core->base + EQOS_MMC_CNTRL); + osi_writela(osi_core, value, + (nveu8_t *)osi_core->base + EQOS_MMC_CNTRL); osi_memset(&osi_core->mmc, 0U, sizeof(struct osi_mmc_counters)); } diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index 30ee0b3..49dd4bf 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -852,6 +852,8 @@ static void ivc_read_mmc(struct osi_core_priv_data *osi_core) osi_core->osd_ops.ivc_send(osi_core, &msg_common, sizeof(msg_common)); + osi_memcpy((void *)&osi_core->mmc, (void *)&msg_common.data.mmc, + sizeof(struct osi_mmc_counters)); } /** From c69f69c9d0bf115e6d85f9cee9a534df5613da4c Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Wed, 31 Mar 2021 13:58:19 +0530 Subject: [PATCH 161/458] Revert "core: handle ioctl in single API" This reverts commit 6b8e39f6d34199f6b0c1314ac1ba1f78eb6644f2. Bug 200671160 Change-Id: Icf22d93e83efbff7cb2a3cdfd5d169e3fd454b4a Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> --- include/osi_core.h | 708 ++++++++++++++++++++++++++++++++------------ osi/core/osi_core.c | 474 ++++++++++------------------- 2 files changed, 679 insertions(+), 503 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index cd6dc35..289b298 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -144,47 +144,6 @@ typedef my_lint_64 nvel64_t; #define TWO_POWER_31 0x80000000U /** @} */ -/** - * @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 -/** @} */ - /** * @brief OSI error macro definition, * @param[in] priv: OSD private data OR NULL @@ -707,42 +666,6 @@ struct osd_core_ops { nve32_t (*ivc_send)(void *priv, void *data, nveu32_t len); }; -/** - * @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 */ -}; - /** * @brief The OSI Core (MAC & MTL) private data structure. */ @@ -1672,117 +1595,533 @@ nve32_t osi_get_mac_version(struct osi_core_priv_data *const osi_core, nve32_t osi_get_hw_features(struct osi_core_priv_data *const osi_core, struct osi_hw_features *hw_feat); +#ifndef OSI_STRIPPED_LIB /** - * @brief osi_handle_ioctl - API to handle runtime command + * @brief osi_validate_core_regs - Read-validate HW registers for func safety. * * @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 + * - 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. - * @param[in] data: void pointer pointing to osi_ioctl + * + * @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 + * 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. + */ +nve32_t osi_validate_core_regs(struct osi_core_priv_data *const osi_core); + +/** + * @brief osi_flush_mtl_tx_queue - Flushing a MTL Tx Queue. + * + * @note + * Algorithm: + * - Invokes EQOS flush Tx queue routine. + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] qinx: MTL queue index. + * + * @pre + * - MAC should out of reset and clocks enabled. + * - hw core initialized. see osi_hw_core_init(). + * + * @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. + */ +nve32_t osi_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, + const nveu32_t qinx); + +/** + * @brief osi_set_avb - Set CBS algo and parameters + * + * @note + * Algorithm: + * - Set AVB algo and populated parameter from osi_core_avb + * structure for TC/TQ + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] avb: osi core avb data structure. + * + * @pre + * - MAC should be init and started. see osi_start_mac() + * - osi_core->osd should be populated. + * + * @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. + */ +nve32_t osi_set_avb(struct osi_core_priv_data *const osi_core, + const struct osi_core_avb_algorithm *avb); + +/** + * @brief osi_get_avb - Get CBS algo and parameters + * + * @note + * Algorithm: + * - get AVB algo and populated parameter from osi_core_avb + * structure for TC/TQ + * + * @param[in] osi_core: OSI core private data structure. + * @param[out] avb: osi core avb data structure. + * + * @pre + * - MAC should be init and started. see osi_start_mac() + * - osi_core->osd should be populated. + * + * @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. + */ +nve32_t osi_get_avb(struct osi_core_priv_data *const osi_core, + struct osi_core_avb_algorithm *avb); + +/** + * @brief osi_configure_txstatus - Configure Tx packet status reporting + * + * @note + * Algorithm: + * - Configure MAC to enable/disable Tx status error + * reporting. + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] tx_status: Enable or disable tx packet status reporting + * + * @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: No + * - De-initialization: No + * + * @retval 0 on success + * @retval -1 on failure. + */ +nve32_t osi_configure_txstatus(struct osi_core_priv_data *const osi_core, + const nveu32_t tx_status); + +/** + * @brief osi_config_rx_crc_check - Configure CRC Checking for Received 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 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. + */ +nve32_t osi_config_rx_crc_check(struct osi_core_priv_data *const osi_core, + const nveu32_t crc_chk); + +/** + * @brief osi_configure_flow_ctrl - Configure flow control settings + * + * @note + * Algorithm: + * - This will enable or disable the flow control. + * flw_ctrl BIT0 is for tx flow ctrl enable/disable + * flw_ctrl BIT1 is for rx flow ctrl enable/disable + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] flw_ctrl: Enable or disable flow control settings + * + * @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. + */ +nve32_t osi_configure_flow_control(struct osi_core_priv_data *const osi_core, + const nveu32_t flw_ctrl); + +/** + * @brief osi_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. + */ +nve32_t osi_config_arp_offload(struct osi_core_priv_data *const osi_core, + const nveu32_t flags, + const nveu8_t *ip_addr); +/** + * @brief osi_config_vlan_filtering - OSI call for configuring VLAN filter + * + * @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 private data structure. + * @param[in] filter_enb_dis: vlan filter enable(1) disable(0) + * @param[in] perfect_hash_filtering: perfect(0) or hash filter(1) + * @param[in] perfect_inverse_match: normal(0) or inverse filter(1) + * + * @pre + * - MAC should be init and started. see osi_start_mac() + * - osi_core->osd should be populated + * + * @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. + */ +nve32_t osi_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); + +/** + * @brief osi_update_vlan_id - 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. + */ +nve32_t osi_update_vlan_id(struct osi_core_priv_data *const osi_core, + const nveu32_t vid); + +/** + * @brief osi_reset_mmc - invoke function to reset MMC counter and data + * structure + * + * @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: + * + * @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. + */ +nve32_t osi_reset_mmc(struct osi_core_priv_data *const osi_core); + +/** + * @brief osi_configure_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. + */ +nve32_t osi_configure_eee(struct osi_core_priv_data *const osi_core, + nveu32_t tx_lpi_enabled, + nveu32_t tx_lpi_timer); + +/** + * @brief osi_save_registers - Take backup of MAC MMIO address space + * + * @param[in] osi_core: OSI core private data structure. + * + * @pre + * - MAC and PHY should be init and started. see osi_start_mac() + * - No further configuration change in MAC shall be done after invoking + * this API + * + * @note + * API Group: + * - Initialization: No + * - Run time: Yes + * - De-initialization: No + * + * @retval 0 on success + * @retval -1 on failure. + */ +nve32_t osi_save_registers(struct osi_core_priv_data *const osi_core); + +/** + * @brief osi_restore_registers - Restore backup of MAC MMIO address space + * + * @param[in] osi_core: OSI core private data structure. + * + * @pre + * - MAC and PHY 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. + */ +nve32_t osi_restore_registers(struct osi_core_priv_data *const osi_core); + +/** + * @brief osi_set_mdc_clk_rate - Derive MDC clock based on provided AXI_CBB clk. + * + * @note + * Algorithm: + * - MDC clock rate will be populated in 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. + * + * @note OSD layer needs get the AXI CBB clock rate with OSD clock API + * (ex - clk_get_rate()) + * + * @note + * Traceability Details: + * + * @note + * Classification: + * - Interrupt: No + * - Signal handler: No + * - Thread safe: No + * - Required Privileges: None + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: No + * - De-initialization: No + * + * @retval 0 on success + * @retval -1 on failure. + */ +nve32_t osi_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, + const nveu64_t csr_clk_rate); + +/** + * @brief osi_config_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() * @@ -1805,6 +2144,7 @@ nve32_t osi_get_hw_features(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -nve32_t osi_handle_ioctl(struct osi_core_priv_data *osi_core, - struct osi_ioctl *data); +nve32_t osi_config_mac_loopback(struct osi_core_priv_data *const osi_core, + const nveu32_t lb_mode); +#endif /* !OSI_STRIPPED_LIB */ #endif /* INCLUDED_OSI_CORE_H */ diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index c1a486f..52be9c0 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -553,7 +553,7 @@ nve32_t osi_adjust_freq(struct osi_core_priv_data *const osi_core, nve32_t ppb) } else { OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "addend > UINT_MAX\n", 0ULL); - return ret; + return -1; } } else { if (addend > diff) { @@ -713,44 +713,12 @@ nve32_t osi_get_mac_version(struct osi_core_priv_data *const osi_core, } #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_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) +nve32_t osi_validate_core_regs(struct osi_core_priv_data *const osi_core) { + if (validate_args(osi_core) < 0) { + return -1; + } + if (osi_core->safety_config == OSI_NULL) { OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "CORE: Safety config is NULL\n", 0ULL); @@ -760,43 +728,100 @@ static nve32_t validate_core_regs(struct osi_core_priv_data *const osi_core) return ops_p->validate_regs(osi_core); } -/** - * @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) +nve32_t osi_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, + const nveu32_t qinx) { + if (validate_args(osi_core) < 0) { + return -1; + } + + return ops_p->flush_mtl_tx_queue(osi_core, qinx); +} + +nve32_t osi_set_avb(struct osi_core_priv_data *const osi_core, + const struct osi_core_avb_algorithm *avb) +{ + if (validate_args(osi_core) < 0) { + return -1; + } + + return ops_p->set_avb_algorithm(osi_core, avb); +} + +nve32_t osi_get_avb(struct osi_core_priv_data *const osi_core, + struct osi_core_avb_algorithm *avb) +{ + if (validate_args(osi_core) < 0) { + return -1; + } + + return ops_p->get_avb_algorithm(osi_core, avb); +} + +nve32_t osi_configure_txstatus(struct osi_core_priv_data *const osi_core, + const nveu32_t tx_status) +{ + if (validate_args(osi_core) < 0) { + return -1; + } + + /* Configure Drop Transmit Status */ + return ops_p->config_tx_status(osi_core, tx_status); +} + +nve32_t osi_config_rx_crc_check(struct osi_core_priv_data *const osi_core, + const nveu32_t crc_chk) +{ + if (validate_args(osi_core) < 0) { + return -1; + } + + /* Configure CRC Checking for Received Packets */ + return ops_p->config_rx_crc_check(osi_core, crc_chk); +} + +nve32_t osi_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) +{ + if (validate_args(osi_core) < 0) { + return -1; + } + + return ops_p->config_vlan_filtering(osi_core, filter_enb_dis, + perfect_hash_filtering, + perfect_inverse_match); +} + +nve32_t osi_update_vlan_id(struct osi_core_priv_data *const osi_core, + const nveu32_t vid) +{ + if (validate_args(osi_core) < 0) { + return -1; + } + + return ops_p->update_vlan_id(osi_core, vid); +} + +nve32_t osi_reset_mmc(struct osi_core_priv_data *const osi_core) +{ + if (validate_args(osi_core) < 0) { + return -1; + } + + ops_p->reset_mmc(osi_core); + + return 0; +} + +nve32_t osi_configure_eee(struct osi_core_priv_data *const osi_core, + nveu32_t tx_lpi_enabled, nveu32_t tx_lpi_timer) +{ + if (validate_args(osi_core) < 0) { + return -1; + } + 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)) { @@ -811,44 +836,45 @@ static nve32_t conf_eee(struct osi_core_priv_data *const osi_core, return 0; } -/** - * @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) +nve32_t osi_save_registers(struct osi_core_priv_data *const osi_core) { + if (validate_args(osi_core) < 0) { + return -1; + } + + /* Call MAC save registers callback and return the value */ + return ops_p->save_registers(osi_core); +} + +nve32_t osi_restore_registers(struct osi_core_priv_data *const osi_core) +{ + if (validate_args(osi_core) < 0) { + return -1; + } + + /* Call MAC restore registers callback and return the value */ + return ops_p->restore_registers(osi_core); +} + +nve32_t osi_configure_flow_control(struct osi_core_priv_data *const osi_core, + const nveu32_t flw_ctrl) +{ + if (validate_args(osi_core) < 0) { + return -1; + } + + /* Configure Flow control settings */ + return ops_p->config_flow_control(osi_core, flw_ctrl); +} + +nve32_t osi_config_arp_offload(struct osi_core_priv_data *const osi_core, + const nveu32_t flags, + const nveu8_t *ip_addr) +{ + if ((validate_args(osi_core) < 0)) { + return -1; + } + if (ip_addr == OSI_NULL) { OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "CORE: ip_addr is NULL\n", 0ULL); @@ -864,40 +890,25 @@ static nve32_t conf_arp_offload(struct osi_core_priv_data *const osi_core, return 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) +nve32_t osi_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, + const nveu64_t csr_clk_rate) { + if (validate_args(osi_core) < 0) { + return -1; + } + + ops_p->set_mdc_clk_rate(osi_core, csr_clk_rate); + + return 0; +} + +nve32_t osi_config_mac_loopback(struct osi_core_priv_data *const osi_core, + const nveu32_t lb_mode) +{ + if (validate_args(osi_core) < 0) { + return -1; + } + /* 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, @@ -910,181 +921,6 @@ static nve32_t conf_mac_loopback(struct osi_core_priv_data *const osi_core, } #endif /* !OSI_STRIPPED_LIB */ -nve32_t osi_handle_ioctl(struct osi_core_priv_data *osi_core, - struct osi_ioctl *data) -{ - nve32_t ret = -1; - - if (validate_args(osi_core) < 0) { - return ret; - } - - if (data == OSI_NULL) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "CORE: Invalid argument\n", 0ULL); - return ret; - } - - 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 = ops_p->update_vlan_id(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: - ops_p->set_speed(osi_core, data->arg6_32); - ret = 0; - 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); - break; - - case OSI_CMD_ADJ_TIME: - ret = osi_adjust_time(osi_core, data->arg8_64); - break; - - case OSI_CMD_CONFIG_PTP: - ret = osi_ptp_configuration(osi_core, data->arg1_u32); - 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); - break; - - 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) { From 8f9e0f84418f6e935927e3efd08f0ecd9821a54a Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Sun, 21 Mar 2021 17:20:33 +0530 Subject: [PATCH 162/458] osi: core: fix coverity issues Defects/Coding rule violations found : 3 Total FORWARD_NULL 1 - (Deviation Not approved) UNUSED_VALUE 2 - (Deviation Not approved) Bug 200671160 Change-Id: Icabb21606a5758ad79e92d9d67e2be9cb889723e Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> --- osi/core/eqos_core.c | 2 +- osi/core/osi_core.c | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 6aa2ec1..c4c48c0 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -3038,7 +3038,7 @@ static nve32_t eqos_adjust_mactime(struct osi_core_priv_data *const osi_core, } /* write seconds value to MAC_System_Time_Seconds_Update register */ - osi_writela(osi_core, sec, (nveu8_t *)addr + EQOS_MAC_STSUR); + 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 diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 52be9c0..f341918 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -130,8 +130,6 @@ nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core) (osi_core->osd_ops.udelay == OSI_NULL) || (osi_core->osd_ops.msleep == OSI_NULL) || (osi_core->osd_ops.usleep_range == OSI_NULL)) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "CORE OSD ops not assigned\n", 0ULL); return -1; } @@ -282,7 +280,7 @@ nve32_t osi_config_fw_err_pkts(struct osi_core_priv_data *const osi_core, nve32_t osi_l2_filter(struct osi_core_priv_data *const osi_core, const struct osi_filter *filter) { - nve32_t ret = -1; + nve32_t ret; if ((validate_args(osi_core) < 0) || (filter == OSI_NULL)) { return -1; From 6f98f6276c2e3e912a28d275297448bd05460c97 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Sun, 21 Mar 2021 17:22:59 +0530 Subject: [PATCH 163/458] osi: core: fix coverity/misra issues Bug 200671160 Change-Id: I98f0bb2a4a0fde05b81551cd2dd0cab4ddac13dc Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> --- include/osi_core.h | 10 ---------- osi/common/common.h | 2 +- osi/core/core_local.h | 2 +- osi/core/eqos_core.c | 34 ++++++++++++++++------------------ osi/core/osi_core.c | 37 ++++++++++++++++++++++--------------- 5 files changed, 40 insertions(+), 45 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 289b298..c9b572f 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -542,16 +542,6 @@ struct osi_vlan_filter { nveu32_t perfect_inverse_match; }; -/** - * @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. */ diff --git a/osi/common/common.h b/osi/common/common.h index 8177d49..0e847dd 100644 --- a/osi/common/common.h +++ b/osi/common/common.h @@ -277,7 +277,7 @@ static inline void osi_memcpy(void *dest, void *src, int n) char *cdest = (char *)dest; int i = 0; - if (src == OSI_NULL || dest == OSI_NULL) { + if ((src == OSI_NULL) || (dest == OSI_NULL)) { return; } for (i = 0; i < n; i++) { diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 36faec2..0ec0f6c 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -207,7 +207,7 @@ struct core_local { /** Core local operations variable */ struct core_ops ops; /** Flag to represent initialization done or not */ - unsigned int init_done; + nveu32_t init_done; }; /** diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index c4c48c0..aa029f8 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1163,7 +1163,7 @@ static void eqos_configure_rxq_priority( /* 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]) == 0)) { + ((pmask & osi_core->rxq_prio[mtlq]) == 0U)) { pmask |= osi_core->rxq_prio[mtlq]; temp = osi_core->rxq_prio[mtlq]; } else { @@ -1944,7 +1944,6 @@ static inline nve32_t eqos_update_mac_addr_helper( const nveu32_t dma_chan, const nveu32_t addr_mask) { - nve32_t ret = 0; /* PDC bit of MAC_Ext_Configuration register is not set so binary * value representation. */ @@ -1958,8 +1957,7 @@ static inline nve32_t eqos_update_mac_addr_helper( OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, "invalid dma channel\n", (nveul64_t)dma_chan); - ret = -1; - goto err_dma_chan; + return -1; } else { /* Do nothing */ } @@ -1976,12 +1974,11 @@ static inline nve32_t eqos_update_mac_addr_helper( OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "invalid address index for MBC\n", 0ULL); - ret = -1; + return -1; } } -err_dma_chan: - return ret; + return 0; } /** @@ -3588,7 +3585,7 @@ static nve32_t eqos_config_rx_crc_check( nveu32_t val; /* return on invalid argument */ - if (crc_chk != OSI_ENABLE && crc_chk != OSI_DISABLE) { + 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; @@ -3645,7 +3642,7 @@ static nve32_t eqos_config_tx_status(struct osi_core_priv_data *const osi_core, nveu32_t val; /* don't allow if tx_status is other than 0 or 1 */ - if (tx_status != OSI_ENABLE && tx_status != OSI_DISABLE) { + 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; @@ -3921,9 +3918,9 @@ static nve32_t eqos_config_arp_offload( const nveu8_t *ip_addr) { void *addr = osi_core->base; - nve32_t mac_ver = osi_core->mac_ver; - nve32_t mac_mcr; - nve32_t val; + 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); @@ -3993,21 +3990,22 @@ static nve32_t eqos_config_vlan_filtering( nveu32_t value; void *base = osi_core->base; - if (filter_enb_dis != OSI_ENABLE && filter_enb_dis != OSI_DISABLE) { + 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) { + 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) { + 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; @@ -4049,7 +4047,7 @@ static nve32_t eqos_config_vlan_filtering( */ static inline nve32_t eqos_update_vlan_id( struct osi_core_priv_data *const osi_core, - nveu32_t vid) + nveu32_t const vid) { /* Don't add VLAN ID to TR register which is eventually set TR * to 0x0 and allow all tagged packets diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index f341918..d6ad691 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -78,18 +78,19 @@ static inline nve32_t validate_args(struct osi_core_priv_data *const osi_core) static nve32_t validate_func_ptrs(struct osi_core_priv_data *const osi_core) { nveu32_t i = 0; + void *temp_ops = (void *)ops_p; #if __SIZEOF_POINTER__ == 8 - nveu64_t *l_ops = (nveu64_t *)ops_p; + nveu64_t *l_ops = (nveu64_t *)temp_ops; #elif __SIZEOF_POINTER__ == 4 - nveu32_t *l_ops = (nveu32_t *)ops_p; + 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) / __SIZEOF_POINTER__); i++) { - if (*l_ops == 0) { + for (i = 0; i < (sizeof(*ops_p) / (nveu64_t)__SIZEOF_POINTER__); i++) { + if (*l_ops == 0U) { return -1; } @@ -417,6 +418,10 @@ static inline nve32_t helper_l3_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; @@ -687,26 +692,28 @@ nve32_t osi_read_mmc(struct osi_core_priv_data *const osi_core) return 0; } - nve32_t osi_get_mac_version(struct osi_core_priv_data *const osi_core, nveu32_t *mac_ver) { - nveu32_t macver; - if (validate_args(osi_core) < 0) { return -1; } - macver = ((ops_p->read_reg(osi_core, (nve32_t)MAC_VERSION)) & - MAC_VERSION_SNVER_MASK); - - if (is_valid_mac_version(macver) == 0) { + if (mac_ver == OSI_NULL) { OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "Invalid MAC version\n", (nveu64_t)macver) + "mac_ver is NULL\n", 0ULL); + return -1; + } + + *mac_ver = ((ops_p->read_reg(osi_core, (nve32_t)MAC_VERSION)) & + MAC_VERSION_SNVER_MASK); + + if (is_valid_mac_version(*mac_ver) == 0) { + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "Invalid MAC version\n", (nveu64_t)*mac_ver) return -1; } - *mac_ver = macver; return 0; } @@ -822,7 +829,7 @@ nve32_t osi_configure_eee(struct osi_core_priv_data *const 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)) { + ((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); @@ -879,7 +886,7 @@ nve32_t osi_config_arp_offload(struct osi_core_priv_data *const osi_core, return -1; } - if (flags != OSI_ENABLE && flags != OSI_DISABLE) { + 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; From a7c58d1c1af2324bc8cc0950d4927e81f1577652 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Sun, 21 Mar 2021 17:38:53 +0530 Subject: [PATCH 164/458] osi: dma: fix coverity issues Bug 200671160 Change-Id: Ic2f0ce168cb7c551262e569cec420852836094a3 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> --- osi/dma/osi_dma.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 3bc2f44..f0ea691 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -164,8 +164,6 @@ nve32_t osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) (osi_dma->osd_ops.receive_packet == OSI_NULL) || (osi_dma->osd_ops.ops_log == OSI_NULL) || (osi_dma->osd_ops.udelay == OSI_NULL)) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "DMA OSD ops not assigned\n", 0ULL); return -1; } @@ -198,7 +196,7 @@ nve32_t osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) { nveu32_t i, chan; - nve32_t ret = -1; + nve32_t ret; if (validate_args(osi_dma) < 0) { return -1; From 332dc397cd45d6b45cd9d32d2ea61a82bdc5f72f Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Sun, 21 Mar 2021 17:44:20 +0530 Subject: [PATCH 165/458] osi: dma: fix misra/cert issues Bug 200671160 Change-Id: I23c70347e91a51eb33ababce27aa0a33dc8ab01c Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> --- osi/common/common.h | 9 ++++----- osi/dma/eqos_dma.c | 7 ++++--- osi/dma/eqos_dma.h | 13 ------------- osi/dma/osi_dma.c | 17 +++++++++-------- 4 files changed, 17 insertions(+), 29 deletions(-) diff --git a/osi/common/common.h b/osi/common/common.h index 0e847dd..dd6375e 100644 --- a/osi/common/common.h +++ b/osi/common/common.h @@ -35,7 +35,6 @@ #define COND_MET 0 #define COND_NOT_MET 1 /** @} */ -struct osi_core_priv_data; /** * @brief osi_lock_init - Initialize lock to unlocked state. @@ -271,11 +270,11 @@ static inline void osi_memset(void *s, nveu32_t c, nveu64_t count) * - Run time: Yes * - De-initialization: No */ -static inline void osi_memcpy(void *dest, void *src, int n) +static inline void osi_memcpy(void *dest, void *src, nve32_t n) { - char *csrc = (char *)src; - char *cdest = (char *)dest; - int i = 0; + nve8_t *csrc = (nve8_t *)src; + nve8_t *cdest = (nve8_t *)dest; + nve32_t i = 0; if ((src == OSI_NULL) || (dest == OSI_NULL)) { return; diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index 53b4581..b781768 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -630,7 +630,7 @@ static void eqos_configure_dma_channel(nveu32_t chan, /* FBE - Fatal Bus Error Enable */ value = osi_readl((nveu8_t *)osi_dma->base + EQOS_DMA_CHX_INTR_ENA(chan)); - if (!osi_dma->use_virtualization) { + if (osi_dma->use_virtualization == OSI_DISABLE) { value |= EQOS_DMA_CHX_INTR_TBUE | EQOS_DMA_CHX_INTR_RBUE; } @@ -900,6 +900,7 @@ static void eqos_config_slot(struct osi_dma_priv_data *osi_dma, nveu32_t interval) { nveu32_t value; + nveu32_t intr; CHECK_CHAN_BOUND(chan); @@ -909,8 +910,8 @@ static void eqos_config_slot(struct osi_dma_priv_data *osi_dma, EQOS_DMA_CHX_SLOT_CTRL(chan)); value &= ~EQOS_DMA_CHX_SLOT_SIV_MASK; /* remove overflow bits of interval */ - interval &= EQOS_DMA_CHX_SLOT_SIV_MASK; - value |= (interval << EQOS_DMA_CHX_SLOT_SIV_SHIFT); + 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 + diff --git a/osi/dma/eqos_dma.h b/osi/dma/eqos_dma.h index 6b4400d..51de179 100644 --- a/osi/dma/eqos_dma.h +++ b/osi/dma/eqos_dma.h @@ -176,17 +176,4 @@ struct dma_func_safety { * @returns Pointer to DMA safety configuration */ void *eqos_get_dma_safety_config(void); - -/** - * @brief eqos_get_dma_chan_ops - EQOS get DMA channel operations - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @returns Pointer to DMA channel operations structure - */ -struct osi_dma_chan_ops *eqos_get_dma_chan_ops(void); #endif /* INCLUDED_EQOS_DMA_H */ diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index f0ea691..31471d5 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -77,7 +77,7 @@ static inline nve32_t validate_args(struct osi_dma_priv_data *osi_dma) * @retval -1 on Failure */ static inline nve32_t validate_dma_chan_num(struct osi_dma_priv_data *osi_dma, - unsigned int chan) + nveu32_t chan) { if (chan >= OSI_EQOS_MAX_NUM_CHANS) { OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, @@ -133,18 +133,19 @@ static inline nve32_t validate_dma_chans(struct osi_dma_priv_data *osi_dma) static nve32_t validate_func_ptrs(struct osi_dma_priv_data *osi_dma) { nveu32_t i = 0; + void *temp_ops = (void *)ops_p; #if __SIZEOF_POINTER__ == 8 - nveu64_t *l_ops = (nveu64_t *)ops_p; + nveu64_t *l_ops = (nveu64_t *)temp_ops; #elif __SIZEOF_POINTER__ == 4 - nveu32_t *l_ops = (nveu32_t *)ops_p; + nveu32_t *l_ops = (nveu32_t *)temp_ops; #else OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "DMA: Undefined architecture\n", 0ULL); return -1; #endif - for (i = 0; i < (sizeof(*ops_p) / __SIZEOF_POINTER__); i++) { - if (*l_ops == 0) { + for (i = 0; i < (sizeof(*ops_p) / (nveu64_t)__SIZEOF_POINTER__); i++) { + if (*l_ops == 0U) { return -1; } @@ -226,7 +227,7 @@ nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) return ret; } - g_dma.mac_ver = osi_readl((unsigned char *)osi_dma->base + MAC_VERSION) & + g_dma.mac_ver = osi_readl((nveu8_t *)osi_dma->base + MAC_VERSION) & MAC_VERSION_SNVER_MASK; if (is_valid_mac_version(g_dma.mac_ver) == 0) { OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, @@ -388,7 +389,7 @@ nve32_t osi_handle_dma_intr(struct osi_dma_priv_data *osi_dma, nveu32_t tx_rx, nveu32_t en_dis) { - typedef void (*dma_intr_fn)(void *, nveu32_t); + typedef void (*dma_intr_fn)(void *base, nveu32_t ch); dma_intr_fn fn[2][2][2] = { { { ops_p->disable_chan_tx_intr, ops_p->enable_chan_tx_intr }, { ops_p->disable_chan_rx_intr, ops_p->enable_chan_rx_intr } }, @@ -638,7 +639,7 @@ nve32_t osi_dma_get_systime_from_mac(struct osi_dma_priv_data *const osi_dma, nveu32_t osi_is_mac_enabled(struct osi_dma_priv_data *const osi_dma) { if (validate_args(osi_dma) < 0) { - return -1; + return OSI_DISABLE; } return common_is_mac_enabled(osi_dma->base, osi_dma->mac); From e32f28530aab2f8b7d50b300a9e5d8967f4bdb6d Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Mon, 16 Sep 2019 13:53:44 +0530 Subject: [PATCH 166/458] nvethernetrm: add support for MGBE initialization Adds MAC CORE and DMA initialization support for MGBE MAC Controller. Bug 200548572 Change-Id: I6796229852b47ff0748a848a6dbe9addab6ab74f Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2250401 --- include/mmc.h | 16 +- include/osi_common.h | 34 ++ include/osi_core.h | 6 +- include/osi_dma.h | 20 +- include/osi_dma_txrx.h | 1 + osi/common/common.h | 3 +- osi/core/core_local.h | 13 + osi/core/mgbe_core.c | 726 ++++++++++++++++++++++++++++++++++++++++ osi/core/mgbe_core.h | 132 ++++++++ osi/core/osi_core.c | 47 +-- osi/dma/dma_local.h | 26 +- osi/dma/hw_desc.h | 2 + osi/dma/mgbe_dma.c | 612 +++++++++++++++++++++++++++++++++ osi/dma/mgbe_dma.h | 95 ++++++ osi/dma/osi_dma.c | 42 ++- osi/dma/osi_dma_local.h | 72 ++++ osi/dma/osi_dma_txrx.c | 14 +- 17 files changed, 1803 insertions(+), 58 deletions(-) create mode 100644 osi/core/mgbe_core.c create mode 100644 osi/core/mgbe_core.h create mode 100644 osi/dma/mgbe_dma.c create mode 100644 osi/dma/mgbe_dma.h create mode 100644 osi/dma/osi_dma_local.h diff --git a/include/mmc.h b/include/mmc.h index e82b6b7..2f5e282 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -534,25 +534,25 @@ struct osi_mmc_counters { */ struct osi_xtra_stat_counters { /** RX buffer unavailable irq count */ - nveu64_t rx_buf_unavail_irq_n[OSI_EQOS_MAX_NUM_QUEUES]; + 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_EQOS_MAX_NUM_QUEUES]; + 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_EQOS_MAX_NUM_QUEUES]; + 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_EQOS_MAX_NUM_QUEUES]; + 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_EQOS_MAX_NUM_QUEUES]; + nveu64_t re_alloc_rxbuf_failed[OSI_MGBE_MAX_NUM_QUEUES]; /** TX per channel interrupt count */ - nveu64_t tx_normal_irq_n[OSI_EQOS_MAX_NUM_QUEUES]; + 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_EQOS_MAX_NUM_QUEUES]; + nveu64_t tx_usecs_swtimer_n[OSI_MGBE_MAX_NUM_QUEUES]; /** RX per channel interrupt count */ - nveu64_t rx_normal_irq_n[OSI_EQOS_MAX_NUM_QUEUES]; + nveu64_t rx_normal_irq_n[OSI_MGBE_MAX_NUM_QUEUES]; /** link connect count */ nveu64_t link_connect_count; /** link disconnect count */ diff --git a/include/osi_common.h b/include/osi_common.h index ba8d006..222b08e 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -142,15 +142,25 @@ #define OSI_MAX_MTU_SIZE 16383U #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 4U #define OSI_EQOS_MAX_NUM_QUEUES 4U +#define OSI_MGBE_MAX_NUM_CHANS 10U +#define OSI_MGBE_MAX_NUM_QUEUES 10U + +/* 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 @@ -161,8 +171,28 @@ #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_MAX_VM_IRQS 5U +#define OSI_IP4_FILTER 0U +#define OSI_IP6_FILTER 1U + +#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; \ + } \ + } \ #ifndef OSI_STRIPPED_LIB #define OSI_L2_FILTER_INDEX_ANY 127U @@ -176,6 +206,10 @@ #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 */ diff --git a/include/osi_core.h b/include/osi_core.h index c9b572f..0a1b399 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -669,11 +669,11 @@ struct osi_core_priv_data { /** 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]; + 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_EQOS_MAX_NUM_CHANS]; + nveu32_t rxq_ctrl[OSI_MGBE_MAX_NUM_CHANS]; /** Rx MTl Queue mapping based on User Priority field */ - nveu32_t rxq_prio[OSI_EQOS_MAX_NUM_CHANS]; + nveu32_t rxq_prio[OSI_MGBE_MAX_NUM_CHANS]; /** MAC HW type EQOS based on DT compatible */ nveu32_t mac; /** MAC version */ diff --git a/include/osi_dma.h b/include/osi_dma.h index 62668ee..00aa3ec 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -387,11 +387,11 @@ struct osi_tx_ring { */ struct osi_xtra_dma_stat_counters { /** Per Q TX packet count */ - nveu64_t q_tx_pkt_n[OSI_EQOS_MAX_NUM_QUEUES]; + nveu64_t q_tx_pkt_n[OSI_MGBE_MAX_NUM_QUEUES]; /** Per Q RX packet count */ - nveu64_t q_rx_pkt_n[OSI_EQOS_MAX_NUM_QUEUES]; + nveu64_t q_rx_pkt_n[OSI_MGBE_MAX_NUM_QUEUES]; /** Per Q TX complete call count */ - nveu64_t tx_clean_n[OSI_EQOS_MAX_NUM_QUEUES]; + 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 */ @@ -413,7 +413,7 @@ struct osi_vm_irq_data { /** Number of VM channels per VM IRQ */ nveu32_t num_vm_chans; /** Array of VM channel list */ - nveu32_t vm_chans[OSI_EQOS_MAX_NUM_CHANS]; + nveu32_t vm_chans[OSI_MGBE_MAX_NUM_CHANS]; }; /** @@ -443,9 +443,9 @@ struct osd_dma_ops { */ struct osi_dma_priv_data { /** Array of pointers to DMA Tx channel Ring */ - struct osi_tx_ring *tx_ring[OSI_EQOS_MAX_NUM_CHANS]; + 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_EQOS_MAX_NUM_CHANS]; + 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 */ @@ -455,7 +455,7 @@ struct osi_dma_priv_data { /** Number of channels enabled in MAC */ nveu32_t num_dma_chans; /** Array of supported DMA channels */ - nveu32_t dma_chans[OSI_EQOS_MAX_NUM_CHANS]; + nveu32_t dma_chans[OSI_MGBE_MAX_NUM_CHANS]; /** DMA Rx channel buffer length at HW level */ nveu32_t rx_buf_len; /** MTU size */ @@ -486,9 +486,9 @@ struct osi_dma_priv_data { * certain safety critical dma registers */ void *safety_config; /** Array of DMA channel slot snterval value from DT */ - nveu32_t slot_interval[OSI_EQOS_MAX_NUM_CHANS]; + nveu32_t slot_interval[OSI_MGBE_MAX_NUM_CHANS]; /** Array of DMA channel slot enabled status from DT*/ - nveu32_t slot_enabled[OSI_EQOS_MAX_NUM_CHANS]; + nveu32_t slot_enabled[OSI_MGBE_MAX_NUM_CHANS]; /** number of VM IRQ's */ nveu32_t num_vm_irqs; /** Array of VM IRQ's */ @@ -499,6 +499,8 @@ struct osi_dma_priv_data { 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; }; diff --git a/include/osi_dma_txrx.h b/include/osi_dma_txrx.h index f142d48..cef6c89 100644 --- a/include/osi_dma_txrx.h +++ b/include/osi_dma_txrx.h @@ -53,4 +53,5 @@ #define DECR_RX_DESC_INDEX(idx, i) ((idx) = ((idx) - (i)) & (RX_DESC_CNT - 1U)) #endif /* !OSI_STRIPPED_LIB */ /** @} */ + #endif /* INCLUDED_OSI_DMA_TXRX_H */ diff --git a/osi/common/common.h b/osi/common/common.h index dd6375e..a0df155 100644 --- a/osi/common/common.h +++ b/osi/common/common.h @@ -219,7 +219,8 @@ static inline nve32_t is_valid_mac_version(nveu32_t mac_ver) { if ((mac_ver == OSI_EQOS_MAC_4_10) || (mac_ver == OSI_EQOS_MAC_5_00) || - (mac_ver == OSI_EQOS_MAC_5_30)) { + (mac_ver == OSI_EQOS_MAC_5_30) || + (mac_ver == OSI_MGBE_MAC_3_10)) { return 1; } diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 0ec0f6c..2257c2a 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -235,4 +235,17 @@ void eqos_init_core_ops(struct core_ops *ops); * - 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); #endif /* INCLUDED_CORE_LOCAL_H */ diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c new file mode 100644 index 0000000..45c46bc --- /dev/null +++ b/osi/core/mgbe_core.c @@ -0,0 +1,726 @@ +/* + * 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 "../osi/common/type.h" +#include <osi_common.h> +#include <osi_core.h> +#include "mgbe_core.h" +#include "core_local.h" + +/** + * @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 == 1U) { + osi_writel(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_readl((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; + 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_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_readl((nveu8_t *)addr + + MGBE_MTL_CHX_TX_OP_MODE(qinx)); + value |= MGBE_MTL_QTOMR_FTQ; + osi_writel(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_readl((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_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 + * + * @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; + osi_writel(value, (nveu8_t *) + osi_core->base + MGBE_MTL_CHX_TX_OP_MODE(qinx)); + + /* read RX Q0 Operating Mode Register */ + value = osi_readl((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; + + osi_writel(value, (nveu8_t *)osi_core->base + + MGBE_MTL_CHX_RX_OP_MODE(qinx)); + /* Transmit Queue weight */ + value = osi_readl((nveu8_t *)osi_core->base + + MGBE_MTL_TXQ_QW(qinx)); + value |= (MGBE_MTL_TXQ_QW_ISCQW + qinx); + osi_writel(value, (nveu8_t *)osi_core->base + + MGBE_MTL_TXQ_QW(qinx)); + /* Enable Rx Queue Control */ + value = osi_readl((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_writel(value, (nveu8_t *)osi_core->base + + MGBE_MAC_RQC0R); + return 0; +} + +/** + * @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. + */ +static void mgbe_configure_mac(struct osi_core_priv_data *osi_core) +{ + nveu32_t value; + + /* Update MAC address 0 high */ + value = (((nveu32_t)osi_core->mac_addr[5] << 8U) | + ((nveu32_t)osi_core->mac_addr[4])); + osi_writel(value, (nveu8_t *)osi_core->base + MGBE_MAC_MA0HR); + + /* Update MAC address 0 Low */ + value = (((nveu32_t)osi_core->mac_addr[3] << 24U) | + ((nveu32_t)osi_core->mac_addr[2] << 16U) | + ((nveu32_t)osi_core->mac_addr[1] << 8U) | + ((nveu32_t)osi_core->mac_addr[0])); + osi_writel(value, (nveu8_t *)osi_core->base + MGBE_MAC_MA0LR); + + /* TODO: Need to check if we need to enable anything in Tx configuration + * value = osi_readl((nveu8_t *)osi_core->base + MGBE_MAC_TMCR); + */ + /* Read MAC Rx Configuration Register */ + value = osi_readl((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; + osi_writel(value, (nveu8_t *)osi_core->base + MGBE_MAC_RMCR); + + /* TODO: MCBC queue enable */ + + /* Disable all MMC nve32_terrupts */ + /* Disable all MMC Tx nve32_terrupts */ + osi_writel(OSI_NONE, (nveu8_t *)osi_core->base + + MGBE_MMC_TX_INTR_EN); + /* Disable all MMC RX nve32_terrupts */ + osi_writel(OSI_NONE, (nveu8_t *)osi_core->base + + MGBE_MMC_RX_INTR_EN); + + /* Configure MMC counters */ + value = osi_readl((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_writel(value, (nveu8_t *)osi_core->base + MGBE_MMC_CNTRL); + + /* Enable MAC nve32_terrupts */ + /* Read MAC IMR Register */ + value = osi_readl((nveu8_t *)osi_core->base + MGBE_MAC_IER); + /* RGSMIIIM - RGMII/SMII nve32_terrupt Enable */ + /* TODO: LPI need to be enabled during EEE implementation */ + value |= MGBE_IMR_RGSMIIIE; + osi_writel(value, (nveu8_t *)osi_core->base + MGBE_MAC_IER); + + /* TODO: USP (user Priority) to RxQ Mapping */ +} + +/** + * @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] base: MGBE virtual base address. + * + * @note MAC has to be out of reset. + */ +static void mgbe_configure_dma(void *base) +{ + nveu32_t value = 0; + + /* AXI Burst Length 8*/ + value |= MGBE_DMA_SBUS_BLEN8; + /* AXI Burst Length 16*/ + value |= MGBE_DMA_SBUS_BLEN16; + /* Enhanced Address Mode Enable */ + value |= MGBE_DMA_SBUS_EAME; + /* AXI Maximum Read Outstanding Request Limit = 31 */ + value |= MGBE_DMA_SBUS_RD_OSR_LMT; + /* AXI Maximum Write Outstanding Request Limit = 31 */ + value |= MGBE_DMA_SBUS_WR_OSR_LMT; + + osi_writel(value, (nveu8_t *)base + MGBE_DMA_SBUS); +} + +/** + * @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; + + /* reset mmc counters */ + osi_writel(MGBE_MMC_CNTRL_CNTRST, (nveu8_t *)osi_core->base + + MGBE_MMC_CNTRL); + + /* Mapping MTL Rx queue and DMA Rx channel */ + value = osi_readl((nveu8_t *)osi_core->base + + MGBE_MTL_RXQ_DMA_MAP0); + value |= MGBE_RXQ_TO_DMA_CHAN_MAP0; + osi_writel(value, (nveu8_t *)osi_core->base + + MGBE_MTL_RXQ_DMA_MAP0); + + value = osi_readl((nveu8_t *)osi_core->base + + MGBE_MTL_RXQ_DMA_MAP1); + value |= MGBE_RXQ_TO_DMA_CHAN_MAP1; + osi_writel(value, (nveu8_t *)osi_core->base + + MGBE_MTL_RXQ_DMA_MAP1); + + value = osi_readl((nveu8_t *)osi_core->base + + MGBE_MTL_RXQ_DMA_MAP2); + value |= MGBE_RXQ_TO_DMA_CHAN_MAP2; + osi_writel(value, (nveu8_t *)osi_core->base + + MGBE_MTL_RXQ_DMA_MAP2); + + /* TODO: DCS enable */ + + /* 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 */ + mgbe_configure_mac(osi_core); + + /* configure MGBE DMA */ + mgbe_configure_dma(osi_core->base); + + return ret; +} + +/** + * @brief mgbe_handle_mac_nve32_trs - Handle MAC nve32_terrupts + * + * 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) +{ +#if 0 /* TODO: Need to re-visit */ + mac_isr = osi_readl((nveu8_t *)osi_core->base + MGBE_MAC_ISR); + + /* Handle MAC interrupts */ + if ((dma_isr & MGBE_DMA_ISR_MACIS) != MGBE_DMA_ISR_MACIS) { + return; + } + + /* TODO: Duplex/speed settigs - Its not same as EQOS for MGBE */ +#endif +} + +/** + * @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_handle_common_intr - Handles common nve32_terrupt. + * + * 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; + nveu32_t dma_isr = 0; + nveu32_t qinx = 0; + nveu32_t i = 0; + nveu32_t dma_sr = 0; + nveu32_t dma_ier = 0; + + dma_isr = osi_readl((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_readl((nveu8_t *)base + + MGBE_DMA_CHX_STATUS(qinx)); + /* read dma channel nve32_terrupt enable register */ + dma_ier = osi_readl((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_writel(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); +} + +/** + * @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(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_readl((nveu8_t *)addr + MGBE_MAC_TMCR); + /* Enable MAC Transmit */ + value |= MGBE_MAC_TMCR_TE; + osi_writel(value, (nveu8_t *)addr + MGBE_MAC_TMCR); + + value = osi_readl((nveu8_t *)addr + MGBE_MAC_RMCR); + /* Enable MAC Receive */ + value |= MGBE_MAC_RMCR_RE; + osi_writel(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_readl((nveu8_t *)addr + MGBE_MAC_TMCR); + /* Disable MAC Transmit */ + value &= ~MGBE_MAC_TMCR_TE; + osi_writel(value, (nveu8_t *)addr + MGBE_MAC_TMCR); + + value = osi_readl((nveu8_t *)addr + MGBE_MAC_RMCR); + /* Disable MAC Receive */ + value &= ~MGBE_MAC_RMCR_RE; + osi_writel(value, (nveu8_t *)addr + MGBE_MAC_RMCR); +} + +/** + * @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_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 = OSI_NULL; + 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 = OSI_NULL; + /* by default speed is 10G */ + ops->set_speed = OSI_NULL; + ops->pad_calibrate = mgbe_pad_calibrate; + ops->set_mdc_clk_rate = OSI_NULL; + ops->flush_mtl_tx_queue = mgbe_flush_mtl_tx_queue; + ops->config_mac_loopback = OSI_NULL; + ops->set_avb_algorithm = OSI_NULL; + ops->get_avb_algorithm = OSI_NULL; + ops->config_fw_err_pkts = OSI_NULL; + ops->config_tx_status = OSI_NULL; + ops->config_rx_crc_check = OSI_NULL; + ops->config_flow_control = OSI_NULL; + ops->config_arp_offload = OSI_NULL; + ops->config_rxcsum_offload = OSI_NULL; + ops->config_mac_pkt_filter_reg = OSI_NULL; + ops->update_mac_addr_low_high_reg = OSI_NULL; + ops->config_l3_l4_filter_enable = OSI_NULL; + ops->config_l3_filters = OSI_NULL; + ops->update_ip4_addr = OSI_NULL; + ops->update_ip6_addr = OSI_NULL; + ops->config_l4_filters = OSI_NULL; + ops->update_l4_port_no = OSI_NULL; + ops->config_vlan_filtering = OSI_NULL; + ops->update_vlan_id = OSI_NULL; + ops->set_systime_to_mac = OSI_NULL; + ops->config_addend = OSI_NULL; + ops->adjust_mactime = OSI_NULL, + //.get_systime_from_mac = OSI_NULL, + ops->config_tscr = OSI_NULL; + ops->config_ssir = OSI_NULL; + ops->read_mmc = OSI_NULL; + ops->reset_mmc = OSI_NULL; +} diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h new file mode 100644 index 0000000..05b1fd0 --- /dev/null +++ b/osi/core/mgbe_core.h @@ -0,0 +1,132 @@ +/* + * 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_CORE_H_ +#define MGBE_CORE_H_ + +/** + * @addtogroup MGBE-MAC MAC register offsets + * + * @brief MGBE MAC register offsets + * @{ + */ +#define MGBE_MAC_RQC0R 0x00A0 +#define MGBE_MAC_MA0HR 0x0300 +#define MGBE_MAC_MA0LR 0x0304 +#define MGBE_MAC_TMCR 0x0000 +#define MGBE_MAC_RMCR 0x0004 +#define MGBE_MMC_TX_INTR_EN 0x0810 +#define MGBE_MMC_RX_INTR_EN 0x080C +#define MGBE_MMC_CNTRL 0x0800 +#define MGBE_MAC_IER 0x00B4 +#define MGBE_MAC_ISR 0x00B0 +/** @} */ + +/** + * @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_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_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_CHX_TX_OP_MODE(x) ((0x0080U * (x)) + 0x1100U) +#define MGBE_MTL_CHX_RX_OP_MODE(x) ((0x0080U * (x)) + 0x1140U) +#define MGBE_MTL_TXQ_QW(x) ((0x0080U * (x)) + 0x1118U) +/** @} */ + + +/** + * @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_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_TXQ_QW_ISCQW OSI_BIT(4) +#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_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_IMR_RGSMIIIE OSI_BIT(0) +#define MGBE_DMA_ISR_MACIS OSI_BIT(17) +#define MGBE_DMA_ISR_DCH0_DCH15_MASK 0xFFU +#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) +/* DMA SBUS */ +#define MGBE_DMA_SBUS_BLEN8 OSI_BIT(2) +#define MGBE_DMA_SBUS_BLEN16 OSI_BIT(3) +#define MGBE_DMA_SBUS_EAME OSI_BIT(11) +#define MGBE_DMA_SBUS_RD_OSR_LMT 0x001F0000U +#define MGBE_DMA_SBUS_WR_OSR_LMT 0x1F000000U +#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_MTL_TXQ_SIZE_SHIFT 16U +#define MGBE_MTL_RXQ_SIZE_SHIFT 16U +/** @} */ + +/** + * @addtogroup MGBE-SIZE SIZE calculation helper Macros + * + * @brief SIZE calculation defines + * @{ + */ +#define FIFO_SIZE_B(x) (x) +#define FIFO_SIZE_KB(x) ((x) * 1024U) +/** @} */ +#endif /* MGBE_CORE_H_ */ diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index d6ad691..bb4d466 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -123,6 +123,19 @@ nve32_t osi_read_phy_reg(struct osi_core_priv_data *const osi_core, nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core) { + typedef void (*init_ops_arr)(struct core_ops *); + typedef void *(*safety_init)(void); + + init_ops_arr i_ops[2][2] = { + { eqos_init_core_ops, ivc_init_core_ops }, + { mgbe_init_core_ops, OSI_NULL } + }; + + safety_init s_init[2][2] = { + { eqos_get_core_safety_config, ivc_get_core_safety_config }, + { OSI_NULL, OSI_NULL } + }; + if (osi_core == OSI_NULL) { return -1; } @@ -134,42 +147,36 @@ nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core) return -1; } - if (osi_core->mac != OSI_MAC_HW_EQOS) { + 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_DISABLE) { - /* Get EQOS HW core ops */ - eqos_init_core_ops(ops_p); - /* Explicitly set osi_core->safety_config = OSI_NULL if - * a particular MAC version does not need SW safety - * mechanisms like periodic read-verify. - */ + 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](ops_p); + } + + if (s_init[osi_core->mac][osi_core->use_virtualization] != OSI_NULL) { osi_core->safety_config = - (void *)eqos_get_core_safety_config(); - } else { - /* Get IVC HW core ops */ - ivc_init_core_ops(ops_p); - /* Explicitly set osi_core->safety_config = OSI_NULL if - * a particular MAC version does not need SW safety - * mechanisms like periodic read-verify. - */ - osi_core->safety_config = - (void *)ivc_get_core_safety_config(); + s_init[osi_core->mac][osi_core->use_virtualization](); } if (validate_func_ptrs(osi_core) < 0) { OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "core: function ptrs validation failed\n", 0ULL); + "core: function ptrs validation failed\n", 0ULL); return -1; } g_core.init_done = OSI_ENABLE; return 0; - } nve32_t osi_poll_for_mac_reset_complete( diff --git a/osi/dma/dma_local.h b/osi/dma/dma_local.h index 5351157..4e67293 100644 --- a/osi/dma/dma_local.h +++ b/osi/dma/dma_local.h @@ -92,15 +92,39 @@ struct dma_local { /** DMA channel operations */ struct dma_chan_ops ops; /** Flag to represent OSI DMA software init done */ - unsigned int 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; }; +/** + * @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 osi_hw_transmit - Initialize Tx DMA descriptors for a channel * diff --git a/osi/dma/hw_desc.h b/osi/dma/hw_desc.h index e8cb6b5..67bc967 100644 --- a/osi/dma/hw_desc.h +++ b/osi/dma/hw_desc.h @@ -68,6 +68,8 @@ (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 /** * @addtogroup EQOS_TxDesc Transmit Descriptors bit fields * diff --git a/osi/dma/mgbe_dma.c b/osi/dma/mgbe_dma.c new file mode 100644 index 0000000..3819700 --- /dev/null +++ b/osi/dma/mgbe_dma.c @@ -0,0 +1,612 @@ +/* + * 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 <osi_common.h> +#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; + + MGBE_CHECK_CHAN_BOUND(chan); + + 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; + + MGBE_CHECK_CHAN_BOUND(chan); + + 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; + + MGBE_CHECK_CHAN_BOUND(chan); + + 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; + + MGBE_CHECK_CHAN_BOUND(chan); + + 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; + MGBE_CHECK_CHAN_BOUND(chan); + + osi_writel(len, (nveu8_t *)addr + MGBE_DMA_CHX_TDRL(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; + + MGBE_CHECK_CHAN_BOUND(chan); + + 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; + + MGBE_CHECK_CHAN_BOUND(chan); + + 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; + MGBE_CHECK_CHAN_BOUND(chan); + + osi_writel(len, (nveu8_t *)addr + MGBE_DMA_CHX_RDRL(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; + + MGBE_CHECK_CHAN_BOUND(chan); + + 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; + + MGBE_CHECK_CHAN_BOUND(chan); + + 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; + + MGBE_CHECK_CHAN_BOUND(chan); + + /* 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); + 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; + + MGBE_CHECK_CHAN_BOUND(chan); + + /* 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); + 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 + * + * @param[in] chan: DMA channel number that need to be configured. + * @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, + struct osi_dma_priv_data *osi_dma) +{ + nveu32_t value; + + MGBE_CHECK_CHAN_BOUND(chan); + + /* 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; + /* TxPBL = 16 */ + value |= MGBE_DMA_CHX_TX_CTRL_TXPBL_RECOMMENDED; + /* 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)); + + value |= (osi_dma->rx_buf_len << MGBE_DMA_CHX_RBSZ_SHIFT); + /* RXPBL = 16 */ + value |= MGBE_DMA_CHX_RX_CTRL_RXPBL_RECOMMENDED; + 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 + */ + 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)13000000 / 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)); + } +} + +/** + * mgbe_dma_chan_to_vmirq_map - Map DMA channels to a specific VM IRQ. + * + * Algorithm: Programs HW to map DMA channels to specific VM. + * + * Dependencies: OSD layer needs to update number of VM channels and + * DMA channel list in osi_vm_irq_data. + * + * @param[in] osi_dma: OSI private data structure. + * + * Return: None. + */ +static void mgbe_dma_chan_to_vmirq_map(struct osi_dma_priv_data *osi_dma) +{ + struct osi_vm_irq_data *irq_data; + nveu32_t i, j; + nveu32_t chan; + + for (i = 0; i < osi_dma->num_vm_irqs; i++) { + irq_data = &osi_dma->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(i), + (nveu8_t *)osi_dma->base + + MGBE_VIRT_INTR_APB_CHX_CNTRL(chan)); + } + } + + osi_writel(0xD, (nveu8_t *)osi_dma->base + 0x8400); +} + +/** + * @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; + + /* configure MGBE DMA channels */ + for (chinx = 0; chinx < osi_dma->num_dma_chans; chinx++) { + mgbe_configure_dma_channel(osi_dma->dma_chans[chinx], osi_dma); + } + + mgbe_dma_chan_to_vmirq_map(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; + + if (osi_dma->mtu >= OSI_MTU_SIZE_8K) { + rx_buf_len = OSI_MTU_SIZE_16K; + } else if (osi_dma->mtu >= OSI_MTU_SIZE_4K) { + rx_buf_len = OSI_MTU_SIZE_8K; + } else if (osi_dma->mtu >= OSI_MTU_SIZE_2K) { + rx_buf_len = OSI_MTU_SIZE_4K; + } else if (osi_dma->mtu > MAX_ETH_FRAME_LEN_DEFAULT) { + rx_buf_len = OSI_MTU_SIZE_2K; + } else { + rx_buf_len = MAX_ETH_FRAME_LEN_DEFAULT; + } + + /* Buffer alignment */ + osi_dma->rx_buf_len = ((rx_buf_len + (MGBE_AXI_BUS_WIDTH - 1U)) & + ~(MGBE_AXI_BUS_WIDTH - 1U)); +} + +/** + * mgbe_get_global_dma_status - Gets DMA status. + * + * Algorithm: Returns global DMA Tx/Rx interrupt status + * + * @param[in] addr: MAC base address. + * + * Dependencies: None. + * Protection: None. + * Return: None. + */ +static nveu32_t mgbe_get_global_dma_status(void *addr) +{ + return osi_readl((nveu8_t *)addr + MGBE_GLOBAL_DMA_STATUS); +} + +/** + * 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. + * + * Dependencies: None. + * Protection: None. + * Return: None. + */ +static void mgbe_clear_vm_tx_intr(void *addr, nveu32_t chan) +{ + MGBE_CHECK_CHAN_BOUND(chan); + + 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_clear_vm_rx_intr - Clear VM Rx interrupt + * + * Algorithm: Clear Rx interrupt source at DMA and wrapper level. + * + * @param[in] addr: MAC base address. + * @param[in] chan: DMA Rx channel number. + * + * Dependencies: None. + * Protection: None. + * Return: None. + */ +static void mgbe_clear_vm_rx_intr(void *addr, nveu32_t chan) +{ + MGBE_CHECK_CHAN_BOUND(chan); + + 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)); +} + +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 = OSI_NULL; + ops->get_global_dma_status = mgbe_get_global_dma_status; + ops->clear_vm_tx_intr = mgbe_clear_vm_tx_intr; + ops->clear_vm_rx_intr = mgbe_clear_vm_rx_intr; +}; diff --git a/osi/dma/mgbe_dma.h b/osi/dma/mgbe_dma.h new file mode 100644 index 0000000..e22f435 --- /dev/null +++ b/osi/dma/mgbe_dma.h @@ -0,0 +1,95 @@ +/* + * 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_MGBE_DMA_H +#define INCLUDED_MGBE_DMA_H + +/** + * @addtogroup MGBE-DMA-CH 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_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_TDRL(x) ((0x0080U * (x)) + 0x3130U) +#define MGBE_DMA_CHX_RDRL(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 fields for MGBE Rgisters + * + * @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 256U +#define MGBE_DMA_CHX_RBSZ_SHIFT 1U +#define MGBE_DMA_CHX_TX_CTRL_TXPBL_RECOMMENDED 0x100000U +#define MGBE_DMA_CHX_RX_CTRL_RXPBL_RECOMMENDED 0x100000U +#define MGBE_AXI_BUS_WIDTH 0x10U +#define MGBE_GLOBAL_DMA_STATUS 0x8700U +#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_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) +/** @} */ +#endif /* INCLUDED_MGBE_DMA_H */ diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 31471d5..deb7657 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -79,7 +79,8 @@ static inline nve32_t validate_args(struct osi_dma_priv_data *osi_dma) static inline nve32_t validate_dma_chan_num(struct osi_dma_priv_data *osi_dma, nveu32_t chan) { - if (chan >= OSI_EQOS_MAX_NUM_CHANS) { + /* TODO: Get the max channel number based on mac/mac_ver */ + if (chan >= OSI_MGBE_MAX_NUM_CHANS) { OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "Invalid DMA channel number\n", 0ULL); return -1; @@ -157,6 +158,18 @@ static nve32_t validate_func_ptrs(struct osi_dma_priv_data *osi_dma) nve32_t osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) { + typedef void (*init_ops_arr)(struct dma_chan_ops *temp); + typedef void *(*safety_init)(void); + + init_ops_arr i_ops[2] = { + eqos_init_dma_chan_ops, mgbe_init_dma_chan_ops + }; + + safety_init s_init[2] = { + eqos_get_dma_safety_config, OSI_NULL + }; + + if (osi_dma == OSI_NULL) { return -1; } @@ -168,20 +181,17 @@ nve32_t osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) return -1; } - if (osi_dma->mac != OSI_MAC_HW_EQOS) { + 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; } - /* Get EQOS HW DMA operations */ - eqos_init_dma_chan_ops(ops_p); + i_ops[osi_dma->mac](ops_p); - /* Explicitly set osi_dma->safety_config = OSI_NULL if - * a particular MAC version does not need SW safety mechanisms - * like periodic read-verify. - */ - osi_dma->safety_config = (void *)eqos_get_dma_safety_config(); + if (s_init[osi_dma->mac] != OSI_NULL) { + osi_dma->safety_config = s_init[osi_dma->mac](); + } if (validate_func_ptrs(osi_dma) < 0) { OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, @@ -203,7 +213,7 @@ nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) return -1; } - if (osi_dma->num_dma_chans > OSI_EQOS_MAX_NUM_CHANS) { + if (osi_dma->num_dma_chans > OSI_MGBE_MAX_NUM_CHANS) { OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "Invalid number of DMA channels\n", 0ULL); return -1; @@ -260,7 +270,7 @@ nve32_t osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma) return -1; } - if (osi_dma->num_dma_chans > OSI_EQOS_MAX_NUM_CHANS) { + if (osi_dma->num_dma_chans > OSI_MGBE_MAX_NUM_CHANS) { OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "Invalid number of DMA channels\n", 0ULL); return -1; @@ -493,6 +503,8 @@ static inline nve32_t rx_dma_desc_validate_args( } 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; } @@ -584,7 +596,11 @@ nve32_t osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, } rx_desc->rdes2 = 0; - rx_desc->rdes3 = (RDES3_IOC | RDES3_B1V); + 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); @@ -721,7 +737,7 @@ nve32_t osi_config_slot_function(struct osi_dma_priv_data *osi_dma, chan = osi_dma->dma_chans[i]; if ((chan == 0x0U) || - (chan >= OSI_EQOS_MAX_NUM_CHANS)) { + (chan >= OSI_MGBE_MAX_NUM_CHANS)) { /* Ignore 0 and invalid channels */ continue; } diff --git a/osi/dma/osi_dma_local.h b/osi/dma/osi_dma_local.h new file mode 100644 index 0000000..087c02d --- /dev/null +++ b/osi/dma/osi_dma_local.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2019-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_OSI_DMA_LOCAL_H +#define INCLUDED_OSI_DMA_LOCAL_H + +#include <osi_dma.h> +#include "eqos_dma.h" +#include "mgbe_dma.h" + +/* 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. + * + * @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); + +/** + * @addtogroup Helper Helper MACROS + * + * @brief EQOS generic helper MACROS. + * @{ + */ +#define CHECK_CHAN_BOUND(chan) \ + { \ + if ((chan) >= OSI_EQOS_MAX_NUM_CHANS) { \ + return; \ + } \ + } \ + +#define BOOLEAN_FALSE (0U != 0U) +#define L32(data) ((data) & 0xFFFFFFFFU) +#define H32(data) (((data) & 0xFFFFFFFF00000000UL) >> 32UL) +/** @} */ + +#endif /* INCLUDED_OSI_DMA_LOCAL_H */ diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index a09eb64..ba6c1e7 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -428,7 +428,9 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, rx_pkt_cx->flags |= OSI_PKT_CX_VALID; if ((rx_desc->rdes3 & RDES3_LD) == RDES3_LD) { - if ((rx_desc->rdes3 & RDES3_ES_BITS) != 0U) { + 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 */ @@ -771,7 +773,8 @@ nve32_t osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, } } - if (((tx_desc->tdes3 & TDES3_LD) == TDES3_LD) && + if ((osi_dma->mac != OSI_MAC_HW_MGBE) && + ((tx_desc->tdes3 & TDES3_LD) == TDES3_LD) && ((tx_desc->tdes3 & TDES3_CTXT) != TDES3_CTXT)) { /* check tx tstamp status */ if ((tx_desc->tdes3 & TDES3_TTSS) == TDES3_TTSS) { @@ -1232,7 +1235,12 @@ static nve32_t rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, } rx_desc->rdes2 = 0; - rx_desc->rdes3 = (RDES3_IOC | RDES3_B1V); + 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; From 964e853f84e264b796ff3e5751c794fa146c935e Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Tue, 3 Dec 2019 11:35:10 +0530 Subject: [PATCH 167/458] nvethernetrm: mgbe: support for MAC speed set Adds support for programming MAC speed based on PHY speed. Bug 200565886 Change-Id: I486444186b5575f68d6336229e0672e219725444 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2258483 --- include/osi_core.h | 3 +++ osi/core/mgbe_core.c | 39 ++++++++++++++++++++++++++++++++++++++- osi/core/mgbe_core.h | 3 +++ 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/include/osi_core.h b/include/osi_core.h index 0a1b399..3cb497f 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -138,6 +138,9 @@ typedef my_lint_64 nvel64_t; #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 diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 45c46bc..d84b964 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -677,6 +677,43 @@ static void mgbe_core_deinit(struct osi_core_priv_data *osi_core) 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] base: MGBE virtual base address. + * @param[in] speed: Operating speed. + * + * @note MAC should be init and started. see osi_start_mac() + */ +static void mgbe_set_speed(struct osi_core_priv_data *const osi_core, int speed) +{ + unsigned int value = 0; + void *base = osi_core->base; + + value = osi_readl((unsigned char *)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_writel(value, (unsigned char *)base + MGBE_MAC_TMCR); +} + /** * @brief mgbe_init_core_ops - Initialize MGBE MAC core operations */ @@ -692,7 +729,7 @@ void mgbe_init_core_ops(struct core_ops *ops) /* only MGBE supports full duplex */ ops->set_mode = OSI_NULL; /* by default speed is 10G */ - ops->set_speed = OSI_NULL; + ops->set_speed = mgbe_set_speed; ops->pad_calibrate = mgbe_pad_calibrate; ops->set_mdc_clk_rate = OSI_NULL; ops->flush_mtl_tx_queue = mgbe_flush_mtl_tx_queue; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 05b1fd0..5052761 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -108,6 +108,9 @@ #define MGBE_DMA_SBUS_EAME OSI_BIT(11) #define MGBE_DMA_SBUS_RD_OSR_LMT 0x001F0000U #define MGBE_DMA_SBUS_WR_OSR_LMT 0x1F000000U +#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 From 5b34c283cd668d7bacb8fb0e5e9aa431356c122f Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Tue, 3 Dec 2019 11:12:35 +0530 Subject: [PATCH 168/458] nvethernetrm: xpcs: XPCS initialization Add support for XPCS initialization in USXMII mode and start of XPCS will happen once speed set for MAC. Bug 200552796 Change-Id: I4c98bec2e92d9b189c7d2404705e28b969592f33 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2258482 --- include/osi_core.h | 4 + osi/core/core_local.h | 6 +- osi/core/eqos_core.c | 5 +- osi/core/ivc_core.c | 6 +- osi/core/mgbe_core.c | 15 ++- osi/core/osi_core.c | 4 +- osi/core/xpcs.c | 271 ++++++++++++++++++++++++++++++++++++++++++ osi/core/xpcs.h | 92 ++++++++++++++ 8 files changed, 386 insertions(+), 17 deletions(-) create mode 100644 osi/core/xpcs.c create mode 100644 osi/core/xpcs.h diff --git a/include/osi_core.h b/include/osi_core.h index 3cb497f..236a38d 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -665,6 +665,10 @@ struct osd_core_ops { struct osi_core_priv_data { /** Memory mapped base address of MAC IP */ void *base; + /** Memory mapped base address of DMA window of MAC IP */ + void *dma_base; + /** Memory mapped base address of XPCS IP */ + void *xpcs_base; /** Pointer to OSD private data structure */ void *osd; /** OSD callback ops structure */ diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 2257c2a..b87f545 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -46,9 +46,9 @@ struct core_ops { /** 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 (10/100/1000) at MAC */ - void (*set_speed)(struct osi_core_priv_data *const osi_core, - const nve32_t speed); + /** 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 */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index aa029f8..5f459e9 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -543,7 +543,7 @@ static nve32_t eqos_poll_for_swr(struct osi_core_priv_data *const osi_core) * * @pre MAC should be initialized and started. see osi_start_mac() */ -static void eqos_set_speed(struct osi_core_priv_data *const osi_core, +static int eqos_set_speed(struct osi_core_priv_data *const osi_core, const nve32_t speed) { nveu32_t mcr_val; @@ -570,8 +570,9 @@ static void eqos_set_speed(struct osi_core_priv_data *const osi_core, } eqos_core_safety_writel(osi_core, mcr_val, - (nveu8_t *)base + EQOS_MAC_MCR, + (unsigned char *)osi_core->base + EQOS_MAC_MCR, EQOS_MAC_MCR_IDX); + return 0; } /** diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index 49dd4bf..21f023f 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -113,7 +113,7 @@ static nve32_t ivc_poll_for_swr(struct osi_core_priv_data *const osi_core) * * @pre MAC should be initialized and started. see osi_start_mac() */ -static void ivc_set_speed(struct osi_core_priv_data *const osi_core, +static int ivc_set_speed(struct osi_core_priv_data *const osi_core, const nve32_t speed) { ivc_msg_common msg_common; @@ -125,8 +125,8 @@ static void ivc_set_speed(struct osi_core_priv_data *const osi_core, msg_common.data.args.arguments[index++] = speed; msg_common.data.args.count = index; - osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); + return osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); } /** diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index d84b964..93f4268 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -26,6 +26,7 @@ #include <osi_core.h> #include "mgbe_core.h" #include "core_local.h" +#include "xpcs.h" /** * @brief mgbe_poll_for_swr - Poll for software reset (SWR bit in DMA Mode) @@ -463,7 +464,8 @@ static nve32_t mgbe_core_init(struct osi_core_priv_data *osi_core, /* configure MGBE DMA */ mgbe_configure_dma(osi_core->base); - return ret; + /* XPCS initialization */ + return xpcs_init(osi_core); } /** @@ -683,17 +685,16 @@ static void mgbe_core_deinit(struct osi_core_priv_data *osi_core) * Algorithm: Based on the speed (2.5G/5G/10G) MAC will be configured * accordingly. * - * @param[in] base: MGBE virtual base address. + * @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 void mgbe_set_speed(struct osi_core_priv_data *const osi_core, int speed) +static int mgbe_set_speed(struct osi_core_priv_data *const osi_core, const int speed) { unsigned int value = 0; - void *base = osi_core->base; - value = osi_readl((unsigned char *)base + MGBE_MAC_TMCR); + value = osi_readl((unsigned char *)osi_core->base + MGBE_MAC_TMCR); switch (speed) { case OSI_SPEED_2500: @@ -711,7 +712,9 @@ static void mgbe_set_speed(struct osi_core_priv_data *const osi_core, int speed) break; } - osi_writel(value, (unsigned char *)base + MGBE_MAC_TMCR); + osi_writel(value, (unsigned char *)osi_core->base + MGBE_MAC_TMCR); + + return xpcs_start(osi_core); } /** diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index bb4d466..d7ef72d 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -260,9 +260,7 @@ nve32_t osi_set_speed(struct osi_core_priv_data *const osi_core, return -1; } - ops_p->set_speed(osi_core, speed); - - return 0; + return ops_p->set_speed(osi_core, speed); } nve32_t osi_pad_calibrate(struct osi_core_priv_data *const osi_core) diff --git a/osi/core/xpcs.c b/osi/core/xpcs.c new file mode 100644 index 0000000..2e2b923 --- /dev/null +++ b/osi/core/xpcs.c @@ -0,0 +1,271 @@ +/* + * 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 "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; + + /* 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); + 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; + xpcs_write(xpcs_base, XPCS_VR_MII_AN_INTR_STS, status); + 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] xpcs_base: XPCS base virtual address. + * @param[in] status: Autonegotation Status. + */ +static inline void xpcs_set_speed(void *xpcs_base, + unsigned int status) +{ + unsigned int speed = status & XPCS_USXG_AN_STS_SPEED_MASK; + unsigned int ctrl = 0; + + 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; + } + + xpcs_write(xpcs_base, 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 = 1000; + unsigned int count = 0; + unsigned int ctrl = 0; + int ret = 0; + int cond = 1; + + ctrl = xpcs_read(xpcs_base, XPCS_SR_MII_CTRL); + ctrl |= XPCS_SR_MII_CTRL_AN_ENABLE; + xpcs_write(xpcs_base, XPCS_SR_MII_CTRL, ctrl); + + ret = xpcs_poll_for_an_complete(osi_core, &an_status); + if (ret < 0) { + return ret; + } + + xpcs_set_speed(xpcs_base, an_status); + + /* 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 == 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_USRA_RST) == 0U) { + cond = 0; + } else { + osi_core->osd_ops.udelay(1000U); + } + } + + /* poll for Rx link up */ + cond = 1; + count = 0; + while (cond == 1) { + 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 = 0; + } else { + osi_core->osd_ops.udelay(1000U); + } + } + + 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; + + /* 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; + xpcs_write(xpcs_base, XPCS_SR_XS_PCS_CTRL2, ctrl); + + /* 2. enable USXGMII Mode inside DWC_xpcs */ + /* 3. USXG_MODE = 10G - default it will be 10G mode */ + /* 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; + 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 + */ + ctrl = xpcs_read(xpcs_base, XPCS_SR_AN_CTRL); + ctrl &= ~XPCS_SR_AN_CTRL_AN_EN; + xpcs_write(xpcs_base, XPCS_SR_AN_CTRL, ctrl); + + ctrl = xpcs_read(xpcs_base, XPCS_VR_XS_PCS_DIG_CTRL1); + ctrl |= XPCS_VR_XS_PCS_DIG_CTRL1_CL37_BP; + xpcs_write(xpcs_base, XPCS_VR_XS_PCS_DIG_CTRL1, ctrl); + + /* 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; +} diff --git a/osi/core/xpcs.h b/osi/core/xpcs.h new file mode 100644 index 0000000..9c609fb --- /dev/null +++ b/osi/core/xpcs.h @@ -0,0 +1,92 @@ +/* + * 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 XPCS_H_ +#define XPCS_H_ + +#include "../osi/common/common.h" +#include <osi_core.h> + +/** + * @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_VR_XS_PCS_DIG_CTRL1 0xE0000 +#define XPCS_SR_AN_CTRL 0x1C0000 +#define XPCS_SR_MII_CTRL 0x7C0000 +#define XPCS_VR_MII_AN_INTR_STS 0x7E0008 +/** @} */ + + +/** + * @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_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 0xFFU + +int xpcs_init(struct osi_core_priv_data *osi_core); +int xpcs_start(struct osi_core_priv_data *osi_core); + +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)); +} + +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))); +} +#endif From 179ecd7ab64152229038d8b9c51b6525cfbed7e6 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Tue, 3 Dec 2019 14:03:25 +0530 Subject: [PATCH 169/458] nvethernetrm: mgbe: support for PHY MDIO read/write Adds support for MGBE MDIO read/write into PHY. It moves EQOS specific code from OSI layer to EQOS layer. Bug 200565891 Change-Id: Ia9755a4d1a7a22560f499801375736ed0ab99c30 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2258484 --- osi/core/mgbe_core.c | 193 ++++++++++++++++++++++++++++++++++++++++++- osi/core/mgbe_core.h | 16 ++++ 2 files changed, 208 insertions(+), 1 deletion(-) diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 93f4268..33124ef 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -717,6 +717,195 @@ static int mgbe_set_speed(struct osi_core_priv_data *const osi_core, const int s return xpcs_start(osi_core); } +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_readl((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_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; + + if (osi_core == OSI_NULL) { + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "osi_core is NULL\n", + 0ULL); + return -1; + } + + /* 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_writel(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_writel(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_writel(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_writel(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_readl((unsigned char *)osi_core->base + MGBE_MDIO_SCCD); + + data = (reg & MGBE_MDIO_SCCD_SDATA_MASK); + return (int)data; +} + /** * @brief mgbe_init_core_ops - Initialize MGBE MAC core operations */ @@ -763,4 +952,6 @@ void mgbe_init_core_ops(struct core_ops *ops) ops->config_ssir = OSI_NULL; ops->read_mmc = OSI_NULL; ops->reset_mmc = OSI_NULL; -} + ops->write_phy_reg = mgbe_write_phy_reg; + ops->read_phy_reg = mgbe_read_phy_reg; +}; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 5052761..90e9339 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -39,6 +39,8 @@ #define MGBE_MMC_CNTRL 0x0800 #define MGBE_MAC_IER 0x00B4 #define MGBE_MAC_ISR 0x00B0 +#define MGBE_MDIO_SCCD 0x0204 +#define MGBE_MDIO_SCCA 0x0200 /** @} */ /** @@ -88,6 +90,20 @@ #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_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_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)) From c34b4b8ab668116ee934afaf7f19b8db61a515c0 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Fri, 15 Nov 2019 18:24:09 +0530 Subject: [PATCH 170/458] nvethernetrm: mgbe: add support for MAC loopback Enable/Disable MGBE loopback mode by set/clear loopback mode (MGBE_MAC_RMCR_LM) in MAC receive configuration. Bug 200565892 Change-Id: Ibd23b264623d9a8b80b7fbe743167df94cd93baf Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2252672 --- osi/core/mgbe_core.c | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 33124ef..002971b 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -199,6 +199,43 @@ static nve32_t mgbe_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core 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_readl((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_writel(value, (unsigned char *)addr + MGBE_MAC_RMCR); + + return 0; +} + /** * @brief mgbe_configure_mtl_queue - Configure MTL Queue * @@ -925,7 +962,7 @@ void mgbe_init_core_ops(struct core_ops *ops) ops->pad_calibrate = mgbe_pad_calibrate; ops->set_mdc_clk_rate = OSI_NULL; ops->flush_mtl_tx_queue = mgbe_flush_mtl_tx_queue; - ops->config_mac_loopback = OSI_NULL; + ops->config_mac_loopback = mgbe_config_mac_loopback; ops->set_avb_algorithm = OSI_NULL; ops->get_avb_algorithm = OSI_NULL; ops->config_fw_err_pkts = OSI_NULL; @@ -947,7 +984,6 @@ void mgbe_init_core_ops(struct core_ops *ops) ops->set_systime_to_mac = OSI_NULL; ops->config_addend = OSI_NULL; ops->adjust_mactime = OSI_NULL, - //.get_systime_from_mac = OSI_NULL, ops->config_tscr = OSI_NULL; ops->config_ssir = OSI_NULL; ops->read_mmc = OSI_NULL; From 49dbf308e2e393d037c2d9e1536d70a0ce67dca9 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Mon, 18 Nov 2019 13:29:40 +0530 Subject: [PATCH 171/458] nvethernetrm: mgbe: support for Tx/Rx checksum offload Bug 200565907 Change-Id: I25b7734600e51bc8e6a460a7adc0967f7b0f4b42 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2258486 Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> --- osi/core/mgbe_core.c | 41 ++++++++++++++- osi/dma/dma_local.h | 21 ++++++++ osi/dma/eqos_desc.c | 107 ++++++++++++++++++++++++++++++++++++++++ osi/dma/hw_desc.h | 3 ++ osi/dma/mgbe_desc.c | 57 +++++++++++++++++++++ osi/dma/osi_dma.c | 7 ++- osi/dma/osi_dma_local.h | 27 ++++++++++ osi/dma/osi_dma_txrx.c | 93 ++++++---------------------------- 8 files changed, 276 insertions(+), 80 deletions(-) create mode 100644 osi/dma/eqos_desc.c create mode 100644 osi/dma/mgbe_desc.c diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 002971b..a8ffcd1 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -236,6 +236,45 @@ static int mgbe_config_mac_loopback(struct osi_core_priv_data *const osi_core, 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_readl((unsigned char *)addr + MGBE_MAC_RMCR); + if (enabled == OSI_ENABLE) { + mac_rmcr |= MGBE_MAC_RMCR_IPC; + } else { + mac_rmcr &= ~MGBE_MAC_RMCR_IPC; + } + + osi_writel(mac_rmcr, (unsigned char *)addr + MGBE_MAC_RMCR); + + return 0; +} + /** * @brief mgbe_configure_mtl_queue - Configure MTL Queue * @@ -970,7 +1009,7 @@ void mgbe_init_core_ops(struct core_ops *ops) ops->config_rx_crc_check = OSI_NULL; ops->config_flow_control = OSI_NULL; ops->config_arp_offload = OSI_NULL; - ops->config_rxcsum_offload = OSI_NULL; + ops->config_rxcsum_offload = mgbe_config_rxcsum_offload, ops->config_mac_pkt_filter_reg = OSI_NULL; ops->update_mac_addr_low_high_reg = OSI_NULL; ops->config_l3_l4_filter_enable = OSI_NULL; diff --git a/osi/dma/dma_local.h b/osi/dma/dma_local.h index 4e67293..ec6cc1b 100644 --- a/osi/dma/dma_local.h +++ b/osi/dma/dma_local.h @@ -85,6 +85,15 @@ struct dma_chan_ops { 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); +}; + /** * @brief OSI DMA private data. */ @@ -125,6 +134,18 @@ void eqos_init_dma_chan_ops(struct dma_chan_ops *ops); */ 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 * diff --git a/osi/dma/eqos_desc.c b/osi/dma/eqos_desc.c new file mode 100644 index 0000000..9aa1536 --- /dev/null +++ b/osi/dma/eqos_desc.c @@ -0,0 +1,107 @@ +/* + * 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 "dma_local.h" +#include "hw_desc.h" + +/** + * @brief 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; + } +} + +void eqos_init_desc_ops(struct desc_ops *d_ops) +{ + d_ops->get_rx_csum = eqos_get_rx_csum; +} diff --git a/osi/dma/hw_desc.h b/osi/dma/hw_desc.h index 67bc967..e58d872 100644 --- a/osi/dma/hw_desc.h +++ b/osi/dma/hw_desc.h @@ -61,6 +61,9 @@ #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 /** @} */ /** Error Summary bits for Received packet */ diff --git a/osi/dma/mgbe_desc.c b/osi/dma/mgbe_desc.c new file mode 100644 index 0000000..25a00e3 --- /dev/null +++ b/osi/dma/mgbe_desc.c @@ -0,0 +1,57 @@ +/* + * 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 "dma_local.h" +#include "hw_desc.h" + +/** + * @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; + } +} + +void mgbe_init_desc_ops(struct desc_ops *d_ops) +{ + d_ops->get_rx_csum = mgbe_get_rx_csum; +} diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index deb7657..4007c0a 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -169,7 +169,6 @@ nve32_t osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) eqos_get_dma_safety_config, OSI_NULL }; - if (osi_dma == OSI_NULL) { return -1; } @@ -193,6 +192,12 @@ nve32_t osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) 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) < 0) { OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "DMA ops validation failed\n", 0ULL); diff --git a/osi/dma/osi_dma_local.h b/osi/dma/osi_dma_local.h index 087c02d..7cb4d60 100644 --- a/osi/dma/osi_dma_local.h +++ b/osi/dma/osi_dma_local.h @@ -28,6 +28,33 @@ #include "eqos_dma.h" #include "mgbe_dma.h" +/** + * @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); +}; + +/** + * @brief eqos_get_desc_ops - EQOS get DMA descriptor operations + * + * Algorithm: Returns pointer DMA descriptor operations structure. + * + * @returns Pointer to DMA descriptor operations structure + */ +struct desc_ops *eqos_get_desc_ops(void); + +/** + * @brief mgbe_get_desc_ops - MGBE get DMA descriptor operations + * + * Algorithm: Returns pointer DMA descriptor operations structure. + * + * @returns Pointer to DMA descriptor operations structure + */ +struct desc_ops *mgbe_get_desc_ops(void); + /* Function prototype needed for misra */ /** diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index ba6c1e7..391327d 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -26,83 +26,7 @@ #include "hw_desc.h" #include "../osi/common/common.h" -/** - * @brief 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 inline void 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; - } -} +static struct desc_ops d_ops; /** * @brief get_rx_vlan_from_desc - Get Rx VLAN from descriptor @@ -440,7 +364,7 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, } /* Check if COE Rx checksum is valid */ - get_rx_csum(rx_desc, rx_pkt_cx); + d_ops.get_rx_csum(rx_desc, rx_pkt_cx); get_rx_vlan_from_desc(rx_desc, rx_pkt_cx); context_desc = rx_ring->rx_desc + rx_ring->cur_rx_idx; @@ -1405,3 +1329,16 @@ nve32_t dma_desc_init(struct osi_dma_priv_data *osi_dma, 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); + + /* TODO: validate function pointers */ + return 0; +} From 318d5ea149784a195422b747ec621f97509d3e9e Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Mon, 18 Nov 2019 13:45:38 +0530 Subject: [PATCH 172/458] nvethernetrm: mgbe: support for ARP offload Bug 200565907 Change-Id: I9c2726127429b3533ebbd594e4e723fabd9cb04f Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2258487 --- osi/core/mgbe_core.c | 56 ++++++++++++++++++++++++++++++++++++++++++-- osi/core/mgbe_core.h | 2 ++ 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index a8ffcd1..748fce6 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -236,6 +236,58 @@ static int mgbe_config_mac_loopback(struct osi_core_priv_data *const osi_core, 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_readl((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_writel(val, (unsigned char *)addr + MGBE_MAC_ARPPA); + + mac_rmcr |= MGBE_MAC_RMCR_ARPEN; + } else { + mac_rmcr &= ~MGBE_MAC_RMCR_ARPEN; + } + + osi_writel(mac_rmcr, (unsigned char *)addr + MGBE_MAC_RMCR); + + return 0; +} + /** * @brief mgbe_config_rxcsum_offload - Enable/Disale rx checksum offload in HW * @@ -1008,8 +1060,8 @@ void mgbe_init_core_ops(struct core_ops *ops) ops->config_tx_status = OSI_NULL; ops->config_rx_crc_check = OSI_NULL; ops->config_flow_control = OSI_NULL; - ops->config_arp_offload = OSI_NULL; - ops->config_rxcsum_offload = mgbe_config_rxcsum_offload, + ops->config_arp_offload = mgbe_config_arp_offload; + ops->config_rxcsum_offload = mgbe_config_rxcsum_offload; ops->config_mac_pkt_filter_reg = OSI_NULL; ops->update_mac_addr_low_high_reg = OSI_NULL; ops->config_l3_l4_filter_enable = OSI_NULL; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 90e9339..aa79e96 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -41,6 +41,7 @@ #define MGBE_MAC_ISR 0x00B0 #define MGBE_MDIO_SCCD 0x0204 #define MGBE_MDIO_SCCA 0x0200 +#define MGBE_MAC_ARPPA 0x0c10 /** @} */ /** @@ -91,6 +92,7 @@ #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 From bc05f905202ddb3fd72581358fe62f31235d73c2 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Mon, 10 Feb 2020 10:29:01 +0530 Subject: [PATCH 173/458] nvethernetrm: Add mgbe MMC stats support Bug 200565915 Change-Id: I8e14f47c050d8f1db196ddbaaab8a7e99f6eeb27 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2258485 Reviewed-by: Mohan Thadikamalla <mohant@nvidia.com> --- osi/core/mgbe_core.c | 5 +- osi/core/mgbe_mmc.c | 529 +++++++++++++++++++++++++++++++++++++++++++ osi/core/mgbe_mmc.h | 236 +++++++++++++++++++ 3 files changed, 768 insertions(+), 2 deletions(-) create mode 100644 osi/core/mgbe_mmc.c create mode 100644 osi/core/mgbe_mmc.h diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 748fce6..60055b0 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -27,6 +27,7 @@ #include "mgbe_core.h" #include "core_local.h" #include "xpcs.h" +#include "mgbe_mmc.h" /** * @brief mgbe_poll_for_swr - Poll for software reset (SWR bit in DMA Mode) @@ -1077,8 +1078,8 @@ void mgbe_init_core_ops(struct core_ops *ops) ops->adjust_mactime = OSI_NULL, ops->config_tscr = OSI_NULL; ops->config_ssir = OSI_NULL; - ops->read_mmc = OSI_NULL; - ops->reset_mmc = OSI_NULL; ops->write_phy_reg = mgbe_write_phy_reg; ops->read_phy_reg = mgbe_read_phy_reg; + ops->read_mmc = mgbe_read_mmc; + ops->reset_mmc = mgbe_reset_mmc; }; diff --git a/osi/core/mgbe_mmc.c b/osi/core/mgbe_mmc.c new file mode 100644 index 0000000..4253df0 --- /dev/null +++ b/osi/core/mgbe_mmc.c @@ -0,0 +1,529 @@ +/* + * 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 <osi_common.h> +#include <osi_core.h> +#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_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); +} diff --git a/osi/core/mgbe_mmc.h b/osi/core/mgbe_mmc.h new file mode 100644 index 0000000..957577d --- /dev/null +++ b/osi/core/mgbe_mmc.h @@ -0,0 +1,236 @@ +/* + * 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 From 65c49f94f594e0abf07449ed739ed1d2e16534f1 Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Thu, 6 Feb 2020 14:18:05 +0530 Subject: [PATCH 174/458] nvethernetrm: mgbe: Add L2 DA filtering Add MGBE L2 DA perfect and inverse filtering support. Bug 200565909 Change-Id: Ic8648d4fed4fa4ab0c4d98b0d791250a8fbf0c04 Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2274440 --- osi/core/mgbe_core.c | 101 ++++++++++++++++++++++++++++++++++++++++++- osi/core/mgbe_core.h | 16 +++++++ 2 files changed, 116 insertions(+), 1 deletion(-) diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 60055b0..5373fb4 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -147,6 +147,105 @@ static nveu32_t mgbe_calculate_per_queue_fifo(nveu32_t fifo_size, return p_fifo; } +/** + * @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] base: Base address from 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( + void *base, + unsigned int perfect_inverse_match) +{ + unsigned int value = 0U; + + value = osi_readl((unsigned char *)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_writel(value, (unsigned char *)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_readl((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_writel(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->base, + OSI_INV_MATCH); + } + + if ((filter->oper_mode & OSI_OPER_DIS_L2_DA_INV) != OSI_DISABLE) { + mgbe_config_l2_da_perfect_inverse_match(osi_core->base, + OSI_PFT_MATCH); + } + + return ret; +} + /** * @brief mgbe_flush_mtl_tx_queue - Flush MTL Tx queue * @@ -1063,7 +1162,7 @@ void mgbe_init_core_ops(struct core_ops *ops) ops->config_flow_control = OSI_NULL; ops->config_arp_offload = mgbe_config_arp_offload; ops->config_rxcsum_offload = mgbe_config_rxcsum_offload; - ops->config_mac_pkt_filter_reg = OSI_NULL; + ops->config_mac_pkt_filter_reg = mgbe_config_mac_pkt_filter_reg; ops->update_mac_addr_low_high_reg = OSI_NULL; ops->config_l3_l4_filter_enable = OSI_NULL; ops->config_l3_filters = OSI_NULL; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index aa79e96..a8e5350 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -29,6 +29,7 @@ * @brief MGBE MAC register offsets * @{ */ +#define MGBE_MAC_PFR 0x0008 #define MGBE_MAC_RQC0R 0x00A0 #define MGBE_MAC_MA0HR 0x0300 #define MGBE_MAC_MA0LR 0x0304 @@ -120,6 +121,21 @@ #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_IPFE OSI_BIT(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) + /* DMA SBUS */ #define MGBE_DMA_SBUS_BLEN8 OSI_BIT(2) #define MGBE_DMA_SBUS_BLEN16 OSI_BIT(3) From 37598d41e83c3835bce639fcda5912deddd71aa8 Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Tue, 4 Feb 2020 11:54:35 +0530 Subject: [PATCH 175/458] nvethernetrm: mgbe: Add VLAN filtering Add MGBE VLAN filtering support. Bug 200565888 Bug 200565909 Change-Id: Ie3a3852d5c2305b14aa46fb5c8756c7e47a66a05 Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2274441 --- osi/core/mgbe_core.c | 75 +++++++++++++++++++++++++++++++++++++++++++- osi/core/mgbe_core.h | 6 ++++ 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 5373fb4..2749c7a 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -246,6 +246,79 @@ static int mgbe_config_mac_pkt_filter_reg(struct osi_core_priv_data *osi_core, 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_readl(base + MGBE_MAC_PFR); + value &= ~(MGBE_MAC_PFR_VTFE); + value |= ((filter_enb_dis << MGBE_MAC_PFR_VTFE_SHIFT) & + MGBE_MAC_PFR_VTFE); + osi_writel(value, base + MGBE_MAC_PFR); + + /* Read MAC VLAN TR register value set VTIM bit */ + value = osi_readl(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_writel(value, base + MGBE_MAC_VLAN_TR); + + return 0; +} + /** * @brief mgbe_flush_mtl_tx_queue - Flush MTL Tx queue * @@ -1170,7 +1243,7 @@ void mgbe_init_core_ops(struct core_ops *ops) ops->update_ip6_addr = OSI_NULL; ops->config_l4_filters = OSI_NULL; ops->update_l4_port_no = OSI_NULL; - ops->config_vlan_filtering = OSI_NULL; + ops->config_vlan_filtering = mgbe_config_vlan_filtering, ops->update_vlan_id = OSI_NULL; ops->set_systime_to_mac = OSI_NULL; ops->config_addend = OSI_NULL; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index a8e5350..df055a7 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -30,6 +30,7 @@ * @{ */ #define MGBE_MAC_PFR 0x0008 +#define MGBE_MAC_VLAN_TR 0x0050 #define MGBE_MAC_RQC0R 0x00A0 #define MGBE_MAC_MA0HR 0x0300 #define MGBE_MAC_MA0LR 0x0304 @@ -131,10 +132,15 @@ #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_DNTU OSI_BIT(21) #define MGBE_MAC_PFR_VUCC OSI_BIT(22) #define MGBE_MAC_PFR_RA OSI_BIT(31) +#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) /* DMA SBUS */ #define MGBE_DMA_SBUS_BLEN8 OSI_BIT(2) From 1a10b3402360f963003d94af2743657314692759 Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Thu, 6 Feb 2020 14:22:44 +0530 Subject: [PATCH 176/458] nvethernetrm: mgbe: Add DA/SA/MC/BC filtering Add support for DA/SA/MC/BC L2 address filtering. Enable MCBC queue, and set queue1 for MCBC queue. Bug 200565909 Change-Id: I79c2608d1f878695eb8f9c8c3c836c1d458095a0 Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2274442 --- include/osi_common.h | 4 +- include/osi_core.h | 1 + osi/core/mgbe_core.c | 148 ++++++++++++++++++++++++++++++++++++++++++- osi/core/mgbe_core.h | 19 ++++++ 4 files changed, 168 insertions(+), 4 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index 222b08e..e6c3b4c 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -146,8 +146,8 @@ #define EQOS_DMA_CHX_IER(x) ((0x0080U * (x)) + 0x1134U) /* FIXME add logic based on HW version */ -#define OSI_EQOS_MAX_NUM_CHANS 4U -#define OSI_EQOS_MAX_NUM_QUEUES 4U +#define OSI_EQOS_MAX_NUM_CHANS 8U +#define OSI_EQOS_MAX_NUM_QUEUES 8U #define OSI_MGBE_MAX_NUM_CHANS 10U #define OSI_MGBE_MAX_NUM_QUEUES 10U diff --git a/include/osi_core.h b/include/osi_core.h index 236a38d..55362cd 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -92,6 +92,7 @@ typedef my_lint_64 nvel64_t; #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 diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 2749c7a..70df157 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -246,6 +246,145 @@ static int mgbe_config_mac_pkt_filter_reg(struct osi_core_priv_data *osi_core, return ret; } +/** + * @brief mgbe_update_mac_addr_helper - Function to update DCS and MBC + * + * Algorithm: This helper routine is to update passed prameter value + * based on DCS and MBC parameter. Validation of dma_chan as well as + * dsc_en status performed before updating DCS bits. + * + * @param[in] osi_core: OSI core private data structure. + * @param[out] value: unsigned int 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 + * @param[in] addr_mask: 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] + * + * @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 inline int mgbe_update_mac_addr_helper( + struct osi_core_priv_data *osi_core, + unsigned int *value, + unsigned int idx, + unsigned int dma_routing_enable, + unsigned int dma_chan, unsigned int addr_mask) +{ + int ret = 0; + /* PDC bit of MAC_Ext_Configuration register is not set so binary + * value representation. + */ + if (dma_routing_enable == OSI_ENABLE) { + if ((dma_chan < OSI_MGBE_MAX_NUM_CHANS) && + (osi_core->dcs_en == OSI_ENABLE)) { + *value = ((dma_chan << MGBE_MAC_ADDRH_DCS_SHIFT) & + MGBE_MAC_ADDRH_DCS); + } else if (dma_chan > OSI_MGBE_MAX_NUM_CHANS - 0x1U) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, + "invalid dma channel\n", + (unsigned long long)dma_chan); + ret = -1; + goto err_dma_chan; + } else { + /* Do nothing */ + } + } + + /* Address mask validation */ + if (addr_mask <= MGBE_MAB_ADDRH_MBC_MAX_MASK && addr_mask > OSI_NONE) { + *value = (*value | + ((addr_mask << MGBE_MAC_ADDRH_MBC_SHIFT) & + MGBE_MAC_ADDRH_MBC)); + } + +err_dma_chan: + return ret; +} + + +/** + * @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) +{ + unsigned int idx = filter->index; + unsigned int dma_routing_enable = filter->dma_routing; + unsigned int dma_chan = filter->dma_chan; + unsigned int addr_mask = filter->addr_mask; + unsigned int src_dest = filter->src_dest; + const unsigned char *addr = filter->mac_address; + unsigned int value = 0x0U; + int ret = 0; + + /* 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; + } + + /* High address clean should happen for filter index >= 0 */ + if (addr == OSI_NULL) { + osi_writel(OSI_DISABLE, (unsigned char *)osi_core->base + + MGBE_MAC_ADDRH((idx))); + return 0; + } + + ret = mgbe_update_mac_addr_helper(osi_core, &value, idx, + dma_routing_enable, dma_chan, + addr_mask); + if (ret == -1) { + /* return on helper error */ + return ret; + } + + /* Setting Source/Destination Address match valid for 1 to 31 index */ + if ((src_dest == OSI_SA_MATCH || src_dest == OSI_DA_MATCH)) { + value = (value | ((src_dest << MGBE_MAC_ADDRH_SA_SHIFT) & + MGBE_MAC_ADDRH_SA)); + } + + osi_writel(((unsigned int)addr[4] | + ((unsigned int)addr[5] << 8) | + MGBE_MAC_ADDRH_AE | + value), + (unsigned char *)osi_core->base + MGBE_MAC_ADDRH((idx))); + + osi_writel(((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))); + + return ret; +} + /** * @brief mgbe_config_vlan_filter_reg - config vlan filter register * @@ -630,7 +769,12 @@ static void mgbe_configure_mac(struct osi_core_priv_data *osi_core) value |= MGBE_MAC_RMCR_ACS | MGBE_MAC_RMCR_CST | MGBE_MAC_RMCR_IPC; osi_writel(value, (nveu8_t *)osi_core->base + MGBE_MAC_RMCR); - /* TODO: MCBC queue enable */ + /* Enable Multicast and Broadcast Queue, default is Q1 */ + value = osi_readl((unsigned char *)osi_core->base + MGBE_MAC_RQC1R); + value |= MGBE_MAC_RQC1R_MCBCQEN; + /* Routing Multicast and Broadcast to Q1 */ + value |= MGBE_MAC_RQC1R_MCBCQ1; + osi_writel(value, (unsigned char *)osi_core->base + MGBE_MAC_RQC1R); /* Disable all MMC nve32_terrupts */ /* Disable all MMC Tx nve32_terrupts */ @@ -1236,7 +1380,7 @@ void mgbe_init_core_ops(struct core_ops *ops) ops->config_arp_offload = mgbe_config_arp_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 = OSI_NULL; + ops->update_mac_addr_low_high_reg = mgbe_update_mac_addr_low_high_reg; ops->config_l3_l4_filter_enable = OSI_NULL; ops->config_l3_filters = OSI_NULL; ops->update_ip4_addr = OSI_NULL; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index df055a7..06c4653 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -32,6 +32,7 @@ #define MGBE_MAC_PFR 0x0008 #define MGBE_MAC_VLAN_TR 0x0050 #define MGBE_MAC_RQC0R 0x00A0 +#define MGBE_MAC_RQC1R 0x00A4 #define MGBE_MAC_MA0HR 0x0300 #define MGBE_MAC_MA0LR 0x0304 #define MGBE_MAC_TMCR 0x0000 @@ -44,6 +45,8 @@ #define MGBE_MDIO_SCCD 0x0204 #define MGBE_MDIO_SCCA 0x0200 #define MGBE_MAC_ARPPA 0x0c10 +#define MGBE_MAC_ADDRH(x) ((0x0008U * (x)) + 0x0300U) +#define MGBE_MAC_ADDRL(x) ((0x0008U * (x)) + 0x0304U) /** @} */ /** @@ -112,6 +115,8 @@ #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_MCBCQEN OSI_BIT(15) +#define MGBE_MAC_RQC1R_MCBCQ1 OSI_BIT(8) #define MGBE_IMR_RGSMIIIE OSI_BIT(0) #define MGBE_DMA_ISR_MACIS OSI_BIT(17) #define MGBE_DMA_ISR_DCH0_DCH15_MASK 0xFFU @@ -137,6 +142,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_VLAN_TR_ETV OSI_BIT(16) #define MGBE_MAC_VLAN_TR_VTIM OSI_BIT(17) #define MGBE_MAC_VLAN_TR_VTIM_SHIFT 17 From 6391838a67db52d78c43e6731decbf1b251e48db Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Wed, 27 Nov 2019 13:47:22 +0530 Subject: [PATCH 177/458] nvethernetrm: mgbe: Add L3 and L4 filtering Add L3 IP address filtering support and L4 port filtering support Bug 200565909 Change-Id: I31748cfacf41bb6358813b80eabb57dd6416da5c Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2274443 --- include/osi_common.h | 5 + include/osi_core.h | 2 + osi/core/mgbe_core.c | 746 ++++++++++++++++++++++++++++++++++++++++++- osi/core/mgbe_core.h | 83 +++++ 4 files changed, 830 insertions(+), 6 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index e6c3b4c..82fdec2 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -148,6 +148,7 @@ /* 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 @@ -166,6 +167,10 @@ #define OSI_ENABLE 1U #define OSI_NONE 0U #define OSI_DISABLE 0U +#if 0 +#define OSI_AMASK_DISABLE 0U + +#endif #define OSI_BIT(nr) ((nveu32_t)1 << (nr)) diff --git a/include/osi_core.h b/include/osi_core.h index 55362cd..8a526b2 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -112,6 +112,8 @@ typedef my_lint_64 nvel64_t; #define OSI_IP4_FILTER 0U #define OSI_IP6_FILTER 1U #define OSI_IPV6_MATCH 1U +#define OSI_IPV4_MATCH 0U + #define OSI_LOG_INFO 1U #define OSI_LOG_ARG_HW_FAIL 4U diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 70df157..be96bae 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -385,6 +385,740 @@ static int mgbe_update_mac_addr_low_high_reg( 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_readl((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. + */ +static void 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_writel(value, (unsigned char *)base + MGBE_MAC_L3L4_DATA); + + /* Program MAC_L3_L4_Address_Control */ + addr = osi_readl((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_writel(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); + } +} + +/** + * @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. + */ +static void 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_readl((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_writel(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; + } + + /* Read the MGBE_MAC_L3L4_DATA for filter register data */ + *value = osi_readl((unsigned char *)base + MGBE_MAC_L3L4_DATA); +} + +/** + * @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; + + 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) { + mgbe_l3l4_filter_write(osi_core, + filter_no, + MGBE_MAC_L3_AD0R, + value); + } else { + mgbe_l3l4_filter_write(osi_core, + filter_no, + MGBE_MAC_L3_AD1R, + value); + } + + return 0; +} + +/** + * @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; + + 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; + mgbe_l3l4_filter_write(osi_core, filter_no, MGBE_MAC_L3_AD0R, value); + /* update Bits[63:32] of 128-bit IP addr */ + value = addr[5]; + temp = (unsigned int)addr[4] << 16; + value |= temp; + mgbe_l3l4_filter_write(osi_core, filter_no, MGBE_MAC_L3_AD1R, value); + /* update Bits[95:64] of 128-bit IP addr */ + value = addr[3]; + temp = (unsigned int)addr[2] << 16; + value |= temp; + mgbe_l3l4_filter_write(osi_core, filter_no, MGBE_MAC_L3_AD2R, value); + /* update Bits[127:96] of 128-bit IP addr */ + value = addr[1]; + temp = (unsigned int)addr[0] << 16; + value |= temp; + mgbe_l3l4_filter_write(osi_core, filter_no, MGBE_MAC_L3_AD3R, value); + + return 0; +} + +/** + * @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_readl((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_writel(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; + + 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; + } + + mgbe_l3l4_filter_read(osi_core, filter_no, MGBE_MAC_L4_ADDR, &value); + 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); + } + mgbe_l3l4_filter_write(osi_core, filter_no, MGBE_MAC_L4_ADDR, value); + + return 0; +} + +/** + * @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; + + 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; + } + + mgbe_l3l4_filter_read(osi_core, filter_no, MGBE_MAC_L3L4_CTR, &value); + 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; + } + } + } + mgbe_l3l4_filter_write(osi_core, filter_no, MGBE_MAC_L3L4_CTR, value); + + /* Set bit corresponding to filter index if value is non-zero */ + mgbe_helper_l3l4_bitmask(&osi_core->l3l4_filter_bitmask, + filter_no, value); + + return 0; +} + +/** + * @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; + + 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; + } + + mgbe_l3l4_filter_read(osi_core, filter_no, MGBE_MAC_L3L4_CTR, &value); + 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; + } + } + mgbe_l3l4_filter_write(osi_core, filter_no, MGBE_MAC_L3L4_CTR, value); + + /* Set bit corresponding to filter index if value is non-zero */ + mgbe_helper_l3l4_bitmask(&osi_core->l3l4_filter_bitmask, + filter_no, value); + + return 0; +} + /** * @brief mgbe_config_vlan_filter_reg - config vlan filter register * @@ -1381,12 +2115,12 @@ void mgbe_init_core_ops(struct core_ops *ops) 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 = OSI_NULL; - ops->config_l3_filters = OSI_NULL; - ops->update_ip4_addr = OSI_NULL; - ops->update_ip6_addr = OSI_NULL; - ops->config_l4_filters = OSI_NULL; - ops->update_l4_port_no = OSI_NULL; + 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->update_vlan_id = OSI_NULL; ops->set_systime_to_mac = OSI_NULL; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 06c4653..f43cab2 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -47,6 +47,80 @@ #define MGBE_MAC_ARPPA 0x0c10 #define MGBE_MAC_ADDRH(x) ((0x0008U * (x)) + 0x0300U) #define MGBE_MAC_ADDRL(x) ((0x0008U * (x)) + 0x0304U) +#define MGBE_MAC_L3L4_ADDR_CTR 0x0C00 +#define MGBE_MAC_L3L4_DATA 0x0C04 +/** @} */ + +/** + * @addtogroup MGBE MAC L3L4 defines + * + * @brief MGBE L3L4 Address Control register + * IDDR filter filed type defines + * @{ + */ +#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 /** @} */ /** @@ -139,6 +213,7 @@ #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) @@ -156,6 +231,14 @@ 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 From ecd0eef1d1c87aec5206cdd68e693bc86f7f0695 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Mon, 18 Nov 2019 16:24:29 +0530 Subject: [PATCH 178/458] nvethernetrm: mgbe: add support for jumbo frames Bug 200565893 Change-Id: Id27f78180a7d2562c3306e2290555f1609e03a48 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2292258 --- osi/core/mgbe_core.c | 25 ++++++++++++++++++++++++- osi/core/mgbe_core.h | 5 +++++ osi/dma/mgbe_dma.c | 17 +++++------------ osi/dma/mgbe_dma.h | 1 + 4 files changed, 35 insertions(+), 13 deletions(-) diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index be96bae..a9f6db3 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -1501,7 +1501,30 @@ static void mgbe_configure_mac(struct osi_core_priv_data *osi_core) /* 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; - osi_writel(value, (nveu8_t *)osi_core->base + MGBE_MAC_RMCR); + + /* 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_writel(value, (unsigned char *)osi_core->base + MGBE_MAC_RMCR); + + value = osi_readl((unsigned char *)osi_core->base + MGBE_MAC_TMCR); + /* Jabber Disable */ + if (osi_core->mtu > OSI_DFLT_MTU_SIZE) { + value |= MGBE_MAC_TMCR_JD; + } + osi_writel(value, (unsigned char *)osi_core->base + MGBE_MAC_TMCR); /* Enable Multicast and Broadcast Queue, default is Q1 */ value = osi_readl((unsigned char *)osi_core->base + MGBE_MAC_RQC1R); diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index f43cab2..22f9549 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -185,6 +185,10 @@ #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_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)) @@ -263,6 +267,7 @@ #define MGBE_RXQ_TO_DMA_CHAN_MAP3 0x0F0E0D0CU #define MGBE_MTL_TXQ_SIZE_SHIFT 16U #define MGBE_MTL_RXQ_SIZE_SHIFT 16U +#define MGBE_MAC_RMCR_GPSL_MSK 0x3FFF0000U /** @} */ /** diff --git a/osi/dma/mgbe_dma.c b/osi/dma/mgbe_dma.c index 3819700..de2f7e1 100644 --- a/osi/dma/mgbe_dma.c +++ b/osi/dma/mgbe_dma.c @@ -412,6 +412,8 @@ static void mgbe_configure_dma_channel(nveu32_t chan, 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 = 16 */ value |= MGBE_DMA_CHX_RX_CTRL_RXPBL_RECOMMENDED; @@ -512,18 +514,9 @@ static void mgbe_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) { nveu32_t rx_buf_len; - if (osi_dma->mtu >= OSI_MTU_SIZE_8K) { - rx_buf_len = OSI_MTU_SIZE_16K; - } else if (osi_dma->mtu >= OSI_MTU_SIZE_4K) { - rx_buf_len = OSI_MTU_SIZE_8K; - } else if (osi_dma->mtu >= OSI_MTU_SIZE_2K) { - rx_buf_len = OSI_MTU_SIZE_4K; - } else if (osi_dma->mtu > MAX_ETH_FRAME_LEN_DEFAULT) { - rx_buf_len = OSI_MTU_SIZE_2K; - } else { - rx_buf_len = MAX_ETH_FRAME_LEN_DEFAULT; - } - + /* 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)); diff --git a/osi/dma/mgbe_dma.h b/osi/dma/mgbe_dma.h index e22f435..426bdc2 100644 --- a/osi/dma/mgbe_dma.h +++ b/osi/dma/mgbe_dma.h @@ -67,6 +67,7 @@ #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 256U +#define MGBE_DMA_CHX_RBSZ_MASK 0x7FFEU #define MGBE_DMA_CHX_RBSZ_SHIFT 1U #define MGBE_DMA_CHX_TX_CTRL_TXPBL_RECOMMENDED 0x100000U #define MGBE_DMA_CHX_RX_CTRL_RXPBL_RECOMMENDED 0x100000U From 8e6b436461fdd24bad562781a66fb872576de2ad Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Thu, 12 Dec 2019 09:45:46 +0530 Subject: [PATCH 179/458] nvethernetrm: mgbe: Enable/Disable slot function control Bug 200576205 Change-Id: I694dbb73f262fe0a1b8b6cca8796f4934feeacd3 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2260753 --- osi/dma/mgbe_dma.c | 43 +++++++++++++++++++++++++++++++++++++++++++ osi/dma/mgbe_dma.h | 2 ++ 2 files changed, 45 insertions(+) diff --git a/osi/dma/mgbe_dma.c b/osi/dma/mgbe_dma.c index de2f7e1..46ce900 100644 --- a/osi/dma/mgbe_dma.c +++ b/osi/dma/mgbe_dma.c @@ -582,6 +582,48 @@ static void mgbe_clear_vm_rx_intr(void *addr, nveu32_t chan) (nveu8_t *)addr + MGBE_VIRT_INTR_CHX_STATUS(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, + unsigned int interval) +{ + unsigned int value; + + MGBE_CHECK_CHAN_BOUND(chan); + + 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; @@ -602,4 +644,5 @@ void mgbe_init_dma_chan_ops(struct dma_chan_ops *ops) ops->get_global_dma_status = mgbe_get_global_dma_status; 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 index 426bdc2..90bbc95 100644 --- a/osi/dma/mgbe_dma.h +++ b/osi/dma/mgbe_dma.h @@ -31,6 +31,7 @@ */ #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) @@ -84,6 +85,7 @@ #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 | \ From 4653d93db4c418fcf08ac5cf378c46d4797dcba2 Mon Sep 17 00:00:00 2001 From: narayanr <narayanr@nvidia.com> Date: Tue, 10 Mar 2020 16:44:25 +0530 Subject: [PATCH 180/458] nvethernetrm: mgbe: Add support to forward error pkts Added support to configure Rx MTL Queue to drop or forward the error packets to DMA or application Bug 200565898 Change-Id: I5e5dbad01c07f7b6efd1a1a0b9c07fcafa9050e5 Signed-off-by: narayanr <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2310097 Reviewed-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> --- osi/core/mgbe_core.c | 60 +++++++++++++++++++++++++++++++++++++++++++- osi/core/mgbe_core.h | 1 + 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index a9f6db3..6fb9d92 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -29,6 +29,64 @@ #include "xpcs.h" #include "mgbe_mmc.h" +/** + * @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_readl((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_writel(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) * @@ -2130,7 +2188,7 @@ void mgbe_init_core_ops(struct core_ops *ops) ops->config_mac_loopback = mgbe_config_mac_loopback; ops->set_avb_algorithm = OSI_NULL; ops->get_avb_algorithm = OSI_NULL; - ops->config_fw_err_pkts = OSI_NULL; + ops->config_fw_err_pkts = mgbe_config_fw_err_pkts; ops->config_tx_status = OSI_NULL; ops->config_rx_crc_check = OSI_NULL; ops->config_flow_control = OSI_NULL; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 22f9549..4467d03 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -268,6 +268,7 @@ #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) /** @} */ /** From 619ac5513e97308c3491375d25231c6922c40486 Mon Sep 17 00:00:00 2001 From: narayanr <narayanr@nvidia.com> Date: Mon, 16 Dec 2019 16:38:45 +0530 Subject: [PATCH 181/458] nvethernetrm: mgbe: add rx stats Bug 200565898 Change-Id: If3bb00422d77d24e2425764015db25cdf4e1d930 Signed-off-by: narayanr <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2309521 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> --- osi/dma/dma_local.h | 3 +++ osi/dma/eqos_desc.c | 34 +++++++++++++++++++++++++++++++++- osi/dma/hw_desc.h | 1 + osi/dma/mgbe_desc.c | 23 +++++++++++++++++++++++ osi/dma/osi_dma_local.h | 3 +++ osi/dma/osi_dma_txrx.c | 4 ++-- 6 files changed, 65 insertions(+), 3 deletions(-) diff --git a/osi/dma/dma_local.h b/osi/dma/dma_local.h index ec6cc1b..ceb5b5c 100644 --- a/osi/dma/dma_local.h +++ b/osi/dma/dma_local.h @@ -92,6 +92,9 @@ 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 pkt_err_stats); }; /** diff --git a/osi/dma/eqos_desc.c b/osi/dma/eqos_desc.c index 9aa1536..0a9493a 100644 --- a/osi/dma/eqos_desc.c +++ b/osi/dma/eqos_desc.c @@ -24,7 +24,38 @@ #include "hw_desc.h" /** - * @brief get_rx_csum - Get the Rx checksum from descriptor if valid + * @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 + 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 eqos_get_rx_csum - Get the Rx checksum from descriptor if valid * * @note * Algorithm: @@ -104,4 +135,5 @@ static void eqos_get_rx_csum(struct osi_rx_desc *rx_desc, 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; } diff --git a/osi/dma/hw_desc.h b/osi/dma/hw_desc.h index e58d872..b588037 100644 --- a/osi/dma/hw_desc.h +++ b/osi/dma/hw_desc.h @@ -73,6 +73,7 @@ /** 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 * diff --git a/osi/dma/mgbe_desc.c b/osi/dma/mgbe_desc.c index 25a00e3..a737a82 100644 --- a/osi/dma/mgbe_desc.c +++ b/osi/dma/mgbe_desc.c @@ -23,6 +23,28 @@ #include "dma_local.h" #include "hw_desc.h" +/** + * @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 + pkt_err_stats) +{ + /* increment rx crc if we see CE bit set */ + if ((rx_desc->rdes3 & RDES3_ERR_MGBE_CRC) == RDES3_ERR_MGBE_CRC) { + pkt_err_stats.rx_crc_error = + osi_update_stats_counter(pkt_err_stats.rx_crc_error, + 1UL); + } +} + /** * @brief mgbe_get_rx_csum - Get the Rx checksum from descriptor if valid * @@ -54,4 +76,5 @@ static void mgbe_get_rx_csum(struct osi_rx_desc *rx_desc, 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; } diff --git a/osi/dma/osi_dma_local.h b/osi/dma/osi_dma_local.h index 7cb4d60..1eeaa62 100644 --- a/osi/dma/osi_dma_local.h +++ b/osi/dma/osi_dma_local.h @@ -35,6 +35,9 @@ 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 pkt_err_stats); }; /** diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 391327d..6cac12a 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -359,8 +359,8 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, * are set */ rx_pkt_cx->flags &= ~OSI_PKT_CX_VALID; - get_rx_err_stats(rx_desc, - &osi_dma->pkt_err_stats); + d_ops.update_rx_err_stats(rx_desc, + osi_dma->pkt_err_stats); } /* Check if COE Rx checksum is valid */ From 692f3049a88a540fe0ecc9984beb3440be78fd7c Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Fri, 13 Mar 2020 11:31:48 +0530 Subject: [PATCH 182/458] nvethernetrm: mgbe: Add AVB CBS support Add AVB CBS set and get operations support. Bug 200565900 Change-Id: I5402a5ac9dcb080c69a11aaa2eec52f68fe833b8 Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2309941 Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User --- include/osi_core.h | 3 + osi/core/mgbe_core.c | 244 ++++++++++++++++++++++++++++++++++++++++++- osi/core/mgbe_core.h | 25 ++++- 3 files changed, 265 insertions(+), 7 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 8a526b2..a5b43df 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -97,6 +97,7 @@ typedef my_lint_64 nvel64_t; #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 */ @@ -578,6 +579,8 @@ struct osi_core_avb_algorithm { * * 10: enable */ nveu32_t oper_mode; + /** TC index */ + unsigned int tcindex; }; #endif /* !OSI_STRIPPED_LIB */ diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 6fb9d92..a9e75f1 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -1505,10 +1505,10 @@ static nve32_t mgbe_configure_mtl_queue(nveu32_t qinx, MGBE_MTL_CHX_RX_OP_MODE(qinx)); /* Transmit Queue weight */ value = osi_readl((nveu8_t *)osi_core->base + - MGBE_MTL_TXQ_QW(qinx)); - value |= (MGBE_MTL_TXQ_QW_ISCQW + qinx); + MGBE_MTL_TCQ_QW(qinx)); + value |= (MGBE_MTL_TCQ_QW_ISCQW + qinx); osi_writel(value, (nveu8_t *)osi_core->base + - MGBE_MTL_TXQ_QW(qinx)); + MGBE_MTL_TCQ_QW(qinx)); /* Enable Rx Queue Control */ value = osi_readl((nveu8_t *)osi_core->base + MGBE_MAC_RQC0R); @@ -1796,7 +1796,240 @@ static inline void mgbe_update_dma_sr_stats(struct osi_core_priv_data *osi_core, } /** - * @brief mgbe_handle_common_intr - Handles common nve32_terrupt. + * @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_readl((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 |= ((tcinx << MGBE_MTL_TX_OP_MODE_Q2TCMAP_SHIFT) & + MGBE_MTL_TX_OP_MODE_Q2TCMAP); + osi_writel(value, (unsigned char *)osi_core->base + + MGBE_MTL_CHX_TX_OP_MODE(qinx)); + + /* Set Algo and Credit control */ + value = osi_readl((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_writel(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_readl((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_writel(value, (unsigned char *)osi_core->base + + MGBE_MTL_TCQ_QW(tcinx)); + + /* Set Send slope credit */ + value = osi_readl((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_writel(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_writel(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_writel(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_readl((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_readl((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_readl((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_readl((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_readl((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_readl((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_common_intr - Handles common interrupt. * * Algorithm: Clear common nve32_terrupt source. * @@ -2186,8 +2419,9 @@ void mgbe_init_core_ops(struct core_ops *ops) ops->set_mdc_clk_rate = OSI_NULL; ops->flush_mtl_tx_queue = mgbe_flush_mtl_tx_queue; ops->config_mac_loopback = mgbe_config_mac_loopback; - ops->set_avb_algorithm = OSI_NULL; ops->get_avb_algorithm = OSI_NULL; + 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 = OSI_NULL; ops->config_rx_crc_check = OSI_NULL; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 4467d03..d67e205 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -147,8 +147,14 @@ #define MGBE_MTL_RXQ_DMA_MAP2 0x1038 #define MGBE_MTL_RXQ_DMA_MAP3 0x103b #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_TXQ_QW(x) ((0x0080U * (x)) + 0x1118U) +#define MGBE_MTL_TC_PRTY_MAP0 0x1040 +#define MGBE_MTL_TC_PRTY_MAP1 0x1044 /** @} */ @@ -159,12 +165,27 @@ * @{ */ #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_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_TXQ_QW_ISCQW OSI_BIT(4) +#define MGBE_MTL_TCQ_QW_ISCQW OSI_BIT(4) #define MGBE_MAC_RMCR_ACS OSI_BIT(1) #define MGBE_MAC_RMCR_CST OSI_BIT(2) #define MGBE_MAC_RMCR_IPC OSI_BIT(9) From d66dc56cabaa64374ef0518bd168d577de06a0d7 Mon Sep 17 00:00:00 2001 From: narayanr <narayanr@nvidia.com> Date: Thu, 12 Mar 2020 20:13:56 +0530 Subject: [PATCH 183/458] nvethernetrm: mgbe: fix doxygen comments Bug 200598918 Change-Id: I230c16d83070356efc8560b26a238db7927e7adf Signed-off-by: narayanr <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2314668 Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> --- osi/core/mgbe_core.c | 7 +++++++ osi/core/xpcs.h | 21 +++++++++++++++++++++ osi/dma/mgbe_dma.c | 32 +++++++++----------------------- osi/dma/mgbe_dma.h | 6 +++--- 4 files changed, 40 insertions(+), 26 deletions(-) diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index a9e75f1..d07ab80 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -2210,6 +2210,13 @@ static int mgbe_set_speed(struct osi_core_priv_data *const osi_core, const int s 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 */ diff --git a/osi/core/xpcs.h b/osi/core/xpcs.h index 9c609fb..b96e9ae 100644 --- a/osi/core/xpcs.h +++ b/osi/core/xpcs.h @@ -69,10 +69,21 @@ #define XPCS_REG_ADDR_SHIFT 10U #define XPCS_REG_ADDR_MASK 0x1FFFU #define XPCS_REG_VALUE_MASK 0xFFU +/** @} */ int xpcs_init(struct osi_core_priv_data *osi_core); int xpcs_start(struct osi_core_priv_data *osi_core); +/** + * @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), @@ -81,6 +92,15 @@ static inline unsigned int xpcs_read(void *xpcs_base, unsigned int reg_addr) ((reg_addr) & XPCS_REG_VALUE_MASK)); } +/** + * @brief xpcs_read - 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) { @@ -89,4 +109,5 @@ static inline void xpcs_write(void *xpcs_base, unsigned int reg_addr, osi_writel(val, (unsigned char *)xpcs_base + (((reg_addr) & XPCS_REG_VALUE_MASK))); } + #endif diff --git a/osi/dma/mgbe_dma.c b/osi/dma/mgbe_dma.c index 46ce900..99f63b0 100644 --- a/osi/dma/mgbe_dma.c +++ b/osi/dma/mgbe_dma.c @@ -445,16 +445,14 @@ static void mgbe_configure_dma_channel(nveu32_t chan, } /** - * mgbe_dma_chan_to_vmirq_map - Map DMA channels to a specific VM IRQ. + * @brief mgbe_dma_chan_to_vmirq_map - Map DMA channels to a specific VM IRQ. * * Algorithm: Programs HW to map DMA channels to specific VM. * - * Dependencies: OSD layer needs to update number of VM channels and - * DMA channel list in osi_vm_irq_data. + * @param[in] osi_dma: OSI DMA private data structure. * - * @param[in] osi_dma: OSI private data structure. - * - * Return: None. + * @note OSD layer needs to update number of VM channels and + * DMA channel list in osi_vm_irq_data. */ static void mgbe_dma_chan_to_vmirq_map(struct osi_dma_priv_data *osi_dma) { @@ -523,15 +521,11 @@ static void mgbe_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) } /** - * mgbe_get_global_dma_status - Gets DMA status. + * @brief mgbe_get_global_dma_status - Gets DMA status. * * Algorithm: Returns global DMA Tx/Rx interrupt status * * @param[in] addr: MAC base address. - * - * Dependencies: None. - * Protection: None. - * Return: None. */ static nveu32_t mgbe_get_global_dma_status(void *addr) { @@ -539,16 +533,12 @@ static nveu32_t mgbe_get_global_dma_status(void *addr) } /** - * mgbe_clear_vm_tx_intr - Clear VM Tx interrupt + * @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. - * - * Dependencies: None. - * Protection: None. - * Return: None. */ static void mgbe_clear_vm_tx_intr(void *addr, nveu32_t chan) { @@ -561,16 +551,12 @@ static void mgbe_clear_vm_tx_intr(void *addr, nveu32_t chan) } /** - * mgbe_clear_vm_rx_intr - Clear VM Rx interrupt - * - * Algorithm: Clear Rx interrupt source at DMA and wrapper level. + * @brief mgbe_clear_vm_rx_intr - Clear VM Rx interrupt * * @param[in] addr: MAC base address. - * @param[in] chan: DMA Rx channel number. + * @param[in] chan: DMA Tx channel number. * - * Dependencies: None. - * Protection: None. - * Return: None. + * Algorithm: Clear Rx interrupt source at DMA and wrapper level. */ static void mgbe_clear_vm_rx_intr(void *addr, nveu32_t chan) { diff --git a/osi/dma/mgbe_dma.h b/osi/dma/mgbe_dma.h index 90bbc95..04e4e4c 100644 --- a/osi/dma/mgbe_dma.h +++ b/osi/dma/mgbe_dma.h @@ -24,7 +24,7 @@ #define INCLUDED_MGBE_DMA_H /** - * @addtogroup MGBE-DMA-CH DMA Channel Register offsets + * @addtogroup MGBE_DMA DMA Channel Register offsets * * @brief MGBE DMA Channel register offsets * @{ @@ -48,7 +48,7 @@ /** @} */ /** - * @addtogroup MGBE-INTR INT Channel Register offsets + * @addtogroup MGBE_INTR INT Channel Register offsets * * @brief MGBE Virtural Interrupt Channel register offsets * @{ @@ -59,7 +59,7 @@ /** @} */ /** - * @addtogroup MGBE BIT fields for MGBE Rgisters + * @addtogroup MGBE_BIT BIT fields for MGBE channel registers * * @brief Values defined for the MGBE registers * @{ From 960e5153ffefa96ba78ef14b98cabda47d3fe5a6 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Fri, 13 Mar 2020 13:55:30 +0530 Subject: [PATCH 184/458] nvethernetrm: mgbe/eqos: Add support for VLAN Adds support for VLAN insertion/deletion and filtering on receive side. Perfect filtering enabled for the VLAN filtering. HW maximum has 32 VLAN perfect filters. If user adds more than 32 then all VID's will be allowed Bug 200565888 Change-Id: I75bdc261a77df4f9d9f5fff9a2943731de9dd4ef Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2312144 Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> --- include/ivc_core.h | 2 +- include/osi_common.h | 4 - include/osi_core.h | 13 +- osi/core/eqos_core.c | 5 +- osi/core/ivc_core.c | 2 +- osi/core/mgbe_core.c | 40 +++- osi/core/mgbe_core.h | 6 + osi/core/osi_core.c | 45 +++- osi/core/vlan_filter.c | 473 ++++++++++++++++++++++++++++++++++++++++ osi/core/vlan_filter.h | 76 +++++++ osi/dma/dma_local.h | 3 + osi/dma/eqos_desc.c | 29 +++ osi/dma/hw_desc.h | 1 + osi/dma/mgbe_desc.c | 24 ++ osi/dma/osi_dma_local.h | 3 + osi/dma/osi_dma_txrx.c | 39 +--- 16 files changed, 713 insertions(+), 52 deletions(-) create mode 100644 osi/core/vlan_filter.c create mode 100644 osi/core/vlan_filter.h diff --git a/include/ivc_core.h b/include/ivc_core.h index 109162d..0dc1308 100644 --- a/include/ivc_core.h +++ b/include/ivc_core.h @@ -78,7 +78,7 @@ typedef enum ivc_cmd { set_avb_algorithm, get_avb_algorithm, config_vlan_filtering, - update_vlan_id, + i_update_vlan_id, reset_mmc, configure_eee, save_registers, diff --git a/include/osi_common.h b/include/osi_common.h index 82fdec2..abdf62e 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -167,10 +167,6 @@ #define OSI_ENABLE 1U #define OSI_NONE 0U #define OSI_DISABLE 0U -#if 0 -#define OSI_AMASK_DISABLE 0U - -#endif #define OSI_BIT(nr) ((nveu32_t)1 << (nr)) diff --git a/include/osi_core.h b/include/osi_core.h index a5b43df..f570430 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -177,6 +177,10 @@ typedef my_lint_64 nvel64_t; 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 + struct osi_core_priv_data; /** @@ -729,6 +733,11 @@ struct osi_core_priv_data { 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; }; /** @@ -1963,8 +1972,8 @@ nve32_t osi_config_vlan_filtering(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -nve32_t osi_update_vlan_id(struct osi_core_priv_data *const osi_core, - const nveu32_t vid); +nve32_t osi_update_vlan_id(struct osi_core_priv_data *const osi_core, + const nveu32_t vid); /** * @brief osi_reset_mmc - invoke function to reset MMC counter and data diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 5f459e9..3cf4139 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -25,6 +25,7 @@ #include "eqos_core.h" #include "eqos_mmc.h" #include "core_local.h" +#include "vlan_filter.h" /** * @brief eqos_core_safety_config - EQOS MAC core safety configuration @@ -4050,10 +4051,6 @@ static inline nve32_t eqos_update_vlan_id( struct osi_core_priv_data *const osi_core, nveu32_t const vid) { - /* Don't add VLAN ID to TR register which is eventually set TR - * to 0x0 and allow all tagged packets - */ - return 0; } diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index 21f023f..137e680 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -1289,7 +1289,7 @@ static inline nve32_t ivc_update_vlan_id( osi_memset(&msg_common, 0, sizeof(msg_common)); - msg_common.cmd = update_vlan_id; + msg_common.cmd = i_update_vlan_id; msg_common.data.args.arguments[index++] = vid; msg_common.data.args.count = index; diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index d07ab80..bc92d95 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -28,6 +28,7 @@ #include "core_local.h" #include "xpcs.h" #include "mgbe_mmc.h" +#include "vlan_filter.h" /** * @brief mgbe_config_fw_err_pkts - Configure forwarding of error packets @@ -1250,6 +1251,21 @@ static int mgbe_config_vlan_filtering(struct osi_core_priv_data *osi_core, return 0; } +/** + * @brief mgbe_update_vlan_id - update VLAN ID in Tag register + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] vid: VLAN ID to be programmed. + * + * @retval 0 on success + * @retval -1 on failure + */ +static inline int mgbe_update_vlan_id(struct osi_core_priv_data *const osi_core, + unsigned int vid) +{ + return 0; +} + /** * @brief mgbe_flush_mtl_tx_queue - Flush MTL Tx queue * @@ -1613,6 +1629,26 @@ static void mgbe_configure_mac(struct osi_core_priv_data *osi_core) value |= MGBE_IMR_RGSMIIIE; osi_writel(value, (nveu8_t *)osi_core->base + MGBE_MAC_IER); + /* Enable VLAN configuration */ + value = osi_readl((unsigned char *)osi_core->base + MGBE_MAC_VLAN_TR); + /* Enable VLAN Tag in RX Status + * Disable double VLAN Tag processing on TX and RX + * TODO: Need to check EQOS comments here + */ + 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_writel(value, (unsigned char *)osi_core->base + MGBE_MAC_VLAN_TR); + + value = osi_readl((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_writel(value, (unsigned char *)osi_core->base + MGBE_MAC_VLANTIR); + /* TODO: USP (user Priority) to RxQ Mapping */ } @@ -2443,8 +2479,8 @@ void mgbe_init_core_ops(struct core_ops *ops) 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->update_vlan_id = OSI_NULL; + ops->config_vlan_filtering = mgbe_config_vlan_filtering; + ops->update_vlan_id = mgbe_update_vlan_id; ops->set_systime_to_mac = OSI_NULL; ops->config_addend = OSI_NULL; ops->adjust_mactime = OSI_NULL, diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index d67e205..d603603 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -31,6 +31,7 @@ */ #define MGBE_MAC_PFR 0x0008 #define MGBE_MAC_VLAN_TR 0x0050 +#define MGBE_MAC_VLANTIR 0x0060 #define MGBE_MAC_RQC0R 0x00A0 #define MGBE_MAC_RQC1R 0x00A4 #define MGBE_MAC_MA0HR 0x0300 @@ -268,6 +269,11 @@ #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) /* DMA SBUS */ #define MGBE_DMA_SBUS_BLEN8 OSI_BIT(2) diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index d7ef72d..bc6e408 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -24,6 +24,7 @@ #include <ivc_core.h> #include "core_local.h" #include "../osi/common/common.h" +#include "vlan_filter.h" /** * @brief g_core - Static core local data variable @@ -189,6 +190,25 @@ nve32_t osi_poll_for_mac_reset_complete( return ops_p->poll_for_swr(osi_core); } +/** + * @brief init_vlan_filters - Helper function to init all VLAN SW information. + * + * Algorithm: Initilize 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_hw_core_init(struct osi_core_priv_data *const osi_core, nveu32_t tx_fifo_size, nveu32_t rx_fifo_size) { @@ -196,6 +216,8 @@ nve32_t osi_hw_core_init(struct osi_core_priv_data *const osi_core, return -1; } + init_vlan_filters(osi_core); + return ops_p->core_init(osi_core, tx_fifo_size, rx_fifo_size); } @@ -805,13 +827,32 @@ nve32_t osi_config_vlan_filtering(struct osi_core_priv_data *const osi_core, } nve32_t osi_update_vlan_id(struct osi_core_priv_data *const osi_core, - const nveu32_t vid) + const nveu32_t vid) { + unsigned int action = vid & VLAN_ACTION_MASK; + unsigned short vlan_id = vid & VLAN_VID_MASK; + + if (validate_args(osi_core) < 0) { return -1; } - return ops_p->update_vlan_id(osi_core, vid); + 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, ops_p, vid); } nve32_t osi_reset_mmc(struct osi_core_priv_data *const osi_core) diff --git a/osi/core/vlan_filter.c b/osi/core/vlan_filter.c new file mode 100644 index 0000000..dd73a4b --- /dev/null +++ b/osi/core/vlan_filter.c @@ -0,0 +1,473 @@ +/* + * 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 "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 = __builtin_ctzl(bitmap); + + if (osi_core->vid[temp] == vlan_id) { + /* vlan ID match found */ + vid_idx = 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 &= ~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 &= ~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 = __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 &= ~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 short 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 &= ~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 found to be deleted in SW queue */ + 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 new file mode 100644 index 0000000..d4406ce --- /dev/null +++ b/osi/core/vlan_filter.h @@ -0,0 +1,76 @@ +/* + * 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 <osi_core.h> +#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/dma/dma_local.h b/osi/dma/dma_local.h index ceb5b5c..996b5ca 100644 --- a/osi/dma/dma_local.h +++ b/osi/dma/dma_local.h @@ -95,6 +95,9 @@ struct desc_ops { /** Called to get rx error stats */ void (*update_rx_err_stats)(struct osi_rx_desc *rx_desc, struct osi_pkt_err_stats pkt_err_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); }; /** diff --git a/osi/dma/eqos_desc.c b/osi/dma/eqos_desc.c index 0a9493a..99a4d8a 100644 --- a/osi/dma/eqos_desc.c +++ b/osi/dma/eqos_desc.c @@ -23,6 +23,34 @@ #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 * @@ -136,4 +164,5 @@ 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; } diff --git a/osi/dma/hw_desc.h b/osi/dma/hw_desc.h index b588037..164637e 100644 --- a/osi/dma/hw_desc.h +++ b/osi/dma/hw_desc.h @@ -64,6 +64,7 @@ #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 */ diff --git a/osi/dma/mgbe_desc.c b/osi/dma/mgbe_desc.c index a737a82..9d7786f 100644 --- a/osi/dma/mgbe_desc.c +++ b/osi/dma/mgbe_desc.c @@ -23,6 +23,29 @@ #include "dma_local.h" #include "hw_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 * @@ -77,4 +100,5 @@ 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; } diff --git a/osi/dma/osi_dma_local.h b/osi/dma/osi_dma_local.h index 1eeaa62..c94cef0 100644 --- a/osi/dma/osi_dma_local.h +++ b/osi/dma/osi_dma_local.h @@ -38,6 +38,9 @@ struct desc_ops { /** Called to get rx error stats */ void (*update_rx_err_stats)(struct osi_rx_desc *rx_desc, struct osi_pkt_err_stats pkt_err_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); }; /** diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 6cac12a..6eb66dc 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -28,41 +28,6 @@ static struct desc_ops d_ops; -/** - * @brief get_rx_vlan_from_desc - Get Rx VLAN from descriptor - * - * @note - * Algorithm: - * - Check if the descriptor has any type set. - * - If set, set a per packet context flag indicating packet is VLAN - * tagged. - * - Extract VLAN tag ID from the descriptor - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @param[in] rx_desc: Rx descriptor - * @param[in, out] rx_pkt_cx: Per-Rx packet context structure - */ -static inline void get_rx_vlan_from_desc(struct osi_rx_desc *rx_desc, - struct osi_rx_pkt_cx *rx_pkt_cx) -{ - nveu32_t 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 get_rx_tstamp_status - Get Tx Time stamp status * @@ -366,7 +331,9 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, /* Check if COE Rx checksum is valid */ d_ops.get_rx_csum(rx_desc, rx_pkt_cx); - get_rx_vlan_from_desc(rx_desc, rx_pkt_cx); + /* Get Rx VLAN from descriptor */ + d_ops.get_rx_vlan(rx_desc, rx_pkt_cx); + context_desc = rx_ring->rx_desc + rx_ring->cur_rx_idx; /* Get rx time stamp */ ret = get_rx_hwstamp(osi_dma, rx_desc, context_desc, From 33990d713d696543cca2754dcec038ef9db843a8 Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Mon, 16 Mar 2020 18:39:43 +0530 Subject: [PATCH 185/458] nvethernetrm: mgbe: Add save and restore support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Define missing register that requires save and restore support - Define MGBE-HW-BACKUP group for these register backup index - Define new mgbe_core_backup_config core_backup structure - Add mgbe_core_backup_init call to initialize reg_addr of mgbe_core_backup_config - Implement save and restore callbacks to save and restore of direct and indirect access registers Bug 200596517 Change-Id: I58e9571a916223c90b3ed1f4622f57648c013c77 Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2310184 Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> --- osi/core/mgbe_core.c | 351 +++++++++++++++++++++++++++++++++++++++---- osi/core/mgbe_core.h | 172 +++++++++++++++++++-- 2 files changed, 478 insertions(+), 45 deletions(-) diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index bc92d95..04e3fae 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -88,6 +88,7 @@ static int mgbe_config_fw_err_pkts(struct osi_core_priv_data *osi_core, return 0; } + /** * @brief mgbe_poll_for_swr - Poll for software reset (SWR bit in DMA Mode) * @@ -499,11 +500,14 @@ static int mgbe_poll_for_l3l4crtl(struct osi_core_priv_data *osi_core) * @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 void mgbe_l3l4_filter_write(struct osi_core_priv_data *osi_core, - unsigned int filter_no, - unsigned int filter_type, - unsigned int value) +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; @@ -538,7 +542,10 @@ static void mgbe_l3l4_filter_write(struct osi_core_priv_data *osi_core, OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, "Fail to write L3_L4_Address_Control\n", filter_type); + return -1; } + + return 0; } /** @@ -552,11 +559,14 @@ static void mgbe_l3l4_filter_write(struct osi_core_priv_data *osi_core, * @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 void mgbe_l3l4_filter_read(struct osi_core_priv_data *osi_core, - unsigned int filter_no, - unsigned int filter_type, - unsigned int *value) +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; @@ -588,11 +598,12 @@ static void mgbe_l3l4_filter_read(struct osi_core_priv_data *osi_core, OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, "Fail to read L3L4 Address\n", filter_type); - return; + return -1; } /* Read the MGBE_MAC_L3L4_DATA for filter register data */ *value = osi_readl((unsigned char *)base + MGBE_MAC_L3L4_DATA); + return 0; } /** @@ -618,6 +629,7 @@ static int mgbe_update_ip4_addr(struct osi_core_priv_data *osi_core, { 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, @@ -650,18 +662,18 @@ static int mgbe_update_ip4_addr(struct osi_core_priv_data *osi_core, temp = (unsigned int)addr[0] << 24; value |= temp; if (src_dst_addr_match == OSI_SOURCE_MATCH) { - mgbe_l3l4_filter_write(osi_core, - filter_no, - MGBE_MAC_L3_AD0R, - value); + ret = mgbe_l3l4_filter_write(osi_core, + filter_no, + MGBE_MAC_L3_AD0R, + value); } else { - mgbe_l3l4_filter_write(osi_core, - filter_no, - MGBE_MAC_L3_AD1R, - value); + ret = mgbe_l3l4_filter_write(osi_core, + filter_no, + MGBE_MAC_L3_AD1R, + value); } - return 0; + return ret; } /** @@ -685,6 +697,7 @@ static int mgbe_update_ip6_addr(struct osi_core_priv_data *osi_core, { 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, @@ -704,24 +717,39 @@ static int mgbe_update_ip6_addr(struct osi_core_priv_data *osi_core, value = addr[7]; temp = (unsigned int)addr[6] << 16; value |= temp; - mgbe_l3l4_filter_write(osi_core, filter_no, MGBE_MAC_L3_AD0R, value); + + 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; - mgbe_l3l4_filter_write(osi_core, filter_no, MGBE_MAC_L3_AD1R, value); + + 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; - mgbe_l3l4_filter_write(osi_core, filter_no, MGBE_MAC_L3_AD2R, value); + + 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; - mgbe_l3l4_filter_write(osi_core, filter_no, MGBE_MAC_L3_AD3R, value); - return 0; + return mgbe_l3l4_filter_write(osi_core, filter_no, MGBE_MAC_L3_AD3R, value); } /** @@ -785,6 +813,7 @@ static int mgbe_update_l4_port_no(struct osi_core_priv_data *osi_core, { 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, @@ -793,7 +822,12 @@ static int mgbe_update_l4_port_no(struct osi_core_priv_data *osi_core, return -1; } - mgbe_l3l4_filter_read(osi_core, filter_no, MGBE_MAC_L4_ADDR, &value); + 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); @@ -803,9 +837,8 @@ static int mgbe_update_l4_port_no(struct osi_core_priv_data *osi_core, value |= ((temp << MGBE_MAC_L4_ADDR_DP_SHIFT) & MGBE_MAC_L4_ADDR_DP_MASK); } - mgbe_l3l4_filter_write(osi_core, filter_no, MGBE_MAC_L4_ADDR, value); - return 0; + return mgbe_l3l4_filter_write(osi_core, filter_no, MGBE_MAC_L4_ADDR, value); } /** @@ -912,6 +945,7 @@ static int mgbe_config_l3_filters(struct osi_core_priv_data *osi_core, 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, @@ -958,7 +992,12 @@ static int mgbe_config_l3_filters(struct osi_core_priv_data *osi_core, return -1; } - mgbe_l3l4_filter_read(osi_core, filter_no, MGBE_MAC_L3L4_CTR, &value); + 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); @@ -1043,13 +1082,18 @@ static int mgbe_config_l3_filters(struct osi_core_priv_data *osi_core, } } } - mgbe_l3l4_filter_write(osi_core, filter_no, MGBE_MAC_L3L4_CTR, value); + + 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 0; + return ret; } /** @@ -1083,6 +1127,7 @@ static int mgbe_config_l4_filters(struct osi_core_priv_data *osi_core, 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, @@ -1128,7 +1173,12 @@ static int mgbe_config_l4_filters(struct osi_core_priv_data *osi_core, return -1; } - mgbe_l3l4_filter_read(osi_core, filter_no, MGBE_MAC_L3L4_CTR, &value); + 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); @@ -1169,13 +1219,18 @@ static int mgbe_config_l4_filters(struct osi_core_priv_data *osi_core, value &= ~MGBE_MAC_L4_DP_CTRL_CLEAR; } } - mgbe_l3l4_filter_write(osi_core, filter_no, MGBE_MAC_L3L4_CTR, value); + + 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 0; + return ret; } /** @@ -1683,6 +1738,92 @@ static void mgbe_configure_dma(void *base) osi_writel(value, (nveu8_t *)base + MGBE_DMA_SBUS); } +/** + * @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_core_init - MGBE MAC, MTL and common DMA Initialization * @@ -1711,6 +1852,8 @@ static nve32_t mgbe_core_init(struct osi_core_priv_data *osi_core, nveu32_t tx_fifo = 0; nveu32_t rx_fifo = 0; + mgbe_core_backup_init(osi_core); + /* reset mmc counters */ osi_writel(MGBE_MMC_CNTRL_CNTRST, (nveu8_t *)osi_core->base + MGBE_MMC_CNTRL); @@ -2281,6 +2424,148 @@ static int mgbe_mdio_busy_wait(struct osi_core_priv_data *const osi_core) 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) +{ + void *base = osi_core->base; + 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_readl(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(base, 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(base, 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(base, 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(base, 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(base, 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(base, 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; + } + } + + 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) +{ + void *base = osi_core->base; + 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_writel(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(base, 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(base, 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(base, 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(base, 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(base, 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(base, 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; + } + } + + return ret; +} + /** * @brief mgbe_write_phy_reg - Write to a PHY register over MDIO bus. * @@ -2488,6 +2773,8 @@ void mgbe_init_core_ops(struct core_ops *ops) ops->config_ssir = OSI_NULL; 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; }; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index d603603..4edaf01 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -29,29 +29,54 @@ * @brief MGBE MAC register offsets * @{ */ -#define MGBE_MAC_PFR 0x0008 -#define MGBE_MAC_VLAN_TR 0x0050 -#define MGBE_MAC_VLANTIR 0x0060 -#define MGBE_MAC_RQC0R 0x00A0 -#define MGBE_MAC_RQC1R 0x00A4 -#define MGBE_MAC_MA0HR 0x0300 -#define MGBE_MAC_MA0LR 0x0304 #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_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_PMTCSR 0x00C0 +#define MGBE_MAC_LPI_CSR 0x00D0 +#define MGBE_MAC_LPI_TIMER_CTRL 0x00D4 +#define MGBE_MAC_LPI_EN_TIMER 0x00D8 +#define MGBE_MDIO_SCCD 0x0204 +#define MGBE_MDIO_SCCA 0x0200 +#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_MMC_TX_INTR_EN 0x0810 #define MGBE_MMC_RX_INTR_EN 0x080C #define MGBE_MMC_CNTRL 0x0800 -#define MGBE_MAC_IER 0x00B4 -#define MGBE_MAC_ISR 0x00B0 -#define MGBE_MDIO_SCCD 0x0204 -#define MGBE_MDIO_SCCA 0x0200 +#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_ARPPA 0x0c10 -#define MGBE_MAC_ADDRH(x) ((0x0008U * (x)) + 0x0300U) -#define MGBE_MAC_ADDRL(x) ((0x0008U * (x)) + 0x0304U) #define MGBE_MAC_L3L4_ADDR_CTR 0x0C00 #define MGBE_MAC_L3L4_DATA 0x0C04 /** @} */ +/** + * @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 L3L4 defines * @@ -59,6 +84,7 @@ * 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 @@ -143,6 +169,7 @@ * @brief MGBE MTL register offsets * @{ */ +#define MGBE_MTL_OP_MODE 0x1000 #define MGBE_MTL_RXQ_DMA_MAP0 0x1030 #define MGBE_MTL_RXQ_DMA_MAP1 0x1034 #define MGBE_MTL_RXQ_DMA_MAP2 0x1038 @@ -307,4 +334,123 @@ #define FIFO_SIZE_B(x) (x) #define FIFO_SIZE_KB(x) ((x) * 1024U) /** @} */ + +/** + * @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_TCR_BAK_IDX ((MGBE_MAC_LPI_EN_TIMER_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))) + +#define MGBE_MAX_BAK_IDX ((MGBE_MAC_VLAN_BAK_IDX(0) + \ + MGBE_MAX_VLAN_FILTER + 1U)) +/** @} */ #endif /* MGBE_CORE_H_ */ From eff0e31267826674961832ff5958038c2895fc6c Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Fri, 15 Nov 2019 16:20:59 +0530 Subject: [PATCH 186/458] nvethernetrm: mgbe: add flow control support Add flow control support for MGBE. Bug 200565905 Change-Id: I4edb82225cfd60fcff47d0aef11b516d9960961a Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2278454 Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> --- include/osi_common.h | 27 ++++++- osi/core/eqos_core.h | 17 ---- osi/core/mgbe_core.c | 182 ++++++++++++++++++++++++++++++++++++++++++- osi/core/mgbe_core.h | 32 ++++++++ 4 files changed, 238 insertions(+), 20 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index abdf62e..9061f20 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -26,9 +26,32 @@ #include "../osi/common/type.h" /** - * @addtogroup Helper Helper MACROS + * @addtogroup FC Flow Control Threshold Macros * - * @brief EQOS generic helper 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 diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 42beca2..9937c75 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -23,23 +23,6 @@ #ifndef INCLUDED_EQOS_CORE_H #define INCLUDED_EQOS_CORE_H -/** - * @addtogroup EQOS-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 (nveu32_t)1 -#define FULL_MINUS_2_K (nveu32_t)2 -#define FULL_MINUS_2_5K (nveu32_t)3 -#define FULL_MINUS_3_K (nveu32_t)4 -#define FULL_MINUS_4_K (nveu32_t)6 -#define FULL_MINUS_6_K (nveu32_t)10 -#define FULL_MINUS_10_K (nveu32_t)18 -#define FULL_MINUS_16_K (nveu32_t)30 -/** @} */ - #ifndef OSI_STRIPPED_LIB /** * @addtogroup EQOS-MDC MDC Clock Selection defines diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 04e3fae..1ff9a9c 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -1502,6 +1502,99 @@ static int mgbe_config_rxcsum_offload( 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 + */ +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 * @@ -1571,9 +1664,22 @@ static nve32_t mgbe_configure_mtl_queue(nveu32_t 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_writel(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_readl((unsigned char *)osi_core->base + + MGBE_MTL_RXQ_FLOW_CTRL(qinx)); + update_rfa_rfd(rx_fifo, &value); + osi_writel(value, (unsigned char *)osi_core->base + + MGBE_MTL_RXQ_FLOW_CTRL(qinx)); + /* Transmit Queue weight */ value = osi_readl((nveu8_t *)osi_core->base + MGBE_MTL_TCQ_QW(qinx)); @@ -1590,6 +1696,70 @@ static nve32_t mgbe_configure_mtl_queue(nveu32_t qinx, 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_readl((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_writel(val, (unsigned char *)addr + MGBE_MAC_QX_TX_FLW_CTRL(0U)); + + /* Configure MAC Rx Flow control*/ + /* Read MAC Rx Flow control Register */ + val = osi_readl((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_writel(val, (unsigned char *)addr + MGBE_MAC_RX_FLW_CTRL); + + return 0; +} + /** * @brief mgbe_configure_mac - Configure MAC * @@ -1704,6 +1874,16 @@ static void mgbe_configure_mac(struct osi_core_priv_data *osi_core) value &= ~MGBE_MAC_VLANTIRR_CSVL; osi_writel(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->base, + 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 */ } @@ -2753,7 +2933,7 @@ void mgbe_init_core_ops(struct core_ops *ops) ops->config_fw_err_pkts = mgbe_config_fw_err_pkts; ops->config_tx_status = OSI_NULL; ops->config_rx_crc_check = OSI_NULL; - ops->config_flow_control = OSI_NULL; + ops->config_flow_control = mgbe_config_flow_control; ops->config_arp_offload = mgbe_config_arp_offload; ops->config_rxcsum_offload = mgbe_config_rxcsum_offload; ops->config_mac_pkt_filter_reg = mgbe_config_mac_pkt_filter_reg; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 4edaf01..11ac556 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -181,6 +181,7 @@ #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_TC_PRTY_MAP0 0x1040 #define MGBE_MTL_TC_PRTY_MAP1 0x1044 /** @} */ @@ -323,6 +324,37 @@ #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_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 +/** @} */ + +/** + * @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 */ /** @} */ /** From 5ac9f01b4f32f61a7a72aee90f9343b31e38b5ea Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Fri, 22 Nov 2019 23:49:03 +0530 Subject: [PATCH 187/458] nvethernetrm: Add support for EEE LPI Add an API to configure the EEE LPI mode. Tx LPI is enabled with a default entry time of 1sec. The MAC controller has capability to automatically enter LPI mode when all transmissions are complete. Bug 200565917 Change-Id: I59b5eccc83770bc7dff9dadb192b733e0d01d7dd Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2274444 Tested-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> --- osi/core/mgbe_core.c | 124 ++++++++++++++++++++++++++++++++++++++++++- osi/core/mgbe_core.h | 36 +++++++++++++ osi/core/mgbe_mmc.c | 12 +++++ osi/core/xpcs.c | 54 +++++++++++++++++++ osi/core/xpcs.h | 6 +++ 5 files changed, 231 insertions(+), 1 deletion(-) diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 1ff9a9c..2355134 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -1877,7 +1877,7 @@ static void mgbe_configure_mac(struct osi_core_priv_data *osi_core) /* 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->base, + 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", @@ -2907,6 +2907,127 @@ static int mgbe_read_phy_reg(struct osi_core_priv_data *osi_core, return (int)data; } +/** + * @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] addr: base address of memory mapped register space of MAC. + * + * @note MAC has to be out of reset, and clocks supplied. + */ +static inline void mgbe_disable_tx_lpi(void *addr) +{ + unsigned int lpi_csr = 0; + + /* Disable LPI control bits */ + lpi_csr = osi_readl((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_writel(lpi_csr, (unsigned char *)addr + 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->xpcs_base, 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_writel(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_writel(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_writel(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_readl((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_writel(lpi_csr, (unsigned char *)addr + MGBE_MAC_LPI_CSR); + } else { + /* Disable LPI control bits */ + mgbe_disable_tx_lpi(osi_core->base); + } +} + /** * @brief mgbe_init_core_ops - Initialize MGBE MAC core operations */ @@ -2957,4 +3078,5 @@ void mgbe_init_core_ops(struct core_ops *ops) ops->restore_registers = mgbe_restore_registers; ops->read_mmc = mgbe_read_mmc; ops->reset_mmc = mgbe_reset_mmc; + ops->configure_eee = mgbe_configure_eee; }; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 11ac556..f126eba 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -23,6 +23,37 @@ #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 408-1 for silicon and 13MHZ-1 for uFPGA + */ +#define MGBE_1US_TIC_COUNTER 0xC +/** @} */ + /** * @addtogroup MGBE-MAC MAC register offsets * @@ -46,6 +77,7 @@ #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_MDIO_SCCD 0x0204 #define MGBE_MDIO_SCCA 0x0200 #define MGBE_MAC_MA0HR 0x0300 @@ -302,6 +334,10 @@ #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) /* DMA SBUS */ #define MGBE_DMA_SBUS_BLEN8 OSI_BIT(2) diff --git a/osi/core/mgbe_mmc.c b/osi/core/mgbe_mmc.c index 4253df0..68cff7a 100644 --- a/osi/core/mgbe_mmc.c +++ b/osi/core/mgbe_mmc.c @@ -358,6 +358,18 @@ void mgbe_read_mmc(struct osi_core_priv_data *osi_core) 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); diff --git a/osi/core/xpcs.c b/osi/core/xpcs.c index 2e2b923..19bf72e 100644 --- a/osi/core/xpcs.c +++ b/osi/core/xpcs.c @@ -269,3 +269,57 @@ int xpcs_init(struct osi_core_priv_data *osi_core) return 0; } + +/** + * @brief xpcs_eee - XPCS enable/disable EEE + * + * Algorithm: This routine update register related to EEE + * for XPCS. + * + * @param[in] xpcs_base: XPCS virtual base address + * @param[in] en_dis: enable - 1 or disable - 0 + * + * @retval 0 on success + * @retval -1 on failure. + */ +int xpcs_eee(void *xpcs_base, unsigned int en_dis) +{ + unsigned int val = 0x0U; + + if (en_dis != OSI_ENABLE && en_dis != OSI_DISABLE) { + 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; + xpcs_write(xpcs_base, XPCS_VR_XS_PCS_EEE_MCTRL0, val); + 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 */ + + /* TODO for uFPGA */ + + 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_EEE_SLR_BYP; + val &= ~XPCS_VR_XS_PCS_EEE_MCTRL0_LTX_EN; + val &= ~XPCS_VR_XS_PCS_EEE_MCTRL0_LRX_EN; + + val |= (XPCS_VR_XS_PCS_EEE_MCTRL0_LTX_EN | + // XPCS_VR_XS_PCS_EEE_MCTRL0_LTX_EN | + XPCS_VR_XS_PCS_EEE_MCTRL0_LRX_EN); + xpcs_write(xpcs_base, XPCS_VR_XS_PCS_EEE_MCTRL0, val); + + return 0; +} diff --git a/osi/core/xpcs.h b/osi/core/xpcs.h index b96e9ae..10cd93a 100644 --- a/osi/core/xpcs.h +++ b/osi/core/xpcs.h @@ -36,10 +36,13 @@ #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_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 0xE00018 /** @} */ @@ -56,6 +59,8 @@ #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_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) @@ -73,6 +78,7 @@ int xpcs_init(struct osi_core_priv_data *osi_core); int xpcs_start(struct osi_core_priv_data *osi_core); +int xpcs_eee(void *xpcs_base, unsigned int en_dis); /** * @brief xpcs_read - read from xpcs. From 7e626950f546946a5fe8931da4c44ecfd4e3787f Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Fri, 13 Mar 2020 16:25:51 +0530 Subject: [PATCH 188/458] nvethernetrm: Add RX Route support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add new ptp_rx_queue variable in osi_ptp_config structure. - Declare an IP callback function for PTP RX queue index programming. - Check and call IP based PTP RX queue callback in osi_ptp_configuration. Bug 200596985 Change-Id: Ief040dc5b607ad729af5e9c0c1870249b456dcc7 Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> --- include/osi_core.h | 32 ++++++++++++++++++++++++++++++++ osi/core/core_local.h | 4 ++++ osi/core/eqos_core.c | 1 + osi/core/osi_core.c | 29 +++++++++++++++++++++++++++++ 4 files changed, 66 insertions(+) diff --git a/include/osi_core.h b/include/osi_core.h index f570430..e0117bc 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -209,6 +209,19 @@ struct osi_filter { nveu32_t src_dest; }; +/** + * @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 */ @@ -633,6 +646,8 @@ struct osi_ptp_config { nveu32_t one_nsec_accuracy; /** PTP system clock which is 62500000Hz */ nveu32_t ptp_clock; + /** PTP Packets RX Queue.*/ + nveu32_t ptp_rx_queue; }; /** @@ -1900,6 +1915,23 @@ nve32_t osi_configure_flow_control(struct osi_core_priv_data *const osi_core, nve32_t osi_config_arp_offload(struct osi_core_priv_data *const osi_core, const nveu32_t flags, const nveu8_t *ip_addr); +/** + * @brief osi_ptp_rxq - 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. + */ +int osi_rxq_route(struct osi_core_priv_data *const osi_core, + const struct osi_rxq_route *rx_route); + /** * @brief osi_config_vlan_filtering - OSI call for configuring VLAN filter * diff --git a/osi/core/core_local.h b/osi/core/core_local.h index b87f545..71ffc93 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -121,6 +121,10 @@ struct core_ops { const nveu32_t ptp_filter); /** Called to configure the sub second increment register */ void (*config_ssir)(struct osi_core_priv_data *const osi_core); + /** 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 */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 3cf4139..2091815 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -4489,6 +4489,7 @@ void eqos_init_core_ops(struct core_ops *ops) ops->adjust_mactime = eqos_adjust_mactime; ops->config_tscr = eqos_config_tscr; ops->config_ssir = eqos_config_ssir; + ops->config_ptp_rxq = OSI_NULL; ops->read_mmc = eqos_read_mmc; ops->write_phy_reg = eqos_write_phy_reg; ops->read_phy_reg = eqos_read_phy_reg; diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index bc6e408..910f1cb 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -658,6 +658,10 @@ nve32_t osi_ptp_configuration(struct osi_core_priv_data *const osi_core, /* disable hw time stamping */ /* Program MAC_Timestamp_Control Register */ ops_p->config_tscr(osi_core, OSI_DISABLE); + /* Disable PTP RX Queue routing */ + ret = ops_p->config_ptp_rxq(osi_core, + osi_core->ptp_config.ptp_rx_queue, + OSI_DISABLE); } else { /* Program MAC_Timestamp_Control Register */ ops_p->config_tscr(osi_core, osi_core->ptp_config.ptp_filter); @@ -702,12 +706,37 @@ nve32_t osi_ptp_configuration(struct osi_core_priv_data *const osi_core, ret = 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 = ops_p->config_ptp_rxq(osi_core, + osi_core->ptp_config.ptp_rx_queue, + OSI_ENABLE); + } } } return ret; } +int osi_rxq_route(struct osi_core_priv_data *const osi_core, + const struct osi_rxq_route *rxq_route) +{ + if (validate_args(osi_core) < 0) { + return -1; + } + + 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 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) { if (validate_args(osi_core) < 0) { From 22122943aba9f9751bf087d2f0484e3d8d50e833 Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Thu, 2 Apr 2020 11:11:45 +0530 Subject: [PATCH 189/458] nvethernetrm: mgbe: Implement PTP RX Queue support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement config_ptp_rxq call back to add PTP RX Packets routing support. Bug 200596985 Change-Id: I7a7649ab903c546d40a2c208fad381da8bfbc990 Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> --- osi/core/mgbe_core.c | 84 ++++++++++++++++++++++++++++++++++++++++++++ osi/core/mgbe_core.h | 6 ++++ 2 files changed, 90 insertions(+) diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 2355134..587d31d 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -1321,6 +1321,89 @@ static inline int mgbe_update_vlan_id(struct osi_core_priv_data *const osi_core, 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_readl(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_writel(value, base + MGBE_MAC_RQC1R); + + return 0; +} + /** * @brief mgbe_flush_mtl_tx_queue - Flush MTL Tx queue * @@ -3072,6 +3155,7 @@ void mgbe_init_core_ops(struct core_ops *ops) ops->adjust_mactime = OSI_NULL, ops->config_tscr = OSI_NULL; ops->config_ssir = OSI_NULL; + 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; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index f126eba..2ff16ec 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -275,6 +275,12 @@ #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_MCBCQ1 OSI_BIT(8) #define MGBE_IMR_RGSMIIIE OSI_BIT(0) From b8318ac6b6e5da400a7bd4d34d5e9cfce26e34be Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Wed, 17 Mar 2021 14:55:01 +0530 Subject: [PATCH 190/458] osi: mgbe: support for get hw features Bug 200565647 Change-Id: I3599f3606254bf70a8b4d48da0497f0c70c89ead Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> --- osi/core/mgbe_core.c | 140 ++++++++++++++++++++++++++++++ osi/core/mgbe_core.h | 199 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 339 insertions(+) diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 587d31d..56b321b 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -3111,6 +3111,145 @@ static void mgbe_configure_eee(struct osi_core_priv_data *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; + + mac_hfr0 = osi_readl(base + MGBE_MAC_HFR0); + mac_hfr1 = osi_readl(base + MGBE_MAC_HFR1); + mac_hfr2 = osi_readl(base + MGBE_MAC_HFR2); + mac_hfr3 = osi_readl(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); + hw_feat->max_frp_bytes = ((mac_hfr3 >> MGBE_MAC_HFR3_FRPPB_SHIFT) & + MGBE_MAC_HFR3_FRPPB_MASK); + hw_feat->max_frp_entries = ((mac_hfr3 >> MGBE_MAC_HFR3_FRPES_SHIFT) & + MGBE_MAC_HFR3_FRPES_MASK); + 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_init_core_ops - Initialize MGBE MAC core operations */ @@ -3163,4 +3302,5 @@ void mgbe_init_core_ops(struct core_ops *ops) 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; }; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 2ff16ec..db7b74a 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -527,4 +527,203 @@ #define MGBE_MAX_BAK_IDX ((MGBE_MAC_VLAN_BAK_IDX(0) + \ MGBE_MAX_VLAN_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 +/** @} */ #endif /* MGBE_CORE_H_ */ From 3be293d6129bc4754125ccbf9da47adc2676a704 Mon Sep 17 00:00:00 2001 From: vbhadram <vbhadram@nvidia.com> Date: Mon, 16 Dec 2019 20:02:06 +0530 Subject: [PATCH 191/458] nvethernetrm: mgbe: add support for RSS This change programs 40byte Hash key and indirection table (Hash table) (has DMA channel numbers) in MAC Once packet received by MAC - 4-tuples will be extracted from the packet and given to RSS hash engine. Hash function will generate hash value by using 40byte key. From hash value LSB bits used as index to RSS lookup table to find out DMA channel number. If there is a match - packet is routed to corresponding DMA channel. If there is no match - packet will be dropped and error will be returned in receive desc. Bug 200565647 Change-Id: Iffbb5a452f03278b3ba0bc061f09b43c7c994289 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2263398 Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> --- include/osi_core.h | 38 +++++++++++ include/osi_dma.h | 20 +++++- include/osi_dma_txrx.h | 1 - osi/core/core_local.h | 2 + osi/core/mgbe_core.c | 143 ++++++++++++++++++++++++++++++++++++++-- osi/core/mgbe_core.h | 13 +++- osi/core/osi_core.c | 9 +++ osi/dma/dma_local.h | 3 + osi/dma/eqos_desc.c | 17 +++++ osi/dma/hw_desc.h | 6 ++ osi/dma/mgbe_desc.c | 37 +++++++++++ osi/dma/osi_dma_local.h | 3 + osi/dma/osi_dma_txrx.c | 3 + 13 files changed, 287 insertions(+), 8 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index e0117bc..773dc50 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -181,6 +181,16 @@ typedef my_lint_64 nvel64_t; #define OSI_VLAN_ACTION_ADD OSI_BIT(31) #define OSI_VLAN_ACTION_DEL 0x0U +/** + * @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 +/** @} */ + struct osi_core_priv_data; /** @@ -650,6 +660,19 @@ struct osi_ptp_config { 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 Max num of MAC core registers to backup. It should be max of or >= * (EQOS_MAX_BAK_IDX=380, coreX,...etc) backup registers. @@ -753,6 +776,8 @@ struct osi_core_priv_data { unsigned short vid[VLAN_NUM_VID]; /** Count of number of VLAN filters in vid array */ unsigned short vlan_filter_cnt; + /** RSS core structure */ + struct osi_core_rss rss; }; /** @@ -2191,4 +2216,17 @@ nve32_t osi_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, nve32_t osi_config_mac_loopback(struct osi_core_priv_data *const osi_core, const nveu32_t lb_mode); #endif /* !OSI_STRIPPED_LIB */ + +/** + * @brief osi_config_rss - Configuration of RSS. + * + * @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. + */ +nve32_t osi_config_rss(struct osi_core_priv_data *const osi_core); #endif /* INCLUDED_OSI_CORE_H */ diff --git a/include/osi_dma.h b/include/osi_dma.h index 00aa3ec..8c2f947 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -94,13 +94,14 @@ #define OSI_PKT_CX_TSO OSI_BIT(2) /** PTP packet */ #define OSI_PKT_CX_PTP OSI_BIT(3) +/** Rx packet has RSS hash */ +#define OSI_PKT_CX_RSS OSI_BIT(4) /** 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) - /** @} */ /** @@ -182,6 +183,19 @@ /** @} */ + +/** + * @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. * @@ -270,6 +284,10 @@ struct osi_rx_pkt_cx { 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; }; diff --git a/include/osi_dma_txrx.h b/include/osi_dma_txrx.h index cef6c89..f142d48 100644 --- a/include/osi_dma_txrx.h +++ b/include/osi_dma_txrx.h @@ -53,5 +53,4 @@ #define DECR_RX_DESC_INDEX(idx, i) ((idx) = ((idx) - (i)) & (RX_DESC_CNT - 1U)) #endif /* !OSI_STRIPPED_LIB */ /** @} */ - #endif /* INCLUDED_OSI_DMA_TXRX_H */ diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 71ffc93..4bd50c7 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -201,6 +201,8 @@ struct core_ops { /** 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); }; diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 56b321b..a0dcf41 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -1779,6 +1779,126 @@ static nve32_t mgbe_configure_mtl_queue(nveu32_t 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_writel(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_writel(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_readl(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_readl(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_writel(value, addr + MGBE_MAC_RSS_CTRL); + + return 0; +} + /** * @brief mgbe_config_flow_control - Configure MAC flow control settings * @@ -1857,8 +1977,11 @@ static int mgbe_config_flow_control(struct osi_core_priv_data *const osi_core, * @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 void mgbe_configure_mac(struct osi_core_priv_data *osi_core) +static int mgbe_configure_mac(struct osi_core_priv_data *osi_core) { nveu32_t value; @@ -1968,6 +2091,9 @@ static void mgbe_configure_mac(struct osi_core_priv_data *osi_core) } } /* TODO: USP (user Priority) to RxQ Mapping */ + + /* RSS cofiguration */ + return mgbe_config_rss(osi_core); } /** @@ -2125,19 +2251,22 @@ static nve32_t mgbe_core_init(struct osi_core_priv_data *osi_core, value = osi_readl((nveu8_t *)osi_core->base + MGBE_MTL_RXQ_DMA_MAP0); value |= MGBE_RXQ_TO_DMA_CHAN_MAP0; - osi_writel(value, (nveu8_t *)osi_core->base + + value |= MGBE_RXQ_TO_DMA_MAP_DDMACH; + osi_writel(value, (unsigned char *)osi_core->base + MGBE_MTL_RXQ_DMA_MAP0); value = osi_readl((nveu8_t *)osi_core->base + MGBE_MTL_RXQ_DMA_MAP1); value |= MGBE_RXQ_TO_DMA_CHAN_MAP1; - osi_writel(value, (nveu8_t *)osi_core->base + + value |= MGBE_RXQ_TO_DMA_MAP_DDMACH; + osi_writel(value, (unsigned char *)osi_core->base + MGBE_MTL_RXQ_DMA_MAP1); value = osi_readl((nveu8_t *)osi_core->base + MGBE_MTL_RXQ_DMA_MAP2); value |= MGBE_RXQ_TO_DMA_CHAN_MAP2; - osi_writel(value, (nveu8_t *)osi_core->base + + value |= MGBE_RXQ_TO_DMA_MAP_DDMACH; + osi_writel(value, (unsigned char *)osi_core->base + MGBE_MTL_RXQ_DMA_MAP2); /* TODO: DCS enable */ @@ -2161,7 +2290,10 @@ static nve32_t mgbe_core_init(struct osi_core_priv_data *osi_core, } /* configure MGBE MAC HW */ - mgbe_configure_mac(osi_core); + ret = mgbe_configure_mac(osi_core); + if (ret < 0) { + return ret; + } /* configure MGBE DMA */ mgbe_configure_dma(osi_core->base); @@ -3303,4 +3435,5 @@ void mgbe_init_core_ops(struct core_ops *ops) 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; }; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index db7b74a..3635d24 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -97,6 +97,9 @@ #define MGBE_MAC_ARPPA 0x0c10 #define MGBE_MAC_L3L4_ADDR_CTR 0x0C00 #define MGBE_MAC_L3L4_DATA 0x0C04 +#define MGBE_MAC_RSS_CTRL 0x0C80 +#define MGBE_MAC_RSS_ADDR 0x0C88 +#define MGBE_MAC_RSS_DATA 0x0C8C /** @} */ /** @@ -344,7 +347,14 @@ #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) /* DMA SBUS */ #define MGBE_DMA_SBUS_BLEN8 OSI_BIT(2) #define MGBE_DMA_SBUS_BLEN16 OSI_BIT(3) @@ -362,6 +372,7 @@ #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 diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 910f1cb..8216b95 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -982,6 +982,15 @@ nve32_t osi_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, return 0; } +int osi_config_rss(struct osi_core_priv_data *const osi_core) +{ + if (validate_args(osi_core) < 0) { + return -1; + } + + return ops_p->config_rss(osi_core); +} + nve32_t osi_config_mac_loopback(struct osi_core_priv_data *const osi_core, const nveu32_t lb_mode) { diff --git a/osi/dma/dma_local.h b/osi/dma/dma_local.h index 996b5ca..c07e0e1 100644 --- a/osi/dma/dma_local.h +++ b/osi/dma/dma_local.h @@ -98,6 +98,9 @@ struct desc_ops { /** 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); }; /** diff --git a/osi/dma/eqos_desc.c b/osi/dma/eqos_desc.c index 99a4d8a..42fc363 100644 --- a/osi/dma/eqos_desc.c +++ b/osi/dma/eqos_desc.c @@ -160,9 +160,26 @@ static void eqos_get_rx_csum(struct osi_rx_desc *rx_desc, } } +/** + * @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(struct osi_rx_desc *rx_desc, + struct osi_rx_pkt_cx *rx_pkt_cx) +{ +} + + 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; } diff --git a/osi/dma/hw_desc.h b/osi/dma/hw_desc.h index 164637e..239a2cc 100644 --- a/osi/dma/hw_desc.h +++ b/osi/dma/hw_desc.h @@ -49,6 +49,12 @@ #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 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 RDES0_OVT 0x0000FFFFU #define RDES1_TSA OSI_BIT(14) #define RDES1_TD OSI_BIT(15) diff --git a/osi/dma/mgbe_desc.c b/osi/dma/mgbe_desc.c index 9d7786f..a94008c 100644 --- a/osi/dma/mgbe_desc.c +++ b/osi/dma/mgbe_desc.c @@ -96,9 +96,46 @@ static void mgbe_get_rx_csum(struct osi_rx_desc *rx_desc, } } +/** + * @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; +} + 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; } diff --git a/osi/dma/osi_dma_local.h b/osi/dma/osi_dma_local.h index c94cef0..52c6221 100644 --- a/osi/dma/osi_dma_local.h +++ b/osi/dma/osi_dma_local.h @@ -41,6 +41,9 @@ struct desc_ops { /** 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); }; /** diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 6eb66dc..a911fd8 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -334,6 +334,9 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, /* Get Rx VLAN from descriptor */ d_ops.get_rx_vlan(rx_desc, rx_pkt_cx); + /* get_rx_hash for RSS */ + d_ops.get_rx_hash(rx_desc, rx_pkt_cx); + context_desc = rx_ring->rx_desc + rx_ring->cur_rx_idx; /* Get rx time stamp */ ret = get_rx_hwstamp(osi_dma, rx_desc, context_desc, From 98dac215f411294077e2e79e89fc801a2e5c80bf Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Tue, 7 Jan 2020 20:48:08 +0530 Subject: [PATCH 192/458] nvethernetrm: mgbe: add PTP support Change takes care of - o Enable PTP for MGBE o Added flags for One step/two step and also for PTP master/slave o Getting timestamp from MAC registers for MGBE. Bug 200565914 Change-Id: I17346451f2619f0526a737a4a6bffdf130af4fc0 Signed-off-by: rakesh goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2314201 Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> --- include/osi_common.h | 9 +- include/osi_core.h | 8 +- include/osi_dma.h | 30 ++- osi/common/mgbe_common.c | 72 +++++++ osi/common/mgbe_common.h | 38 ++++ osi/common/osi_common.c | 2 + osi/core/core_local.h | 3 +- osi/core/eqos_core.c | 117 +++++------ osi/core/ivc_core.c | 4 +- osi/core/mgbe_core.c | 421 ++++++++++++++++++++++++++++++++++++++- osi/core/mgbe_core.h | 10 + osi/core/osi_core.c | 2 +- osi/dma/dma_local.h | 5 + osi/dma/eqos_desc.c | 65 ++++++ osi/dma/hw_desc.h | 11 +- osi/dma/mgbe_desc.c | 63 ++++++ osi/dma/mgbe_dma.h | 33 ++- osi/dma/osi_dma_local.h | 4 + osi/dma/osi_dma_txrx.c | 327 ++++++++++++++++++------------ 19 files changed, 1017 insertions(+), 207 deletions(-) create mode 100644 osi/common/mgbe_common.c create mode 100644 osi/common/mgbe_common.h diff --git a/include/osi_common.h b/include/osi_common.h index 9061f20..42934b1 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -130,6 +130,8 @@ #define OSI_PTP_REQ_CLK_FREQ 250000000U #define OSI_FLOW_CTRL_DISABLE 0U +#define OSI_POLL_COUNT 1000U + #define OSI_ADDRESS_32BIT 0 #define OSI_ADDRESS_40BIT 1 #define OSI_ADDRESS_48BIT 2 @@ -143,7 +145,6 @@ #endif /** @} */ - /** * @addtogroup Helper Helper MACROS * @@ -154,11 +155,15 @@ /* 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 #ifndef OSI_STRIPPED_LIB -#define OSI_LOG_WARN 2U #define OSI_LOG_ARG_OPNOTSUPP 3U #endif /* !OSI_STRIPPED_LIB */ /* Default maximum Giant Packet Size Limit is 16K */ diff --git a/include/osi_core.h b/include/osi_core.h index 773dc50..f586f7e 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -76,6 +76,7 @@ typedef my_lint_64 nvel64_t; #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) #ifndef OSI_STRIPPED_LIB #define OSI_MAC_TCR_SNAPTYPSEL_3 (OSI_BIT(16) | OSI_BIT(17)) @@ -115,11 +116,6 @@ typedef my_lint_64 nvel64_t; #define OSI_IPV6_MATCH 1U #define OSI_IPV4_MATCH 0U - -#define OSI_LOG_INFO 1U -#define OSI_LOG_ARG_HW_FAIL 4U -#define OSI_LOG_ARG_OUTOFBOUND 1U - /* L2 filter operations supported by OSI layer. These operation modes shall be * set by OSD driver as input to update registers accordingly. */ @@ -180,6 +176,8 @@ typedef my_lint_64 nvel64_t; #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 /** * @addtogroup RSS related information diff --git a/include/osi_dma.h b/include/osi_dma.h index 8c2f947..d5af817 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -26,6 +26,19 @@ #include <osi_common.h> #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 * @@ -82,8 +95,8 @@ * 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 tx payload length to be updated + * whether the HW should timestamp transmit/arrival of a packet respectively + * whether a paged buffer. * @{ */ /** VLAN packet */ @@ -94,8 +107,10 @@ #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(4) +#define OSI_PKT_CX_RSS OSI_BIT(5) /** Valid packet */ #define OSI_PKT_CX_VALID OSI_BIT(10) /** Update Packet Length in Tx Desc3 */ @@ -324,6 +339,11 @@ struct osi_tx_swcx { /** 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; }; /** @@ -519,6 +539,10 @@ struct osi_dma_priv_data { nveu64_t resv_buf_phy_addr; /** Tegra Pre-si platform info */ nveu32_t pre_si; + /** PTP flags + * bit 0 PTP mode master(1) slave(0) + * bit 1 PTP sync method twostep(1) onestep(0) */ + unsigned int ptp_flag; }; diff --git a/osi/common/mgbe_common.c b/osi/common/mgbe_common.c new file mode 100644 index 0000000..315fdbf --- /dev/null +++ b/osi/common/mgbe_common.c @@ -0,0 +1,72 @@ +/* + * 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 "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; +} diff --git a/osi/common/mgbe_common.h b/osi/common/mgbe_common.h new file mode 100644 index 0000000..1baff90 --- /dev/null +++ b/osi/common/mgbe_common.h @@ -0,0 +1,38 @@ +/* + * 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_MGBE_COMMON_H +#define INCLUDED_MGBE_COMMON_H + +/** + * @addtogroup MGBE-MAC MGBE MAC PTP HW feature registers + * + * @{ + */ +#define MGBE_MAC_STSR 0x0D08 +#define MGBE_MAC_STNSR 0x0D0C +#define MGBE_MAC_STNSR_TSSS_MASK 0x7FFFFFFFU +/** @} */ + +nveul64_t mgbe_get_systime_from_mac(void *addr); + +#endif /* INCLUDED_MGBE_COMMON_H */ diff --git a/osi/common/osi_common.c b/osi/common/osi_common.c index d06dc7b..9e2b26e 100644 --- a/osi/common/osi_common.c +++ b/osi/common/osi_common.c @@ -32,6 +32,8 @@ void common_get_systime_from_mac(void *addr, nveu32_t mac, nveu32_t *sec, if (mac == OSI_MAC_HW_EQOS) { ns = eqos_get_systime_from_mac(addr); + } else if (mac == OSI_MAC_HW_MGBE) { + ns = eqos_get_systime_from_mac(addr); } else { /* Non EQOS HW is supported yet */ return; diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 4bd50c7..d763adb 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -120,7 +120,8 @@ struct core_ops { 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); + 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, diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 2091815..d97e0cc 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -2740,11 +2740,12 @@ static inline nve32_t eqos_poll_for_tsinit_complete( if ((*mac_tcr & EQOS_MAC_TCR_TSINIT) == 0U) { cond = COND_MET; } + count++; - osi_core->osd_ops.udelay(1000U); + osi_core->osd_ops.udelay(OSI_DELAY_1000US); } - return 0; + return -1; } /** @@ -2779,6 +2780,7 @@ static nve32_t eqos_set_systime_to_mac( 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; @@ -2852,11 +2854,12 @@ static inline nve32_t eqos_poll_for_addend_complete( if ((*mac_tcr & EQOS_MAC_TCR_TSADDREG) == 0U) { cond = COND_MET; } + count++; - osi_core->osd_ops.udelay(1000U); + osi_core->osd_ops.udelay(OSI_DELAY_1000US); } - return 0; + return -1; } /** @@ -2886,6 +2889,7 @@ static nve32_t eqos_config_addend(struct osi_core_priv_data *const osi_core, 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; @@ -2955,11 +2959,12 @@ static inline nve32_t eqos_poll_for_update_ts_complete( if ((*mac_tcr & EQOS_MAC_TCR_TSUPDT) == 0U) { cond = COND_MET; } + count++; - osi_core->osd_ops.udelay(1000U); + osi_core->osd_ops.udelay(OSI_DELAY_1000US); } - return 0; + return -1; } @@ -3082,58 +3087,54 @@ static void eqos_config_tscr(struct osi_core_priv_data *const osi_core, void *addr = osi_core->base; nveu32_t mac_tcr = 0U, i = 0U, temp = 0U; - if (ptp_filter == OSI_DISABLE) { + 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; + 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); - return; - } - - 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; - default: - /* To avoid MISRA violation */ - mac_tcr |= mac_tcr; - break; - } } eqos_core_safety_writel(osi_core, mac_tcr, @@ -3154,12 +3155,12 @@ static void eqos_config_tscr(struct osi_core_priv_data *const osi_core, * - Run time: Yes * - De-initialization: No */ -static void eqos_config_ssir(struct osi_core_priv_data *const osi_core) +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; - nveu32_t ptp_clock = osi_core->ptp_config.ptp_clock; mac_tcr = osi_readla(osi_core, (nveu8_t *)addr + EQOS_MAC_TCR); diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index 137e680..118d66d 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -815,9 +815,9 @@ static void ivc_config_tscr(struct osi_core_priv_data *const osi_core, * * @note MAC should be init and started. see osi_start_mac() */ -static void ivc_config_ssir(struct osi_core_priv_data *const osi_core) +static void ivc_config_ssir(struct osi_core_priv_data *const osi_core, + const unsigned int ptp_clock) { - nveu32_t ptp_clock = osi_core->ptp_config.ptp_clock; ivc_msg_common msg_common; nve32_t index = 0; diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index a0dcf41..fdbc0fd 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -369,7 +369,6 @@ err_dma_chan: return ret; } - /** * @brief mgbe_update_mac_addr_low_high_reg- Update L2 address in filter * register @@ -3382,6 +3381,416 @@ static int mgbe_get_hw_features(struct osi_core_priv_data *osi_core, 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_readl((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_writel(sec, (unsigned char *)addr + MGBE_MAC_STSUR); + + /* write nano seconds value to MAC_System_Time_Nanoseconds_Update + * register + */ + osi_writel(nsec, (unsigned char *)addr + MGBE_MAC_STNSUR); + + /* issue command to update the configured secs and nsecs values */ + mac_tcr |= MGBE_MAC_TCR_TSINIT; + osi_writel(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_readl((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_writel(addend, (unsigned char *)addr + MGBE_MAC_TAR); + + /* issue command to update the configured addend value */ + mac_tcr |= MGBE_MAC_TCR_TSADDREG; + osi_writel(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_readl((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 – <new_sec_value>) + */ + 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 - <new_nsec_value>) if + * MAC_TCR.TSCTRLSSR is set or + * (2^32 - <new_nsec_value> 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_writel(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_writel(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_writel(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) +{ + unsigned int mac_tcr = 0; + 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_writel(mac_tcr, (unsigned char *)addr + MGBE_MAC_TCR); +} + +/** + * @brief mgbe_config_ssir - Configure SSIR + * + * @param[in] addr: Base address indicating the start of + * memory mapped IO region of the MAC. + * it compiled earlier + * @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_readl((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) { + val = ((1U * OSI_NSEC_PER_SEC) / OSI_PTP_REQ_CLK_FREQ); + } 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_writel((unsigned int)val, + (unsigned char *)addr + MGBE_MAC_SSIR); + } +} + /** * @brief mgbe_init_core_ops - Initialize MGBE MAC core operations */ @@ -3421,11 +3830,11 @@ void mgbe_init_core_ops(struct core_ops *ops) ops->update_l4_port_no = mgbe_update_l4_port_no; ops->config_vlan_filtering = mgbe_config_vlan_filtering; ops->update_vlan_id = mgbe_update_vlan_id; - ops->set_systime_to_mac = OSI_NULL; - ops->config_addend = OSI_NULL; - ops->adjust_mactime = OSI_NULL, - ops->config_tscr = OSI_NULL; - ops->config_ssir = OSI_NULL; + 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; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 3635d24..4f8d074 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -377,6 +377,16 @@ #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_STNSUR_ADDSUB_SHIFT 31U +#define MGBE_MAC_SSIR_SSINC_SHIFT 16U +#define MGBE_MAC_STNSR_TSSS_MASK 0x7FFFFFFFU +#define MGBE_MAC_TCR_SNAPTYPSEL_SHIFT 16 #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 diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 8216b95..507e383 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -667,7 +667,7 @@ nve32_t osi_ptp_configuration(struct osi_core_priv_data *const osi_core, ops_p->config_tscr(osi_core, osi_core->ptp_config.ptp_filter); /* Program Sub Second Increment Register */ - ops_p->config_ssir(osi_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) diff --git a/osi/dma/dma_local.h b/osi/dma/dma_local.h index c07e0e1..3a0fca7 100644 --- a/osi/dma/dma_local.h +++ b/osi/dma/dma_local.h @@ -101,6 +101,11 @@ struct desc_ops { /** 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); }; /** diff --git a/osi/dma/eqos_desc.c b/osi/dma/eqos_desc.c index 42fc363..89bdee5 100644 --- a/osi/dma/eqos_desc.c +++ b/osi/dma/eqos_desc.c @@ -175,6 +175,70 @@ static void eqos_get_rx_hash(struct osi_rx_desc *rx_desc, { } +/** + * @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) { @@ -182,4 +246,5 @@ void eqos_init_desc_ops(struct desc_ops *d_ops) 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/hw_desc.h b/osi/dma/hw_desc.h index 239a2cc..45cf896 100644 --- a/osi/dma/hw_desc.h +++ b/osi/dma/hw_desc.h @@ -35,6 +35,7 @@ #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) @@ -50,14 +51,16 @@ #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 RDES0_OVT 0x0000FFFFU -#define RDES1_TSA OSI_BIT(14) -#define RDES1_TD OSI_BIT(15) #define RDES1_IPCE OSI_BIT(7) #define RDES1_IPCB OSI_BIT(6) @@ -96,6 +99,7 @@ #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)) @@ -106,6 +110,7 @@ #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) diff --git a/osi/dma/mgbe_desc.c b/osi/dma/mgbe_desc.c index a94008c..12f12ee 100644 --- a/osi/dma/mgbe_desc.c +++ b/osi/dma/mgbe_desc.c @@ -132,10 +132,73 @@ static void mgbe_get_rx_hash(struct osi_rx_desc *rx_desc, 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_dma.h b/osi/dma/mgbe_dma.h index 04e4e4c..480db86 100644 --- a/osi/dma/mgbe_dma.h +++ b/osi/dma/mgbe_dma.h @@ -23,6 +23,17 @@ #ifndef INCLUDED_MGBE_DMA_H #define INCLUDED_MGBE_DMA_H +/** + * @@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 * @@ -95,4 +106,24 @@ #define MGBE_VIRT_INTR_CHX_CNTRL_TX OSI_BIT(0) #define MGBE_VIRT_INTR_CHX_CNTRL_RX OSI_BIT(1) /** @} */ -#endif /* INCLUDED_MGBE_DMA_H */ + +/** + * @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_local.h b/osi/dma/osi_dma_local.h index 52c6221..962df94 100644 --- a/osi/dma/osi_dma_local.h +++ b/osi/dma/osi_dma_local.h @@ -44,6 +44,10 @@ struct desc_ops { /** 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_rx_desc *rx_desc, + struct osi_rx_desc *context_desc, + struct osi_rx_pkt_cx *rx_pkt_cx); }; /** diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index a911fd8..5abb19c 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -25,119 +25,10 @@ #include "../osi/common/type.h" #include "hw_desc.h" #include "../osi/common/common.h" +#include "mgbe_dma.h" static struct desc_ops d_ops; -/** - * @brief get_rx_tstamp_status - Get Tx Time stamp status - * - * @note - * Algorithm: - * - Check if the received descriptor is a context descriptor. - * - If yes, check whether the time stamp is valid or not. - * - * @param[in] context_desc: Rx context descriptor - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval -1 if TimeStamp is not valid - * @retval 0 if TimeStamp is valid. - */ -static inline nve32_t get_rx_tstamp_status(struct osi_rx_desc *context_desc) -{ - if (((context_desc->rdes3 & RDES3_OWN) != RDES3_OWN) && - ((context_desc->rdes3 & RDES3_CTXT) == RDES3_CTXT)) { - if (((context_desc->rdes0 == OSI_INVALID_VALUE) && - (context_desc->rdes1 == OSI_INVALID_VALUE))) { - /* Invalid time stamp */ - return -1; - } - /* tstamp can be read */ - return 0; - } - /* Busy */ - return -2; -} - -/** - * @brief get_rx_hwstamp - Get Rx HW Time stamp - * - * @note - * Algorithm: - * - Check for TS availability. - * - call get_tx_tstamp_status if TS is valid or not. - * - 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] osi_dma: OSI private data structure. - * @param[in] rx_desc: Rx descriptor - * @param[in] context_desc: Rx context descriptor - * @param[in, out] rx_pkt_cx: Rx packet context - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval -1 if TimeStamp is not available - * @retval 0 if TimeStamp is available. - */ -static nve32_t 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) -{ - nve32_t retry, ret = -1; - - /* 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) != RDES1_TD)) { - for (retry = 0; retry < 10; retry++) { - ret = get_rx_tstamp_status(context_desc); - if (ret == 0) { - /* Update rx pkt context flags to indicate PTP */ - rx_pkt_cx->flags |= OSI_PKT_CX_PTP; - /* Time Stamp can be read */ - break; - } else if (ret != -2) { - /* Failed to get Rx timestamp */ - return ret; - } else { - /* Do nothing here */ - } - /* TS not available yet, so retrying */ - osi_dma->osd_ops.udelay(1U); - } - if (ret != 0) { - /* Timed out waiting for Rx timestamp */ - return ret; - } - - if (OSI_NSEC_PER_SEC > (OSI_ULLONG_MAX / context_desc->rdes1)) { - /* Will not hit this case */ - } else if ((OSI_ULLONG_MAX - - (context_desc->rdes1 * OSI_NSEC_PER_SEC)) < - context_desc->rdes0) { - /* Will not hit this case */ - } else { - 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 ret; -} - /** * @brief get_rx_err_stats - Detect Errors from Rx Descriptor * @@ -339,8 +230,8 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, context_desc = rx_ring->rx_desc + rx_ring->cur_rx_idx; /* Get rx time stamp */ - ret = get_rx_hwstamp(osi_dma, rx_desc, context_desc, - rx_pkt_cx); + ret =d_ops.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; @@ -616,8 +507,121 @@ static inline nve32_t validate_tx_completions_arg( return 0; } -nve32_t osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, - nveu32_t chan, nve32_t budget) +/** + * @brief poll_for_ts_update - Poll for TXTSC bit set for timestamp capture + * + * Algorithm: This routine will be invoked by get_mac_tx_timestamp to poll + * on TXTSC bit to get set or timedout. + * + * @param[in] addr: Base address + * @param[in] chan: Current counter value + * + * @retval -1 on failure + * @retval 0 on success + */ +static inline int poll_for_ts_update(struct osi_dma_priv_data *osi_dma, + unsigned int *count) +{ + unsigned int retry = OSI_POLL_COUNT; + unsigned int val = 0U; + + while (*count < retry) { + /* Read and Check TXTSC in MAC_Timestamp_Control register */ + val = osi_readl((unsigned char *)osi_dma->base + + MGBE_MAC_TSS); + if ((val & MGBE_MAC_TSS_TXTSC) == MGBE_MAC_TSS_TXTSC) { + return 0; + } + (*count)++; + osi_dma->osd_ops.udelay(OSI_DELAY_1US); + } + + return -1; +} + +/** + * @brief get_mac_tx_timestamp - get TX timestamp from timestamp capture + * registers + * + * Algorithm: This routine will be invoked on TX_DONE interrupt and if hw + * timestamp capture enabled for that descriptor. SW will check for Packet + * id maching with dma channel number as for same DMA all tx are FIFO. If match + * update hwtimestamp into local variables. + * + * @param[in] osi: OSI private data structure. + * @param[in] tx_desc: Pointer to tranmit descriptor. + * @param[out] txdone_pkt_cx: Pointer to txdone packet descriptor to be filled + * @param[in] chan: Rx channel number. + * + */ +static void get_mac_tx_timestamp(struct osi_dma_priv_data *osi_dma, + struct osi_tx_desc *tx_desc, + struct osi_txdone_pkt_cx *txdone_pkt_cx, + unsigned int chan) +{ + unsigned char *addr = (unsigned char *)osi_dma->base; + int ret = -1; + int found = 1; + unsigned int count = 0; + unsigned long long var = 0; + + ret = poll_for_ts_update(osi_dma, &count); + if (ret < 0) { + OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + "timestamp done failed\n", 0ULL); + found = 0; + } + + /* check if pkt id is also correct for pkt. current implemtation + * use dma channel index as pktid, we will use pktid from index 0 to + * max DMA channels -1 */ + while (found == 1) { + if (((osi_readl(addr + MGBE_MAC_TS_PID) & + MGBE_MAC_TS_PID_MASK) == chan)) { + txdone_pkt_cx->flags |= OSI_TXDONE_CX_TS; + txdone_pkt_cx->ns = osi_readl(addr + MGBE_MAC_TS_NSEC); + txdone_pkt_cx->ns &= MGBE_MAC_TS_NSEC_MASK; + var = osi_readl(addr + MGBE_MAC_TS_SEC); + if (OSI_NSEC_PER_SEC > (OSI_ULLONG_MAX / var)) { + /* Will not hit this case */ + } else if ((OSI_ULLONG_MAX - (var * OSI_NSEC_PER_SEC)) < + txdone_pkt_cx->ns) { + /* Will not hit this case */ + } else { + txdone_pkt_cx->ns += var * OSI_NSEC_PER_SEC; + } + + found = 0; + } else { + OSI_DMA_INFO(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + "packet ID mismatch \n", 0ULL); + ret = poll_for_ts_update(osi_dma, &count); + if (ret < 0) { + found = 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; @@ -690,9 +694,19 @@ nve32_t osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, } else { /* Do nothing here */ } + } else if (((tx_swcx->flags & OSI_PKT_CX_PTP) == + OSI_PKT_CX_PTP) && + // if not master in onestep mode + (is_ptp_twostep_or_slave_mode(osi_dma->ptp_flag) == + OSI_ENABLE) && + ((tx_desc->tdes3 & TDES3_CTXT) == 0U)) { + get_mac_tx_timestamp(osi_dma, tx_desc, txdone_pkt_cx, chan); + } else { + /* Do nothing here */ } - if (tx_swcx->is_paged_buf == 1U) { + if ((tx_swcx->flags & OSI_PKT_CX_PAGED_BUF) == + OSI_PKT_CX_PAGED_BUF) { txdone_pkt_cx->flags |= OSI_TXDONE_CX_PAGED_BUF; } @@ -718,7 +732,7 @@ nve32_t osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, tx_swcx->buf_virt_addr = OSI_NULL; tx_swcx->buf_phy_addr = 0; - tx_swcx->is_paged_buf = 0; + tx_swcx->flags = 0; INCR_TX_DESC_INDEX(entry, 1U); /* Don't wait to update tx_ring->clean-idx. It will @@ -743,6 +757,8 @@ nve32_t osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, * * @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] sync_mode: PTP sync mode to indetify. + * @param[in] mac: HW MAC ver * * @note * API Group: @@ -753,40 +769,85 @@ nve32_t osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, * @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_desc *tx_desc) + 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)) { - /* Set context type */ - tx_desc->tdes3 |= TDES3_CTXT; + ((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; /* Remove any overflow bits. VT field is 16bit field */ tx_pkt_cx->vtag_id &= TDES3_VT_MASK; /* Fill VLAN Tag ID */ tx_desc->tdes3 |= tx_pkt_cx->vtag_id; /* Set VLAN TAG Valid */ tx_desc->tdes3 |= TDES3_VLTV; + ret = 1; } if ((tx_pkt_cx->flags & OSI_PKT_CX_TSO) == OSI_PKT_CX_TSO) { + /* Set context type */ + tx_desc->tdes3 |= TDES3_CTXT; /* Remove any overflow bits. MSS is 13bit field */ tx_pkt_cx->mss &= TDES2_MSS_MASK; /* Fill MSS */ tx_desc->tdes2 |= tx_pkt_cx->mss; /* Set MSS valid */ tx_desc->tdes3 |= TDES3_TCMSSV; + ret = 1; } - 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. @@ -812,7 +873,8 @@ static inline nve32_t need_cntx_desc(struct osi_tx_pkt_cx *tx_pkt_cx, 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) + struct osi_tx_swcx *tx_swcx, + unsigned int ptp_flag) { nveu64_t tmp; @@ -850,6 +912,12 @@ static inline void fill_first_desc(struct osi_tx_ring *tx_ring, /* 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 */ @@ -954,19 +1022,28 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, 1UL); } - cntx_desc_consumed = need_cntx_desc(tx_pkt_cx, tx_desc); + cntx_desc_consumed = need_cntx_desc(tx_pkt_cx, 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; + /* Packet id */ + tx_desc->tdes0 = chan; + } INCR_TX_DESC_INDEX(entry, 1U); /* 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); + fill_first_desc(tx_ring, tx_pkt_cx, tx_desc, tx_swcx, osi_dma->ptp_flag); INCR_TX_DESC_INDEX(entry, 1U); @@ -1262,7 +1339,7 @@ static nve32_t tx_dma_desc_init(struct osi_dma_priv_data *osi_dma, tx_swcx->len = 0; tx_swcx->buf_virt_addr = OSI_NULL; tx_swcx->buf_phy_addr = 0; - tx_swcx->is_paged_buf = 0; + tx_swcx->flags = 0; } tx_ring->cur_tx_idx = 0; From 8f7983edb14f0829021f923b0b88fdb2db536d57 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Thu, 23 Jan 2020 09:57:42 +0530 Subject: [PATCH 193/458] nvethernetrm: update SSINC & ptp_ref_clk Configure SSINC and ptp_ref_clk based on ethernet IP Bug 200565914 Change-Id: I0a29d4506f56c7e4bdb36cc2cee9276f849b4a26 Signed-off-by: rakesh goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2320590 Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> --- include/osi_core.h | 10 ++++++++++ osi/core/eqos_core.c | 2 +- osi/core/mgbe_core.c | 13 ++++++++----- osi/core/osi_core.c | 18 ++++++++++++++++-- 4 files changed, 35 insertions(+), 8 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index f586f7e..7439f1e 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -189,6 +189,16 @@ typedef my_lint_64 nvel64_t; #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 +/** @} */ + struct osi_core_priv_data; /** diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index d97e0cc..26174e4 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -3146,6 +3146,7 @@ static void eqos_config_tscr(struct osi_core_priv_data *const osi_core, * @brief eqos_config_ssir - Configure SSIR * * @param[in] osi_core: OSI core private data structure. + * @param[in] ptp_clock: PTP required clock frequency * * @pre MAC should be initialized and started. see osi_start_mac() * @@ -3164,7 +3165,6 @@ static void eqos_config_ssir(struct osi_core_priv_data *const osi_core, 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; diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index fdbc0fd..228b903 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -3748,9 +3748,7 @@ static void mgbe_config_tscr(struct osi_core_priv_data *osi_core, /** * @brief mgbe_config_ssir - Configure SSIR * - * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. - * it compiled earlier + * @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() @@ -3769,9 +3767,13 @@ static void mgbe_config_ssir(struct osi_core_priv_data *const osi_core, * 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) { - val = ((1U * OSI_NSEC_PER_SEC) / OSI_PTP_REQ_CLK_FREQ); + 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); } @@ -3784,6 +3786,7 @@ static void mgbe_config_ssir(struct osi_core_priv_data *const osi_core, } val |= (val << MGBE_MAC_SSIR_SSINC_SHIFT); + /* update Sub-second Increment Value */ if (val < UINT_MAX) { osi_writel((unsigned int)val, diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 507e383..3804649 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -666,6 +666,19 @@ nve32_t osi_ptp_configuration(struct osi_core_priv_data *const osi_core, /* Program MAC_Timestamp_Control Register */ 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 */ ops_p->config_ssir(osi_core, osi_core->ptp_config.ptp_clock); @@ -675,8 +688,9 @@ nve32_t osi_ptp_configuration(struct osi_core_priv_data *const osi_core, * 2^32 * 1000 == (1000 << 32) * so addend = (2^32 * 1000)/(ptp_ref_clk_rate in MHZ * SSINC); */ - - if (osi_core->mac_ver <= OSI_EQOS_MAC_4_10) { + 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; From e18eedbdebba0433dec45b345b0bba49e006a7bd Mon Sep 17 00:00:00 2001 From: rakesh goyal <rgoyal@nvidia.com> Date: Sat, 28 Mar 2020 12:58:56 +0530 Subject: [PATCH 194/458] nvethernetrm: eqos: TSN support for EQOS IP 1. Adds basic OSI API's for EST/FPE 2. EST/FPE support for EQOS 3. MMC counters for FPE 4. EST errors and state counter Bug 200561100 Change-Id: Iee3e6caac5d16e1620c25420d72700f9cdd00465 Signed-off-by: rakesh goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2319820 Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> --- include/mmc.h | 21 ++ include/osi_common.h | 12 +- include/osi_core.h | 141 ++++++++- osi/core/core_local.h | 6 + osi/core/eqos_core.c | 643 +++++++++++++++++++++++++++++++++++++++++- osi/core/eqos_core.h | 109 ++++++- osi/core/eqos_mmc.c | 18 ++ osi/core/eqos_mmc.h | 8 +- osi/core/osi_core.c | 40 +++ 9 files changed, 977 insertions(+), 21 deletions(-) diff --git a/include/mmc.h b/include/mmc.h index 2f5e282..b9a88eb 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -527,6 +527,27 @@ struct osi_mmc_counters { * 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; }; /** diff --git a/include/osi_common.h b/include/osi_common.h index 42934b1..24747d1 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -129,6 +129,14 @@ #define OSI_PAUSE_FRAMES_ENABLE 0U #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_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 @@ -272,10 +280,6 @@ * @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 * diff --git a/include/osi_core.h b/include/osi_core.h index 7439f1e..11ce4a1 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -178,7 +178,7 @@ typedef my_lint_64 nvel64_t; #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 * @@ -619,6 +619,62 @@ struct osi_core_avb_algorithm { }; #endif /* !OSI_STRIPPED_LIB */ +/** + * @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 */ @@ -627,29 +683,29 @@ struct osi_ptp_config { * * 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 */ @@ -737,6 +793,10 @@ struct osi_core_priv_data { 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 */ @@ -786,6 +846,16 @@ struct osi_core_priv_data { unsigned short vlan_filter_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; }; /** @@ -2237,4 +2307,49 @@ nve32_t osi_config_mac_loopback(struct osi_core_priv_data *const osi_core, * @retval -1 on failure. */ nve32_t osi_config_rss(struct osi_core_priv_data *const osi_core); + +/** + * @brief osi_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: Configuration osi_est_config structure. + * + * @note MAC should be init and started. see osi_start_mac() + * + * @retval 0 on success + * @retval -1 on failure. + */ +int osi_hw_config_est(struct osi_core_priv_data *osi_core, + struct osi_est_config *est); + +/** + * @brief osi_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: Configuration osi_fpe_config structure. + * + * @note MAC should be init and started. see osi_start_mac() + * + * @retval 0 on success + * @retval -1 on failure. + */ +int osi_hw_config_fpe(struct osi_core_priv_data *osi_core, + struct osi_fpe_config *fpe); #endif /* INCLUDED_OSI_CORE_H */ diff --git a/osi/core/core_local.h b/osi/core/core_local.h index d763adb..6d4d019 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -204,6 +204,12 @@ struct core_ops { 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); }; diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 26174e4..e1972dd 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -21,6 +21,7 @@ */ #include "../osi/common/common.h" +#include <local_common.h> #include <osi_core.h> #include "eqos_core.h" #include "eqos_mmc.h" @@ -1399,6 +1400,135 @@ static void eqos_configure_dma(struct osi_core_priv_data *const osi_core) osi_writela(osi_core, value, (nveu8_t *)base + EQOS_DMA_BMR); } +/** + * @brief eqos_enable_mtl_interrupts - Enable MTL interrupts + * + * Algorithm: enable MTL interrupts for EST + * + * @param[in] addr: MAC base IOVA address. + * + * @note MAC should be init and started. see osi_start_mac() + */ +static inline void eqos_enable_mtl_interrupts(void *addr) +{ + unsigned int mtl_est_ir = OSI_DISABLE; + + mtl_est_ir = osi_readl((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_writel(mtl_est_ir, (unsigned char *)addr + EQOS_MTL_EST_ITRE); +} + +/** + * @brief eqos_enable_fpe_interrupts - Enable MTL interrupts + * + * Algorithm: enable FPE interrupts + * + * @param[in] addr: MAC base IOVA address. + * + * @note MAC should be init and started. see osi_start_mac() + */ +static inline void eqos_enable_fpe_interrupts(void *addr) +{ + unsigned int value = OSI_DISABLE; + + /* Read MAC IER Register and enable Frame Preemption Interrupt + * Enable */ + value = osi_readl((unsigned char *)addr + EQOS_MAC_IMR); + value |= EQOS_IMR_FPEIE; + osi_writel(value, (unsigned char *)addr + EQOS_MAC_IMR); +} + +/** + * @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) { + val = osi_readl((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 { + /* 6*1/(312 MHz) in ns*/ + temp = (6U * 3U); + } + temp = temp << EQOS_MTL_EST_CONTROL_PTOV_SHIFT; + val |= temp; + + /* We have a bug on CTOV for Qbv that synopsys is yet to + * fix[Case – 8001147927, Bug 200468714]. You can go ahead + * with 128*8ns for now. TODO */ + val &= ~EQOS_MTL_EST_CONTROL_CTOV; + temp = (128U * 8U); + 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; + osi_writel(val, (unsigned char *)osi_core->base + + EQOS_MTL_EST_CONTROL); + + eqos_enable_mtl_interrupts(osi_core->base); + } + + if (fpe_sel == OSI_ENABLE) { + val = osi_readl((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_writel(val, (unsigned char *)osi_core->base + + EQOS_MAC_RQC1R); + + eqos_enable_fpe_interrupts(osi_core->base); + } + + /* CBS setting for TC should be by user application/IOCTL as + * per requirement */ +} + /** * @brief eqos_core_init - EQOS MAC, MTL and common DMA Initialization * @@ -1509,12 +1639,69 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const 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; 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_readl((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_writel(val, (unsigned char *)osi_core->base + EQOS_MAC_FPE_CTS); +} + /** * @brief eqos_handle_mac_intrs - Handle MAC interrupts * @@ -1554,8 +1741,10 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, 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) { + if (((mac_isr & EQOS_MAC_ISR_RGSMIIS) != EQOS_MAC_ISR_RGSMIIS) && + ((mac_isr & EQOS_MAC_IMR_FPEIS) != EQOS_MAC_IMR_FPEIS)) { return; } @@ -1595,6 +1784,12 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, } 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_writel(mac_isr, (unsigned char *)osi_core->base + EQOS_MAC_ISR); } /** @@ -1652,6 +1847,111 @@ static inline void update_dma_sr_stats( } } +/** + * @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 = 0; + unsigned int sch_err = 0; + unsigned int frm_err = 0; + unsigned int temp = 0U; + unsigned int i = 0; + unsigned long stat_val = 0; + + val = osi_readl((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_readl(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_writel(sch_err, osi_core->base + EQOS_MTL_EST_SCH_ERR); + } + + 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_readl(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_writel(frm_err, osi_core->base + EQOS_MTL_EST_FRMS_ERR); + } + + 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_writel(val, osi_core->base + EQOS_MTL_EST_STATUS); +} + /** * @brief eqos_handle_common_intr - Handles common interrupt. * @@ -1677,6 +1977,7 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *const osi_core) nveu32_t i = 0; nveu32_t dma_sr = 0; nveu32_t dma_ier = 0; + unsigned int mtl_isr = 0; dma_isr = osi_readla(osi_core, (nveu8_t *)base + EQOS_DMA_ISR); if (dma_isr == 0U) { @@ -1719,6 +2020,15 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *const osi_core) } eqos_handle_mac_intrs(osi_core, dma_isr); + /* Handle MTL inerrupts */ + mtl_isr = osi_readl((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_writel(mtl_isr, (unsigned char *)base + + EQOS_MTL_INTR_STATUS); + } } /** @@ -3218,6 +3528,335 @@ static void eqos_core_deinit(struct osi_core_priv_data *const osi_core) 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_writel(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_writel(val, (unsigned char *)base + EQOS_MTL_EST_GCL_CONTROL); + + while (--retry > 0) { + osi_core->osd_ops.udelay(OSI_DELAY_1US); + val = osi_readl((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_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. + * + * @note MAC should be init and started. see osi_start_mac() + * + * @retval 0 on success + * @retval -1 on failure. + */ +static inline int eqos_gcl_validate(struct osi_core_priv_data *osi_core, + struct osi_est_config *est) +{ + unsigned int wid_val = 0x0U; + unsigned int dep = 0x0U; + unsigned int i; + + if (osi_core->hw_feature == OSI_NULL) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "HW feature is NULL\n", 0ULL); + return -1; + } + + if (osi_core->hw_feature->gcl_width == 0x1U) { + wid_val = OSI_MAX_24BITS; + } else if (osi_core->hw_feature->gcl_width == 0x2U) { + wid_val = OSI_MAX_28BITS; + } else if (osi_core->hw_feature->gcl_width == 0x3U) { + wid_val = OSI_MAX_32BITS; + } else { + /* Do Nothing */ + } + + if (osi_core->hw_feature->gcl_depth == 0x1U) { + dep = OSI_GCL_SIZE_64; + } else if (osi_core->hw_feature->gcl_depth == 0x2U) { + dep = OSI_GCL_SIZE_128; + } else if (osi_core->hw_feature->gcl_depth == 0x3U) { + dep = OSI_GCL_SIZE_256; + } else if (osi_core->hw_feature->gcl_depth == 0x4U) { + dep = OSI_GCL_SIZE_512; + } else if (osi_core->hw_feature->gcl_depth == 0x5U) { + dep = OSI_GCL_SIZE_1024; + } else { + /* Do Nothing */ + } + + if (est->llr > dep) { + return -1; + } + + for (i = 0U; i < est->llr; i++) { + if (est->gcl[i] <= wid_val) { + continue; + } + 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_readl((unsigned char *)base + EQOS_MTL_EST_CONTROL); + val &= ~EQOS_MTL_EST_EEST; + osi_writel(val, (unsigned char *)base + EQOS_MTL_EST_CONTROL); + + return 0; + } + + if (eqos_gcl_validate(osi_core, est) < 0) { + return -1; + } + + ret = eqos_hw_est_write(osi_core, EQOS_MTL_EST_CTR_LOW, est->ctr[0], + OSI_DISABLE); + if (ret < 0) { + 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) { + return ret; + } + + ret = eqos_hw_est_write(osi_core, EQOS_MTL_EST_TER, est->ter, OSI_DISABLE); + if (ret < 0) { + return ret; + } + + ret = eqos_hw_est_write(osi_core, EQOS_MTL_EST_LLR, est->llr, OSI_DISABLE); + if (ret < 0) { + 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) { + return ret; + } + } + + if (est->btr[0] == 0U && est->btr[1] == 0U) { + common_get_systime_from_mac(osi_core->base, osi_core->mac, + &btr[1], &btr[0]); + } + + /* 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) { + 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) { + return ret; + } + + val = osi_readl((unsigned char *)base + EQOS_MTL_EST_CONTROL); + /* Store table */ + val |= EQOS_MTL_EST_SSWL; + val |= EQOS_MTL_EST_EEST; + osi_writel(val, (unsigned char *)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; + + val = osi_readl((unsigned char *)osi_core->base + EQOS_MTL_FPE_CTS); + + if (((fpe->tx_queue_preemption_enable << EQOS_MTL_FPE_CTS_PEC_SHIFT) & + EQOS_MTL_FPE_CTS_PEC) == OSI_DISABLE) { + val &= ~EQOS_MAC_FPE_CTS_EFPE; + osi_writel(val, (unsigned char *)osi_core->base + + EQOS_MAC_FPE_CTS); + + val = osi_readl((unsigned char *)osi_core->base + + EQOS_MAC_RQC1R); + val &= ~EQOS_MAC_RQC1R_FPRQ; + osi_writel(val, (unsigned char *)osi_core->base + + EQOS_MAC_RQC1R); + + return 0; + } + + 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_writel(val, (unsigned char *)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_readl((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_writel(val, (unsigned char *)osi_core->base + EQOS_MAC_RQC1R); + + /* initiate SVER for SMD-V and SMD-R */ + val = osi_readl((unsigned char *)osi_core->base + EQOS_MTL_FPE_CTS); + val |= EQOS_MAC_FPE_CTS_SVER; + osi_writel(val, (unsigned char *)osi_core->base + EQOS_MAC_FPE_CTS); + + val = osi_readl((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_writel(val, (unsigned char *)osi_core->base + EQOS_MTL_FPE_ADV); + + return 0; +} + /** * @brief poll_for_mii_idle Query the status of an ongoing DMA transfer * @@ -4515,4 +5154,6 @@ void eqos_init_core_ops(struct core_ops *ops) 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; } diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 9937c75..4d48e2b 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -100,6 +100,8 @@ #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 @@ -134,7 +136,18 @@ * @{ */ #define EQOS_MTL_OP_MODE 0x0C00 +#define EQOS_MTL_INTR_STATUS 0x0C20 #define EQOS_MTL_RXQ_DMA_MAP0 0x0C30 +#define EQOS_MTL_EST_CONTROL 0x0C50 +#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_CHX_TX_OP_MODE(x) ((0x0040U * (x)) + 0x0D00U) #define EQOS_MTL_TXQ_ETS_CR(x) ((0x0040U * (x)) + 0x0D10U) #define EQOS_MTL_TXQ_QW(x) ((0x0040U * (x)) + 0x0D18U) @@ -194,6 +207,11 @@ #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_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)) @@ -213,9 +231,14 @@ #define EQOS_DMA_BMR_DPSW OSI_BIT(8) #define EQOS_MAC_RQC1R_MCBCQ1 OSI_BIT(16) #define EQOS_MAC_RQC1R_MCBCQEN OSI_BIT(20) +#define EQOS_MAC_RQC1R_FPRQ (OSI_BIT(24) | OSI_BIT(26) | \ + OSI_BIT(27)) +#define EQOS_MAC_RQC1R_FPRQ_SHIFT 24U #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_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 @@ -408,6 +431,89 @@ (TEGRA_SID_EQOS_CH5) |\ (TEGRA_SID_EQOS)) #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_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_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_SSWL OSI_BIT(1) +#define EQOS_MTL_EST_CONTROL_EEST OSI_BIT(0) +/* EST controlOSI_BITmap */ +#define EQOS_MTL_EST_EEST OSI_BIT(0) +#define EQOS_MTL_EST_SSWL OSI_BIT(1) +/* 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_GCRR OSI_BIT(2) +#define EQOS_MTL_EST_SRWO OSI_BIT(0) +#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) /** @} */ void update_ehfc_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value); @@ -425,7 +531,7 @@ void update_ehfc_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value); #define EQOS_MAC_RQC0R_MASK 0xFFU #define EQOS_MAC_RQC1R_MASK 0xF77077U #define EQOS_MAC_RQC2R_MASK 0xFFFFFFFFU -#define EQOS_MAC_IMR_MASK 0x47039U +#define EQOS_MAC_IMR_MASK 0x67039U #define EQOS_MAC_MA0HR_MASK 0xFFFFFU #define EQOS_MAC_MA0LR_MASK 0xFFFFFFFFU #define EQOS_MAC_TCR_MASK 0x1107FF03U @@ -433,7 +539,6 @@ void update_ehfc_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value); #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 diff --git a/osi/core/eqos_mmc.c b/osi/core/eqos_mmc.c index a9cb69d..6b16d64 100644 --- a/osi/core/eqos_mmc.c +++ b/osi/core/eqos_mmc.c @@ -381,4 +381,22 @@ void eqos_read_mmc(struct osi_core_priv_data *const osi_core) 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 index a76630d..8021e0b 100644 --- a/osi/core/eqos_mmc.h +++ b/osi/core/eqos_mmc.h @@ -112,7 +112,13 @@ #define MMC_RXTCP_GD_OCTETS 0x00878 #define MMC_RXTCP_ERR_OCTETS 0x0087c #define MMC_RXICMP_GD_OCTETS 0x00880 -#define MMC_RXICMP_ERR_OCTETS 0x00884U +#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); diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 3804649..c3d90b4 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -1005,6 +1005,30 @@ int osi_config_rss(struct osi_core_priv_data *const osi_core) return ops_p->config_rss(osi_core); } +int osi_hw_config_est(struct osi_core_priv_data *osi_core, + struct osi_est_config *est) +{ + if (validate_args(osi_core) < 0) { + return -1; + } + + if (est == OSI_NULL) { + OSI_CORE_ERR(osi_core->osd, 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_core->osd, OSI_LOG_ARG_INVALID, + "TX Flow control enabled, please disable it", + 0ULL); + return -1; + } + + return ops_p->hw_config_est(osi_core, est); +} + nve32_t osi_config_mac_loopback(struct osi_core_priv_data *const osi_core, const nveu32_t lb_mode) { @@ -1022,6 +1046,22 @@ nve32_t osi_config_mac_loopback(struct osi_core_priv_data *const osi_core, /* Configure MAC loopback */ return ops_p->config_mac_loopback(osi_core, lb_mode); } + +int osi_hw_config_fpe(struct osi_core_priv_data *osi_core, + struct osi_fpe_config *fpe) +{ + if (validate_args(osi_core) < 0) { + return -1; + } + + if (fpe == OSI_NULL) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "FPE data is NULL", 0ULL); + return -1; + } + + return ops_p->hw_config_fpe(osi_core, fpe); +} #endif /* !OSI_STRIPPED_LIB */ nve32_t osi_get_hw_features(struct osi_core_priv_data *const osi_core, From 333e2fc52aefa106a2438b3d207e538c9f2133b9 Mon Sep 17 00:00:00 2001 From: rakesh goyal <rgoyal@nvidia.com> Date: Thu, 23 Apr 2020 17:53:15 +0530 Subject: [PATCH 195/458] nvethernetrm: mgbe: TSN support for MGBE IP 1. EST/FPE support for MGBE 2. MMC counters for FPE 3. EST errors and state counter Bug 200561100 Change-Id: I556c5d53bb483549e217cde2f1bcb342291be912 Signed-off-by: rakesh goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2319826 Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> --- osi/core/mgbe_core.c | 659 ++++++++++++++++++++++++++++++++++++++++++- osi/core/mgbe_core.h | 101 +++++++ osi/core/mgbe_mmc.c | 18 ++ 3 files changed, 767 insertions(+), 11 deletions(-) diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 228b903..2dba5ea 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -22,6 +22,7 @@ #include "../osi/common/common.h" #include "../osi/common/type.h" +#include <local_common.h> #include <osi_common.h> #include <osi_core.h> #include "mgbe_core.h" @@ -1737,7 +1738,8 @@ static nve32_t mgbe_configure_mtl_queue(nveu32_t qinx, /*TTC not applicable for TX*/ /* Enable TxQ */ value |= MGBE_MTL_TXQEN; - osi_writel(value, (nveu8_t *) + value |= (osi_core->tc[qinx] << MGBE_MTL_CHX_TX_OP_MODE_Q2TC_SH); + osi_writel(value, (unsigned char *) osi_core->base + MGBE_MTL_CHX_TX_OP_MODE(qinx)); /* read RX Q0 Operating Mode Register */ @@ -2212,6 +2214,136 @@ static void mgbe_core_backup_init(struct osi_core_priv_data *const osi_core) /* TODO: Add wrapper register backup */ } +/** + * @brief mgbe_enable_mtl_interrupts - Enable MTL interrupts + * + * Algorithm: enable MTL interrupts for EST + * + * @param[in] addr: MAC base IOVA address. + * + * @note MAC should be init and started. see osi_start_mac() + */ +static inline void mgbe_enable_mtl_interrupts(void *addr) +{ + unsigned int mtl_est_ir = OSI_DISABLE; + + mtl_est_ir = osi_readl((unsigned char *)addr + 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_writel(mtl_est_ir, (unsigned char *)addr + MGBE_MTL_EST_ITRE); +} + +/** + * @brief mgbe_enable_fpe_interrupts - Enable MTL interrupts + * + * Algorithm: enable FPE interrupts + * + * @param[in] addr: MAC base IOVA address. + * + * @note MAC should be init and started. see osi_start_mac() + */ +static inline void mgbe_enable_fpe_interrupts(void *addr) +{ + unsigned int value = OSI_DISABLE; + + /* Read MAC IER Register and enable Frame Preemption Interrupt + * Enable */ + value = osi_readl((unsigned char *)addr + MGBE_MAC_IER); + value |= MGBE_IMR_FPEIE; + osi_writel(value, (unsigned char *)addr + MGBE_MAC_IER); +} + +/** + * @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) { + val = osi_readl((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 { + /* 6*1/(312 MHz) in ns*/ + temp = (6U * 3U); + } + temp = temp << MGBE_MTL_EST_CONTROL_PTOV_SHIFT; + val |= temp; + + /* We have a bug on CTOV for Qbv that synopsys is yet to + * fix[Case – 8001147927, Bug 200468714]. You can go ahead + * with 128*8ns for now. TODO */ + val &= ~MGBE_MTL_EST_CONTROL_CTOV; + temp = (128U * 8U); + 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; + osi_writel(val, (unsigned char *)osi_core->base + + MGBE_MTL_EST_CONTROL); + + mgbe_enable_mtl_interrupts(osi_core->base); + } + + if (fpe_sel == OSI_ENABLE) { + val = osi_readl((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_writel(val, (unsigned char *)osi_core->base + + MGBE_MAC_RQC1R); + + mgbe_enable_fpe_interrupts(osi_core->base); + } + + /* CBS setting for TC or TXQ for default configuration + user application should use IOCTL to set CBS as per requirement + */ +} + /** * @brief mgbe_core_init - MGBE MAC, MTL and common DMA Initialization * @@ -2297,12 +2429,70 @@ static nve32_t mgbe_core_init(struct osi_core_priv_data *osi_core, /* configure MGBE DMA */ mgbe_configure_dma(osi_core->base); + /* 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); + } + /* XPCS initialization */ return xpcs_init(osi_core); } /** - * @brief mgbe_handle_mac_nve32_trs - Handle MAC nve32_terrupts + * @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_readl((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_writel(val, (unsigned char *)osi_core->base + MGBE_MAC_FPE_CTS); +} + +/** + * @brief mgbe_handle_mac_intrs - Handle MAC interrupts * * Algorithm: This function takes care of handling the * MAC nve32_terrupts which includes speed, mode detection. @@ -2315,16 +2505,24 @@ static nve32_t mgbe_core_init(struct osi_core_priv_data *osi_core, static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core, nveu32_t dma_isr) { -#if 0 /* TODO: Need to re-visit */ - mac_isr = osi_readl((nveu8_t *)osi_core->base + MGBE_MAC_ISR); + unsigned int mac_isr = 0; + unsigned int mac_ier = 0; + mac_isr = osi_readl((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_readl((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; + } + + osi_writel(mac_isr, (unsigned char *)osi_core->base + MGBE_MAC_ISR); /* TODO: Duplex/speed settigs - Its not same as EQOS for MGBE */ -#endif } /** @@ -2601,6 +2799,110 @@ static int mgbe_get_avb_algorithm(struct osi_core_priv_data *const osi_core, 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 val = 0; + unsigned int sch_err = 0; + unsigned int frm_err = 0; + unsigned int temp = 0U; + unsigned int i = 0; + unsigned long stat_val = 0; + + val = osi_readl(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_readl(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_writel(sch_err, osi_core->base + MGBE_MTL_EST_SCH_ERR); + } + + 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_readl(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_writel(frm_err, osi_core->base + MGBE_MTL_EST_FRMS_ERR); + } + + 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_writel(val, osi_core->base + MGBE_MTL_EST_STATUS); +} + /** * @brief mgbe_handle_common_intr - Handles common interrupt. * @@ -2613,11 +2915,12 @@ static int mgbe_get_avb_algorithm(struct osi_core_priv_data *const osi_core, static void mgbe_handle_common_intr(struct osi_core_priv_data *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; + 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; dma_isr = osi_readl((nveu8_t *)base + MGBE_DMA_ISR); if (dma_isr == OSI_NONE) { @@ -2662,6 +2965,17 @@ static void mgbe_handle_common_intr(struct osi_core_priv_data *osi_core) } mgbe_handle_mac_intrs(osi_core, dma_isr); + + /* Handle MTL inerrupts */ + mtl_isr = osi_readl((unsigned char *)base + MGBE_MTL_INTR_STATUS); + + if (((mtl_isr & MGBE_MTL_IS_ESTIS) == MGBE_MTL_IS_ESTIS) && + ((dma_isr & MGBE_DMA_ISR_MTLIS) == MGBE_DMA_ISR_MTLIS)) { + mgbe_handle_mtl_intrs(osi_core); + mtl_isr &= ~MGBE_MTL_IS_ESTIS; + osi_writel(mtl_isr, (unsigned char *)base + + MGBE_MTL_INTR_STATUS); + } } /** @@ -3118,7 +3432,328 @@ static int mgbe_read_phy_reg(struct osi_core_priv_data *osi_core, reg = osi_readl((unsigned char *)osi_core->base + MGBE_MDIO_SCCD); data = (reg & MGBE_MDIO_SCCD_SDATA_MASK); - return (int)data; + 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_writel(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_writel(val, (unsigned char *)osi_core->base + + MGBE_MTL_EST_GCL_CONTROL); + + while (--retry > 0) { + osi_core->osd_ops.udelay(OSI_DELAY_1US); + val = osi_readl((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_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. + * + * @note MAC should be init and started. see osi_start_mac() + * + * @retval 0 on success + * @retval -1 on failure. + */ +static inline int mgbe_gcl_validate(struct osi_core_priv_data *osi_core, + struct osi_est_config *est) +{ + unsigned int wid_val = 0x0U; + unsigned int dep = 0x0U; + unsigned int i; + + if (osi_core->hw_feature == OSI_NULL) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "HW feature is NULL\n", 0ULL); + return -1; + } + + if (osi_core->hw_feature->gcl_width == 0x1U) { + wid_val = OSI_MAX_24BITS; + } else if (osi_core->hw_feature->gcl_width == 0x2U) { + wid_val = OSI_MAX_28BITS; + } else if (osi_core->hw_feature->gcl_width == 0x3U) { + wid_val = OSI_MAX_32BITS; + } else { + /* Do Nothing */ + } + + if (osi_core->hw_feature->gcl_depth == 0x1U) { + dep = OSI_GCL_SIZE_64; + } else if (osi_core->hw_feature->gcl_depth == 0x2U) { + dep = OSI_GCL_SIZE_128; + } else if (osi_core->hw_feature->gcl_depth == 0x3U) { + dep = OSI_GCL_SIZE_256; + } else if (osi_core->hw_feature->gcl_depth == 0x4U) { + dep = OSI_GCL_SIZE_512; + } else if (osi_core->hw_feature->gcl_depth == 0x5U) { + dep = OSI_GCL_SIZE_1024; + } else { + /* Do Nothing */ + } + + if (est->llr > dep) { + return -1; + } + + for (i = 0U; i < est->llr; i++) { + if (est->gcl[i] <= wid_val) { + continue; + } + + 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_readl((unsigned char *)base + MGBE_MTL_EST_CONTROL); + val &= ~MGBE_MTL_EST_EEST; + osi_writel(val, (unsigned char *)base + MGBE_MTL_EST_CONTROL); + + return 0; + } + ret = mgbe_hw_est_write(osi_core, MGBE_MTL_EST_CTR_LOW, est->ctr[0], 0); + if (ret < 0) { + 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) { + return ret; + } + + ret = mgbe_hw_est_write(osi_core, MGBE_MTL_EST_TER, est->ter, 0); + if (ret < 0) { + return ret; + } + + ret = mgbe_hw_est_write(osi_core, MGBE_MTL_EST_LLR, est->llr, 0); + if (ret < 0) { + 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) { + return ret; + } + } + + if (est->btr[0] == 0U && est->btr[1] == 0U) { + common_get_systime_from_mac(osi_core->base, + osi_core->mac, + &btr[1], &btr[0]); + } + /* 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) { + 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) { + return ret; + } + + val = osi_readl((unsigned char *)base + MGBE_MTL_EST_CONTROL); + /* Store table */ + val |= MGBE_MTL_EST_SSWL; + val |= MGBE_MTL_EST_EEST; + osi_writel(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; + + 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; + + val = osi_readl((unsigned char *)osi_core->base + MGBE_MTL_FPE_CTS); + if (((fpe->tx_queue_preemption_enable << MGBE_MTL_FPE_CTS_PEC_SHIFT) & + MGBE_MTL_FPE_CTS_PEC) == OSI_DISABLE) { + val &= ~MGBE_MAC_FPE_CTS_EFPE; + osi_writel(val, (unsigned char *)osi_core->base + + MGBE_MAC_FPE_CTS); + + val = osi_readl((unsigned char *)osi_core->base + + MGBE_MAC_RQC1R); + val &= ~MGBE_MAC_RQC1R_RQ; + osi_writel(val, (unsigned char *)osi_core->base + + MGBE_MAC_RQC1R); + + return 0; + } + + 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_writel(val, (unsigned char *)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); + return -1; + } + + val = osi_readl((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_writel(val, (unsigned char *)osi_core->base + MGBE_MAC_RQC1R); + + /* initiate SVER for SMD-V and SMD-R */ + val = osi_readl((unsigned char *)osi_core->base + MGBE_MTL_FPE_CTS); + val |= MGBE_MAC_FPE_CTS_SVER; + osi_writel(val, (unsigned char *)osi_core->base + MGBE_MAC_FPE_CTS); + + val = osi_readl((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_writel(val, (unsigned char *)osi_core->base + MGBE_MTL_FPE_ADV); + + return 0; } /** @@ -3848,4 +4483,6 @@ void mgbe_init_core_ops(struct core_ops *ops) 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; }; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 4f8d074..367eb49 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -80,6 +80,8 @@ #define MGBE_MAC_1US_TIC_COUNT 0x00DC #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 @@ -205,10 +207,21 @@ * @{ */ #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_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) @@ -244,6 +257,7 @@ #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) @@ -286,7 +300,13 @@ #define MGBE_MAC_RQC1R_OMCBCQ OSI_BIT(20) #define MGBE_MAC_RQC1R_MCBCQEN OSI_BIT(15) #define MGBE_MAC_RQC1R_MCBCQ1 OSI_BIT(8) +#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_IMR_RGSMIIIE OSI_BIT(0) +#define MGBE_IMR_FPEIE OSI_BIT(15) +#define MGBE_MAC_IMR_FPEIS OSI_BIT(16) +#define MGBE_DMA_ISR_MTLIS OSI_BIT(16) #define MGBE_DMA_ISR_MACIS OSI_BIT(17) #define MGBE_DMA_ISR_DCH0_DCH15_MASK 0xFFU #define MGBE_DMA_CHX_STATUS_TPS OSI_BIT(1) @@ -396,6 +416,87 @@ #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_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_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_CONTROL_EEST OSI_BIT(0) +/* EST controlOSI_BITmap */ +#define MGBE_MTL_EST_EEST OSI_BIT(0) +#define MGBE_MTL_EST_SSWL OSI_BIT(1) +/* 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_GCRR OSI_BIT(2) +#define MGBE_MTL_EST_SRWO OSI_BIT(0) +#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) /** @} */ /** diff --git a/osi/core/mgbe_mmc.c b/osi/core/mgbe_mmc.c index 68cff7a..75ed121 100644 --- a/osi/core/mgbe_mmc.c +++ b/osi/core/mgbe_mmc.c @@ -538,4 +538,22 @@ void mgbe_read_mmc(struct osi_core_priv_data *osi_core) 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); } From b5f66b4176c463b2e63f4aae206bd6f99d05bf4b Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Fri, 17 Apr 2020 10:34:32 +0530 Subject: [PATCH 196/458] nvethernetrm: Add Flexible Receive Parser support - Define new data structure for the FRP table entry, declare new frp_table and NVE variables in the OSI core private structure. - Define a new data structure for the OSI FRP command. Add new OSI API to initiate FRP commands from OSD. Bug 200565623 Change-Id: I84660a6e8270a681b82236d0c39423660b3821ff Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2330182 Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> --- include/osi_common.h | 4 + include/osi_core.h | 128 +++++++ include/osi_dma.h | 10 + osi/core/core_local.h | 12 +- osi/core/frp.c | 836 ++++++++++++++++++++++++++++++++++++++++++ osi/core/frp.h | 84 +++++ osi/core/osi_core.c | 28 ++ 7 files changed, 1101 insertions(+), 1 deletion(-) create mode 100644 osi/core/frp.c create mode 100644 osi/core/frp.h diff --git a/include/osi_common.h b/include/osi_common.h index 24747d1..057f88b 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -280,6 +280,10 @@ * @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 * diff --git a/include/osi_core.h b/include/osi_core.h index 11ce4a1..f7d2e29 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -199,6 +199,44 @@ typedef my_lint_64 nvel64_t; #define OSI_PTP_SSINC_4 4U /** @} */ +/** + * @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 +/** @} */ + struct osi_core_priv_data; /** @@ -584,6 +622,74 @@ struct osi_vlan_filter { 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. */ @@ -675,6 +781,7 @@ struct osi_tsn_stats { unsigned long sw_own_list_complete; }; + /** * @brief PTP configuration structure */ @@ -801,6 +908,8 @@ struct osi_core_priv_data { 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 */ @@ -844,6 +953,10 @@ struct osi_core_priv_data { 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 */ @@ -2308,6 +2421,21 @@ nve32_t osi_config_mac_loopback(struct osi_core_priv_data *const osi_core, */ nve32_t osi_config_rss(struct osi_core_priv_data *const osi_core); +/** + * @brief osi_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. + * + * @note + * 1) MAC and PHY should be init and started. see osi_start_mac() + * + * @retval 0 on success + * @retval -1 on failure. + */ +int osi_configure_frp(struct osi_core_priv_data *const osi_core, + struct osi_core_frp_cmd *const cmd); /** * @brief osi_hw_config_est - Read Setting for GCL from input and update * registers. diff --git a/include/osi_dma.h b/include/osi_dma.h index d5af817..f918984 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -256,6 +256,16 @@ struct osi_pkt_err_stats { 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; }; /** diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 6d4d019..6ab9d27 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -209,7 +209,17 @@ struct core_ops { 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); + 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); }; diff --git a/osi/core/frp.c b/osi/core/frp.c new file mode 100644 index 0000000..44217cc --- /dev/null +++ b/osi/core/frp.c @@ -0,0 +1,836 @@ +/* + * 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 "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 = *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 <= FRP_OFFSET_BYTES(offset)) { + /* Require one entry */ + return 1U; + } + /* Initialize req as 1U and decrement length by FRP_OFFSET_BYTES */ + req = 1U; + match_length -= FRP_OFFSET_BYTES(offset); + if ((match_length / FRP_MD_SIZE) < OSI_FRP_MATCH_DATA_MAX) { + req += (match_length / FRP_MD_SIZE); + if ((match_length % FRP_MD_SIZE) != OSI_NONE) { + /* Need one more entry */ + 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 = 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 = 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 += 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(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 = (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 new file mode 100644 index 0000000..d1092b7 --- /dev/null +++ b/osi/core/frp.h @@ -0,0 +1,84 @@ +/* + * 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 <osi_common.h> +#include <osi_core.h> +#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/osi_core.c b/osi/core/osi_core.c index c3d90b4..0ebdb2d 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -25,6 +25,7 @@ #include "core_local.h" #include "../osi/common/common.h" #include "vlan_filter.h" +#include "frp.h" /** * @brief g_core - Static core local data variable @@ -218,6 +219,9 @@ nve32_t osi_hw_core_init(struct osi_core_priv_data *const osi_core, init_vlan_filters(osi_core); + /* Init FRP */ + init_frp(osi_core); + return ops_p->core_init(osi_core, tx_fifo_size, rx_fifo_size); } @@ -961,6 +965,30 @@ nve32_t osi_configure_flow_control(struct osi_core_priv_data *const osi_core, return ops_p->config_flow_control(osi_core, flw_ctrl); } +int osi_configure_frp(struct osi_core_priv_data *const osi_core, + struct osi_core_frp_cmd *const cmd) +{ + if (validate_args(osi_core) < 0) { + return -1; + } + + 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, ops_p, cmd); +} + nve32_t osi_config_arp_offload(struct osi_core_priv_data *const osi_core, const nveu32_t flags, const nveu8_t *ip_addr) From 46cc5fd776eb67231a77365e2016b0b7d3a145de Mon Sep 17 00:00:00 2001 From: Hareesh Kesireddy <hkesireddy@nvidia.com> Date: Thu, 27 May 2021 23:13:36 -0700 Subject: [PATCH 197/458] osi: tx: update cur_tx_idx after memory barrier Issue: TX and TX completion thread are running in parallel on different CPUs. As soon as first CPU updates OWN bit and TX index (before dmb and TAIL), second CPU started processing this descriptor and found OWN bit as 0. Due to this, 2nd CPU reset the descriptor to 0s in osi_process_tx_completions() before HW process the descriptor. Hence HW still waiting at the reset descriptor while SW clean_idx has moved ahead. Fix: In TX path update cur_tx_idx only after DMB. Bug 3296734 Change-Id: Ic9b6e636e4f8dc8d2e4e6b9af6be201f35e72428 Signed-off-by: Hareesh Kesireddy <hkesireddy@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2536248 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: svc_kernel_abi <svc_kernel_abi@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/dma/osi_dma_txrx.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 5abb19c..0cd0d99 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -1112,6 +1112,12 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, 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(); + tailptr = tx_ring->tx_desc_phy_addr + (entry * sizeof(struct osi_tx_desc)); if (osi_unlikely(tailptr < tx_ring->tx_desc_phy_addr)) { @@ -1121,13 +1127,11 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, return -1; } - tx_ring->cur_tx_idx = entry; - /* - * We need to make sure Tx descriptor updated above is really updated - * before setting up the DMA, hence add memory write barrier here. + * Updating cur_tx_idx allows tx completion thread to read first_desc. + * Hence cur_tx_idx should be updated after memory barrier. */ - dmb_oshst(); + tx_ring->cur_tx_idx = entry; ops->update_tx_tailptr(osi_dma->base, chan, tailptr); From 30fc536a7cb06ce8a17638c9b09e4711de344418 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Tue, 21 Apr 2020 15:02:11 +0530 Subject: [PATCH 198/458] osi: XPCS WAR to combine init and start Change-Id: Iee40898a2b18928f130dfa13f2d7ee8bb5c8c270 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> --- osi/core/mgbe_core.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 2dba5ea..29dfeed 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -2435,8 +2435,7 @@ static nve32_t mgbe_core_init(struct osi_core_priv_data *osi_core, osi_core->hw_feature->fpe_sel); } - /* XPCS initialization */ - return xpcs_init(osi_core); + return 0; } /** @@ -3094,6 +3093,12 @@ static int mgbe_set_speed(struct osi_core_priv_data *const osi_core, const int s osi_writel(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"); + return -1; + } + return xpcs_start(osi_core); } From 3fd3145f08e9c0a4c8a082f89cb711a905117a63 Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Fri, 17 Apr 2020 10:46:02 +0530 Subject: [PATCH 199/458] nvethernetrm: mgbe: Implement FRP callbacks - Add a function to write the FRP entry into HW. - Implement config_frp, update_frp_entry and update_frp_nve MAC callbacks. Bug 200565623 Change-Id: Ia3deeebf60cdf4bd6976d9775fc7e678f6285ce4 Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2330183 Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> --- osi/common/common.h | 30 ++++ osi/core/mgbe_core.c | 363 +++++++++++++++++++++++++++++++++++++++++-- osi/core/mgbe_core.h | 99 +++++++++++- osi/dma/mgbe_desc.c | 30 ++++ osi/dma/mgbe_desc.h | 37 +++++ 5 files changed, 549 insertions(+), 10 deletions(-) create mode 100644 osi/dma/mgbe_desc.h diff --git a/osi/common/common.h b/osi/common/common.h index a0df155..89f6aee 100644 --- a/osi/common/common.h +++ b/osi/common/common.h @@ -36,6 +36,36 @@ #define COND_NOT_MET 1 /** @} */ +/** + * @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. * diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 29dfeed..40ca6d3 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -1585,6 +1585,313 @@ static int mgbe_config_rxcsum_offload( 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_readl(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_writel(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_readl(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_writel(val, base + MGBE_MTL_RXP_INTR_CS); + } else { + /* Reset FRPE bit of MTL_Operation_Mode register */ + op_mode &= ~MGBE_MTL_OP_MODE_FRPE; + osi_writel(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_readl(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_writel(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_writel(data, base + MGBE_MTL_RXP_IND_DATA); + + /* Program MTL_RXP_Indirect_Acc_Control_Status */ + val = osi_readl(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_writel(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 **/ + /* TODO: The DCH position will be updated in the final RTL. + * We need to update this on the final RTL. + */ + tmp = (data->dma_chsel >> MGBE_MTL_FRP_IE3_DCH_SHIFT); + val = (tmp & 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_readl(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_writel(val, base + MGBE_MTL_RXP_CS); + + return 0; +} + /** * @brief update_rfa_rfd - Update RFD and RSA values * @@ -1984,7 +2291,7 @@ static int mgbe_config_flow_control(struct osi_core_priv_data *const osi_core, */ static int mgbe_configure_mac(struct osi_core_priv_data *osi_core) { - nveu32_t value; + unsigned int value = 0U, max_queue = 0U, i = 0U; /* Update MAC address 0 high */ value = (((nveu32_t)osi_core->mac_addr[5] << 8U) | @@ -2032,11 +2339,19 @@ static int mgbe_configure_mac(struct osi_core_priv_data *osi_core) } osi_writel(value, (unsigned char *)osi_core->base + MGBE_MAC_TMCR); - /* Enable Multicast and Broadcast Queue, default is Q1 */ + /* Enable Multicast and Broadcast Queue */ value = osi_readl((unsigned char *)osi_core->base + MGBE_MAC_RQC1R); value |= MGBE_MAC_RQC1R_MCBCQEN; - /* Routing Multicast and Broadcast to Q1 */ - value |= MGBE_MAC_RQC1R_MCBCQ1; + /* 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_writel(value, (unsigned char *)osi_core->base + MGBE_MAC_RQC1R); /* Disable all MMC nve32_terrupts */ @@ -3095,7 +3410,7 @@ static int mgbe_set_speed(struct osi_core_priv_data *const osi_core, const int s if (xpcs_init(osi_core) < 0) { OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "xpcs_init failed\n"); + "xpcs_init failed\n", OSI_NONE); return -1; } @@ -3890,6 +4205,7 @@ static int mgbe_get_hw_features(struct osi_core_priv_data *osi_core, unsigned int mac_hfr1 = 0; unsigned int mac_hfr2 = 0; unsigned int mac_hfr3 = 0; + unsigned int val = 0; mac_hfr0 = osi_readl(base + MGBE_MAC_HFR0); mac_hfr1 = osi_readl(base + MGBE_MAC_HFR1); @@ -3995,10 +4311,36 @@ static int mgbe_get_hw_features(struct osi_core_priv_data *osi_core, MGBE_MAC_HFR3_FRPPIPE_MASK); hw_feat->ost_over_udp = ((mac_hfr3 >> MGBE_MAC_HFR3_POUOST_SHIFT) & MGBE_MAC_HFR3_POUOST_MASK); - hw_feat->max_frp_bytes = ((mac_hfr3 >> MGBE_MAC_HFR3_FRPPB_SHIFT) & - MGBE_MAC_HFR3_FRPPB_MASK); - hw_feat->max_frp_entries = ((mac_hfr3 >> MGBE_MAC_HFR3_FRPES_SHIFT) & - MGBE_MAC_HFR3_FRPES_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) & @@ -4490,4 +4832,7 @@ void mgbe_init_core_ops(struct core_ops *ops) 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; }; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 367eb49..08b6287 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -232,8 +232,90 @@ #define MGBE_MTL_RXQ_FLOW_CTRL(x) ((0x0080U * (x)) + 0x1150U) #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_SHIFT 8U +#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 @@ -299,7 +381,10 @@ #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_MCBCQ1 OSI_BIT(8) +#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 @@ -847,5 +932,17 @@ #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 /** @} */ #endif /* MGBE_CORE_H_ */ diff --git a/osi/dma/mgbe_desc.c b/osi/dma/mgbe_desc.c index 12f12ee..178aaea 100644 --- a/osi/dma/mgbe_desc.c +++ b/osi/dma/mgbe_desc.c @@ -22,6 +22,7 @@ #include "dma_local.h" #include "hw_desc.h" +#include "mgbe_desc.h" /** * @brief mgbe_get_rx_vlan - Get Rx VLAN from descriptor @@ -60,12 +61,41 @@ static inline void mgbe_update_rx_err_stats(struct osi_rx_desc *rx_desc, struct osi_pkt_err_stats pkt_err_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) { pkt_err_stats.rx_crc_error = osi_update_stats_counter(pkt_err_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)) { + pkt_err_stats.frp_parsed = + osi_update_stats_counter(pkt_err_stats.frp_parsed, 1UL); + } + /* Increment FRP dropped count */ + if ((frpsm == OSI_NONE) && (frpsl == MGBE_RDES3_FRPSL)) { + pkt_err_stats.frp_dropped = + osi_update_stats_counter(pkt_err_stats.frp_dropped, + 1UL); + } + /* Increment FRP Parsing Error count */ + if ((frpsm == MGBE_RDES2_FRPSM) && (frpsl == OSI_NONE)) { + pkt_err_stats.frp_err = + osi_update_stats_counter(pkt_err_stats.frp_err, 1UL); + } + /* Increment FRP Incomplete Parsing count */ + if ((frpsm == MGBE_RDES2_FRPSM) && (frpsl == MGBE_RDES3_FRPSL)) { + pkt_err_stats.frp_incomplete = + osi_update_stats_counter(pkt_err_stats.frp_incomplete, + 1UL); + } } /** diff --git a/osi/dma/mgbe_desc.h b/osi/dma/mgbe_desc.h new file mode 100644 index 0000000..8b0d5d0 --- /dev/null +++ b/osi/dma/mgbe_desc.h @@ -0,0 +1,37 @@ +/* + * 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_ */ + From e35bc97e87444f9b46cfd733f6f4c781655675a8 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Mon, 30 Mar 2020 16:33:18 +0530 Subject: [PATCH 200/458] nvethernetrm: mgbe: enable common interrupt Bug 200599175 Change-Id: Ie510fae3837158a84aca51f5ac4a19bbf609d185 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2324884 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> --- osi/core/mgbe_core.c | 27 ++++++++++++++++++++++++++- osi/core/mgbe_core.h | 11 +++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 40ca6d3..683964c 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -2376,6 +2376,13 @@ static int mgbe_configure_mac(struct osi_core_priv_data *osi_core) value |= MGBE_IMR_RGSMIIIE; osi_writel(value, (nveu8_t *)osi_core->base + MGBE_MAC_IER); + /* Enable common interrupt at wrapper level */ + value = osi_readl((unsigned char *)osi_core->base + + MGBE_WRAP_COMMON_INTR_ENABLE); + value |= MGBE_MAC_SBD_INTR; + osi_writel(value, (unsigned char *)osi_core->base + + MGBE_WRAP_COMMON_INTR_ENABLE); + /* Enable VLAN configuration */ value = osi_readl((unsigned char *)osi_core->base + MGBE_MAC_VLAN_TR); /* Enable VLAN Tag in RX Status @@ -3235,6 +3242,16 @@ static void mgbe_handle_common_intr(struct osi_core_priv_data *osi_core) unsigned int dma_sr = 0; unsigned int dma_ier = 0; unsigned int mtl_isr = 0; + unsigned int val = 0; + + /* FIXME: Disabling common interrupt. Needs to be fixed once + * RTL issue http://nvbugs/200517360 resolved. + */ + val = osi_readl((unsigned char *)osi_core->base + + MGBE_WRAP_COMMON_INTR_ENABLE); + val &= ~MGBE_MAC_SBD_INTR; + osi_writel(val, (unsigned char *)osi_core->base + + MGBE_WRAP_COMMON_INTR_ENABLE); dma_isr = osi_readl((nveu8_t *)base + MGBE_DMA_ISR); if (dma_isr == OSI_NONE) { @@ -3282,7 +3299,6 @@ static void mgbe_handle_common_intr(struct osi_core_priv_data *osi_core) /* Handle MTL inerrupts */ mtl_isr = osi_readl((unsigned char *)base + MGBE_MTL_INTR_STATUS); - if (((mtl_isr & MGBE_MTL_IS_ESTIS) == MGBE_MTL_IS_ESTIS) && ((dma_isr & MGBE_DMA_ISR_MTLIS) == MGBE_DMA_ISR_MTLIS)) { mgbe_handle_mtl_intrs(osi_core); @@ -3290,6 +3306,15 @@ static void mgbe_handle_common_intr(struct osi_core_priv_data *osi_core) osi_writel(mtl_isr, (unsigned char *)base + MGBE_MTL_INTR_STATUS); } + + /* Clear common interrupt status in wrapper register */ + osi_writel(MGBE_MAC_SBD_INTR, + (unsigned char *)base + MGBE_WRAP_COMMON_INTR_STATUS); + val = osi_readl((unsigned char *)osi_core->base + + MGBE_WRAP_COMMON_INTR_ENABLE); + val |= MGBE_MAC_SBD_INTR; + osi_writel(val, (unsigned char *)osi_core->base + + MGBE_WRAP_COMMON_INTR_ENABLE); } /** diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 08b6287..e5e8949 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -104,6 +104,16 @@ #define MGBE_MAC_RSS_DATA 0x0C8C /** @} */ +/** + * @addtogroup MGBE-WRAPPER MGBE Wrapper register offsets + * + * @brief MGBE Wrapper register offsets + * @{ + */ +#define MGBE_WRAP_COMMON_INTR_ENABLE 0x8704 +#define MGBE_WRAP_COMMON_INTR_STATUS 0x8708 +/** @} */ + /** * @addtogroup MGBE MAC hash table defines * @@ -582,6 +592,7 @@ #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_SBD_INTR OSI_BIT(2) /** @} */ /** From c2846161bace11bcce88f24b20d20e5d59f412c1 Mon Sep 17 00:00:00 2001 From: mohant <mohant@nvidia.com> Date: Tue, 10 Dec 2019 16:34:34 +0530 Subject: [PATCH 201/458] nvethernetrm: Add PTP offload support Bug 200562286 Change-Id: I7adf08da12458c7291391ef726fe1fa65cb1bda1 Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2319556 Tested-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> --- include/osi_common.h | 1 - include/osi_core.h | 51 ++++++++++++++- osi/core/core_local.h | 3 + osi/core/eqos_core.c | 104 +++++++++++++++++++++++++++++++ osi/core/eqos_core.h | 21 ++++++- osi/core/libnvethernetrm.export | 1 + osi/core/mgbe_core.c | 107 +++++++++++++++++++++++++++++++- osi/core/mgbe_core.h | 27 +++++--- osi/core/osi_core.c | 83 +++++++++++++++++++++++++ 9 files changed, 386 insertions(+), 12 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index 057f88b..67e76d0 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -279,7 +279,6 @@ /** * @brief osi_update_stats_counter - update value by increment passed * as parameter - * * @note * Algorithm: * - Check for boundary and return sum diff --git a/include/osi_core.h b/include/osi_core.h index f7d2e29..6e21410 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -147,6 +147,17 @@ typedef my_lint_64 nvel64_t; #define TWO_POWER_31 0x80000000U /** @} */ +/** + * @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 +/** @} */ + /** * @brief OSI error macro definition, * @param[in] priv: OSD private data OR NULL @@ -725,6 +736,27 @@ struct osi_core_avb_algorithm { }; #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 */ @@ -781,7 +813,6 @@ struct osi_tsn_stats { unsigned long sw_own_list_complete; }; - /** * @brief PTP configuration structure */ @@ -1554,6 +1585,24 @@ nve32_t osi_read_phy_reg(struct osi_core_priv_data *const osi_core, */ nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core); +/** + * @brief osi_config_ptp_offload - Enable/Disable PTP offload + * + * Algorithm: Based on input argument, update TSCR and PTO registers. + * Update ptp_filter for TSCR register and call PTP configurtion API. + * + * @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() + * + * @retval 0 on success + * @retval -1 on failure. + */ +int osi_config_ptp_offload(struct osi_core_priv_data *const osi_core, + struct osi_pto_config *const pto_config); + /** * @brief osi_set_systime_to_mac - Handles setting of system time. * diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 6ab9d27..c6b0a95 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -220,6 +220,9 @@ struct core_ops { /** 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); }; diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index e1972dd..dcbf0c0 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -2372,6 +2372,109 @@ static nve32_t eqos_update_mac_addr_low_high_reg( 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_readl(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_writel(ptc_value, addr + EQOS_MAC_PTO_CR); + eqos_core_safety_writel(osi_core, value, addr + + EQOS_MAC_TCR, EQOS_MAC_TCR_IDX); + osi_writel(OSI_NONE, addr + EQOS_MAC_PIDR0); + osi_writel(OSI_NONE, addr + EQOS_MAC_PIDR1); + osi_writel(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_writel(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_writel(port_id, addr + EQOS_MAC_PIDR0); + osi_writel(OSI_NONE, addr + EQOS_MAC_PIDR1); + osi_writel(OSI_NONE, addr + EQOS_MAC_PIDR2); + + return ret; +} + /** * @brief eqos_config_l3_l4_filter_enable - register write to enable L3/L4 * filters. @@ -5141,6 +5244,7 @@ void eqos_init_core_ops(struct core_ops *ops) 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; diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 4d48e2b..f99cd22 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -124,6 +124,10 @@ #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_DMA_BMR 0x1000 #define EQOS_DMA_SBUS 0x1004 #define EQOS_DMA_ISR 0x1008 @@ -384,12 +388,25 @@ #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_STNSUR_ADDSUB_SHIFT 31U #define EQOS_MAC_TCR_TSCFUPDT OSI_BIT(1) -#define EQOS_MAC_TCR_TSCTRLSSR OSI_BIT(9) +#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 diff --git a/osi/core/libnvethernetrm.export b/osi/core/libnvethernetrm.export index 294f242..b601e24 100644 --- a/osi/core/libnvethernetrm.export +++ b/osi/core/libnvethernetrm.export @@ -37,6 +37,7 @@ osi_set_speed osi_pad_calibrate osi_get_mac_version osi_get_hw_features +osi_config_ptp_offload osi_config_rxcsum_offload osi_l2_filter osi_l3l4_filter diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 683964c..498573f 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -2387,7 +2387,6 @@ static int mgbe_configure_mac(struct osi_core_priv_data *osi_core) value = osi_readl((unsigned char *)osi_core->base + MGBE_MAC_VLAN_TR); /* Enable VLAN Tag in RX Status * Disable double VLAN Tag processing on TX and RX - * TODO: Need to check EQOS comments here */ if (osi_core->strip_vlan_tag == OSI_ENABLE) { /* Enable VLAN Tag stripping always */ @@ -3224,6 +3223,111 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core) osi_writel(val, osi_core->base + MGBE_MTL_EST_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_readl((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_writel(ptc_value, addr + MGBE_MAC_PTO_CR); + osi_writel(value, addr + MGBE_MAC_TCR); + /* Setting PORT ID as 0 */ + osi_writel(OSI_NONE, addr + MGBE_MAC_PIDR0); + osi_writel(OSI_NONE, addr + MGBE_MAC_PIDR1); + osi_writel(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_writel(ptc_value, addr + MGBE_MAC_PTO_CR); + osi_writel(value, addr + MGBE_MAC_TCR); + /* Port ID for PTP offload packet created */ + port_id = pto_config->portid & MGBE_MAC_PIDR_PID_MASK; + osi_writel(port_id, addr + MGBE_MAC_PIDR0); + osi_writel(OSI_NONE, addr + MGBE_MAC_PIDR1); + osi_writel(OSI_NONE, addr + MGBE_MAC_PIDR2); + + return ret; +} + /** * @brief mgbe_handle_common_intr - Handles common interrupt. * @@ -4829,6 +4933,7 @@ void mgbe_init_core_ops(struct core_ops *ops) ops->config_rx_crc_check = OSI_NULL; 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; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index e5e8949..6278119 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -89,6 +89,12 @@ #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 @@ -96,12 +102,10 @@ #define MGBE_MAC_STSUR 0x0D10 #define MGBE_MAC_STNSUR 0x0D14 #define MGBE_MAC_TAR 0x0D18 -#define MGBE_MAC_ARPPA 0x0c10 -#define MGBE_MAC_L3L4_ADDR_CTR 0x0C00 -#define MGBE_MAC_L3L4_DATA 0x0C04 -#define MGBE_MAC_RSS_CTRL 0x0C80 -#define MGBE_MAC_RSS_ADDR 0x0C88 -#define MGBE_MAC_RSS_DATA 0x0C8C +#define MGBE_MAC_PTO_CR 0x0DC0 +#define MGBE_MAC_PIDR0 0x0DC4 +#define MGBE_MAC_PIDR1 0x0DC8 +#define MGBE_MAC_PIDR2 0x0DCC /** @} */ /** @@ -498,10 +502,19 @@ #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_TCR_SNAPTYPSEL_SHIFT 16 +#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 diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 0ebdb2d..4a0972b 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -309,6 +309,89 @@ nve32_t osi_config_fw_err_pkts(struct osi_core_priv_data *const osi_core, return ops_p->config_fw_err_pkts(osi_core, qinx, fw_err); } +int osi_config_ptp_offload(struct osi_core_priv_data *const osi_core, + struct osi_pto_config *const pto_config) +{ + int ret = -1; + + if (validate_args(osi_core) < 0) { + return -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", + 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", + 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", + 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", + 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", + 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", + pto_config->portid); + return ret; + } + + ret = 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", + 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", + 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) { From fd8ad9e006a08bc1654106cc6c142554db323e4e Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Thu, 26 Mar 2020 18:09:17 +0530 Subject: [PATCH 202/458] nvethernetrm: eqos: Implement PTP RX Queue support Add new config_ptp_rxq call back to support PTP RX Packets routing. Bug 200565911 Change-Id: Iee75dba95c011420421e9d5fdd6ce44e3b07872d Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Signed-off-by: narayanr <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2318887 Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> --- osi/core/eqos_core.c | 89 ++++++++++++++++++++++++++++++++++++++++++++ osi/core/eqos_core.h | 8 +++- 2 files changed, 96 insertions(+), 1 deletion(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index dcbf0c0..9859e52 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -3555,6 +3555,94 @@ static void eqos_config_tscr(struct osi_core_priv_data *const osi_core, EQOS_MAC_TCR_IDX); } +/** + * @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 -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_readl(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_writel(value, base + EQOS_MAC_RQC1R); + + return 0; +} + /** * @brief eqos_config_ssir - Configure SSIR * @@ -5260,4 +5348,5 @@ void eqos_init_core_ops(struct core_ops *ops) #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; } diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index f99cd22..562ba07 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -233,11 +233,17 @@ #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_MCBCQ1 OSI_BIT(16) +#define EQOS_MAC_RQC1R_TPQC (OSI_BIT(22) | OSI_BIT(23)) +#define EQOS_MAC_RQC1R_TPQC0 OSI_BIT(22) #define EQOS_MAC_RQC1R_MCBCQEN OSI_BIT(20) +#define EQOS_MAC_RQC1R_MCBCQ1 OSI_BIT(16) #define EQOS_MAC_RQC1R_FPRQ (OSI_BIT(24) | OSI_BIT(26) | \ OSI_BIT(27)) #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_MTL_QTOMR_FTQ_LPOS OSI_BIT(0) #define EQOS_DMA_ISR_MTLIS OSI_BIT(16) #define EQOS_DMA_ISR_MACIS OSI_BIT(17) From 093dc7807ea64d4c612b077de8fb47a6a0dc39d7 Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Wed, 6 May 2020 20:56:33 +0530 Subject: [PATCH 203/458] nvethernetrm: eqos: Implement FRP callbacks - Implement config_frp, update_frp_entry, and update_frp_nve MAC callbacks. - Set MCBCQ to max enabled RX queue index. Bug 200604314 Change-Id: I154712685d8fad6d39a86474ddf18fd292e06451 Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2340089 Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> --- osi/core/eqos_core.c | 311 ++++++++++++++++++++++++++++++++++++++++++- osi/core/eqos_core.h | 82 +++++++++++- osi/core/mgbe_core.c | 8 ++ 3 files changed, 395 insertions(+), 6 deletions(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 9859e52..ffff202 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1125,6 +1125,284 @@ static nve32_t eqos_config_rxcsum_offload( 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); + + /* 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; + } + + op_mode = osi_readl(base + EQOS_MTL_OP_MODE); + val = osi_readl(base + EQOS_MTL_RXP_INTR_CS); + if (enabled == OSI_ENABLE) { + /* Set FRPE bit of MTL_Operation_Mode register */ + op_mode |= EQOS_MTL_OP_MODE_FRPE; + + /* 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 { + /* Reset FRPE bit of MTL_Operation_Mode register */ + op_mode &= ~EQOS_MTL_OP_MODE_FRPE; + + /* Disable FRP Interrupt MTL_RXP_Interrupt_Control_Status */ + val = osi_readl(base + EQOS_MTL_RXP_INTR_CS); + 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(op_mode, base + EQOS_MTL_OP_MODE); + osi_writel(val, base + EQOS_MTL_RXP_INTR_CS); + +frp_enable_re: + /* Enable RE */ + val = osi_readl(base + EQOS_MAC_MCR); + val |= EQOS_MCR_RE; + osi_writel(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_readl(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_writel(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; +} + /** * @brief eqos_configure_rxq_priority - Configure Priorities Selected in * the Receive Queue @@ -1221,7 +1499,7 @@ static void eqos_configure_rxq_priority( */ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) { - nveu32_t value; + nveu32_t value, i = 0U, max_queue = 0U; nveu32_t mac_ext; /* Update MAC address 0 high */ @@ -1273,13 +1551,26 @@ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) eqos_core_safety_writel(osi_core, value, (nveu8_t *)osi_core->base + EQOS_MAC_MCR, EQOS_MAC_MCR_IDX); + /* Enable PDC */ + value = osi_readl((unsigned char *)osi_core->base + EQOS_MAC_EXTR); + value |= EQOS_MAC_EXTR_PDC; + osi_writel(value, (unsigned char *)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 to Q1 */ - value |= EQOS_MAC_RQC1R_MCBCQ1; - eqos_core_safety_writel(osi_core, value, (nveu8_t *)osi_core->base + + /* 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 &= ~(EQOS_MAC_RQC1R_MCBCQ); + value |= (max_queue << EQOS_MAC_RQC1R_MCBCQ_SHIFT); + eqos_core_safety_writel(osi_core, value, (unsigned char *)osi_core->base + EQOS_MAC_RQC1R, EQOS_MAC_RQC1R_IDX); /* Disable all MMC interrupts */ @@ -1978,6 +2269,7 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *const osi_core) nveu32_t dma_sr = 0; nveu32_t dma_ier = 0; unsigned int mtl_isr = 0; + unsigned int frp_isr = 0U; dma_isr = osi_readla(osi_core, (nveu8_t *)base + EQOS_DMA_ISR); if (dma_isr == 0U) { @@ -2029,6 +2321,14 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *const osi_core) osi_writel(mtl_isr, (unsigned char *)base + EQOS_MTL_INTR_STATUS); } + + /* Clear FRP Interrupt MTL_RXP_Interrupt_Control_Status */ + frp_isr = osi_readl((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_writel(frp_isr, (unsigned char *)base + EQOS_MTL_RXP_INTR_CS); } /** @@ -5349,4 +5649,7 @@ void eqos_init_core_ops(struct core_ops *ops) 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; } diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 562ba07..7c6b545 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -152,6 +152,12 @@ #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_ETS_CR(x) ((0x0040U * (x)) + 0x0D10U) #define EQOS_MTL_TXQ_QW(x) ((0x0040U * (x)) + 0x0D18U) @@ -198,8 +204,8 @@ #define EQOS_MTL_TSF OSI_BIT(1) #define EQOS_MTL_TXQEN OSI_BIT(3) #define EQOS_MTL_RSF OSI_BIT(5) -#define EQOS_MCR_TE OSI_BIT(0) -#define EQOS_MCR_RE OSI_BIT(1) +#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) @@ -235,6 +241,9 @@ #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_MCBCQEN OSI_BIT(20) #define EQOS_MAC_RQC1R_MCBCQ1 OSI_BIT(16) #define EQOS_MAC_RQC1R_FPRQ (OSI_BIT(24) | OSI_BIT(26) | \ @@ -303,6 +312,10 @@ 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_MAC_EXTR_DCRCC OSI_BIT(16) #endif /* !OSI_STRIPPED_LIB */ #define EQOS_MTL_RXQ_OP_MODE_FEP OSI_BIT(4) @@ -608,6 +621,71 @@ void update_ehfc_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value); #define EQOS_MAX_CORE_SAFETY_REGS 31U /** @} */ +/** + * @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. diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 498573f..b4e3b94 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -3419,6 +3419,14 @@ static void mgbe_handle_common_intr(struct osi_core_priv_data *osi_core) val |= MGBE_MAC_SBD_INTR; osi_writel(val, (unsigned char *)osi_core->base + MGBE_WRAP_COMMON_INTR_ENABLE); + + /* Clear FRP Interrupts in MTL_RXP_Interrupt_Control_Status */ + val = osi_readl(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_writel(val, base + MGBE_MTL_RXP_INTR_CS); } /** From c4a49ca6f96120d8110f509ac503b249c729dc2e Mon Sep 17 00:00:00 2001 From: narayanr <narayanr@nvidia.com> Date: Tue, 12 May 2020 17:23:59 +0530 Subject: [PATCH 204/458] osi: mgbe: program recommended values program the recommended values by HW team for better performance Bug 200565630 Bug 200570017 Change-Id: I96a870114623ce76804c49706d2961010448ca86 Signed-off-by: narayanr <narayanr@nvidia.com> --- include/osi_dma.h | 2 + osi/core/mgbe_core.c | 52 +++++++++++++++---- osi/core/mgbe_core.h | 26 ++++++++-- osi/dma/mgbe_dma.c | 117 ++++++++++++++++++++++++++++++++++++++++--- osi/dma/mgbe_dma.h | 33 ++++++++++-- 5 files changed, 206 insertions(+), 24 deletions(-) diff --git a/include/osi_dma.h b/include/osi_dma.h index f918984..7a2228b 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -553,6 +553,8 @@ struct osi_dma_priv_data { * bit 0 PTP mode master(1) slave(0) * bit 1 PTP sync method twostep(1) onestep(0) */ unsigned int ptp_flag; + /** Tegra Pre-si platform info */ + unsigned int pre_si; }; diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index b4e3b94..3161142 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -113,7 +113,7 @@ static nve32_t mgbe_poll_for_swr(struct osi_core_priv_data *const osi_core) nveu32_t pre_si = osi_core->pre_si; /* Performing software reset */ - if (pre_si == 1U) { + if (pre_si == OSI_ENABLE) { osi_writel(OSI_ENABLE, (nveu8_t *)addr + MGBE_DMA_MODE); } @@ -194,6 +194,10 @@ static nveu32_t mgbe_calculate_per_queue_fifo(nveu32_t fifo_size, 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; @@ -2431,22 +2435,42 @@ static int mgbe_configure_mac(struct osi_core_priv_data *osi_core) * * @note MAC has to be out of reset. */ -static void mgbe_configure_dma(void *base) +static void mgbe_configure_dma(void *base, nveu32_t pre_si) { nveu32_t value = 0; - /* AXI Burst Length 8*/ - value |= MGBE_DMA_SBUS_BLEN8; - /* AXI Burst Length 16*/ - value |= MGBE_DMA_SBUS_BLEN16; + /* 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 = 31 */ + /* AXI Maximum Read Outstanding Request Limit = 63 */ value |= MGBE_DMA_SBUS_RD_OSR_LMT; - /* AXI Maximum Write Outstanding Request Limit = 31 */ + /* AXI Maximum Write Outstanding Request Limit = 63 */ value |= MGBE_DMA_SBUS_WR_OSR_LMT; osi_writel(value, (nveu8_t *)base + MGBE_DMA_SBUS); + + /* Configure TDPS to 5 */ + value = osi_readl((nveu8_t *)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_writel(value, (nveu8_t *)base + MGBE_DMA_TX_EDMA_CTRL); + + /* Configure RDPS to 5 */ + value = osi_readl((nveu8_t *)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_writel(value, (nveu8_t *)base + MGBE_DMA_RX_EDMA_CTRL); } /** @@ -2723,6 +2747,16 @@ static nve32_t mgbe_core_init(struct osi_core_priv_data *osi_core, /* TODO: DCS enable */ + 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); @@ -2748,7 +2782,7 @@ static nve32_t mgbe_core_init(struct osi_core_priv_data *osi_core, } /* configure MGBE DMA */ - mgbe_configure_dma(osi_core->base); + mgbe_configure_dma(osi_core->base, osi_core->pre_si); /* tsn initialization */ if (osi_core->hw_feature != OSI_NULL) { diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 6278119..e8132b9 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -210,6 +210,8 @@ #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) /** @} */ @@ -475,11 +477,15 @@ #define MGBE_MAC_RSS_ADDR_OB OSI_BIT(0) #define MGBE_MAC_RSS_ADDR_CT OSI_BIT(1) /* DMA SBUS */ -#define MGBE_DMA_SBUS_BLEN8 OSI_BIT(2) -#define MGBE_DMA_SBUS_BLEN16 OSI_BIT(3) +#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 0x001F0000U -#define MGBE_DMA_SBUS_WR_OSR_LMT 0x1F000000U +#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)) @@ -640,6 +646,18 @@ #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 * diff --git a/osi/dma/mgbe_dma.c b/osi/dma/mgbe_dma.c index 99f63b0..901fb33 100644 --- a/osi/dma/mgbe_dma.c +++ b/osi/dma/mgbe_dma.c @@ -137,9 +137,13 @@ static void mgbe_set_tx_ring_len(struct osi_dma_priv_data *osi_dma, nveu32_t len) { void *addr = osi_dma->base; + nveu32_t value; + MGBE_CHECK_CHAN_BOUND(chan); - osi_writel(len, (nveu8_t *)addr + MGBE_DMA_CHX_TDRL(chan)); + 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)); } /** @@ -214,9 +218,13 @@ static void mgbe_set_rx_ring_len(struct osi_dma_priv_data *osi_dma, nveu32_t len) { void *addr = osi_dma->base; + nveu32_t value; + MGBE_CHECK_CHAN_BOUND(chan); - osi_writel(len, (nveu8_t *)addr + MGBE_DMA_CHX_RDRL(chan)); + 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)); } /** @@ -350,16 +358,24 @@ static void mgbe_stop_dma(struct osi_dma_priv_data *osi_dma, nveu32_t chan) * 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; MGBE_CHECK_CHAN_BOUND(chan); @@ -397,8 +413,32 @@ static void mgbe_configure_dma_channel(nveu32_t chan, MGBE_DMA_CHX_TX_CTRL(chan)); /* Enable OSF mode */ value |= MGBE_DMA_CHX_TX_CTRL_OSP; - /* TxPBL = 16 */ - value |= MGBE_DMA_CHX_TX_CTRL_TXPBL_RECOMMENDED; + + /* + * 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; @@ -415,8 +455,26 @@ static void mgbe_configure_dma_channel(nveu32_t chan, /* clear previous Rx buffer size */ value &= ~MGBE_DMA_CHX_RBSZ_MASK; value |= (osi_dma->rx_buf_len << MGBE_DMA_CHX_RBSZ_SHIFT); - /* RXPBL = 16 */ - value |= MGBE_DMA_CHX_RX_CTRL_RXPBL_RECOMMENDED; + /* 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)); @@ -442,6 +500,20 @@ static void mgbe_configure_dma_channel(nveu32_t chan, 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)); } /** @@ -487,10 +559,41 @@ static void mgbe_dma_chan_to_vmirq_map(struct osi_dma_priv_data *osi_dma) 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], osi_dma); + mgbe_configure_dma_channel(osi_dma->dma_chans[chinx], + owrq, orrq, osi_dma); } mgbe_dma_chan_to_vmirq_map(osi_dma); diff --git a/osi/dma/mgbe_dma.h b/osi/dma/mgbe_dma.h index 480db86..9c3a484 100644 --- a/osi/dma/mgbe_dma.h +++ b/osi/dma/mgbe_dma.h @@ -46,8 +46,8 @@ #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_TDRL(x) ((0x0080U * (x)) + 0x3130U) -#define MGBE_DMA_CHX_RDRL(x) ((0x0080U * (x)) + 0x3134U) +#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) @@ -81,8 +81,6 @@ #define MGBE_DMA_CHX_RX_WDT_RWTU 256U #define MGBE_DMA_CHX_RBSZ_MASK 0x7FFEU #define MGBE_DMA_CHX_RBSZ_SHIFT 1U -#define MGBE_DMA_CHX_TX_CTRL_TXPBL_RECOMMENDED 0x100000U -#define MGBE_DMA_CHX_RX_CTRL_RXPBL_RECOMMENDED 0x100000U #define MGBE_AXI_BUS_WIDTH 0x10U #define MGBE_GLOBAL_DMA_STATUS 0x8700U #define MGBE_DMA_CHX_CTRL_PBLX8 OSI_BIT(16) @@ -105,6 +103,33 @@ #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 /** @} */ /** From 234c211071dc167a67f2d9959ec66e8184f071c5 Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Mon, 13 Apr 2020 18:56:09 +0530 Subject: [PATCH 205/458] nvethernetrm: mgbe: Add XDCS support Enable multiple DMA Channels routing support for MC/BC MAC Address with XDCS. Bug 200565911 Change-Id: I7c9f9347361dd72e68696846a0a59e2e241e20c9 Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> --- include/osi_core.h | 4 + osi/core/mgbe_core.c | 341 ++++++++++++++++++++++++++++++++++--------- osi/core/mgbe_core.h | 48 +++++- 3 files changed, 321 insertions(+), 72 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 6e21410..385fbf7 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -274,6 +274,8 @@ struct osi_filter { 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; }; /** @@ -1000,6 +1002,8 @@ struct osi_core_priv_data { unsigned int fpe_ready; /** TSN stats counters */ struct osi_tsn_stats tsn_stats; + /** MC packets Multiple DMA channel selection flags */ + nveu32_t mc_dmasel; }; /** diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 3161142..ce10599 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -212,6 +212,157 @@ static nveu32_t mgbe_calculate_per_queue_fifo(nveu32_t fifo_size, 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_readl((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_writel(value, (nveu8_t *)base + MGBE_MAC_INDIR_DATA); + + /* Program MAC_Indir_Access_Ctrl */ + addr = osi_readl((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_writel(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_readl((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_writel(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_readl((nveu8_t *)base + MGBE_MAC_INDIR_DATA); + return 0; +} + /** * @brief mgbe_config_l2_da_perfect_inverse_match - configure register for * inverse or perfect match. @@ -312,23 +463,13 @@ static int mgbe_config_mac_pkt_filter_reg(struct osi_core_priv_data *osi_core, } /** - * @brief mgbe_update_mac_addr_helper - Function to update DCS and MBC + * @brief mgbe_filter_args_validate - Validates the filter arguments * - * Algorithm: This helper routine is to update passed prameter value - * based on DCS and MBC parameter. Validation of dma_chan as well as - * dsc_en status performed before updating DCS bits. + * Algorithm: This function just validates all arguments provided by + * the osi_filter structure variable. * * @param[in] osi_core: OSI core private data structure. - * @param[out] value: unsigned int 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 - * @param[in] addr_mask: 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] + * @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. @@ -336,42 +477,67 @@ static int mgbe_config_mac_pkt_filter_reg(struct osi_core_priv_data *osi_core, * @retval 0 on success * @retval -1 on failure. */ -static inline int mgbe_update_mac_addr_helper( - struct osi_core_priv_data *osi_core, - unsigned int *value, - unsigned int idx, - unsigned int dma_routing_enable, - unsigned int dma_chan, unsigned int addr_mask) +static int mgbe_filter_args_validate(struct osi_core_priv_data *const osi_core, + const struct osi_filter *filter) { - int ret = 0; - /* PDC bit of MAC_Ext_Configuration register is not set so binary - * value representation. - */ - if (dma_routing_enable == OSI_ENABLE) { - if ((dma_chan < OSI_MGBE_MAX_NUM_CHANS) && - (osi_core->dcs_en == OSI_ENABLE)) { - *value = ((dma_chan << MGBE_MAC_ADDRH_DCS_SHIFT) & - MGBE_MAC_ADDRH_DCS); - } else if (dma_chan > OSI_MGBE_MAX_NUM_CHANS - 0x1U) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, - "invalid dma channel\n", - (unsigned long long)dma_chan); - ret = -1; - goto err_dma_chan; - } else { - /* Do nothing */ - } + 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; } - /* Address mask validation */ - if (addr_mask <= MGBE_MAB_ADDRH_MBC_MAX_MASK && addr_mask > OSI_NONE) { - *value = (*value | - ((addr_mask << MGBE_MAC_ADDRH_MBC_SHIFT) & - MGBE_MAC_ADDRH_MBC)); + /* 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; } -err_dma_chan: - return ret; + /* 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; } /** @@ -396,20 +562,19 @@ static int mgbe_update_mac_addr_low_high_reg( struct osi_core_priv_data *const osi_core, const struct osi_filter *filter) { - unsigned int idx = filter->index; - unsigned int dma_routing_enable = filter->dma_routing; - unsigned int dma_chan = filter->dma_chan; - unsigned int addr_mask = filter->addr_mask; - unsigned int src_dest = filter->src_dest; - const unsigned char *addr = filter->mac_address; - unsigned int value = 0x0U; - int ret = 0; + 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; + const nveu8_t *addr = filter->mac_address; + nveu32_t dma_chansel = filter->dma_chansel; + nveu32_t value = 0x0U; + nve32_t ret = 0; - /* 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); + /* Validate filter values */ + if (mgbe_filter_args_validate(osi_core, filter) < 0) { + /* Filter argments validation got failed */ return -1; } @@ -420,18 +585,21 @@ static int mgbe_update_mac_addr_low_high_reg( return 0; } - ret = mgbe_update_mac_addr_helper(osi_core, &value, idx, - dma_routing_enable, dma_chan, - addr_mask); - if (ret == -1) { - /* return on helper error */ - return ret; + /* Add DMA channel to value if DCS enabled */ + if ((dma_routing_enable == OSI_ENABLE) && + (osi_core->dcs_en == OSI_ENABLE)) { + value = ((dma_chan << MGBE_MAC_ADDRH_DCS_SHIFT) & + MGBE_MAC_ADDRH_DCS); } - /* Setting Source/Destination Address match valid for 1 to 31 index */ - if ((src_dest == OSI_SA_MATCH || src_dest == OSI_DA_MATCH)) { - value = (value | ((src_dest << MGBE_MAC_ADDRH_SA_SHIFT) & - MGBE_MAC_ADDRH_SA)); + 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_writel(((unsigned int)addr[4] | @@ -446,6 +614,16 @@ static int mgbe_update_mac_addr_low_high_reg( ((unsigned int)addr[3] << 24)), (unsigned char *)osi_core->base + MGBE_MAC_ADDRL((idx))); + /* Write XDCS configuration into MAC_DChSel_IndReg(x) */ + if (dma_routing_enable == OSI_ENABLE) { + /* Append DCS DMA channel to XDCS hot bit selection */ + dma_chansel |= (OSI_ENABLE << dma_chan); + ret = mgbe_mac_indir_addr_write(osi_core, + MGBE_MAC_DCHSEL, + idx, + dma_chansel); + } + return ret; } @@ -2745,7 +2923,12 @@ static nve32_t mgbe_core_init(struct osi_core_priv_data *osi_core, osi_writel(value, (unsigned char *)osi_core->base + MGBE_MTL_RXQ_DMA_MAP2); - /* TODO: DCS enable */ + /* Enable XDCS in MAC_Extended_Configuration */ + value = osi_readl((nveu8_t *)osi_core->base + + MGBE_MAC_EXT_CNF); + value |= MGBE_MAC_EXT_CNF_DDS; + osi_writel(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 */ @@ -3691,6 +3874,16 @@ static inline int mgbe_save_registers( } } + /* 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; } @@ -3762,6 +3955,16 @@ static inline int mgbe_restore_registers( } } + /* 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; } diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index e8132b9..e24c44a 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -78,6 +78,7 @@ #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 @@ -86,6 +87,8 @@ #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 @@ -128,6 +131,40 @@ #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 * @@ -612,6 +649,7 @@ #define MGBE_MTL_EST_ITRE_IEBE OSI_BIT(1) #define MGBE_MTL_EST_ITRE_IECC OSI_BIT(0) #define MGBE_MAC_SBD_INTR OSI_BIT(2) +#define MGBE_MAC_EXT_CNF_DDS OSI_BIT(7) /** @} */ /** @@ -686,7 +724,8 @@ #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_TCR_BAK_IDX ((MGBE_MAC_LPI_EN_TIMER_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)) @@ -772,9 +811,12 @@ /* 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_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)) /** @} */ /** From 84da25b57bdef6bcc805a7e8f130f877649fe313 Mon Sep 17 00:00:00 2001 From: rakesh goyal <rgoyal@nvidia.com> Date: Thu, 4 Jun 2020 14:41:34 +0530 Subject: [PATCH 206/458] nvethernetrm: eqos: fix MAC interrupt handling Issue: 1) Return from irq handler if EQOS_MAC_PCS_LNKSTS is not set without checking FPE interrupt status bit set. 2) Continue MTL interrupt if GCL wrong configured and Frames Scheduling error occur. Fix: 1) As MAC interrupt handler code is updated to support FPE, SW should check for possible interrupt status bits before checking PCS interrupt. 2) Correct FPRQ bit fields 3) Set DFBS bit to drop Frames causing Scheduling Error Bug 200604316 Change-Id: I83d35085707d5efd738090f6147b19d5b931d468 Signed-off-by: rakesh goyal <rgoyal@nvidia.com> --- osi/core/eqos_core.c | 25 +++++++++++++++++-------- osi/core/eqos_core.h | 10 ++++------ 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index ffff202..313c20b 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1796,7 +1796,9 @@ static void eqos_tsn_init(struct osi_core_priv_data *osi_core, /*Loop Count to report Scheduling Error*/ val &= ~EQOS_MTL_EST_CONTROL_LCSE; val |= EQOS_MTL_EST_CONTROL_LCSE_VAL; - osi_writel(val, (unsigned char *)osi_core->base + + /* Drop Frames causing Scheduling Error */ + val |= EQOS_MTL_EST_CONTROL_DFBS; + osi_writel(val, (nveu8_t *)osi_core->base + EQOS_MTL_EST_CONTROL); eqos_enable_mtl_interrupts(osi_core->base); @@ -2039,6 +2041,13 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, 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_writel(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. */ @@ -2075,6 +2084,7 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, } 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); @@ -4174,10 +4184,9 @@ static int eqos_hw_config_est(struct osi_core_priv_data *osi_core, } if (est->en_dis == OSI_DISABLE) { - val = osi_readl((unsigned char *)base + EQOS_MTL_EST_CONTROL); - val &= ~EQOS_MTL_EST_EEST; - osi_writel(val, (unsigned char *)base + EQOS_MTL_EST_CONTROL); - + val = osi_readl((nveu8_t *)base + EQOS_MTL_EST_CONTROL); + val &= ~EQOS_MTL_EST_CONTROL_EEST; + osi_writel(val, (nveu8_t *)base + EQOS_MTL_EST_CONTROL); return 0; } @@ -4240,9 +4249,9 @@ static int eqos_hw_config_est(struct osi_core_priv_data *osi_core, val = osi_readl((unsigned char *)base + EQOS_MTL_EST_CONTROL); /* Store table */ - val |= EQOS_MTL_EST_SSWL; - val |= EQOS_MTL_EST_EEST; - osi_writel(val, (unsigned char *)base + EQOS_MTL_EST_CONTROL); + val |= EQOS_MTL_EST_CONTROL_SSWL; + val |= EQOS_MTL_EST_CONTROL_EEST; + osi_writel(val, (nveu8_t *)base + EQOS_MTL_EST_CONTROL); return ret; } diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 7c6b545..473a7d0 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -245,10 +245,11 @@ OSI_BIT(16)) #define EQOS_MAC_RQC1R_MCBCQ_SHIFT 16U #define EQOS_MAC_RQC1R_MCBCQEN OSI_BIT(20) + #define EQOS_MAC_RQC1R_MCBCQ1 OSI_BIT(16) -#define EQOS_MAC_RQC1R_FPRQ (OSI_BIT(24) | OSI_BIT(26) | \ - OSI_BIT(27)) -#define EQOS_MAC_RQC1R_FPRQ_SHIFT 24U +#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) @@ -509,9 +510,6 @@ #define EQOS_MTL_EST_CONTROL_DDBF OSI_BIT(4) #define EQOS_MTL_EST_CONTROL_SSWL OSI_BIT(1) #define EQOS_MTL_EST_CONTROL_EEST OSI_BIT(0) -/* EST controlOSI_BITmap */ -#define EQOS_MTL_EST_EEST OSI_BIT(0) -#define EQOS_MTL_EST_SSWL OSI_BIT(1) /* EST GCL controlOSI_BITmap */ #define EQOS_MTL_EST_ADDR_SHIFT 8U #define EQOS_MTL_EST_ADDR_MASK (OSI_BIT(8) | OSI_BIT(9) | \ From 1a7eeb9c9b1a1bbc2d49b20a7878590e8b2662b2 Mon Sep 17 00:00:00 2001 From: rakesh goyal <rgoyal@nvidia.com> Date: Wed, 24 Jun 2020 10:45:46 +0530 Subject: [PATCH 207/458] osi: mgbe: add support for PMCBCQ and OVHD Issue: MCBC queue for preemptable packet is default Queue 0 and update Overhead Bytes Value default value is not sufficient as per HW update. Fix: MCBCQ for preemptable packet should be different from express packet Q. Using residual Queue for same. Add OVHD for MGBE as per programming information from HW team. Bug 200561100 Bug 200630202 Change-Id: Ib37e37c4d229b62589e76b1879538cd66707024c Signed-off-by: rakesh goyal <rgoyal@nvidia.com> --- osi/core/mgbe_core.c | 26 ++++++++++++++++++++++++++ osi/core/mgbe_core.h | 16 ++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index ce10599..7af9a3e 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -2845,6 +2845,14 @@ static void mgbe_tsn_init(struct osi_core_priv_data *osi_core, osi_writel(val, (unsigned char *)osi_core->base + MGBE_MTL_EST_CONTROL); + val = osi_readl((nveu8_t *)osi_core->base + + MGBE_MTL_EST_OVERHEAD); + val &= ~MGBE_MTL_EST_OVERHEAD_OVHD; + /* As per hardware programming info */ + val |= OVHD_MGBE_MAC; + osi_writel(val, (nveu8_t *)osi_core->base + + MGBE_MTL_EST_OVERHEAD); + mgbe_enable_mtl_interrupts(osi_core->base); } @@ -2859,6 +2867,16 @@ static void mgbe_tsn_init(struct osi_core_priv_data *osi_core, osi_writel(val, (unsigned char *)osi_core->base + MGBE_MAC_RQC1R); + val = osi_readl((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_writel(val, (nveu8_t *)osi_core->base + + MGBE_MAC_RQC4R); + mgbe_enable_fpe_interrupts(osi_core->base); } @@ -4436,6 +4454,14 @@ static int mgbe_hw_config_fpe(struct osi_core_priv_data *osi_core, osi_core->residual_queue = fpe->rq; osi_writel(val, (unsigned char *)osi_core->base + MGBE_MAC_RQC1R); + val = osi_readl((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_writel(val, (nveu8_t *)osi_core->base + MGBE_MAC_RQC4R); + /* initiate SVER for SMD-V and SMD-R */ val = osi_readl((unsigned char *)osi_core->base + MGBE_MTL_FPE_CTS); val |= MGBE_MAC_FPE_CTS_SVER; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index e24c44a..12ad42e 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -68,6 +68,7 @@ #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 @@ -266,6 +267,7 @@ #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 @@ -441,6 +443,9 @@ #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_FPEIE OSI_BIT(15) #define MGBE_MAC_IMR_FPEIS OSI_BIT(16) @@ -607,6 +612,9 @@ #define MGBE_MTL_EST_CONTROL_DDBF OSI_BIT(4) #define MGBE_MTL_EST_CONTROL_SSWL OSI_BIT(1) #define MGBE_MTL_EST_CONTROL_EEST OSI_BIT(0) +#define MGBE_MTL_EST_OVERHEAD_OVHD (OSI_BIT(0) | OSI_BIT(1) | \ + OSI_BIT(2) | OSI_BIT(3) | \ + OSI_BIT(4) | OSI_BIT(5)) /* EST controlOSI_BITmap */ #define MGBE_MTL_EST_EEST OSI_BIT(0) #define MGBE_MTL_EST_SSWL OSI_BIT(1) @@ -819,6 +827,14 @@ OSI_MGBE_MAX_MAC_ADDRESS_FILTER + 1U)) /** @} */ +/** + * @addtogroup IPG over head + * + * @brief OVHD value for MGBE MAC + * @{ + */ +#define OVHD_MGBE_MAC 56U + /** * @addtogroup MGBE-MAC MGBE MAC HW feature registers * From bfad299d245f5a6b85c61f9a380bed3ca2c7a55c Mon Sep 17 00:00:00 2001 From: Srinivas Ramachandran <srinivasra@nvidia.com> Date: Mon, 30 Nov 2020 14:58:51 -0800 Subject: [PATCH 208/458] nvethernetrm: Add support for MACsec controller This commit adds support for MACsec controller HW operations. The MACsec HW ops can be accessed via osi_core layer. Currently, MACsec HW is enabled when MAC interface is brough up, with no LUT entry so that packets will still be bypassed. MTU check is enabled and default interrupts are enabled for statistics. Bug 2913560 Change-Id: I62e8567fac6603db47f4069a40458038f9b4178a Signed-off-by: Srinivas Ramachandran <srinivasra@nvidia.com> --- include/macsec.h | 1096 +++++++++++++++ include/mmc.h | 46 + include/osi_common.h | 6 +- include/osi_core.h | 60 + include/osi_macsec.h | 596 +++++++++ osi/common/common.h | 27 +- osi/core/macsec.c | 3029 ++++++++++++++++++++++++++++++++++++++++++ osi/core/macsec.h | 536 ++++++++ 8 files changed, 5392 insertions(+), 4 deletions(-) create mode 100644 include/macsec.h create mode 100644 include/osi_macsec.h create mode 100644 osi/core/macsec.c create mode 100644 osi/core/macsec.h diff --git a/include/macsec.h b/include/macsec.h new file mode 100644 index 0000000..313edbf --- /dev/null +++ b/include/macsec.h @@ -0,0 +1,1096 @@ +/* + * 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 MACSEC_H +#define MACSEC_H + +#include <osi_core.h> + +/** + * @addtogroup MACsec AMAP + * + * @brief MACsec controller register offsets + * @{ + */ +#define GCM_KEYTABLE_CONFIG 0x0000 +#define GCM_KEYTABLE_DATA(x) (0x0004 + (x * 4)) +#define RX_ICV_ERR_CNTRL 0x4000 +#define INTERRUPT_COMMON_SR 0x4004 +#define TX_IMR 0x4008 +#define TX_ISR 0x400C +#ifdef NET24 +#define RX_IMR 0x4040 +#define RX_ISR 0x4044 +#else +#define RX_IMR 0x4048 +#define RX_ISR 0x404C +#endif /* NET24 */ +#ifdef NET30 +#define INTERRUPT_MASK1_0 0x40A0 +#define TX_SC_PN_EXHAUSTED_STATUS0_0 0x4024 +#define TX_SC_PN_EXHAUSTED_STATUS1_0 0x4028 +#define TX_SC_PN_THRESHOLD_STATUS0_0 0x4018 +#define TX_SC_PN_THRESHOLD_STATUS1_0 0x401C +#define TX_SC_ERROR_INTERRUPT_STATUS_0 0x402C +#define RX_SC_PN_EXHAUSTED_STATUS0_0 0x405C +#define RX_SC_PN_EXHAUSTED_STATUS1_0 0x4060 +#define RX_SC_REPLAY_ERROR_STATUS0_0 0x4090 +#define RX_SC_REPLAY_ERROR_STATUS1_0 0x4094 +#endif +#define STATS_CONFIG 0x9000 +#ifdef NET30 +#define STATS_CONTROL_0 0x900C +#define TX_PKTS_UNTG_LO_0 0x9010 +#define TX_PKTS_UNTG_HI_0 0x9014 +#define TX_OCTETS_PRTCTD_LO_0 0x9018 +#define TX_OCTETS_PRTCTD_HI_0 0x901C +#define TX_PKTS_TOO_LONG_LO_0 0x9020 +#define TX_PKTS_TOO_LONG_HI_0 0x9024 +#define TX_PKTS_PROTECTED_SCx_LO_0(x) (0x9028 + (x * 8)) +#define TX_PKTS_PROTECTED_SCx_HI_0(x) (0x902C + (x * 8)) +#define RX_PKTS_NOTG_LO_0 0x90B0 +#define RX_PKTS_NOTG_HI_0 0x90B4 +#define RX_PKTS_UNTG_LO_0 0x90A8 +#define RX_PKTS_UNTG_HI_0 0x90AC +#define RX_PKTS_BADTAG_LO_0 0x90B8 +#define RX_PKTS_BADTAG_HI_0 0x90BC +#define RX_PKTS_NOSA_LO_0 0x90C0 +#define RX_PKTS_NOSA_HI_0 0x90C4 +#define RX_PKTS_NOSAERROR_LO_0 0x90C8 +#define RX_PKTS_NOSAERROR_HI_0 0x90CC +#define RX_PKTS_OVRRUN_LO_0 0x90D0 +#define RX_PKTS_OVRRUN_HI_0 0x90D4 +#define RX_OCTETS_VLDTD_LO_0 0x90D8 +#define RX_OCTETS_VLDTD_HI_0 0x90DC +#define RX_PKTS_LATE_SCx_LO_0(x) (0x90E0 + (x * 8)) +#define RX_PKTS_LATE_SCx_HI_0(x) (0x90E4 + (x * 8)) +#define RX_PKTS_NOTVALID_SCx_LO_0(x) (0x9160 + (x * 8)) +#define RX_PKTS_NOTVALID_SCx_HI_0(x) (0x9164 + (x * 8)) +#define RX_PKTS_OK_SCx_LO_0(x) (0x91E0 + (x * 8)) +#define RX_PKTS_OK_SCx_HI_0(x) (0x91E4 + (x * 8)) + +#define TX_INPKTS_CRCIN_NOTVALID_LO_0 0x9260 +#define TX_INPKTS_CRCIN_NOTVALID_HI_0 0x9264 +#define RX_INPKTS_CRCIN_NOTVALID_LO_0 0x9268 +#define RX_INPKTS_CRCIN_NOTVALID_HI_0 0x926C + + +#endif +#define MACSEC_CONTROL0 0xD000 +#define MACSEC_LUT_CONFIG 0xD004 +#define MACSEC_LUT_DATA(x) (0xD008 + (x * 4)) +#ifndef NET24 +#define TX_BYP_LUT_VALID 0xD024 +#define TX_SCI_LUT_VALID 0xD028 +#define RX_BYP_LUT_VALID 0xD02C +#define RX_SCI_LUT_VALID 0xD030 +#endif /* NET24 */ +#ifdef NET24 +#define COMMON_IMR 0xD024 +#define COMMON_ISR 0xD028 +#else +#define COMMON_IMR 0xD054 +#define COMMON_ISR 0xD058 +#endif /* NET24 */ +#ifdef NET30 +#define TX_SC_KEY_INVALID_STS0_0 0XD064 +#define TX_SC_KEY_INVALID_STS1_0 0XD068 +#define RX_SC_KEY_INVALID_STS0_0 0XD080 +#define RX_SC_KEY_INVALID_STS1_0 0XD084 + +#define TX_DEBUG_CONTROL_0 0xD098 +#define TX_DEBUG_TRIGGER_EN_0 0xD09C +#define TX_DEBUG_STATUS_0 0xD0C4 +#define DEBUG_BUF_CONFIG_0 0xD0C8 +#define DEBUG_BUF_DATA_0(x) (0xD0CC + (x * 4)) +#define RX_DEBUG_CONTROL_0 0xD0DC +#define RX_DEBUG_TRIGGER_EN_0 0xD0E0 +#define RX_DEBUG_STATUS_0 0xD0F8 + +#endif /* NET30 */ +#define MACSEC_CONTROL1 0xE000 +#define GCM_AES_CNTRL 0xE004 +#define TX_MTU_LEN 0xE008 +#define TX_SOT_DELAY 0xE010 +#define RX_MTU_LEN 0xE014 +#define RX_SOT_DELAY 0xE01C +#ifdef NET30 +#define MACSEC_TX_DVLAN_CONTROL_0 0xE00C +#define MACSEC_RX_DVLAN_CONTROL_0 0xE018 +#endif +/** @} */ + +/** + * @addtogroup GCM_KEYTABLE_CONFIG register + * + * @brief Bit definitions of GCM_KEYTABLE_CONFIG register + * @{ + */ +#define KT_CONFIG_UPDATE OSI_BIT(31) +#define KT_CONFIG_CTLR_SEL OSI_BIT(25) +#define KT_CONFIG_RW OSI_BIT(24) +#define KT_CONFIG_INDEX_MASK (OSI_BIT(4) | OSI_BIT(3) | OSI_BIT(2) |\ + OSI_BIT(1) | OSI_BIT(0)) +#define KT_ENTRY_VALID OSI_BIT(0) +/** @} */ + +/** + * @addtogroup GCM_KEYTABLE_DATA registers + * + * @brief Bit definitions of GCM_KEYTABLE_DATA register & helpful macros + * @{ + */ +#define KT_ENTRY_VALID OSI_BIT(0) +#define MACSEC_KT_DATA_REG_CNT 13 +#define MACSEC_KT_DATA_REG_SAK_CNT 8 +#define MACSEC_KT_DATA_REG_H_CNT 4 +/** @} */ + +/** + * @addtogroup MACSEC_LUT_CONFIG register + * + * @brief Bit definitions of MACSEC_LUT_CONFIG register + * @{ + */ +#define LUT_CONFIG_UPDATE OSI_BIT(31) +#define LUT_CONFIG_CTLR_SEL OSI_BIT(25) +#define LUT_CONFIG_RW OSI_BIT(24) +#define LUT_CONFIG_LUT_SEL_MASK (OSI_BIT(18) | OSI_BIT(17) |\ + OSI_BIT(16)) +#define LUT_CONFIG_LUT_SEL_SHIFT 16 +#define 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 + * @{ + */ +#ifdef NET30 +#define COMMON_SR_SFTY_ERR OSI_BIT(2) +#endif +#define COMMON_SR_RX OSI_BIT(1) +#define COMMON_SR_TX OSI_BIT(0) +/** @} */ + +/** + * @addtogroup MACSEC_CONTROL0 register + * + * @brief Bit definitions of MACSEC_CONTROL0 register + * @{ + */ +#define TX_LKUP_MISS_NS_INTR OSI_BIT(24) +#define RX_LKUP_MISS_NS_INTR OSI_BIT(23) +#define VALIDATE_FRAMES_MASK (OSI_BIT(22) | OSI_BIT(21)) +#define VALIDATE_FRAMES_DIS 0x0 +#define VALIDATE_FRAMES_STRICT OSI_BIT(22) +#define VALIDATE_FRAMES_CHECK OSI_BIT(21) +#define RX_REPLAY_PROT_EN OSI_BIT(20) +#define RX_LKUP_MISS_BYPASS OSI_BIT(19) +#ifndef NET30 +#define RX_SCI_LUT_EN OSI_BIT(18) +#define RX_BYP_LUT_EN OSI_BIT(17) +#endif +#define RX_EN OSI_BIT(16) +#define TX_LKUP_MISS_BYPASS OSI_BIT(3) +#ifndef NET30 +#define TX_SCI_LUT_EN OSI_BIT(2) +#define TX_BYP_LUT_EN OSI_BIT(1) +#endif +#define TX_EN OSI_BIT(0) +/** @} */ + +/** + * @addtogroup MACSEC_CONTROL1 register + * + * @brief Bit definitions of MACSEC_CONTROL1 register + * @{ + */ +#define LOOPBACK_MODE_EN OSI_BIT(31) +#define RX_MTU_CHECK_EN OSI_BIT(16) +#define TX_LUT_PRIO_BYP OSI_BIT(2) +#define TX_MTU_CHECK_EN OSI_BIT(0) +/** @} */ + +/** + * @addtogroup GCM_AES_CNTRL register + * + * @brief Bit definitions of GCM_AES_CNTRL register + * @{ + */ +#define RX_AES_MODE_MASK (OSI_BIT(17) | OSI_BIT(16)) +#define RX_AES_MODE_AES128 0x0 +#define RX_AES_MODE_AES256 OSI_BIT(17) +#define TX_AES_MODE_MASK (OSI_BIT(1) | OSI_BIT(0)) +#define TX_AES_MODE_AES128 0x0 +#define TX_AES_MODE_AES256 OSI_BIT(1) +/** @} */ + +/** + * @addtogroup COMMON_IMR register + * + * @brief Bit definitions of MACSEC_INTERRUPT_MASK register + * @{ + */ +#define SECURE_REG_VIOL_INT_EN OSI_BIT(31) +#define RX_UNINIT_KEY_SLOT_INT_EN OSI_BIT(17) +#define RX_LKUP_MISS_INT_EN OSI_BIT(16) +#define TX_UNINIT_KEY_SLOT_INT_EN OSI_BIT(1) +#define TX_LKUP_MISS_INT_EN OSI_BIT(0) +/** @} */ + +/** + * @addtogroup TX_IMR register + * + * @brief Bit definitions of TX_INTERRUPT_MASK register + * @{ + */ +#ifdef NET30 +#define TX_DBG_BUF_CAPTURE_DONE_INT_EN OSI_BIT(22) +#else +#define TX_SFTY_ERR_CORR_INT_EN OSI_BIT(26) +#define TX_SFTY_ERR_UNCORR_INT_EN OSI_BIT(25) +#define TX_DBG_BUF_CAPTURE_DONE_INT_EN OSI_BIT(2) +#endif +#define TX_MTU_CHECK_FAIL_INT_EN OSI_BIT(19) +#define TX_AES_GCM_BUF_OVF_INT_EN OSI_BIT(18) +#define TX_SC_AN_NOT_VALID_INT_EN OSI_BIT(17) +#define TX_MAC_CRC_ERROR_INT_EN OSI_BIT(16) +#define TX_PN_EXHAUSTED_INT_EN OSI_BIT(1) +#define TX_PN_THRSHLD_RCHD_INT_EN OSI_BIT(0) +/** @} */ + +/** + * @addtogroup RX_IMR register + * + * @brief Bit definitions of RX_INTERRUPT_MASK register + * @{ + */ +#ifdef NET30 +#define RX_DBG_BUF_CAPTURE_DONE_INT_EN OSI_BIT(22) +#else +#define RX_SFTY_ERR_CORR_INT_EN OSI_BIT(26) +#define RX_SFTY_ERR_UNCORR_INT_EN OSI_BIT(25) +#define RX_SC_AN_NOT_VALID_INT_EN OSI_BIT(17) +#define RX_DBG_BUF_CAPTURE_DONE_INT_EN OSI_BIT(2) +#endif +#define RX_ICV_ERROR_INT_EN OSI_BIT(21) +#define RX_REPLAY_ERROR_INT_EN OSI_BIT(20) +#define RX_MTU_CHECK_FAIL_INT_EN OSI_BIT(19) +#define RX_AES_GCM_BUF_OVF_INT_EN OSI_BIT(18) +#define RX_MAC_CRC_ERROR_INT_EN OSI_BIT(16) +#define RX_PN_EXHAUSTED_INT_EN OSI_BIT(1) +#ifdef NET24 +#define RX_PN_THRSHLD_RCHD_INT_EN OSI_BIT(0) +#endif /* NET24 */ +/** @} */ + +/** + * @addtogroup INTERRUPT_MASK1_0 register + * + * @brief Bit definitions of INTERRUPT_MASK1_0 register + * @{ + */ +#define SFTY_ERR_UNCORR_INT_EN OSI_BIT(0) +/** @} */ + +/** + * @addtogroup COMMON_ISR register + * + * @brief Bit definitions of MACSEC_INTERRUPT_STATUS register + * @{ + */ +#define SECURE_REG_VIOL OSI_BIT(31) +#define RX_UNINIT_KEY_SLOT OSI_BIT(17) +#define RX_LKUP_MISS OSI_BIT(16) +#define TX_UNINIT_KEY_SLOT OSI_BIT(1) +#define TX_LKUP_MISS OSI_BIT(0) +/** @} */ + +/** + * @addtogroup TX_ISR register + * + * @brief Bit definitions of TX_INTERRUPT_STATUS register + * @{ + */ +#ifdef NET30 +#define TX_DBG_BUF_CAPTURE_DONE OSI_BIT(22) +#else +#define TX_SFTY_ERR_CORR OSI_BIT(26) +#define TX_SFTY_ERR_UNCORR OSI_BIT(25) +#define TX_DBG_BUF_CAPTURE_DONE OSI_BIT(2) +#endif +#define TX_MTU_CHECK_FAIL OSI_BIT(19) +#define TX_AES_GCM_BUF_OVF OSI_BIT(18) +#define TX_SC_AN_NOT_VALID OSI_BIT(17) +#define TX_MAC_CRC_ERROR OSI_BIT(16) +#define TX_PN_EXHAUSTED OSI_BIT(1) +#define TX_PN_THRSHLD_RCHD OSI_BIT(0) +/** @} */ + +/** + * @addtogroup RX_ISR register + * + * @brief Bit definitions of RX_INTERRUPT_STATUS register + * @{ + */ +#ifdef NET30 +#define RX_DBG_BUF_CAPTURE_DONE OSI_BIT(22) +#else +#define RX_SFTY_ERR_CORR OSI_BIT(26) +#define RX_SFTY_ERR_UNCORR OSI_BIT(25) +#define RX_SC_AN_NOT_VALID OSI_BIT(17) +#define RX_DBG_BUF_CAPTURE_DONE OSI_BIT(2) +#endif +#define RX_ICV_ERROR OSI_BIT(21) +#define RX_REPLAY_ERROR OSI_BIT(20) +#define RX_MTU_CHECK_FAIL OSI_BIT(19) +#define RX_AES_GCM_BUF_OVF OSI_BIT(18) +#define RX_MAC_CRC_ERROR OSI_BIT(16) +#define RX_PN_EXHAUSTED OSI_BIT(1) +#ifdef NET24 +#define RX_PN_THRSHLD_RCHD OSI_BIT(0) +#endif /* NET24 */ +/** @} */ + +/** + * @addtogroup STATS_CONTROL_0 register + * + * @brief Bit definitions of STATS_CONTROL_0 register + * @{ + */ +#ifdef NET30 +#define STATS_CONTROL0_RD_CPY OSI_BIT(3) +#define STATS_CONTROL0_TK_CPY OSI_BIT(2) +#define STATS_CONTROL0_CNT_RL_OVR_CPY OSI_BIT(1) +#define STATS_CONTROL0_CNT_CLR OSI_BIT(0) +#endif /* NET30 */ +/** @} */ + +/** + * @addtogroup DEBUG_BUF_CONFIG_0 register + * + * @brief Bit definitions of DEBUG_BUF_CONFIG_0 register + * @{ + */ +#define DEBUG_BUF_CONFIG_0_UPDATE OSI_BIT(31) +#define DEBUG_BUF_CONFIG_0_CTLR_SEL OSI_BIT(25) +#define DEBUG_BUF_CONFIG_0_RW OSI_BIT(24) +#define DEBUG_BUF_CONFIG_0_IDX_MASK (OSI_BIT(0) | OSI_BIT(1) | \ + OSI_BIT(2) | OSI_BIT(3)) +/** @} */ + +/** + * @addtogroup TX_DEBUG_TRIGGER_EN_0 register + * + * @brief Bit definitions of TX_DEBUG_TRIGGER_EN_0 register + * @{ + */ +#define TX_DBG_CAPTURE OSI_BIT(10) +#define TX_DBG_ICV_CORRUPT OSI_BIT(9) +#define TX_DBG_CRC_CORRUPT OSI_BIT(8) +#define TX_DBG_DATA_MATCH OSI_BIT(7) +#define TX_DBG_LKUP_MATCH OSI_BIT(6) +#define TX_DBG_CRCOUT_MATCH OSI_BIT(5) +#define TX_DBG_CRCIN_MATCH OSI_BIT(4) +#define TX_DBG_ICV_MATCH OSI_BIT(3) +#define TX_DBG_KEY_NOT_VALID OSI_BIT(2) +#define TX_DBG_AN_NOT_VALID OSI_BIT(1) +#define TX_DBG_LKUP_MISS OSI_BIT(0) +/** @} */ + +/** + * @addtogroup TX_DEBUG_STATUS_0 register + * + * @brief Bit definitions of TX_DEBUG_STATUS_0 register + * @{ + */ +#define TX_DBG_STS_CAPTURE OSI_BIT(10) +#define TX_DBG_STS_ICV_CORRUPT OSI_BIT(9) +#define TX_DBG_STS_CRC_CORRUPT OSI_BIT(8) +#define TX_DBG_STS_DATA_MATCH OSI_BIT(7) +#define TX_DBG_STS_LKUP_MATCH OSI_BIT(6) +#define TX_DBG_STS_CRCOUT_MATCH OSI_BIT(5) +#define TX_DBG_STS_CRCIN_MATCH OSI_BIT(4) +#define TX_DBG_STS_ICV_MATCH OSI_BIT(3) +#define TX_DBG_STS_KEY_NOT_VALID OSI_BIT(2) +#define TX_DBG_STS_AN_NOT_VALID OSI_BIT(1) +#define TX_DBG_STS_LKUP_MISS OSI_BIT(0) +/** @} */ + +/** + * @addtogroup RX_DEBUG_TRIGGER_EN_0 register + * + * @brief Bit definitions of RX_DEBUG_TRIGGER_EN_0 register + * @{ + */ +#define RX_DBG_CAPTURE OSI_BIT(10) +#define RX_DBG_ICV_ERROR OSI_BIT(9) +#define RX_DBG_CRC_CORRUPT OSI_BIT(8) +#define RX_DBG_DATA_MATCH OSI_BIT(7) +#define RX_DBG_BYP_LKUP_MATCH OSI_BIT(6) +#define RX_DBG_CRCOUT_MATCH OSI_BIT(5) +#define RX_DBG_CRCIN_MATCH OSI_BIT(4) +#define RX_DBG_REPLAY_ERR OSI_BIT(3) +#define RX_DBG_KEY_NOT_VALID OSI_BIT(2) +#define RX_DBG_LKUP_MISS OSI_BIT(0) +/** @} */ + +/** + * @addtogroup RX_DEBUG_STATUS_0 register + * + * @brief Bit definitions of RX_DEBUG_STATUS_0 register + * @{ + */ +#define RX_DBG_STS_CAPTURE OSI_BIT(10) +#define RX_DBG_STS_ICV_ERROR OSI_BIT(9) +#define RX_DBG_STS_CRC_CORRUPT OSI_BIT(8) +#define RX_DBG_STS_DATA_MATCH OSI_BIT(7) +#define RX_DBG_STS_BYP_LKUP_MATCH OSI_BIT(6) +#define RX_DBG_STS_CRCOUT_MATCH OSI_BIT(5) +#define RX_DBG_STS_CRCIN_MATCH OSI_BIT(4) +#define RX_DBG_STS_REPLAY_ERR OSI_BIT(3) +#define RX_DBG_STS_KEY_NOT_VALID OSI_BIT(2) +#define RX_DBG_STS_LKUP_MISS OSI_BIT(0) +/** @} */ + +/** + * @addtogroup TX_DEBUG_STATUS_0 register + * + * @brief Bit definitions of TX_DEBUG_STATUS_0 register + * @{ + */ +#define TX_DBG_STS_CAPTURE OSI_BIT(10) +#define TX_DBG_STS_ICV_CORRUPT OSI_BIT(9) +#define TX_DBG_STS_CRC_CORRUPT OSI_BIT(8) +#define TX_DBG_STS_DATA_MATCH OSI_BIT(7) +#define TX_DBG_STS_LKUP_MATCH OSI_BIT(6) +#define TX_DBG_STS_CRCOUT_MATCH OSI_BIT(5) +#define TX_DBG_STS_CRCIN_MATCH OSI_BIT(4) +#define TX_DBG_STS_ICV_MATCH OSI_BIT(3) +#define TX_DBG_STS_KEY_NOT_VALID OSI_BIT(2) +#define TX_DBG_STS_AN_NOT_VALID OSI_BIT(1) +#define TX_DBG_STS_LKUP_MISS OSI_BIT(0) +/** @} */ + +/** + * @addtogroup TX_DEBUG_CONTROL_0 register + * + * @brief Bit definitions of TX_DEBUG_CONTROL_0 register + * @{ + */ +#define TX_DEBUG_CONTROL_0_START_CAP OSI_BIT(31) +/** @} */ + +/** + * @addtogroup RX_DEBUG_CONTROL_0 register + * + * @brief Bit definitions of RX_DEBUG_CONTROL_0 register + * @{ + */ +#define RX_DEBUG_CONTROL_0_START_CAP OSI_BIT(31) +/** @} */ + +#define MTU_LENGTH_MASK 0xFFFF +/* MACsec sectag + ICV adds upto 32B */ +#define MACSEC_TAG_ICV_LEN 32 +/* Add 8B for double VLAN tags (4B each), + * 14B for L2 SA/DA/ethertype, TODO - as per IAS SA/DA is ignored from length + * 4B for FCS + */ +#define MTU_ADDONS (8 + 14 + 4) +#define DVLAN_TAG_ETHERTYPE 0x88A8 +#ifndef NET24 +/** + * @addtogroup TX/RX_BYP/SCI_LUT_VALID register + * + * @brief Bit definitions of LUT_VALID registers + * @{ + */ +#define TX_BYP_LUT_VALID_ENTRY(x) OSI_BIT(x) +#define TX_BYP_LUT_VALID_NONE 0x0 +#define TX_SCI_LUT_VALID_ENTRY(x) OSI_BIT(x) +#define TX_SCI_LUT_VALID_NONE 0x0 +#define RX_BYP_LUT_VALID_ENTRY(x) OSI_BIT(x) +#define RX_BYP_LUT_VALID_NONE 0x0 +#define RX_SCI_LUT_VALID_ENTRY(x) OSI_BIT(x) +#define RX_SCI_LUT_VALID_NONE 0x0 +/** @} */ +#endif /* NET24 */ + +/** + * @addtogroup TX/RX LUT bit fields in LUT_DATA registers + * + * @brief Helper macros for LUT data programming + * @{ + */ +#define MACSEC_LUT_DATA_REG_CNT 7 +/* Bit Offsets for LUT DATA[x] registers for various lookup field masks */ +/* DA mask bits in LUT_DATA[1] register */ +#define LUT_DA_BYTE0_INACTIVE OSI_BIT(16) +#define LUT_DA_BYTE1_INACTIVE OSI_BIT(17) +#define LUT_DA_BYTE2_INACTIVE OSI_BIT(18) +#define LUT_DA_BYTE3_INACTIVE OSI_BIT(19) +#define LUT_DA_BYTE4_INACTIVE OSI_BIT(20) +#define LUT_DA_BYTE5_INACTIVE OSI_BIT(21) +/* SA mask bits in LUT_DATA[3] register */ +#define LUT_SA_BYTE0_INACTIVE OSI_BIT(6) +#define LUT_SA_BYTE1_INACTIVE OSI_BIT(7) +#define LUT_SA_BYTE2_INACTIVE OSI_BIT(8) +#define LUT_SA_BYTE3_INACTIVE OSI_BIT(9) +#define LUT_SA_BYTE4_INACTIVE OSI_BIT(10) +#define LUT_SA_BYTE5_INACTIVE OSI_BIT(11) +/* Ether type mask in LUT_DATA[3] register */ +#define LUT_ETHTYPE_INACTIVE OSI_BIT(28) +/* VLAN PCP mask in LUT_DATA[4] register */ +#define LUT_VLAN_PCP_INACTIVE OSI_BIT(0) +/* VLAN ID mask in LUT_DATA[4] register */ +#define LUT_VLAN_ID_INACTIVE OSI_BIT(13) +/* VLAN mask in LUT_DATA[4] register */ +#define LUT_VLAN_ACTIVE OSI_BIT(14) +/* Byte pattern masks in LUT_DATA[4] register */ +#define LUT_BYTE0_PATTERN_INACTIVE OSI_BIT(29) +/* Byte pattern masks in LUT_DATA[5] register */ +#define LUT_BYTE1_PATTERN_INACTIVE OSI_BIT(12) +#define LUT_BYTE2_PATTERN_INACTIVE OSI_BIT(27) +/* Byte pattern masks in LUT_DATA[6] register */ +#define LUT_BYTE3_PATTERN_INACTIVE OSI_BIT(10) +/* Preemptible packet in LUT_DATA[6] register */ +#define LUT_PREEMPT OSI_BIT(11) +/* Preempt mask in LUT_DATA[6] register */ +#define LUT_PREEMPT_INACTIVE OSI_BIT(12) +/* Controlled port mask in LUT_DATA[6] register */ +#define LUT_CONTROLLED_PORT OSI_BIT(13) +#ifdef NET30 +/* DVLAN packet in LUT_DATA[6] register */ +#define 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) +#else +/* BYP LUT entry valid in LUT_DATA[6] register */ +#define BYP_LUT_ENTRY_VALID OSI_BIT(14) +#endif /* NET30 */ +/* AN valid bits for SCI LUT in LUT_DATA[6] register */ +#define LUT_AN0_VALID OSI_BIT(13) +#define LUT_AN1_VALID OSI_BIT(14) +#define LUT_AN2_VALID OSI_BIT(15) +#define LUT_AN3_VALID OSI_BIT(16) +#ifdef NET30 +/* DVLAN packet in LUT_DATA[6] register */ +#define TX_SCI_LUT_DVLAN_PKT OSI_BIT(21) +/* DVLAN outer/inner tag select in LUT_DATA[6] register */ +#define TX_SCI_LUT_DVLAN_OUTER_INNER_TAG_SEL OSI_BIT(22) +#else +/* SCI LUT entry valid in LUT_DATA[6] register */ +#define TX_SCI_LUT_ENTRY_VALID OSI_BIT(21) +#endif /* NET30 */ +/* SA State LUT entry valid in LUT_DATA[0] register */ +#define SA_STATE_LUT_ENTRY_VALID OSI_BIT(0) + +/* Rx LUT macros */ +/* Preemptible packet in LUT_DATA[2] register for Rx SCI */ +#define RX_SCI_LUT_PREEMPT OSI_BIT(8) +/* Preempt mask in LUT_DATA[2] register for Rx SCI */ +#define RX_SCI_LUT_PREEMPT_INACTIVE OSI_BIT(9) +#ifndef NET30 +/* Rx SCI LUT entry valid in LUT_DATA[2] register */ +#define RX_SCI_LUT_ENTRY_VALID OSI_BIT(14) +#endif /* NET30 */ +/* TODO - Invalidate the valid bits for above LUT_ENTRY_VALIDs in write path */ +/** @} */ + +////////////////////////////////////////////////////////////////////////// + /* MACsec OSI data structures */ +////////////////////////////////////////////////////////////////////////// + +/** + * @addtogroup TX/RX BYP/SCI LUT INPUT macros + * + * @brief Helper macros for LUT input programming + * @{ + */ +//TODO - Aggregate all the macros inlined in the struct itself +/** @} */ + +/** + * @brief MACsec secure channel basic information + */ +struct osi_macsec_sc_info { + /** Secure channel identifier */ +#define SCI_LEN 8 + unsigned char sci[SCI_LEN]; + /** Secure association key */ +#define KEY_LEN_128 16 +#define KEY_LEN_256 32 + unsigned char sak[KEY_LEN_128]; + /** current AN */ + unsigned char curr_an; + /** Next PN to use for the current AN */ + unsigned int next_pn; + /** == BELOW FIELDS ARE FILLED BY OSI LAYER == */ + /** bitmap of valid AN */ +#define AN0_VALID OSI_BIT(0) +#define AN1_VALID OSI_BIT(1) +#define AN2_VALID OSI_BIT(2) +#define AN3_VALID OSI_BIT(3) + unsigned int an_valid; + /** SC LUT index */ + unsigned int sc_idx_start; +}; + +/** + * @brief MACsec HW controller LUT's overall status + */ +struct osi_macsec_lut_status { + /** List of max SC's supported */ +#define MAX_NUM_SC 8 +#define MAX_NUM_SA 4 + struct osi_macsec_sc_info sc_info[MAX_NUM_SC]; + /** next available BYP LUT index */ + unsigned int next_byp_idx; + /** next available SC LUT index */ + unsigned int next_sc_idx; +}; + +/** + * @brief MACsec SA State LUT entry outputs structure + */ +struct sa_state_outputs { + /** Next PN to use */ + unsigned int next_pn; + /** Lowest PN to use */ + unsigned int lowest_pn; +}; + +/** + * @brief MACsec SC State LUT entry outputs structure + */ +struct sc_state_outputs { + /** Current AN to use */ +#define CURR_AN_MAX 3 /* 0-3 */ + unsigned int curr_an; +}; + +/** + * @brief MACsec SC Param LUT entry outputs structure + */ +struct sc_param_outputs { + /** Key index start */ +#define KEY_INDEX_MAX 31 /* 0-31 */ + unsigned int key_index_start; + /** PN max for given AN, after which HW will roll over to next AN */ +#define PN_MAX_DEFAULT 0xFFFFFFFF + unsigned int pn_max; + /** PN threshold to trigger irq when threshold is reached */ +#define PN_THRESHOLD_DEFAULT 0xC0000000 + unsigned int pn_threshold; + /** PN window */ + unsigned int pn_window; + /** SC identifier */ + unsigned char sci[SCI_LEN]; + /** Default TCI value V=1, ES=0, SC = 1 */ +#define TCI_DEFAULT 0x1 + /** TCI 3 bits V=0, ES=0, SC=1 */ + unsigned char tci; +#define VLAN_IN_CLEAR_DEFAULT 0x0 + /** vlan in clear config */ + unsigned char vlan_in_clear; +}; + +/** + * @brief MACsec SCI LUT entry outputs structure + */ +struct sci_lut_outputs { + /** SC index to use */ +#define SC_INDEX_MAX 15 /* 0-15 */ + unsigned int sc_index; + /** SC identifier */ + unsigned char sci[SCI_LEN]; + /** AN's valid */ + unsigned int an_valid; +}; + +/** + * @brief MACsec BYP/SCI LUT entry inputs structure + */ +struct lut_inputs { + /** MAC DA to compare */ + unsigned char da[OSI_ETH_ALEN]; + /** MAC SA to compare */ + unsigned char sa[OSI_ETH_ALEN]; + /** Ethertype to compare */ +#define ETHTYPE_LEN 2 + unsigned char ethtype[ETHTYPE_LEN]; + /** 4-Byte pattern to compare */ +#define LUT_BYTE_PATTERN_MAX 4 + unsigned char byte_pattern[LUT_BYTE_PATTERN_MAX]; + /** Offset for 4-Byte pattern to compare */ +#define LUT_BYTE_PATTERN_MAX_OFFSET 63 /* 0-63 */ + unsigned int byte_pattern_offset[LUT_BYTE_PATTERN_MAX]; + /** VLAN PCP to compare */ +#define VLAN_PCP_MAX 7 /* 0-7 */ + unsigned int vlan_pcp; + /** VLAN ID to compare */ +#define VLAN_ID_MAX 4095 /* 1-4095 */ + unsigned int vlan_id; +}; + +/** + * @brief MACsec LUT config data structure + */ +struct macsec_table_config { + /** Controller select + * 0 - Tx + * 1 - Rx + */ +#define CTLR_SEL_TX 0U +#define CTLR_SEL_RX 1U +#define CTLR_SEL_MAX 1U +#define NUM_CTLR 2U + unsigned short ctlr_sel; + /** Read or write operation select + * 0 - Read + * 1 - Write + */ +#define LUT_READ 0U +#define LUT_WRITE 1U +#define RW_MAX 1U + unsigned short rw; + /** Table entry index */ +#define TABLE_INDEX_MAX 31U /* 0-31 */ +#define BYP_LUT_MAX_INDEX TABLE_INDEX_MAX +#define SC_LUT_MAX_INDEX 15U +#define SA_LUT_MAX_INDEX TABLE_INDEX_MAX + unsigned short index; +}; + +/** + * @brief MACsec LUT config data structure + */ +struct osi_macsec_lut_config { + /** Generic table config */ + struct macsec_table_config table_config; + /** LUT select */ +#define LUT_SEL_BYPASS 0U +#define LUT_SEL_SCI 1U +#define LUT_SEL_SC_PARAM 2U +#define LUT_SEL_SC_STATE 3U +#define LUT_SEL_SA_STATE 4U +#define LUT_SEL_MAX 4U /* 0-4 */ + unsigned short lut_sel; + /** flag - encoding various valid bits for above fields */ + unsigned int flags; +//LUT input fields flags bit offsets +#define LUT_FLAGS_DA_BYTE0_VALID OSI_BIT(0) +#define LUT_FLAGS_DA_BYTE1_VALID OSI_BIT(1) +#define LUT_FLAGS_DA_BYTE2_VALID OSI_BIT(2) +#define LUT_FLAGS_DA_BYTE3_VALID OSI_BIT(3) +#define LUT_FLAGS_DA_BYTE4_VALID OSI_BIT(4) +#define LUT_FLAGS_DA_BYTE5_VALID OSI_BIT(5) +#define LUT_FLAGS_DA_VALID (OSI_BIT(0) | OSI_BIT(1) | OSI_BIT(2) |\ + OSI_BIT(3) | OSI_BIT(4) | OSI_BIT(5)) +#define LUT_FLAGS_SA_BYTE0_VALID OSI_BIT(6) +#define LUT_FLAGS_SA_BYTE1_VALID OSI_BIT(7) +#define LUT_FLAGS_SA_BYTE2_VALID OSI_BIT(8) +#define LUT_FLAGS_SA_BYTE3_VALID OSI_BIT(9) +#define LUT_FLAGS_SA_BYTE4_VALID OSI_BIT(10) +#define LUT_FLAGS_SA_BYTE5_VALID OSI_BIT(11) +#define LUT_FLAGS_SA_VALID (OSI_BIT(6) | OSI_BIT(7) | OSI_BIT(8) |\ + OSI_BIT(9) | OSI_BIT(10) | OSI_BIT(11)) +#define LUT_FLAGS_ETHTYPE_VALID OSI_BIT(12) +#define LUT_FLAGS_VLAN_PCP_VALID OSI_BIT(13) +#define LUT_FLAGS_VLAN_ID_VALID OSI_BIT(14) +#define LUT_FLAGS_VLAN_VALID OSI_BIT(15) +#define LUT_FLAGS_BYTE0_PATTERN_VALID OSI_BIT(16) +#define LUT_FLAGS_BYTE1_PATTERN_VALID OSI_BIT(17) +#define LUT_FLAGS_BYTE2_PATTERN_VALID OSI_BIT(18) +#define LUT_FLAGS_BYTE3_PATTERN_VALID OSI_BIT(19) +#define LUT_FLAGS_PREEMPT OSI_BIT(20) +#define LUT_FLAGS_PREEMPT_VALID OSI_BIT(21) +#define LUT_FLAGS_CONTROLLED_PORT OSI_BIT(22) +#define LUT_FLAGS_DVLAN_PKT OSI_BIT(23) +#define LUT_FLAGS_DVLAN_OUTER_INNER_TAG_SEL OSI_BIT(24) +#define LUT_FLAGS_ENTRY_VALID OSI_BIT(31) + /** LUT inputs */ + struct lut_inputs lut_in; + /** SCI LUT outputs */ + struct sci_lut_outputs sci_lut_out; + /** SC Param outputs */ + struct sc_param_outputs sc_param_out; + /** SC State outputs */ + struct sc_state_outputs sc_state_out; + /** SA State outputs */ + struct sa_state_outputs sa_state_out; +}; + +/** + * @brief MACsec KT entry structure + */ +struct kt_entry { + /** SAK key - max 256bit */ + unsigned char sak[KEY_LEN_256]; + /** H-key */ + unsigned char h[KEY_LEN_128]; +}; + +/** + * @brief MACsec KT config data structure + */ +struct osi_macsec_kt_config { + /** Generic table config */ + struct macsec_table_config table_config; + /** KT entry */ + struct kt_entry entry; + /** flag - encoding various valid bits */ + unsigned int flags; +}; + +/** + * @brief MACsec Debug buffer data structure + */ +struct osi_macsec_dbg_buf_config { + /** Controller select + * 0 - Tx + * 1 - Rx + */ + unsigned short ctlr_sel; + /** Read or write operation select + * 0 - Read + * 1 - Write + */ +#define DBG_TBL_READ LUT_READ +#define DBG_TBL_WRITE LUT_WRITE + unsigned short rw; + /* Num of Tx debug buffers */ +#define TX_DBG_BUF_IDX_MAX 12U + /* Num of Rx debug buffers */ +#define RX_DBG_BUF_IDX_MAX 13U +#define DBG_BUF_IDX_MAX RX_DBG_BUF_IDX_MAX + /** debug data buffer */ + unsigned int dbg_buf[4]; + /** flag - encoding various debug event bits */ +#define TX_DBG_LKUP_MISS_EVT OSI_BIT(0) +#define TX_DBG_AN_NOT_VALID_EVT OSI_BIT(1) +#define TX_DBG_KEY_NOT_VALID_EVT OSI_BIT(2) +#define TX_DBG_CRC_CORRUPT_EVT OSI_BIT(3) +#define TX_DBG_ICV_CORRUPT_EVT OSI_BIT(4) +#define TX_DBG_CAPTURE_EVT OSI_BIT(5) +#define RX_DBG_LKUP_MISS_EVT OSI_BIT(6) +#define RX_DBG_KEY_NOT_VALID_EVT OSI_BIT(7) +#define RX_DBG_REPLAY_ERR_EVT OSI_BIT(8) +#define RX_DBG_CRC_CORRUPT_EVT OSI_BIT(9) +#define RX_DBG_ICV_ERROR_EVT OSI_BIT(10) +#define RX_DBG_CAPTURE_EVT OSI_BIT(11) + unsigned int flags; + /** debug buffer index */ + unsigned int index; +}; + +/** + * @brief MACsec core operations structure + */ +struct macsec_core_ops { + /** macsec init */ + int (*init)(struct osi_core_priv_data *const osi_core); + /** macsec de-init */ + void (*deinit)(struct osi_core_priv_data *const osi_core); + /** NS irq handler */ + void (*handle_ns_irq)(struct osi_core_priv_data *const osi_core); + /** S irq handler */ + void (*handle_s_irq)(struct osi_core_priv_data *const osi_core); + /** macsec lut config */ + int (*lut_config)(struct osi_core_priv_data *const osi_core, + struct osi_macsec_lut_config *const lut_config); + /** macsec kt config */ + int (*kt_config)(struct osi_core_priv_data *const osi_core, + struct osi_macsec_kt_config *const kt_config); + /** macsec loopback config */ + int (*loopback_config)(struct osi_core_priv_data *const osi_core, + unsigned int enable); + /** macsec enable */ + int (*macsec_en)(struct osi_core_priv_data *const osi_core, + unsigned int enable); + /** macsec config SA in HW LUT */ + int (*config)(struct osi_core_priv_data *const osi_core, + struct osi_macsec_sc_info *const sc, + unsigned int enable, unsigned short ctlr); + /** macsec read mmc counters */ + void (*read_mmc)(struct osi_core_priv_data *const osi_core); + /** macsec debug buffer config */ + int (*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 */ + int (*dbg_events_config)(struct osi_core_priv_data *const osi_core, + struct osi_macsec_dbg_buf_config *const dbg_buf_config); + +}; + +////////////////////////////////////////////////////////////////////////// + /* OSI interface API prototypes */ +////////////////////////////////////////////////////////////////////////// + +/** + * @brief initializing the macsec core operations + * + * @param[in] osi_core: OSI core private data structure. + * + * @retval 0 on success + * @retval -1 on failure + */ +int osi_init_macsec_ops(struct osi_core_priv_data *const osi_core); + +/** + * @brief initialize the macsec controller + * + * @param[in] osi_core: OSI core private data structure. + * + * @retval 0 on success + * @retval -1 on failure + */ +int osi_macsec_init(struct osi_core_priv_data *const osi_core); + +/** + * @brief De-initialize the macsec controller + * + * @param[in] osi_core: OSI core private data structure. + * + */ +void osi_macsec_deinit(struct osi_core_priv_data *const osi_core); + +/** + * @brief Non-secure irq handler + * + * @param[in] osi_core: OSI core private data structure. + * + * @retval None + */ +void osi_macsec_ns_isr(struct osi_core_priv_data *const osi_core); + +/** + * @brief Secure irq handler + * + * @param[in] osi_core: OSI core private data structure. + * + * @retval None + */ +void osi_macsec_s_isr(struct osi_core_priv_data *const osi_core); + +/** + * @brief MACsec Lookup table config + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] lut_config: OSI macsec LUT config data structure. + * + * @retval 0 on success + * @retval -1 on failure + */ +int osi_macsec_lut_config(struct osi_core_priv_data *const osi_core, + struct osi_macsec_lut_config *const lut_confg); + +/** + * @brief MACsec key table config + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] kt_config: OSI macsec KT config data structure. + * + * @retval 0 on success + * @retval -1 on failure + */ +int osi_macsec_kt_config(struct osi_core_priv_data *const osi_core, + struct osi_macsec_kt_config *const kt_config); + +/** + * @brief MACsec Loopback config + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] enable: Loopback enable/disable flag. + * + * @retval 0 on success + * @retval -1 on failure + */ +int osi_macsec_loopback(struct osi_core_priv_data *const osi_core, + unsigned int enable); + +/** + * @brief MACsec Enable + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] enable: macsec controller Tx/Rx enable/disable flag. + * + * @retval 0 on success + * @retval -1 on failure + */ +int osi_macsec_en(struct osi_core_priv_data *const osi_core, + unsigned int enable); + +/** + * @brief MACsec update secure channel/association in controller + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] tx_sa: Pointer to osi_macsec_sc_info struct for the tx SA. + * @param[in] enable: flag to indicate enable/disable for the Tx SA. + * + * @retval 0 on success + * @retval -1 on failure + */ +int osi_macsec_config(struct osi_core_priv_data *const osi_core, + struct osi_macsec_sc_info *const sc, + unsigned int enable, unsigned short ctlr); + +/** + * @brief MACsec read statistics counters + * + * @param[in] osi_core: OSI core private data structure. + * + * @retval 0 on success + * @retval -1 on failure + */ +int osi_macsec_read_mmc(struct osi_core_priv_data *const osi_core); + +/** + * @brief MACsec debug buffer config + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] dbg_buf_config: OSI macsec debug buffer config data structure. + * + * @retval 0 on success + * @retval -1 on failure + */ +int osi_macsec_dbg_buf_config( + struct osi_core_priv_data *const osi_core, + struct osi_macsec_dbg_buf_config *const dbg_buf_config); + +/** + * @brief MACsec debug events config + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] dbg_buf_config: OSI macsec debug buffer config data structure. + * + * @retval 0 on success + * @retval -1 on failure + */ +int osi_macsec_dbg_events_config( + struct osi_core_priv_data *const osi_core, + struct osi_macsec_dbg_buf_config *const dbg_buf_config); + +#endif /* MACSEC_H */ diff --git a/include/mmc.h b/include/mmc.h index b9a88eb..672b1ea 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -579,4 +579,50 @@ struct osi_xtra_stat_counters { /** link disconnect count */ nveu64_t link_disconnect_count; }; + +/** + * @brief The structure hold macsec statistics counters + */ +struct osi_macsec_mmc_counters { + /** This counter provides the number of controller port macsec + * untaged packets */ + unsigned long long rx_pkts_no_tag; + /** This counter provides the number of controller port macsec + * untaged packets validateFrame != strict */ + unsigned long long rx_pkts_untagged; + /** This counter provides the number of invalid tag or icv packets */ + unsigned long long rx_pkts_bad_tag; + /** This counter provides the number of no sc lookup hit or sc match + * packets */ + unsigned long long rx_pkts_no_sa_err; + /** This counter provides the number of no sc lookup hit or sc match + * packets validateFrame != strict */ + unsigned long long rx_pkts_no_sa; + /** This counter provides the number of late packets + *received PN < lowest PN */ + unsigned long long rx_pkts_late[OSI_MACSEC_SC_INDEX_MAX]; + /** This counter provides the number of overrun packets */ + unsigned long long rx_pkts_overrun; + /** This counter provides the number of octets after IVC passing */ + unsigned long long rx_octets_validated; + /** This counter provides the number not valid packets */ + unsigned long long rx_pkts_not_valid[OSI_MACSEC_SC_INDEX_MAX]; + /** This counter provides the number of invalid packets */ + unsigned long long in_pkts_invalid[OSI_MACSEC_SC_INDEX_MAX]; + /** This counter provides the number of in packet delayed */ + unsigned long long rx_pkts_delayed[OSI_MACSEC_SC_INDEX_MAX]; + /** This counter provides the number of in packets un checked */ + unsigned long long rx_pkts_unchecked[OSI_MACSEC_SC_INDEX_MAX]; + /** This counter provides the number of in packets ok */ + unsigned long long rx_pkts_ok[OSI_MACSEC_SC_INDEX_MAX]; + /** This counter provides the number of out packets untaged */ + unsigned long long tx_pkts_untaged; + /** This counter provides the number of out too long */ + unsigned long long tx_pkts_too_long; + /** This counter provides the number of out packets protected */ + unsigned long long tx_pkts_protected[OSI_MACSEC_SC_INDEX_MAX]; + /** This counter provides the number of out octets protected */ + unsigned long long tx_octets_protected; +}; + #endif diff --git a/include/osi_common.h b/include/osi_common.h index 67e76d0..93f7e36 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -188,6 +188,9 @@ #define OSI_MGBE_MAX_NUM_CHANS 10U #define OSI_MGBE_MAX_NUM_QUEUES 10U +/* 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 @@ -294,7 +297,8 @@ * - Run time: Yes * - De-initialization: No * - * @return nveu64_t value + * @retval 0 on sucess + * @retval -1 on failure */ static inline nveu64_t osi_update_stats_counter(nveu64_t last_value, nveu64_t incr) diff --git a/include/osi_core.h b/include/osi_core.h index 385fbf7..23abf62 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -911,6 +911,52 @@ struct osd_core_ops { nve32_t (*ivc_send)(void *priv, void *data, nveu32_t len); }; +#ifdef MACSEC_SUPPORT +/** + * @brief MACsec interrupt stats structure. + */ +struct osi_macsec_irq_stats { + /** Tx debug buffer capture done */ + unsigned long tx_dbg_capture_done; + /** Tx MTU check failed */ + unsigned long tx_mtu_check_fail; + /** Tx MAC CRC err */ + unsigned long tx_mac_crc_error; + /** Tx SC AN not valid */ + unsigned long tx_sc_an_not_valid; + /** Tx AES GCM buffer overflow */ + unsigned long tx_aes_gcm_buf_ovf; + /** Tx LUT lookup miss */ + unsigned long tx_lkup_miss; + /** Tx uninitialized key slot */ + unsigned long tx_uninit_key_slot; + /** Tx PN threshold reached */ + unsigned long tx_pn_threshold; + /** Tx PN exhausted */ + unsigned long tx_pn_exhausted; + /** Tx debug buffer capture done */ + unsigned long rx_dbg_capture_done; + /** Rx ICV error threshold */ + unsigned long rx_icv_err_threshold; + /** Rx replay error */ + unsigned long rx_replay_error; + /** Rx MTU check failed */ + unsigned long rx_mtu_check_fail; + /** Rx MAC CRC err */ + unsigned long rx_mac_crc_error; + /** Rx AES GCM buffer overflow */ + unsigned long rx_aes_gcm_buf_ovf; + /** Rx LUT lookup miss */ + unsigned long rx_lkup_miss; + /** Rx uninitialized key slot */ + unsigned long rx_uninit_key_slot; + /** Rx PN exhausted */ + unsigned long rx_pn_exhausted; + /** Secure reg violation */ + unsigned long secure_reg_viol; +}; +#endif /* MACSEC_SUPPORT */ + /** * @brief The OSI Core (MAC & MTL) private data structure. */ @@ -921,6 +967,20 @@ struct osi_core_priv_data { void *dma_base; /** Memory mapped base address of XPCS IP */ void *xpcs_base; +#ifdef MACSEC_SUPPORT + /** Memory mapped base address of MACsec IP */ + void *macsec_base; + /** Memory mapped base address of MACsec TZ page */ + void *tz_base; + /** Address of MACsec HW operations structure */ + struct 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; + /** macsec mmc counters */ + struct osi_macsec_mmc_counters macsec_mmc; +#endif /* MACSEC_SUPPORT */ /** Pointer to OSD private data structure */ void *osd; /** OSD callback ops structure */ diff --git a/include/osi_macsec.h b/include/osi_macsec.h new file mode 100644 index 0000000..c5c015c --- /dev/null +++ b/include/osi_macsec.h @@ -0,0 +1,596 @@ +/* + * 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_OSI_MACSEC_H +#define INCLUDED_OSI_MACSEC_H + +#include <osi_core.h> + +////////////////////////////////////////////////////////////////////////// + /* MACsec OSI data structures */ +////////////////////////////////////////////////////////////////////////// + +/** + * @addtogroup TX/RX BYP/SCI LUT helpers macros + * + * @brief Helper macros for LUT programming + * @{ + */ +#define SCI_LEN 8 +#define KEY_LEN_128 16 +#define KEY_LEN_256 32 +#define AN0_VALID OSI_BIT(0) +#define AN1_VALID OSI_BIT(1) +#define AN2_VALID OSI_BIT(2) +#define AN3_VALID OSI_BIT(3) +#define MAX_NUM_SC 8 +#define MAX_NUM_SA 4 +#define CURR_AN_MAX 3 /* 0-3 */ +#define KEY_INDEX_MAX 31 /* 0-31 */ +#define PN_MAX_DEFAULT 0xFFFFFFFF +#define PN_THRESHOLD_DEFAULT 0xC0000000 +#define TCI_DEFAULT 0x1 +#define VLAN_IN_CLEAR_DEFAULT 0x0 +#define SC_INDEX_MAX 15 /* 0-15 */ +#define ETHTYPE_LEN 2 +#define LUT_BYTE_PATTERN_MAX 4 +#define LUT_BYTE_PATTERN_MAX_OFFSET 63 /* 0-63 */ +#define VLAN_PCP_MAX 7 /* 0-7 */ +#define VLAN_ID_MAX 4095 /* 1-4095 */ + +#define LUT_SEL_BYPASS 0U +#define LUT_SEL_SCI 1U +#define LUT_SEL_SC_PARAM 2U +#define LUT_SEL_SC_STATE 3U +#define LUT_SEL_SA_STATE 4U +#define LUT_SEL_MAX 4U /* 0-4 */ + +/* LUT input fields flags bit offsets */ +#define LUT_FLAGS_DA_BYTE0_VALID OSI_BIT(0) +#define LUT_FLAGS_DA_BYTE1_VALID OSI_BIT(1) +#define LUT_FLAGS_DA_BYTE2_VALID OSI_BIT(2) +#define LUT_FLAGS_DA_BYTE3_VALID OSI_BIT(3) +#define LUT_FLAGS_DA_BYTE4_VALID OSI_BIT(4) +#define LUT_FLAGS_DA_BYTE5_VALID OSI_BIT(5) +#define LUT_FLAGS_DA_VALID (OSI_BIT(0) | OSI_BIT(1) | OSI_BIT(2) |\ + OSI_BIT(3) | OSI_BIT(4) | OSI_BIT(5)) +#define LUT_FLAGS_SA_BYTE0_VALID OSI_BIT(6) +#define LUT_FLAGS_SA_BYTE1_VALID OSI_BIT(7) +#define LUT_FLAGS_SA_BYTE2_VALID OSI_BIT(8) +#define LUT_FLAGS_SA_BYTE3_VALID OSI_BIT(9) +#define LUT_FLAGS_SA_BYTE4_VALID OSI_BIT(10) +#define LUT_FLAGS_SA_BYTE5_VALID OSI_BIT(11) +#define LUT_FLAGS_SA_VALID (OSI_BIT(6) | OSI_BIT(7) | OSI_BIT(8) |\ + OSI_BIT(9) | OSI_BIT(10) | OSI_BIT(11)) +#define LUT_FLAGS_ETHTYPE_VALID OSI_BIT(12) +#define LUT_FLAGS_VLAN_PCP_VALID OSI_BIT(13) +#define LUT_FLAGS_VLAN_ID_VALID OSI_BIT(14) +#define LUT_FLAGS_VLAN_VALID OSI_BIT(15) +#define LUT_FLAGS_BYTE0_PATTERN_VALID OSI_BIT(16) +#define LUT_FLAGS_BYTE1_PATTERN_VALID OSI_BIT(17) +#define LUT_FLAGS_BYTE2_PATTERN_VALID OSI_BIT(18) +#define LUT_FLAGS_BYTE3_PATTERN_VALID OSI_BIT(19) +#define LUT_FLAGS_PREEMPT OSI_BIT(20) +#define LUT_FLAGS_PREEMPT_VALID OSI_BIT(21) +#define LUT_FLAGS_CONTROLLED_PORT OSI_BIT(22) +#define LUT_FLAGS_DVLAN_PKT OSI_BIT(23) +#define LUT_FLAGS_DVLAN_OUTER_INNER_TAG_SEL OSI_BIT(24) +#define LUT_FLAGS_ENTRY_VALID OSI_BIT(31) + +/** @} */ + +/** + * @addtogroup Generic table CONFIG register helpers macros + * + * @brief Helper macros for generic table CONFIG register programming + * @{ + */ +#define CTLR_SEL_TX 0U +#define CTLR_SEL_RX 1U +#define CTLR_SEL_MAX 1U +#define NUM_CTLR 2U +#define LUT_READ 0U +#define LUT_WRITE 1U +#define RW_MAX 1U +#define TABLE_INDEX_MAX 31U /* 0-31 */ +#define BYP_LUT_MAX_INDEX TABLE_INDEX_MAX +#define SC_LUT_MAX_INDEX 15U +#define SA_LUT_MAX_INDEX TABLE_INDEX_MAX + +/** @} */ + +/** + * @addtogroup Debug buffer table CONFIG register helpers macros + * + * @brief Helper macros for debug buffer table CONFIG register programming + * @{ + */ +#define DBG_TBL_READ LUT_READ +#define DBG_TBL_WRITE LUT_WRITE +/* Num of Tx debug buffers */ +#define TX_DBG_BUF_IDX_MAX 12U +/* Num of Rx debug buffers */ +#define RX_DBG_BUF_IDX_MAX 13U +#define DBG_BUF_IDX_MAX RX_DBG_BUF_IDX_MAX +/** flag - encoding various debug event bits */ +#define TX_DBG_LKUP_MISS_EVT OSI_BIT(0) +#define TX_DBG_AN_NOT_VALID_EVT OSI_BIT(1) +#define TX_DBG_KEY_NOT_VALID_EVT OSI_BIT(2) +#define TX_DBG_CRC_CORRUPT_EVT OSI_BIT(3) +#define TX_DBG_ICV_CORRUPT_EVT OSI_BIT(4) +#define TX_DBG_CAPTURE_EVT OSI_BIT(5) +#define RX_DBG_LKUP_MISS_EVT OSI_BIT(6) +#define RX_DBG_KEY_NOT_VALID_EVT OSI_BIT(7) +#define RX_DBG_REPLAY_ERR_EVT OSI_BIT(8) +#define RX_DBG_CRC_CORRUPT_EVT OSI_BIT(9) +#define RX_DBG_ICV_ERROR_EVT OSI_BIT(10) +#define RX_DBG_CAPTURE_EVT OSI_BIT(11) + +/** @} */ + +/* AES cipthers 128 bit or 256 bit */ +#define MACSEC_CIPHER_AES128 0U +#define MACSEC_CIPHER_AES256 1U + +/* macsec tx/rx enable */ +#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 34 +/* Add 8B for double VLAN tags (4B each), + * 14B for L2 SA/DA/ethertype + * 4B for FCS + */ + +#define MACSEC_CMD_TZ_CONFIG 0x1 +#define MACSEC_CMD_TZ_KT_RESET 0x2 + +/** + * @brief MACsec SA State LUT entry outputs structure + */ +struct sa_state_outputs { + /** Next PN to use */ + unsigned int next_pn; + /** Lowest PN to use */ + unsigned int lowest_pn; +}; + +/** + * @brief MACsec SC State LUT entry outputs structure + */ +struct sc_state_outputs { + /** Current AN to use */ + unsigned int curr_an; +}; + +/** + * @brief MACsec SC Param LUT entry outputs structure + */ +struct sc_param_outputs { + /** Key index start */ + unsigned int key_index_start; + /** PN max for given AN, after which HW will roll over to next AN */ + unsigned int pn_max; + /** PN threshold to trigger irq when threshold is reached */ + unsigned int pn_threshold; + /** PN window */ + unsigned int pn_window; + /** SC identifier */ + unsigned char sci[SCI_LEN]; + /** Default TCI value V=1, ES=0, SC = 1 + * TCI 3 bits V=0, ES=0, SC=1 */ + unsigned char tci; + /** vlan in clear config */ + unsigned char vlan_in_clear; +}; + +/** + * @brief MACsec SCI LUT entry outputs structure + */ +struct sci_lut_outputs { + /** SC index to use */ + unsigned int sc_index; + /** SC identifier */ + unsigned char sci[SCI_LEN]; + /** AN's valid */ + unsigned int an_valid; +}; + +/** + * @brief MACsec LUT config data structure + */ +struct macsec_table_config { + /** Controller select + * 0 - Tx + * 1 - Rx + */ + unsigned short ctlr_sel; + /** Read or write operation select + * 0 - Read + * 1 - Write + */ + unsigned short rw; + /** Table entry index */ + unsigned short index; +}; + +/** + * @brief MACsec KT entry structure + */ +struct kt_entry { + /** SAK key - max 256bit */ + unsigned char sak[KEY_LEN_256]; + /** H-key */ + unsigned char h[KEY_LEN_128]; +}; + + +/** + * @brief MACsec BYP/SCI LUT entry inputs structure + */ +struct lut_inputs { + /** MAC DA to compare */ + unsigned char da[OSI_ETH_ALEN]; + /** MAC SA to compare */ + unsigned char sa[OSI_ETH_ALEN]; + /** Ethertype to compare */ + unsigned char ethtype[ETHTYPE_LEN]; + /** 4-Byte pattern to compare */ + unsigned char byte_pattern[LUT_BYTE_PATTERN_MAX]; + /** Offset for 4-Byte pattern to compare */ + unsigned int byte_pattern_offset[LUT_BYTE_PATTERN_MAX]; + /** VLAN PCP to compare */ + unsigned int vlan_pcp; + /** VLAN ID to compare */ + unsigned int vlan_id; +}; + +/** + * @brief MACsec secure channel basic information + */ +struct osi_macsec_sc_info { + /** Secure channel identifier */ + unsigned char sci[SCI_LEN]; + /** Secure association key */ + unsigned char sak[KEY_LEN_128]; + /** current AN */ + unsigned char curr_an; + /** Next PN to use for the current AN */ + unsigned int next_pn; + /** bitmap of valid AN */ + unsigned int an_valid; + /** SC LUT index */ + unsigned int sc_idx_start; +}; + +/** + * @brief MACsec HW controller LUT's overall status + */ +struct osi_macsec_lut_status { + /** List of max SC's supported */ + struct osi_macsec_sc_info sc_info[MAX_NUM_SC]; + /** next available BYP LUT index */ + unsigned int next_byp_idx; + /** next available SC LUT index */ + unsigned int next_sc_idx; +}; + +/** + * @brief MACsec LUT config data structure + */ +struct osi_macsec_lut_config { + /** Generic table config */ + struct macsec_table_config table_config; + /** LUT select */ + unsigned short lut_sel; + /** flag - encoding various valid bits for above fields */ + unsigned int flags; + /** LUT inputs */ + struct lut_inputs lut_in; + /** SCI LUT outputs */ + struct sci_lut_outputs sci_lut_out; + /** SC Param outputs */ + struct sc_param_outputs sc_param_out; + /** SC State outputs */ + struct sc_state_outputs sc_state_out; + /** SA State outputs */ + struct sa_state_outputs sa_state_out; +}; + +/** + * @brief MACsec KT config data structure + */ +struct osi_macsec_kt_config { + /** Generic table config */ + struct macsec_table_config table_config; + /** KT entry */ + struct kt_entry entry; + /** flag - encoding various valid bits */ + unsigned int flags; +}; + +/** + * @brief MACsec Debug buffer data structure + */ +struct osi_macsec_dbg_buf_config { + /** Controller select + * 0 - Tx + * 1 - Rx + */ + unsigned short ctlr_sel; + /** Read or write operation select + * 0 - Read + * 1 - Write + */ + unsigned short rw; + /** debug data buffer */ + unsigned int dbg_buf[4]; + /** flag - encoding various debug event bits */ + unsigned int flags; + /** debug buffer index */ + unsigned int index; +}; + +/** + * @brief MACsec core operations structure + */ +struct macsec_core_ops { + /** macsec init */ + int (*init)(struct osi_core_priv_data *const osi_core); + /** macsec de-init */ + int (*deinit)(struct osi_core_priv_data *const osi_core); + /** NS irq handler */ + void (*handle_ns_irq)(struct osi_core_priv_data *const osi_core); + /** S irq handler */ + void (*handle_s_irq)(struct osi_core_priv_data *const osi_core); + /** macsec lut config */ + int (*lut_config)(struct osi_core_priv_data *const osi_core, + struct osi_macsec_lut_config *const lut_config); + /** macsec kt config */ + int (*kt_config)(struct osi_core_priv_data *const osi_core, + struct osi_macsec_kt_config *const kt_config); + /** macsec cipher config */ + int (*cipher_config)(struct osi_core_priv_data *const osi_core, + unsigned int cipher); + /** macsec loopback config */ + int (*loopback_config)(struct osi_core_priv_data *const osi_core, + unsigned int enable); + /** macsec enable */ + int (*macsec_en)(struct osi_core_priv_data *const osi_core, + unsigned int enable); + /** macsec config SA in HW LUT */ + int (*config)(struct osi_core_priv_data *const osi_core, + struct osi_macsec_sc_info *const sc, + unsigned int enable, unsigned short ctlr); + /** macsec read mmc counters */ + void (*read_mmc)(struct osi_core_priv_data *const osi_core); + /** macsec debug buffer config */ + int (*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 */ + int (*dbg_events_config)(struct osi_core_priv_data *const osi_core, + struct osi_macsec_dbg_buf_config *const dbg_buf_config); + +}; + + +////////////////////////////////////////////////////////////////////////// + /* OSI interface API prototypes */ +////////////////////////////////////////////////////////////////////////// + +/** + * @brief initializing the macsec core operations + * + * @note + * Algorithm: + * - Init osi_core macsec ops and lut status structure members + * + * @param[in] osi_core: OSI core private data structure. + * + * @pre + * + * @note + * Traceability Details: + * - SWUD_ID: + * + * @note + * Classification: + * - Interrupt: No + * - Signal handler: No + * - Thread safe: No + * - Required Privileges: None + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: No + * - De-initialization: No + * + * @retval 0 on success + * @retval -1 on failure + */ +int osi_init_macsec_ops(struct osi_core_priv_data *const osi_core); + +/** + * @brief Initialize the macsec controller + * + * @note + * Algorithm: + * - Configure MTU, controller configs, interrupts, clear all LUT's and + * set BYP LUT entries for MKPDU and BC packets + * + * @param[in] osi_core: OSI core private data structure. + * + * @pre + * - MACSEC should be out of reset and clocks are enabled + * + * @note + * Traceability Details: + * - SWUD_ID: + * + * @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 + */ +int osi_macsec_init(struct osi_core_priv_data *const osi_core); + +/** + * @brief De-initialize the macsec controller + * + * @param[in] osi_core: OSI core private data structure. + * + * @retval 0 on success + * @retval -1 on failure + */ +int osi_macsec_deinit(struct osi_core_priv_data *const osi_core); + +/** + * @brief Non-secure irq handler + * + * @param[in] osi_core: OSI core private data structure. + * + * @retval None + */ +void osi_macsec_ns_isr(struct osi_core_priv_data *const osi_core); + +/** + * @brief Secure irq handler + * + * @param[in] osi_core: OSI core private data structure. + * + * @retval None + */ +void osi_macsec_s_isr(struct osi_core_priv_data *const osi_core); + +/** + * @brief MACsec Lookup table config + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] lut_config: OSI macsec LUT config data structure. + * + * @retval 0 on success + * @retval -1 on failure + */ +int osi_macsec_lut_config(struct osi_core_priv_data *const osi_core, + struct osi_macsec_lut_config *const lut_confg); + +/** + * @brief MACsec key table config + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] kt_config: OSI macsec KT config data structure. + * + * @retval 0 on success + * @retval -1 on failure + */ +int osi_macsec_kt_config(struct osi_core_priv_data *const osi_core, + struct osi_macsec_kt_config *const kt_config); + +/** + * @brief MACsec Loopback config + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] enable: Loopback enable/disable flag. + * + * @retval 0 on success + * @retval -1 on failure + */ +int osi_macsec_loopback(struct osi_core_priv_data *const osi_core, + unsigned int enable); + +/** + * @brief MACsec Enable + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] enable: macsec controller Tx/Rx enable/disable flag. + * + * @retval 0 on success + * @retval -1 on failure + */ +int osi_macsec_en(struct osi_core_priv_data *const osi_core, + unsigned int enable); + +/** + * @brief MACsec update secure channel/association in controller + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] tx_sa: Pointer to osi_macsec_sc_info struct for the tx SA. + * @param[in] enable: flag to indicate enable/disable for the Tx SA. + * @param[in] enable: Pointer to netlink message. + * + * @retval 0 on success + * @retval -1 on failure + */ +int osi_macsec_config(struct osi_core_priv_data *const osi_core, + struct osi_macsec_sc_info *const sc, + unsigned int enable, unsigned short ctlr); + +/** + * @brief MACsec read statistics counters + * + * @param[in] osi_core: OSI core private data structure. + * + * @retval 0 on success + * @retval -1 on failure + */ +int osi_macsec_read_mmc(struct osi_core_priv_data *const osi_core); + +/** + * @brief MACsec debug buffer config + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] dbg_buf_config: OSI macsec debug buffer config data structure. + * + * @retval 0 on success + * @retval -1 on failure + */ +int osi_macsec_dbg_buf_config( + struct osi_core_priv_data *const osi_core, + struct osi_macsec_dbg_buf_config *const dbg_buf_config); + +/** + * @brief MACsec debug events config + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] dbg_buf_config: OSI macsec debug buffer config data structure. + * + * @retval 0 on success + * @retval -1 on failure + */ +int osi_macsec_dbg_events_config( + struct osi_core_priv_data *const osi_core, + struct osi_macsec_dbg_buf_config *const dbg_buf_config); + +#endif /* INCLUDED_OSI_MACSEC_H */ diff --git a/osi/common/common.h b/osi/common/common.h index 89f6aee..b997670 100644 --- a/osi/common/common.h +++ b/osi/common/common.h @@ -301,17 +301,38 @@ static inline void osi_memset(void *s, nveu32_t c, nveu64_t count) * - Run time: Yes * - De-initialization: No */ -static inline void osi_memcpy(void *dest, void *src, nve32_t n) +static inline nve32_t osi_memcpy(void *dest, void *src, int n) { nve8_t *csrc = (nve8_t *)src; nve8_t *cdest = (nve8_t *)dest; nve32_t i = 0; - if ((src == OSI_NULL) || (dest == OSI_NULL)) { - return; + 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/core/macsec.c b/osi/core/macsec.c new file mode 100644 index 0000000..8c2fc89 --- /dev/null +++ b/osi/core/macsec.c @@ -0,0 +1,3029 @@ +/* + * 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. + */ + +#include <linux/crypto.h> +#include <osi_macsec.h> +#include <linux/printk.h> +#include "macsec.h" +#include "../osi/common/common.h" + +/** + * @brief poll_for_dbg_buf_update - Query the status of a debug buffer update. + * + * @param[in] osi_core: OSI Core private data structure. + * + * @retval 0 on Success + * @retval -1 on Failure + */ +static int poll_for_dbg_buf_update(struct osi_core_priv_data *const osi_core) +{ + int retry = 5000; + unsigned int dbg_buf_config; + + while (retry > 0) { + dbg_buf_config = osi_readl( + (unsigned char *)osi_core->macsec_base + + DEBUG_BUF_CONFIG_0); + if ((dbg_buf_config & DEBUG_BUF_CONFIG_0_UPDATE) == 0U) { + break; + } + /* wait on UPDATE bit to reset */ + osi_core->osd_ops.udelay(10U); + retry--; + } + /** timeout */ + if (retry <= 0) { + pr_err("%s(): timeout!\n", __func__); + return -1; + } + + return 0; + +} + +/** + * @brief write_dbg_buf_data - Commit.debug buffer to HW + * + * @param[in] osi_core: OSI Core private data structure. + * @param[in] dbg_buf: Pointer to debug buffer data to be written + * + * @retval none + */ +static inline void write_dbg_buf_data( + struct osi_core_priv_data *const osi_core, + unsigned int const *const dbg_buf) +{ + + unsigned char *base = (unsigned char *)osi_core->macsec_base; + int i; + + /* Commit the dbg buffer to HW */ + for (i = 0; i < DBG_BUF_LEN; i++) { + /* pr_err("%s: dbg_buf_data[%d]: 0x%x\n", __func__, + i, dbg_buf[i]); */ + osi_writel(dbg_buf[i], base + DEBUG_BUF_DATA_0(i)); + } +} + +/** + * @brief read_dbg_buf_data - Read.debug buffer from HW + * + * @param[in] osi_core: OSI Core private data structure. + * @param[in] dbg_buf: Pointer to debug buffer data to be read + * + * @retval none + */ +static inline void read_dbg_buf_data( + struct osi_core_priv_data *const osi_core, + unsigned int *dbg_buf) +{ + + unsigned char *base = (unsigned char *)osi_core->macsec_base; + int i; + + /* Read debug buffer from HW */ + for (i = 0; i < DBG_BUF_LEN; i++) { + dbg_buf[i] = osi_readl(base + DEBUG_BUF_DATA_0(1)); + pr_err("%s: dbg_buf_data[%d]: 0x%x\n", __func__, i, dbg_buf[i]); + } +} + +/** + * @brief tx_dbg_trigger_evts - Enable/Disable TX debug trigger events. + * + * @param[in] osi_core: OSI Core private data structure. + * @param[in] dbg_buf_config: Pointer to debug buffer config data structure. + * + * @retval None + */ +static void tx_dbg_trigger_evts( + struct osi_core_priv_data *const osi_core, + struct osi_macsec_dbg_buf_config *const dbg_buf_config) +{ + + unsigned char *base = (unsigned char *)osi_core->macsec_base; + unsigned int flags = 0; + unsigned int tx_trigger_evts, debug_ctrl_reg; + + if (dbg_buf_config->rw == DBG_TBL_WRITE) { + flags = dbg_buf_config->flags; + tx_trigger_evts = osi_readl(base + TX_DEBUG_TRIGGER_EN_0); + if (flags & TX_DBG_LKUP_MISS_EVT) { + tx_trigger_evts |= TX_DBG_LKUP_MISS; + } else { + tx_trigger_evts &= ~TX_DBG_LKUP_MISS; + } + + if (flags & TX_DBG_AN_NOT_VALID_EVT) { + tx_trigger_evts |= TX_DBG_AN_NOT_VALID; + } else { + tx_trigger_evts &= ~TX_DBG_AN_NOT_VALID; + } + + if (flags & TX_DBG_KEY_NOT_VALID_EVT) { + tx_trigger_evts |= TX_DBG_KEY_NOT_VALID; + } else { + tx_trigger_evts &= ~TX_DBG_KEY_NOT_VALID; + } + + if (flags & TX_DBG_CRC_CORRUPT_EVT) { + tx_trigger_evts |= TX_DBG_CRC_CORRUPT; + } else { + tx_trigger_evts &= ~TX_DBG_CRC_CORRUPT; + } + + if (flags & TX_DBG_ICV_CORRUPT_EVT) { + tx_trigger_evts |= TX_DBG_ICV_CORRUPT; + } else { + tx_trigger_evts &= ~TX_DBG_ICV_CORRUPT; + } + + if (flags & TX_DBG_CAPTURE_EVT) { + tx_trigger_evts |= TX_DBG_CAPTURE; + } else { + tx_trigger_evts &= ~TX_DBG_CAPTURE; + } + + pr_err("%s: tx_trigger_evts 0x%x", __func__, tx_trigger_evts); + osi_writel(tx_trigger_evts, base + TX_DEBUG_TRIGGER_EN_0); + if (tx_trigger_evts != OSI_NONE) { + /** Start the tx debug buffer capture */ + debug_ctrl_reg = osi_readl(base + TX_DEBUG_CONTROL_0); + debug_ctrl_reg |= TX_DEBUG_CONTROL_0_START_CAP; + pr_err("%s: debug_ctrl_reg 0x%x", __func__, + debug_ctrl_reg); + osi_writel(debug_ctrl_reg, base + TX_DEBUG_CONTROL_0); + } + } else { + tx_trigger_evts = osi_readl(base + TX_DEBUG_STATUS_0); + pr_err("%s: tx_trigger_evts 0x%x", __func__, tx_trigger_evts); + if (tx_trigger_evts & TX_DBG_LKUP_MISS) { + flags |= TX_DBG_LKUP_MISS_EVT; + } + if (tx_trigger_evts & TX_DBG_AN_NOT_VALID) { + flags |= TX_DBG_AN_NOT_VALID_EVT; + } + if (tx_trigger_evts & TX_DBG_KEY_NOT_VALID) { + flags |= TX_DBG_KEY_NOT_VALID_EVT; + } + if (tx_trigger_evts & TX_DBG_CRC_CORRUPT) { + flags |= TX_DBG_CRC_CORRUPT_EVT; + } + if (tx_trigger_evts & TX_DBG_ICV_CORRUPT) { + flags |= TX_DBG_ICV_CORRUPT_EVT; + } + if (tx_trigger_evts & TX_DBG_CAPTURE) { + flags |= TX_DBG_CAPTURE_EVT; + } + dbg_buf_config->flags = flags; + } +} + +/** + * @brief rx_dbg_trigger_evts - Enable/Disable RX debug trigger events. + * + * @param[in] osi_core: OSI Core private data structure. + * @param[in] dbg_buf_config: Pointer to debug buffer config data structure. + * + * @retval None + */ +static void rx_dbg_trigger_evts( + struct osi_core_priv_data *const osi_core, + struct osi_macsec_dbg_buf_config *const dbg_buf_config) +{ + + unsigned char *base = (unsigned char *)osi_core->macsec_base; + unsigned int flags = 0; + unsigned int rx_trigger_evts, debug_ctrl_reg; + + if (dbg_buf_config->rw == DBG_TBL_WRITE) { + flags = dbg_buf_config->flags; + rx_trigger_evts = osi_readl(base + RX_DEBUG_TRIGGER_EN_0); + if (flags & RX_DBG_LKUP_MISS_EVT) { + rx_trigger_evts |= RX_DBG_LKUP_MISS; + } else { + rx_trigger_evts &= ~RX_DBG_LKUP_MISS; + } + + if (flags & RX_DBG_KEY_NOT_VALID_EVT) { + rx_trigger_evts |= RX_DBG_KEY_NOT_VALID; + } else { + rx_trigger_evts &= ~RX_DBG_KEY_NOT_VALID; + } + + if (flags & RX_DBG_REPLAY_ERR_EVT) { + rx_trigger_evts |= RX_DBG_REPLAY_ERR; + } else { + rx_trigger_evts &= ~RX_DBG_REPLAY_ERR; + } + + if (flags & RX_DBG_CRC_CORRUPT_EVT) { + rx_trigger_evts |= RX_DBG_CRC_CORRUPT; + } else { + rx_trigger_evts &= ~RX_DBG_CRC_CORRUPT; + } + + if (flags & RX_DBG_ICV_ERROR_EVT) { + rx_trigger_evts |= RX_DBG_ICV_ERROR; + } else { + rx_trigger_evts &= ~RX_DBG_ICV_ERROR; + } + + if (flags & RX_DBG_CAPTURE_EVT) { + rx_trigger_evts |= RX_DBG_CAPTURE; + } else { + rx_trigger_evts &= ~RX_DBG_CAPTURE; + } + pr_err("%s: rx_trigger_evts 0x%x", __func__, rx_trigger_evts); + osi_writel(rx_trigger_evts, base + RX_DEBUG_TRIGGER_EN_0); + if (rx_trigger_evts != OSI_NONE) { + /** Start the tx debug buffer capture */ + debug_ctrl_reg = osi_readl(base + RX_DEBUG_CONTROL_0); + debug_ctrl_reg |= RX_DEBUG_CONTROL_0_START_CAP; + pr_err("%s: debug_ctrl_reg 0x%x", __func__, + debug_ctrl_reg); + osi_writel(debug_ctrl_reg, base + RX_DEBUG_CONTROL_0); + } + } else { + rx_trigger_evts = osi_readl(base + RX_DEBUG_STATUS_0); + pr_err("%s: rx_trigger_evts 0x%x", __func__, rx_trigger_evts); + if (rx_trigger_evts & RX_DBG_LKUP_MISS) { + flags |= RX_DBG_LKUP_MISS_EVT; + } + if (rx_trigger_evts & RX_DBG_KEY_NOT_VALID) { + flags |= RX_DBG_KEY_NOT_VALID_EVT; + } + if (rx_trigger_evts & RX_DBG_REPLAY_ERR) { + flags |= RX_DBG_REPLAY_ERR_EVT; + } + if (rx_trigger_evts & RX_DBG_CRC_CORRUPT) { + flags |= RX_DBG_CRC_CORRUPT_EVT; + } + if (rx_trigger_evts & RX_DBG_ICV_ERROR) { + flags |= RX_DBG_ICV_ERROR_EVT; + } + if (rx_trigger_evts & RX_DBG_CAPTURE) { + flags |= RX_DBG_CAPTURE_EVT; + } + dbg_buf_config->flags = flags; + } + +} + +/** + * @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 macsec_dbg_buf_config(struct osi_core_priv_data *const osi_core, + struct osi_macsec_dbg_buf_config *const dbg_buf_config) +{ + + unsigned char *base = (unsigned char *)osi_core->macsec_base; +// unsigned int en_flags; + unsigned int dbg_config_reg = 0; + int ret = 0; + + /* Validate inputs */ + if ((dbg_buf_config->rw > RW_MAX) || + (dbg_buf_config->ctlr_sel > CTLR_SEL_MAX)) { + pr_err("%s(): Params validation failed\n", __func__); + return -1; + } + + if ((dbg_buf_config->ctlr_sel == CTLR_SEL_TX && + dbg_buf_config->index > TX_DBG_BUF_IDX_MAX) || + (dbg_buf_config->ctlr_sel == CTLR_SEL_RX && + dbg_buf_config->index > RX_DBG_BUF_IDX_MAX)) { + pr_err("%s(): Wrong index %d\n", __func__, + dbg_buf_config->index); + return -1; + } + //en_flags = osi_readl(base + TX_DEBUG_TRIGGER_EN_0); + /** disable all trigger events */ + //osi_writel(0, base + TX_DEBUG_TRIGGER_EN_0); + + /* Wait for previous debug table update to finish */ + ret = poll_for_dbg_buf_update(osi_core); + if (ret < 0) { + return ret; + } + + pr_err("%s: ctrl: %hu rw: %hu idx: %hu flags: %#x\n", __func__, + dbg_buf_config->ctlr_sel, dbg_buf_config->rw, + dbg_buf_config->index, dbg_buf_config->flags); + + dbg_config_reg = osi_readl(base + DEBUG_BUF_CONFIG_0); + + if (dbg_buf_config->ctlr_sel) { + dbg_config_reg |= DEBUG_BUF_CONFIG_0_CTLR_SEL; + } else { + dbg_config_reg &= ~DEBUG_BUF_CONFIG_0_CTLR_SEL; + } + + if (dbg_buf_config->rw) { + dbg_config_reg |= 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 &= ~DEBUG_BUF_CONFIG_0_RW; + } + + dbg_config_reg &= ~DEBUG_BUF_CONFIG_0_IDX_MASK; + dbg_config_reg |= dbg_buf_config->index ; + dbg_config_reg |= DEBUG_BUF_CONFIG_0_UPDATE; + pr_err("%s: dbg_config_reg 0x%x\n", __func__, dbg_config_reg); + osi_writel(dbg_config_reg, base + DEBUG_BUF_CONFIG_0); + ret = poll_for_dbg_buf_update(osi_core); + if (ret < 0) { + return ret; + } + + if (!dbg_buf_config->rw) { + read_dbg_buf_data(osi_core, dbg_buf_config->dbg_buf); + } + /** Enable Tx trigger events */ +// osi_writel(en_flags, base + TX_DEBUG_TRIGGER_EN_0); + return 0; +} + + +int macsec_dbg_events_config( + struct osi_core_priv_data *const osi_core, + struct osi_macsec_dbg_buf_config *const dbg_buf_config) +{ + + int ret = 0; + + pr_err("%s():", __func__); + + /* Validate inputs */ + if ((dbg_buf_config->rw > RW_MAX) || + (dbg_buf_config->ctlr_sel > CTLR_SEL_MAX)) { + pr_err("%s(): Params validation failed", __func__); + return -1; + } + switch (dbg_buf_config->ctlr_sel) { + case CTLR_SEL_TX: + tx_dbg_trigger_evts(osi_core, dbg_buf_config); + break; + case CTLR_SEL_RX: + rx_dbg_trigger_evts(osi_core, dbg_buf_config); + break; + } + + return ret; +} + +/** + * @brief macsec_reset_mmc - To reset macsec statistics registers and + * structure variable + * + * @param[in] osi_core: OSI core private data structure. + * + * @note + * 1) MAC/MACSEC should be init and started. + */ +void macsec_reset_mmc(struct osi_core_priv_data *osi_core) +{ + unsigned int value; + signed short retry = 1000; + + value = osi_readl((unsigned char *)osi_core->macsec_base + + STATS_CONTROL_0); + /* reset statitics counters */ + value |= STATS_CONTROL0_CNT_CLR; + osi_writel(value, (unsigned char *)osi_core->base + STATS_CONTROL_0); + osi_memset(&osi_core->macsec_mmc, 0U, + sizeof(struct osi_macsec_mmc_counters)); + /* wait for stats to be cleared */ + while (retry > 0) { + value = osi_readl((unsigned char *)osi_core->macsec_base + + STATS_CONTROL_0); + if ((value & STATS_CONTROL0_CNT_CLR) != + STATS_CONTROL0_CNT_CLR) { + break; + } + osi_core->osd_ops.udelay(10U); + retry--; + } +} + +/** + * @brief update_macsec_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/MACSEC should be init and started. + * + * @retval 0 on MMC counters overflow + * @retval value on current MMC counter value. + */ +static inline unsigned long long update_macsec_mmc_val( + struct osi_core_priv_data *osi_core, + unsigned long long last_value, unsigned long offset) +{ + + unsigned long long temp; + unsigned int value_lo, value_hi; + + value_lo = osi_readl((unsigned char *)osi_core->macsec_base + offset); + value_hi = osi_readl((unsigned char *)osi_core->macsec_base + + (offset + 4U)); + + temp = last_value + (value_lo | value_hi << 31); + if (temp < last_value) { + pr_err("Value overflow resetting all statitics counters\n"); + macsec_reset_mmc(osi_core); + } else { + return temp; + } + + return 0; +} + + +/** + * @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. + */ +void macsec_read_mmc(struct osi_core_priv_data *const osi_core) +{ + struct osi_macsec_mmc_counters *mmc = &osi_core->macsec_mmc; + unsigned short i; + + mmc->tx_pkts_untaged = + update_macsec_mmc_val(osi_core, mmc->tx_pkts_untaged, + TX_PKTS_UNTG_LO_0); + mmc->tx_pkts_too_long = + update_macsec_mmc_val(osi_core, mmc->tx_pkts_too_long, + TX_PKTS_TOO_LONG_LO_0); + mmc->tx_octets_protected = + update_macsec_mmc_val(osi_core, mmc->tx_octets_protected, + TX_OCTETS_PRTCTD_LO_0); + mmc->rx_pkts_no_tag = + update_macsec_mmc_val(osi_core, mmc->rx_pkts_no_tag, + RX_PKTS_NOTG_LO_0); + mmc->rx_pkts_untagged = + update_macsec_mmc_val(osi_core, mmc->rx_pkts_untagged, + RX_PKTS_UNTG_LO_0); + mmc->rx_pkts_bad_tag = + update_macsec_mmc_val(osi_core, mmc->rx_pkts_bad_tag, + RX_PKTS_BADTAG_LO_0); + mmc->rx_pkts_no_sa_err = + update_macsec_mmc_val(osi_core, mmc->rx_pkts_no_sa_err, + RX_PKTS_NOSAERROR_LO_0); + mmc->rx_pkts_no_sa = + update_macsec_mmc_val(osi_core, mmc->rx_pkts_no_sa, + RX_PKTS_NOSA_LO_0); + mmc->rx_pkts_overrun = + update_macsec_mmc_val(osi_core, mmc->rx_pkts_overrun, + RX_PKTS_OVRRUN_LO_0); + mmc->rx_octets_validated = + update_macsec_mmc_val(osi_core, mmc->rx_octets_validated, + RX_OCTETS_VLDTD_LO_0); + + for (i = 0; i <= SC_INDEX_MAX; i++) { + mmc->tx_pkts_protected[i] = + update_macsec_mmc_val(osi_core, + mmc->tx_pkts_protected[i], + TX_PKTS_PROTECTED_SCx_LO_0(i)); + mmc->rx_pkts_late[i] = + update_macsec_mmc_val(osi_core, mmc->rx_pkts_late[i], + 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, + mmc->rx_pkts_not_valid[i], + 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, mmc->rx_pkts_ok[i], + RX_PKTS_OK_SCx_LO_0(i)); + } +} + +int macsec_enable(struct osi_core_priv_data *osi_core, unsigned int enable) +{ + unsigned int val; + unsigned char *base = (unsigned char *)osi_core->macsec_base; + + val = osi_readl(base + MACSEC_CONTROL0); + pr_err("Read MACSEC_CONTROL0: 0x%x\n", val); + + if ((enable & OSI_MACSEC_TX_EN) == OSI_MACSEC_TX_EN) { + pr_err("\tEnabling macsec TX"); + val |= (TX_EN); + } else { + pr_err("\tDisabling macsec TX"); + val &= ~(TX_EN); + } + + if ((enable & OSI_MACSEC_RX_EN) == OSI_MACSEC_RX_EN) { + pr_err("\tEnabling macsec RX"); + val |= (RX_EN); + } else { + pr_err("\tDisabling macsec RX"); + val &= ~(RX_EN); + } + + pr_err("Write MACSEC_CONTROL0: 0x%x\n", val); + osi_writel(val, base + MACSEC_CONTROL0); + + return 0; +} + +/** + * @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 int poll_for_kt_update(struct osi_core_priv_data *osi_core) +{ + /* half sec timeout */ + unsigned int retry = 50000; + unsigned int kt_config; + unsigned int count; + int 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_readl((unsigned char *)osi_core->tz_base + + GCM_KEYTABLE_CONFIG); + if ((kt_config & KT_CONFIG_UPDATE) == 0U) { + /* exit loop */ + cond = 0; + } else { + /* wait on UPDATE bit to reset */ + osi_core->osd_ops.udelay(10U); + } + } + + return 0; +} + +static int kt_key_read(struct osi_core_priv_data *const osi_core, + struct osi_macsec_kt_config *const kt_config) +{ + unsigned int kt_key[MACSEC_KT_DATA_REG_CNT] = {0}; + int i, j; + + for (i = 0; i < MACSEC_KT_DATA_REG_CNT; i++) { + kt_key[i] = osi_readl((unsigned char *)osi_core->tz_base + + GCM_KEYTABLE_DATA(i)); + } + + if ((kt_key[MACSEC_KT_DATA_REG_CNT - 1] & KT_ENTRY_VALID) == + KT_ENTRY_VALID) { + kt_config->flags |= 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 * 4 + j] = + (kt_key[i] >> (j * 8) & 0xFF); + } + } + + for (i = 0; i < MACSEC_KT_DATA_REG_H_CNT; i++) { + for (j = 0; j < INTEGER_LEN; j++) { + kt_config->entry.h[i * 4 + j] = + (kt_key[i + MACSEC_KT_DATA_REG_SAK_CNT] >> (j * 8) + & 0xFF); + } + } + + return 0; +} + +static int kt_key_write(struct osi_core_priv_data *const osi_core, + struct osi_macsec_kt_config *const kt_config) +{ + unsigned int kt_key[MACSEC_KT_DATA_REG_CNT] = {0}; + struct kt_entry entry = kt_config->entry; + int 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] |= (entry.sak[i * 4 + j] << (j * 8)); + } + } + /* 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] |= + (entry.h[i * 4 + j] << (j * 8)); + } + } + + if ((kt_config->flags & LUT_FLAGS_ENTRY_VALID) == + LUT_FLAGS_ENTRY_VALID) { + kt_key[MACSEC_KT_DATA_REG_CNT - 1] |= KT_ENTRY_VALID; + } + + for (i = 0; i < MACSEC_KT_DATA_REG_CNT; i++) { + /* pr_err("%s: kt_key[%d]: 0x%x\n", __func__, i, kt_key[i]); */ + osi_writel(kt_key[i], (unsigned char *)osi_core->tz_base + + GCM_KEYTABLE_DATA(i)); + } + + return 0; +} + +static int macsec_kt_config(struct osi_core_priv_data *const osi_core, + struct osi_macsec_kt_config *const kt_config) +{ + int ret = 0; + unsigned int kt_config_reg = 0; + unsigned char *base = (unsigned char *)osi_core->tz_base; + + /* Validate KT config */ + if ((kt_config->table_config.ctlr_sel > CTLR_SEL_MAX) || + (kt_config->table_config.rw > RW_MAX) || + (kt_config->table_config.index > TABLE_INDEX_MAX)) { + /* TODO - validate using a local cache if index is + * already active */ + return -1; + } + + /* Wait for previous KT update to finish */ + ret = poll_for_kt_update(osi_core); + if (ret < 0) { + return ret; + } + + /* pr_err("%s: ctrl: %hu rw: %hu idx: %hu flags: %#x\n", __func__, + kt_config->table_config.ctlr_sel, + kt_config->table_config.rw, kt_config->table_config.index, + kt_config->flags); */ + kt_config_reg = osi_readl(base + GCM_KEYTABLE_CONFIG); + if (kt_config->table_config.ctlr_sel) { + kt_config_reg |= KT_CONFIG_CTLR_SEL; + } else { + kt_config_reg &= ~KT_CONFIG_CTLR_SEL; + } + + if (kt_config->table_config.rw) { + kt_config_reg |= 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 &= ~KT_CONFIG_RW; + } + + kt_config_reg &= ~KT_CONFIG_INDEX_MASK; + kt_config_reg |= (kt_config->table_config.index); + + kt_config_reg |= KT_CONFIG_UPDATE; + osi_writel(kt_config_reg, base + 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) { + ret = kt_key_read(osi_core, kt_config); + if (ret < 0) { + return ret; + } + } + return ret; +} + +/** + * @brief poll_for_lut_update - Query the status of a LUT update. + * + * @param[in] osi_core: OSI Core private data structure. + * + * @retval 0 on Success + * @retval -1 on Failure + */ +static inline int poll_for_lut_update(struct osi_core_priv_data *osi_core) +{ + /* half sec timeout */ + unsigned int retry = 50000; + unsigned int lut_config; + unsigned int count; + int 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_readl((unsigned char *)osi_core->macsec_base + + MACSEC_LUT_CONFIG); + if ((lut_config & LUT_CONFIG_UPDATE) == 0U) { + /* exit loop */ + cond = 0; + } else { + /* wait on UPDATE bit to reset */ + osi_core->osd_ops.udelay(10U); + } + } + + return 0; +} + +static inline void read_lut_data(struct osi_core_priv_data *const osi_core, + unsigned int *const lut_data) +{ + unsigned char *base = (unsigned char *)osi_core->macsec_base; + int i; + + /* Commit the LUT entry to HW */ + for (i = 0; i < MACSEC_LUT_DATA_REG_CNT; i++) { + lut_data[i] = osi_readl(base + MACSEC_LUT_DATA(i)); + //pr_err("%s: lut_data[%d]: 0x%x\n", __func__, i, lut_data[i]); + } +} + +static int lut_read_inputs(struct osi_macsec_lut_config *const lut_config, + unsigned int *const lut_data) +{ + struct lut_inputs entry = {0}; + unsigned int flags = 0; + + /* MAC DA */ + if ((lut_data[1] & LUT_DA_BYTE0_INACTIVE) != LUT_DA_BYTE0_INACTIVE) { + entry.da[0] = lut_data[0] & 0xFF; + flags |= LUT_FLAGS_DA_BYTE0_VALID; + } + + if ((lut_data[1] & LUT_DA_BYTE1_INACTIVE) != LUT_DA_BYTE1_INACTIVE) { + entry.da[1] = lut_data[0] >> 8 & 0xFF; + flags |= LUT_FLAGS_DA_BYTE1_VALID; + } + + if ((lut_data[1] & LUT_DA_BYTE2_INACTIVE) != LUT_DA_BYTE2_INACTIVE) { + entry.da[2] = lut_data[0] >> 16 & 0xFF; + flags |= LUT_FLAGS_DA_BYTE2_VALID; + } + + if ((lut_data[1] & LUT_DA_BYTE3_INACTIVE) != LUT_DA_BYTE3_INACTIVE) { + entry.da[3] = lut_data[0] >> 24 & 0xFF; + flags |= LUT_FLAGS_DA_BYTE3_VALID; + } + + if ((lut_data[1] & LUT_DA_BYTE4_INACTIVE) != LUT_DA_BYTE4_INACTIVE) { + entry.da[4] = lut_data[1] & 0xFF; + flags |= LUT_FLAGS_DA_BYTE4_VALID; + } + + if ((lut_data[1] & LUT_DA_BYTE5_INACTIVE) != LUT_DA_BYTE5_INACTIVE) { + entry.da[5] = lut_data[1] >> 8 & 0xFF; + flags |= LUT_FLAGS_DA_BYTE5_VALID; + } + + /* MAC SA */ + if ((lut_data[3] & LUT_SA_BYTE0_INACTIVE) != LUT_SA_BYTE0_INACTIVE) { + entry.sa[0] = lut_data[1] >> 22 & 0xFF; + flags |= LUT_FLAGS_SA_BYTE0_VALID; + } + + if ((lut_data[3] & LUT_SA_BYTE1_INACTIVE) != LUT_SA_BYTE1_INACTIVE) { + entry.sa[1] = (lut_data[1] >> 30) | + ((lut_data[2] & 0x3F) << 2); + flags |= LUT_FLAGS_SA_BYTE1_VALID; + } + + if ((lut_data[3] & LUT_SA_BYTE2_INACTIVE) != LUT_SA_BYTE2_INACTIVE) { + entry.sa[2] = lut_data[2] >> 6 & 0xFF; + flags |= LUT_FLAGS_SA_BYTE2_VALID; + } + + if ((lut_data[3] & LUT_SA_BYTE3_INACTIVE) != LUT_SA_BYTE3_INACTIVE) { + entry.sa[3] = lut_data[2] >> 14 & 0xFF; + flags |= LUT_FLAGS_SA_BYTE3_VALID; + } + + if ((lut_data[3] & LUT_SA_BYTE4_INACTIVE) != LUT_SA_BYTE4_INACTIVE) { + entry.sa[4] = lut_data[2] >> 22 & 0xFF; + flags |= LUT_FLAGS_SA_BYTE4_VALID; + } + + if ((lut_data[3] & LUT_SA_BYTE5_INACTIVE) != LUT_SA_BYTE5_INACTIVE) { + entry.sa[5] = (lut_data[2] >> 30) | + ((lut_data[3] & 0x3F) << 2); + flags |= LUT_FLAGS_SA_BYTE5_VALID; + } + + /* Ether type */ + if ((lut_data[3] & LUT_ETHTYPE_INACTIVE) != LUT_ETHTYPE_INACTIVE) { + entry.ethtype[0] = lut_data[3] >> 12 & 0xFF; + entry.ethtype[1] = lut_data[3] >> 20 & 0xFF; + flags |= LUT_FLAGS_ETHTYPE_VALID; + } + + /* VLAN */ + if ((lut_data[4] & LUT_VLAN_ACTIVE) == LUT_VLAN_ACTIVE) { + flags |= LUT_FLAGS_VLAN_VALID; + /* VLAN PCP */ + if ((lut_data[4] & LUT_VLAN_PCP_INACTIVE) != + LUT_VLAN_PCP_INACTIVE) { + flags |= LUT_FLAGS_VLAN_PCP_VALID; + entry.vlan_pcp = lut_data[3] >> 29; + } + + /* VLAN ID */ + if ((lut_data[4] & LUT_VLAN_ID_INACTIVE) != + LUT_VLAN_ID_INACTIVE) { + flags |= LUT_FLAGS_VLAN_ID_VALID; + entry.vlan_id = lut_data[4] >> 1 & 0xFFF; + } + } + + /* Byte patterns */ + if ((lut_data[4] & LUT_BYTE0_PATTERN_INACTIVE) != + LUT_BYTE0_PATTERN_INACTIVE) { + flags |= LUT_FLAGS_BYTE0_PATTERN_VALID; + entry.byte_pattern[0] = lut_data[4] >> 15 & 0xFF; + entry.byte_pattern_offset[0] = lut_data[4] >> 23 & 0x3F; + } + if ((lut_data[5] & LUT_BYTE1_PATTERN_INACTIVE) != + LUT_BYTE1_PATTERN_INACTIVE) { + flags |= LUT_FLAGS_BYTE1_PATTERN_VALID; + entry.byte_pattern[1] = (lut_data[4] >> 30) | + ((lut_data[5] & 0x3F) << 2); + entry.byte_pattern_offset[1] = lut_data[5] >> 6 & 0x3F; + } + if ((lut_data[5] & LUT_BYTE2_PATTERN_INACTIVE) != + LUT_BYTE2_PATTERN_INACTIVE) { + flags |= LUT_FLAGS_BYTE2_PATTERN_VALID; + entry.byte_pattern[2] = lut_data[5] >> 13 & 0xFF; + entry.byte_pattern_offset[2] = lut_data[5] >> 21 & 0x3F; + } + if ((lut_data[6] & LUT_BYTE3_PATTERN_INACTIVE) != + LUT_BYTE3_PATTERN_INACTIVE) { + flags |= LUT_FLAGS_BYTE3_PATTERN_VALID; + entry.byte_pattern[3] = (lut_data[5] >> 28) | + ((lut_data[6] & 0xF) << 4); + entry.byte_pattern_offset[3] = lut_data[6] >> 4 & 0x3F; + } + + /* Preempt mask */ + if ((lut_data[6] & LUT_PREEMPT_INACTIVE) != LUT_PREEMPT_INACTIVE) { + flags |= LUT_FLAGS_PREEMPT_VALID; + if ((lut_data[6] & LUT_PREEMPT) == LUT_PREEMPT) { + flags |= LUT_FLAGS_PREEMPT; + } + } + + lut_config->lut_in = entry; + lut_config->flags = flags; + + return 0; +} + +static int byp_lut_read(struct osi_core_priv_data *const osi_core, + struct osi_macsec_lut_config *const lut_config) +{ + unsigned int lut_data[MACSEC_LUT_DATA_REG_CNT] = {0}; + unsigned int flags = 0, val = 0; + unsigned int index = lut_config->table_config.index; + unsigned char *addr = (unsigned char *)osi_core->macsec_base; + unsigned char *paddr = OSI_NULL; + + read_lut_data(osi_core, lut_data); + + if (lut_read_inputs(lut_config, lut_data) != 0) { + pr_err("LUT inputs error\n"); + return -1; + } + + /* Lookup output */ + if ((lut_data[6] & LUT_CONTROLLED_PORT) == LUT_CONTROLLED_PORT) { + flags |= LUT_FLAGS_CONTROLLED_PORT; + } + + if ((lut_data[6] & BYP_LUT_DVLAN_PKT) == BYP_LUT_DVLAN_PKT) { + flags |= LUT_FLAGS_DVLAN_PKT; + } + + if ((lut_data[6] & BYP_LUT_DVLAN_OUTER_INNER_TAG_SEL) == + BYP_LUT_DVLAN_OUTER_INNER_TAG_SEL) { + flags |= LUT_FLAGS_DVLAN_OUTER_INNER_TAG_SEL; + } + + switch (lut_config->table_config.ctlr_sel) { + case CTLR_SEL_TX: + paddr = addr+TX_BYP_LUT_VALID; + break; + case CTLR_SEL_RX: + paddr = addr+RX_BYP_LUT_VALID; + break; + default: + pr_err("Unknown controller select\n"); + return -1; + } + val = osi_readl(paddr); + if (val & (1U << index)) { + flags |= LUT_FLAGS_ENTRY_VALID; + } + + lut_config->flags |= flags; + + return 0; +} + +static int sci_lut_read(struct osi_core_priv_data *const osi_core, + struct osi_macsec_lut_config *const lut_config) +{ + unsigned int lut_data[MACSEC_LUT_DATA_REG_CNT] = {0}; + unsigned int flags = 0; + unsigned char *addr = (unsigned char *)osi_core->macsec_base; + unsigned int val = 0; + unsigned int index = lut_config->table_config.index; + + if (index > SC_LUT_MAX_INDEX) { + return -1; + } + read_lut_data(osi_core, lut_data); + + switch (lut_config->table_config.ctlr_sel) { + case CTLR_SEL_TX: + if (lut_read_inputs(lut_config, lut_data) != 0) { + pr_err("LUT inputs error\n"); + return -1; + } + if ((lut_data[6] & LUT_AN0_VALID) == LUT_AN0_VALID) { + lut_config->sci_lut_out.an_valid |= AN0_VALID; + } + if ((lut_data[6] & LUT_AN1_VALID) == LUT_AN1_VALID) { + lut_config->sci_lut_out.an_valid |= AN1_VALID; + } + if ((lut_data[6] & LUT_AN2_VALID) == LUT_AN2_VALID) { + lut_config->sci_lut_out.an_valid |= AN2_VALID; + } + if ((lut_data[6] & LUT_AN3_VALID) == LUT_AN3_VALID) { + lut_config->sci_lut_out.an_valid |= AN3_VALID; + } + + lut_config->sci_lut_out.sc_index = lut_data[6] >> 17 & 0xF; + + if ((lut_data[6] & TX_SCI_LUT_DVLAN_PKT) == + TX_SCI_LUT_DVLAN_PKT) { + lut_config->flags |= LUT_FLAGS_DVLAN_PKT; + } + if ((lut_data[6] & TX_SCI_LUT_DVLAN_OUTER_INNER_TAG_SEL) == + TX_SCI_LUT_DVLAN_OUTER_INNER_TAG_SEL) { + lut_config->flags |= + LUT_FLAGS_DVLAN_OUTER_INNER_TAG_SEL; + } + + val = osi_readl(addr+TX_SCI_LUT_VALID); + if (val & (1U << index)) { + lut_config->flags |= LUT_FLAGS_ENTRY_VALID; + } + break; + case CTLR_SEL_RX: + lut_config->sci_lut_out.sci[0] = lut_data[0] & 0xFF; + lut_config->sci_lut_out.sci[1] = lut_data[0] >> 8 & 0xFF; + lut_config->sci_lut_out.sci[2] = lut_data[0] >> 16 & 0xFF; + lut_config->sci_lut_out.sci[3] = lut_data[0] >> 24 & 0xFF; + lut_config->sci_lut_out.sci[4] = lut_data[1] & 0xFF; + lut_config->sci_lut_out.sci[5] = lut_data[1] >> 8 & 0xFF; + lut_config->sci_lut_out.sci[6] = lut_data[1] >> 16 & 0xFF; + lut_config->sci_lut_out.sci[7] = lut_data[1] >> 24 & 0xFF; + + lut_config->sci_lut_out.sc_index = lut_data[2] >> 10 & 0xF; + if ((lut_data[2] & RX_SCI_LUT_PREEMPT_INACTIVE) != + RX_SCI_LUT_PREEMPT_INACTIVE) { + flags |= LUT_FLAGS_PREEMPT_VALID; + if ((lut_data[2] & RX_SCI_LUT_PREEMPT) == + RX_SCI_LUT_PREEMPT) { + flags |= LUT_FLAGS_PREEMPT; + } + } + + val = osi_readl(addr+RX_SCI_LUT_VALID); + if (val & (1U << index)) { + lut_config->flags |= LUT_FLAGS_ENTRY_VALID; + } + break; + default: + pr_err("Unknown controller selected\n"); + return -1; + } + + /* Lookup output */ + return 0; +} + +static int sc_param_lut_read(struct osi_core_priv_data *const osi_core, + struct osi_macsec_lut_config *const lut_config) +{ + unsigned int lut_data[MACSEC_LUT_DATA_REG_CNT] = {0}; + + read_lut_data(osi_core, lut_data); + + switch (lut_config->table_config.ctlr_sel) { + case CTLR_SEL_TX: + lut_config->sc_param_out.key_index_start = lut_data[0] & 0x1F; + 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 = (lut_data[2] >> 5) & 0x3; + lut_config->sc_param_out.sci[0] = lut_data[2] >> 8 & 0xFF; + lut_config->sc_param_out.sci[1] = lut_data[2] >> 16 & 0xFF; + lut_config->sc_param_out.sci[2] = lut_data[2] >> 24 & 0xFF; + lut_config->sc_param_out.sci[3] = lut_data[3] & 0xFF; + lut_config->sc_param_out.sci[4] = lut_data[3] >> 8 & 0xFF; + lut_config->sc_param_out.sci[5] = lut_data[3] >> 16 & 0xFF; + lut_config->sc_param_out.sci[6] = lut_data[3] >> 24 & 0xFF; + lut_config->sc_param_out.sci[7] = lut_data[4] & 0xFF; + lut_config->sc_param_out.vlan_in_clear = + (lut_data[4] >> 8) & 0x1; + break; + case CTLR_SEL_RX: + lut_config->sc_param_out.key_index_start = lut_data[0] & 0x1F; + 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: + pr_err("Unknown controller selected\n"); + return -1; + } + + /* Lookup output */ + return 0; +} + +static int sc_state_lut_read(struct osi_core_priv_data *const osi_core, + struct osi_macsec_lut_config *const lut_config) +{ + unsigned int 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; +} + +static int sa_state_lut_read(struct osi_core_priv_data *const osi_core, + struct osi_macsec_lut_config *const lut_config) +{ + unsigned int lut_data[MACSEC_LUT_DATA_REG_CNT] = {0}; + + read_lut_data(osi_core, lut_data); + + switch (lut_config->table_config.ctlr_sel) { + case CTLR_SEL_TX: + lut_config->sa_state_out.next_pn = lut_data[0]; + if ((lut_data[1] & SA_STATE_LUT_ENTRY_VALID) == + SA_STATE_LUT_ENTRY_VALID) { + lut_config->flags |= LUT_FLAGS_ENTRY_VALID; + } + break; + case 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: + pr_err("Unknown controller selected\n"); + return -1; + } + + /* Lookup output */ + return 0; +} + +static int lut_data_read(struct osi_core_priv_data *const osi_core, + struct osi_macsec_lut_config *const lut_config) +{ + switch (lut_config->lut_sel) { + case LUT_SEL_BYPASS: + if (byp_lut_read(osi_core, lut_config) != 0) { + pr_err("BYP LUT read err\n"); + return -1; + } + break; + case LUT_SEL_SCI: + if (sci_lut_read(osi_core, lut_config) != 0) { + pr_err("SCI LUT read err\n"); + return -1; + } + break; + case LUT_SEL_SC_PARAM: + if (sc_param_lut_read(osi_core, lut_config) != 0) { + pr_err("SC param LUT read err\n"); + return -1; + } + break; + case LUT_SEL_SC_STATE: + if (sc_state_lut_read(osi_core, lut_config) != 0) { + pr_err("SC state LUT read err\n"); + return -1; + } + break; + case LUT_SEL_SA_STATE: + if (sa_state_lut_read(osi_core, lut_config) != 0) { + pr_err("SA state LUT read err\n"); + return -1; + } + break; + default: + //Unsupported LUT + return -1; + } + + return 0; +} + +static inline void commit_lut_data(struct osi_core_priv_data *const osi_core, + unsigned int const *const lut_data) +{ + unsigned char *base = (unsigned char *)osi_core->macsec_base; + int i; + + /* Commit the LUT entry to HW */ + for (i = 0; i < MACSEC_LUT_DATA_REG_CNT; i++) { + //pr_err("%s: lut_data[%d]: 0x%x\n", __func__, i, lut_data[i]); + osi_writel(lut_data[i], base + MACSEC_LUT_DATA(i)); + } +} + +static void rx_sa_state_lut_config( + struct osi_macsec_lut_config *const lut_config, + unsigned int *const lut_data) +{ + struct sa_state_outputs entry = lut_config->sa_state_out; + + lut_data[0] |= entry.next_pn; + lut_data[1] |= entry.lowest_pn; +} + +static void tx_sa_state_lut_config( + struct osi_macsec_lut_config *const lut_config, + unsigned int *const lut_data) +{ + unsigned int flags = lut_config->flags; + struct sa_state_outputs entry = lut_config->sa_state_out; + + lut_data[0] |= entry.next_pn; + if ((flags & LUT_FLAGS_ENTRY_VALID) == LUT_FLAGS_ENTRY_VALID) { + lut_data[1] |= SA_STATE_LUT_ENTRY_VALID; + } + +} + +static int sa_state_lut_config(struct osi_core_priv_data *const osi_core, + struct osi_macsec_lut_config *const lut_config) +{ + unsigned int lut_data[MACSEC_LUT_DATA_REG_CNT] = {0}; + struct macsec_table_config table_config = lut_config->table_config; + + switch (table_config.ctlr_sel) { + case CTLR_SEL_TX: + tx_sa_state_lut_config(lut_config, lut_data); + break; + case CTLR_SEL_RX: + rx_sa_state_lut_config(lut_config, lut_data); + break; + default: + return -1; + } + + commit_lut_data(osi_core, lut_data); + + return 0; +} + +static int sc_state_lut_config(struct osi_core_priv_data *const osi_core, + struct osi_macsec_lut_config *const lut_config) +{ + unsigned int lut_data[MACSEC_LUT_DATA_REG_CNT] = {0}; + struct sc_state_outputs entry = lut_config->sc_state_out; + + lut_data[0] |= entry.curr_an; + commit_lut_data(osi_core, lut_data); + + return 0; +} + +static void rx_sc_param_lut_config( + struct osi_macsec_lut_config *const lut_config, + unsigned int *const lut_data) +{ + struct 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; +} + +static void tx_sc_param_lut_config( + struct osi_macsec_lut_config *const lut_config, + unsigned int *const lut_data) +{ + struct 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] |= entry.tci << 5; + lut_data[2] |= entry.sci[0] << 8; + lut_data[2] |= entry.sci[1] << 16; + lut_data[2] |= entry.sci[2] << 24; + lut_data[3] |= entry.sci[3]; + lut_data[3] |= entry.sci[4] << 8; + lut_data[3] |= entry.sci[5] << 16; + lut_data[3] |= entry.sci[6] << 24; + lut_data[4] |= entry.sci[7]; + lut_data[4] |= entry.vlan_in_clear << 8; +} + +static int sc_param_lut_config(struct osi_core_priv_data *const osi_core, + struct osi_macsec_lut_config *const lut_config) +{ + unsigned int lut_data[MACSEC_LUT_DATA_REG_CNT] = {0}; + struct macsec_table_config table_config = lut_config->table_config; + struct sc_param_outputs entry = lut_config->sc_param_out; + + if (entry.key_index_start > KEY_INDEX_MAX) { + return -1; + } + + switch (table_config.ctlr_sel) { + case CTLR_SEL_TX: + tx_sc_param_lut_config(lut_config, lut_data); + break; + case CTLR_SEL_RX: + rx_sc_param_lut_config(lut_config, lut_data); + break; + } + + commit_lut_data(osi_core, lut_data); + + return 0; +} + +static int lut_config_inputs(struct osi_macsec_lut_config *const lut_config, + unsigned int *const lut_data) +{ + struct lut_inputs entry = lut_config->lut_in; + unsigned int flags; + int i; + + for (i = 0; i < LUT_BYTE_PATTERN_MAX; i++) { + if (entry.byte_pattern_offset[i] > + LUT_BYTE_PATTERN_MAX_OFFSET) { + return -1; + } + } + + if ((entry.vlan_pcp > VLAN_PCP_MAX) || + (entry.vlan_id > VLAN_ID_MAX)) { + return -1; + } + + /* TODO - validate if LUT_FLAGS_VLAN_VALID is incorrectly set + * when LUT_FLAGS_VLAN_PCP_VALID/VLAN_ID_VALID is not set. + */ + + /* TODO - validate if Byte pattern and byte pattern are both provided */ + + flags = lut_config->flags; + /* MAC DA */ + if ((flags & LUT_FLAGS_DA_BYTE0_VALID) == LUT_FLAGS_DA_BYTE0_VALID) { + lut_data[0] |= entry.da[0]; + lut_data[1] &= ~LUT_DA_BYTE0_INACTIVE; + } else { + lut_data[1] |= LUT_DA_BYTE0_INACTIVE; + } + + if ((flags & LUT_FLAGS_DA_BYTE1_VALID) == LUT_FLAGS_DA_BYTE1_VALID) { + lut_data[0] |= entry.da[1] << 8; + lut_data[1] &= ~LUT_DA_BYTE1_INACTIVE; + } else { + lut_data[1] |= LUT_DA_BYTE1_INACTIVE; + } + + if ((flags & LUT_FLAGS_DA_BYTE2_VALID) == LUT_FLAGS_DA_BYTE2_VALID) { + lut_data[0] |= entry.da[2] << 16; + lut_data[1] &= ~LUT_DA_BYTE2_INACTIVE; + } else { + lut_data[1] |= LUT_DA_BYTE2_INACTIVE; + } + + if ((flags & LUT_FLAGS_DA_BYTE3_VALID) == LUT_FLAGS_DA_BYTE3_VALID) { + lut_data[0] |= entry.da[3] << 24; + lut_data[1] &= ~LUT_DA_BYTE3_INACTIVE; + } else { + lut_data[1] |= LUT_DA_BYTE3_INACTIVE; + } + + if ((flags & LUT_FLAGS_DA_BYTE4_VALID) == LUT_FLAGS_DA_BYTE4_VALID) { + lut_data[1] |= entry.da[4]; + lut_data[1] &= ~LUT_DA_BYTE4_INACTIVE; + } else { + lut_data[1] |= LUT_DA_BYTE4_INACTIVE; + } + + if ((flags & LUT_FLAGS_DA_BYTE5_VALID) == LUT_FLAGS_DA_BYTE5_VALID) { + lut_data[1] |= entry.da[5] << 8; + lut_data[1] &= ~LUT_DA_BYTE5_INACTIVE; + } else { + lut_data[1] |= LUT_DA_BYTE5_INACTIVE; + } + + /* MAC SA */ + if ((flags & LUT_FLAGS_SA_BYTE0_VALID) == LUT_FLAGS_SA_BYTE0_VALID) { + lut_data[1] |= entry.sa[0] << 22; + lut_data[3] &= ~LUT_SA_BYTE0_INACTIVE; + } else { + lut_data[3] |= LUT_SA_BYTE0_INACTIVE; + } + + if ((flags & LUT_FLAGS_SA_BYTE1_VALID) == LUT_FLAGS_SA_BYTE1_VALID) { + lut_data[1] |= entry.sa[1] << 30; + lut_data[2] |= (entry.sa[1] >> 2); + lut_data[3] &= ~LUT_SA_BYTE1_INACTIVE; + } else { + lut_data[3] |= LUT_SA_BYTE1_INACTIVE; + } + + if ((flags & LUT_FLAGS_SA_BYTE2_VALID) == LUT_FLAGS_SA_BYTE2_VALID) { + lut_data[2] |= entry.sa[2] << 6; + lut_data[3] &= ~LUT_SA_BYTE2_INACTIVE; + } else { + lut_data[3] |= LUT_SA_BYTE2_INACTIVE; + } + + if ((flags & LUT_FLAGS_SA_BYTE3_VALID) == LUT_FLAGS_SA_BYTE3_VALID) { + lut_data[2] |= entry.sa[3] << 14; + lut_data[3] &= ~LUT_SA_BYTE3_INACTIVE; + } else { + lut_data[3] |= LUT_SA_BYTE3_INACTIVE; + } + + if ((flags & LUT_FLAGS_SA_BYTE4_VALID) == LUT_FLAGS_SA_BYTE4_VALID) { + lut_data[2] |= entry.sa[4] << 22; + lut_data[3] &= ~LUT_SA_BYTE4_INACTIVE; + } else { + lut_data[3] |= LUT_SA_BYTE4_INACTIVE; + } + + if ((flags & LUT_FLAGS_SA_BYTE5_VALID) == LUT_FLAGS_SA_BYTE5_VALID) { + lut_data[2] |= entry.sa[5] << 30; + lut_data[3] |= (entry.sa[5] >> 2); + lut_data[3] &= ~LUT_SA_BYTE5_INACTIVE; + } else { + lut_data[3] |= LUT_SA_BYTE5_INACTIVE; + } + + /* Ether type */ + if ((flags & LUT_FLAGS_ETHTYPE_VALID) == LUT_FLAGS_ETHTYPE_VALID) { + lut_data[3] |= entry.ethtype[0] << 12; + lut_data[3] |= entry.ethtype[1] << 20; + lut_data[3] &= ~LUT_ETHTYPE_INACTIVE; + } else { + lut_data[3] |= LUT_ETHTYPE_INACTIVE; + } + + /* VLAN */ + if ((flags & LUT_FLAGS_VLAN_VALID) == LUT_FLAGS_VLAN_VALID) { + /* VLAN PCP */ + if ((flags & LUT_FLAGS_VLAN_PCP_VALID) == + LUT_FLAGS_VLAN_PCP_VALID) { + lut_data[3] |= entry.vlan_pcp << 29; + lut_data[4] &= ~LUT_VLAN_PCP_INACTIVE; + } else { + lut_data[4] |= LUT_VLAN_PCP_INACTIVE; + } + + /* VLAN ID */ + if ((flags & LUT_FLAGS_VLAN_ID_VALID) == + LUT_FLAGS_VLAN_ID_VALID) { + lut_data[4] |= entry.vlan_id << 1; + lut_data[4] &= ~LUT_VLAN_ID_INACTIVE; + } else { + lut_data[4] |= LUT_VLAN_ID_INACTIVE; + } + lut_data[4] |= LUT_VLAN_ACTIVE; + } else { + lut_data[4] |= LUT_VLAN_PCP_INACTIVE; + lut_data[4] |= LUT_VLAN_ID_INACTIVE; + lut_data[4] &= ~LUT_VLAN_ACTIVE; + } + + /* Byte patterns */ + if ((flags & LUT_FLAGS_BYTE0_PATTERN_VALID) == + LUT_FLAGS_BYTE0_PATTERN_VALID) { + lut_data[4] |= entry.byte_pattern[0] << 15; + lut_data[4] |= entry.byte_pattern_offset[0] << 23; + lut_data[4] &= ~LUT_BYTE0_PATTERN_INACTIVE; + } else { + lut_data[4] |= LUT_BYTE0_PATTERN_INACTIVE; + } + if ((flags & LUT_FLAGS_BYTE1_PATTERN_VALID) == + LUT_FLAGS_BYTE1_PATTERN_VALID) { + lut_data[4] |= entry.byte_pattern[1] << 30; + lut_data[5] |= entry.byte_pattern[1] >> 2; + lut_data[5] |= entry.byte_pattern_offset[1] << 6; + lut_data[5] &= ~LUT_BYTE1_PATTERN_INACTIVE; + } else { + lut_data[5] |= LUT_BYTE1_PATTERN_INACTIVE; + } + + if ((flags & LUT_FLAGS_BYTE2_PATTERN_VALID) == + LUT_FLAGS_BYTE2_PATTERN_VALID) { + lut_data[5] |= entry.byte_pattern[2] << 13; + lut_data[5] |= entry.byte_pattern_offset[2] << 21; + lut_data[5] &= ~LUT_BYTE2_PATTERN_INACTIVE; + } else { + lut_data[5] |= LUT_BYTE2_PATTERN_INACTIVE; + } + + if ((flags & LUT_FLAGS_BYTE3_PATTERN_VALID) == + LUT_FLAGS_BYTE3_PATTERN_VALID) { + lut_data[5] |= entry.byte_pattern[3] << 28; + lut_data[6] |= entry.byte_pattern[3] >> 4; + lut_data[6] |= entry.byte_pattern_offset[3] << 4; + lut_data[6] &= ~LUT_BYTE3_PATTERN_INACTIVE; + } else { + lut_data[6] |= LUT_BYTE3_PATTERN_INACTIVE; + } + + /* Preempt mask */ + if ((flags & LUT_FLAGS_PREEMPT_VALID) == LUT_FLAGS_PREEMPT_VALID) { + if ((flags & LUT_FLAGS_PREEMPT) == LUT_FLAGS_PREEMPT) { + lut_data[6] |= LUT_PREEMPT; + } else { + lut_data[6] &= ~LUT_PREEMPT; + } + lut_data[6] &= ~LUT_PREEMPT_INACTIVE; + } else { + lut_data[6] |= LUT_PREEMPT_INACTIVE; + } + + return 0; +} + +static int rx_sci_lut_config(struct osi_macsec_lut_config *const lut_config, + unsigned int *const lut_data) +{ + unsigned int flags = lut_config->flags; + struct sci_lut_outputs entry = lut_config->sci_lut_out; + + if (entry.sc_index > SC_INDEX_MAX) { + return -1; + } + + lut_data[0] |= (entry.sci[0] | + (entry.sci[1] << 8) | + (entry.sci[2] << 16) | + (entry.sci[3] << 24)); + lut_data[1] |= (entry.sci[4] | + (entry.sci[5] << 8) | + (entry.sci[6] << 16) | + (entry.sci[7] << 24)); + + /* Preempt mask */ + if ((flags & LUT_FLAGS_PREEMPT_VALID) == LUT_FLAGS_PREEMPT_VALID) { + if ((flags & LUT_FLAGS_PREEMPT) == LUT_FLAGS_PREEMPT) { + lut_data[2] |= RX_SCI_LUT_PREEMPT; + } else { + lut_data[2] &= ~RX_SCI_LUT_PREEMPT; + } + lut_data[2] &= ~RX_SCI_LUT_PREEMPT_INACTIVE; + } else { + lut_data[2] |= RX_SCI_LUT_PREEMPT_INACTIVE; + } + + lut_data[2] |= entry.sc_index << 10; + + return 0; +} + +static int tx_sci_lut_config(struct osi_macsec_lut_config *const lut_config, + unsigned int *const lut_data) +{ + unsigned int flags = lut_config->flags; + struct sci_lut_outputs entry = lut_config->sci_lut_out; + unsigned int an_valid = entry.an_valid; + + if (lut_config_inputs(lut_config, lut_data) != 0) { + pr_err("LUT inputs error\n"); + return -1; + } + + /* Lookup result fields */ + if ((an_valid & AN0_VALID) == AN0_VALID) { + lut_data[6] |= LUT_AN0_VALID; + } + if ((an_valid & AN1_VALID) == AN1_VALID) { + lut_data[6] |= LUT_AN1_VALID; + } + if ((an_valid & AN2_VALID) == AN2_VALID) { + lut_data[6] |= LUT_AN2_VALID; + } + if ((an_valid & AN3_VALID) == AN3_VALID) { + lut_data[6] |= LUT_AN3_VALID; + } + + lut_data[6] |= entry.sc_index << 17; + + if ((flags & LUT_FLAGS_DVLAN_PKT) == LUT_FLAGS_DVLAN_PKT) { + lut_data[6] |= TX_SCI_LUT_DVLAN_PKT; + } + + if ((flags & LUT_FLAGS_DVLAN_OUTER_INNER_TAG_SEL) == + LUT_FLAGS_DVLAN_OUTER_INNER_TAG_SEL) { + lut_data[6] |= TX_SCI_LUT_DVLAN_OUTER_INNER_TAG_SEL; + } + return 0; +} + +static int sci_lut_config(struct osi_core_priv_data *const osi_core, + struct osi_macsec_lut_config *const lut_config) +{ + unsigned int lut_data[MACSEC_LUT_DATA_REG_CNT] = {0}; + struct macsec_table_config table_config = lut_config->table_config; + struct sci_lut_outputs entry = lut_config->sci_lut_out; + unsigned char *addr = (unsigned char *)osi_core->macsec_base; + unsigned int val = 0; + unsigned int index = lut_config->table_config.index; + + if ((entry.sc_index > SC_INDEX_MAX) || + (lut_config->table_config.index > SC_LUT_MAX_INDEX)) { + return -1; + } + + switch (table_config.ctlr_sel) { + case CTLR_SEL_TX: + if (tx_sci_lut_config(lut_config, lut_data) < 0) { + pr_err("Failed to config tx sci LUT\n"); + return -1; + } + commit_lut_data(osi_core, lut_data); + + if ((lut_config->flags & LUT_FLAGS_ENTRY_VALID) == + LUT_FLAGS_ENTRY_VALID) { + val = osi_readl(addr+TX_SCI_LUT_VALID); + val |= (1 << index); + osi_writel(val, addr+TX_SCI_LUT_VALID); + } else { + val = osi_readl(addr+TX_SCI_LUT_VALID); + val &= ~(1 << index); + osi_writel(val, addr+TX_SCI_LUT_VALID); + } + + break; + case CTLR_SEL_RX: + if (rx_sci_lut_config(lut_config, lut_data) < 0) { + pr_err("Failed to config rx sci LUT\n"); + return -1; + } + commit_lut_data(osi_core, lut_data); + + if ((lut_config->flags & LUT_FLAGS_ENTRY_VALID) == + LUT_FLAGS_ENTRY_VALID) { + val = osi_readl(addr+RX_SCI_LUT_VALID); + val |= (1 << index); + osi_writel(val, addr+RX_SCI_LUT_VALID); + } else { + val = osi_readl(addr+RX_SCI_LUT_VALID); + val &= ~(1 << index); + osi_writel(val, addr+RX_SCI_LUT_VALID); + } + + break; + default: + pr_err("Unknown controller select\n"); + return -1; + } + return 0; +} + +static int byp_lut_config(struct osi_core_priv_data *const osi_core, + struct osi_macsec_lut_config *const lut_config) +{ + unsigned int lut_data[MACSEC_LUT_DATA_REG_CNT] = {0}; + unsigned int flags = lut_config->flags; + unsigned char *addr = (unsigned char *)osi_core->macsec_base; + unsigned int val = 0; + unsigned int index = lut_config->table_config.index; + + if (lut_config_inputs(lut_config, lut_data) != 0) { + pr_err("LUT inputs error\n"); + return -1; + } + + /* Lookup output */ + if ((flags & LUT_FLAGS_CONTROLLED_PORT) == + LUT_FLAGS_CONTROLLED_PORT) { + lut_data[6] |= LUT_CONTROLLED_PORT; + } + + if ((flags & LUT_FLAGS_DVLAN_PKT) == LUT_FLAGS_DVLAN_PKT) { + lut_data[6] |= BYP_LUT_DVLAN_PKT; + } + + if ((flags & LUT_FLAGS_DVLAN_OUTER_INNER_TAG_SEL) == + 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 CTLR_SEL_TX: + if ((flags & LUT_FLAGS_ENTRY_VALID) == + LUT_FLAGS_ENTRY_VALID) { + val = osi_readl(addr+TX_BYP_LUT_VALID); + val |= (1 << index); + osi_writel(val, addr+TX_BYP_LUT_VALID); + } else { + val = osi_readl(addr+TX_BYP_LUT_VALID); + val &= ~(1 << index); + osi_writel(val, addr+TX_BYP_LUT_VALID); + } + break; + + case CTLR_SEL_RX: + if ((flags & LUT_FLAGS_ENTRY_VALID) == + LUT_FLAGS_ENTRY_VALID) { + val = osi_readl(addr+RX_BYP_LUT_VALID); + val |= (1 << index); + osi_writel(val, addr+RX_BYP_LUT_VALID); + } else { + val = osi_readl(addr+RX_BYP_LUT_VALID); + val &= ~(1 << index); + osi_writel(val, addr+RX_BYP_LUT_VALID); + } + + break; + default: + pr_err("Unknown controller select\n"); + return -1; + } + + return 0; +} + +static inline int lut_data_write(struct osi_core_priv_data *const osi_core, + struct osi_macsec_lut_config *const lut_config) +{ + switch (lut_config->lut_sel) { + case LUT_SEL_BYPASS: + if (byp_lut_config(osi_core, lut_config) != 0) { + pr_err("BYP LUT config err\n"); + return -1; + } + break; + case LUT_SEL_SCI: + if (sci_lut_config(osi_core, lut_config) != 0) { + pr_err("SCI LUT config err\n"); + return -1; + } + break; + case LUT_SEL_SC_PARAM: + if (sc_param_lut_config(osi_core, lut_config) != 0) { + pr_err("SC param LUT config err\n"); + return -1; + } + break; + case LUT_SEL_SC_STATE: + if (sc_state_lut_config(osi_core, lut_config) != 0) { + pr_err("SC state LUT config err\n"); + return -1; + } + break; + case LUT_SEL_SA_STATE: + if (sa_state_lut_config(osi_core, lut_config) != 0) { + pr_err("SA state LUT config err\n"); + return -1; + } + break; + default: + //Unsupported LUT + return -1; + } + + return 0; +} + +static int macsec_lut_config(struct osi_core_priv_data *const osi_core, + struct osi_macsec_lut_config *const lut_config) +{ + int ret = 0; + unsigned int lut_config_reg; + unsigned char *base = (unsigned char *)osi_core->macsec_base; + + /* Validate LUT config */ + if ((lut_config->table_config.ctlr_sel > CTLR_SEL_MAX) || + (lut_config->table_config.rw > RW_MAX) || + (lut_config->table_config.index > TABLE_INDEX_MAX) || + (lut_config->lut_sel > LUT_SEL_MAX)) { + pr_err("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); + /* TODO - validate using a local cache + * if index is already active */ + return -1; + } + + /* Wait for previous LUT update to finish */ + ret = poll_for_lut_update(osi_core); + if (ret < 0) { + return ret; + } + +/* pr_err("%s: LUT: %hu ctrl: %hu rw: %hu idx: %hu flags: %#x\n", __func__, + lut_config->lut_sel, lut_config->table_config.ctlr_sel, + lut_config->table_config.rw, lut_config->table_config.index, + lut_config->flags); */ + + lut_config_reg = osi_readl(base + MACSEC_LUT_CONFIG); + if (lut_config->table_config.ctlr_sel) { + lut_config_reg |= LUT_CONFIG_CTLR_SEL; + } else { + lut_config_reg &= ~LUT_CONFIG_CTLR_SEL; + } + + if (lut_config->table_config.rw) { + lut_config_reg |= 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 &= ~LUT_CONFIG_RW; + } + + lut_config_reg &= ~LUT_CONFIG_LUT_SEL_MASK; + lut_config_reg |= (lut_config->lut_sel << LUT_CONFIG_LUT_SEL_SHIFT); + + lut_config_reg &= ~LUT_CONFIG_INDEX_MASK; + lut_config_reg |= (lut_config->table_config.index); + + lut_config_reg |= LUT_CONFIG_UPDATE; + osi_writel(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) { + ret = lut_data_read(osi_core, lut_config); + if (ret < 0) { + return ret; + } + } + + return 0; +} + +static inline void handle_rx_sc_invalid_key( + struct osi_core_priv_data *const osi_core) +{ + unsigned char *addr = (unsigned char *)osi_core->macsec_base; + unsigned int clear = 0; + + pr_err("%s()\n", __func__); + + /** check which SC/AN had triggered and clear */ + /* rx_sc0_7 */ + clear = osi_readl(addr + RX_SC_KEY_INVALID_STS0_0); + osi_writel(clear, addr + RX_SC_KEY_INVALID_STS0_0); + /* rx_sc8_15 */ + clear = osi_readl(addr + RX_SC_KEY_INVALID_STS1_0); + osi_writel(clear, addr + RX_SC_KEY_INVALID_STS1_0); +} + +static inline void handle_tx_sc_invalid_key( + struct osi_core_priv_data *const osi_core) +{ + unsigned char *addr = (unsigned char *)osi_core->macsec_base; + unsigned int clear = 0; + + pr_err("%s()\n", __func__); + + /** check which SC/AN had triggered and clear */ + /* tx_sc0_7 */ + clear = osi_readl(addr + TX_SC_KEY_INVALID_STS0_0); + osi_writel(clear, addr + TX_SC_KEY_INVALID_STS0_0); + /* tx_sc8_15 */ + clear = osi_readl(addr + TX_SC_KEY_INVALID_STS1_0); + osi_writel(clear, addr + TX_SC_KEY_INVALID_STS1_0); +} + +static inline void handle_safety_err_irq( + struct osi_core_priv_data *const osi_core) +{ + pr_err("%s()\n", __func__); +} + +static inline void handle_rx_sc_replay_err( + struct osi_core_priv_data *const osi_core) +{ + unsigned char *addr = (unsigned char *)osi_core->macsec_base; + unsigned int clear = 0; + + /* pr_err("%s()\n", __func__); */ + + /* rx_sc0_7 */ + clear = osi_readl(addr + RX_SC_REPLAY_ERROR_STATUS0_0); + osi_writel(clear, addr + RX_SC_REPLAY_ERROR_STATUS0_0); + /* rx_sc8_15 */ + clear = osi_readl(addr + RX_SC_REPLAY_ERROR_STATUS1_0); + osi_writel(clear, addr + RX_SC_REPLAY_ERROR_STATUS1_0); +} + +static inline void handle_rx_pn_exhausted( + struct osi_core_priv_data *const osi_core) +{ + unsigned char *addr = (unsigned char *)osi_core->macsec_base; + unsigned int clear = 0; + + /* pr_err("%s()\n", __func__); */ + + /* TODO: Do you need re-enable SC/AN? */ + + /* check which SC/AN had triggered and clear + */ + /* rx_sc0_7 */ + clear = osi_readl(addr + RX_SC_PN_EXHAUSTED_STATUS0_0); + osi_writel(clear, addr + RX_SC_PN_EXHAUSTED_STATUS0_0); + /* rx_sc8_15 */ + clear = osi_readl(addr + RX_SC_PN_EXHAUSTED_STATUS1_0); + osi_writel(clear, addr + RX_SC_PN_EXHAUSTED_STATUS1_0); +} + +static inline void handle_tx_sc_err(struct osi_core_priv_data *const osi_core) +{ + unsigned char *addr = (unsigned char *)osi_core->macsec_base; + unsigned int clear = 0; + + /* pr_err("%s()\n", __func__); */ + + /* TODO: Do you need re-enable SC/AN? */ + + clear = osi_readl(addr + TX_SC_ERROR_INTERRUPT_STATUS_0); + + osi_writel(clear, addr + TX_SC_ERROR_INTERRUPT_STATUS_0); + +} + +static inline void handle_tx_pn_threshold( + struct osi_core_priv_data *const osi_core) +{ + unsigned char *addr = (unsigned char *)osi_core->macsec_base; + unsigned int clear = 0; + + /* pr_err("%s()\n", __func__); */ + + /* TODO: Do you need re-enable SC/AN? */ + + /* check which SC/AN had triggered and clear + */ + /* tx_sc0_7 */ + clear = osi_readl(addr + TX_SC_PN_THRESHOLD_STATUS0_0); + osi_writel(clear, addr + TX_SC_PN_THRESHOLD_STATUS0_0); + /* tx_sc8_15 */ + clear = osi_readl(addr + TX_SC_PN_THRESHOLD_STATUS1_0); + osi_writel(clear, addr + TX_SC_PN_THRESHOLD_STATUS1_0); +} + +static inline void handle_tx_pn_exhausted( + struct osi_core_priv_data *const osi_core) +{ + unsigned char *addr = (unsigned char *)osi_core->macsec_base; + unsigned int clear = 0; + + /* pr_err("%s()\n", __func__); */ + + /* TODO: Do you need re-enable SC/AN? */ + + /* check which SC/AN had triggered and clear + */ + /* tx_sc0_7 */ + clear = osi_readl(addr + TX_SC_PN_EXHAUSTED_STATUS0_0); + osi_writel(clear, addr + TX_SC_PN_EXHAUSTED_STATUS0_0); + /* tx_sc8_15 */ + clear = osi_readl(addr + TX_SC_PN_EXHAUSTED_STATUS1_0); + osi_writel(clear, addr + TX_SC_PN_EXHAUSTED_STATUS1_0); +} + +static inline void handle_tx_irq(struct osi_core_priv_data *const osi_core) +{ + unsigned int tx_isr, clear = 0; + unsigned char *addr = (unsigned char *)osi_core->macsec_base; + + tx_isr = osi_readl(addr + TX_ISR); + pr_err("%s(): tx_isr 0x%x\n", __func__, tx_isr); + if ((tx_isr & TX_DBG_BUF_CAPTURE_DONE) == TX_DBG_BUF_CAPTURE_DONE) { + osi_core->macsec_irq_stats.tx_dbg_capture_done++; + clear |= TX_DBG_BUF_CAPTURE_DONE; + } + + if ((tx_isr & TX_MTU_CHECK_FAIL) == TX_MTU_CHECK_FAIL) { + osi_core->macsec_irq_stats.tx_mtu_check_fail++; + clear |= TX_MTU_CHECK_FAIL; + } + + if ((tx_isr & TX_AES_GCM_BUF_OVF) == TX_AES_GCM_BUF_OVF) { + osi_core->macsec_irq_stats.tx_aes_gcm_buf_ovf++; + clear |= TX_AES_GCM_BUF_OVF; + } + + if ((tx_isr & TX_SC_AN_NOT_VALID) == TX_SC_AN_NOT_VALID) { + osi_core->macsec_irq_stats.tx_sc_an_not_valid++; + handle_tx_sc_err(osi_core); + clear |= TX_SC_AN_NOT_VALID; + } + + if ((tx_isr & TX_MAC_CRC_ERROR) == TX_MAC_CRC_ERROR) { + osi_core->macsec_irq_stats.tx_mac_crc_error++; + clear |= TX_MAC_CRC_ERROR; + } + + if ((tx_isr & TX_PN_THRSHLD_RCHD) == TX_PN_THRSHLD_RCHD) { + osi_core->macsec_irq_stats.tx_pn_threshold++; + /* TODO - need to check which SC/AN had triggered */ + handle_tx_pn_threshold(osi_core); + clear |= TX_PN_THRSHLD_RCHD; + } + + if ((tx_isr & TX_PN_EXHAUSTED) == TX_PN_EXHAUSTED) { + osi_core->macsec_irq_stats.tx_pn_exhausted++; + /* TODO - need to check which SC/AN had triggered */ + handle_tx_pn_exhausted(osi_core); + clear |= TX_PN_EXHAUSTED; + } + if (clear) { + pr_err("%s(): write tx_isr 0x%x\n", __func__, clear); + osi_writel(clear, addr + TX_ISR); + } +} + +static inline void handle_rx_irq(struct osi_core_priv_data *const osi_core) +{ + unsigned int rx_isr, clear = 0; + unsigned char *addr = (unsigned char *)osi_core->macsec_base; + + rx_isr = osi_readl(addr + RX_ISR); + pr_err("%s(): rx_isr 0x%x\n", __func__, rx_isr); + + if ((rx_isr & RX_DBG_BUF_CAPTURE_DONE) == RX_DBG_BUF_CAPTURE_DONE) { + osi_core->macsec_irq_stats.rx_dbg_capture_done++; + clear |= RX_DBG_BUF_CAPTURE_DONE; + } + + if ((rx_isr & RX_ICV_ERROR) == RX_ICV_ERROR) { + osi_core->macsec_irq_stats.rx_icv_err_threshold++; + clear |= RX_ICV_ERROR; + } + + if ((rx_isr & RX_REPLAY_ERROR) == RX_REPLAY_ERROR) { + osi_core->macsec_irq_stats.rx_replay_error++; + handle_rx_sc_replay_err(osi_core); + clear |= RX_REPLAY_ERROR; + } + + if ((rx_isr & RX_MTU_CHECK_FAIL) == RX_MTU_CHECK_FAIL) { + osi_core->macsec_irq_stats.rx_mtu_check_fail++; + clear |= RX_MTU_CHECK_FAIL; + } + + if ((rx_isr & RX_AES_GCM_BUF_OVF) == RX_AES_GCM_BUF_OVF) { + osi_core->macsec_irq_stats.rx_aes_gcm_buf_ovf++; + clear |= RX_AES_GCM_BUF_OVF; + } + + if ((rx_isr & RX_MAC_CRC_ERROR) == RX_MAC_CRC_ERROR) { + osi_core->macsec_irq_stats.rx_mac_crc_error++; + clear |= RX_MAC_CRC_ERROR; + } + + if ((rx_isr & RX_PN_EXHAUSTED) == RX_PN_EXHAUSTED) { + osi_core->macsec_irq_stats.rx_pn_exhausted++; + /* TODO - need to check which SC/AN had triggered */ + handle_rx_pn_exhausted(osi_core); + clear |= RX_PN_EXHAUSTED; + } + if (clear) { + pr_err("%s(): write rx_isr 0x%x\n", __func__, clear); + osi_writel(clear, addr + RX_ISR); + } +} + +static inline void handle_common_irq(struct osi_core_priv_data *const osi_core) +{ + unsigned int common_isr, clear = 0; + unsigned char *addr = (unsigned char *)osi_core->macsec_base; + + common_isr = osi_readl(addr + COMMON_ISR); + pr_err("%s(): common_isr 0x%x\n", __func__, common_isr); + + if ((common_isr & SECURE_REG_VIOL) == SECURE_REG_VIOL) { + osi_core->macsec_irq_stats.secure_reg_viol++; + clear |= SECURE_REG_VIOL; + } + + if ((common_isr & RX_UNINIT_KEY_SLOT) == RX_UNINIT_KEY_SLOT) { + osi_core->macsec_irq_stats.rx_uninit_key_slot++; + clear |= RX_UNINIT_KEY_SLOT; + handle_rx_sc_invalid_key(osi_core); + } + + if ((common_isr & RX_LKUP_MISS) == RX_LKUP_MISS) { + osi_core->macsec_irq_stats.rx_lkup_miss++; + clear |= RX_LKUP_MISS; + } + + if ((common_isr & TX_UNINIT_KEY_SLOT) == TX_UNINIT_KEY_SLOT) { + osi_core->macsec_irq_stats.tx_uninit_key_slot++; + clear |= TX_UNINIT_KEY_SLOT; + handle_tx_sc_invalid_key(osi_core); + } + + if ((common_isr & TX_LKUP_MISS) == TX_LKUP_MISS) { + osi_core->macsec_irq_stats.tx_lkup_miss++; + clear |= TX_LKUP_MISS; + } + if (clear) { + osi_writel(clear, addr + COMMON_ISR); + } +} + +static void macsec_handle_ns_irq(struct osi_core_priv_data *const osi_core) +{ + unsigned int irq_common_sr, common_isr; + unsigned char *addr = (unsigned char *)osi_core->macsec_base; + + irq_common_sr = osi_readl(addr + INTERRUPT_COMMON_SR); + pr_err("%s(): common_sr 0x%x\n", __func__, irq_common_sr); + if ((irq_common_sr & COMMON_SR_TX) == COMMON_SR_TX) { + handle_tx_irq(osi_core); + } + + if ((irq_common_sr & COMMON_SR_RX) == COMMON_SR_RX) { + handle_rx_irq(osi_core); + } + + if ((irq_common_sr & COMMON_SR_SFTY_ERR) == COMMON_SR_SFTY_ERR) { + handle_safety_err_irq(osi_core); + } + + common_isr = osi_readl(addr + COMMON_ISR); + if (common_isr != OSI_NONE) { + handle_common_irq(osi_core); + } +} + +static void macsec_handle_s_irq(struct osi_core_priv_data *const osi_core) +{ + unsigned int common_isr; + unsigned char *addr = (unsigned char *)osi_core->macsec_base; + + pr_err("%s()\n", __func__); + + common_isr = osi_readl(addr + COMMON_ISR); + if (common_isr != OSI_NONE) { + handle_common_irq(osi_core); + } + + return; +} + +static int macsec_loopback_config(struct osi_core_priv_data *const osi_core, + unsigned int enable) +{ + unsigned char *base = (unsigned char *)osi_core->macsec_base; + unsigned int val; + + val = osi_readl(base + MACSEC_CONTROL1); + pr_err("Read MACSEC_CONTROL1: 0x%x\n", val); + + if (enable == OSI_ENABLE) { + val |= LOOPBACK_MODE_EN; + } else if (enable == OSI_DISABLE) { + val &= ~LOOPBACK_MODE_EN; + } else { + return -1; + } + + pr_err("Write MACSEC_CONTROL1: 0x%x\n", val); + osi_writel(val, base + MACSEC_CONTROL1); + return 0; +} + +static int clear_lut(struct osi_core_priv_data *const osi_core) +{ + struct osi_macsec_lut_config lut_config = {0}; + struct osi_macsec_kt_config kt_config = {0}; + struct macsec_table_config *table_config = &lut_config.table_config; + int i, j; + int ret = 0; + + table_config->rw = LUT_WRITE; + /* Clear all the LUT's which have a dedicated LUT valid bit per entry */ + + /* Tx/Rx BYP LUT */ + lut_config.lut_sel = LUT_SEL_BYPASS; + for (i = 0; i <= CTLR_SEL_MAX; i++) { + table_config->ctlr_sel = i; + for (j = 0; j <= BYP_LUT_MAX_INDEX; j++) { + table_config->index = j; + ret = macsec_lut_config(osi_core, &lut_config); + if (ret < 0) { + pr_err("Error clearing CTLR:LUT:INDEX: %d:%d:%d\n", + i, lut_config.lut_sel, j); + return ret; + } + } + } + + /* Tx/Rx SCI LUT */ + lut_config.lut_sel = LUT_SEL_SCI; + for (i = 0; i <= CTLR_SEL_MAX; i++) { + table_config->ctlr_sel = i; + for (j = 0; j <= SC_LUT_MAX_INDEX; j++) { + table_config->index = j; + ret = macsec_lut_config(osi_core, &lut_config); + if (ret < 0) { + pr_err("Error clearing CTLR:LUT:INDEX: %d:%d:%d\n", + i, lut_config.lut_sel, j); + return ret; + } + } + } + + /* Tx/Rx SC param LUT */ + lut_config.lut_sel = LUT_SEL_SC_PARAM; + for (i = 0; i <= CTLR_SEL_MAX; i++) { + table_config->ctlr_sel = i; + for (j = 0; j <= SC_LUT_MAX_INDEX; j++) { + table_config->index = j; + ret = macsec_lut_config(osi_core, &lut_config); + if (ret < 0) { + pr_err("Error clearing CTLR:LUT:INDEX: %d:%d:%d\n", + i, lut_config.lut_sel, j); + return ret; + } + } + } + + /* Tx/Rx SC state */ + lut_config.lut_sel = LUT_SEL_SC_STATE; + for (i = 0; i <= CTLR_SEL_MAX; i++) { + table_config->ctlr_sel = i; + for (j = 0; j <= SC_LUT_MAX_INDEX; j++) { + table_config->index = j; + ret = macsec_lut_config(osi_core, &lut_config); + if (ret < 0) { + pr_err("Error clearing CTLR:LUT:INDEX: %d:%d:%d\n", + i, lut_config.lut_sel, j); + return ret; + } + } + } + + /* Tx SA state LUT */ + lut_config.lut_sel = LUT_SEL_SA_STATE; + table_config->ctlr_sel = CTLR_SEL_TX; + for (j = 0; j <= SA_LUT_MAX_INDEX; j++) { + table_config->index = j; + ret = macsec_lut_config(osi_core, &lut_config); + if (ret < 0) { + pr_err("Error clearing Tx LUT:INDEX: %d:%d\n", + lut_config.lut_sel, j); + return ret; + } + } + + /* Rx SA state LUT */ + lut_config.lut_sel = LUT_SEL_SA_STATE; + table_config->ctlr_sel = CTLR_SEL_RX; + for (j = 0; j <= SA_LUT_MAX_INDEX; j++) { + table_config->index = j; + ret = macsec_lut_config(osi_core, &lut_config); + if (ret < 0) { + pr_err("Error clearing Rx LUT:INDEX: %d:%d\n", + lut_config.lut_sel, j); + return ret; + } + } + + /* Key table */ + table_config = &kt_config.table_config; + table_config->rw = LUT_WRITE; + for (i = 0; i <= CTLR_SEL_MAX; i++) { + table_config->ctlr_sel = i; + for (j = 0; j <= TABLE_INDEX_MAX; j++) { + table_config->index = j; + ret = macsec_kt_config(osi_core, &kt_config); + if (ret < 0) { + pr_err("Error clearing KT CTLR:INDEX: %d:%d\n", + i, j); + return ret; + } + } + } + + return ret; +} + +static int macsec_deinit(struct osi_core_priv_data *const osi_core) +{ + int i; + + for (i = CTLR_SEL_TX; i <= CTLR_SEL_RX; i++) { + osi_memset(&osi_core->macsec_lut_status[i], OSI_NONE, + sizeof(struct osi_macsec_lut_status)); + } + return 0; +} + +static int macsec_init(struct osi_core_priv_data *const osi_core) +{ + unsigned int val = 0; + struct osi_macsec_lut_config lut_config = {0}; + struct macsec_table_config *table_config = &lut_config.table_config; + /* Store MAC address in reverse, per HW design */ + unsigned char mac_da_mkpdu[OSI_ETH_ALEN] = {0x3, 0x0, 0x0, + 0xC2, 0x80, 0x01}; + unsigned char mac_da_bc[OSI_ETH_ALEN] = {0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF}; + unsigned int mtu = osi_core->mtu + MACSEC_TAG_ICV_LEN; + unsigned char *addr = (unsigned char *)osi_core->macsec_base; + int ret = 0; + int i, j; + + /* 1. Set MTU */ + val = osi_readl(addr + TX_MTU_LEN); + pr_err("Read TX_MTU_LEN: 0x%x\n", val); + val &= ~(MTU_LENGTH_MASK); + val |= (mtu & MTU_LENGTH_MASK); + pr_err("Write TX_MTU_LEN: 0x%x\n", val); + osi_writel(val, addr + TX_MTU_LEN); + + val = osi_readl(addr + RX_MTU_LEN); + pr_err("Read RX_MTU_LEN: 0x%x\n", val); + val &= ~(MTU_LENGTH_MASK); + val |= (mtu & MTU_LENGTH_MASK); + pr_err("Write RX_MTU_LEN: 0x%x\n", val); + osi_writel(val, addr + RX_MTU_LEN); + + /* 2. Set essential MACsec control configuration */ + val = osi_readl(addr + MACSEC_CONTROL0); + pr_err("Read MACSEC_CONTROL0: 0x%x\n", val); + val |= (TX_LKUP_MISS_NS_INTR | RX_LKUP_MISS_NS_INTR | + TX_LKUP_MISS_BYPASS | RX_LKUP_MISS_BYPASS); + val &= ~(VALIDATE_FRAMES_MASK); + val |= VALIDATE_FRAMES_STRICT; + val |= RX_REPLAY_PROT_EN; + pr_err("Write MACSEC_CONTROL0: 0x%x\n", val); + osi_writel(val, addr + MACSEC_CONTROL0); + + val = osi_readl(addr + MACSEC_CONTROL1); + pr_err("Read MACSEC_CONTROL1: 0x%x\n", val); + val |= (RX_MTU_CHECK_EN | TX_LUT_PRIO_BYP | TX_MTU_CHECK_EN); + pr_err("Write MACSEC_CONTROL1: 0x%x\n", val); + osi_writel(val, addr + MACSEC_CONTROL1); + + /* set DVLAN tag ethertype */ + + /* val = DVLAN_TAG_ETHERTYPE; + pr_err("Write MACSEC_TX_DVLAN_CONTROL_0: 0x%x\n", val); + osi_writel(val, addr + MACSEC_TX_DVLAN_CONTROL_0); + pr_err("Write MACSEC_RX_DVLAN_CONTROL_0: 0x%x\n", val); + osi_writel(val, addr + MACSEC_RX_DVLAN_CONTROL_0); */ + + val = osi_readl(addr + STATS_CONTROL_0); + pr_err("Read STATS_CONTROL_0: 0x%x\n", val); + /* set STATS rollover bit */ + val |= STATS_CONTROL0_CNT_RL_OVR_CPY; + pr_err("Write STATS_CONTROL_0: 0x%x\n", val); + osi_writel(val, addr + STATS_CONTROL_0); + + /* 3. Enable default interrupts needed */ + val = osi_readl(addr + TX_IMR); + pr_err("Read TX_IMR: 0x%x\n", val); + val |= (TX_DBG_BUF_CAPTURE_DONE_INT_EN | + TX_MTU_CHECK_FAIL_INT_EN | TX_MAC_CRC_ERROR_INT_EN | + TX_SC_AN_NOT_VALID_INT_EN | TX_AES_GCM_BUF_OVF_INT_EN | + TX_PN_EXHAUSTED_INT_EN | TX_PN_THRSHLD_RCHD_INT_EN); + pr_err("Write TX_IMR: 0x%x\n", val); + osi_writel(val, addr + TX_IMR); + + val = osi_readl(addr + RX_IMR); + pr_err("Read RX_IMR: 0x%x\n", val); + + val |= (RX_DBG_BUF_CAPTURE_DONE_INT_EN | + RX_ICV_ERROR_INT_EN | RX_REPLAY_ERROR_INT_EN | + RX_MTU_CHECK_FAIL_INT_EN | RX_MAC_CRC_ERROR_INT_EN | + RX_AES_GCM_BUF_OVF_INT_EN | + RX_PN_EXHAUSTED_INT_EN + ); + pr_err("Write RX_IMR: 0x%x\n", val); + osi_writel(val, addr + RX_IMR); + + val = osi_readl(addr + COMMON_IMR); + pr_err("Read COMMON_IMR: 0x%x\n", val); + + val |= (SECURE_REG_VIOL_INT_EN | RX_UNINIT_KEY_SLOT_INT_EN | + RX_LKUP_MISS_INT_EN | TX_UNINIT_KEY_SLOT_INT_EN | + TX_LKUP_MISS_INT_EN); + pr_err("Write COMMON_IMR: 0x%x\n", val); + osi_writel(val, addr + COMMON_IMR); + + /* 4. TODO - Route safety intr to LIC */ + val = osi_readl(addr + INTERRUPT_MASK1_0); + pr_err("Read INTERRUPT_MASK1_0: 0x%x\n", val); + val |= SFTY_ERR_UNCORR_INT_EN; + pr_err("Write INTERRUPT_MASK1_0: 0x%x\n", val); + osi_writel(val, addr + INTERRUPT_MASK1_0); + + /* 5. Set AES mode + * Default power on reset is AES-GCM128, leave it. + */ + + /* 6. Invalidate LUT entries */ + ret = clear_lut(osi_core); + if (ret < 0) { + pr_err("Invalidating all LUT's failed\n"); + return ret; + } + + /* 7. Set default BYP for MKPDU/BC packets */ + table_config->rw = LUT_WRITE; + lut_config.lut_sel = LUT_SEL_BYPASS; + lut_config.flags |= (LUT_FLAGS_DA_VALID | + LUT_FLAGS_ENTRY_VALID); + for (j = 0; j < OSI_ETH_ALEN; j++) { + lut_config.lut_in.da[j] = mac_da_bc[j]; + } + + for (i = CTLR_SEL_TX; i <= CTLR_SEL_RX; i++) { + table_config->ctlr_sel = (unsigned short) i; + table_config->index = + osi_core->macsec_lut_status[i].next_byp_idx; + ret = macsec_lut_config(osi_core, &lut_config); + if (ret < 0) { + pr_err("Failed to set BYP for BC addr"); + goto exit; + } else { + osi_core->macsec_lut_status[i].next_byp_idx++; + } + } + + for (j = 0; j < OSI_ETH_ALEN; j++) { + lut_config.lut_in.da[j] = mac_da_mkpdu[j]; + } + + for (i = CTLR_SEL_TX; i <= CTLR_SEL_RX; i++) { + table_config->ctlr_sel = (unsigned short) i; + table_config->index = + osi_core->macsec_lut_status[i].next_byp_idx; + ret = macsec_lut_config(osi_core, &lut_config); + if (ret < 0) { + pr_err("Failed to set BYP for MKPDU multicast DA"); + goto exit; + } else { + osi_core->macsec_lut_status[i].next_byp_idx++; + } + } + +exit: + return ret; +} + +static struct osi_macsec_sc_info *find_existing_sc( + struct osi_core_priv_data *const osi_core, + struct osi_macsec_sc_info *const sc, + unsigned short ctlr) +{ + struct osi_macsec_lut_status *lut_status = + &osi_core->macsec_lut_status[ctlr]; + int i; + + for (i = 0; i < lut_status->next_sc_idx; i++) { + if (osi_memcmp(lut_status->sc_info[i].sci, sc->sci, SCI_LEN) == + OSI_NONE) { + return &lut_status->sc_info[i]; + } + } + + return OSI_NULL; +} + +static int del_upd_sc(struct osi_core_priv_data *const osi_core, + struct osi_macsec_sc_info *existing_sc, + struct osi_macsec_sc_info *const sc, + unsigned short ctlr) +{ + struct osi_macsec_lut_config lut_config = {0}; + struct osi_macsec_kt_config kt_config = {0}; + struct macsec_table_config *table_config; + int 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 = 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 = LUT_SEL_SCI; + table_config->index = sc->sc_idx_start; + ret = macsec_lut_config(osi_core, &lut_config); + if (ret < 0) { + pr_err("%s: Failed to del SCI LUT", __func__); + pr_err("%s: index = %hu", __func__, sc->sc_idx_start); + goto err_sci; + } + + /* 2. SC Param LUT */ + lut_config.lut_sel = LUT_SEL_SC_PARAM; + ret = macsec_lut_config(osi_core, &lut_config); + if (ret < 0) { + pr_err("%s: Failed to del SC param", __func__); + goto err_sc_param; + } + + /* 3. SC state LUT */ + lut_config.lut_sel = LUT_SEL_SC_STATE; + ret = macsec_lut_config(osi_core, &lut_config); + if (ret < 0) { + pr_err("%s: Failed to del SC state", __func__); + goto err_sc_state; + } + } + + /* 4. SA State LUT */ + lut_config.lut_sel = LUT_SEL_SA_STATE; + table_config->index = (sc->sc_idx_start * MAX_NUM_SA) + sc->curr_an; + ret = macsec_lut_config(osi_core, &lut_config); + if (ret < 0) { + pr_err("%s: Failed to del SA state", __func__); + goto err_sa_state; + } + + /* 5. Key LUT */ + table_config = &kt_config.table_config; + table_config->ctlr_sel = ctlr; + table_config->rw = LUT_WRITE; + /* Each SC has MAX_NUM_SA's supported in HW */ + table_config->index = (sc->sc_idx_start * MAX_NUM_SA) + sc->curr_an; + ret = macsec_kt_config(osi_core, &kt_config); + if (ret < 0) { + pr_err("%s: Failed to del SAK", __func__); + goto err_kt; + } + + existing_sc->an_valid &= ~OSI_BIT(sc->curr_an); + + return 0; + +err_kt: + /* TODO cleanup SA state LUT */ +err_sa_state: + /* TODO Cleanup SC state LUT */ +err_sc_state: + /* TODO Cleanup SC param LUT */ +err_sc_param: + /* TODO cleanup SC LUT */ +err_sci: + return -1; +} + +static int add_upd_sc(struct osi_core_priv_data *const osi_core, + struct osi_macsec_sc_info *const sc, + unsigned short ctlr) +{ + struct osi_macsec_lut_config lut_config = {0}; + struct osi_macsec_kt_config kt_config = {0}; + struct macsec_table_config *table_config; + int ret, i; +#if 1 /* HKEY GENERATION */ + /* TODO - Move this to OSD */ + struct crypto_cipher *tfm; + unsigned char hkey[KEY_LEN_128]; + unsigned char zeros[KEY_LEN_128] = {0}; + + tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); + if (crypto_cipher_setkey(tfm, sc->sak, KEY_LEN_128)) { + pr_err("%s: Failed to set cipher key for H generation", + __func__); + return -1; + } + crypto_cipher_encrypt_one(tfm, hkey, zeros); + pr_err("\n%s: Generated H key: ", __func__); + for (i = 0; i < KEY_LEN_128; i++) { + pr_cont(" %02x", hkey[i]); + } + pr_err("\n"); + crypto_free_cipher(tfm); +#endif /* HKEY GENERATION */ + + /* 1. Key LUT */ + table_config = &kt_config.table_config; + table_config->ctlr_sel = ctlr; + table_config->rw = LUT_WRITE; + /* Each SC has MAX_NUM_SA's supported in HW */ + table_config->index = (sc->sc_idx_start * MAX_NUM_SA) + sc->curr_an; + kt_config.flags |= LUT_FLAGS_ENTRY_VALID; + + /* Program in reverse order as per HW design */ + for (i = 0; i < KEY_LEN_128; i++) { + kt_config.entry.sak[i] = sc->sak[KEY_LEN_128 - 1 - i]; + kt_config.entry.h[i] = hkey[KEY_LEN_128 - 1 - i]; + } + ret = macsec_kt_config(osi_core, &kt_config); + if (ret < 0) { + pr_err("%s: Failed to set SAK", __func__); + return -1; + } + + table_config = &lut_config.table_config; + table_config->ctlr_sel = ctlr; + table_config->rw = LUT_WRITE; + + /* 2. SA state LUT */ + lut_config.lut_sel = LUT_SEL_SA_STATE; + table_config->index = (sc->sc_idx_start * MAX_NUM_SA) + sc->curr_an; + lut_config.sa_state_out.next_pn = sc->next_pn; + /* TODO - LLPN might have to be updated out of band for replay prot*/ + lut_config.sa_state_out.lowest_pn = sc->next_pn; + lut_config.flags |= LUT_FLAGS_ENTRY_VALID; + ret = macsec_lut_config(osi_core, &lut_config); + if (ret < 0) { + pr_err("%s: Failed to set SA state", __func__); + goto err_sa_state; + } + + /* 3. SC state LUT */ + lut_config.flags = OSI_NONE; + lut_config.lut_sel = LUT_SEL_SC_STATE; + table_config->index = 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) { + pr_err("%s: Failed to set SC state", __func__); + goto err_sc_state; + } + + /* 4. SC param LUT */ + lut_config.flags = OSI_NONE; + lut_config.lut_sel = LUT_SEL_SC_PARAM; + table_config->index = sc->sc_idx_start; + /* Program in reverse order as per HW design */ + for (i = 0; i < SCI_LEN; i++) { + lut_config.sc_param_out.sci[i] = sc->sci[SCI_LEN - 1 - i]; + } + lut_config.sc_param_out.key_index_start = + (sc->sc_idx_start * MAX_NUM_SA); + lut_config.sc_param_out.pn_max = PN_MAX_DEFAULT; + lut_config.sc_param_out.pn_threshold = PN_THRESHOLD_DEFAULT; + lut_config.sc_param_out.pn_window = PN_MAX_DEFAULT; + lut_config.sc_param_out.tci = TCI_DEFAULT; + lut_config.sc_param_out.vlan_in_clear = VLAN_IN_CLEAR_DEFAULT; + ret = macsec_lut_config(osi_core, &lut_config); + if (ret < 0) { + pr_err("%s: Failed to set SC param", __func__); + goto err_sc_param; + } + + /* 5. SCI LUT */ + lut_config.flags = OSI_NONE; + lut_config.lut_sel = LUT_SEL_SCI; + table_config->index = sc->sc_idx_start; + /* Program in reverse order as per HW design */ + for (i = 0; i < OSI_ETH_ALEN; i++) { + /* Extract the mac sa from the SCI itself */ + lut_config.lut_in.sa[i] = sc->sci[OSI_ETH_ALEN - 1 - i]; + } + lut_config.flags |= LUT_FLAGS_SA_VALID; + lut_config.sci_lut_out.sc_index = sc->sc_idx_start; + for (i = 0; i < SCI_LEN; i++) { + lut_config.sci_lut_out.sci[i] = sc->sci[SCI_LEN - 1 - i]; + } + lut_config.sci_lut_out.an_valid = sc->an_valid; + + lut_config.flags |= LUT_FLAGS_ENTRY_VALID; + ret = macsec_lut_config(osi_core, &lut_config); + if (ret < 0) { + pr_err("%s: Failed to set SCI LUT", __func__); + goto err_sci; + } + + return 0; + +err_sci: + //TODO cleanup SC param +err_sc_param: + //TODO cleanup SC state +err_sc_state: + //TODO Cleanup SA state LUT +err_sa_state: + //TODO Cleanup KT + return -1; +} + +static int macsec_config(struct osi_core_priv_data *const osi_core, + struct osi_macsec_sc_info *const sc, + unsigned int enable, unsigned short ctlr) +{ + struct osi_macsec_sc_info *existing_sc = OSI_NULL, *new_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; + int i; + + /* Validate inputs */ + if ((enable != OSI_ENABLE && enable != OSI_DISABLE) || + (ctlr != CTLR_SEL_TX && ctlr != CTLR_SEL_RX)) { + return -1; + } + + /* TODO - lock needed. Multiple instances of supplicant can request + * to add a macsec config simultaneously. + */ + lut_status = &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) { + pr_err("%s: trying to delete non-existing SC ?", + __func__); + return -1; + } else { + pr_err("%s: Adding new SC/SA: ctlr: %hu", __func__, + ctlr); + if (lut_status->next_sc_idx >= MAX_NUM_SC) { + pr_err("%s: Err: Reached max SC LUT entries!", + __func__); + return -1; + } + + new_sc = &lut_status->sc_info[lut_status->next_sc_idx]; + osi_memcpy(new_sc->sci, sc->sci, SCI_LEN); + osi_memcpy(new_sc->sak, sc->sak, KEY_LEN_128); + new_sc->curr_an = sc->curr_an; + new_sc->next_pn = sc->next_pn; + + new_sc->sc_idx_start = lut_status->next_sc_idx; + new_sc->an_valid |= OSI_BIT(sc->curr_an); + + pr_err("%s: Adding new SC\n" + "\tsci: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n" + "\tan: %u\n" + "\tpn: %u" + "\tsc_idx_start: %u" + "\tan_valid: %#x", __func__, + new_sc->sci[0], new_sc->sci[1], new_sc->sci[2], + new_sc->sci[3], new_sc->sci[4], new_sc->sci[5], + new_sc->sci[6], new_sc->sci[7], + new_sc->curr_an, new_sc->next_pn, + new_sc->sc_idx_start, + new_sc->an_valid); + pr_err("\tkey: "); + for (i = 0; i < 16; i++) { + pr_cont(" %02x", new_sc->sak[i]); + } + pr_err(""); + + if (add_upd_sc(osi_core, new_sc, ctlr) != OSI_NONE) { + pr_err("%s: failed to add new SC", __func__); + /* TODO - remove new_sc from lut_status[] ? + * not needed for now, as next_sc_idx is not + * incremented. + */ + return -1; + } else { + /* Update lut status */ + lut_status->next_sc_idx++; + pr_err("%s: Added new SC ctlr: %u " + "nxt_sc_idx: %u", + __func__, ctlr, + lut_status->next_sc_idx); + return 0; + } + } + } else { + pr_err("%s: Updating existing SC", __func__); + if (enable == OSI_DISABLE) { + pr_err("%s: Deleting existing SA", __func__); + if (del_upd_sc(osi_core, existing_sc, sc, ctlr) != + OSI_NONE) { + pr_err("%s: failed to del SA", __func__); + return -1; + } else { + if (existing_sc->an_valid == OSI_NONE) { + lut_status->next_sc_idx--; + 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; + osi_memcpy(tmp_sc_p->sak, sc->sak, KEY_LEN_128); + tmp_sc_p->curr_an = sc->curr_an; + tmp_sc_p->next_pn = sc->next_pn; + + tmp_sc_p->an_valid |= OSI_BIT(sc->curr_an); + + pr_err("%s: Adding new SA to SC\n" + "\tsci: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n" + "\tan: %u\n" + "\tpn: %u" + "\tsc_idx_start: %u" + "\tan_valid: %#x", __func__, + tmp_sc_p->sci[0], tmp_sc_p->sci[1], + tmp_sc_p->sci[2], tmp_sc_p->sci[3], + tmp_sc_p->sci[4], tmp_sc_p->sci[5], + tmp_sc_p->sci[6], tmp_sc_p->sci[7], + tmp_sc_p->curr_an, tmp_sc_p->next_pn, + tmp_sc_p->sc_idx_start, + tmp_sc_p->an_valid); + pr_err("\tkey: "); + for (i = 0; i < 16; i++) { + pr_cont(" %02x", tmp_sc_p->sak[i]); + } + pr_err(""); + + if (add_upd_sc(osi_core, tmp_sc_p, ctlr) != OSI_NONE) { + pr_err("%s: failed to add new SA", __func__); + /* TODO - remove new_sc from lut_status[] ? + * not needed for now, as next_sc_idx is not + * incremented. + */ + return -1; + } else { + /* Update lut status */ + lut_status->next_sc_idx++; + pr_err("%s: Added new SA ctlr: %u", + __func__, ctlr); + /* Now commit the changes */ + *existing_sc = *tmp_sc_p; + return 0; + } + } + return -1; + } +} + +static struct 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, + .kt_config = macsec_kt_config, + .loopback_config = macsec_loopback_config, + .macsec_en = macsec_enable, + .config = macsec_config, + .read_mmc = macsec_read_mmc, + .dbg_buf_config = macsec_dbg_buf_config, + .dbg_events_config = macsec_dbg_events_config, +}; + +static struct osi_macsec_lut_status lut_status[NUM_CTLR]; + +int osi_init_macsec_ops(struct osi_core_priv_data *const osi_core) +{ + if (osi_core->macsec_base == OSI_NULL) { + return -1; + } else { + osi_core->macsec_ops = &macsec_ops; + osi_core->macsec_lut_status = lut_status; + return 0; + } +} + +int osi_macsec_init(struct osi_core_priv_data *const osi_core) +{ + 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); + } + + return -1; +} + +int 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; +} + +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); + } +} + +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); + } +} + +int osi_macsec_lut_config(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; +} + +int osi_macsec_kt_config(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; +} + +int osi_macsec_loopback(struct osi_core_priv_data *const osi_core, + unsigned int 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; +} + +int osi_macsec_en(struct osi_core_priv_data *const osi_core, + unsigned int 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; +} + +int osi_macsec_config(struct osi_core_priv_data *const osi_core, + struct osi_macsec_sc_info *const sc, + unsigned int enable, unsigned short ctlr) +{ + if ((enable != OSI_ENABLE && enable != OSI_DISABLE) || + (ctlr != CTLR_SEL_TX && ctlr != CTLR_SEL_RX)) { + 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); + } + + return -1; +} + +int 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; +} + +int osi_macsec_dbg_buf_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_buf_config != OSI_NULL) { + return osi_core->macsec_ops->dbg_buf_config(osi_core, + dbg_buf_config); + } + + return -1; +} + +int 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; +} diff --git a/osi/core/macsec.h b/osi/core/macsec.h new file mode 100644 index 0000000..bad1b26 --- /dev/null +++ b/osi/core/macsec.h @@ -0,0 +1,536 @@ +/* + * 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_MACSEC_H +#define INCLUDED_MACSEC_H + +/** + * @addtogroup MACsec AMAP + * + * @brief MACsec controller register offsets + * @{ + */ +#define GCM_KEYTABLE_CONFIG 0x0000 +#define GCM_KEYTABLE_DATA(x) (0x0004 + (x * 4)) +#define RX_ICV_ERR_CNTRL 0x4000 +#define INTERRUPT_COMMON_SR 0x4004 +#define TX_IMR 0x4008 +#define TX_ISR 0x400C +#define RX_IMR 0x4048 +#define RX_ISR 0x404C +#define INTERRUPT_MASK1_0 0x40A0 +#define TX_SC_PN_THRESHOLD_STATUS0_0 0x4018 +#define TX_SC_PN_THRESHOLD_STATUS1_0 0x401C +#define TX_SC_PN_EXHAUSTED_STATUS0_0 0x4024 +#define TX_SC_PN_EXHAUSTED_STATUS1_0 0x4028 +#define TX_SC_ERROR_INTERRUPT_STATUS_0 0x402C +#define RX_SC_PN_EXHAUSTED_STATUS0_0 0x405C +#define RX_SC_PN_EXHAUSTED_STATUS1_0 0x4060 +#define RX_SC_REPLAY_ERROR_STATUS0_0 0x4090 +#define RX_SC_REPLAY_ERROR_STATUS1_0 0x4094 +#define STATS_CONFIG 0x9000 +#define STATS_CONTROL_0 0x900C +#define TX_PKTS_UNTG_LO_0 0x9010 +#define TX_PKTS_UNTG_HI_0 0x9014 +#define TX_OCTETS_PRTCTD_LO_0 0x9018 +#define TX_OCTETS_PRTCTD_HI_0 0x901C +#define TX_PKTS_TOO_LONG_LO_0 0x9020 +#define TX_PKTS_TOO_LONG_HI_0 0x9024 +#define TX_PKTS_PROTECTED_SCx_LO_0(x) (0x9028 + (x * 8)) +#define TX_PKTS_PROTECTED_SCx_HI_0(x) (0x902C + (x * 8)) +#define RX_PKTS_NOTG_LO_0 0x90B0 +#define RX_PKTS_NOTG_HI_0 0x90B4 +#define RX_PKTS_UNTG_LO_0 0x90A8 +#define RX_PKTS_UNTG_HI_0 0x90AC +#define RX_PKTS_BADTAG_LO_0 0x90B8 +#define RX_PKTS_BADTAG_HI_0 0x90BC +#define RX_PKTS_NOSA_LO_0 0x90C0 +#define RX_PKTS_NOSA_HI_0 0x90C4 +#define RX_PKTS_NOSAERROR_LO_0 0x90C8 +#define RX_PKTS_NOSAERROR_HI_0 0x90CC +#define RX_PKTS_OVRRUN_LO_0 0x90D0 +#define RX_PKTS_OVRRUN_HI_0 0x90D4 +#define RX_OCTETS_VLDTD_LO_0 0x90D8 +#define RX_OCTETS_VLDTD_HI_0 0x90DC +#define RX_PKTS_LATE_SCx_LO_0(x) (0x90E0 + (x * 8)) +#define RX_PKTS_LATE_SCx_HI_0(x) (0x90E4 + (x * 8)) +#define RX_PKTS_NOTVALID_SCx_LO_0(x) (0x9160 + (x * 8)) +#define RX_PKTS_NOTVALID_SCx_HI_0(x) (0x9164 + (x * 8)) +#define RX_PKTS_OK_SCx_LO_0(x) (0x91E0 + (x * 8)) +#define RX_PKTS_OK_SCx_HI_0(x) (0x91E4 + (x * 8)) + +#define TX_INPKTS_CRCIN_NOTVALID_LO_0 0x9260 +#define TX_INPKTS_CRCIN_NOTVALID_HI_0 0x9264 +#define RX_INPKTS_CRCIN_NOTVALID_LO_0 0x9268 +#define RX_INPKTS_CRCIN_NOTVALID_HI_0 0x926C + +#define MACSEC_CONTROL0 0xD000 +#define MACSEC_LUT_CONFIG 0xD004 +#define MACSEC_LUT_DATA(x) (0xD008 + (x * 4)) +#define TX_BYP_LUT_VALID 0xD024 +#define TX_SCI_LUT_VALID 0xD028 +#define RX_BYP_LUT_VALID 0xD02C +#define RX_SCI_LUT_VALID 0xD030 + +#define COMMON_IMR 0xD054 +#define COMMON_ISR 0xD058 +#define TX_SC_KEY_INVALID_STS0_0 0xD064 +#define TX_SC_KEY_INVALID_STS1_0 0xD068 +#define RX_SC_KEY_INVALID_STS0_0 0xD080 +#define RX_SC_KEY_INVALID_STS1_0 0xD084 + +#define TX_DEBUG_CONTROL_0 0xD098 +#define TX_DEBUG_TRIGGER_EN_0 0xD09C +#define TX_DEBUG_STATUS_0 0xD0C4 +#define DEBUG_BUF_CONFIG_0 0xD0C8 +#define DEBUG_BUF_DATA_0(x) (0xD0CC + (x * 4)) +#define RX_DEBUG_CONTROL_0 0xD0DC +#define RX_DEBUG_TRIGGER_EN_0 0xD0E0 +#define RX_DEBUG_STATUS_0 0xD0F8 + +#define MACSEC_CONTROL1 0xE000 +#define GCM_AES_CONTROL_0 0xE004 +#define TX_MTU_LEN 0xE008 +#define TX_SOT_DELAY 0xE010 +#define RX_MTU_LEN 0xE014 +#define RX_SOT_DELAY 0xE01C +#define MACSEC_TX_DVLAN_CONTROL_0 0xE00C +#define MACSEC_RX_DVLAN_CONTROL_0 0xE018 +/** @} */ + +/** + * @addtogroup GCM_KEYTABLE_CONFIG register + * + * @brief Bit definitions of GCM_KEYTABLE_CONFIG register + * @{ + */ +#define KT_CONFIG_UPDATE OSI_BIT(31) +#define KT_CONFIG_CTLR_SEL OSI_BIT(25) +#define KT_CONFIG_RW OSI_BIT(24) +#define KT_CONFIG_INDEX_MASK (OSI_BIT(4) | OSI_BIT(3) | OSI_BIT(2) |\ + OSI_BIT(1) | OSI_BIT(0)) +#define KT_ENTRY_VALID OSI_BIT(0) +/** @} */ + +/** + * @addtogroup GCM_KEYTABLE_DATA registers + * + * @brief Bit definitions of GCM_KEYTABLE_DATA register & helpful macros + * @{ + */ +#define KT_ENTRY_VALID OSI_BIT(0) +#define MACSEC_KT_DATA_REG_CNT 13 +#define MACSEC_KT_DATA_REG_SAK_CNT 8 +#define MACSEC_KT_DATA_REG_H_CNT 4 +/** @} */ + +/** + * @addtogroup MACSEC_LUT_CONFIG register + * + * @brief Bit definitions of MACSEC_LUT_CONFIG register + * @{ + */ +#define LUT_CONFIG_UPDATE OSI_BIT(31) +#define LUT_CONFIG_CTLR_SEL OSI_BIT(25) +#define LUT_CONFIG_RW OSI_BIT(24) +#define LUT_CONFIG_LUT_SEL_MASK (OSI_BIT(18) | OSI_BIT(17) |\ + OSI_BIT(16)) +#define LUT_CONFIG_LUT_SEL_SHIFT 16 +#define 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 COMMON_SR_SFTY_ERR OSI_BIT(2) +#define COMMON_SR_RX OSI_BIT(1) +#define COMMON_SR_TX OSI_BIT(0) +/** @} */ + +/** + * @addtogroup MACSEC_CONTROL0 register + * + * @brief Bit definitions of MACSEC_CONTROL0 register + * @{ + */ +#define TX_LKUP_MISS_NS_INTR OSI_BIT(24) +#define RX_LKUP_MISS_NS_INTR OSI_BIT(23) +#define VALIDATE_FRAMES_MASK (OSI_BIT(22) | OSI_BIT(21)) +#define VALIDATE_FRAMES_DIS 0x0 +#define VALIDATE_FRAMES_STRICT OSI_BIT(22) +#define VALIDATE_FRAMES_CHECK OSI_BIT(21) +#define RX_REPLAY_PROT_EN OSI_BIT(20) +#define RX_LKUP_MISS_BYPASS OSI_BIT(19) +#define RX_EN OSI_BIT(16) +#define TX_LKUP_MISS_BYPASS OSI_BIT(3) +#define TX_EN OSI_BIT(0) +/** @} */ + +/** + * @addtogroup MACSEC_CONTROL1 register + * + * @brief Bit definitions of MACSEC_CONTROL1 register + * @{ + */ +#define LOOPBACK_MODE_EN OSI_BIT(31) +#define RX_MTU_CHECK_EN OSI_BIT(16) +#define TX_LUT_PRIO_BYP OSI_BIT(2) +#define TX_MTU_CHECK_EN OSI_BIT(0) +/** @} */ + +/** + * @addtogroup GCM_AES_CONTROL_0 register + * + * @brief Bit definitions of GCM_AES_CONTROL_0 register + * @{ + */ +#define RX_AES_MODE_MASK (OSI_BIT(17) | OSI_BIT(16)) +#define RX_AES_MODE_AES128 0x0 +#define RX_AES_MODE_AES256 OSI_BIT(17) +#define TX_AES_MODE_MASK (OSI_BIT(1) | OSI_BIT(0)) +#define TX_AES_MODE_AES128 0x0 +#define TX_AES_MODE_AES256 OSI_BIT(1) +/** @} */ + +/** + * @addtogroup COMMON_IMR register + * + * @brief Bit definitions of MACSEC_INTERRUPT_MASK register + * @{ + */ +#define SECURE_REG_VIOL_INT_EN OSI_BIT(31) +#define RX_UNINIT_KEY_SLOT_INT_EN OSI_BIT(17) +#define RX_LKUP_MISS_INT_EN OSI_BIT(16) +#define TX_UNINIT_KEY_SLOT_INT_EN OSI_BIT(1) +#define TX_LKUP_MISS_INT_EN OSI_BIT(0) +/** @} */ + +/** + * @addtogroup TX_IMR register + * + * @brief Bit definitions of TX_INTERRUPT_MASK register + * @{ + */ +#define TX_DBG_BUF_CAPTURE_DONE_INT_EN OSI_BIT(22) +#define TX_MTU_CHECK_FAIL_INT_EN OSI_BIT(19) +#define TX_AES_GCM_BUF_OVF_INT_EN OSI_BIT(18) +#define TX_SC_AN_NOT_VALID_INT_EN OSI_BIT(17) +#define TX_MAC_CRC_ERROR_INT_EN OSI_BIT(16) +#define TX_PN_EXHAUSTED_INT_EN OSI_BIT(1) +#define TX_PN_THRSHLD_RCHD_INT_EN OSI_BIT(0) +/** @} */ + +/** + * @addtogroup RX_IMR register + * + * @brief Bit definitions of RX_INTERRUPT_MASK register + * @{ + */ +#define RX_DBG_BUF_CAPTURE_DONE_INT_EN OSI_BIT(22) +#define RX_ICV_ERROR_INT_EN OSI_BIT(21) +#define RX_REPLAY_ERROR_INT_EN OSI_BIT(20) +#define RX_MTU_CHECK_FAIL_INT_EN OSI_BIT(19) +#define RX_AES_GCM_BUF_OVF_INT_EN OSI_BIT(18) +#define RX_MAC_CRC_ERROR_INT_EN OSI_BIT(16) +#define RX_PN_EXHAUSTED_INT_EN OSI_BIT(1) +/** @} */ + +/** + * @addtogroup INTERRUPT_MASK1_0 register + * + * @brief Bit definitions of INTERRUPT_MASK1_0 register + * @{ + */ +#define SFTY_ERR_UNCORR_INT_EN OSI_BIT(0) +/** @} */ + +/** + * @addtogroup COMMON_ISR register + * + * @brief Bit definitions of MACSEC_INTERRUPT_STATUS register + * @{ + */ +#define SECURE_REG_VIOL OSI_BIT(31) +#define RX_UNINIT_KEY_SLOT OSI_BIT(17) +#define RX_LKUP_MISS OSI_BIT(16) +#define TX_UNINIT_KEY_SLOT OSI_BIT(1) +#define TX_LKUP_MISS OSI_BIT(0) +/** @} */ + +/** + * @addtogroup TX_ISR register + * + * @brief Bit definitions of TX_INTERRUPT_STATUS register + * @{ + */ +#define TX_DBG_BUF_CAPTURE_DONE OSI_BIT(22) +#define TX_MTU_CHECK_FAIL OSI_BIT(19) +#define TX_AES_GCM_BUF_OVF OSI_BIT(18) +#define TX_SC_AN_NOT_VALID OSI_BIT(17) +#define TX_MAC_CRC_ERROR OSI_BIT(16) +#define TX_PN_EXHAUSTED OSI_BIT(1) +#define TX_PN_THRSHLD_RCHD OSI_BIT(0) +/** @} */ + +/** + * @addtogroup RX_ISR register + * + * @brief Bit definitions of RX_INTERRUPT_STATUS register + * @{ + */ +#define RX_DBG_BUF_CAPTURE_DONE OSI_BIT(22) +#define RX_ICV_ERROR OSI_BIT(21) +#define RX_REPLAY_ERROR OSI_BIT(20) +#define RX_MTU_CHECK_FAIL OSI_BIT(19) +#define RX_AES_GCM_BUF_OVF OSI_BIT(18) +#define RX_MAC_CRC_ERROR OSI_BIT(16) +#define RX_PN_EXHAUSTED OSI_BIT(1) +/** @} */ + +/** + * @addtogroup STATS_CONTROL_0 register + * + * @brief Bit definitions of STATS_CONTROL_0 register + * @{ + */ +#define STATS_CONTROL0_RD_CPY OSI_BIT(3) +#define STATS_CONTROL0_TK_CPY OSI_BIT(2) +#define STATS_CONTROL0_CNT_RL_OVR_CPY OSI_BIT(1) +#define STATS_CONTROL0_CNT_CLR OSI_BIT(0) +/** @} */ + +/** + * @addtogroup DEBUG_BUF_CONFIG_0 register + * + * @brief Bit definitions of DEBUG_BUF_CONFIG_0 register + * @{ + */ +#define DEBUG_BUF_CONFIG_0_UPDATE OSI_BIT(31) +#define DEBUG_BUF_CONFIG_0_CTLR_SEL OSI_BIT(25) +#define DEBUG_BUF_CONFIG_0_RW OSI_BIT(24) +#define DEBUG_BUF_CONFIG_0_IDX_MASK (OSI_BIT(0) | OSI_BIT(1) | \ + OSI_BIT(2) | OSI_BIT(3)) +/** @} */ + +/** + * @addtogroup TX_DEBUG_TRIGGER_EN_0 register + * + * @brief Bit definitions of TX_DEBUG_TRIGGER_EN_0 register + * @{ + */ +#define TX_DBG_CAPTURE OSI_BIT(10) +#define TX_DBG_ICV_CORRUPT OSI_BIT(9) +#define TX_DBG_CRC_CORRUPT OSI_BIT(8) +#define TX_DBG_DATA_MATCH OSI_BIT(7) +#define TX_DBG_LKUP_MATCH OSI_BIT(6) +#define TX_DBG_CRCOUT_MATCH OSI_BIT(5) +#define TX_DBG_CRCIN_MATCH OSI_BIT(4) +#define TX_DBG_ICV_MATCH OSI_BIT(3) +#define TX_DBG_KEY_NOT_VALID OSI_BIT(2) +#define TX_DBG_AN_NOT_VALID OSI_BIT(1) +#define TX_DBG_LKUP_MISS OSI_BIT(0) +/** @} */ + +/** + * @addtogroup TX_DEBUG_STATUS_0 register + * + * @brief Bit definitions of TX_DEBUG_STATUS_0 register + * @{ + */ +#define TX_DBG_STS_CAPTURE OSI_BIT(10) +#define TX_DBG_STS_ICV_CORRUPT OSI_BIT(9) +#define TX_DBG_STS_CRC_CORRUPT OSI_BIT(8) +#define TX_DBG_STS_DATA_MATCH OSI_BIT(7) +#define TX_DBG_STS_LKUP_MATCH OSI_BIT(6) +#define TX_DBG_STS_CRCOUT_MATCH OSI_BIT(5) +#define TX_DBG_STS_CRCIN_MATCH OSI_BIT(4) +#define TX_DBG_STS_ICV_MATCH OSI_BIT(3) +#define TX_DBG_STS_KEY_NOT_VALID OSI_BIT(2) +#define TX_DBG_STS_AN_NOT_VALID OSI_BIT(1) +#define TX_DBG_STS_LKUP_MISS OSI_BIT(0) +/** @} */ + +/** + * @addtogroup RX_DEBUG_TRIGGER_EN_0 register + * + * @brief Bit definitions of RX_DEBUG_TRIGGER_EN_0 register + * @{ + */ +#define RX_DBG_CAPTURE OSI_BIT(10) +#define RX_DBG_ICV_ERROR OSI_BIT(9) +#define RX_DBG_CRC_CORRUPT OSI_BIT(8) +#define RX_DBG_DATA_MATCH OSI_BIT(7) +#define RX_DBG_BYP_LKUP_MATCH OSI_BIT(6) +#define RX_DBG_CRCOUT_MATCH OSI_BIT(5) +#define RX_DBG_CRCIN_MATCH OSI_BIT(4) +#define RX_DBG_REPLAY_ERR OSI_BIT(3) +#define RX_DBG_KEY_NOT_VALID OSI_BIT(2) +#define RX_DBG_LKUP_MISS OSI_BIT(0) +/** @} */ + +/** + * @addtogroup RX_DEBUG_STATUS_0 register + * + * @brief Bit definitions of RX_DEBUG_STATUS_0 register + * @{ + */ +#define RX_DBG_STS_CAPTURE OSI_BIT(10) +#define RX_DBG_STS_ICV_ERROR OSI_BIT(9) +#define RX_DBG_STS_CRC_CORRUPT OSI_BIT(8) +#define RX_DBG_STS_DATA_MATCH OSI_BIT(7) +#define RX_DBG_STS_BYP_LKUP_MATCH OSI_BIT(6) +#define RX_DBG_STS_CRCOUT_MATCH OSI_BIT(5) +#define RX_DBG_STS_CRCIN_MATCH OSI_BIT(4) +#define RX_DBG_STS_REPLAY_ERR OSI_BIT(3) +#define RX_DBG_STS_KEY_NOT_VALID OSI_BIT(2) +#define RX_DBG_STS_LKUP_MISS OSI_BIT(0) +/** @} */ + +/** + * @addtogroup TX_DEBUG_STATUS_0 register + * + * @brief Bit definitions of TX_DEBUG_STATUS_0 register + * @{ + */ +#define TX_DBG_STS_CAPTURE OSI_BIT(10) +#define TX_DBG_STS_ICV_CORRUPT OSI_BIT(9) +#define TX_DBG_STS_CRC_CORRUPT OSI_BIT(8) +#define TX_DBG_STS_DATA_MATCH OSI_BIT(7) +#define TX_DBG_STS_LKUP_MATCH OSI_BIT(6) +#define TX_DBG_STS_CRCOUT_MATCH OSI_BIT(5) +#define TX_DBG_STS_CRCIN_MATCH OSI_BIT(4) +#define TX_DBG_STS_ICV_MATCH OSI_BIT(3) +#define TX_DBG_STS_KEY_NOT_VALID OSI_BIT(2) +#define TX_DBG_STS_AN_NOT_VALID OSI_BIT(1) +#define TX_DBG_STS_LKUP_MISS OSI_BIT(0) +/** @} */ + +/** + * @addtogroup TX_DEBUG_CONTROL_0 register + * + * @brief Bit definitions of TX_DEBUG_CONTROL_0 register + * @{ + */ +#define TX_DEBUG_CONTROL_0_START_CAP OSI_BIT(31) +/** @} */ + +/** + * @addtogroup RX_DEBUG_CONTROL_0 register + * + * @brief Bit definitions of RX_DEBUG_CONTROL_0 register + * @{ + */ +#define RX_DEBUG_CONTROL_0_START_CAP OSI_BIT(31) +/** @} */ + +#define MTU_LENGTH_MASK 0xFFFF +#define MTU_ADDONS (8 + 14 + 4) +#define DVLAN_TAG_ETHERTYPE 0x88A8 +/** + * @addtogroup TX/RX_BYP/SCI_LUT_VALID register + * + * @brief Bit definitions of LUT_VALID registers + * @{ + */ +#define TX_BYP_LUT_VALID_ENTRY(x) OSI_BIT(x) +#define TX_BYP_LUT_VALID_NONE 0x0 +#define TX_SCI_LUT_VALID_ENTRY(x) OSI_BIT(x) +#define TX_SCI_LUT_VALID_NONE 0x0 +#define RX_BYP_LUT_VALID_ENTRY(x) OSI_BIT(x) +#define RX_BYP_LUT_VALID_NONE 0x0 +#define RX_SCI_LUT_VALID_ENTRY(x) OSI_BIT(x) +#define RX_SCI_LUT_VALID_NONE 0x0 +/** @} */ + +/** + * @addtogroup TX/RX LUT bit fields in LUT_DATA registers + * + * @brief Helper macros for LUT data programming + * @{ + */ +#define MACSEC_LUT_DATA_REG_CNT 7 +/* Bit Offsets for LUT DATA[x] registers for various lookup field masks */ +/* DA mask bits in LUT_DATA[1] register */ +#define LUT_DA_BYTE0_INACTIVE OSI_BIT(16) +#define LUT_DA_BYTE1_INACTIVE OSI_BIT(17) +#define LUT_DA_BYTE2_INACTIVE OSI_BIT(18) +#define LUT_DA_BYTE3_INACTIVE OSI_BIT(19) +#define LUT_DA_BYTE4_INACTIVE OSI_BIT(20) +#define LUT_DA_BYTE5_INACTIVE OSI_BIT(21) +/* SA mask bits in LUT_DATA[3] register */ +#define LUT_SA_BYTE0_INACTIVE OSI_BIT(6) +#define LUT_SA_BYTE1_INACTIVE OSI_BIT(7) +#define LUT_SA_BYTE2_INACTIVE OSI_BIT(8) +#define LUT_SA_BYTE3_INACTIVE OSI_BIT(9) +#define LUT_SA_BYTE4_INACTIVE OSI_BIT(10) +#define LUT_SA_BYTE5_INACTIVE OSI_BIT(11) +/* Ether type mask in LUT_DATA[3] register */ +#define LUT_ETHTYPE_INACTIVE OSI_BIT(28) +/* VLAN PCP mask in LUT_DATA[4] register */ +#define LUT_VLAN_PCP_INACTIVE OSI_BIT(0) +/* VLAN ID mask in LUT_DATA[4] register */ +#define LUT_VLAN_ID_INACTIVE OSI_BIT(13) +/* VLAN mask in LUT_DATA[4] register */ +#define LUT_VLAN_ACTIVE OSI_BIT(14) +/* Byte pattern masks in LUT_DATA[4] register */ +#define LUT_BYTE0_PATTERN_INACTIVE OSI_BIT(29) +/* Byte pattern masks in LUT_DATA[5] register */ +#define LUT_BYTE1_PATTERN_INACTIVE OSI_BIT(12) +#define LUT_BYTE2_PATTERN_INACTIVE OSI_BIT(27) +/* Byte pattern masks in LUT_DATA[6] register */ +#define LUT_BYTE3_PATTERN_INACTIVE OSI_BIT(10) +/* Preemptable packet in LUT_DATA[6] register */ +#define LUT_PREEMPT OSI_BIT(11) +/* Preempt mask in LUT_DATA[6] register */ +#define LUT_PREEMPT_INACTIVE OSI_BIT(12) +/* Controlled port mask in LUT_DATA[6] register */ +#define LUT_CONTROLLED_PORT OSI_BIT(13) +/* DVLAN packet in LUT_DATA[6] register */ +#define 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 LUT_AN0_VALID OSI_BIT(13) +#define LUT_AN1_VALID OSI_BIT(14) +#define LUT_AN2_VALID OSI_BIT(15) +#define LUT_AN3_VALID OSI_BIT(16) +/* DVLAN packet in LUT_DATA[6] register */ +#define TX_SCI_LUT_DVLAN_PKT OSI_BIT(21) +/* DVLAN outer/inner tag select in LUT_DATA[6] register */ +#define TX_SCI_LUT_DVLAN_OUTER_INNER_TAG_SEL OSI_BIT(22) +/* SA State LUT entry valid in LUT_DATA[0] register */ +#define SA_STATE_LUT_ENTRY_VALID OSI_BIT(0) + +/* Preemptable packet in LUT_DATA[2] register for Rx SCI */ +#define RX_SCI_LUT_PREEMPT OSI_BIT(8) +/* Preempt mask in LUT_DATA[2] register for Rx SCI */ +#define 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 */ From 7aade293ea1b0c3423cd3a034131ce8274023caa Mon Sep 17 00:00:00 2001 From: Mahesh Patil <maheshp@nvidia.com> Date: Mon, 11 Jan 2021 14:48:06 -0800 Subject: [PATCH 209/458] nvethernetrm: Reduce 2 byte ethertype from mtu Add 2 byte to SECTAG+ICV length to reduce 2 byte mtu size Bug 200690445 Change-Id: I4ccab6958e73fdfe90e386714a5ea4a8454ed8d9 Signed-off-by: Mahesh Patil <maheshp@nvidia.com> --- include/macsec.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/macsec.h b/include/macsec.h index 313edbf..620e254 100644 --- a/include/macsec.h +++ b/include/macsec.h @@ -512,8 +512,8 @@ /** @} */ #define MTU_LENGTH_MASK 0xFFFF -/* MACsec sectag + ICV adds upto 32B */ -#define MACSEC_TAG_ICV_LEN 32 +/* MACsec sectag + ICV + 2B ethertype adds upto 34B */ +#define MACSEC_TAG_ICV_LEN 34 /* Add 8B for double VLAN tags (4B each), * 14B for L2 SA/DA/ethertype, TODO - as per IAS SA/DA is ignored from length * 4B for FCS From 1efa092198863692c7e640699e09172ce1e94471 Mon Sep 17 00:00:00 2001 From: Mahesh Patil <maheshp@nvidia.com> Date: Mon, 11 Jan 2021 14:25:07 -0800 Subject: [PATCH 210/458] nvethernetrm: Update mmc counter properly Don't add accumulated previous counter value when counter is updated with latest value. Register value itself is accumulated counter. Bug 200688810 Change-Id: I93c971724557813a317cc118ce1b4459b9772d83 Signed-off-by: Mahesh Patil <maheshp@nvidia.com> --- osi/core/macsec.c | 85 +++++++++-------------------------------------- 1 file changed, 15 insertions(+), 70 deletions(-) diff --git a/osi/core/macsec.c b/osi/core/macsec.c index 8c2fc89..80b5526 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -398,40 +398,6 @@ int macsec_dbg_events_config( return ret; } -/** - * @brief macsec_reset_mmc - To reset macsec statistics registers and - * structure variable - * - * @param[in] osi_core: OSI core private data structure. - * - * @note - * 1) MAC/MACSEC should be init and started. - */ -void macsec_reset_mmc(struct osi_core_priv_data *osi_core) -{ - unsigned int value; - signed short retry = 1000; - - value = osi_readl((unsigned char *)osi_core->macsec_base + - STATS_CONTROL_0); - /* reset statitics counters */ - value |= STATS_CONTROL0_CNT_CLR; - osi_writel(value, (unsigned char *)osi_core->base + STATS_CONTROL_0); - osi_memset(&osi_core->macsec_mmc, 0U, - sizeof(struct osi_macsec_mmc_counters)); - /* wait for stats to be cleared */ - while (retry > 0) { - value = osi_readl((unsigned char *)osi_core->macsec_base - + STATS_CONTROL_0); - if ((value & STATS_CONTROL0_CNT_CLR) != - STATS_CONTROL0_CNT_CLR) { - break; - } - osi_core->osd_ops.udelay(10U); - retry--; - } -} - /** * @brief update_macsec_mmc_val - function to read register and return value * to callee @@ -439,18 +405,16 @@ void macsec_reset_mmc(struct osi_core_priv_data *osi_core) * 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/MACSEC should be init and started. * - * @retval 0 on MMC counters overflow * @retval value on current MMC counter value. */ static inline unsigned long long update_macsec_mmc_val( struct osi_core_priv_data *osi_core, - unsigned long long last_value, unsigned long offset) + unsigned long offset) { unsigned long long temp; @@ -459,16 +423,9 @@ static inline unsigned long long update_macsec_mmc_val( value_lo = osi_readl((unsigned char *)osi_core->macsec_base + offset); value_hi = osi_readl((unsigned char *)osi_core->macsec_base + (offset + 4U)); + temp = (value_lo | value_hi << 31); - temp = last_value + (value_lo | value_hi << 31); - if (temp < last_value) { - pr_err("Value overflow resetting all statitics counters\n"); - macsec_reset_mmc(osi_core); - } else { - return temp; - } - - return 0; + return temp; } @@ -490,53 +447,41 @@ void macsec_read_mmc(struct osi_core_priv_data *const osi_core) unsigned short i; mmc->tx_pkts_untaged = - update_macsec_mmc_val(osi_core, mmc->tx_pkts_untaged, - TX_PKTS_UNTG_LO_0); + update_macsec_mmc_val(osi_core, TX_PKTS_UNTG_LO_0); mmc->tx_pkts_too_long = - update_macsec_mmc_val(osi_core, mmc->tx_pkts_too_long, - TX_PKTS_TOO_LONG_LO_0); + update_macsec_mmc_val(osi_core, TX_PKTS_TOO_LONG_LO_0); mmc->tx_octets_protected = - update_macsec_mmc_val(osi_core, mmc->tx_octets_protected, - TX_OCTETS_PRTCTD_LO_0); + update_macsec_mmc_val(osi_core, TX_OCTETS_PRTCTD_LO_0); mmc->rx_pkts_no_tag = - update_macsec_mmc_val(osi_core, mmc->rx_pkts_no_tag, - RX_PKTS_NOTG_LO_0); + update_macsec_mmc_val(osi_core, RX_PKTS_NOTG_LO_0); mmc->rx_pkts_untagged = - update_macsec_mmc_val(osi_core, mmc->rx_pkts_untagged, - RX_PKTS_UNTG_LO_0); + update_macsec_mmc_val(osi_core, RX_PKTS_UNTG_LO_0); mmc->rx_pkts_bad_tag = - update_macsec_mmc_val(osi_core, mmc->rx_pkts_bad_tag, - RX_PKTS_BADTAG_LO_0); + update_macsec_mmc_val(osi_core, RX_PKTS_BADTAG_LO_0); mmc->rx_pkts_no_sa_err = - update_macsec_mmc_val(osi_core, mmc->rx_pkts_no_sa_err, - RX_PKTS_NOSAERROR_LO_0); + update_macsec_mmc_val(osi_core, RX_PKTS_NOSAERROR_LO_0); mmc->rx_pkts_no_sa = - update_macsec_mmc_val(osi_core, mmc->rx_pkts_no_sa, - RX_PKTS_NOSA_LO_0); + update_macsec_mmc_val(osi_core, RX_PKTS_NOSA_LO_0); mmc->rx_pkts_overrun = - update_macsec_mmc_val(osi_core, mmc->rx_pkts_overrun, - RX_PKTS_OVRRUN_LO_0); + update_macsec_mmc_val(osi_core, RX_PKTS_OVRRUN_LO_0); mmc->rx_octets_validated = - update_macsec_mmc_val(osi_core, mmc->rx_octets_validated, - RX_OCTETS_VLDTD_LO_0); + update_macsec_mmc_val(osi_core, RX_OCTETS_VLDTD_LO_0); for (i = 0; i <= SC_INDEX_MAX; i++) { mmc->tx_pkts_protected[i] = update_macsec_mmc_val(osi_core, - mmc->tx_pkts_protected[i], TX_PKTS_PROTECTED_SCx_LO_0(i)); mmc->rx_pkts_late[i] = - update_macsec_mmc_val(osi_core, mmc->rx_pkts_late[i], + update_macsec_mmc_val(osi_core, 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, - mmc->rx_pkts_not_valid[i], 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, mmc->rx_pkts_ok[i], + update_macsec_mmc_val(osi_core, RX_PKTS_OK_SCx_LO_0(i)); } } From 6458b613a41d527dd7a976fd37a57214457274fe Mon Sep 17 00:00:00 2001 From: Mahesh Patil <maheshp@nvidia.com> Date: Wed, 13 Jan 2021 14:57:38 -0800 Subject: [PATCH 211/458] nvethernetrm: Use correct sc start_idx in delete Use correct sc start_idx when deleting SC/AN Bug 3206033 Change-Id: I38fc92c743e905d04a5cdc671b5cb59f55ba7c97 Signed-off-by: Mahesh Patil <maheshp@nvidia.com> --- osi/core/macsec.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/osi/core/macsec.c b/osi/core/macsec.c index 80b5526..be797c8 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -2457,7 +2457,7 @@ static int del_upd_sc(struct osi_core_priv_data *const osi_core, if (existing_sc->curr_an == sc->curr_an) { /* 1. SCI LUT */ lut_config.lut_sel = LUT_SEL_SCI; - table_config->index = sc->sc_idx_start; + table_config->index = existing_sc->sc_idx_start; ret = macsec_lut_config(osi_core, &lut_config); if (ret < 0) { pr_err("%s: Failed to del SCI LUT", __func__); @@ -2484,7 +2484,8 @@ static int del_upd_sc(struct osi_core_priv_data *const osi_core, /* 4. SA State LUT */ lut_config.lut_sel = LUT_SEL_SA_STATE; - table_config->index = (sc->sc_idx_start * MAX_NUM_SA) + sc->curr_an; + table_config->index = (existing_sc->sc_idx_start * MAX_NUM_SA) + + sc->curr_an; ret = macsec_lut_config(osi_core, &lut_config); if (ret < 0) { pr_err("%s: Failed to del SA state", __func__); @@ -2496,7 +2497,8 @@ static int del_upd_sc(struct osi_core_priv_data *const osi_core, table_config->ctlr_sel = ctlr; table_config->rw = LUT_WRITE; /* Each SC has MAX_NUM_SA's supported in HW */ - table_config->index = (sc->sc_idx_start * MAX_NUM_SA) + sc->curr_an; + table_config->index = (existing_sc->sc_idx_start * MAX_NUM_SA) + + sc->curr_an; ret = macsec_kt_config(osi_core, &kt_config); if (ret < 0) { pr_err("%s: Failed to del SAK", __func__); From d7cbf99911d9ada574fdd103940ddc46230ccfd0 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Wed, 31 Mar 2021 09:52:14 +0530 Subject: [PATCH 212/458] osi: add support for handling multiple IP's Issue: Since core_ops/dma_chan_ops are static global variables and these are stored in data segment of a process. In linux when insmod happens eqos and mgbe will get probe which inturn initialize osi core ops. Since data segment is shared here eqos core ops pointer overwritten by mgbe core operations. Fix: Use separe core ops and local global variable for each instance. Bug 200671160 Change-Id: I7f093608d812e2ced1bf73339dbd70f0091fe5b4 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> --- include/osi_core.h | 31 ++++ include/osi_dma.h | 33 +++- osi/common/common.h | 6 + osi/core/core_local.h | 13 +- osi/core/eqos_core.c | 19 ++- osi/core/mgbe_core.c | 150 +++++++++++++++++- osi/core/osi_core.c | 347 ++++++++++++++++++++++++++++-------------- osi/dma/dma_local.h | 13 +- osi/dma/osi_dma.c | 200 ++++++++++++++++-------- 9 files changed, 621 insertions(+), 191 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 23abf62..32fc6a8 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -2593,4 +2593,35 @@ int osi_hw_config_est(struct osi_core_priv_data *osi_core, */ int osi_hw_config_fpe(struct osi_core_priv_data *osi_core, struct osi_fpe_config *fpe); + +/** + * @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: + * + * @note + * Classification: + * - Interrupt: No + * - Signal handler: No + * - Thread safe: No + * - Required Privileges: None + * + * @note + * 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); #endif /* INCLUDED_OSI_CORE_H */ diff --git a/include/osi_dma.h b/include/osi_dma.h index 7a2228b..b0955d1 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -553,8 +553,6 @@ struct osi_dma_priv_data { * bit 0 PTP mode master(1) slave(0) * bit 1 PTP sync method twostep(1) onestep(0) */ unsigned int ptp_flag; - /** Tegra Pre-si platform info */ - unsigned int pre_si; }; @@ -1472,4 +1470,35 @@ nve32_t osi_clear_rx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); */ 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: + * + * @note + * Classification: + * - Interrupt: No + * - Signal handler: No + * - Thread safe: No + * - Required Privileges: None + * + * @note + * 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/osi/common/common.h b/osi/common/common.h index b997670..75a8951 100644 --- a/osi/common/common.h +++ b/osi/common/common.h @@ -36,6 +36,12 @@ #define COND_NOT_MET 1 /** @} */ + +/** + * @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 diff --git a/osi/core/core_local.h b/osi/core/core_local.h index c6b0a95..5559193 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -25,6 +25,13 @@ #include <osi_core.h> +/** + * @brief Maximum number of OSI core instances. + */ +#ifndef MAX_CORE_INSTANCES +#define MAX_CORE_INSTANCES 5U +#endif + /** * @brief Initialize MAC & MTL core operations. */ @@ -230,10 +237,14 @@ struct core_ops { * @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; + struct core_ops *ops_p; /** Flag to represent initialization done or not */ nveu32_t init_done; + /** Magic number to validate osi core pointer */ + nveu64_t magic_num; }; /** diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 313c20b..5e3d229 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -5589,6 +5589,23 @@ static nve32_t eqos_get_hw_features(struct osi_core_priv_data *const osi_core, return 0; } +/** + * @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 + */ +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; +} + /** * @brief eqos_get_core_safety_config - EQOS MAC safety configuration * @@ -5629,7 +5646,6 @@ void eqos_init_core_ops(struct core_ops *ops) ops->adjust_mactime = eqos_adjust_mactime; ops->config_tscr = eqos_config_tscr; ops->config_ssir = eqos_config_ssir; - ops->config_ptp_rxq = OSI_NULL; ops->read_mmc = eqos_read_mmc; ops->write_phy_reg = eqos_write_phy_reg; ops->read_phy_reg = eqos_read_phy_reg; @@ -5661,4 +5677,5 @@ void eqos_init_core_ops(struct core_ops *ops) 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; } diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 7af9a3e..5c3c3e3 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -5176,6 +5176,143 @@ static void mgbe_config_ssir(struct osi_core_priv_data *const osi_core, } } +/** + * @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(struct osi_core_priv_data *const osi_core, + 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; +} + +/** + * @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( + 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(struct osi_core_priv_data *const osi_core, + 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(struct osi_core_priv_data *const osi_core, + 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(struct osi_core_priv_data *const osi_core, + const nveu64_t csr_clk_rate) +{ +} + /** * @brief mgbe_init_core_ops - Initialize MGBE MAC core operations */ @@ -5184,24 +5321,23 @@ 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 = OSI_NULL; + 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 = OSI_NULL; + 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 = OSI_NULL; + 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->get_avb_algorithm = OSI_NULL; 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 = OSI_NULL; - ops->config_rx_crc_check = OSI_NULL; + 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; @@ -5236,4 +5372,6 @@ void mgbe_init_core_ops(struct core_ops *ops) ops->config_frp = mgbe_config_frp; ops->update_frp_entry = mgbe_update_frp_entry; ops->update_frp_nve = mgbe_update_frp_nve; + ops->write_reg = mgbe_write_reg; + ops->read_reg = mgbe_read_reg; }; diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 4a0972b..cdf7c9f 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -28,21 +28,41 @@ #include "frp.h" /** - * @brief g_core - Static core local data variable + * @brief g_core - Static core local data array. */ -static struct core_local g_core = { - .init_done = OSI_DISABLE, -}; +static struct core_local g_core[MAX_CORE_INSTANCES]; /** - * @brief ops_p - Pointer local core operations. + * @brief g_ops - Static core operations array. */ -static struct core_ops *ops_p = &g_core.ops; +static struct core_ops g_ops[MAX_MAC_IP_TYPES]; + +struct osi_core_priv_data *osi_get_core(void) +{ + nveu32_t i; + + for (i = 0U; i < MAX_CORE_INSTANCES; i++) { + if (g_core[i].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; + + return &g_core[i].osi_core; +} /** * @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: @@ -53,10 +73,13 @@ static struct core_ops *ops_p = &g_core.ops; * @retval 0 on Success * @retval -1 on Failure */ -static inline nve32_t validate_args(struct osi_core_priv_data *const osi_core) +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) || - (g_core.init_done == OSI_DISABLE)) { + 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; } @@ -67,6 +90,7 @@ static inline nve32_t validate_args(struct osi_core_priv_data *const osi_core) * @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: @@ -77,7 +101,8 @@ static inline nve32_t validate_args(struct osi_core_priv_data *const osi_core) * @retval 0 on Success * @retval -1 on Failure */ -static nve32_t validate_func_ptrs(struct osi_core_priv_data *const osi_core) +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; @@ -106,34 +131,39 @@ 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) { - if (validate_args(osi_core) < 0) { + struct core_local *l_core = (struct core_local *)osi_core; + + if (validate_args(osi_core, l_core) < 0) { return -1; } - return ops_p->write_phy_reg(osi_core, phyaddr, phyreg, phydata); + return l_core->ops_p->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) { - if (validate_args(osi_core) < 0) { + struct core_local *l_core = (struct core_local *)osi_core; + + if (validate_args(osi_core, l_core) < 0) { return -1; } - return ops_p->read_phy_reg(osi_core, phyaddr, phyreg); + return l_core->ops_p->read_phy_reg(osi_core, phyaddr, phyreg); } nve32_t osi_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[2][2] = { + init_ops_arr i_ops[MAX_MAC_IP_TYPES][MAX_MAC_IP_TYPES] = { { eqos_init_core_ops, ivc_init_core_ops }, { mgbe_init_core_ops, OSI_NULL } }; - safety_init s_init[2][2] = { + 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 } }; @@ -142,6 +172,11 @@ nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core) 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) || @@ -162,7 +197,7 @@ nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core) } if (i_ops[osi_core->mac][osi_core->use_virtualization] != OSI_NULL) { - i_ops[osi_core->mac][osi_core->use_virtualization](ops_p); + 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) { @@ -170,13 +205,14 @@ nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core) s_init[osi_core->mac][osi_core->use_virtualization](); } - if (validate_func_ptrs(osi_core) < 0) { + 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; } - g_core.init_done = OSI_ENABLE; + l_core->ops_p = &g_ops[osi_core->mac]; + l_core->init_done = OSI_ENABLE; return 0; } @@ -184,11 +220,13 @@ nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core) nve32_t osi_poll_for_mac_reset_complete( struct osi_core_priv_data *const osi_core) { - if (validate_args(osi_core) < 0) { + struct core_local *l_core = (struct core_local *)osi_core; + + if (validate_args(osi_core, l_core) < 0) { return -1; } - return ops_p->poll_for_swr(osi_core); + return l_core->ops_p->poll_for_swr(osi_core); } /** @@ -213,7 +251,9 @@ static inline void init_vlan_filters(struct osi_core_priv_data *const osi_core) nve32_t osi_hw_core_init(struct osi_core_priv_data *const osi_core, nveu32_t tx_fifo_size, nveu32_t rx_fifo_size) { - if (validate_args(osi_core) < 0) { + struct core_local *l_core = (struct core_local *)osi_core; + + if (validate_args(osi_core, l_core) < 0) { return -1; } @@ -222,49 +262,60 @@ nve32_t osi_hw_core_init(struct osi_core_priv_data *const osi_core, /* Init FRP */ init_frp(osi_core); - return ops_p->core_init(osi_core, tx_fifo_size, rx_fifo_size); + return l_core->ops_p->core_init(osi_core, tx_fifo_size, rx_fifo_size); } nve32_t osi_hw_core_deinit(struct osi_core_priv_data *const osi_core) { - if (validate_args(osi_core) < 0) { + struct core_local *l_core = (struct core_local *)osi_core; + + if (validate_args(osi_core, l_core) < 0) { return -1; } - ops_p->core_deinit(osi_core); + l_core->ops_p->core_deinit(osi_core); + + 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) { - if (validate_args(osi_core) < 0) { + struct core_local *l_core = (struct core_local *)osi_core; + + if (validate_args(osi_core, l_core) < 0) { return -1; } - ops_p->start_mac(osi_core); + l_core->ops_p->start_mac(osi_core); return 0; } nve32_t osi_stop_mac(struct osi_core_priv_data *const osi_core) { - if (validate_args(osi_core) < 0) { + struct core_local *l_core = (struct core_local *)osi_core; + + if (validate_args(osi_core, l_core) < 0) { return -1; } - ops_p->stop_mac(osi_core); + l_core->ops_p->stop_mac(osi_core); return 0; } nve32_t osi_common_isr(struct osi_core_priv_data *const osi_core) { - if (validate_args(osi_core) < 0) { + struct core_local *l_core = (struct core_local *)osi_core; + + if (validate_args(osi_core, l_core) < 0) { return -1; } - ops_p->handle_common_intr(osi_core); + l_core->ops_p->handle_common_intr(osi_core); return 0; } @@ -272,49 +323,58 @@ nve32_t osi_common_isr(struct osi_core_priv_data *const osi_core) nve32_t osi_set_mode(struct osi_core_priv_data *const osi_core, const nve32_t mode) { - if (validate_args(osi_core) < 0) { + struct core_local *l_core = (struct core_local *)osi_core; + + if (validate_args(osi_core, l_core) < 0) { return -1; } - return ops_p->set_mode(osi_core, mode); + 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) { - if (validate_args(osi_core) < 0) { + struct core_local *l_core = (struct core_local *)osi_core; + + if (validate_args(osi_core, l_core) < 0) { return -1; } - return ops_p->set_speed(osi_core, speed); + return l_core->ops_p->set_speed(osi_core, speed); } nve32_t osi_pad_calibrate(struct osi_core_priv_data *const osi_core) { - if (validate_args(osi_core) < 0) { + struct core_local *l_core = (struct core_local *)osi_core; + + if (validate_args(osi_core, l_core) < 0) { return -1; } - return ops_p->pad_calibrate(osi_core); + 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) { - if (validate_args(osi_core) < 0) { + 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 ops_p->config_fw_err_pkts(osi_core, qinx, fw_err); + return l_core->ops_p->config_fw_err_pkts(osi_core, qinx, fw_err); } int osi_config_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; - if (validate_args(osi_core) < 0) { + if (validate_args(osi_core, l_core) < 0) { return -1; } @@ -372,7 +432,7 @@ int osi_config_ptp_offload(struct osi_core_priv_data *const osi_core, return ret; } - ret = ops_p->config_ptp_offload(osi_core, pto_config); + 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", @@ -395,9 +455,10 @@ int osi_config_ptp_offload(struct osi_core_priv_data *const osi_core, 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) < 0) || (filter == OSI_NULL)) { + if ((validate_args(osi_core, l_core) < 0) || (filter == OSI_NULL)) { return -1; } @@ -407,7 +468,7 @@ nve32_t osi_l2_filter(struct osi_core_priv_data *const osi_core, return -1; } - ret = ops_p->config_mac_pkt_filter_reg(osi_core, filter); + 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", @@ -427,7 +488,7 @@ nve32_t osi_l2_filter(struct osi_core_priv_data *const osi_core, return ret; } - ret = ops_p->update_mac_addr_low_high_reg(osi_core, filter); + ret = l_core->ops_p->update_mac_addr_low_high_reg(osi_core, filter); } return ret; @@ -455,6 +516,7 @@ nve32_t osi_l2_filter(struct osi_core_priv_data *const osi_core, */ 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, @@ -504,6 +566,7 @@ static inline nve32_t helper_l4_filter( */ 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, @@ -546,9 +609,10 @@ nve32_t osi_l3l4_filter(struct osi_core_priv_data *const osi_core, 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) < 0) { + if (validate_args(osi_core, l_core) < 0) { return -1; } @@ -561,10 +625,10 @@ nve32_t osi_l3l4_filter(struct osi_core_priv_data *const osi_core, } if (is_l4_filter == OSI_ENABLE) { - ret = helper_l4_filter(osi_core, l_filter, type, + 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_filter, type, + ret = helper_l3_filter(osi_core, l_core->ops_p, l_filter, type, dma_routing_enable, dma_chan); } @@ -575,9 +639,9 @@ nve32_t osi_l3l4_filter(struct osi_core_priv_data *const osi_core, } if (osi_core->l3l4_filter_bitmask != OSI_DISABLE) { - ret = ops_p->config_l3_l4_filter_enable(osi_core, OSI_ENABLE); + ret = l_core->ops_p->config_l3_l4_filter_enable(osi_core, OSI_ENABLE); } else { - ret = ops_p->config_l3_l4_filter_enable(osi_core, OSI_DISABLE); + ret = l_core->ops_p->config_l3_l4_filter_enable(osi_core, OSI_DISABLE); } return ret; @@ -586,21 +650,25 @@ nve32_t osi_l3l4_filter(struct osi_core_priv_data *const osi_core, nve32_t osi_config_rxcsum_offload(struct osi_core_priv_data *const osi_core, const nveu32_t enable) { - if (validate_args(osi_core) < 0) { + struct core_local *l_core = (struct core_local *)osi_core; + + if (validate_args(osi_core, l_core) < 0) { return -1; } - return ops_p->config_rxcsum_offload(osi_core, enable); + 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) { - if (validate_args(osi_core) < 0) { + struct core_local *l_core = (struct core_local *)osi_core; + + if (validate_args(osi_core, l_core) < 0) { return -1; } - return ops_p->set_systime_to_mac(osi_core, sec, nsec); + return l_core->ops_p->set_systime_to_mac(osi_core, sec, nsec); } /** @@ -630,6 +698,8 @@ static inline nveu64_t div_u64(nveu64_t dividend, 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; @@ -638,7 +708,7 @@ nve32_t osi_adjust_freq(struct osi_core_priv_data *const osi_core, nve32_t ppb) nve32_t ret = -1; nve32_t ppb1 = ppb; - if (validate_args(osi_core) < 0) { + if (validate_args(osi_core, l_core) < 0) { return -1; } @@ -683,12 +753,13 @@ nve32_t osi_adjust_freq(struct osi_core_priv_data *const osi_core, nve32_t ppb) } } - return ops_p->config_addend(osi_core, addend); + 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; @@ -697,7 +768,7 @@ nve32_t osi_adjust_time(struct osi_core_priv_data *const osi_core, nve32_t ret = -1; nvel64_t nsec_delta1 = nsec_delta; - if (validate_args(osi_core) < 0) { + if (validate_args(osi_core, l_core) < 0) { return -1; } @@ -726,32 +797,33 @@ nve32_t osi_adjust_time(struct osi_core_priv_data *const osi_core, return ret; } - return ops_p->adjust_mactime(osi_core, sec, nsec, neg_adj, - osi_core->ptp_config.one_nsec_accuracy); + 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) < 0) { + if (validate_args(osi_core, l_core) < 0) { return -1; } if (enable == OSI_DISABLE) { /* disable hw time stamping */ /* Program MAC_Timestamp_Control Register */ - ops_p->config_tscr(osi_core, OSI_DISABLE); + l_core->ops_p->config_tscr(osi_core, OSI_DISABLE); /* Disable PTP RX Queue routing */ - ret = ops_p->config_ptp_rxq(osi_core, + 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 */ - ops_p->config_tscr(osi_core, osi_core->ptp_config.ptp_filter); + 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) { @@ -767,7 +839,7 @@ nve32_t osi_ptp_configuration(struct osi_core_priv_data *const osi_core, } } /* Program Sub Second Increment Register */ - ops_p->config_ssir(osi_core, osi_core->ptp_config.ptp_clock); + 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) @@ -800,16 +872,16 @@ nve32_t osi_ptp_configuration(struct osi_core_priv_data *const osi_core, } /* Program addend value */ - ret = ops_p->config_addend(osi_core, osi_core->default_addend); + ret = l_core->ops_p->config_addend(osi_core, osi_core->default_addend); /* Set current time */ if (ret == 0) { - ret = ops_p->set_systime_to_mac(osi_core, + 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 = ops_p->config_ptp_rxq(osi_core, + ret = l_core->ops_p->config_ptp_rxq(osi_core, osi_core->ptp_config.ptp_rx_queue, OSI_ENABLE); } @@ -822,7 +894,9 @@ nve32_t osi_ptp_configuration(struct osi_core_priv_data *const osi_core, int osi_rxq_route(struct osi_core_priv_data *const osi_core, const struct osi_rxq_route *rxq_route) { - if (validate_args(osi_core) < 0) { + struct core_local *l_core = (struct core_local *)osi_core; + + if (validate_args(osi_core, l_core) < 0) { return -1; } @@ -833,18 +907,20 @@ int osi_rxq_route(struct osi_core_priv_data *const osi_core, return -1; } - return ops_p->config_ptp_rxq(osi_core, + 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) { - if (validate_args(osi_core) < 0) { + struct core_local *l_core = (struct core_local *)osi_core; + + if (validate_args(osi_core, l_core) < 0) { return -1; } - ops_p->read_mmc(osi_core); + l_core->ops_p->read_mmc(osi_core); return 0; } @@ -852,7 +928,9 @@ nve32_t osi_read_mmc(struct osi_core_priv_data *const osi_core) nve32_t osi_get_mac_version(struct osi_core_priv_data *const osi_core, nveu32_t *mac_ver) { - if (validate_args(osi_core) < 0) { + struct core_local *l_core = (struct core_local *)osi_core; + + if (validate_args(osi_core, l_core) < 0) { return -1; } @@ -862,7 +940,7 @@ nve32_t osi_get_mac_version(struct osi_core_priv_data *const osi_core, return -1; } - *mac_ver = ((ops_p->read_reg(osi_core, (nve32_t)MAC_VERSION)) & + *mac_ver = ((l_core->ops_p->read_reg(osi_core, (nve32_t)MAC_VERSION)) & MAC_VERSION_SNVER_MASK); if (is_valid_mac_version(*mac_ver) == 0) { @@ -877,7 +955,9 @@ nve32_t osi_get_mac_version(struct osi_core_priv_data *const osi_core, #ifndef OSI_STRIPPED_LIB nve32_t osi_validate_core_regs(struct osi_core_priv_data *const osi_core) { - if (validate_args(osi_core) < 0) { + struct core_local *l_core = (struct core_local *)osi_core; + + if (validate_args(osi_core, l_core) < 0) { return -1; } @@ -887,59 +967,69 @@ nve32_t osi_validate_core_regs(struct osi_core_priv_data *const osi_core) return -1; } - return ops_p->validate_regs(osi_core); + return l_core->ops_p->validate_regs(osi_core); } nve32_t osi_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, const nveu32_t qinx) { - if (validate_args(osi_core) < 0) { + struct core_local *l_core = (struct core_local *)osi_core; + + if (validate_args(osi_core, l_core) < 0) { return -1; } - return ops_p->flush_mtl_tx_queue(osi_core, qinx); + return l_core->ops_p->flush_mtl_tx_queue(osi_core, qinx); } nve32_t osi_set_avb(struct osi_core_priv_data *const osi_core, const struct osi_core_avb_algorithm *avb) { - if (validate_args(osi_core) < 0) { + struct core_local *l_core = (struct core_local *)osi_core; + + if (validate_args(osi_core, l_core) < 0) { return -1; } - return ops_p->set_avb_algorithm(osi_core, avb); + return l_core->ops_p->set_avb_algorithm(osi_core, avb); } nve32_t osi_get_avb(struct osi_core_priv_data *const osi_core, struct osi_core_avb_algorithm *avb) { - if (validate_args(osi_core) < 0) { + struct core_local *l_core = (struct core_local *)osi_core; + + if (validate_args(osi_core, l_core) < 0) { return -1; } - return ops_p->get_avb_algorithm(osi_core, avb); + return l_core->ops_p->get_avb_algorithm(osi_core, avb); } nve32_t osi_configure_txstatus(struct osi_core_priv_data *const osi_core, const nveu32_t tx_status) { - if (validate_args(osi_core) < 0) { + struct core_local *l_core = (struct core_local *)osi_core; + + if (validate_args(osi_core, l_core) < 0) { return -1; } /* Configure Drop Transmit Status */ - return ops_p->config_tx_status(osi_core, tx_status); + return l_core->ops_p->config_tx_status(osi_core, tx_status); } nve32_t osi_config_rx_crc_check(struct osi_core_priv_data *const osi_core, const nveu32_t crc_chk) { - if (validate_args(osi_core) < 0) { + struct core_local *l_core = (struct core_local *)osi_core; + + if (validate_args(osi_core, l_core) < 0) { return -1; } /* Configure CRC Checking for Received Packets */ - return ops_p->config_rx_crc_check(osi_core, crc_chk); + return l_core->ops_p->config_rx_crc_check(osi_core, crc_chk); } nve32_t osi_config_vlan_filtering(struct osi_core_priv_data *const osi_core, @@ -947,11 +1037,13 @@ nve32_t osi_config_vlan_filtering(struct osi_core_priv_data *const osi_core, const nveu32_t perfect_hash_filtering, const nveu32_t perfect_inverse_match) { - if (validate_args(osi_core) < 0) { + struct core_local *l_core = (struct core_local *)osi_core; + + if (validate_args(osi_core, l_core) < 0) { return -1; } - return ops_p->config_vlan_filtering(osi_core, filter_enb_dis, + return l_core->ops_p->config_vlan_filtering(osi_core, filter_enb_dis, perfect_hash_filtering, perfect_inverse_match); } @@ -959,11 +1051,12 @@ nve32_t osi_config_vlan_filtering(struct osi_core_priv_data *const osi_core, nve32_t osi_update_vlan_id(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 (validate_args(osi_core) < 0) { + if (validate_args(osi_core, l_core) < 0) { return -1; } @@ -982,16 +1075,18 @@ nve32_t osi_update_vlan_id(struct osi_core_priv_data *const osi_core, return -1; } - return update_vlan_id(osi_core, ops_p, vid); + return update_vlan_id(osi_core, l_core->ops_p, vid); } nve32_t osi_reset_mmc(struct osi_core_priv_data *const osi_core) { - if (validate_args(osi_core) < 0) { + struct core_local *l_core = (struct core_local *)osi_core; + + if (validate_args(osi_core, l_core) < 0) { return -1; } - ops_p->reset_mmc(osi_core); + l_core->ops_p->reset_mmc(osi_core); return 0; } @@ -999,7 +1094,9 @@ nve32_t osi_reset_mmc(struct osi_core_priv_data *const osi_core) nve32_t osi_configure_eee(struct osi_core_priv_data *const osi_core, nveu32_t tx_lpi_enabled, nveu32_t tx_lpi_timer) { - if (validate_args(osi_core) < 0) { + struct core_local *l_core = (struct core_local *)osi_core; + + if (validate_args(osi_core, l_core) < 0) { return -1; } @@ -1012,46 +1109,54 @@ nve32_t osi_configure_eee(struct osi_core_priv_data *const osi_core, return -1; } - ops_p->configure_eee(osi_core, tx_lpi_enabled, tx_lpi_timer); + l_core->ops_p->configure_eee(osi_core, tx_lpi_enabled, tx_lpi_timer); return 0; } nve32_t osi_save_registers(struct osi_core_priv_data *const osi_core) { - if (validate_args(osi_core) < 0) { + struct core_local *l_core = (struct core_local *)osi_core; + + if (validate_args(osi_core, l_core) < 0) { return -1; } /* Call MAC save registers callback and return the value */ - return ops_p->save_registers(osi_core); + return l_core->ops_p->save_registers(osi_core); } nve32_t osi_restore_registers(struct osi_core_priv_data *const osi_core) { - if (validate_args(osi_core) < 0) { + struct core_local *l_core = (struct core_local *)osi_core; + + if (validate_args(osi_core, l_core) < 0) { return -1; } /* Call MAC restore registers callback and return the value */ - return ops_p->restore_registers(osi_core); + return l_core->ops_p->restore_registers(osi_core); } nve32_t osi_configure_flow_control(struct osi_core_priv_data *const osi_core, const nveu32_t flw_ctrl) { - if (validate_args(osi_core) < 0) { + struct core_local *l_core = (struct core_local *)osi_core; + + if (validate_args(osi_core, l_core) < 0) { return -1; } /* Configure Flow control settings */ - return ops_p->config_flow_control(osi_core, flw_ctrl); + return l_core->ops_p->config_flow_control(osi_core, flw_ctrl); } int osi_configure_frp(struct osi_core_priv_data *const osi_core, struct osi_core_frp_cmd *const cmd) { - if (validate_args(osi_core) < 0) { + struct core_local *l_core = (struct core_local *)osi_core; + + if (validate_args(osi_core, l_core) < 0) { return -1; } @@ -1069,14 +1174,16 @@ int osi_configure_frp(struct osi_core_priv_data *const osi_core, return -1; } - return setup_frp(osi_core, ops_p, cmd); + return setup_frp(osi_core, l_core->ops_p, cmd); } nve32_t osi_config_arp_offload(struct osi_core_priv_data *const osi_core, const nveu32_t flags, const nveu8_t *ip_addr) { - if ((validate_args(osi_core) < 0)) { + struct core_local *l_core = (struct core_local *)osi_core; + + if ((validate_args(osi_core, l_core) < 0)) { return -1; } @@ -1092,34 +1199,40 @@ nve32_t osi_config_arp_offload(struct osi_core_priv_data *const osi_core, return -1; } - return ops_p->config_arp_offload(osi_core, flags, ip_addr); + return l_core->ops_p->config_arp_offload(osi_core, flags, ip_addr); } nve32_t osi_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, const nveu64_t csr_clk_rate) { - if (validate_args(osi_core) < 0) { + struct core_local *l_core = (struct core_local *)osi_core; + + if (validate_args(osi_core, l_core) < 0) { return -1; } - ops_p->set_mdc_clk_rate(osi_core, csr_clk_rate); + l_core->ops_p->set_mdc_clk_rate(osi_core, csr_clk_rate); return 0; } int osi_config_rss(struct osi_core_priv_data *const osi_core) { - if (validate_args(osi_core) < 0) { + struct core_local *l_core = (struct core_local *)osi_core; + + if (validate_args(osi_core, l_core) < 0) { return -1; } - return ops_p->config_rss(osi_core); + return l_core->ops_p->config_rss(osi_core); } int osi_hw_config_est(struct osi_core_priv_data *osi_core, struct osi_est_config *est) { - if (validate_args(osi_core) < 0) { + struct core_local *l_core = (struct core_local *)osi_core; + + if (validate_args(osi_core, l_core) < 0) { return -1; } @@ -1137,13 +1250,15 @@ int osi_hw_config_est(struct osi_core_priv_data *osi_core, return -1; } - return ops_p->hw_config_est(osi_core, est); + return l_core->ops_p->hw_config_est(osi_core, est); } nve32_t osi_config_mac_loopback(struct osi_core_priv_data *const osi_core, const nveu32_t lb_mode) { - if (validate_args(osi_core) < 0) { + struct core_local *l_core = (struct core_local *)osi_core; + + if (validate_args(osi_core, l_core) < 0) { return -1; } @@ -1155,13 +1270,15 @@ nve32_t osi_config_mac_loopback(struct osi_core_priv_data *const osi_core, } /* Configure MAC loopback */ - return ops_p->config_mac_loopback(osi_core, lb_mode); + return l_core->ops_p->config_mac_loopback(osi_core, lb_mode); } int osi_hw_config_fpe(struct osi_core_priv_data *osi_core, struct osi_fpe_config *fpe) { - if (validate_args(osi_core) < 0) { + struct core_local *l_core = (struct core_local *)osi_core; + + if (validate_args(osi_core, l_core) < 0) { return -1; } @@ -1171,14 +1288,16 @@ int osi_hw_config_fpe(struct osi_core_priv_data *osi_core, return -1; } - return ops_p->hw_config_fpe(osi_core, fpe); + return l_core->ops_p->hw_config_fpe(osi_core, fpe); } #endif /* !OSI_STRIPPED_LIB */ nve32_t osi_get_hw_features(struct osi_core_priv_data *const osi_core, struct osi_hw_features *hw_feat) { - if (validate_args(osi_core) < 0) { + struct core_local *l_core = (struct core_local *)osi_core; + + if (validate_args(osi_core, l_core) < 0) { return -1; } @@ -1188,5 +1307,5 @@ nve32_t osi_get_hw_features(struct osi_core_priv_data *const osi_core, return -1; } - return ops_p->get_hw_features(osi_core, hw_feat); + return l_core->ops_p->get_hw_features(osi_core, hw_feat); } diff --git a/osi/dma/dma_local.h b/osi/dma/dma_local.h index 3a0fca7..4d1d794 100644 --- a/osi/dma/dma_local.h +++ b/osi/dma/dma_local.h @@ -27,6 +27,13 @@ #include <osi_dma.h> #include "eqos_dma.h" +/** + * @brief Maximum number of OSI DMA instances. + */ +#ifndef MAX_DMA_INSTANCES +#define MAX_DMA_INSTANCES 5U +#endif + /** * @brief MAC DMA Channel operations */ @@ -112,14 +119,18 @@ struct desc_ops { * @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; + struct dma_chan_ops *ops_p; /** 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; }; /** diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 4007c0a..14cfbaa 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -26,21 +26,41 @@ #include "../osi/common/common.h" /** - * @brief g_dma - DMA local data variable + * @brief g_dma - DMA local data array. */ -static struct dma_local g_dma = { - .init_done = OSI_DISABLE, -}; +static struct dma_local g_dma[MAX_DMA_INSTANCES]; /** - * @brief ops_p - Pointer to local DMA HW operations. + * @brief g_ops - local DMA HW operations array. */ -static struct dma_chan_ops *ops_p = &g_dma.ops; +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: @@ -51,10 +71,11 @@ static struct dma_chan_ops *ops_p = &g_dma.ops; * @retval 0 on Success * @retval -1 on Failure */ -static inline nve32_t validate_args(struct osi_dma_priv_data *osi_dma) +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) || - (g_dma.init_done == OSI_DISABLE)) { + (l_dma->init_done == OSI_DISABLE)) { return -1; } @@ -121,6 +142,7 @@ static inline nve32_t validate_dma_chans(struct osi_dma_priv_data *osi_dma) * @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: @@ -131,7 +153,8 @@ static inline nve32_t validate_dma_chans(struct osi_dma_priv_data *osi_dma) * @retval 0 on Success * @retval -1 on Failure */ -static nve32_t validate_func_ptrs(struct osi_dma_priv_data *osi_dma) +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; @@ -158,14 +181,15 @@ static nve32_t validate_func_ptrs(struct osi_dma_priv_data *osi_dma) nve32_t osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) { + struct dma_local *l_dma = (struct dma_local *)osi_dma; typedef void (*init_ops_arr)(struct dma_chan_ops *temp); typedef void *(*safety_init)(void); - init_ops_arr i_ops[2] = { + init_ops_arr i_ops[MAX_MAC_IP_TYPES] = { eqos_init_dma_chan_ops, mgbe_init_dma_chan_ops }; - safety_init s_init[2] = { + safety_init s_init[MAX_MAC_IP_TYPES] = { eqos_get_dma_safety_config, OSI_NULL }; @@ -173,6 +197,11 @@ nve32_t osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) return -1; } + if ((l_dma->magic_num != (nveu64_t)osi_dma) || + (l_dma->init_done == OSI_ENABLE)) { + return -1; + } + 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) || @@ -186,7 +215,7 @@ nve32_t osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) return -1; } - i_ops[osi_dma->mac](ops_p); + 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](); @@ -198,23 +227,25 @@ nve32_t osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) return -1; } - if (validate_func_ptrs(osi_dma) < 0) { + 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; } - g_dma.init_done = OSI_ENABLE; + 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) < 0) { + if (validate_args(osi_dma, l_dma) < 0) { return -1; } @@ -230,38 +261,38 @@ nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) return -1; } - ret = ops_p->init_dma_channel(osi_dma); + 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, ops_p); + ret = dma_desc_init(osi_dma, l_dma->ops_p); if (ret != 0) { return ret; } - g_dma.mac_ver = osi_readl((nveu8_t *)osi_dma->base + MAC_VERSION) & + l_dma->mac_ver = osi_readl((nveu8_t *)osi_dma->base + MAC_VERSION) & MAC_VERSION_SNVER_MASK; - if (is_valid_mac_version(g_dma.mac_ver) == 0) { + if (is_valid_mac_version(l_dma->mac_ver) == 0) { OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "Invalid MAC version\n", (nveu64_t)g_dma.mac_ver); + "Invalid MAC version\n", (nveu64_t)l_dma->mac_ver); return -1; } - if ((g_dma.mac_ver != OSI_EQOS_MAC_4_10) && - (g_dma.mac_ver != OSI_EQOS_MAC_5_00)) { - g_dma.vm_intr = OSI_ENABLE; + 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]; - ops_p->enable_chan_tx_intr(osi_dma->base, chan); - ops_p->enable_chan_rx_intr(osi_dma->base, chan); - ops_p->start_dma(osi_dma, chan); + 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); } return 0; @@ -269,9 +300,10 @@ nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) 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) < 0) { + if (validate_args(osi_dma, l_dma) < 0) { return -1; } @@ -288,16 +320,21 @@ nve32_t osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma) } for (i = 0; i < osi_dma->num_dma_chans; i++) { - ops_p->stop_dma(osi_dma, osi_dma->dma_chans[i]); + l_dma->ops_p->stop_dma(osi_dma, osi_dma->dma_chans[i]); } + 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) { - if (validate_args(osi_dma) < 0) { + struct dma_local *l_dma = (struct dma_local *)osi_dma; + + if (validate_args(osi_dma, l_dma) < 0) { return -1; } @@ -305,7 +342,7 @@ nve32_t osi_disable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, return -1; } - ops_p->disable_chan_tx_intr(osi_dma->base, chan); + l_dma->ops_p->disable_chan_tx_intr(osi_dma->base, chan); return 0; } @@ -313,7 +350,9 @@ nve32_t osi_disable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, nve32_t osi_enable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, nveu32_t chan) { - if (validate_args(osi_dma) < 0) { + struct dma_local *l_dma = (struct dma_local *)osi_dma; + + if (validate_args(osi_dma, l_dma) < 0) { return -1; } @@ -321,7 +360,7 @@ nve32_t osi_enable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, return -1; } - ops_p->enable_chan_tx_intr(osi_dma->base, chan); + l_dma->ops_p->enable_chan_tx_intr(osi_dma->base, chan); return 0; } @@ -329,7 +368,9 @@ nve32_t osi_enable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, nve32_t osi_disable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, nveu32_t chan) { - if (validate_args(osi_dma) < 0) { + struct dma_local *l_dma = (struct dma_local *)osi_dma; + + if (validate_args(osi_dma, l_dma) < 0) { return -1; } @@ -337,7 +378,7 @@ nve32_t osi_disable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, return -1; } - ops_p->disable_chan_rx_intr(osi_dma->base, chan); + l_dma->ops_p->disable_chan_rx_intr(osi_dma->base, chan); return 0; } @@ -345,7 +386,9 @@ nve32_t osi_disable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, nve32_t osi_enable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, nveu32_t chan) { - if (validate_args(osi_dma) < 0) { + struct dma_local *l_dma = (struct dma_local *)osi_dma; + + if (validate_args(osi_dma, l_dma) < 0) { return -1; } @@ -353,7 +396,7 @@ nve32_t osi_enable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, return -1; } - ops_p->enable_chan_rx_intr(osi_dma->base, chan); + l_dma->ops_p->enable_chan_rx_intr(osi_dma->base, chan); return 0; } @@ -361,7 +404,9 @@ nve32_t osi_enable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, nve32_t osi_clear_vm_tx_intr(struct osi_dma_priv_data *osi_dma, nveu32_t chan) { - if (validate_args(osi_dma) < 0) { + struct dma_local *l_dma = (struct dma_local *)osi_dma; + + if (validate_args(osi_dma, l_dma) < 0) { return -1; } @@ -369,7 +414,7 @@ nve32_t osi_clear_vm_tx_intr(struct osi_dma_priv_data *osi_dma, return -1; } - ops_p->clear_vm_tx_intr(osi_dma->base, chan); + l_dma->ops_p->clear_vm_tx_intr(osi_dma->base, chan); return 0; } @@ -377,7 +422,9 @@ nve32_t osi_clear_vm_tx_intr(struct osi_dma_priv_data *osi_dma, nve32_t osi_clear_vm_rx_intr(struct osi_dma_priv_data *osi_dma, nveu32_t chan) { - if (validate_args(osi_dma) < 0) { + struct dma_local *l_dma = (struct dma_local *)osi_dma; + + if (validate_args(osi_dma, l_dma) < 0) { return -1; } @@ -385,18 +432,20 @@ nve32_t osi_clear_vm_rx_intr(struct osi_dma_priv_data *osi_dma, return -1; } - ops_p->clear_vm_rx_intr(osi_dma->base, chan); + 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) { - if (validate_args(osi_dma) < 0) { + struct dma_local *l_dma = (struct dma_local *)osi_dma; + + if (validate_args(osi_dma, l_dma) < 0) { return 0; } - return ops_p->get_global_dma_status(osi_dma->base); + return l_dma->ops_p->get_global_dma_status(osi_dma->base); } nve32_t osi_handle_dma_intr(struct osi_dma_priv_data *osi_dma, @@ -404,15 +453,16 @@ nve32_t osi_handle_dma_intr(struct osi_dma_priv_data *osi_dma, 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] = { - { { ops_p->disable_chan_tx_intr, ops_p->enable_chan_tx_intr }, - { ops_p->disable_chan_rx_intr, ops_p->enable_chan_rx_intr } }, - { { ops_p->clear_vm_tx_intr, ops_p->enable_chan_tx_intr }, - { ops_p->clear_vm_rx_intr, ops_p->enable_chan_rx_intr } } + { { 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) < 0) { + if (validate_args(osi_dma, l_dma) < 0) { return -1; } @@ -425,7 +475,7 @@ nve32_t osi_handle_dma_intr(struct osi_dma_priv_data *osi_dma, return -1; } - fn[g_dma.vm_intr][tx_rx][en_dis](osi_dma->base, chan); + fn[l_dma->vm_intr][tx_rx][en_dis](osi_dma->base, chan); return 0; } @@ -433,7 +483,9 @@ nve32_t osi_handle_dma_intr(struct osi_dma_priv_data *osi_dma, nve32_t osi_start_dma(struct osi_dma_priv_data *osi_dma, nveu32_t chan) { - if (validate_args(osi_dma) < 0) { + struct dma_local *l_dma = (struct dma_local *)osi_dma; + + if (validate_args(osi_dma, l_dma) < 0) { return -1; } @@ -441,7 +493,7 @@ nve32_t osi_start_dma(struct osi_dma_priv_data *osi_dma, return -1; } - ops_p->start_dma(osi_dma, chan); + l_dma->ops_p->start_dma(osi_dma, chan); return 0; } @@ -449,7 +501,9 @@ nve32_t osi_start_dma(struct osi_dma_priv_data *osi_dma, nve32_t osi_stop_dma(struct osi_dma_priv_data *osi_dma, nveu32_t chan) { - if (validate_args(osi_dma) < 0) { + struct dma_local *l_dma = (struct dma_local *)osi_dma; + + if (validate_args(osi_dma, l_dma) < 0) { return -1; } @@ -457,7 +511,7 @@ nve32_t osi_stop_dma(struct osi_dma_priv_data *osi_dma, return -1; } - ops_p->stop_dma(osi_dma, chan); + l_dma->ops_p->stop_dma(osi_dma, chan); return 0; } @@ -493,10 +547,11 @@ nveu32_t osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring) */ 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) < 0) { + if (validate_args(osi_dma, l_dma) < 0) { return -1; } @@ -556,13 +611,14 @@ static inline void rx_dma_handle_ioc(struct osi_dma_priv_data *osi_dma, 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; /* for CERT-C error */ nveu64_t temp; 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, rx_ring, chan) < 0) { + if (rx_dma_desc_validate_args(osi_dma, l_dma, rx_ring, chan) < 0) { /* Return on arguments validation failure */ return -1; } @@ -629,18 +685,20 @@ nve32_t osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, return -1; } - ops_p->update_rx_tailptr(osi_dma->base, chan, tailptr); + 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) { - if (validate_args(osi_dma) < 0) { + struct dma_local *l_dma = (struct dma_local *)osi_dma; + + if (validate_args(osi_dma, l_dma) < 0) { return -1; } - ops_p->set_rx_buf_len(osi_dma); + l_dma->ops_p->set_rx_buf_len(osi_dma); return 0; } @@ -648,7 +706,9 @@ nve32_t osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) nve32_t osi_dma_get_systime_from_mac(struct osi_dma_priv_data *const osi_dma, nveu32_t *sec, nveu32_t *nsec) { - if (validate_args(osi_dma) < 0) { + struct dma_local *l_dma = (struct dma_local *)osi_dma; + + if (validate_args(osi_dma, l_dma) < 0) { return -1; } @@ -659,7 +719,9 @@ nve32_t osi_dma_get_systime_from_mac(struct osi_dma_priv_data *const osi_dma, nveu32_t osi_is_mac_enabled(struct osi_dma_priv_data *const osi_dma) { - if (validate_args(osi_dma) < 0) { + struct dma_local *l_dma = (struct dma_local *)osi_dma; + + if (validate_args(osi_dma, l_dma) < 0) { return OSI_DISABLE; } @@ -668,7 +730,9 @@ nveu32_t osi_is_mac_enabled(struct osi_dma_priv_data *const osi_dma) nve32_t osi_hw_transmit(struct osi_dma_priv_data *osi_dma, nveu32_t chan) { - if (osi_unlikely(validate_args(osi_dma) < 0)) { + struct dma_local *l_dma = (struct dma_local *)osi_dma; + + if (osi_unlikely(validate_args(osi_dma, l_dma) < 0)) { return -1; } @@ -682,7 +746,7 @@ nve32_t osi_hw_transmit(struct osi_dma_priv_data *osi_dma, nveu32_t chan) return -1; } - return hw_transmit(osi_dma, osi_dma->tx_ring[chan], ops_p, chan); + return hw_transmit(osi_dma, osi_dma->tx_ring[chan], l_dma->ops_p, chan); } #ifndef OSI_STRIPPED_LIB @@ -710,9 +774,10 @@ nve32_t osi_hw_transmit(struct osi_dma_priv_data *osi_dma, nveu32_t chan) * @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) < 0) { + if (validate_args(osi_dma, l_dma) < 0) { return -1; } @@ -729,11 +794,12 @@ static inline nve32_t osi_slot_args_validate(struct osi_dma_priv_data *osi_dma, 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, set) < 0) { + if (osi_slot_args_validate(osi_dma, l_dma, set) < 0) { return -1; } @@ -766,7 +832,7 @@ nve32_t osi_config_slot_function(struct osi_dma_priv_data *osi_dma, return -1; } tx_ring->slot_check = set; - ops_p->config_slot(osi_dma, chan, set, interval); + l_dma->ops_p->config_slot(osi_dma, chan, set, interval); } } @@ -775,11 +841,13 @@ nve32_t osi_config_slot_function(struct osi_dma_priv_data *osi_dma, nve32_t osi_validate_dma_regs(struct osi_dma_priv_data *osi_dma) { - if (validate_args(osi_dma) < 0) { + struct dma_local *l_dma = (struct dma_local *)osi_dma; + + if (validate_args(osi_dma, l_dma) < 0) { return -1; } - return ops_p->validate_regs(osi_dma); + return l_dma->ops_p->validate_regs(osi_dma); } nve32_t osi_txring_empty(struct osi_dma_priv_data *osi_dma, nveu32_t chan) From 3b58f56f668c246c3317332419693ddbc8038079 Mon Sep 17 00:00:00 2001 From: Rakesh Goayl <rgoyal@nvidia.com> Date: Wed, 31 Mar 2021 12:51:39 +0530 Subject: [PATCH 213/458] osi: compile OSI core and dma for QNX Bug 200671160 Change-Id: I0c635914471cbd99d49b3e9d4b09dd70cd7d3159 Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> --- osi/core/Makefile.sdk | 8 +++++++- osi/core/Makefile.tmk | 9 +++++++-- osi/core/eqos_core.c | 21 ++++++++++++--------- osi/core/mgbe_core.c | 22 +++++++++++++--------- osi/dma/Makefile.sdk | 6 +++++- osi/dma/Makefile.tmk | 7 +++++-- osi/dma/osi_dma_txrx.c | 1 - 7 files changed, 49 insertions(+), 25 deletions(-) diff --git a/osi/core/Makefile.sdk b/osi/core/Makefile.sdk index d3fa4a2..ecabc4c 100644 --- a/osi/core/Makefile.sdk +++ b/osi/core/Makefile.sdk @@ -10,7 +10,7 @@ include $(PDK_TOP)/drive-t186ref-qnx/make/nvdefs.mk TARGETS = libnvethernetrm.so -CFLAGS += -g -Wall $(NV_PLATFORM_OPT) $(NV_PLATFORM_CFLAGS) -DOSI_STRIPPED_LIB +CFLAGS += -g -Wall $(NV_PLATFORM_OPT) $(NV_PLATFORM_CFLAGS) CPPFLAGS = $(NV_PLATFORM_SDK_INC) $(NV_PLATFORM_CPPFLAGS) -I../../../include -I../dma -I../common/include CPPFLAGS += -DNV_IS_SAFETY=$(NV_PLATFORM_SAFETY) LDFLAGS := \ @@ -21,9 +21,15 @@ LDFLAGS += -shared OBJS := eqos_core.o OBJS += eqos_mmc.o OBJS += osi_core.o +OBJS += vlan_filter.o +OBJS += frp.o +OBJS += mgbe_core.o +OBJS += xpcs.o +OBJS += mgbe_mmc.o OBJS += ivc_core.o OBJS += ./../common/osi_common.o OBJS += ./../common/eqos_common.o +OBJS += ./../common/mgbe_common.o CFLAGS += -D_FILE_OFFSET_BITS=64 diff --git a/osi/core/Makefile.tmk b/osi/core/Makefile.tmk index cc1d181..95afd03 100644 --- a/osi/core/Makefile.tmk +++ b/osi/core/Makefile.tmk @@ -26,7 +26,6 @@ ifdef NV_COMPONENT_FLAG_SHARED_LIBRARY_SECTION include $(NV_BUILD_START_COMPONENT) NV_COMPONENT_STRICT_WARNINGS_qnx_64 := 1 -NV_COMPONENT_CFLAGS := -DOSI_STRIPPED_LIB NV_COMPONENT_NAME := nvethernetrm NV_COMPONENT_OWN_INTERFACE_DIR := . @@ -34,9 +33,15 @@ NV_COMPONENT_SOURCES := \ eqos_core.c \ eqos_mmc.c \ osi_core.c \ + vlan_filter.c \ ivc_core.c \ + frp.c \ + mgbe_core.c \ + xpcs.c \ + mgbe_mmc.c \ $(NV_SOURCE)/nvethernetrm/osi/common/osi_common.c \ - $(NV_SOURCE)/nvethernetrm/osi/common/eqos_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 \ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 5e3d229..32c3af6 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -2183,7 +2183,6 @@ static void eqos_handle_mtl_intrs(struct osi_core_priv_data *osi_core) 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; @@ -2198,7 +2197,8 @@ static void eqos_handle_mtl_intrs(struct osi_core_priv_data *osi_core) 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_readl(osi_core->base + EQOS_MTL_EST_SCH_ERR); + sch_err = osi_readl((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; @@ -2209,7 +2209,8 @@ static void eqos_handle_mtl_intrs(struct osi_core_priv_data *osi_core) } } sch_err &= 0xFFU; /* only 8 TC allowed so clearing all */ - osi_writel(sch_err, osi_core->base + EQOS_MTL_EST_SCH_ERR); + osi_writel(sch_err, + (nveu8_t *)osi_core->base + EQOS_MTL_EST_SCH_ERR); } if ((val & EQOS_MTL_EST_STATUS_HLBF) == EQOS_MTL_EST_STATUS_HLBF) { @@ -2218,7 +2219,8 @@ static void eqos_handle_mtl_intrs(struct osi_core_priv_data *osi_core) 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_readl(osi_core->base + EQOS_MTL_EST_FRMS_ERR); + frm_err = osi_readl((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; @@ -2229,7 +2231,8 @@ static void eqos_handle_mtl_intrs(struct osi_core_priv_data *osi_core) } } frm_err &= 0xFFU; /* 8 TC allowed so clearing all */ - osi_writel(frm_err, osi_core->base + EQOS_MTL_EST_FRMS_ERR); + osi_writel(frm_err, (nveu8_t *)osi_core->base + + EQOS_MTL_EST_FRMS_ERR); } if ((val & EQOS_MTL_EST_STATUS_SWLC) == EQOS_MTL_EST_STATUS_SWLC) { @@ -2250,7 +2253,7 @@ static void eqos_handle_mtl_intrs(struct osi_core_priv_data *osi_core) osi_core->est_ready = OSI_DISABLE; } /* clear EST status register as interrupt is handled */ - osi_writel(val, osi_core->base + EQOS_MTL_EST_STATUS); + osi_writel(val, (nveu8_t *)osi_core->base + EQOS_MTL_EST_STATUS); } /** @@ -2708,7 +2711,7 @@ static int eqos_config_ptp_offload(struct osi_core_priv_data *osi_core, unsigned int port_id = 0x0U; /* Read MAC TCR */ - value = osi_readl(addr + EQOS_MAC_TCR); + value = osi_readl((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 | @@ -3923,7 +3926,7 @@ static int eqos_config_ptp_rxq(struct osi_core_priv_data *osi_core, } /* Read MAC_RxQ_Ctrl1 */ - value = osi_readl(base + EQOS_MAC_RQC1R); + value = osi_readl((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. @@ -5598,7 +5601,7 @@ static nve32_t eqos_get_hw_features(struct osi_core_priv_data *const osi_core, * * @retval -1 Always */ -nve32_t eqos_config_rss(struct osi_core_priv_data *const osi_core) +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); diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 5c3c3e3..c51da08 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -2084,7 +2084,7 @@ static int mgbe_update_frp_nve(struct osi_core_priv_data *const osi_core, * @param[in] rx_fifo: Rx FIFO size. * @param[in] value: Stores RFD and RSA values */ -void update_rfa_rfd(unsigned int rx_fifo, unsigned int *value) +static void update_rfa_rfd(unsigned int rx_fifo, unsigned int *value) { switch (rx_fifo) { case MGBE_21K: @@ -3379,7 +3379,7 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core) unsigned int i = 0; unsigned long stat_val = 0; - val = osi_readl(osi_core->base + MGBE_MTL_EST_STATUS); + val = osi_readl((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); @@ -3403,7 +3403,8 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core) 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_readl(osi_core->base + MGBE_MTL_EST_SCH_ERR); + sch_err = osi_readl((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; @@ -3414,7 +3415,8 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core) } } sch_err &= 0xFFU; //only 8 TC allowed so clearing all - osi_writel(sch_err, osi_core->base + MGBE_MTL_EST_SCH_ERR); + osi_writel(sch_err, (nveu8_t *)osi_core->base + + MGBE_MTL_EST_SCH_ERR); } if ((val & MGBE_MTL_EST_STATUS_HLBF) == MGBE_MTL_EST_STATUS_HLBF) { @@ -3423,7 +3425,8 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core) 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_readl(osi_core->base + MGBE_MTL_EST_FRMS_ERR); + frm_err = osi_readl((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; @@ -3434,7 +3437,8 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core) } } frm_err &= 0xFFU; //only 8 TC allowed so clearing all - osi_writel(frm_err, osi_core->base + MGBE_MTL_EST_FRMS_ERR); + osi_writel(frm_err, (nveu8_t *)osi_core->base + + MGBE_MTL_EST_FRMS_ERR); } if ((val & MGBE_MTL_EST_STATUS_SWLC) == MGBE_MTL_EST_STATUS_SWLC) { @@ -3455,7 +3459,7 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core) osi_core->est_ready = OSI_DISABLE; } /* clear EST status register as interrupt is handled */ - osi_writel(val, osi_core->base + MGBE_MTL_EST_STATUS); + osi_writel(val, (nveu8_t *)osi_core->base + MGBE_MTL_EST_STATUS); } /** @@ -3656,12 +3660,12 @@ static void mgbe_handle_common_intr(struct osi_core_priv_data *osi_core) MGBE_WRAP_COMMON_INTR_ENABLE); /* Clear FRP Interrupts in MTL_RXP_Interrupt_Control_Status */ - val = osi_readl(base + MGBE_MTL_RXP_INTR_CS); + val = osi_readl((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_writel(val, base + MGBE_MTL_RXP_INTR_CS); + osi_writel(val, (nveu8_t *)base + MGBE_MTL_RXP_INTR_CS); } /** diff --git a/osi/dma/Makefile.sdk b/osi/dma/Makefile.sdk index 39ff0b0..6415826 100644 --- a/osi/dma/Makefile.sdk +++ b/osi/dma/Makefile.sdk @@ -10,7 +10,7 @@ include $(PDK_TOP)/drive-t186ref-qnx/make/nvdefs.mk TARGETS = libnvethernetcl.so -CFLAGS += -g -Wall $(NV_PLATFORM_OPT) $(NV_PLATFORM_CFLAGS) -DOSI_STRIPPED_LIB +CFLAGS += -g -Wall $(NV_PLATFORM_OPT) $(NV_PLATFORM_CFLAGS) CPPFLAGS = $(NV_PLATFORM_SDK_INC) $(NV_PLATFORM_CPPFLAGS) -I../../../include -I../core -I../common/include CPPFLAGS += -DNV_IS_SAFETY=$(NV_PLATFORM_SAFETY) LDFLAGS := \ @@ -21,8 +21,12 @@ LDFLAGS += -shared OBJS := eqos_dma.o OBJS += osi_dma.o OBJS += osi_dma_txrx.o +OBJS += mgbe_dma.o +OBJS += eqos_desc.o +OBJS += mgbe_desc.o OBJS += ./../common/osi_common.o OBJS += ./../common/eqos_common.o +OBJS += ./../common/mgbe_common.o CFLAGS += -D_FILE_OFFSET_BITS=64 diff --git a/osi/dma/Makefile.tmk b/osi/dma/Makefile.tmk index 99677cf..de97716 100644 --- a/osi/dma/Makefile.tmk +++ b/osi/dma/Makefile.tmk @@ -26,7 +26,6 @@ ifdef NV_COMPONENT_FLAG_SHARED_LIBRARY_SECTION include $(NV_BUILD_START_COMPONENT) NV_COMPONENT_STRICT_WARNINGS_qnx_64 := 1 -NV_COMPONENT_CFLAGS := -DOSI_STRIPPED_LIB NV_COMPONENT_NAME := nvethernetcl NV_COMPONENT_OWN_INTERFACE_DIR := . @@ -34,8 +33,12 @@ NV_COMPONENT_SOURCES := \ eqos_dma.c \ osi_dma.c \ osi_dma_txrx.c \ + mgbe_dma.c \ + eqos_desc.c \ + mgbe_desc.c \ $(NV_SOURCE)/nvethernetrm/osi/common/osi_common.c \ - $(NV_SOURCE)/nvethernetrm/osi/common/eqos_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 \ diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 0cd0d99..3aca22e 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -22,7 +22,6 @@ #include "dma_local.h" #include <osi_dma_txrx.h> -#include "../osi/common/type.h" #include "hw_desc.h" #include "../osi/common/common.h" #include "mgbe_dma.h" From c9a63a7a92039ef18ba8aecc14e4c60a753806d7 Mon Sep 17 00:00:00 2001 From: rakesh goyal <rgoyal@nvidia.com> Date: Thu, 18 Feb 2021 21:49:59 +0530 Subject: [PATCH 214/458] core: handle ioctl in single API To reduce number of external interface APIs, consolidate all IOCTL API to one interface API. Bug 200671160 Change-Id: I407ee5c50c8b3293c5be613beda68e1e450dce89 Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> --- include/osi_core.h | 850 ++++++++------------------------ osi/core/libnvethernetrm.export | 3 +- osi/core/osi_core.c | 748 +++++++++++++++++++--------- 3 files changed, 739 insertions(+), 862 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 32fc6a8..4667252 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -78,9 +78,7 @@ typedef my_lint_64 nvel64_t; #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) -#ifndef OSI_STRIPPED_LIB #define OSI_MAC_TCR_SNAPTYPSEL_3 (OSI_BIT(16) | OSI_BIT(17)) -#endif /* !OSI_STRIPPED_LIB */ /** @} */ /** @@ -156,6 +154,52 @@ typedef my_lint_64 nvel64_t; #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 /** @} */ /** @@ -957,6 +1001,52 @@ struct osi_macsec_irq_stats { }; #endif /* MACSEC_SUPPORT */ +/** + * @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; +}; + /** * @brief The OSI Core (MAC & MTL) private data structure. */ @@ -1649,24 +1739,6 @@ nve32_t osi_read_phy_reg(struct osi_core_priv_data *const osi_core, */ nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core); -/** - * @brief osi_config_ptp_offload - Enable/Disable PTP offload - * - * Algorithm: Based on input argument, update TSCR and PTO registers. - * Update ptp_filter for TSCR register and call PTP configurtion API. - * - * @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() - * - * @retval 0 on success - * @retval -1 on failure. - */ -int osi_config_ptp_offload(struct osi_core_priv_data *const osi_core, - struct osi_pto_config *const pto_config); - /** * @brief osi_set_systime_to_mac - Handles setting of system time. * @@ -1951,550 +2023,134 @@ nve32_t osi_get_mac_version(struct osi_core_priv_data *const osi_core, nve32_t osi_get_hw_features(struct osi_core_priv_data *const osi_core, struct osi_hw_features *hw_feat); -#ifndef OSI_STRIPPED_LIB /** - * @brief osi_validate_core_regs - Read-validate HW registers for func safety. + * @brief osi_handle_ioctl - API to handle runtime command * * @note * Algorithm: - * - Reads pre-configured list of MAC/MTL configuration registers - * and compares with last written value for any modifications. + * - 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 * * @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 - * 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. - */ -nve32_t osi_validate_core_regs(struct osi_core_priv_data *const osi_core); - -/** - * @brief osi_flush_mtl_tx_queue - Flushing a MTL Tx Queue. - * - * @note - * Algorithm: - * - Invokes EQOS flush Tx queue routine. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] qinx: MTL queue index. - * - * @pre - * - MAC should out of reset and clocks enabled. - * - hw core initialized. see osi_hw_core_init(). - * - * @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. - */ -nve32_t osi_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, - const nveu32_t qinx); - -/** - * @brief osi_set_avb - Set CBS algo and parameters - * - * @note - * Algorithm: - * - Set AVB algo and populated parameter from osi_core_avb - * structure for TC/TQ - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] avb: osi core avb data structure. - * - * @pre - * - MAC should be init and started. see osi_start_mac() - * - osi_core->osd should be populated. - * - * @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. - */ -nve32_t osi_set_avb(struct osi_core_priv_data *const osi_core, - const struct osi_core_avb_algorithm *avb); - -/** - * @brief osi_get_avb - Get CBS algo and parameters - * - * @note - * Algorithm: - * - get AVB algo and populated parameter from osi_core_avb - * structure for TC/TQ - * - * @param[in] osi_core: OSI core private data structure. - * @param[out] avb: osi core avb data structure. - * - * @pre - * - MAC should be init and started. see osi_start_mac() - * - osi_core->osd should be populated. - * - * @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. - */ -nve32_t osi_get_avb(struct osi_core_priv_data *const osi_core, - struct osi_core_avb_algorithm *avb); - -/** - * @brief osi_configure_txstatus - Configure Tx packet status reporting - * - * @note - * Algorithm: - * - Configure MAC to enable/disable Tx status error - * reporting. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] tx_status: Enable or disable tx packet status reporting - * - * @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: No - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_configure_txstatus(struct osi_core_priv_data *const osi_core, - const nveu32_t tx_status); - -/** - * @brief osi_config_rx_crc_check - Configure CRC Checking for Received 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 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. - */ -nve32_t osi_config_rx_crc_check(struct osi_core_priv_data *const osi_core, - const nveu32_t crc_chk); - -/** - * @brief osi_configure_flow_ctrl - Configure flow control settings - * - * @note - * Algorithm: - * - This will enable or disable the flow control. - * flw_ctrl BIT0 is for tx flow ctrl enable/disable - * flw_ctrl BIT1 is for rx flow ctrl enable/disable - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] flw_ctrl: Enable or disable flow control settings - * - * @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. - */ -nve32_t osi_configure_flow_control(struct osi_core_priv_data *const osi_core, - const nveu32_t flw_ctrl); - -/** - * @brief osi_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. - */ -nve32_t osi_config_arp_offload(struct osi_core_priv_data *const osi_core, - const nveu32_t flags, - const nveu8_t *ip_addr); -/** - * @brief osi_ptp_rxq - 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. - */ -int osi_rxq_route(struct osi_core_priv_data *const osi_core, - const struct osi_rxq_route *rx_route); - -/** - * @brief osi_config_vlan_filtering - OSI call for configuring VLAN filter - * - * @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 private data structure. - * @param[in] filter_enb_dis: vlan filter enable(1) disable(0) - * @param[in] perfect_hash_filtering: perfect(0) or hash filter(1) - * @param[in] perfect_inverse_match: normal(0) or inverse filter(1) - * - * @pre - * - MAC should be init and started. see osi_start_mac() - * - osi_core->osd should be populated - * - * @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. - */ -nve32_t osi_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); - -/** - * @brief osi_update_vlan_id - 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. - */ -nve32_t osi_update_vlan_id(struct osi_core_priv_data *const osi_core, - const nveu32_t vid); - -/** - * @brief osi_reset_mmc - invoke function to reset MMC counter and data - * structure - * - * @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: - * - * @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. - */ -nve32_t osi_reset_mmc(struct osi_core_priv_data *const osi_core); - -/** - * @brief osi_configure_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. - */ -nve32_t osi_configure_eee(struct osi_core_priv_data *const osi_core, - nveu32_t tx_lpi_enabled, - nveu32_t tx_lpi_timer); - -/** - * @brief osi_save_registers - Take backup of MAC MMIO address space - * - * @param[in] osi_core: OSI core private data structure. - * - * @pre - * - MAC and PHY should be init and started. see osi_start_mac() - * - No further configuration change in MAC shall be done after invoking - * this API - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_save_registers(struct osi_core_priv_data *const osi_core); - -/** - * @brief osi_restore_registers - Restore backup of MAC MMIO address space - * - * @param[in] osi_core: OSI core private data structure. - * - * @pre - * - MAC and PHY 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. - */ -nve32_t osi_restore_registers(struct osi_core_priv_data *const osi_core); - -/** - * @brief osi_set_mdc_clk_rate - Derive MDC clock based on provided AXI_CBB clk. - * - * @note - * Algorithm: - * - MDC clock rate will be populated in 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. - * - * @note OSD layer needs get the AXI CBB clock rate with OSD clock API - * (ex - clk_get_rate()) - * - * @note - * Traceability Details: - * - * @note - * Classification: - * - Interrupt: No - * - Signal handler: No - * - Thread safe: No - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, - const nveu64_t csr_clk_rate); - -/** - * @brief osi_config_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 + * @param[in] data: void pointer pointing to osi_ioctl * * @pre MAC should be init and started. see osi_start_mac() * @@ -2517,82 +2173,8 @@ nve32_t osi_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -nve32_t osi_config_mac_loopback(struct osi_core_priv_data *const osi_core, - const nveu32_t lb_mode); -#endif /* !OSI_STRIPPED_LIB */ - -/** - * @brief osi_config_rss - Configuration of RSS. - * - * @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. - */ -nve32_t osi_config_rss(struct osi_core_priv_data *const osi_core); - -/** - * @brief osi_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. - * - * @note - * 1) MAC and PHY should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -int osi_configure_frp(struct osi_core_priv_data *const osi_core, - struct osi_core_frp_cmd *const cmd); -/** - * @brief osi_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: Configuration osi_est_config structure. - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -int osi_hw_config_est(struct osi_core_priv_data *osi_core, - struct osi_est_config *est); - -/** - * @brief osi_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: Configuration osi_fpe_config structure. - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -int osi_hw_config_fpe(struct osi_core_priv_data *osi_core, - struct osi_fpe_config *fpe); +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. diff --git a/osi/core/libnvethernetrm.export b/osi/core/libnvethernetrm.export index b601e24..88934be 100644 --- a/osi/core/libnvethernetrm.export +++ b/osi/core/libnvethernetrm.export @@ -1,6 +1,6 @@ ################################### tell Emacs this is a -*- makefile-gmake -*- # -# Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2019-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"), @@ -37,7 +37,6 @@ osi_set_speed osi_pad_calibrate osi_get_mac_version osi_get_hw_features -osi_config_ptp_offload osi_config_rxcsum_offload osi_l2_filter osi_l3l4_filter diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index cdf7c9f..d559d3c 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -368,16 +368,12 @@ nve32_t osi_config_fw_err_pkts(struct osi_core_priv_data *const osi_core, return l_core->ops_p->config_fw_err_pkts(osi_core, qinx, fw_err); } -int osi_config_ptp_offload(struct osi_core_priv_data *const osi_core, - struct osi_pto_config *const pto_config) +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; - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - /* Validate input arguments */ if (pto_config == OSI_NULL) { OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, @@ -740,7 +736,7 @@ nve32_t osi_adjust_freq(struct osi_core_priv_data *const osi_core, nve32_t ppb) } else { OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "addend > UINT_MAX\n", 0ULL); - return -1; + return ret; } } else { if (addend > diff) { @@ -891,8 +887,22 @@ nve32_t osi_ptp_configuration(struct osi_core_priv_data *const osi_core, return ret; } -int osi_rxq_route(struct osi_core_priv_data *const osi_core, - const struct osi_rxq_route *rxq_route) +/** + * @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; @@ -953,7 +963,43 @@ nve32_t osi_get_mac_version(struct osi_core_priv_data *const osi_core, } #ifndef OSI_STRIPPED_LIB -nve32_t osi_validate_core_regs(struct osi_core_priv_data *const osi_core) +/** + * @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_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; @@ -970,96 +1016,44 @@ nve32_t osi_validate_core_regs(struct osi_core_priv_data *const osi_core) return l_core->ops_p->validate_regs(osi_core); } -nve32_t osi_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, - const nveu32_t qinx) -{ - 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->flush_mtl_tx_queue(osi_core, qinx); -} - -nve32_t osi_set_avb(struct osi_core_priv_data *const osi_core, - const struct osi_core_avb_algorithm *avb) -{ - 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_avb_algorithm(osi_core, avb); -} - -nve32_t osi_get_avb(struct osi_core_priv_data *const osi_core, - struct osi_core_avb_algorithm *avb) -{ - 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->get_avb_algorithm(osi_core, avb); -} - -nve32_t osi_configure_txstatus(struct osi_core_priv_data *const osi_core, - const nveu32_t tx_status) -{ - struct core_local *l_core = (struct core_local *)osi_core; - - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - - /* Configure Drop Transmit Status */ - return l_core->ops_p->config_tx_status(osi_core, tx_status); -} - -nve32_t osi_config_rx_crc_check(struct osi_core_priv_data *const osi_core, - const nveu32_t crc_chk) -{ - struct core_local *l_core = (struct core_local *)osi_core; - - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - - /* Configure CRC Checking for Received Packets */ - return l_core->ops_p->config_rx_crc_check(osi_core, crc_chk); -} - -nve32_t osi_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) -{ - 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_vlan_filtering(osi_core, filter_enb_dis, - perfect_hash_filtering, - perfect_inverse_match); -} - -nve32_t osi_update_vlan_id(struct osi_core_priv_data *const osi_core, - const nveu32_t vid) +/** + * @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 (validate_args(osi_core, l_core) < 0) { - return -1; - } - if ((osi_core->mac_ver == OSI_EQOS_MAC_4_10) || (osi_core->mac_ver == OSI_EQOS_MAC_5_00)) { /* No VLAN ID filtering */ @@ -1078,28 +1072,45 @@ nve32_t osi_update_vlan_id(struct osi_core_priv_data *const osi_core, return update_vlan_id(osi_core, l_core->ops_p, vid); } -nve32_t osi_reset_mmc(struct osi_core_priv_data *const osi_core) +/** + * @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 (validate_args(osi_core, l_core) < 0) { - return -1; - } - - l_core->ops_p->reset_mmc(osi_core); - - return 0; -} - -nve32_t osi_configure_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 (validate_args(osi_core, l_core) < 0) { - return -1; - } - 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)) { @@ -1114,52 +1125,40 @@ nve32_t osi_configure_eee(struct osi_core_priv_data *const osi_core, return 0; } -nve32_t osi_save_registers(struct osi_core_priv_data *const osi_core) +/** + * @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 (validate_args(osi_core, l_core) < 0) { - return -1; - } - - /* Call MAC save registers callback and return the value */ - return l_core->ops_p->save_registers(osi_core); -} - -nve32_t osi_restore_registers(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; - } - - /* Call MAC restore registers callback and return the value */ - return l_core->ops_p->restore_registers(osi_core); -} - -nve32_t osi_configure_flow_control(struct osi_core_priv_data *const osi_core, - const nveu32_t flw_ctrl) -{ - struct core_local *l_core = (struct core_local *)osi_core; - - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - - /* Configure Flow control settings */ - return l_core->ops_p->config_flow_control(osi_core, flw_ctrl); -} - -int osi_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 (validate_args(osi_core, l_core) < 0) { - return -1; - } - if (cmd == OSI_NULL) { OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "Invalid argment\n", OSI_NONE); @@ -1177,16 +1176,46 @@ int osi_configure_frp(struct osi_core_priv_data *const osi_core, return setup_frp(osi_core, l_core->ops_p, cmd); } -nve32_t osi_config_arp_offload(struct osi_core_priv_data *const osi_core, - const nveu32_t flags, - const nveu8_t *ip_addr) +/** + * @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 ((validate_args(osi_core, l_core) < 0)) { - return -1; - } - if (ip_addr == OSI_NULL) { OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "CORE: ip_addr is NULL\n", 0ULL); @@ -1202,66 +1231,42 @@ nve32_t osi_config_arp_offload(struct osi_core_priv_data *const osi_core, return l_core->ops_p->config_arp_offload(osi_core, flags, ip_addr); } -nve32_t osi_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, - const nveu64_t csr_clk_rate) +/** + * @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; - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - - l_core->ops_p->set_mdc_clk_rate(osi_core, csr_clk_rate); - - return 0; -} - -int osi_config_rss(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->config_rss(osi_core); -} - -int osi_hw_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 (validate_args(osi_core, l_core) < 0) { - return -1; - } - - if (est == OSI_NULL) { - OSI_CORE_ERR(osi_core->osd, 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_core->osd, 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); -} - -nve32_t osi_config_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; - - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - /* 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, @@ -1269,28 +1274,319 @@ nve32_t osi_config_mac_loopback(struct osi_core_priv_data *const osi_core, return -1; } - /* Configure MAC loopback */ return l_core->ops_p->config_mac_loopback(osi_core, lb_mode); } +#endif /* !OSI_STRIPPED_LIB */ -int osi_hw_config_fpe(struct osi_core_priv_data *osi_core, - struct osi_fpe_config *fpe) +/** + * @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 (validate_args(osi_core, l_core) < 0) { + 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_core->osd, OSI_LOG_ARG_INVALID, + 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); } + +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; + struct core_ops *ops_p; + nve32_t ret = -1; + + 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 ret; + } + + 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); + break; + + case OSI_CMD_ADJ_TIME: + ret = osi_adjust_time(osi_core, data->arg8_64); + break; + + case OSI_CMD_CONFIG_PTP: + ret = osi_ptp_configuration(osi_core, data->arg1_u32); + 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); + 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; + + 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) From 836d0d14778d1e523642355969567475888737fa Mon Sep 17 00:00:00 2001 From: Mahesh Patil <maheshp@nvidia.com> Date: Wed, 10 Mar 2021 13:31:15 -0800 Subject: [PATCH 215/458] nvethernetrm: Enable macsec debug feature Validate input parameters and handle debug buffer interrupts Bug 3265346 Change-Id: I8a7ebf66d20867fe4fb890d7d09d044d15108a17 Signed-off-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2496672 Tested-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> --- osi/core/macsec.c | 81 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 59 insertions(+), 22 deletions(-) diff --git a/osi/core/macsec.c b/osi/core/macsec.c index be797c8..b6fa908 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -102,8 +102,9 @@ static inline void read_dbg_buf_data( /* Read debug buffer from HW */ for (i = 0; i < DBG_BUF_LEN; i++) { - dbg_buf[i] = osi_readl(base + DEBUG_BUF_DATA_0(1)); - pr_err("%s: dbg_buf_data[%d]: 0x%x\n", __func__, i, dbg_buf[i]); + dbg_buf[i] = osi_readl(base + DEBUG_BUF_DATA_0(i)); + /* pr_err("%s: dbg_buf_data[%d]: 0x%x\n", __func__, + i, dbg_buf[i]); */ } } @@ -163,7 +164,8 @@ static void tx_dbg_trigger_evts( tx_trigger_evts &= ~TX_DBG_CAPTURE; } - pr_err("%s: tx_trigger_evts 0x%x", __func__, tx_trigger_evts); + pr_err("%s: tx_dbg_trigger_evts 0x%x", __func__, + tx_trigger_evts); osi_writel(tx_trigger_evts, base + TX_DEBUG_TRIGGER_EN_0); if (tx_trigger_evts != OSI_NONE) { /** Start the tx debug buffer capture */ @@ -174,8 +176,9 @@ static void tx_dbg_trigger_evts( osi_writel(debug_ctrl_reg, base + TX_DEBUG_CONTROL_0); } } else { - tx_trigger_evts = osi_readl(base + TX_DEBUG_STATUS_0); - pr_err("%s: tx_trigger_evts 0x%x", __func__, tx_trigger_evts); + tx_trigger_evts = osi_readl(base + TX_DEBUG_TRIGGER_EN_0); + pr_err("%s: tx_dbg_trigger_evts 0x%x", __func__, + tx_trigger_evts); if (tx_trigger_evts & TX_DBG_LKUP_MISS) { flags |= TX_DBG_LKUP_MISS_EVT; } @@ -253,7 +256,8 @@ static void rx_dbg_trigger_evts( } else { rx_trigger_evts &= ~RX_DBG_CAPTURE; } - pr_err("%s: rx_trigger_evts 0x%x", __func__, rx_trigger_evts); + pr_err("%s: rx_dbg_trigger_evts 0x%x", __func__, + rx_trigger_evts); osi_writel(rx_trigger_evts, base + RX_DEBUG_TRIGGER_EN_0); if (rx_trigger_evts != OSI_NONE) { /** Start the tx debug buffer capture */ @@ -264,8 +268,9 @@ static void rx_dbg_trigger_evts( osi_writel(debug_ctrl_reg, base + RX_DEBUG_CONTROL_0); } } else { - rx_trigger_evts = osi_readl(base + RX_DEBUG_STATUS_0); - pr_err("%s: rx_trigger_evts 0x%x", __func__, rx_trigger_evts); + rx_trigger_evts = osi_readl(base + RX_DEBUG_TRIGGER_EN_0); + pr_err("%s: rx_dbg_trigger_evts 0x%x", __func__, + rx_trigger_evts); if (rx_trigger_evts & RX_DBG_LKUP_MISS) { flags |= RX_DBG_LKUP_MISS_EVT; } @@ -286,7 +291,6 @@ static void rx_dbg_trigger_evts( } dbg_buf_config->flags = flags; } - } /** @@ -303,7 +307,6 @@ static int macsec_dbg_buf_config(struct osi_core_priv_data *const osi_core, { unsigned char *base = (unsigned char *)osi_core->macsec_base; -// unsigned int en_flags; unsigned int dbg_config_reg = 0; int ret = 0; @@ -322,9 +325,6 @@ static int macsec_dbg_buf_config(struct osi_core_priv_data *const osi_core, dbg_buf_config->index); return -1; } - //en_flags = osi_readl(base + TX_DEBUG_TRIGGER_EN_0); - /** disable all trigger events */ - //osi_writel(0, base + TX_DEBUG_TRIGGER_EN_0); /* Wait for previous debug table update to finish */ ret = poll_for_dbg_buf_update(osi_core); @@ -332,9 +332,9 @@ static int macsec_dbg_buf_config(struct osi_core_priv_data *const osi_core, return ret; } - pr_err("%s: ctrl: %hu rw: %hu idx: %hu flags: %#x\n", __func__, + /* pr_err("%s: ctrl: %hu rw: %hu idx: %hu\n", __func__, dbg_buf_config->ctlr_sel, dbg_buf_config->rw, - dbg_buf_config->index, dbg_buf_config->flags); + dbg_buf_config->index); */ dbg_config_reg = osi_readl(base + DEBUG_BUF_CONFIG_0); @@ -355,7 +355,6 @@ static int macsec_dbg_buf_config(struct osi_core_priv_data *const osi_core, dbg_config_reg &= ~DEBUG_BUF_CONFIG_0_IDX_MASK; dbg_config_reg |= dbg_buf_config->index ; dbg_config_reg |= DEBUG_BUF_CONFIG_0_UPDATE; - pr_err("%s: dbg_config_reg 0x%x\n", __func__, dbg_config_reg); osi_writel(dbg_config_reg, base + DEBUG_BUF_CONFIG_0); ret = poll_for_dbg_buf_update(osi_core); if (ret < 0) { @@ -365,8 +364,6 @@ static int macsec_dbg_buf_config(struct osi_core_priv_data *const osi_core, if (!dbg_buf_config->rw) { read_dbg_buf_data(osi_core, dbg_buf_config->dbg_buf); } - /** Enable Tx trigger events */ -// osi_writel(en_flags, base + TX_DEBUG_TRIGGER_EN_0); return 0; } @@ -375,9 +372,8 @@ int macsec_dbg_events_config( struct osi_core_priv_data *const osi_core, struct osi_macsec_dbg_buf_config *const dbg_buf_config) { - - int ret = 0; - + unsigned int i, events = 0; + unsigned int flags = dbg_buf_config->flags; pr_err("%s():", __func__); /* Validate inputs */ @@ -386,6 +382,21 @@ int macsec_dbg_events_config( pr_err("%s(): Params validation failed", __func__); return -1; } + + /* Only one event allowed to configure at a time */ + if (flags != OSI_NONE && dbg_buf_config->rw == DBG_TBL_WRITE) { + for (i = 0; i < 32U; i++) { + if (flags & (1U << i)) { + events++; + } + } + if (events > 1U) { + pr_err("%s(): Don't allow more than one" + " debug events set 0x%x\n", __func__, flags); + return -1; + } + } + switch (dbg_buf_config->ctlr_sel) { case CTLR_SEL_TX: tx_dbg_trigger_evts(osi_core, dbg_buf_config); @@ -395,7 +406,7 @@ int macsec_dbg_events_config( break; } - return ret; + return 0; } /** @@ -1929,6 +1940,30 @@ static inline void handle_tx_pn_exhausted( osi_writel(clear, addr + TX_SC_PN_EXHAUSTED_STATUS1_0); } +static inline void handle_dbg_evt_capture_done( + struct osi_core_priv_data *const osi_core, + unsigned short ctrl_sel) +{ + unsigned char *addr = (unsigned char *)osi_core->macsec_base; + unsigned int trigger_evts = 0; + + if (ctrl_sel == CTLR_SEL_TX) { + trigger_evts = osi_readl(addr + TX_DEBUG_STATUS_0); + pr_err("%s: TX_DEBUG_STATUS_0 0x%x", __func__, trigger_evts); + osi_writel(trigger_evts, addr + TX_DEBUG_STATUS_0); + /* clear all trigger events */ + trigger_evts = 0U; + osi_writel(trigger_evts, addr + TX_DEBUG_TRIGGER_EN_0); + } else if (ctrl_sel == CTLR_SEL_RX) { + trigger_evts = osi_readl(addr + RX_DEBUG_STATUS_0); + pr_err("%s: RX_DEBUG_STATUS_0 0x%x", __func__, trigger_evts); + osi_writel(trigger_evts, addr + RX_DEBUG_STATUS_0); + /* clear all trigger events */ + trigger_evts = 0U; + osi_writel(trigger_evts, addr + RX_DEBUG_TRIGGER_EN_0); + } +} + static inline void handle_tx_irq(struct osi_core_priv_data *const osi_core) { unsigned int tx_isr, clear = 0; @@ -1937,6 +1972,7 @@ static inline void handle_tx_irq(struct osi_core_priv_data *const osi_core) tx_isr = osi_readl(addr + TX_ISR); pr_err("%s(): tx_isr 0x%x\n", __func__, tx_isr); if ((tx_isr & TX_DBG_BUF_CAPTURE_DONE) == TX_DBG_BUF_CAPTURE_DONE) { + handle_dbg_evt_capture_done(osi_core, CTLR_SEL_TX); osi_core->macsec_irq_stats.tx_dbg_capture_done++; clear |= TX_DBG_BUF_CAPTURE_DONE; } @@ -1990,6 +2026,7 @@ static inline void handle_rx_irq(struct osi_core_priv_data *const osi_core) pr_err("%s(): rx_isr 0x%x\n", __func__, rx_isr); if ((rx_isr & RX_DBG_BUF_CAPTURE_DONE) == RX_DBG_BUF_CAPTURE_DONE) { + handle_dbg_evt_capture_done(osi_core, CTLR_SEL_RX); osi_core->macsec_irq_stats.rx_dbg_capture_done++; clear |= RX_DBG_BUF_CAPTURE_DONE; } From cc554c67f38931ac8d57f5aa4135785c69fc1f4f Mon Sep 17 00:00:00 2001 From: nannaiah <nannaiah@nvidia.com> Date: Wed, 7 Apr 2021 21:19:27 -0700 Subject: [PATCH 216/458] osi: Add virtualization fix. - Change osi_readl to osi_readla - Change osi_writel to osi_writela - Add IVC macsec commands. - Add OSI_MGBE_MAC_3_00 as valid list of version. - Disable validate_func_ptrs as it returns failure. Bug 2694285 JIRA T23XMGBE-118 Signed-off-by: Nagaraj annaiah <nannaiah@nvidia.com> Change-Id: I49187c0decb3de4184b7ef5e3a2e553a60c1d54f Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2515254 Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> --- include/ivc_core.h | 12 + osi/common/common.h | 1 + osi/core/core_local.h | 13 + osi/core/eqos_core.c | 166 ++++++----- osi/core/ivc_core.c | 205 ++++++++++++++ osi/core/macsec.c | 248 ++++++++-------- osi/core/mgbe_core.c | 639 ++++++++++++++++++++++++------------------ osi/core/osi_core.c | 5 +- osi/core/xpcs.c | 8 +- osi/dma/osi_dma.c | 3 +- 10 files changed, 840 insertions(+), 460 deletions(-) diff --git a/include/ivc_core.h b/include/ivc_core.h index 0dc1308..cb37ba8 100644 --- a/include/ivc_core.h +++ b/include/ivc_core.h @@ -86,6 +86,18 @@ typedef enum ivc_cmd { set_mdc_clk_rate, config_mac_loopback, #endif /* !OSI_STRIPPED_LIB */ + init_macsec, + deinit_macsec, + handle_ns_irq_macsec, + handle_s_irq_macsec, + lut_config_macsec, + kt_config_macsec, + loopback_config_macsec, + en_macsec, + config_macsec, + read_mmc_macsec, + dbg_buf_config_macsec, + dbg_events_config_macsec, }ivc_cmd; /** diff --git a/osi/common/common.h b/osi/common/common.h index 75a8951..7aa998d 100644 --- a/osi/common/common.h +++ b/osi/common/common.h @@ -256,6 +256,7 @@ static inline nve32_t is_valid_mac_version(nveu32_t mac_ver) if ((mac_ver == OSI_EQOS_MAC_4_10) || (mac_ver == OSI_EQOS_MAC_5_00) || (mac_ver == OSI_EQOS_MAC_5_30) || + (mac_ver == OSI_MGBE_MAC_3_00) || (mac_ver == OSI_MGBE_MAC_3_10)) { return 1; } diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 5559193..5a31274 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -285,4 +285,17 @@ void ivc_init_core_ops(struct core_ops *ops); * - 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); #endif /* INCLUDED_CORE_LOCAL_H */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 32c3af6..62f70fe 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -40,7 +40,7 @@ static struct core_func_safety eqos_core_safety_config; * Algorithm: * - Acquire RW lock, so that eqos_validate_core_regs does not run while * updating the safety critical register. - * - call osi_writel() to actually update the memory mapped 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. @@ -1202,9 +1202,9 @@ static int eqos_config_frp(struct osi_core_priv_data *const osi_core, frp_enable_re: /* Enable RE */ - val = osi_readl(base + EQOS_MAC_MCR); + val = osi_readla(osi_core, base + EQOS_MAC_MCR); val |= EQOS_MCR_RE; - osi_writel(val, base + EQOS_MAC_MCR); + osi_writela(osi_core, val, base + EQOS_MAC_MCR); return ret; } @@ -1237,13 +1237,13 @@ static int eqos_update_frp_nve(struct osi_core_priv_data *const osi_core, } /* Update NVE and NPE in MTL_RXP_Control_Status register */ - val = osi_readl(base + EQOS_MTL_RXP_CS); + 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_writel(val, base + EQOS_MTL_RXP_CS); + osi_writela(osi_core, val, base + EQOS_MTL_RXP_CS); return 0; } @@ -1552,9 +1552,11 @@ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) EQOS_MAC_MCR, EQOS_MAC_MCR_IDX); /* Enable PDC */ - value = osi_readl((unsigned char *)osi_core->base + EQOS_MAC_EXTR); + value = osi_readla(osi_core, + (unsigned char *)osi_core->base + EQOS_MAC_EXTR); value |= EQOS_MAC_EXTR_PDC; - osi_writel(value, (unsigned char *)osi_core->base + EQOS_MAC_EXTR); + osi_writela(osi_core, value, + (unsigned char *)osi_core->base + EQOS_MAC_EXTR); /* Enable Multicast and Broadcast Queue, default is Q0 */ value = osi_readla(osi_core, @@ -1696,15 +1698,18 @@ static void eqos_configure_dma(struct osi_core_priv_data *const osi_core) * * Algorithm: enable MTL interrupts for EST * - * @param[in] addr: MAC base IOVA address. + * @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(void *addr) +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_readl((unsigned char *)addr + EQOS_MTL_EST_ITRE); + 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 @@ -1715,7 +1720,8 @@ static inline void eqos_enable_mtl_interrupts(void *addr) 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_writel(mtl_est_ir, (unsigned char *)addr + EQOS_MTL_EST_ITRE); + osi_writela(osi_core, mtl_est_ir, + (unsigned char *)addr + EQOS_MTL_EST_ITRE); } /** @@ -1723,19 +1729,21 @@ static inline void eqos_enable_mtl_interrupts(void *addr) * * Algorithm: enable FPE interrupts * - * @param[in] addr: MAC base IOVA address. + * @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(void *addr) +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_readl((unsigned char *)addr + EQOS_MAC_IMR); + value = osi_readla(osi_core, (unsigned char *)addr + EQOS_MAC_IMR); value |= EQOS_IMR_FPEIE; - osi_writel(value, (unsigned char *)addr + EQOS_MAC_IMR); + osi_writela(osi_core, value, (unsigned char *)addr + EQOS_MAC_IMR); } /** @@ -1762,7 +1770,7 @@ static void eqos_tsn_init(struct osi_core_priv_data *osi_core, unsigned int temp = 0U; if (est_sel == OSI_ENABLE) { - val = osi_readl((unsigned char *)osi_core->base + + val = osi_readla(osi_core, (unsigned char *)osi_core->base + EQOS_MTL_EST_CONTROL); /* @@ -1798,24 +1806,24 @@ static void eqos_tsn_init(struct osi_core_priv_data *osi_core, val |= EQOS_MTL_EST_CONTROL_LCSE_VAL; /* Drop Frames causing Scheduling Error */ val |= EQOS_MTL_EST_CONTROL_DFBS; - osi_writel(val, (nveu8_t *)osi_core->base + + osi_writela(osi_core, val, (nveu8_t *)osi_core->base + EQOS_MTL_EST_CONTROL); - eqos_enable_mtl_interrupts(osi_core->base); + eqos_enable_mtl_interrupts(osi_core); } if (fpe_sel == OSI_ENABLE) { - val = osi_readl((unsigned char *)osi_core->base + + 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_writel(val, (unsigned char *)osi_core->base + + osi_writela(osi_core, val, (unsigned char *)osi_core->base + EQOS_MAC_RQC1R); - eqos_enable_fpe_interrupts(osi_core->base); + eqos_enable_fpe_interrupts(osi_core); } /* CBS setting for TC should be by user application/IOCTL as @@ -1959,7 +1967,8 @@ 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_readl((unsigned char *)osi_core->base + EQOS_MAC_FPE_CTS); + 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; @@ -1992,7 +2001,8 @@ static void eqos_handle_mac_fpe_intrs(struct osi_core_priv_data *osi_core) val &= ~EQOS_MAC_FPE_CTS_EFPE; } - osi_writel(val, (unsigned char *)osi_core->base + EQOS_MAC_FPE_CTS); + osi_writela(osi_core, val, + (unsigned char *)osi_core->base + EQOS_MAC_FPE_CTS); } /** @@ -2046,7 +2056,8 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, eqos_handle_mac_fpe_intrs(osi_core); mac_isr &= ~EQOS_MAC_IMR_FPEIS; } - osi_writel(mac_isr, (nveu8_t *)osi_core->base + EQOS_MAC_ISR); + 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); @@ -2090,7 +2101,8 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, eqos_handle_mac_fpe_intrs(osi_core); mac_isr &= ~EQOS_MAC_IMR_FPEIS; } - osi_writel(mac_isr, (unsigned char *)osi_core->base + EQOS_MAC_ISR); + osi_writela(osi_core, mac_isr, + (unsigned char *)osi_core->base + EQOS_MAC_ISR); } /** @@ -2173,7 +2185,8 @@ static void eqos_handle_mtl_intrs(struct osi_core_priv_data *osi_core) unsigned int i = 0; unsigned long stat_val = 0; - val = osi_readl((unsigned char *)osi_core->base + EQOS_MTL_EST_STATUS); + 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); @@ -2197,7 +2210,7 @@ static void eqos_handle_mtl_intrs(struct osi_core_priv_data *osi_core) 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_readl((nveu8_t *)osi_core->base + + 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; @@ -2209,7 +2222,7 @@ static void eqos_handle_mtl_intrs(struct osi_core_priv_data *osi_core) } } sch_err &= 0xFFU; /* only 8 TC allowed so clearing all */ - osi_writel(sch_err, + osi_writela(osi_core, sch_err, (nveu8_t *)osi_core->base + EQOS_MTL_EST_SCH_ERR); } @@ -2219,7 +2232,7 @@ static void eqos_handle_mtl_intrs(struct osi_core_priv_data *osi_core) 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_readl((nveu8_t *)osi_core->base + + 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; @@ -2231,7 +2244,7 @@ static void eqos_handle_mtl_intrs(struct osi_core_priv_data *osi_core) } } frm_err &= 0xFFU; /* 8 TC allowed so clearing all */ - osi_writel(frm_err, (nveu8_t *)osi_core->base + + osi_writela(osi_core, frm_err, (nveu8_t *)osi_core->base + EQOS_MTL_EST_FRMS_ERR); } @@ -2253,7 +2266,8 @@ static void eqos_handle_mtl_intrs(struct osi_core_priv_data *osi_core) osi_core->est_ready = OSI_DISABLE; } /* clear EST status register as interrupt is handled */ - osi_writel(val, (nveu8_t *)osi_core->base + EQOS_MTL_EST_STATUS); + osi_writela(osi_core, val, + (nveu8_t *)osi_core->base + EQOS_MTL_EST_STATUS); } /** @@ -2326,22 +2340,25 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *const osi_core) eqos_handle_mac_intrs(osi_core, dma_isr); /* Handle MTL inerrupts */ - mtl_isr = osi_readl((unsigned char *)base + EQOS_MTL_INTR_STATUS); + 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_writel(mtl_isr, (unsigned char *)base + + osi_writela(osi_core, mtl_isr, (unsigned char *)base + EQOS_MTL_INTR_STATUS); } /* Clear FRP Interrupt MTL_RXP_Interrupt_Control_Status */ - frp_isr = osi_readl((unsigned char *)base + EQOS_MTL_RXP_INTR_CS); + 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_writel(frp_isr, (unsigned char *)base + EQOS_MTL_RXP_INTR_CS); + osi_writela(osi_core, frp_isr, + (unsigned char *)base + EQOS_MTL_RXP_INTR_CS); } /** @@ -2711,7 +2728,7 @@ static int eqos_config_ptp_offload(struct osi_core_priv_data *osi_core, unsigned int port_id = 0x0U; /* Read MAC TCR */ - value = osi_readl((nveu8_t *)addr + EQOS_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 | @@ -2722,12 +2739,12 @@ static int eqos_config_ptp_offload(struct osi_core_priv_data *osi_core, /** Handle PTO disable */ if (pto_config->en_dis == OSI_DISABLE) { osi_core->ptp_config.ptp_filter = value; - osi_writel(ptc_value, addr + EQOS_MAC_PTO_CR); + 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_writel(OSI_NONE, addr + EQOS_MAC_PIDR0); - osi_writel(OSI_NONE, addr + EQOS_MAC_PIDR1); - osi_writel(OSI_NONE, addr + EQOS_MAC_PIDR2); + 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; } @@ -2776,14 +2793,14 @@ static int eqos_config_ptp_offload(struct osi_core_priv_data *osi_core, value |= OSI_MAC_TCR_TSEVENTENA; osi_core->ptp_config.ptp_filter = value; /** Write PTO_CR and TCR registers */ - osi_writel(ptc_value, addr + EQOS_MAC_PTO_CR); + 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_writel(port_id, addr + EQOS_MAC_PIDR0); - osi_writel(OSI_NONE, addr + EQOS_MAC_PIDR1); - osi_writel(OSI_NONE, addr + EQOS_MAC_PIDR2); + 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; } @@ -3926,7 +3943,7 @@ static int eqos_config_ptp_rxq(struct osi_core_priv_data *osi_core, } /* Read MAC_RxQ_Ctrl1 */ - value = osi_readl((nveu8_t *)base + EQOS_MAC_RQC1R); + 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. @@ -3951,7 +3968,7 @@ static int eqos_config_ptp_rxq(struct osi_core_priv_data *osi_core, value |= EQOS_MAC_RQC1R_OMCBCQ; } /* Write MAC_RxQ_Ctrl1 */ - osi_writel(value, base + EQOS_MAC_RQC1R); + osi_writela(osi_core, value, base + EQOS_MAC_RQC1R); return 0; } @@ -4055,17 +4072,18 @@ static int eqos_hw_est_write(struct osi_core_priv_data *osi_core, int retry = 1000; unsigned int val = 0x0; - osi_writel(data, (unsigned char *)base + EQOS_MTL_EST_DATA); + 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_writel(val, (unsigned char *)base + EQOS_MTL_EST_GCL_CONTROL); + 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_readl((unsigned char *)base + + val = osi_readla(osi_core, (unsigned char *)base + EQOS_MTL_EST_GCL_CONTROL); if ((val & EQOS_MTL_EST_SRWO) == EQOS_MTL_EST_SRWO) { continue; @@ -4187,9 +4205,11 @@ static int eqos_hw_config_est(struct osi_core_priv_data *osi_core, } if (est->en_dis == OSI_DISABLE) { - val = osi_readl((nveu8_t *)base + EQOS_MTL_EST_CONTROL); + val = osi_readla(osi_core, + (nveu8_t *)base + EQOS_MTL_EST_CONTROL); val &= ~EQOS_MTL_EST_CONTROL_EEST; - osi_writel(val, (nveu8_t *)base + EQOS_MTL_EST_CONTROL); + osi_writela(osi_core, val, + (nveu8_t *)base + EQOS_MTL_EST_CONTROL); return 0; } @@ -4211,12 +4231,14 @@ static int eqos_hw_config_est(struct osi_core_priv_data *osi_core, return ret; } - ret = eqos_hw_est_write(osi_core, EQOS_MTL_EST_TER, est->ter, OSI_DISABLE); + ret = eqos_hw_est_write(osi_core, EQOS_MTL_EST_TER, est->ter, + OSI_DISABLE); if (ret < 0) { return ret; } - ret = eqos_hw_est_write(osi_core, EQOS_MTL_EST_LLR, est->llr, OSI_DISABLE); + ret = eqos_hw_est_write(osi_core, EQOS_MTL_EST_LLR, est->llr, + OSI_DISABLE); if (ret < 0) { return ret; } @@ -4226,7 +4248,8 @@ static int eqos_hw_config_est(struct osi_core_priv_data *osi_core, 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); + ret = eqos_hw_est_write(osi_core, addr, est->gcl[i], + OSI_ENABLE); if (ret < 0) { return ret; } @@ -4250,11 +4273,12 @@ static int eqos_hw_config_est(struct osi_core_priv_data *osi_core, return ret; } - val = osi_readl((unsigned char *)base + EQOS_MTL_EST_CONTROL); + 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; - osi_writel(val, (nveu8_t *)base + EQOS_MTL_EST_CONTROL); + osi_writela(osi_core, val, (nveu8_t *)base + EQOS_MTL_EST_CONTROL); return ret; } @@ -4292,18 +4316,19 @@ static int eqos_hw_config_fpe(struct osi_core_priv_data *osi_core, osi_core->fpe_ready = OSI_DISABLE; - val = osi_readl((unsigned char *)osi_core->base + EQOS_MTL_FPE_CTS); + val = osi_readla(osi_core, + (unsigned char *)osi_core->base + EQOS_MTL_FPE_CTS); if (((fpe->tx_queue_preemption_enable << EQOS_MTL_FPE_CTS_PEC_SHIFT) & EQOS_MTL_FPE_CTS_PEC) == OSI_DISABLE) { val &= ~EQOS_MAC_FPE_CTS_EFPE; - osi_writel(val, (unsigned char *)osi_core->base + + osi_writela(osi_core, val, (unsigned char *)osi_core->base + EQOS_MAC_FPE_CTS); - val = osi_readl((unsigned char *)osi_core->base + + val = osi_readla(osi_core, (unsigned char *)osi_core->base + EQOS_MAC_RQC1R); val &= ~EQOS_MAC_RQC1R_FPRQ; - osi_writel(val, (unsigned char *)osi_core->base + + osi_writela(osi_core, val, (unsigned char *)osi_core->base + EQOS_MAC_RQC1R); return 0; @@ -4327,7 +4352,8 @@ static int eqos_hw_config_fpe(struct osi_core_priv_data *osi_core, } } } - osi_writel(val, (unsigned char *)osi_core->base + EQOS_MTL_FPE_CTS); + osi_writela(osi_core, val, + (unsigned char *)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) { @@ -4336,7 +4362,8 @@ static int eqos_hw_config_fpe(struct osi_core_priv_data *osi_core, return -1; } - val = osi_readl((unsigned char *)osi_core->base + EQOS_MAC_RQC1R); + 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; @@ -4344,18 +4371,23 @@ static int eqos_hw_config_fpe(struct osi_core_priv_data *osi_core, val |= temp; /* update RQ in OSI CORE struct */ osi_core->residual_queue = fpe->rq; - osi_writel(val, (unsigned char *)osi_core->base + EQOS_MAC_RQC1R); + osi_writela(osi_core, val, + (unsigned char *)osi_core->base + EQOS_MAC_RQC1R); /* initiate SVER for SMD-V and SMD-R */ - val = osi_readl((unsigned char *)osi_core->base + EQOS_MTL_FPE_CTS); + val = osi_readla(osi_core, + (unsigned char *)osi_core->base + EQOS_MTL_FPE_CTS); val |= EQOS_MAC_FPE_CTS_SVER; - osi_writel(val, (unsigned char *)osi_core->base + EQOS_MAC_FPE_CTS); + osi_writela(osi_core, val, + (unsigned char *)osi_core->base + EQOS_MAC_FPE_CTS); - val = osi_readl((unsigned char *)osi_core->base + EQOS_MTL_FPE_ADV); + 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_writel(val, (unsigned char *)osi_core->base + EQOS_MTL_FPE_ADV); + osi_writela(osi_core, val, + (unsigned char *)osi_core->base + EQOS_MTL_FPE_ADV); return 0; } diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index 118d66d..468a136 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -23,10 +23,12 @@ #include <osi_common.h> #include <osi_core.h> #include <ivc_core.h> +#include <osi_macsec.h> #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 @@ -1447,6 +1449,182 @@ static nve32_t ivc_config_mac_loopback( } #endif +/** + * @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) +{ + + return 0; +} + +/** + * @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) +{ + return 0; +} + +/** + * @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) +{ + +} + +/** + * @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. + * + * @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) +{ + return 0; +} + +/** + * @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 *osi_core, + unsigned int enable) +{ + return 0; +} + +/** + * @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) +{ + return 0; +} + +/** + * @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 int ivc_macsec_kt_config(struct osi_core_priv_data *const osi_core, + struct osi_macsec_kt_config *const kt_config) +{ + return 0; +} + +/** + * @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 int ivc_macsec_lut_config(struct osi_core_priv_data *const osi_core, + struct osi_macsec_lut_config *const lut_config) +{ + return 0; +} + +/** + * @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(struct osi_core_priv_data *const osi_core) +{ + +} + +/** + * @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(struct osi_core_priv_data *const osi_core) +{ +} + +/** + * @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) +{ + return 0; +} + +/** + * @brief ivc_macsec_init -Initialize. + * + * @param[in] osi_core: OSI Core private data structure. + * + * @retval 0 on Success + * @retval -1 on Failure + */ +static int ivc_macsec_init(struct osi_core_priv_data *const osi_core) +{ + return 0; +} + /** * @brief ivc_init_core_ops - Initialize IVC core operations. * @@ -1508,6 +1686,33 @@ void ivc_init_core_ops(struct core_ops *ops) #endif /* !OSI_STRIPPED_LIB */ }; +/** + * @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 macsec_core_ops *ops = (struct 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; + ops->kt_config = ivc_macsec_kt_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; +} + /** * @brief ivc_get_core_safety_config - EQOS MAC safety configuration */ diff --git a/osi/core/macsec.c b/osi/core/macsec.c index b6fa908..d2e8c23 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -40,7 +40,7 @@ static int poll_for_dbg_buf_update(struct osi_core_priv_data *const osi_core) unsigned int dbg_buf_config; while (retry > 0) { - dbg_buf_config = osi_readl( + dbg_buf_config = osi_readla(osi_core, (unsigned char *)osi_core->macsec_base + DEBUG_BUF_CONFIG_0); if ((dbg_buf_config & DEBUG_BUF_CONFIG_0_UPDATE) == 0U) { @@ -80,7 +80,7 @@ static inline void write_dbg_buf_data( for (i = 0; i < DBG_BUF_LEN; i++) { /* pr_err("%s: dbg_buf_data[%d]: 0x%x\n", __func__, i, dbg_buf[i]); */ - osi_writel(dbg_buf[i], base + DEBUG_BUF_DATA_0(i)); + osi_writela(osi_core, dbg_buf[i], base + DEBUG_BUF_DATA_0(i)); } } @@ -102,7 +102,7 @@ static inline void read_dbg_buf_data( /* Read debug buffer from HW */ for (i = 0; i < DBG_BUF_LEN; i++) { - dbg_buf[i] = osi_readl(base + DEBUG_BUF_DATA_0(i)); + dbg_buf[i] = osi_readla(osi_core, base + DEBUG_BUF_DATA_0(i)); /* pr_err("%s: dbg_buf_data[%d]: 0x%x\n", __func__, i, dbg_buf[i]); */ } @@ -127,7 +127,8 @@ static void tx_dbg_trigger_evts( if (dbg_buf_config->rw == DBG_TBL_WRITE) { flags = dbg_buf_config->flags; - tx_trigger_evts = osi_readl(base + TX_DEBUG_TRIGGER_EN_0); + tx_trigger_evts = osi_readla(osi_core, + base + TX_DEBUG_TRIGGER_EN_0); if (flags & TX_DBG_LKUP_MISS_EVT) { tx_trigger_evts |= TX_DBG_LKUP_MISS; } else { @@ -166,17 +167,21 @@ static void tx_dbg_trigger_evts( pr_err("%s: tx_dbg_trigger_evts 0x%x", __func__, tx_trigger_evts); - osi_writel(tx_trigger_evts, base + TX_DEBUG_TRIGGER_EN_0); + osi_writela(osi_core, tx_trigger_evts, + base + TX_DEBUG_TRIGGER_EN_0); if (tx_trigger_evts != OSI_NONE) { /** Start the tx debug buffer capture */ - debug_ctrl_reg = osi_readl(base + TX_DEBUG_CONTROL_0); + debug_ctrl_reg = osi_readla(osi_core, + base + TX_DEBUG_CONTROL_0); debug_ctrl_reg |= TX_DEBUG_CONTROL_0_START_CAP; pr_err("%s: debug_ctrl_reg 0x%x", __func__, debug_ctrl_reg); - osi_writel(debug_ctrl_reg, base + TX_DEBUG_CONTROL_0); + osi_writela(osi_core, debug_ctrl_reg, + base + TX_DEBUG_CONTROL_0); } } else { - tx_trigger_evts = osi_readl(base + TX_DEBUG_TRIGGER_EN_0); + tx_trigger_evts = osi_readla(osi_core, + base + TX_DEBUG_TRIGGER_EN_0); pr_err("%s: tx_dbg_trigger_evts 0x%x", __func__, tx_trigger_evts); if (tx_trigger_evts & TX_DBG_LKUP_MISS) { @@ -220,7 +225,8 @@ static void rx_dbg_trigger_evts( if (dbg_buf_config->rw == DBG_TBL_WRITE) { flags = dbg_buf_config->flags; - rx_trigger_evts = osi_readl(base + RX_DEBUG_TRIGGER_EN_0); + rx_trigger_evts = osi_readla(osi_core, + base + RX_DEBUG_TRIGGER_EN_0); if (flags & RX_DBG_LKUP_MISS_EVT) { rx_trigger_evts |= RX_DBG_LKUP_MISS; } else { @@ -258,17 +264,21 @@ static void rx_dbg_trigger_evts( } pr_err("%s: rx_dbg_trigger_evts 0x%x", __func__, rx_trigger_evts); - osi_writel(rx_trigger_evts, base + RX_DEBUG_TRIGGER_EN_0); + osi_writela(osi_core, rx_trigger_evts, + base + RX_DEBUG_TRIGGER_EN_0); if (rx_trigger_evts != OSI_NONE) { /** Start the tx debug buffer capture */ - debug_ctrl_reg = osi_readl(base + RX_DEBUG_CONTROL_0); + debug_ctrl_reg = osi_readla(osi_core, + base + RX_DEBUG_CONTROL_0); debug_ctrl_reg |= RX_DEBUG_CONTROL_0_START_CAP; pr_err("%s: debug_ctrl_reg 0x%x", __func__, debug_ctrl_reg); - osi_writel(debug_ctrl_reg, base + RX_DEBUG_CONTROL_0); + osi_writela(osi_core, debug_ctrl_reg, + base + RX_DEBUG_CONTROL_0); } } else { - rx_trigger_evts = osi_readl(base + RX_DEBUG_TRIGGER_EN_0); + rx_trigger_evts = osi_readla(osi_core, + base + RX_DEBUG_TRIGGER_EN_0); pr_err("%s: rx_dbg_trigger_evts 0x%x", __func__, rx_trigger_evts); if (rx_trigger_evts & RX_DBG_LKUP_MISS) { @@ -336,7 +346,7 @@ static int macsec_dbg_buf_config(struct osi_core_priv_data *const osi_core, dbg_buf_config->ctlr_sel, dbg_buf_config->rw, dbg_buf_config->index); */ - dbg_config_reg = osi_readl(base + DEBUG_BUF_CONFIG_0); + dbg_config_reg = osi_readla(osi_core, base + DEBUG_BUF_CONFIG_0); if (dbg_buf_config->ctlr_sel) { dbg_config_reg |= DEBUG_BUF_CONFIG_0_CTLR_SEL; @@ -355,7 +365,7 @@ static int macsec_dbg_buf_config(struct osi_core_priv_data *const osi_core, dbg_config_reg &= ~DEBUG_BUF_CONFIG_0_IDX_MASK; dbg_config_reg |= dbg_buf_config->index ; dbg_config_reg |= DEBUG_BUF_CONFIG_0_UPDATE; - osi_writel(dbg_config_reg, base + DEBUG_BUF_CONFIG_0); + osi_writela(osi_core, dbg_config_reg, base + DEBUG_BUF_CONFIG_0); ret = poll_for_dbg_buf_update(osi_core); if (ret < 0) { return ret; @@ -431,9 +441,11 @@ static inline unsigned long long update_macsec_mmc_val( unsigned long long temp; unsigned int value_lo, value_hi; - value_lo = osi_readl((unsigned char *)osi_core->macsec_base + offset); - value_hi = osi_readl((unsigned char *)osi_core->macsec_base + - (offset + 4U)); + value_lo = osi_readla(osi_core, + (unsigned char *)osi_core->macsec_base + offset); + value_hi = osi_readla(osi_core, + (unsigned char *)osi_core->macsec_base + + (offset + 4U)); temp = (value_lo | value_hi << 31); return temp; @@ -502,7 +514,7 @@ int macsec_enable(struct osi_core_priv_data *osi_core, unsigned int enable) unsigned int val; unsigned char *base = (unsigned char *)osi_core->macsec_base; - val = osi_readl(base + MACSEC_CONTROL0); + val = osi_readla(osi_core, base + MACSEC_CONTROL0); pr_err("Read MACSEC_CONTROL0: 0x%x\n", val); if ((enable & OSI_MACSEC_TX_EN) == OSI_MACSEC_TX_EN) { @@ -522,7 +534,7 @@ int macsec_enable(struct osi_core_priv_data *osi_core, unsigned int enable) } pr_err("Write MACSEC_CONTROL0: 0x%x\n", val); - osi_writel(val, base + MACSEC_CONTROL0); + osi_writela(osi_core, val, base + MACSEC_CONTROL0); return 0; } @@ -555,7 +567,8 @@ static inline int poll_for_kt_update(struct osi_core_priv_data *osi_core) count++; - kt_config = osi_readl((unsigned char *)osi_core->tz_base + + kt_config = osi_readla(osi_core, + (unsigned char *)osi_core->tz_base + GCM_KEYTABLE_CONFIG); if ((kt_config & KT_CONFIG_UPDATE) == 0U) { /* exit loop */ @@ -576,8 +589,9 @@ static int kt_key_read(struct osi_core_priv_data *const osi_core, int i, j; for (i = 0; i < MACSEC_KT_DATA_REG_CNT; i++) { - kt_key[i] = osi_readl((unsigned char *)osi_core->tz_base + - GCM_KEYTABLE_DATA(i)); + kt_key[i] = osi_readla(osi_core, + (unsigned char *)osi_core->tz_base + + GCM_KEYTABLE_DATA(i)); } if ((kt_key[MACSEC_KT_DATA_REG_CNT - 1] & KT_ENTRY_VALID) == @@ -633,8 +647,9 @@ static int kt_key_write(struct osi_core_priv_data *const osi_core, for (i = 0; i < MACSEC_KT_DATA_REG_CNT; i++) { /* pr_err("%s: kt_key[%d]: 0x%x\n", __func__, i, kt_key[i]); */ - osi_writel(kt_key[i], (unsigned char *)osi_core->tz_base + - GCM_KEYTABLE_DATA(i)); + osi_writela(osi_core, kt_key[i], + (unsigned char *)osi_core->tz_base + + GCM_KEYTABLE_DATA(i)); } return 0; @@ -666,7 +681,7 @@ static int macsec_kt_config(struct osi_core_priv_data *const osi_core, kt_config->table_config.ctlr_sel, kt_config->table_config.rw, kt_config->table_config.index, kt_config->flags); */ - kt_config_reg = osi_readl(base + GCM_KEYTABLE_CONFIG); + kt_config_reg = osi_readla(osi_core, base + GCM_KEYTABLE_CONFIG); if (kt_config->table_config.ctlr_sel) { kt_config_reg |= KT_CONFIG_CTLR_SEL; } else { @@ -688,7 +703,7 @@ static int macsec_kt_config(struct osi_core_priv_data *const osi_core, kt_config_reg |= (kt_config->table_config.index); kt_config_reg |= KT_CONFIG_UPDATE; - osi_writel(kt_config_reg, base + GCM_KEYTABLE_CONFIG); + osi_writela(osi_core, kt_config_reg, base + GCM_KEYTABLE_CONFIG); /* Wait for this KT update to finish */ ret = poll_for_kt_update(osi_core); @@ -733,8 +748,9 @@ static inline int poll_for_lut_update(struct osi_core_priv_data *osi_core) count++; - lut_config = osi_readl((unsigned char *)osi_core->macsec_base + - MACSEC_LUT_CONFIG); + lut_config = osi_readla(osi_core, + (unsigned char *)osi_core->macsec_base + + MACSEC_LUT_CONFIG); if ((lut_config & LUT_CONFIG_UPDATE) == 0U) { /* exit loop */ cond = 0; @@ -755,7 +771,7 @@ static inline void read_lut_data(struct osi_core_priv_data *const osi_core, /* Commit the LUT entry to HW */ for (i = 0; i < MACSEC_LUT_DATA_REG_CNT; i++) { - lut_data[i] = osi_readl(base + MACSEC_LUT_DATA(i)); + lut_data[i] = osi_readla(osi_core, base + MACSEC_LUT_DATA(i)); //pr_err("%s: lut_data[%d]: 0x%x\n", __func__, i, lut_data[i]); } } @@ -938,7 +954,7 @@ static int byp_lut_read(struct osi_core_priv_data *const osi_core, pr_err("Unknown controller select\n"); return -1; } - val = osi_readl(paddr); + val = osi_readla(osi_core, paddr); if (val & (1U << index)) { flags |= LUT_FLAGS_ENTRY_VALID; } @@ -993,7 +1009,7 @@ static int sci_lut_read(struct osi_core_priv_data *const osi_core, LUT_FLAGS_DVLAN_OUTER_INNER_TAG_SEL; } - val = osi_readl(addr+TX_SCI_LUT_VALID); + val = osi_readla(osi_core, addr+TX_SCI_LUT_VALID); if (val & (1U << index)) { lut_config->flags |= LUT_FLAGS_ENTRY_VALID; } @@ -1018,7 +1034,7 @@ static int sci_lut_read(struct osi_core_priv_data *const osi_core, } } - val = osi_readl(addr+RX_SCI_LUT_VALID); + val = osi_readla(osi_core, addr+RX_SCI_LUT_VALID); if (val & (1U << index)) { lut_config->flags |= LUT_FLAGS_ENTRY_VALID; } @@ -1164,7 +1180,7 @@ static inline void commit_lut_data(struct osi_core_priv_data *const osi_core, /* Commit the LUT entry to HW */ for (i = 0; i < MACSEC_LUT_DATA_REG_CNT; i++) { //pr_err("%s: lut_data[%d]: 0x%x\n", __func__, i, lut_data[i]); - osi_writel(lut_data[i], base + MACSEC_LUT_DATA(i)); + osi_writela(osi_core, lut_data[i], base + MACSEC_LUT_DATA(i)); } } @@ -1589,13 +1605,13 @@ static int sci_lut_config(struct osi_core_priv_data *const osi_core, if ((lut_config->flags & LUT_FLAGS_ENTRY_VALID) == LUT_FLAGS_ENTRY_VALID) { - val = osi_readl(addr+TX_SCI_LUT_VALID); + val = osi_readla(osi_core, addr+TX_SCI_LUT_VALID); val |= (1 << index); - osi_writel(val, addr+TX_SCI_LUT_VALID); + osi_writela(osi_core, val, addr+TX_SCI_LUT_VALID); } else { - val = osi_readl(addr+TX_SCI_LUT_VALID); + val = osi_readla(osi_core, addr+TX_SCI_LUT_VALID); val &= ~(1 << index); - osi_writel(val, addr+TX_SCI_LUT_VALID); + osi_writela(osi_core, val, addr+TX_SCI_LUT_VALID); } break; @@ -1608,13 +1624,13 @@ static int sci_lut_config(struct osi_core_priv_data *const osi_core, if ((lut_config->flags & LUT_FLAGS_ENTRY_VALID) == LUT_FLAGS_ENTRY_VALID) { - val = osi_readl(addr+RX_SCI_LUT_VALID); + val = osi_readla(osi_core, addr+RX_SCI_LUT_VALID); val |= (1 << index); - osi_writel(val, addr+RX_SCI_LUT_VALID); + osi_writela(osi_core, val, addr+RX_SCI_LUT_VALID); } else { - val = osi_readl(addr+RX_SCI_LUT_VALID); + val = osi_readla(osi_core, addr+RX_SCI_LUT_VALID); val &= ~(1 << index); - osi_writel(val, addr+RX_SCI_LUT_VALID); + osi_writela(osi_core, val, addr+RX_SCI_LUT_VALID); } break; @@ -1660,26 +1676,26 @@ static int byp_lut_config(struct osi_core_priv_data *const osi_core, case CTLR_SEL_TX: if ((flags & LUT_FLAGS_ENTRY_VALID) == LUT_FLAGS_ENTRY_VALID) { - val = osi_readl(addr+TX_BYP_LUT_VALID); + val = osi_readla(osi_core, addr+TX_BYP_LUT_VALID); val |= (1 << index); - osi_writel(val, addr+TX_BYP_LUT_VALID); + osi_writela(osi_core, val, addr+TX_BYP_LUT_VALID); } else { - val = osi_readl(addr+TX_BYP_LUT_VALID); + val = osi_readla(osi_core, addr+TX_BYP_LUT_VALID); val &= ~(1 << index); - osi_writel(val, addr+TX_BYP_LUT_VALID); + osi_writela(osi_core, val, addr+TX_BYP_LUT_VALID); } break; case CTLR_SEL_RX: if ((flags & LUT_FLAGS_ENTRY_VALID) == LUT_FLAGS_ENTRY_VALID) { - val = osi_readl(addr+RX_BYP_LUT_VALID); + val = osi_readla(osi_core, addr+RX_BYP_LUT_VALID); val |= (1 << index); - osi_writel(val, addr+RX_BYP_LUT_VALID); + osi_writela(osi_core, val, addr+RX_BYP_LUT_VALID); } else { - val = osi_readl(addr+RX_BYP_LUT_VALID); + val = osi_readla(osi_core, addr+RX_BYP_LUT_VALID); val &= ~(1 << index); - osi_writel(val, addr+RX_BYP_LUT_VALID); + osi_writela(osi_core, val, addr+RX_BYP_LUT_VALID); } break; @@ -1766,7 +1782,7 @@ static int macsec_lut_config(struct osi_core_priv_data *const osi_core, lut_config->table_config.rw, lut_config->table_config.index, lut_config->flags); */ - lut_config_reg = osi_readl(base + MACSEC_LUT_CONFIG); + lut_config_reg = osi_readla(osi_core, base + MACSEC_LUT_CONFIG); if (lut_config->table_config.ctlr_sel) { lut_config_reg |= LUT_CONFIG_CTLR_SEL; } else { @@ -1791,7 +1807,7 @@ static int macsec_lut_config(struct osi_core_priv_data *const osi_core, lut_config_reg |= (lut_config->table_config.index); lut_config_reg |= LUT_CONFIG_UPDATE; - osi_writel(lut_config_reg, base + MACSEC_LUT_CONFIG); + 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); @@ -1819,11 +1835,11 @@ static inline void handle_rx_sc_invalid_key( /** check which SC/AN had triggered and clear */ /* rx_sc0_7 */ - clear = osi_readl(addr + RX_SC_KEY_INVALID_STS0_0); - osi_writel(clear, addr + RX_SC_KEY_INVALID_STS0_0); + clear = osi_readla(osi_core, addr + RX_SC_KEY_INVALID_STS0_0); + osi_writela(osi_core, clear, addr + RX_SC_KEY_INVALID_STS0_0); /* rx_sc8_15 */ - clear = osi_readl(addr + RX_SC_KEY_INVALID_STS1_0); - osi_writel(clear, addr + RX_SC_KEY_INVALID_STS1_0); + clear = osi_readla(osi_core, addr + RX_SC_KEY_INVALID_STS1_0); + osi_writela(osi_core, clear, addr + RX_SC_KEY_INVALID_STS1_0); } static inline void handle_tx_sc_invalid_key( @@ -1836,11 +1852,11 @@ static inline void handle_tx_sc_invalid_key( /** check which SC/AN had triggered and clear */ /* tx_sc0_7 */ - clear = osi_readl(addr + TX_SC_KEY_INVALID_STS0_0); - osi_writel(clear, addr + TX_SC_KEY_INVALID_STS0_0); + clear = osi_readla(osi_core, addr + TX_SC_KEY_INVALID_STS0_0); + osi_writela(osi_core, clear, addr + TX_SC_KEY_INVALID_STS0_0); /* tx_sc8_15 */ - clear = osi_readl(addr + TX_SC_KEY_INVALID_STS1_0); - osi_writel(clear, addr + TX_SC_KEY_INVALID_STS1_0); + clear = osi_readla(osi_core, addr + TX_SC_KEY_INVALID_STS1_0); + osi_writela(osi_core, clear, addr + TX_SC_KEY_INVALID_STS1_0); } static inline void handle_safety_err_irq( @@ -1858,11 +1874,11 @@ static inline void handle_rx_sc_replay_err( /* pr_err("%s()\n", __func__); */ /* rx_sc0_7 */ - clear = osi_readl(addr + RX_SC_REPLAY_ERROR_STATUS0_0); - osi_writel(clear, addr + RX_SC_REPLAY_ERROR_STATUS0_0); + clear = osi_readla(osi_core, addr + RX_SC_REPLAY_ERROR_STATUS0_0); + osi_writela(osi_core, clear, addr + RX_SC_REPLAY_ERROR_STATUS0_0); /* rx_sc8_15 */ - clear = osi_readl(addr + RX_SC_REPLAY_ERROR_STATUS1_0); - osi_writel(clear, addr + RX_SC_REPLAY_ERROR_STATUS1_0); + clear = osi_readla(osi_core, addr + RX_SC_REPLAY_ERROR_STATUS1_0); + osi_writela(osi_core, clear, addr + RX_SC_REPLAY_ERROR_STATUS1_0); } static inline void handle_rx_pn_exhausted( @@ -1878,11 +1894,11 @@ static inline void handle_rx_pn_exhausted( /* check which SC/AN had triggered and clear */ /* rx_sc0_7 */ - clear = osi_readl(addr + RX_SC_PN_EXHAUSTED_STATUS0_0); - osi_writel(clear, addr + RX_SC_PN_EXHAUSTED_STATUS0_0); + clear = osi_readla(osi_core, addr + RX_SC_PN_EXHAUSTED_STATUS0_0); + osi_writela(osi_core, clear, addr + RX_SC_PN_EXHAUSTED_STATUS0_0); /* rx_sc8_15 */ - clear = osi_readl(addr + RX_SC_PN_EXHAUSTED_STATUS1_0); - osi_writel(clear, addr + RX_SC_PN_EXHAUSTED_STATUS1_0); + clear = osi_readla(osi_core, addr + RX_SC_PN_EXHAUSTED_STATUS1_0); + osi_writela(osi_core, clear, addr + RX_SC_PN_EXHAUSTED_STATUS1_0); } static inline void handle_tx_sc_err(struct osi_core_priv_data *const osi_core) @@ -1894,9 +1910,9 @@ static inline void handle_tx_sc_err(struct osi_core_priv_data *const osi_core) /* TODO: Do you need re-enable SC/AN? */ - clear = osi_readl(addr + TX_SC_ERROR_INTERRUPT_STATUS_0); + clear = osi_readla(osi_core, addr + TX_SC_ERROR_INTERRUPT_STATUS_0); - osi_writel(clear, addr + TX_SC_ERROR_INTERRUPT_STATUS_0); + osi_writela(osi_core, clear, addr + TX_SC_ERROR_INTERRUPT_STATUS_0); } @@ -1913,11 +1929,11 @@ static inline void handle_tx_pn_threshold( /* check which SC/AN had triggered and clear */ /* tx_sc0_7 */ - clear = osi_readl(addr + TX_SC_PN_THRESHOLD_STATUS0_0); - osi_writel(clear, addr + TX_SC_PN_THRESHOLD_STATUS0_0); + clear = osi_readla(osi_core, addr + TX_SC_PN_THRESHOLD_STATUS0_0); + osi_writela(osi_core, clear, addr + TX_SC_PN_THRESHOLD_STATUS0_0); /* tx_sc8_15 */ - clear = osi_readl(addr + TX_SC_PN_THRESHOLD_STATUS1_0); - osi_writel(clear, addr + TX_SC_PN_THRESHOLD_STATUS1_0); + clear = osi_readla(osi_core, addr + TX_SC_PN_THRESHOLD_STATUS1_0); + osi_writela(osi_core, clear, addr + TX_SC_PN_THRESHOLD_STATUS1_0); } static inline void handle_tx_pn_exhausted( @@ -1933,11 +1949,11 @@ static inline void handle_tx_pn_exhausted( /* check which SC/AN had triggered and clear */ /* tx_sc0_7 */ - clear = osi_readl(addr + TX_SC_PN_EXHAUSTED_STATUS0_0); - osi_writel(clear, addr + TX_SC_PN_EXHAUSTED_STATUS0_0); + clear = osi_readla(osi_core, addr + TX_SC_PN_EXHAUSTED_STATUS0_0); + osi_writela(osi_core, clear, addr + TX_SC_PN_EXHAUSTED_STATUS0_0); /* tx_sc8_15 */ - clear = osi_readl(addr + TX_SC_PN_EXHAUSTED_STATUS1_0); - osi_writel(clear, addr + TX_SC_PN_EXHAUSTED_STATUS1_0); + clear = osi_readla(osi_core, addr + TX_SC_PN_EXHAUSTED_STATUS1_0); + osi_writela(osi_core, clear, addr + TX_SC_PN_EXHAUSTED_STATUS1_0); } static inline void handle_dbg_evt_capture_done( @@ -1948,19 +1964,21 @@ static inline void handle_dbg_evt_capture_done( unsigned int trigger_evts = 0; if (ctrl_sel == CTLR_SEL_TX) { - trigger_evts = osi_readl(addr + TX_DEBUG_STATUS_0); + trigger_evts = osi_readla(osi_core, addr + TX_DEBUG_STATUS_0); pr_err("%s: TX_DEBUG_STATUS_0 0x%x", __func__, trigger_evts); - osi_writel(trigger_evts, addr + TX_DEBUG_STATUS_0); + osi_writela(osi_core, trigger_evts, addr + TX_DEBUG_STATUS_0); /* clear all trigger events */ trigger_evts = 0U; - osi_writel(trigger_evts, addr + TX_DEBUG_TRIGGER_EN_0); + osi_writela(osi_core, trigger_evts, + addr + TX_DEBUG_TRIGGER_EN_0); } else if (ctrl_sel == CTLR_SEL_RX) { - trigger_evts = osi_readl(addr + RX_DEBUG_STATUS_0); + trigger_evts = osi_readla(osi_core, addr + RX_DEBUG_STATUS_0); pr_err("%s: RX_DEBUG_STATUS_0 0x%x", __func__, trigger_evts); - osi_writel(trigger_evts, addr + RX_DEBUG_STATUS_0); + osi_writela(osi_core, trigger_evts, addr + RX_DEBUG_STATUS_0); /* clear all trigger events */ trigger_evts = 0U; - osi_writel(trigger_evts, addr + RX_DEBUG_TRIGGER_EN_0); + osi_writela(osi_core, trigger_evts, + addr + RX_DEBUG_TRIGGER_EN_0); } } @@ -1969,7 +1987,7 @@ static inline void handle_tx_irq(struct osi_core_priv_data *const osi_core) unsigned int tx_isr, clear = 0; unsigned char *addr = (unsigned char *)osi_core->macsec_base; - tx_isr = osi_readl(addr + TX_ISR); + tx_isr = osi_readla(osi_core, addr + TX_ISR); pr_err("%s(): tx_isr 0x%x\n", __func__, tx_isr); if ((tx_isr & TX_DBG_BUF_CAPTURE_DONE) == TX_DBG_BUF_CAPTURE_DONE) { handle_dbg_evt_capture_done(osi_core, CTLR_SEL_TX); @@ -2013,7 +2031,7 @@ static inline void handle_tx_irq(struct osi_core_priv_data *const osi_core) } if (clear) { pr_err("%s(): write tx_isr 0x%x\n", __func__, clear); - osi_writel(clear, addr + TX_ISR); + osi_writela(osi_core, clear, addr + TX_ISR); } } @@ -2022,7 +2040,7 @@ static inline void handle_rx_irq(struct osi_core_priv_data *const osi_core) unsigned int rx_isr, clear = 0; unsigned char *addr = (unsigned char *)osi_core->macsec_base; - rx_isr = osi_readl(addr + RX_ISR); + rx_isr = osi_readla(osi_core, addr + RX_ISR); pr_err("%s(): rx_isr 0x%x\n", __func__, rx_isr); if ((rx_isr & RX_DBG_BUF_CAPTURE_DONE) == RX_DBG_BUF_CAPTURE_DONE) { @@ -2065,7 +2083,7 @@ static inline void handle_rx_irq(struct osi_core_priv_data *const osi_core) } if (clear) { pr_err("%s(): write rx_isr 0x%x\n", __func__, clear); - osi_writel(clear, addr + RX_ISR); + osi_writela(osi_core, clear, addr + RX_ISR); } } @@ -2074,7 +2092,7 @@ static inline void handle_common_irq(struct osi_core_priv_data *const osi_core) unsigned int common_isr, clear = 0; unsigned char *addr = (unsigned char *)osi_core->macsec_base; - common_isr = osi_readl(addr + COMMON_ISR); + common_isr = osi_readla(osi_core, addr + COMMON_ISR); pr_err("%s(): common_isr 0x%x\n", __func__, common_isr); if ((common_isr & SECURE_REG_VIOL) == SECURE_REG_VIOL) { @@ -2104,7 +2122,7 @@ static inline void handle_common_irq(struct osi_core_priv_data *const osi_core) clear |= TX_LKUP_MISS; } if (clear) { - osi_writel(clear, addr + COMMON_ISR); + osi_writela(osi_core, clear, addr + COMMON_ISR); } } @@ -2113,7 +2131,7 @@ static void macsec_handle_ns_irq(struct osi_core_priv_data *const osi_core) unsigned int irq_common_sr, common_isr; unsigned char *addr = (unsigned char *)osi_core->macsec_base; - irq_common_sr = osi_readl(addr + INTERRUPT_COMMON_SR); + irq_common_sr = osi_readla(osi_core, addr + INTERRUPT_COMMON_SR); pr_err("%s(): common_sr 0x%x\n", __func__, irq_common_sr); if ((irq_common_sr & COMMON_SR_TX) == COMMON_SR_TX) { handle_tx_irq(osi_core); @@ -2127,7 +2145,7 @@ static void macsec_handle_ns_irq(struct osi_core_priv_data *const osi_core) handle_safety_err_irq(osi_core); } - common_isr = osi_readl(addr + COMMON_ISR); + common_isr = osi_readla(osi_core, addr + COMMON_ISR); if (common_isr != OSI_NONE) { handle_common_irq(osi_core); } @@ -2140,7 +2158,7 @@ static void macsec_handle_s_irq(struct osi_core_priv_data *const osi_core) pr_err("%s()\n", __func__); - common_isr = osi_readl(addr + COMMON_ISR); + common_isr = osi_readla(osi_core, addr + COMMON_ISR); if (common_isr != OSI_NONE) { handle_common_irq(osi_core); } @@ -2154,7 +2172,7 @@ static int macsec_loopback_config(struct osi_core_priv_data *const osi_core, unsigned char *base = (unsigned char *)osi_core->macsec_base; unsigned int val; - val = osi_readl(base + MACSEC_CONTROL1); + val = osi_readla(osi_core, base + MACSEC_CONTROL1); pr_err("Read MACSEC_CONTROL1: 0x%x\n", val); if (enable == OSI_ENABLE) { @@ -2166,7 +2184,7 @@ static int macsec_loopback_config(struct osi_core_priv_data *const osi_core, } pr_err("Write MACSEC_CONTROL1: 0x%x\n", val); - osi_writel(val, base + MACSEC_CONTROL1); + osi_writela(osi_core, val, base + MACSEC_CONTROL1); return 0; } @@ -2313,22 +2331,22 @@ static int macsec_init(struct osi_core_priv_data *const osi_core) int i, j; /* 1. Set MTU */ - val = osi_readl(addr + TX_MTU_LEN); + val = osi_readla(osi_core, addr + TX_MTU_LEN); pr_err("Read TX_MTU_LEN: 0x%x\n", val); val &= ~(MTU_LENGTH_MASK); val |= (mtu & MTU_LENGTH_MASK); pr_err("Write TX_MTU_LEN: 0x%x\n", val); - osi_writel(val, addr + TX_MTU_LEN); + osi_writela(osi_core, val, addr + TX_MTU_LEN); - val = osi_readl(addr + RX_MTU_LEN); + val = osi_readla(osi_core, addr + RX_MTU_LEN); pr_err("Read RX_MTU_LEN: 0x%x\n", val); val &= ~(MTU_LENGTH_MASK); val |= (mtu & MTU_LENGTH_MASK); pr_err("Write RX_MTU_LEN: 0x%x\n", val); - osi_writel(val, addr + RX_MTU_LEN); + osi_writela(osi_core, val, addr + RX_MTU_LEN); /* 2. Set essential MACsec control configuration */ - val = osi_readl(addr + MACSEC_CONTROL0); + val = osi_readla(osi_core, addr + MACSEC_CONTROL0); pr_err("Read MACSEC_CONTROL0: 0x%x\n", val); val |= (TX_LKUP_MISS_NS_INTR | RX_LKUP_MISS_NS_INTR | TX_LKUP_MISS_BYPASS | RX_LKUP_MISS_BYPASS); @@ -2336,40 +2354,40 @@ static int macsec_init(struct osi_core_priv_data *const osi_core) val |= VALIDATE_FRAMES_STRICT; val |= RX_REPLAY_PROT_EN; pr_err("Write MACSEC_CONTROL0: 0x%x\n", val); - osi_writel(val, addr + MACSEC_CONTROL0); + osi_writela(osi_core, val, addr + MACSEC_CONTROL0); - val = osi_readl(addr + MACSEC_CONTROL1); + val = osi_readla(osi_core, addr + MACSEC_CONTROL1); pr_err("Read MACSEC_CONTROL1: 0x%x\n", val); val |= (RX_MTU_CHECK_EN | TX_LUT_PRIO_BYP | TX_MTU_CHECK_EN); pr_err("Write MACSEC_CONTROL1: 0x%x\n", val); - osi_writel(val, addr + MACSEC_CONTROL1); + osi_writela(osi_core, val, addr + MACSEC_CONTROL1); /* set DVLAN tag ethertype */ /* val = DVLAN_TAG_ETHERTYPE; pr_err("Write MACSEC_TX_DVLAN_CONTROL_0: 0x%x\n", val); - osi_writel(val, addr + MACSEC_TX_DVLAN_CONTROL_0); + osi_writela(osi_core, val, addr + MACSEC_TX_DVLAN_CONTROL_0); pr_err("Write MACSEC_RX_DVLAN_CONTROL_0: 0x%x\n", val); - osi_writel(val, addr + MACSEC_RX_DVLAN_CONTROL_0); */ + osi_writela(osi_core, val, addr + MACSEC_RX_DVLAN_CONTROL_0); */ - val = osi_readl(addr + STATS_CONTROL_0); + val = osi_readla(osi_core, addr + STATS_CONTROL_0); pr_err("Read STATS_CONTROL_0: 0x%x\n", val); /* set STATS rollover bit */ val |= STATS_CONTROL0_CNT_RL_OVR_CPY; pr_err("Write STATS_CONTROL_0: 0x%x\n", val); - osi_writel(val, addr + STATS_CONTROL_0); + osi_writela(osi_core, val, addr + STATS_CONTROL_0); /* 3. Enable default interrupts needed */ - val = osi_readl(addr + TX_IMR); + val = osi_readla(osi_core, addr + TX_IMR); pr_err("Read TX_IMR: 0x%x\n", val); val |= (TX_DBG_BUF_CAPTURE_DONE_INT_EN | TX_MTU_CHECK_FAIL_INT_EN | TX_MAC_CRC_ERROR_INT_EN | TX_SC_AN_NOT_VALID_INT_EN | TX_AES_GCM_BUF_OVF_INT_EN | TX_PN_EXHAUSTED_INT_EN | TX_PN_THRSHLD_RCHD_INT_EN); pr_err("Write TX_IMR: 0x%x\n", val); - osi_writel(val, addr + TX_IMR); + osi_writela(osi_core, val, addr + TX_IMR); - val = osi_readl(addr + RX_IMR); + val = osi_readla(osi_core, addr + RX_IMR); pr_err("Read RX_IMR: 0x%x\n", val); val |= (RX_DBG_BUF_CAPTURE_DONE_INT_EN | @@ -2379,23 +2397,23 @@ static int macsec_init(struct osi_core_priv_data *const osi_core) RX_PN_EXHAUSTED_INT_EN ); pr_err("Write RX_IMR: 0x%x\n", val); - osi_writel(val, addr + RX_IMR); + osi_writela(osi_core, val, addr + RX_IMR); - val = osi_readl(addr + COMMON_IMR); + val = osi_readla(osi_core, addr + COMMON_IMR); pr_err("Read COMMON_IMR: 0x%x\n", val); val |= (SECURE_REG_VIOL_INT_EN | RX_UNINIT_KEY_SLOT_INT_EN | RX_LKUP_MISS_INT_EN | TX_UNINIT_KEY_SLOT_INT_EN | TX_LKUP_MISS_INT_EN); pr_err("Write COMMON_IMR: 0x%x\n", val); - osi_writel(val, addr + COMMON_IMR); + osi_writela(osi_core, val, addr + COMMON_IMR); /* 4. TODO - Route safety intr to LIC */ - val = osi_readl(addr + INTERRUPT_MASK1_0); + val = osi_readla(osi_core, addr + INTERRUPT_MASK1_0); pr_err("Read INTERRUPT_MASK1_0: 0x%x\n", val); val |= SFTY_ERR_UNCORR_INT_EN; pr_err("Write INTERRUPT_MASK1_0: 0x%x\n", val); - osi_writel(val, addr + INTERRUPT_MASK1_0); + osi_writela(osi_core, val, addr + INTERRUPT_MASK1_0); /* 5. Set AES mode * Default power on reset is AES-GCM128, leave it. diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index c51da08..8463697 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -64,7 +64,7 @@ static int mgbe_config_fw_err_pkts(struct osi_core_priv_data *osi_core, } /* Read MTL RXQ Operation_Mode Register */ - val = osi_readl((unsigned char *)osi_core->base + + 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 */ @@ -84,7 +84,7 @@ static int mgbe_config_fw_err_pkts(struct osi_core_priv_data *osi_core, /* Write to FEP bit of MTL RXQ Operation Mode Register to enable or * disable the forwarding of error packets to DMA or application. */ - osi_writel(val, (unsigned char *)osi_core->base + + osi_writela(osi_core, val, (unsigned char *)osi_core->base + MGBE_MTL_CHX_RX_OP_MODE(qinx)); return 0; @@ -114,7 +114,8 @@ static nve32_t mgbe_poll_for_swr(struct osi_core_priv_data *const osi_core) /* Performing software reset */ if (pre_si == OSI_ENABLE) { - osi_writel(OSI_ENABLE, (nveu8_t *)addr + MGBE_DMA_MODE); + osi_writela(osi_core, OSI_ENABLE, + (nveu8_t *)addr + MGBE_DMA_MODE); } /* Poll Until Poll Condition */ @@ -126,7 +127,7 @@ static nve32_t mgbe_poll_for_swr(struct osi_core_priv_data *const osi_core) count++; - dma_bmr = osi_readl((nveu8_t *)addr + MGBE_DMA_MODE); + dma_bmr = osi_readla(osi_core, (nveu8_t *)addr + MGBE_DMA_MODE); if ((dma_bmr & MGBE_DMA_MODE_SWR) == OSI_NONE) { cond = 0; } else { @@ -233,7 +234,8 @@ static int mgbe_poll_for_mac_acrtl(struct osi_core_priv_data *osi_core) /* Poll Until MAC_Indir_Access_Ctrl OB is clear */ while (count < MGBE_MAC_INDIR_AC_OB_RETRY) { - mac_indir_addr_ctrl = osi_readl((nveu8_t *)osi_core->base + + 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 */ @@ -272,10 +274,10 @@ static int mgbe_mac_indir_addr_write(struct osi_core_priv_data *osi_core, nveu32_t addr = 0; /* Write MAC_Indir_Access_Data register value */ - osi_writel(value, (nveu8_t *)base + MGBE_MAC_INDIR_DATA); + osi_writela(osi_core, value, (nveu8_t *)base + MGBE_MAC_INDIR_DATA); /* Program MAC_Indir_Access_Ctrl */ - addr = osi_readl((nveu8_t *)base + MGBE_MAC_INDIR_AC); + addr = osi_readla(osi_core, (nveu8_t *)base + MGBE_MAC_INDIR_AC); /* update Mode Select */ addr &= ~(MGBE_MAC_INDIR_AC_MSEL); @@ -294,7 +296,7 @@ static int mgbe_mac_indir_addr_write(struct osi_core_priv_data *osi_core, addr |= MGBE_MAC_INDIR_AC_OB; /* Write MGBE_MAC_L3L4_ADDR_CTR */ - osi_writel(addr, (nveu8_t *)base + MGBE_MAC_INDIR_AC); + 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) { @@ -330,7 +332,7 @@ static int mgbe_mac_indir_addr_read(struct osi_core_priv_data *osi_core, nveu32_t addr = 0; /* Program MAC_Indir_Access_Ctrl */ - addr = osi_readl((nveu8_t *)base + MGBE_MAC_INDIR_AC); + addr = osi_readla(osi_core, (nveu8_t *)base + MGBE_MAC_INDIR_AC); /* update Mode Select */ addr &= ~(MGBE_MAC_INDIR_AC_MSEL); @@ -349,7 +351,7 @@ static int mgbe_mac_indir_addr_read(struct osi_core_priv_data *osi_core, addr |= MGBE_MAC_INDIR_AC_OB; /* Write MGBE_MAC_L3L4_ADDR_CTR */ - osi_writel(addr, (nveu8_t *)base + MGBE_MAC_INDIR_AC); + 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) { @@ -359,7 +361,7 @@ static int mgbe_mac_indir_addr_read(struct osi_core_priv_data *osi_core, } /* Read MAC_Indir_Access_Data register value */ - *value = osi_readl((nveu8_t *)base + MGBE_MAC_INDIR_DATA); + *value = osi_readla(osi_core, (nveu8_t *)base + MGBE_MAC_INDIR_DATA); return 0; } @@ -370,24 +372,26 @@ static int mgbe_mac_indir_addr_read(struct osi_core_priv_data *osi_core, * Algorithm: This sequence is used to select perfect/inverse matching * for L2 DA * - * @param[in] base: Base address from OSI core private data structure. + * @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( - void *base, + struct osi_core_priv_data *osi_core, unsigned int perfect_inverse_match) { unsigned int value = 0U; - value = osi_readl((unsigned char *)base + MGBE_MAC_PFR); + 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_writel(value, (unsigned char *)base + MGBE_MAC_PFR); + osi_writela(osi_core, value, + (unsigned char *)osi_core->base + MGBE_MAC_PFR); } /** @@ -410,7 +414,8 @@ static int mgbe_config_mac_pkt_filter_reg(struct osi_core_priv_data *osi_core, unsigned int value = 0U; int ret = 0; - value = osi_readl((unsigned char *)osi_core->base + MGBE_MAC_PFR); + 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 | @@ -447,15 +452,16 @@ static int mgbe_config_mac_pkt_filter_reg(struct osi_core_priv_data *osi_core, value &= ~MGBE_MAC_PFR_HPF; } - osi_writel(value, (unsigned char *)osi_core->base + MGBE_MAC_PFR); + 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->base, + 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->base, + mgbe_config_l2_da_perfect_inverse_match(osi_core, OSI_PFT_MATCH); } @@ -580,8 +586,9 @@ static int mgbe_update_mac_addr_low_high_reg( /* High address clean should happen for filter index >= 0 */ if (addr == OSI_NULL) { - osi_writel(OSI_DISABLE, (unsigned char *)osi_core->base + - MGBE_MAC_ADDRH((idx))); + osi_writela(osi_core, OSI_DISABLE, + (unsigned char *)osi_core->base + + MGBE_MAC_ADDRH((idx))); return 0; } @@ -602,13 +609,13 @@ static int mgbe_update_mac_addr_low_high_reg( MGBE_MAC_ADDRH_SA); } - osi_writel(((unsigned int)addr[4] | + 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_writel(((unsigned int)addr[0] | + osi_writela(osi_core, ((unsigned int)addr[0] | ((unsigned int)addr[1] << 8) | ((unsigned int)addr[2] << 16) | ((unsigned int)addr[3] << 24)), @@ -657,8 +664,9 @@ static int mgbe_poll_for_l3l4crtl(struct osi_core_priv_data *osi_core) count++; - l3l4_addr_ctrl = osi_readl((unsigned char *)osi_core->base + - MGBE_MAC_L3L4_ADDR_CTR); + 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; @@ -695,10 +703,12 @@ static int mgbe_l3l4_filter_write(struct osi_core_priv_data *osi_core, unsigned int addr = 0; /* Write MAC_L3_L4_Data register value */ - osi_writel(value, (unsigned char *)base + MGBE_MAC_L3L4_DATA); + osi_writela(osi_core, value, + (unsigned char *)base + MGBE_MAC_L3L4_DATA); /* Program MAC_L3_L4_Address_Control */ - addr = osi_readl((unsigned char *)base + MGBE_MAC_L3L4_ADDR_CTR); + addr = osi_readla(osi_core, + (unsigned char *)base + MGBE_MAC_L3L4_ADDR_CTR); /* update filter number */ addr &= ~(MGBE_MAC_L3L4_ADDR_CTR_IDDR_FNUM); @@ -717,7 +727,8 @@ static int mgbe_l3l4_filter_write(struct osi_core_priv_data *osi_core, addr |= MGBE_MAC_L3L4_ADDR_CTR_XB; /* Write MGBE_MAC_L3L4_ADDR_CTR */ - osi_writel(addr, (unsigned char *)base + 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) { @@ -754,7 +765,8 @@ static int mgbe_l3l4_filter_read(struct osi_core_priv_data *osi_core, unsigned int addr = 0; /* Program MAC_L3_L4_Address_Control */ - addr = osi_readl((unsigned char *)base + MGBE_MAC_L3L4_ADDR_CTR); + addr = osi_readla(osi_core, + (unsigned char *)base + MGBE_MAC_L3L4_ADDR_CTR); /* update filter number */ addr &= ~(MGBE_MAC_L3L4_ADDR_CTR_IDDR_FNUM); @@ -773,7 +785,8 @@ static int mgbe_l3l4_filter_read(struct osi_core_priv_data *osi_core, addr |= MGBE_MAC_L3L4_ADDR_CTR_XB; /* Write MGBE_MAC_L3L4_ADDR_CTR */ - osi_writel(addr, (unsigned char *)base + 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) { @@ -784,7 +797,8 @@ static int mgbe_l3l4_filter_read(struct osi_core_priv_data *osi_core, } /* Read the MGBE_MAC_L3L4_DATA for filter register data */ - *value = osi_readl((unsigned char *)base + MGBE_MAC_L3L4_DATA); + *value = osi_readla(osi_core, + (unsigned char *)base + MGBE_MAC_L3L4_DATA); return 0; } @@ -900,7 +914,8 @@ static int mgbe_update_ip6_addr(struct osi_core_priv_data *osi_core, temp = (unsigned int)addr[6] << 16; value |= temp; - ret = mgbe_l3l4_filter_write(osi_core, filter_no, MGBE_MAC_L3_AD0R, value); + 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; @@ -910,7 +925,8 @@ static int mgbe_update_ip6_addr(struct osi_core_priv_data *osi_core, temp = (unsigned int)addr[4] << 16; value |= temp; - ret = mgbe_l3l4_filter_write(osi_core, filter_no, MGBE_MAC_L3_AD1R, value); + 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; @@ -920,7 +936,8 @@ static int mgbe_update_ip6_addr(struct osi_core_priv_data *osi_core, temp = (unsigned int)addr[2] << 16; value |= temp; - ret = mgbe_l3l4_filter_write(osi_core, filter_no, MGBE_MAC_L3_AD2R, value); + 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; @@ -931,7 +948,8 @@ static int mgbe_update_ip6_addr(struct osi_core_priv_data *osi_core, temp = (unsigned int)addr[0] << 16; value |= temp; - return mgbe_l3l4_filter_write(osi_core, filter_no, MGBE_MAC_L3_AD3R, value); + return mgbe_l3l4_filter_write(osi_core, filter_no, + MGBE_MAC_L3_AD3R, value); } /** @@ -947,8 +965,8 @@ static int mgbe_update_ip6_addr(struct osi_core_priv_data *osi_core, * @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) + struct osi_core_priv_data *const osi_core, + unsigned int filter_enb_dis) { unsigned int value = 0U; void *base = osi_core->base; @@ -961,11 +979,11 @@ static int mgbe_config_l3_l4_filter_enable( return -1; } - value = osi_readl((unsigned char *)base + MGBE_MAC_PFR); + 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_writel(value, (unsigned char *)base + MGBE_MAC_PFR); + osi_writela(osi_core, value, (unsigned char *)base + MGBE_MAC_PFR); return 0; } @@ -1004,7 +1022,8 @@ static int mgbe_update_l4_port_no(struct osi_core_priv_data *osi_core, return -1; } - ret = mgbe_l3l4_filter_read(osi_core, filter_no, MGBE_MAC_L4_ADDR, &value); + 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; @@ -1020,7 +1039,8 @@ static int mgbe_update_l4_port_no(struct osi_core_priv_data *osi_core, MGBE_MAC_L4_ADDR_DP_MASK); } - return mgbe_l3l4_filter_write(osi_core, filter_no, MGBE_MAC_L4_ADDR, value); + return mgbe_l3l4_filter_write(osi_core, filter_no, + MGBE_MAC_L4_ADDR, value); } /** @@ -1174,7 +1194,8 @@ static int mgbe_config_l3_filters(struct osi_core_priv_data *osi_core, return -1; } - ret = mgbe_l3l4_filter_read(osi_core, filter_no, MGBE_MAC_L3L4_CTR, &value); + 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; @@ -1265,7 +1286,8 @@ static int mgbe_config_l3_filters(struct osi_core_priv_data *osi_core, } } - ret = mgbe_l3l4_filter_write(osi_core, filter_no, MGBE_MAC_L3L4_CTR, value); + 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; @@ -1355,7 +1377,8 @@ static int mgbe_config_l4_filters(struct osi_core_priv_data *osi_core, return -1; } - ret = mgbe_l3l4_filter_read(osi_core, filter_no, MGBE_MAC_L3L4_CTR, &value); + 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; @@ -1402,7 +1425,8 @@ static int mgbe_config_l4_filters(struct osi_core_priv_data *osi_core, } } - ret = mgbe_l3l4_filter_write(osi_core, filter_no, MGBE_MAC_L3L4_CTR, value); + 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; @@ -1472,18 +1496,18 @@ static int mgbe_config_vlan_filtering(struct osi_core_priv_data *osi_core, } /* Read MAC PFR value set VTFE bit */ - value = osi_readl(base + MGBE_MAC_PFR); + 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_writel(value, base + MGBE_MAC_PFR); + osi_writela(osi_core, value, base + MGBE_MAC_PFR); /* Read MAC VLAN TR register value set VTIM bit */ - value = osi_readl(base + MGBE_MAC_VLAN_TR); + 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_writel(value, base + MGBE_MAC_VLAN_TR); + osi_writela(osi_core, value, base + MGBE_MAC_VLAN_TR); return 0; } @@ -1557,7 +1581,7 @@ static int mgbe_config_ptp_rxq(struct osi_core_priv_data *const osi_core, } /* Read MAC_RxQ_Ctrl1 */ - value = osi_readl(base + MGBE_MAC_RQC1R); + 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 @@ -1581,7 +1605,7 @@ static int mgbe_config_ptp_rxq(struct osi_core_priv_data *const osi_core, value |= MGBE_MAC_RQC1R_OMCBCQ; } /* Write MAC_RxQ_Ctrl1 */ - osi_writel(value, base + MGBE_MAC_RQC1R); + osi_writela(osi_core, value, base + MGBE_MAC_RQC1R); return 0; } @@ -1598,8 +1622,9 @@ static int mgbe_config_ptp_rxq(struct osi_core_priv_data *const osi_core, * @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) +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; @@ -1612,10 +1637,10 @@ static nve32_t mgbe_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core } /* Read Tx Q Operating Mode Register and flush TxQ */ - value = osi_readl((nveu8_t *)addr + + value = osi_readla(osi_core, (nveu8_t *)addr + MGBE_MTL_CHX_TX_OP_MODE(qinx)); value |= MGBE_MTL_QTOMR_FTQ; - osi_writel(value, (nveu8_t *)addr + + 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 */ @@ -1627,7 +1652,7 @@ static nve32_t mgbe_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core count++; - value = osi_readl((nveu8_t *)addr + + 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; @@ -1663,7 +1688,7 @@ static int mgbe_config_mac_loopback(struct osi_core_priv_data *const osi_core, } /* Read MAC Configuration Register */ - value = osi_readl((unsigned char *)addr + MGBE_MAC_RMCR); + value = osi_readla(osi_core, (unsigned char *)addr + MGBE_MAC_RMCR); if (lb_mode == OSI_ENABLE) { /* Enable Loopback Mode */ value |= MGBE_MAC_RMCR_LM; @@ -1671,7 +1696,7 @@ static int mgbe_config_mac_loopback(struct osi_core_priv_data *const osi_core, value &= ~MGBE_MAC_RMCR_LM; } - osi_writel(value, (unsigned char *)addr + MGBE_MAC_RMCR); + osi_writela(osi_core, value, (unsigned char *)addr + MGBE_MAC_RMCR); return 0; } @@ -1708,7 +1733,7 @@ static int mgbe_config_arp_offload(struct osi_core_priv_data *const osi_core, return -1; } - mac_rmcr = osi_readl((unsigned char *)addr + MGBE_MAC_RMCR); + mac_rmcr = osi_readla(osi_core, (unsigned char *)addr + MGBE_MAC_RMCR); if (enable == OSI_ENABLE) { val = (((unsigned int)ip_addr[0]) << 24) | @@ -1716,14 +1741,15 @@ static int mgbe_config_arp_offload(struct osi_core_priv_data *const osi_core, (((unsigned int)ip_addr[2]) << 8) | (((unsigned int)ip_addr[3])); - osi_writel(val, (unsigned char *)addr + MGBE_MAC_ARPPA); + 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_writel(mac_rmcr, (unsigned char *)addr + MGBE_MAC_RMCR); + osi_writela(osi_core, mac_rmcr, (unsigned char *)addr + MGBE_MAC_RMCR); return 0; } @@ -1755,14 +1781,14 @@ static int mgbe_config_rxcsum_offload( return -1; } - mac_rmcr = osi_readl((unsigned char *)addr + MGBE_MAC_RMCR); + 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_writel(mac_rmcr, (unsigned char *)addr + MGBE_MAC_RMCR); + osi_writela(osi_core, mac_rmcr, (unsigned char *)addr + MGBE_MAC_RMCR); return 0; } @@ -1797,11 +1823,11 @@ static int mgbe_config_frp(struct osi_core_priv_data *const osi_core, return -1; } - op_mode = osi_readl(base + MGBE_MTL_OP_MODE); + 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_writel(op_mode, base + MGBE_MTL_OP_MODE); + 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), @@ -1819,16 +1845,16 @@ static int mgbe_config_frp(struct osi_core_priv_data *const osi_core, } /* Enable FRP Interrupts in MTL_RXP_Interrupt_Control_Status */ - val = osi_readl(base + MGBE_MTL_RXP_INTR_CS); + 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_writel(val, base + MGBE_MTL_RXP_INTR_CS); + 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_writel(op_mode, base + MGBE_MTL_OP_MODE); + 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), @@ -1846,12 +1872,12 @@ static int mgbe_config_frp(struct osi_core_priv_data *const osi_core, } /* Disable FRP Interrupts in MTL_RXP_Interrupt_Control_Status */ - val = osi_readl(base + MGBE_MTL_RXP_INTR_CS); + 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_writel(val, base + MGBE_MTL_RXP_INTR_CS); + osi_writela(osi_core, val, base + MGBE_MTL_RXP_INTR_CS); } return 0; @@ -1906,10 +1932,10 @@ static int mgbe_frp_write(struct osi_core_priv_data *osi_core, } /* Write data into MTL_RXP_Indirect_Acc_Data */ - osi_writel(data, base + MGBE_MTL_RXP_IND_DATA); + osi_writela(osi_core, data, base + MGBE_MTL_RXP_IND_DATA); /* Program MTL_RXP_Indirect_Acc_Control_Status */ - val = osi_readl(base + MGBE_MTL_RXP_IND_CS); + 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 */ @@ -1925,7 +1951,7 @@ static int mgbe_frp_write(struct osi_core_priv_data *osi_core, val |= (addr & MGBE_MTL_RXP_IND_CS_ADDR); /* Start write */ val |= MGBE_MTL_RXP_IND_CS_BUSY; - osi_writel(val, base + MGBE_MTL_RXP_IND_CS); + 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), @@ -2063,13 +2089,13 @@ static int mgbe_update_frp_nve(struct osi_core_priv_data *const osi_core, } /* Update NVE and NPE in MTL_RXP_Control_Status register */ - val = osi_readl(base + MGBE_MTL_RXP_CS); + 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_writel(val, base + MGBE_MTL_RXP_CS); + osi_writela(osi_core, val, base + MGBE_MTL_RXP_CS); return 0; } @@ -2228,11 +2254,11 @@ static nve32_t mgbe_configure_mtl_queue(nveu32_t qinx, /* Enable TxQ */ value |= MGBE_MTL_TXQEN; value |= (osi_core->tc[qinx] << MGBE_MTL_CHX_TX_OP_MODE_Q2TC_SH); - osi_writel(value, (unsigned char *) + 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_readl((nveu8_t *)osi_core->base + + 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 */ @@ -2240,31 +2266,31 @@ static nve32_t mgbe_configure_mtl_queue(nveu32_t qinx, /* Enable HW flow control */ value |= MGBE_MTL_RXQ_OP_MODE_EHFC; - osi_writel(value, (nveu8_t *)osi_core->base + + 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_readl((unsigned char *)osi_core->base + + value = osi_readla(osi_core, (unsigned char *)osi_core->base + MGBE_MTL_RXQ_FLOW_CTRL(qinx)); update_rfa_rfd(rx_fifo, &value); - osi_writel(value, (unsigned char *)osi_core->base + + osi_writela(osi_core, value, (unsigned char *)osi_core->base + MGBE_MTL_RXQ_FLOW_CTRL(qinx)); /* Transmit Queue weight */ - value = osi_readl((nveu8_t *)osi_core->base + + value = osi_readla(osi_core, (nveu8_t *)osi_core->base + MGBE_MTL_TCQ_QW(qinx)); value |= (MGBE_MTL_TCQ_QW_ISCQW + qinx); - osi_writel(value, (nveu8_t *)osi_core->base + + osi_writela(osi_core, value, (nveu8_t *)osi_core->base + MGBE_MTL_TCQ_QW(qinx)); /* Enable Rx Queue Control */ - value = osi_readl((nveu8_t *)osi_core->base + + 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_writel(value, (nveu8_t *)osi_core->base + + osi_writela(osi_core, value, (nveu8_t *)osi_core->base + MGBE_MAC_RQC0R); return 0; } @@ -2296,7 +2322,7 @@ static int mgbe_rss_write_reg(struct osi_core_priv_data *osi_core, int cond = 1; /* data into RSS Lookup Table or RSS Hash Key */ - osi_writel(value, addr + MGBE_MAC_RSS_DATA); + osi_writela(osi_core, value, addr + MGBE_MAC_RSS_DATA); if (is_key == OSI_ENABLE) { ctrl |= MGBE_MAC_RSS_ADDR_ADDRT; @@ -2305,7 +2331,7 @@ static int mgbe_rss_write_reg(struct osi_core_priv_data *osi_core, ctrl |= idx << MGBE_MAC_RSS_ADDR_RSSIA_SHIFT; ctrl |= MGBE_MAC_RSS_ADDR_OB; ctrl &= ~MGBE_MAC_RSS_ADDR_CT; - osi_writel(ctrl, addr + MGBE_MAC_RSS_ADDR); + osi_writela(osi_core, ctrl, addr + MGBE_MAC_RSS_ADDR); /* poll for write operation to complete */ while (cond == 1) { @@ -2318,7 +2344,7 @@ static int mgbe_rss_write_reg(struct osi_core_priv_data *osi_core, count++; - value = osi_readl(addr + MGBE_MAC_RSS_ADDR); + value = osi_readla(osi_core, addr + MGBE_MAC_RSS_ADDR); if ((value & MGBE_MAC_RSS_ADDR_OB) == OSI_NONE) { cond = 0; } else { @@ -2381,10 +2407,10 @@ static int mgbe_config_rss(struct osi_core_priv_data *osi_core) } /* Enable RSS */ - value = osi_readl(addr + MGBE_MAC_RSS_CTRL); + 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_writel(value, addr + MGBE_MAC_RSS_CTRL); + osi_writela(osi_core, value, addr + MGBE_MAC_RSS_CTRL); return 0; } @@ -2413,7 +2439,8 @@ static int mgbe_config_flow_control(struct osi_core_priv_data *const osi_core, /* Configure MAC Tx Flow control */ /* Read MAC Tx Flow control Register of Q0 */ - val = osi_readl((unsigned char *)addr + MGBE_MAC_QX_TX_FLW_CTRL(0U)); + 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 @@ -2430,11 +2457,13 @@ static int mgbe_config_flow_control(struct osi_core_priv_data *const osi_core, } /* Write to MAC Tx Flow control Register of Q0 */ - osi_writel(val, (unsigned char *)addr + MGBE_MAC_QX_TX_FLW_CTRL(0U)); + 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_readl((unsigned char *)addr + MGBE_MAC_RX_FLW_CTRL); + 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 @@ -2448,7 +2477,8 @@ static int mgbe_config_flow_control(struct osi_core_priv_data *const osi_core, } /* Write to MAC Rx Flow control Register */ - osi_writel(val, (unsigned char *)addr + MGBE_MAC_RX_FLW_CTRL); + osi_writela(osi_core, val, + (unsigned char *)addr + MGBE_MAC_RX_FLW_CTRL); return 0; } @@ -2478,20 +2508,23 @@ static int mgbe_configure_mac(struct osi_core_priv_data *osi_core) /* Update MAC address 0 high */ value = (((nveu32_t)osi_core->mac_addr[5] << 8U) | ((nveu32_t)osi_core->mac_addr[4])); - osi_writel(value, (nveu8_t *)osi_core->base + MGBE_MAC_MA0HR); + osi_writela(osi_core, value, + (nveu8_t *)osi_core->base + MGBE_MAC_MA0HR); /* Update MAC address 0 Low */ value = (((nveu32_t)osi_core->mac_addr[3] << 24U) | ((nveu32_t)osi_core->mac_addr[2] << 16U) | ((nveu32_t)osi_core->mac_addr[1] << 8U) | ((nveu32_t)osi_core->mac_addr[0])); - osi_writel(value, (nveu8_t *)osi_core->base + MGBE_MAC_MA0LR); + osi_writela(osi_core, value, + (nveu8_t *)osi_core->base + MGBE_MAC_MA0LR); /* TODO: Need to check if we need to enable anything in Tx configuration - * value = osi_readl((nveu8_t *)osi_core->base + MGBE_MAC_TMCR); + * value = osi_readla(osi_core, + (nveu8_t *)osi_core->base + MGBE_MAC_TMCR); */ /* Read MAC Rx Configuration Register */ - value = osi_readl((nveu8_t *)osi_core->base + MGBE_MAC_RMCR); + 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 */ @@ -2512,17 +2545,21 @@ static int mgbe_configure_mac(struct osi_core_priv_data *osi_core) value &= ~MGBE_MAC_RMCR_WD; } - osi_writel(value, (unsigned char *)osi_core->base + MGBE_MAC_RMCR); + osi_writela(osi_core, value, + (unsigned char *)osi_core->base + MGBE_MAC_RMCR); - value = osi_readl((unsigned char *)osi_core->base + MGBE_MAC_TMCR); + value = osi_readla(osi_core, + (unsigned char *)osi_core->base + MGBE_MAC_TMCR); /* Jabber Disable */ if (osi_core->mtu > OSI_DFLT_MTU_SIZE) { value |= MGBE_MAC_TMCR_JD; } - osi_writel(value, (unsigned char *)osi_core->base + MGBE_MAC_TMCR); + osi_writela(osi_core, value, + (unsigned char *)osi_core->base + MGBE_MAC_TMCR); /* Enable Multicast and Broadcast Queue */ - value = osi_readl((unsigned char *)osi_core->base + MGBE_MAC_RQC1R); + 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++) { @@ -2534,39 +2571,43 @@ static int mgbe_configure_mac(struct osi_core_priv_data *osi_core) } value &= ~(MGBE_MAC_RQC1R_MCBCQ); value |= (max_queue << MGBE_MAC_RQC1R_MCBCQ_SHIFT); - osi_writel(value, (unsigned char *)osi_core->base + MGBE_MAC_RQC1R); + 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_writel(OSI_NONE, (nveu8_t *)osi_core->base + + osi_writela(osi_core, OSI_NONE, (nveu8_t *)osi_core->base + MGBE_MMC_TX_INTR_EN); /* Disable all MMC RX nve32_terrupts */ - osi_writel(OSI_NONE, (nveu8_t *)osi_core->base + + osi_writela(osi_core, OSI_NONE, (nveu8_t *)osi_core->base + MGBE_MMC_RX_INTR_EN); /* Configure MMC counters */ - value = osi_readl((nveu8_t *)osi_core->base + MGBE_MMC_CNTRL); + 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_writel(value, (nveu8_t *)osi_core->base + MGBE_MMC_CNTRL); + osi_writela(osi_core, value, + (nveu8_t *)osi_core->base + MGBE_MMC_CNTRL); /* Enable MAC nve32_terrupts */ /* Read MAC IMR Register */ - value = osi_readl((nveu8_t *)osi_core->base + MGBE_MAC_IER); + value = osi_readla(osi_core, (nveu8_t *)osi_core->base + MGBE_MAC_IER); /* RGSMIIIM - RGMII/SMII nve32_terrupt Enable */ /* TODO: LPI need to be enabled during EEE implementation */ value |= MGBE_IMR_RGSMIIIE; - osi_writel(value, (nveu8_t *)osi_core->base + MGBE_MAC_IER); + osi_writela(osi_core, value, (nveu8_t *)osi_core->base + MGBE_MAC_IER); /* Enable common interrupt at wrapper level */ - value = osi_readl((unsigned char *)osi_core->base + + value = osi_readla(osi_core, (unsigned char *)osi_core->base + MGBE_WRAP_COMMON_INTR_ENABLE); value |= MGBE_MAC_SBD_INTR; - osi_writel(value, (unsigned char *)osi_core->base + + osi_writela(osi_core, value, (unsigned char *)osi_core->base + MGBE_WRAP_COMMON_INTR_ENABLE); /* Enable VLAN configuration */ - value = osi_readl((unsigned char *)osi_core->base + MGBE_MAC_VLAN_TR); + 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 */ @@ -2575,14 +2616,17 @@ static int mgbe_configure_mac(struct osi_core_priv_data *osi_core) value |= MGBE_MAC_VLANTR_EVLS_ALWAYS_STRIP; } value |= MGBE_MAC_VLANTR_EVLRXS | MGBE_MAC_VLANTR_DOVLTC; - osi_writel(value, (unsigned char *)osi_core->base + MGBE_MAC_VLAN_TR); + osi_writela(osi_core, value, + (unsigned char *)osi_core->base + MGBE_MAC_VLAN_TR); - value = osi_readl((unsigned char *)osi_core->base + MGBE_MAC_VLANTIR); + 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_writel(value, (unsigned char *)osi_core->base + MGBE_MAC_VLANTIR); + 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) { @@ -2609,11 +2653,12 @@ static int mgbe_configure_mac(struct osi_core_priv_data *osi_core) * 2) Enable enhanced Address mode * 3) Programming max read outstanding request limit * - * @param[in] base: MGBE virtual base address. + * @param[in] osi_core: OSI core private data structure. * * @note MAC has to be out of reset. */ -static void mgbe_configure_dma(void *base, nveu32_t pre_si) +static void mgbe_configure_dma(struct osi_core_priv_data *osi_core, + nveu32_t pre_si) { nveu32_t value = 0; @@ -2628,27 +2673,32 @@ static void mgbe_configure_dma(void *base, nveu32_t pre_si) /* AXI Maximum Write Outstanding Request Limit = 63 */ value |= MGBE_DMA_SBUS_WR_OSR_LMT; - osi_writel(value, (nveu8_t *)base + MGBE_DMA_SBUS); + osi_writela(osi_core, value, + (nveu8_t *)osi_core->base + MGBE_DMA_SBUS); /* Configure TDPS to 5 */ - value = osi_readl((nveu8_t *)base + MGBE_DMA_TX_EDMA_CTRL); + 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_writel(value, (nveu8_t *)base + MGBE_DMA_TX_EDMA_CTRL); + osi_writela(osi_core, value, + (nveu8_t *)osi_core->base + MGBE_DMA_TX_EDMA_CTRL); /* Configure RDPS to 5 */ - value = osi_readl((nveu8_t *)base + MGBE_DMA_RX_EDMA_CTRL); + 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_writel(value, (nveu8_t *)base + MGBE_DMA_RX_EDMA_CTRL); + osi_writela(osi_core, value, + (nveu8_t *)osi_core->base + MGBE_DMA_RX_EDMA_CTRL); } /** @@ -2742,15 +2792,17 @@ static void mgbe_core_backup_init(struct osi_core_priv_data *const osi_core) * * Algorithm: enable MTL interrupts for EST * - * @param[in] addr: MAC base IOVA address. + * @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(void *addr) +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_readl((unsigned char *)addr + MGBE_MTL_EST_ITRE); + 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 @@ -2761,7 +2813,8 @@ static inline void mgbe_enable_mtl_interrupts(void *addr) 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_writel(mtl_est_ir, (unsigned char *)addr + MGBE_MTL_EST_ITRE); + osi_writela(osi_core, mtl_est_ir, + (unsigned char *)osi_core->base + MGBE_MTL_EST_ITRE); } /** @@ -2769,19 +2822,22 @@ static inline void mgbe_enable_mtl_interrupts(void *addr) * * Algorithm: enable FPE interrupts * - * @param[in] addr: MAC base IOVA address. + * @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(void *addr) +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_readl((unsigned char *)addr + MGBE_MAC_IER); + value = osi_readla(osi_core, (unsigned char *) + osi_core->base + MGBE_MAC_IER); value |= MGBE_IMR_FPEIE; - osi_writel(value, (unsigned char *)addr + MGBE_MAC_IER); + osi_writela(osi_core, value, (unsigned char *) + osi_core->base + MGBE_MAC_IER); } /** @@ -2808,7 +2864,7 @@ static void mgbe_tsn_init(struct osi_core_priv_data *osi_core, unsigned int temp = 0U; if (est_sel == OSI_ENABLE) { - val = osi_readl((unsigned char *)osi_core->base + + val = osi_readla(osi_core, (unsigned char *)osi_core->base + MGBE_MTL_EST_CONTROL); /* @@ -2842,42 +2898,42 @@ static void mgbe_tsn_init(struct osi_core_priv_data *osi_core, /*Loop Count to report Scheduling Error*/ val &= ~MGBE_MTL_EST_CONTROL_LCSE; val |= MGBE_MTL_EST_CONTROL_LCSE_VAL; - osi_writel(val, (unsigned char *)osi_core->base + + osi_writela(osi_core, val, (unsigned char *)osi_core->base + MGBE_MTL_EST_CONTROL); - val = osi_readl((nveu8_t *)osi_core->base + + 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 |= OVHD_MGBE_MAC; - osi_writel(val, (nveu8_t *)osi_core->base + + osi_writela(osi_core, val, (nveu8_t *)osi_core->base + MGBE_MTL_EST_OVERHEAD); - mgbe_enable_mtl_interrupts(osi_core->base); + mgbe_enable_mtl_interrupts(osi_core); } if (fpe_sel == OSI_ENABLE) { - val = osi_readl((unsigned char *)osi_core->base + + 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_writel(val, (unsigned char *)osi_core->base + + osi_writela(osi_core, val, (unsigned char *)osi_core->base + MGBE_MAC_RQC1R); - val = osi_readl((nveu8_t *)osi_core->base + + 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_writel(val, (nveu8_t *)osi_core->base + + osi_writela(osi_core, val, (nveu8_t *)osi_core->base + MGBE_MAC_RQC4R); - mgbe_enable_fpe_interrupts(osi_core->base); + mgbe_enable_fpe_interrupts(osi_core); } /* CBS setting for TC or TXQ for default configuration @@ -2916,36 +2972,36 @@ static nve32_t mgbe_core_init(struct osi_core_priv_data *osi_core, mgbe_core_backup_init(osi_core); /* reset mmc counters */ - osi_writel(MGBE_MMC_CNTRL_CNTRST, (nveu8_t *)osi_core->base + + 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_readl((nveu8_t *)osi_core->base + + 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_writel(value, (unsigned char *)osi_core->base + + osi_writela(osi_core, value, (unsigned char *)osi_core->base + MGBE_MTL_RXQ_DMA_MAP0); - value = osi_readl((nveu8_t *)osi_core->base + + 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_writel(value, (unsigned char *)osi_core->base + + osi_writela(osi_core, value, (unsigned char *)osi_core->base + MGBE_MTL_RXQ_DMA_MAP1); - value = osi_readl((nveu8_t *)osi_core->base + + 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_writel(value, (unsigned char *)osi_core->base + + osi_writela(osi_core, value, (unsigned char *)osi_core->base + MGBE_MTL_RXQ_DMA_MAP2); /* Enable XDCS in MAC_Extended_Configuration */ - value = osi_readl((nveu8_t *)osi_core->base + + value = osi_readla(osi_core, (nveu8_t *)osi_core->base + MGBE_MAC_EXT_CNF); value |= MGBE_MAC_EXT_CNF_DDS; - osi_writel(value, (nveu8_t *)osi_core->base + + osi_writela(osi_core, value, (nveu8_t *)osi_core->base + MGBE_MAC_EXT_CNF); if (osi_core->pre_si == OSI_ENABLE) { @@ -2983,7 +3039,7 @@ static nve32_t mgbe_core_init(struct osi_core_priv_data *osi_core, } /* configure MGBE DMA */ - mgbe_configure_dma(osi_core->base, osi_core->pre_si); + mgbe_configure_dma(osi_core, osi_core->pre_si); /* tsn initialization */ if (osi_core->hw_feature != OSI_NULL) { @@ -3010,7 +3066,8 @@ 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_readl((unsigned char *)osi_core->base + MGBE_MAC_FPE_CTS); + 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; @@ -3043,7 +3100,8 @@ static void mgbe_handle_mac_fpe_intrs(struct osi_core_priv_data *osi_core) val &= ~MGBE_MAC_FPE_CTS_EFPE; } - osi_writel(val, (unsigned char *)osi_core->base + MGBE_MAC_FPE_CTS); + osi_writela(osi_core, val, (unsigned char *) + osi_core->base + MGBE_MAC_FPE_CTS); } /** @@ -3063,20 +3121,23 @@ static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core, unsigned int mac_isr = 0; unsigned int mac_ier = 0; - mac_isr = osi_readl((unsigned char *)osi_core->base + MGBE_MAC_ISR); + 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_readl((unsigned char *)osi_core->base + MGBE_MAC_IER); + 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; } - osi_writel(mac_isr, (unsigned char *)osi_core->base + MGBE_MAC_ISR); + 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 */ } @@ -3202,7 +3263,7 @@ static int mgbe_set_avb_algorithm( qinx = avb->qindex; tcinx = avb->tcindex; - value = osi_readl((unsigned char *)osi_core->base + + 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 */ @@ -3211,11 +3272,11 @@ static int mgbe_set_avb_algorithm( /* Set TC mapping */ value |= ((tcinx << MGBE_MTL_TX_OP_MODE_Q2TCMAP_SHIFT) & MGBE_MTL_TX_OP_MODE_Q2TCMAP); - osi_writel(value, (unsigned char *)osi_core->base + + osi_writela(osi_core, value, (unsigned char *)osi_core->base + MGBE_MTL_CHX_TX_OP_MODE(qinx)); /* Set Algo and Credit control */ - value = osi_readl((unsigned char *)osi_core->base + + 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; @@ -3225,36 +3286,36 @@ static int mgbe_set_avb_algorithm( value &= ~MGBE_MTL_TCQ_ETS_CR_AVALG; value |= (avb->algo << MGBE_MTL_TCQ_ETS_CR_AVALG_SHIFT) & MGBE_MTL_TCQ_ETS_CR_AVALG; - osi_writel(value, (unsigned char *)osi_core->base + + 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_readl((unsigned char *)osi_core->base + + 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_writel(value, (unsigned char *)osi_core->base + + osi_writela(osi_core, value, (unsigned char *)osi_core->base + MGBE_MTL_TCQ_QW(tcinx)); /* Set Send slope credit */ - value = osi_readl((unsigned char *)osi_core->base + + 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_writel(value, (unsigned char *)osi_core->base + + 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_writel(value, (unsigned char *)osi_core->base + + 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_writel(value, (unsigned char *)osi_core->base + + osi_writela(osi_core, value, (unsigned char *)osi_core->base + MGBE_MTL_TCQ_ETS_LCR(tcinx)); } @@ -3307,7 +3368,7 @@ static int mgbe_get_avb_algorithm(struct osi_core_priv_data *const osi_core, } qinx = avb->qindex; - value = osi_readl((unsigned char *)osi_core->base + + 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 */ @@ -3320,7 +3381,7 @@ static int mgbe_get_avb_algorithm(struct osi_core_priv_data *const osi_core, tcinx = avb->tcindex; /* Get Algo and Credit control */ - value = osi_readl((unsigned char *)osi_core->base + + 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; @@ -3329,24 +3390,24 @@ static int mgbe_get_avb_algorithm(struct osi_core_priv_data *const osi_core, if (avb->algo == OSI_MTL_TXQ_AVALG_CBS) { /* Get Idle slope credit*/ - value = osi_readl((unsigned char *)osi_core->base + + 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_readl((unsigned char *)osi_core->base + + 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_readl((unsigned char *)osi_core->base + + 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_readl((unsigned char *)osi_core->base + + 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; } @@ -3379,7 +3440,8 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core) unsigned int i = 0; unsigned long stat_val = 0; - val = osi_readl((nveu8_t *)osi_core->base + MGBE_MTL_EST_STATUS); + 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); @@ -3403,7 +3465,7 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core) 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_readl((nveu8_t *)osi_core->base + + 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; @@ -3415,7 +3477,7 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core) } } sch_err &= 0xFFU; //only 8 TC allowed so clearing all - osi_writel(sch_err, (nveu8_t *)osi_core->base + + osi_writela(osi_core, sch_err, (nveu8_t *)osi_core->base + MGBE_MTL_EST_SCH_ERR); } @@ -3425,7 +3487,7 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core) 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_readl((nveu8_t *)osi_core->base + + 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; @@ -3437,7 +3499,7 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core) } } frm_err &= 0xFFU; //only 8 TC allowed so clearing all - osi_writel(frm_err, (nveu8_t *)osi_core->base + + osi_writela(osi_core, frm_err, (nveu8_t *)osi_core->base + MGBE_MTL_EST_FRMS_ERR); } @@ -3459,7 +3521,8 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core) osi_core->est_ready = OSI_DISABLE; } /* clear EST status register as interrupt is handled */ - osi_writel(val, (nveu8_t *)osi_core->base + MGBE_MTL_EST_STATUS); + osi_writela(osi_core, val, + (nveu8_t *)osi_core->base + MGBE_MTL_EST_STATUS); } /** @@ -3487,7 +3550,7 @@ static int mgbe_config_ptp_offload(struct osi_core_priv_data *const osi_core, unsigned int port_id = 0x0U; /* Read MAC TCR */ - value = osi_readl((unsigned char *)addr + MGBE_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 | @@ -3500,12 +3563,12 @@ static int mgbe_config_ptp_offload(struct osi_core_priv_data *const osi_core, if (pto_config->en_dis == OSI_DISABLE) { /* update global setting in ptp_filter */ osi_core->ptp_config.ptp_filter = value; - osi_writel(ptc_value, addr + MGBE_MAC_PTO_CR); - osi_writel(value, addr + MGBE_MAC_TCR); + 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_writel(OSI_NONE, addr + MGBE_MAC_PIDR0); - osi_writel(OSI_NONE, addr + MGBE_MAC_PIDR1); - osi_writel(OSI_NONE, addr + MGBE_MAC_PIDR2); + 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; } @@ -3556,13 +3619,13 @@ static int mgbe_config_ptp_offload(struct osi_core_priv_data *const osi_core, /* update global setting in ptp_filter */ osi_core->ptp_config.ptp_filter = value; /** Write PTO_CR and TCR registers */ - osi_writel(ptc_value, addr + MGBE_MAC_PTO_CR); - osi_writel(value, addr + MGBE_MAC_TCR); + 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_writel(port_id, addr + MGBE_MAC_PIDR0); - osi_writel(OSI_NONE, addr + MGBE_MAC_PIDR1); - osi_writel(OSI_NONE, addr + MGBE_MAC_PIDR2); + 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; } @@ -3590,13 +3653,13 @@ static void mgbe_handle_common_intr(struct osi_core_priv_data *osi_core) /* FIXME: Disabling common interrupt. Needs to be fixed once * RTL issue http://nvbugs/200517360 resolved. */ - val = osi_readl((unsigned char *)osi_core->base + + val = osi_readla(osi_core, (unsigned char *)osi_core->base + MGBE_WRAP_COMMON_INTR_ENABLE); val &= ~MGBE_MAC_SBD_INTR; - osi_writel(val, (unsigned char *)osi_core->base + + osi_writela(osi_core, val, (unsigned char *)osi_core->base + MGBE_WRAP_COMMON_INTR_ENABLE); - dma_isr = osi_readl((nveu8_t *)base + MGBE_DMA_ISR); + dma_isr = osi_readla(osi_core, (nveu8_t *)base + MGBE_DMA_ISR); if (dma_isr == OSI_NONE) { return; } @@ -3613,10 +3676,10 @@ static void mgbe_handle_common_intr(struct osi_core_priv_data *osi_core) } /* read dma channel status register */ - dma_sr = osi_readl((nveu8_t *)base + + dma_sr = osi_readla(osi_core, (nveu8_t *)base + MGBE_DMA_CHX_STATUS(qinx)); /* read dma channel nve32_terrupt enable register */ - dma_ier = osi_readl((nveu8_t *)base + + dma_ier = osi_readla(osi_core, (nveu8_t *)base + MGBE_DMA_CHX_IER(qinx)); /* process only those nve32_terrupts which we @@ -3632,7 +3695,7 @@ static void mgbe_handle_common_intr(struct osi_core_priv_data *osi_core) } /* ack non ti/ri nve32_ts */ - osi_writel(dma_sr, (nveu8_t *)base + + osi_writela(osi_core, dma_sr, (nveu8_t *)base + MGBE_DMA_CHX_STATUS(qinx)); mgbe_update_dma_sr_stats(osi_core, dma_sr, qinx); } @@ -3641,31 +3704,32 @@ static void mgbe_handle_common_intr(struct osi_core_priv_data *osi_core) mgbe_handle_mac_intrs(osi_core, dma_isr); /* Handle MTL inerrupts */ - mtl_isr = osi_readl((unsigned char *)base + MGBE_MTL_INTR_STATUS); + mtl_isr = osi_readla(osi_core, + (unsigned char *)base + MGBE_MTL_INTR_STATUS); if (((mtl_isr & MGBE_MTL_IS_ESTIS) == MGBE_MTL_IS_ESTIS) && ((dma_isr & MGBE_DMA_ISR_MTLIS) == MGBE_DMA_ISR_MTLIS)) { mgbe_handle_mtl_intrs(osi_core); mtl_isr &= ~MGBE_MTL_IS_ESTIS; - osi_writel(mtl_isr, (unsigned char *)base + + osi_writela(osi_core, mtl_isr, (unsigned char *)base + MGBE_MTL_INTR_STATUS); } /* Clear common interrupt status in wrapper register */ - osi_writel(MGBE_MAC_SBD_INTR, + osi_writela(osi_core, MGBE_MAC_SBD_INTR, (unsigned char *)base + MGBE_WRAP_COMMON_INTR_STATUS); - val = osi_readl((unsigned char *)osi_core->base + + val = osi_readla(osi_core, (unsigned char *)osi_core->base + MGBE_WRAP_COMMON_INTR_ENABLE); val |= MGBE_MAC_SBD_INTR; - osi_writel(val, (unsigned char *)osi_core->base + + 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_readl((nveu8_t *)base + MGBE_MTL_RXP_INTR_CS); + 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_writel(val, (nveu8_t *)base + MGBE_MTL_RXP_INTR_CS); + osi_writela(osi_core, val, (nveu8_t *)base + MGBE_MTL_RXP_INTR_CS); } /** @@ -3698,15 +3762,15 @@ static void mgbe_start_mac(struct osi_core_priv_data *const osi_core) nveu32_t value; void *addr = osi_core->base; - value = osi_readl((nveu8_t *)addr + MGBE_MAC_TMCR); + value = osi_readla(osi_core, (nveu8_t *)addr + MGBE_MAC_TMCR); /* Enable MAC Transmit */ value |= MGBE_MAC_TMCR_TE; - osi_writel(value, (nveu8_t *)addr + MGBE_MAC_TMCR); + osi_writela(osi_core, value, (nveu8_t *)addr + MGBE_MAC_TMCR); - value = osi_readl((nveu8_t *)addr + MGBE_MAC_RMCR); + value = osi_readla(osi_core, (nveu8_t *)addr + MGBE_MAC_RMCR); /* Enable MAC Receive */ value |= MGBE_MAC_RMCR_RE; - osi_writel(value, (nveu8_t *)addr + MGBE_MAC_RMCR); + osi_writela(osi_core, value, (nveu8_t *)addr + MGBE_MAC_RMCR); } /** @@ -3723,15 +3787,15 @@ static void mgbe_stop_mac(struct osi_core_priv_data *const osi_core) nveu32_t value; void *addr = osi_core->base; - value = osi_readl((nveu8_t *)addr + MGBE_MAC_TMCR); + value = osi_readla(osi_core, (nveu8_t *)addr + MGBE_MAC_TMCR); /* Disable MAC Transmit */ value &= ~MGBE_MAC_TMCR_TE; - osi_writel(value, (nveu8_t *)addr + MGBE_MAC_TMCR); + osi_writela(osi_core, value, (nveu8_t *)addr + MGBE_MAC_TMCR); - value = osi_readl((nveu8_t *)addr + MGBE_MAC_RMCR); + value = osi_readla(osi_core, (nveu8_t *)addr + MGBE_MAC_RMCR); /* Disable MAC Receive */ value &= ~MGBE_MAC_RMCR_RE; - osi_writel(value, (nveu8_t *)addr + MGBE_MAC_RMCR); + osi_writela(osi_core, value, (nveu8_t *)addr + MGBE_MAC_RMCR); } /** @@ -3760,11 +3824,13 @@ static void mgbe_core_deinit(struct osi_core_priv_data *osi_core) * * @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) +static int mgbe_set_speed(struct osi_core_priv_data *const osi_core, + const int speed) { unsigned int value = 0; - value = osi_readl((unsigned char *)osi_core->base + MGBE_MAC_TMCR); + value = osi_readla(osi_core, + (unsigned char *) osi_core->base + MGBE_MAC_TMCR); switch (speed) { case OSI_SPEED_2500: @@ -3782,7 +3848,8 @@ static int mgbe_set_speed(struct osi_core_priv_data *const osi_core, const int s break; } - osi_writel(value, (unsigned char *)osi_core->base + MGBE_MAC_TMCR); + 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, @@ -3816,8 +3883,8 @@ static int mgbe_mdio_busy_wait(struct osi_core_priv_data *const osi_core) count++; - mac_gmiiar = osi_readl((unsigned char *)osi_core->base + - MGBE_MDIO_SCCD); + 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 { @@ -3852,7 +3919,8 @@ static inline int mgbe_save_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_readl(config->reg_addr[i]); + config->reg_val[i] = osi_readla(osi_core, + config->reg_addr[i]); } } @@ -3933,7 +4001,8 @@ static inline int mgbe_restore_registers( for (i = 0; i < MGBE_MAX_BAK_IDX; i++) { if (config->reg_addr[i] != OSI_NULL) { /* Write back the saved register value */ - osi_writel(config->reg_val[i], config->reg_addr[i]); + osi_writela(osi_core, config->reg_val[i], + config->reg_addr[i]); } } @@ -4036,7 +4105,8 @@ static int mgbe_write_phy_reg(struct osi_core_priv_data *osi_core, /* set port address and register address */ reg |= (phyaddr << MGBE_MDIO_SCCA_PA_SHIFT) | (phyreg & MGBE_MDIO_SCCA_RA_MASK); - osi_writel(reg, (unsigned char *)osi_core->base + MGBE_MDIO_SCCA); + osi_writela(osi_core, reg, (unsigned char *) + osi_core->base + MGBE_MDIO_SCCA); /* Program Data register */ reg = phydata | @@ -4059,7 +4129,8 @@ static int mgbe_write_phy_reg(struct osi_core_priv_data *osi_core, MGBE_MDIO_SCCD_CR_SHIFT); } - osi_writel(reg, (unsigned char *)osi_core->base + MGBE_MDIO_SCCD); + 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); @@ -4112,7 +4183,8 @@ static int mgbe_read_phy_reg(struct osi_core_priv_data *osi_core, /* set port address and register address */ reg |= (phyaddr << MGBE_MDIO_SCCA_PA_SHIFT) | (phyreg & MGBE_MDIO_SCCA_RA_MASK); - osi_writel(reg, (unsigned char *)osi_core->base + MGBE_MDIO_SCCA); + 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) | @@ -4134,7 +4206,8 @@ static int mgbe_read_phy_reg(struct osi_core_priv_data *osi_core, MGBE_MDIO_SCCD_CR_SHIFT); } - osi_writel(reg, (unsigned char *)osi_core->base + MGBE_MDIO_SCCD); + osi_writela(osi_core, reg, (unsigned char *) + osi_core->base + MGBE_MDIO_SCCD); ret = mgbe_mdio_busy_wait(osi_core); if (ret < 0) { @@ -4145,7 +4218,8 @@ static int mgbe_read_phy_reg(struct osi_core_priv_data *osi_core, return ret; } - reg = osi_readl((unsigned char *)osi_core->base + MGBE_MDIO_SCCD); + reg = osi_readla(osi_core, (unsigned char *) + osi_core->base + MGBE_MDIO_SCCD); data = (reg & MGBE_MDIO_SCCD_SDATA_MASK); return (int)data; @@ -4173,19 +4247,19 @@ static int mgbe_hw_est_write(struct osi_core_priv_data *osi_core, int retry = 1000; unsigned int val = 0x0; - osi_writel(data, (unsigned char *)osi_core->base + + 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_writel(val, (unsigned char *)osi_core->base + + 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_readl((unsigned char *)osi_core->base + + 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; @@ -4308,9 +4382,11 @@ static int mgbe_hw_config_est(struct osi_core_priv_data *osi_core, } if (est->en_dis == OSI_DISABLE) { - val = osi_readl((unsigned char *)base + MGBE_MTL_EST_CONTROL); + val = osi_readla(osi_core, (unsigned char *) + base + MGBE_MTL_EST_CONTROL); val &= ~MGBE_MTL_EST_EEST; - osi_writel(val, (unsigned char *)base + MGBE_MTL_EST_CONTROL); + osi_writela(osi_core, val, (unsigned char *) + base + MGBE_MTL_EST_CONTROL); return 0; } @@ -4365,11 +4441,13 @@ static int mgbe_hw_config_est(struct osi_core_priv_data *osi_core, return ret; } - val = osi_readl((unsigned char *)base + MGBE_MTL_EST_CONTROL); + val = osi_readla(osi_core, (unsigned char *) + base + MGBE_MTL_EST_CONTROL); /* Store table */ val |= MGBE_MTL_EST_SSWL; val |= MGBE_MTL_EST_EEST; - osi_writel(val, (unsigned char *)base + MGBE_MTL_EST_CONTROL); + osi_writela(osi_core, val, (unsigned char *) + base + MGBE_MTL_EST_CONTROL); return ret; } @@ -4407,17 +4485,18 @@ static int mgbe_hw_config_fpe(struct osi_core_priv_data *osi_core, osi_core->fpe_ready = OSI_DISABLE; - val = osi_readl((unsigned char *)osi_core->base + MGBE_MTL_FPE_CTS); + val = osi_readla(osi_core, (unsigned char *) + osi_core->base + MGBE_MTL_FPE_CTS); if (((fpe->tx_queue_preemption_enable << MGBE_MTL_FPE_CTS_PEC_SHIFT) & MGBE_MTL_FPE_CTS_PEC) == OSI_DISABLE) { val &= ~MGBE_MAC_FPE_CTS_EFPE; - osi_writel(val, (unsigned char *)osi_core->base + + osi_writela(osi_core, val, (unsigned char *)osi_core->base + MGBE_MAC_FPE_CTS); - val = osi_readl((unsigned char *)osi_core->base + + val = osi_readla(osi_core, (unsigned char *)osi_core->base + MGBE_MAC_RQC1R); val &= ~MGBE_MAC_RQC1R_RQ; - osi_writel(val, (unsigned char *)osi_core->base + + osi_writela(osi_core, val, (unsigned char *)osi_core->base + MGBE_MAC_RQC1R); return 0; @@ -4441,7 +4520,8 @@ static int mgbe_hw_config_fpe(struct osi_core_priv_data *osi_core, } } } - osi_writel(val, (unsigned char *)osi_core->base + MGBE_MTL_FPE_CTS); + osi_writela(osi_core, val, (unsigned char *) + 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, @@ -4449,33 +4529,39 @@ static int mgbe_hw_config_fpe(struct osi_core_priv_data *osi_core, return -1; } - val = osi_readl((unsigned char *)osi_core->base + MGBE_MAC_RQC1R); + 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_writel(val, (unsigned char *)osi_core->base + MGBE_MAC_RQC1R); + osi_writela(osi_core, val, (unsigned char *) + osi_core->base + MGBE_MAC_RQC1R); - val = osi_readl((nveu8_t *)osi_core->base + MGBE_MAC_RQC4R); + 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_writel(val, (nveu8_t *)osi_core->base + MGBE_MAC_RQC4R); + osi_writela(osi_core, val, (nveu8_t *)osi_core->base + MGBE_MAC_RQC4R); /* initiate SVER for SMD-V and SMD-R */ - val = osi_readl((unsigned char *)osi_core->base + MGBE_MTL_FPE_CTS); + val = osi_readla(osi_core, (unsigned char *) + osi_core->base + MGBE_MTL_FPE_CTS); val |= MGBE_MAC_FPE_CTS_SVER; - osi_writel(val, (unsigned char *)osi_core->base + MGBE_MAC_FPE_CTS); + osi_writela(osi_core, val, (unsigned char *) + osi_core->base + MGBE_MAC_FPE_CTS); - val = osi_readl((unsigned char *)osi_core->base + MGBE_MTL_FPE_ADV); + 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_writel(val, (unsigned char *)osi_core->base + MGBE_MTL_FPE_ADV); + osi_writela(osi_core, val, (unsigned char *) + osi_core->base + MGBE_MTL_FPE_ADV); return 0; } @@ -4487,19 +4573,21 @@ static int mgbe_hw_config_fpe(struct osi_core_priv_data *osi_core, * 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] addr: base address of memory mapped register space of MAC. + * @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(void *addr) +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_readl((unsigned char *)addr + MGBE_MAC_LPI_CSR); + 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_writel(lpi_csr, (unsigned char *)addr + MGBE_MAC_LPI_CSR); + osi_writela(osi_core, lpi_csr, (unsigned char *) + osi_core->base + MGBE_MAC_LPI_CSR); } /** @@ -4555,7 +4643,7 @@ static void mgbe_configure_eee(struct osi_core_priv_data *osi_core, MGBE_LPI_LS_TIMER_MASK); lpi_timer_ctrl |= (MGBE_DEFAULT_LPI_TW_TIMER & MGBE_LPI_TW_TIMER_MASK); - osi_writel(lpi_timer_ctrl, (unsigned char *)addr + + 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 @@ -4570,7 +4658,7 @@ static void mgbe_configure_eee(struct osi_core_priv_data *osi_core, /* 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_writel(tic_counter, (unsigned char *)addr + + osi_writela(osi_core, tic_counter, (unsigned char *)addr + MGBE_MAC_1US_TIC_COUNT); /* 6. Program the MAC_LPI_Auto_Entry_Timer register (LPIET) @@ -4580,7 +4668,7 @@ static void mgbe_configure_eee(struct osi_core_priv_data *osi_core, * to enter LPI mode after all tx is complete. Default 1sec */ lpi_entry_timer |= (tx_lpi_timer & MGBE_LPI_ENTRY_TIMER_MASK); - osi_writel(lpi_entry_timer, (unsigned char *)addr + + osi_writela(osi_core, lpi_entry_timer, (unsigned char *)addr + MGBE_MAC_LPI_EN_TIMER); /* 7. Set LPIATE and LPITXA (bit[20:19]) of @@ -4591,13 +4679,15 @@ static void mgbe_configure_eee(struct osi_core_priv_data *osi_core, * enters the LPI mode after completing all scheduled * packets and remain IDLE for the time indicated by LPIET. */ - lpi_csr = osi_readl((unsigned char *)addr + MGBE_MAC_LPI_CSR); + 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_writel(lpi_csr, (unsigned char *)addr + MGBE_MAC_LPI_CSR); + osi_writela(osi_core, lpi_csr, (unsigned char *) + addr + MGBE_MAC_LPI_CSR); } else { /* Disable LPI control bits */ - mgbe_disable_tx_lpi(osi_core->base); + mgbe_disable_tx_lpi(osi_core); } } @@ -4611,10 +4701,10 @@ static int mgbe_get_hw_features(struct osi_core_priv_data *osi_core, unsigned int mac_hfr3 = 0; unsigned int val = 0; - mac_hfr0 = osi_readl(base + MGBE_MAC_HFR0); - mac_hfr1 = osi_readl(base + MGBE_MAC_HFR1); - mac_hfr2 = osi_readl(base + MGBE_MAC_HFR2); - mac_hfr3 = osi_readl(base + MGBE_MAC_HFR3); + 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); @@ -4790,8 +4880,8 @@ static inline int mgbe_poll_for_tsinit_complete( while (retry < OSI_POLL_COUNT) { /* Read and Check TSINIT in MAC_Timestamp_Control register */ - *mac_tcr = osi_readl((unsigned char *)osi_core->base + - MGBE_MAC_TCR); + *mac_tcr = osi_readla(osi_core, (unsigned char *) + osi_core->base + MGBE_MAC_TCR); if ((*mac_tcr & MGBE_MAC_TCR_TSINIT) == 0U) { return 0; } @@ -4834,16 +4924,16 @@ static int mgbe_set_systime_to_mac(struct osi_core_priv_data *osi_core, } /* write seconds value to MAC_System_Time_Seconds_Update register */ - osi_writel(sec, (unsigned char *)addr + MGBE_MAC_STSUR); + osi_writela(osi_core, sec, (unsigned char *)addr + MGBE_MAC_STSUR); /* write nano seconds value to MAC_System_Time_Nanoseconds_Update * register */ - osi_writel(nsec, (unsigned char *)addr + MGBE_MAC_STNSUR); + 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_writel(mac_tcr, (unsigned char *)addr + MGBE_MAC_TCR); + 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) { @@ -4877,8 +4967,8 @@ static inline int mgbe_poll_for_addend_complete( /* Poll */ while (retry < OSI_POLL_COUNT) { /* Read and Check TSADDREG in MAC_Timestamp_Control register */ - *mac_tcr = osi_readl((unsigned char *)osi_core->base + - MGBE_MAC_TCR); + *mac_tcr = osi_readla(osi_core, (unsigned char *) + osi_core->base + MGBE_MAC_TCR); if ((*mac_tcr & MGBE_MAC_TCR_TSADDREG) == 0U) { return 0; } @@ -4918,11 +5008,11 @@ static int mgbe_config_addend(struct osi_core_priv_data *osi_core, } /* write addend value to MAC_Timestamp_Addend register */ - osi_writel(addend, (unsigned char *)addr + MGBE_MAC_TAR); + 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_writel(mac_tcr, (unsigned char *)addr + MGBE_MAC_TCR); + 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) { @@ -4947,15 +5037,16 @@ static int mgbe_config_addend(struct osi_core_priv_data *osi_core, * @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) +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_readl((unsigned char *)osi_core->base + - MGBE_MAC_TCR); + *mac_tcr = osi_readla(osi_core, (unsigned char *) + osi_core->base + MGBE_MAC_TCR); if ((*mac_tcr & MGBE_MAC_TCR_TSUPDT) == 0U) { return 0; } @@ -5032,20 +5123,20 @@ static int mgbe_adjust_mactime(struct osi_core_priv_data *osi_core, } /* write seconds value to MAC_System_Time_Seconds_Update register */ - osi_writel(sec, (unsigned char *)addr + MGBE_MAC_STSUR); + 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_writel(value, (unsigned char *)addr + MGBE_MAC_STNSUR); + 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_writel(mac_tcr, (unsigned char *)addr + MGBE_MAC_TCR); + 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) { @@ -5128,7 +5219,7 @@ static void mgbe_config_tscr(struct osi_core_priv_data *osi_core, mac_tcr = OSI_DISABLE; } - osi_writel(mac_tcr, (unsigned char *)addr + MGBE_MAC_TCR); + osi_writela(osi_core, mac_tcr, (unsigned char *)addr + MGBE_MAC_TCR); } /** @@ -5146,7 +5237,7 @@ static void mgbe_config_ssir(struct osi_core_priv_data *const osi_core, unsigned int mac_tcr; void *addr = osi_core->base; - mac_tcr = osi_readl((unsigned char *)addr + MGBE_MAC_TCR); + 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) @@ -5175,7 +5266,7 @@ static void mgbe_config_ssir(struct osi_core_priv_data *const osi_core, /* update Sub-second Increment Value */ if (val < UINT_MAX) { - osi_writel((unsigned int)val, + osi_writela(osi_core, (unsigned int)val, (unsigned char *)addr + MGBE_MAC_SSIR); } } diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index d559d3c..9092f53 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -104,6 +104,7 @@ static inline nve32_t validate_args(struct osi_core_priv_data *const osi_core, static nve32_t validate_func_ptrs(struct osi_core_priv_data *const osi_core, struct core_ops *ops_p) { +#if 0 nveu32_t i = 0; void *temp_ops = (void *)ops_p; #if __SIZEOF_POINTER__ == 8 @@ -123,7 +124,7 @@ static nve32_t validate_func_ptrs(struct osi_core_priv_data *const osi_core, l_ops++; } - +#endif return 0; } @@ -160,7 +161,7 @@ nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core) init_ops_arr i_ops[MAX_MAC_IP_TYPES][MAX_MAC_IP_TYPES] = { { eqos_init_core_ops, ivc_init_core_ops }, - { mgbe_init_core_ops, OSI_NULL } + { mgbe_init_core_ops, ivc_init_core_ops } }; safety_init s_init[MAX_MAC_IP_TYPES][MAX_MAC_IP_TYPES] = { diff --git a/osi/core/xpcs.c b/osi/core/xpcs.c index 19bf72e..e71c0e8 100644 --- a/osi/core/xpcs.c +++ b/osi/core/xpcs.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -205,6 +205,9 @@ int xpcs_init(struct osi_core_priv_data *osi_core) unsigned int ctrl = 0; int cond = 1; + if (osi_core->xpcs_base == OSI_NULL) + return -1; + /* Switching to USXGMII Mode based on * XPCS programming guideline 7.6 */ @@ -290,6 +293,9 @@ int xpcs_eee(void *xpcs_base, unsigned int en_dis) 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; diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 14cfbaa..09e1537 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -156,6 +156,7 @@ static inline nve32_t validate_dma_chans(struct osi_dma_priv_data *osi_dma) static nve32_t validate_func_ptrs(struct osi_dma_priv_data *osi_dma, struct dma_chan_ops *ops_p) { +#if 0 nveu32_t i = 0; void *temp_ops = (void *)ops_p; #if __SIZEOF_POINTER__ == 8 @@ -175,7 +176,7 @@ static nve32_t validate_func_ptrs(struct osi_dma_priv_data *osi_dma, l_ops++; } - +#endif return 0; } From 29124be8d400e642c3708fa5bedb9c7f22b600c0 Mon Sep 17 00:00:00 2001 From: Mahesh Patil <maheshp@nvidia.com> Date: Mon, 1 Feb 2021 11:37:15 -0800 Subject: [PATCH 217/458] nvethernetrm: Enable key program through TZ Enabling macsec key's programming using TZ Bug 3246511 Change-Id: I1e7633b042e1ebedef78fff9812aeaaa2480a1c4 Signed-off-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2478489 Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> --- include/macsec.h | 1096 ------------------------------------------ include/mmc.h | 5 +- include/osi_core.h | 6 + include/osi_macsec.h | 27 +- osi/core/macsec.c | 109 +++-- 5 files changed, 103 insertions(+), 1140 deletions(-) delete mode 100644 include/macsec.h diff --git a/include/macsec.h b/include/macsec.h deleted file mode 100644 index 620e254..0000000 --- a/include/macsec.h +++ /dev/null @@ -1,1096 +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 MACSEC_H -#define MACSEC_H - -#include <osi_core.h> - -/** - * @addtogroup MACsec AMAP - * - * @brief MACsec controller register offsets - * @{ - */ -#define GCM_KEYTABLE_CONFIG 0x0000 -#define GCM_KEYTABLE_DATA(x) (0x0004 + (x * 4)) -#define RX_ICV_ERR_CNTRL 0x4000 -#define INTERRUPT_COMMON_SR 0x4004 -#define TX_IMR 0x4008 -#define TX_ISR 0x400C -#ifdef NET24 -#define RX_IMR 0x4040 -#define RX_ISR 0x4044 -#else -#define RX_IMR 0x4048 -#define RX_ISR 0x404C -#endif /* NET24 */ -#ifdef NET30 -#define INTERRUPT_MASK1_0 0x40A0 -#define TX_SC_PN_EXHAUSTED_STATUS0_0 0x4024 -#define TX_SC_PN_EXHAUSTED_STATUS1_0 0x4028 -#define TX_SC_PN_THRESHOLD_STATUS0_0 0x4018 -#define TX_SC_PN_THRESHOLD_STATUS1_0 0x401C -#define TX_SC_ERROR_INTERRUPT_STATUS_0 0x402C -#define RX_SC_PN_EXHAUSTED_STATUS0_0 0x405C -#define RX_SC_PN_EXHAUSTED_STATUS1_0 0x4060 -#define RX_SC_REPLAY_ERROR_STATUS0_0 0x4090 -#define RX_SC_REPLAY_ERROR_STATUS1_0 0x4094 -#endif -#define STATS_CONFIG 0x9000 -#ifdef NET30 -#define STATS_CONTROL_0 0x900C -#define TX_PKTS_UNTG_LO_0 0x9010 -#define TX_PKTS_UNTG_HI_0 0x9014 -#define TX_OCTETS_PRTCTD_LO_0 0x9018 -#define TX_OCTETS_PRTCTD_HI_0 0x901C -#define TX_PKTS_TOO_LONG_LO_0 0x9020 -#define TX_PKTS_TOO_LONG_HI_0 0x9024 -#define TX_PKTS_PROTECTED_SCx_LO_0(x) (0x9028 + (x * 8)) -#define TX_PKTS_PROTECTED_SCx_HI_0(x) (0x902C + (x * 8)) -#define RX_PKTS_NOTG_LO_0 0x90B0 -#define RX_PKTS_NOTG_HI_0 0x90B4 -#define RX_PKTS_UNTG_LO_0 0x90A8 -#define RX_PKTS_UNTG_HI_0 0x90AC -#define RX_PKTS_BADTAG_LO_0 0x90B8 -#define RX_PKTS_BADTAG_HI_0 0x90BC -#define RX_PKTS_NOSA_LO_0 0x90C0 -#define RX_PKTS_NOSA_HI_0 0x90C4 -#define RX_PKTS_NOSAERROR_LO_0 0x90C8 -#define RX_PKTS_NOSAERROR_HI_0 0x90CC -#define RX_PKTS_OVRRUN_LO_0 0x90D0 -#define RX_PKTS_OVRRUN_HI_0 0x90D4 -#define RX_OCTETS_VLDTD_LO_0 0x90D8 -#define RX_OCTETS_VLDTD_HI_0 0x90DC -#define RX_PKTS_LATE_SCx_LO_0(x) (0x90E0 + (x * 8)) -#define RX_PKTS_LATE_SCx_HI_0(x) (0x90E4 + (x * 8)) -#define RX_PKTS_NOTVALID_SCx_LO_0(x) (0x9160 + (x * 8)) -#define RX_PKTS_NOTVALID_SCx_HI_0(x) (0x9164 + (x * 8)) -#define RX_PKTS_OK_SCx_LO_0(x) (0x91E0 + (x * 8)) -#define RX_PKTS_OK_SCx_HI_0(x) (0x91E4 + (x * 8)) - -#define TX_INPKTS_CRCIN_NOTVALID_LO_0 0x9260 -#define TX_INPKTS_CRCIN_NOTVALID_HI_0 0x9264 -#define RX_INPKTS_CRCIN_NOTVALID_LO_0 0x9268 -#define RX_INPKTS_CRCIN_NOTVALID_HI_0 0x926C - - -#endif -#define MACSEC_CONTROL0 0xD000 -#define MACSEC_LUT_CONFIG 0xD004 -#define MACSEC_LUT_DATA(x) (0xD008 + (x * 4)) -#ifndef NET24 -#define TX_BYP_LUT_VALID 0xD024 -#define TX_SCI_LUT_VALID 0xD028 -#define RX_BYP_LUT_VALID 0xD02C -#define RX_SCI_LUT_VALID 0xD030 -#endif /* NET24 */ -#ifdef NET24 -#define COMMON_IMR 0xD024 -#define COMMON_ISR 0xD028 -#else -#define COMMON_IMR 0xD054 -#define COMMON_ISR 0xD058 -#endif /* NET24 */ -#ifdef NET30 -#define TX_SC_KEY_INVALID_STS0_0 0XD064 -#define TX_SC_KEY_INVALID_STS1_0 0XD068 -#define RX_SC_KEY_INVALID_STS0_0 0XD080 -#define RX_SC_KEY_INVALID_STS1_0 0XD084 - -#define TX_DEBUG_CONTROL_0 0xD098 -#define TX_DEBUG_TRIGGER_EN_0 0xD09C -#define TX_DEBUG_STATUS_0 0xD0C4 -#define DEBUG_BUF_CONFIG_0 0xD0C8 -#define DEBUG_BUF_DATA_0(x) (0xD0CC + (x * 4)) -#define RX_DEBUG_CONTROL_0 0xD0DC -#define RX_DEBUG_TRIGGER_EN_0 0xD0E0 -#define RX_DEBUG_STATUS_0 0xD0F8 - -#endif /* NET30 */ -#define MACSEC_CONTROL1 0xE000 -#define GCM_AES_CNTRL 0xE004 -#define TX_MTU_LEN 0xE008 -#define TX_SOT_DELAY 0xE010 -#define RX_MTU_LEN 0xE014 -#define RX_SOT_DELAY 0xE01C -#ifdef NET30 -#define MACSEC_TX_DVLAN_CONTROL_0 0xE00C -#define MACSEC_RX_DVLAN_CONTROL_0 0xE018 -#endif -/** @} */ - -/** - * @addtogroup GCM_KEYTABLE_CONFIG register - * - * @brief Bit definitions of GCM_KEYTABLE_CONFIG register - * @{ - */ -#define KT_CONFIG_UPDATE OSI_BIT(31) -#define KT_CONFIG_CTLR_SEL OSI_BIT(25) -#define KT_CONFIG_RW OSI_BIT(24) -#define KT_CONFIG_INDEX_MASK (OSI_BIT(4) | OSI_BIT(3) | OSI_BIT(2) |\ - OSI_BIT(1) | OSI_BIT(0)) -#define KT_ENTRY_VALID OSI_BIT(0) -/** @} */ - -/** - * @addtogroup GCM_KEYTABLE_DATA registers - * - * @brief Bit definitions of GCM_KEYTABLE_DATA register & helpful macros - * @{ - */ -#define KT_ENTRY_VALID OSI_BIT(0) -#define MACSEC_KT_DATA_REG_CNT 13 -#define MACSEC_KT_DATA_REG_SAK_CNT 8 -#define MACSEC_KT_DATA_REG_H_CNT 4 -/** @} */ - -/** - * @addtogroup MACSEC_LUT_CONFIG register - * - * @brief Bit definitions of MACSEC_LUT_CONFIG register - * @{ - */ -#define LUT_CONFIG_UPDATE OSI_BIT(31) -#define LUT_CONFIG_CTLR_SEL OSI_BIT(25) -#define LUT_CONFIG_RW OSI_BIT(24) -#define LUT_CONFIG_LUT_SEL_MASK (OSI_BIT(18) | OSI_BIT(17) |\ - OSI_BIT(16)) -#define LUT_CONFIG_LUT_SEL_SHIFT 16 -#define 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 - * @{ - */ -#ifdef NET30 -#define COMMON_SR_SFTY_ERR OSI_BIT(2) -#endif -#define COMMON_SR_RX OSI_BIT(1) -#define COMMON_SR_TX OSI_BIT(0) -/** @} */ - -/** - * @addtogroup MACSEC_CONTROL0 register - * - * @brief Bit definitions of MACSEC_CONTROL0 register - * @{ - */ -#define TX_LKUP_MISS_NS_INTR OSI_BIT(24) -#define RX_LKUP_MISS_NS_INTR OSI_BIT(23) -#define VALIDATE_FRAMES_MASK (OSI_BIT(22) | OSI_BIT(21)) -#define VALIDATE_FRAMES_DIS 0x0 -#define VALIDATE_FRAMES_STRICT OSI_BIT(22) -#define VALIDATE_FRAMES_CHECK OSI_BIT(21) -#define RX_REPLAY_PROT_EN OSI_BIT(20) -#define RX_LKUP_MISS_BYPASS OSI_BIT(19) -#ifndef NET30 -#define RX_SCI_LUT_EN OSI_BIT(18) -#define RX_BYP_LUT_EN OSI_BIT(17) -#endif -#define RX_EN OSI_BIT(16) -#define TX_LKUP_MISS_BYPASS OSI_BIT(3) -#ifndef NET30 -#define TX_SCI_LUT_EN OSI_BIT(2) -#define TX_BYP_LUT_EN OSI_BIT(1) -#endif -#define TX_EN OSI_BIT(0) -/** @} */ - -/** - * @addtogroup MACSEC_CONTROL1 register - * - * @brief Bit definitions of MACSEC_CONTROL1 register - * @{ - */ -#define LOOPBACK_MODE_EN OSI_BIT(31) -#define RX_MTU_CHECK_EN OSI_BIT(16) -#define TX_LUT_PRIO_BYP OSI_BIT(2) -#define TX_MTU_CHECK_EN OSI_BIT(0) -/** @} */ - -/** - * @addtogroup GCM_AES_CNTRL register - * - * @brief Bit definitions of GCM_AES_CNTRL register - * @{ - */ -#define RX_AES_MODE_MASK (OSI_BIT(17) | OSI_BIT(16)) -#define RX_AES_MODE_AES128 0x0 -#define RX_AES_MODE_AES256 OSI_BIT(17) -#define TX_AES_MODE_MASK (OSI_BIT(1) | OSI_BIT(0)) -#define TX_AES_MODE_AES128 0x0 -#define TX_AES_MODE_AES256 OSI_BIT(1) -/** @} */ - -/** - * @addtogroup COMMON_IMR register - * - * @brief Bit definitions of MACSEC_INTERRUPT_MASK register - * @{ - */ -#define SECURE_REG_VIOL_INT_EN OSI_BIT(31) -#define RX_UNINIT_KEY_SLOT_INT_EN OSI_BIT(17) -#define RX_LKUP_MISS_INT_EN OSI_BIT(16) -#define TX_UNINIT_KEY_SLOT_INT_EN OSI_BIT(1) -#define TX_LKUP_MISS_INT_EN OSI_BIT(0) -/** @} */ - -/** - * @addtogroup TX_IMR register - * - * @brief Bit definitions of TX_INTERRUPT_MASK register - * @{ - */ -#ifdef NET30 -#define TX_DBG_BUF_CAPTURE_DONE_INT_EN OSI_BIT(22) -#else -#define TX_SFTY_ERR_CORR_INT_EN OSI_BIT(26) -#define TX_SFTY_ERR_UNCORR_INT_EN OSI_BIT(25) -#define TX_DBG_BUF_CAPTURE_DONE_INT_EN OSI_BIT(2) -#endif -#define TX_MTU_CHECK_FAIL_INT_EN OSI_BIT(19) -#define TX_AES_GCM_BUF_OVF_INT_EN OSI_BIT(18) -#define TX_SC_AN_NOT_VALID_INT_EN OSI_BIT(17) -#define TX_MAC_CRC_ERROR_INT_EN OSI_BIT(16) -#define TX_PN_EXHAUSTED_INT_EN OSI_BIT(1) -#define TX_PN_THRSHLD_RCHD_INT_EN OSI_BIT(0) -/** @} */ - -/** - * @addtogroup RX_IMR register - * - * @brief Bit definitions of RX_INTERRUPT_MASK register - * @{ - */ -#ifdef NET30 -#define RX_DBG_BUF_CAPTURE_DONE_INT_EN OSI_BIT(22) -#else -#define RX_SFTY_ERR_CORR_INT_EN OSI_BIT(26) -#define RX_SFTY_ERR_UNCORR_INT_EN OSI_BIT(25) -#define RX_SC_AN_NOT_VALID_INT_EN OSI_BIT(17) -#define RX_DBG_BUF_CAPTURE_DONE_INT_EN OSI_BIT(2) -#endif -#define RX_ICV_ERROR_INT_EN OSI_BIT(21) -#define RX_REPLAY_ERROR_INT_EN OSI_BIT(20) -#define RX_MTU_CHECK_FAIL_INT_EN OSI_BIT(19) -#define RX_AES_GCM_BUF_OVF_INT_EN OSI_BIT(18) -#define RX_MAC_CRC_ERROR_INT_EN OSI_BIT(16) -#define RX_PN_EXHAUSTED_INT_EN OSI_BIT(1) -#ifdef NET24 -#define RX_PN_THRSHLD_RCHD_INT_EN OSI_BIT(0) -#endif /* NET24 */ -/** @} */ - -/** - * @addtogroup INTERRUPT_MASK1_0 register - * - * @brief Bit definitions of INTERRUPT_MASK1_0 register - * @{ - */ -#define SFTY_ERR_UNCORR_INT_EN OSI_BIT(0) -/** @} */ - -/** - * @addtogroup COMMON_ISR register - * - * @brief Bit definitions of MACSEC_INTERRUPT_STATUS register - * @{ - */ -#define SECURE_REG_VIOL OSI_BIT(31) -#define RX_UNINIT_KEY_SLOT OSI_BIT(17) -#define RX_LKUP_MISS OSI_BIT(16) -#define TX_UNINIT_KEY_SLOT OSI_BIT(1) -#define TX_LKUP_MISS OSI_BIT(0) -/** @} */ - -/** - * @addtogroup TX_ISR register - * - * @brief Bit definitions of TX_INTERRUPT_STATUS register - * @{ - */ -#ifdef NET30 -#define TX_DBG_BUF_CAPTURE_DONE OSI_BIT(22) -#else -#define TX_SFTY_ERR_CORR OSI_BIT(26) -#define TX_SFTY_ERR_UNCORR OSI_BIT(25) -#define TX_DBG_BUF_CAPTURE_DONE OSI_BIT(2) -#endif -#define TX_MTU_CHECK_FAIL OSI_BIT(19) -#define TX_AES_GCM_BUF_OVF OSI_BIT(18) -#define TX_SC_AN_NOT_VALID OSI_BIT(17) -#define TX_MAC_CRC_ERROR OSI_BIT(16) -#define TX_PN_EXHAUSTED OSI_BIT(1) -#define TX_PN_THRSHLD_RCHD OSI_BIT(0) -/** @} */ - -/** - * @addtogroup RX_ISR register - * - * @brief Bit definitions of RX_INTERRUPT_STATUS register - * @{ - */ -#ifdef NET30 -#define RX_DBG_BUF_CAPTURE_DONE OSI_BIT(22) -#else -#define RX_SFTY_ERR_CORR OSI_BIT(26) -#define RX_SFTY_ERR_UNCORR OSI_BIT(25) -#define RX_SC_AN_NOT_VALID OSI_BIT(17) -#define RX_DBG_BUF_CAPTURE_DONE OSI_BIT(2) -#endif -#define RX_ICV_ERROR OSI_BIT(21) -#define RX_REPLAY_ERROR OSI_BIT(20) -#define RX_MTU_CHECK_FAIL OSI_BIT(19) -#define RX_AES_GCM_BUF_OVF OSI_BIT(18) -#define RX_MAC_CRC_ERROR OSI_BIT(16) -#define RX_PN_EXHAUSTED OSI_BIT(1) -#ifdef NET24 -#define RX_PN_THRSHLD_RCHD OSI_BIT(0) -#endif /* NET24 */ -/** @} */ - -/** - * @addtogroup STATS_CONTROL_0 register - * - * @brief Bit definitions of STATS_CONTROL_0 register - * @{ - */ -#ifdef NET30 -#define STATS_CONTROL0_RD_CPY OSI_BIT(3) -#define STATS_CONTROL0_TK_CPY OSI_BIT(2) -#define STATS_CONTROL0_CNT_RL_OVR_CPY OSI_BIT(1) -#define STATS_CONTROL0_CNT_CLR OSI_BIT(0) -#endif /* NET30 */ -/** @} */ - -/** - * @addtogroup DEBUG_BUF_CONFIG_0 register - * - * @brief Bit definitions of DEBUG_BUF_CONFIG_0 register - * @{ - */ -#define DEBUG_BUF_CONFIG_0_UPDATE OSI_BIT(31) -#define DEBUG_BUF_CONFIG_0_CTLR_SEL OSI_BIT(25) -#define DEBUG_BUF_CONFIG_0_RW OSI_BIT(24) -#define DEBUG_BUF_CONFIG_0_IDX_MASK (OSI_BIT(0) | OSI_BIT(1) | \ - OSI_BIT(2) | OSI_BIT(3)) -/** @} */ - -/** - * @addtogroup TX_DEBUG_TRIGGER_EN_0 register - * - * @brief Bit definitions of TX_DEBUG_TRIGGER_EN_0 register - * @{ - */ -#define TX_DBG_CAPTURE OSI_BIT(10) -#define TX_DBG_ICV_CORRUPT OSI_BIT(9) -#define TX_DBG_CRC_CORRUPT OSI_BIT(8) -#define TX_DBG_DATA_MATCH OSI_BIT(7) -#define TX_DBG_LKUP_MATCH OSI_BIT(6) -#define TX_DBG_CRCOUT_MATCH OSI_BIT(5) -#define TX_DBG_CRCIN_MATCH OSI_BIT(4) -#define TX_DBG_ICV_MATCH OSI_BIT(3) -#define TX_DBG_KEY_NOT_VALID OSI_BIT(2) -#define TX_DBG_AN_NOT_VALID OSI_BIT(1) -#define TX_DBG_LKUP_MISS OSI_BIT(0) -/** @} */ - -/** - * @addtogroup TX_DEBUG_STATUS_0 register - * - * @brief Bit definitions of TX_DEBUG_STATUS_0 register - * @{ - */ -#define TX_DBG_STS_CAPTURE OSI_BIT(10) -#define TX_DBG_STS_ICV_CORRUPT OSI_BIT(9) -#define TX_DBG_STS_CRC_CORRUPT OSI_BIT(8) -#define TX_DBG_STS_DATA_MATCH OSI_BIT(7) -#define TX_DBG_STS_LKUP_MATCH OSI_BIT(6) -#define TX_DBG_STS_CRCOUT_MATCH OSI_BIT(5) -#define TX_DBG_STS_CRCIN_MATCH OSI_BIT(4) -#define TX_DBG_STS_ICV_MATCH OSI_BIT(3) -#define TX_DBG_STS_KEY_NOT_VALID OSI_BIT(2) -#define TX_DBG_STS_AN_NOT_VALID OSI_BIT(1) -#define TX_DBG_STS_LKUP_MISS OSI_BIT(0) -/** @} */ - -/** - * @addtogroup RX_DEBUG_TRIGGER_EN_0 register - * - * @brief Bit definitions of RX_DEBUG_TRIGGER_EN_0 register - * @{ - */ -#define RX_DBG_CAPTURE OSI_BIT(10) -#define RX_DBG_ICV_ERROR OSI_BIT(9) -#define RX_DBG_CRC_CORRUPT OSI_BIT(8) -#define RX_DBG_DATA_MATCH OSI_BIT(7) -#define RX_DBG_BYP_LKUP_MATCH OSI_BIT(6) -#define RX_DBG_CRCOUT_MATCH OSI_BIT(5) -#define RX_DBG_CRCIN_MATCH OSI_BIT(4) -#define RX_DBG_REPLAY_ERR OSI_BIT(3) -#define RX_DBG_KEY_NOT_VALID OSI_BIT(2) -#define RX_DBG_LKUP_MISS OSI_BIT(0) -/** @} */ - -/** - * @addtogroup RX_DEBUG_STATUS_0 register - * - * @brief Bit definitions of RX_DEBUG_STATUS_0 register - * @{ - */ -#define RX_DBG_STS_CAPTURE OSI_BIT(10) -#define RX_DBG_STS_ICV_ERROR OSI_BIT(9) -#define RX_DBG_STS_CRC_CORRUPT OSI_BIT(8) -#define RX_DBG_STS_DATA_MATCH OSI_BIT(7) -#define RX_DBG_STS_BYP_LKUP_MATCH OSI_BIT(6) -#define RX_DBG_STS_CRCOUT_MATCH OSI_BIT(5) -#define RX_DBG_STS_CRCIN_MATCH OSI_BIT(4) -#define RX_DBG_STS_REPLAY_ERR OSI_BIT(3) -#define RX_DBG_STS_KEY_NOT_VALID OSI_BIT(2) -#define RX_DBG_STS_LKUP_MISS OSI_BIT(0) -/** @} */ - -/** - * @addtogroup TX_DEBUG_STATUS_0 register - * - * @brief Bit definitions of TX_DEBUG_STATUS_0 register - * @{ - */ -#define TX_DBG_STS_CAPTURE OSI_BIT(10) -#define TX_DBG_STS_ICV_CORRUPT OSI_BIT(9) -#define TX_DBG_STS_CRC_CORRUPT OSI_BIT(8) -#define TX_DBG_STS_DATA_MATCH OSI_BIT(7) -#define TX_DBG_STS_LKUP_MATCH OSI_BIT(6) -#define TX_DBG_STS_CRCOUT_MATCH OSI_BIT(5) -#define TX_DBG_STS_CRCIN_MATCH OSI_BIT(4) -#define TX_DBG_STS_ICV_MATCH OSI_BIT(3) -#define TX_DBG_STS_KEY_NOT_VALID OSI_BIT(2) -#define TX_DBG_STS_AN_NOT_VALID OSI_BIT(1) -#define TX_DBG_STS_LKUP_MISS OSI_BIT(0) -/** @} */ - -/** - * @addtogroup TX_DEBUG_CONTROL_0 register - * - * @brief Bit definitions of TX_DEBUG_CONTROL_0 register - * @{ - */ -#define TX_DEBUG_CONTROL_0_START_CAP OSI_BIT(31) -/** @} */ - -/** - * @addtogroup RX_DEBUG_CONTROL_0 register - * - * @brief Bit definitions of RX_DEBUG_CONTROL_0 register - * @{ - */ -#define RX_DEBUG_CONTROL_0_START_CAP OSI_BIT(31) -/** @} */ - -#define MTU_LENGTH_MASK 0xFFFF -/* MACsec sectag + ICV + 2B ethertype adds upto 34B */ -#define MACSEC_TAG_ICV_LEN 34 -/* Add 8B for double VLAN tags (4B each), - * 14B for L2 SA/DA/ethertype, TODO - as per IAS SA/DA is ignored from length - * 4B for FCS - */ -#define MTU_ADDONS (8 + 14 + 4) -#define DVLAN_TAG_ETHERTYPE 0x88A8 -#ifndef NET24 -/** - * @addtogroup TX/RX_BYP/SCI_LUT_VALID register - * - * @brief Bit definitions of LUT_VALID registers - * @{ - */ -#define TX_BYP_LUT_VALID_ENTRY(x) OSI_BIT(x) -#define TX_BYP_LUT_VALID_NONE 0x0 -#define TX_SCI_LUT_VALID_ENTRY(x) OSI_BIT(x) -#define TX_SCI_LUT_VALID_NONE 0x0 -#define RX_BYP_LUT_VALID_ENTRY(x) OSI_BIT(x) -#define RX_BYP_LUT_VALID_NONE 0x0 -#define RX_SCI_LUT_VALID_ENTRY(x) OSI_BIT(x) -#define RX_SCI_LUT_VALID_NONE 0x0 -/** @} */ -#endif /* NET24 */ - -/** - * @addtogroup TX/RX LUT bit fields in LUT_DATA registers - * - * @brief Helper macros for LUT data programming - * @{ - */ -#define MACSEC_LUT_DATA_REG_CNT 7 -/* Bit Offsets for LUT DATA[x] registers for various lookup field masks */ -/* DA mask bits in LUT_DATA[1] register */ -#define LUT_DA_BYTE0_INACTIVE OSI_BIT(16) -#define LUT_DA_BYTE1_INACTIVE OSI_BIT(17) -#define LUT_DA_BYTE2_INACTIVE OSI_BIT(18) -#define LUT_DA_BYTE3_INACTIVE OSI_BIT(19) -#define LUT_DA_BYTE4_INACTIVE OSI_BIT(20) -#define LUT_DA_BYTE5_INACTIVE OSI_BIT(21) -/* SA mask bits in LUT_DATA[3] register */ -#define LUT_SA_BYTE0_INACTIVE OSI_BIT(6) -#define LUT_SA_BYTE1_INACTIVE OSI_BIT(7) -#define LUT_SA_BYTE2_INACTIVE OSI_BIT(8) -#define LUT_SA_BYTE3_INACTIVE OSI_BIT(9) -#define LUT_SA_BYTE4_INACTIVE OSI_BIT(10) -#define LUT_SA_BYTE5_INACTIVE OSI_BIT(11) -/* Ether type mask in LUT_DATA[3] register */ -#define LUT_ETHTYPE_INACTIVE OSI_BIT(28) -/* VLAN PCP mask in LUT_DATA[4] register */ -#define LUT_VLAN_PCP_INACTIVE OSI_BIT(0) -/* VLAN ID mask in LUT_DATA[4] register */ -#define LUT_VLAN_ID_INACTIVE OSI_BIT(13) -/* VLAN mask in LUT_DATA[4] register */ -#define LUT_VLAN_ACTIVE OSI_BIT(14) -/* Byte pattern masks in LUT_DATA[4] register */ -#define LUT_BYTE0_PATTERN_INACTIVE OSI_BIT(29) -/* Byte pattern masks in LUT_DATA[5] register */ -#define LUT_BYTE1_PATTERN_INACTIVE OSI_BIT(12) -#define LUT_BYTE2_PATTERN_INACTIVE OSI_BIT(27) -/* Byte pattern masks in LUT_DATA[6] register */ -#define LUT_BYTE3_PATTERN_INACTIVE OSI_BIT(10) -/* Preemptible packet in LUT_DATA[6] register */ -#define LUT_PREEMPT OSI_BIT(11) -/* Preempt mask in LUT_DATA[6] register */ -#define LUT_PREEMPT_INACTIVE OSI_BIT(12) -/* Controlled port mask in LUT_DATA[6] register */ -#define LUT_CONTROLLED_PORT OSI_BIT(13) -#ifdef NET30 -/* DVLAN packet in LUT_DATA[6] register */ -#define 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) -#else -/* BYP LUT entry valid in LUT_DATA[6] register */ -#define BYP_LUT_ENTRY_VALID OSI_BIT(14) -#endif /* NET30 */ -/* AN valid bits for SCI LUT in LUT_DATA[6] register */ -#define LUT_AN0_VALID OSI_BIT(13) -#define LUT_AN1_VALID OSI_BIT(14) -#define LUT_AN2_VALID OSI_BIT(15) -#define LUT_AN3_VALID OSI_BIT(16) -#ifdef NET30 -/* DVLAN packet in LUT_DATA[6] register */ -#define TX_SCI_LUT_DVLAN_PKT OSI_BIT(21) -/* DVLAN outer/inner tag select in LUT_DATA[6] register */ -#define TX_SCI_LUT_DVLAN_OUTER_INNER_TAG_SEL OSI_BIT(22) -#else -/* SCI LUT entry valid in LUT_DATA[6] register */ -#define TX_SCI_LUT_ENTRY_VALID OSI_BIT(21) -#endif /* NET30 */ -/* SA State LUT entry valid in LUT_DATA[0] register */ -#define SA_STATE_LUT_ENTRY_VALID OSI_BIT(0) - -/* Rx LUT macros */ -/* Preemptible packet in LUT_DATA[2] register for Rx SCI */ -#define RX_SCI_LUT_PREEMPT OSI_BIT(8) -/* Preempt mask in LUT_DATA[2] register for Rx SCI */ -#define RX_SCI_LUT_PREEMPT_INACTIVE OSI_BIT(9) -#ifndef NET30 -/* Rx SCI LUT entry valid in LUT_DATA[2] register */ -#define RX_SCI_LUT_ENTRY_VALID OSI_BIT(14) -#endif /* NET30 */ -/* TODO - Invalidate the valid bits for above LUT_ENTRY_VALIDs in write path */ -/** @} */ - -////////////////////////////////////////////////////////////////////////// - /* MACsec OSI data structures */ -////////////////////////////////////////////////////////////////////////// - -/** - * @addtogroup TX/RX BYP/SCI LUT INPUT macros - * - * @brief Helper macros for LUT input programming - * @{ - */ -//TODO - Aggregate all the macros inlined in the struct itself -/** @} */ - -/** - * @brief MACsec secure channel basic information - */ -struct osi_macsec_sc_info { - /** Secure channel identifier */ -#define SCI_LEN 8 - unsigned char sci[SCI_LEN]; - /** Secure association key */ -#define KEY_LEN_128 16 -#define KEY_LEN_256 32 - unsigned char sak[KEY_LEN_128]; - /** current AN */ - unsigned char curr_an; - /** Next PN to use for the current AN */ - unsigned int next_pn; - /** == BELOW FIELDS ARE FILLED BY OSI LAYER == */ - /** bitmap of valid AN */ -#define AN0_VALID OSI_BIT(0) -#define AN1_VALID OSI_BIT(1) -#define AN2_VALID OSI_BIT(2) -#define AN3_VALID OSI_BIT(3) - unsigned int an_valid; - /** SC LUT index */ - unsigned int sc_idx_start; -}; - -/** - * @brief MACsec HW controller LUT's overall status - */ -struct osi_macsec_lut_status { - /** List of max SC's supported */ -#define MAX_NUM_SC 8 -#define MAX_NUM_SA 4 - struct osi_macsec_sc_info sc_info[MAX_NUM_SC]; - /** next available BYP LUT index */ - unsigned int next_byp_idx; - /** next available SC LUT index */ - unsigned int next_sc_idx; -}; - -/** - * @brief MACsec SA State LUT entry outputs structure - */ -struct sa_state_outputs { - /** Next PN to use */ - unsigned int next_pn; - /** Lowest PN to use */ - unsigned int lowest_pn; -}; - -/** - * @brief MACsec SC State LUT entry outputs structure - */ -struct sc_state_outputs { - /** Current AN to use */ -#define CURR_AN_MAX 3 /* 0-3 */ - unsigned int curr_an; -}; - -/** - * @brief MACsec SC Param LUT entry outputs structure - */ -struct sc_param_outputs { - /** Key index start */ -#define KEY_INDEX_MAX 31 /* 0-31 */ - unsigned int key_index_start; - /** PN max for given AN, after which HW will roll over to next AN */ -#define PN_MAX_DEFAULT 0xFFFFFFFF - unsigned int pn_max; - /** PN threshold to trigger irq when threshold is reached */ -#define PN_THRESHOLD_DEFAULT 0xC0000000 - unsigned int pn_threshold; - /** PN window */ - unsigned int pn_window; - /** SC identifier */ - unsigned char sci[SCI_LEN]; - /** Default TCI value V=1, ES=0, SC = 1 */ -#define TCI_DEFAULT 0x1 - /** TCI 3 bits V=0, ES=0, SC=1 */ - unsigned char tci; -#define VLAN_IN_CLEAR_DEFAULT 0x0 - /** vlan in clear config */ - unsigned char vlan_in_clear; -}; - -/** - * @brief MACsec SCI LUT entry outputs structure - */ -struct sci_lut_outputs { - /** SC index to use */ -#define SC_INDEX_MAX 15 /* 0-15 */ - unsigned int sc_index; - /** SC identifier */ - unsigned char sci[SCI_LEN]; - /** AN's valid */ - unsigned int an_valid; -}; - -/** - * @brief MACsec BYP/SCI LUT entry inputs structure - */ -struct lut_inputs { - /** MAC DA to compare */ - unsigned char da[OSI_ETH_ALEN]; - /** MAC SA to compare */ - unsigned char sa[OSI_ETH_ALEN]; - /** Ethertype to compare */ -#define ETHTYPE_LEN 2 - unsigned char ethtype[ETHTYPE_LEN]; - /** 4-Byte pattern to compare */ -#define LUT_BYTE_PATTERN_MAX 4 - unsigned char byte_pattern[LUT_BYTE_PATTERN_MAX]; - /** Offset for 4-Byte pattern to compare */ -#define LUT_BYTE_PATTERN_MAX_OFFSET 63 /* 0-63 */ - unsigned int byte_pattern_offset[LUT_BYTE_PATTERN_MAX]; - /** VLAN PCP to compare */ -#define VLAN_PCP_MAX 7 /* 0-7 */ - unsigned int vlan_pcp; - /** VLAN ID to compare */ -#define VLAN_ID_MAX 4095 /* 1-4095 */ - unsigned int vlan_id; -}; - -/** - * @brief MACsec LUT config data structure - */ -struct macsec_table_config { - /** Controller select - * 0 - Tx - * 1 - Rx - */ -#define CTLR_SEL_TX 0U -#define CTLR_SEL_RX 1U -#define CTLR_SEL_MAX 1U -#define NUM_CTLR 2U - unsigned short ctlr_sel; - /** Read or write operation select - * 0 - Read - * 1 - Write - */ -#define LUT_READ 0U -#define LUT_WRITE 1U -#define RW_MAX 1U - unsigned short rw; - /** Table entry index */ -#define TABLE_INDEX_MAX 31U /* 0-31 */ -#define BYP_LUT_MAX_INDEX TABLE_INDEX_MAX -#define SC_LUT_MAX_INDEX 15U -#define SA_LUT_MAX_INDEX TABLE_INDEX_MAX - unsigned short index; -}; - -/** - * @brief MACsec LUT config data structure - */ -struct osi_macsec_lut_config { - /** Generic table config */ - struct macsec_table_config table_config; - /** LUT select */ -#define LUT_SEL_BYPASS 0U -#define LUT_SEL_SCI 1U -#define LUT_SEL_SC_PARAM 2U -#define LUT_SEL_SC_STATE 3U -#define LUT_SEL_SA_STATE 4U -#define LUT_SEL_MAX 4U /* 0-4 */ - unsigned short lut_sel; - /** flag - encoding various valid bits for above fields */ - unsigned int flags; -//LUT input fields flags bit offsets -#define LUT_FLAGS_DA_BYTE0_VALID OSI_BIT(0) -#define LUT_FLAGS_DA_BYTE1_VALID OSI_BIT(1) -#define LUT_FLAGS_DA_BYTE2_VALID OSI_BIT(2) -#define LUT_FLAGS_DA_BYTE3_VALID OSI_BIT(3) -#define LUT_FLAGS_DA_BYTE4_VALID OSI_BIT(4) -#define LUT_FLAGS_DA_BYTE5_VALID OSI_BIT(5) -#define LUT_FLAGS_DA_VALID (OSI_BIT(0) | OSI_BIT(1) | OSI_BIT(2) |\ - OSI_BIT(3) | OSI_BIT(4) | OSI_BIT(5)) -#define LUT_FLAGS_SA_BYTE0_VALID OSI_BIT(6) -#define LUT_FLAGS_SA_BYTE1_VALID OSI_BIT(7) -#define LUT_FLAGS_SA_BYTE2_VALID OSI_BIT(8) -#define LUT_FLAGS_SA_BYTE3_VALID OSI_BIT(9) -#define LUT_FLAGS_SA_BYTE4_VALID OSI_BIT(10) -#define LUT_FLAGS_SA_BYTE5_VALID OSI_BIT(11) -#define LUT_FLAGS_SA_VALID (OSI_BIT(6) | OSI_BIT(7) | OSI_BIT(8) |\ - OSI_BIT(9) | OSI_BIT(10) | OSI_BIT(11)) -#define LUT_FLAGS_ETHTYPE_VALID OSI_BIT(12) -#define LUT_FLAGS_VLAN_PCP_VALID OSI_BIT(13) -#define LUT_FLAGS_VLAN_ID_VALID OSI_BIT(14) -#define LUT_FLAGS_VLAN_VALID OSI_BIT(15) -#define LUT_FLAGS_BYTE0_PATTERN_VALID OSI_BIT(16) -#define LUT_FLAGS_BYTE1_PATTERN_VALID OSI_BIT(17) -#define LUT_FLAGS_BYTE2_PATTERN_VALID OSI_BIT(18) -#define LUT_FLAGS_BYTE3_PATTERN_VALID OSI_BIT(19) -#define LUT_FLAGS_PREEMPT OSI_BIT(20) -#define LUT_FLAGS_PREEMPT_VALID OSI_BIT(21) -#define LUT_FLAGS_CONTROLLED_PORT OSI_BIT(22) -#define LUT_FLAGS_DVLAN_PKT OSI_BIT(23) -#define LUT_FLAGS_DVLAN_OUTER_INNER_TAG_SEL OSI_BIT(24) -#define LUT_FLAGS_ENTRY_VALID OSI_BIT(31) - /** LUT inputs */ - struct lut_inputs lut_in; - /** SCI LUT outputs */ - struct sci_lut_outputs sci_lut_out; - /** SC Param outputs */ - struct sc_param_outputs sc_param_out; - /** SC State outputs */ - struct sc_state_outputs sc_state_out; - /** SA State outputs */ - struct sa_state_outputs sa_state_out; -}; - -/** - * @brief MACsec KT entry structure - */ -struct kt_entry { - /** SAK key - max 256bit */ - unsigned char sak[KEY_LEN_256]; - /** H-key */ - unsigned char h[KEY_LEN_128]; -}; - -/** - * @brief MACsec KT config data structure - */ -struct osi_macsec_kt_config { - /** Generic table config */ - struct macsec_table_config table_config; - /** KT entry */ - struct kt_entry entry; - /** flag - encoding various valid bits */ - unsigned int flags; -}; - -/** - * @brief MACsec Debug buffer data structure - */ -struct osi_macsec_dbg_buf_config { - /** Controller select - * 0 - Tx - * 1 - Rx - */ - unsigned short ctlr_sel; - /** Read or write operation select - * 0 - Read - * 1 - Write - */ -#define DBG_TBL_READ LUT_READ -#define DBG_TBL_WRITE LUT_WRITE - unsigned short rw; - /* Num of Tx debug buffers */ -#define TX_DBG_BUF_IDX_MAX 12U - /* Num of Rx debug buffers */ -#define RX_DBG_BUF_IDX_MAX 13U -#define DBG_BUF_IDX_MAX RX_DBG_BUF_IDX_MAX - /** debug data buffer */ - unsigned int dbg_buf[4]; - /** flag - encoding various debug event bits */ -#define TX_DBG_LKUP_MISS_EVT OSI_BIT(0) -#define TX_DBG_AN_NOT_VALID_EVT OSI_BIT(1) -#define TX_DBG_KEY_NOT_VALID_EVT OSI_BIT(2) -#define TX_DBG_CRC_CORRUPT_EVT OSI_BIT(3) -#define TX_DBG_ICV_CORRUPT_EVT OSI_BIT(4) -#define TX_DBG_CAPTURE_EVT OSI_BIT(5) -#define RX_DBG_LKUP_MISS_EVT OSI_BIT(6) -#define RX_DBG_KEY_NOT_VALID_EVT OSI_BIT(7) -#define RX_DBG_REPLAY_ERR_EVT OSI_BIT(8) -#define RX_DBG_CRC_CORRUPT_EVT OSI_BIT(9) -#define RX_DBG_ICV_ERROR_EVT OSI_BIT(10) -#define RX_DBG_CAPTURE_EVT OSI_BIT(11) - unsigned int flags; - /** debug buffer index */ - unsigned int index; -}; - -/** - * @brief MACsec core operations structure - */ -struct macsec_core_ops { - /** macsec init */ - int (*init)(struct osi_core_priv_data *const osi_core); - /** macsec de-init */ - void (*deinit)(struct osi_core_priv_data *const osi_core); - /** NS irq handler */ - void (*handle_ns_irq)(struct osi_core_priv_data *const osi_core); - /** S irq handler */ - void (*handle_s_irq)(struct osi_core_priv_data *const osi_core); - /** macsec lut config */ - int (*lut_config)(struct osi_core_priv_data *const osi_core, - struct osi_macsec_lut_config *const lut_config); - /** macsec kt config */ - int (*kt_config)(struct osi_core_priv_data *const osi_core, - struct osi_macsec_kt_config *const kt_config); - /** macsec loopback config */ - int (*loopback_config)(struct osi_core_priv_data *const osi_core, - unsigned int enable); - /** macsec enable */ - int (*macsec_en)(struct osi_core_priv_data *const osi_core, - unsigned int enable); - /** macsec config SA in HW LUT */ - int (*config)(struct osi_core_priv_data *const osi_core, - struct osi_macsec_sc_info *const sc, - unsigned int enable, unsigned short ctlr); - /** macsec read mmc counters */ - void (*read_mmc)(struct osi_core_priv_data *const osi_core); - /** macsec debug buffer config */ - int (*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 */ - int (*dbg_events_config)(struct osi_core_priv_data *const osi_core, - struct osi_macsec_dbg_buf_config *const dbg_buf_config); - -}; - -////////////////////////////////////////////////////////////////////////// - /* OSI interface API prototypes */ -////////////////////////////////////////////////////////////////////////// - -/** - * @brief initializing the macsec core operations - * - * @param[in] osi_core: OSI core private data structure. - * - * @retval 0 on success - * @retval -1 on failure - */ -int osi_init_macsec_ops(struct osi_core_priv_data *const osi_core); - -/** - * @brief initialize the macsec controller - * - * @param[in] osi_core: OSI core private data structure. - * - * @retval 0 on success - * @retval -1 on failure - */ -int osi_macsec_init(struct osi_core_priv_data *const osi_core); - -/** - * @brief De-initialize the macsec controller - * - * @param[in] osi_core: OSI core private data structure. - * - */ -void osi_macsec_deinit(struct osi_core_priv_data *const osi_core); - -/** - * @brief Non-secure irq handler - * - * @param[in] osi_core: OSI core private data structure. - * - * @retval None - */ -void osi_macsec_ns_isr(struct osi_core_priv_data *const osi_core); - -/** - * @brief Secure irq handler - * - * @param[in] osi_core: OSI core private data structure. - * - * @retval None - */ -void osi_macsec_s_isr(struct osi_core_priv_data *const osi_core); - -/** - * @brief MACsec Lookup table config - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] lut_config: OSI macsec LUT config data structure. - * - * @retval 0 on success - * @retval -1 on failure - */ -int osi_macsec_lut_config(struct osi_core_priv_data *const osi_core, - struct osi_macsec_lut_config *const lut_confg); - -/** - * @brief MACsec key table config - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] kt_config: OSI macsec KT config data structure. - * - * @retval 0 on success - * @retval -1 on failure - */ -int osi_macsec_kt_config(struct osi_core_priv_data *const osi_core, - struct osi_macsec_kt_config *const kt_config); - -/** - * @brief MACsec Loopback config - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] enable: Loopback enable/disable flag. - * - * @retval 0 on success - * @retval -1 on failure - */ -int osi_macsec_loopback(struct osi_core_priv_data *const osi_core, - unsigned int enable); - -/** - * @brief MACsec Enable - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] enable: macsec controller Tx/Rx enable/disable flag. - * - * @retval 0 on success - * @retval -1 on failure - */ -int osi_macsec_en(struct osi_core_priv_data *const osi_core, - unsigned int enable); - -/** - * @brief MACsec update secure channel/association in controller - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] tx_sa: Pointer to osi_macsec_sc_info struct for the tx SA. - * @param[in] enable: flag to indicate enable/disable for the Tx SA. - * - * @retval 0 on success - * @retval -1 on failure - */ -int osi_macsec_config(struct osi_core_priv_data *const osi_core, - struct osi_macsec_sc_info *const sc, - unsigned int enable, unsigned short ctlr); - -/** - * @brief MACsec read statistics counters - * - * @param[in] osi_core: OSI core private data structure. - * - * @retval 0 on success - * @retval -1 on failure - */ -int osi_macsec_read_mmc(struct osi_core_priv_data *const osi_core); - -/** - * @brief MACsec debug buffer config - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] dbg_buf_config: OSI macsec debug buffer config data structure. - * - * @retval 0 on success - * @retval -1 on failure - */ -int osi_macsec_dbg_buf_config( - struct osi_core_priv_data *const osi_core, - struct osi_macsec_dbg_buf_config *const dbg_buf_config); - -/** - * @brief MACsec debug events config - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] dbg_buf_config: OSI macsec debug buffer config data structure. - * - * @retval 0 on success - * @retval -1 on failure - */ -int osi_macsec_dbg_events_config( - struct osi_core_priv_data *const osi_core, - struct osi_macsec_dbg_buf_config *const dbg_buf_config); - -#endif /* MACSEC_H */ diff --git a/include/mmc.h b/include/mmc.h index 672b1ea..438f8bf 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -580,6 +580,7 @@ struct osi_xtra_stat_counters { nveu64_t link_disconnect_count; }; +#ifdef MACSEC_SUPPORT /** * @brief The structure hold macsec statistics counters */ @@ -624,5 +625,5 @@ struct osi_macsec_mmc_counters { /** This counter provides the number of out octets protected */ unsigned long long tx_octets_protected; }; - -#endif +#endif /* MACSEC_SUPPORT */ +#endif /* INCLUDED_MMC_H */ \ No newline at end of file diff --git a/include/osi_core.h b/include/osi_core.h index 4667252..247f297 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -953,6 +953,12 @@ struct osd_core_ops { void (*msleep)(nveu32_t msec); /** ivcsend callback*/ nve32_t (*ivc_send)(void *priv, void *data, nveu32_t len); +#ifdef MACSEC_SUPPORT + /** Program macsec key table through Trust Zone callback */ + int (*macsec_tz_kt_config)(void *priv, unsigned char cmd, + void *const kt_config, + void *const genl_info); +#endif /* MACSEC_SUPPORT */ }; #ifdef MACSEC_SUPPORT diff --git a/include/osi_macsec.h b/include/osi_macsec.h index c5c015c..f9769f5 100644 --- a/include/osi_macsec.h +++ b/include/osi_macsec.h @@ -162,7 +162,9 @@ * 4B for FCS */ +/* macsec tz key config cmd */ #define MACSEC_CMD_TZ_CONFIG 0x1 +/* macsec tz key table entries reset cmd */ #define MACSEC_CMD_TZ_KT_RESET 0x2 /** @@ -356,7 +358,8 @@ struct osi_macsec_dbg_buf_config { */ struct macsec_core_ops { /** macsec init */ - int (*init)(struct osi_core_priv_data *const osi_core); + int (*init)(struct osi_core_priv_data *const osi_core, + void *const genl_info); /** macsec de-init */ int (*deinit)(struct osi_core_priv_data *const osi_core); /** NS irq handler */ @@ -368,7 +371,8 @@ struct macsec_core_ops { struct osi_macsec_lut_config *const lut_config); /** macsec kt config */ int (*kt_config)(struct osi_core_priv_data *const osi_core, - struct osi_macsec_kt_config *const kt_config); + struct osi_macsec_kt_config *const kt_config, + void *const genl_info); /** macsec cipher config */ int (*cipher_config)(struct osi_core_priv_data *const osi_core, unsigned int cipher); @@ -381,7 +385,8 @@ struct macsec_core_ops { /** macsec config SA in HW LUT */ int (*config)(struct osi_core_priv_data *const osi_core, struct osi_macsec_sc_info *const sc, - unsigned int enable, unsigned short ctlr); + unsigned int enable, unsigned short ctlr, + void *const genl_info); /** macsec read mmc counters */ void (*read_mmc)(struct osi_core_priv_data *const osi_core); /** macsec debug buffer config */ @@ -440,6 +445,7 @@ int osi_init_macsec_ops(struct osi_core_priv_data *const osi_core); * set BYP LUT entries for MKPDU and BC packets * * @param[in] osi_core: OSI core private data structure. + * @param[in] genl_info: Pointer to netlink genl_info data structure. * * @pre * - MACSEC should be out of reset and clocks are enabled @@ -464,7 +470,9 @@ int osi_init_macsec_ops(struct osi_core_priv_data *const osi_core); * @retval 0 on success * @retval -1 on failure */ -int osi_macsec_init(struct osi_core_priv_data *const osi_core); +int osi_macsec_init(struct osi_core_priv_data *const osi_core, + void *const genl_info); + /** * @brief De-initialize the macsec controller @@ -511,12 +519,14 @@ int osi_macsec_lut_config(struct osi_core_priv_data *const osi_core, * * @param[in] osi_core: OSI core private data structure. * @param[in] kt_config: OSI macsec KT config data structure. + * @param[in] genl_info: Pointer to netlink genl_info data structure. * * @retval 0 on success * @retval -1 on failure */ int osi_macsec_kt_config(struct osi_core_priv_data *const osi_core, - struct osi_macsec_kt_config *const kt_config); + struct osi_macsec_kt_config *const kt_config, + void *const genl_info); /** * @brief MACsec Loopback config @@ -546,16 +556,17 @@ int osi_macsec_en(struct osi_core_priv_data *const osi_core, * @brief MACsec update secure channel/association in controller * * @param[in] osi_core: OSI core private data structure. - * @param[in] tx_sa: Pointer to osi_macsec_sc_info struct for the tx SA. + * @param[in] sc: Pointer to osi_macsec_sc_info struct for the tx SA. * @param[in] enable: flag to indicate enable/disable for the Tx SA. - * @param[in] enable: Pointer to netlink message. + * @param[in] genl_info: Pointer to netlink genl_info data structure. * * @retval 0 on success * @retval -1 on failure */ int osi_macsec_config(struct osi_core_priv_data *const osi_core, struct osi_macsec_sc_info *const sc, - unsigned int enable, unsigned short ctlr); + unsigned int enable, unsigned short ctlr, + void *const genl_info); /** * @brief MACsec read statistics counters diff --git a/osi/core/macsec.c b/osi/core/macsec.c index d2e8c23..02fd2eb 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -20,7 +20,9 @@ * DEALINGS IN THE SOFTWARE. */ +#ifdef MACSEC_KEY_PROGRAM #include <linux/crypto.h> +#endif #include <osi_macsec.h> #include <linux/printk.h> #include "macsec.h" @@ -539,6 +541,7 @@ int macsec_enable(struct osi_core_priv_data *osi_core, unsigned int enable) return 0; } +#ifdef MACSEC_KEY_PROGRAM /** * @brief poll_for_kt_update - Query the status of a KT update. * @@ -656,7 +659,8 @@ static int kt_key_write(struct osi_core_priv_data *const osi_core, } static int macsec_kt_config(struct osi_core_priv_data *const osi_core, - struct osi_macsec_kt_config *const kt_config) + struct osi_macsec_kt_config *const kt_config, + void *const genl_info) { int ret = 0; unsigned int kt_config_reg = 0; @@ -720,6 +724,16 @@ static int macsec_kt_config(struct osi_core_priv_data *const osi_core, return ret; } +#else +static int macsec_kt_config(struct osi_core_priv_data *const osi_core, + struct osi_macsec_kt_config *const kt_config, + void *const genl_info) +{ + return osi_core->osd_ops.macsec_tz_kt_config(osi_core, + MACSEC_CMD_TZ_CONFIG, kt_config, genl_info); +} +#endif /* MACSEC_KEY_PROGRAM */ + /** * @brief poll_for_lut_update - Query the status of a LUT update. * @@ -2191,7 +2205,9 @@ static int macsec_loopback_config(struct osi_core_priv_data *const osi_core, static int 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}; +#endif struct macsec_table_config *table_config = &lut_config.table_config; int i, j; int ret = 0; @@ -2285,6 +2301,7 @@ static int clear_lut(struct osi_core_priv_data *const osi_core) } } +#ifdef MACSEC_KEY_PROGRAM /* Key table */ table_config = &kt_config.table_config; table_config->rw = LUT_WRITE; @@ -2292,7 +2309,7 @@ static int clear_lut(struct osi_core_priv_data *const osi_core) table_config->ctlr_sel = i; for (j = 0; j <= TABLE_INDEX_MAX; j++) { table_config->index = j; - ret = macsec_kt_config(osi_core, &kt_config); + ret = macsec_kt_config(osi_core, &kt_config, OSI_NULL); if (ret < 0) { pr_err("Error clearing KT CTLR:INDEX: %d:%d\n", i, j); @@ -2300,6 +2317,7 @@ static int clear_lut(struct osi_core_priv_data *const osi_core) } } } +#endif /* MACSEC_KEY_PROGRAM */ return ret; } @@ -2315,10 +2333,14 @@ static int macsec_deinit(struct osi_core_priv_data *const osi_core) return 0; } -static int macsec_init(struct osi_core_priv_data *const osi_core) +static int macsec_init(struct osi_core_priv_data *const osi_core, + void *const genl_info) { unsigned int val = 0; struct osi_macsec_lut_config lut_config = {0}; +#ifndef MACSEC_KEY_PROGRAM + struct osd_core_ops *osd_ops = &osi_core->osd_ops; +#endif struct macsec_table_config *table_config = &lut_config.table_config; /* Store MAC address in reverse, per HW design */ unsigned char mac_da_mkpdu[OSI_ETH_ALEN] = {0x3, 0x0, 0x0, @@ -2408,25 +2430,28 @@ static int macsec_init(struct osi_core_priv_data *const osi_core) pr_err("Write COMMON_IMR: 0x%x\n", val); osi_writela(osi_core, val, addr + COMMON_IMR); - /* 4. TODO - Route safety intr to LIC */ - val = osi_readla(osi_core, addr + INTERRUPT_MASK1_0); - pr_err("Read INTERRUPT_MASK1_0: 0x%x\n", val); - val |= SFTY_ERR_UNCORR_INT_EN; - pr_err("Write INTERRUPT_MASK1_0: 0x%x\n", val); - osi_writela(osi_core, val, addr + INTERRUPT_MASK1_0); - - /* 5. Set AES mode + /* 4. Set AES mode * Default power on reset is AES-GCM128, leave it. */ - /* 6. Invalidate LUT entries */ + /* 5. Invalidate LUT entries */ ret = clear_lut(osi_core); if (ret < 0) { pr_err("Invalidating all LUT's failed\n"); return ret; } +#ifndef MACSEC_KEY_PROGRAM + /* clear KT entries */ + ret = osd_ops->macsec_tz_kt_config(osi_core, + MACSEC_CMD_TZ_KT_RESET, + OSI_NULL, genl_info); + if (ret < 0) { + pr_err("TZ key config failed %d\n", ret); + goto exit; + } +#endif /* !MACSEC_KEY_PROGRAM */ - /* 7. Set default BYP for MKPDU/BC packets */ + /* 6. Set default BYP for MKPDU/BC packets */ table_config->rw = LUT_WRITE; lut_config.lut_sel = LUT_SEL_BYPASS; lut_config.flags |= (LUT_FLAGS_DA_VALID | @@ -2491,7 +2516,7 @@ static struct osi_macsec_sc_info *find_existing_sc( static int del_upd_sc(struct osi_core_priv_data *const osi_core, struct osi_macsec_sc_info *existing_sc, struct osi_macsec_sc_info *const sc, - unsigned short ctlr) + unsigned short ctlr, void *const genl_info) { struct osi_macsec_lut_config lut_config = {0}; struct osi_macsec_kt_config kt_config = {0}; @@ -2554,7 +2579,7 @@ static int del_upd_sc(struct osi_core_priv_data *const osi_core, /* Each SC has MAX_NUM_SA's supported in HW */ table_config->index = (existing_sc->sc_idx_start * MAX_NUM_SA) + sc->curr_an; - ret = macsec_kt_config(osi_core, &kt_config); + ret = macsec_kt_config(osi_core, &kt_config, genl_info); if (ret < 0) { pr_err("%s: Failed to del SAK", __func__); goto err_kt; @@ -2578,13 +2603,15 @@ err_sci: static int add_upd_sc(struct osi_core_priv_data *const osi_core, struct osi_macsec_sc_info *const sc, - unsigned short ctlr) + unsigned short ctlr, void *const genl_info) { struct osi_macsec_lut_config lut_config = {0}; struct osi_macsec_kt_config kt_config = {0}; struct macsec_table_config *table_config; int ret, i; -#if 1 /* HKEY GENERATION */ + +#ifdef MACSEC_KEY_PROGRAM + /* HKEY GENERATION */ /* TODO - Move this to OSD */ struct crypto_cipher *tfm; unsigned char hkey[KEY_LEN_128]; @@ -2603,7 +2630,7 @@ static int add_upd_sc(struct osi_core_priv_data *const osi_core, } pr_err("\n"); crypto_free_cipher(tfm); -#endif /* HKEY GENERATION */ +#endif /* MACSEC_KEY_PROGRAM */ /* 1. Key LUT */ table_config = &kt_config.table_config; @@ -2613,12 +2640,19 @@ static int add_upd_sc(struct osi_core_priv_data *const osi_core, table_config->index = (sc->sc_idx_start * MAX_NUM_SA) + sc->curr_an; kt_config.flags |= LUT_FLAGS_ENTRY_VALID; +#ifdef MACSEC_KEY_PROGRAM /* Program in reverse order as per HW design */ for (i = 0; i < KEY_LEN_128; i++) { kt_config.entry.sak[i] = sc->sak[KEY_LEN_128 - 1 - i]; kt_config.entry.h[i] = hkey[KEY_LEN_128 - 1 - i]; } - ret = macsec_kt_config(osi_core, &kt_config); +#else + for (i = 0; i < KEY_LEN_128; i++) { + kt_config.entry.sak[i] = sc->sak[i]; + } +#endif /* MACSEC_KEY_PROGRAM */ + + ret = macsec_kt_config(osi_core, &kt_config, genl_info); if (ret < 0) { pr_err("%s: Failed to set SAK", __func__); return -1; @@ -2711,7 +2745,8 @@ err_sa_state: static int macsec_config(struct osi_core_priv_data *const osi_core, struct osi_macsec_sc_info *const sc, - unsigned int enable, unsigned short ctlr) + unsigned int enable, unsigned short ctlr, + void *const genl_info) { struct osi_macsec_sc_info *existing_sc = OSI_NULL, *new_sc = OSI_NULL; struct osi_macsec_sc_info tmp_sc; @@ -2773,7 +2808,7 @@ static int macsec_config(struct osi_core_priv_data *const osi_core, } pr_err(""); - if (add_upd_sc(osi_core, new_sc, ctlr) != OSI_NONE) { + if (add_upd_sc(osi_core, new_sc, ctlr, genl_info) != OSI_NONE) { pr_err("%s: failed to add new SC", __func__); /* TODO - remove new_sc from lut_status[] ? * not needed for now, as next_sc_idx is not @@ -2794,7 +2829,7 @@ static int macsec_config(struct osi_core_priv_data *const osi_core, pr_err("%s: Updating existing SC", __func__); if (enable == OSI_DISABLE) { pr_err("%s: Deleting existing SA", __func__); - if (del_upd_sc(osi_core, existing_sc, sc, ctlr) != + if (del_upd_sc(osi_core, existing_sc, sc, ctlr, genl_info) != OSI_NONE) { pr_err("%s: failed to del SA", __func__); return -1; @@ -2837,7 +2872,8 @@ static int macsec_config(struct osi_core_priv_data *const osi_core, } pr_err(""); - if (add_upd_sc(osi_core, tmp_sc_p, ctlr) != OSI_NONE) { + if (add_upd_sc(osi_core, tmp_sc_p, ctlr, genl_info) != + OSI_NONE) { pr_err("%s: failed to add new SA", __func__); /* TODO - remove new_sc from lut_status[] ? * not needed for now, as next_sc_idx is not @@ -2845,10 +2881,10 @@ static int macsec_config(struct osi_core_priv_data *const osi_core, */ return -1; } else { - /* Update lut status */ - lut_status->next_sc_idx++; - pr_err("%s: Added new SA ctlr: %u", - __func__, ctlr); + pr_err("%s: Updated new SC ctlr: %u " + "nxt_sc_idx: %u", + __func__, ctlr, + lut_status->next_sc_idx); /* Now commit the changes */ *existing_sc = *tmp_sc_p; return 0; @@ -2877,7 +2913,8 @@ static struct osi_macsec_lut_status lut_status[NUM_CTLR]; int osi_init_macsec_ops(struct osi_core_priv_data *const osi_core) { - if (osi_core->macsec_base == OSI_NULL) { + if (osi_core->macsec_base == OSI_NULL || + osi_core->osd_ops.macsec_tz_kt_config == OSI_NULL) { return -1; } else { osi_core->macsec_ops = &macsec_ops; @@ -2886,11 +2923,12 @@ int osi_init_macsec_ops(struct osi_core_priv_data *const osi_core) } } -int osi_macsec_init(struct osi_core_priv_data *const osi_core) +int osi_macsec_init(struct osi_core_priv_data *const osi_core, + void *const genl_info) { 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); + return osi_core->macsec_ops->init(osi_core, genl_info); } return -1; @@ -2933,12 +2971,14 @@ int osi_macsec_lut_config(struct osi_core_priv_data *const osi_core, } int osi_macsec_kt_config(struct osi_core_priv_data *const osi_core, - struct osi_macsec_kt_config *const kt_config) + struct osi_macsec_kt_config *const kt_config, + void *const genl_info) { 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 osi_core->macsec_ops->kt_config(osi_core, kt_config, + genl_info); } return -1; @@ -2975,7 +3015,8 @@ int osi_macsec_en(struct osi_core_priv_data *const osi_core, int osi_macsec_config(struct osi_core_priv_data *const osi_core, struct osi_macsec_sc_info *const sc, - unsigned int enable, unsigned short ctlr) + unsigned int enable, unsigned short ctlr, + void *const genl_info) { if ((enable != OSI_ENABLE && enable != OSI_DISABLE) || (ctlr != CTLR_SEL_TX && ctlr != CTLR_SEL_RX)) { @@ -2985,7 +3026,7 @@ int osi_macsec_config(struct osi_core_priv_data *const osi_core, 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); + enable, ctlr, genl_info); } return -1; From 4b208ee617696242f545a2f2917e6a9012f3e546 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Fri, 16 Apr 2021 19:01:06 +0530 Subject: [PATCH 218/458] osi: fix build errors for MACSec IVC ops Bug 200671160 Change-Id: I02e2753db3d7c196a67e62aca7a4853471605e97 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2516096 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> --- osi/core/ivc_core.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index 468a136..ccea0d6 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -1505,13 +1505,15 @@ static void ivc_macsec_read_mmc(struct osi_core_priv_data *const osi_core) * @param[in] sc: Secure Channel info. * @param[in] enable: enable or disable. * @param[in] ctlr: Controller instance. + * @param[in] genl_info: Generic netlink information structure. * * @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 int enable, unsigned short ctlr, + void *const genl_info) { return 0; } @@ -1551,12 +1553,14 @@ static int ivc_macsec_loopback_config(struct osi_core_priv_data *const osi_core, * * @param[in] osi_core: OSI Core private data structure. * @param[in] kt_config: KT config structure. + * @param[in] genl_info: Generic netlink information structure. * * @retval 0 on Success * @retval -1 on Failure */ static int ivc_macsec_kt_config(struct osi_core_priv_data *const osi_core, - struct osi_macsec_kt_config *const kt_config) + struct osi_macsec_kt_config *const kt_config, + void *const genl_info) { return 0; } @@ -1616,11 +1620,13 @@ static int ivc_macsec_deinit(struct osi_core_priv_data *const osi_core) * @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) +static int ivc_macsec_init(struct osi_core_priv_data *const osi_core, + void *const genl_info) { return 0; } From be0f9c150914867073865c0f08c3dd4b3274f776 Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Wed, 17 Mar 2021 15:11:25 +0530 Subject: [PATCH 219/458] nvethernetrm: add interface operations for virtualization/non-virtualization Issue: In current implementation virualization callback are at HW ops level, which leads to multiple IVC calls. Fix: - IVC call happens only for core API's in case virtualization - For non-virtualization case HW operations will be invoked directly from OS OSD. - From Ethernet server OSD - OSI HAL API's should be called to access the HW operations Bug 200671160 Change-Id: Ic3730fb822ae37fdf29fabf429f18f5d5bacd210 Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2509243 Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> --- include/ivc_core.h | 5 + include/osi_core.h | 317 ++++++++ osi/core/Makefile.sdk | 1 + osi/core/Makefile.tmk | 1 + osi/core/core_local.h | 61 ++ osi/core/ivc_core.c | 69 ++ osi/core/mgbe_core.c | 4 +- osi/core/osi_core.c | 1605 +++-------------------------------------- osi/core/osi_hal.c | 1590 ++++++++++++++++++++++++++++++++++++++++ osi/dma/osi_dma.c | 5 +- 10 files changed, 2164 insertions(+), 1494 deletions(-) create mode 100644 osi/core/osi_hal.c diff --git a/include/ivc_core.h b/include/ivc_core.h index cb37ba8..d9ba66c 100644 --- a/include/ivc_core.h +++ b/include/ivc_core.h @@ -68,6 +68,7 @@ typedef enum ivc_cmd { reg_read, reg_write, get_hw_features, + handle_ioctl, #ifndef OSI_STRIPPED_LIB config_tx_status, config_rx_crc_check, @@ -179,6 +180,10 @@ typedef struct ivc_msg_common { * core argument structure */ ivc_core_args init_args; + /** + * ioctl command structure + */ + struct osi_ioctl ioctl_data; }data; } ivc_msg_common; diff --git a/include/osi_core.h b/include/osi_core.h index 247f297..b04a152 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -2212,4 +2212,321 @@ nve32_t osi_handle_ioctl(struct osi_core_priv_data *osi_core, * @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 + * + * @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: + * + * @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. + */ +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 + * + * @note + * Classification: + * - Interrupt: No + * - Signal handler: No + * - Thread safe: No + * - Required Privileges: None + * + * @note + * 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 + * + * @note + * Classification: + * - Interrupt: No + * - Signal handler: No + * - Thread safe: No + * - Required Privileges: None + * + * @note + * 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 + * + * @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. + */ +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 + * + * @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 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/osi/core/Makefile.sdk b/osi/core/Makefile.sdk index ecabc4c..fc79ef8 100644 --- a/osi/core/Makefile.sdk +++ b/osi/core/Makefile.sdk @@ -26,6 +26,7 @@ OBJS += frp.o OBJS += mgbe_core.o OBJS += xpcs.o OBJS += mgbe_mmc.o +OBJS += osi_hal.o OBJS += ivc_core.o OBJS += ./../common/osi_common.o OBJS += ./../common/eqos_common.o diff --git a/osi/core/Makefile.tmk b/osi/core/Makefile.tmk index 95afd03..3626205 100644 --- a/osi/core/Makefile.tmk +++ b/osi/core/Makefile.tmk @@ -34,6 +34,7 @@ NV_COMPONENT_SOURCES := \ eqos_mmc.c \ osi_core.c \ vlan_filter.c \ + osi_hal.c \ ivc_core.c \ frp.c \ mgbe_core.c \ diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 5a31274..1ea5ef2 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -32,6 +32,36 @@ #define MAX_CORE_INSTANCES 5U #endif +/** + * @brief Maximum number of interface operations. + */ +#define MAX_INTERFACE_OPS 2U + +/** + * 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. */ @@ -241,8 +271,12 @@ struct core_local { 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; /** 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; }; @@ -298,4 +332,31 @@ void mgbe_init_core_ops(struct core_ops *ops); * - 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); + #endif /* INCLUDED_CORE_LOCAL_H */ diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index ccea0d6..f22e19c 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -904,6 +904,35 @@ static nve32_t ivc_write_phy_reg(struct osi_core_priv_data *const osi_core, sizeof(msg_common)); } +/** + * @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 msg_common; + + osi_memset(&msg_common, 0, sizeof(msg_common)); + + msg_common.cmd = handle_ioctl; + osi_memcpy((void *)&msg_common.data.ioctl_data, (void *)data, + sizeof(struct osi_ioctl)); + ret = osi_core->osd_ops.ivc_send(osi_core, &msg_common, + sizeof(msg_common)); + osi_memcpy((void *)data, (void *)&msg_common.data.ioctl_data, + sizeof(struct osi_ioctl)); + return ret; +} + /** * @brief ivc_read_phy_reg - Read from a PHY register through MAC over MDIO bus * @@ -1726,3 +1755,43 @@ 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(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/mgbe_core.c b/osi/core/mgbe_core.c index 8463697..aca72bd 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -2997,10 +2997,10 @@ static nve32_t mgbe_core_init(struct osi_core_priv_data *osi_core, osi_writela(osi_core, value, (unsigned char *)osi_core->base + MGBE_MTL_RXQ_DMA_MAP2); - /* Enable XDCS in MAC_Extended_Configuration */ + /* Enable XDCS in MAC_Extended_Configuration, enable with @rakesh CL */ value = osi_readla(osi_core, (nveu8_t *)osi_core->base + MGBE_MAC_EXT_CNF); - value |= MGBE_MAC_EXT_CNF_DDS; + //value |= MGBE_MAC_EXT_CNF_DDS; osi_writela(osi_core, value, (nveu8_t *)osi_core->base + MGBE_MAC_EXT_CNF); diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 9092f53..51a8f15 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -24,18 +24,85 @@ #include <ivc_core.h> #include "core_local.h" #include "../osi/common/common.h" -#include "vlan_filter.h" -#include "frp.h" /** - * @brief g_core - Static core local data array. + * @brief g_core - Static core local data array */ static struct core_local g_core[MAX_CORE_INSTANCES]; /** - * @brief g_ops - Static core operations array. + * @brief if_ops - Static core interface operations for virtual/non-virtual + * case */ -static struct core_ops g_ops[MAX_MAC_IP_TYPES]; +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) { @@ -58,74 +125,42 @@ struct osi_core_priv_data *osi_get_core(void) return &g_core[i].osi_core; } -/** - * @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) +nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_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)) { + struct core_local *l_core = (struct core_local *)osi_core; + nve32_t ret = -1; + + if (osi_core == OSI_NULL) { 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) -{ -#if 0 - 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) { - return -1; - } - - l_ops++; + if (osi_core->use_virtualization > OSI_ENABLE) { + return ret; } -#endif - return 0; + + 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->if_init_done = OSI_ENABLE; + + return ret; } nve32_t osi_write_phy_reg(struct osi_core_priv_data *const osi_core, @@ -134,11 +169,12 @@ nve32_t osi_write_phy_reg(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) { + if (validate_if_args(osi_core, l_core) < 0) { return -1; } - return l_core->ops_p->write_phy_reg(osi_core, phyaddr, phyreg, phydata); + 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, @@ -146,107 +182,11 @@ nve32_t osi_read_phy_reg(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) { + if (validate_if_args(osi_core, l_core) < 0) { return -1; } - return l_core->ops_p->read_phy_reg(osi_core, phyaddr, phyreg); -} - -nve32_t osi_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, ivc_init_core_ops }, - { mgbe_init_core_ops, ivc_init_core_ops } - }; - - 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) || - (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: Initilize 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; + 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, @@ -254,1355 +194,40 @@ nve32_t osi_hw_core_init(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) { + if (validate_if_args(osi_core, l_core) < 0) { return -1; } - init_vlan_filters(osi_core); - - /* Init FRP */ - init_frp(osi_core); - - return l_core->ops_p->core_init(osi_core, tx_fifo_size, rx_fifo_size); + 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_args(osi_core, l_core) < 0) { + if (validate_if_args(osi_core, l_core) < 0) { return -1; } - l_core->ops_p->core_deinit(osi_core); - - 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", - 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", - 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", - 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", - 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", - 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", - 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", - 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", - 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; - } - - 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 (validate_args(osi_core, l_core) < 0) { - return -1; - } - - 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 (is_valid_mac_version(*mac_ver) == 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_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 (validate_args(osi_core, l_core) < 0) { - return -1; - } - - 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); + 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; - struct core_ops *ops_p; nve32_t ret = -1; - if (validate_args(osi_core, l_core) < 0) { + if (validate_if_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 ret; } - 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); - break; - - case OSI_CMD_ADJ_TIME: - ret = osi_adjust_time(osi_core, data->arg8_64); - break; - - case OSI_CMD_CONFIG_PTP: - ret = osi_ptp_configuration(osi_core, data->arg1_u32); - 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); - 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; - - 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); + 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 new file mode 100644 index 0000000..e26b98f --- /dev/null +++ b/osi/core/osi_hal.c @@ -0,0 +1,1590 @@ +/* + * 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. + */ + +#include <local_common.h> +#include <ivc_core.h> +#include "core_local.h" +#include "../osi/common/common.h" +#include "vlan_filter.h" +#include "frp.h" + +/** + * @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) +{ +#if 0 + 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) { + return -1; + } + + l_ops++; + } +#endif + 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) || + (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; + + if (validate_args(osi_core, l_core) < 0) { + return -1; + } + + init_vlan_filters(osi_core); + + /* Init FRP */ + init_frp(osi_core); + + return l_core->ops_p->core_init(osi_core, tx_fifo_size, rx_fifo_size); +} + +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->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; + } + + 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 (is_valid_mac_version(*mac_ver) == 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); +} + +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 (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); + break; + + case OSI_CMD_ADJ_TIME: + ret = osi_adjust_time(osi_core, data->arg8_64); + break; + + case OSI_CMD_CONFIG_PTP: + ret = osi_ptp_configuration(osi_core, data->arg1_u32); + 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); + 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; + + 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/dma/osi_dma.c b/osi/dma/osi_dma.c index 09e1537..392089d 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -324,8 +324,9 @@ nve32_t osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma) l_dma->ops_p->stop_dma(osi_dma, osi_dma->dma_chans[i]); } - l_dma->magic_num = 0; - l_dma->init_done = OSI_DISABLE; + /* FIXME: Need to fix */ +// l_dma->magic_num = 0; +// l_dma->init_done = OSI_DISABLE; return 0; } From f88d5cdd5a341191171d62b5dc36404a80029981 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Tue, 20 Apr 2021 15:53:20 +0530 Subject: [PATCH 220/458] osi: enable validation of function pointer Function pointer mgbe_validate_dma_regs() missing for mgbe which resulted in failure. Adding dummy function to make sure validate function pointers will pass. Bug 200671160 Change-Id: I4c998c86b56451e180e4ee0614192b6100d88bde Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2517631 Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> --- osi/core/osi_hal.c | 6 ++++-- osi/dma/mgbe_dma.c | 34 +++++++++++++++++++++++++++++++++- osi/dma/osi_dma.c | 10 ++++++---- 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index e26b98f..8e625ab 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -77,7 +77,6 @@ static inline nve32_t validate_args(struct osi_core_priv_data *const osi_core, static nve32_t validate_func_ptrs(struct osi_core_priv_data *const osi_core, struct core_ops *ops_p) { -#if 0 nveu32_t i = 0; void *temp_ops = (void *)ops_p; #if __SIZEOF_POINTER__ == 8 @@ -92,12 +91,15 @@ static nve32_t validate_func_ptrs(struct osi_core_priv_data *const osi_core, 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++; } -#endif + return 0; } diff --git a/osi/dma/mgbe_dma.c b/osi/dma/mgbe_dma.c index 901fb33..2d667c5 100644 --- a/osi/dma/mgbe_dma.c +++ b/osi/dma/mgbe_dma.c @@ -623,6 +623,38 @@ static void mgbe_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) ~(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(struct osi_dma_priv_data *osi_dma) +{ + /* TODO: for mgbe */ + return 0; +} + /** * @brief mgbe_get_global_dma_status - Gets DMA status. * @@ -729,7 +761,7 @@ void mgbe_init_dma_chan_ops(struct dma_chan_ops *ops) 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 = OSI_NULL; + ops->validate_regs = mgbe_validate_dma_regs; ops->get_global_dma_status = mgbe_get_global_dma_status; ops->clear_vm_tx_intr = mgbe_clear_vm_tx_intr; ops->clear_vm_rx_intr = mgbe_clear_vm_rx_intr; diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 392089d..fe09b36 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -156,7 +156,6 @@ static inline nve32_t validate_dma_chans(struct osi_dma_priv_data *osi_dma) static nve32_t validate_func_ptrs(struct osi_dma_priv_data *osi_dma, struct dma_chan_ops *ops_p) { -#if 0 nveu32_t i = 0; void *temp_ops = (void *)ops_p; #if __SIZEOF_POINTER__ == 8 @@ -164,19 +163,22 @@ static nve32_t validate_func_ptrs(struct osi_dma_priv_data *osi_dma, #elif __SIZEOF_POINTER__ == 4 nveu32_t *l_ops = (nveu32_t *)temp_ops; #else - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "DMA: Undefined architecture\n", 0ULL); + 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++; } -#endif + return 0; } From 041a918578186a7199bb5d300cf6f567fdeb8d4b Mon Sep 17 00:00:00 2001 From: praveen <pbajantri@nvidia.com> Date: Thu, 4 Feb 2021 22:36:40 -0800 Subject: [PATCH 221/458] osi: eqos: Add support for clause 45 direct access - Add support for clause 45 direct access. Jira ESDP-11141 Bug 200713249 Change-Id: I647ccc3f57ab35cf4b9e7ef098d807d636dcb692 Signed-off-by: praveen <pbajantri@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2480826 Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2517425 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Tested-by: Rakesh Goyal <rgoyal@nvidia.com> --- include/osi_core.h | 2 + osi/core/eqos_core.c | 128 ++++++++++++++++++++++++++++--------------- osi/core/eqos_core.h | 4 ++ 3 files changed, 91 insertions(+), 43 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index b04a152..3c8a513 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -143,6 +143,8 @@ typedef my_lint_64 nvel64_t; #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) /** @} */ /** diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 62f70fe..8c61fcd 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -4476,6 +4476,7 @@ static nve32_t eqos_write_phy_reg(struct osi_core_priv_data *const osi_core, { 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 */ @@ -4485,40 +4486,57 @@ static nve32_t eqos_write_phy_reg(struct osi_core_priv_data *const osi_core, return ret; } - 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)); + /* 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); - 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 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); + /* 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 */ - ret = poll_for_mii_idle(osi_core); - if (ret < 0) { - /* poll_for_mii_idle fail */ - return ret; - } - - return ret; + return poll_for_mii_idle(osi_core); } /** @@ -4557,29 +4575,53 @@ static nve32_t eqos_read_phy_reg(struct osi_core_priv_data *const osi_core, 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 */ + /* 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); + } - 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); diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 473a7d0..1be72a8 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -439,6 +439,10 @@ #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) From 2e9019287f1143c2c5ff93faa804c5a51e535397 Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Wed, 21 Apr 2021 09:32:11 +0530 Subject: [PATCH 222/458] core: fix get_core init_done check Issue: In case of virtualization, init_done for VM's osi_core is not set which leads to give same osi_core in case of other VM. Fix: osi_get_core check for if_init_done instead of init_done Change-Id: Ib8ffe156723685b4f7fde1f197df3c2c589f75ac Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2518053 Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> --- osi/core/osi_core.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 51a8f15..be73b6c 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -109,7 +109,7 @@ struct osi_core_priv_data *osi_get_core(void) nveu32_t i; for (i = 0U; i < MAX_CORE_INSTANCES; i++) { - if (g_core[i].init_done == OSI_ENABLE) { + if (g_core[i].if_init_done == OSI_ENABLE) { continue; } @@ -138,6 +138,11 @@ nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core) 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) { From 7fb6383f2893f38d7160e5894f277d7d514c12a2 Mon Sep 17 00:00:00 2001 From: Mahesh Patil <maheshp@nvidia.com> Date: Fri, 12 Feb 2021 12:05:41 -0800 Subject: [PATCH 223/458] nvethernetrm: Add aes 128/256bit macsec config Adding aes 128/256 bit config support through sysfs node Bug 3257779 Change-Id: Ic1736b309a28faa7591184167a94156ca816fb57 Signed-off-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2484200 Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> --- include/osi_macsec.h | 16 ++++++++++++++++ osi/core/macsec.c | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/include/osi_macsec.h b/include/osi_macsec.h index f9769f5..4164ac1 100644 --- a/include/osi_macsec.h +++ b/include/osi_macsec.h @@ -167,6 +167,10 @@ /* macsec tz key table entries reset cmd */ #define MACSEC_CMD_TZ_KT_RESET 0x2 +/* AES cipthers 128 bit or 256 bit */ +#define MACSEC_CIPHER_AES128 0U +#define MACSEC_CIPHER_AES256 1U + /** * @brief MACsec SA State LUT entry outputs structure */ @@ -528,6 +532,18 @@ int osi_macsec_kt_config(struct osi_core_priv_data *const osi_core, struct osi_macsec_kt_config *const kt_config, void *const genl_info); +/** + * @brief MACsec cipther config + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] cipher: AES cipher to be configured to controller. + * + * @retval 0 on success + * @retval -1 on failure + */ +int osi_macsec_cipher_config(struct osi_core_priv_data *const osi_core, + unsigned int cipher); + /** * @brief MACsec Loopback config * diff --git a/osi/core/macsec.c b/osi/core/macsec.c index 02fd2eb..9a409cd 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -2180,6 +2180,32 @@ static void macsec_handle_s_irq(struct osi_core_priv_data *const osi_core) return; } +static int macsec_cipher_config(struct osi_core_priv_data *const osi_core, + unsigned int cipher) +{ + unsigned char *base = (unsigned char *)osi_core->macsec_base; + unsigned int val; + + val = osi_readla(osi_core, base + GCM_AES_CONTROL_0); + pr_err("Read GCM_AES_CONTROL_0: 0x%x\n", val); + + val &= ~TX_AES_MODE_MASK; + val &= ~RX_AES_MODE_MASK; + if (cipher == MACSEC_CIPHER_AES128) { + val |= TX_AES_MODE_AES128; + val |= RX_AES_MODE_AES128; + } else if (cipher == MACSEC_CIPHER_AES256) { + val |= TX_AES_MODE_AES256; + val |= RX_AES_MODE_AES256; + } else { + return -1; + } + + pr_err("Write GCM_AES_CONTROL_0: 0x%x\n", val); + osi_writela(osi_core val, base + GCM_AES_CONTROL_0); + return 0; +} + static int macsec_loopback_config(struct osi_core_priv_data *const osi_core, unsigned int enable) { @@ -2901,6 +2927,7 @@ static struct macsec_core_ops macsec_ops = { .handle_s_irq = macsec_handle_s_irq, .lut_config = macsec_lut_config, .kt_config = macsec_kt_config, + .cipher_config = macsec_cipher_config, .loopback_config = macsec_loopback_config, .macsec_en = macsec_enable, .config = macsec_config, @@ -2984,6 +3011,17 @@ int osi_macsec_kt_config(struct osi_core_priv_data *const osi_core, return -1; } +int osi_macsec_cipher_config(struct osi_core_priv_data *const osi_core, + unsigned int 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; +} + int osi_macsec_loopback(struct osi_core_priv_data *const osi_core, unsigned int enable) { From 662786ec865a5b0be795f9b6565ab0b7097fa329 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Fri, 30 Apr 2021 14:06:34 +0530 Subject: [PATCH 224/458] osi: macsec: fix build issue Bug 200722499 Change-Id: I75cd89350954bc8ed7632ec0788d2efe7c6848aa Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2522868 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Gaurav Asati <gasati@nvidia.com> --- osi/core/macsec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osi/core/macsec.c b/osi/core/macsec.c index 9a409cd..641c39e 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -2202,7 +2202,7 @@ static int macsec_cipher_config(struct osi_core_priv_data *const osi_core, } pr_err("Write GCM_AES_CONTROL_0: 0x%x\n", val); - osi_writela(osi_core val, base + GCM_AES_CONTROL_0); + osi_writela(osi_core, val, base + GCM_AES_CONTROL_0); return 0; } From 57f73c336ca11c5ebbdfd42e2ad36f6145c8d703 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Fri, 23 Apr 2021 16:00:06 +0530 Subject: [PATCH 225/458] osi: dma: update default PTP configuration flags If OSD doesn't set PTP mode via ptp_flag, set PTP configuration to PTP sync in two step sync with slave mode. Bug 200722499 Change-Id: I4572f457405db1982458da406f94d3be47c339c2 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2523248 Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> --- osi/dma/osi_dma.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index fe09b36..9be44a4 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -298,6 +298,14 @@ nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) 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; } From 8019d07ef90e46686fb7126d64a9af98e216c8ac Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Wed, 14 Apr 2021 12:37:30 +0530 Subject: [PATCH 226/458] osi: Update export API's Add newly created API's for OSI core and DMA and remove deprecated API's. Bug 200671160 Change-Id: I719a07fe909d98c5d669f8998233427def7fb29e Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2517727 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> --- osi/core/libnvethernetrm.export | 20 ++------------------ osi/dma/libnvethernetcl.export | 8 +++----- 2 files changed, 5 insertions(+), 23 deletions(-) diff --git a/osi/core/libnvethernetrm.export b/osi/core/libnvethernetrm.export index 88934be..2383430 100644 --- a/osi/core/libnvethernetrm.export +++ b/osi/core/libnvethernetrm.export @@ -26,23 +26,7 @@ osi_init_core_ops osi_write_phy_reg osi_read_phy_reg -osi_poll_for_mac_reset_complete osi_hw_core_init osi_hw_core_deinit -osi_start_mac -osi_stop_mac -osi_common_isr -osi_set_mode -osi_set_speed -osi_pad_calibrate -osi_get_mac_version -osi_get_hw_features -osi_config_rxcsum_offload -osi_l2_filter -osi_l3l4_filter -osi_config_fw_err_pkts -osi_ptp_configuration -osi_adjust_time -osi_adjust_freq -osi_set_systime_to_mac -osi_read_mmc +osi_get_core +osi_handle_ioctl diff --git a/osi/dma/libnvethernetcl.export b/osi/dma/libnvethernetcl.export index 2cc1dbe..776b13f 100644 --- a/osi/dma/libnvethernetcl.export +++ b/osi/dma/libnvethernetcl.export @@ -1,6 +1,6 @@ ################################### tell Emacs this is a -*- makefile-gmake -*- # -# Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2019-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"), @@ -23,10 +23,6 @@ # libnvethernetcl interface export # ############################################################################### -osi_disable_chan_tx_intr -osi_enable_chan_tx_intr -osi_disable_chan_rx_intr -osi_enable_chan_rx_intr osi_start_dma osi_stop_dma osi_get_refill_rx_desc_cnt @@ -40,3 +36,5 @@ 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 From dc2eb710f25edc23c894f0acaec39ef3abee8479 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Wed, 14 Apr 2021 11:35:46 +0530 Subject: [PATCH 227/458] osi: core: fix eqos return codes and disable PDC Disable PDC support as current code is not complete. Update return values as successfor PTP supporting API's. Bug 200671160 Change-Id: I778d51503bb2213ae623aa6bb18e16a8557337f3 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2523244 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> --- osi/core/eqos_core.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 8c61fcd..a32ddc5 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1551,10 +1551,10 @@ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) eqos_core_safety_writel(osi_core, value, (nveu8_t *)osi_core->base + EQOS_MAC_MCR, EQOS_MAC_MCR_IDX); - /* Enable PDC */ value = osi_readla(osi_core, (unsigned char *)osi_core->base + EQOS_MAC_EXTR); - value |= EQOS_MAC_EXTR_PDC; + /* TODO: Re-enable PDC along with packet duplication */ + /* value |= EQOS_MAC_EXTR_PDC; */ osi_writela(osi_core, value, (unsigned char *)osi_core->base + EQOS_MAC_EXTR); @@ -3488,7 +3488,7 @@ static inline nve32_t eqos_poll_for_tsinit_complete( osi_core->osd_ops.udelay(OSI_DELAY_1000US); } - return -1; + return 0; } /** @@ -3602,7 +3602,7 @@ static inline nve32_t eqos_poll_for_addend_complete( osi_core->osd_ops.udelay(OSI_DELAY_1000US); } - return -1; + return 0; } /** @@ -3916,7 +3916,7 @@ static int eqos_config_ptp_rxq(struct osi_core_priv_data *osi_core, /* 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 -1; + return 0; } /* Validate enable argument */ From 69e84525e1731c22288b7537bffd358097bbfec3 Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Tue, 23 Mar 2021 15:52:35 +0530 Subject: [PATCH 228/458] nvethernetrm: eqos: enable MC/BC packet duplication 1) Enable MC/BC packet duplication 2) All MC/BC packets route to highest MTL queue 3) Remove setting MAC address as part of hw_core_init API. Now OSD should set it. 4) Handle lower mac version as packet duplication is not supported. Bug 200711542 Bug 200711544 Bug 200713215 Change-Id: I7034d5920e3c0d1a16c2694696f14647421550e8 Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2508690 Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> --- osi/core/eqos_core.c | 198 ++++++++++++++++++++++++++++--------------- osi/core/eqos_core.h | 3 +- osi/core/mgbe_core.c | 76 +++++++++-------- 3 files changed, 174 insertions(+), 103 deletions(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index a32ddc5..705294d 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1480,7 +1480,6 @@ static void eqos_configure_rxq_priority( * Algorithm: * - This takes care of configuring the below * parameters for the MAC - * - Programming the MAC address * - Enable required MAC control fields in MCR * - Enable JE/JD/WD/GPSLCE based on the MTU size * - Enable Multicast and Broadcast Queue @@ -1499,24 +1498,9 @@ static void eqos_configure_rxq_priority( */ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) { - nveu32_t value, i = 0U, max_queue = 0U; + nveu32_t value; nveu32_t mac_ext; - /* Update MAC address 0 high */ - value = (((nveu32_t)osi_core->mac_addr[5] << 8U) | - ((nveu32_t)osi_core->mac_addr[4])); - eqos_core_safety_writel(osi_core, value, - (nveu8_t *)osi_core->base + - EQOS_MAC_MA0HR, EQOS_MAC_MA0HR_IDX); - - /* Update MAC address 0 Low */ - value = (((nveu32_t)osi_core->mac_addr[3] << 24U) | - ((nveu32_t)osi_core->mac_addr[2] << 16U) | - ((nveu32_t)osi_core->mac_addr[1] << 8U) | - ((nveu32_t)osi_core->mac_addr[0])); - eqos_core_safety_writel(osi_core, value, (nveu8_t *)osi_core->base + - EQOS_MAC_MA0LR, EQOS_MAC_MA0LR_IDX); - /* Read MAC Configuration Register */ value = osi_readla(osi_core, (nveu8_t *)osi_core->base + EQOS_MAC_MCR); @@ -1551,28 +1535,27 @@ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) eqos_core_safety_writel(osi_core, value, (nveu8_t *)osi_core->base + EQOS_MAC_MCR, EQOS_MAC_MCR_IDX); - value = osi_readla(osi_core, - (unsigned char *)osi_core->base + EQOS_MAC_EXTR); - /* TODO: Re-enable PDC along with packet duplication */ - /* value |= EQOS_MAC_EXTR_PDC; */ - osi_writela(osi_core, value, - (unsigned char *)osi_core->base + EQOS_MAC_EXTR); + /* 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; - /* 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]; - } - } + + /* Routing Multicast and Broadcast depending on mac version */ value &= ~(EQOS_MAC_RQC1R_MCBCQ); - value |= (max_queue << EQOS_MAC_RQC1R_MCBCQ_SHIFT); - eqos_core_safety_writel(osi_core, value, (unsigned char *)osi_core->base + + 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 */ @@ -2550,13 +2533,12 @@ static nve32_t eqos_config_mac_pkt_filter_reg( * @note * Algorithm: * - This helper routine is to update passed parameter value - * based on DCS and MBC parameter. Validation of dma_chan as well as - * dsc_en status performed before updating DCS bits. + * based on DCS and MBC parameter. Validation of dsc_en status performed + * before updating DCS bits. * * @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 * @param[in] addr_mask: filter will not consider byte in comparison * Bit 5: MAC_Address${i}_High[15:8] @@ -2564,6 +2546,7 @@ static nve32_t eqos_config_mac_pkt_filter_reg( * Bit 3: MAC_Address${i}_Low[31:24] * .. * Bit 0: MAC_Address${i}_Low[7:0] + * @pram[in] src_dest: Source/Destination Address match * * @pre * - MAC should be initialized and started. see osi_start_mac() @@ -2579,30 +2562,32 @@ static nve32_t eqos_config_mac_pkt_filter_reg( * @retval -1 on failure. */ static inline nve32_t eqos_update_mac_addr_helper( - struct osi_core_priv_data *const osi_core, + const 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, - const nveu32_t addr_mask) + const nveu32_t addr_mask, + const nveu32_t src_dest) { - /* PDC bit of MAC_Ext_Configuration register is not set so binary - * value representation. + 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 (dma_routing_enable == OSI_ENABLE) { - if ((dma_chan < OSI_EQOS_MAX_NUM_CHANS) && - (osi_core->dcs_en == OSI_ENABLE)) { - *value = ((dma_chan << EQOS_MAC_ADDRH_DCS_SHIFT) & - EQOS_MAC_ADDRH_DCS); - } else if ((dma_chan == OSI_CHAN_ANY) || - (dma_chan > (OSI_EQOS_MAX_NUM_CHANS - 0x1U))) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, - "invalid dma channel\n", - (nveul64_t)dma_chan); - return -1; - } else { - /* Do nothing */ - } + 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 */ @@ -2623,6 +2608,71 @@ static inline nve32_t eqos_update_mac_addr_helper( 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; + + 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 |= (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 @@ -2659,36 +2709,48 @@ static nve32_t eqos_update_mac_addr_low_high_reg( nveu32_t dma_chan = filter->dma_chan; nveu32_t addr_mask = filter->addr_mask; nveu32_t src_dest = filter->src_dest; - nveu32_t value = 0x0U; + nveu32_t value = OSI_DISABLE; nve32_t ret = 0; - if (idx > (EQOS_MAX_MAC_ADDRESS_FILTER - 0x1U)) { + 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\n", 0ULL); + "invalid MAC filter index or channel number\n", + 0ULL); return -1; } - ret = eqos_update_mac_addr_helper(osi_core, &value, idx, - dma_routing_enable, dma_chan, - addr_mask); + /* 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; } - /* 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) || (src_dest == OSI_DA_MATCH))) { - value = (value | ((src_dest << EQOS_MAC_ADDRH_SA_SHIFT) & - EQOS_MAC_ADDRH_SA)); - } - /* 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))); diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 1be72a8..d9dfc11 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -244,9 +244,10 @@ #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_MCBCQ1 OSI_BIT(16) #define EQOS_MAC_RQC1R_FPRQ (OSI_BIT(26) | OSI_BIT(25) | \ OSI_BIT(24)) #define EQOS_MAC_RQC1R_FPRQ_SHIFT 24U diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index aca72bd..058c32d 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -569,12 +569,12 @@ static int mgbe_update_mac_addr_low_high_reg( 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; 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; @@ -584,20 +584,44 @@ static int mgbe_update_mac_addr_low_high_reg( return -1; } - /* High address clean should happen for filter index >= 0 */ - if (addr == OSI_NULL) { - osi_writela(osi_core, OSI_DISABLE, - (unsigned char *)osi_core->base + + 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); + } + + osi_writela(osi_core, value, (nveu8_t *)osi_core->base + MGBE_MAC_ADDRH((idx))); return 0; } - /* Add DMA channel to value if DCS enabled */ - if ((dma_routing_enable == OSI_ENABLE) && - (osi_core->dcs_en == OSI_ENABLE)) { - value = ((dma_chan << MGBE_MAC_ADDRH_DCS_SHIFT) & + /* 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 */ @@ -622,14 +646,12 @@ static int mgbe_update_mac_addr_low_high_reg( (unsigned char *)osi_core->base + MGBE_MAC_ADDRL((idx))); /* Write XDCS configuration into MAC_DChSel_IndReg(x) */ - if (dma_routing_enable == OSI_ENABLE) { - /* Append DCS DMA channel to XDCS hot bit selection */ - dma_chansel |= (OSI_ENABLE << dma_chan); - ret = mgbe_mac_indir_addr_write(osi_core, - MGBE_MAC_DCHSEL, - idx, - dma_chansel); - } + /* 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; } @@ -2505,20 +2527,6 @@ static int mgbe_configure_mac(struct osi_core_priv_data *osi_core) { unsigned int value = 0U, max_queue = 0U, i = 0U; - /* Update MAC address 0 high */ - value = (((nveu32_t)osi_core->mac_addr[5] << 8U) | - ((nveu32_t)osi_core->mac_addr[4])); - osi_writela(osi_core, value, - (nveu8_t *)osi_core->base + MGBE_MAC_MA0HR); - - /* Update MAC address 0 Low */ - value = (((nveu32_t)osi_core->mac_addr[3] << 24U) | - ((nveu32_t)osi_core->mac_addr[2] << 16U) | - ((nveu32_t)osi_core->mac_addr[1] << 8U) | - ((nveu32_t)osi_core->mac_addr[0])); - osi_writela(osi_core, value, - (nveu8_t *)osi_core->base + MGBE_MAC_MA0LR); - /* 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); @@ -2997,10 +3005,10 @@ static nve32_t mgbe_core_init(struct osi_core_priv_data *osi_core, osi_writela(osi_core, value, (unsigned char *)osi_core->base + MGBE_MTL_RXQ_DMA_MAP2); - /* Enable XDCS in MAC_Extended_Configuration, enable with @rakesh CL */ + /* 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; + value |= MGBE_MAC_EXT_CNF_DDS; osi_writela(osi_core, value, (nveu8_t *)osi_core->base + MGBE_MAC_EXT_CNF); From cce744d5d8a86d41d54a2c60b5712e3439cb2622 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Thu, 6 May 2021 13:16:04 +0530 Subject: [PATCH 229/458] osi: fix return value for eqos_poll_for_update_ts_complete Bug 200722499 Change-Id: I24aee19dfe9238f4327a49eb5818c84f65cdd1db Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2525603 Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> --- osi/core/eqos_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 705294d..1bb2a0a 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -3769,7 +3769,7 @@ static inline nve32_t eqos_poll_for_update_ts_complete( osi_core->osd_ops.udelay(OSI_DELAY_1000US); } - return -1; + return 0; } From 7a32c62df2f5603021db97a3725a10099612db6e Mon Sep 17 00:00:00 2001 From: rakesh goyal <rgoyal@nvidia.com> Date: Wed, 24 Mar 2021 20:44:08 +0530 Subject: [PATCH 230/458] core: remove void input argument - Changed void input arguments to proper type - Modifed ivc_msg_common to ivc_msg_common_t Bug 2739123 Change-Id: Id7964440f6c5d377ba3dd1a7661a2571fdc681d8 Signed-off-by: rakesh goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2514922 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> --- include/ivc_core.h | 7 +-- include/osi_core.h | 4 +- include/osi_dma.h | 10 +++-- osi/core/ivc_core.c | 104 ++++++++++++++++++++++---------------------- osi/dma/osi_dma.c | 2 +- 5 files changed, 66 insertions(+), 61 deletions(-) diff --git a/include/ivc_core.h b/include/ivc_core.h index d9ba66c..17c01da 100644 --- a/include/ivc_core.h +++ b/include/ivc_core.h @@ -185,13 +185,13 @@ typedef struct ivc_msg_common { */ struct osi_ioctl ioctl_data; }data; -} ivc_msg_common; +} ivc_msg_common_t; /** * @brief osd_ivc_send_cmd - OSD ivc send cmd * * @param[in] priv: OSD private data - * @param[in] data: data + * @param[in] ivc_buf: ivc_msg_common structure * @param[in] len: length of data * @note * API Group: @@ -202,7 +202,8 @@ typedef struct ivc_msg_common { * @retval ivc status * @retval -1 on failure */ -nve32_t osd_ivc_send_cmd(void *priv, void *data, nveu32_t len); +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 diff --git a/include/osi_core.h b/include/osi_core.h index 3c8a513..49bbafb 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -26,6 +26,7 @@ #include <osi_common.h> #include "mmc.h" +struct ivc_msg_common; /** * @addtogroup typedef related info * @@ -954,7 +955,8 @@ struct osd_core_ops { /** msleep callback */ void (*msleep)(nveu32_t msec); /** ivcsend callback*/ - nve32_t (*ivc_send)(void *priv, void *data, nveu32_t len); + 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 */ int (*macsec_tz_kt_config)(void *priv, unsigned char cmd, diff --git a/include/osi_dma.h b/include/osi_dma.h index b0955d1..37ccd1b 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -471,13 +471,15 @@ struct osd_dma_ops { /** DMA transmit complete callback */ void (*transmit_complete)(void *priv, void *buffer, nveu64_t dmaaddr, nveu32_t len, - void *txdone_pkt_cx); + struct osi_txdone_pkt_cx *txdone_pkt_cx); /** DMA receive packet callback */ - void (*receive_packet)(void *priv, void *rxring, + void (*receive_packet)(void *priv, struct osi_rx_ring *rx_ring, nveu32_t chan, nveu32_t dma_buf_len, - void *rxpkt_cx, void *rx_pkt_swcx); + struct osi_rx_pkt_cx *rx_pkt_cx, + struct osi_rx_swcx *rx_swcx); /** RX buffer reallocation callback */ - void (*realloc_buf)(void *priv, void *rxring, nveu32_t chan); + 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, diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index f22e19c..dbb9a56 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -59,7 +59,7 @@ static nve32_t ivc_config_fw_err_pkts( const nveu32_t fw_err) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; nve32_t index = 0; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -91,7 +91,7 @@ static nve32_t ivc_config_fw_err_pkts( */ static nve32_t ivc_poll_for_swr(struct osi_core_priv_data *const osi_core) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -118,7 +118,7 @@ static nve32_t ivc_poll_for_swr(struct osi_core_priv_data *const osi_core) static int ivc_set_speed(struct osi_core_priv_data *const osi_core, const nve32_t speed) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; nve32_t index = 0; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -151,7 +151,7 @@ static int ivc_set_speed(struct osi_core_priv_data *const osi_core, static nve32_t ivc_set_mode(struct osi_core_priv_data *const osi_core, const nve32_t mode) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; nve32_t index = 0; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -185,7 +185,7 @@ static nve32_t ivc_set_mode(struct osi_core_priv_data *const osi_core, */ static nve32_t ivc_pad_calibrate(struct osi_core_priv_data *const osi_core) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -215,7 +215,7 @@ static nve32_t ivc_config_rxcsum_offload( struct osi_core_priv_data *const osi_core, const nveu32_t enabled) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; nve32_t index = 0; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -243,7 +243,7 @@ static nve32_t ivc_core_init( const nveu32_t tx_fifo_size, const nveu32_t rx_fifo_size) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -285,7 +285,7 @@ static nve32_t ivc_core_init( static void ivc_handle_common_intr( struct osi_core_priv_data *const osi_core) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -312,7 +312,7 @@ static void ivc_handle_common_intr( */ static void ivc_start_mac(struct osi_core_priv_data *const osi_core) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -338,7 +338,7 @@ static void ivc_start_mac(struct osi_core_priv_data *const osi_core) */ static void ivc_stop_mac(struct osi_core_priv_data *const osi_core) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -368,7 +368,7 @@ static nve32_t ivc_config_mac_pkt_filter_reg( struct osi_core_priv_data *const osi_core, const struct osi_filter *filter) { - ivc_msg_common msg_filter; + ivc_msg_common_t msg_filter; osi_memset(&msg_filter, 0, sizeof(msg_filter)); @@ -376,7 +376,7 @@ static nve32_t ivc_config_mac_pkt_filter_reg( osi_memcpy((void *)&msg_filter.data.filter, (void *)filter, sizeof(struct osi_filter)); - return osi_core->osd_ops.ivc_send(osi_core, (char *)&msg_filter, + return osi_core->osd_ops.ivc_send(osi_core, &msg_filter, sizeof(msg_filter)); } @@ -400,7 +400,7 @@ static nve32_t ivc_update_mac_addr_low_high_reg( struct osi_core_priv_data *const osi_core, const struct osi_filter *filter) { - ivc_msg_common msg_filter; + ivc_msg_common_t msg_filter; osi_memset(&msg_filter, 0, sizeof(msg_filter)); @@ -408,7 +408,7 @@ static nve32_t ivc_update_mac_addr_low_high_reg( osi_memcpy((void *) &msg_filter.data.filter, (void *) filter, sizeof(struct osi_filter)); - return osi_core->osd_ops.ivc_send(osi_core, (char *)&msg_filter, + return osi_core->osd_ops.ivc_send(osi_core, &msg_filter, sizeof(msg_filter)); } @@ -433,7 +433,7 @@ static nve32_t ivc_config_l3_l4_filter_enable( struct osi_core_priv_data *const osi_core, const nveu32_t filter_enb_dis) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; nve32_t index = 0; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -471,7 +471,7 @@ static nve32_t ivc_update_ip4_addr( const nveu8_t addr[], const nveu32_t src_dst_addr_match) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; nve32_t index = 0; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -510,7 +510,7 @@ static nve32_t ivc_update_ip6_addr( const nveu32_t filter_no, const nveu16_t addr[]) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; nve32_t index = 0; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -558,7 +558,7 @@ static nve32_t ivc_update_l4_port_no( const nveu16_t port_no, const nveu32_t src_dst_port_match) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; nve32_t index = 0; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -609,7 +609,7 @@ static nve32_t ivc_config_l3_filters( const nveu32_t dma_routing_enable, const nveu32_t dma_chan) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; nve32_t index = 0; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -662,7 +662,7 @@ static nve32_t ivc_config_l4_filters( const nveu32_t dma_routing_enable, const nveu32_t dma_chan) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; nve32_t index = 0; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -704,7 +704,7 @@ static nve32_t ivc_set_systime_to_mac( const nveu32_t sec, const nveu32_t nsec) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; nve32_t index = 0; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -738,7 +738,7 @@ static nve32_t ivc_set_systime_to_mac( static nve32_t ivc_config_addend(struct osi_core_priv_data *const osi_core, const nveu32_t addend) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; nve32_t index = 0; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -770,7 +770,7 @@ static nve32_t ivc_adjust_mactime(struct osi_core_priv_data *const osi_core, nveu32_t sec, nveu32_t nsec, nveu32_t add_sub, nveu32_t one_nsec_accuracy) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; nve32_t index = 0; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -797,7 +797,7 @@ static nve32_t ivc_adjust_mactime(struct osi_core_priv_data *const osi_core, static void ivc_config_tscr(struct osi_core_priv_data *const osi_core, const nveu32_t ptp_filter) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; nve32_t index = 0; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -820,7 +820,7 @@ static void ivc_config_tscr(struct osi_core_priv_data *const osi_core, static void ivc_config_ssir(struct osi_core_priv_data *const osi_core, const unsigned int ptp_clock) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; nve32_t index = 0; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -845,7 +845,7 @@ static void ivc_config_ssir(struct osi_core_priv_data *const osi_core, */ static void ivc_read_mmc(struct osi_core_priv_data *osi_core) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -854,7 +854,7 @@ static void ivc_read_mmc(struct osi_core_priv_data *osi_core) osi_core->osd_ops.ivc_send(osi_core, &msg_common, sizeof(msg_common)); - osi_memcpy((void *)&osi_core->mmc, (void *)&msg_common.data.mmc, + osi_memcpy((void *)&osi_core->mmc, &msg_common.data.mmc, sizeof(struct osi_mmc_counters)); } @@ -889,7 +889,7 @@ static nve32_t ivc_write_phy_reg(struct osi_core_priv_data *const osi_core, const nveu32_t phyreg, const nveu16_t phydata) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; nve32_t index = 0; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -919,7 +919,7 @@ static nve32_t ivc_handle_ioctl(struct osi_core_priv_data *osi_core, struct osi_ioctl *data) { nve32_t ret = 0; - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -949,7 +949,7 @@ 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 msg_common; + ivc_msg_common_t msg_common; nve32_t index = 0; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -974,7 +974,7 @@ static nve32_t ivc_read_phy_reg(struct osi_core_priv_data *const osi_core, */ static nveu32_t ivc_read_reg(struct osi_core_priv_data *const osi_core, const nve32_t reg) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; nve32_t index = 0; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -999,7 +999,7 @@ static nveu32_t ivc_read_reg(struct osi_core_priv_data *const osi_core, */ static nveu32_t ivc_write_reg(struct osi_core_priv_data *const osi_core, const nveu32_t val, const nve32_t reg) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; nve32_t index = 0; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -1016,14 +1016,14 @@ static nveu32_t ivc_write_reg(struct osi_core_priv_data *const osi_core, static nve32_t ivc_get_hw_features(struct osi_core_priv_data *const osi_core, struct osi_hw_features *hw_feat) { - ivc_msg_common msg_hw_feat; + ivc_msg_common_t msg_hw_feat; nve32_t ret = 0; osi_memset(&msg_hw_feat, 0, sizeof(msg_hw_feat)); msg_hw_feat.cmd = get_hw_features; - ret = osi_core->osd_ops.ivc_send(osi_core, (char *)&msg_hw_feat, + ret = osi_core->osd_ops.ivc_send(osi_core, &msg_hw_feat, sizeof(msg_hw_feat)); if (ret != 0) { return ret; @@ -1057,7 +1057,7 @@ static nve32_t ivc_config_flow_control( struct osi_core_priv_data *const osi_core, const nveu32_t flw_ctrl) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; nve32_t index = 0; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -1080,7 +1080,7 @@ static nve32_t ivc_config_flow_control( */ static nve32_t ivc_validate_core_regs(struct osi_core_priv_data *const osi_core) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -1105,7 +1105,7 @@ static nve32_t ivc_config_rx_crc_check( struct osi_core_priv_data *const osi_core, const nveu32_t crc_chk) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; nve32_t index = 0; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -1136,7 +1136,7 @@ static nve32_t ivc_flush_mtl_tx_queue( struct osi_core_priv_data *const osi_core, const nveu32_t qinx) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; nve32_t index = 0; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -1163,7 +1163,7 @@ static nve32_t ivc_flush_mtl_tx_queue( static nve32_t ivc_config_tx_status(struct osi_core_priv_data *const osi_core, const nveu32_t tx_status) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; nve32_t index = 0; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -1192,7 +1192,7 @@ static nve32_t ivc_set_avb_algorithm( struct osi_core_priv_data *const osi_core, const struct osi_core_avb_algorithm *const avb) { - ivc_msg_common msg_avb; + ivc_msg_common_t msg_avb; osi_memset(&msg_avb, 0, sizeof(msg_avb)); @@ -1200,7 +1200,7 @@ static nve32_t ivc_set_avb_algorithm( osi_memcpy((void *)&msg_avb.data.avb_algo, (void *)avb, sizeof(struct osi_core_avb_algorithm)); - return osi_core->osd_ops.ivc_send(osi_core, (char *)&msg_avb, + return osi_core->osd_ops.ivc_send(osi_core, &msg_avb, sizeof(msg_avb)); } @@ -1219,7 +1219,7 @@ static nve32_t ivc_set_avb_algorithm( static nve32_t ivc_get_avb_algorithm(struct osi_core_priv_data *const osi_core, struct osi_core_avb_algorithm *const avb) { - ivc_msg_common msg_avb; + ivc_msg_common_t msg_avb; osi_memset(&msg_avb, 0, sizeof(msg_avb)); @@ -1227,7 +1227,7 @@ static nve32_t ivc_get_avb_algorithm(struct osi_core_priv_data *const osi_core, osi_memcpy((void *) &msg_avb.data.avb_algo, (void *)avb, sizeof(struct osi_core_avb_algorithm)); - return osi_core->osd_ops.ivc_send(osi_core, (char *)&msg_avb, + return osi_core->osd_ops.ivc_send(osi_core, &msg_avb, sizeof(msg_avb)); } @@ -1250,7 +1250,7 @@ static nve32_t ivc_config_arp_offload( const nveu32_t enable, const nveu8_t *ip_addr) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; nve32_t index = 0; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -1285,7 +1285,7 @@ static nve32_t ivc_config_vlan_filtering( const nveu32_t perfect_hash_filtering, const nveu32_t perfect_inverse_match) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; nve32_t index = 0; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -1315,7 +1315,7 @@ static inline nve32_t ivc_update_vlan_id( /* Don't add VLAN ID to TR register which is eventually set TR * to 0x0 and allow all tagged packets */ - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; nve32_t index = 0; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -1340,7 +1340,7 @@ static inline nve32_t ivc_update_vlan_id( */ static void ivc_reset_mmc(struct osi_core_priv_data *osi_core) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -1366,7 +1366,7 @@ static void ivc_configure_eee(struct osi_core_priv_data *const osi_core, const nveu32_t tx_lpi_enabled, const nveu32_t tx_lpi_timer) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; nve32_t index = 0; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -1390,7 +1390,7 @@ static void ivc_configure_eee(struct osi_core_priv_data *const osi_core, static inline nve32_t ivc_save_registers( struct osi_core_priv_data *const osi_core) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; nve32_t index = 0; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -1412,7 +1412,7 @@ static inline nve32_t ivc_save_registers( static inline nve32_t ivc_restore_registers( struct osi_core_priv_data *const osi_core) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; nve32_t index = 0; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -1436,7 +1436,7 @@ static inline nve32_t ivc_restore_registers( static void ivc_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, const nveu64_t csr_clk_rate) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; nve32_t index = 0; osi_memset(&msg_common, 0, sizeof(msg_common)); @@ -1464,7 +1464,7 @@ static nve32_t ivc_config_mac_loopback( struct osi_core_priv_data *const osi_core, const nveu32_t lb_mode) { - ivc_msg_common msg_common; + ivc_msg_common_t msg_common; nve32_t index = 0; osi_memset(&msg_common, 0, sizeof(msg_common)); diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 9be44a4..821560c 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -277,7 +277,7 @@ nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) } l_dma->mac_ver = osi_readl((nveu8_t *)osi_dma->base + MAC_VERSION) & - MAC_VERSION_SNVER_MASK; + MAC_VERSION_SNVER_MASK; if (is_valid_mac_version(l_dma->mac_ver) == 0) { OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "Invalid MAC version\n", (nveu64_t)l_dma->mac_ver); From 0c8aba9a901fb6af138febc446bacaf7dcfbb787 Mon Sep 17 00:00:00 2001 From: Nagarjuna Kristam <nkristam@nvidia.com> Date: Fri, 30 Apr 2021 13:28:35 +0530 Subject: [PATCH 231/458] nvethernetrm: Export API's. Issue: New API's are added which are needed by QNX OSD. Fix: Add new API's in export files. Bug 200718904 Change-Id: I05f1f48d27815a80b20af078c9682923f72b2ca4 Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2529104 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> --- osi/dma/libnvethernetcl.export | 1 + 1 file changed, 1 insertion(+) diff --git a/osi/dma/libnvethernetcl.export b/osi/dma/libnvethernetcl.export index 776b13f..5ffcc3b 100644 --- a/osi/dma/libnvethernetcl.export +++ b/osi/dma/libnvethernetcl.export @@ -38,3 +38,4 @@ osi_dma_get_systime_from_mac osi_is_mac_enabled osi_get_dma osi_handle_dma_intr +osi_get_global_dma_status \ No newline at end of file From d663ac7c4821847100fd32e41ddd718fda98888f Mon Sep 17 00:00:00 2001 From: nannaiah <nannaiah@nvidia.com> Date: Thu, 6 May 2021 12:49:30 -0700 Subject: [PATCH 232/458] nvethernetrm: Add PTP config to ioctl Bug 200671160 Signed-off-by: Nagaraj annaiah <nannaiah@nvidia.com> Change-Id: I71bad68eb995b9a64f6fdfa85147a722bf751e91 Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2525909 Tested-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> --- include/osi_core.h | 2 ++ osi/core/ivc_core.c | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/include/osi_core.h b/include/osi_core.h index 49bbafb..9ea2535 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -1055,6 +1055,8 @@ struct osi_ioctl { struct osi_est_config est; /* FRP structure */ struct osi_fpe_config fpe; + /** PTP configuration settings */ + struct osi_ptp_config ptp_config; }; /** diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index dbb9a56..d2e972b 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -923,6 +923,13 @@ static nve32_t ivc_handle_ioctl(struct osi_core_priv_data *osi_core, osi_memset(&msg_common, 0, sizeof(msg_common)); + + if (data->cmd == OSI_CMD_CONFIG_PTP) { + osi_memcpy((void *)&data->ptp_config, + (void *)&osi_core->ptp_config, + sizeof(struct osi_ptp_config)); + } + msg_common.cmd = handle_ioctl; osi_memcpy((void *)&msg_common.data.ioctl_data, (void *)data, sizeof(struct osi_ioctl)); From 36b1e74cb94d5022191a4f8b53c11a780c32f8b0 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Mon, 17 May 2021 12:56:07 +0530 Subject: [PATCH 233/458] osi: mgbe: add note for RIWT programming Bug 3287883 Change-Id: I2850d8b71ef084e4126b99822e2bc4191fb75c15 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2530378 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> --- osi/dma/mgbe_dma.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osi/dma/mgbe_dma.c b/osi/dma/mgbe_dma.c index 2d667c5..64e3cd8 100644 --- a/osi/dma/mgbe_dma.c +++ b/osi/dma/mgbe_dma.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -485,6 +485,12 @@ static void mgbe_configure_dma_channel(nveu32_t chan, * 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 + From d5c47ea81a78ce767a9be05e42abfa96fb88e88f Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Mon, 3 May 2021 22:34:43 +0530 Subject: [PATCH 234/458] osi: update XPCS speed based UPHY GBE mode Bug 3288030 Change-Id: Ic33774fce09d1d426d107a8c4bfa883e9a576f6e Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2531231 Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> --- include/osi_core.h | 2 ++ osi/core/xpcs.c | 10 ++++++++++ osi/core/xpcs.h | 5 +++++ 3 files changed, 17 insertions(+) diff --git a/include/osi_core.h b/include/osi_core.h index 9ea2535..023595b 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -1166,6 +1166,8 @@ struct osi_core_priv_data { 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; }; /** diff --git a/osi/core/xpcs.c b/osi/core/xpcs.c index e71c0e8..b6578e8 100644 --- a/osi/core/xpcs.c +++ b/osi/core/xpcs.c @@ -218,7 +218,17 @@ int xpcs_init(struct osi_core_priv_data *osi_core) xpcs_write(xpcs_base, XPCS_SR_XS_PCS_CTRL2, ctrl); /* 2. enable USXGMII Mode inside DWC_xpcs */ + /* 3. USXG_MODE = 10G - default it will be 10G mode */ + 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; + } + + xpcs_write(xpcs_base, XPCS_VR_XS_PCS_KR_CTRL, ctrl); + /* 4. Program PHY to operate at 10Gbps/5Gbps/2Gbps * this step not required since PHY speed programming * already done as part of phy INIT diff --git a/osi/core/xpcs.h b/osi/core/xpcs.h index 10cd93a..9e5f806 100644 --- a/osi/core/xpcs.h +++ b/osi/core/xpcs.h @@ -39,6 +39,7 @@ #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 @@ -74,6 +75,10 @@ #define XPCS_REG_ADDR_SHIFT 10U #define XPCS_REG_ADDR_MASK 0x1FFFU #define XPCS_REG_VALUE_MASK 0xFFU +#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) /** @} */ int xpcs_init(struct osi_core_priv_data *osi_core); From a63839a8f18f6dc79748de9f824a1972e0c2695f Mon Sep 17 00:00:00 2001 From: Mahesh Patil <maheshp@nvidia.com> Date: Fri, 26 Mar 2021 12:51:55 -0700 Subject: [PATCH 235/458] nvethernetrm: Update mac/macsec init Update mac/macsec init programming 1. macsec clock and reset programming order at init and deinit 2. macsec SOT values as per macsec IAS 3. mac IPG values as per macsec IAS Bug 3266535 Signed-off-by: Mahesh Patil <maheshp@nvidia.com> Change-Id: Ie6351f632b0ac7487ec7b5bfd34d9337d3782a59 Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2506488 Reviewed-by: svc_kernel_abi <svc_kernel_abi@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/eqos_core.c | 43 ++++++++++++++++++++++++++++++++++++++++++ osi/core/eqos_core.h | 7 +++++++ osi/core/macsec.c | 19 +++++++++++++++++++ osi/core/macsec.h | 3 +++ osi/core/mgbe_core.c | 45 ++++++++++++++++++++++++++++++++++++++++++++ osi/core/mgbe_core.h | 5 ++++- 6 files changed, 121 insertions(+), 1 deletion(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 1bb2a0a..f300ecc 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1473,6 +1473,46 @@ static void eqos_configure_rxq_priority( } } +#ifdef MACSEC_SUPPORT +/** + * @brief eqos_config_macsec_ipg - Configure MAC IPG according to macsec IAS + * + * @note + * Algorithm: + * - Increase MAC IPG value to accommodate macsec 32 byte SECTAG. + * + * @param[in] osi_core: OSI core private data. + * + * @pre + * 1) MAC has to be out of reset. + * 2) Shall not use this ipg value in half duplex mode + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: No + * - De-initialization: No + */ +static void eqos_config_macsec_ipg(struct osi_core_priv_data *const osi_core) +{ + nveu32_t value; + + /* 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); + value |= (EQOS_MCR_IPG << EQOS_MCR_IPG_SHIFT) & 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 << EQOS_MAC_EXTR_EIPG_SHIFT) & + EQOS_MAC_EXTR_EIPG_MASK; + osi_writela(osi_core, value, (nveu8_t *)osi_core->base + EQOS_MAC_EXTR); +} +#endif /* MACSEC_SUPPORT */ + /** * @brief eqos_configure_mac - Configure MAC * @@ -1628,6 +1668,9 @@ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) if (osi_core->dcs_en != OSI_ENABLE) { eqos_configure_rxq_priority(osi_core); } +#ifdef MACSEC_SUPPORT + eqos_config_macsec_ipg(osi_core); +#endif /* MACSEC_SUPPORT */ } /** diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index d9dfc11..4d48c7b 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -195,6 +195,9 @@ #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 0x700000U +#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) @@ -319,6 +322,10 @@ #define EQOS_MTL_OP_MODE_DTXSTS OSI_BIT(1) #define EQOS_MAC_EXTR_PDC OSI_BIT(19) #define EQOS_MAC_EXTR_DCRCC OSI_BIT(16) +#define EQOS_MAC_EXTR_EIPGEN OSI_BIT(24) +#define EQOS_MAC_EXTR_EIPG_MASK 0x3E000000 +#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) diff --git a/osi/core/macsec.c b/osi/core/macsec.c index 641c39e..4b2f650 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -2393,6 +2393,25 @@ static int macsec_init(struct osi_core_priv_data *const osi_core, pr_err("Write RX_MTU_LEN: 0x%x\n", val); osi_writela(osi_core, val, addr + RX_MTU_LEN); + /* 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 + TX_SOT_DELAY); + pr_err("Read TX_SOT_DELAY: 0x%x\n", val); + val &= ~(SOT_LENGTH_MASK); + val |= (EQOS_MACSEC_SOT_DELAY & SOT_LENGTH_MASK); + pr_err("Write TX_SOT_DELAY: 0x%x\n", val); + osi_writela(osi_core, val, addr + TX_SOT_DELAY); + + val = osi_readla(osi_core, addr + RX_SOT_DELAY); + pr_err("Read RX_SOT_DELAY: 0x%x\n", val); + val &= ~(SOT_LENGTH_MASK); + val |= (EQOS_MACSEC_SOT_DELAY & SOT_LENGTH_MASK); + pr_err("Write RX_SOT_DELAY: 0x%x\n", val); + osi_writela(osi_core, val, addr + RX_SOT_DELAY); + } + /* 2. Set essential MACsec control configuration */ val = osi_readla(osi_core, addr + MACSEC_CONTROL0); pr_err("Read MACSEC_CONTROL0: 0x%x\n", val); diff --git a/osi/core/macsec.h b/osi/core/macsec.h index bad1b26..9ca0bca 100644 --- a/osi/core/macsec.h +++ b/osi/core/macsec.h @@ -448,6 +448,9 @@ #define MTU_LENGTH_MASK 0xFFFF #define MTU_ADDONS (8 + 14 + 4) #define DVLAN_TAG_ETHERTYPE 0x88A8 +#define SOT_LENGTH_MASK 0x1F +#define EQOS_MACSEC_SOT_DELAY 0x4E + /** * @addtogroup TX/RX_BYP/SCI_LUT_VALID register * diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 058c32d..cea99ec 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -2505,6 +2505,47 @@ static int mgbe_config_flow_control(struct osi_core_priv_data *const osi_core, return 0; } +#ifdef MACSEC_SUPPORT +/** + * @brief mgbe_config_macsec_ipg - Configure MAC IPG according to macsec IAS + * + * @note + * Algorithm: + * - Increase MAC IPG value to accommodate macsec 32 byte SECTAG. + * + * @param[in] osi_core: OSI core private data. + * + * @pre + * 1) MAC has to be out of reset. + * 2) Shall not use this ipg value in half duplex mode + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: No + * - De-initialization: No + */ +static void mgbe_config_macsec_ipg(struct osi_core_priv_data *const osi_core) +{ + nveu32_t value = 0U; + + /* 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); +} +#endif /* MACSEC_SUPPORT */ + /** * @brief mgbe_configure_mac - Configure MAC * @@ -2648,6 +2689,10 @@ static int mgbe_configure_mac(struct osi_core_priv_data *osi_core) } /* TODO: USP (user Priority) to RxQ Mapping */ +#ifdef MACSEC_SUPPORT + mgbe_config_macsec_ipg(osi_core); +#endif /* MACSEC_SUPPORT */ + /* RSS cofiguration */ return mgbe_config_rss(osi_core); } diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 12ad42e..71faf9d 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -424,6 +424,8 @@ #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_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) @@ -658,6 +660,7 @@ #define MGBE_MTL_EST_ITRE_IECC OSI_BIT(0) #define MGBE_MAC_SBD_INTR OSI_BIT(2) #define MGBE_MAC_EXT_CNF_DDS OSI_BIT(7) +#define MGBE_MAC_EXT_CNF_EIPG 0x1U /** @} */ /** From cd13575155a90a00aa0400770245d94c0c15721f Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Tue, 4 May 2021 17:27:51 +0530 Subject: [PATCH 236/458] osi: dma: use separate desc ops for MGBE/EQOS Change-Id: I0ad1bcd3114caf99a55f2601be73b90e3116f810 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2524398 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: svc_kernel_abi <svc_kernel_abi@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/dma/osi_dma_txrx.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 3aca22e..d5afef2 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -26,7 +26,7 @@ #include "../osi/common/common.h" #include "mgbe_dma.h" -static struct desc_ops d_ops; +static struct desc_ops d_ops[MAX_MAC_IP_TYPES]; /** * @brief get_rx_err_stats - Detect Errors from Rx Descriptor @@ -131,6 +131,7 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, 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; @@ -214,22 +215,22 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, * are set */ rx_pkt_cx->flags &= ~OSI_PKT_CX_VALID; - d_ops.update_rx_err_stats(rx_desc, + d_ops[ip_type].update_rx_err_stats(rx_desc, osi_dma->pkt_err_stats); } /* Check if COE Rx checksum is valid */ - d_ops.get_rx_csum(rx_desc, rx_pkt_cx); + d_ops[ip_type].get_rx_csum(rx_desc, rx_pkt_cx); /* Get Rx VLAN from descriptor */ - d_ops.get_rx_vlan(rx_desc, rx_pkt_cx); + d_ops[ip_type].get_rx_vlan(rx_desc, rx_pkt_cx); /* get_rx_hash for RSS */ - d_ops.get_rx_hash(rx_desc, rx_pkt_cx); + 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.get_rx_hwstamp(osi_dma, rx_desc, + 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 + @@ -1387,7 +1388,7 @@ nve32_t init_desc_ops(struct osi_dma_priv_data *osi_dma) eqos_init_desc_ops, mgbe_init_desc_ops }; - desc_ops[osi_dma->mac](&d_ops); + desc_ops[osi_dma->mac](&d_ops[osi_dma->mac]); /* TODO: validate function pointers */ return 0; From 38b75dc2bac24f9526a87a202c8afd90883c0eab Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Tue, 18 May 2021 22:02:20 +0530 Subject: [PATCH 237/458] osi: dma: fix tx_bytes count Issue: In case of VLAN ping, the ndev->stats.tx_bytes are not getting incremented as expected Fix: Make sure the tx_swcx->len gets updated with the VLAN_HLEN (4 bytes) during VLAN transmission. So that the same will be used in case of process tx completions Bug 3296258 Change-Id: Iaa01d766497f9017b7564fbcfc3ac0b93d626032 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2531924 Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> --- osi/dma/osi_dma_txrx.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index d5afef2..d583ee0 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -712,6 +712,14 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, 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->buf_virt_addr, tx_swcx->buf_phy_addr, @@ -756,6 +764,7 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, * 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 @@ -771,6 +780,7 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, */ 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) @@ -790,6 +800,10 @@ static inline nve32_t need_cntx_desc(struct osi_tx_pkt_cx *tx_pkt_cx, 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; } @@ -1022,8 +1036,8 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, 1UL); } - cntx_desc_consumed = need_cntx_desc(tx_pkt_cx, tx_desc, osi_dma->ptp_flag, - osi_dma->mac); + 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)) { From c0a7df69862c53fc104df398e16335b9b609a67f Mon Sep 17 00:00:00 2001 From: Nagarjuna Kristam <nkristam@nvidia.com> Date: Thu, 13 May 2021 17:08:31 +0530 Subject: [PATCH 238/458] osi: dma: Add vm_num entry in irq_data Issue: irq_data structure uses index of its array as VM number assosciated with that channel. Which is not true. Fix: Add vm_num entry in irq_data which is updated by OSD to its corresponding DMA channels. Bug 200730767 Change-Id: Ida3219f8d4cef9bda1890e50a20853553f9bd930 Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2532465 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> --- include/osi_dma.h | 2 ++ osi/dma/eqos_dma.c | 2 +- osi/dma/mgbe_dma.c | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/include/osi_dma.h b/include/osi_dma.h index 37ccd1b..8127561 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -460,6 +460,8 @@ struct osi_dma_priv_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]; }; diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index b781768..633fee4 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -736,7 +736,7 @@ static void eqos_dma_chan_to_vmirq_map(struct osi_dma_priv_data *osi_dma) if (chan >= OSI_EQOS_MAX_NUM_CHANS) { continue; } - osi_writel(OSI_BIT(i), + osi_writel(OSI_BIT(irq_data->vm_num), (nveu8_t *)osi_dma->base + EQOS_VIRT_INTR_APB_CHX_CNTRL(chan)); } diff --git a/osi/dma/mgbe_dma.c b/osi/dma/mgbe_dma.c index 64e3cd8..4c3343c 100644 --- a/osi/dma/mgbe_dma.c +++ b/osi/dma/mgbe_dma.c @@ -548,7 +548,7 @@ static void mgbe_dma_chan_to_vmirq_map(struct osi_dma_priv_data *osi_dma) continue; } - osi_writel(OSI_BIT(i), + osi_writel(OSI_BIT(irq_data->vm_num), (nveu8_t *)osi_dma->base + MGBE_VIRT_INTR_APB_CHX_CNTRL(chan)); } From 5cbc0025f84d82dfeb67ff2105af7e719e9479d5 Mon Sep 17 00:00:00 2001 From: Nagarjuna Kristam <nkristam@nvidia.com> Date: Tue, 18 May 2021 13:08:23 +0530 Subject: [PATCH 239/458] osi: common: Fix mgbe xpcs and osi_common code - Return success xpcs-base is null for now. - Add is mac enable support for MGBE. - Call HW type common API base on MAC HW. - Add generic channel mask macro. Bug 200718904 Change-Id: Icc228697d0464c18af77312457a6bcfbf484ab7d Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2532466 Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> --- include/osi_dma.h | 9 +++++++++ osi/common/mgbe_common.c | 15 ++++++++++++++- osi/common/mgbe_common.h | 9 +++++++-- osi/common/osi_common.c | 26 ++++++++++++-------------- osi/core/xpcs.c | 15 +++++++++++++-- 5 files changed, 55 insertions(+), 19 deletions(-) diff --git a/include/osi_dma.h b/include/osi_dma.h index 8127561..5421beb 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -58,6 +58,15 @@ #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 diff --git a/osi/common/mgbe_common.c b/osi/common/mgbe_common.c index 315fdbf..0ca6879 100644 --- a/osi/common/mgbe_common.c +++ b/osi/common/mgbe_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -70,3 +70,16 @@ nveul64_t mgbe_get_systime_from_mac(void *addr) 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 index 1baff90..7ebffeb 100644 --- a/osi/common/mgbe_common.h +++ b/osi/common/mgbe_common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -24,15 +24,20 @@ #define INCLUDED_MGBE_COMMON_H /** - * @addtogroup MGBE-MAC MGBE MAC PTP HW feature registers + * @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 index 9e2b26e..18df8ff 100644 --- a/osi/common/osi_common.c +++ b/osi/common/osi_common.c @@ -21,6 +21,7 @@ */ #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, @@ -29,15 +30,12 @@ void common_get_systime_from_mac(void *addr, nveu32_t mac, nveu32_t *sec, 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 + }; - if (mac == OSI_MAC_HW_EQOS) { - ns = eqos_get_systime_from_mac(addr); - } else if (mac == OSI_MAC_HW_MGBE) { - ns = eqos_get_systime_from_mac(addr); - } else { - /* Non EQOS HW is supported yet */ - return; - } + ns = i_ops[mac](addr); temp = div_u64_rem((nveu64_t)ns, OSI_NSEC_PER_SEC, &remain); if (temp < UINT_MAX) { @@ -54,12 +52,12 @@ void common_get_systime_from_mac(void *addr, nveu32_t mac, nveu32_t *sec, nveu32_t common_is_mac_enabled(void *addr, nveu32_t mac) { - if (mac == OSI_MAC_HW_EQOS) { - return eqos_is_mac_enabled(addr); - } else { - /* Non EQOS HW is supported yet */ - return OSI_DISABLE; - } + 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, diff --git a/osi/core/xpcs.c b/osi/core/xpcs.c index b6578e8..8b9c392 100644 --- a/osi/core/xpcs.c +++ b/osi/core/xpcs.c @@ -135,6 +135,13 @@ int xpcs_start(struct osi_core_priv_data *osi_core) int ret = 0; int cond = 1; + 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; + } + ctrl = xpcs_read(xpcs_base, XPCS_SR_MII_CTRL); ctrl |= XPCS_SR_MII_CTRL_AN_ENABLE; xpcs_write(xpcs_base, XPCS_SR_MII_CTRL, ctrl); @@ -205,8 +212,12 @@ int xpcs_init(struct osi_core_priv_data *osi_core) unsigned int ctrl = 0; int cond = 1; - if (osi_core->xpcs_base == OSI_NULL) - return -1; + 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; + } /* Switching to USXGMII Mode based on * XPCS programming guideline 7.6 From 03c09c2ff1645dc73fce9e37b190bed74c4f3288 Mon Sep 17 00:00:00 2001 From: Mahesh Patil <maheshp@nvidia.com> Date: Wed, 12 May 2021 12:39:38 -0700 Subject: [PATCH 240/458] nvethernetrm: Remove osd callback from osi Remove calling osd callback from osi to program SAK and program SAK from OSD itself. Bug 3308383 Signed-off-by: Mahesh Patil <maheshp@nvidia.com> Change-Id: I2b27cea66bd9770aec52ed53ba430eb276cf73f7 Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2528707 Reviewed-by: svc_kernel_abi <svc_kernel_abi@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_macsec.h | 22 ++++----- osi/core/ivc_core.c | 15 +++--- osi/core/macsec.c | 106 +++++++++++++++++++------------------------ 3 files changed, 63 insertions(+), 80 deletions(-) diff --git a/include/osi_macsec.h b/include/osi_macsec.h index 4164ac1..7ae5c92 100644 --- a/include/osi_macsec.h +++ b/include/osi_macsec.h @@ -362,8 +362,7 @@ struct osi_macsec_dbg_buf_config { */ struct macsec_core_ops { /** macsec init */ - int (*init)(struct osi_core_priv_data *const osi_core, - void *const genl_info); + int (*init)(struct osi_core_priv_data *const osi_core); /** macsec de-init */ int (*deinit)(struct osi_core_priv_data *const osi_core); /** NS irq handler */ @@ -373,10 +372,11 @@ struct macsec_core_ops { /** macsec lut config */ int (*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 */ int (*kt_config)(struct osi_core_priv_data *const osi_core, - struct osi_macsec_kt_config *const kt_config, - void *const genl_info); + struct osi_macsec_kt_config *const kt_config); +#endif /* MACSEC_KEY_PROGRAM */ /** macsec cipher config */ int (*cipher_config)(struct osi_core_priv_data *const osi_core, unsigned int cipher); @@ -390,7 +390,7 @@ struct macsec_core_ops { int (*config)(struct osi_core_priv_data *const osi_core, struct osi_macsec_sc_info *const sc, unsigned int enable, unsigned short ctlr, - void *const genl_info); + unsigned short *kt_idx); /** macsec read mmc counters */ void (*read_mmc)(struct osi_core_priv_data *const osi_core); /** macsec debug buffer config */ @@ -449,7 +449,6 @@ int osi_init_macsec_ops(struct osi_core_priv_data *const osi_core); * set BYP LUT entries for MKPDU and BC packets * * @param[in] osi_core: OSI core private data structure. - * @param[in] genl_info: Pointer to netlink genl_info data structure. * * @pre * - MACSEC should be out of reset and clocks are enabled @@ -474,8 +473,7 @@ int osi_init_macsec_ops(struct osi_core_priv_data *const osi_core); * @retval 0 on success * @retval -1 on failure */ -int osi_macsec_init(struct osi_core_priv_data *const osi_core, - void *const genl_info); +int osi_macsec_init(struct osi_core_priv_data *const osi_core); /** @@ -523,14 +521,12 @@ int osi_macsec_lut_config(struct osi_core_priv_data *const osi_core, * * @param[in] osi_core: OSI core private data structure. * @param[in] kt_config: OSI macsec KT config data structure. - * @param[in] genl_info: Pointer to netlink genl_info data structure. * * @retval 0 on success * @retval -1 on failure */ int osi_macsec_kt_config(struct osi_core_priv_data *const osi_core, - struct osi_macsec_kt_config *const kt_config, - void *const genl_info); + struct osi_macsec_kt_config *const kt_config); /** * @brief MACsec cipther config @@ -574,7 +570,7 @@ int osi_macsec_en(struct osi_core_priv_data *const osi_core, * @param[in] osi_core: OSI core private data structure. * @param[in] sc: Pointer to osi_macsec_sc_info struct for the tx SA. * @param[in] enable: flag to indicate enable/disable for the Tx SA. - * @param[in] genl_info: Pointer to netlink genl_info data structure. + * @param[out] kt_idx: Key table index to program SAK. * * @retval 0 on success * @retval -1 on failure @@ -582,7 +578,7 @@ int osi_macsec_en(struct osi_core_priv_data *const osi_core, int osi_macsec_config(struct osi_core_priv_data *const osi_core, struct osi_macsec_sc_info *const sc, unsigned int enable, unsigned short ctlr, - void *const genl_info); + unsigned short *kt_idx); /** * @brief MACsec read statistics counters diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index d2e972b..ba72d87 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -1541,7 +1541,7 @@ static void ivc_macsec_read_mmc(struct osi_core_priv_data *const osi_core) * @param[in] sc: Secure Channel info. * @param[in] enable: enable or disable. * @param[in] ctlr: Controller instance. - * @param[in] genl_info: Generic netlink information structure. + * @param[[out] kt_idx: Key table index to program SAK. * * @retval 0 on Success * @retval -1 on Failure @@ -1549,7 +1549,7 @@ static void ivc_macsec_read_mmc(struct osi_core_priv_data *const osi_core) 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, - void *const genl_info) + unsigned short *kt_idx) { return 0; } @@ -1584,22 +1584,22 @@ static int ivc_macsec_loopback_config(struct osi_core_priv_data *const osi_core, return 0; } +#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. - * @param[in] genl_info: Generic netlink information structure. * * @retval 0 on Success * @retval -1 on Failure */ static int ivc_macsec_kt_config(struct osi_core_priv_data *const osi_core, - struct osi_macsec_kt_config *const kt_config, - void *const genl_info) + struct osi_macsec_kt_config *const kt_config) { return 0; } +#endif /* MACSEC_KEY_PROGRAM */ /** * @brief ivc_macsec_lut_config - LUT config. @@ -1661,8 +1661,7 @@ static int ivc_macsec_deinit(struct osi_core_priv_data *const osi_core) * @retval 0 on Success * @retval -1 on Failure */ -static int ivc_macsec_init(struct osi_core_priv_data *const osi_core, - void *const genl_info) +static int ivc_macsec_init(struct osi_core_priv_data *const osi_core) { return 0; } @@ -1746,7 +1745,9 @@ void ivc_init_macsec_ops(void *macsecops) 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->loopback_config = ivc_macsec_loopback_config; ops->macsec_en = ivc_macsec_enable; ops->config = ivc_macsec_config; diff --git a/osi/core/macsec.c b/osi/core/macsec.c index 4b2f650..5122c5d 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -659,8 +659,7 @@ static int kt_key_write(struct osi_core_priv_data *const osi_core, } static int macsec_kt_config(struct osi_core_priv_data *const osi_core, - struct osi_macsec_kt_config *const kt_config, - void *const genl_info) + struct osi_macsec_kt_config *const kt_config) { int ret = 0; unsigned int kt_config_reg = 0; @@ -723,15 +722,6 @@ static int macsec_kt_config(struct osi_core_priv_data *const osi_core, } return ret; } - -#else -static int macsec_kt_config(struct osi_core_priv_data *const osi_core, - struct osi_macsec_kt_config *const kt_config, - void *const genl_info) -{ - return osi_core->osd_ops.macsec_tz_kt_config(osi_core, - MACSEC_CMD_TZ_CONFIG, kt_config, genl_info); -} #endif /* MACSEC_KEY_PROGRAM */ /** @@ -2335,7 +2325,7 @@ static int clear_lut(struct osi_core_priv_data *const osi_core) table_config->ctlr_sel = i; for (j = 0; j <= TABLE_INDEX_MAX; j++) { table_config->index = j; - ret = macsec_kt_config(osi_core, &kt_config, OSI_NULL); + ret = macsec_kt_config(osi_core, &kt_config); if (ret < 0) { pr_err("Error clearing KT CTLR:INDEX: %d:%d\n", i, j); @@ -2359,14 +2349,10 @@ static int macsec_deinit(struct osi_core_priv_data *const osi_core) return 0; } -static int macsec_init(struct osi_core_priv_data *const osi_core, - void *const genl_info) +static int macsec_init(struct osi_core_priv_data *const osi_core) { unsigned int val = 0; struct osi_macsec_lut_config lut_config = {0}; -#ifndef MACSEC_KEY_PROGRAM - struct osd_core_ops *osd_ops = &osi_core->osd_ops; -#endif struct macsec_table_config *table_config = &lut_config.table_config; /* Store MAC address in reverse, per HW design */ unsigned char mac_da_mkpdu[OSI_ETH_ALEN] = {0x3, 0x0, 0x0, @@ -2485,16 +2471,6 @@ static int macsec_init(struct osi_core_priv_data *const osi_core, pr_err("Invalidating all LUT's failed\n"); return ret; } -#ifndef MACSEC_KEY_PROGRAM - /* clear KT entries */ - ret = osd_ops->macsec_tz_kt_config(osi_core, - MACSEC_CMD_TZ_KT_RESET, - OSI_NULL, genl_info); - if (ret < 0) { - pr_err("TZ key config failed %d\n", ret); - goto exit; - } -#endif /* !MACSEC_KEY_PROGRAM */ /* 6. Set default BYP for MKPDU/BC packets */ table_config->rw = LUT_WRITE; @@ -2561,16 +2537,18 @@ static struct osi_macsec_sc_info *find_existing_sc( static int del_upd_sc(struct osi_core_priv_data *const osi_core, struct osi_macsec_sc_info *existing_sc, struct osi_macsec_sc_info *const sc, - unsigned short ctlr, void *const genl_info) + unsigned short ctlr, unsigned short *kt_idx) { - struct osi_macsec_lut_config lut_config = {0}; +#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 macsec_table_config *table_config; int 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 = LUT_WRITE; @@ -2617,25 +2595,30 @@ static int del_upd_sc(struct osi_core_priv_data *const osi_core, goto err_sa_state; } + /* Store key table index returned to osd */ + *kt_idx = (existing_sc->sc_idx_start * 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 = LUT_WRITE; /* Each SC has MAX_NUM_SA's supported in HW */ - table_config->index = (existing_sc->sc_idx_start * MAX_NUM_SA) + - sc->curr_an; - ret = macsec_kt_config(osi_core, &kt_config, genl_info); + table_config->index = *kt_idx; + ret = macsec_kt_config(osi_core, &kt_config); if (ret < 0) { pr_err("%s: Failed to del SAK", __func__); goto err_kt; } +#endif /* MACSEC_KEY_PROGRAM */ existing_sc->an_valid &= ~OSI_BIT(sc->curr_an); return 0; +#ifdef MACSEC_KEY_PROGRAM err_kt: /* TODO cleanup SA state LUT */ +#endif err_sa_state: /* TODO Cleanup SC state LUT */ err_sc_state: @@ -2648,12 +2631,14 @@ err_sci: static int add_upd_sc(struct osi_core_priv_data *const osi_core, struct osi_macsec_sc_info *const sc, - unsigned short ctlr, void *const genl_info) + unsigned short ctlr, unsigned short *kt_idx) { struct osi_macsec_lut_config lut_config = {0}; - struct osi_macsec_kt_config kt_config = {0}; struct macsec_table_config *table_config; int ret, i; +#ifdef MACSEC_KEY_PROGRAM + struct osi_macsec_kt_config kt_config = {0}; +#endif /* MACSEC_KEY_PROGRAM */ #ifdef MACSEC_KEY_PROGRAM /* HKEY GENERATION */ @@ -2677,31 +2662,29 @@ static int add_upd_sc(struct osi_core_priv_data *const osi_core, crypto_free_cipher(tfm); #endif /* MACSEC_KEY_PROGRAM */ + /* Store key table index returned to osd */ + *kt_idx = (sc->sc_idx_start * MAX_NUM_SA) + sc->curr_an; +#ifdef MACSEC_KEY_PROGRAM /* 1. Key LUT */ table_config = &kt_config.table_config; table_config->ctlr_sel = ctlr; table_config->rw = LUT_WRITE; /* Each SC has MAX_NUM_SA's supported in HW */ - table_config->index = (sc->sc_idx_start * MAX_NUM_SA) + sc->curr_an; + table_config->index = *kt_idx; kt_config.flags |= LUT_FLAGS_ENTRY_VALID; -#ifdef MACSEC_KEY_PROGRAM /* Program in reverse order as per HW design */ for (i = 0; i < KEY_LEN_128; i++) { kt_config.entry.sak[i] = sc->sak[KEY_LEN_128 - 1 - i]; kt_config.entry.h[i] = hkey[KEY_LEN_128 - 1 - i]; } -#else - for (i = 0; i < KEY_LEN_128; i++) { - kt_config.entry.sak[i] = sc->sak[i]; - } -#endif /* MACSEC_KEY_PROGRAM */ - ret = macsec_kt_config(osi_core, &kt_config, genl_info); + ret = macsec_kt_config(osi_core, &kt_config); if (ret < 0) { pr_err("%s: Failed to set SAK", __func__); return -1; } +#endif /* MACSEC_KEY_PROGRAM */ table_config = &lut_config.table_config; table_config->ctlr_sel = ctlr; @@ -2791,7 +2774,7 @@ err_sa_state: static int macsec_config(struct osi_core_priv_data *const osi_core, struct osi_macsec_sc_info *const sc, unsigned int enable, unsigned short ctlr, - void *const genl_info) + unsigned short *kt_idx) { struct osi_macsec_sc_info *existing_sc = OSI_NULL, *new_sc = OSI_NULL; struct osi_macsec_sc_info tmp_sc; @@ -2801,7 +2784,8 @@ static int macsec_config(struct osi_core_priv_data *const osi_core, /* Validate inputs */ if ((enable != OSI_ENABLE && enable != OSI_DISABLE) || - (ctlr != CTLR_SEL_TX && ctlr != CTLR_SEL_RX)) { + (ctlr != CTLR_SEL_TX && ctlr != CTLR_SEL_RX) || + (kt_idx == OSI_NULL)) { return -1; } @@ -2853,7 +2837,8 @@ static int macsec_config(struct osi_core_priv_data *const osi_core, } pr_err(""); - if (add_upd_sc(osi_core, new_sc, ctlr, genl_info) != OSI_NONE) { + if (add_upd_sc(osi_core, new_sc, ctlr, kt_idx) != + OSI_NONE) { pr_err("%s: failed to add new SC", __func__); /* TODO - remove new_sc from lut_status[] ? * not needed for now, as next_sc_idx is not @@ -2874,7 +2859,7 @@ static int macsec_config(struct osi_core_priv_data *const osi_core, pr_err("%s: Updating existing SC", __func__); if (enable == OSI_DISABLE) { pr_err("%s: Deleting existing SA", __func__); - if (del_upd_sc(osi_core, existing_sc, sc, ctlr, genl_info) != + if (del_upd_sc(osi_core, existing_sc, sc, ctlr, kt_idx) != OSI_NONE) { pr_err("%s: failed to del SA", __func__); return -1; @@ -2917,7 +2902,7 @@ static int macsec_config(struct osi_core_priv_data *const osi_core, } pr_err(""); - if (add_upd_sc(osi_core, tmp_sc_p, ctlr, genl_info) != + if (add_upd_sc(osi_core, tmp_sc_p, ctlr, kt_idx) != OSI_NONE) { pr_err("%s: failed to add new SA", __func__); /* TODO - remove new_sc from lut_status[] ? @@ -2945,7 +2930,9 @@ static struct macsec_core_ops macsec_ops = { .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, @@ -2959,8 +2946,7 @@ static struct osi_macsec_lut_status lut_status[NUM_CTLR]; int osi_init_macsec_ops(struct osi_core_priv_data *const osi_core) { - if (osi_core->macsec_base == OSI_NULL || - osi_core->osd_ops.macsec_tz_kt_config == OSI_NULL) { + if (osi_core->macsec_base == OSI_NULL) { return -1; } else { osi_core->macsec_ops = &macsec_ops; @@ -2969,12 +2955,11 @@ int osi_init_macsec_ops(struct osi_core_priv_data *const osi_core) } } -int osi_macsec_init(struct osi_core_priv_data *const osi_core, - void *const genl_info) +int osi_macsec_init(struct osi_core_priv_data *const osi_core) { 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, genl_info); + return osi_core->macsec_ops->init(osi_core); } return -1; @@ -3016,19 +3001,19 @@ int osi_macsec_lut_config(struct osi_core_priv_data *const osi_core, return -1; } +#ifdef MACSEC_KEY_PROGRAM int osi_macsec_kt_config(struct osi_core_priv_data *const osi_core, - struct osi_macsec_kt_config *const kt_config, - void *const genl_info) + 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, - genl_info); + return osi_core->macsec_ops->kt_config(osi_core, kt_config); } return -1; } +#endif /* MACSEC_KEY_PROGRAM */ int osi_macsec_cipher_config(struct osi_core_priv_data *const osi_core, unsigned int cipher) @@ -3073,17 +3058,18 @@ int osi_macsec_en(struct osi_core_priv_data *const osi_core, int osi_macsec_config(struct osi_core_priv_data *const osi_core, struct osi_macsec_sc_info *const sc, unsigned int enable, unsigned short ctlr, - void *const genl_info) + unsigned short *kt_idx) { if ((enable != OSI_ENABLE && enable != OSI_DISABLE) || - (ctlr != CTLR_SEL_TX && ctlr != CTLR_SEL_RX)) { + (ctlr != CTLR_SEL_TX && ctlr != CTLR_SEL_RX) || + (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, genl_info); + enable, ctlr, kt_idx); } return -1; From 44b6813a57d2d8427a12c99b80249df5f3300a04 Mon Sep 17 00:00:00 2001 From: nannaiah <nannaiah@nvidia.com> Date: Fri, 14 May 2021 00:52:47 -0700 Subject: [PATCH 241/458] nvethernetrm: Update IVC support for macsec 1. Cleanup ivc_cmd to remove unwanted commands. 2. Update macsec IVC API's. 3. Add HAL read and write register. Bug 2694285 Bug 2694285 Change-Id: I4d120b7bcfdc9ed65e2bf35a54fa4233a8b6e534 Signed-off-by: Nagaraj annaiah <nannaiah@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2529496 Reviewed-by: Mahesh Patil <maheshp@nvidia.com> --- include/ivc_core.h | 108 ++- include/osi_core.h | 2 + osi/common/common.h | 4 +- osi/core/ivc_core.c | 1646 ++++++------------------------------------- osi/core/macsec.c | 21 +- osi/core/osi_hal.c | 8 + 6 files changed, 282 insertions(+), 1507 deletions(-) mode change 100644 => 100755 osi/common/common.h mode change 100644 => 100755 osi/core/osi_hal.c diff --git a/include/ivc_core.h b/include/ivc_core.h index 17c01da..0ddb5aa 100644 --- a/include/ivc_core.h +++ b/include/ivc_core.h @@ -23,7 +23,8 @@ #ifndef IVC_CORE_H #define IVC_CORE_H -#include "osi_core.h" +#include <osi_macsec.h> + /** * @brief Ethernet Maximum IVC BUF */ @@ -38,61 +39,18 @@ * @brief IVC commands between OSD & OSI. */ typedef enum ivc_cmd { - poll_for_swr = 1, - core_init, + core_init = 1, core_deinit, - start_mac, - stop_mac, - handle_common_intr, - set_mode, - set_speed, - pad_calibrate, - config_fw_err_pkts, - config_rxcsum_offload, - config_mac_pkt_filter_reg, - update_mac_addr_low_high_reg, - config_l3_l4_filter_enable, - config_l3_filters, - update_ip4_addr, - update_ip6_addr, - config_l4_filters, - update_l4_port_no, - set_systime_to_mac, - config_addend, - adjust_mactime, - config_tscr, - config_ssir, - read_mmc, write_phy_reg, read_phy_reg, - reg_read, - reg_write, - get_hw_features, handle_ioctl, -#ifndef OSI_STRIPPED_LIB - config_tx_status, - config_rx_crc_check, - config_flow_control, - config_arp_offload, - validate_regs, - flush_mtl_tx_queue, - set_avb_algorithm, - get_avb_algorithm, - config_vlan_filtering, - i_update_vlan_id, - reset_mmc, - configure_eee, - save_registers, - restore_registers, - set_mdc_clk_rate, - config_mac_loopback, -#endif /* !OSI_STRIPPED_LIB */ 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, @@ -139,6 +97,22 @@ typedef struct ivc_core_args { 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_config; +#endif + /** * @brief IVC message structure. */ @@ -148,42 +122,42 @@ typedef struct ivc_msg_common { * Status code value is "0" for success and "< 0" for failure. */ nve32_t status; - /** - * ID of the CMD. - */ + /** ID of the CMD. */ ivc_cmd cmd; - /** - * message count, used for debug - */ + /** message count, used for debug */ nveu32_t count; union { - /** - * IVC argument structure - */ + /** IVC argument structure */ ivc_args args; #ifndef OSI_STRIPPED_LIB - /** - * avb algorithm structure - */ + /** avb algorithm structure */ struct osi_core_avb_algorithm avb_algo; #endif - /** - * OSI filter structure - */ + /** 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 - */ + /** core argument structure */ ivc_core_args init_args; - /** - * ioctl command structure - */ + /** 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; +#endif }data; } ivc_msg_common_t; diff --git a/include/osi_core.h b/include/osi_core.h index 023595b..07df5f3 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -203,6 +203,8 @@ typedef my_lint_64 nvel64_t; #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 /** @} */ /** diff --git a/osi/common/common.h b/osi/common/common.h old mode 100644 new mode 100755 index 7aa998d..dd192b2 --- a/osi/common/common.h +++ b/osi/common/common.h @@ -308,11 +308,11 @@ static inline void osi_memset(void *s, nveu32_t c, nveu64_t count) * - Run time: Yes * - De-initialization: No */ -static inline nve32_t osi_memcpy(void *dest, void *src, int n) +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; - nve32_t i = 0; + nveu64_t i = 0; if (src == OSI_NULL || dest == OSI_NULL) { return -1; diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index ba72d87..df25935 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -36,196 +36,35 @@ static struct core_func_safety ivc_safety_config; /** - * @brief ivc_config_fw_err_pkts - Configure forwarding of error packets + * @brief ivc_handle_ioctl - marshell input argument to handle runtime command * * @param[in] osi_core: OSI core private data structure. - * @param[in] qinx: Queue index - * @param[in] fw_err: Enable or 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 ivc_config_fw_err_pkts( - struct osi_core_priv_data *const osi_core, - const nveu32_t qinx, - const nveu32_t fw_err) - -{ - ivc_msg_common_t msg_common; - nve32_t index = 0; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - msg_common.cmd = config_fw_err_pkts; - msg_common.data.args.arguments[index++] = qinx; - msg_common.data.args.arguments[index++] = fw_err; - msg_common.data.args.count = index; - - return osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); -} - -/** - * @brief ivc_poll_for_swr - Poll for software reset (SWR bit in DMA Mode) - * - * @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: No - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t ivc_poll_for_swr(struct osi_core_priv_data *const osi_core) -{ - ivc_msg_common_t msg_common; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - msg_common.cmd = poll_for_swr; - - return osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); -} - -/** - * @brief ivc_set_speed - Set operating speed - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] speed: Operating 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 ivc_set_speed(struct osi_core_priv_data *const osi_core, - const nve32_t speed) -{ - ivc_msg_common_t msg_common; - nve32_t index = 0; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - msg_common.cmd = set_speed; - msg_common.data.args.arguments[index++] = speed; - msg_common.data.args.count = index; - - return osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); -} - -/** - * @brief ivc_set_mode - Set operating mode - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] mode: Operating 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 on success - * @retval -1 on failure. - */ -static nve32_t ivc_set_mode(struct osi_core_priv_data *const osi_core, - const nve32_t mode) -{ - ivc_msg_common_t msg_common; - nve32_t index = 0; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - msg_common.cmd = set_mode; - msg_common.data.args.arguments[index++] = mode; - msg_common.data.args.count = index; - - return osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); -} - -/** - * @brief ivc_pad_calibrate - PAD calibration - * - * @param[in] osi_core: OSI core private data structure. - * - * @note - * - MAC should out of reset and clocks enabled. - * - RGMII and MDIO nve32_terface 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 ivc_pad_calibrate(struct osi_core_priv_data *const osi_core) -{ - ivc_msg_common_t msg_common; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - msg_common.cmd = pad_calibrate; - - return osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); -} - -/** - * @brief ivc_config_rxcsum_offload - Enable/Disale rx checksum offload in HW - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] enabled: Flag to indicate feature is to be enabled/disabled. + * @param[in] data: OSI IOCTL data structure. * * @note MAC should be init 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. + * @retval data from PHY register on success + * @retval -1 on failure */ -static nve32_t ivc_config_rxcsum_offload( - struct osi_core_priv_data *const osi_core, - const nveu32_t enabled) +static nve32_t ivc_handle_ioctl(struct osi_core_priv_data *osi_core, + struct osi_ioctl *data) { - ivc_msg_common_t msg_common; - nve32_t index = 0; + nve32_t ret = 0; + ivc_msg_common_t msg; - osi_memset(&msg_common, 0, sizeof(msg_common)); + osi_memset(&msg, 0, sizeof(msg)); - msg_common.cmd = config_rxcsum_offload; - msg_common.data.args.arguments[index++] = enabled; - msg_common.data.args.count = index; + msg.cmd = handle_ioctl; + msg.status = osi_memcpy((void *)&msg.data.ioctl_data, + (void *)data, + sizeof(struct osi_ioctl)); - return osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); + ret = osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); + + msg.status = osi_memcpy((void *)data, + (void *)&msg.data.ioctl_data, + sizeof(struct osi_ioctl)); + return ret; } /** @@ -238,625 +77,19 @@ static nve32_t ivc_config_rxcsum_offload( * @retval 0 on success * @retval -1 on failure. */ -static nve32_t ivc_core_init( - struct osi_core_priv_data *const osi_core, - const nveu32_t tx_fifo_size, - const nveu32_t rx_fifo_size) +static nve32_t ivc_core_init(struct osi_core_priv_data *const osi_core, + nveu32_t tx_fifo_size, + nveu32_t rx_fifo_size) { - ivc_msg_common_t msg_common; + ivc_msg_common_t msg; - osi_memset(&msg_common, 0, sizeof(msg_common)); + osi_memset(&msg, 0, sizeof(msg)); - msg_common.cmd = core_init; - msg_common.data.init_args.tx_fifo_size = tx_fifo_size; - msg_common.data.init_args.rx_fifo_size = rx_fifo_size; - msg_common.data.init_args.strip_vlan_tag = osi_core->strip_vlan_tag; - msg_common.data.init_args.pause_frames = osi_core->pause_frames; - msg_common.data.init_args.flow_ctrl = osi_core->flow_ctrl; - msg_common.data.init_args.num_mtl_queues = osi_core->num_mtl_queues; - msg_common.data.init_args.pre_si = osi_core->pre_si; - osi_memcpy(&msg_common.data.init_args.mtl_queues, - &osi_core->mtl_queues, sizeof(osi_core->mtl_queues)); - osi_memcpy(&msg_common.data.init_args.rxq_ctrl, - &osi_core->rxq_ctrl, sizeof(osi_core->rxq_ctrl)); - osi_memcpy(&msg_common.data.init_args.rxq_prio, - &osi_core->rxq_prio, sizeof(osi_core->rxq_prio)); - osi_memcpy(&msg_common.data.init_args.mac_addr, - &osi_core->mac_addr, OSI_ETH_ALEN); + msg.cmd = core_init; - return osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); + return osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); } -/** - * @brief ivc_handle_common_nve32_tr - Handles common nve32_terrupt. - * - * @param[in] osi_core: OSI core private data structure. - * - * @note MAC should be init and started. see osi_start_mac() - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - */ -static void ivc_handle_common_intr( - struct osi_core_priv_data *const osi_core) -{ - ivc_msg_common_t msg_common; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - msg_common.cmd = handle_common_intr; - - osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); -} - -/** - * @brief ivc_start_mac - Start MAC Tx/Rx engine - * - * @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() - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - */ -static void ivc_start_mac(struct osi_core_priv_data *const osi_core) -{ - ivc_msg_common_t msg_common; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - msg_common.cmd = start_mac; - - osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); -} - -/** - * @brief ivc_stop_mac - Stop MAC Tx/Rx engine - * - * @param[in] osi_core: OSI core private data structure. - * - * @note MAC DMA deinit should be complete. See osi_hw_dma_deinit() - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - */ -static void ivc_stop_mac(struct osi_core_priv_data *const osi_core) -{ - ivc_msg_common_t msg_common; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - msg_common.cmd = stop_mac; - - osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); -} - -/** - * @brief ivc_config_mac_pkt_filter_reg - configure mac filter register. - * - * @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() - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 always - */ -static nve32_t ivc_config_mac_pkt_filter_reg( - struct osi_core_priv_data *const osi_core, - const struct osi_filter *filter) -{ - ivc_msg_common_t msg_filter; - - osi_memset(&msg_filter, 0, sizeof(msg_filter)); - - msg_filter.cmd = config_mac_pkt_filter_reg; - osi_memcpy((void *)&msg_filter.data.filter, - (void *)filter, sizeof(struct osi_filter)); - - return osi_core->osd_ops.ivc_send(osi_core, &msg_filter, - sizeof(msg_filter)); -} - -/** - * @brief ivc_update_mac_addr_low_high_reg- Update L2 address in filter - * register - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] filter: OSI filter structure. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t ivc_update_mac_addr_low_high_reg( - struct osi_core_priv_data *const osi_core, - const struct osi_filter *filter) -{ - ivc_msg_common_t msg_filter; - - osi_memset(&msg_filter, 0, sizeof(msg_filter)); - - msg_filter.cmd = update_mac_addr_low_high_reg; - osi_memcpy((void *) &msg_filter.data.filter, - (void *) filter, sizeof(struct osi_filter)); - - return osi_core->osd_ops.ivc_send(osi_core, &msg_filter, - sizeof(msg_filter)); -} - -/** - * @brief ivc_config_l3_l4_filter_enable - register write to enable L3/L4 - * filters. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] filter_enb_dis: enable/disable - * - * @note MAC should be init 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 ivc_config_l3_l4_filter_enable( - struct osi_core_priv_data *const osi_core, - const nveu32_t filter_enb_dis) -{ - ivc_msg_common_t msg_common; - nve32_t index = 0; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - msg_common.cmd = config_l3_l4_filter_enable; - msg_common.data.args.arguments[index++] = filter_enb_dis; - msg_common.data.args.count = index; - - return osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); -} - -/** - * @brief ivc_update_ip4_addr - configure register for IPV4 address 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() - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t ivc_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) -{ - ivc_msg_common_t msg_common; - nve32_t index = 0; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - msg_common.cmd = update_ip4_addr; - msg_common.data.args.arguments[index++] = filter_no; - osi_memcpy((void *)(nveu8_t *)&msg_common.data.args.arguments[index++], - (void *)addr, 4); - msg_common.data.args.arguments[index++] = src_dst_addr_match; - msg_common.data.args.count = index; - - return osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); -} - -/** - * @brief ivc_update_ip6_addr - add ipv6 address in register - * - * @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() - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t ivc_update_ip6_addr( - struct osi_core_priv_data *const osi_core, - const nveu32_t filter_no, - const nveu16_t addr[]) -{ - ivc_msg_common_t msg_common; - nve32_t index = 0; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - msg_common.cmd = update_ip6_addr; - msg_common.data.args.arguments[index++] = filter_no; - msg_common.data.args.arguments[index++] = addr[0]; - msg_common.data.args.arguments[index++] = addr[1]; - msg_common.data.args.arguments[index++] = addr[2]; - msg_common.data.args.arguments[index++] = addr[3]; - msg_common.data.args.arguments[index++] = addr[4]; - msg_common.data.args.arguments[index++] = addr[5]; - msg_common.data.args.arguments[index++] = addr[6]; - msg_common.data.args.arguments[index++] = addr[7]; - msg_common.data.args.count = index; - - return osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); -} - -/** - * @brief ivc_update_l4_port_no -program source port no - * - * @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 - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t ivc_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) -{ - ivc_msg_common_t msg_common; - nve32_t index = 0; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - msg_common.cmd = update_l4_port_no; - msg_common.data.args.arguments[index++] = filter_no; - msg_common.data.args.arguments[index++] = port_no; - msg_common.data.args.arguments[index++] = src_dst_port_match; - msg_common.data.args.count = index; - - return osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); -} - -/** - * @brief ivc_config_l3_filters - config L3 filters. - * - * @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 - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t ivc_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) -{ - ivc_msg_common_t msg_common; - nve32_t index = 0; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - msg_common.cmd = config_l3_filters; - msg_common.data.args.arguments[index++] = filter_no; - msg_common.data.args.arguments[index++] = enb_dis; - msg_common.data.args.arguments[index++] = ipv4_ipv6_match; - msg_common.data.args.arguments[index++] = src_dst_addr_match; - msg_common.data.args.arguments[index++] = perfect_inverse_match; - msg_common.data.args.arguments[index++] = dma_routing_enable; - msg_common.data.args.arguments[index++] = dma_chan; - msg_common.data.args.count = index; - - return osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); -} - -/** - * @brief ivc_config_l4_filters - Config L4 filters. - * - * @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 - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t ivc_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) -{ - ivc_msg_common_t msg_common; - nve32_t index = 0; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - msg_common.cmd = config_l4_filters; - msg_common.data.args.arguments[index++] = filter_no; - msg_common.data.args.arguments[index++] = enb_dis; - msg_common.data.args.arguments[index++] = tcp_udp_match; - msg_common.data.args.arguments[index++] = src_dst_port_match; - msg_common.data.args.arguments[index++] = perfect_inverse_match; - msg_common.data.args.arguments[index++] = dma_routing_enable; - msg_common.data.args.arguments[index++] = dma_chan; - msg_common.data.args.count = index; - - return osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); -} - -/** - * @brief ivc_set_systime_to_mac - Set system time - * - * @param[in] osi_core: OSI core private data structure. - * @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() - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t ivc_set_systime_to_mac( - struct osi_core_priv_data *const osi_core, - const nveu32_t sec, - const nveu32_t nsec) -{ - ivc_msg_common_t msg_common; - nve32_t index = 0; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - msg_common.cmd = set_systime_to_mac; - msg_common.data.args.arguments[index++] = sec; - msg_common.data.args.arguments[index++] = nsec; - msg_common.data.args.count = index; - - return osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); -} - -/** - * @brief ivc_config_addend - Configure addend - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] addend: Addend value to be configured - * - * @note MAC should be init 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 ivc_config_addend(struct osi_core_priv_data *const osi_core, - const nveu32_t addend) -{ - ivc_msg_common_t msg_common; - nve32_t index = 0; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - msg_common.cmd = config_addend; - msg_common.data.args.arguments[index++] = addend; - msg_common.data.args.count = index; - - return osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); -} - -/** - * @brief ivc_adjust_mactime - Adjust MAC time with system time - * - * @param[in] osi_core: OSI core private data structure. - * @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 nve32_t ivc_adjust_mactime(struct osi_core_priv_data *const osi_core, - nveu32_t sec, nveu32_t nsec, - nveu32_t add_sub, nveu32_t one_nsec_accuracy) -{ - ivc_msg_common_t msg_common; - nve32_t index = 0; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - msg_common.cmd = adjust_mactime; - msg_common.data.args.arguments[index++] = sec; - msg_common.data.args.arguments[index++] = nsec; - msg_common.data.args.arguments[index++] = add_sub; - msg_common.data.args.arguments[index++] = one_nsec_accuracy; - msg_common.data.args.count = index; - - return osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); -} - -/** - * @brief ivc_config_tscr - Configure Time Stamp Register - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] ptp_filter: PTP rx filter parameters - * - * @note MAC should be init and started. see osi_start_mac() - */ -static void ivc_config_tscr(struct osi_core_priv_data *const osi_core, - const nveu32_t ptp_filter) -{ - ivc_msg_common_t msg_common; - nve32_t index = 0; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - msg_common.cmd = config_tscr; - msg_common.data.args.arguments[index++] = ptp_filter; - msg_common.data.args.count = index; - - osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); -} - -/** - * @brief ivc_config_ssir - Configure SSIR - * - * @param[in] osi_core: OSI core private data structure. - * - * @note MAC should be init and started. see osi_start_mac() - */ -static void ivc_config_ssir(struct osi_core_priv_data *const osi_core, - const unsigned int ptp_clock) -{ - ivc_msg_common_t msg_common; - nve32_t index = 0; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - msg_common.cmd = config_ssir; - msg_common.data.args.arguments[index++] = ptp_clock; - msg_common.data.args.count = index; - - osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); -} - -/** - * @brief ivc_read_mmc - To read 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 - */ -static void ivc_read_mmc(struct osi_core_priv_data *osi_core) -{ - ivc_msg_common_t msg_common; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - msg_common.cmd = read_mmc; - - osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); - - osi_memcpy((void *)&osi_core->mmc, &msg_common.data.mmc, - sizeof(struct osi_mmc_counters)); -} /** * @brief ivc_core_deinit - EQOS MAC core deinitialization @@ -867,8 +100,19 @@ static void ivc_read_mmc(struct osi_core_priv_data *osi_core) */ static void ivc_core_deinit(struct osi_core_priv_data *const osi_core) { - /* Stop the MAC by disabling both MAC Tx and Rx */ - ivc_stop_mac(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 */ + } + } /** @@ -889,56 +133,20 @@ static nve32_t ivc_write_phy_reg(struct osi_core_priv_data *const osi_core, const nveu32_t phyreg, const nveu16_t phydata) { - ivc_msg_common_t msg_common; - nve32_t index = 0; + ivc_msg_common_t msg; + nveu32_t index = 0; - osi_memset(&msg_common, 0, sizeof(msg_common)); + osi_memset(&msg, 0, sizeof(msg)); - msg_common.cmd = write_phy_reg; - msg_common.data.args.arguments[index++] = phyaddr; - msg_common.data.args.arguments[index++] = phyreg; - msg_common.data.args.arguments[index++] = phydata; - msg_common.data.args.count = index; + 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_common, - sizeof(msg_common)); + return osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); } -/** - * @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_common; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - - if (data->cmd == OSI_CMD_CONFIG_PTP) { - osi_memcpy((void *)&data->ptp_config, - (void *)&osi_core->ptp_config, - sizeof(struct osi_ptp_config)); - } - - msg_common.cmd = handle_ioctl; - osi_memcpy((void *)&msg_common.data.ioctl_data, (void *)data, - sizeof(struct osi_ioctl)); - ret = osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); - osi_memcpy((void *)data, (void *)&msg_common.data.ioctl_data, - sizeof(struct osi_ioctl)); - return ret; -} /** * @brief ivc_read_phy_reg - Read from a PHY register through MAC over MDIO bus @@ -956,535 +164,20 @@ 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_common; - nve32_t index = 0; + ivc_msg_common_t msg; + nveu32_t index = 0; - osi_memset(&msg_common, 0, sizeof(msg_common)); + osi_memset(&msg, 0, sizeof(msg)); - msg_common.cmd = read_phy_reg; - msg_common.data.args.arguments[index++] = phyaddr; - msg_common.data.args.arguments[index++] = phyreg; - msg_common.data.args.count = index; + 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_common, - sizeof(msg_common)); + return osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); } -/** - * @brief ivc_read_reg - Read a reg - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] reg: Register. - * - * @retval data from register on success - * @retval -1 on failure - */ -static nveu32_t ivc_read_reg(struct osi_core_priv_data *const osi_core, - const nve32_t reg) { - ivc_msg_common_t msg_common; - nve32_t index = 0; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - msg_common.cmd = reg_read; - msg_common.data.args.arguments[index++] = reg; - msg_common.data.args.count = index; - - return osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); -} - -/** - * @brief ivc_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. - * - * @retval data from register on success - * @retval -1 on failure - */ -static nveu32_t ivc_write_reg(struct osi_core_priv_data *const osi_core, - const nveu32_t val, const nve32_t reg) { - ivc_msg_common_t msg_common; - nve32_t index = 0; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - msg_common.cmd = reg_write; - msg_common.data.args.arguments[index++] = val; - msg_common.data.args.arguments[index++] = reg; - msg_common.data.args.count = index; - - return osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); -} - -static nve32_t ivc_get_hw_features(struct osi_core_priv_data *const osi_core, - struct osi_hw_features *hw_feat) -{ - ivc_msg_common_t msg_hw_feat; - nve32_t ret = 0; - - osi_memset(&msg_hw_feat, 0, sizeof(msg_hw_feat)); - - msg_hw_feat.cmd = get_hw_features; - - ret = osi_core->osd_ops.ivc_send(osi_core, &msg_hw_feat, - sizeof(msg_hw_feat)); - if (ret != 0) { - return ret; - } - - osi_memcpy((void *)hw_feat, (void *)&msg_hw_feat.data.hw_feat, - sizeof(struct osi_hw_features)); - - return ret; -} - -#ifndef OSI_STRIPPED_LIB -/** - * @brief ivc_config_flow_control - Configure MAC flow control settings - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] flw_ctrl: flw_ctrl settings - * - * @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 ivc_config_flow_control( - struct osi_core_priv_data *const osi_core, - const nveu32_t flw_ctrl) -{ - ivc_msg_common_t msg_common; - nve32_t index = 0; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - msg_common.cmd = config_flow_control; - msg_common.data.args.arguments[index++] = flw_ctrl; - msg_common.data.args.count = index; - - return osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); -} - -/** - * @brief Read-validate HW registers for functional safety. - * - * @param[in] osi_core: OSI core private data structure. - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t ivc_validate_core_regs(struct osi_core_priv_data *const osi_core) -{ - ivc_msg_common_t msg_common; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - msg_common.cmd = validate_regs; - - return osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); -} - -/** - * @brief ivc_config_rx_crc_check - Configure CRC Checking for Rx Packets - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] crc_chk: Enable or disable checking of CRC field in received pkts - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t ivc_config_rx_crc_check( - struct osi_core_priv_data *const osi_core, - const nveu32_t crc_chk) -{ - ivc_msg_common_t msg_common; - nve32_t index = 0; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - msg_common.cmd = config_rx_crc_check; - msg_common.data.args.arguments[index++] = crc_chk; - msg_common.data.args.count = index; - - return osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); -} - -/** - * @brief ivc_flush_mtl_tx_queue - Flush MTL Tx queue - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] qinx: MTL queue index. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t ivc_flush_mtl_tx_queue( - struct osi_core_priv_data *const osi_core, - const nveu32_t qinx) -{ - ivc_msg_common_t msg_common; - nve32_t index = 0; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - msg_common.cmd = flush_mtl_tx_queue; - msg_common.data.args.arguments[index++] = qinx; - msg_common.data.args.count = index; - - return osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); -} - -/** - * @brief ivc_config_tx_status - Configure MAC to forward the tx pkt status - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] tx_status: Enable or Disable the forwarding of tx pkt status - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t ivc_config_tx_status(struct osi_core_priv_data *const osi_core, - const nveu32_t tx_status) -{ - ivc_msg_common_t msg_common; - nve32_t index = 0; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - msg_common.cmd = config_tx_status; - msg_common.data.args.arguments[index++] = tx_status; - msg_common.data.args.count = index; - - return osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); -} - -/** - * @brief ivc_set_avb_algorithm - Set TxQ/TC avb config - * - * @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 nve32_t ivc_set_avb_algorithm( - struct osi_core_priv_data *const osi_core, - const struct osi_core_avb_algorithm *const avb) -{ - ivc_msg_common_t msg_avb; - - osi_memset(&msg_avb, 0, sizeof(msg_avb)); - - msg_avb.cmd = set_avb_algorithm; - osi_memcpy((void *)&msg_avb.data.avb_algo, (void *)avb, - sizeof(struct osi_core_avb_algorithm)); - - return osi_core->osd_ops.ivc_send(osi_core, &msg_avb, - sizeof(msg_avb)); -} - -/** - * @brief ivc_get_avb_algorithm - Get TxQ/TC avb config - * - * @param[in] osi_core: osi core priv data structure - * @param[out] avb: structure ponve32_ter 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 nve32_t ivc_get_avb_algorithm(struct osi_core_priv_data *const osi_core, - struct osi_core_avb_algorithm *const avb) -{ - ivc_msg_common_t msg_avb; - - osi_memset(&msg_avb, 0, sizeof(msg_avb)); - - msg_avb.cmd = get_avb_algorithm; - osi_memcpy((void *) &msg_avb.data.avb_algo, - (void *)avb, sizeof(struct osi_core_avb_algorithm)); - - return osi_core->osd_ops.ivc_send(osi_core, &msg_avb, - sizeof(msg_avb)); -} - -/** - * @brief ivc_config_arp_offload - Enable/Disable ARP offload - * - * @param[in] osi_core: OSI core private 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. - * - * @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 nve32_t ivc_config_arp_offload( - struct osi_core_priv_data *const osi_core, - const nveu32_t enable, - const nveu8_t *ip_addr) -{ - ivc_msg_common_t msg_common; - nve32_t index = 0; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - msg_common.cmd = config_arp_offload; - msg_common.data.args.arguments[index++] = enable; - osi_memcpy((void *)(nveu8_t *)&msg_common.data.args.arguments[index++], - (void *)ip_addr, 4); - msg_common.data.args.count = index; - - return osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); -} - -/** - * @brief ivc_config_vlan_filter_reg - config vlan filter register - * - * @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 nve32_t ivc_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) -{ - ivc_msg_common_t msg_common; - nve32_t index = 0; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - msg_common.cmd = config_vlan_filtering; - msg_common.data.args.arguments[index++] = filter_enb_dis; - msg_common.data.args.arguments[index++] = perfect_hash_filtering; - msg_common.data.args.arguments[index++] = perfect_inverse_match; - msg_common.data.args.count = index; - - return osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); -} - -/** - * @brief ivc_update_vlan_id - update VLAN ID in Tag register - * - * @param[in] base: Base address from OSI core private data structure. - * @param[in] vid: VLAN ID to be programmed. - * - * @retval 0 always - */ -static inline nve32_t ivc_update_vlan_id( - struct osi_core_priv_data *const osi_core, - nveu32_t vid) -{ - /* Don't add VLAN ID to TR register which is eventually set TR - * to 0x0 and allow all tagged packets - */ - ivc_msg_common_t msg_common; - nve32_t index = 0; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - msg_common.cmd = i_update_vlan_id; - msg_common.data.args.arguments[index++] = vid; - msg_common.data.args.count = index; - - return osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); -} - -/** - * @brief ivc_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 - */ -static void ivc_reset_mmc(struct osi_core_priv_data *osi_core) -{ - ivc_msg_common_t msg_common; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - msg_common.cmd = reset_mmc; - - osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); -} - -/** - * @brief ivc_configure_eee - Configure the EEE LPI mode - * - * @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. - * - * @note - * Required clks and resets has to be enabled. - * MAC/PHY should be initialized - */ -static void ivc_configure_eee(struct osi_core_priv_data *const osi_core, - const nveu32_t tx_lpi_enabled, - const nveu32_t tx_lpi_timer) -{ - ivc_msg_common_t msg_common; - nve32_t index = 0; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - msg_common.cmd = configure_eee; - msg_common.data.args.arguments[index++] = tx_lpi_enabled; - msg_common.data.args.arguments[index++] = tx_lpi_timer; - msg_common.data.args.count = index; - - osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); -} - -/* - * @brief Function to store a backup of MAC register space during SOC suspend. - * - * @param[in] osi_core: OSI core private data structure. - * - * @retval 0 on Success - */ -static inline nve32_t ivc_save_registers( - struct osi_core_priv_data *const osi_core) -{ - ivc_msg_common_t msg_common; - nve32_t index = 0; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - msg_common.cmd = save_registers; - msg_common.data.args.count = index; - - return osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); -} - -/** - * @brief Function to restore the backup of MAC registers during SOC resume. - * - * @param[in] osi_core: OSI core private data structure. - * - * @retval 0 on Success - */ -static inline nve32_t ivc_restore_registers( - struct osi_core_priv_data *const osi_core) -{ - ivc_msg_common_t msg_common; - nve32_t index = 0; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - msg_common.cmd = restore_registers; - msg_common.data.args.count = index; - - return osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); -} - -/** - * @brief ivc_set_mdc_clk_rate - Derive MDC clock based on provided AXI_CBB clk - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] csr_clk_rate: CSR (AXI CBB) clock rate. - * - * @note OSD layer needs get the AXI CBB clock rate with OSD clock API - * (ex - clk_get_rate()) - */ -static void ivc_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, - const nveu64_t csr_clk_rate) -{ - ivc_msg_common_t msg_common; - nve32_t index = 0; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - msg_common.cmd = set_mdc_clk_rate; - msg_common.data.args.arguments[index++] = csr_clk_rate; - msg_common.data.args.count = index; - - osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); -} - -/** - * @brief ivc_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 - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t ivc_config_mac_loopback( - struct osi_core_priv_data *const osi_core, - const nveu32_t lb_mode) -{ - ivc_msg_common_t msg_common; - nve32_t index = 0; - - osi_memset(&msg_common, 0, sizeof(msg_common)); - - msg_common.cmd = config_mac_loopback; - msg_common.data.args.arguments[index++] = lb_mode; - msg_common.data.args.count = index; - - return osi_core->osd_ops.ivc_send(osi_core, &msg_common, - sizeof(msg_common)); -} -#endif - +#ifdef MACSEC_SUPPORT /** * @brief ivc_macsec_dbg_events_config - Configure Debug events * @@ -1498,8 +191,27 @@ 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; - return 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; } /** @@ -1511,10 +223,31 @@ static int ivc_macsec_dbg_events_config( * @retval 0 on Success * @retval -1 on Failure */ -static int ivc_macsec_dbg_buf_config(struct osi_core_priv_data *const osi_core, +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) { - return 0; + 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; } /** @@ -1531,7 +264,17 @@ static int ivc_macsec_dbg_buf_config(struct osi_core_priv_data *const osi_core, */ 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)); } /** @@ -1551,7 +294,26 @@ static int ivc_macsec_config(struct osi_core_priv_data *const osi_core, unsigned int enable, unsigned short ctlr, unsigned short *kt_idx) { - return 0; + 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; } /** @@ -1563,10 +325,19 @@ static int ivc_macsec_config(struct osi_core_priv_data *const osi_core, * @retval 0 on Success * @retval -1 on Failure */ -static int ivc_macsec_enable(struct osi_core_priv_data *osi_core, +static int ivc_macsec_enable(struct osi_core_priv_data *const osi_core, unsigned int enable) { - return 0; + 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; + msg.data.args.count = index; + + return osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); } /** @@ -1581,7 +352,16 @@ static int ivc_macsec_enable(struct osi_core_priv_data *osi_core, static int ivc_macsec_loopback_config(struct osi_core_priv_data *const osi_core, unsigned int enable) { - return 0; + 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; + msg.data.args.count = index; + + return osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); } #ifdef MACSEC_KEY_PROGRAM @@ -1597,10 +377,42 @@ static int ivc_macsec_loopback_config(struct osi_core_priv_data *const osi_core, static int ivc_macsec_kt_config(struct osi_core_priv_data *const osi_core, struct osi_macsec_kt_config *const kt_config) { - return 0; + ivc_msg_common_t msg; + + 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)); + + return osi_core->osd_ops.ivc_send(osi_core, (char *)&msg, sizeof(msg)); } #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; + msg.data.args.count = index; + + return osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); +} /** * @brief ivc_macsec_lut_config - LUT config. * @@ -1613,7 +425,16 @@ static int ivc_macsec_kt_config(struct osi_core_priv_data *const osi_core, static int ivc_macsec_lut_config(struct osi_core_priv_data *const osi_core, struct osi_macsec_lut_config *const lut_config) { - return 0; + ivc_msg_common_t msg; + + 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)); + + return osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); } /** @@ -1649,7 +470,13 @@ static void ivc_macsec_handle_ns_irq(struct osi_core_priv_data *const osi_core) static int ivc_macsec_deinit(struct osi_core_priv_data *const osi_core) { - return 0; + 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)); } /** @@ -1663,69 +490,14 @@ static int ivc_macsec_deinit(struct osi_core_priv_data *const osi_core) */ static int ivc_macsec_init(struct osi_core_priv_data *const osi_core) { - return 0; -} + ivc_msg_common_t msg; -/** - * @brief ivc_init_core_ops - Initialize IVC core operations. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - */ -void ivc_init_core_ops(struct core_ops *ops) -{ - ops->poll_for_swr = ivc_poll_for_swr; - ops->core_init = ivc_core_init; - ops->core_deinit = ivc_core_deinit; - ops->start_mac = ivc_start_mac; - ops->stop_mac = ivc_stop_mac; - ops->handle_common_intr = ivc_handle_common_intr; - ops->set_mode = ivc_set_mode; - ops->set_speed = ivc_set_speed; - ops->pad_calibrate = ivc_pad_calibrate; - ops->config_fw_err_pkts = ivc_config_fw_err_pkts; - ops->config_rxcsum_offload = ivc_config_rxcsum_offload; - ops->config_mac_pkt_filter_reg = ivc_config_mac_pkt_filter_reg; - ops->update_mac_addr_low_high_reg = ivc_update_mac_addr_low_high_reg; - ops->config_l3_l4_filter_enable = ivc_config_l3_l4_filter_enable; - ops->config_l3_filters = ivc_config_l3_filters; - ops->update_ip4_addr = ivc_update_ip4_addr; - ops->update_ip6_addr = ivc_update_ip6_addr; - ops->config_l4_filters = ivc_config_l4_filters; - ops->update_l4_port_no = ivc_update_l4_port_no; - ops->set_systime_to_mac = ivc_set_systime_to_mac; - ops->config_addend = ivc_config_addend; - ops->adjust_mactime = ivc_adjust_mactime; - ops->config_tscr = ivc_config_tscr; - ops->config_ssir = ivc_config_ssir; - ops->read_mmc = ivc_read_mmc; - ops->write_phy_reg = ivc_write_phy_reg; - ops->read_phy_reg = ivc_read_phy_reg; - ops->read_reg = ivc_read_reg; - ops->write_reg = ivc_write_reg; - ops->get_hw_features = ivc_get_hw_features; -#ifndef OSI_STRIPPED_LIB - ops->config_tx_status = ivc_config_tx_status; - ops->config_rx_crc_check = ivc_config_rx_crc_check; - ops->config_flow_control = ivc_config_flow_control; - ops->config_arp_offload = ivc_config_arp_offload; - ops->validate_regs = ivc_validate_core_regs; - ops->flush_mtl_tx_queue = ivc_flush_mtl_tx_queue; - ops->set_avb_algorithm = ivc_set_avb_algorithm; - ops->get_avb_algorithm = ivc_get_avb_algorithm; - ops->config_vlan_filtering = ivc_config_vlan_filtering; - ops->update_vlan_id = ivc_update_vlan_id; - ops->reset_mmc = ivc_reset_mmc; - ops->configure_eee = ivc_configure_eee; - ops->save_registers = ivc_save_registers; - ops->restore_registers = ivc_restore_registers; - ops->set_mdc_clk_rate = ivc_set_mdc_clk_rate; - ops->config_mac_loopback = ivc_config_mac_loopback; -#endif /* !OSI_STRIPPED_LIB */ -}; + osi_memset(&msg, 0, sizeof(msg)); + + msg.cmd = init_macsec; + + return osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); +} /** * @brief ivc_init_macsec_ops - Initialize IVC core operations. @@ -1748,6 +520,7 @@ void ivc_init_macsec_ops(void *macsecops) #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; @@ -1755,6 +528,7 @@ void ivc_init_macsec_ops(void *macsecops) ops->dbg_buf_config = ivc_macsec_dbg_buf_config; ops->dbg_events_config = ivc_macsec_dbg_events_config; } +#endif /** * @brief ivc_get_core_safety_config - EQOS MAC safety configuration diff --git a/osi/core/macsec.c b/osi/core/macsec.c index 5122c5d..e752f10 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -24,9 +24,15 @@ #include <linux/crypto.h> #endif #include <osi_macsec.h> -#include <linux/printk.h> #include "macsec.h" #include "../osi/common/common.h" +#include "core_local.h" +#ifdef LINUX_IVC +#include <linux/printk.h> +#else +#define pr_cont(args...) +#define pr_err(args...) +#endif /** * @brief poll_for_dbg_buf_update - Query the status of a debug buffer update. @@ -2942,6 +2948,12 @@ static struct macsec_core_ops macsec_ops = { .dbg_events_config = macsec_dbg_events_config, }; +/** + * @brief if_ops - Static core interface operations for virtual + * case + */ +static struct macsec_core_ops virt_macsec_ops; + static struct osi_macsec_lut_status lut_status[NUM_CTLR]; int osi_init_macsec_ops(struct osi_core_priv_data *const osi_core) @@ -2949,7 +2961,12 @@ int osi_init_macsec_ops(struct osi_core_priv_data *const osi_core) if (osi_core->macsec_base == OSI_NULL) { return -1; } else { - osi_core->macsec_ops = &macsec_ops; + if (osi_core->use_virtualization == OSI_ENABLE) { + osi_core->macsec_ops = &virt_macsec_ops; + ivc_init_macsec_ops(osi_core->macsec_ops); + } else { + osi_core->macsec_ops = &macsec_ops; + } osi_core->macsec_lut_status = lut_status; return 0; } diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c old mode 100644 new mode 100755 index 8e625ab..c836d64 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -1553,6 +1553,14 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, ret = config_fpe(osi_core, &data->fpe); break; + case OSI_CMD_READ_REG: + ret = ops_p->read_reg(osi_core, (nve32_t) data->arg1_u32); + break; + + case OSI_CMD_WRITE_REG: + ret = ops_p->write_reg(osi_core, (nve32_t) data->arg1_u32, + (nve32_t) data->arg2_u32); + break; default: OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "CORE: Incorrect command\n", From cc38efe70863a25afc3e463f253477da1ce1109d Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Mon, 31 May 2021 21:06:28 +0530 Subject: [PATCH 242/458] osi: mgbe: fix disabling VM interrupts Issue: At OSI level MGBE interrupts not disabled with osi_dma_handle_intr() API because disabling interrupts code missing for MGBE. Fix: Add disabling TX/RX interrupts. Bug 200722499 Change-Id: I274dfe3e5a02c36783c886f5e153790685b81503 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2537508 Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/dma/mgbe_dma.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osi/dma/mgbe_dma.c b/osi/dma/mgbe_dma.c index 4c3343c..2a9465c 100644 --- a/osi/dma/mgbe_dma.c +++ b/osi/dma/mgbe_dma.c @@ -689,6 +689,8 @@ static void mgbe_clear_vm_tx_intr(void *addr, nveu32_t chan) (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); } /** @@ -707,6 +709,8 @@ static void mgbe_clear_vm_rx_intr(void *addr, nveu32_t chan) (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); } /** From 3a81b9f2aa048cedf1980bde6d4b21c3ccb9af86 Mon Sep 17 00:00:00 2001 From: Nagarjuna Kristam <nkristam@nvidia.com> Date: Mon, 24 May 2021 10:14:43 +0530 Subject: [PATCH 243/458] osi: common: Move VM IRQ configuration core to dma Issue: VM IRQ configuration needs is done using DMA base, instead of RM base. Fix: Add VM IRQ configuration code to osi core init sequence. Remove the same code in DMA. Bug 200718904 Bug 200730767 Change-Id: I5bf41c85d745a977875ed2eeb044b4db088e0b64 Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2539623 Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> --- include/osi_core.h | 16 ++++++++++++++++ include/osi_dma.h | 16 ---------------- osi/core/eqos_core.c | 38 ++++++++++++++++++++++++++++++++++++++ osi/core/eqos_core.h | 1 + osi/core/mgbe_core.c | 36 ++++++++++++++++++++++++++++++++++++ osi/core/mgbe_core.h | 1 + osi/dma/eqos_dma.c | 36 ------------------------------------ osi/dma/mgbe_dma.c | 37 ------------------------------------- 8 files changed, 92 insertions(+), 89 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 07df5f3..3677557 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -942,6 +942,18 @@ struct core_backup { 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 */ @@ -1170,6 +1182,10 @@ struct osi_core_priv_data { 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; }; /** diff --git a/include/osi_dma.h b/include/osi_dma.h index 5421beb..58432a2 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -463,18 +463,6 @@ struct osi_xtra_dma_stat_counters { struct osi_dma_priv_data; -/** - * @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 DMA callbacks */ @@ -550,10 +538,6 @@ struct osi_dma_priv_data { 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]; - /** number of VM IRQ's */ - nveu32_t num_vm_irqs; - /** Array of VM IRQ's */ - struct osi_vm_irq_data irq_data[OSI_MAX_VM_IRQS]; /** DMA callback ops structure */ struct osd_dma_ops osd_ops; /** Virtual address of reserved DMA buffer */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index f300ecc..fe8b49e 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1856,6 +1856,42 @@ static void eqos_tsn_init(struct osi_core_priv_data *osi_core, * 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)); + } + } +} + /** * @brief eqos_core_init - EQOS MAC, MTL and common DMA Initialization * @@ -1975,6 +2011,8 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core, /* initialize L3L4 Filters variable */ osi_core->l3l4_filter_bitmask = OSI_NONE; + eqos_dma_chan_to_vmirq_map(osi_core); + return ret; } diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 4d48c7b..a3c6da2 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -180,6 +180,7 @@ #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)) /** @} */ /** diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index cea99ec..fe29e92 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -2994,6 +2994,40 @@ static void mgbe_tsn_init(struct osi_core_priv_data *osi_core, */ } +/** + * @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. + */ +static void mgbe_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; + + 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(0xD, (nveu8_t *)osi_core->base + 0x8400); +} + + /** * @brief mgbe_core_init - MGBE MAC, MTL and common DMA Initialization * @@ -3100,6 +3134,8 @@ static nve32_t mgbe_core_init(struct osi_core_priv_data *osi_core, osi_core->hw_feature->fpe_sel); } + mgbe_dma_chan_to_vmirq_map(osi_core); + return 0; } diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 71faf9d..f3c803a 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -120,6 +120,7 @@ */ #define MGBE_WRAP_COMMON_INTR_ENABLE 0x8704 #define MGBE_WRAP_COMMON_INTR_STATUS 0x8708 +#define MGBE_VIRT_INTR_APB_CHX_CNTRL(x) (0x8200U + ((x) * 4U)) /** @} */ /** diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index 633fee4..31c5067 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -709,40 +709,6 @@ static void eqos_configure_dma_channel(nveu32_t chan, } } -/** - * @brief eqos_dma_chan_to_vmirq_map - Map DMA channels to a specific VM IRQ. - * - * @param[in] osi_dma: OSI private data structure. - * - * Algorithm: Programs HW to map DMA channels to specific VM. - * - * @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_dma_priv_data *osi_dma) -{ - struct osi_vm_irq_data *irq_data; - nveu32_t i, j; - nveu32_t chan; - - for (i = 0; i < osi_dma->num_vm_irqs; i++) { - irq_data = &osi_dma->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_dma->base + - EQOS_VIRT_INTR_APB_CHX_CNTRL(chan)); - } - } -} - /** * @brief eqos_init_dma_channel - DMA channel INIT * @@ -773,8 +739,6 @@ static nve32_t eqos_init_dma_channel(struct osi_dma_priv_data *osi_dma) eqos_configure_dma_channel(osi_dma->dma_chans[chinx], osi_dma); } - eqos_dma_chan_to_vmirq_map(osi_dma); - return 0; } diff --git a/osi/dma/mgbe_dma.c b/osi/dma/mgbe_dma.c index 2a9465c..98b7c39 100644 --- a/osi/dma/mgbe_dma.c +++ b/osi/dma/mgbe_dma.c @@ -522,41 +522,6 @@ static void mgbe_configure_dma_channel(nveu32_t chan, MGBE_DMA_CHX_RX_CNTRL2(chan)); } -/** - * @brief mgbe_dma_chan_to_vmirq_map - Map DMA channels to a specific VM IRQ. - * - * Algorithm: Programs HW to map DMA channels to specific VM. - * - * @param[in] osi_dma: OSI DMA private data structure. - * - * @note OSD layer needs to update number of VM channels and - * DMA channel list in osi_vm_irq_data. - */ -static void mgbe_dma_chan_to_vmirq_map(struct osi_dma_priv_data *osi_dma) -{ - struct osi_vm_irq_data *irq_data; - nveu32_t i, j; - nveu32_t chan; - - for (i = 0; i < osi_dma->num_vm_irqs; i++) { - irq_data = &osi_dma->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_dma->base + - MGBE_VIRT_INTR_APB_CHX_CNTRL(chan)); - } - } - - osi_writel(0xD, (nveu8_t *)osi_dma->base + 0x8400); -} - /** * @brief mgbe_init_dma_channel - DMA channel INIT * @@ -602,8 +567,6 @@ static nve32_t mgbe_init_dma_channel(struct osi_dma_priv_data *osi_dma) owrq, orrq, osi_dma); } - mgbe_dma_chan_to_vmirq_map(osi_dma); - return 0; } From 9b1cf186e937766c60933346d78cdebb94e5f54b Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Thu, 10 Jun 2021 14:04:08 +0530 Subject: [PATCH 244/458] osi: core: ivc: Fix MMC counter read issue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issue: MMC counters are not updated when the ethernet virtualization server is enabled. Fix: Handle MMC counter copy properly in IVC IOVTL’s function. Bug 200647791 Change-Id: I544cccbf1b4ca599a7137ac3f793c956b066b7d2 Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2542447 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: svc_kernel_abi <svc_kernel_abi@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/ivc_core.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index df25935..b457c15 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -61,9 +61,15 @@ static nve32_t ivc_handle_ioctl(struct osi_core_priv_data *osi_core, ret = osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); - msg.status = osi_memcpy((void *)data, - (void *)&msg.data.ioctl_data, - sizeof(struct osi_ioctl)); + 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; } From eeede50c2cb00779d983efb5ec9eff35d60b2557 Mon Sep 17 00:00:00 2001 From: Nagarjuna Kristam <nkristam@nvidia.com> Date: Wed, 9 Jun 2021 20:11:53 +0530 Subject: [PATCH 245/458] osi: dma: Flush packets on DMA stop Issue: When DMA channel is stopped, but packet for that channel is not yet process from RX queue, it will not be processed and will result in all other channel packets stuck in the queue. Fix: Enable RPF(Rx packet flush) bit when stop DMA and reset in start DMA. This wil ensure any packet in RX queue for stopped DMA will be flushed and ensuresmooth working of all other channels. Bug 200718904 Change-Id: I12f9ecc1754a82d2c2a90d27448348bb4acde349 Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2541985 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: svc_kernel_abi <svc_kernel_abi@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/dma/eqos_dma.c | 2 ++ osi/dma/mgbe_dma.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index 31c5067..cda570a 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -539,6 +539,7 @@ static void eqos_start_dma(struct osi_dma_priv_data *osi_dma, nveu32_t chan) 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); @@ -583,6 +584,7 @@ static void eqos_stop_dma(struct osi_dma_priv_data *osi_dma, nveu32_t chan) 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); diff --git a/osi/dma/mgbe_dma.c b/osi/dma/mgbe_dma.c index 98b7c39..75e2d9f 100644 --- a/osi/dma/mgbe_dma.c +++ b/osi/dma/mgbe_dma.c @@ -316,6 +316,7 @@ static void mgbe_start_dma(struct osi_dma_priv_data *osi_dma, nveu32_t 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)); } @@ -345,6 +346,7 @@ static void mgbe_stop_dma(struct osi_dma_priv_data *osi_dma, nveu32_t 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)); } From ac083ef3531d4078eb81d4eab2f48bc409c82d71 Mon Sep 17 00:00:00 2001 From: Nagarjuna Kristam <nkristam@nvidia.com> Date: Wed, 9 Jun 2021 20:17:22 +0530 Subject: [PATCH 246/458] core: eqos: Fix DCS setting during filter delete Issue: When a L2 filter is deleted, corresponding channel bit is reset on local variable and OR'ed with register value. Due to OR operation value was never got reset. Fix: Clear register value for all DCS bit and OR with temp value containing final list of DCS bits. Bug 200718904 Change-Id: I7c26b06babede74851916ae846a2fe5cf62645f4 Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2541986 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: svc_kernel_abi <svc_kernel_abi@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/eqos_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index fe8b49e..5124638 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -2746,6 +2746,7 @@ static void eqos_l2_filter_delete(struct osi_core_priv_data *osi_core, 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))); From 7a1d12756db45ef619bf33464502bd83d920afb9 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Fri, 11 Jun 2021 12:48:45 +0530 Subject: [PATCH 247/458] osi: xpcs: support for Tx/Rx lane bring-up MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Below is per Lane bring-up sequence as per IAS SW should trigger per lane bring up sequence as follows. o Set PCS_WRAP_UPHY_HW_INIT_CONTROL_0_0. HW_TX_INIT_EN = 1 o Set PCS_WRAP_UPHY_HW_INIT_CONTROL_0_0. HW_RX_INIT_EN = 1 o Wait for HW_TX_INIT_EN = 0 o Wait for HW_RX_INIT_EN = 0 o Check PCS Lock status by reading the status bit “PCS_WRAP_INTERRUPT_STATUS_0.PCS_LINK_STS” This change implements above sequence. Above sequence not required for pre-silicon platforms because NvUPHY is not available. Bug 200740702 Change-Id: I40415e25bc6ded9a1692a381399105487a306efc Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2543048 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: svc_kernel_abi <svc_kernel_abi@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/xpcs.c | 129 ++++++++++++++++++++++++++++++++++++++++++++++++ osi/core/xpcs.h | 15 +++++- 2 files changed, 143 insertions(+), 1 deletion(-) diff --git a/osi/core/xpcs.c b/osi/core/xpcs.c index 8b9c392..468f8a3 100644 --- a/osi/core/xpcs.c +++ b/osi/core/xpcs.c @@ -194,6 +194,127 @@ int xpcs_start(struct osi_core_priv_data *osi_core) 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 = xpcs_read(xpcs_base, XPCS_WRAP_UPHY_HW_INIT_CTRL); + val |= lane_init_en; + xpcs_write(xpcs_base, XPCS_WRAP_UPHY_HW_INIT_CTRL, val); + + count = 0; + while (cond == COND_NOT_MET) { + if (count > retry) { + return -1; + } + count++; + + val = xpcs_read(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 = xpcs_read(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 */ + xpcs_write(xpcs_base, XPCS_WRAP_IRQ_STATUS, val); + + 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) +{ + 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; + } + + if (xpcs_uphy_lane_bring_up(osi_core, + XPCS_WRAP_UPHY_HW_INIT_CTRL_RX_EN) < 0) { + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + "UPHY RX lane bring-up failed\n", 0ULL); + return -1; + } + + if (xpcs_check_pcs_lock_status(osi_core) < 0) { + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + "PCS block lock not achieved\n", 0ULL); + return -1; + } + + return 0; +} + /** * @brief xpcs_init - XPCS initialization * @@ -219,6 +340,14 @@ int xpcs_init(struct osi_core_priv_data *osi_core) 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 */ diff --git a/osi/core/xpcs.h b/osi/core/xpcs.h index 9e5f806..caec9f6 100644 --- a/osi/core/xpcs.h +++ b/osi/core/xpcs.h @@ -26,6 +26,15 @@ #include "../osi/common/common.h" #include <osi_core.h> +/** + * @addtogroup XPCS helper macros + * + * @brief XPCS helper macros. + * @{ + */ +#define XPCS_RETRY_COUNT (RETRY_COUNT * (2U)) +/** @} */ + /** * @addtogroup XPCS Register offsets * @@ -44,6 +53,8 @@ #define XPCS_SR_MII_CTRL 0x7C0000 #define XPCS_VR_MII_AN_INTR_STS 0x7E0008 #define XPCS_VR_XS_PCS_EEE_MCTRL0 0xE00018 +#define XPCS_WRAP_UPHY_HW_INIT_CTRL 0x8020 +#define XPCS_WRAP_IRQ_STATUS 0x8050 /** @} */ @@ -79,6 +90,9 @@ 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) /** @} */ int xpcs_init(struct osi_core_priv_data *osi_core); @@ -120,5 +134,4 @@ static inline void xpcs_write(void *xpcs_base, unsigned int reg_addr, osi_writel(val, (unsigned char *)xpcs_base + (((reg_addr) & XPCS_REG_VALUE_MASK))); } - #endif From ebc209f6dc11f6b49b1934a7f0b98794a0102354 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Thu, 24 Jun 2021 13:21:10 +0530 Subject: [PATCH 248/458] osi: eqos: apply IPG settings for EQOS 5.30 Increasing IPG for EQOS MAC created issue for the performance. Restricting the IPG settings only for Orin EQOS. Bug 3331025 Change-Id: Ic389ac70c2c4f517321037b427c36028cee99b07 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2549246 Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: svc_kernel_abi <svc_kernel_abi@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/eqos_core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 5124638..7f14356 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1669,7 +1669,9 @@ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) eqos_configure_rxq_priority(osi_core); } #ifdef MACSEC_SUPPORT - eqos_config_macsec_ipg(osi_core); + if (osi_core->mac_ver == OSI_EQOS_MAC_5_30) { + eqos_config_macsec_ipg(osi_core); + } #endif /* MACSEC_SUPPORT */ } From af440c1347e0ba8451ddc0e9acad16a275ba9143 Mon Sep 17 00:00:00 2001 From: rakesh goyal <rgoyal@nvidia.com> Date: Tue, 30 Jun 2020 21:20:14 +0530 Subject: [PATCH 249/458] osi: common: Add support for MGBE 2 step timestamp - OSI DMA -- During Trasnmit: --- include/osi_core.h | 39 ++++++++++ include/osi_dma.h | 6 ++ osi/common/include/local_common.h | 11 +++ osi/core/core_local.h | 10 +++ osi/core/mgbe_core.c | 68 ++++++++++++++++- osi/core/mgbe_core.h | 8 ++ osi/core/osi_core.c | 3 + osi/core/osi_hal.c | 84 +++++++++++++++++++++ osi/dma/dma_local.h | 6 ++ osi/dma/osi_dma_txrx.c | 121 ++++++------------------------ 10 files changed, 253 insertions(+), 103 deletions(-) mode change 100755 => 100644 osi/core/osi_hal.c diff --git a/include/osi_core.h b/include/osi_core.h index 3677557..86cdcbd 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -80,6 +80,7 @@ typedef my_lint_64 nvel64_t; #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) /** @} */ /** @@ -205,6 +206,8 @@ typedef my_lint_64 nvel64_t; #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 /** @} */ /** @@ -1025,6 +1028,24 @@ struct osi_macsec_irq_stats { }; #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. */ @@ -1071,6 +1092,8 @@ struct osi_ioctl { struct osi_fpe_config fpe; /** PTP configuration settings */ struct osi_ptp_config ptp_config; + /** TX Timestamp structure */ + struct osi_core_tx_ts tx_ts; }; /** @@ -2181,6 +2204,14 @@ nve32_t osi_get_hw_features(struct osi_core_priv_data *const osi_core, * 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 + * * @param[in] osi_core: OSI core private data structure. * @param[in] data: void pointer pointing to osi_ioctl * @@ -2365,6 +2396,14 @@ struct osi_core_priv_data *osi_get_core(void); * 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 + * * @param[in] osi_core: OSI core private data structure. * @param[in] data: void pointer pointing to osi_ioctl * diff --git a/include/osi_dma.h b/include/osi_dma.h index 58432a2..c46cf85 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -157,6 +157,8 @@ #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) /** @} */ /** @@ -363,6 +365,8 @@ struct osi_tx_swcx { * 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; }; /** @@ -410,6 +414,8 @@ struct osi_txdone_pkt_cx { /** 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; }; /** diff --git a/osi/common/include/local_common.h b/osi/common/include/local_common.h index 9251d95..134cae0 100644 --- a/osi/common/include/local_common.h +++ b/osi/common/include/local_common.h @@ -25,6 +25,17 @@ #include <osi_common.h> +/** + * @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 * diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 1ea5ef2..366dbdc 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -24,6 +24,7 @@ #define INCLUDED_CORE_LOCAL_H #include <osi_core.h> +#include <local_common.h> /** * @brief Maximum number of OSI core instances. @@ -37,6 +38,11 @@ */ #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 */ @@ -273,12 +279,16 @@ struct core_local { 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; }; /** diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index fe29e92..9b7d4f4 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -2642,9 +2642,9 @@ static int mgbe_configure_mac(struct osi_core_priv_data *osi_core) /* Enable MAC nve32_terrupts */ /* Read MAC IMR Register */ value = osi_readla(osi_core, (nveu8_t *)osi_core->base + MGBE_MAC_IER); - /* RGSMIIIM - RGMII/SMII nve32_terrupt Enable */ + /* RGSMIIIM - RGMII/SMII interrupt and TSIE Enable */ /* TODO: LPI need to be enabled during EEE implementation */ - value |= MGBE_IMR_RGSMIIIE; + value |= (MGBE_IMR_RGSMIIIE | MGBE_IMR_TSIE); osi_writela(osi_core, value, (nveu8_t *)osi_core->base + MGBE_MAC_IER); /* Enable common interrupt at wrapper level */ @@ -3193,6 +3193,28 @@ static void mgbe_handle_mac_fpe_intrs(struct osi_core_priv_data *osi_core) 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 * @@ -3207,8 +3229,9 @@ static void mgbe_handle_mac_fpe_intrs(struct osi_core_priv_data *osi_core) static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core, nveu32_t dma_isr) { - unsigned int mac_isr = 0; - unsigned int mac_ier = 0; + struct core_local *l_core = (struct core_local *)osi_core; + nveu32_t mac_isr = 0; + nveu32_t mac_ier = 0; mac_isr = osi_readla(osi_core, (unsigned char *)osi_core->base + MGBE_MAC_ISR); @@ -3225,6 +3248,43 @@ static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core, mac_isr &= ~MGBE_MAC_IMR_FPEIS; } + 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; + + /* 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) { + 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]; + } + } + 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 */ diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index f3c803a..b606811 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -106,6 +106,10 @@ #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_PTO_CR 0x0DC0 #define MGBE_MAC_PIDR0 0x0DC4 #define MGBE_MAC_PIDR1 0x0DC8 @@ -450,8 +454,10 @@ 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_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 0xFFU @@ -662,6 +668,8 @@ #define MGBE_MAC_SBD_INTR OSI_BIT(2) #define MGBE_MAC_EXT_CNF_DDS OSI_BIT(7) #define MGBE_MAC_EXT_CNF_EIPG 0x1U +/* TX timestamp */ +#define MGBE_MAC_TSS_TXTSC OSI_BIT(15) /** @} */ /** diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index be73b6c..f8821d0 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -122,6 +122,9 @@ struct osi_core_priv_data *osi_get_core(void) 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; + return &g_core[i].osi_core; } diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c old mode 100755 new mode 100644 index c836d64..3875a58 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -1362,6 +1362,80 @@ static nve32_t config_fpe(struct osi_core_priv_data *osi_core, 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; + + 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; + } + + return ret; +} + nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, struct osi_ioctl *data) { @@ -1561,6 +1635,16 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, ret = ops_p->write_reg(osi_core, (nve32_t) data->arg1_u32, (nve32_t) data->arg2_u32); break; + + 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; + default: OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "CORE: Incorrect command\n", diff --git a/osi/dma/dma_local.h b/osi/dma/dma_local.h index 4d1d794..04450ca 100644 --- a/osi/dma/dma_local.h +++ b/osi/dma/dma_local.h @@ -123,6 +123,12 @@ struct dma_local { 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 */ diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index d583ee0..8cd3abf 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -25,6 +25,7 @@ #include "hw_desc.h" #include "../osi/common/common.h" #include "mgbe_dma.h" +#include "local_common.h" static struct desc_ops d_ops[MAX_MAC_IP_TYPES]; @@ -507,102 +508,6 @@ static inline nve32_t validate_tx_completions_arg( return 0; } -/** - * @brief poll_for_ts_update - Poll for TXTSC bit set for timestamp capture - * - * Algorithm: This routine will be invoked by get_mac_tx_timestamp to poll - * on TXTSC bit to get set or timedout. - * - * @param[in] addr: Base address - * @param[in] chan: Current counter value - * - * @retval -1 on failure - * @retval 0 on success - */ -static inline int poll_for_ts_update(struct osi_dma_priv_data *osi_dma, - unsigned int *count) -{ - unsigned int retry = OSI_POLL_COUNT; - unsigned int val = 0U; - - while (*count < retry) { - /* Read and Check TXTSC in MAC_Timestamp_Control register */ - val = osi_readl((unsigned char *)osi_dma->base + - MGBE_MAC_TSS); - if ((val & MGBE_MAC_TSS_TXTSC) == MGBE_MAC_TSS_TXTSC) { - return 0; - } - (*count)++; - osi_dma->osd_ops.udelay(OSI_DELAY_1US); - } - - return -1; -} - -/** - * @brief get_mac_tx_timestamp - get TX timestamp from timestamp capture - * registers - * - * Algorithm: This routine will be invoked on TX_DONE interrupt and if hw - * timestamp capture enabled for that descriptor. SW will check for Packet - * id maching with dma channel number as for same DMA all tx are FIFO. If match - * update hwtimestamp into local variables. - * - * @param[in] osi: OSI private data structure. - * @param[in] tx_desc: Pointer to tranmit descriptor. - * @param[out] txdone_pkt_cx: Pointer to txdone packet descriptor to be filled - * @param[in] chan: Rx channel number. - * - */ -static void get_mac_tx_timestamp(struct osi_dma_priv_data *osi_dma, - struct osi_tx_desc *tx_desc, - struct osi_txdone_pkt_cx *txdone_pkt_cx, - unsigned int chan) -{ - unsigned char *addr = (unsigned char *)osi_dma->base; - int ret = -1; - int found = 1; - unsigned int count = 0; - unsigned long long var = 0; - - ret = poll_for_ts_update(osi_dma, &count); - if (ret < 0) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "timestamp done failed\n", 0ULL); - found = 0; - } - - /* check if pkt id is also correct for pkt. current implemtation - * use dma channel index as pktid, we will use pktid from index 0 to - * max DMA channels -1 */ - while (found == 1) { - if (((osi_readl(addr + MGBE_MAC_TS_PID) & - MGBE_MAC_TS_PID_MASK) == chan)) { - txdone_pkt_cx->flags |= OSI_TXDONE_CX_TS; - txdone_pkt_cx->ns = osi_readl(addr + MGBE_MAC_TS_NSEC); - txdone_pkt_cx->ns &= MGBE_MAC_TS_NSEC_MASK; - var = osi_readl(addr + MGBE_MAC_TS_SEC); - if (OSI_NSEC_PER_SEC > (OSI_ULLONG_MAX / var)) { - /* Will not hit this case */ - } else if ((OSI_ULLONG_MAX - (var * OSI_NSEC_PER_SEC)) < - txdone_pkt_cx->ns) { - /* Will not hit this case */ - } else { - txdone_pkt_cx->ns += var * OSI_NSEC_PER_SEC; - } - - found = 0; - } else { - OSI_DMA_INFO(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "packet ID mismatch \n", 0ULL); - ret = poll_for_ts_update(osi_dma, &count); - if (ret < 0) { - found = 0; - } - } - } -} - /** * @brief is_ptp_twostep_or_slave_mode - check for dut in ptp 2step or slave * mode @@ -697,10 +602,12 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, } 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)) { - get_mac_tx_timestamp(osi_dma, tx_desc, txdone_pkt_cx, chan); + txdone_pkt_cx->pktid = tx_swcx->pktid; + txdone_pkt_cx->flags |= OSI_TXDONE_CX_TS_DELAYED; } else { /* Do nothing here */ } @@ -993,6 +900,7 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, 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; @@ -1000,6 +908,7 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, struct osi_tx_swcx *tx_swcx = OSI_NULL; struct osi_tx_desc *cx_desc = OSI_NULL; nve32_t cntx_desc_consumed; + nveu32_t pkt_id = 0x0U; nveu32_t desc_cnt = 0U; nveu64_t tailptr, tmp; nveu32_t entry = 0U; @@ -1043,8 +952,15 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, (osi_dma->mac == OSI_MAC_HW_MGBE)) { /* mark packet id valid */ tx_desc->tdes3 |= TDES3_PIDV; - /* Packet id */ - tx_desc->tdes0 = chan; + 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, 1U); @@ -1058,6 +974,13 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, /* 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, 1U); From d2f02fd2d0e7ea4983a2e10e463ce3600a915bdf Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Mon, 28 Jun 2021 18:34:44 +0530 Subject: [PATCH 250/458] dma: fix MGBE function called for EQOS Issue: OSI_PKT_CX_PTP is set in tx_sw_cx for PTP packets irrespective of EQOS/MGBE However, for EQOS this below condition is sufficient ((tx_desc->tdes3 & TDES3_LD) == TDES3_LD) && ((tx_desc->tdes3 & TDES3_CTXT) != TDES3_CTXT) && ((tx_desc->tdes3 & TDES3_TTSS) == TDES3_TTSS)) For MGBE sw need to rely on OSI_PKT_CX_PTP set in sw_cx. But current condition is broken for EQOS, as it falls back to OSI_PKT_CX_PTP check, Which needs to be avoided. In QNX, we have case where PTP_CX_PTP is set for descriptor with only FD bit set in desc. Fix: Update logic to handle EQOS to ignore such packet desc for tx time. Bug 200603265 Change-Id: I4348d0c5e5ef01d8aec5e5ef638c11162cde70b6 Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2550879 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: svc_kernel_abi <svc_kernel_abi@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Sachin Nikam <snikam@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/dma/osi_dma_txrx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 8cd3abf..3099133 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -576,11 +576,11 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, } } - if ((osi_dma->mac != OSI_MAC_HW_MGBE) && - ((tx_desc->tdes3 & TDES3_LD) == TDES3_LD) && - ((tx_desc->tdes3 & TDES3_CTXT) != TDES3_CTXT)) { + if (osi_dma->mac != OSI_MAC_HW_MGBE) { /* check tx tstamp status */ - if ((tx_desc->tdes3 & TDES3_TTSS) == TDES3_TTSS) { + 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; From b8d5261e3bf74c23ed165c142d93c87088690d6a Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Sun, 27 Jun 2021 16:23:46 +0530 Subject: [PATCH 251/458] osi: core: add different XFI/USXGMII modes This change takes care of configuring different connection speeds of XFI/USXGMII modes Bug 200718307 Change-Id: I28aedb4f7b3a8e4a6bd4acd319487785c8294c05 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2550414 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_core.h | 10 ++++++ osi/core/xpcs.c | 84 +++++++++++++++++++++++++--------------------- 2 files changed, 56 insertions(+), 38 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 86cdcbd..b444bfa 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -149,6 +149,14 @@ typedef my_lint_64 nvel64_t; #define OSI_MII_ADDR_C45 OSI_BIT(30) /** @} */ +/** + * @brief Ethernet PHY Interface Modes + */ +#define OSI_XFI_MODE_10G 0 +#define OSI_XFI_MODE_5G 1 +#define OSI_USXGMII_MODE_10G 2 +#define OSI_USXGMII_MODE_5G 3 + /** * @addtogroup PTP-offload PTP offload defines * @{ @@ -1209,6 +1217,8 @@ struct osi_core_priv_data { 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; }; /** diff --git a/osi/core/xpcs.c b/osi/core/xpcs.c index 468f8a3..e098d88 100644 --- a/osi/core/xpcs.c +++ b/osi/core/xpcs.c @@ -129,11 +129,11 @@ 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 = 1000; + unsigned int retry = RETRY_COUNT; unsigned int count = 0; unsigned int ctrl = 0; int ret = 0; - int cond = 1; + int cond = COND_NOT_MET; if (osi_core->xpcs_base == OSI_NULL) { OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, @@ -142,40 +142,43 @@ int xpcs_start(struct osi_core_priv_data *osi_core) return 0; } - ctrl = xpcs_read(xpcs_base, XPCS_SR_MII_CTRL); - ctrl |= XPCS_SR_MII_CTRL_AN_ENABLE; - xpcs_write(xpcs_base, XPCS_SR_MII_CTRL, ctrl); + 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; + xpcs_write(xpcs_base, XPCS_SR_MII_CTRL, ctrl); - ret = xpcs_poll_for_an_complete(osi_core, &an_status); - if (ret < 0) { - return ret; - } - - xpcs_set_speed(xpcs_base, an_status); - - /* 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 == 1) { - if (count > retry) { - return -1; + ret = xpcs_poll_for_an_complete(osi_core, &an_status); + if (ret < 0) { + return ret; } - count++; + xpcs_set_speed(xpcs_base, an_status); + /* USXGMII Rate Adaptor Reset before data transfer */ ctrl = xpcs_read(xpcs_base, XPCS_VR_XS_PCS_DIG_CTRL1); - if ((ctrl & XPCS_VR_XS_PCS_DIG_CTRL1_USRA_RST) == 0U) { - cond = 0; - } else { - osi_core->osd_ops.udelay(1000U); + 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 = 1; + cond = COND_NOT_MET; count = 0; - while (cond == 1) { + while (cond == COND_NOT_MET) { if (count > retry) { return -1; } @@ -185,7 +188,7 @@ int xpcs_start(struct osi_core_priv_data *osi_core) 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 = 0; + cond = COND_MET; } else { osi_core->osd_ops.udelay(1000U); } @@ -360,11 +363,14 @@ int xpcs_init(struct osi_core_priv_data *osi_core) /* 2. enable USXGMII Mode inside DWC_xpcs */ /* 3. USXG_MODE = 10G - default it will be 10G mode */ - ctrl = xpcs_read(xpcs_base, XPCS_VR_XS_PCS_KR_CTRL); - ctrl &= ~(XPCS_VR_XS_PCS_KR_CTRL_USXG_MODE_MASK); + 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; + if (osi_core->uphy_gbe_mode == OSI_DISABLE) { + ctrl |= XPCS_VR_XS_PCS_KR_CTRL_USXG_MODE_5G; + } } xpcs_write(xpcs_base, XPCS_VR_XS_PCS_KR_CTRL, ctrl); @@ -403,14 +409,16 @@ int xpcs_init(struct osi_core_priv_data *osi_core) * clear AN_EN in SR_AN_CTRL * set CL37_BP in VR_XS_PCS_DIG_CTRL1 */ - ctrl = xpcs_read(xpcs_base, XPCS_SR_AN_CTRL); - ctrl &= ~XPCS_SR_AN_CTRL_AN_EN; - xpcs_write(xpcs_base, XPCS_SR_AN_CTRL, ctrl); - - ctrl = xpcs_read(xpcs_base, XPCS_VR_XS_PCS_DIG_CTRL1); - ctrl |= XPCS_VR_XS_PCS_DIG_CTRL1_CL37_BP; - xpcs_write(xpcs_base, XPCS_VR_XS_PCS_DIG_CTRL1, ctrl); + 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; + xpcs_write(xpcs_base, XPCS_SR_AN_CTRL, ctrl); + ctrl = xpcs_read(xpcs_base, XPCS_VR_XS_PCS_DIG_CTRL1); + ctrl |= XPCS_VR_XS_PCS_DIG_CTRL1_CL37_BP; + xpcs_write(xpcs_base, XPCS_VR_XS_PCS_DIG_CTRL1, ctrl); + } /* TODO: 9. MII_AN_INTR_EN to 1, to enable auto-negotiation * complete interrupt */ From fbdd229e0292680ff8f730bec1396ef8e2575ddc Mon Sep 17 00:00:00 2001 From: Mahesh Patil <maheshp@nvidia.com> Date: Tue, 31 Mar 2020 18:12:39 -0700 Subject: [PATCH 252/458] eqos: core: pad calibration Issue: 1. Current pad calibration does not check for RGMII/MDIO interfaces idle Fix: 1. Make sure RGMII and MDIO interface are idle before doing pad calibration as per spec Bug 2831220 Signed-off-by: Mahesh Patil <maheshp@nvidia.com> Change-Id: I6b3f35017f62444575d16366d9ac31a5c96fecf7 Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2321641 Reviewed-by: svc_kernel_abi <svc_kernel_abi@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: Sachin Nikam <snikam@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_common.h | 4 + include/osi_core.h | 30 +++- osi/core/Makefile.tmk | 3 +- osi/core/eqos_core.c | 372 +++++++++++++++++++++++++++++++++++++++++- osi/core/eqos_core.h | 12 ++ osi/dma/Makefile.tmk | 3 +- 6 files changed, 411 insertions(+), 13 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index 93f7e36..d1a4bad 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -171,11 +171,15 @@ #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) diff --git a/include/osi_core.h b/include/osi_core.h index b444bfa..0faac0c 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -969,6 +969,8 @@ struct osi_vm_irq_data { *@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, @@ -1104,6 +1106,28 @@ struct osi_ioctl { struct osi_core_tx_ts tx_ts; }; +/** + * @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 The OSI Core (MAC & MTL) private data structure. */ @@ -1219,6 +1243,8 @@ struct osi_core_priv_data { 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; }; /** @@ -1515,8 +1541,6 @@ nve32_t osi_set_speed(struct osi_core_priv_data *const osi_core, * * @pre * - MAC should out of reset and clocks enabled. - * - RGMII and MDIO interface needs to be IDLE before performing PAD - * calibration. * * @note * Traceability Details: @@ -1536,7 +1560,7 @@ nve32_t osi_set_speed(struct osi_core_priv_data *const osi_core, * - De-initialization: No * * @retval 0 on success - * @retval -1 on failure. + * @retval -1 value on failure or pad calibration is disabled */ nve32_t osi_pad_calibrate(struct osi_core_priv_data *const osi_core); diff --git a/osi/core/Makefile.tmk b/osi/core/Makefile.tmk index 3626205..62d8355 100644 --- a/osi/core/Makefile.tmk +++ b/osi/core/Makefile.tmk @@ -46,8 +46,7 @@ NV_COMPONENT_SOURCES := \ NV_COMPONENT_INCLUDES := \ $(NV_SOURCE)/nvethernetrm/include \ - $(NV_SOURCE)/nvethernetrm/osi/common/include \ - $(NV_SOURCE)/core/include + $(NV_SOURCE)/nvethernetrm/osi/common/include include $(NV_BUILD_SHARED_LIBRARY) endif diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 7f14356..ff7a0f4 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -28,6 +28,16 @@ #include "core_local.h" #include "vlan_filter.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 */ @@ -730,6 +740,112 @@ static nveu32_t eqos_calculate_per_queue_fifo(nveu32_t fifo_size, return p_fifo; } +#ifdef UPDATED_PAD_CAL +/** + * @brief eqos_pad_calibrate - PAD calibration + * + * @note + * Algorithm: + * - Call pre pad calibration function to make RGMII interface idle + * - 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 + * - Call post pad calibration function to restore pre pad calibration + * settings + * + * @param[in] osi_core: OSI core private data structure. + * + * @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) { + 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); + ret = eqos_post_pad_calibrate(osi_core); +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 * @@ -773,10 +889,8 @@ static nve32_t eqos_pad_calibrate(struct osi_core_priv_data *const osi_core) 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. */ @@ -787,11 +901,9 @@ static nve32_t eqos_pad_calibrate(struct osi_core_priv_data *const osi_core) 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) { @@ -808,7 +920,6 @@ static nve32_t eqos_pad_calibrate(struct osi_core_priv_data *const osi_core) cond = COND_MET; } } - calibration_failed: /* 6. Re-program the value PAD_E_INPUT_OR_E_PWRD in * ETHER_QOS_SDMEMCOMPPADCTRL_0 to save power @@ -816,9 +927,9 @@ calibration_failed: 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 @@ -1935,6 +2046,7 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core, 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) { @@ -1942,6 +2054,7 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core, "eqos pad calibration failed\n", 0ULL); return ret; } +#endif /* !UPDATED_PAD_CAL */ /* reset mmc counters */ osi_writela(osi_core, EQOS_MMC_CNTRL_CNTRST, @@ -5812,6 +5925,253 @@ static nve32_t eqos_get_hw_features(struct osi_core_priv_data *const osi_core, 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 * diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index a3c6da2..a9313f4 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -97,6 +97,7 @@ #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 @@ -159,12 +160,14 @@ #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) /** @} */ /** @@ -238,6 +241,8 @@ #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) @@ -322,6 +327,10 @@ #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 0x3E000000 @@ -561,6 +570,9 @@ #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); diff --git a/osi/dma/Makefile.tmk b/osi/dma/Makefile.tmk index de97716..5e47393 100644 --- a/osi/dma/Makefile.tmk +++ b/osi/dma/Makefile.tmk @@ -42,8 +42,7 @@ NV_COMPONENT_SOURCES := \ NV_COMPONENT_INCLUDES := \ $(NV_SOURCE)/nvethernetrm/include \ - $(NV_SOURCE)/nvethernetrm/osi/common/include \ - $(NV_SOURCE)/core/include + $(NV_SOURCE)/nvethernetrm/osi/common/include include $(NV_BUILD_SHARED_LIBRARY) endif From 2ceb7dca52516e7468cfd6acdedb0481c77158e8 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Mon, 28 Jun 2021 23:00:41 +0530 Subject: [PATCH 253/458] osi: dma: Add debug capabilities - Dumps the descriptor if enable_desc_dump flag enabled. - Dumps registers/structure through OSI DMA IOCTL. Bug 200737108 Change-Id: I75924cdbd815528dcddba7b9d33dbd4a162f9bbe Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2550985 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: svc_kernel_abi <svc_kernel_abi@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_dma.h | 55 +++++++++- osi/dma/Makefile.tmk | 1 + osi/dma/debug.c | 243 +++++++++++++++++++++++++++++++++++++++++ osi/dma/debug.h | 50 +++++++++ osi/dma/osi_dma.c | 36 +++++- osi/dma/osi_dma_txrx.c | 35 ++++++ 6 files changed, 418 insertions(+), 2 deletions(-) create mode 100644 osi/dma/debug.c create mode 100644 osi/dma/debug.h diff --git a/include/osi_dma.h b/include/osi_dma.h index c46cf85..6252332 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -235,6 +235,21 @@ #define OSI_DMA_INTR_ENABLE 1U /** @} */ +/** + * @addtogroup OSI_DMA-DEBUG helper macros + * + * @brief Helper macros for OSI dma debugging. + * @{ + */ +#ifdef OSI_DMA_DEBUG +#define OSI_DMA_IOCTL_CMD_REG_DUMP 1U +#define OSI_DMA_IOCTL_CMD_STRUCTS_DUMP 2U +#define OSI_DMA_DEBUG_DESC 1U +#define OSI_DMA_DEBUG_REG 2U +#define OSI_DMA_DEBUG_STRUCTS 3U +#endif /* OSI_DMA_DEBUG */ +/** @} */ + /** * @brief OSI packet error stats */ @@ -491,6 +506,20 @@ struct osd_dma_ops { nveul64_t loga); /**.ops_log function callback */ void (*udelay)(nveu64_t usec); +#ifdef OSI_DMA_DEBUG + /**.printf function callback */ + void (*printf)(struct osi_dma_priv_data *osi_dma, + nveu32_t type, + const char *fmt, ...); +#endif +}; + +/** + * @brief The OSI DMA IOCTL data structure. + */ +struct osi_dma_ioctl_data { + /** IOCTL command number */ + nveu32_t cmd; }; /** @@ -556,9 +585,14 @@ struct osi_dma_priv_data { * bit 0 PTP mode master(1) slave(0) * bit 1 PTP sync method twostep(1) onestep(0) */ unsigned int ptp_flag; + /** OSI DMA IOCTL data */ + struct osi_dma_ioctl_data ioctl_data; +#ifdef OSI_DMA_DEBUG + /** Flag to enable/disable descriptor dump */ + nveu32_t enable_desc_dump; +#endif }; - /** * @brief osi_disable_chan_tx_intr - Disables DMA Tx channel interrupts. * @@ -1314,6 +1348,25 @@ nveu32_t osi_is_mac_enabled(struct osi_dma_priv_data *const osi_dma); */ 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 + * + * @note + * 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. diff --git a/osi/dma/Makefile.tmk b/osi/dma/Makefile.tmk index 5e47393..a9f8942 100644 --- a/osi/dma/Makefile.tmk +++ b/osi/dma/Makefile.tmk @@ -36,6 +36,7 @@ NV_COMPONENT_SOURCES := \ 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 diff --git a/osi/dma/debug.c b/osi/dma/debug.c new file mode 100644 index 0000000..7a37c97 --- /dev/null +++ b/osi/dma/debug.c @@ -0,0 +1,243 @@ +/* + * 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_DMA_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; + + rem = i % 4; + temp = size - rem; + + for (i = 0; i < temp; i += 4) { + osi_dma->osd_ops.printf(osi_dma, OSI_DMA_DEBUG_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_DMA_DEBUG_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_DMA_DEBUG_STRUCTS, + "OSI DMA struct: "); + dump_struct(osi_dma, (unsigned char *)osi_dma, + sizeof(struct osi_dma_priv_data)); + + osi_dma->osd_ops.printf(osi_dma, OSI_DMA_DEBUG_STRUCTS, + "OSI DMA Tx/Rx Ring struct: "); + 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_DMA_DEBUG_STRUCTS, + "OSD DMA ops struct: "); + dump_struct(osi_dma, (unsigned char *)(&osi_dma->osd_ops), + sizeof(struct osd_dma_ops)); + + osi_dma->osd_ops.printf(osi_dma, OSI_DMA_DEBUG_STRUCTS, + "OSI local DMA struct: "); + dump_struct(osi_dma, (unsigned char *)l_dma, + sizeof(struct dma_local)); + + osi_dma->osd_ops.printf(osi_dma, OSI_DMA_DEBUG_STRUCTS, + "OSI local ops DMA struct: "); + 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: + 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_DMA_DEBUG_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_DMA_DEBUG_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_DMA_DEBUG_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 + TX_DESC_CNT - 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_DMA_DEBUG_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, 1U); + } + } +} + +/** + * @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 diff --git a/osi/dma/debug.h b/osi/dma/debug.h new file mode 100644 index 0000000..639841d --- /dev/null +++ b/osi/dma/debug.h @@ -0,0 +1,50 @@ +/* + * 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_OSI_DMA_DEBUG_H +#define INCLUDED_OSI_DMA_DEBUG_H + +#include <osi_common.h> +#include <osi_dma.h> +#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_OSI_DMA_DEBUG_H*/ diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 821560c..b33cd0f 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -24,7 +24,9 @@ #include <local_common.h> #include "hw_desc.h" #include "../osi/common/common.h" - +#ifdef OSI_DMA_DEBUG +#include "debug.h" +#endif /** * @brief g_dma - DMA local data array. */ @@ -208,6 +210,9 @@ nve32_t osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) 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_DMA_DEBUG + (osi_dma->osd_ops.printf == OSI_NULL) || +#endif (osi_dma->osd_ops.udelay == OSI_NULL)) { return -1; } @@ -761,6 +766,35 @@ nve32_t osi_hw_transmit(struct osi_dma_priv_data *osi_dma, nveu32_t chan) 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_DMA_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 + default: + OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "DMA: Invalid IOCTL command", 0ULL); + return -1; + } + + return 0; +} + #ifndef OSI_STRIPPED_LIB /** diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 3099133..c3a0ce9 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -26,6 +26,9 @@ #include "../osi/common/common.h" #include "mgbe_dma.h" #include "local_common.h" +#ifdef OSI_DMA_DEBUG +#include "debug.h" +#endif static struct desc_ops d_ops[MAX_MAC_IP_TYPES]; @@ -161,6 +164,12 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, if ((rx_desc->rdes3 & RDES3_OWN) == RDES3_OWN) { break; } +#ifdef OSI_DMA_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_DMA_DEBUG */ INCR_RX_DESC_INDEX(rx_ring->cur_rx_idx, 1U); @@ -243,6 +252,13 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, * those are valid. */ ptp_rx_swcx->flags |= OSI_RX_SWCX_REUSE; +#ifdef OSI_DMA_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_DMA_DEBUG */ /* Context descriptor was consumed. Its skb * and DMA mapping will be recycled */ @@ -560,6 +576,13 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, break; } +#ifdef OSI_DMA_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_DMA_DEBUG */ + /* check for Last Descriptor */ if ((tx_desc->tdes3 & TDES3_LD) == TDES3_LD) { if ((tx_desc->tdes3 & TDES3_ES_BITS) != 0U) { @@ -907,6 +930,10 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, 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_DMA_DEBUG + nveu32_t f_idx = tx_ring->cur_tx_idx; + nveu32_t l_idx = 0; +#endif /* OSI_DMA_DEBUG */ nve32_t cntx_desc_consumed; nveu32_t pkt_id = 0x0U; nveu32_t desc_cnt = 0U; @@ -1055,6 +1082,14 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, */ dmb_oshst(); +#ifdef OSI_DMA_DEBUG + if (osi_dma->enable_desc_dump == 1U) { + l_idx = entry; + desc_dump(osi_dma, f_idx, DECR_TX_DESC_INDEX(l_idx, 1U), + (TX_DESC_DUMP | TX_DESC_DUMP_TX), chan); + } +#endif /* OSI_DMA_DEBUG */ + tailptr = tx_ring->tx_desc_phy_addr + (entry * sizeof(struct osi_tx_desc)); if (osi_unlikely(tailptr < tx_ring->tx_desc_phy_addr)) { From dc8e16b336effef57d3e4fbbb680e333ed1cec78 Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Fri, 9 Jul 2021 01:30:47 +0530 Subject: [PATCH 254/458] nvethernetrm: bug fix to use absolute time passed as input Issue: BTR register don't use fixed value from input argument and use only offset with current time. Fix: Absolute time can also be input argument. Fix bug so it can work with standard utility. Bug 200622871 Change-Id: I063c29b5d1d1d546ed59f8bf1f870e4876e03858 Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2556217 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/eqos_core.c | 5 ++++- osi/core/mgbe_core.c | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index ff7a0f4..aea2057 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -4514,7 +4514,10 @@ static int eqos_hw_config_est(struct osi_core_priv_data *osi_core, } } - if (est->btr[0] == 0U && est->btr[1] == 0U) { + 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]); } diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 9b7d4f4..d70aae1 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -4572,7 +4572,9 @@ static int mgbe_hw_config_est(struct osi_core_priv_data *osi_core, } } - if (est->btr[0] == 0U && est->btr[1] == 0U) { + 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]); From 0edba05f96ce3961cb4e8655b302b42e84365d44 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Mon, 31 May 2021 22:50:37 +0530 Subject: [PATCH 255/458] osi: use max_chans based on MAC version Issue: Maximum number of DMA channels is different for Xavier/Orin EQOS/MGBE IP's. Using macro of maximum number of channels will create problem for other IP's. Fix: Assign maximum number of DMA channels based on MAC version. Bug 200741194 Change-Id: I321780b6868dfb36700863a5852b76424d3bbf6b Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2556425 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_common.h | 15 +----- osi/common/common.h | 28 ++++++---- osi/core/core_local.h | 2 + osi/core/osi_hal.c | 2 +- osi/dma/dma_local.h | 9 ++++ osi/dma/eqos_dma.c | 63 +++++++++++----------- osi/dma/mgbe_dma.c | 62 +++++++++++----------- osi/dma/osi_dma.c | 37 +++++++------ osi/dma/osi_dma_local.h | 112 ---------------------------------------- osi/dma/osi_dma_txrx.c | 8 ++- 10 files changed, 125 insertions(+), 213 deletions(-) delete mode 100644 osi/dma/osi_dma_local.h diff --git a/include/osi_common.h b/include/osi_common.h index d1a4bad..c159685 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -191,6 +191,7 @@ #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 @@ -224,20 +225,6 @@ #define OSI_IP4_FILTER 0U #define OSI_IP6_FILTER 1U -#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; \ - } \ - } \ - #ifndef OSI_STRIPPED_LIB #define OSI_L2_FILTER_INDEX_ANY 127U #define OSI_HASH_FILTER_MODE 1U diff --git a/osi/common/common.h b/osi/common/common.h index dd192b2..105be69 100755 --- a/osi/common/common.h +++ b/osi/common/common.h @@ -236,9 +236,10 @@ static inline void osi_writela(void *priv, nveu32_t val, void *addr) #endif /** - * @brief is_valid_mac_version - Check if read MAC IP is valid or not. + * @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. * @@ -251,17 +252,26 @@ static inline void osi_writela(void *priv, nveu32_t val, void *addr) * @retval 0 - for not Valid MAC * @retval 1 - for Valid MAC */ -static inline nve32_t is_valid_mac_version(nveu32_t mac_ver) +static inline nve32_t validate_mac_ver_update_chans(nveu32_t mac_ver, + nveu32_t *max_chans) { - if ((mac_ver == OSI_EQOS_MAC_4_10) || - (mac_ver == OSI_EQOS_MAC_5_00) || - (mac_ver == OSI_EQOS_MAC_5_30) || - (mac_ver == OSI_MGBE_MAC_3_00) || - (mac_ver == OSI_MGBE_MAC_3_10)) { - return 1; + 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: + *max_chans = OSI_MGBE_MAX_NUM_CHANS; + break; + default: + return 0; } - return 0; + return 1; } /** diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 366dbdc..7d31847 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -289,6 +289,8 @@ struct core_local { 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; }; /** diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 3875a58..9db7511 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -932,7 +932,7 @@ nve32_t osi_get_mac_version(struct osi_core_priv_data *const osi_core, *mac_ver = ((l_core->ops_p->read_reg(osi_core, (nve32_t)MAC_VERSION)) & MAC_VERSION_SNVER_MASK); - if (is_valid_mac_version(*mac_ver) == 0) { + 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; diff --git a/osi/dma/dma_local.h b/osi/dma/dma_local.h index 04450ca..5528870 100644 --- a/osi/dma/dma_local.h +++ b/osi/dma/dma_local.h @@ -137,6 +137,8 @@ struct dma_local { nveu32_t vm_intr; /** Magic number to validate osi_dma pointer */ nveu64_t magic_num; + /** Maximum number of DMA channels */ + nveu32_t max_chans; }; /** @@ -238,7 +240,14 @@ nve32_t dma_desc_init(struct osi_dma_priv_data *osi_dma, 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) ((data) & 0xFFFFFFFFU) diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index cda570a..7ac0aed 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -103,7 +103,9 @@ static void eqos_dma_safety_init(struct osi_dma_priv_data *osi_dma) 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 + @@ -166,8 +168,9 @@ 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)); @@ -210,9 +213,9 @@ static void eqos_disable_chan_tx_intr(void *addr, nveu32_t chan) 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; @@ -242,9 +245,9 @@ static void eqos_enable_chan_tx_intr(void *addr, nveu32_t chan) 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)); @@ -285,9 +288,9 @@ static void eqos_disable_chan_rx_intr(void *addr, nveu32_t chan) 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; @@ -317,7 +320,9 @@ static void eqos_set_tx_ring_len(struct osi_dma_priv_data *osi_dma, 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); @@ -345,9 +350,9 @@ 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 + @@ -388,9 +393,9 @@ 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 + @@ -420,7 +425,9 @@ static void eqos_set_rx_ring_len(struct osi_dma_priv_data *osi_dma, 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); @@ -448,9 +455,9 @@ 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 + @@ -490,9 +497,9 @@ 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 + @@ -524,9 +531,9 @@ 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)); @@ -569,9 +576,9 @@ 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)); @@ -618,9 +625,9 @@ 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 */ @@ -733,11 +740,6 @@ static nve32_t eqos_init_dma_channel(struct osi_dma_priv_data *osi_dma) /* configure EQOS DMA channels */ for (chinx = 0; chinx < osi_dma->num_dma_chans; chinx++) { - if (osi_dma->dma_chans[chinx] >= OSI_EQOS_MAX_NUM_CHANS) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma: invalid channel number\n", 0ULL); - return -1; - } eqos_configure_dma_channel(osi_dma->dma_chans[chinx], osi_dma); } @@ -868,8 +870,9 @@ static void eqos_config_slot(struct osi_dma_priv_data *osi_dma, 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 + @@ -927,8 +930,9 @@ static nveu32_t eqos_get_global_dma_status(void *addr) */ 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, @@ -953,8 +957,9 @@ static void eqos_clear_vm_tx_intr(void *addr, nveu32_t chan) */ 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, diff --git a/osi/dma/mgbe_dma.c b/osi/dma/mgbe_dma.c index 75e2d9f..bb6ef96 100644 --- a/osi/dma/mgbe_dma.c +++ b/osi/dma/mgbe_dma.c @@ -40,9 +40,9 @@ 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; @@ -65,9 +65,9 @@ static void mgbe_disable_chan_tx_intr(void *addr, nveu32_t chan) 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; @@ -90,9 +90,9 @@ static void mgbe_enable_chan_tx_intr(void *addr, nveu32_t chan) 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; @@ -113,9 +113,9 @@ static void mgbe_disable_chan_rx_intr(void *addr, nveu32_t chan) 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; @@ -138,9 +138,9 @@ static void mgbe_set_tx_ring_len(struct osi_dma_priv_data *osi_dma, { 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)); @@ -160,9 +160,9 @@ 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 + @@ -194,9 +194,9 @@ 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 + @@ -219,9 +219,9 @@ static void mgbe_set_rx_ring_len(struct osi_dma_priv_data *osi_dma, { 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)); @@ -241,9 +241,9 @@ 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 + @@ -274,9 +274,9 @@ 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 + @@ -305,9 +305,9 @@ 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); @@ -335,9 +335,9 @@ 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); @@ -378,9 +378,9 @@ static void mgbe_configure_dma_channel(nveu32_t chan, 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 */ @@ -648,8 +648,9 @@ static nveu32_t mgbe_get_global_dma_status(void *addr) */ 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, @@ -668,8 +669,9 @@ static void mgbe_clear_vm_tx_intr(void *addr, nveu32_t chan) */ 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, @@ -698,9 +700,9 @@ static void mgbe_config_slot(struct osi_dma_priv_data *osi_dma, 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 + diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index b33cd0f..da8d63e 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -102,10 +102,11 @@ static inline nve32_t validate_args(struct osi_dma_priv_data *osi_dma, static inline nve32_t validate_dma_chan_num(struct osi_dma_priv_data *osi_dma, nveu32_t chan) { - /* TODO: Get the max channel number based on mac/mac_ver */ - if (chan >= OSI_MGBE_MAX_NUM_CHANS) { + 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", 0ULL); + "Invalid DMA channel number\n", chan); return -1; } @@ -128,11 +129,14 @@ static inline nve32_t validate_dma_chan_num(struct osi_dma_priv_data *osi_dma, */ 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 (validate_dma_chan_num(osi_dma, - osi_dma->dma_chans[i]) < 0) { + 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; } } @@ -257,7 +261,16 @@ nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) return -1; } - if (osi_dma->num_dma_chans > OSI_MGBE_MAX_NUM_CHANS) { + 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; @@ -281,14 +294,6 @@ nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) return ret; } - l_dma->mac_ver = osi_readl((nveu8_t *)osi_dma->base + MAC_VERSION) & - MAC_VERSION_SNVER_MASK; - if (is_valid_mac_version(l_dma->mac_ver) == 0) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "Invalid MAC version\n", (nveu64_t)l_dma->mac_ver); - return -1; - } - 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; @@ -323,7 +328,7 @@ nve32_t osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma) return -1; } - if (osi_dma->num_dma_chans > OSI_MGBE_MAX_NUM_CHANS) { + 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; @@ -854,7 +859,7 @@ nve32_t osi_config_slot_function(struct osi_dma_priv_data *osi_dma, chan = osi_dma->dma_chans[i]; if ((chan == 0x0U) || - (chan >= OSI_MGBE_MAX_NUM_CHANS)) { + (chan >= l_dma->max_chans)) { /* Ignore 0 and invalid channels */ continue; } diff --git a/osi/dma/osi_dma_local.h b/osi/dma/osi_dma_local.h deleted file mode 100644 index 962df94..0000000 --- a/osi/dma/osi_dma_local.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2019-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_OSI_DMA_LOCAL_H -#define INCLUDED_OSI_DMA_LOCAL_H - -#include <osi_dma.h> -#include "eqos_dma.h" -#include "mgbe_dma.h" - -/** - * @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 pkt_err_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_rx_desc *rx_desc, - struct osi_rx_desc *context_desc, - struct osi_rx_pkt_cx *rx_pkt_cx); -}; - -/** - * @brief eqos_get_desc_ops - EQOS get DMA descriptor operations - * - * Algorithm: Returns pointer DMA descriptor operations structure. - * - * @returns Pointer to DMA descriptor operations structure - */ -struct desc_ops *eqos_get_desc_ops(void); - -/** - * @brief mgbe_get_desc_ops - MGBE get DMA descriptor operations - * - * Algorithm: Returns pointer DMA descriptor operations structure. - * - * @returns Pointer to DMA descriptor operations structure - */ -struct desc_ops *mgbe_get_desc_ops(void); - -/* 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. - * - * @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); - -/** - * @addtogroup Helper Helper MACROS - * - * @brief EQOS generic helper MACROS. - * @{ - */ -#define CHECK_CHAN_BOUND(chan) \ - { \ - if ((chan) >= OSI_EQOS_MAX_NUM_CHANS) { \ - return; \ - } \ - } \ - -#define BOOLEAN_FALSE (0U != 0U) -#define L32(data) ((data) & 0xFFFFFFFFU) -#define H32(data) (((data) & 0xFFFFFFFF00000000UL) >> 32UL) -/** @} */ - -#endif /* INCLUDED_OSI_DMA_LOCAL_H */ diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index c3a0ce9..cf3e3e9 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -101,9 +101,11 @@ static inline nve32_t validate_rx_completions_arg( 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 >= OSI_EQOS_MAX_NUM_CHANS))) { + (chan >= l_dma->max_chans))) { return -1; } @@ -507,8 +509,10 @@ static inline nve32_t validate_tx_completions_arg( 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 >= OSI_EQOS_MAX_NUM_CHANS))) { + (chan >= l_dma->max_chans))) { return -1; } From d6b717361844d788d0c98b895c269c87819c392e Mon Sep 17 00:00:00 2001 From: Mahesh Patil <maheshp@nvidia.com> Date: Mon, 14 Jun 2021 15:17:25 -0700 Subject: [PATCH 256/458] nvethernetrm: address review comments - Convert primitive data type to nv_ type's - Replace debug pr_ prints with OSI_CORE_ print macro's - Add all macsec register macro's with prefix MACSEC_ - Update all osi function header as per 5.2 coding guidelines(PLC) - Remove printk.h header file and use OSI_CORE_ERR macro's in all prints - Implement clean up LUT's in add_upd_sc() and del_upd_sc() Bug 3264523 Change-Id: Ie41097c85fbcb90ce0c4cac470fe0f068ed22247 Signed-off-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2548476 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: svc_kernel_abi <svc_kernel_abi@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/mmc.h | 34 +- include/osi_core.h | 42 +- include/osi_macsec.h | 818 +++++++++++------ osi/common/type.h | 8 + osi/core/ivc_core.c | 2 +- osi/core/macsec.c | 2094 ++++++++++++++++++++++-------------------- osi/core/macsec.h | 566 ++++++------ 7 files changed, 1989 insertions(+), 1575 deletions(-) diff --git a/include/mmc.h b/include/mmc.h index 438f8bf..ffe9385 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -587,43 +587,43 @@ struct osi_xtra_stat_counters { struct osi_macsec_mmc_counters { /** This counter provides the number of controller port macsec * untaged packets */ - unsigned long long rx_pkts_no_tag; + nveul64_t rx_pkts_no_tag; /** This counter provides the number of controller port macsec * untaged packets validateFrame != strict */ - unsigned long long rx_pkts_untagged; + nveul64_t rx_pkts_untagged; /** This counter provides the number of invalid tag or icv packets */ - unsigned long long rx_pkts_bad_tag; + nveul64_t rx_pkts_bad_tag; /** This counter provides the number of no sc lookup hit or sc match * packets */ - unsigned long long rx_pkts_no_sa_err; + nveul64_t rx_pkts_no_sa_err; /** This counter provides the number of no sc lookup hit or sc match * packets validateFrame != strict */ - unsigned long long rx_pkts_no_sa; + nveul64_t rx_pkts_no_sa; /** This counter provides the number of late packets *received PN < lowest PN */ - unsigned long long rx_pkts_late[OSI_MACSEC_SC_INDEX_MAX]; + nveul64_t rx_pkts_late[OSI_MACSEC_SC_INDEX_MAX]; /** This counter provides the number of overrun packets */ - unsigned long long rx_pkts_overrun; + nveul64_t rx_pkts_overrun; /** This counter provides the number of octets after IVC passing */ - unsigned long long rx_octets_validated; + nveul64_t rx_octets_validated; /** This counter provides the number not valid packets */ - unsigned long long rx_pkts_not_valid[OSI_MACSEC_SC_INDEX_MAX]; + nveul64_t rx_pkts_not_valid[OSI_MACSEC_SC_INDEX_MAX]; /** This counter provides the number of invalid packets */ - unsigned long long in_pkts_invalid[OSI_MACSEC_SC_INDEX_MAX]; + nveul64_t in_pkts_invalid[OSI_MACSEC_SC_INDEX_MAX]; /** This counter provides the number of in packet delayed */ - unsigned long long rx_pkts_delayed[OSI_MACSEC_SC_INDEX_MAX]; + nveul64_t rx_pkts_delayed[OSI_MACSEC_SC_INDEX_MAX]; /** This counter provides the number of in packets un checked */ - unsigned long long rx_pkts_unchecked[OSI_MACSEC_SC_INDEX_MAX]; + nveul64_t rx_pkts_unchecked[OSI_MACSEC_SC_INDEX_MAX]; /** This counter provides the number of in packets ok */ - unsigned long long rx_pkts_ok[OSI_MACSEC_SC_INDEX_MAX]; + nveul64_t rx_pkts_ok[OSI_MACSEC_SC_INDEX_MAX]; /** This counter provides the number of out packets untaged */ - unsigned long long tx_pkts_untaged; + nveul64_t tx_pkts_untaged; /** This counter provides the number of out too long */ - unsigned long long tx_pkts_too_long; + nveul64_t tx_pkts_too_long; /** This counter provides the number of out packets protected */ - unsigned long long tx_pkts_protected[OSI_MACSEC_SC_INDEX_MAX]; + nveul64_t tx_pkts_protected[OSI_MACSEC_SC_INDEX_MAX]; /** This counter provides the number of out octets protected */ - unsigned long long tx_octets_protected; + nveul64_t tx_octets_protected; }; #endif /* MACSEC_SUPPORT */ #endif /* INCLUDED_MMC_H */ \ No newline at end of file diff --git a/include/osi_core.h b/include/osi_core.h index 0faac0c..7c1973a 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -986,7 +986,7 @@ struct osd_core_ops { nveu32_t len); #ifdef MACSEC_SUPPORT /** Program macsec key table through Trust Zone callback */ - int (*macsec_tz_kt_config)(void *priv, unsigned char cmd, + nve32_t (*macsec_tz_kt_config)(void *priv, unsigned char cmd, void *const kt_config, void *const genl_info); #endif /* MACSEC_SUPPORT */ @@ -998,43 +998,43 @@ struct osd_core_ops { */ struct osi_macsec_irq_stats { /** Tx debug buffer capture done */ - unsigned long tx_dbg_capture_done; + nveu64_t tx_dbg_capture_done; /** Tx MTU check failed */ - unsigned long tx_mtu_check_fail; + nveu64_t tx_mtu_check_fail; /** Tx MAC CRC err */ - unsigned long tx_mac_crc_error; + nveu64_t tx_mac_crc_error; /** Tx SC AN not valid */ - unsigned long tx_sc_an_not_valid; + nveu64_t tx_sc_an_not_valid; /** Tx AES GCM buffer overflow */ - unsigned long tx_aes_gcm_buf_ovf; + nveu64_t tx_aes_gcm_buf_ovf; /** Tx LUT lookup miss */ - unsigned long tx_lkup_miss; + nveu64_t tx_lkup_miss; /** Tx uninitialized key slot */ - unsigned long tx_uninit_key_slot; + nveu64_t tx_uninit_key_slot; /** Tx PN threshold reached */ - unsigned long tx_pn_threshold; + nveu64_t tx_pn_threshold; /** Tx PN exhausted */ - unsigned long tx_pn_exhausted; + nveu64_t tx_pn_exhausted; /** Tx debug buffer capture done */ - unsigned long rx_dbg_capture_done; + nveu64_t rx_dbg_capture_done; /** Rx ICV error threshold */ - unsigned long rx_icv_err_threshold; + nveu64_t rx_icv_err_threshold; /** Rx replay error */ - unsigned long rx_replay_error; + nveu64_t rx_replay_error; /** Rx MTU check failed */ - unsigned long rx_mtu_check_fail; + nveu64_t rx_mtu_check_fail; /** Rx MAC CRC err */ - unsigned long rx_mac_crc_error; + nveu64_t rx_mac_crc_error; /** Rx AES GCM buffer overflow */ - unsigned long rx_aes_gcm_buf_ovf; + nveu64_t rx_aes_gcm_buf_ovf; /** Rx LUT lookup miss */ - unsigned long rx_lkup_miss; + nveu64_t rx_lkup_miss; /** Rx uninitialized key slot */ - unsigned long rx_uninit_key_slot; + nveu64_t rx_uninit_key_slot; /** Rx PN exhausted */ - unsigned long rx_pn_exhausted; + nveu64_t rx_pn_exhausted; /** Secure reg violation */ - unsigned long secure_reg_viol; + nveu64_t secure_reg_viol; }; #endif /* MACSEC_SUPPORT */ @@ -1144,7 +1144,7 @@ struct osi_core_priv_data { /** Memory mapped base address of MACsec TZ page */ void *tz_base; /** Address of MACsec HW operations structure */ - struct macsec_core_ops *macsec_ops; + 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 */ diff --git a/include/osi_macsec.h b/include/osi_macsec.h index 7ae5c92..6316f45 100644 --- a/include/osi_macsec.h +++ b/include/osi_macsec.h @@ -26,7 +26,7 @@ #include <osi_core.h> ////////////////////////////////////////////////////////////////////////// - /* MACsec OSI data structures */ + /* MACSEC OSI data structures */ ////////////////////////////////////////////////////////////////////////// /** @@ -35,67 +35,68 @@ * @brief Helper macros for LUT programming * @{ */ -#define SCI_LEN 8 -#define KEY_LEN_128 16 -#define KEY_LEN_256 32 -#define AN0_VALID OSI_BIT(0) -#define AN1_VALID OSI_BIT(1) -#define AN2_VALID OSI_BIT(2) -#define AN3_VALID OSI_BIT(3) -#define MAX_NUM_SC 8 -#define MAX_NUM_SA 4 -#define CURR_AN_MAX 3 /* 0-3 */ -#define KEY_INDEX_MAX 31 /* 0-31 */ -#define PN_MAX_DEFAULT 0xFFFFFFFF -#define PN_THRESHOLD_DEFAULT 0xC0000000 -#define TCI_DEFAULT 0x1 -#define VLAN_IN_CLEAR_DEFAULT 0x0 -#define SC_INDEX_MAX 15 /* 0-15 */ -#define ETHTYPE_LEN 2 -#define LUT_BYTE_PATTERN_MAX 4 -#define LUT_BYTE_PATTERN_MAX_OFFSET 63 /* 0-63 */ -#define VLAN_PCP_MAX 7 /* 0-7 */ -#define VLAN_ID_MAX 4095 /* 1-4095 */ - -#define LUT_SEL_BYPASS 0U -#define LUT_SEL_SCI 1U -#define LUT_SEL_SC_PARAM 2U -#define LUT_SEL_SC_STATE 3U -#define LUT_SEL_SA_STATE 4U -#define LUT_SEL_MAX 4U /* 0-4 */ +#define OSI_SCI_LEN 8 +#define OSI_KEY_LEN_128 16 +#define OSI_KEY_LEN_256 32 +#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_SC 8 +#define OSI_MAX_NUM_SA 4 +#define OSI_CURR_AN_MAX 3 +#define OSI_KEY_INDEX_MAX 31 +#define OSI_PN_MAX_DEFAULT 0xFFFFFFFF +#define OSI_PN_THRESHOLD_DEFAULT 0xC0000000 +#define OSI_TCI_DEFAULT 0x1 +#define OSI_VLAN_IN_CLEAR_DEFAULT 0x0 +#define OSI_SC_INDEX_MAX 15 +#define OSI_ETHTYPE_LEN 2 +#define OSI_LUT_BYTE_PATTERN_MAX 4 +/* LUT byte pattern offset range 0-63 */ +#define OSI_LUT_BYTE_PATTERN_MAX_OFFSET 63 +/* VLAN PCP range 0-7 */ +#define OSI_VLAN_PCP_MAX 7 +/* VLAN ID range 1-4095 */ +#define OSI_VLAN_ID_MAX 4095 +#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 LUT_FLAGS_DA_BYTE0_VALID OSI_BIT(0) -#define LUT_FLAGS_DA_BYTE1_VALID OSI_BIT(1) -#define LUT_FLAGS_DA_BYTE2_VALID OSI_BIT(2) -#define LUT_FLAGS_DA_BYTE3_VALID OSI_BIT(3) -#define LUT_FLAGS_DA_BYTE4_VALID OSI_BIT(4) -#define LUT_FLAGS_DA_BYTE5_VALID OSI_BIT(5) -#define LUT_FLAGS_DA_VALID (OSI_BIT(0) | OSI_BIT(1) | OSI_BIT(2) |\ +#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 LUT_FLAGS_SA_BYTE0_VALID OSI_BIT(6) -#define LUT_FLAGS_SA_BYTE1_VALID OSI_BIT(7) -#define LUT_FLAGS_SA_BYTE2_VALID OSI_BIT(8) -#define LUT_FLAGS_SA_BYTE3_VALID OSI_BIT(9) -#define LUT_FLAGS_SA_BYTE4_VALID OSI_BIT(10) -#define LUT_FLAGS_SA_BYTE5_VALID OSI_BIT(11) -#define LUT_FLAGS_SA_VALID (OSI_BIT(6) | OSI_BIT(7) | OSI_BIT(8) |\ +#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 LUT_FLAGS_ETHTYPE_VALID OSI_BIT(12) -#define LUT_FLAGS_VLAN_PCP_VALID OSI_BIT(13) -#define LUT_FLAGS_VLAN_ID_VALID OSI_BIT(14) -#define LUT_FLAGS_VLAN_VALID OSI_BIT(15) -#define LUT_FLAGS_BYTE0_PATTERN_VALID OSI_BIT(16) -#define LUT_FLAGS_BYTE1_PATTERN_VALID OSI_BIT(17) -#define LUT_FLAGS_BYTE2_PATTERN_VALID OSI_BIT(18) -#define LUT_FLAGS_BYTE3_PATTERN_VALID OSI_BIT(19) -#define LUT_FLAGS_PREEMPT OSI_BIT(20) -#define LUT_FLAGS_PREEMPT_VALID OSI_BIT(21) -#define LUT_FLAGS_CONTROLLED_PORT OSI_BIT(22) -#define LUT_FLAGS_DVLAN_PKT OSI_BIT(23) -#define LUT_FLAGS_DVLAN_OUTER_INNER_TAG_SEL OSI_BIT(24) -#define LUT_FLAGS_ENTRY_VALID OSI_BIT(31) - +#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) /** @} */ /** @@ -104,18 +105,17 @@ * @brief Helper macros for generic table CONFIG register programming * @{ */ -#define CTLR_SEL_TX 0U -#define CTLR_SEL_RX 1U -#define CTLR_SEL_MAX 1U -#define NUM_CTLR 2U -#define LUT_READ 0U -#define LUT_WRITE 1U -#define RW_MAX 1U -#define TABLE_INDEX_MAX 31U /* 0-31 */ -#define BYP_LUT_MAX_INDEX TABLE_INDEX_MAX -#define SC_LUT_MAX_INDEX 15U -#define SA_LUT_MAX_INDEX TABLE_INDEX_MAX - +#define OSI_CTLR_SEL_TX 0U +#define OSI_CTLR_SEL_RX 1U +#define OSI_CTLR_SEL_MAX 1U +#define OSI_NUM_CTLR 2U +#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 /** @} */ /** @@ -124,287 +124,283 @@ * @brief Helper macros for debug buffer table CONFIG register programming * @{ */ -#define DBG_TBL_READ LUT_READ -#define DBG_TBL_WRITE LUT_WRITE +#define OSI_DBG_TBL_READ OSI_LUT_READ +#define OSI_DBG_TBL_WRITE OSI_LUT_WRITE /* Num of Tx debug buffers */ -#define TX_DBG_BUF_IDX_MAX 12U +#define OSI_TX_DBG_BUF_IDX_MAX 12U /* Num of Rx debug buffers */ -#define RX_DBG_BUF_IDX_MAX 13U -#define DBG_BUF_IDX_MAX RX_DBG_BUF_IDX_MAX +#define OSI_RX_DBG_BUF_IDX_MAX 13U +#define OSI_DBG_BUF_IDX_MAX OSI_RX_DBG_BUF_IDX_MAX /** flag - encoding various debug event bits */ -#define TX_DBG_LKUP_MISS_EVT OSI_BIT(0) -#define TX_DBG_AN_NOT_VALID_EVT OSI_BIT(1) -#define TX_DBG_KEY_NOT_VALID_EVT OSI_BIT(2) -#define TX_DBG_CRC_CORRUPT_EVT OSI_BIT(3) -#define TX_DBG_ICV_CORRUPT_EVT OSI_BIT(4) -#define TX_DBG_CAPTURE_EVT OSI_BIT(5) -#define RX_DBG_LKUP_MISS_EVT OSI_BIT(6) -#define RX_DBG_KEY_NOT_VALID_EVT OSI_BIT(7) -#define RX_DBG_REPLAY_ERR_EVT OSI_BIT(8) -#define RX_DBG_CRC_CORRUPT_EVT OSI_BIT(9) -#define RX_DBG_ICV_ERROR_EVT OSI_BIT(10) -#define RX_DBG_CAPTURE_EVT OSI_BIT(11) - +#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) /** @} */ -/* AES cipthers 128 bit or 256 bit */ -#define MACSEC_CIPHER_AES128 0U -#define MACSEC_CIPHER_AES256 1U +/** + * @addtogroup AES ciphers + * + * @brief Helper macro's for AES ciphers + * @{ + */ +#define OSI_MACSEC_CIPHER_AES128 0U +#define OSI_MACSEC_CIPHER_AES256 1U +/** @} */ -/* macsec tx/rx enable */ +/** + * @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 */ +/* MACSEC SECTAG + ICV + 2B ethertype adds upto 34B */ #define MACSEC_TAG_ICV_LEN 34 -/* Add 8B for double VLAN tags (4B each), - * 14B for L2 SA/DA/ethertype - * 4B for FCS - */ - -/* macsec tz key config cmd */ -#define MACSEC_CMD_TZ_CONFIG 0x1 -/* macsec tz key table entries reset cmd */ -#define MACSEC_CMD_TZ_KT_RESET 0x2 - -/* AES cipthers 128 bit or 256 bit */ -#define MACSEC_CIPHER_AES128 0U -#define MACSEC_CIPHER_AES256 1U +/* 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 MACsec SA State LUT entry outputs structure + * @brief MACSEC SA State LUT entry outputs structure */ -struct sa_state_outputs { - /** Next PN to use */ - unsigned int next_pn; - /** Lowest PN to use */ - unsigned int lowest_pn; +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 + * @brief MACSEC SC State LUT entry outputs structure */ -struct sc_state_outputs { - /** Current AN to use */ - unsigned int curr_an; +struct osi_sc_state_outputs { + /** Indicates current AN to use */ + nveu32_t curr_an; }; /** - * @brief MACsec SC Param LUT entry outputs structure + * @brief MACSEC SC Param LUT entry outputs structure */ -struct sc_param_outputs { - /** Key index start */ - unsigned int key_index_start; +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 */ - unsigned int pn_max; + nveu32_t pn_max; /** PN threshold to trigger irq when threshold is reached */ - unsigned int pn_threshold; - /** PN window */ - unsigned int pn_window; + nveu32_t pn_threshold; + /** Indidate PN window for engress packets */ + nveu32_t pn_window; /** SC identifier */ - unsigned char sci[SCI_LEN]; - /** Default TCI value V=1, ES=0, SC = 1 - * TCI 3 bits V=0, ES=0, SC=1 */ - unsigned char tci; - /** vlan in clear config */ - unsigned char vlan_in_clear; + 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 + * @brief MACSEC SCI LUT entry outputs structure */ -struct sci_lut_outputs { - /** SC index to use */ - unsigned int sc_index; +struct osi_sci_lut_outputs { + /** Indicates SC index to use */ + nveu32_t sc_index; /** SC identifier */ - unsigned char sci[SCI_LEN]; + nveu8_t sci[OSI_SCI_LEN]; /** AN's valid */ - unsigned int an_valid; + nveu32_t an_valid; }; /** - * @brief MACsec LUT config data structure + * @brief MACSEC LUT config data structure */ -struct macsec_table_config { - /** Controller select - * 0 - Tx - * 1 - Rx - */ - unsigned short ctlr_sel; - /** Read or write operation select - * 0 - Read - * 1 - Write - */ - unsigned short rw; - /** Table entry index */ - unsigned short index; +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 KT entry structure + * @brief MACSEC Key Table entry structure */ -struct kt_entry { - /** SAK key - max 256bit */ - unsigned char sak[KEY_LEN_256]; - /** H-key */ - unsigned char h[KEY_LEN_128]; +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 + * @brief MACSEC BYP/SCI LUT entry inputs structure */ -struct lut_inputs { +struct osi_lut_inputs { /** MAC DA to compare */ - unsigned char da[OSI_ETH_ALEN]; + nveu8_t da[OSI_ETH_ALEN]; /** MAC SA to compare */ - unsigned char sa[OSI_ETH_ALEN]; + nveu8_t sa[OSI_ETH_ALEN]; /** Ethertype to compare */ - unsigned char ethtype[ETHTYPE_LEN]; + nveu8_t ethtype[OSI_ETHTYPE_LEN]; /** 4-Byte pattern to compare */ - unsigned char byte_pattern[LUT_BYTE_PATTERN_MAX]; + nveu8_t byte_pattern[OSI_LUT_BYTE_PATTERN_MAX]; /** Offset for 4-Byte pattern to compare */ - unsigned int byte_pattern_offset[LUT_BYTE_PATTERN_MAX]; + nveu32_t byte_pattern_offset[OSI_LUT_BYTE_PATTERN_MAX]; /** VLAN PCP to compare */ - unsigned int vlan_pcp; + nveu32_t vlan_pcp; /** VLAN ID to compare */ - unsigned int vlan_id; + nveu32_t vlan_id; }; /** - * @brief MACsec secure channel basic information + * @brief MACSEC secure channel basic information */ struct osi_macsec_sc_info { /** Secure channel identifier */ - unsigned char sci[SCI_LEN]; + nveu8_t sci[OSI_SCI_LEN]; /** Secure association key */ - unsigned char sak[KEY_LEN_128]; + nveu8_t sak[OSI_KEY_LEN_128]; /** current AN */ - unsigned char curr_an; + nveu8_t curr_an; /** Next PN to use for the current AN */ - unsigned int next_pn; + nveu32_t next_pn; /** bitmap of valid AN */ - unsigned int an_valid; + nveu32_t an_valid; + /** PN window */ + nveu32_t pn_window; /** SC LUT index */ - unsigned int sc_idx_start; + nveu32_t sc_idx_start; }; /** - * @brief MACsec HW controller LUT's overall status + * @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[MAX_NUM_SC]; + struct osi_macsec_sc_info sc_info[OSI_MAX_NUM_SC]; /** next available BYP LUT index */ - unsigned int next_byp_idx; + nveu32_t next_byp_idx; /** next available SC LUT index */ - unsigned int next_sc_idx; + nveu32_t next_sc_idx; }; /** - * @brief MACsec LUT config data structure + * @brief MACSEC LUT config data structure */ struct osi_macsec_lut_config { /** Generic table config */ - struct macsec_table_config table_config; - /** LUT select */ - unsigned short lut_sel; - /** flag - encoding various valid bits for above fields */ - unsigned int flags; - /** LUT inputs */ - struct lut_inputs lut_in; + 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 sci_lut_outputs sci_lut_out; - /** SC Param outputs */ - struct sc_param_outputs sc_param_out; - /** SC State outputs */ - struct sc_state_outputs sc_state_out; - /** SA State outputs */ - struct sa_state_outputs sa_state_out; + 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 KT config data structure + * @brief MACSEC Key Table config data structure */ struct osi_macsec_kt_config { /** Generic table config */ - struct macsec_table_config table_config; - /** KT entry */ - struct kt_entry entry; - /** flag - encoding various valid bits */ - unsigned int flags; + 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 data structure + * @brief MACSEC Debug buffer config data structure */ struct osi_macsec_dbg_buf_config { - /** Controller select - * 0 - Tx - * 1 - Rx - */ - unsigned short ctlr_sel; - /** Read or write operation select - * 0 - Read - * 1 - Write - */ - unsigned short rw; - /** debug data buffer */ - unsigned int dbg_buf[4]; + /** 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 */ - unsigned int flags; - /** debug buffer index */ - unsigned int index; + nveu32_t flags; + /** Indicates debug buffer index */ + nveu32_t index; }; /** - * @brief MACsec core operations structure + * @brief MACSEC core operations structure */ -struct macsec_core_ops { +struct osi_macsec_core_ops { /** macsec init */ - int (*init)(struct osi_core_priv_data *const osi_core); + nve32_t (*init)(struct osi_core_priv_data *const osi_core); /** macsec de-init */ - int (*deinit)(struct osi_core_priv_data *const osi_core); - /** NS irq handler */ + 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); - /** S irq handler */ + /** Secure irq handler */ void (*handle_s_irq)(struct osi_core_priv_data *const osi_core); /** macsec lut config */ - int (*lut_config)(struct osi_core_priv_data *const osi_core, + 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 */ - int (*kt_config)(struct osi_core_priv_data *const osi_core, + 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 */ - int (*cipher_config)(struct osi_core_priv_data *const osi_core, - unsigned int cipher); + nve32_t (*cipher_config)(struct osi_core_priv_data *const osi_core, + nveu32_t cipher); /** macsec loopback config */ - int (*loopback_config)(struct osi_core_priv_data *const osi_core, - unsigned int enable); + nve32_t (*loopback_config)(struct osi_core_priv_data *const osi_core, + nveu32_t enable); /** macsec enable */ - int (*macsec_en)(struct osi_core_priv_data *const osi_core, - unsigned int enable); + nve32_t (*macsec_en)(struct osi_core_priv_data *const osi_core, + nveu32_t enable); /** macsec config SA in HW LUT */ - int (*config)(struct osi_core_priv_data *const osi_core, + nve32_t (*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); + 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 */ - int (*dbg_buf_config)(struct osi_core_priv_data *const osi_core, + 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 */ - int (*dbg_events_config)(struct osi_core_priv_data *const osi_core, + nve32_t (*dbg_events_config)(struct osi_core_priv_data *const osi_core, struct osi_macsec_dbg_buf_config *const dbg_buf_config); }; - ////////////////////////////////////////////////////////////////////////// - /* OSI interface API prototypes */ + /* MACSEC OSI interface API prototypes */ ////////////////////////////////////////////////////////////////////////// /** @@ -438,7 +434,7 @@ struct macsec_core_ops { * @retval 0 on success * @retval -1 on failure */ -int osi_init_macsec_ops(struct osi_core_priv_data *const osi_core); +nve32_t osi_init_macsec_ops(struct osi_core_priv_data *const osi_core); /** * @brief Initialize the macsec controller @@ -473,24 +469,71 @@ int osi_init_macsec_ops(struct osi_core_priv_data *const osi_core); * @retval 0 on success * @retval -1 on failure */ -int osi_macsec_init(struct osi_core_priv_data *const osi_core); - +nve32_t osi_macsec_init(struct osi_core_priv_data *const osi_core); /** - * @brief De-initialize the macsec controller + * @brief De-Initialize the macsec controller + * + * @note + * Algorithm: + * - Resets macsec global data structures * * @param[in] osi_core: OSI core private data structure. * + * @pre + * - MACSEC TX/RX engine shall be disabled. + * + * @note + * Traceability Details: + * - SWUD_ID: + * + * @note + * Classification: + * - Interrupt: No + * - Signal handler: No + * - Thread safe: No + * - Required Privileges: None + * + * @note + * API Group: + * - Initialization: No + * - Run time: Yes + * - De-initialization: Yes + * * @retval 0 on success * @retval -1 on failure */ -int osi_macsec_deinit(struct osi_core_priv_data *const osi_core); +nve32_t osi_macsec_deinit(struct osi_core_priv_data *const osi_core); /** - * @brief Non-secure irq handler + * @brief Non-secure irq handler. + * + * @note + * Algorithm: + * - Takes care of handling the non secture interrupts accordingly as per + * the MACSEC IP * * @param[in] osi_core: OSI core private data structure. * + * @pre MACSEC should be inited and enabled. + * + * @note + * Traceability Details: + * - SWUD_ID: + * + * @note + * Classification: + * - Interrupt: Yes + * - Signal handler: No + * - Thread safe: No + * - Required Privileges: None + * + * @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); @@ -498,121 +541,362 @@ void osi_macsec_ns_isr(struct osi_core_priv_data *const osi_core); /** * @brief Secure irq handler * + * @note + * Algorithm: + * - Takes care of handling the secture interrupts accordingly as per + * the MACSEC IP + * * @param[in] osi_core: OSI core private data structure. * + * @pre MACSEC should be inited and enabled. + * + * @note + * Traceability Details: + * - SWUD_ID: + * + * @note + * Classification: + * - Interrupt: Yes + * - Signal handler: No + * - Thread safe: No + * - Required Privileges: None + * + * @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 MACsec Lookup table config + * @brief MACSEC Lookup table configuration + * + * @note + * Algorithm: + * - Configures MACSEC LUT entry for BYP, SCI, SC PARAM, SC STATE, SA STATE + * table * * @param[in] osi_core: OSI core private data structure. * @param[in] lut_config: OSI macsec LUT config data structure. * + * @pre + * - MACSEC shall be initialized and enalbed + * + * @note + * Traceability Details: + * - SWUD_ID: + * + * @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 */ -int osi_macsec_lut_config(struct osi_core_priv_data *const osi_core, +nve32_t osi_macsec_lut_config(struct osi_core_priv_data *const osi_core, struct osi_macsec_lut_config *const lut_confg); /** - * @brief MACsec key table config + * @brief MACSEC Key table configuration + * + * @note + * Algorithm: + * - Configures MACSEC Key Table entry * * @param[in] osi_core: OSI core private data structure. - * @param[in] kt_config: OSI macsec KT config data structure. + * @param[in] kt_config: OSI macsec Key table config data structure. + * + * @pre + * - MACSEC shall be initialized and enalbed + * + * @note + * Traceability Details: + * - SWUD_ID: + * + * @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 */ -int osi_macsec_kt_config(struct osi_core_priv_data *const osi_core, +nve32_t osi_macsec_kt_config(struct osi_core_priv_data *const osi_core, struct osi_macsec_kt_config *const kt_config); /** - * @brief MACsec cipther config + * @brief MACSEC cipher configuration + * + * @note + * Algorithm: + * - Configure MACSEC tx/rx controller cipther mode. * * @param[in] osi_core: OSI core private data structure. * @param[in] cipher: AES cipher to be configured to controller. * + * @pre + * - MACSEC shall be initialized and enalbed + * + * @note + * Traceability Details: + * - SWUD_ID: + * + * @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 */ -int osi_macsec_cipher_config(struct osi_core_priv_data *const osi_core, - unsigned int cipher); +nve32_t osi_macsec_cipher_config(struct osi_core_priv_data *const osi_core, + nveu32_t cipher); /** - * @brief MACsec Loopback config + * @brief MACSEC Loopback configuration + * + * @note + * Algorithm: + * - Configure MACSEC controller to loopback mode. * * @param[in] osi_core: OSI core private data structure. * @param[in] enable: Loopback enable/disable flag. * + * @pre + * - MACSEC shall be initialized and enalbed + * + * @note + * Traceability Details: + * - SWUD_ID: + * + * @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 */ -int osi_macsec_loopback(struct osi_core_priv_data *const osi_core, - unsigned int enable); +nve32_t osi_macsec_loopback(struct osi_core_priv_data *const osi_core, + nveu32_t enable); /** - * @brief MACsec Enable + * @brief MACSEC Controller Enable/Disable + * + * @note + * Algorithm: + * - Configure MACSEC controller to loopback mode. * * @param[in] osi_core: OSI core private data structure. - * @param[in] enable: macsec controller Tx/Rx enable/disable flag. + * @param[in] enable: Loopback enable/disable flag. + * + * @pre + * - MACSEC shall be initialized and enalbed + * + * @note + * Traceability Details: + * - SWUD_ID: + * + * @note + * Classification: + * - Interrupt: No + * - Signal handler: No + * - Thread safe: No + * - Required Privileges: None + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: Yes + * - De-initialization: Yes * * @retval 0 on success * @retval -1 on failure */ -int osi_macsec_en(struct osi_core_priv_data *const osi_core, - unsigned int enable); +nve32_t osi_macsec_en(struct osi_core_priv_data *const osi_core, + nveu32_t enable); /** - * @brief MACsec update secure channel/association in controller + * @brief MACSEC update secure channel/association in controller + * + * @note + * Algorithm: + * - Create/Delete/Update SC/AN in controller. * * @param[in] osi_core: OSI core private data structure. * @param[in] sc: Pointer to osi_macsec_sc_info struct for the tx SA. * @param[in] enable: flag to indicate enable/disable for the Tx SA. * @param[out] kt_idx: Key table index to program SAK. * + * @pre + * - MACSEC shall be initialized and enalbed + * + * @note + * Traceability Details: + * - SWUD_ID: + * + * @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 */ -int osi_macsec_config(struct osi_core_priv_data *const osi_core, +nve32_t osi_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); + nveu32_t enable, nveu16_t ctlr, + nveu16_t *kt_idx); /** - * @brief MACsec read statistics counters + * @brief MACSEC read statistics counters + * + * @note + * Algorithm: + * - Reads the MACSEC statistics counters * * @param[in] osi_core: OSI core private data structure. * + * @pre + * - MACSEC shall be initialized and enalbed + * + * @note + * Traceability Details: + * - SWUD_ID: + * + * @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 */ -int osi_macsec_read_mmc(struct osi_core_priv_data *const osi_core); +nve32_t osi_macsec_read_mmc(struct osi_core_priv_data *const osi_core); /** - * @brief MACsec debug buffer config + * @brief MACSEC debug buffer configuration + * + * @note + * Algorithm: + * - Read or Write MACSEC debug buffers * * @param[in] osi_core: OSI core private data structure. * @param[in] dbg_buf_config: OSI macsec debug buffer config data structure. * + * @pre + * - MACSEC shall be initialized and enalbed + * + * @note + * Traceability Details: + * - SWUD_ID: + * + * @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 */ -int osi_macsec_dbg_buf_config( +nve32_t osi_macsec_dbg_buf_config( struct osi_core_priv_data *const osi_core, struct osi_macsec_dbg_buf_config *const dbg_buf_config); /** - * @brief MACsec debug events config + * @brief MACSEC debug events configuration + * + * @note + * Algorithm: + * - Configures MACSEC debug events to be triggered. * * @param[in] osi_core: OSI core private data structure. * @param[in] dbg_buf_config: OSI macsec debug buffer config data structure. * + * @pre + * - MACSEC shall be initialized and enalbed + * + * @note + * Traceability Details: + * - SWUD_ID: + * + * @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 */ -int osi_macsec_dbg_events_config( +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); diff --git a/osi/common/type.h b/osi/common/type.h index 035c69f..d2ed7c7 100644 --- a/osi/common/type.h +++ b/osi/common/type.h @@ -35,6 +35,10 @@ 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 */ @@ -49,6 +53,10 @@ typedef unsigned long my_uint64_t; 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 */ diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index b457c15..d4a1ac5 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -516,7 +516,7 @@ static int ivc_macsec_init(struct osi_core_priv_data *const osi_core) */ void ivc_init_macsec_ops(void *macsecops) { - struct macsec_core_ops *ops = (struct macsec_core_ops *) macsecops; + struct osi_macsec_core_ops *ops = (struct osi_macsec_core_ops *) macsecops; ops->init = ivc_macsec_init; ops->deinit = ivc_macsec_deinit; diff --git a/osi/core/macsec.c b/osi/core/macsec.c index e752f10..6c77b51 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -27,7 +27,7 @@ #include "macsec.h" #include "../osi/common/common.h" #include "core_local.h" -#ifdef LINUX_IVC +#ifdef DEBUG_MACSEC #include <linux/printk.h> #else #define pr_cont(args...) @@ -42,26 +42,31 @@ * @retval 0 on Success * @retval -1 on Failure */ -static int poll_for_dbg_buf_update(struct osi_core_priv_data *const osi_core) +static nve32_t poll_for_dbg_buf_update(struct osi_core_priv_data *const osi_core) { - int retry = 5000; - unsigned int dbg_buf_config; + nve32_t retry = RETRY_COUNT; + nveu32_t dbg_buf_config; + nve32_t cond = COND_NOT_MET; + nveu32_t count; - while (retry > 0) { - dbg_buf_config = osi_readla(osi_core, - (unsigned char *)osi_core->macsec_base + - DEBUG_BUF_CONFIG_0); - if ((dbg_buf_config & DEBUG_BUF_CONFIG_0_UPDATE) == 0U) { - break; + 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) == 0U) { + cond = COND_MET; + } + + count++; /* wait on UPDATE bit to reset */ osi_core->osd_ops.udelay(10U); - retry--; - } - /** timeout */ - if (retry <= 0) { - pr_err("%s(): timeout!\n", __func__); - return -1; } return 0; @@ -78,17 +83,19 @@ static int poll_for_dbg_buf_update(struct osi_core_priv_data *const osi_core) */ static inline void write_dbg_buf_data( struct osi_core_priv_data *const osi_core, - unsigned int const *const dbg_buf) + nveu32_t const *const dbg_buf) { - unsigned char *base = (unsigned char *)osi_core->macsec_base; - int i; + 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++) { /* pr_err("%s: dbg_buf_data[%d]: 0x%x\n", __func__, - i, dbg_buf[i]); */ - osi_writela(osi_core, dbg_buf[i], base + DEBUG_BUF_DATA_0(i)); + i, dbg_buf[i]); + */ + osi_writela(osi_core, dbg_buf[i], base + + MACSEC_DEBUG_BUF_DATA_0(i)); } } @@ -102,15 +109,16 @@ static inline void write_dbg_buf_data( */ static inline void read_dbg_buf_data( struct osi_core_priv_data *const osi_core, - unsigned int *dbg_buf) + nveu32_t *dbg_buf) { - unsigned char *base = (unsigned char *)osi_core->macsec_base; - int i; + 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 + DEBUG_BUF_DATA_0(i)); + dbg_buf[i] = osi_readla(osi_core, base + + MACSEC_DEBUG_BUF_DATA_0(i)); /* pr_err("%s: dbg_buf_data[%d]: 0x%x\n", __func__, i, dbg_buf[i]); */ } @@ -129,86 +137,86 @@ static void tx_dbg_trigger_evts( struct osi_macsec_dbg_buf_config *const dbg_buf_config) { - unsigned char *base = (unsigned char *)osi_core->macsec_base; - unsigned int flags = 0; - unsigned int tx_trigger_evts, debug_ctrl_reg; + nveu8_t *base = (nveu8_t *)osi_core->macsec_base; + nveu32_t flags = 0; + nveu32_t tx_trigger_evts, debug_ctrl_reg; - if (dbg_buf_config->rw == DBG_TBL_WRITE) { + if (dbg_buf_config->rw == OSI_DBG_TBL_WRITE) { flags = dbg_buf_config->flags; tx_trigger_evts = osi_readla(osi_core, - base + TX_DEBUG_TRIGGER_EN_0); - if (flags & TX_DBG_LKUP_MISS_EVT) { - tx_trigger_evts |= TX_DBG_LKUP_MISS; + base + MACSEC_TX_DEBUG_TRIGGER_EN_0); + if (flags & OSI_TX_DBG_LKUP_MISS_EVT) { + tx_trigger_evts |= MACSEC_TX_DBG_LKUP_MISS; } else { - tx_trigger_evts &= ~TX_DBG_LKUP_MISS; + tx_trigger_evts &= ~MACSEC_TX_DBG_LKUP_MISS; } - if (flags & TX_DBG_AN_NOT_VALID_EVT) { - tx_trigger_evts |= TX_DBG_AN_NOT_VALID; + if (flags & OSI_TX_DBG_AN_NOT_VALID_EVT) { + tx_trigger_evts |= MACSEC_TX_DBG_AN_NOT_VALID; } else { - tx_trigger_evts &= ~TX_DBG_AN_NOT_VALID; + tx_trigger_evts &= ~MACSEC_TX_DBG_AN_NOT_VALID; } - if (flags & TX_DBG_KEY_NOT_VALID_EVT) { - tx_trigger_evts |= TX_DBG_KEY_NOT_VALID; + if (flags & OSI_TX_DBG_KEY_NOT_VALID_EVT) { + tx_trigger_evts |= MACSEC_TX_DBG_KEY_NOT_VALID; } else { - tx_trigger_evts &= ~TX_DBG_KEY_NOT_VALID; + tx_trigger_evts &= ~MACSEC_TX_DBG_KEY_NOT_VALID; } - if (flags & TX_DBG_CRC_CORRUPT_EVT) { - tx_trigger_evts |= TX_DBG_CRC_CORRUPT; + if (flags & OSI_TX_DBG_CRC_CORRUPT_EVT) { + tx_trigger_evts |= MACSEC_TX_DBG_CRC_CORRUPT; } else { - tx_trigger_evts &= ~TX_DBG_CRC_CORRUPT; + tx_trigger_evts &= ~MACSEC_TX_DBG_CRC_CORRUPT; } - if (flags & TX_DBG_ICV_CORRUPT_EVT) { - tx_trigger_evts |= TX_DBG_ICV_CORRUPT; + if (flags & OSI_TX_DBG_ICV_CORRUPT_EVT) { + tx_trigger_evts |= MACSEC_TX_DBG_ICV_CORRUPT; } else { - tx_trigger_evts &= ~TX_DBG_ICV_CORRUPT; + tx_trigger_evts &= ~MACSEC_TX_DBG_ICV_CORRUPT; } - if (flags & TX_DBG_CAPTURE_EVT) { - tx_trigger_evts |= TX_DBG_CAPTURE; + if (flags & OSI_TX_DBG_CAPTURE_EVT) { + tx_trigger_evts |= MACSEC_TX_DBG_CAPTURE; } else { - tx_trigger_evts &= ~TX_DBG_CAPTURE; + tx_trigger_evts &= ~MACSEC_TX_DBG_CAPTURE; } pr_err("%s: tx_dbg_trigger_evts 0x%x", __func__, tx_trigger_evts); osi_writela(osi_core, tx_trigger_evts, - base + TX_DEBUG_TRIGGER_EN_0); + 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 + TX_DEBUG_CONTROL_0); - debug_ctrl_reg |= TX_DEBUG_CONTROL_0_START_CAP; + base + MACSEC_TX_DEBUG_CONTROL_0); + debug_ctrl_reg |= MACSEC_TX_DEBUG_CONTROL_0_START_CAP; pr_err("%s: debug_ctrl_reg 0x%x", __func__, debug_ctrl_reg); osi_writela(osi_core, debug_ctrl_reg, - base + TX_DEBUG_CONTROL_0); + base + MACSEC_TX_DEBUG_CONTROL_0); } } else { tx_trigger_evts = osi_readla(osi_core, - base + TX_DEBUG_TRIGGER_EN_0); + base + MACSEC_TX_DEBUG_TRIGGER_EN_0); pr_err("%s: tx_dbg_trigger_evts 0x%x", __func__, tx_trigger_evts); - if (tx_trigger_evts & TX_DBG_LKUP_MISS) { - flags |= TX_DBG_LKUP_MISS_EVT; + if (tx_trigger_evts & MACSEC_TX_DBG_LKUP_MISS) { + flags |= OSI_TX_DBG_LKUP_MISS_EVT; } - if (tx_trigger_evts & TX_DBG_AN_NOT_VALID) { - flags |= TX_DBG_AN_NOT_VALID_EVT; + if (tx_trigger_evts & MACSEC_TX_DBG_AN_NOT_VALID) { + flags |= OSI_TX_DBG_AN_NOT_VALID_EVT; } - if (tx_trigger_evts & TX_DBG_KEY_NOT_VALID) { - flags |= TX_DBG_KEY_NOT_VALID_EVT; + if (tx_trigger_evts & MACSEC_TX_DBG_KEY_NOT_VALID) { + flags |= OSI_TX_DBG_KEY_NOT_VALID_EVT; } - if (tx_trigger_evts & TX_DBG_CRC_CORRUPT) { - flags |= TX_DBG_CRC_CORRUPT_EVT; + if (tx_trigger_evts & MACSEC_TX_DBG_CRC_CORRUPT) { + flags |= OSI_TX_DBG_CRC_CORRUPT_EVT; } - if (tx_trigger_evts & TX_DBG_ICV_CORRUPT) { - flags |= TX_DBG_ICV_CORRUPT_EVT; + if (tx_trigger_evts & MACSEC_TX_DBG_ICV_CORRUPT) { + flags |= OSI_TX_DBG_ICV_CORRUPT_EVT; } - if (tx_trigger_evts & TX_DBG_CAPTURE) { - flags |= TX_DBG_CAPTURE_EVT; + if (tx_trigger_evts & MACSEC_TX_DBG_CAPTURE) { + flags |= OSI_TX_DBG_CAPTURE_EVT; } dbg_buf_config->flags = flags; } @@ -227,85 +235,85 @@ static void rx_dbg_trigger_evts( struct osi_macsec_dbg_buf_config *const dbg_buf_config) { - unsigned char *base = (unsigned char *)osi_core->macsec_base; - unsigned int flags = 0; - unsigned int rx_trigger_evts, debug_ctrl_reg; + nveu8_t *base = (nveu8_t *)osi_core->macsec_base; + nveu32_t flags = 0; + nveu32_t rx_trigger_evts, debug_ctrl_reg; - if (dbg_buf_config->rw == DBG_TBL_WRITE) { + if (dbg_buf_config->rw == OSI_DBG_TBL_WRITE) { flags = dbg_buf_config->flags; rx_trigger_evts = osi_readla(osi_core, - base + RX_DEBUG_TRIGGER_EN_0); - if (flags & RX_DBG_LKUP_MISS_EVT) { - rx_trigger_evts |= RX_DBG_LKUP_MISS; + base + MACSEC_RX_DEBUG_TRIGGER_EN_0); + if (flags & OSI_RX_DBG_LKUP_MISS_EVT) { + rx_trigger_evts |= MACSEC_RX_DBG_LKUP_MISS; } else { - rx_trigger_evts &= ~RX_DBG_LKUP_MISS; + rx_trigger_evts &= ~MACSEC_RX_DBG_LKUP_MISS; } - if (flags & RX_DBG_KEY_NOT_VALID_EVT) { - rx_trigger_evts |= RX_DBG_KEY_NOT_VALID; + if (flags & OSI_RX_DBG_KEY_NOT_VALID_EVT) { + rx_trigger_evts |= MACSEC_RX_DBG_KEY_NOT_VALID; } else { - rx_trigger_evts &= ~RX_DBG_KEY_NOT_VALID; + rx_trigger_evts &= ~MACSEC_RX_DBG_KEY_NOT_VALID; } - if (flags & RX_DBG_REPLAY_ERR_EVT) { - rx_trigger_evts |= RX_DBG_REPLAY_ERR; + if (flags & OSI_RX_DBG_REPLAY_ERR_EVT) { + rx_trigger_evts |= MACSEC_RX_DBG_REPLAY_ERR; } else { - rx_trigger_evts &= ~RX_DBG_REPLAY_ERR; + rx_trigger_evts &= ~MACSEC_RX_DBG_REPLAY_ERR; } - if (flags & RX_DBG_CRC_CORRUPT_EVT) { - rx_trigger_evts |= RX_DBG_CRC_CORRUPT; + if (flags & OSI_RX_DBG_CRC_CORRUPT_EVT) { + rx_trigger_evts |= MACSEC_RX_DBG_CRC_CORRUPT; } else { - rx_trigger_evts &= ~RX_DBG_CRC_CORRUPT; + rx_trigger_evts &= ~MACSEC_RX_DBG_CRC_CORRUPT; } - if (flags & RX_DBG_ICV_ERROR_EVT) { - rx_trigger_evts |= RX_DBG_ICV_ERROR; + if (flags & OSI_RX_DBG_ICV_ERROR_EVT) { + rx_trigger_evts |= MACSEC_RX_DBG_ICV_ERROR; } else { - rx_trigger_evts &= ~RX_DBG_ICV_ERROR; + rx_trigger_evts &= ~MACSEC_RX_DBG_ICV_ERROR; } - if (flags & RX_DBG_CAPTURE_EVT) { - rx_trigger_evts |= RX_DBG_CAPTURE; + if (flags & OSI_RX_DBG_CAPTURE_EVT) { + rx_trigger_evts |= MACSEC_RX_DBG_CAPTURE; } else { - rx_trigger_evts &= ~RX_DBG_CAPTURE; + rx_trigger_evts &= ~MACSEC_RX_DBG_CAPTURE; } pr_err("%s: rx_dbg_trigger_evts 0x%x", __func__, rx_trigger_evts); osi_writela(osi_core, rx_trigger_evts, - base + RX_DEBUG_TRIGGER_EN_0); + 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 + RX_DEBUG_CONTROL_0); - debug_ctrl_reg |= RX_DEBUG_CONTROL_0_START_CAP; + base + MACSEC_RX_DEBUG_CONTROL_0); + debug_ctrl_reg |= MACSEC_RX_DEBUG_CONTROL_0_START_CAP; pr_err("%s: debug_ctrl_reg 0x%x", __func__, debug_ctrl_reg); osi_writela(osi_core, debug_ctrl_reg, - base + RX_DEBUG_CONTROL_0); + base + MACSEC_RX_DEBUG_CONTROL_0); } } else { rx_trigger_evts = osi_readla(osi_core, - base + RX_DEBUG_TRIGGER_EN_0); + base + MACSEC_RX_DEBUG_TRIGGER_EN_0); pr_err("%s: rx_dbg_trigger_evts 0x%x", __func__, rx_trigger_evts); - if (rx_trigger_evts & RX_DBG_LKUP_MISS) { - flags |= RX_DBG_LKUP_MISS_EVT; + if (rx_trigger_evts & MACSEC_RX_DBG_LKUP_MISS) { + flags |= OSI_RX_DBG_LKUP_MISS_EVT; } - if (rx_trigger_evts & RX_DBG_KEY_NOT_VALID) { - flags |= RX_DBG_KEY_NOT_VALID_EVT; + if (rx_trigger_evts & MACSEC_RX_DBG_KEY_NOT_VALID) { + flags |= OSI_RX_DBG_KEY_NOT_VALID_EVT; } - if (rx_trigger_evts & RX_DBG_REPLAY_ERR) { - flags |= RX_DBG_REPLAY_ERR_EVT; + if (rx_trigger_evts & MACSEC_RX_DBG_REPLAY_ERR) { + flags |= OSI_RX_DBG_REPLAY_ERR_EVT; } - if (rx_trigger_evts & RX_DBG_CRC_CORRUPT) { - flags |= RX_DBG_CRC_CORRUPT_EVT; + if (rx_trigger_evts & MACSEC_RX_DBG_CRC_CORRUPT) { + flags |= OSI_RX_DBG_CRC_CORRUPT_EVT; } - if (rx_trigger_evts & RX_DBG_ICV_ERROR) { - flags |= RX_DBG_ICV_ERROR_EVT; + if (rx_trigger_evts & MACSEC_RX_DBG_ICV_ERROR) { + flags |= OSI_RX_DBG_ICV_ERROR_EVT; } - if (rx_trigger_evts & RX_DBG_CAPTURE) { - flags |= RX_DBG_CAPTURE_EVT; + if (rx_trigger_evts & MACSEC_RX_DBG_CAPTURE) { + flags |= OSI_RX_DBG_CAPTURE_EVT; } dbg_buf_config->flags = flags; } @@ -320,25 +328,26 @@ static void rx_dbg_trigger_evts( * @retval 0 on Success * @retval -1 on Failure */ -static int macsec_dbg_buf_config(struct osi_core_priv_data *const osi_core, +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) { - unsigned char *base = (unsigned char *)osi_core->macsec_base; - unsigned int dbg_config_reg = 0; - int ret = 0; + nveu8_t *base = (nveu8_t *)osi_core->macsec_base; + nveu32_t dbg_config_reg = 0; + nve32_t ret = 0; /* Validate inputs */ - if ((dbg_buf_config->rw > RW_MAX) || - (dbg_buf_config->ctlr_sel > CTLR_SEL_MAX)) { - pr_err("%s(): Params validation failed\n", __func__); + 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 == CTLR_SEL_TX && - dbg_buf_config->index > TX_DBG_BUF_IDX_MAX) || - (dbg_buf_config->ctlr_sel == CTLR_SEL_RX && - dbg_buf_config->index > RX_DBG_BUF_IDX_MAX)) { + 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)) { pr_err("%s(): Wrong index %d\n", __func__, dbg_buf_config->index); return -1; @@ -354,26 +363,26 @@ static int macsec_dbg_buf_config(struct osi_core_priv_data *const osi_core, dbg_buf_config->ctlr_sel, dbg_buf_config->rw, dbg_buf_config->index); */ - dbg_config_reg = osi_readla(osi_core, base + DEBUG_BUF_CONFIG_0); + dbg_config_reg = osi_readla(osi_core, base + MACSEC_DEBUG_BUF_CONFIG_0); if (dbg_buf_config->ctlr_sel) { - dbg_config_reg |= DEBUG_BUF_CONFIG_0_CTLR_SEL; + dbg_config_reg |= MACSEC_DEBUG_BUF_CONFIG_0_CTLR_SEL; } else { - dbg_config_reg &= ~DEBUG_BUF_CONFIG_0_CTLR_SEL; + dbg_config_reg &= ~MACSEC_DEBUG_BUF_CONFIG_0_CTLR_SEL; } if (dbg_buf_config->rw) { - dbg_config_reg |= DEBUG_BUF_CONFIG_0_RW; + 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 &= ~DEBUG_BUF_CONFIG_0_RW; + dbg_config_reg &= ~MACSEC_DEBUG_BUF_CONFIG_0_RW; } - dbg_config_reg &= ~DEBUG_BUF_CONFIG_0_IDX_MASK; + dbg_config_reg &= ~MACSEC_DEBUG_BUF_CONFIG_0_IDX_MASK; dbg_config_reg |= dbg_buf_config->index ; - dbg_config_reg |= DEBUG_BUF_CONFIG_0_UPDATE; - osi_writela(osi_core, dbg_config_reg, base + DEBUG_BUF_CONFIG_0); + 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; @@ -386,40 +395,41 @@ static int macsec_dbg_buf_config(struct osi_core_priv_data *const osi_core, } -int macsec_dbg_events_config( +nve32_t macsec_dbg_events_config( struct osi_core_priv_data *const osi_core, struct osi_macsec_dbg_buf_config *const dbg_buf_config) { - unsigned int i, events = 0; - unsigned int flags = dbg_buf_config->flags; + nveu32_t i, events = 0; + nveu32_t flags = dbg_buf_config->flags; pr_err("%s():", __func__); /* Validate inputs */ - if ((dbg_buf_config->rw > RW_MAX) || - (dbg_buf_config->ctlr_sel > CTLR_SEL_MAX)) { - pr_err("%s(): Params validation failed", __func__); + 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 == DBG_TBL_WRITE) { + if (flags != OSI_NONE && dbg_buf_config->rw == OSI_DBG_TBL_WRITE) { for (i = 0; i < 32U; i++) { if (flags & (1U << i)) { events++; } } if (events > 1U) { - pr_err("%s(): Don't allow more than one" - " debug events set 0x%x\n", __func__, flags); + 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 CTLR_SEL_TX: + case OSI_CTLR_SEL_TX: tx_dbg_trigger_evts(osi_core, dbg_buf_config); break; - case CTLR_SEL_RX: + case OSI_CTLR_SEL_RX: rx_dbg_trigger_evts(osi_core, dbg_buf_config); break; } @@ -445,14 +455,13 @@ static inline unsigned long long update_macsec_mmc_val( struct osi_core_priv_data *osi_core, unsigned long offset) { - - unsigned long long temp; - unsigned int value_lo, value_hi; + nveul64_t temp; + nveu32_t value_lo, value_hi; value_lo = osi_readla(osi_core, - (unsigned char *)osi_core->macsec_base + offset); + (nveu8_t *)osi_core->macsec_base + offset); value_hi = osi_readla(osi_core, - (unsigned char *)osi_core->macsec_base + + (nveu8_t *)osi_core->macsec_base + (offset + 4U)); temp = (value_lo | value_hi << 31); @@ -475,70 +484,70 @@ static inline unsigned long long update_macsec_mmc_val( void macsec_read_mmc(struct osi_core_priv_data *const osi_core) { struct osi_macsec_mmc_counters *mmc = &osi_core->macsec_mmc; - unsigned short i; + nveu16_t i; mmc->tx_pkts_untaged = - update_macsec_mmc_val(osi_core, TX_PKTS_UNTG_LO_0); + update_macsec_mmc_val(osi_core, MACSEC_TX_PKTS_UNTG_LO_0); mmc->tx_pkts_too_long = - update_macsec_mmc_val(osi_core, TX_PKTS_TOO_LONG_LO_0); + update_macsec_mmc_val(osi_core, MACSEC_TX_PKTS_TOO_LONG_LO_0); mmc->tx_octets_protected = - update_macsec_mmc_val(osi_core, TX_OCTETS_PRTCTD_LO_0); + update_macsec_mmc_val(osi_core, MACSEC_TX_OCTETS_PRTCTD_LO_0); mmc->rx_pkts_no_tag = - update_macsec_mmc_val(osi_core, RX_PKTS_NOTG_LO_0); + update_macsec_mmc_val(osi_core, MACSEC_RX_PKTS_NOTG_LO_0); mmc->rx_pkts_untagged = - update_macsec_mmc_val(osi_core, RX_PKTS_UNTG_LO_0); + update_macsec_mmc_val(osi_core, MACSEC_RX_PKTS_UNTG_LO_0); mmc->rx_pkts_bad_tag = - update_macsec_mmc_val(osi_core, RX_PKTS_BADTAG_LO_0); + update_macsec_mmc_val(osi_core, MACSEC_RX_PKTS_BADTAG_LO_0); mmc->rx_pkts_no_sa_err = - update_macsec_mmc_val(osi_core, RX_PKTS_NOSAERROR_LO_0); + update_macsec_mmc_val(osi_core, MACSEC_RX_PKTS_NOSAERROR_LO_0); mmc->rx_pkts_no_sa = - update_macsec_mmc_val(osi_core, RX_PKTS_NOSA_LO_0); + update_macsec_mmc_val(osi_core, MACSEC_RX_PKTS_NOSA_LO_0); mmc->rx_pkts_overrun = - update_macsec_mmc_val(osi_core, RX_PKTS_OVRRUN_LO_0); + update_macsec_mmc_val(osi_core, MACSEC_RX_PKTS_OVRRUN_LO_0); mmc->rx_octets_validated = - update_macsec_mmc_val(osi_core, RX_OCTETS_VLDTD_LO_0); + update_macsec_mmc_val(osi_core, MACSEC_RX_OCTETS_VLDTD_LO_0); - for (i = 0; i <= SC_INDEX_MAX; i++) { + for (i = 0; i <= OSI_SC_INDEX_MAX; i++) { mmc->tx_pkts_protected[i] = update_macsec_mmc_val(osi_core, - TX_PKTS_PROTECTED_SCx_LO_0(i)); + MACSEC_TX_PKTS_PROTECTED_SCx_LO_0(i)); mmc->rx_pkts_late[i] = update_macsec_mmc_val(osi_core, - RX_PKTS_LATE_SCx_LO_0(i)); + 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, - RX_PKTS_NOTVALID_SCx_LO_0(i)); + 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, - RX_PKTS_OK_SCx_LO_0(i)); + MACSEC_RX_PKTS_OK_SCx_LO_0(i)); } } -int macsec_enable(struct osi_core_priv_data *osi_core, unsigned int enable) +nve32_t macsec_enable(struct osi_core_priv_data *osi_core, nveu32_t enable) { - unsigned int val; - unsigned char *base = (unsigned char *)osi_core->macsec_base; + nveu32_t val; + nveu8_t *base = (nveu8_t *)osi_core->macsec_base; val = osi_readla(osi_core, base + MACSEC_CONTROL0); pr_err("Read MACSEC_CONTROL0: 0x%x\n", val); if ((enable & OSI_MACSEC_TX_EN) == OSI_MACSEC_TX_EN) { pr_err("\tEnabling macsec TX"); - val |= (TX_EN); + val |= (MACSEC_TX_EN); } else { pr_err("\tDisabling macsec TX"); - val &= ~(TX_EN); + val &= ~(MACSEC_TX_EN); } if ((enable & OSI_MACSEC_RX_EN) == OSI_MACSEC_RX_EN) { pr_err("\tEnabling macsec RX"); - val |= (RX_EN); + val |= (MACSEC_RX_EN); } else { pr_err("\tDisabling macsec RX"); - val &= ~(RX_EN); + val &= ~(MACSEC_RX_EN); } pr_err("Write MACSEC_CONTROL0: 0x%x\n", val); @@ -556,13 +565,13 @@ int macsec_enable(struct osi_core_priv_data *osi_core, unsigned int enable) * @retval 0 on Success * @retval -1 on Failure */ -static inline int poll_for_kt_update(struct osi_core_priv_data *osi_core) +static inline nve32_t poll_for_kt_update(struct osi_core_priv_data *osi_core) { /* half sec timeout */ - unsigned int retry = 50000; - unsigned int kt_config; - unsigned int count; - int cond = 1; + nveu32_t retry = 50000; + nveu32_t kt_config; + nveu32_t count; + nve32_t cond = 1; count = 0; while (cond == 1) { @@ -577,9 +586,9 @@ static inline int poll_for_kt_update(struct osi_core_priv_data *osi_core) count++; kt_config = osi_readla(osi_core, - (unsigned char *)osi_core->tz_base + - GCM_KEYTABLE_CONFIG); - if ((kt_config & KT_CONFIG_UPDATE) == 0U) { + (nveu8_t *)osi_core->tz_base + + MACSEC_GCM_KEYTABLE_CONFIG); + if ((kt_config & MACSEC_KT_CONFIG_UPDATE) == 0U) { /* exit loop */ cond = 0; } else { @@ -591,21 +600,21 @@ static inline int poll_for_kt_update(struct osi_core_priv_data *osi_core) return 0; } -static int kt_key_read(struct osi_core_priv_data *const osi_core, +static nve32_t kt_key_read(struct osi_core_priv_data *const osi_core, struct osi_macsec_kt_config *const kt_config) { - unsigned int kt_key[MACSEC_KT_DATA_REG_CNT] = {0}; - int i, j; + nveu32_t kt_key[MACSEC_KT_DATA_REG_CNT] = {0}; + nve32_t i, j; for (i = 0; i < MACSEC_KT_DATA_REG_CNT; i++) { kt_key[i] = osi_readla(osi_core, - (unsigned char *)osi_core->tz_base + - GCM_KEYTABLE_DATA(i)); + (nveu8_t *)osi_core->tz_base + + MACSEC_GCM_KEYTABLE_DATA(i)); } - if ((kt_key[MACSEC_KT_DATA_REG_CNT - 1] & KT_ENTRY_VALID) == - KT_ENTRY_VALID) { - kt_config->flags |= LUT_FLAGS_ENTRY_VALID; + if ((kt_key[MACSEC_KT_DATA_REG_CNT - 1] & 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++) { @@ -626,12 +635,12 @@ static int kt_key_read(struct osi_core_priv_data *const osi_core, return 0; } -static int kt_key_write(struct osi_core_priv_data *const osi_core, +static nve32_t kt_key_write(struct osi_core_priv_data *const osi_core, struct osi_macsec_kt_config *const kt_config) { - unsigned int kt_key[MACSEC_KT_DATA_REG_CNT] = {0}; - struct kt_entry entry = kt_config->entry; - int i, j; + nveu32_t kt_key[MACSEC_KT_DATA_REG_CNT] = {0}; + struct osi_kt_entry entry = kt_config->entry; + nve32_t i, j; /* write SAK */ for (i = 0; i < MACSEC_KT_DATA_REG_SAK_CNT; i++) { @@ -649,34 +658,32 @@ static int kt_key_write(struct osi_core_priv_data *const osi_core, } } - if ((kt_config->flags & LUT_FLAGS_ENTRY_VALID) == - LUT_FLAGS_ENTRY_VALID) { - kt_key[MACSEC_KT_DATA_REG_CNT - 1] |= KT_ENTRY_VALID; + if ((kt_config->flags & OSI_LUT_FLAGS_ENTRY_VALID) == + OSI_LUT_FLAGS_ENTRY_VALID) { + kt_key[MACSEC_KT_DATA_REG_CNT - 1] |= MACSEC_KT_ENTRY_VALID; } for (i = 0; i < MACSEC_KT_DATA_REG_CNT; i++) { /* pr_err("%s: kt_key[%d]: 0x%x\n", __func__, i, kt_key[i]); */ osi_writela(osi_core, kt_key[i], - (unsigned char *)osi_core->tz_base + - GCM_KEYTABLE_DATA(i)); + (nveu8_t *)osi_core->tz_base + + MACSEC_GCM_KEYTABLE_DATA(i)); } return 0; } -static int macsec_kt_config(struct osi_core_priv_data *const osi_core, +static nve32_t macsec_kt_config(struct osi_core_priv_data *const osi_core, struct osi_macsec_kt_config *const kt_config) { - int ret = 0; - unsigned int kt_config_reg = 0; - unsigned char *base = (unsigned char *)osi_core->tz_base; + nve32_t ret = 0; + nveu32_t kt_config_reg = 0; + nveu8_t *base = (nveu8_t *)osi_core->tz_base; /* Validate KT config */ - if ((kt_config->table_config.ctlr_sel > CTLR_SEL_MAX) || - (kt_config->table_config.rw > RW_MAX) || - (kt_config->table_config.index > TABLE_INDEX_MAX)) { - /* TODO - validate using a local cache if index is - * already active */ + 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; } @@ -690,29 +697,29 @@ static int macsec_kt_config(struct osi_core_priv_data *const osi_core, kt_config->table_config.ctlr_sel, kt_config->table_config.rw, kt_config->table_config.index, kt_config->flags); */ - kt_config_reg = osi_readla(osi_core, base + GCM_KEYTABLE_CONFIG); + kt_config_reg = osi_readla(osi_core, base + MACSEC_GCM_KEYTABLE_CONFIG); if (kt_config->table_config.ctlr_sel) { - kt_config_reg |= KT_CONFIG_CTLR_SEL; + kt_config_reg |= MACSEC_KT_CONFIG_CTLR_SEL; } else { - kt_config_reg &= ~KT_CONFIG_CTLR_SEL; + kt_config_reg &= ~MACSEC_KT_CONFIG_CTLR_SEL; } if (kt_config->table_config.rw) { - kt_config_reg |= KT_CONFIG_RW; + 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 &= ~KT_CONFIG_RW; + kt_config_reg &= ~MACSEC_KT_CONFIG_RW; } - kt_config_reg &= ~KT_CONFIG_INDEX_MASK; + kt_config_reg &= ~MACSEC_KT_CONFIG_INDEX_MASK; kt_config_reg |= (kt_config->table_config.index); - kt_config_reg |= KT_CONFIG_UPDATE; - osi_writela(osi_core, kt_config_reg, base + GCM_KEYTABLE_CONFIG); + 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); @@ -738,13 +745,13 @@ static int macsec_kt_config(struct osi_core_priv_data *const osi_core, * @retval 0 on Success * @retval -1 on Failure */ -static inline int poll_for_lut_update(struct osi_core_priv_data *osi_core) +static inline nve32_t poll_for_lut_update(struct osi_core_priv_data *osi_core) { /* half sec timeout */ - unsigned int retry = 50000; - unsigned int lut_config; - unsigned int count; - int cond = 1; + nveu32_t retry = 50000; + nveu32_t lut_config; + nveu32_t count; + nve32_t cond = 1; count = 0; while (cond == 1) { @@ -759,9 +766,9 @@ static inline int poll_for_lut_update(struct osi_core_priv_data *osi_core) count++; lut_config = osi_readla(osi_core, - (unsigned char *)osi_core->macsec_base + + (nveu8_t *)osi_core->macsec_base + MACSEC_LUT_CONFIG); - if ((lut_config & LUT_CONFIG_UPDATE) == 0U) { + if ((lut_config & MACSEC_LUT_CONFIG_UPDATE) == 0U) { /* exit loop */ cond = 0; } else { @@ -774,10 +781,10 @@ static inline int poll_for_lut_update(struct osi_core_priv_data *osi_core) } static inline void read_lut_data(struct osi_core_priv_data *const osi_core, - unsigned int *const lut_data) + nveu32_t *const lut_data) { - unsigned char *base = (unsigned char *)osi_core->macsec_base; - int i; + nveu8_t *base = (nveu8_t *)osi_core->macsec_base; + nve32_t i; /* Commit the LUT entry to HW */ for (i = 0; i < MACSEC_LUT_DATA_REG_CNT; i++) { @@ -786,134 +793,148 @@ static inline void read_lut_data(struct osi_core_priv_data *const osi_core, } } -static int lut_read_inputs(struct osi_macsec_lut_config *const lut_config, - unsigned int *const lut_data) +static nve32_t lut_read_inputs(struct osi_macsec_lut_config *const lut_config, + nveu32_t *const lut_data) { - struct lut_inputs entry = {0}; - unsigned int flags = 0; + struct osi_lut_inputs entry = {0}; + nveu32_t flags = 0; /* MAC DA */ - if ((lut_data[1] & LUT_DA_BYTE0_INACTIVE) != LUT_DA_BYTE0_INACTIVE) { + if ((lut_data[1] & MACSEC_LUT_DA_BYTE0_INACTIVE) != + MACSEC_LUT_DA_BYTE0_INACTIVE) { entry.da[0] = lut_data[0] & 0xFF; - flags |= LUT_FLAGS_DA_BYTE0_VALID; + flags |= OSI_LUT_FLAGS_DA_BYTE0_VALID; } - if ((lut_data[1] & LUT_DA_BYTE1_INACTIVE) != LUT_DA_BYTE1_INACTIVE) { + if ((lut_data[1] & MACSEC_LUT_DA_BYTE1_INACTIVE) != + MACSEC_LUT_DA_BYTE1_INACTIVE) { entry.da[1] = lut_data[0] >> 8 & 0xFF; - flags |= LUT_FLAGS_DA_BYTE1_VALID; + flags |= OSI_LUT_FLAGS_DA_BYTE1_VALID; } - if ((lut_data[1] & LUT_DA_BYTE2_INACTIVE) != LUT_DA_BYTE2_INACTIVE) { + if ((lut_data[1] & MACSEC_LUT_DA_BYTE2_INACTIVE) != + MACSEC_LUT_DA_BYTE2_INACTIVE) { entry.da[2] = lut_data[0] >> 16 & 0xFF; - flags |= LUT_FLAGS_DA_BYTE2_VALID; + flags |= OSI_LUT_FLAGS_DA_BYTE2_VALID; } - if ((lut_data[1] & LUT_DA_BYTE3_INACTIVE) != LUT_DA_BYTE3_INACTIVE) { + if ((lut_data[1] & MACSEC_LUT_DA_BYTE3_INACTIVE) != + MACSEC_LUT_DA_BYTE3_INACTIVE) { entry.da[3] = lut_data[0] >> 24 & 0xFF; - flags |= LUT_FLAGS_DA_BYTE3_VALID; + flags |= OSI_LUT_FLAGS_DA_BYTE3_VALID; } - if ((lut_data[1] & LUT_DA_BYTE4_INACTIVE) != LUT_DA_BYTE4_INACTIVE) { + if ((lut_data[1] & MACSEC_LUT_DA_BYTE4_INACTIVE) != + MACSEC_LUT_DA_BYTE4_INACTIVE) { entry.da[4] = lut_data[1] & 0xFF; - flags |= LUT_FLAGS_DA_BYTE4_VALID; + flags |= OSI_LUT_FLAGS_DA_BYTE4_VALID; } - if ((lut_data[1] & LUT_DA_BYTE5_INACTIVE) != LUT_DA_BYTE5_INACTIVE) { + if ((lut_data[1] & MACSEC_LUT_DA_BYTE5_INACTIVE) != + MACSEC_LUT_DA_BYTE5_INACTIVE) { entry.da[5] = lut_data[1] >> 8 & 0xFF; - flags |= LUT_FLAGS_DA_BYTE5_VALID; + flags |= OSI_LUT_FLAGS_DA_BYTE5_VALID; } /* MAC SA */ - if ((lut_data[3] & LUT_SA_BYTE0_INACTIVE) != LUT_SA_BYTE0_INACTIVE) { + if ((lut_data[3] & MACSEC_LUT_SA_BYTE0_INACTIVE) != + MACSEC_LUT_SA_BYTE0_INACTIVE) { entry.sa[0] = lut_data[1] >> 22 & 0xFF; - flags |= LUT_FLAGS_SA_BYTE0_VALID; + flags |= OSI_LUT_FLAGS_SA_BYTE0_VALID; } - if ((lut_data[3] & LUT_SA_BYTE1_INACTIVE) != LUT_SA_BYTE1_INACTIVE) { + if ((lut_data[3] & MACSEC_LUT_SA_BYTE1_INACTIVE) != + MACSEC_LUT_SA_BYTE1_INACTIVE) { entry.sa[1] = (lut_data[1] >> 30) | ((lut_data[2] & 0x3F) << 2); - flags |= LUT_FLAGS_SA_BYTE1_VALID; + flags |= OSI_LUT_FLAGS_SA_BYTE1_VALID; } - if ((lut_data[3] & LUT_SA_BYTE2_INACTIVE) != LUT_SA_BYTE2_INACTIVE) { + if ((lut_data[3] & MACSEC_LUT_SA_BYTE2_INACTIVE) != + MACSEC_LUT_SA_BYTE2_INACTIVE) { entry.sa[2] = lut_data[2] >> 6 & 0xFF; - flags |= LUT_FLAGS_SA_BYTE2_VALID; + flags |= OSI_LUT_FLAGS_SA_BYTE2_VALID; } - if ((lut_data[3] & LUT_SA_BYTE3_INACTIVE) != LUT_SA_BYTE3_INACTIVE) { + if ((lut_data[3] & MACSEC_LUT_SA_BYTE3_INACTIVE) != + MACSEC_LUT_SA_BYTE3_INACTIVE) { entry.sa[3] = lut_data[2] >> 14 & 0xFF; - flags |= LUT_FLAGS_SA_BYTE3_VALID; + flags |= OSI_LUT_FLAGS_SA_BYTE3_VALID; } - if ((lut_data[3] & LUT_SA_BYTE4_INACTIVE) != LUT_SA_BYTE4_INACTIVE) { + if ((lut_data[3] & MACSEC_LUT_SA_BYTE4_INACTIVE) != + MACSEC_LUT_SA_BYTE4_INACTIVE) { entry.sa[4] = lut_data[2] >> 22 & 0xFF; - flags |= LUT_FLAGS_SA_BYTE4_VALID; + flags |= OSI_LUT_FLAGS_SA_BYTE4_VALID; } - if ((lut_data[3] & LUT_SA_BYTE5_INACTIVE) != LUT_SA_BYTE5_INACTIVE) { + if ((lut_data[3] & MACSEC_LUT_SA_BYTE5_INACTIVE) != + MACSEC_LUT_SA_BYTE5_INACTIVE) { entry.sa[5] = (lut_data[2] >> 30) | ((lut_data[3] & 0x3F) << 2); - flags |= LUT_FLAGS_SA_BYTE5_VALID; + flags |= OSI_LUT_FLAGS_SA_BYTE5_VALID; } /* Ether type */ - if ((lut_data[3] & LUT_ETHTYPE_INACTIVE) != LUT_ETHTYPE_INACTIVE) { + if ((lut_data[3] & MACSEC_LUT_ETHTYPE_INACTIVE) != + MACSEC_LUT_ETHTYPE_INACTIVE) { entry.ethtype[0] = lut_data[3] >> 12 & 0xFF; entry.ethtype[1] = lut_data[3] >> 20 & 0xFF; - flags |= LUT_FLAGS_ETHTYPE_VALID; + flags |= OSI_LUT_FLAGS_ETHTYPE_VALID; } /* VLAN */ - if ((lut_data[4] & LUT_VLAN_ACTIVE) == LUT_VLAN_ACTIVE) { - flags |= LUT_FLAGS_VLAN_VALID; + if ((lut_data[4] & MACSEC_LUT_VLAN_ACTIVE) == MACSEC_LUT_VLAN_ACTIVE) { + flags |= OSI_LUT_FLAGS_VLAN_VALID; /* VLAN PCP */ - if ((lut_data[4] & LUT_VLAN_PCP_INACTIVE) != - LUT_VLAN_PCP_INACTIVE) { - flags |= LUT_FLAGS_VLAN_PCP_VALID; + 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] >> 29; } /* VLAN ID */ - if ((lut_data[4] & LUT_VLAN_ID_INACTIVE) != - LUT_VLAN_ID_INACTIVE) { - flags |= LUT_FLAGS_VLAN_ID_VALID; + 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 & 0xFFF; } } /* Byte patterns */ - if ((lut_data[4] & LUT_BYTE0_PATTERN_INACTIVE) != - LUT_BYTE0_PATTERN_INACTIVE) { - flags |= LUT_FLAGS_BYTE0_PATTERN_VALID; + 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] = lut_data[4] >> 15 & 0xFF; entry.byte_pattern_offset[0] = lut_data[4] >> 23 & 0x3F; } - if ((lut_data[5] & LUT_BYTE1_PATTERN_INACTIVE) != - LUT_BYTE1_PATTERN_INACTIVE) { - flags |= LUT_FLAGS_BYTE1_PATTERN_VALID; + 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] = (lut_data[4] >> 30) | ((lut_data[5] & 0x3F) << 2); entry.byte_pattern_offset[1] = lut_data[5] >> 6 & 0x3F; } - if ((lut_data[5] & LUT_BYTE2_PATTERN_INACTIVE) != - LUT_BYTE2_PATTERN_INACTIVE) { - flags |= LUT_FLAGS_BYTE2_PATTERN_VALID; + 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] = lut_data[5] >> 13 & 0xFF; entry.byte_pattern_offset[2] = lut_data[5] >> 21 & 0x3F; } - if ((lut_data[6] & LUT_BYTE3_PATTERN_INACTIVE) != - LUT_BYTE3_PATTERN_INACTIVE) { - flags |= LUT_FLAGS_BYTE3_PATTERN_VALID; + 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] = (lut_data[5] >> 28) | ((lut_data[6] & 0xF) << 4); entry.byte_pattern_offset[3] = lut_data[6] >> 4 & 0x3F; } /* Preempt mask */ - if ((lut_data[6] & LUT_PREEMPT_INACTIVE) != LUT_PREEMPT_INACTIVE) { - flags |= LUT_FLAGS_PREEMPT_VALID; - if ((lut_data[6] & LUT_PREEMPT) == LUT_PREEMPT) { - flags |= LUT_FLAGS_PREEMPT; + 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; } } @@ -923,50 +944,54 @@ static int lut_read_inputs(struct osi_macsec_lut_config *const lut_config, return 0; } -static int byp_lut_read(struct osi_core_priv_data *const osi_core, +static nve32_t byp_lut_read(struct osi_core_priv_data *const osi_core, struct osi_macsec_lut_config *const lut_config) { - unsigned int lut_data[MACSEC_LUT_DATA_REG_CNT] = {0}; - unsigned int flags = 0, val = 0; - unsigned int index = lut_config->table_config.index; - unsigned char *addr = (unsigned char *)osi_core->macsec_base; - unsigned char *paddr = OSI_NULL; + 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; read_lut_data(osi_core, lut_data); if (lut_read_inputs(lut_config, lut_data) != 0) { - pr_err("LUT inputs error\n"); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "LUT inputs error\n", 0ULL); return -1; } /* Lookup output */ - if ((lut_data[6] & LUT_CONTROLLED_PORT) == LUT_CONTROLLED_PORT) { - flags |= LUT_FLAGS_CONTROLLED_PORT; + if ((lut_data[6] & MACSEC_LUT_CONTROLLED_PORT) == + MACSEC_LUT_CONTROLLED_PORT) { + flags |= OSI_LUT_FLAGS_CONTROLLED_PORT; } - if ((lut_data[6] & BYP_LUT_DVLAN_PKT) == BYP_LUT_DVLAN_PKT) { - flags |= LUT_FLAGS_DVLAN_PKT; + 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 |= LUT_FLAGS_DVLAN_OUTER_INNER_TAG_SEL; + flags |= OSI_LUT_FLAGS_DVLAN_OUTER_INNER_TAG_SEL; } switch (lut_config->table_config.ctlr_sel) { - case CTLR_SEL_TX: - paddr = addr+TX_BYP_LUT_VALID; + case OSI_CTLR_SEL_TX: + paddr = addr + MACSEC_TX_BYP_LUT_VALID; break; - case CTLR_SEL_RX: - paddr = addr+RX_BYP_LUT_VALID; + case OSI_CTLR_SEL_RX: + paddr = addr + MACSEC_RX_BYP_LUT_VALID; break; default: - pr_err("Unknown controller select\n"); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Unknown controller select\n", 0ULL); return -1; } val = osi_readla(osi_core, paddr); if (val & (1U << index)) { - flags |= LUT_FLAGS_ENTRY_VALID; + flags |= OSI_LUT_FLAGS_ENTRY_VALID; } lut_config->flags |= flags; @@ -974,57 +999,62 @@ static int byp_lut_read(struct osi_core_priv_data *const osi_core, return 0; } -static int sci_lut_read(struct osi_core_priv_data *const osi_core, +static nve32_t sci_lut_read(struct osi_core_priv_data *const osi_core, struct osi_macsec_lut_config *const lut_config) { - unsigned int lut_data[MACSEC_LUT_DATA_REG_CNT] = {0}; - unsigned int flags = 0; - unsigned char *addr = (unsigned char *)osi_core->macsec_base; - unsigned int val = 0; - unsigned int index = lut_config->table_config.index; + 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; - if (index > SC_LUT_MAX_INDEX) { + if (index > OSI_SC_LUT_MAX_INDEX) { return -1; } read_lut_data(osi_core, lut_data); switch (lut_config->table_config.ctlr_sel) { - case CTLR_SEL_TX: + case OSI_CTLR_SEL_TX: if (lut_read_inputs(lut_config, lut_data) != 0) { - pr_err("LUT inputs error\n"); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "LUT inputs error\n", 0ULL); return -1; } - if ((lut_data[6] & LUT_AN0_VALID) == LUT_AN0_VALID) { - lut_config->sci_lut_out.an_valid |= AN0_VALID; + 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] & LUT_AN1_VALID) == LUT_AN1_VALID) { - lut_config->sci_lut_out.an_valid |= AN1_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] & LUT_AN2_VALID) == LUT_AN2_VALID) { - lut_config->sci_lut_out.an_valid |= AN2_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] & LUT_AN3_VALID) == LUT_AN3_VALID) { - lut_config->sci_lut_out.an_valid |= AN3_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 & 0xF; - if ((lut_data[6] & TX_SCI_LUT_DVLAN_PKT) == - TX_SCI_LUT_DVLAN_PKT) { - lut_config->flags |= LUT_FLAGS_DVLAN_PKT; + 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] & TX_SCI_LUT_DVLAN_OUTER_INNER_TAG_SEL) == - TX_SCI_LUT_DVLAN_OUTER_INNER_TAG_SEL) { + 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 |= - LUT_FLAGS_DVLAN_OUTER_INNER_TAG_SEL; + OSI_LUT_FLAGS_DVLAN_OUTER_INNER_TAG_SEL; } - val = osi_readla(osi_core, addr+TX_SCI_LUT_VALID); + val = osi_readla(osi_core, addr+MACSEC_TX_SCI_LUT_VALID); if (val & (1U << index)) { - lut_config->flags |= LUT_FLAGS_ENTRY_VALID; + lut_config->flags |= OSI_LUT_FLAGS_ENTRY_VALID; } break; - case CTLR_SEL_RX: + case OSI_CTLR_SEL_RX: lut_config->sci_lut_out.sci[0] = lut_data[0] & 0xFF; lut_config->sci_lut_out.sci[1] = lut_data[0] >> 8 & 0xFF; lut_config->sci_lut_out.sci[2] = lut_data[0] >> 16 & 0xFF; @@ -1035,22 +1065,23 @@ static int sci_lut_read(struct osi_core_priv_data *const osi_core, lut_config->sci_lut_out.sci[7] = lut_data[1] >> 24 & 0xFF; lut_config->sci_lut_out.sc_index = lut_data[2] >> 10 & 0xF; - if ((lut_data[2] & RX_SCI_LUT_PREEMPT_INACTIVE) != - RX_SCI_LUT_PREEMPT_INACTIVE) { - flags |= LUT_FLAGS_PREEMPT_VALID; - if ((lut_data[2] & RX_SCI_LUT_PREEMPT) == - RX_SCI_LUT_PREEMPT) { - flags |= LUT_FLAGS_PREEMPT; + 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+RX_SCI_LUT_VALID); + val = osi_readla(osi_core, addr+MACSEC_RX_SCI_LUT_VALID); if (val & (1U << index)) { - lut_config->flags |= LUT_FLAGS_ENTRY_VALID; + lut_config->flags |= OSI_LUT_FLAGS_ENTRY_VALID; } break; default: - pr_err("Unknown controller selected\n"); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Unknown controller selected\n", 0ULL); return -1; } @@ -1058,15 +1089,15 @@ static int sci_lut_read(struct osi_core_priv_data *const osi_core, return 0; } -static int sc_param_lut_read(struct osi_core_priv_data *const osi_core, +static nve32_t sc_param_lut_read(struct osi_core_priv_data *const osi_core, struct osi_macsec_lut_config *const lut_config) { - unsigned int lut_data[MACSEC_LUT_DATA_REG_CNT] = {0}; + nveu32_t lut_data[MACSEC_LUT_DATA_REG_CNT] = {0}; read_lut_data(osi_core, lut_data); switch (lut_config->table_config.ctlr_sel) { - case CTLR_SEL_TX: + case OSI_CTLR_SEL_TX: lut_config->sc_param_out.key_index_start = lut_data[0] & 0x1F; lut_config->sc_param_out.pn_max = (lut_data[0] >> 5) | (lut_data[1] << 27); @@ -1084,7 +1115,7 @@ static int sc_param_lut_read(struct osi_core_priv_data *const osi_core, lut_config->sc_param_out.vlan_in_clear = (lut_data[4] >> 8) & 0x1; break; - case CTLR_SEL_RX: + case OSI_CTLR_SEL_RX: lut_config->sc_param_out.key_index_start = lut_data[0] & 0x1F; lut_config->sc_param_out.pn_window = (lut_data[0] >> 5) | (lut_data[1] << 27); @@ -1092,7 +1123,8 @@ static int sc_param_lut_read(struct osi_core_priv_data *const osi_core, (lut_data[2] << 27); break; default: - pr_err("Unknown controller selected\n"); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Unknown controller selected\n", 0ULL); return -1; } @@ -1100,10 +1132,10 @@ static int sc_param_lut_read(struct osi_core_priv_data *const osi_core, return 0; } -static int sc_state_lut_read(struct osi_core_priv_data *const osi_core, +static nve32_t sc_state_lut_read(struct osi_core_priv_data *const osi_core, struct osi_macsec_lut_config *const lut_config) { - unsigned int lut_data[MACSEC_LUT_DATA_REG_CNT] = {0}; + 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]; @@ -1111,27 +1143,28 @@ static int sc_state_lut_read(struct osi_core_priv_data *const osi_core, return 0; } -static int sa_state_lut_read(struct osi_core_priv_data *const osi_core, +static nve32_t sa_state_lut_read(struct osi_core_priv_data *const osi_core, struct osi_macsec_lut_config *const lut_config) { - unsigned int lut_data[MACSEC_LUT_DATA_REG_CNT] = {0}; + nveu32_t lut_data[MACSEC_LUT_DATA_REG_CNT] = {0}; read_lut_data(osi_core, lut_data); switch (lut_config->table_config.ctlr_sel) { - case CTLR_SEL_TX: + case OSI_CTLR_SEL_TX: lut_config->sa_state_out.next_pn = lut_data[0]; - if ((lut_data[1] & SA_STATE_LUT_ENTRY_VALID) == - SA_STATE_LUT_ENTRY_VALID) { - lut_config->flags |= LUT_FLAGS_ENTRY_VALID; + 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 CTLR_SEL_RX: + 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: - pr_err("Unknown controller selected\n"); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Unknown controller selected\n", 0ULL); return -1; } @@ -1139,42 +1172,49 @@ static int sa_state_lut_read(struct osi_core_priv_data *const osi_core, return 0; } -static int lut_data_read(struct osi_core_priv_data *const osi_core, +static nve32_t lut_data_read(struct osi_core_priv_data *const osi_core, struct osi_macsec_lut_config *const lut_config) { switch (lut_config->lut_sel) { - case LUT_SEL_BYPASS: + case OSI_LUT_SEL_BYPASS: if (byp_lut_read(osi_core, lut_config) != 0) { - pr_err("BYP LUT read err\n"); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "BYP LUT read err\n", 0ULL); return -1; } break; - case LUT_SEL_SCI: + case OSI_LUT_SEL_SCI: if (sci_lut_read(osi_core, lut_config) != 0) { - pr_err("SCI LUT read err\n"); + pr_err("\n"); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "SCI LUT read err\n", 0ULL); return -1; } break; - case LUT_SEL_SC_PARAM: + case OSI_LUT_SEL_SC_PARAM: if (sc_param_lut_read(osi_core, lut_config) != 0) { - pr_err("SC param LUT read err\n"); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "SC param LUT read err\n", 0ULL); return -1; } break; - case LUT_SEL_SC_STATE: + case OSI_LUT_SEL_SC_STATE: if (sc_state_lut_read(osi_core, lut_config) != 0) { - pr_err("SC state LUT read err\n"); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "SC state LUT read err\n", 0ULL); return -1; } break; - case LUT_SEL_SA_STATE: + case OSI_LUT_SEL_SA_STATE: if (sa_state_lut_read(osi_core, lut_config) != 0) { - pr_err("SA state LUT read err\n"); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "SA state LUT read err\n", 0ULL); return -1; } break; default: - //Unsupported LUT + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Unsupported LUT\n", 0ULL); return -1; } @@ -1182,10 +1222,10 @@ static int lut_data_read(struct osi_core_priv_data *const osi_core, } static inline void commit_lut_data(struct osi_core_priv_data *const osi_core, - unsigned int const *const lut_data) + nveu32_t const *const lut_data) { - unsigned char *base = (unsigned char *)osi_core->macsec_base; - int i; + nveu8_t *base = (nveu8_t *)osi_core->macsec_base; + nve32_t i; /* Commit the LUT entry to HW */ for (i = 0; i < MACSEC_LUT_DATA_REG_CNT; i++) { @@ -1196,9 +1236,9 @@ static inline void commit_lut_data(struct osi_core_priv_data *const osi_core, static void rx_sa_state_lut_config( struct osi_macsec_lut_config *const lut_config, - unsigned int *const lut_data) + nveu32_t *const lut_data) { - struct sa_state_outputs entry = lut_config->sa_state_out; + struct osi_sa_state_outputs entry = lut_config->sa_state_out; lut_data[0] |= entry.next_pn; lut_data[1] |= entry.lowest_pn; @@ -1206,29 +1246,29 @@ static void rx_sa_state_lut_config( static void tx_sa_state_lut_config( struct osi_macsec_lut_config *const lut_config, - unsigned int *const lut_data) + nveu32_t *const lut_data) { - unsigned int flags = lut_config->flags; - struct sa_state_outputs entry = lut_config->sa_state_out; + 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 & LUT_FLAGS_ENTRY_VALID) == LUT_FLAGS_ENTRY_VALID) { - lut_data[1] |= SA_STATE_LUT_ENTRY_VALID; + if ((flags & OSI_LUT_FLAGS_ENTRY_VALID) == OSI_LUT_FLAGS_ENTRY_VALID) { + lut_data[1] |= MACSEC_SA_STATE_LUT_ENTRY_VALID; } } -static int sa_state_lut_config(struct osi_core_priv_data *const osi_core, +static nve32_t sa_state_lut_config(struct osi_core_priv_data *const osi_core, struct osi_macsec_lut_config *const lut_config) { - unsigned int lut_data[MACSEC_LUT_DATA_REG_CNT] = {0}; - struct macsec_table_config table_config = lut_config->table_config; + nveu32_t lut_data[MACSEC_LUT_DATA_REG_CNT] = {0}; + struct osi_macsec_table_config table_config = lut_config->table_config; switch (table_config.ctlr_sel) { - case CTLR_SEL_TX: + case OSI_CTLR_SEL_TX: tx_sa_state_lut_config(lut_config, lut_data); break; - case CTLR_SEL_RX: + case OSI_CTLR_SEL_RX: rx_sa_state_lut_config(lut_config, lut_data); break; default: @@ -1240,11 +1280,11 @@ static int sa_state_lut_config(struct osi_core_priv_data *const osi_core, return 0; } -static int sc_state_lut_config(struct osi_core_priv_data *const osi_core, +static nve32_t sc_state_lut_config(struct osi_core_priv_data *const osi_core, struct osi_macsec_lut_config *const lut_config) { - unsigned int lut_data[MACSEC_LUT_DATA_REG_CNT] = {0}; - struct sc_state_outputs entry = lut_config->sc_state_out; + 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); @@ -1254,9 +1294,9 @@ static int sc_state_lut_config(struct osi_core_priv_data *const osi_core, static void rx_sc_param_lut_config( struct osi_macsec_lut_config *const lut_config, - unsigned int *const lut_data) + nveu32_t *const lut_data) { - struct sc_param_outputs entry = lut_config->sc_param_out; + 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; @@ -1267,9 +1307,9 @@ static void rx_sc_param_lut_config( static void tx_sc_param_lut_config( struct osi_macsec_lut_config *const lut_config, - unsigned int *const lut_data) + nveu32_t *const lut_data) { - struct sc_param_outputs entry = lut_config->sc_param_out; + 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; @@ -1288,22 +1328,22 @@ static void tx_sc_param_lut_config( lut_data[4] |= entry.vlan_in_clear << 8; } -static int sc_param_lut_config(struct osi_core_priv_data *const osi_core, +static nve32_t sc_param_lut_config(struct osi_core_priv_data *const osi_core, struct osi_macsec_lut_config *const lut_config) { - unsigned int lut_data[MACSEC_LUT_DATA_REG_CNT] = {0}; - struct macsec_table_config table_config = lut_config->table_config; - struct sc_param_outputs entry = lut_config->sc_param_out; + 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; - if (entry.key_index_start > KEY_INDEX_MAX) { + if (entry.key_index_start > OSI_KEY_INDEX_MAX) { return -1; } switch (table_config.ctlr_sel) { - case CTLR_SEL_TX: + case OSI_CTLR_SEL_TX: tx_sc_param_lut_config(lut_config, lut_data); break; - case CTLR_SEL_RX: + case OSI_CTLR_SEL_RX: rx_sc_param_lut_config(lut_config, lut_data); break; } @@ -1313,215 +1353,236 @@ static int sc_param_lut_config(struct osi_core_priv_data *const osi_core, return 0; } -static int lut_config_inputs(struct osi_macsec_lut_config *const lut_config, - unsigned int *const lut_data) +static nve32_t lut_config_inputs(struct osi_macsec_lut_config *const lut_config, + nveu32_t *const lut_data) { - struct lut_inputs entry = lut_config->lut_in; - unsigned int flags; - int i; + struct osi_lut_inputs entry = lut_config->lut_in; + nveu32_t flags = lut_config->flags; + nve32_t i, j; - for (i = 0; i < LUT_BYTE_PATTERN_MAX; i++) { - if (entry.byte_pattern_offset[i] > - LUT_BYTE_PATTERN_MAX_OFFSET) { + for (i = 0, j = OSI_LUT_FLAGS_BYTE0_PATTERN_VALID; + i < OSI_LUT_BYTE_PATTERN_MAX; i++, j <<= 1) { + if ((flags & j) == j) { + if (entry.byte_pattern_offset[i] > + OSI_LUT_BYTE_PATTERN_MAX_OFFSET) { + return -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 ((entry.vlan_pcp > VLAN_PCP_MAX) || - (entry.vlan_id > VLAN_ID_MAX)) { - 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; + } } - /* TODO - validate if LUT_FLAGS_VLAN_VALID is incorrectly set - * when LUT_FLAGS_VLAN_PCP_VALID/VLAN_ID_VALID is not set. - */ - - /* TODO - validate if Byte pattern and byte pattern are both provided */ - - flags = lut_config->flags; /* MAC DA */ - if ((flags & LUT_FLAGS_DA_BYTE0_VALID) == LUT_FLAGS_DA_BYTE0_VALID) { + if ((flags & OSI_LUT_FLAGS_DA_BYTE0_VALID) == + OSI_LUT_FLAGS_DA_BYTE0_VALID) { lut_data[0] |= entry.da[0]; - lut_data[1] &= ~LUT_DA_BYTE0_INACTIVE; + lut_data[1] &= ~MACSEC_LUT_DA_BYTE0_INACTIVE; } else { - lut_data[1] |= LUT_DA_BYTE0_INACTIVE; + lut_data[1] |= MACSEC_LUT_DA_BYTE0_INACTIVE; } - if ((flags & LUT_FLAGS_DA_BYTE1_VALID) == LUT_FLAGS_DA_BYTE1_VALID) { + if ((flags & OSI_LUT_FLAGS_DA_BYTE1_VALID) == + OSI_LUT_FLAGS_DA_BYTE1_VALID) { lut_data[0] |= entry.da[1] << 8; - lut_data[1] &= ~LUT_DA_BYTE1_INACTIVE; + lut_data[1] &= ~MACSEC_LUT_DA_BYTE1_INACTIVE; } else { - lut_data[1] |= LUT_DA_BYTE1_INACTIVE; + lut_data[1] |= MACSEC_LUT_DA_BYTE1_INACTIVE; } - if ((flags & LUT_FLAGS_DA_BYTE2_VALID) == LUT_FLAGS_DA_BYTE2_VALID) { + if ((flags & OSI_LUT_FLAGS_DA_BYTE2_VALID) == + OSI_LUT_FLAGS_DA_BYTE2_VALID) { lut_data[0] |= entry.da[2] << 16; - lut_data[1] &= ~LUT_DA_BYTE2_INACTIVE; + lut_data[1] &= ~MACSEC_LUT_DA_BYTE2_INACTIVE; } else { - lut_data[1] |= LUT_DA_BYTE2_INACTIVE; + lut_data[1] |= MACSEC_LUT_DA_BYTE2_INACTIVE; } - if ((flags & LUT_FLAGS_DA_BYTE3_VALID) == LUT_FLAGS_DA_BYTE3_VALID) { + if ((flags & OSI_LUT_FLAGS_DA_BYTE3_VALID) == + OSI_LUT_FLAGS_DA_BYTE3_VALID) { lut_data[0] |= entry.da[3] << 24; - lut_data[1] &= ~LUT_DA_BYTE3_INACTIVE; + lut_data[1] &= ~MACSEC_LUT_DA_BYTE3_INACTIVE; } else { - lut_data[1] |= LUT_DA_BYTE3_INACTIVE; + lut_data[1] |= MACSEC_LUT_DA_BYTE3_INACTIVE; } - if ((flags & LUT_FLAGS_DA_BYTE4_VALID) == LUT_FLAGS_DA_BYTE4_VALID) { + if ((flags & OSI_LUT_FLAGS_DA_BYTE4_VALID) == + OSI_LUT_FLAGS_DA_BYTE4_VALID) { lut_data[1] |= entry.da[4]; - lut_data[1] &= ~LUT_DA_BYTE4_INACTIVE; + lut_data[1] &= ~MACSEC_LUT_DA_BYTE4_INACTIVE; } else { - lut_data[1] |= LUT_DA_BYTE4_INACTIVE; + lut_data[1] |= MACSEC_LUT_DA_BYTE4_INACTIVE; } - if ((flags & LUT_FLAGS_DA_BYTE5_VALID) == LUT_FLAGS_DA_BYTE5_VALID) { + if ((flags & OSI_LUT_FLAGS_DA_BYTE5_VALID) == + OSI_LUT_FLAGS_DA_BYTE5_VALID) { lut_data[1] |= entry.da[5] << 8; - lut_data[1] &= ~LUT_DA_BYTE5_INACTIVE; + lut_data[1] &= ~MACSEC_LUT_DA_BYTE5_INACTIVE; } else { - lut_data[1] |= LUT_DA_BYTE5_INACTIVE; + lut_data[1] |= MACSEC_LUT_DA_BYTE5_INACTIVE; } /* MAC SA */ - if ((flags & LUT_FLAGS_SA_BYTE0_VALID) == LUT_FLAGS_SA_BYTE0_VALID) { + if ((flags & OSI_LUT_FLAGS_SA_BYTE0_VALID) == + OSI_LUT_FLAGS_SA_BYTE0_VALID) { lut_data[1] |= entry.sa[0] << 22; - lut_data[3] &= ~LUT_SA_BYTE0_INACTIVE; + lut_data[3] &= ~MACSEC_LUT_SA_BYTE0_INACTIVE; } else { - lut_data[3] |= LUT_SA_BYTE0_INACTIVE; + lut_data[3] |= MACSEC_LUT_SA_BYTE0_INACTIVE; } - if ((flags & LUT_FLAGS_SA_BYTE1_VALID) == LUT_FLAGS_SA_BYTE1_VALID) { + if ((flags & OSI_LUT_FLAGS_SA_BYTE1_VALID) == + OSI_LUT_FLAGS_SA_BYTE1_VALID) { lut_data[1] |= entry.sa[1] << 30; lut_data[2] |= (entry.sa[1] >> 2); - lut_data[3] &= ~LUT_SA_BYTE1_INACTIVE; + lut_data[3] &= ~MACSEC_LUT_SA_BYTE1_INACTIVE; } else { - lut_data[3] |= LUT_SA_BYTE1_INACTIVE; + lut_data[3] |= MACSEC_LUT_SA_BYTE1_INACTIVE; } - if ((flags & LUT_FLAGS_SA_BYTE2_VALID) == LUT_FLAGS_SA_BYTE2_VALID) { + if ((flags & OSI_LUT_FLAGS_SA_BYTE2_VALID) == + OSI_LUT_FLAGS_SA_BYTE2_VALID) { lut_data[2] |= entry.sa[2] << 6; - lut_data[3] &= ~LUT_SA_BYTE2_INACTIVE; + lut_data[3] &= ~MACSEC_LUT_SA_BYTE2_INACTIVE; } else { - lut_data[3] |= LUT_SA_BYTE2_INACTIVE; + lut_data[3] |= MACSEC_LUT_SA_BYTE2_INACTIVE; } - if ((flags & LUT_FLAGS_SA_BYTE3_VALID) == LUT_FLAGS_SA_BYTE3_VALID) { + if ((flags & OSI_LUT_FLAGS_SA_BYTE3_VALID) == + OSI_LUT_FLAGS_SA_BYTE3_VALID) { lut_data[2] |= entry.sa[3] << 14; - lut_data[3] &= ~LUT_SA_BYTE3_INACTIVE; + lut_data[3] &= ~MACSEC_LUT_SA_BYTE3_INACTIVE; } else { - lut_data[3] |= LUT_SA_BYTE3_INACTIVE; + lut_data[3] |= MACSEC_LUT_SA_BYTE3_INACTIVE; } - if ((flags & LUT_FLAGS_SA_BYTE4_VALID) == LUT_FLAGS_SA_BYTE4_VALID) { + if ((flags & OSI_LUT_FLAGS_SA_BYTE4_VALID) == + OSI_LUT_FLAGS_SA_BYTE4_VALID) { lut_data[2] |= entry.sa[4] << 22; - lut_data[3] &= ~LUT_SA_BYTE4_INACTIVE; + lut_data[3] &= ~MACSEC_LUT_SA_BYTE4_INACTIVE; } else { - lut_data[3] |= LUT_SA_BYTE4_INACTIVE; + lut_data[3] |= MACSEC_LUT_SA_BYTE4_INACTIVE; } - if ((flags & LUT_FLAGS_SA_BYTE5_VALID) == LUT_FLAGS_SA_BYTE5_VALID) { + if ((flags & OSI_LUT_FLAGS_SA_BYTE5_VALID) == + OSI_LUT_FLAGS_SA_BYTE5_VALID) { lut_data[2] |= entry.sa[5] << 30; lut_data[3] |= (entry.sa[5] >> 2); - lut_data[3] &= ~LUT_SA_BYTE5_INACTIVE; + lut_data[3] &= ~MACSEC_LUT_SA_BYTE5_INACTIVE; } else { - lut_data[3] |= LUT_SA_BYTE5_INACTIVE; + lut_data[3] |= MACSEC_LUT_SA_BYTE5_INACTIVE; } /* Ether type */ - if ((flags & LUT_FLAGS_ETHTYPE_VALID) == LUT_FLAGS_ETHTYPE_VALID) { + if ((flags & OSI_LUT_FLAGS_ETHTYPE_VALID) == + OSI_LUT_FLAGS_ETHTYPE_VALID) { lut_data[3] |= entry.ethtype[0] << 12; lut_data[3] |= entry.ethtype[1] << 20; - lut_data[3] &= ~LUT_ETHTYPE_INACTIVE; + lut_data[3] &= ~MACSEC_LUT_ETHTYPE_INACTIVE; } else { - lut_data[3] |= LUT_ETHTYPE_INACTIVE; + lut_data[3] |= MACSEC_LUT_ETHTYPE_INACTIVE; } /* VLAN */ - if ((flags & LUT_FLAGS_VLAN_VALID) == LUT_FLAGS_VLAN_VALID) { + if ((flags & OSI_LUT_FLAGS_VLAN_VALID) == OSI_LUT_FLAGS_VLAN_VALID) { /* VLAN PCP */ - if ((flags & LUT_FLAGS_VLAN_PCP_VALID) == - LUT_FLAGS_VLAN_PCP_VALID) { + if ((flags & OSI_LUT_FLAGS_VLAN_PCP_VALID) == + OSI_LUT_FLAGS_VLAN_PCP_VALID) { lut_data[3] |= entry.vlan_pcp << 29; - lut_data[4] &= ~LUT_VLAN_PCP_INACTIVE; + lut_data[4] &= ~MACSEC_LUT_VLAN_PCP_INACTIVE; } else { - lut_data[4] |= LUT_VLAN_PCP_INACTIVE; + lut_data[4] |= MACSEC_LUT_VLAN_PCP_INACTIVE; } /* VLAN ID */ - if ((flags & LUT_FLAGS_VLAN_ID_VALID) == - LUT_FLAGS_VLAN_ID_VALID) { + if ((flags & OSI_LUT_FLAGS_VLAN_ID_VALID) == + OSI_LUT_FLAGS_VLAN_ID_VALID) { lut_data[4] |= entry.vlan_id << 1; - lut_data[4] &= ~LUT_VLAN_ID_INACTIVE; + lut_data[4] &= ~MACSEC_LUT_VLAN_ID_INACTIVE; } else { - lut_data[4] |= LUT_VLAN_ID_INACTIVE; + lut_data[4] |= MACSEC_LUT_VLAN_ID_INACTIVE; } - lut_data[4] |= LUT_VLAN_ACTIVE; + lut_data[4] |= MACSEC_LUT_VLAN_ACTIVE; } else { - lut_data[4] |= LUT_VLAN_PCP_INACTIVE; - lut_data[4] |= LUT_VLAN_ID_INACTIVE; - lut_data[4] &= ~LUT_VLAN_ACTIVE; + lut_data[4] |= MACSEC_LUT_VLAN_PCP_INACTIVE; + lut_data[4] |= MACSEC_LUT_VLAN_ID_INACTIVE; + lut_data[4] &= ~MACSEC_LUT_VLAN_ACTIVE; } /* Byte patterns */ - if ((flags & LUT_FLAGS_BYTE0_PATTERN_VALID) == - LUT_FLAGS_BYTE0_PATTERN_VALID) { + if ((flags & OSI_LUT_FLAGS_BYTE0_PATTERN_VALID) == + OSI_LUT_FLAGS_BYTE0_PATTERN_VALID) { lut_data[4] |= entry.byte_pattern[0] << 15; lut_data[4] |= entry.byte_pattern_offset[0] << 23; - lut_data[4] &= ~LUT_BYTE0_PATTERN_INACTIVE; + lut_data[4] &= ~MACSEC_LUT_BYTE0_PATTERN_INACTIVE; } else { - lut_data[4] |= LUT_BYTE0_PATTERN_INACTIVE; + lut_data[4] |= MACSEC_LUT_BYTE0_PATTERN_INACTIVE; } - if ((flags & LUT_FLAGS_BYTE1_PATTERN_VALID) == - LUT_FLAGS_BYTE1_PATTERN_VALID) { + if ((flags & OSI_LUT_FLAGS_BYTE1_PATTERN_VALID) == + OSI_LUT_FLAGS_BYTE1_PATTERN_VALID) { lut_data[4] |= entry.byte_pattern[1] << 30; lut_data[5] |= entry.byte_pattern[1] >> 2; lut_data[5] |= entry.byte_pattern_offset[1] << 6; - lut_data[5] &= ~LUT_BYTE1_PATTERN_INACTIVE; + lut_data[5] &= ~MACSEC_LUT_BYTE1_PATTERN_INACTIVE; } else { - lut_data[5] |= LUT_BYTE1_PATTERN_INACTIVE; + lut_data[5] |= MACSEC_LUT_BYTE1_PATTERN_INACTIVE; } - if ((flags & LUT_FLAGS_BYTE2_PATTERN_VALID) == - LUT_FLAGS_BYTE2_PATTERN_VALID) { + if ((flags & OSI_LUT_FLAGS_BYTE2_PATTERN_VALID) == + OSI_LUT_FLAGS_BYTE2_PATTERN_VALID) { lut_data[5] |= entry.byte_pattern[2] << 13; lut_data[5] |= entry.byte_pattern_offset[2] << 21; - lut_data[5] &= ~LUT_BYTE2_PATTERN_INACTIVE; + lut_data[5] &= ~MACSEC_LUT_BYTE2_PATTERN_INACTIVE; } else { - lut_data[5] |= LUT_BYTE2_PATTERN_INACTIVE; + lut_data[5] |= MACSEC_LUT_BYTE2_PATTERN_INACTIVE; } - if ((flags & LUT_FLAGS_BYTE3_PATTERN_VALID) == - LUT_FLAGS_BYTE3_PATTERN_VALID) { + if ((flags & OSI_LUT_FLAGS_BYTE3_PATTERN_VALID) == + OSI_LUT_FLAGS_BYTE3_PATTERN_VALID) { lut_data[5] |= entry.byte_pattern[3] << 28; lut_data[6] |= entry.byte_pattern[3] >> 4; lut_data[6] |= entry.byte_pattern_offset[3] << 4; - lut_data[6] &= ~LUT_BYTE3_PATTERN_INACTIVE; + lut_data[6] &= ~MACSEC_LUT_BYTE3_PATTERN_INACTIVE; } else { - lut_data[6] |= LUT_BYTE3_PATTERN_INACTIVE; + lut_data[6] |= MACSEC_LUT_BYTE3_PATTERN_INACTIVE; } /* Preempt mask */ - if ((flags & LUT_FLAGS_PREEMPT_VALID) == LUT_FLAGS_PREEMPT_VALID) { - if ((flags & LUT_FLAGS_PREEMPT) == LUT_FLAGS_PREEMPT) { - lut_data[6] |= LUT_PREEMPT; + 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] &= ~LUT_PREEMPT; + lut_data[6] &= ~MACSEC_LUT_PREEMPT; } - lut_data[6] &= ~LUT_PREEMPT_INACTIVE; + lut_data[6] &= ~MACSEC_LUT_PREEMPT_INACTIVE; } else { - lut_data[6] |= LUT_PREEMPT_INACTIVE; + lut_data[6] |= MACSEC_LUT_PREEMPT_INACTIVE; } return 0; } -static int rx_sci_lut_config(struct osi_macsec_lut_config *const lut_config, - unsigned int *const lut_data) +static nve32_t rx_sci_lut_config( + struct osi_macsec_lut_config *const lut_config, + nveu32_t *const lut_data) { - unsigned int flags = lut_config->flags; - struct sci_lut_outputs entry = lut_config->sci_lut_out; + nveu32_t flags = lut_config->flags; + struct osi_sci_lut_outputs entry = lut_config->sci_lut_out; - if (entry.sc_index > SC_INDEX_MAX) { + if (entry.sc_index > OSI_SC_INDEX_MAX) { return -1; } @@ -1535,15 +1596,16 @@ static int rx_sci_lut_config(struct osi_macsec_lut_config *const lut_config, (entry.sci[7] << 24)); /* Preempt mask */ - if ((flags & LUT_FLAGS_PREEMPT_VALID) == LUT_FLAGS_PREEMPT_VALID) { - if ((flags & LUT_FLAGS_PREEMPT) == LUT_FLAGS_PREEMPT) { - lut_data[2] |= RX_SCI_LUT_PREEMPT; + 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] &= ~RX_SCI_LUT_PREEMPT; + lut_data[2] &= ~MACSEC_RX_SCI_LUT_PREEMPT; } - lut_data[2] &= ~RX_SCI_LUT_PREEMPT_INACTIVE; + lut_data[2] &= ~MACSEC_RX_SCI_LUT_PREEMPT_INACTIVE; } else { - lut_data[2] |= RX_SCI_LUT_PREEMPT_INACTIVE; + lut_data[2] |= MACSEC_RX_SCI_LUT_PREEMPT_INACTIVE; } lut_data[2] |= entry.sc_index << 10; @@ -1551,233 +1613,258 @@ static int rx_sci_lut_config(struct osi_macsec_lut_config *const lut_config, return 0; } -static int tx_sci_lut_config(struct osi_macsec_lut_config *const lut_config, - unsigned int *const lut_data) +static nve32_t tx_sci_lut_config( + struct osi_macsec_lut_config *const lut_config, + nveu32_t *const lut_data) { - unsigned int flags = lut_config->flags; - struct sci_lut_outputs entry = lut_config->sci_lut_out; - unsigned int an_valid = entry.an_valid; + 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) { - pr_err("LUT inputs error\n"); return -1; } /* Lookup result fields */ - if ((an_valid & AN0_VALID) == AN0_VALID) { - lut_data[6] |= LUT_AN0_VALID; + if ((an_valid & OSI_AN0_VALID) == OSI_AN0_VALID) { + lut_data[6] |= MACSEC_LUT_AN0_VALID; } - if ((an_valid & AN1_VALID) == AN1_VALID) { - lut_data[6] |= LUT_AN1_VALID; + if ((an_valid & OSI_AN1_VALID) == OSI_AN1_VALID) { + lut_data[6] |= MACSEC_LUT_AN1_VALID; } - if ((an_valid & AN2_VALID) == AN2_VALID) { - lut_data[6] |= LUT_AN2_VALID; + if ((an_valid & OSI_AN2_VALID) == OSI_AN2_VALID) { + lut_data[6] |= MACSEC_LUT_AN2_VALID; } - if ((an_valid & AN3_VALID) == AN3_VALID) { - lut_data[6] |= LUT_AN3_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 & LUT_FLAGS_DVLAN_PKT) == LUT_FLAGS_DVLAN_PKT) { - lut_data[6] |= TX_SCI_LUT_DVLAN_PKT; + if ((flags & OSI_LUT_FLAGS_DVLAN_PKT) == OSI_LUT_FLAGS_DVLAN_PKT) { + lut_data[6] |= MACSEC_TX_SCI_LUT_DVLAN_PKT; } - if ((flags & LUT_FLAGS_DVLAN_OUTER_INNER_TAG_SEL) == - LUT_FLAGS_DVLAN_OUTER_INNER_TAG_SEL) { - lut_data[6] |= TX_SCI_LUT_DVLAN_OUTER_INNER_TAG_SEL; + 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; } -static int sci_lut_config(struct osi_core_priv_data *const osi_core, +static nve32_t sci_lut_config(struct osi_core_priv_data *const osi_core, struct osi_macsec_lut_config *const lut_config) { - unsigned int lut_data[MACSEC_LUT_DATA_REG_CNT] = {0}; - struct macsec_table_config table_config = lut_config->table_config; - struct sci_lut_outputs entry = lut_config->sci_lut_out; - unsigned char *addr = (unsigned char *)osi_core->macsec_base; - unsigned int val = 0; - unsigned int index = lut_config->table_config.index; + 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; - if ((entry.sc_index > SC_INDEX_MAX) || - (lut_config->table_config.index > SC_LUT_MAX_INDEX)) { + if ((entry.sc_index > OSI_SC_INDEX_MAX) || + (lut_config->table_config.index > OSI_SC_LUT_MAX_INDEX)) { return -1; } switch (table_config.ctlr_sel) { - case CTLR_SEL_TX: + case OSI_CTLR_SEL_TX: if (tx_sci_lut_config(lut_config, lut_data) < 0) { - pr_err("Failed to config tx sci LUT\n"); + 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 & LUT_FLAGS_ENTRY_VALID) == - LUT_FLAGS_ENTRY_VALID) { - val = osi_readla(osi_core, addr+TX_SCI_LUT_VALID); + 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 |= (1 << index); - osi_writela(osi_core, val, addr+TX_SCI_LUT_VALID); + osi_writela(osi_core, val, addr + + MACSEC_TX_SCI_LUT_VALID); } else { - val = osi_readla(osi_core, addr+TX_SCI_LUT_VALID); + val = osi_readla(osi_core, addr + + MACSEC_TX_SCI_LUT_VALID); val &= ~(1 << index); - osi_writela(osi_core, val, addr+TX_SCI_LUT_VALID); + osi_writela(osi_core, val, addr + + MACSEC_TX_SCI_LUT_VALID); } break; - case CTLR_SEL_RX: + case OSI_CTLR_SEL_RX: if (rx_sci_lut_config(lut_config, lut_data) < 0) { - pr_err("Failed to config rx sci LUT\n"); + 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 & LUT_FLAGS_ENTRY_VALID) == - LUT_FLAGS_ENTRY_VALID) { - val = osi_readla(osi_core, addr+RX_SCI_LUT_VALID); + 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 |= (1 << index); - osi_writela(osi_core, val, addr+RX_SCI_LUT_VALID); + osi_writela(osi_core, val, addr + + MACSEC_RX_SCI_LUT_VALID); } else { - val = osi_readla(osi_core, addr+RX_SCI_LUT_VALID); + val = osi_readla(osi_core, addr + + MACSEC_RX_SCI_LUT_VALID); val &= ~(1 << index); - osi_writela(osi_core, val, addr+RX_SCI_LUT_VALID); + osi_writela(osi_core, val, addr + + MACSEC_RX_SCI_LUT_VALID); } break; default: - pr_err("Unknown controller select\n"); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Unknown controller select\n", 0ULL); return -1; } return 0; } -static int byp_lut_config(struct osi_core_priv_data *const osi_core, +static nve32_t byp_lut_config(struct osi_core_priv_data *const osi_core, struct osi_macsec_lut_config *const lut_config) { - unsigned int lut_data[MACSEC_LUT_DATA_REG_CNT] = {0}; - unsigned int flags = lut_config->flags; - unsigned char *addr = (unsigned char *)osi_core->macsec_base; - unsigned int val = 0; - unsigned int index = lut_config->table_config.index; + 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; if (lut_config_inputs(lut_config, lut_data) != 0) { - pr_err("LUT inputs error\n"); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "LUT inputs error\n", 0ULL); return -1; } /* Lookup output */ - if ((flags & LUT_FLAGS_CONTROLLED_PORT) == - LUT_FLAGS_CONTROLLED_PORT) { - lut_data[6] |= LUT_CONTROLLED_PORT; + if ((flags & OSI_LUT_FLAGS_CONTROLLED_PORT) == + OSI_LUT_FLAGS_CONTROLLED_PORT) { + lut_data[6] |= MACSEC_LUT_CONTROLLED_PORT; } - if ((flags & LUT_FLAGS_DVLAN_PKT) == LUT_FLAGS_DVLAN_PKT) { - lut_data[6] |= BYP_LUT_DVLAN_PKT; + if ((flags & OSI_LUT_FLAGS_DVLAN_PKT) == OSI_LUT_FLAGS_DVLAN_PKT) { + lut_data[6] |= MACSEC_BYP_LUT_DVLAN_PKT; } - if ((flags & LUT_FLAGS_DVLAN_OUTER_INNER_TAG_SEL) == - LUT_FLAGS_DVLAN_OUTER_INNER_TAG_SEL) { + 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 CTLR_SEL_TX: - if ((flags & LUT_FLAGS_ENTRY_VALID) == - LUT_FLAGS_ENTRY_VALID) { - val = osi_readla(osi_core, addr+TX_BYP_LUT_VALID); + 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 |= (1 << index); - osi_writela(osi_core, val, addr+TX_BYP_LUT_VALID); + osi_writela(osi_core, val, addr + + MACSEC_TX_BYP_LUT_VALID); } else { - val = osi_readla(osi_core, addr+TX_BYP_LUT_VALID); + val = osi_readla(osi_core, addr + + MACSEC_TX_BYP_LUT_VALID); val &= ~(1 << index); - osi_writela(osi_core, val, addr+TX_BYP_LUT_VALID); + osi_writela(osi_core, val, addr + + MACSEC_TX_BYP_LUT_VALID); } break; - case CTLR_SEL_RX: - if ((flags & LUT_FLAGS_ENTRY_VALID) == - LUT_FLAGS_ENTRY_VALID) { - val = osi_readla(osi_core, addr+RX_BYP_LUT_VALID); + 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 |= (1 << index); - osi_writela(osi_core, val, addr+RX_BYP_LUT_VALID); + osi_writela(osi_core, val, addr + + MACSEC_RX_BYP_LUT_VALID); } else { - val = osi_readla(osi_core, addr+RX_BYP_LUT_VALID); + val = osi_readla(osi_core, addr + + MACSEC_RX_BYP_LUT_VALID); val &= ~(1 << index); - osi_writela(osi_core, val, addr+RX_BYP_LUT_VALID); + osi_writela(osi_core, val, addr + + MACSEC_RX_BYP_LUT_VALID); } break; default: - pr_err("Unknown controller select\n"); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Unknown controller select\n", 0ULL); return -1; } return 0; } -static inline int lut_data_write(struct osi_core_priv_data *const osi_core, - struct osi_macsec_lut_config *const lut_config) +static inline nve32_t lut_data_write(struct osi_core_priv_data *const osi_core, + struct osi_macsec_lut_config *const lut_config) { switch (lut_config->lut_sel) { - case LUT_SEL_BYPASS: + case OSI_LUT_SEL_BYPASS: if (byp_lut_config(osi_core, lut_config) != 0) { - pr_err("BYP LUT config err\n"); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "BYP LUT config err\n", 0ULL); return -1; } break; - case LUT_SEL_SCI: + case OSI_LUT_SEL_SCI: if (sci_lut_config(osi_core, lut_config) != 0) { - pr_err("SCI LUT config err\n"); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "SCI LUT config err\n", 0ULL); return -1; } break; - case LUT_SEL_SC_PARAM: + case OSI_LUT_SEL_SC_PARAM: if (sc_param_lut_config(osi_core, lut_config) != 0) { - pr_err("SC param LUT config err\n"); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "SC param LUT config err\n", 0ULL); return -1; } break; - case LUT_SEL_SC_STATE: + case OSI_LUT_SEL_SC_STATE: if (sc_state_lut_config(osi_core, lut_config) != 0) { - pr_err("SC state LUT config err\n"); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "SC state LUT config err\n", 0ULL); return -1; } break; - case LUT_SEL_SA_STATE: + case OSI_LUT_SEL_SA_STATE: if (sa_state_lut_config(osi_core, lut_config) != 0) { - pr_err("SA state LUT config err\n"); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "SA state LUT config err\n", 0ULL); return -1; } break; default: - //Unsupported LUT + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Unsupported LUT\n", 0ULL); return -1; } return 0; } -static int macsec_lut_config(struct osi_core_priv_data *const osi_core, +static nve32_t macsec_lut_config(struct osi_core_priv_data *const osi_core, struct osi_macsec_lut_config *const lut_config) { - int ret = 0; - unsigned int lut_config_reg; - unsigned char *base = (unsigned char *)osi_core->macsec_base; + nve32_t ret = 0; + nveu32_t lut_config_reg; + nveu8_t *base = (nveu8_t *)osi_core->macsec_base; /* Validate LUT config */ - if ((lut_config->table_config.ctlr_sel > CTLR_SEL_MAX) || - (lut_config->table_config.rw > RW_MAX) || - (lut_config->table_config.index > TABLE_INDEX_MAX) || - (lut_config->lut_sel > LUT_SEL_MAX)) { + 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)) { pr_err("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); - /* TODO - validate using a local cache - * if index is already active */ return -1; } @@ -1790,33 +1877,35 @@ static int macsec_lut_config(struct osi_core_priv_data *const osi_core, /* pr_err("%s: LUT: %hu ctrl: %hu rw: %hu idx: %hu flags: %#x\n", __func__, lut_config->lut_sel, lut_config->table_config.ctlr_sel, lut_config->table_config.rw, lut_config->table_config.index, - lut_config->flags); */ + lut_config->flags); +*/ lut_config_reg = osi_readla(osi_core, base + MACSEC_LUT_CONFIG); if (lut_config->table_config.ctlr_sel) { - lut_config_reg |= LUT_CONFIG_CTLR_SEL; + lut_config_reg |= MACSEC_LUT_CONFIG_CTLR_SEL; } else { - lut_config_reg &= ~LUT_CONFIG_CTLR_SEL; + lut_config_reg &= ~MACSEC_LUT_CONFIG_CTLR_SEL; } if (lut_config->table_config.rw) { - lut_config_reg |= LUT_CONFIG_RW; + 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 &= ~LUT_CONFIG_RW; + lut_config_reg &= ~MACSEC_LUT_CONFIG_RW; } - lut_config_reg &= ~LUT_CONFIG_LUT_SEL_MASK; - lut_config_reg |= (lut_config->lut_sel << LUT_CONFIG_LUT_SEL_SHIFT); + lut_config_reg &= ~MACSEC_LUT_CONFIG_LUT_SEL_MASK; + lut_config_reg |= (lut_config->lut_sel << + MACSEC_LUT_CONFIG_LUT_SEL_SHIFT); - lut_config_reg &= ~LUT_CONFIG_INDEX_MASK; + lut_config_reg &= ~MACSEC_LUT_CONFIG_INDEX_MASK; lut_config_reg |= (lut_config->table_config.index); - lut_config_reg |= LUT_CONFIG_UPDATE; + 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 */ @@ -1838,35 +1927,35 @@ static int macsec_lut_config(struct osi_core_priv_data *const osi_core, static inline void handle_rx_sc_invalid_key( struct osi_core_priv_data *const osi_core) { - unsigned char *addr = (unsigned char *)osi_core->macsec_base; - unsigned int clear = 0; + nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; + nveu32_t clear = 0; pr_err("%s()\n", __func__); /** check which SC/AN had triggered and clear */ /* rx_sc0_7 */ - clear = osi_readla(osi_core, addr + RX_SC_KEY_INVALID_STS0_0); - osi_writela(osi_core, clear, addr + RX_SC_KEY_INVALID_STS0_0); + 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 + RX_SC_KEY_INVALID_STS1_0); - osi_writela(osi_core, clear, addr + RX_SC_KEY_INVALID_STS1_0); + 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); } static inline void handle_tx_sc_invalid_key( struct osi_core_priv_data *const osi_core) { - unsigned char *addr = (unsigned char *)osi_core->macsec_base; - unsigned int clear = 0; + nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; + nveu32_t clear = 0; pr_err("%s()\n", __func__); /** check which SC/AN had triggered and clear */ /* tx_sc0_7 */ - clear = osi_readla(osi_core, addr + TX_SC_KEY_INVALID_STS0_0); - osi_writela(osi_core, clear, addr + TX_SC_KEY_INVALID_STS0_0); + 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 + TX_SC_KEY_INVALID_STS1_0); - osi_writela(osi_core, clear, addr + TX_SC_KEY_INVALID_STS1_0); + 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); } static inline void handle_safety_err_irq( @@ -1878,284 +1967,295 @@ static inline void handle_safety_err_irq( static inline void handle_rx_sc_replay_err( struct osi_core_priv_data *const osi_core) { - unsigned char *addr = (unsigned char *)osi_core->macsec_base; - unsigned int clear = 0; + nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; + nveu32_t clear = 0; /* pr_err("%s()\n", __func__); */ /* rx_sc0_7 */ - clear = osi_readla(osi_core, addr + RX_SC_REPLAY_ERROR_STATUS0_0); - osi_writela(osi_core, clear, addr + RX_SC_REPLAY_ERROR_STATUS0_0); + 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 + RX_SC_REPLAY_ERROR_STATUS1_0); - osi_writela(osi_core, clear, addr + RX_SC_REPLAY_ERROR_STATUS1_0); + 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); } static inline void handle_rx_pn_exhausted( struct osi_core_priv_data *const osi_core) { - unsigned char *addr = (unsigned char *)osi_core->macsec_base; - unsigned int clear = 0; + nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; + nveu32_t clear = 0; /* pr_err("%s()\n", __func__); */ - /* TODO: Do you need re-enable SC/AN? */ - - /* check which SC/AN had triggered and clear - */ + /* Check which SC/AN had triggered and clear */ /* rx_sc0_7 */ - clear = osi_readla(osi_core, addr + RX_SC_PN_EXHAUSTED_STATUS0_0); - osi_writela(osi_core, clear, addr + RX_SC_PN_EXHAUSTED_STATUS0_0); + 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 + RX_SC_PN_EXHAUSTED_STATUS1_0); - osi_writela(osi_core, clear, addr + RX_SC_PN_EXHAUSTED_STATUS1_0); + 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); } static inline void handle_tx_sc_err(struct osi_core_priv_data *const osi_core) { - unsigned char *addr = (unsigned char *)osi_core->macsec_base; - unsigned int clear = 0; + nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; + nveu32_t clear = 0; /* pr_err("%s()\n", __func__); */ - - /* TODO: Do you need re-enable SC/AN? */ - - clear = osi_readla(osi_core, addr + TX_SC_ERROR_INTERRUPT_STATUS_0); - - osi_writela(osi_core, clear, addr + TX_SC_ERROR_INTERRUPT_STATUS_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); } static inline void handle_tx_pn_threshold( struct osi_core_priv_data *const osi_core) { - unsigned char *addr = (unsigned char *)osi_core->macsec_base; - unsigned int clear = 0; + nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; + nveu32_t clear = 0; /* pr_err("%s()\n", __func__); */ - /* TODO: Do you need re-enable SC/AN? */ - - /* check which SC/AN had triggered and clear - */ + /* check which SC/AN had triggered and clear */ /* tx_sc0_7 */ - clear = osi_readla(osi_core, addr + TX_SC_PN_THRESHOLD_STATUS0_0); - osi_writela(osi_core, clear, addr + TX_SC_PN_THRESHOLD_STATUS0_0); + 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 + TX_SC_PN_THRESHOLD_STATUS1_0); - osi_writela(osi_core, clear, addr + TX_SC_PN_THRESHOLD_STATUS1_0); + 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); } static inline void handle_tx_pn_exhausted( struct osi_core_priv_data *const osi_core) { - unsigned char *addr = (unsigned char *)osi_core->macsec_base; - unsigned int clear = 0; + nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; + nveu32_t clear = 0; /* pr_err("%s()\n", __func__); */ - /* TODO: Do you need re-enable SC/AN? */ - - /* check which SC/AN had triggered and clear - */ + /* check which SC/AN had triggered and clear */ /* tx_sc0_7 */ - clear = osi_readla(osi_core, addr + TX_SC_PN_EXHAUSTED_STATUS0_0); - osi_writela(osi_core, clear, addr + TX_SC_PN_EXHAUSTED_STATUS0_0); + 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 + TX_SC_PN_EXHAUSTED_STATUS1_0); - osi_writela(osi_core, clear, addr + TX_SC_PN_EXHAUSTED_STATUS1_0); + 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); } static inline void handle_dbg_evt_capture_done( struct osi_core_priv_data *const osi_core, - unsigned short ctrl_sel) + nveu16_t ctrl_sel) { - unsigned char *addr = (unsigned char *)osi_core->macsec_base; - unsigned int trigger_evts = 0; + nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; + nveu32_t trigger_evts = 0; - if (ctrl_sel == CTLR_SEL_TX) { - trigger_evts = osi_readla(osi_core, addr + TX_DEBUG_STATUS_0); - pr_err("%s: TX_DEBUG_STATUS_0 0x%x", __func__, trigger_evts); - osi_writela(osi_core, trigger_evts, addr + TX_DEBUG_STATUS_0); + if (ctrl_sel == OSI_CTLR_SEL_TX) { + trigger_evts = osi_readla(osi_core, addr + + MACSEC_TX_DEBUG_STATUS_0); + pr_err("%s: MACSEC_TX_DEBUG_STATUS_0 0x%x", __func__, trigger_evts); + 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 + TX_DEBUG_TRIGGER_EN_0); - } else if (ctrl_sel == CTLR_SEL_RX) { - trigger_evts = osi_readla(osi_core, addr + RX_DEBUG_STATUS_0); - pr_err("%s: RX_DEBUG_STATUS_0 0x%x", __func__, trigger_evts); - osi_writela(osi_core, trigger_evts, addr + RX_DEBUG_STATUS_0); + 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); + pr_err("%s: MACSEC_RX_DEBUG_STATUS_0 0x%x", __func__, trigger_evts); + 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 + RX_DEBUG_TRIGGER_EN_0); + addr + MACSEC_RX_DEBUG_TRIGGER_EN_0); } } static inline void handle_tx_irq(struct osi_core_priv_data *const osi_core) { - unsigned int tx_isr, clear = 0; - unsigned char *addr = (unsigned char *)osi_core->macsec_base; + nveu32_t tx_isr, clear = 0; + nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; - tx_isr = osi_readla(osi_core, addr + TX_ISR); + tx_isr = osi_readla(osi_core, addr + MACSEC_TX_ISR); pr_err("%s(): tx_isr 0x%x\n", __func__, tx_isr); - if ((tx_isr & TX_DBG_BUF_CAPTURE_DONE) == TX_DBG_BUF_CAPTURE_DONE) { - handle_dbg_evt_capture_done(osi_core, CTLR_SEL_TX); + 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); osi_core->macsec_irq_stats.tx_dbg_capture_done++; - clear |= TX_DBG_BUF_CAPTURE_DONE; + clear |= MACSEC_TX_DBG_BUF_CAPTURE_DONE; } - if ((tx_isr & TX_MTU_CHECK_FAIL) == TX_MTU_CHECK_FAIL) { + if ((tx_isr & MACSEC_TX_MTU_CHECK_FAIL) == MACSEC_TX_MTU_CHECK_FAIL) { osi_core->macsec_irq_stats.tx_mtu_check_fail++; - clear |= TX_MTU_CHECK_FAIL; + clear |= MACSEC_TX_MTU_CHECK_FAIL; } - if ((tx_isr & TX_AES_GCM_BUF_OVF) == TX_AES_GCM_BUF_OVF) { + if ((tx_isr & MACSEC_TX_AES_GCM_BUF_OVF) == MACSEC_TX_AES_GCM_BUF_OVF) { osi_core->macsec_irq_stats.tx_aes_gcm_buf_ovf++; - clear |= TX_AES_GCM_BUF_OVF; + clear |= MACSEC_TX_AES_GCM_BUF_OVF; } - if ((tx_isr & TX_SC_AN_NOT_VALID) == TX_SC_AN_NOT_VALID) { + if ((tx_isr & MACSEC_TX_SC_AN_NOT_VALID) == MACSEC_TX_SC_AN_NOT_VALID) { osi_core->macsec_irq_stats.tx_sc_an_not_valid++; handle_tx_sc_err(osi_core); - clear |= TX_SC_AN_NOT_VALID; + clear |= MACSEC_TX_SC_AN_NOT_VALID; } - if ((tx_isr & TX_MAC_CRC_ERROR) == TX_MAC_CRC_ERROR) { + if ((tx_isr & MACSEC_TX_MAC_CRC_ERROR) == MACSEC_TX_MAC_CRC_ERROR) { osi_core->macsec_irq_stats.tx_mac_crc_error++; - clear |= TX_MAC_CRC_ERROR; + clear |= MACSEC_TX_MAC_CRC_ERROR; } - if ((tx_isr & TX_PN_THRSHLD_RCHD) == TX_PN_THRSHLD_RCHD) { + if ((tx_isr & MACSEC_TX_PN_THRSHLD_RCHD) == MACSEC_TX_PN_THRSHLD_RCHD) { osi_core->macsec_irq_stats.tx_pn_threshold++; - /* TODO - need to check which SC/AN had triggered */ handle_tx_pn_threshold(osi_core); - clear |= TX_PN_THRSHLD_RCHD; + clear |= MACSEC_TX_PN_THRSHLD_RCHD; } - if ((tx_isr & TX_PN_EXHAUSTED) == TX_PN_EXHAUSTED) { + if ((tx_isr & MACSEC_TX_PN_EXHAUSTED) == MACSEC_TX_PN_EXHAUSTED) { osi_core->macsec_irq_stats.tx_pn_exhausted++; - /* TODO - need to check which SC/AN had triggered */ handle_tx_pn_exhausted(osi_core); - clear |= TX_PN_EXHAUSTED; + clear |= MACSEC_TX_PN_EXHAUSTED; } if (clear) { pr_err("%s(): write tx_isr 0x%x\n", __func__, clear); - osi_writela(osi_core, clear, addr + TX_ISR); + osi_writela(osi_core, clear, addr + MACSEC_TX_ISR); } } static inline void handle_rx_irq(struct osi_core_priv_data *const osi_core) { - unsigned int rx_isr, clear = 0; - unsigned char *addr = (unsigned char *)osi_core->macsec_base; + nveu32_t rx_isr, clear = 0; + nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; - rx_isr = osi_readla(osi_core, addr + RX_ISR); + rx_isr = osi_readla(osi_core, addr + MACSEC_RX_ISR); pr_err("%s(): rx_isr 0x%x\n", __func__, rx_isr); - if ((rx_isr & RX_DBG_BUF_CAPTURE_DONE) == RX_DBG_BUF_CAPTURE_DONE) { - handle_dbg_evt_capture_done(osi_core, CTLR_SEL_RX); + 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); osi_core->macsec_irq_stats.rx_dbg_capture_done++; - clear |= RX_DBG_BUF_CAPTURE_DONE; + clear |= MACSEC_RX_DBG_BUF_CAPTURE_DONE; } - if ((rx_isr & RX_ICV_ERROR) == RX_ICV_ERROR) { + if ((rx_isr & MACSEC_RX_ICV_ERROR) == MACSEC_RX_ICV_ERROR) { osi_core->macsec_irq_stats.rx_icv_err_threshold++; - clear |= RX_ICV_ERROR; + clear |= MACSEC_RX_ICV_ERROR; } - if ((rx_isr & RX_REPLAY_ERROR) == RX_REPLAY_ERROR) { + if ((rx_isr & MACSEC_RX_REPLAY_ERROR) == MACSEC_RX_REPLAY_ERROR) { osi_core->macsec_irq_stats.rx_replay_error++; handle_rx_sc_replay_err(osi_core); - clear |= RX_REPLAY_ERROR; + clear |= MACSEC_RX_REPLAY_ERROR; } - if ((rx_isr & RX_MTU_CHECK_FAIL) == RX_MTU_CHECK_FAIL) { + if ((rx_isr & MACSEC_RX_MTU_CHECK_FAIL) == MACSEC_RX_MTU_CHECK_FAIL) { osi_core->macsec_irq_stats.rx_mtu_check_fail++; - clear |= RX_MTU_CHECK_FAIL; + clear |= MACSEC_RX_MTU_CHECK_FAIL; } - if ((rx_isr & RX_AES_GCM_BUF_OVF) == RX_AES_GCM_BUF_OVF) { + if ((rx_isr & MACSEC_RX_AES_GCM_BUF_OVF) == MACSEC_RX_AES_GCM_BUF_OVF) { osi_core->macsec_irq_stats.rx_aes_gcm_buf_ovf++; - clear |= RX_AES_GCM_BUF_OVF; + clear |= MACSEC_RX_AES_GCM_BUF_OVF; } - if ((rx_isr & RX_MAC_CRC_ERROR) == RX_MAC_CRC_ERROR) { + if ((rx_isr & MACSEC_RX_MAC_CRC_ERROR) == MACSEC_RX_MAC_CRC_ERROR) { osi_core->macsec_irq_stats.rx_mac_crc_error++; - clear |= RX_MAC_CRC_ERROR; + clear |= MACSEC_RX_MAC_CRC_ERROR; } - if ((rx_isr & RX_PN_EXHAUSTED) == RX_PN_EXHAUSTED) { + if ((rx_isr & MACSEC_RX_PN_EXHAUSTED) == MACSEC_RX_PN_EXHAUSTED) { osi_core->macsec_irq_stats.rx_pn_exhausted++; - /* TODO - need to check which SC/AN had triggered */ handle_rx_pn_exhausted(osi_core); - clear |= RX_PN_EXHAUSTED; + clear |= MACSEC_RX_PN_EXHAUSTED; } if (clear) { pr_err("%s(): write rx_isr 0x%x\n", __func__, clear); - osi_writela(osi_core, clear, addr + RX_ISR); + osi_writela(osi_core, clear, addr + MACSEC_RX_ISR); } } static inline void handle_common_irq(struct osi_core_priv_data *const osi_core) { - unsigned int common_isr, clear = 0; - unsigned char *addr = (unsigned char *)osi_core->macsec_base; + nveu32_t common_isr, clear = 0; + nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; - common_isr = osi_readla(osi_core, addr + COMMON_ISR); + common_isr = osi_readla(osi_core, addr + MACSEC_COMMON_ISR); pr_err("%s(): common_isr 0x%x\n", __func__, common_isr); - if ((common_isr & SECURE_REG_VIOL) == SECURE_REG_VIOL) { + if ((common_isr & MACSEC_SECURE_REG_VIOL) == MACSEC_SECURE_REG_VIOL) { osi_core->macsec_irq_stats.secure_reg_viol++; - clear |= SECURE_REG_VIOL; + clear |= MACSEC_SECURE_REG_VIOL; } - if ((common_isr & RX_UNINIT_KEY_SLOT) == RX_UNINIT_KEY_SLOT) { + if ((common_isr & MACSEC_RX_UNINIT_KEY_SLOT) == + MACSEC_RX_UNINIT_KEY_SLOT) { osi_core->macsec_irq_stats.rx_uninit_key_slot++; - clear |= RX_UNINIT_KEY_SLOT; + clear |= MACSEC_RX_UNINIT_KEY_SLOT; handle_rx_sc_invalid_key(osi_core); } - if ((common_isr & RX_LKUP_MISS) == RX_LKUP_MISS) { + if ((common_isr & MACSEC_RX_LKUP_MISS) == MACSEC_RX_LKUP_MISS) { osi_core->macsec_irq_stats.rx_lkup_miss++; - clear |= RX_LKUP_MISS; + clear |= MACSEC_RX_LKUP_MISS; } - if ((common_isr & TX_UNINIT_KEY_SLOT) == TX_UNINIT_KEY_SLOT) { + if ((common_isr & MACSEC_TX_UNINIT_KEY_SLOT) == + MACSEC_TX_UNINIT_KEY_SLOT) { osi_core->macsec_irq_stats.tx_uninit_key_slot++; - clear |= TX_UNINIT_KEY_SLOT; + clear |= MACSEC_TX_UNINIT_KEY_SLOT; handle_tx_sc_invalid_key(osi_core); } - if ((common_isr & TX_LKUP_MISS) == TX_LKUP_MISS) { + if ((common_isr & MACSEC_TX_LKUP_MISS) == MACSEC_TX_LKUP_MISS) { osi_core->macsec_irq_stats.tx_lkup_miss++; - clear |= TX_LKUP_MISS; + clear |= MACSEC_TX_LKUP_MISS; } if (clear) { - osi_writela(osi_core, clear, addr + COMMON_ISR); + osi_writela(osi_core, clear, addr + MACSEC_COMMON_ISR); } } static void macsec_handle_ns_irq(struct osi_core_priv_data *const osi_core) { - unsigned int irq_common_sr, common_isr; - unsigned char *addr = (unsigned char *)osi_core->macsec_base; + nveu32_t irq_common_sr, common_isr; + nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; - irq_common_sr = osi_readla(osi_core, addr + INTERRUPT_COMMON_SR); + irq_common_sr = osi_readla(osi_core, addr + MACSEC_INTERRUPT_COMMON_SR); pr_err("%s(): common_sr 0x%x\n", __func__, irq_common_sr); - if ((irq_common_sr & COMMON_SR_TX) == COMMON_SR_TX) { + if ((irq_common_sr & MACSEC_COMMON_SR_TX) == MACSEC_COMMON_SR_TX) { handle_tx_irq(osi_core); } - if ((irq_common_sr & COMMON_SR_RX) == COMMON_SR_RX) { + if ((irq_common_sr & MACSEC_COMMON_SR_RX) == MACSEC_COMMON_SR_RX) { handle_rx_irq(osi_core); } - if ((irq_common_sr & COMMON_SR_SFTY_ERR) == COMMON_SR_SFTY_ERR) { + 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 + COMMON_ISR); + common_isr = osi_readla(osi_core, addr + MACSEC_COMMON_ISR); if (common_isr != OSI_NONE) { handle_common_irq(osi_core); } @@ -2163,12 +2263,12 @@ static void macsec_handle_ns_irq(struct osi_core_priv_data *const osi_core) static void macsec_handle_s_irq(struct osi_core_priv_data *const osi_core) { - unsigned int common_isr; - unsigned char *addr = (unsigned char *)osi_core->macsec_base; + nveu32_t common_isr; + nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; pr_err("%s()\n", __func__); - common_isr = osi_readla(osi_core, addr + COMMON_ISR); + common_isr = osi_readla(osi_core, addr + MACSEC_COMMON_ISR); if (common_isr != OSI_NONE) { handle_common_irq(osi_core); } @@ -2176,45 +2276,46 @@ static void macsec_handle_s_irq(struct osi_core_priv_data *const osi_core) return; } -static int macsec_cipher_config(struct osi_core_priv_data *const osi_core, - unsigned int cipher) +static nve32_t macsec_cipher_config(struct osi_core_priv_data *const osi_core, + nveu32_t cipher) { - unsigned char *base = (unsigned char *)osi_core->macsec_base; - unsigned int val; + nveu8_t *base = (nveu8_t *)osi_core->macsec_base; + nveu32_t val; - val = osi_readla(osi_core, base + GCM_AES_CONTROL_0); - pr_err("Read GCM_AES_CONTROL_0: 0x%x\n", val); + val = osi_readla(osi_core, base + MACSEC_GCM_AES_CONTROL_0); + pr_err("Read MACSEC_GCM_AES_CONTROL_0: 0x%x\n", val); - val &= ~TX_AES_MODE_MASK; - val &= ~RX_AES_MODE_MASK; - if (cipher == MACSEC_CIPHER_AES128) { - val |= TX_AES_MODE_AES128; - val |= RX_AES_MODE_AES128; - } else if (cipher == MACSEC_CIPHER_AES256) { - val |= TX_AES_MODE_AES256; - val |= RX_AES_MODE_AES256; + 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; } - pr_err("Write GCM_AES_CONTROL_0: 0x%x\n", val); - osi_writela(osi_core, val, base + GCM_AES_CONTROL_0); + pr_err("Write MACSEC_GCM_AES_CONTROL_0: 0x%x\n", val); + osi_writela(osi_core, val, base + MACSEC_GCM_AES_CONTROL_0); return 0; } -static int macsec_loopback_config(struct osi_core_priv_data *const osi_core, - unsigned int enable) +static nve32_t macsec_loopback_config( + struct osi_core_priv_data *const osi_core, + nveu32_t enable) { - unsigned char *base = (unsigned char *)osi_core->macsec_base; - unsigned int val; + nveu8_t *base = (nveu8_t *)osi_core->macsec_base; + nveu32_t val; val = osi_readla(osi_core, base + MACSEC_CONTROL1); pr_err("Read MACSEC_CONTROL1: 0x%x\n", val); if (enable == OSI_ENABLE) { - val |= LOOPBACK_MODE_EN; + val |= MACSEC_LOOPBACK_MODE_EN; } else if (enable == OSI_DISABLE) { - val &= ~LOOPBACK_MODE_EN; + val &= ~MACSEC_LOOPBACK_MODE_EN; } else { return -1; } @@ -2224,24 +2325,24 @@ static int macsec_loopback_config(struct osi_core_priv_data *const osi_core, return 0; } -static int clear_lut(struct osi_core_priv_data *const osi_core) +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}; #endif - struct macsec_table_config *table_config = &lut_config.table_config; - int i, j; - int ret = 0; + struct osi_macsec_table_config *table_config = &lut_config.table_config; + nveu32_t i, j; + nve32_t ret = 0; - table_config->rw = LUT_WRITE; + table_config->rw = OSI_LUT_WRITE; /* Clear all the LUT's which have a dedicated LUT valid bit per entry */ /* Tx/Rx BYP LUT */ - lut_config.lut_sel = LUT_SEL_BYPASS; - for (i = 0; i <= CTLR_SEL_MAX; i++) { + 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 <= BYP_LUT_MAX_INDEX; j++) { + 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) { @@ -2253,10 +2354,10 @@ static int clear_lut(struct osi_core_priv_data *const osi_core) } /* Tx/Rx SCI LUT */ - lut_config.lut_sel = LUT_SEL_SCI; - for (i = 0; i <= CTLR_SEL_MAX; i++) { + 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 <= SC_LUT_MAX_INDEX; j++) { + 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) { @@ -2268,10 +2369,10 @@ static int clear_lut(struct osi_core_priv_data *const osi_core) } /* Tx/Rx SC param LUT */ - lut_config.lut_sel = LUT_SEL_SC_PARAM; - for (i = 0; i <= CTLR_SEL_MAX; i++) { + 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 <= SC_LUT_MAX_INDEX; j++) { + 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) { @@ -2283,10 +2384,10 @@ static int clear_lut(struct osi_core_priv_data *const osi_core) } /* Tx/Rx SC state */ - lut_config.lut_sel = LUT_SEL_SC_STATE; - for (i = 0; i <= CTLR_SEL_MAX; i++) { + 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 <= SC_LUT_MAX_INDEX; j++) { + 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) { @@ -2298,9 +2399,9 @@ static int clear_lut(struct osi_core_priv_data *const osi_core) } /* Tx SA state LUT */ - lut_config.lut_sel = LUT_SEL_SA_STATE; - table_config->ctlr_sel = CTLR_SEL_TX; - for (j = 0; j <= SA_LUT_MAX_INDEX; j++) { + 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) { @@ -2311,9 +2412,9 @@ static int clear_lut(struct osi_core_priv_data *const osi_core) } /* Rx SA state LUT */ - lut_config.lut_sel = LUT_SEL_SA_STATE; - table_config->ctlr_sel = CTLR_SEL_RX; - for (j = 0; j <= SA_LUT_MAX_INDEX; j++) { + 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) { @@ -2326,10 +2427,10 @@ static int clear_lut(struct osi_core_priv_data *const osi_core) #ifdef MACSEC_KEY_PROGRAM /* Key table */ table_config = &kt_config.table_config; - table_config->rw = LUT_WRITE; - for (i = 0; i <= CTLR_SEL_MAX; i++) { + table_config->rw = OSI_LUT_WRITE; + for (i = 0; i <= OSI_CTLR_SEL_MAX; i++) { table_config->ctlr_sel = i; - for (j = 0; j <= TABLE_INDEX_MAX; j++) { + for (j = 0; j <= OSI_TABLE_INDEX_MAX; j++) { table_config->index = j; ret = macsec_kt_config(osi_core, &kt_config); if (ret < 0) { @@ -2344,128 +2445,136 @@ static int clear_lut(struct osi_core_priv_data *const osi_core) return ret; } -static int macsec_deinit(struct osi_core_priv_data *const osi_core) +static nve32_t macsec_deinit(struct osi_core_priv_data *const osi_core) { - int i; + nveu32_t i; - for (i = CTLR_SEL_TX; i <= CTLR_SEL_RX; i++) { + 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)); } return 0; } -static int macsec_init(struct osi_core_priv_data *const osi_core) +static nve32_t macsec_init(struct osi_core_priv_data *const osi_core) { - unsigned int val = 0; + nveu32_t val = 0; struct osi_macsec_lut_config lut_config = {0}; - struct macsec_table_config *table_config = &lut_config.table_config; + struct osi_macsec_table_config *table_config = &lut_config.table_config; /* Store MAC address in reverse, per HW design */ - unsigned char mac_da_mkpdu[OSI_ETH_ALEN] = {0x3, 0x0, 0x0, - 0xC2, 0x80, 0x01}; - unsigned char mac_da_bc[OSI_ETH_ALEN] = {0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF}; - unsigned int mtu = osi_core->mtu + MACSEC_TAG_ICV_LEN; - unsigned char *addr = (unsigned char *)osi_core->macsec_base; - int ret = 0; - int i, j; + nveu8_t mac_da_mkpdu[OSI_ETH_ALEN] = {0x3, 0x0, 0x0, + 0xC2, 0x80, 0x01}; + nveu8_t mac_da_bc[OSI_ETH_ALEN] = {0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF}; + nveu32_t mtu = osi_core->mtu + MACSEC_TAG_ICV_LEN; + nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; + nve32_t ret = 0; + nveu16_t i, j; /* 1. Set MTU */ - val = osi_readla(osi_core, addr + TX_MTU_LEN); - pr_err("Read TX_MTU_LEN: 0x%x\n", val); + val = osi_readla(osi_core, addr + MACSEC_TX_MTU_LEN); + pr_err("Read MACSEC_TX_MTU_LEN: 0x%x\n", val); val &= ~(MTU_LENGTH_MASK); val |= (mtu & MTU_LENGTH_MASK); - pr_err("Write TX_MTU_LEN: 0x%x\n", val); - osi_writela(osi_core, val, addr + TX_MTU_LEN); + pr_err("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 + RX_MTU_LEN); - pr_err("Read RX_MTU_LEN: 0x%x\n", val); + val = osi_readla(osi_core, addr + MACSEC_RX_MTU_LEN); + pr_err("Read MACSEC_RX_MTU_LEN: 0x%x\n", val); val &= ~(MTU_LENGTH_MASK); val |= (mtu & MTU_LENGTH_MASK); - pr_err("Write RX_MTU_LEN: 0x%x\n", val); - osi_writela(osi_core, val, addr + RX_MTU_LEN); + pr_err("Write MACSEC_RX_MTU_LEN: 0x%x\n", val); + osi_writela(osi_core, val, addr + MACSEC_RX_MTU_LEN); /* 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 + TX_SOT_DELAY); - pr_err("Read TX_SOT_DELAY: 0x%x\n", val); + val = osi_readla(osi_core, addr + MACSEC_TX_SOT_DELAY); + pr_err("Read MACSEC_TX_SOT_DELAY: 0x%x\n", val); val &= ~(SOT_LENGTH_MASK); val |= (EQOS_MACSEC_SOT_DELAY & SOT_LENGTH_MASK); - pr_err("Write TX_SOT_DELAY: 0x%x\n", val); - osi_writela(osi_core, val, addr + TX_SOT_DELAY); + pr_err("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 + RX_SOT_DELAY); - pr_err("Read RX_SOT_DELAY: 0x%x\n", val); + val = osi_readla(osi_core, addr + MACSEC_RX_SOT_DELAY); + pr_err("Read MACSEC_RX_SOT_DELAY: 0x%x\n", val); val &= ~(SOT_LENGTH_MASK); val |= (EQOS_MACSEC_SOT_DELAY & SOT_LENGTH_MASK); - pr_err("Write RX_SOT_DELAY: 0x%x\n", val); - osi_writela(osi_core, val, addr + RX_SOT_DELAY); + pr_err("Write MACSEC_RX_SOT_DELAY: 0x%x\n", val); + osi_writela(osi_core, val, addr + MACSEC_RX_SOT_DELAY); } /* 2. Set essential MACsec control configuration */ val = osi_readla(osi_core, addr + MACSEC_CONTROL0); pr_err("Read MACSEC_CONTROL0: 0x%x\n", val); - val |= (TX_LKUP_MISS_NS_INTR | RX_LKUP_MISS_NS_INTR | - TX_LKUP_MISS_BYPASS | RX_LKUP_MISS_BYPASS); - val &= ~(VALIDATE_FRAMES_MASK); - val |= VALIDATE_FRAMES_STRICT; - val |= RX_REPLAY_PROT_EN; + 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; pr_err("Write MACSEC_CONTROL0: 0x%x\n", val); osi_writela(osi_core, val, addr + MACSEC_CONTROL0); val = osi_readla(osi_core, addr + MACSEC_CONTROL1); pr_err("Read MACSEC_CONTROL1: 0x%x\n", val); - val |= (RX_MTU_CHECK_EN | TX_LUT_PRIO_BYP | TX_MTU_CHECK_EN); + val |= (MACSEC_RX_MTU_CHECK_EN | MACSEC_TX_LUT_PRIO_BYP | + MACSEC_TX_MTU_CHECK_EN); pr_err("Write MACSEC_CONTROL1: 0x%x\n", val); osi_writela(osi_core, val, addr + MACSEC_CONTROL1); /* set DVLAN tag ethertype */ /* val = DVLAN_TAG_ETHERTYPE; - pr_err("Write MACSEC_TX_DVLAN_CONTROL_0: 0x%x\n", val); - osi_writela(osi_core, val, addr + MACSEC_TX_DVLAN_CONTROL_0); - pr_err("Write MACSEC_RX_DVLAN_CONTROL_0: 0x%x\n", val); - osi_writela(osi_core, val, addr + MACSEC_RX_DVLAN_CONTROL_0); */ + * pr_err("Write MACSEC_TX_DVLAN_CONTROL_0: 0x%x\n", val); + * osi_writela(osi_core, val, addr + MACSEC_TX_DVLAN_CONTROL_0); + * pr_err("Write MACSEC_RX_DVLAN_CONTROL_0: 0x%x\n", val); + * osi_writela(osi_core, val, addr + MACSEC_RX_DVLAN_CONTROL_0); + */ - val = osi_readla(osi_core, addr + STATS_CONTROL_0); - pr_err("Read STATS_CONTROL_0: 0x%x\n", val); + val = osi_readla(osi_core, addr + MACSEC_STATS_CONTROL_0); + pr_err("Read MACSEC_STATS_CONTROL_0: 0x%x\n", val); /* set STATS rollover bit */ - val |= STATS_CONTROL0_CNT_RL_OVR_CPY; - pr_err("Write STATS_CONTROL_0: 0x%x\n", val); - osi_writela(osi_core, val, addr + STATS_CONTROL_0); + val |= MACSEC_STATS_CONTROL0_CNT_RL_OVR_CPY; + pr_err("Write MACSEC_STATS_CONTROL_0: 0x%x\n", val); + osi_writela(osi_core, val, addr + MACSEC_STATS_CONTROL_0); /* 3. Enable default interrupts needed */ - val = osi_readla(osi_core, addr + TX_IMR); - pr_err("Read TX_IMR: 0x%x\n", val); - val |= (TX_DBG_BUF_CAPTURE_DONE_INT_EN | - TX_MTU_CHECK_FAIL_INT_EN | TX_MAC_CRC_ERROR_INT_EN | - TX_SC_AN_NOT_VALID_INT_EN | TX_AES_GCM_BUF_OVF_INT_EN | - TX_PN_EXHAUSTED_INT_EN | TX_PN_THRSHLD_RCHD_INT_EN); - pr_err("Write TX_IMR: 0x%x\n", val); - osi_writela(osi_core, val, addr + TX_IMR); + val = osi_readla(osi_core, addr + MACSEC_TX_IMR); + pr_err("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); + pr_err("Write MACSEC_TX_IMR: 0x%x\n", val); + osi_writela(osi_core, val, addr + MACSEC_TX_IMR); - val = osi_readla(osi_core, addr + RX_IMR); - pr_err("Read RX_IMR: 0x%x\n", val); + val = osi_readla(osi_core, addr + MACSEC_RX_IMR); + pr_err("Read MACSEC_RX_IMR: 0x%x\n", val); - val |= (RX_DBG_BUF_CAPTURE_DONE_INT_EN | - RX_ICV_ERROR_INT_EN | RX_REPLAY_ERROR_INT_EN | - RX_MTU_CHECK_FAIL_INT_EN | RX_MAC_CRC_ERROR_INT_EN | - RX_AES_GCM_BUF_OVF_INT_EN | - RX_PN_EXHAUSTED_INT_EN + 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 ); - pr_err("Write RX_IMR: 0x%x\n", val); - osi_writela(osi_core, val, addr + RX_IMR); + pr_err("Write MACSEC_RX_IMR: 0x%x\n", val); + osi_writela(osi_core, val, addr + MACSEC_RX_IMR); - val = osi_readla(osi_core, addr + COMMON_IMR); - pr_err("Read COMMON_IMR: 0x%x\n", val); + val = osi_readla(osi_core, addr + MACSEC_COMMON_IMR); + pr_err("Read MACSEC_COMMON_IMR: 0x%x\n", val); - val |= (SECURE_REG_VIOL_INT_EN | RX_UNINIT_KEY_SLOT_INT_EN | - RX_LKUP_MISS_INT_EN | TX_UNINIT_KEY_SLOT_INT_EN | - TX_LKUP_MISS_INT_EN); - pr_err("Write COMMON_IMR: 0x%x\n", val); - osi_writela(osi_core, val, addr + COMMON_IMR); + 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); + pr_err("Write MACSEC_COMMON_IMR: 0x%x\n", val); + osi_writela(osi_core, val, addr + MACSEC_COMMON_IMR); /* 4. Set AES mode * Default power on reset is AES-GCM128, leave it. @@ -2474,26 +2583,28 @@ static int macsec_init(struct osi_core_priv_data *const osi_core) /* 5. Invalidate LUT entries */ ret = clear_lut(osi_core); if (ret < 0) { - pr_err("Invalidating all LUT's failed\n"); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Invalidating all LUT's failed\n", ret); return ret; } /* 6. Set default BYP for MKPDU/BC packets */ - table_config->rw = LUT_WRITE; - lut_config.lut_sel = LUT_SEL_BYPASS; - lut_config.flags |= (LUT_FLAGS_DA_VALID | - LUT_FLAGS_ENTRY_VALID); + 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 = CTLR_SEL_TX; i <= CTLR_SEL_RX; i++) { - table_config->ctlr_sel = (unsigned short) i; + 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) { - pr_err("Failed to set BYP for BC addr"); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Failed to set BYP for BC addr\n", ret); goto exit; } else { osi_core->macsec_lut_status[i].next_byp_idx++; @@ -2504,13 +2615,15 @@ static int macsec_init(struct osi_core_priv_data *const osi_core) lut_config.lut_in.da[j] = mac_da_mkpdu[j]; } - for (i = CTLR_SEL_TX; i <= CTLR_SEL_RX; i++) { - table_config->ctlr_sel = (unsigned short) i; + 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) { - pr_err("Failed to set BYP for MKPDU multicast DA"); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Failed to set BYP for MKPDU multicast DA\n", ret); + goto exit; } else { osi_core->macsec_lut_status[i].next_byp_idx++; @@ -2524,15 +2637,15 @@ exit: static struct osi_macsec_sc_info *find_existing_sc( struct osi_core_priv_data *const osi_core, struct osi_macsec_sc_info *const sc, - unsigned short ctlr) + nveu16_t ctlr) { struct osi_macsec_lut_status *lut_status = &osi_core->macsec_lut_status[ctlr]; - int i; + nveu32_t i; for (i = 0; i < lut_status->next_sc_idx; i++) { - if (osi_memcmp(lut_status->sc_info[i].sci, sc->sci, SCI_LEN) == - OSI_NONE) { + if (osi_memcmp(lut_status->sc_info[i].sci, sc->sci, + OSI_SCI_LEN) == OSI_NONE) { return &lut_status->sc_info[i]; } } @@ -2540,24 +2653,24 @@ static struct osi_macsec_sc_info *find_existing_sc( return OSI_NULL; } -static int del_upd_sc(struct osi_core_priv_data *const osi_core, +static nve32_t del_upd_sc(struct osi_core_priv_data *const osi_core, struct osi_macsec_sc_info *existing_sc, struct osi_macsec_sc_info *const sc, - unsigned short ctlr, unsigned short *kt_idx) + 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 macsec_table_config *table_config; - int ret; + 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 = LUT_WRITE; + 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 @@ -2565,54 +2678,59 @@ static int del_upd_sc(struct osi_core_priv_data *const osi_core, */ if (existing_sc->curr_an == sc->curr_an) { /* 1. SCI LUT */ - lut_config.lut_sel = LUT_SEL_SCI; + lut_config.lut_sel = OSI_LUT_SEL_SCI; table_config->index = existing_sc->sc_idx_start; ret = macsec_lut_config(osi_core, &lut_config); if (ret < 0) { - pr_err("%s: Failed to del SCI LUT", __func__); - pr_err("%s: index = %hu", __func__, sc->sc_idx_start); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Failed to del SCI LUT idx\n", + sc->sc_idx_start); goto err_sci; } /* 2. SC Param LUT */ - lut_config.lut_sel = LUT_SEL_SC_PARAM; + lut_config.lut_sel = OSI_LUT_SEL_SC_PARAM; ret = macsec_lut_config(osi_core, &lut_config); if (ret < 0) { - pr_err("%s: Failed to del SC param", __func__); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Failed to del SC param\n", ret); goto err_sc_param; } /* 3. SC state LUT */ - lut_config.lut_sel = LUT_SEL_SC_STATE; + lut_config.lut_sel = OSI_LUT_SEL_SC_STATE; ret = macsec_lut_config(osi_core, &lut_config); if (ret < 0) { - pr_err("%s: Failed to del SC state", __func__); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Failed to del SC state\n", ret); goto err_sc_state; } } /* 4. SA State LUT */ - lut_config.lut_sel = LUT_SEL_SA_STATE; - table_config->index = (existing_sc->sc_idx_start * MAX_NUM_SA) + + lut_config.lut_sel = OSI_LUT_SEL_SA_STATE; + table_config->index = (existing_sc->sc_idx_start * OSI_MAX_NUM_SA) + sc->curr_an; ret = macsec_lut_config(osi_core, &lut_config); if (ret < 0) { - pr_err("%s: Failed to del SA state", __func__); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Failed to del SA state\n", ret); goto err_sa_state; } /* Store key table index returned to osd */ - *kt_idx = (existing_sc->sc_idx_start * MAX_NUM_SA) + sc->curr_an; + *kt_idx = (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 = LUT_WRITE; - /* Each SC has MAX_NUM_SA's supported in HW */ + 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) { - pr_err("%s: Failed to del SAK", __func__); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Failed to del SAK\n", ret); goto err_kt; } #endif /* MACSEC_KEY_PROGRAM */ @@ -2623,45 +2741,40 @@ static int del_upd_sc(struct osi_core_priv_data *const osi_core, #ifdef MACSEC_KEY_PROGRAM err_kt: - /* TODO cleanup SA state LUT */ #endif err_sa_state: - /* TODO Cleanup SC state LUT */ err_sc_state: - /* TODO Cleanup SC param LUT */ err_sc_param: - /* TODO cleanup SC LUT */ err_sci: return -1; } -static int add_upd_sc(struct osi_core_priv_data *const osi_core, +static nve32_t add_upd_sc(struct osi_core_priv_data *const osi_core, struct osi_macsec_sc_info *const sc, - unsigned short ctlr, unsigned short *kt_idx) + nveu16_t ctlr, nveu16_t *kt_idx) { struct osi_macsec_lut_config lut_config = {0}; - struct macsec_table_config *table_config; - int ret, i; + struct osi_macsec_table_config *table_config; + nve32_t ret, i; #ifdef MACSEC_KEY_PROGRAM struct osi_macsec_kt_config kt_config = {0}; #endif /* MACSEC_KEY_PROGRAM */ #ifdef MACSEC_KEY_PROGRAM /* HKEY GENERATION */ - /* TODO - Move this to OSD */ struct crypto_cipher *tfm; - unsigned char hkey[KEY_LEN_128]; - unsigned char zeros[KEY_LEN_128] = {0}; + nveu8_t hkey[OSI_KEY_LEN_128]; + nveu8_t zeros[OSI_KEY_LEN_128] = {0}; tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); - if (crypto_cipher_setkey(tfm, sc->sak, KEY_LEN_128)) { + if (crypto_cipher_setkey(tfm, sc->sak, OSI_KEY_LEN_128)) { pr_err("%s: Failed to set cipher key for H generation", __func__); return -1; } crypto_cipher_encrypt_one(tfm, hkey, zeros); pr_err("\n%s: Generated H key: ", __func__); - for (i = 0; i < KEY_LEN_128; i++) { + for (i = 0; i < OSI_KEY_LEN_128; i++) { pr_cont(" %02x", hkey[i]); } pr_err("\n"); @@ -2669,158 +2782,190 @@ static int add_upd_sc(struct osi_core_priv_data *const osi_core, #endif /* MACSEC_KEY_PROGRAM */ /* Store key table index returned to osd */ - *kt_idx = (sc->sc_idx_start * MAX_NUM_SA) + sc->curr_an; + *kt_idx = (sc->sc_idx_start * OSI_MAX_NUM_SA) + sc->curr_an; #ifdef MACSEC_KEY_PROGRAM /* 1. Key LUT */ table_config = &kt_config.table_config; table_config->ctlr_sel = ctlr; - table_config->rw = LUT_WRITE; - /* Each SC has MAX_NUM_SA's supported in HW */ + 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 |= LUT_FLAGS_ENTRY_VALID; + kt_config.flags |= OSI_LUT_FLAGS_ENTRY_VALID; /* Program in reverse order as per HW design */ - for (i = 0; i < KEY_LEN_128; i++) { - kt_config.entry.sak[i] = sc->sak[KEY_LEN_128 - 1 - i]; - kt_config.entry.h[i] = hkey[KEY_LEN_128 - 1 - i]; + for (i = 0; i < OSI_KEY_LEN_128; i++) { + kt_config.entry.sak[i] = sc->sak[OSI_KEY_LEN_128 - 1 - i]; + kt_config.entry.h[i] = hkey[OSI_KEY_LEN_128 - 1 - i]; } ret = macsec_kt_config(osi_core, &kt_config); if (ret < 0) { - pr_err("%s: Failed to set SAK", __func__); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Failed to set SAK\n", ret); return -1; } #endif /* MACSEC_KEY_PROGRAM */ table_config = &lut_config.table_config; table_config->ctlr_sel = ctlr; - table_config->rw = LUT_WRITE; + table_config->rw = OSI_LUT_WRITE; /* 2. SA state LUT */ - lut_config.lut_sel = LUT_SEL_SA_STATE; - table_config->index = (sc->sc_idx_start * MAX_NUM_SA) + sc->curr_an; + lut_config.lut_sel = OSI_LUT_SEL_SA_STATE; + table_config->index = (sc->sc_idx_start * OSI_MAX_NUM_SA) + sc->curr_an; lut_config.sa_state_out.next_pn = sc->next_pn; /* TODO - LLPN might have to be updated out of band for replay prot*/ lut_config.sa_state_out.lowest_pn = sc->next_pn; - lut_config.flags |= LUT_FLAGS_ENTRY_VALID; + lut_config.flags |= OSI_LUT_FLAGS_ENTRY_VALID; ret = macsec_lut_config(osi_core, &lut_config); if (ret < 0) { - pr_err("%s: Failed to set SA state", __func__); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Failed to set SA state\n", ret); goto err_sa_state; } /* 3. SC state LUT */ lut_config.flags = OSI_NONE; - lut_config.lut_sel = LUT_SEL_SC_STATE; + lut_config.lut_sel = OSI_LUT_SEL_SC_STATE; table_config->index = 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) { - pr_err("%s: Failed to set SC state", __func__); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Failed to set SC state\n", ret); goto err_sc_state; } /* 4. SC param LUT */ lut_config.flags = OSI_NONE; - lut_config.lut_sel = LUT_SEL_SC_PARAM; + lut_config.lut_sel = OSI_LUT_SEL_SC_PARAM; table_config->index = sc->sc_idx_start; /* Program in reverse order as per HW design */ - for (i = 0; i < SCI_LEN; i++) { - lut_config.sc_param_out.sci[i] = sc->sci[SCI_LEN - 1 - i]; + for (i = 0; i < OSI_SCI_LEN; i++) { + lut_config.sc_param_out.sci[i] = sc->sci[OSI_SCI_LEN - 1 - i]; } lut_config.sc_param_out.key_index_start = - (sc->sc_idx_start * MAX_NUM_SA); - lut_config.sc_param_out.pn_max = PN_MAX_DEFAULT; - lut_config.sc_param_out.pn_threshold = PN_THRESHOLD_DEFAULT; - lut_config.sc_param_out.pn_window = PN_MAX_DEFAULT; - lut_config.sc_param_out.tci = TCI_DEFAULT; - lut_config.sc_param_out.vlan_in_clear = VLAN_IN_CLEAR_DEFAULT; + (sc->sc_idx_start * 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) { - pr_err("%s: Failed to set SC param", __func__); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Failed to set SC param\n", ret); goto err_sc_param; } /* 5. SCI LUT */ lut_config.flags = OSI_NONE; - lut_config.lut_sel = LUT_SEL_SCI; + lut_config.lut_sel = OSI_LUT_SEL_SCI; table_config->index = sc->sc_idx_start; /* Program in reverse order as per HW design */ for (i = 0; i < OSI_ETH_ALEN; i++) { /* Extract the mac sa from the SCI itself */ lut_config.lut_in.sa[i] = sc->sci[OSI_ETH_ALEN - 1 - i]; } - lut_config.flags |= LUT_FLAGS_SA_VALID; + lut_config.flags |= OSI_LUT_FLAGS_SA_VALID; lut_config.sci_lut_out.sc_index = sc->sc_idx_start; - for (i = 0; i < SCI_LEN; i++) { - lut_config.sci_lut_out.sci[i] = sc->sci[SCI_LEN - 1 - i]; + for (i = 0; i < OSI_SCI_LEN; i++) { + lut_config.sci_lut_out.sci[i] = sc->sci[OSI_SCI_LEN - 1 - i]; } lut_config.sci_lut_out.an_valid = sc->an_valid; - lut_config.flags |= LUT_FLAGS_ENTRY_VALID; + lut_config.flags |= OSI_LUT_FLAGS_ENTRY_VALID; ret = macsec_lut_config(osi_core, &lut_config); if (ret < 0) { - pr_err("%s: Failed to set SCI LUT", __func__); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Failed to set SCI LUT\n", ret); goto err_sci; } return 0; err_sci: - //TODO cleanup SC param + /* 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 = sc->sc_idx_start; + macsec_lut_config(osi_core, &lut_config); + err_sc_param: - //TODO cleanup SC state + /* cleanup SC state */ + 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_STATE; + table_config->index = sc->sc_idx_start; + macsec_lut_config(osi_core, &lut_config); + err_sc_state: - //TODO Cleanup SA state LUT + /* 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 = (sc->sc_idx_start * OSI_MAX_NUM_SA) + sc->curr_an; + macsec_lut_config(osi_core, &lut_config); + err_sa_state: - //TODO Cleanup KT +#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; + macsec_kt_config(osi_core, &kt_config); +#endif /* MACSEC_KEY_PROGRAM */ return -1; } -static int macsec_config(struct osi_core_priv_data *const osi_core, +static nve32_t 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) + nveu32_t enable, nveu16_t ctlr, + nveu16_t *kt_idx) { struct osi_macsec_sc_info *existing_sc = OSI_NULL, *new_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; - int i; + nve32_t i; /* Validate inputs */ if ((enable != OSI_ENABLE && enable != OSI_DISABLE) || - (ctlr != CTLR_SEL_TX && ctlr != CTLR_SEL_RX) || + (ctlr != OSI_CTLR_SEL_TX && ctlr != OSI_CTLR_SEL_RX) || (kt_idx == OSI_NULL)) { return -1; } - /* TODO - lock needed. Multiple instances of supplicant can request - * to add a macsec config simultaneously. - */ lut_status = &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) { - pr_err("%s: trying to delete non-existing SC ?", - __func__); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "trying to delete non-existing SC ?\n", + 0ULL); return -1; } else { pr_err("%s: Adding new SC/SA: ctlr: %hu", __func__, ctlr); - if (lut_status->next_sc_idx >= MAX_NUM_SC) { - pr_err("%s: Err: Reached max SC LUT entries!", - __func__); + if (lut_status->next_sc_idx >= 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; } new_sc = &lut_status->sc_info[lut_status->next_sc_idx]; - osi_memcpy(new_sc->sci, sc->sci, SCI_LEN); - osi_memcpy(new_sc->sak, sc->sak, KEY_LEN_128); + osi_memcpy(new_sc->sci, sc->sci, OSI_SCI_LEN); + osi_memcpy(new_sc->sak, sc->sak, OSI_KEY_LEN_128); new_sc->curr_an = sc->curr_an; new_sc->next_pn = sc->next_pn; + new_sc->pn_window = sc->pn_window; new_sc->sc_idx_start = lut_status->next_sc_idx; new_sc->an_valid |= OSI_BIT(sc->curr_an); @@ -2830,26 +2975,23 @@ static int macsec_config(struct osi_core_priv_data *const osi_core, "\tan: %u\n" "\tpn: %u" "\tsc_idx_start: %u" - "\tan_valid: %#x", __func__, + "\tan_valid: %#x \tpn_window: %#x", __func__, new_sc->sci[0], new_sc->sci[1], new_sc->sci[2], new_sc->sci[3], new_sc->sci[4], new_sc->sci[5], new_sc->sci[6], new_sc->sci[7], new_sc->curr_an, new_sc->next_pn, new_sc->sc_idx_start, - new_sc->an_valid); + new_sc->an_valid, new_sc->pn_window); pr_err("\tkey: "); - for (i = 0; i < 16; i++) { + for (i = 0; i < OSI_KEY_LEN_128; i++) { pr_cont(" %02x", new_sc->sak[i]); } pr_err(""); if (add_upd_sc(osi_core, new_sc, ctlr, kt_idx) != OSI_NONE) { - pr_err("%s: failed to add new SC", __func__); - /* TODO - remove new_sc from lut_status[] ? - * not needed for now, as next_sc_idx is not - * incremented. - */ + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "failed to add new SC\n", 0ULL); return -1; } else { /* Update lut status */ @@ -2867,7 +3009,8 @@ static int macsec_config(struct osi_core_priv_data *const osi_core, pr_err("%s: Deleting existing SA", __func__); if (del_upd_sc(osi_core, existing_sc, sc, ctlr, kt_idx) != OSI_NONE) { - pr_err("%s: failed to del SA", __func__); + 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) { @@ -2881,11 +3024,13 @@ static int macsec_config(struct osi_core_priv_data *const osi_core, } else { /* Take backup copy. * Don't directly commit SC changes until LUT's are - * programmed successfully */ + * programmed successfully + */ *tmp_sc_p = *existing_sc; - osi_memcpy(tmp_sc_p->sak, sc->sak, KEY_LEN_128); + osi_memcpy(tmp_sc_p->sak, sc->sak, OSI_KEY_LEN_128); 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->an_valid |= OSI_BIT(sc->curr_an); @@ -2894,27 +3039,24 @@ static int macsec_config(struct osi_core_priv_data *const osi_core, "\tan: %u\n" "\tpn: %u" "\tsc_idx_start: %u" - "\tan_valid: %#x", __func__, + "\tan_valid: %#x \tpn_window: %#x", __func__, tmp_sc_p->sci[0], tmp_sc_p->sci[1], tmp_sc_p->sci[2], tmp_sc_p->sci[3], tmp_sc_p->sci[4], tmp_sc_p->sci[5], tmp_sc_p->sci[6], tmp_sc_p->sci[7], tmp_sc_p->curr_an, tmp_sc_p->next_pn, tmp_sc_p->sc_idx_start, - tmp_sc_p->an_valid); + tmp_sc_p->an_valid, tmp_sc_p->pn_window); pr_err("\tkey: "); - for (i = 0; i < 16; i++) { + for (i = 0; i < OSI_KEY_LEN_128; i++) { pr_cont(" %02x", tmp_sc_p->sak[i]); } pr_err(""); if (add_upd_sc(osi_core, tmp_sc_p, ctlr, kt_idx) != OSI_NONE) { - pr_err("%s: failed to add new SA", __func__); - /* TODO - remove new_sc from lut_status[] ? - * not needed for now, as next_sc_idx is not - * incremented. - */ + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "failed to add new SA\n", 0ULL); return -1; } else { pr_err("%s: Updated new SC ctlr: %u " @@ -2930,7 +3072,7 @@ static int macsec_config(struct osi_core_priv_data *const osi_core, } } -static struct macsec_core_ops macsec_ops = { +static struct osi_macsec_core_ops macsec_ops = { .init = macsec_init, .deinit = macsec_deinit, .handle_ns_irq = macsec_handle_ns_irq, @@ -2952,11 +3094,11 @@ static struct macsec_core_ops macsec_ops = { * @brief if_ops - Static core interface operations for virtual * case */ -static struct macsec_core_ops virt_macsec_ops; +static struct osi_macsec_core_ops virt_macsec_ops; -static struct osi_macsec_lut_status lut_status[NUM_CTLR]; +static struct osi_macsec_lut_status lut_status[OSI_NUM_CTLR]; -int osi_init_macsec_ops(struct osi_core_priv_data *const osi_core) +nve32_t osi_init_macsec_ops(struct osi_core_priv_data *const osi_core) { if (osi_core->macsec_base == OSI_NULL) { return -1; @@ -2972,7 +3114,7 @@ int osi_init_macsec_ops(struct osi_core_priv_data *const osi_core) } } -int osi_macsec_init(struct osi_core_priv_data *const osi_core) +nve32_t osi_macsec_init(struct osi_core_priv_data *const osi_core) { if (osi_core != OSI_NULL && osi_core->macsec_ops != OSI_NULL && osi_core->macsec_ops->init != OSI_NULL) { @@ -2982,7 +3124,7 @@ int osi_macsec_init(struct osi_core_priv_data *const osi_core) return -1; } -int osi_macsec_deinit(struct osi_core_priv_data *const osi_core) +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) { @@ -3007,7 +3149,7 @@ void osi_macsec_s_isr(struct osi_core_priv_data *const osi_core) } } -int osi_macsec_lut_config(struct osi_core_priv_data *const osi_core, +nve32_t osi_macsec_lut_config(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 && @@ -3019,7 +3161,7 @@ int osi_macsec_lut_config(struct osi_core_priv_data *const osi_core, } #ifdef MACSEC_KEY_PROGRAM -int osi_macsec_kt_config(struct osi_core_priv_data *const osi_core, +nve32_t osi_macsec_kt_config(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 && @@ -3032,8 +3174,8 @@ int osi_macsec_kt_config(struct osi_core_priv_data *const osi_core, } #endif /* MACSEC_KEY_PROGRAM */ -int osi_macsec_cipher_config(struct osi_core_priv_data *const osi_core, - unsigned int cipher) +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) { @@ -3043,8 +3185,8 @@ int osi_macsec_cipher_config(struct osi_core_priv_data *const osi_core, return -1; } -int osi_macsec_loopback(struct osi_core_priv_data *const osi_core, - unsigned int enable) +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 && @@ -3055,8 +3197,8 @@ int osi_macsec_loopback(struct osi_core_priv_data *const osi_core, return -1; } -int osi_macsec_en(struct osi_core_priv_data *const osi_core, - unsigned int enable) +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) && @@ -3072,13 +3214,13 @@ int osi_macsec_en(struct osi_core_priv_data *const osi_core, return -1; } -int osi_macsec_config(struct osi_core_priv_data *const osi_core, +nve32_t osi_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) + nveu32_t enable, nveu16_t ctlr, + nveu16_t *kt_idx) { if ((enable != OSI_ENABLE && enable != OSI_DISABLE) || - (ctlr != CTLR_SEL_TX && ctlr != CTLR_SEL_RX) || + (ctlr != OSI_CTLR_SEL_TX && ctlr != OSI_CTLR_SEL_RX) || (kt_idx == OSI_NULL)) { return -1; } @@ -3092,7 +3234,7 @@ int osi_macsec_config(struct osi_core_priv_data *const osi_core, return -1; } -int osi_macsec_read_mmc(struct osi_core_priv_data *const osi_core) +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) { @@ -3103,7 +3245,7 @@ int osi_macsec_read_mmc(struct osi_core_priv_data *const osi_core) return -1; } -int osi_macsec_dbg_buf_config( +nve32_t osi_macsec_dbg_buf_config( struct osi_core_priv_data *const osi_core, struct osi_macsec_dbg_buf_config *const dbg_buf_config) { @@ -3117,7 +3259,7 @@ int osi_macsec_dbg_buf_config( return -1; } -int osi_macsec_dbg_events_config( +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) { diff --git a/osi/core/macsec.h b/osi/core/macsec.h index 9ca0bca..927a673 100644 --- a/osi/core/macsec.h +++ b/osi/core/macsec.h @@ -29,115 +29,114 @@ * @brief MACsec controller register offsets * @{ */ -#define GCM_KEYTABLE_CONFIG 0x0000 -#define GCM_KEYTABLE_DATA(x) (0x0004 + (x * 4)) -#define RX_ICV_ERR_CNTRL 0x4000 -#define INTERRUPT_COMMON_SR 0x4004 -#define TX_IMR 0x4008 -#define TX_ISR 0x400C -#define RX_IMR 0x4048 -#define RX_ISR 0x404C -#define INTERRUPT_MASK1_0 0x40A0 -#define TX_SC_PN_THRESHOLD_STATUS0_0 0x4018 -#define TX_SC_PN_THRESHOLD_STATUS1_0 0x401C -#define TX_SC_PN_EXHAUSTED_STATUS0_0 0x4024 -#define TX_SC_PN_EXHAUSTED_STATUS1_0 0x4028 -#define TX_SC_ERROR_INTERRUPT_STATUS_0 0x402C -#define RX_SC_PN_EXHAUSTED_STATUS0_0 0x405C -#define RX_SC_PN_EXHAUSTED_STATUS1_0 0x4060 -#define RX_SC_REPLAY_ERROR_STATUS0_0 0x4090 -#define RX_SC_REPLAY_ERROR_STATUS1_0 0x4094 -#define STATS_CONFIG 0x9000 -#define STATS_CONTROL_0 0x900C -#define TX_PKTS_UNTG_LO_0 0x9010 -#define TX_PKTS_UNTG_HI_0 0x9014 -#define TX_OCTETS_PRTCTD_LO_0 0x9018 -#define TX_OCTETS_PRTCTD_HI_0 0x901C -#define TX_PKTS_TOO_LONG_LO_0 0x9020 -#define TX_PKTS_TOO_LONG_HI_0 0x9024 -#define TX_PKTS_PROTECTED_SCx_LO_0(x) (0x9028 + (x * 8)) -#define TX_PKTS_PROTECTED_SCx_HI_0(x) (0x902C + (x * 8)) -#define RX_PKTS_NOTG_LO_0 0x90B0 -#define RX_PKTS_NOTG_HI_0 0x90B4 -#define RX_PKTS_UNTG_LO_0 0x90A8 -#define RX_PKTS_UNTG_HI_0 0x90AC -#define RX_PKTS_BADTAG_LO_0 0x90B8 -#define RX_PKTS_BADTAG_HI_0 0x90BC -#define RX_PKTS_NOSA_LO_0 0x90C0 -#define RX_PKTS_NOSA_HI_0 0x90C4 -#define RX_PKTS_NOSAERROR_LO_0 0x90C8 -#define RX_PKTS_NOSAERROR_HI_0 0x90CC -#define RX_PKTS_OVRRUN_LO_0 0x90D0 -#define RX_PKTS_OVRRUN_HI_0 0x90D4 -#define RX_OCTETS_VLDTD_LO_0 0x90D8 -#define RX_OCTETS_VLDTD_HI_0 0x90DC -#define RX_PKTS_LATE_SCx_LO_0(x) (0x90E0 + (x * 8)) -#define RX_PKTS_LATE_SCx_HI_0(x) (0x90E4 + (x * 8)) -#define RX_PKTS_NOTVALID_SCx_LO_0(x) (0x9160 + (x * 8)) -#define RX_PKTS_NOTVALID_SCx_HI_0(x) (0x9164 + (x * 8)) -#define RX_PKTS_OK_SCx_LO_0(x) (0x91E0 + (x * 8)) -#define RX_PKTS_OK_SCx_HI_0(x) (0x91E4 + (x * 8)) +#define MASCEC_GCM_KEYTABLE_CONFIG 0x0000 +#define MACSEC_GCM_KEYTABLE_DATA(x) (0x0004 + (x * 4)) +#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_INTERRUPT_MASK1_0 0x40A0 +#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_CONFIG 0x9000 +#define MACSEC_STATS_CONTROL_0 0x900C +#define MACSEC_TX_PKTS_UNTG_LO_0 0x9010 +#define MACSEC_TX_PKTS_UNTG_HI_0 0x9014 +#define MACSEC_TX_OCTETS_PRTCTD_LO_0 0x9018 +#define MACSEC_TX_OCTETS_PRTCTD_HI_0 0x901C +#define MACSEC_TX_PKTS_TOO_LONG_LO_0 0x9020 +#define MACSEC_TX_PKTS_TOO_LONG_HI_0 0x9024 +#define MACSEC_TX_PKTS_PROTECTED_SCx_LO_0(x) (0x9028 + (x * 8)) +#define MACSEC_TX_PKTS_PROTECTED_SCx_HI_0(x) (0x902C + (x * 8)) +#define MACSEC_RX_PKTS_NOTG_LO_0 0x90B0 +#define MACSEC_RX_PKTS_NOTG_HI_0 0x90B4 +#define MACSEC_RX_PKTS_UNTG_LO_0 0x90A8 +#define MACSEC_RX_PKTS_UNTG_HI_0 0x90AC +#define MACSEC_RX_PKTS_BADTAG_LO_0 0x90B8 +#define MACSEC_RX_PKTS_BADTAG_HI_0 0x90BC +#define MACSEC_RX_PKTS_NOSA_LO_0 0x90C0 +#define MACSEC_RX_PKTS_NOSA_HI_0 0x90C4 +#define MACSEC_RX_PKTS_NOSAERROR_LO_0 0x90C8 +#define MACSEC_RX_PKTS_NOSAERROR_HI_0 0x90CC +#define MACSEC_RX_PKTS_OVRRUN_LO_0 0x90D0 +#define MACSEC_RX_PKTS_OVRRUN_HI_0 0x90D4 +#define MACSEC_RX_OCTETS_VLDTD_LO_0 0x90D8 +#define MACSEC_RX_OCTETS_VLDTD_HI_0 0x90DC +#define MACSEC_RX_PKTS_LATE_SCx_LO_0(x) (0x90E0 + (x * 8)) +#define MACSEC_RX_PKTS_LATE_SCx_HI_0(x) (0x90E4 + (x * 8)) +#define MACSEC_RX_PKTS_NOTVALID_SCx_LO_0(x) (0x9160 + (x * 8)) +#define MACSEC_RX_PKTS_NOTVALID_SCx_HI_0(x) (0x9164 + (x * 8)) +#define MACSEC_RX_PKTS_OK_SCx_LO_0(x) (0x91E0 + (x * 8)) +#define MACSEC_RX_PKTS_OK_SCx_HI_0(x) (0x91E4 + (x * 8)) -#define TX_INPKTS_CRCIN_NOTVALID_LO_0 0x9260 -#define TX_INPKTS_CRCIN_NOTVALID_HI_0 0x9264 -#define RX_INPKTS_CRCIN_NOTVALID_LO_0 0x9268 -#define RX_INPKTS_CRCIN_NOTVALID_HI_0 0x926C +#define MACSEC_TX_INPKTS_CRCIN_NOTVALID_LO_0 0x9260 +#define MACSEC_TX_INPKTS_CRCIN_NOTVALID_HI_0 0x9264 +#define MACSEC_RX_INPKTS_CRCIN_NOTVALID_LO_0 0x9268 +#define MACSEC_RX_INPKTS_CRCIN_NOTVALID_HI_0 0x926C -#define MACSEC_CONTROL0 0xD000 +#define MACSEC_CONTROL0 0xD000 #define MACSEC_LUT_CONFIG 0xD004 #define MACSEC_LUT_DATA(x) (0xD008 + (x * 4)) -#define TX_BYP_LUT_VALID 0xD024 -#define TX_SCI_LUT_VALID 0xD028 -#define RX_BYP_LUT_VALID 0xD02C -#define RX_SCI_LUT_VALID 0xD030 +#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 COMMON_IMR 0xD054 -#define COMMON_ISR 0xD058 -#define TX_SC_KEY_INVALID_STS0_0 0xD064 -#define TX_SC_KEY_INVALID_STS1_0 0xD068 -#define RX_SC_KEY_INVALID_STS0_0 0xD080 -#define RX_SC_KEY_INVALID_STS1_0 0xD084 +#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 TX_DEBUG_CONTROL_0 0xD098 -#define TX_DEBUG_TRIGGER_EN_0 0xD09C -#define TX_DEBUG_STATUS_0 0xD0C4 -#define DEBUG_BUF_CONFIG_0 0xD0C8 -#define DEBUG_BUF_DATA_0(x) (0xD0CC + (x * 4)) -#define RX_DEBUG_CONTROL_0 0xD0DC -#define RX_DEBUG_TRIGGER_EN_0 0xD0E0 -#define RX_DEBUG_STATUS_0 0xD0F8 +#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) (0xD0CC + (x * 4)) +#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 GCM_AES_CONTROL_0 0xE004 -#define TX_MTU_LEN 0xE008 -#define TX_SOT_DELAY 0xE010 -#define RX_MTU_LEN 0xE014 -#define RX_SOT_DELAY 0xE01C +#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 #define MACSEC_TX_DVLAN_CONTROL_0 0xE00C #define MACSEC_RX_DVLAN_CONTROL_0 0xE018 /** @} */ /** - * @addtogroup GCM_KEYTABLE_CONFIG register + * @addtogroup MACSEC_GCM_KEYTABLE_CONFIG register * - * @brief Bit definitions of GCM_KEYTABLE_CONFIG register + * @brief Bit definitions of MACSEC_GCM_KEYTABLE_CONFIG register * @{ */ -#define KT_CONFIG_UPDATE OSI_BIT(31) -#define KT_CONFIG_CTLR_SEL OSI_BIT(25) -#define KT_CONFIG_RW OSI_BIT(24) -#define KT_CONFIG_INDEX_MASK (OSI_BIT(4) | OSI_BIT(3) | OSI_BIT(2) |\ +#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 KT_ENTRY_VALID OSI_BIT(0) +#define MACSEC_KT_ENTRY_VALID OSI_BIT(0) /** @} */ /** - * @addtogroup GCM_KEYTABLE_DATA registers + * @addtogroup MACSEC_GCM_KEYTABLE_DATA registers * - * @brief Bit definitions of GCM_KEYTABLE_DATA register & helpful macros + * @brief Bit definitions of MACSEC_GCM_KEYTABLE_DATA register & helpful macros * @{ */ -#define KT_ENTRY_VALID OSI_BIT(0) #define MACSEC_KT_DATA_REG_CNT 13 #define MACSEC_KT_DATA_REG_SAK_CNT 8 #define MACSEC_KT_DATA_REG_H_CNT 4 @@ -149,13 +148,13 @@ * @brief Bit definitions of MACSEC_LUT_CONFIG register * @{ */ -#define LUT_CONFIG_UPDATE OSI_BIT(31) -#define LUT_CONFIG_CTLR_SEL OSI_BIT(25) -#define LUT_CONFIG_RW OSI_BIT(24) -#define LUT_CONFIG_LUT_SEL_MASK (OSI_BIT(18) | OSI_BIT(17) |\ +#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 LUT_CONFIG_LUT_SEL_SHIFT 16 -#define LUT_CONFIG_INDEX_MASK (OSI_BIT(4) | OSI_BIT(3) | OSI_BIT(2) |\ +#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)) /** @} */ /** @@ -164,9 +163,9 @@ * @brief Bit definitions of MACSEC_INTERRUPT_COMMON_STATUS register * @{ */ -#define COMMON_SR_SFTY_ERR OSI_BIT(2) -#define COMMON_SR_RX OSI_BIT(1) -#define COMMON_SR_TX OSI_BIT(0) +#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) /** @} */ /** @@ -175,17 +174,17 @@ * @brief Bit definitions of MACSEC_CONTROL0 register * @{ */ -#define TX_LKUP_MISS_NS_INTR OSI_BIT(24) -#define RX_LKUP_MISS_NS_INTR OSI_BIT(23) -#define VALIDATE_FRAMES_MASK (OSI_BIT(22) | OSI_BIT(21)) -#define VALIDATE_FRAMES_DIS 0x0 -#define VALIDATE_FRAMES_STRICT OSI_BIT(22) -#define VALIDATE_FRAMES_CHECK OSI_BIT(21) -#define RX_REPLAY_PROT_EN OSI_BIT(20) -#define RX_LKUP_MISS_BYPASS OSI_BIT(19) -#define RX_EN OSI_BIT(16) -#define TX_LKUP_MISS_BYPASS OSI_BIT(3) -#define TX_EN OSI_BIT(0) +#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_DIS 0x0 +#define MACSEC_VALIDATE_FRAMES_STRICT OSI_BIT(22) +#define MACSEC_VALIDATE_FRAMES_CHECK OSI_BIT(21) +#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) /** @} */ /** @@ -194,255 +193,236 @@ * @brief Bit definitions of MACSEC_CONTROL1 register * @{ */ -#define LOOPBACK_MODE_EN OSI_BIT(31) -#define RX_MTU_CHECK_EN OSI_BIT(16) -#define TX_LUT_PRIO_BYP OSI_BIT(2) -#define TX_MTU_CHECK_EN OSI_BIT(0) +#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 GCM_AES_CONTROL_0 register + * @addtogroup MACSEC_GCM_AES_CONTROL_0 register * - * @brief Bit definitions of GCM_AES_CONTROL_0 register + * @brief Bit definitions of MACSEC_GCM_AES_CONTROL_0 register * @{ */ -#define RX_AES_MODE_MASK (OSI_BIT(17) | OSI_BIT(16)) -#define RX_AES_MODE_AES128 0x0 -#define RX_AES_MODE_AES256 OSI_BIT(17) -#define TX_AES_MODE_MASK (OSI_BIT(1) | OSI_BIT(0)) -#define TX_AES_MODE_AES128 0x0 -#define TX_AES_MODE_AES256 OSI_BIT(1) +#define MACSEC_RX_AES_MODE_MASK (OSI_BIT(17) | OSI_BIT(16)) +#define MACSEC_RX_AES_MODE_AES128 0x0 +#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 0x0 +#define MACSEC_TX_AES_MODE_AES256 OSI_BIT(1) /** @} */ /** - * @addtogroup COMMON_IMR register + * @addtogroup MACSEC_COMMON_IMR register * * @brief Bit definitions of MACSEC_INTERRUPT_MASK register * @{ */ -#define SECURE_REG_VIOL_INT_EN OSI_BIT(31) -#define RX_UNINIT_KEY_SLOT_INT_EN OSI_BIT(17) -#define RX_LKUP_MISS_INT_EN OSI_BIT(16) -#define TX_UNINIT_KEY_SLOT_INT_EN OSI_BIT(1) -#define TX_LKUP_MISS_INT_EN OSI_BIT(0) +#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 TX_IMR register + * @addtogroup MACSEC_TX_IMR register * * @brief Bit definitions of TX_INTERRUPT_MASK register * @{ */ -#define TX_DBG_BUF_CAPTURE_DONE_INT_EN OSI_BIT(22) -#define TX_MTU_CHECK_FAIL_INT_EN OSI_BIT(19) -#define TX_AES_GCM_BUF_OVF_INT_EN OSI_BIT(18) -#define TX_SC_AN_NOT_VALID_INT_EN OSI_BIT(17) -#define TX_MAC_CRC_ERROR_INT_EN OSI_BIT(16) -#define TX_PN_EXHAUSTED_INT_EN OSI_BIT(1) -#define TX_PN_THRSHLD_RCHD_INT_EN OSI_BIT(0) +#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 RX_IMR register + * @addtogroup MACSEC_RX_IMR register * * @brief Bit definitions of RX_INTERRUPT_MASK register * @{ */ -#define RX_DBG_BUF_CAPTURE_DONE_INT_EN OSI_BIT(22) -#define RX_ICV_ERROR_INT_EN OSI_BIT(21) -#define RX_REPLAY_ERROR_INT_EN OSI_BIT(20) -#define RX_MTU_CHECK_FAIL_INT_EN OSI_BIT(19) -#define RX_AES_GCM_BUF_OVF_INT_EN OSI_BIT(18) -#define RX_MAC_CRC_ERROR_INT_EN OSI_BIT(16) -#define RX_PN_EXHAUSTED_INT_EN OSI_BIT(1) +#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 INTERRUPT_MASK1_0 register + * @addtogroup MACSEC_INTERRUPT_MASK1_0 register * - * @brief Bit definitions of INTERRUPT_MASK1_0 register + * @brief Bit definitions of MACSEC_INTERRUPT_MASK1_0 register * @{ */ -#define SFTY_ERR_UNCORR_INT_EN OSI_BIT(0) +#define MACSEC_SFTY_ERR_UNCORR_INT_EN OSI_BIT(0) /** @} */ /** - * @addtogroup COMMON_ISR register + * @addtogroup MACSEC_COMMON_ISR register * * @brief Bit definitions of MACSEC_INTERRUPT_STATUS register * @{ */ -#define SECURE_REG_VIOL OSI_BIT(31) -#define RX_UNINIT_KEY_SLOT OSI_BIT(17) -#define RX_LKUP_MISS OSI_BIT(16) -#define TX_UNINIT_KEY_SLOT OSI_BIT(1) -#define TX_LKUP_MISS OSI_BIT(0) +#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 TX_ISR register + * @addtogroup MACSEC_TX_ISR register * * @brief Bit definitions of TX_INTERRUPT_STATUS register * @{ */ -#define TX_DBG_BUF_CAPTURE_DONE OSI_BIT(22) -#define TX_MTU_CHECK_FAIL OSI_BIT(19) -#define TX_AES_GCM_BUF_OVF OSI_BIT(18) -#define TX_SC_AN_NOT_VALID OSI_BIT(17) -#define TX_MAC_CRC_ERROR OSI_BIT(16) -#define TX_PN_EXHAUSTED OSI_BIT(1) -#define TX_PN_THRSHLD_RCHD OSI_BIT(0) +#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 RX_ISR register + * @addtogroup MACSEC_RX_ISR register * * @brief Bit definitions of RX_INTERRUPT_STATUS register * @{ */ -#define RX_DBG_BUF_CAPTURE_DONE OSI_BIT(22) -#define RX_ICV_ERROR OSI_BIT(21) -#define RX_REPLAY_ERROR OSI_BIT(20) -#define RX_MTU_CHECK_FAIL OSI_BIT(19) -#define RX_AES_GCM_BUF_OVF OSI_BIT(18) -#define RX_MAC_CRC_ERROR OSI_BIT(16) -#define RX_PN_EXHAUSTED OSI_BIT(1) +#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 STATS_CONTROL_0 register + * @addtogroup MACSEC_STATS_CONTROL_0 register * - * @brief Bit definitions of STATS_CONTROL_0 register + * @brief Bit definitions of MACSEC_STATS_CONTROL_0 register * @{ */ -#define STATS_CONTROL0_RD_CPY OSI_BIT(3) -#define STATS_CONTROL0_TK_CPY OSI_BIT(2) -#define STATS_CONTROL0_CNT_RL_OVR_CPY OSI_BIT(1) -#define STATS_CONTROL0_CNT_CLR OSI_BIT(0) +#define MACSEC_STATS_CONTROL0_RD_CPY OSI_BIT(3) +#define MACSEC_STATS_CONTROL0_TK_CPY OSI_BIT(2) +#define MACSEC_STATS_CONTROL0_CNT_RL_OVR_CPY OSI_BIT(1) +#define MACSEC_STATS_CONTROL0_CNT_CLR OSI_BIT(0) /** @} */ /** - * @addtogroup DEBUG_BUF_CONFIG_0 register + * @addtogroup MACSEC_DEBUG_BUF_CONFIG_0 register * - * @brief Bit definitions of DEBUG_BUF_CONFIG_0 register + * @brief Bit definitions of MACSEC_DEBUG_BUF_CONFIG_0 register * @{ */ -#define DEBUG_BUF_CONFIG_0_UPDATE OSI_BIT(31) -#define DEBUG_BUF_CONFIG_0_CTLR_SEL OSI_BIT(25) -#define DEBUG_BUF_CONFIG_0_RW OSI_BIT(24) -#define DEBUG_BUF_CONFIG_0_IDX_MASK (OSI_BIT(0) | OSI_BIT(1) | \ +#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 TX_DEBUG_TRIGGER_EN_0 register + * @addtogroup MACSEC_TX_DEBUG_TRIGGER_EN_0 register * - * @brief Bit definitions of TX_DEBUG_TRIGGER_EN_0 register + * @brief Bit definitions of MACSEC_TX_DEBUG_TRIGGER_EN_0 register * @{ */ -#define TX_DBG_CAPTURE OSI_BIT(10) -#define TX_DBG_ICV_CORRUPT OSI_BIT(9) -#define TX_DBG_CRC_CORRUPT OSI_BIT(8) -#define TX_DBG_DATA_MATCH OSI_BIT(7) -#define TX_DBG_LKUP_MATCH OSI_BIT(6) -#define TX_DBG_CRCOUT_MATCH OSI_BIT(5) -#define TX_DBG_CRCIN_MATCH OSI_BIT(4) -#define TX_DBG_ICV_MATCH OSI_BIT(3) -#define TX_DBG_KEY_NOT_VALID OSI_BIT(2) -#define TX_DBG_AN_NOT_VALID OSI_BIT(1) -#define TX_DBG_LKUP_MISS OSI_BIT(0) +#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_DATA_MATCH OSI_BIT(7) +#define MACSEC_TX_DBG_LKUP_MATCH OSI_BIT(6) +#define MACSEC_TX_DBG_CRCOUT_MATCH OSI_BIT(5) +#define MACSEC_TX_DBG_CRCIN_MATCH OSI_BIT(4) +#define MACSEC_TX_DBG_ICV_MATCH OSI_BIT(3) +#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 TX_DEBUG_STATUS_0 register + * @addtogroup MACSEC_TX_DEBUG_STATUS_0 register * - * @brief Bit definitions of TX_DEBUG_STATUS_0 register + * @brief Bit definitions of MACSEC_TX_DEBUG_STATUS_0 register * @{ */ -#define TX_DBG_STS_CAPTURE OSI_BIT(10) -#define TX_DBG_STS_ICV_CORRUPT OSI_BIT(9) -#define TX_DBG_STS_CRC_CORRUPT OSI_BIT(8) -#define TX_DBG_STS_DATA_MATCH OSI_BIT(7) -#define TX_DBG_STS_LKUP_MATCH OSI_BIT(6) -#define TX_DBG_STS_CRCOUT_MATCH OSI_BIT(5) -#define TX_DBG_STS_CRCIN_MATCH OSI_BIT(4) -#define TX_DBG_STS_ICV_MATCH OSI_BIT(3) -#define TX_DBG_STS_KEY_NOT_VALID OSI_BIT(2) -#define TX_DBG_STS_AN_NOT_VALID OSI_BIT(1) -#define TX_DBG_STS_LKUP_MISS OSI_BIT(0) +#define MACSEC_TX_DBG_STS_CAPTURE OSI_BIT(10) +#define MACSEC_TX_DBG_STS_ICV_CORRUPT OSI_BIT(9) +#define MACSEC_TX_DBG_STS_CRC_CORRUPT OSI_BIT(8) +#define MACSEC_TX_DBG_STS_DATA_MATCH OSI_BIT(7) +#define MACSEC_TX_DBG_STS_LKUP_MATCH OSI_BIT(6) +#define MACSEC_TX_DBG_STS_CRCOUT_MATCH OSI_BIT(5) +#define MACSEC_TX_DBG_STS_CRCIN_MATCH OSI_BIT(4) +#define MACSEC_TX_DBG_STS_ICV_MATCH OSI_BIT(3) +#define MACSEC_TX_DBG_STS_KEY_NOT_VALID OSI_BIT(2) +#define MACSEC_TX_DBG_STS_AN_NOT_VALID OSI_BIT(1) +#define MACSEC_TX_DBG_STS_LKUP_MISS OSI_BIT(0) /** @} */ /** - * @addtogroup RX_DEBUG_TRIGGER_EN_0 register + * @addtogroup MACSEC_RX_DEBUG_TRIGGER_EN_0 register * - * @brief Bit definitions of RX_DEBUG_TRIGGER_EN_0 register + * @brief Bit definitions of MACSEC_RX_DEBUG_TRIGGER_EN_0 register * @{ */ -#define RX_DBG_CAPTURE OSI_BIT(10) -#define RX_DBG_ICV_ERROR OSI_BIT(9) -#define RX_DBG_CRC_CORRUPT OSI_BIT(8) -#define RX_DBG_DATA_MATCH OSI_BIT(7) -#define RX_DBG_BYP_LKUP_MATCH OSI_BIT(6) -#define RX_DBG_CRCOUT_MATCH OSI_BIT(5) -#define RX_DBG_CRCIN_MATCH OSI_BIT(4) -#define RX_DBG_REPLAY_ERR OSI_BIT(3) -#define RX_DBG_KEY_NOT_VALID OSI_BIT(2) -#define RX_DBG_LKUP_MISS OSI_BIT(0) +#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_DATA_MATCH OSI_BIT(7) +#define MACSEC_RX_DBG_BYP_LKUP_MATCH OSI_BIT(6) +#define MACSEC_RX_DBG_CRCOUT_MATCH OSI_BIT(5) +#define MACSEC_RX_DBG_CRCIN_MATCH OSI_BIT(4) +#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 RX_DEBUG_STATUS_0 register + * @addtogroup MACSEC_RX_DEBUG_STATUS_0 register * - * @brief Bit definitions of RX_DEBUG_STATUS_0 register + * @brief Bit definitions of MACSEC_RX_DEBUG_STATUS_0 register * @{ */ -#define RX_DBG_STS_CAPTURE OSI_BIT(10) -#define RX_DBG_STS_ICV_ERROR OSI_BIT(9) -#define RX_DBG_STS_CRC_CORRUPT OSI_BIT(8) -#define RX_DBG_STS_DATA_MATCH OSI_BIT(7) -#define RX_DBG_STS_BYP_LKUP_MATCH OSI_BIT(6) -#define RX_DBG_STS_CRCOUT_MATCH OSI_BIT(5) -#define RX_DBG_STS_CRCIN_MATCH OSI_BIT(4) -#define RX_DBG_STS_REPLAY_ERR OSI_BIT(3) -#define RX_DBG_STS_KEY_NOT_VALID OSI_BIT(2) -#define RX_DBG_STS_LKUP_MISS OSI_BIT(0) +#define MACSEC_RX_DBG_STS_CAPTURE OSI_BIT(10) +#define MACSEC_RX_DBG_STS_ICV_ERROR OSI_BIT(9) +#define MACSEC_RX_DBG_STS_CRC_CORRUPT OSI_BIT(8) +#define MACSEC_RX_DBG_STS_DATA_MATCH OSI_BIT(7) +#define MACSEC_RX_DBG_STS_BYP_LKUP_MATCH OSI_BIT(6) +#define MACSEC_RX_DBG_STS_CRCOUT_MATCH OSI_BIT(5) +#define MACSEC_RX_DBG_STS_CRCIN_MATCH OSI_BIT(4) +#define MACSEC_RX_DBG_STS_REPLAY_ERR OSI_BIT(3) +#define MACSEC_RX_DBG_STS_KEY_NOT_VALID OSI_BIT(2) +#define MACSEC_RX_DBG_STS_LKUP_MISS OSI_BIT(0) /** @} */ /** - * @addtogroup TX_DEBUG_STATUS_0 register + * @addtogroup MACSEC_TX_DEBUG_CONTROL_0 register * - * @brief Bit definitions of TX_DEBUG_STATUS_0 register + * @brief Bit definitions of MACSEC_TX_DEBUG_CONTROL_0 register * @{ */ -#define TX_DBG_STS_CAPTURE OSI_BIT(10) -#define TX_DBG_STS_ICV_CORRUPT OSI_BIT(9) -#define TX_DBG_STS_CRC_CORRUPT OSI_BIT(8) -#define TX_DBG_STS_DATA_MATCH OSI_BIT(7) -#define TX_DBG_STS_LKUP_MATCH OSI_BIT(6) -#define TX_DBG_STS_CRCOUT_MATCH OSI_BIT(5) -#define TX_DBG_STS_CRCIN_MATCH OSI_BIT(4) -#define TX_DBG_STS_ICV_MATCH OSI_BIT(3) -#define TX_DBG_STS_KEY_NOT_VALID OSI_BIT(2) -#define TX_DBG_STS_AN_NOT_VALID OSI_BIT(1) -#define TX_DBG_STS_LKUP_MISS OSI_BIT(0) +#define MACSEC_TX_DEBUG_CONTROL_0_START_CAP OSI_BIT(31) /** @} */ /** - * @addtogroup TX_DEBUG_CONTROL_0 register + * @addtogroup MACSEC_RX_DEBUG_CONTROL_0 register * - * @brief Bit definitions of TX_DEBUG_CONTROL_0 register + * @brief Bit definitions of MACSEC_RX_DEBUG_CONTROL_0 register * @{ */ -#define TX_DEBUG_CONTROL_0_START_CAP OSI_BIT(31) -/** @} */ - -/** - * @addtogroup RX_DEBUG_CONTROL_0 register - * - * @brief Bit definitions of RX_DEBUG_CONTROL_0 register - * @{ - */ -#define RX_DEBUG_CONTROL_0_START_CAP OSI_BIT(31) +#define MACSEC_RX_DEBUG_CONTROL_0_START_CAP OSI_BIT(31) /** @} */ #define MTU_LENGTH_MASK 0xFFFF @@ -457,14 +437,14 @@ * @brief Bit definitions of LUT_VALID registers * @{ */ -#define TX_BYP_LUT_VALID_ENTRY(x) OSI_BIT(x) -#define TX_BYP_LUT_VALID_NONE 0x0 -#define TX_SCI_LUT_VALID_ENTRY(x) OSI_BIT(x) -#define TX_SCI_LUT_VALID_NONE 0x0 -#define RX_BYP_LUT_VALID_ENTRY(x) OSI_BIT(x) -#define RX_BYP_LUT_VALID_NONE 0x0 -#define RX_SCI_LUT_VALID_ENTRY(x) OSI_BIT(x) -#define RX_SCI_LUT_VALID_NONE 0x0 +#define MACSEC_TX_BYP_LUT_VALID_ENTRY(x) OSI_BIT(x) +#define MACSEC_TX_BYP_LUT_VALID_NONE 0x0 +#define MACSEC_TX_SCI_LUT_VALID_ENTRY(x) OSI_BIT(x) +#define MACSEC_TX_SCI_LUT_VALID_NONE 0x0 +#define MACSEC_RX_BYP_LUT_VALID_ENTRY(x) OSI_BIT(x) +#define MACSEC_RX_BYP_LUT_VALID_NONE 0x0 +#define MACSEC_RX_SCI_LUT_VALID_ENTRY(x) OSI_BIT(x) +#define MACSEC_RX_SCI_LUT_VALID_NONE 0x0 /** @} */ /** @@ -476,60 +456,60 @@ #define MACSEC_LUT_DATA_REG_CNT 7 /* Bit Offsets for LUT DATA[x] registers for various lookup field masks */ /* DA mask bits in LUT_DATA[1] register */ -#define LUT_DA_BYTE0_INACTIVE OSI_BIT(16) -#define LUT_DA_BYTE1_INACTIVE OSI_BIT(17) -#define LUT_DA_BYTE2_INACTIVE OSI_BIT(18) -#define LUT_DA_BYTE3_INACTIVE OSI_BIT(19) -#define LUT_DA_BYTE4_INACTIVE OSI_BIT(20) -#define LUT_DA_BYTE5_INACTIVE OSI_BIT(21) +#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 LUT_SA_BYTE0_INACTIVE OSI_BIT(6) -#define LUT_SA_BYTE1_INACTIVE OSI_BIT(7) -#define LUT_SA_BYTE2_INACTIVE OSI_BIT(8) -#define LUT_SA_BYTE3_INACTIVE OSI_BIT(9) -#define LUT_SA_BYTE4_INACTIVE OSI_BIT(10) -#define LUT_SA_BYTE5_INACTIVE OSI_BIT(11) +#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 LUT_ETHTYPE_INACTIVE OSI_BIT(28) +#define MACSEC_LUT_ETHTYPE_INACTIVE OSI_BIT(28) /* VLAN PCP mask in LUT_DATA[4] register */ -#define LUT_VLAN_PCP_INACTIVE OSI_BIT(0) +#define MACSEC_LUT_VLAN_PCP_INACTIVE OSI_BIT(0) /* VLAN ID mask in LUT_DATA[4] register */ -#define LUT_VLAN_ID_INACTIVE OSI_BIT(13) +#define MACSEC_LUT_VLAN_ID_INACTIVE OSI_BIT(13) /* VLAN mask in LUT_DATA[4] register */ -#define LUT_VLAN_ACTIVE OSI_BIT(14) +#define MACSEC_LUT_VLAN_ACTIVE OSI_BIT(14) /* Byte pattern masks in LUT_DATA[4] register */ -#define LUT_BYTE0_PATTERN_INACTIVE OSI_BIT(29) +#define MACSEC_LUT_BYTE0_PATTERN_INACTIVE OSI_BIT(29) /* Byte pattern masks in LUT_DATA[5] register */ -#define LUT_BYTE1_PATTERN_INACTIVE OSI_BIT(12) -#define LUT_BYTE2_PATTERN_INACTIVE OSI_BIT(27) +#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 LUT_BYTE3_PATTERN_INACTIVE OSI_BIT(10) +#define MACSEC_LUT_BYTE3_PATTERN_INACTIVE OSI_BIT(10) /* Preemptable packet in LUT_DATA[6] register */ -#define LUT_PREEMPT OSI_BIT(11) +#define MACSEC_LUT_PREEMPT OSI_BIT(11) /* Preempt mask in LUT_DATA[6] register */ -#define LUT_PREEMPT_INACTIVE OSI_BIT(12) +#define MACSEC_LUT_PREEMPT_INACTIVE OSI_BIT(12) /* Controlled port mask in LUT_DATA[6] register */ -#define LUT_CONTROLLED_PORT OSI_BIT(13) +#define MACSEC_LUT_CONTROLLED_PORT OSI_BIT(13) /* DVLAN packet in LUT_DATA[6] register */ -#define BYP_LUT_DVLAN_PKT OSI_BIT(14) +#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 LUT_AN0_VALID OSI_BIT(13) -#define LUT_AN1_VALID OSI_BIT(14) -#define LUT_AN2_VALID OSI_BIT(15) -#define LUT_AN3_VALID OSI_BIT(16) +#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 TX_SCI_LUT_DVLAN_PKT OSI_BIT(21) +#define MACSEC_TX_SCI_LUT_DVLAN_PKT OSI_BIT(21) /* DVLAN outer/inner tag select in LUT_DATA[6] register */ -#define TX_SCI_LUT_DVLAN_OUTER_INNER_TAG_SEL OSI_BIT(22) +#define MACSEC_TX_SCI_LUT_DVLAN_OUTER_INNER_TAG_SEL OSI_BIT(22) /* SA State LUT entry valid in LUT_DATA[0] register */ -#define SA_STATE_LUT_ENTRY_VALID OSI_BIT(0) +#define MACSEC_SA_STATE_LUT_ENTRY_VALID OSI_BIT(0) /* Preemptable packet in LUT_DATA[2] register for Rx SCI */ -#define RX_SCI_LUT_PREEMPT OSI_BIT(8) +#define MACSEC_RX_SCI_LUT_PREEMPT OSI_BIT(8) /* Preempt mask in LUT_DATA[2] register for Rx SCI */ -#define RX_SCI_LUT_PREEMPT_INACTIVE OSI_BIT(9) +#define MACSEC_RX_SCI_LUT_PREEMPT_INACTIVE OSI_BIT(9) /** @} */ /* debug buffer data read/write length */ From dc9664175430fa4d14dd11d9a229888e9e81eb37 Mon Sep 17 00:00:00 2001 From: Mahesh Patil <maheshp@nvidia.com> Date: Tue, 13 Jul 2021 18:18:41 -0700 Subject: [PATCH 257/458] nvethernetrm: adjust macsec mtu configuration Adjust macsec mtu setting as osi_core->mtu is not reducing mtu for macsec SECTAG Bug 200730979 Change-Id: I69399b5b9ebd04b5c2c8964bab5b6635f66cfef8 Signed-off-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2558623 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: svc_kernel_abi <svc_kernel_abi@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/macsec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osi/core/macsec.c b/osi/core/macsec.c index 6c77b51..ae85c5f 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -2466,7 +2466,7 @@ static nve32_t macsec_init(struct osi_core_priv_data *const osi_core) 0xC2, 0x80, 0x01}; nveu8_t mac_da_bc[OSI_ETH_ALEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; - nveu32_t mtu = osi_core->mtu + MACSEC_TAG_ICV_LEN; + nveu32_t mtu = osi_core->mtu; nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; nve32_t ret = 0; nveu16_t i, j; From 766d92adc846a5d47f832febf964a2ef5e9592ce Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Sat, 10 Jul 2021 22:11:58 +0530 Subject: [PATCH 258/458] nvethrnetrm: add debug prints and validation function issue: 1) Missing code related to GCL validation in MGBE 2) Missing debug prints Fix: Fix above issues 1) Add call for validate GCL entries for MGBE 2) Add debug prints for all errors before return Bug 200622871 Change-Id: I060597fec2de1cb17b80c0c14f257401d3ff8d31 Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2557029 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: svc_kernel_abi <svc_kernel_abi@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/core_local.h | 4 ++ osi/core/eqos_core.c | 101 ++++++++++++++++++++++++++------------- osi/core/mgbe_core.c | 107 ++++++++++++++++++++++++++++-------------- 3 files changed, 145 insertions(+), 67 deletions(-) diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 7d31847..0e264a6 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -291,6 +291,10 @@ struct core_local { 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; }; /** diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index aea2057..3e8d37c 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1885,6 +1885,43 @@ static inline void eqos_enable_fpe_interrupts( 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}; + 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]; + } + + 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 * @@ -1909,6 +1946,7 @@ static void eqos_tsn_init(struct osi_core_priv_data *osi_core, 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); @@ -4375,48 +4413,24 @@ static int eqos_hw_est_write(struct osi_core_priv_data *osi_core, static inline int eqos_gcl_validate(struct osi_core_priv_data *osi_core, struct osi_est_config *est) { - unsigned int wid_val = 0x0U; - unsigned int dep = 0x0U; + struct core_local *l_core = (struct core_local *)osi_core; unsigned int i; - if (osi_core->hw_feature == OSI_NULL) { + if (est->llr > l_core->gcl_dep) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "HW feature is NULL\n", 0ULL); - return -1; - } - - if (osi_core->hw_feature->gcl_width == 0x1U) { - wid_val = OSI_MAX_24BITS; - } else if (osi_core->hw_feature->gcl_width == 0x2U) { - wid_val = OSI_MAX_28BITS; - } else if (osi_core->hw_feature->gcl_width == 0x3U) { - wid_val = OSI_MAX_32BITS; - } else { - /* Do Nothing */ - } - - if (osi_core->hw_feature->gcl_depth == 0x1U) { - dep = OSI_GCL_SIZE_64; - } else if (osi_core->hw_feature->gcl_depth == 0x2U) { - dep = OSI_GCL_SIZE_128; - } else if (osi_core->hw_feature->gcl_depth == 0x3U) { - dep = OSI_GCL_SIZE_256; - } else if (osi_core->hw_feature->gcl_depth == 0x4U) { - dep = OSI_GCL_SIZE_512; - } else if (osi_core->hw_feature->gcl_depth == 0x5U) { - dep = OSI_GCL_SIZE_1024; - } else { - /* Do Nothing */ - } - - if (est->llr > dep) { + "input argument more than GCL depth\n", + (unsigned long long)est->llr); return -1; } for (i = 0U; i < est->llr; i++) { - if (est->gcl[i] <= wid_val) { + if (est->gcl[i] <= l_core->gcl_width_val) { continue; } + + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "validation of GCL entry failed\n", + (unsigned long long)i); return -1; } @@ -4473,12 +4487,16 @@ static int eqos_hw_config_est(struct osi_core_priv_data *osi_core, } if (eqos_gcl_validate(osi_core, est) < 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 @@ -4487,18 +4505,24 @@ static int eqos_hw_config_est(struct osi_core_priv_data *osi_core, 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; } @@ -4510,6 +4534,9 @@ static int eqos_hw_config_est(struct osi_core_priv_data *osi_core, 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; } } @@ -4526,12 +4553,20 @@ static int eqos_hw_config_est(struct osi_core_priv_data *osi_core, 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; } diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index d70aae1..fb2e54f 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -2893,6 +2893,43 @@ static inline void mgbe_enable_fpe_interrupts( 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}; + 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]; + } + + 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 * @@ -2917,6 +2954,7 @@ static void mgbe_tsn_init(struct osi_core_priv_data *osi_core, 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); @@ -4441,49 +4479,24 @@ static int mgbe_hw_est_write(struct osi_core_priv_data *osi_core, static inline int mgbe_gcl_validate(struct osi_core_priv_data *osi_core, struct osi_est_config *est) { - unsigned int wid_val = 0x0U; - unsigned int dep = 0x0U; + struct core_local *l_core = (struct core_local *)osi_core; unsigned int i; - if (osi_core->hw_feature == OSI_NULL) { + if (est->llr > l_core->gcl_dep) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "HW feature is NULL\n", 0ULL); - return -1; - } - - if (osi_core->hw_feature->gcl_width == 0x1U) { - wid_val = OSI_MAX_24BITS; - } else if (osi_core->hw_feature->gcl_width == 0x2U) { - wid_val = OSI_MAX_28BITS; - } else if (osi_core->hw_feature->gcl_width == 0x3U) { - wid_val = OSI_MAX_32BITS; - } else { - /* Do Nothing */ - } - - if (osi_core->hw_feature->gcl_depth == 0x1U) { - dep = OSI_GCL_SIZE_64; - } else if (osi_core->hw_feature->gcl_depth == 0x2U) { - dep = OSI_GCL_SIZE_128; - } else if (osi_core->hw_feature->gcl_depth == 0x3U) { - dep = OSI_GCL_SIZE_256; - } else if (osi_core->hw_feature->gcl_depth == 0x4U) { - dep = OSI_GCL_SIZE_512; - } else if (osi_core->hw_feature->gcl_depth == 0x5U) { - dep = OSI_GCL_SIZE_1024; - } else { - /* Do Nothing */ - } - - if (est->llr > dep) { + "input argument more than GCL depth\n", + (unsigned long long)est->llr); return -1; } for (i = 0U; i < est->llr; i++) { - if (est->gcl[i] <= wid_val) { + if (est->gcl[i] <= l_core->gcl_width_val) { continue; } + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "validation of GCL entry failed\n", + (unsigned long long)i); return -1; } @@ -4526,7 +4539,7 @@ static int mgbe_hw_config_est(struct osi_core_priv_data *osi_core, 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); + "EST not supported in HW\n", 0ULL); return -1; } @@ -4539,8 +4552,17 @@ static int mgbe_hw_config_est(struct osi_core_priv_data *osi_core, return 0; } + + if (mgbe_gcl_validate(osi_core, est) < 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 @@ -4548,16 +4570,22 @@ static int mgbe_hw_config_est(struct osi_core_priv_data *osi_core, 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; } @@ -4568,6 +4596,9 @@ static int mgbe_hw_config_est(struct osi_core_priv_data *osi_core, 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; } } @@ -4583,12 +4614,20 @@ static int mgbe_hw_config_est(struct osi_core_priv_data *osi_core, 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; } From 97e460939191d1e42dddf3be68de06c20d0882b0 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Thu, 15 Jul 2021 13:18:06 +0530 Subject: [PATCH 259/458] osi: Update MGBE MAC version On uFPGA MGBE MAC version is 0x31 and it got updated to 0x40 on silicon. Bug 200751806 Change-Id: Ic9d35b7a36cff158dd17feeddce6267a3ec2a082 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2559464 Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: svc_kernel_abi <svc_kernel_abi@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_common.h | 1 + osi/common/common.h | 1 + osi/dma/debug.c | 1 + 3 files changed, 3 insertions(+) mode change 100755 => 100644 osi/common/common.h diff --git a/include/osi_common.h b/include/osi_common.h index c159685..93a0daf 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -220,6 +220,7 @@ #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 diff --git a/osi/common/common.h b/osi/common/common.h old mode 100755 new mode 100644 index 105be69..3969e3c --- a/osi/common/common.h +++ b/osi/common/common.h @@ -265,6 +265,7 @@ static inline nve32_t validate_mac_ver_update_chans(nveu32_t mac_ver, 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: diff --git a/osi/dma/debug.c b/osi/dma/debug.c index 7a37c97..74f69a2 100644 --- a/osi/dma/debug.c +++ b/osi/dma/debug.c @@ -117,6 +117,7 @@ void reg_dump(struct osi_dma_priv_data *osi_dma) max_addr = 0x14EC; break; case OSI_MGBE_MAC_3_10: + case OSI_MGBE_MAC_4_00: addr = 0x3100; max_addr = 0x35FC; break; From 260d4696240243ab6fc4f3c2199698a765898fdc Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Wed, 14 Jul 2021 18:52:18 +0530 Subject: [PATCH 260/458] osi: Add core debug for registers/structures - Adds core debugging for registers/structures. - Add change to use single macro for CORE and DMA. Bug 200737108 Change-Id: If96af2ef0c39e01b6c1dad74ee11fd820df76a8d Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2559319 Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: svc_kernel_abi <svc_kernel_abi@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_common.h | 13 +++- include/osi_core.h | 10 +++ include/osi_dma.h | 15 ++--- osi/core/debug.c | 148 +++++++++++++++++++++++++++++++++++++++++ osi/core/debug.h | 34 ++++++++++ osi/core/osi_hal.c | 17 ++++- osi/dma/debug.c | 48 ++++++++----- osi/dma/debug.h | 6 +- osi/dma/osi_dma.c | 13 ++-- osi/dma/osi_dma_txrx.c | 24 +++---- 10 files changed, 278 insertions(+), 50 deletions(-) create mode 100644 osi/core/debug.c create mode 100644 osi/core/debug.h diff --git a/include/osi_common.h b/include/osi_common.h index 93a0daf..ac920d2 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -244,9 +244,20 @@ #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 diff --git a/include/osi_core.h b/include/osi_core.h index 7c1973a..84f8e49 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -216,6 +216,10 @@ typedef my_lint_64 nvel64_t; #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 */ /** @} */ /** @@ -990,6 +994,12 @@ struct osd_core_ops { 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 diff --git a/include/osi_dma.h b/include/osi_dma.h index 6252332..a6fe4d3 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -241,13 +241,10 @@ * @brief Helper macros for OSI dma debugging. * @{ */ -#ifdef OSI_DMA_DEBUG +#ifdef OSI_DEBUG #define OSI_DMA_IOCTL_CMD_REG_DUMP 1U #define OSI_DMA_IOCTL_CMD_STRUCTS_DUMP 2U -#define OSI_DMA_DEBUG_DESC 1U -#define OSI_DMA_DEBUG_REG 2U -#define OSI_DMA_DEBUG_STRUCTS 3U -#endif /* OSI_DMA_DEBUG */ +#endif /* OSI_DEBUG */ /** @} */ /** @@ -506,12 +503,12 @@ struct osd_dma_ops { nveul64_t loga); /**.ops_log function callback */ void (*udelay)(nveu64_t usec); -#ifdef OSI_DMA_DEBUG +#ifdef OSI_DEBUG /**.printf function callback */ void (*printf)(struct osi_dma_priv_data *osi_dma, nveu32_t type, const char *fmt, ...); -#endif +#endif /* OSI_DEBUG */ }; /** @@ -587,10 +584,10 @@ struct osi_dma_priv_data { unsigned int ptp_flag; /** OSI DMA IOCTL data */ struct osi_dma_ioctl_data ioctl_data; -#ifdef OSI_DMA_DEBUG +#ifdef OSI_DEBUG /** Flag to enable/disable descriptor dump */ nveu32_t enable_desc_dump; -#endif +#endif /* OSI_DEBUG */ }; /** diff --git a/osi/core/debug.c b/osi/core/debug.c new file mode 100644 index 0000000..8b16296 --- /dev/null +++ b/osi/core/debug.c @@ -0,0 +1,148 @@ +/* + * 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 new file mode 100644 index 0000000..5029510 --- /dev/null +++ b/osi/core/debug.h @@ -0,0 +1,34 @@ +/* + * 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 <osi_core.h> +#include <osi_macsec.h> +#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/osi_hal.c b/osi/core/osi_hal.c index 9db7511..351adbd 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -26,6 +26,9 @@ #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. @@ -156,6 +159,9 @@ static nve32_t osi_hal_init_core_ops(struct osi_core_priv_data *const osi_core) 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; } @@ -1644,7 +1650,16 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, free_tx_ts(osi_core, data->arg1_u32); 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 */ default: OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "CORE: Incorrect command\n", diff --git a/osi/dma/debug.c b/osi/dma/debug.c index 74f69a2..33745dc 100644 --- a/osi/dma/debug.c +++ b/osi/dma/debug.c @@ -20,7 +20,7 @@ * DEALINGS IN THE SOFTWARE. */ -#ifdef OSI_DMA_DEBUG +#ifdef OSI_DEBUG #include "debug.h" /** @@ -38,18 +38,24 @@ static void dump_struct(struct osi_dma_priv_data *osi_dma, 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_DMA_DEBUG_STRUCTS, + 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_DMA_DEBUG_STRUCTS, "%x", + osi_dma->osd_ops.printf(osi_dma, OSI_DEBUG_TYPE_STRUCTS, "%x", ptr[i]); } } @@ -64,13 +70,16 @@ 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_DMA_DEBUG_STRUCTS, - "OSI DMA struct: "); + 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_DMA_DEBUG_STRUCTS, - "OSI DMA Tx/Rx Ring struct: "); + 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)); @@ -79,18 +88,21 @@ void structs_dump(struct osi_dma_priv_data *osi_dma) } - osi_dma->osd_ops.printf(osi_dma, OSI_DMA_DEBUG_STRUCTS, - "OSD DMA ops struct: "); + 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_DMA_DEBUG_STRUCTS, - "OSI local DMA struct: "); + 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_DMA_DEBUG_STRUCTS, - "OSI local ops DMA struct: "); + 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)); } @@ -130,7 +142,7 @@ void reg_dump(struct osi_dma_priv_data *osi_dma) break; reg_val = osi_readl((nveu8_t *)osi_dma->base + addr); - osi_dma->osd_ops.printf(osi_dma, OSI_DMA_DEBUG_REG, + osi_dma->osd_ops.printf(osi_dma, OSI_DEBUG_TYPE_REG, "%x: %x\n", addr, reg_val); addr += 4; } @@ -150,7 +162,7 @@ static void rx_desc_dump(struct osi_dma_priv_data *osi_dma, unsigned int idx, 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_DMA_DEBUG_DESC, + 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))), @@ -181,7 +193,7 @@ static void tx_desc_dump(struct osi_dma_priv_data *osi_dma, unsigned int f_idx, tx_desc = tx_ring->tx_desc + f_idx; ctxt = tx_desc->tdes3 & TDES3_CTXT; - ops->printf(osi_dma, OSI_DMA_DEBUG_DESC, + 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, @@ -202,7 +214,7 @@ static void tx_desc_dump(struct osi_dma_priv_data *osi_dma, unsigned int f_idx, tx_desc = tx_ring->tx_desc + i; ctxt = tx_desc->tdes3 & TDES3_CTXT; - ops->printf(osi_dma, OSI_DMA_DEBUG_DESC, + 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, @@ -241,4 +253,4 @@ void desc_dump(struct osi_dma_priv_data *osi_dma, unsigned int f_idx, break; } } -#endif +#endif /* OSI_DEBUG */ diff --git a/osi/dma/debug.h b/osi/dma/debug.h index 639841d..aca3739 100644 --- a/osi/dma/debug.h +++ b/osi/dma/debug.h @@ -20,8 +20,8 @@ * DEALINGS IN THE SOFTWARE. */ -#ifndef INCLUDED_OSI_DMA_DEBUG_H -#define INCLUDED_OSI_DMA_DEBUG_H +#ifndef INCLUDED_DMA_DEBUG_H +#define INCLUDED_DMA_DEBUG_H #include <osi_common.h> #include <osi_dma.h> @@ -47,4 +47,4 @@ 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_OSI_DMA_DEBUG_H*/ +#endif /* INCLUDED_DMA_DEBUG_H*/ diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index da8d63e..bf18eae 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -24,9 +24,10 @@ #include <local_common.h> #include "hw_desc.h" #include "../osi/common/common.h" -#ifdef OSI_DMA_DEBUG +#ifdef OSI_DEBUG #include "debug.h" -#endif +#endif /* OSI_DEBUG */ + /** * @brief g_dma - DMA local data array. */ @@ -214,9 +215,9 @@ nve32_t osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) 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_DMA_DEBUG +#ifdef OSI_DEBUG (osi_dma->osd_ops.printf == OSI_NULL) || -#endif +#endif /* OSI_DEBUG */ (osi_dma->osd_ops.udelay == OSI_NULL)) { return -1; } @@ -783,14 +784,14 @@ nve32_t osi_dma_ioctl(struct osi_dma_priv_data *osi_dma) data = &osi_dma->ioctl_data; switch (data->cmd) { -#ifdef OSI_DMA_DEBUG +#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 +#endif /* OSI_DEBUG */ default: OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "DMA: Invalid IOCTL command", 0ULL); diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index cf3e3e9..cc07cd6 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -26,9 +26,9 @@ #include "../osi/common/common.h" #include "mgbe_dma.h" #include "local_common.h" -#ifdef OSI_DMA_DEBUG +#ifdef OSI_DEBUG #include "debug.h" -#endif +#endif /* OSI_DEBUG */ static struct desc_ops d_ops[MAX_MAC_IP_TYPES]; @@ -166,12 +166,12 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, if ((rx_desc->rdes3 & RDES3_OWN) == RDES3_OWN) { break; } -#ifdef OSI_DMA_DEBUG +#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_DMA_DEBUG */ +#endif /* OSI_DEBUG */ INCR_RX_DESC_INDEX(rx_ring->cur_rx_idx, 1U); @@ -254,13 +254,13 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, * those are valid. */ ptp_rx_swcx->flags |= OSI_RX_SWCX_REUSE; -#ifdef OSI_DMA_DEBUG +#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_DMA_DEBUG */ +#endif /* OSI_DEBUG */ /* Context descriptor was consumed. Its skb * and DMA mapping will be recycled */ @@ -580,12 +580,12 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, break; } -#ifdef OSI_DMA_DEBUG +#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_DMA_DEBUG */ +#endif /* OSI_DEBUG */ /* check for Last Descriptor */ if ((tx_desc->tdes3 & TDES3_LD) == TDES3_LD) { @@ -934,10 +934,10 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, 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_DMA_DEBUG +#ifdef OSI_DEBUG nveu32_t f_idx = tx_ring->cur_tx_idx; nveu32_t l_idx = 0; -#endif /* OSI_DMA_DEBUG */ +#endif /* OSI_DEBUG */ nve32_t cntx_desc_consumed; nveu32_t pkt_id = 0x0U; nveu32_t desc_cnt = 0U; @@ -1086,13 +1086,13 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, */ dmb_oshst(); -#ifdef OSI_DMA_DEBUG +#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, 1U), (TX_DESC_DUMP | TX_DESC_DUMP_TX), chan); } -#endif /* OSI_DMA_DEBUG */ +#endif /* OSI_DEBUG */ tailptr = tx_ring->tx_desc_phy_addr + (entry * sizeof(struct osi_tx_desc)); From e65ae17db36207eec180c3e988c265940a7b786f Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Sun, 8 Aug 2021 00:55:11 +0530 Subject: [PATCH 261/458] osi: xpcs: fix XPCS wrapper register programming Bug 200760072 Change-Id: I704f8f9e5b46ada7bd4dd6dd09fd43d09f10e906 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2572477 Tested-by: Narayan Reddy <narayanr@nvidia.com> Tested-by: Alex Waterman <alexw@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/xpcs.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/osi/core/xpcs.c b/osi/core/xpcs.c index e098d88..57dc96a 100644 --- a/osi/core/xpcs.c +++ b/osi/core/xpcs.c @@ -218,9 +218,11 @@ static nve32_t xpcs_uphy_lane_bring_up(struct osi_core_priv_data *osi_core, nveu32_t val = 0; nveu32_t count; - val = xpcs_read(xpcs_base, XPCS_WRAP_UPHY_HW_INIT_CTRL); + val = osi_readla(osi_core, + (nveu8_t *)xpcs_base + XPCS_WRAP_UPHY_HW_INIT_CTRL); val |= lane_init_en; - xpcs_write(xpcs_base, XPCS_WRAP_UPHY_HW_INIT_CTRL, val); + osi_writela(osi_core, val, + (nveu8_t *)xpcs_base + XPCS_WRAP_UPHY_HW_INIT_CTRL); count = 0; while (cond == COND_NOT_MET) { @@ -229,7 +231,8 @@ static nve32_t xpcs_uphy_lane_bring_up(struct osi_core_priv_data *osi_core, } count++; - val = xpcs_read(xpcs_base, XPCS_WRAP_UPHY_HW_INIT_CTRL); + 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; @@ -266,7 +269,8 @@ static nve32_t xpcs_check_pcs_lock_status(struct osi_core_priv_data *osi_core) } count++; - val = xpcs_read(xpcs_base, XPCS_WRAP_IRQ_STATUS); + 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 */ @@ -277,7 +281,7 @@ static nve32_t xpcs_check_pcs_lock_status(struct osi_core_priv_data *osi_core) } /* Clear the status */ - xpcs_write(xpcs_base, XPCS_WRAP_IRQ_STATUS, val); + osi_writela(osi_core, val, (nveu8_t *)xpcs_base + XPCS_WRAP_IRQ_STATUS); return 0; } From 9c80dccd48629211c2c98993b6766e62bcf01faa Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Thu, 12 Aug 2021 22:23:15 +0530 Subject: [PATCH 262/458] osi: eqos: Fix queue size config for Orin EQOS Issue: 1) MTL Tx/Rx queue configuration happens by reading HW feature registers from the MAC. 2) For Xavier EQOS RXFIFOSIZE/TXFIFOSIZE - 9 implies MTL queue size 36KB But for Orin EQOS value - 9 implies MTL queue size 64KB. 3) While calculating per queue fifo size 64KB not considered which resulted in wrong configuration which is 36KB and per queue it will be 4KB (36KB/8). 4) For TSO to work properly PBL should be limited to half the size of programmed queue size. With above incorrect programming with PBL - 32 queue size becoming 4KB which is exactly same as programmed queue size. Because of this TSO is not working. Fix: Fix Tx/Rx queue configuration by using 64KB for Orin EQOS. Bug 200761740 Change-Id: I4ed13961133367f4027c2dbf27be28d0990cf3f9 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2575466 GVS: Gerrit_Virtual_Submit Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: Ashish Mhetre <amhetre@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/eqos_core.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 3e8d37c..e4f3ea3 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -645,6 +645,7 @@ static nve32_t eqos_set_mode(struct osi_core_priv_data *const osi_core, * MAC HW is being shared equally among the queues that are * configured. * + * @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. * @@ -658,7 +659,8 @@ static nve32_t eqos_set_mode(struct osi_core_priv_data *const osi_core, * * @retval Queue size that need to be programmed. */ -static nveu32_t eqos_calculate_per_queue_fifo(nveu32_t fifo_size, +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 */ @@ -698,7 +700,11 @@ static nveu32_t eqos_calculate_per_queue_fifo(nveu32_t fifo_size, q_fifo_size = FIFO_SIZE_KB(32U); break; case 9: - q_fifo_size = FIFO_SIZE_KB(36U); + 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); @@ -2128,10 +2134,12 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core, } /* Calculate value of Transmit queue fifo size to be programmed */ - tx_fifo = eqos_calculate_per_queue_fifo(tx_fifo_size, + 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(rx_fifo_size, + rx_fifo = eqos_calculate_per_queue_fifo(osi_core->mac_ver, + rx_fifo_size, osi_core->num_mtl_queues); /* Configure MTL Queues */ From ebcec61ecf283e84efa05fb7a7858d564233d59c Mon Sep 17 00:00:00 2001 From: Mahesh Patil <maheshp@nvidia.com> Date: Mon, 9 Aug 2021 09:15:09 -0700 Subject: [PATCH 263/458] nvethernetrm: Properly apply eqos sot delay mask Fix to apply SOT mask to EQOS_MACSEC_SOT_DELAY to program SOT delay properly Bug 200760072 Change-Id: Ib201c17434ca8ef240dae46568aaca8869f32929 Signed-off-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2573240 Tested-by: Bhadram Varka <vbhadram@nvidia.com> Tested-by: Ashish Mhetre <amhetre@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/macsec.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osi/core/macsec.h b/osi/core/macsec.h index 927a673..5f11a5d 100644 --- a/osi/core/macsec.h +++ b/osi/core/macsec.h @@ -428,7 +428,7 @@ #define MTU_LENGTH_MASK 0xFFFF #define MTU_ADDONS (8 + 14 + 4) #define DVLAN_TAG_ETHERTYPE 0x88A8 -#define SOT_LENGTH_MASK 0x1F +#define SOT_LENGTH_MASK 0xFF #define EQOS_MACSEC_SOT_DELAY 0x4E /** From d82401b7f6269ffb701cc042473d7f50a69ddec1 Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Thu, 12 Aug 2021 08:20:51 +0000 Subject: [PATCH 264/458] eqos: set ssnic to 6 Set SSIN to 6 for EQOS mac version 5.3 Bug 200760072 Change-Id: I72923d42313880dd362b7b6b197269f3495a18de Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2575178 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_core.h | 1 + osi/core/eqos_core.c | 2 ++ osi/core/osi_hal.c | 3 +++ 3 files changed, 6 insertions(+) diff --git a/include/osi_core.h b/include/osi_core.h index 84f8e49..d2d920d 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -272,6 +272,7 @@ typedef my_lint_64 nvel64_t; */ #define OSI_PTP_SSINC_16 16U #define OSI_PTP_SSINC_4 4U +#define OSI_PTP_SSINC_6 6U /** @} */ /** diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index e4f3ea3..3d8cb48 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -4304,6 +4304,8 @@ static void eqos_config_ssir(struct osi_core_priv_data *const osi_core, 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; } diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 351adbd..ce52259 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -837,6 +837,9 @@ nve32_t osi_ptp_configuration(struct osi_core_priv_data *const osi_core, 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); From f39eccd4dd1ebb7da42a4ba51850517fbb59bfe9 Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Mon, 16 Aug 2021 12:57:02 +0530 Subject: [PATCH 265/458] nvethernetrm: enable common interrupt in eqos wrapper Enable EQOS_CORE_SBD_INTR in ETHER_QOS_COMMON_INTR_ENABLE and clear in ETHER_QOS_COMMON_INTR_STATUS. Bug 200760072 Change-Id: Id0e4a6d5704664faf633181d816d3708cb85956a Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2577049 Tested-by: Bhadram Varka <vbhadram@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/eqos_core.c | 22 ++++++++++++++++++++-- osi/core/eqos_core.h | 3 +++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 3d8cb48..43739e3 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1692,6 +1692,15 @@ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) 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) { @@ -2520,8 +2529,17 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *const osi_core) nveu32_t i = 0; nveu32_t dma_sr = 0; nveu32_t dma_ier = 0; - unsigned int mtl_isr = 0; - unsigned int frp_isr = 0U; + nveu32_t mtl_isr = 0; + nveu32_t frp_isr = 0U; + nveu32_t val = 0U; + + if (osi_core->mac_ver >= OSI_EQOS_MAC_5_30) { + val = osi_readla(osi_core, (nveu8_t *)osi_core->base + + EQOS_WRAP_COMMON_INTR_STATUS); + val |= EQOS_MAC_SBD_INTR; + osi_writela(osi_core, val, (nveu8_t *)osi_core->base + + EQOS_WRAP_COMMON_INTR_STATUS); + } dma_isr = osi_readla(osi_core, (nveu8_t *)base + EQOS_DMA_ISR); if (dma_isr == 0U) { diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index a9313f4..02bc699 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -184,6 +184,9 @@ #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 EQOS_WRAP_COMMON_INTR_ENABLE 0x8704 +#define EQOS_WRAP_COMMON_INTR_STATUS 0x8708 +#define EQOS_MAC_SBD_INTR 0x4 /** @} */ /** From f98364d349e1cac2e79cf26fc31fc0467be1e5a4 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Tue, 24 Aug 2021 14:33:54 +0530 Subject: [PATCH 266/458] osi: eqos: mgbe: program SID through HV window Issue: In non-hypervisor configurations SID programmed through RM window. In orin EQOS/MGBE these SID should program through HV window to get reflected in controller register space. Fix: Program SID through HV window Bug 3358505 Bug 200761024 Change-Id: I1db99c85e875aeaf6c692011a0d2fbe16277d288 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2582062 Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_core.h | 2 ++ osi/core/eqos_core.c | 30 ++++++++++++++++++++++-------- osi/core/eqos_core.h | 15 +++++++++++++++ osi/core/mgbe_core.c | 15 ++++++++++++++- osi/core/mgbe_core.h | 24 ++++++++++++++++++++++++ 5 files changed, 77 insertions(+), 9 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index d2d920d..60db8ae 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -1145,6 +1145,8 @@ struct core_padctrl { 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 */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 43739e3..b2830d4 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -2113,15 +2113,29 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core, osi_writela(osi_core, EQOS_MMC_CNTRL_CNTRST, (nveu8_t *)osi_core->base + EQOS_MMC_CNTRL); - /* 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); + if (osi_core->use_virtualization == OSI_DISABLE) { + if ((osi_core->hv_base != OSI_NULL) && + (osi_core->mac_ver == OSI_EQOS_MAC_5_30)) { + osi_writela(osi_core, EQOS_5_30_ASID_CTRL_VAL, + (nveu8_t *)osi_core->hv_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); + osi_writela(osi_core, EQOS_5_30_ASID1_CTRL_VAL, + (nveu8_t *)osi_core->hv_base + + EQOS_AXI_ASID1_CTRL); + } else { + /* 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 */ diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 02bc699..ce58e8e 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -492,6 +492,21 @@ (TEGRA_SID_EQOS_CH6) |\ (TEGRA_SID_EQOS_CH5) |\ (TEGRA_SID_EQOS)) +#define EQOS_5_30_SID (nveu32_t)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 */ diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index fb2e54f..c7c7366 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -3062,7 +3062,20 @@ static void mgbe_dma_chan_to_vmirq_map(struct osi_core_priv_data *osi_core) } } - osi_writel(0xD, (nveu8_t *)osi_core->base + 0x8400); + if ((osi_core->use_virtualization == OSI_DISABLE) && + (osi_core->hv_base != OSI_NULL)) { + osi_writela(osi_core, MGBE_ASID_CTRL_VAL, + (nveu8_t *)osi_core->hv_base + + MGBE_WRAP_AXI_ASID0_CTRL); + + osi_writela(osi_core, MGBE_ASID1_CTRL_VAL, + (nveu8_t *)osi_core->hv_base + + MGBE_WRAP_AXI_ASID1_CTRL); + + osi_writela(osi_core, MGBE_ASID2_CTRL_VAL, + (nveu8_t *)osi_core->hv_base + + MGBE_WRAP_AXI_ASID2_CTRL); + } } diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index b606811..bf8be2d 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -122,6 +122,9 @@ * @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_WRAP_COMMON_INTR_STATUS 0x8708 #define MGBE_VIRT_INTR_APB_CHX_CNTRL(x) (0x8200U + ((x) * 4U)) @@ -670,6 +673,27 @@ #define MGBE_MAC_EXT_CNF_EIPG 0x1U /* TX timestamp */ #define MGBE_MAC_TSS_TXTSC OSI_BIT(15) +#define MGBE_SID_SHIFT_24 24U +#define MGBE_SID_SHIFT_16 16U +#define MGBE_SID_SHIFT_8 8U +#define MGBE_SID (nveu32_t)0x6U +#define MGBE_SID_CH3 ((MGBE_SID) << MGBE_SID_SHIFT_24) +#define MGBE_SID_CH2 ((MGBE_SID) << MGBE_SID_SHIFT_16) +#define MGBE_SID_CH1 ((MGBE_SID) << MGBE_SID_SHIFT_8) +#define MGBE_ASID_CTRL_VAL ((MGBE_SID_CH3) |\ + (MGBE_SID_CH2) |\ + (MGBE_SID_CH1) |\ + (MGBE_SID)) +#define MGBE_SID_CH7 ((MGBE_SID) << MGBE_SID_SHIFT_24) +#define MGBE_SID_CH6 ((MGBE_SID) << MGBE_SID_SHIFT_16) +#define MGBE_SID_CH5 ((MGBE_SID) << MGBE_SID_SHIFT_8) +#define MGBE_ASID1_CTRL_VAL ((MGBE_SID_CH7) |\ + (MGBE_SID_CH6) |\ + (MGBE_SID_CH5) |\ + (MGBE_SID)) +#define MGBE_SID_CH9 ((MGBE_SID) << MGBE_SID_SHIFT_8) +#define MGBE_ASID2_CTRL_VAL ((MGBE_SID_CH9) |\ + (MGBE_SID)) /** @} */ /** From 38c2fea84fb5491a84668eb50e56cfde1276b40c Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Wed, 25 Aug 2021 19:30:28 -0700 Subject: [PATCH 267/458] Revert "osi: eqos: mgbe: program SID through HV window" This reverts commit b16c09af3b0cd4ba0d068613bb81912df05225fa. Reason for revert: Created regression for AV + L Bug 3358505 Bug 200761024 Change-Id: I31fbd921f9655cd62073918be9d4151f5cc29f8b Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2584378 Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_core.h | 2 -- osi/core/eqos_core.c | 30 ++++++++---------------------- osi/core/eqos_core.h | 15 --------------- osi/core/mgbe_core.c | 15 +-------------- osi/core/mgbe_core.h | 24 ------------------------ 5 files changed, 9 insertions(+), 77 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 60db8ae..d2d920d 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -1145,8 +1145,6 @@ struct core_padctrl { 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 */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index b2830d4..43739e3 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -2113,29 +2113,15 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core, 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_core->mac_ver == OSI_EQOS_MAC_5_30)) { - osi_writela(osi_core, EQOS_5_30_ASID_CTRL_VAL, - (nveu8_t *)osi_core->hv_base + - EQOS_AXI_ASID_CTRL); + /* 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); - osi_writela(osi_core, EQOS_5_30_ASID1_CTRL_VAL, - (nveu8_t *)osi_core->hv_base + - EQOS_AXI_ASID1_CTRL); - } else { - /* 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); - } - } + /* 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 */ diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index ce58e8e..02bc699 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -492,21 +492,6 @@ (TEGRA_SID_EQOS_CH6) |\ (TEGRA_SID_EQOS_CH5) |\ (TEGRA_SID_EQOS)) -#define EQOS_5_30_SID (nveu32_t)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 */ diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index c7c7366..fb2e54f 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -3062,20 +3062,7 @@ static void mgbe_dma_chan_to_vmirq_map(struct osi_core_priv_data *osi_core) } } - if ((osi_core->use_virtualization == OSI_DISABLE) && - (osi_core->hv_base != OSI_NULL)) { - osi_writela(osi_core, MGBE_ASID_CTRL_VAL, - (nveu8_t *)osi_core->hv_base + - MGBE_WRAP_AXI_ASID0_CTRL); - - osi_writela(osi_core, MGBE_ASID1_CTRL_VAL, - (nveu8_t *)osi_core->hv_base + - MGBE_WRAP_AXI_ASID1_CTRL); - - osi_writela(osi_core, MGBE_ASID2_CTRL_VAL, - (nveu8_t *)osi_core->hv_base + - MGBE_WRAP_AXI_ASID2_CTRL); - } + osi_writel(0xD, (nveu8_t *)osi_core->base + 0x8400); } diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index bf8be2d..b606811 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -122,9 +122,6 @@ * @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_WRAP_COMMON_INTR_STATUS 0x8708 #define MGBE_VIRT_INTR_APB_CHX_CNTRL(x) (0x8200U + ((x) * 4U)) @@ -673,27 +670,6 @@ #define MGBE_MAC_EXT_CNF_EIPG 0x1U /* TX timestamp */ #define MGBE_MAC_TSS_TXTSC OSI_BIT(15) -#define MGBE_SID_SHIFT_24 24U -#define MGBE_SID_SHIFT_16 16U -#define MGBE_SID_SHIFT_8 8U -#define MGBE_SID (nveu32_t)0x6U -#define MGBE_SID_CH3 ((MGBE_SID) << MGBE_SID_SHIFT_24) -#define MGBE_SID_CH2 ((MGBE_SID) << MGBE_SID_SHIFT_16) -#define MGBE_SID_CH1 ((MGBE_SID) << MGBE_SID_SHIFT_8) -#define MGBE_ASID_CTRL_VAL ((MGBE_SID_CH3) |\ - (MGBE_SID_CH2) |\ - (MGBE_SID_CH1) |\ - (MGBE_SID)) -#define MGBE_SID_CH7 ((MGBE_SID) << MGBE_SID_SHIFT_24) -#define MGBE_SID_CH6 ((MGBE_SID) << MGBE_SID_SHIFT_16) -#define MGBE_SID_CH5 ((MGBE_SID) << MGBE_SID_SHIFT_8) -#define MGBE_ASID1_CTRL_VAL ((MGBE_SID_CH7) |\ - (MGBE_SID_CH6) |\ - (MGBE_SID_CH5) |\ - (MGBE_SID)) -#define MGBE_SID_CH9 ((MGBE_SID) << MGBE_SID_SHIFT_8) -#define MGBE_ASID2_CTRL_VAL ((MGBE_SID_CH9) |\ - (MGBE_SID)) /** @} */ /** From 8e3743f7571615be76430f007910a11e34c2ad0e Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Fri, 20 Aug 2021 03:05:35 +0530 Subject: [PATCH 268/458] osi: core: xpcs: modify lane bringup sequence Issue: there is a PHY reset(RX_PCS_PHY_RDY) programming in Rx sequence that was disabling the Tx path from MGBE PCS Fix: Control entire programming sequence from SW and by pass HW FSM Bug 3359851 Bug 200765222 Change-Id: Iffd00d1dff00204e36eb3a14b19c07dcd3a502b8 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2584394 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/xpcs.c | 120 +++++++++++++++++++++++++++++++++++++++++++++--- osi/core/xpcs.h | 13 +++++- 2 files changed, 125 insertions(+), 8 deletions(-) diff --git a/osi/core/xpcs.c b/osi/core/xpcs.c index 57dc96a..001a197 100644 --- a/osi/core/xpcs.c +++ b/osi/core/xpcs.c @@ -299,6 +299,13 @@ static nve32_t xpcs_check_pcs_lock_status(struct osi_core_priv_data *osi_core) */ static nve32_t xpcs_lane_bring_up(struct osi_core_priv_data *osi_core) { + unsigned int retry = 1000; + unsigned int count; + int cond; + nveu32_t cnt = 0; + nveu32_t val = 0; +#define PCS_RETRY_MAX 300 + 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, @@ -306,16 +313,115 @@ static nve32_t xpcs_lane_bring_up(struct osi_core_priv_data *osi_core) return -1; } - if (xpcs_uphy_lane_bring_up(osi_core, - XPCS_WRAP_UPHY_HW_INIT_CTRL_RX_EN) < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "UPHY RX 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); + } } - if (xpcs_check_pcs_lock_status(osi_core) < 0) { + /* 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); + + + while (cnt < PCS_RETRY_MAX) { + /* 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) { + cnt += 1; + osi_core->osd_ops.udelay(1000U); + } else { + OSI_CORE_INFO(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + "PCS block lock SUCCESS\n", 0ULL); + break; + } + } + + if (cnt == PCS_RETRY_MAX) { OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "PCS block lock not achieved\n", 0ULL); + "Failed to get PCS block lock after max retries\n", + cnt); return -1; } diff --git a/osi/core/xpcs.h b/osi/core/xpcs.h index caec9f6..f5e85a1 100644 --- a/osi/core/xpcs.h +++ b/osi/core/xpcs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -55,6 +55,7 @@ #define XPCS_VR_XS_PCS_EEE_MCTRL0 0xE00018 #define XPCS_WRAP_UPHY_HW_INIT_CTRL 0x8020 #define XPCS_WRAP_IRQ_STATUS 0x8050 +#define XPCS_WRAP_UPHY_RX_CONTROL_0_0 0x801C /** @} */ @@ -93,6 +94,16 @@ #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) + /** @} */ int xpcs_init(struct osi_core_priv_data *osi_core); From 6815e75ef36cc15da3ff5adbbd47be3de7974105 Mon Sep 17 00:00:00 2001 From: Bitan Biswas <bbiswas@nvidia.com> Date: Wed, 1 Sep 2021 02:47:17 -0700 Subject: [PATCH 269/458] scripts: upgrade to k5.10 checkpatch.pl Upgrade kernel/nvethernetrm checkpatch.pl to k5.10 version Bug 200712834 Change-Id: I35477ec2cc6e6ecb829e88db95111b50f1657b67 Signed-off-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2587203 GVS: Gerrit_Virtual_Submit Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: Sachin Nikam <snikam@nvidia.com> Reviewed-by: Ketan Patil <ketanp@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- scripts/checkpatch.pl | 1365 ++++++++++++++++++++++-------- scripts/const_structs.checkpatch | 4 + scripts/spelling.txt | 296 ++++++- 3 files changed, 1285 insertions(+), 380 deletions(-) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index fcb0dd1..d898e1a 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1,9 +1,11 @@ #!/usr/bin/env perl +# SPDX-License-Identifier: GPL-2.0 +# # (c) 2001, Dave Jones. (the file handling bit) # (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit) # (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite) # (c) 2008-2010 Andy Whitcroft <apw@canonical.com> -# Licensed under the terms of the GNU GPL License version 2 +# (c) 2010-2018 Joe Perches <joe@perches.com> use strict; use warnings; @@ -11,6 +13,7 @@ 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)); @@ -41,6 +44,8 @@ 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 = (); @@ -49,7 +54,7 @@ my %ignore_type = (); my @ignore = (); my $help = 0; my $configuration_file = ".checkpatch.conf"; -my $max_line_length = 80; +my $max_line_length = 100; my $ignore_perl_version = 0; my $minimum_perl_version = 5.10.0; my $min_conf_desc_length = 4; @@ -57,9 +62,13 @@ 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 $typedefsfile; my $color = "auto"; -my $allow_c99_comments = 1; +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) = @_; @@ -93,8 +102,11 @@ Options: --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, if exceeded, warn + --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 @@ -120,6 +132,8 @@ Options: --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. @@ -213,6 +227,7 @@ GetOptions( '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, @@ -228,6 +243,7 @@ GetOptions( '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); @@ -239,13 +255,15 @@ 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; - if (!$ignore_perl_version) { - exit(1); - } + exit(1) if (!$ignore_perl_version); } #if no filenames are given, push '-' to read patch from stdin @@ -262,9 +280,12 @@ if ($color =~ /^[01]$/) { } elsif ($color =~ /^auto$/i) { $color = (-t STDOUT); } else { - die "Invalid color mode: $color\n"; + 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) = @_; @@ -347,9 +368,10 @@ our $Sparse = qr{ __force| __iomem| __must_check| - __init_refok| __kprobes| __ref| + __refconst| + __refdata| __rcu| __private }x; @@ -379,6 +401,7 @@ our $Attribute = qr{ __noclone| __deprecated| __read_mostly| + __ro_after_init| __kprobes| $InitAttribute| ____cacheline_aligned| @@ -457,14 +480,26 @@ 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:| @@ -562,12 +597,36 @@ our @mode_permission_funcs = ( ["__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 | @@ -602,6 +661,37 @@ 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| @@ -677,7 +767,7 @@ sub read_words { next; } - $$wordsRef .= '|' if ($$wordsRef ne ""); + $$wordsRef .= '|' if (defined $$wordsRef); $$wordsRef .= $line; } close($file); @@ -687,16 +777,18 @@ sub read_words { return 0; } -my $const_structs = ""; -read_words(\$const_structs, $conststructsfile) - or warn "No structs that should be const will be found - file '$conststructsfile': $!\n"; +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"; +} -my $typeOtherTypedefs = ""; -if (length($typedefsfile)) { +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); } -$typeTypedefs .= '|' . $typeOtherTypedefs if ($typeOtherTypedefs ne ""); sub build_types { my $mods = "(?x: \n" . join("|\n ", (@modifierList, @modifierListFile)) . "\n)"; @@ -735,12 +827,12 @@ sub build_types { }x; $Type = qr{ $NonptrType - (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)? + (?:(?:\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*\])+)? + (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4} (?:\s+$Inline|\s+$Modifier)* }x; $Declare = qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type}; @@ -761,7 +853,7 @@ 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*\(| - (?:$Storage\s+)?${Type}\s+uninitialized_var\s*\( + (?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\( )}; sub deparenthesize { @@ -804,14 +896,29 @@ sub seed_camelcase_file { } } +our %maintained_status = (); + sub is_maintained_obsolete { my ($filename) = @_; return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl")); - my $status = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`; + 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 $status =~ /obsolete/i; + 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; @@ -824,8 +931,8 @@ sub seed_camelcase_includes { $camelcase_seeded = 1; - if (-e ".git") { - my $git_last_include_commit = `git log --no-merges --pretty=format:"%h%n" -1 -- include`; + 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 { @@ -852,8 +959,8 @@ sub seed_camelcase_includes { return; } - if (-e ".git") { - $files = `git ls-files "include/*.h"`; + if (-e "$gitroot") { + $files = `${git_command} ls-files "include/*.h"`; @include_files = split('\n', $files); } @@ -872,18 +979,28 @@ sub seed_camelcase_includes { } } +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 ".git")); + return ($id, $desc) if ((which("git") eq "") || !(-e "$gitroot")); - my $output = `git log --no-color --format='%H %s' -1 $commit 2>&1`; + 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\./) { + 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... # @@ -914,7 +1031,7 @@ 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 ".git"); +die "$P: No git repository found\n" if ($git && !-e "$gitroot"); if ($git) { my @commits = (); @@ -927,7 +1044,7 @@ if ($git) { } else { $git_range = "-1 $commit_expr"; } - my $lines = `git log --no-color --no-merges --pretty=format:'%H %s' $git_range`; + 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)); @@ -942,8 +1059,12 @@ if ($git) { } 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"; @@ -966,6 +1087,7 @@ for my $filename (@ARGV) { while (<$FILE>) { chomp; push(@rawlines, $_); + $vname = qq("$1") if ($filename eq '-' && $_ =~ m/^Subject:\s+(.+)/i); } close($FILE); @@ -987,17 +1109,18 @@ for my $filename (@ARGV) { @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 ($^V lt 5.10.0) { + if (!$perl_version_ok) { print << "EOM" NOTE: perl $^V is not modern enough to detect all possible issues. - An upgrade to at least perl v5.10.0 is suggested. + An upgrade to at least perl $minimum_perl_version is suggested. EOM } if ($exit) { @@ -1032,6 +1155,7 @@ sub parse_email { my ($formatted_email) = @_; my $name = ""; + my $name_comment = ""; my $address = ""; my $comment = ""; @@ -1045,7 +1169,7 @@ sub parse_email { } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) { $address = $1; $comment = $2 if defined $2; - $formatted_email =~ s/$address.*$//; + $formatted_email =~ s/\Q$address\E.*$//; $name = $formatted_email; $name = trim($name); $name =~ s/^\"|\"$//g; @@ -1062,8 +1186,12 @@ sub parse_email { } } + $comment = trim($comment); $name = trim($name); $name =~ s/^\"|\"$//g; + if ($name =~ s/(\s*\([^\)]+\))\s*//) { + $name_comment = trim($1); + } $address = trim($address); $address =~ s/^\<|\>$//g; @@ -1072,14 +1200,16 @@ sub parse_email { $name = "\"$name\""; } - return ($name, $address, $comment); + return ($name, $name_comment, $address, $comment); } sub format_email { - my ($name, $address) = @_; + my ($name, $name_comment, $address, $comment) = @_; my $formatted_email; + $name_comment = trim($name_comment); + $comment = trim($comment); $name = trim($name); $name =~ s/^\"|\"$//g; $address = trim($address); @@ -1092,12 +1222,35 @@ sub format_email { if ("$name" eq "") { $formatted_email = "$address"; } else { - $formatted_email = "$name <$address>"; + $formatted_email = "$name$name_comment <$address>"; } - + $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) = @_; @@ -1131,7 +1284,7 @@ sub expand_tabs { if ($c eq "\t") { $res .= ' '; $n++; - for (; ($n % 8) != 0; $n++) { + for (; ($n % $tabsize) != 0; $n++) { $res .= ' '; } next; @@ -1187,7 +1340,7 @@ sub sanitise_line { for ($off = 1; $off < length($line); $off++) { $c = substr($line, $off, 1); - # Comments we are wacking completly including the begin + # Comments we are whacking completely including the begin # and end, all to $;. if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') { $sanitise_quote = '*/'; @@ -1267,6 +1420,7 @@ sub sanitise_line { 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]); } @@ -1559,8 +1713,16 @@ sub ctx_statement_level { 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. - my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@); + ($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 @@ -1614,6 +1776,28 @@ sub raw_line { 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); @@ -2121,7 +2305,7 @@ sub string_find_replace { sub tabify { my ($leading) = @_; - my $source_indent = 8; + my $source_indent = $tabsize; my $max_spaces_before_tab = $source_indent - 1; my $spaces_to_tab = " " x $source_indent; @@ -2163,6 +2347,19 @@ sub pos_last_openparen { 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; @@ -2179,10 +2376,16 @@ sub process { 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; @@ -2227,6 +2430,8 @@ sub process { my $camelcase_file_seeded = 0; + my $checklicenseline = 1; + sanitise_line_reset(); my $line; foreach my $rawline (@rawlines) { @@ -2237,7 +2442,7 @@ sub process { if ($rawline=~/^\+\+\+\s+(\S+)/) { $setup_docs = 0; - if ($1 =~ m@Documentation/admin-guide/kernel-parameters.rst$@) { + if ($1 =~ m@Documentation/admin-guide/kernel-parameters.txt$@) { $setup_docs = 1; } #next; @@ -2318,6 +2523,15 @@ sub process { $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 && @@ -2418,6 +2632,20 @@ sub process { } 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; } @@ -2429,10 +2657,22 @@ sub process { $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+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", @@ -2450,14 +2690,67 @@ sub process { } } +# 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:/i) { + 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; } @@ -2505,8 +2798,8 @@ sub process { } } - my ($email_name, $email_address, $comment) = parse_email($email); - my $suggested_email = format_email(($email_name, $email_address)); + 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); @@ -2516,11 +2809,9 @@ sub process { $dequoted =~ s/" </ </; # Don't force email to have quotes # Allow just an angle bracketed address - if ("$dequoted$comment" ne $email && - "<$email_address>$comment" ne $email && - "$suggested_email$comment" ne $email) { + if (!same_email_addresses($email, $suggested_email, 0)) { WARN("BAD_SIGN_OFF", - "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr); + "email address '$email' might be better as '$suggested_email'\n" . $herecurr); } } @@ -2534,6 +2825,24 @@ sub process { } else { $signatures{$sig_nospace} = 1; } + +# Check Co-developed-by: immediately followed by Signed-off-by: with same name and email + if ($sign_off =~ /^co-developed-by:$/i) { + if ($email eq $author) { + WARN("BAD_SIGN_OFF", + "Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . "$here\n" . $rawline); + } + if (!defined $lines[$linenr]) { + WARN("BAD_SIGN_OFF", + "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline); + } elsif ($rawlines[$linenr] !~ /^\s*signed-off-by:\s*(.*)/i) { + WARN("BAD_SIGN_OFF", + "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]); + } elsif ($1 ne $email) { + WARN("BAD_SIGN_OFF", + "Co-developed-by and Signed-off-by: name/email do not match \n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]); + } + } } # Check email subject for common tools that don't need to be mentioned @@ -2543,16 +2852,10 @@ sub process { "A patch subject line should describe the change not the tool that found it\n" . $herecurr); } -# Check for old stable address - if ($line =~ /^\s*cc:\s*.*<?\bstable\@kernel\.org\b>?.*$/i) { - ERROR("STABLE_ADDRESS", - "The 'stable' address should be 'stable\@vger.kernel.org'\n" . $herecurr); - } - -# Check for unwanted Gerrit info - if ($in_commit_log && !$ignore_changeid && $line =~ /^\s*change-id:/i) { +# Check for Gerrit Change-Ids not in any patch context + if ($realfile eq '' && !$has_patch_separator && !$ignore_changeid && $line =~ /^\s*change-id:/i) { ERROR("GERRIT_CHANGE_ID", - "Remove Gerrit Change-Id's before submitting upstream.\n" . $herecurr); + "Remove Gerrit Change-Id's before submitting upstream\n" . $herecurr); } # Check if the commit log is in a possible stack dump @@ -2560,8 +2863,10 @@ sub process { ($line =~ /^\s*(?:WARNING:|BUG:)/ || $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ || # timestamp - $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/)) { - # stack dump address + $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/) || + $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; } @@ -2588,7 +2893,7 @@ sub process { # 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):/i && + $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 && @@ -2657,6 +2962,14 @@ sub process { "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", @@ -2733,6 +3046,53 @@ sub process { } } +# 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 =~ /^-/); @@ -2771,7 +3131,10 @@ sub process { # 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/ && - $line =~ /^\+\s*config\s+/) { + # '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; @@ -2786,7 +3149,7 @@ sub process { next if ($f =~ /^-/); last if (!$file && $f =~ /^\@\@/); - if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate)\s*\"/) { + if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) { $is_start = 1; } elsif ($lines[$ln - 1] =~ /^\+\s*(?:---)?help(?:---)?$/) { $length = -1; @@ -2796,7 +3159,13 @@ sub process { $f =~ s/#.*//; $f =~ s/^\s+//; next if ($f =~ /^$/); - if ($f =~ /^\s*config\s/) { + + # 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; } @@ -2809,14 +3178,43 @@ sub process { #print "is_start<$is_start> is_end<$is_end> length<$length>\n"; } -# check for MAINTAINERS entries that don't have the right form - if ($realfile =~ /^MAINTAINERS$/ && - $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 + 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); + } + } } } @@ -2849,7 +3247,7 @@ sub process { my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g; my $dt_path = $root . "/Documentation/devicetree/bindings/"; - my $vp_file = $dt_path . "vendor-prefixes.txt"; + my $vp_file = $dt_path . "vendor-prefixes.yaml"; foreach my $compat (@compats) { my $compat2 = $compat; @@ -2864,7 +3262,7 @@ sub process { next if $compat !~ /^([a-zA-Z0-9\-]+)\,/; my $vendor = $1; - `grep -Eq "^$vendor\\b" $vp_file`; + `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); @@ -2872,15 +3270,79 @@ sub process { } } +# 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 @@ -2907,8 +3369,13 @@ sub process { $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) { $msg_type = ""; - # EFI_GUID is another special case - } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/) { + # 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 @@ -2926,8 +3393,10 @@ sub process { if ($msg_type ne "" && (show_type("LONG_LINE") || show_type($msg_type))) { - WARN($msg_type, - "line over $max_line_length characters\n" . $herecurr); + my $msg_level = \&WARN; + $msg_level = \&CHK if ($file); + &{$msg_level}($msg_type, + "line length of $length exceeds $max_line_length columns\n" . $herecurr); } } @@ -2937,25 +3406,11 @@ sub process { "adding a line without newline at end of file\n" . $herecurr); } -# Blackfin: use hi/lo macros - if ($realfile =~ m@arch/blackfin/.*\.S$@) { - if ($line =~ /\.[lL][[:space:]]*=.*&[[:space:]]*0x[fF][fF][fF][fF]/) { - my $herevet = "$here\n" . cat_vet($line) . "\n"; - ERROR("LO_MACRO", - "use the LO() macro, not (... & 0xFFFF)\n" . $herevet); - } - if ($line =~ /\.[hH][[:space:]]*=.*>>[[:space:]]*16/) { - my $herevet = "$here\n" . cat_vet($line) . "\n"; - ERROR("HI_MACRO", - "use the HI() macro, not (... >> 16)\n" . $herevet); - } - } - # 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 8 must use tabs. +# more than $tabsize must use tabs. if ($rawline =~ /^\+\s* \t\s*\S/ || $rawline =~ /^\+\s* \s*/) { my $herevet = "$here\n" . cat_vet($rawline) . "\n"; @@ -2974,12 +3429,18 @@ sub process { "please, no space before tabs\n" . $herevet) && $fix) { while ($fixed[$fixlinenr] =~ - s/(^\+.*) {8,8}\t/$1\t\t/) {} + 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", @@ -2987,20 +3448,20 @@ sub process { } # check indentation starts on a tab stop - if ($^V && $^V ge 5.10.0 && - $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$))/) { + 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 % 8) { + if ($indent % $tabsize) { if (WARN("TABSTOP", "Statements should start on a tabstop\n" . $herecurr) && $fix) { - $fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/8)@e; + $fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/$tabsize)@e; } } } # check multi-line statement indentation matches previous line - if ($^V && $^V ge 5.10.0 && + 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; @@ -3012,8 +3473,8 @@ sub process { my $newindent = $2; my $goodtabindent = $oldindent . - "\t" x ($pos / 8) . - " " x ($pos % 8); + "\t" x ($pos / $tabsize) . + " " x ($pos % $tabsize); my $goodspaceindent = $oldindent . " " x $pos; if ($newindent ne $goodtabindent && @@ -3051,7 +3512,7 @@ sub process { if ($realfile =~ m@^(drivers/net/|net/)@ && $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ && $rawline =~ /^\+[ \t]*\*/ && - $realline > 2) { + $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); } @@ -3110,6 +3571,7 @@ sub process { $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) && @@ -3156,7 +3618,7 @@ sub process { # known declaration macros $sline =~ /^\+\s+$declaration_macros/ || # start of struct or union or enum - $sline =~ /^\+\s+(?:union|struct|enum|typedef)\b/ || + $sline =~ /^\+\s+(?:static\s+)?(?:const\s+)?(?:union|struct|enum|typedef)\b/ || # start or end of block or continuation of declaration $sline =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ || # bitfield continuation @@ -3189,6 +3651,12 @@ sub process { # 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)\(/) { @@ -3230,18 +3698,6 @@ sub process { "CVS style keyword markers, these will _not_ be updated\n". $herecurr); } -# Blackfin: don't use __builtin_bfin_[cs]sync - if ($line =~ /__builtin_bfin_csync/) { - my $herevet = "$here\n" . cat_vet($line) . "\n"; - ERROR("CSYNC", - "use the CSYNC() macro in asm/blackfin.h\n" . $herevet); - } - if ($line =~ /__builtin_bfin_ssync/) { - my $herevet = "$here\n" . cat_vet($line) . "\n"; - ERROR("SSYNC", - "use the SSYNC() macro in asm/blackfin.h\n" . $herevet); - } - # check for old HOTPLUG __dev<foo> section markings if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) { WARN("HOTPLUG_SECTION", @@ -3489,11 +3945,11 @@ sub process { #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 % 8) != 0 || + (($sindent % $tabsize) != 0 || ($sindent < $indent) || ($sindent == $indent && ($s !~ /^\s*(?:\}|\{|else\b)/)) || - ($sindent > $indent + 8))) { + ($sindent > $indent + $tabsize))) { WARN("SUSPECT_CODE_INDENT", "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n"); } @@ -3515,6 +3971,17 @@ sub process { #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/) { @@ -3694,19 +4161,48 @@ sub process { "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/) { @@ -3741,7 +4237,7 @@ sub process { } # check for function declarations without arguments like "int foo()" - if ($line =~ /(\b$Type\s+$Ident)\s*\(\s*\)/) { + 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) { @@ -3836,28 +4332,10 @@ sub process { "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr); } -# printk should use KERN_* levels. Note that follow on printk's on the -# same line do not need a level, so we use the current block context -# to try and find and validate the current printk. In summary the current -# printk includes all preceding printk's which have no newline on the end. -# we assume the first bad printk is the one to report. - if ($line =~ /\bprintk\((?!KERN_)\s*"/) { - my $ok = 0; - for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) { - #print "CHECK<$lines[$ln - 1]\n"; - # we have a preceding printk if it ends - # with "\n" ignore it, else it is to blame - if ($lines[$ln - 1] =~ m{\bprintk\(}) { - if ($rawlines[$ln - 1] !~ m{\\n"}) { - $ok = 1; - } - last; - } - } - if ($ok == 0) { - WARN("PRINTK_WITHOUT_KERN_LEVEL", - "printk() should include KERN_ facility level\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]+)/) { @@ -3870,15 +4348,6 @@ sub process { "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(... to printk(KERN_$orig ...\n" . $herecurr); } - if ($line =~ /\bpr_warning\s*\(/) { - if (WARN("PREFER_PR_LEVEL", - "Prefer pr_warn(... to pr_warning(...\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ - s/\bpr_warning\b/pr_warn/; - } - } - if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) { my $orig = $1; my $level = lc($orig); @@ -3888,6 +4357,12 @@ sub process { "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. @@ -3896,16 +4371,29 @@ sub process { "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 (($line=~/$Type\s*$Ident\(.*\).*\s*{/) and - !($line=~/\#\s*define.*do\s\{/) and !($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 declarations go on the next line\n" . $herecurr) && + "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*){(.*)$/; + $fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*)\{(.*)$/; my $line1 = $1; my $line2 = $2; fix_insert_line($fixlinenr, ltrim($line1)); @@ -4022,7 +4510,7 @@ sub process { my ($where, $prefix) = ($-[1], $1); if ($prefix !~ /$Type\s+$/ && ($where != 0 || $prefix !~ /^.\s+$/) && - $prefix !~ /[{,]\s+$/) { + $prefix !~ /[{,:]\s+$/) { if (ERROR("BRACKET_SPACE", "space prohibited before open square bracket '['\n" . $herecurr) && $fix) { @@ -4334,7 +4822,7 @@ sub process { ($op eq '>' && $ca =~ /<\S+\@\S+$/)) { - $ok = 1; + $ok = 1; } # for asm volatile statements @@ -4412,11 +4900,11 @@ sub process { #need space before brace following if, while, etc if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) || - $line =~ /do\{/) { + $line =~ /\b(?:else|do)\{/) { if (ERROR("SPACING", "space required before the open brace '{'\n" . $herecurr) && $fix) { - $fixed[$fixlinenr] =~ s/^(\+.*(?:do|\)))\{/$1 {/; + $fixed[$fixlinenr] =~ s/^(\+.*(?:do|else|\)))\{/$1 {/; } } @@ -4430,7 +4918,7 @@ sub process { # closing brace should have a space following it when it has anything # on the line - if ($line =~ /}(?!(?:,|;|\)))\S/) { + if ($line =~ /}(?!(?:,|;|\)|\}))\S/) { if (ERROR("SPACING", "space required after that close brace '}'\n" . $herecurr) && $fix) { @@ -4505,7 +4993,9 @@ sub process { } # check for unnecessary parentheses around comparisons in if uses - if ($^V && $^V ge 5.10.0 && defined($stat) && +# 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); @@ -4539,10 +5029,21 @@ sub process { } } +# 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 ($^V && $^V ge 5.10.0 && + if ($perl_version_ok && $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) { my $value = $1; $value = deparenthesize($value); @@ -4569,7 +5070,7 @@ sub process { } # if statements using unnecessary parentheses - ie: if ((foo == bar)) - if ($^V && $^V ge 5.10.0 && + if ($perl_version_ok && $line =~ /\bif\s*((?:\(\s*){2,})/) { my $openparens = $1; my $count = $openparens =~ tr@\(@\(@; @@ -4586,7 +5087,7 @@ sub process { # 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 ($^V && $^V ge 5.10.0 && + if ($perl_version_ok && $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) { my $lead = $1; my $const = $2; @@ -4659,15 +5160,37 @@ sub process { my ($s, $c) = ($stat, $cond); if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) { - ERROR("ASSIGN_IN_IF", - "do not use assignment in if condition\n" . $herecurr); + 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 + $s =~ s/$;//g; # Remove any comments if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ && $c !~ /}\s*while\s*/) { @@ -4706,7 +5229,7 @@ sub process { # 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 + $s =~ s/$;//g; # Remove any comments if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) { ERROR("TRAILING_STATEMENTS", "trailing statements should be on next line\n" . $herecurr); @@ -4778,24 +5301,14 @@ sub process { while ($line =~ m{($Constant|$Lval)}g) { my $var = $1; -#gcc binary extension - if ($var =~ /^$Binary$/) { - if (WARN("GCC_BINARY_CONSTANT", - "Avoid gcc v4.3+ binary constant extension: <$var>\n" . $herecurr) && - $fix) { - my $hexval = sprintf("0x%x", oct($var)); - $fixed[$fixlinenr] =~ - s/\b$var\b/$hexval/; - } - } - #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) - $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_[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) { @@ -4876,6 +5389,7 @@ sub process { 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); } @@ -4885,13 +5399,13 @@ sub process { $dstat =~ s/\s*$//s; # Flatten any parentheses and braces - while ($dstat =~ s/\([^\(\)]*\)/1/ || - $dstat =~ s/\{[^\{\}]*\}/1/ || - $dstat =~ s/.\[[^\[\]]*\]/1/) + while ($dstat =~ s/\([^\(\)]*\)/1u/ || + $dstat =~ s/\{[^\{\}]*\}/1u/ || + $dstat =~ s/.\[[^\[\]]*\]/1u/) { } - # Flatten any obvious string concatentation. + # Flatten any obvious string concatenation. while ($dstat =~ s/($String)\s*$Ident/$1/ || $dstat =~ s/$Ident\s*($String)/$1/) { @@ -4916,12 +5430,8 @@ sub process { #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n"; $ctx =~ s/\n*$//; - my $herectx = $here . "\n"; my $stmt_cnt = statement_rawlines($ctx); - - for (my $n = 0; $n < $stmt_cnt; $n++) { - $herectx .= raw_line($linenr, $n) . "\n"; - } + my $herectx = get_stat_here($linenr, $stmt_cnt, $here); if ($dstat ne '' && $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(), @@ -4932,6 +5442,7 @@ sub process { $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 {... @@ -4973,10 +5484,10 @@ sub process { next if ($arg =~ /\.\.\./); next if ($arg =~ /^type$/i); my $tmp_stmt = $define_stmt; - $tmp_stmt =~ s/\b(typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g; + $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 =~ s/\b$arg\b//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"); @@ -4993,12 +5504,9 @@ sub process { # 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 $herectx = $here . "\n"; my $cnt = statement_rawlines($ctx); + my $herectx = get_stat_here($linenr, $cnt, $here); - for (my $n = 0; $n < $cnt; $n++) { - $herectx .= raw_line($linenr, $n) . "\n"; - } WARN("MACRO_WITH_FLOW_CONTROL", "Macros with flow control statements should be avoided\n" . "$herectx"); } @@ -5018,7 +5526,7 @@ sub process { # 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 ($^V && $^V ge 5.10.0 && + if ($perl_version_ok && $realfile !~ m@/vmlinux.lds.h$@ && $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) { my $ln = $linenr; @@ -5038,11 +5546,7 @@ sub process { $ctx =~ s/\n*$//; my $cnt = statement_rawlines($ctx); - my $herectx = $here . "\n"; - - for (my $n = 0; $n < $cnt; $n++) { - $herectx .= raw_line($linenr, $n) . "\n"; - } + my $herectx = get_stat_here($linenr, $cnt, $here); if (($stmts =~ tr/;/;/) == 1 && $stmts !~ /^\s*(if|while|for|switch)\b/) { @@ -5056,27 +5560,13 @@ sub process { } elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) { $ctx =~ s/\n*$//; my $cnt = statement_rawlines($ctx); - my $herectx = $here . "\n"; - - for (my $n = 0; $n < $cnt; $n++) { - $herectx .= raw_line($linenr, $n) . "\n"; - } + my $herectx = get_stat_here($linenr, $cnt, $here); WARN("TRAILING_SEMICOLON", "macros should not use a trailing semicolon\n" . "$herectx"); } } -# make sure symbols are always wrapped with VMLINUX_SYMBOL() ... -# all assignments may have only one of the following with an assignment: -# . -# ALIGN(...) -# VMLINUX_SYMBOL(...) - if ($realfile eq 'vmlinux.lds.h' && $line =~ /(?:(?:^|\s)$Ident\s*=|=\s*$Ident(?:\s|$))/) { - WARN("MISSING_VMLINUX_SYMBOL", - "vmlinux.lds.h needs VMLINUX_SYMBOL() around C-visible symbols\n" . $herecurr); - } - # check for redundant bracing round if etc if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) { my ($level, $endln, @chunks) = @@ -5183,12 +5673,8 @@ sub process { } } if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) { - my $herectx = $here . "\n"; my $cnt = statement_rawlines($block); - - for (my $n = 0; $n < $cnt; $n++) { - $herectx .= raw_line($linenr, $n) . "\n"; - } + my $herectx = get_stat_here($linenr, $cnt, $here); WARN("BRACES", "braces {} are not necessary for single statement blocks\n" . $herectx); @@ -5286,15 +5772,28 @@ sub process { } # concatenated string without spaces between elements - if ($line =~ /$String[A-Z_]/ || $line =~ /[A-Za-z0-9_]$String/) { - CHK("CONCATENATED_STRING", - "Concatenated strings should use spaces between elements\n" . $herecurr); + 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*"/) { - WARN("STRING_FRAGMENTS", - "Consecutive strings are generally better as a single string\n" . $herecurr); + 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 @@ -5323,16 +5822,21 @@ sub process { } # check for line continuations in quoted strings with odd counts of " - if ($rawline =~ /\\$/ && $rawline =~ tr/"/"/ % 2) { + 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/) { - CHK("REDUNDANT_CODE", - "if this code is redundant consider removing it\n" . - $herecurr); + 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 @@ -5379,7 +5883,8 @@ sub process { 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*(?:devm_)?(?:[kv][czm]alloc(?:_node|_array)?\b|kstrdup|kmemdup|(?:dev_)?alloc_skb)/) { + 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); } @@ -5403,7 +5908,7 @@ sub process { } # check for mask then right shift without a parentheses - if ($^V && $^V ge 5.10.0 && + if ($perl_version_ok && $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ && $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so WARN("MASK_THEN_SHIFT", @@ -5411,7 +5916,7 @@ sub process { } # check for pointer comparisons to NULL - if ($^V && $^V ge 5.10.0) { + if ($perl_version_ok) { while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) { my $val = $1; my $equal = "!"; @@ -5500,7 +6005,7 @@ sub process { # ignore udelay's < 10, however if (! ($delay < 10) ) { CHK("USLEEP_RANGE", - "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $herecurr); + "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst\n" . $herecurr); } if ($delay > 2000) { WARN("LONG_UDELAY", @@ -5512,7 +6017,7 @@ sub process { if ($line =~ /\bmsleep\s*\((\d+)\);/) { if ($1 < 20) { WARN("MSLEEP", - "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $herecurr); + "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.rst\n" . $herecurr); } } @@ -5560,8 +6065,7 @@ sub process { my $barriers = qr{ mb| rmb| - wmb| - read_barrier_depends + wmb }x; my $barrier_stems = qr{ mb__before_atomic| @@ -5602,6 +6106,14 @@ sub process { } } +# 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", @@ -5655,6 +6167,18 @@ sub process { "__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/) { @@ -5677,7 +6201,7 @@ sub process { } # Check for __attribute__ weak, or __weak declarations (may have link issues) - if ($^V && $^V ge 5.10.0 && + 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/)) { @@ -5758,34 +6282,58 @@ sub process { } } - # check for vsprintf extension %p<foo> misuses - if ($^V && $^V ge 5.10.0 && +# check for vsprintf extension %p<foo> misuses + if ($perl_version_ok && defined $stat && $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s && $1 !~ /^_*volatile_*$/) { - my $bad_extension = ""; + 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; - if ($fmt =~ /(\%[\*\d\.]*p(?![\WFfSsBKRraEhMmIiUDdgVCbGNO]).)/) { - $bad_extension = $1; - last; + + 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_extension ne "") { - my $stat_real = raw_line($linenr, 0); - for (my $count = $linenr + 1; $count <= $lc; $count++) { - $stat_real = $stat_real . "\n" . raw_line($count, 0); + 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"); } - WARN("VSPRINTF_POINTER_EXTENSION", - "Invalid vsprintf pointer extension '$bad_extension'\n" . "$here\n$stat_real\n"); } } # Check for misused memsets - if ($^V && $^V ge 5.10.0 && + if ($perl_version_ok && defined $stat && $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) { @@ -5803,7 +6351,7 @@ sub process { } # Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar) -# if ($^V && $^V ge 5.10.0 && +# 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", @@ -5814,7 +6362,7 @@ sub process { # } # Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar) -# if ($^V && $^V ge 5.10.0 && +# if ($perl_version_ok && # defined $stat && # $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { # WARN("PREFER_ETHER_ADDR_EQUAL", @@ -5823,7 +6371,7 @@ sub process { # 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 ($^V && $^V ge 5.10.0 && +# if ($perl_version_ok && # defined $stat && # $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { # @@ -5845,7 +6393,7 @@ sub process { # } # typecasts on min/max could be min_t/max_t - if ($^V && $^V ge 5.10.0 && + if ($perl_version_ok && defined $stat && $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) { if (defined $2 || defined $7) { @@ -5869,23 +6417,23 @@ sub process { } # check usleep_range arguments - if ($^V && $^V ge 5.10.0 && + 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.txt\n" . "$here\n$stat\n"); + "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.txt\n" . "$here\n$stat\n"); + "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n"); } } # check for naked sscanf - if ($^V && $^V ge 5.10.0 && + if ($perl_version_ok && defined $stat && $line =~ /\bsscanf\b/ && ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ && @@ -5893,24 +6441,18 @@ sub process { $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) { my $lc = $stat =~ tr@\n@@; $lc = $lc + $linenr; - my $stat_real = raw_line($linenr, 0); - for (my $count = $linenr + 1; $count <= $lc; $count++) { - $stat_real = $stat_real . "\n" . raw_line($count, 0); - } + 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 ($^V && $^V ge 5.10.0 && + if ($perl_version_ok && defined $stat && $line =~ /\bsscanf\b/) { my $lc = $stat =~ tr@\n@@; $lc = $lc + $linenr; - my $stat_real = raw_line($linenr, 0); - for (my $count = $linenr + 1; $count <= $lc; $count++) { - $stat_real = $stat_real . "\n" . raw_line($count, 0); - } + 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@%@%@; @@ -5943,8 +6485,7 @@ sub process { if (defined $cond) { substr($s, 0, length($cond), ''); } - if ($s =~ /^\s*;/ && - $function_name ne 'uninitialized_var') + if ($s =~ /^\s*;/) { WARN("AVOID_EXTERNS", "externs should be avoided in .c files\n" . $herecurr); @@ -5964,7 +6505,7 @@ sub process { # check for function declarations that have arguments without identifier names if (defined $stat && - $stat =~ /^.\s*(?:extern\s+)?$Type\s*$Ident\s*\(\s*([^{]+)\s*\)\s*;/s && + $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) { @@ -5977,7 +6518,7 @@ sub process { } # check for function definitions - if ($^V && $^V ge 5.10.0 && + if ($perl_version_ok && defined $stat && $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) { $context_function = $1; @@ -6005,26 +6546,26 @@ sub process { if (!grep(/$name/, @setup_docs)) { CHK("UNDOCUMENTED_SETUP", - "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.rst\n" . $herecurr); + "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.txt\n" . $herecurr); } } -# check for pointless casting of kmalloc return - if ($line =~ /\*\s*\)\s*[kv][czm]alloc(_node){0,1}\b/) { +# 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 ($^V && $^V ge 5.10.0 && - $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*([kv][mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) { + 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 ($^V && $^V ge 5.10.0 && + 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; @@ -6040,12 +6581,9 @@ sub process { } if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ && !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) { - my $ctx = ''; - my $herectx = $here . "\n"; my $cnt = statement_rawlines($stat); - for (my $n = 0; $n < $cnt; $n++) { - $herectx .= raw_line($linenr, $n) . "\n"; - } + my $herectx = get_stat_here($linenr, $cnt, $here); + if (WARN("ALLOC_WITH_MULTIPLY", "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) && $cnt == 1 && @@ -6056,8 +6594,9 @@ sub process { } # check for krealloc arg reuse - if ($^V && $^V ge 5.10.0 && - $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*\1\s*,/) { + 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); } @@ -6089,51 +6628,51 @@ sub process { } } +# 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*$/) { + 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) && + "Prefer IS_ENABLED(<FOO>) to ${CONFIG_}<FOO> || ${CONFIG_}<FOO>_MODULE\n" . $herecurr) && $fix) { $fixed[$fixlinenr] = "\+#if IS_ENABLED($config)"; } } -# check for case / default statements not preceded by break/fallthrough/switch - if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) { - my $has_break = 0; - my $has_statement = 0; - my $count = 0; - my $prevline = $linenr; - while ($prevline > 1 && ($file || $count < 3) && !$has_break) { - $prevline--; - my $rline = $rawlines[$prevline - 1]; - my $fline = $lines[$prevline - 1]; - last if ($fline =~ /^\@\@/); - next if ($fline =~ /^\-/); - next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/); - $has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i); - next if ($fline =~ /^.[\s$;]*$/); - $has_statement = 1; - $count++; - $has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|return\b|goto\b|continue\b)/); - } - if (!$has_break && $has_statement) { - WARN("MISSING_BREAK", - "Possible switch case/default not preceded by break or fallthrough comment\n" . $herecurr); +# 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 ($^V && $^V ge 5.10.0 && + if ($perl_version_ok && defined $stat && $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) { - my $ctx = ''; - my $herectx = $here . "\n"; my $cnt = statement_rawlines($stat); - for (my $n = 0; $n < $cnt; $n++) { - $herectx .= raw_line($linenr, $n) . "\n"; - } + my $herectx = get_stat_here($linenr, $cnt, $here); + WARN("DEFAULT_NO_BREAK", "switch default: should use break\n" . $herectx); } @@ -6204,9 +6743,24 @@ sub process { "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 ($line !~ /\bconst\b/ && + 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); @@ -6232,12 +6786,18 @@ sub process { } # likely/unlikely comparisons similar to "(likely(foo) > 0)" - if ($^V && $^V ge 5.10.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/@) { @@ -6249,28 +6809,6 @@ sub process { } } -# whine about ACCESS_ONCE - if ($^V && $^V ge 5.10.0 && - $line =~ /\bACCESS_ONCE\s*$balanced_parens\s*(=(?!=))?\s*($FuncArg)?/) { - my $par = $1; - my $eq = $2; - my $fun = $3; - $par =~ s/^\(\s*(.*)\s*\)$/$1/; - if (defined($eq)) { - if (WARN("PREFER_WRITE_ONCE", - "Prefer WRITE_ONCE(<FOO>, <BAR>) over ACCESS_ONCE(<FOO>) = <BAR>\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)\s*$eq\s*\Q$fun\E/WRITE_ONCE($par, $fun)/; - } - } else { - if (WARN("PREFER_READ_ONCE", - "Prefer READ_ONCE(<FOO>) over ACCESS_ONCE(<FOO>)\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)/READ_ONCE($par)/; - } - } - } - # check for mutex_trylock_recursive usage if ($line =~ /mutex_trylock_recursive/) { ERROR("LOCKING", @@ -6294,9 +6832,70 @@ sub process { "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 - if ($^V && $^V ge 5.10.0 && +# 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) { @@ -6305,10 +6904,7 @@ sub process { my $lc = $stat =~ tr@\n@@; $lc = $lc + $linenr; - my $stat_real = raw_line($linenr, 0); - for (my $count = $linenr + 1; $count <= $lc; $count++) { - $stat_real = $stat_real . "\n" . raw_line($count, 0); - } + my $stat_real = get_stat_real($linenr, $lc); my $skip_args = ""; if ($arg_pos > 1) { @@ -6319,8 +6915,9 @@ sub process { if ($stat =~ /$test/) { my $val = $1; $val = $6 if ($skip_args ne ""); - if (($val =~ /^$Int$/ && $val !~ /^$Octal$/) || - ($val =~ /^$Octal$/ && length($val) ne 4)) { + 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); } @@ -6333,30 +6930,13 @@ sub process { } # check for uses of S_<PERMS> that could be octal for readability - if ($line =~ /\b$mode_perms_string_search\b/) { - my $val = ""; - my $oval = ""; - my $to = 0; - my $curpos = 0; - my $lastpos = 0; - while ($line =~ /\b(($mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) { - $curpos = pos($line); - 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*$//; - my $octal = sprintf("%04o", $to); + 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/$val/$octal/; + $fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/; } } @@ -6377,6 +6957,12 @@ sub process { "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 @@ -6401,9 +6987,38 @@ sub process { ERROR("NOT_UNIFIED_DIFF", "Does not appear to be a unified-diff format patch\n"); } - if ($is_patch && $has_commit_log && $chk_signoff && $signoff == 0) { - ERROR("MISSING_SIGN_OFF", - "Missing Signed-off-by: line(s)\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(); diff --git a/scripts/const_structs.checkpatch b/scripts/const_structs.checkpatch index ac5f126..1aae4f4 100644 --- a/scripts/const_structs.checkpatch +++ b/scripts/const_structs.checkpatch @@ -39,11 +39,15 @@ 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 diff --git a/scripts/spelling.txt b/scripts/spelling.txt index aa0cc49..953f4a2 100644 --- a/scripts/spelling.txt +++ b/scripts/spelling.txt @@ -9,7 +9,12 @@ # abandonning||abandoning abigious||ambiguous +abitrary||arbitrary abitrate||arbitrate +abnornally||abnormally +abnrormal||abnormal +abord||abort +aboslute||absolute abov||above abreviated||abbreviated absense||absence @@ -25,6 +30,7 @@ accessable||accessible accesss||access accidentaly||accidentally accidentually||accidentally +acclerated||accelerated accoding||according accomodate||accommodate accomodates||accommodates @@ -34,8 +40,11 @@ accout||account accquire||acquire accquired||acquired accross||across +accumalate||accumulate +accumalator||accumulator acessable||accessible acess||access +acessing||accessing achitecture||architecture acient||ancient acitions||actions @@ -49,7 +58,9 @@ activete||activate actived||activated actualy||actually acumulating||accumulating +acumulative||accumulative acumulator||accumulator +acutally||actually adapater||adapter addional||additional additionaly||additionally @@ -58,12 +69,15 @@ 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 @@ -77,6 +91,7 @@ algorith||algorithm algorithmical||algorithmically algoritm||algorithm algoritms||algorithms +algorithmn||algorithm algorrithm||algorithm algorritm||algorithm aligment||alignment @@ -95,11 +110,16 @@ 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 @@ -130,6 +150,7 @@ arbitary||arbitrary architechture||architecture arguement||argument arguements||arguments +arithmatic||arithmetic aritmetic||arithmetic arne't||aren't arraival||arrival @@ -138,6 +159,7 @@ artillary||artillery asign||assign asser||assert assertation||assertion +assertting||asserting assiged||assigned assigment||assignment assigments||assignments @@ -145,20 +167,29 @@ 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 @@ -172,6 +203,7 @@ avaible||available availabe||available availabled||available availablity||availability +availaible||available availale||available availavility||availability availble||available @@ -205,28 +237,41 @@ 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 @@ -240,6 +285,7 @@ charaters||characters charcter||character chcek||check chck||check +checksumed||checksummed checksuming||checksumming childern||children childs||children @@ -255,7 +301,9 @@ claread||cleared clared||cleared closeing||closing clustred||clustered +cnfiguration||configuration coexistance||coexistence +colescing||coalescing collapsable||collapsible colorfull||colorful comand||command @@ -272,8 +320,10 @@ comsumer||consumer comsuming||consuming compability||compatibility compaibility||compatibility +comparsion||comparison compatability||compatibility compatable||compatible +compatibililty||compatibility compatibiliy||compatibility compatibilty||compatibility compatiblity||compatibility @@ -285,22 +335,30 @@ 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 -connecetd||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 @@ -310,11 +368,13 @@ 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 @@ -342,10 +402,16 @@ 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 @@ -362,29 +428,35 @@ 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 @@ -395,43 +467,66 @@ 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 @@ -439,6 +534,8 @@ elementry||elementary eletronic||electronic embeded||embedded enabledi||enabled +enbale||enable +enble||enable enchanced||enhanced encorporating||incorporating encrupted||encrypted @@ -447,8 +544,12 @@ 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 @@ -460,13 +561,20 @@ 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 @@ -474,6 +582,7 @@ exlcude||exclude exlcusive||exclusive exmaple||example expecially||especially +experies||expires explicite||explicit explicitely||explicitly explict||explicit @@ -482,11 +591,16 @@ explictly||explicitly expresion||expression exprimental||experimental extened||extended +exteneded||extended extensability||extensibility extention||extension +extenstion||extension extracter||extractor -falied||failed +faied||failed +faield||failed faild||failed +failded||failed +failer||failure faill||fail failied||failed faillure||failure @@ -504,8 +618,12 @@ 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 @@ -520,13 +638,17 @@ 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 @@ -537,14 +659,19 @@ 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 @@ -553,14 +680,18 @@ 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 @@ -568,12 +699,16 @@ 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 @@ -591,10 +726,12 @@ 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 @@ -603,6 +740,7 @@ independed||independent indiate||indicate indicat||indicate inexpect||inexpected +inferface||interface infomation||information informatiom||information informations||information @@ -617,14 +755,23 @@ 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 @@ -639,13 +786,14 @@ intermittant||intermittent internel||internal interoprability||interoperability interuupt||interrupt +interupt||interrupt +interupts||interrupts interrface||interface interrrupt||interrupt interrup||interrupt interrups||interrupts interruptted||interrupted interupted||interrupted -interupt||interrupt intial||initial intialisation||initialisation intialised||initialised @@ -654,10 +802,14 @@ 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 @@ -666,14 +818,18 @@ 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 @@ -683,6 +839,7 @@ langauge||language langugage||language lauch||launch layed||laid +legnth||length leightweight||lightweight lengh||length lenght||length @@ -693,29 +850,42 @@ 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 @@ -723,11 +893,14 @@ 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 @@ -736,21 +909,28 @@ 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 @@ -772,21 +952,29 @@ 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 -occured||occurred occuring||occurring +offser||offset offet||offset +offlaod||offload +offloded||offloaded +offseting||offsetting omited||omitted omiting||omitting omitt||omit @@ -801,6 +989,7 @@ optmizations||optimizations orientatied||orientated orientied||oriented orignal||original +originial||original otherise||otherwise ouput||output oustanding||outstanding @@ -820,6 +1009,7 @@ packege||package packge||package packtes||packets pakage||package +paket||packet pallette||palette paln||plan paramameters||parameters @@ -829,23 +1019,33 @@ 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 @@ -857,7 +1057,10 @@ poiter||pointer posible||possible positon||position possibilites||possibilities +potocol||protocol powerfull||powerful +pramater||parameter +preamle||preamble preample||preamble preapre||prepare preceeded||preceded @@ -868,8 +1071,11 @@ precission||precision preemptable||preemptible prefered||preferred prefferably||preferably +prefitler||prefilter premption||preemption prepaired||prepared +preperation||preparation +preprare||prepare pressre||pressure primative||primitive princliple||principle @@ -891,12 +1097,15 @@ 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 @@ -906,24 +1115,30 @@ 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 @@ -935,6 +1150,7 @@ recommanded||recommended recyle||recycle redircet||redirect redirectrion||redirection +redundacy||redundancy reename||rename refcounf||refcount refence||reference @@ -944,7 +1160,9 @@ refering||referring refernces||references refernnce||reference refrence||reference +registed||registered registerd||registered +registeration||registration registeresd||registered registerred||registered registes||registers @@ -957,6 +1175,7 @@ regulamentations||regulations reigstration||registration releated||related relevent||relevant +reloade||reload remoote||remote remore||remote removeable||removable @@ -967,25 +1186,37 @@ 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 @@ -1006,30 +1237,39 @@ 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 -sepc||spec 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 @@ -1037,6 +1277,7 @@ shoule||should shrinked||shrunk siginificantly||significantly signabl||signal +significanly||significantly similary||similarly similiar||similar simlar||similar @@ -1046,9 +1287,11 @@ singaled||signaled singal||signal singed||signed sleeped||slept +sliped||slipped softwares||software speach||speech specfic||specific +specfield||specified speciefied||specified specifc||specific specifed||specified @@ -1071,8 +1314,12 @@ 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 @@ -1084,13 +1331,16 @@ 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 @@ -1108,6 +1358,7 @@ surpressed||suppressed surpresses||suppresses susbsystem||subsystem suspeneded||suspended +suspsend||suspend suspicously||suspiciously swaping||swapping switchs||switches @@ -1119,9 +1370,11 @@ swithcing||switching swithed||switched swithing||switching swtich||switch +syfs||sysfs symetric||symmetric synax||syntax synchonized||synchronized +synchronuously||synchronously syncronize||synchronize syncronized||synchronized syncronizing||synchronizing @@ -1130,28 +1383,39 @@ 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 @@ -1162,6 +1426,8 @@ transormed||transformed trasfer||transfer trasmission||transmission treshold||threshold +triggerd||triggered +trigerred||triggered trigerring||triggering trun||turn tunning||tuning @@ -1169,8 +1435,12 @@ 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 @@ -1181,12 +1451,20 @@ 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 @@ -1199,13 +1477,17 @@ 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 @@ -1220,6 +1502,7 @@ varible||variable varient||variant vaule||value verbse||verbose +veify||verify verisons||versions verison||version verson||version @@ -1229,7 +1512,9 @@ virtaul||virtual virtiual||virtual visiters||visitors vitual||virtual +vunerable||vulnerable wakeus||wakeups +wathdog||watchdog wating||waiting wiat||wait wether||whether @@ -1246,5 +1531,6 @@ wnat||want workarould||workaround writeing||writing writting||writing +wtih||with zombe||zombie zomebie||zombie From 97919114b21860ef1bdbaf6b294af2451dbd8b08 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Sat, 28 Aug 2021 20:33:17 +0530 Subject: [PATCH 270/458] osi: eqos: Increase EQOS_MAX_*_SAFETY_REGS Issue: Current array size index for EQOS MTL safety register storage 4. It created issue when interface going down/up for Orin EQOS (MTL/DMA queues/channels - 8) while initializing the safety register structure. Fix: Increase EQOS_MAX_CORE/DMA_SAFETY_REGS to accommodate Orin EQOS registers extra registers as well. Bug 200765067 Change-Id: I79226eadfc0964d5034c685c7c31a7989afaeff7 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2585014 Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/eqos_core.h | 41 ++++++++++++++++---------- osi/dma/eqos_dma.h | 70 +++++++++++++++++++++++++++++--------------- 2 files changed, 72 insertions(+), 39 deletions(-) diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 02bc699..b502cdd 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -614,6 +614,9 @@ void update_ehfc_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value); #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 @@ -627,24 +630,32 @@ void update_ehfc_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value); #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_TXQ0_QW_IDX 22U -#ifndef OSI_STRIPPED_LIB -#define EQOS_MAC_HTR1_IDX 3U -#define EQOS_MAC_HTR2_IDX 4U -#define EQOS_MAC_HTR3_IDX 5U #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_TXQ1_QW_IDX 23U -#define EQOS_MTL_TXQ2_QW_IDX 24U -#define EQOS_MTL_TXQ3_QW_IDX 25U -#define EQOS_MTL_CH1_RX_OP_MODE_IDX 27U -#define EQOS_MTL_CH2_RX_OP_MODE_IDX 28U -#define EQOS_MTL_CH3_RX_OP_MODE_IDX 29U -#endif /* !OSI_STRIPPED_LIB */ -#define EQOS_MTL_CH0_RX_OP_MODE_IDX 26U -#define EQOS_DMA_SBUS_IDX 30U -#define EQOS_MAX_CORE_SAFETY_REGS 31U +#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_MAX_CORE_SAFETY_REGS 44U /** @} */ /** diff --git a/osi/dma/eqos_dma.h b/osi/dma/eqos_dma.h index 51de179..fd17fde 100644 --- a/osi/dma/eqos_dma.h +++ b/osi/dma/eqos_dma.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -118,32 +118,54 @@ * Using macros instead of enum due to misra error. */ #define EQOS_DMA_CH0_CTRL_IDX 0U -#define EQOS_DMA_CH0_TX_CTRL_IDX 4U -#define EQOS_DMA_CH0_RX_CTRL_IDX 8U -#define EQOS_DMA_CH0_RDRL_IDX 16U -#define EQOS_DMA_CH0_TDRL_IDX 12U -#define EQOS_DMA_CH0_INTR_ENA_IDX 20U -#ifndef OSI_STRIPPED_LIB #define EQOS_DMA_CH1_CTRL_IDX 1U #define EQOS_DMA_CH2_CTRL_IDX 2U #define EQOS_DMA_CH3_CTRL_IDX 3U -#define EQOS_DMA_CH1_TX_CTRL_IDX 5U -#define EQOS_DMA_CH2_TX_CTRL_IDX 6U -#define EQOS_DMA_CH3_TX_CTRL_IDX 7U -#define EQOS_DMA_CH1_RX_CTRL_IDX 9U -#define EQOS_DMA_CH2_RX_CTRL_IDX 10U -#define EQOS_DMA_CH3_RX_CTRL_IDX 11U -#define EQOS_DMA_CH1_TDRL_IDX 13U -#define EQOS_DMA_CH2_TDRL_IDX 14U -#define EQOS_DMA_CH3_TDRL_IDX 15U -#define EQOS_DMA_CH1_RDRL_IDX 17U -#define EQOS_DMA_CH2_RDRL_IDX 18U -#define EQOS_DMA_CH3_RDRL_IDX 19U -#define EQOS_DMA_CH1_INTR_ENA_IDX 21U -#define EQOS_DMA_CH2_INTR_ENA_IDX 22U -#define EQOS_DMA_CH3_INTR_ENA_IDX 23U -#endif /* OSI_STRIPPED_LIB */ -#define EQOS_MAX_DMA_SAFETY_REGS 24U +#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 /** @} */ From 33d9efbf7b130edfa291f8dac0d165a8ac89b64a Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Wed, 1 Sep 2021 14:34:56 +0530 Subject: [PATCH 271/458] osi: eqos: Fix 4 to 7 RXQ to DMA mapping Issue: DCS test are getting fail due to invalid RXQ to DMA mapping. Fix: Enable DMA mapping for RXQ 4 to 7 Bug 200765514 Change-Id: Idece787a9aa7d9c9bac52be64f55a9ec962f092f Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2587182 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/eqos_core.c | 11 ++++++++++- osi/core/eqos_core.h | 6 +++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 43739e3..de6dad4 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -2093,6 +2093,7 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core, 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; @@ -2125,17 +2126,25 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core, } /* Mapping MTL Rx queue and DMA Rx channel */ - /* TODO: Need to add EQOS_MTL_RXQ_DMA_MAP1 for EQOS */ 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); diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index b502cdd..8aa0d70 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -143,6 +143,7 @@ #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_STATUS 0x0C58 #define EQOS_MTL_EST_SCH_ERR 0x0C60 @@ -197,7 +198,9 @@ */ /* 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) @@ -655,7 +658,8 @@ void update_ehfc_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value); #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_MAX_CORE_SAFETY_REGS 44U +#define EQOS_MTL_RXQ_DMA_MAP1_IDX 44U +#define EQOS_MAX_CORE_SAFETY_REGS 45U /** @} */ /** From 9bca2a246174f89e644437842967d3443214de2a Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Mon, 6 Sep 2021 16:13:41 +0530 Subject: [PATCH 272/458] core: eqos: Program OVHD value for EQOS As per guidelines form HW team, add recommended OVHD for eqos Bug 200765943 Change-Id: Ic885ed9681869fd6f13c65407d208f9e30e19e5e Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2589995 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/eqos_core.c | 8 ++++++++ osi/core/eqos_core.h | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index de6dad4..a21b838 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -2001,6 +2001,14 @@ static void eqos_tsn_init(struct osi_core_priv_data *osi_core, 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); } diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 8aa0d70..326732d 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -145,6 +145,7 @@ #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 @@ -538,6 +539,10 @@ #define EQOS_MTL_EST_CONTROL_DDBF OSI_BIT(4) #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) | \ From 7ccb0dc827b0cb249fc177c42ff4e6db0f896957 Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Fri, 27 Aug 2021 18:24:16 +0530 Subject: [PATCH 273/458] dma: mgbe: update RWT and RWUT programming for silicon Issue: RWT and RWUT programmed for uFPGA Fix: Update RWIT programming Update minimum rx coalescing timer value Bug 200767374 Change-Id: I09c21764f0c294021c7546f75351c19c34a0b9db Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2589496 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Sachin Nikam <snikam@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_common.h | 3 ++- osi/dma/mgbe_dma.c | 11 ++++++++++- osi/dma/mgbe_dma.h | 14 +++++++++++++- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index ac920d2..c7513dc 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -60,7 +60,8 @@ #ifndef OSI_STRIPPED_LIB #define OSI_MAX_RX_COALESCE_USEC 1020U -#define OSI_MIN_RX_COALESCE_USEC 3U +#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 diff --git a/osi/dma/mgbe_dma.c b/osi/dma/mgbe_dma.c index bb6ef96..6d9d6db 100644 --- a/osi/dma/mgbe_dma.c +++ b/osi/dma/mgbe_dma.c @@ -502,11 +502,20 @@ static void mgbe_configure_dma_channel(nveu32_t chan, /* Conversion of usec to Rx Interrupt Watchdog Timer Count */ /* TODO: Need to fix AXI clock for silicon */ value |= ((osi_dma->rx_riwt * - ((nveu32_t)13000000 / OSI_ONE_MEGA_HZ)) / + ((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 */ diff --git a/osi/dma/mgbe_dma.h b/osi/dma/mgbe_dma.h index 9c3a484..3b93cdc 100644 --- a/osi/dma/mgbe_dma.h +++ b/osi/dma/mgbe_dma.h @@ -23,6 +23,15 @@ #ifndef INCLUDED_MGBE_DMA_H #define INCLUDED_MGBE_DMA_H +/** + * @addtogroup MGBE AXI Clock defines + * + * @brief AXI Clock defines + * @{ + */ +#define MGBE_AXI_CLK_FREQ 408000000U +/** @} */ + /** * @@addtogroup Timestamp Capture Register * @brief MGBE MAC Timestamp Register offset @@ -78,7 +87,10 @@ #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 256U +#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 From 6005325d99035ac27ebeae4f79d0157981d40d03 Mon Sep 17 00:00:00 2001 From: Mahesh Patil <maheshp@nvidia.com> Date: Mon, 12 Jul 2021 16:46:43 -0700 Subject: [PATCH 274/458] nvethernetrm: change MAC ipg as per macsec req Change MAC ipg value as macsec IAS requirement when macsec is used Bug 3335658 Change-Id: Ie681bb0a66b256c32ac6093114fe29c65bf20a07 Signed-off-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2558031 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/core_local.h | 4 ++ osi/core/eqos_core.c | 160 ++++++++++++++++++++++++++++++------------ osi/core/eqos_core.h | 2 +- osi/core/macsec.c | 31 ++++++-- osi/core/mgbe_core.c | 144 +++++++++++++++++++++++++------------ osi/core/mgbe_core.h | 1 + 6 files changed, 245 insertions(+), 97 deletions(-) diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 0e264a6..8cd9da6 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -266,6 +266,10 @@ struct core_ops { /** 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 (*config_macsec_ipg)(struct osi_core_priv_data *const osi_core, + const nveu32_t enable); +#endif /* MACSEC_SUPPORT */ }; diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index a21b838..4b25892 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1590,46 +1590,6 @@ static void eqos_configure_rxq_priority( } } -#ifdef MACSEC_SUPPORT -/** - * @brief eqos_config_macsec_ipg - Configure MAC IPG according to macsec IAS - * - * @note - * Algorithm: - * - Increase MAC IPG value to accommodate macsec 32 byte SECTAG. - * - * @param[in] osi_core: OSI core private data. - * - * @pre - * 1) MAC has to be out of reset. - * 2) Shall not use this ipg value in half duplex mode - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - */ -static void eqos_config_macsec_ipg(struct osi_core_priv_data *const osi_core) -{ - nveu32_t value; - - /* 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); - value |= (EQOS_MCR_IPG << EQOS_MCR_IPG_SHIFT) & 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 << EQOS_MAC_EXTR_EIPG_SHIFT) & - EQOS_MAC_EXTR_EIPG_MASK; - osi_writela(osi_core, value, (nveu8_t *)osi_core->base + EQOS_MAC_EXTR); -} -#endif /* MACSEC_SUPPORT */ - /** * @brief eqos_configure_mac - Configure MAC * @@ -1794,11 +1754,6 @@ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) if (osi_core->dcs_en != OSI_ENABLE) { eqos_configure_rxq_priority(osi_core); } -#ifdef MACSEC_SUPPORT - if (osi_core->mac_ver == OSI_EQOS_MAC_5_30) { - eqos_config_macsec_ipg(osi_core); - } -#endif /* MACSEC_SUPPORT */ } /** @@ -2686,6 +2641,49 @@ static void eqos_stop_mac(struct osi_core_priv_data *const osi_core) 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. @@ -6272,6 +6270,75 @@ static nve32_t eqos_config_rss(struct osi_core_priv_data *const osi_core) return -1; } +#ifdef MACSEC_SUPPORT +/** + * @brief eqos_config_macsec_ipg - Configure MAC IPG according to macsec IAS + * + * @note + * Algorithm: + * - Stop MAC Tx + * - Update MAC IPG value to accommodate macsec 32 byte SECTAG. + * - Start MAC Tx + * + * @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 + */ +void eqos_config_macsec_ipg(struct osi_core_priv_data *const osi_core, + const nveu32_t enable) +{ + nveu32_t value; + + 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); + value |= (EQOS_MCR_IPG << EQOS_MCR_IPG_SHIFT) & + 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 << EQOS_MAC_EXTR_EIPG_SHIFT) & + 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); + } +} +#endif /* MACSEC_SUPPORT */ + /** * @brief eqos_get_core_safety_config - EQOS MAC safety configuration * @@ -6344,4 +6411,7 @@ void eqos_init_core_ops(struct core_ops *ops) 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->config_macsec_ipg = eqos_config_macsec_ipg; +#endif /* MACSEC_SUPPORT */ } diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 326732d..687b1a8 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -206,7 +206,7 @@ #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 0x700000U +#define EQOS_MCR_IPG_MASK 0x7000000U #define EQOS_MCR_IPG_SHIFT 24U #define EQOS_MCR_IPG 0x7U #define EQOS_MCR_IPC OSI_BIT(27) diff --git a/osi/core/macsec.c b/osi/core/macsec.c index ae85c5f..bcea324 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -2448,11 +2448,21 @@ static nve32_t clear_lut(struct osi_core_priv_data *const osi_core) static nve32_t macsec_deinit(struct osi_core_priv_data *const osi_core) { nveu32_t i; + struct core_local *l_core = (struct core_local *)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 ipg value as per macsec requirement */ + if (l_core->ops_p->config_macsec_ipg != OSI_NULL) { + l_core->ops_p->config_macsec_ipg(osi_core, OSI_DISABLE); + } else { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Failed config macsec IPG\n", 0ULL); + } + return 0; } @@ -2461,6 +2471,7 @@ static nve32_t macsec_init(struct osi_core_priv_data *const osi_core) nveu32_t val = 0; struct osi_macsec_lut_config lut_config = {0}; struct osi_macsec_table_config *table_config = &lut_config.table_config; + struct core_local *l_core = (struct core_local *)osi_core; /* Store MAC address in reverse, per HW design */ nveu8_t mac_da_mkpdu[OSI_ETH_ALEN] = {0x3, 0x0, 0x0, 0xC2, 0x80, 0x01}; @@ -2471,7 +2482,15 @@ static nve32_t macsec_init(struct osi_core_priv_data *const osi_core) nve32_t ret = 0; nveu16_t i, j; - /* 1. Set MTU */ + /* Update MAC ipg value as per macsec requirement */ + if (l_core->ops_p->config_macsec_ipg != OSI_NULL) { + l_core->ops_p->config_macsec_ipg(osi_core, OSI_ENABLE); + } else { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Failed config macsec IPG\n", 0ULL); + } + + /* Set MTU */ val = osi_readla(osi_core, addr + MACSEC_TX_MTU_LEN); pr_err("Read MACSEC_TX_MTU_LEN: 0x%x\n", val); val &= ~(MTU_LENGTH_MASK); @@ -2505,7 +2524,7 @@ static nve32_t macsec_init(struct osi_core_priv_data *const osi_core) osi_writela(osi_core, val, addr + MACSEC_RX_SOT_DELAY); } - /* 2. Set essential MACsec control configuration */ + /* Set essential MACsec control configuration */ val = osi_readla(osi_core, addr + MACSEC_CONTROL0); pr_err("Read MACSEC_CONTROL0: 0x%x\n", val); val |= (MACSEC_TX_LKUP_MISS_NS_INTR | MACSEC_RX_LKUP_MISS_NS_INTR | @@ -2539,7 +2558,7 @@ static nve32_t macsec_init(struct osi_core_priv_data *const osi_core) pr_err("Write MACSEC_STATS_CONTROL_0: 0x%x\n", val); osi_writela(osi_core, val, addr + MACSEC_STATS_CONTROL_0); - /* 3. Enable default interrupts needed */ + /* Enable default interrupts needed */ val = osi_readla(osi_core, addr + MACSEC_TX_IMR); pr_err("Read MACSEC_TX_IMR: 0x%x\n", val); val |= (MACSEC_TX_DBG_BUF_CAPTURE_DONE_INT_EN | @@ -2576,11 +2595,11 @@ static nve32_t macsec_init(struct osi_core_priv_data *const osi_core) pr_err("Write MACSEC_COMMON_IMR: 0x%x\n", val); osi_writela(osi_core, val, addr + MACSEC_COMMON_IMR); - /* 4. Set AES mode + /* Set AES mode * Default power on reset is AES-GCM128, leave it. */ - /* 5. Invalidate LUT entries */ + /* Invalidate LUT entries */ ret = clear_lut(osi_core); if (ret < 0) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, @@ -2588,7 +2607,7 @@ static nve32_t macsec_init(struct osi_core_priv_data *const osi_core) return ret; } - /* 6. Set default BYP for MKPDU/BC packets */ + /* 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 | diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index fb2e54f..4e5689c 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -2505,47 +2505,6 @@ static int mgbe_config_flow_control(struct osi_core_priv_data *const osi_core, return 0; } -#ifdef MACSEC_SUPPORT -/** - * @brief mgbe_config_macsec_ipg - Configure MAC IPG according to macsec IAS - * - * @note - * Algorithm: - * - Increase MAC IPG value to accommodate macsec 32 byte SECTAG. - * - * @param[in] osi_core: OSI core private data. - * - * @pre - * 1) MAC has to be out of reset. - * 2) Shall not use this ipg value in half duplex mode - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - */ -static void mgbe_config_macsec_ipg(struct osi_core_priv_data *const osi_core) -{ - nveu32_t value = 0U; - - /* 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); -} -#endif /* MACSEC_SUPPORT */ - /** * @brief mgbe_configure_mac - Configure MAC * @@ -2689,10 +2648,6 @@ static int mgbe_configure_mac(struct osi_core_priv_data *osi_core) } /* TODO: USP (user Priority) to RxQ Mapping */ -#ifdef MACSEC_SUPPORT - mgbe_config_macsec_ipg(osi_core); -#endif /* MACSEC_SUPPORT */ - /* RSS cofiguration */ return mgbe_config_rss(osi_core); } @@ -3985,6 +3940,37 @@ static void mgbe_stop_mac(struct osi_core_priv_data *const osi_core) 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 * @@ -5598,6 +5584,71 @@ static void mgbe_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, { } +#ifdef MACSEC_SUPPORT +/** + * @brief mgbe_config_macsec_ipg - Configure MAC IPG according to macsec IAS + * + * @note + * Algorithm: + * - Stop MAC Tx + * - Update MAC IPG value to accommodate macsec 32 byte SECTAG. + * - Start MAC Tx + * + * @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 + */ +void mgbe_config_macsec_ipg(struct osi_core_priv_data *const osi_core, + const nveu32_t enable) +{ + nveu32_t value = 0U; + + /* 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); +} +#endif /* MACSEC_SUPPORT */ + /** * @brief mgbe_init_core_ops - Initialize MGBE MAC core operations */ @@ -5659,4 +5710,7 @@ void mgbe_init_core_ops(struct core_ops *ops) ops->update_frp_nve = mgbe_update_frp_nve; ops->write_reg = mgbe_write_reg; ops->read_reg = mgbe_read_reg; +#ifdef MACSEC_SUPPORT + ops->config_macsec_ipg = mgbe_config_macsec_ipg; +#endif /* MACSEC_SUPPORT */ }; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index b606811..9ffc291 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -668,6 +668,7 @@ #define MGBE_MAC_SBD_INTR OSI_BIT(2) #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) /** @} */ From c7dac4a78e66e7ffbd7d4d12795632fc2e7506b9 Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Tue, 14 Sep 2021 09:02:35 +0530 Subject: [PATCH 275/458] core: eqos: handling onestep ipv4 flags Issue: OSI_MAC_TCR_CSC not handled in eqos code Fix: update time control register with CSC bit if passed form upper layer. Bug 200764256 Change-Id: Ifbfab0de4bb81625c4bd023fad67131ee6a43987 Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2593818 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: Mohan Thadikamalla <mohant@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/eqos_core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 4b25892..046c6b3 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -4207,6 +4207,9 @@ static void eqos_config_tscr(struct osi_core_priv_data *const osi_core, 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; From 702ce0d7fd3057df7adac0fe8ba1dad94098f698 Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Mon, 16 Aug 2021 14:09:06 +0530 Subject: [PATCH 276/458] osi: eqos: Fix FRP entry update fail Issue: FRP entry update command is getting failed due to an invalid RXPI check on EQOS IP. Fix: Fix the RXPI check on the FRP update as per the databook. Bug 200766666 Change-Id: I4631623ec06bf815c88c5364f5ae599d0e7702dc Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2587257 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/eqos_core.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 046c6b3..ce278c5 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1277,6 +1277,16 @@ static int eqos_config_frp(struct osi_core_priv_data *const osi_core, 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), @@ -1292,29 +1302,20 @@ static int eqos_config_frp(struct osi_core_priv_data *const osi_core, goto frp_enable_re; } - op_mode = osi_readl(base + EQOS_MTL_OP_MODE); val = osi_readl(base + EQOS_MTL_RXP_INTR_CS); if (enabled == OSI_ENABLE) { - /* Set FRPE bit of MTL_Operation_Mode register */ - op_mode |= EQOS_MTL_OP_MODE_FRPE; - /* 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 { - /* Reset FRPE bit of MTL_Operation_Mode register */ - op_mode &= ~EQOS_MTL_OP_MODE_FRPE; - /* Disable FRP Interrupt MTL_RXP_Interrupt_Control_Status */ - val = osi_readl(base + EQOS_MTL_RXP_INTR_CS); 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(op_mode, base + EQOS_MTL_OP_MODE); osi_writel(val, base + EQOS_MTL_RXP_INTR_CS); frp_enable_re: From 1b41ce0f4136ad5b514233483c86c08657ef9502 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Fri, 10 Sep 2021 15:18:15 +0530 Subject: [PATCH 277/458] osi: eqos: mgbe: program SID through HV window Issue: In non-hypervisor configurations SID programmed through RM window. In orin EQOS/MGBE these SID should program through HV window to get reflected in controller register space. Fix: Program SID based on MAC instance ID through HV window Bug 200761024 Change-Id: I1a37455647429e917e7558e812fe7e512d646918 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2592482 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_core.h | 4 ++++ osi/core/eqos_core.c | 31 +++++++++++++++++++++++-------- osi/core/eqos_core.h | 15 +++++++++++++++ osi/core/mgbe_core.c | 34 +++++++++++++++++++++++++++++----- osi/core/mgbe_core.h | 13 +++++++++++++ 5 files changed, 84 insertions(+), 13 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index d2d920d..4bfd577 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -1145,6 +1145,8 @@ struct core_padctrl { 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 */ @@ -1256,6 +1258,8 @@ struct osi_core_priv_data { nveu32_t phy_iface_mode; /** eqos pad control structure */ struct core_padctrl padctrl; + /** MGBE MAC instance ID's */ + nveu32_t instance_id; }; /** diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index ce278c5..edfdb9e 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -2078,15 +2078,30 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core, osi_writela(osi_core, EQOS_MMC_CNTRL_CNTRST, (nveu8_t *)osi_core->base + EQOS_MMC_CNTRL); - /* 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); + 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); - /* 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); + 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 */ diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 687b1a8..07fb3b3 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -496,6 +496,21 @@ (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 */ diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 4e5689c..21fe7f0 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -2994,9 +2994,13 @@ static void mgbe_tsn_init(struct osi_core_priv_data *osi_core, * * @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 void mgbe_dma_chan_to_vmirq_map(struct osi_core_priv_data *osi_core) +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; @@ -3017,7 +3021,29 @@ static void mgbe_dma_chan_to_vmirq_map(struct osi_core_priv_data *osi_core) } } - osi_writel(0xD, (nveu8_t *)osi_core->base + 0x8400); + 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; } @@ -3127,9 +3153,7 @@ static nve32_t mgbe_core_init(struct osi_core_priv_data *osi_core, osi_core->hw_feature->fpe_sel); } - mgbe_dma_chan_to_vmirq_map(osi_core); - - return 0; + return mgbe_dma_chan_to_vmirq_map(osi_core); } /** diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 9ffc291..0719c41 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -122,6 +122,9 @@ * @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_WRAP_COMMON_INTR_STATUS 0x8708 #define MGBE_VIRT_INTR_APB_CHX_CNTRL(x) (0x8200U + ((x) * 4U)) @@ -671,6 +674,16 @@ #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)) /** @} */ /** From 1ebd90edb0281ec0e97896494122a0232eeb536f Mon Sep 17 00:00:00 2001 From: Nagaraj Annaiah <nannaiah@nvidia.com> Date: Tue, 31 Aug 2021 03:51:17 +0000 Subject: [PATCH 278/458] osi: core: macsec: Add macsec fix Issue: macsec doesn't work for virtualization. Fix: 1.Move virtualization checks before address check. 2. Copy PTP config to ioctl structure. Bug 2694285 Change-Id: I81f47cf23e37a62a3e5b8ecece8ae905ec1a5df3 Signed-off-by: Nagaraj Annaiah <nannaiah@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2587833 Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/ivc_core.c | 6 ++++++ osi/core/macsec.c | 17 ++++++++--------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index d4a1ac5..144cff0 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -59,6 +59,12 @@ static nve32_t ivc_handle_ioctl(struct osi_core_priv_data *osi_core, (void *)data, sizeof(struct osi_ioctl)); + if (data->cmd == OSI_CMD_CONFIG_PTP) { + osi_memcpy((void *)&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) { diff --git a/osi/core/macsec.c b/osi/core/macsec.c index bcea324..e5570b8 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -3119,18 +3119,17 @@ static struct osi_macsec_lut_status lut_status[OSI_NUM_CTLR]; nve32_t osi_init_macsec_ops(struct osi_core_priv_data *const osi_core) { - if (osi_core->macsec_base == OSI_NULL) { - return -1; + 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->use_virtualization == OSI_ENABLE) { - osi_core->macsec_ops = &virt_macsec_ops; - ivc_init_macsec_ops(osi_core->macsec_ops); - } else { - osi_core->macsec_ops = &macsec_ops; + if (osi_core->macsec_base == OSI_NULL) { + return -1; } - osi_core->macsec_lut_status = lut_status; - return 0; + osi_core->macsec_ops = &macsec_ops; } + osi_core->macsec_lut_status = lut_status; + return 0; } nve32_t osi_macsec_init(struct osi_core_priv_data *const osi_core) From 682c88d674b1197253f3d0147560a7c350e211c9 Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Mon, 6 Sep 2021 19:40:15 +0530 Subject: [PATCH 279/458] core: mgbe: use lock for time stamping Using lock for protect critical section between common interrupt and ioctl call to read timestamp Add mmc counters for lock failure during node addition and deletion. Bug 200743666 Change-Id: I12a2e57993e91d6ed50ed0efc84d1b60ef736677 Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2590099 Tested-by: Gaurav Asati <gasati@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: Gaurav Asati <gasati@nvidia.com> Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/mmc.h | 4 ++++ osi/core/core_local.h | 2 ++ osi/core/mgbe_core.c | 13 +++++++++++++ osi/core/osi_core.c | 1 + osi/core/osi_hal.c | 12 ++++++++++++ osi/dma/dma_local.h | 2 +- 6 files changed, 33 insertions(+), 1 deletion(-) diff --git a/include/mmc.h b/include/mmc.h index ffe9385..6f5e2a0 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -578,6 +578,10 @@ struct osi_xtra_stat_counters { 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 diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 8cd9da6..a6ca061 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -299,6 +299,8 @@ struct core_local { nveu32_t gcl_dep; /** Max GCL width (time + gate) value supported by HW */ nveu32_t gcl_width_val; + /** TS lock */ + nveu32_t ts_lock; }; /** diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 21fe7f0..3ba4875 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -3270,6 +3270,15 @@ static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core, 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) & @@ -3299,7 +3308,11 @@ static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core, 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, diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index f8821d0..508dbb4 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -167,6 +167,7 @@ nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core) return ret; } l_core->if_init_done = OSI_ENABLE; + l_core->ts_lock = OSI_DISABLE; return ret; } diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index ce52259..548b444 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -1425,6 +1425,15 @@ static inline nve32_t get_tx_ts(struct osi_core_priv_data *osi_core, 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)) { @@ -1442,6 +1451,9 @@ static inline nve32_t get_tx_ts(struct osi_core_priv_data *osi_core, temp = temp->next; } + /* mask return as initial value is returned always */ + (void)__sync_fetch_and_sub(&l_core->ts_lock, 1); +done: return ret; } diff --git a/osi/dma/dma_local.h b/osi/dma/dma_local.h index 5528870..bff9a5f 100644 --- a/osi/dma/dma_local.h +++ b/osi/dma/dma_local.h @@ -249,7 +249,7 @@ nve32_t dma_desc_init(struct osi_dma_priv_data *osi_dma, } \ } \ -#define BOOLEAN_FALSE (0U != 0U) +#define BOOLEAN_FALSE (0U != 0U) #define L32(data) ((data) & 0xFFFFFFFFU) #define H32(data) (((data) & 0xFFFFFFFF00000000UL) >> 32UL) /** @} */ From 43d870317798686e6de73589f4265b7a30fcdb0f Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Fri, 10 Sep 2021 18:09:12 +0530 Subject: [PATCH 280/458] dma: check tx_pkt_cx length field Validate tx_pkt_cx before updating hardware Bug 200765943 Bug 200763256 Change-Id: I44c4b1ec3adfed2b9f871924b3f03a3dd6e2ab2f Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2592513 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/dma/osi_dma_txrx.c | 79 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 69 insertions(+), 10 deletions(-) diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index cc07cd6..c6f37e0 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -728,8 +728,6 @@ static inline nve32_t need_cntx_desc(struct osi_tx_pkt_cx *tx_pkt_cx, if ((tx_pkt_cx->flags & OSI_PKT_CX_VLAN) == OSI_PKT_CX_VLAN) { /* Set context type */ tx_desc->tdes3 |= TDES3_CTXT; - /* Remove any overflow bits. VT field is 16bit field */ - tx_pkt_cx->vtag_id &= TDES3_VT_MASK; /* Fill VLAN Tag ID */ tx_desc->tdes3 |= tx_pkt_cx->vtag_id; /* Set VLAN TAG Valid */ @@ -744,8 +742,6 @@ static inline nve32_t need_cntx_desc(struct osi_tx_pkt_cx *tx_pkt_cx, if ((tx_pkt_cx->flags & OSI_PKT_CX_TSO) == OSI_PKT_CX_TSO) { /* Set context type */ tx_desc->tdes3 |= TDES3_CTXT; - /* Remove any overflow bits. MSS is 13bit field */ - tx_pkt_cx->mss &= TDES2_MSS_MASK; /* Fill MSS */ tx_desc->tdes2 |= tx_pkt_cx->mss; /* Set MSS valid */ @@ -870,8 +866,6 @@ static inline void fill_first_desc(struct osi_tx_ring *tx_ring, /* if LEN bit is set, update packet payload len */ if ((tx_pkt_cx->flags & OSI_PKT_CX_LEN) == OSI_PKT_CX_LEN) { - /* Remove any overflow bits. PL field is 15 bit wide */ - tx_pkt_cx->payload_len &= ~TDES3_PL_MASK; /* Update packet len in desc */ tx_desc->tdes3 |= tx_pkt_cx->payload_len; } @@ -885,13 +879,11 @@ static inline void fill_first_desc(struct osi_tx_ring *tx_ring, * Typical TCP hdr len = 20B / 4 = 5 */ tx_pkt_cx->tcp_udp_hdrlen /= OSI_TSO_HDR_LEN_DIVISOR; - /* Remove any overflow bits. THL field is only 4 bit wide */ - tx_pkt_cx->tcp_udp_hdrlen &= TDES3_THL_MASK; + /* Update hdr len in desc */ tx_desc->tdes3 |= (tx_pkt_cx->tcp_udp_hdrlen << TDES3_THL_SHIFT); - /* Remove any overflow bits. TPL field is 18 bit wide */ - tx_pkt_cx->payload_len &= TDES3_TPL_MASK; + /* Update TCP payload len in desc */ tx_desc->tdes3 &= ~TDES3_TPL_MASK; tx_desc->tdes3 |= tx_pkt_cx->payload_len; @@ -922,6 +914,68 @@ static inline void dmb_oshst(void) asm volatile("dmb oshst" : : : "memory"); } +/** + * @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, @@ -963,6 +1017,11 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, "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 = From 26ed06a690edec1d47e9c212c65b337bf540701d Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Sun, 12 Sep 2021 20:25:33 +0530 Subject: [PATCH 281/458] core: update code for TSN - Update CTOV recommended value - Update PTOV recommended value - Disable PEC filed on preemption disable - Disable EEST with message to reprogram GCL instead of dropping packet on HLBF/HLBS - Configure code not to drop any packet silently on HLBF and HLBS error - Q2TC mapping with CBS enable Bug 200763256 Bug 200765943 Change-Id: I7a2581af488e22a23d32ce1819440c21f4748800 Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2593162 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/eqos_core.c | 80 ++++++++++++++++++++++++++++++-------------- osi/core/eqos_core.h | 2 ++ osi/core/mgbe_core.c | 71 ++++++++++++++++++++++++++------------- osi/core/mgbe_core.h | 11 ++---- 4 files changed, 107 insertions(+), 57 deletions(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index edfdb9e..c50df07 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1935,35 +1935,34 @@ static void eqos_tsn_init(struct osi_core_priv_data *osi_core, /* 6*1/(78.6 MHz) in ns*/ temp = (6U * 13U); } else { - /* 6*1/(312 MHz) in ns*/ - temp = (6U * 3U); + temp = EQOS_MTL_EST_PTOV_RECOMMEND; } temp = temp << EQOS_MTL_EST_CONTROL_PTOV_SHIFT; val |= temp; - /* We have a bug on CTOV for Qbv that synopsys is yet to - * fix[Case – 8001147927, Bug 200468714]. You can go ahead - * with 128*8ns for now. TODO */ val &= ~EQOS_MTL_EST_CONTROL_CTOV; - temp = (128U * 8U); + 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; - /* Drop Frames causing Scheduling Error */ - val |= EQOS_MTL_EST_CONTROL_DFBS; + + 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); + EQOS_MTL_EST_CONTROL); val = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MTL_EST_OVERHEAD); + 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_MTL_EST_OVERHEAD); eqos_enable_mtl_interrupts(osi_core); } @@ -2400,12 +2399,13 @@ static inline void update_dma_sr_stats( */ static void eqos_handle_mtl_intrs(struct osi_core_priv_data *osi_core) { - unsigned int val = 0; - unsigned int sch_err = 0; - unsigned int frm_err = 0; + 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 = 0; + unsigned long stat_val = 0U; + unsigned int value = 0U; val = osi_readla(osi_core, (unsigned char *)osi_core->base + EQOS_MTL_EST_STATUS); @@ -2446,6 +2446,18 @@ static void eqos_handle_mtl_intrs(struct osi_core_priv_data *osi_core) 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) { @@ -2468,6 +2480,19 @@ static void eqos_handle_mtl_intrs(struct osi_core_priv_data *osi_core) 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) { @@ -4675,24 +4700,26 @@ static int eqos_hw_config_fpe(struct osi_core_priv_data *osi_core, osi_core->fpe_ready = OSI_DISABLE; - val = osi_readla(osi_core, - (unsigned char *)osi_core->base + EQOS_MTL_FPE_CTS); if (((fpe->tx_queue_preemption_enable << EQOS_MTL_FPE_CTS_PEC_SHIFT) & EQOS_MTL_FPE_CTS_PEC) == OSI_DISABLE) { - val &= ~EQOS_MAC_FPE_CTS_EFPE; - osi_writela(osi_core, val, (unsigned char *)osi_core->base + - EQOS_MAC_FPE_CTS); + 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, (unsigned char *)osi_core->base + - EQOS_MAC_RQC1R); - val &= ~EQOS_MAC_RQC1R_FPRQ; - osi_writela(osi_core, val, (unsigned char *)osi_core->base + - EQOS_MAC_RQC1R); + 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 @@ -4712,7 +4739,7 @@ static int eqos_hw_config_fpe(struct osi_core_priv_data *osi_core, } } osi_writela(osi_core, val, - (unsigned char *)osi_core->base + EQOS_MTL_FPE_CTS); + (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) { @@ -5330,6 +5357,7 @@ static nve32_t eqos_set_avb_algorithm( 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; diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 07fb3b3..c5b3d7f 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -538,6 +538,7 @@ 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) | \ @@ -545,6 +546,7 @@ 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_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)) diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 3ba4875..359475a 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -2927,23 +2927,22 @@ static void mgbe_tsn_init(struct osi_core_priv_data *osi_core, /* 6*1/(78.6 MHz) in ns*/ temp = (6U * 13U); } else { - /* 6*1/(312 MHz) in ns*/ - temp = (6U * 3U); + temp = MGBE_MTL_EST_PTOV_RECOMMEND; } temp = temp << MGBE_MTL_EST_CONTROL_PTOV_SHIFT; val |= temp; - /* We have a bug on CTOV for Qbv that synopsys is yet to - * fix[Case – 8001147927, Bug 200468714]. You can go ahead - * with 128*8ns for now. TODO */ val &= ~MGBE_MTL_EST_CONTROL_CTOV; - temp = (128U * 8U); + 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); @@ -2951,7 +2950,7 @@ static void mgbe_tsn_init(struct osi_core_priv_data *osi_core, MGBE_MTL_EST_OVERHEAD); val &= ~MGBE_MTL_EST_OVERHEAD_OVHD; /* As per hardware programming info */ - val |= OVHD_MGBE_MAC; + val |= MGBE_MTL_EST_OVERHEAD_RECOMMEND; osi_writela(osi_core, val, (nveu8_t *)osi_core->base + MGBE_MTL_EST_OVERHEAD); @@ -3449,6 +3448,7 @@ static int mgbe_set_avb_algorithm( 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 + @@ -3612,12 +3612,13 @@ static int mgbe_get_avb_algorithm(struct osi_core_priv_data *const osi_core, */ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core) { - unsigned int val = 0; - unsigned int sch_err = 0; - unsigned int frm_err = 0; + 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 = 0; + unsigned long stat_val = 0U; + unsigned int value = 0U; val = osi_readla(osi_core, (nveu8_t *)osi_core->base + MGBE_MTL_EST_STATUS); @@ -3658,6 +3659,14 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core) 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) { @@ -3680,6 +3689,20 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core) 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) { @@ -4698,23 +4721,25 @@ static int mgbe_hw_config_fpe(struct osi_core_priv_data *osi_core, osi_core->fpe_ready = OSI_DISABLE; - val = osi_readla(osi_core, (unsigned char *) - osi_core->base + MGBE_MTL_FPE_CTS); if (((fpe->tx_queue_preemption_enable << MGBE_MTL_FPE_CTS_PEC_SHIFT) & MGBE_MTL_FPE_CTS_PEC) == OSI_DISABLE) { - val &= ~MGBE_MAC_FPE_CTS_EFPE; - osi_writela(osi_core, val, (unsigned char *)osi_core->base + - MGBE_MAC_FPE_CTS); + 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, (unsigned char *)osi_core->base + - MGBE_MAC_RQC1R); - val &= ~MGBE_MAC_RQC1R_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_FPE_CTS); + val &= ~MGBE_MAC_FPE_CTS_EFPE; + osi_writela(osi_core, val, (nveu8_t *)osi_core->base + + MGBE_MAC_FPE_CTS); return 0; } + 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 @@ -4733,8 +4758,8 @@ static int mgbe_hw_config_fpe(struct osi_core_priv_data *osi_core, } } } - osi_writela(osi_core, val, (unsigned char *) - osi_core->base + MGBE_MTL_FPE_CTS); + 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, diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 0719c41..d99a63c 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -609,6 +609,7 @@ 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) | \ @@ -616,6 +617,7 @@ 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_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)) @@ -627,6 +629,7 @@ #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) @@ -853,14 +856,6 @@ OSI_MGBE_MAX_MAC_ADDRESS_FILTER + 1U)) /** @} */ -/** - * @addtogroup IPG over head - * - * @brief OVHD value for MGBE MAC - * @{ - */ -#define OVHD_MGBE_MAC 56U - /** * @addtogroup MGBE-MAC MGBE MAC HW feature registers * From d2e4dc2ea2fa5c5758ac4229cfe4360c60a025a9 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Tue, 21 Sep 2021 00:57:58 +0530 Subject: [PATCH 282/458] osi: xpcs: Fix Tx lane bring-up failure Issue: During Tx lane bring up power up will fail if the lane is already powered up. Fix: Don't bring-up Tx lane if its already powered up. Bug 200766119 Bug 200764018 Change-Id: Idbdffdca7b9c9cccd8b8876fcfe8ea7448a7ed10 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2597604 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/xpcs.c | 8 ++++++++ osi/core/xpcs.h | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/osi/core/xpcs.c b/osi/core/xpcs.c index 001a197..dbaebdb 100644 --- a/osi/core/xpcs.c +++ b/osi/core/xpcs.c @@ -218,6 +218,14 @@ static nve32_t xpcs_uphy_lane_bring_up(struct osi_core_priv_data *osi_core, 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; diff --git a/osi/core/xpcs.h b/osi/core/xpcs.h index f5e85a1..43b2cef 100644 --- a/osi/core/xpcs.h +++ b/osi/core/xpcs.h @@ -54,6 +54,7 @@ #define XPCS_VR_MII_AN_INTR_STS 0x7E0008 #define XPCS_VR_XS_PCS_EEE_MCTRL0 0xE00018 #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 /** @} */ @@ -103,7 +104,7 @@ #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) /** @} */ int xpcs_init(struct osi_core_priv_data *osi_core); From 77e516a54bea143dbc517da25ef84a4878d56d62 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Mon, 20 Sep 2021 17:30:34 +0530 Subject: [PATCH 283/458] osi: mgbe: add handling of tx errors handle Tx buffer underflow handle Tx jabber timeout handle Tx IP header error handle Tx Payload checksum error Bug 200565898 Change-Id: I2de4cd11580251f0387039c1f8f3c39792c1ab65 Signed-off-by: narayanr <narayanr@nvidia.com> Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2596092 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_core.h | 16 +++++++++ osi/core/mgbe_core.c | 82 +++++++++++++++++++++++++++++++++++++++----- osi/core/mgbe_core.h | 9 +++++ 3 files changed, 99 insertions(+), 8 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 4bfd577..2c8ea5b 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -1139,6 +1139,20 @@ struct core_padctrl { 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; +}; + /** * @brief The OSI Core (MAC & MTL) private data structure. */ @@ -1260,6 +1274,8 @@ struct osi_core_priv_data { 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; }; /** diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 359475a..698db59 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -2226,6 +2226,7 @@ static void update_rfa_rfd(unsigned int rx_fifo, unsigned int *value) * 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. @@ -2314,6 +2315,13 @@ static nve32_t mgbe_configure_mtl_queue(nveu32_t qinx, (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; } @@ -2602,8 +2610,9 @@ static int mgbe_configure_mac(struct osi_core_priv_data *osi_core) /* 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); + 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 */ @@ -3248,6 +3257,7 @@ static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core, 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); @@ -3263,6 +3273,35 @@ static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core, 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); @@ -3610,7 +3649,8 @@ static int mgbe_get_avb_algorithm(struct osi_core_priv_data *const osi_core, * * @note MAC should be init and started. see osi_start_mac() */ -static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core) +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; @@ -3619,6 +3659,32 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core) 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); @@ -3725,6 +3791,10 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core) /* 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); } /** @@ -3908,12 +3978,8 @@ static void mgbe_handle_common_intr(struct osi_core_priv_data *osi_core) /* Handle MTL inerrupts */ mtl_isr = osi_readla(osi_core, (unsigned char *)base + MGBE_MTL_INTR_STATUS); - if (((mtl_isr & MGBE_MTL_IS_ESTIS) == MGBE_MTL_IS_ESTIS) && - ((dma_isr & MGBE_DMA_ISR_MTLIS) == MGBE_DMA_ISR_MTLIS)) { - mgbe_handle_mtl_intrs(osi_core); - mtl_isr &= ~MGBE_MTL_IS_ESTIS; - osi_writela(osi_core, mtl_isr, (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 */ diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index d99a63c..d6da589 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -74,6 +74,7 @@ #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 @@ -293,6 +294,8 @@ #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 @@ -409,6 +412,8 @@ #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) @@ -458,6 +463,7 @@ #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) @@ -530,6 +536,9 @@ #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) From 84a7dfbda3a02f410ca63b012bbfad7c62c33078 Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Wed, 9 Jun 2021 16:50:47 +0530 Subject: [PATCH 284/458] core: add CMD_PTP_TSC_CAP to capture time issue: Requirement is to have a method by which TSC-PTP-CAPTURE can be initiated. fix: Having osi_core ioctl to trigger and capture TSC-PTP timestamp using HW logic. Caller need to call osi_handle_ioctl with command as OSI_CMD_CAP_TSC_PTP, osi_core pointer and osi_core_ptp_tsc_data structure. Bug 200736396 Change-Id: I511dc4f490fdef81655a62c18268764741855fe4 Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2554284 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_core.h | 26 ++++++++++++++++ osi/core/core_local.h | 2 ++ osi/core/eqos_core.c | 70 +++++++++++++++++++++++++++++++++++++++++++ osi/core/eqos_core.h | 6 ++++ osi/core/mgbe_core.c | 65 ++++++++++++++++++++++++++++++++++++++++ osi/core/mgbe_core.h | 5 ++++ osi/core/osi_hal.c | 5 ++++ 7 files changed, 179 insertions(+) diff --git a/include/osi_core.h b/include/osi_core.h index 2c8ea5b..897beef 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -220,6 +220,7 @@ typedef my_lint_64 nvel64_t; #define OSI_CMD_REG_DUMP 44U #define OSI_CMD_STRUCTS_DUMP 45U #endif /* OSI_DEBUG */ +#define OSI_CMD_CAP_TSC_PTP 46U /** @} */ /** @@ -942,6 +943,21 @@ struct osi_core_rss { 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. @@ -1115,6 +1131,8 @@ struct osi_ioctl { 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; }; /** @@ -2277,6 +2295,10 @@ nve32_t osi_get_hw_features(struct osi_core_priv_data *const osi_core, * 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 + * * @param[in] osi_core: OSI core private data structure. * @param[in] data: void pointer pointing to osi_ioctl * @@ -2469,6 +2491,10 @@ struct osi_core_priv_data *osi_get_core(void); * 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 + * * @param[in] osi_core: OSI core private data structure. * @param[in] data: void pointer pointing to osi_ioctl * diff --git a/osi/core/core_local.h b/osi/core/core_local.h index a6ca061..be28ab5 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -270,6 +270,8 @@ struct core_ops { void (*config_macsec_ipg)(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); }; diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index c50df07..6710965 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -43,6 +43,75 @@ static nve32_t eqos_pre_pad_calibrate( */ 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 = 1000U; + 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 { + /* sleep if SWR is set */ + osi_core->osd_ops.msleep(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. * @@ -6461,4 +6530,5 @@ void eqos_init_core_ops(struct core_ops *ops) #ifdef MACSEC_SUPPORT ops->config_macsec_ipg = eqos_config_macsec_ipg; #endif /* MACSEC_SUPPORT */ + ops->ptp_tsc_capture = eqos_ptp_tsc_capture; } diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index c5b3d7f..01b78ac 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -189,6 +189,12 @@ #define EQOS_WRAP_COMMON_INTR_ENABLE 0x8704 #define EQOS_WRAP_COMMON_INTR_STATUS 0x8708 #define EQOS_MAC_SBD_INTR 0x4 +#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 0x801CU +#define EQOS_WRAP_PTP_CAPTURE_HIGH 0x8018U + /** @} */ /** diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 698db59..3f6db2c 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -31,6 +31,70 @@ #include "mgbe_mmc.h" #include "vlan_filter.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 = 1000U; + 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 { + /* sleep if SWR is set */ + osi_core->osd_ops.msleep(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 * @@ -5836,6 +5900,7 @@ void mgbe_init_core_ops(struct core_ops *ops) 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 diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index d6da589..8fba0a2 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -129,6 +129,11 @@ #define MGBE_WRAP_COMMON_INTR_ENABLE 0x8704 #define MGBE_WRAP_COMMON_INTR_STATUS 0x8708 #define MGBE_VIRT_INTR_APB_CHX_CNTRL(x) (0x8200U + ((x) * 4U)) +#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 /** @} */ /** diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 548b444..9823e15 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -1665,6 +1665,7 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, free_tx_ts(osi_core, data->arg1_u32); ret = 0; break; + #ifdef OSI_DEBUG case OSI_CMD_REG_DUMP: core_reg_dump(osi_core); @@ -1675,6 +1676,10 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *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; + default: OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "CORE: Incorrect command\n", From e02733c4cc11465536cb7b59aac54ee1791ea030 Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Wed, 22 Sep 2021 05:02:17 +0530 Subject: [PATCH 285/458] osi: core: Enable Transparent Tx LPI Mode In this mode, the transmit LPI state-machine does not move to TX_QUIET state. On detecting Lower-Power Idle on XGMII/GMII Tx interface, xpcs goes to the TX_SLEEP state and remains in this state till MAC stops sending LPI. Bug 200764486 Change-Id: I376ac481e880472d7a11b60931a90d6f9c7a0067 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2598380 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/mgbe_core.h | 3 ++- osi/core/xpcs.c | 12 +++++------- osi/core/xpcs.h | 6 ++++-- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 8fba0a2..a22e23b 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -51,7 +51,8 @@ * cycles of CSR clock that constitutes a period of 1us. * it should be APB clock in MHZ i.e 408-1 for silicon and 13MHZ-1 for uFPGA */ -#define MGBE_1US_TIC_COUNTER 0xC +#define MGBE_1US_TIC_COUNTER 0x197 + /** @} */ /** diff --git a/osi/core/xpcs.c b/osi/core/xpcs.c index dbaebdb..4486cfb 100644 --- a/osi/core/xpcs.c +++ b/osi/core/xpcs.c @@ -589,19 +589,17 @@ int xpcs_eee(void *xpcs_base, unsigned int en_dis) * 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 */ - /* TODO for uFPGA */ - 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_EEE_SLR_BYP; - val &= ~XPCS_VR_XS_PCS_EEE_MCTRL0_LTX_EN; - val &= ~XPCS_VR_XS_PCS_EEE_MCTRL0_LRX_EN; - val |= (XPCS_VR_XS_PCS_EEE_MCTRL0_LTX_EN | - // XPCS_VR_XS_PCS_EEE_MCTRL0_LTX_EN | XPCS_VR_XS_PCS_EEE_MCTRL0_LRX_EN); xpcs_write(xpcs_base, XPCS_VR_XS_PCS_EEE_MCTRL0, val); + /* 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; + xpcs_write(xpcs_base, XPCS_VR_XS_PCS_EEE_MCTRL1, val); + return 0; } diff --git a/osi/core/xpcs.h b/osi/core/xpcs.h index 43b2cef..39f9e11 100644 --- a/osi/core/xpcs.h +++ b/osi/core/xpcs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -52,7 +52,8 @@ #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 0xE00018 +#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 @@ -73,6 +74,7 @@ #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) From 69e5889b68cbf83724227679865086e5f7aeeaa6 Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Thu, 30 Sep 2021 12:49:36 +0530 Subject: [PATCH 286/458] osi: core: mgbe: pass correct argument Issue: base pointer is passed instead of osi_core for mgbe_l3l4_filter_read and mgbe_l3l4_filter_write as an first argument. Fix: Pass osi_core pointer instead of base Bug 200764768 Change-Id: I29ec030b2cab98d49f164d1011ac0f951496aa1c Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2603073 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/mgbe_core.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 3f6db2c..7574965 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -4273,7 +4273,6 @@ static int mgbe_mdio_busy_wait(struct osi_core_priv_data *const osi_core) static inline int mgbe_save_registers( struct osi_core_priv_data *const osi_core) { - void *base = osi_core->base; unsigned int i = 0; struct core_backup *config = &osi_core->backup_config; int ret = 0; @@ -4289,37 +4288,37 @@ static inline int mgbe_save_registers( /* Save L3 and L4 indirect addressing registers */ for (i = 0; i < OSI_MGBE_MAX_L3_L4_FILTER; i++) { - ret = mgbe_l3l4_filter_read(base, i, MGBE_MAC_L3L4_CTR, + 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(base, i, MGBE_MAC_L4_ADDR, + 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(base, i, MGBE_MAC_L3_AD0R, + 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(base, i, MGBE_MAC_L3_AD1R, + 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(base, i, MGBE_MAC_L3_AD2R, + 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(base, i, MGBE_MAC_L3_AD3R, + 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 */ @@ -4355,7 +4354,6 @@ static inline int mgbe_save_registers( static inline int mgbe_restore_registers( struct osi_core_priv_data *const osi_core) { - void *base = osi_core->base; unsigned int i = 0; struct core_backup *config = &osi_core->backup_config; int ret = 0; @@ -4371,37 +4369,37 @@ static inline int mgbe_restore_registers( /* Restore L3 and L4 indirect addressing registers */ for (i = 0; i < OSI_MGBE_MAX_L3_L4_FILTER; i++) { - ret = mgbe_l3l4_filter_write(base, i, MGBE_MAC_L3L4_CTR, + 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(base, i, MGBE_MAC_L4_ADDR, + 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(base, i, MGBE_MAC_L3_AD0R, + 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(base, i, MGBE_MAC_L3_AD1R, + 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(base, i, MGBE_MAC_L3_AD2R, + 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(base, i, MGBE_MAC_L3_AD3R, + 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 */ From e256c38aee77f4bff86e5e1151d3a95bec4f3835 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Mon, 4 Oct 2021 08:23:34 +0530 Subject: [PATCH 287/458] osi: dma: fix SMMU faults with iova address 0x0 Issue: Transmit buffer address is pupulated in transmit descriptor only if buffer address is less than UINT_MAX. If the buffer address equals to UINT_MAX then descriptor will have value of zero which is filled during transmit completions. Because of this HW tries to fetch the address zero which not valid and results in SMMU fault. Fix: Fill all tdesc0 using with lower 32 bits and tdesc1 with higher 32 bits Bug 200779695 Change-Id: I3706234d3f8c561f8291ffd63a1b1d63d046d2f2 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2604615 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/dma/dma_local.h | 4 ++-- osi/dma/osi_dma.c | 22 ++----------------- osi/dma/osi_dma_txrx.c | 50 +++++++----------------------------------- 3 files changed, 12 insertions(+), 64 deletions(-) diff --git a/osi/dma/dma_local.h b/osi/dma/dma_local.h index bff9a5f..f22c190 100644 --- a/osi/dma/dma_local.h +++ b/osi/dma/dma_local.h @@ -250,8 +250,8 @@ nve32_t dma_desc_init(struct osi_dma_priv_data *osi_dma, } \ #define BOOLEAN_FALSE (0U != 0U) -#define L32(data) ((data) & 0xFFFFFFFFU) -#define H32(data) (((data) & 0xFFFFFFFF00000000UL) >> 32UL) +#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/osi_dma.c b/osi/dma/osi_dma.c index bf18eae..cb07cb0 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -635,8 +635,6 @@ 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; - /* for CERT-C error */ - nveu64_t temp; nveu64_t tailptr = 0; struct osi_rx_swcx *rx_swcx = OSI_NULL; struct osi_rx_desc *rx_desc = OSI_NULL; @@ -660,24 +658,8 @@ nve32_t osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, rx_swcx->flags = 0; /* Populate the newly allocated buffer address */ - temp = L32(rx_swcx->buf_phy_addr); - if (temp > UINT_MAX) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma: Invalid buf_phy_addr\n", 0ULL); - /* error case do nothing */ - } else { - /* Store Receive Descriptor 0 */ - rx_desc->rdes0 = (nveu32_t)temp; - } - - temp = H32(rx_swcx->buf_phy_addr); - if (temp <= UINT_MAX) { - /* Store Receive Descriptor 1 */ - rx_desc->rdes1 = (nveu32_t)temp; - } else { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma: Invalid buf_phy_addr\n", 0ULL); - } + 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; diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index c6f37e0..ddc02cb 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -820,19 +820,8 @@ static inline void fill_first_desc(struct osi_tx_ring *tx_ring, struct osi_tx_swcx *tx_swcx, unsigned int ptp_flag) { - nveu64_t tmp; - - /* update the first buffer pointer and length */ - tmp = L32(tx_swcx->buf_phy_addr); - if (tmp < UINT_MAX) { - tx_desc->tdes0 = (nveu32_t)tmp; - } - - tmp = H32(tx_swcx->buf_phy_addr); - if (tmp < UINT_MAX) { - tx_desc->tdes1 = (nveu32_t)tmp; - } - + 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; @@ -995,7 +984,7 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, nve32_t cntx_desc_consumed; nveu32_t pkt_id = 0x0U; nveu32_t desc_cnt = 0U; - nveu64_t tailptr, tmp; + nveu64_t tailptr; nveu32_t entry = 0U; nveu32_t i; @@ -1082,15 +1071,8 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, /* Fill remaining descriptors */ for (i = 0; i < desc_cnt; i++) { - tmp = L32(tx_swcx->buf_phy_addr); - if (tmp < UINT_MAX) { - tx_desc->tdes0 = (nveu32_t)tmp; - } - - tmp = H32(tx_swcx->buf_phy_addr); - if (tmp < UINT_MAX) { - tx_desc->tdes1 = (nveu32_t)tmp; - } + 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; @@ -1202,7 +1184,7 @@ static nve32_t rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, 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, tmp; + nveu64_t tailptr = 0; nveu32_t i; nve32_t ret = 0; @@ -1226,24 +1208,8 @@ static nve32_t rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, rx_desc->rdes2 = 0; rx_desc->rdes3 = 0; - tmp = L32(rx_swcx->buf_phy_addr); - if (tmp < UINT_MAX) { - rx_desc->rdes0 = (nveu32_t)tmp; - } else { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma_txrx: Invalid buf_phy_addr\n", 0ULL); - return -1; - } - - tmp = H32(rx_swcx->buf_phy_addr); - if (tmp < UINT_MAX) { - rx_desc->rdes1 = (nveu32_t)tmp; - } else { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma_txrx: Invalid buf_phy_addr\n", 0ULL); - return -1; - } - + 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; From a44aadc1cac0299e15d852ee372f50bfac92ca29 Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Tue, 28 Sep 2021 01:40:39 +0530 Subject: [PATCH 288/458] osi: core: Set QHLBF bit As per HW fix, program QHLBF to 1 to get HLBF error in 1-2 cycle of GCL. Bug 200778825 Bug 200649072 case: 01085007 Change-Id: I18cfa6ad4eda56e2684abd86b7dc02c7a143c0ef Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2601421 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/eqos_core.c | 1 + osi/core/eqos_core.h | 1 + osi/core/mgbe_core.c | 1 + osi/core/mgbe_core.h | 1 + 4 files changed, 4 insertions(+) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 6710965..69ac811 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -4731,6 +4731,7 @@ static int eqos_hw_config_est(struct osi_core_priv_data *osi_core, /* 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; diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 01b78ac..3ed5162 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -560,6 +560,7 @@ #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) | \ diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 7574965..293cbee 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -4810,6 +4810,7 @@ static int mgbe_hw_config_est(struct osi_core_priv_data *osi_core, /* 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); diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index a22e23b..db24513 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -648,6 +648,7 @@ /* 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) | \ From ad3466897ec88b30a7e26b0a74de7b31dc77d2d3 Mon Sep 17 00:00:00 2001 From: Mahesh Patil <maheshp@nvidia.com> Date: Mon, 27 Sep 2021 17:29:30 -0700 Subject: [PATCH 289/458] nvethernetrm: Fix err for macro MACSEC_KEY_PROGRAM Fix compiler err when macro MACSEC_KEY_PROGRAM enabled Bug 3389496 Change-Id: Ic95dd8c5b63538f3f246122ddb203a649afc6975 Signed-off-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2601538 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Sanath Kumar Gampa <sgampa@nvidia.com> Reviewed-by: Nagaraj Annaiah <nannaiah@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/ivc_core.c | 2 +- osi/core/macsec.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index 144cff0..ea60491 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -398,7 +398,7 @@ static int ivc_macsec_kt_config(struct osi_core_priv_data *const osi_core, (void *)kt_config, sizeof(struct osi_macsec_kt_config)); - return osi_core->osd_ops.ivc_send(osi_core, (char *)&msg, sizeof(msg)); + return osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); } #endif /* MACSEC_KEY_PROGRAM */ diff --git a/osi/core/macsec.h b/osi/core/macsec.h index 5f11a5d..108c727 100644 --- a/osi/core/macsec.h +++ b/osi/core/macsec.h @@ -29,7 +29,7 @@ * @brief MACsec controller register offsets * @{ */ -#define MASCEC_GCM_KEYTABLE_CONFIG 0x0000 +#define MACSEC_GCM_KEYTABLE_CONFIG 0x0000 #define MACSEC_GCM_KEYTABLE_DATA(x) (0x0004 + (x * 4)) #define MACSEC_RX_ICV_ERR_CNTRL 0x4000 #define MACSEC_INTERRUPT_COMMON_SR 0x4004 From 4b816f1f2f78a160d1d29a250e95f4bd8ffe3a42 Mon Sep 17 00:00:00 2001 From: Nagaraj Annaiah <nannaiah@nvidia.com> Date: Tue, 5 Oct 2021 19:28:01 +0000 Subject: [PATCH 290/458] osi: core & dma : Increase osi and dma instances - Increase OSI and DMA instances to 10 to support multiple VF's. - Copy PTP config to ioctl structure. Bug 2694285 Change-Id: I558b161c64a5467dc9e7260e58801eb6b1735d50 Signed-off-by: Nagaraj Annaiah <nannaiah@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2605781 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/core_local.h | 2 +- osi/core/ivc_core.c | 2 +- osi/dma/dma_local.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osi/core/core_local.h b/osi/core/core_local.h index be28ab5..75863d4 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -30,7 +30,7 @@ * @brief Maximum number of OSI core instances. */ #ifndef MAX_CORE_INSTANCES -#define MAX_CORE_INSTANCES 5U +#define MAX_CORE_INSTANCES 10U #endif /** diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index ea60491..bfff91b 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -60,7 +60,7 @@ static nve32_t ivc_handle_ioctl(struct osi_core_priv_data *osi_core, sizeof(struct osi_ioctl)); if (data->cmd == OSI_CMD_CONFIG_PTP) { - osi_memcpy((void *)&data->ptp_config, + osi_memcpy((void *)&msg.data.ioctl_data.ptp_config, (void *)&osi_core->ptp_config, sizeof(struct osi_ptp_config)); } diff --git a/osi/dma/dma_local.h b/osi/dma/dma_local.h index f22c190..163f9a1 100644 --- a/osi/dma/dma_local.h +++ b/osi/dma/dma_local.h @@ -31,7 +31,7 @@ * @brief Maximum number of OSI DMA instances. */ #ifndef MAX_DMA_INSTANCES -#define MAX_DMA_INSTANCES 5U +#define MAX_DMA_INSTANCES 10U #endif /** From 06482fbf0b34d26e5f37fd9d90221eceb6da7e3a Mon Sep 17 00:00:00 2001 From: Sanath Kumar Gampa <sgampa@nvidia.com> Date: Mon, 4 Oct 2021 16:11:22 +0530 Subject: [PATCH 291/458] nvethernetrm: MTL_EST CTOV config for MACSEC Issue: h/w requirement to change the MTL_EST value depending on MACSEC Fix: Change the value in MACSEC enable/disable flow Bug 200630202 Change-Id: Iefdb14e44841941ab3e8f8c116746b0db6c63ba5 Signed-off-by: Sanath Kumar Gampa <sgampa@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2604830 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/core_local.h | 2 +- osi/core/eqos_core.c | 37 ++++++++++++++++++++++++++++++++----- osi/core/eqos_core.h | 4 ++++ osi/core/macsec.c | 16 ++++++++-------- osi/core/mgbe_core.c | 35 ++++++++++++++++++++++++++++++----- osi/core/mgbe_core.h | 7 +++++++ 6 files changed, 82 insertions(+), 19 deletions(-) diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 75863d4..8f15e3a 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -267,7 +267,7 @@ struct core_ops { int (*config_ptp_offload)(struct osi_core_priv_data *const osi_core, struct osi_pto_config *const pto_config); #ifdef MACSEC_SUPPORT - void (*config_macsec_ipg)(struct osi_core_priv_data *const osi_core, + 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, diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 69ac811..1bcdb31 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -6389,13 +6389,14 @@ static nve32_t eqos_config_rss(struct osi_core_priv_data *const osi_core) #ifdef MACSEC_SUPPORT /** - * @brief eqos_config_macsec_ipg - Configure MAC IPG according to macsec IAS + * @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 @@ -6410,11 +6411,16 @@ static nve32_t eqos_config_rss(struct osi_core_priv_data *const osi_core) * - Run time: Yes * - De-initialization: No */ -void eqos_config_macsec_ipg(struct osi_core_priv_data *const osi_core, - const nveu32_t enable) +void eqos_config_for_macsec(struct osi_core_priv_data *const osi_core, + const nveu32_t enable) { - nveu32_t value; + nveu32_t value = 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); @@ -6453,7 +6459,28 @@ void eqos_config_macsec_ipg(struct osi_core_priv_data *const osi_core, /* start MAC Tx */ eqos_config_mac_tx(osi_core, OSI_ENABLE); } + + /* Updated MTL_EST depending on MACSEC enable/disable */ + if (osi_core->hw_feature->est_sel == OSI_ENABLE) { + value = osi_readla(osi_core, + (unsigned char *)osi_core->base + + EQOS_MTL_EST_CONTROL); + value &= ~EQOS_MTL_EST_CONTROL_CTOV; + if (enable == OSI_ENABLE) { + value |= (EQOS_MTL_EST_CTOV_MACSEC_RECOMMEND << + EQOS_MTL_EST_CONTROL_CTOV_SHIFT) & + EQOS_MTL_EST_CONTROL_CTOV; + } else { + value |= (EQOS_MTL_EST_CTOV_RECOMMEND << + EQOS_MTL_EST_CONTROL_CTOV_SHIFT) & + EQOS_MTL_EST_CONTROL_CTOV; + } + osi_writela(osi_core, value, + (nveu8_t *)osi_core->base + + EQOS_MTL_EST_CONTROL); + } } + #endif /* MACSEC_SUPPORT */ /** @@ -6529,7 +6556,7 @@ void eqos_init_core_ops(struct core_ops *ops) ops->update_frp_nve = eqos_update_frp_nve; ops->config_rss = eqos_config_rss; #ifdef MACSEC_SUPPORT - ops->config_macsec_ipg = eqos_config_macsec_ipg; + ops->macsec_config_mac = eqos_config_for_macsec; #endif /* MACSEC_SUPPORT */ ops->ptp_tsc_capture = eqos_ptp_tsc_capture; } diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 3ed5162..5f03a65 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -553,6 +553,10 @@ OSI_BIT(22) | OSI_BIT(23)) #define EQOS_MTL_EST_CONTROL_CTOV_SHIFT 12U #define EQOS_MTL_EST_CTOV_RECOMMEND 94U +#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)) diff --git a/osi/core/macsec.c b/osi/core/macsec.c index e5570b8..0ac216d 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -2455,12 +2455,12 @@ static nve32_t macsec_deinit(struct osi_core_priv_data *const osi_core) sizeof(struct osi_macsec_lut_status)); } - /* Update MAC ipg value as per macsec requirement */ - if (l_core->ops_p->config_macsec_ipg != OSI_NULL) { - l_core->ops_p->config_macsec_ipg(osi_core, OSI_DISABLE); + /* 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 macsec IPG\n", 0ULL); + "Failed config MAC per macsec\n", 0ULL); } return 0; @@ -2482,12 +2482,12 @@ static nve32_t macsec_init(struct osi_core_priv_data *const osi_core) nve32_t ret = 0; nveu16_t i, j; - /* Update MAC ipg value as per macsec requirement */ - if (l_core->ops_p->config_macsec_ipg != OSI_NULL) { - l_core->ops_p->config_macsec_ipg(osi_core, OSI_ENABLE); + /* 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 config macsec IPG\n", 0ULL); + "Failed to config mac per macsec\n", 0ULL); } /* Set MTU */ diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 293cbee..06ac7e6 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -5777,13 +5777,14 @@ static void mgbe_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, #ifdef MACSEC_SUPPORT /** - * @brief mgbe_config_macsec_ipg - Configure MAC IPG according to macsec IAS + * @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 @@ -5798,11 +5799,15 @@ static void mgbe_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, * - Run time: Yes * - De-initialization: No */ -void mgbe_config_macsec_ipg(struct osi_core_priv_data *const osi_core, - const nveu32_t enable) +void mgbe_config_for_macsec(struct osi_core_priv_data *const osi_core, + const nveu32_t enable) { nveu32_t value = 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) { @@ -5837,6 +5842,26 @@ void mgbe_config_macsec_ipg(struct osi_core_priv_data *const osi_core, } /* start MAC Tx */ mgbe_config_mac_tx(osi_core, OSI_ENABLE); + + /* Program MTL_EST depending on MACSEC enable/disable */ + if (osi_core->hw_feature->est_sel == OSI_ENABLE) { + value = osi_readla(osi_core, + (unsigned char *)osi_core->base + + MGBE_MTL_EST_CONTROL); + value &= ~MGBE_MTL_EST_CONTROL_CTOV; + if (enable == OSI_ENABLE) { + value |= (MGBE_MTL_EST_CTOV_MACSEC_RECOMMEND << + MGBE_MTL_EST_CONTROL_CTOV_SHIFT) & + MGBE_MTL_EST_CONTROL_CTOV; + } else { + value |= (MGBE_MTL_EST_CTOV_RECOMMEND << + MGBE_MTL_EST_CONTROL_CTOV_SHIFT) & + MGBE_MTL_EST_CONTROL_CTOV; + } + osi_writela(osi_core, value, + (unsigned char *)osi_core->base + + MGBE_MTL_EST_CONTROL); + } } #endif /* MACSEC_SUPPORT */ @@ -5903,6 +5928,6 @@ void mgbe_init_core_ops(struct core_ops *ops) ops->write_reg = mgbe_write_reg; ops->read_reg = mgbe_read_reg; #ifdef MACSEC_SUPPORT - ops->config_macsec_ipg = mgbe_config_macsec_ipg; + ops->macsec_config_mac = mgbe_config_for_macsec; #endif /* MACSEC_SUPPORT */ }; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index db24513..d39d283 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -633,6 +633,13 @@ OSI_BIT(21) | OSI_BIT(22)) #define MGBE_MTL_EST_CONTROL_CTOV_SHIFT 11U #define MGBE_MTL_EST_CTOV_RECOMMEND 42U +#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)) From 6b2420082026f6ed540d1d338ddf0e7332b084d3 Mon Sep 17 00:00:00 2001 From: Sanath Kumar Gampa <sgampa@nvidia.com> Date: Wed, 6 Oct 2021 21:03:09 +0530 Subject: [PATCH 292/458] nvethernetrm:Disabled DIC as part of mgbe init Issue:seeing 0 Throughput after MACSEC is enabled Fix: Disable DIC to fix 0 Tput issue Bug 200770840 Change-Id: I8cceee8fd8509ec484bfbb6063ca4dd8be091fa5 Signed-off-by: Sanath Kumar Gampa <sgampa@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2606457 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/mgbe_core.c | 2 ++ osi/core/mgbe_core.h | 1 + 2 files changed, 3 insertions(+) diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 06ac7e6..edd5552 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -2630,6 +2630,8 @@ static int mgbe_configure_mac(struct osi_core_priv_data *osi_core) 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; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index d39d283..7f2fe5c 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -444,6 +444,7 @@ #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) From 252c4c94f750dad280264d53d7a9d8407bad4744 Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Wed, 13 Oct 2021 19:52:46 +0530 Subject: [PATCH 293/458] osi: core: Add MTU IOCTL support Issue: When the ethernet server got enabled, the MTU changes are not getting communicated to the ethernet server. Fix: Add new OSI IOCTL and implement HAL and IVC message for ethernet server. Bug 3402313 Change-Id: I28bab58c2847d275324e54229ac50459d3059d26 Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2610189 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Nagaraj Annaiah <nannaiah@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_core.h | 1 + osi/core/osi_hal.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/include/osi_core.h b/include/osi_core.h index 897beef..5a7fc76 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -221,6 +221,7 @@ typedef my_lint_64 nvel64_t; #define OSI_CMD_STRUCTS_DUMP 45U #endif /* OSI_DEBUG */ #define OSI_CMD_CAP_TSC_PTP 46U +#define OSI_CMD_MAC_MTU 47U /** @} */ /** diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 9823e15..90e7d9e 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -1666,6 +1666,10 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, ret = 0; break; + case OSI_CMD_MAC_MTU: + ret = 0; + break; + #ifdef OSI_DEBUG case OSI_CMD_REG_DUMP: core_reg_dump(osi_core); From 17f17453b342f06df0df10e42a86156be27a6dae Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Tue, 12 Oct 2021 20:28:16 +0530 Subject: [PATCH 294/458] osi: dma: check TDES3_ES_BITS for EQOS Issue: TDES3_ES_BITS not valid for MGBE which results wrong error stats in ethtool o/p Fix: Check TDES3_ES_BITS only for EQOS. Bug 200779501 Change-Id: Idccc8cca54b2fe6f8ac30ed99f2cc69d093acea9 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2609473 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/dma/osi_dma_txrx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index ddc02cb..aef9bd0 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -589,7 +589,8 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, /* check for Last Descriptor */ if ((tx_desc->tdes3 & TDES3_LD) == TDES3_LD) { - if ((tx_desc->tdes3 & TDES3_ES_BITS) != 0U) { + 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, From be0b411fd46bc48f149a311f9d3ab60663e79193 Mon Sep 17 00:00:00 2001 From: Sanath Kumar Gampa <sgampa@nvidia.com> Date: Thu, 21 Oct 2021 15:18:22 +0530 Subject: [PATCH 295/458] osi:macsec: changes to send next PN to supplicant As part of MKA, supplicant requests for Next PN used by SecY. Added changes to OSI to send to send the Next PN for a given SCI and AN. Bug 3371004 Change-Id: Iaf001ba5e6b5480396e2f774a42927831160a2e5 Signed-off-by: Sanath Kumar Gampa <sgampa@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2614365 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_macsec.h | 42 ++++++++++++++++++++++++++++++++++++++++++ osi/core/macsec.c | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/include/osi_macsec.h b/include/osi_macsec.h index 6316f45..cdbc6c1 100644 --- a/include/osi_macsec.h +++ b/include/osi_macsec.h @@ -396,6 +396,9 @@ struct osi_macsec_core_ops { /** 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, nve32_t *key_index, nveu16_t ctlr); }; @@ -900,4 +903,43 @@ 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 MACSEC Key Index Start for a given SCI + * + * @note + * Algorithm: + * - Retrieves the Key_index used for a given SCI in SC. + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] sci: Secure Channel Identifier + * @param[out] key_index: Pointer which will be filled with key_index start + * @param[in] ctrl: Tx or Rx controller + * + * + * @pre + * - MACSEC shall be initialized and enalbed + * + * @note + * Traceability Details: + * - SWUD_ID: + * + * @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 vaid Key Index Start 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, nve32_t *key_index, nveu16_t ctlr); #endif /* INCLUDED_OSI_MACSEC_H */ diff --git a/osi/core/macsec.c b/osi/core/macsec.c index 0ac216d..870e82a 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -2672,6 +2672,32 @@ static struct osi_macsec_sc_info *find_existing_sc( return OSI_NULL; } +nve32_t macsec_get_sc_lut_key_index(struct osi_core_priv_data *const osi_core, + nveu8_t *sci, nve32_t *key_index, nveu16_t ctlr) +{ + struct osi_macsec_sc_info sc; + struct osi_macsec_sc_info *sc_info = OSI_NULL; + + /* 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; + } + + osi_memcpy(sc.sci, sci, OSI_SCI_LEN); + 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; +} + static nve32_t del_upd_sc(struct osi_core_priv_data *const osi_core, struct osi_macsec_sc_info *existing_sc, struct osi_macsec_sc_info *const sc, @@ -3107,6 +3133,7 @@ static struct osi_macsec_core_ops macsec_ops = { .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_sc_lut_key_index, }; /** @@ -3178,6 +3205,19 @@ nve32_t osi_macsec_lut_config(struct osi_core_priv_data *const osi_core, return -1; } +nve32_t osi_macsec_get_sc_lut_key_index(struct osi_core_priv_data *const osi_core, + nveu8_t *sci, nve32_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; +} + #ifdef MACSEC_KEY_PROGRAM nve32_t osi_macsec_kt_config(struct osi_core_priv_data *const osi_core, struct osi_macsec_kt_config *const kt_config) From ad03676e697ad4d29c70aff1ac0f83b5dc95509e Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Mon, 16 Aug 2021 18:37:52 +0530 Subject: [PATCH 296/458] nvethernetrm: MAC to MAC time sync - Add code to store role of FD - Function to return osi_core pointer for first role match. - add code to calculate time offset between Primary and Secondary PTP controller HW time. - calculate frequency adjustment calculation. - call appropriate HAL function for secondary interface. Bug 200733666 Change-Id: I7a141ea691d80d9f69fd18b28ae0964cb1bf2fb3 Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2614283 Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_core.h | 15 +- include/osi_dma.h | 7 +- osi/core/core_local.h | 83 ++++++++++ osi/core/osi_core.c | 47 +++++- osi/core/osi_hal.c | 349 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 494 insertions(+), 7 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 5a7fc76..5acd755 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -49,14 +49,23 @@ typedef my_lint_64 nvel64_t; /** @} */ /** - * @addtogroup PTP related information + * @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 /** @} */ /** @@ -1295,6 +1304,10 @@ struct osi_core_priv_data { 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; }; /** diff --git a/include/osi_dma.h b/include/osi_dma.h index a6fe4d3..1b141c9 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -579,8 +579,11 @@ struct osi_dma_priv_data { /** Tegra Pre-si platform info */ nveu32_t pre_si; /** PTP flags - * bit 0 PTP mode master(1) slave(0) - * bit 1 PTP sync method twostep(1) onestep(0) */ + * 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; diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 8f15e3a..0cd03a4 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -274,6 +274,50 @@ struct core_ops { struct osi_core_ptp_tsc_data *data); }; +/** + * @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. @@ -303,6 +347,14 @@ struct core_local { 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; }; /** @@ -383,4 +435,35 @@ void hw_interface_init_core_ops(struct if_core_ops *if_ops_p); */ 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/osi_core.c b/osi/core/osi_core.c index 508dbb4..f5eaadf 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -128,6 +128,26 @@ struct osi_core_priv_data *osi_get_core(void) 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; @@ -166,8 +186,15 @@ nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core) "if_init_core_ops failed\n", 0ULL); return ret; } - l_core->if_init_done = OSI_ENABLE; 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); + l_core->hw_init_successful = OSI_DISABLE; + l_core->m2m_tsync = OSI_DISABLE; + l_core->if_init_done = OSI_ENABLE; return ret; } @@ -202,24 +229,36 @@ 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; + nve32_t ret; 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); + ret = l_core->if_ops_p->if_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_hw_core_deinit(struct osi_core_priv_data *const osi_core) { struct core_local *l_core = (struct core_local *)osi_core; + nve32_t ret; if (validate_if_args(osi_core, l_core) < 0) { return -1; } - return l_core->if_ops_p->if_core_deinit(osi_core); + ret = l_core->if_ops_p->if_core_deinit(osi_core); + if (ret == 0) { + l_core->hw_init_successful = OSI_DISABLE; + } + + return ret; } nve32_t osi_handle_ioctl(struct osi_core_priv_data *osi_core, diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 90e7d9e..f647752 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -1457,12 +1457,189 @@ 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 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; @@ -1558,6 +1735,10 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, #endif /* !OSI_STRIPPED_LIB */ case OSI_CMD_POLL_FOR_MAC_RST: ret = ops_p->poll_for_swr(osi_core); + /* For ethernet server */ + if (ret == 0) { + l_core->hw_init_successful = OSI_ENABLE; + } break; case OSI_CMD_START_MAC: @@ -1606,14 +1787,140 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, 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: @@ -1623,6 +1930,48 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, 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); From 25c8f7254eb6a2925920866e86482ad3a87eaa7b Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Fri, 22 Oct 2021 12:42:03 +0530 Subject: [PATCH 297/458] nvethernetrm: core: MAC to MAC tsync dynamic support Add code to support enable/disable M2M sync using ioctl. Bug 200733666 Change-Id: Ifedad7981644c816345f3e10a0b0f8289e032200 Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2614964 Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_core.h | 9 +++++++++ osi/core/osi_hal.c | 7 +++++++ 2 files changed, 16 insertions(+) diff --git a/include/osi_core.h b/include/osi_core.h index 5acd755..d3fe4c5 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -231,6 +231,7 @@ typedef my_lint_64 nvel64_t; #endif /* OSI_DEBUG */ #define OSI_CMD_CAP_TSC_PTP 46U #define OSI_CMD_MAC_MTU 47U +#define OSI_CMD_CONF_M2M_TS 48U /** @} */ /** @@ -2313,6 +2314,10 @@ nve32_t osi_get_hw_features(struct osi_core_priv_data *const osi_core, * 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 * @@ -2509,6 +2514,10 @@ struct osi_core_priv_data *osi_get_core(void); * 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 * diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index f647752..897c007 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -2033,6 +2033,13 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, 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; + default: OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "CORE: Incorrect command\n", From 45ecc719d22274bef03a5f3e507f843066d72ffe Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Wed, 27 Oct 2021 08:12:36 +0530 Subject: [PATCH 298/458] osi: xpcs: Remove XPCS lane bring up retry Issue: When the ethernet server got enabled the boot time KPI increased due to the XPCS lane up retry. Fix: Remove retry from OSI and add SET_SPEED ioctl retry from OSD. Bug 3414276 Change-Id: I617ab51ee6ddd50b449f78ecc9c858b1d9196b3e Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2617516 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Nagaraj Annaiah <nannaiah@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/xpcs.c | 57 ++++++++++++++++++------------------------------- 1 file changed, 21 insertions(+), 36 deletions(-) diff --git a/osi/core/xpcs.c b/osi/core/xpcs.c index 4486cfb..7bba29c 100644 --- a/osi/core/xpcs.c +++ b/osi/core/xpcs.c @@ -309,10 +309,8 @@ static nve32_t xpcs_lane_bring_up(struct osi_core_priv_data *osi_core) { unsigned int retry = 1000; unsigned int count; - int cond; - nveu32_t cnt = 0; nveu32_t val = 0; -#define PCS_RETRY_MAX 300 + int cond; if (xpcs_uphy_lane_bring_up(osi_core, XPCS_WRAP_UPHY_HW_INIT_CTRL_TX_EN) < 0) { @@ -393,43 +391,30 @@ static nve32_t xpcs_lane_bring_up(struct osi_core_priv_data *osi_core) 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); - while (cnt < PCS_RETRY_MAX) { - /* 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); - /* 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); - 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) { - cnt += 1; - osi_core->osd_ops.udelay(1000U); - } else { - OSI_CORE_INFO(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "PCS block lock SUCCESS\n", 0ULL); - break; - } - } - - if (cnt == PCS_RETRY_MAX) { + 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 after max retries\n", - cnt); + "Failed to get PCS block lock\n", 0ULL); return -1; } From 1ad0b32135e308d2050c03ec86d958109bb0133c Mon Sep 17 00:00:00 2001 From: Sanath Kumar Gampa <sgampa@nvidia.com> Date: Tue, 2 Nov 2021 09:21:48 +0530 Subject: [PATCH 299/458] osi:macsec:lowest pn changes to enable sa Enhancement to receive lowest_pn from supplicant as part of receive AN enable Bug 3371004 Change-Id: If81f8449f7ebda996c95117e2c84722fdc57c5d0 Signed-off-by: Sanath Kumar Gampa <sgampa@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2619949 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_macsec.h | 2 ++ osi/core/macsec.c | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/osi_macsec.h b/include/osi_macsec.h index cdbc6c1..e421087 100644 --- a/include/osi_macsec.h +++ b/include/osi_macsec.h @@ -278,6 +278,8 @@ struct osi_macsec_sc_info { 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 */ diff --git a/osi/core/macsec.c b/osi/core/macsec.c index 870e82a..0726f7f 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -2859,8 +2859,7 @@ static nve32_t add_upd_sc(struct osi_core_priv_data *const osi_core, lut_config.lut_sel = OSI_LUT_SEL_SA_STATE; table_config->index = (sc->sc_idx_start * OSI_MAX_NUM_SA) + sc->curr_an; lut_config.sa_state_out.next_pn = sc->next_pn; - /* TODO - LLPN might have to be updated out of band for replay prot*/ - lut_config.sa_state_out.lowest_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) { From bf4ed97f22b2be3a2282709b132f7511151f4570 Mon Sep 17 00:00:00 2001 From: Bibhay Ranjan <bibhayr@nvidia.com> Date: Tue, 5 Oct 2021 18:38:56 +0530 Subject: [PATCH 300/458] nveqos:fix MISRA_C-2012_Rule_8.13 and 10.4 issues MISRA FIXES ===== DIFF ====== Total misra violation count changed by -21 Rule: MISRA_C-2012_Rule_10.4 Diff: -1 Rule: MISRA_C-2012_Rule_8.13 Diff: -20 Rule: Total Diff: -21 CERT FIXES ===== DIFF ====== Total cert violation count changed by 0 Bug 200770325 Change-Id: Ib6cca8c2eaff5ae8cddd718b2f0c309c6888d4fc Signed-off-by: Bibhay Ranjan <bibhayr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2605632 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/ivc_core.h | 2 +- include/osi_dma.h | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/include/ivc_core.h b/include/ivc_core.h index 0ddb5aa..069345e 100644 --- a/include/ivc_core.h +++ b/include/ivc_core.h @@ -28,7 +28,7 @@ /** * @brief Ethernet Maximum IVC BUF */ -#define ETHER_MAX_IVC_BUF 2048 +#define ETHER_MAX_IVC_BUF 2048U /** * @brief IVC maximum arguments diff --git a/include/osi_dma.h b/include/osi_dma.h index 1b141c9..5941c66 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -488,11 +488,12 @@ struct osd_dma_ops { /** DMA transmit complete callback */ void (*transmit_complete)(void *priv, void *buffer, nveu64_t dmaaddr, nveu32_t len, - struct osi_txdone_pkt_cx *txdone_pkt_cx); + 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, - struct osi_rx_pkt_cx *rx_pkt_cx, + 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, From 06a21e0c167816ee50e20c3c9ef3dd6757283c10 Mon Sep 17 00:00:00 2001 From: Sanath Kumar Gampa <sgampa@nvidia.com> Date: Wed, 10 Nov 2021 16:29:26 +0530 Subject: [PATCH 301/458] osi:macsec:Fix to address sc_an_not_valid counter Issue: tx_sc_an_not_valid counter is increasing in stress tests when there is AN roll over happens Fix: Program the SCI LUT with vaid AN map and then enable AN in sc_state LUT Bug 3422356 Change-Id: I17021d435076ff94367a58a4c74b50124c97d68a Signed-off-by: Sanath Kumar Gampa <sgampa@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2623649 GVS: Gerrit_Virtual_Submit Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Mahesh Patil <maheshp@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/macsec.c | 47 ++++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/osi/core/macsec.c b/osi/core/macsec.c index 0726f7f..907b1bc 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -2868,19 +2868,7 @@ static nve32_t add_upd_sc(struct osi_core_priv_data *const osi_core, goto err_sa_state; } - /* 3. SC state LUT */ - lut_config.flags = OSI_NONE; - lut_config.lut_sel = OSI_LUT_SEL_SC_STATE; - table_config->index = 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", ret); - goto err_sc_state; - } - - /* 4. SC param LUT */ + /* 3. SC param LUT */ lut_config.flags = OSI_NONE; lut_config.lut_sel = OSI_LUT_SEL_SC_PARAM; table_config->index = sc->sc_idx_start; @@ -2902,7 +2890,7 @@ static nve32_t add_upd_sc(struct osi_core_priv_data *const osi_core, goto err_sc_param; } - /* 5. SCI LUT */ + /* 4. SCI LUT */ lut_config.flags = OSI_NONE; lut_config.lut_sel = OSI_LUT_SEL_SCI; table_config->index = sc->sc_idx_start; @@ -2926,8 +2914,30 @@ static nve32_t add_upd_sc(struct osi_core_priv_data *const osi_core, goto err_sci; } + /* 5. SC state LUT */ + lut_config.flags = OSI_NONE; + lut_config.lut_sel = OSI_LUT_SEL_SC_STATE; + table_config->index = 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", 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 = sc->sc_idx_start; + macsec_lut_config(osi_core, &lut_config); + err_sci: /* cleanup SC param */ osi_memset(&lut_config, 0, sizeof(lut_config)); @@ -2938,15 +2948,6 @@ err_sci: macsec_lut_config(osi_core, &lut_config); err_sc_param: - /* cleanup SC state */ - 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_STATE; - table_config->index = sc->sc_idx_start; - macsec_lut_config(osi_core, &lut_config); - -err_sc_state: /* Cleanup SA state LUT */ osi_memset(&lut_config, 0, sizeof(lut_config)); table_config = &lut_config.table_config; From 264ae5f040eda7cea843994317610eaa0bccb692 Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Fri, 19 Nov 2021 14:26:03 +0530 Subject: [PATCH 302/458] core: enable m2m_sync for primary and secondary interfaces Issue: Ask is to enable Mac-to-Mac tsync on interface for primary and secondary interface. Fix: update default value. Bug 200733666 Change-Id: Ie00e3cf96d0deb75d7c623a63bc0d06ed637ca2c Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2628723 Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: Sheetal Tigadoli <stigadoli@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/osi_core.c | 24 +++++++++--------------- osi/core/osi_hal.c | 14 +++++++++----- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index f5eaadf..9656878 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -195,6 +195,12 @@ nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core) 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; + } return ret; } @@ -229,36 +235,24 @@ 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; - nve32_t ret; if (validate_if_args(osi_core, l_core) < 0) { return -1; } - ret = l_core->if_ops_p->if_core_init(osi_core, tx_fifo_size, - rx_fifo_size); - if (ret == 0) { - l_core->hw_init_successful = OSI_ENABLE; - } - - return ret; + 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; - nve32_t ret; if (validate_if_args(osi_core, l_core) < 0) { return -1; } - ret = l_core->if_ops_p->if_core_deinit(osi_core); - if (ret == 0) { - l_core->hw_init_successful = OSI_DISABLE; - } - - return ret; + return l_core->if_ops_p->if_core_deinit(osi_core); } nve32_t osi_handle_ioctl(struct osi_core_priv_data *osi_core, diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 897c007..a6071e2 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -234,6 +234,7 @@ 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; @@ -244,7 +245,13 @@ nve32_t osi_hal_hw_core_init(struct osi_core_priv_data *const osi_core, /* Init FRP */ init_frp(osi_core); - return l_core->ops_p->core_init(osi_core, tx_fifo_size, rx_fifo_size); + 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) @@ -255,6 +262,7 @@ nve32_t osi_hal_hw_core_deinit(struct osi_core_priv_data *const osi_core) return -1; } + l_core->hw_init_successful = OSI_DISABLE; l_core->ops_p->core_deinit(osi_core); /* FIXME: Should be fixed */ @@ -1735,10 +1743,6 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, #endif /* !OSI_STRIPPED_LIB */ case OSI_CMD_POLL_FOR_MAC_RST: ret = ops_p->poll_for_swr(osi_core); - /* For ethernet server */ - if (ret == 0) { - l_core->hw_init_successful = OSI_ENABLE; - } break; case OSI_CMD_START_MAC: From cf52f1b2e804007240d58dc953186dcf9c76a457 Mon Sep 17 00:00:00 2001 From: Sanath Kumar Gampa <sgampa@nvidia.com> Date: Mon, 15 Nov 2021 17:20:20 +0530 Subject: [PATCH 303/458] osi:macsec:Changes to enable AN after key program Issue: In longer stress tests we see unint_key_slot errors if the key programing is done after AN is enabled. Fix: Fix is to program the key and then enable AN. Done some code cleanup as well Bug 3422356 Change-Id: I7aeb2f9ab681509b54e9f6763464dfedb46cd26e Signed-off-by: Sanath Kumar Gampa <sgampa@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2626062 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_macsec.h | 9 ++ osi/core/macsec.c | 306 ++++++++++++++++++------------------------- 2 files changed, 137 insertions(+), 178 deletions(-) diff --git a/include/osi_macsec.h b/include/osi_macsec.h index e421087..6602425 100644 --- a/include/osi_macsec.h +++ b/include/osi_macsec.h @@ -172,6 +172,13 @@ #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 */ @@ -286,6 +293,8 @@ struct osi_macsec_sc_info { nveu32_t pn_window; /** SC LUT index */ nveu32_t sc_idx_start; + /** flags - encoding various states of SA */ + nveu32_t flags; }; /** diff --git a/osi/core/macsec.c b/osi/core/macsec.c index 907b1bc..14f7970 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -91,9 +91,6 @@ static inline void write_dbg_buf_data( /* Commit the dbg buffer to HW */ for (i = 0; i < DBG_BUF_LEN; i++) { - /* pr_err("%s: dbg_buf_data[%d]: 0x%x\n", __func__, - i, dbg_buf[i]); - */ osi_writela(osi_core, dbg_buf[i], base + MACSEC_DEBUG_BUF_DATA_0(i)); } @@ -119,8 +116,6 @@ static inline void read_dbg_buf_data( for (i = 0; i < DBG_BUF_LEN; i++) { dbg_buf[i] = osi_readla(osi_core, base + MACSEC_DEBUG_BUF_DATA_0(i)); - /* pr_err("%s: dbg_buf_data[%d]: 0x%x\n", __func__, - i, dbg_buf[i]); */ } } @@ -181,8 +176,8 @@ static void tx_dbg_trigger_evts( tx_trigger_evts &= ~MACSEC_TX_DBG_CAPTURE; } - pr_err("%s: tx_dbg_trigger_evts 0x%x", __func__, - tx_trigger_evts); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "tx_dbg_trigger_evts \n", tx_trigger_evts); osi_writela(osi_core, tx_trigger_evts, base + MACSEC_TX_DEBUG_TRIGGER_EN_0); if (tx_trigger_evts != OSI_NONE) { @@ -190,16 +185,16 @@ static void tx_dbg_trigger_evts( debug_ctrl_reg = osi_readla(osi_core, base + MACSEC_TX_DEBUG_CONTROL_0); debug_ctrl_reg |= MACSEC_TX_DEBUG_CONTROL_0_START_CAP; - pr_err("%s: debug_ctrl_reg 0x%x", __func__, - debug_ctrl_reg); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "debug_ctrl_reg \n", debug_ctrl_reg); osi_writela(osi_core, debug_ctrl_reg, base + MACSEC_TX_DEBUG_CONTROL_0); } } else { tx_trigger_evts = osi_readla(osi_core, base + MACSEC_TX_DEBUG_TRIGGER_EN_0); - pr_err("%s: tx_dbg_trigger_evts 0x%x", __func__, - tx_trigger_evts); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "tx_dbg_trigger_evts \n", tx_trigger_evts); if (tx_trigger_evts & MACSEC_TX_DBG_LKUP_MISS) { flags |= OSI_TX_DBG_LKUP_MISS_EVT; } @@ -278,8 +273,8 @@ static void rx_dbg_trigger_evts( } else { rx_trigger_evts &= ~MACSEC_RX_DBG_CAPTURE; } - pr_err("%s: rx_dbg_trigger_evts 0x%x", __func__, - rx_trigger_evts); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "rx_dbg_trigger_evts \n", rx_trigger_evts); osi_writela(osi_core, rx_trigger_evts, base + MACSEC_RX_DEBUG_TRIGGER_EN_0); if (rx_trigger_evts != OSI_NONE) { @@ -287,16 +282,16 @@ static void rx_dbg_trigger_evts( debug_ctrl_reg = osi_readla(osi_core, base + MACSEC_RX_DEBUG_CONTROL_0); debug_ctrl_reg |= MACSEC_RX_DEBUG_CONTROL_0_START_CAP; - pr_err("%s: debug_ctrl_reg 0x%x", __func__, - debug_ctrl_reg); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "debug_ctrl_reg \n", debug_ctrl_reg); osi_writela(osi_core, debug_ctrl_reg, base + MACSEC_RX_DEBUG_CONTROL_0); } } else { rx_trigger_evts = osi_readla(osi_core, base + MACSEC_RX_DEBUG_TRIGGER_EN_0); - pr_err("%s: rx_dbg_trigger_evts 0x%x", __func__, - rx_trigger_evts); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "rx_dbg_trigger_evts \n", rx_trigger_evts); if (rx_trigger_evts & MACSEC_RX_DBG_LKUP_MISS) { flags |= OSI_RX_DBG_LKUP_MISS_EVT; } @@ -348,8 +343,8 @@ static nve32_t macsec_dbg_buf_config(struct osi_core_priv_data *const osi_core, 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)) { - pr_err("%s(): Wrong index %d\n", __func__, - dbg_buf_config->index); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Wrong index \n", dbg_buf_config->index); return -1; } @@ -359,10 +354,6 @@ static nve32_t macsec_dbg_buf_config(struct osi_core_priv_data *const osi_core, return ret; } - /* pr_err("%s: ctrl: %hu rw: %hu idx: %hu\n", __func__, - dbg_buf_config->ctlr_sel, dbg_buf_config->rw, - dbg_buf_config->index); */ - dbg_config_reg = osi_readla(osi_core, base + MACSEC_DEBUG_BUF_CONFIG_0); if (dbg_buf_config->ctlr_sel) { @@ -401,7 +392,6 @@ nve32_t macsec_dbg_events_config( { nveu32_t i, events = 0; nveu32_t flags = dbg_buf_config->flags; - pr_err("%s():", __func__); /* Validate inputs */ if ((dbg_buf_config->rw > OSI_RW_MAX) || @@ -532,25 +522,31 @@ nve32_t macsec_enable(struct osi_core_priv_data *osi_core, nveu32_t enable) nveu8_t *base = (nveu8_t *)osi_core->macsec_base; val = osi_readla(osi_core, base + MACSEC_CONTROL0); - pr_err("Read MACSEC_CONTROL0: 0x%x\n", val); + 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) { - pr_err("\tEnabling macsec TX"); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "Enabling macsec TX\n", 0ULL); val |= (MACSEC_TX_EN); } else { - pr_err("\tDisabling macsec TX"); + 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) { - pr_err("\tEnabling macsec RX"); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "Enabling macsec RX\n", 0ULL); val |= (MACSEC_RX_EN); } else { - pr_err("\tDisabling macsec RX"); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "Disabling macsec RX\n", 0ULL); val &= ~(MACSEC_RX_EN); } - pr_err("Write MACSEC_CONTROL0: 0x%x\n", val); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "Write MACSEC_CONTROL0:\n", val); osi_writela(osi_core, val, base + MACSEC_CONTROL0); return 0; @@ -664,7 +660,6 @@ static nve32_t kt_key_write(struct osi_core_priv_data *const osi_core, } for (i = 0; i < MACSEC_KT_DATA_REG_CNT; i++) { - /* pr_err("%s: kt_key[%d]: 0x%x\n", __func__, i, kt_key[i]); */ osi_writela(osi_core, kt_key[i], (nveu8_t *)osi_core->tz_base + MACSEC_GCM_KEYTABLE_DATA(i)); @@ -693,10 +688,6 @@ static nve32_t macsec_kt_config(struct osi_core_priv_data *const osi_core, return ret; } - /* pr_err("%s: ctrl: %hu rw: %hu idx: %hu flags: %#x\n", __func__, - kt_config->table_config.ctlr_sel, - kt_config->table_config.rw, kt_config->table_config.index, - kt_config->flags); */ kt_config_reg = osi_readla(osi_core, base + MACSEC_GCM_KEYTABLE_CONFIG); if (kt_config->table_config.ctlr_sel) { kt_config_reg |= MACSEC_KT_CONFIG_CTLR_SEL; @@ -789,7 +780,6 @@ static inline void read_lut_data(struct osi_core_priv_data *const osi_core, /* 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)); - //pr_err("%s: lut_data[%d]: 0x%x\n", __func__, i, lut_data[i]); } } @@ -1185,7 +1175,6 @@ static nve32_t lut_data_read(struct osi_core_priv_data *const osi_core, break; case OSI_LUT_SEL_SCI: if (sci_lut_read(osi_core, lut_config) != 0) { - pr_err("\n"); OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "SCI LUT read err\n", 0ULL); return -1; @@ -1229,7 +1218,6 @@ static inline void commit_lut_data(struct osi_core_priv_data *const osi_core, /* Commit the LUT entry to HW */ for (i = 0; i < MACSEC_LUT_DATA_REG_CNT; i++) { - //pr_err("%s: lut_data[%d]: 0x%x\n", __func__, i, lut_data[i]); osi_writela(osi_core, lut_data[i], base + MACSEC_LUT_DATA(i)); } } @@ -1860,11 +1848,8 @@ static nve32_t macsec_lut_config(struct osi_core_priv_data *const osi_core, (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)) { - pr_err("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); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Validating LUT config failed.\n", 0ULL); return -1; } @@ -1874,12 +1859,6 @@ static nve32_t macsec_lut_config(struct osi_core_priv_data *const osi_core, return ret; } -/* pr_err("%s: LUT: %hu ctrl: %hu rw: %hu idx: %hu flags: %#x\n", __func__, - lut_config->lut_sel, lut_config->table_config.ctlr_sel, - lut_config->table_config.rw, lut_config->table_config.index, - lut_config->flags); -*/ - lut_config_reg = osi_readla(osi_core, base + MACSEC_LUT_CONFIG); if (lut_config->table_config.ctlr_sel) { lut_config_reg |= MACSEC_LUT_CONFIG_CTLR_SEL; @@ -1930,8 +1909,6 @@ static inline void handle_rx_sc_invalid_key( nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; nveu32_t clear = 0; - pr_err("%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); @@ -1947,8 +1924,6 @@ static inline void handle_tx_sc_invalid_key( nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; nveu32_t clear = 0; - pr_err("%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); @@ -1961,7 +1936,6 @@ static inline void handle_tx_sc_invalid_key( static inline void handle_safety_err_irq( struct osi_core_priv_data *const osi_core) { - pr_err("%s()\n", __func__); } static inline void handle_rx_sc_replay_err( @@ -1970,8 +1944,6 @@ static inline void handle_rx_sc_replay_err( nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; nveu32_t clear = 0; - /* pr_err("%s()\n", __func__); */ - /* rx_sc0_7 */ clear = osi_readla(osi_core, addr + MACSEC_RX_SC_REPLAY_ERROR_STATUS0_0); @@ -1990,8 +1962,6 @@ static inline void handle_rx_pn_exhausted( nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; nveu32_t clear = 0; - /* pr_err("%s()\n", __func__); */ - /* Check which SC/AN had triggered and clear */ /* rx_sc0_7 */ clear = osi_readla(osi_core, addr + @@ -2010,7 +1980,6 @@ 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; - /* pr_err("%s()\n", __func__); */ clear = osi_readla(osi_core, addr + MACSEC_TX_SC_ERROR_INTERRUPT_STATUS_0); osi_writela(osi_core, clear, addr + @@ -2024,8 +1993,6 @@ static inline void handle_tx_pn_threshold( nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; nveu32_t clear = 0; - /* pr_err("%s()\n", __func__); */ - /* check which SC/AN had triggered and clear */ /* tx_sc0_7 */ clear = osi_readla(osi_core, addr + @@ -2045,8 +2012,6 @@ static inline void handle_tx_pn_exhausted( nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; nveu32_t clear = 0; - /* pr_err("%s()\n", __func__); */ - /* check which SC/AN had triggered and clear */ /* tx_sc0_7 */ clear = osi_readla(osi_core, addr + @@ -2070,7 +2035,6 @@ static inline void handle_dbg_evt_capture_done( if (ctrl_sel == OSI_CTLR_SEL_TX) { trigger_evts = osi_readla(osi_core, addr + MACSEC_TX_DEBUG_STATUS_0); - pr_err("%s: MACSEC_TX_DEBUG_STATUS_0 0x%x", __func__, trigger_evts); osi_writela(osi_core, trigger_evts, addr + MACSEC_TX_DEBUG_STATUS_0); /* clear all trigger events */ @@ -2080,7 +2044,6 @@ static inline void handle_dbg_evt_capture_done( } else if (ctrl_sel == OSI_CTLR_SEL_RX) { trigger_evts = osi_readla(osi_core, addr + MACSEC_RX_DEBUG_STATUS_0); - pr_err("%s: MACSEC_RX_DEBUG_STATUS_0 0x%x", __func__, trigger_evts); osi_writela(osi_core, trigger_evts, addr + MACSEC_RX_DEBUG_STATUS_0); /* clear all trigger events */ @@ -2096,7 +2059,8 @@ static inline void handle_tx_irq(struct osi_core_priv_data *const osi_core) nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; tx_isr = osi_readla(osi_core, addr + MACSEC_TX_ISR); - pr_err("%s(): tx_isr 0x%x\n", __func__, tx_isr); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "tx_isr \n", 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); @@ -2137,7 +2101,8 @@ static inline void handle_tx_irq(struct osi_core_priv_data *const osi_core) clear |= MACSEC_TX_PN_EXHAUSTED; } if (clear) { - pr_err("%s(): write tx_isr 0x%x\n", __func__, clear); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "write tx_isr \n", clear); osi_writela(osi_core, clear, addr + MACSEC_TX_ISR); } } @@ -2148,7 +2113,8 @@ static inline void handle_rx_irq(struct osi_core_priv_data *const osi_core) nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; rx_isr = osi_readla(osi_core, addr + MACSEC_RX_ISR); - pr_err("%s(): rx_isr 0x%x\n", __func__, rx_isr); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "rx_isr \n", rx_isr); if ((rx_isr & MACSEC_RX_DBG_BUF_CAPTURE_DONE) == MACSEC_RX_DBG_BUF_CAPTURE_DONE) { @@ -2189,7 +2155,8 @@ static inline void handle_rx_irq(struct osi_core_priv_data *const osi_core) clear |= MACSEC_RX_PN_EXHAUSTED; } if (clear) { - pr_err("%s(): write rx_isr 0x%x\n", __func__, clear); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "write rx_isr \n", clear); osi_writela(osi_core, clear, addr + MACSEC_RX_ISR); } } @@ -2200,7 +2167,8 @@ static inline void handle_common_irq(struct osi_core_priv_data *const osi_core) nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; common_isr = osi_readla(osi_core, addr + MACSEC_COMMON_ISR); - pr_err("%s(): common_isr 0x%x\n", __func__, common_isr); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "common_isr \n", common_isr); if ((common_isr & MACSEC_SECURE_REG_VIOL) == MACSEC_SECURE_REG_VIOL) { osi_core->macsec_irq_stats.secure_reg_viol++; @@ -2241,7 +2209,8 @@ static void macsec_handle_ns_irq(struct osi_core_priv_data *const osi_core) nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; irq_common_sr = osi_readla(osi_core, addr + MACSEC_INTERRUPT_COMMON_SR); - pr_err("%s(): common_sr 0x%x\n", __func__, irq_common_sr); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "common_sr \n", irq_common_sr); if ((irq_common_sr & MACSEC_COMMON_SR_TX) == MACSEC_COMMON_SR_TX) { handle_tx_irq(osi_core); } @@ -2266,7 +2235,8 @@ 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; - pr_err("%s()\n", __func__); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "macsec_handle_s_irq \n", 0ULL); common_isr = osi_readla(osi_core, addr + MACSEC_COMMON_ISR); if (common_isr != OSI_NONE) { @@ -2283,7 +2253,6 @@ static nve32_t macsec_cipher_config(struct osi_core_priv_data *const osi_core, nveu32_t val; val = osi_readla(osi_core, base + MACSEC_GCM_AES_CONTROL_0); - pr_err("Read MACSEC_GCM_AES_CONTROL_0: 0x%x\n", val); val &= ~MACSEC_TX_AES_MODE_MASK; val &= ~MACSEC_RX_AES_MODE_MASK; @@ -2297,7 +2266,6 @@ static nve32_t macsec_cipher_config(struct osi_core_priv_data *const osi_core, return -1; } - pr_err("Write MACSEC_GCM_AES_CONTROL_0: 0x%x\n", val); osi_writela(osi_core, val, base + MACSEC_GCM_AES_CONTROL_0); return 0; } @@ -2310,7 +2278,6 @@ static nve32_t macsec_loopback_config( nveu32_t val; val = osi_readla(osi_core, base + MACSEC_CONTROL1); - pr_err("Read MACSEC_CONTROL1: 0x%x\n", val); if (enable == OSI_ENABLE) { val |= MACSEC_LOOPBACK_MODE_EN; @@ -2320,7 +2287,6 @@ static nve32_t macsec_loopback_config( return -1; } - pr_err("Write MACSEC_CONTROL1: 0x%x\n", val); osi_writela(osi_core, val, base + MACSEC_CONTROL1); return 0; } @@ -2346,8 +2312,8 @@ static nve32_t clear_lut(struct osi_core_priv_data *const osi_core) table_config->index = j; ret = macsec_lut_config(osi_core, &lut_config); if (ret < 0) { - pr_err("Error clearing CTLR:LUT:INDEX: %d:%d:%d\n", - i, lut_config.lut_sel, j); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "Error Clearing BYP LUT\n", 0ULL); return ret; } } @@ -2361,8 +2327,8 @@ static nve32_t clear_lut(struct osi_core_priv_data *const osi_core) table_config->index = j; ret = macsec_lut_config(osi_core, &lut_config); if (ret < 0) { - pr_err("Error clearing CTLR:LUT:INDEX: %d:%d:%d\n", - i, lut_config.lut_sel, j); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "Error Clearing SCI LUT\n", 0ULL); return ret; } } @@ -2376,8 +2342,9 @@ static nve32_t clear_lut(struct osi_core_priv_data *const osi_core) table_config->index = j; ret = macsec_lut_config(osi_core, &lut_config); if (ret < 0) { - pr_err("Error clearing CTLR:LUT:INDEX: %d:%d:%d\n", - i, lut_config.lut_sel, j); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "Error Clearing SC Param LUT \n", + 0ULL); return ret; } } @@ -2391,8 +2358,9 @@ static nve32_t clear_lut(struct osi_core_priv_data *const osi_core) table_config->index = j; ret = macsec_lut_config(osi_core, &lut_config); if (ret < 0) { - pr_err("Error clearing CTLR:LUT:INDEX: %d:%d:%d\n", - i, lut_config.lut_sel, j); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "Error Clearing SC State LUT \n", + 0ULL); return ret; } } @@ -2405,8 +2373,9 @@ static nve32_t clear_lut(struct osi_core_priv_data *const osi_core) table_config->index = j; ret = macsec_lut_config(osi_core, &lut_config); if (ret < 0) { - pr_err("Error clearing Tx LUT:INDEX: %d:%d\n", - lut_config.lut_sel, j); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "Error Clearing Tx SA State LUT\n", + 0ULL); return ret; } } @@ -2418,8 +2387,9 @@ static nve32_t clear_lut(struct osi_core_priv_data *const osi_core) table_config->index = j; ret = macsec_lut_config(osi_core, &lut_config); if (ret < 0) { - pr_err("Error clearing Rx LUT:INDEX: %d:%d\n", - lut_config.lut_sel, j); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "Error Clearing Rx SA State LUT\n", + 0ULL); return ret; } } @@ -2434,8 +2404,8 @@ static nve32_t clear_lut(struct osi_core_priv_data *const osi_core) table_config->index = j; ret = macsec_kt_config(osi_core, &kt_config); if (ret < 0) { - pr_err("Error clearing KT CTLR:INDEX: %d:%d\n", - i, j); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "Error Clearing KT\n", 0ULL); return ret; } } @@ -2492,17 +2462,21 @@ static nve32_t macsec_init(struct osi_core_priv_data *const osi_core) /* Set MTU */ val = osi_readla(osi_core, addr + MACSEC_TX_MTU_LEN); - pr_err("Read MACSEC_TX_MTU_LEN: 0x%x\n", val); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "Read MACSEC_TX_MTU_LEN: \n", val); val &= ~(MTU_LENGTH_MASK); val |= (mtu & MTU_LENGTH_MASK); - pr_err("Write MACSEC_TX_MTU_LEN: 0x%x\n", val); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "Write MACSEC_TX_MTU_LEN: \n", val); osi_writela(osi_core, val, addr + MACSEC_TX_MTU_LEN); val = osi_readla(osi_core, addr + MACSEC_RX_MTU_LEN); - pr_err("Read MACSEC_RX_MTU_LEN: 0x%x\n", val); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "Read MACSEC_RX_MTU_LEN: \n", val); val &= ~(MTU_LENGTH_MASK); val |= (mtu & MTU_LENGTH_MASK); - pr_err("Write MACSEC_RX_MTU_LEN: 0x%x\n", val); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "Write MACSEC_RX_MTU_LEN: \n", val); osi_writela(osi_core, val, addr + MACSEC_RX_MTU_LEN); /* set TX/RX SOT, as SOT value different for eqos. @@ -2510,36 +2484,44 @@ static nve32_t macsec_init(struct osi_core_priv_data *const osi_core) */ if (osi_core->mac == OSI_MAC_HW_EQOS) { val = osi_readla(osi_core, addr + MACSEC_TX_SOT_DELAY); - pr_err("Read MACSEC_TX_SOT_DELAY: 0x%x\n", val); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "Read MACSEC_TX_SOT_DELAY: \n", val); val &= ~(SOT_LENGTH_MASK); val |= (EQOS_MACSEC_SOT_DELAY & SOT_LENGTH_MASK); - pr_err("Write MACSEC_TX_SOT_DELAY: 0x%x\n", val); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "Write MACSEC_TX_SOT_DELAY \n", val); osi_writela(osi_core, val, addr + MACSEC_TX_SOT_DELAY); val = osi_readla(osi_core, addr + MACSEC_RX_SOT_DELAY); - pr_err("Read MACSEC_RX_SOT_DELAY: 0x%x\n", val); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "Read MACSEC_RX_SOT_DELAY: \n", val); val &= ~(SOT_LENGTH_MASK); val |= (EQOS_MACSEC_SOT_DELAY & SOT_LENGTH_MASK); - pr_err("Write MACSEC_RX_SOT_DELAY: 0x%x\n", val); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "Write MACSEC_RX_SOT_DELAY \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); - pr_err("Read MACSEC_CONTROL0: 0x%x\n", val); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "Read MACSEC_CONTROL0: \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; - pr_err("Write MACSEC_CONTROL0: 0x%x\n", val); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "Write MACSEC_CONTROL0: \n", val); osi_writela(osi_core, val, addr + MACSEC_CONTROL0); val = osi_readla(osi_core, addr + MACSEC_CONTROL1); - pr_err("Read MACSEC_CONTROL1: 0x%x\n", val); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "Read MACSEC_CONTROL1: \n", val); val |= (MACSEC_RX_MTU_CHECK_EN | MACSEC_TX_LUT_PRIO_BYP | MACSEC_TX_MTU_CHECK_EN); - pr_err("Write MACSEC_CONTROL1: 0x%x\n", val); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "Write MACSEC_CONTROL1: \n", val); osi_writela(osi_core, val, addr + MACSEC_CONTROL1); /* set DVLAN tag ethertype */ @@ -2552,15 +2534,18 @@ static nve32_t macsec_init(struct osi_core_priv_data *const osi_core) */ val = osi_readla(osi_core, addr + MACSEC_STATS_CONTROL_0); - pr_err("Read MACSEC_STATS_CONTROL_0: 0x%x\n", val); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "Read MACSEC_STATS_CONTROL_0: \n", val); /* set STATS rollover bit */ val |= MACSEC_STATS_CONTROL0_CNT_RL_OVR_CPY; - pr_err("Write MACSEC_STATS_CONTROL_0: 0x%x\n", val); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "Write MACSEC_STATS_CONTROL_0: \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); - pr_err("Read MACSEC_TX_IMR: 0x%x\n", val); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "Read MACSEC_TX_IMR: \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 | @@ -2568,11 +2553,13 @@ static nve32_t macsec_init(struct osi_core_priv_data *const osi_core) MACSEC_TX_AES_GCM_BUF_OVF_INT_EN | MACSEC_TX_PN_EXHAUSTED_INT_EN | MACSEC_TX_PN_THRSHLD_RCHD_INT_EN); - pr_err("Write MACSEC_TX_IMR: 0x%x\n", val); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "Write MACSEC_TX_IMR: \n", val); osi_writela(osi_core, val, addr + MACSEC_TX_IMR); val = osi_readla(osi_core, addr + MACSEC_RX_IMR); - pr_err("Read MACSEC_RX_IMR: 0x%x\n", val); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "Read MACSEC_RX_IMR: \n", val); val |= (MACSEC_RX_DBG_BUF_CAPTURE_DONE_INT_EN | MACSEC_RX_ICV_ERROR_INT_EN | RX_REPLAY_ERROR_INT_EN | @@ -2581,18 +2568,21 @@ static nve32_t macsec_init(struct osi_core_priv_data *const osi_core) MACSEC_RX_AES_GCM_BUF_OVF_INT_EN | MACSEC_RX_PN_EXHAUSTED_INT_EN ); - pr_err("Write MACSEC_RX_IMR: 0x%x\n", val); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "Write MACSEC_RX_IMR: \n", val); osi_writela(osi_core, val, addr + MACSEC_RX_IMR); val = osi_readla(osi_core, addr + MACSEC_COMMON_IMR); - pr_err("Read MACSEC_COMMON_IMR: 0x%x\n", val); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "Read MACSEC_COMMON_IMR: \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); - pr_err("Write MACSEC_COMMON_IMR: 0x%x\n", val); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "Write MACSEC_COMMON_IMR: \n", val); osi_writela(osi_core, val, addr + MACSEC_COMMON_IMR); /* Set AES mode @@ -2813,16 +2803,13 @@ static nve32_t add_upd_sc(struct osi_core_priv_data *const osi_core, tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); if (crypto_cipher_setkey(tfm, sc->sak, OSI_KEY_LEN_128)) { - pr_err("%s: Failed to set cipher key for H generation", - __func__); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Failed to set cipher key for H generation\n", 0ULL); return -1; } crypto_cipher_encrypt_one(tfm, hkey, zeros); - pr_err("\n%s: Generated H key: ", __func__); - for (i = 0; i < OSI_KEY_LEN_128; i++) { - pr_cont(" %02x", hkey[i]); - } - pr_err("\n"); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Generated H key \n", 0ULL); crypto_free_cipher(tfm); #endif /* MACSEC_KEY_PROGRAM */ @@ -2914,18 +2901,19 @@ static nve32_t add_upd_sc(struct osi_core_priv_data *const osi_core, goto err_sci; } - /* 5. SC state LUT */ - lut_config.flags = OSI_NONE; - lut_config.lut_sel = OSI_LUT_SEL_SC_STATE; - table_config->index = 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", ret); - goto err_sc_state; + 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 = 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", ret); + goto err_sc_state; + } } - return 0; err_sc_state: @@ -2978,7 +2966,6 @@ static nve32_t macsec_config(struct osi_core_priv_data *const osi_core, struct osi_macsec_sc_info tmp_sc; struct osi_macsec_sc_info *tmp_sc_p = &tmp_sc; struct osi_macsec_lut_status *lut_status; - nve32_t i; /* Validate inputs */ if ((enable != OSI_ENABLE && enable != OSI_DISABLE) || @@ -2997,8 +2984,8 @@ static nve32_t macsec_config(struct osi_core_priv_data *const osi_core, 0ULL); return -1; } else { - pr_err("%s: Adding new SC/SA: ctlr: %hu", __func__, - ctlr); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Adding new SC/SA: \n", ctlr); if (lut_status->next_sc_idx >= OSI_MAX_NUM_SC) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Err: Reached max SC LUT entries!\n", 0ULL); @@ -3011,28 +2998,11 @@ static nve32_t macsec_config(struct osi_core_priv_data *const osi_core, 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 = lut_status->next_sc_idx; new_sc->an_valid |= OSI_BIT(sc->curr_an); - pr_err("%s: Adding new SC\n" - "\tsci: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n" - "\tan: %u\n" - "\tpn: %u" - "\tsc_idx_start: %u" - "\tan_valid: %#x \tpn_window: %#x", __func__, - new_sc->sci[0], new_sc->sci[1], new_sc->sci[2], - new_sc->sci[3], new_sc->sci[4], new_sc->sci[5], - new_sc->sci[6], new_sc->sci[7], - new_sc->curr_an, new_sc->next_pn, - new_sc->sc_idx_start, - new_sc->an_valid, new_sc->pn_window); - pr_err("\tkey: "); - for (i = 0; i < OSI_KEY_LEN_128; i++) { - pr_cont(" %02x", new_sc->sak[i]); - } - pr_err(""); - if (add_upd_sc(osi_core, new_sc, ctlr, kt_idx) != OSI_NONE) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, @@ -3041,17 +3011,17 @@ static nve32_t macsec_config(struct osi_core_priv_data *const osi_core, } else { /* Update lut status */ lut_status->next_sc_idx++; - pr_err("%s: Added new SC ctlr: %u " - "nxt_sc_idx: %u", - __func__, ctlr, - lut_status->next_sc_idx); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Added new SC\n", 0ULL); return 0; } } } else { - pr_err("%s: Updating existing SC", __func__); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Updating existing SC \n", 0ULL); if (enable == OSI_DISABLE) { - pr_err("%s: Deleting existing SA", __func__); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Deleting existing SA \n", 0ULL); if (del_upd_sc(osi_core, existing_sc, sc, ctlr, kt_idx) != OSI_NONE) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, @@ -3076,38 +3046,18 @@ static nve32_t macsec_config(struct osi_core_priv_data *const osi_core, 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); - pr_err("%s: Adding new SA to SC\n" - "\tsci: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n" - "\tan: %u\n" - "\tpn: %u" - "\tsc_idx_start: %u" - "\tan_valid: %#x \tpn_window: %#x", __func__, - tmp_sc_p->sci[0], tmp_sc_p->sci[1], - tmp_sc_p->sci[2], tmp_sc_p->sci[3], - tmp_sc_p->sci[4], tmp_sc_p->sci[5], - tmp_sc_p->sci[6], tmp_sc_p->sci[7], - tmp_sc_p->curr_an, tmp_sc_p->next_pn, - tmp_sc_p->sc_idx_start, - tmp_sc_p->an_valid, tmp_sc_p->pn_window); - pr_err("\tkey: "); - for (i = 0; i < OSI_KEY_LEN_128; i++) { - pr_cont(" %02x", tmp_sc_p->sak[i]); - } - pr_err(""); - if (add_upd_sc(osi_core, tmp_sc_p, ctlr, kt_idx) != OSI_NONE) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "failed to add new SA\n", 0ULL); return -1; } else { - pr_err("%s: Updated new SC ctlr: %u " - "nxt_sc_idx: %u", - __func__, ctlr, - lut_status->next_sc_idx); + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "Updated new SC\n", ctlr); /* Now commit the changes */ *existing_sc = *tmp_sc_p; return 0; From 4702a15dd611fa514edd143521701a1e66916a77 Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Mon, 22 Nov 2021 13:54:17 +0000 Subject: [PATCH 304/458] mgbe: Fix FRP DMA route issue Issue: FRP MC/BC packets routing to multiple DMA channels is not happening. Fix: Correct the FRP entry DCH programming to enable multiple DMA channels route. Bug 3417901 Change-Id: Ib3d5794253b89d7d3a00164fa7fd011e4ac9e50b Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2629966 Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/mgbe_core.c | 6 +----- osi/core/mgbe_core.h | 1 - 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index edd5552..ce18c51 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -2133,11 +2133,7 @@ static int mgbe_update_frp_entry(struct osi_core_priv_data *const osi_core, } /** Write DCH into IE3 **/ - /* TODO: The DCH position will be updated in the final RTL. - * We need to update this on the final RTL. - */ - tmp = (data->dma_chsel >> MGBE_MTL_FRP_IE3_DCH_SHIFT); - val = (tmp & MGBE_MTL_FRP_IE3_DCH_MASK); + 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 */ diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 7f2fe5c..5591f6d 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -368,7 +368,6 @@ #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_SHIFT 8U #define MGBE_MTL_FRP_IE3_DCH_MASK 0xFFFFU /* Indirect register defines */ #define MGBE_MTL_RXP_DROP_CNT 0U From 8baea29699f37b6034d8fa2a92cfd8341540989a Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Thu, 16 Dec 2021 01:56:57 +0530 Subject: [PATCH 305/458] core: eqos: fix PTP register offset Issue: ETHER_QOS_PTP_CAPTURE_* register offset was wrong. low and high offset are swapped. Fix: correct the offset value. Bug 3471827 Change-Id: Ia7e13209e123f1c58655af9b79186aa6a21ad316 Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2642729 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/eqos_core.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 5f03a65..bea364f 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -192,8 +192,8 @@ #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 0x801CU -#define EQOS_WRAP_PTP_CAPTURE_HIGH 0x8018U +#define EQOS_WRAP_PTP_CAPTURE_LOW 0x8018U +#define EQOS_WRAP_PTP_CAPTURE_HIGH 0x801CU /** @} */ From 5f6c9b725b6f7d601f1ade314d3194fce1f7d49b Mon Sep 17 00:00:00 2001 From: Prateek Patel <prpatel@nvidia.com> Date: Thu, 16 Dec 2021 08:04:24 +0000 Subject: [PATCH 306/458] nvethernetrm: fix large_shift coverity defect Checking vid_idx == 32U implies that vid_idx is 32 on the true branch. In expression OSI_BIT(vid_idx), left shifting by more than 31 bits has undefined behavior. The shift amount, vid_idx, is 32. Return with "-1" error condition to fix the defect. CID 10060748 Bug 3461002 Change-Id: I7711152fcf93e50f3c85eddf20b3e9721fb4f853 Signed-off-by: Prateek Patel <prpatel@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2642992 Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Sachin Nikam <snikam@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/vlan_filter.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/osi/core/vlan_filter.c b/osi/core/vlan_filter.c index dd73a4b..7368f53 100644 --- a/osi/core/vlan_filter.c +++ b/osi/core/vlan_filter.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -422,10 +422,11 @@ static inline int del_vlan_id(struct osi_core_priv_data *osi_core, 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 found to be deleted in SW queue */ - return dequeue_vlan_id(osi_core, 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); From a98c105b088ee1b909c613fcf54a36fdd1e50ac5 Mon Sep 17 00:00:00 2001 From: Mahesh Patil <maheshp@nvidia.com> Date: Wed, 21 Jul 2021 18:00:16 -0700 Subject: [PATCH 307/458] nvethernetrm: pad calibration Enable update pad caliration code under UPDATED_PAD_CAL macro and remove old pad calibration code Bug 2831220 Change-Id: I01daa72ff6e6cfb016de85f22b55404a9d8a54ba Signed-off-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2562771 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: Nagaraj Annaiah <nannaiah@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/eqos_core.c | 172 ++++++++++++------------------------------- 1 file changed, 49 insertions(+), 123 deletions(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 1bcdb31..855580b 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2021, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -28,7 +28,6 @@ #include "core_local.h" #include "vlan_filter.h" -#ifdef UPDATED_PAD_CAL /* * Forward declarations of local functions. */ @@ -36,7 +35,6 @@ 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 @@ -815,7 +813,6 @@ static nveu32_t eqos_calculate_per_queue_fifo(nveu32_t mac_ver, return p_fifo; } -#ifdef UPDATED_PAD_CAL /** * @brief eqos_pad_calibrate - PAD calibration * @@ -853,10 +850,11 @@ 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; + nve32_t cond = COND_NOT_MET, ret = 0, ret1 = 0; nveu32_t value; - __sync_val_compare_and_swap(&osi_core->padctrl.is_pad_cal_in_progress, + /* mask return as initial value returned always */ + (void)__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) { @@ -893,6 +891,8 @@ static nve32_t eqos_pad_calibrate(struct osi_core_priv_data *const osi_core) while (cond == COND_NOT_MET) { if (count > retry) { ret = -1; + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Error:pad calibration timeout!\n", 0ULL); goto calibration_failed; } count++; @@ -912,100 +912,20 @@ calibration_failed: 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); + /* overwrite calibration timeout error ret value + * if eqos_post_pad_calibrate() fails */ + ret1 = eqos_post_pad_calibrate(osi_core); + if (ret1 < 0) { + ret = ret1; + } error: - __sync_val_compare_and_swap(&osi_core->padctrl.is_pad_cal_in_progress, + /* mask return as initial value returned always */ + (void)__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 * @@ -2132,16 +2052,6 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core, 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); @@ -6123,7 +6033,6 @@ static nve32_t eqos_get_hw_features(struct osi_core_priv_data *const osi_core, return 0; } -#ifdef UPDATED_PAD_CAL /** * @brief eqos_padctl_rx_pins Enable/Disable RGMII Rx pins * @@ -6136,14 +6045,18 @@ static nve32_t eqos_get_hw_features(struct osi_core_priv_data *const osi_core, * @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) +static nve32_t eqos_padctl_rx_pins(struct osi_core_priv_data *const osi_core, + unsigned int enable) { nveu32_t value; + nve32_t ret = 0; void *pad_addr = osi_core->padctrl.padctrl_base; if (pad_addr == OSI_NULL) { - return -1; + ret = -1; + OSI_CORE_ERR(osi_core->osd, + OSI_LOG_ARG_HW_FAIL, "Error: pad_addr is null\n", 0ULL); + goto fail; } if (enable == OSI_ENABLE) { value = osi_readla(osi_core, (nveu8_t *)pad_addr + @@ -6198,7 +6111,8 @@ static int eqos_padctl_rx_pins(struct osi_core_priv_data *const osi_core, osi_writela(osi_core, value, (nveu8_t *)pad_addr + osi_core->padctrl.offset_rd3); } - return 0; +fail: + return ret; } /** @@ -6214,7 +6128,7 @@ static int eqos_padctl_rx_pins(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -static inline int poll_for_mac_tx_rx_idle(struct osi_core_priv_data *osi_core) +static inline nve32_t poll_for_mac_tx_rx_idle(struct osi_core_priv_data *osi_core) { nveu32_t retry = 0; nveu32_t mac_debug; @@ -6261,7 +6175,7 @@ static inline int poll_for_mac_tx_rx_idle(struct osi_core_priv_data *osi_core) * @retval negative value on failure. */ -static int eqos_pre_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) { nve32_t ret = 0; nveu32_t value; @@ -6284,33 +6198,43 @@ static int eqos_pre_pad_calibrate(struct osi_core_priv_data *const osi_core) } if (osi_core->osd_ops.padctrl_mii_rx_pins != OSI_NULL) { + /* call linux specific function to disable pads */ ret = osi_core->osd_ops.padctrl_mii_rx_pins(osi_core->osd, OSI_DISABLE); } else { + /* called for qnx, this function can be made void and validate + * input parameter at begining in osi_pad_calibrate() for qnx */ ret = eqos_padctl_rx_pins(osi_core, OSI_DISABLE); } if (ret < 0) { - goto error; + goto pad_fail; } - return ret; -error: - /* roll back on fail */ - eqos_start_mac(osi_core); + goto pass; + +pad_fail: + /* Roll back on fail */ + /* Try to enable pads on error if even if pad disable fails + * on safe side */ if (osi_core->osd_ops.padctrl_mii_rx_pins != OSI_NULL) { + /* This is called for linux. Mask return as + * eqos_pre_pad_calibrate() error returned to caller */ (void)osi_core->osd_ops.padctrl_mii_rx_pins(osi_core->osd, OSI_ENABLE); } else { + /* This is called for qnx. Mask return as + * eqos_pre_pad_calibrate() error returned to caller */ (void)eqos_padctl_rx_pins(osi_core, OSI_ENABLE); } - +error: + eqos_start_mac(osi_core); /* Enable MAC RGSMIIIE - RGMII/SMII interrupts */ /* Read MAC IMR Register */ - value = osi_readl((unsigned char *)osi_core->base + EQOS_MAC_IMR); + 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); - +pass: return ret; } @@ -6341,9 +6265,12 @@ static nve32_t eqos_post_pad_calibrate( nveu32_t mac_isr = 0; if (osi_core->osd_ops.padctrl_mii_rx_pins != OSI_NULL) { + /* called for linux */ ret = osi_core->osd_ops.padctrl_mii_rx_pins(osi_core->osd, OSI_ENABLE); } else { + /* called for qnx, add proper return value for qnx + * if this function is not changed to void */ ret = eqos_padctl_rx_pins(osi_core, OSI_ENABLE); } /* handle only those MAC interrupts which are enabled */ @@ -6352,12 +6279,12 @@ static nve32_t eqos_post_pad_calibrate( 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) { + 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) { + if (mac_pcs != 0U) { /* do nothing */ } } @@ -6368,7 +6295,6 @@ static nve32_t eqos_post_pad_calibrate( EQOS_MAC_IMR, EQOS_MAC_IMR_IDX); return ret; } -#endif /* UPDATED_PAD_CAL */ /** * @brief eqos_config_rss - Configure RSS From 636c5bd55647a4990bab77f5c5a73263160e8478 Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Tue, 14 Dec 2021 19:06:47 +0530 Subject: [PATCH 308/458] core: add support configure pps out signal Issue: Default pps output is 1 pulse (of width clk_ptp_i) every second. Fix: option to configure to binary rollover is 2 Hz, and the digital rollover is 1 Hz. Bug 3462227 Change-Id: Ic777bfaf51a72ec91c8f165910e824c55cae3057 Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2641896 Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_core.h | 5 ++++- osi/core/core_local.h | 4 +++- osi/core/eqos_core.c | 8 ++++++++ osi/core/eqos_core.h | 5 ++++- osi/core/mgbe_core.c | 11 ++++++++++- osi/core/mgbe_core.h | 5 ++++- osi/core/osi_core.c | 11 ++++++++++- 7 files changed, 43 insertions(+), 6 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index d3fe4c5..a857cd6 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2021, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -1309,6 +1309,9 @@ struct osi_core_priv_data { * 1 - Primary interface, 2 - secondary interface, 0 - inactive interface */ nveu32_t m2m_role; + /** control pps output signal + */ + nveu32_t pps_frq; }; /** diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 0cd03a4..d030d65 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -355,6 +355,8 @@ struct core_local { 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; }; /** diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 855580b..21636bb 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -4186,7 +4186,9 @@ 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 | @@ -4244,6 +4246,12 @@ static void eqos_config_tscr(struct osi_core_priv_data *const osi_core, 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); } /** diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index bea364f..1f4cf07 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2021, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -129,6 +129,7 @@ #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 @@ -277,6 +278,8 @@ 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) diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index ce18c51..bbe882f 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -5523,7 +5523,9 @@ static int mgbe_adjust_mactime(struct osi_core_priv_data *osi_core, 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) { @@ -5585,6 +5587,13 @@ static void mgbe_config_tscr(struct osi_core_priv_data *osi_core, } 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); } /** diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 5591f6d..b038b1f 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -112,6 +112,7 @@ #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 @@ -252,6 +253,8 @@ #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)) /** @} */ /** diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 9656878..7fa9d97 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2021, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -124,6 +124,7 @@ struct osi_core_priv_data *osi_get_core(void) 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; } @@ -202,6 +203,14 @@ nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core) 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; } From a18fcfcf5d7ab60d1c18d50c0690006b8d3b424e Mon Sep 17 00:00:00 2001 From: Mahesh Patil <maheshp@nvidia.com> Date: Sun, 9 Jan 2022 22:53:35 -0800 Subject: [PATCH 309/458] Revert "nvethernetrm: pad calibration" This reverts commit 54263d6ea50b731224ed67ed1ab9585aaa2247b8. Bug 3494618 Change-Id: I8e609fb2d42be713d255703d79e1b318078f2907 Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2651963 Reviewed-by: Hyong Bin Kim <hyongbink@nvidia.com> Reviewed-by: Kasinadha Dendukuri <kdendukuri@nvidia.com> Reviewed-by: Sumeet Gupta <sumeetg@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: Kasinadha Dendukuri <kdendukuri@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/eqos_core.c | 172 +++++++++++++++++++++++++++++++------------ 1 file changed, 123 insertions(+), 49 deletions(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 21636bb..0b9fe41 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2022, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -28,6 +28,7 @@ #include "core_local.h" #include "vlan_filter.h" +#ifdef UPDATED_PAD_CAL /* * Forward declarations of local functions. */ @@ -35,6 +36,7 @@ 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 @@ -813,6 +815,7 @@ static nveu32_t eqos_calculate_per_queue_fifo(nveu32_t mac_ver, return p_fifo; } +#ifdef UPDATED_PAD_CAL /** * @brief eqos_pad_calibrate - PAD calibration * @@ -850,11 +853,10 @@ 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, ret1 = 0; + nve32_t cond = COND_NOT_MET, ret = 0; nveu32_t value; - /* mask return as initial value returned always */ - (void)__sync_val_compare_and_swap(&osi_core->padctrl.is_pad_cal_in_progress, + __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) { @@ -891,8 +893,6 @@ static nve32_t eqos_pad_calibrate(struct osi_core_priv_data *const osi_core) while (cond == COND_NOT_MET) { if (count > retry) { ret = -1; - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Error:pad calibration timeout!\n", 0ULL); goto calibration_failed; } count++; @@ -912,20 +912,100 @@ calibration_failed: 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); - /* overwrite calibration timeout error ret value - * if eqos_post_pad_calibrate() fails */ - ret1 = eqos_post_pad_calibrate(osi_core); - if (ret1 < 0) { - ret = ret1; - } + ret = eqos_post_pad_calibrate(osi_core); error: - /* mask return as initial value returned always */ - (void)__sync_val_compare_and_swap(&osi_core->padctrl.is_pad_cal_in_progress, + __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 * @@ -2052,6 +2132,16 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core, 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); @@ -6041,6 +6131,7 @@ static nve32_t eqos_get_hw_features(struct osi_core_priv_data *const osi_core, return 0; } +#ifdef UPDATED_PAD_CAL /** * @brief eqos_padctl_rx_pins Enable/Disable RGMII Rx pins * @@ -6053,18 +6144,14 @@ static nve32_t eqos_get_hw_features(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -static nve32_t eqos_padctl_rx_pins(struct osi_core_priv_data *const osi_core, - unsigned int enable) +static int eqos_padctl_rx_pins(struct osi_core_priv_data *const osi_core, + unsigned int enable) { nveu32_t value; - nve32_t ret = 0; void *pad_addr = osi_core->padctrl.padctrl_base; if (pad_addr == OSI_NULL) { - ret = -1; - OSI_CORE_ERR(osi_core->osd, - OSI_LOG_ARG_HW_FAIL, "Error: pad_addr is null\n", 0ULL); - goto fail; + return -1; } if (enable == OSI_ENABLE) { value = osi_readla(osi_core, (nveu8_t *)pad_addr + @@ -6119,8 +6206,7 @@ static nve32_t eqos_padctl_rx_pins(struct osi_core_priv_data *const osi_core, osi_writela(osi_core, value, (nveu8_t *)pad_addr + osi_core->padctrl.offset_rd3); } -fail: - return ret; + return 0; } /** @@ -6136,7 +6222,7 @@ fail: * @retval 0 on success * @retval -1 on failure. */ -static inline nve32_t poll_for_mac_tx_rx_idle(struct osi_core_priv_data *osi_core) +static inline int poll_for_mac_tx_rx_idle(struct osi_core_priv_data *osi_core) { nveu32_t retry = 0; nveu32_t mac_debug; @@ -6183,7 +6269,7 @@ static inline nve32_t poll_for_mac_tx_rx_idle(struct osi_core_priv_data *osi_cor * @retval negative value on failure. */ -static nve32_t eqos_pre_pad_calibrate(struct osi_core_priv_data *const osi_core) +static int eqos_pre_pad_calibrate(struct osi_core_priv_data *const osi_core) { nve32_t ret = 0; nveu32_t value; @@ -6206,43 +6292,33 @@ static nve32_t eqos_pre_pad_calibrate(struct osi_core_priv_data *const osi_core) } if (osi_core->osd_ops.padctrl_mii_rx_pins != OSI_NULL) { - /* call linux specific function to disable pads */ ret = osi_core->osd_ops.padctrl_mii_rx_pins(osi_core->osd, OSI_DISABLE); } else { - /* called for qnx, this function can be made void and validate - * input parameter at begining in osi_pad_calibrate() for qnx */ ret = eqos_padctl_rx_pins(osi_core, OSI_DISABLE); } if (ret < 0) { - goto pad_fail; + goto error; } - goto pass; - -pad_fail: - /* Roll back on fail */ - /* Try to enable pads on error if even if pad disable fails - * on safe side */ + return ret; +error: + /* roll back on fail */ + eqos_start_mac(osi_core); if (osi_core->osd_ops.padctrl_mii_rx_pins != OSI_NULL) { - /* This is called for linux. Mask return as - * eqos_pre_pad_calibrate() error returned to caller */ (void)osi_core->osd_ops.padctrl_mii_rx_pins(osi_core->osd, OSI_ENABLE); } else { - /* This is called for qnx. Mask return as - * eqos_pre_pad_calibrate() error returned to caller */ (void)eqos_padctl_rx_pins(osi_core, OSI_ENABLE); } -error: - eqos_start_mac(osi_core); + /* Enable MAC RGSMIIIE - RGMII/SMII interrupts */ /* Read MAC IMR Register */ - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + EQOS_MAC_IMR); + 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); -pass: + return ret; } @@ -6273,12 +6349,9 @@ static nve32_t eqos_post_pad_calibrate( nveu32_t mac_isr = 0; if (osi_core->osd_ops.padctrl_mii_rx_pins != OSI_NULL) { - /* called for linux */ ret = osi_core->osd_ops.padctrl_mii_rx_pins(osi_core->osd, OSI_ENABLE); } else { - /* called for qnx, add proper return value for qnx - * if this function is not changed to void */ ret = eqos_padctl_rx_pins(osi_core, OSI_ENABLE); } /* handle only those MAC interrupts which are enabled */ @@ -6287,12 +6360,12 @@ static nve32_t eqos_post_pad_calibrate( 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)) { + 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 != 0U) { + if (mac_pcs) { /* do nothing */ } } @@ -6303,6 +6376,7 @@ static nve32_t eqos_post_pad_calibrate( EQOS_MAC_IMR, EQOS_MAC_IMR_IDX); return ret; } +#endif /* UPDATED_PAD_CAL */ /** * @brief eqos_config_rss - Configure RSS From b4e5d26dd3f7ff7b93f1b7ed6836050607d2624b Mon Sep 17 00:00:00 2001 From: Sanath Kumar Gampa <sgampa@nvidia.com> Date: Thu, 30 Dec 2021 11:07:53 +0530 Subject: [PATCH 310/458] osi: Avoid macsec and fpe coexistance on MGBE Issue: Internal FIFO over/underflows if MACSEC and FPE are enabled on MGBE interafce and pre-emptable and express frames are sent in interleaved fashion Fix: Do not allow enabling any of MACSEC and FPE if the other is already enabled. Bug 3484034 Change-Id: Ifc80eb9333c836652a86362a1f7788a0ce70dbb7 Signed-off-by: Sanath Kumar Gampa <sgampa@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2647788 Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Om Prakash Singh <omp@nvidia.com> Reviewed-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_core.h | 9 +++++++++ osi/core/macsec.c | 26 ++++++++++++++++++++++++-- osi/core/mgbe_core.c | 32 +++++++++++++++++++++++++++++--- osi/core/osi_core.c | 3 +++ 4 files changed, 65 insertions(+), 5 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index a857cd6..453b4b2 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -1207,6 +1207,15 @@ struct osi_core_priv_data { struct osi_macsec_lut_status *macsec_lut_status; /** 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; diff --git a/osi/core/macsec.c b/osi/core/macsec.c index 14f7970..62ee507 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -20,6 +20,7 @@ * DEALINGS IN THE SOFTWARE. */ +#ifdef MACSEC_SUPPORT #ifdef MACSEC_KEY_PROGRAM #include <linux/crypto.h> #endif @@ -520,6 +521,19 @@ nve32_t macsec_enable(struct osi_core_priv_data *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) || (enable & OSI_MACSEC_RX_EN)) && + (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, @@ -545,11 +559,18 @@ nve32_t macsec_enable(struct osi_core_priv_data *osi_core, nveu32_t enable) val &= ~(MACSEC_RX_EN); } + if ((enable & OSI_MACSEC_TX_EN) || (enable & OSI_MACSEC_RX_EN)) + osi_core->is_macsec_enabled = OSI_ENABLE; + else + osi_core->is_macsec_enabled = OSI_DISABLE; + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, "Write MACSEC_CONTROL0:\n", val); osi_writela(osi_core, val, base + MACSEC_CONTROL0); - return 0; +exit: + osi_unlock_irq_enabled(&osi_core->macsec_fpe_lock); + return ret; } #ifdef MACSEC_KEY_PROGRAM @@ -3280,3 +3301,4 @@ nve32_t osi_macsec_dbg_events_config( return -1; } +#endif /* MACSEC_SUPPORT */ diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index bbe882f..73c878c 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -4838,6 +4838,7 @@ static int mgbe_hw_config_fpe(struct osi_core_priv_data *osi_core, 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)) { @@ -4846,6 +4847,17 @@ static int mgbe_hw_config_fpe(struct osi_core_priv_data *osi_core, 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) & @@ -4862,7 +4874,11 @@ static int mgbe_hw_config_fpe(struct osi_core_priv_data *osi_core, osi_writela(osi_core, val, (nveu8_t *)osi_core->base + MGBE_MAC_FPE_CTS); - return 0; +#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 + @@ -4891,7 +4907,8 @@ static int mgbe_hw_config_fpe(struct osi_core_priv_data *osi_core, 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); - return -1; + ret = -1; + goto exit; } val = osi_readla(osi_core, (unsigned char *) @@ -4928,7 +4945,16 @@ static int mgbe_hw_config_fpe(struct osi_core_priv_data *osi_core, osi_writela(osi_core, val, (unsigned char *) osi_core->base + MGBE_MTL_FPE_ADV); - return 0; +#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; } /** diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 7fa9d97..043d194 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -193,6 +193,9 @@ nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core) 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; From b45b90249113f7ecafd4d838bac2f4be161a0c88 Mon Sep 17 00:00:00 2001 From: Gaurav Asati <gasati@nvidia.com> Date: Tue, 21 Dec 2021 20:09:39 +0530 Subject: [PATCH 311/458] nvethernetrm: add support desc dump on QNX. - Enable desc dump on normal builds - export API osi_dma_ioctl Bug 3375445 Change-Id: I66f33f6c370ebcfcfa194e88d598633cd0892a15 Signed-off-by: Gaurav Asati <gasati@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2645253 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/Makefile.tmk | 7 ++++++- osi/dma/Makefile.tmk | 7 ++++++- osi/dma/libnvethernetcl.export | 5 +++-- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/osi/core/Makefile.tmk b/osi/core/Makefile.tmk index 62d8355..9d98508 100644 --- a/osi/core/Makefile.tmk +++ b/osi/core/Makefile.tmk @@ -1,6 +1,6 @@ ################################### tell Emacs this is a -*- makefile-gmake -*- # -# Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved. +# 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"), @@ -40,10 +40,15 @@ NV_COMPONENT_SOURCES := \ mgbe_core.c \ xpcs.c \ mgbe_mmc.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 +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 diff --git a/osi/dma/Makefile.tmk b/osi/dma/Makefile.tmk index a9f8942..7e1e52d 100644 --- a/osi/dma/Makefile.tmk +++ b/osi/dma/Makefile.tmk @@ -1,6 +1,6 @@ ################################### tell Emacs this is a -*- makefile-gmake -*- # -# Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved. +# 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"), @@ -45,6 +45,11 @@ 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 diff --git a/osi/dma/libnvethernetcl.export b/osi/dma/libnvethernetcl.export index 5ffcc3b..311e3bc 100644 --- a/osi/dma/libnvethernetcl.export +++ b/osi/dma/libnvethernetcl.export @@ -1,6 +1,6 @@ ################################### tell Emacs this is a -*- makefile-gmake -*- # -# Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved. +# 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"), @@ -38,4 +38,5 @@ osi_dma_get_systime_from_mac osi_is_mac_enabled osi_get_dma osi_handle_dma_intr -osi_get_global_dma_status \ No newline at end of file +osi_get_global_dma_status +osi_dma_ioctl From 3bf1ec11e0e97644afdf4edf44f0ec8e6e3d4b88 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Thu, 27 Jan 2022 07:37:13 +0530 Subject: [PATCH 312/458] osi: dma: combine global DMA status functions Global DMA status register offsets are same for EQOS and MGBE. Combine EQOS and MGBE function into single function instead of two functions. Bug 200770328 Change-Id: Ia5dfebfd4625daa7bfd04e53e13a6df6a111047e Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2660067 Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Gaurav Asati <gasati@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/dma/dma_local.h | 4 +--- osi/dma/eqos_dma.c | 21 +-------------------- osi/dma/eqos_dma.h | 3 +-- osi/dma/hw_common.h | 36 ++++++++++++++++++++++++++++++++++++ osi/dma/mgbe_dma.c | 15 +-------------- osi/dma/mgbe_dma.h | 3 +-- osi/dma/osi_dma.c | 5 +++-- 7 files changed, 44 insertions(+), 43 deletions(-) create mode 100644 osi/dma/hw_common.h diff --git a/osi/dma/dma_local.h b/osi/dma/dma_local.h index 163f9a1..a1cbd35 100644 --- a/osi/dma/dma_local.h +++ b/osi/dma/dma_local.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -84,8 +84,6 @@ struct dma_chan_ops { nveu32_t set, nveu32_t interval); #endif /* !OSI_STRIPPED_LIB */ - /** Called to get Global DMA status */ - nveu32_t (*get_global_dma_status)(void *addr); /** Called to clear VM Tx interrupt */ void (*clear_vm_tx_intr)(void *addr, nveu32_t chan); /** Called to clear VM Rx interrupt */ diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index 7ac0aed..095ddbf 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2021, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -897,24 +897,6 @@ static void eqos_config_slot(struct osi_dma_priv_data *osi_dma, } #endif /* !OSI_STRIPPED_LIB */ -/** - * @brief eqos_get_global_dma_status - Gets DMA status. - * - * Algorithm: Returns global DMA Tx/Rx interrupt status - * - * @param[in] addr: MAC base address. - * - * @note - * Dependencies: None. - * Protection: None. - * - * @retval status - */ -static nveu32_t eqos_get_global_dma_status(void *addr) -{ - return osi_readl((nveu8_t *)addr + EQOS_GLOBAL_DMA_STATUS); -} - /** * @brief eqos_clear_vm_tx_intr - Handle VM Tx interrupt * @@ -1001,7 +983,6 @@ void eqos_init_dma_chan_ops(struct dma_chan_ops *ops) ops->validate_regs = eqos_validate_dma_regs; ops->config_slot = eqos_config_slot; #endif /* !OSI_STRIPPED_LIB */ - ops->get_global_dma_status = eqos_get_global_dma_status; 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 index fd17fde..7644438 100644 --- a/osi/dma/eqos_dma.h +++ b/osi/dma/eqos_dma.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2021, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -58,7 +58,6 @@ #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)) -#define EQOS_GLOBAL_DMA_STATUS (0x8700U) /** @} */ /** diff --git a/osi/dma/hw_common.h b/osi/dma/hw_common.h new file mode 100644 index 0000000..a7b6335 --- /dev/null +++ b/osi/dma/hw_common.h @@ -0,0 +1,36 @@ +/* + * 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/mgbe_dma.c b/osi/dma/mgbe_dma.c index 6d9d6db..186730c 100644 --- a/osi/dma/mgbe_dma.c +++ b/osi/dma/mgbe_dma.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -635,18 +635,6 @@ static nve32_t mgbe_validate_dma_regs(struct osi_dma_priv_data *osi_dma) return 0; } -/** - * @brief mgbe_get_global_dma_status - Gets DMA status. - * - * Algorithm: Returns global DMA Tx/Rx interrupt status - * - * @param[in] addr: MAC base address. - */ -static nveu32_t mgbe_get_global_dma_status(void *addr) -{ - return osi_readl((nveu8_t *)addr + MGBE_GLOBAL_DMA_STATUS); -} - /** * @brief mgbe_clear_vm_tx_intr - Clear VM Tx interrupt * @@ -748,7 +736,6 @@ void mgbe_init_dma_chan_ops(struct dma_chan_ops *ops) 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->get_global_dma_status = mgbe_get_global_dma_status; 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 index 3b93cdc..1538936 100644 --- a/osi/dma/mgbe_dma.h +++ b/osi/dma/mgbe_dma.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -94,7 +94,6 @@ #define MGBE_DMA_CHX_RBSZ_MASK 0x7FFEU #define MGBE_DMA_CHX_RBSZ_SHIFT 1U #define MGBE_AXI_BUS_WIDTH 0x10U -#define MGBE_GLOBAL_DMA_STATUS 0x8700U #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) diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index cb07cb0..65fa3a3 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2021, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -27,6 +27,7 @@ #ifdef OSI_DEBUG #include "debug.h" #endif /* OSI_DEBUG */ +#include "hw_common.h" /** * @brief g_dma - DMA local data array. @@ -468,7 +469,7 @@ nveu32_t osi_get_global_dma_status(struct osi_dma_priv_data *osi_dma) return 0; } - return l_dma->ops_p->get_global_dma_status(osi_dma->base); + 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, From 7ef7709b49bedd5f7ec240f46ad420adaf83ca94 Mon Sep 17 00:00:00 2001 From: Mahesh Patil <maheshp@nvidia.com> Date: Mon, 18 Oct 2021 16:41:06 -0700 Subject: [PATCH 313/458] nvethernetrm: macsec qnx OSI changes Macsec qnx driver OSI changes Bug 3338180 Change-Id: I2ad4f1b8b919893f2823a120973c1805b58bbb88 Signed-off-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2612659 GVS: Gerrit_Virtual_Submit Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: Gaurav Asati <gasati@nvidia.com> Tested-by: Sanath Kumar Gampa <sgampa@nvidia.com> --- include/osi_core.h | 2 +- osi/core/Makefile.tmk | 16 +- osi/core/eqos_core.c | 42 +++-- osi/core/libnvethernetrm.export | 18 +- osi/core/macsec.c | 313 ++++++++++++++++++++------------ osi/core/macsec.h | 10 +- osi/core/mgbe_core.c | 38 ++-- 7 files changed, 284 insertions(+), 155 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 453b4b2..3c45359 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -1194,9 +1194,9 @@ struct osi_core_priv_data { void *dma_base; /** Memory mapped base address of XPCS IP */ void *xpcs_base; -#ifdef MACSEC_SUPPORT /** 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 */ diff --git a/osi/core/Makefile.tmk b/osi/core/Makefile.tmk index 9d98508..b1a858f 100644 --- a/osi/core/Makefile.tmk +++ b/osi/core/Makefile.tmk @@ -43,7 +43,18 @@ NV_COMPONENT_SOURCES := \ 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_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 @@ -52,6 +63,9 @@ endif NV_COMPONENT_INCLUDES := \ $(NV_SOURCE)/nvethernetrm/include \ $(NV_SOURCE)/nvethernetrm/osi/common/include +#ifeq ($(NV_BUILD_CONFIGURATION_OS_IS_QNX),1) +#NV_COMPONENT_SYSTEM_SHARED_LIBRARIES += qcrypto +#endif include $(NV_BUILD_SHARED_LIBRARY) endif diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 0b9fe41..696c735 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2021, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -6468,24 +6468,30 @@ void eqos_config_for_macsec(struct osi_core_priv_data *const osi_core, eqos_config_mac_tx(osi_core, OSI_ENABLE); } - /* Updated MTL_EST depending on MACSEC enable/disable */ - if (osi_core->hw_feature->est_sel == OSI_ENABLE) { - value = osi_readla(osi_core, - (unsigned char *)osi_core->base + - EQOS_MTL_EST_CONTROL); - value &= ~EQOS_MTL_EST_CONTROL_CTOV; - if (enable == OSI_ENABLE) { - value |= (EQOS_MTL_EST_CTOV_MACSEC_RECOMMEND << - EQOS_MTL_EST_CONTROL_CTOV_SHIFT) & - EQOS_MTL_EST_CONTROL_CTOV; - } else { - value |= (EQOS_MTL_EST_CTOV_RECOMMEND << - EQOS_MTL_EST_CONTROL_CTOV_SHIFT) & - EQOS_MTL_EST_CONTROL_CTOV; + 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, + (unsigned char *)osi_core->base + + EQOS_MTL_EST_CONTROL); + value &= ~EQOS_MTL_EST_CONTROL_CTOV; + if (enable == OSI_ENABLE) { + value |= (EQOS_MTL_EST_CTOV_MACSEC_RECOMMEND << + EQOS_MTL_EST_CONTROL_CTOV_SHIFT) & + EQOS_MTL_EST_CONTROL_CTOV; + } else { + value |= (EQOS_MTL_EST_CTOV_RECOMMEND << + EQOS_MTL_EST_CONTROL_CTOV_SHIFT) & + EQOS_MTL_EST_CONTROL_CTOV; + } + osi_writela(osi_core, value, + (nveu8_t *)osi_core->base + + EQOS_MTL_EST_CONTROL); } - 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); } } diff --git a/osi/core/libnvethernetrm.export b/osi/core/libnvethernetrm.export index 2383430..a5c9f43 100644 --- a/osi/core/libnvethernetrm.export +++ b/osi/core/libnvethernetrm.export @@ -1,6 +1,6 @@ ################################### tell Emacs this is a -*- makefile-gmake -*- # -# Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved. +# 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"), @@ -30,3 +30,19 @@ 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_lut_config +#osi_macsec_loopback +#osi_macsec_read_mmc +#osi_macsec_dbg_buf_config +#osi_macsec_dbg_events_config +#osi_macsec_kt_config +#osi_macsec_get_sc_lut_key_index diff --git a/osi/core/macsec.c b/osi/core/macsec.c index 62ee507..ea703da 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -21,18 +21,33 @@ */ #ifdef MACSEC_SUPPORT -#ifdef MACSEC_KEY_PROGRAM +#if defined(MACSEC_KEY_PROGRAM) && defined(QNX_OS) +#include <qcrypto/qcrypto.h> +#include <qcrypto/qcrypto_error.h> +#include <qcrypto/qcrypto_keys.h> +#elif defined(MACSEC_KEY_PROGRAM) && defined(LINUX_OS) #include <linux/crypto.h> #endif + #include <osi_macsec.h> #include "macsec.h" #include "../osi/common/common.h" #include "core_local.h" -#ifdef DEBUG_MACSEC + +#if defined(DEBUG_MACSEC) && defined(QNX_OS) +#define LOG(...) \ + { \ + slogf(0, 2, ##__VA_ARGS__); \ + } + +#elif defined(DEBUG_MACSEC) && defined(LINUX_OS) #include <linux/printk.h> +#define LOG(...) \ + { \ + pr_err(##__VA_ARGS__); \ + } #else -#define pr_cont(args...) -#define pr_err(args...) +#define LOG(...) #endif /** @@ -177,8 +192,7 @@ static void tx_dbg_trigger_evts( tx_trigger_evts &= ~MACSEC_TX_DBG_CAPTURE; } - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "tx_dbg_trigger_evts \n", tx_trigger_evts); + 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) { @@ -186,16 +200,15 @@ static void tx_dbg_trigger_evts( debug_ctrl_reg = osi_readla(osi_core, base + MACSEC_TX_DEBUG_CONTROL_0); debug_ctrl_reg |= MACSEC_TX_DEBUG_CONTROL_0_START_CAP; - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "debug_ctrl_reg \n", debug_ctrl_reg); + LOG("%s: debug_ctrl_reg 0x%x", __func__, + debug_ctrl_reg); osi_writela(osi_core, debug_ctrl_reg, base + MACSEC_TX_DEBUG_CONTROL_0); } } else { tx_trigger_evts = osi_readla(osi_core, base + MACSEC_TX_DEBUG_TRIGGER_EN_0); - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "tx_dbg_trigger_evts \n", tx_trigger_evts); + LOG("%s: 0x%x", __func__, tx_trigger_evts); if (tx_trigger_evts & MACSEC_TX_DBG_LKUP_MISS) { flags |= OSI_TX_DBG_LKUP_MISS_EVT; } @@ -274,8 +287,7 @@ static void rx_dbg_trigger_evts( } else { rx_trigger_evts &= ~MACSEC_RX_DBG_CAPTURE; } - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "rx_dbg_trigger_evts \n", rx_trigger_evts); + 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) { @@ -283,16 +295,15 @@ static void rx_dbg_trigger_evts( debug_ctrl_reg = osi_readla(osi_core, base + MACSEC_RX_DEBUG_CONTROL_0); debug_ctrl_reg |= MACSEC_RX_DEBUG_CONTROL_0_START_CAP; - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "debug_ctrl_reg \n", debug_ctrl_reg); + LOG("%s: debug_ctrl_reg 0x%x", __func__, + debug_ctrl_reg); osi_writela(osi_core, debug_ctrl_reg, base + MACSEC_RX_DEBUG_CONTROL_0); } } else { rx_trigger_evts = osi_readla(osi_core, base + MACSEC_RX_DEBUG_TRIGGER_EN_0); - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "rx_dbg_trigger_evts \n", rx_trigger_evts); + LOG("%s: 0x%x", __func__, rx_trigger_evts); if (rx_trigger_evts & MACSEC_RX_DBG_LKUP_MISS) { flags |= OSI_RX_DBG_LKUP_MISS_EVT; } @@ -541,21 +552,21 @@ nve32_t macsec_enable(struct osi_core_priv_data *osi_core, nveu32_t enable) 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); + "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); + "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); + "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); + "Disabling macsec RX \n", 0ULL); val &= ~(MACSEC_RX_EN); } @@ -564,8 +575,7 @@ nve32_t macsec_enable(struct osi_core_priv_data *osi_core, nveu32_t enable) else osi_core->is_macsec_enabled = OSI_DISABLE; - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "Write MACSEC_CONTROL0:\n", val); + LOG("Write MACSEC_CONTROL0: 0x%x\n", val); osi_writela(osi_core, val, base + MACSEC_CONTROL0); exit: @@ -1869,8 +1879,11 @@ static nve32_t macsec_lut_config(struct osi_core_priv_data *const osi_core, (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)) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Validating LUT config failed.\n", 0ULL); + 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; } @@ -1930,6 +1943,8 @@ static inline void handle_rx_sc_invalid_key( 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); @@ -1945,6 +1960,8 @@ static inline void handle_tx_sc_invalid_key( 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); @@ -1957,6 +1974,7 @@ static inline void handle_tx_sc_invalid_key( static inline void handle_safety_err_irq( struct osi_core_priv_data *const osi_core) { + LOG("%s()\n", __func__); } static inline void handle_rx_sc_replay_err( @@ -2080,8 +2098,7 @@ static inline void handle_tx_irq(struct osi_core_priv_data *const osi_core) nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; tx_isr = osi_readla(osi_core, addr + MACSEC_TX_ISR); - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "tx_isr \n", 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); @@ -2122,8 +2139,6 @@ static inline void handle_tx_irq(struct osi_core_priv_data *const osi_core) clear |= MACSEC_TX_PN_EXHAUSTED; } if (clear) { - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "write tx_isr \n", clear); osi_writela(osi_core, clear, addr + MACSEC_TX_ISR); } } @@ -2134,8 +2149,7 @@ static inline void handle_rx_irq(struct osi_core_priv_data *const osi_core) nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; rx_isr = osi_readla(osi_core, addr + MACSEC_RX_ISR); - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "rx_isr \n", 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) { @@ -2176,8 +2190,6 @@ static inline void handle_rx_irq(struct osi_core_priv_data *const osi_core) clear |= MACSEC_RX_PN_EXHAUSTED; } if (clear) { - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "write rx_isr \n", clear); osi_writela(osi_core, clear, addr + MACSEC_RX_ISR); } } @@ -2188,8 +2200,7 @@ static inline void handle_common_irq(struct osi_core_priv_data *const osi_core) nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; common_isr = osi_readla(osi_core, addr + MACSEC_COMMON_ISR); - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "common_isr \n", common_isr); + LOG("%s(): common_isr 0x%x\n", __func__, common_isr); if ((common_isr & MACSEC_SECURE_REG_VIOL) == MACSEC_SECURE_REG_VIOL) { osi_core->macsec_irq_stats.secure_reg_viol++; @@ -2230,8 +2241,7 @@ static void macsec_handle_ns_irq(struct osi_core_priv_data *const osi_core) nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; irq_common_sr = osi_readla(osi_core, addr + MACSEC_INTERRUPT_COMMON_SR); - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "common_sr \n", irq_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); } @@ -2256,8 +2266,7 @@ 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; - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "macsec_handle_s_irq \n", 0ULL); + LOG("%s()\n", __func__); common_isr = osi_readla(osi_core, addr + MACSEC_COMMON_ISR); if (common_isr != OSI_NONE) { @@ -2333,8 +2342,8 @@ static nve32_t clear_lut(struct osi_core_priv_data *const osi_core) table_config->index = j; ret = macsec_lut_config(osi_core, &lut_config); if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Error Clearing BYP LUT\n", 0ULL); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Error clearing CTLR:BYPASS LUT:INDEX: \n", j); return ret; } } @@ -2348,8 +2357,8 @@ static nve32_t clear_lut(struct osi_core_priv_data *const osi_core) table_config->index = j; ret = macsec_lut_config(osi_core, &lut_config); if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Error Clearing SCI LUT\n", 0ULL); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Error clearing CTLR:SCI LUT:INDEX: \n", j); return ret; } } @@ -2363,9 +2372,8 @@ static nve32_t clear_lut(struct osi_core_priv_data *const osi_core) table_config->index = j; ret = macsec_lut_config(osi_core, &lut_config); if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Error Clearing SC Param LUT \n", - 0ULL); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Error clearing CTLR:SC PARAM LUT:INDEX: \n", j); return ret; } } @@ -2379,9 +2387,8 @@ static nve32_t clear_lut(struct osi_core_priv_data *const osi_core) table_config->index = j; ret = macsec_lut_config(osi_core, &lut_config); if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Error Clearing SC State LUT \n", - 0ULL); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Error clearing CTLR:SC STATE LUT:INDEX: \n", j); return ret; } } @@ -2394,9 +2401,8 @@ static nve32_t clear_lut(struct osi_core_priv_data *const osi_core) table_config->index = j; ret = macsec_lut_config(osi_core, &lut_config); if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Error Clearing Tx SA State LUT\n", - 0ULL); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Error clearing TX CTLR:SA STATE LUT:INDEX: \n", j); return ret; } } @@ -2408,9 +2414,8 @@ static nve32_t clear_lut(struct osi_core_priv_data *const osi_core) table_config->index = j; ret = macsec_lut_config(osi_core, &lut_config); if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Error Clearing Rx SA State LUT\n", - 0ULL); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Error clearing RX CTLR:SA STATE LUT:INDEX: \n", j); return ret; } } @@ -2425,8 +2430,8 @@ static nve32_t clear_lut(struct osi_core_priv_data *const osi_core) table_config->index = j; ret = macsec_kt_config(osi_core, &kt_config); if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Error Clearing KT\n", 0ULL); + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Error clearing KT LUT:INDEX: \n", j); return ret; } } @@ -2453,7 +2458,6 @@ static nve32_t macsec_deinit(struct osi_core_priv_data *const osi_core) OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Failed config MAC per macsec\n", 0ULL); } - return 0; } @@ -2483,21 +2487,17 @@ static nve32_t macsec_init(struct osi_core_priv_data *const osi_core) /* Set MTU */ val = osi_readla(osi_core, addr + MACSEC_TX_MTU_LEN); - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "Read MACSEC_TX_MTU_LEN: \n", val); + LOG("Read MACSEC_TX_MTU_LEN: 0x%x\n", val); val &= ~(MTU_LENGTH_MASK); val |= (mtu & MTU_LENGTH_MASK); - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "Write MACSEC_TX_MTU_LEN: \n", val); + 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); - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "Read MACSEC_RX_MTU_LEN: \n", val); + LOG("Read MACSEC_RX_MTU_LEN: 0x%x\n", val); val &= ~(MTU_LENGTH_MASK); val |= (mtu & MTU_LENGTH_MASK); - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "Write MACSEC_RX_MTU_LEN: \n", val); + LOG("Write MACSEC_RX_MTU_LEN: 0x%x\n", val); osi_writela(osi_core, val, addr + MACSEC_RX_MTU_LEN); /* set TX/RX SOT, as SOT value different for eqos. @@ -2505,68 +2505,57 @@ static nve32_t macsec_init(struct osi_core_priv_data *const osi_core) */ if (osi_core->mac == OSI_MAC_HW_EQOS) { val = osi_readla(osi_core, addr + MACSEC_TX_SOT_DELAY); - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "Read MACSEC_TX_SOT_DELAY: \n", val); + LOG("Read MACSEC_TX_SOT_DELAY: 0x%x\n", val); val &= ~(SOT_LENGTH_MASK); val |= (EQOS_MACSEC_SOT_DELAY & SOT_LENGTH_MASK); - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "Write MACSEC_TX_SOT_DELAY \n", val); + 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); - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "Read MACSEC_RX_SOT_DELAY: \n", val); + LOG("Read MACSEC_RX_SOT_DELAY: 0x%x\n", val); val &= ~(SOT_LENGTH_MASK); val |= (EQOS_MACSEC_SOT_DELAY & SOT_LENGTH_MASK); - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "Write MACSEC_RX_SOT_DELAY \n", val); + 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); - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "Read MACSEC_CONTROL0: \n", val); + 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; - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "Write MACSEC_CONTROL0: \n", val); + LOG("Write MACSEC_CONTROL0: 0x%x\n", val); osi_writela(osi_core, val, addr + MACSEC_CONTROL0); val = osi_readla(osi_core, addr + MACSEC_CONTROL1); - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "Read MACSEC_CONTROL1: \n", val); + LOG("Read MACSEC_CONTROL1: 0x%x\n", val); val |= (MACSEC_RX_MTU_CHECK_EN | MACSEC_TX_LUT_PRIO_BYP | MACSEC_TX_MTU_CHECK_EN); - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "Write MACSEC_CONTROL1: \n", val); + LOG("Write MACSEC_CONTROL1: 0x%x\n", val); osi_writela(osi_core, val, addr + MACSEC_CONTROL1); /* set DVLAN tag ethertype */ /* val = DVLAN_TAG_ETHERTYPE; - * pr_err("Write MACSEC_TX_DVLAN_CONTROL_0: 0x%x\n", val); + * LOG("Write MACSEC_TX_DVLAN_CONTROL_0: 0x%x\n", val); * osi_writela(osi_core, val, addr + MACSEC_TX_DVLAN_CONTROL_0); - * pr_err("Write MACSEC_RX_DVLAN_CONTROL_0: 0x%x\n", val); + * LOG("Write MACSEC_RX_DVLAN_CONTROL_0: 0x%x\n", val); * osi_writela(osi_core, val, addr + MACSEC_RX_DVLAN_CONTROL_0); */ val = osi_readla(osi_core, addr + MACSEC_STATS_CONTROL_0); - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "Read MACSEC_STATS_CONTROL_0: \n", val); + LOG("Read MACSEC_STATS_CONTROL_0: 0x%x\n", val); /* set STATS rollover bit */ val |= MACSEC_STATS_CONTROL0_CNT_RL_OVR_CPY; - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "Write MACSEC_STATS_CONTROL_0: \n", val); + 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); - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "Read MACSEC_TX_IMR: \n", val); + 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 | @@ -2574,13 +2563,11 @@ static nve32_t macsec_init(struct osi_core_priv_data *const osi_core) MACSEC_TX_AES_GCM_BUF_OVF_INT_EN | MACSEC_TX_PN_EXHAUSTED_INT_EN | MACSEC_TX_PN_THRSHLD_RCHD_INT_EN); - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "Write MACSEC_TX_IMR: \n", val); + LOG("Write MACSEC_TX_IMR: 0x%x\n", val); osi_writela(osi_core, val, addr + MACSEC_TX_IMR); val = osi_readla(osi_core, addr + MACSEC_RX_IMR); - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "Read MACSEC_RX_IMR: \n", val); + 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 | @@ -2589,21 +2576,18 @@ static nve32_t macsec_init(struct osi_core_priv_data *const osi_core) MACSEC_RX_AES_GCM_BUF_OVF_INT_EN | MACSEC_RX_PN_EXHAUSTED_INT_EN ); - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "Write MACSEC_RX_IMR: \n", val); + 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); - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "Read MACSEC_COMMON_IMR: \n", val); + 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); - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "Write MACSEC_COMMON_IMR: \n", val); + LOG("Write MACSEC_COMMON_IMR: 0x%x\n", val); osi_writela(osi_core, val, addr + MACSEC_COMMON_IMR); /* Set AES mode @@ -2814,28 +2798,106 @@ static nve32_t add_upd_sc(struct osi_core_priv_data *const osi_core, nve32_t ret, i; #ifdef MACSEC_KEY_PROGRAM struct osi_macsec_kt_config kt_config = {0}; + nveu8_t hkey[OSI_KEY_LEN_128] = {0}; + nveu8_t zeros[OSI_KEY_LEN_128] = {0}; #endif /* MACSEC_KEY_PROGRAM */ -#ifdef MACSEC_KEY_PROGRAM - /* HKEY GENERATION */ +#if defined(MACSEC_KEY_PROGRAM) && defined(QNX_OS) + qcrypto_ctx_t *qctx = NULL; + qcrypto_ctx_t *qkeyctx = NULL; + qcrypto_key_t *qkey = NULL; + unsigned long int out_len = 0; + /* Initialize cipher arguments */ + qcrypto_cipher_args_t cargs = { + .action = QCRYPTO_CIPHER_ENCRYPT, + .iv = NULL, + .ivsize = 0, + }; + + LOG("%s: In Function :", __func__); + /* Initialize the Qcrypto Library */ + ret = qcrypto_init(QCRYPTO_INIT_LAZY, NULL); + if (ret != QCRYPTO_R_EOK) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "qcryto_init() failed\n", ret); + goto qcrypto_cleanup; + } + + /* Request symmetric keygen */ + ret = qcrypto_keygen_request("symmetric", NULL, 0, &qkeyctx); + if (ret != QCRYPTO_R_EOK) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "qcrypto_keygen_request() failed \n", ret); + goto qcrypto_cleanup; + } + + /* Request aes-128-ecb */ + ret = qcrypto_cipher_request("aes-128-ecb", NULL, 0, &qctx); + if (ret != QCRYPTO_R_EOK) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "qcrypto_cipher_request() failed \n", ret); + goto qcrypto_cleanup; + } + + /* Load key */ + ret = qcrypto_key_from_mem(qkeyctx, &qkey, sc->sak, OSI_KEY_LEN_128); + if (ret != QCRYPTO_R_EOK) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "qcrypto_key_from_mem() failed \n", ret); + goto qcrypto_cleanup; + } + + /* Initialize cipher encryption */ + ret = qcrypto_cipher_init(qctx, qkey, &cargs); + if (ret != QCRYPTO_R_EOK) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "qcrypto_cipher_init() failed \n", ret); + goto qcrypto_cleanup; + } + + /* Cipher encryption */ + ret = qcrypto_cipher_encrypt(qctx, zeros, OSI_KEY_LEN_128, hkey, &out_len); + if (ret != QCRYPTO_R_EOK) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "qcrypto_cipher_encrypt() failed \n", ret); + goto qcrypto_cleanup; + } + LOG(" %s: Generated H key: "HKEYSTR, __func__, HKEY2STR(hkey)); + /* Finalize cipher encryption */ + ret = qcrypto_cipher_final(qctx, hkey, &out_len); + if (ret != QCRYPTO_R_EOK) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "qcrypto_cipher_final() failed \n", ret); + goto qcrypto_cleanup; + } + +qcrypto_cleanup: + /* Release all context handles */ + qcrypto_release_ctx(qctx); + qcrypto_release_ctx(qkeyctx); + /* Release the key handle */ + qcrypto_release_key(qkey); + /* Uninitialize the Qcrypto Library */ + qcrypto_uninit(); + +#elif defined(MACSEC_KEY_PROGRAM) && defined(LINUX_OS) + /* HKEY GENERATION */ struct crypto_cipher *tfm; - nveu8_t hkey[OSI_KEY_LEN_128]; - nveu8_t zeros[OSI_KEY_LEN_128] = {0}; tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); if (crypto_cipher_setkey(tfm, sc->sak, OSI_KEY_LEN_128)) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Failed to set cipher key for H generation\n", 0ULL); + "Failed to set key for H generation\n", 0ULL); return -1; } crypto_cipher_encrypt_one(tfm, hkey, zeros); - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Generated H key \n", 0ULL); + LOG(" %s: Generated H key: "HKEYSTR, __func__, HKEY2STR(hkey)); crypto_free_cipher(tfm); -#endif /* MACSEC_KEY_PROGRAM */ +#endif /* MACSEC_KEY_PROGRAM && QNX_OS*/ /* Store key table index returned to osd */ *kt_idx = (sc->sc_idx_start * OSI_MAX_NUM_SA) + sc->curr_an; + #ifdef MACSEC_KEY_PROGRAM /* 1. Key LUT */ table_config = &kt_config.table_config; @@ -2975,6 +3037,7 @@ err_sa_state: table_config->index = *kt_idx; macsec_kt_config(osi_core, &kt_config); #endif /* MACSEC_KEY_PROGRAM */ + return -1; } @@ -3005,8 +3068,7 @@ static nve32_t macsec_config(struct osi_core_priv_data *const osi_core, 0ULL); return -1; } else { - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Adding new SC/SA: \n", ctlr); + LOG("%s: Adding new SC/SA: ctlr: %hu", __func__, ctlr); if (lut_status->next_sc_idx >= OSI_MAX_NUM_SC) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Err: Reached max SC LUT entries!\n", 0ULL); @@ -3024,6 +3086,20 @@ static nve32_t macsec_config(struct osi_core_priv_data *const osi_core, new_sc->sc_idx_start = lut_status->next_sc_idx; new_sc->an_valid |= OSI_BIT(sc->curr_an); + LOG("%s: Adding new SC\n" + "\tsci: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n" + "\tan: %u\n" + "\tpn: %u" + "\tsc_idx_start: %u" + "\tan_valid: %#x \tpn_window: %#x\n", __func__, + new_sc->sci[0], new_sc->sci[1], new_sc->sci[2], + new_sc->sci[3], new_sc->sci[4], new_sc->sci[5], + new_sc->sci[6], new_sc->sci[7], + new_sc->curr_an, new_sc->next_pn, + new_sc->sc_idx_start, + new_sc->an_valid, new_sc->pn_window); + LOG("key: "KEYSTR, KEY2STR(new_sc->sak)); + if (add_upd_sc(osi_core, new_sc, ctlr, kt_idx) != OSI_NONE) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, @@ -3032,17 +3108,17 @@ static nve32_t macsec_config(struct osi_core_priv_data *const osi_core, } else { /* Update lut status */ lut_status->next_sc_idx++; - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Added new SC\n", 0ULL); + LOG("%s: Added new SC ctlr: %u " + "nxt_sc_idx: %u", + __func__, ctlr, + lut_status->next_sc_idx); return 0; } } } else { - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Updating existing SC \n", 0ULL); + LOG("%s: Updating existing SC", __func__); if (enable == OSI_DISABLE) { - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Deleting existing SA \n", 0ULL); + LOG("%s: Deleting existing SA", __func__); if (del_upd_sc(osi_core, existing_sc, sc, ctlr, kt_idx) != OSI_NONE) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, @@ -3077,8 +3153,10 @@ static nve32_t macsec_config(struct osi_core_priv_data *const osi_core, "failed to add new SA\n", 0ULL); return -1; } else { - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "Updated new SC\n", ctlr); + LOG("%s: Updated new SC ctlr: %u " + "nxt_sc_idx: %u", + __func__, ctlr, + lut_status->next_sc_idx); /* Now commit the changes */ *existing_sc = *tmp_sc_p; return 0; @@ -3301,4 +3379,5 @@ nve32_t osi_macsec_dbg_events_config( return -1; } + #endif /* MACSEC_SUPPORT */ diff --git a/osi/core/macsec.h b/osi/core/macsec.h index 108c727..a1b7531 100644 --- a/osi/core/macsec.h +++ b/osi/core/macsec.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -23,6 +23,14 @@ #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 */ + /** * @addtogroup MACsec AMAP * diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 73c878c..7ff7c6e 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -5876,24 +5876,30 @@ void mgbe_config_for_macsec(struct osi_core_priv_data *const osi_core, /* start MAC Tx */ mgbe_config_mac_tx(osi_core, OSI_ENABLE); - /* Program MTL_EST depending on MACSEC enable/disable */ - if (osi_core->hw_feature->est_sel == OSI_ENABLE) { - value = osi_readla(osi_core, - (unsigned char *)osi_core->base + - MGBE_MTL_EST_CONTROL); - value &= ~MGBE_MTL_EST_CONTROL_CTOV; - if (enable == OSI_ENABLE) { - value |= (MGBE_MTL_EST_CTOV_MACSEC_RECOMMEND << - MGBE_MTL_EST_CONTROL_CTOV_SHIFT) & - MGBE_MTL_EST_CONTROL_CTOV; + 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, + (unsigned char *)osi_core->base + + MGBE_MTL_EST_CONTROL); + value &= ~MGBE_MTL_EST_CONTROL_CTOV; + if (enable == OSI_ENABLE) { + value |= (MGBE_MTL_EST_CTOV_MACSEC_RECOMMEND << + MGBE_MTL_EST_CONTROL_CTOV_SHIFT) & + MGBE_MTL_EST_CONTROL_CTOV; + } else { + value |= (MGBE_MTL_EST_CTOV_RECOMMEND << + MGBE_MTL_EST_CONTROL_CTOV_SHIFT) & + MGBE_MTL_EST_CONTROL_CTOV; + } + osi_writela(osi_core, value, + (unsigned char *)osi_core->base + + MGBE_MTL_EST_CONTROL); } else { - value |= (MGBE_MTL_EST_CTOV_RECOMMEND << - MGBE_MTL_EST_CONTROL_CTOV_SHIFT) & - MGBE_MTL_EST_CONTROL_CTOV; + OSI_CORE_ERR(osi_core->osd, + OSI_LOG_ARG_HW_FAIL, "Error: osi_core->hw_feature is NULL\n", + 0ULL); } - osi_writela(osi_core, value, - (unsigned char *)osi_core->base + - MGBE_MTL_EST_CONTROL); } } #endif /* MACSEC_SUPPORT */ From bc95f426a73e4691347bf8b0e332b3b6734904b7 Mon Sep 17 00:00:00 2001 From: Sanath Kumar Gampa <sgampa@nvidia.com> Date: Fri, 10 Dec 2021 14:44:58 +0530 Subject: [PATCH 314/458] To fecilitate calling the PTP-TSC capture in ISR Change the usleep used to udelay, so that PTP-TSC fetching can happen in ISR context Bug 3430408 Change-Id: I2d6f3755e94fafabe80913fd81cbf1a85c83d407 Signed-off-by: Sanath Kumar Gampa <sgampa@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2639986 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/eqos_core.c | 6 +++--- osi/core/mgbe_core.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 696c735..b551657 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -67,7 +67,7 @@ static struct core_func_safety eqos_core_safety_config; 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 = 1000U; + nveu32_t retry = 20U; nveu32_t count = 0U, val = 0U; nve32_t cond = COND_NOT_MET; nve32_t ret = -1; @@ -94,8 +94,8 @@ static nve32_t eqos_ptp_tsc_capture(struct osi_core_priv_data *const osi_core, if ((val & OSI_ENABLE) == OSI_NONE) { cond = COND_MET; } else { - /* sleep if SWR is set */ - osi_core->osd_ops.msleep(1U); + /* delay if SWR is set */ + osi_core->osd_ops.udelay(1U); } } diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 7ff7c6e..eb8c042 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -55,7 +55,7 @@ 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 = 1000U; + nveu32_t retry = 20U; nveu32_t count = 0U, val = 0U; nve32_t cond = COND_NOT_MET; nve32_t ret = -1; @@ -77,8 +77,8 @@ static nve32_t mgbe_ptp_tsc_capture(struct osi_core_priv_data *const osi_core, if ((val & OSI_ENABLE) == OSI_NONE) { cond = COND_MET; } else { - /* sleep if SWR is set */ - osi_core->osd_ops.msleep(1U); + /* delay if SWR is set */ + osi_core->osd_ops.udelay(1U); } } From 418c1130ca3196442e226eeaeb86e7ff5a74fcc8 Mon Sep 17 00:00:00 2001 From: Om Prakash Singh <omp@nvidia.com> Date: Fri, 4 Feb 2022 11:26:41 +0530 Subject: [PATCH 315/458] osi: fix mmc.h dependency on osi_common.h mmc.h uses few definition from osi_common.h Bug 3500728 Change-Id: I95696ddd63cee4979c0a79cda9a87e65b895dee0 Signed-off-by: Om Prakash Singh <omp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2663878 Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/mmc.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/mmc.h b/include/mmc.h index 6f5e2a0..194135c 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2021, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -24,6 +24,7 @@ #define INCLUDED_MMC_H #include "../osi/common/type.h" +#include "osi_common.h" /** * @brief osi_mmc_counters - The structure to hold RMON counter values From c2a5ef726b8253646d07ddc1f2a390529e107ab2 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Tue, 8 Feb 2022 18:30:25 +0530 Subject: [PATCH 316/458] osi: fix coverity defects CID 10060746 Big parameter passed by value CID 10060747 Big parameter passed by value CID 10127879 Dereference after null check Bug 3461002 Change-Id: Ib1d88177ade979e43e9177ff69f7817982b39be0 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2665777 Reviewed-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Sachin Nikam <snikam@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/mgbe_core.c | 6 ------ osi/dma/dma_local.h | 2 +- osi/dma/eqos_desc.c | 17 ++++++----------- osi/dma/mgbe_desc.c | 28 ++++++++++++---------------- osi/dma/osi_dma_txrx.c | 4 ++-- 5 files changed, 21 insertions(+), 36 deletions(-) diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index eb8c042..acc6529 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -4441,12 +4441,6 @@ static int mgbe_write_phy_reg(struct osi_core_priv_data *osi_core, int ret = 0; unsigned int reg; - if (osi_core == OSI_NULL) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "osi_core is NULL\n", - 0ULL); - return -1; - } - /* Wait for any previous MII read/write operation to complete */ ret = mgbe_mdio_busy_wait(osi_core); if (ret < 0) { diff --git a/osi/dma/dma_local.h b/osi/dma/dma_local.h index a1cbd35..697fdd1 100644 --- a/osi/dma/dma_local.h +++ b/osi/dma/dma_local.h @@ -99,7 +99,7 @@ struct desc_ops { 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 pkt_err_stats); + 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); diff --git a/osi/dma/eqos_desc.c b/osi/dma/eqos_desc.c index 89bdee5..5fbb301 100644 --- a/osi/dma/eqos_desc.c +++ b/osi/dma/eqos_desc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -62,23 +62,18 @@ static inline void eqos_get_rx_vlan(struct osi_rx_desc *rx_desc, * @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 - pkt_err_stats) + 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) { - pkt_err_stats.rx_crc_error = - osi_update_stats_counter( - pkt_err_stats.rx_crc_error, - 1UL); + 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) { - pkt_err_stats.rx_frame_error = - osi_update_stats_counter( - pkt_err_stats.rx_frame_error, - 1UL); + stats->rx_frame_error = + osi_update_stats_counter(stats->rx_frame_error, 1UL); } } diff --git a/osi/dma/mgbe_desc.c b/osi/dma/mgbe_desc.c index 178aaea..ef12db5 100644 --- a/osi/dma/mgbe_desc.c +++ b/osi/dma/mgbe_desc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -58,17 +58,15 @@ static inline void mgbe_get_rx_vlan(struct osi_rx_desc *rx_desc, * @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 - pkt_err_stats) + 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) { - pkt_err_stats.rx_crc_error = - osi_update_stats_counter(pkt_err_stats.rx_crc_error, - 1UL); + stats->rx_crc_error = + osi_update_stats_counter(stats->rx_crc_error, 1UL); } /* Update FRP Counters */ @@ -76,25 +74,23 @@ static inline void mgbe_update_rx_err_stats(struct osi_rx_desc *rx_desc, frpsl = rx_desc->rdes3 & MGBE_RDES3_FRPSL; /* Increment FRP parsed count */ if ((frpsm == OSI_NONE) && (frpsl == OSI_NONE)) { - pkt_err_stats.frp_parsed = - osi_update_stats_counter(pkt_err_stats.frp_parsed, 1UL); + stats->frp_parsed = + osi_update_stats_counter(stats->frp_parsed, 1UL); } /* Increment FRP dropped count */ if ((frpsm == OSI_NONE) && (frpsl == MGBE_RDES3_FRPSL)) { - pkt_err_stats.frp_dropped = - osi_update_stats_counter(pkt_err_stats.frp_dropped, - 1UL); + stats->frp_dropped = + osi_update_stats_counter(stats->frp_dropped, 1UL); } /* Increment FRP Parsing Error count */ if ((frpsm == MGBE_RDES2_FRPSM) && (frpsl == OSI_NONE)) { - pkt_err_stats.frp_err = - osi_update_stats_counter(pkt_err_stats.frp_err, 1UL); + 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)) { - pkt_err_stats.frp_incomplete = - osi_update_stats_counter(pkt_err_stats.frp_incomplete, - 1UL); + stats->frp_incomplete = + osi_update_stats_counter(stats->frp_incomplete, 1UL); } } diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index aef9bd0..62fc4bc 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2021, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -228,7 +228,7 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, */ rx_pkt_cx->flags &= ~OSI_PKT_CX_VALID; d_ops[ip_type].update_rx_err_stats(rx_desc, - osi_dma->pkt_err_stats); + &osi_dma->pkt_err_stats); } /* Check if COE Rx checksum is valid */ From c5328a53d682155bdcb75c8157e43151d4848cf8 Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Fri, 28 Jan 2022 12:30:29 +0000 Subject: [PATCH 317/458] mgbe: modify AXI clock to 480MHz 480MHz APP clock needs to be used for 10G speed as per IAS. Change the clock source to reflect the same. Bug 200778229 Change-Id: Idf60c4a090ed82b0a1be58d5b45b3a557c59fdfc Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2660870 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Sachin Nikam <snikam@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/mgbe_core.h | 4 ++-- osi/dma/mgbe_dma.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index b038b1f..d91f883 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -49,9 +49,9 @@ #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 408-1 for silicon and 13MHZ-1 for uFPGA + * it should be APB clock in MHZ i.e 480-1 for silicon and 13MHZ-1 for uFPGA */ -#define MGBE_1US_TIC_COUNTER 0x197 +#define MGBE_1US_TIC_COUNTER 0x1DF /** @} */ diff --git a/osi/dma/mgbe_dma.h b/osi/dma/mgbe_dma.h index 1538936..9321501 100644 --- a/osi/dma/mgbe_dma.h +++ b/osi/dma/mgbe_dma.h @@ -29,7 +29,7 @@ * @brief AXI Clock defines * @{ */ -#define MGBE_AXI_CLK_FREQ 408000000U +#define MGBE_AXI_CLK_FREQ 480000000U /** @} */ /** From 491fc105ecfb569bebc49265d38349ef80942067 Mon Sep 17 00:00:00 2001 From: Sanath Kumar Gampa <sgampa@nvidia.com> Date: Mon, 10 Jan 2022 17:42:17 +0530 Subject: [PATCH 318/458] macsec: get next PN and IRQ stats cmd with server Some of the commands such as get next PN and irq stats are not working if thernet server is enabled, fixed the same. And also moved HKEY generation to OSD, to avoid dependency on Crypto libs on LK. devmemr/w can read/write to macsec addresses Bug 3522740 Change-Id: Id3b328cfd83aa976ef5bde8adc057588bb6fed38 Signed-off-by: Sanath Kumar Gampa <sgampa@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2652212 Reviewed-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-by: Gaurav Asati <gasati@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/ivc_core.h | 9 ++- include/osi_core.h | 4 ++ include/osi_macsec.h | 6 +- osi/core/core_local.h | 9 +++ osi/core/eqos_core.c | 46 +++++++++++++ osi/core/ivc_core.c | 66 ++++++++++++++++-- osi/core/macsec.c | 157 +++++++----------------------------------- osi/core/mgbe_core.c | 44 ++++++++++++ osi/core/osi_hal.c | 11 ++- 9 files changed, 211 insertions(+), 141 deletions(-) diff --git a/include/ivc_core.h b/include/ivc_core.h index 069345e..221a0eb 100644 --- a/include/ivc_core.h +++ b/include/ivc_core.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -57,6 +57,7 @@ typedef enum ivc_cmd { read_mmc_macsec, dbg_buf_config_macsec, dbg_events_config_macsec, + macsec_get_sc_lut_key_index, }ivc_cmd; /** @@ -110,6 +111,10 @@ typedef struct macsec_config { unsigned short ctlr; /** MACsec KT index */ unsigned short kt_idx; + /** MACsec KT index */ + nve32_t key_index; + /** MACsec SCI */ + nveu8_t sci[OSI_SCI_LEN]; } macsec_config; #endif @@ -157,6 +162,8 @@ typedef struct ivc_msg_common { 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; diff --git a/include/osi_core.h b/include/osi_core.h index 3c45359..4473934 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -232,6 +232,10 @@ typedef my_lint_64 nvel64_t; #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 */ /** @} */ /** diff --git a/include/osi_macsec.h b/include/osi_macsec.h index 6602425..27c1b29 100644 --- a/include/osi_macsec.h +++ b/include/osi_macsec.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -281,6 +281,10 @@ struct osi_macsec_sc_info { 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 */ diff --git a/osi/core/core_local.h b/osi/core/core_local.h index d030d65..0858e5b 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -187,6 +187,15 @@ struct core_ops { 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 */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index b551657..c70e1a5 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -5142,6 +5142,48 @@ static nveu32_t eqos_write_reg(struct osi_core_priv_data *const osi_core, 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. @@ -6542,6 +6584,10 @@ void eqos_init_core_ops(struct core_ops *ops) 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; diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index bfff91b..f8a30a3 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -287,6 +287,45 @@ static void ivc_macsec_read_mmc(struct osi_core_priv_data *const osi_core) msg.status = osi_memcpy((void *)&osi_core->macsec_mmc, (void *) &msg.data.macsec_mmc, sizeof(struct osi_macsec_mmc_counters)); + 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, nve32_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; } /** @@ -387,9 +426,10 @@ static int ivc_macsec_loopback_config(struct osi_core_priv_data *const osi_core, * @retval -1 on Failure */ static int ivc_macsec_kt_config(struct osi_core_priv_data *const osi_core, - struct osi_macsec_kt_config *const kt_config) + struct osi_macsec_kt_config *kt_config) { ivc_msg_common_t msg; + int ret = 0; osi_memset(&msg, 0, sizeof(msg)); @@ -398,7 +438,14 @@ static int ivc_macsec_kt_config(struct osi_core_priv_data *const osi_core, (void *)kt_config, sizeof(struct osi_macsec_kt_config)); - return osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); + 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 */ @@ -435,9 +482,10 @@ static int ivc_macsec_cipher_config(struct osi_core_priv_data *const osi_core, * @retval -1 on Failure */ static int ivc_macsec_lut_config(struct osi_core_priv_data *const osi_core, - struct osi_macsec_lut_config *const lut_config) + struct osi_macsec_lut_config *lut_config) { ivc_msg_common_t msg; + int ret = 0; osi_memset(&msg, 0, sizeof(msg)); @@ -446,7 +494,14 @@ static int ivc_macsec_lut_config(struct osi_core_priv_data *const osi_core, (void *)lut_config, sizeof(struct osi_macsec_lut_config)); - return osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); + 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; } /** @@ -539,6 +594,7 @@ void ivc_init_macsec_ops(void *macsecops) 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; } #endif diff --git a/osi/core/macsec.c b/osi/core/macsec.c index ea703da..943f1b8 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -21,14 +21,6 @@ */ #ifdef MACSEC_SUPPORT -#if defined(MACSEC_KEY_PROGRAM) && defined(QNX_OS) -#include <qcrypto/qcrypto.h> -#include <qcrypto/qcrypto_error.h> -#include <qcrypto/qcrypto_keys.h> -#elif defined(MACSEC_KEY_PROGRAM) && defined(LINUX_OS) -#include <linux/crypto.h> -#endif - #include <osi_macsec.h> #include "macsec.h" #include "../osi/common/common.h" @@ -795,7 +787,7 @@ static inline nve32_t poll_for_lut_update(struct osi_core_priv_data *osi_core) cond = 0; } else { /* wait on UPDATE bit to reset */ - osi_core->osd_ops.udelay(10U); + osi_core->osd_ops.udelay(1U); } } @@ -2798,126 +2790,33 @@ static nve32_t add_upd_sc(struct osi_core_priv_data *const osi_core, nve32_t ret, i; #ifdef MACSEC_KEY_PROGRAM struct osi_macsec_kt_config kt_config = {0}; - nveu8_t hkey[OSI_KEY_LEN_128] = {0}; - nveu8_t zeros[OSI_KEY_LEN_128] = {0}; #endif /* MACSEC_KEY_PROGRAM */ -#if defined(MACSEC_KEY_PROGRAM) && defined(QNX_OS) - qcrypto_ctx_t *qctx = NULL; - qcrypto_ctx_t *qkeyctx = NULL; - qcrypto_key_t *qkey = NULL; - unsigned long int out_len = 0; - /* Initialize cipher arguments */ - qcrypto_cipher_args_t cargs = { - .action = QCRYPTO_CIPHER_ENCRYPT, - .iv = NULL, - .ivsize = 0, - }; - - LOG("%s: In Function :", __func__); - /* Initialize the Qcrypto Library */ - ret = qcrypto_init(QCRYPTO_INIT_LAZY, NULL); - if (ret != QCRYPTO_R_EOK) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "qcryto_init() failed\n", ret); - goto qcrypto_cleanup; - } - - /* Request symmetric keygen */ - ret = qcrypto_keygen_request("symmetric", NULL, 0, &qkeyctx); - if (ret != QCRYPTO_R_EOK) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "qcrypto_keygen_request() failed \n", ret); - goto qcrypto_cleanup; - } - - /* Request aes-128-ecb */ - ret = qcrypto_cipher_request("aes-128-ecb", NULL, 0, &qctx); - if (ret != QCRYPTO_R_EOK) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "qcrypto_cipher_request() failed \n", ret); - goto qcrypto_cleanup; - } - - /* Load key */ - ret = qcrypto_key_from_mem(qkeyctx, &qkey, sc->sak, OSI_KEY_LEN_128); - if (ret != QCRYPTO_R_EOK) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "qcrypto_key_from_mem() failed \n", ret); - goto qcrypto_cleanup; - } - - /* Initialize cipher encryption */ - ret = qcrypto_cipher_init(qctx, qkey, &cargs); - if (ret != QCRYPTO_R_EOK) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "qcrypto_cipher_init() failed \n", ret); - goto qcrypto_cleanup; - } - - /* Cipher encryption */ - ret = qcrypto_cipher_encrypt(qctx, zeros, OSI_KEY_LEN_128, hkey, &out_len); - if (ret != QCRYPTO_R_EOK) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "qcrypto_cipher_encrypt() failed \n", ret); - goto qcrypto_cleanup; - } - LOG(" %s: Generated H key: "HKEYSTR, __func__, HKEY2STR(hkey)); - /* Finalize cipher encryption */ - ret = qcrypto_cipher_final(qctx, hkey, &out_len); - if (ret != QCRYPTO_R_EOK) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "qcrypto_cipher_final() failed \n", ret); - goto qcrypto_cleanup; - } - -qcrypto_cleanup: - /* Release all context handles */ - qcrypto_release_ctx(qctx); - qcrypto_release_ctx(qkeyctx); - /* Release the key handle */ - qcrypto_release_key(qkey); - /* Uninitialize the Qcrypto Library */ - qcrypto_uninit(); - -#elif defined(MACSEC_KEY_PROGRAM) && defined(LINUX_OS) - /* HKEY GENERATION */ - struct crypto_cipher *tfm; - - tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); - if (crypto_cipher_setkey(tfm, sc->sak, OSI_KEY_LEN_128)) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Failed to set key for H generation\n", 0ULL); - return -1; - } - crypto_cipher_encrypt_one(tfm, hkey, zeros); - LOG(" %s: Generated H key: "HKEYSTR, __func__, HKEY2STR(hkey)); - crypto_free_cipher(tfm); -#endif /* MACSEC_KEY_PROGRAM && QNX_OS*/ - /* Store key table index returned to osd */ *kt_idx = (sc->sc_idx_start * OSI_MAX_NUM_SA) + sc->curr_an; #ifdef MACSEC_KEY_PROGRAM /* 1. 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; - kt_config.flags |= OSI_LUT_FLAGS_ENTRY_VALID; + 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; /* Program in reverse order as per HW design */ - for (i = 0; i < OSI_KEY_LEN_128; i++) { - kt_config.entry.sak[i] = sc->sak[OSI_KEY_LEN_128 - 1 - i]; - kt_config.entry.h[i] = hkey[OSI_KEY_LEN_128 - 1 - i]; - } + for (i = 0; i < OSI_KEY_LEN_128; i++) { + kt_config.entry.sak[i] = sc->sak[OSI_KEY_LEN_128 - 1 - i]; + kt_config.entry.h[i] = sc->hkey[OSI_KEY_LEN_128 - 1 - i]; + } - 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", ret); - return -1; + 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", ret); + return -1; + } } #endif /* MACSEC_KEY_PROGRAM */ @@ -3078,6 +2977,9 @@ static nve32_t macsec_config(struct osi_core_priv_data *const osi_core, new_sc = &lut_status->sc_info[lut_status->next_sc_idx]; osi_memcpy(new_sc->sci, sc->sci, OSI_SCI_LEN); osi_memcpy(new_sc->sak, sc->sak, OSI_KEY_LEN_128); +#ifdef MACSEC_KEY_PROGRAM + osi_memcpy(new_sc->hkey, sc->hkey, OSI_KEY_LEN_128); +#endif /* MACSEC_KEY_PROGRAM */ new_sc->curr_an = sc->curr_an; new_sc->next_pn = sc->next_pn; new_sc->pn_window = sc->pn_window; @@ -3086,20 +2988,6 @@ static nve32_t macsec_config(struct osi_core_priv_data *const osi_core, new_sc->sc_idx_start = lut_status->next_sc_idx; new_sc->an_valid |= OSI_BIT(sc->curr_an); - LOG("%s: Adding new SC\n" - "\tsci: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n" - "\tan: %u\n" - "\tpn: %u" - "\tsc_idx_start: %u" - "\tan_valid: %#x \tpn_window: %#x\n", __func__, - new_sc->sci[0], new_sc->sci[1], new_sc->sci[2], - new_sc->sci[3], new_sc->sci[4], new_sc->sci[5], - new_sc->sci[6], new_sc->sci[7], - new_sc->curr_an, new_sc->next_pn, - new_sc->sc_idx_start, - new_sc->an_valid, new_sc->pn_window); - LOG("key: "KEYSTR, KEY2STR(new_sc->sak)); - if (add_upd_sc(osi_core, new_sc, ctlr, kt_idx) != OSI_NONE) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, @@ -3140,6 +3028,9 @@ static nve32_t macsec_config(struct osi_core_priv_data *const osi_core, */ *tmp_sc_p = *existing_sc; osi_memcpy(tmp_sc_p->sak, sc->sak, OSI_KEY_LEN_128); +#ifdef MACSEC_KEY_PROGRAM + osi_memcpy(tmp_sc_p->hkey, sc->hkey, OSI_KEY_LEN_128); +#endif /* MACSEC_KEY_PROGRAM */ tmp_sc_p->curr_an = sc->curr_an; tmp_sc_p->next_pn = sc->next_pn; tmp_sc_p->pn_window = sc->pn_window; diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index acc6529..ebc58fe 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -5725,6 +5725,48 @@ static nveu32_t mgbe_write_reg(struct osi_core_priv_data *const osi_core, 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. * @@ -5961,6 +6003,8 @@ void mgbe_init_core_ops(struct core_ops *ops) 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 */ }; diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index a6071e2..9eeab35 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -2009,7 +2009,16 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, ret = ops_p->write_reg(osi_core, (nve32_t) data->arg1_u32, (nve32_t) data->arg2_u32); break; +#ifdef MACSEC_SUPPORT + case OSI_CMD_READ_MACSEC_REG: + ret = ops_p->read_macsec_reg(osi_core, (nve32_t) data->arg1_u32); + break; + case OSI_CMD_WRITE_MACSEC_REG: + ret = ops_p->write_macsec_reg(osi_core, (nve32_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; From 55dc6ca49191a753ef211a763ca1843b290c105e Mon Sep 17 00:00:00 2001 From: Gaurav Asati <gasati@nvidia.com> Date: Thu, 20 Jan 2022 11:07:43 +0530 Subject: [PATCH 319/458] osi: Add Async-sync details to API header Issue: Async-sync details to API header is needed. Fix: Add Async-sync details to API header and remove duplicate Thread details. Bug 3350640 Change-Id: I0838e53951389c9fa408323324cedba0268f4706 Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2572939 Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com> Signed-off-by: Gaurav Asati <gasati@nvidia.com> (cherry picked from commit 8acef05c924ed72e256e792a8cd623a221494287) Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2657054 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_core.h | 90 ++++++++++++++++++++++++++++++---------------- include/osi_dma.h | 68 +++++++++++++++++++++++------------ 2 files changed, 105 insertions(+), 53 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 4473934..26cd610 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -1345,9 +1345,10 @@ struct osi_core_priv_data { * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -1387,9 +1388,10 @@ nve32_t osi_poll_for_mac_reset_complete( * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -1421,9 +1423,10 @@ nve32_t osi_hw_core_init(struct osi_core_priv_data *const osi_core, * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -1455,9 +1458,10 @@ nve32_t osi_hw_core_deinit(struct osi_core_priv_data *const osi_core); * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -1488,9 +1492,10 @@ nve32_t osi_start_mac(struct osi_core_priv_data *const osi_core); * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -1522,9 +1527,10 @@ nve32_t osi_stop_mac(struct osi_core_priv_data *const osi_core); * * @note * Classification: - * - Interrupt: Yes + * - Interrupt handler: Yes * - Signal handler: Yes * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -1556,9 +1562,10 @@ nve32_t osi_common_isr(struct osi_core_priv_data *const osi_core); * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -1592,9 +1599,10 @@ nve32_t osi_set_mode(struct osi_core_priv_data *const osi_core, * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -1628,9 +1636,10 @@ nve32_t osi_set_speed(struct osi_core_priv_data *const osi_core, * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -1664,9 +1673,10 @@ nve32_t osi_pad_calibrate(struct osi_core_priv_data *const osi_core); * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -1699,9 +1709,10 @@ nve32_t osi_config_fw_err_pkts(struct osi_core_priv_data *const osi_core, * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -1737,9 +1748,10 @@ nve32_t osi_config_rxcsum_offload(struct osi_core_priv_data *const osi_core, * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -1781,9 +1793,10 @@ nve32_t osi_l2_filter(struct osi_core_priv_data *const osi_core, * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -1820,9 +1833,10 @@ nve32_t osi_write_phy_reg(struct osi_core_priv_data *const osi_core, * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -1862,9 +1876,10 @@ nve32_t osi_read_mmc(struct osi_core_priv_data *const osi_core); * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -1894,9 +1909,10 @@ nve32_t osi_read_phy_reg(struct osi_core_priv_data *const osi_core, * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -1927,9 +1943,10 @@ nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core); * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -1964,9 +1981,10 @@ nve32_t osi_set_systime_to_mac(struct osi_core_priv_data *const osi_core, * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -2001,9 +2019,10 @@ nve32_t osi_adjust_freq(struct osi_core_priv_data *const osi_core, nve32_t ppb); * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -2047,9 +2066,10 @@ nve32_t osi_adjust_time(struct osi_core_priv_data *const osi_core, * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -2105,9 +2125,10 @@ void *eqos_get_core_safety_config(void); * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -2144,9 +2165,10 @@ nve32_t osi_l3l4_filter(struct osi_core_priv_data *const osi_core, * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -2175,9 +2197,10 @@ nve32_t osi_get_mac_version(struct osi_core_priv_data *const osi_core, * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -2344,9 +2367,10 @@ nve32_t osi_get_hw_features(struct osi_core_priv_data *const osi_core, * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -2376,9 +2400,10 @@ nve32_t osi_handle_ioctl(struct osi_core_priv_data *osi_core, * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -2544,9 +2569,10 @@ struct osi_core_priv_data *osi_get_core(void); * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -2585,9 +2611,10 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -2619,9 +2646,10 @@ nve32_t osi_hal_hw_core_init(struct osi_core_priv_data *const osi_core, * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -2663,9 +2691,10 @@ nve32_t osi_hal_hw_core_deinit(struct osi_core_priv_data *const osi_core); * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -2708,9 +2737,10 @@ nve32_t osi_hal_write_phy_reg(struct osi_core_priv_data *const osi_core, * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note diff --git a/include/osi_dma.h b/include/osi_dma.h index 5941c66..312187a 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2021, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -616,9 +616,10 @@ struct osi_dma_priv_data { * * @note * Classification: - * - Interrupt: Yes + * - Interrupt handler: Yes * - Signal handler: Yes * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -655,9 +656,10 @@ nve32_t osi_disable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, * * @note * Classification: - * - Interrupt: Yes + * - Interrupt handler: Yes * - Signal handler: Yes * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -694,9 +696,10 @@ nve32_t osi_enable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, * * @note * Classification: - * - Interrupt: Yes + * - Interrupt handler: Yes * - Signal handler: Yes * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -733,9 +736,10 @@ nve32_t osi_disable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, * * @note * Classification: - * - Interrupt: Yes + * - Interrupt handler: Yes * - Signal handler: Yes * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -823,9 +827,10 @@ nve32_t osi_clear_vm_rx_intr(struct osi_dma_priv_data *osi_dma, * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -859,9 +864,10 @@ nve32_t osi_start_dma(struct osi_dma_priv_data *osi_dma, nveu32_t chan); * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -891,9 +897,10 @@ nve32_t osi_stop_dma(struct osi_dma_priv_data *osi_dma, nveu32_t chan); * * @note * Classification: - * - Interrupt: Yes + * - Interrupt handler: Yes * - Signal handler: Yes * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -928,9 +935,10 @@ nveu32_t osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring); * * @note * Classification: - * - Interrupt: Yes + * - Interrupt handler: Yes * - Signal handler: Yes * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -961,9 +969,10 @@ nve32_t osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -1011,9 +1020,10 @@ nve32_t osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma); * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -1054,9 +1064,10 @@ nve32_t osi_hw_transmit(struct osi_dma_priv_data *osi_dma, nveu32_t chan); * * @note * Classification: - * - Interrupt: Yes + * - Interrupt handler: Yes * - Signal handler: Yes * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -1102,9 +1113,10 @@ nve32_t osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, * * @note * Classification: - * - Interrupt: Yes + * - Interrupt handler: Yes * - Signal handler: Yes * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -1158,9 +1170,10 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -1193,9 +1206,10 @@ nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma); * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -1220,9 +1234,10 @@ nve32_t osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma); * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -1256,9 +1271,10 @@ nve32_t osi_init_dma_ops(struct osi_dma_priv_data *osi_dma); * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -1290,9 +1306,10 @@ nve32_t osi_dma_get_systime_from_mac(struct osi_dma_priv_data *const osi_dma, * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -1333,9 +1350,10 @@ nveu32_t osi_is_mac_enabled(struct osi_dma_priv_data *const osi_dma); * * @note * Classification: - * - Interrupt: Yes + * - Interrupt handler: Yes * - Signal handler: Yes * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -1391,9 +1409,10 @@ nve32_t osi_dma_ioctl(struct osi_dma_priv_data *osi_dma); * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -1426,9 +1445,10 @@ nve32_t osi_validate_dma_regs(struct osi_dma_priv_data *osi_dma); * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -1459,9 +1479,10 @@ nve32_t osi_clear_tx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note @@ -1543,9 +1564,10 @@ nve32_t osi_txring_empty(struct osi_dma_priv_data *osi_dma, nveu32_t chan); * * @note * Classification: - * - Interrupt: No + * - Interrupt handler: No * - Signal handler: No * - Thread safe: No + * - Async/Sync: Sync * - Required Privileges: None * * @note From c39b30578941ac5ce3737afa5c2e13f453884393 Mon Sep 17 00:00:00 2001 From: Gaurav Asati <gasati@nvidia.com> Date: Thu, 20 Jan 2022 11:28:16 +0530 Subject: [PATCH 320/458] osi: update API headers Use @usage instead of @note and group all classification and API group details under @usage. Bug 3350640 Change-Id: If77cfd76519f17427b95a2300ad722dc6f83f518 Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com> Signed-off-by: Gaurav Asati <gasati@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2587106 (cherry picked from commit 0002e2d0b2cf85811b09e8c7157dbd777c8fc117) Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2657079 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_core.h | 721 +++++++++++++++++++++------------------------ include/osi_dma.h | 540 +++++++++++++++------------------ 2 files changed, 576 insertions(+), 685 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 26cd610..5c53119 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -1343,19 +1343,17 @@ struct osi_core_priv_data { * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETRM_004 * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No + * @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. @@ -1386,19 +1384,17 @@ nve32_t osi_poll_for_mac_reset_complete( * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETRM_006 * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No + * @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. @@ -1421,19 +1417,17 @@ nve32_t osi_hw_core_init(struct osi_core_priv_data *const osi_core, * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETRM_007 * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: No - * - Run time: No - * - De-initialization: Yes + * @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. @@ -1456,19 +1450,17 @@ nve32_t osi_hw_core_deinit(struct osi_core_priv_data *const osi_core); * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETRM_008 * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No + * @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. @@ -1490,19 +1482,17 @@ nve32_t osi_start_mac(struct osi_core_priv_data *const osi_core); * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETRM_009 * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: No - * - Run time: No - * - De-initialization: Yes + * @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. @@ -1525,19 +1515,17 @@ nve32_t osi_stop_mac(struct osi_core_priv_data *const osi_core); * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETRM_010 * - * @note - * Classification: - * - Interrupt handler: Yes - * - Signal handler: Yes - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No + * @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. @@ -1560,19 +1548,17 @@ nve32_t osi_common_isr(struct osi_core_priv_data *const osi_core); * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETRM_011 * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No + * @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. @@ -1597,19 +1583,17 @@ nve32_t osi_set_mode(struct osi_core_priv_data *const osi_core, * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETRM_012 * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No + * @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. @@ -1634,19 +1618,17 @@ nve32_t osi_set_speed(struct osi_core_priv_data *const osi_core, * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETRM_013 * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No + * @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 @@ -1671,19 +1653,17 @@ nve32_t osi_pad_calibrate(struct osi_core_priv_data *const osi_core); * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETRM_020 * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No + * @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. @@ -1707,19 +1687,17 @@ nve32_t osi_config_fw_err_pkts(struct osi_core_priv_data *const osi_core, * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETRM_017 * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No + * @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. @@ -1746,19 +1724,17 @@ nve32_t osi_config_rxcsum_offload(struct osi_core_priv_data *const osi_core, * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETRM_018 * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No + * @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. @@ -1791,19 +1767,17 @@ nve32_t osi_l2_filter(struct osi_core_priv_data *const osi_core, * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETRM_002 * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No + * @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. @@ -1831,19 +1805,17 @@ nve32_t osi_write_phy_reg(struct osi_core_priv_data *const osi_core, * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETRM_014 * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No + * @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. @@ -1874,19 +1846,17 @@ nve32_t osi_read_mmc(struct osi_core_priv_data *const osi_core); * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETRM_003 * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No + * @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 @@ -1907,19 +1877,17 @@ nve32_t osi_read_phy_reg(struct osi_core_priv_data *const osi_core, * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETRM_001 * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No + * @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); @@ -1941,19 +1909,17 @@ nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core); * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETRM_005 * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No + * @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. @@ -1979,19 +1945,17 @@ nve32_t osi_set_systime_to_mac(struct osi_core_priv_data *const osi_core, * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETRM_023 * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No + * @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. @@ -2017,19 +1981,17 @@ nve32_t osi_adjust_freq(struct osi_core_priv_data *const osi_core, nve32_t ppb); * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETRM_022 * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No + * @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. @@ -2064,19 +2026,17 @@ nve32_t osi_adjust_time(struct osi_core_priv_data *const osi_core, * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETRM_021 * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No + * @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. @@ -2123,19 +2083,17 @@ void *eqos_get_core_safety_config(void); * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETRM_019 * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No + * @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. @@ -2163,19 +2121,17 @@ nve32_t osi_l3l4_filter(struct osi_core_priv_data *const osi_core, * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETRM_015 * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No + * @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. @@ -2195,19 +2151,17 @@ nve32_t osi_get_mac_version(struct osi_core_priv_data *const osi_core, * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETRM_016 * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No + * @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. @@ -2365,19 +2319,17 @@ nve32_t osi_get_hw_features(struct osi_core_priv_data *const osi_core, * @note * Traceability Details: * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No + * @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. @@ -2398,19 +2350,17 @@ nve32_t osi_handle_ioctl(struct osi_core_priv_data *osi_core, * @note * Traceability Details: * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No + * @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. @@ -2567,19 +2517,17 @@ struct osi_core_priv_data *osi_get_core(void); * @note * Traceability Details: * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No + * @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. @@ -2609,19 +2557,17 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETRM_006 * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No + * @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. @@ -2644,19 +2590,17 @@ nve32_t osi_hal_hw_core_init(struct osi_core_priv_data *const osi_core, * Traceability Details: * - SWUD_ID: TODO * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: No - * - Run time: No - * - De-initialization: Yes + * @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. @@ -2689,19 +2633,17 @@ nve32_t osi_hal_hw_core_deinit(struct osi_core_priv_data *const osi_core); * Traceability Details: * - SWUD_ID: TODO * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No + * @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. @@ -2735,19 +2677,17 @@ nve32_t osi_hal_write_phy_reg(struct osi_core_priv_data *const osi_core, * Traceability Details: * - SWUD_ID: TODO * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No + * @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 @@ -2755,3 +2695,4 @@ nve32_t osi_hal_write_phy_reg(struct osi_core_priv_data *const osi_core, 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 index 312187a..4a21457 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -614,19 +614,17 @@ struct osi_dma_priv_data { * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETCL_001 * - * @note - * Classification: - * - Interrupt handler: Yes - * - Signal handler: Yes - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: Yes + * @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. @@ -654,19 +652,17 @@ nve32_t osi_disable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETCL_002 * - * @note - * Classification: - * - Interrupt handler: Yes - * - Signal handler: Yes - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No + * @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. @@ -694,19 +690,17 @@ nve32_t osi_enable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETCL_003 * - * @note - * Classification: - * - Interrupt handler: Yes - * - Signal handler: Yes - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: Yes + * @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. @@ -734,19 +728,17 @@ nve32_t osi_disable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETCL_004 * - * @note - * Classification: - * - Interrupt handler: Yes - * - Signal handler: Yes - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No + * @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. @@ -825,19 +817,17 @@ nve32_t osi_clear_vm_rx_intr(struct osi_dma_priv_data *osi_dma, * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETCL_005 * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No + * @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. @@ -862,19 +852,17 @@ nve32_t osi_start_dma(struct osi_dma_priv_data *osi_dma, nveu32_t chan); * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETCL_006 * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: No - * - Run time: No - * - De-initialization: Yes + * @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. @@ -895,19 +883,17 @@ nve32_t osi_stop_dma(struct osi_dma_priv_data *osi_dma, nveu32_t chan); * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETCL_007 * - * @note - * Classification: - * - Interrupt handler: Yes - * - Signal handler: Yes - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No + * @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." */ @@ -933,19 +919,17 @@ nveu32_t osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring); * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETCL_008 * - * @note - * Classification: - * - Interrupt handler: Yes - * - Signal handler: Yes - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No + * @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. @@ -967,19 +951,17 @@ nve32_t osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETCL_009 * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No + * @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. @@ -1018,19 +1000,17 @@ nve32_t osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma); * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETCL_010 * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No + * @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. @@ -1062,19 +1042,17 @@ nve32_t osi_hw_transmit(struct osi_dma_priv_data *osi_dma, nveu32_t chan); * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETCL_011 * - * @note - * Classification: - * - Interrupt handler: Yes - * - Signal handler: Yes - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No + * @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. */ @@ -1111,19 +1089,17 @@ nve32_t osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETCL_012 * - * @note - * Classification: - * - Interrupt handler: Yes - * - Signal handler: Yes - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No + * @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. */ @@ -1168,19 +1144,17 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETCL_013 * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No + * @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. @@ -1204,19 +1178,17 @@ nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma); * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETCL_014 * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: No - * - Run time: No - * - De-initialization: Yes + * @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. @@ -1232,19 +1204,17 @@ nve32_t osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma); * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETCL_015 * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No + * @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 @@ -1269,19 +1239,17 @@ nve32_t osi_init_dma_ops(struct osi_dma_priv_data *osi_dma); * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETCL_016 * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No + * @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. @@ -1304,19 +1272,17 @@ nve32_t osi_dma_get_systime_from_mac(struct osi_dma_priv_data *const osi_dma, * Traceability Details: * - SWUD_ID: ETHERNET_NVETHERNETCL_017 * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No + * @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. @@ -1348,19 +1314,17 @@ nveu32_t osi_is_mac_enabled(struct osi_dma_priv_data *const osi_dma); * @note * Traceability Details: TBD * - * @note - * Classification: - * - Interrupt handler: Yes - * - Signal handler: Yes - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No + * @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. @@ -1375,9 +1339,7 @@ nve32_t osi_handle_dma_intr(struct osi_dma_priv_data *osi_dma, * * @note * Traceability Details: TBD - * - * @note - * API Group: + * - API Group: * - Initialization: Yes * - Run time: Yes * - De-initialization: No @@ -1407,19 +1369,17 @@ nve32_t osi_dma_ioctl(struct osi_dma_priv_data *osi_dma); * @note * Traceability Details: * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No + * @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. @@ -1443,19 +1403,17 @@ nve32_t osi_validate_dma_regs(struct osi_dma_priv_data *osi_dma); * @note * Traceability Details: * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No + * @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. @@ -1477,19 +1435,17 @@ nve32_t osi_clear_tx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); * @note * Traceability Details: * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No + * @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. @@ -1510,9 +1466,7 @@ nve32_t osi_config_slot_function(struct osi_dma_priv_data *osi_dma, * @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: + * - API Group: * - Initialization: No * - Run time: Yes * - De-initialization: No @@ -1536,9 +1490,7 @@ nve32_t osi_clear_rx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); * @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: + * - API Group: * - Initialization: No * - Run time: Yes * - De-initialization: No @@ -1562,19 +1514,17 @@ nve32_t osi_txring_empty(struct osi_dma_priv_data *osi_dma, nveu32_t chan); * @note * Traceability Details: * - * @note - * Classification: - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No + * @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. From 4173451f481ae87e6e2262aa8de72bfb63362d2e Mon Sep 17 00:00:00 2001 From: Gaurav Asati <gasati@nvidia.com> Date: Thu, 20 Jan 2022 21:18:02 +0530 Subject: [PATCH 321/458] core: eqos: update structure and function documentation Update eqos_core.c function definitions to address new SWUD guidelines. JIRA T23XMGBE-839 Change-Id: I8f4953c2756c9a550739b6c9f049669dbaa7cf89 Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com> Signed-off-by: Gaurav Asati <gasati@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2604786 (cherry picked from commit 47043b9343640807c2f66beb8026b6a1f81bc42d) Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2657436 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/eqos_core.c | 363 ++++++++++++++++++++++++++++--------------- osi/core/eqos_mmc.c | 5 +- 2 files changed, 244 insertions(+), 124 deletions(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index c70e1a5..900050b 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -399,8 +399,15 @@ static void eqos_core_backup_init(struct osi_core_priv_data *const osi_core) /** * @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 + * @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() * @@ -479,14 +486,14 @@ static nve32_t eqos_config_flow_control( * * @note * Algorithm: - * - When this bit is reset, the Rx queue drops packets with - * error status (CRC error, GMII_ER, watchdog timeout, or overflow). - * When this bit is set, all packets except the runt error packets - * are forwarded to the application or DMA. + * - Validate fw_err and return -1 if fails. + * - Enable or disable forward error packet confiration based on fw_err. + * - Refer to EQOS column of <<RM_20, (sequence diagram)>> for API details. + * - TraceID: ETHERNET_NVETHERNETRM_020 * - * @param[in] osi_core: OSI core private data structure. - * @param[in] qinx: Queue index - * @param[in] fw_err: Enable or Disable the forwarding of error packets + * @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() * @@ -549,10 +556,12 @@ static nve32_t eqos_config_fw_err_pkts( * * @note * Algorithm: - * - CAR reset will be issued through MAC reset pin. - * Waits for SWR reset to be cleared in DMA Mode register. + * - 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 <<RM_04, (sequence diagram)>> for API details. + * - TraceID: ETHERNET_NVETHERNETRM_004 * - * @param[in] osi_core: OSI core private data structure. + * @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. * @@ -562,8 +571,8 @@ static nve32_t eqos_config_fw_err_pkts( * - Run time: No * - De-initialization: No * - * @retval 0 on success - * @retval -1 on failure. + * @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) { @@ -612,9 +621,12 @@ static nve32_t eqos_poll_for_swr(struct osi_core_priv_data *const osi_core) * 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 <<RM_12, (sequence diagram)>> for API details. + * - TraceID: ETHERNET_NVETHERNETRM_012 * - * @param[in] osi_core: OSI core private data structure. - * @param[in] speed: Operating speed. + * @param[in] base: EQOS virtual base address. + * @param[in] speed: Operating speed. Valid values are OSI_SPEED_* * * @note * API Group: @@ -663,9 +675,12 @@ static int eqos_set_speed(struct osi_core_priv_data *const osi_core, * 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 <<RM_11, (sequence diagram)>> for API details. + * - TraceID: ETHERNET_NVETHERNETRM_011 * - * @param[in] osi_core: OSI core private data structure. - * @param[in] mode: Operating mode. + * @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() * @@ -710,9 +725,13 @@ static nve32_t eqos_set_mode(struct osi_core_priv_data *const osi_core, * * @note * Algorithm: - * - Total Tx/Rx FIFO size which is read from - * MAC HW is being shared equally among the queues that are - * configured. + * - 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. @@ -817,22 +836,23 @@ static nveu32_t eqos_calculate_per_queue_fifo(nveu32_t mac_ver, #ifdef UPDATED_PAD_CAL /** - * @brief eqos_pad_calibrate - PAD calibration + * @brief eqos_pad_calibrate - performs PAD calibration * * @note * Algorithm: - * - Call pre pad calibration function to make RGMII interface idle * - 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 + * - 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 - * - Call post pad calibration function to restore pre pad calibration - * settings + * - return 0 if wait for AUTO_CAL_ACTIVE is success else -1. + * - Refer to EQOS column of <<RM_13, (sequence diagram)>> for API details. + * - TraceID:ETHERNET_NVETHERNETRM_013 * - * @param[in] osi_core: OSI core private data structure. + * @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. @@ -1009,8 +1029,17 @@ calibration_failed: /** * @brief eqos_flush_mtl_tx_queue - Flush MTL Tx queue * - * @param[in] osi_core: OSI core private data structure. - * @param[in] qinx: MTL queue index. + * @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. @@ -1079,7 +1108,14 @@ static nve32_t eqos_flush_mtl_tx_queue( * 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 + * 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: @@ -1174,6 +1210,7 @@ void update_ehfc_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value) } } +/** \cond DO_NOT_DOCUMENT */ /** * @brief eqos_configure_mtl_queue - Configure MTL Queue * @@ -1259,18 +1296,23 @@ static nve32_t eqos_configure_mtl_queue(nveu32_t qinx, 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 the IP checksum offload engine COE in MAC receiver. + * - Enable/disable the IP checksum offload engine COE in MAC receiver based on enabled. * - Update the MAC configuration register. + * - Refer to OSI column of <<RM_17, (sequence diagram)>> for sequence + * of execution. + * - TraceID:ETHERNET_NVETHERNETRM_017 * - * @param[in] osi_core: OSI core private data structure. - * @param[in] enabled: Flag to indicate feature is to be enabled/disabled. + * @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() * @@ -1590,6 +1632,7 @@ static int eqos_update_frp_entry(struct osi_core_priv_data *const osi_core, return ret; } +/** \cond DO_NOT_DOCUMENT */ /** * @brief eqos_configure_rxq_priority - Configure Priorities Selected in * the Receive Queue @@ -1871,6 +1914,7 @@ static void eqos_configure_dma(struct osi_core_priv_data *const osi_core) 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 @@ -2097,10 +2141,14 @@ static void eqos_dma_chan_to_vmirq_map(struct osi_core_priv_data *osi_core) * Algorithm: * - This function will take care of initializing MAC, MTL and * common DMA registers. + * - Refer to OSI column of <<RM_06, (sequence diagram)>> for sequence + * of execution. + * - TraceID:ETHERNET_NVETHERNETRM_006 * - * @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 + * @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() @@ -2301,9 +2349,16 @@ static void eqos_handle_mac_fpe_intrs(struct osi_core_priv_data *osi_core) * @note * Algorithm: * - This function takes care of handling the - * MAC interrupts which includes speed, mode detection. + * 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. + * @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 @@ -2395,6 +2450,7 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, (unsigned char *)osi_core->base + EQOS_MAC_ISR); } +/** \cond DO_NOT_DOCUMENT */ /** * @brief update_dma_sr_stats - stats for dma_status error * @@ -2449,6 +2505,7 @@ static inline void update_dma_sr_stats( osi_update_stats_counter(val, 1U); } } +/** \endcond */ /** * @brief eqos_handle_mtl_intrs - Handle MTL interrupts @@ -2591,7 +2648,13 @@ static void eqos_handle_mtl_intrs(struct osi_core_priv_data *osi_core) * * @note * Algorithm: - * - Clear common interrupt source. + * - 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 <<RM_10, (sequence diagram)>> for API details. + * - TraceID:ETHERNET_NVETHERNETRM_010 * * @param[in] osi_core: OSI core private data structure. * @@ -2691,7 +2754,9 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *const osi_core) * * @note * Algorithm: - * - Enable MAC Transmitter and Receiver + * - Enable MAC Transmitter and Receiver in EQOS_MAC_MCR_IDX + * - Refer to EQOS column of <<RM_08, (sequence diagram)>> for API details. + * - TraceID:ETHERNET_NVETHERNETRM_008 * * @param[in] osi_core: OSI core private data structure. * @@ -2724,7 +2789,9 @@ static void eqos_start_mac(struct osi_core_priv_data *const osi_core) * * @note * Algorithm: - * - Disables MAC Transmitter and Receiver + * - Disable MAC Transmitter and Receiver in EQOS_MAC_MCR_IDX + * - Refer to EQOS column of <<RM_07, (sequence diagram)>> for API details. + * - TraceID:ETHERNET_NVETHERNETRM_007 * * @param[in] osi_core: OSI core private data structure. * @@ -2800,11 +2867,12 @@ static void eqos_config_mac_tx(struct osi_core_priv_data *const osi_core, * * @note * Algorithm: - * - This sequence is used to select perfect/inverse matching - * for L2 DA + * - use perfect_inverse_match filed to set perfect/inverse matching for L2 DA. + * - Refer to EQOS column of <<RM_18, (sequence diagram)>> for API details. + * - TraceID:ETHERNET_NVETHERNETRM_018 * - * @param[in] osi_core: OSI core private data structure. - * @param[in] perfect_inverse_match: 1 - inverse mode 0- perfect mode + * @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() * @@ -2839,13 +2907,14 @@ static inline nve32_t eqos_config_l2_da_perfect_inverse_match( * @brief eqos_config_mac_pkt_filter_reg - configure mac filter register. * * @note - * Algorithm: * - This sequence is used to configure MAC in different pkt * processing modes like promiscuous, multicast, unicast, - * hash unicast/multicast. + * hash unicast/multicast based on input filter arguments. + * - Refer to EQOS column of <<RM_18, (sequence diagram)>> for API details. + * - TraceID:ETHERNET_NVETHERNETRM_018 * - * @param[in] osi_core: OSI core private data structure. - * @param[in] filter: OSI filter structure. + * @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() * @@ -2913,25 +2982,25 @@ static nve32_t eqos_config_mac_pkt_filter_reg( } /** - * @brief eqos_update_mac_addr_helper - Function to update DCS and MBC + * @brief eqos_update_mac_addr_helper - Function to update DCS and MBC; helper function for + * eqos_update_mac_addr_low_high_reg() * * @note * Algorithm: - * - This helper routine is to update passed parameter value - * based on DCS and MBC parameter. Validation of dsc_en status performed - * before updating DCS bits. + * - 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 <<RM_18, (sequence diagram)>> for API details. + * - TraceID:ETHERNET_NVETHERNETRM_018 * - * @param[in] osi_core: OSI core private data structure. + * @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: filter index - * @param[in] dma_chan: dma channel number - * @param[in] addr_mask: 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] - * @pram[in] src_dest: Source/Destination Address match + * @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() @@ -3065,10 +3134,12 @@ static void eqos_l2_filter_delete(struct osi_core_priv_data *osi_core, * * @note * 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. + * - 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 <<RM_18, (sequence diagram)>> for API details. + * - TraceID:ETHERNET_NVETHERNETRM_018 * * @param[in] osi_core: OSI core private data structure. * @param[in] filter: OSI filter structure. @@ -3259,7 +3330,8 @@ static int eqos_config_ptp_offload(struct osi_core_priv_data *osi_core, * * @note * Algorithm: - * - This routine to enable/disable L4/l4 filter + * - 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 @@ -3296,13 +3368,15 @@ static nve32_t eqos_config_l3_l4_filter_enable( * * @note * Algorithm: - * - This sequence is used to update IPv4 source/destination - * Address for L3 layer filtering + * - 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 <<RM_19, (sequence diagram)>> for API details. + * - TraceID:ETHERNET_NVETHERNETRM_019 * - * @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 + * @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() * @@ -3360,12 +3434,14 @@ static nve32_t eqos_update_ip4_addr(struct osi_core_priv_data *const osi_core, * * @note * Algorithm: - * - This sequence is used to update IPv6 source/destination - * Address for L3 layer filtering + * - 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 <<RM_19, (sequence diagram)>> for API details. + * - TraceID:ETHERNET_NVETHERNETRM_019 * - * @param[in] osi_core: OSI core private data structure. - * @param[in] filter_no: filter index - * @param[in] addr: ipv6 address + * @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() * @@ -3432,13 +3508,15 @@ static nve32_t eqos_update_ip6_addr(struct osi_core_priv_data *const osi_core, * * @note * Algorithm: - * - sequence is used to update Source Port Number for - * L4(TCP/UDP) layer filtering. + * - 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 <<RM_19, (sequence diagram)>> for API details. + * - TraceID:ETHERNET_NVETHERNETRM_019 * - * @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 + * @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() @@ -3487,6 +3565,7 @@ static nve32_t eqos_update_l4_port_no( return 0; } +/** \cond DO_NOT_DOCUMENT */ /** * @brief eqos_set_dcs - check and update dma routing register * @@ -3573,25 +3652,27 @@ static inline void eqos_helper_l3l4_bitmask(nveu32_t *bitmask, *bitmask &= ~temp; } } +/** \endcond */ /** * @brief eqos_config_l3_filters - config L3 filters. * * @note * 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. + * - 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 <<RM_19, (sequence diagram)>> for API details. + * - TraceID:ETHERNET_NVETHERNETRM_019 * - * @param[in, out] 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 + * @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() @@ -3764,17 +3845,20 @@ static nve32_t eqos_config_l3_filters( * * @note * Algorithm: - * - This sequence is used to configure L4(TCP/UDP) filters for - * SA and DA Port Number matching + * - 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 <<RM_19, (sequence diagram)>> for API details. + * - TraceID:ETHERNET_NVETHERNETRM_019 * - * @param[in, out] 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, 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: 0 - source port, otherwise - dest port + * @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: filter based dma routing enable(1) - * @param[in] dma_chan: dma channel for routing based on filter + * @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() @@ -3889,10 +3973,11 @@ static nve32_t eqos_config_l4_filters( * * @note * Algorithm: - * - Read TSINIT value from MAC TCR register until it is - * equal to zero. + * - 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. + * @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 * @@ -3944,10 +4029,13 @@ static inline nve32_t eqos_poll_for_tsinit_complete( * * @note * Algorithm: - * - Updates system time (seconds and nano seconds) - * in hardware registers + * - 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 <<RM_05, (sequence diagram)>> for API details. + * - TraceID:ETHERNET_NVETHERNETRM_005 * - * @param[in] osi_core: OSI core private data structure. + * @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 * @@ -4004,10 +4092,11 @@ static nve32_t eqos_set_systime_to_mac( * * @note * Algorithm: - * - Read TSADDREG value from MAC TCR register until it is - * equal to zero. + * - 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. + * @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 * @@ -4059,8 +4148,12 @@ static inline nve32_t eqos_poll_for_addend_complete( * @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 <<RM_23, (sequence diagram)>> for API details. + * - TraceID:ETHERNET_NVETHERNETRM_023 * - * @param[in] osi_core: OSI core private data structure. + * @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() @@ -4112,8 +4205,10 @@ static nve32_t eqos_config_addend(struct osi_core_priv_data *const osi_core, * 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. + * @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 * @@ -4164,9 +4259,13 @@ static inline nve32_t eqos_poll_for_update_ts_complete( * * @note * Algorithm: - * - Update MAC time with system time + * - 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 <<RM_22, (sequence diagram)>> for API details. + * - TraceID:ETHERNET_NVETHERNETRM_022 * - * @param[in] osi_core: OSI core private data structure. + * @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 @@ -4258,6 +4357,7 @@ static nve32_t eqos_adjust_mactime(struct osi_core_priv_data *const osi_core, return 0; } +/** \cond DO_NOT_DOCUMENT */ /** * @brief eqos_config_tscr - Configure Time Stamp Register * @@ -4343,6 +4443,7 @@ static void eqos_config_tscr(struct osi_core_priv_data *const osi_core, } osi_writela(osi_core, value, (nveu8_t *)addr + EQOS_MAC_PPS_CTL); } +/** \endcond */ /** * @brief eqos_config_ptp_rxq - To config PTP RX packets queue @@ -4433,10 +4534,21 @@ static int eqos_config_ptp_rxq(struct osi_core_priv_data *osi_core, } /** - * @brief eqos_config_ssir - Configure SSIR + * @brief eqos_config_ssir - Configure SSIR register * - * @param[in] osi_core: OSI core private data structure. - * @param[in] ptp_clock: PTP required clock frequency + * @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 <<RM_21, (sequence diagram)>> 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() * @@ -4492,9 +4604,10 @@ static void eqos_config_ssir(struct osi_core_priv_data *const osi_core, * * @note * Algorithm: - * - This function will take care of deinitializing MAC + * - This function calls eqos_stop_mac() + * - TraceId:ETHERNET_NVETHERNETRM_007 * - * @param[in] osi_core: OSI core private data structure. + * @param[in] osi_core: OSI core private data structure. Used param is base. * * @pre Required clks and resets has to be enabled * @@ -4856,6 +4969,7 @@ static int eqos_hw_config_fpe(struct osi_core_priv_data *osi_core, return 0; } +/** \cond DO_NOT_DOCUMENT */ /** * @brief poll_for_mii_idle Query the status of an ongoing DMA transfer * @@ -4902,6 +5016,7 @@ static inline nve32_t poll_for_mii_idle(struct osi_core_priv_data *osi_core) return 0; } +/** \endcond */ /** * @brief eqos_write_phy_reg - Write to a PHY register through MAC over MDIO bus @@ -4916,6 +5031,8 @@ static inline nve32_t poll_for_mii_idle(struct osi_core_priv_data *osi_core) * in this operation. * - Write into MAC MDIO address register poll for GMII busy for MDIO * operation to complete. + * - Refer to EQOS column of <<RM_02, (sequence diagram)>> 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 @@ -5016,6 +5133,8 @@ static nve32_t eqos_write_phy_reg(struct osi_core_priv_data *const osi_core, * - 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 <<RM_03, (sequence diagram)>> 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 diff --git a/osi/core/eqos_mmc.c b/osi/core/eqos_mmc.c index 6b16d64..e0de057 100644 --- a/osi/core/eqos_mmc.c +++ b/osi/core/eqos_mmc.c @@ -107,8 +107,9 @@ void eqos_reset_mmc(struct osi_core_priv_data *const osi_core) * * @note * Algorithm: - * - Pass register offset and old value to helper function and - * update structure. + * - 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. * From 067b05e0abcf563254db878f5a22e2e204adebf4 Mon Sep 17 00:00:00 2001 From: Gaurav Asati <gasati@nvidia.com> Date: Mon, 24 Jan 2022 10:59:19 +0530 Subject: [PATCH 322/458] osi: dma: update tx and rx completion API's. - Add tx and rx completion API's with failure return value. JIRA T23XMGBE-443 Change-Id: Ib6aa3b559f1356e9285f8d4cc129abc049884342 Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com> Signed-off-by: Gaurav Asati <gasati@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2618556 (cherry picked from commit 6bd8b7fe13f258928bb81ebe22c30fe5b51688c0) Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2658600 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_dma.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/osi_dma.h b/include/osi_dma.h index 4a21457..c21221f 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -1054,7 +1054,7 @@ nve32_t osi_hw_transmit(struct osi_dma_priv_data *osi_dma, nveu32_t chan); * - Run time: Yes * - De-initialization: No * - * @returns Number of descriptors (buffers) processed. + * @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); @@ -1101,7 +1101,7 @@ nve32_t osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, * - Run time: Yes * - De-initialization: No * - * @returns Number of descriptors (buffers) processed. + * @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, From 500a09e304172b3bf4e29cd102f5add5ce3b9c08 Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Tue, 9 Nov 2021 17:58:03 +0530 Subject: [PATCH 323/458] nvethenetrm: core: SW WAR implementation for switching of Gates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issue: switching of Gates did not happen for intermediate cycles when CTR is less than GCL execution time Fix: SW WAR as per recommendation. 1) At the programming time make sure (CTR - total TI) should be 0 or more than 8PTP clock time. 2) Switching to New List check for following Old BTR + n(CTR) - New GCL list's BTR >= 8PTP or New GCL list's BTR – (Old BTR + n(CTR)) >= 8PTP Bug 200724911 Change-Id: I19127a134655a66bb66d025f964b85afc6c23c2e Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2622942 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_common.h | 5 +- osi/core/Makefile.sdk | 3 +- osi/core/Makefile.tmk | 1 + osi/core/core_common.c | 228 +++++++++++++++++++++++++++++++++++++++++ osi/core/core_common.h | 61 +++++++++++ osi/core/core_local.h | 2 + osi/core/eqos_core.c | 62 +++-------- osi/core/eqos_core.h | 3 +- osi/core/mgbe_core.c | 61 +++-------- osi/core/mgbe_core.h | 4 +- 10 files changed, 328 insertions(+), 102 deletions(-) create mode 100644 osi/core/core_common.c create mode 100644 osi/core/core_common.h diff --git a/include/osi_common.h b/include/osi_common.h index c7513dc..e833903 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2021, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -133,6 +133,9 @@ #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 diff --git a/osi/core/Makefile.sdk b/osi/core/Makefile.sdk index fc79ef8..5ee8e6d 100644 --- a/osi/core/Makefile.sdk +++ b/osi/core/Makefile.sdk @@ -1,4 +1,4 @@ -# Copyright (c) 2020-2021 NVIDIA CORPORATION. All Rights Reserved. +# Copyright (c) 2020-2022 NVIDIA CORPORATION. All Rights Reserved. # # NVIDIA CORPORATION and its licensors retain all intellectual property # and proprietary rights in and to this software, related documentation @@ -31,6 +31,7 @@ OBJS += ivc_core.o OBJS += ./../common/osi_common.o OBJS += ./../common/eqos_common.o OBJS += ./../common/mgbe_common.o +OBJS += core_common.o CFLAGS += -D_FILE_OFFSET_BITS=64 diff --git a/osi/core/Makefile.tmk b/osi/core/Makefile.tmk index b1a858f..9e003a9 100644 --- a/osi/core/Makefile.tmk +++ b/osi/core/Makefile.tmk @@ -41,6 +41,7 @@ NV_COMPONENT_SOURCES := \ 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 \ diff --git a/osi/core/core_common.c b/osi/core/core_common.c new file mode 100644 index 0000000..0d218a6 --- /dev/null +++ b/osi/core/core_common.c @@ -0,0 +1,228 @@ +/* + * 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 new file mode 100644 index 0000000..81b69a7 --- /dev/null +++ b/osi/core/core_common.h @@ -0,0 +1,61 @@ +/* + * 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 index 0858e5b..95f75df 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -366,6 +366,8 @@ struct core_local { nveu32_t m2m_tsync; /** control pps output signal */ nveu32_t pps_freq; + /** Time interval mask for GCL entry */ + nveu32_t ti_mask; }; /** diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 900050b..ec2cf0b 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -27,6 +27,7 @@ #include "eqos_mmc.h" #include "core_local.h" #include "vlan_filter.h" +#include "core_common.h" #ifdef UPDATED_PAD_CAL /* @@ -1981,6 +1982,8 @@ 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}; @@ -1993,6 +1996,7 @@ static inline void eqos_save_gcl_params(struct osi_core_priv_data *osi_core) } 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) || @@ -4674,46 +4678,6 @@ static int eqos_hw_est_write(struct osi_core_priv_data *osi_core, return 0; } -/** - * @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. - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static inline int eqos_gcl_validate(struct osi_core_priv_data *osi_core, - struct osi_est_config *est) -{ - struct core_local *l_core = (struct core_local *)osi_core; - unsigned int i; - - if (est->llr > l_core->gcl_dep) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "input argument more than GCL depth\n", - (unsigned long long)est->llr); - return -1; - } - - for (i = 0U; i < est->llr; i++) { - if (est->gcl[i] <= l_core->gcl_width_val) { - continue; - } - - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "validation of GCL entry failed\n", - (unsigned long long)i); - return -1; - } - - return 0; -} - /** * @brief eqos_hw_config_est - Read Setting for GCL from input and update * registers. @@ -4763,7 +4727,15 @@ static int eqos_hw_config_est(struct osi_core_priv_data *osi_core, return 0; } - if (eqos_gcl_validate(osi_core, est) < 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; @@ -4818,14 +4790,6 @@ static int eqos_hw_config_est(struct osi_core_priv_data *osi_core, } } - 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]); - } - /* Write parameters */ ret = eqos_hw_est_write(osi_core, EQOS_MTL_EST_BTR_LOW, btr[0] + est->btr_offset[0], OSI_DISABLE); diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 1f4cf07..76e265f 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -556,6 +556,7 @@ 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 @@ -582,8 +583,8 @@ OSI_BIT(14) | OSI_BIT(15) | \ OSI_BIT(16) | OSI_BIT(17) | \ OSI_BIT(18) | OSI_BIT(19)) -#define EQOS_MTL_EST_GCRR OSI_BIT(2) #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 << \ diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index ebc58fe..c1883bb 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -30,6 +30,7 @@ #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 @@ -2931,6 +2932,8 @@ 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}; @@ -2943,6 +2946,7 @@ static inline void mgbe_save_gcl_params(struct osi_core_priv_data *osi_core) } 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 || @@ -4629,46 +4633,6 @@ static int mgbe_hw_est_write(struct osi_core_priv_data *osi_core, return 0; } -/** - * @brief mgbe_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. - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static inline int mgbe_gcl_validate(struct osi_core_priv_data *osi_core, - struct osi_est_config *est) -{ - struct core_local *l_core = (struct core_local *)osi_core; - unsigned int i; - - if (est->llr > l_core->gcl_dep) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "input argument more than GCL depth\n", - (unsigned long long)est->llr); - return -1; - } - - for (i = 0U; i < est->llr; i++) { - if (est->gcl[i] <= l_core->gcl_width_val) { - continue; - } - - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "validation of GCL entry failed\n", - (unsigned long long)i); - return -1; - } - - return 0; -} - /** * @brief mgbe_hw_config_est - Read Setting for GCL from input and update * registers. @@ -4719,7 +4683,15 @@ static int mgbe_hw_config_est(struct osi_core_priv_data *osi_core, return 0; } - if (mgbe_gcl_validate(osi_core, est) < 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; @@ -4769,13 +4741,6 @@ static int mgbe_hw_config_est(struct osi_core_priv_data *osi_core, } } - 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]); - } /* Write parameters */ ret = mgbe_hw_est_write(osi_core, MGBE_MTL_EST_BTR_LOW, btr[0] + est->btr_offset[0], OSI_DISABLE); diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index d91f883..19d723b 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -636,6 +636,7 @@ 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 @@ -650,7 +651,6 @@ #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_CONTROL_EEST OSI_BIT(0) #define MGBE_MTL_EST_OVERHEAD_OVHD (OSI_BIT(0) | OSI_BIT(1) | \ OSI_BIT(2) | OSI_BIT(3) | \ OSI_BIT(4) | OSI_BIT(5)) @@ -667,8 +667,8 @@ OSI_BIT(14) | OSI_BIT(15) | \ OSI_BIT(16) | OSI_BIT(17) | \ OSI_BIT(18) | OSI_BIT(19)) -#define MGBE_MTL_EST_GCRR OSI_BIT(2) #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 << \ From b8a07f093e0db02fa32de1ef75451068a7fe553e Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Mon, 28 Feb 2022 08:51:15 +0530 Subject: [PATCH 324/458] osi: dma: Define macro for DMA TX max buffer size Bug 3528173 Change-Id: If7152ec75bcf21d820cd68c3aff31e3c6aa8ae6b Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2675628 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Gaurav Asati <gasati@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_dma.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/osi_dma.h b/include/osi_dma.h index c21221f..c7a800f 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -247,6 +247,11 @@ #endif /* OSI_DEBUG */ /** @} */ +/** + * @brief Maximum buffer length per DMA descriptor (16KB - 1). + */ +#define OSI_TX_MAX_BUFF_SIZE 0x3FFFU + /** * @brief OSI packet error stats */ From a4e68accdf695dba99f89f4086eed74b12e9517c Mon Sep 17 00:00:00 2001 From: Sanath Kumar Gampa <sgampa@nvidia.com> Date: Thu, 24 Feb 2022 18:00:20 +0530 Subject: [PATCH 325/458] osi:macsec: Address SC over-writing issue Issue: In multi VM use case if multiple SCs are added using supplicants Then we may over-write an exisitng SC if we stop and start the first supplicant Fix: Before adding an SC find the vacant SC slot Bug 3522740 Change-Id: Ic10f7a542a01328876b0103c34cc1115bfd426b5 Signed-off-by: Sanath Kumar Gampa <sgampa@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2675003 Reviewed-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_macsec.h | 4 ++-- osi/core/macsec.c | 42 ++++++++++++++++++++++++++++++++---------- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/include/osi_macsec.h b/include/osi_macsec.h index 27c1b29..9e4f5e1 100644 --- a/include/osi_macsec.h +++ b/include/osi_macsec.h @@ -309,8 +309,8 @@ struct osi_macsec_lut_status { struct osi_macsec_sc_info sc_info[OSI_MAX_NUM_SC]; /** next available BYP LUT index */ nveu32_t next_byp_idx; - /** next available SC LUT index */ - nveu32_t next_sc_idx; + /** number of active SCs */ + nveu32_t num_of_sc_used; }; /** diff --git a/osi/core/macsec.c b/osi/core/macsec.c index 943f1b8..44f4718 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -2649,7 +2649,7 @@ static struct osi_macsec_sc_info *find_existing_sc( &osi_core->macsec_lut_status[ctlr]; nveu32_t i; - for (i = 0; i < lut_status->next_sc_idx; i++) { + for (i = 0; i < OSI_MAX_NUM_SC; i++) { if (osi_memcmp(lut_status->sc_info[i].sci, sc->sci, OSI_SCI_LEN) == OSI_NONE) { return &lut_status->sc_info[i]; @@ -2659,6 +2659,21 @@ static struct osi_macsec_sc_info *find_existing_sc( return OSI_NULL; } +static nveu32_t get_avail_sc_idx(struct osi_core_priv_data *const osi_core, + nveu16_t ctlr) +{ + struct osi_macsec_lut_status *lut_status = + &osi_core->macsec_lut_status[ctlr]; + nveu32_t i; + + for (i = 0; i < OSI_MAX_NUM_SC; i++) { + if (lut_status->sc_info[i].an_valid == OSI_NONE) { + return i; + } + } + return i; +} + nve32_t macsec_get_sc_lut_key_index(struct osi_core_priv_data *const osi_core, nveu8_t *sci, nve32_t *key_index, nveu16_t ctlr) { @@ -2949,6 +2964,7 @@ static nve32_t macsec_config(struct osi_core_priv_data *const osi_core, struct osi_macsec_sc_info tmp_sc; struct osi_macsec_sc_info *tmp_sc_p = &tmp_sc; struct osi_macsec_lut_status *lut_status; + nve32_t avail_sc_idx = 0; /* Validate inputs */ if ((enable != OSI_ENABLE && enable != OSI_DISABLE) || @@ -2968,13 +2984,19 @@ static nve32_t macsec_config(struct osi_core_priv_data *const osi_core, return -1; } else { LOG("%s: Adding new SC/SA: ctlr: %hu", __func__, ctlr); - if (lut_status->next_sc_idx >= OSI_MAX_NUM_SC) { + if (lut_status->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; } - new_sc = &lut_status->sc_info[lut_status->next_sc_idx]; + 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->sc_info[avail_sc_idx]; osi_memcpy(new_sc->sci, sc->sci, OSI_SCI_LEN); osi_memcpy(new_sc->sak, sc->sak, OSI_KEY_LEN_128); #ifdef MACSEC_KEY_PROGRAM @@ -2985,7 +3007,7 @@ static nve32_t macsec_config(struct osi_core_priv_data *const osi_core, new_sc->pn_window = sc->pn_window; new_sc->flags = sc->flags; - new_sc->sc_idx_start = lut_status->next_sc_idx; + new_sc->sc_idx_start = avail_sc_idx; new_sc->an_valid |= OSI_BIT(sc->curr_an); if (add_upd_sc(osi_core, new_sc, ctlr, kt_idx) != @@ -2995,11 +3017,11 @@ static nve32_t macsec_config(struct osi_core_priv_data *const osi_core, return -1; } else { /* Update lut status */ - lut_status->next_sc_idx++; + lut_status->num_of_sc_used++; LOG("%s: Added new SC ctlr: %u " - "nxt_sc_idx: %u", + "Total active SCs: %u", __func__, ctlr, - lut_status->next_sc_idx); + lut_status->num_of_sc_used); return 0; } } @@ -3014,7 +3036,7 @@ static nve32_t macsec_config(struct osi_core_priv_data *const osi_core, return -1; } else { if (existing_sc->an_valid == OSI_NONE) { - lut_status->next_sc_idx--; + lut_status->num_of_sc_used--; osi_memset(existing_sc, OSI_NONE, sizeof(*existing_sc)); } @@ -3045,9 +3067,9 @@ static nve32_t macsec_config(struct osi_core_priv_data *const osi_core, return -1; } else { LOG("%s: Updated new SC ctlr: %u " - "nxt_sc_idx: %u", + "Total active SCs: %u", __func__, ctlr, - lut_status->next_sc_idx); + lut_status->num_of_sc_used); /* Now commit the changes */ *existing_sc = *tmp_sc_p; return 0; From 0b0aaa3d48c40e2b1147c26879956d1642b9b9ec Mon Sep 17 00:00:00 2001 From: Gaurav Asati <gasati@nvidia.com> Date: Thu, 10 Mar 2022 09:58:28 +0530 Subject: [PATCH 326/458] nvethernetrm: mgbe: Remove stale PTP timestamp. - When PTP Tx timestamp list is full with timestamps and a new timestamp is generated by Hw, remove oldest entry. Bug 3554871 Signed-off-by: Gaurav Asati <gasati@nvidia.com> Change-Id: If4fdb884638687609798827d3ee6b5a0a3919c1e Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2679260 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Gaurav Asati <gasati@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> Tested-by: Gaurav Asati <gasati@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/mgbe_core.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index c1883bb..896c2bf 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -3390,9 +3390,21 @@ static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core, nveu32_t 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; + 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, From 9203c4e3b65e491866815a4f95083dc85dcb4e3b Mon Sep 17 00:00:00 2001 From: Sanath Kumar Gampa <sgampa@nvidia.com> Date: Tue, 8 Mar 2022 17:37:15 +0530 Subject: [PATCH 327/458] osi:macsec: fix coverity defect Issue: Coverity issue : "Unchecked return value" Fix: Check the return value and print error Bug 3460422 CID 10127972 Change-Id: I78df96d969cbd23b22969cc02b79a64c17e8fe18 Signed-off-by: Sanath Kumar Gampa <sgampa@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2678123 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Sachin Nikam <snikam@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/macsec.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/osi/core/macsec.c b/osi/core/macsec.c index 44f4718..edf8ce3 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -2921,7 +2921,11 @@ err_sc_state: table_config->rw = OSI_LUT_WRITE; lut_config.lut_sel = OSI_LUT_SEL_SCI; table_config->index = sc->sc_idx_start; - macsec_lut_config(osi_core, &lut_config); + 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", ret); + } err_sci: /* cleanup SC param */ @@ -2930,7 +2934,11 @@ err_sci: table_config->ctlr_sel = ctlr; lut_config.lut_sel = OSI_LUT_SEL_SC_PARAM; table_config->index = sc->sc_idx_start; - macsec_lut_config(osi_core, &lut_config); + 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 LUT\n", ret); + } err_sc_param: /* Cleanup SA state LUT */ @@ -2940,7 +2948,11 @@ err_sc_param: table_config->rw = OSI_LUT_WRITE; lut_config.lut_sel = OSI_LUT_SEL_SA_STATE; table_config->index = (sc->sc_idx_start * OSI_MAX_NUM_SA) + sc->curr_an; - macsec_lut_config(osi_core, &lut_config); + 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 LUT\n", ret); + } err_sa_state: #ifdef MACSEC_KEY_PROGRAM @@ -2949,7 +2961,11 @@ err_sa_state: table_config->ctlr_sel = ctlr; table_config->rw = OSI_LUT_WRITE; table_config->index = *kt_idx; - macsec_kt_config(osi_core, &kt_config); + 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", ret); + } #endif /* MACSEC_KEY_PROGRAM */ return -1; From a9f0eaf55bbbf7e171b24bd1abbcabf3247e6353 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Mon, 14 Mar 2022 10:06:42 +0530 Subject: [PATCH 328/458] osi: mgbe: fix MGBE channels mask Bug 3420115 Change-Id: If086f090082bda7972d01776543f24c8cf9b060f Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2680952 Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Sachin Nikam <snikam@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/mgbe_core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 19d723b..55279e1 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -478,7 +478,7 @@ #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 0xFFU +#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) From 42a7078cd8ee8f2fa73d6bc0a717b6de721b5e0d Mon Sep 17 00:00:00 2001 From: Gaurav Asati <gasati@nvidia.com> Date: Mon, 8 Feb 2021 09:15:42 +0530 Subject: [PATCH 329/458] osi: Change barrier. Issue: Using "asm volatile" is leading to compilation issues with new coverity version. Fix: Change "asm volatile" to __sync_synchronize as same functionality is achieved without any issues. Bug 200699678 Change-Id: I685d27efab48443f2d2a664ae803e724cccde3fc Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2481631 (cherry picked from commit 63cdb70b76f3ae2b214d1ca371d42bdc7680e617) Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2486720 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/dma/osi_dma_txrx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 62fc4bc..c48b1ee 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -901,7 +901,7 @@ static inline void fill_first_desc(struct osi_tx_ring *tx_ring, */ static inline void dmb_oshst(void) { - asm volatile("dmb oshst" : : : "memory"); + __sync_synchronize(); } /** From 17fe734106fa2d07adfbc860cd55d56de2760f2c Mon Sep 17 00:00:00 2001 From: Mahesh Patil <maheshp@nvidia.com> Date: Thu, 24 Mar 2022 11:46:03 -0700 Subject: [PATCH 330/458] core: eqos: Fix pad calibration change coverity Fixed pad calibration change coverity issue Bug 3461002 Change-Id: I2e040dfcd4c1f7fd34637cd6b7c43e5ab3d9d7c4 Signed-off-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2686833 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Sachin Nikam <snikam@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/eqos_core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index ec2cf0b..1fad797 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -913,7 +913,6 @@ static nve32_t eqos_pad_calibrate(struct osi_core_priv_data *const osi_core) count = 0; while (cond == COND_NOT_MET) { if (count > retry) { - ret = -1; goto calibration_failed; } count++; @@ -933,7 +932,7 @@ calibration_failed: 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); + 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); From 9cea40f89db21bf27f3fe2714f4d09925f2fe655 Mon Sep 17 00:00:00 2001 From: Sanath Kumar Gampa <sgampa@nvidia.com> Date: Tue, 22 Mar 2022 18:36:19 +0530 Subject: [PATCH 331/458] osi:macsec:Change to update MACSEC MTU Issue: If MTU is increased after Supplicant is initialized we are not updating the MACSEC MTU so the frames will get dropped as the MACSEC MTU is lesser than the frames received Fix: Changes to update the MACSEC MTU along with MAC MTU Bug 3577143 Change-Id: Iff61099ff2a9ae1f6fe6e48948d842604fd9e2c4 Signed-off-by: Sanath Kumar Gampa <sgampa@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2685281 Reviewed-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/ivc_core.h | 1 + include/osi_macsec.h | 48 +++++++++++++++++++++- osi/core/ivc_core.c | 33 ++++++++++++++- osi/core/libnvethernetrm.export | 1 + osi/core/macsec.c | 73 ++++++++++++++++++++++++--------- 5 files changed, 133 insertions(+), 23 deletions(-) diff --git a/include/ivc_core.h b/include/ivc_core.h index 221a0eb..9efd063 100644 --- a/include/ivc_core.h +++ b/include/ivc_core.h @@ -58,6 +58,7 @@ typedef enum ivc_cmd { dbg_buf_config_macsec, dbg_events_config_macsec, macsec_get_sc_lut_key_index, + macsec_update_mtu_size, }ivc_cmd; /** diff --git a/include/osi_macsec.h b/include/osi_macsec.h index 9e4f5e1..633973f 100644 --- a/include/osi_macsec.h +++ b/include/osi_macsec.h @@ -374,7 +374,8 @@ struct osi_macsec_dbg_buf_config { */ struct osi_macsec_core_ops { /** macsec init */ - nve32_t (*init)(struct osi_core_priv_data *const osi_core); + 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 */ @@ -414,6 +415,9 @@ struct osi_macsec_core_ops { /** 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, nve32_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); }; @@ -463,6 +467,7 @@ nve32_t osi_init_macsec_ops(struct osi_core_priv_data *const osi_core); * set BYP LUT entries for MKPDU and BC packets * * @param[in] osi_core: OSI core private data structure. + * @param[in] mtu: MTU Length. * * @pre * - MACSEC should be out of reset and clocks are enabled @@ -487,7 +492,8 @@ nve32_t osi_init_macsec_ops(struct osi_core_priv_data *const osi_core); * @retval 0 on success * @retval -1 on failure */ -nve32_t osi_macsec_init(struct osi_core_priv_data *const osi_core); +nve32_t osi_macsec_init(struct osi_core_priv_data *const osi_core, + nveu32_t mtu); /** * @brief De-Initialize the macsec controller @@ -957,4 +963,42 @@ nve32_t osi_macsec_dbg_events_config( nve32_t osi_macsec_get_sc_lut_key_index( struct osi_core_priv_data *const osi_core, nveu8_t *sci, nve32_t *key_index, nveu16_t ctlr); + +/** + * @brief sets MACSEC MTU + * + * @note + * Algorithm: + * - Sets MACSEC MTU + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] mtu: MACSEC MTU + * + * + * @pre + * - MACSEC shall be initialized and enalbed + * + * @note + * Traceability Details: + * - SWUD_ID: + * + * @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 vaid Key Index Start on success + * @retval -1 on failure + */ +nve32_t osi_macsec_update_mtu(struct osi_core_priv_data *const osi_core, + nveu32_t mtu); + #endif /* INCLUDED_OSI_MACSEC_H */ diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index f8a30a3..dad51f1 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -367,6 +367,31 @@ static int ivc_macsec_config(struct osi_core_priv_data *const osi_core, 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. * @@ -555,13 +580,18 @@ static int ivc_macsec_deinit(struct osi_core_priv_data *const osi_core) * @retval 0 on Success * @retval -1 on Failure */ -static int ivc_macsec_init(struct osi_core_priv_data *const osi_core) +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)); } @@ -595,6 +625,7 @@ void ivc_init_macsec_ops(void *macsecops) 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 diff --git a/osi/core/libnvethernetrm.export b/osi/core/libnvethernetrm.export index a5c9f43..77ef8af 100644 --- a/osi/core/libnvethernetrm.export +++ b/osi/core/libnvethernetrm.export @@ -46,3 +46,4 @@ osi_handle_ioctl #osi_macsec_dbg_events_config #osi_macsec_kt_config #osi_macsec_get_sc_lut_key_index +#osi_macsec_update_mtu diff --git a/osi/core/macsec.c b/osi/core/macsec.c index edf8ce3..d907f4f 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -2453,30 +2453,17 @@ static nve32_t macsec_deinit(struct osi_core_priv_data *const osi_core) return 0; } -static nve32_t macsec_init(struct osi_core_priv_data *const osi_core) +static nve32_t macsec_update_mtu(struct osi_core_priv_data *const osi_core, + nveu32_t mtu) { nveu32_t val = 0; - struct osi_macsec_lut_config lut_config = {0}; - struct osi_macsec_table_config *table_config = &lut_config.table_config; - struct core_local *l_core = (struct core_local *)osi_core; - /* Store MAC address in reverse, per HW design */ - nveu8_t mac_da_mkpdu[OSI_ETH_ALEN] = {0x3, 0x0, 0x0, - 0xC2, 0x80, 0x01}; - nveu8_t mac_da_bc[OSI_ETH_ALEN] = {0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF}; - nveu32_t mtu = osi_core->mtu; nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; - nve32_t ret = 0; - nveu16_t i, j; - /* 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 { + if (mtu > OSI_MAX_MTU_SIZE) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Failed to config mac per macsec\n", 0ULL); + "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); @@ -2492,6 +2479,39 @@ static nve32_t macsec_init(struct osi_core_priv_data *const osi_core) LOG("Write MACSEC_RX_MTU_LEN: 0x%x\n", val); osi_writela(osi_core, val, addr + MACSEC_RX_MTU_LEN); + return 0; +} + +static nve32_t macsec_init(struct osi_core_priv_data *const osi_core, + nveu32_t mtu) +{ + nveu32_t val = 0; + struct osi_macsec_lut_config lut_config = {0}; + struct osi_macsec_table_config *table_config = &lut_config.table_config; + struct core_local *l_core = (struct core_local *)osi_core; + /* Store MAC address in reverse, per HW design */ + nveu8_t mac_da_mkpdu[OSI_ETH_ALEN] = {0x3, 0x0, 0x0, + 0xC2, 0x80, 0x01}; + nveu8_t mac_da_bc[OSI_ETH_ALEN] = {0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF}; + nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; + nve32_t ret = 0; + nveu16_t i, j; + + /* 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 */ @@ -3112,6 +3132,7 @@ static struct osi_macsec_core_ops macsec_ops = { .dbg_buf_config = macsec_dbg_buf_config, .dbg_events_config = macsec_dbg_events_config, .get_sc_lut_key_index = macsec_get_sc_lut_key_index, + .update_mtu = macsec_update_mtu, }; /** @@ -3137,11 +3158,12 @@ nve32_t osi_init_macsec_ops(struct osi_core_priv_data *const osi_core) return 0; } -nve32_t osi_macsec_init(struct osi_core_priv_data *const osi_core) +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); + return osi_core->macsec_ops->init(osi_core, mtu); } return -1; @@ -3196,6 +3218,17 @@ nve32_t osi_macsec_get_sc_lut_key_index(struct osi_core_priv_data *const osi_cor return -1; } +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 nve32_t osi_macsec_kt_config(struct osi_core_priv_data *const osi_core, struct osi_macsec_kt_config *const kt_config) From 18e4feb747741506c3a42b8cd12c9b90b801c0f7 Mon Sep 17 00:00:00 2001 From: Om Prakash Singh <omp@nvidia.com> Date: Wed, 16 Feb 2022 21:37:55 +0530 Subject: [PATCH 332/458] osi: core: add support for HSI 1) Add OSI IOCTL to enable HSI feature at runtime 2) Enable LIC interrupt for Correctable, Uncorrectable and Parity error 3) Program register to enable safety feature Bug 3543410 Change-Id: I8a9f33bab72eb37e8aa64c16c610be6e5271c7f8 Signed-off-by: Om Prakash Singh <omp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2670989 Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_core.h | 118 ++++++++++++++++ osi/core/core_local.h | 5 + osi/core/eqos_core.c | 261 +++++++++++++++++++++++++++++++++-- osi/core/eqos_core.h | 51 ++++++- osi/core/macsec.c | 46 +++++++ osi/core/mgbe_core.c | 308 ++++++++++++++++++++++++++++++++++++++++-- osi/core/mgbe_core.h | 53 +++++++- osi/core/osi_core.c | 19 +++ osi/core/osi_hal.c | 7 +- osi/core/xpcs.c | 11 +- osi/core/xpcs.h | 18 ++- 11 files changed, 874 insertions(+), 23 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 5c53119..40b95f4 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -236,6 +236,9 @@ typedef my_lint_64 nvel64_t; #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 /** @} */ /** @@ -329,6 +332,72 @@ typedef my_lint_64 nvel64_t; #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; /** @@ -1186,6 +1255,52 @@ struct osi_core_pkt_err_stats { 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. */ @@ -1325,6 +1440,9 @@ struct osi_core_priv_data { /** control pps output signal */ nveu32_t pps_frq; +#ifdef HSI_SUPPORT + struct osi_hsi_data hsi; +#endif }; /** diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 95f75df..cd3f416 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -281,6 +281,11 @@ struct core_ops { #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 */ + void (*core_hsi_configure)(struct osi_core_priv_data *const osi_core, + const nveu32_t enable); +#endif }; /** diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 1fad797..ba07162 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1703,6 +1703,146 @@ static void eqos_configure_rxq_priority( } } +#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 + * + */ +static void 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); + } +} +#endif /** * @brief eqos_configure_mac - Configure MAC * @@ -1823,7 +1963,6 @@ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) /* 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); @@ -1868,7 +2007,6 @@ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) eqos_configure_rxq_priority(osi_core); } } - /** * @brief eqos_configure_dma - Configure DMA * @@ -2134,6 +2272,8 @@ static void eqos_dma_chan_to_vmirq_map(struct osi_core_priv_data *osi_core) (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); } } @@ -2379,10 +2519,31 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, 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; @@ -2646,6 +2807,86 @@ static void eqos_handle_mtl_intrs(struct osi_core_priv_data *osi_core) (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. * @@ -2679,14 +2920,15 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *const osi_core) nveu32_t dma_ier = 0; nveu32_t mtl_isr = 0; nveu32_t frp_isr = 0U; - nveu32_t val = 0U; if (osi_core->mac_ver >= OSI_EQOS_MAC_5_30) { - val = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_WRAP_COMMON_INTR_STATUS); - val |= EQOS_MAC_SBD_INTR; - osi_writela(osi_core, val, (nveu8_t *)osi_core->base + + 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); @@ -6701,4 +6943,7 @@ void eqos_init_core_ops(struct core_ops *ops) 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 index 76e265f..0459d18 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -180,16 +180,20 @@ * @{ */ #define EQOS_CLOCK_CTRL_0 0x8000U -#define EQOS_APB_ERR_STATUS 0x8214U +#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_MAC_SBD_INTR 0x4 #define EQOS_WRAP_SYNC_TSC_PTP_CAPTURE 0x800CU #define EQOS_WRAP_TSC_CAPTURE_LOW 0x8010U #define EQOS_WRAP_TSC_CAPTURE_HIGH 0x8014U @@ -242,6 +246,7 @@ #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) @@ -283,6 +288,7 @@ #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) @@ -1078,4 +1084,45 @@ struct core_func_safety { #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/macsec.c b/osi/core/macsec.c index d907f4f..50a3353 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -2088,6 +2088,7 @@ 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; + nveu64_t tx_crc_err = 0; tx_isr = osi_readla(osi_core, addr + MACSEC_TX_ISR); LOG("%s(): tx_isr 0x%x\n", __func__, tx_isr); @@ -2117,6 +2118,21 @@ static inline void handle_tx_irq(struct osi_core_priv_data *const osi_core) if ((tx_isr & MACSEC_TX_MAC_CRC_ERROR) == MACSEC_TX_MAC_CRC_ERROR) { 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) { @@ -2139,6 +2155,8 @@ 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; + nveu64_t rx_crc_err = 0; + nveu64_t rx_icv_err = 0; rx_isr = osi_readla(osi_core, addr + MACSEC_RX_ISR); LOG("%s(): rx_isr 0x%x\n", __func__, rx_isr); @@ -2153,6 +2171,20 @@ static inline void handle_rx_irq(struct osi_core_priv_data *const osi_core) if ((rx_isr & MACSEC_RX_ICV_ERROR) == MACSEC_RX_ICV_ERROR) { 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) { @@ -2174,6 +2206,20 @@ static inline void handle_rx_irq(struct osi_core_priv_data *const osi_core) if ((rx_isr & MACSEC_RX_MAC_CRC_ERROR) == MACSEC_RX_MAC_CRC_ERROR) { 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) { diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 896c2bf..008bd3c 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -2574,6 +2574,178 @@ static int mgbe_config_flow_control(struct osi_core_priv_data *const osi_core, 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 + * + */ +static void mgbe_hsi_configure(struct osi_core_priv_data *const osi_core, + const nveu32_t enable) +{ + nveu32_t value = 0U; + void *xpcs_base = osi_core->xpcs_base; + + 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); + xpcs_write(xpcs_base, XPCS_BASE_PMA_MMD_SR_PMA_KR_FEC_CTRL, value); + + /* 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; + xpcs_write(xpcs_base, XPCS_VR_XS_PCS_SFTY_TMR_CTRL, value); + + /* 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 */ + xpcs_write(xpcs_base, XPCS_BASE_PMA_MMD_SR_PMA_KR_FEC_CTRL, 0); + + /* T23X-MGBE_HSIv2-11:Deinitialization of Watchdog Timer */ + xpcs_write(xpcs_base, XPCS_VR_XS_PCS_SFTY_TMR_CTRL, 0); + + /* 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); + } +} +#endif + /** * @brief mgbe_configure_mac - Configure MAC * @@ -3093,6 +3265,8 @@ static nve32_t mgbe_dma_chan_to_vmirq_map(struct osi_core_priv_data *osi_core) (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) && @@ -3980,6 +4154,123 @@ static int mgbe_config_ptp_offload(struct osi_core_priv_data *const osi_core, 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) { + xpcs_write(xpcs_base, XPCS_VR_XS_PCS_SFTY_UE_INTR0, 0); + } + val = xpcs_read(xpcs_base, XPCS_VR_XS_PCS_SFTY_CE_INTR); + if (val != 0U) { + xpcs_write(xpcs_base, XPCS_VR_XS_PCS_SFTY_CE_INTR, 0); + } + } +} +#endif + /** * @brief mgbe_handle_common_intr - Handles common interrupt. * @@ -4000,15 +4291,11 @@ static void mgbe_handle_common_intr(struct osi_core_priv_data *osi_core) unsigned int mtl_isr = 0; unsigned int val = 0; - /* FIXME: Disabling common interrupt. Needs to be fixed once - * RTL issue http://nvbugs/200517360 resolved. - */ - 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); - +#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; @@ -5984,4 +6271,7 @@ void mgbe_init_core_ops(struct core_ops *ops) 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 index 55279e1..8fc3368 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -129,8 +129,13 @@ #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 @@ -697,7 +702,7 @@ #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_SBD_INTR OSI_BIT(2) + #define MGBE_MAC_EXT_CNF_DDS OSI_BIT(7) #define MGBE_MAC_EXT_CNF_EIPG 0x1U #define MGBE_MAC_EXT_CNF_EIPG_MASK 0x7FU @@ -1092,4 +1097,50 @@ #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/osi_core.c b/osi/core/osi_core.c index 043d194..75c9e72 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -25,6 +25,25 @@ #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 */ diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 9eeab35..e4bbf9b 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -2052,7 +2052,12 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, ret = 0; } break; - +#ifdef HSI_SUPPORT + case OSI_CMD_HSI_CONFIGURE: + ops_p->core_hsi_configure(osi_core, data->arg1_u32); + ret = 0; + break; +#endif default: OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "CORE: Incorrect command\n", diff --git a/osi/core/xpcs.c b/osi/core/xpcs.c index 7bba29c..8576f84 100644 --- a/osi/core/xpcs.c +++ b/osi/core/xpcs.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -50,6 +50,14 @@ static inline int xpcs_poll_for_an_complete(struct osi_core_priv_data *osi_core, 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; } @@ -522,6 +530,7 @@ int xpcs_init(struct osi_core_priv_data *osi_core) ctrl |= XPCS_VR_XS_PCS_DIG_CTRL1_CL37_BP; xpcs_write(xpcs_base, XPCS_VR_XS_PCS_DIG_CTRL1, ctrl); } + /* TODO: 9. MII_AN_INTR_EN to 1, to enable auto-negotiation * complete interrupt */ diff --git a/osi/core/xpcs.h b/osi/core/xpcs.h index 39f9e11..9b0560a 100644 --- a/osi/core/xpcs.h +++ b/osi/core/xpcs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -107,6 +107,22 @@ #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); From 9bd1403e12e1aee591c126d5e91f30563a93512e Mon Sep 17 00:00:00 2001 From: Sanath Kumar Gampa <sgampa@nvidia.com> Date: Fri, 29 Oct 2021 14:20:13 +0530 Subject: [PATCH 333/458] osi:macsec: Fix osi macsec Misra/coverity issues Issue: Found aroung 900 MISRA?COVERITY defects on OSI MACSEC changes Fix: Fixed the defects by making minor changes without impacting the functionality Removed calling poll_for_dbg_buf_update, poll_for_kt_update and poll_for_lut_update before lut_write as we are anyhow polling after the lut_write Bug 3460422 Change-Id: Ib33e8188cd90472b851732f0936c3e29142bb4a3 Signed-off-by: Sanath Kumar Gampa <sgampa@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2618714 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/ivc_core.h | 2 +- include/osi_common.h | 1 + include/osi_macsec.h | 41 +- osi/common/common.h | 3 +- osi/core/Makefile.tmk | 3 - osi/core/eqos_core.c | 30 +- osi/core/eqos_core.h | 2 +- osi/core/ivc_core.c | 42 +- osi/core/libnvethernetrm.export | 6 +- osi/core/macsec.c | 879 +++++++++++++++++--------------- osi/core/macsec.h | 138 +---- osi/core/mgbe_core.c | 23 +- 12 files changed, 567 insertions(+), 603 deletions(-) diff --git a/include/ivc_core.h b/include/ivc_core.h index 9efd063..e8da34f 100644 --- a/include/ivc_core.h +++ b/include/ivc_core.h @@ -113,7 +113,7 @@ typedef struct macsec_config { /** MACsec KT index */ unsigned short kt_idx; /** MACsec KT index */ - nve32_t key_index; + nveu32_t key_index; /** MACsec SCI */ nveu8_t sci[OSI_SCI_LEN]; } macsec_config; diff --git a/include/osi_common.h b/include/osi_common.h index e833903..a6497bc 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -214,6 +214,7 @@ #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)) diff --git a/include/osi_macsec.h b/include/osi_macsec.h index 633973f..af6efb2 100644 --- a/include/osi_macsec.h +++ b/include/osi_macsec.h @@ -35,30 +35,30 @@ * @brief Helper macros for LUT programming * @{ */ -#define OSI_SCI_LEN 8 -#define OSI_KEY_LEN_128 16 -#define OSI_KEY_LEN_256 32 +#define OSI_SCI_LEN 8U +#define OSI_KEY_LEN_128 16U +#define OSI_KEY_LEN_256 32U #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_SC 8 -#define OSI_MAX_NUM_SA 4 +#define OSI_MAX_NUM_SC 8U +#define OSI_MAX_NUM_SA 4U #define OSI_CURR_AN_MAX 3 -#define OSI_KEY_INDEX_MAX 31 -#define OSI_PN_MAX_DEFAULT 0xFFFFFFFF -#define OSI_PN_THRESHOLD_DEFAULT 0xC0000000 +#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 15 +#define OSI_SC_INDEX_MAX 15U #define OSI_ETHTYPE_LEN 2 -#define OSI_LUT_BYTE_PATTERN_MAX 4 +#define OSI_LUT_BYTE_PATTERN_MAX 4U /* LUT byte pattern offset range 0-63 */ -#define OSI_LUT_BYTE_PATTERN_MAX_OFFSET 63 +#define OSI_LUT_BYTE_PATTERN_MAX_OFFSET 63U /* VLAN PCP range 0-7 */ -#define OSI_VLAN_PCP_MAX 7 +#define OSI_VLAN_PCP_MAX 7U /* VLAN ID range 1-4095 */ -#define OSI_VLAN_ID_MAX 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 @@ -130,7 +130,6 @@ #define OSI_TX_DBG_BUF_IDX_MAX 12U /* Num of Rx debug buffers */ #define OSI_RX_DBG_BUF_IDX_MAX 13U -#define OSI_DBG_BUF_IDX_MAX OSI_RX_DBG_BUF_IDX_MAX /** 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) @@ -308,7 +307,7 @@ 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 */ - nveu32_t next_byp_idx; + nveu16_t next_byp_idx; /** number of active SCs */ nveu32_t num_of_sc_used; }; @@ -414,7 +413,7 @@ struct osi_macsec_core_ops { 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, nve32_t *key_index, nveu16_t ctlr); + 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); @@ -629,8 +628,8 @@ void osi_macsec_s_isr(struct osi_core_priv_data *const osi_core); * @retval 0 on success * @retval -1 on failure */ -nve32_t osi_macsec_lut_config(struct osi_core_priv_data *const osi_core, - struct osi_macsec_lut_config *const lut_confg); +nve32_t osi_macsec_config_lut(struct osi_core_priv_data *const osi_core, + struct osi_macsec_lut_config *const lut_config); /** * @brief MACSEC Key table configuration @@ -665,7 +664,7 @@ nve32_t osi_macsec_lut_config(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure */ -nve32_t osi_macsec_kt_config(struct osi_core_priv_data *const osi_core, +nve32_t osi_macsec_config_kt(struct osi_core_priv_data *const osi_core, struct osi_macsec_kt_config *const kt_config); /** @@ -883,7 +882,7 @@ nve32_t osi_macsec_read_mmc(struct osi_core_priv_data *const osi_core); * @retval 0 on success * @retval -1 on failure */ -nve32_t osi_macsec_dbg_buf_config( +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); @@ -962,7 +961,7 @@ nve32_t osi_macsec_dbg_events_config( */ nve32_t osi_macsec_get_sc_lut_key_index( struct osi_core_priv_data *const osi_core, - nveu8_t *sci, nve32_t *key_index, nveu16_t ctlr); + nveu8_t *sci, nveu32_t *key_index, nveu16_t ctlr); /** * @brief sets MACSEC MTU diff --git a/osi/common/common.h b/osi/common/common.h index 3969e3c..af7052f 100644 --- a/osi/common/common.h +++ b/osi/common/common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -34,6 +34,7 @@ #define RETRY_COUNT 1000U #define COND_MET 0 #define COND_NOT_MET 1 +#define RETRY_DELAY 1U /** @} */ diff --git a/osi/core/Makefile.tmk b/osi/core/Makefile.tmk index 9e003a9..521160a 100644 --- a/osi/core/Makefile.tmk +++ b/osi/core/Makefile.tmk @@ -64,9 +64,6 @@ endif NV_COMPONENT_INCLUDES := \ $(NV_SOURCE)/nvethernetrm/include \ $(NV_SOURCE)/nvethernetrm/osi/common/include -#ifeq ($(NV_BUILD_CONFIGURATION_OS_IS_QNX),1) -#NV_COMPONENT_SYSTEM_SHARED_LIBRARIES += qcrypto -#endif include $(NV_BUILD_SHARED_LIBRARY) endif diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index ba07162..13368eb 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -6785,12 +6785,12 @@ static nve32_t eqos_config_rss(struct osi_core_priv_data *const osi_core) * - Run time: Yes * - De-initialization: No */ -void eqos_config_for_macsec(struct osi_core_priv_data *const osi_core, +static void eqos_config_for_macsec(struct osi_core_priv_data *const osi_core, const nveu32_t enable) { - nveu32_t value = 0U; + nveu32_t value = 0U, temp = 0U; - if (enable != OSI_ENABLE && enable != OSI_DISABLE) { + 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; @@ -6805,15 +6805,17 @@ void eqos_config_for_macsec(struct osi_core_priv_data *const osi_core, */ value = osi_readla(osi_core, (nveu8_t *)osi_core->base + EQOS_MAC_MCR); - value |= (EQOS_MCR_IPG << EQOS_MCR_IPG_SHIFT) & - EQOS_MCR_IPG_MASK; + 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; - value |= (EQOS_MAC_EXTR_EIPG << EQOS_MAC_EXTR_EIPG_SHIFT) & - EQOS_MAC_EXTR_EIPG_MASK; + 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 { @@ -6838,17 +6840,17 @@ void eqos_config_for_macsec(struct osi_core_priv_data *const osi_core, /* Updated MTL_EST depending on MACSEC enable/disable */ if (osi_core->hw_feature->est_sel == OSI_ENABLE) { value = osi_readla(osi_core, - (unsigned char *)osi_core->base + + (nveu8_t *)osi_core->base + EQOS_MTL_EST_CONTROL); value &= ~EQOS_MTL_EST_CONTROL_CTOV; if (enable == OSI_ENABLE) { - value |= (EQOS_MTL_EST_CTOV_MACSEC_RECOMMEND << - EQOS_MTL_EST_CONTROL_CTOV_SHIFT) & - EQOS_MTL_EST_CONTROL_CTOV; + temp = EQOS_MTL_EST_CTOV_MACSEC_RECOMMEND; + temp = temp << EQOS_MTL_EST_CONTROL_CTOV_SHIFT; + value |= temp & EQOS_MTL_EST_CONTROL_CTOV; } else { - value |= (EQOS_MTL_EST_CTOV_RECOMMEND << - EQOS_MTL_EST_CONTROL_CTOV_SHIFT) & - EQOS_MTL_EST_CONTROL_CTOV; + 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 + diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 0459d18..c3b503a 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -355,7 +355,7 @@ #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 0x3E000000 +#define EQOS_MAC_EXTR_EIPG_MASK 0x3E000000U #define EQOS_MAC_EXTR_EIPG_SHIFT 25U #define EQOS_MAC_EXTR_EIPG 0x3U #endif /* !OSI_STRIPPED_LIB */ diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index dad51f1..65a980c 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -287,9 +287,9 @@ static void ivc_macsec_read_mmc(struct osi_core_priv_data *const osi_core) msg.status = osi_memcpy((void *)&osi_core->macsec_mmc, (void *) &msg.data.macsec_mmc, sizeof(struct osi_macsec_mmc_counters)); - osi_memcpy((void *)&osi_core->macsec_irq_stats, - (void *) &msg.data.macsec_irq_stats, - sizeof(struct osi_macsec_irq_stats)); + msg.status = osi_memcpy((void *)&osi_core->macsec_irq_stats, + (void *) &msg.data.macsec_irq_stats, + sizeof(struct osi_macsec_irq_stats)); } /** @@ -305,7 +305,7 @@ static void ivc_macsec_read_mmc(struct osi_core_priv_data *const osi_core) * @retval -1 on Failure */ static int ivc_get_sc_lut_key_index(struct osi_core_priv_data *const osi_core, - nveu8_t *sci, nve32_t *key_index, + nveu8_t *sci, nveu32_t *key_index, nveu16_t ctlr) { ivc_msg_common_t msg; @@ -410,7 +410,8 @@ static int ivc_macsec_enable(struct osi_core_priv_data *const osi_core, osi_memset(&msg, 0, sizeof(msg)); msg.cmd = en_macsec; - msg.data.args.arguments[index++] = enable; + msg.data.args.arguments[index] = enable; + index++; msg.data.args.count = index; return osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); @@ -434,7 +435,8 @@ static int ivc_macsec_loopback_config(struct osi_core_priv_data *const osi_core, osi_memset(&msg, 0, sizeof(msg)); msg.cmd = loopback_config_macsec; - msg.data.args.arguments[index++] = enable; + msg.data.args.arguments[index] = enable; + index++; msg.data.args.count = index; return osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); @@ -450,11 +452,11 @@ static int ivc_macsec_loopback_config(struct osi_core_priv_data *const osi_core, * @retval 0 on Success * @retval -1 on Failure */ -static int ivc_macsec_kt_config(struct osi_core_priv_data *const osi_core, - struct osi_macsec_kt_config *kt_config) +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; - int ret = 0; + nve32_t ret = 0; osi_memset(&msg, 0, sizeof(msg)); @@ -464,8 +466,9 @@ static int ivc_macsec_kt_config(struct osi_core_priv_data *const osi_core, sizeof(struct osi_macsec_kt_config)); ret = osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); - if (ret != 0) + if (ret != 0) { return ret; + } msg.status = osi_memcpy((void *)kt_config, (void *)&msg.data.kt_config, @@ -492,7 +495,8 @@ static int ivc_macsec_cipher_config(struct osi_core_priv_data *const osi_core, osi_memset(&msg, 0, sizeof(msg)); msg.cmd = cipher_config; - msg.data.args.arguments[index++] = cipher; + msg.data.args.arguments[index] = cipher; + index++; msg.data.args.count = index; return osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); @@ -506,11 +510,11 @@ static int ivc_macsec_cipher_config(struct osi_core_priv_data *const osi_core, * @retval 0 on Success * @retval -1 on Failure */ -static int ivc_macsec_lut_config(struct osi_core_priv_data *const osi_core, - struct osi_macsec_lut_config *lut_config) +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; - int ret = 0; + nve32_t ret = 0; osi_memset(&msg, 0, sizeof(msg)); @@ -520,8 +524,9 @@ static int ivc_macsec_lut_config(struct osi_core_priv_data *const osi_core, sizeof(struct osi_macsec_lut_config)); ret = osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); - if (ret != 0) + if (ret != 0) { return ret; + } msg.status = osi_memcpy((void *)lut_config, (void *)&msg.data.lut_config, @@ -537,7 +542,8 @@ static int ivc_macsec_lut_config(struct osi_core_priv_data *const osi_core, */ static void ivc_macsec_handle_s_irq(struct osi_core_priv_data *const osi_core) { - + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "Nothing to handle \n", 0ULL); } /** @@ -549,6 +555,8 @@ static void ivc_macsec_handle_s_irq(struct osi_core_priv_data *const osi_core) static void ivc_macsec_handle_ns_irq(struct osi_core_priv_data *const osi_core) { + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "Nothing to handle \n", 0ULL); } /** @@ -617,7 +625,7 @@ void ivc_init_macsec_ops(void *macsecops) #ifdef MACSEC_KEY_PROGRAM ops->kt_config = ivc_macsec_kt_config; #endif /* MACSEC_KEY_PROGRAM */ - ops->cipher_config = ivc_macsec_cipher_config, + 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; diff --git a/osi/core/libnvethernetrm.export b/osi/core/libnvethernetrm.export index 77ef8af..d27755a 100644 --- a/osi/core/libnvethernetrm.export +++ b/osi/core/libnvethernetrm.export @@ -39,11 +39,11 @@ osi_handle_ioctl #osi_macsec_cipher_config #osi_macsec_config #osi_init_macsec_ops -#osi_macsec_lut_config +#osi_macsec_config_lut #osi_macsec_loopback #osi_macsec_read_mmc -#osi_macsec_dbg_buf_config +#osi_macsec_config_dbg_buf #osi_macsec_dbg_events_config -#osi_macsec_kt_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 index 50a3353..726b87c 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -52,7 +52,7 @@ */ static nve32_t poll_for_dbg_buf_update(struct osi_core_priv_data *const osi_core) { - nve32_t retry = RETRY_COUNT; + nveu32_t retry = RETRY_COUNT; nveu32_t dbg_buf_config; nve32_t cond = COND_NOT_MET; nveu32_t count; @@ -68,13 +68,13 @@ static nve32_t poll_for_dbg_buf_update(struct osi_core_priv_data *const osi_core 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) == 0U) { + 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(10U); + osi_core->osd_ops.udelay(RETRY_DELAY); } return 0; @@ -82,7 +82,7 @@ static nve32_t poll_for_dbg_buf_update(struct osi_core_priv_data *const osi_core } /** - * @brief write_dbg_buf_data - Commit.debug buffer to HW + * @brief write_dbg_buf_data - Commit debug buffer to HW * * @param[in] osi_core: OSI Core private data structure. * @param[in] dbg_buf: Pointer to debug buffer data to be written @@ -105,7 +105,7 @@ static inline void write_dbg_buf_data( } /** - * @brief read_dbg_buf_data - Read.debug buffer from HW + * @brief read_dbg_buf_data - Read debug buffer from HW * * @param[in] osi_core: OSI Core private data structure. * @param[in] dbg_buf: Pointer to debug buffer data to be read @@ -148,37 +148,37 @@ static void tx_dbg_trigger_evts( 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) { + 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) { + 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) { + 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) { + 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) { + 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) { + if ((flags & OSI_TX_DBG_CAPTURE_EVT) != OSI_NONE) { tx_trigger_evts |= MACSEC_TX_DBG_CAPTURE; } else { tx_trigger_evts &= ~MACSEC_TX_DBG_CAPTURE; @@ -201,22 +201,22 @@ static void tx_dbg_trigger_evts( 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) { + 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) { + 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) { + 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) { + 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) { + 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) { + if ((tx_trigger_evts & MACSEC_TX_DBG_CAPTURE) != OSI_NONE) { flags |= OSI_TX_DBG_CAPTURE_EVT; } dbg_buf_config->flags = flags; @@ -244,37 +244,37 @@ static void rx_dbg_trigger_evts( 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) { + 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) { + 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) { + 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) { + 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) { + 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) { + if ((flags & OSI_RX_DBG_CAPTURE_EVT) != OSI_NONE) { rx_trigger_evts |= MACSEC_RX_DBG_CAPTURE; } else { rx_trigger_evts &= ~MACSEC_RX_DBG_CAPTURE; @@ -296,22 +296,22 @@ static void rx_dbg_trigger_evts( 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) { + 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) { + 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) { + 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) { + 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) { + 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) { + if ((rx_trigger_evts & MACSEC_RX_DBG_CAPTURE) != OSI_NONE) { flags |= OSI_RX_DBG_CAPTURE_EVT; } dbg_buf_config->flags = flags; @@ -343,30 +343,24 @@ static nve32_t macsec_dbg_buf_config(struct osi_core_priv_data *const osi_core, 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)) { + 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; } - /* Wait for previous debug table update to finish */ - ret = poll_for_dbg_buf_update(osi_core); - if (ret < 0) { - return ret; - } - dbg_config_reg = osi_readla(osi_core, base + MACSEC_DEBUG_BUF_CONFIG_0); - if (dbg_buf_config->ctlr_sel) { + 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) { + 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); @@ -383,19 +377,19 @@ static nve32_t macsec_dbg_buf_config(struct osi_core_priv_data *const osi_core, return ret; } - if (!dbg_buf_config->rw) { + if (dbg_buf_config->rw == OSI_NONE) { read_dbg_buf_data(osi_core, dbg_buf_config->dbg_buf); } return 0; } -nve32_t macsec_dbg_events_config( +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) { - nveu32_t i, events = 0; - nveu32_t flags = dbg_buf_config->flags; + nveu64_t events = 0; + nveu32_t i, flags = dbg_buf_config->flags; /* Validate inputs */ if ((dbg_buf_config->rw > OSI_RW_MAX) || @@ -406,10 +400,10 @@ nve32_t macsec_dbg_events_config( } /* Only one event allowed to configure at a time */ - if (flags != OSI_NONE && dbg_buf_config->rw == OSI_DBG_TBL_WRITE) { + if ((flags != OSI_NONE) && (dbg_buf_config->rw == OSI_DBG_TBL_WRITE)) { for (i = 0; i < 32U; i++) { - if (flags & (1U << i)) { - events++; + if ((flags & ((nveu32_t)(1U) << i)) != OSI_NONE) { + CERT_C__POST_INC__U64(events); } } if (events > 1U) { @@ -426,6 +420,10 @@ nve32_t macsec_dbg_events_config( 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; @@ -445,27 +443,23 @@ nve32_t macsec_dbg_events_config( * * @retval value on current MMC counter value. */ -static inline unsigned long long update_macsec_mmc_val( +static inline nveul64_t update_macsec_mmc_val( struct osi_core_priv_data *osi_core, - unsigned long offset) + nveu64_t offset) { - nveul64_t temp; - nveu32_t value_lo, value_hi; + 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 + 4U)); - temp = (value_lo | value_hi << 31); - - return temp; + ((offset & 0xFFFFU) + 4U)); + return ((value_lo) | (value_hi << 31)); } /** - * @brief macsec_read_mmc - To read statitics registers and update structure - * variable + * @brief macsec_read_mmc - To read statitics registers and update mmc structure * * Algorithm: Pass register offset and old value to helper function and * update structure. @@ -475,7 +469,7 @@ static inline unsigned long long update_macsec_mmc_val( * @note * 1) MAC/MACSEC should be init and started. */ -void macsec_read_mmc(struct osi_core_priv_data *const osi_core) +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; @@ -520,7 +514,8 @@ void macsec_read_mmc(struct osi_core_priv_data *const osi_core) } } -nve32_t macsec_enable(struct osi_core_priv_data *osi_core, nveu32_t enable) +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; @@ -530,7 +525,8 @@ nve32_t macsec_enable(struct osi_core_priv_data *osi_core, nveu32_t enable) /* MACSEC and FPE cannot coexist on MGBE refer bug 3484034 */ if ((osi_core->mac == OSI_MAC_HW_MGBE) && - ((enable & OSI_MACSEC_TX_EN) || (enable & OSI_MACSEC_RX_EN)) && + (((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); @@ -562,10 +558,12 @@ nve32_t macsec_enable(struct osi_core_priv_data *osi_core, nveu32_t enable) val &= ~(MACSEC_RX_EN); } - if ((enable & OSI_MACSEC_TX_EN) || (enable & OSI_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 + } else { osi_core->is_macsec_enabled = OSI_DISABLE; + } LOG("Write MACSEC_CONTROL0: 0x%x\n", val); osi_writela(osi_core, val, base + MACSEC_CONTROL0); @@ -587,7 +585,7 @@ exit: static inline nve32_t poll_for_kt_update(struct osi_core_priv_data *osi_core) { /* half sec timeout */ - nveu32_t retry = 50000; + nveu32_t retry = RETRY_COUNT; nveu32_t kt_config; nveu32_t count; nve32_t cond = 1; @@ -607,12 +605,12 @@ static inline nve32_t poll_for_kt_update(struct osi_core_priv_data *osi_core) kt_config = osi_readla(osi_core, (nveu8_t *)osi_core->tz_base + MACSEC_GCM_KEYTABLE_CONFIG); - if ((kt_config & MACSEC_KT_CONFIG_UPDATE) == 0U) { + 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(10U); + osi_core->osd_ops.udelay(RETRY_DELAY); } } @@ -623,7 +621,7 @@ 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}; - nve32_t i, j; + nveu32_t i, j; for (i = 0; i < MACSEC_KT_DATA_REG_CNT; i++) { kt_key[i] = osi_readla(osi_core, @@ -631,23 +629,23 @@ static nve32_t kt_key_read(struct osi_core_priv_data *const osi_core, MACSEC_GCM_KEYTABLE_DATA(i)); } - if ((kt_key[MACSEC_KT_DATA_REG_CNT - 1] & MACSEC_KT_ENTRY_VALID) == + 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 * 4 + j] = - (kt_key[i] >> (j * 8) & 0xFF); + 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 * 4 + j] = - (kt_key[i + MACSEC_KT_DATA_REG_SAK_CNT] >> (j * 8) - & 0xFF); + kt_config->entry.h[(i * 4U) + j] = + (nveu8_t)((kt_key[i + MACSEC_KT_DATA_REG_SAK_CNT] >> (j * 8U)) + & 0xFFU); } } @@ -655,17 +653,18 @@ static nve32_t kt_key_read(struct osi_core_priv_data *const osi_core, } static nve32_t kt_key_write(struct osi_core_priv_data *const osi_core, - struct osi_macsec_kt_config *const kt_config) + 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; - nve32_t i, j; + 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] |= (entry.sak[i * 4 + j] << (j * 8)); + kt_key[i] |= ((nveu32_t)(entry.sak[(i * 4U) + j]) << + (j * 8U)); } } /* write H-key */ @@ -673,13 +672,13 @@ static nve32_t kt_key_write(struct osi_core_priv_data *const osi_core, /* 4-bytes in each register */ for (j = 0; j < INTEGER_LEN; j++) { kt_key[i + MACSEC_KT_DATA_REG_SAK_CNT] |= - (entry.h[i * 4 + j] << (j * 8)); + ((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 - 1] |= MACSEC_KT_ENTRY_VALID; + kt_key[MACSEC_KT_DATA_REG_CNT - 1U] |= MACSEC_KT_ENTRY_VALID; } for (i = 0; i < MACSEC_KT_DATA_REG_CNT; i++) { @@ -705,20 +704,14 @@ static nve32_t macsec_kt_config(struct osi_core_priv_data *const osi_core, return -1; } - /* Wait for previous KT update to finish */ - ret = poll_for_kt_update(osi_core); - if (ret < 0) { - return ret; - } - kt_config_reg = osi_readla(osi_core, base + MACSEC_GCM_KEYTABLE_CONFIG); - if (kt_config->table_config.ctlr_sel) { + 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) { + 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); @@ -741,7 +734,7 @@ static nve32_t macsec_kt_config(struct osi_core_priv_data *const osi_core, return ret; } - if (!kt_config->table_config.rw) { + if (kt_config->table_config.rw == OSI_NONE) { ret = kt_key_read(osi_core, kt_config); if (ret < 0) { return ret; @@ -762,7 +755,7 @@ static nve32_t macsec_kt_config(struct osi_core_priv_data *const osi_core, static inline nve32_t poll_for_lut_update(struct osi_core_priv_data *osi_core) { /* half sec timeout */ - nveu32_t retry = 50000; + nveu32_t retry = RETRY_COUNT; nveu32_t lut_config; nveu32_t count; nve32_t cond = 1; @@ -782,12 +775,12 @@ static inline nve32_t poll_for_lut_update(struct osi_core_priv_data *osi_core) lut_config = osi_readla(osi_core, (nveu8_t *)osi_core->macsec_base + MACSEC_LUT_CONFIG); - if ((lut_config & MACSEC_LUT_CONFIG_UPDATE) == 0U) { + 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(1U); + osi_core->osd_ops.udelay(RETRY_DELAY); } } @@ -798,7 +791,7 @@ 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; - nve32_t i; + nveu32_t i; /* Commit the LUT entry to HW */ for (i = 0; i < MACSEC_LUT_DATA_REG_CNT; i++) { @@ -807,7 +800,7 @@ static inline void read_lut_data(struct osi_core_priv_data *const osi_core, } static nve32_t lut_read_inputs(struct osi_macsec_lut_config *const lut_config, - nveu32_t *const lut_data) + const nveu32_t *const lut_data) { struct osi_lut_inputs entry = {0}; nveu32_t flags = 0; @@ -815,84 +808,84 @@ static nve32_t lut_read_inputs(struct osi_macsec_lut_config *const lut_config, /* MAC DA */ if ((lut_data[1] & MACSEC_LUT_DA_BYTE0_INACTIVE) != MACSEC_LUT_DA_BYTE0_INACTIVE) { - entry.da[0] = lut_data[0] & 0xFF; + 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] = lut_data[0] >> 8 & 0xFF; + 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] = lut_data[0] >> 16 & 0xFF; + 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] = lut_data[0] >> 24 & 0xFF; + 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] = lut_data[1] & 0xFF; + 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] = lut_data[1] >> 8 & 0xFF; + entry.da[5] = (nveu8_t)((lut_data[1] >> 8) & 0xFFU); flags |= OSI_LUT_FLAGS_DA_BYTE5_VALID; } /* MAC SA */ if ((lut_data[3] & MACSEC_LUT_SA_BYTE0_INACTIVE) != MACSEC_LUT_SA_BYTE0_INACTIVE) { - entry.sa[0] = lut_data[1] >> 22 & 0xFF; + 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] = (lut_data[1] >> 30) | - ((lut_data[2] & 0x3F) << 2); + 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] = lut_data[2] >> 6 & 0xFF; + 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] = lut_data[2] >> 14 & 0xFF; + 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] = lut_data[2] >> 22 & 0xFF; + 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] = (lut_data[2] >> 30) | - ((lut_data[3] & 0x3F) << 2); + entry.sa[5] = (nveu8_t)((lut_data[2] >> 30) | + ((lut_data[3] & 0x3FU) << 2)); flags |= OSI_LUT_FLAGS_SA_BYTE5_VALID; } /* Ether type */ if ((lut_data[3] & MACSEC_LUT_ETHTYPE_INACTIVE) != MACSEC_LUT_ETHTYPE_INACTIVE) { - entry.ethtype[0] = lut_data[3] >> 12 & 0xFF; - entry.ethtype[1] = lut_data[3] >> 20 & 0xFF; + 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; } @@ -903,14 +896,14 @@ static nve32_t lut_read_inputs(struct osi_macsec_lut_config *const lut_config, 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] >> 29; + 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 & 0xFFF; + entry.vlan_id = (lut_data[4] >> 1) & 0xFFFU; } } @@ -918,28 +911,32 @@ static nve32_t lut_read_inputs(struct osi_macsec_lut_config *const lut_config, 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] = lut_data[4] >> 15 & 0xFF; - entry.byte_pattern_offset[0] = lut_data[4] >> 23 & 0x3F; + 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] = (lut_data[4] >> 30) | - ((lut_data[5] & 0x3F) << 2); - entry.byte_pattern_offset[1] = lut_data[5] >> 6 & 0x3F; + 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] = lut_data[5] >> 13 & 0xFF; - entry.byte_pattern_offset[2] = lut_data[5] >> 21 & 0x3F; + 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] = (lut_data[5] >> 28) | - ((lut_data[6] & 0xF) << 4); - entry.byte_pattern_offset[3] = lut_data[6] >> 4 & 0x3F; + 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 */ @@ -965,6 +962,7 @@ static nve32_t byp_lut_read(struct osi_core_priv_data *const osi_core, 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); @@ -1000,16 +998,17 @@ static nve32_t byp_lut_read(struct osi_core_priv_data *const osi_core, default: OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Unknown controller select\n", 0ULL); - return -1; + ret = -1; + break; } - val = osi_readla(osi_core, paddr); - if (val & (1U << index)) { - flags |= OSI_LUT_FLAGS_ENTRY_VALID; + 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; } - - lut_config->flags |= flags; - - return 0; + return ret; } static nve32_t sci_lut_read(struct osi_core_priv_data *const osi_core, @@ -1020,6 +1019,7 @@ static nve32_t sci_lut_read(struct osi_core_priv_data *const osi_core, 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; @@ -1050,7 +1050,7 @@ static nve32_t sci_lut_read(struct osi_core_priv_data *const osi_core, lut_config->sci_lut_out.an_valid |= OSI_AN3_VALID; } - lut_config->sci_lut_out.sc_index = lut_data[6] >> 17 & 0xF; + 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) { @@ -1063,21 +1063,21 @@ static nve32_t sci_lut_read(struct osi_core_priv_data *const osi_core, } val = osi_readla(osi_core, addr+MACSEC_TX_SCI_LUT_VALID); - if (val & (1U << index)) { + if ((val & ((nveu32_t)(1U) << index)) != OSI_NONE) { lut_config->flags |= OSI_LUT_FLAGS_ENTRY_VALID; } break; case OSI_CTLR_SEL_RX: - lut_config->sci_lut_out.sci[0] = lut_data[0] & 0xFF; - lut_config->sci_lut_out.sci[1] = lut_data[0] >> 8 & 0xFF; - lut_config->sci_lut_out.sci[2] = lut_data[0] >> 16 & 0xFF; - lut_config->sci_lut_out.sci[3] = lut_data[0] >> 24 & 0xFF; - lut_config->sci_lut_out.sci[4] = lut_data[1] & 0xFF; - lut_config->sci_lut_out.sci[5] = lut_data[1] >> 8 & 0xFF; - lut_config->sci_lut_out.sci[6] = lut_data[1] >> 16 & 0xFF; - lut_config->sci_lut_out.sci[7] = lut_data[1] >> 24 & 0xFF; + 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 & 0xF; + 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; @@ -1088,48 +1088,50 @@ static nve32_t sci_lut_read(struct osi_core_priv_data *const osi_core, } val = osi_readla(osi_core, addr+MACSEC_RX_SCI_LUT_VALID); - if (val & (1U << index)) { + 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); - return -1; + ret = -1; + break; } /* Lookup output */ - return 0; + return ret; } 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] & 0x1F; + 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 = (lut_data[2] >> 5) & 0x3; - lut_config->sc_param_out.sci[0] = lut_data[2] >> 8 & 0xFF; - lut_config->sc_param_out.sci[1] = lut_data[2] >> 16 & 0xFF; - lut_config->sc_param_out.sci[2] = lut_data[2] >> 24 & 0xFF; - lut_config->sc_param_out.sci[3] = lut_data[3] & 0xFF; - lut_config->sc_param_out.sci[4] = lut_data[3] >> 8 & 0xFF; - lut_config->sc_param_out.sci[5] = lut_data[3] >> 16 & 0xFF; - lut_config->sc_param_out.sci[6] = lut_data[3] >> 24 & 0xFF; - lut_config->sc_param_out.sci[7] = lut_data[4] & 0xFF; + 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 = - (lut_data[4] >> 8) & 0x1; + (nveu8_t)((lut_data[4] >> 8) & 0x1U); break; case OSI_CTLR_SEL_RX: - lut_config->sc_param_out.key_index_start = lut_data[0] & 0x1F; + 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) | @@ -1138,11 +1140,12 @@ static nve32_t sc_param_lut_read(struct osi_core_priv_data *const osi_core, default: OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Unknown controller selected\n", 0ULL); - return -1; + ret = -1; + break; } /* Lookup output */ - return 0; + return ret; } static nve32_t sc_state_lut_read(struct osi_core_priv_data *const osi_core, @@ -1160,6 +1163,7 @@ 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); @@ -1178,16 +1182,19 @@ static nve32_t sa_state_lut_read(struct osi_core_priv_data *const osi_core, default: OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Unknown controller selected\n", 0ULL); - return -1; + ret = -1; + break; } /* Lookup output */ - return 0; + return ret; } 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: if (byp_lut_read(osi_core, lut_config) != 0) { @@ -1227,17 +1234,18 @@ static nve32_t lut_data_read(struct osi_core_priv_data *const osi_core, default: OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Unsupported LUT\n", 0ULL); - return -1; + ret = -1; + break; } - return 0; + return ret; } 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; - nve32_t i; + nveu32_t i; /* Commit the LUT entry to HW */ for (i = 0; i < MACSEC_LUT_DATA_REG_CNT; i++) { @@ -1255,9 +1263,8 @@ static void rx_sa_state_lut_config( lut_data[1] |= entry.lowest_pn; } -static void tx_sa_state_lut_config( - struct osi_macsec_lut_config *const lut_config, - nveu32_t *const lut_data) +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; @@ -1274,6 +1281,7 @@ static nve32_t sa_state_lut_config(struct osi_core_priv_data *const osi_core, { 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: @@ -1283,16 +1291,17 @@ static nve32_t sa_state_lut_config(struct osi_core_priv_data *const osi_core, rx_sa_state_lut_config(lut_config, lut_data); break; default: - return -1; + ret = -1; + break; } commit_lut_data(osi_core, lut_data); - return 0; + return ret; } static nve32_t sc_state_lut_config(struct osi_core_priv_data *const osi_core, - struct osi_macsec_lut_config *const lut_config) + 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; @@ -1317,7 +1326,7 @@ static void rx_sc_param_lut_config( } static void tx_sc_param_lut_config( - struct osi_macsec_lut_config *const 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; @@ -1327,16 +1336,16 @@ static void tx_sc_param_lut_config( lut_data[1] |= entry.pn_max >> 27; lut_data[1] |= entry.pn_threshold << 5; lut_data[2] |= entry.pn_threshold >> 27; - lut_data[2] |= entry.tci << 5; - lut_data[2] |= entry.sci[0] << 8; - lut_data[2] |= entry.sci[1] << 16; - lut_data[2] |= entry.sci[2] << 24; - lut_data[3] |= entry.sci[3]; - lut_data[3] |= entry.sci[4] << 8; - lut_data[3] |= entry.sci[5] << 16; - lut_data[3] |= entry.sci[6] << 24; - lut_data[4] |= entry.sci[7]; - lut_data[4] |= entry.vlan_in_clear << 8; + 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; } static nve32_t sc_param_lut_config(struct osi_core_priv_data *const osi_core, @@ -1345,6 +1354,7 @@ static nve32_t sc_param_lut_config(struct osi_core_priv_data *const osi_core, 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) { return -1; @@ -1357,11 +1367,16 @@ static nve32_t sc_param_lut_config(struct osi_core_priv_data *const osi_core, 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 0; + return ret; } static nve32_t lut_config_inputs(struct osi_macsec_lut_config *const lut_config, @@ -1369,16 +1384,16 @@ static nve32_t lut_config_inputs(struct osi_macsec_lut_config *const lut_config, { struct osi_lut_inputs entry = lut_config->lut_in; nveu32_t flags = lut_config->flags; - nve32_t i, j; + nveu32_t i, j = OSI_LUT_FLAGS_BYTE0_PATTERN_VALID; - for (i = 0, j = OSI_LUT_FLAGS_BYTE0_PATTERN_VALID; - i < OSI_LUT_BYTE_PATTERN_MAX; i++, j <<= 1) { + 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) == @@ -1399,7 +1414,7 @@ static nve32_t lut_config_inputs(struct osi_macsec_lut_config *const lut_config, /* MAC DA */ if ((flags & OSI_LUT_FLAGS_DA_BYTE0_VALID) == OSI_LUT_FLAGS_DA_BYTE0_VALID) { - lut_data[0] |= entry.da[0]; + 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; @@ -1407,7 +1422,7 @@ static nve32_t lut_config_inputs(struct osi_macsec_lut_config *const lut_config, if ((flags & OSI_LUT_FLAGS_DA_BYTE1_VALID) == OSI_LUT_FLAGS_DA_BYTE1_VALID) { - lut_data[0] |= entry.da[1] << 8; + 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; @@ -1415,7 +1430,7 @@ static nve32_t lut_config_inputs(struct osi_macsec_lut_config *const lut_config, if ((flags & OSI_LUT_FLAGS_DA_BYTE2_VALID) == OSI_LUT_FLAGS_DA_BYTE2_VALID) { - lut_data[0] |= entry.da[2] << 16; + 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; @@ -1423,7 +1438,7 @@ static nve32_t lut_config_inputs(struct osi_macsec_lut_config *const lut_config, if ((flags & OSI_LUT_FLAGS_DA_BYTE3_VALID) == OSI_LUT_FLAGS_DA_BYTE3_VALID) { - lut_data[0] |= entry.da[3] << 24; + 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; @@ -1431,7 +1446,7 @@ static nve32_t lut_config_inputs(struct osi_macsec_lut_config *const lut_config, if ((flags & OSI_LUT_FLAGS_DA_BYTE4_VALID) == OSI_LUT_FLAGS_DA_BYTE4_VALID) { - lut_data[1] |= entry.da[4]; + 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; @@ -1439,7 +1454,7 @@ static nve32_t lut_config_inputs(struct osi_macsec_lut_config *const lut_config, if ((flags & OSI_LUT_FLAGS_DA_BYTE5_VALID) == OSI_LUT_FLAGS_DA_BYTE5_VALID) { - lut_data[1] |= entry.da[5] << 8; + 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; @@ -1448,7 +1463,7 @@ static nve32_t lut_config_inputs(struct osi_macsec_lut_config *const lut_config, /* MAC SA */ if ((flags & OSI_LUT_FLAGS_SA_BYTE0_VALID) == OSI_LUT_FLAGS_SA_BYTE0_VALID) { - lut_data[1] |= entry.sa[0] << 22; + 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; @@ -1456,8 +1471,8 @@ static nve32_t lut_config_inputs(struct osi_macsec_lut_config *const lut_config, if ((flags & OSI_LUT_FLAGS_SA_BYTE1_VALID) == OSI_LUT_FLAGS_SA_BYTE1_VALID) { - lut_data[1] |= entry.sa[1] << 30; - lut_data[2] |= (entry.sa[1] >> 2); + 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; @@ -1465,7 +1480,7 @@ static nve32_t lut_config_inputs(struct osi_macsec_lut_config *const lut_config, if ((flags & OSI_LUT_FLAGS_SA_BYTE2_VALID) == OSI_LUT_FLAGS_SA_BYTE2_VALID) { - lut_data[2] |= entry.sa[2] << 6; + 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; @@ -1473,7 +1488,7 @@ static nve32_t lut_config_inputs(struct osi_macsec_lut_config *const lut_config, if ((flags & OSI_LUT_FLAGS_SA_BYTE3_VALID) == OSI_LUT_FLAGS_SA_BYTE3_VALID) { - lut_data[2] |= entry.sa[3] << 14; + 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; @@ -1481,7 +1496,7 @@ static nve32_t lut_config_inputs(struct osi_macsec_lut_config *const lut_config, if ((flags & OSI_LUT_FLAGS_SA_BYTE4_VALID) == OSI_LUT_FLAGS_SA_BYTE4_VALID) { - lut_data[2] |= entry.sa[4] << 22; + 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; @@ -1489,8 +1504,8 @@ static nve32_t lut_config_inputs(struct osi_macsec_lut_config *const lut_config, if ((flags & OSI_LUT_FLAGS_SA_BYTE5_VALID) == OSI_LUT_FLAGS_SA_BYTE5_VALID) { - lut_data[2] |= entry.sa[5] << 30; - lut_data[3] |= (entry.sa[5] >> 2); + 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; @@ -1499,8 +1514,8 @@ static nve32_t lut_config_inputs(struct osi_macsec_lut_config *const lut_config, /* Ether type */ if ((flags & OSI_LUT_FLAGS_ETHTYPE_VALID) == OSI_LUT_FLAGS_ETHTYPE_VALID) { - lut_data[3] |= entry.ethtype[0] << 12; - lut_data[3] |= entry.ethtype[1] << 20; + 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; @@ -1535,7 +1550,7 @@ static nve32_t lut_config_inputs(struct osi_macsec_lut_config *const lut_config, /* Byte patterns */ if ((flags & OSI_LUT_FLAGS_BYTE0_PATTERN_VALID) == OSI_LUT_FLAGS_BYTE0_PATTERN_VALID) { - lut_data[4] |= entry.byte_pattern[0] << 15; + 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 { @@ -1543,8 +1558,8 @@ static nve32_t lut_config_inputs(struct osi_macsec_lut_config *const lut_config, } if ((flags & OSI_LUT_FLAGS_BYTE1_PATTERN_VALID) == OSI_LUT_FLAGS_BYTE1_PATTERN_VALID) { - lut_data[4] |= entry.byte_pattern[1] << 30; - lut_data[5] |= entry.byte_pattern[1] >> 2; + 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 { @@ -1553,7 +1568,7 @@ static nve32_t lut_config_inputs(struct osi_macsec_lut_config *const lut_config, if ((flags & OSI_LUT_FLAGS_BYTE2_PATTERN_VALID) == OSI_LUT_FLAGS_BYTE2_PATTERN_VALID) { - lut_data[5] |= entry.byte_pattern[2] << 13; + 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 { @@ -1562,8 +1577,8 @@ static nve32_t lut_config_inputs(struct osi_macsec_lut_config *const lut_config, if ((flags & OSI_LUT_FLAGS_BYTE3_PATTERN_VALID) == OSI_LUT_FLAGS_BYTE3_PATTERN_VALID) { - lut_data[5] |= entry.byte_pattern[3] << 28; - lut_data[6] |= entry.byte_pattern[3] >> 4; + 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 { @@ -1587,7 +1602,7 @@ static nve32_t lut_config_inputs(struct osi_macsec_lut_config *const lut_config, } static nve32_t rx_sci_lut_config( - struct osi_macsec_lut_config *const lut_config, + const struct osi_macsec_lut_config *const lut_config, nveu32_t *const lut_data) { nveu32_t flags = lut_config->flags; @@ -1597,14 +1612,14 @@ static nve32_t rx_sci_lut_config( return -1; } - lut_data[0] |= (entry.sci[0] | - (entry.sci[1] << 8) | - (entry.sci[2] << 16) | - (entry.sci[3] << 24)); - lut_data[1] |= (entry.sci[4] | - (entry.sci[5] << 8) | - (entry.sci[6] << 16) | - (entry.sci[7] << 24)); + 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) == @@ -1672,6 +1687,7 @@ static nve32_t sci_lut_config(struct osi_core_priv_data *const osi_core, 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)) { @@ -1691,13 +1707,13 @@ static nve32_t sci_lut_config(struct osi_core_priv_data *const osi_core, OSI_LUT_FLAGS_ENTRY_VALID) { val = osi_readla(osi_core, addr + MACSEC_TX_SCI_LUT_VALID); - val |= (1 << index); + 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 &= ~(1 << index); + val &= ~((nveu32_t)(1U) << index); osi_writela(osi_core, val, addr + MACSEC_TX_SCI_LUT_VALID); } @@ -1715,13 +1731,13 @@ static nve32_t sci_lut_config(struct osi_core_priv_data *const osi_core, OSI_LUT_FLAGS_ENTRY_VALID) { val = osi_readla(osi_core, addr + MACSEC_RX_SCI_LUT_VALID); - val |= (1 << index); + 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 &= ~(1 << index); + val &= ~((nveu32_t)(1U) << index); osi_writela(osi_core, val, addr + MACSEC_RX_SCI_LUT_VALID); } @@ -1730,9 +1746,10 @@ static nve32_t sci_lut_config(struct osi_core_priv_data *const osi_core, default: OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Unknown controller select\n", 0ULL); - return -1; + ret = -1; + break; } - return 0; + return ret; } static nve32_t byp_lut_config(struct osi_core_priv_data *const osi_core, @@ -1743,6 +1760,7 @@ static nve32_t byp_lut_config(struct osi_core_priv_data *const osi_core, 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, @@ -1773,13 +1791,13 @@ static nve32_t byp_lut_config(struct osi_core_priv_data *const osi_core, OSI_LUT_FLAGS_ENTRY_VALID) { val = osi_readla(osi_core, addr + MACSEC_TX_BYP_LUT_VALID); - val |= (1 << index); + 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 &= ~(1 << index); + val &= ~((nveu32_t)(1U) << (index & 0x1FU)); osi_writela(osi_core, val, addr + MACSEC_TX_BYP_LUT_VALID); } @@ -1790,13 +1808,13 @@ static nve32_t byp_lut_config(struct osi_core_priv_data *const osi_core, OSI_LUT_FLAGS_ENTRY_VALID) { val = osi_readla(osi_core, addr + MACSEC_RX_BYP_LUT_VALID); - val |= (1 << index); + 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 &= ~(1 << index); + val &= ~((nveu32_t)(1U) << (index & 0x1FU)); osi_writela(osi_core, val, addr + MACSEC_RX_BYP_LUT_VALID); } @@ -1805,15 +1823,18 @@ static nve32_t byp_lut_config(struct osi_core_priv_data *const osi_core, default: OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Unknown controller select\n", 0ULL); - return -1; + ret = -1; + break; } - return 0; + return ret; } 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: if (byp_lut_config(osi_core, lut_config) != 0) { @@ -1853,10 +1874,11 @@ static inline nve32_t lut_data_write(struct osi_core_priv_data *const osi_core, default: OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Unsupported LUT\n", 0ULL); - return -1; + ret = -1; + break; } - return 0; + return ret; } static nve32_t macsec_lut_config(struct osi_core_priv_data *const osi_core, @@ -1879,20 +1901,14 @@ static nve32_t macsec_lut_config(struct osi_core_priv_data *const osi_core, 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) { + 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) { + 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); @@ -1904,11 +1920,11 @@ static nve32_t macsec_lut_config(struct osi_core_priv_data *const osi_core, } lut_config_reg &= ~MACSEC_LUT_CONFIG_LUT_SEL_MASK; - lut_config_reg |= (lut_config->lut_sel << + 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 |= (lut_config->table_config.index); + 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); @@ -1919,7 +1935,7 @@ static nve32_t macsec_lut_config(struct osi_core_priv_data *const osi_core, return ret; } - if (!lut_config->table_config.rw) { + if (lut_config->table_config.rw == OSI_NONE) { ret = lut_data_read(osi_core, lut_config); if (ret < 0) { return ret; @@ -1964,8 +1980,10 @@ static inline void handle_tx_sc_invalid_key( } static inline void handle_safety_err_irq( - struct osi_core_priv_data *const osi_core) + 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__); } @@ -2081,6 +2099,9 @@ static inline void handle_dbg_evt_capture_done( 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); } } @@ -2095,28 +2116,28 @@ static inline void handle_tx_irq(struct osi_core_priv_data *const osi_core) 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); - osi_core->macsec_irq_stats.tx_dbg_capture_done++; + 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) { - osi_core->macsec_irq_stats.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) { - osi_core->macsec_irq_stats.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) { - osi_core->macsec_irq_stats.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) { - osi_core->macsec_irq_stats.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) { @@ -2136,17 +2157,17 @@ static inline void handle_tx_irq(struct osi_core_priv_data *const osi_core) } if ((tx_isr & MACSEC_TX_PN_THRSHLD_RCHD) == MACSEC_TX_PN_THRSHLD_RCHD) { - osi_core->macsec_irq_stats.tx_pn_threshold++; + 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) { - osi_core->macsec_irq_stats.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) { + if (clear != OSI_NONE) { osi_writela(osi_core, clear, addr + MACSEC_TX_ISR); } } @@ -2164,12 +2185,12 @@ static inline void handle_rx_irq(struct osi_core_priv_data *const osi_core) 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); - osi_core->macsec_irq_stats.rx_dbg_capture_done++; + 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) { - osi_core->macsec_irq_stats.rx_icv_err_threshold++; + 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) { @@ -2188,23 +2209,23 @@ static inline void handle_rx_irq(struct osi_core_priv_data *const osi_core) } if ((rx_isr & MACSEC_RX_REPLAY_ERROR) == MACSEC_RX_REPLAY_ERROR) { - osi_core->macsec_irq_stats.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) { - osi_core->macsec_irq_stats.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) { - osi_core->macsec_irq_stats.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) { - osi_core->macsec_irq_stats.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) { @@ -2223,11 +2244,11 @@ static inline void handle_rx_irq(struct osi_core_priv_data *const osi_core) } if ((rx_isr & MACSEC_RX_PN_EXHAUSTED) == MACSEC_RX_PN_EXHAUSTED) { - osi_core->macsec_irq_stats.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) { + if (clear != OSI_NONE) { osi_writela(osi_core, clear, addr + MACSEC_RX_ISR); } } @@ -2241,34 +2262,34 @@ static inline void handle_common_irq(struct osi_core_priv_data *const osi_core) LOG("%s(): common_isr 0x%x\n", __func__, common_isr); if ((common_isr & MACSEC_SECURE_REG_VIOL) == MACSEC_SECURE_REG_VIOL) { - osi_core->macsec_irq_stats.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) { - osi_core->macsec_irq_stats.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) { - osi_core->macsec_irq_stats.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) { - osi_core->macsec_irq_stats.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) { - osi_core->macsec_irq_stats.tx_lkup_miss++; + CERT_C__POST_INC__U64(osi_core->macsec_irq_stats.tx_lkup_miss); clear |= MACSEC_TX_LKUP_MISS; } - if (clear) { + if (clear != OSI_NONE) { osi_writela(osi_core, clear, addr + MACSEC_COMMON_ISR); } } @@ -2366,7 +2387,7 @@ static nve32_t clear_lut(struct osi_core_priv_data *const osi_core) struct osi_macsec_kt_config kt_config = {0}; #endif struct osi_macsec_table_config *table_config = &lut_config.table_config; - nveu32_t i, j; + nveu16_t i, j; nve32_t ret = 0; table_config->rw = OSI_LUT_WRITE; @@ -2482,7 +2503,7 @@ static nve32_t clear_lut(struct osi_core_priv_data *const osi_core) static nve32_t macsec_deinit(struct osi_core_priv_data *const osi_core) { nveu32_t i; - struct core_local *l_core = (struct core_local *)osi_core; + 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, @@ -2534,11 +2555,11 @@ static nve32_t macsec_init(struct osi_core_priv_data *const osi_core, nveu32_t val = 0; struct osi_macsec_lut_config lut_config = {0}; struct osi_macsec_table_config *table_config = &lut_config.table_config; - struct core_local *l_core = (struct core_local *)osi_core; + const struct core_local *l_core = (void *)osi_core; /* Store MAC address in reverse, per HW design */ - nveu8_t mac_da_mkpdu[OSI_ETH_ALEN] = {0x3, 0x0, 0x0, + const nveu8_t mac_da_mkpdu[OSI_ETH_ALEN] = {0x3, 0x0, 0x0, 0xC2, 0x80, 0x01}; - nveu8_t mac_da_bc[OSI_ETH_ALEN] = {0xFF, 0xFF, 0xFF, + const nveu8_t mac_da_bc[OSI_ETH_ALEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; nve32_t ret = 0; @@ -2595,15 +2616,6 @@ static nve32_t macsec_init(struct osi_core_priv_data *const osi_core, LOG("Write MACSEC_CONTROL1: 0x%x\n", val); osi_writela(osi_core, val, addr + MACSEC_CONTROL1); - /* set DVLAN tag ethertype */ - - /* val = DVLAN_TAG_ETHERTYPE; - * LOG("Write MACSEC_TX_DVLAN_CONTROL_0: 0x%x\n", val); - * osi_writela(osi_core, val, addr + MACSEC_TX_DVLAN_CONTROL_0); - * LOG("Write MACSEC_RX_DVLAN_CONTROL_0: 0x%x\n", val); - * osi_writela(osi_core, val, addr + MACSEC_RX_DVLAN_CONTROL_0); - */ - val = osi_readla(osi_core, addr + MACSEC_STATS_CONTROL_0); LOG("Read MACSEC_STATS_CONTROL_0: 0x%x\n", val); /* set STATS rollover bit */ @@ -2656,7 +2668,7 @@ static nve32_t macsec_init(struct osi_core_priv_data *const osi_core, 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", ret); + "Invalidating all LUT's failed\n", (nveul64_t)ret); return ret; } @@ -2676,7 +2688,7 @@ static nve32_t macsec_init(struct osi_core_priv_data *const osi_core, 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", ret); + "Failed to set BYP for BC addr\n", (nveul64_t)ret); goto exit; } else { osi_core->macsec_lut_status[i].next_byp_idx++; @@ -2694,7 +2706,7 @@ static nve32_t macsec_init(struct osi_core_priv_data *const osi_core, 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", ret); + "Failed to set BYP for MKPDU multicast DA\n", (nveul64_t)ret); goto exit; } else { @@ -2707,44 +2719,45 @@ exit: } static struct osi_macsec_sc_info *find_existing_sc( - struct osi_core_priv_data *const osi_core, + const 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 = + 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->sc_info[i].sci, sc->sci, - OSI_SCI_LEN) == OSI_NONE) { - return &lut_status->sc_info[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; } -static nveu32_t get_avail_sc_idx(struct osi_core_priv_data *const osi_core, +static nveu32_t get_avail_sc_idx(const struct osi_core_priv_data *const osi_core, nveu16_t ctlr) { - struct osi_macsec_lut_status *lut_status = + 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->sc_info[i].an_valid == OSI_NONE) { + if (lut_status_ptr->sc_info[i].an_valid == OSI_NONE) { return i; } } return i; } -nve32_t macsec_get_sc_lut_key_index(struct osi_core_priv_data *const osi_core, - nveu8_t *sci, nve32_t *key_index, nveu16_t ctlr) +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; - struct osi_macsec_sc_info *sc_info = OSI_NULL; + const struct osi_macsec_sc_info *sc_info = OSI_NULL; + nve32_t ret = 0; /* Validate inputs */ if ((sci == OSI_NULL) || (key_index == OSI_NULL) || @@ -2754,7 +2767,12 @@ nve32_t macsec_get_sc_lut_key_index(struct osi_core_priv_data *const osi_core, return -1; } - osi_memcpy(sc.sci, sci, OSI_SCI_LEN); + 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, @@ -2767,9 +2785,9 @@ nve32_t macsec_get_sc_lut_key_index(struct osi_core_priv_data *const osi_core, } static nve32_t del_upd_sc(struct osi_core_priv_data *const osi_core, - struct osi_macsec_sc_info *existing_sc, - struct osi_macsec_sc_info *const sc, - nveu16_t ctlr, nveu16_t *kt_idx) + 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}; @@ -2792,13 +2810,13 @@ static nve32_t del_upd_sc(struct osi_core_priv_data *const osi_core, if (existing_sc->curr_an == sc->curr_an) { /* 1. SCI LUT */ lut_config.lut_sel = OSI_LUT_SEL_SCI; - table_config->index = existing_sc->sc_idx_start; + 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); - goto err_sci; + return -1; } /* 2. SC Param LUT */ @@ -2806,8 +2824,8 @@ static nve32_t del_upd_sc(struct osi_core_priv_data *const osi_core, 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", ret); - goto err_sc_param; + "Failed to del SC param\n", (nveul64_t)ret); + return -1; } /* 3. SC state LUT */ @@ -2815,24 +2833,25 @@ static nve32_t del_upd_sc(struct osi_core_priv_data *const osi_core, 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", ret); - goto err_sc_state; + "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 = (existing_sc->sc_idx_start * OSI_MAX_NUM_SA) + - sc->curr_an; + 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", ret); - goto err_sa_state; + "Failed to del SA state\n", (nveul64_t)ret); + return -1; } /* Store key table index returned to osd */ - *kt_idx = (existing_sc->sc_idx_start * OSI_MAX_NUM_SA) + sc->curr_an; + *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; @@ -2843,38 +2862,30 @@ static nve32_t del_upd_sc(struct osi_core_priv_data *const osi_core, 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", ret); - goto err_kt; + "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; - -#ifdef MACSEC_KEY_PROGRAM -err_kt: -#endif -err_sa_state: -err_sc_state: -err_sc_param: -err_sci: - return -1; } 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) + const 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, i; + 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 = (sc->sc_idx_start * OSI_MAX_NUM_SA) + sc->curr_an; + *kt_idx = (nveu16_t)(((sc->sc_idx_start & 0xFFU) * OSI_MAX_NUM_SA) + sc->curr_an); #ifdef MACSEC_KEY_PROGRAM /* 1. Key LUT */ @@ -2888,14 +2899,14 @@ static nve32_t add_upd_sc(struct osi_core_priv_data *const osi_core, /* Program in reverse order as per HW design */ for (i = 0; i < OSI_KEY_LEN_128; i++) { - kt_config.entry.sak[i] = sc->sak[OSI_KEY_LEN_128 - 1 - i]; - kt_config.entry.h[i] = sc->hkey[OSI_KEY_LEN_128 - 1 - i]; + kt_config.entry.sak[i] = sc->sak[OSI_KEY_LEN_128 - 1U - i]; + kt_config.entry.h[i] = sc->hkey[OSI_KEY_LEN_128 - 1U - i]; } 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", ret); + "Failed to set SAK\n", (nveul64_t)ret); return -1; } } @@ -2907,24 +2918,25 @@ static nve32_t add_upd_sc(struct osi_core_priv_data *const osi_core, /* 2. SA state LUT */ lut_config.lut_sel = OSI_LUT_SEL_SA_STATE; - table_config->index = (sc->sc_idx_start * OSI_MAX_NUM_SA) + sc->curr_an; + table_config->index = (nveu16_t)((sc->sc_idx_start * 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", ret); + "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 = sc->sc_idx_start; + table_config->index = (nveu16_t)(sc->sc_idx_start); /* Program in reverse order as per HW design */ for (i = 0; i < OSI_SCI_LEN; i++) { - lut_config.sc_param_out.sci[i] = sc->sci[OSI_SCI_LEN - 1 - i]; + lut_config.sc_param_out.sci[i] = sc->sci[OSI_SCI_LEN - 1U - i]; } lut_config.sc_param_out.key_index_start = (sc->sc_idx_start * OSI_MAX_NUM_SA); @@ -2936,23 +2948,23 @@ static nve32_t add_upd_sc(struct osi_core_priv_data *const osi_core, 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", ret); + "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 = sc->sc_idx_start; + table_config->index = (nveu16_t)(sc->sc_idx_start); /* Program in reverse order as per HW design */ for (i = 0; i < OSI_ETH_ALEN; i++) { /* Extract the mac sa from the SCI itself */ - lut_config.lut_in.sa[i] = sc->sci[OSI_ETH_ALEN - 1 - i]; + lut_config.lut_in.sa[i] = sc->sci[OSI_ETH_ALEN - 1U - i]; } 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 - 1 - 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; @@ -2960,7 +2972,7 @@ static nve32_t add_upd_sc(struct osi_core_priv_data *const osi_core, 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", ret); + "Failed to set SCI LUT\n", (nveul64_t)ret); goto err_sci; } @@ -2968,12 +2980,12 @@ static nve32_t add_upd_sc(struct osi_core_priv_data *const osi_core, /* 5. SC state LUT */ lut_config.flags = OSI_NONE; lut_config.lut_sel = OSI_LUT_SEL_SC_STATE; - table_config->index = sc->sc_idx_start; + 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", ret); + "Failed to set SC state\n", (nveul64_t)ret); goto err_sc_state; } } @@ -2986,11 +2998,11 @@ err_sc_state: table_config->ctlr_sel = ctlr; table_config->rw = OSI_LUT_WRITE; lut_config.lut_sel = OSI_LUT_SEL_SCI; - table_config->index = sc->sc_idx_start; + table_config->index = (nveu16_t)(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 set SCI LUT\n", ret); + "Failed to set SCI LUT\n", (nveul64_t)ret); } err_sci: @@ -2999,11 +3011,11 @@ err_sci: table_config = &lut_config.table_config; table_config->ctlr_sel = ctlr; lut_config.lut_sel = OSI_LUT_SEL_SC_PARAM; - table_config->index = sc->sc_idx_start; + table_config->index = (nveu16_t)(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 set SC param LUT\n", ret); + "Failed to set SC param LUT\n", (nveul64_t)ret); } err_sc_param: @@ -3013,11 +3025,11 @@ err_sc_param: table_config->ctlr_sel = ctlr; table_config->rw = OSI_LUT_WRITE; lut_config.lut_sel = OSI_LUT_SEL_SA_STATE; - table_config->index = (sc->sc_idx_start * OSI_MAX_NUM_SA) + sc->curr_an; + table_config->index = (nveu16_t)((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 set SA state LUT\n", ret); + "Failed to set SA state LUT\n", (nveul64_t)ret); } err_sa_state: @@ -3030,14 +3042,14 @@ err_sa_state: 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", ret); + "Failed to set SAK\n", (nveul64_t)ret); } #endif /* MACSEC_KEY_PROGRAM */ return -1; } -static nve32_t macsec_config(struct osi_core_priv_data *const osi_core, +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) @@ -3045,17 +3057,18 @@ static nve32_t macsec_config(struct osi_core_priv_data *const osi_core, struct osi_macsec_sc_info *existing_sc = OSI_NULL, *new_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; - nve32_t avail_sc_idx = 0; + struct osi_macsec_lut_status *lut_status_ptr; + nveu32_t avail_sc_idx = 0; + nve32_t ret = 0; /* Validate inputs */ - if ((enable != OSI_ENABLE && enable != OSI_DISABLE) || - (ctlr != OSI_CTLR_SEL_TX && ctlr != OSI_CTLR_SEL_RX) || + if (((enable != OSI_ENABLE) && (enable != OSI_DISABLE)) || + ((ctlr != OSI_CTLR_SEL_TX) && (ctlr != OSI_CTLR_SEL_RX)) || (kt_idx == OSI_NULL)) { return -1; } - lut_status = &osi_core->macsec_lut_status[ctlr]; + 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) { @@ -3066,7 +3079,7 @@ static nve32_t macsec_config(struct osi_core_priv_data *const osi_core, return -1; } else { LOG("%s: Adding new SC/SA: ctlr: %hu", __func__, ctlr); - if (lut_status->num_of_sc_used >= OSI_MAX_NUM_SC) { + 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; @@ -3078,11 +3091,26 @@ static nve32_t macsec_config(struct osi_core_priv_data *const osi_core, "Err: NO free SC Index\n", 0ULL); return -1; } - new_sc = &lut_status->sc_info[avail_sc_idx]; - osi_memcpy(new_sc->sci, sc->sci, OSI_SCI_LEN); - osi_memcpy(new_sc->sak, sc->sak, OSI_KEY_LEN_128); + new_sc = &lut_status_ptr->sc_info[avail_sc_idx]; + ret = osi_memcpy(new_sc->sci, sc->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; + } + ret = osi_memcpy(new_sc->sak, sc->sak, OSI_KEY_LEN_128); + if (ret < OSI_NONE_SIGNED) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "memcpy Failed\n", 0ULL); + return -1; + } #ifdef MACSEC_KEY_PROGRAM - osi_memcpy(new_sc->hkey, sc->hkey, OSI_KEY_LEN_128); + ret = osi_memcpy(new_sc->hkey, sc->hkey, OSI_KEY_LEN_128); + if (ret < OSI_NONE_SIGNED) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "memcpy Failed\n", 0ULL); + return -1; + } #endif /* MACSEC_KEY_PROGRAM */ new_sc->curr_an = sc->curr_an; new_sc->next_pn = sc->next_pn; @@ -3093,17 +3121,17 @@ static nve32_t macsec_config(struct osi_core_priv_data *const osi_core, new_sc->an_valid |= OSI_BIT(sc->curr_an); if (add_upd_sc(osi_core, new_sc, ctlr, kt_idx) != - OSI_NONE) { + 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->num_of_sc_used++; + lut_status_ptr->num_of_sc_used++; LOG("%s: Added new SC ctlr: %u " "Total active SCs: %u", __func__, ctlr, - lut_status->num_of_sc_used); + lut_status_ptr->num_of_sc_used); return 0; } } @@ -3112,13 +3140,14 @@ static nve32_t macsec_config(struct osi_core_priv_data *const osi_core, if (enable == OSI_DISABLE) { LOG("%s: Deleting existing SA", __func__); if (del_upd_sc(osi_core, existing_sc, sc, ctlr, kt_idx) != - OSI_NONE) { + 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->num_of_sc_used--; + 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)); } @@ -3131,19 +3160,29 @@ static nve32_t macsec_config(struct osi_core_priv_data *const osi_core, * programmed successfully */ *tmp_sc_p = *existing_sc; - osi_memcpy(tmp_sc_p->sak, sc->sak, OSI_KEY_LEN_128); + ret = osi_memcpy(tmp_sc_p->sak, sc->sak, OSI_KEY_LEN_128); + if (ret < OSI_NONE_SIGNED) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "memcpy Failed\n", 0ULL); + return -1; + } #ifdef MACSEC_KEY_PROGRAM - osi_memcpy(tmp_sc_p->hkey, sc->hkey, OSI_KEY_LEN_128); + ret = osi_memcpy(tmp_sc_p->hkey, sc->hkey, OSI_KEY_LEN_128); + if (ret < OSI_NONE_SIGNED) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "memcpy Failed\n", 0ULL); + return -1; + } #endif /* MACSEC_KEY_PROGRAM */ 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); + 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) { + OSI_NONE_SIGNED) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "failed to add new SA\n", 0ULL); return -1; @@ -3151,46 +3190,44 @@ static nve32_t macsec_config(struct osi_core_priv_data *const osi_core, LOG("%s: Updated new SC ctlr: %u " "Total active SCs: %u", __func__, ctlr, - lut_status->num_of_sc_used); + lut_status_ptr->num_of_sc_used); /* Now commit the changes */ *existing_sc = *tmp_sc_p; return 0; } } - return -1; } } -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 = macsec_config, - .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_sc_lut_key_index, - .update_mtu = macsec_update_mtu, -}; - /** * @brief if_ops - Static core interface operations for virtual * case */ -static struct osi_macsec_core_ops virt_macsec_ops; - -static struct osi_macsec_lut_status lut_status[OSI_NUM_CTLR]; 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_lut_status lut_status[OSI_NUM_CTLR]; + 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); @@ -3207,8 +3244,8 @@ nve32_t osi_init_macsec_ops(struct osi_core_priv_data *const osi_core) 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) { + 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); } @@ -3217,8 +3254,8 @@ nve32_t osi_macsec_init(struct osi_core_priv_data *const osi_core, 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) { + 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; @@ -3226,25 +3263,25 @@ nve32_t osi_macsec_deinit(struct osi_core_priv_data *const osi_core) 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) { + 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); } } 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) { + 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); } } -nve32_t osi_macsec_lut_config(struct osi_core_priv_data *const osi_core, +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) { + 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); } @@ -3252,11 +3289,11 @@ nve32_t osi_macsec_lut_config(struct osi_core_priv_data *const osi_core, } nve32_t osi_macsec_get_sc_lut_key_index(struct osi_core_priv_data *const osi_core, - nveu8_t *sci, nve32_t *key_index, + 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) { + 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); } @@ -3276,12 +3313,12 @@ nve32_t osi_macsec_update_mtu(struct osi_core_priv_data *const osi_core, } #ifdef MACSEC_KEY_PROGRAM -nve32_t osi_macsec_kt_config(struct osi_core_priv_data *const osi_core, +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) { + 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); } @@ -3292,8 +3329,8 @@ nve32_t osi_macsec_kt_config(struct osi_core_priv_data *const osi_core, 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) { + 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); } @@ -3304,8 +3341,8 @@ 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) { + 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); } @@ -3321,8 +3358,8 @@ nve32_t osi_macsec_en(struct osi_core_priv_data *const osi_core, return -1; } - if (osi_core != OSI_NULL && osi_core->macsec_ops != OSI_NULL && - osi_core->macsec_ops->macsec_en != OSI_NULL) { + 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); } @@ -3334,14 +3371,14 @@ nve32_t osi_macsec_config(struct osi_core_priv_data *const osi_core, nveu32_t enable, nveu16_t ctlr, nveu16_t *kt_idx) { - if ((enable != OSI_ENABLE && enable != OSI_DISABLE) || - (ctlr != OSI_CTLR_SEL_TX && ctlr != OSI_CTLR_SEL_RX) || + if (((enable != OSI_ENABLE) && (enable != OSI_DISABLE)) || + ((ctlr != OSI_CTLR_SEL_TX) && (ctlr != OSI_CTLR_SEL_RX)) || (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) { + 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); } @@ -3351,8 +3388,8 @@ nve32_t osi_macsec_config(struct osi_core_priv_data *const osi_core, 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) { + 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; } @@ -3360,13 +3397,13 @@ nve32_t osi_macsec_read_mmc(struct osi_core_priv_data *const osi_core) return -1; } -nve32_t osi_macsec_dbg_buf_config( +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) { + 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); } @@ -3379,8 +3416,8 @@ nve32_t osi_macsec_dbg_events_config( 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) { + 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); } diff --git a/osi/core/macsec.h b/osi/core/macsec.h index a1b7531..6470076 100644 --- a/osi/core/macsec.h +++ b/osi/core/macsec.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -31,6 +31,17 @@ #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 * @@ -38,14 +49,12 @@ * @{ */ #define MACSEC_GCM_KEYTABLE_CONFIG 0x0000 -#define MACSEC_GCM_KEYTABLE_DATA(x) (0x0004 + (x * 4)) -#define MACSEC_RX_ICV_ERR_CNTRL 0x4000 +#define MACSEC_GCM_KEYTABLE_DATA(x) ((0x0004U) + ((x) * 4U)) #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_INTERRUPT_MASK1_0 0x40A0 #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 @@ -55,45 +64,26 @@ #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_CONFIG 0x9000 #define MACSEC_STATS_CONTROL_0 0x900C #define MACSEC_TX_PKTS_UNTG_LO_0 0x9010 -#define MACSEC_TX_PKTS_UNTG_HI_0 0x9014 #define MACSEC_TX_OCTETS_PRTCTD_LO_0 0x9018 -#define MACSEC_TX_OCTETS_PRTCTD_HI_0 0x901C #define MACSEC_TX_PKTS_TOO_LONG_LO_0 0x9020 -#define MACSEC_TX_PKTS_TOO_LONG_HI_0 0x9024 -#define MACSEC_TX_PKTS_PROTECTED_SCx_LO_0(x) (0x9028 + (x * 8)) -#define MACSEC_TX_PKTS_PROTECTED_SCx_HI_0(x) (0x902C + (x * 8)) +#define MACSEC_TX_PKTS_PROTECTED_SCx_LO_0(x) ((0x9028UL) + ((x) * 8UL)) #define MACSEC_RX_PKTS_NOTG_LO_0 0x90B0 -#define MACSEC_RX_PKTS_NOTG_HI_0 0x90B4 #define MACSEC_RX_PKTS_UNTG_LO_0 0x90A8 -#define MACSEC_RX_PKTS_UNTG_HI_0 0x90AC #define MACSEC_RX_PKTS_BADTAG_LO_0 0x90B8 -#define MACSEC_RX_PKTS_BADTAG_HI_0 0x90BC #define MACSEC_RX_PKTS_NOSA_LO_0 0x90C0 -#define MACSEC_RX_PKTS_NOSA_HI_0 0x90C4 #define MACSEC_RX_PKTS_NOSAERROR_LO_0 0x90C8 -#define MACSEC_RX_PKTS_NOSAERROR_HI_0 0x90CC #define MACSEC_RX_PKTS_OVRRUN_LO_0 0x90D0 -#define MACSEC_RX_PKTS_OVRRUN_HI_0 0x90D4 #define MACSEC_RX_OCTETS_VLDTD_LO_0 0x90D8 -#define MACSEC_RX_OCTETS_VLDTD_HI_0 0x90DC -#define MACSEC_RX_PKTS_LATE_SCx_LO_0(x) (0x90E0 + (x * 8)) -#define MACSEC_RX_PKTS_LATE_SCx_HI_0(x) (0x90E4 + (x * 8)) -#define MACSEC_RX_PKTS_NOTVALID_SCx_LO_0(x) (0x9160 + (x * 8)) -#define MACSEC_RX_PKTS_NOTVALID_SCx_HI_0(x) (0x9164 + (x * 8)) -#define MACSEC_RX_PKTS_OK_SCx_LO_0(x) (0x91E0 + (x * 8)) -#define MACSEC_RX_PKTS_OK_SCx_HI_0(x) (0x91E4 + (x * 8)) +#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_TX_INPKTS_CRCIN_NOTVALID_LO_0 0x9260 -#define MACSEC_TX_INPKTS_CRCIN_NOTVALID_HI_0 0x9264 -#define MACSEC_RX_INPKTS_CRCIN_NOTVALID_LO_0 0x9268 -#define MACSEC_RX_INPKTS_CRCIN_NOTVALID_HI_0 0x926C #define MACSEC_CONTROL0 0xD000 #define MACSEC_LUT_CONFIG 0xD004 -#define MACSEC_LUT_DATA(x) (0xD008 + (x * 4)) +#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 @@ -110,7 +100,7 @@ #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) (0xD0CC + (x * 4)) +#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 @@ -121,8 +111,6 @@ #define MACSEC_TX_SOT_DELAY 0xE010 #define MACSEC_RX_MTU_LEN 0xE014 #define MACSEC_RX_SOT_DELAY 0xE01C -#define MACSEC_TX_DVLAN_CONTROL_0 0xE00C -#define MACSEC_RX_DVLAN_CONTROL_0 0xE018 /** @} */ /** @@ -145,9 +133,9 @@ * @brief Bit definitions of MACSEC_GCM_KEYTABLE_DATA register & helpful macros * @{ */ -#define MACSEC_KT_DATA_REG_CNT 13 -#define MACSEC_KT_DATA_REG_SAK_CNT 8 -#define MACSEC_KT_DATA_REG_H_CNT 4 +#define MACSEC_KT_DATA_REG_CNT 13U +#define MACSEC_KT_DATA_REG_SAK_CNT 8U +#define MACSEC_KT_DATA_REG_H_CNT 4U /** @} */ /** @@ -185,9 +173,7 @@ #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_DIS 0x0 #define MACSEC_VALIDATE_FRAMES_STRICT OSI_BIT(22) -#define MACSEC_VALIDATE_FRAMES_CHECK OSI_BIT(21) #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) @@ -214,10 +200,10 @@ * @{ */ #define MACSEC_RX_AES_MODE_MASK (OSI_BIT(17) | OSI_BIT(16)) -#define MACSEC_RX_AES_MODE_AES128 0x0 +#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 0x0 +#define MACSEC_TX_AES_MODE_AES128 0x0U #define MACSEC_TX_AES_MODE_AES256 OSI_BIT(1) /** @} */ @@ -264,15 +250,6 @@ #define MACSEC_RX_PN_EXHAUSTED_INT_EN OSI_BIT(1) /** @} */ -/** - * @addtogroup MACSEC_INTERRUPT_MASK1_0 register - * - * @brief Bit definitions of MACSEC_INTERRUPT_MASK1_0 register - * @{ - */ -#define MACSEC_SFTY_ERR_UNCORR_INT_EN OSI_BIT(0) -/** @} */ - /** * @addtogroup MACSEC_COMMON_ISR register * @@ -322,10 +299,7 @@ * @brief Bit definitions of MACSEC_STATS_CONTROL_0 register * @{ */ -#define MACSEC_STATS_CONTROL0_RD_CPY OSI_BIT(3) -#define MACSEC_STATS_CONTROL0_TK_CPY OSI_BIT(2) #define MACSEC_STATS_CONTROL0_CNT_RL_OVR_CPY OSI_BIT(1) -#define MACSEC_STATS_CONTROL0_CNT_CLR OSI_BIT(0) /** @} */ /** @@ -350,35 +324,11 @@ #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_DATA_MATCH OSI_BIT(7) -#define MACSEC_TX_DBG_LKUP_MATCH OSI_BIT(6) -#define MACSEC_TX_DBG_CRCOUT_MATCH OSI_BIT(5) -#define MACSEC_TX_DBG_CRCIN_MATCH OSI_BIT(4) -#define MACSEC_TX_DBG_ICV_MATCH OSI_BIT(3) #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_TX_DEBUG_STATUS_0 register - * - * @brief Bit definitions of MACSEC_TX_DEBUG_STATUS_0 register - * @{ - */ -#define MACSEC_TX_DBG_STS_CAPTURE OSI_BIT(10) -#define MACSEC_TX_DBG_STS_ICV_CORRUPT OSI_BIT(9) -#define MACSEC_TX_DBG_STS_CRC_CORRUPT OSI_BIT(8) -#define MACSEC_TX_DBG_STS_DATA_MATCH OSI_BIT(7) -#define MACSEC_TX_DBG_STS_LKUP_MATCH OSI_BIT(6) -#define MACSEC_TX_DBG_STS_CRCOUT_MATCH OSI_BIT(5) -#define MACSEC_TX_DBG_STS_CRCIN_MATCH OSI_BIT(4) -#define MACSEC_TX_DBG_STS_ICV_MATCH OSI_BIT(3) -#define MACSEC_TX_DBG_STS_KEY_NOT_VALID OSI_BIT(2) -#define MACSEC_TX_DBG_STS_AN_NOT_VALID OSI_BIT(1) -#define MACSEC_TX_DBG_STS_LKUP_MISS OSI_BIT(0) -/** @} */ - /** * @addtogroup MACSEC_RX_DEBUG_TRIGGER_EN_0 register * @@ -388,33 +338,11 @@ #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_DATA_MATCH OSI_BIT(7) -#define MACSEC_RX_DBG_BYP_LKUP_MATCH OSI_BIT(6) -#define MACSEC_RX_DBG_CRCOUT_MATCH OSI_BIT(5) -#define MACSEC_RX_DBG_CRCIN_MATCH OSI_BIT(4) #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_RX_DEBUG_STATUS_0 register - * - * @brief Bit definitions of MACSEC_RX_DEBUG_STATUS_0 register - * @{ - */ -#define MACSEC_RX_DBG_STS_CAPTURE OSI_BIT(10) -#define MACSEC_RX_DBG_STS_ICV_ERROR OSI_BIT(9) -#define MACSEC_RX_DBG_STS_CRC_CORRUPT OSI_BIT(8) -#define MACSEC_RX_DBG_STS_DATA_MATCH OSI_BIT(7) -#define MACSEC_RX_DBG_STS_BYP_LKUP_MATCH OSI_BIT(6) -#define MACSEC_RX_DBG_STS_CRCOUT_MATCH OSI_BIT(5) -#define MACSEC_RX_DBG_STS_CRCIN_MATCH OSI_BIT(4) -#define MACSEC_RX_DBG_STS_REPLAY_ERR OSI_BIT(3) -#define MACSEC_RX_DBG_STS_KEY_NOT_VALID OSI_BIT(2) -#define MACSEC_RX_DBG_STS_LKUP_MISS OSI_BIT(0) -/** @} */ - /** * @addtogroup MACSEC_TX_DEBUG_CONTROL_0 register * @@ -433,11 +361,9 @@ #define MACSEC_RX_DEBUG_CONTROL_0_START_CAP OSI_BIT(31) /** @} */ -#define MTU_LENGTH_MASK 0xFFFF -#define MTU_ADDONS (8 + 14 + 4) -#define DVLAN_TAG_ETHERTYPE 0x88A8 -#define SOT_LENGTH_MASK 0xFF -#define EQOS_MACSEC_SOT_DELAY 0x4E +#define MTU_LENGTH_MASK 0xFFFFU +#define SOT_LENGTH_MASK 0xFFU +#define EQOS_MACSEC_SOT_DELAY 0x4EU /** * @addtogroup TX/RX_BYP/SCI_LUT_VALID register @@ -445,14 +371,6 @@ * @brief Bit definitions of LUT_VALID registers * @{ */ -#define MACSEC_TX_BYP_LUT_VALID_ENTRY(x) OSI_BIT(x) -#define MACSEC_TX_BYP_LUT_VALID_NONE 0x0 -#define MACSEC_TX_SCI_LUT_VALID_ENTRY(x) OSI_BIT(x) -#define MACSEC_TX_SCI_LUT_VALID_NONE 0x0 -#define MACSEC_RX_BYP_LUT_VALID_ENTRY(x) OSI_BIT(x) -#define MACSEC_RX_BYP_LUT_VALID_NONE 0x0 -#define MACSEC_RX_SCI_LUT_VALID_ENTRY(x) OSI_BIT(x) -#define MACSEC_RX_SCI_LUT_VALID_NONE 0x0 /** @} */ /** @@ -461,7 +379,7 @@ * @brief Helper macros for LUT data programming * @{ */ -#define MACSEC_LUT_DATA_REG_CNT 7 +#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) diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 008bd3c..8668149 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -6132,11 +6132,12 @@ static void mgbe_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, * - Run time: Yes * - De-initialization: No */ -void mgbe_config_for_macsec(struct osi_core_priv_data *const osi_core, +static void mgbe_config_for_macsec(struct osi_core_priv_data *const osi_core, const nveu32_t enable) { - nveu32_t value = 0U; - if (enable != OSI_ENABLE && enable != OSI_DISABLE) { + 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; @@ -6180,20 +6181,20 @@ void mgbe_config_for_macsec(struct osi_core_priv_data *const osi_core, /* Program MTL_EST depending on MACSEC enable/disable */ if (osi_core->hw_feature->est_sel == OSI_ENABLE) { value = osi_readla(osi_core, - (unsigned char *)osi_core->base + + (nveu8_t *)osi_core->base + MGBE_MTL_EST_CONTROL); value &= ~MGBE_MTL_EST_CONTROL_CTOV; if (enable == OSI_ENABLE) { - value |= (MGBE_MTL_EST_CTOV_MACSEC_RECOMMEND << - MGBE_MTL_EST_CONTROL_CTOV_SHIFT) & - MGBE_MTL_EST_CONTROL_CTOV; + temp = MGBE_MTL_EST_CTOV_MACSEC_RECOMMEND; + temp = temp << MGBE_MTL_EST_CONTROL_CTOV_SHIFT; + value |= temp & MGBE_MTL_EST_CONTROL_CTOV; } else { - value |= (MGBE_MTL_EST_CTOV_RECOMMEND << - MGBE_MTL_EST_CONTROL_CTOV_SHIFT) & - MGBE_MTL_EST_CONTROL_CTOV; + 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, - (unsigned char *)osi_core->base + + (nveu8_t *)osi_core->base + MGBE_MTL_EST_CONTROL); } else { OSI_CORE_ERR(osi_core->osd, From 159887b46c87957f07069d41b808681d2d0574f1 Mon Sep 17 00:00:00 2001 From: Om Prakash Singh <omp@nvidia.com> Date: Tue, 12 Apr 2022 20:30:28 +0530 Subject: [PATCH 334/458] osi: macsec: set ICV error threshold to 1 Issue: default IVC error threshoud 16k. Which is not same as Other error like RX/TX CRC error. It is conflicting with expection of DT based error reporting threshold "nvidia,hsi_err_count_threshold" Fix: Set ICV error threshold to 1 to match the other error interrupt frequnecy. Bug 3543410 Change-Id: Ic64fcdaa007e9a57823515dc8f970d636b34eaa1 Signed-off-by: Om Prakash Singh <omp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2696380 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Sanath Kumar Gampa <sgampa@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/macsec.c | 3 +++ osi/core/macsec.h | 1 + 2 files changed, 4 insertions(+) diff --git a/osi/core/macsec.c b/osi/core/macsec.c index 726b87c..d8070f7 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -2636,6 +2636,9 @@ static nve32_t macsec_init(struct osi_core_priv_data *const osi_core, 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); diff --git a/osi/core/macsec.h b/osi/core/macsec.h index 6470076..7d027d0 100644 --- a/osi/core/macsec.h +++ b/osi/core/macsec.h @@ -50,6 +50,7 @@ */ #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 From c63626c987512ba8555b925f8276bd5f208f466c Mon Sep 17 00:00:00 2001 From: Sanath Kumar Gampa <sgampa@nvidia.com> Date: Thu, 31 Mar 2022 19:28:27 +0530 Subject: [PATCH 335/458] osi:macsec: Separate lut_status for each IP Issue: If macsec is created on EQOS and then created on MGBE, we are over writing the lut_status of EQOS with MGBE lut_status. Fix: Create different lut_status structure in osi_core so that each IP will have its own lut_status structure. Bug 3587231 Change-Id: I826c3d210ed18350140f1cbcb41b748550f92844 Signed-off-by: Sanath Kumar Gampa <sgampa@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2690839 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_core.h | 57 +++++++++++++++++++++++++++++++++++++++++++- include/osi_macsec.h | 47 ++---------------------------------- osi/core/macsec.c | 5 +--- 3 files changed, 59 insertions(+), 50 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 40b95f4..e7b84ae 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -48,6 +48,21 @@ typedef my_uint16_t nveu16_t; 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 * @@ -1104,6 +1119,46 @@ struct osd_core_ops { }; #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. */ @@ -1323,7 +1378,7 @@ struct osi_core_priv_data { /** 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; + struct osi_macsec_lut_status macsec_lut_status[OSI_NUM_CTLR]; /** macsec mmc counters */ struct osi_macsec_mmc_counters macsec_mmc; /** MACSEC enabled state */ diff --git a/include/osi_macsec.h b/include/osi_macsec.h index af6efb2..8d35f33 100644 --- a/include/osi_macsec.h +++ b/include/osi_macsec.h @@ -25,6 +25,7 @@ #include <osi_core.h> +#ifdef MACSEC_SUPPORT ////////////////////////////////////////////////////////////////////////// /* MACSEC OSI data structures */ ////////////////////////////////////////////////////////////////////////// @@ -35,14 +36,10 @@ * @brief Helper macros for LUT programming * @{ */ -#define OSI_SCI_LEN 8U -#define OSI_KEY_LEN_128 16U -#define OSI_KEY_LEN_256 32U #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_SC 8U #define OSI_MAX_NUM_SA 4U #define OSI_CURR_AN_MAX 3 #define OSI_KEY_INDEX_MAX 31U @@ -108,7 +105,6 @@ #define OSI_CTLR_SEL_TX 0U #define OSI_CTLR_SEL_RX 1U #define OSI_CTLR_SEL_MAX 1U -#define OSI_NUM_CTLR 2U #define OSI_LUT_READ 0U #define OSI_LUT_WRITE 1U #define OSI_RW_MAX 1U @@ -272,46 +268,6 @@ struct osi_lut_inputs { nveu32_t vlan_id; }; -/** - * @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 LUT config data structure */ @@ -1000,4 +956,5 @@ nve32_t osi_macsec_get_sc_lut_key_index( 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/core/macsec.c b/osi/core/macsec.c index d8070f7..6d89ac0 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -2722,7 +2722,7 @@ exit: } static struct osi_macsec_sc_info *find_existing_sc( - const struct osi_core_priv_data *const osi_core, + struct osi_core_priv_data *const osi_core, struct osi_macsec_sc_info *const sc, nveu16_t ctlr) { @@ -3206,11 +3206,9 @@ static nve32_t config_macsec(struct osi_core_priv_data *const osi_core, * @brief if_ops - Static core interface operations for virtual * case */ - 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_lut_status lut_status[OSI_NUM_CTLR]; static struct osi_macsec_core_ops macsec_ops = { .init = macsec_init, .deinit = macsec_deinit, @@ -3240,7 +3238,6 @@ nve32_t osi_init_macsec_ops(struct osi_core_priv_data *const osi_core) } osi_core->macsec_ops = &macsec_ops; } - osi_core->macsec_lut_status = lut_status; return 0; } From f9782a6641cf446f9224d6306bb43df988b7edbb Mon Sep 17 00:00:00 2001 From: Nagaraj Annaiah <nannaiah@nvidia.com> Date: Tue, 15 Feb 2022 08:28:27 +0000 Subject: [PATCH 336/458] osi core: Fix compiler warnings for HVRTOS Issue: Unused variables are treated as errors with HVRTOS compiler. Fix: 1. Add unused attributes macro for unused function arguments. 2. Fix typecast errors. 3. Add flag to check if ethernet server status, this is needed to skip check for function pointer validation. Bug 3562777 Change-Id: I0a4a36fb330c580d1879f46304842c610e62316c Signed-off-by: Nagaraj Annaiah <nannaiah@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2670097 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_common.h | 5 +++++ include/osi_core.h | 8 ++++---- include/osi_dma.h | 2 ++ osi/common/common.h | 10 ++-------- osi/core/core_local.h | 3 --- osi/core/eqos_core.c | 24 +----------------------- osi/core/frp.c | 24 ++++++++++++------------ osi/core/ivc_core.c | 13 ++++++++----- osi/core/macsec.c | 4 ++++ osi/core/mgbe_core.c | 41 ++++++++++++++++------------------------- osi/core/osi_hal.c | 10 +++++----- osi/core/vlan_filter.c | 18 +++++++++--------- osi/dma/eqos_desc.c | 4 ++-- osi/dma/mgbe_dma.c | 5 +++-- osi/dma/osi_dma.c | 14 ++++++++------ 15 files changed, 81 insertions(+), 104 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index a6497bc..0c3a75f 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -287,6 +287,11 @@ /** @} */ #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 diff --git a/include/osi_core.h b/include/osi_core.h index e7b84ae..2c146d0 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -176,10 +176,10 @@ typedef my_lint_64 nvel64_t; /** * @brief Ethernet PHY Interface Modes */ -#define OSI_XFI_MODE_10G 0 -#define OSI_XFI_MODE_5G 1 -#define OSI_USXGMII_MODE_10G 2 -#define OSI_USXGMII_MODE_5G 3 +#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 diff --git a/include/osi_dma.h b/include/osi_dma.h index c7a800f..d95c51b 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -597,6 +597,8 @@ struct osi_dma_priv_data { /** 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; }; /** diff --git a/osi/common/common.h b/osi/common/common.h index af7052f..d2b9082 100644 --- a/osi/common/common.h +++ b/osi/common/common.h @@ -191,11 +191,6 @@ static inline void osi_writel(nveu32_t val, void *addr) *(volatile nveu32_t *)addr = val; } -#ifdef ETHERNET_SERVER -nveu32_t osi_readla(void *priv, void *addr); - -void osi_writela(void *priv, nveu32_t val, void *addr); -#else /** * @brief osi_readla - Read a memory mapped register. * @@ -211,7 +206,7 @@ void osi_writela(void *priv, nveu32_t val, void *addr); * * @return Data from memory mapped register - success. */ -static inline nveu32_t osi_readla(void *priv, void *addr) +static inline nveu32_t osi_readla(OSI_UNUSED void *priv, void *addr) { return *(volatile nveu32_t *)addr; } @@ -230,11 +225,10 @@ static inline nveu32_t osi_readla(void *priv, void *addr) * * @note Physical address has to be memmory mapped. */ -static inline void osi_writela(void *priv, nveu32_t val, void *addr) +static inline void osi_writela(OSI_UNUSED void *priv, nveu32_t val, void *addr) { *(volatile nveu32_t *)addr = val; } -#endif /** * @brief validate_mac_ver_update_chans - Validates mac version and update chan diff --git a/osi/core/core_local.h b/osi/core/core_local.h index cd3f416..9534a9e 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -230,9 +230,6 @@ struct core_ops { const nveu32_t filter_enb_dis, const nveu32_t perfect_hash_filtering, const nveu32_t perfect_inverse_match); - /** called to update VLAN id */ - nve32_t (*update_vlan_id)(struct osi_core_priv_data *const osi_core, - const nveu32_t vid); /** Called to reset MMC HW counter structure */ void (*reset_mmc)(struct osi_core_priv_data *const osi_core); /** Called to configure EEE Tx LPI */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 13368eb..949df0d 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -3266,7 +3266,7 @@ static inline nve32_t eqos_update_mac_addr_helper( const nveu32_t idx, const nveu32_t dma_chan, const nveu32_t addr_mask, - const nveu32_t src_dest) + OSI_UNUSED const nveu32_t src_dest) { nveu32_t temp; @@ -6081,27 +6081,6 @@ static nve32_t eqos_config_vlan_filtering( return 0; } -/** - * @brief eqos_update_vlan_id - update VLAN ID in Tag register - * - * @param[in] osi_core: OSI core priv data structure - * @param[in] vid: VLAN ID to be programmed. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 always - */ -static inline nve32_t eqos_update_vlan_id( - struct osi_core_priv_data *const osi_core, - nveu32_t const vid) -{ - return 0; -} - /** * @brief eqos_configure_eee - Configure the EEE LPI mode * @@ -6926,7 +6905,6 @@ void eqos_init_core_ops(struct core_ops *ops) 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->update_vlan_id = eqos_update_vlan_id; ops->reset_mmc = eqos_reset_mmc; ops->configure_eee = eqos_configure_eee; ops->save_registers = eqos_save_registers; diff --git a/osi/core/frp.c b/osi/core/frp.c index 44217cc..4b0c953 100644 --- a/osi/core/frp.c +++ b/osi/core/frp.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -80,7 +80,7 @@ static int frp_entry_find(struct osi_core_priv_data *const osi_core, found = OSI_ENABLE; } else { /* Increment entries */ - *no_entries = *no_entries + 1U; + *no_entries = (unsigned char) (*no_entries + 1U); } } } @@ -117,18 +117,18 @@ static unsigned char frp_req_entries(unsigned char offset, } /* Check does the given length can fit in fist entry */ - if (match_length <= FRP_OFFSET_BYTES(offset)) { + 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 -= FRP_OFFSET_BYTES(offset); + match_length = (unsigned char) (match_length - (unsigned char) FRP_OFFSET_BYTES(offset)); if ((match_length / FRP_MD_SIZE) < OSI_FRP_MATCH_DATA_MAX) { - req += (match_length / FRP_MD_SIZE); + req = (unsigned char) (req + (match_length / FRP_MD_SIZE)); if ((match_length % FRP_MD_SIZE) != OSI_NONE) { /* Need one more entry */ - req += 1U; + req = (unsigned char) (req + 1U); } } @@ -274,7 +274,7 @@ static int frp_entry_add(struct osi_core_priv_data *const osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "No Link FRP ID index found\n", OSI_NONE); - i = next_frp_id; + i = (unsigned char) next_frp_id; } ok_index = i; } @@ -462,7 +462,7 @@ static int frp_add_proto(struct osi_core_priv_data *const osi_core, /* Check and Add protocol FRP entire */ if (proto_entry == OSI_ENABLE) { /* Check for space */ - req = frp_req_entries(cmd->offset, cmd->match_length) + 1U; + 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", @@ -484,7 +484,7 @@ static int frp_add_proto(struct osi_core_priv_data *const osi_core, } /* Increment pos value */ - *pos += 1U; + *pos = (unsigned char) (*pos + 1U); } return 0; @@ -499,8 +499,8 @@ static int frp_add_proto(struct osi_core_priv_data *const osi_core, * @param[in] cmd: OSI FRP command structure. * */ -static void frp_parse_mtype(struct osi_core_priv_data *const osi_core, - struct osi_core_frp_cmd *const cmd) +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; @@ -592,7 +592,7 @@ static int frp_delete(struct osi_core_priv_data *const osi_core, (sizeof(struct osi_core_frp_entry) * count)); /* Move in FRP table entries by count */ - for (i = (pos + count); i <= frp_cnt; i++) { + for (i = (unsigned char) (pos + count); i <= frp_cnt; i++) { frp_entry_copy(&osi_core->frp_table[pos], &osi_core->frp_table[i]); pos++; diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index 65a980c..fe40e26 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -90,8 +90,8 @@ static nve32_t ivc_handle_ioctl(struct osi_core_priv_data *osi_core, * @retval -1 on failure. */ static nve32_t ivc_core_init(struct osi_core_priv_data *const osi_core, - nveu32_t tx_fifo_size, - nveu32_t rx_fifo_size) + OSI_UNUSED nveu32_t tx_fifo_size, + OSI_UNUSED nveu32_t rx_fifo_size) { ivc_msg_common_t msg; @@ -540,7 +540,8 @@ static nve32_t ivc_macsec_lut_config(struct osi_core_priv_data *const osi_core, * @param[in] osi_core: OSI Core private data structure. * */ -static void ivc_macsec_handle_s_irq(struct osi_core_priv_data *const osi_core) +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); @@ -553,7 +554,8 @@ static void ivc_macsec_handle_s_irq(struct osi_core_priv_data *const osi_core) * */ -static void ivc_macsec_handle_ns_irq(struct osi_core_priv_data *const osi_core) +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); @@ -667,7 +669,8 @@ static nve32_t vir_ivc_core_deinit(struct osi_core_priv_data *const osi_core) * * @retval Return 0 */ -static nve32_t vir_ivc_init_core_ops(struct osi_core_priv_data *const osi_core) +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 diff --git a/osi/core/macsec.c b/osi/core/macsec.c index 6d89ac0..70f3b02 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -2109,7 +2109,9 @@ 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); @@ -2176,8 +2178,10 @@ 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); diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 8668149..7a14834 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -1599,21 +1599,6 @@ static int mgbe_config_vlan_filtering(struct osi_core_priv_data *osi_core, return 0; } -/** - * @brief mgbe_update_vlan_id - update VLAN ID in Tag register - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] vid: VLAN ID to be programmed. - * - * @retval 0 on success - * @retval -1 on failure - */ -static inline int mgbe_update_vlan_id(struct osi_core_priv_data *const osi_core, - unsigned int vid) -{ - return 0; -} - /** * @brief mgbe_config_ptp_rxq - Config PTP RX packets queue route * @@ -4375,7 +4360,8 @@ static void mgbe_handle_common_intr(struct osi_core_priv_data *osi_core) * * @retval zero always */ -static nve32_t mgbe_pad_calibrate(struct osi_core_priv_data *const osi_core) +static nve32_t mgbe_pad_calibrate(OSI_UNUSED + struct osi_core_priv_data *const osi_core) { return 0; } @@ -5942,8 +5928,9 @@ static void mgbe_config_ssir(struct osi_core_priv_data *const osi_core, * - De-initialization: Yes * @retval 0 */ -static nve32_t mgbe_set_mode(struct osi_core_priv_data *const osi_core, - const nve32_t mode) +static nve32_t mgbe_set_mode(OSI_UNUSED + struct osi_core_priv_data *const osi_core, + OSI_UNUSED const nve32_t mode) { return 0; } @@ -6044,6 +6031,7 @@ static nveu32_t mgbe_write_macsec_reg(struct osi_core_priv_data *const osi_core, * @retval 0 */ static nve32_t mgbe_validate_core_regs( + OSI_UNUSED struct osi_core_priv_data *const osi_core) { return 0; @@ -6063,8 +6051,9 @@ static nve32_t mgbe_validate_core_regs( * - De-initialization: Yes * @retval 0 */ -static nve32_t mgbe_config_tx_status(struct osi_core_priv_data *const osi_core, - const nveu32_t tx_status) +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; } @@ -6083,8 +6072,9 @@ static nve32_t mgbe_config_tx_status(struct osi_core_priv_data *const osi_core, * - De-initialization: Yes * @retval 0 */ -static nve32_t mgbe_config_rx_crc_check(struct osi_core_priv_data *const osi_core, - const nveu32_t crc_chk) +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; } @@ -6103,7 +6093,9 @@ static nve32_t mgbe_config_rx_crc_check(struct osi_core_priv_data *const osi_cor * - De-initialization: Yes * @retval 0 */ -static void mgbe_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, +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) { } @@ -6133,7 +6125,7 @@ static void mgbe_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, * - De-initialization: No */ static void mgbe_config_for_macsec(struct osi_core_priv_data *const osi_core, - const nveu32_t enable) + const nveu32_t enable) { nveu32_t value = 0U, temp = 0U; @@ -6243,7 +6235,6 @@ void mgbe_init_core_ops(struct core_ops *ops) 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->update_vlan_id = mgbe_update_vlan_id; ops->set_systime_to_mac = mgbe_set_systime_to_mac; ops->config_addend = mgbe_config_addend; ops->adjust_mactime = mgbe_adjust_mactime; diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index e4bbf9b..a2c433c 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -1563,7 +1563,7 @@ static inline nve32_t freq_offset_calculate(struct osi_core_priv_data *sec_osi_c */ if (offset >= 1000000000 || offset <= -1000000000) { s->count = SERVO_STATS_0; /* JUMP */ - return s->last_ppb; + return (nve32_t) s->last_ppb; } switch (s->count) { @@ -2002,20 +2002,20 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, break; case OSI_CMD_READ_REG: - ret = ops_p->read_reg(osi_core, (nve32_t) data->arg1_u32); + ret = (nve32_t) ops_p->read_reg(osi_core, (nve32_t) data->arg1_u32); break; case OSI_CMD_WRITE_REG: - ret = ops_p->write_reg(osi_core, (nve32_t) data->arg1_u32, + 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 = ops_p->read_macsec_reg(osi_core, (nve32_t) data->arg1_u32); + ret = (nve32_t) ops_p->read_macsec_reg(osi_core, (nve32_t) data->arg1_u32); break; case OSI_CMD_WRITE_MACSEC_REG: - ret = ops_p->write_macsec_reg(osi_core, (nve32_t) data->arg1_u32, + ret = (nve32_t) ops_p->write_macsec_reg(osi_core, (nveu32_t) data->arg1_u32, (nve32_t) data->arg2_u32); break; #endif /* MACSEC_SUPPORT */ diff --git a/osi/core/vlan_filter.c b/osi/core/vlan_filter.c index 7368f53..4f99be2 100644 --- a/osi/core/vlan_filter.c +++ b/osi/core/vlan_filter.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -44,11 +44,11 @@ static inline unsigned int get_vlan_filter_idx( unsigned long temp = 0U; while (bitmap != 0U) { - temp = __builtin_ctzl(bitmap); + temp = (unsigned long) __builtin_ctzl(bitmap); if (osi_core->vid[temp] == vlan_id) { /* vlan ID match found */ - vid_idx = temp; + vid_idx = (unsigned int)temp; break; } @@ -84,7 +84,7 @@ static inline int allow_all_vid_tags(unsigned char *base, hash_filter_reg |= VLAN_HASH_ALLOW_ALL; } else { vlan_tag_reg &= ~MAC_VLAN_TAG_CTRL_VHTM; - hash_filter_reg &= ~VLAN_HASH_ALLOW_ALL; + hash_filter_reg &= (unsigned int) ~VLAN_HASH_ALLOW_ALL; } osi_writel(vlan_tag_reg, base + MAC_VLAN_TAG_CTRL); @@ -232,7 +232,7 @@ static inline int update_vlan_filters(struct osi_core_priv_data *osi_core, osi_writel(val, base + MAC_VLAN_TAG_DATA); val = osi_readl(base + MAC_VLAN_TAG_CTRL); - val &= ~MAC_VLAN_TAG_CTRL_OFS_MASK; + 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; @@ -277,7 +277,7 @@ static inline int add_vlan_id(struct osi_core_priv_data *osi_core, } /* Get free index to add the VID */ - vid_idx = __builtin_ctzl(~osi_core->vf_bitmap); + 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 */ @@ -306,7 +306,7 @@ static inline int add_vlan_id(struct osi_core_priv_data *osi_core, } val = osi_readl((unsigned char *)osi_core->base + MAC_VLAN_TAG_DATA); - val &= ~VLAN_VID_MASK; + 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); @@ -326,7 +326,7 @@ static inline int add_vlan_id(struct osi_core_priv_data *osi_core, * @return -1 on failure. */ static inline int dequeue_vlan_id(struct osi_core_priv_data *osi_core, - unsigned short idx) + unsigned int idx) { unsigned int i; @@ -381,7 +381,7 @@ static inline int dequeue_vid_to_add_filter_reg( osi_core->vid[vid_idx] = vlan_id; val = osi_readl((unsigned char *)osi_core->base + MAC_VLAN_TAG_DATA); - val &= ~VLAN_VID_MASK; + 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); diff --git a/osi/dma/eqos_desc.c b/osi/dma/eqos_desc.c index 5fbb301..f45b200 100644 --- a/osi/dma/eqos_desc.c +++ b/osi/dma/eqos_desc.c @@ -165,8 +165,8 @@ static void eqos_get_rx_csum(struct osi_rx_desc *rx_desc, * @param[in] rx_desc: Rx Descriptor. * @param[in] rx_pkt_cx: Per-Rx packet context structure */ -static void eqos_get_rx_hash(struct osi_rx_desc *rx_desc, - struct osi_rx_pkt_cx *rx_pkt_cx) +static void eqos_get_rx_hash(OSI_UNUSED struct osi_rx_desc *rx_desc, + OSI_UNUSED struct osi_rx_pkt_cx *rx_pkt_cx) { } diff --git a/osi/dma/mgbe_dma.c b/osi/dma/mgbe_dma.c index 186730c..eab9f3b 100644 --- a/osi/dma/mgbe_dma.c +++ b/osi/dma/mgbe_dma.c @@ -629,7 +629,8 @@ static void mgbe_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) * @retval 0 on success * @retval -1 on failure. */ -static nve32_t mgbe_validate_dma_regs(struct osi_dma_priv_data *osi_dma) +static nve32_t mgbe_validate_dma_regs(OSI_UNUSED + struct osi_dma_priv_data *osi_dma) { /* TODO: for mgbe */ return 0; @@ -694,7 +695,7 @@ static void mgbe_clear_vm_rx_intr(void *addr, nveu32_t chan) static void mgbe_config_slot(struct osi_dma_priv_data *osi_dma, unsigned int chan, unsigned int set, - unsigned int interval) + OSI_UNUSED unsigned int interval) { unsigned int value; #if 0 diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 65fa3a3..cfbaf89 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -213,14 +213,16 @@ nve32_t osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) return -1; } - 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) || + 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) || + (osi_dma->osd_ops.printf == OSI_NULL) || #endif /* OSI_DEBUG */ - (osi_dma->osd_ops.udelay == OSI_NULL)) { - return -1; + (osi_dma->osd_ops.udelay == OSI_NULL)) { + return -1; + } } if (osi_dma->mac > OSI_MAC_HW_MGBE) { From bfb924f3a933a3ded069963a8933940279cf175b Mon Sep 17 00:00:00 2001 From: Bibhay Ranjan <bibhayr@nvidia.com> Date: Mon, 28 Mar 2022 21:15:02 +0530 Subject: [PATCH 337/458] nvethernetrm: fix code defects Issue: SPARSE errors Fix: Fix code as per the guidelines in the errors Bug 3568991 Change-Id: If52bf7d5b3e8d4ca10a254e802ee5257a8816633 Signed-off-by: Bibhay Ranjan <bibhayr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2688520 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/mmc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mmc.h b/include/mmc.h index 194135c..0d3c7ab 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -631,4 +631,4 @@ struct osi_macsec_mmc_counters { nveul64_t tx_octets_protected; }; #endif /* MACSEC_SUPPORT */ -#endif /* INCLUDED_MMC_H */ \ No newline at end of file +#endif /* INCLUDED_MMC_H */ From 85b162292f8417393627ce715f4419edf7917451 Mon Sep 17 00:00:00 2001 From: Om Prakash Singh <omp@nvidia.com> Date: Sun, 24 Apr 2022 10:45:44 +0530 Subject: [PATCH 338/458] osi: core: fix XPCS_REG_VALUE_MASK Issue: PCS register read/write is failing due to wrong value of XPCS_REG_VALUE_MASK; Fix: update XPCS_REG_VALUE_MASK value to 0x3FF Bug 3591736 Change-Id: Id62aff5f8749b94810475ff79665899a10bec3e4 Signed-off-by: Om Prakash Singh <omp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2701996 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/xpcs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osi/core/xpcs.h b/osi/core/xpcs.h index 9b0560a..c4d27ea 100644 --- a/osi/core/xpcs.h +++ b/osi/core/xpcs.h @@ -89,7 +89,7 @@ #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 0xFFU +#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)) From 2e0ca71ca733ebe472bf5512882465cfbe0a6c1b Mon Sep 17 00:00:00 2001 From: Sanath Kumar Gampa <sgampa@nvidia.com> Date: Mon, 11 Apr 2022 18:11:58 +0530 Subject: [PATCH 339/458] osi:macsec: Fix MISRA defects in QNX OSD Dependent change made in osi to fix a misra defect in QNX OSD Bug 3598679 Change-Id: Ie6b48a6d1cb8d34b00c437cc3b57971ad447fa3b Signed-off-by: Sanath Kumar Gampa <sgampa@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2695627 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_macsec.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/osi_macsec.h b/include/osi_macsec.h index 8d35f33..994f45c 100644 --- a/include/osi_macsec.h +++ b/include/osi_macsec.h @@ -160,7 +160,7 @@ #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 34 +#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 */ From bb667d105bf2ce5aafd3b547b2c2fc387b2d334f Mon Sep 17 00:00:00 2001 From: Sanath Kumar Gampa <sgampa@nvidia.com> Date: Tue, 29 Mar 2022 12:11:18 +0530 Subject: [PATCH 340/458] osi:macsec reduce complexity of MACSEC APIs Issue: Complexity of OSI APIs cannot be greater than 10 Fix: Split the functionality of complex APIs to multiple APIs. Added De-oxygen comments as well for macsec osi APIs Bug 3460422 Change-Id: I2383904d8581efa54a8d2ec2f85a50cb12b22e89 Signed-off-by: Sanath Kumar Gampa <sgampa@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2688990 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_macsec.h | 422 ++--- osi/core/macsec.c | 3481 +++++++++++++++++++++++++++++++++++------- 2 files changed, 3106 insertions(+), 797 deletions(-) diff --git a/include/osi_macsec.h b/include/osi_macsec.h index 994f45c..8d98bd3 100644 --- a/include/osi_macsec.h +++ b/include/osi_macsec.h @@ -381,31 +381,25 @@ struct osi_macsec_core_ops { ////////////////////////////////////////////////////////////////////////// /** - * @brief initializing the macsec core operations + * @brief osi_init_macsec_ops - macsec initialize operations * * @note * Algorithm: - * - Init osi_core macsec ops and lut status structure members + * - 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. + * @param[in] osi_core: OSI core private data structure. used param macsec_base * - * @pre - * - * @note - * Traceability Details: - * - SWUD_ID: - * - * @note - * Classification: - * - Interrupt: No - * - Signal handler: No - * - Thread safe: No - * - Required Privileges: None + * @pre MACSEC needs to be out of reset and proper clock configured. * * @note * API Group: - * - Initialization: Yes - * - Run time: No + * - Initialization: No + * - Run time: Yes * - De-initialization: No * * @retval 0 on success @@ -414,33 +408,24 @@ struct osi_macsec_core_ops { nve32_t osi_init_macsec_ops(struct osi_core_priv_data *const osi_core); /** - * @brief Initialize the macsec controller + * @brief osi_macsec_init - Initialize the macsec controller * * @note * Algorithm: - * - Configure MTU, controller configs, interrupts, clear all LUT's and + * - 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 Length. + * @param[in] mtu: mtu to be programmed * - * @pre - * - MACSEC should be out of reset and clocks are enabled - * - * @note - * Traceability Details: - * - SWUD_ID: - * - * @note - * Classification: - * - Interrupt: No - * - Signal handler: No - * - Thread safe: No - * - Required Privileges: None + * @pre MACSEC needs to be out of reset and proper clock configured. * * @note * API Group: - * - Initialization: Yes + * - Initialization: No * - Run time: Yes * - De-initialization: No * @@ -451,33 +436,24 @@ nve32_t osi_macsec_init(struct osi_core_priv_data *const osi_core, nveu32_t mtu); /** - * @brief De-Initialize the macsec controller + * @brief osi_macsec_deinit - De-Initialize the macsec controller * * @note * Algorithm: - * - Resets macsec global data structures + * - 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. + * @param[in] osi_core: OSI core private data structure * - * @pre - * - MACSEC TX/RX engine shall be disabled. - * - * @note - * Traceability Details: - * - SWUD_ID: - * - * @note - * Classification: - * - Interrupt: No - * - Signal handler: No - * - Thread safe: No - * - Required Privileges: None + * @pre MACSEC needs to be out of reset and proper clock configured. * * @note * API Group: * - Initialization: No * - Run time: Yes - * - De-initialization: Yes + * - De-initialization: No * * @retval 0 on success * @retval -1 on failure @@ -485,27 +461,18 @@ nve32_t osi_macsec_init(struct osi_core_priv_data *const osi_core, nve32_t osi_macsec_deinit(struct osi_core_priv_data *const osi_core); /** - * @brief Non-secure irq handler. + * @brief osi_macsec_ns_isr - macsec non-secure irq handler * * @note * Algorithm: - * - Takes care of handling the non secture interrupts accordingly as per - * the MACSEC IP + * - 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. + * @param[in] osi_core: OSI core private data structure * - * @pre MACSEC should be inited and enabled. - * - * @note - * Traceability Details: - * - SWUD_ID: - * - * @note - * Classification: - * - Interrupt: Yes - * - Signal handler: No - * - Thread safe: No - * - Required Privileges: None + * @pre MACSEC needs to be out of reset and proper clock configured. * * @note * API Group: @@ -513,32 +480,23 @@ nve32_t osi_macsec_deinit(struct osi_core_priv_data *const osi_core); * - Run time: Yes * - De-initialization: No * - * @retval None + * @retval none */ void osi_macsec_ns_isr(struct osi_core_priv_data *const osi_core); /** - * @brief Secure irq handler + * @brief osi_macsec_s_isr - macsec secure irq handler * * @note * Algorithm: - * - Takes care of handling the secture interrupts accordingly as per - * the MACSEC IP + * - 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. + * @param[in] osi_core: OSI core private data structure * - * @pre MACSEC should be inited and enabled. - * - * @note - * Traceability Details: - * - SWUD_ID: - * - * @note - * Classification: - * - Interrupt: Yes - * - Signal handler: No - * - Thread safe: No - * - Required Privileges: None + * @pre MACSEC needs to be out of reset and proper clock configured. * * @note * API Group: @@ -546,34 +504,24 @@ void osi_macsec_ns_isr(struct osi_core_priv_data *const osi_core); * - Run time: Yes * - De-initialization: No * - * @retval None + * @retval none */ void osi_macsec_s_isr(struct osi_core_priv_data *const osi_core); /** - * @brief MACSEC Lookup table configuration + * @brief osi_macsec_config_lut - Read or write to macsec LUTs * * @note * Algorithm: - * - Configures MACSEC LUT entry for BYP, SCI, SC PARAM, SC STATE, SA STATE - * table + * - 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[in] lut_config: OSI macsec LUT config data structure. + * @param[in] osi_core: OSI core private data structure + * @param[out] lut_config: Pointer to the lut configuration * - * @pre - * - MACSEC shall be initialized and enalbed - * - * @note - * Traceability Details: - * - SWUD_ID: - * - * @note - * Classification: - * - Interrupt: No - * - Signal handler: No - * - Thread safe: No - * - Required Privileges: None + * @pre MACSEC needs to be out of reset and proper clock configured. * * @note * API Group: @@ -588,28 +536,19 @@ nve32_t osi_macsec_config_lut(struct osi_core_priv_data *const osi_core, struct osi_macsec_lut_config *const lut_config); /** - * @brief MACSEC Key table configuration + * @brief osi_macsec_config_kt - API to read or update the keys * * @note * Algorithm: - * - Configures MACSEC Key Table entry + * - 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: OSI macsec Key table config data structure. + * @param[in] osi_core: OSI core private data structure + * @param[in] kt_config: Keys that needs to be programmed * - * @pre - * - MACSEC shall be initialized and enalbed - * - * @note - * Traceability Details: - * - SWUD_ID: - * - * @note - * Classification: - * - Interrupt: No - * - Signal handler: No - * - Thread safe: No - * - Required Privileges: None + * @pre MACSEC needs to be out of reset and proper clock configured. * * @note * API Group: @@ -624,28 +563,19 @@ nve32_t osi_macsec_config_kt(struct osi_core_priv_data *const osi_core, struct osi_macsec_kt_config *const kt_config); /** - * @brief MACSEC cipher configuration + * @brief osi_macsec_cipher_config - API to update the cipher * * @note * Algorithm: - * - Configure MACSEC tx/rx controller cipther mode. + * - 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: AES cipher to be configured to controller. + * @param[in] osi_core: OSI core private data structure + * @param[in] cipher: Cipher suit to be used * - * @pre - * - MACSEC shall be initialized and enalbed - * - * @note - * Traceability Details: - * - SWUD_ID: - * - * @note - * Classification: - * - Interrupt: No - * - Signal handler: No - * - Thread safe: No - * - Required Privileges: None + * @pre MACSEC needs to be out of reset and proper clock configured. * * @note * API Group: @@ -660,28 +590,19 @@ nve32_t osi_macsec_cipher_config(struct osi_core_priv_data *const osi_core, nveu32_t cipher); /** - * @brief MACSEC Loopback configuration + * @brief osi_macsec_loopback - API to enable/disable macsec loopback * * @note * Algorithm: - * - Configure MACSEC controller to loopback mode. + * - 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: Loopback enable/disable flag. + * @param[in] osi_core: OSI core private data structure + * @param[in] enable: parameter to enable or disable * - * @pre - * - MACSEC shall be initialized and enalbed - * - * @note - * Traceability Details: - * - SWUD_ID: - * - * @note - * Classification: - * - Interrupt: No - * - Signal handler: No - * - Thread safe: No - * - Required Privileges: None + * @pre MACSEC needs to be out of reset and proper clock configured. * * @note * API Group: @@ -696,34 +617,26 @@ nve32_t osi_macsec_loopback(struct osi_core_priv_data *const osi_core, nveu32_t enable); /** - * @brief MACSEC Controller Enable/Disable + * @brief osi_macsec_en - API to enable/disable macsec * * @note * Algorithm: - * - Configure MACSEC controller to loopback mode. + * - 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: Loopback enable/disable flag. + * @param[in] osi_core: OSI core private data structure + * @param[in] enable: parameter to enable or disable * - * @pre - * - MACSEC shall be initialized and enalbed - * - * @note - * Traceability Details: - * - SWUD_ID: - * - * @note - * Classification: - * - Interrupt: No - * - Signal handler: No - * - Thread safe: No - * - Required Privileges: None + * @pre MACSEC needs to be out of reset and proper clock configured. * * @note * API Group: - * - Initialization: Yes + * - Initialization: No * - Run time: Yes - * - De-initialization: Yes + * - De-initialization: No * * @retval 0 on success * @retval -1 on failure @@ -732,30 +645,22 @@ nve32_t osi_macsec_en(struct osi_core_priv_data *const osi_core, nveu32_t enable); /** - * @brief MACSEC update secure channel/association in controller + * @brief osi_macsec_config - Updates SC or SA in the macsec * * @note * Algorithm: - * - Create/Delete/Update SC/AN in controller. + * - 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 osi_macsec_sc_info struct for the tx SA. - * @param[in] enable: flag to indicate enable/disable for the Tx SA. - * @param[out] kt_idx: Key table index to program SAK. + * @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 shall be initialized and enalbed - * - * @note - * Traceability Details: - * - SWUD_ID: - * - * @note - * Classification: - * - Interrupt: No - * - Signal handler: No - * - Thread safe: No - * - Required Privileges: None + * @pre MACSEC needs to be out of reset and proper clock configured. * * @note * API Group: @@ -772,27 +677,18 @@ nve32_t osi_macsec_config(struct osi_core_priv_data *const osi_core, nveu16_t *kt_idx); /** - * @brief MACSEC read statistics counters + * @brief osi_macsec_read_mmc - Updates the mmc counters * * @note * Algorithm: - * - Reads the MACSEC statistics counters + * - 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[in] osi_core: OSI core private data structure. + * @param[out] osi_core: OSI core private data structure * - * @pre - * - MACSEC shall be initialized and enalbed - * - * @note - * Traceability Details: - * - SWUD_ID: - * - * @note - * Classification: - * - Interrupt: No - * - Signal handler: No - * - Thread safe: No - * - Required Privileges: None + * @pre MACSEC needs to be out of reset and proper clock configured. * * @note * API Group: @@ -806,28 +702,19 @@ nve32_t osi_macsec_config(struct osi_core_priv_data *const osi_core, nve32_t osi_macsec_read_mmc(struct osi_core_priv_data *const osi_core); /** - * @brief MACSEC debug buffer configuration + * @brief osi_macsec_config_dbg_buf - Reads the debug buffer captured * * @note * Algorithm: - * - Read or Write MACSEC debug buffers + * - 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[in] dbg_buf_config: OSI macsec debug buffer config data structure. + * @param[in] osi_core: OSI core private data structure + * @param[out] dbg_buf_config: dbg buffer data captured * - * @pre - * - MACSEC shall be initialized and enalbed - * - * @note - * Traceability Details: - * - SWUD_ID: - * - * @note - * Classification: - * - Interrupt: No - * - Signal handler: No - * - Thread safe: No - * - Required Privileges: None + * @pre MACSEC needs to be out of reset and proper clock configured. * * @note * API Group: @@ -843,28 +730,19 @@ nve32_t osi_macsec_config_dbg_buf( struct osi_macsec_dbg_buf_config *const dbg_buf_config); /** - * @brief MACSEC debug events configuration + * @brief osi_macsec_dbg_events_config - Enables debug buffer events * * @note * Algorithm: - * - Configures MACSEC debug events to be triggered. + * - 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: OSI macsec debug buffer config data structure. + * @param[in] osi_core: OSI core private data structure + * @param[in] dbg_buf_config: dbg buffer data captured * - * @pre - * - MACSEC shall be initialized and enalbed - * - * @note - * Traceability Details: - * - SWUD_ID: - * - * @note - * Classification: - * - Interrupt: No - * - Signal handler: No - * - Thread safe: No - * - Required Privileges: None + * @pre MACSEC needs to be out of reset and proper clock configured. * * @note * API Group: @@ -880,31 +758,21 @@ nve32_t osi_macsec_dbg_events_config( struct osi_macsec_dbg_buf_config *const dbg_buf_config); /** - * @brief MACSEC Key Index Start for a given SCI + * @brief osi_macsec_get_sc_lut_key_index - API to get key index for a given SCI * * @note * Algorithm: - * - Retrieves the Key_index used for a given SCI in SC. + * - 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: Secure Channel Identifier - * @param[out] key_index: Pointer which will be filled with key_index start - * @param[in] ctrl: Tx or Rx controller + * @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 shall be initialized and enalbed - * - * @note - * Traceability Details: - * - SWUD_ID: - * - * @note - * Classification: - * - Interrupt: No - * - Signal handler: No - * - Thread safe: No - * - Required Privileges: None + * @pre MACSEC needs to be out of reset and proper clock configured. * * @note * API Group: @@ -912,7 +780,7 @@ nve32_t osi_macsec_dbg_events_config( * - Run time: Yes * - De-initialization: No * - * @retval vaid Key Index Start on success + * @retval 0 on success * @retval -1 on failure */ nve32_t osi_macsec_get_sc_lut_key_index( @@ -920,29 +788,19 @@ nve32_t osi_macsec_get_sc_lut_key_index( nveu8_t *sci, nveu32_t *key_index, nveu16_t ctlr); /** - * @brief sets MACSEC MTU + * @brief osi_macsec_update_mtu - Update the macsec mtu in run-time * * @note * Algorithm: - * - Sets MACSEC MTU + * - 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: MACSEC MTU + * @param[in] osi_core: OSI core private data structure + * @param[in] mtu: mtu that needs to be programmed * - * - * @pre - * - MACSEC shall be initialized and enalbed - * - * @note - * Traceability Details: - * - SWUD_ID: - * - * @note - * Classification: - * - Interrupt: No - * - Signal handler: No - * - Thread safe: No - * - Required Privileges: None + * @pre MACSEC needs to be out of reset and proper clock configured. * * @note * API Group: @@ -950,7 +808,7 @@ nve32_t osi_macsec_get_sc_lut_key_index( * - Run time: Yes * - De-initialization: No * - * @retval vaid Key Index Start on success + * @retval 0 on success * @retval -1 on failure */ nve32_t osi_macsec_update_mtu(struct osi_core_priv_data *const osi_core, diff --git a/osi/core/macsec.c b/osi/core/macsec.c index 70f3b02..a1c545f 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -45,10 +45,25 @@ /** * @brief poll_for_dbg_buf_update - Query the status of a debug buffer update. * - * @param[in] osi_core: OSI Core private data structure. + * @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: *********** * - * @retval 0 on Success - * @retval -1 on Failure + * @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) { @@ -84,10 +99,22 @@ static nve32_t poll_for_dbg_buf_update(struct osi_core_priv_data *const osi_core /** * @brief write_dbg_buf_data - Commit debug buffer to HW * - * @param[in] osi_core: OSI Core private data structure. + * @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 * - * @retval none + * @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, @@ -107,10 +134,22 @@ static inline void write_dbg_buf_data( /** * @brief read_dbg_buf_data - Read debug buffer from HW * - * @param[in] osi_core: OSI Core private data structure. + * @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 * - * @retval none + * @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, @@ -128,12 +167,109 @@ static inline void read_dbg_buf_data( } /** - * @brief tx_dbg_trigger_evts - Enable/Disable TX debug trigger events. + * @brief write_tx_dbg_trigger_evts - Trigger and start capturing the tx dbg events * - * @param[in] osi_core: OSI Core private data structure. - * @param[in] dbg_buf_config: Pointer to debug buffer config data structure. + * @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: *********** * - * @retval None + * @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, @@ -142,61 +278,10 @@ static void tx_dbg_trigger_evts( nveu8_t *base = (nveu8_t *)osi_core->macsec_base; nveu32_t flags = 0; - nveu32_t tx_trigger_evts, debug_ctrl_reg; + nveu32_t tx_trigger_evts; if (dbg_buf_config->rw == OSI_DBG_TBL_WRITE) { - 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); - } + 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); @@ -224,12 +309,108 @@ static void tx_dbg_trigger_evts( } /** - * @brief rx_dbg_trigger_evts - Enable/Disable RX debug trigger events. + * @brief write_rx_dbg_trigger_evts - Trigger and start capturing the rx dbg events * - * @param[in] osi_core: OSI Core private data structure. - * @param[in] dbg_buf_config: Pointer to debug buffer config data structure. + * @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: *********** * - * @retval None + * @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, @@ -238,60 +419,10 @@ static void rx_dbg_trigger_evts( nveu8_t *base = (nveu8_t *)osi_core->macsec_base; nveu32_t flags = 0; - nveu32_t rx_trigger_evts, debug_ctrl_reg; + nveu32_t rx_trigger_evts = 0; if (dbg_buf_config->rw == OSI_DBG_TBL_WRITE) { - 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); - } + 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); @@ -319,22 +450,33 @@ static void rx_dbg_trigger_evts( } /** - * @brief macsec_dbg_buf_config - Read/Write debug buffers. + * @brief validate_inputs_macsec_dbg_buf_conf - validates the dbg buffer configuration * - * @param[in] osi_core: OSI Core private data structure. - * @param[in] dbg_buf_config: Pointer to debug buffer config data structure. + * @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: *********** * - * @retval 0 on Success - * @retval -1 on Failure + * @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) +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) { - - nveu8_t *base = (nveu8_t *)osi_core->macsec_base; - nveu32_t dbg_config_reg = 0; - nve32_t ret = 0; - /* Validate inputs */ if ((dbg_buf_config->rw > OSI_RW_MAX) || (dbg_buf_config->ctlr_sel > OSI_CTLR_SEL_MAX)) { @@ -351,6 +493,47 @@ static nve32_t macsec_dbg_buf_config(struct osi_core_priv_data *const osi_core, "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); @@ -383,7 +566,31 @@ static nve32_t macsec_dbg_buf_config(struct osi_core_priv_data *const osi_core, 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) @@ -430,18 +637,26 @@ static nve32_t macsec_dbg_events_config( } /** - * @brief update_macsec_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] offset: HW register offset + * @brief update_macsec_mmc_val - Reads specific macsec mmc counters * * @note - * 1) MAC/MACSEC should be init and started. + * Algorithm: + * - Reads and returns macsec mmc counters + * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. + * - TraceID: *********** * - * @retval value on current MMC counter value. + * @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, @@ -457,17 +672,24 @@ static inline nveul64_t update_macsec_mmc_val( return ((value_lo) | (value_hi << 31)); } - /** - * @brief macsec_read_mmc - To read statitics registers and update mmc structure - * - * Algorithm: Pass register offset and old value to helper function and - * update structure. - * - * @param[in] osi_core: OSI core private data structure. + * @brief macsec_read_mmc - Reads all macsec mmc counters * * @note - * 1) MAC/MACSEC should be init and started. + * 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) { @@ -514,6 +736,35 @@ static void macsec_read_mmc(struct osi_core_priv_data *const osi_core) } } +/** + * @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) { @@ -690,6 +941,18 @@ static nve32_t kt_key_write(struct osi_core_priv_data *const osi_core, 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) { @@ -697,11 +960,9 @@ static nve32_t macsec_kt_config(struct osi_core_priv_data *const osi_core, nveu32_t kt_config_reg = 0; nveu8_t *base = (nveu8_t *)osi_core->tz_base; - /* 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; + ret = validate_kt_config(kt_config); + if (ret < 0) { + return ret; } kt_config_reg = osi_readla(osi_core, base + MACSEC_GCM_KEYTABLE_CONFIG); @@ -747,10 +1008,26 @@ static nve32_t macsec_kt_config(struct osi_core_priv_data *const osi_core, /** * @brief poll_for_lut_update - Query the status of a LUT update. * - * @param[in] osi_core: OSI Core private data structure. + * @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: *********** * - * @retval 0 on Success - * @retval -1 on Failure + * @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) { @@ -787,6 +1064,26 @@ static inline nve32_t poll_for_lut_update(struct osi_core_priv_data *osi_core) 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) { @@ -799,113 +1096,222 @@ static inline void read_lut_data(struct osi_core_priv_data *const osi_core, } } -static nve32_t lut_read_inputs(struct osi_macsec_lut_config *const lut_config, - const nveu32_t *const lut_data) +/** + * @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) { - struct osi_lut_inputs entry = {0}; - nveu32_t flags = 0; - /* 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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) | + entry->sa[1] = (nveu8_t)((lut_data[1] >> 30) | ((lut_data[2] & 0x3FU) << 2)); - flags |= OSI_LUT_FLAGS_SA_BYTE1_VALID; + *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; + 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; + 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; + 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) | + entry->sa[5] = (nveu8_t)((lut_data[2] >> 30) | ((lut_data[3] & 0x3FU) << 2)); - flags |= OSI_LUT_FLAGS_SA_BYTE5_VALID; + *flags |= OSI_LUT_FLAGS_SA_BYTE5_VALID; } - /* 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; - } +} +/** + * @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; + *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; + *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; + *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) != @@ -954,6 +1360,29 @@ static nve32_t lut_read_inputs(struct osi_macsec_lut_config *const lut_config, 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) { @@ -1011,28 +1440,35 @@ static nve32_t byp_lut_read(struct osi_core_priv_data *const osi_core, return ret; } -static nve32_t sci_lut_read(struct osi_core_priv_data *const osi_core, - struct osi_macsec_lut_config *const lut_config) +/** + * @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 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; + nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; 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; - } if ((lut_data[6] & MACSEC_LUT_AN0_VALID) == MACSEC_LUT_AN0_VALID) { lut_config->sci_lut_out.an_valid |= OSI_AN0_VALID; @@ -1063,9 +1499,59 @@ static nve32_t sci_lut_read(struct osi_core_priv_data *const osi_core, } val = osi_readla(osi_core, addr+MACSEC_TX_SCI_LUT_VALID); - if ((val & ((nveu32_t)(1U) << index)) != OSI_NONE) { + 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); @@ -1103,6 +1589,30 @@ static nve32_t sci_lut_read(struct osi_core_priv_data *const osi_core, 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) { @@ -1148,6 +1658,30 @@ static nve32_t sc_param_lut_read(struct osi_core_priv_data *const osi_core, 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) { @@ -1159,6 +1693,30 @@ static nve32_t sc_state_lut_read(struct osi_core_priv_data *const osi_core, 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) { @@ -1190,6 +1748,29 @@ static nve32_t sa_state_lut_read(struct osi_core_priv_data *const osi_core, 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) { @@ -1197,39 +1778,19 @@ static nve32_t lut_data_read(struct osi_core_priv_data *const osi_core, switch (lut_config->lut_sel) { case OSI_LUT_SEL_BYPASS: - if (byp_lut_read(osi_core, lut_config) != 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "BYP LUT read err\n", 0ULL); - return -1; - } + ret = byp_lut_read(osi_core, lut_config); break; case OSI_LUT_SEL_SCI: - if (sci_lut_read(osi_core, lut_config) != 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "SCI LUT read err\n", 0ULL); - return -1; - } + ret = sci_lut_read(osi_core, lut_config); break; case OSI_LUT_SEL_SC_PARAM: - if (sc_param_lut_read(osi_core, lut_config) != 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "SC param LUT read err\n", 0ULL); - return -1; - } + ret = sc_param_lut_read(osi_core, lut_config); break; case OSI_LUT_SEL_SC_STATE: - if (sc_state_lut_read(osi_core, lut_config) != 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "SC state LUT read err\n", 0ULL); - return -1; - } + ret = sc_state_lut_read(osi_core, lut_config); break; case OSI_LUT_SEL_SA_STATE: - if (sa_state_lut_read(osi_core, lut_config) != 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "SA state LUT read err\n", 0ULL); - return -1; - } + ret = sa_state_lut_read(osi_core, lut_config); break; default: OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, @@ -1241,6 +1802,26 @@ static nve32_t lut_data_read(struct osi_core_priv_data *const osi_core, 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) { @@ -1253,8 +1834,28 @@ static inline void commit_lut_data(struct osi_core_priv_data *const osi_core, } } +/** + * @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( - struct osi_macsec_lut_config *const 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; @@ -1263,6 +1864,26 @@ static void rx_sa_state_lut_config( 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) { @@ -1276,6 +1897,30 @@ static void tx_sa_state_lut_config(const struct osi_macsec_lut_config *const lut } +/** + * @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) { @@ -1300,8 +1945,32 @@ static nve32_t sa_state_lut_config(struct osi_core_priv_data *const osi_core, 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, - struct osi_macsec_lut_config *const lut_config) + 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; @@ -1312,8 +1981,28 @@ static nve32_t sc_state_lut_config(struct osi_core_priv_data *const osi_core, 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( - struct osi_macsec_lut_config *const 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; @@ -1325,6 +2014,26 @@ static void rx_sc_param_lut_config( 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) @@ -1348,6 +2057,31 @@ static void tx_sc_param_lut_config( 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) { @@ -1357,6 +2091,8 @@ static nve32_t sc_param_lut_config(struct osi_core_priv_data *const osi_core, 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; } @@ -1379,38 +2115,111 @@ static nve32_t sc_param_lut_config(struct osi_core_priv_data *const osi_core, return ret; } -static nve32_t lut_config_inputs(struct osi_macsec_lut_config *const lut_config, +/** + * @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; - 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; + /* 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_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_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_VLAN_VALID) == OSI_LUT_FLAGS_VLAN_VALID) { - if ((entry.vlan_pcp > OSI_VLAN_PCP_MAX) || - (entry.vlan_id > OSI_VLAN_ID_MAX)) { - return -1; + 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) { @@ -1460,56 +2269,33 @@ static nve32_t lut_config_inputs(struct osi_macsec_lut_config *const lut_config, lut_data[1] |= MACSEC_LUT_DA_BYTE5_INACTIVE; } - /* 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_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) == @@ -1520,6 +2306,33 @@ static nve32_t lut_config_inputs(struct osi_macsec_lut_config *const lut_config, } 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) { @@ -1546,6 +2359,33 @@ static nve32_t lut_config_inputs(struct osi_macsec_lut_config *const lut_config, 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) == @@ -1584,6 +2424,32 @@ static nve32_t lut_config_inputs(struct osi_macsec_lut_config *const lut_config, } 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) == @@ -1597,10 +2463,100 @@ static nve32_t lut_config_inputs(struct osi_macsec_lut_config *const lut_config, } 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) @@ -1639,6 +2595,31 @@ static nve32_t rx_sci_lut_config( 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) @@ -1678,6 +2659,32 @@ static nve32_t tx_sci_lut_config( 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) { @@ -1691,6 +2698,8 @@ static nve32_t sci_lut_config(struct osi_core_priv_data *const osi_core, 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; } @@ -1752,6 +2761,31 @@ static nve32_t sci_lut_config(struct osi_core_priv_data *const osi_core, 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) { @@ -1830,6 +2864,29 @@ static nve32_t byp_lut_config(struct osi_core_priv_data *const osi_core, 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) { @@ -1837,39 +2894,19 @@ static inline nve32_t lut_data_write(struct osi_core_priv_data *const osi_core, switch (lut_config->lut_sel) { case OSI_LUT_SEL_BYPASS: - if (byp_lut_config(osi_core, lut_config) != 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "BYP LUT config err\n", 0ULL); - return -1; - } + ret = byp_lut_config(osi_core, lut_config); break; case OSI_LUT_SEL_SCI: - if (sci_lut_config(osi_core, lut_config) != 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "SCI LUT config err\n", 0ULL); - return -1; - } + ret = sci_lut_config(osi_core, lut_config); break; case OSI_LUT_SEL_SC_PARAM: - if (sc_param_lut_config(osi_core, lut_config) != 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "SC param LUT config err\n", 0ULL); - return -1; - } + ret = sc_param_lut_config(osi_core, lut_config); break; case OSI_LUT_SEL_SC_STATE: - if (sc_state_lut_config(osi_core, lut_config) != 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "SC state LUT config err\n", 0ULL); - return -1; - } + ret = sc_state_lut_config(osi_core, lut_config); break; case OSI_LUT_SEL_SA_STATE: - if (sa_state_lut_config(osi_core, lut_config) != 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "SA state LUT config err\n", 0ULL); - return -1; - } + ret = sa_state_lut_config(osi_core, lut_config); break; default: OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, @@ -1881,13 +2918,30 @@ static inline nve32_t lut_data_write(struct osi_core_priv_data *const osi_core, return ret; } -static nve32_t macsec_lut_config(struct osi_core_priv_data *const osi_core, - struct osi_macsec_lut_config *const lut_config) +/** + * @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) { - nve32_t ret = 0; - nveu32_t lut_config_reg; - nveu8_t *base = (nveu8_t *)osi_core->macsec_base; - /* Validate LUT config */ if ((lut_config->table_config.ctlr_sel > OSI_CTLR_SEL_MAX) || (lut_config->table_config.rw > OSI_RW_MAX) || @@ -1900,6 +2954,54 @@ static nve32_t macsec_lut_config(struct osi_core_priv_data *const osi_core, 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) { @@ -1945,6 +3047,25 @@ static nve32_t macsec_lut_config(struct osi_core_priv_data *const osi_core, 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) { @@ -1962,6 +3083,25 @@ static inline void handle_rx_sc_invalid_key( 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) { @@ -1979,6 +3119,25 @@ static inline void handle_tx_sc_invalid_key( 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) { @@ -1987,6 +3146,25 @@ static inline void handle_safety_err_irq( 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) { @@ -2005,6 +3183,25 @@ static inline void handle_rx_sc_replay_err( 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) { @@ -2024,6 +3221,25 @@ static inline void handle_rx_pn_exhausted( 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; @@ -2036,6 +3252,25 @@ static inline void handle_tx_sc_err(struct osi_core_priv_data *const osi_core) } +/** + * @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) { @@ -2055,6 +3290,25 @@ static inline void handle_tx_pn_threshold( 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) { @@ -2074,6 +3328,27 @@ static inline void handle_tx_pn_exhausted( 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) @@ -2105,6 +3380,34 @@ static inline void handle_dbg_evt_capture_done( } } +/** + * @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; @@ -2174,6 +3477,36 @@ static inline void handle_tx_irq(struct osi_core_priv_data *const osi_core) } } +/** + * @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; @@ -2257,6 +3590,30 @@ static inline void handle_rx_irq(struct osi_core_priv_data *const osi_core) } } +/** + * @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; @@ -2298,6 +3655,29 @@ static inline void handle_common_irq(struct osi_core_priv_data *const osi_core) } } +/** + * @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; @@ -2324,6 +3704,25 @@ static void macsec_handle_ns_irq(struct osi_core_priv_data *const 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; @@ -2335,10 +3734,31 @@ static void macsec_handle_s_irq(struct osi_core_priv_data *const osi_core) if (common_isr != OSI_NONE) { handle_common_irq(osi_core); } - - return; } +/** + * @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) { @@ -2363,6 +3783,29 @@ static nve32_t macsec_cipher_config(struct osi_core_priv_data *const osi_core, 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) @@ -2384,19 +3827,36 @@ static nve32_t macsec_loopback_config( return 0; } -static nve32_t clear_lut(struct osi_core_priv_data *const osi_core) +/** + * @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}; -#ifdef MACSEC_KEY_PROGRAM - struct osi_macsec_kt_config kt_config = {0}; -#endif 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; - /* Clear all the LUT's which have a dedicated LUT valid bit per entry */ - /* Tx/Rx BYP LUT */ lut_config.lut_sel = OSI_LUT_SEL_BYPASS; for (i = 0; i <= OSI_CTLR_SEL_MAX; i++) { @@ -2412,6 +3872,39 @@ static nve32_t clear_lut(struct osi_core_priv_data *const osi_core) } } + 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++) { @@ -2426,7 +3919,39 @@ static nve32_t clear_lut(struct osi_core_priv_data *const osi_core) } } } + 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++) { @@ -2441,7 +3966,40 @@ static nve32_t clear_lut(struct osi_core_priv_data *const osi_core) } } } + 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++) { @@ -2456,7 +4014,40 @@ static nve32_t clear_lut(struct osi_core_priv_data *const osi_core) } } } + 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; @@ -2482,6 +4073,68 @@ static nve32_t clear_lut(struct osi_core_priv_data *const osi_core) 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 */ @@ -2504,6 +4157,28 @@ static nve32_t clear_lut(struct osi_core_priv_data *const osi_core) 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; @@ -2524,6 +4199,30 @@ static nve32_t macsec_deinit(struct osi_core_priv_data *const osi_core) 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) { @@ -2553,22 +4252,132 @@ static nve32_t macsec_update_mtu(struct osi_core_priv_data *const osi_core, return 0; } -static nve32_t macsec_init(struct osi_core_priv_data *const osi_core, - nveu32_t mtu) +/** + * @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) { - nveu32_t val = 0; struct osi_macsec_lut_config lut_config = {0}; struct osi_macsec_table_config *table_config = &lut_config.table_config; - const struct core_local *l_core = (void *)osi_core; /* 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}; - nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; 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); @@ -2678,53 +4487,33 @@ static nve32_t macsec_init(struct osi_core_priv_data *const osi_core, "Invalidating all LUT's failed\n", (nveul64_t)ret); return ret; } - - /* 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); - goto exit; - } else { - osi_core->macsec_lut_status[i].next_byp_idx++; - } - } - - 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); - - goto exit; - } else { - osi_core->macsec_lut_status[i].next_byp_idx++; - } - } - -exit: - 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, @@ -2744,6 +4533,28 @@ static struct osi_macsec_sc_info *find_existing_sc( 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) { @@ -2759,6 +4570,33 @@ static nveu32_t get_avail_sc_idx(const struct osi_core_priv_data *const osi_core 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) { @@ -2791,6 +4629,37 @@ static nve32_t macsec_get_key_index(struct osi_core_priv_data *const osi_core, 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, @@ -2879,9 +4748,99 @@ static nve32_t del_upd_sc(struct osi_core_priv_data *const osi_core, 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, - const struct osi_macsec_sc_info *const sc, - nveu16_t ctlr, nveu16_t *kt_idx) + 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; @@ -2904,11 +4863,8 @@ static nve32_t add_upd_sc(struct osi_core_priv_data *const osi_core, table_config->index = *kt_idx; kt_config.flags |= OSI_LUT_FLAGS_ENTRY_VALID; - /* Program in reverse order as per HW design */ - for (i = 0; i < OSI_KEY_LEN_128; i++) { - kt_config.entry.sak[i] = sc->sak[OSI_KEY_LEN_128 - 1U - i]; - kt_config.entry.h[i] = sc->hkey[OSI_KEY_LEN_128 - 1U - i]; - } + 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) { @@ -2925,8 +4881,8 @@ static nve32_t add_upd_sc(struct osi_core_priv_data *const osi_core, /* 2. SA state LUT */ lut_config.lut_sel = OSI_LUT_SEL_SA_STATE; - table_config->index = (nveu16_t)((sc->sc_idx_start * OSI_MAX_NUM_SA) + - sc->curr_an); + 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; @@ -2941,12 +4897,10 @@ static nve32_t add_upd_sc(struct osi_core_priv_data *const osi_core, lut_config.flags = OSI_NONE; lut_config.lut_sel = OSI_LUT_SEL_SC_PARAM; table_config->index = (nveu16_t)(sc->sc_idx_start); - /* Program in reverse order as per HW design */ - for (i = 0; i < OSI_SCI_LEN; i++) { - lut_config.sc_param_out.sci[i] = sc->sci[OSI_SCI_LEN - 1U - i]; - } + 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 * OSI_MAX_NUM_SA); + ((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; @@ -2963,11 +4917,8 @@ static nve32_t add_upd_sc(struct osi_core_priv_data *const osi_core, lut_config.flags = OSI_NONE; lut_config.lut_sel = OSI_LUT_SEL_SCI; table_config->index = (nveu16_t)(sc->sc_idx_start); - /* Program in reverse order as per HW design */ - for (i = 0; i < OSI_ETH_ALEN; i++) { - /* Extract the mac sa from the SCI itself */ - lut_config.lut_in.sa[i] = sc->sci[OSI_ETH_ALEN - 1U - i]; - } + /* 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++) { @@ -3007,10 +4958,7 @@ err_sc_state: 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); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Failed to set SCI LUT\n", (nveul64_t)ret); - } + print_error(osi_core, ret); err_sci: /* cleanup SC param */ @@ -3020,10 +4968,7 @@ err_sci: 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); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Failed to set SC param LUT\n", (nveul64_t)ret); - } + print_error(osi_core, ret); err_sc_param: /* Cleanup SA state LUT */ @@ -3032,12 +4977,10 @@ err_sc_param: 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 * OSI_MAX_NUM_SA) + sc->curr_an); + 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); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Failed to set SA state LUT\n", (nveul64_t)ret); - } + print_error(osi_core, ret); err_sa_state: #ifdef MACSEC_KEY_PROGRAM @@ -3047,31 +4990,224 @@ err_sa_state: table_config->rw = OSI_LUT_WRITE; 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 set SAK\n", (nveul64_t)ret); - } + 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, *new_sc = OSI_NULL; + 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; - nveu32_t avail_sc_idx = 0; - nve32_t ret = 0; + nve32_t ret; - /* Validate inputs */ - if (((enable != OSI_ENABLE) && (enable != OSI_DISABLE)) || - ((ctlr != OSI_CTLR_SEL_TX) && (ctlr != OSI_CTLR_SEL_RX)) || - (kt_idx == OSI_NULL)) { + 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; } @@ -3086,61 +5222,7 @@ static nve32_t config_macsec(struct osi_core_priv_data *const osi_core, return -1; } else { LOG("%s: Adding new SC/SA: ctlr: %hu", __func__, 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 = osi_memcpy(new_sc->sci, sc->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; - } - ret = osi_memcpy(new_sc->sak, sc->sak, OSI_KEY_LEN_128); - if (ret < OSI_NONE_SIGNED) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "memcpy Failed\n", 0ULL); - return -1; - } -#ifdef MACSEC_KEY_PROGRAM - ret = osi_memcpy(new_sc->hkey, sc->hkey, OSI_KEY_LEN_128); - if (ret < OSI_NONE_SIGNED) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "memcpy Failed\n", 0ULL); - return -1; - } -#endif /* MACSEC_KEY_PROGRAM */ - 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); - - 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; - } + return add_new_sc(osi_core, sc, ctlr, kt_idx); } } else { LOG("%s: Updating existing SC", __func__); @@ -3167,20 +5249,12 @@ static nve32_t config_macsec(struct osi_core_priv_data *const osi_core, * programmed successfully */ *tmp_sc_p = *existing_sc; - ret = osi_memcpy(tmp_sc_p->sak, sc->sak, OSI_KEY_LEN_128); + 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; } -#ifdef MACSEC_KEY_PROGRAM - ret = osi_memcpy(tmp_sc_p->hkey, sc->hkey, OSI_KEY_LEN_128); - if (ret < OSI_NONE_SIGNED) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "memcpy Failed\n", 0ULL); - return -1; - } -#endif /* MACSEC_KEY_PROGRAM */ tmp_sc_p->curr_an = sc->curr_an; tmp_sc_p->next_pn = sc->next_pn; tmp_sc_p->pn_window = sc->pn_window; @@ -3207,8 +5281,29 @@ static nve32_t config_macsec(struct osi_core_priv_data *const osi_core, } /** - * @brief if_ops - Static core interface operations for virtual - * case + * @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) { @@ -3245,6 +5340,31 @@ nve32_t osi_init_macsec_ops(struct osi_core_priv_data *const osi_core) 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) { @@ -3256,6 +5376,29 @@ nve32_t osi_macsec_init(struct osi_core_priv_data *const osi_core, 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) && @@ -3265,6 +5408,26 @@ nve32_t osi_macsec_deinit(struct osi_core_priv_data *const 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) && @@ -3273,6 +5436,26 @@ 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 + */ void osi_macsec_s_isr(struct osi_core_priv_data *const osi_core) { if ((osi_core != OSI_NULL) && (osi_core->macsec_ops != OSI_NULL) && @@ -3281,6 +5464,30 @@ 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) { @@ -3292,6 +5499,32 @@ nve32_t osi_macsec_config_lut(struct osi_core_priv_data *const osi_core, 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) @@ -3305,6 +5538,30 @@ nve32_t osi_macsec_get_sc_lut_key_index(struct osi_core_priv_data *const osi_cor 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) { @@ -3317,6 +5574,30 @@ nve32_t osi_macsec_update_mtu(struct osi_core_priv_data *const osi_core, } #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) { @@ -3330,6 +5611,30 @@ nve32_t osi_macsec_config_kt(struct osi_core_priv_data *const osi_core, } #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) { @@ -3341,6 +5646,30 @@ nve32_t osi_macsec_cipher_config(struct osi_core_priv_data *const osi_core, 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) { @@ -3353,6 +5682,31 @@ nve32_t osi_macsec_loopback(struct osi_core_priv_data *const osi_core, 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) { @@ -3370,14 +5724,40 @@ nve32_t osi_macsec_en(struct osi_core_priv_data *const osi_core, 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_TX) && (ctlr != OSI_CTLR_SEL_RX)) || - (kt_idx == OSI_NULL)) { + (ctlr > OSI_CTLR_SEL_MAX) || (kt_idx == OSI_NULL)) { return -1; } @@ -3390,6 +5770,29 @@ nve32_t osi_macsec_config(struct osi_core_priv_data *const osi_core, 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) && @@ -3401,6 +5804,30 @@ nve32_t osi_macsec_read_mmc(struct osi_core_priv_data *const osi_core) 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) @@ -3415,6 +5842,30 @@ nve32_t osi_macsec_config_dbg_buf( 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) From ec0b1870677ca671194ca4184755f0a5373dea15 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Tue, 26 Apr 2022 13:43:52 +0530 Subject: [PATCH 341/458] osi: core: program 0xF's while deleting MAC address Issue: After deleting the MAC address its observed that old MAC address values are there in low/high registers which creates confusion while checking the register dump/ Fix: Program 0xF's in low/high registers while deleting the MAC address. Bug 3609583 Change-Id: I1d93d6bc31eb1c49e7641ff97f73d0ed4bb0345f Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2702855 Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/eqos_core.c | 4 ++++ osi/core/mgbe_core.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 949df0d..da8b05b 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -3341,6 +3341,10 @@ static void eqos_l2_filter_delete(struct osi_core_priv_data *osi_core, 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); diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 7a14834..4388d19 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -678,8 +678,12 @@ static int mgbe_update_mac_addr_low_high_reg( 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; } From fcb76fd65b130b19dcdca9c9181181fb2136622f Mon Sep 17 00:00:00 2001 From: Hareesh Kesireddy <hkesireddy@nvidia.com> Date: Wed, 20 Apr 2022 17:34:17 +0530 Subject: [PATCH 342/458] osi: remove extra args for tx complete callback Dma phy address, virtual address and packet length can be obtained from tx swcx structure. Hence passing pointer to tx swcx is sufficient. In future, if more information from osi is needed, it can be embedded into tx swcx itself rather than adding more arguments to osd tx complete call back. Bug 3576506 Change-Id: I061ea27cd1b4d68c19f3e9d95a247505c511ce0c Signed-off-by: Hareesh Kesireddy <hkesireddy@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2700341 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_dma.h | 9 +++++++-- osi/dma/osi_dma_txrx.c | 4 +--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/include/osi_dma.h b/include/osi_dma.h index d95c51b..b80a345 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -384,6 +384,12 @@ struct osi_tx_swcx { 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; }; /** @@ -491,8 +497,7 @@ struct osi_dma_priv_data; */ struct osd_dma_ops { /** DMA transmit complete callback */ - void (*transmit_complete)(void *priv, void *buffer, - nveu64_t dmaaddr, nveu32_t len, + void (*transmit_complete)(void *priv, const struct osi_tx_swcx *swcx, const struct osi_txdone_pkt_cx *txdone_pkt_cx); /** DMA receive packet callback */ diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index c48b1ee..988160e 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -656,9 +656,7 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, tx_swcx->len = 0; } osi_dma->osd_ops.transmit_complete(osi_dma->osd, - tx_swcx->buf_virt_addr, - tx_swcx->buf_phy_addr, - tx_swcx->len, + tx_swcx, txdone_pkt_cx); } else { OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, From 71e7aef0fff847f7b20f0b40fdf3dd653ddfc7ea Mon Sep 17 00:00:00 2001 From: Om Prakash Singh <omp@nvidia.com> Date: Thu, 21 Apr 2022 15:17:24 +0530 Subject: [PATCH 343/458] core: add pcs register readback after write support As per T23X-MGBE_HSIv2-14 requirement for PCS register we need to perform readback for each write operation to verify write operation was successful Bug 3606649 Change-Id: I7cca6baa43feaa4207b6158f0abc796e656338dd Signed-off-by: Om Prakash Singh <omp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2700845 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/core_local.h | 2 +- osi/core/eqos_core.c | 5 ++- osi/core/mgbe_core.c | 37 ++++++++++++------- osi/core/osi_hal.c | 3 +- osi/core/xpcs.c | 83 +++++++++++++++++++++++++++++++------------ osi/core/xpcs.h | 40 +++++++++++++++++++-- 6 files changed, 129 insertions(+), 41 deletions(-) diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 9534a9e..d616c53 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -280,7 +280,7 @@ struct core_ops { struct osi_core_ptp_tsc_data *data); #ifdef HSI_SUPPORT /** Interface function called to initialize HSI */ - void (*core_hsi_configure)(struct osi_core_priv_data *const osi_core, + int (*core_hsi_configure)(struct osi_core_priv_data *const osi_core, const nveu32_t enable); #endif }; diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index da8b05b..4ab9a96 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1714,8 +1714,10 @@ static void eqos_configure_rxq_priority( * @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 void eqos_hsi_configure(struct osi_core_priv_data *const osi_core, +static int eqos_hsi_configure(struct osi_core_priv_data *const osi_core, const nveu32_t enable) { nveu32_t value; @@ -1841,6 +1843,7 @@ static void eqos_hsi_configure(struct osi_core_priv_data *const osi_core, osi_writela(osi_core, value, (nveu8_t *)osi_core->base + EQOS_WRAP_COMMON_INTR_ENABLE); } + return 0; } #endif /** diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 4388d19..18d03e2 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -2572,12 +2572,14 @@ static int mgbe_config_flow_control(struct osi_core_priv_data *const osi_core, * @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 void mgbe_hsi_configure(struct osi_core_priv_data *const osi_core, +static int mgbe_hsi_configure(struct osi_core_priv_data *const osi_core, const nveu32_t enable) { nveu32_t value = 0U; - void *xpcs_base = osi_core->xpcs_base; + int ret = 0; if (enable == OSI_ENABLE) { osi_core->hsi.enabled = OSI_ENABLE; @@ -2585,13 +2587,17 @@ static void mgbe_hsi_configure(struct osi_core_priv_data *const osi_core, /* T23X-MGBE_HSIv2-10 Enable PCS ECC */ value = (EN_ERR_IND | FEC_EN); - xpcs_write(xpcs_base, XPCS_BASE_PMA_MMD_SR_PMA_KR_FEC_CTRL, value); - + 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; - xpcs_write(xpcs_base, XPCS_VR_XS_PCS_SFTY_TMR_CTRL, value); - + 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); @@ -2670,11 +2676,15 @@ static void mgbe_hsi_configure(struct osi_core_priv_data *const osi_core, osi_core->hsi.enabled = OSI_DISABLE; /* T23X-MGBE_HSIv2-10 Disable PCS ECC */ - xpcs_write(xpcs_base, XPCS_BASE_PMA_MMD_SR_PMA_KR_FEC_CTRL, 0); - + 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 */ - xpcs_write(xpcs_base, XPCS_VR_XS_PCS_SFTY_TMR_CTRL, 0); - + 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); @@ -2732,6 +2742,7 @@ static void mgbe_hsi_configure(struct osi_core_priv_data *const osi_core, osi_writela(osi_core, value, (nveu8_t *)osi_core->xpcs_base + XPCS_WRAP_INTERRUPT_CONTROL); } + return ret; } #endif @@ -4250,11 +4261,11 @@ static void mgbe_handle_hsi_intr(struct osi_core_priv_data *osi_core) /* Clear status register for PCS error */ val = xpcs_read(xpcs_base, XPCS_VR_XS_PCS_SFTY_UE_INTR0); if (val != 0U) { - xpcs_write(xpcs_base, XPCS_VR_XS_PCS_SFTY_UE_INTR0, 0); + (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) { - xpcs_write(xpcs_base, XPCS_VR_XS_PCS_SFTY_CE_INTR, 0); + (void)xpcs_write_safety(osi_core, XPCS_VR_XS_PCS_SFTY_CE_INTR, 0); } } } @@ -5258,7 +5269,7 @@ static void mgbe_configure_eee(struct osi_core_priv_data *osi_core, unsigned int tic_counter = 0; void *addr = osi_core->base; - if (xpcs_eee(osi_core->xpcs_base, tx_lpi_enabled) != 0) { + 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; diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index a2c433c..0407070 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -2054,8 +2054,7 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, break; #ifdef HSI_SUPPORT case OSI_CMD_HSI_CONFIGURE: - ops_p->core_hsi_configure(osi_core, data->arg1_u32); - ret = 0; + ret = ops_p->core_hsi_configure(osi_core, data->arg1_u32); break; #endif default: diff --git a/osi/core/xpcs.c b/osi/core/xpcs.c index 8576f84..6ba0d31 100644 --- a/osi/core/xpcs.c +++ b/osi/core/xpcs.c @@ -42,6 +42,7 @@ static inline int xpcs_poll_for_an_complete(struct osi_core_priv_data *osi_core, unsigned int retry = 1000; unsigned int count; int cond = 1; + int ret = 0; /* 14. Poll for AN complete */ cond = 1; @@ -70,7 +71,10 @@ static inline int xpcs_poll_for_an_complete(struct osi_core_priv_data *osi_core, } else { /* 15. clear interrupt */ status &= ~XPCS_VR_MII_AN_INTR_STS_CL37_ANCMPLT_INTR; - xpcs_write(xpcs_base, XPCS_VR_MII_AN_INTR_STS, status); + ret = xpcs_write_safety(osi_core, XPCS_VR_MII_AN_INTR_STS, status); + if (ret != 0) { + return ret; + } cond = 0; } } @@ -90,14 +94,18 @@ static inline int xpcs_poll_for_an_complete(struct osi_core_priv_data *osi_core, * * Algorithm: This routine program XPCS speed based on AN status. * - * @param[in] xpcs_base: XPCS base virtual address. + * @param[in] osi_core: OSI core data structure. * @param[in] status: Autonegotation Status. + * + * @retval 0 on success + * @retval -1 on failure */ -static inline void xpcs_set_speed(void *xpcs_base, +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); @@ -120,7 +128,7 @@ static inline void xpcs_set_speed(void *xpcs_base, break; } - xpcs_write(xpcs_base, XPCS_SR_MII_CTRL, ctrl); + return xpcs_write_safety(osi_core, XPCS_SR_MII_CTRL, ctrl); } /** @@ -154,15 +162,19 @@ int xpcs_start(struct osi_core_priv_data *osi_core) (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; - xpcs_write(xpcs_base, XPCS_SR_MII_CTRL, ctrl); - + 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; } - xpcs_set_speed(xpcs_base, an_status); - + 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; @@ -446,6 +458,7 @@ int xpcs_init(struct osi_core_priv_data *osi_core) 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, @@ -469,8 +482,10 @@ int xpcs_init(struct osi_core_priv_data *osi_core) /* 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; - xpcs_write(xpcs_base, XPCS_SR_XS_PCS_CTRL2, ctrl); - + 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 */ @@ -484,8 +499,10 @@ int xpcs_init(struct osi_core_priv_data *osi_core) } } - xpcs_write(xpcs_base, XPCS_VR_XS_PCS_KR_CTRL, ctrl); - + 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 @@ -493,6 +510,14 @@ int xpcs_init(struct osi_core_priv_data *osi_core) /* 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); @@ -524,11 +549,16 @@ int xpcs_init(struct osi_core_priv_data *osi_core) (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; - xpcs_write(xpcs_base, XPCS_SR_AN_CTRL, ctrl); - + 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; - xpcs_write(xpcs_base, XPCS_VR_XS_PCS_DIG_CTRL1, ctrl); + 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 @@ -549,15 +579,17 @@ int xpcs_init(struct osi_core_priv_data *osi_core) * Algorithm: This routine update register related to EEE * for XPCS. * - * @param[in] xpcs_base: XPCS virtual base address + * @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(void *xpcs_base, unsigned int en_dis) +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; @@ -570,7 +602,10 @@ int xpcs_eee(void *xpcs_base, unsigned int en_dis) 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; - xpcs_write(xpcs_base, XPCS_VR_XS_PCS_EEE_MCTRL0, val); + ret = xpcs_write_safety(osi_core, XPCS_VR_XS_PCS_EEE_MCTRL0, val); + if (ret != 0) { + return ret; + } return 0; } @@ -588,12 +623,16 @@ int xpcs_eee(void *xpcs_base, unsigned int en_dis) /* 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); - xpcs_write(xpcs_base, XPCS_VR_XS_PCS_EEE_MCTRL0, val); - + 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; - xpcs_write(xpcs_base, XPCS_VR_XS_PCS_EEE_MCTRL1, val); - + 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 index c4d27ea..070e441 100644 --- a/osi/core/xpcs.h +++ b/osi/core/xpcs.h @@ -127,7 +127,7 @@ int xpcs_init(struct osi_core_priv_data *osi_core); int xpcs_start(struct osi_core_priv_data *osi_core); -int xpcs_eee(void *xpcs_base, unsigned int en_dis); +int xpcs_eee(struct osi_core_priv_data *osi_core, unsigned int en_dis); /** * @brief xpcs_read - read from xpcs. @@ -148,7 +148,7 @@ static inline unsigned int xpcs_read(void *xpcs_base, unsigned int reg_addr) } /** - * @brief xpcs_read - write to xpcs. + * @brief xpcs_write - write to xpcs. * * Algorithm: This routine writes data to XPCS register. * @@ -164,4 +164,40 @@ static inline void xpcs_write(void *xpcs_base, unsigned int reg_addr, 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 From 7ea62b2b648b6036fdca3d97a90f18d0f05de8f9 Mon Sep 17 00:00:00 2001 From: Nagaraj Annaiah <nannaiah@nvidia.com> Date: Wed, 4 May 2022 14:07:25 +0000 Subject: [PATCH 344/458] osi core: Fix macsec and eqos compiler warnings for HVRTOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issue: 1. conversion to ‘nveu16_t {aka short unsigned int}’ from ‘unsigned int’ may alter its value. 2. mac_tcr may be used uninitialized in this function 3. Explicitly assigning value of variable of type 'nveu32_t' (aka 'unsigned int') to itself - mac_tcr |= mac_tcr; Fix: 1. Add Typecast before conversion. 2. init mac_tcr to zero 3. Remove unused get_rx_err_stats function. 4. Remove mac_tcr from default. Bug 3562777 Change-Id: I9030bf73d13ffd1d848266301a1df97144eaa391 Signed-off-by: Nagaraj Annaiah <nannaiah@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2707197 Reviewed-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_core.h | 5 ----- osi/core/eqos_core.c | 8 +++----- osi/core/macsec.c | 4 ++-- osi/dma/osi_dma_txrx.c | 2 ++ 4 files changed, 7 insertions(+), 12 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 2c146d0..ccdfb27 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -36,14 +36,9 @@ struct ivc_msg_common; /* 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; /** @} */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 4ab9a96..ed6cf58 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -4308,7 +4308,7 @@ static nve32_t eqos_set_systime_to_mac( const nveu32_t nsec) { void *addr = osi_core->base; - nveu32_t mac_tcr; + nveu32_t mac_tcr = 0U; nve32_t ret; /* To be sure previous write was flushed (if Any) */ @@ -4422,7 +4422,7 @@ static inline nve32_t eqos_poll_for_addend_complete( static nve32_t eqos_config_addend(struct osi_core_priv_data *const osi_core, const nveu32_t addend) { - nveu32_t mac_tcr; + nveu32_t mac_tcr = 0U; nve32_t ret; /* To be sure previous write was flushed (if Any) */ @@ -4542,7 +4542,7 @@ static nve32_t eqos_adjust_mactime(struct osi_core_priv_data *const osi_core, const nveu32_t one_nsec_accuracy) { void *addr = osi_core->base; - nveu32_t mac_tcr; + nveu32_t mac_tcr = 0U; nveu32_t value = 0; nveul64_t temp = 0; nveu32_t sec1 = sec; @@ -4675,8 +4675,6 @@ static void eqos_config_tscr(struct osi_core_priv_data *const osi_core, mac_tcr |= OSI_MAC_TCR_CSC; break; default: - /* To avoid MISRA violation */ - mac_tcr |= mac_tcr; break; } } diff --git a/osi/core/macsec.c b/osi/core/macsec.c index a1c545f..d016a25 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -4306,7 +4306,7 @@ static nve32_t set_byp_lut(struct osi_core_priv_data *const osi_core) "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 = (nveu16_t ) ((osi_core->macsec_lut_status[i].next_byp_idx & 0xFFU) + 1U); } } @@ -4326,7 +4326,7 @@ static nve32_t set_byp_lut(struct osi_core_priv_data *const osi_core) return ret; } else { - osi_core->macsec_lut_status[i].next_byp_idx = + osi_core->macsec_lut_status[i].next_byp_idx = (nveu16_t ) ((osi_core->macsec_lut_status[i].next_byp_idx & 0xFFU) + 1U); } } diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 988160e..2bafea1 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -32,6 +32,7 @@ static struct desc_ops d_ops[MAX_MAC_IP_TYPES]; +#ifdef OSI_DEBUG /** * @brief get_rx_err_stats - Detect Errors from Rx Descriptor * @@ -70,6 +71,7 @@ static inline void get_rx_err_stats(struct osi_rx_desc *rx_desc, 1UL); } } +#endif /** * @brief validate_rx_completions_arg- Validate input argument of rx_completions From 20cc545bdcbe329750f71a28aee67880e91da1bf Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Tue, 12 Oct 2021 19:06:53 +0530 Subject: [PATCH 345/458] osi: dma: Support for variable Tx/Rx ring length o Adds support for variable Tx/Rx ring length o Default ring size 1K used if ring size passed from OSD is zero. Bug 3489814 Change-Id: I9c57b8d9e0c424bf39633998e0845fc97975de8f Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2652960 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_dma.h | 7 ++++++- include/osi_dma_txrx.h | 17 ++++++++++------- osi/dma/debug.c | 6 +++--- osi/dma/dma_local.h | 17 +++++++++++++++++ osi/dma/osi_dma.c | 40 +++++++++++++++++++++++++++++++++------- osi/dma/osi_dma_txrx.c | 30 +++++++++++++++--------------- 6 files changed, 84 insertions(+), 33 deletions(-) diff --git a/include/osi_dma.h b/include/osi_dma.h index b80a345..934784f 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -604,6 +604,10 @@ struct osi_dma_priv_data { #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; }; /** @@ -909,7 +913,8 @@ nve32_t osi_stop_dma(struct osi_dma_priv_data *osi_dma, nveu32_t chan); * * @retval "Number of available free descriptors." */ -nveu32_t osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring); +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 diff --git a/include/osi_dma_txrx.h b/include/osi_dma_txrx.h index f142d48..97b3607 100644 --- a/include/osi_dma_txrx.h +++ b/include/osi_dma_txrx.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -29,8 +29,11 @@ * @brief Helper macros for defining Tx/Rx descriptor count * @{ */ -#define TX_DESC_CNT 1024U -#define RX_DESC_CNT 1024U +#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 */ @@ -43,14 +46,14 @@ * @{ */ /** Increment the tx descriptor index */ -#define INCR_TX_DESC_INDEX(idx, i) ((idx) = ((idx) + (i)) & (TX_DESC_CNT - 1U)) +#define INCR_TX_DESC_INDEX(idx, x) ((idx) = ((idx) + (1U)) & ((x) - 1U)) /** Increment the rx descriptor index */ -#define INCR_RX_DESC_INDEX(idx, i) ((idx) = ((idx) + (i)) & (RX_DESC_CNT - 1U)) +#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, i) ((idx) = ((idx) - (i)) & (TX_DESC_CNT - 1U)) +#define DECR_TX_DESC_INDEX(idx, x) ((idx) = ((idx) - (1U)) & ((x) - 1U)) /** Decrement the rx descriptor index */ -#define DECR_RX_DESC_INDEX(idx, i) ((idx) = ((idx) - (i)) & (RX_DESC_CNT - 1U)) +#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/osi/dma/debug.c b/osi/dma/debug.c index 33745dc..3ccb451 100644 --- a/osi/dma/debug.c +++ b/osi/dma/debug.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -205,7 +205,7 @@ static void tx_desc_dump(struct osi_dma_priv_data *osi_dma, unsigned int f_idx, int cnt; if (f_idx > l_idx) { - cnt = l_idx + TX_DESC_CNT - f_idx; + cnt = l_idx + osi_dma->tx_ring_sz - f_idx; } else { cnt = l_idx - f_idx; } @@ -223,7 +223,7 @@ static void tx_desc_dump(struct osi_dma_priv_data *osi_dma, unsigned int f_idx, tx_desc->tdes3, tx_desc->tdes2, tx_desc->tdes1, tx_desc->tdes0); - INCR_TX_DESC_INDEX(i, 1U); + INCR_TX_DESC_INDEX(i, osi_dma->tx_ring_sz); } } } diff --git a/osi/dma/dma_local.h b/osi/dma/dma_local.h index 697fdd1..465fd03 100644 --- a/osi/dma/dma_local.h +++ b/osi/dma/dma_local.h @@ -34,6 +34,14 @@ #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 */ @@ -227,6 +235,15 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, 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 * diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index cfbaf89..6d7e16f 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -193,6 +193,8 @@ static nve32_t validate_func_ptrs(struct osi_dma_priv_data *osi_dma, 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); @@ -231,6 +233,26 @@ nve32_t osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) 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) { @@ -542,15 +564,19 @@ nve32_t osi_stop_dma(struct osi_dma_priv_data *osi_dma, return 0; } -nveu32_t osi_get_refill_rx_desc_cnt(struct osi_rx_ring *rx_ring) +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 >= RX_DESC_CNT) || - (rx_ring->refill_idx >= RX_DESC_CNT)) { + (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) & (RX_DESC_CNT - 1U); + return (rx_ring->cur_rx_idx - rx_ring->refill_idx) & + (osi_dma->rx_ring_sz - 1U); } /** @@ -649,7 +675,7 @@ nve32_t osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, /* Refill buffers */ while ((rx_ring->refill_idx != rx_ring->cur_rx_idx) && - (rx_ring->refill_idx < RX_DESC_CNT)) { + (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; @@ -675,7 +701,7 @@ nve32_t osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, rx_dma_handle_ioc(osi_dma, rx_ring, rx_desc); rx_desc->rdes3 |= RDES3_OWN; - INCR_RX_DESC_INDEX(rx_ring->refill_idx, 1U); + INCR_RX_DESC_INDEX(rx_ring->refill_idx, osi_dma->rx_ring_sz); } /* Update the Rx tail ptr whenever buffer is replenished to @@ -684,7 +710,7 @@ nve32_t osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, * knows to loop over to start of ring. */ tailptr = rx_ring->rx_desc_phy_addr + - (sizeof(struct osi_rx_desc) * (RX_DESC_CNT)); + (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 */ diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 2bafea1..84c1ee8 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -150,7 +150,7 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, return ret; } - if (rx_ring->cur_rx_idx >= RX_DESC_CNT) { + 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; @@ -175,7 +175,7 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, } #endif /* OSI_DEBUG */ - INCR_RX_DESC_INDEX(rx_ring->cur_rx_idx, 1U); + 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)) { @@ -266,7 +266,7 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, /* Context descriptor was consumed. Its skb * and DMA mapping will be recycled */ - INCR_RX_DESC_INDEX(rx_ring->cur_rx_idx, 1U); + 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)) { @@ -571,7 +571,7 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, 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 < TX_DESC_CNT) && + 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)); @@ -676,7 +676,7 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, tx_swcx->buf_virt_addr = OSI_NULL; tx_swcx->buf_phy_addr = 0; tx_swcx->flags = 0; - INCR_TX_DESC_INDEX(entry, 1U); + 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 @@ -990,7 +990,7 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, nveu32_t i; entry = tx_ring->cur_tx_idx; - if (entry >= TX_DESC_CNT) { + 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; @@ -1042,7 +1042,7 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, /* update packet id */ tx_desc->tdes0 = pkt_id; } - INCR_TX_DESC_INDEX(entry, 1U); + INCR_TX_DESC_INDEX(entry, osi_dma->tx_ring_sz); /* Storing context descriptor to set DMA_OWN at last */ cx_desc = tx_desc; @@ -1062,7 +1062,7 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, tx_swcx->pktid = pkt_id; } - INCR_TX_DESC_INDEX(entry, 1U); + INCR_TX_DESC_INDEX(entry, osi_dma->tx_ring_sz); first_desc = tx_desc; last_desc = tx_desc; @@ -1078,7 +1078,7 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, /* set HW OWN bit for descriptor*/ tx_desc->tdes3 |= TDES3_OWN; - INCR_TX_DESC_INDEX(entry, 1U); + 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; @@ -1131,7 +1131,7 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, #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, 1U), + 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 */ @@ -1199,7 +1199,7 @@ static nve32_t rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, rx_ring->cur_rx_idx = 0; rx_ring->refill_idx = 0; - for (i = 0; i < RX_DESC_CNT; i++) { + for (i = 0; i < osi_dma->rx_ring_sz; i++) { rx_swcx = rx_ring->rx_swcx + i; rx_desc = rx_ring->rx_desc + i; @@ -1237,7 +1237,7 @@ static nve32_t rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, } tailptr = rx_ring->rx_desc_phy_addr + - (sizeof(struct osi_rx_desc) * (RX_DESC_CNT)); + (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 */ @@ -1246,7 +1246,7 @@ static nve32_t rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, return -1; } - ops->set_rx_ring_len(osi_dma, chan, (RX_DESC_CNT - 1U)); + 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); @@ -1333,7 +1333,7 @@ static nve32_t tx_dma_desc_init(struct osi_dma_priv_data *osi_dma, return -1; } - for (j = 0; j < TX_DESC_CNT; j++) { + for (j = 0; j < osi_dma->tx_ring_sz; j++) { tx_desc = tx_ring->tx_desc + j; tx_swcx = tx_ring->tx_swcx + j; @@ -1356,7 +1356,7 @@ static nve32_t tx_dma_desc_init(struct osi_dma_priv_data *osi_dma, tx_ring->slot_check = OSI_DISABLE; ops->set_tx_ring_len(osi_dma, chan, - (TX_DESC_CNT - 1U)); + (osi_dma->tx_ring_sz - 1U)); ops->set_tx_ring_start_addr(osi_dma->base, chan, tx_ring->tx_desc_phy_addr); } From e563f11267f13ef0ad90d4eb5c5dcb2f51965655 Mon Sep 17 00:00:00 2001 From: Sanath Kumar Gampa <sgampa@nvidia.com> Date: Wed, 2 Mar 2022 12:45:38 +0530 Subject: [PATCH 346/458] osi:macsec: Changs to program key thorugh TzVault Bug 3568672 Change-Id: I35607905da986c50737f253874c090368e017388 Signed-off-by: Sanath Kumar Gampa <sgampa@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2676624 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-by: Nagaraj Annaiah <nannaiah@nvidia.com> Reviewed-by: Om Prakash Singh <omp@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Tested-by: Mahesh Patil <maheshp@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/Makefile.tmk | 4 ++-- osi/core/libnvethernetrm.export | 34 ++++++++++++++++----------------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/osi/core/Makefile.tmk b/osi/core/Makefile.tmk index 521160a..00ba1cb 100644 --- a/osi/core/Makefile.tmk +++ b/osi/core/Makefile.tmk @@ -47,9 +47,9 @@ NV_COMPONENT_SOURCES := \ $(NV_SOURCE)/nvethernetrm/osi/common/mgbe_common.c \ $(NV_SOURCE)/nvethernetrm/osi/core/macsec.c -#NV_COMPONENT_CFLAGS += -DMACSEC_SUPPORT +NV_COMPONENT_CFLAGS += -DMACSEC_SUPPORT +NV_COMPONENT_CFLAGS += -DDEBUG_MACSEC #NV_COMPONENT_CFLAGS += -DMACSEC_KEY_PROGRAM -#NV_COMPONENT_CFLAGS += -DDEBUG_MACSEC ifeq ($(NV_BUILD_CONFIGURATION_OS_IS_LINUX),1) NV_COMPONENT_CFLAGS += -DLINUX_OS diff --git a/osi/core/libnvethernetrm.export b/osi/core/libnvethernetrm.export index d27755a..28df803 100644 --- a/osi/core/libnvethernetrm.export +++ b/osi/core/libnvethernetrm.export @@ -30,20 +30,20 @@ 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 +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_loopback +osi_macsec_read_mmc +osi_macsec_dbg_events_config +osi_macsec_config_dbg_buf +osi_macsec_config_lut +osi_macsec_get_sc_lut_key_index +osi_macsec_update_mtu +# Enable below if MACSEC_KEY_PROGRAM is enabled +#osi_macsec_kt_config From 7889b203fa0d0c9ca7a840fe17a8ab6564e47157 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Mon, 17 Jan 2022 08:37:42 +0530 Subject: [PATCH 347/458] osi: dma: interrupt enable/disable retry Adds retry for interrupt enable/disable and combine interrupt handling part for EQOS/MGBE Bug 3503523 Change-Id: Icc8b10cd786c878972e2e508ede3edb8d52addf8 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2652907 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_dma.h | 38 -------- osi/dma/dma_local.h | 14 --- osi/dma/eqos_dma.c | 212 -------------------------------------------- osi/dma/eqos_dma.h | 8 -- osi/dma/hw_common.h | 3 +- osi/dma/mgbe_dma.c | 146 ------------------------------ osi/dma/mgbe_dma.h | 20 ----- osi/dma/osi_dma.c | 195 ++++++++++++++++++++++++++-------------- 8 files changed, 132 insertions(+), 504 deletions(-) diff --git a/include/osi_dma.h b/include/osi_dma.h index 934784f..852c94b 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -777,44 +777,6 @@ nve32_t osi_enable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, */ 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 * diff --git a/osi/dma/dma_local.h b/osi/dma/dma_local.h index 465fd03..1dc24c7 100644 --- a/osi/dma/dma_local.h +++ b/osi/dma/dma_local.h @@ -66,14 +66,6 @@ struct dma_chan_ops { /** 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 */ @@ -92,10 +84,6 @@ struct dma_chan_ops { 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); }; /** @@ -139,8 +127,6 @@ struct dma_local { 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 */ diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index 095ddbf..f6302fb 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -145,159 +145,6 @@ static void eqos_dma_safety_init(struct osi_dma_priv_data *osi_dma) 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. * @@ -897,59 +744,6 @@ static void eqos_config_slot(struct osi_dma_priv_data *osi_dma, } #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 */ @@ -971,10 +765,6 @@ void eqos_init_dma_chan_ops(struct dma_chan_ops *ops) 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; @@ -983,6 +773,4 @@ void eqos_init_dma_chan_ops(struct dma_chan_ops *ops) 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 index 7644438..2559590 100644 --- a/osi/dma/eqos_dma.h +++ b/osi/dma/eqos_dma.h @@ -55,9 +55,6 @@ #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)) /** @} */ /** @@ -66,8 +63,6 @@ * @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) @@ -76,9 +71,6 @@ #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) diff --git a/osi/dma/hw_common.h b/osi/dma/hw_common.h index a7b6335..48d48fc 100644 --- a/osi/dma/hw_common.h +++ b/osi/dma/hw_common.h @@ -30,7 +30,8 @@ * @{ */ #define HW_GLOBAL_DMA_STATUS 0x8700U +#define VIRT_INTR_CHX_CNTRL(x) (0x8600U + ((x) * 8U)) +#define VIRT_INTR_CHX_STATUS(x) (0x8604U + ((x) * 8U)) /** @} */ #endif /* INCLUDED_HW_COMMON_H */ - diff --git a/osi/dma/mgbe_dma.c b/osi/dma/mgbe_dma.c index eab9f3b..faae4c6 100644 --- a/osi/dma/mgbe_dma.c +++ b/osi/dma/mgbe_dma.c @@ -25,104 +25,6 @@ #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. * @@ -636,48 +538,6 @@ static nve32_t mgbe_validate_dma_regs(OSI_UNUSED 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 * @@ -728,16 +588,10 @@ void mgbe_init_dma_chan_ops(struct dma_chan_ops *ops) 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 index 9321501..351e09d 100644 --- a/osi/dma/mgbe_dma.h +++ b/osi/dma/mgbe_dma.h @@ -67,15 +67,6 @@ #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)) /** @} */ /** @@ -102,18 +93,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 diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 6d7e16f..f60125d 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -39,6 +39,86 @@ static struct dma_local g_dma[MAX_DMA_INSTANCES]; */ static struct dma_chan_ops g_ops[MAX_MAC_IP_TYPES]; +typedef nve32_t (*dma_intr_fn)(struct osi_dma_priv_data const *osi_dma, + nveu32_t intr_ctrl, nveu32_t intr_status, + nveu32_t dma_status, nveu32_t val); +static inline nve32_t enable_intr(struct osi_dma_priv_data const *osi_dma, + nveu32_t intr_ctrl, nveu32_t intr_status, + nveu32_t dma_status, nveu32_t val); +static inline nve32_t disable_intr(struct osi_dma_priv_data const *osi_dma, + nveu32_t intr_ctrl, nveu32_t intr_status, + nveu32_t dma_status, nveu32_t val); +static dma_intr_fn intr_fn[2] = { disable_intr, enable_intr }; + +static inline nveu32_t set_pos_val(nveu32_t val, nveu32_t pos_val) +{ + return (val | pos_val); +} + +static inline nveu32_t clear_pos_val(nveu32_t val, nveu32_t pos_val) +{ + return (val & ~pos_val); +} + +static inline nve32_t intr_en_dis_retry(nveu8_t *base, nveu32_t intr_ctrl, + nveu32_t val, nveu32_t en_dis) +{ + typedef nveu32_t (*set_clear)(nveu32_t val, nveu32_t pos); + set_clear set_clr[2] = { clear_pos_val, set_pos_val }; + nveu32_t cntrl1, cntrl2, i; + + for (i = 0U; i < 10U; i++) { + cntrl1 = osi_readl(base + intr_ctrl); + cntrl1 = set_clr[en_dis](cntrl1, val); + osi_writel(cntrl1, base + intr_ctrl); + + cntrl2 = osi_readl(base + intr_ctrl); + if (cntrl1 == cntrl2) { + break; + } else { + continue; + } + } + + /* failure case retry failed */ + if (i == 10U) { + return -1; + } + + return 0; +} + +static inline nve32_t enable_intr(struct osi_dma_priv_data const *osi_dma, + nveu32_t intr_ctrl, OSI_UNUSED nveu32_t intr_status, + OSI_UNUSED nveu32_t dma_status, nveu32_t val) +{ + return intr_en_dis_retry((nveu8_t *)osi_dma->base, intr_ctrl, + val, OSI_DMA_INTR_ENABLE); +} + +static inline nve32_t disable_intr(struct osi_dma_priv_data const *osi_dma, + nveu32_t intr_ctrl, nveu32_t intr_status, + nveu32_t dma_status, nveu32_t val) +{ + nveu8_t *base = (nveu8_t *)osi_dma->base; + const nveu32_t status_val[4] = { + 0, + EQOS_DMA_CHX_STATUS_CLEAR_TX, + EQOS_DMA_CHX_STATUS_CLEAR_RX, + 0, + }; + nveu32_t status; + + status = osi_readl(base + intr_status); + if ((status & val) == val) { + osi_writel(status_val[val], base + dma_status); + osi_writel(val, base + intr_status); + } + + return intr_en_dis_retry((nveu8_t *)osi_dma->base, intr_ctrl, + val, OSI_DMA_INTR_DISABLE); +} + struct osi_dma_priv_data *osi_get_dma(void) { nveu32_t i; @@ -320,17 +400,32 @@ nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) 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); + ret = intr_fn[OSI_DMA_INTR_ENABLE](osi_dma, + VIRT_INTR_CHX_CNTRL(chan), + VIRT_INTR_CHX_STATUS(chan), + ((osi_dma->mac == OSI_MAC_HW_MGBE) ? + MGBE_DMA_CHX_STATUS(chan) : + EQOS_DMA_CHX_STATUS(chan)), + OSI_BIT(OSI_DMA_CH_TX_INTR)); + if (ret < 0) { + return ret; + } + + ret = intr_fn[OSI_DMA_INTR_ENABLE](osi_dma, + VIRT_INTR_CHX_CNTRL(chan), + VIRT_INTR_CHX_STATUS(chan), + ((osi_dma->mac == OSI_MAC_HW_MGBE) ? + MGBE_DMA_CHX_STATUS(chan) : + EQOS_DMA_CHX_STATUS(chan)), + OSI_BIT(OSI_DMA_CH_RX_INTR)); + if (ret < 0) { + return ret; + } + l_dma->ops_p->start_dma(osi_dma, chan); } @@ -390,9 +485,12 @@ nve32_t osi_disable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, return -1; } - l_dma->ops_p->disable_chan_tx_intr(osi_dma->base, chan); - - return 0; + return intr_fn[OSI_DMA_INTR_DISABLE](osi_dma, VIRT_INTR_CHX_CNTRL(chan), + VIRT_INTR_CHX_STATUS(chan), + ((osi_dma->mac == OSI_MAC_HW_MGBE) ? + MGBE_DMA_CHX_STATUS(chan) : + EQOS_DMA_CHX_STATUS(chan)), + OSI_BIT(OSI_DMA_CH_TX_INTR)); } nve32_t osi_enable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, @@ -408,9 +506,12 @@ nve32_t osi_enable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, return -1; } - l_dma->ops_p->enable_chan_tx_intr(osi_dma->base, chan); - - return 0; + return intr_fn[OSI_DMA_INTR_ENABLE](osi_dma, VIRT_INTR_CHX_CNTRL(chan), + VIRT_INTR_CHX_STATUS(chan), + ((osi_dma->mac == OSI_MAC_HW_MGBE) ? + MGBE_DMA_CHX_STATUS(chan) : + EQOS_DMA_CHX_STATUS(chan)), + OSI_BIT(OSI_DMA_CH_TX_INTR)); } nve32_t osi_disable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, @@ -426,9 +527,12 @@ nve32_t osi_disable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, return -1; } - l_dma->ops_p->disable_chan_rx_intr(osi_dma->base, chan); - - return 0; + return intr_fn[OSI_DMA_INTR_DISABLE](osi_dma, VIRT_INTR_CHX_CNTRL(chan), + VIRT_INTR_CHX_STATUS(chan), + ((osi_dma->mac == OSI_MAC_HW_MGBE) ? + MGBE_DMA_CHX_STATUS(chan) : + EQOS_DMA_CHX_STATUS(chan)), + OSI_BIT(OSI_DMA_CH_RX_INTR)); } nve32_t osi_enable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, @@ -444,45 +548,12 @@ nve32_t osi_enable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, 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; + return intr_fn[OSI_DMA_INTR_ENABLE](osi_dma, VIRT_INTR_CHX_CNTRL(chan), + VIRT_INTR_CHX_STATUS(chan), + ((osi_dma->mac == OSI_MAC_HW_MGBE) ? + MGBE_DMA_CHX_STATUS(chan) : + EQOS_DMA_CHX_STATUS(chan)), + OSI_BIT(OSI_DMA_CH_RX_INTR)); } nveu32_t osi_get_global_dma_status(struct osi_dma_priv_data *osi_dma) @@ -502,13 +573,6 @@ nve32_t osi_handle_dma_intr(struct osi_dma_priv_data *osi_dma, 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; @@ -523,9 +587,10 @@ nve32_t osi_handle_dma_intr(struct osi_dma_priv_data *osi_dma, return -1; } - fn[l_dma->vm_intr][tx_rx][en_dis](osi_dma->base, chan); - - return 0; + return intr_fn[en_dis](osi_dma, VIRT_INTR_CHX_CNTRL(chan), + VIRT_INTR_CHX_STATUS(chan), ((osi_dma->mac == OSI_MAC_HW_MGBE) ? + MGBE_DMA_CHX_STATUS(chan) : EQOS_DMA_CHX_STATUS(chan)), + OSI_BIT(tx_rx)); } nve32_t osi_start_dma(struct osi_dma_priv_data *osi_dma, From 40a6108f50d40765894ed30dc6b6b1d91227e1a6 Mon Sep 17 00:00:00 2001 From: Om Prakash Singh <omp@nvidia.com> Date: Wed, 27 Apr 2022 07:25:50 +0530 Subject: [PATCH 348/458] osi: dma/core: add interface to configure debug interrupt add interface to configure debug related interrupt Bug 3600647 Change-Id: Iae43ceb441254b89a5b32ef9441ce42fca812e49 Signed-off-by: Om Prakash Singh <omp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2703337 Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_core.h | 3 ++ include/osi_dma.h | 3 ++ include/osi_macsec.h | 4 +- osi/core/macsec.c | 97 ++++++++++++++++++++++++++++++++------------ osi/core/mgbe_core.c | 6 --- osi/core/mgbe_core.h | 2 - osi/core/osi_hal.c | 9 ++++ osi/dma/dma_local.h | 4 ++ osi/dma/eqos_dma.c | 69 +++++++++++++++++++++++-------- osi/dma/eqos_dma.h | 4 +- osi/dma/mgbe_dma.c | 67 +++++++++++++++++++++++------- osi/dma/mgbe_dma.h | 4 +- osi/dma/osi_dma.c | 3 ++ 13 files changed, 207 insertions(+), 68 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index ccdfb27..866b5f1 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -249,6 +249,9 @@ typedef my_lint_64 nvel64_t; #ifdef HSI_SUPPORT #define OSI_CMD_HSI_CONFIGURE 51U #endif +#ifdef OSI_DEBUG +#define OSI_CMD_DEBUG_INTR_CONFIG 52U +#endif /** @} */ /** diff --git a/include/osi_dma.h b/include/osi_dma.h index 852c94b..d36ab0c 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -244,6 +244,7 @@ #ifdef OSI_DEBUG #define OSI_DMA_IOCTL_CMD_REG_DUMP 1U #define OSI_DMA_IOCTL_CMD_STRUCTS_DUMP 2U +#define OSI_DMA_IOCTL_CMD_DEBUG_INTR_CONFIG 3U #endif /* OSI_DEBUG */ /** @} */ @@ -528,6 +529,8 @@ struct osd_dma_ops { struct osi_dma_ioctl_data { /** IOCTL command number */ nveu32_t cmd; + /** IOCTL command argument */ + nveu32_t arg_u32; }; /** diff --git a/include/osi_macsec.h b/include/osi_macsec.h index 8d98bd3..aa03912 100644 --- a/include/osi_macsec.h +++ b/include/osi_macsec.h @@ -373,7 +373,9 @@ struct osi_macsec_core_ops { /** macsec set MTU size */ nve32_t (*update_mtu)(struct osi_core_priv_data *const osi_core, nveu32_t mtu); - +#ifdef OSI_DEBUG + void (*debug_intr_config)(struct osi_core_priv_data *const osi_core, nveu32_t enable); +#endif }; ////////////////////////////////////////////////////////////////////////// diff --git a/osi/core/macsec.c b/osi/core/macsec.c index d016a25..22aefba 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -4436,16 +4436,10 @@ static nve32_t macsec_init(struct osi_core_priv_data *const osi_core, LOG("Write MACSEC_STATS_CONTROL_0: 0x%x\n", val); osi_writela(osi_core, val, addr + MACSEC_STATS_CONTROL_0); - /* Enable default interrupts needed */ + /* Enable default HSI related 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); + val |= MACSEC_TX_MAC_CRC_ERROR_INT_EN; LOG("Write MACSEC_TX_IMR: 0x%x\n", val); osi_writela(osi_core, val, addr + MACSEC_TX_IMR); @@ -4454,28 +4448,11 @@ static nve32_t macsec_init(struct osi_core_priv_data *const osi_core, 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 - ); + val |= (MACSEC_RX_ICV_ERROR_INT_EN | + MACSEC_RX_MAC_CRC_ERROR_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. */ @@ -5280,6 +5257,69 @@ static nve32_t config_macsec(struct osi_core_priv_data *const osi_core, } } +#ifdef OSI_DEBUG +static void macsec_debug_intr_config(struct osi_core_priv_data *const osi_core, nveu32_t enable) +{ + nveu32_t val = 0; + nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; + + if (enable == OSI_ENABLE) { + val = osi_readla(osi_core, addr + MACSEC_TX_IMR); + val |= (MACSEC_TX_DBG_BUF_CAPTURE_DONE_INT_EN | + MACSEC_TX_MTU_CHECK_FAIL_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); + osi_writela(osi_core, val, addr + MACSEC_TX_IMR); + + val = osi_readla(osi_core, addr + MACSEC_RX_IMR); + + val |= (MACSEC_RX_DBG_BUF_CAPTURE_DONE_INT_EN | + RX_REPLAY_ERROR_INT_EN | + MACSEC_RX_MTU_CHECK_FAIL_INT_EN | + MACSEC_RX_AES_GCM_BUF_OVF_INT_EN | + MACSEC_RX_PN_EXHAUSTED_INT_EN + ); + osi_writela(osi_core, val, addr + MACSEC_RX_IMR); + + val = osi_readla(osi_core, addr + MACSEC_COMMON_IMR); + val |= (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 | + MACSEC_SECURE_REG_VIOL_INT_EN); + osi_writela(osi_core, val, addr + MACSEC_COMMON_IMR); + } else { + val = osi_readla(osi_core, addr + MACSEC_TX_IMR); + val &= (~MACSEC_TX_DBG_BUF_CAPTURE_DONE_INT_EN & + ~MACSEC_TX_MTU_CHECK_FAIL_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); + osi_writela(osi_core, val, addr + MACSEC_TX_IMR); + + val = osi_readla(osi_core, addr + MACSEC_RX_IMR); + val &= (~MACSEC_RX_DBG_BUF_CAPTURE_DONE_INT_EN & + ~RX_REPLAY_ERROR_INT_EN & + ~MACSEC_RX_MTU_CHECK_FAIL_INT_EN & + ~MACSEC_RX_AES_GCM_BUF_OVF_INT_EN & + ~MACSEC_RX_PN_EXHAUSTED_INT_EN + ); + osi_writela(osi_core, val, addr + MACSEC_RX_IMR); + + val = osi_readla(osi_core, addr + MACSEC_COMMON_IMR); + val &= (~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 & + ~MACSEC_SECURE_REG_VIOL_INT_EN); + osi_writela(osi_core, val, addr + MACSEC_COMMON_IMR); + } +} +#endif + /** * @brief osi_init_macsec_ops - macsec initialize operations * @@ -5326,6 +5366,9 @@ nve32_t osi_init_macsec_ops(struct osi_core_priv_data *const osi_core) .dbg_events_config = macsec_dbg_events_config, .get_sc_lut_key_index = macsec_get_key_index, .update_mtu = macsec_update_mtu, +#ifdef OSI_DEBUG + .debug_intr_config = macsec_debug_intr_config, +#endif }; if (osi_core->use_virtualization == OSI_ENABLE) { diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 18d03e2..da38797 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -2366,12 +2366,6 @@ static nve32_t mgbe_configure_mtl_queue(nveu32_t 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; } diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 8fc3368..c251a39 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -308,7 +308,6 @@ #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 @@ -426,7 +425,6 @@ #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) diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 0407070..81cb787 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -2057,6 +2057,15 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, ret = ops_p->core_hsi_configure(osi_core, data->arg1_u32); break; #endif + +#ifdef OSI_DEBUG + case OSI_CMD_DEBUG_INTR_CONFIG: +#ifdef MACSEC_SUPPORT + osi_core->macsec_ops->debug_intr_config(osi_core, data->arg1_u32); +#endif + ret = 0; + break; +#endif default: OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "CORE: Incorrect command\n", diff --git a/osi/dma/dma_local.h b/osi/dma/dma_local.h index 1dc24c7..3c0bb3d 100644 --- a/osi/dma/dma_local.h +++ b/osi/dma/dma_local.h @@ -84,6 +84,10 @@ struct dma_chan_ops { nveu32_t set, nveu32_t interval); #endif /* !OSI_STRIPPED_LIB */ +#ifdef OSI_DEBUG + /** Called to enable/disable debug interrupt */ + void (*debug_intr_config)(struct osi_dma_priv_data *osi_dma); +#endif }; /** diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index f6302fb..dab365d 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -476,26 +476,11 @@ static void eqos_configure_dma_channel(nveu32_t chan, 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); + value |= (EQOS_DMA_CHX_INTR_TIE | EQOS_DMA_CHX_INTR_RIE); 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); @@ -752,7 +737,56 @@ void *eqos_get_dma_safety_config(void) return &eqos_dma_safety_config; } +#ifdef OSI_DEBUG /** + * @brief Enable/disable debug interrupt + * + * @param[in] osi_dma: OSI DMA private data structure. + * + * Algorithm: + * - if osi_dma->ioctl_data.arg_u32 == OSI_ENABLE enable debug interrupt + * - else disable bebug inerrupts + */ +static void eqos_debug_intr_config(struct osi_dma_priv_data *osi_dma) +{ + nveu32_t chinx; + nveu32_t chan; + nveu32_t val; + nveu32_t enable = osi_dma->ioctl_data.arg_u32; + + if (enable == OSI_ENABLE) { + for (chinx = 0; chinx < osi_dma->num_dma_chans; chinx++) { + chan = osi_dma->dma_chans[chinx]; + val = osi_readl((nveu8_t *)osi_dma->base + + EQOS_DMA_CHX_INTR_ENA(chan)); + + val |= (EQOS_DMA_CHX_INTR_AIE | + EQOS_DMA_CHX_INTR_FBEE | + EQOS_DMA_CHX_INTR_RBUE | + EQOS_DMA_CHX_INTR_TBUE | + EQOS_DMA_CHX_INTR_NIE); + osi_writel(val, (nveu8_t *)osi_dma->base + + EQOS_DMA_CHX_INTR_ENA(chan)); + } + + } else { + for (chinx = 0; chinx < osi_dma->num_dma_chans; chinx++) { + chan = osi_dma->dma_chans[chinx]; + val = osi_readl((nveu8_t *)osi_dma->base + + EQOS_DMA_CHX_INTR_ENA(chan)); + val &= (~EQOS_DMA_CHX_INTR_AIE & + ~EQOS_DMA_CHX_INTR_FBEE & + ~EQOS_DMA_CHX_INTR_RBUE & + ~EQOS_DMA_CHX_INTR_TBUE & + ~EQOS_DMA_CHX_INTR_NIE); + osi_writel(val, (nveu8_t *)osi_dma->base + + EQOS_DMA_CHX_INTR_ENA(chan)); + } + } +} +#endif + +/* * @brief eqos_init_dma_chan_ops - Initialize EQOS DMA operations. * * @param[in] ops: DMA channel operations pointer. @@ -773,4 +807,7 @@ void eqos_init_dma_chan_ops(struct dma_chan_ops *ops) ops->validate_regs = eqos_validate_dma_regs; ops->config_slot = eqos_config_slot; #endif /* !OSI_STRIPPED_LIB */ +#ifdef OSI_DEBUG + ops->debug_intr_config = eqos_debug_intr_config; +#endif } diff --git a/osi/dma/eqos_dma.h b/osi/dma/eqos_dma.h index 2559590..b1a595b 100644 --- a/osi/dma/eqos_dma.h +++ b/osi/dma/eqos_dma.h @@ -72,12 +72,14 @@ (EQOS_DMA_CHX_STATUS_RI | EQOS_DMA_CHX_STATUS_NIS) #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) +#ifdef OSI_DEBUG +#define EQOS_DMA_CHX_INTR_TBUE OSI_BIT(2) #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) +#endif #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) diff --git a/osi/dma/mgbe_dma.c b/osi/dma/mgbe_dma.c index faae4c6..f728fe8 100644 --- a/osi/dma/mgbe_dma.c +++ b/osi/dma/mgbe_dma.c @@ -284,24 +284,11 @@ static void mgbe_configure_dma_channel(nveu32_t chan, 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); + value |= (MGBE_DMA_CHX_INTR_TIE | MGBE_DMA_CHX_INTR_RIE); osi_writel(value, (nveu8_t *)osi_dma->base + MGBE_DMA_CHX_INTR_ENA(chan)); @@ -580,6 +567,55 @@ static void mgbe_config_slot(struct osi_dma_priv_data *osi_dma, } } +#ifdef OSI_DEBUG +/** + * @brief Enable/disable debug interrupt + * + * @param[in] osi_dma: OSI DMA private data structure. + * + * Algorithm: + * - if osi_dma->ioctl_data.arg_u32 == OSI_ENABLE enable debug interrupt + * - else disable bebug inerrupts + */ +static void mgbe_debug_intr_config(struct osi_dma_priv_data *osi_dma) +{ + nveu32_t chinx; + nveu32_t chan; + nveu32_t val; + nveu32_t enable = osi_dma->ioctl_data.arg_u32; + + if (enable == OSI_ENABLE) { + for (chinx = 0; chinx < osi_dma->num_dma_chans; chinx++) { + chan = osi_dma->dma_chans[chinx]; + val = osi_readl((nveu8_t *)osi_dma->base + + MGBE_DMA_CHX_INTR_ENA(chan)); + + val |= (MGBE_DMA_CHX_INTR_AIE | + MGBE_DMA_CHX_INTR_FBEE | + MGBE_DMA_CHX_INTR_RBUE | + MGBE_DMA_CHX_INTR_TBUE | + MGBE_DMA_CHX_INTR_NIE); + osi_writel(val, (nveu8_t *)osi_dma->base + + MGBE_DMA_CHX_INTR_ENA(chan)); + } + + } else { + for (chinx = 0; chinx < osi_dma->num_dma_chans; chinx++) { + chan = osi_dma->dma_chans[chinx]; + val = osi_readl((nveu8_t *)osi_dma->base + + MGBE_DMA_CHX_INTR_ENA(chan)); + val &= (~MGBE_DMA_CHX_INTR_AIE & + ~MGBE_DMA_CHX_INTR_FBEE & + ~MGBE_DMA_CHX_INTR_RBUE & + ~MGBE_DMA_CHX_INTR_TBUE & + ~MGBE_DMA_CHX_INTR_NIE); + osi_writel(val, (nveu8_t *)osi_dma->base + + MGBE_DMA_CHX_INTR_ENA(chan)); + } + } +} +#endif + void mgbe_init_dma_chan_ops(struct dma_chan_ops *ops) { ops->set_tx_ring_len = mgbe_set_tx_ring_len; @@ -594,4 +630,7 @@ void mgbe_init_dma_chan_ops(struct dma_chan_ops *ops) ops->set_rx_buf_len = mgbe_set_rx_buf_len; ops->validate_regs = mgbe_validate_dma_regs; ops->config_slot = mgbe_config_slot; +#ifdef OSI_DEBUG + ops->debug_intr_config = mgbe_debug_intr_config; +#endif }; diff --git a/osi/dma/mgbe_dma.h b/osi/dma/mgbe_dma.h index 351e09d..52495cd 100644 --- a/osi/dma/mgbe_dma.h +++ b/osi/dma/mgbe_dma.h @@ -87,12 +87,14 @@ #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) +#ifdef OSI_DEBUG +#define MGBE_DMA_CHX_INTR_TBUE OSI_BIT(2) #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) +#endif #define MGBE_DMA_CHX_SLOT_ESC OSI_BIT(0) #define MGBE_DMA_CHX_TX_CNTRL2_ORRQ_RECOMMENDED 64U #define MGBE_DMA_CHX_TX_CNTRL2_ORRQ_SHIFT 24U diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index f60125d..d1bf7f7 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -867,6 +867,9 @@ nve32_t osi_dma_ioctl(struct osi_dma_priv_data *osi_dma) case OSI_DMA_IOCTL_CMD_STRUCTS_DUMP: structs_dump(osi_dma); break; + case OSI_DMA_IOCTL_CMD_DEBUG_INTR_CONFIG: + l_dma->ops_p->debug_intr_config(osi_dma); + break; #endif /* OSI_DEBUG */ default: OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, From 8e2a85224d9ddcfd223b12df7aa68e2272dbf99e Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Wed, 18 May 2022 09:46:41 +0530 Subject: [PATCH 349/458] osi: dma: remove unused functions Remove below functions which are not used. osi_enable_chan_tx_intr osi_disable_chan_tx_intr osi_disable_chan_rx_intr osi_enable_chan_rx_intr Bug 3503523 Change-Id: I1b414c3d763922d3d87b29516de8d0bdc0ac5526 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2714137 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_dma.h | 152 ---------------------------------------------- osi/dma/osi_dma.c | 84 ------------------------- 2 files changed, 236 deletions(-) diff --git a/include/osi_dma.h b/include/osi_dma.h index d36ab0c..92ca752 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -613,158 +613,6 @@ struct osi_dma_priv_data { 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. * diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index d1bf7f7..61d44a2 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -472,90 +472,6 @@ nve32_t osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma) 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; - } - - return intr_fn[OSI_DMA_INTR_DISABLE](osi_dma, VIRT_INTR_CHX_CNTRL(chan), - VIRT_INTR_CHX_STATUS(chan), - ((osi_dma->mac == OSI_MAC_HW_MGBE) ? - MGBE_DMA_CHX_STATUS(chan) : - EQOS_DMA_CHX_STATUS(chan)), - OSI_BIT(OSI_DMA_CH_TX_INTR)); -} - -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; - } - - return intr_fn[OSI_DMA_INTR_ENABLE](osi_dma, VIRT_INTR_CHX_CNTRL(chan), - VIRT_INTR_CHX_STATUS(chan), - ((osi_dma->mac == OSI_MAC_HW_MGBE) ? - MGBE_DMA_CHX_STATUS(chan) : - EQOS_DMA_CHX_STATUS(chan)), - OSI_BIT(OSI_DMA_CH_TX_INTR)); -} - -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; - } - - return intr_fn[OSI_DMA_INTR_DISABLE](osi_dma, VIRT_INTR_CHX_CNTRL(chan), - VIRT_INTR_CHX_STATUS(chan), - ((osi_dma->mac == OSI_MAC_HW_MGBE) ? - MGBE_DMA_CHX_STATUS(chan) : - EQOS_DMA_CHX_STATUS(chan)), - OSI_BIT(OSI_DMA_CH_RX_INTR)); -} - -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; - } - - return intr_fn[OSI_DMA_INTR_ENABLE](osi_dma, VIRT_INTR_CHX_CNTRL(chan), - VIRT_INTR_CHX_STATUS(chan), - ((osi_dma->mac == OSI_MAC_HW_MGBE) ? - MGBE_DMA_CHX_STATUS(chan) : - EQOS_DMA_CHX_STATUS(chan)), - OSI_BIT(OSI_DMA_CH_RX_INTR)); -} - nveu32_t osi_get_global_dma_status(struct osi_dma_priv_data *osi_dma) { struct dma_local *l_dma = (struct dma_local *)osi_dma; From 0b70de0b07c1374645c0cd7da05b9839bd37c1ea Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Thu, 12 May 2022 17:12:30 +0530 Subject: [PATCH 350/458] osi: core: removed unused code Issue: Called same function 2 times in interrupt handler. Fix: Remove extra call and write operation to status register. Change-Id: Iaa2a4815c90430e293b1d66b45855035cc03e6c4 Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2711620 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/eqos_core.c | 19 +++++-------------- osi/core/mgbe_core.c | 8 +------- 2 files changed, 6 insertions(+), 21 deletions(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index ed6cf58..fde5c17 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -2528,6 +2528,11 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, mac_isr = osi_readla(osi_core, (nveu8_t *)osi_core->base + EQOS_MAC_ISR); + /* Handle MAC interrupts */ + if ((dma_isr & EQOS_DMA_ISR_MACIS) != EQOS_DMA_ISR_MACIS) { + return; + } + #ifdef HSI_SUPPORT if (osi_core->mac_ver >= OSI_EQOS_MAC_5_30) { /* T23X-EQOS_HSIv2-19: Consistency Monitor for TX Frame */ @@ -2547,10 +2552,6 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, } } #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, @@ -2566,10 +2567,7 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, 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); @@ -2608,13 +2606,6 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, /* 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 */ diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index da38797..8892717 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -3505,7 +3505,6 @@ static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core, 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) { @@ -3537,8 +3536,6 @@ static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core, } } - 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; @@ -3597,11 +3594,8 @@ static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core, (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 */ + return; } /** From cba4430d3c8ca586fcee7ae143c1f303467cdf9d Mon Sep 17 00:00:00 2001 From: Om Prakash Singh <omp@nvidia.com> Date: Tue, 17 May 2022 12:08:36 +0530 Subject: [PATCH 351/458] osi: core: enable FSM_CONTROL.TMOUTEN 1) set NTMRMD value 2 to avoid timeout at the time of interface up 2) FSM_CONTROL.TMOUTEN bit Bug 3584387 Change-Id: I46cba0cc2322e4752f4c9abff0bd72f01d5b9fd2 Signed-off-by: Om Prakash Singh <omp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2713538 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/eqos_core.c | 5 ++--- osi/core/mgbe_core.c | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index fde5c17..5960ef9 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1748,14 +1748,13 @@ static int eqos_hsi_configure(struct osi_core_priv_data *const osi_core, /* 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; + value |= (0x2U << 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; + value = (EQOS_PRTYEN | EQOS_TMOUTEN); osi_writela(osi_core, value, (nveu8_t *)osi_core->base + EQOS_MAC_FSM_CONTROL); diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 8892717..2c6ee37 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -2608,14 +2608,13 @@ static int mgbe_hsi_configure(struct osi_core_priv_data *const osi_core, 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; + value |= (0x2U << 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; + value = (MGBE_PRTYEN | MGBE_TMOUTEN); osi_writela(osi_core, value, (nveu8_t *)osi_core->base + MGBE_MAC_FSM_CONTROL); From 1c69bdf4d0d99cde0ca4a2deca0b900a9cde3277 Mon Sep 17 00:00:00 2001 From: Om Prakash Singh <omp@nvidia.com> Date: Thu, 26 May 2022 12:47:52 +0530 Subject: [PATCH 352/458] ivc: add change to support diag interface Add below IVC commands that will be use by nvethmgr for diag test: nvethmgr_get_status nvethmgr_verify_ts nvethmgr_get_avb_perf Bug 3620612 Change-Id: I900e97e12988035648b86fe2e8becaa6f312b256 Signed-off-by: Om Prakash Singh <omp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2709692 Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/ivc_core.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/ivc_core.h b/include/ivc_core.h index e8da34f..88900fe 100644 --- a/include/ivc_core.h +++ b/include/ivc_core.h @@ -59,6 +59,9 @@ typedef enum ivc_cmd { dbg_events_config_macsec, macsec_get_sc_lut_key_index, macsec_update_mtu_size, + nvethmgr_get_status, + nvethmgr_verify_ts, + nvethmgr_get_avb_perf, }ivc_cmd; /** From d24f3f9e2ef771bc3d7b72584482266a8940d2db Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Tue, 1 Feb 2022 13:10:35 +0530 Subject: [PATCH 353/458] osi: core: support for suspend/resume IOCTL's Issue: While ethernet going into suspend all registers of controllers saved through save_registers IOCTL and same will be restored during resume. Register restoring without following sequence will lead to multiple issues. Fix: For every dynamic configuration save the input parameters and use the same parameters through API's to restore the controller configuration. API approach will follow the specific sequence for programming the controller registers. Bug 3665476 Change-Id: Ia31303daf0ba5c78f3eb5cd2706a1ce420536539 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2662333 Reviewed-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_core.h | 4 +- osi/core/core_local.h | 122 ++++++++++++++ osi/core/osi_hal.c | 372 ++++++++++++++++++++++++++++++++++------- osi/core/vlan_filter.h | 8 +- 4 files changed, 440 insertions(+), 66 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 866b5f1..01cc735 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -252,6 +252,8 @@ typedef my_lint_64 nvel64_t; #ifdef OSI_DEBUG #define OSI_CMD_DEBUG_INTR_CONFIG 52U #endif +#define OSI_CMD_SUSPEND 53U +#define OSI_CMD_RESUME 54U /** @} */ /** @@ -2270,7 +2272,7 @@ void *eqos_get_core_safety_config(void); * @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, + struct osi_l3_l4_filter *const l_filter, const nveu32_t type, const nveu32_t dma_routing_enable, const nveu32_t dma_chan, diff --git a/osi/core/core_local.h b/osi/core/core_local.h index d616c53..453e8e8 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -43,6 +43,21 @@ */ #define MAX_TX_TS_CNT (PKT_ID_CNT * OSI_MGBE_MAX_NUM_CHANS) +/** + * @brief Dynamic configuration helper macros. + */ +#define DYNAMIC_CFG_L3_L4 OSI_BIT(0) +#define DYNAMIC_CFG_FC OSI_BIT(1) +#define DYNAMIC_CFG_AVB OSI_BIT(2) +#define DYNAMIC_CFG_L2 OSI_BIT(3) +#define DYNAMIC_CFG_RXCSUM OSI_BIT(4) +#define DYNAMIC_CFG_VLAN OSI_BIT(5) +#define DYNAMIC_CFG_EEE OSI_BIT(6) +#define DYNAMIC_CFG_PTP OSI_BIT(7) +#define DYNAMIC_CFG_EST OSI_BIT(8) +#define DYNAMIC_CFG_FPE OSI_BIT(9) +#define OSI_SUSPENDED OSI_BIT(0) + /** * interface core ops */ @@ -330,6 +345,82 @@ struct core_ptp_servo { nveu32_t m2m_lock; }; +/** + * @brief L3/L4 dynamic config storage structure. + */ +struct l3_l4_filters { + /** Represent whether index used or not */ + nveu32_t used; + /** Type of filter */ + nveu32_t type; + /** Represents whether DMA routing enabled or not */ + nveu32_t dma_routing_enable; + /** DMA channel number of routing enabled */ + nveu32_t dma_chan; + /** Tells whether its L4 or L3 filter */ + nveu32_t is_l4_filter; + /** Filter information */ + struct osi_l3_l4_filter l3l4_filter; +}; + +/** + * @brief AVB dynamic config storage structure + */ +struct core_avb { + /** Represend whether AVB config done or not */ + nveu32_t used; + /** AVB data structure */ + struct osi_core_avb_algorithm avb_info; +}; + +/** + * @brief VLAN dynamic config storage structure + */ +struct core_vlan { + /** VID to be stored */ + nveu32_t vid; + /** Represens whether VLAN config done or not */ + nveu32_t used; +}; + +/** + * @brief L2 filter dynamic config storage structure + */ +struct core_l2 { + nveu32_t used; + struct osi_filter filter; +}; + +/** + * @brief Dynamic config storage structure + */ +struct dynamic_cfg { + nveu32_t flags; + /** L3_L4 filters */ + struct l3_l4_filters l3_l4[OSI_MGBE_MAX_L3_L4_FILTER]; + /** flow control */ + nveu32_t flow_ctrl; + /** AVB */ + struct core_avb avb[OSI_MGBE_MAX_NUM_QUEUES]; + /** RXCSUM */ + nveu32_t rxcsum; + /** VLAN arguments storage */ + struct core_vlan vlan[VLAN_NUM_VID]; + /** LPI parameters storage */ + nveu32_t tx_lpi_enabled; + nveu32_t tx_lpi_timer; + /** PTP information storage */ + nveu32_t ptp; + /** EST information storage */ + struct osi_est_config est; + /** FPE information storage */ + struct osi_fpe_config fpe; + /** L2 filter storage */ + struct osi_filter l2_filter; + /** L2 filter configuration */ + struct core_l2 l2[EQOS_MAX_MAC_ADDRESS_FILTER]; +}; + /** * @brief Core local data structure. */ @@ -370,8 +461,39 @@ struct core_local { nveu32_t pps_freq; /** Time interval mask for GCL entry */ nveu32_t ti_mask; + /** HW Tx fifo size */ + nveu32_t tx_fifo_size; + /** HW RX fifo size */ + nveu32_t rx_fifo_size; + /** Hardware dynamic configuration context */ + struct dynamic_cfg cfg; + /** Hardware dynamic configuration state */ + nveu32_t state; }; +/** + * @brief update_counter_u - Increment unsigned int counter + * + * @param[out] value: Pointer to value to be incremented. + * @param[in] incr: increment value + * + * @note + * API Group: + * - Initialization: Yes + * - Run time: No + * - De-initialization: No + */ +static inline void update_counter_u(nveu32_t *value, nveu32_t incr) +{ + nveu32_t temp = *value + incr; + + if (temp < *value) { + /* Overflow, so reset it to zero */ + *value = 0U; + } + *value = temp; +} + /** * @brief eqos_init_core_ops - Initialize EQOS core operations. * diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 81cb787..7d89a5e 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -110,7 +110,7 @@ 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; + struct core_local *l_core = (struct core_local *)(void *)osi_core; if (validate_args(osi_core, l_core) < 0) { return -1; @@ -121,8 +121,9 @@ nve32_t osi_hal_write_phy_reg(struct osi_core_priv_data *const osi_core, 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; + struct core_local *l_core = (struct core_local *)(void *)osi_core; if (validate_args(osi_core, l_core) < 0) { return -1; @@ -133,8 +134,8 @@ nve32_t osi_hal_read_phy_reg(struct osi_core_priv_data *const osi_core, 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 *); + struct core_local *l_core = (struct core_local *)(void *)osi_core; + typedef void (*init_ops_arr)(struct core_ops *local_ops); typedef void *(*safety_init)(void); init_ops_arr i_ops[MAX_MAC_IP_TYPES][MAX_MAC_IP_TYPES] = { @@ -202,7 +203,7 @@ static nve32_t osi_hal_init_core_ops(struct osi_core_priv_data *const osi_core) 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; + struct core_local *l_core = (struct core_local *)(void *)osi_core; if (validate_args(osi_core, l_core) < 0) { return -1; @@ -233,7 +234,7 @@ static inline void init_vlan_filters(struct osi_core_priv_data *const osi_core) 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; + struct core_local *l_core = (struct core_local *)(void *)osi_core; nve32_t ret; if (validate_args(osi_core, l_core) < 0) { @@ -246,17 +247,20 @@ nve32_t osi_hal_hw_core_init(struct osi_core_priv_data *const osi_core, 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; + if (ret < 0) { + return ret; } + l_core->tx_fifo_size = tx_fifo_size; + l_core->rx_fifo_size = rx_fifo_size; + 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; + struct core_local *l_core = (struct core_local *)(void *)osi_core; if (validate_args(osi_core, l_core) < 0) { return -1; @@ -265,6 +269,13 @@ nve32_t osi_hal_hw_core_deinit(struct osi_core_priv_data *const osi_core) l_core->hw_init_successful = OSI_DISABLE; l_core->ops_p->core_deinit(osi_core); + if (l_core->state != OSI_SUSPENDED) { + /* Reset restore operation flags on interface down */ + l_core->cfg.flags = OSI_DISABLE; + } + + l_core->state = OSI_DISABLE; + /* FIXME: Should be fixed */ //l_core->init_done = OSI_DISABLE; //l_core->magic_num = 0; @@ -274,7 +285,7 @@ nve32_t osi_hal_hw_core_deinit(struct osi_core_priv_data *const osi_core) nve32_t osi_start_mac(struct osi_core_priv_data *const osi_core) { - struct core_local *l_core = (struct core_local *)osi_core; + struct core_local *l_core = (struct core_local *)(void *)osi_core; if (validate_args(osi_core, l_core) < 0) { return -1; @@ -287,7 +298,7 @@ nve32_t osi_start_mac(struct osi_core_priv_data *const osi_core) nve32_t osi_stop_mac(struct osi_core_priv_data *const osi_core) { - struct core_local *l_core = (struct core_local *)osi_core; + struct core_local *l_core = (struct core_local *)(void *)osi_core; if (validate_args(osi_core, l_core) < 0) { return -1; @@ -300,7 +311,7 @@ nve32_t osi_stop_mac(struct osi_core_priv_data *const osi_core) nve32_t osi_common_isr(struct osi_core_priv_data *const osi_core) { - struct core_local *l_core = (struct core_local *)osi_core; + struct core_local *l_core = (struct core_local *)(void *)osi_core; if (validate_args(osi_core, l_core) < 0) { return -1; @@ -314,7 +325,7 @@ nve32_t osi_common_isr(struct osi_core_priv_data *const osi_core) 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; + struct core_local *l_core = (struct core_local *)(void *)osi_core; if (validate_args(osi_core, l_core) < 0) { return -1; @@ -326,7 +337,7 @@ nve32_t osi_set_mode(struct osi_core_priv_data *const osi_core, 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; + struct core_local *l_core = (struct core_local *)(void *)osi_core; if (validate_args(osi_core, l_core) < 0) { return -1; @@ -337,7 +348,7 @@ nve32_t osi_set_speed(struct osi_core_priv_data *const osi_core, nve32_t osi_pad_calibrate(struct osi_core_priv_data *const osi_core) { - struct core_local *l_core = (struct core_local *)osi_core; + struct core_local *l_core = (struct core_local *)(void *)osi_core; if (validate_args(osi_core, l_core) < 0) { return -1; @@ -349,7 +360,7 @@ nve32_t osi_pad_calibrate(struct osi_core_priv_data *const 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; + struct core_local *l_core = (struct core_local *)(void *)osi_core; if (validate_args(osi_core, l_core) < 0) { return -1; @@ -362,7 +373,7 @@ nve32_t osi_config_fw_err_pkts(struct osi_core_priv_data *const osi_core, 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; + struct core_local *l_core = (struct core_local *)(void *)osi_core; int ret = -1; /* Validate input arguments */ @@ -442,7 +453,7 @@ static nve32_t conf_ptp_offload(struct osi_core_priv_data *const osi_core, 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; + struct core_local *l_core = (struct core_local *)(void *)osi_core; nve32_t ret; if ((validate_args(osi_core, l_core) < 0) || (filter == OSI_NULL)) { @@ -505,7 +516,7 @@ nve32_t osi_l2_filter(struct osi_core_priv_data *const osi_core, 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, + struct osi_l3_l4_filter *l_filter, nveu32_t type, nveu32_t dma_routing_enable, nveu32_t dma_chan) @@ -513,11 +524,11 @@ static inline nve32_t helper_l4_filter( nve32_t ret = 0; ret = ops_p->config_l4_filters(osi_core, - l_filter.filter_no, - l_filter.filter_enb_dis, + l_filter->filter_no, + l_filter->filter_enb_dis, type, - l_filter.src_dst_addr_match, - l_filter.perfect_inverse_match, + l_filter->src_dst_addr_match, + l_filter->perfect_inverse_match, dma_routing_enable, dma_chan); if (ret < 0) { @@ -527,9 +538,9 @@ static inline nve32_t helper_l4_filter( } return ops_p->update_l4_port_no(osi_core, - l_filter.filter_no, - l_filter.port_no, - l_filter.src_dst_addr_match); + l_filter->filter_no, + l_filter->port_no, + l_filter->src_dst_addr_match); } /** @@ -555,7 +566,7 @@ static inline nve32_t helper_l4_filter( 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, + struct osi_l3_l4_filter *l_filter, nveu32_t type, nveu32_t dma_routing_enable, nveu32_t dma_chan) @@ -563,11 +574,11 @@ static inline nve32_t helper_l3_filter( nve32_t ret = 0; ret = ops_p->config_l3_filters(osi_core, - l_filter.filter_no, - l_filter.filter_enb_dis, + l_filter->filter_no, + l_filter->filter_enb_dis, type, - l_filter.src_dst_addr_match, - l_filter.perfect_inverse_match, + l_filter->src_dst_addr_match, + l_filter->perfect_inverse_match, dma_routing_enable, dma_chan); if (ret < 0) { @@ -577,12 +588,12 @@ static inline nve32_t helper_l3_filter( } if (type == OSI_IP6_FILTER) { - ret = ops_p->update_ip6_addr(osi_core, l_filter.filter_no, - l_filter.ip6_addr); + 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); + 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); @@ -593,11 +604,11 @@ static inline nve32_t helper_l3_filter( } nve32_t osi_l3l4_filter(struct osi_core_priv_data *const osi_core, - const struct osi_l3_l4_filter l_filter, + struct osi_l3_l4_filter *const 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; + struct core_local *l_core = (struct core_local *)(void *)osi_core; nve32_t ret = -1; if (validate_args(osi_core, l_core) < 0) { @@ -640,7 +651,7 @@ nve32_t osi_l3l4_filter(struct osi_core_priv_data *const osi_core, 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; + struct core_local *l_core = (struct core_local *)(void *)osi_core; if (validate_args(osi_core, l_core) < 0) { return -1; @@ -652,7 +663,7 @@ nve32_t osi_config_rxcsum_offload(struct osi_core_priv_data *const osi_core, 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; + struct core_local *l_core = (struct core_local *)(void *)osi_core; if (validate_args(osi_core, l_core) < 0) { return -1; @@ -688,7 +699,7 @@ static inline nveu64_t div_u64(nveu64_t dividend, 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; + struct core_local *l_core = (struct core_local *)(void *)osi_core; nveu64_t adj; nveu64_t temp; @@ -749,7 +760,7 @@ nve32_t osi_adjust_freq(struct osi_core_priv_data *const osi_core, nve32_t ppb) 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; + struct core_local *l_core = (struct core_local *)(void *)osi_core; nveu32_t neg_adj = 0; nveu32_t sec = 0, nsec = 0; nveu64_t quotient; @@ -794,7 +805,7 @@ nve32_t osi_adjust_time(struct osi_core_priv_data *const osi_core, 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; + struct core_local *l_core = (struct core_local *)(void *)osi_core; nve32_t ret = 0; nveu64_t temp = 0, temp1 = 0, temp2 = 0; nveu64_t ssinc = 0; @@ -904,7 +915,7 @@ nve32_t osi_ptp_configuration(struct osi_core_priv_data *const osi_core, 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; + struct core_local *l_core = (struct core_local *)(void *)osi_core; if (rxq_route->route_type != OSI_RXQ_ROUTE_PTP) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, @@ -920,7 +931,7 @@ static nve32_t rxq_route_config(struct osi_core_priv_data *const osi_core, nve32_t osi_read_mmc(struct osi_core_priv_data *const osi_core) { - struct core_local *l_core = (struct core_local *)osi_core; + struct core_local *l_core = (struct core_local *)(void *)osi_core; if (validate_args(osi_core, l_core) < 0) { return -1; @@ -934,7 +945,7 @@ nve32_t osi_read_mmc(struct osi_core_priv_data *const osi_core) 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; + struct core_local *l_core = (struct core_local *)(void *)osi_core; if (validate_args(osi_core, l_core) < 0) { return -1; @@ -997,7 +1008,7 @@ nve32_t osi_get_mac_version(struct osi_core_priv_data *const osi_core, */ static nve32_t validate_core_regs(struct osi_core_priv_data *const osi_core) { - struct core_local *l_core = (struct core_local *)osi_core; + struct core_local *l_core = (struct core_local *)(void *)osi_core; if (osi_core->safety_config == OSI_NULL) { OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, @@ -1042,7 +1053,7 @@ static nve32_t validate_core_regs(struct osi_core_priv_data *const osi_core) 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; + struct core_local *const l_core = (struct core_local *)(void *)osi_core; unsigned int action = vid & VLAN_ACTION_MASK; unsigned short vlan_id = vid & VLAN_VID_MASK; @@ -1101,7 +1112,7 @@ static nve32_t vlan_id_update(struct osi_core_priv_data *const osi_core, 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; + struct core_local *l_core = (struct core_local *)(void *)osi_core; if ((tx_lpi_timer >= OSI_MAX_TX_LPI_TIMER) || (tx_lpi_timer <= OSI_MIN_TX_LPI_TIMER) || @@ -1149,7 +1160,7 @@ static nve32_t conf_eee(struct osi_core_priv_data *const osi_core, 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; + struct core_local *l_core = (struct core_local *)(void *)osi_core; if (cmd == OSI_NULL) { OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, @@ -1206,7 +1217,7 @@ 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; + struct core_local *l_core = (struct core_local *)(void *)osi_core; if (ip_addr == OSI_NULL) { OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, @@ -1257,7 +1268,7 @@ static nve32_t conf_arp_offload(struct osi_core_priv_data *const osi_core, 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; + struct core_local *l_core = (struct core_local *)(void *)osi_core; /* don't allow only if loopback mode is other than 0 or 1 */ if (lb_mode != OSI_ENABLE && lb_mode != OSI_DISABLE) { @@ -1313,7 +1324,7 @@ static nve32_t conf_mac_loopback(struct osi_core_priv_data *const osi_core, 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; + struct core_local *l_core = (struct core_local *)(void *)osi_core; if (est == OSI_NULL) { OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, @@ -1368,7 +1379,7 @@ static nve32_t config_est(struct osi_core_priv_data *osi_core, 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; + struct core_local *l_core = (struct core_local *)(void *)osi_core; if (fpe == OSI_NULL) { OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, @@ -1393,7 +1404,7 @@ static nve32_t config_fpe(struct osi_core_priv_data *osi_core, 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 core_local *l_core = (struct core_local *)(void *)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; @@ -1427,7 +1438,7 @@ static inline void free_tx_ts(struct osi_core_priv_data *osi_core, 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 core_local *l_core = (struct core_local *)(void *)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; @@ -1630,11 +1641,175 @@ static inline nve32_t freq_offset_calculate(struct osi_core_priv_data *sec_osi_c } #endif +static void cfg_l3_l4_filter(struct core_local *l_core) +{ + nveu32_t i = 0U; + + for (i = 0U; i < OSI_MGBE_MAX_L3_L4_FILTER; i++) { + if (l_core->cfg.l3_l4[i].used == OSI_DISABLE) { + continue; + } + + (void)osi_l3l4_filter((struct osi_core_priv_data *)(void *)l_core, + &l_core->cfg.l3_l4[i].l3l4_filter, + l_core->cfg.l3_l4[i].type, + l_core->cfg.l3_l4[i].dma_routing_enable, + l_core->cfg.l3_l4[i].dma_chan, + l_core->cfg.l3_l4[i].is_l4_filter); + } +} + +static void cfg_fc(struct core_local *l_core) +{ + (void)l_core->ops_p->config_flow_control((struct osi_core_priv_data *)(void *)l_core, + l_core->cfg.flow_ctrl); +} + +static void cfg_avb(struct core_local *l_core) +{ + nveu32_t i; + + for (i = 0U; i < OSI_MGBE_MAX_NUM_QUEUES; i++) { + if (l_core->cfg.avb[i].used == OSI_DISABLE) { + continue; + } + + (void)l_core->ops_p->set_avb_algorithm((struct osi_core_priv_data *)(void *)l_core, + &l_core->cfg.avb[i].avb_info); + } +} + +static void cfg_l2_filter(struct core_local *l_core) +{ + nveu32_t i; + + (void)osi_l2_filter((struct osi_core_priv_data *)(void *)l_core, + &l_core->cfg.l2_filter); + + for (i = 0U; i < EQOS_MAX_MAC_ADDRESS_FILTER; i++) { + if (l_core->cfg.l2[i].used == OSI_DISABLE) { + continue; + } + + (void)osi_l2_filter((struct osi_core_priv_data *)(void *)l_core, + &l_core->cfg.l2[i].filter); + } +} + +static void cfg_rxcsum(struct core_local *l_core) +{ + (void)l_core->ops_p->config_rxcsum_offload((struct osi_core_priv_data *)(void *)l_core, + l_core->cfg.rxcsum); +} + +static void cfg_vlan(struct core_local *l_core) +{ + nveu32_t i; + + for (i = 0U; i < VLAN_NUM_VID; i++) { + if (l_core->cfg.vlan[i].used == OSI_DISABLE) { + continue; + } + + (void)vlan_id_update((struct osi_core_priv_data *)(void *)l_core, + (l_core->cfg.vlan[i].vid | OSI_VLAN_ACTION_ADD)); + } +} + +static void cfg_eee(struct core_local *l_core) +{ + (void)conf_eee((struct osi_core_priv_data *)(void *)l_core, + l_core->cfg.tx_lpi_enabled, + l_core->cfg.tx_lpi_timer); +} + +static void cfg_ptp(struct core_local *l_core) +{ + struct osi_core_priv_data *osi_core = (struct osi_core_priv_data *)(void *)l_core; + struct osi_ioctl ioctl_data = {}; + + ioctl_data.arg1_u32 = l_core->cfg.ptp; + ioctl_data.cmd = OSI_CMD_CONFIG_PTP; + + (void)osi_handle_ioctl(osi_core, &ioctl_data); +} + +static void cfg_est(struct core_local *l_core) +{ + (void)config_est((struct osi_core_priv_data *)(void *)l_core, + &l_core->cfg.est); +} + +static void cfg_fpe(struct core_local *l_core) +{ + (void)config_fpe((struct osi_core_priv_data *)(void *)l_core, + &l_core->cfg.fpe); +} + +static void apply_dynamic_cfg(struct osi_core_priv_data *osi_core) +{ + struct core_local *l_core = (struct core_local *)(void *)osi_core; + typedef void (*cfg_fn)(struct core_local *local_core); + const cfg_fn fn[] = { + cfg_l3_l4_filter, cfg_fc, cfg_avb, cfg_l2_filter, + cfg_rxcsum, cfg_vlan, cfg_eee, cfg_ptp, cfg_est, cfg_fpe + }; + nveu32_t flags = l_core->cfg.flags; + nveu32_t i = 0U; + + while (flags > 0U) { + if ((flags & OSI_ENABLE) == OSI_ENABLE) { + fn[i](l_core); + } + + flags = flags >> 1U; + update_counter_u(&i, 1U); + } +} + +static void store_l3l4_filter(struct osi_core_priv_data *osi_core, + struct osi_l3_l4_filter *l3l4_filter, + nveu32_t type, nveu32_t dma_routing_enable, + nveu32_t dma_chan, nveu32_t is_l4_filter) +{ + struct core_local *l_core = (struct core_local *)(void *)osi_core; + struct l3_l4_filters *l3_l4 = &l_core->cfg.l3_l4[l3l4_filter->filter_no]; + + if (l3l4_filter->filter_enb_dis == OSI_ENABLE) { + l3_l4->type = type; + l3_l4->dma_routing_enable = dma_routing_enable; + l3_l4->dma_chan = dma_chan; + l3_l4->is_l4_filter = is_l4_filter; + (void)osi_memcpy(&l3_l4->l3l4_filter, l3l4_filter, + sizeof(struct osi_l3_l4_filter)); + l3_l4->used = OSI_ENABLE; + } else { + l3_l4->used = OSI_DISABLE; + } +} + +static void store_l2_filter(struct osi_core_priv_data *osi_core, + struct osi_filter *filter) +{ + struct core_local *l_core = (struct core_local *)(void *)osi_core; + + if ((filter->oper_mode & OSI_OPER_ADDR_UPDATE) == OSI_OPER_ADDR_UPDATE) { + (void)osi_memcpy(&l_core->cfg.l2[filter->index].filter, filter, + sizeof(struct osi_filter)); + l_core->cfg.l2[filter->index].used = OSI_ENABLE; + } else if ((filter->oper_mode & OSI_OPER_ADDR_DEL) == OSI_OPER_ADDR_DEL) { + l_core->cfg.l2[filter->index].used = OSI_DISABLE; + } else { + (void)osi_memcpy(&l_core->cfg.l2_filter, filter, + sizeof(struct osi_filter)); + } +} + 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; + struct core_local *l_core = (struct core_local *)(void *)osi_core; + const struct core_ops *ops_p; nve32_t ret = -1; #if DRIFT_CAL struct osi_core_priv_data *sec_osi_core; @@ -1668,9 +1843,16 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, break; case OSI_CMD_L3L4_FILTER: - ret = osi_l3l4_filter(osi_core, data->l3l4_filter, + ret = osi_l3l4_filter(osi_core, &data->l3l4_filter, data->arg1_u32, data->arg2_u32, data->arg3_u32, data->arg4_u32); + if (ret == 0) { + store_l3l4_filter(osi_core, &data->l3l4_filter, + data->arg1_u32, data->arg2_u32, + data->arg3_u32, data->arg4_u32); + l_core->cfg.flags |= DYNAMIC_CFG_L3_L4; + } + break; case OSI_CMD_MDC_CONFIG: @@ -1697,6 +1879,11 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, case OSI_CMD_FLOW_CTRL: ret = ops_p->config_flow_control(osi_core, data->arg1_u32); + if (ret == 0) { + l_core->cfg.flow_ctrl = data->arg1_u32; + l_core->cfg.flags |= DYNAMIC_CFG_FC; + } + break; case OSI_CMD_GET_AVB: @@ -1705,6 +1892,13 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, case OSI_CMD_SET_AVB: ret = ops_p->set_avb_algorithm(osi_core, &data->avb); + if (ret == 0) { + (void)osi_memcpy(&l_core->cfg.avb[data->avb.qindex].avb_info, + &data->avb, sizeof(struct osi_core_avb_algorithm)); + l_core->cfg.avb[data->avb.qindex].used = OSI_ENABLE; + l_core->cfg.flags |= DYNAMIC_CFG_AVB; + } + break; case OSI_CMD_CONFIG_RX_CRC_CHECK: @@ -1713,6 +1907,18 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, case OSI_CMD_UPDATE_VLAN_ID: ret = vlan_id_update(osi_core, data->arg1_u32); + if (ret == 0) { + if ((data->arg1_u32 & VLAN_ACTION_MASK) == OSI_VLAN_ACTION_ADD) { + l_core->cfg.vlan[data->arg1_u32 & VLAN_VID_MASK].vid = + data->arg1_u32 & VLAN_VID_MASK; + l_core->cfg.vlan[data->arg1_u32 & VLAN_VID_MASK].used = OSI_ENABLE; + } else { + l_core->cfg.vlan[data->arg1_u32 & VLAN_VID_MASK].used = OSI_DISABLE; + } + + l_core->cfg.flags |= DYNAMIC_CFG_VLAN; + } + break; case OSI_CMD_CONFIG_TXSTATUS: @@ -1738,6 +1944,12 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, case OSI_CMD_CONFIG_EEE: ret = conf_eee(osi_core, data->arg1_u32, data->arg2_u32); + if (ret == 0) { + l_core->cfg.tx_lpi_enabled = data->arg1_u32; + l_core->cfg.tx_lpi_timer = data->arg2_u32; + l_core->cfg.flags |= DYNAMIC_CFG_EEE; + } + break; #endif /* !OSI_STRIPPED_LIB */ @@ -1783,10 +1995,20 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, case OSI_CMD_L2_FILTER: ret = osi_l2_filter(osi_core, &data->l2_filter); + if (ret == 0) { + store_l2_filter(osi_core, &data->l2_filter); + l_core->cfg.flags |= DYNAMIC_CFG_L2; + } + break; case OSI_CMD_RXCSUM_OFFLOAD: ret = ops_p->config_rxcsum_offload(osi_core, data->arg1_u32); + if (ret == 0) { + l_core->cfg.rxcsum = data->arg1_u32; + l_core->cfg.flags |= DYNAMIC_CFG_RXCSUM; + } + break; case OSI_CMD_ADJ_FREQ: @@ -1898,6 +2120,10 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, case OSI_CMD_CONFIG_PTP: ret = osi_ptp_configuration(osi_core, data->arg1_u32); + if (ret == 0) { + l_core->cfg.ptp = data->arg1_u32; + l_core->cfg.flags |= DYNAMIC_CFG_PTP; + } #if DRIFT_CAL if (ret < 0) { OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, @@ -1995,10 +2221,22 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, case OSI_CMD_CONFIG_EST: ret = config_est(osi_core, &data->est); + if (ret == 0) { + (void)osi_memcpy(&l_core->cfg.est, &data->est, + sizeof(struct osi_est_config)); + l_core->cfg.flags |= DYNAMIC_CFG_EST; + } + break; case OSI_CMD_CONFIG_FPE: ret = config_fpe(osi_core, &data->fpe); + if (ret == 0) { + (void)osi_memcpy(&l_core->cfg.fpe, &data->fpe, + sizeof(struct osi_fpe_config)); + l_core->cfg.flags |= DYNAMIC_CFG_FPE; + } + break; case OSI_CMD_READ_REG: @@ -2066,6 +2304,18 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, ret = 0; break; #endif + case OSI_CMD_SUSPEND: + l_core->state = OSI_SUSPENDED; + ret = osi_hal_hw_core_deinit(osi_core); + break; + case OSI_CMD_RESUME: + ret = osi_hal_hw_core_init(osi_core, l_core->tx_fifo_size, l_core->rx_fifo_size); + if (ret < 0) { + break; + } + + apply_dynamic_cfg(osi_core); + break; default: OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "CORE: Incorrect command\n", @@ -2079,7 +2329,7 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, 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; + struct core_local *l_core = (struct core_local *)(void *)osi_core; if (validate_args(osi_core, l_core) < 0) { return -1; diff --git a/osi/core/vlan_filter.h b/osi/core/vlan_filter.h index d4406ce..67f827f 100644 --- a/osi/core/vlan_filter.h +++ b/osi/core/vlan_filter.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -53,9 +53,9 @@ */ #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_VID_MASK 0xFFFFU +#define VLAN_ID_INVALID 0xFFFFU +#define VLAN_HASH_ALLOW_ALL 0xFFFFU #define VLAN_ACTION_MASK OSI_BIT(31) /** @} */ From 16990dd50311e9e8332c96eb94120264da867d37 Mon Sep 17 00:00:00 2001 From: Sanath Kumar Gampa <sgampa@nvidia.com> Date: Fri, 17 Jun 2022 09:00:11 +0530 Subject: [PATCH 354/458] osi: macsec: Update the sak len to 256 Bug 3673435 Change-Id: I841a9d631ff1b186f1a59e29d26822698b6e6e3d Signed-off-by: Sanath Kumar Gampa <sgampa@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2730246 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/osi_core.h b/include/osi_core.h index 01cc735..bae257d 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -1126,7 +1126,7 @@ struct osi_macsec_sc_info { /** Secure channel identifier */ nveu8_t sci[OSI_SCI_LEN]; /** Secure association key */ - nveu8_t sak[OSI_KEY_LEN_128]; + nveu8_t sak[OSI_KEY_LEN_256]; #ifdef MACSEC_KEY_PROGRAM /** Secure association key */ nveu8_t hkey[OSI_KEY_LEN_128]; From 6f6942d9c6d66e6f30ad4954848ef09199d8f205 Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Fri, 24 Jun 2022 17:52:21 +0000 Subject: [PATCH 355/458] osi: core: Fix MISRA issues Fixed straight forward MISRA issues ===== DIFF ====== Total misra violation count changed by -319 Rule: MISRA_C-2012_Directive_4.4 Diff: -3 Rule: MISRA_C-2012_Directive_4.6 Diff: -32 Rule: MISRA_C-2012_Directive_4.9 Diff: 3 Rule: MISRA_C-2012_Rule_10.1 Diff: -4 Rule: MISRA_C-2012_Rule_10.3 Diff: -2 Rule: MISRA_C-2012_Rule_10.4 Diff: -21 Rule: MISRA_C-2012_Rule_11.1 Diff: -20 Rule: MISRA_C-2012_Rule_12.1 Diff: -74 Rule: MISRA_C-2012_Rule_15.5 Diff: 1 Rule: MISRA_C-2012_Rule_15.7 Diff: -2 Rule: MISRA_C-2012_Rule_16.1 Diff: -1 Rule: MISRA_C-2012_Rule_16.3 Diff: -1 Rule: MISRA_C-2012_Rule_17.7 Diff: -5 Rule: MISRA_C-2012_Rule_2.5 Diff: -157 Rule: MISRA_C-2012_Rule_8.6 Diff: -1 Rule: Total Diff: -319 JIRA NET-96 Bug 3695218 Change-Id: I221f95aaf23e9214fde21632b68425b705552752 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2735077 Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Sanath Kumar Gampa <sgampa@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_common.h | 17 +-- osi/common/common.h | 16 ++- osi/core/core_common.h | 2 +- osi/core/core_local.h | 24 +--- osi/core/eqos_core.c | 62 ++++++---- osi/core/eqos_core.h | 106 ++++------------- osi/core/frp.c | 10 +- osi/core/mgbe_core.c | 261 ++++++++++++++++++++--------------------- osi/core/mgbe_core.h | 66 ++--------- osi/core/mgbe_mmc.c | 6 +- osi/core/mgbe_mmc.h | 29 +---- osi/core/osi_hal.c | 34 +++--- osi/core/vlan_filter.c | 13 +- osi/core/vlan_filter.h | 2 +- osi/core/xpcs.c | 4 +- osi/core/xpcs.h | 5 - 16 files changed, 258 insertions(+), 399 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index 0c3a75f..76d00b9 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -39,14 +39,11 @@ #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 /** @} */ @@ -175,15 +172,17 @@ #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 + +#ifdef UPDATED_PAD_CAL /* MAC Tx/Rx Idle retry and delay count */ #define OSI_TXRX_IDLE_RETRY 5000U #define OSI_DELAY_COUNT 10U +#endif #define EQOS_DMA_CHX_STATUS(x) ((0x0080U * (x)) + 0x1160U) #define MGBE_DMA_CHX_STATUS(x) ((0x0080U * (x)) + 0x3160U) @@ -232,21 +231,11 @@ #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 */ /** @} */ diff --git a/osi/common/common.h b/osi/common/common.h index d2b9082..ec41481 100644 --- a/osi/common/common.h +++ b/osi/common/common.h @@ -250,24 +250,30 @@ static inline void osi_writela(OSI_UNUSED void *priv, nveu32_t val, void *addr) static inline nve32_t validate_mac_ver_update_chans(nveu32_t mac_ver, nveu32_t *max_chans) { + nve32_t ret; + switch (mac_ver) { case OSI_EQOS_MAC_4_10: case OSI_EQOS_MAC_5_00: *max_chans = OSI_EQOS_XP_MAX_CHANS; + ret = 1; break; case OSI_EQOS_MAC_5_30: *max_chans = OSI_EQOS_MAX_NUM_CHANS; + ret = 1; 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; + ret = 1; break; default: - return 0; + ret = 0; + break; } - return 1; + return ret; } /** @@ -320,7 +326,7 @@ static inline nve32_t osi_memcpy(void *dest, void *src, nveu64_t n) nve8_t *cdest = (nve8_t *)dest; nveu64_t i = 0; - if (src == OSI_NULL || dest == OSI_NULL) { + if ((src == OSI_NULL) || (dest == OSI_NULL)) { return -1; } for (i = 0; i < n; i++) { @@ -336,7 +342,7 @@ static inline nve32_t osi_memcmp(void *dest, void *src, nve32_t n) nve8_t *csrc = (nve8_t *)src; nve8_t *cdest = (nve8_t *)dest; - if (src == OSI_NULL || dest == OSI_NULL) + if ((src == OSI_NULL) || (dest == OSI_NULL)) return -1; for (i = 0; i < n; i++) { @@ -344,6 +350,8 @@ static inline nve32_t osi_memcmp(void *dest, void *src, nve32_t n) return -1; } else if (csrc[i] > cdest[i]) { return 1; + } else { + /* Do Nothing */ } } return 0; diff --git a/osi/core/core_common.h b/osi/core/core_common.h index 81b69a7..ca36384 100644 --- a/osi/core/core_common.h +++ b/osi/core/core_common.h @@ -28,7 +28,7 @@ OSI_BIT(10) | OSI_BIT(11) | \ OSI_BIT(12) | OSI_BIT(13) | \ OSI_BIT(14) | OSI_BIT(15) | \ - OSI_BIT(16) | (17) | \ + OSI_BIT(16) | (17U) | \ OSI_BIT(18) | OSI_BIT(19)) #define MTL_EST_SRWO OSI_BIT(0) #define MTL_EST_R1W0 OSI_BIT(1) diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 453e8e8..46b5f87 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -308,17 +308,16 @@ struct core_ops { #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 +#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 +#define ETHER_NSEC_MASK 0x7FFFFFFFU +#define SERVO_STATS_0 0U +#define SERVO_STATS_1 1U +#define SERVO_STATS_2 2U /** * @brief servo data structure. @@ -507,19 +506,6 @@ static inline void update_counter_u(nveu32_t *value, nveu32_t incr) */ 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. * diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 5960ef9..399bc72 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1376,7 +1376,7 @@ static int eqos_config_frp(struct osi_core_priv_data *const osi_core, unsigned int op_mode = 0U, val = 0U; int ret = 0; - if (enabled != OSI_ENABLE && enabled != OSI_DISABLE) { + if ((enabled != OSI_ENABLE) && (enabled != OSI_DISABLE)) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid enable input\n", enabled); @@ -2127,19 +2127,19 @@ static inline void eqos_save_gcl_params(struct osi_core_priv_data *osi_core) 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); + if ((osi_core->hw_feature->gcl_width == 0U) || + (osi_core->hw_feature->gcl_width > 3U)) { + 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)) { + if ((osi_core->hw_feature->gcl_depth == 0U) || + (osi_core->hw_feature->gcl_depth > 5U)) { /* Do Nothing */ OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Wrong HW feature GCL depth\n", @@ -2594,13 +2594,25 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, /* 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); + ret = eqos_set_speed(osi_core, OSI_SPEED_10); + if (osi_unlikely(ret < 0)) { + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + "set speed in 10Mbps failed\n", 0ULL); + } } else if ((mac_pcs & EQOS_MAC_PCS_LNKSPEED) == EQOS_MAC_PCS_LNKSPEED_100) { - eqos_set_speed(osi_core, OSI_SPEED_100); + ret = eqos_set_speed(osi_core, OSI_SPEED_100); + if (osi_unlikely(ret < 0)) { + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + "set speed in 100Mbps failed\n", 0ULL); + } } else if ((mac_pcs & EQOS_MAC_PCS_LNKSPEED) == EQOS_MAC_PCS_LNKSPEED_1000) { - eqos_set_speed(osi_core, OSI_SPEED_1000); + ret = eqos_set_speed(osi_core, OSI_SPEED_1000); + if (osi_unlikely(ret < 0)) { + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + "set speed in 1000Mbps failed\n", 0ULL); + } } else { /* Nothing here */ } @@ -3338,8 +3350,8 @@ static void eqos_l2_filter_delete(struct osi_core_priv_data *osi_core, (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) { + 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))); @@ -3479,7 +3491,7 @@ static nve32_t eqos_update_mac_addr_low_high_reg( * @retval 0 on success * @retval -1 on failure. */ -static int eqos_config_ptp_offload(struct osi_core_priv_data *osi_core, +static int eqos_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; @@ -4698,9 +4710,9 @@ static void eqos_config_tscr(struct osi_core_priv_data *const osi_core, * @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) +static nve32_t eqos_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 = OSI_NONE; @@ -4720,7 +4732,7 @@ static int eqos_config_ptp_rxq(struct osi_core_priv_data *osi_core, } /* Validate enable argument */ - if (enable != OSI_ENABLE && enable != OSI_DISABLE) { + if ((enable != OSI_ENABLE) && (enable != OSI_DISABLE)) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid enable input\n", enable); @@ -4937,8 +4949,8 @@ static int eqos_hw_est_write(struct osi_core_priv_data *osi_core, * @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) +static int eqos_hw_config_est(struct osi_core_priv_data *const osi_core, + struct osi_est_config *const est) { void *base = osi_core->base; unsigned int btr[2] = {0}; @@ -4966,7 +4978,7 @@ static int eqos_hw_config_est(struct osi_core_priv_data *osi_core, btr[0] = est->btr[0]; btr[1] = est->btr[1]; - if (btr[0] == 0U && btr[1] == 0U) { + if ((btr[0] == 0U) && (btr[1] == 0U)) { common_get_systime_from_mac(osi_core->base, osi_core->mac, &btr[1], &btr[0]); } @@ -5074,8 +5086,8 @@ static int eqos_hw_config_est(struct osi_core_priv_data *osi_core, * @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) +static int eqos_hw_config_fpe(struct osi_core_priv_data *const osi_core, + struct osi_fpe_config *const fpe) { unsigned int i = 0U; unsigned int val = 0U; @@ -5133,7 +5145,7 @@ static int eqos_hw_config_fpe(struct osi_core_priv_data *osi_core, (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) { + 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; @@ -6727,7 +6739,7 @@ static nve32_t eqos_post_pad_calibrate( * * @retval -1 Always */ -static nve32_t eqos_config_rss(struct osi_core_priv_data *const osi_core) +static nve32_t eqos_config_rss(struct osi_core_priv_data *osi_core) { OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, "RSS not supported by EQOS\n", 0ULL); diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index c3b503a..841b225 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -77,7 +77,6 @@ #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 @@ -97,11 +96,16 @@ #endif /* !OSI_STRIPPED_LIB */ #define EQOS_MAC_ANS 0x00E4 #define EQOS_MAC_PCS 0x00F8 + +#ifdef UPDATED_PAD_CAL #define EQOS_MAC_DEBUG 0x0114 +#define EQOS_MAC_DEBUG_RPESTS OSI_BIT(0) +#define EQOS_MAC_DEBUG_TPESTS OSI_BIT(16) +#endif + #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) @@ -150,7 +154,6 @@ #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 @@ -158,19 +161,15 @@ #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) /** @} */ /** @@ -189,9 +188,13 @@ #define EQOS_VIRT_INTR_APB_CHX_CNTRL(x) (0x8200U + ((x) * 4U)) #define VIRTUAL_APB_ERR_CTRL 0x8300 #define EQOS_WRAP_COMMON_INTR_ENABLE 0x8704 + +#ifdef HSI_SUPPORT #define EQOS_REGISTER_PARITY_ERR OSI_BIT(5) #define EQOS_CORE_CORRECTABLE_ERR OSI_BIT(4) #define EQOS_CORE_UNCORRECTABLE_ERR OSI_BIT(3) +#endif + #define EQOS_MAC_SBD_INTR OSI_BIT(2) #define EQOS_WRAP_COMMON_INTR_STATUS 0x8708 #define EQOS_WRAP_SYNC_TSC_PTP_CAPTURE 0x800CU @@ -242,11 +245,6 @@ #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) @@ -260,8 +258,6 @@ #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) @@ -288,7 +284,12 @@ #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) + +#ifdef HSI_SUPPORT #define EQOS_DMA_ISR_TXSTSIS OSI_BIT(13) +#define EQOS_IMR_TXESIE OSI_BIT(13) +#endif + #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) @@ -298,13 +299,6 @@ #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) @@ -315,8 +309,6 @@ #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 @@ -325,34 +317,15 @@ #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 @@ -448,8 +421,6 @@ #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) @@ -567,10 +538,7 @@ /* 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) @@ -619,9 +587,10 @@ #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) +#ifdef UPDATED_PAD_CAL /* EQOS RGMII Rx padctrl registers E_INPUT bit */ -#define EQOS_PADCTL_EQOS_E_INPUT OSI_BIT(6) - +#define EQOS_PADCTL_EQOS_E_INPUT OSI_BIT(6) +#endif /** @} */ void update_ehfc_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value); @@ -660,9 +629,6 @@ void update_ehfc_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value); #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 @@ -676,30 +642,8 @@ void update_ehfc_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value); #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 @@ -735,16 +679,15 @@ void update_ehfc_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value); #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_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) | \ @@ -760,8 +703,6 @@ void update_ehfc_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value); #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) | \ @@ -1041,9 +982,6 @@ struct core_func_safety { #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 diff --git a/osi/core/frp.c b/osi/core/frp.c index 4b0c953..6004e50 100644 --- a/osi/core/frp.c +++ b/osi/core/frp.c @@ -260,7 +260,7 @@ static int frp_entry_add(struct osi_core_priv_data *const osi_core, /* 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) { + ((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); @@ -268,8 +268,8 @@ static int frp_entry_add(struct osi_core_priv_data *const osi_core, } /* Validate next_frp_id index ok_index */ - if (filter_mode == OSI_FRP_MODE_LINK || - filter_mode == OSI_FRP_MODE_IM_LINK) { + 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", @@ -334,8 +334,8 @@ static int frp_entry_add(struct osi_core_priv_data *const osi_core, } /* Check and fill final OKI */ - if (filter_mode == OSI_FRP_MODE_LINK || - filter_mode == OSI_FRP_MODE_IM_LINK) { + 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; diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 2c6ee37..b414821 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -115,15 +115,15 @@ done: * @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) +static nve32_t mgbe_config_fw_err_pkts(struct osi_core_priv_data *const osi_core, + const nveu32_t qinx, + const nveu32_t 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) || + if (((enable_fw_err_pkts != OSI_ENABLE) && + (enable_fw_err_pkts != OSI_DISABLE)) || (qinx >= OSI_MGBE_MAX_NUM_CHANS)) { return -1; } @@ -473,7 +473,7 @@ static inline void mgbe_config_l2_da_perfect_inverse_match( * * @retval 0 always */ -static int mgbe_config_mac_pkt_filter_reg(struct osi_core_priv_data *osi_core, +static nve32_t mgbe_config_mac_pkt_filter_reg(struct osi_core_priv_data *const osi_core, const struct osi_filter *filter) { unsigned int value = 0U; @@ -567,8 +567,8 @@ static int mgbe_filter_args_validate(struct osi_core_priv_data *const osi_core, } /* check for DMA channel index (0 to 9) */ - if ((dma_chan > OSI_MGBE_MAX_NUM_CHANS - 0x1U) && - (dma_chan != OSI_CHAN_ANY)){ + 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); @@ -592,7 +592,7 @@ static int mgbe_filter_args_validate(struct osi_core_priv_data *const osi_core, } /* validate src_dest argument */ - if (src_dest != OSI_SA_MATCH && src_dest != OSI_DA_MATCH) { + 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); @@ -600,8 +600,8 @@ static int mgbe_filter_args_validate(struct osi_core_priv_data *const osi_core, } /* validate dma_routing_enable argument */ - if (dma_routing_enable != OSI_ENABLE && - dma_routing_enable != OSI_DISABLE) { + 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); @@ -909,10 +909,10 @@ static int mgbe_l3l4_filter_read(struct osi_core_priv_data *osi_core, * @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) +static nve32_t mgbe_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) { unsigned int value = 0U; unsigned int temp = 0U; @@ -933,8 +933,8 @@ static int mgbe_update_ip4_addr(struct osi_core_priv_data *osi_core, } /* validate src_dst_addr_match argument */ - if (src_dst_addr_match != OSI_SOURCE_MATCH && - src_dst_addr_match != OSI_INV_MATCH) { + 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); @@ -978,9 +978,9 @@ static int mgbe_update_ip4_addr(struct osi_core_priv_data *osi_core, * @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[]) +static nve32_t mgbe_update_ip6_addr(struct osi_core_priv_data *const osi_core, + const nveu32_t filter_no, + const nveu16_t addr[]) { unsigned int value = 0U; unsigned int temp = 0U; @@ -1055,15 +1055,15 @@ static int mgbe_update_ip6_addr(struct osi_core_priv_data *osi_core, * @retval 0 on success * @retval -1 on failure. */ -static int mgbe_config_l3_l4_filter_enable( +static nve32_t mgbe_config_l3_l4_filter_enable( struct osi_core_priv_data *const osi_core, - unsigned int filter_enb_dis) + const nveu32_t 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) { + 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); @@ -1097,10 +1097,10 @@ static int mgbe_config_l3_l4_filter_enable( * @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) +static nve32_t mgbe_update_l4_port_no(struct osi_core_priv_data *osi_core, + const nveu32_t filter_no, + const nveu16_t port_no, + const nveu32_t src_dst_port_match) { unsigned int value = 0U; unsigned int temp = 0U; @@ -1228,14 +1228,14 @@ static inline void mgbe_helper_l3l4_bitmask(unsigned int *bitmask, * @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) +static nve32_t mgbe_config_l3_filters(struct osi_core_priv_data *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) { unsigned int value = 0U; int ret = 0; @@ -1247,38 +1247,38 @@ static int mgbe_config_l3_filters(struct osi_core_priv_data *osi_core, return -1; } /* validate enb_dis argument */ - if (enb_dis != OSI_ENABLE && enb_dis != OSI_DISABLE) { + 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) { + 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) { + 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) { + 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)) { + (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); @@ -1303,10 +1303,10 @@ static int mgbe_config_l3_filters(struct osi_core_priv_data *osi_core, * matching */ value &= ~MGBE_MAC_L3_IP6_CTRL_CLEAR; - value |= ((MGBE_MAC_L3L4_CTR_L3SAM0 | - perfect_inverse_match << + value |= ((MGBE_MAC_L3L4_CTR_L3SAM0) | + ((perfect_inverse_match << MGBE_MAC_L3L4_CTR_L3SAIM0_SHIFT) & - ((MGBE_MAC_L3L4_CTR_L3SAM0 | + (MGBE_MAC_L3L4_CTR_L3SAM0 | MGBE_MAC_L3L4_CTR_L3SAIM0))); value |= mgbe_set_dcs(osi_core, value, dma_routing_enable, @@ -1317,10 +1317,10 @@ static int mgbe_config_l3_filters(struct osi_core_priv_data *osi_core, * matching */ value &= ~MGBE_MAC_L3_IP6_CTRL_CLEAR; - value |= ((MGBE_MAC_L3L4_CTR_L3DAM0 | - perfect_inverse_match << + value |= ((MGBE_MAC_L3L4_CTR_L3DAM0) | + ((perfect_inverse_match << MGBE_MAC_L3L4_CTR_L3DAIM0_SHIFT) & - ((MGBE_MAC_L3L4_CTR_L3DAM0 | + (MGBE_MAC_L3L4_CTR_L3DAM0 | MGBE_MAC_L3L4_CTR_L3DAIM0))); value |= mgbe_set_dcs(osi_core, value, dma_routing_enable, @@ -1340,10 +1340,10 @@ static int mgbe_config_l3_filters(struct osi_core_priv_data *osi_core, * matching */ value &= ~MGBE_MAC_L3_IP4_SA_CTRL_CLEAR; - value |= ((MGBE_MAC_L3L4_CTR_L3SAM0 | - perfect_inverse_match << + value |= ((MGBE_MAC_L3L4_CTR_L3SAM0) | + ((perfect_inverse_match << MGBE_MAC_L3L4_CTR_L3SAIM0_SHIFT) & - ((MGBE_MAC_L3L4_CTR_L3SAM0 | + (MGBE_MAC_L3L4_CTR_L3SAM0 | MGBE_MAC_L3L4_CTR_L3SAIM0))); value |= mgbe_set_dcs(osi_core, value, dma_routing_enable, @@ -1360,10 +1360,10 @@ static int mgbe_config_l3_filters(struct osi_core_priv_data *osi_core, * matching */ value &= ~MGBE_MAC_L3_IP4_DA_CTRL_CLEAR; - value |= ((MGBE_MAC_L3L4_CTR_L3DAM0 | - perfect_inverse_match << + value |= ((MGBE_MAC_L3L4_CTR_L3DAM0) | + ((perfect_inverse_match << MGBE_MAC_L3L4_CTR_L3DAIM0_SHIFT) & - ((MGBE_MAC_L3L4_CTR_L3DAM0 | + (MGBE_MAC_L3L4_CTR_L3DAM0 | MGBE_MAC_L3L4_CTR_L3DAIM0))); value |= mgbe_set_dcs(osi_core, value, dma_routing_enable, @@ -1412,14 +1412,14 @@ static int mgbe_config_l3_filters(struct osi_core_priv_data *osi_core, * @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) +static nve32_t mgbe_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) { unsigned int value = 0U; int ret = 0; @@ -1431,37 +1431,37 @@ static int mgbe_config_l4_filters(struct osi_core_priv_data *osi_core, return -1; } /* validate enb_dis argument */ - if (enb_dis != OSI_ENABLE && enb_dis != OSI_DISABLE) { + 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) { + 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) { + 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) { + 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)) { + (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); @@ -1482,11 +1482,11 @@ static int mgbe_config_l4_filters(struct osi_core_priv_data *osi_core, 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 << + 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)); + MGBE_MAC_L3L4_CTR_L4SPIM0))); value |= mgbe_set_dcs(osi_core, value, dma_routing_enable, dma_chan); @@ -1500,9 +1500,9 @@ static int mgbe_config_l4_filters(struct osi_core_priv_data *osi_core, * matching */ value &= ~MGBE_MAC_L4_DP_CTRL_CLEAR; - value |= ((MGBE_MAC_L3L4_CTR_L4DPM0 | - perfect_inverse_match << - MGBE_MAC_L3L4_CTR_L4DPIM0_SHIFT) & + 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, @@ -1547,10 +1547,10 @@ static int mgbe_config_l4_filters(struct osi_core_priv_data *osi_core, * @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) +static nve32_t mgbe_config_vlan_filtering(struct osi_core_priv_data *osi_core, + const nveu32_t filter_enb_dis, + const nveu32_t perfect_hash_filtering, + const nveu32_t perfect_inverse_match) { unsigned int value; unsigned char *base = osi_core->base; @@ -1570,7 +1570,7 @@ static int mgbe_config_vlan_filtering(struct osi_core_priv_data *osi_core, } /* validate filter_enb_dis argument */ - if (filter_enb_dis != OSI_ENABLE && filter_enb_dis != OSI_DISABLE) { + 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); @@ -1578,8 +1578,8 @@ static int mgbe_config_vlan_filtering(struct osi_core_priv_data *osi_core, } /* validate perfect_inverse_match argument */ - if (perfect_inverse_match != OSI_ENABLE && - perfect_inverse_match != OSI_DISABLE) { + 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); @@ -1635,7 +1635,7 @@ static int mgbe_config_ptp_rxq(struct osi_core_priv_data *const osi_core, } /* Validate enable argument */ - if (enable != OSI_ENABLE && enable != OSI_DISABLE) { + if ((enable != OSI_ENABLE) && (enable != OSI_DISABLE)) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid enable input\n", enable); @@ -1752,14 +1752,14 @@ static nve32_t mgbe_flush_mtl_tx_queue( * @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) +static nve32_t mgbe_config_mac_loopback(struct osi_core_priv_data *const osi_core, + nveu32_t 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) { + if ((lb_mode != OSI_ENABLE) && (lb_mode != OSI_DISABLE)) { return -1; } @@ -1805,7 +1805,7 @@ static int mgbe_config_arp_offload(struct osi_core_priv_data *const osi_core, unsigned int val; void *addr = osi_core->base; - if (enable != OSI_ENABLE && enable != OSI_DISABLE) { + if ((enable != OSI_ENABLE) && (enable != OSI_DISABLE)) { return -1; } @@ -1846,14 +1846,14 @@ static int mgbe_config_arp_offload(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -static int mgbe_config_rxcsum_offload( +static nve32_t mgbe_config_rxcsum_offload( struct osi_core_priv_data *const osi_core, - unsigned int enabled) + nveu32_t enabled) { void *addr = osi_core->base; unsigned int mac_rmcr; - if (enabled != OSI_ENABLE && enabled != OSI_DISABLE) { + if ((enabled != OSI_ENABLE) && (enabled != OSI_DISABLE)) { return -1; } @@ -1892,7 +1892,7 @@ static int mgbe_config_frp(struct osi_core_priv_data *const osi_core, unsigned int op_mode = 0U, val = 0U; int ret = -1; - if (enabled != OSI_ENABLE && enabled != OSI_DISABLE) { + if ((enabled != OSI_ENABLE) && (enabled != OSI_DISABLE)) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid enable input\n", enabled); @@ -1985,7 +1985,7 @@ static int mgbe_frp_write(struct osi_core_priv_data *osi_core, unsigned char *base = osi_core->base; unsigned int val = 0U; - if (acc_sel != OSI_ENABLE && acc_sel != OSI_DISABLE) { + 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); @@ -2461,9 +2461,9 @@ static int mgbe_config_rss(struct osi_core_priv_data *osi_core) /* 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); + ((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; @@ -2773,8 +2773,8 @@ static int mgbe_configure_mac(struct osi_core_priv_data *osi_core) 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) { + 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 */ @@ -3103,19 +3103,19 @@ static inline void mgbe_save_gcl_params(struct osi_core_priv_data *osi_core) 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); + if ((osi_core->hw_feature->gcl_width == 0U) || + (osi_core->hw_feature->gcl_width > 3U)) { + 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) { + if ((osi_core->hw_feature->gcl_depth == 0U) || + (osi_core->hw_feature->gcl_depth > 5U)) { /* Do Nothing */ OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Wrong HW feature GCL depth\n", @@ -3306,7 +3306,7 @@ static nve32_t mgbe_dma_chan_to_vmirq_map(struct osi_core_priv_data *osi_core) * @retval 0 on success * @retval -1 on failure. */ -static nve32_t mgbe_core_init(struct osi_core_priv_data *osi_core, +static nve32_t mgbe_core_init(struct osi_core_priv_data *const osi_core, nveu32_t tx_fifo_size, nveu32_t rx_fifo_size) { @@ -4267,7 +4267,7 @@ static void mgbe_handle_hsi_intr(struct osi_core_priv_data *osi_core) * * @note MAC should be init and started. see osi_start_mac() */ -static void mgbe_handle_common_intr(struct osi_core_priv_data *osi_core) +static void mgbe_handle_common_intr(struct osi_core_priv_data *const osi_core) { void *base = osi_core->base; unsigned int dma_isr = 0; @@ -4459,7 +4459,7 @@ static void mgbe_config_mac_tx(struct osi_core_priv_data *const osi_core, * * @note Required clks and resets has to be enabled */ -static void mgbe_core_deinit(struct osi_core_priv_data *osi_core) +static void mgbe_core_deinit(struct osi_core_priv_data *const osi_core) { /* Stop the MAC by disabling both MAC Tx and Rx */ mgbe_stop_mac(osi_core); @@ -4725,9 +4725,9 @@ static inline int mgbe_restore_registers( * @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) + nveu32_t phyaddr, + nveu32_t phyreg, + nveu16_t phydata) { int ret = 0; unsigned int reg; @@ -4912,7 +4912,7 @@ static int mgbe_hw_est_write(struct osi_core_priv_data *osi_core, break; } - if ((val & MGBE_MTL_EST_ERR0) == MGBE_MTL_EST_ERR0 || + if (((val & MGBE_MTL_EST_ERR0) == MGBE_MTL_EST_ERR0) || (retry <= 0)) { return -1; } @@ -4943,8 +4943,8 @@ static int mgbe_hw_est_write(struct osi_core_priv_data *osi_core, * @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) +static int mgbe_hw_config_est(struct osi_core_priv_data *const osi_core, + struct osi_est_config *const est) { unsigned int btr[2] = {0}; unsigned int val = 0x0; @@ -4972,7 +4972,7 @@ static int mgbe_hw_config_est(struct osi_core_priv_data *osi_core, btr[0] = est->btr[0]; btr[1] = est->btr[1]; - if (btr[0] == 0U && btr[1] == 0U) { + if ((btr[0] == 0U) && (btr[1] == 0U)) { common_get_systime_from_mac(osi_core->base, osi_core->mac, &btr[1], &btr[0]); @@ -5077,8 +5077,8 @@ static int mgbe_hw_config_est(struct osi_core_priv_data *osi_core, * @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) +static int mgbe_hw_config_fpe(struct osi_core_priv_data *const osi_core, + struct osi_fpe_config *const fpe) { unsigned int i = 0U; unsigned int val = 0U; @@ -5150,7 +5150,7 @@ static int mgbe_hw_config_fpe(struct osi_core_priv_data *osi_core, 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) { + 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; @@ -5246,9 +5246,9 @@ static inline void mgbe_disable_tx_lpi(struct osi_core_priv_data *osi_core) * 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) +static void mgbe_configure_eee(struct osi_core_priv_data *const osi_core, + const nveu32_t tx_lpi_enabled, + const nveu32_t tx_lpi_timer) { unsigned int lpi_csr = 0; unsigned int lpi_timer_ctrl = 0; @@ -5328,7 +5328,7 @@ static void mgbe_configure_eee(struct osi_core_priv_data *osi_core, } } -static int mgbe_get_hw_features(struct osi_core_priv_data *osi_core, +static int mgbe_get_hw_features(struct osi_core_priv_data *const osi_core, struct osi_hw_features *hw_feat) { unsigned char *base = (unsigned char *)osi_core->base; @@ -5546,9 +5546,8 @@ static inline int mgbe_poll_for_tsinit_complete( * @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) +static nve32_t mgbe_set_systime_to_mac(struct osi_core_priv_data *osi_core, + nveu32_t sec, nveu32_t nsec) { unsigned int mac_tcr; void *addr = osi_core->base; @@ -5631,8 +5630,8 @@ static inline int mgbe_poll_for_addend_complete( * @retval 0 on success * @retval -1 on failure. */ -static int mgbe_config_addend(struct osi_core_priv_data *osi_core, - unsigned int addend) +static nve32_t mgbe_config_addend(struct osi_core_priv_data *const osi_core, + const nveu32_t addend) { unsigned int mac_tcr; void *addr = osi_core->base; @@ -5714,9 +5713,9 @@ static inline int mgbe_poll_for_update_ts_complete( * @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) + nveu32_t sec, nveu32_t nsec, + nveu32_t add_sub, + nveu32_t one_nsec_accuracy) { void *addr = osi_core->base; unsigned int mac_tcr; @@ -5793,7 +5792,7 @@ static int mgbe_adjust_mactime(struct osi_core_priv_data *osi_core, * @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) + nveu32_t ptp_filter) { struct core_local *l_core = (struct core_local *)osi_core; unsigned int mac_tcr = 0; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index c251a39..65d54b3 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -85,10 +85,7 @@ #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 @@ -129,9 +126,12 @@ #define MGBE_WRAP_AXI_ASID1_CTRL 0x8404 #define MGBE_WRAP_AXI_ASID2_CTRL 0x8408 #define MGBE_WRAP_COMMON_INTR_ENABLE 0x8704 + +#ifdef HSI_SUPPORT #define MGBE_REGISTER_PARITY_ERR OSI_BIT(5) #define MGBE_CORE_CORRECTABLE_ERR OSI_BIT(4) #define MGBE_CORE_UNCORRECTABLE_ERR OSI_BIT(3) +#endif #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)) @@ -165,13 +165,6 @@ #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) | \ @@ -182,7 +175,6 @@ 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) /** @} */ @@ -215,12 +207,6 @@ #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) @@ -288,13 +274,11 @@ #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 @@ -309,8 +293,6 @@ #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_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 @@ -329,15 +311,11 @@ #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) | \ @@ -352,16 +330,15 @@ #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_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) | \ @@ -377,16 +354,9 @@ #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) | \ @@ -402,8 +372,6 @@ * @{ */ #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)) @@ -459,14 +427,12 @@ #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 @@ -490,7 +456,6 @@ #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) @@ -503,10 +468,8 @@ #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 @@ -527,7 +490,6 @@ #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) @@ -571,7 +533,6 @@ #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 @@ -586,7 +547,6 @@ #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) @@ -647,13 +607,9 @@ */ #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)) @@ -746,7 +702,6 @@ * @brief SIZE calculation defines * @{ */ -#define FIFO_SIZE_B(x) (x) #define FIFO_SIZE_KB(x) ((x) * 1024U) /** @} */ @@ -875,13 +830,13 @@ 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) + \ +#define MGBE_MAC_VLAN_BAK_IDX(x) ((MGBE_MAC_L3_AD3R_BAK_IDX(0U) + \ OSI_MGBE_MAX_L3_L4_FILTER + (x))) /* Add MAC_DChSel_IndReg */ -#define MGBE_MAC_DCHSEL_BAK_IDX(x) ((MGBE_MAC_VLAN_BAK_IDX(0) + \ +#define MGBE_MAC_DCHSEL_BAK_IDX(x) ((MGBE_MAC_VLAN_BAK_IDX(0U) + \ MGBE_MAX_VLAN_FILTER + 1U)) -#define MGBE_MAX_BAK_IDX ((MGBE_MAC_DCHSEL_BAK_IDX(0) + \ +#define MGBE_MAX_BAK_IDX ((MGBE_MAC_DCHSEL_BAK_IDX(0U) + \ OSI_MGBE_MAX_MAC_ADDRESS_FILTER + 1U)) /** @} */ @@ -960,7 +915,6 @@ #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 diff --git a/osi/core/mgbe_mmc.c b/osi/core/mgbe_mmc.c index 75ed121..2c124d9 100644 --- a/osi/core/mgbe_mmc.c +++ b/osi/core/mgbe_mmc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -75,7 +75,7 @@ static inline unsigned long update_mmc_val(struct osi_core_priv_data *osi_core, * 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) +void mgbe_reset_mmc(struct osi_core_priv_data *const osi_core) { unsigned int value; @@ -99,7 +99,7 @@ void mgbe_reset_mmc(struct osi_core_priv_data *osi_core) * 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) +void mgbe_read_mmc(struct osi_core_priv_data *const osi_core) { struct osi_mmc_counters *mmc = &osi_core->mmc; diff --git a/osi/core/mgbe_mmc.h b/osi/core/mgbe_mmc.h index 957577d..7257686 100644 --- a/osi/core/mgbe_mmc.h +++ b/osi/core/mgbe_mmc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -67,13 +67,6 @@ #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 @@ -118,24 +111,10 @@ #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 @@ -147,8 +126,6 @@ #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 @@ -220,7 +197,7 @@ * 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); +void mgbe_read_mmc(struct osi_core_priv_data *const osi_core); /** * @brief mgbe_reset_mmc - To reset MMC registers and ether_mmc_counter @@ -232,5 +209,5 @@ void mgbe_read_mmc(struct osi_core_priv_data *osi_core); * 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); +void mgbe_reset_mmc(struct osi_core_priv_data *const osi_core); #endif diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 7d89a5e..99ff711 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -276,10 +276,6 @@ nve32_t osi_hal_hw_core_deinit(struct osi_core_priv_data *const osi_core) l_core->state = OSI_DISABLE; - /* FIXME: Should be fixed */ - //l_core->init_done = OSI_DISABLE; - //l_core->magic_num = 0; - return 0; } @@ -383,33 +379,33 @@ static nve32_t conf_ptp_offload(struct osi_core_priv_data *const osi_core, return ret; } - if (pto_config->mc_uc != OSI_ENABLE && - pto_config->mc_uc != OSI_DISABLE) { + 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) { + 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) { + 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) { + 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); @@ -1055,7 +1051,7 @@ static nve32_t vlan_id_update(struct osi_core_priv_data *const osi_core, { struct core_local *const l_core = (struct core_local *)(void *)osi_core; unsigned int action = vid & VLAN_ACTION_MASK; - unsigned short vlan_id = vid & VLAN_VID_MASK; + unsigned short vlan_id = (unsigned short)(vid & VLAN_VID_MASK); if ((osi_core->mac_ver == OSI_EQOS_MAC_4_10) || (osi_core->mac_ver == OSI_EQOS_MAC_5_00)) { @@ -1271,7 +1267,7 @@ static nve32_t conf_mac_loopback(struct osi_core_priv_data *const osi_core, struct core_local *l_core = (struct core_local *)(void *)osi_core; /* don't allow only if loopback mode is other than 0 or 1 */ - if (lb_mode != OSI_ENABLE && lb_mode != OSI_DISABLE) { + 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; @@ -1572,7 +1568,7 @@ static inline nve32_t freq_offset_calculate(struct osi_core_priv_data *sec_osi_c * it should be corrected with adjust time * threshold value 1 sec */ - if (offset >= 1000000000 || offset <= -1000000000) { + if ((offset >= 1000000000) || (offset <= -1000000000)) { s->count = SERVO_STATS_0; /* JUMP */ return (nve32_t) s->last_ppb; } @@ -1603,6 +1599,8 @@ static inline nve32_t freq_offset_calculate(struct osi_core_priv_data *sec_osi_c s->drift = -MAX_FREQ; } else if (s->drift > MAX_FREQ) { s->drift = MAX_FREQ; + } else { + /* Do Nothing */ } ppb = s->drift; @@ -1616,8 +1614,8 @@ static inline nve32_t freq_offset_calculate(struct osi_core_priv_data *sec_osi_c 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 = (s->const_i * cofficient * offset * WEIGHT_BY_10) / (100); + ppb = ((s->const_p * cofficient * offset * WEIGHT_BY_10) / (100)) + s->drift + ki_term; /* FIXME tune cofficients */ diff --git a/osi/core/vlan_filter.c b/osi/core/vlan_filter.c index 4f99be2..e973bf3 100644 --- a/osi/core/vlan_filter.c +++ b/osi/core/vlan_filter.c @@ -336,14 +336,14 @@ static inline int dequeue_vlan_id(struct osi_core_priv_data *osi_core, /* 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] = osi_core->vid[i + 1U]; } 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 allow_all_vid_tags(osi_core->base, OSI_DISABLE); } return 0; @@ -390,7 +390,7 @@ static inline int dequeue_vid_to_add_filter_reg( } 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] = osi_core->vid[i + 1U]; } osi_core->vid[i] = VLAN_ID_INVALID; @@ -452,7 +452,10 @@ static inline int del_vlan_id(struct osi_core_priv_data *osi_core, } if (osi_core->vlan_filter_cnt == VLAN_HW_MAX_NRVF) { - allow_all_vid_tags(osi_core->base, OSI_DISABLE); + ret = allow_all_vid_tags(osi_core->base, OSI_DISABLE); + if (ret < 0) { + return -1; + } } /* if SW queue is not empty dequeue from SW queue and update filter */ @@ -464,7 +467,7 @@ int update_vlan_id(struct osi_core_priv_data *osi_core, unsigned int vid) { unsigned int action = vid & VLAN_ACTION_MASK; - unsigned short vlan_id = vid & VLAN_VID_MASK; + unsigned short vlan_id = (unsigned short)(vid & VLAN_VID_MASK); if (action == OSI_VLAN_ACTION_ADD) { return add_vlan_id(osi_core, ops_p, vlan_id); diff --git a/osi/core/vlan_filter.h b/osi/core/vlan_filter.h index 67f827f..32e783a 100644 --- a/osi/core/vlan_filter.h +++ b/osi/core/vlan_filter.h @@ -36,7 +36,7 @@ #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_MASK 0x7CU #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) diff --git a/osi/core/xpcs.c b/osi/core/xpcs.c index 6ba0d31..7eae067 100644 --- a/osi/core/xpcs.c +++ b/osi/core/xpcs.c @@ -397,7 +397,7 @@ static nve32_t xpcs_lane_bring_up(struct osi_core_priv_data *osi_core) 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) { + if ((val & XPCS_WRAP_UPHY_RX_CONTROL_0_0_RX_CAL_EN) == 0U) { cond = COND_MET; } else { osi_core->osd_ops.udelay(1000U); @@ -591,7 +591,7 @@ int xpcs_eee(struct osi_core_priv_data *osi_core, unsigned int en_dis) unsigned int val = 0x0U; int ret = 0; - if (en_dis != OSI_ENABLE && en_dis != OSI_DISABLE) { + if ((en_dis != OSI_ENABLE) && (en_dis != OSI_DISABLE)) { return -1; } diff --git a/osi/core/xpcs.h b/osi/core/xpcs.h index 070e441..b512f83 100644 --- a/osi/core/xpcs.h +++ b/osi/core/xpcs.h @@ -42,11 +42,8 @@ * @{ */ #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 @@ -67,7 +64,6 @@ * @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) @@ -95,7 +91,6 @@ 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) From 879afe6abcab7f20f8e9cfec3de9fd78af87e261 Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Mon, 20 Jun 2022 22:27:49 +0530 Subject: [PATCH 356/458] core: delete stale TX time stamp from OSI hw queue Issue: In corner case TX TS form hardware in OSI list, not claimed by OSD which lead to stale time at OSI. Fix: if there is no timestamp read from OSD in last 2 seconds, remove that time stamp from OSI list Bug 3620425 Change-Id: I0a77cfe716aa13ddf49bdd32f56fb49b74b9d265 Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2731974 Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_core.h | 8 +++ osi/core/osi_hal.c | 142 +++++++++++++++++++++++++++------------------ 2 files changed, 94 insertions(+), 56 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index bae257d..b8a0660 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -78,6 +78,14 @@ typedef my_lint_64 nvel64_t; #define OSI_PTP_M2M_SECONDARY 2U /** @} */ +/** + * @addtogroup PTP PTP related information + * + *@brief 1 Second in NenoSec + */ +#define OSI_1SEC_TO_NSEC 1000000000LL +/** @} */ + /** * @addtogroup EQOS_PTP PTP Helper MACROS * diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 99ff711..2a87c4f 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -1417,62 +1417,6 @@ static inline void free_tx_ts(struct osi_core_priv_data *osi_core, } } -/** - * @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 *)(void *)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 * @@ -1511,6 +1455,92 @@ static void read_sec_ns(void *addr, nveu32_t mac, } } +/** + * @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 *)(void *)osi_core; + struct osi_core_tx_ts *temp = l_core->tx_ts_head.next; + struct osi_core_tx_ts const *head = &l_core->tx_ts_head; + nve32_t ret = -1; + nveu32_t count = 0U; +#if !defined(__QNX__) + nveu32_t nsec, sec, temp_nsec; + nvel64_t temp_val = 0LL; + nvel64_t ts_val = 0LL; + + read_sec_ns(osi_core->base, osi_core->mac, &sec, &nsec); + ts_val = (nvel64_t)(sec * OSI_1SEC_TO_NSEC) + (nvel64_t)nsec; +#endif + + 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 !defined(__QNX__) + temp_nsec = temp->nsec & ETHER_NSEC_MASK; + temp_val = (nvel64_t)(temp->sec * OSI_1SEC_TO_NSEC) + (nvel64_t)temp_nsec; + + if (((ts_val - temp_val) > (2LL * OSI_1SEC_TO_NSEC)) && + (temp->in_use != OSI_NONE)) { + /* remove old node from the link */ + temp->next->prev = temp->prev; + temp->prev->next = temp->next; + /* Clear in_use fields */ + temp->in_use = OSI_DISABLE; + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, + "Removing stale TS from queue pkt_id\n", + temp->pkt_id); + count++; + temp = temp->next; + continue; + } else +#endif + 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; + } else { + /* empty case */ + } + + 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 calculate time drift between primary and secondary * interface. From bb47c20f52ab7f6e1b746903d57eb2ec33eba6d2 Mon Sep 17 00:00:00 2001 From: Sanath Kumar Gampa <sgampa@nvidia.com> Date: Wed, 22 Jun 2022 17:36:35 +0530 Subject: [PATCH 357/458] osi: macsec: fixes for misra defects Below are the rules addressed Rule: MISRA_C-2012_Rule_15.5 Diff: -90 Rule: MISRA_C-2012_Rule_2.5 Diff: -34 Rule: MISRA_C-2012_Rule_8.13 Diff: -5 Rule: MISRA_C-2012_Rule_8.6 Diff: -1 Rule: CERT_INT31-C Diff: -2 Bug 3691236 Change-Id: I0b943b7626ea47e34eee585e42f0c9b98d67a7f4 Signed-off-by: Sanath Kumar Gampa <sgampa@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2732627 Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_macsec.h | 19 +- osi/core/eqos_core.c | 4 +- osi/core/ivc_core.c | 14 +- osi/core/macsec.c | 594 +++++++++++++++++++++++++++---------------- osi/core/macsec.h | 19 +- osi/core/mgbe_core.c | 4 +- 6 files changed, 413 insertions(+), 241 deletions(-) diff --git a/include/osi_macsec.h b/include/osi_macsec.h index aa03912..5ac81d7 100644 --- a/include/osi_macsec.h +++ b/include/osi_macsec.h @@ -41,7 +41,9 @@ #define OSI_AN2_VALID OSI_BIT(2) #define OSI_AN3_VALID OSI_BIT(3) #define OSI_MAX_NUM_SA 4U +#ifdef DEBUG_MACSEC #define OSI_CURR_AN_MAX 3 +#endif /* DEBUG_MACSEC */ #define OSI_KEY_INDEX_MAX 31U #define OSI_PN_MAX_DEFAULT 0xFFFFFFFFU #define OSI_PN_THRESHOLD_DEFAULT 0xC0000000U @@ -120,8 +122,6 @@ * @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 */ @@ -159,20 +159,15 @@ */ #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 */ +#ifdef MACSEC_KEY_PROGRAM #define OSI_CREATE_SA 1U +#endif /* MACSEC_KEY_PROGRAM */ #define OSI_ENABLE_SA 2U -#define OSI_DISABLE_SA 3U /** * @brief MACSEC SA State LUT entry outputs structure @@ -238,6 +233,7 @@ struct osi_macsec_table_config { nveu16_t index; }; +#if defined(MACSEC_KEY_PROGRAM) || defined(LINUX_OS) /** * @brief MACSEC Key Table entry structure */ @@ -247,6 +243,7 @@ struct osi_kt_entry { /** Indicates Hash-key */ nveu8_t h[OSI_KEY_LEN_128]; }; +#endif /* MACSEC_KEY_PROGRAM */ /** * @brief MACSEC BYP/SCI LUT entry inputs structure @@ -296,6 +293,7 @@ struct osi_macsec_lut_config { struct osi_sa_state_outputs sa_state_out; }; +#if defined(MACSEC_KEY_PROGRAM) || defined(LINUX_OS) /** * @brief MACSEC Key Table config data structure */ @@ -307,6 +305,7 @@ struct osi_macsec_kt_config { /** Indicates key table entry valid or not, bit 31 */ nveu32_t flags; }; +#endif /* MACSEC_KEY_PROGRAM */ /** * @brief MACSEC Debug buffer config data structure @@ -537,6 +536,7 @@ void osi_macsec_s_isr(struct osi_core_priv_data *const osi_core); nve32_t osi_macsec_config_lut(struct osi_core_priv_data *const osi_core, struct osi_macsec_lut_config *const lut_config); +#ifdef MACSEC_KEY_PROGRAM /** * @brief osi_macsec_config_kt - API to read or update the keys * @@ -563,6 +563,7 @@ nve32_t osi_macsec_config_lut(struct osi_core_priv_data *const osi_core, */ nve32_t osi_macsec_config_kt(struct osi_core_priv_data *const osi_core, struct osi_macsec_kt_config *const kt_config); +#endif /* MACSEC_KEY_PROGRAM */ /** * @brief osi_macsec_cipher_config - API to update the cipher diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 399bc72..6cf75b4 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -6779,7 +6779,7 @@ static void eqos_config_for_macsec(struct osi_core_priv_data *const osi_core, 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; + goto exit; } if (osi_core->mac_ver == OSI_EQOS_MAC_5_30) { /* stop MAC Tx */ @@ -6847,6 +6847,8 @@ static void eqos_config_for_macsec(struct osi_core_priv_data *const osi_core, OSI_LOG_ARG_HW_FAIL, "Error: osi_core->hw_feature is NULL\n", 0ULL); } +exit: + return; } #endif /* MACSEC_SUPPORT */ diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index fe40e26..31bd1e9 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -216,13 +216,13 @@ static int ivc_macsec_dbg_events_config( ret = osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); if (ret != 0) { - return ret; + goto exit; } msg.status = osi_memcpy((void *)dbg_buf_config, (void *)&msg.data.dbg_buf_config, sizeof(struct osi_macsec_dbg_buf_config)); - +exit: return ret; } @@ -252,13 +252,13 @@ static int ivc_macsec_dbg_buf_config( ret = osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); if (ret != 0) { - return ret; + goto exit; } msg.status = osi_memcpy((void *)dbg_buf_config, (void *) &msg.data.dbg_buf_config, sizeof(struct osi_macsec_dbg_buf_config)); - +exit: return ret; } @@ -360,10 +360,11 @@ static int ivc_macsec_config(struct osi_core_priv_data *const osi_core, ret = osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); if (ret != 0) { - return ret; + goto exit; } *kt_idx = msg.data.macsec_cfg.kt_idx; +exit: return ret; } @@ -525,12 +526,13 @@ static nve32_t ivc_macsec_lut_config(struct osi_core_priv_data *const osi_core, ret = osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); if (ret != 0) { - return ret; + goto exit; } msg.status = osi_memcpy((void *)lut_config, (void *)&msg.data.lut_config, sizeof(struct osi_macsec_lut_config)); +exit: return ret; } diff --git a/osi/core/macsec.c b/osi/core/macsec.c index 22aefba..c3dbf21 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -70,6 +70,7 @@ 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; + nve32_t ret = 0; nveu32_t count; count = 0; @@ -77,7 +78,8 @@ static nve32_t poll_for_dbg_buf_update(struct osi_core_priv_data *const osi_core if (count > retry) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "timeout!\n", 0ULL); - return -1; + ret = -1; + goto err; } dbg_buf_config = osi_readla(osi_core, @@ -91,8 +93,8 @@ static nve32_t poll_for_dbg_buf_update(struct osi_core_priv_data *const osi_core /* wait on UPDATE bit to reset */ osi_core->osd_ops.udelay(RETRY_DELAY); } - - return 0; +err: + return ret; } @@ -194,7 +196,8 @@ static void write_tx_dbg_trigger_evts( nveu8_t *base = (nveu8_t *)osi_core->macsec_base; nveu32_t flags = 0; - nveu32_t tx_trigger_evts, debug_ctrl_reg; + nveu32_t tx_trigger_evts; + nveu32_t debug_ctrl_reg; flags = dbg_buf_config->flags; tx_trigger_evts = osi_readla(osi_core, @@ -280,7 +283,7 @@ static void tx_dbg_trigger_evts( nveu32_t flags = 0; nveu32_t tx_trigger_evts; - if (dbg_buf_config->rw == OSI_DBG_TBL_WRITE) { + if (dbg_buf_config->rw == OSI_LUT_WRITE) { write_tx_dbg_trigger_evts(osi_core, dbg_buf_config); } else { tx_trigger_evts = osi_readla(osi_core, @@ -336,7 +339,8 @@ static void write_rx_dbg_trigger_evts( nveu8_t *base = (nveu8_t *)osi_core->macsec_base; nveu32_t flags = 0; - nveu32_t rx_trigger_evts = 0, debug_ctrl_reg; + nveu32_t rx_trigger_evts = 0; + nveu32_t debug_ctrl_reg; flags = dbg_buf_config->flags; rx_trigger_evts = osi_readla(osi_core, @@ -421,7 +425,7 @@ static void rx_dbg_trigger_evts( nveu32_t flags = 0; nveu32_t rx_trigger_evts = 0; - if (dbg_buf_config->rw == OSI_DBG_TBL_WRITE) { + if (dbg_buf_config->rw == OSI_LUT_WRITE) { write_rx_dbg_trigger_evts(osi_core, dbg_buf_config); } else { rx_trigger_evts = osi_readla(osi_core, @@ -477,12 +481,15 @@ 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) { + nve32_t ret = 0; + /* 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; + ret = -1; + goto err; } if (((dbg_buf_config->ctlr_sel == OSI_CTLR_SEL_TX) && @@ -491,9 +498,11 @@ static nve32_t validate_inputs_macsec_dbg_buf_conf( (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; + ret = -1; + goto err; } - return 0; +err: + return ret; } /** @@ -532,7 +541,8 @@ static nve32_t macsec_dbg_buf_config(struct osi_core_priv_data *const osi_core, nve32_t ret = 0; if (validate_inputs_macsec_dbg_buf_conf(osi_core, dbg_buf_config) < 0) { - return -1; + ret = -1; + goto err; } dbg_config_reg = osi_readla(osi_core, base + MACSEC_DEBUG_BUF_CONFIG_0); @@ -557,13 +567,14 @@ static nve32_t macsec_dbg_buf_config(struct osi_core_priv_data *const osi_core, 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; + goto err; } - if (dbg_buf_config->rw == OSI_NONE) { + if (dbg_buf_config->rw == OSI_LUT_READ) { read_dbg_buf_data(osi_core, dbg_buf_config->dbg_buf); } - return 0; +err: + return ret; } /** @@ -597,17 +608,19 @@ static nve32_t macsec_dbg_events_config( { nveu64_t events = 0; nveu32_t i, flags = dbg_buf_config->flags; + nve32_t ret = 0; /* 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; + ret = -1; + goto err; } /* Only one event allowed to configure at a time */ - if ((flags != OSI_NONE) && (dbg_buf_config->rw == OSI_DBG_TBL_WRITE)) { + if ((flags != OSI_NONE) && (dbg_buf_config->rw == OSI_LUT_WRITE)) { for (i = 0; i < 32U; i++) { if ((flags & ((nveu32_t)(1U) << i)) != OSI_NONE) { CERT_C__POST_INC__U64(events); @@ -616,7 +629,8 @@ static nve32_t macsec_dbg_events_config( 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; + ret = -1; + goto err; } } @@ -632,8 +646,8 @@ static nve32_t macsec_dbg_events_config( "Unknown controller select\n", 0ULL); break; } - - return 0; +err: + return ret; } /** @@ -662,7 +676,8 @@ static inline nveul64_t update_macsec_mmc_val( struct osi_core_priv_data *osi_core, nveu64_t offset) { - nveul64_t value_lo, value_hi; + nveul64_t value_lo; + nveul64_t value_hi; value_lo = osi_readla(osi_core, (nveu8_t *)osi_core->macsec_base + offset); @@ -943,13 +958,17 @@ static nve32_t kt_key_write(struct osi_core_priv_data *const osi_core, static nve32_t validate_kt_config(const struct osi_macsec_kt_config *const kt_config) { + nve32_t ret = 0; + /* 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; + ret = -1; + goto err; } - return 0; +err: + return ret; } @@ -962,7 +981,7 @@ static nve32_t macsec_kt_config(struct osi_core_priv_data *const osi_core, ret = validate_kt_config(kt_config); if (ret < 0) { - return ret; + goto err; } kt_config_reg = osi_readla(osi_core, base + MACSEC_GCM_KEYTABLE_CONFIG); @@ -977,7 +996,7 @@ static nve32_t macsec_kt_config(struct osi_core_priv_data *const osi_core, /* For write operation, load the lut_data registers */ ret = kt_key_write(osi_core, kt_config); if (ret < 0) { - return ret; + goto err; } } else { kt_config_reg &= ~MACSEC_KT_CONFIG_RW; @@ -992,15 +1011,16 @@ static nve32_t macsec_kt_config(struct osi_core_priv_data *const osi_core, /* Wait for this KT update to finish */ ret = poll_for_kt_update(osi_core); if (ret < 0) { - return ret; + goto err; } if (kt_config->table_config.rw == OSI_NONE) { ret = kt_key_read(osi_core, kt_config); if (ret < 0) { - return ret; + goto err; } } +err: return ret; } #endif /* MACSEC_KEY_PROGRAM */ @@ -1036,6 +1056,7 @@ static inline nve32_t poll_for_lut_update(struct osi_core_priv_data *osi_core) nveu32_t lut_config; nveu32_t count; nve32_t cond = 1; + nve32_t ret = 0; count = 0; while (cond == 1) { @@ -1044,7 +1065,8 @@ static inline nve32_t poll_for_lut_update(struct osi_core_priv_data *osi_core) OSI_LOG_ARG_HW_FAIL, "LUT update timed out\n", 0ULL); - return -1; + ret = -1; + goto exit; } count++; @@ -1060,8 +1082,8 @@ static inline nve32_t poll_for_lut_update(struct osi_core_priv_data *osi_core) osi_core->osd_ops.udelay(RETRY_DELAY); } } - - return 0; +exit: + return ret; } /** @@ -1295,7 +1317,7 @@ static void lut_read_inputs_vlan(const nveu32_t *const lut_data, * @retval -1 for failure */ static nve32_t lut_read_inputs(struct osi_macsec_lut_config *const lut_config, - nveu32_t *const lut_data) + const nveu32_t *const lut_data) { struct osi_lut_inputs entry = {0}; nveu32_t flags = 0; @@ -1387,7 +1409,8 @@ 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 flags = 0; + nveu32_t val = 0; nveu32_t index = lut_config->table_config.index; nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; nveu8_t *paddr = OSI_NULL; @@ -1398,7 +1421,8 @@ static nve32_t byp_lut_read(struct osi_core_priv_data *const osi_core, 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; + ret = -1; + goto err; } /* Lookup output */ @@ -1437,6 +1461,7 @@ static nve32_t byp_lut_read(struct osi_core_priv_data *const osi_core, } lut_config->flags |= flags; } +err: return ret; } @@ -1540,7 +1565,8 @@ static nve32_t sci_lut_read(struct osi_core_priv_data *const osi_core, nve32_t ret = 0; if (index > OSI_SC_LUT_MAX_INDEX) { - return -1; + ret = -1; + goto exit; } read_lut_data(osi_core, lut_data); @@ -1549,7 +1575,8 @@ static nve32_t sci_lut_read(struct osi_core_priv_data *const osi_core, 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; + ret = -1; + goto exit; } tx_sci_lut_read(osi_core, lut_config, lut_data); break; @@ -1584,8 +1611,7 @@ static nve32_t sci_lut_read(struct osi_core_priv_data *const osi_core, ret = -1; break; } - - /* Lookup output */ +exit: return ret; } @@ -1654,7 +1680,6 @@ static nve32_t sc_param_lut_read(struct osi_core_priv_data *const osi_core, break; } - /* Lookup output */ return ret; } @@ -1922,7 +1947,7 @@ static void tx_sa_state_lut_config(const struct osi_macsec_lut_config *const lut * @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) + const 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; @@ -2083,7 +2108,7 @@ static void tx_sc_param_lut_config( * @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) + const 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; @@ -2093,7 +2118,8 @@ static nve32_t sc_param_lut_config(struct osi_core_priv_data *const osi_core, 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; + ret = -1; + goto exit; } switch (table_config.ctlr_sel) { @@ -2111,7 +2137,7 @@ static nve32_t sc_param_lut_config(struct osi_core_priv_data *const osi_core, } commit_lut_data(osi_core, lut_data); - +exit: return ret; } @@ -2491,18 +2517,20 @@ static void lut_config_preempt_mask(const struct osi_macsec_lut_config *const lu * @retval 0 on success * @retval -1 on failure */ -static nve32_t lut_config_inputs(struct osi_macsec_lut_config *const lut_config, +static nve32_t lut_config_inputs(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; nveu32_t i, j = OSI_LUT_FLAGS_BYTE0_PATTERN_VALID; + nve32_t ret = 0; 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; + ret = -1; + goto exit; } } j <<= 1; @@ -2512,14 +2540,16 @@ static nve32_t lut_config_inputs(struct osi_macsec_lut_config *const lut_config, OSI_LUT_FLAGS_BYTE0_PATTERN_VALID) { if (entry.byte_pattern_offset[0] > OSI_LUT_BYTE_PATTERN_MAX_OFFSET) { - return -1; + ret = -1; + goto exit; } } 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; + ret = -1; + goto exit; } } @@ -2529,8 +2559,8 @@ static nve32_t lut_config_inputs(struct osi_macsec_lut_config *const lut_config, 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; +exit: + return ret; } /** @@ -2563,9 +2593,11 @@ static nve32_t rx_sci_lut_config( { nveu32_t flags = lut_config->flags; struct osi_sci_lut_outputs entry = lut_config->sci_lut_out; + nve32_t ret = 0; if (entry.sc_index > OSI_SC_INDEX_MAX) { - return -1; + ret = -1; + goto exit; } lut_data[0] |= ((nveu32_t)(entry.sci[0]) | @@ -2591,12 +2623,12 @@ static nve32_t rx_sci_lut_config( } lut_data[2] |= entry.sc_index << 10; - - return 0; +exit: + return ret; } /** - * @brief rx_sci_lut_config - update lut_data from lut_config for sci_lut + * @brief tx_sci_lut_config - update lut_data from lut_config for sci_lut * * @note * Algorithm: @@ -2621,15 +2653,17 @@ static nve32_t rx_sci_lut_config( * @retval -1 on failure */ static nve32_t tx_sci_lut_config( - struct osi_macsec_lut_config *const 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; nveu32_t an_valid = entry.an_valid; + nve32_t ret = 0; if (lut_config_inputs(lut_config, lut_data) != 0) { - return -1; + ret = -1; + goto exit; } /* Lookup result fields */ @@ -2656,7 +2690,8 @@ static nve32_t tx_sci_lut_config( OSI_LUT_FLAGS_DVLAN_OUTER_INNER_TAG_SEL) { lut_data[6] |= MACSEC_TX_SCI_LUT_DVLAN_OUTER_INNER_TAG_SEL; } - return 0; +exit: + return ret; } /** @@ -2686,7 +2721,7 @@ static nve32_t tx_sci_lut_config( * @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) + const 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; @@ -2700,7 +2735,8 @@ static nve32_t sci_lut_config(struct osi_core_priv_data *const osi_core, (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; + ret = -1; + goto exit; } switch (table_config.ctlr_sel) { @@ -2708,7 +2744,8 @@ static nve32_t sci_lut_config(struct osi_core_priv_data *const osi_core, 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; + ret = -1; + goto exit; } commit_lut_data(osi_core, lut_data); @@ -2732,7 +2769,8 @@ static nve32_t sci_lut_config(struct osi_core_priv_data *const osi_core, 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; + ret = -1; + goto exit; } commit_lut_data(osi_core, lut_data); @@ -2758,6 +2796,7 @@ static nve32_t sci_lut_config(struct osi_core_priv_data *const osi_core, ret = -1; break; } +exit: return ret; } @@ -2787,7 +2826,7 @@ static nve32_t sci_lut_config(struct osi_core_priv_data *const osi_core, * @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) + const struct osi_macsec_lut_config *const lut_config) { nveu32_t lut_data[MACSEC_LUT_DATA_REG_CNT] = {0}; nveu32_t flags = lut_config->flags; @@ -2799,7 +2838,8 @@ static nve32_t byp_lut_config(struct osi_core_priv_data *const osi_core, 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; + ret = -1; + goto exit; } /* Lookup output */ @@ -2860,7 +2900,7 @@ static nve32_t byp_lut_config(struct osi_core_priv_data *const osi_core, ret = -1; break; } - +exit: return ret; } @@ -2888,7 +2928,7 @@ static nve32_t byp_lut_config(struct osi_core_priv_data *const osi_core, * @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) + const struct osi_macsec_lut_config *const lut_config) { nve32_t ret = 0; @@ -2942,6 +2982,8 @@ static inline nve32_t lut_data_write(struct osi_core_priv_data *const osi_core, */ static nve32_t validate_lut_conf(const struct osi_macsec_lut_config *const lut_config) { + nve32_t ret = 0; + /* Validate LUT config */ if ((lut_config->table_config.ctlr_sel > OSI_CTLR_SEL_MAX) || (lut_config->table_config.rw > OSI_RW_MAX) || @@ -2952,9 +2994,11 @@ static nve32_t validate_lut_conf(const struct osi_macsec_lut_config *const lut_c lut_config->table_config.ctlr_sel, lut_config->table_config.rw, lut_config->table_config.index, lut_config->lut_sel); - return -1; + ret = -1; + goto exit; } - return 0; +exit: + return ret; } /** @@ -2994,13 +3038,14 @@ static nve32_t macsec_lut_config(struct osi_core_priv_data *const osi_core, nveu8_t *base = (nveu8_t *)osi_core->macsec_base; if (validate_lut_conf(lut_config) < 0) { - return -1; + ret = -1; + goto exit; } /* Wait for previous LUT update to finish */ ret = poll_for_lut_update(osi_core); if (ret < 0) { - return ret; + goto exit; } lut_config_reg = osi_readla(osi_core, base + MACSEC_LUT_CONFIG); @@ -3015,7 +3060,7 @@ static nve32_t macsec_lut_config(struct osi_core_priv_data *const osi_core, /* For write operation, load the lut_data registers */ ret = lut_data_write(osi_core, lut_config); if (ret < 0) { - return ret; + goto exit; } } else { lut_config_reg &= ~MACSEC_LUT_CONFIG_RW; @@ -3034,17 +3079,17 @@ static nve32_t macsec_lut_config(struct osi_core_priv_data *const osi_core, /* Wait for this LUT update to finish */ ret = poll_for_lut_update(osi_core); if (ret < 0) { - return ret; + goto exit; } if (lut_config->table_config.rw == OSI_NONE) { ret = lut_data_read(osi_core, lut_config); if (ret < 0) { - return ret; + goto exit; } } - - return 0; +exit: + return ret; } /** @@ -3509,7 +3554,8 @@ static inline void handle_tx_irq(struct osi_core_priv_data *const osi_core) */ static inline void handle_rx_irq(struct osi_core_priv_data *const osi_core) { - nveu32_t rx_isr, clear = 0; + nveu32_t rx_isr; + nveu32_t clear = 0; nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; #ifdef HSI_SUPPORT nveu64_t rx_crc_err = 0; @@ -3616,7 +3662,8 @@ static inline void handle_rx_irq(struct osi_core_priv_data *const osi_core) */ static inline void handle_common_irq(struct osi_core_priv_data *const osi_core) { - nveu32_t common_isr, clear = 0; + nveu32_t common_isr; + nveu32_t clear = 0; nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; common_isr = osi_readla(osi_core, addr + MACSEC_COMMON_ISR); @@ -3764,6 +3811,7 @@ static nve32_t macsec_cipher_config(struct osi_core_priv_data *const osi_core, { nveu8_t *base = (nveu8_t *)osi_core->macsec_base; nveu32_t val; + nve32_t ret = 0; val = osi_readla(osi_core, base + MACSEC_GCM_AES_CONTROL_0); @@ -3776,11 +3824,13 @@ static nve32_t macsec_cipher_config(struct osi_core_priv_data *const osi_core, val |= MACSEC_TX_AES_MODE_AES256; val |= MACSEC_RX_AES_MODE_AES256; } else { - return -1; + ret = -1; + goto exit; } osi_writela(osi_core, val, base + MACSEC_GCM_AES_CONTROL_0); - return 0; +exit: + return ret; } /** @@ -3812,6 +3862,7 @@ static nve32_t macsec_loopback_config( { nveu8_t *base = (nveu8_t *)osi_core->macsec_base; nveu32_t val; + nve32_t ret = 0; val = osi_readla(osi_core, base + MACSEC_CONTROL1); @@ -3820,11 +3871,13 @@ static nve32_t macsec_loopback_config( } else if (enable == OSI_DISABLE) { val &= ~MACSEC_LOOPBACK_MODE_EN; } else { - return -1; + ret = -1; + goto exit; } osi_writela(osi_core, val, base + MACSEC_CONTROL1); - return 0; +exit: + return ret; } /** @@ -3867,11 +3920,11 @@ static nve32_t clear_byp_lut(struct osi_core_priv_data *const osi_core) if (ret < 0) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Error clearing CTLR:BYPASS LUT:INDEX: \n", j); - return ret; + goto exit; } } } - +exit: return ret; } @@ -3915,10 +3968,11 @@ static nve32_t clear_sci_lut(struct osi_core_priv_data *const osi_core) if (ret < 0) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Error clearing CTLR:SCI LUT:INDEX: \n", j); - return ret; + goto exit; } } } +exit: return ret; } @@ -3962,10 +4016,11 @@ static nve32_t clear_sc_param_lut(struct osi_core_priv_data *const osi_core) 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; + goto exit; } } } +exit: return ret; } @@ -4010,10 +4065,11 @@ static nve32_t clear_sc_state_lut(struct osi_core_priv_data *const osi_core) 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; + goto exit; } } } +exit: return ret; } @@ -4057,7 +4113,7 @@ static nve32_t clear_sa_state_lut(struct osi_core_priv_data *const osi_core) 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; + goto exit; } } @@ -4070,9 +4126,10 @@ static nve32_t clear_sa_state_lut(struct osi_core_priv_data *const osi_core) 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; + goto exit; } } +exit: return ret; } @@ -4117,23 +4174,23 @@ static nve32_t clear_lut(struct osi_core_priv_data *const osi_core) /* 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; + goto exit; } ret = clear_sci_lut(osi_core); if (ret < 0) { - return ret; + goto exit; } ret = clear_sc_param_lut(osi_core); if (ret < 0) { - return ret; + goto exit; } ret = clear_sc_state_lut(osi_core); if (ret < 0) { - return ret; + goto exit; } ret = clear_sa_state_lut(osi_core); if (ret < 0) { - return ret; + goto exit; } #ifdef MACSEC_KEY_PROGRAM @@ -4148,12 +4205,12 @@ static nve32_t clear_lut(struct osi_core_priv_data *const osi_core) if (ret < 0) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Error clearing KT LUT:INDEX: \n", j); - return ret; + goto exit; } } } #endif /* MACSEC_KEY_PROGRAM */ - +exit: return ret; } @@ -4228,11 +4285,13 @@ static nve32_t macsec_update_mtu(struct osi_core_priv_data *const osi_core, { nveu32_t val = 0; nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; + nve32_t ret = 0; if (mtu > OSI_MAX_MTU_SIZE) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Invalid MTU received!!\n", mtu); - return -1; + ret = -1; + goto exit; } /* Set MTU */ val = osi_readla(osi_core, addr + MACSEC_TX_MTU_LEN); @@ -4248,8 +4307,8 @@ static nve32_t macsec_update_mtu(struct osi_core_priv_data *const osi_core, 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; +exit: + return ret; } /** @@ -4304,7 +4363,7 @@ static nve32_t set_byp_lut(struct osi_core_priv_data *const osi_core) 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; + goto exit; } else { osi_core->macsec_lut_status[i].next_byp_idx = (nveu16_t ) ((osi_core->macsec_lut_status[i].next_byp_idx & 0xFFU) + 1U); @@ -4324,13 +4383,14 @@ static nve32_t set_byp_lut(struct osi_core_priv_data *const osi_core) 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; + goto exit; } else { osi_core->macsec_lut_status[i].next_byp_idx = (nveu16_t ) ((osi_core->macsec_lut_status[i].next_byp_idx & 0xFFU) + 1U); } } - return 0; +exit: + return ret; } /** @@ -4389,7 +4449,7 @@ static nve32_t macsec_init(struct osi_core_priv_data *const osi_core, /* Set MTU */ ret = macsec_update_mtu(osi_core, mtu); if (ret < 0) { - return ret; + goto exit; } /* set TX/RX SOT, as SOT value different for eqos. @@ -4462,9 +4522,11 @@ static nve32_t macsec_init(struct osi_core_priv_data *const 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; + goto exit; } - return set_byp_lut(osi_core); + ret = set_byp_lut(osi_core); +exit: + return ret; } /** @@ -4498,16 +4560,17 @@ static struct osi_macsec_sc_info *find_existing_sc( { struct osi_macsec_lut_status *lut_status_ptr = &osi_core->macsec_lut_status[ctlr]; + struct osi_macsec_sc_info *sc_found = OSI_NULL; 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]; + sc_found = &lut_status_ptr->sc_info[i]; } } - return OSI_NULL; + return sc_found; } /** @@ -4541,7 +4604,7 @@ static nveu32_t get_avail_sc_idx(const struct osi_core_priv_data *const osi_core for (i = 0; i < OSI_MAX_NUM_SC; i++) { if (lut_status_ptr->sc_info[i].an_valid == OSI_NONE) { - return i; + break; } } return i; @@ -4586,24 +4649,28 @@ static nve32_t macsec_get_key_index(struct osi_core_priv_data *const osi_core, (ctlr > OSI_CTLR_SEL_MAX)) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Params validation failed\n", 0ULL); - return -1; + ret = -1; + goto exit; } 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; + ret = -1; + goto exit; } 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; + ret = -1; + goto exit; } *key_index = (sc_info->sc_idx_start * OSI_MAX_NUM_SA); - return 0; +exit: + return ret; } /** @@ -4647,7 +4714,7 @@ static nve32_t del_upd_sc(struct osi_core_priv_data *const osi_core, #endif /* MACSEC_KEY_PROGRAM */ struct osi_macsec_lut_config lut_config = {0}; struct osi_macsec_table_config *table_config; - nve32_t ret; + nve32_t ret = 0; /* All input/output fields are already zero'd in declaration. * Write all 0's to LUT index to clear everything @@ -4669,7 +4736,8 @@ static nve32_t del_upd_sc(struct osi_core_priv_data *const osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Failed to del SCI LUT idx\n", sc->sc_idx_start); - return -1; + ret = -1; + goto exit; } /* 2. SC Param LUT */ @@ -4678,7 +4746,8 @@ static nve32_t del_upd_sc(struct osi_core_priv_data *const osi_core, 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; + ret = -1; + goto exit; } /* 3. SC state LUT */ @@ -4687,7 +4756,8 @@ static nve32_t del_upd_sc(struct osi_core_priv_data *const osi_core, 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; + ret = -1; + goto exit; } } @@ -4699,7 +4769,8 @@ static nve32_t del_upd_sc(struct osi_core_priv_data *const osi_core, 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; + ret = -1; + goto exit; } /* Store key table index returned to osd */ @@ -4716,13 +4787,14 @@ static nve32_t del_upd_sc(struct osi_core_priv_data *const osi_core, if (ret < 0) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Failed to del SAK\n", (nveul64_t)ret); - return -1; + ret = -1; + goto exit; } #endif /* MACSEC_KEY_PROGRAM */ existing_sc->an_valid &= ~OSI_BIT(sc->curr_an); - - return 0; +exit: + return ret; } /** @@ -4785,6 +4857,87 @@ static void copy_rev_order(nveu8_t *dst_buff, const nveu8_t *src_buff, nveu16_t } } +/** + * @brief add_upd_sc_err_cleanup - Helper function to handle error conditions in add_upd_sc + * + * @note + * Algorithm: + * - Depending on the error_mask passed clear the 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 + * @param[in] error_mask: Error mask that indicate which LUTs need to be cleared + * @param[in] ctlr: Controller to be selected + * @param[in] sc: Pointer to the SC that was intended to be added + * + * @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 add_upd_sc_err_cleanup(struct osi_core_priv_data *const osi_core, + nveu8_t mask, nveu16_t ctlr, + const struct osi_macsec_sc_info *const sc) +{ + struct osi_macsec_lut_config lut_config = {0}; + struct osi_macsec_table_config *table_config; + nve32_t ret_fail = 0; + nveu8_t error_mask = mask; + + if ((error_mask & OSI_BIT(3)) != OSI_NONE) { + /* Cleanup SCI LUT */ + error_mask &= ((~OSI_BIT(3)) & (0xFFU)); + 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_fail = macsec_lut_config(osi_core, &lut_config); + print_error(osi_core, ret_fail); + } + if ((error_mask & OSI_BIT(2)) != OSI_NONE) { + /* cleanup SC param */ + error_mask &= ((~OSI_BIT(2)) & (0xFFU)); + 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_fail = macsec_lut_config(osi_core, &lut_config); + print_error(osi_core, ret_fail); + } + if ((error_mask & OSI_BIT(1)) != OSI_NONE) { + /* Cleanup SA state LUT */ + error_mask &= ((~OSI_BIT(1)) & (0xFFU)); + 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_fail = macsec_lut_config(osi_core, &lut_config); + print_error(osi_core, ret_fail); + } +#ifdef MACSEC_KEY_PROGRAM + if ((error_mask & OSI_BIT(0)) != OSI_NONE) { + error_mask &= ((~OSI_BIT(0)) & (0xFFU)); + 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_fail = macsec_kt_config(osi_core, &kt_config); + print_error(osi_core, ret_fail); + } +#endif /* MACSEC_KEY_PROGRAM */ +} + /** * @brief add_upd_sc - add or update an SC * @@ -4800,7 +4953,7 @@ static void copy_rev_order(nveu8_t *dst_buff, const nveu8_t *src_buff, nveu16_t * - 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 existing sc * @param[in] ctlr: Controller to be selected * @param[out] kt_idx: Key index to be passed to osd * @@ -4816,13 +4969,14 @@ static void copy_rev_order(nveu8_t *dst_buff, const nveu8_t *src_buff, nveu16_t * @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) + const 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; + nve32_t ret = 0; nveu32_t i; + nveu8_t error_mask = 0; #ifdef MACSEC_KEY_PROGRAM struct osi_macsec_kt_config kt_config = {0}; #endif /* MACSEC_KEY_PROGRAM */ @@ -4847,7 +5001,8 @@ static nve32_t add_upd_sc(struct osi_core_priv_data *const osi_core, if (ret < 0) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Failed to set SAK\n", (nveul64_t)ret); - return -1; + ret = -1; + goto exit; } } #endif /* MACSEC_KEY_PROGRAM */ @@ -4867,7 +5022,8 @@ static nve32_t add_upd_sc(struct osi_core_priv_data *const osi_core, 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; + error_mask |= OSI_BIT(0); + goto exit; } /* 3. SC param LUT */ @@ -4887,7 +5043,8 @@ static nve32_t add_upd_sc(struct osi_core_priv_data *const osi_core, 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; + error_mask |= OSI_BIT(1); + goto exit; } /* 4. SCI LUT */ @@ -4908,7 +5065,8 @@ static nve32_t add_upd_sc(struct osi_core_priv_data *const osi_core, 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; + error_mask |= OSI_BIT(2); + goto exit; } if (sc->flags == OSI_ENABLE_SA) { @@ -4921,56 +5079,13 @@ static nve32_t add_upd_sc(struct osi_core_priv_data *const osi_core, 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; + error_mask |= OSI_BIT(3); + goto exit; } } - 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; +exit: + add_upd_sc_err_cleanup(osi_core, error_mask, ctlr, sc); + return ret; } /** @@ -5000,13 +5115,15 @@ err_sa_state: static nve32_t macsec_config_validate_inputs(nveu32_t enable, nveu16_t ctlr, const nveu16_t *kt_idx) { + nve32_t ret = 0; + /* 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; + ret = -1; } - return 0; + return ret; } /** @@ -5099,21 +5216,24 @@ static nve32_t add_new_sc(struct osi_core_priv_data *const osi_core, 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; + ret = -1; + goto exit; } 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; + ret = -1; + goto exit; } 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; + ret = -1; + goto exit; } new_sc->curr_an = sc->curr_an; new_sc->next_pn = sc->next_pn; @@ -5127,7 +5247,8 @@ static nve32_t add_new_sc(struct osi_core_priv_data *const osi_core, OSI_NONE_SIGNED) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "failed to add new SC\n", 0ULL); - return -1; + ret = -1; + goto exit; } else { /* Update lut status */ lut_status_ptr->num_of_sc_used++; @@ -5135,8 +5256,9 @@ static nve32_t add_new_sc(struct osi_core_priv_data *const osi_core, "Total active SCs: %u", __func__, ctlr, lut_status_ptr->num_of_sc_used); - return 0; } +exit: + return ret; } /** @@ -5180,12 +5302,13 @@ static nve32_t config_macsec(struct osi_core_priv_data *const osi_core, 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; + nve32_t ret = 0; 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; + ret = -1; + goto exit; } lut_status_ptr = &osi_core->macsec_lut_status[ctlr]; @@ -5196,10 +5319,12 @@ static nve32_t config_macsec(struct osi_core_priv_data *const osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "trying to delete non-existing SC ?\n", 0ULL); - return -1; + ret = -1; + goto exit; } else { LOG("%s: Adding new SC/SA: ctlr: %hu", __func__, ctlr); - return add_new_sc(osi_core, sc, ctlr, kt_idx); + ret = add_new_sc(osi_core, sc, ctlr, kt_idx); + goto exit; } } else { LOG("%s: Updating existing SC", __func__); @@ -5209,7 +5334,8 @@ static nve32_t config_macsec(struct osi_core_priv_data *const osi_core, OSI_NONE_SIGNED) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "failed to del SA\n", 0ULL); - return -1; + ret = -1; + goto exit; } else { if ((existing_sc->an_valid == OSI_NONE) && (lut_status_ptr->num_of_sc_used != OSI_NONE)) { @@ -5218,7 +5344,7 @@ static nve32_t config_macsec(struct osi_core_priv_data *const osi_core, sizeof(*existing_sc)); } - return 0; + goto exit; } } else { /* Take backup copy. @@ -5230,7 +5356,8 @@ static nve32_t config_macsec(struct osi_core_priv_data *const osi_core, if (ret < OSI_NONE_SIGNED) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "memcpy Failed\n", 0ULL); - return -1; + ret = -1; + goto exit; } tmp_sc_p->curr_an = sc->curr_an; tmp_sc_p->next_pn = sc->next_pn; @@ -5243,7 +5370,8 @@ static nve32_t config_macsec(struct osi_core_priv_data *const osi_core, OSI_NONE_SIGNED) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "failed to add new SA\n", 0ULL); - return -1; + ret = -1; + goto exit; } else { LOG("%s: Updated new SC ctlr: %u " "Total active SCs: %u", @@ -5251,10 +5379,11 @@ static nve32_t config_macsec(struct osi_core_priv_data *const osi_core, lut_status_ptr->num_of_sc_used); /* Now commit the changes */ *existing_sc = *tmp_sc_p; - return 0; } } } +exit: + return ret; } #ifdef OSI_DEBUG @@ -5348,6 +5477,7 @@ static void macsec_debug_intr_config(struct osi_core_priv_data *const osi_core, nve32_t osi_init_macsec_ops(struct osi_core_priv_data *const osi_core) { static struct osi_macsec_core_ops virt_macsec_ops; + nve32_t ret = 0; static struct osi_macsec_core_ops macsec_ops = { .init = macsec_init, .deinit = macsec_deinit, @@ -5376,11 +5506,13 @@ nve32_t osi_init_macsec_ops(struct osi_core_priv_data *const osi_core) ivc_init_macsec_ops(osi_core->macsec_ops); } else { if (osi_core->macsec_base == OSI_NULL) { - return -1; + ret = -1; + goto exit; } osi_core->macsec_ops = &macsec_ops; } - return 0; +exit: + return ret; } /** @@ -5411,12 +5543,14 @@ nve32_t osi_init_macsec_ops(struct osi_core_priv_data *const osi_core) nve32_t osi_macsec_init(struct osi_core_priv_data *const osi_core, nveu32_t mtu) { + nve32_t ret = -1; + 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); + ret = osi_core->macsec_ops->init(osi_core, mtu); } - return -1; + return ret; } /** @@ -5444,11 +5578,13 @@ nve32_t osi_macsec_init(struct osi_core_priv_data *const osi_core, */ nve32_t osi_macsec_deinit(struct osi_core_priv_data *const osi_core) { + nve32_t ret = -1; + 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); + ret = osi_core->macsec_ops->deinit(osi_core); } - return -1; + return ret; } /** @@ -5534,12 +5670,14 @@ void osi_macsec_s_isr(struct osi_core_priv_data *const osi_core) nve32_t osi_macsec_config_lut(struct osi_core_priv_data *const osi_core, struct osi_macsec_lut_config *const lut_config) { + nve32_t ret = -1; + 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); + ret = osi_core->macsec_ops->lut_config(osi_core, lut_config); } - return -1; + return ret; } /** @@ -5572,13 +5710,15 @@ nve32_t osi_macsec_get_sc_lut_key_index(struct osi_core_priv_data *const osi_cor nveu8_t *sci, nveu32_t *key_index, nveu16_t ctlr) { + nve32_t ret = -1; + 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, + ret = osi_core->macsec_ops->get_sc_lut_key_index(osi_core, sci, key_index, ctlr); } - return -1; + return ret; } /** @@ -5608,12 +5748,14 @@ nve32_t osi_macsec_get_sc_lut_key_index(struct osi_core_priv_data *const osi_cor nve32_t osi_macsec_update_mtu(struct osi_core_priv_data *const osi_core, nveu32_t mtu) { + nve32_t ret = -1; + 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); + ret = osi_core->macsec_ops->update_mtu(osi_core, mtu); } - return -1; + return ret; } #ifdef MACSEC_KEY_PROGRAM @@ -5644,13 +5786,15 @@ nve32_t osi_macsec_update_mtu(struct osi_core_priv_data *const osi_core, nve32_t osi_macsec_config_kt(struct osi_core_priv_data *const osi_core, struct osi_macsec_kt_config *const kt_config) { + nve32_t ret = -1; + 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); + ret = osi_core->macsec_ops->kt_config(osi_core, kt_config); } - return -1; + return ret; } #endif /* MACSEC_KEY_PROGRAM */ @@ -5681,12 +5825,14 @@ nve32_t osi_macsec_config_kt(struct osi_core_priv_data *const osi_core, nve32_t osi_macsec_cipher_config(struct osi_core_priv_data *const osi_core, nveu32_t cipher) { + nve32_t ret = -1; + 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); + ret = osi_core->macsec_ops->cipher_config(osi_core, cipher); } - return -1; + return ret; } /** @@ -5716,13 +5862,14 @@ nve32_t osi_macsec_cipher_config(struct osi_core_priv_data *const osi_core, nve32_t osi_macsec_loopback(struct osi_core_priv_data *const osi_core, nveu32_t enable) { + nve32_t ret = -1; 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); + ret = osi_core->macsec_ops->loopback_config(osi_core, enable); } - return -1; + return ret; } /** @@ -5753,18 +5900,20 @@ nve32_t osi_macsec_loopback(struct osi_core_priv_data *const osi_core, nve32_t osi_macsec_en(struct osi_core_priv_data *const osi_core, nveu32_t enable) { + nve32_t ret = -1; + if (((enable & OSI_MACSEC_TX_EN) != OSI_MACSEC_TX_EN) && ((enable & OSI_MACSEC_RX_EN) != OSI_MACSEC_RX_EN) && (enable != OSI_DISABLE)) { - return -1; + goto exit; } 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); + ret = osi_core->macsec_ops->macsec_en(osi_core, enable); } - - return -1; +exit: + return ret; } /** @@ -5799,18 +5948,20 @@ nve32_t osi_macsec_config(struct osi_core_priv_data *const osi_core, nveu32_t enable, nveu16_t ctlr, nveu16_t *kt_idx) { + nve32_t ret = -1; + if (((enable != OSI_ENABLE) && (enable != OSI_DISABLE)) || (ctlr > OSI_CTLR_SEL_MAX) || (kt_idx == OSI_NULL)) { - return -1; + goto exit; } 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, + ret = osi_core->macsec_ops->config(osi_core, sc, enable, ctlr, kt_idx); } - - return -1; +exit: + return ret; } /** @@ -5838,13 +5989,14 @@ nve32_t osi_macsec_config(struct osi_core_priv_data *const osi_core, */ nve32_t osi_macsec_read_mmc(struct osi_core_priv_data *const osi_core) { + nve32_t ret = -1; + 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; + ret = 0; } - - return -1; + return ret; } /** @@ -5875,14 +6027,15 @@ 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) { + nve32_t ret = -1; 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, + ret = osi_core->macsec_ops->dbg_buf_config(osi_core, dbg_buf_config); } - return -1; + return ret; } /** @@ -5913,14 +6066,15 @@ 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) { + nve32_t ret = -1; 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, + ret = osi_core->macsec_ops->dbg_events_config(osi_core, dbg_buf_config); } - return -1; + return ret; } #endif /* MACSEC_SUPPORT */ diff --git a/osi/core/macsec.h b/osi/core/macsec.h index 7d027d0..6a2c132 100644 --- a/osi/core/macsec.h +++ b/osi/core/macsec.h @@ -48,8 +48,10 @@ * @brief MACsec controller register offsets * @{ */ +#ifdef MACSEC_KEY_PROGRAM #define MACSEC_GCM_KEYTABLE_CONFIG 0x0000 #define MACSEC_GCM_KEYTABLE_DATA(x) ((0x0004U) + ((x) * 4U)) +#endif /* MACSEC_KEY_PROGRAM */ #define MACSEC_RX_ICV_ERR_CNTRL 0x4000 #define MACSEC_INTERRUPT_COMMON_SR 0x4004 #define MACSEC_TX_IMR 0x4008 @@ -89,8 +91,9 @@ #define MACSEC_TX_SCI_LUT_VALID 0xD028 #define MACSEC_RX_BYP_LUT_VALID 0xD02C #define MACSEC_RX_SCI_LUT_VALID 0xD030 - +#ifdef OSI_DEBUG #define MACSEC_COMMON_IMR 0xD054 +#endif /* OSI_DEBUG */ #define MACSEC_COMMON_ISR 0xD058 #define MACSEC_TX_SC_KEY_INVALID_STS0_0 0xD064 #define MACSEC_TX_SC_KEY_INVALID_STS1_0 0xD068 @@ -114,6 +117,7 @@ #define MACSEC_RX_SOT_DELAY 0xE01C /** @} */ +#ifdef MACSEC_KEY_PROGRAM /** * @addtogroup MACSEC_GCM_KEYTABLE_CONFIG register * @@ -138,6 +142,7 @@ #define MACSEC_KT_DATA_REG_SAK_CNT 8U #define MACSEC_KT_DATA_REG_H_CNT 4U /** @} */ +#endif /* MACSEC_KEY_PROGRAM */ /** * @addtogroup MACSEC_LUT_CONFIG register @@ -208,6 +213,7 @@ #define MACSEC_TX_AES_MODE_AES256 OSI_BIT(1) /** @} */ +#ifdef OSI_DEBUG /** * @addtogroup MACSEC_COMMON_IMR register * @@ -220,6 +226,7 @@ #define MACSEC_TX_UNINIT_KEY_SLOT_INT_EN OSI_BIT(1) #define MACSEC_TX_LKUP_MISS_INT_EN OSI_BIT(0) /** @} */ +#endif /* OSI_DEBUG */ /** * @addtogroup MACSEC_TX_IMR register @@ -227,11 +234,12 @@ * @brief Bit definitions of TX_INTERRUPT_MASK register * @{ */ +#define MACSEC_TX_MAC_CRC_ERROR_INT_EN OSI_BIT(16) +#ifdef OSI_DEBUG #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) /** @} */ @@ -243,12 +251,13 @@ * @{ */ #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) +#endif /* OSI_DEBUG */ +#define MACSEC_RX_ICV_ERROR_INT_EN OSI_BIT(21) +#define MACSEC_RX_MAC_CRC_ERROR_INT_EN OSI_BIT(16) /** @} */ /** @@ -441,6 +450,8 @@ /* debug buffer data read/write length */ #define DBG_BUF_LEN 4U +#ifdef MACSEC_KEY_PROGRAM #define INTEGER_LEN 4U +#endif /* MACSEC_KEY_PROGRAM */ #endif /* INCLUDED_MACSEC_H */ diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index b414821..a603e4d 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -6133,7 +6133,7 @@ static void mgbe_config_for_macsec(struct osi_core_priv_data *const osi_core, 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; + goto exit; } /* stop MAC Tx */ mgbe_config_mac_tx(osi_core, OSI_DISABLE); @@ -6195,6 +6195,8 @@ static void mgbe_config_for_macsec(struct osi_core_priv_data *const osi_core, 0ULL); } } +exit: + return; } #endif /* MACSEC_SUPPORT */ From 936badf0b29defe4a0394df6fe0dad6d566f9e7d Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Thu, 23 Jun 2022 14:02:05 +0530 Subject: [PATCH 358/458] osi: dma: combine set_tx_ring_len func Bug 200770328 Change-Id: I86670a482539da2bf164f0f3f3292d338cec28a4 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2734191 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/dma/dma_local.h | 4 ---- osi/dma/eqos_dma.c | 31 ------------------------------- osi/dma/mgbe_dma.c | 24 ------------------------ osi/dma/osi_dma_txrx.c | 16 ++++++++++++++-- 4 files changed, 14 insertions(+), 61 deletions(-) diff --git a/osi/dma/dma_local.h b/osi/dma/dma_local.h index 3c0bb3d..6ba450f 100644 --- a/osi/dma/dma_local.h +++ b/osi/dma/dma_local.h @@ -46,10 +46,6 @@ * @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); diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index dab365d..90fed58 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -145,36 +145,6 @@ static void eqos_dma_safety_init(struct osi_dma_priv_data *osi_dma) osi_lock_init(&config->dma_safety_lock); } -/** - * @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. * @@ -793,7 +763,6 @@ static void eqos_debug_intr_config(struct osi_dma_priv_data *osi_dma) */ 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; diff --git a/osi/dma/mgbe_dma.c b/osi/dma/mgbe_dma.c index f728fe8..ed6340e 100644 --- a/osi/dma/mgbe_dma.c +++ b/osi/dma/mgbe_dma.c @@ -25,29 +25,6 @@ #include "mgbe_dma.h" #include "dma_local.h" -/** - * @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. * @@ -618,7 +595,6 @@ static void mgbe_debug_intr_config(struct osi_dma_priv_data *osi_dma) 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; diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 84c1ee8..8c0d120 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -1294,6 +1294,19 @@ static nve32_t rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, return ret; } +static inline void set_tx_ring_len(const struct osi_dma_priv_data *const osi_dma, + nveu32_t chan, + nveu32_t len) +{ + const nveu32_t ring_len_reg[2] = { EQOS_DMA_CHX_TDRL(chan), MGBE_DMA_CHX_TX_CNTRL2(chan) }; + const nveu32_t mask[2] = { 0x3FFU, 0x3FFFU }; + nveu32_t val; + + val = osi_readl((nveu8_t *)osi_dma->base + ring_len_reg[osi_dma->mac]); + val |= len & mask[osi_dma->mac]; + osi_writel(val, (nveu8_t *)osi_dma->base + ring_len_reg[osi_dma->mac]); +} + /** * @brief tx_dma_desc_init - Initialize DMA Transmit descriptors. * @@ -1355,8 +1368,7 @@ static nve32_t tx_dma_desc_init(struct osi_dma_priv_data *osi_dma, 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)); + 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); } From 63852c5193005617e7ac2045dfc59bd5edf7d0a0 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Thu, 23 Jun 2022 14:38:40 +0530 Subject: [PATCH 359/458] osi: dma: combine set_rx_ring_len func Bug 200770328 Change-Id: I3d1005b2540ec1de7b87b12a96ecf0c72befdd5a Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2734212 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/dma/dma_local.h | 4 ---- osi/dma/eqos_dma.c | 31 ------------------------------- osi/dma/mgbe_dma.c | 24 ------------------------ osi/dma/osi_dma_txrx.c | 11 +++++++++-- 4 files changed, 9 insertions(+), 61 deletions(-) diff --git a/osi/dma/dma_local.h b/osi/dma/dma_local.h index 6ba450f..da7a1ab 100644 --- a/osi/dma/dma_local.h +++ b/osi/dma/dma_local.h @@ -52,10 +52,6 @@ struct dma_chan_ops { /** 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); diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index 90fed58..1d0fad7 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -220,36 +220,6 @@ static void eqos_update_tx_tailptr(void *addr, nveu32_t 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. * @@ -763,7 +733,6 @@ static void eqos_debug_intr_config(struct osi_dma_priv_data *osi_dma) */ void eqos_init_dma_chan_ops(struct dma_chan_ops *ops) { - 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; diff --git a/osi/dma/mgbe_dma.c b/osi/dma/mgbe_dma.c index ed6340e..f7b6263 100644 --- a/osi/dma/mgbe_dma.c +++ b/osi/dma/mgbe_dma.c @@ -83,29 +83,6 @@ static void mgbe_update_tx_tailptr(void *addr, nveu32_t 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. * @@ -595,7 +572,6 @@ static void mgbe_debug_intr_config(struct osi_dma_priv_data *osi_dma) void mgbe_init_dma_chan_ops(struct dma_chan_ops *ops) { - 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; diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 8c0d120..33ca026 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -1182,12 +1182,15 @@ static nve32_t rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, nveu32_t chan, struct dma_chan_ops *ops) { + const nveu32_t ring_len_reg[2] = { EQOS_DMA_CHX_RDRL(chan), MGBE_DMA_CHX_RX_CNTRL2(chan) }; + const nveu32_t mask[2] = { 0x3FFU, 0x3FFFU }; 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; + nveu32_t val; + nveu32_t i; rx_ring = osi_dma->rx_ring[chan]; if (osi_unlikely(rx_ring == OSI_NULL)) { @@ -1246,7 +1249,11 @@ static nve32_t rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, return -1; } - ops->set_rx_ring_len(osi_dma, chan, (osi_dma->rx_ring_sz - 1U)); + /* Update the HW DMA ring length */ + val = osi_readl((nveu8_t *)osi_dma->base + ring_len_reg[osi_dma->mac]); + val |= (osi_dma->rx_ring_sz - 1U) & mask[osi_dma->mac]; + osi_writel(val, (nveu8_t *)osi_dma->base + ring_len_reg[osi_dma->mac]); + 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); From 2d835234a11db33960c6aa5b8ee4dd9f33236e81 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Thu, 23 Jun 2022 16:08:09 +0530 Subject: [PATCH 360/458] osi: dma: combine set_tx_ring_start_addr func Bug 200770328 Change-Id: Iae8994211d1b30dee8f43de5064919a5c62a39cd Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2734261 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/dma/dma_local.h | 3 --- osi/dma/eqos_dma.c | 39 --------------------------------------- osi/dma/mgbe_dma.c | 31 ------------------------------- osi/dma/osi_dma_txrx.c | 37 +++++++++++++++++++++++++++---------- 4 files changed, 27 insertions(+), 83 deletions(-) diff --git a/osi/dma/dma_local.h b/osi/dma/dma_local.h index da7a1ab..2617fee 100644 --- a/osi/dma/dma_local.h +++ b/osi/dma/dma_local.h @@ -46,9 +46,6 @@ * @brief MAC DMA Channel operations */ struct dma_chan_ops { - /** 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); diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index 1d0fad7..8c79083 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -145,44 +145,6 @@ static void eqos_dma_safety_init(struct osi_dma_priv_data *osi_dma) osi_lock_init(&config->dma_safety_lock); } -/** - * @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. * @@ -733,7 +695,6 @@ static void eqos_debug_intr_config(struct osi_dma_priv_data *osi_dma) */ void eqos_init_dma_chan_ops(struct dma_chan_ops *ops) { - 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; diff --git a/osi/dma/mgbe_dma.c b/osi/dma/mgbe_dma.c index f7b6263..aae4538 100644 --- a/osi/dma/mgbe_dma.c +++ b/osi/dma/mgbe_dma.c @@ -25,36 +25,6 @@ #include "mgbe_dma.h" #include "dma_local.h" -/** - * @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. * @@ -572,7 +542,6 @@ static void mgbe_debug_intr_config(struct osi_dma_priv_data *osi_dma) void mgbe_init_dma_chan_ops(struct dma_chan_ops *ops) { - 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; diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 33ca026..94127a7 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -1301,17 +1301,36 @@ static nve32_t rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, return ret; } -static inline void set_tx_ring_len(const struct osi_dma_priv_data *const osi_dma, - nveu32_t chan, - nveu32_t len) +static inline void set_tx_ring_len_and_start_addr(const struct osi_dma_priv_data *const osi_dma, + nveu64_t tx_desc_phy_addr, + nveu32_t chan, + nveu32_t len) { - const nveu32_t ring_len_reg[2] = { EQOS_DMA_CHX_TDRL(chan), MGBE_DMA_CHX_TX_CNTRL2(chan) }; + const nveu32_t ring_len_reg[2] = { + EQOS_DMA_CHX_TDRL(chan), + MGBE_DMA_CHX_TX_CNTRL2(chan) + }; + const nveu32_t start_addr_high_reg[2] = { + EQOS_DMA_CHX_TDLH(chan), + MGBE_DMA_CHX_TDLH(chan) + }; + const nveu32_t start_addr_low_reg[2] = { + EQOS_DMA_CHX_TDLA(chan), + MGBE_DMA_CHX_TDLA(chan) + }; const nveu32_t mask[2] = { 0x3FFU, 0x3FFFU }; nveu32_t val; + /* Program ring length */ val = osi_readl((nveu8_t *)osi_dma->base + ring_len_reg[osi_dma->mac]); val |= len & mask[osi_dma->mac]; osi_writel(val, (nveu8_t *)osi_dma->base + ring_len_reg[osi_dma->mac]); + + /* Program tx ring start address */ + osi_writel(H32(tx_desc_phy_addr), + (nveu8_t *)osi_dma->base + start_addr_high_reg[osi_dma->mac]); + osi_writel(L32(tx_desc_phy_addr), + (nveu8_t *)osi_dma->base + start_addr_low_reg[osi_dma->mac]); } /** @@ -1334,8 +1353,7 @@ static inline void set_tx_ring_len(const struct osi_dma_priv_data *const osi_dma * @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) +static nve32_t tx_dma_desc_init(struct osi_dma_priv_data *osi_dma) { struct osi_tx_ring *tx_ring = OSI_NULL; struct osi_tx_desc *tx_desc = OSI_NULL; @@ -1375,9 +1393,8 @@ static nve32_t tx_dma_desc_init(struct osi_dma_priv_data *osi_dma, tx_ring->slot_number = 0U; tx_ring->slot_check = OSI_DISABLE; - 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); + set_tx_ring_len_and_start_addr(osi_dma, tx_ring->tx_desc_phy_addr, + chan, (osi_dma->tx_ring_sz - 1U)); } return 0; @@ -1388,7 +1405,7 @@ nve32_t dma_desc_init(struct osi_dma_priv_data *osi_dma, { nve32_t ret = 0; - ret = tx_dma_desc_init(osi_dma, ops); + ret = tx_dma_desc_init(osi_dma); if (ret != 0) { return ret; } From ec7f99564eedb94220b4e3d4978ebb2bfe10f371 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Thu, 23 Jun 2022 17:05:16 +0530 Subject: [PATCH 361/458] osi: dma: combine set_rx_ring_start_addr func Bug 200770328 Change-Id: Id5c4eec460daab8424e28ed77d46079be24811e7 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2734293 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/dma/dma_local.h | 3 --- osi/dma/eqos_dma.c | 39 --------------------------------------- osi/dma/mgbe_dma.c | 31 ------------------------------- osi/dma/osi_dma_txrx.c | 21 ++++++++++++++++++--- 4 files changed, 18 insertions(+), 76 deletions(-) diff --git a/osi/dma/dma_local.h b/osi/dma/dma_local.h index 2617fee..dd7cb56 100644 --- a/osi/dma/dma_local.h +++ b/osi/dma/dma_local.h @@ -49,9 +49,6 @@ struct dma_chan_ops { /** 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 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); diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index 8c79083..ae4495f 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -182,44 +182,6 @@ static void eqos_update_tx_tailptr(void *addr, nveu32_t 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 * @@ -695,7 +657,6 @@ static void eqos_debug_intr_config(struct osi_dma_priv_data *osi_dma) */ void eqos_init_dma_chan_ops(struct dma_chan_ops *ops) { - 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->start_dma = eqos_start_dma; diff --git a/osi/dma/mgbe_dma.c b/osi/dma/mgbe_dma.c index aae4538..ce32846 100644 --- a/osi/dma/mgbe_dma.c +++ b/osi/dma/mgbe_dma.c @@ -53,36 +53,6 @@ static void mgbe_update_tx_tailptr(void *addr, nveu32_t 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 * @@ -542,7 +512,6 @@ static void mgbe_debug_intr_config(struct osi_dma_priv_data *osi_dma) void mgbe_init_dma_chan_ops(struct dma_chan_ops *ops) { - 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->start_dma = mgbe_start_dma; diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 94127a7..f1530eb 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -1182,7 +1182,18 @@ static nve32_t rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, nveu32_t chan, struct dma_chan_ops *ops) { - const nveu32_t ring_len_reg[2] = { EQOS_DMA_CHX_RDRL(chan), MGBE_DMA_CHX_RX_CNTRL2(chan) }; + const nveu32_t start_addr_high_reg[2] = { + EQOS_DMA_CHX_RDLH(chan), + MGBE_DMA_CHX_RDLH(chan) + }; + const nveu32_t start_addr_low_reg[2] = { + EQOS_DMA_CHX_RDLA(chan), + MGBE_DMA_CHX_RDLA(chan) + }; + const nveu32_t ring_len_reg[2] = { + EQOS_DMA_CHX_RDRL(chan), + MGBE_DMA_CHX_RX_CNTRL2(chan) + }; const nveu32_t mask[2] = { 0x3FFU, 0x3FFFU }; struct osi_rx_ring *rx_ring = OSI_NULL; struct osi_rx_desc *rx_desc = OSI_NULL; @@ -1255,8 +1266,12 @@ static nve32_t rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, osi_writel(val, (nveu8_t *)osi_dma->base + ring_len_reg[osi_dma->mac]); 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); + + /* Program Ring start address */ + osi_writel(H32(rx_ring->rx_desc_phy_addr), + (nveu8_t *)osi_dma->base + start_addr_high_reg[osi_dma->mac]); + osi_writel(L32(rx_ring->rx_desc_phy_addr), + (nveu8_t *)osi_dma->base + start_addr_low_reg[osi_dma->mac]); return ret; } From 922427eb01e35a890038c5873725c92eee9347c7 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Thu, 23 Jun 2022 17:22:45 +0530 Subject: [PATCH 362/458] osi: dma: combine update_tx_tailptr func Bug 200770328 Change-Id: I6eba39420850ffc39b7eb0dad63829245faa0bde Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2734299 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/dma/dma_local.h | 5 ----- osi/dma/eqos_dma.c | 38 -------------------------------------- osi/dma/mgbe_dma.c | 29 ----------------------------- osi/dma/osi_dma.c | 2 +- osi/dma/osi_dma_txrx.c | 8 ++++++-- 5 files changed, 7 insertions(+), 75 deletions(-) diff --git a/osi/dma/dma_local.h b/osi/dma/dma_local.h index dd7cb56..ed1cea4 100644 --- a/osi/dma/dma_local.h +++ b/osi/dma/dma_local.h @@ -46,9 +46,6 @@ * @brief MAC DMA Channel operations */ struct dma_chan_ops { - /** Called to update Tx Ring tail pointer */ - void (*update_tx_tailptr)(void *addr, nveu32_t chan, - nveu64_t tailptr); /** Called to update Rx ring tail pointer */ void (*update_rx_tailptr)(void *addr, nveu32_t chan, nveu64_t tailptr); @@ -172,7 +169,6 @@ nve32_t init_desc_ops(struct osi_dma_priv_data *osi_dma); * * @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 @@ -183,7 +179,6 @@ nve32_t init_desc_ops(struct osi_dma_priv_data *osi_dma); */ 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 */ diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index ae4495f..7206591 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -145,43 +145,6 @@ static void eqos_dma_safety_init(struct osi_dma_priv_data *osi_dma) osi_lock_init(&config->dma_safety_lock); } -/** - * @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_update_rx_tailptr - Update Rx ring tail pointer * @@ -657,7 +620,6 @@ static void eqos_debug_intr_config(struct osi_dma_priv_data *osi_dma) */ void eqos_init_dma_chan_ops(struct dma_chan_ops *ops) { - ops->update_tx_tailptr = eqos_update_tx_tailptr; ops->update_rx_tailptr = eqos_update_rx_tailptr; ops->start_dma = eqos_start_dma; ops->stop_dma = eqos_stop_dma; diff --git a/osi/dma/mgbe_dma.c b/osi/dma/mgbe_dma.c index ce32846..cf72336 100644 --- a/osi/dma/mgbe_dma.c +++ b/osi/dma/mgbe_dma.c @@ -25,34 +25,6 @@ #include "mgbe_dma.h" #include "dma_local.h" -/** - * @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_update_rx_tailptr - Update Rx ring tail pointer * @@ -512,7 +484,6 @@ static void mgbe_debug_intr_config(struct osi_dma_priv_data *osi_dma) void mgbe_init_dma_chan_ops(struct dma_chan_ops *ops) { - ops->update_tx_tailptr = mgbe_update_tx_tailptr; ops->update_rx_tailptr = mgbe_update_rx_tailptr; ops->start_dma = mgbe_start_dma; ops->stop_dma = mgbe_stop_dma; diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 61d44a2..269afd8 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -761,7 +761,7 @@ nve32_t osi_hw_transmit(struct osi_dma_priv_data *osi_dma, nveu32_t chan) return -1; } - return hw_transmit(osi_dma, osi_dma->tx_ring[chan], l_dma->ops_p, chan); + return hw_transmit(osi_dma, osi_dma->tx_ring[chan], chan); } nve32_t osi_dma_ioctl(struct osi_dma_priv_data *osi_dma) diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index f1530eb..405b4e1 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -968,7 +968,6 @@ fail: 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; @@ -982,6 +981,10 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, nveu32_t f_idx = tx_ring->cur_tx_idx; nveu32_t l_idx = 0; #endif /* OSI_DEBUG */ + const nveu32_t tail_ptr_reg[2] = { + EQOS_DMA_CHX_TDTP(chan), + MGBE_DMA_CHX_TDTLP(chan) + }; nve32_t cntx_desc_consumed; nveu32_t pkt_id = 0x0U; nveu32_t desc_cnt = 0U; @@ -1151,7 +1154,8 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, */ tx_ring->cur_tx_idx = entry; - ops->update_tx_tailptr(osi_dma->base, chan, tailptr); + /* Update the Tx tail pointer */ + osi_writel(L32(tailptr), (nveu8_t *)osi_dma->base + tail_ptr_reg[osi_dma->mac]); return 0; } From aad0f2c846e974e1cbccf5a32f54de5368a4ec58 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Thu, 23 Jun 2022 18:11:17 +0530 Subject: [PATCH 363/458] osi: dma: combine update_rx_tail_ptr func Bug 200770328 Change-Id: I14a298a6fcfb9a869226580bba46ed0e470721bc Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2734314 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/dma/dma_local.h | 21 ++++++++++++++++----- osi/dma/eqos_dma.c | 37 ------------------------------------- osi/dma/mgbe_dma.c | 34 ---------------------------------- osi/dma/osi_dma.c | 4 ++-- osi/dma/osi_dma_txrx.c | 15 ++++++--------- 5 files changed, 24 insertions(+), 87 deletions(-) diff --git a/osi/dma/dma_local.h b/osi/dma/dma_local.h index ed1cea4..dacc052 100644 --- a/osi/dma/dma_local.h +++ b/osi/dma/dma_local.h @@ -24,8 +24,10 @@ #ifndef INCLUDED_DMA_LOCAL_H #define INCLUDED_DMA_LOCAL_H +#include "../osi/common/common.h" #include <osi_dma.h> #include "eqos_dma.h" +#include "mgbe_dma.h" /** * @brief Maximum number of OSI DMA instances. @@ -46,9 +48,6 @@ * @brief MAC DMA Channel operations */ struct dma_chan_ops { - /** Called to update Rx ring tail pointer */ - void (*update_rx_tailptr)(void *addr, nveu32_t chan, - nveu64_t tailptr); /** 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 */ @@ -203,8 +202,7 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, * @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); +nve32_t dma_desc_init(struct osi_dma_priv_data *osi_dma); static inline nveu32_t is_power_of_two(nveu32_t num) { @@ -238,6 +236,19 @@ static inline nveu32_t is_power_of_two(nveu32_t num) #define BOOLEAN_FALSE (0U != 0U) #define L32(data) ((nveu32_t)((data) & 0xFFFFFFFFU)) #define H32(data) ((nveu32_t)(((data) & 0xFFFFFFFF00000000UL) >> 32UL)) + +static inline void update_rx_tail_ptr(const struct osi_dma_priv_data *const osi_dma, + nveu32_t chan, + nveu64_t tailptr) +{ + const nveu32_t tail_ptr_reg[2] = { + EQOS_DMA_CHX_RDTP(chan), + MGBE_DMA_CHX_RDTLP(chan) + }; + + osi_writel(L32(tailptr), (nveu8_t *)osi_dma->base + tail_ptr_reg[osi_dma->mac]); +} + /** @} */ #endif /* INCLUDED_DMA_LOCAL_H */ diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index 7206591..7845114 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -145,42 +145,6 @@ static void eqos_dma_safety_init(struct osi_dma_priv_data *osi_dma) osi_lock_init(&config->dma_safety_lock); } -/** - * @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. * @@ -620,7 +584,6 @@ static void eqos_debug_intr_config(struct osi_dma_priv_data *osi_dma) */ void eqos_init_dma_chan_ops(struct dma_chan_ops *ops) { - ops->update_rx_tailptr = eqos_update_rx_tailptr; ops->start_dma = eqos_start_dma; ops->stop_dma = eqos_stop_dma; ops->init_dma_channel = eqos_init_dma_channel; diff --git a/osi/dma/mgbe_dma.c b/osi/dma/mgbe_dma.c index cf72336..5fdb71c 100644 --- a/osi/dma/mgbe_dma.c +++ b/osi/dma/mgbe_dma.c @@ -25,39 +25,6 @@ #include "mgbe_dma.h" #include "dma_local.h" -/** - * @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. * @@ -484,7 +451,6 @@ static void mgbe_debug_intr_config(struct osi_dma_priv_data *osi_dma) void mgbe_init_dma_chan_ops(struct dma_chan_ops *ops) { - ops->update_rx_tailptr = mgbe_update_rx_tailptr; ops->start_dma = mgbe_start_dma; ops->stop_dma = mgbe_stop_dma; ops->init_dma_channel = mgbe_init_dma_channel; diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 269afd8..7832775 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -395,7 +395,7 @@ nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) return ret; } - ret = dma_desc_init(osi_dma, l_dma->ops_p); + ret = dma_desc_init(osi_dma); if (ret != 0) { return ret; } @@ -700,7 +700,7 @@ nve32_t osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, return -1; } - l_dma->ops_p->update_rx_tailptr(osi_dma->base, chan, tailptr); + update_rx_tail_ptr(osi_dma, chan, tailptr); return 0; } diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 405b4e1..84b76ef 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -1183,8 +1183,7 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, * @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) + nveu32_t chan) { const nveu32_t start_addr_high_reg[2] = { EQOS_DMA_CHX_RDLH(chan), @@ -1269,7 +1268,7 @@ static nve32_t rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, val |= (osi_dma->rx_ring_sz - 1U) & mask[osi_dma->mac]; osi_writel(val, (nveu8_t *)osi_dma->base + ring_len_reg[osi_dma->mac]); - ops->update_rx_tailptr(osi_dma->base, chan, tailptr); + update_rx_tail_ptr(osi_dma, chan, tailptr); /* Program Ring start address */ osi_writel(H32(rx_ring->rx_desc_phy_addr), @@ -1301,8 +1300,7 @@ static nve32_t rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, * @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) +static nve32_t rx_dma_desc_init(struct osi_dma_priv_data *osi_dma) { nveu32_t chan = 0; nveu32_t i; @@ -1311,7 +1309,7 @@ static nve32_t rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, 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); + ret = rx_dma_desc_initialization(osi_dma, chan); if (ret != 0) { return ret; } @@ -1419,8 +1417,7 @@ static nve32_t tx_dma_desc_init(struct osi_dma_priv_data *osi_dma) return 0; } -nve32_t dma_desc_init(struct osi_dma_priv_data *osi_dma, - struct dma_chan_ops *ops) +nve32_t dma_desc_init(struct osi_dma_priv_data *osi_dma) { nve32_t ret = 0; @@ -1429,7 +1426,7 @@ nve32_t dma_desc_init(struct osi_dma_priv_data *osi_dma, return ret; } - ret = rx_dma_desc_init(osi_dma, ops); + ret = rx_dma_desc_init(osi_dma); if (ret != 0) { return ret; } From 833eabd1ee38231c611764add4d19a787af2b0f5 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Thu, 23 Jun 2022 18:50:27 +0530 Subject: [PATCH 364/458] osi: dma: combine start_dma Bug 200770328 Change-Id: I106acca1253dd3d03b5e032f8b0acd7484828c58 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2734346 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_dma.h | 35 -------------------------- osi/dma/dma_local.h | 2 -- osi/dma/eqos_dma.c | 46 ---------------------------------- osi/dma/libnvethernetcl.export | 1 - osi/dma/mgbe_dma.c | 31 ----------------------- osi/dma/osi_dma.c | 44 ++++++++++++++++++-------------- 6 files changed, 25 insertions(+), 134 deletions(-) diff --git a/include/osi_dma.h b/include/osi_dma.h index 92ca752..c1a2d27 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -628,41 +628,6 @@ struct osi_dma_priv_data { */ nveu32_t osi_get_global_dma_status(struct osi_dma_priv_data *osi_dma); -/** - * @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 * diff --git a/osi/dma/dma_local.h b/osi/dma/dma_local.h index dacc052..7cc89be 100644 --- a/osi/dma/dma_local.h +++ b/osi/dma/dma_local.h @@ -48,8 +48,6 @@ * @brief MAC DMA Channel operations */ struct dma_chan_ops { - /** 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 */ diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index 7845114..3a5836e 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -145,51 +145,6 @@ static void eqos_dma_safety_init(struct osi_dma_priv_data *osi_dma) osi_lock_init(&config->dma_safety_lock); } -/** - * @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. * @@ -584,7 +539,6 @@ static void eqos_debug_intr_config(struct osi_dma_priv_data *osi_dma) */ void eqos_init_dma_chan_ops(struct dma_chan_ops *ops) { - 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; diff --git a/osi/dma/libnvethernetcl.export b/osi/dma/libnvethernetcl.export index 311e3bc..cf0ab92 100644 --- a/osi/dma/libnvethernetcl.export +++ b/osi/dma/libnvethernetcl.export @@ -23,7 +23,6 @@ # libnvethernetcl interface export # ############################################################################### -osi_start_dma osi_stop_dma osi_get_refill_rx_desc_cnt osi_rx_dma_desc_init diff --git a/osi/dma/mgbe_dma.c b/osi/dma/mgbe_dma.c index 5fdb71c..19cdfbb 100644 --- a/osi/dma/mgbe_dma.c +++ b/osi/dma/mgbe_dma.c @@ -25,36 +25,6 @@ #include "mgbe_dma.h" #include "dma_local.h" -/** - * @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. * @@ -451,7 +421,6 @@ static void mgbe_debug_intr_config(struct osi_dma_priv_data *osi_dma) void mgbe_init_dma_chan_ops(struct dma_chan_ops *ops) { - 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; diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 7832775..377c1f5 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -357,6 +357,30 @@ nve32_t osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) return 0; } +static inline void start_dma(const struct osi_dma_priv_data *const osi_dma, nveu32_t chan) +{ + const nveu32_t tx_dma_reg[2] = { + EQOS_DMA_CHX_TX_CTRL(chan), + MGBE_DMA_CHX_TX_CTRL(chan) + }; + const nveu32_t rx_dma_reg[2] = { + EQOS_DMA_CHX_RX_CTRL(chan), + MGBE_DMA_CHX_RX_CTRL(chan) + }; + nveu32_t val; + + /* Start Tx DMA */ + val = osi_readl((nveu8_t *)osi_dma->base + tx_dma_reg[osi_dma->mac]); + val |= OSI_BIT(0); + osi_writel(val, (nveu8_t *)osi_dma->base + tx_dma_reg[osi_dma->mac]); + + /* Start Rx DMA */ + val = osi_readl((nveu8_t *)osi_dma->base + rx_dma_reg[osi_dma->mac]); + val |= OSI_BIT(0); + val &= ~OSI_BIT(31); + osi_writel(val, (nveu8_t *)osi_dma->base + rx_dma_reg[osi_dma->mac]); +} + nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) { struct dma_local *l_dma = (struct dma_local *)osi_dma; @@ -426,7 +450,7 @@ nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) return ret; } - l_dma->ops_p->start_dma(osi_dma, chan); + start_dma(osi_dma, chan); } /** @@ -509,24 +533,6 @@ nve32_t osi_handle_dma_intr(struct osi_dma_priv_data *osi_dma, OSI_BIT(tx_rx)); } -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) { From 403223361c63ab3f16f4b575a61697f83bf580b5 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Thu, 23 Jun 2022 21:02:10 +0530 Subject: [PATCH 365/458] osi: dma: combine stop_dma Bug 200770328 Change-Id: I7ecf219ce16ca9bbdde1c5301eaa8accb105e048 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2734404 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_dma.h | 35 ------------------------ osi/dma/dma_local.h | 2 -- osi/dma/eqos_dma.c | 46 ------------------------------- osi/dma/libnvethernetcl.export | 1 - osi/dma/mgbe_dma.c | 31 --------------------- osi/dma/osi_dma.c | 49 ++++++++++++++++++---------------- 6 files changed, 26 insertions(+), 138 deletions(-) diff --git a/include/osi_dma.h b/include/osi_dma.h index c1a2d27..e4de41f 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -628,41 +628,6 @@ struct osi_dma_priv_data { */ nveu32_t osi_get_global_dma_status(struct osi_dma_priv_data *osi_dma); -/** - * @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 * diff --git a/osi/dma/dma_local.h b/osi/dma/dma_local.h index 7cc89be..cc54b70 100644 --- a/osi/dma/dma_local.h +++ b/osi/dma/dma_local.h @@ -48,8 +48,6 @@ * @brief MAC DMA Channel operations */ struct dma_chan_ops { - /** 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 */ diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index 3a5836e..c628eca 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -145,51 +145,6 @@ static void eqos_dma_safety_init(struct osi_dma_priv_data *osi_dma) osi_lock_init(&config->dma_safety_lock); } -/** - * @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 * @@ -539,7 +494,6 @@ static void eqos_debug_intr_config(struct osi_dma_priv_data *osi_dma) */ void eqos_init_dma_chan_ops(struct dma_chan_ops *ops) { - 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 diff --git a/osi/dma/libnvethernetcl.export b/osi/dma/libnvethernetcl.export index cf0ab92..8fdb285 100644 --- a/osi/dma/libnvethernetcl.export +++ b/osi/dma/libnvethernetcl.export @@ -23,7 +23,6 @@ # libnvethernetcl interface export # ############################################################################### -osi_stop_dma osi_get_refill_rx_desc_cnt osi_rx_dma_desc_init osi_set_rx_buf_len diff --git a/osi/dma/mgbe_dma.c b/osi/dma/mgbe_dma.c index 19cdfbb..63f4955 100644 --- a/osi/dma/mgbe_dma.c +++ b/osi/dma/mgbe_dma.c @@ -25,36 +25,6 @@ #include "mgbe_dma.h" #include "dma_local.h" -/** - * @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 * @@ -421,7 +391,6 @@ static void mgbe_debug_intr_config(struct osi_dma_priv_data *osi_dma) void mgbe_init_dma_chan_ops(struct dma_chan_ops *ops) { - 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; diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 377c1f5..12f5ebe 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -464,6 +464,31 @@ nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) return 0; } +static inline void stop_dma(const struct osi_dma_priv_data *const osi_dma, + nveu32_t chan) +{ + const nveu32_t dma_tx_reg[2] = { + EQOS_DMA_CHX_TX_CTRL(chan), + MGBE_DMA_CHX_TX_CTRL(chan) + }; + const nveu32_t dma_rx_reg[2] = { + EQOS_DMA_CHX_RX_CTRL(chan), + MGBE_DMA_CHX_RX_CTRL(chan) + }; + nveu32_t val; + + /* Stop Tx DMA */ + val = osi_readl((nveu8_t *)osi_dma->base + dma_tx_reg[osi_dma->mac]); + val &= ~OSI_BIT(0); + osi_writel(val, (nveu8_t *)osi_dma->base + dma_tx_reg[osi_dma->mac]); + + /* Stop Rx DMA */ + val = osi_readl((nveu8_t *)osi_dma->base + dma_rx_reg[osi_dma->mac]); + val &= ~OSI_BIT(0); + val |= OSI_BIT(31); + osi_writel(val, (nveu8_t *)osi_dma->base + dma_rx_reg[osi_dma->mac]); +} + nve32_t osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma) { struct dma_local *l_dma = (struct dma_local *)osi_dma; @@ -486,13 +511,9 @@ nve32_t osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma) } for (i = 0; i < osi_dma->num_dma_chans; i++) { - l_dma->ops_p->stop_dma(osi_dma, osi_dma->dma_chans[i]); + 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; } @@ -533,24 +554,6 @@ nve32_t osi_handle_dma_intr(struct osi_dma_priv_data *osi_dma, OSI_BIT(tx_rx)); } -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) { From 70b2ce03989ed96b316fba7e7852fce4fde46134 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Fri, 24 Jun 2022 10:20:53 +0530 Subject: [PATCH 366/458] osi: dma: perform rx_pkt_cx memset after OWN bit check Bug 200770328 Change-Id: Ibf89ec6e6e3ffec845120ad4d6da159ef9782eb5 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2734689 Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/dma/osi_dma_txrx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 84b76ef..5bd2280 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -160,14 +160,14 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, *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; } + rx_swcx = rx_ring->rx_swcx + rx_ring->cur_rx_idx; + osi_memset(rx_pkt_cx, 0U, sizeof(*rx_pkt_cx)); #ifdef OSI_DEBUG if (osi_dma->enable_desc_dump == 1U) { desc_dump(osi_dma, rx_ring->cur_rx_idx, From a68f6eab801ad26a19654c557b4e12c2f3c5e8a7 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Tue, 28 Jun 2022 11:31:16 +0530 Subject: [PATCH 367/458] osi: dma: combine rx_buf_len Bug 200770328 Change-Id: I573462275d13eba1417203eb44606913b7885552 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2736236 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_dma.h | 1 - osi/dma/dma_local.h | 2 -- osi/dma/eqos_dma.c | 36 ------------------------------------ osi/dma/eqos_dma.h | 1 - osi/dma/hw_common.h | 1 + osi/dma/mgbe_dma.c | 25 ++----------------------- osi/dma/mgbe_dma.h | 1 - osi/dma/osi_dma.c | 14 +++++++++++++- 8 files changed, 16 insertions(+), 65 deletions(-) diff --git a/include/osi_dma.h b/include/osi_dma.h index e4de41f..a17433d 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -45,7 +45,6 @@ * @brief EQOS generic helper MACROS. * @{ */ -#define OSI_NET_IP_ALIGN 0x2U #define NV_VLAN_HLEN 0x4U #define OSI_ETH_HLEN 0xEU diff --git a/osi/dma/dma_local.h b/osi/dma/dma_local.h index cc54b70..cea5055 100644 --- a/osi/dma/dma_local.h +++ b/osi/dma/dma_local.h @@ -50,8 +50,6 @@ struct dma_chan_ops { /** 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 */ diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index c628eca..f5a9624 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -279,41 +279,6 @@ static nve32_t eqos_init_dma_channel(struct osi_dma_priv_data *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. @@ -495,7 +460,6 @@ static void eqos_debug_intr_config(struct osi_dma_priv_data *osi_dma) void eqos_init_dma_chan_ops(struct dma_chan_ops *ops) { 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; diff --git a/osi/dma/eqos_dma.h b/osi/dma/eqos_dma.h index b1a595b..4b48627 100644 --- a/osi/dma/eqos_dma.h +++ b/osi/dma/eqos_dma.h @@ -159,7 +159,6 @@ #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 /** @} */ /** diff --git a/osi/dma/hw_common.h b/osi/dma/hw_common.h index 48d48fc..9e615d0 100644 --- a/osi/dma/hw_common.h +++ b/osi/dma/hw_common.h @@ -32,6 +32,7 @@ #define HW_GLOBAL_DMA_STATUS 0x8700U #define VIRT_INTR_CHX_CNTRL(x) (0x8600U + ((x) * 8U)) #define VIRT_INTR_CHX_STATUS(x) (0x8604U + ((x) * 8U)) +#define AXI_BUS_WIDTH 0x10U /** @} */ #endif /* INCLUDED_HW_COMMON_H */ diff --git a/osi/dma/mgbe_dma.c b/osi/dma/mgbe_dma.c index 63f4955..fbac178 100644 --- a/osi/dma/mgbe_dma.c +++ b/osi/dma/mgbe_dma.c @@ -243,28 +243,7 @@ static nve32_t mgbe_init_dma_channel(struct osi_dma_priv_data *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)); -} - +#ifndef OSI_STRIPPED_LIB /** * @brief Read-validate HW registers for functional safety. * @@ -392,7 +371,7 @@ static void mgbe_debug_intr_config(struct osi_dma_priv_data *osi_dma) void mgbe_init_dma_chan_ops(struct dma_chan_ops *ops) { ops->init_dma_channel = mgbe_init_dma_channel; - ops->set_rx_buf_len = mgbe_set_rx_buf_len; +#ifndef OSI_STRIPPED_LIB ops->validate_regs = mgbe_validate_dma_regs; ops->config_slot = mgbe_config_slot; #ifdef OSI_DEBUG diff --git a/osi/dma/mgbe_dma.h b/osi/dma/mgbe_dma.h index 52495cd..fce843b 100644 --- a/osi/dma/mgbe_dma.h +++ b/osi/dma/mgbe_dma.h @@ -84,7 +84,6 @@ #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_RIE OSI_BIT(6) diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 12f5ebe..5f807ff 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -717,12 +717,24 @@ nve32_t osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, nve32_t osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) { struct dma_local *l_dma = (struct dma_local *)osi_dma; + nveu32_t rx_buf_len; if (validate_args(osi_dma, l_dma) < 0) { return -1; } - l_dma->ops_p->set_rx_buf_len(osi_dma); + if (osi_dma->mtu > OSI_MAX_MTU_SIZE) { + OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "Invalid MTU setting\n", 0ULL); + return -1; + } + + /* Add Ethernet header + FCS */ + rx_buf_len = osi_dma->mtu + OSI_ETH_HLEN + NV_VLAN_HLEN; + + /* Buffer alignment */ + osi_dma->rx_buf_len = ((rx_buf_len + (AXI_BUS_WIDTH - 1U)) & + ~(AXI_BUS_WIDTH - 1U)); return 0; } From 5d937f6cf23df69f12f3a3583662ae37c996ea62 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Tue, 28 Jun 2022 11:31:16 +0530 Subject: [PATCH 368/458] osi: dma: combine init_dma_channel This change combines EQOS and MGBE init into single function and also removes the safety registers validation. Bug 200770328 Change-Id: I75b575a53318b10770b40d76e209b6f6aa9bbead Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2737141 Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_dma.h | 40 ------ osi/dma/dma_local.h | 5 - osi/dma/eqos_dma.c | 322 -------------------------------------------- osi/dma/hw_common.h | 8 ++ osi/dma/mgbe_dma.c | 255 +---------------------------------- osi/dma/mgbe_dma.h | 5 +- osi/dma/osi_dma.c | 159 ++++++++++++++++++---- 7 files changed, 144 insertions(+), 650 deletions(-) diff --git a/include/osi_dma.h b/include/osi_dma.h index a17433d..1c0831d 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -576,9 +576,6 @@ struct osi_dma_priv_data { 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*/ @@ -1108,43 +1105,6 @@ nve32_t osi_handle_dma_intr(struct osi_dma_priv_data *osi_dma, */ 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. * diff --git a/osi/dma/dma_local.h b/osi/dma/dma_local.h index cea5055..dc531c4 100644 --- a/osi/dma/dma_local.h +++ b/osi/dma/dma_local.h @@ -48,12 +48,7 @@ * @brief MAC DMA Channel operations */ struct dma_chan_ops { - /** Called to initialize the DMA channel */ - nve32_t (*init_dma_channel)(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, diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index f5a9624..115bedd 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -25,319 +25,7 @@ #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_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 */ - /* TIE - Transmit Interrupt Enable */ - /* RIE - Receive Interrupt Enable */ - value = osi_readl((nveu8_t *)osi_dma->base + - EQOS_DMA_CHX_INTR_ENA(chan)); - value |= (EQOS_DMA_CHX_INTR_TIE | EQOS_DMA_CHX_INTR_RIE); - 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; -} - #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 * @@ -395,14 +83,6 @@ static void eqos_config_slot(struct osi_dma_priv_data *osi_dma, } #endif /* !OSI_STRIPPED_LIB */ -/** - * @brief eqos_get_dma_safety_config - EQOS get DMA safety configuration - */ -void *eqos_get_dma_safety_config(void) -{ - return &eqos_dma_safety_config; -} - #ifdef OSI_DEBUG /** * @brief Enable/disable debug interrupt @@ -459,9 +139,7 @@ static void eqos_debug_intr_config(struct osi_dma_priv_data *osi_dma) */ void eqos_init_dma_chan_ops(struct dma_chan_ops *ops) { - ops->init_dma_channel = eqos_init_dma_channel; #ifndef OSI_STRIPPED_LIB - ops->validate_regs = eqos_validate_dma_regs; ops->config_slot = eqos_config_slot; #endif /* !OSI_STRIPPED_LIB */ #ifdef OSI_DEBUG diff --git a/osi/dma/hw_common.h b/osi/dma/hw_common.h index 9e615d0..474c7d3 100644 --- a/osi/dma/hw_common.h +++ b/osi/dma/hw_common.h @@ -33,6 +33,14 @@ #define VIRT_INTR_CHX_CNTRL(x) (0x8600U + ((x) * 8U)) #define VIRT_INTR_CHX_STATUS(x) (0x8604U + ((x) * 8U)) #define AXI_BUS_WIDTH 0x10U +#define DMA_CHX_INTR_TIE OSI_BIT(0) +#define DMA_CHX_INTR_RIE OSI_BIT(6) +#define DMA_CHX_CTRL_PBLX8 OSI_BIT(16) +#define DMA_CHX_TX_CTRL_OSP OSI_BIT(4) +#define DMA_CHX_TX_CTRL_TSE OSI_BIT(12) +#define DMA_CHX_RBSZ_MASK 0x7FFEU +#define DMA_CHX_RBSZ_SHIFT 1U +#define DMA_CHX_RX_WDT_RWT_MASK 0xFFU /** @} */ #endif /* INCLUDED_HW_COMMON_H */ diff --git a/osi/dma/mgbe_dma.c b/osi/dma/mgbe_dma.c index fbac178..95eb967 100644 --- a/osi/dma/mgbe_dma.c +++ b/osi/dma/mgbe_dma.c @@ -25,258 +25,7 @@ #include "mgbe_dma.h" #include "dma_local.h" -/** - * @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 */ - /* TIE - Transmit Interrupt Enable */ - /* RIE - Receive Interrupt 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_RIE); - 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; -} - #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 mgbe_validate_dma_regs(OSI_UNUSED - struct osi_dma_priv_data *osi_dma) -{ - /* TODO: for mgbe */ - return 0; -} - /** * @brief mgbe_config_slot - Configure slot Checking for DMA channel * @@ -318,6 +67,7 @@ static void mgbe_config_slot(struct osi_dma_priv_data *osi_dma, MGBE_DMA_CHX_SLOT_CTRL(chan)); } } +#endif #ifdef OSI_DEBUG /** @@ -370,10 +120,9 @@ static void mgbe_debug_intr_config(struct osi_dma_priv_data *osi_dma) void mgbe_init_dma_chan_ops(struct dma_chan_ops *ops) { - ops->init_dma_channel = mgbe_init_dma_channel; #ifndef OSI_STRIPPED_LIB - ops->validate_regs = mgbe_validate_dma_regs; ops->config_slot = mgbe_config_slot; +#endif #ifdef OSI_DEBUG ops->debug_intr_config = mgbe_debug_intr_config; #endif diff --git a/osi/dma/mgbe_dma.h b/osi/dma/mgbe_dma.h index fce843b..97010bf 100644 --- a/osi/dma/mgbe_dma.h +++ b/osi/dma/mgbe_dma.h @@ -79,9 +79,8 @@ #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_RX_WDT_RWTU_2048_CYCLE 3000U +#define MGBE_DMA_CHX_RX_WDT_RWTU_MASK 3000U #define MGBE_DMA_CHX_RBSZ_MASK 0x7FFEU #define MGBE_DMA_CHX_RBSZ_SHIFT 1U #define MGBE_DMA_CHX_CTRL_PBLX8 OSI_BIT(16) diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 5f807ff..fb672a2 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -226,6 +226,7 @@ static inline nve32_t validate_dma_chans(struct osi_dma_priv_data *osi_dma) return 0; } +#ifndef OSI_STRIPPED_LIB /** * @brief Function to validate function pointers. * @@ -269,6 +270,7 @@ static nve32_t validate_func_ptrs(struct osi_dma_priv_data *osi_dma, return 0; } +#endif nve32_t osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) { @@ -276,16 +278,11 @@ nve32_t osi_init_dma_ops(struct osi_dma_priv_data *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; } @@ -335,21 +332,19 @@ nve32_t osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) 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; } +#ifndef OSI_STRIPPED_LIB 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; } +#endif l_dma->ops_p = &g_ops[osi_dma->mac]; l_dma->init_done = OSI_ENABLE; @@ -381,6 +376,132 @@ static inline void start_dma(const struct osi_dma_priv_data *const osi_dma, nveu osi_writel(val, (nveu8_t *)osi_dma->base + rx_dma_reg[osi_dma->mac]); } +static void init_dma_channel(const struct osi_dma_priv_data *const osi_dma, + nveu32_t chan) +{ + const nveu32_t intr_en_reg[2] = { + EQOS_DMA_CHX_INTR_ENA(chan), + MGBE_DMA_CHX_INTR_ENA(chan) + }; + const nveu32_t chx_ctrl_reg[2] = { + EQOS_DMA_CHX_CTRL(chan), + MGBE_DMA_CHX_CTRL(chan) + }; + const nveu32_t tx_ctrl_reg[2] = { + EQOS_DMA_CHX_TX_CTRL(chan), + MGBE_DMA_CHX_TX_CTRL(chan) + }; + const nveu32_t rx_ctrl_reg[2] = { + EQOS_DMA_CHX_RX_CTRL(chan), + MGBE_DMA_CHX_RX_CTRL(chan) + }; + const nveu32_t rx_wdt_reg[2] = { + EQOS_DMA_CHX_RX_WDT(chan), + MGBE_DMA_CHX_RX_WDT(chan) + }; + const nveu32_t tx_pbl[2] = { + EQOS_DMA_CHX_TX_CTRL_TXPBL_RECOMMENDED, + ((((MGBE_TXQ_SIZE / osi_dma->num_dma_chans) - + osi_dma->mtu) / (MGBE_AXI_DATAWIDTH / 8U)) - 5U) + }; + const nveu32_t rx_pbl[2] = { + EQOS_DMA_CHX_RX_CTRL_RXPBL_RECOMMENDED, + ((MGBE_RXQ_SIZE / osi_dma->num_dma_chans) / 2U) + }; + const nveu32_t rwt_val[2] = { + (((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), + (((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) + }; + const nveu32_t rwtu_val[2] = { + EQOS_DMA_CHX_RX_WDT_RWTU_512_CYCLE, + MGBE_DMA_CHX_RX_WDT_RWTU_2048_CYCLE + }; + const nveu32_t rwtu_mask[2] = { + EQOS_DMA_CHX_RX_WDT_RWTU_MASK, + MGBE_DMA_CHX_RX_WDT_RWTU_MASK + }; + const nveu32_t owrq = (MGBE_DMA_CHX_RX_CNTRL2_OWRQ_MCHAN / osi_dma->num_dma_chans); + const nveu32_t owrq_arr[OSI_MGBE_MAX_NUM_CHANS] = { + MGBE_DMA_CHX_RX_CNTRL2_OWRQ_SCHAN, owrq, owrq, owrq, + owrq, owrq, owrq, owrq, owrq, owrq + }; + nveu32_t val; + + /* Enable Transmit/Receive interrupts */ + val = osi_readl((nveu8_t *)osi_dma->base + intr_en_reg[osi_dma->mac]); + val |= (DMA_CHX_INTR_TIE | DMA_CHX_INTR_RIE); + osi_writel(val, (nveu8_t *)osi_dma->base + intr_en_reg[osi_dma->mac]); + + /* Enable PBLx8 */ + val = osi_readl((nveu8_t *)osi_dma->base + chx_ctrl_reg[osi_dma->mac]); + val |= DMA_CHX_CTRL_PBLX8; + osi_writel(val, (nveu8_t *)osi_dma->base + chx_ctrl_reg[osi_dma->mac]); + + /* Program OSP, TSO enable and TXPBL */ + val = osi_readl((nveu8_t *)osi_dma->base + tx_ctrl_reg[osi_dma->mac]); + val |= (DMA_CHX_TX_CTRL_OSP | DMA_CHX_TX_CTRL_TSE); + + if (osi_dma->mac == OSI_MAC_HW_EQOS) { + val |= tx_pbl[osi_dma->mac]; + } else { + /* + * 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 (tx_pbl[osi_dma->mac] >= MGBE_DMA_CHX_MAX_PBL) { + val |= ((MGBE_DMA_CHX_MAX_PBL / 8U) << MGBE_DMA_CHX_CTRL_PBL_SHIFT); + } else { + val |= ((tx_pbl[osi_dma->mac] / 8U) << MGBE_DMA_CHX_CTRL_PBL_SHIFT); + } + } + osi_writel(val, (nveu8_t *)osi_dma->base + tx_ctrl_reg[osi_dma->mac]); + + val = osi_readl((nveu8_t *)osi_dma->base + rx_ctrl_reg[osi_dma->mac]); + val &= ~DMA_CHX_RBSZ_MASK; + val |= (osi_dma->rx_buf_len << DMA_CHX_RBSZ_SHIFT); + if (osi_dma->mac == OSI_MAC_HW_EQOS) { + val |= rx_pbl[osi_dma->mac]; + } else { + if (rx_pbl[osi_dma->mac] >= MGBE_DMA_CHX_MAX_PBL) { + val |= ((MGBE_DMA_CHX_MAX_PBL / 8U) << MGBE_DMA_CHX_CTRL_PBL_SHIFT); + } else { + val |= ((rx_pbl[osi_dma->mac] / 8U) << MGBE_DMA_CHX_CTRL_PBL_SHIFT); + } + } + osi_writel(val, (nveu8_t *)osi_dma->base + rx_ctrl_reg[osi_dma->mac]); + + if ((osi_dma->use_riwt == OSI_ENABLE) && + (osi_dma->rx_riwt < UINT_MAX)) { + val = osi_readl((nveu8_t *)osi_dma->base + rx_wdt_reg[osi_dma->mac]); + val &= ~DMA_CHX_RX_WDT_RWT_MASK; + val |= rwt_val[osi_dma->mac]; + osi_writel(val, (nveu8_t *)osi_dma->base + rx_wdt_reg[osi_dma->mac]); + + val = osi_readl((nveu8_t *)osi_dma->base + rx_wdt_reg[osi_dma->mac]); + val &= ~rwtu_mask[osi_dma->mac]; + val |= rwtu_val[osi_dma->mac]; + osi_writel(val, (nveu8_t *)osi_dma->base + rx_wdt_reg[osi_dma->mac]); + } + + if (osi_dma->mac == OSI_MAC_HW_MGBE) { + /* Update ORRQ in DMA_CH(#i)_Tx_Control2 register */ + val = osi_readl((nveu8_t *)osi_dma->base + MGBE_DMA_CHX_TX_CNTRL2(chan)); + val |= (((MGBE_DMA_CHX_TX_CNTRL2_ORRQ_RECOMMENDED / osi_dma->num_dma_chans)) << + MGBE_DMA_CHX_TX_CNTRL2_ORRQ_SHIFT); + osi_writel(val, (nveu8_t *)osi_dma->base + MGBE_DMA_CHX_TX_CNTRL2(chan)); + + /* Update OWRQ in DMA_CH(#i)_Rx_Control2 register */ + val = osi_readl((nveu8_t *)osi_dma->base + MGBE_DMA_CHX_RX_CNTRL2(chan)); + val |= (owrq_arr[osi_dma->num_dma_chans - 1U] << MGBE_DMA_CHX_RX_CNTRL2_OWRQ_SHIFT); + osi_writel(val, (nveu8_t *)osi_dma->base + MGBE_DMA_CHX_RX_CNTRL2(chan)); + } +} + nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) { struct dma_local *l_dma = (struct dma_local *)osi_dma; @@ -412,13 +533,6 @@ nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) 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); if (ret != 0) { return ret; @@ -428,6 +542,8 @@ nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) for (i = 0; i < osi_dma->num_dma_chans; i++) { chan = osi_dma->dma_chans[i]; + init_dma_channel(osi_dma, chan); + ret = intr_fn[OSI_DMA_INTR_ENABLE](osi_dma, VIRT_INTR_CHX_CNTRL(chan), VIRT_INTR_CHX_STATUS(chan), @@ -907,17 +1023,6 @@ nve32_t osi_config_slot_function(struct osi_dma_priv_data *osi_dma, 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]; From 455e3c610cc926787e04231f6a3b1412337da9f7 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Tue, 21 Jun 2022 20:57:57 +0530 Subject: [PATCH 369/458] osi: core: common poll_for_swr Combine MGBE/EQOS HW level functions into single function. Bug 3701869 Change-Id: I02c4881ec95cc5637867d68e560f4790c3548737 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2732106 Reviewed-by: Krishna Thota <kthota@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_core.h | 35 ----------------------- osi/core/core_common.c | 43 ++++++++++++++++++++++++++++ osi/core/core_common.h | 2 ++ osi/core/core_local.h | 2 -- osi/core/eqos_core.c | 64 ------------------------------------------ osi/core/eqos_core.h | 1 - osi/core/mgbe_core.c | 50 --------------------------------- osi/core/mgbe_core.h | 1 - osi/core/osi_hal.c | 15 ++-------- 9 files changed, 47 insertions(+), 166 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index b8a0660..87d61dd 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -1508,41 +1508,6 @@ struct osi_core_priv_data { #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. * diff --git a/osi/core/core_common.c b/osi/core/core_common.c index 0d218a6..e42d132 100644 --- a/osi/core/core_common.c +++ b/osi/core/core_common.c @@ -25,6 +25,49 @@ #include "mgbe_core.h" #include "eqos_core.h" +static inline nve32_t poll_check(struct osi_core_priv_data *const osi_core, nveu8_t *addr, + nveu32_t bit_check, nveu32_t *value) +{ + nveu32_t retry = RETRY_COUNT; + nve32_t cond = COND_NOT_MET; + nveu32_t count; + nve32_t ret = 0; + + /* 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_check: timeout\n", 0ULL); + ret = -1; + goto fail; + } + + count++; + + *value = osi_readla(osi_core, addr); + if ((*value & bit_check) == OSI_NONE) { + cond = COND_MET; + } else { + osi_core->osd_ops.udelay(OSI_DELAY_1000US); + } + } +fail: + return ret; +} + + +nve32_t hw_poll_for_swr(struct osi_core_priv_data *const osi_core) +{ + nveu32_t dma_mode_val = 0U; + const nveu32_t dma_mode[2] = { EQOS_DMA_BMR, MGBE_DMA_MODE }; + void *addr = osi_core->base; + + return poll_check(osi_core, ((nveu8_t *)addr + dma_mode[osi_core->mac]), + DMA_MODE_SWR, &dma_mode_val); +} + + /** * @brief hw_est_read - indirect read the GCL to Software own list * (SWOL) diff --git a/osi/core/core_common.h b/osi/core/core_common.h index ca36384..f486536 100644 --- a/osi/core/core_common.h +++ b/osi/core/core_common.h @@ -38,6 +38,7 @@ #define MTL_EST_ERR0 OSI_BIT(20) #define MTL_EST_CONTROL_EEST OSI_BIT(0) #define MTL_EST_STATUS_SWOL OSI_BIT(7) +#define DMA_MODE_SWR OSI_BIT(0) /** * @addtogroup typedef related info @@ -58,4 +59,5 @@ struct est_read { 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); +nve32_t hw_poll_for_swr(struct osi_core_priv_data *const osi_core); #endif /* INCLUDED_CORE_COMMON_H */ diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 46b5f87..5fd38ff 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -87,8 +87,6 @@ struct if_core_ops { * @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, diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 6cf75b4..e2b60cc 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -552,69 +552,6 @@ static nve32_t eqos_config_fw_err_pkts( 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 <<RM_04, (sequence diagram)>> 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 * @@ -6869,7 +6806,6 @@ void *eqos_get_core_safety_config(void) 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; diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 841b225..7c46457 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -261,7 +261,6 @@ #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) diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index a603e4d..dafd92e 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -155,55 +155,6 @@ static nve32_t mgbe_config_fw_err_pkts(struct osi_core_priv_data *const osi_core 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 * @@ -6205,7 +6156,6 @@ exit: */ 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; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 65d54b3..4e0405c 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -371,7 +371,6 @@ * @brief consists of corresponding MGBE MAC, MTL register bit values * @{ */ -#define MGBE_DMA_MODE_SWR OSI_BIT(0) #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)) diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 2a87c4f..26466b3 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -25,6 +25,7 @@ #include "core_local.h" #include "../osi/common/common.h" #include "vlan_filter.h" +#include "core_common.h" #include "frp.h" #ifdef OSI_DEBUG #include "debug.h" @@ -200,18 +201,6 @@ static nve32_t osi_hal_init_core_ops(struct osi_core_priv_data *const osi_core) 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 *)(void *)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. * @@ -1982,7 +1971,7 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, #endif /* !OSI_STRIPPED_LIB */ case OSI_CMD_POLL_FOR_MAC_RST: - ret = ops_p->poll_for_swr(osi_core); + ret = hw_poll_for_swr(osi_core); break; case OSI_CMD_START_MAC: From 9b0cf68c15cb9165f726811c4f8f4800a99bce0f Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Thu, 30 Jun 2022 18:21:38 +0000 Subject: [PATCH 370/458] osi: core: combine start_mac Bug 3701869 Change-Id: Ice5ea78f32da1641cc847138869df97149eb72c9 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2737988 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/core_common.c | 18 ++++++++++++++++++ osi/core/core_common.h | 1 + osi/core/core_local.h | 2 -- osi/core/eqos_core.c | 40 ++-------------------------------------- osi/core/mgbe_core.c | 27 --------------------------- osi/core/osi_hal.c | 4 ++-- 6 files changed, 23 insertions(+), 69 deletions(-) diff --git a/osi/core/core_common.c b/osi/core/core_common.c index e42d132..fce2fb6 100644 --- a/osi/core/core_common.c +++ b/osi/core/core_common.c @@ -67,6 +67,24 @@ nve32_t hw_poll_for_swr(struct osi_core_priv_data *const osi_core) DMA_MODE_SWR, &dma_mode_val); } +void hw_start_mac(struct osi_core_priv_data *const osi_core) +{ + void *addr = osi_core->base; + nveu32_t value; + const nveu32_t mac_mcr_te_reg[2] = { EQOS_MAC_MCR, MGBE_MAC_TMCR }; + const nveu32_t mac_mcr_re_reg[2] = { EQOS_MAC_MCR, MGBE_MAC_RMCR }; + const nveu32_t set_bit_te[2] = { EQOS_MCR_TE, MGBE_MAC_TMCR_TE }; + const nveu32_t set_bit_re[2] = { EQOS_MCR_RE, MGBE_MAC_RMCR_RE }; + + value = osi_readla(osi_core, ((nveu8_t *)addr + mac_mcr_te_reg[osi_core->mac])); + value |= set_bit_te[osi_core->mac]; + osi_writela(osi_core, value, ((nveu8_t *)addr + mac_mcr_te_reg[osi_core->mac])); + + value = osi_readla(osi_core, ((nveu8_t *)addr + mac_mcr_re_reg[osi_core->mac])); + value |= set_bit_re[osi_core->mac]; + osi_writela(osi_core, value, ((nveu8_t *)addr + mac_mcr_re_reg[osi_core->mac])); +} + /** * @brief hw_est_read - indirect read the GCL to Software own list diff --git a/osi/core/core_common.h b/osi/core/core_common.h index f486536..fe9fe1c 100644 --- a/osi/core/core_common.h +++ b/osi/core/core_common.h @@ -60,4 +60,5 @@ 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); nve32_t hw_poll_for_swr(struct osi_core_priv_data *const osi_core); +void hw_start_mac(struct osi_core_priv_data *const osi_core); #endif /* INCLUDED_CORE_COMMON_H */ diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 5fd38ff..95380a2 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -93,8 +93,6 @@ struct core_ops { 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 */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index e2b60cc..2b9a742 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -2936,41 +2936,6 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *const osi_core) (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 <<RM_08, (sequence diagram)>> 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 * @@ -6593,7 +6558,7 @@ static int eqos_pre_pad_calibrate(struct osi_core_priv_data *const osi_core) return ret; error: /* roll back on fail */ - eqos_start_mac(osi_core); + hw_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); @@ -6658,7 +6623,7 @@ static nve32_t eqos_post_pad_calibrate( /* do nothing */ } } - eqos_start_mac(osi_core); + hw_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 + @@ -6808,7 +6773,6 @@ void eqos_init_core_ops(struct core_ops *ops) { 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; diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index dafd92e..a707b54 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -4319,32 +4319,6 @@ static nve32_t mgbe_pad_calibrate(OSI_UNUSED 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 * @@ -6159,7 +6133,6 @@ void mgbe_init_core_ops(struct core_ops *ops) 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 */ diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 26466b3..09ca1ca 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -276,7 +276,7 @@ nve32_t osi_start_mac(struct osi_core_priv_data *const osi_core) return -1; } - l_core->ops_p->start_mac(osi_core); + hw_start_mac(osi_core); return 0; } @@ -1975,7 +1975,7 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, break; case OSI_CMD_START_MAC: - ops_p->start_mac(osi_core); + hw_start_mac(osi_core); ret = 0; break; From d46911c3037950257b7f79f18d7d4991633c0b70 Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Thu, 30 Jun 2022 18:56:45 +0000 Subject: [PATCH 371/458] osi: core: combine stop_mac Bug 3701869 Change-Id: I27a16c3f7c088be815b36d416ae068b5e60db143 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2738006 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/core_common.c | 17 +++++++++++++++++ osi/core/core_common.h | 1 + osi/core/core_local.h | 2 -- osi/core/eqos_core.c | 41 +++-------------------------------------- osi/core/mgbe_core.c | 28 +--------------------------- osi/core/osi_hal.c | 4 ++-- 6 files changed, 24 insertions(+), 69 deletions(-) diff --git a/osi/core/core_common.c b/osi/core/core_common.c index fce2fb6..5d19a57 100644 --- a/osi/core/core_common.c +++ b/osi/core/core_common.c @@ -85,6 +85,23 @@ void hw_start_mac(struct osi_core_priv_data *const osi_core) osi_writela(osi_core, value, ((nveu8_t *)addr + mac_mcr_re_reg[osi_core->mac])); } +void hw_stop_mac(struct osi_core_priv_data *const osi_core) +{ + void *addr = osi_core->base; + nveu32_t value; + const nveu32_t mac_mcr_te_reg[2] = { EQOS_MAC_MCR, MGBE_MAC_TMCR }; + const nveu32_t mac_mcr_re_reg[2] = { EQOS_MAC_MCR, MGBE_MAC_RMCR }; + const nveu32_t clear_bit_te[2] = { EQOS_MCR_TE, MGBE_MAC_TMCR_TE }; + const nveu32_t clear_bit_re[2] = { EQOS_MCR_RE, MGBE_MAC_RMCR_RE }; + + value = osi_readla(osi_core, ((nveu8_t *)addr + mac_mcr_te_reg[osi_core->mac])); + value &= ~clear_bit_te[osi_core->mac]; + osi_writela(osi_core, value, ((nveu8_t *)addr + mac_mcr_te_reg[osi_core->mac])); + + value = osi_readla(osi_core, ((nveu8_t *)addr + mac_mcr_re_reg[osi_core->mac])); + value &= ~clear_bit_re[osi_core->mac]; + osi_writela(osi_core, value, ((nveu8_t *)addr + mac_mcr_re_reg[osi_core->mac])); +} /** * @brief hw_est_read - indirect read the GCL to Software own list diff --git a/osi/core/core_common.h b/osi/core/core_common.h index fe9fe1c..1ae84e6 100644 --- a/osi/core/core_common.h +++ b/osi/core/core_common.h @@ -61,4 +61,5 @@ nve32_t gcl_validate(struct osi_core_priv_data *const osi_core, const nveu32_t *btr, nveu32_t mac); nve32_t hw_poll_for_swr(struct osi_core_priv_data *const osi_core); void hw_start_mac(struct osi_core_priv_data *const osi_core); +void hw_stop_mac(struct osi_core_priv_data *const osi_core); #endif /* INCLUDED_CORE_COMMON_H */ diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 95380a2..c52715f 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -93,8 +93,6 @@ struct core_ops { 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 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) */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 2b9a742..76914cd 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -2936,40 +2936,6 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *const osi_core) (unsigned char *)base + EQOS_MTL_RXP_INTR_CS); } -/** - * @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 <<RM_07, (sequence diagram)>> 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 @@ -4758,7 +4724,7 @@ static void eqos_config_ssir(struct osi_core_priv_data *const osi_core, * * @note * Algorithm: - * - This function calls eqos_stop_mac() + * - This function calls hw_stop_mac() * - TraceId:ETHERNET_NVETHERNETRM_007 * * @param[in] osi_core: OSI core private data structure. Used param is base. @@ -4774,7 +4740,7 @@ static void eqos_config_ssir(struct osi_core_priv_data *const osi_core, 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); + hw_stop_mac(osi_core); } /** @@ -6534,7 +6500,7 @@ static int eqos_pre_pad_calibrate(struct osi_core_priv_data *const osi_core) 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); + hw_stop_mac(osi_core); ret = poll_for_mii_idle(osi_core); if (ret < 0) { goto error; @@ -6773,7 +6739,6 @@ void eqos_init_core_ops(struct core_ops *ops) { ops->core_init = eqos_core_init; ops->core_deinit = eqos_core_deinit; - 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; diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index a707b54..7f28d00 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -4319,31 +4319,6 @@ static nve32_t mgbe_pad_calibrate(OSI_UNUSED return 0; } -/** - * @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 @@ -4387,7 +4362,7 @@ static void mgbe_config_mac_tx(struct osi_core_priv_data *const osi_core, static void mgbe_core_deinit(struct osi_core_priv_data *const osi_core) { /* Stop the MAC by disabling both MAC Tx and Rx */ - mgbe_stop_mac(osi_core); + hw_stop_mac(osi_core); } /** @@ -6133,7 +6108,6 @@ void mgbe_init_core_ops(struct core_ops *ops) ops->core_init = mgbe_core_init; ops->core_deinit = mgbe_core_deinit; ops->validate_regs = mgbe_validate_core_regs; - 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; diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 09ca1ca..03be6a3 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -289,7 +289,7 @@ nve32_t osi_stop_mac(struct osi_core_priv_data *const osi_core) return -1; } - l_core->ops_p->stop_mac(osi_core); + hw_stop_mac(osi_core); return 0; } @@ -1980,7 +1980,7 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, break; case OSI_CMD_STOP_MAC: - ops_p->stop_mac(osi_core); + hw_stop_mac(osi_core); ret = 0; break; From c6e8224be62aa9688e36f98486532aeb47505449 Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Thu, 30 Jun 2022 19:31:45 +0000 Subject: [PATCH 372/458] osi: core: combine set_mode Bug 3701869 Change-Id: I01d8e45b5818277441775d17e332c246ffa13a0e Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2738021 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/core_common.c | 26 +++++++++++++++++++ osi/core/core_common.h | 1 + osi/core/core_local.h | 3 --- osi/core/eqos_core.c | 59 +++--------------------------------------- osi/core/mgbe_core.c | 22 ---------------- osi/core/osi_hal.c | 4 +-- 6 files changed, 32 insertions(+), 83 deletions(-) diff --git a/osi/core/core_common.c b/osi/core/core_common.c index 5d19a57..49715b0 100644 --- a/osi/core/core_common.c +++ b/osi/core/core_common.c @@ -103,6 +103,32 @@ void hw_stop_mac(struct osi_core_priv_data *const osi_core) osi_writela(osi_core, value, ((nveu8_t *)addr + mac_mcr_re_reg[osi_core->mac])); } +nve32_t hw_set_mode(struct osi_core_priv_data *const osi_core, const nve32_t mode) +{ + void *base = osi_core->base; + nveu32_t mcr_val; + nve32_t ret = 0; + const nveu32_t set_bit[2] = { EQOS_MCR_DO, EQOS_MCR_DM }; + const nveu32_t clear_bit[2] = { EQOS_MCR_DM, EQOS_MCR_DO }; + + /* don't allow only if loopback mode is other than 0 or 1 */ + if ((mode != OSI_FULL_DUPLEX) && (mode != OSI_HALF_DUPLEX)) { + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + "Invalid duplex mode\n", 0ULL); + ret = -1; + goto fail; + } + + if (osi_core->mac == OSI_MAC_HW_EQOS) { + mcr_val = osi_readla(osi_core, (nveu8_t *)base + EQOS_MAC_MCR); + mcr_val |= set_bit[mode]; + mcr_val &= ~clear_bit[mode]; + osi_writela(osi_core, mcr_val, ((nveu8_t *)base + EQOS_MAC_MCR)); + } +fail: + return ret; +} + /** * @brief hw_est_read - indirect read the GCL to Software own list * (SWOL) diff --git a/osi/core/core_common.h b/osi/core/core_common.h index 1ae84e6..268a094 100644 --- a/osi/core/core_common.h +++ b/osi/core/core_common.h @@ -62,4 +62,5 @@ nve32_t gcl_validate(struct osi_core_priv_data *const osi_core, nve32_t hw_poll_for_swr(struct osi_core_priv_data *const osi_core); void hw_start_mac(struct osi_core_priv_data *const osi_core); void hw_stop_mac(struct osi_core_priv_data *const osi_core); +nve32_t hw_set_mode(struct osi_core_priv_data *const osi_core, const nve32_t mode); #endif /* INCLUDED_CORE_COMMON_H */ diff --git a/osi/core/core_local.h b/osi/core/core_local.h index c52715f..e82d1b2 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -95,9 +95,6 @@ struct core_ops { void (*core_deinit)(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); diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 76914cd..008323c 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -606,58 +606,6 @@ static int eqos_set_speed(struct osi_core_priv_data *const osi_core, 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 <<RM_11, (sequence diagram)>> 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 * @@ -2437,7 +2385,7 @@ static void eqos_handle_mac_fpe_intrs(struct osi_core_priv_data *osi_core) * - 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. + * eqos_set_speed(), hw_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. @@ -2514,13 +2462,13 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, /* 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); + ret = hw_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); + ret = hw_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); @@ -6740,7 +6688,6 @@ void eqos_init_core_ops(struct core_ops *ops) ops->core_init = eqos_core_init; ops->core_deinit = eqos_core_deinit; 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; diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 7f28d00..f337588 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -5816,26 +5816,6 @@ static void mgbe_config_ssir(struct osi_core_priv_data *const osi_core, } } -/** - * @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 * @@ -6109,8 +6089,6 @@ void mgbe_init_core_ops(struct core_ops *ops) ops->core_deinit = mgbe_core_deinit; ops->validate_regs = mgbe_validate_core_regs; 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; diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 03be6a3..e81f4c1 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -316,7 +316,7 @@ nve32_t osi_set_mode(struct osi_core_priv_data *const osi_core, return -1; } - return l_core->ops_p->set_mode(osi_core, mode); + return hw_set_mode(osi_core, mode); } nve32_t osi_set_speed(struct osi_core_priv_data *const osi_core, @@ -2003,7 +2003,7 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, break; case OSI_CMD_SET_MODE: - ret = ops_p->set_mode(osi_core, data->arg6_32); + ret = hw_set_mode(osi_core, data->arg6_32); break; case OSI_CMD_SET_SPEED: From 2d2b1058c4f816066103dea125467a1e47cdfb74 Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Thu, 30 Jun 2022 20:57:51 +0000 Subject: [PATCH 373/458] osi: core: combine set_speed Bug 3701869 Change-Id: Ie41b31e94f0ec0fb0b8d2d52cca7fafa81fd54c2 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2738062 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/core_common.c | 68 ++++++++++++++++++++++++++++++++++++++ osi/core/core_common.h | 1 + osi/core/core_local.h | 3 -- osi/core/eqos_core.c | 75 +++--------------------------------------- osi/core/mgbe_core.c | 49 --------------------------- osi/core/osi_hal.c | 4 +-- 6 files changed, 75 insertions(+), 125 deletions(-) diff --git a/osi/core/core_common.c b/osi/core/core_common.c index 49715b0..8b93162 100644 --- a/osi/core/core_common.c +++ b/osi/core/core_common.c @@ -24,6 +24,7 @@ #include "core_common.h" #include "mgbe_core.h" #include "eqos_core.h" +#include "xpcs.h" static inline nve32_t poll_check(struct osi_core_priv_data *const osi_core, nveu8_t *addr, nveu32_t bit_check, nveu32_t *value) @@ -129,6 +130,73 @@ fail: return ret; } +nve32_t hw_set_speed(struct osi_core_priv_data *const osi_core, const nve32_t speed) +{ + nveu32_t value; + nve32_t ret = 0; + void *base = osi_core->base; + const nveu32_t mac_mcr[2] = { EQOS_MAC_MCR, MGBE_MAC_TMCR }; + + if ((osi_core->mac == OSI_MAC_HW_EQOS && speed > OSI_SPEED_1000) || + (osi_core->mac == OSI_MAC_HW_MGBE && (speed < OSI_SPEED_2500 || + speed > OSI_SPEED_10000))) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "unsupported speed\n", (nveul64_t)speed); + ret = -1; + goto fail; + } + + value = osi_readla(osi_core, ((nveu8_t *)base + mac_mcr[osi_core->mac])); + switch (speed) { + default: + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "unsupported speed\n", (nveul64_t)speed); + ret = -1; + goto fail; + case OSI_SPEED_10: + value |= EQOS_MCR_PS; + value &= ~EQOS_MCR_FES; + break; + case OSI_SPEED_100: + value |= EQOS_MCR_PS; + value |= EQOS_MCR_FES; + break; + case OSI_SPEED_1000: + value &= ~EQOS_MCR_PS; + value &= ~EQOS_MCR_FES; + break; + 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; + + } + osi_writela(osi_core, value, ((nveu8_t *)osi_core->base + mac_mcr[osi_core->mac])); + + if (osi_core->mac == OSI_MAC_HW_MGBE) { + if (xpcs_init(osi_core) < 0) { + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + "xpcs_init failed\n", OSI_NONE); + ret = -1; + goto fail; + } + + ret = xpcs_start(osi_core); + if (ret < 0) { + goto fail; + } + } +fail: + return ret; +} + + + /** * @brief hw_est_read - indirect read the GCL to Software own list * (SWOL) diff --git a/osi/core/core_common.h b/osi/core/core_common.h index 268a094..3dd0efa 100644 --- a/osi/core/core_common.h +++ b/osi/core/core_common.h @@ -63,4 +63,5 @@ nve32_t hw_poll_for_swr(struct osi_core_priv_data *const osi_core); void hw_start_mac(struct osi_core_priv_data *const osi_core); void hw_stop_mac(struct osi_core_priv_data *const osi_core); nve32_t hw_set_mode(struct osi_core_priv_data *const osi_core, const nve32_t mode); +nve32_t hw_set_speed(struct osi_core_priv_data *const osi_core, const nve32_t speed); #endif /* INCLUDED_CORE_COMMON_H */ diff --git a/osi/core/core_local.h b/osi/core/core_local.h index e82d1b2..8dc99af 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -95,9 +95,6 @@ struct core_ops { void (*core_deinit)(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 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 */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 008323c..f0fd3b4 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -552,60 +552,6 @@ static nve32_t eqos_config_fw_err_pkts( 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 <<RM_12, (sequence diagram)>> 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_calculate_per_queue_fifo - Calculate per queue FIFO size * @@ -2385,7 +2331,7 @@ static void eqos_handle_mac_fpe_intrs(struct osi_core_priv_data *osi_core) * - 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(), hw_set_mode()(proceed even on error for this call) API's. + * hw_set_speed(), hw_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. @@ -2479,25 +2425,13 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, /* 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) { - ret = eqos_set_speed(osi_core, OSI_SPEED_10); - if (osi_unlikely(ret < 0)) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "set speed in 10Mbps failed\n", 0ULL); - } + hw_set_speed(osi_core, OSI_SPEED_10); } else if ((mac_pcs & EQOS_MAC_PCS_LNKSPEED) == EQOS_MAC_PCS_LNKSPEED_100) { - ret = eqos_set_speed(osi_core, OSI_SPEED_100); - if (osi_unlikely(ret < 0)) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "set speed in 100Mbps failed\n", 0ULL); - } + hw_set_speed(osi_core, OSI_SPEED_100); } else if ((mac_pcs & EQOS_MAC_PCS_LNKSPEED) == EQOS_MAC_PCS_LNKSPEED_1000) { - ret = eqos_set_speed(osi_core, OSI_SPEED_1000); - if (osi_unlikely(ret < 0)) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "set speed in 1000Mbps failed\n", 0ULL); - } + hw_set_speed(osi_core, OSI_SPEED_1000); } else { /* Nothing here */ } @@ -6688,7 +6622,6 @@ void eqos_init_core_ops(struct core_ops *ops) ops->core_init = eqos_core_init; ops->core_deinit = eqos_core_deinit; ops->handle_common_intr = eqos_handle_common_intr; - 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; diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index f337588..ef820f5 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -4365,53 +4365,6 @@ static void mgbe_core_deinit(struct osi_core_priv_data *const osi_core) hw_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 * @@ -6089,8 +6042,6 @@ void mgbe_init_core_ops(struct core_ops *ops) ops->core_deinit = mgbe_core_deinit; ops->validate_regs = mgbe_validate_core_regs; ops->handle_common_intr = mgbe_handle_common_intr; - /* 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; diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index e81f4c1..3f40b08 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -328,7 +328,7 @@ nve32_t osi_set_speed(struct osi_core_priv_data *const osi_core, return -1; } - return l_core->ops_p->set_speed(osi_core, speed); + return hw_set_speed(osi_core, speed); } nve32_t osi_pad_calibrate(struct osi_core_priv_data *const osi_core) @@ -2007,7 +2007,7 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, break; case OSI_CMD_SET_SPEED: - ret = ops_p->set_speed(osi_core, data->arg6_32); + ret = hw_set_speed(osi_core, data->arg6_32); break; case OSI_CMD_L2_FILTER: From 43cd5b0da27c3738575a165c0fc8aa7f64c811b6 Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Sun, 3 Jul 2022 20:08:37 +0000 Subject: [PATCH 374/458] osi: core: combine flush_mtl_tx_queue Bug 3701869 Change-Id: Ifea025c0eb2d4373a348283aaa93eb7d0eca193a Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2739121 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/core_common.c | 18 ++++++++++ osi/core/core_common.h | 3 ++ osi/core/core_local.h | 3 -- osi/core/eqos_core.c | 78 +----------------------------------------- osi/core/eqos_core.h | 2 -- osi/core/mgbe_core.c | 57 +----------------------------- osi/core/mgbe_core.h | 2 -- 7 files changed, 23 insertions(+), 140 deletions(-) diff --git a/osi/core/core_common.c b/osi/core/core_common.c index 8b93162..c79e39e 100644 --- a/osi/core/core_common.c +++ b/osi/core/core_common.c @@ -196,6 +196,24 @@ fail: } +nve32_t hw_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, + const nveu32_t qinx) +{ + void *addr = osi_core->base; + nveu32_t tx_op_mode_val = 0U; + nveu32_t value; + const nveu32_t tx_op_mode[2] = { EQOS_MTL_CHX_TX_OP_MODE(qinx), + MGBE_MTL_CHX_TX_OP_MODE(qinx)}; + + /* Read Tx Q Operating Mode Register and flush TxQ */ + value = osi_readla(osi_core, ((nveu8_t *)addr + tx_op_mode[osi_core->mac])); + value |= MTL_QTOMR_FTQ; + osi_writela(osi_core, value, ((nveu8_t *)addr + tx_op_mode[osi_core->mac])); + + /* Poll Until FTQ bit resets for Successful Tx Q flush */ + return poll_check(osi_core, ((nveu8_t *)addr + tx_op_mode[osi_core->mac]), + MTL_QTOMR_FTQ, &tx_op_mode_val); +} /** * @brief hw_est_read - indirect read the GCL to Software own list diff --git a/osi/core/core_common.h b/osi/core/core_common.h index 3dd0efa..c0c7185 100644 --- a/osi/core/core_common.h +++ b/osi/core/core_common.h @@ -39,6 +39,7 @@ #define MTL_EST_CONTROL_EEST OSI_BIT(0) #define MTL_EST_STATUS_SWOL OSI_BIT(7) #define DMA_MODE_SWR OSI_BIT(0) +#define MTL_QTOMR_FTQ OSI_BIT(0) /** * @addtogroup typedef related info @@ -64,4 +65,6 @@ void hw_start_mac(struct osi_core_priv_data *const osi_core); void hw_stop_mac(struct osi_core_priv_data *const osi_core); nve32_t hw_set_mode(struct osi_core_priv_data *const osi_core, const nve32_t mode); nve32_t hw_set_speed(struct osi_core_priv_data *const osi_core, const nve32_t speed); +nve32_t hw_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, + const nveu32_t qinx); #endif /* INCLUDED_CORE_COMMON_H */ diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 8dc99af..f5983c7 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -203,9 +203,6 @@ struct core_ops { /** 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); diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index f0fd3b4..b4d95bd 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -857,81 +857,6 @@ calibration_failed: } #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 * @@ -1080,7 +1005,7 @@ static nve32_t eqos_configure_mtl_queue(nveu32_t qinx, nveu32_t value = 0; nve32_t ret = 0; - ret = eqos_flush_mtl_tx_queue(osi_core, qinx); + ret = hw_flush_mtl_tx_queue(osi_core, qinx); if (ret < 0) { return ret; } @@ -6655,7 +6580,6 @@ void eqos_init_core_ops(struct core_ops *ops) 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; diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 7c46457..55cbf42 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -228,7 +228,6 @@ #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) @@ -280,7 +279,6 @@ #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) diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index ef820f5..65b7159 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -1637,60 +1637,6 @@ static int mgbe_config_ptp_rxq(struct osi_core_priv_data *const osi_core, 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 * @@ -2266,7 +2212,7 @@ static nve32_t mgbe_configure_mtl_queue(nveu32_t qinx, * Setting related to CBS will come here for TC. * default: 0x0 SP */ - ret = mgbe_flush_mtl_tx_queue(osi_core, qinx); + ret = hw_flush_mtl_tx_queue(osi_core, qinx); if (ret < 0) { return ret; } @@ -6044,7 +5990,6 @@ void mgbe_init_core_ops(struct core_ops *ops) ops->handle_common_intr = mgbe_handle_common_intr; 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, diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 4e0405c..9676fc4 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -385,8 +385,6 @@ #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) From bd4c50decfadefcaaf4361bbb704c509349e1905 Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Sun, 3 Jul 2022 20:39:32 +0000 Subject: [PATCH 375/458] osi: core: combine config_fw_err_pkts Bug 3701869 Change-Id: I5a0fe6e24d8aa69054a18f927d7135552482e8b9 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2739131 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_core.h | 36 --------------------- osi/core/core_common.c | 44 ++++++++++++++++++++++++++ osi/core/core_common.h | 3 ++ osi/core/core_local.h | 4 --- osi/core/eqos_core.c | 71 ------------------------------------------ osi/core/eqos_core.h | 2 -- osi/core/mgbe_core.c | 60 ----------------------------------- osi/core/mgbe_core.h | 1 - osi/core/osi_hal.c | 16 +--------- 9 files changed, 48 insertions(+), 189 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 87d61dd..c73304e 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -1781,42 +1781,6 @@ nve32_t osi_set_speed(struct osi_core_priv_data *const osi_core, */ 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. * diff --git a/osi/core/core_common.c b/osi/core/core_common.c index c79e39e..aa9aef1 100644 --- a/osi/core/core_common.c +++ b/osi/core/core_common.c @@ -215,6 +215,50 @@ nve32_t hw_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, MTL_QTOMR_FTQ, &tx_op_mode_val); } +nve32_t hw_config_fw_err_pkts(struct osi_core_priv_data *osi_core, + const nveu32_t qinx, const nveu32_t enable_fw_err_pkts) +{ + nveu32_t val; + nve32_t ret = 0; + const nveu32_t rx_op_mode[2] = { EQOS_MTL_CHX_RX_OP_MODE(qinx), + MGBE_MTL_CHX_RX_OP_MODE(qinx)}; + const nveu32_t max_q[2] = { OSI_EQOS_MAX_NUM_QUEUES, + OSI_MGBE_MAX_NUM_QUEUES}; + + /* Check for valid enable_fw_err_pkts and qinx values */ + if ((enable_fw_err_pkts != OSI_ENABLE && + enable_fw_err_pkts != OSI_DISABLE) || + (qinx >= max_q[osi_core->mac])) { + ret = -1; + goto fail; + } + + /* Read MTL RXQ Operation_Mode Register */ + val = osi_readla(osi_core, ((nveu8_t *)osi_core->base + + rx_op_mode[osi_core->mac])); + + /* 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 |= 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 &= ~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, ((nveu8_t *)osi_core->base + + rx_op_mode[osi_core->mac])); +fail: + return ret; +} /** * @brief hw_est_read - indirect read the GCL to Software own list * (SWOL) diff --git a/osi/core/core_common.h b/osi/core/core_common.h index c0c7185..b0b00e6 100644 --- a/osi/core/core_common.h +++ b/osi/core/core_common.h @@ -40,6 +40,7 @@ #define MTL_EST_STATUS_SWOL OSI_BIT(7) #define DMA_MODE_SWR OSI_BIT(0) #define MTL_QTOMR_FTQ OSI_BIT(0) +#define MTL_RXQ_OP_MODE_FEP OSI_BIT(4) /** * @addtogroup typedef related info @@ -67,4 +68,6 @@ nve32_t hw_set_mode(struct osi_core_priv_data *const osi_core, const nve32_t mod nve32_t hw_set_speed(struct osi_core_priv_data *const osi_core, const nve32_t speed); nve32_t hw_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, const nveu32_t qinx); +nve32_t hw_config_fw_err_pkts(struct osi_core_priv_data *osi_core, + const nveu32_t qinx, const nveu32_t enable_fw_err_pkts); #endif /* INCLUDED_CORE_COMMON_H */ diff --git a/osi/core/core_local.h b/osi/core/core_local.h index f5983c7..357d030 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -97,10 +97,6 @@ struct core_ops { void (*handle_common_intr)(struct osi_core_priv_data *const osi_core); /** 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, diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index b4d95bd..011e965 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -482,76 +482,6 @@ static nve32_t eqos_config_flow_control( 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 <<RM_20, (sequence diagram)>> 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_calculate_per_queue_fifo - Calculate per queue FIFO size * @@ -6548,7 +6478,6 @@ void eqos_init_core_ops(struct core_ops *ops) ops->core_deinit = eqos_core_deinit; ops->handle_common_intr = eqos_handle_common_intr; 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; diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 55cbf42..3d1eee7 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -319,7 +319,6 @@ #define EQOS_MAC_VLAN_TR_VTHM OSI_BIT(25) #define EQOS_MAC_STNSR_TSSS_MASK 0x7FFFFFFFU #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) @@ -329,7 +328,6 @@ #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 diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 65b7159..9d8b114 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -96,65 +96,6 @@ 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 nve32_t mgbe_config_fw_err_pkts(struct osi_core_priv_data *const osi_core, - const nveu32_t qinx, - const nveu32_t 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_calculate_per_queue_fifo - Calculate per queue FIFO size * @@ -5993,7 +5934,6 @@ void mgbe_init_core_ops(struct core_ops *ops) 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; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 9676fc4..3069dca 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -534,7 +534,6 @@ #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) diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 3f40b08..ee2bccf 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -342,19 +342,6 @@ nve32_t osi_pad_calibrate(struct osi_core_priv_data *const osi_core) 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 *)(void *)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) { @@ -1943,8 +1930,7 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, break; case OSI_CMD_CONFIG_FW_ERR: - ret = ops_p->config_fw_err_pkts(osi_core, data->arg1_u32, - data->arg2_u32); + ret = hw_config_fw_err_pkts(osi_core, data->arg1_u32, data->arg2_u32); break; case OSI_CMD_ARP_OFFLOAD: From 82db6f563b6993c3ba85698a78ca7b759168099d Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Sun, 3 Jul 2022 21:25:25 +0000 Subject: [PATCH 376/458] osi: core: combine config_rxcsum_offload Bug 3701869 Change-Id: I802497b6f973c69b994373697251964e532243f7 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2739139 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/core_common.c | 28 +++++++++++++++++++++ osi/core/core_common.h | 3 +++ osi/core/core_local.h | 4 --- osi/core/eqos_core.c | 56 ------------------------------------------ osi/core/mgbe_core.c | 40 ------------------------------ osi/core/osi_hal.c | 6 ++--- 6 files changed, 34 insertions(+), 103 deletions(-) diff --git a/osi/core/core_common.c b/osi/core/core_common.c index aa9aef1..b9693dc 100644 --- a/osi/core/core_common.c +++ b/osi/core/core_common.c @@ -259,6 +259,34 @@ nve32_t hw_config_fw_err_pkts(struct osi_core_priv_data *osi_core, fail: return ret; } + +nve32_t hw_config_rxcsum_offload(struct osi_core_priv_data *const osi_core, + nveu32_t enabled) +{ + void *addr = osi_core->base; + nveu32_t value; + nve32_t ret = 0; + const nveu32_t rxcsum_mode[2] = { EQOS_MAC_MCR, MGBE_MAC_RMCR}; + const nveu32_t ipc_value[2] = { EQOS_MCR_IPC, MGBE_MAC_RMCR_IPC}; + + if (enabled != OSI_ENABLE && enabled != OSI_DISABLE) { + ret = -1; + goto fail; + } + + value = osi_readla(osi_core, ((nveu8_t *)addr + rxcsum_mode[osi_core->mac])); + if (enabled == OSI_ENABLE) { + value |= ipc_value[osi_core->mac]; + } else { + value &= ~ipc_value[osi_core->mac]; + } + + osi_writela(osi_core, value, ((nveu8_t *)addr + rxcsum_mode[osi_core->mac])); +fail: + return ret; +} + + /** * @brief hw_est_read - indirect read the GCL to Software own list * (SWOL) diff --git a/osi/core/core_common.h b/osi/core/core_common.h index b0b00e6..62df704 100644 --- a/osi/core/core_common.h +++ b/osi/core/core_common.h @@ -70,4 +70,7 @@ nve32_t hw_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, const nveu32_t qinx); nve32_t hw_config_fw_err_pkts(struct osi_core_priv_data *osi_core, const nveu32_t qinx, const nveu32_t enable_fw_err_pkts); +nve32_t hw_config_rxcsum_offload(struct osi_core_priv_data *const osi_core, + nveu32_t enabled); + #endif /* INCLUDED_CORE_COMMON_H */ diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 357d030..4bf7547 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -97,10 +97,6 @@ struct core_ops { void (*handle_common_intr)(struct osi_core_priv_data *const osi_core); /** Called to do pad caliberation */ nve32_t (*pad_calibrate)(struct osi_core_priv_data *const osi_core); - /** 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, diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 011e965..845d9bb 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -984,61 +984,6 @@ static nve32_t eqos_configure_mtl_queue(nveu32_t qinx, } /** \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 <<RM_17, (sequence diagram)>> 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 * @@ -6478,7 +6423,6 @@ void eqos_init_core_ops(struct core_ops *ops) ops->core_deinit = eqos_core_deinit; ops->handle_common_intr = eqos_handle_common_intr; ops->pad_calibrate = eqos_pad_calibrate; - 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; diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 9d8b114..a9e40af 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -1668,45 +1668,6 @@ static int mgbe_config_arp_offload(struct osi_core_priv_data *const osi_core, 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 nve32_t mgbe_config_rxcsum_offload( - struct osi_core_priv_data *const osi_core, - nveu32_t 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 * @@ -5939,7 +5900,6 @@ void mgbe_init_core_ops(struct core_ops *ops) 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; diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index ee2bccf..44f3f65 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -629,7 +629,7 @@ nve32_t osi_config_rxcsum_offload(struct osi_core_priv_data *const osi_core, return -1; } - return l_core->ops_p->config_rxcsum_offload(osi_core, enable); + return hw_config_rxcsum_offload(osi_core, enable); } nve32_t osi_set_systime_to_mac(struct osi_core_priv_data *const osi_core, @@ -1702,7 +1702,7 @@ static void cfg_l2_filter(struct core_local *l_core) static void cfg_rxcsum(struct core_local *l_core) { - (void)l_core->ops_p->config_rxcsum_offload((struct osi_core_priv_data *)(void *)l_core, + (void)hw_config_rxcsum_offload((struct osi_core_priv_data *)(void *)l_core, l_core->cfg.rxcsum); } @@ -2006,7 +2006,7 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, break; case OSI_CMD_RXCSUM_OFFLOAD: - ret = ops_p->config_rxcsum_offload(osi_core, data->arg1_u32); + ret = hw_config_rxcsum_offload(osi_core, data->arg1_u32); if (ret == 0) { l_core->cfg.rxcsum = data->arg1_u32; l_core->cfg.flags |= DYNAMIC_CFG_RXCSUM; From 21937b85dd9cfe9c95c27e60874c10f59507014b Mon Sep 17 00:00:00 2001 From: Sanath Kumar Gampa <sgampa@nvidia.com> Date: Fri, 1 Jul 2022 08:59:31 +0530 Subject: [PATCH 377/458] osi: macsec API cleanup Bug 3709820 Change-Id: I935ca2d373bea1b7d8b15f790ffc3719fa9d0881 Signed-off-by: Sanath Kumar Gampa <sgampa@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2738227 Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/ivc_core.h | 4 +- include/osi_macsec.h | 53 ++---- osi/core/Makefile.interface.tmk | 4 + osi/core/Makefile.tmk | 2 +- osi/core/ivc_core.c | 57 ++----- osi/core/libnvethernetrm.export | 7 +- osi/core/libnvethernetrm_debug.export | 47 +++++ osi/core/macsec.c | 237 +++++++++++--------------- osi/core/macsec.h | 45 ++--- osi/core/osi_hal.c | 9 +- 10 files changed, 214 insertions(+), 251 deletions(-) create mode 100644 osi/core/libnvethernetrm_debug.export diff --git a/include/ivc_core.h b/include/ivc_core.h index 88900fe..e977dd4 100644 --- a/include/ivc_core.h +++ b/include/ivc_core.h @@ -46,8 +46,7 @@ typedef enum ivc_cmd { handle_ioctl, init_macsec, deinit_macsec, - handle_ns_irq_macsec, - handle_s_irq_macsec, + handle_irq_macsec, lut_config_macsec, kt_config_macsec, cipher_config, @@ -58,7 +57,6 @@ typedef enum ivc_cmd { dbg_buf_config_macsec, dbg_events_config_macsec, macsec_get_sc_lut_key_index, - macsec_update_mtu_size, nvethmgr_get_status, nvethmgr_verify_ts, nvethmgr_get_avb_perf, diff --git a/include/osi_macsec.h b/include/osi_macsec.h index 5ac81d7..99f10f8 100644 --- a/include/osi_macsec.h +++ b/include/osi_macsec.h @@ -332,10 +332,8 @@ struct osi_macsec_core_ops { 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 irq handler */ + void (*handle_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); @@ -347,9 +345,11 @@ struct osi_macsec_core_ops { /** macsec cipher config */ nve32_t (*cipher_config)(struct osi_core_priv_data *const osi_core, nveu32_t cipher); +#ifdef DEBUG_MACSEC /** macsec loopback config */ nve32_t (*loopback_config)(struct osi_core_priv_data *const osi_core, nveu32_t enable); +#endif /* DEBUG_MACSEC */ /** macsec enable */ nve32_t (*macsec_en)(struct osi_core_priv_data *const osi_core, nveu32_t enable); @@ -360,21 +360,24 @@ struct osi_macsec_core_ops { nveu16_t *kt_idx); /** macsec read mmc counters */ void (*read_mmc)(struct osi_core_priv_data *const osi_core); +#ifdef DEBUG_MACSEC /** 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); +#endif /* DEBUG_MACSEC */ /** 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); -#ifdef OSI_DEBUG - void (*debug_intr_config)(struct osi_core_priv_data *const osi_core, nveu32_t enable); -#endif +#ifdef DEBUG_MACSEC + /** macsec interrupts configuration */ + void (*intr_config)(struct osi_core_priv_data *const osi_core, nveu32_t enable); +#endif /* DEBUG_MACSEC */ }; ////////////////////////////////////////////////////////////////////////// @@ -462,12 +465,12 @@ nve32_t osi_macsec_init(struct osi_core_priv_data *const osi_core, nve32_t osi_macsec_deinit(struct osi_core_priv_data *const osi_core); /** - * @brief osi_macsec_ns_isr - macsec non-secure irq handler + * @brief osi_macsec_isr - macsec irq handler * * @note * Algorithm: * - Return -1 if osi core or ops is null - * - handles non-secure macsec interrupts + * - handles macsec interrupts * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. * - TraceID: *********** * @@ -483,31 +486,7 @@ nve32_t osi_macsec_deinit(struct osi_core_priv_data *const osi_core); * * @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); +void osi_macsec_isr(struct osi_core_priv_data *const osi_core); /** * @brief osi_macsec_config_lut - Read or write to macsec LUTs @@ -592,6 +571,7 @@ nve32_t osi_macsec_config_kt(struct osi_core_priv_data *const osi_core, nve32_t osi_macsec_cipher_config(struct osi_core_priv_data *const osi_core, nveu32_t cipher); +#ifdef DEBUG_MACSEC /** * @brief osi_macsec_loopback - API to enable/disable macsec loopback * @@ -616,8 +596,10 @@ nve32_t osi_macsec_cipher_config(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure */ + nve32_t osi_macsec_loopback(struct osi_core_priv_data *const osi_core, nveu32_t enable); +#endif /* DEBUG_MACSEC */ /** * @brief osi_macsec_en - API to enable/disable macsec @@ -704,6 +686,7 @@ nve32_t osi_macsec_config(struct osi_core_priv_data *const osi_core, */ nve32_t osi_macsec_read_mmc(struct osi_core_priv_data *const osi_core); +#ifdef DEBUG_MACSEC /** * @brief osi_macsec_config_dbg_buf - Reads the debug buffer captured * @@ -759,7 +742,7 @@ nve32_t osi_macsec_config_dbg_buf( 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); - +#endif /* DEBUG_MACSEC */ /** * @brief osi_macsec_get_sc_lut_key_index - API to get key index for a given SCI * diff --git a/osi/core/Makefile.interface.tmk b/osi/core/Makefile.interface.tmk index 4637979..752cfc2 100644 --- a/osi/core/Makefile.interface.tmk +++ b/osi/core/Makefile.interface.tmk @@ -26,7 +26,11 @@ ifdef NV_INTERFACE_FLAG_SHARED_LIBRARY_SECTION NV_INTERFACE_NAME := nvethernetrm +ifeq ($(NV_BUILD_CONFIGURATION_IS_SAFETY),0) +NV_INTERFACE_EXPORTS := lib$(NV_INTERFACE_NAME)_debug +else NV_INTERFACE_EXPORTS := lib$(NV_INTERFACE_NAME) +endif NV_INTERFACE_PUBLIC_INCLUDES := \ ./include endif diff --git a/osi/core/Makefile.tmk b/osi/core/Makefile.tmk index 00ba1cb..9f97df6 100644 --- a/osi/core/Makefile.tmk +++ b/osi/core/Makefile.tmk @@ -48,7 +48,6 @@ NV_COMPONENT_SOURCES := \ $(NV_SOURCE)/nvethernetrm/osi/core/macsec.c NV_COMPONENT_CFLAGS += -DMACSEC_SUPPORT -NV_COMPONENT_CFLAGS += -DDEBUG_MACSEC #NV_COMPONENT_CFLAGS += -DMACSEC_KEY_PROGRAM ifeq ($(NV_BUILD_CONFIGURATION_OS_IS_LINUX),1) @@ -59,6 +58,7 @@ endif ifeq ($(NV_BUILD_CONFIGURATION_IS_SAFETY),0) NV_COMPONENT_CFLAGS += -DOSI_DEBUG +NV_COMPONENT_CFLAGS += -DDEBUG_MACSEC endif NV_COMPONENT_INCLUDES := \ diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index 31bd1e9..ce39fa7 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -190,6 +190,7 @@ static nve32_t ivc_read_phy_reg(struct osi_core_priv_data *const osi_core, } #ifdef MACSEC_SUPPORT +#ifdef DEBUG_MACSEC /** * @brief ivc_macsec_dbg_events_config - Configure Debug events * @@ -261,6 +262,7 @@ static int ivc_macsec_dbg_buf_config( exit: return ret; } +#endif /* DEBUG_MACSEC */ /** * @brief macsec_read_mmc - To read statitics registers and update structure @@ -368,31 +370,6 @@ exit: 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. * @@ -418,6 +395,7 @@ static int ivc_macsec_enable(struct osi_core_priv_data *const osi_core, return osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); } +#ifdef DEBUG_MACSEC /** * @brief ivc_macsec_loopback_config - Loopback configure. * @@ -442,6 +420,7 @@ static int ivc_macsec_loopback_config(struct osi_core_priv_data *const osi_core, return osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); } +#endif /* DEBUG_MACSEC */ #ifdef MACSEC_KEY_PROGRAM /** @@ -537,32 +516,18 @@ exit: } /** - * @brief ivc_macsec_handle_s_irq - handle s irq. + * @brief ivc_macsec_handle_irq - handle macsec irq. * * @param[in] osi_core: OSI Core private data structure. * */ -static void ivc_macsec_handle_s_irq(OSI_UNUSED +static void ivc_macsec_handle_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. * @@ -623,21 +588,21 @@ void ivc_init_macsec_ops(void *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->handle_irq = ivc_macsec_handle_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; +#ifdef DEBUG_MACSEC + ops->loopback_config = ivc_macsec_loopback_config; ops->dbg_events_config = ivc_macsec_dbg_events_config; + ops->dbg_buf_config = ivc_macsec_dbg_buf_config; +#endif /* DEBUG_MACSEC */ ops->get_sc_lut_key_index = ivc_get_sc_lut_key_index; - ops->update_mtu = ivc_macsec_update_mtu; } #endif diff --git a/osi/core/libnvethernetrm.export b/osi/core/libnvethernetrm.export index 28df803..c267b97 100644 --- a/osi/core/libnvethernetrm.export +++ b/osi/core/libnvethernetrm.export @@ -32,18 +32,13 @@ osi_get_core osi_handle_ioctl osi_macsec_en osi_macsec_deinit -osi_macsec_ns_isr -osi_macsec_s_isr +osi_macsec_isr osi_macsec_init osi_macsec_cipher_config osi_macsec_config osi_init_macsec_ops -osi_macsec_loopback osi_macsec_read_mmc -osi_macsec_dbg_events_config -osi_macsec_config_dbg_buf osi_macsec_config_lut osi_macsec_get_sc_lut_key_index -osi_macsec_update_mtu # Enable below if MACSEC_KEY_PROGRAM is enabled #osi_macsec_kt_config diff --git a/osi/core/libnvethernetrm_debug.export b/osi/core/libnvethernetrm_debug.export new file mode 100644 index 0000000..32f526d --- /dev/null +++ b/osi/core/libnvethernetrm_debug.export @@ -0,0 +1,47 @@ +################################### 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 +osi_macsec_en +osi_macsec_deinit +osi_macsec_isr +osi_macsec_init +osi_macsec_cipher_config +osi_macsec_config +osi_init_macsec_ops +osi_macsec_loopback +osi_macsec_read_mmc +osi_macsec_dbg_events_config +osi_macsec_config_dbg_buf +osi_macsec_config_lut +osi_macsec_get_sc_lut_key_index +# Enable below if MACSEC_KEY_PROGRAM is enabled +#osi_macsec_kt_config diff --git a/osi/core/macsec.c b/osi/core/macsec.c index c3dbf21..d92f8f4 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -36,12 +36,13 @@ #include <linux/printk.h> #define LOG(...) \ { \ - pr_err(##__VA_ARGS__); \ + pr_err(__VA_ARGS__); \ } #else #define LOG(...) #endif +#ifdef DEBUG_MACSEC /** * @brief poll_for_dbg_buf_update - Query the status of a debug buffer update. * @@ -649,6 +650,7 @@ static nve32_t macsec_dbg_events_config( err: return ret; } +#endif /* DEBUG_MACSEC */ /** * @brief update_macsec_mmc_val - Reads specific macsec mmc counters @@ -3703,7 +3705,7 @@ static inline void handle_common_irq(struct osi_core_priv_data *const osi_core) } /** - * @brief macsec_handle_ns_irq - Non-secure interrupt handler + * @brief macsec_handle_irq - Macsec interrupt handler * * @note * Algorithm: @@ -3725,7 +3727,7 @@ static inline void handle_common_irq(struct osi_core_priv_data *const osi_core) * - Run time: Yes * - De-initialization: No */ -static void macsec_handle_ns_irq(struct osi_core_priv_data *const osi_core) +static void macsec_handle_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; @@ -3751,38 +3753,6 @@ static void macsec_handle_ns_irq(struct osi_core_priv_data *const 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 * @@ -3833,6 +3803,7 @@ exit: return ret; } +#ifdef DEBUG_MACSEC /** * @brief macsec_loopback_config - Configures the loopback mode * @@ -3879,6 +3850,7 @@ static nve32_t macsec_loopback_config( exit: return ret; } +#endif /* DEBUG_MACSEC */ /** * @brief clear_byp_lut - Clears the bypass lut @@ -4393,6 +4365,81 @@ exit: return ret; } +#ifdef DEBUG_MACSEC +static void macsec_intr_config(struct osi_core_priv_data *const osi_core, nveu32_t enable) +{ + nveu32_t val = 0; + nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; + + if (enable == OSI_ENABLE) { + 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_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); + osi_writela(osi_core, val, addr + MACSEC_TX_IMR); + LOG("Write MACSEC_TX_IMR: 0x%x\n", val); + + 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 | + RX_REPLAY_ERROR_INT_EN | + MACSEC_RX_MTU_CHECK_FAIL_INT_EN | + MACSEC_RX_AES_GCM_BUF_OVF_INT_EN | + MACSEC_RX_PN_EXHAUSTED_INT_EN + ); + osi_writela(osi_core, val, addr + MACSEC_RX_IMR); + LOG("Write MACSEC_RX_IMR: 0x%x\n", val); + + val = osi_readla(osi_core, addr + MACSEC_COMMON_IMR); + LOG("Read MACSEC_COMMON_IMR: 0x%x\n", val); + val |= (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 | + MACSEC_SECURE_REG_VIOL_INT_EN); + osi_writela(osi_core, val, addr + MACSEC_COMMON_IMR); + LOG("Write MACSEC_COMMON_IMR: 0x%x\n", val); + } else { + 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_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); + osi_writela(osi_core, val, addr + MACSEC_TX_IMR); + LOG("Write MACSEC_TX_IMR: 0x%x\n", val); + + 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 & + ~RX_REPLAY_ERROR_INT_EN & + ~MACSEC_RX_MTU_CHECK_FAIL_INT_EN & + ~MACSEC_RX_AES_GCM_BUF_OVF_INT_EN & + ~MACSEC_RX_PN_EXHAUSTED_INT_EN + ); + osi_writela(osi_core, val, addr + MACSEC_RX_IMR); + LOG("Write MACSEC_RX_IMR: 0x%x\n", val); + + val = osi_readla(osi_core, addr + MACSEC_COMMON_IMR); + LOG("Read MACSEC_COMMON_IMR: 0x%x\n", val); + val &= (~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 & + ~MACSEC_SECURE_REG_VIOL_INT_EN); + osi_writela(osi_core, val, addr + MACSEC_COMMON_IMR); + LOG("Write MACSEC_COMMON_IMR: 0x%x\n", val); + } +} +#endif /* DEBUG_MACSEC */ + /** * @brief macsec_init - Inititlizes macsec * @@ -4505,7 +4552,7 @@ static nve32_t macsec_init(struct osi_core_priv_data *const osi_core, /* set ICV error threshold to 1 */ osi_writela(osi_core, 1U, addr + MACSEC_RX_ICV_ERR_CNTRL); - + /* Enabling interrupts only related to HSI */ val = osi_readla(osi_core, addr + MACSEC_RX_IMR); LOG("Read MACSEC_RX_IMR: 0x%x\n", val); val |= (MACSEC_RX_ICV_ERROR_INT_EN | @@ -5386,69 +5433,6 @@ exit: return ret; } -#ifdef OSI_DEBUG -static void macsec_debug_intr_config(struct osi_core_priv_data *const osi_core, nveu32_t enable) -{ - nveu32_t val = 0; - nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; - - if (enable == OSI_ENABLE) { - val = osi_readla(osi_core, addr + MACSEC_TX_IMR); - val |= (MACSEC_TX_DBG_BUF_CAPTURE_DONE_INT_EN | - MACSEC_TX_MTU_CHECK_FAIL_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); - osi_writela(osi_core, val, addr + MACSEC_TX_IMR); - - val = osi_readla(osi_core, addr + MACSEC_RX_IMR); - - val |= (MACSEC_RX_DBG_BUF_CAPTURE_DONE_INT_EN | - RX_REPLAY_ERROR_INT_EN | - MACSEC_RX_MTU_CHECK_FAIL_INT_EN | - MACSEC_RX_AES_GCM_BUF_OVF_INT_EN | - MACSEC_RX_PN_EXHAUSTED_INT_EN - ); - osi_writela(osi_core, val, addr + MACSEC_RX_IMR); - - val = osi_readla(osi_core, addr + MACSEC_COMMON_IMR); - val |= (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 | - MACSEC_SECURE_REG_VIOL_INT_EN); - osi_writela(osi_core, val, addr + MACSEC_COMMON_IMR); - } else { - val = osi_readla(osi_core, addr + MACSEC_TX_IMR); - val &= (~MACSEC_TX_DBG_BUF_CAPTURE_DONE_INT_EN & - ~MACSEC_TX_MTU_CHECK_FAIL_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); - osi_writela(osi_core, val, addr + MACSEC_TX_IMR); - - val = osi_readla(osi_core, addr + MACSEC_RX_IMR); - val &= (~MACSEC_RX_DBG_BUF_CAPTURE_DONE_INT_EN & - ~RX_REPLAY_ERROR_INT_EN & - ~MACSEC_RX_MTU_CHECK_FAIL_INT_EN & - ~MACSEC_RX_AES_GCM_BUF_OVF_INT_EN & - ~MACSEC_RX_PN_EXHAUSTED_INT_EN - ); - osi_writela(osi_core, val, addr + MACSEC_RX_IMR); - - val = osi_readla(osi_core, addr + MACSEC_COMMON_IMR); - val &= (~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 & - ~MACSEC_SECURE_REG_VIOL_INT_EN); - osi_writela(osi_core, val, addr + MACSEC_COMMON_IMR); - } -} -#endif - /** * @brief osi_init_macsec_ops - macsec initialize operations * @@ -5481,23 +5465,22 @@ nve32_t osi_init_macsec_ops(struct osi_core_priv_data *const osi_core) 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, + .handle_irq = macsec_handle_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, -#ifdef OSI_DEBUG - .debug_intr_config = macsec_debug_intr_config, +#ifdef DEBUG_MACSEC + .loopback_config = macsec_loopback_config, + .dbg_buf_config = macsec_dbg_buf_config, + .dbg_events_config = macsec_dbg_events_config, + .intr_config = macsec_intr_config, #endif }; @@ -5588,12 +5571,12 @@ nve32_t osi_macsec_deinit(struct osi_core_priv_data *const osi_core) } /** - * @brief osi_macsec_ns_isr - macsec non-secure irq handler + * @brief osi_macsec_isr - macsec irq handler * * @note * Algorithm: * - Return -1 if osi core or ops is null - * - handles non-secure macsec interrupts + * - handles macsec interrupts * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. * - TraceID: *********** * @@ -5607,39 +5590,11 @@ nve32_t osi_macsec_deinit(struct osi_core_priv_data *const osi_core) * - Run time: Yes * - De-initialization: No */ -void osi_macsec_ns_isr(struct osi_core_priv_data *const osi_core) +void osi_macsec_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); + (osi_core->macsec_ops->handle_irq != OSI_NULL)) { + osi_core->macsec_ops->handle_irq(osi_core); } } @@ -5835,6 +5790,7 @@ nve32_t osi_macsec_cipher_config(struct osi_core_priv_data *const osi_core, return ret; } +#ifdef DEBUG_MACSEC /** * @brief osi_macsec_loopback - API to enable/disable macsec loopback * @@ -5871,6 +5827,7 @@ nve32_t osi_macsec_loopback(struct osi_core_priv_data *const osi_core, return ret; } +#endif /* DEBUG_MACSEC */ /** * @brief osi_macsec_en - API to enable/disable macsec @@ -5999,6 +5956,7 @@ nve32_t osi_macsec_read_mmc(struct osi_core_priv_data *const osi_core) return ret; } +#ifdef DEBUG_MACSEC /** * @brief osi_macsec_config_dbg_buf - Reads the debug buffer captured * @@ -6077,4 +6035,5 @@ nve32_t osi_macsec_dbg_events_config( return ret; } +#endif /* DEBUG_MACSEC */ #endif /* MACSEC_SUPPORT */ diff --git a/osi/core/macsec.h b/osi/core/macsec.h index 6a2c132..d958c91 100644 --- a/osi/core/macsec.h +++ b/osi/core/macsec.h @@ -91,23 +91,25 @@ #define MACSEC_TX_SCI_LUT_VALID 0xD028 #define MACSEC_RX_BYP_LUT_VALID 0xD02C #define MACSEC_RX_SCI_LUT_VALID 0xD030 -#ifdef OSI_DEBUG +#ifdef DEBUG_MACSEC #define MACSEC_COMMON_IMR 0xD054 -#endif /* OSI_DEBUG */ +#endif /* DEBUG_MACSEC */ #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_TX_DEBUG_TRIGGER_EN_0 0xD09C +#define MACSEC_RX_DEBUG_STATUS_0 0xD0F8 +#define MACSEC_RX_DEBUG_TRIGGER_EN_0 0xD0E0 +#ifdef DEBUG_MACSEC +#define MACSEC_TX_DEBUG_CONTROL_0 0xD098 #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 +#endif /* DEBUG_MACSEC */ #define MACSEC_CONTROL1 0xE000 #define MACSEC_GCM_AES_CONTROL_0 0xE004 @@ -193,7 +195,9 @@ * @brief Bit definitions of MACSEC_CONTROL1 register * @{ */ +#ifdef DEBUG_MACSEC #define MACSEC_LOOPBACK_MODE_EN OSI_BIT(31) +#endif /* DEBUG_MACSEC */ #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) @@ -213,7 +217,7 @@ #define MACSEC_TX_AES_MODE_AES256 OSI_BIT(1) /** @} */ -#ifdef OSI_DEBUG +#ifdef DEBUG_MACSEC /** * @addtogroup MACSEC_COMMON_IMR register * @@ -226,7 +230,7 @@ #define MACSEC_TX_UNINIT_KEY_SLOT_INT_EN OSI_BIT(1) #define MACSEC_TX_LKUP_MISS_INT_EN OSI_BIT(0) /** @} */ -#endif /* OSI_DEBUG */ +#endif /* DEBUG_MACSEC */ /** * @addtogroup MACSEC_TX_IMR register @@ -235,7 +239,7 @@ * @{ */ #define MACSEC_TX_MAC_CRC_ERROR_INT_EN OSI_BIT(16) -#ifdef OSI_DEBUG +#ifdef DEBUG_MACSEC #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) @@ -255,7 +259,7 @@ #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_PN_EXHAUSTED_INT_EN OSI_BIT(1) -#endif /* OSI_DEBUG */ +#endif /* DEBUG_MACSEC */ #define MACSEC_RX_ICV_ERROR_INT_EN OSI_BIT(21) #define MACSEC_RX_MAC_CRC_ERROR_INT_EN OSI_BIT(16) /** @} */ @@ -273,6 +277,16 @@ #define MACSEC_TX_LKUP_MISS OSI_BIT(0) /** @} */ +/** + * @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_TX_ISR register * @@ -303,15 +317,7 @@ #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) -/** @} */ - +#ifdef DEBUG_MACSEC /** * @addtogroup MACSEC_DEBUG_BUF_CONFIG_0 register * @@ -370,6 +376,7 @@ */ #define MACSEC_RX_DEBUG_CONTROL_0_START_CAP OSI_BIT(31) /** @} */ +#endif /* DEBUG_MACSEC */ #define MTU_LENGTH_MASK 0xFFFFU #define SOT_LENGTH_MASK 0xFFU diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 44f3f65..d1a4ecd 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -2271,6 +2271,11 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, case OSI_CMD_MAC_MTU: ret = 0; +#ifdef MACSEC_SUPPORT + if (osi_core->macsec_ops->update_mtu != OSI_NULL) { + ret = osi_core->macsec_ops->update_mtu(osi_core, data->arg1_u32); + } +#endif /* MACSEC_SUPPORT */ break; #ifdef OSI_DEBUG @@ -2301,8 +2306,8 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, #ifdef OSI_DEBUG case OSI_CMD_DEBUG_INTR_CONFIG: -#ifdef MACSEC_SUPPORT - osi_core->macsec_ops->debug_intr_config(osi_core, data->arg1_u32); +#ifdef DEBUG_MACSEC + osi_core->macsec_ops->intr_config(osi_core, data->arg1_u32); #endif ret = 0; break; From 0610f6bd35dffd94ed57112d53c1bc19e33ffa8c Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Wed, 3 Aug 2022 06:49:07 +0530 Subject: [PATCH 378/458] osi: dma: mgbe: fix regression RWTU programming Bug 200770328 Change-Id: I738daa23df274c5f8e485829c3876ef96310015f Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2754972 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/dma/mgbe_dma.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osi/dma/mgbe_dma.h b/osi/dma/mgbe_dma.h index 97010bf..d4a81f6 100644 --- a/osi/dma/mgbe_dma.h +++ b/osi/dma/mgbe_dma.h @@ -79,8 +79,8 @@ #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 3000U -#define MGBE_DMA_CHX_RX_WDT_RWTU_MASK 3000U +#define MGBE_DMA_CHX_RX_WDT_RWTU_2048_CYCLE 0x3000U +#define MGBE_DMA_CHX_RX_WDT_RWTU_MASK 0x3000U #define MGBE_DMA_CHX_RBSZ_MASK 0x7FFEU #define MGBE_DMA_CHX_RBSZ_SHIFT 1U #define MGBE_DMA_CHX_CTRL_PBLX8 OSI_BIT(16) From d399e48572037a1d03d660d70d43ee166cacfb79 Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Mon, 4 Jul 2022 19:41:24 +0000 Subject: [PATCH 379/458] osi: core: skip out not required code for Safety QNX Bug 3701869 Change-Id: Ic1f676708ff6e3faf7dbed09f0e7048448252e57 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2739627 Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit Tested-by: Bhadram Varka <vbhadram@nvidia.com> --- include/ivc_core.h | 2 - include/osi_common.h | 7 +- include/osi_core.h | 436 ++++++++--------------------------------- include/osi_dma.h | 2 - osi/core/Makefile.tmk | 2 + osi/core/core_common.c | 3 +- osi/core/core_common.h | 2 + osi/core/core_local.h | 171 +++++++++------- osi/core/eqos_core.c | 296 +++++++++++++++------------- osi/core/eqos_core.h | 16 +- osi/core/frp.c | 2 + osi/core/frp.h | 2 + osi/core/macsec.c | 9 +- osi/core/mgbe_core.c | 263 +++++++++++++------------ osi/core/osi_hal.c | 319 ++++++++++++------------------ osi/core/vlan_filter.c | 2 + osi/core/xpcs.c | 10 +- osi/dma/osi_dma_txrx.c | 2 +- 18 files changed, 643 insertions(+), 903 deletions(-) diff --git a/include/ivc_core.h b/include/ivc_core.h index e977dd4..8e690b7 100644 --- a/include/ivc_core.h +++ b/include/ivc_core.h @@ -86,8 +86,6 @@ typedef struct ivc_core_args { 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 */ diff --git a/include/osi_common.h b/include/osi_common.h index 76d00b9..cffe3ca 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -129,8 +129,6 @@ #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 @@ -139,13 +137,14 @@ #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 */ +#define OSI_POLL_COUNT 1000U +#define OSI_MAX_32BITS 0xFFFFFFFFU +#define OSI_MASK_16BITS 0xFFFFU #ifndef UINT_MAX #define UINT_MAX (~0U) #endif diff --git a/include/osi_core.h b/include/osi_core.h index c73304e..36671e9 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -317,6 +317,7 @@ typedef my_lint_64 nvel64_t; #define OSI_PTP_SSINC_6 6U /** @} */ +#ifndef OSI_STRIPPED_LIB /** * @addtogroup Flexible Receive Parser related information * @@ -354,6 +355,7 @@ typedef my_lint_64 nvel64_t; #define OSI_FRP_MATCH_VLAN 9U #define OSI_FRP_MATCH_MAX 10U /** @} */ +#endif /* !OSI_STRIPPED_LIB */ #ifdef HSI_SUPPORT /** @@ -451,6 +453,7 @@ struct osi_filter { nveu32_t dma_chansel; }; +#ifndef OSI_STRIPPED_LIB /** * @brief OSI core structure for RXQ route */ @@ -463,7 +466,7 @@ struct osi_rxq_route { /** RX queue index */ unsigned int idx; }; - +#endif /** * @brief L3/L4 filter function dependent parameter */ @@ -909,7 +912,6 @@ struct osi_core_avb_algorithm { /** TC index */ unsigned int tcindex; }; -#endif /* !OSI_STRIPPED_LIB */ /** * @brief struct ptp_offload_param - Parameter to support PTP offload. @@ -988,6 +990,37 @@ struct osi_tsn_stats { unsigned long sw_own_list_complete; }; +/** + * @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 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]; +}; + +#endif /* !OSI_STRIPPED_LIB */ + /** * @brief PTP configuration structure */ @@ -1037,18 +1070,6 @@ struct osi_ptp_config { 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 @@ -1065,21 +1086,6 @@ struct osi_core_ptp_tsc_data { 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 @@ -1263,17 +1269,17 @@ struct osi_ioctl { 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; + /* RXQ route structure */ + struct osi_rxq_route rxq_route; +#endif /* !OSI_STRIPPED_LIB */ /** PTP configuration settings */ struct osi_ptp_config ptp_config; /** TX Timestamp structure */ @@ -1304,6 +1310,7 @@ struct core_padctrl { unsigned int pad_calibration_enable; }; +#ifndef OSI_STRIPPED_LIB /** * @brief OSI CORE packet error stats */ @@ -1317,6 +1324,7 @@ struct osi_core_pkt_err_stats { /** Under Flow Error */ nveu64_t mgbe_tx_underflow_err; }; +#endif #ifdef HSI_SUPPORT /** @@ -1370,8 +1378,6 @@ struct osi_hsi_data { 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 */ @@ -1411,18 +1417,12 @@ struct osi_core_priv_data { 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 */ @@ -1437,49 +1437,61 @@ struct osi_core_priv_data { 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; + /** TQ:TC mapping */ + unsigned int tc[OSI_MGBE_MAX_NUM_CHANS]; +#ifndef OSI_STRIPPED_LIB + /** xtra sw error counters */ + struct osi_xtra_stat_counters xstats; + /** Memory mapped base address of HV window */ + void *hv_base; + /** Residual queue valid with FPE support */ + unsigned int residual_queue; /** 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 */ + /* 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 */ + /* FPE enabled, verify and respose done with peer device + * 1- Successful and can be used between P2P device + */ unsigned int fpe_ready; /** TSN stats counters */ struct osi_tsn_stats tsn_stats; + /** csr clock is to program LPI 1 us tick timer register. + * Value stored in MHz + */ + nveu32_t csr_clk_speed; + 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; +#endif + /** eqos pad control structure */ + struct core_padctrl padctrl; + /** MDC clock rate */ + nveu32_t mdc_cr; + /** 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; + /** Flag which decides virtualization is enabled(1) or disabled(0) */ + nveu32_t use_virtualization; + /** HW supported feature list */ + struct osi_hw_features *hw_feature; /** MC packets Multiple DMA channel selection flags */ nveu32_t mc_dmasel; /** UPHY GBE mode (1 for 10G, 0 for 5G) */ @@ -1490,12 +1502,12 @@ struct osi_core_priv_data { 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; +#ifndef OSI_STRIPPED_LIB /** Packet error stats */ struct osi_core_pkt_err_stats pkt_err_stats; +#endif /** Ethernet controller MAC to MAC Time sync role * 1 - Primary interface, 2 - secondary interface, 0 - inactive interface */ @@ -1580,71 +1592,6 @@ nve32_t osi_hw_core_init(struct osi_core_priv_data *const osi_core, */ 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. * @@ -1678,109 +1625,6 @@ nve32_t osi_stop_mac(struct osi_core_priv_data *const osi_core); */ 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_rxcsum_offload - Configure RX checksum offload in MAC. * @@ -2154,130 +1998,14 @@ nve32_t osi_adjust_time(struct osi_core_priv_data *const osi_core, nve32_t osi_ptp_configuration(struct osi_core_priv_data *const osi_core, const nveu32_t enable); +#ifndef OSI_STRIPPED_LIB /* 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, - struct osi_l3_l4_filter *const 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); +#endif /** * @brief osi_handle_ioctl - API to handle runtime command diff --git a/include/osi_dma.h b/include/osi_dma.h index 1c0831d..33aaec6 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -586,8 +586,6 @@ struct osi_dma_priv_data { 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 diff --git a/osi/core/Makefile.tmk b/osi/core/Makefile.tmk index 9f97df6..c3ea29c 100644 --- a/osi/core/Makefile.tmk +++ b/osi/core/Makefile.tmk @@ -59,6 +59,8 @@ endif ifeq ($(NV_BUILD_CONFIGURATION_IS_SAFETY),0) NV_COMPONENT_CFLAGS += -DOSI_DEBUG NV_COMPONENT_CFLAGS += -DDEBUG_MACSEC +else +NV_COMPONENT_CFLAGS += -DOSI_STRIPPED_LIB endif NV_COMPONENT_INCLUDES := \ diff --git a/osi/core/core_common.c b/osi/core/core_common.c index b9693dc..87dd536 100644 --- a/osi/core/core_common.c +++ b/osi/core/core_common.c @@ -286,7 +286,7 @@ fail: return ret; } - +#ifndef OSI_STRIPPED_LIB /** * @brief hw_est_read - indirect read the GCL to Software own list * (SWOL) @@ -488,3 +488,4 @@ nve32_t gcl_validate(struct osi_core_priv_data *const osi_core, return 0; } +#endif /* !OSI_STRIPPED_LIB */ diff --git a/osi/core/core_common.h b/osi/core/core_common.h index 62df704..06528bc 100644 --- a/osi/core/core_common.h +++ b/osi/core/core_common.h @@ -58,9 +58,11 @@ struct est_read { /** @} */ +#ifndef OSI_STRIPPED_LIB 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 /* !OSI_STRIPPED_LIB */ nve32_t hw_poll_for_swr(struct osi_core_priv_data *const osi_core); void hw_start_mac(struct osi_core_priv_data *const osi_core); void hw_stop_mac(struct osi_core_priv_data *const osi_core); diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 4bf7547..2493bd8 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -56,8 +56,21 @@ #define DYNAMIC_CFG_PTP OSI_BIT(7) #define DYNAMIC_CFG_EST OSI_BIT(8) #define DYNAMIC_CFG_FPE OSI_BIT(9) + +#define DYNAMIC_CFG_L3_L4_IDX 0U +#define DYNAMIC_CFG_FC_IDX 1U +#define DYNAMIC_CFG_AVB_IDX 2U +#define DYNAMIC_CFG_L2_IDX 3U +#define DYNAMIC_CFG_RXCSUM_IDX 4U +#define DYNAMIC_CFG_VLAN_IDX 5U +#define DYNAMIC_CFG_EEE_IDX 6U +#define DYNAMIC_CFG_PTP_IDX 7U +#define DYNAMIC_CFG_EST_IDX 8U +#define DYNAMIC_CFG_FPE_IDX 9U + #define OSI_SUSPENDED OSI_BIT(0) + /** * interface core ops */ @@ -118,11 +131,67 @@ struct core_ops { const nveu32_t perfect_inverse_match, const nveu32_t dma_routing_enable, const nveu32_t dma_chan); + /** 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 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 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 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 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 get HW features */ + nve32_t (*get_hw_features)(struct osi_core_priv_data *const osi_core, + struct osi_hw_features *hw_feat); + int (*ptp_tsc_capture)(struct osi_core_priv_data *const osi_core, + struct osi_core_ptp_tsc_data *data); /** 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 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); +#ifndef OSI_STRIPPED_LIB + void (*macsec_config_mac)(struct osi_core_priv_data *const osi_core, + const nveu32_t enable); +#endif /* !OSI_STRIPPED_LIB */ +#endif /* MACSEC_SUPPORT */ +#ifndef OSI_STRIPPED_LIB /** Called to update ip6 address */ nve32_t (*update_ip6_addr)(struct osi_core_priv_data *const osi_core, const nveu32_t filter_no, @@ -141,66 +210,7 @@ struct core_ops { 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 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); @@ -216,6 +226,19 @@ struct core_ops { 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 HW PTP offload feature */ + int (*config_ptp_offload)(struct osi_core_priv_data *const osi_core, + struct osi_pto_config *const pto_config); + /** 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 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 VLAN filtering */ nve32_t (*config_vlan_filtering)( struct osi_core_priv_data *const osi_core, @@ -239,12 +262,6 @@ struct core_ops { 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); @@ -261,15 +278,13 @@ struct core_ops { /** 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); + /** Called to configure RSS for MAC */ + nve32_t (*config_rss)(struct osi_core_priv_data *osi_core); + /** 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); +#endif /* !OSI_STRIPPED_LIB */ #ifdef HSI_SUPPORT /** Interface function called to initialize HSI */ int (*core_hsi_configure)(struct osi_core_priv_data *const osi_core, @@ -339,6 +354,7 @@ struct l3_l4_filters { struct osi_l3_l4_filter l3l4_filter; }; +#ifndef OSI_STRIPPED_LIB /** * @brief AVB dynamic config storage structure */ @@ -348,6 +364,7 @@ struct core_avb { /** AVB data structure */ struct osi_core_avb_algorithm avb_info; }; +#endif /* !OSI_STRIPPED_LIB */ /** * @brief VLAN dynamic config storage structure @@ -376,8 +393,10 @@ struct dynamic_cfg { struct l3_l4_filters l3_l4[OSI_MGBE_MAX_L3_L4_FILTER]; /** flow control */ nveu32_t flow_ctrl; +#ifndef OSI_STRIPPED_LIB /** AVB */ struct core_avb avb[OSI_MGBE_MAX_NUM_QUEUES]; +#endif /* !OSI_STRIPPED_LIB */ /** RXCSUM */ nveu32_t rxcsum; /** VLAN arguments storage */ @@ -387,10 +406,12 @@ struct dynamic_cfg { nveu32_t tx_lpi_timer; /** PTP information storage */ nveu32_t ptp; +#ifndef OSI_STRIPPED_LIB /** EST information storage */ struct osi_est_config est; /** FPE information storage */ struct osi_fpe_config fpe; +#endif /* !OSI_STRIPPED_LIB */ /** L2 filter storage */ struct osi_filter l2_filter; /** L2 filter configuration */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 845d9bb..333aa7b 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -151,6 +151,7 @@ static inline void eqos_core_safety_writel( osi_unlock_irq_enabled(&config->core_safety_lock); } +#ifndef OSI_STRIPPED_LIB /** * @brief Initialize the eqos_core_safety_config. * @@ -481,6 +482,7 @@ static nve32_t eqos_config_flow_control( return 0; } +#endif /* !OSI_STRIPPED_LIB */ /** * @brief eqos_calculate_per_queue_fifo - Calculate per queue FIFO size @@ -984,6 +986,7 @@ static nve32_t eqos_configure_mtl_queue(nveu32_t qinx, } /** \endcond */ +#ifndef OSI_STRIPPED_LIB /** * @brief eqos_config_frp - Enable/Disale RX Flexible Receive Parser in HW * @@ -1262,6 +1265,7 @@ static int eqos_update_frp_entry(struct osi_core_priv_data *const osi_core, return ret; } +#endif /* !OSI_STRIPPED_LIB */ /** \cond DO_NOT_DOCUMENT */ /** @@ -1625,6 +1629,7 @@ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) osi_writela(osi_core, value, (nveu8_t *)osi_core->base + EQOS_MAC_VLANTIR); +#ifndef OSI_STRIPPED_LIB /* 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); @@ -1635,6 +1640,8 @@ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) 0ULL); } } +#endif /* !OSI_STRIPPED_LIB */ + /* USP (user Priority) to RxQ Mapping, only if DCS not enabled */ if (osi_core->dcs_en != OSI_ENABLE) { eqos_configure_rxq_priority(osi_core); @@ -1687,6 +1694,7 @@ static void eqos_configure_dma(struct osi_core_priv_data *const osi_core) } /** \endcond */ +#ifndef OSI_STRIPPED_LIB /** * @brief eqos_enable_mtl_interrupts - Enable MTL interrupts * @@ -1818,12 +1826,7 @@ static void eqos_tsn_init(struct osi_core_priv_data *osi_core, * 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 = EQOS_MTL_EST_PTOV_RECOMMEND; temp = temp << EQOS_MTL_EST_CONTROL_PTOV_SHIFT; val |= temp; @@ -1871,6 +1874,7 @@ static void eqos_tsn_init(struct osi_core_priv_data *osi_core, /* CBS setting for TC should be by user application/IOCTL as * per requirement */ } +#endif /* !OSI_STRIPPED_LIB */ /** * @brief Map DMA channels to a specific VM IRQ. @@ -1953,9 +1957,10 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core, nveu32_t tx_fifo = 0; nveu32_t rx_fifo = 0; +#ifndef OSI_STRIPPED_LIB eqos_core_safety_init(osi_core); eqos_core_backup_init(osi_core); - +#endif /* !OSI_STRIPPED_LIB */ #ifndef UPDATED_PAD_CAL /* PAD calibration */ ret = eqos_pad_calibrate(osi_core); @@ -1971,6 +1976,7 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core, (nveu8_t *)osi_core->base + EQOS_MMC_CNTRL); if (osi_core->use_virtualization == OSI_DISABLE) { +#ifndef OSI_STRIPPED_LIB if (osi_core->hv_base != OSI_NULL) { osi_writela(osi_core, EQOS_5_30_ASID_CTRL_VAL, (nveu8_t *)osi_core->hv_base + @@ -1980,6 +1986,7 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core, (nveu8_t *)osi_core->hv_base + EQOS_AXI_ASID1_CTRL); } +#endif if (osi_core->mac_ver < OSI_EQOS_MAC_5_30) { /* AXI ASID CTRL for channel 0 to 3 */ @@ -2052,11 +2059,13 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core, /* configure EQOS DMA */ eqos_configure_dma(osi_core); +#ifndef OSI_STRIPPED_LIB /* 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); } +#endif /* !OSI_STRIPPED_LIB */ /* initialize L3L4 Filters variable */ osi_core->l3l4_filter_bitmask = OSI_NONE; @@ -2066,6 +2075,7 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core, return ret; } +#ifndef OSI_STRIPPED_LIB /** * @brief eqos_handle_mac_fpe_intrs * @@ -2118,6 +2128,7 @@ static void eqos_handle_mac_fpe_intrs(struct osi_core_priv_data *osi_core) osi_writela(osi_core, val, (unsigned char *)osi_core->base + EQOS_MAC_FPE_CTS); } +#endif /* !OSI_STRIPPED_LIB */ /** * @brief eqos_handle_mac_intrs - Handle MAC interrupts @@ -2194,10 +2205,12 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, return; } +#ifndef OSI_STRIPPED_LIB 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); } +#endif /* !OSI_STRIPPED_LIB */ mac_pcs = osi_readla(osi_core, (nveu8_t *)osi_core->base + EQOS_MAC_PCS); @@ -2238,6 +2251,7 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, } +#ifndef OSI_STRIPPED_LIB /** \cond DO_NOT_DOCUMENT */ /** * @brief update_dma_sr_stats - stats for dma_status error @@ -2430,6 +2444,7 @@ static void eqos_handle_mtl_intrs(struct osi_core_priv_data *osi_core) osi_writela(osi_core, val, (nveu8_t *)osi_core->base + EQOS_MTL_EST_STATUS); } +#endif /* !OSI_STRIPPED_LIB */ #ifdef HSI_SUPPORT /** @@ -2542,8 +2557,10 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *const osi_core) nveu32_t i = 0; nveu32_t dma_sr = 0; nveu32_t dma_ier = 0; +#ifndef OSI_STRIPPED_LIB nveu32_t mtl_isr = 0; nveu32_t frp_isr = 0U; +#endif /* !OSI_STRIPPED_LIB */ if (osi_core->mac_ver >= OSI_EQOS_MAC_5_30) { osi_writela(osi_core, EQOS_MAC_SBD_INTR, (nveu8_t *)osi_core->base + @@ -2591,11 +2608,15 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *const osi_core) /* ack non ti/ri ints */ osi_writela(osi_core, dma_sr, (nveu8_t *)base + EQOS_DMA_CHX_STATUS(qinx)); +#ifndef OSI_STRIPPED_LIB update_dma_sr_stats(osi_core, dma_sr, qinx); +#endif /* !OSI_STRIPPED_LIB */ } } eqos_handle_mac_intrs(osi_core, dma_isr); + +#ifndef OSI_STRIPPED_LIB /* Handle MTL inerrupts */ mtl_isr = osi_readla(osi_core, (unsigned char *)base + EQOS_MTL_INTR_STATUS); @@ -2616,9 +2637,10 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *const osi_core) EQOS_MTL_RXP_INTR_CS_PDRFIS); osi_writela(osi_core, frp_isr, (unsigned char *)base + EQOS_MTL_RXP_INTR_CS); +#endif /* !OSI_STRIPPED_LIB */ } -#ifdef MACSEC_SUPPORT +#if defined(MACSEC_SUPPORT) && !defined(OSI_STRIPPED_LIB) /** * @brief eqos_config_mac_tx - Enable/Disable MAC Tx * @@ -3025,6 +3047,112 @@ static nve32_t eqos_update_mac_addr_low_high_reg( 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 <<RM_19, (sequence diagram)>> 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; +} +#ifndef OSI_STRIPPED_LIB /** * @brief eqos_config_ptp_offload - Enable/Disable PTP offload * @@ -3128,111 +3256,6 @@ static int eqos_config_ptp_offload(struct osi_core_priv_data *const osi_core, 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 <<RM_19, (sequence diagram)>> 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 * @@ -3368,6 +3391,7 @@ static nve32_t eqos_update_l4_port_no( return 0; } +#endif /* !OSI_STRIPPED_LIB */ /** \cond DO_NOT_DOCUMENT */ /** @@ -3644,6 +3668,7 @@ static nve32_t eqos_config_l3_filters( return 0; } +#ifndef OSI_STRIPPED_LIB /** * @brief eqos_config_l4_filters - Config L4 filters. * @@ -3771,6 +3796,7 @@ static nve32_t eqos_config_l4_filters( return 0; } +#endif /* !OSI_STRIPPED_LIB */ /** * @brief eqos_poll_for_tsinit_complete - Poll for time stamp init complete @@ -4247,6 +4273,7 @@ static void eqos_config_tscr(struct osi_core_priv_data *const osi_core, } /** \endcond */ +#ifndef OSI_STRIPPED_LIB /** * @brief eqos_config_ptp_rxq - To config PTP RX packets queue * @@ -4334,6 +4361,7 @@ static nve32_t eqos_config_ptp_rxq(struct osi_core_priv_data *const osi_core, return 0; } +#endif /* !OSI_STRIPPED_LIB */ /** * @brief eqos_config_ssir - Configure SSIR register @@ -4425,6 +4453,7 @@ static void eqos_core_deinit(struct osi_core_priv_data *const osi_core) hw_stop_mac(osi_core); } +#ifndef OSI_STRIPPED_LIB /** * @brief eqos_hw_est_write - indirect write the GCL to Software own list * (SWOL) @@ -4730,6 +4759,7 @@ static int eqos_hw_config_fpe(struct osi_core_priv_data *const osi_core, return 0; } +#endif /* !OSI_STRIPPED_LIB */ /** \cond DO_NOT_DOCUMENT */ /** @@ -5913,10 +5943,10 @@ static nve32_t eqos_get_hw_features(struct osi_core_priv_data *const osi_core, 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); + mac_hfr0 = osi_readla(osi_core, (nveu8_t *)osi_core->base + EQOS_MAC_HFR0); + mac_hfr1 = osi_readla(osi_core, (nveu8_t *)osi_core->base + EQOS_MAC_HFR1); + mac_hfr2 = osi_readla(osi_core, (nveu8_t *)osi_core->base + EQOS_MAC_HFR2); + mac_hfr3 = osi_readla(osi_core, (nveu8_t *)osi_core->base + EQOS_MAC_HFR3); hw_feat->mii_sel = ((mac_hfr0 >> EQOS_MAC_HFR0_MIISEL_SHIFT) & EQOS_MAC_HFR0_MIISEL_MASK); @@ -6280,6 +6310,7 @@ static nve32_t eqos_post_pad_calibrate( } #endif /* UPDATED_PAD_CAL */ +#ifndef OSI_STRIPPED_LIB /** * @brief eqos_config_rss - Configure RSS * @@ -6296,8 +6327,9 @@ static nve32_t eqos_config_rss(struct osi_core_priv_data *osi_core) return -1; } +#endif /* !OSI_STRIPPED_LIB */ -#ifdef MACSEC_SUPPORT +#if defined(MACSEC_SUPPORT) && !defined(OSI_STRIPPED_LIB) /** * @brief eqos_config_for_macsec - Configure MAC according to macsec IAS * @@ -6403,6 +6435,7 @@ exit: #endif /* MACSEC_SUPPORT */ +#ifndef OSI_STRIPPED_LIB /** * @brief eqos_get_core_safety_config - EQOS MAC safety configuration * @@ -6416,6 +6449,7 @@ void *eqos_get_core_safety_config(void) { return &eqos_core_safety_config; } +#endif void eqos_init_core_ops(struct core_ops *ops) { @@ -6427,26 +6461,30 @@ void eqos_init_core_ops(struct core_ops *ops) 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->adjust_mactime = eqos_adjust_mactime; ops->read_mmc = eqos_read_mmc; ops->write_phy_reg = eqos_write_phy_reg; ops->read_phy_reg = eqos_read_phy_reg; + ops->get_hw_features = eqos_get_hw_features; + ops->ptp_tsc_capture = eqos_ptp_tsc_capture; + ops->update_ip4_addr = eqos_update_ip4_addr; 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->macsec_config_mac = eqos_config_for_macsec; +#endif /* !OSI_STRIPPED_LIB */ +#endif /* MACSEC_SUPPORT */ +#ifndef OSI_STRIPPED_LIB + 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->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; @@ -6462,18 +6500,14 @@ void eqos_init_core_ops(struct core_ops *ops) 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; + ops->config_ptp_rxq = eqos_config_ptp_rxq; +#endif /* !OSI_STRIPPED_LIB */ #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 index 3d1eee7..685098c 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -321,13 +321,13 @@ #define EQOS_MAC_PFR_SHIFT 16 #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_MAC_EXTR_DCRCC OSI_BIT(16) +#endif /* !OSI_STRIPPED_LIB */ +#define EQOS_MAC_EXTR_PDC OSI_BIT(19) #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_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 @@ -494,6 +494,7 @@ (EQOS_5_30_SID)) #define EQOS_MMC_INTR_DISABLE 0xFFFFFFFFU +#ifndef OSI_STRIPPED_LIB /* MAC FPE control/statusOSI_BITmap */ #define EQOS_MAC_FPE_CTS_EFPE OSI_BIT(0) #define EQOS_MAC_FPE_CTS_TRSP OSI_BIT(19) @@ -529,10 +530,8 @@ #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_VAL 0U #define EQOS_MTL_EST_CONTROL_DFBS OSI_BIT(5) @@ -582,6 +581,11 @@ #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) +#endif /* !OSI_STRIPPED_LIB */ +#ifdef MACSEC_SUPPORT +/* MACSEC Recommended value*/ +#define EQOS_MTL_EST_CTOV_MACSEC_RECOMMEND 758U +#endif /* MACSEC_SUPPORT */ #ifdef UPDATED_PAD_CAL /* EQOS RGMII Rx padctrl registers E_INPUT bit */ #define EQOS_PADCTL_EQOS_E_INPUT OSI_BIT(6) diff --git a/osi/core/frp.c b/osi/core/frp.c index 6004e50..65da6df 100644 --- a/osi/core/frp.c +++ b/osi/core/frp.c @@ -23,6 +23,7 @@ #include "../osi/common/common.h" #include "frp.h" +#ifndef OSI_STRIPPED_LIB /** * @brief frp_entry_copy - Copy FRP entry * @@ -834,3 +835,4 @@ void init_frp(struct osi_core_priv_data *const osi_core) osi_memset(osi_core->frp_table, 0U, (sizeof(struct osi_core_frp_entry) * OSI_FRP_MAX_ENTRY)); } +#endif /* !OSI_STRIPPED_LIB */ diff --git a/osi/core/frp.h b/osi/core/frp.h index d1092b7..6455c20 100644 --- a/osi/core/frp.h +++ b/osi/core/frp.h @@ -23,6 +23,7 @@ #ifndef FRP_H #define FRP_H +#ifndef OSI_STRIPPED_LIB #include <osi_common.h> #include <osi_core.h> #include "core_local.h" @@ -80,5 +81,6 @@ int setup_frp(struct osi_core_priv_data *const osi_core, * @retval -1 on failure. */ void init_frp(struct osi_core_priv_data *const osi_core); +#endif /* !OSI_STRIPPED_LIB */ #endif /* FRP_H */ diff --git a/osi/core/macsec.c b/osi/core/macsec.c index d92f8f4..f382447 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -4211,13 +4211,16 @@ exit: static nve32_t macsec_deinit(struct osi_core_priv_data *const osi_core) { nveu32_t i; +#if defined(MACSEC_SUPPORT) && !defined(OSI_STRIPPED_LIB) const struct core_local *l_core = (void *)osi_core; +#endif 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)); } +#if defined(MACSEC_SUPPORT) && !defined(OSI_STRIPPED_LIB) /* 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); @@ -4225,6 +4228,7 @@ static nve32_t macsec_deinit(struct osi_core_priv_data *const osi_core) OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Failed config MAC per macsec\n", 0ULL); } +#endif return 0; } @@ -4481,10 +4485,13 @@ static nve32_t macsec_init(struct osi_core_priv_data *const osi_core, nveu32_t mtu) { nveu32_t val = 0; +#if defined(MACSEC_SUPPORT) && !defined(OSI_STRIPPED_LIB) const struct core_local *l_core = (void *)osi_core; +#endif nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; nve32_t ret = 0; +#if defined(MACSEC_SUPPORT) && !defined(OSI_STRIPPED_LIB) /* 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); @@ -4492,7 +4499,7 @@ static nve32_t macsec_init(struct osi_core_priv_data *const osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Failed to config mac per macsec\n", 0ULL); } - +#endif /* Set MTU */ ret = macsec_update_mtu(osi_core, mtu); if (ret < 0) { diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index a9e40af..33b664f 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -854,7 +854,7 @@ static nve32_t mgbe_update_ip4_addr(struct osi_core_priv_data *const osi_core, return ret; } - +#ifndef OSI_STRIPPED_LIB /** * @brief mgbe_update_ip6_addr - add ipv6 address in register * @@ -935,42 +935,6 @@ static nve32_t mgbe_update_ip6_addr(struct osi_core_priv_data *const osi_core, 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 nve32_t mgbe_config_l3_l4_filter_enable( - struct osi_core_priv_data *const osi_core, - const nveu32_t 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 * @@ -1025,7 +989,43 @@ static nve32_t mgbe_update_l4_port_no(struct osi_core_priv_data *osi_core, return mgbe_l3l4_filter_write(osi_core, filter_no, MGBE_MAC_L4_ADDR, value); } +#endif /* !OSI_STRIPPED_LIB */ +/** + * @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_set_dcs - check and update dma routing register * @@ -1283,6 +1283,7 @@ static nve32_t mgbe_config_l3_filters(struct osi_core_priv_data *osi_core, return ret; } +#ifndef OSI_STRIPPED_LIB /** * @brief mgbe_config_l4_filters - Config L4 filters. * @@ -1970,6 +1971,7 @@ static int mgbe_update_frp_nve(struct osi_core_priv_data *const osi_core, return 0; } +#endif /* !OSI_STRIPPED_LIB */ /** * @brief update_rfa_rfd - Update RFD and RSA values @@ -2168,6 +2170,7 @@ static nve32_t mgbe_configure_mtl_queue(nveu32_t qinx, return 0; } +#ifndef OSI_STRIPPED_LIB /** * @brief mgbe_rss_write_reg - Write into RSS registers * @@ -2355,6 +2358,7 @@ static int mgbe_config_flow_control(struct osi_core_priv_data *const osi_core, return 0; } +#endif /* !OSI_STRIPPED_LIB */ #ifdef HSI_SUPPORT /** @@ -2672,6 +2676,7 @@ static int mgbe_configure_mac(struct osi_core_priv_data *osi_core) osi_writela(osi_core, value, (unsigned char *)osi_core->base + MGBE_MAC_VLANTIR); +#ifndef OSI_STRIPPED_LIB /* 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); @@ -2685,7 +2690,10 @@ static int mgbe_configure_mac(struct osi_core_priv_data *osi_core) /* TODO: USP (user Priority) to RxQ Mapping */ /* RSS cofiguration */ - return mgbe_config_rss(osi_core); + mgbe_config_rss(osi_core); +#endif /* !OSI_STRIPPED_LIB */ + + return 0; } /** @@ -2701,8 +2709,7 @@ static int mgbe_configure_mac(struct osi_core_priv_data *osi_core) * * @note MAC has to be out of reset. */ -static void mgbe_configure_dma(struct osi_core_priv_data *osi_core, - nveu32_t pre_si) +static void mgbe_configure_dma(struct osi_core_priv_data *osi_core) { nveu32_t value = 0; @@ -2723,28 +2730,19 @@ static void mgbe_configure_dma(struct osi_core_priv_data *osi_core, /* 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; - } + 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; - } + value |= MGBE_DMA_RX_EDMA_CTRL_RDPS; osi_writela(osi_core, value, (nveu8_t *)osi_core->base + MGBE_DMA_RX_EDMA_CTRL); } +#ifndef OSI_STRIPPED_LIB /** * @brief Initialize the osi_core->backup_config. * @@ -2962,12 +2960,7 @@ static void mgbe_tsn_init(struct osi_core_priv_data *osi_core, * 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 = MGBE_MTL_EST_PTOV_RECOMMEND; temp = temp << MGBE_MTL_EST_CONTROL_PTOV_SHIFT; val |= temp; @@ -3024,6 +3017,7 @@ static void mgbe_tsn_init(struct osi_core_priv_data *osi_core, user application should use IOCTL to set CBS as per requirement */ } +#endif /* !OSI_STRIPPED_LIB */ /** * @brief Map DMA channels to a specific VM IRQ. @@ -3038,7 +3032,9 @@ static void mgbe_tsn_init(struct osi_core_priv_data *osi_core, */ static nve32_t mgbe_dma_chan_to_vmirq_map(struct osi_core_priv_data *osi_core) { +#ifndef OSI_STRIPPED_LIB nveu32_t sid[4] = { MGBE0_SID, MGBE1_SID, MGBE2_SID, MGBE3_SID }; +#endif struct osi_vm_irq_data *irq_data; nveu32_t i, j; nveu32_t chan; @@ -3061,6 +3057,7 @@ static nve32_t mgbe_dma_chan_to_vmirq_map(struct osi_core_priv_data *osi_core) (nveu8_t *)osi_core->base + MGBE_VIRTUAL_APB_ERR_CTRL); } +#ifndef OSI_STRIPPED_LIB if ((osi_core->use_virtualization == OSI_DISABLE) && (osi_core->hv_base != OSI_NULL)) { if (osi_core->instance_id > 3U) { @@ -3082,7 +3079,7 @@ static nve32_t mgbe_dma_chan_to_vmirq_map(struct osi_core_priv_data *osi_core) (nveu8_t *)osi_core->hv_base + MGBE_WRAP_AXI_ASID2_CTRL); } - +#endif return 0; } @@ -3115,7 +3112,9 @@ static nve32_t mgbe_core_init(struct osi_core_priv_data *const osi_core, nveu32_t tx_fifo = 0; nveu32_t rx_fifo = 0; +#ifndef OSI_STRIPPED_LIB mgbe_core_backup_init(osi_core); +#endif /* !OSI_STRIPPED_LIB */ /* reset mmc counters */ osi_writela(osi_core, MGBE_MMC_CNTRL_CNTRST, (nveu8_t *)osi_core->base + @@ -3150,15 +3149,9 @@ static nve32_t mgbe_core_init(struct osi_core_priv_data *const osi_core, 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; - } + /* 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, @@ -3185,17 +3178,20 @@ static nve32_t mgbe_core_init(struct osi_core_priv_data *const osi_core, } /* configure MGBE DMA */ - mgbe_configure_dma(osi_core, osi_core->pre_si); + mgbe_configure_dma(osi_core); +#ifndef OSI_STRIPPED_LIB /* 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); } +#endif /* !OSI_STRIPPED_LIB */ return mgbe_dma_chan_to_vmirq_map(osi_core); } +#ifndef OSI_STRIPPED_LIB /** * @brief mgbe_handle_mac_fpe_intrs * @@ -3249,6 +3245,7 @@ static void mgbe_handle_mac_fpe_intrs(struct osi_core_priv_data *osi_core) osi_writela(osi_core, val, (unsigned char *) osi_core->base + MGBE_MAC_FPE_CTS); } +#endif /* !OSI_STRIPPED_LIB */ /** * @brief Get free timestamp index from TS array by validating in_use param @@ -3288,8 +3285,10 @@ static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core, { struct core_local *l_core = (struct core_local *)osi_core; nveu32_t mac_isr = 0; +#ifndef OSI_STRIPPED_LIB nveu32_t mac_ier = 0; nveu32_t tx_errors = 0; +#endif /* !OSI_STRIPPED_LIB */ mac_isr = osi_readla(osi_core, (unsigned char *)osi_core->base + MGBE_MAC_ISR); @@ -3298,12 +3297,14 @@ static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core, return; } +#ifndef OSI_STRIPPED_LIB 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); } + /* 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 @@ -3333,6 +3334,7 @@ static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core, 1UL); } } +#endif /* !OSI_STRIPPED_LIB */ if ((mac_isr & MGBE_ISR_TSIS) == MGBE_ISR_TSIS) { struct osi_core_tx_ts *head = &l_core->tx_ts_head; @@ -3340,9 +3342,11 @@ static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core, 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); +#ifndef OSI_STRIPPED_LIB osi_core->xstats.ts_lock_add_fail = osi_update_stats_counter( osi_core->xstats.ts_lock_add_fail, 1U); +#endif /* !OSI_STRIPPED_LIB */ goto done; } @@ -3396,6 +3400,7 @@ done: return; } +#ifndef OSI_STRIPPED_LIB /** * @brief mgbe_update_dma_sr_stats - stats for dma_status error * @@ -3709,10 +3714,12 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core, MGBE_MTL_QINT_STATUS(qinx)); /* Transmit Queue Underflow Interrupt Status */ if (qstatus & MGBE_MTL_QINT_TXUNIFS) { +#ifndef OSI_STRIPPED_LIB osi_core->pkt_err_stats.mgbe_tx_underflow_err = osi_update_stats_counter( osi_core->pkt_err_stats.mgbe_tx_underflow_err, 1UL); +#endif /* !OSI_STRIPPED_LIB */ } /* Clear interrupt status by writing back with 1 */ osi_writel(1U, (unsigned char *)osi_core->base + @@ -3939,6 +3946,7 @@ static int mgbe_config_ptp_offload(struct osi_core_priv_data *const osi_core, return ret; } +#endif /* !OSI_STRIPPED_LIB */ #ifdef HSI_SUPPORT /** @@ -4074,8 +4082,10 @@ static void mgbe_handle_common_intr(struct osi_core_priv_data *const osi_core) unsigned int i = 0; unsigned int dma_sr = 0; unsigned int dma_ier = 0; +#ifndef OSI_STRIPPED_LIB unsigned int mtl_isr = 0; unsigned int val = 0; +#endif /* !OSI_STRIPPED_LIB */ #ifdef HSI_SUPPORT if (osi_core->hsi.enabled == OSI_ENABLE) { @@ -4120,12 +4130,15 @@ static void mgbe_handle_common_intr(struct osi_core_priv_data *const osi_core) /* ack non ti/ri nve32_ts */ osi_writela(osi_core, dma_sr, (nveu8_t *)base + MGBE_DMA_CHX_STATUS(qinx)); +#ifndef OSI_STRIPPED_LIB mgbe_update_dma_sr_stats(osi_core, dma_sr, qinx); +#endif /* !OSI_STRIPPED_LIB */ } } mgbe_handle_mac_intrs(osi_core, dma_isr); +#ifndef OSI_STRIPPED_LIB /* Handle MTL inerrupts */ mtl_isr = osi_readla(osi_core, (unsigned char *)base + MGBE_MTL_INTR_STATUS); @@ -4149,6 +4162,7 @@ static void mgbe_handle_common_intr(struct osi_core_priv_data *const osi_core) 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); +#endif /* !OSI_STRIPPED_LIB */ } /** @@ -4167,7 +4181,7 @@ static nve32_t mgbe_pad_calibrate(OSI_UNUSED return 0; } -#ifdef MACSEC_SUPPORT +#if defined(MACSEC_SUPPORT) && !defined(OSI_STRIPPED_LIB) /** * @brief mgbe_config_mac_tx - Enable/Disable MAC Tx * @@ -4248,6 +4262,7 @@ static int mgbe_mdio_busy_wait(struct osi_core_priv_data *const osi_core) return 0; } +#ifndef OSI_STRIPPED_LIB /* * @brief mgbe_save_registers Function to store a backup of * MAC register space during SOC suspend. @@ -4409,6 +4424,7 @@ static inline int mgbe_restore_registers( return ret; } +#endif /* !OSI_STRIPPED_LIB */ /** * @brief mgbe_write_phy_reg - Write to a PHY register over MDIO bus. @@ -4464,15 +4480,8 @@ static int mgbe_write_phy_reg(struct osi_core_priv_data *osi_core, * 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); - } + 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); @@ -4541,15 +4550,8 @@ static int mgbe_read_phy_reg(struct osi_core_priv_data *osi_core, * 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); - } + 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); @@ -4570,6 +4572,7 @@ static int mgbe_read_phy_reg(struct osi_core_priv_data *osi_core, return (int)data; } +#ifndef OSI_STRIPPED_LIB /** * @brief mgbe_hw_est_write - indirect write the GCL to Software own list * (SWOL) @@ -5028,6 +5031,7 @@ static void mgbe_configure_eee(struct osi_core_priv_data *const osi_core, mgbe_disable_tx_lpi(osi_core); } } +#endif /* !OSI_STRIPPED_LIB */ static int mgbe_get_hw_features(struct osi_core_priv_data *const osi_core, struct osi_hw_features *hw_feat) @@ -5591,12 +5595,7 @@ static void mgbe_config_ssir(struct osi_core_priv_data *const osi_core, * 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; - } + val = OSI_PTP_SSINC_4; } else { val = ((1U * OSI_NSEC_PER_SEC) / ptp_clock); } @@ -5700,6 +5699,7 @@ static nveu32_t mgbe_write_macsec_reg(struct osi_core_priv_data *const osi_core, } #endif /* MACSEC_SUPPORT */ +#ifndef OSI_STRIPPED_LIB /** * @brief mgbe_validate_core_regs - Validates MGBE core registers. * @@ -5781,8 +5781,9 @@ static void mgbe_set_mdc_clk_rate(OSI_UNUSED const nveu64_t csr_clk_rate) { } +#endif /* !OSI_STRIPPED_LIB */ -#ifdef MACSEC_SUPPORT +#if defined(MACSEC_SUPPORT) && !defined(OSI_STRIPPED_LIB) /** * @brief mgbe_config_for_macsec - Configure MAC according to macsec IAS * @@ -5888,55 +5889,59 @@ void mgbe_init_core_ops(struct core_ops *ops) { ops->core_init = mgbe_core_init; ops->core_deinit = mgbe_core_deinit; - ops->validate_regs = mgbe_validate_core_regs; ops->handle_common_intr = mgbe_handle_common_intr; ops->pad_calibrate = mgbe_pad_calibrate; - ops->set_mdc_clk_rate = mgbe_set_mdc_clk_rate; - 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_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->set_systime_to_mac = mgbe_set_systime_to_mac; + ops->config_addend = mgbe_config_addend; + ops->config_tscr = mgbe_config_tscr; + ops->config_ssir = mgbe_config_ssir, + ops->adjust_mactime = mgbe_adjust_mactime; + ops->read_mmc = mgbe_read_mmc; + ops->write_phy_reg = mgbe_write_phy_reg; + ops->read_phy_reg = mgbe_read_phy_reg; + ops->get_hw_features = mgbe_get_hw_features; + ops->ptp_tsc_capture = mgbe_ptp_tsc_capture; + ops->update_ip4_addr = mgbe_update_ip4_addr; + ops->read_reg = mgbe_read_reg; + ops->write_reg = mgbe_write_reg; +#ifdef MACSEC_SUPPORT + ops->read_macsec_reg = mgbe_read_macsec_reg; + ops->write_macsec_reg = mgbe_write_macsec_reg; +#ifndef OSI_STRIPPED_LIB + ops->macsec_config_mac = mgbe_config_for_macsec; +#endif /* !OSI_STRIPPED_LIB */ +#endif /* MACSEC_SUPPORT */ +#ifndef OSI_STRIPPED_LIB + 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_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_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->validate_regs = mgbe_validate_core_regs; + ops->set_avb_algorithm = mgbe_set_avb_algorithm; + ops->get_avb_algorithm = mgbe_get_avb_algorithm, 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->save_registers = mgbe_save_registers; + ops->restore_registers = mgbe_restore_registers; + ops->set_mdc_clk_rate = mgbe_set_mdc_clk_rate; + ops->config_mac_loopback = mgbe_config_mac_loopback; 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 */ + ops->config_rss = mgbe_config_rss; + ops->config_ptp_rxq = mgbe_config_ptp_rxq; +#endif /* !OSI_STRIPPED_LIB */ #ifdef HSI_SUPPORT ops->core_hsi_configure = mgbe_hsi_configure; #endif diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index d1a4ecd..70416eb 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -137,18 +137,20 @@ static nve32_t osi_hal_init_core_ops(struct osi_core_priv_data *const osi_core) { struct core_local *l_core = (struct core_local *)(void *)osi_core; typedef void (*init_ops_arr)(struct core_ops *local_ops); +#ifndef OSI_STRIPPED_LIB typedef void *(*safety_init)(void); - +#endif 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 } }; +#ifndef OSI_STRIPPED_LIB 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 } }; - +#endif if (osi_core == OSI_NULL) { return -1; } @@ -184,11 +186,12 @@ static nve32_t osi_hal_init_core_ops(struct osi_core_priv_data *const osi_core) i_ops[osi_core->mac][osi_core->use_virtualization](&g_ops[osi_core->mac]); } +#ifndef OSI_STRIPPED_LIB 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](); } - +#endif 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); @@ -201,6 +204,7 @@ static nve32_t osi_hal_init_core_ops(struct osi_core_priv_data *const osi_core) return 0; } +#ifndef OSI_STRIPPED_LIB /** * @brief init_vlan_filters - Helper function to init all VLAN SW information. * @@ -219,6 +223,7 @@ static inline void init_vlan_filters(struct osi_core_priv_data *const osi_core) osi_core->vf_bitmap = 0U; osi_core->vlan_filter_cnt = 0U; } +#endif 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) @@ -230,10 +235,12 @@ nve32_t osi_hal_hw_core_init(struct osi_core_priv_data *const osi_core, return -1; } +#ifndef OSI_STRIPPED_LIB init_vlan_filters(osi_core); /* Init FRP */ init_frp(osi_core); +#endif /* !OSI_STRIPPED_LIB */ ret = l_core->ops_p->core_init(osi_core, tx_fifo_size, rx_fifo_size); if (ret < 0) { @@ -268,32 +275,6 @@ nve32_t osi_hal_hw_core_deinit(struct osi_core_priv_data *const osi_core) return 0; } -nve32_t osi_start_mac(struct osi_core_priv_data *const osi_core) -{ - struct core_local *l_core = (struct core_local *)(void *)osi_core; - - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - - hw_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 *)(void *)osi_core; - - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - - hw_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 *)(void *)osi_core; @@ -307,41 +288,7 @@ nve32_t osi_common_isr(struct osi_core_priv_data *const 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 *)(void *)osi_core; - - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - - return hw_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 *)(void *)osi_core; - - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - - return hw_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 *)(void *)osi_core; - - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - - return l_core->ops_p->pad_calibrate(osi_core); -} - +#ifndef OSI_STRIPPED_LIB static nve32_t conf_ptp_offload(struct osi_core_priv_data *const osi_core, struct osi_pto_config *const pto_config) { @@ -421,6 +368,7 @@ static nve32_t conf_ptp_offload(struct osi_core_priv_data *const osi_core, return ret; } +#endif /* !OSI_STRIPPED_LIB */ nve32_t osi_l2_filter(struct osi_core_priv_data *const osi_core, const struct osi_filter *filter) @@ -465,6 +413,7 @@ nve32_t osi_l2_filter(struct osi_core_priv_data *const osi_core, return ret; } +#ifndef OSI_STRIPPED_LIB /** * @brief helper_l4_filter helper function for l4 filtering * @@ -514,6 +463,7 @@ static inline nve32_t helper_l4_filter( l_filter->port_no, l_filter->src_dst_addr_match); } +#endif /* !OSI_STRIPPED_LIB */ /** * @brief helper_l3_filter helper function for l3 filtering @@ -560,8 +510,10 @@ static inline nve32_t helper_l3_filter( } if (type == OSI_IP6_FILTER) { +#ifndef OSI_STRIPPED_LIB ret = ops_p->update_ip6_addr(osi_core, l_filter->filter_no, l_filter->ip6_addr); +#endif /* !OSI_STRIPPED_LIB */ } else if (type == OSI_IP4_FILTER) { ret = ops_p->update_ip4_addr(osi_core, l_filter->filter_no, l_filter->ip4_addr, @@ -575,10 +527,10 @@ static inline nve32_t helper_l3_filter( return ret; } -nve32_t osi_l3l4_filter(struct osi_core_priv_data *const osi_core, - struct osi_l3_l4_filter *const l_filter, - const nveu32_t type, const nveu32_t dma_routing_enable, - const nveu32_t dma_chan, const nveu32_t is_l4_filter) +static nve32_t osi_l3l4_filter(struct osi_core_priv_data *const osi_core, + struct osi_l3_l4_filter *const 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 *)(void *)osi_core; nve32_t ret = -1; @@ -596,8 +548,10 @@ nve32_t osi_l3l4_filter(struct osi_core_priv_data *const osi_core, } if (is_l4_filter == OSI_ENABLE) { +#ifndef OSI_STRIPPED_LIB ret = helper_l4_filter(osi_core, l_core->ops_p, l_filter, type, dma_routing_enable, dma_chan); +#endif /* !OSI_STRIPPED_LIB */ } else { ret = helper_l3_filter(osi_core, l_core->ops_p, l_filter, type, dma_routing_enable, dma_chan); @@ -790,28 +744,17 @@ nve32_t osi_ptp_configuration(struct osi_core_priv_data *const osi_core, /* disable hw time stamping */ /* Program MAC_Timestamp_Control Register */ l_core->ops_p->config_tscr(osi_core, OSI_DISABLE); +#ifndef OSI_STRIPPED_LIB /* Disable PTP RX Queue routing */ ret = l_core->ops_p->config_ptp_rxq(osi_core, osi_core->ptp_config.ptp_rx_queue, OSI_DISABLE); +#endif /* !OSI_STRIPPED_LIB */ } 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); @@ -822,15 +765,9 @@ nve32_t osi_ptp_configuration(struct osi_core_priv_data *const osi_core, * 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; - } + 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); @@ -859,10 +796,12 @@ nve32_t osi_ptp_configuration(struct osi_core_priv_data *const osi_core, osi_core->ptp_config.sec, osi_core->ptp_config.nsec); if (ret == 0) { +#ifndef OSI_STRIPPED_LIB /* Enable PTP RX Queue routing */ ret = l_core->ops_p->config_ptp_rxq(osi_core, osi_core->ptp_config.ptp_rx_queue, OSI_ENABLE); +#endif /* !OSI_STRIPPED_LIB */ } } } @@ -870,6 +809,46 @@ nve32_t osi_ptp_configuration(struct osi_core_priv_data *const osi_core, return ret; } +nve32_t osi_read_mmc(struct osi_core_priv_data *const osi_core) +{ + struct core_local *l_core = (struct core_local *)(void *)osi_core; + + if (validate_args(osi_core, l_core) < 0) { + return -1; + } + + l_core->ops_p->read_mmc(osi_core); + + return 0; +} + +static 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 *)(void *)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 = osi_readla(osi_core, ((nveu8_t *)osi_core->base + (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 rxq_route_config - Enable PTP RX packets routing * @@ -901,47 +880,7 @@ static nve32_t rxq_route_config(struct osi_core_priv_data *const osi_core, rxq_route->enable); } -nve32_t osi_read_mmc(struct osi_core_priv_data *const osi_core) -{ - struct core_local *l_core = (struct core_local *)(void *)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 *)(void *)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. * @@ -1251,7 +1190,6 @@ static nve32_t conf_mac_loopback(struct osi_core_priv_data *const osi_core, 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 @@ -1361,6 +1299,7 @@ static nve32_t config_fpe(struct osi_core_priv_data *osi_core, return l_core->ops_p->hw_config_fpe(osi_core, fpe); } +#endif /* !OSI_STRIPPED_LIB */ /** * @brief Free stale timestamps for channel @@ -1465,9 +1404,11 @@ static inline nve32_t get_tx_ts(struct osi_core_priv_data *osi_core, 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); +#ifndef OSI_STRIPPED_LIB osi_core->xstats.ts_lock_del_fail = osi_update_stats_counter( osi_core->xstats.ts_lock_del_fail, 1U); +#endif goto done; } @@ -1663,26 +1604,6 @@ static void cfg_l3_l4_filter(struct core_local *l_core) } } -static void cfg_fc(struct core_local *l_core) -{ - (void)l_core->ops_p->config_flow_control((struct osi_core_priv_data *)(void *)l_core, - l_core->cfg.flow_ctrl); -} - -static void cfg_avb(struct core_local *l_core) -{ - nveu32_t i; - - for (i = 0U; i < OSI_MGBE_MAX_NUM_QUEUES; i++) { - if (l_core->cfg.avb[i].used == OSI_DISABLE) { - continue; - } - - (void)l_core->ops_p->set_avb_algorithm((struct osi_core_priv_data *)(void *)l_core, - &l_core->cfg.avb[i].avb_info); - } -} - static void cfg_l2_filter(struct core_local *l_core) { nveu32_t i; @@ -1706,6 +1627,7 @@ static void cfg_rxcsum(struct core_local *l_core) l_core->cfg.rxcsum); } +#ifndef OSI_STRIPPED_LIB static void cfg_vlan(struct core_local *l_core) { nveu32_t i; @@ -1720,6 +1642,26 @@ static void cfg_vlan(struct core_local *l_core) } } +static void cfg_fc(struct core_local *l_core) +{ + (void)l_core->ops_p->config_flow_control((struct osi_core_priv_data *)(void *)l_core, + l_core->cfg.flow_ctrl); +} + +static void cfg_avb(struct core_local *l_core) +{ + nveu32_t i; + + for (i = 0U; i < OSI_MGBE_MAX_NUM_QUEUES; i++) { + if (l_core->cfg.avb[i].used == OSI_DISABLE) { + continue; + } + + (void)l_core->ops_p->set_avb_algorithm((struct osi_core_priv_data *)(void *)l_core, + &l_core->cfg.avb[i].avb_info); + } +} + static void cfg_eee(struct core_local *l_core) { (void)conf_eee((struct osi_core_priv_data *)(void *)l_core, @@ -1727,17 +1669,6 @@ static void cfg_eee(struct core_local *l_core) l_core->cfg.tx_lpi_timer); } -static void cfg_ptp(struct core_local *l_core) -{ - struct osi_core_priv_data *osi_core = (struct osi_core_priv_data *)(void *)l_core; - struct osi_ioctl ioctl_data = {}; - - ioctl_data.arg1_u32 = l_core->cfg.ptp; - ioctl_data.cmd = OSI_CMD_CONFIG_PTP; - - (void)osi_handle_ioctl(osi_core, &ioctl_data); -} - static void cfg_est(struct core_local *l_core) { (void)config_est((struct osi_core_priv_data *)(void *)l_core, @@ -1749,14 +1680,36 @@ static void cfg_fpe(struct core_local *l_core) (void)config_fpe((struct osi_core_priv_data *)(void *)l_core, &l_core->cfg.fpe); } +#endif /* !OSI_STRIPPED_LIB */ + +static void cfg_ptp(struct core_local *l_core) +{ + struct osi_core_priv_data *osi_core = (struct osi_core_priv_data *)(void *)l_core; + struct osi_ioctl ioctl_data = {}; + + ioctl_data.arg1_u32 = l_core->cfg.ptp; + ioctl_data.cmd = OSI_CMD_CONFIG_PTP; + + (void)osi_handle_ioctl(osi_core, &ioctl_data); +} static void apply_dynamic_cfg(struct osi_core_priv_data *osi_core) { struct core_local *l_core = (struct core_local *)(void *)osi_core; typedef void (*cfg_fn)(struct core_local *local_core); const cfg_fn fn[] = { - cfg_l3_l4_filter, cfg_fc, cfg_avb, cfg_l2_filter, - cfg_rxcsum, cfg_vlan, cfg_eee, cfg_ptp, cfg_est, cfg_fpe + [DYNAMIC_CFG_L3_L4_IDX] = cfg_l3_l4_filter, + [DYNAMIC_CFG_L2_IDX] = cfg_l2_filter, + [DYNAMIC_CFG_RXCSUM_IDX] = cfg_rxcsum, +#ifndef OSI_STRIPPED_LIB + [DYNAMIC_CFG_VLAN_IDX] = cfg_vlan, + [DYNAMIC_CFG_FC_IDX] = cfg_fc, + [DYNAMIC_CFG_AVB_IDX] = cfg_avb, + [DYNAMIC_CFG_EEE_IDX] = cfg_eee, + [DYNAMIC_CFG_EST_IDX] = cfg_est, + [DYNAMIC_CFG_FPE_IDX] = cfg_fpe, +#endif /* !OSI_STRIPPED_LIB */ + [DYNAMIC_CFG_PTP_IDX] = cfg_ptp }; nveu32_t flags = l_core->cfg.flags; nveu32_t i = 0U; @@ -1841,11 +1794,6 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, } 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, @@ -1859,6 +1807,11 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, break; +#ifndef OSI_STRIPPED_LIB + case OSI_CMD_RESTORE_REGISTER: + ret = ops_p->restore_registers(osi_core); + break; + case OSI_CMD_MDC_CONFIG: ops_p->set_mdc_clk_rate(osi_core, data->arg5_u64); ret = 0; @@ -1929,9 +1882,6 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, ret = ops_p->config_tx_status(osi_core, data->arg1_u32); break; - case OSI_CMD_CONFIG_FW_ERR: - ret = hw_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, @@ -1956,6 +1906,10 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, break; #endif /* !OSI_STRIPPED_LIB */ + case OSI_CMD_CONFIG_FW_ERR: + ret = hw_config_fw_err_pkts(osi_core, data->arg1_u32, data->arg2_u32); + break; + case OSI_CMD_POLL_FOR_MAC_RST: ret = hw_poll_for_swr(osi_core); break; @@ -2206,6 +2160,7 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, } #endif break; +#ifndef OSI_STRIPPED_LIB case OSI_CMD_CONFIG_PTP_OFFLOAD: ret = conf_ptp_offload(osi_core, &data->pto_config); break; @@ -2241,7 +2196,7 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, } break; - +#endif /* !OSI_STRIPPED_LIB */ case OSI_CMD_READ_REG: ret = (nve32_t) ops_p->read_reg(osi_core, (nve32_t) data->arg1_u32); break; @@ -2334,24 +2289,6 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, 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 *)(void *)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; diff --git a/osi/core/vlan_filter.c b/osi/core/vlan_filter.c index e973bf3..b9b7b2a 100644 --- a/osi/core/vlan_filter.c +++ b/osi/core/vlan_filter.c @@ -23,6 +23,7 @@ #include "../osi/common/common.h" #include "vlan_filter.h" +#ifndef OSI_STRIPPED_LIB /** * @brief get_vlan_filter_idx - Get VLAN HW filter index which match vlan_id * @@ -475,3 +476,4 @@ int update_vlan_id(struct osi_core_priv_data *osi_core, return del_vlan_id(osi_core, ops_p, vlan_id); } +#endif /* !OSI_STRIPPED_LIB */ diff --git a/osi/core/xpcs.c b/osi/core/xpcs.c index 7eae067..f35d196 100644 --- a/osi/core/xpcs.c +++ b/osi/core/xpcs.c @@ -467,12 +467,10 @@ int xpcs_init(struct osi_core_priv_data *osi_core) 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; - } + 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 diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 5bd2280..2f4d0d4 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -168,7 +168,7 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, } rx_swcx = rx_ring->rx_swcx + rx_ring->cur_rx_idx; osi_memset(rx_pkt_cx, 0U, sizeof(*rx_pkt_cx)); -#ifdef OSI_DEBUG +#if defined OSI_DEBUG && !defined OSI_STRIPPED_LIB 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); From 0e6dd5414dfda32d0c836642a8030a10c9c2d737 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Tue, 12 Jul 2022 07:06:19 +0530 Subject: [PATCH 380/458] osi: dma: compile out not required code for Safety QNX Bug 200770328 Change-Id: I8ee51c89954b47ceff5e261b6a2d8cc6b3f16f36 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2735897 Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_dma.h | 32 +++++++--- include/osi_dma_txrx.h | 4 +- osi/dma/Makefile.interface.tmk | 4 ++ osi/dma/Makefile.tmk | 3 +- osi/dma/dma_local.h | 2 + osi/dma/eqos_desc.c | 36 +++++++----- osi/dma/eqos_dma.c | 4 ++ osi/dma/libnvethernetcl_safety.export | 39 +++++++++++++ osi/dma/mgbe_desc.c | 61 ++++++++++--------- osi/dma/mgbe_dma.c | 4 ++ osi/dma/osi_dma.c | 4 +- osi/dma/osi_dma_txrx.c | 84 ++++++++++++--------------- 12 files changed, 175 insertions(+), 102 deletions(-) create mode 100644 osi/dma/libnvethernetcl_safety.export diff --git a/include/osi_dma.h b/include/osi_dma.h index 33aaec6..7284bef 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -252,6 +252,7 @@ */ #define OSI_TX_MAX_BUFF_SIZE 0x3FFFU +#ifndef OSI_STRIPPED_LIB /** * @brief OSI packet error stats */ @@ -295,6 +296,7 @@ struct osi_pkt_err_stats { /** FRP Incomplete Parsing */ unsigned long frp_incomplete; }; +#endif /* !OSI_STRIPPED_LIB */ /** * @brief Receive Descriptor @@ -333,16 +335,18 @@ struct osi_rx_pkt_cx { 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; + /** TS in nsec for the received packet */ + nveul64_t ns; +#ifndef OSI_STRIPPED_LIB + /** Stores the VLAN tag ID in received packet */ + nveu32_t vlan_tag; /** 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; +#endif /* !OSI_STRIPPED_LIB */ }; /** @@ -374,9 +378,11 @@ struct osi_tx_swcx { void *buf_virt_addr; /** Length of buffer */ nveu32_t len; +#ifndef OSI_STRIPPED_LIB /** Flag to keep track of whether buffer pointed by buf_phy_addr * is a paged buffer/linear buffer */ nveu32_t is_paged_buf; +#endif /* !OSI_STRIPPED_LIB */ /** Flag to keep track of SWCX * Bit 0 is_paged_buf - whether buffer pointed by buf_phy_addr * is a paged buffer/linear buffer @@ -456,10 +462,12 @@ struct osi_tx_ring { nveu32_t cur_tx_idx; /** Descriptor index for descriptor cleanup */ nveu32_t clean_idx; +#ifndef OSI_STRIPPED_LIB /** Slot function check */ nveu32_t slot_check; /** Slot number */ nveu32_t slot_number; +#endif /* !OSI_STRIPPED_LIB */ /** Transmit packet context */ struct osi_tx_pkt_cx tx_pkt_cx; /** Transmit complete packet context information */ @@ -468,6 +476,7 @@ struct osi_tx_ring { nveu32_t frame_cnt; }; +#ifndef OSI_STRIPPED_LIB /** * @brief osi_xtra_dma_stat_counters - OSI DMA extra stats counters */ @@ -489,6 +498,7 @@ struct osi_xtra_dma_stat_counters { /** Total number of TSO packet count */ nveu64_t tx_tso_pkt_n; }; +#endif /* !OSI_STRIPPED_LIB */ struct osi_dma_priv_data; @@ -522,6 +532,7 @@ struct osd_dma_ops { #endif /* OSI_DEBUG */ }; +#ifdef OSI_DEBUG /** * @brief The OSI DMA IOCTL data structure. */ @@ -531,6 +542,7 @@ struct osi_dma_ioctl_data { /** IOCTL command argument */ nveu32_t arg_u32; }; +#endif /* OSI_DEBUG */ /** * @brief The OSI DMA private data structure. @@ -554,10 +566,12 @@ struct osi_dma_priv_data { nveu32_t rx_buf_len; /** MTU size */ nveu32_t mtu; +#ifndef OSI_STRIPPED_LIB /** Packet error stats */ struct osi_pkt_err_stats pkt_err_stats; /** Extra DMA stats */ struct osi_xtra_dma_stat_counters dstats; +#endif /* !OSI_STRIPPED_LIB */ /** Receive Interrupt Watchdog Timer Count Units */ nveu32_t rx_riwt; /** Flag which decides riwt is enabled(1) or disabled(0) */ @@ -574,18 +588,20 @@ struct osi_dma_priv_data { nveu32_t tx_frames; /** Flag which decides tx_frames is enabled(1) or disabled(0) */ nveu32_t use_tx_frames; + /** DMA callback ops structure */ + struct osd_dma_ops osd_ops; +#ifndef OSI_STRIPPED_LIB /** Flag which decides virtualization is enabled(1) or disabled(0) */ nveu32_t use_virtualization; /** 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; +#endif /* !OSI_STRIPPED_LIB */ /** PTP flags * OSI_PTP_SYNC_MASTER - acting as master * OSI_PTP_SYNC_SLAVE - acting as slave @@ -593,9 +609,9 @@ struct osi_dma_priv_data { * OSI_PTP_SYNC_TWOSTEP - two step mode */ unsigned int ptp_flag; +#ifdef OSI_DEBUG /** 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 */ @@ -1086,6 +1102,7 @@ nveu32_t osi_is_mac_enabled(struct osi_dma_priv_data *const osi_dma); nve32_t osi_handle_dma_intr(struct osi_dma_priv_data *osi_dma, nveu32_t chan, nveu32_t tx_rx, nveu32_t en_dis); +#ifdef OSI_DEBUG /** * @brief osi_dma_ioctl - OSI DMA IOCTL * @@ -1102,6 +1119,7 @@ nve32_t osi_handle_dma_intr(struct osi_dma_priv_data *osi_dma, * @retval -1 on failure. */ nve32_t osi_dma_ioctl(struct osi_dma_priv_data *osi_dma); +#endif /* OSI_DEBUG */ #ifndef OSI_STRIPPED_LIB /** * @brief osi_clear_tx_pkt_err_stats - Clear tx packet error stats. diff --git a/include/osi_dma_txrx.h b/include/osi_dma_txrx.h index 97b3607..35834b6 100644 --- a/include/osi_dma_txrx.h +++ b/include/osi_dma_txrx.h @@ -49,9 +49,11 @@ #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 +#ifdef OSI_DEBUG /** Decrement the tx descriptor index */ #define DECR_TX_DESC_INDEX(idx, x) ((idx) = ((idx) - (1U)) & ((x) - 1U)) +#endif /* OSI_DEBUG */ +#ifndef OSI_STRIPPED_LIB /** Decrement the rx descriptor index */ #define DECR_RX_DESC_INDEX(idx, x) ((idx) = ((idx) - (1U)) & ((x) - 1U)) #endif /* !OSI_STRIPPED_LIB */ diff --git a/osi/dma/Makefile.interface.tmk b/osi/dma/Makefile.interface.tmk index c12901e..5df87ee 100644 --- a/osi/dma/Makefile.interface.tmk +++ b/osi/dma/Makefile.interface.tmk @@ -26,7 +26,11 @@ ifdef NV_INTERFACE_FLAG_SHARED_LIBRARY_SECTION NV_INTERFACE_NAME := nvethernetcl +ifeq ($(NV_BUILD_CONFIGURATION_IS_SAFETY), 0) NV_INTERFACE_EXPORTS := lib$(NV_INTERFACE_NAME) +else +NV_INTERFACE_EXPORTS := lib$(NV_INTERFACE_NAME)_safety +endif NV_INTERFACE_PUBLIC_INCLUDES := \ ./include endif diff --git a/osi/dma/Makefile.tmk b/osi/dma/Makefile.tmk index 7e1e52d..7b82994 100644 --- a/osi/dma/Makefile.tmk +++ b/osi/dma/Makefile.tmk @@ -47,9 +47,10 @@ NV_COMPONENT_INCLUDES := \ ifeq ($(NV_BUILD_CONFIGURATION_IS_SAFETY),0) NV_COMPONENT_CFLAGS += -DOSI_DEBUG +else +NV_COMPONENT_CFLAGS += -DOSI_STRIPPED_LIB endif - include $(NV_BUILD_SHARED_LIBRARY) endif diff --git a/osi/dma/dma_local.h b/osi/dma/dma_local.h index dc531c4..07cd21c 100644 --- a/osi/dma/dma_local.h +++ b/osi/dma/dma_local.h @@ -68,6 +68,7 @@ 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); +#ifndef OSI_STRIPPED_LIB /** Called to get rx error stats */ void (*update_rx_err_stats)(struct osi_rx_desc *rx_desc, struct osi_pkt_err_stats *stats); @@ -77,6 +78,7 @@ struct desc_ops { /** 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); +#endif /* !OSI_STRIPPED_LIB */ /** Called to get RX hw timestamp */ int (*get_rx_hwstamp)(struct osi_dma_priv_data *osi_dma, struct osi_rx_desc *rx_desc, diff --git a/osi/dma/eqos_desc.c b/osi/dma/eqos_desc.c index f45b200..54004d0 100644 --- a/osi/dma/eqos_desc.c +++ b/osi/dma/eqos_desc.c @@ -23,6 +23,7 @@ #include "dma_local.h" #include "hw_desc.h" +#ifndef OSI_STRIPPED_LIB /** * @brief eqos_get_rx_vlan - Get Rx VLAN from descriptor * @@ -77,6 +78,22 @@ static inline void eqos_update_rx_err_stats(struct osi_rx_desc *rx_desc, } } +/** + * @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) +{ +} +#endif /* !OSI_STRIPPED_LIB */ + /** * @brief eqos_get_rx_csum - Get the Rx checksum from descriptor if valid * @@ -155,21 +172,6 @@ static void eqos_get_rx_csum(struct osi_rx_desc *rx_desc, } } -/** - * @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 * @@ -237,9 +239,11 @@ static int eqos_get_rx_hwstamp(struct osi_dma_priv_data *osi_dma, void eqos_init_desc_ops(struct desc_ops *d_ops) { - d_ops->get_rx_csum = eqos_get_rx_csum; +#ifndef OSI_STRIPPED_LIB 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; +#endif /* !OSI_STRIPPED_LIB */ + d_ops->get_rx_csum = eqos_get_rx_csum; d_ops->get_rx_hwstamp = eqos_get_rx_hwstamp; } diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index 115bedd..e9ff1a6 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -137,7 +137,11 @@ static void eqos_debug_intr_config(struct osi_dma_priv_data *osi_dma) * * @param[in] ops: DMA channel operations pointer. */ +#ifndef OSI_STRIPPED_LIB void eqos_init_dma_chan_ops(struct dma_chan_ops *ops) +#else +void eqos_init_dma_chan_ops(OSI_UNUSED struct dma_chan_ops *ops) +#endif /* !OSI_STRIPPED_LIB */ { #ifndef OSI_STRIPPED_LIB ops->config_slot = eqos_config_slot; diff --git a/osi/dma/libnvethernetcl_safety.export b/osi/dma/libnvethernetcl_safety.export new file mode 100644 index 0000000..5e62c6c --- /dev/null +++ b/osi/dma/libnvethernetcl_safety.export @@ -0,0 +1,39 @@ +################################### tell Emacs this is a -*- makefile-gmake -*- +# +# 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. +# +# libnvethernetcl safety interface export +# +############################################################################### +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 diff --git a/osi/dma/mgbe_desc.c b/osi/dma/mgbe_desc.c index ef12db5..7a3fb29 100644 --- a/osi/dma/mgbe_desc.c +++ b/osi/dma/mgbe_desc.c @@ -24,6 +24,7 @@ #include "hw_desc.h" #include "mgbe_desc.h" +#ifndef OSI_STRIPPED_LIB /** * @brief mgbe_get_rx_vlan - Get Rx VLAN from descriptor * @@ -94,34 +95,6 @@ static inline void mgbe_update_rx_err_stats(struct osi_rx_desc *rx_desc, } } -/** - * @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 * @@ -157,7 +130,35 @@ static void mgbe_get_rx_hash(struct osi_rx_desc *rx_desc, rx_pkt_cx->rx_hash = rx_desc->rdes1; rx_pkt_cx->flags |= OSI_PKT_CX_RSS; } +#endif /* !OSI_STRIPPED_LIB */ +/** + * @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_hwstamp - Get Rx HW Time stamp * @@ -222,9 +223,11 @@ static int mgbe_get_rx_hwstamp(struct osi_dma_priv_data *osi_dma, void mgbe_init_desc_ops(struct desc_ops *d_ops) { - d_ops->get_rx_csum = mgbe_get_rx_csum; +#ifndef OSI_STRIPPED_LIB 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; +#endif /* !OSI_STRIPPED_LIB */ + d_ops->get_rx_csum = mgbe_get_rx_csum; d_ops->get_rx_hwstamp = mgbe_get_rx_hwstamp; } diff --git a/osi/dma/mgbe_dma.c b/osi/dma/mgbe_dma.c index 95eb967..c061e31 100644 --- a/osi/dma/mgbe_dma.c +++ b/osi/dma/mgbe_dma.c @@ -118,7 +118,11 @@ static void mgbe_debug_intr_config(struct osi_dma_priv_data *osi_dma) } #endif +#ifndef OSI_STRIPPED_LIB void mgbe_init_dma_chan_ops(struct dma_chan_ops *ops) +#else +void mgbe_init_dma_chan_ops(OSI_UNUSED struct dma_chan_ops *ops) +#endif { #ifndef OSI_STRIPPED_LIB ops->config_slot = mgbe_config_slot; diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index fb672a2..8d5c817 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -901,6 +901,7 @@ nve32_t osi_hw_transmit(struct osi_dma_priv_data *osi_dma, nveu32_t chan) return hw_transmit(osi_dma, osi_dma->tx_ring[chan], chan); } +#ifdef OSI_DEBUG nve32_t osi_dma_ioctl(struct osi_dma_priv_data *osi_dma) { struct dma_local *l_dma = (struct dma_local *)osi_dma; @@ -913,7 +914,6 @@ nve32_t osi_dma_ioctl(struct osi_dma_priv_data *osi_dma) data = &osi_dma->ioctl_data; switch (data->cmd) { -#ifdef OSI_DEBUG case OSI_DMA_IOCTL_CMD_REG_DUMP: reg_dump(osi_dma); break; @@ -923,7 +923,6 @@ nve32_t osi_dma_ioctl(struct osi_dma_priv_data *osi_dma) case OSI_DMA_IOCTL_CMD_DEBUG_INTR_CONFIG: l_dma->ops_p->debug_intr_config(osi_dma); break; -#endif /* OSI_DEBUG */ default: OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "DMA: Invalid IOCTL command", 0ULL); @@ -932,6 +931,7 @@ nve32_t osi_dma_ioctl(struct osi_dma_priv_data *osi_dma) return 0; } +#endif /* OSI_DEBUG */ #ifndef OSI_STRIPPED_LIB diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 2f4d0d4..b5889a5 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -32,47 +32,6 @@ static struct desc_ops d_ops[MAX_MAC_IP_TYPES]; -#ifdef OSI_DEBUG -/** - * @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); - } -} -#endif - /** * @brief validate_rx_completions_arg- Validate input argument of rx_completions * @@ -141,7 +100,9 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, struct osi_rx_desc *context_desc = OSI_NULL; nveu32_t ip_type = osi_dma->mac; nve32_t received = 0; +#ifndef OSI_STRIPPED_LIB nve32_t received_resv = 0; +#endif /* !OSI_STRIPPED_LIB */ nve32_t ret = 0; ret = validate_rx_completions_arg(osi_dma, chan, more_data_avail, @@ -159,7 +120,11 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, /* Reset flag to indicate if more Rx frames available to OSD layer */ *more_data_avail = OSI_NONE; - while ((received < budget) && (received_resv < budget)) { + while ((received < budget) +#ifndef OSI_STRIPPED_LIB + && (received_resv < budget) +#endif /* !OSI_STRIPPED_LIB */ + ) { rx_desc = rx_ring->rx_desc + rx_ring->cur_rx_idx; /* check for data availability */ @@ -177,6 +142,7 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, INCR_RX_DESC_INDEX(rx_ring->cur_rx_idx, osi_dma->rx_ring_sz); +#ifndef OSI_STRIPPED_LIB if (osi_unlikely(rx_swcx->buf_virt_addr == osi_dma->resv_buf_virt_addr)) { rx_swcx->buf_virt_addr = OSI_NULL; @@ -189,6 +155,7 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, } continue; } +#endif /* !OSI_STRIPPED_LIB */ /* packet already processed */ if ((rx_swcx->flags & OSI_RX_SWCX_PROCESSED) == @@ -229,19 +196,22 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, * are set */ rx_pkt_cx->flags &= ~OSI_PKT_CX_VALID; +#ifndef OSI_STRIPPED_LIB d_ops[ip_type].update_rx_err_stats(rx_desc, &osi_dma->pkt_err_stats); +#endif /* !OSI_STRIPPED_LIB */ } /* Check if COE Rx checksum is valid */ d_ops[ip_type].get_rx_csum(rx_desc, rx_pkt_cx); +#ifndef OSI_STRIPPED_LIB /* 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); - +#endif /* !OSI_STRIPPED_LIB */ 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, @@ -281,15 +251,18 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, return -1; } } +#ifndef OSI_STRIPPED_LIB 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); +#endif /* !OSI_STRIPPED_LIB */ received++; } +#ifndef OSI_STRIPPED_LIB /* 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. @@ -306,10 +279,11 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, *more_data_avail = OSI_ENABLE; } } - +#endif /* !OSI_STRIPPED_LIB */ return received; } +#ifndef OSI_STRIPPED_LIB /** * @brief inc_tx_pkt_stats - Increment Tx packet count Stats * @@ -439,7 +413,6 @@ static inline void get_tx_err_stats(struct osi_tx_desc *tx_desc, } } -#ifndef OSI_STRIPPED_LIB nve32_t osi_clear_tx_pkt_err_stats(struct osi_dma_priv_data *osi_dma) { nve32_t ret = -1; @@ -568,9 +541,10 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, txdone_pkt_cx = &tx_ring->txdone_pkt_cx; entry = tx_ring->clean_idx; +#ifndef OSI_STRIPPED_LIB osi_dma->dstats.tx_clean_n[chan] = osi_update_stats_counter(osi_dma->dstats.tx_clean_n[chan], 1U); - +#endif /* !OSI_STRIPPED_LIB */ 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)); @@ -594,11 +568,15 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, if (((tx_desc->tdes3 & TDES3_ES_BITS) != 0U) && (osi_dma->mac != OSI_MAC_HW_MGBE)) { txdone_pkt_cx->flags |= OSI_TXDONE_CX_ERROR; +#ifndef OSI_STRIPPED_LIB /* fill packet error stats */ get_tx_err_stats(tx_desc, &osi_dma->pkt_err_stats); +#endif /* !OSI_STRIPPED_LIB */ } else { +#ifndef OSI_STRIPPED_LIB inc_tx_pkt_stats(osi_dma, chan); +#endif /* !OSI_STRIPPED_LIB */ } if (processed < INT_MAX) { @@ -815,11 +793,19 @@ static inline unsigned int is_ptp_onestep_and_master_mode(unsigned int ptp_flag) * @param[in, out] tx_desc: Pointer to transmit descriptor to be filled. * @param[in] tx_swcx: Pointer to corresponding tx descriptor software context. */ +#ifndef OSI_STRIPPED_LIB 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) +#else +static inline void fill_first_desc(OSI_UNUSED 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) +#endif /* !OSI_STRIPPED_LIB */ { tx_desc->tdes0 = L32(tx_swcx->buf_phy_addr); tx_desc->tdes1 = H32(tx_swcx->buf_phy_addr); @@ -878,6 +864,7 @@ static inline void fill_first_desc(struct osi_tx_ring *tx_ring, tx_desc->tdes3 &= ~TDES3_TPL_MASK; tx_desc->tdes3 |= tx_pkt_cx->payload_len; } else { +#ifndef OSI_STRIPPED_LIB if ((tx_ring->slot_check == OSI_ENABLE) && (tx_ring->slot_number < OSI_SLOT_NUM_MAX)) { /* Fill Slot number */ @@ -886,6 +873,7 @@ static inline void fill_first_desc(struct osi_tx_ring *tx_ring, tx_ring->slot_number = ((tx_ring->slot_number + 1U) % OSI_SLOT_NUM_MAX); } +#endif /* !OSI_STRIPPED_LIB */ } } @@ -1015,6 +1003,7 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, return -1; } +#ifndef OSI_STRIPPED_LIB /* 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 = @@ -1027,6 +1016,7 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, osi_update_stats_counter(osi_dma->dstats.tx_tso_pkt_n, 1UL); } +#endif /* !OSI_STRIPPED_LIB */ cntx_desc_consumed = need_cntx_desc(tx_pkt_cx, tx_swcx, tx_desc, osi_dma->ptp_flag, osi_dma->mac); @@ -1406,9 +1396,11 @@ static nve32_t tx_dma_desc_init(struct osi_dma_priv_data *osi_dma) tx_ring->cur_tx_idx = 0; tx_ring->clean_idx = 0; +#ifndef OSI_STRIPPED_LIB /* Slot function parameter initialization */ tx_ring->slot_number = 0U; tx_ring->slot_check = OSI_DISABLE; +#endif /* !OSI_STRIPPED_LIB */ set_tx_ring_len_and_start_addr(osi_dma, tx_ring->tx_desc_phy_addr, chan, (osi_dma->tx_ring_sz - 1U)); From 65bab3e41e62ce39b6c0e76d096b27520fb196ca Mon Sep 17 00:00:00 2001 From: Mahesh Patil <maheshp@nvidia.com> Date: Thu, 14 Jul 2022 21:40:52 +0000 Subject: [PATCH 381/458] osi: core: Change macsec log level Change macsec log level for general prints and disable DEBUG_MACSEC macro for safety build Bug 3708920 Change-Id: Iec9b28d0e1eeb4ceb17767d7311cb7945a42009d Signed-off-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2745325 Reviewed-by: Nagaraj Annaiah <nannaiah@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit --- osi/core/macsec.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/osi/core/macsec.c b/osi/core/macsec.c index f382447..ad5605a 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -29,14 +29,14 @@ #if defined(DEBUG_MACSEC) && defined(QNX_OS) #define LOG(...) \ { \ - slogf(0, 2, ##__VA_ARGS__); \ + slogf(0, 6, ##__VA_ARGS__); \ } #elif defined(DEBUG_MACSEC) && defined(LINUX_OS) #include <linux/printk.h> #define LOG(...) \ { \ - pr_err(__VA_ARGS__); \ + pr_debug(__VA_ARGS__); \ } #else #define LOG(...) @@ -803,26 +803,21 @@ static nve32_t macsec_enable(struct osi_core_priv_data *const osi_core, } val = osi_readla(osi_core, base + MACSEC_CONTROL0); - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "Read MACSEC_CONTROL0: \n", val); + LOG("Read MACSEC_CONTROL0: 0x%x \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); + LOG("Enabling macsec TX\n"); val |= (MACSEC_TX_EN); } else { - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "Disabling macsec TX \n", 0ULL); + LOG("Disabling macsec TX\n"); 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); + LOG("Enabling macsec RX\n"); val |= (MACSEC_RX_EN); } else { - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "Disabling macsec RX \n", 0ULL); + LOG("Disabling macsec RX\n"); val &= ~(MACSEC_RX_EN); } From f8558df3b95fb7260bc81247384a5753ef337234 Mon Sep 17 00:00:00 2001 From: Nagaraj Annaiah <nannaiah@nvidia.com> Date: Wed, 29 Jun 2022 19:07:34 +0000 Subject: [PATCH 382/458] osi: core: xpcs: Reduce PCS lock time out. Issue: Longer PCS delay causes IVC time out. Fix: Reduce PCS delay loop to 5 Micro sec. Bug 3688266 Change-Id: Ide7e90b2eb62034ad55ba406dbcfe1d56687573b Signed-off-by: Nagaraj Annaiah <nannaiah@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2737257 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/xpcs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osi/core/xpcs.c b/osi/core/xpcs.c index f35d196..7a50dc2 100644 --- a/osi/core/xpcs.c +++ b/osi/core/xpcs.c @@ -265,7 +265,7 @@ static nve32_t xpcs_uphy_lane_bring_up(struct osi_core_priv_data *osi_core, /* exit loop */ cond = COND_MET; } else { - osi_core->osd_ops.udelay(500U); + osi_core->osd_ops.udelay(5U); } } @@ -304,7 +304,7 @@ static nve32_t xpcs_check_pcs_lock_status(struct osi_core_priv_data *osi_core) /* exit loop */ cond = COND_MET; } else { - osi_core->osd_ops.udelay(500U); + osi_core->osd_ops.udelay(5U); } } From eede9dc4849a2108a69528b59a8142ef8621613f Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Sat, 18 Jun 2022 11:47:19 +0000 Subject: [PATCH 383/458] mgbe: core: call lane bringup on local fault call lane bringup when there are local faults and stop the network queues. restart the network queues when proper link is up Bug 3744088 Bug 3654543 Bug 3665378 Change-Id: I33180c965b29543dcdfb0d8f611be06b6b97a42e Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2730882 Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> GVS: Gerrit_Virtual_Submit --- include/osi_core.h | 2 ++ osi/core/mgbe_core.c | 12 ++++++++++++ osi/core/mgbe_core.h | 4 ++++ 3 files changed, 18 insertions(+) diff --git a/include/osi_core.h b/include/osi_core.h index 36671e9..d2ac5fc 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -1130,6 +1130,8 @@ struct osd_core_ops { nveu32_t type, const char *fmt, ...); #endif + /** Lane bringup restart callback */ + void (*restart_lane_bringup)(void *priv, unsigned int en_disable); }; #ifdef MACSEC_SUPPORT diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 33b664f..5fe78a0 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -3297,6 +3297,18 @@ static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core, return; } + /* Check for Link status change interrupt */ + if ((mac_isr & MGBE_MAC_ISR_LSI) == OSI_ENABLE) { + /* For Local fault need to stop network data and restart the LANE bringup */ + if ((mac_isr & MGBE_MAC_ISR_LS_MASK) == MGBE_MAC_ISR_LS_LOCAL_FAULT) { + osi_core->osd_ops.restart_lane_bringup(osi_core->osd, OSI_DISABLE); + } else if ((mac_isr & MGBE_MAC_ISR_LS_MASK) == MGBE_MAC_ISR_LS_LINK_OK) { + osi_core->osd_ops.restart_lane_bringup(osi_core->osd, OSI_ENABLE); + } else { + /* Do Nothing */ + } + } + #ifndef OSI_STRIPPED_LIB mac_ier = osi_readla(osi_core, (unsigned char *)osi_core->base + MGBE_MAC_IER); diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 3069dca..1132910 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -510,6 +510,10 @@ #define MGBE_MAC_TX_TJT OSI_BIT(0) #define MGBE_MAC_TX_IHE OSI_BIT(12) #define MGBE_MAC_TX_PCE OSI_BIT(13) +#define MGBE_MAC_ISR_LSI OSI_BIT(0) +#define MGBE_MAC_ISR_LS_MASK (OSI_BIT(25) | OSI_BIT(24)) +#define MGBE_MAC_ISR_LS_LOCAL_FAULT OSI_BIT(25) +#define MGBE_MAC_ISR_LS_LINK_OK 0U /* DMA SBUS */ #define MGBE_DMA_SBUS_UNDEF OSI_BIT(0) #define MGBE_DMA_SBUS_BLEN256 OSI_BIT(7) From abd80e150c419fe1628c37b2b3c638d7e74d84ce Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Tue, 9 Aug 2022 11:07:41 +0530 Subject: [PATCH 384/458] osi: Pass OSD pointer for better logging Issue: Currently logs don't have any IP/inteface specific name to indicate that from which IP/interface these logs are coming. Fix: Pass OSD pointer so that interface or device name can be added to the logs. Reduce XPCS logging Bug 3719492 Bug 3722532 Change-Id: Id909b14f24f441ab40ff6497f1998aeb4ab34611 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2745731 Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- osi/core/core_common.c | 6 ++-- osi/core/core_local.h | 2 ++ osi/core/eqos_core.c | 42 +++++++++++------------ osi/core/frp.c | 2 +- osi/core/mgbe_core.c | 24 ++++++------- osi/core/osi_core.c | 12 +++---- osi/core/osi_hal.c | 77 +++++++++++++++++++++--------------------- osi/core/vlan_filter.c | 10 +++--- osi/core/xpcs.c | 25 +++++++++----- osi/core/xpcs.h | 2 +- osi/dma/osi_dma.c | 40 +++++++++++----------- osi/dma/osi_dma_txrx.c | 34 +++++++++---------- 12 files changed, 142 insertions(+), 134 deletions(-) diff --git a/osi/core/core_common.c b/osi/core/core_common.c index 87dd536..9de1a76 100644 --- a/osi/core/core_common.c +++ b/osi/core/core_common.c @@ -38,7 +38,7 @@ static inline nve32_t poll_check(struct osi_core_priv_data *const osi_core, nveu count = 0; while (cond == COND_NOT_MET) { if (count > retry) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "poll_check: timeout\n", 0ULL); ret = -1; goto fail; @@ -114,7 +114,7 @@ nve32_t hw_set_mode(struct osi_core_priv_data *const osi_core, const nve32_t mod /* don't allow only if loopback mode is other than 0 or 1 */ if ((mode != OSI_FULL_DUPLEX) && (mode != OSI_HALF_DUPLEX)) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid duplex mode\n", 0ULL); ret = -1; goto fail; @@ -180,8 +180,6 @@ nve32_t hw_set_speed(struct osi_core_priv_data *const osi_core, const nve32_t sp if (osi_core->mac == OSI_MAC_HW_MGBE) { if (xpcs_init(osi_core) < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "xpcs_init failed\n", OSI_NONE); ret = -1; goto fail; } diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 2493bd8..81cd8e1 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -466,6 +466,8 @@ struct core_local { struct dynamic_cfg cfg; /** Hardware dynamic configuration state */ nveu32_t state; + /** XPCS Lane bringup/Block lock status */ + nveu32_t lane_status; }; /** diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 333aa7b..bea4438 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -74,7 +74,7 @@ static nve32_t eqos_ptp_tsc_capture(struct osi_core_priv_data *const osi_core, nve32_t ret = -1; if (osi_core->mac_ver < OSI_EQOS_MAC_5_30) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "ptp_tsc: older IP\n", 0ULL); goto done; } @@ -431,7 +431,7 @@ static nve32_t eqos_config_flow_control( /* return on invalid argument */ if (flw_ctrl > (OSI_FLOW_CTRL_RX | OSI_FLOW_CTRL_TX)) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "flw_ctr: invalid input\n", 0ULL); return -1; } @@ -1965,7 +1965,7 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core, /* PAD calibration */ ret = eqos_pad_calibrate(osi_core); if (ret < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "eqos pad calibration failed\n", 0ULL); return ret; } @@ -2024,7 +2024,7 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core, } if (osi_unlikely(osi_core->num_mtl_queues > OSI_EQOS_MAX_NUM_QUEUES)) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Number of queues is incorrect\n", 0ULL); return -1; } @@ -2042,7 +2042,7 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core, 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, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Incorrect queues number\n", 0ULL); return -1; } @@ -2223,13 +2223,13 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, if ((mac_pcs & EQOS_MAC_PCS_LNKMOD) == EQOS_MAC_PCS_LNKMOD) { ret = hw_set_mode(osi_core, OSI_FULL_DUPLEX); if (osi_unlikely(ret < 0)) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "set mode in full duplex failed\n", 0ULL); } } else { ret = hw_set_mode(osi_core, OSI_HALF_DUPLEX); if (osi_unlikely(ret < 0)) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "set mode in half duplex failed\n", 0ULL); } } @@ -2382,7 +2382,7 @@ static void eqos_handle_mtl_intrs(struct osi_core_priv_data *osi_core) 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, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Disabling EST due to HLBS, correct GCL\n", OSI_NONE); } @@ -2417,7 +2417,7 @@ static void eqos_handle_mtl_intrs(struct osi_core_priv_data *osi_core) 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, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Disabling EST due to HLBF, correct GCL\n", OSI_NONE); } @@ -3836,7 +3836,7 @@ static inline nve32_t eqos_poll_for_tsinit_complete( count = 0; while (cond == COND_NOT_MET) { if (count > retry) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "poll_for_tsinit: timeout\n", 0ULL); return -1; } @@ -3954,7 +3954,7 @@ static inline nve32_t eqos_poll_for_addend_complete( count = 0; while (cond == COND_NOT_MET) { if (count > retry) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "poll_for_addend: timeout\n", 0ULL); return -1; } @@ -4065,7 +4065,7 @@ static inline nve32_t eqos_poll_for_update_ts_complete( count = 0; while (cond == COND_NOT_MET) { if (count > retry) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "poll_for_update_ts: timeout\n", 0ULL); return -1; } @@ -5180,7 +5180,7 @@ static nve32_t eqos_validate_core_regs( * take care of corrective action. */ osi_unlock_irq_enabled(&config->core_safety_lock); - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "register mismatch\n", 0ULL); return -1; } @@ -5222,7 +5222,7 @@ static nve32_t eqos_config_rx_crc_check( /* return on invalid argument */ if ((crc_chk != OSI_ENABLE) && (crc_chk != OSI_DISABLE)) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "rx_crc: invalid input\n", 0ULL); return -1; } @@ -5279,7 +5279,7 @@ static nve32_t eqos_config_tx_status(struct osi_core_priv_data *const osi_core, /* 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, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "tx_status: invalid input\n", 0ULL); return -1; } @@ -5575,7 +5575,7 @@ static nve32_t eqos_config_arp_offload( EQOS_5_00_MAC_ARPPA); } else { /* Unsupported MAC ver */ - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "arp_offload: invalid HW\n", 0ULL); return -1; } @@ -5629,21 +5629,21 @@ static nve32_t eqos_config_vlan_filtering( if ((filter_enb_dis != OSI_ENABLE) && (filter_enb_dis != OSI_DISABLE)) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, 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, + OSI_CORE_ERR(osi_core->osd, 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, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "vlan_filter: invalid input\n", 0ULL); return -1; } @@ -6322,7 +6322,7 @@ static nve32_t eqos_post_pad_calibrate( */ static nve32_t eqos_config_rss(struct osi_core_priv_data *osi_core) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "RSS not supported by EQOS\n", 0ULL); return -1; @@ -6359,7 +6359,7 @@ static void eqos_config_for_macsec(struct osi_core_priv_data *const osi_core, nveu32_t value = 0U, temp = 0U; if ((enable != OSI_ENABLE) && (enable != OSI_DISABLE)) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Failed to config EQOS per MACSEC\n", 0ULL); goto exit; } diff --git a/osi/core/frp.c b/osi/core/frp.c index 65da6df..df97039 100644 --- a/osi/core/frp.c +++ b/osi/core/frp.c @@ -190,7 +190,7 @@ static void frp_entry_mode_parse(unsigned char filter_mode, data->inverse_match = OSI_DISABLE; break; default: - //OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + //OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, // "Invalid filter mode argment\n", // filter_mode); break; diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 5fe78a0..5af26d5 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -257,7 +257,7 @@ static int mgbe_mac_indir_addr_write(struct osi_core_priv_data *osi_core, /* Wait until OB bit reset */ if (mgbe_poll_for_mac_acrtl(osi_core) < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Fail to write MAC_Indir_Access_Ctrl\n", mc_no); return -1; } @@ -312,7 +312,7 @@ static int mgbe_mac_indir_addr_read(struct osi_core_priv_data *osi_core, /* Wait until OB bit reset */ if (mgbe_poll_for_mac_acrtl(osi_core) < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Fail to write MAC_Indir_Access_Ctrl\n", mc_no); return -1; } @@ -477,7 +477,7 @@ static int mgbe_filter_args_validate(struct osi_core_priv_data *const osi_core, /* validate addr_mask argument */ if (addr_mask > MGBE_MAB_ADDRH_MBC_MAX_MASK) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid addr_mask value\n", addr_mask); return -1; @@ -485,7 +485,7 @@ static int mgbe_filter_args_validate(struct osi_core_priv_data *const osi_core, /* validate src_dest argument */ if ((src_dest != OSI_SA_MATCH) && (src_dest != OSI_DA_MATCH)) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid src_dest value\n", src_dest); return -1; @@ -494,7 +494,7 @@ static int mgbe_filter_args_validate(struct osi_core_priv_data *const osi_core, /* 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, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid dma_routing value\n", dma_routing_enable); return -1; @@ -715,7 +715,7 @@ static int mgbe_l3l4_filter_write(struct osi_core_priv_data *osi_core, /* Wait untile XB bit reset */ if (mgbe_poll_for_l3l4crtl(osi_core) < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Fail to write L3_L4_Address_Control\n", filter_type); return -1; @@ -773,7 +773,7 @@ static int mgbe_l3l4_filter_read(struct osi_core_priv_data *osi_core, /* Wait untile XB bit reset */ if (mgbe_poll_for_l3l4crtl(osi_core) < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Fail to read L3L4 Address\n", filter_type); return -1; @@ -1012,7 +1012,7 @@ static int mgbe_config_l3_l4_filter_enable( /* 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, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid filter_enb_dis value\n", filter_enb_dis); return -1; @@ -2212,7 +2212,7 @@ static int mgbe_rss_write_reg(struct osi_core_priv_data *osi_core, /* poll for write operation to complete */ while (cond == 1) { if (count > retry) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Failed to update RSS Hash key or table\n", 0ULL); return -1; @@ -3788,7 +3788,7 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core, 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, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Disabling EST due to HLBS, correct GCL\n", OSI_NONE); } @@ -3822,7 +3822,7 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core, 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, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Disabling EST due to HLBF, correct GCL\n", OSI_NONE); } @@ -5825,7 +5825,7 @@ static void mgbe_config_for_macsec(struct osi_core_priv_data *const osi_core, nveu32_t value = 0U, temp = 0U; if ((enable != OSI_ENABLE) && (enable != OSI_DISABLE)) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Failed to config MGBE per MACSEC\n", 0ULL); goto exit; } diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 75c9e72..931298b 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -79,7 +79,7 @@ static nve32_t validate_if_func_ptrs(struct osi_core_priv_data *const osi_core, #elif __SIZEOF_POINTER__ == 4 nveu32_t *l_ops = (nveu32_t *)temp_ops; #else - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Undefined architecture\n", 0ULL); return -1; #endif @@ -87,7 +87,7 @@ static nve32_t validate_if_func_ptrs(struct osi_core_priv_data *const osi_core, 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, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "failed at index : ", i); return -1; } @@ -195,14 +195,14 @@ nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core) } if (validate_if_func_ptrs(osi_core, l_core->if_ops_p) < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, 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, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "if_init_core_ops failed\n", 0ULL); return ret; } @@ -228,7 +228,7 @@ nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core) 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, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "invalid pps_frq\n", (nveu64_t)osi_core->pps_frq); ret = -1; } @@ -297,7 +297,7 @@ nve32_t osi_handle_ioctl(struct osi_core_priv_data *osi_core, } if (data == OSI_NULL) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "CORE: Invalid argument\n", 0ULL); return ret; } diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 70416eb..3ab2efe 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -88,14 +88,14 @@ static nve32_t validate_func_ptrs(struct osi_core_priv_data *const osi_core, #elif __SIZEOF_POINTER__ == 4 nveu32_t *l_ops = (nveu32_t *)temp_ops; #else - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, 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, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "core: fn ptr validation failed at\n", (nveu64_t)i); return -1; @@ -171,13 +171,13 @@ static nve32_t osi_hal_init_core_ops(struct osi_core_priv_data *const osi_core) } if (osi_core->mac > OSI_MAC_HW_MGBE) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, 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, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid use_virtualization value\n", 0ULL); return -1; } @@ -193,7 +193,7 @@ static nve32_t osi_hal_init_core_ops(struct osi_core_priv_data *const osi_core) } #endif if (validate_func_ptrs(osi_core, &g_ops[osi_core->mac]) < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "core: function ptrs validation failed\n", 0ULL); return -1; } @@ -247,6 +247,7 @@ nve32_t osi_hal_hw_core_init(struct osi_core_priv_data *const osi_core, return ret; } + l_core->lane_status = OSI_ENABLE; l_core->tx_fifo_size = tx_fifo_size; l_core->rx_fifo_size = rx_fifo_size; l_core->hw_init_successful = OSI_ENABLE; @@ -297,7 +298,7 @@ static nve32_t conf_ptp_offload(struct osi_core_priv_data *const osi_core, /* Validate input arguments */ if (pto_config == OSI_NULL) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "pto_config is NULL\n", 0ULL); return ret; } @@ -381,14 +382,14 @@ nve32_t osi_l2_filter(struct osi_core_priv_data *const osi_core, } if (filter == OSI_NULL) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, 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, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "failed to configure MAC packet filter register\n", 0ULL); return ret; @@ -453,7 +454,7 @@ static inline nve32_t helper_l4_filter( dma_routing_enable, dma_chan); if (ret < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "failed to configure L4 filters\n", 0ULL); return ret; } @@ -504,7 +505,7 @@ static inline nve32_t helper_l3_filter( dma_routing_enable, dma_chan); if (ret < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "failed to configure L3 filters\n", 0ULL); return ret; } @@ -519,7 +520,7 @@ static inline nve32_t helper_l3_filter( l_filter->ip4_addr, l_filter->src_dst_addr_match); } else { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid L3 filter type\n", 0ULL); return -1; } @@ -656,7 +657,7 @@ nve32_t osi_adjust_freq(struct osi_core_priv_data *const osi_core, nve32_t ppb) if (temp < UINT_MAX) { diff = (nveu32_t)temp; } else { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "temp > UINT_MAX\n", + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "temp > UINT_MAX\n", 0ULL); return ret; } @@ -665,7 +666,7 @@ nve32_t osi_adjust_freq(struct osi_core_priv_data *const osi_core, nve32_t ppb) if (addend <= (UINT_MAX - diff)) { addend = (addend + diff); } else { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "addend > UINT_MAX\n", 0ULL); return ret; } @@ -675,7 +676,7 @@ nve32_t osi_adjust_freq(struct osi_core_priv_data *const osi_core, nve32_t ppb) } else if (addend < diff) { addend = diff - addend; } else { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "addend = diff\n", 0ULL); } } @@ -711,7 +712,7 @@ nve32_t osi_adjust_time(struct osi_core_priv_data *const osi_core, if (quotient <= UINT_MAX) { sec = (nveu32_t)quotient; } else { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "quotient > UINT_MAX\n", 0ULL); return ret; } @@ -719,7 +720,7 @@ nve32_t osi_adjust_time(struct osi_core_priv_data *const osi_core, if (reminder <= UINT_MAX) { nsec = (nveu32_t)reminder; } else { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "reminder > UINT_MAX\n", 0ULL); return ret; } @@ -781,7 +782,7 @@ nve32_t osi_ptp_configuration(struct osi_core_priv_data *const osi_core, if (temp2 < UINT_MAX) { osi_core->default_addend = (nveu32_t)temp2; } else { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "core: temp2 >= UINT_MAX\n", 0ULL); return -1; } @@ -831,7 +832,7 @@ static nve32_t osi_get_mac_version(struct osi_core_priv_data *const osi_core, nv } if (mac_ver == OSI_NULL) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "mac_ver is NULL\n", 0ULL); return -1; } @@ -840,7 +841,7 @@ static nve32_t osi_get_mac_version(struct osi_core_priv_data *const osi_core, nv 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, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid MAC version\n", (nveu64_t)*mac_ver) return -1; } @@ -922,7 +923,7 @@ static nve32_t validate_core_regs(struct osi_core_priv_data *const osi_core) struct core_local *l_core = (struct core_local *)(void *)osi_core; if (osi_core->safety_config == OSI_NULL) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "CORE: Safety config is NULL\n", 0ULL); return -1; } @@ -977,7 +978,7 @@ static nve32_t vlan_id_update(struct osi_core_priv_data *const osi_core, 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, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "CORE: Invalid action/vlan_id\n", 0ULL); /* Unsupported action */ return -1; @@ -1028,7 +1029,7 @@ static nve32_t conf_eee(struct osi_core_priv_data *const 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, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid Tx LPI timer value\n", (nveul64_t)tx_lpi_timer); return -1; @@ -1074,7 +1075,7 @@ static int configure_frp(struct osi_core_priv_data *const osi_core, struct core_local *l_core = (struct core_local *)(void *)osi_core; if (cmd == OSI_NULL) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid argment\n", OSI_NONE); return -1; } @@ -1131,13 +1132,13 @@ static nve32_t conf_arp_offload(struct osi_core_priv_data *const osi_core, struct core_local *l_core = (struct core_local *)(void *)osi_core; if (ip_addr == OSI_NULL) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, 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, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid ARP offload enable/disable flag\n", 0ULL); return -1; } @@ -1183,7 +1184,7 @@ static nve32_t conf_mac_loopback(struct osi_core_priv_data *const 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, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid loopback mode\n", 0ULL); return -1; } @@ -1237,14 +1238,14 @@ static nve32_t config_est(struct osi_core_priv_data *osi_core, struct core_local *l_core = (struct core_local *)(void *)osi_core; if (est == OSI_NULL) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, 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, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "TX Flow control enabled, please disable it", 0ULL); return -1; @@ -1292,7 +1293,7 @@ static nve32_t config_fpe(struct osi_core_priv_data *osi_core, struct core_local *l_core = (struct core_local *)(void *)osi_core; if (fpe == OSI_NULL) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "FPE data is NULL", 0ULL); return -1; } @@ -1788,7 +1789,7 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, ops_p = l_core->ops_p; if (data == OSI_NULL) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "CORE: Invalid argument\n", 0ULL); return -1; } @@ -1972,7 +1973,7 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, ret = osi_adjust_freq(osi_core, data->arg6_32); #if DRIFT_CAL if (ret < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "CORE: adjust freq failed\n", 0ULL); break; } @@ -2017,7 +2018,7 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, } if (ret < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "CORE: adjust_freq for sec_controller failed\n", 0ULL); ret = 0; @@ -2029,7 +2030,7 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, ret = osi_adjust_time(osi_core, data->arg8_64); #if DRIFT_CAL if (ret < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "CORE: adjust_time failed\n", 0ULL); break; } @@ -2067,7 +2068,7 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, } if (ret < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "CORE: adjust_time for sec_controller failed\n", 0ULL); ret = 0; @@ -2083,7 +2084,7 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, } #if DRIFT_CAL if (ret < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "CORE: configure_ptp failed\n", 0ULL); break; } @@ -2119,7 +2120,7 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, data->arg2_u32); #if DRIFT_CAL if (ret < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "CORE: set systohw time failed\n", 0ULL); break; } @@ -2153,7 +2154,7 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, } } if (ret < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "CORE: set_time for sec_controller failed\n", 0ULL); ret = 0; @@ -2280,7 +2281,7 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, apply_dynamic_cfg(osi_core); break; default: - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "CORE: Incorrect command\n", (nveul64_t)data->cmd); break; diff --git a/osi/core/vlan_filter.c b/osi/core/vlan_filter.c index b9b7b2a..e5209fd 100644 --- a/osi/core/vlan_filter.c +++ b/osi/core/vlan_filter.c @@ -155,7 +155,7 @@ static inline int enqueue_vlan_id(struct osi_core_priv_data *osi_core, /* 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, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "VLAN ID already programmed\n", 0ULL); return -1; @@ -189,7 +189,7 @@ static inline int poll_for_vlan_filter_reg_rw( count = 0; while (cond == 1) { if (count > retry) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "VLAN filter update timedout\n", 0ULL); return -1; } @@ -241,7 +241,7 @@ static inline int update_vlan_filters(struct osi_core_priv_data *osi_core, ret = poll_for_vlan_filter_reg_rw(osi_core); if (ret < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Failed to update VLAN filters\n", 0ULL); return -1; } @@ -300,7 +300,7 @@ static inline int add_vlan_id(struct osi_core_priv_data *osi_core, OSI_DISABLE, OSI_DISABLE); if (ret < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Failed to enable VLAN filtering\n", 0ULL); return -1; } @@ -446,7 +446,7 @@ static inline int del_vlan_id(struct osi_core_priv_data *osi_core, OSI_DISABLE, OSI_DISABLE); if (ret < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Failed to disable VLAN filtering\n", 0ULL); return -1; } diff --git a/osi/core/xpcs.c b/osi/core/xpcs.c index 7a50dc2..d8c377c 100644 --- a/osi/core/xpcs.c +++ b/osi/core/xpcs.c @@ -21,6 +21,7 @@ */ #include "xpcs.h" +#include "core_local.h" /** * @brief xpcs_poll_for_an_complete - Polling for AN complete. @@ -49,7 +50,7 @@ static inline int xpcs_poll_for_an_complete(struct osi_core_priv_data *osi_core, count = 0; while (cond == 1) { if (count > retry) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "XPCS AN completion timed out\n", 0ULL); #ifdef HSI_SUPPORT if (osi_core->hsi.enabled == OSI_ENABLE) { @@ -80,7 +81,7 @@ static inline int xpcs_poll_for_an_complete(struct osi_core_priv_data *osi_core, } if ((status & XPCS_USXG_AN_STS_SPEED_MASK) == 0U) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "XPCS AN completed with zero speed\n", 0ULL); return -1; } @@ -152,7 +153,7 @@ int xpcs_start(struct osi_core_priv_data *osi_core) int cond = COND_NOT_MET; if (osi_core->xpcs_base == OSI_NULL) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "XPCS base is NULL", 0ULL); /* TODO: Remove this once silicon arrives */ return 0; @@ -327,6 +328,7 @@ static nve32_t xpcs_check_pcs_lock_status(struct osi_core_priv_data *osi_core) */ static nve32_t xpcs_lane_bring_up(struct osi_core_priv_data *osi_core) { + struct core_local *l_core = (struct core_local *)(void *)osi_core; unsigned int retry = 1000; unsigned int count; nveu32_t val = 0; @@ -334,7 +336,7 @@ static nve32_t xpcs_lane_bring_up(struct osi_core_priv_data *osi_core) 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, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "UPHY TX lane bring-up failed\n", 0ULL); return -1; } @@ -433,9 +435,16 @@ static nve32_t xpcs_lane_bring_up(struct osi_core_priv_data *osi_core) 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); + if (l_core->lane_status == OSI_ENABLE) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Failed to get PCS block lock\n", 0ULL); + l_core->lane_status = OSI_DISABLE; + } return -1; + } else { + OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "PCS block lock SUCCESS\n", 0ULL); + l_core->lane_status = OSI_ENABLE; } return 0; @@ -461,15 +470,13 @@ int xpcs_init(struct osi_core_priv_data *osi_core) int ret = 0; if (osi_core->xpcs_base == OSI_NULL) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "XPCS base is NULL", 0ULL); /* TODO: Remove this once silicon arrives */ return 0; } 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; } diff --git a/osi/core/xpcs.h b/osi/core/xpcs.h index b512f83..7fcd741 100644 --- a/osi/core/xpcs.h +++ b/osi/core/xpcs.h @@ -191,7 +191,7 @@ static inline int xpcs_write_safety(struct osi_core_priv_data *osi_core, osi_core->osd_ops.udelay(OSI_DELAY_1US); } - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "xpcs_write_safety failed", reg_addr); return -1; } diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 8d5c817..ab59fed 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -187,7 +187,7 @@ static inline nve32_t validate_dma_chan_num(struct osi_dma_priv_data *osi_dma, 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, + OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "Invalid DMA channel number\n", chan); return -1; } @@ -216,7 +216,7 @@ static inline nve32_t validate_dma_chans(struct osi_dma_priv_data *osi_dma) 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, + OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "Invalid DMA channel number:\n", osi_dma->dma_chans[i]); return -1; @@ -252,14 +252,14 @@ static nve32_t validate_func_ptrs(struct osi_dma_priv_data *osi_dma, #elif __SIZEOF_POINTER__ == 4 nveu32_t *l_ops = (nveu32_t *)temp_ops; #else - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_DMA_ERR(osi_dma->osd, 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, + OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "dma: fn ptr validation failed at\n", (nveu64_t)i); return -1; @@ -305,7 +305,7 @@ nve32_t osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) } if (osi_dma->mac > OSI_MAC_HW_MGBE) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "DMA: Invalid MAC HW type\n", 0ULL); return -1; } @@ -315,7 +315,7 @@ nve32_t osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) (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, + OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "DMA: Using default Tx ring size: \n", osi_dma->tx_ring_sz); } @@ -325,7 +325,7 @@ nve32_t osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) (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, + OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "DMA: Using default rx ring size: \n", osi_dma->tx_ring_sz); } @@ -333,14 +333,14 @@ nve32_t osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) i_ops[osi_dma->mac](&g_ops[osi_dma->mac]); if (init_desc_ops(osi_dma) < 0) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "DMA desc ops init failed\n", 0ULL); return -1; } #ifndef OSI_STRIPPED_LIB if (validate_func_ptrs(osi_dma, &g_ops[osi_dma->mac]) < 0) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "DMA ops validation failed\n", 0ULL); return -1; } @@ -516,19 +516,19 @@ nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) 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, + OSI_DMA_ERR(osi_dma->osd, 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, + OSI_DMA_ERR(osi_dma->osd, 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, + OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "DMA channels validation failed\n", 0ULL); return -1; } @@ -615,13 +615,13 @@ nve32_t osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma) } if (osi_dma->num_dma_chans > l_dma->max_chans) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_DMA_ERR(osi_dma->osd, 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, + OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "DMA channels validation failed\n", 0ULL); return -1; } @@ -715,13 +715,13 @@ static inline nve32_t rx_dma_desc_validate_args( 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, + OSI_DMA_ERR(osi_dma->osd, 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, + OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "dma: Invalid channel\n", 0ULL); return -1; } @@ -820,7 +820,7 @@ nve32_t osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, 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, + OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "dma: Invalid tailptr\n", 0ULL); return -1; } @@ -840,7 +840,7 @@ nve32_t osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) } if (osi_dma->mtu > OSI_MAX_MTU_SIZE) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "Invalid MTU setting\n", 0ULL); return -1; } @@ -893,7 +893,7 @@ nve32_t osi_hw_transmit(struct osi_dma_priv_data *osi_dma, nveu32_t chan) } if (osi_unlikely(osi_dma->tx_ring[chan] == OSI_NULL)) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "DMA: Invalid Tx ring\n", 0ULL); return -1; } @@ -924,7 +924,7 @@ nve32_t osi_dma_ioctl(struct osi_dma_priv_data *osi_dma) l_dma->ops_p->debug_intr_config(osi_dma); break; default: - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "DMA: Invalid IOCTL command", 0ULL); return -1; } diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index b5889a5..eeea0ce 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -72,14 +72,14 @@ static inline nve32_t validate_rx_completions_arg( *rx_ring = osi_dma->rx_ring[chan]; if (osi_unlikely(*rx_ring == OSI_NULL)) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_DMA_ERR(osi_dma->osd, 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, + OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "validate_input_rx_completions: Invalid pointers\n", 0ULL); return -1; @@ -112,7 +112,7 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, } if (rx_ring->cur_rx_idx >= osi_dma->rx_ring_sz) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "dma_txrx: Invalid cur_rx_idx\n", 0ULL); return -1; } @@ -245,7 +245,7 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, osi_dma->rx_buf_len, rx_pkt_cx, rx_swcx); } else { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "dma_txrx: Invalid function pointer\n", 0ULL); return -1; @@ -494,7 +494,7 @@ static inline nve32_t validate_tx_completions_arg( *tx_ring = osi_dma->tx_ring[chan]; if (osi_unlikely(*tx_ring == OSI_NULL)) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "validate_tx_completions_arg: Invalid pointers\n", 0ULL); return -1; @@ -639,7 +639,7 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, tx_swcx, txdone_pkt_cx); } else { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "dma_txrx: Invalid function pointer\n", 0ULL); return -1; @@ -917,25 +917,25 @@ static inline nve32_t validate_ctx(struct osi_dma_priv_data *osi_dma, 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, + OSI_DMA_ERR(osi_dma->osd, 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, + OSI_DMA_ERR(osi_dma->osd, 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, + OSI_DMA_ERR(osi_dma->osd, 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, + OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "dma_txrx: Invalid frame len\n", (nveul64_t)tx_pkt_cx->payload_len); goto fail; @@ -943,7 +943,7 @@ static inline nve32_t validate_ctx(struct osi_dma_priv_data *osi_dma, } if (osi_unlikely(tx_pkt_cx->vtag_id > TDES3_VT_MASK)) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "dma_txrx: Invalid VTAG_ID\n", (nveul64_t)tx_pkt_cx->vtag_id); goto fail; @@ -982,7 +982,7 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, entry = tx_ring->cur_tx_idx; if (entry >= osi_dma->tx_ring_sz) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "dma_txrx: Invalid cur_tx_idx\n", 0ULL); return -1; } @@ -994,7 +994,7 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, 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, + OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "dma_txrx: Invalid desc_cnt\n", 0ULL); return -1; } @@ -1133,7 +1133,7 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, (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, + OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "dma_txrx: Invalid tx_desc_phy_addr\n", 0ULL); return -1; } @@ -1198,7 +1198,7 @@ static nve32_t rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, rx_ring = osi_dma->rx_ring[chan]; if (osi_unlikely(rx_ring == OSI_NULL)) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "dma_txrx: Invalid argument\n", 0ULL); return -1; }; @@ -1248,7 +1248,7 @@ static nve32_t rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, if (osi_unlikely((tailptr < rx_ring->rx_desc_phy_addr))) { /* Will not hit this case */ - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "dma_txrx: Invalid phys address\n", 0ULL); return -1; } @@ -1373,7 +1373,7 @@ static nve32_t tx_dma_desc_init(struct osi_dma_priv_data *osi_dma) tx_ring = osi_dma->tx_ring[chan]; if (osi_unlikely(tx_ring == OSI_NULL)) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, + OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "dma_txrx: Invalid pointers\n", 0ULL); return -1; } From 86d0902440f74316bdcc5aaf9f6e303d6f7a7f62 Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Tue, 5 Jul 2022 15:05:59 +0000 Subject: [PATCH 385/458] osi: core: combine set_systime_to_mac Bug 3701869 Change-Id: I7df8c486b9fea489bf16c700d93e070f0d455dd2 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2740056 Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- osi/core/core_common.c | 35 ++++++++++++ osi/core/core_common.h | 3 ++ osi/core/core_local.h | 4 -- osi/core/eqos_core.c | 120 ----------------------------------------- osi/core/eqos_core.h | 1 - osi/core/mgbe_core.c | 86 ----------------------------- osi/core/mgbe_core.h | 1 - osi/core/osi_hal.c | 16 +++--- 8 files changed, 44 insertions(+), 222 deletions(-) diff --git a/osi/core/core_common.c b/osi/core/core_common.c index 9de1a76..219a62d 100644 --- a/osi/core/core_common.c +++ b/osi/core/core_common.c @@ -284,6 +284,41 @@ fail: return ret; } +nve32_t hw_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 = 0U; + nve32_t ret = 0; + const nveu32_t mac_tscr[2] = { EQOS_MAC_TCR, MGBE_MAC_TCR}; + const nveu32_t mac_stsur[2] = { EQOS_MAC_STSUR, MGBE_MAC_STSUR}; + const nveu32_t mac_stnsur[2] = { EQOS_MAC_STNSUR, MGBE_MAC_STNSUR}; + + ret = poll_check(osi_core, ((nveu8_t *)addr + mac_tscr[osi_core->mac]), + MAC_TCR_TSINIT, &mac_tcr); + if (ret == -1) { + goto fail; + } + + /* write seconds value to MAC_System_Time_Seconds_Update register */ + osi_writela(osi_core, sec, ((nveu8_t *)addr + mac_stsur[osi_core->mac])); + + /* write nano seconds value to MAC_System_Time_Nanoseconds_Update + * register + */ + osi_writela(osi_core, nsec, ((nveu8_t *)addr + mac_stnsur[osi_core->mac])); + + /* issue command to update the configured secs and nsecs values */ + mac_tcr |= MAC_TCR_TSINIT; + osi_writela(osi_core, mac_tcr, ((nveu8_t *)addr + mac_tscr[osi_core->mac])); + + ret = poll_check(osi_core, ((nveu8_t *)addr + mac_tscr[osi_core->mac]), + MAC_TCR_TSINIT, &mac_tcr); +fail: + return ret; +} + + #ifndef OSI_STRIPPED_LIB /** * @brief hw_est_read - indirect read the GCL to Software own list diff --git a/osi/core/core_common.h b/osi/core/core_common.h index 06528bc..4c545bb 100644 --- a/osi/core/core_common.h +++ b/osi/core/core_common.h @@ -41,6 +41,7 @@ #define DMA_MODE_SWR OSI_BIT(0) #define MTL_QTOMR_FTQ OSI_BIT(0) #define MTL_RXQ_OP_MODE_FEP OSI_BIT(4) +#define MAC_TCR_TSINIT OSI_BIT(2) /** * @addtogroup typedef related info @@ -74,5 +75,7 @@ nve32_t hw_config_fw_err_pkts(struct osi_core_priv_data *osi_core, const nveu32_t qinx, const nveu32_t enable_fw_err_pkts); nve32_t hw_config_rxcsum_offload(struct osi_core_priv_data *const osi_core, nveu32_t enabled); +nve32_t hw_set_systime_to_mac(struct osi_core_priv_data *const osi_core, + const nveu32_t sec, const nveu32_t nsec); #endif /* INCLUDED_CORE_COMMON_H */ diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 81cd8e1..ec1af8b 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -131,10 +131,6 @@ struct core_ops { const nveu32_t perfect_inverse_match, const nveu32_t dma_routing_enable, const nveu32_t dma_chan); - /** 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 set the addend value to adjust the time */ nve32_t (*config_addend)(struct osi_core_priv_data *const osi_core, const nveu32_t addend); diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index bea4438..ebc8a12 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -3798,125 +3798,6 @@ static nve32_t eqos_config_l4_filters( } #endif /* !OSI_STRIPPED_LIB */ -/** - * @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_core->osd, 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 <<RM_05, (sequence diagram)>> 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 = 0U; - 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 * @@ -6461,7 +6342,6 @@ void eqos_init_core_ops(struct core_ops *ops) 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->set_systime_to_mac = eqos_set_systime_to_mac; ops->config_addend = eqos_config_addend; ops->config_tscr = eqos_config_tscr; ops->config_ssir = eqos_config_ssir; diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 685098c..27fa4b6 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -420,7 +420,6 @@ #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) | \ diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 5af26d5..b0555da 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -5211,91 +5211,6 @@ static int mgbe_get_hw_features(struct osi_core_priv_data *const osi_core, 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 nve32_t mgbe_set_systime_to_mac(struct osi_core_priv_data *osi_core, - nveu32_t sec, nveu32_t 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 * @@ -5907,7 +5822,6 @@ void mgbe_init_core_ops(struct core_ops *ops) 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->set_systime_to_mac = mgbe_set_systime_to_mac; ops->config_addend = mgbe_config_addend; ops->config_tscr = mgbe_config_tscr; ops->config_ssir = mgbe_config_ssir, diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 1132910..1369f13 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -539,7 +539,6 @@ #define MGBE_MTL_RXQ_SIZE_SHIFT 16U #define MGBE_MAC_RMCR_GPSL_MSK 0x3FFF0000U #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) diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 3ab2efe..6adbb56 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -596,7 +596,7 @@ nve32_t osi_set_systime_to_mac(struct osi_core_priv_data *const osi_core, return -1; } - return l_core->ops_p->set_systime_to_mac(osi_core, sec, nsec); + return hw_set_systime_to_mac(osi_core, sec, nsec); } /** @@ -793,9 +793,9 @@ nve32_t osi_ptp_configuration(struct osi_core_priv_data *const osi_core, /* 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); + ret = hw_set_systime_to_mac(osi_core, + osi_core->ptp_config.sec, + osi_core->ptp_config.nsec); if (ret == 0) { #ifndef OSI_STRIPPED_LIB /* Enable PTP RX Queue routing */ @@ -1772,7 +1772,6 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, #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; @@ -2116,8 +2115,7 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, break; case OSI_CMD_SET_SYSTOHW_TIME: - ret = ops_p->set_systime_to_mac(osi_core, data->arg1_u32, - data->arg2_u32); + ret = hw_set_systime_to_mac(osi_core, data->arg1_u32, data->arg2_u32); #if DRIFT_CAL if (ret < 0) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, @@ -2144,9 +2142,7 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, 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); + ret = hw_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; From e11ffed221527d9fb437e7e6e3b28949b244ac9d Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Tue, 5 Jul 2022 17:52:37 +0000 Subject: [PATCH 386/458] osi: core: combine config_addend Bug 3701869 Change-Id: I6a656ac72e8d87b96ac9efa9bf9e1c9a979306b1 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2740109 Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- osi/core/core_common.c | 27 ++++++++++ osi/core/core_common.h | 5 +- osi/core/core_local.h | 3 -- osi/core/eqos_core.c | 112 ----------------------------------------- osi/core/eqos_core.h | 1 - osi/core/mgbe_core.c | 80 ----------------------------- osi/core/mgbe_core.h | 1 - osi/core/osi_hal.c | 5 +- 8 files changed, 32 insertions(+), 202 deletions(-) diff --git a/osi/core/core_common.c b/osi/core/core_common.c index 219a62d..3ddc879 100644 --- a/osi/core/core_common.c +++ b/osi/core/core_common.c @@ -318,6 +318,33 @@ fail: return ret; } +nve32_t hw_config_addend(struct osi_core_priv_data *const osi_core, + const nveu32_t addend) +{ + void *addr = osi_core->base; + nveu32_t mac_tcr = 0U; + nve32_t ret = 0; + const nveu32_t mac_tscr[2] = { EQOS_MAC_TCR, MGBE_MAC_TCR}; + const nveu32_t mac_tar[2] = { EQOS_MAC_TAR, MGBE_MAC_TAR}; + + ret = poll_check(osi_core, ((nveu8_t *)addr + mac_tscr[osi_core->mac]), + MAC_TCR_TSADDREG, &mac_tcr); + if (ret == -1) { + goto fail; + } + + /* write addend value to MAC_Timestamp_Addend register */ + osi_writela(osi_core, addend, ((nveu8_t *)addr + mac_tar[osi_core->mac])); + + /* issue command to update the configured addend value */ + mac_tcr |= MAC_TCR_TSADDREG; + osi_writela(osi_core, mac_tcr, ((nveu8_t *)addr + mac_tscr[osi_core->mac])); + + ret = poll_check(osi_core, ((nveu8_t *)addr + mac_tscr[osi_core->mac]), + MAC_TCR_TSADDREG, &mac_tcr); +fail: + return ret; +} #ifndef OSI_STRIPPED_LIB /** diff --git a/osi/core/core_common.h b/osi/core/core_common.h index 4c545bb..b0a1652 100644 --- a/osi/core/core_common.h +++ b/osi/core/core_common.h @@ -42,7 +42,7 @@ #define MTL_QTOMR_FTQ OSI_BIT(0) #define MTL_RXQ_OP_MODE_FEP OSI_BIT(4) #define MAC_TCR_TSINIT OSI_BIT(2) - +#define MAC_TCR_TSADDREG OSI_BIT(5) /** * @addtogroup typedef related info * @@ -77,5 +77,6 @@ nve32_t hw_config_rxcsum_offload(struct osi_core_priv_data *const osi_core, nveu32_t enabled); nve32_t hw_set_systime_to_mac(struct osi_core_priv_data *const osi_core, const nveu32_t sec, const nveu32_t nsec); - +nve32_t hw_config_addend(struct osi_core_priv_data *const osi_core, + const nveu32_t addend); #endif /* INCLUDED_CORE_COMMON_H */ diff --git a/osi/core/core_local.h b/osi/core/core_local.h index ec1af8b..4fcb8c8 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -131,9 +131,6 @@ struct core_ops { const nveu32_t perfect_inverse_match, const nveu32_t dma_routing_enable, const nveu32_t dma_chan); - /** 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 configure the TimeStampControl register */ void (*config_tscr)(struct osi_core_priv_data *const osi_core, const nveu32_t ptp_filter); diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index ebc8a12..9e6e0cc 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -3798,117 +3798,6 @@ static nve32_t eqos_config_l4_filters( } #endif /* !OSI_STRIPPED_LIB */ -/** - * @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_core->osd, 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 <<RM_23, (sequence diagram)>> 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 = 0U; - 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 * @@ -6342,7 +6231,6 @@ void eqos_init_core_ops(struct core_ops *ops) 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->config_addend = eqos_config_addend; ops->config_tscr = eqos_config_tscr; ops->config_ssir = eqos_config_ssir; ops->adjust_mactime = eqos_adjust_mactime; diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 27fa4b6..cd5d712 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -419,7 +419,6 @@ #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_TSUPDT OSI_BIT(3) #define EQOS_MAC_TCR_TSCFUPDT OSI_BIT(1) #define EQOS_MAC_PTO_CR_DN (OSI_BIT(15) | OSI_BIT(14) | \ diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index b0555da..0ef4b67 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -5211,85 +5211,6 @@ static int mgbe_get_hw_features(struct osi_core_priv_data *const osi_core, 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 nve32_t mgbe_config_addend(struct osi_core_priv_data *const osi_core, - const nveu32_t 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 * @@ -5822,7 +5743,6 @@ void mgbe_init_core_ops(struct core_ops *ops) 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->config_addend = mgbe_config_addend; ops->config_tscr = mgbe_config_tscr; ops->config_ssir = mgbe_config_ssir, ops->adjust_mactime = mgbe_adjust_mactime; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 1369f13..5b820ca 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -540,7 +540,6 @@ #define MGBE_MAC_RMCR_GPSL_MSK 0x3FFF0000U #define MGBE_MAC_TCR_TSCFUPDT OSI_BIT(1) #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 diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 6adbb56..e510bfe 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -681,7 +681,7 @@ nve32_t osi_adjust_freq(struct osi_core_priv_data *const osi_core, nve32_t ppb) } } - return l_core->ops_p->config_addend(osi_core, addend); + return hw_config_addend(osi_core, addend); } nve32_t osi_adjust_time(struct osi_core_priv_data *const osi_core, @@ -788,8 +788,7 @@ nve32_t osi_ptp_configuration(struct osi_core_priv_data *const osi_core, } /* Program addend value */ - ret = l_core->ops_p->config_addend(osi_core, - osi_core->default_addend); + ret = hw_config_addend(osi_core, osi_core->default_addend); /* Set current time */ if (ret == 0) { From 73a42b9cdb7f18d56eb4e6486df0751d08e28d71 Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Wed, 6 Jul 2022 03:05:45 +0000 Subject: [PATCH 387/458] osi: core: combine config_tscr Bug 3701869 Change-Id: I1eb04dd9cf439ce55b1bdc6df73f793af85eddcd Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2740317 Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- osi/core/core_common.c | 83 ++++++++++++++++++++++++++++++++++++++++ osi/core/core_common.h | 4 ++ osi/core/core_local.h | 3 -- osi/core/eqos_core.c | 87 ------------------------------------------ osi/core/eqos_core.h | 2 - osi/core/mgbe_core.c | 86 ----------------------------------------- osi/core/mgbe_core.h | 2 - osi/core/osi_hal.c | 4 +- 8 files changed, 89 insertions(+), 182 deletions(-) diff --git a/osi/core/core_common.c b/osi/core/core_common.c index 3ddc879..8037acc 100644 --- a/osi/core/core_common.c +++ b/osi/core/core_common.c @@ -346,6 +346,89 @@ fail: return ret; } +#ifndef OSI_STRIPPED_LIB +void hw_config_tscr(struct osi_core_priv_data *const osi_core, const nveu32_t ptp_filter) +#else +void hw_config_tscr(struct osi_core_priv_data *const osi_core, OSI_UNUSED const nveu32_t ptp_filter) +#endif /* !OSI_STRIPPED_LIB */ +{ + void *addr = osi_core->base; + struct core_local *l_core = (struct core_local *)osi_core; + nveu32_t mac_tcr = 0U; +#ifndef OSI_STRIPPED_LIB + nveu32_t i = 0U, temp = 0U; +#endif /* !OSI_STRIPPED_LIB */ + nveu32_t value = 0x0U; + const nveu32_t mac_tscr[2] = { EQOS_MAC_TCR, MGBE_MAC_TCR}; + const nveu32_t mac_pps[2] = { EQOS_MAC_PPS_CTL, MGBE_MAC_PPS_CTL}; + +#ifndef OSI_STRIPPED_LIB + 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_SNAPTYPSEL_3: + mac_tcr |= OSI_MAC_TCR_SNAPTYPSEL_3; + 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: + break; + } + } + } else { + /* Disabling the MAC time stamping */ + mac_tcr = OSI_DISABLE; + } +#else + mac_tcr = (OSI_MAC_TCR_TSENA | OSI_MAC_TCR_TSCFUPDT | OSI_MAC_TCR_TSCTRLSSR + | OSI_MAC_TCR_TSVER2ENA | OSI_MAC_TCR_TSIPENA | OSI_MAC_TCR_TSIPV6ENA | + OSI_MAC_TCR_TSIPV4ENA | OSI_MAC_TCR_SNAPTYPSEL_1); +#endif /* !OSI_STRIPPED_LIB */ + + osi_writela(osi_core, mac_tcr, ((nveu8_t *)addr + mac_tscr[osi_core->mac])); + + value = osi_readla(osi_core, (nveu8_t *)addr + mac_pps[osi_core->mac]); + value &= ~MAC_PPS_CTL_PPSCTRL0; + if (l_core->pps_freq == OSI_ENABLE) { + value |= OSI_ENABLE; + } + osi_writela(osi_core, value, ((nveu8_t *)addr + mac_pps[osi_core->mac])); +} + #ifndef OSI_STRIPPED_LIB /** * @brief hw_est_read - indirect read the GCL to Software own list diff --git a/osi/core/core_common.h b/osi/core/core_common.h index b0a1652..a7330cb 100644 --- a/osi/core/core_common.h +++ b/osi/core/core_common.h @@ -43,6 +43,9 @@ #define MTL_RXQ_OP_MODE_FEP OSI_BIT(4) #define MAC_TCR_TSINIT OSI_BIT(2) #define MAC_TCR_TSADDREG OSI_BIT(5) +#define MAC_PPS_CTL_PPSCTRL0 (OSI_BIT(3) | OSI_BIT(2) |\ + OSI_BIT(1) | OSI_BIT(0)) + /** * @addtogroup typedef related info * @@ -79,4 +82,5 @@ nve32_t hw_set_systime_to_mac(struct osi_core_priv_data *const osi_core, const nveu32_t sec, const nveu32_t nsec); nve32_t hw_config_addend(struct osi_core_priv_data *const osi_core, const nveu32_t addend); +void hw_config_tscr(struct osi_core_priv_data *const osi_core, const nveu32_t ptp_filter); #endif /* INCLUDED_CORE_COMMON_H */ diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 4fcb8c8..f197b09 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -131,9 +131,6 @@ struct core_ops { const nveu32_t perfect_inverse_match, const nveu32_t dma_routing_enable, const nveu32_t dma_chan); - /** 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); diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 9e6e0cc..e23bfe8 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -3957,92 +3957,6 @@ static nve32_t eqos_adjust_mactime(struct osi_core_priv_data *const osi_core, 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: - 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 */ - #ifndef OSI_STRIPPED_LIB /** * @brief eqos_config_ptp_rxq - To config PTP RX packets queue @@ -6231,7 +6145,6 @@ void eqos_init_core_ops(struct core_ops *ops) 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->config_tscr = eqos_config_tscr; ops->config_ssir = eqos_config_ssir; ops->adjust_mactime = eqos_adjust_mactime; ops->read_mmc = eqos_read_mmc; diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index cd5d712..166ac77 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -277,8 +277,6 @@ 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_DMA_ISR_MTLIS OSI_BIT(16) #define EQOS_DMA_ISR_MACIS OSI_BIT(17) diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 0ef4b67..dd26005 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -5335,91 +5335,6 @@ static int mgbe_adjust_mactime(struct osi_core_priv_data *osi_core, 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, - nveu32_t 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 * @@ -5743,7 +5658,6 @@ void mgbe_init_core_ops(struct core_ops *ops) 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->config_tscr = mgbe_config_tscr; ops->config_ssir = mgbe_config_ssir, ops->adjust_mactime = mgbe_adjust_mactime; ops->read_mmc = mgbe_read_mmc; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 5b820ca..428b2ad 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -244,8 +244,6 @@ #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)) /** @} */ /** diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index e510bfe..4339440 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -744,7 +744,7 @@ nve32_t osi_ptp_configuration(struct osi_core_priv_data *const osi_core, if (enable == OSI_DISABLE) { /* disable hw time stamping */ /* Program MAC_Timestamp_Control Register */ - l_core->ops_p->config_tscr(osi_core, OSI_DISABLE); + hw_config_tscr(osi_core, OSI_DISABLE); #ifndef OSI_STRIPPED_LIB /* Disable PTP RX Queue routing */ ret = l_core->ops_p->config_ptp_rxq(osi_core, @@ -753,7 +753,7 @@ nve32_t osi_ptp_configuration(struct osi_core_priv_data *const osi_core, #endif /* !OSI_STRIPPED_LIB */ } else { /* Program MAC_Timestamp_Control Register */ - l_core->ops_p->config_tscr(osi_core, + hw_config_tscr(osi_core, osi_core->ptp_config.ptp_filter); /* Program Sub Second Increment Register */ From 4e9d836783b71b33a8501f9aa1e76345291462cc Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Wed, 6 Jul 2022 03:39:44 +0000 Subject: [PATCH 388/458] osi: core: combine config_ssir 1) Combine config_ssir 2) Store MAC version in local core/dma variable for differentiating across SoCs. Bug 3701869 Change-Id: I43dd9f7d2194191d849ea10f15b84b2c40111ee0 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2740328 Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- osi/common/common.h | 14 +++++++-- osi/core/core_common.c | 17 +++++++++++ osi/core/core_common.h | 5 ++++ osi/core/core_local.h | 5 ++-- osi/core/eqos_core.c | 67 ------------------------------------------ osi/core/eqos_core.h | 3 -- osi/core/mgbe_core.c | 45 ---------------------------- osi/core/mgbe_core.h | 4 +-- osi/core/osi_hal.c | 5 ++-- osi/dma/dma_local.h | 2 ++ osi/dma/osi_dma.c | 3 +- 11 files changed, 42 insertions(+), 128 deletions(-) diff --git a/osi/common/common.h b/osi/common/common.h index ec41481..b7ecfc6 100644 --- a/osi/common/common.h +++ b/osi/common/common.h @@ -37,6 +37,12 @@ #define RETRY_DELAY 1U /** @} */ +/** MAC version type for EQOS version previous to 5.30 */ +#define MAC_CORE_VER_TYPE_EQOS 0U +/** MAC version type for EQOS version 5.30 */ +#define MAC_CORE_VER_TYPE_EQOS_5_30 1U +/** MAC version type for MGBE IP */ +#define MAC_CORE_VER_TYPE_MGBE 2U /** * @brief Maximum number of supported MAC IP types (EQOS and MGBE) @@ -248,24 +254,26 @@ static inline void osi_writela(OSI_UNUSED void *priv, nveu32_t val, void *addr) * @retval 1 - for Valid MAC */ static inline nve32_t validate_mac_ver_update_chans(nveu32_t mac_ver, - nveu32_t *max_chans) + nveu32_t *max_chans, + nveu32_t *l_mac_ver) { nve32_t ret; switch (mac_ver) { - case OSI_EQOS_MAC_4_10: case OSI_EQOS_MAC_5_00: *max_chans = OSI_EQOS_XP_MAX_CHANS; + *l_mac_ver = MAC_CORE_VER_TYPE_EQOS; ret = 1; break; case OSI_EQOS_MAC_5_30: *max_chans = OSI_EQOS_MAX_NUM_CHANS; + *l_mac_ver = MAC_CORE_VER_TYPE_EQOS_5_30; ret = 1; 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; + *l_mac_ver = MAC_CORE_VER_TYPE_MGBE; ret = 1; break; default: diff --git a/osi/core/core_common.c b/osi/core/core_common.c index 8037acc..9d55a4d 100644 --- a/osi/core/core_common.c +++ b/osi/core/core_common.c @@ -429,6 +429,23 @@ void hw_config_tscr(struct osi_core_priv_data *const osi_core, OSI_UNUSED const osi_writela(osi_core, value, ((nveu8_t *)addr + mac_pps[osi_core->mac])); } +void hw_config_ssir(struct osi_core_priv_data *const osi_core) +{ + nveul64_t val = 0U; + void *addr = osi_core->base; + const struct core_local *l_core = (struct core_local *)osi_core; + const nveu32_t mac_ssir[2] = { EQOS_MAC_SSIR, MGBE_MAC_SSIR}; + const nveu32_t ptp_ssinc[3] = {OSI_PTP_SSINC_4, OSI_PTP_SSINC_6, OSI_PTP_SSINC_4}; + + /* by default Fine method is enabled */ + /* Fix the SSINC value based on Exact MAC used */ + val = ptp_ssinc[l_core->l_mac_ver]; + + val |= val << MAC_SSIR_SSINC_SHIFT; + /* update Sub-second Increment Value */ + osi_writela(osi_core, (nveu32_t)val, ((nveu8_t *)addr + mac_ssir[osi_core->mac])); +} + #ifndef OSI_STRIPPED_LIB /** * @brief hw_est_read - indirect read the GCL to Software own list diff --git a/osi/core/core_common.h b/osi/core/core_common.h index a7330cb..4b0e9f1 100644 --- a/osi/core/core_common.h +++ b/osi/core/core_common.h @@ -45,6 +45,10 @@ #define MAC_TCR_TSADDREG OSI_BIT(5) #define MAC_PPS_CTL_PPSCTRL0 (OSI_BIT(3) | OSI_BIT(2) |\ OSI_BIT(1) | OSI_BIT(0)) +#define MAC_TCR_TSCFUPDT OSI_BIT(1) +#define MAC_TCR_TSCTRLSSR OSI_BIT(9) +#define MAC_SSIR_SSINC_SHIFT 16U + /** * @addtogroup typedef related info @@ -83,4 +87,5 @@ nve32_t hw_set_systime_to_mac(struct osi_core_priv_data *const osi_core, nve32_t hw_config_addend(struct osi_core_priv_data *const osi_core, const nveu32_t addend); void hw_config_tscr(struct osi_core_priv_data *const osi_core, const nveu32_t ptp_filter); +void hw_config_ssir(struct osi_core_priv_data *const osi_core); #endif /* INCLUDED_CORE_COMMON_H */ diff --git a/osi/core/core_local.h b/osi/core/core_local.h index f197b09..28b415b 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -131,9 +131,6 @@ struct core_ops { const nveu32_t perfect_inverse_match, const nveu32_t dma_routing_enable, const nveu32_t dma_chan); - /** 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 adjust the mac time */ nve32_t (*adjust_mactime)(struct osi_core_priv_data *const osi_core, const nveu32_t sec, @@ -458,6 +455,8 @@ struct core_local { nveu32_t state; /** XPCS Lane bringup/Block lock status */ nveu32_t lane_status; + /** Exact MAC used across SOCs 0:Legacy EQOS, 1:Orin EQOS, 2:Orin MGBE */ + nveu32_t l_mac_ver; }; /** diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index e23bfe8..72c35f6 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -4047,72 +4047,6 @@ static nve32_t eqos_config_ptp_rxq(struct osi_core_priv_data *const osi_core, } #endif /* !OSI_STRIPPED_LIB */ -/** - * @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 <<RM_21, (sequence diagram)>> 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 * @@ -6145,7 +6079,6 @@ void eqos_init_core_ops(struct core_ops *ops) 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->config_ssir = eqos_config_ssir; ops->adjust_mactime = eqos_adjust_mactime; ops->read_mmc = eqos_read_mmc; ops->write_phy_reg = eqos_write_phy_reg; diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 166ac77..010642a 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -416,9 +416,7 @@ #define EQOS_MAC_RQC2_PSRQ_SHIFT 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_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) | \ @@ -429,7 +427,6 @@ #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 diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index dd26005..1839e34 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -5335,50 +5335,6 @@ static int mgbe_adjust_mactime(struct osi_core_priv_data *osi_core, return 0; } -/** - * @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) { - 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_read_reg - Read a register * @@ -5658,7 +5614,6 @@ void mgbe_init_core_ops(struct core_ops *ops) 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->config_ssir = mgbe_config_ssir, ops->adjust_mactime = mgbe_adjust_mactime; ops->read_mmc = mgbe_read_mmc; ops->write_phy_reg = mgbe_write_phy_reg; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 428b2ad..dc49f44 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -536,13 +536,11 @@ #define MGBE_MTL_TXQ_SIZE_SHIFT 16U #define MGBE_MTL_RXQ_SIZE_SHIFT 16U #define MGBE_MAC_RMCR_GPSL_MSK 0x3FFF0000U -#define MGBE_MAC_TCR_TSCFUPDT OSI_BIT(1) #define MGBE_MAC_TCR_TSUPDT OSI_BIT(3) -#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) diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 4339440..8df24be 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -757,8 +757,7 @@ nve32_t osi_ptp_configuration(struct osi_core_priv_data *const osi_core, osi_core->ptp_config.ptp_filter); /* Program Sub Second Increment Register */ - l_core->ops_p->config_ssir(osi_core, - osi_core->ptp_config.ptp_clock); + hw_config_ssir(osi_core); /* formula for calculating addend value is * TSAR = (2^32 * 1000) / (ptp_ref_clk_rate in MHz * SSINC) @@ -839,7 +838,7 @@ static nve32_t osi_get_mac_version(struct osi_core_priv_data *const osi_core, nv *mac_ver = osi_readla(osi_core, ((nveu8_t *)osi_core->base + (nve32_t)MAC_VERSION)) & MAC_VERSION_SNVER_MASK; - if (validate_mac_ver_update_chans(*mac_ver, &l_core->max_chans) == 0) { + if (validate_mac_ver_update_chans(*mac_ver, &l_core->max_chans, &l_core->l_mac_ver) == 0) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid MAC version\n", (nveu64_t)*mac_ver) return -1; diff --git a/osi/dma/dma_local.h b/osi/dma/dma_local.h index 07cd21c..1820ab4 100644 --- a/osi/dma/dma_local.h +++ b/osi/dma/dma_local.h @@ -108,6 +108,8 @@ struct dma_local { nveu64_t magic_num; /** Maximum number of DMA channels */ nveu32_t max_chans; + /** Exact MAC used across SOCs 0:Legacy EQOS, 1:Orin EQOS, 2:Orin MGBE */ + nveu32_t l_mac_ver; }; /** diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index ab59fed..b5e421e 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -515,7 +515,8 @@ nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) 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) { + &l_dma->max_chans, + &l_dma->l_mac_ver) == 0) { OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "Invalid MAC version\n", (nveu64_t)l_dma->mac_ver); return -1; From 209d08a4b096e8f50cab16f07f862c63f3429e45 Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Wed, 6 Jul 2022 09:32:26 +0000 Subject: [PATCH 389/458] osi: core: combine ptp_tsc_capture Bug 3701869 Change-Id: Ib8b2ea895866e2d260aa5e5aa753ecfd49b663ae Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2740494 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/core_common.c | 40 ++++++++++++++++++++++++ osi/core/core_common.h | 8 +++++ osi/core/core_local.h | 2 -- osi/core/eqos_core.c | 70 ------------------------------------------ osi/core/eqos_core.h | 5 --- osi/core/mgbe_core.c | 65 --------------------------------------- osi/core/mgbe_core.h | 5 --- osi/core/osi_hal.c | 2 +- 8 files changed, 49 insertions(+), 148 deletions(-) diff --git a/osi/core/core_common.c b/osi/core/core_common.c index 9d55a4d..1e2c5f2 100644 --- a/osi/core/core_common.c +++ b/osi/core/core_common.c @@ -446,6 +446,46 @@ void hw_config_ssir(struct osi_core_priv_data *const osi_core) osi_writela(osi_core, (nveu32_t)val, ((nveu8_t *)addr + mac_ssir[osi_core->mac])); } +nve32_t hw_ptp_tsc_capture(struct osi_core_priv_data *const osi_core, + struct osi_core_ptp_tsc_data *data) +{ +#ifndef OSI_STRIPPED_LIB + const struct core_local *l_core = (struct core_local *)osi_core; +#endif /* !OSI_STRIPPED_LIB */ + void *addr = osi_core->base; + nveu32_t tsc_ptp = 0U; + nve32_t ret = 0; + +#ifndef OSI_STRIPPED_LIB + /* This code is NA for Orin use case */ + if (l_core->l_mac_ver < MAC_CORE_VER_TYPE_EQOS_5_30) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "ptp_tsc: older IP\n", 0ULL); + ret = -1; + goto exit; + } +#endif /* !OSI_STRIPPED_LIB */ + + osi_writela(osi_core, OSI_ENABLE, (nveu8_t *)osi_core->base + WRAP_SYNC_TSC_PTP_CAPTURE); + + ret = poll_check(osi_core, ((nveu8_t *)addr + WRAP_SYNC_TSC_PTP_CAPTURE), + OSI_ENABLE, &tsc_ptp); + if (ret == -1) { + goto exit; + } + + data->tsc_low_bits = osi_readla(osi_core, (nveu8_t *)osi_core->base + + WRAP_TSC_CAPTURE_LOW); + data->tsc_high_bits = osi_readla(osi_core, (nveu8_t *)osi_core->base + + WRAP_TSC_CAPTURE_HIGH); + data->ptp_low_bits = osi_readla(osi_core, (nveu8_t *)osi_core->base + + WRAP_PTP_CAPTURE_LOW); + data->ptp_high_bits = osi_readla(osi_core, (nveu8_t *)osi_core->base + + WRAP_PTP_CAPTURE_HIGH); +exit: + return ret; +} + #ifndef OSI_STRIPPED_LIB /** * @brief hw_est_read - indirect read the GCL to Software own list diff --git a/osi/core/core_common.h b/osi/core/core_common.h index 4b0e9f1..6ae147b 100644 --- a/osi/core/core_common.h +++ b/osi/core/core_common.h @@ -50,6 +50,12 @@ #define MAC_SSIR_SSINC_SHIFT 16U +#define WRAP_SYNC_TSC_PTP_CAPTURE 0x800CU +#define WRAP_TSC_CAPTURE_LOW 0x8010U +#define WRAP_TSC_CAPTURE_HIGH 0x8014U +#define WRAP_PTP_CAPTURE_LOW 0x8018U +#define WRAP_PTP_CAPTURE_HIGH 0x801CU + /** * @addtogroup typedef related info * @@ -88,4 +94,6 @@ nve32_t hw_config_addend(struct osi_core_priv_data *const osi_core, const nveu32_t addend); void hw_config_tscr(struct osi_core_priv_data *const osi_core, const nveu32_t ptp_filter); void hw_config_ssir(struct osi_core_priv_data *const osi_core); +nve32_t hw_ptp_tsc_capture(struct osi_core_priv_data *const osi_core, + struct osi_core_ptp_tsc_data *data); #endif /* INCLUDED_CORE_COMMON_H */ diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 28b415b..8d03864 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -151,8 +151,6 @@ struct core_ops { /** Called to get HW features */ nve32_t (*get_hw_features)(struct osi_core_priv_data *const osi_core, struct osi_hw_features *hw_feat); - int (*ptp_tsc_capture)(struct osi_core_priv_data *const osi_core, - struct osi_core_ptp_tsc_data *data); /** 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, diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 72c35f6..3cbd1b4 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -44,75 +44,6 @@ static nve32_t eqos_pre_pad_calibrate( */ 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_core->osd, 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. * @@ -6084,7 +6015,6 @@ void eqos_init_core_ops(struct core_ops *ops) ops->write_phy_reg = eqos_write_phy_reg; ops->read_phy_reg = eqos_read_phy_reg; ops->get_hw_features = eqos_get_hw_features; - ops->ptp_tsc_capture = eqos_ptp_tsc_capture; ops->update_ip4_addr = eqos_update_ip4_addr; ops->read_reg = eqos_read_reg; ops->write_reg = eqos_write_reg; diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 010642a..dbd6ef7 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -197,11 +197,6 @@ #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 /** @} */ diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 1839e34..1752974 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -32,70 +32,6 @@ #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_calculate_per_queue_fifo - Calculate per queue FIFO size * @@ -5619,7 +5555,6 @@ void mgbe_init_core_ops(struct core_ops *ops) ops->write_phy_reg = mgbe_write_phy_reg; ops->read_phy_reg = mgbe_read_phy_reg; ops->get_hw_features = mgbe_get_hw_features; - ops->ptp_tsc_capture = mgbe_ptp_tsc_capture; ops->update_ip4_addr = mgbe_update_ip4_addr; ops->read_reg = mgbe_read_reg; ops->write_reg = mgbe_write_reg; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index dc49f44..d77e1bb 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -136,11 +136,6 @@ #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 /** @} */ /** diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 8df24be..71e1645 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -2239,7 +2239,7 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, break; #endif /* OSI_DEBUG */ case OSI_CMD_CAP_TSC_PTP: - ret = ops_p->ptp_tsc_capture(osi_core, &data->ptp_tsc); + ret = hw_ptp_tsc_capture(osi_core, &data->ptp_tsc); break; case OSI_CMD_CONF_M2M_TS: From 600ee00ccadec0a7fea004e8a7dcfad26859f05b Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Fri, 22 Jul 2022 13:28:56 +0530 Subject: [PATCH 390/458] core: configure ETS as default selection algorithm Issue: Default TX selection is SP, due to which highest TX queue get most of TX bandwidth. Fix: Set ETS as selection policy (WRR)with equal weights given to all Tx Queue. Set default configuration on disabling CBS. Bug 3735907 Change-Id: I33b849695641ceaeef77ff819121d51e132214aa Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2749330 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/eqos_core.c | 21 +++++++++++++----- osi/core/mgbe_core.c | 53 +++++++++++++++++++++++++++++++++++++------- osi/core/mgbe_core.h | 8 +++++++ 3 files changed, 69 insertions(+), 13 deletions(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 3cbd1b4..101a4d2 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -901,7 +901,7 @@ static nve32_t eqos_configure_mtl_queue(nveu32_t 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); + value |= EQOS_MTL_TXQ_QW_ISCQW; eqos_core_safety_writel(osi_core, value, (nveu8_t *)osi_core->base + EQOS_MTL_TXQ_QW(qinx), EQOS_MTL_TXQ0_QW_IDX + qinx); @@ -4958,10 +4958,8 @@ static nve32_t eqos_set_avb_algorithm( 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); + osi_writela(osi_core, value, (nveu8_t *)osi_core->base + + EQOS_MTL_TXQ_QW(qinx)); /* Set Hi credit */ value = avb->hi_credit & EQOS_MTL_TXQ_ETS_HCR_HC_MASK; @@ -4974,6 +4972,19 @@ static nve32_t eqos_set_avb_algorithm( 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)); + } else { + /* Reset register values to POR/initialized values */ + osi_writela(osi_core, OSI_DISABLE, (nveu8_t *)osi_core->base + + EQOS_MTL_TXQ_ETS_SSCR(qinx)); + + osi_writela(osi_core, EQOS_MTL_TXQ_QW_ISCQW, + (nveu8_t *)osi_core->base + EQOS_MTL_TXQ_QW(qinx)); + + osi_writela(osi_core, OSI_DISABLE, (nveu8_t *)osi_core->base + + EQOS_MTL_TXQ_ETS_HCR(qinx)); + + osi_writela(osi_core, OSI_DISABLE, (nveu8_t *)osi_core->base + + EQOS_MTL_TXQ_ETS_LCR(qinx)); } return 0; diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 1752974..8f70311 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -2057,6 +2057,14 @@ static nve32_t mgbe_configure_mtl_queue(nveu32_t qinx, return ret; } + if (osi_unlikely((qinx >= OSI_MGBE_MAX_NUM_QUEUES) || + (osi_core->tc[qinx] >= OSI_MAX_TC_NUM))) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "Incorrect queues/TC number\n", 0ULL); + ret = -1; + goto end; + } + value = (tx_fifo << MGBE_MTL_TXQ_SIZE_SHIFT); /* Enable Store and Forward mode */ value |= MGBE_MTL_TSF; @@ -2089,12 +2097,21 @@ static nve32_t mgbe_configure_mtl_queue(nveu32_t qinx, osi_writela(osi_core, value, (unsigned char *)osi_core->base + MGBE_MTL_RXQ_FLOW_CTRL(qinx)); - /* Transmit Queue weight */ + /* Transmit Queue weight, all TX weights are equal */ value = osi_readla(osi_core, (nveu8_t *)osi_core->base + MGBE_MTL_TCQ_QW(qinx)); - value |= (MGBE_MTL_TCQ_QW_ISCQW + qinx); + value |= MGBE_MTL_TCQ_QW_ISCQW; osi_writela(osi_core, value, (nveu8_t *)osi_core->base + MGBE_MTL_TCQ_QW(qinx)); + + /* Default ETS tx selection algo */ + value = osi_readla(osi_core, (nveu8_t *)osi_core->base + + MGBE_MTL_TCQ_ETS_CR(osi_core->tc[qinx])); + value &= ~MGBE_MTL_TCQ_ETS_CR_AVALG; + value |= OSI_MGBE_TXQ_AVALG_ETS; + osi_writela(osi_core, value, (nveu8_t *)osi_core->base + + MGBE_MTL_TCQ_ETS_CR(osi_core->tc[qinx])); + /* Enable Rx Queue Control */ value = osi_readla(osi_core, (nveu8_t *)osi_core->base + MGBE_MAC_RQC0R); @@ -2102,8 +2119,8 @@ static nve32_t mgbe_configure_mtl_queue(nveu32_t qinx, (MGBE_MAC_RXQC0_RXQEN_SHIFT(qinx))); osi_writela(osi_core, value, (nveu8_t *)osi_core->base + MGBE_MAC_RQC0R); - - return 0; +end: + return ret; } #ifndef OSI_STRIPPED_LIB @@ -3487,14 +3504,17 @@ static int mgbe_set_avb_algorithm( /* Set Algo and Credit control */ value = osi_readla(osi_core, (unsigned char *)osi_core->base + MGBE_MTL_TCQ_ETS_CR(tcinx)); + value &= ~MGBE_MTL_TCQ_ETS_CR_AVALG; + value &= ~MGBE_MTL_TCQ_ETS_CR_CC; 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 |= (OSI_MTL_TXQ_AVALG_CBS << MGBE_MTL_TCQ_ETS_CR_AVALG_SHIFT) & + MGBE_MTL_TCQ_ETS_CR_AVALG; + } else { + value |= (OSI_MGBE_TXQ_AVALG_ETS << MGBE_MTL_TCQ_ETS_CR_AVALG_SHIFT) & + MGBE_MTL_TCQ_ETS_CR_AVALG; } - 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)); @@ -3526,6 +3546,23 @@ static int mgbe_set_avb_algorithm( 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)); + } else { + /* Reset register values to POR/initialized values */ + osi_writela(osi_core, MGBE_MTL_TCQ_QW_ISCQW, (nveu8_t *)osi_core->base + + MGBE_MTL_TCQ_QW(tcinx)); + osi_writela(osi_core, OSI_DISABLE, (nveu8_t *)osi_core->base + + MGBE_MTL_TCQ_ETS_SSCR(tcinx)); + osi_writela(osi_core, OSI_DISABLE, (nveu8_t *)osi_core->base + + MGBE_MTL_TCQ_ETS_HCR(tcinx)); + osi_writela(osi_core, OSI_DISABLE, (nveu8_t *)osi_core->base + + MGBE_MTL_TCQ_ETS_LCR(tcinx)); + + value = osi_readla(osi_core, (nveu8_t *)osi_core->base + + MGBE_MTL_CHX_TX_OP_MODE(qinx)); + value &= ~MGBE_MTL_TX_OP_MODE_Q2TCMAP; + value |= (osi_core->tc[qinx] << MGBE_MTL_CHX_TX_OP_MODE_Q2TC_SH); + osi_writela(osi_core, value, (nveu8_t *)osi_core->base + + MGBE_MTL_CHX_TX_OP_MODE(qinx)); } return 0; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index d77e1bb..eac8a31 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -52,7 +52,15 @@ * 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 MTL queue ETS algorithm mode + * + * @brief MTL queue algorithm type + * @{ + */ +#define OSI_MGBE_TXQ_AVALG_ETS 2U /** @} */ /** From 384474dadbd431ac34b61e400769b57eea37a7fd Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Sat, 27 Aug 2022 21:55:06 +0000 Subject: [PATCH 391/458] osi: core: fix misra 4.6 rule ===== DIFF ====== Total misra violation count changed by -240 Rule: MISRA_C-2012_Directive_4.6 Diff: -240 Rule: Total Diff: -240 Bug 3695218 Change-Id: Ida2d3a775872637eda3058ea361a00346c86f7f7 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2767895 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- include/ivc_core.h | 6 +- include/mmc.h | 12 +- include/osi_common.h | 26 +- include/osi_core.h | 128 ++++---- include/osi_dma.h | 18 +- osi/core/core_local.h | 26 +- osi/core/debug.c | 24 +- osi/core/eqos_core.c | 194 +++++------ osi/core/eqos_core.h | 12 +- osi/core/frp.c | 134 ++++---- osi/core/frp.h | 4 +- osi/core/ivc_core.c | 28 +- osi/core/mgbe_core.c | 716 ++++++++++++++++++++--------------------- osi/core/mgbe_core.h | 16 +- osi/core/mgbe_mmc.c | 18 +- osi/core/osi_hal.c | 10 +- osi/core/vlan_filter.c | 116 +++---- osi/core/vlan_filter.h | 5 +- osi/core/xpcs.c | 62 ++-- osi/core/xpcs.h | 30 +- 20 files changed, 792 insertions(+), 793 deletions(-) diff --git a/include/ivc_core.h b/include/ivc_core.h index 8e690b7..d4e5253 100644 --- a/include/ivc_core.h +++ b/include/ivc_core.h @@ -106,11 +106,11 @@ typedef struct macsec_config { /** MACsec secure channel basic information */ struct osi_macsec_sc_info sc_info; /** MACsec enable or disable */ - unsigned int enable; + nveu32_t enable; /** MACsec controller */ - unsigned short ctlr; + nveu16_t ctlr; /** MACsec KT index */ - unsigned short kt_idx; + nveu16_t kt_idx; /** MACsec KT index */ nveu32_t key_index; /** MACsec SCI */ diff --git a/include/mmc.h b/include/mmc.h index 0d3c7ab..1eb449c 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -530,25 +530,25 @@ struct osi_mmc_counters { 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; + nveu64_t 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; + nveu64_t 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; + nveu64_t 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; + nveu64_t 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; + nveu64_t 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; + nveu64_t mmc_rx_fpe_fragment_cnt; }; /** diff --git a/include/osi_common.h b/include/osi_common.h index cffe3ca..9cc8ac0 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -32,19 +32,19 @@ * 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_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_32_K (unsigned int)62 +#define FULL_MINUS_1_5K ((nveu32_t)1) +#define FULL_MINUS_2_K ((nveu32_t)2) +#define FULL_MINUS_2_5K ((nveu32_t)3) +#define FULL_MINUS_3_K ((nveu32_t)4) +#define FULL_MINUS_4_K ((nveu32_t)6) +#define FULL_MINUS_6_K ((nveu32_t)10) +#define FULL_MINUS_10_K ((nveu32_t)18) +#define FULL_MINUS_16_K ((nveu32_t)30) +#define FULL_MINUS_18_K ((nveu32_t)34) +#define FULL_MINUS_21_K ((nveu32_t)40) +#define FULL_MINUS_24_K ((nveu32_t)46) +#define FULL_MINUS_29_K ((nveu32_t)56) +#define FULL_MINUS_32_K ((nveu32_t)62) /** @} */ /** diff --git a/include/osi_core.h b/include/osi_core.h index d2ac5fc..1add2d9 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -460,11 +460,11 @@ struct osi_filter { struct osi_rxq_route { #define OSI_RXQ_ROUTE_PTP 0U /** Indicates RX routing type OSI_RXQ_ROUTE_* */ - unsigned int route_type; + nveu32_t route_type; /** RXQ routing enable(1) disable (0) */ - unsigned int enable; + nveu32_t enable; /** RX queue index */ - unsigned int idx; + nveu32_t idx; }; #endif /** @@ -816,23 +816,23 @@ struct osi_vlan_filter { */ struct osi_core_frp_data { /* Entry Match Data */ - unsigned int match_data; + nveu32_t match_data; /* Entry Match Enable mask */ - unsigned int match_en; + nveu32_t match_en; /* Entry Accept frame flag */ - unsigned char accept_frame; + nveu8_t accept_frame; /* Entry Reject Frame flag */ - unsigned char reject_frame; + nveu8_t reject_frame; /* Entry Inverse match flag */ - unsigned char inverse_match; + nveu8_t inverse_match; /* Entry Next Instruction Control match flag */ - unsigned char next_ins_ctrl; + nveu8_t next_ins_ctrl; /* Entry Frame offset in the packet data */ - unsigned char frame_offset; + nveu8_t frame_offset; /* Entry OK Index - Next Instruction */ - unsigned char ok_index; + nveu8_t ok_index; /* Entry DMA Channel selection (1-bit for each channel) */ - unsigned int dma_chsel; + nveu32_t dma_chsel; }; /** @@ -840,23 +840,23 @@ struct osi_core_frp_data { */ struct osi_core_frp_cmd { /* FRP Command type */ - unsigned int cmd; + nveu32_t cmd; /* OSD FRP ID */ int frp_id; /* OSD match data type */ - unsigned char match_type; + nveu8_t match_type; /* OSD match data */ - unsigned char match[OSI_FRP_MATCH_DATA_MAX]; + nveu8_t match[OSI_FRP_MATCH_DATA_MAX]; /* OSD match data length */ - unsigned char match_length; + nveu8_t match_length; /* OSD Offset */ - unsigned char offset; + nveu8_t offset; /* OSD FRP filter mode flag */ - unsigned char filter_mode; + nveu8_t filter_mode; /* OSD FRP Link ID */ int next_frp_id; /* OSD DMA Channel Selection */ - unsigned int dma_sel; + nveu32_t dma_sel; }; /** @@ -910,7 +910,7 @@ struct osi_core_avb_algorithm { * 10: enable */ nveu32_t oper_mode; /** TC index */ - unsigned int tcindex; + nveu32_t tcindex; }; /** @@ -918,20 +918,20 @@ struct osi_core_avb_algorithm { */ struct osi_pto_config { /** enable(0) / disable(1) */ - unsigned int en_dis; + nveu32_t en_dis; /** Flag for Master mode. * OSI_ENABLE for master OSI_DISABLE for slave */ - unsigned int master; + nveu32_t master; /** Flag to Select PTP packets for Taking Snapshots */ - unsigned int snap_type; + nveu32_t snap_type; /** ptp domain */ - unsigned int domain_num; + nveu32_t 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; + nveu32_t mc_uc; /** Port identification */ - unsigned int portid; + nveu32_t portid; }; /** @@ -939,23 +939,23 @@ struct osi_pto_config { */ struct osi_est_config { /** enable/disable */ - unsigned int en_dis; + nveu32_t 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]; + nveu32_t btr[2]; /** 64 bit base time offset index 0 for nsec, index 1 for sec */ - unsigned int btr_offset[2]; + nveu32_t btr_offset[2]; /** 40 bit cycle time register, index 0 for nsec, index 1 for sec */ - unsigned int ctr[2]; + nveu32_t ctr[2]; /** Configured Time Interval width + 7 bit extension register */ - unsigned int ter; + nveu32_t ter; /** size of the gate control list */ - unsigned int llr; + nveu32_t llr; /** data array 8 bit gate op + 24 execution time * MGBE HW support GCL depth 256 */ - unsigned int gcl[OSI_GCL_SIZE_256]; + nveu32_t gcl[OSI_GCL_SIZE_256]; }; /** @@ -963,11 +963,11 @@ struct osi_est_config { */ struct osi_fpe_config { /** Queue Mask 1 preemption 0- express bit representation */ - unsigned int tx_queue_preemption_enable; + nveu32_t tx_queue_preemption_enable; /** RQ for all preemptable packets which are not filtered * based on user priority or SA-DA */ - unsigned int rq; + nveu32_t rq; }; /** @@ -975,19 +975,19 @@ struct osi_fpe_config { */ struct osi_tsn_stats { /** Constant Gate Control Error */ - unsigned long const_gate_ctr_err; + nveu64_t const_gate_ctr_err; /** Head-Of-Line Blocking due to Scheduling */ - unsigned long head_of_line_blk_sch; + nveu64_t head_of_line_blk_sch; /** Per TC Schedule Error */ - unsigned long hlbs_q[OSI_MAX_TC_NUM]; + nveu64_t hlbs_q[OSI_MAX_TC_NUM]; /** Head-Of-Line Blocking due to Frame Size */ - unsigned long head_of_line_blk_frm; + nveu64_t head_of_line_blk_frm; /** Per TC Frame Size Error */ - unsigned long hlbf_q[OSI_MAX_TC_NUM]; + nveu64_t hlbf_q[OSI_MAX_TC_NUM]; /** BTR Error */ - unsigned long base_time_reg_err; + nveu64_t base_time_reg_err; /** Switch to Software Owned List Complete */ - unsigned long sw_own_list_complete; + nveu64_t sw_own_list_complete; }; /** @@ -996,11 +996,11 @@ struct osi_tsn_stats { */ struct osi_core_rss { /** Flag to represent to enable RSS or not */ - unsigned int enable; + nveu32_t enable; /** Array for storing RSS Hash key */ - unsigned char key[OSI_RSS_HASH_KEY_SIZE]; + nveu8_t key[OSI_RSS_HASH_KEY_SIZE]; /** Array for storing RSS Hash table */ - unsigned int table[OSI_RSS_MAX_TABLE_SIZE]; + nveu32_t table[OSI_RSS_MAX_TABLE_SIZE]; }; /** @@ -1104,7 +1104,7 @@ struct osi_vm_irq_data { */ struct osd_core_ops { /** padctrl rx pin disable/enable callback */ - int (*padctrl_mii_rx_pins)(void *priv, nveu32_t enable); + nve32_t (*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, @@ -1120,7 +1120,7 @@ struct osd_core_ops { 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, + nve32_t (*macsec_tz_kt_config)(void *priv, nveu8_t cmd, void *const kt_config, void *const genl_info); #endif /* MACSEC_SUPPORT */ @@ -1131,7 +1131,7 @@ struct osd_core_ops { const char *fmt, ...); #endif /** Lane bringup restart callback */ - void (*restart_lane_bringup)(void *priv, unsigned int en_disable); + void (*restart_lane_bringup)(void *priv, nveu32_t en_disable); }; #ifdef MACSEC_SUPPORT @@ -1297,19 +1297,19 @@ struct core_padctrl { /** Memory mapped base address of eqos padctrl registers */ void *padctrl_base; /** EQOS_RD0_0 register offset */ - unsigned int offset_rd0; + nveu32_t offset_rd0; /** EQOS_RD1_0 register offset */ - unsigned int offset_rd1; + nveu32_t offset_rd1; /** EQOS_RD2_0 register offset */ - unsigned int offset_rd2; + nveu32_t offset_rd2; /** EQOS_RD3_0 register offset */ - unsigned int offset_rd3; + nveu32_t offset_rd3; /** RX_CTL_0 register offset */ - unsigned int offset_rx_ctl; + nveu32_t offset_rx_ctl; /** is pad calibration in progress */ - unsigned int is_pad_cal_in_progress; + nveu32_t is_pad_cal_in_progress; /** This flag set/reset using priv ioctl and DT entry */ - unsigned int pad_calibration_enable; + nveu32_t pad_calibration_enable; }; #ifndef OSI_STRIPPED_LIB @@ -1405,7 +1405,7 @@ struct osi_core_priv_data { /** 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; + nveu32_t is_fpe_enabled; #endif /* MACSEC_SUPPORT */ /** Pointer to OSD private data structure */ void *osd; @@ -1442,14 +1442,14 @@ struct osi_core_priv_data { /** DMA channel selection enable (1) */ nveu32_t dcs_en; /** TQ:TC mapping */ - unsigned int tc[OSI_MGBE_MAX_NUM_CHANS]; + nveu32_t tc[OSI_MGBE_MAX_NUM_CHANS]; #ifndef OSI_STRIPPED_LIB /** xtra sw error counters */ struct osi_xtra_stat_counters xstats; /** Memory mapped base address of HV window */ void *hv_base; /** Residual queue valid with FPE support */ - unsigned int residual_queue; + nveu32_t residual_queue; /** Functional safety config to do periodic read-verify of * certain safety critical registers */ void *safety_config; @@ -1458,28 +1458,28 @@ struct osi_core_priv_data { /** 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; + nveu32_t frp_cnt; /** RSS core structure */ struct osi_core_rss rss; /* Switch to Software Owned List Complete. * 1 - Successful and User configured GCL in placed */ - unsigned int est_ready; + nveu32_t est_ready; /* FPE enabled, verify and respose done with peer device * 1- Successful and can be used between P2P device */ - unsigned int fpe_ready; + nveu32_t fpe_ready; /** TSN stats counters */ struct osi_tsn_stats tsn_stats; /** csr clock is to program LPI 1 us tick timer register. * Value stored in MHz */ nveu32_t csr_clk_speed; - unsigned long vf_bitmap; + nveu64_t vf_bitmap; /** Array to maintaion VLAN filters */ - unsigned short vid[VLAN_NUM_VID]; + nveu16_t vid[VLAN_NUM_VID]; /** Count of number of VLAN filters in vid array */ - unsigned short vlan_filter_cnt; + nveu16_t vlan_filter_cnt; #endif /** eqos pad control structure */ struct core_padctrl padctrl; diff --git a/include/osi_dma.h b/include/osi_dma.h index 7284bef..be6867d 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -288,13 +288,13 @@ struct osi_pkt_err_stats { /** FRP Parsed count, includes accept * routing-bypass, or result-bypass count. */ - unsigned long frp_parsed; + nveu64_t frp_parsed; /** FRP Dropped count */ - unsigned long frp_dropped; + nveu64_t frp_dropped; /** FRP Parsing Error count */ - unsigned long frp_err; + nveu64_t frp_err; /** FRP Incomplete Parsing */ - unsigned long frp_incomplete; + nveu64_t frp_incomplete; }; #endif /* !OSI_STRIPPED_LIB */ @@ -387,9 +387,9 @@ struct osi_tx_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; + nveu32_t flags; /** Packet id of packet for which TX timestamp needed */ - unsigned int pktid; + nveu32_t pktid; /** dma channel number for osd use */ nveu32_t chan; /** reserved field 1 for future use */ @@ -444,7 +444,7 @@ struct osi_txdone_pkt_cx { * bit is set in fields */ nveul64_t ns; /** Passing packet id to map TX time to packet */ - unsigned int pktid; + nveu32_t pktid; }; /** @@ -608,7 +608,7 @@ struct osi_dma_priv_data { * OSI_PTP_SYNC_ONESTEP - one-step mode * OSI_PTP_SYNC_TWOSTEP - two step mode */ - unsigned int ptp_flag; + nveu32_t ptp_flag; #ifdef OSI_DEBUG /** OSI DMA IOCTL data */ struct osi_dma_ioctl_data ioctl_data; @@ -667,7 +667,7 @@ nveu32_t osi_get_global_dma_status(struct osi_dma_priv_data *osi_dma); * @retval "Number of available free descriptors." */ nveu32_t osi_get_refill_rx_desc_cnt(struct osi_dma_priv_data *osi_dma, - unsigned int chan); + nveu32_t chan); /** * @brief osi_rx_dma_desc_init - DMA Rx descriptor init diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 8d03864..6c91a39 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -212,7 +212,7 @@ struct core_ops { const nveu32_t enable, const nveu8_t *ip_addr); /** Called to configure HW PTP offload feature */ - int (*config_ptp_offload)(struct osi_core_priv_data *const osi_core, + nve32_t (*config_ptp_offload)(struct osi_core_priv_data *const osi_core, struct osi_pto_config *const pto_config); /** Called periodically to read and validate safety critical * registers against last written value */ @@ -248,31 +248,31 @@ struct core_ops { struct osi_core_priv_data *const osi_core, const nveu32_t lb_mode); /** Called to update GCL config */ - int (*hw_config_est)(struct osi_core_priv_data *const osi_core, + nve32_t (*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, + nve32_t (*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); + nve32_t (*config_frp)(struct osi_core_priv_data *const osi_core, + const nveu32_t enabled); /** Called to update FRP Instruction Table entry */ - int (*update_frp_entry)(struct osi_core_priv_data *const osi_core, - const unsigned int pos, + nve32_t (*update_frp_entry)(struct osi_core_priv_data *const osi_core, + const nveu32_t 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); + nve32_t (*update_frp_nve)(struct osi_core_priv_data *const osi_core, + const nveu32_t nve); /** Called to configure RSS for MAC */ nve32_t (*config_rss)(struct osi_core_priv_data *osi_core); /** 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); + const nveu32_t rxq_idx, + const nveu32_t enable); #endif /* !OSI_STRIPPED_LIB */ #ifdef HSI_SUPPORT /** Interface function called to initialize HSI */ - int (*core_hsi_configure)(struct osi_core_priv_data *const osi_core, + nve32_t (*core_hsi_configure)(struct osi_core_priv_data *const osi_core, const nveu32_t enable); #endif }; @@ -458,7 +458,7 @@ struct core_local { }; /** - * @brief update_counter_u - Increment unsigned int counter + * @brief update_counter_u - Increment nveu32_t counter * * @param[out] value: Pointer to value to be incremented. * @param[in] incr: increment value diff --git a/osi/core/debug.c b/osi/core/debug.c index 8b16296..d083b36 100644 --- a/osi/core/debug.c +++ b/osi/core/debug.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -32,7 +32,7 @@ * */ static void core_dump_struct(struct osi_core_priv_data *osi_core, - unsigned char *ptr, + nveu8_t *ptr, unsigned long size) { nveu32_t i = 0, rem, j; @@ -72,40 +72,40 @@ void core_structs_dump(struct osi_core_priv_data *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, + core_dump_struct(osi_core, (nveu8_t *)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, + core_dump_struct(osi_core, (nveu8_t *)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, + core_dump_struct(osi_core, (nveu8_t *)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, + core_dump_struct(osi_core, (nveu8_t *)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, + core_dump_struct(osi_core, (nveu8_t *)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, + core_dump_struct(osi_core, (nveu8_t *)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, + core_dump_struct(osi_core, (nveu8_t *)l_core->if_ops_p, sizeof(struct if_core_ops)); } @@ -116,9 +116,9 @@ void core_structs_dump(struct osi_core_priv_data *osi_core) */ void core_reg_dump(struct osi_core_priv_data *osi_core) { - unsigned int max_addr; - unsigned int addr = 0x0; - unsigned int reg_val; + nveu32_t max_addr; + nveu32_t addr = 0x0; + nveu32_t reg_val; switch (osi_core->mac_ver) { case OSI_EQOS_MAC_5_00: diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 101a4d2..6f7dc03 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -934,12 +934,12 @@ static nve32_t eqos_configure_mtl_queue(nveu32_t qinx, * @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) +static nve32_t eqos_config_frp(struct osi_core_priv_data *const osi_core, + const nveu32_t enabled) { - unsigned char *base = osi_core->base; - unsigned int op_mode = 0U, val = 0U; - int ret = 0; + nveu8_t *base = osi_core->base; + nveu32_t op_mode = 0U, val = 0U; + nve32_t ret = 0; if ((enabled != OSI_ENABLE) && (enabled != OSI_DISABLE)) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, @@ -1016,11 +1016,11 @@ frp_enable_re: * @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) +static nve32_t eqos_update_frp_nve(struct osi_core_priv_data *const osi_core, + const nveu32_t nve) { - unsigned int val; - unsigned char *base = osi_core->base; + nveu32_t val; + nveu8_t *base = osi_core->base; /* Validate the NVE value */ if (nve >= OSI_FRP_MAX_ENTRY) { @@ -1056,13 +1056,13 @@ static int eqos_update_frp_nve(struct osi_core_priv_data *const osi_core, * @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) +static nve32_t eqos_frp_write(struct osi_core_priv_data *osi_core, + nveu32_t addr, + nveu32_t data) { - int ret = 0; - unsigned char *base = osi_core->base; - unsigned int val = 0U; + nve32_t ret = 0; + nveu8_t *base = osi_core->base; + nveu32_t val = 0U; /* Wait for ready */ ret = osi_readl_poll_timeout((base + EQOS_MTL_RXP_IND_CS), @@ -1125,12 +1125,12 @@ static int eqos_frp_write(struct osi_core_priv_data *osi_core, * @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, +static nve32_t eqos_update_frp_entry(struct osi_core_priv_data *const osi_core, + const nveu32_t pos, struct osi_core_frp_data *const data) { - unsigned int val = 0U, tmp = 0U; - int ret = -1; + nveu32_t val = 0U, tmp = 0U; + nve32_t ret = -1; /* Validate pos value */ if (pos >= OSI_FRP_MAX_ENTRY) { @@ -1283,7 +1283,7 @@ static void eqos_configure_rxq_priority( * @retval 0 on success * @retval -1 on failure */ -static int eqos_hsi_configure(struct osi_core_priv_data *const osi_core, +static nve32_t eqos_hsi_configure(struct osi_core_priv_data *const osi_core, const nveu32_t enable) { nveu32_t value; @@ -1638,10 +1638,10 @@ static void eqos_configure_dma(struct osi_core_priv_data *const osi_core) static inline void eqos_enable_mtl_interrupts( struct osi_core_priv_data *const osi_core) { - unsigned int mtl_est_ir = OSI_DISABLE; + nveu32_t mtl_est_ir = OSI_DISABLE; void *addr = osi_core->base; - mtl_est_ir = osi_readla(osi_core, (unsigned char *) + mtl_est_ir = osi_readla(osi_core, (nveu8_t *) addr + EQOS_MTL_EST_ITRE); /* enable only MTL interrupt realted to * Constant Gate Control Error @@ -1654,7 +1654,7 @@ static inline void eqos_enable_mtl_interrupts( 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); + (nveu8_t *)addr + EQOS_MTL_EST_ITRE); } /** @@ -1669,14 +1669,14 @@ static inline void eqos_enable_mtl_interrupts( static inline void eqos_enable_fpe_interrupts( struct osi_core_priv_data *const osi_core) { - unsigned int value = OSI_DISABLE; + nveu32_t 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 = osi_readla(osi_core, (nveu8_t *)addr + EQOS_MAC_IMR); value |= EQOS_IMR_FPEIE; - osi_writela(osi_core, value, (unsigned char *)addr + EQOS_MAC_IMR); + osi_writela(osi_core, value, (nveu8_t *)addr + EQOS_MAC_IMR); } /** @@ -1689,11 +1689,11 @@ static inline void eqos_enable_fpe_interrupts( 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, + nveu32_t 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, + nveu32_t gcl_depthth[6] = {0, OSI_GCL_SIZE_64, OSI_GCL_SIZE_128, OSI_GCL_SIZE_256, OSI_GCL_SIZE_512, OSI_GCL_SIZE_1024}; @@ -1701,7 +1701,7 @@ static inline void eqos_save_gcl_params(struct osi_core_priv_data *osi_core) (osi_core->hw_feature->gcl_width > 3U)) { 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); + (nveul64_t)osi_core->hw_feature->gcl_width); } else { l_core->gcl_width_val = gcl_widhth[osi_core->hw_feature->gcl_width]; @@ -1713,7 +1713,7 @@ static inline void eqos_save_gcl_params(struct osi_core_priv_data *osi_core) /* 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); + (nveul64_t)osi_core->hw_feature->gcl_depth); } else { l_core->gcl_dep = gcl_depthth[osi_core->hw_feature->gcl_depth]; } @@ -1737,14 +1737,14 @@ static inline void eqos_save_gcl_params(struct osi_core_priv_data *osi_core) * @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) + nveu32_t est_sel, nveu32_t fpe_sel) { - unsigned int val = 0x0; - unsigned int temp = 0U; + nveu32_t val = 0x0; + nveu32_t temp = 0U; if (est_sel == OSI_ENABLE) { eqos_save_gcl_params(osi_core); - val = osi_readla(osi_core, (unsigned char *)osi_core->base + + val = osi_readla(osi_core, (nveu8_t *)osi_core->base + EQOS_MTL_EST_CONTROL); /* @@ -1789,14 +1789,14 @@ static void eqos_tsn_init(struct osi_core_priv_data *osi_core, } if (fpe_sel == OSI_ENABLE) { - val = osi_readla(osi_core, (unsigned char *)osi_core->base + + val = osi_readla(osi_core, (nveu8_t *)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 + + osi_writela(osi_core, val, (nveu8_t *)osi_core->base + EQOS_MAC_RQC1R); eqos_enable_fpe_interrupts(osi_core); @@ -2019,11 +2019,11 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core, */ static void eqos_handle_mac_fpe_intrs(struct osi_core_priv_data *osi_core) { - unsigned int val = 0; + nveu32_t 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); + (nveu8_t *)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; @@ -2057,7 +2057,7 @@ static void eqos_handle_mac_fpe_intrs(struct osi_core_priv_data *osi_core) } osi_writela(osi_core, val, - (unsigned char *)osi_core->base + EQOS_MAC_FPE_CTS); + (nveu8_t *)osi_core->base + EQOS_MAC_FPE_CTS); } #endif /* !OSI_STRIPPED_LIB */ @@ -2258,16 +2258,16 @@ static inline void update_dma_sr_stats( */ 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; + nveu32_t val = 0U; + nveu32_t sch_err = 0U; + nveu32_t frm_err = 0U; + nveu32_t temp = 0U; + nveu32_t i = 0; + nveu64_t stat_val = 0U; + nveu32_t value = 0U; val = osi_readla(osi_core, - (unsigned char *)osi_core->base + EQOS_MTL_EST_STATUS); + (nveu8_t *)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); @@ -2550,24 +2550,24 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *const osi_core) #ifndef OSI_STRIPPED_LIB /* Handle MTL inerrupts */ mtl_isr = osi_readla(osi_core, - (unsigned char *)base + EQOS_MTL_INTR_STATUS); + (nveu8_t *)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 + + osi_writela(osi_core, mtl_isr, (nveu8_t *)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); + (nveu8_t *)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); + (nveu8_t *)base + EQOS_MTL_RXP_INTR_CS); #endif /* !OSI_STRIPPED_LIB */ } @@ -3100,14 +3100,14 @@ static nve32_t eqos_update_ip4_addr(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_config_ptp_offload(struct osi_core_priv_data *const osi_core, +static nve32_t eqos_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; + nveu8_t *addr = (nveu8_t *)osi_core->base; + nve32_t ret = 0; + nveu32_t value = 0x0U; + nveu32_t ptc_value = 0x0U; + nveu32_t port_id = 0x0U; /* Read MAC TCR */ value = osi_readla(osi_core, (nveu8_t *)addr + EQOS_MAC_TCR); @@ -3903,12 +3903,12 @@ static nve32_t eqos_adjust_mactime(struct osi_core_priv_data *const osi_core, * @retval -1 on failure. */ static nve32_t eqos_config_ptp_rxq(struct osi_core_priv_data *const osi_core, - const unsigned int rxq_idx, - const unsigned int enable) + const nveu32_t rxq_idx, + const nveu32_t enable) { - unsigned char *base = osi_core->base; - unsigned int value = OSI_NONE; - unsigned int i = 0U; + nveu8_t *base = osi_core->base; + nveu32_t value = OSI_NONE; + nveu32_t i = 0U; /* Validate the RX queue index argment */ if (rxq_idx >= OSI_EQOS_MAX_NUM_QUEUES) { @@ -4018,26 +4018,26 @@ static void eqos_core_deinit(struct osi_core_priv_data *const osi_core) * @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) +static nve32_t eqos_hw_est_write(struct osi_core_priv_data *osi_core, + nveu32_t addr_val, + nveu32_t data, nveu32_t gcla) { void *base = osi_core->base; - int retry = 1000; - unsigned int val = 0x0; + nve32_t retry = 1000; + nveu32_t val = 0x0; - osi_writela(osi_core, data, (unsigned char *)base + EQOS_MTL_EST_DATA); + osi_writela(osi_core, data, (nveu8_t *)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); + (nveu8_t *)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 + + val = osi_readla(osi_core, (nveu8_t *)base + EQOS_MTL_EST_GCL_CONTROL); if ((val & EQOS_MTL_EST_SRWO) == EQOS_MTL_EST_SRWO) { continue; @@ -4077,15 +4077,15 @@ static int eqos_hw_est_write(struct osi_core_priv_data *osi_core, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_hw_config_est(struct osi_core_priv_data *const osi_core, +static nve32_t eqos_hw_config_est(struct osi_core_priv_data *const osi_core, struct osi_est_config *const 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; + nveu32_t btr[2] = {0}; + nveu32_t val = 0x0; + nveu32_t addr = 0x0; + nveu32_t i; + nve32_t ret = 0; if ((osi_core->hw_feature != OSI_NULL) && (osi_core->hw_feature->est_sel == OSI_DISABLE)) { @@ -4161,7 +4161,7 @@ static int eqos_hw_config_est(struct osi_core_priv_data *const osi_core, if (ret < 0) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "GCL enties write failed\n", - (unsigned long long)i); + (nveul64_t)i); return ret; } } @@ -4172,7 +4172,7 @@ static int eqos_hw_config_est(struct osi_core_priv_data *const osi_core, if (ret < 0) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "GCL BTR[0] failed\n", - (unsigned long long)(btr[0] + + (nveul64_t)(btr[0] + est->btr_offset[0])); return ret; } @@ -4182,12 +4182,12 @@ static int eqos_hw_config_est(struct osi_core_priv_data *const osi_core, if (ret < 0) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "GCL BTR[1] failed\n", - (unsigned long long)(btr[1] + + (nveul64_t)(btr[1] + est->btr_offset[1])); return ret; } - val = osi_readla(osi_core, (unsigned char *) + val = osi_readla(osi_core, (nveu8_t *) base + EQOS_MTL_EST_CONTROL); /* Store table */ val |= EQOS_MTL_EST_CONTROL_SSWL; @@ -4214,13 +4214,13 @@ static int eqos_hw_config_est(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -static int eqos_hw_config_fpe(struct osi_core_priv_data *const osi_core, +static nve32_t eqos_hw_config_fpe(struct osi_core_priv_data *const osi_core, struct osi_fpe_config *const fpe) { - unsigned int i = 0U; - unsigned int val = 0U; - unsigned int temp = 0U, temp1 = 0U; - unsigned int temp_shift = 0U; + nveu32_t i = 0U; + nveu32_t val = 0U; + nveu32_t temp = 0U, temp1 = 0U; + nveu32_t temp_shift = 0U; if ((osi_core->hw_feature != OSI_NULL) && (osi_core->hw_feature->fpe_sel == OSI_DISABLE)) { @@ -4280,7 +4280,7 @@ static int eqos_hw_config_fpe(struct osi_core_priv_data *const osi_core, } val = osi_readla(osi_core, - (unsigned char *)osi_core->base + EQOS_MAC_RQC1R); + (nveu8_t *)osi_core->base + EQOS_MAC_RQC1R); val &= ~EQOS_MAC_RQC1R_FPRQ; temp = fpe->rq; temp = temp << EQOS_MAC_RQC1R_FPRQ_SHIFT; @@ -4289,22 +4289,22 @@ static int eqos_hw_config_fpe(struct osi_core_priv_data *const osi_core, /* 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); + (nveu8_t *)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); + (nveu8_t *)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); + (nveu8_t *)osi_core->base + EQOS_MAC_FPE_CTS); val = osi_readla(osi_core, - (unsigned char *)osi_core->base + EQOS_MTL_FPE_ADV); + (nveu8_t *)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); + (nveu8_t *)osi_core->base + EQOS_MTL_FPE_ADV); return 0; } @@ -5636,8 +5636,8 @@ static nve32_t eqos_get_hw_features(struct osi_core_priv_data *const osi_core, * @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) +static nve32_t eqos_padctl_rx_pins(struct osi_core_priv_data *const osi_core, + nveu32_t enable) { nveu32_t value; void *pad_addr = osi_core->padctrl.padctrl_base; @@ -5672,7 +5672,7 @@ static int eqos_padctl_rx_pins(struct osi_core_priv_data *const osi_core, osi_writela(osi_core, value, (nveu8_t *)pad_addr + osi_core->padctrl.offset_rd3); } else { - value = osi_readla(osi_core, (unsigned char *)pad_addr + + 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 + @@ -5714,7 +5714,7 @@ static int eqos_padctl_rx_pins(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -static inline int poll_for_mac_tx_rx_idle(struct osi_core_priv_data *osi_core) +static inline nve32_t poll_for_mac_tx_rx_idle(struct osi_core_priv_data *osi_core) { nveu32_t retry = 0; nveu32_t mac_debug; @@ -5761,7 +5761,7 @@ static inline int poll_for_mac_tx_rx_idle(struct osi_core_priv_data *osi_core) * @retval negative value on failure. */ -static int eqos_pre_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) { nve32_t ret = 0; nveu32_t value; @@ -5806,7 +5806,7 @@ error: /* Enable MAC RGSMIIIE - RGMII/SMII interrupts */ /* Read MAC IMR Register */ - value = osi_readl((unsigned char *)osi_core->base + EQOS_MAC_IMR); + value = osi_readl((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); diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index dbd6ef7..8013344 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -543,18 +543,18 @@ #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 << \ +#define EQOS_MTL_EST_BTR_LOW ((nveu32_t)0x0 << \ EQOS_MTL_EST_ADDR_SHIFT) -#define EQOS_MTL_EST_BTR_HIGH ((unsigned int)0x1 << \ +#define EQOS_MTL_EST_BTR_HIGH ((nveu32_t)0x1 << \ EQOS_MTL_EST_ADDR_SHIFT) -#define EQOS_MTL_EST_CTR_LOW ((unsigned int)0x2 << \ +#define EQOS_MTL_EST_CTR_LOW ((nveu32_t)0x2 << \ EQOS_MTL_EST_ADDR_SHIFT) -#define EQOS_MTL_EST_CTR_HIGH ((unsigned int)0x3 << \ +#define EQOS_MTL_EST_CTR_HIGH ((nveu32_t)0x3 << \ EQOS_MTL_EST_ADDR_SHIFT) #define EQOS_MTL_EST_CTR_HIGH_MAX 0xFFU -#define EQOS_MTL_EST_TER ((unsigned int)0x4 << \ +#define EQOS_MTL_EST_TER ((nveu32_t)0x4 << \ EQOS_MTL_EST_ADDR_SHIFT) -#define EQOS_MTL_EST_LLR ((unsigned int)0x5 << \ +#define EQOS_MTL_EST_LLR ((nveu32_t)0x5 << \ EQOS_MTL_EST_ADDR_SHIFT) /*EST MTL interrupt STATUS and ERR*/ #define EQOS_MTL_IS_ESTIS OSI_BIT(18) diff --git a/osi/core/frp.c b/osi/core/frp.c index df97039..41075b5 100644 --- a/osi/core/frp.c +++ b/osi/core/frp.c @@ -62,12 +62,12 @@ static void frp_entry_copy(struct osi_core_frp_entry *dst, * @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) +static nve32_t frp_entry_find(struct osi_core_priv_data *const osi_core, + nve32_t frp_id, + nveu8_t *start, + nveu8_t *no_entries) { - unsigned char count = OSI_NONE, found = OSI_NONE; + nveu8_t count = OSI_NONE, found = OSI_NONE; struct osi_core_frp_entry *entry = OSI_NULL; /* Parse the FRP table for give frp_id */ @@ -81,7 +81,7 @@ static int frp_entry_find(struct osi_core_priv_data *const osi_core, found = OSI_ENABLE; } else { /* Increment entries */ - *no_entries = (unsigned char) (*no_entries + 1U); + *no_entries = (nveu8_t) (*no_entries + 1U); } } } @@ -105,10 +105,10 @@ static int frp_entry_find(struct osi_core_priv_data *const osi_core, * * @retval No of FRP entries required. */ -static unsigned char frp_req_entries(unsigned char offset, - unsigned char match_length) +static nveu8_t frp_req_entries(nveu8_t offset, + nveu8_t match_length) { - unsigned char req = 0U; + nveu8_t req = 0U; /* Validate for match_length */ if ((match_length == OSI_NONE) || @@ -118,18 +118,18 @@ static unsigned char frp_req_entries(unsigned char offset, } /* Check does the given length can fit in fist entry */ - if (match_length <= (unsigned char) FRP_OFFSET_BYTES(offset)) { + if (match_length <= (nveu8_t) 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)); + match_length = (nveu8_t) (match_length - (nveu8_t) FRP_OFFSET_BYTES(offset)); if ((match_length / FRP_MD_SIZE) < OSI_FRP_MATCH_DATA_MAX) { - req = (unsigned char) (req + (match_length / FRP_MD_SIZE)); + req = (nveu8_t) (req + (match_length / FRP_MD_SIZE)); if ((match_length % FRP_MD_SIZE) != OSI_NONE) { /* Need one more entry */ - req = (unsigned char) (req + 1U); + req = (nveu8_t) (req + 1U); } } @@ -145,7 +145,7 @@ static unsigned char frp_req_entries(unsigned char offset, * @param[in] data: FRP entry data pointer. * */ -static void frp_entry_mode_parse(unsigned char filter_mode, +static void frp_entry_mode_parse(nveu8_t filter_mode, struct osi_core_frp_data *data) { switch (filter_mode) { @@ -216,23 +216,23 @@ static void frp_entry_mode_parse(unsigned char filter_mode, * @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) +static nve32_t frp_entry_add(struct osi_core_priv_data *const osi_core, + nve32_t frp_id, + nveu8_t pos, + nveu8_t *const match, + nveu8_t length, + nveu8_t offset, + nveu8_t filter_mode, + nve32_t next_frp_id, + nveu32_t 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; + nveu32_t req_entries = 0U; + nveu8_t ok_index = 0U; + nveu8_t fo_t = 0U; + nveu8_t fp_t = 0U; + nveu8_t i = 0U, j = 0U, md_pos = 0U; /* Validate length */ if (length > OSI_FRP_MATCH_DATA_MAX) { @@ -275,7 +275,7 @@ static int frp_entry_add(struct osi_core_priv_data *const osi_core, 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; + i = (nveu8_t) next_frp_id; } ok_index = i; } @@ -296,9 +296,9 @@ static int frp_entry_add(struct osi_core_priv_data *const osi_core, 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]) + data->match_data |= ((nveu32_t)match[md_pos]) << (j * FRP_ME_BYTE_SHIFT); - data->match_en |= ((unsigned int)FRP_ME_BYTE << + data->match_en |= ((nveu32_t)FRP_ME_BYTE << (j * FRP_ME_BYTE_SHIFT)); md_pos++; if (md_pos >= length) { @@ -355,12 +355,12 @@ static int frp_entry_add(struct osi_core_priv_data *const osi_core, * @retval 0 on success. * @retval -1 on failure. */ -static int frp_hw_write(struct osi_core_priv_data *const osi_core, +static nve32_t frp_hw_write(struct osi_core_priv_data *const osi_core, struct core_ops *ops_p) { - int ret = -1, tmp = -1; + nve32_t ret = -1, tmp = -1; struct osi_core_frp_entry *entry; - unsigned int frp_cnt = osi_core->frp_cnt, i = OSI_NONE; + nveu32_t frp_cnt = osi_core->frp_cnt, i = OSI_NONE; /* Disable the FRP in HW */ ret = ops_p->config_frp(osi_core, OSI_DISABLE); @@ -410,17 +410,17 @@ hw_write_enable_frp: * @retval 0 on success. * @retval -1 on failure. */ -static int frp_add_proto(struct osi_core_priv_data *const osi_core, +static nve32_t frp_add_proto(struct osi_core_priv_data *const osi_core, struct osi_core_frp_cmd *const cmd, - unsigned char *pos) + nveu8_t *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; + nve32_t ret = -1, proto_oki = -1; + nveu8_t proto_entry = OSI_DISABLE; + nveu8_t req = 0U; + nveu8_t proto_match[FRP_PROTO_LENGTH]; + nveu8_t proto_lendth; + nveu8_t proto_offset; + nveu8_t match_type = cmd->match_type; switch (match_type) { case OSI_FRP_MATCH_L4_S_UPORT: @@ -463,7 +463,7 @@ static int frp_add_proto(struct osi_core_priv_data *const osi_core, /* 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); + req = (nveu8_t) (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", @@ -485,7 +485,7 @@ static int frp_add_proto(struct osi_core_priv_data *const osi_core, } /* Increment pos value */ - *pos = (unsigned char) (*pos + 1U); + *pos = (nveu8_t) (*pos + 1U); } return 0; @@ -503,8 +503,8 @@ static int frp_add_proto(struct osi_core_priv_data *const osi_core, 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; + nveu8_t offset; + nveu8_t match_type = cmd->match_type; switch (match_type) { case OSI_FRP_MATCH_L2_DA: @@ -555,14 +555,14 @@ static void frp_parse_mtype(OSI_UNUSED struct osi_core_priv_data *const osi_core * @retval 0 on success. * @retval -1 on failure. */ -static int frp_delete(struct osi_core_priv_data *const osi_core, +static nve32_t 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; + nve32_t ret = -1; + nveu8_t i = 0U, pos = 0U, count = 0U; + nve32_t frp_id = cmd->frp_id; + nveu32_t frp_cnt = osi_core->frp_cnt; /* Check for FRP entries */ if (frp_cnt == 0U) { @@ -581,7 +581,7 @@ static int frp_delete(struct osi_core_priv_data *const osi_core, } /* Validate pos and count */ - if (((unsigned int)pos + count) > frp_cnt) { + if (((nveu32_t)pos + count) > frp_cnt) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Invalid FRP entry index\n", OSI_NONE); @@ -593,7 +593,7 @@ static int frp_delete(struct osi_core_priv_data *const osi_core, (sizeof(struct osi_core_frp_entry) * count)); /* Move in FRP table entries by count */ - for (i = (unsigned char) (pos + count); i <= frp_cnt; i++) { + for (i = (nveu8_t) (pos + count); i <= frp_cnt; i++) { frp_entry_copy(&osi_core->frp_table[pos], &osi_core->frp_table[i]); pos++; @@ -624,13 +624,13 @@ static int frp_delete(struct osi_core_priv_data *const osi_core, * @retval 0 on success. * @retval -1 on failure. */ -static int frp_update(struct osi_core_priv_data *const osi_core, +static nve32_t 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; + nve32_t ret = -1; + nveu8_t pos = 0U, count = 0U, req = 0U; + nve32_t frp_id = cmd->frp_id; /* Validate given frp_id */ if (frp_entry_find(osi_core, frp_id, &pos, &count) < 0) { @@ -709,14 +709,14 @@ static int frp_update(struct osi_core_priv_data *const osi_core, * @retval 0 on success. * @retval -1 on failure. */ -static int frp_add(struct osi_core_priv_data *const osi_core, +static nve32_t 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; + nve32_t ret = -1; + nveu8_t pos = 0U, count = 0U; + nve32_t frp_id = cmd->frp_id; + nveu32_t nve = osi_core->frp_cnt; /* Check for MAX FRP entries */ if (nve >= OSI_FRP_MAX_ENTRY) { @@ -739,7 +739,7 @@ static int frp_add(struct osi_core_priv_data *const osi_core, frp_parse_mtype(osi_core, cmd); /* Process and add FRP Command Protocal Entry */ - ret = frp_add_proto(osi_core, cmd, (unsigned char *)&nve); + ret = frp_add_proto(osi_core, cmd, (nveu8_t *)&nve); if (ret < 0) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Fail to parse match type\n", @@ -748,7 +748,7 @@ static int frp_add(struct osi_core_priv_data *const osi_core, } /* Add Match data FRP Entry */ - ret = frp_entry_add(osi_core, frp_id, (unsigned char)nve, + ret = frp_entry_add(osi_core, frp_id, (nveu8_t)nve, cmd->match, cmd->match_length, cmd->offset, cmd->filter_mode, cmd->next_frp_id, cmd->dma_sel); @@ -783,11 +783,11 @@ static int frp_add(struct osi_core_priv_data *const osi_core, * @retval 0 on success. * @retval -1 on failure. */ -int setup_frp(struct osi_core_priv_data *const osi_core, +nve32_t 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; + nve32_t ret = -1; switch (cmd->cmd) { case OSI_FRP_CMD_ADD: diff --git a/osi/core/frp.h b/osi/core/frp.h index 6455c20..b8525e3 100644 --- a/osi/core/frp.h +++ b/osi/core/frp.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -65,7 +65,7 @@ * @retval 0 on success. * @retval -1 on failure. */ -int setup_frp(struct osi_core_priv_data *const osi_core, +nve32_t setup_frp(struct osi_core_priv_data *const osi_core, struct core_ops *ops_p, struct osi_core_frp_cmd *const cmd); diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index ce39fa7..c0023cd 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -200,7 +200,7 @@ static nve32_t ivc_read_phy_reg(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -static int ivc_macsec_dbg_events_config( +static nve32_t ivc_macsec_dbg_events_config( struct osi_core_priv_data *const osi_core, struct osi_macsec_dbg_buf_config *const dbg_buf_config) { @@ -236,7 +236,7 @@ exit: * @retval 0 on Success * @retval -1 on Failure */ -static int ivc_macsec_dbg_buf_config( +static nve32_t ivc_macsec_dbg_buf_config( struct osi_core_priv_data *const osi_core, struct osi_macsec_dbg_buf_config *const dbg_buf_config) { @@ -306,7 +306,7 @@ static void ivc_macsec_read_mmc(struct osi_core_priv_data *const osi_core) * @retval 0 on Success * @retval -1 on Failure */ -static int ivc_get_sc_lut_key_index(struct osi_core_priv_data *const osi_core, +static nve32_t ivc_get_sc_lut_key_index(struct osi_core_priv_data *const osi_core, nveu8_t *sci, nveu32_t *key_index, nveu16_t ctlr) { @@ -342,10 +342,10 @@ static int ivc_get_sc_lut_key_index(struct osi_core_priv_data *const osi_core, * @retval 0 on Success * @retval -1 on Failure */ -static int ivc_macsec_config(struct osi_core_priv_data *const osi_core, +static nve32_t 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) + nveu32_t enable, nveu16_t ctlr, + nveu16_t *kt_idx) { ivc_msg_common_t msg; nve32_t ret = 0; @@ -379,8 +379,8 @@ exit: * @retval 0 on Success * @retval -1 on Failure */ -static int ivc_macsec_enable(struct osi_core_priv_data *const osi_core, - unsigned int enable) +static nve32_t ivc_macsec_enable(struct osi_core_priv_data *const osi_core, + nveu32_t enable) { ivc_msg_common_t msg; nveu32_t index = 0; @@ -405,8 +405,8 @@ static int ivc_macsec_enable(struct osi_core_priv_data *const osi_core, * @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) +static nve32_t ivc_macsec_loopback_config(struct osi_core_priv_data *const osi_core, + nveu32_t enable) { ivc_msg_common_t msg; nveu32_t index = 0; @@ -466,8 +466,8 @@ static nve32_t ivc_macsec_kt_config(struct osi_core_priv_data *const osi_core, * @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) +static nve32_t ivc_macsec_cipher_config(struct osi_core_priv_data *const osi_core, + nveu32_t cipher) { ivc_msg_common_t msg; nveu32_t index = 0; @@ -537,7 +537,7 @@ static void ivc_macsec_handle_irq(OSI_UNUSED * @retval -1 on Failure */ -static int ivc_macsec_deinit(struct osi_core_priv_data *const osi_core) +static nve32_t ivc_macsec_deinit(struct osi_core_priv_data *const osi_core) { ivc_msg_common_t msg; @@ -557,7 +557,7 @@ static int ivc_macsec_deinit(struct osi_core_priv_data *const osi_core) * @retval 0 on Success * @retval -1 on Failure */ -static int ivc_macsec_init(struct osi_core_priv_data *const osi_core, +static nve32_t ivc_macsec_init(struct osi_core_priv_data *const osi_core, nveu32_t mtu) { ivc_msg_common_t msg; diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 8f70311..09aadb9 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -120,7 +120,7 @@ static nveu32_t mgbe_calculate_per_queue_fifo(nveu32_t fifo_size, * @retval 0 on success * @retval -1 on failure. */ -static int mgbe_poll_for_mac_acrtl(struct osi_core_priv_data *osi_core) +static nve32_t mgbe_poll_for_mac_acrtl(struct osi_core_priv_data *osi_core) { nveu32_t count = 0U; nveu32_t mac_indir_addr_ctrl = 0U; @@ -158,7 +158,7 @@ static int mgbe_poll_for_mac_acrtl(struct osi_core_priv_data *osi_core) * @retval 0 on success * @retval -1 on failure. */ -static int mgbe_mac_indir_addr_write(struct osi_core_priv_data *osi_core, +static nve32_t mgbe_mac_indir_addr_write(struct osi_core_priv_data *osi_core, nveu32_t mc_no, nveu32_t addr_offset, nveu32_t value) @@ -216,7 +216,7 @@ static int mgbe_mac_indir_addr_write(struct osi_core_priv_data *osi_core, * @retval 0 on success * @retval -1 on failure. */ -static int mgbe_mac_indir_addr_read(struct osi_core_priv_data *osi_core, +static nve32_t mgbe_mac_indir_addr_read(struct osi_core_priv_data *osi_core, nveu32_t mc_no, nveu32_t addr_offset, nveu32_t *value) @@ -272,19 +272,19 @@ static int mgbe_mac_indir_addr_read(struct osi_core_priv_data *osi_core, */ static inline void mgbe_config_l2_da_perfect_inverse_match( struct osi_core_priv_data *osi_core, - unsigned int perfect_inverse_match) + nveu32_t perfect_inverse_match) { - unsigned int value = 0U; + nveu32_t value = 0U; value = osi_readla(osi_core, - (unsigned char *)osi_core->base + MGBE_MAC_PFR); + (nveu8_t *)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); + (nveu8_t *)osi_core->base + MGBE_MAC_PFR); } /** @@ -304,11 +304,11 @@ static inline void mgbe_config_l2_da_perfect_inverse_match( static nve32_t mgbe_config_mac_pkt_filter_reg(struct osi_core_priv_data *const osi_core, const struct osi_filter *filter) { - unsigned int value = 0U; - int ret = 0; + nveu32_t value = 0U; + nve32_t ret = 0; value = osi_readla(osi_core, - (unsigned char *)osi_core->base + MGBE_MAC_PFR); + (nveu8_t *)osi_core->base + MGBE_MAC_PFR); /* Retain all other values */ value &= (MGBE_MAC_PFR_DAIF | MGBE_MAC_PFR_DBF | MGBE_MAC_PFR_SAIF | @@ -346,7 +346,7 @@ static nve32_t mgbe_config_mac_pkt_filter_reg(struct osi_core_priv_data *const o } osi_writela(osi_core, value, - (unsigned char *)osi_core->base + MGBE_MAC_PFR); + (nveu8_t *)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, @@ -376,7 +376,7 @@ static nve32_t mgbe_config_mac_pkt_filter_reg(struct osi_core_priv_data *const o * @retval 0 on success * @retval -1 on failure. */ -static int mgbe_filter_args_validate(struct osi_core_priv_data *const osi_core, +static nve32_t mgbe_filter_args_validate(struct osi_core_priv_data *const osi_core, const struct osi_filter *filter) { nveu32_t idx = filter->index; @@ -457,7 +457,7 @@ static int mgbe_filter_args_validate(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -static int mgbe_update_mac_addr_low_high_reg( +static nve32_t mgbe_update_mac_addr_low_high_reg( struct osi_core_priv_data *const osi_core, const struct osi_filter *filter) { @@ -510,7 +510,7 @@ static int mgbe_update_mac_addr_low_high_reg( 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))); + (nveu8_t *)osi_core->base + MGBE_MAC_ADDRL((idx))); return 0; } @@ -530,17 +530,17 @@ static int mgbe_update_mac_addr_low_high_reg( MGBE_MAC_ADDRH_SA); } - osi_writela(osi_core, ((unsigned int)addr[4] | - ((unsigned int)addr[5] << 8) | + osi_writela(osi_core, ((nveu32_t)addr[4] | + ((nveu32_t)addr[5] << 8) | MGBE_MAC_ADDRH_AE | value), - (unsigned char *)osi_core->base + MGBE_MAC_ADDRH((idx))); + (nveu8_t *)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))); + osi_writela(osi_core, ((nveu32_t)addr[0] | + ((nveu32_t)addr[1] << 8) | + ((nveu32_t)addr[2] << 16) | + ((nveu32_t)addr[3] << 24)), + (nveu8_t *)osi_core->base + MGBE_MAC_ADDRL((idx))); /* Write XDCS configuration into MAC_DChSel_IndReg(x) */ /* Append DCS DMA channel to XDCS hot bit selection */ @@ -566,12 +566,12 @@ static int mgbe_update_mac_addr_low_high_reg( * @retval 0 on success * @retval -1 on failure. */ -static int mgbe_poll_for_l3l4crtl(struct osi_core_priv_data *osi_core) +static nve32_t 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; + nveu32_t retry = 10; + nveu32_t count; + nveu32_t l3l4_addr_ctrl = 0; + nve32_t cond = 1; /* Poll Until L3_L4_Address_Control XB is clear */ count = 0; @@ -584,7 +584,7 @@ static int mgbe_poll_for_l3l4crtl(struct osi_core_priv_data *osi_core) count++; l3l4_addr_ctrl = osi_readla(osi_core, - (unsigned char *)osi_core->base + + (nveu8_t *)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 */ @@ -613,21 +613,21 @@ static int mgbe_poll_for_l3l4crtl(struct osi_core_priv_data *osi_core) * @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) +static nve32_t mgbe_l3l4_filter_write(struct osi_core_priv_data *osi_core, + nveu32_t filter_no, + nveu32_t filter_type, + nveu32_t value) { void *base = osi_core->base; - unsigned int addr = 0; + nveu32_t addr = 0; /* Write MAC_L3_L4_Data register value */ osi_writela(osi_core, value, - (unsigned char *)base + MGBE_MAC_L3L4_DATA); + (nveu8_t *)base + MGBE_MAC_L3L4_DATA); /* Program MAC_L3_L4_Address_Control */ addr = osi_readla(osi_core, - (unsigned char *)base + MGBE_MAC_L3L4_ADDR_CTR); + (nveu8_t *)base + MGBE_MAC_L3L4_ADDR_CTR); /* update filter number */ addr &= ~(MGBE_MAC_L3L4_ADDR_CTR_IDDR_FNUM); @@ -647,7 +647,7 @@ static int mgbe_l3l4_filter_write(struct osi_core_priv_data *osi_core, /* Write MGBE_MAC_L3L4_ADDR_CTR */ osi_writela(osi_core, addr, - (unsigned char *)base + MGBE_MAC_L3L4_ADDR_CTR); + (nveu8_t *)base + MGBE_MAC_L3L4_ADDR_CTR); /* Wait untile XB bit reset */ if (mgbe_poll_for_l3l4crtl(osi_core) < 0) { @@ -675,17 +675,17 @@ static int mgbe_l3l4_filter_write(struct osi_core_priv_data *osi_core, * @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) +static nve32_t mgbe_l3l4_filter_read(struct osi_core_priv_data *osi_core, + nveu32_t filter_no, + nveu32_t filter_type, + nveu32_t *value) { void *base = osi_core->base; - unsigned int addr = 0; + nveu32_t addr = 0; /* Program MAC_L3_L4_Address_Control */ addr = osi_readla(osi_core, - (unsigned char *)base + MGBE_MAC_L3L4_ADDR_CTR); + (nveu8_t *)base + MGBE_MAC_L3L4_ADDR_CTR); /* update filter number */ addr &= ~(MGBE_MAC_L3L4_ADDR_CTR_IDDR_FNUM); @@ -705,7 +705,7 @@ static int mgbe_l3l4_filter_read(struct osi_core_priv_data *osi_core, /* Write MGBE_MAC_L3L4_ADDR_CTR */ osi_writela(osi_core, addr, - (unsigned char *)base + MGBE_MAC_L3L4_ADDR_CTR); + (nveu8_t *)base + MGBE_MAC_L3L4_ADDR_CTR); /* Wait untile XB bit reset */ if (mgbe_poll_for_l3l4crtl(osi_core) < 0) { @@ -717,7 +717,7 @@ static int mgbe_l3l4_filter_read(struct osi_core_priv_data *osi_core, /* Read the MGBE_MAC_L3L4_DATA for filter register data */ *value = osi_readla(osi_core, - (unsigned char *)base + MGBE_MAC_L3L4_DATA); + (nveu8_t *)base + MGBE_MAC_L3L4_DATA); return 0; } @@ -742,9 +742,9 @@ static nve32_t mgbe_update_ip4_addr(struct osi_core_priv_data *const osi_core, const nveu8_t addr[], const nveu32_t src_dst_addr_match) { - unsigned int value = 0U; - unsigned int temp = 0U; - int ret = 0; + nveu32_t value = 0U; + nveu32_t temp = 0U; + nve32_t ret = 0; if (addr == OSI_NULL) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, @@ -756,7 +756,7 @@ static nve32_t mgbe_update_ip4_addr(struct osi_core_priv_data *const osi_core, 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); + (nveul64_t)filter_no); return -1; } @@ -770,11 +770,11 @@ static nve32_t mgbe_update_ip4_addr(struct osi_core_priv_data *const osi_core, } value = addr[3]; - temp = (unsigned int)addr[2] << 8; + temp = (nveu32_t)addr[2] << 8; value |= temp; - temp = (unsigned int)addr[1] << 16; + temp = (nveu32_t)addr[1] << 16; value |= temp; - temp = (unsigned int)addr[0] << 24; + temp = (nveu32_t)addr[0] << 24; value |= temp; if (src_dst_addr_match == OSI_SOURCE_MATCH) { ret = mgbe_l3l4_filter_write(osi_core, @@ -810,9 +810,9 @@ static nve32_t mgbe_update_ip6_addr(struct osi_core_priv_data *const osi_core, const nveu32_t filter_no, const nveu16_t addr[]) { - unsigned int value = 0U; - unsigned int temp = 0U; - int ret = 0; + nveu32_t value = 0U; + nveu32_t temp = 0U; + nve32_t ret = 0; if (addr == OSI_NULL) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, @@ -824,13 +824,13 @@ static nve32_t mgbe_update_ip6_addr(struct osi_core_priv_data *const osi_core, 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); + (nveul64_t)filter_no); return -1; } /* update Bits[31:0] of 128-bit IP addr */ value = addr[7]; - temp = (unsigned int)addr[6] << 16; + temp = (nveu32_t)addr[6] << 16; value |= temp; ret = mgbe_l3l4_filter_write(osi_core, filter_no, @@ -841,7 +841,7 @@ static nve32_t mgbe_update_ip6_addr(struct osi_core_priv_data *const osi_core, } /* update Bits[63:32] of 128-bit IP addr */ value = addr[5]; - temp = (unsigned int)addr[4] << 16; + temp = (nveu32_t)addr[4] << 16; value |= temp; ret = mgbe_l3l4_filter_write(osi_core, filter_no, @@ -852,7 +852,7 @@ static nve32_t mgbe_update_ip6_addr(struct osi_core_priv_data *const osi_core, } /* update Bits[95:64] of 128-bit IP addr */ value = addr[3]; - temp = (unsigned int)addr[2] << 16; + temp = (nveu32_t)addr[2] << 16; value |= temp; ret = mgbe_l3l4_filter_write(osi_core, filter_no, @@ -864,7 +864,7 @@ static nve32_t mgbe_update_ip6_addr(struct osi_core_priv_data *const osi_core, /* update Bits[127:96] of 128-bit IP addr */ value = addr[1]; - temp = (unsigned int)addr[0] << 16; + temp = (nveu32_t)addr[0] << 16; value |= temp; return mgbe_l3l4_filter_write(osi_core, filter_no, @@ -894,14 +894,14 @@ static nve32_t mgbe_update_l4_port_no(struct osi_core_priv_data *osi_core, const nveu16_t port_no, const nveu32_t src_dst_port_match) { - unsigned int value = 0U; - unsigned int temp = 0U; - int ret = 0; + nveu32_t value = 0U; + nveu32_t temp = 0U; + nve32_t 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); + (nveul64_t)filter_no); return -1; } @@ -914,7 +914,7 @@ static nve32_t mgbe_update_l4_port_no(struct osi_core_priv_data *osi_core, 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); + value |= ((nveu32_t)port_no & MGBE_MAC_L4_ADDR_SP_MASK); } else { value &= ~MGBE_MAC_L4_ADDR_DP_MASK; temp = port_no; @@ -939,11 +939,11 @@ static nve32_t mgbe_update_l4_port_no(struct osi_core_priv_data *osi_core, * @retval 0 on success * @retval -1 on failure. */ -static int mgbe_config_l3_l4_filter_enable( +static nve32_t mgbe_config_l3_l4_filter_enable( struct osi_core_priv_data *const osi_core, - unsigned int filter_enb_dis) + nveu32_t filter_enb_dis) { - unsigned int value = 0U; + nveu32_t value = 0U; void *base = osi_core->base; /* validate filter_enb_dis argument */ @@ -954,11 +954,11 @@ static int mgbe_config_l3_l4_filter_enable( return -1; } - value = osi_readla(osi_core, (unsigned char *)base + MGBE_MAC_PFR); + value = osi_readla(osi_core, (nveu8_t *)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); + osi_writela(osi_core, value, (nveu8_t *)base + MGBE_MAC_PFR); return 0; } @@ -970,7 +970,7 @@ static int mgbe_config_l3_l4_filter_enable( * 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] 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 * @@ -979,12 +979,12 @@ static int mgbe_config_l3_l4_filter_enable( * 2) DCS bit of RxQ should be enabled for dynamic channel selection * in filter support * - * @retval updated unsigned int value param + * @retval updated nveu32_t 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) +static inline nveu32_t mgbe_set_dcs(struct osi_core_priv_data *osi_core, + nveu32_t value, + nveu32_t dma_routing_enable, + nveu32_t dma_chan) { if ((dma_routing_enable == OSI_ENABLE) && (dma_chan < OSI_MGBE_MAX_NUM_CHANS) && (osi_core->dcs_en == @@ -1012,11 +1012,11 @@ static inline unsigned int mgbe_set_dcs(struct osi_core_priv_data *osi_core, * * @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) +static inline void mgbe_helper_l3l4_bitmask(nveu32_t *bitmask, + nveu32_t filter_no, + nveu32_t value) { - unsigned int temp; + nveu32_t temp; temp = OSI_ENABLE; temp = temp << filter_no; @@ -1065,13 +1065,13 @@ static nve32_t mgbe_config_l3_filters(struct osi_core_priv_data *osi_core, const nveu32_t dma_routing_enable, const nveu32_t dma_chan) { - unsigned int value = 0U; - int ret = 0; + nveu32_t value = 0U; + nve32_t 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); + (nveul64_t)filter_no); return -1; } /* validate enb_dis argument */ @@ -1109,7 +1109,7 @@ static nve32_t mgbe_config_l3_filters(struct osi_core_priv_data *osi_core, (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); + (nveul64_t)dma_chan); return -1; } @@ -1250,13 +1250,13 @@ static nve32_t mgbe_config_l4_filters(struct osi_core_priv_data *const osi_core, const nveu32_t dma_routing_enable, const nveu32_t dma_chan) { - unsigned int value = 0U; - int ret = 0; + nveu32_t value = 0U; + nve32_t 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); + (nveul64_t)filter_no); return -1; } /* validate enb_dis argument */ @@ -1293,7 +1293,7 @@ static nve32_t mgbe_config_l4_filters(struct osi_core_priv_data *const osi_core, (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); + (nveu32_t)dma_chan); return -1; } @@ -1381,8 +1381,8 @@ static nve32_t mgbe_config_vlan_filtering(struct osi_core_priv_data *osi_core, const nveu32_t perfect_hash_filtering, const nveu32_t perfect_inverse_match) { - unsigned int value; - unsigned char *base = osi_core->base; + nveu32_t value; + nveu8_t *base = osi_core->base; /* validate perfect_inverse_match argument */ if (perfect_hash_filtering == OSI_HASH_FILTER_MODE) { @@ -1447,13 +1447,13 @@ static nve32_t mgbe_config_vlan_filtering(struct osi_core_priv_data *osi_core, * @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) +static nve32_t mgbe_config_ptp_rxq(struct osi_core_priv_data *const osi_core, + const nveu32_t rxq_idx, + const nveu32_t enable) { - unsigned char *base = osi_core->base; - unsigned int value = 0U; - unsigned int i = 0U; + nveu8_t *base = osi_core->base; + nveu32_t value = 0U; + nveu32_t i = 0U; /* Validate the RX queue index argument */ if (rxq_idx >= OSI_MGBE_MAX_NUM_QUEUES) { @@ -1530,7 +1530,7 @@ static int mgbe_config_ptp_rxq(struct osi_core_priv_data *const osi_core, static nve32_t mgbe_config_mac_loopback(struct osi_core_priv_data *const osi_core, nveu32_t lb_mode) { - unsigned int value; + nveu32_t value; void *addr = osi_core->base; /* don't allow only if loopback mode is other than 0 or 1 */ @@ -1539,7 +1539,7 @@ static nve32_t mgbe_config_mac_loopback(struct osi_core_priv_data *const osi_cor } /* Read MAC Configuration Register */ - value = osi_readla(osi_core, (unsigned char *)addr + MGBE_MAC_RMCR); + value = osi_readla(osi_core, (nveu8_t *)addr + MGBE_MAC_RMCR); if (lb_mode == OSI_ENABLE) { /* Enable Loopback Mode */ value |= MGBE_MAC_RMCR_LM; @@ -1547,7 +1547,7 @@ static nve32_t mgbe_config_mac_loopback(struct osi_core_priv_data *const osi_cor value &= ~MGBE_MAC_RMCR_LM; } - osi_writela(osi_core, value, (unsigned char *)addr + MGBE_MAC_RMCR); + osi_writela(osi_core, value, (nveu8_t *)addr + MGBE_MAC_RMCR); return 0; } @@ -1572,35 +1572,35 @@ static nve32_t mgbe_config_mac_loopback(struct osi_core_priv_data *const osi_cor * @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) +static nve32_t mgbe_config_arp_offload(struct osi_core_priv_data *const osi_core, + const nveu32_t enable, + const nveu8_t *ip_addr) { - unsigned int mac_rmcr; - unsigned int val; + nveu32_t mac_rmcr; + nveu32_t 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); + mac_rmcr = osi_readla(osi_core, (nveu8_t *)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])); + val = (((nveu32_t)ip_addr[0]) << 24) | + (((nveu32_t)ip_addr[1]) << 16) | + (((nveu32_t)ip_addr[2]) << 8) | + (((nveu32_t)ip_addr[3])); osi_writela(osi_core, val, - (unsigned char *)addr + MGBE_MAC_ARPPA); + (nveu8_t *)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); + osi_writela(osi_core, mac_rmcr, (nveu8_t *)addr + MGBE_MAC_RMCR); return 0; } @@ -1621,12 +1621,12 @@ static int mgbe_config_arp_offload(struct osi_core_priv_data *const osi_core, * @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) +static nve32_t mgbe_config_frp(struct osi_core_priv_data *const osi_core, + const nveu32_t enabled) { - unsigned char *base = osi_core->base; - unsigned int op_mode = 0U, val = 0U; - int ret = -1; + nveu8_t *base = osi_core->base; + nveu32_t op_mode = 0U, val = 0U; + nve32_t ret = -1; if ((enabled != OSI_ENABLE) && (enabled != OSI_DISABLE)) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, @@ -1712,14 +1712,14 @@ static int mgbe_config_frp(struct osi_core_priv_data *const osi_core, * @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) +static nve32_t mgbe_frp_write(struct osi_core_priv_data *osi_core, + nveu32_t acc_sel, + nveu32_t addr, + nveu32_t data) { - int ret = 0; - unsigned char *base = osi_core->base; - unsigned int val = 0U; + nve32_t ret = 0; + nveu8_t *base = osi_core->base; + nveu32_t val = 0U; if ((acc_sel != OSI_ENABLE) && (acc_sel != OSI_DISABLE)) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, @@ -1797,12 +1797,12 @@ static int mgbe_frp_write(struct osi_core_priv_data *osi_core, * @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, +static nve32_t mgbe_update_frp_entry(struct osi_core_priv_data *const osi_core, + const nveu32_t pos, struct osi_core_frp_data *const data) { - unsigned int val = 0U, tmp = 0U; - int ret = -1; + nveu32_t val = 0U, tmp = 0U; + nve32_t ret = -1; /* Validate pos value */ if (pos >= OSI_FRP_MAX_ENTRY) { @@ -1882,11 +1882,11 @@ static int mgbe_update_frp_entry(struct osi_core_priv_data *const osi_core, * @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) +static nve32_t mgbe_update_frp_nve(struct osi_core_priv_data *const osi_core, + const nveu32_t nve) { - unsigned int val; - unsigned char *base = osi_core->base; + nveu32_t val; + nveu8_t *base = osi_core->base; /* Validate the NVE value */ if (nve >= OSI_FRP_MAX_ENTRY) { @@ -1919,7 +1919,7 @@ static int mgbe_update_frp_nve(struct osi_core_priv_data *const osi_core, * @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) +static void update_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value) { switch (rx_fifo) { case MGBE_21K: @@ -2072,7 +2072,7 @@ static nve32_t mgbe_configure_mtl_queue(nveu32_t qinx, /* 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_writela(osi_core, value, (nveu8_t *) osi_core->base + MGBE_MTL_CHX_TX_OP_MODE(qinx)); /* read RX Q0 Operating Mode Register */ @@ -2091,10 +2091,10 @@ static nve32_t mgbe_configure_mtl_queue(nveu32_t qinx, * RFA: Threshold for Activating Flow Control * RFD: Threshold for Deactivating Flow Control */ - value = osi_readla(osi_core, (unsigned char *)osi_core->base + + value = osi_readla(osi_core, (nveu8_t *)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 + + osi_writela(osi_core, value, (nveu8_t *)osi_core->base + MGBE_MTL_RXQ_FLOW_CTRL(qinx)); /* Transmit Queue weight, all TX weights are equal */ @@ -2139,16 +2139,16 @@ end: * @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) +static nve32_t mgbe_rss_write_reg(struct osi_core_priv_data *osi_core, + nveu32_t idx, + nveu32_t value, + nveu32_t 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; + nveu8_t *addr = (nveu8_t *)osi_core->base; + nveu32_t retry = 100; + nveu32_t ctrl = 0; + nveu32_t count = 0; + nve32_t cond = 1; /* data into RSS Lookup Table or RSS Hash Key */ osi_writela(osi_core, value, addr + MGBE_MAC_RSS_DATA); @@ -2196,12 +2196,12 @@ static int mgbe_rss_write_reg(struct osi_core_priv_data *osi_core, * @retval 0 on success * @retval -1 on failure. */ -static int mgbe_config_rss(struct osi_core_priv_data *osi_core) +static nve32_t 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; + nveu8_t *addr = (nveu8_t *)osi_core->base; + nveu32_t value = 0; + nveu32_t i = 0, j = 0; + nve32_t ret = 0; if (osi_core->rss.enable == OSI_DISABLE) { /* RSS not supported */ @@ -2215,10 +2215,10 @@ static int mgbe_config_rss(struct osi_core_priv_data *osi_core) /* 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)); + value = ((nveu32_t)osi_core->rss.key[i] | + ((nveu32_t)osi_core->rss.key[i + 1U] << 8U) | + ((nveu32_t)osi_core->rss.key[i + 2U] << 16U) | + ((nveu32_t)osi_core->rss.key[i + 3U] << 24U)); ret = mgbe_rss_write_reg(osi_core, j, value, OSI_ENABLE); if (ret < 0) { return ret; @@ -2255,10 +2255,10 @@ static int mgbe_config_rss(struct osi_core_priv_data *osi_core) * @retval 0 on success * @retval -1 on failure. */ -static int mgbe_config_flow_control(struct osi_core_priv_data *const osi_core, +static nve32_t mgbe_config_flow_control(struct osi_core_priv_data *const osi_core, const nveu32_t flw_ctrl) { - unsigned int val; + nveu32_t val; void *addr = osi_core->base; /* return on invalid argument */ @@ -2269,7 +2269,7 @@ static int mgbe_config_flow_control(struct osi_core_priv_data *const osi_core, /* 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)); + (nveu8_t *)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 @@ -2287,12 +2287,12 @@ static int mgbe_config_flow_control(struct osi_core_priv_data *const osi_core, /* Write to MAC Tx Flow control Register of Q0 */ osi_writela(osi_core, val, - (unsigned char *)addr + MGBE_MAC_QX_TX_FLW_CTRL(0U)); + (nveu8_t *)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); + (nveu8_t *)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 @@ -2307,7 +2307,7 @@ static int mgbe_config_flow_control(struct osi_core_priv_data *const osi_core, /* Write to MAC Rx Flow control Register */ osi_writela(osi_core, val, - (unsigned char *)addr + MGBE_MAC_RX_FLW_CTRL); + (nveu8_t *)addr + MGBE_MAC_RX_FLW_CTRL); return 0; } @@ -2325,11 +2325,11 @@ static int mgbe_config_flow_control(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure */ -static int mgbe_hsi_configure(struct osi_core_priv_data *const osi_core, +static nve32_t mgbe_hsi_configure(struct osi_core_priv_data *const osi_core, const nveu32_t enable) { nveu32_t value = 0U; - int ret = 0; + nve32_t ret = 0; if (enable == OSI_ENABLE) { osi_core->hsi.enabled = OSI_ENABLE; @@ -2513,9 +2513,9 @@ static int mgbe_hsi_configure(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -static int mgbe_configure_mac(struct osi_core_priv_data *osi_core) +static nve32_t mgbe_configure_mac(struct osi_core_priv_data *osi_core) { - unsigned int value = 0U, max_queue = 0U, i = 0U; + nveu32_t 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, @@ -2544,10 +2544,10 @@ static int mgbe_configure_mac(struct osi_core_priv_data *osi_core) } osi_writela(osi_core, value, - (unsigned char *)osi_core->base + MGBE_MAC_RMCR); + (nveu8_t *)osi_core->base + MGBE_MAC_RMCR); value = osi_readla(osi_core, - (unsigned char *)osi_core->base + MGBE_MAC_TMCR); + (nveu8_t *)osi_core->base + MGBE_MAC_TMCR); /* DDIC bit set is needed to improve MACSEC Tput */ value |= MGBE_MAC_TMCR_DDIC; /* Jabber Disable */ @@ -2555,11 +2555,11 @@ static int mgbe_configure_mac(struct osi_core_priv_data *osi_core) value |= MGBE_MAC_TMCR_JD; } osi_writela(osi_core, value, - (unsigned char *)osi_core->base + MGBE_MAC_TMCR); + (nveu8_t *)osi_core->base + MGBE_MAC_TMCR); /* Enable Multicast and Broadcast Queue */ value = osi_readla(osi_core, - (unsigned char *)osi_core->base + MGBE_MAC_RQC1R); + (nveu8_t *)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++) { @@ -2572,7 +2572,7 @@ static int mgbe_configure_mac(struct osi_core_priv_data *osi_core) 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); + (nveu8_t *)osi_core->base + MGBE_MAC_RQC1R); /* Disable all MMC nve32_terrupts */ /* Disable all MMC Tx nve32_terrupts */ @@ -2600,15 +2600,15 @@ static int mgbe_configure_mac(struct osi_core_priv_data *osi_core) 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 + + value = osi_readla(osi_core, (nveu8_t *)osi_core->base + MGBE_WRAP_COMMON_INTR_ENABLE); value |= MGBE_MAC_SBD_INTR; - osi_writela(osi_core, value, (unsigned char *)osi_core->base + + osi_writela(osi_core, value, (nveu8_t *)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); + (nveu8_t *)osi_core->base + MGBE_MAC_VLAN_TR); /* Enable VLAN Tag in RX Status * Disable double VLAN Tag processing on TX and RX */ @@ -2618,16 +2618,16 @@ static int mgbe_configure_mac(struct osi_core_priv_data *osi_core) } value |= MGBE_MAC_VLANTR_EVLRXS | MGBE_MAC_VLANTR_DOVLTC; osi_writela(osi_core, value, - (unsigned char *)osi_core->base + MGBE_MAC_VLAN_TR); + (nveu8_t *)osi_core->base + MGBE_MAC_VLAN_TR); value = osi_readla(osi_core, - (unsigned char *)osi_core->base + MGBE_MAC_VLANTIR); + (nveu8_t *)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); + (nveu8_t *)osi_core->base + MGBE_MAC_VLANTIR); #ifndef OSI_STRIPPED_LIB /* Configure default flow control settings */ @@ -2709,8 +2709,8 @@ static void mgbe_configure_dma(struct osi_core_priv_data *osi_core) 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; + nveu8_t *base = (nveu8_t *)osi_core->base; + nveu32_t i; /* MAC registers backup */ config->reg_addr[MGBE_MAC_TMCR_BAK_IDX] = base + MGBE_MAC_TMCR; @@ -2794,9 +2794,9 @@ static void mgbe_core_backup_init(struct osi_core_priv_data *const osi_core) static inline void mgbe_enable_mtl_interrupts( struct osi_core_priv_data *osi_core) { - unsigned int mtl_est_ir = OSI_DISABLE; + nveu32_t mtl_est_ir = OSI_DISABLE; - mtl_est_ir = osi_readla(osi_core, (unsigned char *) + mtl_est_ir = osi_readla(osi_core, (nveu8_t *) osi_core->base + MGBE_MTL_EST_ITRE); /* enable only MTL interrupt realted to * Constant Gate Control Error @@ -2809,7 +2809,7 @@ static inline void mgbe_enable_mtl_interrupts( 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); + (nveu8_t *)osi_core->base + MGBE_MTL_EST_ITRE); } /** @@ -2824,14 +2824,14 @@ static inline void mgbe_enable_mtl_interrupts( static inline void mgbe_enable_fpe_interrupts( struct osi_core_priv_data *osi_core) { - unsigned int value = OSI_DISABLE; + nveu32_t value = OSI_DISABLE; /* Read MAC IER Register and enable Frame Preemption Interrupt * Enable */ - value = osi_readla(osi_core, (unsigned char *) + value = osi_readla(osi_core, (nveu8_t *) osi_core->base + MGBE_MAC_IER); value |= MGBE_IMR_FPEIE; - osi_writela(osi_core, value, (unsigned char *) + osi_writela(osi_core, value, (nveu8_t *) osi_core->base + MGBE_MAC_IER); } @@ -2845,11 +2845,11 @@ static inline void mgbe_enable_fpe_interrupts( 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, + nveu32_t 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, + nveu32_t gcl_depthth[6] = {0, OSI_GCL_SIZE_64, OSI_GCL_SIZE_128, OSI_GCL_SIZE_256, OSI_GCL_SIZE_512, OSI_GCL_SIZE_1024}; @@ -2857,7 +2857,7 @@ static inline void mgbe_save_gcl_params(struct osi_core_priv_data *osi_core) (osi_core->hw_feature->gcl_width > 3U)) { 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); + (nveul64_t)osi_core->hw_feature->gcl_width); } else { l_core->gcl_width_val = gcl_widhth[osi_core->hw_feature->gcl_width]; @@ -2869,7 +2869,7 @@ static inline void mgbe_save_gcl_params(struct osi_core_priv_data *osi_core) /* 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); + (nveul64_t)osi_core->hw_feature->gcl_depth); } else { l_core->gcl_dep = gcl_depthth[osi_core->hw_feature->gcl_depth]; } @@ -2893,14 +2893,14 @@ static inline void mgbe_save_gcl_params(struct osi_core_priv_data *osi_core) * @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) + nveu32_t est_sel, nveu32_t fpe_sel) { - unsigned int val = 0x0; - unsigned int temp = 0U; + nveu32_t val = 0x0; + nveu32_t temp = 0U; if (est_sel == OSI_ENABLE) { mgbe_save_gcl_params(osi_core); - val = osi_readla(osi_core, (unsigned char *)osi_core->base + + val = osi_readla(osi_core, (nveu8_t *)osi_core->base + MGBE_MTL_EST_CONTROL); /* @@ -2928,7 +2928,7 @@ static void mgbe_tsn_init(struct osi_core_priv_data *osi_core, val &= ~MGBE_MTL_EST_CONTROL_DDBF; val |= MGBE_MTL_EST_CONTROL_DDBF; - osi_writela(osi_core, val, (unsigned char *)osi_core->base + + osi_writela(osi_core, val, (nveu8_t *)osi_core->base + MGBE_MTL_EST_CONTROL); val = osi_readla(osi_core, (nveu8_t *)osi_core->base + @@ -2943,14 +2943,14 @@ static void mgbe_tsn_init(struct osi_core_priv_data *osi_core, } if (fpe_sel == OSI_ENABLE) { - val = osi_readla(osi_core, (unsigned char *)osi_core->base + + val = osi_readla(osi_core, (nveu8_t *)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 + + osi_writela(osi_core, val, (nveu8_t *)osi_core->base + MGBE_MAC_RQC1R); val = osi_readla(osi_core, (nveu8_t *)osi_core->base + @@ -3078,21 +3078,21 @@ static nve32_t mgbe_core_init(struct osi_core_priv_data *const osi_core, 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 + + osi_writela(osi_core, value, (nveu8_t *)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 + + osi_writela(osi_core, value, (nveu8_t *)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 + + osi_writela(osi_core, value, (nveu8_t *)osi_core->base + MGBE_MTL_RXQ_DMA_MAP2); /* Enable XDCS in MAC_Extended_Configuration */ @@ -3158,10 +3158,10 @@ static nve32_t mgbe_core_init(struct osi_core_priv_data *const osi_core, */ static void mgbe_handle_mac_fpe_intrs(struct osi_core_priv_data *osi_core) { - unsigned int val = 0; + nveu32_t val = 0; /* interrupt bit clear on read as CSR_SW is reset */ - val = osi_readla(osi_core, (unsigned char *) + val = osi_readla(osi_core, (nveu8_t *) osi_core->base + MGBE_MAC_FPE_CTS); if ((val & MGBE_MAC_FPE_CTS_RVER) == MGBE_MAC_FPE_CTS_RVER) { @@ -3195,7 +3195,7 @@ static void mgbe_handle_mac_fpe_intrs(struct osi_core_priv_data *osi_core) val &= ~MGBE_MAC_FPE_CTS_EFPE; } - osi_writela(osi_core, val, (unsigned char *) + osi_writela(osi_core, val, (nveu8_t *) osi_core->base + MGBE_MAC_FPE_CTS); } #endif /* !OSI_STRIPPED_LIB */ @@ -3244,7 +3244,7 @@ static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core, #endif /* !OSI_STRIPPED_LIB */ mac_isr = osi_readla(osi_core, - (unsigned char *)osi_core->base + MGBE_MAC_ISR); + (nveu8_t *)osi_core->base + MGBE_MAC_ISR); /* Handle MAC interrupts */ if ((dma_isr & MGBE_DMA_ISR_MACIS) != MGBE_DMA_ISR_MACIS) { return; @@ -3264,7 +3264,7 @@ static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core, #ifndef OSI_STRIPPED_LIB mac_ier = osi_readla(osi_core, - (unsigned char *)osi_core->base + MGBE_MAC_IER); + (nveu8_t *)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); @@ -3275,7 +3275,7 @@ static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core, /* Check for the type of Tx error by reading MAC_Rx_Tx_Status * register */ - tx_errors = osi_readl((unsigned char *)osi_core->base + + tx_errors = osi_readl((nveu8_t *)osi_core->base + MGBE_MAC_RX_TX_STS); if ((tx_errors & MGBE_MAC_TX_TJT) == MGBE_MAC_TX_TJT) { /* increment Tx Jabber timeout stats */ @@ -3430,14 +3430,14 @@ static inline void mgbe_update_dma_sr_stats(struct osi_core_priv_data *osi_core, * @retval 0 on success * @retval -1 on failure. */ -static int mgbe_set_avb_algorithm( +static nve32_t 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; + nveu32_t value; + nve32_t ret = -1; + nveu32_t qinx = 0U; + nveu32_t tcinx = 0U; if (avb == OSI_NULL) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, @@ -3450,7 +3450,7 @@ static int mgbe_set_avb_algorithm( 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); + (nveul64_t)avb->qindex); return ret; } @@ -3458,7 +3458,7 @@ static int mgbe_set_avb_algorithm( 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); + (nveul64_t)avb->qindex); return ret; } @@ -3466,7 +3466,7 @@ static int mgbe_set_avb_algorithm( 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); + (nveul64_t)avb->tcindex); return ret; } @@ -3474,7 +3474,7 @@ static int mgbe_set_avb_algorithm( 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); + (nveul64_t)avb->qindex); return ret; } @@ -3482,13 +3482,13 @@ static int mgbe_set_avb_algorithm( 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); + (nveul64_t)avb->tcindex); return ret; } qinx = avb->qindex; tcinx = avb->tcindex; - value = osi_readla(osi_core, (unsigned char *)osi_core->base + + value = osi_readla(osi_core, (nveu8_t *)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 */ @@ -3498,11 +3498,11 @@ static int mgbe_set_avb_algorithm( 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 + + osi_writela(osi_core, value, (nveu8_t *)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 + + value = osi_readla(osi_core, (nveu8_t *)osi_core->base + MGBE_MTL_TCQ_ETS_CR(tcinx)); value &= ~MGBE_MTL_TCQ_ETS_CR_AVALG; value &= ~MGBE_MTL_TCQ_ETS_CR_CC; @@ -3515,36 +3515,36 @@ static int mgbe_set_avb_algorithm( value |= (OSI_MGBE_TXQ_AVALG_ETS << MGBE_MTL_TCQ_ETS_CR_AVALG_SHIFT) & MGBE_MTL_TCQ_ETS_CR_AVALG; } - osi_writela(osi_core, value, (unsigned char *)osi_core->base + + osi_writela(osi_core, value, (nveu8_t *)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 + + value = osi_readla(osi_core, (nveu8_t *)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 + + osi_writela(osi_core, value, (nveu8_t *)osi_core->base + MGBE_MTL_TCQ_QW(tcinx)); /* Set Send slope credit */ - value = osi_readla(osi_core, (unsigned char *)osi_core->base + + value = osi_readla(osi_core, (nveu8_t *)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 + + osi_writela(osi_core, value, (nveu8_t *)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 + + osi_writela(osi_core, value, (nveu8_t *)osi_core->base + MGBE_MTL_TCQ_ETS_HCR(tcinx)); - /* low credit is -ve number, osi_write need a unsigned int + /* low credit is -ve number, osi_write need a nveu32_t * 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 + + osi_writela(osi_core, value, (nveu8_t *)osi_core->base + MGBE_MTL_TCQ_ETS_LCR(tcinx)); } else { /* Reset register values to POR/initialized values */ @@ -3591,13 +3591,13 @@ static int mgbe_set_avb_algorithm( * @retval 0 on success * @retval -1 on failure. */ -static int mgbe_get_avb_algorithm(struct osi_core_priv_data *const osi_core, +static nve32_t 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; + nveu32_t value; + nve32_t ret = -1; + nveu32_t qinx = 0U; + nveu32_t tcinx = 0U; if (avb == OSI_NULL) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, @@ -3609,12 +3609,12 @@ static int mgbe_get_avb_algorithm(struct osi_core_priv_data *const osi_core, 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); + (nveul64_t)avb->qindex); return ret; } qinx = avb->qindex; - value = osi_readla(osi_core, (unsigned char *)osi_core->base + + value = osi_readla(osi_core, (nveu8_t *)osi_core->base + MGBE_MTL_CHX_TX_OP_MODE(qinx)); /* Get TxQ/TC mode as per input struct after masking 3:2 bit */ @@ -3627,7 +3627,7 @@ static int mgbe_get_avb_algorithm(struct osi_core_priv_data *const osi_core, tcinx = avb->tcindex; /* Get Algo and Credit control */ - value = osi_readla(osi_core, (unsigned char *)osi_core->base + + value = osi_readla(osi_core, (nveu8_t *)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; @@ -3636,24 +3636,24 @@ static int mgbe_get_avb_algorithm(struct osi_core_priv_data *const osi_core, if (avb->algo == OSI_MTL_TXQ_AVALG_CBS) { /* Get Idle slope credit*/ - value = osi_readla(osi_core, (unsigned char *)osi_core->base + + value = osi_readla(osi_core, (nveu8_t *)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 + + value = osi_readla(osi_core, (nveu8_t *)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 + + value = osi_readla(osi_core, (nveu8_t *)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 + + value = osi_readla(osi_core, (nveu8_t *)osi_core->base + MGBE_MTL_TCQ_ETS_LCR(tcinx)); avb->low_credit = value & MGBE_MTL_TCQ_ETS_LCR_LC_MASK; } @@ -3678,24 +3678,24 @@ static int mgbe_get_avb_algorithm(struct osi_core_priv_data *const osi_core, * @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) + nveu32_t mtl_isr) { - unsigned int val = 0U; - unsigned int sch_err = 0U; - unsigned int frm_err = 0U; - unsigned int temp = 0U; - unsigned int i = 0; + nveu32_t val = 0U; + nveu32_t sch_err = 0U; + nveu32_t frm_err = 0U; + nveu32_t temp = 0U; + nveu32_t i = 0; unsigned long stat_val = 0U; - unsigned int value = 0U; - unsigned int qstatus = 0U; - unsigned int qinx = 0U; + nveu32_t value = 0U; + nveu32_t qstatus = 0U; + nveu32_t 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 + + qstatus = osi_readl((nveu8_t *)osi_core->base + MGBE_MTL_QINT_STATUS(qinx)); /* Transmit Queue Underflow Interrupt Status */ if (qstatus & MGBE_MTL_QINT_TXUNIFS) { @@ -3707,7 +3707,7 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core, #endif /* !OSI_STRIPPED_LIB */ } /* Clear interrupt status by writing back with 1 */ - osi_writel(1U, (unsigned char *)osi_core->base + + osi_writel(1U, (nveu8_t *)osi_core->base + MGBE_MTL_QINT_STATUS(qinx)); } } @@ -3755,7 +3755,7 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core, 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 */ + /* Reset EST with prnve32_t to configure it properly */ value = osi_readla(osi_core, (nveu8_t *)osi_core->base + MGBE_MTL_EST_CONTROL); value &= ~MGBE_MTL_EST_EEST; @@ -3786,7 +3786,7 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core, osi_writela(osi_core, frm_err, (nveu8_t *)osi_core->base + MGBE_MTL_EST_FRMS_ERR); - /* Reset EST with print to configure it properly */ + /* Reset EST with prnve32_t 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 */ @@ -3823,7 +3823,7 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core, (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 + + osi_writela(osi_core, mtl_isr, (nveu8_t *)osi_core->base + MGBE_MTL_INTR_STATUS); } @@ -3842,17 +3842,17 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core, * @retval -1 on failure. */ -static int mgbe_config_ptp_offload(struct osi_core_priv_data *const osi_core, +static nve32_t 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; + nveu8_t *addr = (nveu8_t *)osi_core->base; + nve32_t ret = 0; + nveu32_t value = 0x0U; + nveu32_t ptc_value = 0x0U; + nveu32_t port_id = 0x0U; /* Read MAC TCR */ - value = osi_readla(osi_core, (unsigned char *)addr + MGBE_MAC_TCR); + value = osi_readla(osi_core, (nveu8_t *)addr + MGBE_MAC_TCR); /* clear old configuration */ value &= ~(MGBE_MAC_TCR_TSENMACADDR | OSI_MAC_TCR_SNAPTYPSEL_3 | @@ -4062,14 +4062,14 @@ static void mgbe_handle_hsi_intr(struct osi_core_priv_data *osi_core) static void mgbe_handle_common_intr(struct osi_core_priv_data *const 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; + nveu32_t dma_isr = 0; + nveu32_t qinx = 0; + nveu32_t i = 0; + nveu32_t dma_sr = 0; + nveu32_t dma_ier = 0; #ifndef OSI_STRIPPED_LIB - unsigned int mtl_isr = 0; - unsigned int val = 0; + nveu32_t mtl_isr = 0; + nveu32_t val = 0; #endif /* !OSI_STRIPPED_LIB */ #ifdef HSI_SUPPORT @@ -4126,18 +4126,18 @@ static void mgbe_handle_common_intr(struct osi_core_priv_data *const osi_core) #ifndef OSI_STRIPPED_LIB /* Handle MTL inerrupts */ mtl_isr = osi_readla(osi_core, - (unsigned char *)base + MGBE_MTL_INTR_STATUS); + (nveu8_t *)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 + + (nveu8_t *)base + MGBE_WRAP_COMMON_INTR_STATUS); + val = osi_readla(osi_core, (nveu8_t *)osi_core->base + MGBE_WRAP_COMMON_INTR_ENABLE); val |= MGBE_MAC_SBD_INTR; - osi_writela(osi_core, val, (unsigned char *)osi_core->base + + osi_writela(osi_core, val, (nveu8_t *)osi_core->base + MGBE_WRAP_COMMON_INTR_ENABLE); /* Clear FRP Interrupts in MTL_RXP_Interrupt_Control_Status */ @@ -4219,13 +4219,13 @@ static void mgbe_core_deinit(struct osi_core_priv_data *const osi_core) * * @param[in] osi_core: OSI core data struture. */ -static int mgbe_mdio_busy_wait(struct osi_core_priv_data *const osi_core) +static nve32_t 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; + nveu32_t retry = 50000; + nveu32_t mac_gmiiar; + nveu32_t count; + nve32_t cond = 1; count = 0; while (cond == 1) { @@ -4235,7 +4235,7 @@ static int mgbe_mdio_busy_wait(struct osi_core_priv_data *const osi_core) count++; - mac_gmiiar = osi_readla(osi_core, (unsigned char *) + mac_gmiiar = osi_readla(osi_core, (nveu8_t *) osi_core->base + MGBE_MDIO_SCCD); if ((mac_gmiiar & MGBE_MDIO_SCCD_SBUSY) == 0U) { cond = 0; @@ -4260,12 +4260,12 @@ static int mgbe_mdio_busy_wait(struct osi_core_priv_data *const osi_core) * @retval 0 on success * @retval -1 on failure. */ -static inline int mgbe_save_registers( +static inline nve32_t mgbe_save_registers( struct osi_core_priv_data *const osi_core) { - unsigned int i = 0; + nveu32_t i = 0; struct core_backup *config = &osi_core->backup_config; - int ret = 0; + nve32_t ret = 0; /* Save direct access registers */ for (i = 0; i < MGBE_DIRECT_MAX_BAK_IDX; i++) { @@ -4341,12 +4341,12 @@ static inline int mgbe_save_registers( * @retval 0 on success * @retval -1 on failure. */ -static inline int mgbe_restore_registers( +static inline nve32_t mgbe_restore_registers( struct osi_core_priv_data *const osi_core) { - unsigned int i = 0; + nveu32_t i = 0; struct core_backup *config = &osi_core->backup_config; - int ret = 0; + nve32_t ret = 0; /* Restore direct access registers */ for (i = 0; i < MGBE_MAX_BAK_IDX; i++) { @@ -4426,13 +4426,13 @@ static inline int mgbe_restore_registers( * @retval 0 on success * @retval -1 on failure. */ -static int mgbe_write_phy_reg(struct osi_core_priv_data *osi_core, +static nve32_t mgbe_write_phy_reg(struct osi_core_priv_data *osi_core, nveu32_t phyaddr, nveu32_t phyreg, nveu16_t phydata) { - int ret = 0; - unsigned int reg; + nve32_t ret = 0; + nveu32_t reg; /* Wait for any previous MII read/write operation to complete */ ret = mgbe_mdio_busy_wait(osi_core); @@ -4451,7 +4451,7 @@ static int mgbe_write_phy_reg(struct osi_core_priv_data *osi_core, /* 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_writela(osi_core, reg, (nveu8_t *) osi_core->base + MGBE_MDIO_SCCA); /* Program Data register */ @@ -4468,7 +4468,7 @@ static int mgbe_write_phy_reg(struct osi_core_priv_data *osi_core, 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_writela(osi_core, reg, (nveu8_t *) osi_core->base + MGBE_MDIO_SCCD); /* wait for MII write operation to complete */ @@ -4498,13 +4498,13 @@ static int mgbe_write_phy_reg(struct osi_core_priv_data *osi_core, * @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) +static nve32_t mgbe_read_phy_reg(struct osi_core_priv_data *osi_core, + nveu32_t phyaddr, + nveu32_t phyreg) { - unsigned int reg; - unsigned int data; - int ret = 0; + nveu32_t reg; + nveu32_t data; + nve32_t ret = 0; ret = mgbe_mdio_busy_wait(osi_core); if (ret < 0) { @@ -4522,7 +4522,7 @@ static int mgbe_read_phy_reg(struct osi_core_priv_data *osi_core, /* 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_writela(osi_core, reg, (nveu8_t *) osi_core->base + MGBE_MDIO_SCCA); /* Program Data register */ @@ -4538,7 +4538,7 @@ static int mgbe_read_phy_reg(struct osi_core_priv_data *osi_core, 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_writela(osi_core, reg, (nveu8_t *) osi_core->base + MGBE_MDIO_SCCD); ret = mgbe_mdio_busy_wait(osi_core); @@ -4550,11 +4550,11 @@ static int mgbe_read_phy_reg(struct osi_core_priv_data *osi_core, return ret; } - reg = osi_readla(osi_core, (unsigned char *) + reg = osi_readla(osi_core, (nveu8_t *) osi_core->base + MGBE_MDIO_SCCD); data = (reg & MGBE_MDIO_SCCD_SDATA_MASK); - return (int)data; + return (nve32_t)data; } #ifndef OSI_STRIPPED_LIB @@ -4573,26 +4573,26 @@ static int mgbe_read_phy_reg(struct osi_core_priv_data *osi_core, * @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) +static nve32_t mgbe_hw_est_write(struct osi_core_priv_data *osi_core, + nveu32_t addr_val, nveu32_t data, + nveu32_t gcla) { - int retry = 1000; - unsigned int val = 0x0; + nve32_t retry = 1000; + nveu32_t val = 0x0; - osi_writela(osi_core, data, (unsigned char *)osi_core->base + + osi_writela(osi_core, data, (nveu8_t *)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 + + osi_writela(osi_core, val, (nveu8_t *)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 + + val = osi_readla(osi_core, (nveu8_t *)osi_core->base + MGBE_MTL_EST_GCL_CONTROL); if ((val & MGBE_MTL_EST_SRWO) == MGBE_MTL_EST_SRWO) { continue; @@ -4632,15 +4632,15 @@ static int mgbe_hw_est_write(struct osi_core_priv_data *osi_core, * @retval 0 on success * @retval -1 on failure. */ -static int mgbe_hw_config_est(struct osi_core_priv_data *const osi_core, +static nve32_t mgbe_hw_config_est(struct osi_core_priv_data *const osi_core, struct osi_est_config *const est) { - unsigned int btr[2] = {0}; - unsigned int val = 0x0; + nveu32_t btr[2] = {0}; + nveu32_t val = 0x0; void *base = osi_core->base; - unsigned int i; - int ret = 0; - unsigned int addr = 0x0; + nveu32_t i; + nve32_t ret = 0; + nveu32_t addr = 0x0; if ((osi_core->hw_feature != OSI_NULL) && (osi_core->hw_feature->est_sel == OSI_DISABLE)) { @@ -4650,10 +4650,10 @@ static int mgbe_hw_config_est(struct osi_core_priv_data *const osi_core, } if (est->en_dis == OSI_DISABLE) { - val = osi_readla(osi_core, (unsigned char *) + val = osi_readla(osi_core, (nveu8_t *) base + MGBE_MTL_EST_CONTROL); val &= ~MGBE_MTL_EST_EEST; - osi_writela(osi_core, val, (unsigned char *) + osi_writela(osi_core, val, (nveu8_t *) base + MGBE_MTL_EST_CONTROL); return 0; @@ -4712,7 +4712,7 @@ static int mgbe_hw_config_est(struct osi_core_priv_data *const osi_core, if (ret < 0) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "GCL enties write failed\n", - (unsigned long long)i); + (nveul64_t)i); return ret; } } @@ -4723,7 +4723,7 @@ static int mgbe_hw_config_est(struct osi_core_priv_data *const osi_core, if (ret < 0) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "GCL BTR[0] failed\n", - (unsigned long long)(btr[0] + + (nveul64_t)(btr[0] + est->btr_offset[0])); return ret; } @@ -4733,18 +4733,18 @@ static int mgbe_hw_config_est(struct osi_core_priv_data *const osi_core, if (ret < 0) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "GCL BTR[1] failed\n", - (unsigned long long)(btr[1] + + (nveul64_t)(btr[1] + est->btr_offset[1])); return ret; } - val = osi_readla(osi_core, (unsigned char *) + val = osi_readla(osi_core, (nveu8_t *) 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 *) + osi_writela(osi_core, val, (nveu8_t *) base + MGBE_MTL_EST_CONTROL); return ret; @@ -4766,14 +4766,14 @@ static int mgbe_hw_config_est(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -static int mgbe_hw_config_fpe(struct osi_core_priv_data *const osi_core, +static nve32_t mgbe_hw_config_fpe(struct osi_core_priv_data *const osi_core, struct osi_fpe_config *const fpe) { - unsigned int i = 0U; - unsigned int val = 0U; - unsigned int temp = 0U, temp1 = 0U; - unsigned int temp_shift = 0U; - int ret = 0; + nveu32_t i = 0U; + nveu32_t val = 0U; + nveu32_t temp = 0U, temp1 = 0U; + nveu32_t temp_shift = 0U; + nve32_t ret = 0; if ((osi_core->hw_feature != OSI_NULL) && (osi_core->hw_feature->fpe_sel == OSI_DISABLE)) { @@ -4846,7 +4846,7 @@ static int mgbe_hw_config_fpe(struct osi_core_priv_data *const osi_core, goto exit; } - val = osi_readla(osi_core, (unsigned char *) + val = osi_readla(osi_core, (nveu8_t *) osi_core->base + MGBE_MAC_RQC1R); val &= ~MGBE_MAC_RQC1R_RQ; temp = fpe->rq; @@ -4854,7 +4854,7 @@ static int mgbe_hw_config_fpe(struct osi_core_priv_data *const osi_core, temp = (temp & MGBE_MAC_RQC1R_RQ); val |= temp; osi_core->residual_queue = fpe->rq; - osi_writela(osi_core, val, (unsigned char *) + osi_writela(osi_core, val, (nveu8_t *) osi_core->base + MGBE_MAC_RQC1R); val = osi_readla(osi_core, (nveu8_t *)osi_core->base + MGBE_MAC_RQC4R); @@ -4866,18 +4866,18 @@ static int mgbe_hw_config_fpe(struct osi_core_priv_data *const osi_core, 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 *) + val = osi_readla(osi_core, (nveu8_t *) osi_core->base + MGBE_MTL_FPE_CTS); val |= MGBE_MAC_FPE_CTS_SVER; - osi_writela(osi_core, val, (unsigned char *) + osi_writela(osi_core, val, (nveu8_t *) osi_core->base + MGBE_MAC_FPE_CTS); - val = osi_readla(osi_core, (unsigned char *) + val = osi_readla(osi_core, (nveu8_t *) 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_writela(osi_core, val, (nveu8_t *) osi_core->base + MGBE_MTL_FPE_ADV); #ifdef MACSEC_SUPPORT @@ -4905,14 +4905,14 @@ exit: */ static inline void mgbe_disable_tx_lpi(struct osi_core_priv_data *osi_core) { - unsigned int lpi_csr = 0; + nveu32_t lpi_csr = 0; /* Disable LPI control bits */ - lpi_csr = osi_readla(osi_core, (unsigned char *) + lpi_csr = osi_readla(osi_core, (nveu8_t *) 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_writela(osi_core, lpi_csr, (nveu8_t *) osi_core->base + MGBE_MAC_LPI_CSR); } @@ -4939,10 +4939,10 @@ static void mgbe_configure_eee(struct osi_core_priv_data *const osi_core, const nveu32_t tx_lpi_enabled, const nveu32_t 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; + nveu32_t lpi_csr = 0; + nveu32_t lpi_timer_ctrl = 0; + nveu32_t lpi_entry_timer = 0; + nveu32_t tic_counter = 0; void *addr = osi_core->base; if (xpcs_eee(osi_core, tx_lpi_enabled) != 0) { @@ -4969,7 +4969,7 @@ static void mgbe_configure_eee(struct osi_core_priv_data *const osi_core, 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 + + osi_writela(osi_core, lpi_timer_ctrl, (nveu8_t *)addr + MGBE_MAC_LPI_TIMER_CTRL); /* 4. For GMII, read the link status of the PHY chip by @@ -4984,7 +4984,7 @@ static void mgbe_configure_eee(struct osi_core_priv_data *const osi_core, /* 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 + + osi_writela(osi_core, tic_counter, (nveu8_t *)addr + MGBE_MAC_1US_TIC_COUNT); /* 6. Program the MAC_LPI_Auto_Entry_Timer register (LPIET) @@ -4994,7 +4994,7 @@ static void mgbe_configure_eee(struct osi_core_priv_data *const osi_core, * 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 + + osi_writela(osi_core, lpi_entry_timer, (nveu8_t *)addr + MGBE_MAC_LPI_EN_TIMER); /* 7. Set LPIATE and LPITXA (bit[20:19]) of @@ -5005,11 +5005,11 @@ static void mgbe_configure_eee(struct osi_core_priv_data *const osi_core, * 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 *) + lpi_csr = osi_readla(osi_core, (nveu8_t *) 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 *) + osi_writela(osi_core, lpi_csr, (nveu8_t *) addr + MGBE_MAC_LPI_CSR); } else { /* Disable LPI control bits */ @@ -5018,15 +5018,15 @@ static void mgbe_configure_eee(struct osi_core_priv_data *const osi_core, } #endif /* !OSI_STRIPPED_LIB */ -static int mgbe_get_hw_features(struct osi_core_priv_data *const osi_core, +static nve32_t mgbe_get_hw_features(struct osi_core_priv_data *const 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; + nveu8_t *base = (nveu8_t *)osi_core->base; + nveu32_t mac_hfr0 = 0; + nveu32_t mac_hfr1 = 0; + nveu32_t mac_hfr2 = 0; + nveu32_t mac_hfr3 = 0; + nveu32_t val = 0; mac_hfr0 = osi_readla(osi_core, base + MGBE_MAC_HFR0); mac_hfr1 = osi_readla(osi_core, base + MGBE_MAC_HFR1); @@ -5199,15 +5199,15 @@ static int mgbe_get_hw_features(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -static inline int mgbe_poll_for_update_ts_complete( +static inline nve32_t mgbe_poll_for_update_ts_complete( struct osi_core_priv_data *osi_core, - unsigned int *mac_tcr) + nveu32_t *mac_tcr) { - unsigned int retry = 0U; + nveu32_t retry = 0U; while (retry < OSI_POLL_COUNT) { /* Read and Check TSUPDT in MAC_Timestamp_Control register */ - *mac_tcr = osi_readla(osi_core, (unsigned char *) + *mac_tcr = osi_readla(osi_core, (nveu8_t *) osi_core->base + MGBE_MAC_TCR); if ((*mac_tcr & MGBE_MAC_TCR_TSUPDT) == 0U) { return 0; @@ -5238,16 +5238,16 @@ static inline int mgbe_poll_for_update_ts_complete( * @retval 0 on success * @retval -1 on failure. */ -static int mgbe_adjust_mactime(struct osi_core_priv_data *osi_core, +static nve32_t mgbe_adjust_mactime(struct osi_core_priv_data *osi_core, nveu32_t sec, nveu32_t nsec, nveu32_t add_sub, nveu32_t one_nsec_accuracy) { void *addr = osi_core->base; - unsigned int mac_tcr; - unsigned int value = 0; - unsigned long long temp = 0; - int ret; + nveu32_t mac_tcr; + nveu32_t value = 0; + nveul64_t temp = 0; + nve32_t ret; /* To be sure previous write was flushed (if Any) */ ret = mgbe_poll_for_update_ts_complete(osi_core, &mac_tcr); @@ -5262,7 +5262,7 @@ static int mgbe_adjust_mactime(struct osi_core_priv_data *osi_core, */ temp = (TWO_POWER_32 - sec); if (temp < UINT_MAX) { - sec = (unsigned int)temp; + sec = (nveu32_t)temp; } else { /* do nothing here */ } @@ -5285,20 +5285,20 @@ static int mgbe_adjust_mactime(struct osi_core_priv_data *osi_core, } /* write seconds value to MAC_System_Time_Seconds_Update register */ - osi_writela(osi_core, sec, (unsigned char *)addr + MGBE_MAC_STSUR); + osi_writela(osi_core, sec, (nveu8_t *)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); + osi_writela(osi_core, value, (nveu8_t *)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); + osi_writela(osi_core, mac_tcr, (nveu8_t *)addr + MGBE_MAC_TCR); ret = mgbe_poll_for_update_ts_complete(osi_core, &mac_tcr); if (ret == -1) { diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index eac8a31..0f72fbf 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -33,7 +33,7 @@ * 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_DEFAULT_LPI_LS_TIMER ((nveu32_t)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 @@ -491,7 +491,7 @@ #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_EVLS_ALWAYS_STRIP ((nveu32_t)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) @@ -627,18 +627,18 @@ #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 << \ +#define MGBE_MTL_EST_BTR_LOW ((nveu32_t)0x0 << \ MGBE_MTL_EST_ADDR_SHIFT) -#define MGBE_MTL_EST_BTR_HIGH ((unsigned int)0x1 << \ +#define MGBE_MTL_EST_BTR_HIGH ((nveu32_t)0x1 << \ MGBE_MTL_EST_ADDR_SHIFT) -#define MGBE_MTL_EST_CTR_LOW ((unsigned int)0x2 << \ +#define MGBE_MTL_EST_CTR_LOW ((nveu32_t)0x2 << \ MGBE_MTL_EST_ADDR_SHIFT) -#define MGBE_MTL_EST_CTR_HIGH ((unsigned int)0x3 << \ +#define MGBE_MTL_EST_CTR_HIGH ((nveu32_t)0x3 << \ MGBE_MTL_EST_ADDR_SHIFT) #define MGBE_MTL_EST_CTR_HIGH_MAX 0xFFU -#define MGBE_MTL_EST_TER ((unsigned int)0x4 << \ +#define MGBE_MTL_EST_TER ((nveu32_t)0x4 << \ MGBE_MTL_EST_ADDR_SHIFT) -#define MGBE_MTL_EST_LLR ((unsigned int)0x5 << \ +#define MGBE_MTL_EST_LLR ((nveu32_t)0x5 << \ MGBE_MTL_EST_ADDR_SHIFT) /*EST MTL interrupt STATUS and ERR*/ #define MGBE_MTL_IS_ESTIS OSI_BIT(18) diff --git a/osi/core/mgbe_mmc.c b/osi/core/mgbe_mmc.c index 2c124d9..10f6563 100644 --- a/osi/core/mgbe_mmc.c +++ b/osi/core/mgbe_mmc.c @@ -43,12 +43,12 @@ * @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) +static inline nveu64_t update_mmc_val(struct osi_core_priv_data *osi_core, + nveu64_t last_value, + nveu64_t offset) { - unsigned long temp; - unsigned int value = osi_readl((unsigned char *)osi_core->base + + nveu64_t temp; + nveu32_t value = osi_readl((nveu8_t *)osi_core->base + offset); temp = last_value + value; @@ -56,7 +56,7 @@ static inline unsigned long update_mmc_val(struct osi_core_priv_data *osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, "Value overflow resetting all counters\n", - (unsigned long long)offset); + (nveul64_t)offset); mgbe_reset_mmc(osi_core); } else { return temp; @@ -77,12 +77,12 @@ static inline unsigned long update_mmc_val(struct osi_core_priv_data *osi_core, */ void mgbe_reset_mmc(struct osi_core_priv_data *const osi_core) { - unsigned int value; + nveu32_t value; - value = osi_readl((unsigned char *)osi_core->base + MGBE_MMC_CNTRL); + value = osi_readl((nveu8_t *)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_writel(value, (nveu8_t *)osi_core->base + MGBE_MMC_CNTRL); osi_memset(&osi_core->mmc, 0U, sizeof(struct osi_mmc_counters)); } diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 71e1645..b8c23fa 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -214,7 +214,7 @@ static nve32_t osi_hal_init_core_ops(struct osi_core_priv_data *const osi_core) */ static inline void init_vlan_filters(struct osi_core_priv_data *const osi_core) { - unsigned int i = 0U; + nveu32_t i = 0U; for (i = 0; i < VLAN_NUM_VID; i++) { osi_core->vid[i] = VLAN_ID_INVALID; @@ -294,7 +294,7 @@ 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 *)(void *)osi_core; - int ret = -1; + nve32_t ret = -1; /* Validate input arguments */ if (pto_config == OSI_NULL) { @@ -964,8 +964,8 @@ static nve32_t vlan_id_update(struct osi_core_priv_data *const osi_core, const nveu32_t vid) { struct core_local *const l_core = (struct core_local *)(void *)osi_core; - unsigned int action = vid & VLAN_ACTION_MASK; - unsigned short vlan_id = (unsigned short)(vid & VLAN_VID_MASK); + nveu32_t action = vid & VLAN_ACTION_MASK; + nveu16_t vlan_id = (nveu16_t)(vid & VLAN_VID_MASK); if ((osi_core->mac_ver == OSI_EQOS_MAC_4_10) || (osi_core->mac_ver == OSI_EQOS_MAC_5_00)) { @@ -1067,7 +1067,7 @@ static nve32_t conf_eee(struct osi_core_priv_data *const osi_core, * @retval 0 on success * @retval -1 on failure. */ -static int configure_frp(struct osi_core_priv_data *const osi_core, +static nve32_t 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 *)(void *)osi_core; diff --git a/osi/core/vlan_filter.c b/osi/core/vlan_filter.c index e5209fd..03ea908 100644 --- a/osi/core/vlan_filter.c +++ b/osi/core/vlan_filter.c @@ -36,11 +36,11 @@ * @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( +static inline nveu32_t get_vlan_filter_idx( struct osi_core_priv_data *osi_core, - unsigned short vlan_id) + nveu16_t vlan_id) { - unsigned int vid_idx = VLAN_HW_FILTER_FULL_IDX; + nveu32_t vid_idx = VLAN_HW_FILTER_FULL_IDX; unsigned long bitmap = osi_core->vf_bitmap; unsigned long temp = 0U; @@ -49,7 +49,7 @@ static inline unsigned int get_vlan_filter_idx( if (osi_core->vid[temp] == vlan_id) { /* vlan ID match found */ - vid_idx = (unsigned int)temp; + vid_idx = (nveu32_t)temp; break; } @@ -71,11 +71,11 @@ static inline unsigned int get_vlan_filter_idx( * * @return 0 on success */ -static inline int allow_all_vid_tags(unsigned char *base, - unsigned int pass_all_vids) +static inline nve32_t allow_all_vid_tags(nveu8_t *base, + nveu32_t pass_all_vids) { - unsigned int vlan_tag_reg = 0; - unsigned int hash_filter_reg = 0; + nveu32_t vlan_tag_reg = 0; + nveu32_t hash_filter_reg = 0; vlan_tag_reg = osi_readl(base + MAC_VLAN_TAG_CTRL); hash_filter_reg = osi_readl(base + MAC_VLAN_HASH_FILTER); @@ -85,7 +85,7 @@ static inline int allow_all_vid_tags(unsigned char *base, 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; + hash_filter_reg &= (nveu32_t) ~VLAN_HASH_ALLOW_ALL; } osi_writel(vlan_tag_reg, base + MAC_VLAN_TAG_CTRL); @@ -108,11 +108,11 @@ static inline int allow_all_vid_tags(unsigned char *base, * @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) +static inline nve32_t is_vlan_id_enqueued(struct osi_core_priv_data *osi_core, + nveu16_t vlan_id, + nveu32_t *idx) { - unsigned int i = 0; + nveu32_t i = 0; if (osi_core->vlan_filter_cnt == VLAN_HW_FILTER_FULL_IDX) { /* No elements in SW queue to search */ @@ -141,11 +141,11 @@ static inline int is_vlan_id_enqueued(struct osi_core_priv_data *osi_core, * @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) +static inline nve32_t enqueue_vlan_id(struct osi_core_priv_data *osi_core, + nveu16_t vlan_id) { - int ret = 0; - unsigned int idx; + nve32_t ret = 0; + nveu32_t idx; if (osi_core->vlan_filter_cnt == VLAN_NUM_VID) { /* Entire SW queue full */ @@ -178,13 +178,13 @@ static inline int enqueue_vlan_id(struct osi_core_priv_data *osi_core, * @return 0 on success. * @return -1 on failure. */ -static inline int poll_for_vlan_filter_reg_rw( +static inline nve32_t 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; + nveu32_t retry = 10; + nveu32_t count; + nveu32_t val = 0; + nve32_t cond = 1; count = 0; while (cond == 1) { @@ -196,7 +196,7 @@ static inline int poll_for_vlan_filter_reg_rw( count++; - val = osi_readl((unsigned char *)osi_core->base + + val = osi_readl((nveu8_t *)osi_core->base + MAC_VLAN_TAG_CTRL); if ((val & MAC_VLAN_TAG_CTRL_OB) == OSI_NONE) { /* Set cond to 0 to exit loop */ @@ -223,17 +223,17 @@ static inline int poll_for_vlan_filter_reg_rw( * @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) +static inline nve32_t update_vlan_filters(struct osi_core_priv_data *osi_core, + nveu32_t vid_idx, + nveu32_t val) { - unsigned char *base = (unsigned char *)osi_core->base; - int ret = 0; + nveu8_t *base = (nveu8_t *)osi_core->base; + nve32_t 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 &= (nveu32_t) ~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; @@ -260,13 +260,13 @@ static inline int update_vlan_filters(struct osi_core_priv_data *osi_core, * @return 0 on success * @return -1 on failure. */ -static inline int add_vlan_id(struct osi_core_priv_data *osi_core, +static inline nve32_t add_vlan_id(struct osi_core_priv_data *osi_core, struct core_ops *ops_p, - unsigned short vlan_id) + nveu16_t vlan_id) { - unsigned int vid_idx = 0; - unsigned int val = 0; - int ret = 0; + nveu32_t vid_idx = 0; + nveu32_t val = 0; + nve32_t ret = 0; /* Check if VLAN ID already programmed */ vid_idx = get_vlan_filter_idx(osi_core, vlan_id); @@ -278,7 +278,7 @@ static inline int add_vlan_id(struct osi_core_priv_data *osi_core, } /* Get free index to add the VID */ - vid_idx = (unsigned int) __builtin_ctzl(~osi_core->vf_bitmap); + vid_idx = (nveu32_t) __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 */ @@ -306,8 +306,8 @@ static inline int add_vlan_id(struct osi_core_priv_data *osi_core, } } - val = osi_readl((unsigned char *)osi_core->base + MAC_VLAN_TAG_DATA); - val &= (unsigned int) ~VLAN_VID_MASK; + val = osi_readl((nveu8_t *)osi_core->base + MAC_VLAN_TAG_DATA); + val &= (nveu32_t) ~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); @@ -326,10 +326,10 @@ static inline int add_vlan_id(struct osi_core_priv_data *osi_core, * @return 0 on success * @return -1 on failure. */ -static inline int dequeue_vlan_id(struct osi_core_priv_data *osi_core, - unsigned int idx) +static inline nve32_t dequeue_vlan_id(struct osi_core_priv_data *osi_core, + nveu32_t idx) { - unsigned int i; + nveu32_t i; if (osi_core->vlan_filter_cnt == VLAN_HW_MAX_NRVF) { return -1; @@ -364,14 +364,14 @@ static inline int dequeue_vlan_id(struct osi_core_priv_data *osi_core, * @return 0 on success * @return -1 on failure. */ -static inline int dequeue_vid_to_add_filter_reg( +static inline nve32_t dequeue_vid_to_add_filter_reg( struct osi_core_priv_data *osi_core, - unsigned int vid_idx) + nveu32_t vid_idx) { - unsigned int val = 0; - unsigned short vlan_id = 0; - unsigned int i = 0; - int ret = 0; + nveu32_t val = 0; + nveu16_t vlan_id = 0; + nveu32_t i = 0; + nve32_t ret = 0; vlan_id = osi_core->vid[VLAN_HW_FILTER_FULL_IDX]; if (vlan_id == VLAN_ID_INVALID) { @@ -381,8 +381,8 @@ static inline int dequeue_vid_to_add_filter_reg( 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 = osi_readl((nveu8_t *)osi_core->base + MAC_VLAN_TAG_DATA); + val &= (nveu32_t) ~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); @@ -410,14 +410,14 @@ static inline int dequeue_vid_to_add_filter_reg( * @return 0 on success * @return -1 on failure. */ -static inline int del_vlan_id(struct osi_core_priv_data *osi_core, +static inline nve32_t del_vlan_id(struct osi_core_priv_data *osi_core, struct core_ops *ops_p, - unsigned short vlan_id) + nveu16_t vlan_id) { - unsigned int vid_idx = 0; - unsigned int val = 0; - unsigned int idx; - int ret = 0; + nveu32_t vid_idx = 0; + nveu32_t val = 0; + nveu32_t idx; + nve32_t ret = 0; /* Search for vlan filter index to be deleted */ vid_idx = get_vlan_filter_idx(osi_core, vlan_id); @@ -463,12 +463,12 @@ static inline int del_vlan_id(struct osi_core_priv_data *osi_core, return dequeue_vid_to_add_filter_reg(osi_core, vid_idx); } -int update_vlan_id(struct osi_core_priv_data *osi_core, +nve32_t update_vlan_id(struct osi_core_priv_data *osi_core, struct core_ops *ops_p, - unsigned int vid) + nveu32_t vid) { - unsigned int action = vid & VLAN_ACTION_MASK; - unsigned short vlan_id = (unsigned short)(vid & VLAN_VID_MASK); + nveu32_t action = vid & VLAN_ACTION_MASK; + nveu16_t vlan_id = (nveu16_t)(vid & VLAN_VID_MASK); if (action == OSI_VLAN_ACTION_ADD) { return add_vlan_id(osi_core, ops_p, vlan_id); diff --git a/osi/core/vlan_filter.h b/osi/core/vlan_filter.h index 32e783a..d4b09fe 100644 --- a/osi/core/vlan_filter.h +++ b/osi/core/vlan_filter.h @@ -70,7 +70,6 @@ * @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); +nve32_t update_vlan_id(struct osi_core_priv_data *osi_core, + struct core_ops *ops_p, nveu32_t vid); #endif /* VLAN_FILTER_H */ diff --git a/osi/core/xpcs.c b/osi/core/xpcs.c index d8c377c..66cc78f 100644 --- a/osi/core/xpcs.c +++ b/osi/core/xpcs.c @@ -35,15 +35,15 @@ * @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) +static inline nve32_t xpcs_poll_for_an_complete(struct osi_core_priv_data *osi_core, + nveu32_t *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; + nveu32_t status = 0; + nveu32_t retry = 1000; + nveu32_t count; + nve32_t cond = 1; + nve32_t ret = 0; /* 14. Poll for AN complete */ cond = 1; @@ -101,11 +101,11 @@ static inline int xpcs_poll_for_an_complete(struct osi_core_priv_data *osi_core, * @retval 0 on success * @retval -1 on failure */ -static inline int xpcs_set_speed(struct osi_core_priv_data *osi_core, - unsigned int status) +static inline nve32_t xpcs_set_speed(struct osi_core_priv_data *osi_core, + nveu32_t status) { - unsigned int speed = status & XPCS_USXG_AN_STS_SPEED_MASK; - unsigned int ctrl = 0; + nveu32_t speed = status & XPCS_USXG_AN_STS_SPEED_MASK; + nveu32_t ctrl = 0; void *xpcs_base = osi_core->xpcs_base; ctrl = xpcs_read(xpcs_base, XPCS_SR_MII_CTRL); @@ -142,15 +142,15 @@ static inline int xpcs_set_speed(struct osi_core_priv_data *osi_core, * @retval 0 on success * @retval -1 on failure. */ -int xpcs_start(struct osi_core_priv_data *osi_core) +nve32_t 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; + nveu32_t an_status = 0; + nveu32_t retry = RETRY_COUNT; + nveu32_t count = 0; + nveu32_t ctrl = 0; + nve32_t ret = 0; + nve32_t cond = COND_NOT_MET; if (osi_core->xpcs_base == OSI_NULL) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, @@ -231,7 +231,7 @@ int xpcs_start(struct osi_core_priv_data *osi_core) * @retval -1 on failure. */ static nve32_t xpcs_uphy_lane_bring_up(struct osi_core_priv_data *osi_core, - unsigned int lane_init_en) + nveu32_t lane_init_en) { void *xpcs_base = osi_core->xpcs_base; nveu32_t retry = XPCS_RETRY_COUNT; @@ -329,10 +329,10 @@ static nve32_t xpcs_check_pcs_lock_status(struct osi_core_priv_data *osi_core) static nve32_t xpcs_lane_bring_up(struct osi_core_priv_data *osi_core) { struct core_local *l_core = (struct core_local *)(void *)osi_core; - unsigned int retry = 1000; - unsigned int count; + nveu32_t retry = 1000; + nveu32_t count; nveu32_t val = 0; - int cond; + nve32_t cond; if (xpcs_uphy_lane_bring_up(osi_core, XPCS_WRAP_UPHY_HW_INIT_CTRL_TX_EN) < 0) { @@ -460,14 +460,14 @@ static nve32_t xpcs_lane_bring_up(struct osi_core_priv_data *osi_core) * @retval 0 on success * @retval -1 on failure. */ -int xpcs_init(struct osi_core_priv_data *osi_core) +nve32_t 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; + nveu32_t retry = 1000; + nveu32_t count; + nveu32_t ctrl = 0; + nve32_t cond = 1; + nve32_t ret = 0; if (osi_core->xpcs_base == OSI_NULL) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, @@ -590,11 +590,11 @@ int xpcs_init(struct osi_core_priv_data *osi_core) * @retval 0 on success * @retval -1 on failure. */ -int xpcs_eee(struct osi_core_priv_data *osi_core, unsigned int en_dis) +nve32_t xpcs_eee(struct osi_core_priv_data *osi_core, nveu32_t en_dis) { void *xpcs_base = osi_core->xpcs_base; - unsigned int val = 0x0U; - int ret = 0; + nveu32_t val = 0x0U; + nve32_t ret = 0; if ((en_dis != OSI_ENABLE) && (en_dis != OSI_DISABLE)) { return -1; diff --git a/osi/core/xpcs.h b/osi/core/xpcs.h index 7fcd741..9690e93 100644 --- a/osi/core/xpcs.h +++ b/osi/core/xpcs.h @@ -120,9 +120,9 @@ #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); +nve32_t xpcs_init(struct osi_core_priv_data *osi_core); +nve32_t xpcs_start(struct osi_core_priv_data *osi_core); +nve32_t xpcs_eee(struct osi_core_priv_data *osi_core, nveu32_t en_dis); /** * @brief xpcs_read - read from xpcs. @@ -134,11 +134,11 @@ int xpcs_eee(struct osi_core_priv_data *osi_core, unsigned int en_dis); * * @retval value read from xpcs register. */ -static inline unsigned int xpcs_read(void *xpcs_base, unsigned int reg_addr) +static inline nveu32_t xpcs_read(void *xpcs_base, nveu32_t 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 + + ((nveu8_t *)xpcs_base + XPCS_ADDRESS)); + return osi_readl((nveu8_t *)xpcs_base + ((reg_addr) & XPCS_REG_VALUE_MASK)); } @@ -151,12 +151,12 @@ static inline unsigned int xpcs_read(void *xpcs_base, unsigned int reg_addr) * @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) +static inline void xpcs_write(void *xpcs_base, nveu32_t reg_addr, + nveu32_t 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 + + ((nveu8_t *)xpcs_base + XPCS_ADDRESS)); + osi_writel(val, (nveu8_t *)xpcs_base + (((reg_addr) & XPCS_REG_VALUE_MASK))); } @@ -174,13 +174,13 @@ static inline void xpcs_write(void *xpcs_base, unsigned int reg_addr, * @retval -1 on failure. * */ -static inline int xpcs_write_safety(struct osi_core_priv_data *osi_core, - unsigned int reg_addr, - unsigned int val) +static inline nve32_t xpcs_write_safety(struct osi_core_priv_data *osi_core, + nveu32_t reg_addr, + nveu32_t val) { void *xpcs_base = osi_core->xpcs_base; - unsigned int read_val; - int retry = 10; + nveu32_t read_val; + nve32_t retry = 10; while (--retry > 0) { xpcs_write(xpcs_base, reg_addr, val); From 8406b92eb4355f4bfc9450502b3b8f7acaba658c Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Mon, 29 Aug 2022 18:29:41 +0000 Subject: [PATCH 392/458] osi: core: fix misra 2.x rules ===== DIFF ====== Total misra violation count changed by -591 Rule: MISRA_C-2012_Rule_2.2 Diff: -1 Rule: MISRA_C-2012_Rule_2.3 Diff: -3 Rule: MISRA_C-2012_Rule_2.4 Diff: -2 Rule: MISRA_C-2012_Rule_2.5 Diff: -585 Rule: Total Diff: -591 Bug 3695218 Change-Id: I57e85ba94f434cb3bd729b4f5f75bb4a592fb279 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2768383 Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- include/mmc.h | 2 + include/osi_common.h | 15 +- include/osi_core.h | 117 +++--- include/osi_macsec.h | 2 + osi/common/common.h | 2 + osi/common/type.h | 14 +- osi/core/core_common.h | 10 +- osi/core/core_local.h | 19 +- osi/core/eqos_core.h | 412 ++++++++++---------- osi/core/macsec.h | 2 + osi/core/mgbe_core.h | 865 +++++++++++++++++++++-------------------- osi/core/mgbe_mmc.h | 1 - osi/core/osi_hal.c | 1 - osi/core/vlan_filter.h | 2 + 14 files changed, 753 insertions(+), 711 deletions(-) diff --git a/include/mmc.h b/include/mmc.h index 1eb449c..95b957a 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -551,6 +551,7 @@ struct osi_mmc_counters { nveu64_t mmc_rx_fpe_fragment_cnt; }; +#ifndef OSI_STRIPPED_LIB /** * @brief osi_xtra_stat_counters - OSI core extra stat counters */ @@ -584,6 +585,7 @@ struct osi_xtra_stat_counters { /** lock fail count node removal */ nveu64_t ts_lock_del_fail; }; +#endif /* !OSI_STRIPPED_LIB */ #ifdef MACSEC_SUPPORT /** diff --git a/include/osi_common.h b/include/osi_common.h index 9cc8ac0..a2d8acc 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -165,13 +165,13 @@ /* 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 #ifndef OSI_STRIPPED_LIB +#define OSI_LOG_WARN 2U #define OSI_LOG_ARG_OPNOTSUPP 3U #endif /* !OSI_STRIPPED_LIB */ /* Default maximum Giant Packet Size Limit is 16K */ @@ -198,8 +198,10 @@ /* MACSEC max SC's supported 16*/ #define OSI_MACSEC_SC_INDEX_MAX 16 +#ifndef OSI_STRIPPED_LIB /* HW supports 8 Hash table regs, but eqos_validate_core_regs only checks 4 */ #define OSI_EQOS_MAX_HASH_REGS 4U +#endif /* OSI_STRIPPED_LIB */ #define MAC_VERSION 0x110 #define MAC_VERSION_SNVER_MASK 0x7FU @@ -217,11 +219,14 @@ #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 +#ifndef OSI_STRIPPED_LIB #define OSI_MGBE_MAC_3_00 0x30U +#define OSI_EQOS_MAC_4_10 0x41U +#define OSI_EQOS_MAC_5_10 0x51U +#endif /* OSI_STRIPPED_LIB */ + +#define OSI_EQOS_MAC_5_00 0x50U +#define OSI_EQOS_MAC_5_30 0x53U #define OSI_MGBE_MAC_3_10 0x31U #define OSI_MGBE_MAC_4_00 0x40U diff --git a/include/osi_core.h b/include/osi_core.h index 1add2d9..d101b03 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -43,6 +43,62 @@ typedef long long my_lint_64; typedef my_lint_64 nvel64_t; /** @} */ +#ifndef OSI_STRIPPED_LIB +#define OSI_PTP_SNAP_TRANSPORT 1U +#define OSI_VLAN_ACTION_DEL 0x0U +#define OSI_VLAN_ACTION_ADD OSI_BIT(31) +#define OSI_RXQ_ROUTE_PTP 0U +#define EQOS_MAX_HTR_REGS 8U + +/** + * @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 +/** @} */ + +#define OSI_CMD_SAVE_REGISTER 13U +#define OSI_CMD_RESTORE_REGISTER 2U +#define OSI_CMD_RESET_MMC 12U +#define OSI_CMD_MDC_CONFIG 1U +#define OSI_CMD_MAC_LB 14U +#define OSI_CMD_GET_AVB 23U +#define OSI_CMD_FLOW_CTRL 15U +#define OSI_CMD_CONFIG_TXSTATUS 27U +#define OSI_CMD_CONFIG_RX_CRC_CHECK 25U +#define OSI_CMD_CONFIG_EEE 32U +#define OSI_CMD_ARP_OFFLOAD 30U +#define OSI_CMD_UPDATE_VLAN_ID 26U +#define OSI_CMD_SET_AVB 24U +#define OSI_CMD_VLAN_FILTER 31U +#define OSI_CMD_VALIDATE_CORE_REG 11U + +/** + * @addtogroup PTP-offload PTP offload defines + * @{ + */ +#define OSI_PTP_MAX_PORTID 0xFFFFU +#define OSI_PTP_MAX_DOMAIN 0xFFU +#define OSI_PTP_SNAP_ORDINARY 0U +#define OSI_PTP_SNAP_P2P 3U +/** @} */ + +#define OSI_MAC_TCR_TSMASTERENA OSI_BIT(15) +#define OSI_MAC_TCR_TSEVENTENA OSI_BIT(14) +#define OSI_MAC_TCR_TSENALL OSI_BIT(8) +#define OSI_MAC_TCR_SNAPTYPSEL_3 (OSI_BIT(16) | OSI_BIT(17)) +#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_FLOW_CTRL_TX OSI_BIT(0) +#define OSI_FLOW_CTRL_RX OSI_BIT(1) +#endif /* !OSI_STRIPPED_LIB */ + + #ifdef MACSEC_SUPPORT /** * @addtogroup MACSEC related helper MACROs @@ -58,16 +114,6 @@ typedef my_lint_64 nvel64_t; /** @} */ #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 * @@ -94,19 +140,12 @@ typedef my_lint_64 nvel64_t; */ #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) /** @} */ @@ -119,7 +158,6 @@ typedef my_lint_64 nvel64_t; #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 @@ -128,12 +166,14 @@ typedef my_lint_64 nvel64_t; #define OSI_MAX_TC_NUM 8U #define OSI_DFLT_MTU_SIZE 1500U #define OSI_MTU_SIZE_9000 9000U + +#ifndef OSI_STRIPPED_LIB /* HW supports 8 Hash table regs, but eqos_validate_core_regs only checks 4 */ #define OSI_EQOS_MAX_HASH_REGS 4U +#endif /* !OSI_STRIPPED_LIB */ + #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 @@ -184,15 +224,6 @@ typedef my_lint_64 nvel64_t; #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 @@ -200,8 +231,6 @@ typedef my_lint_64 nvel64_t; * @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 @@ -210,11 +239,6 @@ typedef my_lint_64 nvel64_t; #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 @@ -222,16 +246,8 @@ typedef my_lint_64 nvel64_t; #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 @@ -291,20 +307,8 @@ typedef my_lint_64 nvel64_t; } #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 @@ -312,7 +316,6 @@ typedef my_lint_64 nvel64_t; * @brief PTP SSINC values * @{ */ -#define OSI_PTP_SSINC_16 16U #define OSI_PTP_SSINC_4 4U #define OSI_PTP_SSINC_6 6U /** @} */ diff --git a/include/osi_macsec.h b/include/osi_macsec.h index 99f10f8..441cc9e 100644 --- a/include/osi_macsec.h +++ b/include/osi_macsec.h @@ -116,6 +116,7 @@ #define OSI_SA_LUT_MAX_INDEX OSI_TABLE_INDEX_MAX /** @} */ +#ifndef OSI_STRIPPED_LIB /** * @addtogroup Debug buffer table CONFIG register helpers macros * @@ -140,6 +141,7 @@ #define OSI_RX_DBG_ICV_ERROR_EVT OSI_BIT(10) #define OSI_RX_DBG_CAPTURE_EVT OSI_BIT(11) /** @} */ +#endif /* !OSI_STRIPPED_LIB */ /** * @addtogroup AES ciphers diff --git a/osi/common/common.h b/osi/common/common.h index b7ecfc6..aeeb738 100644 --- a/osi/common/common.h +++ b/osi/common/common.h @@ -49,6 +49,7 @@ */ #define MAX_MAC_IP_TYPES 2U +#ifndef OSI_STRIPPED_LIB /** * @brief osi_readl_poll_timeout - Periodically poll an address until * a condition is met or a timeout occurs @@ -76,6 +77,7 @@ } \ (cond) ? 0 : -1; \ }) +#endif /* !OSI_STRIPPED_LIB */ struct osi_core_priv_data; diff --git a/osi/common/type.h b/osi/common/type.h index d2ed7c7..929a062 100644 --- a/osi/common/type.h +++ b/osi/common/type.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -37,8 +37,6 @@ typedef unsigned int my_uint32_t; 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 */ @@ -55,8 +53,6 @@ typedef my_uint32_t nveu32_t; 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 */ @@ -67,4 +63,12 @@ typedef my_ulint_64 nveul64_t; typedef my_uint64_t nveu64_t; /** @} */ +#ifndef OSI_STRIPPED_LIB +/** intermediate type for short */ +typedef short my_int16_t; +/** typedef equivalent to short */ +typedef my_int16_t nve16_t; +#endif /* !OSI_STRIPPED_LIB */ + #endif /* INCLUDED_TYPE_H */ + diff --git a/osi/core/core_common.h b/osi/core/core_common.h index 6ae147b..69f8abf 100644 --- a/osi/core/core_common.h +++ b/osi/core/core_common.h @@ -24,6 +24,9 @@ #define INCLUDED_CORE_COMMON_H #include "core_local.h" + +#ifndef OSI_STRIPPED_LIB +#define MAC_TCR_TSCTRLSSR OSI_BIT(9) #define MTL_EST_ADDR_MASK (OSI_BIT(8) | OSI_BIT(9) | \ OSI_BIT(10) | OSI_BIT(11) | \ OSI_BIT(12) | OSI_BIT(13) | \ @@ -38,6 +41,9 @@ #define MTL_EST_ERR0 OSI_BIT(20) #define MTL_EST_CONTROL_EEST OSI_BIT(0) #define MTL_EST_STATUS_SWOL OSI_BIT(7) +#define MAC_TCR_TSCFUPDT OSI_BIT(1) +#endif /* !OSI_STRIPPED_LIB */ + #define DMA_MODE_SWR OSI_BIT(0) #define MTL_QTOMR_FTQ OSI_BIT(0) #define MTL_RXQ_OP_MODE_FEP OSI_BIT(4) @@ -45,8 +51,6 @@ #define MAC_TCR_TSADDREG OSI_BIT(5) #define MAC_PPS_CTL_PPSCTRL0 (OSI_BIT(3) | OSI_BIT(2) |\ OSI_BIT(1) | OSI_BIT(0)) -#define MAC_TCR_TSCFUPDT OSI_BIT(1) -#define MAC_TCR_TSCTRLSSR OSI_BIT(9) #define MAC_SSIR_SSINC_SHIFT 16U @@ -56,6 +60,7 @@ #define WRAP_PTP_CAPTURE_LOW 0x8018U #define WRAP_PTP_CAPTURE_HIGH 0x801CU +#ifndef OSI_STRIPPED_LIB /** * @addtogroup typedef related info * @@ -72,7 +77,6 @@ struct est_read { /** @} */ -#ifndef OSI_STRIPPED_LIB 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); diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 6c91a39..07693be 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -46,27 +46,30 @@ /** * @brief Dynamic configuration helper macros. */ -#define DYNAMIC_CFG_L3_L4 OSI_BIT(0) +#define DYNAMIC_CFG_L3_L4 OSI_BIT(0) +#define DYNAMIC_CFG_L3_L4_IDX 0U +#define DYNAMIC_CFG_L2 OSI_BIT(3) +#define DYNAMIC_CFG_L2_IDX 3U +#define DYNAMIC_CFG_RXCSUM OSI_BIT(4) +#define DYNAMIC_CFG_RXCSUM_IDX 4U +#define DYNAMIC_CFG_PTP OSI_BIT(7) +#define DYNAMIC_CFG_PTP_IDX 7U + +#ifndef OSI_STRIPPED_LIB #define DYNAMIC_CFG_FC OSI_BIT(1) #define DYNAMIC_CFG_AVB OSI_BIT(2) -#define DYNAMIC_CFG_L2 OSI_BIT(3) -#define DYNAMIC_CFG_RXCSUM OSI_BIT(4) #define DYNAMIC_CFG_VLAN OSI_BIT(5) #define DYNAMIC_CFG_EEE OSI_BIT(6) -#define DYNAMIC_CFG_PTP OSI_BIT(7) #define DYNAMIC_CFG_EST OSI_BIT(8) #define DYNAMIC_CFG_FPE OSI_BIT(9) -#define DYNAMIC_CFG_L3_L4_IDX 0U #define DYNAMIC_CFG_FC_IDX 1U #define DYNAMIC_CFG_AVB_IDX 2U -#define DYNAMIC_CFG_L2_IDX 3U -#define DYNAMIC_CFG_RXCSUM_IDX 4U #define DYNAMIC_CFG_VLAN_IDX 5U #define DYNAMIC_CFG_EEE_IDX 6U -#define DYNAMIC_CFG_PTP_IDX 7U #define DYNAMIC_CFG_EST_IDX 8U #define DYNAMIC_CFG_FPE_IDX 9U +#endif /* !OSI_STRIPPED_LIB */ #define OSI_SUSPENDED OSI_BIT(0) diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 8013344..d3356c5 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -24,6 +24,204 @@ #define INCLUDED_EQOS_CORE_H #ifndef OSI_STRIPPED_LIB +#define EQOS_MAC_LPI_CSR 0x00D0 +#define EQOS_MAC_LPI_TIMER_CTRL 0x00D4 +#define EQOS_MAC_LPI_EN_TIMER 0x00D8 +#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_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_IND_CS 0x0CB0 +#define EQOS_MTL_RXP_IND_DATA 0x0CB4 +#define EQOS_MAC_RX_FLW_CTRL 0x0090 +#define EQOS_MAC_STNSR 0x0B0C +#define EQOS_MAC_STSR 0x0B08 +#define EQOS_MAC_MA0LR 0x0304 +#define EQOS_MAC_PIDR0 0x0BC4 +#define EQOS_MAC_PTO_CR 0x0BC0 +#define EQOS_MAC_PIDR1 0x0BC8 +#define EQOS_MAC_PIDR2 0x0BCC +#define EQOS_MAC_PMTCSR 0x00C0 +#define EQOS_MAC_QX_TX_FLW_CTRL(x) ((0x0004U * (x)) + 0x0070U) +#define EQOS_MTL_TXQ_ETS_CR(x) ((0x0040U * (x)) + 0x0D10U) +#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_MAC_HTR_REG(x) ((0x0004U * (x)) + 0x0010U) +#define EQOS_MAC_L3_AD2R(x) ((0x0030U * (x)) + 0x0918U) +#define EQOS_MAC_L3_AD3R(x) ((0x0030U * (x)) + 0x091CU) +#define EQOS_MAC_L4_ADR(x) ((0x0030U * (x)) + 0x0904U) +#define EQOS_MTL_INTR_STATUS 0x0C20 +#define EQOS_MTL_OP_MODE 0x0C00 +#define EQOS_MAC_FPE_CTS 0x0234 +#define EQOS_MAC_MA0HR 0x0300 +#define EQOS_4_10_MAC_ARPPA 0x0AE0 +#define EQOS_5_00_MAC_ARPPA 0x0210 +#define EQOS_CLOCK_CTRL_0 0x8000U +#define EQOS_APB_ERR_STATUS 0x8214U + +#define EQOS_MAC_MA0HR_IDX 11U +#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_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_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_ASID1_CTRL_VAL ((EQOS_5_30_SID_CH7) |\ + (EQOS_5_30_SID_CH6) |\ + (EQOS_5_30_SID_CH5) |\ + (EQOS_5_30_SID)) +#define EQOS_MAC_MA0HR_MASK 0xFFFFFU +#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_L4SPI_SHIFT 19 +#define EQOS_MAC_L3L4_CTR_L4PEN0 OSI_BIT(16) +#define EQOS_MAC_L3L4_CTR_L4PEN0_SHIFT 16 +#define EQOS_MAC_IMR_MASK 0x67039U +#define EQOS_MAC_HTR_MASK 0xFFFFFFFFU +#define EQOS_MAC_HTR0_IDX 2U +#define EQOS_IMR_FPEIE OSI_BIT(17) +#define EQOS_DMA_SBUS_MASK 0xDF1F3CFFU +#define EQOS_DMA_ISR_MTLIS OSI_BIT(16) +#define EQOS_DMA_CHX_STATUS_FBE OSI_BIT(10) +#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_TPS OSI_BIT(1) +#define EQOS_MAC_L3L4_CTR_L4DPI_SHIFT 21 +/** + * @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)) +/* Indirect register defines */ +#define EQOS_MTL_RXP_IND_CS_BUSY OSI_BIT(31) +#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)) +/** @} */ + +/* 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) + +#define EQOS_RXQ_DMA_MAP0_MASK 0x13131313U +#define EQOS_MTL_TXQ_QW_MASK 0x1FFFFFU +#define EQOS_PAD_AUTO_CAL_CFG_MASK 0x7FFFFFFFU +#define EQOS_MTL_TXQ_OP_MODE_MASK 0xFF007EU +#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_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_RXQ_OP_MODE_MASK 0xFFFFFFBU +#define EQOS_MAC_RQC1R_MASK 0xF77077U +#define EQOS_MAC_RQC1R_FPRQ (OSI_BIT(26) | OSI_BIT(25) | \ + OSI_BIT(24)) +#define EQOS_MAC_RQC1R_FPRQ_SHIFT 24U +#define EQOS_MAC_RQC0R_MASK 0xFFU +#define EQOS_MAC_QX_TX_FLW_CTRL_TFE OSI_BIT(1) +#define EQOS_MAC_QX_TXFC_MASK 0xFFFF00F2U +#define EQOS_MAC_Q0_TXFC_IDX 6U +#define EQOS_MAC_PTO_CR_ASYNCEN OSI_BIT(1) +#define EQOS_MAC_RQC1R_OMCBCQ OSI_BIT(28) +#define EQOS_MAC_PIDR_PID_MASK 0XFFFFU +#define EQOS_MAC_PFR_MASK 0x803107FFU +#define EQOS_MAC_PAUSE_TIME 0xFFFF0000U +#define EQOS_MAC_PAUSE_TIME_MASK 0xFFFF0000U +#define EQOS_MAC_MCR_MASK 0xFFFFFF7FU +#define EQOS_MAC_MA0LR_IDX 12U +#define EQOS_MAC_MA0LR_MASK 0xFFFFFFFFU +#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_PTOEN 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_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) + +#define EQOS_MCR_IPG_MASK 0x7000000U +#define EQOS_MCR_IPG_SHIFT 24U +#define EQOS_MCR_IPG 0x7U +#define EQOS_MAC_TCR_TSENMACADDR OSI_BIT(18) +#define EQOS_MAC_TCR_SNAPTYPSEL_SHIFT 16U +#define EQOS_MAC_TAR_IDX 15U +#define EQOS_MAC_SSIR_IDX 14U +#define EQOS_MAC_RX_FLW_CTRL_RFE OSI_BIT(0) +#define EQOS_MAC_TCR_MASK 0x1107FF03U +#define EQOS_MAC_TAR_MASK 0xFFFFFFFFU +#define EQOS_MAC_SSIR_MASK 0xFFFF00U +#define EQOS_MAC_RQC2R_MASK 0xFFFFFFFFU +#define EQOS_MAC_RQC1R_TPQC (OSI_BIT(22) | OSI_BIT(23)) +#define EQOS_MAC_RQC1R_TPQC0 OSI_BIT(22) +#define EQOS_MAC_RQC1R_PTPQ (OSI_BIT(6) | OSI_BIT(5) | \ + OSI_BIT(4)) +#define EQOS_MAC_RQC1R_PTPQ_SHIFT 4U /** * @addtogroup EQOS-MDC MDC Clock Selection defines * @@ -39,6 +237,11 @@ #define EQOS_CSR_300_500M 0x6 /* MDC = clk_csr/204 */ #define EQOS_CSR_500_800M 0x7 /* MDC = clk_csr/324 */ /** @} */ +#define EQOS_MTL_FRP_IE2_DCH_SHIFT 24U +#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) #endif /* !OSI_STRIPPED_LIB */ /** * @addtogroup EQOS-SIZE SIZE calculation helper Macros @@ -77,24 +280,17 @@ #define EQOS_MAC_MCR 0x0000 #define EQOS_MAC_EXTR 0x0004 #define EQOS_MAC_PFR 0x0008 -#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 +#endif /* !OSI_STRIPPED_LIB */ #define EQOS_MAC_PCS 0x00F8 #ifdef UPDATED_PAD_CAL @@ -105,34 +301,20 @@ #define EQOS_MAC_MDIO_ADDRESS 0x0200 #define EQOS_MAC_MDIO_DATA 0x0204 -#define EQOS_5_00_MAC_ARPPA 0x0210 -#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 @@ -145,30 +327,10 @@ * @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_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_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_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) /** @} */ @@ -178,8 +340,6 @@ * @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 @@ -215,9 +375,6 @@ #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) @@ -239,7 +396,6 @@ #define EQOS_MCR_CST OSI_BIT(21) #define EQOS_MCR_GPSLCE OSI_BIT(23) #define EQOS_IMR_RGSMIIIE OSI_BIT(0) -#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)) @@ -256,8 +412,6 @@ #define EQOS_DMA_SBUS_BLEN16 OSI_BIT(3) #define EQOS_DMA_SBUS_EAME OSI_BIT(11) #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 @@ -265,14 +419,6 @@ #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_DMA_ISR_MTLIS OSI_BIT(16) #define EQOS_DMA_ISR_MACIS OSI_BIT(17) #ifdef HSI_SUPPORT @@ -289,20 +435,8 @@ #define EQOS_MTL_RXQ_SIZE_SHIFT 20U #ifndef OSI_STRIPPED_LIB #define EQOS_MAC_ENABLE_LM OSI_BIT(12) -#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_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) @@ -315,16 +449,12 @@ #define EQOS_MTL_OP_MODE_FRPE OSI_BIT(15) #define EQOS_MTL_OP_MODE_DTXSTS OSI_BIT(1) #define EQOS_MAC_EXTR_DCRCC OSI_BIT(16) -#endif /* !OSI_STRIPPED_LIB */ -#define EQOS_MAC_EXTR_PDC OSI_BIT(19) #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 -#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 +#endif /* !OSI_STRIPPED_LIB */ +#define EQOS_MAC_EXTR_PDC OSI_BIT(19) #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 @@ -343,17 +473,10 @@ #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) @@ -409,18 +532,7 @@ #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_TCR_TSENMACADDR OSI_BIT(18) -#define EQOS_MAC_TCR_SNAPTYPSEL_SHIFT 16U #define EQOS_MAC_TCR_TSUPDT OSI_BIT(3) -#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_GMIIDR_GD_WR_MASK 0xFFFF0000U #define EQOS_MAC_GMIIDR_GD_MASK 0xFFFFU @@ -439,12 +551,6 @@ #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 @@ -465,21 +571,6 @@ (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 #ifndef OSI_STRIPPED_LIB @@ -570,7 +661,7 @@ #define EQOS_MTL_EST_ITRE_IEBE OSI_BIT(1) #define EQOS_MTL_EST_ITRE_IECC OSI_BIT(0) #endif /* !OSI_STRIPPED_LIB */ -#ifdef MACSEC_SUPPORT +#if defined(MACSEC_SUPPORT) && !defined(OSI_STRIPPED_LIB) /* MACSEC Recommended value*/ #define EQOS_MTL_EST_CTOV_MACSEC_RECOMMEND 758U #endif /* MACSEC_SUPPORT */ @@ -588,26 +679,7 @@ void update_ehfc_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value); * @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. @@ -615,17 +687,11 @@ void update_ehfc_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value); */ #define EQOS_MAC_MCR_IDX 0U #define EQOS_MAC_PFR_IDX 1U -#define EQOS_MAC_HTR0_IDX 2U -#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 @@ -636,68 +702,6 @@ void update_ehfc_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value); #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_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_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. @@ -715,6 +719,7 @@ struct core_func_safety { nveu32_t core_safety_lock; }; +#ifndef OSI_STRIPPED_LIB /** * @addtogroup EQOS_HW EQOS HW BACKUP registers * @@ -826,7 +831,6 @@ struct core_func_safety { * 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 */ /** @} */ diff --git a/osi/core/macsec.h b/osi/core/macsec.h index d958c91..933262f 100644 --- a/osi/core/macsec.h +++ b/osi/core/macsec.h @@ -455,8 +455,10 @@ #define MACSEC_RX_SCI_LUT_PREEMPT_INACTIVE OSI_BIT(9) /** @} */ +#ifndef OSI_STRIPPED_LIB /* debug buffer data read/write length */ #define DBG_BUF_LEN 4U +#endif /* !OSI_STRIPPED_LIB */ #ifdef MACSEC_KEY_PROGRAM #define INTEGER_LEN 4U #endif /* MACSEC_KEY_PROGRAM */ diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 0f72fbf..d3a6002 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -23,129 +23,98 @@ #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 ((nveu32_t)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 -/** @} */ +#ifndef OSI_STRIPPED_LIB +#define MGBE_MAC_RX_FLW_CTRL 0x0090 +#define MGBE_MAC_QX_TX_FLW_CTRL(x) ((0x0004U * (x)) + 0x0070U) +#define MGBE_MAC_ARPPA 0x0C10 +#define MGBE_MAC_LPI_CSR 0x00D0 +#define MGBE_MAC_LPI_TIMER_CTRL 0x00D4 +#define MGBE_MAC_LPI_EN_TIMER 0x00D8 +#define MGBE_MAC_RSS_CTRL 0x0C80 +#define MGBE_MAC_RSS_ADDR 0x0C88 +#define MGBE_MAC_RSS_DATA 0x0C8C +#define MGBE_MAC_PTO_CR 0x0DC0 +#define MGBE_MAC_PIDR0 0x0DC4 +#define MGBE_MAC_PIDR1 0x0DC8 +#define MGBE_MAC_PIDR2 0x0DCC +#define MGBE_MAC_PMTCSR 0x00C0 +#define MGBE_MAC_HTR_REG(x) ((0x0004U * (x)) + 0x0010U) +#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_ITRE 0x1070 +#define MGBE_MTL_EST_GCL_CONTROL 0x1080 +#define MGBE_MTL_EST_DATA 0x1084 +#define MGBE_MAC_STSR 0x0D08 +#define MGBE_MAC_STNSR 0x0D0C +#define MGBE_MAC_RX_TX_STS 0x00B8 +#define MGBE_MAC_RQC4R 0x0094 +#define MGBE_MAC_RQC2R 0x00A8 +#define MGBE_MAC_FPE_CTS 0x0280 +#define MGBE_MTL_TCQ_ETS_HCR(x) ((0x0080U * (x)) + 0x1120U) +#define MGBE_MTL_TCQ_ETS_LCR(x) ((0x0080U * (x)) + 0x1124U) +#define MGBE_MTL_TCQ_ETS_SSCR(x) ((0x0080U * (x)) + 0x111CU) +#define MGBE_WRAP_AXI_ASID0_CTRL 0x8400 +#define MGBE_WRAP_AXI_ASID1_CTRL 0x8404 +#define MGBE_WRAP_AXI_ASID2_CTRL 0x8408 +#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 +#define MGBE_MTL_QINT_STATUS(x) ((0x0080U * (x)) + 0x1174U) +#define MGBE_MTL_OP_MODE 0x1000 +#define MGBE_MTL_INTR_STATUS 0x1020 +#define MGBE_MTL_FPE_CTS 0x1090 +#define MGBE_MTL_FPE_ADV 0x1094 -/** - * @addtogroup MGBE MTL queue ETS algorithm mode - * - * @brief MTL queue algorithm type - * @{ - */ -#define OSI_MGBE_TXQ_AVALG_ETS 2U -/** @} */ +#define MGBE_MTL_TCQ_ETS_CR_AVALG_SHIFT 0U +#define MGBE_MTL_QINT_TXUNIFS OSI_BIT(0) +#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_SID_VAL1(x) (((x) << 24U) |\ + ((x) << 16U) |\ + ((x) << 8U) |\ + (x)) +#define MGBE_SID_VAL2(x) (((x) << 8U) |\ + (x)) -/** - * @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_ADDRH(x) ((0x0008U * (x)) + 0x0300U) -#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 - -#ifdef HSI_SUPPORT -#define MGBE_REGISTER_PARITY_ERR OSI_BIT(5) -#define MGBE_CORE_CORRECTABLE_ERR OSI_BIT(4) -#define MGBE_CORE_UNCORRECTABLE_ERR OSI_BIT(3) -#endif -#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_MTL_TCQ_ETS_CR_CC OSI_BIT(3) +#define MGBE_MTL_TCQ_ETS_CR_CC_SHIFT 3U +#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 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_8PTP_CYCLE 26U +#define MGBE_DMA_ISR_MTLIS OSI_BIT(16) +#define MGBE_IMR_FPEIE OSI_BIT(15) +#define MGBE_MAC_EXT_CNF_EIPG 0x1U +#define MGBE_MAC_EXT_CNF_EIPG_MASK 0x7FU +#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_MAC_RX_FLW_CTRL_RFE OSI_BIT(0) +#define MGBE_MAC_STNSR_TSSS_MASK 0x7FFFFFFFU +#define MGBE_MAC_TCR_SNAPTYPSEL_SHIFT 16U +#define MGBE_MAC_TCR_TSENMACADDR OSI_BIT(18) +#define MGBE_MAC_TMCR_IPG_MASK 0x700U +#define MGBE_MAC_RQC1R_RQ_SHIFT 4U +#define MGBE_MAC_PAUSE_TIME 0xFFFF0000U +#define MGBE_MAC_PAUSE_TIME_MASK 0xFFFF0000U +#define MGBE_MAC_TX_TJT OSI_BIT(0) +#define MGBE_MAC_TX_IHE OSI_BIT(12) +#define MGBE_MAC_VLAN_TR_VTHM OSI_BIT(25) +#define MGBE_MAC_VLAN_TR_VTIM OSI_BIT(17) +#define MGBE_MAC_VLAN_TR_VTIM_SHIFT 17 /** * @addtogroup MGBE MAC hash table defines * @@ -156,149 +125,157 @@ #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 - -/* 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_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 +/* 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 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) +/* EST GCRA addresses */ +#define MGBE_MTL_EST_BTR_LOW ((nveu32_t)0x0 << \ + MGBE_MTL_EST_ADDR_SHIFT) +#define MGBE_MTL_EST_BTR_HIGH ((nveu32_t)0x1 << \ + MGBE_MTL_EST_ADDR_SHIFT) +#define MGBE_MTL_EST_CTR_LOW ((nveu32_t)0x2 << \ + MGBE_MTL_EST_ADDR_SHIFT) +#define MGBE_MTL_EST_CTR_HIGH ((nveu32_t)0x3 << \ + MGBE_MTL_EST_ADDR_SHIFT) +#define MGBE_MTL_EST_CTR_HIGH_MAX 0xFFU +#define MGBE_MTL_EST_TER ((nveu32_t)0x4 << \ + MGBE_MTL_EST_ADDR_SHIFT) +#define MGBE_MTL_EST_LLR ((nveu32_t)0x5 << \ + MGBE_MTL_EST_ADDR_SHIFT) + +#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_DDBF OSI_BIT(4) +#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 + +#define MGBE_MAC_TX_PCE OSI_BIT(13) +/* 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_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 + +#define MGBE_MAC_IMR_FPEIS OSI_BIT(16) +#define MGBE_MAC_L3L4_CTR_L4DPIM0_SHIFT 21 +#define MGBE_MAC_L3L4_CTR_L4PEN0 OSI_BIT(16) +#define MGBE_MAC_L3L4_CTR_L4SPIM0_SHIFT 19 #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_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_FPE_CTS_RRSP OSI_BIT(17) +#define MGBE_MAC_RQC1R_PTPQ_SHIFT 24U +#define MGBE_MAC_RQC1R_PTPQ (OSI_BIT(27) | OSI_BIT(26) | \ + OSI_BIT(25) | OSI_BIT(24)) +#define MGBE_MAC_RMCR_LM OSI_BIT(10) +#define MGBE_MAC_RMCR_ARPEN OSI_BIT(31) +#define MGBE_MAC_QX_TX_FLW_CTRL_TFE OSI_BIT(1) +#define MGBE_MAC_TMCR_IFP OSI_BIT(11) +#define MGBE_MAC_RQC1R_TPQC0 OSI_BIT(21) +#define MGBE_MAC_RQC1R_OMCBCQ OSI_BIT(20) +#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) /** - * @addtogroup MGBE-DMA DMA register offsets + * @addtogroup - MGBE-LPI LPI configuration macros * - * @brief MGBE DMA register offsets + * @brief LPI timers and config register field masks. * @{ */ -#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 - * @{ +/* 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_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_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_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_STATUS(x) ((0x0080U * (x)) + 0x1174U) -#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 +#define MGBE_DEFAULT_LPI_LS_TIMER ((nveu32_t)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 +#define MGBE_MAC_1US_TIC_COUNT 0x00DC /** @} */ +#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 +/* 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 /** * @addtogroup MGBE-MTL FRP Indirect Access register defines @@ -365,6 +342,211 @@ OSI_BIT(3) | OSI_BIT(2) | \ OSI_BIT(1) | OSI_BIT(0)) /** @} */ +#define MGBE_DMA_CHX_STATUS_RPS OSI_BIT(8) +#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_FBE OSI_BIT(12) + +#define MGBE_MAC_L4_ADDR 0x1 +#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_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_RQC1R_RQ (OSI_BIT(7) | OSI_BIT(6) | \ + OSI_BIT(5) | OSI_BIT(4)) +#define MGBE_MAC_PFR_VTFE_SHIFT 16 +#define MGBE_MAC_PIDR_PID_MASK 0XFFFFU + + +#endif /* !OSI_STRIPPED_LIB */ + +/** + * @addtogroup MGBE MTL queue ETS algorithm mode + * + * @brief MTL queue algorithm type + * @{ + */ +#define OSI_MGBE_TXQ_AVALG_ETS 2U +#define MGBE_MTL_TCQ_ETS_CR_AVALG (OSI_BIT(1) | OSI_BIT(0)) +/** @} */ + +/** + * @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_VLAN_TR 0x0050 +#define MGBE_MAC_VLANTIR 0x0060 +#define MGBE_MAC_RQC0R 0x00A0 +#define MGBE_MAC_RQC1R 0x00A4 +#define MGBE_MAC_ISR 0x00B0 +#define MGBE_MAC_IER 0x00B4 +#define MGBE_MAC_EXT_CNF 0x0140 +#define MGBE_MDIO_SCCD 0x0204 +#define MGBE_MDIO_SCCA 0x0200 +#define MGBE_MAC_ADDRH(x) ((0x0008U * (x)) + 0x0300U) +#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_TCR 0x0D00 +#define MGBE_MAC_SSIR 0x0D04 +#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 +/** @} */ + +/** + * @addtogroup MGBE-WRAPPER MGBE Wrapper register offsets + * + * @brief MGBE Wrapper register offsets + * @{ + */ +#define MGBE_WRAP_COMMON_INTR_ENABLE 0x8704 + +#ifdef HSI_SUPPORT +#define MGBE_REGISTER_PARITY_ERR OSI_BIT(5) +#define MGBE_CORE_CORRECTABLE_ERR OSI_BIT(4) +#define MGBE_CORE_UNCORRECTABLE_ERR OSI_BIT(3) +#endif +#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 +/** @} */ + + +/** + * @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 + +/* 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_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_MAC_XB_WAIT 10U +#define MGBE_MAC_L3L4_CTR 0x0 +#define MGBE_MAC_L3_AD0R 0x4 +#define MGBE_MAC_L3_AD1R 0x5 + +#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_L4DPM0 OSI_BIT(20) +#define MGBE_MAC_L3L4_CTR_L4SPIM0 OSI_BIT(19) +#define MGBE_MAC_L3L4_CTR_L4SPM0 OSI_BIT(18) +#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) +/** @} */ + +/** + * @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_RXQ_DMA_MAP0 0x1030 +#define MGBE_MTL_RXQ_DMA_MAP1 0x1034 +#define MGBE_MTL_RXQ_DMA_MAP2 0x1038 +#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_CHX_RX_OP_MODE(x) ((0x0080U * (x)) + 0x1140U) +#define MGBE_MTL_RXQ_FLOW_CTRL(x) ((0x0080U * (x)) + 0x1150U) +/** @} */ + /** * @addtogroup HW Register BIT values @@ -372,32 +554,16 @@ * @brief consists of corresponding MGBE MAC, MTL register bit values * @{ */ -#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_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_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 @@ -414,43 +580,22 @@ #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_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_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) @@ -462,7 +607,6 @@ #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) @@ -488,29 +632,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_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 ((nveu32_t)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) #define MGBE_MAC_ISR_LSI OSI_BIT(0) #define MGBE_MAC_ISR_LS_MASK (OSI_BIT(25) | OSI_BIT(24)) #define MGBE_MAC_ISR_LS_LOCAL_FAULT OSI_BIT(25) @@ -523,8 +649,6 @@ #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)) @@ -540,135 +664,22 @@ #define MGBE_MTL_RXQ_SIZE_SHIFT 16U #define MGBE_MAC_RMCR_GPSL_MSK 0x3FFF0000U #define MGBE_MAC_TCR_TSUPDT OSI_BIT(3) -#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_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 +#if defined(MACSEC_SUPPORT) && !defined(OSI_STRIPPED_LIB) /** * 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_LCSE (OSI_BIT(7) | OSI_BIT(6)) -#define MGBE_MTL_EST_CONTROL_LCSE_VAL 0U -#define MGBE_MTL_EST_CONTROL_DDBF OSI_BIT(4) -#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 ((nveu32_t)0x0 << \ - MGBE_MTL_EST_ADDR_SHIFT) -#define MGBE_MTL_EST_BTR_HIGH ((nveu32_t)0x1 << \ - MGBE_MTL_EST_ADDR_SHIFT) -#define MGBE_MTL_EST_CTR_LOW ((nveu32_t)0x2 << \ - MGBE_MTL_EST_ADDR_SHIFT) -#define MGBE_MTL_EST_CTR_HIGH ((nveu32_t)0x3 << \ - MGBE_MTL_EST_ADDR_SHIFT) -#define MGBE_MTL_EST_CTR_HIGH_MAX 0xFFU -#define MGBE_MTL_EST_TER ((nveu32_t)0x4 << \ - MGBE_MTL_EST_ADDR_SHIFT) -#define MGBE_MTL_EST_LLR ((nveu32_t)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)) /** @} */ /** @@ -708,12 +719,11 @@ * @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 /** @} */ +#ifndef OSI_STRIPPED_LIB /** * @addtogroup MGBE-HW-BACKUP * @@ -836,6 +846,7 @@ #define MGBE_MAX_BAK_IDX ((MGBE_MAC_DCHSEL_BAK_IDX(0U) + \ OSI_MGBE_MAX_MAC_ADDRESS_FILTER + 1U)) /** @} */ +#endif /* !OSI_STRIPPED_LIB */ /** * @addtogroup MGBE-MAC MGBE MAC HW feature registers diff --git a/osi/core/mgbe_mmc.h b/osi/core/mgbe_mmc.h index 7257686..ac97c46 100644 --- a/osi/core/mgbe_mmc.h +++ b/osi/core/mgbe_mmc.h @@ -112,7 +112,6 @@ #define MMC_RXLPIUSECCNTR 0x009A4 #define MMC_RXLPITRANCNTR 0x009A8 #define MMC_RXALIGNMENTERROR 0x009BC -#define MMC_RX_PER_PRIO_PKT_B 0x009D8 #define MMC_TX_FPE_FRAG_COUNTER 0x00A08 #define MMC_TX_HOLD_REQ_COUNTER 0x00A0C #define MMC_RX_PKT_ASSEMBLY_ERR_CNTR 0x00A28 diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index b8c23fa..af9e257 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -2135,7 +2135,6 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, } 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); diff --git a/osi/core/vlan_filter.h b/osi/core/vlan_filter.h index d4b09fe..e60568f 100644 --- a/osi/core/vlan_filter.h +++ b/osi/core/vlan_filter.h @@ -26,6 +26,7 @@ #include <osi_core.h> #include "core_local.h" +#ifndef OSI_STRIPPED_LIB /** * @addtogroup MAC-VLAN MAC VLAN configuration registers and bit fields * @@ -72,4 +73,5 @@ */ nve32_t update_vlan_id(struct osi_core_priv_data *osi_core, struct core_ops *ops_p, nveu32_t vid); +#endif /* !OSI_STRIPPED_LIB */ #endif /* VLAN_FILTER_H */ From f4b5d5ed3fe147b935ee47e209ad310844d888e5 Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Wed, 6 Jul 2022 11:58:02 +0000 Subject: [PATCH 393/458] osi: core: combine core_deinit Bug 3701869 Change-Id: I985e909803f8de858f2c6a8020f9c77eaa75951d Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2740574 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- osi/core/core_local.h | 2 -- osi/core/eqos_core.c | 25 ------------------------- osi/core/mgbe_core.c | 16 ---------------- osi/core/osi_hal.c | 2 +- 4 files changed, 1 insertion(+), 44 deletions(-) diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 07693be..9f77685 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -107,8 +107,6 @@ struct core_ops { 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 handle common interrupt */ void (*handle_common_intr)(struct osi_core_priv_data *const osi_core); /** Called to do pad caliberation */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 6f7dc03..d0b7124 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -3978,30 +3978,6 @@ static nve32_t eqos_config_ptp_rxq(struct osi_core_priv_data *const osi_core, } #endif /* !OSI_STRIPPED_LIB */ -/** - * @brief eqos_core_deinit - EQOS MAC core deinitialization - * - * @note - * Algorithm: - * - This function calls hw_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 */ - hw_stop_mac(osi_core); -} - #ifndef OSI_STRIPPED_LIB /** * @brief eqos_hw_est_write - indirect write the GCL to Software own list @@ -6014,7 +5990,6 @@ void *eqos_get_core_safety_config(void) void eqos_init_core_ops(struct core_ops *ops) { ops->core_init = eqos_core_init; - ops->core_deinit = eqos_core_deinit; ops->handle_common_intr = eqos_handle_common_intr; ops->pad_calibrate = eqos_pad_calibrate; ops->config_mac_pkt_filter_reg = eqos_config_mac_pkt_filter_reg; diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 09aadb9..de54755 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -4197,21 +4197,6 @@ static void mgbe_config_mac_tx(struct osi_core_priv_data *const osi_core, } #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 *const osi_core) -{ - /* Stop the MAC by disabling both MAC Tx and Rx */ - hw_stop_mac(osi_core); -} - /** * @brief mgbe_mdio_busy_wait - MDIO busy wait loop * @@ -5580,7 +5565,6 @@ exit: void mgbe_init_core_ops(struct core_ops *ops) { ops->core_init = mgbe_core_init; - ops->core_deinit = mgbe_core_deinit; ops->handle_common_intr = mgbe_handle_common_intr; ops->pad_calibrate = mgbe_pad_calibrate; ops->config_mac_pkt_filter_reg = mgbe_config_mac_pkt_filter_reg; diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index af9e257..a309a42 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -264,7 +264,7 @@ nve32_t osi_hal_hw_core_deinit(struct osi_core_priv_data *const osi_core) } l_core->hw_init_successful = OSI_DISABLE; - l_core->ops_p->core_deinit(osi_core); + hw_stop_mac(osi_core); if (l_core->state != OSI_SUSPENDED) { /* Reset restore operation flags on interface down */ From 4a2788fdd18af49ceb5ffa187cf00bf3ef1b4a9b Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Wed, 6 Jul 2022 14:04:42 +0000 Subject: [PATCH 394/458] osi: core: combine config_mac_pkt_filter_reg Bug 3701869 Change-Id: I603bd57511f115fb5af42dca2a5804cf4926ebbb Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2740658 Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- osi/core/core_common.c | 72 ++++++++++++++++++++++++ osi/core/core_common.h | 18 +++++- osi/core/core_local.h | 4 -- osi/core/eqos_core.c | 121 ----------------------------------------- osi/core/eqos_core.h | 10 ---- osi/core/mgbe_core.c | 104 ----------------------------------- osi/core/mgbe_core.h | 10 ---- osi/core/osi_hal.c | 2 +- 8 files changed, 90 insertions(+), 251 deletions(-) diff --git a/osi/core/core_common.c b/osi/core/core_common.c index 1e2c5f2..8d03c68 100644 --- a/osi/core/core_common.c +++ b/osi/core/core_common.c @@ -486,6 +486,78 @@ exit: return ret; } +static inline void config_l2_da_perfect_inverse_match( + struct osi_core_priv_data *osi_core, + nveu32_t perfect_inverse_match) +{ + nveu32_t value = 0U; + + value = osi_readla(osi_core, ((nveu8_t *)osi_core->base + MAC_PKT_FILTER_REG)); + value &= ~MAC_PFR_DAIF; + if (perfect_inverse_match == OSI_INV_MATCH) { + /* Set DA Inverse Filtering */ + value |= MAC_PFR_DAIF; + } + osi_writela(osi_core, value, ((nveu8_t *)osi_core->base + MAC_PKT_FILTER_REG)); +} + +nve32_t hw_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 + MAC_PKT_FILTER_REG)); + + /*Retain all other values */ + value &= (MAC_PFR_DAIF | MAC_PFR_DBF | MAC_PFR_SAIF | + MAC_PFR_SAF | MAC_PFR_PCF | MAC_PFR_VTFE | + MAC_PFR_IPFE | MAC_PFR_DNTU | MAC_PFR_RA); + + if ((filter->oper_mode & OSI_OPER_EN_PERFECT) != OSI_DISABLE) { + value |= MAC_PFR_HPF; + } + +#ifndef OSI_STRIPPED_LIB + if ((filter->oper_mode & OSI_OPER_DIS_PERFECT) != OSI_DISABLE) { + value &= ~MAC_PFR_HPF; + } + + if ((filter->oper_mode & OSI_OPER_EN_PROMISC) != OSI_DISABLE) { + value |= MAC_PFR_PR; + } + + if ((filter->oper_mode & OSI_OPER_DIS_PROMISC) != OSI_DISABLE) { + value &= ~MAC_PFR_PR; + } + + if ((filter->oper_mode & OSI_OPER_EN_ALLMULTI) != OSI_DISABLE) { + value |= MAC_PFR_PM; + } + + if ((filter->oper_mode & OSI_OPER_DIS_ALLMULTI) != OSI_DISABLE) { + value &= ~MAC_PFR_PM; + } +#endif /* !OSI_STRIPPED_LIB */ + + osi_writela(osi_core, value, + ((nveu8_t *)osi_core->base + MAC_PKT_FILTER_REG)); + +#ifndef OSI_STRIPPED_LIB + if ((filter->oper_mode & OSI_OPER_EN_L2_DA_INV) != OSI_DISABLE) { + config_l2_da_perfect_inverse_match(osi_core, OSI_INV_MATCH); + } + + if ((filter->oper_mode & OSI_OPER_DIS_L2_DA_INV) != OSI_DISABLE) { +#endif /* !OSI_STRIPPED_LIB */ + config_l2_da_perfect_inverse_match(osi_core, OSI_PFT_MATCH); +#ifndef OSI_STRIPPED_LIB + } +#endif /* !OSI_STRIPPED_LIB */ + + return ret; +} + #ifndef OSI_STRIPPED_LIB /** * @brief hw_est_read - indirect read the GCL to Software own list diff --git a/osi/core/core_common.h b/osi/core/core_common.h index 69f8abf..77b4d4d 100644 --- a/osi/core/core_common.h +++ b/osi/core/core_common.h @@ -52,13 +52,27 @@ #define MAC_PPS_CTL_PPSCTRL0 (OSI_BIT(3) | OSI_BIT(2) |\ OSI_BIT(1) | OSI_BIT(0)) #define MAC_SSIR_SSINC_SHIFT 16U - +#define MAC_PFR_PR OSI_BIT(0) +#define MAC_PFR_DAIF OSI_BIT(3) +#define MAC_PFR_PM OSI_BIT(4) +#define MAC_PFR_DBF OSI_BIT(5) +#define MAC_PFR_PCF (OSI_BIT(6) | OSI_BIT(7)) +#define MAC_PFR_SAIF OSI_BIT(8) +#define MAC_PFR_SAF OSI_BIT(9) +#define MAC_PFR_HPF OSI_BIT(10) +#define MAC_PFR_VTFE OSI_BIT(16) +#define MAC_PFR_IPFE OSI_BIT(20) +#define MAC_PFR_IPFE_SHIFT 20U +#define MAC_PFR_DNTU OSI_BIT(21) +#define MAC_PFR_RA OSI_BIT(31) #define WRAP_SYNC_TSC_PTP_CAPTURE 0x800CU #define WRAP_TSC_CAPTURE_LOW 0x8010U #define WRAP_TSC_CAPTURE_HIGH 0x8014U #define WRAP_PTP_CAPTURE_LOW 0x8018U #define WRAP_PTP_CAPTURE_HIGH 0x801CU +#define MAC_PKT_FILTER_REG 0x0008 + #ifndef OSI_STRIPPED_LIB /** @@ -100,4 +114,6 @@ void hw_config_tscr(struct osi_core_priv_data *const osi_core, const nveu32_t pt void hw_config_ssir(struct osi_core_priv_data *const osi_core); nve32_t hw_ptp_tsc_capture(struct osi_core_priv_data *const osi_core, struct osi_core_ptp_tsc_data *data); +nve32_t hw_config_mac_pkt_filter_reg(struct osi_core_priv_data *const osi_core, + const struct osi_filter *filter); #endif /* INCLUDED_CORE_COMMON_H */ diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 9f77685..0600b53 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -111,10 +111,6 @@ struct core_ops { void (*handle_common_intr)(struct osi_core_priv_data *const osi_core); /** Called to do pad caliberation */ nve32_t (*pad_calibrate)(struct osi_core_priv_data *const osi_core); - /** 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, diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index d0b7124..aa659fb 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -2614,126 +2614,6 @@ static void eqos_config_mac_tx(struct osi_core_priv_data *const osi_core, } #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 <<RM_18, (sequence diagram)>> 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 <<RM_18, (sequence diagram)>> 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() @@ -5992,7 +5872,6 @@ void eqos_init_core_ops(struct core_ops *ops) ops->core_init = eqos_core_init; ops->handle_common_intr = eqos_handle_common_intr; ops->pad_calibrate = eqos_pad_calibrate; - 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; diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index d3356c5..bfe5f86 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -460,19 +460,9 @@ #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_L3L4_CTR_L4SPM0 OSI_BIT(18) #define EQOS_MAC_L3L4_CTR_L4SPIM0 OSI_BIT(19) #define EQOS_MAC_L3L4_CTR_L4DPM0 OSI_BIT(20) diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index de54755..d45ad98 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -258,109 +258,6 @@ static nve32_t mgbe_mac_indir_addr_read(struct osi_core_priv_data *osi_core, 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, - nveu32_t perfect_inverse_match) -{ - nveu32_t value = 0U; - - value = osi_readla(osi_core, - (nveu8_t *)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, - (nveu8_t *)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 nve32_t mgbe_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 + 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, - (nveu8_t *)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 * @@ -5567,7 +5464,6 @@ void mgbe_init_core_ops(struct core_ops *ops) ops->core_init = mgbe_core_init; ops->handle_common_intr = mgbe_handle_common_intr; ops->pad_calibrate = mgbe_pad_calibrate; - 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; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index d3a6002..74fb4f2 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -598,19 +598,9 @@ #define MGBE_DMA_ISR_DCH0_DCH15_MASK 0x3FFU #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_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_IPFE OSI_BIT(20) #define MGBE_MAC_PFR_IPFE_SHIFT 20 -#define MGBE_MAC_PFR_DNTU OSI_BIT(21) -#define MGBE_MAC_PFR_RA OSI_BIT(31) #define MGBE_MAC_ADDRH_AE OSI_BIT(31) #define MGBE_MAC_ADDRH_SA OSI_BIT(30) #define MGBE_MAC_ADDRH_SA_SHIFT 30 diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index a309a42..ca9a8dc 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -387,7 +387,7 @@ nve32_t osi_l2_filter(struct osi_core_priv_data *const osi_core, return -1; } - ret = l_core->ops_p->config_mac_pkt_filter_reg(osi_core, filter); + ret = hw_config_mac_pkt_filter_reg(osi_core, filter); if (ret < 0) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "failed to configure MAC packet filter register\n", From 5ce577f554bd9f64f4d90737503e863afa505a01 Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Wed, 6 Jul 2022 14:29:53 +0000 Subject: [PATCH 395/458] osi: core: combine config_l3_l4_filter_enable Bug 3701869 Change-Id: Ic36cb61075495589c9aaf9bafb7ce1eeda4de673 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2740674 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/core_common.c | 24 ++++++++++++++++++++++++ osi/core/core_common.h | 2 ++ osi/core/core_local.h | 4 ---- osi/core/eqos_core.c | 42 +----------------------------------------- osi/core/eqos_core.h | 8 ++++---- osi/core/mgbe_core.c | 36 ------------------------------------ osi/core/mgbe_core.h | 8 ++++---- osi/core/osi_hal.c | 6 ++---- 8 files changed, 37 insertions(+), 93 deletions(-) diff --git a/osi/core/core_common.c b/osi/core/core_common.c index 8d03c68..4d24ec5 100644 --- a/osi/core/core_common.c +++ b/osi/core/core_common.c @@ -558,6 +558,30 @@ nve32_t hw_config_mac_pkt_filter_reg(struct osi_core_priv_data *const osi_core, return ret; } +nve32_t hw_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; + nve32_t ret = 0; + + /* 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); + ret = -1; + goto fail; + } + + value = osi_readla(osi_core, ((nveu8_t *)base + MAC_PKT_FILTER_REG)); + value &= ~(MAC_PFR_IPFE); + value |= ((filter_enb_dis << MAC_PFR_IPFE_SHIFT) & MAC_PFR_IPFE); + osi_writela(osi_core, value, ((nveu8_t *)base + MAC_PKT_FILTER_REG)); +fail: + return ret; +} + #ifndef OSI_STRIPPED_LIB /** * @brief hw_est_read - indirect read the GCL to Software own list diff --git a/osi/core/core_common.h b/osi/core/core_common.h index 77b4d4d..8d1f6ea 100644 --- a/osi/core/core_common.h +++ b/osi/core/core_common.h @@ -116,4 +116,6 @@ nve32_t hw_ptp_tsc_capture(struct osi_core_priv_data *const osi_core, struct osi_core_ptp_tsc_data *data); nve32_t hw_config_mac_pkt_filter_reg(struct osi_core_priv_data *const osi_core, const struct osi_filter *filter); +nve32_t hw_config_l3_l4_filter_enable(struct osi_core_priv_data *const osi_core, + const nveu32_t filter_enb_dis); #endif /* INCLUDED_CORE_COMMON_H */ diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 0600b53..249d3cb 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -115,10 +115,6 @@ struct core_ops { 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, diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index aa659fb..38a3bc4 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -2858,46 +2858,6 @@ static nve32_t eqos_update_mac_addr_low_high_reg( 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 * @@ -2963,6 +2923,7 @@ static nve32_t eqos_update_ip4_addr(struct osi_core_priv_data *const osi_core, return 0; } + #ifndef OSI_STRIPPED_LIB /** * @brief eqos_config_ptp_offload - Enable/Disable PTP offload @@ -5873,7 +5834,6 @@ void eqos_init_core_ops(struct core_ops *ops) ops->handle_common_intr = eqos_handle_common_intr; ops->pad_calibrate = eqos_pad_calibrate; 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->adjust_mactime = eqos_adjust_mactime; ops->read_mmc = eqos_read_mmc; diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index bfe5f86..99142a3 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -24,6 +24,7 @@ #define INCLUDED_EQOS_CORE_H #ifndef OSI_STRIPPED_LIB +#define EQOS_MAC_PFR 0x0008 #define EQOS_MAC_LPI_CSR 0x00D0 #define EQOS_MAC_LPI_TIMER_CTRL 0x00D4 #define EQOS_MAC_LPI_EN_TIMER 0x00D8 @@ -68,6 +69,9 @@ #define EQOS_CLOCK_CTRL_0 0x8000U #define EQOS_APB_ERR_STATUS 0x8214U +#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_MA0HR_IDX 11U #define EQOS_5_30_SID 0x3U #define EQOS_5_30_SID_CH3 ((EQOS_5_30_SID) << EQOS_ASID_CTRL_SHIFT_24) @@ -279,7 +283,6 @@ */ #define EQOS_MAC_MCR 0x0000 #define EQOS_MAC_EXTR 0x0004 -#define EQOS_MAC_PFR 0x0008 #define EQOS_MAC_VLAN_TAG 0x0050 #define EQOS_MAC_VLANTIR 0x0060 #define EQOS_MAC_RQC0R 0x00A0 @@ -460,9 +463,6 @@ #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_VTFE OSI_BIT(16) -#define EQOS_MAC_PFR_IPFE OSI_BIT(20) -#define EQOS_MAC_PFR_IPFE_SHIFT 20U #define EQOS_MAC_L3L4_CTR_L4SPM0 OSI_BIT(18) #define EQOS_MAC_L3L4_CTR_L4SPIM0 OSI_BIT(19) #define EQOS_MAC_L3L4_CTR_L4DPM0 OSI_BIT(20) diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index d45ad98..77950c4 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -824,41 +824,6 @@ static nve32_t mgbe_update_l4_port_no(struct osi_core_priv_data *osi_core, } #endif /* !OSI_STRIPPED_LIB */ -/** - * @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 nve32_t mgbe_config_l3_l4_filter_enable( - struct osi_core_priv_data *const osi_core, - nveu32_t filter_enb_dis) -{ - nveu32_t 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_core->osd, OSI_LOG_ARG_INVALID, - "Invalid filter_enb_dis value\n", - filter_enb_dis); - return -1; - } - - value = osi_readla(osi_core, (nveu8_t *)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, (nveu8_t *)base + MGBE_MAC_PFR); - - return 0; -} /** * @brief mgbe_set_dcs - check and update dma routing register * @@ -5465,7 +5430,6 @@ void mgbe_init_core_ops(struct core_ops *ops) ops->handle_common_intr = mgbe_handle_common_intr; ops->pad_calibrate = mgbe_pad_calibrate; 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->adjust_mactime = mgbe_adjust_mactime; ops->read_mmc = mgbe_read_mmc; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 74fb4f2..8a2a498 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -24,6 +24,7 @@ #define MGBE_CORE_H_ #ifndef OSI_STRIPPED_LIB +#define MGBE_MAC_PFR 0x0008 #define MGBE_MAC_RX_FLW_CTRL 0x0090 #define MGBE_MAC_QX_TX_FLW_CTRL(x) ((0x0004U * (x)) + 0x0070U) #define MGBE_MAC_ARPPA 0x0C10 @@ -69,6 +70,9 @@ #define MGBE_MTL_FPE_CTS 0x1090 #define MGBE_MTL_FPE_ADV 0x1094 +#define MGBE_MAC_PFR_VTFE OSI_BIT(16) +#define MGBE_MAC_PFR_IPFE OSI_BIT(20) +#define MGBE_MAC_PFR_IPFE_SHIFT 20 #define MGBE_MTL_TCQ_ETS_CR_AVALG_SHIFT 0U #define MGBE_MTL_QINT_TXUNIFS OSI_BIT(0) #define MGBE_MTL_TX_OP_MODE_Q2TCMAP (OSI_BIT(10) | OSI_BIT(9) |\ @@ -382,7 +386,6 @@ */ #define MGBE_MAC_TMCR 0x0000 #define MGBE_MAC_RMCR 0x0004 -#define MGBE_MAC_PFR 0x0008 #define MGBE_MAC_VLAN_TR 0x0050 #define MGBE_MAC_VLANTIR 0x0060 #define MGBE_MAC_RQC0R 0x00A0 @@ -598,9 +601,6 @@ #define MGBE_DMA_ISR_DCH0_DCH15_MASK 0x3FFU #define MGBE_DMA_CHX_STATUS_TI OSI_BIT(0) #define MGBE_DMA_CHX_STATUS_RI OSI_BIT(6) -#define MGBE_MAC_PFR_VTFE OSI_BIT(16) -#define MGBE_MAC_PFR_IPFE OSI_BIT(20) -#define MGBE_MAC_PFR_IPFE_SHIFT 20 #define MGBE_MAC_ADDRH_AE OSI_BIT(31) #define MGBE_MAC_ADDRH_SA OSI_BIT(30) #define MGBE_MAC_ADDRH_SA_SHIFT 30 diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index ca9a8dc..c8592fc 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -565,11 +565,9 @@ static nve32_t osi_l3l4_filter(struct osi_core_priv_data *const osi_core, } if (osi_core->l3l4_filter_bitmask != OSI_DISABLE) { - ret = l_core->ops_p->config_l3_l4_filter_enable(osi_core, - OSI_ENABLE); + ret = hw_config_l3_l4_filter_enable(osi_core, OSI_ENABLE); } else { - ret = l_core->ops_p->config_l3_l4_filter_enable(osi_core, - OSI_DISABLE); + ret = hw_config_l3_l4_filter_enable(osi_core, OSI_DISABLE); } return ret; From e32a81bb75d701936af8d3011b5eeb763e83fa65 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Tue, 12 Jul 2022 21:53:05 +0530 Subject: [PATCH 396/458] osi: dma: Fix MISRA issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ===== DIFF ====== Total misra violation count changed by -162 Rule: MISRA_C-2012_Directive_4.6 Diff: -13 Rule: MISRA_C-2012_Directive_4.9 Diff: 5 Rule: MISRA_C-2012_Rule_10.1 Diff: -2 Rule: MISRA_C-2012_Rule_11.3 Diff: -15 Rule: MISRA_C-2012_Rule_11.5 Diff: 15 Rule: MISRA_C-2012_Rule_12.2 Diff: -2 Rule: MISRA_C-2012_Rule_15.1 Diff: 64 Rule: MISRA_C-2012_Rule_15.4 Diff: 5 Rule: MISRA_C-2012_Rule_15.5 Diff: -76 Rule: MISRA_C-2012_Rule_15.6 Diff: -1 Rule: MISRA_C-2012_Rule_15.7 Diff: -2 Rule: MISRA_C-2012_Rule_16.4 Diff: -1 Rule: MISRA_C-2012_Rule_2.3 Diff: -2 Rule: MISRA_C-2012_Rule_2.4 Diff: -1 Rule: MISRA_C-2012_Rule_2.5 Diff: -106 Rule: MISRA_C-2012_Rule_5.7 Diff: -1 Rule: MISRA_C-2012_Rule_5.9 Diff: -6 Rule: MISRA_C-2012_Rule_8.13 Diff: -18 Rule: MISRA_C-2012_Rule_8.2 Diff: -1 Rule: MISRA_C-2012_Rule_8.3 Diff: -2 Rule: MISRA_C-2012_Rule_8.9 Diff: -2 Rule: Total Diff: -162 *******************CERT report Analysis summary report: Defects/Coding rule violations found : 47 Total CERT_INT30-C 47 - (Deviation Not approved) Total 47 ===== DIFF ====== Total cert violation count changed by -16 Rule: CERT_INT30-C Diff: -16 Rule: Total Diff: -16 *******************CERT ADV report Analysis summary report: Defects/Coding rule violations found : 36 Total CERT_DCL37-C (Full Deviation) 36 - (Deviation Approved) Total 36 ===== DIFF ====== Total cert_adv violation count changed by -76 Rule: CERT_DCL37-C Diff: -62 Rule: CERT_EXP39-C Diff: -14 Rule: Total Diff: -76 JIRA NET-224 Change-Id: I2084da3d98646e6f9fb7933adbee39343e509e8d Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2744955 Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- include/osi_common.h | 2 +- include/osi_dma.h | 11 +- include/osi_dma_txrx.h | 1 - osi/common/common.h | 41 ++++-- osi/common/osi_common.c | 4 +- osi/dma/debug.c | 2 + osi/dma/dma_local.h | 44 ++---- osi/dma/eqos_desc.c | 120 ++++++++-------- osi/dma/eqos_dma.h | 96 ------------- osi/dma/hw_desc.h | 18 +-- osi/dma/mgbe_desc.c | 42 +++--- osi/dma/mgbe_desc.h | 2 + osi/dma/mgbe_dma.h | 50 +------ osi/dma/osi_dma.c | 301 ++++++++++++++++++++++++---------------- osi/dma/osi_dma_txrx.c | 178 ++++++++++++++---------- 15 files changed, 440 insertions(+), 472 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index a2d8acc..3b1834c 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -313,7 +313,7 @@ static inline nveu64_t osi_update_stats_counter(nveu64_t last_value, if (temp < last_value) { /* Stats overflow, so reset it to zero */ - return 0UL; + temp = 0UL; } return temp; diff --git a/include/osi_dma.h b/include/osi_dma.h index be6867d..77df993 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -118,7 +118,9 @@ /** Paged buffer */ #define OSI_PKT_CX_PAGED_BUF OSI_BIT(4) /** Rx packet has RSS hash */ +#ifndef OSI_STRIPPED_LIB #define OSI_PKT_CX_RSS OSI_BIT(5) +#endif /* !OSI_STRIPPED_LIB */ /** Valid packet */ #define OSI_PKT_CX_VALID OSI_BIT(10) /** Update Packet Length in Tx Desc3 */ @@ -127,18 +129,18 @@ #define OSI_PKT_CX_IP_CSUM OSI_BIT(12) /** @} */ +#ifndef OSI_STRIPPED_LIB /** * @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 /** @} */ +#endif /* !OSI_STRIPPED_LIB */ /** * @addtogroup EQOS-TX Tx done packet context fields @@ -208,7 +210,7 @@ /** @} */ - +#ifndef OSI_STRIPPED_LIB /** * @addtogroup RSS-HASH type * @@ -220,6 +222,7 @@ #define OSI_RX_PKT_HASH_TYPE_L3 0x2U #define OSI_RX_PKT_HASH_TYPE_L4 0x3U /** @} */ +#endif /* !OSI_STRIPPED_LIB */ /** * @addtogroup OSI-INTR OSI DMA interrupt handling macros. @@ -666,7 +669,7 @@ nveu32_t osi_get_global_dma_status(struct osi_dma_priv_data *osi_dma); * * @retval "Number of available free descriptors." */ -nveu32_t osi_get_refill_rx_desc_cnt(struct osi_dma_priv_data *osi_dma, +nveu32_t osi_get_refill_rx_desc_cnt(const struct osi_dma_priv_data *const osi_dma, nveu32_t chan); /** diff --git a/include/osi_dma_txrx.h b/include/osi_dma_txrx.h index 35834b6..325a0dd 100644 --- a/include/osi_dma_txrx.h +++ b/include/osi_dma_txrx.h @@ -32,7 +32,6 @@ #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 /** @} */ diff --git a/osi/common/common.h b/osi/common/common.h index aeeb738..3d37f14 100644 --- a/osi/common/common.h +++ b/osi/common/common.h @@ -256,25 +256,25 @@ static inline void osi_writela(OSI_UNUSED void *priv, nveu32_t val, void *addr) * @retval 1 - for Valid MAC */ static inline nve32_t validate_mac_ver_update_chans(nveu32_t mac_ver, - nveu32_t *max_chans, + nveu32_t *num_max_chans, nveu32_t *l_mac_ver) { nve32_t ret; switch (mac_ver) { case OSI_EQOS_MAC_5_00: - *max_chans = OSI_EQOS_XP_MAX_CHANS; + *num_max_chans = OSI_EQOS_XP_MAX_CHANS; *l_mac_ver = MAC_CORE_VER_TYPE_EQOS; ret = 1; break; case OSI_EQOS_MAC_5_30: - *max_chans = OSI_EQOS_MAX_NUM_CHANS; + *num_max_chans = OSI_EQOS_MAX_NUM_CHANS; *l_mac_ver = MAC_CORE_VER_TYPE_EQOS_5_30; ret = 1; break; case OSI_MGBE_MAC_3_10: case OSI_MGBE_MAC_4_00: - *max_chans = OSI_MGBE_MAX_NUM_CHANS; + *num_max_chans = OSI_MGBE_MAX_NUM_CHANS; *l_mac_ver = MAC_CORE_VER_TYPE_MGBE; ret = 1; break; @@ -305,7 +305,7 @@ static inline void osi_memset(void *s, nveu32_t c, nveu64_t count) nveu64_t temp = count; if (s == OSI_NULL) { - return; + goto done; } xs = (nveu8_t *)s; while (temp != 0UL) { @@ -315,6 +315,8 @@ static inline void osi_memset(void *s, nveu32_t c, nveu64_t count) } temp--; } +done: + return; } /** @@ -332,38 +334,47 @@ static inline void osi_memset(void *s, nveu32_t c, nveu64_t count) */ 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; + const nve8_t *csrc = (nve8_t *)src; + nve32_t ret = 0; nveu64_t i = 0; if ((src == OSI_NULL) || (dest == OSI_NULL)) { - return -1; + ret = -1; + goto fail; } for (i = 0; i < n; i++) { cdest[i] = csrc[i]; } - return 0; +fail: + return ret; } static inline nve32_t osi_memcmp(void *dest, void *src, nve32_t n) { + const nve8_t *const cdest = (nve8_t *)dest; + const nve8_t *const csrc = (nve8_t *)src; + nve32_t ret = 0; nve32_t i; - nve8_t *csrc = (nve8_t *)src; - nve8_t *cdest = (nve8_t *)dest; - if ((src == OSI_NULL) || (dest == OSI_NULL)) - return -1; + if ((src == OSI_NULL) || (dest == OSI_NULL)) { + ret = -1; + goto fail; + } for (i = 0; i < n; i++) { if (csrc[i] < cdest[i]) { - return -1; + ret = -1; + goto fail; } else if (csrc[i] > cdest[i]) { - return 1; + ret = 1; + goto fail; } else { /* Do Nothing */ } } - return 0; +fail: + return ret; } #endif diff --git a/osi/common/osi_common.c b/osi/common/osi_common.c index 18df8ff..3a369d6 100644 --- a/osi/common/osi_common.c +++ b/osi/common/osi_common.c @@ -31,7 +31,7 @@ void common_get_systime_from_mac(void *addr, nveu32_t mac, nveu32_t *sec, nveu64_t remain; nveul64_t ns; typedef nveul64_t (*get_time)(void *addr); - get_time i_ops[MAX_MAC_IP_TYPES] = { + const get_time i_ops[MAX_MAC_IP_TYPES] = { eqos_get_systime_from_mac, mgbe_get_systime_from_mac }; @@ -53,7 +53,7 @@ void common_get_systime_from_mac(void *addr, nveu32_t mac, nveu32_t *sec, 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] = { + const mac_enable_arr i_ops[MAX_MAC_IP_TYPES] = { eqos_is_mac_enabled, mgbe_is_mac_enabled }; diff --git a/osi/dma/debug.c b/osi/dma/debug.c index 3ccb451..aecbfa8 100644 --- a/osi/dma/debug.c +++ b/osi/dma/debug.c @@ -250,6 +250,8 @@ void desc_dump(struct osi_dma_priv_data *osi_dma, unsigned int f_idx, rx_desc_dump(osi_dma, f_idx, chan); break; default: + OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, + "Invalid desc dump flag\n", 0ULL); break; } } diff --git a/osi/dma/dma_local.h b/osi/dma/dma_local.h index 1820ab4..7c87e89 100644 --- a/osi/dma/dma_local.h +++ b/osi/dma/dma_local.h @@ -66,7 +66,7 @@ struct dma_chan_ops { */ struct desc_ops { /** Called to get receive checksum */ - void (*get_rx_csum)(struct osi_rx_desc *rx_desc, + void (*get_rx_csum)(const struct osi_rx_desc *const rx_desc, struct osi_rx_pkt_cx *rx_pkt_cx); #ifndef OSI_STRIPPED_LIB /** Called to get rx error stats */ @@ -80,10 +80,10 @@ struct desc_ops { struct osi_rx_pkt_cx *rx_pkt_cx); #endif /* !OSI_STRIPPED_LIB */ /** 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); + nve32_t (*get_rx_hwstamp)(const struct osi_dma_priv_data *const osi_dma, + const struct osi_rx_desc *const rx_desc, + const struct osi_rx_desc *const context_desc, + struct osi_rx_pkt_cx *rx_pkt_cx); }; /** @@ -107,7 +107,7 @@ struct dma_local { /** Magic number to validate osi_dma pointer */ nveu64_t magic_num; /** Maximum number of DMA channels */ - nveu32_t max_chans; + nveu32_t num_max_chans; /** Exact MAC used across SOCs 0:Legacy EQOS, 1:Orin EQOS, 2:Orin MGBE */ nveu32_t l_mac_ver; }; @@ -141,14 +141,14 @@ 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); +void eqos_init_desc_ops(struct desc_ops *p_dops); /** * @brief mgbe_get_desc_ops - MGBE init DMA descriptor operations */ -void mgbe_init_desc_ops(struct desc_ops *d_ops); +void mgbe_init_desc_ops(struct desc_ops *p_dops); -nve32_t init_desc_ops(struct osi_dma_priv_data *osi_dma); +nve32_t init_desc_ops(const struct osi_dma_priv_data *const osi_dma); /** * @brief osi_hw_transmit - Initialize Tx DMA descriptors for a channel @@ -199,33 +199,15 @@ nve32_t dma_desc_init(struct osi_dma_priv_data *osi_dma); static inline nveu32_t is_power_of_two(nveu32_t num) { + nveu32_t ret = OSI_DISABLE; + if ((num > 0U) && ((num & (num - 1U)) == 0U)) { - return OSI_ENABLE; + ret = OSI_ENABLE; } - return OSI_DISABLE; + return ret; } -/** - * @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)) diff --git a/osi/dma/eqos_desc.c b/osi/dma/eqos_desc.c index 54004d0..389ac72 100644 --- a/osi/dma/eqos_desc.c +++ b/osi/dma/eqos_desc.c @@ -115,7 +115,7 @@ static void eqos_get_rx_hash(OSI_UNUSED struct osi_rx_desc *rx_desc, * @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, +static void eqos_get_rx_csum(const struct osi_rx_desc *const rx_desc, struct osi_rx_pkt_cx *rx_pkt_cx) { nveu32_t pkt_type; @@ -125,51 +125,49 @@ static void eqos_get_rx_csum(struct osi_rx_desc *rx_desc, * 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 */ + if ((rx_desc->rdes3 & RDES3_RS1V) == RDES3_RS1V) { + if ((rx_desc->rdes1 & + (RDES1_IPCE | RDES1_IPCB | RDES1_IPHE)) == OSI_DISABLE) { + rx_pkt_cx->rxcsum |= OSI_CHECKSUM_UNNECESSARY; } - } else { - /* Do nothing */ + if ((rx_desc->rdes1 & RDES1_IPCB) != RDES1_IPCB) { + 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; + } + } } - if ((rx_desc->rdes1 & RDES1_IPCE) == RDES1_IPCE) { - rx_pkt_cx->rxcsum |= OSI_CHECKSUM_TCP_UDP_BAD; - } + return; } /** @@ -188,12 +186,13 @@ static void eqos_get_rx_csum(struct osi_rx_desc *rx_desc, * @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) +static nve32_t eqos_get_rx_hwstamp(const struct osi_dma_priv_data *const osi_dma, + const struct osi_rx_desc *const rx_desc, + const struct osi_rx_desc *const context_desc, + struct osi_rx_pkt_cx *rx_pkt_cx) { - int retry; + nve32_t ret = 0; + nve32_t retry; /* Check for RS1V/TSA/TD valid */ if (((rx_desc->rdes3 & RDES3_RS1V) == RDES3_RS1V) && @@ -207,7 +206,8 @@ static int eqos_get_rx_hwstamp(struct osi_dma_priv_data *osi_dma, OSI_INVALID_VALUE) && (context_desc->rdes1 == OSI_INVALID_VALUE)) { - return -1; + ret = -1; + goto fail; } /* Update rx pkt context flags to indicate * PTP */ @@ -221,29 +221,31 @@ static int eqos_get_rx_hwstamp(struct osi_dma_priv_data *osi_dma, } if (retry == 10) { /* Timed out waiting for Rx timestamp */ - return -1; + ret = -1; + goto fail; } 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; + ret = -1; + goto fail; } } else { - return -1; + ret = -1; } - - return 0; +fail: + return ret; } -void eqos_init_desc_ops(struct desc_ops *d_ops) +void eqos_init_desc_ops(struct desc_ops *p_dops) { #ifndef OSI_STRIPPED_LIB - 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; + p_dops->update_rx_err_stats = eqos_update_rx_err_stats; + p_dops->get_rx_vlan = eqos_get_rx_vlan; + p_dops->get_rx_hash = eqos_get_rx_hash; #endif /* !OSI_STRIPPED_LIB */ - d_ops->get_rx_csum = eqos_get_rx_csum; - d_ops->get_rx_hwstamp = eqos_get_rx_hwstamp; + p_dops->get_rx_csum = eqos_get_rx_csum; + p_dops->get_rx_hwstamp = eqos_get_rx_hwstamp; } diff --git a/osi/dma/eqos_dma.h b/osi/dma/eqos_dma.h index 4b48627..cb4fbf0 100644 --- a/osi/dma/eqos_dma.h +++ b/osi/dma/eqos_dma.h @@ -71,8 +71,6 @@ #define EQOS_DMA_CHX_STATUS_CLEAR_RX \ (EQOS_DMA_CHX_STATUS_RI | EQOS_DMA_CHX_STATUS_NIS) -#define EQOS_DMA_CHX_INTR_TIE OSI_BIT(0) -#define EQOS_DMA_CHX_INTR_RIE OSI_BIT(6) #ifdef OSI_DEBUG #define EQOS_DMA_CHX_INTR_TBUE OSI_BIT(2) #define EQOS_DMA_CHX_INTR_RBUE OSI_BIT(7) @@ -80,11 +78,6 @@ #define EQOS_DMA_CHX_INTR_AIE OSI_BIT(14) #define EQOS_DMA_CHX_INTR_NIE OSI_BIT(15) #endif -#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 @@ -95,99 +88,10 @@ /* 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 /** @} */ - -/** - * @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_desc.h b/osi/dma/hw_desc.h index 45cf896..ddf27f0 100644 --- a/osi/dma/hw_desc.h +++ b/osi/dma/hw_desc.h @@ -45,22 +45,26 @@ #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) +#ifndef OSI_STRIPPED_LIB +#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 RDES0_OVT 0x0000FFFFU +#define RDES3_RS0V OSI_BIT(25) +#define RDES3_RSV OSI_BIT(26) #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 RDES3_ELLT_CVLAN 0x90000U +#define RDES3_ERR_MGBE_CRC (OSI_BIT(16) | OSI_BIT(17)) +#endif /* !OSI_STRIPPED_LIB */ #define RDES1_IPCE OSI_BIT(7) #define RDES1_IPCB OSI_BIT(6) @@ -73,7 +77,6 @@ #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 */ @@ -83,7 +86,6 @@ /** 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 * diff --git a/osi/dma/mgbe_desc.c b/osi/dma/mgbe_desc.c index 7a3fb29..f3169f8 100644 --- a/osi/dma/mgbe_desc.c +++ b/osi/dma/mgbe_desc.c @@ -146,10 +146,10 @@ static void mgbe_get_rx_hash(struct osi_rx_desc *rx_desc, * @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, +static void mgbe_get_rx_csum(const struct osi_rx_desc *const rx_desc, struct osi_rx_pkt_cx *rx_pkt_cx) { - unsigned int ellt = rx_desc->rdes3 & RDES3_ELLT; + nveu32_t ellt = rx_desc->rdes3 & RDES3_ELLT; /* Always include either checksum none/unnecessary * depending on status fields in desc. @@ -175,15 +175,17 @@ static void mgbe_get_rx_csum(struct osi_rx_desc *rx_desc, * @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) +static nve32_t mgbe_get_rx_hwstamp(const struct osi_dma_priv_data *const osi_dma, + const struct osi_rx_desc *const rx_desc, + const struct osi_rx_desc *const context_desc, + struct osi_rx_pkt_cx *rx_pkt_cx) { - int retry; + nve32_t ret = 0; + nve32_t retry; if ((rx_desc->rdes3 & RDES3_CDA) != RDES3_CDA) { - return -1; + ret = -1; + goto fail; } for (retry = 0; retry < 10; retry++) { @@ -194,7 +196,8 @@ static int mgbe_get_rx_hwstamp(struct osi_dma_priv_data *osi_dma, if ((context_desc->rdes0 == OSI_INVALID_VALUE) && (context_desc->rdes1 == OSI_INVALID_VALUE)) { /* Invalid time stamp */ - return -1; + ret = -1; + goto fail; } /* Update rx pkt context flags to indicate PTP */ rx_pkt_cx->flags |= OSI_PKT_CX_PTP; @@ -208,26 +211,27 @@ static int mgbe_get_rx_hwstamp(struct osi_dma_priv_data *osi_dma, if (retry == 10) { /* Timed out waiting for Rx timestamp */ - return -1; + ret = -1; + goto fail; } 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; + ret = -1; } - return 0; +fail: + return ret; } -void mgbe_init_desc_ops(struct desc_ops *d_ops) +void mgbe_init_desc_ops(struct desc_ops *p_dops) { #ifndef OSI_STRIPPED_LIB - 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; + p_dops->update_rx_err_stats = mgbe_update_rx_err_stats; + p_dops->get_rx_vlan = mgbe_get_rx_vlan; + p_dops->get_rx_hash = mgbe_get_rx_hash; #endif /* !OSI_STRIPPED_LIB */ - d_ops->get_rx_csum = mgbe_get_rx_csum; - d_ops->get_rx_hwstamp = mgbe_get_rx_hwstamp; + p_dops->get_rx_csum = mgbe_get_rx_csum; + p_dops->get_rx_hwstamp = mgbe_get_rx_hwstamp; } diff --git a/osi/dma/mgbe_desc.h b/osi/dma/mgbe_desc.h index 8b0d5d0..d3bc340 100644 --- a/osi/dma/mgbe_desc.h +++ b/osi/dma/mgbe_desc.h @@ -23,6 +23,7 @@ #ifndef MGBE_DESC_H_ #define MGBE_DESC_H_ +#ifndef OSI_STRIPPED_LIB /** * @addtogroup MGBE MAC FRP Stats. * @@ -32,6 +33,7 @@ #define MGBE_RDES2_FRPSM OSI_BIT(10) #define MGBE_RDES3_FRPSL OSI_BIT(14) /** @} */ +#endif /* !OSI_STRIPPED_LIB */ #endif /* MGBE_DESC_H_ */ diff --git a/osi/dma/mgbe_dma.h b/osi/dma/mgbe_dma.h index d4a81f6..89032ca 100644 --- a/osi/dma/mgbe_dma.h +++ b/osi/dma/mgbe_dma.h @@ -32,17 +32,6 @@ #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 * @@ -51,7 +40,9 @@ */ #define MGBE_DMA_CHX_TX_CTRL(x) ((0x0080U * (x)) + 0x3104U) #define MGBE_DMA_CHX_RX_CTRL(x) ((0x0080U * (x)) + 0x3108U) +#ifndef OSI_STRIPPED_LIB #define MGBE_DMA_CHX_SLOT_CTRL(x) ((0x0080U * (x)) + 0x310CU) +#endif /* !OSI_STRIPPED_LIB */ #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) @@ -60,10 +51,8 @@ #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) /** @} */ @@ -75,17 +64,10 @@ * @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 0x3000U #define MGBE_DMA_CHX_RX_WDT_RWTU_MASK 0x3000U -#define MGBE_DMA_CHX_RBSZ_MASK 0x7FFEU -#define MGBE_DMA_CHX_RBSZ_SHIFT 1U -#define MGBE_DMA_CHX_CTRL_PBLX8 OSI_BIT(16) -#define MGBE_DMA_CHX_INTR_TIE OSI_BIT(0) -#define MGBE_DMA_CHX_INTR_RIE OSI_BIT(6) #ifdef OSI_DEBUG #define MGBE_DMA_CHX_INTR_TBUE OSI_BIT(2) #define MGBE_DMA_CHX_INTR_RBUE OSI_BIT(7) @@ -93,15 +75,14 @@ #define MGBE_DMA_CHX_INTR_AIE OSI_BIT(14) #define MGBE_DMA_CHX_INTR_NIE OSI_BIT(15) #endif +#ifndef OSI_STRIPPED_LIB #define MGBE_DMA_CHX_SLOT_ESC OSI_BIT(0) +#endif /* !OSI_STRIPPED_LIB */ #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 /** @} */ @@ -111,35 +92,14 @@ * @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 +#define MGBE_DMA_CHX_MAX_PBL_VAL 0x200000U /* 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 index b5e421e..5a6ba85 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -32,12 +32,10 @@ /** * @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]; typedef nve32_t (*dma_intr_fn)(struct osi_dma_priv_data const *osi_dma, nveu32_t intr_ctrl, nveu32_t intr_status, @@ -64,8 +62,9 @@ static inline nve32_t intr_en_dis_retry(nveu8_t *base, nveu32_t intr_ctrl, nveu32_t val, nveu32_t en_dis) { typedef nveu32_t (*set_clear)(nveu32_t val, nveu32_t pos); - set_clear set_clr[2] = { clear_pos_val, set_pos_val }; + const set_clear set_clr[2] = { clear_pos_val, set_pos_val }; nveu32_t cntrl1, cntrl2, i; + nve32_t ret = -1; for (i = 0U; i < 10U; i++) { cntrl1 = osi_readl(base + intr_ctrl); @@ -74,18 +73,14 @@ static inline nve32_t intr_en_dis_retry(nveu8_t *base, nveu32_t intr_ctrl, cntrl2 = osi_readl(base + intr_ctrl); if (cntrl1 == cntrl2) { + ret = 0; break; } else { continue; } } - /* failure case retry failed */ - if (i == 10U) { - return -1; - } - - return 0; + return ret; } static inline nve32_t enable_intr(struct osi_dma_priv_data const *osi_dma, @@ -121,6 +116,8 @@ static inline nve32_t disable_intr(struct osi_dma_priv_data const *osi_dma, struct osi_dma_priv_data *osi_get_dma(void) { + static struct dma_local g_dma[MAX_DMA_INSTANCES]; + struct osi_dma_priv_data *osi_dma = OSI_NULL; nveu32_t i; for (i = 0U; i < MAX_DMA_INSTANCES; i++) { @@ -132,12 +129,14 @@ struct osi_dma_priv_data *osi_get_dma(void) } if (i == MAX_DMA_INSTANCES) { - return OSI_NULL; + goto fail; } g_dma[i].magic_num = (nveu64_t)&g_dma[i].osi_dma; - return &g_dma[i].osi_dma; + osi_dma = &g_dma[i].osi_dma; +fail: + return osi_dma; } /** @@ -155,15 +154,17 @@ struct osi_dma_priv_data *osi_get_dma(void) * @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) +static inline nve32_t dma_validate_args(const struct osi_dma_priv_data *const osi_dma, + const struct dma_local *const l_dma) { + nve32_t ret = 0; + if ((osi_dma == OSI_NULL) || (osi_dma->base == OSI_NULL) || (l_dma->init_done == OSI_DISABLE)) { - return -1; + ret = -1; } - return 0; + return ret; } /** @@ -184,15 +185,16 @@ static inline nve32_t validate_args(struct osi_dma_priv_data *osi_dma, 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; + const struct dma_local *const l_dma = (struct dma_local *)(void *)osi_dma; + nve32_t ret = 0; - if (chan >= l_dma->max_chans) { + if (chan >= l_dma->num_max_chans) { OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "Invalid DMA channel number\n", chan); - return -1; + ret = -1; } - return 0; + return ret; } /** @@ -211,19 +213,20 @@ static inline nve32_t validate_dma_chan_num(struct osi_dma_priv_data *osi_dma, */ 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; + const struct dma_local *const l_dma = (struct dma_local *)(void *)osi_dma; + nveu32_t i = 0U; + nve32_t ret = 0; for (i = 0; i < osi_dma->num_dma_chans; i++) { - if (osi_dma->dma_chans[i] > l_dma->max_chans) { + if (osi_dma->dma_chans[i] > l_dma->num_max_chans) { OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "Invalid DMA channel number:\n", osi_dma->dma_chans[i]); - return -1; + ret = -1; } } - return 0; + return ret; } #ifndef OSI_STRIPPED_LIB @@ -274,22 +277,26 @@ static nve32_t validate_func_ptrs(struct osi_dma_priv_data *osi_dma, 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 }; + const nveu32_t default_rz[] = { EQOS_DEFAULT_RING_SZ, MGBE_DEFAULT_RING_SZ }; + const nveu32_t max_rz[] = { EQOS_DEFAULT_RING_SZ, MGBE_MAX_RING_SZ }; + struct dma_local *l_dma = (struct dma_local *)(void *)osi_dma; typedef void (*init_ops_arr)(struct dma_chan_ops *temp); + static struct dma_chan_ops dma_gops[MAX_MAC_IP_TYPES]; + nve32_t ret = 0; - init_ops_arr i_ops[MAX_MAC_IP_TYPES] = { + const init_ops_arr i_ops[MAX_MAC_IP_TYPES] = { eqos_init_dma_chan_ops, mgbe_init_dma_chan_ops }; if (osi_dma == OSI_NULL) { - return -1; + ret = -1; + goto fail; } if ((l_dma->magic_num != (nveu64_t)osi_dma) || (l_dma->init_done == OSI_ENABLE)) { - return -1; + ret = -1; + goto fail; } if (osi_dma->is_ethernet_server != OSI_ENABLE) { @@ -300,56 +307,63 @@ nve32_t osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) (osi_dma->osd_ops.printf == OSI_NULL) || #endif /* OSI_DEBUG */ (osi_dma->osd_ops.udelay == OSI_NULL)) { - return -1; + ret = -1; + goto fail; } } if (osi_dma->mac > OSI_MAC_HW_MGBE) { OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "DMA: Invalid MAC HW type\n", 0ULL); - return -1; + ret = -1; + goto fail; } if ((osi_dma->tx_ring_sz == 0U) || - !(is_power_of_two(osi_dma->tx_ring_sz)) || + (is_power_of_two(osi_dma->tx_ring_sz) == 0U) || (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_dma->osd, OSI_LOG_ARG_INVALID, - "DMA: Using default Tx ring size: \n", + "DMA: Invalid Tx ring size:\n", osi_dma->tx_ring_sz); + ret = -1; + goto fail; } if ((osi_dma->rx_ring_sz == 0U) || - !(is_power_of_two(osi_dma->rx_ring_sz)) || + (is_power_of_two(osi_dma->rx_ring_sz) == 0U) || (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_dma->osd, OSI_LOG_ARG_INVALID, - "DMA: Using default rx ring size: \n", + "DMA: Invalid Rx ring size:\n", osi_dma->tx_ring_sz); + ret = -1; + goto fail; } - i_ops[osi_dma->mac](&g_ops[osi_dma->mac]); + i_ops[osi_dma->mac](&dma_gops[osi_dma->mac]); if (init_desc_ops(osi_dma) < 0) { OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "DMA desc ops init failed\n", 0ULL); - return -1; + ret = -1; + goto fail; } #ifndef OSI_STRIPPED_LIB - if (validate_func_ptrs(osi_dma, &g_ops[osi_dma->mac]) < 0) { + if (validate_func_ptrs(osi_dma, &dma_gops[osi_dma->mac]) < 0) { OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "DMA ops validation failed\n", 0ULL); - return -1; + ret = -1; + goto fail; } #endif - l_dma->ops_p = &g_ops[osi_dma->mac]; + l_dma->ops_p = &dma_gops[osi_dma->mac]; l_dma->init_done = OSI_ENABLE; - return 0; +fail: + return ret; } static inline void start_dma(const struct osi_dma_priv_data *const osi_dma, nveu32_t chan) @@ -454,7 +468,7 @@ static void init_dma_channel(const struct osi_dma_priv_data *const osi_dma, * calculation by using above formula */ if (tx_pbl[osi_dma->mac] >= MGBE_DMA_CHX_MAX_PBL) { - val |= ((MGBE_DMA_CHX_MAX_PBL / 8U) << MGBE_DMA_CHX_CTRL_PBL_SHIFT); + val |= MGBE_DMA_CHX_MAX_PBL_VAL; } else { val |= ((tx_pbl[osi_dma->mac] / 8U) << MGBE_DMA_CHX_CTRL_PBL_SHIFT); } @@ -468,7 +482,7 @@ static void init_dma_channel(const struct osi_dma_priv_data *const osi_dma, val |= rx_pbl[osi_dma->mac]; } else { if (rx_pbl[osi_dma->mac] >= MGBE_DMA_CHX_MAX_PBL) { - val |= ((MGBE_DMA_CHX_MAX_PBL / 8U) << MGBE_DMA_CHX_CTRL_PBL_SHIFT); + val |= MGBE_DMA_CHX_MAX_PBL_VAL; } else { val |= ((rx_pbl[osi_dma->mac] / 8U) << MGBE_DMA_CHX_CTRL_PBL_SHIFT); } @@ -504,39 +518,44 @@ static void init_dma_channel(const struct osi_dma_priv_data *const osi_dma, nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) { - struct dma_local *l_dma = (struct dma_local *)osi_dma; + struct dma_local *l_dma = (struct dma_local *)(void *)osi_dma; nveu32_t i, chan; - nve32_t ret; + nve32_t ret = 0; - if (validate_args(osi_dma, l_dma) < 0) { - return -1; + if (dma_validate_args(osi_dma, l_dma) < 0) { + ret = -1; + goto fail; } 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, + &l_dma->num_max_chans, &l_dma->l_mac_ver) == 0) { OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "Invalid MAC version\n", (nveu64_t)l_dma->mac_ver); - return -1; + ret = -1; + goto fail; } - if (osi_dma->num_dma_chans > l_dma->max_chans) { + if ((osi_dma->num_dma_chans == 0U) || + (osi_dma->num_dma_chans > l_dma->num_max_chans)) { OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "Invalid number of DMA channels\n", 0ULL); - return -1; + ret = -1; + goto fail; } if (validate_dma_chans(osi_dma) < 0) { OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "DMA channels validation failed\n", 0ULL); - return -1; + ret = -1; + goto fail; } ret = dma_desc_init(osi_dma); if (ret != 0) { - return ret; + goto fail; } /* Enable channel interrupts at wrapper level and start DMA */ @@ -553,7 +572,7 @@ nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) EQOS_DMA_CHX_STATUS(chan)), OSI_BIT(OSI_DMA_CH_TX_INTR)); if (ret < 0) { - return ret; + goto fail; } ret = intr_fn[OSI_DMA_INTR_ENABLE](osi_dma, @@ -564,7 +583,7 @@ nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) EQOS_DMA_CHX_STATUS(chan)), OSI_BIT(OSI_DMA_CH_RX_INTR)); if (ret < 0) { - return ret; + goto fail; } start_dma(osi_dma, chan); @@ -578,7 +597,8 @@ nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) osi_dma->ptp_flag = (OSI_PTP_SYNC_SLAVE | OSI_PTP_SYNC_TWOSTEP); } - return 0; +fail: + return ret; } static inline void stop_dma(const struct osi_dma_priv_data *const osi_dma, @@ -608,41 +628,49 @@ static inline void stop_dma(const struct osi_dma_priv_data *const osi_dma, nve32_t osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma) { - struct dma_local *l_dma = (struct dma_local *)osi_dma; + struct dma_local *l_dma = (struct dma_local *)(void *)osi_dma; + nve32_t ret = 0; nveu32_t i; - if (validate_args(osi_dma, l_dma) < 0) { - return -1; + if (dma_validate_args(osi_dma, l_dma) < 0) { + ret = -1; + goto fail; } - if (osi_dma->num_dma_chans > l_dma->max_chans) { + if (osi_dma->num_dma_chans > l_dma->num_max_chans) { OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "Invalid number of DMA channels\n", 0ULL); - return -1; + ret = -1; + goto fail; } if (validate_dma_chans(osi_dma) < 0) { OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "DMA channels validation failed\n", 0ULL); - return -1; + ret = -1; + goto fail; } for (i = 0; i < osi_dma->num_dma_chans; i++) { stop_dma(osi_dma, osi_dma->dma_chans[i]); } - return 0; +fail: + return ret; } nveu32_t osi_get_global_dma_status(struct osi_dma_priv_data *osi_dma) { - struct dma_local *l_dma = (struct dma_local *)osi_dma; + struct dma_local *l_dma = (struct dma_local *)(void *)osi_dma; + nveu32_t ret = 0U; - if (validate_args(osi_dma, l_dma) < 0) { - return 0; + if (dma_validate_args(osi_dma, l_dma) < 0) { + goto fail; } - return osi_readl((nveu8_t *)osi_dma->base + HW_GLOBAL_DMA_STATUS); + ret = osi_readl((nveu8_t *)osi_dma->base + HW_GLOBAL_DMA_STATUS); +fail: + return ret; } nve32_t osi_handle_dma_intr(struct osi_dma_priv_data *osi_dma, @@ -650,44 +678,54 @@ nve32_t osi_handle_dma_intr(struct osi_dma_priv_data *osi_dma, nveu32_t tx_rx, nveu32_t en_dis) { - struct dma_local *l_dma = (struct dma_local *)osi_dma; + struct dma_local *l_dma = (struct dma_local *)(void *)osi_dma; + nve32_t ret = 0; - if (validate_args(osi_dma, l_dma) < 0) { - return -1; + if (dma_validate_args(osi_dma, l_dma) < 0) { + ret = -1; + goto fail; } if (validate_dma_chan_num(osi_dma, chan) < 0) { - return -1; + ret = -1; + goto fail; } if ((tx_rx > OSI_DMA_CH_RX_INTR) || (en_dis > OSI_DMA_INTR_ENABLE)) { - return -1; + ret = -1; + goto fail; } - return intr_fn[en_dis](osi_dma, VIRT_INTR_CHX_CNTRL(chan), + ret = intr_fn[en_dis](osi_dma, VIRT_INTR_CHX_CNTRL(chan), VIRT_INTR_CHX_STATUS(chan), ((osi_dma->mac == OSI_MAC_HW_MGBE) ? MGBE_DMA_CHX_STATUS(chan) : EQOS_DMA_CHX_STATUS(chan)), OSI_BIT(tx_rx)); + +fail: + return ret; } -nveu32_t osi_get_refill_rx_desc_cnt(struct osi_dma_priv_data *osi_dma, - unsigned int chan) +nveu32_t osi_get_refill_rx_desc_cnt(const struct osi_dma_priv_data *const osi_dma, + nveu32_t chan) { - struct osi_rx_ring *rx_ring = osi_dma->rx_ring[chan]; + const struct osi_rx_ring *const rx_ring = osi_dma->rx_ring[chan]; + nveu32_t ret = 0U; 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; + goto fail; } - return (rx_ring->cur_rx_idx - rx_ring->refill_idx) & + ret = (rx_ring->cur_rx_idx - rx_ring->refill_idx) & (osi_dma->rx_ring_sz - 1U); +fail: + return ret; } /** - * @brief rx_dma_desc_validate_args - DMA Rx descriptor init args Validate + * @brief rx_dma_desc_dma_validate_args - DMA Rx descriptor init args Validate * * Algorithm: Validates DMA Rx descriptor init argments. * @@ -704,30 +742,36 @@ nveu32_t osi_get_refill_rx_desc_cnt(struct osi_dma_priv_data *osi_dma, * @retval 0 on success * @retval -1 on failure. */ -static inline nve32_t rx_dma_desc_validate_args( +static inline nve32_t rx_dma_desc_dma_validate_args( struct osi_dma_priv_data *osi_dma, struct dma_local *l_dma, - struct osi_rx_ring *rx_ring, + const struct osi_rx_ring *const rx_ring, nveu32_t chan) { - if (validate_args(osi_dma, l_dma) < 0) { - return -1; + nve32_t ret = 0; + + if (dma_validate_args(osi_dma, l_dma) < 0) { + ret = -1; + goto fail; } if (!((rx_ring != OSI_NULL) && (rx_ring->rx_swcx != OSI_NULL) && (rx_ring->rx_desc != OSI_NULL))) { OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "dma: Invalid pointers\n", 0ULL); - return -1; + ret = -1; + goto fail; } if (validate_dma_chan_num(osi_dma, chan) < 0) { OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "dma: Invalid channel\n", 0ULL); - return -1; + ret = -1; + goto fail; } - return 0; +fail: + return ret; } /** @@ -748,8 +792,8 @@ static inline nve32_t rx_dma_desc_validate_args( * - De-initialization: No * */ -static inline void rx_dma_handle_ioc(struct osi_dma_priv_data *osi_dma, - struct osi_rx_ring *rx_ring, +static inline void rx_dma_handle_ioc(const struct osi_dma_priv_data *const osi_dma, + const struct osi_rx_ring *const rx_ring, struct osi_rx_desc *rx_desc) { /* reset IOC bit if RWIT is enabled */ @@ -770,14 +814,16 @@ static inline void rx_dma_handle_ioc(struct osi_dma_priv_data *osi_dma, 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 dma_local *l_dma = (struct dma_local *)(void *)osi_dma; struct osi_rx_swcx *rx_swcx = OSI_NULL; struct osi_rx_desc *rx_desc = OSI_NULL; + nveu64_t tailptr = 0; + nve32_t ret = 0; - if (rx_dma_desc_validate_args(osi_dma, l_dma, rx_ring, chan) < 0) { + if (rx_dma_desc_dma_validate_args(osi_dma, l_dma, rx_ring, chan) < 0) { /* Return on arguments validation failure */ - return -1; + ret = -1; + goto fail; } /* Refill buffers */ @@ -823,27 +869,32 @@ nve32_t osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, /* Will not hit this case, used for CERT-C compliance */ OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "dma: Invalid tailptr\n", 0ULL); - return -1; + ret = -1; + goto fail; } update_rx_tail_ptr(osi_dma, chan, tailptr); - return 0; +fail: + return ret; } nve32_t osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) { - struct dma_local *l_dma = (struct dma_local *)osi_dma; + struct dma_local *l_dma = (struct dma_local *)(void *)osi_dma; nveu32_t rx_buf_len; + nve32_t ret = 0; - if (validate_args(osi_dma, l_dma) < 0) { - return -1; + if (dma_validate_args(osi_dma, l_dma) < 0) { + ret = -1; + goto fail; } if (osi_dma->mtu > OSI_MAX_MTU_SIZE) { OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "Invalid MTU setting\n", 0ULL); - return -1; + ret = -1; + goto fail; } /* Add Ethernet header + FCS */ @@ -852,54 +903,64 @@ nve32_t osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) /* Buffer alignment */ osi_dma->rx_buf_len = ((rx_buf_len + (AXI_BUS_WIDTH - 1U)) & ~(AXI_BUS_WIDTH - 1U)); - - return 0; +fail: + return ret; } 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; + struct dma_local *l_dma = (struct dma_local *)(void *)osi_dma; + nve32_t ret = 0; - if (validate_args(osi_dma, l_dma) < 0) { - return -1; + if (dma_validate_args(osi_dma, l_dma) < 0) { + ret = -1; } common_get_systime_from_mac(osi_dma->base, osi_dma->mac, sec, nsec); - return 0; + return ret; } nveu32_t osi_is_mac_enabled(struct osi_dma_priv_data *const osi_dma) { - struct dma_local *l_dma = (struct dma_local *)osi_dma; + struct dma_local *l_dma = (struct dma_local *)(void *)osi_dma; + nveu32_t ret = OSI_DISABLE; - if (validate_args(osi_dma, l_dma) < 0) { - return OSI_DISABLE; + if (dma_validate_args(osi_dma, l_dma) < 0) { + goto fail; } - return common_is_mac_enabled(osi_dma->base, osi_dma->mac); + ret = common_is_mac_enabled(osi_dma->base, osi_dma->mac); +fail: + return ret; } 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; + struct dma_local *l_dma = (struct dma_local *)(void *)osi_dma; + nve32_t ret = 0; - if (osi_unlikely(validate_args(osi_dma, l_dma) < 0)) { - return -1; + if (osi_unlikely(dma_validate_args(osi_dma, l_dma) < 0)) { + ret = -1; + goto fail; } if (osi_unlikely(validate_dma_chan_num(osi_dma, chan) < 0)) { - return -1; + ret = -1; + goto fail; } if (osi_unlikely(osi_dma->tx_ring[chan] == OSI_NULL)) { OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "DMA: Invalid Tx ring\n", 0ULL); - return -1; + ret = -1; + goto fail; } - return hw_transmit(osi_dma, osi_dma->tx_ring[chan], chan); + ret = hw_transmit(osi_dma, osi_dma->tx_ring[chan], chan); +fail: + return ret; } #ifdef OSI_DEBUG @@ -908,7 +969,7 @@ 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)) { + if (osi_unlikely(dma_validate_args(osi_dma, l_dma) < 0)) { return -1; } @@ -962,7 +1023,7 @@ 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) { + if (dma_validate_args(osi_dma, l_dma) < 0) { return -1; } @@ -993,7 +1054,7 @@ nve32_t osi_config_slot_function(struct osi_dma_priv_data *osi_dma, chan = osi_dma->dma_chans[i]; if ((chan == 0x0U) || - (chan >= l_dma->max_chans)) { + (chan >= l_dma->num_max_chans)) { /* Ignore 0 and invalid channels */ continue; } diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index eeea0ce..29fd848 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -58,16 +58,18 @@ static struct desc_ops d_ops[MAX_MAC_IP_TYPES]; static inline nve32_t validate_rx_completions_arg( struct osi_dma_priv_data *osi_dma, nveu32_t chan, - nveu32_t *more_data_avail, + const nveu32_t *const 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; + const struct dma_local *const l_dma = (struct dma_local *)(void *)osi_dma; + nve32_t ret = 0; if (osi_unlikely((osi_dma == OSI_NULL) || (more_data_avail == OSI_NULL) || - (chan >= l_dma->max_chans))) { - return -1; + (chan >= l_dma->num_max_chans))) { + ret = -1; + goto fail; } *rx_ring = osi_dma->rx_ring[chan]; @@ -75,17 +77,20 @@ static inline nve32_t validate_rx_completions_arg( OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "validate_input_rx_completions: Invalid pointers\n", 0ULL); - return -1; + ret = -1; + goto fail; } *rx_pkt_cx = &(*rx_ring)->rx_pkt_cx; if (osi_unlikely(*rx_pkt_cx == OSI_NULL)) { OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "validate_input_rx_completions: Invalid pointers\n", 0ULL); - return -1; + ret = -1; + goto fail; } - return 0; +fail: + return ret; } nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, @@ -108,13 +113,15 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, ret = validate_rx_completions_arg(osi_dma, chan, more_data_avail, &rx_ring, &rx_pkt_cx); if (osi_unlikely(ret < 0)) { - return ret; + received = -1; + goto fail; } if (rx_ring->cur_rx_idx >= osi_dma->rx_ring_sz) { OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "dma_txrx: Invalid cur_rx_idx\n", 0ULL); - return -1; + received = -1; + goto fail; } /* Reset flag to indicate if more Rx frames available to OSD layer */ @@ -248,7 +255,8 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "dma_txrx: Invalid function pointer\n", 0ULL); - return -1; + received = -1; + goto fail; } } #ifndef OSI_STRIPPED_LIB @@ -280,6 +288,8 @@ nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, } } #endif /* !OSI_STRIPPED_LIB */ + +fail: return received; } @@ -484,11 +494,13 @@ static inline nve32_t validate_tx_completions_arg( nveu32_t chan, struct osi_tx_ring **tx_ring) { - struct dma_local *l_dma = (struct dma_local *)osi_dma; + const struct dma_local *const l_dma = (struct dma_local *)(void *)osi_dma; + nve32_t ret = 0; if (osi_unlikely((osi_dma == OSI_NULL) || - (chan >= l_dma->max_chans))) { - return -1; + (chan >= l_dma->num_max_chans))) { + ret = -1; + goto fail; } *tx_ring = osi_dma->tx_ring[chan]; @@ -497,10 +509,11 @@ static inline nve32_t validate_tx_completions_arg( OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "validate_tx_completions_arg: Invalid pointers\n", 0ULL); - return -1; + ret = -1; + goto fail; } - - return 0; +fail: + return ret; } /** @@ -513,15 +526,15 @@ static inline nve32_t validate_tx_completions_arg( * @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) +static inline nveu32_t is_ptp_twostep_or_slave_mode(nveu32_t 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) +nve32_t osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, + nveu32_t chan, nve32_t budget) { struct osi_tx_ring *tx_ring = OSI_NULL; struct osi_txdone_pkt_cx *txdone_pkt_cx = OSI_NULL; @@ -535,7 +548,8 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, ret = validate_tx_completions_arg(osi_dma, chan, &tx_ring); if (osi_unlikely(ret < 0)) { - return ret; + processed = -1; + goto fail; } txdone_pkt_cx = &tx_ring->txdone_pkt_cx; @@ -642,7 +656,8 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "dma_txrx: Invalid function pointer\n", 0ULL); - return -1; + processed = -1; + goto fail; } tx_desc->tdes3 = 0; @@ -664,6 +679,7 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, tx_ring->clean_idx = entry; } +fail: return processed; } @@ -692,18 +708,17 @@ int osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, * @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) +static inline nve32_t need_cntx_desc(const struct osi_tx_pkt_cx *const tx_pkt_cx, + struct osi_tx_swcx *tx_swcx, + struct osi_tx_desc *tx_desc, + nveu32_t ptp_sync_flag, + nveu32_t 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; @@ -730,24 +745,22 @@ static inline nve32_t need_cntx_desc(struct osi_tx_pkt_cx *tx_pkt_cx, /* 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; - } + if (((mac == OSI_MAC_HW_EQOS) && + ((ptp_sync_flag & OSI_PTP_SYNC_TWOSTEP) == OSI_PTP_SYNC_TWOSTEP))) { + /* Doing nothing */ + } else { + /* 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; + } - /* 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; } - - ret = 1; } } @@ -764,7 +777,7 @@ static inline nve32_t need_cntx_desc(struct osi_tx_pkt_cx *tx_pkt_cx, * @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) +static inline nveu32_t is_ptp_onestep_and_master_mode(nveu32_t ptp_flag) { return (((ptp_flag & OSI_PTP_SYNC_MASTER) == OSI_PTP_SYNC_MASTER) && ((ptp_flag & OSI_PTP_SYNC_ONESTEP) == OSI_PTP_SYNC_ONESTEP)) ? @@ -798,13 +811,13 @@ 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) + nveu32_t ptp_flag) #else static inline void fill_first_desc(OSI_UNUSED 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) + nveu32_t ptp_flag) #endif /* !OSI_STRIPPED_LIB */ { tx_desc->tdes0 = L32(tx_swcx->buf_phy_addr); @@ -911,54 +924,63 @@ static inline void dmb_oshst(void) * @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) +static inline nve32_t validate_ctx(const struct osi_dma_priv_data *const osi_dma, + const struct osi_tx_pkt_cx *const tx_pkt_cx) { + nve32_t ret = 0; + 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_dma->osd, OSI_LOG_ARG_INVALID, "dma_txrx: Invalid TSO header len\n", (nveul64_t)tx_pkt_cx->tcp_udp_hdrlen); + ret = -1; goto fail; } else if (osi_unlikely(tx_pkt_cx->payload_len > TDES3_TPL_MASK)) { OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "dma_txrx: Invalid TSO payload len\n", (nveul64_t)tx_pkt_cx->payload_len); + ret = -1; goto fail; } else if (osi_unlikely(tx_pkt_cx->mss > TDES2_MSS_MASK)) { OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "dma_txrx: Invalid MSS\n", (nveul64_t)tx_pkt_cx->mss); + ret = -1; goto fail; + } else { + /* empty statement */ } } 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_dma->osd, OSI_LOG_ARG_INVALID, "dma_txrx: Invalid frame len\n", (nveul64_t)tx_pkt_cx->payload_len); + ret = -1; goto fail; } + } else { + /* empty statement */ } if (osi_unlikely(tx_pkt_cx->vtag_id > TDES3_VT_MASK)) { OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "dma_txrx: Invalid VTAG_ID\n", (nveul64_t)tx_pkt_cx->vtag_id); - goto fail; + ret = -1; } - return 0; fail: - return -1; + return ret; } nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, struct osi_tx_ring *tx_ring, nveu32_t chan) { - struct dma_local *l_dma = (struct dma_local *)osi_dma; + struct dma_local *l_dma = (struct dma_local *)(void *)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; @@ -978,13 +1000,15 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, nveu32_t desc_cnt = 0U; nveu64_t tailptr; nveu32_t entry = 0U; + nve32_t ret = 0; nveu32_t i; entry = tx_ring->cur_tx_idx; if (entry >= osi_dma->tx_ring_sz) { OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "dma_txrx: Invalid cur_tx_idx\n", 0ULL); - return -1; + ret = -1; + goto fail; } tx_desc = tx_ring->tx_desc + entry; @@ -996,11 +1020,13 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, /* Will not hit this case */ OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "dma_txrx: Invalid desc_cnt\n", 0ULL); - return -1; + ret = -1; + goto fail; } if (validate_ctx(osi_dma, tx_pkt_cx) < 0) { - return -1; + ret = -1; + goto fail; } #ifndef OSI_STRIPPED_LIB @@ -1135,7 +1161,8 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, /* Will not hit this case */ OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "dma_txrx: Invalid tx_desc_phy_addr\n", 0ULL); - return -1; + ret = -1; + goto fail; } /* @@ -1147,7 +1174,8 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, /* Update the Tx tail pointer */ osi_writel(L32(tailptr), (nveu8_t *)osi_dma->base + tail_ptr_reg[osi_dma->mac]); - return 0; +fail: + return ret; } /** @@ -1172,7 +1200,7 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, * @retval 0 on success * @retval -1 on failure. */ -static nve32_t rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, +static nve32_t rx_dma_desc_initialization(const struct osi_dma_priv_data *const osi_dma, nveu32_t chan) { const nveu32_t start_addr_high_reg[2] = { @@ -1200,7 +1228,8 @@ static nve32_t rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, if (osi_unlikely(rx_ring == OSI_NULL)) { OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "dma_txrx: Invalid argument\n", 0ULL); - return -1; + ret = -1; + goto fail; }; rx_ring->cur_rx_idx = 0; @@ -1250,7 +1279,8 @@ static nve32_t rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, /* Will not hit this case */ OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "dma_txrx: Invalid phys address\n", 0ULL); - return -1; + ret = -1; + goto fail; } /* Update the HW DMA ring length */ @@ -1266,6 +1296,7 @@ static nve32_t rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, osi_writel(L32(rx_ring->rx_desc_phy_addr), (nveu8_t *)osi_dma->base + start_addr_low_reg[osi_dma->mac]); +fail: return ret; } @@ -1293,18 +1324,19 @@ static nve32_t rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, static nve32_t rx_dma_desc_init(struct osi_dma_priv_data *osi_dma) { nveu32_t chan = 0; - nveu32_t i; nve32_t ret = 0; + nveu32_t i; for (i = 0; i < osi_dma->num_dma_chans; i++) { chan = osi_dma->dma_chans[i]; ret = rx_dma_desc_initialization(osi_dma, chan); if (ret != 0) { - return ret; + goto fail; } } +fail: return ret; } @@ -1360,12 +1392,13 @@ static inline void set_tx_ring_len_and_start_addr(const struct osi_dma_priv_data * @retval 0 on success * @retval -1 on failure. */ -static nve32_t tx_dma_desc_init(struct osi_dma_priv_data *osi_dma) +static nve32_t tx_dma_desc_init(const struct osi_dma_priv_data *const osi_dma) { 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; + nve32_t ret = 0; nveu32_t i, j; for (i = 0; i < osi_dma->num_dma_chans; i++) { @@ -1375,7 +1408,8 @@ static nve32_t tx_dma_desc_init(struct osi_dma_priv_data *osi_dma) if (osi_unlikely(tx_ring == OSI_NULL)) { OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "dma_txrx: Invalid pointers\n", 0ULL); - return -1; + ret = -1; + goto fail; } for (j = 0; j < osi_dma->tx_ring_sz; j++) { @@ -1406,7 +1440,8 @@ static nve32_t tx_dma_desc_init(struct osi_dma_priv_data *osi_dma) chan, (osi_dma->tx_ring_sz - 1U)); } - return 0; +fail: + return ret; } nve32_t dma_desc_init(struct osi_dma_priv_data *osi_dma) @@ -1415,26 +1450,27 @@ nve32_t dma_desc_init(struct osi_dma_priv_data *osi_dma) ret = tx_dma_desc_init(osi_dma); if (ret != 0) { - return ret; + goto fail; } ret = rx_dma_desc_init(osi_dma); if (ret != 0) { - return ret; + goto fail; } +fail: return ret; } -nve32_t init_desc_ops(struct osi_dma_priv_data *osi_dma) +nve32_t init_desc_ops(const struct osi_dma_priv_data *const osi_dma) { - typedef void (*desc_ops_arr)(struct desc_ops *); + typedef void (*desc_ops_arr)(struct desc_ops *p_ops); - desc_ops_arr desc_ops[2] = { + const desc_ops_arr desc_ops_a[2] = { eqos_init_desc_ops, mgbe_init_desc_ops }; - desc_ops[osi_dma->mac](&d_ops[osi_dma->mac]); + desc_ops_a[osi_dma->mac](&d_ops[osi_dma->mac]); /* TODO: validate function pointers */ return 0; From 18028249942b1853952c84c713cc7f8158e9df8c Mon Sep 17 00:00:00 2001 From: Hareesh Kesireddy <hkesireddy@nvidia.com> Date: Fri, 2 Sep 2022 23:19:44 +0530 Subject: [PATCH 397/458] osi: dma: provide choice for driver to skip dmb - Added a skip dmb flag in tx_ring to let driver decide whether barrier need to be performed or not. - Using rsvd1 in tx swcx for storing nvsocket data index. Bug 3672681 Jira NET-332 Change-Id: Ie35b7487c6ba2ae92acd46ec51ec4342b856e404 Signed-off-by: Hareesh Kesireddy <hkesireddy@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2771038 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_dma.h | 6 ++++-- osi/dma/osi_dma_txrx.c | 5 ++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/include/osi_dma.h b/include/osi_dma.h index 77df993..002a519 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -395,8 +395,8 @@ struct osi_tx_swcx { nveu32_t pktid; /** dma channel number for osd use */ nveu32_t chan; - /** reserved field 1 for future use */ - nveu64_t rsvd1; + /** nvsocket data index */ + nveu64_t data_idx; /** reserved field 2 for future use */ nveu64_t rsvd2; }; @@ -477,6 +477,8 @@ struct osi_tx_ring { struct osi_txdone_pkt_cx txdone_pkt_cx; /** Number of packets or frames transmitted */ nveu32_t frame_cnt; + /** flag to skip memory barrier */ + nveu32_t skip_dmb; }; #ifndef OSI_STRIPPED_LIB diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 29fd848..5a6037d 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -669,6 +669,7 @@ nve32_t osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, tx_swcx->buf_virt_addr = OSI_NULL; tx_swcx->buf_phy_addr = 0; tx_swcx->flags = 0; + tx_swcx->data_idx = 0; INCR_TX_DESC_INDEX(entry, osi_dma->tx_ring_sz); /* Don't wait to update tx_ring->clean-idx. It will @@ -1145,7 +1146,9 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, * 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(); + if (tx_ring->skip_dmb == 0U) { + dmb_oshst(); + } #ifdef OSI_DEBUG if (osi_dma->enable_desc_dump == 1U) { From 3c79e2127a2511e8e3a24e090adfda0c546cba56 Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Thu, 11 Aug 2022 06:33:53 +0530 Subject: [PATCH 398/458] nvethernetrm: take exported ioctl related header out Issue: SW needs to support IOCTL on safety builds and these header should be exposed to user Fix: Create new header file which is exposed externally Fix Coverity issues Enable TSN and FRP for safety build Optimize the code between eqos and mgbe Bug 3704251 Change-Id: I2807f8283a296de1f96d3f902cb4ad5a4781be50 Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2759333 GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> --- include/ivc_core.h | 12 +- include/mmc.h | 525 ----------------------- include/nvethernetrm_export.h | 782 ++++++++++++++++++++++++++++++++++ include/osi_common.h | 73 +--- include/osi_core.h | 311 +++----------- osi/common/common.h | 6 +- osi/core/core_common.c | 658 +++++++++++++++++++++++++++- osi/core/core_common.h | 42 +- osi/core/core_local.h | 68 ++- osi/core/eqos_core.c | 600 +++----------------------- osi/core/eqos_core.h | 225 +++++----- osi/core/frp.c | 179 ++++---- osi/core/frp.h | 6 +- osi/core/ivc_core.c | 25 +- osi/core/mgbe_core.c | 759 ++++++--------------------------- osi/core/mgbe_core.h | 274 ++++++------ osi/core/osi_hal.c | 200 +++++---- 17 files changed, 2216 insertions(+), 2529 deletions(-) create mode 100644 include/nvethernetrm_export.h diff --git a/include/ivc_core.h b/include/ivc_core.h index d4e5253..9488686 100644 --- a/include/ivc_core.h +++ b/include/ivc_core.h @@ -35,6 +35,14 @@ */ #define MAX_ARGS 10 +/* + *@brief All Stats + */ +struct osi_stats { + struct osi_mmc_counters mmc_s; + struct osi_tsn_stats tsn_s; +}; + /** * @brief IVC commands between OSD & OSI. */ @@ -135,10 +143,8 @@ typedef struct ivc_msg_common { 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 */ @@ -149,6 +155,8 @@ typedef struct ivc_msg_common { ivc_core_args init_args; /** ioctl command structure */ struct osi_ioctl ioctl_data; + /** All stats */ + struct osi_stats eth_stats; #ifdef MACSEC_SUPPORT /** lut config */ struct osi_macsec_lut_config lut_config; diff --git a/include/mmc.h b/include/mmc.h index 95b957a..1231557 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -26,531 +26,6 @@ #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 */ - nveu64_t mmc_tx_fpe_frag_cnt; - /** This counter provides the count of number of times a hold - * request is given to MAC */ - nveu64_t 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 */ - nveu64_t 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 */ - nveu64_t mmc_rx_packet_smd_err_cnt; - /** This counter provides the number of MAC frames that were - * successfully reassembled and delivered to MAC */ - nveu64_t mmc_rx_packet_asm_ok_cnt; - /** This counter provides the number of additional mPackets received - * due to preemption */ - nveu64_t mmc_rx_fpe_fragment_cnt; -}; - #ifndef OSI_STRIPPED_LIB /** * @brief osi_xtra_stat_counters - OSI core extra stat counters diff --git a/include/nvethernetrm_export.h b/include/nvethernetrm_export.h new file mode 100644 index 0000000..bd5ea96 --- /dev/null +++ b/include/nvethernetrm_export.h @@ -0,0 +1,782 @@ +/* + * 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_NVETHERNETRM_EXPORT_H +#define INCLUDED_NVETHERNETRM_EXPORT_H + +#include "../osi/common/type.h" + +/** + * @addtogroup Helper MACROS + * + * @brief EQOS generic helper MACROS. + * @{ + */ +#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 + +/** + * @addtogroup Flexible Receive Parser related information + * + * @brief Flexible Receive Parser commands, table size and other defines + * @{ + */ +/* Match data defines */ +#define OSI_FRP_MATCH_DATA_MAX 12U +/** @} */ + +/** + * @addtogroup MTL queue operation mode + * + * @brief MTL queue operation mode options + * @{ + */ +#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 +/** @} */ + +/** + * @addtogroup Helper MACROS + * + * @brief EQOS generic helper MACROS. + * @{ + */ +/* L2 DA filter mode(enable/disable) */ +#define OSI_OPER_EN_L2_DA_INV OSI_BIT(4) +#define OSI_OPER_DIS_L2_DA_INV OSI_BIT(5) + +/* Ethernet Address length */ +#define OSI_ETH_ALEN 6U +#define OSI_MAX_TC_NUM 8U +/** @} */ + +#pragma pack(push, 1) +/** + * @brief FRP command structure for OSD to OSI + */ +struct osi_core_frp_cmd { + /** FRP Command type */ + nveu32_t cmd; + /** OSD FRP ID */ + nve32_t frp_id; + /** OSD match data type */ + nveu8_t match_type; + /** OSD match data */ + nveu8_t match[OSI_FRP_MATCH_DATA_MAX]; + /** OSD match data length */ + nveu8_t match_length; + /** OSD Offset */ + nveu8_t offset; + /** OSD FRP filter mode flag */ + nveu8_t filter_mode; + /** OSD FRP Link ID */ + nve32_t next_frp_id; + /** OSD DMA Channel Selection */ + nveu32_t dma_sel; +}; + +/** + * @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 */ + nveu32_t tcindex; +}; + +/** + * @brief OSI Core EST structure + */ +struct osi_est_config { + /** enable/disable */ + nveu32_t 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 + */ + nveu32_t btr[2]; + /** 64 bit base time offset index 0 for nsec, index 1 for sec */ + nveu32_t btr_offset[2]; + /** 40 bit cycle time register, index 0 for nsec, index 1 for sec */ + nveu32_t ctr[2]; + /** Configured Time Interval width + 7 bit extension register */ + nveu32_t ter; + /** size of the gate control list */ + nveu32_t llr; + /** data array 8 bit gate op + 24 execution time + * MGBE HW support GCL depth 256 */ + nveu32_t gcl[OSI_GCL_SIZE_256]; +}; + +/** + * @brief OSI Core FPE structure + */ +struct osi_fpe_config { + /** Queue Mask 1 preemption 0- express bit representation */ + nveu32_t tx_queue_preemption_enable; + /** RQ for all preemptable packets which are not filtered + * based on user priority or SA-DA + */ + nveu32_t rq; +}; + +/** + * @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 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 OSI Core TSN error stats structure + */ +struct osi_tsn_stats { + /** Constant Gate Control Error */ + nveu64_t const_gate_ctr_err; + /** Head-Of-Line Blocking due to Scheduling */ + nveu64_t head_of_line_blk_sch; + /** Per TC Schedule Error */ + nveu64_t hlbs_q[OSI_MAX_TC_NUM]; + /** Head-Of-Line Blocking due to Frame Size */ + nveu64_t head_of_line_blk_frm; + /** Per TC Frame Size Error */ + nveu64_t hlbf_q[OSI_MAX_TC_NUM]; + /** BTR Error */ + nveu64_t base_time_reg_err; + /** Switch to Software Owned List Complete */ + nveu64_t sw_own_list_complete; +}; + +/** + * @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 */ + nveu64_t mmc_tx_fpe_frag_cnt; + /** This counter provides the count of number of times a hold + * request is given to MAC */ + nveu64_t 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 */ + nveu64_t 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 */ + nveu64_t mmc_rx_packet_smd_err_cnt; + /** This counter provides the number of MAC frames that were + * successfully reassembled and delivered to MAC */ + nveu64_t mmc_rx_packet_asm_ok_cnt; + /** This counter provides the number of additional mPackets received + * due to preemption */ + nveu64_t mmc_rx_fpe_fragment_cnt; +}; + +#pragma pack(pop) +#endif /* INCLUDED_NVETHERNETRM_EXPORT_H */ diff --git a/include/osi_common.h b/include/osi_common.h index 3b1834c..6e3f27f 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -70,6 +70,22 @@ /** @} */ #ifndef OSI_STRIPPED_LIB + +/** + * @addtogroup Helper MACROS + * + * @brief EQOS generic helper MACROS. + * @{ + */ +#define OSI_PAUSE_FRAMES_ENABLE 0U +#define OSI_PTP_REQ_CLK_FREQ 250000000U +#define OSI_FLOW_CTRL_DISABLE 0U + +#define OSI_ADDRESS_32BIT 0 +#define OSI_ADDRESS_40BIT 1 +#define OSI_ADDRESS_48BIT 2 +/** @ } */ + /** * @addtogroup - LPI-Timers LPI configuration macros * @@ -117,34 +133,7 @@ /** @} */ #endif /* !OSI_STRIPPED_LIB */ -/** - * @addtogroup Helper Helper MACROS - * - * @brief EQOS generic helper MACROS. - * @{ - */ -#ifndef OSI_STRIPPED_LIB -#define OSI_PAUSE_FRAMES_ENABLE 0U -#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_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_ADDRESS_32BIT 0 -#define OSI_ADDRESS_40BIT 1 -#define OSI_ADDRESS_48BIT 2 -#endif /* !OSI_STRIPPED_LIB */ - #define OSI_POLL_COUNT 1000U -#define OSI_MAX_32BITS 0xFFFFFFFFU -#define OSI_MASK_16BITS 0xFFFFU #ifndef UINT_MAX #define UINT_MAX (~0U) #endif @@ -165,15 +154,15 @@ /* log levels */ #define OSI_LOG_INFO 1U +#ifndef OSI_STRIPPED_LIB +#define OSI_LOG_WARN 2U +#endif /* OSI_STRIPPED_LIB */ #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 -#ifndef OSI_STRIPPED_LIB -#define OSI_LOG_WARN 2U #define OSI_LOG_ARG_OPNOTSUPP 3U -#endif /* !OSI_STRIPPED_LIB */ /* Default maximum Giant Packet Size Limit is 16K */ #define OSI_MAX_MTU_SIZE 16383U @@ -256,30 +245,6 @@ #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 */ diff --git a/include/osi_core.h b/include/osi_core.h index d101b03..6f092f0 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -23,6 +23,7 @@ #ifndef INCLUDED_OSI_CORE_H #define INCLUDED_OSI_CORE_H +#include "nvethernetrm_export.h" #include <osi_common.h> #include "mmc.h" @@ -65,16 +66,17 @@ typedef my_lint_64 nvel64_t; #define OSI_CMD_RESET_MMC 12U #define OSI_CMD_MDC_CONFIG 1U #define OSI_CMD_MAC_LB 14U -#define OSI_CMD_GET_AVB 23U #define OSI_CMD_FLOW_CTRL 15U #define OSI_CMD_CONFIG_TXSTATUS 27U #define OSI_CMD_CONFIG_RX_CRC_CHECK 25U #define OSI_CMD_CONFIG_EEE 32U #define OSI_CMD_ARP_OFFLOAD 30U #define OSI_CMD_UPDATE_VLAN_ID 26U -#define OSI_CMD_SET_AVB 24U #define OSI_CMD_VLAN_FILTER 31U #define OSI_CMD_VALIDATE_CORE_REG 11U +#define OSI_CMD_CONFIG_PTP_OFFLOAD 34U +#define OSI_CMD_PTP_RXQ_ROUTE 35U +#define OSI_CMD_CONFIG_RSS 37U /** * @addtogroup PTP-offload PTP offload defines @@ -94,7 +96,6 @@ typedef my_lint_64 nvel64_t; #define OSI_MAC_TCR_CSC OSI_BIT(19) #define OSI_MAC_TCR_AV8021ASMEN OSI_BIT(28) -#define OSI_FLOW_CTRL_TX OSI_BIT(0) #define OSI_FLOW_CTRL_RX OSI_BIT(1) #endif /* !OSI_STRIPPED_LIB */ @@ -163,7 +164,6 @@ typedef my_lint_64 nvel64_t; #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 @@ -172,8 +172,7 @@ typedef my_lint_64 nvel64_t; #define OSI_EQOS_MAX_HASH_REGS 4U #endif /* !OSI_STRIPPED_LIB */ -#define OSI_ETH_ALEN 6U - +#define OSI_FLOW_CTRL_TX OSI_BIT(0) #define OSI_FULL_DUPLEX 1 #define OSI_HALF_DUPLEX 0 @@ -190,8 +189,6 @@ typedef my_lint_64 nvel64_t; #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) @@ -224,7 +221,6 @@ typedef my_lint_64 nvel64_t; #define OSI_USXGMII_MODE_10G 2U #define OSI_USXGMII_MODE_5G 3U - /** * @addtogroup IOCTL OPS MACROS * @@ -239,6 +235,7 @@ typedef my_lint_64 nvel64_t; #define OSI_CMD_PAD_CALIBRATION 8U #define OSI_CMD_READ_MMC 9U #define OSI_CMD_GET_MAC_VER 10U +#define OSI_CMD_RESET_MMC 12U #define OSI_CMD_SET_MODE 16U #define OSI_CMD_SET_SPEED 17U #define OSI_CMD_L2_FILTER 18U @@ -246,13 +243,12 @@ typedef my_lint_64 nvel64_t; #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_GET_HW_FEAT 28U #define OSI_CMD_CONFIG_FW_ERR 29U #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 @@ -320,20 +316,22 @@ typedef my_lint_64 nvel64_t; #define OSI_PTP_SSINC_6 6U /** @} */ -#ifndef OSI_STRIPPED_LIB /** * @addtogroup Flexible Receive Parser related information * * @brief Flexible Receive Parser commands, table size and other defines * @{ */ +#ifndef OSI_STRIPPED_LIB +#define OSI_FRP_CMD_MAX 3U +#define OSI_FRP_MATCH_MAX 10U +#endif /* !OSI_STRIPPED_LIB */ #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 @@ -345,7 +343,6 @@ typedef my_lint_64 nvel64_t; #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 @@ -356,9 +353,7 @@ typedef my_lint_64 nvel64_t; #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 /** @} */ -#endif /* !OSI_STRIPPED_LIB */ #ifdef HSI_SUPPORT /** @@ -428,34 +423,6 @@ extern nveu32_t hsi_err_code[][3]; 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; -}; - #ifndef OSI_STRIPPED_LIB /** * @brief OSI core structure for RXQ route @@ -470,26 +437,6 @@ struct osi_rxq_route { nveu32_t idx; }; #endif -/** - * @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. @@ -814,64 +761,6 @@ struct osi_vlan_filter { nveu32_t perfect_inverse_match; }; -/** - * @brief FRP Instruction configuration structure - */ -struct osi_core_frp_data { - /* Entry Match Data */ - nveu32_t match_data; - /* Entry Match Enable mask */ - nveu32_t match_en; - /* Entry Accept frame flag */ - nveu8_t accept_frame; - /* Entry Reject Frame flag */ - nveu8_t reject_frame; - /* Entry Inverse match flag */ - nveu8_t inverse_match; - /* Entry Next Instruction Control match flag */ - nveu8_t next_ins_ctrl; - /* Entry Frame offset in the packet data */ - nveu8_t frame_offset; - /* Entry OK Index - Next Instruction */ - nveu8_t ok_index; - /* Entry DMA Channel selection (1-bit for each channel) */ - nveu32_t dma_chsel; -}; - -/** - * @brief FRP command structure for OSD to OSI - */ -struct osi_core_frp_cmd { - /* FRP Command type */ - nveu32_t cmd; - /* OSD FRP ID */ - int frp_id; - /* OSD match data type */ - nveu8_t match_type; - /* OSD match data */ - nveu8_t match[OSI_FRP_MATCH_DATA_MAX]; - /* OSD match data length */ - nveu8_t match_length; - /* OSD Offset */ - nveu8_t offset; - /* OSD FRP filter mode flag */ - nveu8_t filter_mode; - /* OSD FRP Link ID */ - int next_frp_id; - /* OSD DMA Channel Selection */ - nveu32_t 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 */ @@ -882,40 +771,6 @@ struct osi_l2_da_filter { 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 */ - nveu32_t tcindex; -}; - /** * @brief struct ptp_offload_param - Parameter to support PTP offload. */ @@ -937,62 +792,6 @@ struct osi_pto_config { nveu32_t portid; }; -/** - * @brief OSI Core EST structure - */ -struct osi_est_config { - /** enable/disable */ - nveu32_t 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 - */ - nveu32_t btr[2]; - /** 64 bit base time offset index 0 for nsec, index 1 for sec */ - nveu32_t btr_offset[2]; - /** 40 bit cycle time register, index 0 for nsec, index 1 for sec */ - nveu32_t ctr[2]; - /** Configured Time Interval width + 7 bit extension register */ - nveu32_t ter; - /** size of the gate control list */ - nveu32_t llr; - /** data array 8 bit gate op + 24 execution time - * MGBE HW support GCL depth 256 */ - nveu32_t gcl[OSI_GCL_SIZE_256]; -}; - -/** - * @brief OSI Core FPE structure - */ -struct osi_fpe_config { - /** Queue Mask 1 preemption 0- express bit representation */ - nveu32_t tx_queue_preemption_enable; - /** RQ for all preemptable packets which are not filtered - * based on user priority or SA-DA - */ - nveu32_t rq; -}; - -/** - * @brief OSI Core TSN error stats structure - */ -struct osi_tsn_stats { - /** Constant Gate Control Error */ - nveu64_t const_gate_ctr_err; - /** Head-Of-Line Blocking due to Scheduling */ - nveu64_t head_of_line_blk_sch; - /** Per TC Schedule Error */ - nveu64_t hlbs_q[OSI_MAX_TC_NUM]; - /** Head-Of-Line Blocking due to Frame Size */ - nveu64_t head_of_line_blk_frm; - /** Per TC Frame Size Error */ - nveu64_t hlbf_q[OSI_MAX_TC_NUM]; - /** BTR Error */ - nveu64_t base_time_reg_err; - /** Switch to Software Owned List Complete */ - nveu64_t sw_own_list_complete; -}; - /** * @brief osi_core_rss - Struture used to store RSS Hash key and table * information. @@ -1073,7 +872,6 @@ struct osi_ptp_config { nveu32_t ptp_rx_queue; }; - /** * @brief osi_core_ptp_tsc_data - Struture used to store TSC and PTP time * information. @@ -1089,7 +887,6 @@ struct osi_core_ptp_tsc_data { nveu32_t tsc_low_bits; }; - /** * @brief OSI VM IRQ data */ @@ -1223,6 +1020,40 @@ struct osi_macsec_irq_stats { }; #endif /* MACSEC_SUPPORT */ +/** + * @brief FRP Instruction configuration structure + */ +struct osi_core_frp_data { + /** Entry Match Data */ + nveu32_t match_data; + /** Entry Match Enable mask */ + nveu32_t match_en; + /** Entry Accept frame flag */ + nveu8_t accept_frame; + /** Entry Reject Frame flag */ + nveu8_t reject_frame; + /** Entry Inverse match flag */ + nveu8_t inverse_match; + /** Entry Next Instruction Control match flag */ + nveu8_t next_ins_ctrl; + /** Entry Frame offset in the packet data */ + nveu8_t frame_offset; + /** Entry OK Index - Next Instruction */ + nveu8_t ok_index; + /** Entry DMA Channel selection (1-bit for each channel) */ + nveu32_t dma_chsel; +}; + +/** + * @brief FRP Instruction table entry configuration structure + */ +struct osi_core_frp_entry { + /** FRP ID */ + nve32_t frp_id; + /** FRP Entry data structure */ + struct osi_core_frp_data data; +}; + /** * @brief Core time stamp data strcuture */ @@ -1269,22 +1100,22 @@ struct osi_ioctl { struct osi_l3_l4_filter l3l4_filter; /* HW feature structure */ struct osi_hw_features hw_feat; -#ifndef OSI_STRIPPED_LIB - /* AVB structure */ + /** AVB structure */ struct osi_core_avb_algorithm avb; - /* VLAN filter structure */ +#ifndef OSI_STRIPPED_LIB + /** VLAN filter structure */ struct osi_vlan_filter vlan_filter; - /* PTP offload config structure*/ + /** PTP offload config structure*/ struct osi_pto_config pto_config; - /* FRP structure */ - struct osi_core_frp_cmd frp_cmd; - /* EST structure */ - struct osi_est_config est; - /* FRP structure */ - struct osi_fpe_config fpe; - /* RXQ route structure */ + /** RXQ route structure */ struct osi_rxq_route rxq_route; #endif /* !OSI_STRIPPED_LIB */ + /** 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 */ @@ -1451,19 +1282,29 @@ struct osi_core_priv_data { struct osi_xtra_stat_counters xstats; /** Memory mapped base address of HV window */ void *hv_base; - /** Residual queue valid with FPE support */ - nveu32_t residual_queue; /** 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; + /** csr clock is to program LPI 1 us tick timer register. + * Value stored in MHz + */ + nveu32_t csr_clk_speed; + nveu64_t vf_bitmap; + /** Array to maintain VLAN filters */ + nveu16_t vid[VLAN_NUM_VID]; + /** Count of number of VLAN filters in vid array */ + nveu16_t vlan_filter_cnt; + /** RSS core structure */ + struct osi_core_rss rss; +#endif + /** Residual queue valid with FPE support */ + nveu32_t residual_queue; /** FRP Instruction Table */ struct osi_core_frp_entry frp_table[OSI_FRP_MAX_ENTRY]; /** Number of valid Entries in the FRP Instruction Table */ nveu32_t frp_cnt; - /** RSS core structure */ - struct osi_core_rss rss; /* Switch to Software Owned List Complete. * 1 - Successful and User configured GCL in placed */ @@ -1474,16 +1315,6 @@ struct osi_core_priv_data { nveu32_t fpe_ready; /** TSN stats counters */ struct osi_tsn_stats tsn_stats; - /** csr clock is to program LPI 1 us tick timer register. - * Value stored in MHz - */ - nveu32_t csr_clk_speed; - nveu64_t vf_bitmap; - /** Array to maintaion VLAN filters */ - nveu16_t vid[VLAN_NUM_VID]; - /** Count of number of VLAN filters in vid array */ - nveu16_t vlan_filter_cnt; -#endif /** eqos pad control structure */ struct core_padctrl padctrl; /** MDC clock rate */ diff --git a/osi/common/common.h b/osi/common/common.h index 3d37f14..5944292 100644 --- a/osi/common/common.h +++ b/osi/common/common.h @@ -49,7 +49,6 @@ */ #define MAX_MAC_IP_TYPES 2U -#ifndef OSI_STRIPPED_LIB /** * @brief osi_readl_poll_timeout - Periodically poll an address until * a condition is met or a timeout occurs @@ -67,9 +66,9 @@ */ #define osi_readl_poll_timeout(addr, fn, val, cond, delay_us, retry) \ ({ \ - unsigned int count = 0; \ + nveu32_t count = 0; \ while (count++ < retry) { \ - val = osi_readl((unsigned char *)addr); \ + val = osi_readl((nveu8_t *)addr); \ if ((cond)) { \ break; \ } \ @@ -77,7 +76,6 @@ } \ (cond) ? 0 : -1; \ }) -#endif /* !OSI_STRIPPED_LIB */ struct osi_core_priv_data; diff --git a/osi/core/core_common.c b/osi/core/core_common.c index 4d24ec5..c353206 100644 --- a/osi/core/core_common.c +++ b/osi/core/core_common.c @@ -462,7 +462,7 @@ nve32_t hw_ptp_tsc_capture(struct osi_core_priv_data *const osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "ptp_tsc: older IP\n", 0ULL); ret = -1; - goto exit; + goto done; } #endif /* !OSI_STRIPPED_LIB */ @@ -471,7 +471,7 @@ nve32_t hw_ptp_tsc_capture(struct osi_core_priv_data *const osi_core, ret = poll_check(osi_core, ((nveu8_t *)addr + WRAP_SYNC_TSC_PTP_CAPTURE), OSI_ENABLE, &tsc_ptp); if (ret == -1) { - goto exit; + goto done; } data->tsc_low_bits = osi_readla(osi_core, (nveu8_t *)osi_core->base + @@ -482,7 +482,7 @@ nve32_t hw_ptp_tsc_capture(struct osi_core_priv_data *const osi_core, WRAP_PTP_CAPTURE_LOW); data->ptp_high_bits = osi_readla(osi_core, (nveu8_t *)osi_core->base + WRAP_PTP_CAPTURE_HIGH); -exit: +done: return ret; } @@ -582,7 +582,6 @@ fail: return ret; } -#ifndef OSI_STRIPPED_LIB /** * @brief hw_est_read - indirect read the GCL to Software own list * (SWOL) @@ -611,8 +610,7 @@ static inline nve32_t hw_est_read(struct osi_core_priv_data *osi_core, 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}; + 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; @@ -659,11 +657,11 @@ err: * @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) +static 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 struct core_local *l_core = (struct core_local *)(void *)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, @@ -687,7 +685,7 @@ nve32_t gcl_validate(struct osi_core_priv_data *const osi_core, nveu32_t bunk = 0U; nveu32_t est_status; nveu64_t old_btr, old_ctr; - nve32_t ret; + nve32_t ret = 0; nveu32_t val = 0U; nveu64_t rem = 0U; const struct est_read hw_read_arr[4] = { @@ -700,7 +698,8 @@ nve32_t gcl_validate(struct osi_core_priv_data *const osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "input argument more than GCL depth\n", (nveul64_t)est->llr); - return -1; + ret = -1; + goto done; } ctr = ((nveu64_t)est->ctr[1] * OSI_NSEC_PER_SEC) + est->ctr[0]; @@ -713,12 +712,13 @@ nve32_t gcl_validate(struct osi_core_priv_data *const osi_core, ((ctr - sum_tin) >= PTP_CYCLE_8[mac])) { continue; } else if (((ctr - sum_ti) != 0U) && - ((ctr - sum_ti) < PTP_CYCLE_8[mac])) { + ((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; + ret = -1; + goto done; } else { //do nothing } @@ -729,16 +729,17 @@ nve32_t gcl_validate(struct osi_core_priv_data *const osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "validation of GCL entry failed\n", (nveul64_t)i); - return -1; + ret = -1; + goto done; } /* Check for BTR in case of new ETS while current GCL enabled */ - val = osi_readla(osi_core, - (nveu8_t *)osi_core->base + + 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; + ret = 0; + goto done; } /* Read EST_STATUS for bunk */ @@ -758,7 +759,7 @@ nve32_t gcl_validate(struct osi_core_priv_data *const osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Reading failed for index\n", (nveul64_t)i); - return ret; + goto done; } } @@ -769,19 +770,630 @@ nve32_t gcl_validate(struct osi_core_priv_data *const osi_core, 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; + ret = -1; + goto done; } } 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; + ret = -1; + goto done; } } else { // Nothing to do } - return 0; +done: + return ret; +} + +/** + * @brief 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 nve32_t hw_est_write(struct osi_core_priv_data *osi_core, + nveu32_t addr_val, nveu32_t data, + nveu32_t gcla) +{ + nve32_t retry = 1000; + nveu32_t val = 0x0; + nve32_t ret = 0; + const nveu32_t MTL_EST_DATA[MAX_MAC_IP_TYPES] = {EQOS_MTL_EST_DATA, + MGBE_MTL_EST_DATA}; + const nveu32_t MTL_EST_GCL_CONTROL[MAX_MAC_IP_TYPES] = {EQOS_MTL_EST_GCL_CONTROL, + MGBE_MTL_EST_GCL_CONTROL}; + + osi_writela(osi_core, data, (nveu8_t *)osi_core->base + + MTL_EST_DATA[osi_core->mac]); + + val &= ~MTL_EST_ADDR_MASK; + val |= (gcla == 1U) ? 0x0U : MTL_EST_GCRR; + val |= MTL_EST_SRWO; + val |= addr_val; + osi_writela(osi_core, val, (nveu8_t *)osi_core->base + + MTL_EST_GCL_CONTROL[osi_core->mac]); + + while (--retry > 0) { + val = osi_readla(osi_core, (nveu8_t *)osi_core->base + + MTL_EST_GCL_CONTROL[osi_core->mac]); + if ((val & MTL_EST_SRWO) == MTL_EST_SRWO) { + osi_core->osd_ops.udelay(OSI_DELAY_1US); + continue; + } + + break; + } + + if (((val & MTL_EST_ERR0) == MTL_EST_ERR0) || + (retry <= 0)) { + ret = -1; + } + + return ret; +} + +/** + * @brief 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. + */ +nve32_t hw_config_est(struct osi_core_priv_data *const osi_core, + struct osi_est_config *const est) +{ + nveu32_t btr[2] = {0}; + nveu32_t val = 0x0; + void *base = osi_core->base; + nveu32_t i; + nve32_t ret = 0; + nveu32_t addr = 0x0; + const nveu32_t MTL_EST_CONTROL[MAX_MAC_IP_TYPES] = {EQOS_MTL_EST_CONTROL, + MGBE_MTL_EST_CONTROL}; + 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}; + const nveu32_t MTL_EST_TER[MAX_MAC_IP_TYPES] = {EQOS_MTL_EST_TER, + MGBE_MTL_EST_TER}; + const nveu32_t MTL_EST_LLR[MAX_MAC_IP_TYPES] = {EQOS_MTL_EST_LLR, + MGBE_MTL_EST_LLR}; + + 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); + ret = -1; + goto done; + } + + if (est->en_dis == OSI_DISABLE) { + val = osi_readla(osi_core, (nveu8_t *)base + + MTL_EST_CONTROL[osi_core->mac]); + val &= ~MTL_EST_EEST; + osi_writela(osi_core, val, (nveu8_t *)base + + MTL_EST_CONTROL[osi_core->mac]); + + ret = 0; + } else { + 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); + ret = -1; + goto done; + } + + ret = hw_est_write(osi_core, MTL_EST_CTR_LOW[osi_core->mac], est->ctr[0], 0); + if (ret < 0) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "GCL CTR[0] failed\n", 0LL); + goto done; + } + /* 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] &= MTL_EST_CTR_HIGH_MAX; + ret = hw_est_write(osi_core, MTL_EST_CTR_HIGH[osi_core->mac], est->ctr[1], 0); + if (ret < 0) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "GCL CTR[1] failed\n", 0LL); + goto done; + } + + ret = hw_est_write(osi_core, MTL_EST_TER[osi_core->mac], est->ter, 0); + if (ret < 0) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "GCL TER failed\n", 0LL); + goto done; + } + + ret = hw_est_write(osi_core, MTL_EST_LLR[osi_core->mac], est->llr, 0); + if (ret < 0) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "GCL LLR failed\n", 0LL); + goto done; + } + + /* Write GCL table */ + for (i = 0U; i < est->llr; i++) { + addr = i; + addr = addr << MTL_EST_ADDR_SHIFT; + addr &= MTL_EST_ADDR_MASK; + ret = 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", + (nveul64_t)i); + goto done; + } + } + + /* Write parameters */ + ret = hw_est_write(osi_core, MTL_EST_BTR_LOW[osi_core->mac], + 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", + (btr[0] + est->btr_offset[0])); + goto done; + } + + ret = hw_est_write(osi_core, MTL_EST_BTR_HIGH[osi_core->mac], + 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", + (btr[1] + est->btr_offset[1])); + goto done; + } + + val = osi_readla(osi_core, (nveu8_t *)base + + MTL_EST_CONTROL[osi_core->mac]); + /* Store table */ + val |= MTL_EST_SSWL; + val |= MTL_EST_EEST; + val |= MTL_EST_QHLBF; + osi_writela(osi_core, val, (nveu8_t *)base + + MTL_EST_CONTROL[osi_core->mac]); + } +done: + return ret; +} + +/** + * @brief hw_config_fpe - 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. + */ +nve32_t hw_config_fpe(struct osi_core_priv_data *const osi_core, + struct osi_fpe_config *const fpe) +{ + nveu32_t i = 0U; + nveu32_t val = 0U; + nveu32_t temp = 0U, temp1 = 0U; + nveu32_t temp_shift = 0U; + nve32_t ret = 0; + const nveu32_t MTL_FPE_CTS[MAX_MAC_IP_TYPES] = {EQOS_MTL_FPE_CTS, + MGBE_MTL_FPE_CTS}; + const nveu32_t MAC_FPE_CTS[MAX_MAC_IP_TYPES] = {EQOS_MAC_FPE_CTS, + MGBE_MAC_FPE_CTS}; + const nveu32_t max_number_queue[MAX_MAC_IP_TYPES] = {OSI_EQOS_MAX_NUM_QUEUES, + OSI_MGBE_MAX_NUM_QUEUES}; + const nveu32_t MAC_RQC1R[MAX_MAC_IP_TYPES] = {EQOS_MAC_RQC1R, + MGBE_MAC_RQC1R}; + const nveu32_t MAC_RQC1R_RQ[MAX_MAC_IP_TYPES] = {EQOS_MAC_RQC1R_FPRQ, + MGBE_MAC_RQC1R_RQ}; + const nveu32_t MAC_RQC1R_RQ_SHIFT[MAX_MAC_IP_TYPES] = {EQOS_MAC_RQC1R_FPRQ_SHIFT, + MGBE_MAC_RQC1R_RQ_SHIFT}; + const nveu32_t MTL_FPE_ADV[MAX_MAC_IP_TYPES] = {EQOS_MTL_FPE_ADV, + MGBE_MTL_FPE_ADV}; + + 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); + ret = -1; + goto error; + } + + if (osi_core->mac == OSI_MAC_HW_MGBE) { +#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 done; + } +#endif /* MACSEC_SUPPORT */ + } + + osi_core->fpe_ready = OSI_DISABLE; + + if (((fpe->tx_queue_preemption_enable << MTL_FPE_CTS_PEC_SHIFT) & + MTL_FPE_CTS_PEC) == OSI_DISABLE) { + val = osi_readla(osi_core, (nveu8_t *)osi_core->base + + MTL_FPE_CTS[osi_core->mac]); + val &= ~MTL_FPE_CTS_PEC; + osi_writela(osi_core, val, (nveu8_t *)osi_core->base + + MTL_FPE_CTS[osi_core->mac]); + + val = osi_readla(osi_core, (nveu8_t *)osi_core->base + + MAC_FPE_CTS[osi_core->mac]); + val &= ~MAC_FPE_CTS_EFPE; + osi_writela(osi_core, val, (nveu8_t *)osi_core->base + + MAC_FPE_CTS[osi_core->mac]); + + if (osi_core->mac == OSI_MAC_HW_MGBE) { +#ifdef MACSEC_SUPPORT + osi_core->is_fpe_enabled = OSI_DISABLE; +#endif /* MACSEC_SUPPORT */ + } + ret = 0; + } else { + val = osi_readla(osi_core, (nveu8_t *)osi_core->base + + MTL_FPE_CTS[osi_core->mac]); + val &= ~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 += MTL_FPE_CTS_PEC_SHIFT; + /* set queue for preemtable */ + if (temp_shift < 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 + + MTL_FPE_CTS[osi_core->mac]); + + if ((fpe->rq == 0x0U) || (fpe->rq >= max_number_queue[osi_core->mac])) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "FPE init failed due to wrong RQ\n", fpe->rq); + ret = -1; + goto done; + } + + val = osi_readla(osi_core, (nveu8_t *)osi_core->base + + MAC_RQC1R[osi_core->mac]); + val &= ~MAC_RQC1R_RQ[osi_core->mac]; + temp = fpe->rq; + temp = temp << MAC_RQC1R_RQ_SHIFT[osi_core->mac]; + temp = (temp & MAC_RQC1R_RQ[osi_core->mac]); + val |= temp; + osi_core->residual_queue = fpe->rq; + osi_writela(osi_core, val, (nveu8_t *)osi_core->base + + MAC_RQC1R[osi_core->mac]); + + if (osi_core->mac == OSI_MAC_HW_MGBE) { + 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, (nveu8_t *)osi_core->base + + MTL_FPE_CTS[osi_core->mac]); + val |= MAC_FPE_CTS_SVER; + osi_writela(osi_core, val, (nveu8_t *)osi_core->base + + MAC_FPE_CTS[osi_core->mac]); + + val = osi_readla(osi_core, (nveu8_t *)osi_core->base + + MTL_FPE_ADV[osi_core->mac]); + val &= ~MTL_FPE_ADV_HADV_MASK; + //(minimum_fragment_size +IPG/EIPG + Preamble) *.8 ~98ns for10G + val |= MTL_FPE_ADV_HADV_VAL; + osi_writela(osi_core, val, (nveu8_t *)osi_core->base + + MTL_FPE_ADV[osi_core->mac]); + + if (osi_core->mac == OSI_MAC_HW_MGBE) { +#ifdef MACSEC_SUPPORT + osi_core->is_fpe_enabled = OSI_ENABLE; +#endif /* MACSEC_SUPPORT */ + } + } +done: + + if (osi_core->mac == OSI_MAC_HW_MGBE) { +#ifdef MACSEC_SUPPORT + osi_unlock_irq_enabled(&osi_core->macsec_fpe_lock); +#endif /* MACSEC_SUPPORT */ + } + +error: + return ret; +} + +/** + * @brief 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 enable_mtl_interrupts(struct osi_core_priv_data *osi_core) +{ + nveu32_t mtl_est_ir = OSI_DISABLE; + const nveu32_t MTL_EST_ITRE[MAX_MAC_IP_TYPES] = {EQOS_MTL_EST_ITRE, + MGBE_MTL_EST_ITRE}; + + mtl_est_ir = osi_readla(osi_core, (nveu8_t *)osi_core->base + + MTL_EST_ITRE[osi_core->mac]); + /* 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 |= (MTL_EST_ITRE_CGCE | MTL_EST_ITRE_IEHS | + MTL_EST_ITRE_IEHF | MTL_EST_ITRE_IEBE | + MTL_EST_ITRE_IECC); + osi_writela(osi_core, mtl_est_ir, (nveu8_t *)osi_core->base + + MTL_EST_ITRE[osi_core->mac]); +} + +/** + * @brief 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 enable_fpe_interrupts(struct osi_core_priv_data *osi_core) +{ + nveu32_t value = OSI_DISABLE; + const nveu32_t MAC_IER[MAX_MAC_IP_TYPES] = {EQOS_MAC_IMR, + MGBE_MAC_IER}; + const nveu32_t IMR_FPEIE[MAX_MAC_IP_TYPES] = {EQOS_IMR_FPEIE, + MGBE_IMR_FPEIE}; + + /* Read MAC IER Register and enable Frame Preemption Interrupt + * Enable */ + value = osi_readla(osi_core, (nveu8_t *)osi_core->base + + MAC_IER[osi_core->mac]); + value |= IMR_FPEIE[osi_core->mac]; + osi_writela(osi_core, value, (nveu8_t *)osi_core->base + + MAC_IER[osi_core->mac]); +} + +/** + * @brief 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 save_gcl_params(struct osi_core_priv_data *osi_core) +{ + struct core_local *l_core = (struct core_local *)(void *)osi_core; + const nveu32_t gcl_widhth[4] = {0, OSI_MAX_24BITS, OSI_MAX_28BITS, + OSI_MAX_32BITS}; + const nveu32_t gcl_ti_mask[4] = {0, OSI_MASK_16BITS, OSI_MASK_20BITS, + OSI_MASK_24BITS}; + const nveu32_t 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 == 0U) || + (osi_core->hw_feature->gcl_width > 3U)) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "Wrong HW feature GCL width\n", + (nveul64_t)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 == 0U) || + (osi_core->hw_feature->gcl_depth > 5U)) { + /* Do Nothing */ + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "Wrong HW feature GCL depth\n", + (nveul64_t)osi_core->hw_feature->gcl_depth); + } else { + l_core->gcl_dep = gcl_depthth[osi_core->hw_feature->gcl_depth]; + } +} + +/** + * @brief hw_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() + */ +void hw_tsn_init(struct osi_core_priv_data *osi_core, + nveu32_t est_sel, nveu32_t fpe_sel) +{ + nveu32_t val = 0x0; + nveu32_t temp = 0U; + const nveu32_t MTL_EST_CONTROL[MAX_MAC_IP_TYPES] = {EQOS_MTL_EST_CONTROL, + MGBE_MTL_EST_CONTROL}; + const nveu32_t MTL_EST_CONTROL_PTOV[MAX_MAC_IP_TYPES] = {EQOS_MTL_EST_CONTROL_PTOV, + MGBE_MTL_EST_CONTROL_PTOV}; + const nveu32_t MTL_EST_PTOV_RECOMMEND[MAX_MAC_IP_TYPES] = {EQOS_MTL_EST_PTOV_RECOMMEND, + MGBE_MTL_EST_PTOV_RECOMMEND}; + const nveu32_t MTL_EST_CONTROL_PTOV_SHIFT[MAX_MAC_IP_TYPES] = {EQOS_MTL_EST_CONTROL_PTOV_SHIFT, + MGBE_MTL_EST_CONTROL_PTOV_SHIFT}; + const nveu32_t MTL_EST_CONTROL_CTOV[MAX_MAC_IP_TYPES] = {EQOS_MTL_EST_CONTROL_CTOV, + MGBE_MTL_EST_CONTROL_CTOV}; + const nveu32_t MTL_EST_CTOV_RECOMMEND[MAX_MAC_IP_TYPES] = {EQOS_MTL_EST_CTOV_RECOMMEND, + MGBE_MTL_EST_CTOV_RECOMMEND}; + const nveu32_t MTL_EST_CONTROL_CTOV_SHIFT[MAX_MAC_IP_TYPES] = {EQOS_MTL_EST_CONTROL_CTOV_SHIFT, + MGBE_MTL_EST_CONTROL_CTOV_SHIFT}; + const nveu32_t MTL_EST_CONTROL_LCSE[MAX_MAC_IP_TYPES] = {EQOS_MTL_EST_CONTROL_LCSE, + MGBE_MTL_EST_CONTROL_LCSE}; + const nveu32_t MTL_EST_CONTROL_LCSE_VAL[MAX_MAC_IP_TYPES] = {EQOS_MTL_EST_CONTROL_LCSE_VAL, + MGBE_MTL_EST_CONTROL_LCSE_VAL}; + const nveu32_t MTL_EST_CONTROL_DDBF[MAX_MAC_IP_TYPES] = {EQOS_MTL_EST_CONTROL_DDBF, + MGBE_MTL_EST_CONTROL_DDBF}; + const nveu32_t MTL_EST_OVERHEAD[MAX_MAC_IP_TYPES] = {EQOS_MTL_EST_OVERHEAD, + MGBE_MTL_EST_OVERHEAD}; + const nveu32_t MTL_EST_OVERHEAD_OVHD[MAX_MAC_IP_TYPES] = {EQOS_MTL_EST_OVERHEAD_OVHD, + MGBE_MTL_EST_OVERHEAD_OVHD}; + const nveu32_t MTL_EST_OVERHEAD_RECOMMEND[MAX_MAC_IP_TYPES] = {EQOS_MTL_EST_OVERHEAD_RECOMMEND, + MGBE_MTL_EST_OVERHEAD_RECOMMEND}; + const nveu32_t MAC_RQC1R[MAX_MAC_IP_TYPES] = {EQOS_MAC_RQC1R, + MGBE_MAC_RQC1R}; + const nveu32_t MAC_RQC1R_RQ[MAX_MAC_IP_TYPES] = {EQOS_MAC_RQC1R_FPRQ, + MGBE_MAC_RQC1R_RQ}; + const nveu32_t MAC_RQC1R_RQ_SHIFT[MAX_MAC_IP_TYPES] = {EQOS_MAC_RQC1R_FPRQ_SHIFT, + MGBE_MAC_RQC1R_RQ_SHIFT}; + + if (est_sel == OSI_ENABLE) { + save_gcl_params(osi_core); + val = osi_readla(osi_core, (nveu8_t *)osi_core->base + + MTL_EST_CONTROL[osi_core->mac]); + + /* + * 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 &= ~MTL_EST_CONTROL_PTOV[osi_core->mac]; + temp = MTL_EST_PTOV_RECOMMEND[osi_core->mac]; + temp = temp << MTL_EST_CONTROL_PTOV_SHIFT[osi_core->mac]; + val |= temp; + + val &= ~MTL_EST_CONTROL_CTOV[osi_core->mac]; + temp = MTL_EST_CTOV_RECOMMEND[osi_core->mac]; + temp = temp << MTL_EST_CONTROL_CTOV_SHIFT[osi_core->mac]; + val |= temp; + + /*Loop Count to report Scheduling Error*/ + val &= ~MTL_EST_CONTROL_LCSE[osi_core->mac]; + val |= MTL_EST_CONTROL_LCSE_VAL[osi_core->mac]; + + if (osi_core->mac == OSI_MAC_HW_EQOS) { + val &= ~EQOS_MTL_EST_CONTROL_DFBS; + } + val &= ~MTL_EST_CONTROL_DDBF[osi_core->mac]; + val |= MTL_EST_CONTROL_DDBF[osi_core->mac]; + osi_writela(osi_core, val, (nveu8_t *)osi_core->base + + MTL_EST_CONTROL[osi_core->mac]); + + val = osi_readla(osi_core, (nveu8_t *)osi_core->base + + MTL_EST_OVERHEAD[osi_core->mac]); + val &= ~MTL_EST_OVERHEAD_OVHD[osi_core->mac]; + /* As per hardware programming info */ + val |= MTL_EST_OVERHEAD_RECOMMEND[osi_core->mac]; + osi_writela(osi_core, val, (nveu8_t *)osi_core->base + + MTL_EST_OVERHEAD[osi_core->mac]); + + enable_mtl_interrupts(osi_core); + } + + if (fpe_sel == OSI_ENABLE) { + val = osi_readla(osi_core, (nveu8_t *)osi_core->base + + MAC_RQC1R[osi_core->mac]); + val &= ~MAC_RQC1R_RQ[osi_core->mac]; + temp = osi_core->residual_queue; + temp = temp << MAC_RQC1R_RQ_SHIFT[osi_core->mac]; + temp = (temp & MAC_RQC1R_RQ[osi_core->mac]); + val |= temp; + osi_writela(osi_core, val, (nveu8_t *)osi_core->base + + MAC_RQC1R[osi_core->mac]); + + if (osi_core->mac == OSI_MAC_HW_MGBE) { + 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); + } + + 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 + */ } -#endif /* !OSI_STRIPPED_LIB */ diff --git a/osi/core/core_common.h b/osi/core/core_common.h index 8d1f6ea..cd281d9 100644 --- a/osi/core/core_common.h +++ b/osi/core/core_common.h @@ -24,9 +24,8 @@ #define INCLUDED_CORE_COMMON_H #include "core_local.h" - -#ifndef OSI_STRIPPED_LIB #define MAC_TCR_TSCTRLSSR OSI_BIT(9) +#define MTL_EST_ADDR_SHIFT 8 #define MTL_EST_ADDR_MASK (OSI_BIT(8) | OSI_BIT(9) | \ OSI_BIT(10) | OSI_BIT(11) | \ OSI_BIT(12) | OSI_BIT(13) | \ @@ -42,8 +41,28 @@ #define MTL_EST_CONTROL_EEST OSI_BIT(0) #define MTL_EST_STATUS_SWOL OSI_BIT(7) #define MAC_TCR_TSCFUPDT OSI_BIT(1) -#endif /* !OSI_STRIPPED_LIB */ - +/* EST control OSI_BIT map */ +#define MTL_EST_EEST OSI_BIT(0) +#define MTL_EST_SSWL OSI_BIT(1) +#define MTL_EST_QHLBF OSI_BIT(3) +#define MTL_EST_CTR_HIGH_MAX 0xFFU +#define MTL_EST_ITRE_CGCE OSI_BIT(4) +#define MTL_EST_ITRE_IEHS OSI_BIT(3) +#define MTL_EST_ITRE_IEHF OSI_BIT(2) +#define MTL_EST_ITRE_IEBE OSI_BIT(1) +#define MTL_EST_ITRE_IECC OSI_BIT(0) +/* MTL_FPE_CTRL_STS */ +#define 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 MTL_FPE_CTS_PEC_SHIFT 8U +#define MTL_FPE_CTS_PEC_MAX_SHIFT 16U +#define MAC_FPE_CTS_EFPE OSI_BIT(0) +#define MAC_FPE_CTS_SVER OSI_BIT(1) +/* MTL FPE adv registers */ +#define MTL_FPE_ADV_HADV_MASK (0xFFFFU) +#define MTL_FPE_ADV_HADV_VAL 100U #define DMA_MODE_SWR OSI_BIT(0) #define MTL_QTOMR_FTQ OSI_BIT(0) #define MTL_RXQ_OP_MODE_FEP OSI_BIT(4) @@ -74,7 +93,6 @@ #define MAC_PKT_FILTER_REG 0x0008 -#ifndef OSI_STRIPPED_LIB /** * @addtogroup typedef related info * @@ -83,18 +101,14 @@ */ struct est_read { - /* variable pointer */ + /** variable pointer */ nveu32_t *var; - /* memory register/address offset */ + /** 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 /* !OSI_STRIPPED_LIB */ nve32_t hw_poll_for_swr(struct osi_core_priv_data *const osi_core); void hw_start_mac(struct osi_core_priv_data *const osi_core); void hw_stop_mac(struct osi_core_priv_data *const osi_core); @@ -118,4 +132,10 @@ nve32_t hw_config_mac_pkt_filter_reg(struct osi_core_priv_data *const osi_core, const struct osi_filter *filter); nve32_t hw_config_l3_l4_filter_enable(struct osi_core_priv_data *const osi_core, const nveu32_t filter_enb_dis); +nve32_t hw_config_est(struct osi_core_priv_data *const osi_core, + struct osi_est_config *const est); +nve32_t hw_config_fpe(struct osi_core_priv_data *const osi_core, + struct osi_fpe_config *const fpe); +void hw_tsn_init(struct osi_core_priv_data *osi_core, + nveu32_t est_sel, nveu32_t fpe_sel); #endif /* INCLUDED_CORE_COMMON_H */ diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 249d3cb..e069a5d 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -47,29 +47,30 @@ * @brief Dynamic configuration helper macros. */ #define DYNAMIC_CFG_L3_L4 OSI_BIT(0) -#define DYNAMIC_CFG_L3_L4_IDX 0U +#define DYNAMIC_CFG_AVB OSI_BIT(2) #define DYNAMIC_CFG_L2 OSI_BIT(3) #define DYNAMIC_CFG_L2_IDX 3U #define DYNAMIC_CFG_RXCSUM OSI_BIT(4) -#define DYNAMIC_CFG_RXCSUM_IDX 4U #define DYNAMIC_CFG_PTP OSI_BIT(7) -#define DYNAMIC_CFG_PTP_IDX 7U - -#ifndef OSI_STRIPPED_LIB -#define DYNAMIC_CFG_FC OSI_BIT(1) -#define DYNAMIC_CFG_AVB OSI_BIT(2) -#define DYNAMIC_CFG_VLAN OSI_BIT(5) -#define DYNAMIC_CFG_EEE OSI_BIT(6) #define DYNAMIC_CFG_EST OSI_BIT(8) #define DYNAMIC_CFG_FPE OSI_BIT(9) +#ifndef OSI_STRIPPED_LIB +#define DYNAMIC_CFG_FC OSI_BIT(1) +#define DYNAMIC_CFG_VLAN OSI_BIT(5) +#define DYNAMIC_CFG_EEE OSI_BIT(6) #define DYNAMIC_CFG_FC_IDX 1U -#define DYNAMIC_CFG_AVB_IDX 2U #define DYNAMIC_CFG_VLAN_IDX 5U #define DYNAMIC_CFG_EEE_IDX 6U +#endif /* !OSI_STRIPPED_LIB */ + +#define DYNAMIC_CFG_L3_L4_IDX 0U +#define DYNAMIC_CFG_AVB_IDX 2U +#define DYNAMIC_CFG_L2_IDX 3U +#define DYNAMIC_CFG_RXCSUM_IDX 4U +#define DYNAMIC_CFG_PTP_IDX 7U #define DYNAMIC_CFG_EST_IDX 8U #define DYNAMIC_CFG_FPE_IDX 9U -#endif /* !OSI_STRIPPED_LIB */ #define OSI_SUSPENDED OSI_BIT(0) @@ -210,13 +211,6 @@ struct core_ops { /** 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 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 VLAN filtering */ nve32_t (*config_vlan_filtering)( struct osi_core_priv_data *const osi_core, @@ -240,22 +234,6 @@ struct core_ops { nve32_t (*config_mac_loopback)( struct osi_core_priv_data *const osi_core, const nveu32_t lb_mode); - /** Called to update GCL config */ - nve32_t (*hw_config_est)(struct osi_core_priv_data *const osi_core, - struct osi_est_config *const est); - /** Called to update FPE config */ - nve32_t (*hw_config_fpe)(struct osi_core_priv_data *const osi_core, - struct osi_fpe_config *const fpe); - /** Called to configure FRP engine */ - nve32_t (*config_frp)(struct osi_core_priv_data *const osi_core, - const nveu32_t enabled); - /** Called to update FRP Instruction Table entry */ - nve32_t (*update_frp_entry)(struct osi_core_priv_data *const osi_core, - const nveu32_t pos, - struct osi_core_frp_data *const data); - /** Called to update FRP NVE and */ - nve32_t (*update_frp_nve)(struct osi_core_priv_data *const osi_core, - const nveu32_t nve); /** Called to configure RSS for MAC */ nve32_t (*config_rss)(struct osi_core_priv_data *osi_core); /** Called to configure the PTP RX packets Queue */ @@ -263,6 +241,22 @@ struct core_ops { const nveu32_t rxq_idx, const nveu32_t enable); #endif /* !OSI_STRIPPED_LIB */ + /** 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 FRP engine */ + nve32_t (*config_frp)(struct osi_core_priv_data *const osi_core, + const nveu32_t enabled); + /** Called to update FRP Instruction Table entry */ + nve32_t (*update_frp_entry)(struct osi_core_priv_data *const osi_core, + const nveu32_t pos, + struct osi_core_frp_data *const data); + /** Called to update FRP NVE and */ + nve32_t (*update_frp_nve)(struct osi_core_priv_data *const osi_core, + const nveu32_t nve); #ifdef HSI_SUPPORT /** Interface function called to initialize HSI */ nve32_t (*core_hsi_configure)(struct osi_core_priv_data *const osi_core, @@ -332,7 +326,6 @@ struct l3_l4_filters { struct osi_l3_l4_filter l3l4_filter; }; -#ifndef OSI_STRIPPED_LIB /** * @brief AVB dynamic config storage structure */ @@ -342,7 +335,6 @@ struct core_avb { /** AVB data structure */ struct osi_core_avb_algorithm avb_info; }; -#endif /* !OSI_STRIPPED_LIB */ /** * @brief VLAN dynamic config storage structure @@ -371,10 +363,8 @@ struct dynamic_cfg { struct l3_l4_filters l3_l4[OSI_MGBE_MAX_L3_L4_FILTER]; /** flow control */ nveu32_t flow_ctrl; -#ifndef OSI_STRIPPED_LIB /** AVB */ struct core_avb avb[OSI_MGBE_MAX_NUM_QUEUES]; -#endif /* !OSI_STRIPPED_LIB */ /** RXCSUM */ nveu32_t rxcsum; /** VLAN arguments storage */ @@ -384,12 +374,10 @@ struct dynamic_cfg { nveu32_t tx_lpi_timer; /** PTP information storage */ nveu32_t ptp; -#ifndef OSI_STRIPPED_LIB /** EST information storage */ struct osi_est_config est; /** FPE information storage */ struct osi_fpe_config fpe; -#endif /* !OSI_STRIPPED_LIB */ /** L2 filter storage */ struct osi_filter l2_filter; /** L2 filter configuration */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 38a3bc4..df7a0c8 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -917,7 +917,6 @@ static nve32_t eqos_configure_mtl_queue(nveu32_t qinx, } /** \endcond */ -#ifndef OSI_STRIPPED_LIB /** * @brief eqos_config_frp - Enable/Disale RX Flexible Receive Parser in HW * @@ -935,7 +934,7 @@ static nve32_t eqos_configure_mtl_queue(nveu32_t qinx, * @retval -1 on failure. */ static nve32_t eqos_config_frp(struct osi_core_priv_data *const osi_core, - const nveu32_t enabled) + const nveu32_t enabled) { nveu8_t *base = osi_core->base; nveu32_t op_mode = 0U, val = 0U; @@ -945,7 +944,8 @@ static nve32_t eqos_config_frp(struct osi_core_priv_data *const osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid enable input\n", enabled); - return -1; + ret = -1; + goto done; } /* Disable RE */ @@ -1000,6 +1000,7 @@ frp_enable_re: val |= EQOS_MCR_RE; osi_writela(osi_core, val, base + EQOS_MAC_MCR); +done: return ret; } @@ -1017,17 +1018,18 @@ frp_enable_re: * @retval -1 on failure. */ static nve32_t eqos_update_frp_nve(struct osi_core_priv_data *const osi_core, - const nveu32_t nve) + const nveu32_t nve) { nveu32_t val; nveu8_t *base = osi_core->base; + nve32_t ret = -1; /* 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; + goto done; } /* Update NVE and NPE in MTL_RXP_Control_Status register */ @@ -1039,7 +1041,10 @@ static nve32_t eqos_update_frp_nve(struct osi_core_priv_data *const osi_core, 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; + ret = 0; + +done: + return ret; } /** @@ -1057,8 +1062,8 @@ static nve32_t eqos_update_frp_nve(struct osi_core_priv_data *const osi_core, * @retval -1 on failure. */ static nve32_t eqos_frp_write(struct osi_core_priv_data *osi_core, - nveu32_t addr, - nveu32_t data) + nveu32_t addr, + nveu32_t data) { nve32_t ret = 0; nveu8_t *base = osi_core->base; @@ -1076,7 +1081,8 @@ static nve32_t eqos_frp_write(struct osi_core_priv_data *osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Fail to write\n", val); - return -1; + ret = -1; + goto done; } /* Write data into MTL_RXP_Indirect_Acc_Data */ @@ -1105,9 +1111,10 @@ static nve32_t eqos_frp_write(struct osi_core_priv_data *osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Fail to write\n", val); - return -1; + ret = -1; } +done: return ret; } @@ -1126,8 +1133,8 @@ static nve32_t eqos_frp_write(struct osi_core_priv_data *osi_core, * @retval -1 on failure. */ static nve32_t eqos_update_frp_entry(struct osi_core_priv_data *const osi_core, - const nveu32_t pos, - struct osi_core_frp_data *const data) + const nveu32_t pos, + struct osi_core_frp_data *const data) { nveu32_t val = 0U, tmp = 0U; nve32_t ret = -1; @@ -1137,7 +1144,8 @@ static nve32_t eqos_update_frp_entry(struct osi_core_priv_data *const osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid FRP table entry\n", pos); - return -1; + ret = -1; + goto done; } /** Write Match Data into IE0 **/ @@ -1145,7 +1153,8 @@ static nve32_t eqos_update_frp_entry(struct osi_core_priv_data *const osi_core, ret = eqos_frp_write(osi_core, EQOS_MTL_FRP_IE0(pos), val); if (ret < 0) { /* Match Data Write fail */ - return -1; + ret = -1; + goto done; } /** Write Match Enable into IE1 **/ @@ -1153,7 +1162,8 @@ static nve32_t eqos_update_frp_entry(struct osi_core_priv_data *const osi_core, ret = eqos_frp_write(osi_core, EQOS_MTL_FRP_IE1(pos), val); if (ret < 0) { /* Match Enable Write fail */ - return -1; + ret = -1; + goto done; } /** Write AF, RF, IM, NIC, FO and OKI into IE2 **/ @@ -1183,7 +1193,8 @@ static nve32_t eqos_update_frp_entry(struct osi_core_priv_data *const osi_core, ret = eqos_frp_write(osi_core, EQOS_MTL_FRP_IE2(pos), val); if (ret < 0) { /* FRP IE2 Write fail */ - return -1; + ret = -1; + goto done; } /** Write DCH into IE3 **/ @@ -1191,12 +1202,12 @@ static nve32_t eqos_update_frp_entry(struct osi_core_priv_data *const osi_core, ret = eqos_frp_write(osi_core, EQOS_MTL_FRP_IE3(pos), val); if (ret < 0) { /* DCH Write fail */ - return -1; + ret = -1; } +done: return ret; } -#endif /* !OSI_STRIPPED_LIB */ /** \cond DO_NOT_DOCUMENT */ /** @@ -1411,6 +1422,7 @@ static nve32_t eqos_hsi_configure(struct osi_core_priv_data *const osi_core, return 0; } #endif + /** * @brief eqos_configure_mac - Configure MAC * @@ -1625,188 +1637,6 @@ static void eqos_configure_dma(struct osi_core_priv_data *const osi_core) } /** \endcond */ -#ifndef OSI_STRIPPED_LIB -/** - * @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) -{ - nveu32_t mtl_est_ir = OSI_DISABLE; - void *addr = osi_core->base; - - mtl_est_ir = osi_readla(osi_core, (nveu8_t *) - 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, - (nveu8_t *)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) -{ - nveu32_t value = OSI_DISABLE; - void *addr = osi_core->base; - - /* Read MAC IER Register and enable Frame Preemption Interrupt - * Enable */ - value = osi_readla(osi_core, (nveu8_t *)addr + EQOS_MAC_IMR); - value |= EQOS_IMR_FPEIE; - osi_writela(osi_core, value, (nveu8_t *)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; - nveu32_t 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}; - nveu32_t 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 == 0U) || - (osi_core->hw_feature->gcl_width > 3U)) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Wrong HW feature GCL width\n", - (nveul64_t)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 == 0U) || - (osi_core->hw_feature->gcl_depth > 5U)) { - /* Do Nothing */ - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Wrong HW feature GCL depth\n", - (nveul64_t)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, - nveu32_t est_sel, nveu32_t fpe_sel) -{ - nveu32_t val = 0x0; - nveu32_t temp = 0U; - - if (est_sel == OSI_ENABLE) { - eqos_save_gcl_params(osi_core); - val = osi_readla(osi_core, (nveu8_t *)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; - 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, (nveu8_t *)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, (nveu8_t *)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 */ -} -#endif /* !OSI_STRIPPED_LIB */ - /** * @brief Map DMA channels to a specific VM IRQ. * @@ -1990,13 +1820,11 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core, /* configure EQOS DMA */ eqos_configure_dma(osi_core); -#ifndef OSI_STRIPPED_LIB /* 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); + hw_tsn_init(osi_core, osi_core->hw_feature->est_sel, + osi_core->hw_feature->fpe_sel); } -#endif /* !OSI_STRIPPED_LIB */ /* initialize L3L4 Filters variable */ osi_core->l3l4_filter_bitmask = OSI_NONE; @@ -2006,7 +1834,6 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core, return ret; } -#ifndef OSI_STRIPPED_LIB /** * @brief eqos_handle_mac_fpe_intrs * @@ -2059,7 +1886,6 @@ static void eqos_handle_mac_fpe_intrs(struct osi_core_priv_data *osi_core) osi_writela(osi_core, val, (nveu8_t *)osi_core->base + EQOS_MAC_FPE_CTS); } -#endif /* !OSI_STRIPPED_LIB */ /** * @brief eqos_handle_mac_intrs - Handle MAC interrupts @@ -2136,12 +1962,10 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, return; } -#ifndef OSI_STRIPPED_LIB 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); } -#endif /* !OSI_STRIPPED_LIB */ mac_pcs = osi_readla(osi_core, (nveu8_t *)osi_core->base + EQOS_MAC_PCS); @@ -2239,6 +2063,7 @@ static inline void update_dma_sr_stats( } } /** \endcond */ +#endif /* !OSI_STRIPPED_LIB */ /** * @brief eqos_handle_mtl_intrs - Handle MTL interrupts @@ -2263,7 +2088,7 @@ static void eqos_handle_mtl_intrs(struct osi_core_priv_data *osi_core) nveu32_t frm_err = 0U; nveu32_t temp = 0U; nveu32_t i = 0; - nveu64_t stat_val = 0U; + nveul64_t stat_val = 0U; nveu32_t value = 0U; val = osi_readla(osi_core, @@ -2274,7 +2099,7 @@ static void eqos_handle_mtl_intrs(struct osi_core_priv_data *osi_core) /* return if interrupt is not related to EST */ if (val == OSI_DISABLE) { - return; + goto done; } /* increase counter write 1 back will clear */ @@ -2374,8 +2199,10 @@ static void eqos_handle_mtl_intrs(struct osi_core_priv_data *osi_core) /* clear EST status register as interrupt is handled */ osi_writela(osi_core, val, (nveu8_t *)osi_core->base + EQOS_MTL_EST_STATUS); + +done: + return; } -#endif /* !OSI_STRIPPED_LIB */ #ifdef HSI_SUPPORT /** @@ -2488,10 +2315,8 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *const osi_core) nveu32_t i = 0; nveu32_t dma_sr = 0; nveu32_t dma_ier = 0; -#ifndef OSI_STRIPPED_LIB nveu32_t mtl_isr = 0; nveu32_t frp_isr = 0U; -#endif /* !OSI_STRIPPED_LIB */ if (osi_core->mac_ver >= OSI_EQOS_MAC_5_30) { osi_writela(osi_core, EQOS_MAC_SBD_INTR, (nveu8_t *)osi_core->base + @@ -2547,7 +2372,6 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *const osi_core) eqos_handle_mac_intrs(osi_core, dma_isr); -#ifndef OSI_STRIPPED_LIB /* Handle MTL inerrupts */ mtl_isr = osi_readla(osi_core, (nveu8_t *)base + EQOS_MTL_INTR_STATUS); @@ -2568,7 +2392,6 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *const osi_core) EQOS_MTL_RXP_INTR_CS_PDRFIS); osi_writela(osi_core, frp_isr, (nveu8_t *)base + EQOS_MTL_RXP_INTR_CS); -#endif /* !OSI_STRIPPED_LIB */ } #if defined(MACSEC_SUPPORT) && !defined(OSI_STRIPPED_LIB) @@ -3819,314 +3642,6 @@ static nve32_t eqos_config_ptp_rxq(struct osi_core_priv_data *const osi_core, } #endif /* !OSI_STRIPPED_LIB */ -#ifndef OSI_STRIPPED_LIB -/** - * @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 nve32_t eqos_hw_est_write(struct osi_core_priv_data *osi_core, - nveu32_t addr_val, - nveu32_t data, nveu32_t gcla) -{ - void *base = osi_core->base; - nve32_t retry = 1000; - nveu32_t val = 0x0; - - osi_writela(osi_core, data, (nveu8_t *)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, - (nveu8_t *)base + EQOS_MTL_EST_GCL_CONTROL); - - while (--retry > 0) { - osi_core->osd_ops.udelay(OSI_DELAY_1US); - val = osi_readla(osi_core, (nveu8_t *)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 nve32_t eqos_hw_config_est(struct osi_core_priv_data *const osi_core, - struct osi_est_config *const est) -{ - void *base = osi_core->base; - nveu32_t btr[2] = {0}; - nveu32_t val = 0x0; - nveu32_t addr = 0x0; - nveu32_t i; - nve32_t 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", - (nveul64_t)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", - (nveul64_t)(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", - (nveul64_t)(btr[1] + - est->btr_offset[1])); - return ret; - } - - val = osi_readla(osi_core, (nveu8_t *) - 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 nve32_t eqos_hw_config_fpe(struct osi_core_priv_data *const osi_core, - struct osi_fpe_config *const fpe) -{ - nveu32_t i = 0U; - nveu32_t val = 0U; - nveu32_t temp = 0U, temp1 = 0U; - nveu32_t 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, - (nveu8_t *)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, - (nveu8_t *)osi_core->base + EQOS_MAC_RQC1R); - - /* initiate SVER for SMD-V and SMD-R */ - val = osi_readla(osi_core, - (nveu8_t *)osi_core->base + EQOS_MTL_FPE_CTS); - val |= EQOS_MAC_FPE_CTS_SVER; - osi_writela(osi_core, val, - (nveu8_t *)osi_core->base + EQOS_MAC_FPE_CTS); - - val = osi_readla(osi_core, - (nveu8_t *)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, - (nveu8_t *)osi_core->base + EQOS_MTL_FPE_ADV); - - return 0; -} -#endif /* !OSI_STRIPPED_LIB */ - /** \cond DO_NOT_DOCUMENT */ /** * @brief poll_for_mii_idle Query the status of an ongoing DMA transfer @@ -4674,6 +4189,7 @@ static nve32_t eqos_config_tx_status(struct osi_core_priv_data *const osi_core, return 0; } +#endif /* !OSI_STRIPPED_LIB */ /** * @brief eqos_set_avb_algorithm - Set TxQ/TC avb config @@ -4717,21 +4233,21 @@ static nve32_t eqos_set_avb_algorithm( if (avb == OSI_NULL) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "avb structure is NULL\n", 0ULL); - return ret; + goto done; } /* 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; + goto done; } /* 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; + goto done; } /* can't set AVB mode for queue 0 */ @@ -4739,7 +4255,7 @@ static nve32_t eqos_set_avb_algorithm( OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OPNOTSUPP, "Not allowed to set AVB for Q0\n", (nveul64_t)avb->qindex); - return ret; + goto done; } qinx = avb->qindex; @@ -4804,7 +4320,9 @@ static nve32_t eqos_set_avb_algorithm( EQOS_MTL_TXQ_ETS_LCR(qinx)); } - return 0; + ret = 0; +done: + return ret; } /** @@ -4848,13 +4366,13 @@ static nve32_t eqos_get_avb_algorithm(struct osi_core_priv_data *const osi_core, if (avb == OSI_NULL) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "avb structure is NULL\n", 0ULL); - return ret; + goto done; } 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; + goto done; } qinx = avb->qindex; @@ -4895,9 +4413,13 @@ static nve32_t eqos_get_avb_algorithm(struct osi_core_priv_data *const osi_core, EQOS_MTL_TXQ_ETS_LCR(qinx)); avb->low_credit = value & EQOS_MTL_TXQ_ETS_LCR_LC_MASK; - return 0; + ret = 0; + +done: + return ret; } +#ifndef OSI_STRIPPED_LIB /** * @brief eqos_config_arp_offload - Enable/Disable ARP offload * @@ -5738,7 +5260,7 @@ static void eqos_config_for_macsec(struct osi_core_priv_data *const osi_core, if ((enable != OSI_ENABLE) && (enable != OSI_DISABLE)) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Failed to config EQOS per MACSEC\n", 0ULL); - goto exit; + goto done; } if (osi_core->mac_ver == OSI_EQOS_MAC_5_30) { /* stop MAC Tx */ @@ -5806,7 +5328,7 @@ static void eqos_config_for_macsec(struct osi_core_priv_data *const osi_core, OSI_LOG_ARG_HW_FAIL, "Error: osi_core->hw_feature is NULL\n", 0ULL); } -exit: +done: return; } @@ -5843,6 +5365,11 @@ void eqos_init_core_ops(struct core_ops *ops) ops->update_ip4_addr = eqos_update_ip4_addr; ops->read_reg = eqos_read_reg; ops->write_reg = eqos_write_reg; + ops->set_avb_algorithm = eqos_set_avb_algorithm; + ops->get_avb_algorithm = eqos_get_avb_algorithm; + ops->config_frp = eqos_config_frp; + ops->update_frp_entry = eqos_update_frp_entry; + ops->update_frp_nve = eqos_update_frp_nve; #ifdef MACSEC_SUPPORT ops->read_macsec_reg = eqos_read_macsec_reg; ops->write_macsec_reg = eqos_write_macsec_reg; @@ -5860,8 +5387,6 @@ void eqos_init_core_ops(struct core_ops *ops) ops->config_arp_offload = eqos_config_arp_offload; ops->config_ptp_offload = eqos_config_ptp_offload; ops->validate_regs = eqos_validate_core_regs; - 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; @@ -5869,11 +5394,6 @@ void eqos_init_core_ops(struct core_ops *ops) ops->restore_registers = eqos_restore_registers; ops->set_mdc_clk_rate = eqos_set_mdc_clk_rate; ops->config_mac_loopback = eqos_config_mac_loopback; - ops->hw_config_est = eqos_hw_config_est; - ops->hw_config_fpe = eqos_hw_config_fpe; - 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; ops->config_ptp_rxq = eqos_config_ptp_rxq; #endif /* !OSI_STRIPPED_LIB */ diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 99142a3..fd963f0 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -28,20 +28,6 @@ #define EQOS_MAC_LPI_CSR 0x00D0 #define EQOS_MAC_LPI_TIMER_CTRL 0x00D4 #define EQOS_MAC_LPI_EN_TIMER 0x00D8 -#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_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_IND_CS 0x0CB0 -#define EQOS_MTL_RXP_IND_DATA 0x0CB4 #define EQOS_MAC_RX_FLW_CTRL 0x0090 #define EQOS_MAC_STNSR 0x0B0C #define EQOS_MAC_STSR 0x0B08 @@ -52,17 +38,6 @@ #define EQOS_MAC_PIDR2 0x0BCC #define EQOS_MAC_PMTCSR 0x00C0 #define EQOS_MAC_QX_TX_FLW_CTRL(x) ((0x0004U * (x)) + 0x0070U) -#define EQOS_MTL_TXQ_ETS_CR(x) ((0x0040U * (x)) + 0x0D10U) -#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_MAC_HTR_REG(x) ((0x0004U * (x)) + 0x0010U) -#define EQOS_MAC_L3_AD2R(x) ((0x0030U * (x)) + 0x0918U) -#define EQOS_MAC_L3_AD3R(x) ((0x0030U * (x)) + 0x091CU) -#define EQOS_MAC_L4_ADR(x) ((0x0030U * (x)) + 0x0904U) -#define EQOS_MTL_INTR_STATUS 0x0C20 -#define EQOS_MTL_OP_MODE 0x0C00 -#define EQOS_MAC_FPE_CTS 0x0234 #define EQOS_MAC_MA0HR 0x0300 #define EQOS_4_10_MAC_ARPPA 0x0AE0 #define EQOS_5_00_MAC_ARPPA 0x0210 @@ -98,9 +73,11 @@ #define EQOS_MAC_IMR_MASK 0x67039U #define EQOS_MAC_HTR_MASK 0xFFFFFFFFU #define EQOS_MAC_HTR0_IDX 2U -#define EQOS_IMR_FPEIE OSI_BIT(17) +#define EQOS_MAC_HTR_REG(x) ((0x0004U * (x)) + 0x0010U) +#define EQOS_MAC_L3_AD2R(x) ((0x0030U * (x)) + 0x0918U) +#define EQOS_MAC_L3_AD3R(x) ((0x0030U * (x)) + 0x091CU) +#define EQOS_MAC_L4_ADR(x) ((0x0030U * (x)) + 0x0904U) #define EQOS_DMA_SBUS_MASK 0xDF1F3CFFU -#define EQOS_DMA_ISR_MTLIS OSI_BIT(16) #define EQOS_DMA_CHX_STATUS_FBE OSI_BIT(10) #define EQOS_DMA_CHX_STATUS_TBU OSI_BIT(2) #define EQOS_DMA_CHX_STATUS_RBU OSI_BIT(7) @@ -108,6 +85,88 @@ #define EQOS_DMA_CHX_STATUS_RWT OSI_BIT(9) #define EQOS_DMA_CHX_STATUS_TPS OSI_BIT(1) #define EQOS_MAC_L3L4_CTR_L4DPI_SHIFT 21 +#define EQOS_MAC_RQC0R_MASK 0xFFU +#define EQOS_MAC_QX_TX_FLW_CTRL_TFE OSI_BIT(1) +#define EQOS_MAC_QX_TXFC_MASK 0xFFFF00F2U +#define EQOS_MAC_Q0_TXFC_IDX 6U +#define EQOS_MAC_PTO_CR_ASYNCEN OSI_BIT(1) +#define EQOS_MAC_RQC1R_OMCBCQ OSI_BIT(28) +#define EQOS_MAC_PIDR_PID_MASK 0XFFFFU +#define EQOS_MAC_PFR_MASK 0x803107FFU +#define EQOS_MAC_PAUSE_TIME 0xFFFF0000U +#define EQOS_MAC_PAUSE_TIME_MASK 0xFFFF0000U +#define EQOS_MAC_MCR_MASK 0xFFFFFF7FU +#define EQOS_MAC_MA0LR_IDX 12U +#define EQOS_MAC_MA0LR_MASK 0xFFFFFFFFU +#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_PTOEN OSI_BIT(0) + +#define EQOS_MCR_IPG_MASK 0x7000000U +#define EQOS_MCR_IPG_SHIFT 24U +#define EQOS_MCR_IPG 0x7U +#define EQOS_MAC_TCR_TSENMACADDR OSI_BIT(18) +#define EQOS_MAC_TCR_SNAPTYPSEL_SHIFT 16U +#define EQOS_MAC_TAR_IDX 15U +#define EQOS_MAC_SSIR_IDX 14U +#define EQOS_MAC_RX_FLW_CTRL_RFE OSI_BIT(0) +#define EQOS_MAC_TCR_MASK 0x1107FF03U +#define EQOS_MAC_TAR_MASK 0xFFFFFFFFU +#define EQOS_MAC_SSIR_MASK 0xFFFF00U +#define EQOS_MAC_RQC2R_MASK 0xFFFFFFFFU +#define EQOS_MAC_RQC1R_TPQC (OSI_BIT(22) | OSI_BIT(23)) +#define EQOS_MAC_RQC1R_TPQC0 OSI_BIT(22) +#define EQOS_MAC_RQC1R_PTPQ (OSI_BIT(6) | OSI_BIT(5) | \ + OSI_BIT(4)) +#define EQOS_MAC_RQC1R_PTPQ_SHIFT 4U +/** + * @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 */ +/** @} */ +#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) +#endif /* !OSI_STRIPPED_LIB */ +#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_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_IND_CS 0x0CB0 +#define EQOS_MTL_RXP_IND_DATA 0x0CB4 +#define EQOS_MTL_TXQ_ETS_CR(x) ((0x0040U * (x)) + 0x0D10U) +#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_INTR_STATUS 0x0C20 +#define EQOS_MTL_OP_MODE 0x0C00 +#define EQOS_MAC_FPE_CTS 0x0234 +#define EQOS_IMR_FPEIE OSI_BIT(17) +#define EQOS_MTL_FRP_IE2_DCH_SHIFT 24U +#define EQOS_DMA_ISR_MTLIS OSI_BIT(16) /** * @addtogroup EQOS-MTL FRP Indirect Access register defines * @@ -148,10 +207,14 @@ #define EQOS_MTL_RXP_INTR_CS_NPEOVIS OSI_BIT(1) #define EQOS_MTL_RXP_INTR_CS_NVEOVIS OSI_BIT(0) +#ifndef OSI_STRIPPED_LIB #define EQOS_RXQ_DMA_MAP0_MASK 0x13131313U #define EQOS_MTL_TXQ_QW_MASK 0x1FFFFFU #define EQOS_PAD_AUTO_CAL_CFG_MASK 0x7FFFFFFFU #define EQOS_MTL_TXQ_OP_MODE_MASK 0xFF007EU +#define EQOS_MTL_RXQ_OP_MODE_MASK 0xFFFFFFBU +#define EQOS_MAC_RQC1R_MASK 0xF77077U +#endif /* !OSI_STRIPPED_LIB */ #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 @@ -160,32 +223,9 @@ #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_RXQ_OP_MODE_MASK 0xFFFFFFBU -#define EQOS_MAC_RQC1R_MASK 0xF77077U #define EQOS_MAC_RQC1R_FPRQ (OSI_BIT(26) | OSI_BIT(25) | \ OSI_BIT(24)) #define EQOS_MAC_RQC1R_FPRQ_SHIFT 24U -#define EQOS_MAC_RQC0R_MASK 0xFFU -#define EQOS_MAC_QX_TX_FLW_CTRL_TFE OSI_BIT(1) -#define EQOS_MAC_QX_TXFC_MASK 0xFFFF00F2U -#define EQOS_MAC_Q0_TXFC_IDX 6U -#define EQOS_MAC_PTO_CR_ASYNCEN OSI_BIT(1) -#define EQOS_MAC_RQC1R_OMCBCQ OSI_BIT(28) -#define EQOS_MAC_PIDR_PID_MASK 0XFFFFU -#define EQOS_MAC_PFR_MASK 0x803107FFU -#define EQOS_MAC_PAUSE_TIME 0xFFFF0000U -#define EQOS_MAC_PAUSE_TIME_MASK 0xFFFF0000U -#define EQOS_MAC_MCR_MASK 0xFFFFFF7FU -#define EQOS_MAC_MA0LR_IDX 12U -#define EQOS_MAC_MA0LR_MASK 0xFFFFFFFFU -#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_PTOEN 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) @@ -209,44 +249,6 @@ #define EQOS_MTL_FRP_IE2_RF OSI_BIT(1) #define EQOS_MTL_FRP_IE2_AF OSI_BIT(0) -#define EQOS_MCR_IPG_MASK 0x7000000U -#define EQOS_MCR_IPG_SHIFT 24U -#define EQOS_MCR_IPG 0x7U -#define EQOS_MAC_TCR_TSENMACADDR OSI_BIT(18) -#define EQOS_MAC_TCR_SNAPTYPSEL_SHIFT 16U -#define EQOS_MAC_TAR_IDX 15U -#define EQOS_MAC_SSIR_IDX 14U -#define EQOS_MAC_RX_FLW_CTRL_RFE OSI_BIT(0) -#define EQOS_MAC_TCR_MASK 0x1107FF03U -#define EQOS_MAC_TAR_MASK 0xFFFFFFFFU -#define EQOS_MAC_SSIR_MASK 0xFFFF00U -#define EQOS_MAC_RQC2R_MASK 0xFFFFFFFFU -#define EQOS_MAC_RQC1R_TPQC (OSI_BIT(22) | OSI_BIT(23)) -#define EQOS_MAC_RQC1R_TPQC0 OSI_BIT(22) -#define EQOS_MAC_RQC1R_PTPQ (OSI_BIT(6) | OSI_BIT(5) | \ - OSI_BIT(4)) -#define EQOS_MAC_RQC1R_PTPQ_SHIFT 4U -/** - * @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 */ -/** @} */ -#define EQOS_MTL_FRP_IE2_DCH_SHIFT 24U -#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) -#endif /* !OSI_STRIPPED_LIB */ /** * @addtogroup EQOS-SIZE SIZE calculation helper Macros * @@ -440,8 +442,6 @@ #define EQOS_MAC_ENABLE_LM OSI_BIT(12) #define EQOS_MCR_ARPEN OSI_BIT(31) #define EQOS_RX_CLK_SEL OSI_BIT(8) -#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_TR_VTIM OSI_BIT(17) @@ -449,14 +449,25 @@ #define EQOS_MAC_VLAN_TR_VTHM OSI_BIT(25) #define EQOS_MAC_STNSR_TSSS_MASK 0x7FFFFFFFU #define EQOS_MAC_PFR_SHIFT 16 -#define EQOS_MTL_OP_MODE_FRPE OSI_BIT(15) #define EQOS_MTL_OP_MODE_DTXSTS OSI_BIT(1) #define EQOS_MAC_EXTR_DCRCC OSI_BIT(16) +#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_AVALG OSI_BIT(2) +#define EQOS_MTL_TXQ_ETS_CR_AVALG_SHIFT 2U +#define EQOS_MTL_TXQ_ETS_CR_CC OSI_BIT(3) +#define EQOS_MTL_TXQ_ETS_CR_CC_SHIFT 3U +#define EQOS_MAC_EXTR_PDC OSI_BIT(19) #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_TXQEN_MASK (OSI_BIT(3) | OSI_BIT(2)) +#define EQOS_MTL_TXQEN_MASK_SHIFT 2U +#define EQOS_MTL_OP_MODE_FRPE OSI_BIT(15) #define EQOS_MAC_EXTR_PDC OSI_BIT(19) #define EQOS_MTL_RXQ_OP_MODE_EHFC OSI_BIT(7) #define EQOS_MTL_RXQ_OP_MODE_RFA_SHIFT 8U @@ -563,26 +574,14 @@ (TEGRA_SID_EQOS)) #define EQOS_MMC_INTR_DISABLE 0xFFFFFFFFU -#ifndef OSI_STRIPPED_LIB /* 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) | \ @@ -599,14 +598,10 @@ #define EQOS_MTL_EST_CONTROL_CTOV_SHIFT 12U #define EQOS_MTL_EST_CTOV_RECOMMEND 94U #define EQOS_8PTP_CYCLE 40U -#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_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) | \ @@ -614,15 +609,6 @@ #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 ((nveu32_t)0x0 << \ EQOS_MTL_EST_ADDR_SHIFT) @@ -632,7 +618,6 @@ EQOS_MTL_EST_ADDR_SHIFT) #define EQOS_MTL_EST_CTR_HIGH ((nveu32_t)0x3 << \ EQOS_MTL_EST_ADDR_SHIFT) -#define EQOS_MTL_EST_CTR_HIGH_MAX 0xFFU #define EQOS_MTL_EST_TER ((nveu32_t)0x4 << \ EQOS_MTL_EST_ADDR_SHIFT) #define EQOS_MTL_EST_LLR ((nveu32_t)0x5 << \ @@ -645,12 +630,6 @@ #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) -#endif /* !OSI_STRIPPED_LIB */ #if defined(MACSEC_SUPPORT) && !defined(OSI_STRIPPED_LIB) /* MACSEC Recommended value*/ #define EQOS_MTL_EST_CTOV_MACSEC_RECOMMEND 758U diff --git a/osi/core/frp.c b/osi/core/frp.c index 41075b5..dab09d1 100644 --- a/osi/core/frp.c +++ b/osi/core/frp.c @@ -23,7 +23,6 @@ #include "../osi/common/common.h" #include "frp.h" -#ifndef OSI_STRIPPED_LIB /** * @brief frp_entry_copy - Copy FRP entry * @@ -34,7 +33,7 @@ * */ static void frp_entry_copy(struct osi_core_frp_entry *dst, - struct osi_core_frp_entry *src) + struct osi_core_frp_entry *const src) { dst->frp_id = src->frp_id; dst->data.match_data = src->data.match_data; @@ -63,12 +62,13 @@ static void frp_entry_copy(struct osi_core_frp_entry *dst, * @retval -1 on failure. */ static nve32_t frp_entry_find(struct osi_core_priv_data *const osi_core, - nve32_t frp_id, - nveu8_t *start, - nveu8_t *no_entries) + nve32_t frp_id, + nveu8_t *start, + nveu8_t *no_entries) { nveu8_t count = OSI_NONE, found = OSI_NONE; struct osi_core_frp_entry *entry = OSI_NULL; + nve32_t ret = 0; /* Parse the FRP table for give frp_id */ for (count = 0U; count < osi_core->frp_cnt; count++) { @@ -81,17 +81,17 @@ static nve32_t frp_entry_find(struct osi_core_priv_data *const osi_core, found = OSI_ENABLE; } else { /* Increment entries */ - *no_entries = (nveu8_t) (*no_entries + 1U); + *no_entries = (nveu8_t)(*no_entries + 1U); } } } if (found == OSI_NONE) { /* No entry found return error */ - return -1; + ret = -1; } - return 0; + return ret; } /** @@ -106,33 +106,37 @@ static nve32_t frp_entry_find(struct osi_core_priv_data *const osi_core, * @retval No of FRP entries required. */ static nveu8_t frp_req_entries(nveu8_t offset, - nveu8_t match_length) + nveu8_t match_length) { nveu8_t req = 0U; + nveu8_t temp_match_length = match_length; - /* Validate for match_length */ - if ((match_length == OSI_NONE) || - (match_length > OSI_FRP_MATCH_DATA_MAX)) { + /* Validate for temp_match_length */ + if ((temp_match_length == OSI_NONE) || + (temp_match_length > OSI_FRP_MATCH_DATA_MAX)) { /* return zero */ - return req; + goto done; } /* Check does the given length can fit in fist entry */ - if (match_length <= (nveu8_t) FRP_OFFSET_BYTES(offset)) { + if (temp_match_length <= (nveu8_t)FRP_OFFSET_BYTES(offset)) { /* Require one entry */ - return 1U; + req = 1U; + goto done; } /* Initialize req as 1U and decrement length by FRP_OFFSET_BYTES */ req = 1U; - match_length = (nveu8_t) (match_length - (nveu8_t) FRP_OFFSET_BYTES(offset)); - if ((match_length / FRP_MD_SIZE) < OSI_FRP_MATCH_DATA_MAX) { - req = (nveu8_t) (req + (match_length / FRP_MD_SIZE)); - if ((match_length % FRP_MD_SIZE) != OSI_NONE) { + temp_match_length = (nveu8_t)(temp_match_length - + (nveu8_t)FRP_OFFSET_BYTES(offset)); + if ((temp_match_length / FRP_MD_SIZE) < OSI_FRP_MATCH_DATA_MAX) { + req = (nveu8_t)(req + (temp_match_length / FRP_MD_SIZE)); + if ((temp_match_length % FRP_MD_SIZE) != OSI_NONE) { /* Need one more entry */ - req = (nveu8_t) (req + 1U); + req = (nveu8_t)(req + 1U); } } +done: return req; } @@ -217,14 +221,14 @@ static void frp_entry_mode_parse(nveu8_t filter_mode, * @retval -1 on failure. */ static nve32_t frp_entry_add(struct osi_core_priv_data *const osi_core, - nve32_t frp_id, - nveu8_t pos, - nveu8_t *const match, - nveu8_t length, - nveu8_t offset, - nveu8_t filter_mode, - nve32_t next_frp_id, - nveu32_t dma_sel) + nve32_t frp_id, + nveu8_t pos, + nveu8_t *const match, + nveu8_t length, + nveu8_t offset, + nveu8_t filter_mode, + nve32_t next_frp_id, + nveu32_t dma_sel) { struct osi_core_frp_entry *entry = OSI_NULL; struct osi_core_frp_data *data = OSI_NULL; @@ -233,13 +237,16 @@ static nve32_t frp_entry_add(struct osi_core_priv_data *const osi_core, nveu8_t fo_t = 0U; nveu8_t fp_t = 0U; nveu8_t i = 0U, j = 0U, md_pos = 0U; + nveu8_t temp_pos = pos; + nve32_t ret; /* 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; + ret = -1; + goto done; } /* Validate filter_mode */ @@ -247,7 +254,8 @@ static nve32_t frp_entry_add(struct osi_core_priv_data *const osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid filter mode argment\n", filter_mode); - return -1; + ret = -1; + goto done; } /* Validate offset */ @@ -255,17 +263,19 @@ static nve32_t frp_entry_add(struct osi_core_priv_data *const osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid offset value\n", offset); - return -1; + ret = -1; + goto done; } /* 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)) { + ((req_entries + temp_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; + ret = -1; + goto done; } /* Validate next_frp_id index ok_index */ @@ -275,7 +285,7 @@ static nve32_t frp_entry_add(struct osi_core_priv_data *const osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "No Link FRP ID index found\n", OSI_NONE); - i = (nveu8_t) next_frp_id; + i = (nveu8_t)next_frp_id; } ok_index = i; } @@ -286,7 +296,7 @@ static nve32_t frp_entry_add(struct osi_core_priv_data *const osi_core, md_pos = 0U; for (i = 0U; i < req_entries; i++) { /* Get FRP entry*/ - entry = &osi_core->frp_table[pos]; + entry = &osi_core->frp_table[temp_pos]; data = &entry->data; /* Fill FRP ID */ @@ -324,10 +334,10 @@ static nve32_t frp_entry_add(struct osi_core_priv_data *const osi_core, data->next_ins_ctrl = OSI_ENABLE; /* Init next FRP entry */ - pos++; + temp_pos++; fo_t++; fp_t = OSI_NONE; - data->ok_index = pos; + data->ok_index = temp_pos; } else { data->next_ins_ctrl = OSI_DISABLE; data->ok_index = OSI_DISABLE; @@ -342,7 +352,9 @@ static nve32_t frp_entry_add(struct osi_core_priv_data *const osi_core, data->ok_index = ok_index; } - return 0; + ret = 0; +done: + return ret; } /** @@ -356,9 +368,9 @@ static nve32_t frp_entry_add(struct osi_core_priv_data *const osi_core, * @retval -1 on failure. */ static nve32_t frp_hw_write(struct osi_core_priv_data *const osi_core, - struct core_ops *ops_p) + struct core_ops *const ops_p) { - nve32_t ret = -1, tmp = -1; + nve32_t ret, tmp; struct osi_core_frp_entry *entry; nveu32_t frp_cnt = osi_core->frp_cnt, i = OSI_NONE; @@ -411,10 +423,10 @@ hw_write_enable_frp: * @retval -1 on failure. */ static nve32_t frp_add_proto(struct osi_core_priv_data *const osi_core, - struct osi_core_frp_cmd *const cmd, - nveu8_t *pos) + struct osi_core_frp_cmd *const cmd, + nveu8_t *pos) { - nve32_t ret = -1, proto_oki = -1; + nve32_t ret, proto_oki; nveu8_t proto_entry = OSI_DISABLE; nveu8_t req = 0U; nveu8_t proto_match[FRP_PROTO_LENGTH]; @@ -463,16 +475,18 @@ static nve32_t frp_add_proto(struct osi_core_priv_data *const osi_core, /* Check and Add protocol FRP entire */ if (proto_entry == OSI_ENABLE) { /* Check for space */ - req = (nveu8_t) (frp_req_entries(cmd->offset, cmd->match_length) + 1U); + req = (nveu8_t)(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; + ret = -1; + goto done; } /* Add protocol FRP entire */ - proto_oki = *pos + 1; + proto_oki = (nve32_t)*pos; + proto_oki += 1; ret = frp_entry_add(osi_core, cmd->frp_id, *pos, proto_match, proto_lendth, proto_offset, OSI_FRP_MODE_LINK, @@ -481,14 +495,16 @@ static nve32_t frp_add_proto(struct osi_core_priv_data *const osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Fail add FRP protocol entry\n", OSI_NONE); - return ret; + goto done; } /* Increment pos value */ - *pos = (nveu8_t) (*pos + 1U); + *pos = (nveu8_t)(*pos + (nveu8_t)1); } - return 0; + ret = 0; +done: + return ret; } /** @@ -496,12 +512,10 @@ static nve32_t frp_add_proto(struct osi_core_priv_data *const osi_core, * * 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) +static void frp_parse_mtype(struct osi_core_frp_cmd *const cmd) { nveu8_t offset; nveu8_t match_type = cmd->match_type; @@ -556,10 +570,10 @@ static void frp_parse_mtype(OSI_UNUSED struct osi_core_priv_data *const osi_core * @retval -1 on failure. */ static nve32_t frp_delete(struct osi_core_priv_data *const osi_core, - struct core_ops *ops_p, - struct osi_core_frp_cmd *const cmd) + struct core_ops *ops_p, + struct osi_core_frp_cmd *const cmd) { - nve32_t ret = -1; + nve32_t ret; nveu8_t i = 0U, pos = 0U, count = 0U; nve32_t frp_id = cmd->frp_id; nveu32_t frp_cnt = osi_core->frp_cnt; @@ -569,7 +583,8 @@ static nve32_t frp_delete(struct osi_core_priv_data *const osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "No FRP entries in the table\n", OSI_NONE); - return -1; + ret = -1; + goto done; } /* Find the FRP entry */ @@ -577,7 +592,8 @@ static nve32_t frp_delete(struct osi_core_priv_data *const osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "No FRP entry found to delete\n", OSI_NONE); - return -1; + ret = -1; + goto done; } /* Validate pos and count */ @@ -585,7 +601,8 @@ static nve32_t frp_delete(struct osi_core_priv_data *const osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Invalid FRP entry index\n", OSI_NONE); - return -1; + ret = -1; + goto done; } /* Update the frp_table entry */ @@ -593,7 +610,7 @@ static nve32_t frp_delete(struct osi_core_priv_data *const osi_core, (sizeof(struct osi_core_frp_entry) * count)); /* Move in FRP table entries by count */ - for (i = (nveu8_t) (pos + count); i <= frp_cnt; i++) { + for (i = (nveu8_t)(pos + count); i <= frp_cnt; i++) { frp_entry_copy(&osi_core->frp_table[pos], &osi_core->frp_table[i]); pos++; @@ -610,6 +627,7 @@ static nve32_t frp_delete(struct osi_core_priv_data *const osi_core, /* Update the frp_cnt entry */ osi_core->frp_cnt = (frp_cnt - count); +done: return ret; } @@ -625,10 +643,10 @@ static nve32_t frp_delete(struct osi_core_priv_data *const osi_core, * @retval -1 on failure. */ static nve32_t frp_update(struct osi_core_priv_data *const osi_core, - struct core_ops *ops_p, - struct osi_core_frp_cmd *const cmd) + struct core_ops *ops_p, + struct osi_core_frp_cmd *const cmd) { - nve32_t ret = -1; + nve32_t ret; nveu8_t pos = 0U, count = 0U, req = 0U; nve32_t frp_id = cmd->frp_id; @@ -637,11 +655,12 @@ static nve32_t frp_update(struct osi_core_priv_data *const osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "No FRP entry found\n", OSI_NONE); - return -1; + ret = -1; + goto done; } /* Parse match type and update command offset */ - frp_parse_mtype(osi_core, cmd); + frp_parse_mtype(cmd); /* Calculate the required FRP entries for Update Command. */ req = frp_req_entries(cmd->offset, cmd->match_length); @@ -663,7 +682,8 @@ static nve32_t frp_update(struct osi_core_priv_data *const osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Old and New required FRP entries mismatch\n", OSI_NONE); - return -1; + ret = -1; + goto done; } /* Process and update FRP Command Protocal Entry */ @@ -672,7 +692,7 @@ static nve32_t frp_update(struct osi_core_priv_data *const osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Fail to parse match type\n", OSI_NONE); - return ret; + goto done; } /* Update FRP entries */ @@ -684,7 +704,7 @@ static nve32_t frp_update(struct osi_core_priv_data *const osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Fail to update FRP entry\n", OSI_NONE); - return ret; + goto done; } /* Write FRP Table into HW */ @@ -695,6 +715,7 @@ static nve32_t frp_update(struct osi_core_priv_data *const osi_core, OSI_NONE); } +done: return ret; } @@ -710,10 +731,10 @@ static nve32_t frp_update(struct osi_core_priv_data *const osi_core, * @retval -1 on failure. */ static nve32_t frp_add(struct osi_core_priv_data *const osi_core, - struct core_ops *ops_p, - struct osi_core_frp_cmd *const cmd) + struct core_ops *ops_p, + struct osi_core_frp_cmd *const cmd) { - nve32_t ret = -1; + nve32_t ret; nveu8_t pos = 0U, count = 0U; nve32_t frp_id = cmd->frp_id; nveu32_t nve = osi_core->frp_cnt; @@ -723,7 +744,8 @@ static nve32_t frp_add(struct osi_core_priv_data *const osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, "FRP etries are full\n", nve); - return -1; + ret = -1; + goto done; } /* Check the FRP entry already exists */ @@ -732,11 +754,12 @@ static nve32_t frp_add(struct osi_core_priv_data *const osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "FRP entry already exists\n", OSI_NONE); - return -1; + ret = -1; + goto done; } /* Parse match type and update command offset */ - frp_parse_mtype(osi_core, cmd); + frp_parse_mtype(cmd); /* Process and add FRP Command Protocal Entry */ ret = frp_add_proto(osi_core, cmd, (nveu8_t *)&nve); @@ -744,7 +767,7 @@ static nve32_t frp_add(struct osi_core_priv_data *const osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Fail to parse match type\n", OSI_NONE); - return ret; + goto done; } /* Add Match data FRP Entry */ @@ -756,7 +779,7 @@ static nve32_t frp_add(struct osi_core_priv_data *const osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Fail to add FRP entry\n", nve); - return ret; + goto done; } osi_core->frp_cnt = nve + frp_req_entries(cmd->offset, cmd->match_length); @@ -769,6 +792,7 @@ static nve32_t frp_add(struct osi_core_priv_data *const osi_core, OSI_NONE); } +done: return ret; } @@ -784,8 +808,8 @@ static nve32_t frp_add(struct osi_core_priv_data *const osi_core, * @retval -1 on failure. */ nve32_t setup_frp(struct osi_core_priv_data *const osi_core, - struct core_ops *ops_p, - struct osi_core_frp_cmd *const cmd) + struct core_ops *ops_p, + struct osi_core_frp_cmd *const cmd) { nve32_t ret = -1; @@ -835,4 +859,3 @@ void init_frp(struct osi_core_priv_data *const osi_core) osi_memset(osi_core->frp_table, 0U, (sizeof(struct osi_core_frp_entry) * OSI_FRP_MAX_ENTRY)); } -#endif /* !OSI_STRIPPED_LIB */ diff --git a/osi/core/frp.h b/osi/core/frp.h index b8525e3..aefdb10 100644 --- a/osi/core/frp.h +++ b/osi/core/frp.h @@ -23,7 +23,6 @@ #ifndef FRP_H #define FRP_H -#ifndef OSI_STRIPPED_LIB #include <osi_common.h> #include <osi_core.h> #include "core_local.h" @@ -66,8 +65,8 @@ * @retval -1 on failure. */ nve32_t setup_frp(struct osi_core_priv_data *const osi_core, - struct core_ops *ops_p, - struct osi_core_frp_cmd *const cmd); + struct core_ops *ops_p, + struct osi_core_frp_cmd *const cmd); /** * @brief init_frp - Init the FRP Instruction Table. @@ -81,6 +80,5 @@ nve32_t setup_frp(struct osi_core_priv_data *const osi_core, * @retval -1 on failure. */ void init_frp(struct osi_core_priv_data *const osi_core); -#endif /* !OSI_STRIPPED_LIB */ #endif /* FRP_H */ diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index c0023cd..aec2d6e 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -69,11 +69,14 @@ static nve32_t ivc_handle_ioctl(struct osi_core_priv_data *osi_core, if (data->cmd == OSI_CMD_READ_MMC) { msg.status = osi_memcpy((void *)&osi_core->mmc, - (void *)&msg.data.mmc, - sizeof(struct osi_mmc_counters)); + (void *)&msg.data.mmc, + sizeof(struct osi_mmc_counters)); + msg.status = osi_memcpy((void *)&osi_core->tsn_stats, + (void *)&msg.data.eth_stats.tsn_s, + sizeof(struct osi_tsn_stats)); } else { msg.status = osi_memcpy((void *)data, - (void *)&msg.data.ioctl_data, + (void *)&msg.data.ioctl_data, sizeof(struct osi_ioctl)); } return ret; @@ -217,13 +220,13 @@ static nve32_t ivc_macsec_dbg_events_config( ret = osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); if (ret != 0) { - goto exit; + goto done; } msg.status = osi_memcpy((void *)dbg_buf_config, (void *)&msg.data.dbg_buf_config, sizeof(struct osi_macsec_dbg_buf_config)); -exit: +done: return ret; } @@ -253,13 +256,13 @@ static nve32_t ivc_macsec_dbg_buf_config( ret = osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); if (ret != 0) { - goto exit; + goto done; } msg.status = osi_memcpy((void *)dbg_buf_config, (void *) &msg.data.dbg_buf_config, sizeof(struct osi_macsec_dbg_buf_config)); -exit: +done: return ret; } #endif /* DEBUG_MACSEC */ @@ -362,11 +365,11 @@ static nve32_t ivc_macsec_config(struct osi_core_priv_data *const osi_core, ret = osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); if (ret != 0) { - goto exit; + goto done; } *kt_idx = msg.data.macsec_cfg.kt_idx; -exit: +done: return ret; } @@ -505,13 +508,13 @@ static nve32_t ivc_macsec_lut_config(struct osi_core_priv_data *const osi_core, ret = osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); if (ret != 0) { - goto exit; + goto done; } msg.status = osi_memcpy((void *)lut_config, (void *)&msg.data.lut_config, sizeof(struct osi_macsec_lut_config)); -exit: +done: return ret; } diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 77950c4..f3100e3 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -47,7 +47,7 @@ * @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 queue_count) { nveu32_t q_fifo_size = 0; /* calculated fifo size per queue */ nveu32_t p_fifo = 0; /* per queue fifo size program value */ @@ -159,9 +159,9 @@ static nve32_t mgbe_poll_for_mac_acrtl(struct osi_core_priv_data *osi_core) * @retval -1 on failure. */ static nve32_t mgbe_mac_indir_addr_write(struct osi_core_priv_data *osi_core, - nveu32_t mc_no, - nveu32_t addr_offset, - nveu32_t value) + nveu32_t mc_no, + nveu32_t addr_offset, + nveu32_t value) { void *base = osi_core->base; nveu32_t addr = 0; @@ -217,9 +217,9 @@ static nve32_t mgbe_mac_indir_addr_write(struct osi_core_priv_data *osi_core, * @retval -1 on failure. */ static nve32_t mgbe_mac_indir_addr_read(struct osi_core_priv_data *osi_core, - nveu32_t mc_no, - nveu32_t addr_offset, - nveu32_t *value) + nveu32_t mc_no, + nveu32_t addr_offset, + nveu32_t *value) { void *base = osi_core->base; nveu32_t addr = 0; @@ -274,7 +274,7 @@ static nve32_t mgbe_mac_indir_addr_read(struct osi_core_priv_data *osi_core, * @retval -1 on failure. */ static nve32_t mgbe_filter_args_validate(struct osi_core_priv_data *const osi_core, - const struct osi_filter *filter) + const struct osi_filter *filter) { nveu32_t idx = filter->index; nveu32_t dma_routing_enable = filter->dma_routing; @@ -511,9 +511,9 @@ static nve32_t mgbe_poll_for_l3l4crtl(struct osi_core_priv_data *osi_core) * @retval -1 on failure. */ static nve32_t mgbe_l3l4_filter_write(struct osi_core_priv_data *osi_core, - nveu32_t filter_no, - nveu32_t filter_type, - nveu32_t value) + nveu32_t filter_no, + nveu32_t filter_type, + nveu32_t value) { void *base = osi_core->base; nveu32_t addr = 0; @@ -573,9 +573,9 @@ static nve32_t mgbe_l3l4_filter_write(struct osi_core_priv_data *osi_core, * @retval -1 on failure. */ static nve32_t mgbe_l3l4_filter_read(struct osi_core_priv_data *osi_core, - nveu32_t filter_no, - nveu32_t filter_type, - nveu32_t *value) + nveu32_t filter_no, + nveu32_t filter_type, + nveu32_t *value) { void *base = osi_core->base; nveu32_t addr = 0; @@ -687,6 +687,7 @@ static nve32_t mgbe_update_ip4_addr(struct osi_core_priv_data *const osi_core, return ret; } + #ifndef OSI_STRIPPED_LIB /** * @brief mgbe_update_ip6_addr - add ipv6 address in register @@ -844,9 +845,9 @@ static nve32_t mgbe_update_l4_port_no(struct osi_core_priv_data *osi_core, * @retval updated nveu32_t value param */ static inline nveu32_t mgbe_set_dcs(struct osi_core_priv_data *osi_core, - nveu32_t value, - nveu32_t dma_routing_enable, - nveu32_t dma_chan) + nveu32_t value, + nveu32_t dma_routing_enable, + nveu32_t dma_chan) { if ((dma_routing_enable == OSI_ENABLE) && (dma_chan < OSI_MGBE_MAX_NUM_CHANS) && (osi_core->dcs_en == @@ -1104,13 +1105,13 @@ static nve32_t mgbe_config_l3_filters(struct osi_core_priv_data *osi_core, * @retval -1 on failure. */ static nve32_t mgbe_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) + 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) { nveu32_t value = 0U; nve32_t ret = 0; @@ -1310,8 +1311,8 @@ static nve32_t mgbe_config_vlan_filtering(struct osi_core_priv_data *osi_core, * @retval -1 on failure. */ static nve32_t mgbe_config_ptp_rxq(struct osi_core_priv_data *const osi_core, - const nveu32_t rxq_idx, - const nveu32_t enable) + const nveu32_t rxq_idx, + const nveu32_t enable) { nveu8_t *base = osi_core->base; nveu32_t value = 0U; @@ -1435,8 +1436,8 @@ static nve32_t mgbe_config_mac_loopback(struct osi_core_priv_data *const osi_cor * @retval -1 on failure. */ static nve32_t mgbe_config_arp_offload(struct osi_core_priv_data *const osi_core, - const nveu32_t enable, - const nveu8_t *ip_addr) + const nveu32_t enable, + const nveu8_t *ip_addr) { nveu32_t mac_rmcr; nveu32_t val; @@ -1466,6 +1467,7 @@ static nve32_t mgbe_config_arp_offload(struct osi_core_priv_data *const osi_core return 0; } +#endif /* !OSI_STRIPPED_LIB */ /** * @brief mgbe_config_frp - Enable/Disale RX Flexible Receive Parser in HW @@ -1484,17 +1486,18 @@ static nve32_t mgbe_config_arp_offload(struct osi_core_priv_data *const osi_core * @retval -1 on failure. */ static nve32_t mgbe_config_frp(struct osi_core_priv_data *const osi_core, - const nveu32_t enabled) + const nveu32_t enabled) { nveu8_t *base = osi_core->base; nveu32_t op_mode = 0U, val = 0U; - nve32_t ret = -1; + nve32_t 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; + ret = -1; + goto done; } op_mode = osi_readla(osi_core, base + MGBE_MTL_OP_MODE); @@ -1515,7 +1518,8 @@ static nve32_t mgbe_config_frp(struct osi_core_priv_data *const osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Fail to enable FRP\n", val); - return -1; + ret = -1; + goto done; } /* Enable FRP Interrupts in MTL_RXP_Interrupt_Control_Status */ @@ -1542,7 +1546,8 @@ static nve32_t mgbe_config_frp(struct osi_core_priv_data *const osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Fail to disable FRP\n", val); - return -1; + ret = -1; + goto done; } /* Disable FRP Interrupts in MTL_RXP_Interrupt_Control_Status */ @@ -1554,7 +1559,8 @@ static nve32_t mgbe_config_frp(struct osi_core_priv_data *const osi_core, osi_writela(osi_core, val, base + MGBE_MTL_RXP_INTR_CS); } - return 0; +done: + return ret; } /** @@ -1575,9 +1581,9 @@ static nve32_t mgbe_config_frp(struct osi_core_priv_data *const osi_core, * @retval -1 on failure. */ static nve32_t mgbe_frp_write(struct osi_core_priv_data *osi_core, - nveu32_t acc_sel, - nveu32_t addr, - nveu32_t data) + nveu32_t acc_sel, + nveu32_t addr, + nveu32_t data) { nve32_t ret = 0; nveu8_t *base = osi_core->base; @@ -1587,7 +1593,8 @@ static nve32_t mgbe_frp_write(struct osi_core_priv_data *osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid acc_sel argment\n", acc_sel); - return -1; + ret = -1; + goto done; } /* Wait for ready */ @@ -1602,7 +1609,8 @@ static nve32_t mgbe_frp_write(struct osi_core_priv_data *osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Fail to write\n", val); - return -1; + ret = -1; + goto done; } /* Write data into MTL_RXP_Indirect_Acc_Data */ @@ -1639,9 +1647,10 @@ static nve32_t mgbe_frp_write(struct osi_core_priv_data *osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Fail to write\n", val); - return -1; + ret = -1; } +done: return ret; } @@ -1660,8 +1669,8 @@ static nve32_t mgbe_frp_write(struct osi_core_priv_data *osi_core, * @retval -1 on failure. */ static nve32_t mgbe_update_frp_entry(struct osi_core_priv_data *const osi_core, - const nveu32_t pos, - struct osi_core_frp_data *const data) + const nveu32_t pos, + struct osi_core_frp_data *const data) { nveu32_t val = 0U, tmp = 0U; nve32_t ret = -1; @@ -1671,7 +1680,8 @@ static nve32_t mgbe_update_frp_entry(struct osi_core_priv_data *const osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid FRP table entry\n", pos); - return -1; + ret = -1; + goto done; } /** Write Match Data into IE0 **/ @@ -1679,7 +1689,8 @@ static nve32_t mgbe_update_frp_entry(struct osi_core_priv_data *const osi_core, ret = mgbe_frp_write(osi_core, OSI_DISABLE, MGBE_MTL_FRP_IE0(pos), val); if (ret < 0) { /* Match Data Write fail */ - return -1; + ret = -1; + goto done; } /** Write Match Enable into IE1 **/ @@ -1687,7 +1698,8 @@ static nve32_t mgbe_update_frp_entry(struct osi_core_priv_data *const osi_core, ret = mgbe_frp_write(osi_core, OSI_DISABLE, MGBE_MTL_FRP_IE1(pos), val); if (ret < 0) { /* Match Enable Write fail */ - return -1; + ret = -1; + goto done; } /** Write AF, RF, IM, NIC, FO and OKI into IE2 **/ @@ -1717,7 +1729,8 @@ static nve32_t mgbe_update_frp_entry(struct osi_core_priv_data *const osi_core, ret = mgbe_frp_write(osi_core, OSI_DISABLE, MGBE_MTL_FRP_IE2(pos), val); if (ret < 0) { /* FRP IE2 Write fail */ - return -1; + ret = -1; + goto done; } /** Write DCH into IE3 **/ @@ -1725,9 +1738,10 @@ static nve32_t mgbe_update_frp_entry(struct osi_core_priv_data *const osi_core, ret = mgbe_frp_write(osi_core, OSI_DISABLE, MGBE_MTL_FRP_IE3(pos), val); if (ret < 0) { /* DCH Write fail */ - return -1; + ret = -1; } +done: return ret; } @@ -1745,17 +1759,19 @@ static nve32_t mgbe_update_frp_entry(struct osi_core_priv_data *const osi_core, * @retval -1 on failure. */ static nve32_t mgbe_update_frp_nve(struct osi_core_priv_data *const osi_core, - const nveu32_t nve) + const nveu32_t nve) { nveu32_t val; nveu8_t *base = osi_core->base; + nve32_t ret; /* 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; + ret = -1; + goto done; } /* Update NVE and NPE in MTL_RXP_Control_Status register */ @@ -1767,9 +1783,11 @@ static nve32_t mgbe_update_frp_nve(struct osi_core_priv_data *const osi_core, 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; + ret = 0; + +done: + return ret; } -#endif /* !OSI_STRIPPED_LIB */ /** * @brief update_rfa_rfd - Update RFD and RSA values @@ -1888,9 +1906,9 @@ static void update_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value) * @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) + struct osi_core_priv_data *osi_core, + nveu32_t tx_fifo, + nveu32_t rx_fifo) { nveu32_t value = 0; nve32_t ret = 0; @@ -2002,9 +2020,9 @@ end: * @retval -1 on failure. */ static nve32_t mgbe_rss_write_reg(struct osi_core_priv_data *osi_core, - nveu32_t idx, - nveu32_t value, - nveu32_t is_key) + nveu32_t idx, + nveu32_t value, + nveu32_t is_key) { nveu8_t *addr = (nveu8_t *)osi_core->base; nveu32_t retry = 100; @@ -2118,7 +2136,7 @@ static nve32_t mgbe_config_rss(struct osi_core_priv_data *osi_core) * @retval -1 on failure. */ static nve32_t mgbe_config_flow_control(struct osi_core_priv_data *const osi_core, - const nveu32_t flw_ctrl) + const nveu32_t flw_ctrl) { nveu32_t val; void *addr = osi_core->base; @@ -2188,7 +2206,7 @@ static nve32_t mgbe_config_flow_control(struct osi_core_priv_data *const osi_cor * @retval -1 on failure */ static nve32_t mgbe_hsi_configure(struct osi_core_priv_data *const osi_core, - const nveu32_t enable) + const nveu32_t enable) { nveu32_t value = 0U; nve32_t ret = 0; @@ -2643,195 +2661,6 @@ static void mgbe_core_backup_init(struct osi_core_priv_data *const osi_core) /* 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) -{ - nveu32_t mtl_est_ir = OSI_DISABLE; - - mtl_est_ir = osi_readla(osi_core, (nveu8_t *) - 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, - (nveu8_t *)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) -{ - nveu32_t value = OSI_DISABLE; - - /* Read MAC IER Register and enable Frame Preemption Interrupt - * Enable */ - value = osi_readla(osi_core, (nveu8_t *) - osi_core->base + MGBE_MAC_IER); - value |= MGBE_IMR_FPEIE; - osi_writela(osi_core, value, (nveu8_t *) - 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; - nveu32_t 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}; - nveu32_t 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 == 0U) || - (osi_core->hw_feature->gcl_width > 3U)) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Wrong HW feature GCL width\n", - (nveul64_t)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 == 0U) || - (osi_core->hw_feature->gcl_depth > 5U)) { - /* Do Nothing */ - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Wrong HW feature GCL depth\n", - (nveul64_t)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, - nveu32_t est_sel, nveu32_t fpe_sel) -{ - nveu32_t val = 0x0; - nveu32_t temp = 0U; - - if (est_sel == OSI_ENABLE) { - mgbe_save_gcl_params(osi_core); - val = osi_readla(osi_core, (nveu8_t *)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; - 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, (nveu8_t *)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, (nveu8_t *)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, (nveu8_t *)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 - */ -} #endif /* !OSI_STRIPPED_LIB */ /** @@ -2918,8 +2747,8 @@ static nve32_t mgbe_dma_chan_to_vmirq_map(struct osi_core_priv_data *osi_core) * @retval -1 on failure. */ static nve32_t mgbe_core_init(struct osi_core_priv_data *const osi_core, - nveu32_t tx_fifo_size, - nveu32_t rx_fifo_size) + nveu32_t tx_fifo_size, + nveu32_t rx_fifo_size) { nve32_t ret = 0; nveu32_t qinx = 0; @@ -2995,18 +2824,15 @@ static nve32_t mgbe_core_init(struct osi_core_priv_data *const osi_core, /* configure MGBE DMA */ mgbe_configure_dma(osi_core); -#ifndef OSI_STRIPPED_LIB /* 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); + hw_tsn_init(osi_core, osi_core->hw_feature->est_sel, + osi_core->hw_feature->fpe_sel); } -#endif /* !OSI_STRIPPED_LIB */ return mgbe_dma_chan_to_vmirq_map(osi_core); } -#ifndef OSI_STRIPPED_LIB /** * @brief mgbe_handle_mac_fpe_intrs * @@ -3060,7 +2886,6 @@ static void mgbe_handle_mac_fpe_intrs(struct osi_core_priv_data *osi_core) osi_writela(osi_core, val, (nveu8_t *) osi_core->base + MGBE_MAC_FPE_CTS); } -#endif /* !OSI_STRIPPED_LIB */ /** * @brief Get free timestamp index from TS array by validating in_use param @@ -3100,8 +2925,8 @@ static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core, { struct core_local *l_core = (struct core_local *)osi_core; nveu32_t mac_isr = 0; -#ifndef OSI_STRIPPED_LIB nveu32_t mac_ier = 0; +#ifndef OSI_STRIPPED_LIB nveu32_t tx_errors = 0; #endif /* !OSI_STRIPPED_LIB */ @@ -3124,7 +2949,6 @@ static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core, } } -#ifndef OSI_STRIPPED_LIB mac_ier = osi_readla(osi_core, (nveu8_t *)osi_core->base + MGBE_MAC_IER); if (((mac_isr & MGBE_MAC_IMR_FPEIS) == MGBE_MAC_IMR_FPEIS) && @@ -3132,6 +2956,7 @@ static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core, mgbe_handle_mac_fpe_intrs(osi_core); } +#ifndef OSI_STRIPPED_LIB /* 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 @@ -3268,6 +3093,7 @@ static inline void mgbe_update_dma_sr_stats(struct osi_core_priv_data *osi_core, osi_update_stats_counter(val, 1U); } } +#endif /* !OSI_STRIPPED_LIB */ /** * @brief mgbe_set_avb_algorithm - Set TxQ/TC avb config @@ -3305,7 +3131,7 @@ static nve32_t mgbe_set_avb_algorithm( OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "avb structure is NULL\n", 0ULL); - return ret; + goto done; } /* queue index in range */ @@ -3313,7 +3139,7 @@ static nve32_t mgbe_set_avb_algorithm( OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid Queue index\n", (nveul64_t)avb->qindex); - return ret; + goto done; } /* queue oper_mode in range check*/ @@ -3321,7 +3147,7 @@ static nve32_t mgbe_set_avb_algorithm( OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid Queue mode\n", (nveul64_t)avb->qindex); - return ret; + goto done; } /* Validate algo is valid */ @@ -3329,7 +3155,7 @@ static nve32_t mgbe_set_avb_algorithm( OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid Algo input\n", (nveul64_t)avb->tcindex); - return ret; + goto done; } /* can't set AVB mode for queue 0 */ @@ -3337,7 +3163,7 @@ static nve32_t mgbe_set_avb_algorithm( OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OPNOTSUPP, "Not allowed to set AVB for Q0\n", (nveul64_t)avb->qindex); - return ret; + goto done; } /* TC index range check */ @@ -3345,7 +3171,7 @@ static nve32_t mgbe_set_avb_algorithm( OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid Queue TC mapping\n", (nveul64_t)avb->tcindex); - return ret; + goto done; } qinx = avb->qindex; @@ -3427,7 +3253,10 @@ static nve32_t mgbe_set_avb_algorithm( MGBE_MTL_CHX_TX_OP_MODE(qinx)); } - return 0; + ret = 0; + +done: + return ret; } /** @@ -3454,7 +3283,7 @@ static nve32_t mgbe_set_avb_algorithm( * @retval -1 on failure. */ static nve32_t mgbe_get_avb_algorithm(struct osi_core_priv_data *const osi_core, - struct osi_core_avb_algorithm *const avb) + struct osi_core_avb_algorithm *const avb) { nveu32_t value; nve32_t ret = -1; @@ -3547,7 +3376,7 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core, nveu32_t frm_err = 0U; nveu32_t temp = 0U; nveu32_t i = 0; - unsigned long stat_val = 0U; + nveul64_t stat_val = 0U; nveu32_t value = 0U; nveu32_t qstatus = 0U; nveu32_t qinx = 0U; @@ -3555,12 +3384,12 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core, /* 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)) { + if ((mtl_isr & OSI_BIT(qinx)) == OSI_BIT(qinx)) { /* check if Q has underflow error */ qstatus = osi_readl((nveu8_t *)osi_core->base + MGBE_MTL_QINT_STATUS(qinx)); /* Transmit Queue Underflow Interrupt Status */ - if (qstatus & MGBE_MTL_QINT_TXUNIFS) { + if ((qstatus & MGBE_MTL_QINT_TXUNIFS) == MGBE_MTL_QINT_TXUNIFS) { #ifndef OSI_STRIPPED_LIB osi_core->pkt_err_stats.mgbe_tx_underflow_err = osi_update_stats_counter( @@ -3575,7 +3404,7 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core, } if ((mtl_isr & MGBE_MTL_IS_ESTIS) != MGBE_MTL_IS_ESTIS) { - return; + goto done; } val = osi_readla(osi_core, @@ -3586,7 +3415,7 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core, /* return if interrupt is not related to EST */ if (val == OSI_DISABLE) { - return; + goto done; } /* increase counter write 1 back will clear */ @@ -3684,11 +3513,12 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core, 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, (nveu8_t *)osi_core->base + - MGBE_MTL_INTR_STATUS); +done: + return; } +#ifndef OSI_STRIPPED_LIB + /** * @brief mgbe_config_ptp_offload - Enable/Disable PTP offload * @@ -3705,7 +3535,7 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core, */ static nve32_t mgbe_config_ptp_offload(struct osi_core_priv_data *const osi_core, - struct osi_pto_config *const pto_config) + struct osi_pto_config *const pto_config) { nveu8_t *addr = (nveu8_t *)osi_core->base; nve32_t ret = 0; @@ -3929,10 +3759,8 @@ static void mgbe_handle_common_intr(struct osi_core_priv_data *const osi_core) nveu32_t i = 0; nveu32_t dma_sr = 0; nveu32_t dma_ier = 0; -#ifndef OSI_STRIPPED_LIB nveu32_t mtl_isr = 0; nveu32_t val = 0; -#endif /* !OSI_STRIPPED_LIB */ #ifdef HSI_SUPPORT if (osi_core->hsi.enabled == OSI_ENABLE) { @@ -3941,7 +3769,7 @@ static void mgbe_handle_common_intr(struct osi_core_priv_data *const osi_core) #endif dma_isr = osi_readla(osi_core, (nveu8_t *)base + MGBE_DMA_ISR); if (dma_isr == OSI_NONE) { - return; + goto done; } //FIXME Need to check how we can get the DMA channel here instead of @@ -3985,7 +3813,6 @@ static void mgbe_handle_common_intr(struct osi_core_priv_data *const osi_core) mgbe_handle_mac_intrs(osi_core, dma_isr); -#ifndef OSI_STRIPPED_LIB /* Handle MTL inerrupts */ mtl_isr = osi_readla(osi_core, (nveu8_t *)base + MGBE_MTL_INTR_STATUS); @@ -4009,7 +3836,9 @@ static void mgbe_handle_common_intr(struct osi_core_priv_data *const osi_core) 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); -#endif /* !OSI_STRIPPED_LIB */ + +done: + return; } /** @@ -4274,9 +4103,9 @@ static inline nve32_t mgbe_restore_registers( * @retval -1 on failure. */ static nve32_t mgbe_write_phy_reg(struct osi_core_priv_data *osi_core, - nveu32_t phyaddr, - nveu32_t phyreg, - nveu16_t phydata) + nveu32_t phyaddr, + nveu32_t phyreg, + nveu16_t phydata) { nve32_t ret = 0; nveu32_t reg; @@ -4346,8 +4175,8 @@ static nve32_t mgbe_write_phy_reg(struct osi_core_priv_data *osi_core, * @retval -1 on failure. */ static nve32_t mgbe_read_phy_reg(struct osi_core_priv_data *osi_core, - nveu32_t phyaddr, - nveu32_t phyreg) + nveu32_t phyaddr, + nveu32_t phyreg) { nveu32_t reg; nveu32_t data; @@ -4405,340 +4234,6 @@ static nve32_t mgbe_read_phy_reg(struct osi_core_priv_data *osi_core, } #ifndef OSI_STRIPPED_LIB -/** - * @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 nve32_t mgbe_hw_est_write(struct osi_core_priv_data *osi_core, - nveu32_t addr_val, nveu32_t data, - nveu32_t gcla) -{ - nve32_t retry = 1000; - nveu32_t val = 0x0; - - osi_writela(osi_core, data, (nveu8_t *)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, (nveu8_t *)osi_core->base + - MGBE_MTL_EST_GCL_CONTROL); - - while (--retry > 0) { - osi_core->osd_ops.udelay(OSI_DELAY_1US); - val = osi_readla(osi_core, (nveu8_t *)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 nve32_t mgbe_hw_config_est(struct osi_core_priv_data *const osi_core, - struct osi_est_config *const est) -{ - nveu32_t btr[2] = {0}; - nveu32_t val = 0x0; - void *base = osi_core->base; - nveu32_t i; - nve32_t ret = 0; - nveu32_t 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, (nveu8_t *) - base + MGBE_MTL_EST_CONTROL); - val &= ~MGBE_MTL_EST_EEST; - osi_writela(osi_core, val, (nveu8_t *) - 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", - (nveul64_t)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", - (nveul64_t)(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", - (nveul64_t)(btr[1] + - est->btr_offset[1])); - return ret; - } - - val = osi_readla(osi_core, (nveu8_t *) - 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, (nveu8_t *) - 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 nve32_t mgbe_hw_config_fpe(struct osi_core_priv_data *const osi_core, - struct osi_fpe_config *const fpe) -{ - nveu32_t i = 0U; - nveu32_t val = 0U; - nveu32_t temp = 0U, temp1 = 0U; - nveu32_t temp_shift = 0U; - nve32_t 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, (nveu8_t *) - 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, (nveu8_t *) - 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, (nveu8_t *) - osi_core->base + MGBE_MTL_FPE_CTS); - val |= MGBE_MAC_FPE_CTS_SVER; - osi_writela(osi_core, val, (nveu8_t *) - osi_core->base + MGBE_MAC_FPE_CTS); - - val = osi_readla(osi_core, (nveu8_t *) - 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, (nveu8_t *) - 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. * @@ -4866,7 +4361,7 @@ static void mgbe_configure_eee(struct osi_core_priv_data *const osi_core, #endif /* !OSI_STRIPPED_LIB */ static nve32_t mgbe_get_hw_features(struct osi_core_priv_data *const osi_core, - struct osi_hw_features *hw_feat) + struct osi_hw_features *hw_feat) { nveu8_t *base = (nveu8_t *)osi_core->base; nveu32_t mac_hfr0 = 0; @@ -5086,9 +4581,9 @@ static inline nve32_t mgbe_poll_for_update_ts_complete( * @retval -1 on failure. */ static nve32_t mgbe_adjust_mactime(struct osi_core_priv_data *osi_core, - nveu32_t sec, nveu32_t nsec, - nveu32_t add_sub, - nveu32_t one_nsec_accuracy) + nveu32_t sec, nveu32_t nsec, + nveu32_t add_sub, + nveu32_t one_nsec_accuracy) { void *addr = osi_core->base; nveu32_t mac_tcr; @@ -5169,7 +4664,7 @@ static nve32_t mgbe_adjust_mactime(struct osi_core_priv_data *osi_core, * @retval 0 */ static nveu32_t mgbe_read_reg(struct osi_core_priv_data *const osi_core, - const nve32_t reg) + const nve32_t reg) { return osi_readla(osi_core, (nveu8_t *)osi_core->base + reg); } @@ -5354,7 +4849,7 @@ static void mgbe_config_for_macsec(struct osi_core_priv_data *const osi_core, if ((enable != OSI_ENABLE) && (enable != OSI_DISABLE)) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Failed to config MGBE per MACSEC\n", 0ULL); - goto exit; + goto done; } /* stop MAC Tx */ mgbe_config_mac_tx(osi_core, OSI_DISABLE); @@ -5416,7 +4911,7 @@ static void mgbe_config_for_macsec(struct osi_core_priv_data *const osi_core, 0ULL); } } -exit: +done: return; } #endif /* MACSEC_SUPPORT */ @@ -5439,6 +4934,11 @@ void mgbe_init_core_ops(struct core_ops *ops) ops->update_ip4_addr = mgbe_update_ip4_addr; ops->read_reg = mgbe_read_reg; ops->write_reg = mgbe_write_reg; + ops->set_avb_algorithm = mgbe_set_avb_algorithm; + ops->get_avb_algorithm = mgbe_get_avb_algorithm; + ops->config_frp = mgbe_config_frp; + ops->update_frp_entry = mgbe_update_frp_entry; + ops->update_frp_nve = mgbe_update_frp_nve; #ifdef MACSEC_SUPPORT ops->read_macsec_reg = mgbe_read_macsec_reg; ops->write_macsec_reg = mgbe_write_macsec_reg; @@ -5456,8 +4956,6 @@ void mgbe_init_core_ops(struct core_ops *ops) ops->config_arp_offload = mgbe_config_arp_offload; ops->config_ptp_offload = mgbe_config_ptp_offload; ops->validate_regs = mgbe_validate_core_regs; - ops->set_avb_algorithm = mgbe_set_avb_algorithm; - ops->get_avb_algorithm = mgbe_get_avb_algorithm, ops->config_vlan_filtering = mgbe_config_vlan_filtering; ops->reset_mmc = mgbe_reset_mmc; ops->configure_eee = mgbe_configure_eee; @@ -5465,11 +4963,6 @@ void mgbe_init_core_ops(struct core_ops *ops) ops->restore_registers = mgbe_restore_registers; ops->set_mdc_clk_rate = mgbe_set_mdc_clk_rate; ops->config_mac_loopback = mgbe_config_mac_loopback; - 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->config_rss = mgbe_config_rss; ops->config_ptp_rxq = mgbe_config_ptp_rxq; #endif /* !OSI_STRIPPED_LIB */ diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 8a2a498..90de78e 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -26,6 +26,7 @@ #ifndef OSI_STRIPPED_LIB #define MGBE_MAC_PFR 0x0008 #define MGBE_MAC_RX_FLW_CTRL 0x0090 +#define MGBE_MAC_RQC2R 0x00A8 #define MGBE_MAC_QX_TX_FLW_CTRL(x) ((0x0004U * (x)) + 0x0070U) #define MGBE_MAC_ARPPA 0x0C10 #define MGBE_MAC_LPI_CSR 0x00D0 @@ -34,84 +35,31 @@ #define MGBE_MAC_RSS_CTRL 0x0C80 #define MGBE_MAC_RSS_ADDR 0x0C88 #define MGBE_MAC_RSS_DATA 0x0C8C +#define MGBE_MAC_STSR 0x0D08 +#define MGBE_MAC_STNSR 0x0D0C #define MGBE_MAC_PTO_CR 0x0DC0 #define MGBE_MAC_PIDR0 0x0DC4 #define MGBE_MAC_PIDR1 0x0DC8 #define MGBE_MAC_PIDR2 0x0DCC #define MGBE_MAC_PMTCSR 0x00C0 #define MGBE_MAC_HTR_REG(x) ((0x0004U * (x)) + 0x0010U) -#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_ITRE 0x1070 -#define MGBE_MTL_EST_GCL_CONTROL 0x1080 -#define MGBE_MTL_EST_DATA 0x1084 -#define MGBE_MAC_STSR 0x0D08 -#define MGBE_MAC_STNSR 0x0D0C #define MGBE_MAC_RX_TX_STS 0x00B8 -#define MGBE_MAC_RQC4R 0x0094 -#define MGBE_MAC_RQC2R 0x00A8 -#define MGBE_MAC_FPE_CTS 0x0280 -#define MGBE_MTL_TCQ_ETS_HCR(x) ((0x0080U * (x)) + 0x1120U) -#define MGBE_MTL_TCQ_ETS_LCR(x) ((0x0080U * (x)) + 0x1124U) -#define MGBE_MTL_TCQ_ETS_SSCR(x) ((0x0080U * (x)) + 0x111CU) #define MGBE_WRAP_AXI_ASID0_CTRL 0x8400 #define MGBE_WRAP_AXI_ASID1_CTRL 0x8404 #define MGBE_WRAP_AXI_ASID2_CTRL 0x8408 -#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 -#define MGBE_MTL_QINT_STATUS(x) ((0x0080U * (x)) + 0x1174U) -#define MGBE_MTL_OP_MODE 0x1000 -#define MGBE_MTL_INTR_STATUS 0x1020 -#define MGBE_MTL_FPE_CTS 0x1090 -#define MGBE_MTL_FPE_ADV 0x1094 - #define MGBE_MAC_PFR_VTFE OSI_BIT(16) #define MGBE_MAC_PFR_IPFE OSI_BIT(20) #define MGBE_MAC_PFR_IPFE_SHIFT 20 -#define MGBE_MTL_TCQ_ETS_CR_AVALG_SHIFT 0U -#define MGBE_MTL_QINT_TXUNIFS OSI_BIT(0) -#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_SID_VAL1(x) (((x) << 24U) |\ ((x) << 16U) |\ ((x) << 8U) |\ (x)) #define MGBE_SID_VAL2(x) (((x) << 8U) |\ (x)) - -#define MGBE_MTL_TCQ_ETS_CR_CC OSI_BIT(3) -#define MGBE_MTL_TCQ_ETS_CR_CC_SHIFT 3U -#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 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_8PTP_CYCLE 26U -#define MGBE_DMA_ISR_MTLIS OSI_BIT(16) -#define MGBE_IMR_FPEIE OSI_BIT(15) -#define MGBE_MAC_EXT_CNF_EIPG 0x1U -#define MGBE_MAC_EXT_CNF_EIPG_MASK 0x7FU -#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_MAC_RX_FLW_CTRL_RFE OSI_BIT(0) -#define MGBE_MAC_STNSR_TSSS_MASK 0x7FFFFFFFU -#define MGBE_MAC_TCR_SNAPTYPSEL_SHIFT 16U -#define MGBE_MAC_TCR_TSENMACADDR OSI_BIT(18) -#define MGBE_MAC_TMCR_IPG_MASK 0x700U -#define MGBE_MAC_RQC1R_RQ_SHIFT 4U #define MGBE_MAC_PAUSE_TIME 0xFFFF0000U #define MGBE_MAC_PAUSE_TIME_MASK 0xFFFF0000U #define MGBE_MAC_TX_TJT OSI_BIT(0) @@ -130,83 +78,16 @@ /** @} */ #define MGBE_MAX_VLAN_FILTER 32U -/* 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 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) -/* EST GCRA addresses */ -#define MGBE_MTL_EST_BTR_LOW ((nveu32_t)0x0 << \ - MGBE_MTL_EST_ADDR_SHIFT) -#define MGBE_MTL_EST_BTR_HIGH ((nveu32_t)0x1 << \ - MGBE_MTL_EST_ADDR_SHIFT) -#define MGBE_MTL_EST_CTR_LOW ((nveu32_t)0x2 << \ - MGBE_MTL_EST_ADDR_SHIFT) -#define MGBE_MTL_EST_CTR_HIGH ((nveu32_t)0x3 << \ - MGBE_MTL_EST_ADDR_SHIFT) -#define MGBE_MTL_EST_CTR_HIGH_MAX 0xFFU -#define MGBE_MTL_EST_TER ((nveu32_t)0x4 << \ - MGBE_MTL_EST_ADDR_SHIFT) -#define MGBE_MTL_EST_LLR ((nveu32_t)0x5 << \ - MGBE_MTL_EST_ADDR_SHIFT) - -#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_DDBF OSI_BIT(4) -#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 - -#define MGBE_MAC_TX_PCE OSI_BIT(13) -/* 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_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 - -#define MGBE_MAC_IMR_FPEIS OSI_BIT(16) #define MGBE_MAC_L3L4_CTR_L4DPIM0_SHIFT 21 #define MGBE_MAC_L3L4_CTR_L4PEN0 OSI_BIT(16) #define MGBE_MAC_L3L4_CTR_L4SPIM0_SHIFT 19 #define MGBE_MAC_L3_AD2R 0x6 #define MGBE_MAC_L3_AD3R 0x7 -#define MGBE_MAC_FPE_CTS_RRSP OSI_BIT(17) +#define MGBE_MAC_RX_FLW_CTRL_RFE OSI_BIT(0) +#define MGBE_MAC_STNSR_TSSS_MASK 0x7FFFFFFFU +#define MGBE_MAC_TCR_SNAPTYPSEL_SHIFT 16U +#define MGBE_MAC_TCR_TSENMACADDR OSI_BIT(18) +#define MGBE_MAC_TMCR_IPG_MASK 0x700U #define MGBE_MAC_RQC1R_PTPQ_SHIFT 24U #define MGBE_MAC_RQC1R_PTPQ (OSI_BIT(27) | OSI_BIT(26) | \ OSI_BIT(25) | OSI_BIT(24)) @@ -224,7 +105,7 @@ #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_PCE OSI_BIT(13) /** * @addtogroup - MGBE-LPI LPI configuration macros * @@ -264,6 +145,95 @@ OSI_BIT(11) | OSI_BIT(10) | \ OSI_BIT(9) | OSI_BIT(8)) #define MGBE_MAC_PTO_CR_DN_SHIFT 8U +#define MGBE_DMA_CHX_STATUS_RPS OSI_BIT(8) +#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_FBE OSI_BIT(12) + +#define MGBE_MAC_L4_ADDR 0x1 +#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_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_PFR_VTFE_SHIFT 16 +#define MGBE_MAC_PIDR_PID_MASK 0XFFFFU + +#endif /* !OSI_STRIPPED_LIB */ + +#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_ITRE 0x1070 +#define MGBE_MTL_EST_GCL_CONTROL 0x1080 +#define MGBE_MTL_EST_DATA 0x1084 +#define MGBE_MAC_RQC4R 0x0094 +#define MGBE_MAC_FPE_CTS 0x0280 +#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 + +#define MGBE_MTL_TCQ_ETS_HCR(x) ((0x0080U * (x)) + 0x1120U) +#define MGBE_MTL_TCQ_ETS_LCR(x) ((0x0080U * (x)) + 0x1124U) +#define MGBE_MTL_TCQ_ETS_SSCR(x) ((0x0080U * (x)) + 0x111CU) +#define MGBE_MTL_OP_MODE 0x1000 +#define MGBE_MTL_INTR_STATUS 0x1020 +#define MGBE_MTL_FPE_CTS 0x1090 +#define MGBE_MTL_FPE_ADV 0x1094 + +#define MGBE_MTL_QINT_STATUS(x) ((0x0080U * (x)) + 0x1174U) +#define MGBE_MTL_TCQ_ETS_CR_AVALG_SHIFT 0U +#define MGBE_MTL_QINT_TXUNIFS OSI_BIT(0) +#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_TCQ_ETS_CR_CC OSI_BIT(3) +#define MGBE_MTL_TCQ_ETS_CR_CC_SHIFT 3U +#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_8PTP_CYCLE 26U +#define MGBE_DMA_ISR_MTLIS OSI_BIT(16) +#define MGBE_IMR_FPEIE OSI_BIT(15) +#ifndef OSI_STRIPPED_LIB +#define MGBE_MAC_EXT_CNF_EIPG 0x1U +#define MGBE_MAC_EXT_CNF_EIPG_MASK 0x7FU +#endif /* !OSI_STRIPPED_LIB */ +#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_MAC_RQC1R_RQ_SHIFT 4U +#define MGBE_MTL_EST_EEST OSI_BIT(0) +/* EST GCL controlOSI_BITmap */ +#define MGBE_MTL_EST_ADDR_SHIFT 8 +/*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) +/* 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_RVER OSI_BIT(16) +#define MGBE_MAC_FPE_CTS_SVER OSI_BIT(1) +#define MGBE_MAC_FPE_CTS_SRSP OSI_BIT(2) +/* MTL FPE adv registers */ +#define MGBE_MAC_IMR_FPEIS OSI_BIT(16) +#define MGBE_MAC_FPE_CTS_RRSP OSI_BIT(17) /* MTL_EST_CONTROL */ #define MGBE_MTL_EST_CONTROL_PTOV (OSI_BIT(23) | OSI_BIT(24) | \ OSI_BIT(25) | OSI_BIT(26) | \ @@ -280,6 +250,8 @@ OSI_BIT(21) | OSI_BIT(22)) #define MGBE_MTL_EST_CONTROL_CTOV_SHIFT 11U #define MGBE_MTL_EST_CTOV_RECOMMEND 42U +#define MGBE_MAC_RQC1R_RQ (OSI_BIT(7) | OSI_BIT(6) | \ + OSI_BIT(5) | OSI_BIT(4)) /** * @addtogroup MGBE-MTL FRP Indirect Access register defines @@ -346,27 +318,6 @@ OSI_BIT(3) | OSI_BIT(2) | \ OSI_BIT(1) | OSI_BIT(0)) /** @} */ -#define MGBE_DMA_CHX_STATUS_RPS OSI_BIT(8) -#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_FBE OSI_BIT(12) - -#define MGBE_MAC_L4_ADDR 0x1 -#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_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_RQC1R_RQ (OSI_BIT(7) | OSI_BIT(6) | \ - OSI_BIT(5) | OSI_BIT(4)) -#define MGBE_MAC_PFR_VTFE_SHIFT 16 -#define MGBE_MAC_PIDR_PID_MASK 0XFFFFU - - -#endif /* !OSI_STRIPPED_LIB */ /** * @addtogroup MGBE MTL queue ETS algorithm mode @@ -667,6 +618,31 @@ */ #define MGBE_MTL_EST_CTOV_MACSEC_RECOMMEND 295U #endif /* MACSEC_SUPPORT */ +#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_DDBF OSI_BIT(4) +#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 GCL controlOSI_BITmap */ +#define MGBE_MTL_EST_ADDR_SHIFT 8 +/* EST GCRA addresses */ +#define MGBE_MTL_EST_BTR_LOW ((nveu32_t)0x0 << \ + MGBE_MTL_EST_ADDR_SHIFT) +#define MGBE_MTL_EST_BTR_HIGH ((nveu32_t)0x1 << \ + MGBE_MTL_EST_ADDR_SHIFT) +#define MGBE_MTL_EST_CTR_LOW ((nveu32_t)0x2 << \ + MGBE_MTL_EST_ADDR_SHIFT) +#define MGBE_MTL_EST_CTR_HIGH ((nveu32_t)0x3 << \ + MGBE_MTL_EST_ADDR_SHIFT) +#define MGBE_MTL_EST_TER ((nveu32_t)0x4 << \ + MGBE_MTL_EST_ADDR_SHIFT) +#define MGBE_MTL_EST_LLR ((nveu32_t)0x5 << \ + MGBE_MTL_EST_ADDR_SHIFT) +/*EST MTL interrupt STATUS and ERR*/ +#define MGBE_MTL_IS_ESTIS OSI_BIT(18) + #define MGBE_MAC_EXT_CNF_DDS OSI_BIT(7) /* TX timestamp */ #define MGBE_MAC_TSS_TXTSC OSI_BIT(15) diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index c8592fc..e2f657d 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -1036,57 +1036,6 @@ static nve32_t conf_eee(struct osi_core_priv_data *const osi_core, 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 nve32_t 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 *)(void *)osi_core; - - if (cmd == OSI_NULL) { - OSI_CORE_ERR(osi_core->osd, 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. * @@ -1187,6 +1136,63 @@ static nve32_t conf_mac_loopback(struct osi_core_priv_data *const osi_core, return l_core->ops_p->config_mac_loopback(osi_core, lb_mode); } +#endif /* !OSI_STRIPPED_LIB */ + +/** + * @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 nve32_t 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 *)(void *)osi_core; + nve32_t ret; + + if (cmd == OSI_NULL) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "FRP command invalid\n", 0ULL); + ret = -1; + goto done; + } + + /* Check for supported MAC version */ + if ((osi_core->mac == OSI_MAC_HW_EQOS) && + (osi_core->mac_ver < OSI_EQOS_MAC_5_30)) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "MAC doesn't support FRP\n", OSI_NONE); + ret = -1; + goto done; + } + + ret = setup_frp(osi_core, l_core->ops_p, cmd); +done: + return ret; +} /** * @brief config_est - Read Setting for GCL from input and update @@ -1231,12 +1237,13 @@ static nve32_t conf_mac_loopback(struct osi_core_priv_data *const osi_core, 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 *)(void *)osi_core; + nve32_t ret; if (est == OSI_NULL) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "EST data is NULL", 0ULL); - return -1; + ret = -1; + goto done; } if ((osi_core->flow_ctrl & OSI_FLOW_CTRL_TX) == @@ -1244,10 +1251,14 @@ static nve32_t config_est(struct osi_core_priv_data *osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "TX Flow control enabled, please disable it", 0ULL); - return -1; + ret = -1; + goto done; } - return l_core->ops_p->hw_config_est(osi_core, est); + ret = hw_config_est(osi_core, est); + +done: + return ret; } /** @@ -1286,17 +1297,20 @@ static nve32_t config_est(struct osi_core_priv_data *osi_core, 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 *)(void *)osi_core; + nve32_t ret; if (fpe == OSI_NULL) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "FPE data is NULL", 0ULL); - return -1; + ret = -1; + goto done; } - return l_core->ops_p->hw_config_fpe(osi_core, fpe); + ret = hw_config_fpe(osi_core, fpe); + +done: + return ret; } -#endif /* !OSI_STRIPPED_LIB */ /** * @brief Free stale timestamps for channel @@ -1645,6 +1659,14 @@ static void cfg_fc(struct core_local *l_core) l_core->cfg.flow_ctrl); } +static void cfg_eee(struct core_local *l_core) +{ + (void)conf_eee((struct osi_core_priv_data *)(void *)l_core, + l_core->cfg.tx_lpi_enabled, + l_core->cfg.tx_lpi_timer); +} +#endif /* !OSI_STRIPPED_LIB */ + static void cfg_avb(struct core_local *l_core) { nveu32_t i; @@ -1659,13 +1681,6 @@ static void cfg_avb(struct core_local *l_core) } } -static void cfg_eee(struct core_local *l_core) -{ - (void)conf_eee((struct osi_core_priv_data *)(void *)l_core, - l_core->cfg.tx_lpi_enabled, - l_core->cfg.tx_lpi_timer); -} - static void cfg_est(struct core_local *l_core) { (void)config_est((struct osi_core_priv_data *)(void *)l_core, @@ -1677,7 +1692,6 @@ static void cfg_fpe(struct core_local *l_core) (void)config_fpe((struct osi_core_priv_data *)(void *)l_core, &l_core->cfg.fpe); } -#endif /* !OSI_STRIPPED_LIB */ static void cfg_ptp(struct core_local *l_core) { @@ -1701,11 +1715,11 @@ static void apply_dynamic_cfg(struct osi_core_priv_data *osi_core) #ifndef OSI_STRIPPED_LIB [DYNAMIC_CFG_VLAN_IDX] = cfg_vlan, [DYNAMIC_CFG_FC_IDX] = cfg_fc, - [DYNAMIC_CFG_AVB_IDX] = cfg_avb, [DYNAMIC_CFG_EEE_IDX] = cfg_eee, +#endif /* !OSI_STRIPPED_LIB */ + [DYNAMIC_CFG_AVB_IDX] = cfg_avb, [DYNAMIC_CFG_EST_IDX] = cfg_est, [DYNAMIC_CFG_FPE_IDX] = cfg_fpe, -#endif /* !OSI_STRIPPED_LIB */ [DYNAMIC_CFG_PTP_IDX] = cfg_ptp }; nveu32_t flags = l_core->cfg.flags; @@ -1778,7 +1792,8 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, #endif if (validate_args(osi_core, l_core) < 0) { - return ret; + ret = -1; + goto done; } ops_p = l_core->ops_p; @@ -1786,7 +1801,8 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, if (data == OSI_NULL) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "CORE: Invalid argument\n", 0ULL); - return -1; + ret = -1; + goto done; } switch (data->cmd) { @@ -1839,21 +1855,6 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, 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); - if (ret == 0) { - (void)osi_memcpy(&l_core->cfg.avb[data->avb.qindex].avb_info, - &data->avb, sizeof(struct osi_core_avb_algorithm)); - l_core->cfg.avb[data->avb.qindex].used = OSI_ENABLE; - l_core->cfg.flags |= DYNAMIC_CFG_AVB; - } - - break; - case OSI_CMD_CONFIG_RX_CRC_CHECK: ret = ops_p->config_rx_crc_check(osi_core, data->arg1_u32); break; @@ -1900,8 +1901,21 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, } break; - #endif /* !OSI_STRIPPED_LIB */ + 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); + if (ret == 0) { + (void)osi_memcpy(&l_core->cfg.avb[data->avb.qindex].avb_info, + &data->avb, sizeof(struct osi_core_avb_algorithm)); + l_core->cfg.avb[data->avb.qindex].used = OSI_ENABLE; + l_core->cfg.flags |= DYNAMIC_CFG_AVB; + } + break; + case OSI_CMD_CONFIG_FW_ERR: ret = hw_config_fw_err_pkts(osi_core, data->arg1_u32, data->arg2_u32); break; @@ -2161,14 +2175,15 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, 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; +#endif /* !OSI_STRIPPED_LIB */ + case OSI_CMD_CONFIG_FRP: + ret = configure_frp(osi_core, &data->frp_cmd); + break; + case OSI_CMD_CONFIG_EST: ret = config_est(osi_core, &data->est); if (ret == 0) { @@ -2188,7 +2203,7 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, } break; -#endif /* !OSI_STRIPPED_LIB */ + case OSI_CMD_READ_REG: ret = (nve32_t) ops_p->read_reg(osi_core, (nve32_t) data->arg1_u32); break; @@ -2278,6 +2293,7 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, break; } +done: return ret; } From 56233beeb68772ac69cf42679afbb58bd4df8d04 Mon Sep 17 00:00:00 2001 From: Sanath Kumar Gampa <sgampa@nvidia.com> Date: Thu, 18 Aug 2022 15:52:56 +0530 Subject: [PATCH 399/458] osi: macsec: Fix CERT INT31-C issues in macsec Bug 3745813 Change-Id: I36ea0483857d82bc60277be33f279057689ffef1 Signed-off-by: Sanath Kumar Gampa <sgampa@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2763014 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-by: Sachin Nikam <snikam@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- osi/core/macsec.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/osi/core/macsec.c b/osi/core/macsec.c index ad5605a..c2c9ecd 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -4779,7 +4779,7 @@ static nve32_t del_upd_sc(struct osi_core_priv_data *const osi_core, 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); + table_config->index = (nveu16_t)(existing_sc->sc_idx_start & 0xFFU); ret = macsec_lut_config(osi_core, &lut_config); if (ret < 0) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, @@ -4812,8 +4812,8 @@ static nve32_t del_upd_sc(struct osi_core_priv_data *const osi_core, /* 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); + table_config->index = (nveu16_t)(((existing_sc->sc_idx_start * OSI_MAX_NUM_SA) + + sc->curr_an) & (0xFFU)); ret = macsec_lut_config(osi_core, &lut_config); if (ret < 0) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, @@ -4823,8 +4823,8 @@ static nve32_t del_upd_sc(struct osi_core_priv_data *const osi_core, } /* Store key table index returned to osd */ - *kt_idx = (nveu16_t)((existing_sc->sc_idx_start * OSI_MAX_NUM_SA) + - sc->curr_an); + *kt_idx = (nveu16_t)(((existing_sc->sc_idx_start * OSI_MAX_NUM_SA) + + sc->curr_an) & (0xFFU)); #ifdef MACSEC_KEY_PROGRAM /* 5. Key LUT */ table_config = &kt_config.table_config; @@ -4945,7 +4945,7 @@ static void add_upd_sc_err_cleanup(struct osi_core_priv_data *const osi_core, 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); + table_config->index = (nveu16_t)(sc->sc_idx_start & 0xFFU); ret_fail = macsec_lut_config(osi_core, &lut_config); print_error(osi_core, ret_fail); } @@ -4956,7 +4956,7 @@ static void add_upd_sc_err_cleanup(struct osi_core_priv_data *const osi_core, 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); + table_config->index = (nveu16_t)(sc->sc_idx_start & 0xFFU); ret_fail = macsec_lut_config(osi_core, &lut_config); print_error(osi_core, ret_fail); } @@ -5078,7 +5078,7 @@ static nve32_t add_upd_sc(struct osi_core_priv_data *const osi_core, /* 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); + table_config->index = (nveu16_t)(sc->sc_idx_start & 0xFFU); 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) * From 99647c64ea9b095239863b3e296ea44b05358e76 Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Mon, 19 Sep 2022 22:35:22 +0530 Subject: [PATCH 400/458] nvethernetrm: update filename and location Update file name to be added in SDK Bug 3704251 Change-Id: Ibc6b53a6c152973f249d8af94a33cd537b1ea7ec Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2778302 Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- include/mmc.h | 2 +- osi/common/type.h => include/nvethernet_type.h | 0 include/nvethernetrm_export.h | 2 +- include/osi_common.h | 2 +- osi/common/common.h | 2 +- osi/core/mgbe_core.c | 1 - osi/dma/eqos_dma.c | 1 - 7 files changed, 4 insertions(+), 6 deletions(-) rename osi/common/type.h => include/nvethernet_type.h (100%) diff --git a/include/mmc.h b/include/mmc.h index 1231557..ef45f66 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -23,7 +23,7 @@ #ifndef INCLUDED_MMC_H #define INCLUDED_MMC_H -#include "../osi/common/type.h" +#include <nvethernet_type.h> #include "osi_common.h" #ifndef OSI_STRIPPED_LIB diff --git a/osi/common/type.h b/include/nvethernet_type.h similarity index 100% rename from osi/common/type.h rename to include/nvethernet_type.h diff --git a/include/nvethernetrm_export.h b/include/nvethernetrm_export.h index bd5ea96..2baf54f 100644 --- a/include/nvethernetrm_export.h +++ b/include/nvethernetrm_export.h @@ -23,7 +23,7 @@ #ifndef INCLUDED_NVETHERNETRM_EXPORT_H #define INCLUDED_NVETHERNETRM_EXPORT_H -#include "../osi/common/type.h" +#include <nvethernet_type.h> /** * @addtogroup Helper MACROS diff --git a/include/osi_common.h b/include/osi_common.h index 6e3f27f..b9bd1e3 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -23,7 +23,7 @@ #ifndef INCLUDED_OSI_COMMON_H #define INCLUDED_OSI_COMMON_H -#include "../osi/common/type.h" +#include <nvethernet_type.h> /** * @addtogroup FC Flow Control Threshold Macros diff --git a/osi/common/common.h b/osi/common/common.h index 5944292..8191356 100644 --- a/osi/common/common.h +++ b/osi/common/common.h @@ -22,7 +22,7 @@ #ifndef INCLUDED_COMMON_H #define INCLUDED_COMMON_H -#include "../osi/common/type.h" +#include <nvethernet_type.h> #include <osi_common.h> /** diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index f3100e3..582c75e 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -21,7 +21,6 @@ */ #include "../osi/common/common.h" -#include "../osi/common/type.h" #include <local_common.h> #include <osi_common.h> #include <osi_core.h> diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index e9ff1a6..cca4687 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -23,7 +23,6 @@ #include "../osi/common/common.h" #include "dma_local.h" #include "eqos_dma.h" -#include "../osi/common/type.h" #ifndef OSI_STRIPPED_LIB /** From 287f0799f7fe57d50a3c386ea1b4d05822944988 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Thu, 8 Sep 2022 11:37:37 +0530 Subject: [PATCH 401/458] osi: dma: increment rx_buf_len for alignment Issue: If the DMA buffer address is not aligned with EQOS/MGBE system bus width then data will be lost. Fix: Add 15bytes extra at head portion for alignment and 15byte extra to cover tail portion of the buffer. Bug 3572785 Change-Id: Ic0ce1e052cb6e952eba25fbc0cf696affca605cb Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2716666 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Hareesh Kesireddy <hkesireddy@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- osi/dma/osi_dma.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 5a6ba85..23706f5 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -477,7 +477,13 @@ static void init_dma_channel(const struct osi_dma_priv_data *const osi_dma, val = osi_readl((nveu8_t *)osi_dma->base + rx_ctrl_reg[osi_dma->mac]); val &= ~DMA_CHX_RBSZ_MASK; - val |= (osi_dma->rx_buf_len << DMA_CHX_RBSZ_SHIFT); + /** Subtract 30 bytes again which were added for buffer address alignment + * HW don't need those extra 30 bytes. If data length received more than + * below programed value then it will result in two descriptors which + * eventually drop by OSI. Subtracting 30 bytes so that HW don't receive + * unwanted length data. + **/ + val |= ((osi_dma->rx_buf_len - 30U) << DMA_CHX_RBSZ_SHIFT); if (osi_dma->mac == OSI_MAC_HW_EQOS) { val |= rx_pbl[osi_dma->mac]; } else { @@ -903,6 +909,12 @@ nve32_t osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) /* Buffer alignment */ osi_dma->rx_buf_len = ((rx_buf_len + (AXI_BUS_WIDTH - 1U)) & ~(AXI_BUS_WIDTH - 1U)); + + /* Add 30 bytes (15bytes extra at head portion for alignment and 15bytes + * extra to cover tail portion) again for the buffer address alignment + */ + osi_dma->rx_buf_len += 30U; + fail: return ret; } From 65559ee9bca42e6871db711395d6b1dee500f8a7 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Wed, 7 Sep 2022 12:33:29 +0530 Subject: [PATCH 402/458] osi: dma: Fix CERT issues Analysis summary report: Defects/Coding rule violations found : 3 Total CERT_INT30-C 3 - (Deviation Not approved) Total 3 ===== DIFF ====== Total cert violation count changed by -44 Rule: CERT_INT30-C Diff: -44 Rule: Total Diff: -44 Jira NET-224 Change-Id: I0cdbece05a61f4b22e4447d7cedc6ca401bd5736 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2772787 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/dma/dma_local.h | 7 ++++--- osi/dma/osi_dma.c | 14 +++++++++----- osi/dma/osi_dma_txrx.c | 9 ++++++--- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/osi/dma/dma_local.h b/osi/dma/dma_local.h index 7c87e89..f2001b4 100644 --- a/osi/dma/dma_local.h +++ b/osi/dma/dma_local.h @@ -161,7 +161,7 @@ nve32_t init_desc_ops(const struct osi_dma_priv_data *const osi_dma); * * @param[in, out] osi_dma: OSI DMA private data. * @param[in] tx_ring: DMA Tx ring. - * @param[in] chan: DMA Tx channel number. Max OSI_EQOS_MAX_NUM_CHANS. + * @param[in] dma_chan: DMA Tx channel number. Max OSI_EQOS_MAX_NUM_CHANS. * * @note * API Group: @@ -171,7 +171,7 @@ nve32_t init_desc_ops(const struct osi_dma_priv_data *const osi_dma); */ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, struct osi_tx_ring *tx_ring, - nveu32_t chan); + nveu32_t dma_chan); /* Function prototype needed for misra */ @@ -213,9 +213,10 @@ static inline nveu32_t is_power_of_two(nveu32_t num) #define H32(data) ((nveu32_t)(((data) & 0xFFFFFFFF00000000UL) >> 32UL)) static inline void update_rx_tail_ptr(const struct osi_dma_priv_data *const osi_dma, - nveu32_t chan, + nveu32_t dma_chan, nveu64_t tailptr) { + nveu32_t chan = dma_chan & 0xFU; const nveu32_t tail_ptr_reg[2] = { EQOS_DMA_CHX_RDTP(chan), MGBE_DMA_CHX_RDTLP(chan) diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 23706f5..b3b1899 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -366,8 +366,9 @@ fail: return ret; } -static inline void start_dma(const struct osi_dma_priv_data *const osi_dma, nveu32_t chan) +static inline void start_dma(const struct osi_dma_priv_data *const osi_dma, nveu32_t dma_chan) { + nveu32_t chan = dma_chan & 0xFU; const nveu32_t tx_dma_reg[2] = { EQOS_DMA_CHX_TX_CTRL(chan), MGBE_DMA_CHX_TX_CTRL(chan) @@ -391,8 +392,10 @@ static inline void start_dma(const struct osi_dma_priv_data *const osi_dma, nveu } static void init_dma_channel(const struct osi_dma_priv_data *const osi_dma, - nveu32_t chan) + nveu32_t dma_chan) { + nveu32_t chan = dma_chan & 0xFU; + nveu32_t riwt = osi_dma->rx_riwt & 0xFFFU; const nveu32_t intr_en_reg[2] = { EQOS_DMA_CHX_INTR_ENA(chan), MGBE_DMA_CHX_INTR_ENA(chan) @@ -423,9 +426,9 @@ static void init_dma_channel(const struct osi_dma_priv_data *const osi_dma, ((MGBE_RXQ_SIZE / osi_dma->num_dma_chans) / 2U) }; const nveu32_t rwt_val[2] = { - (((osi_dma->rx_riwt * (EQOS_AXI_CLK_FREQ / OSI_ONE_MEGA_HZ)) / + (((riwt * (EQOS_AXI_CLK_FREQ / OSI_ONE_MEGA_HZ)) / EQOS_DMA_CHX_RX_WDT_RWTU) & EQOS_DMA_CHX_RX_WDT_RWT_MASK), - (((osi_dma->rx_riwt * ((nveu32_t)MGBE_AXI_CLK_FREQ / OSI_ONE_MEGA_HZ)) / + (((riwt * ((nveu32_t)MGBE_AXI_CLK_FREQ / OSI_ONE_MEGA_HZ)) / MGBE_DMA_CHX_RX_WDT_RWTU) & MGBE_DMA_CHX_RX_WDT_RWT_MASK) }; const nveu32_t rwtu_val[2] = { @@ -608,8 +611,9 @@ fail: } static inline void stop_dma(const struct osi_dma_priv_data *const osi_dma, - nveu32_t chan) + nveu32_t dma_chan) { + nveu32_t chan = dma_chan & 0xFU; const nveu32_t dma_tx_reg[2] = { EQOS_DMA_CHX_TX_CTRL(chan), MGBE_DMA_CHX_TX_CTRL(chan) diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 5a6037d..6cd651f 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -979,7 +979,7 @@ fail: nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, struct osi_tx_ring *tx_ring, - nveu32_t chan) + nveu32_t dma_chan) { struct dma_local *l_dma = (struct dma_local *)(void *)osi_dma; struct osi_tx_pkt_cx *tx_pkt_cx = OSI_NULL; @@ -992,6 +992,7 @@ nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, nveu32_t f_idx = tx_ring->cur_tx_idx; nveu32_t l_idx = 0; #endif /* OSI_DEBUG */ + nveu32_t chan = dma_chan & 0xFU; const nveu32_t tail_ptr_reg[2] = { EQOS_DMA_CHX_TDTP(chan), MGBE_DMA_CHX_TDTLP(chan) @@ -1204,8 +1205,9 @@ fail: * @retval -1 on failure. */ static nve32_t rx_dma_desc_initialization(const struct osi_dma_priv_data *const osi_dma, - nveu32_t chan) + nveu32_t dma_chan) { + nveu32_t chan = dma_chan & 0xFU; const nveu32_t start_addr_high_reg[2] = { EQOS_DMA_CHX_RDLH(chan), MGBE_DMA_CHX_RDLH(chan) @@ -1345,9 +1347,10 @@ fail: static inline void set_tx_ring_len_and_start_addr(const struct osi_dma_priv_data *const osi_dma, nveu64_t tx_desc_phy_addr, - nveu32_t chan, + nveu32_t dma_chan, nveu32_t len) { + nveu32_t chan = dma_chan & 0xFU; const nveu32_t ring_len_reg[2] = { EQOS_DMA_CHX_TDRL(chan), MGBE_DMA_CHX_TX_CNTRL2(chan) From 8395e26ba1237459955cba7af41748b4fefcdc71 Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Mon, 19 Sep 2022 14:24:31 +0530 Subject: [PATCH 403/458] nvethernetrm: support L2 filter from ioctls Move L2 and L3 structure to osi_core as new structure at OSD level created to user data. Number of max L2 filter check based on mac version. Bug 3659048 Change-Id: I9e1e7c015e8c3a0579a363ccd6bcfe9d84e67eea Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2777333 Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- include/nvethernetrm_export.h | 82 +++-------------------------------- include/osi_common.h | 20 ++++++++- include/osi_core.h | 52 ++++++++++++++++++++++ osi/core/eqos_core.c | 5 ++- 4 files changed, 80 insertions(+), 79 deletions(-) diff --git a/include/nvethernetrm_export.h b/include/nvethernetrm_export.h index 2baf54f..d74538a 100644 --- a/include/nvethernetrm_export.h +++ b/include/nvethernetrm_export.h @@ -31,17 +31,11 @@ * @brief EQOS generic helper MACROS. * @{ */ -#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_MAX_TC_NUM 8U +/* Ethernet Address length */ +#define OSI_ETH_ALEN 6U +/** @} */ /** * @addtogroup Flexible Receive Parser related information @@ -74,21 +68,6 @@ #define OSI_MTL_TXQ_AVALG_SP 0U /** @} */ -/** - * @addtogroup Helper MACROS - * - * @brief EQOS generic helper MACROS. - * @{ - */ -/* L2 DA filter mode(enable/disable) */ -#define OSI_OPER_EN_L2_DA_INV OSI_BIT(4) -#define OSI_OPER_DIS_L2_DA_INV OSI_BIT(5) - -/* Ethernet Address length */ -#define OSI_ETH_ALEN 6U -#define OSI_MAX_TC_NUM 8U -/** @} */ - #pragma pack(push, 1) /** * @brief FRP command structure for OSD to OSI @@ -124,7 +103,7 @@ struct osi_core_avb_algorithm { 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. + * there is positive credit and no packet to transmit in the channel. * * Expected values are enable(1) or disable(0) */ nveu32_t credit_control; @@ -155,7 +134,7 @@ struct osi_est_config { /** enable/disable */ nveu32_t en_dis; /** 64 bit base time register - * if both vlaues are 0, take ptp time to avoid BTRE + * if both values are 0, take ptp time to avoid BTRE * index 0 for nsec, index 1 for sec */ nveu32_t btr[2]; @@ -184,55 +163,6 @@ struct osi_fpe_config { nveu32_t rq; }; -/** - * @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 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 OSI Core TSN error stats structure */ diff --git a/include/osi_common.h b/include/osi_common.h index b9bd1e3..baf296c 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -69,6 +69,24 @@ #define osi_unlikely(x) __builtin_expect(!!(x), 0) /** @} */ +/** + * @addtogroup Helper MACROS + * + * @brief EQOS generic helper MACROS. + * @{ + */ +#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_512 512U +#define OSI_GCL_SIZE_1024 1024U +/** @} */ + #ifndef OSI_STRIPPED_LIB /** @@ -80,7 +98,6 @@ #define OSI_PAUSE_FRAMES_ENABLE 0U #define OSI_PTP_REQ_CLK_FREQ 250000000U #define OSI_FLOW_CTRL_DISABLE 0U - #define OSI_ADDRESS_32BIT 0 #define OSI_ADDRESS_40BIT 1 #define OSI_ADDRESS_48BIT 2 @@ -197,7 +214,6 @@ #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) diff --git a/include/osi_core.h b/include/osi_core.h index 6f092f0..a49b72c 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -158,6 +158,7 @@ typedef my_lint_64 nvel64_t; */ #define EQOS_DMA_CHX_IER(x) ((0x0080U * (x)) + 0x1134U) #define EQOS_MAX_MAC_ADDRESS_FILTER 128U +#define EQOS_MAX_MAC_5_3_ADDRESS_FILTER 32U #define EQOS_MAX_L3_L4_FILTER 8U #define OSI_MGBE_MAX_MAC_ADDRESS_FILTER 32U #define OSI_DA_MATCH 0U @@ -189,6 +190,8 @@ typedef my_lint_64 nvel64_t; #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) @@ -423,6 +426,34 @@ extern nveu32_t hsi_err_code[][3]; 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; +}; + #ifndef OSI_STRIPPED_LIB /** * @brief OSI core structure for RXQ route @@ -438,6 +469,27 @@ struct osi_rxq_route { }; #endif +/** + * @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. */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index df7a0c8..029dd43 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -2621,6 +2621,7 @@ static nve32_t eqos_update_mac_addr_low_high_reg( struct osi_core_priv_data *const osi_core, const struct osi_filter *filter) { + const struct core_local *l_core = (struct core_local *)(void *)osi_core; nveu32_t idx = filter->index; nveu32_t dma_routing_enable = filter->dma_routing; nveu32_t dma_chan = filter->dma_chan; @@ -2628,8 +2629,10 @@ static nve32_t eqos_update_mac_addr_low_high_reg( nveu32_t src_dest = filter->src_dest; nveu32_t value = OSI_DISABLE; nve32_t ret = 0; + const nveu32_t eqos_max_madd[2] = {EQOS_MAX_MAC_ADDRESS_FILTER, + EQOS_MAX_MAC_5_3_ADDRESS_FILTER}; - if ((idx > (EQOS_MAX_MAC_ADDRESS_FILTER - 0x1U)) || + if ((idx >= eqos_max_madd[l_core->l_mac_ver]) || (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", From 1e92b13064842f61e79c93a07c409a38f186b082 Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Thu, 8 Sep 2022 00:08:43 +0530 Subject: [PATCH 404/458] osi: core: Fix CERT/CERT ADV/Coverity issues **CERT report** ===== DIFF ====== Total cert violation count changed by -34 Rule: CERT_INT30-C Diff: -22 Rule: CERT_INT31-C Diff: -2 Rule: CERT_INT32-C Diff: -10 Rule: Total Diff: -34 **CERT ADV report** ===== DIFF ====== Total cert_adv violation count changed by -13 Rule: CERT_DCL37-C Diff: 1 Rule: CERT_EXP39-C Diff: -13 Rule: CERT_INT34-C Diff: -1 Rule: Total Diff: -13 **Coverity report** ===== DIFF ====== Total coverity violation count changed by -1 Rule: UNUSED_VALUE Diff: -1 Rule: Total Diff: -1 undef DRIFT_CAL since no longer used Bug 3695218 Change-Id: I6638e2954ec2a74a66a756713b389610534d207a Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2776244 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/core_common.c | 8 +++++--- osi/core/core_local.h | 8 +++++++- osi/core/eqos_core.c | 6 ++++-- osi/core/mgbe_core.c | 4 ++-- osi/core/osi_core.c | 14 ++++++++------ osi/core/osi_hal.c | 6 ++++-- 6 files changed, 30 insertions(+), 16 deletions(-) diff --git a/osi/core/core_common.c b/osi/core/core_common.c index c353206..51baef0 100644 --- a/osi/core/core_common.c +++ b/osi/core/core_common.c @@ -195,10 +195,11 @@ fail: nve32_t hw_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, - const nveu32_t qinx) + const nveu32_t q_inx) { void *addr = osi_core->base; nveu32_t tx_op_mode_val = 0U; + nveu32_t qinx = (q_inx & 0xFU); nveu32_t value; const nveu32_t tx_op_mode[2] = { EQOS_MTL_CHX_TX_OP_MODE(qinx), MGBE_MTL_CHX_TX_OP_MODE(qinx)}; @@ -214,10 +215,11 @@ nve32_t hw_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, } nve32_t hw_config_fw_err_pkts(struct osi_core_priv_data *osi_core, - const nveu32_t qinx, const nveu32_t enable_fw_err_pkts) + const nveu32_t q_inx, const nveu32_t enable_fw_err_pkts) { nveu32_t val; nve32_t ret = 0; + nveu32_t qinx = (q_inx & 0xFU); const nveu32_t rx_op_mode[2] = { EQOS_MTL_CHX_RX_OP_MODE(qinx), MGBE_MTL_CHX_RX_OP_MODE(qinx)}; const nveu32_t max_q[2] = { OSI_EQOS_MAX_NUM_QUEUES, @@ -353,7 +355,7 @@ void hw_config_tscr(struct osi_core_priv_data *const osi_core, OSI_UNUSED const #endif /* !OSI_STRIPPED_LIB */ { void *addr = osi_core->base; - struct core_local *l_core = (struct core_local *)osi_core; + struct core_local *l_core = (struct core_local *)(void *)osi_core; nveu32_t mac_tcr = 0U; #ifndef OSI_STRIPPED_LIB nveu32_t i = 0U, temp = 0U; diff --git a/osi/core/core_local.h b/osi/core/core_local.h index e069a5d..164678e 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -267,12 +267,16 @@ struct core_ops { /** * @brief constant values for drift MAC to MAC sync. */ -#ifndef DRIFT_CAL +/* No longer needed since DRIFT CAL is not used */ +#undef ENABLE_DRIFT_CAL +#ifdef ENABLE_DRIFT_CAL #define DRIFT_CAL 1 #define I_COMPONENT_BY_10 3 #define P_COMPONENT_BY_10 7 #define WEIGHT_BY_10 10 #define MAX_FREQ 85000000LL +#else +#define DRIFT_CAL 0 #endif #define EQOS_SEC_OFFSET 0xB08 #define EQOS_NSEC_OFFSET 0xB0C @@ -526,6 +530,7 @@ void hw_interface_init_core_ops(struct if_core_ops *if_ops_p); */ void ivc_interface_init_core_ops(struct if_core_ops *if_ops_p); +#ifdef ENABLE_DRIFT_CAL /** * @brief get osi pointer for PTP primary/sec interface * @@ -557,4 +562,5 @@ void ivc_interface_init_core_ops(struct if_core_ops *if_ops_p); * @retval NULL on failure. */ struct osi_core_priv_data *get_role_pointer(nveu32_t role); +#endif #endif /* INCLUDED_CORE_LOCAL_H */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 029dd43..907f799 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -860,13 +860,14 @@ void update_ehfc_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value) * @retval 0 on success * @retval -1 on failure. */ -static nve32_t eqos_configure_mtl_queue(nveu32_t qinx, +static nve32_t eqos_configure_mtl_queue(nveu32_t q_inx, struct osi_core_priv_data *const osi_core, nveu32_t tx_fifo, nveu32_t rx_fifo) { nveu32_t value = 0; nve32_t ret = 0; + nveu32_t qinx = (q_inx & 0xFU); ret = hw_flush_mtl_tx_queue(osi_core, qinx); if (ret < 0) { @@ -2545,12 +2546,13 @@ static inline nve32_t eqos_update_mac_addr_helper( */ static void eqos_l2_filter_delete(struct osi_core_priv_data *osi_core, nveu32_t *value, - const nveu32_t idx, + const nveu32_t filter_idx, const nveu32_t dma_routing_enable, const nveu32_t dma_chan) { nveu32_t dcs_check = *value; nveu32_t temp = OSI_DISABLE; + nveu32_t idx = (filter_idx & 0xFFU); osi_writela(osi_core, OSI_MAX_32BITS, (nveu8_t *)osi_core->base + EQOS_MAC_ADDRL((idx))); diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 582c75e..b8a3234 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -408,7 +408,7 @@ static nve32_t mgbe_update_mac_addr_low_high_reg( osi_writela(osi_core, OSI_MAX_32BITS, (nveu8_t *)osi_core->base + MGBE_MAC_ADDRL((idx))); - return 0; + return ret; } /* Add DMA channel to value in binary */ @@ -2922,7 +2922,7 @@ static inline nveu32_t get_free_ts_idx(struct core_local *l_core) 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; + struct core_local *l_core = (struct core_local *)(void *)osi_core; nveu32_t mac_isr = 0; nveu32_t mac_ier = 0; #ifndef OSI_STRIPPED_LIB diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 931298b..4930cc8 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -148,6 +148,7 @@ struct osi_core_priv_data *osi_get_core(void) return &g_core[i].osi_core; } +#ifdef ENABLE_DRIFT_CAL struct osi_core_priv_data *get_role_pointer(nveu32_t role) { nveu32_t i; @@ -167,10 +168,11 @@ struct osi_core_priv_data *get_role_pointer(nveu32_t role) return OSI_NULL; } +#endif nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core) { - struct core_local *l_core = (struct core_local *)osi_core; + struct core_local *l_core = (struct core_local *)(void *)osi_core; nve32_t ret = -1; if (osi_core == OSI_NULL) { @@ -240,7 +242,7 @@ 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; + struct core_local *l_core = (struct core_local *)(void *)osi_core; if (validate_if_args(osi_core, l_core) < 0) { return -1; @@ -253,7 +255,7 @@ nve32_t osi_write_phy_reg(struct osi_core_priv_data *const osi_core, 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; + struct core_local *l_core = (struct core_local *)(void *)osi_core; if (validate_if_args(osi_core, l_core) < 0) { return -1; @@ -265,7 +267,7 @@ nve32_t osi_read_phy_reg(struct osi_core_priv_data *const osi_core, 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; + struct core_local *l_core = (struct core_local *)(void *)osi_core; if (validate_if_args(osi_core, l_core) < 0) { return -1; @@ -277,7 +279,7 @@ nve32_t osi_hw_core_init(struct osi_core_priv_data *const osi_core, nve32_t osi_hw_core_deinit(struct osi_core_priv_data *const osi_core) { - struct core_local *l_core = (struct core_local *)osi_core; + struct core_local *l_core = (struct core_local *)(void *)osi_core; if (validate_if_args(osi_core, l_core) < 0) { return -1; @@ -289,7 +291,7 @@ nve32_t osi_hw_core_deinit(struct osi_core_priv_data *const 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; + struct core_local *l_core = (struct core_local *)(void *)osi_core; nve32_t ret = -1; if (validate_if_args(osi_core, l_core) < 0) { diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index e2f657d..d69f0f2 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -1343,6 +1343,7 @@ static inline void free_tx_ts(struct osi_core_priv_data *osi_core, } } +#if (!defined(ETHERNET_SERVER) && !defined(__QNX__)) || DRIFT_CAL /** * @brief read time counters from HW register * @@ -1380,6 +1381,7 @@ static void read_sec_ns(void *addr, nveu32_t mac, *nsec = ns1; } } +#endif /** * @brief Parses internal ts structure array and update time stamp if packet @@ -1403,7 +1405,7 @@ static inline nve32_t get_tx_ts(struct osi_core_priv_data *osi_core, struct osi_core_tx_ts const *head = &l_core->tx_ts_head; nve32_t ret = -1; nveu32_t count = 0U; -#if !defined(__QNX__) +#if !defined(ETHERNET_SERVER) && !defined(__QNX__) nveu32_t nsec, sec, temp_nsec; nvel64_t temp_val = 0LL; nvel64_t ts_val = 0LL; @@ -1424,7 +1426,7 @@ static inline nve32_t get_tx_ts(struct osi_core_priv_data *osi_core, } while ((temp != head) && (count < MAX_TX_TS_CNT)) { -#if !defined(__QNX__) +#if !defined(ETHERNET_SERVER) && !defined(__QNX__) temp_nsec = temp->nsec & ETHER_NSEC_MASK; temp_val = (nvel64_t)(temp->sec * OSI_1SEC_TO_NSEC) + (nvel64_t)temp_nsec; From 9e69b99908e72b820d3c8963fdc6eaab79a43560 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Wed, 21 Sep 2022 11:02:48 +0000 Subject: [PATCH 405/458] osi: mgbe: configure MTL RXFIFO and flow control MTL RXFIFO memory available for MGBE - 192KB Below is the distribution - 1) Q0 - 160KB 2) Q1 to Q8 - 2KB 3) Q9 - 16KB It also update flow control parameters for the Rx queues 1) Q0 - FULL_MINUS_32K 2) Q1 to Q9 - FULL_MINUS_1_5K Bug 3787316 Change-Id: I3049d742e784aa3273090191856482121a3e1d3e Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2779472 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_common.h | 4 -- osi/core/mgbe_core.c | 144 ++++++++++++------------------------------- osi/core/mgbe_core.h | 23 ------- 3 files changed, 38 insertions(+), 133 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index baf296c..a5c1e09 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -40,10 +40,6 @@ #define FULL_MINUS_6_K ((nveu32_t)10) #define FULL_MINUS_10_K ((nveu32_t)18) #define FULL_MINUS_16_K ((nveu32_t)30) -#define FULL_MINUS_18_K ((nveu32_t)34) -#define FULL_MINUS_21_K ((nveu32_t)40) -#define FULL_MINUS_24_K ((nveu32_t)46) -#define FULL_MINUS_29_K ((nveu32_t)56) #define FULL_MINUS_32_K ((nveu32_t)62) /** @} */ diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index b8a3234..1aaa8a7 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -1788,99 +1788,6 @@ done: return ret; } -/** - * @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(nveu32_t rx_fifo, nveu32_t *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 * @@ -1904,11 +1811,38 @@ static void update_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value) * @retval 0 on success * @retval -1 on failure. */ -static nve32_t mgbe_configure_mtl_queue(nveu32_t qinx, +static nve32_t mgbe_configure_mtl_queue(nveu32_t hw_qinx, struct osi_core_priv_data *osi_core, - nveu32_t tx_fifo, - nveu32_t rx_fifo) + nveu32_t tx_fifo) { + nveu32_t qinx = hw_qinx & 0xFU; + /* + * Total available Rx queue size is 192KB. + * Below is the destribution among the Rx queueu - + * Q0 - 160KB + * Q1 to Q8 - 2KB each = 8 * 2KB = 16KB + * Q9 - 16KB (MVBCQ) + * + * Formula to calculate the value to be programmed in HW + * + * vale= (size in KB / 256) - 1U + */ + const nveu32_t rx_fifo_sz[OSI_MGBE_MAX_NUM_QUEUES] = { + 160U, 2U, 2U, 2U, 2U, 2U, 2U, 2U, 2U, 16U, + }; + const nveu32_t rfd_rfa[OSI_MGBE_MAX_NUM_QUEUES] = { + FULL_MINUS_32_K, + FULL_MINUS_1_5K, + FULL_MINUS_1_5K, + FULL_MINUS_1_5K, + FULL_MINUS_1_5K, + FULL_MINUS_1_5K, + FULL_MINUS_1_5K, + FULL_MINUS_1_5K, + FULL_MINUS_1_5K, + FULL_MINUS_1_5K, + }; + nveu32_t rx_fifo_sz_t = 0U; nveu32_t value = 0; nve32_t ret = 0; @@ -1957,7 +1891,8 @@ static nve32_t mgbe_configure_mtl_queue(nveu32_t 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); + rx_fifo_sz_t = (((rx_fifo_sz[qinx] * 1024U) / 256U) - 1U); + value |= (rx_fifo_sz_t << MGBE_MTL_RXQ_SIZE_SHIFT); /* Enable Store and Forward mode */ value |= MGBE_MTL_RSF; /* Enable HW flow control */ @@ -1972,7 +1907,10 @@ static nve32_t mgbe_configure_mtl_queue(nveu32_t qinx, */ value = osi_readla(osi_core, (nveu8_t *)osi_core->base + MGBE_MTL_RXQ_FLOW_CTRL(qinx)); - update_rfa_rfd(rx_fifo, &value); + value &= ~MGBE_MTL_RXQ_OP_MODE_RFD_MASK; + value &= ~MGBE_MTL_RXQ_OP_MODE_RFA_MASK; + value |= (rfd_rfa[qinx] << MGBE_MTL_RXQ_OP_MODE_RFD_SHIFT) & MGBE_MTL_RXQ_OP_MODE_RFD_MASK; + value |= (rfd_rfa[qinx] << MGBE_MTL_RXQ_OP_MODE_RFA_SHIFT) & MGBE_MTL_RXQ_OP_MODE_RFA_MASK; osi_writela(osi_core, value, (nveu8_t *)osi_core->base + MGBE_MTL_RXQ_FLOW_CTRL(qinx)); @@ -2747,13 +2685,12 @@ static nve32_t mgbe_dma_chan_to_vmirq_map(struct osi_core_priv_data *osi_core) */ static nve32_t mgbe_core_init(struct osi_core_priv_data *const osi_core, nveu32_t tx_fifo_size, - nveu32_t rx_fifo_size) + OSI_UNUSED 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; #ifndef OSI_STRIPPED_LIB mgbe_core_backup_init(osi_core); @@ -2794,21 +2731,16 @@ static nve32_t mgbe_core_init(struct osi_core_priv_data *const osi_core, /* 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); + osi_core, tx_fifo); if (ret < 0) { return ret; } diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 90de78e..1f89cd9 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -648,28 +648,6 @@ #define MGBE_MAC_TSS_TXTSC OSI_BIT(15) /** @} */ -/** - * @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 * @@ -686,7 +664,6 @@ * @{ */ #define MGBE_TX_FIFO_SIZE_128KB 10U -#define MGBE_RX_FIFO_SIZE_192KB 12U /** @} */ #ifndef OSI_STRIPPED_LIB From e2edfc285b774061ba9185a75fd29792f61036be Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Wed, 14 Sep 2022 00:48:29 +0530 Subject: [PATCH 406/458] osi: core: Fix MISRA issues ===== DIFF ====== Total misra violation count changed by -71 Rule: MISRA_C-2012_Directive_4.5 Diff: -3 Rule: MISRA_C-2012_Rule_11.1 Diff: -5 Rule: MISRA_C-2012_Rule_11.3 Diff: -1 Rule: MISRA_C-2012_Rule_11.5 Diff: 1 Rule: MISRA_C-2012_Rule_12.1 Diff: -6 Rule: MISRA_C-2012_Rule_12.2 Diff: -7 Rule: MISRA_C-2012_Rule_15.1 Diff: -1 Rule: MISRA_C-2012_Rule_15.6 Diff: -1 Rule: MISRA_C-2012_Rule_16.1 Diff: -1 Rule: MISRA_C-2012_Rule_16.3 Diff: -1 Rule: MISRA_C-2012_Rule_17.7 Diff: -4 Rule: MISRA_C-2012_Rule_17.8 Diff: -5 Rule: MISRA_C-2012_Rule_2.4 Diff: -4 Rule: MISRA_C-2012_Rule_2.5 Diff: -18 Rule: MISRA_C-2012_Rule_20.5 Diff: -1 Rule: MISRA_C-2012_Rule_5.6 Diff: -1 Rule: MISRA_C-2012_Rule_5.8 Diff: -1 Rule: MISRA_C-2012_Rule_5.9 Diff: -4 Rule: MISRA_C-2012_Rule_8.3 Diff: -2 Rule: MISRA_C-2012_Rule_8.9 Diff: -5 Rule: MISRA_C-2012_Rule_9.5 Diff: -1 Rule: Total Diff: -71 Bug 3695218 Change-Id: I9bd904f8a77195ca34fb2d47639a214f0083ccf7 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2776281 Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- include/ivc_core.h | 8 +- include/nvethernetrm_export.h | 17 ++ include/osi_core.h | 14 +- osi/core/core_common.c | 52 +++--- osi/core/core_common.h | 14 +- osi/core/core_local.h | 21 ++- osi/core/eqos_core.c | 131 +++++--------- osi/core/eqos_core.h | 41 ++--- osi/core/ivc_core.c | 111 ++++++------ osi/core/macsec.c | 19 +-- osi/core/mgbe_core.c | 70 ++++---- osi/core/mgbe_core.h | 5 +- osi/core/mgbe_mmc.c | 312 +++++++++++++++++----------------- osi/core/osi_core.c | 15 +- osi/core/osi_hal.c | 11 +- osi/core/xpcs.c | 3 +- 16 files changed, 415 insertions(+), 429 deletions(-) diff --git a/include/ivc_core.h b/include/ivc_core.h index 9488686..e67ab11 100644 --- a/include/ivc_core.h +++ b/include/ivc_core.h @@ -46,7 +46,7 @@ struct osi_stats { /** * @brief IVC commands between OSD & OSI. */ -typedef enum ivc_cmd { +typedef enum { core_init = 1, core_deinit, write_phy_reg, @@ -73,7 +73,7 @@ typedef enum ivc_cmd { /** * @brief IVC arguments structure. */ -typedef struct ivc_args { +typedef struct { /** Number of arguments */ nveu32_t count; /** arguments */ @@ -83,7 +83,7 @@ typedef struct ivc_args { /** * @brief IVC core argument structure. */ -typedef struct ivc_core_args { +typedef struct { /** Number of MTL queues enabled in MAC */ nveu32_t num_mtl_queues; /** Array of MTL queues */ @@ -110,7 +110,7 @@ typedef struct ivc_core_args { * @brief macsec config structure. */ #ifdef MACSEC_SUPPORT -typedef struct macsec_config { +typedef struct { /** MACsec secure channel basic information */ struct osi_macsec_sc_info sc_info; /** MACsec enable or disable */ diff --git a/include/nvethernetrm_export.h b/include/nvethernetrm_export.h index d74538a..1dbbfb6 100644 --- a/include/nvethernetrm_export.h +++ b/include/nvethernetrm_export.h @@ -68,6 +68,23 @@ #define OSI_MTL_TXQ_AVALG_SP 0U /** @} */ +#ifndef OSI_STRIPPED_LIB +/** + * @addtogroup Helper MACROS + * + * @brief EQOS generic helper MACROS. + * @{ + */ +/* L2 DA filter mode(enable/disable) */ +#define OSI_OPER_EN_L2_DA_INV OSI_BIT(4) +#define OSI_OPER_DIS_L2_DA_INV OSI_BIT(5) +#endif /* !OSI_STRIPPED_LIB */ + +/* Ethernet Address length */ +#define OSI_ETH_ALEN 6U +#define OSI_MAX_TC_NUM 8U +/** @} */ + #pragma pack(push, 1) /** * @brief FRP command structure for OSD to OSI diff --git a/include/osi_core.h b/include/osi_core.h index a49b72c..a3d9f34 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -45,6 +45,8 @@ typedef my_lint_64 nvel64_t; /** @} */ #ifndef OSI_STRIPPED_LIB +#define OSI_OPER_EN_L2_DA_INV OSI_BIT(4) +#define OSI_OPER_DIS_L2_DA_INV OSI_BIT(5) #define OSI_PTP_SNAP_TRANSPORT 1U #define OSI_VLAN_ACTION_DEL 0x0U #define OSI_VLAN_ACTION_ADD OSI_BIT(31) @@ -125,13 +127,6 @@ typedef my_lint_64 nvel64_t; #define OSI_PTP_M2M_SECONDARY 2U /** @} */ -/** - * @addtogroup PTP PTP related information - * - *@brief 1 Second in NenoSec - */ -#define OSI_1SEC_TO_NSEC 1000000000LL -/** @} */ /** * @addtogroup EQOS_PTP PTP Helper MACROS @@ -190,8 +185,6 @@ typedef my_lint_64 nvel64_t; #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) @@ -220,7 +213,7 @@ typedef my_lint_64 nvel64_t; * @brief Ethernet PHY Interface Modes */ #define OSI_XFI_MODE_10G 0U -#define OSI_XFI_MODE_5G 1U +#define OSI_XFI_MODE_5G 1U #define OSI_USXGMII_MODE_10G 2U #define OSI_USXGMII_MODE_5G 3U @@ -238,7 +231,6 @@ typedef my_lint_64 nvel64_t; #define OSI_CMD_PAD_CALIBRATION 8U #define OSI_CMD_READ_MMC 9U #define OSI_CMD_GET_MAC_VER 10U -#define OSI_CMD_RESET_MMC 12U #define OSI_CMD_SET_MODE 16U #define OSI_CMD_SET_SPEED 17U #define OSI_CMD_L2_FILTER 18U diff --git a/osi/core/core_common.c b/osi/core/core_common.c index 51baef0..00fd99f 100644 --- a/osi/core/core_common.c +++ b/osi/core/core_common.c @@ -109,7 +109,7 @@ nve32_t hw_set_mode(struct osi_core_priv_data *const osi_core, const nve32_t mod void *base = osi_core->base; nveu32_t mcr_val; nve32_t ret = 0; - const nveu32_t set_bit[2] = { EQOS_MCR_DO, EQOS_MCR_DM }; + const nveu32_t bit_set[2] = { EQOS_MCR_DO, EQOS_MCR_DM }; const nveu32_t clear_bit[2] = { EQOS_MCR_DM, EQOS_MCR_DO }; /* don't allow only if loopback mode is other than 0 or 1 */ @@ -122,7 +122,7 @@ nve32_t hw_set_mode(struct osi_core_priv_data *const osi_core, const nve32_t mod if (osi_core->mac == OSI_MAC_HW_EQOS) { mcr_val = osi_readla(osi_core, (nveu8_t *)base + EQOS_MAC_MCR); - mcr_val |= set_bit[mode]; + mcr_val |= bit_set[mode]; mcr_val &= ~clear_bit[mode]; osi_writela(osi_core, mcr_val, ((nveu8_t *)base + EQOS_MAC_MCR)); } @@ -137,9 +137,9 @@ nve32_t hw_set_speed(struct osi_core_priv_data *const osi_core, const nve32_t sp void *base = osi_core->base; const nveu32_t mac_mcr[2] = { EQOS_MAC_MCR, MGBE_MAC_TMCR }; - if ((osi_core->mac == OSI_MAC_HW_EQOS && speed > OSI_SPEED_1000) || - (osi_core->mac == OSI_MAC_HW_MGBE && (speed < OSI_SPEED_2500 || - speed > OSI_SPEED_10000))) { + if (((osi_core->mac == OSI_MAC_HW_EQOS) && (speed > OSI_SPEED_1000)) || + ((osi_core->mac == OSI_MAC_HW_MGBE) && ((speed < OSI_SPEED_2500) || + (speed > OSI_SPEED_10000)))) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "unsupported speed\n", (nveul64_t)speed); ret = -1; @@ -148,11 +148,6 @@ nve32_t hw_set_speed(struct osi_core_priv_data *const osi_core, const nve32_t sp value = osi_readla(osi_core, ((nveu8_t *)base + mac_mcr[osi_core->mac])); switch (speed) { - default: - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "unsupported speed\n", (nveul64_t)speed); - ret = -1; - goto fail; case OSI_SPEED_10: value |= EQOS_MCR_PS; value &= ~EQOS_MCR_FES; @@ -174,7 +169,16 @@ nve32_t hw_set_speed(struct osi_core_priv_data *const osi_core, const nve32_t sp case OSI_SPEED_10000: value &= ~MGBE_MAC_TMCR_SS_10G; break; - + default: + if (osi_core->mac == OSI_MAC_HW_EQOS) { + value &= ~EQOS_MCR_PS; + value &= ~EQOS_MCR_FES; + } else if (osi_core->mac == OSI_MAC_HW_MGBE) { + value &= ~MGBE_MAC_TMCR_SS_10G; + } else { + /* Do Nothing */ + } + break; } osi_writela(osi_core, value, ((nveu8_t *)osi_core->base + mac_mcr[osi_core->mac])); @@ -199,10 +203,10 @@ nve32_t hw_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, { void *addr = osi_core->base; nveu32_t tx_op_mode_val = 0U; - nveu32_t qinx = (q_inx & 0xFU); + nveu32_t que_idx = (q_inx & 0xFU); nveu32_t value; - const nveu32_t tx_op_mode[2] = { EQOS_MTL_CHX_TX_OP_MODE(qinx), - MGBE_MTL_CHX_TX_OP_MODE(qinx)}; + const nveu32_t tx_op_mode[2] = { EQOS_MTL_CHX_TX_OP_MODE(que_idx), + MGBE_MTL_CHX_TX_OP_MODE(que_idx)}; /* Read Tx Q Operating Mode Register and flush TxQ */ value = osi_readla(osi_core, ((nveu8_t *)addr + tx_op_mode[osi_core->mac])); @@ -219,16 +223,16 @@ nve32_t hw_config_fw_err_pkts(struct osi_core_priv_data *osi_core, { nveu32_t val; nve32_t ret = 0; - nveu32_t qinx = (q_inx & 0xFU); - const nveu32_t rx_op_mode[2] = { EQOS_MTL_CHX_RX_OP_MODE(qinx), - MGBE_MTL_CHX_RX_OP_MODE(qinx)}; + nveu32_t que_idx = (q_inx & 0xFU); + const nveu32_t rx_op_mode[2] = { EQOS_MTL_CHX_RX_OP_MODE(que_idx), + MGBE_MTL_CHX_RX_OP_MODE(que_idx)}; const nveu32_t max_q[2] = { OSI_EQOS_MAX_NUM_QUEUES, OSI_MGBE_MAX_NUM_QUEUES}; - /* Check for valid enable_fw_err_pkts and qinx values */ - if ((enable_fw_err_pkts != OSI_ENABLE && - enable_fw_err_pkts != OSI_DISABLE) || - (qinx >= max_q[osi_core->mac])) { + /* Check for valid enable_fw_err_pkts and que_idx values */ + if (((enable_fw_err_pkts != OSI_ENABLE) && + (enable_fw_err_pkts != OSI_DISABLE)) || + (que_idx >= max_q[osi_core->mac])) { ret = -1; goto fail; } @@ -269,7 +273,7 @@ nve32_t hw_config_rxcsum_offload(struct osi_core_priv_data *const osi_core, const nveu32_t rxcsum_mode[2] = { EQOS_MAC_MCR, MGBE_MAC_RMCR}; const nveu32_t ipc_value[2] = { EQOS_MCR_IPC, MGBE_MAC_RMCR_IPC}; - if (enabled != OSI_ENABLE && enabled != OSI_DISABLE) { + if ((enabled != OSI_ENABLE) && (enabled != OSI_DISABLE)) { ret = -1; goto fail; } @@ -435,7 +439,7 @@ void hw_config_ssir(struct osi_core_priv_data *const osi_core) { nveul64_t val = 0U; void *addr = osi_core->base; - const struct core_local *l_core = (struct core_local *)osi_core; + const struct core_local *l_core = (struct core_local *)(void *)osi_core; const nveu32_t mac_ssir[2] = { EQOS_MAC_SSIR, MGBE_MAC_SSIR}; const nveu32_t ptp_ssinc[3] = {OSI_PTP_SSINC_4, OSI_PTP_SSINC_6, OSI_PTP_SSINC_4}; @@ -568,7 +572,7 @@ nve32_t hw_config_l3_l4_filter_enable(struct osi_core_priv_data *const osi_core, nve32_t ret = 0; /* validate filter_enb_dis argument */ - if (filter_enb_dis != OSI_ENABLE && filter_enb_dis != OSI_DISABLE) { + 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); diff --git a/osi/core/core_common.h b/osi/core/core_common.h index cd281d9..9cfac2a 100644 --- a/osi/core/core_common.h +++ b/osi/core/core_common.h @@ -24,7 +24,14 @@ #define INCLUDED_CORE_COMMON_H #include "core_local.h" + +#ifndef OSI_STRIPPED_LIB +#define MAC_PFR_PR OSI_BIT(0) +#define MAC_TCR_TSCFUPDT OSI_BIT(1) #define MAC_TCR_TSCTRLSSR OSI_BIT(9) +#define MAC_PFR_PM OSI_BIT(4) +#endif /* !OSI_STRIPPED_LIB */ + #define MTL_EST_ADDR_SHIFT 8 #define MTL_EST_ADDR_MASK (OSI_BIT(8) | OSI_BIT(9) | \ OSI_BIT(10) | OSI_BIT(11) | \ @@ -40,7 +47,6 @@ #define MTL_EST_ERR0 OSI_BIT(20) #define MTL_EST_CONTROL_EEST OSI_BIT(0) #define MTL_EST_STATUS_SWOL OSI_BIT(7) -#define MAC_TCR_TSCFUPDT OSI_BIT(1) /* EST control OSI_BIT map */ #define MTL_EST_EEST OSI_BIT(0) #define MTL_EST_SSWL OSI_BIT(1) @@ -71,9 +77,7 @@ #define MAC_PPS_CTL_PPSCTRL0 (OSI_BIT(3) | OSI_BIT(2) |\ OSI_BIT(1) | OSI_BIT(0)) #define MAC_SSIR_SSINC_SHIFT 16U -#define MAC_PFR_PR OSI_BIT(0) #define MAC_PFR_DAIF OSI_BIT(3) -#define MAC_PFR_PM OSI_BIT(4) #define MAC_PFR_DBF OSI_BIT(5) #define MAC_PFR_PCF (OSI_BIT(6) | OSI_BIT(7)) #define MAC_PFR_SAIF OSI_BIT(8) @@ -115,9 +119,9 @@ void hw_stop_mac(struct osi_core_priv_data *const osi_core); nve32_t hw_set_mode(struct osi_core_priv_data *const osi_core, const nve32_t mode); nve32_t hw_set_speed(struct osi_core_priv_data *const osi_core, const nve32_t speed); nve32_t hw_flush_mtl_tx_queue(struct osi_core_priv_data *const osi_core, - const nveu32_t qinx); + const nveu32_t q_inx); nve32_t hw_config_fw_err_pkts(struct osi_core_priv_data *osi_core, - const nveu32_t qinx, const nveu32_t enable_fw_err_pkts); + const nveu32_t q_inx, const nveu32_t enable_fw_err_pkts); nve32_t hw_config_rxcsum_offload(struct osi_core_priv_data *const osi_core, nveu32_t enabled); nve32_t hw_set_systime_to_mac(struct osi_core_priv_data *const osi_core, diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 164678e..583213c 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -106,8 +106,8 @@ struct if_core_ops { struct core_ops { /** 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); + nveu32_t tx_fifo_size, + nveu32_t rx_fifo_size); /** Called to handle common interrupt */ void (*handle_common_intr)(struct osi_core_priv_data *const osi_core); /** Called to do pad caliberation */ @@ -268,25 +268,29 @@ struct core_ops { * @brief constant values for drift MAC to MAC sync. */ /* No longer needed since DRIFT CAL is not used */ -#undef ENABLE_DRIFT_CAL #ifdef ENABLE_DRIFT_CAL #define DRIFT_CAL 1 #define I_COMPONENT_BY_10 3 #define P_COMPONENT_BY_10 7 #define WEIGHT_BY_10 10 #define MAX_FREQ 85000000LL +#define SERVO_STATS_0 0U +#define SERVO_STATS_1 1U +#define SERVO_STATS_2 2U #else #define DRIFT_CAL 0 #endif + +#if (!defined(ETHERNET_SERVER) && !defined(__QNX__)) || DRIFT_CAL #define EQOS_SEC_OFFSET 0xB08 #define EQOS_NSEC_OFFSET 0xB0C #define MGBE_SEC_OFFSET 0xD08 #define MGBE_NSEC_OFFSET 0xD0C #define ETHER_NSEC_MASK 0x7FFFFFFFU -#define SERVO_STATS_0 0U -#define SERVO_STATS_1 1U -#define SERVO_STATS_2 2U +#define OSI_1SEC_TO_NSEC 1000000000LL +#endif +#if DRIFT_CAL /** * @brief servo data structure. */ @@ -311,6 +315,7 @@ struct core_ptp_servo { /* MAC to MAC locking to access HW time register within OSI calls */ nveu32_t m2m_lock; }; +#endif /** * @brief L3/L4 dynamic config storage structure. @@ -409,7 +414,7 @@ struct core_local { /** 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; + nveu32_t num_max_chans; /** GCL depth supported by HW */ nveu32_t gcl_dep; /** Max GCL width (time + gate) value supported by HW */ @@ -418,8 +423,10 @@ struct core_local { nveu32_t ts_lock; /** Controller mac to mac role */ nveu32_t ether_m2m_role; +#if DRIFT_CAL /** Servo structure */ struct core_ptp_servo serv; +#endif /** 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 */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 907f799..596d60e 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -39,6 +39,7 @@ static nve32_t eqos_pre_pad_calibrate( struct osi_core_priv_data *const osi_core); #endif /* UPDATED_PAD_CAL */ +#ifndef OSI_STRIPPED_LIB /** * @brief eqos_core_safety_config - EQOS MAC core safety configuration */ @@ -82,7 +83,6 @@ static inline void eqos_core_safety_writel( osi_unlock_irq_enabled(&config->core_safety_lock); } -#ifndef OSI_STRIPPED_LIB /** * @brief Initialize the eqos_core_safety_config. * @@ -387,9 +387,7 @@ static nve32_t eqos_config_flow_control( } /* 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); + osi_writela(osi_core, val, (nveu8_t *)addr + EQOS_MAC_QX_TX_FLW_CTRL(0U)); /* Configure MAC Rx Flow control*/ /* Read MAC Rx Flow control Register */ @@ -595,9 +593,7 @@ static nve32_t eqos_pad_calibrate(struct osi_core_priv_data *const 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); + osi_writela(osi_core, value, (nveu8_t *)ioaddr + EQOS_PAD_AUTO_CAL_CFG); /* 4. Wait on 10 to 12 us before start checking for calibration done. * This delay is consumed in delay inside while loop. @@ -687,9 +683,8 @@ static nve32_t eqos_pad_calibrate(struct osi_core_priv_data *const 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); + osi_writela(osi_core, value, (nveu8_t *)ioaddr + EQOS_PAD_AUTO_CAL_CFG); + /* 4. Wait on 1 to 3 us before start checking for calibration done. * This delay is consumed in delay inside while loop. */ @@ -867,9 +862,9 @@ static nve32_t eqos_configure_mtl_queue(nveu32_t q_inx, { nveu32_t value = 0; nve32_t ret = 0; - nveu32_t qinx = (q_inx & 0xFU); + nveu32_t que_idx = (q_inx & 0xFU); - ret = hw_flush_mtl_tx_queue(osi_core, qinx); + ret = hw_flush_mtl_tx_queue(osi_core, que_idx); if (ret < 0) { return ret; } @@ -879,13 +874,11 @@ static nve32_t eqos_configure_mtl_queue(nveu32_t q_inx, 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); + osi_writela(osi_core, value, (nveu8_t *)osi_core->base + EQOS_MTL_CHX_TX_OP_MODE(que_idx)); /* read RX Q0 Operating Mode Register */ value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MTL_CHX_RX_OP_MODE(qinx)); + EQOS_MTL_CHX_RX_OP_MODE(que_idx)); value |= (rx_fifo << EQOS_MTL_RXQ_SIZE_SHIFT); /* Enable Store and Forward mode */ value |= EQOS_MTL_RSF; @@ -895,24 +888,19 @@ static nve32_t eqos_configure_mtl_queue(nveu32_t q_inx, * 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); + osi_writela(osi_core, value, (nveu8_t *)osi_core->base + EQOS_MTL_CHX_RX_OP_MODE(que_idx)); /* Transmit Queue weight */ value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MTL_TXQ_QW(qinx)); + EQOS_MTL_TXQ_QW(que_idx)); value |= EQOS_MTL_TXQ_QW_ISCQW; - eqos_core_safety_writel(osi_core, value, (nveu8_t *)osi_core->base + - EQOS_MTL_TXQ_QW(qinx), - EQOS_MTL_TXQ0_QW_IDX + qinx); + osi_writela(osi_core, value, (nveu8_t *)osi_core->base + EQOS_MTL_TXQ_QW(que_idx)); /* 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); + value |= ((osi_core->rxq_ctrl[que_idx] & EQOS_RXQ_EN_MASK) << (que_idx * 2U)); + osi_writela(osi_core, value, (nveu8_t *)osi_core->base + EQOS_MAC_RQC0R); return 0; } @@ -1275,9 +1263,7 @@ static void eqos_configure_rxq_priority( 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); + osi_writela(osi_core, val, (nveu8_t *)osi_core->base + EQOS_MAC_RQC2R); } } @@ -1308,8 +1294,7 @@ static nve32_t eqos_hsi_configure(struct osi_core_priv_data *const osi_core, 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); + osi_writela(osi_core, value, (nveu8_t *)osi_core->base + EQOS_MAC_IMR); /* T23X-EQOS_HSIv2-1: Enabling of Memory ECC */ value = osi_readla(osi_core, @@ -1375,8 +1360,7 @@ static nve32_t eqos_hsi_configure(struct osi_core_priv_data *const osi_core, 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); + osi_writela(osi_core, value, (nveu8_t *)osi_core->base + EQOS_MAC_IMR); /* T23X-EQOS_HSIv2-1: Disable of Memory ECC */ value = osi_readla(osi_core, @@ -1483,8 +1467,7 @@ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) /* 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); + osi_writela(osi_core, value, (nveu8_t *)osi_core->base + EQOS_MAC_MCR); /* Enable common interrupt at wrapper level */ if (osi_core->mac_ver >= OSI_EQOS_MAC_5_30) { @@ -1511,12 +1494,11 @@ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) /* 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; + value |= ((nveu32_t)EQOS_MAC_RQC1R_MCBCQ7) << EQOS_MAC_RQC1R_MCBCQ_SHIFT; } else { - value |= EQOS_MAC_RQC1R_MCBCQ3 << EQOS_MAC_RQC1R_MCBCQ_SHIFT; + value |= ((nveu32_t)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); + osi_writela(osi_core, value, (nveu8_t *)osi_core->base + EQOS_MAC_RQC1R); /* Disable all MMC interrupts */ /* Disable all MMC Tx Interrupts */ @@ -1544,8 +1526,7 @@ static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) /* 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); + osi_writela(osi_core, value, (nveu8_t *)osi_core->base + EQOS_MAC_IMR); /* Enable VLAN configuration */ value = osi_readla(osi_core, @@ -1628,9 +1609,7 @@ static void eqos_configure_dma(struct osi_core_priv_data *const osi_core) /* 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); + osi_writela(osi_core, value, (nveu8_t *)base + EQOS_DMA_SBUS); value = osi_readla(osi_core, (nveu8_t *)base + EQOS_DMA_BMR); value |= EQOS_DMA_BMR_DPSW; @@ -1709,8 +1688,8 @@ static void eqos_dma_chan_to_vmirq_map(struct osi_core_priv_data *osi_core) * @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) + nveu32_t tx_fifo_size, + nveu32_t rx_fifo_size) { nve32_t ret = 0; nveu32_t qinx = 0; @@ -1774,15 +1753,10 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core, 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); + osi_writela(osi_core, value, (nveu8_t *)osi_core->base + EQOS_MTL_RXQ_DMA_MAP0); 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); + osi_writela(osi_core, value1, (nveu8_t *)osi_core->base + EQOS_MTL_RXQ_DMA_MAP1); } if (osi_unlikely(osi_core->num_mtl_queues > OSI_EQOS_MAX_NUM_QUEUES)) { @@ -1993,14 +1967,17 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, /* set speed at MAC level */ /* TODO: set_tx_clk needs to be done */ /* Maybe through workqueue for QNX */ + /* hw_set_speed is treated as void since it is + * an internal functin which will be always success + */ if ((mac_pcs & EQOS_MAC_PCS_LNKSPEED) == EQOS_MAC_PCS_LNKSPEED_10) { - hw_set_speed(osi_core, OSI_SPEED_10); + (void)hw_set_speed(osi_core, OSI_SPEED_10); } else if ((mac_pcs & EQOS_MAC_PCS_LNKSPEED) == EQOS_MAC_PCS_LNKSPEED_100) { - hw_set_speed(osi_core, OSI_SPEED_100); + (void)hw_set_speed(osi_core, OSI_SPEED_100); } else if ((mac_pcs & EQOS_MAC_PCS_LNKSPEED) == EQOS_MAC_PCS_LNKSPEED_1000) { - hw_set_speed(osi_core, OSI_SPEED_1000); + (void)hw_set_speed(osi_core, OSI_SPEED_1000); } else { /* Nothing here */ } @@ -2424,16 +2401,12 @@ static void eqos_config_mac_tx(struct osi_core_priv_data *const osi_core, 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); + osi_writela(osi_core, value, (nveu8_t *)addr + EQOS_MAC_MCR); } 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); + osi_writela(osi_core, value, (nveu8_t *)addr + EQOS_MAC_MCR); } } #endif /* MACSEC_SUPPORT */ @@ -2791,8 +2764,7 @@ static nve32_t eqos_config_ptp_offload(struct osi_core_priv_data *const osi_core 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, value, addr + EQOS_MAC_TCR); 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); @@ -2845,8 +2817,7 @@ static nve32_t eqos_config_ptp_offload(struct osi_core_priv_data *const osi_core 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); + osi_writela(osi_core, value, addr + EQOS_MAC_TCR); /* 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); @@ -3545,9 +3516,7 @@ static nve32_t eqos_adjust_mactime(struct osi_core_priv_data *const osi_core, * 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); + osi_writela(osi_core, mac_tcr, (nveu8_t *)addr + EQOS_MAC_TCR); ret = eqos_poll_for_update_ts_complete(osi_core, &mac_tcr); if (ret == -1) { @@ -4270,9 +4239,7 @@ static nve32_t eqos_set_avb_algorithm( /* 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); + osi_writela(osi_core, value, (nveu8_t *)osi_core->base + EQOS_MTL_CHX_TX_OP_MODE(qinx)); /* Set Algo and Credit control */ value = OSI_DISABLE; @@ -4489,9 +4456,7 @@ static nve32_t eqos_config_arp_offload( mac_mcr &= ~EQOS_MCR_ARPEN; } - eqos_core_safety_writel(osi_core, mac_mcr, - (nveu8_t *)addr + EQOS_MAC_MCR, - EQOS_MAC_MCR_IDX); + osi_writela(osi_core, mac_mcr, (nveu8_t *)addr + EQOS_MAC_MCR); return 0; } @@ -4555,8 +4520,7 @@ static nve32_t eqos_config_vlan_filtering( 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); + osi_writela(osi_core, value, (nveu8_t *)base + EQOS_MAC_PFR); value = osi_readla(osi_core, (nveu8_t *)base + EQOS_MAC_VLAN_TR); value &= ~(EQOS_MAC_VLAN_TR_VTIM | EQOS_MAC_VLAN_TR_VTHM); @@ -4831,9 +4795,7 @@ static nve32_t eqos_config_mac_loopback( (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); + osi_writela(osi_core, mcr_val, (nveu8_t *)addr + EQOS_MAC_MCR); return 0; } @@ -5114,8 +5076,7 @@ static nve32_t eqos_pre_pad_calibrate(struct osi_core_priv_data *const osi_core) /* 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); + osi_writela(osi_core, value, (nveu8_t *)osi_core->base + EQOS_MAC_IMR); hw_stop_mac(osi_core); ret = poll_for_mii_idle(osi_core); if (ret < 0) { @@ -5152,8 +5113,7 @@ error: /* Read MAC IMR Register */ value = osi_readl((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); + osi_writela(osi_core, value, (nveu8_t *)osi_core->base + EQOS_MAC_IMR); return ret; } @@ -5208,8 +5168,7 @@ static nve32_t eqos_post_pad_calibrate( hw_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); + osi_writela(osi_core, mac_imr, (nveu8_t *)osi_core->base + EQOS_MAC_IMR); return ret; } #endif /* UPDATED_PAD_CAL */ diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index fd963f0..75a6268 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -642,6 +642,27 @@ void update_ehfc_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value); +#define EQOS_MAX_CORE_SAFETY_REGS 45U + +/** + * @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-Safety-Register EQOS Safety Register Mask * @@ -654,6 +675,7 @@ void update_ehfc_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value); * EQOS_MAX_CORE_SAFETY_REGS. * Using macro instead of enum due to misra error. */ +#ifndef OSI_STRIPPED_LIB #define EQOS_MAC_MCR_IDX 0U #define EQOS_MAC_PFR_IDX 1U #define EQOS_MAC_RQC0R_IDX 7U @@ -668,27 +690,8 @@ void update_ehfc_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value); #define EQOS_MTL_CH0_RX_OP_MODE_IDX 34U #define EQOS_DMA_SBUS_IDX 43U #define EQOS_MTL_RXQ_DMA_MAP1_IDX 44U -#define EQOS_MAX_CORE_SAFETY_REGS 45U /** @} */ -/** - * @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; -}; - -#ifndef OSI_STRIPPED_LIB /** * @addtogroup EQOS_HW EQOS HW BACKUP registers * diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index aec2d6e..1820778 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -30,11 +30,6 @@ #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 * @@ -55,29 +50,31 @@ static nve32_t ivc_handle_ioctl(struct osi_core_priv_data *osi_core, 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)); + /* osi_memcpy is treated as void since it is + * an internal functin which will be always success + */ + (void)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)); + (void)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)); - msg.status = osi_memcpy((void *)&osi_core->tsn_stats, - (void *)&msg.data.eth_stats.tsn_s, - sizeof(struct osi_tsn_stats)); + (void)osi_memcpy((void *)&osi_core->mmc, + (void *)&msg.data.mmc, + sizeof(struct osi_mmc_counters)); + (void)osi_memcpy((void *)&osi_core->tsn_stats, + (void *)&msg.data.eth_stats.tsn_s, + sizeof(struct osi_tsn_stats)); } else { - msg.status = osi_memcpy((void *)data, - (void *)&msg.data.ioctl_data, - sizeof(struct osi_ioctl)); + (void)osi_memcpy((void *)data, + (void *)&msg.data.ioctl_data, + sizeof(struct osi_ioctl)); } return ret; } @@ -214,18 +211,18 @@ static nve32_t ivc_macsec_dbg_events_config( 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)); + (void)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) { goto done; } - msg.status = osi_memcpy((void *)dbg_buf_config, - (void *)&msg.data.dbg_buf_config, - sizeof(struct osi_macsec_dbg_buf_config)); + (void)osi_memcpy((void *)dbg_buf_config, + (void *)&msg.data.dbg_buf_config, + sizeof(struct osi_macsec_dbg_buf_config)); done: return ret; } @@ -250,18 +247,18 @@ static nve32_t ivc_macsec_dbg_buf_config( 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)); + (void)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) { goto done; } - msg.status = osi_memcpy((void *)dbg_buf_config, - (void *) &msg.data.dbg_buf_config, - sizeof(struct osi_macsec_dbg_buf_config)); + (void)osi_memcpy((void *)dbg_buf_config, + (void *) &msg.data.dbg_buf_config, + sizeof(struct osi_macsec_dbg_buf_config)); done: return ret; } @@ -289,12 +286,12 @@ static void ivc_macsec_read_mmc(struct osi_core_priv_data *const osi_core) 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)); + (void)osi_memcpy((void *)&osi_core->macsec_mmc, + (void *) &msg.data.macsec_mmc, + sizeof(struct osi_macsec_mmc_counters)); + (void)osi_memcpy((void *)&osi_core->macsec_irq_stats, + (void *) &msg.data.macsec_irq_stats, + sizeof(struct osi_macsec_irq_stats)); } /** @@ -319,9 +316,9 @@ static nve32_t ivc_get_sc_lut_key_index(struct osi_core_priv_data *const osi_cor 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); + (void)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)); @@ -356,9 +353,9 @@ static nve32_t ivc_macsec_config(struct osi_core_priv_data *const osi_core, 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)); + (void)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; @@ -444,18 +441,18 @@ static nve32_t ivc_macsec_kt_config(struct osi_core_priv_data *const osi_core, 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)); + (void)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)); + (void)osi_memcpy((void *)kt_config, + (void *)&msg.data.kt_config, + sizeof(struct osi_macsec_kt_config)); return ret; } #endif /* MACSEC_KEY_PROGRAM */ @@ -502,18 +499,18 @@ static nve32_t ivc_macsec_lut_config(struct osi_core_priv_data *const osi_core, 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)); + (void)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) { goto done; } - msg.status = osi_memcpy((void *)lut_config, - (void *)&msg.data.lut_config, - sizeof(struct osi_macsec_lut_config)); + (void)osi_memcpy((void *)lut_config, + (void *)&msg.data.lut_config, + sizeof(struct osi_macsec_lut_config)); done: return ret; } @@ -614,6 +611,8 @@ void ivc_init_macsec_ops(void *macsecops) */ void *ivc_get_core_safety_config(void) { + static struct core_func_safety ivc_safety_config; + return &ivc_safety_config; } diff --git a/osi/core/macsec.c b/osi/core/macsec.c index c2c9ecd..e566a89 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -4440,7 +4440,7 @@ static void macsec_intr_config(struct osi_core_priv_data *const osi_core, nveu32 #endif /* DEBUG_MACSEC */ /** - * @brief macsec_init - Inititlizes macsec + * @brief macsec_initialize - Inititlizes macsec * * @note * Algorithm: @@ -4476,8 +4476,7 @@ static void macsec_intr_config(struct osi_core_priv_data *const osi_core, nveu32 * @retval 0 for success * @retval -1 for failure */ -static nve32_t macsec_init(struct osi_core_priv_data *const osi_core, - nveu32_t mtu) +static nve32_t macsec_initialize(struct osi_core_priv_data *const osi_core, nveu32_t mtu) { nveu32_t val = 0; #if defined(MACSEC_SUPPORT) && !defined(OSI_STRIPPED_LIB) @@ -5311,7 +5310,7 @@ exit: } /** - * @brief config_macsec - API to update LUTs for addition/deletion of SC/SA + * @brief macsec_configure - API to update LUTs for addition/deletion of SC/SA * * @note * Algorithm: @@ -5342,10 +5341,10 @@ exit: * @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) +static nve32_t macsec_configure(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; @@ -5465,7 +5464,7 @@ nve32_t osi_init_macsec_ops(struct osi_core_priv_data *const osi_core) static struct osi_macsec_core_ops virt_macsec_ops; nve32_t ret = 0; static struct osi_macsec_core_ops macsec_ops = { - .init = macsec_init, + .init = macsec_initialize, .deinit = macsec_deinit, .handle_irq = macsec_handle_irq, .lut_config = macsec_lut_config, @@ -5474,7 +5473,7 @@ nve32_t osi_init_macsec_ops(struct osi_core_priv_data *const osi_core) #endif /* MACSEC_KEY_PROGRAM */ .cipher_config = macsec_cipher_config, .macsec_en = macsec_enable, - .config = config_macsec, + .config = macsec_configure, .read_mmc = macsec_read_mmc, .get_sc_lut_key_index = macsec_get_key_index, .update_mtu = macsec_update_mtu, diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 1aaa8a7..8cf7dda 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -848,18 +848,20 @@ static inline nveu32_t mgbe_set_dcs(struct osi_core_priv_data *osi_core, nveu32_t dma_routing_enable, nveu32_t dma_chan) { + nveu32_t temp = value; + 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); + temp |= ((dma_routing_enable << + MGBE_MAC_L3L4_CTR_DMCHEN0_SHIFT) & + MGBE_MAC_L3L4_CTR_DMCHEN0); + temp |= ((dma_chan << + MGBE_MAC_L3L4_CTR_DMCHN0_SHIFT) & + MGBE_MAC_L3L4_CTR_DMCHN0); } - return value; + return temp; } /** @@ -918,7 +920,7 @@ static inline void mgbe_helper_l3l4_bitmask(nveu32_t *bitmask, * @retval 0 on success * @retval -1 on failure. */ -static nve32_t mgbe_config_l3_filters(struct osi_core_priv_data *osi_core, +static nve32_t mgbe_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, @@ -2353,7 +2355,7 @@ static nve32_t mgbe_configure_mac(struct osi_core_priv_data *osi_core) /* 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); + value |= ((((nveu32_t)OSI_MAX_MTU_SIZE) << 16U) & MGBE_MAC_RMCR_GPSL_MSK); } else { value &= ~MGBE_MAC_RMCR_JE; value &= ~MGBE_MAC_RMCR_GPSLCE; @@ -4033,10 +4035,10 @@ static inline nve32_t mgbe_restore_registers( * @retval 0 on success * @retval -1 on failure. */ -static nve32_t mgbe_write_phy_reg(struct osi_core_priv_data *osi_core, - nveu32_t phyaddr, - nveu32_t phyreg, - nveu16_t phydata) +static nve32_t mgbe_write_phy_reg(struct osi_core_priv_data *const osi_core, + const nveu32_t phyaddr, + const nveu32_t phyreg, + const nveu16_t phydata) { nve32_t ret = 0; nveu32_t reg; @@ -4063,7 +4065,7 @@ static nve32_t mgbe_write_phy_reg(struct osi_core_priv_data *osi_core, /* Program Data register */ reg = phydata | - (MGBE_MDIO_SCCD_CMD_WR << MGBE_MDIO_SCCD_CMD_SHIFT) | + (((nveu32_t)MGBE_MDIO_SCCD_CMD_WR) << MGBE_MDIO_SCCD_CMD_SHIFT) | MGBE_MDIO_SCCD_SBUSY; /** @@ -4073,7 +4075,7 @@ static nve32_t mgbe_write_phy_reg(struct osi_core_priv_data *osi_core, * of 2.5MHz only CR need to be set to 5. */ reg &= ~MGBE_MDIO_SCCD_CRS; - reg |= ((0x5U & MGBE_MDIO_SCCD_CR_MASK) << MGBE_MDIO_SCCD_CR_SHIFT); + reg |= ((((nveu32_t)0x5U) & MGBE_MDIO_SCCD_CR_MASK) << MGBE_MDIO_SCCD_CR_SHIFT); osi_writela(osi_core, reg, (nveu8_t *) osi_core->base + MGBE_MDIO_SCCD); @@ -4105,9 +4107,9 @@ static nve32_t mgbe_write_phy_reg(struct osi_core_priv_data *osi_core, * @retval 0 on success * @retval -1 on failure. */ -static nve32_t mgbe_read_phy_reg(struct osi_core_priv_data *osi_core, - nveu32_t phyaddr, - nveu32_t phyreg) +static nve32_t mgbe_read_phy_reg(struct osi_core_priv_data *const osi_core, + const nveu32_t phyaddr, + const nveu32_t phyreg) { nveu32_t reg; nveu32_t data; @@ -4133,7 +4135,7 @@ static nve32_t mgbe_read_phy_reg(struct osi_core_priv_data *osi_core, osi_core->base + MGBE_MDIO_SCCA); /* Program Data register */ - reg = (MGBE_MDIO_SCCD_CMD_RD << MGBE_MDIO_SCCD_CMD_SHIFT) | + reg = (((nveu32_t)MGBE_MDIO_SCCD_CMD_RD) << MGBE_MDIO_SCCD_CMD_SHIFT) | MGBE_MDIO_SCCD_SBUSY; /** @@ -4143,7 +4145,7 @@ static nve32_t mgbe_read_phy_reg(struct osi_core_priv_data *osi_core, * of 2.5MHz only CR need to be set to 5. */ reg &= ~MGBE_MDIO_SCCD_CRS; - reg |= ((0x5U & MGBE_MDIO_SCCD_CR_MASK) << MGBE_MDIO_SCCD_CR_SHIFT); + reg |= ((((nveu32_t)0x5U) & MGBE_MDIO_SCCD_CR_MASK) << MGBE_MDIO_SCCD_CR_SHIFT); osi_writela(osi_core, reg, (nveu8_t *) osi_core->base + MGBE_MDIO_SCCD); @@ -4511,17 +4513,21 @@ static inline nve32_t mgbe_poll_for_update_ts_complete( * @retval 0 on success * @retval -1 on failure. */ -static nve32_t mgbe_adjust_mactime(struct osi_core_priv_data *osi_core, - nveu32_t sec, nveu32_t nsec, - nveu32_t add_sub, - nveu32_t one_nsec_accuracy) +static nve32_t mgbe_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 temp_sec; + nveu32_t temp_nsec; nve32_t ret; + temp_sec = sec; + temp_nsec = nsec; /* To be sure previous write was flushed (if Any) */ ret = mgbe_poll_for_update_ts_complete(osi_core, &mac_tcr); if (ret == -1) { @@ -4533,9 +4539,9 @@ static nve32_t mgbe_adjust_mactime(struct osi_core_priv_data *osi_core, * the system time, then MAC_STSUR reg should be * programmed with (2^32 – <new_sec_value>) */ - temp = (TWO_POWER_32 - sec); + temp = (TWO_POWER_32 - temp_sec); if (temp < UINT_MAX) { - sec = (nveu32_t)temp; + temp_sec = (nveu32_t)temp; } else { /* do nothing here */ } @@ -4547,23 +4553,23 @@ static nve32_t mgbe_adjust_mactime(struct osi_core_priv_data *osi_core, * (2^32 - <new_nsec_value> if MAC_TCR.TSCTRLSSR is reset) */ if (one_nsec_accuracy == OSI_ENABLE) { - if (nsec < UINT_MAX) { - nsec = (TEN_POWER_9 - nsec); + if (temp_nsec < UINT_MAX) { + temp_nsec = (TEN_POWER_9 - temp_nsec); } } else { - if (nsec < UINT_MAX) { - nsec = (TWO_POWER_31 - nsec); + if (temp_nsec < UINT_MAX) { + temp_nsec = (TWO_POWER_31 - temp_nsec); } } } /* write seconds value to MAC_System_Time_Seconds_Update register */ - osi_writela(osi_core, sec, (nveu8_t *)addr + MGBE_MAC_STSUR); + osi_writela(osi_core, temp_sec, (nveu8_t *)addr + MGBE_MAC_STSUR); /* write nano seconds value and add_sub to * MAC_System_Time_Nanoseconds_Update register */ - value |= nsec; + value |= temp_nsec; value |= (add_sub << MGBE_MAC_STNSUR_ADDSUB_SHIFT); osi_writela(osi_core, value, (nveu8_t *)addr + MGBE_MAC_STNSUR); diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 1f89cd9..0b4ae00 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -162,6 +162,9 @@ #define MGBE_MAC_PFR_VTFE_SHIFT 16 #define MGBE_MAC_PIDR_PID_MASK 0XFFFFU +#define MGBE_MTL_RXP_BYPASS_CNT 2U +#define MGBE_MAC_FPE_CTS_SVER OSI_BIT(1) + #endif /* !OSI_STRIPPED_LIB */ #define MGBE_MTL_EST_CONTROL 0x1050 @@ -229,7 +232,6 @@ #define MGBE_MAC_FPE_CTS_TRSP OSI_BIT(19) #define MGBE_MAC_FPE_CTS_TVER OSI_BIT(18) #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 adv registers */ #define MGBE_MAC_IMR_FPEIS OSI_BIT(16) @@ -308,7 +310,6 @@ #define MGBE_MTL_FRP_IE2_AF OSI_BIT(0) #define MGBE_MTL_FRP_IE3_DCH_MASK 0xFFFFU /* Indirect register defines */ -#define MGBE_MTL_RXP_BYPASS_CNT 2U #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_WRRDN OSI_BIT(16) diff --git a/osi/core/mgbe_mmc.c b/osi/core/mgbe_mmc.c index 10f6563..3a522f2 100644 --- a/osi/core/mgbe_mmc.c +++ b/osi/core/mgbe_mmc.c @@ -27,7 +27,7 @@ #include "mgbe_core.h" /** - * @brief update_mmc_val - function to read register and return value to callee + * @brief mgbe_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. @@ -43,9 +43,9 @@ * @retval 0 on MMC counters overflow * @retval value on current MMC counter value. */ -static inline nveu64_t update_mmc_val(struct osi_core_priv_data *osi_core, - nveu64_t last_value, - nveu64_t offset) +static inline nveu64_t mgbe_update_mmc_val(struct osi_core_priv_data *osi_core, + nveu64_t last_value, + nveu64_t offset) { nveu64_t temp; nveu32_t value = osi_readl((nveu8_t *)osi_core->base + @@ -62,7 +62,7 @@ static inline nveu64_t update_mmc_val(struct osi_core_priv_data *osi_core, return temp; } - return 0; + return 0ULL; } /** @@ -104,456 +104,456 @@ void mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_update_mmc_val(osi_core, mmc->mmc_tx_deferred, MMC_TXDEFERRED); mmc->mmc_tx_latecol = - update_mmc_val(osi_core, mmc->mmc_tx_latecol, + mgbe_update_mmc_val(osi_core, mmc->mmc_tx_latecol, MMC_TXLATECOL); mmc->mmc_tx_exesscol = - update_mmc_val(osi_core, mmc->mmc_tx_exesscol, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_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, + mgbe_update_mmc_val(osi_core, mmc->mmc_rx_fpe_fragment_cnt, MMC_RX_FPE_FRAG_CNTR); } diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 4930cc8..9759da4 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -44,17 +44,6 @@ nveu32_t hsi_err_code[][3] = { }; #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. * @@ -126,6 +115,7 @@ static inline nve32_t validate_if_args(struct osi_core_priv_data *const osi_core struct osi_core_priv_data *osi_get_core(void) { nveu32_t i; + static struct core_local g_core[MAX_CORE_INSTANCES]; for (i = 0U; i < MAX_CORE_INSTANCES; i++) { if (g_core[i].if_init_done == OSI_ENABLE) { @@ -173,6 +163,7 @@ struct osi_core_priv_data *get_role_pointer(nveu32_t role) nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core) { struct core_local *l_core = (struct core_local *)(void *)osi_core; + static struct if_core_ops if_ops[MAX_INTERFACE_OPS]; nve32_t ret = -1; if (osi_core == OSI_NULL) { @@ -210,10 +201,12 @@ nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core) } l_core->ts_lock = OSI_DISABLE; l_core->ether_m2m_role = osi_core->m2m_role; +#if DRIFT_CAL 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); +#endif #ifdef MACSEC_SUPPORT osi_lock_init(&osi_core->macsec_fpe_lock); #endif /* MACSEC_SUPPORT */ diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index d69f0f2..e9e890b 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -34,7 +34,6 @@ /** * @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. @@ -136,11 +135,12 @@ nve32_t osi_hal_read_phy_reg(struct osi_core_priv_data *const osi_core, static nve32_t osi_hal_init_core_ops(struct osi_core_priv_data *const osi_core) { struct core_local *l_core = (struct core_local *)(void *)osi_core; - typedef void (*init_ops_arr)(struct core_ops *local_ops); + typedef void (*init_core_ops_arr)(struct core_ops *local_ops); + static struct core_ops g_ops[MAX_MAC_IP_TYPES]; #ifndef OSI_STRIPPED_LIB typedef void *(*safety_init)(void); #endif - init_ops_arr i_ops[MAX_MAC_IP_TYPES][MAX_MAC_IP_TYPES] = { + init_core_ops_arr i_ops[MAX_MAC_IP_TYPES][MAX_MAC_IP_TYPES] = { { eqos_init_core_ops, OSI_NULL }, { mgbe_init_core_ops, OSI_NULL } }; @@ -836,7 +836,8 @@ static nve32_t osi_get_mac_version(struct osi_core_priv_data *const osi_core, nv *mac_ver = osi_readla(osi_core, ((nveu8_t *)osi_core->base + (nve32_t)MAC_VERSION)) & MAC_VERSION_SNVER_MASK; - if (validate_mac_ver_update_chans(*mac_ver, &l_core->max_chans, &l_core->l_mac_ver) == 0) { + if (validate_mac_ver_update_chans(*mac_ver, &l_core->num_max_chans, + &l_core->l_mac_ver) == 0) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid MAC version\n", (nveu64_t)*mac_ver) return -1; @@ -1710,7 +1711,7 @@ static void apply_dynamic_cfg(struct osi_core_priv_data *osi_core) { struct core_local *l_core = (struct core_local *)(void *)osi_core; typedef void (*cfg_fn)(struct core_local *local_core); - const cfg_fn fn[] = { + const cfg_fn fn[10] = { [DYNAMIC_CFG_L3_L4_IDX] = cfg_l3_l4_filter, [DYNAMIC_CFG_L2_IDX] = cfg_l2_filter, [DYNAMIC_CFG_RXCSUM_IDX] = cfg_rxcsum, diff --git a/osi/core/xpcs.c b/osi/core/xpcs.c index 66cc78f..2a3b652 100644 --- a/osi/core/xpcs.c +++ b/osi/core/xpcs.c @@ -600,8 +600,9 @@ nve32_t xpcs_eee(struct osi_core_priv_data *osi_core, nveu32_t en_dis) return -1; } - if (xpcs_base == OSI_NULL) + if (xpcs_base == OSI_NULL) { return -1; + } if (en_dis == OSI_DISABLE) { val = xpcs_read(xpcs_base, XPCS_VR_XS_PCS_EEE_MCTRL0); From 21bb04e8d665595a172fba184c5a00d7a5f9fda6 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Thu, 6 Oct 2022 07:32:38 +0530 Subject: [PATCH 407/458] osi: core: remove safety backup and save/restore code Bug 3701869 Change-Id: Ib2b139db7c8829d01f57581a18506ba6641cd4ab Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2787478 Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- include/ivc_core.h | 10 - include/osi_core.h | 29 --- osi/core/core_local.h | 7 - osi/core/eqos_core.c | 441 ------------------------------------------ osi/core/eqos_core.h | 166 +--------------- osi/core/ivc_core.c | 10 - osi/core/mgbe_core.c | 278 -------------------------- osi/core/osi_hal.c | 77 -------- 8 files changed, 1 insertion(+), 1017 deletions(-) diff --git a/include/ivc_core.h b/include/ivc_core.h index e67ab11..c2a6513 100644 --- a/include/ivc_core.h +++ b/include/ivc_core.h @@ -193,14 +193,4 @@ typedef struct ivc_msg_common { */ 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/osi_core.h b/include/osi_core.h index a3d9f34..96a0a4d 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -63,8 +63,6 @@ typedef my_lint_64 nvel64_t; #define OSI_RSS_MAX_TABLE_SIZE 128U /** @} */ -#define OSI_CMD_SAVE_REGISTER 13U -#define OSI_CMD_RESTORE_REGISTER 2U #define OSI_CMD_RESET_MMC 12U #define OSI_CMD_MDC_CONFIG 1U #define OSI_CMD_MAC_LB 14U @@ -75,7 +73,6 @@ typedef my_lint_64 nvel64_t; #define OSI_CMD_ARP_OFFLOAD 30U #define OSI_CMD_UPDATE_VLAN_ID 26U #define OSI_CMD_VLAN_FILTER 31U -#define OSI_CMD_VALIDATE_CORE_REG 11U #define OSI_CMD_CONFIG_PTP_OFFLOAD 34U #define OSI_CMD_PTP_RXQ_ROUTE 35U #define OSI_CMD_CONFIG_RSS 37U @@ -1326,11 +1323,6 @@ struct osi_core_priv_data { struct osi_xtra_stat_counters xstats; /** Memory mapped base address of HV window */ void *hv_base; - /** 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; /** csr clock is to program LPI 1 us tick timer register. * Value stored in MHz */ @@ -1878,15 +1870,6 @@ nve32_t osi_adjust_time(struct osi_core_priv_data *const osi_core, nve32_t osi_ptp_configuration(struct osi_core_priv_data *const osi_core, const nveu32_t enable); -#ifndef OSI_STRIPPED_LIB -/* 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); -#endif - /** * @brief osi_handle_ioctl - API to handle runtime command * @@ -1896,8 +1879,6 @@ void *eqos_get_core_safety_config(void); * - 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 @@ -1914,13 +1895,9 @@ void *eqos_get_core_safety_config(void); * - 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 @@ -2094,8 +2071,6 @@ struct osi_core_priv_data *osi_get_core(void); * - 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 @@ -2112,13 +2087,9 @@ struct osi_core_priv_data *osi_get_core(void); * - 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 diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 583213c..72f21b5 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -208,9 +208,6 @@ struct core_ops { /** Called to configure HW PTP offload feature */ nve32_t (*config_ptp_offload)(struct osi_core_priv_data *const osi_core, struct osi_pto_config *const pto_config); - /** 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 configure VLAN filtering */ nve32_t (*config_vlan_filtering)( struct osi_core_priv_data *const osi_core, @@ -223,10 +220,6 @@ struct core_ops { 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); diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 596d60e..86848c7 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -40,295 +40,6 @@ static nve32_t eqos_pre_pad_calibrate( #endif /* UPDATED_PAD_CAL */ #ifndef OSI_STRIPPED_LIB -/** - * @brief eqos_core_safety_config - EQOS MAC core safety configuration - */ -static struct core_func_safety eqos_core_safety_config; - -/** - * @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 * @@ -1698,10 +1409,6 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core, nveu32_t tx_fifo = 0; nveu32_t rx_fifo = 0; -#ifndef OSI_STRIPPED_LIB - eqos_core_safety_init(osi_core); - eqos_core_backup_init(osi_core); -#endif /* !OSI_STRIPPED_LIB */ #ifndef UPDATED_PAD_CAL /* PAD calibration */ ret = eqos_pad_calibrate(osi_core); @@ -3984,67 +3691,6 @@ static inline void eqos_disable_tx_lpi( (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_core->osd, 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 * @@ -4625,74 +4271,6 @@ static void eqos_configure_eee(struct osi_core_priv_data *const 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 * @@ -5298,22 +4876,6 @@ done: #endif /* MACSEC_SUPPORT */ -#ifndef OSI_STRIPPED_LIB -/** - * @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; -} -#endif - void eqos_init_core_ops(struct core_ops *ops) { ops->core_init = eqos_core_init; @@ -5350,12 +4912,9 @@ void eqos_init_core_ops(struct core_ops *ops) 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->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; ops->config_rss = eqos_config_rss; diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 75a6268..5003301 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -434,6 +434,7 @@ #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_RXQ_EN_MASK (OSI_BIT(0) | OSI_BIT(1)) #define EQOS_DMA_SBUS_RD_OSR_LMT 0x001F0000U #define EQOS_DMA_SBUS_WR_OSR_LMT 0x1F000000U #define EQOS_MTL_TXQ_SIZE_SHIFT 16U @@ -642,171 +643,6 @@ void update_ehfc_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value); -#define EQOS_MAX_CORE_SAFETY_REGS 45U - -/** - * @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-Safety-Register EQOS Safety Register Mask - * - * @brief EQOS HW register masks and index - * @{ - */ -#define EQOS_RXQ_EN_MASK (OSI_BIT(0) | OSI_BIT(1)) - -/* 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. - */ -#ifndef OSI_STRIPPED_LIB -#define EQOS_MAC_MCR_IDX 0U -#define EQOS_MAC_PFR_IDX 1U -#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_TCR_IDX 13U -#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_TXQ0_QW_IDX 26U -#define EQOS_MTL_CH0_RX_OP_MODE_IDX 34U -#define EQOS_DMA_SBUS_IDX 43U -#define EQOS_MTL_RXQ_DMA_MAP1_IDX 44U -/** @} */ - -/** - * @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. - */ - -#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 * diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index 1820778..8ec6d51 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -606,16 +606,6 @@ void ivc_init_macsec_ops(void *macsecops) } #endif -/** - * @brief ivc_get_core_safety_config - EQOS MAC safety configuration - */ -void *ivc_get_core_safety_config(void) -{ - static struct core_func_safety ivc_safety_config; - - return &ivc_safety_config; -} - /** * @brief vir_ivc_core_deinit - MAC core deinitialization * diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 8cf7dda..07260a7 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -2514,94 +2514,6 @@ static void mgbe_configure_dma(struct osi_core_priv_data *osi_core) (nveu8_t *)osi_core->base + MGBE_DMA_RX_EDMA_CTRL); } -#ifndef OSI_STRIPPED_LIB -/** - * @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; - nveu8_t *base = (nveu8_t *)osi_core->base; - nveu32_t 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 */ -} -#endif /* !OSI_STRIPPED_LIB */ - /** * @brief Map DMA channels to a specific VM IRQ. * @@ -2694,10 +2606,6 @@ static nve32_t mgbe_core_init(struct osi_core_priv_data *const osi_core, nveu32_t value = 0; nveu32_t tx_fifo = 0; -#ifndef OSI_STRIPPED_LIB - mgbe_core_backup_init(osi_core); -#endif /* !OSI_STRIPPED_LIB */ - /* reset mmc counters */ osi_writela(osi_core, MGBE_MMC_CNTRL_CNTRST, (nveu8_t *)osi_core->base + MGBE_MMC_CNTRL); @@ -3856,170 +3764,6 @@ static nve32_t mgbe_mdio_busy_wait(struct osi_core_priv_data *const osi_core) return 0; } -#ifndef OSI_STRIPPED_LIB -/* - * @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 nve32_t mgbe_save_registers( - struct osi_core_priv_data *const osi_core) -{ - nveu32_t i = 0; - struct core_backup *config = &osi_core->backup_config; - nve32_t 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 nve32_t mgbe_restore_registers( - struct osi_core_priv_data *const osi_core) -{ - nveu32_t i = 0; - struct core_backup *config = &osi_core->backup_config; - nve32_t 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; -} -#endif /* !OSI_STRIPPED_LIB */ - /** * @brief mgbe_write_phy_reg - Write to a PHY register over MDIO bus. * @@ -4671,25 +4415,6 @@ static nveu32_t mgbe_write_macsec_reg(struct osi_core_priv_data *const osi_core, #endif /* MACSEC_SUPPORT */ #ifndef OSI_STRIPPED_LIB -/** - * @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 * @@ -4892,12 +4617,9 @@ void mgbe_init_core_ops(struct core_ops *ops) 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->validate_regs = mgbe_validate_core_regs; ops->config_vlan_filtering = mgbe_config_vlan_filtering; ops->reset_mmc = mgbe_reset_mmc; ops->configure_eee = mgbe_configure_eee; - ops->save_registers = mgbe_save_registers; - ops->restore_registers = mgbe_restore_registers; ops->set_mdc_clk_rate = mgbe_set_mdc_clk_rate; ops->config_mac_loopback = mgbe_config_mac_loopback; ops->config_rss = mgbe_config_rss; diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index e9e890b..fdd0f1d 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -137,20 +137,11 @@ static nve32_t osi_hal_init_core_ops(struct osi_core_priv_data *const osi_core) struct core_local *l_core = (struct core_local *)(void *)osi_core; typedef void (*init_core_ops_arr)(struct core_ops *local_ops); static struct core_ops g_ops[MAX_MAC_IP_TYPES]; -#ifndef OSI_STRIPPED_LIB - typedef void *(*safety_init)(void); -#endif init_core_ops_arr i_ops[MAX_MAC_IP_TYPES][MAX_MAC_IP_TYPES] = { { eqos_init_core_ops, OSI_NULL }, { mgbe_init_core_ops, OSI_NULL } }; -#ifndef OSI_STRIPPED_LIB - 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 } - }; -#endif if (osi_core == OSI_NULL) { return -1; } @@ -186,12 +177,6 @@ static nve32_t osi_hal_init_core_ops(struct osi_core_priv_data *const osi_core) i_ops[osi_core->mac][osi_core->use_virtualization](&g_ops[osi_core->mac]); } -#ifndef OSI_STRIPPED_LIB - 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](); - } -#endif if (validate_func_ptrs(osi_core, &g_ops[osi_core->mac]) < 0) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "core: function ptrs validation failed\n", 0ULL); @@ -878,56 +863,6 @@ static nve32_t rxq_route_config(struct osi_core_priv_data *const osi_core, rxq_route->enable); } - -/** - * @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 *)(void *)osi_core; - - if (osi_core->safety_config == OSI_NULL) { - OSI_CORE_ERR(osi_core->osd, 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 * @@ -1823,28 +1758,16 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, break; #ifndef OSI_STRIPPED_LIB - case OSI_CMD_RESTORE_REGISTER: - ret = ops_p->restore_registers(osi_core); - 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; From 22b2f9f552882efb248f545f81349f567f8b3d3a Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Fri, 1 Apr 2022 04:58:30 +0000 Subject: [PATCH 408/458] osi: dma: mgbe: set rx checksum flags Check if the descriptor has any checksum validation errors. If none, set a per packet context flag indicating no err in Rx checksum so that OSD layer will mark the packet appropriately to skip TCP/UDP checksum validation in case of QNX Bug 3725941 Change-Id: Ifa5fff35cc776bf72b96943835dbd2c1b6d44df2 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2691195 Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- osi/dma/mgbe_desc.c | 26 +++++++++++++++++++++++++- osi/dma/mgbe_desc.h | 15 ++++++++++++++- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/osi/dma/mgbe_desc.c b/osi/dma/mgbe_desc.c index f3169f8..6b15b67 100644 --- a/osi/dma/mgbe_desc.c +++ b/osi/dma/mgbe_desc.c @@ -150,6 +150,7 @@ static void mgbe_get_rx_csum(const struct osi_rx_desc *const rx_desc, struct osi_rx_pkt_cx *rx_pkt_cx) { nveu32_t ellt = rx_desc->rdes3 & RDES3_ELLT; + nveu32_t pkt_type; /* Always include either checksum none/unnecessary * depending on status fields in desc. @@ -158,8 +159,31 @@ static void mgbe_get_rx_csum(const struct osi_rx_desc *const rx_desc, if ((ellt != RDES3_ELLT_IPHE) && (ellt != RDES3_ELLT_CSUM_ERR)) { rx_pkt_cx->rxcsum |= OSI_CHECKSUM_UNNECESSARY; } + + rx_pkt_cx->rxcsum |= OSI_CHECKSUM_IPv4; + if (ellt == RDES3_ELLT_IPHE) { + rx_pkt_cx->rxcsum |= OSI_CHECKSUM_IPv4_BAD; + } + + pkt_type = rx_desc->rdes3 & MGBE_RDES3_PT_MASK; + if (pkt_type == MGBE_RDES3_PT_IPV4_TCP) { + rx_pkt_cx->rxcsum |= OSI_CHECKSUM_TCPv4; + } else if (pkt_type == MGBE_RDES3_PT_IPV4_UDP) { + rx_pkt_cx->rxcsum |= OSI_CHECKSUM_UDPv4; + } else if (pkt_type == MGBE_RDES3_PT_IPV6_TCP) { + rx_pkt_cx->rxcsum |= OSI_CHECKSUM_TCPv6; + } else if (pkt_type == MGBE_RDES3_PT_IPV6_UDP) { + rx_pkt_cx->rxcsum |= OSI_CHECKSUM_UDPv6; + } else { + /* Do nothing */ + } + + if (ellt == RDES3_ELLT_CSUM_ERR) { + rx_pkt_cx->rxcsum |= OSI_CHECKSUM_TCP_UDP_BAD; + } } -/** + +/** * @brief mgbe_get_rx_hwstamp - Get Rx HW Time stamp * * Algorithm: diff --git a/osi/dma/mgbe_desc.h b/osi/dma/mgbe_desc.h index d3bc340..ae7bda1 100644 --- a/osi/dma/mgbe_desc.h +++ b/osi/dma/mgbe_desc.h @@ -35,5 +35,18 @@ /** @} */ #endif /* !OSI_STRIPPED_LIB */ -#endif /* MGBE_DESC_H_ */ +/** + * @addtogroup MGBE RDESC bits. + * + * @brief Values defined for the MGBE rx descriptor bit fields + * @{ + */ +#define MGBE_RDES3_PT_MASK (OSI_BIT(20) | OSI_BIT(21) | OSI_BIT(22) | OSI_BIT(23)) +#define MGBE_RDES3_PT_IPV4_TCP OSI_BIT(20) +#define MGBE_RDES3_PT_IPV4_UDP OSI_BIT(21) +#define MGBE_RDES3_PT_IPV6_TCP (OSI_BIT(20) | OSI_BIT(23)) +#define MGBE_RDES3_PT_IPV6_UDP (OSI_BIT(21) | OSI_BIT(23)) +/** @} */ + +#endif /* MGBE_DESC_H_ */ From abfb746542b92fafe3025787b8ebb5cd36ad844f Mon Sep 17 00:00:00 2001 From: Hareesh Kesireddy <hkesireddy@nvidia.com> Date: Tue, 11 Oct 2022 13:43:10 +0530 Subject: [PATCH 409/458] osi: dma: align total rx buf length to 16 bytes Bug 3820633 Change-Id: I85adcb3d9093b26811f8174a8b8712fc27d29a42 Signed-off-by: Hareesh Kesireddy <hkesireddy@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2789959 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Ajay Gupta <ajayg@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- osi/dma/osi_dma.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index b3b1899..337aa43 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -910,14 +910,14 @@ nve32_t osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) /* Add Ethernet header + FCS */ rx_buf_len = osi_dma->mtu + OSI_ETH_HLEN + NV_VLAN_HLEN; - /* Buffer alignment */ - osi_dma->rx_buf_len = ((rx_buf_len + (AXI_BUS_WIDTH - 1U)) & - ~(AXI_BUS_WIDTH - 1U)); - /* Add 30 bytes (15bytes extra at head portion for alignment and 15bytes * extra to cover tail portion) again for the buffer address alignment */ - osi_dma->rx_buf_len += 30U; + rx_buf_len += 30U; + + /* Buffer alignment */ + osi_dma->rx_buf_len = ((rx_buf_len + (AXI_BUS_WIDTH - 1U)) & + ~(AXI_BUS_WIDTH - 1U)); fail: return ret; From 1ea653fc42d20ef8fd76840b151d601028b4dc43 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Wed, 12 Oct 2022 08:02:43 +0530 Subject: [PATCH 410/458] osi: core: Handle common interrupts before de-init Issue: During resume common interrupt raised for XPCS remote and local link faults for MGBE0_0 on FS. It resulted raising scheduling lane bring up through workqueue but by that time driver is not ready handle the data transfers. Fix: Disable the common interrupts and handle the same if there are any pending interrupts. Bug 3812764 Change-Id: Ia647e46ef66d8687e1173873af8d8b67f2d7cc4b Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2793960 Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- osi/core/core_common.h | 4 ++-- osi/core/osi_hal.c | 15 ++++++++++++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/osi/core/core_common.h b/osi/core/core_common.h index 9cfac2a..63721fd 100644 --- a/osi/core/core_common.h +++ b/osi/core/core_common.h @@ -95,8 +95,8 @@ #define WRAP_PTP_CAPTURE_LOW 0x8018U #define WRAP_PTP_CAPTURE_HIGH 0x801CU #define MAC_PKT_FILTER_REG 0x0008 - - +#define HW_MAC_IER 0x00B4U +#define WRAP_COMMON_INTR_ENABLE 0x8704U /** * @addtogroup typedef related info * diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index fdd0f1d..30680d8 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -248,9 +248,22 @@ nve32_t osi_hal_hw_core_deinit(struct osi_core_priv_data *const osi_core) return -1; } - l_core->hw_init_successful = OSI_DISABLE; + /* Stop the MAC */ hw_stop_mac(osi_core); + /* Disable MAC interrupts */ + osi_writela(osi_core, 0U, ((nveu8_t *)osi_core->base + HW_MAC_IER)); + + if (l_core->l_mac_ver != MAC_CORE_VER_TYPE_EQOS) { + osi_writela(osi_core, 0U, + ((nveu8_t *)osi_core->base + WRAP_COMMON_INTR_ENABLE)); + } + + /* Handle the common interrupt if any status bits set */ + l_core->ops_p->handle_common_intr(osi_core); + + l_core->hw_init_successful = OSI_DISABLE; + if (l_core->state != OSI_SUSPENDED) { /* Reset restore operation flags on interface down */ l_core->cfg.flags = OSI_DISABLE; From 8bb1b24f59ea8ddaae91384ec6a8e4830a64cb8c Mon Sep 17 00:00:00 2001 From: Diptanshu Jamgade <djamgade@nvidia.com> Date: Tue, 11 Oct 2022 17:23:53 +0530 Subject: [PATCH 411/458] nvethernetrm: update OSI_PAUSE_FRAMES_ENABLE macro Update OSI_PAUSE_FRAMES_ENABLE as per the updated DT-bindings. Bug 3529804 Change-Id: Ice290ef85c370956cec2a7b29cc0b6f82ac39093 Signed-off-by: Diptanshu Jamgade <djamgade@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2790122 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Sumeet Gupta <sumeetg@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- include/osi_common.h | 2 +- include/osi_core.h | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index a5c1e09..bc6cc96 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -91,7 +91,7 @@ * @brief EQOS generic helper MACROS. * @{ */ -#define OSI_PAUSE_FRAMES_ENABLE 0U +#define OSI_PAUSE_FRAMES_ENABLE 1U #define OSI_PTP_REQ_CLK_FREQ 250000000U #define OSI_FLOW_CTRL_DISABLE 0U #define OSI_ADDRESS_32BIT 0 diff --git a/include/osi_core.h b/include/osi_core.h index 96a0a4d..c09b9c4 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -869,7 +869,7 @@ struct core_backup { */ struct osi_ptp_config { /** PTP filter parameters bit fields. - * + * * Enable Timestamp, Fine Timestamp, 1 nanosecond accuracy * are enabled by default. * @@ -896,7 +896,7 @@ struct osi_ptp_config { * 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 */ @@ -1304,7 +1304,7 @@ struct osi_core_priv_data { nveu32_t mtu; /** Ethernet MAC address */ nveu8_t mac_addr[OSI_ETH_ALEN]; - /** DT entry to enable(0) or disable(1) pause frame support */ + /** DT entry to enable(1) or disable(0) pause frame support */ nveu32_t pause_frames; /** Current flow control settings */ nveu32_t flow_ctrl; @@ -1394,7 +1394,7 @@ struct osi_core_priv_data { /** * @brief osi_hw_core_init - EQOS MAC, MTL and common DMA initialization. - * + * * @note * Algorithm: * - Invokes EQOS MAC, MTL and common DMA register init code. @@ -1466,7 +1466,7 @@ nve32_t osi_hw_core_deinit(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 From 3c01e876ff120e195b4096f2da82e2c8809abc2e Mon Sep 17 00:00:00 2001 From: Zhongjie Wang <zhowang@nvidia.com> Date: Fri, 16 Sep 2022 19:19:39 +0000 Subject: [PATCH 412/458] osi: dma: using swcx to store nvsocket rx data idx - Added a data_idx field in rx swcx to store nvsocket data index. Tx data idx has been added in a earlier commit. Jira NET-242 Change-Id: I81e4c41efceabab4dbf556ac3f57ca26e0737a81 Signed-off-by: Zhongjie Wang <zhowang@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2778530 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Ajay Gupta <ajayg@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- include/osi_dma.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/osi_dma.h b/include/osi_dma.h index 002a519..1a8871f 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -148,7 +148,7 @@ * @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 @@ -327,6 +327,8 @@ struct osi_rx_swcx { nveu32_t len; /** Flags to share info about Rx swcx between OSD and OSI */ nveu32_t flags; + /** nvsocket data index */ + nveu64_t data_idx; }; /** From 9bae4a21831c21a427f5fede1fd4c624f4768316 Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Thu, 29 Sep 2022 18:25:41 +0530 Subject: [PATCH 413/458] osi: core: Fix misc optimizations 1) remove duplicate checks 2) remove unused APIs 3) moved to STRIPPED if not used Bug 3701869 Change-Id: Id6ba8649ff5135affa949ea8dde947db10003f80 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2784309 Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- include/osi_common.h | 3 +- include/osi_core.h | 615 ----------------------------------- osi/common/common.h | 2 + osi/core/core_common.c | 13 +- osi/core/osi_hal.c | 715 ++++++++++++++++++++++++++++------------- 5 files changed, 506 insertions(+), 842 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index bc6cc96..600d75b 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -224,16 +224,15 @@ #define OSI_MGBE_MAC_3_00 0x30U #define OSI_EQOS_MAC_4_10 0x41U #define OSI_EQOS_MAC_5_10 0x51U +#define OSI_MGBE_MAC_4_00 0x40U #endif /* OSI_STRIPPED_LIB */ #define OSI_EQOS_MAC_5_00 0x50U #define OSI_EQOS_MAC_5_30 0x53U #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_HASH_FILTER_MODE 1U diff --git a/include/osi_core.h b/include/osi_core.h index c09b9c4..4523ccf 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -1464,110 +1464,6 @@ nve32_t osi_hw_core_init(struct osi_core_priv_data *const osi_core, */ nve32_t osi_hw_core_deinit(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_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. * @@ -1612,42 +1508,6 @@ 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. * @@ -1718,158 +1578,6 @@ nve32_t osi_read_phy_reg(struct osi_core_priv_data *const osi_core, */ 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); - /** * @brief osi_handle_ioctl - API to handle runtime command * @@ -2061,327 +1769,4 @@ nve32_t osi_handle_ioctl(struct osi_core_priv_data *osi_core, * @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_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_RESET_MMC - * invoke function to reset MMC counter and data - * structure - * - 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/osi/common/common.h b/osi/common/common.h index 8191356..83ff916 100644 --- a/osi/common/common.h +++ b/osi/common/common.h @@ -271,7 +271,9 @@ static inline nve32_t validate_mac_ver_update_chans(nveu32_t mac_ver, ret = 1; break; case OSI_MGBE_MAC_3_10: +#ifndef OSI_STRIPPED_LIB case OSI_MGBE_MAC_4_00: +#endif /* !OSI_STRIPPED_LIB */ *num_max_chans = OSI_MGBE_MAX_NUM_CHANS; *l_mac_ver = MAC_CORE_VER_TYPE_MGBE; ret = 1; diff --git a/osi/core/core_common.c b/osi/core/core_common.c index 00fd99f..7175d5d 100644 --- a/osi/core/core_common.c +++ b/osi/core/core_common.c @@ -492,6 +492,7 @@ done: return ret; } +#ifndef OSI_STRIPPED_LIB static inline void config_l2_da_perfect_inverse_match( struct osi_core_priv_data *osi_core, nveu32_t perfect_inverse_match) @@ -506,6 +507,7 @@ static inline void config_l2_da_perfect_inverse_match( } osi_writela(osi_core, value, ((nveu8_t *)osi_core->base + MAC_PKT_FILTER_REG)); } +#endif /* !OSI_STRIPPED_LIB */ nve32_t hw_config_mac_pkt_filter_reg(struct osi_core_priv_data *const osi_core, const struct osi_filter *filter) @@ -555,10 +557,13 @@ nve32_t hw_config_mac_pkt_filter_reg(struct osi_core_priv_data *const osi_core, } if ((filter->oper_mode & OSI_OPER_DIS_L2_DA_INV) != OSI_DISABLE) { -#endif /* !OSI_STRIPPED_LIB */ config_l2_da_perfect_inverse_match(osi_core, OSI_PFT_MATCH); -#ifndef OSI_STRIPPED_LIB } +#else + value = osi_readla(osi_core, ((nveu8_t *)osi_core->base + MAC_PKT_FILTER_REG)); + value &= ~MAC_PFR_DAIF; + osi_writela(osi_core, value, ((nveu8_t *)osi_core->base + MAC_PKT_FILTER_REG)); + #endif /* !OSI_STRIPPED_LIB */ return ret; @@ -574,8 +579,8 @@ nve32_t hw_config_l3_l4_filter_enable(struct osi_core_priv_data *const osi_core, /* 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); + "Invalid filter_enb_dis value\n", + filter_enb_dis); ret = -1; goto fail; } diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 30680d8..1e43274 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -35,6 +35,7 @@ * @brief g_ops - Static core operations array. */ +#if DRIFT_CAL /** * @brief Function to validate input arguments of API. * @@ -61,6 +62,7 @@ static inline nve32_t validate_args(struct osi_core_priv_data *const osi_core, return 0; } +#endif /** * @brief Function to validate function pointers. @@ -106,29 +108,102 @@ static nve32_t validate_func_ptrs(struct osi_core_priv_data *const osi_core, 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) +/** + * @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. + */ +static 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 *)(void *)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) +/** + * @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 + */ +static 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 *)(void *)osi_core; - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - return l_core->ops_p->read_phy_reg(osi_core, phyaddr, phyreg); } @@ -210,16 +285,12 @@ static inline void init_vlan_filters(struct osi_core_priv_data *const osi_core) } #endif -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) +static 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 *)(void *)osi_core; nve32_t ret; - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - #ifndef OSI_STRIPPED_LIB init_vlan_filters(osi_core); @@ -240,14 +311,40 @@ nve32_t osi_hal_hw_core_init(struct osi_core_priv_data *const osi_core, return ret; } -nve32_t osi_hal_hw_core_deinit(struct osi_core_priv_data *const osi_core) +/** + * @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. + */ +static nve32_t osi_hal_hw_core_deinit(struct osi_core_priv_data *const osi_core) { struct core_local *l_core = (struct core_local *)(void *)osi_core; - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - /* Stop the MAC */ hw_stop_mac(osi_core); @@ -274,17 +371,149 @@ nve32_t osi_hal_hw_core_deinit(struct osi_core_priv_data *const osi_core) return 0; } -nve32_t osi_common_isr(struct osi_core_priv_data *const osi_core) +/** + * @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); +} + +/** + * @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. + */ +static nve32_t osi_ptp_configuration(struct osi_core_priv_data *const osi_core, + OSI_UNUSED const nveu32_t enable) +{ +#ifndef OSI_STRIPPED_LIB struct core_local *l_core = (struct core_local *)(void *)osi_core; +#endif /* !OSI_STRIPPED_LIB */ + 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; +#ifndef OSI_STRIPPED_LIB + if (enable == OSI_DISABLE) { + /* disable hw time stamping */ + /* Program MAC_Timestamp_Control Register */ + hw_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 { +#endif /* !OSI_STRIPPED_LIB */ + /* Program MAC_Timestamp_Control Register */ + hw_config_tscr(osi_core, osi_core->ptp_config.ptp_filter); + + /* Program Sub Second Increment Register */ + hw_config_ssir(osi_core); + + /* 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); + */ + 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_core->osd, OSI_LOG_ARG_INVALID, + "core: temp2 >= UINT_MAX\n", 0ULL); + return -1; + } + + /* Program addend value */ + ret = hw_config_addend(osi_core, osi_core->default_addend); + + /* Set current time */ + if (ret == 0) { + ret = hw_set_systime_to_mac(osi_core, + osi_core->ptp_config.sec, + osi_core->ptp_config.nsec); +#ifndef OSI_STRIPPED_LIB + 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); + } +#endif /* !OSI_STRIPPED_LIB */ + } +#ifndef OSI_STRIPPED_LIB } +#endif /* !OSI_STRIPPED_LIB */ - l_core->ops_p->handle_common_intr(osi_core); - - return 0; + return ret; } #ifndef OSI_STRIPPED_LIB @@ -369,22 +598,46 @@ static nve32_t conf_ptp_offload(struct osi_core_priv_data *const osi_core, } #endif /* !OSI_STRIPPED_LIB */ -nve32_t osi_l2_filter(struct osi_core_priv_data *const osi_core, - const struct osi_filter *filter) +/** + * @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. + */ +static 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 *)(void *)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_core->osd, OSI_LOG_ARG_INVALID, - "CORE: filter is NULL\n", 0ULL); - return -1; - } - ret = hw_config_mac_pkt_filter_reg(osi_core, filter); if (ret < 0) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, @@ -534,10 +787,6 @@ static nve32_t osi_l3l4_filter(struct osi_core_priv_data *const osi_core, struct core_local *l_core = (struct core_local *)(void *)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, @@ -571,59 +820,41 @@ static nve32_t osi_l3l4_filter(struct osi_core_priv_data *const osi_core, 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 *)(void *)osi_core; - - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - - return hw_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 *)(void *)osi_core; - - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - - return hw_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. - * + * @brief osi_adjust_freq - Adjust frequency * * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * @returns Quotient + * 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. */ -static inline nveu64_t div_u64(nveu64_t dividend, - nveu64_t divisor) +static nve32_t osi_adjust_freq(struct osi_core_priv_data *const osi_core, nve32_t ppb) { - 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 *)(void *)osi_core; - nveu64_t adj; nveu64_t temp; nveu32_t diff = 0; @@ -632,10 +863,6 @@ nve32_t osi_adjust_freq(struct osi_core_priv_data *const osi_core, nve32_t ppb) 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; @@ -680,8 +907,8 @@ nve32_t osi_adjust_freq(struct osi_core_priv_data *const osi_core, nve32_t ppb) return hw_config_addend(osi_core, addend); } -nve32_t osi_adjust_time(struct osi_core_priv_data *const osi_core, - nvel64_t nsec_delta) +static 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 *)(void *)osi_core; nveu32_t neg_adj = 0; @@ -692,10 +919,6 @@ nve32_t osi_adjust_time(struct osi_core_priv_data *const osi_core, 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; @@ -725,112 +948,10 @@ nve32_t osi_adjust_time(struct osi_core_priv_data *const osi_core, 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 *)(void *)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 */ - hw_config_tscr(osi_core, OSI_DISABLE); -#ifndef OSI_STRIPPED_LIB - /* Disable PTP RX Queue routing */ - ret = l_core->ops_p->config_ptp_rxq(osi_core, - osi_core->ptp_config.ptp_rx_queue, - OSI_DISABLE); -#endif /* !OSI_STRIPPED_LIB */ - } else { - /* Program MAC_Timestamp_Control Register */ - hw_config_tscr(osi_core, - osi_core->ptp_config.ptp_filter); - - /* Program Sub Second Increment Register */ - hw_config_ssir(osi_core); - - /* 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); - */ - 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_core->osd, OSI_LOG_ARG_INVALID, - "core: temp2 >= UINT_MAX\n", 0ULL); - return -1; - } - - /* Program addend value */ - ret = hw_config_addend(osi_core, osi_core->default_addend); - - /* Set current time */ - if (ret == 0) { - ret = hw_set_systime_to_mac(osi_core, - osi_core->ptp_config.sec, - osi_core->ptp_config.nsec); - if (ret == 0) { -#ifndef OSI_STRIPPED_LIB - /* Enable PTP RX Queue routing */ - ret = l_core->ops_p->config_ptp_rxq(osi_core, - osi_core->ptp_config.ptp_rx_queue, - OSI_ENABLE); -#endif /* !OSI_STRIPPED_LIB */ - } - } - } - - return ret; -} - -nve32_t osi_read_mmc(struct osi_core_priv_data *const osi_core) -{ - struct core_local *l_core = (struct core_local *)(void *)osi_core; - - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - - l_core->ops_p->read_mmc(osi_core); - - return 0; -} - static 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 *)(void *)osi_core; - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - - if (mac_ver == OSI_NULL) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "mac_ver is NULL\n", 0ULL); - return -1; - } - *mac_ver = osi_readla(osi_core, ((nveu8_t *)osi_core->base + (nve32_t)MAC_VERSION)) & MAC_VERSION_SNVER_MASK; @@ -1724,8 +1845,173 @@ static void store_l2_filter(struct osi_core_priv_data *osi_core, } } -nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, - struct osi_ioctl *data) +/** + * @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. + */ +static 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 *)(void *)osi_core; const struct core_ops *ops_p; @@ -1742,20 +2028,8 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, nvel64_t secondary_time; #endif - if (validate_args(osi_core, l_core) < 0) { - ret = -1; - goto done; - } - ops_p = l_core->ops_p; - if (data == OSI_NULL) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "CORE: Invalid argument\n", 0ULL); - ret = -1; - goto done; - } - switch (data->cmd) { case OSI_CMD_L3L4_FILTER: ret = osi_l3l4_filter(osi_core, &data->l3l4_filter, @@ -2232,7 +2506,6 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, break; } -done: return ret; } From e49f5c01ced76cf9959af1c999e60e7dd32d5705 Mon Sep 17 00:00:00 2001 From: Om Prakash Singh <omp@nvidia.com> Date: Sat, 27 Aug 2022 18:13:43 +0530 Subject: [PATCH 414/458] osi: core: macsec: enable SECURE_REG_VIOL intr enable SECURE_REG_VIOL interrupt to generate uncorrected Error for illegal access errors for MACSEC Registers Bug 3590939 Change-Id: I4f50c1b709ed3662eb6062dcbbbe42a8e36f101c Signed-off-by: Om Prakash Singh <omp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2767836 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_core.h | 6 ++++-- osi/core/macsec.c | 16 ++++++++++++---- osi/core/macsec.h | 6 ++---- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 4523ccf..a2423b4 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -366,6 +366,7 @@ typedef my_lint_64 nvel64_t; #define MACSEC_RX_CRC_ERR_IDX 0U #define MACSEC_TX_CRC_ERR_IDX 1U #define MACSEC_RX_ICV_ERR_IDX 2U +#define MACSEC_REG_VIOL_ERR_IDX 3U /** @} */ extern nveu32_t hsi_err_code[][3]; @@ -388,13 +389,14 @@ extern nveu32_t hsi_err_code[][3]; /** * @brief Maximum number of different mac error code + * HSI_SW_ERR_CODE + Two (Corrected and Uncorrected error code) */ #define HSI_MAX_MAC_ERROR_CODE 6U /** * @brief Maximum number of different macsec error code */ -#define HSI_MAX_MACSEC_ERROR_CODE 3U +#define HSI_MAX_MACSEC_ERROR_CODE 4U /** * @addtogroup HSI_SW_ERR_CODE @@ -409,7 +411,7 @@ extern nveu32_t hsi_err_code[][3]; #define OSI_MACSEC_RX_CRC_ERR 0x1005U #define OSI_MACSEC_TX_CRC_ERR 0x1006U #define OSI_MACSEC_RX_ICV_ERR 0x1007U - +#define OSI_MACSEC_REG_VIOL_ERR 0x1008U /** @} */ #endif diff --git a/osi/core/macsec.c b/osi/core/macsec.c index e566a89..50e7175 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -3669,6 +3669,13 @@ static inline void handle_common_irq(struct osi_core_priv_data *const osi_core) 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; +#ifdef HSI_SUPPORT + if (osi_core->hsi.enabled == OSI_ENABLE) { + osi_core->hsi.macsec_err_code[MACSEC_REG_VIOL_ERR_IDX] = + OSI_MACSEC_REG_VIOL_ERR; + osi_core->hsi.macsec_report_err = OSI_ENABLE; + } +#endif } if ((common_isr & MACSEC_RX_UNINIT_KEY_SLOT) == @@ -4399,8 +4406,7 @@ static void macsec_intr_config(struct osi_core_priv_data *const osi_core, nveu32 val |= (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 | - MACSEC_SECURE_REG_VIOL_INT_EN); + MACSEC_TX_LKUP_MISS_INT_EN); osi_writela(osi_core, val, addr + MACSEC_COMMON_IMR); LOG("Write MACSEC_COMMON_IMR: 0x%x\n", val); } else { @@ -4431,8 +4437,7 @@ static void macsec_intr_config(struct osi_core_priv_data *const osi_core, nveu32 val &= (~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 & - ~MACSEC_SECURE_REG_VIOL_INT_EN); + ~MACSEC_TX_LKUP_MISS_INT_EN); osi_writela(osi_core, val, addr + MACSEC_COMMON_IMR); LOG("Write MACSEC_COMMON_IMR: 0x%x\n", val); } @@ -4561,6 +4566,9 @@ static nve32_t macsec_initialize(struct osi_core_priv_data *const osi_core, nveu 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); + val |= MACSEC_SECURE_REG_VIOL_INT_EN; + osi_writela(osi_core, val, addr + MACSEC_COMMON_IMR); /* Set AES mode * Default power on reset is AES-GCM128, leave it. */ diff --git a/osi/core/macsec.h b/osi/core/macsec.h index 933262f..079de4d 100644 --- a/osi/core/macsec.h +++ b/osi/core/macsec.h @@ -91,9 +91,7 @@ #define MACSEC_TX_SCI_LUT_VALID 0xD028 #define MACSEC_RX_BYP_LUT_VALID 0xD02C #define MACSEC_RX_SCI_LUT_VALID 0xD030 -#ifdef DEBUG_MACSEC #define MACSEC_COMMON_IMR 0xD054 -#endif /* DEBUG_MACSEC */ #define MACSEC_COMMON_ISR 0xD058 #define MACSEC_TX_SC_KEY_INVALID_STS0_0 0xD064 #define MACSEC_TX_SC_KEY_INVALID_STS1_0 0xD068 @@ -217,7 +215,6 @@ #define MACSEC_TX_AES_MODE_AES256 OSI_BIT(1) /** @} */ -#ifdef DEBUG_MACSEC /** * @addtogroup MACSEC_COMMON_IMR register * @@ -225,12 +222,13 @@ * @{ */ #define MACSEC_SECURE_REG_VIOL_INT_EN OSI_BIT(31) +#ifdef DEBUG_MACSEC #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) -/** @} */ #endif /* DEBUG_MACSEC */ +/** @} */ /** * @addtogroup MACSEC_TX_IMR register From 410d3692a1bf61c2683c91e32e4ac8dfe89b3d7e Mon Sep 17 00:00:00 2001 From: Om Prakash Singh <omp@nvidia.com> Date: Mon, 19 Sep 2022 09:32:58 +0530 Subject: [PATCH 415/458] osi: core: Disable HSI causing problem 1) Disable PCS FEC_EN programming as should be enabled only for autonagotiation mode and phy support is also needed. Current phy AQR113C does not has FEC capability (Bug 3799112) 2) Enabling MAC_FSM_CONTROL.TMOUTEN cauing uncorrected error on boot (Bug 3584387) Bug 3590939 Change-Id: Ib5491c64c1028e312470d113934848098e2b0fd5 Signed-off-by: Om Prakash Singh <omp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2777890 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Tested-by: Sanath Kumar Gampa <sgampa@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- osi/core/eqos_core.c | 3 ++- osi/core/mgbe_core.c | 14 ++------------ 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 86848c7..0826004 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1028,7 +1028,8 @@ static nve32_t eqos_hsi_configure(struct osi_core_priv_data *const osi_core, /* T23X-EQOS_HSIv2-3: Enabling and Initialization of Watchdog */ /* T23X-EQOS_HSIv2-4: Enabling of Consistency Monitor for FSM States */ - value = (EQOS_PRTYEN | EQOS_TMOUTEN); + /* TODO enable EQOS_TMOUTEN. Bug 3584387 */ + value = EQOS_PRTYEN; osi_writela(osi_core, value, (nveu8_t *)osi_core->base + EQOS_MAC_FSM_CONTROL); diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 07260a7..d5f8e10 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -2154,12 +2154,6 @@ static nve32_t mgbe_hsi_configure(struct osi_core_priv_data *const osi_core, 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; @@ -2189,7 +2183,8 @@ static nve32_t mgbe_hsi_configure(struct osi_core_priv_data *const osi_core, /* T23X-MGBE_HSIv2-3: Enabling and Initialization of Watchdog Timer */ /* T23X-MGBE_HSIv2-4: Enabling of Consistency Monitor for XGMAC FSM State */ - value = (MGBE_PRTYEN | MGBE_TMOUTEN); + /* TODO enable MGBE_TMOUTEN. Bug 3584387 */ + value = MGBE_PRTYEN; osi_writela(osi_core, value, (nveu8_t *)osi_core->base + MGBE_MAC_FSM_CONTROL); @@ -2243,11 +2238,6 @@ static nve32_t mgbe_hsi_configure(struct osi_core_priv_data *const osi_core, } 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) { From 17db8688382f06515e0b5c1cb627b195fc103c02 Mon Sep 17 00:00:00 2001 From: Om Prakash Singh <omp@nvidia.com> Date: Fri, 23 Sep 2022 08:57:49 +0530 Subject: [PATCH 416/458] osi: core: use u16 type for reporter ID reporter IDs are u16 type for error reporting API Bug 3590939 Change-Id: Iae56610dce407fbf8d4b3a1ea67d3f568c22a681 Signed-off-by: Om Prakash Singh <omp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2781194 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_core.h | 5 +++-- osi/core/eqos_core.c | 2 +- osi/core/mgbe_core.c | 2 +- osi/core/osi_core.c | 20 ++++++++++++++------ 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index a2423b4..9bac52c 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -369,7 +369,8 @@ typedef my_lint_64 nvel64_t; #define MACSEC_REG_VIOL_ERR_IDX 3U /** @} */ -extern nveu32_t hsi_err_code[][3]; +extern nveu32_t hsi_err_code[][2]; +extern nveu16_t hsi_reporter_id[]; /** * @addtogroup HSI_TIME_THRESHOLD @@ -1217,7 +1218,7 @@ struct osi_hsi_data { /** error count threshold to report error */ nveu32_t err_count_threshold; /** HSI reporter ID */ - nveu32_t reporter_id; + nveu16_t reporter_id; /** HSI error codes */ nveu32_t err_code[HSI_MAX_MAC_ERROR_CODE]; /** HSI MAC report count threshold based error */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 0826004..795fb6a 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -999,7 +999,7 @@ static nve32_t eqos_hsi_configure(struct osi_core_priv_data *const osi_core, if (enable == OSI_ENABLE) { osi_core->hsi.enabled = OSI_ENABLE; - osi_core->hsi.reporter_id = hsi_err_code[osi_core->instance_id][REPORTER_IDX]; + osi_core->hsi.reporter_id = hsi_reporter_id[osi_core->instance_id]; /* T23X-EQOS_HSIv2-19: Enabling of Consistency Monitor for TX Frame Errors */ value = osi_readla(osi_core, diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index d5f8e10..93bcc38 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -2152,7 +2152,7 @@ static nve32_t mgbe_hsi_configure(struct osi_core_priv_data *const osi_core, if (enable == OSI_ENABLE) { osi_core->hsi.enabled = OSI_ENABLE; - osi_core->hsi.reporter_id = hsi_err_code[osi_core->instance_id][REPORTER_IDX]; + osi_core->hsi.reporter_id = hsi_reporter_id[osi_core->instance_id]; /* T23X-MGBE_HSIv2-12:Initialization of Transaction Timeout in PCS */ /* T23X-MGBE_HSIv2-11:Initialization of Watchdog Timer */ diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 9759da4..0f0fc94 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -35,12 +35,20 @@ * 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}, +nveu32_t hsi_err_code[][2] = { + {0x2A00, 0x2E08}, + {0x2A01, 0x2E09}, + {0x2A02, 0x2E0A}, + {0x2A03, 0x2E0B}, + {0x28AD, 0x2DE6}, +}; + +nveu16_t hsi_reporter_id[] = { + 0x8019, + 0x801A, + 0x801B, + 0x801C, + 0x8009, }; #endif From 97de39a4c4216354138ca210741538750ed3d278 Mon Sep 17 00:00:00 2001 From: Om Prakash Singh <omp@nvidia.com> Date: Fri, 23 Sep 2022 07:31:30 +0530 Subject: [PATCH 417/458] osi: core: add SW error code for XPCS write failure As return specific error code on PCS read-after-write fails. And add SW error code to report for FSI on failure. Bug 3792855 Change-Id: I51b8a088247d98621750af7bb42100a078c083c2 Signed-off-by: Om Prakash Singh <omp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2781195 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_core.h | 6 +++++- osi/core/core_common.c | 4 ++-- osi/core/xpcs.h | 4 ++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 9bac52c..50c28fa 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -347,6 +347,8 @@ typedef my_lint_64 nvel64_t; #define OSI_FRP_MATCH_VLAN 9U /** @} */ +#define XPCS_WRITE_FAIL_CODE -9 + #ifdef HSI_SUPPORT /** * @addtogroup hsi_err_code_idx @@ -362,6 +364,7 @@ typedef my_lint_64 nvel64_t; #define TX_FRAME_ERR_IDX 3U #define RX_CSUM_ERR_IDX 4U #define AUTONEG_ERR_IDX 5U +#define XPCS_WRITE_FAIL_IDX 6U #define MACSEC_RX_CRC_ERR_IDX 0U #define MACSEC_TX_CRC_ERR_IDX 1U @@ -392,7 +395,7 @@ extern nveu16_t hsi_reporter_id[]; * @brief Maximum number of different mac error code * HSI_SW_ERR_CODE + Two (Corrected and Uncorrected error code) */ -#define HSI_MAX_MAC_ERROR_CODE 6U +#define HSI_MAX_MAC_ERROR_CODE 7U /** * @brief Maximum number of different macsec error code @@ -413,6 +416,7 @@ extern nveu16_t hsi_reporter_id[]; #define OSI_MACSEC_TX_CRC_ERR 0x1006U #define OSI_MACSEC_RX_ICV_ERR 0x1007U #define OSI_MACSEC_REG_VIOL_ERR 0x1008U +#define OSI_XPCS_WRITE_FAIL_ERR 0x1009U /** @} */ #endif diff --git a/osi/core/core_common.c b/osi/core/core_common.c index 7175d5d..747edfa 100644 --- a/osi/core/core_common.c +++ b/osi/core/core_common.c @@ -183,8 +183,8 @@ nve32_t hw_set_speed(struct osi_core_priv_data *const osi_core, const nve32_t sp osi_writela(osi_core, value, ((nveu8_t *)osi_core->base + mac_mcr[osi_core->mac])); if (osi_core->mac == OSI_MAC_HW_MGBE) { - if (xpcs_init(osi_core) < 0) { - ret = -1; + ret = xpcs_init(osi_core); + if (ret < 0) { goto fail; } diff --git a/osi/core/xpcs.h b/osi/core/xpcs.h index 9690e93..0509668 100644 --- a/osi/core/xpcs.h +++ b/osi/core/xpcs.h @@ -171,7 +171,7 @@ static inline void xpcs_write(void *xpcs_base, nveu32_t reg_addr, * @param[in] val: write value to register address * * @retval 0 on success - * @retval -1 on failure. + * @retval XPCS_WRITE_FAIL_CODE on failure * */ static inline nve32_t xpcs_write_safety(struct osi_core_priv_data *osi_core, @@ -193,6 +193,6 @@ static inline nve32_t xpcs_write_safety(struct osi_core_priv_data *osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "xpcs_write_safety failed", reg_addr); - return -1; + return XPCS_WRITE_FAIL_CODE; } #endif From 3b1f32682fab5e4dbfed4f0856ef5bf68bf90415 Mon Sep 17 00:00:00 2001 From: Om Prakash Singh <omp@nvidia.com> Date: Thu, 29 Sep 2022 17:41:39 +0530 Subject: [PATCH 418/458] osi: core: enable HSI_SUPPORT and fix MISRA issue enable HSI_SUPPORT at OSI unit level and address misra issues. Bug 3590939 Change-Id: Ia87bafe077553d0140219047a578100c3f5684aa Signed-off-by: Om Prakash Singh <omp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2784224 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_core.h | 3 --- osi/core/Makefile.tmk | 1 + osi/core/eqos_core.c | 4 ++-- osi/core/eqos_core.h | 1 - osi/core/mgbe_core.c | 11 ++++++----- osi/core/mgbe_core.h | 1 - osi/core/xpcs.h | 5 +---- 7 files changed, 10 insertions(+), 16 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 50c28fa..46b062f 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -356,8 +356,6 @@ typedef my_lint_64 nvel64_t; * @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 @@ -365,7 +363,6 @@ typedef my_lint_64 nvel64_t; #define RX_CSUM_ERR_IDX 4U #define AUTONEG_ERR_IDX 5U #define XPCS_WRITE_FAIL_IDX 6U - #define MACSEC_RX_CRC_ERR_IDX 0U #define MACSEC_TX_CRC_ERR_IDX 1U #define MACSEC_RX_ICV_ERR_IDX 2U diff --git a/osi/core/Makefile.tmk b/osi/core/Makefile.tmk index c3ea29c..a4fb0a0 100644 --- a/osi/core/Makefile.tmk +++ b/osi/core/Makefile.tmk @@ -47,6 +47,7 @@ NV_COMPONENT_SOURCES := \ $(NV_SOURCE)/nvethernetrm/osi/common/mgbe_common.c \ $(NV_SOURCE)/nvethernetrm/osi/core/macsec.c +NV_COMPONENT_CFLAGS += -DHSI_SUPPORT NV_COMPONENT_CFLAGS += -DMACSEC_SUPPORT #NV_COMPONENT_CFLAGS += -DMACSEC_KEY_PROGRAM diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 795fb6a..39a29e2 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1021,8 +1021,8 @@ static nve32_t eqos_hsi_configure(struct osi_core_priv_data *const osi_core, /* 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 |= (0x2U << EQOS_NTMRMD_SHIFT) & EQOS_NTMRMD_MASK; + value |= ((nveu32_t)0x2U << EQOS_LTMRMD_SHIFT) & EQOS_LTMRMD_MASK; + value |= ((nveu32_t)0x2U << EQOS_NTMRMD_SHIFT) & EQOS_NTMRMD_MASK; osi_writela(osi_core, value, (nveu8_t *)osi_core->base + EQOS_MAC_FSM_ACT_TIMER); diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 5003301..51382b1 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -853,7 +853,6 @@ void update_ehfc_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value); #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 diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 93bcc38..e275c05 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -2159,7 +2159,7 @@ static nve32_t mgbe_hsi_configure(struct osi_core_priv_data *const osi_core, 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; + goto fail; } /* T23X-MGBE_HSIv2-1 Configure ECC */ value = osi_readla(osi_core, @@ -2175,9 +2175,9 @@ static nve32_t mgbe_hsi_configure(struct osi_core_priv_data *const osi_core, /* 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 |= (0x2U << MGBE_NTMRMD_SHIFT) & MGBE_NTMRMD_MASK; + value |= ((nveu32_t)0x0U << MGBE_CTMR_SHIFT) & MGBE_CTMR_MASK; + value |= ((nveu32_t)0x2U << MGBE_LTMRMD_SHIFT) & MGBE_LTMRMD_MASK; + value |= ((nveu32_t)0x2U << MGBE_NTMRMD_SHIFT) & MGBE_NTMRMD_MASK; osi_writela(osi_core, value, (nveu8_t *)osi_core->base + MGBE_DWCXG_CORE_MAC_FSM_ACT_TIMER); @@ -2241,7 +2241,7 @@ static nve32_t mgbe_hsi_configure(struct osi_core_priv_data *const osi_core, /* 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; + goto fail; } /* T23X-MGBE_HSIv2-1 Disable ECC */ value = osi_readla(osi_core, @@ -2300,6 +2300,7 @@ static nve32_t mgbe_hsi_configure(struct osi_core_priv_data *const osi_core, osi_writela(osi_core, value, (nveu8_t *)osi_core->xpcs_base + XPCS_WRAP_INTERRUPT_CONTROL); } +fail: return ret; } #endif diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 0b4ae00..abb4d83 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -1038,7 +1038,6 @@ #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 diff --git a/osi/core/xpcs.h b/osi/core/xpcs.h index 0509668..0246db8 100644 --- a/osi/core/xpcs.h +++ b/osi/core/xpcs.h @@ -109,13 +109,10 @@ #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_MASK 0xFFU #define XPCS_SFTY_1US_MULT_SHIFT 0U #endif /** @} */ From 038f231851f95b84097c5b5c822037128d160084 Mon Sep 17 00:00:00 2001 From: Om Prakash Singh <omp@nvidia.com> Date: Tue, 4 Oct 2022 20:22:08 +0530 Subject: [PATCH 419/458] osi: core: add support for HSI error injection Add new osi ioctl command OSI_CMD_HSI_INJECT_ERR for IP specific error injection configuration. different type of error is injected based on input error code value. Bug 3806923 Signed-off-by: Om Prakash Singh <omp@nvidia.com> Change-Id: I01269d211293aa67471fadcf6e349f049f9c1a51 Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2786840 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_core.h | 32 +++++++++++++++++-- osi/core/core_common.c | 72 ++++++++++++++++++++++++++++++++++++++++++ osi/core/core_common.h | 4 +++ osi/core/core_local.h | 3 ++ osi/core/eqos_core.c | 42 ++++++++++++++++++++++++ osi/core/eqos_core.h | 5 +++ osi/core/macsec.h | 9 ++++++ osi/core/mgbe_core.c | 46 +++++++++++++++++++++++++++ osi/core/mgbe_core.h | 8 +++++ osi/core/osi_core.c | 31 ++++++++---------- osi/core/osi_hal.c | 4 +++ 11 files changed, 237 insertions(+), 19 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 46b062f..8181c96 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -96,6 +96,13 @@ typedef my_lint_64 nvel64_t; #define OSI_MAC_TCR_AV8021ASMEN OSI_BIT(28) #define OSI_FLOW_CTRL_RX OSI_BIT(1) + +#define OSI_INSTANCE_ID_MBGE0 0 +#define OSI_INSTANCE_ID_MGBE1 1 +#define OSI_INSTANCE_ID_MGBE2 2 +#define OSI_INSTANCE_ID_MGBE3 3 +#define OSI_INSTANCE_ID_EQOS0 4 + #endif /* !OSI_STRIPPED_LIB */ @@ -266,6 +273,9 @@ typedef my_lint_64 nvel64_t; #endif #define OSI_CMD_SUSPEND 53U #define OSI_CMD_RESUME 54U +#ifdef HSI_SUPPORT +#define OSI_CMD_HSI_INJECT_ERR 55U +#endif /** @} */ /** @@ -290,8 +300,8 @@ typedef my_lint_64 nvel64_t; */ #define OSI_CORE_INFO(priv, type, err, loga) \ { \ - osi_core->osd_ops.ops_log(priv, __func__, __LINE__, \ - OSI_LOG_INFO, type, err, loga); \ + osi_core->osd_ops.ops_log((priv), __func__, __LINE__, \ + OSI_LOG_INFO, (type), (err), (loga)); \ } #define VLAN_NUM_VID 4096U @@ -414,6 +424,24 @@ extern nveu16_t hsi_reporter_id[]; #define OSI_MACSEC_RX_ICV_ERR 0x1007U #define OSI_MACSEC_REG_VIOL_ERR 0x1008U #define OSI_XPCS_WRITE_FAIL_ERR 0x1009U + +#define OSI_HSI_MGBE0_UE_CODE 0x2A00U +#define OSI_HSI_MGBE1_UE_CODE 0x2A01U +#define OSI_HSI_MGBE2_UE_CODE 0x2A02U +#define OSI_HSI_MGBE3_UE_CODE 0x2A03U +#define OSI_HSI_EQOS0_UE_CODE 0x28ADU + +#define OSI_HSI_MGBE0_CE_CODE 0x2E08U +#define OSI_HSI_MGBE1_CE_CODE 0x2E09U +#define OSI_HSI_MGBE2_CE_CODE 0x2E0AU +#define OSI_HSI_MGBE3_CE_CODE 0x2E0BU +#define OSI_HSI_EQOS0_CE_CODE 0x2DE6U + +#define OSI_HSI_MGBE0_REPORTER_ID 0x8019U +#define OSI_HSI_MGBE1_REPORTER_ID 0x801AU +#define OSI_HSI_MGBE2_REPORTER_ID 0x801BU +#define OSI_HSI_MGBE3_REPORTER_ID 0x801CU +#define OSI_HSI_EQOS0_REPORTER_ID 0x8009U /** @} */ #endif diff --git a/osi/core/core_common.c b/osi/core/core_common.c index 747edfa..9b921ea 100644 --- a/osi/core/core_common.c +++ b/osi/core/core_common.c @@ -25,6 +25,7 @@ #include "mgbe_core.h" #include "eqos_core.h" #include "xpcs.h" +#include "macsec.h" static inline nve32_t poll_check(struct osi_core_priv_data *const osi_core, nveu8_t *addr, nveu32_t bit_check, nveu32_t *value) @@ -1408,3 +1409,74 @@ void hw_tsn_init(struct osi_core_priv_data *osi_core, user application should use IOCTL to set CBS as per requirement */ } + +#ifdef HSI_SUPPORT +/** + * @brief hsi_common_error_inject + * + * Algorithm: + * - For macsec HSI: trigger interrupt using MACSEC_*_INTERRUPT_SET_0 register + * - For mmc counter based: trigger interrupt by incrementing count by threshold value + * - For rest: Directly set the error detected as there is no other mean to induce error + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] error_code: Ethernet HSI error code + * + * @note MAC should be init and started. see osi_start_mac() + */ +void hsi_common_error_inject(struct osi_core_priv_data *osi_core, + nveu32_t error_code) +{ + switch (error_code) { + case OSI_INBOUND_BUS_CRC_ERR: + osi_core->mmc.mmc_rx_crc_error = + osi_update_stats_counter(osi_core->mmc.mmc_rx_crc_error, + osi_core->hsi.err_count_threshold); + break; + case OSI_RECEIVE_CHECKSUM_ERR: + osi_core->mmc.mmc_rx_udp_err = + osi_update_stats_counter(osi_core->mmc.mmc_rx_udp_err, + osi_core->hsi.err_count_threshold); + break; + case OSI_MACSEC_RX_CRC_ERR: + osi_writela(osi_core, MACSEC_RX_MAC_CRC_ERROR, + (nveu8_t *)osi_core->macsec_base + + MACSEC_RX_ISR_SET); + break; + case OSI_MACSEC_TX_CRC_ERR: + osi_writela(osi_core, MACSEC_TX_MAC_CRC_ERROR, + (nveu8_t *)osi_core->macsec_base + + MACSEC_TX_ISR_SET); + break; + case OSI_MACSEC_RX_ICV_ERR: + osi_writela(osi_core, MACSEC_RX_ICV_ERROR, + (nveu8_t *)osi_core->macsec_base + + MACSEC_RX_ISR_SET); + break; + case OSI_MACSEC_REG_VIOL_ERR: + osi_writela(osi_core, MACSEC_SECURE_REG_VIOL, + (nveu8_t *)osi_core->macsec_base + + MACSEC_COMMON_ISR_SET); + break; + case OSI_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; + break; + case OSI_PCS_AUTONEG_ERR: + 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; + break; + case OSI_XPCS_WRITE_FAIL_ERR: + osi_core->hsi.err_code[XPCS_WRITE_FAIL_IDX] = OSI_XPCS_WRITE_FAIL_ERR; + osi_core->hsi.report_err = OSI_ENABLE; + osi_core->hsi.report_count_err[XPCS_WRITE_FAIL_IDX] = OSI_ENABLE; + break; + default: + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "Invalid error code\n", (nveu32_t)error_code); + break; + } +} +#endif diff --git a/osi/core/core_common.h b/osi/core/core_common.h index 63721fd..c858835 100644 --- a/osi/core/core_common.h +++ b/osi/core/core_common.h @@ -142,4 +142,8 @@ nve32_t hw_config_fpe(struct osi_core_priv_data *const osi_core, struct osi_fpe_config *const fpe); void hw_tsn_init(struct osi_core_priv_data *osi_core, nveu32_t est_sel, nveu32_t fpe_sel); +#ifdef HSI_SUPPORT +void hsi_common_error_inject(struct osi_core_priv_data *osi_core, + nveu32_t error_code); +#endif #endif /* INCLUDED_CORE_COMMON_H */ diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 72f21b5..4f0dfcf 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -254,6 +254,9 @@ struct core_ops { /** Interface function called to initialize HSI */ nve32_t (*core_hsi_configure)(struct osi_core_priv_data *const osi_core, const nveu32_t enable); + /** Interface function called to inject error */ + void (*core_hsi_inject_err)(struct osi_core_priv_data *const osi_core, + const nveu32_t error_code); #endif }; diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 39a29e2..c741b4b 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -28,6 +28,7 @@ #include "core_local.h" #include "vlan_filter.h" #include "core_common.h" +#include "macsec.h" #ifdef UPDATED_PAD_CAL /* @@ -1118,6 +1119,46 @@ static nve32_t eqos_hsi_configure(struct osi_core_priv_data *const osi_core, } return 0; } + +/** + * @brief eqos_hsi_inject_err - inject error + * + * @note + * Algorithm: + * - Use error injection method induce error + * + * @param[in, out] osi_core: OSI core private data structure. + * @param[in] type: UE_IDX/CE_IDX + * + * @retval 0 on success + * @retval -1 on failure + */ + +static void eqos_hsi_inject_err(struct osi_core_priv_data *const osi_core, + const nveu32_t error_code) +{ + nveu32_t value; + + switch (error_code) { + case OSI_HSI_EQOS0_CE_CODE: + value = (EQOS_MTL_DBG_CTL_EIEC | EQOS_MTL_DBG_CTL_EIEE); + osi_writela(osi_core, value, (nveu8_t *)osi_core->base + + EQOS_MTL_DBG_CTL); + break; + case OSI_HSI_EQOS0_UE_CODE: + value = EQOS_MTL_DPP_ECC_EIC_BLEI; + osi_writela(osi_core, value, (nveu8_t *)osi_core->base + + EQOS_MTL_DPP_ECC_EIC); + + value = (EQOS_MTL_DBG_CTL_EIEC | EQOS_MTL_DBG_CTL_EIEE); + osi_writela(osi_core, value, (nveu8_t *)osi_core->base + + EQOS_MTL_DBG_CTL); + break; + default: + hsi_common_error_inject(osi_core, error_code); + break; + } +} #endif /** @@ -4923,5 +4964,6 @@ void eqos_init_core_ops(struct core_ops *ops) #endif /* !OSI_STRIPPED_LIB */ #ifdef HSI_SUPPORT ops->core_hsi_configure = eqos_hsi_configure; + ops->core_hsi_inject_err = eqos_hsi_inject_err; #endif } diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 51382b1..c8ed90b 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -858,6 +858,11 @@ void update_ehfc_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value); #define EQOS_MTL_DPP_CONTROL 0xCE0U #define EQOS_EDPP OSI_BIT(0) #define EQOS_MAC_DPP_FSM_INTERRUPT_STATUS 0x140U +#define EQOS_MTL_DBG_CTL 0xC08U +#define EQOS_MTL_DBG_CTL_EIEC OSI_BIT(18) +#define EQOS_MTL_DBG_CTL_EIEE OSI_BIT(16) +#define EQOS_MTL_DPP_ECC_EIC 0xCE4U +#define EQOS_MTL_DPP_ECC_EIC_BLEI OSI_BIT(0) /** @} */ #endif diff --git a/osi/core/macsec.h b/osi/core/macsec.h index 079de4d..380413e 100644 --- a/osi/core/macsec.h +++ b/osi/core/macsec.h @@ -461,4 +461,13 @@ #define INTEGER_LEN 4U #endif /* MACSEC_KEY_PROGRAM */ +#ifdef HSI_SUPPORT +/* Set RX ISR set interrupt status bit */ +#define MACSEC_RX_ISR_SET 0x4050U +/* Set TX ISR set interrupt status bit */ +#define MACSEC_TX_ISR_SET 0x4010U +/* Set Common ISR set interrupt status bit */ +#define MACSEC_COMMON_ISR_SET 0xd05cU +#endif + #endif /* INCLUDED_MACSEC_H */ diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index e275c05..374fcb4 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -30,6 +30,7 @@ #include "mgbe_mmc.h" #include "vlan_filter.h" #include "core_common.h" +#include "macsec.h" /** * @brief mgbe_calculate_per_queue_fifo - Calculate per queue FIFO size @@ -2303,6 +2304,50 @@ static nve32_t mgbe_hsi_configure(struct osi_core_priv_data *const osi_core, fail: return ret; } + +/** + * @brief mgbe_hsi_inject_err - Inject error + * + * Algorithm: Use error injection method to induce error + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] error_code: HSI Error code + * + */ +static void mgbe_hsi_inject_err(struct osi_core_priv_data *const osi_core, + const nveu32_t error_code) +{ + const nveu32_t val_ce = (MGBE_MTL_DEBUG_CONTROL_FDBGEN | + MGBE_MTL_DEBUG_CONTROL_DBGMOD | + MGBE_MTL_DEBUG_CONTROL_FIFORDEN | + MGBE_MTL_DEBUG_CONTROL_EIEE | + MGBE_MTL_DEBUG_CONTROL_EIEC); + + const nveu32_t val_ue = (MGBE_MTL_DEBUG_CONTROL_FDBGEN | + MGBE_MTL_DEBUG_CONTROL_DBGMOD | + MGBE_MTL_DEBUG_CONTROL_FIFORDEN | + MGBE_MTL_DEBUG_CONTROL_EIEE); + + switch (error_code) { + case OSI_HSI_MGBE0_CE_CODE: + case OSI_HSI_MGBE1_CE_CODE: + case OSI_HSI_MGBE2_CE_CODE: + case OSI_HSI_MGBE3_CE_CODE: + osi_writela(osi_core, val_ce, (nveu8_t *)osi_core->base + + MGBE_MTL_DEBUG_CONTROL); + break; + case OSI_HSI_MGBE0_UE_CODE: + case OSI_HSI_MGBE1_UE_CODE: + case OSI_HSI_MGBE2_UE_CODE: + case OSI_HSI_MGBE3_UE_CODE: + osi_writela(osi_core, val_ue, (nveu8_t *)osi_core->base + + MGBE_MTL_DEBUG_CONTROL); + break; + default: + hsi_common_error_inject(osi_core, error_code); + break; + } +} #endif /** @@ -4618,5 +4663,6 @@ void mgbe_init_core_ops(struct core_ops *ops) #endif /* !OSI_STRIPPED_LIB */ #ifdef HSI_SUPPORT ops->core_hsi_configure = mgbe_hsi_configure; + ops->core_hsi_inject_err = mgbe_hsi_inject_err; #endif }; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index abb4d83..bc13c9f 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -380,6 +380,14 @@ #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_MTL_DEBUG_CONTROL 0x1008U +#define MGBE_MTL_DEBUG_CONTROL_FDBGEN OSI_BIT(0) +#define MGBE_MTL_DEBUG_CONTROL_DBGMOD OSI_BIT(1) +#define MGBE_MTL_DEBUG_CONTROL_FIFORDEN OSI_BIT(10) +#define MGBE_MTL_DEBUG_CONTROL_EIEE OSI_BIT(16) +#define MGBE_MTL_DEBUG_CONTROL_EIEC OSI_BIT(18) + #endif #define MGBE_MAC_SBD_INTR OSI_BIT(2) #define MGBE_WRAP_COMMON_INTR_STATUS 0x8708 diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 0f0fc94..17dd988 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -27,28 +27,25 @@ #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 + * @brief hsi_err_code - Array of error code */ nveu32_t hsi_err_code[][2] = { - {0x2A00, 0x2E08}, - {0x2A01, 0x2E09}, - {0x2A02, 0x2E0A}, - {0x2A03, 0x2E0B}, - {0x28AD, 0x2DE6}, + {OSI_HSI_MGBE0_UE_CODE, OSI_HSI_MGBE0_CE_CODE}, + {OSI_HSI_MGBE1_UE_CODE, OSI_HSI_MGBE1_CE_CODE}, + {OSI_HSI_MGBE2_UE_CODE, OSI_HSI_MGBE2_CE_CODE}, + {OSI_HSI_MGBE3_UE_CODE, OSI_HSI_MGBE3_CE_CODE}, + {OSI_HSI_EQOS0_UE_CODE, OSI_HSI_EQOS0_CE_CODE}, }; +/** + * @brief hsi_reporter_id - Array of reporter_id + */ nveu16_t hsi_reporter_id[] = { - 0x8019, - 0x801A, - 0x801B, - 0x801C, - 0x8009, + OSI_HSI_MGBE0_REPORTER_ID, + OSI_HSI_MGBE1_REPORTER_ID, + OSI_HSI_MGBE2_REPORTER_ID, + OSI_HSI_MGBE3_REPORTER_ID, + OSI_HSI_EQOS0_REPORTER_ID, }; #endif diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 1e43274..70fa45a 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -2477,6 +2477,10 @@ static nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, case OSI_CMD_HSI_CONFIGURE: ret = ops_p->core_hsi_configure(osi_core, data->arg1_u32); break; + case OSI_CMD_HSI_INJECT_ERR: + ops_p->core_hsi_inject_err(osi_core, data->arg1_u32); + ret = 0; + break; #endif #ifdef OSI_DEBUG From 9dea49113853b4ef09dfca0ecbd76e6ed94539b6 Mon Sep 17 00:00:00 2001 From: Sanath Kumar Gampa <sgampa@nvidia.com> Date: Tue, 1 Nov 2022 15:05:46 +0530 Subject: [PATCH 420/458] osi:core: Address review comments on HSI changes Bug 3590939 Change-Id: Id54b61871d5152c58376781c421077c62174bc2f Signed-off-by: Sanath Kumar Gampa <sgampa@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2801135 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_core.h | 50 +++++++++++++++++++++++------------------- osi/core/core_common.c | 8 +++---- osi/core/eqos_core.c | 6 ++--- osi/core/mgbe_core.c | 10 ++++----- osi/core/osi_core.c | 8 +++---- 5 files changed, 43 insertions(+), 39 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 8181c96..ab1eb01 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -101,7 +101,7 @@ typedef my_lint_64 nvel64_t; #define OSI_INSTANCE_ID_MGBE1 1 #define OSI_INSTANCE_ID_MGBE2 2 #define OSI_INSTANCE_ID_MGBE3 3 -#define OSI_INSTANCE_ID_EQOS0 4 +#define OSI_INSTANCE_ID_EQOS 4 #endif /* !OSI_STRIPPED_LIB */ @@ -361,9 +361,9 @@ typedef my_lint_64 nvel64_t; #ifdef HSI_SUPPORT /** - * @addtogroup hsi_err_code_idx + * @addtogroup osi_hsi_err_code_idx * - * @brief data index for hsi_err_code array + * @brief data index for osi_hsi_err_code array * @{ */ #define UE_IDX 0U @@ -379,8 +379,8 @@ typedef my_lint_64 nvel64_t; #define MACSEC_REG_VIOL_ERR_IDX 3U /** @} */ -extern nveu32_t hsi_err_code[][2]; -extern nveu16_t hsi_reporter_id[]; +extern nveu32_t osi_hsi_err_code[][2]; +extern nveu16_t osi_hsi_reporter_id[]; /** * @addtogroup HSI_TIME_THRESHOLD @@ -402,7 +402,7 @@ extern nveu16_t hsi_reporter_id[]; * @brief Maximum number of different mac error code * HSI_SW_ERR_CODE + Two (Corrected and Uncorrected error code) */ -#define HSI_MAX_MAC_ERROR_CODE 7U +#define OSI_HSI_MAX_MAC_ERROR_CODE 7U /** * @brief Maximum number of different macsec error code @@ -425,23 +425,23 @@ extern nveu16_t hsi_reporter_id[]; #define OSI_MACSEC_REG_VIOL_ERR 0x1008U #define OSI_XPCS_WRITE_FAIL_ERR 0x1009U -#define OSI_HSI_MGBE0_UE_CODE 0x2A00U -#define OSI_HSI_MGBE1_UE_CODE 0x2A01U -#define OSI_HSI_MGBE2_UE_CODE 0x2A02U -#define OSI_HSI_MGBE3_UE_CODE 0x2A03U -#define OSI_HSI_EQOS0_UE_CODE 0x28ADU +#define OSI_HSI_MGBE0_UE_CODE 0x2A00U +#define OSI_HSI_MGBE1_UE_CODE 0x2A01U +#define OSI_HSI_MGBE2_UE_CODE 0x2A02U +#define OSI_HSI_MGBE3_UE_CODE 0x2A03U +#define OSI_HSI_EQOS0_UE_CODE 0x28ADU -#define OSI_HSI_MGBE0_CE_CODE 0x2E08U -#define OSI_HSI_MGBE1_CE_CODE 0x2E09U -#define OSI_HSI_MGBE2_CE_CODE 0x2E0AU -#define OSI_HSI_MGBE3_CE_CODE 0x2E0BU -#define OSI_HSI_EQOS0_CE_CODE 0x2DE6U +#define OSI_HSI_MGBE0_CE_CODE 0x2E08U +#define OSI_HSI_MGBE1_CE_CODE 0x2E09U +#define OSI_HSI_MGBE2_CE_CODE 0x2E0AU +#define OSI_HSI_MGBE3_CE_CODE 0x2E0BU +#define OSI_HSI_EQOS0_CE_CODE 0x2DE6U -#define OSI_HSI_MGBE0_REPORTER_ID 0x8019U -#define OSI_HSI_MGBE1_REPORTER_ID 0x801AU -#define OSI_HSI_MGBE2_REPORTER_ID 0x801BU -#define OSI_HSI_MGBE3_REPORTER_ID 0x801CU -#define OSI_HSI_EQOS0_REPORTER_ID 0x8009U +#define OSI_HSI_MGBE0_REPORTER_ID 0x8019U +#define OSI_HSI_MGBE1_REPORTER_ID 0x801AU +#define OSI_HSI_MGBE2_REPORTER_ID 0x801BU +#define OSI_HSI_MGBE3_REPORTER_ID 0x801CU +#define OSI_HSI_EQOS0_REPORTER_ID 0x8009U /** @} */ #endif @@ -1249,9 +1249,9 @@ struct osi_hsi_data { /** HSI reporter ID */ nveu16_t reporter_id; /** HSI error codes */ - nveu32_t err_code[HSI_MAX_MAC_ERROR_CODE]; + nveu32_t err_code[OSI_HSI_MAX_MAC_ERROR_CODE]; /** HSI MAC report count threshold based error */ - nveu32_t report_count_err[HSI_MAX_MAC_ERROR_CODE]; + nveu32_t report_count_err[OSI_HSI_MAX_MAC_ERROR_CODE]; /** Indicates if error reporting to FSI is pending */ nveu32_t report_err; /** HSI MACSEC error codes */ @@ -1278,6 +1278,10 @@ struct osi_hsi_data { nveu64_t tx_frame_err_count; /** tx frame error count threshold hit */ nveu64_t tx_frame_err_threshold; + /** Rx UDP error injection count */ + nveu64_t inject_udp_err_count; + /** Rx CRC error injection count */ + nveu64_t inject_crc_err_count; }; #endif diff --git a/osi/core/core_common.c b/osi/core/core_common.c index 9b921ea..d80ea39 100644 --- a/osi/core/core_common.c +++ b/osi/core/core_common.c @@ -1429,13 +1429,13 @@ void hsi_common_error_inject(struct osi_core_priv_data *osi_core, { switch (error_code) { case OSI_INBOUND_BUS_CRC_ERR: - osi_core->mmc.mmc_rx_crc_error = - osi_update_stats_counter(osi_core->mmc.mmc_rx_crc_error, + osi_core->hsi.inject_crc_err_count = + osi_update_stats_counter(osi_core->hsi.inject_crc_err_count, osi_core->hsi.err_count_threshold); break; case OSI_RECEIVE_CHECKSUM_ERR: - osi_core->mmc.mmc_rx_udp_err = - osi_update_stats_counter(osi_core->mmc.mmc_rx_udp_err, + osi_core->hsi.inject_udp_err_count = + osi_update_stats_counter(osi_core->hsi.inject_udp_err_count, osi_core->hsi.err_count_threshold); break; case OSI_MACSEC_RX_CRC_ERR: diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index c741b4b..137d557 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1000,7 +1000,7 @@ static nve32_t eqos_hsi_configure(struct osi_core_priv_data *const osi_core, if (enable == OSI_ENABLE) { osi_core->hsi.enabled = OSI_ENABLE; - osi_core->hsi.reporter_id = hsi_reporter_id[osi_core->instance_id]; + osi_core->hsi.reporter_id = osi_hsi_reporter_id[osi_core->instance_id]; /* T23X-EQOS_HSIv2-19: Enabling of Consistency Monitor for TX Frame Errors */ value = osi_readla(osi_core, @@ -1960,7 +1960,7 @@ static void eqos_handle_hsi_intr(struct osi_core_priv_data *const osi_core) 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_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 */ @@ -1973,7 +1973,7 @@ static void eqos_handle_hsi_intr(struct osi_core_priv_data *const osi_core) } 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_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); diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 374fcb4..56b2bc5 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -2153,7 +2153,7 @@ static nve32_t mgbe_hsi_configure(struct osi_core_priv_data *const osi_core, if (enable == OSI_ENABLE) { osi_core->hsi.enabled = OSI_ENABLE; - osi_core->hsi.reporter_id = hsi_reporter_id[osi_core->instance_id]; + osi_core->hsi.reporter_id = osi_hsi_reporter_id[osi_core->instance_id]; /* T23X-MGBE_HSIv2-12:Initialization of Transaction Timeout in PCS */ /* T23X-MGBE_HSIv2-11:Initialization of Watchdog Timer */ @@ -3526,7 +3526,7 @@ static void mgbe_handle_hsi_intr(struct osi_core_priv_data *osi_core) 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_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 */ @@ -3539,7 +3539,7 @@ static void mgbe_handle_hsi_intr(struct osi_core_priv_data *osi_core) } 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_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); @@ -3578,7 +3578,7 @@ static void mgbe_handle_hsi_intr(struct osi_core_priv_data *osi_core) 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.err_code[UE_IDX] = osi_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 */ @@ -3590,7 +3590,7 @@ static void mgbe_handle_hsi_intr(struct osi_core_priv_data *osi_core) 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.err_code[CE_IDX] = osi_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); diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 17dd988..8605579 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -27,9 +27,9 @@ #ifdef HSI_SUPPORT /** - * @brief hsi_err_code - Array of error code + * @brief osi_hsi_err_code - Array of error code */ -nveu32_t hsi_err_code[][2] = { +nveu32_t osi_hsi_err_code[][2] = { {OSI_HSI_MGBE0_UE_CODE, OSI_HSI_MGBE0_CE_CODE}, {OSI_HSI_MGBE1_UE_CODE, OSI_HSI_MGBE1_CE_CODE}, {OSI_HSI_MGBE2_UE_CODE, OSI_HSI_MGBE2_CE_CODE}, @@ -38,9 +38,9 @@ nveu32_t hsi_err_code[][2] = { }; /** - * @brief hsi_reporter_id - Array of reporter_id + * @brief osi_hsi_reporter_id - Array of reporter_id */ -nveu16_t hsi_reporter_id[] = { +nveu16_t osi_hsi_reporter_id[] = { OSI_HSI_MGBE0_REPORTER_ID, OSI_HSI_MGBE1_REPORTER_ID, OSI_HSI_MGBE2_REPORTER_ID, From ae9837f68e228934ba86cfee702aeec80fae4490 Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Wed, 19 Oct 2022 13:21:17 +0530 Subject: [PATCH 421/458] nvethernetrm: Convert OSI core as a static library Issue: OSI core needs to be converted as a static library for the HVRTOS server. Fix: Convert OSI core as a static library. Bug 3691486 Change-Id: Ie1f7fc0c3a722cb7ddab24da8488904ead80ecc4 Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2794675 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- osi/core/Makefile.interface.tmk | 11 ++----- osi/core/Makefile.sdk | 43 ------------------------ osi/core/Makefile.tmk | 4 +-- osi/core/debug.c | 2 +- osi/core/libnvethernetrm.export | 44 ------------------------- osi/core/libnvethernetrm_debug.export | 47 --------------------------- osi/dma/debug.c | 6 ++-- 7 files changed, 9 insertions(+), 148 deletions(-) delete mode 100644 osi/core/Makefile.sdk delete mode 100644 osi/core/libnvethernetrm.export delete mode 100644 osi/core/libnvethernetrm_debug.export diff --git a/osi/core/Makefile.interface.tmk b/osi/core/Makefile.interface.tmk index 752cfc2..4abf439 100644 --- a/osi/core/Makefile.interface.tmk +++ b/osi/core/Makefile.interface.tmk @@ -24,17 +24,12 @@ # ############################################################################### -ifdef NV_INTERFACE_FLAG_SHARED_LIBRARY_SECTION -NV_INTERFACE_NAME := nvethernetrm -ifeq ($(NV_BUILD_CONFIGURATION_IS_SAFETY),0) -NV_INTERFACE_EXPORTS := lib$(NV_INTERFACE_NAME)_debug -else -NV_INTERFACE_EXPORTS := lib$(NV_INTERFACE_NAME) -endif +ifdef NV_INTERFACE_FLAG_STATIC_LIBRARY_SECTION +NV_COMPONENT_NAME := nvethernetrm +NV_INTERFACE_COMPONENT_DIR := . NV_INTERFACE_PUBLIC_INCLUDES := \ ./include endif - # Local Variables: # indent-tabs-mode: t # tab-width: 8 diff --git a/osi/core/Makefile.sdk b/osi/core/Makefile.sdk deleted file mode 100644 index 5ee8e6d..0000000 --- a/osi/core/Makefile.sdk +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright (c) 2020-2022 NVIDIA CORPORATION. All Rights Reserved. -# -# NVIDIA CORPORATION and its licensors retain all intellectual property -# and proprietary rights in and to this software, related documentation -# and any modifications thereto. Any use, reproduction, disclosure or -# distribution of this software and related documentation without an express -# license agreement from NVIDIA CORPORATION is strictly prohibited. - -include $(PDK_TOP)/drive-t186ref-qnx/make/nvdefs.mk - -TARGETS = libnvethernetrm.so - -CFLAGS += -g -Wall $(NV_PLATFORM_OPT) $(NV_PLATFORM_CFLAGS) -CPPFLAGS = $(NV_PLATFORM_SDK_INC) $(NV_PLATFORM_CPPFLAGS) -I../../../include -I../dma -I../common/include -CPPFLAGS += -DNV_IS_SAFETY=$(NV_PLATFORM_SAFETY) -LDFLAGS := \ - $(NV_PLATFORM_SDK_LIB) \ - $(NV_PLATFORM_LDFLAGS) -LDFLAGS += -shared - -OBJS := eqos_core.o -OBJS += eqos_mmc.o -OBJS += osi_core.o -OBJS += vlan_filter.o -OBJS += frp.o -OBJS += mgbe_core.o -OBJS += xpcs.o -OBJS += mgbe_mmc.o -OBJS += osi_hal.o -OBJS += ivc_core.o -OBJS += ./../common/osi_common.o -OBJS += ./../common/eqos_common.o -OBJS += ./../common/mgbe_common.o -OBJS += core_common.o - -CFLAGS += -D_FILE_OFFSET_BITS=64 - -$(TARGETS): $(OBJS) - $(LD) $(LDFLAGS) -o $@ $^ $(LDLIBS) - $(STRIP) --strip-unneeded -R .comment -R .GCC.command.line $@ - -clean clobber: - rm -rf $(OBJS) $(TARGETS) diff --git a/osi/core/Makefile.tmk b/osi/core/Makefile.tmk index a4fb0a0..21b9bce 100644 --- a/osi/core/Makefile.tmk +++ b/osi/core/Makefile.tmk @@ -22,7 +22,7 @@ # ############################################################################### -ifdef NV_COMPONENT_FLAG_SHARED_LIBRARY_SECTION +ifdef NV_COMPONENT_FLAG_STATIC_LIBRARY_SECTION include $(NV_BUILD_START_COMPONENT) NV_COMPONENT_STRICT_WARNINGS_qnx_64 := 1 @@ -68,7 +68,7 @@ NV_COMPONENT_INCLUDES := \ $(NV_SOURCE)/nvethernetrm/include \ $(NV_SOURCE)/nvethernetrm/osi/common/include -include $(NV_BUILD_SHARED_LIBRARY) +include $(NV_BUILD_STATIC_LIBRARY) endif # Local Variables: diff --git a/osi/core/debug.c b/osi/core/debug.c index d083b36..622edf7 100644 --- a/osi/core/debug.c +++ b/osi/core/debug.c @@ -35,7 +35,7 @@ static void core_dump_struct(struct osi_core_priv_data *osi_core, nveu8_t *ptr, unsigned long size) { - nveu32_t i = 0, rem, j; + nveu32_t i = 0, rem, j = 0; unsigned long temp; if (ptr == OSI_NULL) { diff --git a/osi/core/libnvethernetrm.export b/osi/core/libnvethernetrm.export deleted file mode 100644 index c267b97..0000000 --- a/osi/core/libnvethernetrm.export +++ /dev/null @@ -1,44 +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 -osi_macsec_en -osi_macsec_deinit -osi_macsec_isr -osi_macsec_init -osi_macsec_cipher_config -osi_macsec_config -osi_init_macsec_ops -osi_macsec_read_mmc -osi_macsec_config_lut -osi_macsec_get_sc_lut_key_index -# Enable below if MACSEC_KEY_PROGRAM is enabled -#osi_macsec_kt_config diff --git a/osi/core/libnvethernetrm_debug.export b/osi/core/libnvethernetrm_debug.export deleted file mode 100644 index 32f526d..0000000 --- a/osi/core/libnvethernetrm_debug.export +++ /dev/null @@ -1,47 +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 -osi_macsec_en -osi_macsec_deinit -osi_macsec_isr -osi_macsec_init -osi_macsec_cipher_config -osi_macsec_config -osi_init_macsec_ops -osi_macsec_loopback -osi_macsec_read_mmc -osi_macsec_dbg_events_config -osi_macsec_config_dbg_buf -osi_macsec_config_lut -osi_macsec_get_sc_lut_key_index -# Enable below if MACSEC_KEY_PROGRAM is enabled -#osi_macsec_kt_config diff --git a/osi/dma/debug.c b/osi/dma/debug.c index aecbfa8..8c29763 100644 --- a/osi/dma/debug.c +++ b/osi/dma/debug.c @@ -35,7 +35,7 @@ static void dump_struct(struct osi_dma_priv_data *osi_dma, unsigned char *ptr, unsigned long size) { - nveu32_t i = 0, rem, j; + nveu32_t i = 0, rem, j = 0; unsigned long temp; if (ptr == OSI_NULL) { @@ -205,9 +205,9 @@ static void tx_desc_dump(struct osi_dma_priv_data *osi_dma, unsigned int f_idx, int cnt; if (f_idx > l_idx) { - cnt = l_idx + osi_dma->tx_ring_sz - f_idx; + cnt = (int)(l_idx + osi_dma->tx_ring_sz - f_idx); } else { - cnt = l_idx - f_idx; + cnt = (int)(l_idx - f_idx); } for (i = f_idx; cnt >= 0; cnt--) { From b563b87655441429e515f0500dad729968a6fd0f Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Mon, 10 Oct 2022 12:40:48 +0530 Subject: [PATCH 422/458] osi: eqos: configure MTL RXFIFO and PFC threshold MTL RXFIFO memory available for EQOS - 64KB Below is the distribution - 1) Q0 - 36KB 2) Q1 to Q6 - 2KB 3) Q8 - 16KB It also update flow control parameters for the Rx queues 1) Q0 - FULL_MINUS_16K 2) Q1 to Q7 - FULL_MINUS_1_5K Bug 3787316 Change-Id: I59031ad03f02d5804fcc65cb24e05559e6358500 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2789263 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- include/osi_common.h | 6 - include/osi_core.h | 3 +- osi/core/core_local.h | 16 +-- osi/core/eqos_core.c | 291 +++++++----------------------------------- osi/core/eqos_core.h | 28 ---- osi/core/ivc_core.c | 4 +- osi/core/mgbe_core.c | 110 ++-------------- osi/core/mgbe_core.h | 18 --- osi/core/osi_core.c | 6 +- osi/core/osi_hal.c | 9 +- 10 files changed, 70 insertions(+), 421 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index 600d75b..e0240c9 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -33,12 +33,6 @@ * @{ */ #define FULL_MINUS_1_5K ((nveu32_t)1) -#define FULL_MINUS_2_K ((nveu32_t)2) -#define FULL_MINUS_2_5K ((nveu32_t)3) -#define FULL_MINUS_3_K ((nveu32_t)4) -#define FULL_MINUS_4_K ((nveu32_t)6) -#define FULL_MINUS_6_K ((nveu32_t)10) -#define FULL_MINUS_10_K ((nveu32_t)18) #define FULL_MINUS_16_K ((nveu32_t)30) #define FULL_MINUS_32_K ((nveu32_t)62) /** @} */ diff --git a/include/osi_core.h b/include/osi_core.h index ab1eb01..a2c57f6 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -1465,8 +1465,7 @@ struct osi_core_priv_data { * @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); +nve32_t osi_hw_core_init(struct osi_core_priv_data *const osi_core); /** * @brief osi_hw_core_deinit - EQOS MAC deinitialization. diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 4f0dfcf..cc951ae 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -43,6 +43,11 @@ */ #define MAX_TX_TS_CNT (PKT_ID_CNT * OSI_MGBE_MAX_NUM_CHANS) +/** + * @brief FIFO size helper macro + */ +#define FIFO_SZ(x) ((((x) * 1024U) / 256U) - 1U) + /** * @brief Dynamic configuration helper macros. */ @@ -80,8 +85,7 @@ */ 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); + nve32_t (*if_core_init)(struct osi_core_priv_data *const osi_core); /** 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 */ @@ -105,9 +109,7 @@ struct if_core_ops { */ struct core_ops { /** Called to initialize MAC and MTL registers */ - nve32_t (*core_init)(struct osi_core_priv_data *const osi_core, - nveu32_t tx_fifo_size, - nveu32_t rx_fifo_size); + nve32_t (*core_init)(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 do pad caliberation */ @@ -431,10 +433,6 @@ struct core_local { nveu32_t pps_freq; /** Time interval mask for GCL entry */ nveu32_t ti_mask; - /** HW Tx fifo size */ - nveu32_t tx_fifo_size; - /** HW RX fifo size */ - nveu32_t rx_fifo_size; /** Hardware dynamic configuration context */ struct dynamic_cfg cfg; /** Hardware dynamic configuration state */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 137d557..e5d3c89 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -125,120 +125,6 @@ static nve32_t eqos_config_flow_control( } #endif /* !OSI_STRIPPED_LIB */ -/** - * @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 @@ -427,115 +313,6 @@ calibration_failed: } #endif /* UPDATED_PAD_CAL */ -/** - * @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 @@ -567,21 +344,47 @@ void update_ehfc_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value) * @retval 0 on success * @retval -1 on failure. */ -static nve32_t eqos_configure_mtl_queue(nveu32_t q_inx, - struct osi_core_priv_data *const osi_core, - nveu32_t tx_fifo, - nveu32_t rx_fifo) +static nve32_t eqos_configure_mtl_queue(struct osi_core_priv_data *const osi_core, + nveu32_t q_inx) { + const struct core_local *l_core = (struct core_local *)(void *)osi_core; + const nveu32_t rx_fifo_sz[2U][OSI_EQOS_MAX_NUM_QUEUES] = { + { FIFO_SZ(9U), FIFO_SZ(9U), FIFO_SZ(9U), FIFO_SZ(9U), + FIFO_SZ(1U), FIFO_SZ(1U), FIFO_SZ(1U), FIFO_SZ(1U) }, + { FIFO_SZ(36U), FIFO_SZ(2U), FIFO_SZ(2U), FIFO_SZ(2U), + FIFO_SZ(2U), FIFO_SZ(2U), FIFO_SZ(2U), FIFO_SZ(16U) }, + }; + const nveu32_t tx_fifo_sz[2U][OSI_EQOS_MAX_NUM_QUEUES] = { + { FIFO_SZ(9U), FIFO_SZ(9U), FIFO_SZ(9U), FIFO_SZ(9U), + FIFO_SZ(1U), FIFO_SZ(1U), FIFO_SZ(1U), FIFO_SZ(1U) }, + { FIFO_SZ(8U), FIFO_SZ(8U), FIFO_SZ(8U), FIFO_SZ(8U), + FIFO_SZ(8U), FIFO_SZ(8U), FIFO_SZ(8U), FIFO_SZ(8U) }, + }; + const nveu32_t rfd_rfa[OSI_EQOS_MAX_NUM_QUEUES] = { + FULL_MINUS_16_K, + FULL_MINUS_1_5K, + FULL_MINUS_1_5K, + FULL_MINUS_1_5K, + FULL_MINUS_1_5K, + FULL_MINUS_1_5K, + FULL_MINUS_1_5K, + FULL_MINUS_1_5K, + }; + nveu32_t l_macv = (l_core->l_mac_ver & 0x1U); + nveu32_t que_idx = (q_inx & 0x7U); + nveu32_t rx_fifo_sz_t = 0U; + nveu32_t tx_fifo_sz_t = 0U; nveu32_t value = 0; nve32_t ret = 0; - nveu32_t que_idx = (q_inx & 0xFU); + + tx_fifo_sz_t = tx_fifo_sz[l_macv][que_idx]; ret = hw_flush_mtl_tx_queue(osi_core, que_idx); if (ret < 0) { return ret; } - value = (tx_fifo << EQOS_MTL_TXQ_SIZE_SHIFT); + value = (tx_fifo_sz_t << EQOS_MTL_TXQ_SIZE_SHIFT); /* Enable Store and Forward mode */ value |= EQOS_MTL_TSF; /* Enable TxQ */ @@ -591,7 +394,9 @@ static nve32_t eqos_configure_mtl_queue(nveu32_t q_inx, /* read RX Q0 Operating Mode Register */ value = osi_readla(osi_core, (nveu8_t *)osi_core->base + EQOS_MTL_CHX_RX_OP_MODE(que_idx)); - value |= (rx_fifo << EQOS_MTL_RXQ_SIZE_SHIFT); + + rx_fifo_sz_t = rx_fifo_sz[l_macv][que_idx]; + value |= (rx_fifo_sz_t << EQOS_MTL_RXQ_SIZE_SHIFT); /* Enable Store and Forward mode */ value |= EQOS_MTL_RSF; /* Update EHFL, RFA and RFD @@ -599,7 +404,13 @@ static nve32_t eqos_configure_mtl_queue(nveu32_t q_inx, * RFA: Threshold for Activating Flow Control * RFD: Threshold for Deactivating Flow Control */ - update_ehfc_rfa_rfd(rx_fifo, &value); + value &= ~EQOS_MTL_RXQ_OP_MODE_RFD_MASK; + value &= ~EQOS_MTL_RXQ_OP_MODE_RFA_MASK; + value |= EQOS_MTL_RXQ_OP_MODE_EHFC; + value |= (rfd_rfa[que_idx] << EQOS_MTL_RXQ_OP_MODE_RFD_SHIFT) & + EQOS_MTL_RXQ_OP_MODE_RFD_MASK; + value |= (rfd_rfa[que_idx] << EQOS_MTL_RXQ_OP_MODE_RFA_SHIFT) & + EQOS_MTL_RXQ_OP_MODE_RFA_MASK; osi_writela(osi_core, value, (nveu8_t *)osi_core->base + EQOS_MTL_CHX_RX_OP_MODE(que_idx)); /* Transmit Queue weight */ @@ -1440,16 +1251,12 @@ static void eqos_dma_chan_to_vmirq_map(struct osi_core_priv_data *osi_core) * @retval 0 on success * @retval -1 on failure. */ -static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core, - nveu32_t tx_fifo_size, - nveu32_t rx_fifo_size) +static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core) { 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; #ifndef UPDATED_PAD_CAL /* PAD calibration */ @@ -1514,15 +1321,6 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core, 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] >= @@ -1531,8 +1329,7 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core, "Incorrect queues number\n", 0ULL); return -1; } - ret = eqos_configure_mtl_queue(osi_core->mtl_queues[qinx], - osi_core, tx_fifo, rx_fifo); + ret = eqos_configure_mtl_queue(osi_core, osi_core->mtl_queues[qinx]); if (ret < 0) { return ret; } diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index c8ed90b..6cf8551 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -249,34 +249,6 @@ #define EQOS_MTL_FRP_IE2_RF OSI_BIT(1) #define EQOS_MTL_FRP_IE2_AF OSI_BIT(0) -/** - * @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 * diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index 8ec6d51..c319a16 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -89,9 +89,7 @@ static nve32_t ivc_handle_ioctl(struct osi_core_priv_data *osi_core, * @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) +static nve32_t ivc_core_init(struct osi_core_priv_data *const osi_core) { ivc_msg_common_t msg; diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 56b2bc5..e25b828 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -32,80 +32,6 @@ #include "core_common.h" #include "macsec.h" -/** - * @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. @@ -1807,16 +1733,14 @@ done: * @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 hw_qinx, - struct osi_core_priv_data *osi_core, - nveu32_t tx_fifo) +static nve32_t mgbe_configure_mtl_queue(struct osi_core_priv_data *osi_core, + nveu32_t hw_qinx) { nveu32_t qinx = hw_qinx & 0xFU; /* @@ -1831,7 +1755,12 @@ static nve32_t mgbe_configure_mtl_queue(nveu32_t hw_qinx, * vale= (size in KB / 256) - 1U */ const nveu32_t rx_fifo_sz[OSI_MGBE_MAX_NUM_QUEUES] = { - 160U, 2U, 2U, 2U, 2U, 2U, 2U, 2U, 2U, 16U, + FIFO_SZ(160U), FIFO_SZ(2U), FIFO_SZ(2U), FIFO_SZ(2U), FIFO_SZ(2U), + FIFO_SZ(2U), FIFO_SZ(2U), FIFO_SZ(2U), FIFO_SZ(2U), FIFO_SZ(16U), + }; + const nveu32_t tx_fifo_sz[OSI_MGBE_MAX_NUM_QUEUES] = { + FIFO_SZ(12U), FIFO_SZ(12U), FIFO_SZ(12U), FIFO_SZ(12U), FIFO_SZ(12U), + FIFO_SZ(12U), FIFO_SZ(12U), FIFO_SZ(12U), FIFO_SZ(12U), FIFO_SZ(12U), }; const nveu32_t rfd_rfa[OSI_MGBE_MAX_NUM_QUEUES] = { FULL_MINUS_32_K, @@ -1845,7 +1774,6 @@ static nve32_t mgbe_configure_mtl_queue(nveu32_t hw_qinx, FULL_MINUS_1_5K, FULL_MINUS_1_5K, }; - nveu32_t rx_fifo_sz_t = 0U; nveu32_t value = 0; nve32_t ret = 0; @@ -1881,7 +1809,7 @@ static nve32_t mgbe_configure_mtl_queue(nveu32_t hw_qinx, goto end; } - value = (tx_fifo << MGBE_MTL_TXQ_SIZE_SHIFT); + value = (tx_fifo_sz[qinx] << MGBE_MTL_TXQ_SIZE_SHIFT); /* Enable Store and Forward mode */ value |= MGBE_MTL_TSF; /*TTC not applicable for TX*/ @@ -1894,8 +1822,7 @@ static nve32_t mgbe_configure_mtl_queue(nveu32_t hw_qinx, /* read RX Q0 Operating Mode Register */ value = osi_readla(osi_core, (nveu8_t *)osi_core->base + MGBE_MTL_CHX_RX_OP_MODE(qinx)); - rx_fifo_sz_t = (((rx_fifo_sz[qinx] * 1024U) / 256U) - 1U); - value |= (rx_fifo_sz_t << MGBE_MTL_RXQ_SIZE_SHIFT); + value |= (rx_fifo_sz[qinx] << MGBE_MTL_RXQ_SIZE_SHIFT); /* Enable Store and Forward mode */ value |= MGBE_MTL_RSF; /* Enable HW flow control */ @@ -2622,8 +2549,6 @@ static nve32_t mgbe_dma_chan_to_vmirq_map(struct osi_core_priv_data *osi_core) * 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. @@ -2633,14 +2558,11 @@ static nve32_t mgbe_dma_chan_to_vmirq_map(struct osi_core_priv_data *osi_core) * @retval 0 on success * @retval -1 on failure. */ -static nve32_t mgbe_core_init(struct osi_core_priv_data *const osi_core, - nveu32_t tx_fifo_size, - OSI_UNUSED nveu32_t rx_fifo_size) +static nve32_t mgbe_core_init(struct osi_core_priv_data *const osi_core) { nve32_t ret = 0; nveu32_t qinx = 0; nveu32_t value = 0; - nveu32_t tx_fifo = 0; /* reset mmc counters */ osi_writela(osi_core, MGBE_MMC_CNTRL_CNTRST, (nveu8_t *)osi_core->base + @@ -2675,18 +2597,10 @@ static nve32_t mgbe_core_init(struct osi_core_priv_data *const osi_core, osi_writela(osi_core, value, (nveu8_t *)osi_core->base + MGBE_MAC_EXT_CNF); - /* Actual HW RAM size for Tx is 128KB and Rx is 192KB */ - tx_fifo_size = MGBE_TX_FIFO_SIZE_128KB; - - /* 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); - /* 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); + ret = mgbe_configure_mtl_queue(osi_core, osi_core->mtl_queues[qinx]); if (ret < 0) { return ret; } diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index bc13c9f..94c971f 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -657,24 +657,6 @@ #define MGBE_MAC_TSS_TXTSC OSI_BIT(15) /** @} */ -/** - * @addtogroup MGBE-SIZE SIZE calculation helper Macros - * - * @brief SIZE calculation defines - * @{ - */ -#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_128KB 10U -/** @} */ - #ifndef OSI_STRIPPED_LIB /** * @addtogroup MGBE-HW-BACKUP diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 8605579..2d75675 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -262,8 +262,7 @@ nve32_t osi_read_phy_reg(struct osi_core_priv_data *const osi_core, 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) +nve32_t osi_hw_core_init(struct osi_core_priv_data *const osi_core) { struct core_local *l_core = (struct core_local *)(void *)osi_core; @@ -271,8 +270,7 @@ nve32_t osi_hw_core_init(struct osi_core_priv_data *const osi_core, return -1; } - return l_core->if_ops_p->if_core_init(osi_core, tx_fifo_size, - rx_fifo_size); + return l_core->if_ops_p->if_core_init(osi_core); } nve32_t osi_hw_core_deinit(struct osi_core_priv_data *const osi_core) diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 70fa45a..6920db6 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -285,8 +285,7 @@ static inline void init_vlan_filters(struct osi_core_priv_data *const osi_core) } #endif -static 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) +static nve32_t osi_hal_hw_core_init(struct osi_core_priv_data *const osi_core) { struct core_local *l_core = (struct core_local *)(void *)osi_core; nve32_t ret; @@ -298,14 +297,12 @@ static nve32_t osi_hal_hw_core_init(struct osi_core_priv_data *const osi_core, init_frp(osi_core); #endif /* !OSI_STRIPPED_LIB */ - ret = l_core->ops_p->core_init(osi_core, tx_fifo_size, rx_fifo_size); + ret = l_core->ops_p->core_init(osi_core); if (ret < 0) { return ret; } l_core->lane_status = OSI_ENABLE; - l_core->tx_fifo_size = tx_fifo_size; - l_core->rx_fifo_size = rx_fifo_size; l_core->hw_init_successful = OSI_ENABLE; return ret; @@ -2496,7 +2493,7 @@ static nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, ret = osi_hal_hw_core_deinit(osi_core); break; case OSI_CMD_RESUME: - ret = osi_hal_hw_core_init(osi_core, l_core->tx_fifo_size, l_core->rx_fifo_size); + ret = osi_hal_hw_core_init(osi_core); if (ret < 0) { break; } From 161c4ab2406770891cd1294913474bb656f2c2ec Mon Sep 17 00:00:00 2001 From: Sanath Kumar Gampa <sgampa@nvidia.com> Date: Thu, 10 Nov 2022 07:43:19 +0530 Subject: [PATCH 423/458] osi: Removal of global variables related to HSI Removed Report ID and error codes from global and moved them to local. Bug 3857897 Change-Id: Ib1a5d70782e8c8e26ca3f04316f7f2bb2b03735f Signed-off-by: Sanath Kumar Gampa <sgampa@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2806355 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- include/osi_common.h | 2 +- include/osi_core.h | 7 ++----- osi/core/eqos_core.c | 8 +++----- osi/core/mgbe_core.c | 12 ++++++++++++ osi/core/osi_core.c | 24 ------------------------ 5 files changed, 18 insertions(+), 35 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index e0240c9..de3e13e 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -160,7 +160,7 @@ /* Logging defines */ /* log levels */ -#define OSI_LOG_INFO 1U +#define OSI_LOG_INFO 1U #ifndef OSI_STRIPPED_LIB #define OSI_LOG_WARN 2U #endif /* OSI_STRIPPED_LIB */ diff --git a/include/osi_core.h b/include/osi_core.h index a2c57f6..f3e97ec 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -300,8 +300,8 @@ typedef my_lint_64 nvel64_t; */ #define OSI_CORE_INFO(priv, type, err, loga) \ { \ - osi_core->osd_ops.ops_log((priv), __func__, __LINE__, \ - OSI_LOG_INFO, (type), (err), (loga)); \ + osi_core->osd_ops.ops_log(priv, __func__, __LINE__, \ + OSI_LOG_INFO, type, err, loga); \ } #define VLAN_NUM_VID 4096U @@ -379,9 +379,6 @@ typedef my_lint_64 nvel64_t; #define MACSEC_REG_VIOL_ERR_IDX 3U /** @} */ -extern nveu32_t osi_hsi_err_code[][2]; -extern nveu16_t osi_hsi_reporter_id[]; - /** * @addtogroup HSI_TIME_THRESHOLD * diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index e5d3c89..59eca7e 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -811,7 +811,7 @@ static nve32_t eqos_hsi_configure(struct osi_core_priv_data *const osi_core, if (enable == OSI_ENABLE) { osi_core->hsi.enabled = OSI_ENABLE; - osi_core->hsi.reporter_id = osi_hsi_reporter_id[osi_core->instance_id]; + osi_core->hsi.reporter_id = OSI_HSI_EQOS0_REPORTER_ID; /* T23X-EQOS_HSIv2-19: Enabling of Consistency Monitor for TX Frame Errors */ value = osi_readla(osi_core, @@ -1756,8 +1756,7 @@ static void eqos_handle_hsi_intr(struct osi_core_priv_data *const osi_core) 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] = - osi_hsi_err_code[osi_core->instance_id][UE_IDX]; + osi_core->hsi.err_code[UE_IDX] = OSI_HSI_EQOS0_UE_CODE; osi_core->hsi.report_err = OSI_ENABLE; osi_core->hsi.report_count_err[UE_IDX] = OSI_ENABLE; /* Disable the interrupt */ @@ -1769,8 +1768,7 @@ static void eqos_handle_hsi_intr(struct osi_core_priv_data *const osi_core) EQOS_WRAP_COMMON_INTR_ENABLE); } if ((val & EQOS_CORE_CORRECTABLE_ERR) == EQOS_CORE_CORRECTABLE_ERR) { - osi_core->hsi.err_code[CE_IDX] = - osi_hsi_err_code[osi_core->instance_id][CE_IDX]; + osi_core->hsi.err_code[CE_IDX] = OSI_HSI_EQOS0_CE_CODE; osi_core->hsi.report_err = OSI_ENABLE; osi_core->hsi.ce_count = osi_update_stats_counter(osi_core->hsi.ce_count, 1UL); diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index e25b828..a7aa896 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -2077,6 +2077,12 @@ static nve32_t mgbe_hsi_configure(struct osi_core_priv_data *const osi_core, { nveu32_t value = 0U; nve32_t ret = 0; + const nveu16_t osi_hsi_reporter_id[] = { + OSI_HSI_MGBE0_REPORTER_ID, + OSI_HSI_MGBE1_REPORTER_ID, + OSI_HSI_MGBE2_REPORTER_ID, + OSI_HSI_MGBE3_REPORTER_ID, + }; if (enable == OSI_ENABLE) { osi_core->hsi.enabled = OSI_ENABLE; @@ -3434,6 +3440,12 @@ static void mgbe_handle_hsi_intr(struct osi_core_priv_data *osi_core) nveu32_t val2 = 0; void *xpcs_base = osi_core->xpcs_base; nveu64_t ce_count_threshold; + const nveu32_t osi_hsi_err_code[][2] = { + {OSI_HSI_MGBE0_UE_CODE, OSI_HSI_MGBE0_CE_CODE}, + {OSI_HSI_MGBE1_UE_CODE, OSI_HSI_MGBE1_CE_CODE}, + {OSI_HSI_MGBE2_UE_CODE, OSI_HSI_MGBE2_CE_CODE}, + {OSI_HSI_MGBE3_UE_CODE, OSI_HSI_MGBE3_CE_CODE}, + }; val = osi_readla(osi_core, (nveu8_t *)osi_core->base + MGBE_WRAP_COMMON_INTR_STATUS); diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 2d75675..e73872a 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -25,30 +25,6 @@ #include "core_local.h" #include "../osi/common/common.h" -#ifdef HSI_SUPPORT -/** - * @brief osi_hsi_err_code - Array of error code - */ -nveu32_t osi_hsi_err_code[][2] = { - {OSI_HSI_MGBE0_UE_CODE, OSI_HSI_MGBE0_CE_CODE}, - {OSI_HSI_MGBE1_UE_CODE, OSI_HSI_MGBE1_CE_CODE}, - {OSI_HSI_MGBE2_UE_CODE, OSI_HSI_MGBE2_CE_CODE}, - {OSI_HSI_MGBE3_UE_CODE, OSI_HSI_MGBE3_CE_CODE}, - {OSI_HSI_EQOS0_UE_CODE, OSI_HSI_EQOS0_CE_CODE}, -}; - -/** - * @brief osi_hsi_reporter_id - Array of reporter_id - */ -nveu16_t osi_hsi_reporter_id[] = { - OSI_HSI_MGBE0_REPORTER_ID, - OSI_HSI_MGBE1_REPORTER_ID, - OSI_HSI_MGBE2_REPORTER_ID, - OSI_HSI_MGBE3_REPORTER_ID, - OSI_HSI_EQOS0_REPORTER_ID, -}; -#endif - /** * @brief Function to validate function pointers. * From b661f52642b7baa168603ed8857fb802c7973ed9 Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Wed, 16 Nov 2022 00:22:20 +0530 Subject: [PATCH 424/458] osi: core: merge ioctl calls to osi_core_init By default enable below settings during core init, so that we can avoid the same by calling from Guest OS 1) bring mac out of reset 2) forward error packets 3) set mode to full duplex 4) enable rx csum 5) Configure PTP 6) start mac Bug 3701869 Change-Id: I26578b7a0b8c91c4880d9ef6a3a171ab1c1945aa Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2809705 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- include/osi_core.h | 10 +-- osi/core/core_common.c | 17 +++- osi/core/eqos_core.c | 5 ++ osi/core/eqos_core.h | 2 + osi/core/mgbe_core.c | 8 ++ osi/core/mgbe_core.h | 1 + osi/core/osi_hal.c | 173 ++++++++++++++++++++++++++--------------- 7 files changed, 149 insertions(+), 67 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index f3e97ec..25d2aa2 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -76,6 +76,11 @@ typedef my_lint_64 nvel64_t; #define OSI_CMD_CONFIG_PTP_OFFLOAD 34U #define OSI_CMD_PTP_RXQ_ROUTE 35U #define OSI_CMD_CONFIG_RSS 37U +#define OSI_CMD_CONFIG_FW_ERR 29U +#define OSI_CMD_START_MAC 5U +#define OSI_CMD_SET_MODE 16U +#define OSI_CMD_POLL_FOR_MAC_RST 4U +#define OSI_CMD_GET_MAC_VER 10U /** * @addtogroup PTP-offload PTP offload defines @@ -228,14 +233,10 @@ typedef my_lint_64 nvel64_t; * @{ */ #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_SET_MODE 16U #define OSI_CMD_SET_SPEED 17U #define OSI_CMD_L2_FILTER 18U #define OSI_CMD_RXCSUM_OFFLOAD 19U @@ -245,7 +246,6 @@ typedef my_lint_64 nvel64_t; #define OSI_CMD_GET_AVB 23U #define OSI_CMD_SET_AVB 24U #define OSI_CMD_GET_HW_FEAT 28U -#define OSI_CMD_CONFIG_FW_ERR 29U #define OSI_CMD_SET_SYSTOHW_TIME 33U #define OSI_CMD_CONFIG_FRP 36U #define OSI_CMD_CONFIG_EST 38U diff --git a/osi/core/core_common.c b/osi/core/core_common.c index d80ea39..fa92f15 100644 --- a/osi/core/core_common.c +++ b/osi/core/core_common.c @@ -227,9 +227,9 @@ nve32_t hw_config_fw_err_pkts(struct osi_core_priv_data *osi_core, nveu32_t que_idx = (q_inx & 0xFU); const nveu32_t rx_op_mode[2] = { EQOS_MTL_CHX_RX_OP_MODE(que_idx), MGBE_MTL_CHX_RX_OP_MODE(que_idx)}; +#ifndef OSI_STRIPPED_LIB const nveu32_t max_q[2] = { OSI_EQOS_MAX_NUM_QUEUES, OSI_MGBE_MAX_NUM_QUEUES}; - /* Check for valid enable_fw_err_pkts and que_idx values */ if (((enable_fw_err_pkts != OSI_ENABLE) && (enable_fw_err_pkts != OSI_DISABLE)) || @@ -263,6 +263,21 @@ nve32_t hw_config_fw_err_pkts(struct osi_core_priv_data *osi_core, rx_op_mode[osi_core->mac])); fail: return ret; +#else + /* using void to skip the misra error of unused variable */ + (void)enable_fw_err_pkts; + /* Read MTL RXQ Operation_Mode Register */ + val = osi_readla(osi_core, ((nveu8_t *)osi_core->base + + rx_op_mode[osi_core->mac])); + val |= 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, ((nveu8_t *)osi_core->base + + rx_op_mode[osi_core->mac])); + + return ret; +#endif /* !OSI_STRIPPED_LIB */ } nve32_t hw_config_rxcsum_offload(struct osi_core_priv_data *const osi_core, diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 59eca7e..d6ecb12 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1333,6 +1333,11 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core) if (ret < 0) { return ret; } + /* Enable by default to configure forward error packets. + * Since this is a local function this will always return sucess, + * so no need to check for return value + */ + (void)hw_config_fw_err_pkts(osi_core, osi_core->mtl_queues[qinx], OSI_ENABLE); } /* configure EQOS MAC HW */ diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 6cf8551..499fadf 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -296,6 +296,8 @@ #define EQOS_DMA_BMR 0x1000 #define EQOS_DMA_SBUS 0x1004 #define EQOS_DMA_ISR 0x1008 +#define EQOS_PTP_CLK_SPEED 208333334U +#define EQOS_X_PTP_CLK_SPEED 312500000U /** @} */ /** diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index a7aa896..955320b 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -2610,6 +2610,14 @@ static nve32_t mgbe_core_init(struct osi_core_priv_data *const osi_core) if (ret < 0) { return ret; } + /* Enable by default to configure forward error packets. + * Since this is a local function this will always return sucess, + * so no need to check for return value + */ + ret = hw_config_fw_err_pkts(osi_core, osi_core->mtl_queues[qinx], OSI_ENABLE); + if (ret < 0) { + return ret; + } } /* configure MGBE MAC HW */ diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 94c971f..15fd39e 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -206,6 +206,7 @@ #define MGBE_MTL_TCQ_ETS_LCR_LC_MASK 0x1FFFFFFFU #define MGBE_8PTP_CYCLE 26U +#define MGBE_PTP_CLK_SPEED 312500000U #define MGBE_DMA_ISR_MTLIS OSI_BIT(16) #define MGBE_IMR_FPEIE OSI_BIT(15) #ifndef OSI_STRIPPED_LIB diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 6920db6..8fff81e 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -26,6 +26,8 @@ #include "../osi/common/common.h" #include "vlan_filter.h" #include "core_common.h" +#include "eqos_core.h" +#include "mgbe_core.h" #include "frp.h" #ifdef OSI_DEBUG #include "debug.h" @@ -285,29 +287,6 @@ static inline void init_vlan_filters(struct osi_core_priv_data *const osi_core) } #endif -static nve32_t osi_hal_hw_core_init(struct osi_core_priv_data *const osi_core) -{ - struct core_local *l_core = (struct core_local *)(void *)osi_core; - nve32_t ret; - -#ifndef OSI_STRIPPED_LIB - init_vlan_filters(osi_core); - - /* Init FRP */ - init_frp(osi_core); -#endif /* !OSI_STRIPPED_LIB */ - - ret = l_core->ops_p->core_init(osi_core); - if (ret < 0) { - return ret; - } - - l_core->lane_status = OSI_ENABLE; - l_core->hw_init_successful = OSI_ENABLE; - - return ret; -} - /** * @brief osi_hal_hw_core_deinit - HW API for MAC deinitialization. * @@ -513,6 +492,94 @@ static nve32_t osi_ptp_configuration(struct osi_core_priv_data *const osi_core, return ret; } +static 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 *)(void *)osi_core; + nve32_t ret = 0; + + *mac_ver = osi_readla(osi_core, ((nveu8_t *)osi_core->base + (nve32_t)MAC_VERSION)) & + MAC_VERSION_SNVER_MASK; + + if (validate_mac_ver_update_chans(*mac_ver, &l_core->num_max_chans, + &l_core->l_mac_ver) == 0) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "Invalid MAC version\n", (nveu64_t)*mac_ver) + ret = -1; + } + + return ret; +} + +static nve32_t osi_hal_hw_core_init(struct osi_core_priv_data *const osi_core) +{ + struct core_local *l_core = (struct core_local *)(void *)osi_core; + const nveu32_t ptp_ref_clk_rate[3] = {EQOS_X_PTP_CLK_SPEED, EQOS_PTP_CLK_SPEED, + MGBE_PTP_CLK_SPEED}; + nve32_t ret; + + ret = osi_get_mac_version(osi_core, &osi_core->mac_ver); + if (ret < 0) { + goto fail; + } + + /* Bring MAC out of reset */ + ret = hw_poll_for_swr(osi_core); + if (ret < 0) { + goto fail; + } + +#ifndef OSI_STRIPPED_LIB + init_vlan_filters(osi_core); + + /* Init FRP */ + init_frp(osi_core); +#endif /* !OSI_STRIPPED_LIB */ + + ret = l_core->ops_p->core_init(osi_core); + if (ret < 0) { + goto fail; + } + + /* By default set MAC to Full duplex mode. + * Since this is a local function it will always return sucess, + * so no need to check for return value + */ + (void)hw_set_mode(osi_core, OSI_FULL_DUPLEX); + + /* By default enable rxcsum */ + ret = hw_config_rxcsum_offload(osi_core, OSI_ENABLE); + if (ret == 0) { + l_core->cfg.rxcsum = OSI_ENABLE; + l_core->cfg.flags |= DYNAMIC_CFG_RXCSUM; + } + + /* Set default PTP settings */ + osi_core->ptp_config.ptp_rx_queue = 3U; + osi_core->ptp_config.ptp_ref_clk_rate = ptp_ref_clk_rate[l_core->l_mac_ver]; + osi_core->ptp_config.ptp_filter = OSI_MAC_TCR_TSENA | OSI_MAC_TCR_TSCFUPDT | + OSI_MAC_TCR_TSCTRLSSR | OSI_MAC_TCR_TSVER2ENA | + OSI_MAC_TCR_TSIPENA | OSI_MAC_TCR_TSIPV6ENA | + OSI_MAC_TCR_TSIPV4ENA | OSI_MAC_TCR_SNAPTYPSEL_1; + osi_core->ptp_config.sec = 0; + osi_core->ptp_config.nsec = 0; + osi_core->ptp_config.one_nsec_accuracy = OSI_ENABLE; + ret = osi_ptp_configuration(osi_core, OSI_ENABLE); + if (ret < 0) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "Fail to configure PTP\n", 0ULL); + goto fail; + } + + /* Start the MAC */ + hw_start_mac(osi_core); + + l_core->lane_status = OSI_ENABLE; + l_core->hw_init_successful = OSI_ENABLE; + +fail: + return ret; +} + #ifndef OSI_STRIPPED_LIB static nve32_t conf_ptp_offload(struct osi_core_priv_data *const osi_core, struct osi_pto_config *const pto_config) @@ -945,22 +1012,7 @@ static nve32_t osi_adjust_time(struct osi_core_priv_data *const osi_core, osi_core->ptp_config.one_nsec_accuracy); } -static 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 *)(void *)osi_core; - *mac_ver = osi_readla(osi_core, ((nveu8_t *)osi_core->base + (nve32_t)MAC_VERSION)) & - MAC_VERSION_SNVER_MASK; - - if (validate_mac_ver_update_chans(*mac_ver, &l_core->num_max_chans, - &l_core->l_mac_ver) == 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid MAC version\n", (nveu64_t)*mac_ver) - return -1; - } - - return 0; -} #ifndef OSI_STRIPPED_LIB /** @@ -2111,21 +2163,6 @@ static nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, } break; -#endif /* !OSI_STRIPPED_LIB */ - 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); - if (ret == 0) { - (void)osi_memcpy(&l_core->cfg.avb[data->avb.qindex].avb_info, - &data->avb, sizeof(struct osi_core_avb_algorithm)); - l_core->cfg.avb[data->avb.qindex].used = OSI_ENABLE; - l_core->cfg.flags |= DYNAMIC_CFG_AVB; - } - break; - case OSI_CMD_CONFIG_FW_ERR: ret = hw_config_fw_err_pkts(osi_core, data->arg1_u32, data->arg2_u32); break; @@ -2143,6 +2180,28 @@ static nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, hw_stop_mac(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 = hw_set_mode(osi_core, data->arg6_32); + break; +#endif /* !OSI_STRIPPED_LIB */ + + 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); + if (ret == 0) { + (void)osi_memcpy(&l_core->cfg.avb[data->avb.qindex].avb_info, + &data->avb, sizeof(struct osi_core_avb_algorithm)); + l_core->cfg.avb[data->avb.qindex].used = OSI_ENABLE; + l_core->cfg.flags |= DYNAMIC_CFG_AVB; + } + break; case OSI_CMD_COMMON_ISR: ops_p->handle_common_intr(osi_core); @@ -2158,14 +2217,6 @@ static nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *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 = hw_set_mode(osi_core, data->arg6_32); - break; - case OSI_CMD_SET_SPEED: ret = hw_set_speed(osi_core, data->arg6_32); break; From a84c9dafe3c42d0061479f7a0a9c80dcf5880da2 Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Fri, 11 Nov 2022 13:25:59 +0530 Subject: [PATCH 425/458] nvethernetrm: take arguments field out of union ioctl_data as well as arguments required to support PTP IOCTL in ASIL path Bug 3868362 Change-Id: Id6d3cf7626b7426a8e44a086335501cf86f50d62 Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2807393 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- include/ivc_core.h | 5 +++-- include/osi_common.h | 2 ++ osi/core/ivc_core.c | 30 +++++++++++++++--------------- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/include/ivc_core.h b/include/ivc_core.h index c2a6513..9392699 100644 --- a/include/ivc_core.h +++ b/include/ivc_core.h @@ -140,9 +140,10 @@ typedef struct ivc_msg_common { /** message count, used for debug */ nveu32_t count; + /** IVC argument structure */ + ivc_args args; + union { - /** IVC argument structure */ - ivc_args args; /** avb algorithm structure */ struct osi_core_avb_algorithm avb_algo; /** OSI filter structure */ diff --git a/include/osi_common.h b/include/osi_common.h index de3e13e..3b55f2d 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -211,6 +211,8 @@ #define OSI_NONE 0U #define OSI_NONE_SIGNED 0 #define OSI_DISABLE 0U +#define OSI_H_DISABLE 0x10101010U +#define OSI_H_ENABLE (~OSI_H_DISABLE) #define OSI_BIT(nr) ((nveu32_t)1 << (nr)) diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index c319a16..936f290 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -149,10 +149,10 @@ static nve32_t ivc_write_phy_reg(struct osi_core_priv_data *const osi_core, 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; + msg.args.arguments[index++] = phyaddr; + msg.args.arguments[index++] = phyreg; + msg.args.arguments[index++] = phydata; + msg.args.count = index; return osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); } @@ -180,9 +180,9 @@ static nve32_t ivc_read_phy_reg(struct osi_core_priv_data *const osi_core, 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; + msg.args.arguments[index++] = phyaddr; + msg.args.arguments[index++] = phyreg; + msg.args.count = index; return osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); } @@ -386,9 +386,9 @@ static nve32_t ivc_macsec_enable(struct osi_core_priv_data *const osi_core, osi_memset(&msg, 0, sizeof(msg)); msg.cmd = en_macsec; - msg.data.args.arguments[index] = enable; + msg.args.arguments[index] = enable; index++; - msg.data.args.count = index; + msg.args.count = index; return osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); } @@ -412,9 +412,9 @@ static nve32_t ivc_macsec_loopback_config(struct osi_core_priv_data *const osi_c osi_memset(&msg, 0, sizeof(msg)); msg.cmd = loopback_config_macsec; - msg.data.args.arguments[index] = enable; + msg.args.arguments[index] = enable; index++; - msg.data.args.count = index; + msg.args.count = index; return osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); } @@ -473,9 +473,9 @@ static nve32_t ivc_macsec_cipher_config(struct osi_core_priv_data *const osi_cor osi_memset(&msg, 0, sizeof(msg)); msg.cmd = cipher_config; - msg.data.args.arguments[index] = cipher; + msg.args.arguments[index] = cipher; index++; - msg.data.args.count = index; + msg.args.count = index; return osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); } @@ -564,9 +564,9 @@ static nve32_t ivc_macsec_init(struct osi_core_priv_data *const osi_core, osi_memset(&msg, 0, sizeof(msg)); msg.cmd = init_macsec; - msg.data.args.arguments[index] = mtu; + msg.args.arguments[index] = mtu; index++; - msg.data.args.count = index; + msg.args.count = index; return osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); } From 4cb630ef6ef65e38ffe8649249fccadbae9f768d Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Mon, 14 Nov 2022 15:10:14 +0530 Subject: [PATCH 426/458] osi: core: Update ethernet stats to VF osi core Issue: When the ethernet server got enabled, OSI core stats are not getting updated to VF's. Fix: Add IOCTL to copy OSI core stats into VF's OSI core structure. Bug 3763499 Change-Id: Ib0a957ff90805b7e716d8f5994e0a65d63660c1e Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2808680 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/ivc_core.h | 14 ++------ include/mmc.h | 36 ------------------- include/nvethernetrm_export.h | 33 +++++++++++++++-- include/osi_core.h | 27 ++------------ osi/core/eqos_core.c | 55 ++++++++++++++-------------- osi/core/ivc_core.c | 20 +++++++---- osi/core/mgbe_core.c | 68 +++++++++++++++++------------------ osi/core/osi_hal.c | 4 +-- 8 files changed, 115 insertions(+), 142 deletions(-) diff --git a/include/ivc_core.h b/include/ivc_core.h index 9392699..2be9f17 100644 --- a/include/ivc_core.h +++ b/include/ivc_core.h @@ -35,14 +35,6 @@ */ #define MAX_ARGS 10 -/* - *@brief All Stats - */ -struct osi_stats { - struct osi_mmc_counters mmc_s; - struct osi_tsn_stats tsn_s; -}; - /** * @brief IVC commands between OSD & OSI. */ @@ -151,13 +143,13 @@ typedef struct ivc_msg_common { /** OSI HW features */ struct osi_hw_features hw_feat; /** MMC counters */ - struct osi_mmc_counters mmc; + struct osi_mmc_counters mmc_s; + /** OSI stats counters */ + struct osi_stats stats_s; /** core argument structure */ ivc_core_args init_args; /** ioctl command structure */ struct osi_ioctl ioctl_data; - /** All stats */ - struct osi_stats eth_stats; #ifdef MACSEC_SUPPORT /** lut config */ struct osi_macsec_lut_config lut_config; diff --git a/include/mmc.h b/include/mmc.h index ef45f66..3b0a864 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -26,42 +26,6 @@ #include <nvethernet_type.h> #include "osi_common.h" -#ifndef OSI_STRIPPED_LIB -/** - * @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; -}; -#endif /* !OSI_STRIPPED_LIB */ - #ifdef MACSEC_SUPPORT /** * @brief The structure hold macsec statistics counters diff --git a/include/nvethernetrm_export.h b/include/nvethernetrm_export.h index 1dbbfb6..abecbbd 100644 --- a/include/nvethernetrm_export.h +++ b/include/nvethernetrm_export.h @@ -56,6 +56,9 @@ #define OSI_MTL_QUEUE_AVB 0x1U #define OSI_MTL_QUEUE_ENABLE 0x2U #define OSI_MTL_QUEUE_MODEMAX 0x3U +#ifndef OSI_STRIPPED_LIB +#define OSI_MTL_MAX_NUM_QUEUES 10U +#endif /** @} */ /** @@ -181,9 +184,9 @@ struct osi_fpe_config { }; /** - * @brief OSI Core TSN error stats structure + * @brief OSI Core error stats structure */ -struct osi_tsn_stats { +struct osi_stats { /** Constant Gate Control Error */ nveu64_t const_gate_ctr_err; /** Head-Of-Line Blocking due to Scheduling */ @@ -198,6 +201,32 @@ struct osi_tsn_stats { nveu64_t base_time_reg_err; /** Switch to Software Owned List Complete */ nveu64_t sw_own_list_complete; +#ifndef OSI_STRIPPED_LIB + /** 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; + /** RX buffer unavailable irq count */ + nveu64_t rx_buf_unavail_irq_n[OSI_MTL_MAX_NUM_QUEUES]; + /** Transmit Process Stopped irq count */ + nveu64_t tx_proc_stopped_irq_n[OSI_MTL_MAX_NUM_QUEUES]; + /** Transmit Buffer Unavailable irq count */ + nveu64_t tx_buf_unavail_irq_n[OSI_MTL_MAX_NUM_QUEUES]; + /** Receive Process Stopped irq count */ + nveu64_t rx_proc_stopped_irq_n[OSI_MTL_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; + /** lock fail count node addition */ + nveu64_t ts_lock_add_fail; + /** lock fail count node removal */ + nveu64_t ts_lock_del_fail; +#endif }; /** diff --git a/include/osi_core.h b/include/osi_core.h index 25d2aa2..e54921e 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -276,6 +276,7 @@ typedef my_lint_64 nvel64_t; #ifdef HSI_SUPPORT #define OSI_CMD_HSI_INJECT_ERR 55U #endif +#define OSI_CMD_READ_STATS 56U /** @} */ /** @@ -1216,22 +1217,6 @@ struct core_padctrl { nveu32_t pad_calibration_enable; }; -#ifndef OSI_STRIPPED_LIB -/** - * @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; -}; -#endif - #ifdef HSI_SUPPORT /** * @brief The OSI Core HSI private data structure. @@ -1352,8 +1337,6 @@ struct osi_core_priv_data { /** TQ:TC mapping */ nveu32_t tc[OSI_MGBE_MAX_NUM_CHANS]; #ifndef OSI_STRIPPED_LIB - /** xtra sw error counters */ - struct osi_xtra_stat_counters xstats; /** Memory mapped base address of HV window */ void *hv_base; /** csr clock is to program LPI 1 us tick timer register. @@ -1382,8 +1365,8 @@ struct osi_core_priv_data { * 1- Successful and can be used between P2P device */ nveu32_t fpe_ready; - /** TSN stats counters */ - struct osi_tsn_stats tsn_stats; + /** MAC stats counters */ + struct osi_stats stats; /** eqos pad control structure */ struct core_padctrl padctrl; /** MDC clock rate */ @@ -1409,10 +1392,6 @@ struct osi_core_priv_data { nveu32_t phy_iface_mode; /** MGBE MAC instance ID's */ nveu32_t instance_id; -#ifndef OSI_STRIPPED_LIB - /** Packet error stats */ - struct osi_core_pkt_err_stats pkt_err_stats; -#endif /** Ethernet controller MAC to MAC Time sync role * 1 - Primary interface, 2 - secondary interface, 0 - inactive interface */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index d6ecb12..3239d9e 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1561,33 +1561,33 @@ static inline void update_dma_sr_stats( 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] = + val = osi_core->stats.rx_buf_unavail_irq_n[qinx]; + osi_core->stats.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] = + val = osi_core->stats.tx_proc_stopped_irq_n[qinx]; + osi_core->stats.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] = + val = osi_core->stats.tx_buf_unavail_irq_n[qinx]; + osi_core->stats.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] = + val = osi_core->stats.rx_proc_stopped_irq_n[qinx]; + osi_core->stats.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 = + val = osi_core->stats.rx_watchdog_irq_n; + osi_core->stats.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 = + val = osi_core->stats.fatal_bus_error_irq_n; + osi_core->stats.fatal_bus_error_irq_n = osi_update_stats_counter(val, 1U); } } @@ -1634,15 +1634,15 @@ static void eqos_handle_mtl_intrs(struct osi_core_priv_data *osi_core) /* 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 = + stat_val = osi_core->stats.const_gate_ctr_err; + osi_core->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 = + stat_val = osi_core->stats.head_of_line_blk_sch; + osi_core->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 + @@ -1651,8 +1651,8 @@ static void eqos_handle_mtl_intrs(struct osi_core_priv_data *osi_core) 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] = + stat_val = osi_core->stats.hlbs_q[i]; + osi_core->stats.hlbs_q[i] = osi_update_stats_counter(stat_val, 1U); } } @@ -1675,8 +1675,8 @@ static void eqos_handle_mtl_intrs(struct osi_core_priv_data *osi_core) 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 = + stat_val = osi_core->stats.head_of_line_blk_frm; + osi_core->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 + @@ -1685,8 +1685,8 @@ static void eqos_handle_mtl_intrs(struct osi_core_priv_data *osi_core) 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] = + stat_val = osi_core->stats.hlbf_q[i]; + osi_core->stats.hlbf_q[i] = osi_update_stats_counter(stat_val, 1U); } } @@ -1713,15 +1713,15 @@ static void eqos_handle_mtl_intrs(struct osi_core_priv_data *osi_core) 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 = + stat_val = osi_core->stats.sw_own_list_complete; + osi_core->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 = + stat_val = osi_core->stats.base_time_reg_err; + osi_core->stats.base_time_reg_err = osi_update_stats_counter(stat_val, 1U); osi_core->est_ready = OSI_DISABLE; } @@ -1818,7 +1818,8 @@ static void eqos_handle_hsi_intr(struct osi_core_priv_data *const osi_core) * 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 + * - Handle Non-TI/RI interrupts for all MTL queues and + * increments #osi_core_priv_data->stats * based on error detected per cahnnel. * - Calls eqos_handle_mac_intrs() to handle MAC interrupts. * - Refer to EQOS column of <<RM_10, (sequence diagram)>> for API details. diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index 936f290..da9c5a7 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -64,18 +64,26 @@ static nve32_t ivc_handle_ioctl(struct osi_core_priv_data *osi_core, ret = osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); - if (data->cmd == OSI_CMD_READ_MMC) { + switch (data->cmd) { + case OSI_CMD_READ_MMC: (void)osi_memcpy((void *)&osi_core->mmc, - (void *)&msg.data.mmc, + (void *)&msg.data.mmc_s, sizeof(struct osi_mmc_counters)); - (void)osi_memcpy((void *)&osi_core->tsn_stats, - (void *)&msg.data.eth_stats.tsn_s, - sizeof(struct osi_tsn_stats)); - } else { + break; + + case OSI_CMD_READ_STATS: + (void)osi_memcpy((void *)&osi_core->stats, + (void *)&msg.data.stats_s, + sizeof(struct osi_stats)); + break; + + default: (void)osi_memcpy((void *)data, (void *)&msg.data.ioctl_data, sizeof(struct osi_ioctl)); + break; } + return ret; } diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 955320b..84dcd12 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -2771,23 +2771,23 @@ static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core, 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_core->stats.mgbe_jabber_timeout_err = osi_update_stats_counter( - osi_core->pkt_err_stats.mgbe_jabber_timeout_err, + osi_core->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_core->stats.mgbe_ip_header_err = osi_update_stats_counter( - osi_core->pkt_err_stats.mgbe_ip_header_err, + osi_core->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_core->stats.mgbe_payload_cs_err = osi_update_stats_counter( - osi_core->pkt_err_stats.mgbe_payload_cs_err, + osi_core->stats.mgbe_payload_cs_err, 1UL); } } @@ -2800,9 +2800,9 @@ static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core, /* mask return as initial value is returned always */ (void)__sync_fetch_and_sub(&l_core->ts_lock, 1); #ifndef OSI_STRIPPED_LIB - osi_core->xstats.ts_lock_add_fail = + osi_core->stats.ts_lock_add_fail = osi_update_stats_counter( - osi_core->xstats.ts_lock_add_fail, 1U); + osi_core->stats.ts_lock_add_fail, 1U); #endif /* !OSI_STRIPPED_LIB */ goto done; } @@ -2873,28 +2873,28 @@ static inline void mgbe_update_dma_sr_stats(struct osi_core_priv_data *osi_core, 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] = + val = osi_core->stats.rx_buf_unavail_irq_n[qinx]; + osi_core->stats.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] = + val = osi_core->stats.tx_proc_stopped_irq_n[qinx]; + osi_core->stats.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] = + val = osi_core->stats.tx_buf_unavail_irq_n[qinx]; + osi_core->stats.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] = + val = osi_core->stats.rx_proc_stopped_irq_n[qinx]; + osi_core->stats.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 = + val = osi_core->stats.fatal_bus_error_irq_n; + osi_core->stats.fatal_bus_error_irq_n = osi_update_stats_counter(val, 1U); } } @@ -3196,9 +3196,9 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core, /* Transmit Queue Underflow Interrupt Status */ if ((qstatus & MGBE_MTL_QINT_TXUNIFS) == MGBE_MTL_QINT_TXUNIFS) { #ifndef OSI_STRIPPED_LIB - osi_core->pkt_err_stats.mgbe_tx_underflow_err = + osi_core->stats.mgbe_tx_underflow_err = osi_update_stats_counter( - osi_core->pkt_err_stats.mgbe_tx_underflow_err, + osi_core->stats.mgbe_tx_underflow_err, 1UL); #endif /* !OSI_STRIPPED_LIB */ } @@ -3226,15 +3226,15 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core, /* 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 = + stat_val = osi_core->stats.const_gate_ctr_err; + osi_core->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 = + stat_val = osi_core->stats.head_of_line_blk_sch; + osi_core->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 + @@ -3243,8 +3243,8 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core, 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] = + stat_val = osi_core->stats.hlbs_q[i]; + osi_core->stats.hlbs_q[i] = osi_update_stats_counter(stat_val, 1U); } } @@ -3263,8 +3263,8 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core, 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 = + stat_val = osi_core->stats.head_of_line_blk_frm; + osi_core->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 + @@ -3273,8 +3273,8 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core, 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] = + stat_val = osi_core->stats.hlbf_q[i]; + osi_core->stats.hlbf_q[i] = osi_update_stats_counter(stat_val, 1U); } } @@ -3302,15 +3302,15 @@ static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core, 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 = + stat_val = osi_core->stats.sw_own_list_complete; + osi_core->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 = + stat_val = osi_core->stats.base_time_reg_err; + osi_core->stats.base_time_reg_err = osi_update_stats_counter(stat_val, 1U); osi_core->est_ready = OSI_DISABLE; } diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 8fff81e..9d0f383 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -1537,9 +1537,9 @@ static inline nve32_t get_tx_ts(struct osi_core_priv_data *osi_core, /* mask return as initial value is returned always */ (void)__sync_fetch_and_sub(&l_core->ts_lock, 1); #ifndef OSI_STRIPPED_LIB - osi_core->xstats.ts_lock_del_fail = + osi_core->stats.ts_lock_del_fail = osi_update_stats_counter( - osi_core->xstats.ts_lock_del_fail, 1U); + osi_core->stats.ts_lock_del_fail, 1U); #endif goto done; } From 61db74f9dce5366112382a383117a95e5ac3d1c7 Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Wed, 23 Nov 2022 14:56:32 +0530 Subject: [PATCH 427/458] osi: core: Disable TXESIE for safety Issue: Observed common intrrupt on safety builds as TXESIE is not served. Fix: Disable TXESIE intrrupt for safety builds Bug 3846917 Change-Id: I8f01d382eb2979439f7a82fce346c66f1133061f Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2814604 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/mgbe_core.c | 5 ++++- osi/core/mgbe_core.h | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 84dcd12..8452b26 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -2384,7 +2384,10 @@ static nve32_t mgbe_configure_mac(struct osi_core_priv_data *osi_core) /* 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); +#ifndef OSI_STRIPPED_LIB + value |= (MGBE_IMR_TXESIE); +#endif + value |= (MGBE_IMR_RGSMIIIE | MGBE_IMR_TSIE); osi_writela(osi_core, value, (nveu8_t *)osi_core->base + MGBE_MAC_IER); /* Enable common interrupt at wrapper level */ diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 15fd39e..7514722 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -165,6 +165,7 @@ #define MGBE_MTL_RXP_BYPASS_CNT 2U #define MGBE_MAC_FPE_CTS_SVER OSI_BIT(1) +#define MGBE_IMR_TXESIE OSI_BIT(13) #endif /* !OSI_STRIPPED_LIB */ #define MGBE_MTL_EST_CONTROL 0x1050 @@ -556,7 +557,6 @@ #define MGBE_MAC_RQC1R_MCBCQ_SHIFT 8U #define MGBE_IMR_RGSMIIIE OSI_BIT(0) #define MGBE_IMR_TSIE OSI_BIT(12) -#define MGBE_IMR_TXESIE OSI_BIT(13) #define MGBE_ISR_TSIS OSI_BIT(12) #define MGBE_DMA_ISR_MACIS OSI_BIT(17) #define MGBE_DMA_ISR_DCH0_DCH15_MASK 0x3FFU From 7a588a1fc6e84ad888b15bb17005529e5cbf5210 Mon Sep 17 00:00:00 2001 From: Hareesh Kesireddy <hkesireddy@nvidia.com> Date: Wed, 26 Oct 2022 18:13:39 +0530 Subject: [PATCH 428/458] osi: l3l4: support four tuple for l3l4 fitlers Following implemented for non safety. - Moved l3l4 filter index assignment to OSI for better management. OSDs need not worry about managing l3l4 filter indexes. - Restructured code to support four tuple for osi l3 l4 filter. - Added a wildcard l3l4 filter at highest filter index to allow the the packets to receive on default dma channel (from l2 filter) for the packets which do not match with any of the configured l3 l4 filters. - For IPv4, allowed user to configure all SA+DA+SP+DP together at a single l3l4 filter index or user can selectively add any combination among them (e.g, only SA or SP+DA, etc.). - For IPV6, only restriction is to add either of the SA or DA only but not both at a time at a single l3l4 index. Bug 3576506 Bug 3825731 Change-Id: I20bd197f5bf793a77f5e723d1875875d442af66e Signed-off-by: Hareesh Kesireddy <hkesireddy@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2802626 Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- include/nvethernet_type.h | 7 - include/nvethernetrm_l3l4.h | 89 +++++ include/osi_common.h | 1 - include/osi_core.h | 30 +- osi/common/common.h | 12 +- osi/core/core_common.c | 224 ++++++++++++ osi/core/core_common.h | 31 ++ osi/core/core_local.h | 63 +--- osi/core/eqos_core.c | 637 +++----------------------------- osi/core/eqos_core.h | 65 +--- osi/core/mgbe_core.c | 711 ++++-------------------------------- osi/core/mgbe_core.h | 63 +--- osi/core/osi_hal.c | 488 +++++++++++++++++-------- 13 files changed, 835 insertions(+), 1586 deletions(-) create mode 100644 include/nvethernetrm_l3l4.h diff --git a/include/nvethernet_type.h b/include/nvethernet_type.h index 929a062..b80e8fc 100644 --- a/include/nvethernet_type.h +++ b/include/nvethernet_type.h @@ -63,12 +63,5 @@ typedef my_ulint_64 nveul64_t; typedef my_uint64_t nveu64_t; /** @} */ -#ifndef OSI_STRIPPED_LIB -/** intermediate type for short */ -typedef short my_int16_t; -/** typedef equivalent to short */ -typedef my_int16_t nve16_t; -#endif /* !OSI_STRIPPED_LIB */ - #endif /* INCLUDED_TYPE_H */ diff --git a/include/nvethernetrm_l3l4.h b/include/nvethernetrm_l3l4.h new file mode 100644 index 0000000..65e8c7b --- /dev/null +++ b/include/nvethernetrm_l3l4.h @@ -0,0 +1,89 @@ +/* + * 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_NVETHERNETRM_L3L4_H +#define INCLUDED_NVETHERNETRM_L3L4_H + +#include <nvethernet_type.h> + +/** helper macro for enable */ +#define OSI_TRUE ((nveu32_t)1U) + +/** helper macro to disable */ +#define OSI_FALSE ((nveu32_t)0U) + +/** + * @brief L3/L4 filter function dependent parameter + */ +struct osi_l3_l4_filter { + /** filter data */ + struct { +#ifndef OSI_STRIPPED_LIB + /** udp (OSI_TRUE) or tcp (OSI_FALSE) */ + nveu32_t is_udp; + /** ipv6 (OSI_TRUE) or ipv4 (OSI_FALSE) */ + nveu32_t is_ipv6; + /** perfect(OSI_FALSE) or inverse(OSI_TRUE) */ + nveu32_t perfect_inverse_match; +#endif /* !OSI_STRIPPED_LIB */ + /** destination ip address information */ + struct { + /** ipv4 address */ + nveu8_t ip4_addr[4]; +#ifndef OSI_STRIPPED_LIB + /** ipv6 address */ + nveu16_t ip6_addr[8]; + /** Port number */ + nveu16_t port_no; + /** addr match enable (OSI_TRUE) or disable (OSI_FALSE) */ + nveu32_t addr_match; + /** port match enable (OSI_TRUE) or disable (OSI_FALSE) */ + nveu32_t port_match; +#endif /* !OSI_STRIPPED_LIB */ + } dst; +#ifndef OSI_STRIPPED_LIB + /** ip address and port information */ + struct { + /** ipv4 address */ + nveu8_t ip4_addr[4]; + /** ipv6 address */ + nveu16_t ip6_addr[8]; + /** Port number */ + nveu16_t port_no; + /** addr match enable (OSI_TRUE) or disable (OSI_FALSE) */ + nveu32_t addr_match; + /** port match enable (OSI_TRUE) or disable (OSI_FALSE) */ + nveu32_t port_match; + } src; +#endif /* !OSI_STRIPPED_LIB */ + } data; +#ifndef OSI_STRIPPED_LIB + /** Represents whether DMA routing enabled (OSI_TRUE) or not (OSI_FALSE) */ + nveu32_t dma_routing_enable; +#endif /* !OSI_STRIPPED_LIB */ + /** DMA channel number of routing enabled */ + nveu32_t dma_chan; + /** filter enable (OSI_TRUE) or disable (OSI_FALSE) */ + nveu32_t filter_enb_dis; +}; + +#endif /* INCLUDED_NVETHERNETRM_L3L4_H */ diff --git a/include/osi_common.h b/include/osi_common.h index 3b55f2d..8dd1a13 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -228,7 +228,6 @@ #define OSI_MGBE_MAC_3_10 0x31U #define OSI_MAX_VM_IRQS 5U -#define OSI_IP4_FILTER 0U #ifndef OSI_STRIPPED_LIB #define OSI_HASH_FILTER_MODE 1U diff --git a/include/osi_core.h b/include/osi_core.h index e54921e..5e65d26 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -24,6 +24,7 @@ #define INCLUDED_OSI_CORE_H #include "nvethernetrm_export.h" +#include "nvethernetrm_l3l4.h" #include <osi_common.h> #include "mmc.h" @@ -166,7 +167,9 @@ typedef my_lint_64 nvel64_t; #define EQOS_MAX_L3_L4_FILTER 8U #define OSI_MGBE_MAX_MAC_ADDRESS_FILTER 32U #define OSI_DA_MATCH 0U +#ifndef OSI_STRIPPED_LIB #define OSI_INV_MATCH 1U +#endif /* !OSI_STRIPPED_LIB */ #define OSI_AMASK_DISABLE 0U #define OSI_CHAN_ANY 0xFFU #define OSI_DFLT_MTU_SIZE 1500U @@ -182,11 +185,6 @@ typedef my_lint_64 nvel64_t; #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. */ @@ -201,7 +199,6 @@ typedef my_lint_64 nvel64_t; #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 @@ -488,27 +485,6 @@ struct osi_rxq_route { }; #endif -/** - * @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. */ diff --git a/osi/common/common.h b/osi/common/common.h index 83ff916..8bdfebe 100644 --- a/osi/common/common.h +++ b/osi/common/common.h @@ -332,10 +332,10 @@ done: * - Run time: Yes * - De-initialization: No */ -static inline nve32_t osi_memcpy(void *dest, void *src, nveu64_t n) +static inline nve32_t osi_memcpy(void *dest, const void *src, nveu64_t n) { - nve8_t *cdest = (nve8_t *)dest; - const nve8_t *csrc = (nve8_t *)src; + nve8_t *cdest = dest; + const nve8_t *csrc = src; nve32_t ret = 0; nveu64_t i = 0; @@ -351,10 +351,10 @@ fail: return ret; } -static inline nve32_t osi_memcmp(void *dest, void *src, nve32_t n) +static inline nve32_t osi_memcmp(const void *dest, const void *src, nve32_t n) { - const nve8_t *const cdest = (nve8_t *)dest; - const nve8_t *const csrc = (nve8_t *)src; + const nve8_t *const cdest = dest; + const nve8_t *const csrc = src; nve32_t ret = 0; nve32_t i; diff --git a/osi/core/core_common.c b/osi/core/core_common.c index fa92f15..c977db5 100644 --- a/osi/core/core_common.c +++ b/osi/core/core_common.c @@ -1495,3 +1495,227 @@ void hsi_common_error_inject(struct osi_core_priv_data *osi_core, } } #endif + +/** + * @brief prepare_l3l4_ctr_reg - Prepare control register for L3L4 filters. + * + * @note + * Algorithm: + * - This sequence is used to prepare L3L4 control register for SA and DA Port Number matching. + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] l3_l4: Pointer to l3 l4 filter structure (#osi_l3_l4_filter) + * @param[out] ctr_reg: Pointer to L3L4 CTR register value + * + * @note 1) MAC should be init and started. see osi_start_mac() + * + * @retval L3L4 CTR register value + */ +static void prepare_l3l4_ctr_reg(const struct osi_core_priv_data *const osi_core, + const struct osi_l3_l4_filter *const l3_l4, + nveu32_t *ctr_reg) +{ +#ifndef OSI_STRIPPED_LIB + nveu32_t perfect_inverse_match = l3_l4->data.perfect_inverse_match; + nveu32_t dma_routing_enable = l3_l4->dma_routing_enable; + nveu32_t dst_addr_match = l3_l4->data.dst.addr_match; +#else + nveu32_t perfect_inverse_match = OSI_FALSE; + nveu32_t dma_routing_enable = OSI_TRUE; + nveu32_t dst_addr_match = OSI_TRUE; +#endif /* !OSI_STRIPPED_LIB */ + const nveu32_t dma_chan_shift[2] = { + EQOS_MAC_L3L4_CTR_DMCHN_SHIFT, + MGBE_MAC_L3L4_CTR_DMCHN_SHIFT + }; + + const nveu32_t dma_chan_en_shift[2] = { + EQOS_MAC_L3L4_CTR_DMCHEN_SHIFT, + MGBE_MAC_L3L4_CTR_DMCHEN_SHIFT + }; + nveu32_t value = 0U; + + /* set routing dma channel */ + value |= dma_routing_enable << (dma_chan_en_shift[osi_core->mac] & 0x1FU); + value |= l3_l4->dma_chan << (dma_chan_shift[osi_core->mac] & 0x1FU); + + /* Enable L3 filters for IPv4 DESTINATION addr matching */ + value |= (dst_addr_match << MAC_L3L4_CTR_L3DAM_SHIFT) | + (perfect_inverse_match << MAC_L3L4_CTR_L3DAIM_SHIFT); + +#ifndef OSI_STRIPPED_LIB + /* Enable L3 filters for IPv4 SOURCE addr matching */ + value |= (l3_l4->data.src.addr_match << MAC_L3L4_CTR_L3SAM_SHIFT) | + (perfect_inverse_match << MAC_L3L4_CTR_L3SAIM_SHIFT); + + /* Enable L4 filters for DESTINATION port No matching */ + value |= (l3_l4->data.dst.port_match << MAC_L3L4_CTR_L4DPM_SHIFT) | + (perfect_inverse_match << MAC_L3L4_CTR_L4DPIM_SHIFT); + + /* Enable L4 filters for SOURCE Port No matching */ + value |= (l3_l4->data.src.port_match << MAC_L3L4_CTR_L4SPM_SHIFT) | + (perfect_inverse_match << MAC_L3L4_CTR_L4SPIM_SHIFT); + + /* set udp / tcp port matching bit (for l4) */ + value |= l3_l4->data.is_udp << MAC_L3L4_CTR_L4PEN_SHIFT; + + /* set ipv4 / ipv6 protocol matching bit (for l3) */ + value |= l3_l4->data.is_ipv6 << MAC_L3L4_CTR_L3PEN_SHIFT; +#endif /* !OSI_STRIPPED_LIB */ + + *ctr_reg = value; +} + +/** + * @brief prepare_l3_addr_registers - prepare register data for IPv4/IPv6 address filtering + * + * @note + * Algorithm: + * - Update IPv4/IPv6 source/destination address for L3 layer filtering. + * - For IPv4, both source/destination address can be configured but + * for IPv6, only one of the source/destination address can be configured. + * + * @param[in] l3_l4: Pointer to l3 l4 filter structure (#osi_l3_l4_filter) + * @param[out] l3_addr1_reg: Pointer to L3 ADDR1 register value + * + * @note 1) MAC should be init and started. see osi_start_mac() + */ +static void prepare_l3_addr_registers(const struct osi_l3_l4_filter *const l3_l4, +#ifndef OSI_STRIPPED_LIB + nveu32_t *l3_addr0_reg, + nveu32_t *l3_addr2_reg, + nveu32_t *l3_addr3_reg, +#endif /* !OSI_STRIPPED_LIB */ + nveu32_t *l3_addr1_reg) +{ +#ifndef OSI_STRIPPED_LIB + if (l3_l4->data.is_ipv6 == OSI_TRUE) { + const nveu16_t *addr; + /* For IPv6, either source address or destination + * address only one of them can be enabled + */ + if (l3_l4->data.src.addr_match == OSI_TRUE) { + /* select src address only */ + addr = l3_l4->data.src.ip6_addr; + } else { + /* select dst address only */ + addr = l3_l4->data.dst.ip6_addr; + } + /* update Bits[31:0] of 128-bit IP addr */ + *l3_addr0_reg = addr[7] | ((nveu32_t)addr[6] << 16); + + /* update Bits[63:32] of 128-bit IP addr */ + *l3_addr1_reg = addr[5] | ((nveu32_t)addr[4] << 16); + + /* update Bits[95:64] of 128-bit IP addr */ + *l3_addr2_reg = addr[3] | ((nveu32_t)addr[2] << 16); + + /* update Bits[127:96] of 128-bit IP addr */ + *l3_addr3_reg = addr[1] | ((nveu32_t)addr[0] << 16); + } else { +#endif /* !OSI_STRIPPED_LIB */ + const nveu8_t *addr; + nveu32_t value; + +#ifndef OSI_STRIPPED_LIB + /* set source address */ + addr = l3_l4->data.src.ip4_addr; + value = addr[3]; + value |= (nveu32_t)addr[2] << 8; + value |= (nveu32_t)addr[1] << 16; + value |= (nveu32_t)addr[0] << 24; + *l3_addr0_reg = value; +#endif /* !OSI_STRIPPED_LIB */ + + /* set destination address */ + addr = l3_l4->data.dst.ip4_addr; + value = addr[3]; + value |= (nveu32_t)addr[2] << 8; + value |= (nveu32_t)addr[1] << 16; + value |= (nveu32_t)addr[0] << 24; + *l3_addr1_reg = value; +#ifndef OSI_STRIPPED_LIB + } +#endif /* !OSI_STRIPPED_LIB */ +} + +#ifndef OSI_STRIPPED_LIB +/** + * @brief prepare_l4_port_register - program source and destination port number + * + * @note + * Algorithm: + * - Program l4 address register with source and destination port numbers. + * + * @param[in] l3_l4: Pointer to l3 l4 filter structure (#osi_l3_l4_filter) + * @param[out] l4_addr_reg: Pointer to L3 ADDR0 register value + * + * @note 1) MAC should be init and started. see osi_start_mac() + * 3) DCS bits should be enabled in RXQ to DMA mapping register + */ +static void prepare_l4_port_register(const struct osi_l3_l4_filter *const l3_l4, + nveu32_t *l4_addr_reg) +{ + nveu32_t value = 0U; + + /* set source port */ + value |= ((nveu32_t)l3_l4->data.src.port_no + & MGBE_MAC_L4_ADDR_SP_MASK); + + /* set destination port */ + value |= (((nveu32_t)l3_l4->data.dst.port_no << + MGBE_MAC_L4_ADDR_DP_SHIFT) & MGBE_MAC_L4_ADDR_DP_MASK); + + *l4_addr_reg = value; +} +#endif /* !OSI_STRIPPED_LIB */ + +/** + * @brief prepare_l3l4_registers - function to prepare l3l4 registers + * + * @note + * Algorithm: + * - If filter to be enabled, + * - Prepare l3 ip address registers using prepare_l3_addr_registers(). + * - Prepare l4 port register using prepare_l4_port_register(). + * - Prepare l3l4 control register using prepare_l3l4_ctr_reg(). + * + * @param[in] osi_core: OSI core private data structure. + * @param[in] l3_l4: Pointer to l3 l4 filter structure (#osi_l3_l4_filter) + * @param[out] l4_addr_reg: Pointer to L3 ADDR0 register value + * + * @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 + */ +void prepare_l3l4_registers(const struct osi_core_priv_data *const osi_core, + const struct osi_l3_l4_filter *const l3_l4, +#ifndef OSI_STRIPPED_LIB + nveu32_t *l3_addr0_reg, + nveu32_t *l3_addr2_reg, + nveu32_t *l3_addr3_reg, + nveu32_t *l4_addr_reg, +#endif /* !OSI_STRIPPED_LIB */ + nveu32_t *l3_addr1_reg, + nveu32_t *ctr_reg) +{ + /* prepare regiser data if filter to be enabled */ + if (l3_l4->filter_enb_dis == OSI_TRUE) { + /* prepare l3 filter ip address register data */ + prepare_l3_addr_registers(l3_l4, +#ifndef OSI_STRIPPED_LIB + l3_addr0_reg, + l3_addr2_reg, + l3_addr3_reg, +#endif /* !OSI_STRIPPED_LIB */ + l3_addr1_reg); + +#ifndef OSI_STRIPPED_LIB + /* prepare l4 filter port register data */ + prepare_l4_port_register(l3_l4, l4_addr_reg); +#endif /* !OSI_STRIPPED_LIB */ + + /* prepare control register data */ + prepare_l3l4_ctr_reg(osi_core, l3_l4, ctr_reg); + } +} diff --git a/osi/core/core_common.h b/osi/core/core_common.h index c858835..58fe13a 100644 --- a/osi/core/core_common.h +++ b/osi/core/core_common.h @@ -97,6 +97,27 @@ #define MAC_PKT_FILTER_REG 0x0008 #define HW_MAC_IER 0x00B4U #define WRAP_COMMON_INTR_ENABLE 0x8704U + +/* common l3 l4 register bit fields for eqos and mgbe */ +#ifndef OSI_STRIPPED_LIB +#define MAC_L3L4_CTR_L3PEN_SHIFT 0 +#define MAC_L3L4_CTR_L3SAM_SHIFT 2 +#define MAC_L3L4_CTR_L3SAIM_SHIFT 3 +#endif /* !OSI_STRIPPED_LIB */ +#define MAC_L3L4_CTR_L3DAM_SHIFT 4 +#define MAC_L3L4_CTR_L3DAIM_SHIFT 5 +#ifndef OSI_STRIPPED_LIB +#define MAC_L3L4_CTR_L4PEN_SHIFT 16 +#define MAC_L3L4_CTR_L4SPM_SHIFT 18 +#define MAC_L3L4_CTR_L4SPIM_SHIFT 19 +#define MAC_L3L4_CTR_L4DPM_SHIFT 20 +#define MAC_L3L4_CTR_L4DPIM_SHIFT 21 +#endif /* !OSI_STRIPPED_LIB */ +#define EQOS_MAC_L3L4_CTR_DMCHN_SHIFT 24 /* 3 bits */ +#define EQOS_MAC_L3L4_CTR_DMCHEN_SHIFT 28 +#define MGBE_MAC_L3L4_CTR_DMCHN_SHIFT 24 /* 4 bits */ +#define MGBE_MAC_L3L4_CTR_DMCHEN_SHIFT 31 + /** * @addtogroup typedef related info * @@ -142,6 +163,16 @@ nve32_t hw_config_fpe(struct osi_core_priv_data *const osi_core, struct osi_fpe_config *const fpe); void hw_tsn_init(struct osi_core_priv_data *osi_core, nveu32_t est_sel, nveu32_t fpe_sel); +void prepare_l3l4_registers(const struct osi_core_priv_data *const osi_core, + const struct osi_l3_l4_filter *const l3_l4, +#ifndef OSI_STRIPPED_LIB + nveu32_t *l3_addr0_reg, + nveu32_t *l3_addr2_reg, + nveu32_t *l3_addr3_reg, + nveu32_t *l4_addr_reg, +#endif /* !OSI_STRIPPED_LIB */ + nveu32_t *l3_addr1_reg, + nveu32_t *ctr_reg); #ifdef HSI_SUPPORT void hsi_common_error_inject(struct osi_core_priv_data *osi_core, nveu32_t error_code); diff --git a/osi/core/core_local.h b/osi/core/core_local.h index cc951ae..1b3af20 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -118,15 +118,10 @@ struct core_ops { 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 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 configure L3L4 filter */ + nve32_t (*config_l3l4_filters)(struct osi_core_priv_data *const osi_core, + nveu32_t filter_no, + const struct osi_l3_l4_filter *const l3_l4); /** Called to adjust the mac time */ nve32_t (*adjust_mactime)(struct osi_core_priv_data *const osi_core, const nveu32_t sec, @@ -147,11 +142,6 @@ struct core_ops { /** 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 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 read reg */ nveu32_t (*read_reg)(struct osi_core_priv_data *const osi_core, const nve32_t reg); @@ -173,25 +163,6 @@ struct core_ops { #endif /* !OSI_STRIPPED_LIB */ #endif /* MACSEC_SUPPORT */ #ifndef OSI_STRIPPED_LIB - /** 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 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); @@ -315,24 +286,6 @@ struct core_ptp_servo { }; #endif -/** - * @brief L3/L4 dynamic config storage structure. - */ -struct l3_l4_filters { - /** Represent whether index used or not */ - nveu32_t used; - /** Type of filter */ - nveu32_t type; - /** Represents whether DMA routing enabled or not */ - nveu32_t dma_routing_enable; - /** DMA channel number of routing enabled */ - nveu32_t dma_chan; - /** Tells whether its L4 or L3 filter */ - nveu32_t is_l4_filter; - /** Filter information */ - struct osi_l3_l4_filter l3l4_filter; -}; - /** * @brief AVB dynamic config storage structure */ @@ -367,7 +320,7 @@ struct core_l2 { struct dynamic_cfg { nveu32_t flags; /** L3_L4 filters */ - struct l3_l4_filters l3_l4[OSI_MGBE_MAX_L3_L4_FILTER]; + struct osi_l3_l4_filter l3_l4[OSI_MGBE_MAX_L3_L4_FILTER]; /** flow control */ nveu32_t flow_ctrl; /** AVB */ @@ -441,6 +394,12 @@ struct core_local { nveu32_t lane_status; /** Exact MAC used across SOCs 0:Legacy EQOS, 1:Orin EQOS, 2:Orin MGBE */ nveu32_t l_mac_ver; +#ifndef OSI_STRIPPED_LIB +#ifdef L3L4_WILDCARD_FILTER + /** l3l4 wildcard filter configured (OSI_ENABLE) / not configured (OSI_DISABLE) */ + nveu32_t l3l4_wildcard_filter_configured; +#endif /* L3L4_WILDCARD_FILTER */ +#endif /* OSI_STRIPPED_LIB */ }; /** diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 3239d9e..d59f991 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1231,7 +1231,8 @@ static void eqos_dma_chan_to_vmirq_map(struct osi_core_priv_data *osi_core) * - 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 + * - 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. * @@ -2209,72 +2210,6 @@ static nve32_t eqos_update_mac_addr_low_high_reg( return ret; } -/** - * @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 <<RM_19, (sequence diagram)>> 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; -} - #ifndef OSI_STRIPPED_LIB /** * @brief eqos_config_ptp_offload - Enable/Disable PTP offload @@ -2376,548 +2311,76 @@ static nve32_t eqos_config_ptp_offload(struct osi_core_priv_data *const osi_core return ret; } - -/** - * @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 <<RM_19, (sequence diagram)>> 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 <<RM_19, (sequence diagram)>> 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; -} #endif /* !OSI_STRIPPED_LIB */ -/** \cond DO_NOT_DOCUMENT */ /** - * @brief eqos_set_dcs - check and update dma routing register + * @brief eqos_config_l3l4_filters - Config L3L4 filters. * * @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. + * - This sequence is used to configure L3L4 filters for SA and DA Port Number matching. + * - Prepare register data using prepare_l3l4_registers(). + * - Write l3l4 reigsters using mgbe_l3l4_filter_write(). + * - Return 0 on success. + * - Return -1 on any register failure. * * @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 + * @param[in] filter_no_r: filter index + * @param[in] l3_l4: Pointer to l3 l4 filter structure (#osi_l3_l4_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 <<RM_19, (sequence diagram)>> 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 + * @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 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) +static nve32_t eqos_config_l3l4_filters(struct osi_core_priv_data *const osi_core, + nveu32_t filter_no_r, + const struct osi_l3_l4_filter *const l3_l4) { - nveu32_t value = 0U; void *base = osi_core->base; +#ifndef OSI_STRIPPED_LIB + nveu32_t l3_addr0_reg = 0; + nveu32_t l3_addr2_reg = 0; + nveu32_t l3_addr3_reg = 0; + nveu32_t l4_addr_reg = 0; +#endif /* !OSI_STRIPPED_LIB */ + nveu32_t l3_addr1_reg = 0; + nveu32_t ctr_reg = 0; + nveu32_t filter_no = filter_no_r & (OSI_MGBE_MAX_L3_L4_FILTER - 1U); - 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; -} + prepare_l3l4_registers(osi_core, l3_l4, +#ifndef OSI_STRIPPED_LIB + &l3_addr0_reg, + &l3_addr2_reg, + &l3_addr3_reg, + &l4_addr_reg, +#endif /* !OSI_STRIPPED_LIB */ + &l3_addr1_reg, + &ctr_reg); #ifndef OSI_STRIPPED_LIB -/** - * @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 <<RM_19, (sequence diagram)>> 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; + /* Update l3 ip addr MGBE_MAC_L3_AD0R register */ + osi_writela(osi_core, l3_addr0_reg, (nveu8_t *)base + EQOS_MAC_L3_AD0R(filter_no)); - 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; - } + /* Update l3 ip addr MGBE_MAC_L3_AD2R register */ + osi_writela(osi_core, l3_addr2_reg, (nveu8_t *)base + EQOS_MAC_L3_AD2R(filter_no)); - 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; - } + /* Update l3 ip addr MGBE_MAC_L3_AD3R register */ + osi_writela(osi_core, l3_addr3_reg, (nveu8_t *)base + EQOS_MAC_L3_AD3R(filter_no)); - 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)); + /* Update l4 port EQOS_MAC_L4_ADR register */ + osi_writela(osi_core, l4_addr_reg, (nveu8_t *)base + EQOS_MAC_L4_ADR(filter_no)); +#endif /* !OSI_STRIPPED_LIB */ - 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); + /* Update l3 ip addr MGBE_MAC_L3_AD1R register */ + osi_writela(osi_core, l3_addr1_reg, (nveu8_t *)base + EQOS_MAC_L3_AD1R(filter_no)); + + /* Write CTR register */ + osi_writela(osi_core, ctr_reg, (nveu8_t *)base + EQOS_MAC_L3L4_CTR(filter_no)); return 0; } -#endif /* !OSI_STRIPPED_LIB */ /** * @brief eqos_poll_for_update_ts_complete - Poll for update time stamp @@ -4725,13 +4188,11 @@ void eqos_init_core_ops(struct core_ops *ops) ops->handle_common_intr = eqos_handle_common_intr; ops->pad_calibrate = eqos_pad_calibrate; ops->update_mac_addr_low_high_reg = eqos_update_mac_addr_low_high_reg; - ops->config_l3_filters = eqos_config_l3_filters; ops->adjust_mactime = eqos_adjust_mactime; ops->read_mmc = eqos_read_mmc; ops->write_phy_reg = eqos_write_phy_reg; ops->read_phy_reg = eqos_read_phy_reg; ops->get_hw_features = eqos_get_hw_features; - ops->update_ip4_addr = eqos_update_ip4_addr; ops->read_reg = eqos_read_reg; ops->write_reg = eqos_write_reg; ops->set_avb_algorithm = eqos_set_avb_algorithm; @@ -4746,10 +4207,8 @@ void eqos_init_core_ops(struct core_ops *ops) ops->macsec_config_mac = eqos_config_for_macsec; #endif /* !OSI_STRIPPED_LIB */ #endif /* MACSEC_SUPPORT */ + ops->config_l3l4_filters = eqos_config_l3l4_filters; #ifndef OSI_STRIPPED_LIB - 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->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; diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 499fadf..92bd66f 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -64,19 +64,10 @@ (EQOS_5_30_SID_CH5) |\ (EQOS_5_30_SID)) #define EQOS_MAC_MA0HR_MASK 0xFFFFFU -#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_L4SPI_SHIFT 19 -#define EQOS_MAC_L3L4_CTR_L4PEN0 OSI_BIT(16) -#define EQOS_MAC_L3L4_CTR_L4PEN0_SHIFT 16 #define EQOS_MAC_IMR_MASK 0x67039U #define EQOS_MAC_HTR_MASK 0xFFFFFFFFU #define EQOS_MAC_HTR0_IDX 2U #define EQOS_MAC_HTR_REG(x) ((0x0004U * (x)) + 0x0010U) -#define EQOS_MAC_L3_AD2R(x) ((0x0030U * (x)) + 0x0918U) -#define EQOS_MAC_L3_AD3R(x) ((0x0030U * (x)) + 0x091CU) -#define EQOS_MAC_L4_ADR(x) ((0x0030U * (x)) + 0x0904U) #define EQOS_DMA_SBUS_MASK 0xDF1F3CFFU #define EQOS_DMA_CHX_STATUS_FBE OSI_BIT(10) #define EQOS_DMA_CHX_STATUS_TBU OSI_BIT(2) @@ -84,7 +75,6 @@ #define EQOS_DMA_CHX_STATUS_RPS OSI_BIT(8) #define EQOS_DMA_CHX_STATUS_RWT OSI_BIT(9) #define EQOS_DMA_CHX_STATUS_TPS OSI_BIT(1) -#define EQOS_MAC_L3L4_CTR_L4DPI_SHIFT 21 #define EQOS_MAC_RQC0R_MASK 0xFFU #define EQOS_MAC_QX_TX_FLW_CTRL_TFE OSI_BIT(1) #define EQOS_MAC_QX_TXFC_MASK 0xFFFF00F2U @@ -285,8 +275,13 @@ #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_L3_AD0R(x) ((0x0030U * (x)) + 0x0910U) #define EQOS_MAC_L3_AD1R(x) ((0x0030U * (x)) + 0x0914U) +#ifndef OSI_STRIPPED_LIB +#define EQOS_MAC_L3_AD0R(x) ((0x0030U * (x)) + 0x0910U) +#define EQOS_MAC_L3_AD2R(x) ((0x0030U * (x)) + 0x0918U) +#define EQOS_MAC_L3_AD3R(x) ((0x0030U * (x)) + 0x091CU) +#define EQOS_MAC_L4_ADR(x) ((0x0030U * (x)) + 0x0904U) +#endif /* !OSI_STRIPPED_LIB */ #define EQOS_MAC_TCR 0x0B00 #define EQOS_MAC_SSIR 0x0B04 #define EQOS_MAC_STSUR 0x0B10 @@ -449,49 +444,11 @@ #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_L3L4_CTR_L4SPM0 OSI_BIT(18) -#define EQOS_MAC_L3L4_CTR_L4SPIM0 OSI_BIT(19) -#define EQOS_MAC_L3L4_CTR_L4DPM0 OSI_BIT(20) -#define EQOS_MAC_L3L4_CTR_L4DPIM0 OSI_BIT(21) -#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) +#ifndef OSI_STRIPPED_LIB +#define EQOS_MAC_L4_SP_MASK 0x0000FFFFU +#define EQOS_MAC_L4_DP_MASK 0xFFFF0000U +#define EQOS_MAC_L4_DP_SHIFT 16 +#endif /* !OSI_STRIPPED_LIB */ #define EQOS_MAC_ADDRH_DCS (OSI_BIT(23) | OSI_BIT(22) | \ OSI_BIT(21) | OSI_BIT(20) | \ OSI_BIT(19) | OSI_BIT(18) | \ diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 8452b26..2a550c3 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -484,672 +484,105 @@ static nve32_t mgbe_l3l4_filter_write(struct osi_core_priv_data *osi_core, } /** - * @brief mgbe_l3l4_filter_read - L3_L4 filter register read. + * @brief mgbe_config_l3l4_filters - Config L3L4 filters. * - * 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 nve32_t mgbe_l3l4_filter_read(struct osi_core_priv_data *osi_core, - nveu32_t filter_no, - nveu32_t filter_type, - nveu32_t *value) -{ - void *base = osi_core->base; - nveu32_t addr = 0; - - /* Program MAC_L3_L4_Address_Control */ - addr = osi_readla(osi_core, - (nveu8_t *)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, - (nveu8_t *)base + MGBE_MAC_L3L4_ADDR_CTR); - - /* Wait untile XB bit reset */ - if (mgbe_poll_for_l3l4crtl(osi_core) < 0) { - OSI_CORE_ERR(osi_core->osd, 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, - (nveu8_t *)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 + * @note + * Algorithm: + * - This sequence is used to configure L3L4 filters for SA and DA Port Number matching. + * - Prepare register data using prepare_l3l4_registers(). + * - Write l3l4 reigsters using mgbe_l3l4_filter_write(). + * - Return 0 on success. + * - Return -1 on any register failure. * * @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 nve32_t mgbe_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) -{ - nveu32_t value = 0U; - nveu32_t temp = 0U; - nve32_t 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", - (nveul64_t)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 = (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) { - 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; -} - -#ifndef OSI_STRIPPED_LIB -/** - * @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 nve32_t mgbe_update_ip6_addr(struct osi_core_priv_data *const osi_core, - const nveu32_t filter_no, - const nveu16_t addr[]) -{ - nveu32_t value = 0U; - nveu32_t temp = 0U; - nve32_t 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", - (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; - - 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 = (nveu32_t)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 = (nveu32_t)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 = (nveu32_t)addr[0] << 16; - value |= temp; - - return mgbe_l3l4_filter_write(osi_core, filter_no, - MGBE_MAC_L3_AD3R, value); -} - -/** - * @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 + * @param[in] filter_no_r: filter index + * @param[in] l3_l4: Pointer to l3 l4 filter structure (#osi_l3_l4_filter) * * @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 nve32_t mgbe_update_l4_port_no(struct osi_core_priv_data *osi_core, - const nveu32_t filter_no, - const nveu16_t port_no, - const nveu32_t src_dst_port_match) +static nve32_t mgbe_config_l3l4_filters(struct osi_core_priv_data *const osi_core, + nveu32_t filter_no_r, + const struct osi_l3_l4_filter *const l3_l4) { - nveu32_t value = 0U; - nveu32_t temp = 0U; - nve32_t ret = 0; +#ifndef OSI_STRIPPED_LIB + nveu32_t l3_addr0_reg = 0; + nveu32_t l3_addr2_reg = 0; + nveu32_t l3_addr3_reg = 0; + nveu32_t l4_addr_reg = 0; +#endif /* !OSI_STRIPPED_LIB */ + nveu32_t l3_addr1_reg = 0; + nveu32_t ctr_reg = 0; + nveu32_t filter_no = filter_no_r & (OSI_MGBE_MAX_L3_L4_FILTER - 1U); + nve32_t err; + nve32_t ret = -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", - (nveul64_t)filter_no); - return -1; + prepare_l3l4_registers(osi_core, l3_l4, +#ifndef OSI_STRIPPED_LIB + &l3_addr0_reg, + &l3_addr2_reg, + &l3_addr3_reg, + &l4_addr_reg, +#endif /* !OSI_STRIPPED_LIB */ + &l3_addr1_reg, + &ctr_reg); + +#ifndef OSI_STRIPPED_LIB + /* Update l3 ip addr MGBE_MAC_L3_AD0R register */ + err = mgbe_l3l4_filter_write(osi_core, filter_no, MGBE_MAC_L3_AD0R, l3_addr0_reg); + if (err < 0) { + /* Write MGBE_MAC_L3_AD0R fail return error */ + goto exit_func; } - 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; + /* Update l3 ip addr MGBE_MAC_L3_AD2R register */ + err = mgbe_l3l4_filter_write(osi_core, filter_no, MGBE_MAC_L3_AD2R, l3_addr2_reg); + if (err < 0) { + /* Write MGBE_MAC_L3_AD2R fail return error */ + goto exit_func; } - if (src_dst_port_match == OSI_SOURCE_MATCH) { - value &= ~MGBE_MAC_L4_ADDR_SP_MASK; - value |= ((nveu32_t)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); + /* Update l3 ip addr MGBE_MAC_L3_AD3R register */ + err = mgbe_l3l4_filter_write(osi_core, filter_no, MGBE_MAC_L3_AD3R, l3_addr3_reg); + if (err < 0) { + /* Write MGBE_MAC_L3_AD3R fail return error */ + goto exit_func; } - return mgbe_l3l4_filter_write(osi_core, filter_no, - MGBE_MAC_L4_ADDR, value); -} + /* Update l4 port register MGBE_MAC_L4_ADDR register */ + err = mgbe_l3l4_filter_write(osi_core, filter_no, MGBE_MAC_L4_ADDR, l4_addr_reg); + if (err < 0) { + /* Write MGBE_MAC_L4_ADDR fail return error */ + goto exit_func; + } #endif /* !OSI_STRIPPED_LIB */ -/** - * @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: 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 - * - * @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 nveu32_t value param - */ -static inline nveu32_t mgbe_set_dcs(struct osi_core_priv_data *osi_core, - nveu32_t value, - nveu32_t dma_routing_enable, - nveu32_t dma_chan) -{ - nveu32_t temp = value; - - if ((dma_routing_enable == OSI_ENABLE) && (dma_chan < - OSI_MGBE_MAX_NUM_CHANS) && (osi_core->dcs_en == - OSI_ENABLE)) { - temp |= ((dma_routing_enable << - MGBE_MAC_L3L4_CTR_DMCHEN0_SHIFT) & - MGBE_MAC_L3L4_CTR_DMCHEN0); - temp |= ((dma_chan << - MGBE_MAC_L3L4_CTR_DMCHN0_SHIFT) & - MGBE_MAC_L3L4_CTR_DMCHN0); + /* Update l3 ip addr MGBE_MAC_L3_AD1R register */ + err = mgbe_l3l4_filter_write(osi_core, filter_no, MGBE_MAC_L3_AD1R, l3_addr1_reg); + if (err < 0) { + /* Write MGBE_MAC_L3_AD1R fail return error */ + goto exit_func; } - return temp; -} - -/** - * @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(nveu32_t *bitmask, - nveu32_t filter_no, - nveu32_t value) -{ - nveu32_t 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 nve32_t mgbe_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; - nve32_t 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", - (nveul64_t)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", - (nveul64_t)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 CTR register */ + err = mgbe_l3l4_filter_write(osi_core, filter_no, MGBE_MAC_L3L4_CTR, ctr_reg); + if (err < 0) { /* Write MGBE_MAC_L3L4_CTR fail return error */ - return ret; + goto exit_func; } - /* Set bit corresponding to filter index if value is non-zero */ - mgbe_helper_l3l4_bitmask(&osi_core->l3l4_filter_bitmask, - filter_no, value); + /* success */ + ret = 0; + +exit_func: return ret; } #ifndef OSI_STRIPPED_LIB -/** - * @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 nve32_t mgbe_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) -{ - nveu32_t value = 0U; - nve32_t 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", - (nveul64_t)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", - (nveu32_t)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 * @@ -4560,13 +3993,11 @@ void mgbe_init_core_ops(struct core_ops *ops) ops->handle_common_intr = mgbe_handle_common_intr; ops->pad_calibrate = mgbe_pad_calibrate; ops->update_mac_addr_low_high_reg = mgbe_update_mac_addr_low_high_reg; - ops->config_l3_filters = mgbe_config_l3_filters; ops->adjust_mactime = mgbe_adjust_mactime; ops->read_mmc = mgbe_read_mmc; ops->write_phy_reg = mgbe_write_phy_reg; ops->read_phy_reg = mgbe_read_phy_reg; ops->get_hw_features = mgbe_get_hw_features; - ops->update_ip4_addr = mgbe_update_ip4_addr; ops->read_reg = mgbe_read_reg; ops->write_reg = mgbe_write_reg; ops->set_avb_algorithm = mgbe_set_avb_algorithm; @@ -4581,10 +4012,8 @@ void mgbe_init_core_ops(struct core_ops *ops) ops->macsec_config_mac = mgbe_config_for_macsec; #endif /* !OSI_STRIPPED_LIB */ #endif /* MACSEC_SUPPORT */ + ops->config_l3l4_filters = mgbe_config_l3l4_filters; #ifndef OSI_STRIPPED_LIB - 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_tx_status = mgbe_config_tx_status; ops->config_rx_crc_check = mgbe_config_rx_crc_check; ops->config_flow_control = mgbe_config_flow_control; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 7514722..42f42eb 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -78,11 +78,6 @@ /** @} */ #define MGBE_MAX_VLAN_FILTER 32U -#define MGBE_MAC_L3L4_CTR_L4DPIM0_SHIFT 21 -#define MGBE_MAC_L3L4_CTR_L4PEN0 OSI_BIT(16) -#define MGBE_MAC_L3L4_CTR_L4SPIM0_SHIFT 19 -#define MGBE_MAC_L3_AD2R 0x6 -#define MGBE_MAC_L3_AD3R 0x7 #define MGBE_MAC_RX_FLW_CTRL_RFE OSI_BIT(0) #define MGBE_MAC_STNSR_TSSS_MASK 0x7FFFFFFFU #define MGBE_MAC_TCR_SNAPTYPSEL_SHIFT 16U @@ -151,10 +146,6 @@ #define MGBE_DMA_CHX_STATUS_RBU OSI_BIT(7) #define MGBE_DMA_CHX_STATUS_FBE OSI_BIT(12) -#define MGBE_MAC_L4_ADDR 0x1 -#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_LPI_CSR_LPITE OSI_BIT(20) #define MGBE_MAC_LPI_CSR_LPITXA OSI_BIT(19) #define MGBE_MAC_LPI_CSR_PLS OSI_BIT(17) @@ -433,52 +424,16 @@ */ #define MGBE_MAC_XB_WAIT 10U #define MGBE_MAC_L3L4_CTR 0x0 -#define MGBE_MAC_L3_AD0R 0x4 #define MGBE_MAC_L3_AD1R 0x5 - -#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_L4DPM0 OSI_BIT(20) -#define MGBE_MAC_L3L4_CTR_L4SPIM0 OSI_BIT(19) -#define MGBE_MAC_L3L4_CTR_L4SPM0 OSI_BIT(18) -#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) +#ifndef OSI_STRIPPED_LIB +#define MGBE_MAC_L3_AD0R 0x4 +#define MGBE_MAC_L3_AD2R 0x6 +#define MGBE_MAC_L3_AD3R 0x7 +#define MGBE_MAC_L4_ADDR 0x1 +#define MGBE_MAC_L4_ADDR_SP_MASK 0x0000FFFFU +#define MGBE_MAC_L4_ADDR_DP_MASK 0xFFFF0000U +#define MGBE_MAC_L4_ADDR_DP_SHIFT 16 +#endif /* !OSI_STRIPPED_LIB */ /** @} */ /** diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 9d0f383..c298739 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -729,158 +729,356 @@ static nve32_t osi_l2_filter(struct osi_core_priv_data *const osi_core, return ret; } -#ifndef OSI_STRIPPED_LIB /** - * @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. + * @brief l3l4_find_match - function to find filter match * * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No + * Algorithm: + * - Search through filter list l_core->cfg.l3_l4[] and find for a + * match with l3_l4 input data. + * - Filter data matches, store the filter index into filter_no. + * - Store first found filter index into free_filter_no. + * - Return 0 on match. + * - Return -1 on failure. * - * @retval 0 on Success - * @retval -1 on Failure + * @param[in] l_core: OSI local core data structure. + * @param[in] l3_l4: Pointer to l3 l4 filter structure (#osi_l3_l4_filter) + * @param[out] filter_no: pointer to filter index + * @param[out] free_filter_no: pointer to free filter index + * @param[in] max_filter_no: maximum allowed filter number + * + * @pre + * - MAC should be initialized and started. see osi_start_mac() + * + * @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) +static nve32_t l3l4_find_match(const struct core_local *const l_core, + const struct osi_l3_l4_filter *const l3_l4, + nveu32_t *filter_no, + nveu32_t *free_filter_no, + nveu32_t max_filter_no) { - nve32_t ret = 0; + nveu32_t i; + nve32_t ret = -1; + nveu32_t found_free_index = 0; + nve32_t filter_size = (nve32_t)sizeof(l3_l4->data); - 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_core->osd, OSI_LOG_ARG_HW_FAIL, - "failed to configure L4 filters\n", 0ULL); - return ret; - } + /* init free index value to invalid value */ + *free_filter_no = UINT_MAX; - return ops_p->update_l4_port_no(osi_core, - l_filter->filter_no, - l_filter->port_no, - l_filter->src_dst_addr_match); -} -#endif /* !OSI_STRIPPED_LIB */ + for (i = 0; i < max_filter_no; i++) { + if (l_core->cfg.l3_l4[i].filter_enb_dis == OSI_FALSE) { + /* filter not enabled, save free index */ + if (found_free_index == 0U) { + *free_filter_no = i; + found_free_index = 1; + } + continue; + } -/** - * @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; + if (osi_memcmp(&(l_core->cfg.l3_l4[i].data), &(l3_l4->data), + filter_size) != 0) { + /* data do not match */ + continue; + } - 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_core->osd, OSI_LOG_ARG_HW_FAIL, - "failed to configure L3 filters\n", 0ULL); - return ret; - } - - if (type == OSI_IP6_FILTER) { -#ifndef OSI_STRIPPED_LIB - ret = ops_p->update_ip6_addr(osi_core, l_filter->filter_no, - l_filter->ip6_addr); -#endif /* !OSI_STRIPPED_LIB */ - } 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_core->osd, OSI_LOG_ARG_INVALID, - "Invalid L3 filter type\n", 0ULL); - return -1; + /* found a match */ + ret = 0; + *filter_no = i; + break; } return ret; } -static nve32_t osi_l3l4_filter(struct osi_core_priv_data *const osi_core, - struct osi_l3_l4_filter *const l_filter, - const nveu32_t type, const nveu32_t dma_routing_enable, - const nveu32_t dma_chan, const nveu32_t is_l4_filter) +/** + * @brief configure_l3l4_filter_helper - helper function for l3l4 configuration + * + * @note + * Algorithm: + * - Validate all the l3_l4 structure parameter. + * Return -1 if parameter validation fails. + * - Confifure l3l4 filter using l_core->ops_p->config_l3l4_filters(). + * Return -1 if config_l3l4_filters() fails. + * - Store the filter into l_core->cfg.l3_l4[] and enable + * l3l4 filter if any of the filter index enabled currently. + * + * @param[inout] l_core: OSI local core data structure. + * @param[in] filter_no: pointer to filter number + * @param[in] l3_l4: Pointer to l3 l4 filter structure (#osi_l3_l4_filter) + * + * @pre + * - MAC should be initialized and started. see osi_start_mac() + * + * @retval 0 on success + * @retval -1 on failure. + */ +static nve32_t configure_l3l4_filter_helper(struct osi_core_priv_data *const osi_core, + nveu32_t filter_no, + const struct osi_l3_l4_filter *const l3_l4) { - struct core_local *l_core = (struct core_local *)(void *)osi_core; + struct osi_l3_l4_filter *cfg_l3_l4; + struct core_local *const l_core = (struct core_local *)(void *)osi_core; + const nveu32_t max_filter_no[2] = { + EQOS_MAX_L3_L4_FILTER, + OSI_MGBE_MAX_L3_L4_FILTER + }; + const nveu32_t max_dma_chan[2] = { + OSI_EQOS_MAX_NUM_CHANS, + OSI_MGBE_MAX_NUM_CHANS + }; nve32_t ret = -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; + /* validate filter index */ + if (filter_no >= max_filter_no[osi_core->mac]) { + OSI_CORE_ERR((osi_core->osd), (OSI_LOG_ARG_OUTOFBOUND), + ("invalid filter index for L3/L4 filter\n"), (filter_no)); + goto exit_func; } - if (is_l4_filter == OSI_ENABLE) { + /* validate dma channel */ + if (l3_l4->dma_chan > max_dma_chan[osi_core->mac]) { + OSI_CORE_ERR((osi_core->osd), (OSI_LOG_ARG_OUTOFBOUND), + ("L3L4: Wrong DMA channel: "), (l3_l4->dma_chan)); + goto exit_func; + } + + /* valate enb parameters */ + if (( #ifndef OSI_STRIPPED_LIB - ret = helper_l4_filter(osi_core, l_core->ops_p, l_filter, type, - dma_routing_enable, dma_chan); + l3_l4->dma_routing_enable | + l3_l4->data.is_udp | + l3_l4->data.is_ipv6 | + l3_l4->data.perfect_inverse_match | + l3_l4->data.src.port_match | + l3_l4->data.src.addr_match | + l3_l4->data.dst.port_match | + l3_l4->data.dst.addr_match | #endif /* !OSI_STRIPPED_LIB */ - } else { - ret = helper_l3_filter(osi_core, l_core->ops_p, l_filter, type, - dma_routing_enable, dma_chan); + l3_l4->filter_enb_dis + ) > OSI_TRUE) { + OSI_CORE_ERR((osi_core->osd), (OSI_LOG_ARG_OUTOFBOUND), + ("L3L4: one of the enb param > OSI_TRUE: "), (filter_no)); + goto exit_func; } +#ifndef OSI_STRIPPED_LIB + /* validate port/addr enb bits */ + if (l3_l4->filter_enb_dis == OSI_TRUE) { + if ((l3_l4->data.src.port_match | l3_l4->data.src.addr_match | + l3_l4->data.dst.port_match | l3_l4->data.dst.addr_match) + == OSI_FALSE) { + OSI_CORE_ERR((osi_core->osd), (OSI_LOG_ARG_OUTOFBOUND), + ("L3L4: None of the enb bits are not set: "), + (filter_no)); + goto exit_func; + } + if ((l3_l4->data.is_ipv6 & l3_l4->data.src.addr_match & + l3_l4->data.dst.addr_match) != OSI_FALSE) { + OSI_CORE_ERR((osi_core->osd), (OSI_LOG_ARG_OUTOFBOUND), + ("L3L4: Both ip6 addr match bits are set\n"), + (filter_no)); + goto exit_func; + } + } +#endif /* !OSI_STRIPPED_LIB */ + + ret = l_core->ops_p->config_l3l4_filters(osi_core, filter_no, l3_l4); if (ret < 0) { - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "L3/L4 helper function failed\n", 0ULL); - return ret; + OSI_CORE_ERR((osi_core->osd), (OSI_LOG_ARG_HW_FAIL), + ("Failed to config L3L4 filters: "), (filter_no)); + goto exit_func; } - if (osi_core->l3l4_filter_bitmask != OSI_DISABLE) { + cfg_l3_l4 = &(l_core->cfg.l3_l4[filter_no]); + if (l3_l4->filter_enb_dis == OSI_TRUE) { + /* Store the filter. + * osi_memcpy is an internal function and it cannot fail, hence + * ignoring return value. + */ + (void)osi_memcpy(cfg_l3_l4, l3_l4, sizeof(struct osi_l3_l4_filter)); + OSI_CORE_INFO((osi_core->osd), (OSI_LOG_ARG_OUTOFBOUND), + ("L3L4: ADD: "), (filter_no)); + + /* update filter mask bit */ + osi_core->l3l4_filter_bitmask |= (((nveu32_t)1U << filter_no) & 0x1FU); + } else { + /* Clear the filter data. + * osi_memset is an internal function and it cannot fail, hence + * ignoring return value. + */ + (void)osi_memset(cfg_l3_l4, 0, sizeof(struct osi_l3_l4_filter)); + OSI_CORE_INFO((osi_core->osd), (OSI_LOG_ARG_OUTOFBOUND), + ("L3L4: DELETE: "), (filter_no)); + + /* update filter mask bit */ + osi_core->l3l4_filter_bitmask &= ~(((nveu32_t)1U << filter_no) & 0x1FU); + } + + if (osi_core->l3l4_filter_bitmask != 0U) { + /* enable l3l4 filter */ ret = hw_config_l3_l4_filter_enable(osi_core, OSI_ENABLE); } else { + /* disable l3l4 filter */ ret = hw_config_l3_l4_filter_enable(osi_core, OSI_DISABLE); } +exit_func: + + return ret; +} + +#ifndef OSI_STRIPPED_LIB +#ifdef L3L4_WILDCARD_FILTER +/** + * @brief l3l4_add_wildcard_filter - function to configure wildcard filter. + * + * @note + * Algorithm: + * - Configure wildcard filter with all 4 tuple as 0s using configure_l3l4_filter_helper(). + * + * @param[in] osi_core: OSI Core private data structure. + * @param[in] max_filter_no: maximum allowed filter number + * + * @pre + * - MAC should be initialized and started. see osi_start_mac() + */ +static void l3l4_add_wildcard_filter(struct osi_core_priv_data *const osi_core, + nveu32_t max_filter_no) +{ + nve32_t err; + struct osi_l3_l4_filter *l3l4_filter; + struct core_local *l_core = (struct core_local *)(void *)osi_core; + + /* use max filter index to confiture wildcard filter */ + if (l_core->l3l4_wildcard_filter_configured != OSI_ENABLE) { + /* configure INV filter for IPV4/UDP with DA(0) + SP (0) + + * DP (0) with routing not enabled + */ + l3l4_filter = &(l_core->cfg.l3_l4[max_filter_no]); + osi_memset(l3l4_filter, 0, sizeof(struct osi_l3_l4_filter)); + l3l4_filter->filter_enb_dis = OSI_TRUE; + l3l4_filter->data.is_udp = OSI_TRUE; + l3l4_filter->data.perfect_inverse_match = OSI_TRUE; + l3l4_filter->data.src.port_match = OSI_TRUE; + l3l4_filter->data.dst.port_match = OSI_TRUE; + l3l4_filter->data.src.addr_match = OSI_TRUE; + l3l4_filter->data.dst.addr_match = OSI_TRUE; + + /* configure wildcard at last filter index */ + err = configure_l3l4_filter_helper(osi_core, max_filter_no, l3l4_filter); + if (err < 0) { + /* wildcard config failed */ + OSI_CORE_ERR((osi_core->osd), (OSI_LOG_ARG_INVALID), + ("L3L4: Wildcard config failed: "), (max_filter_no)); + } else { + /* wildcard config success */ + l_core->l3l4_wildcard_filter_configured = OSI_ENABLE; + OSI_CORE_INFO((osi_core->osd), (OSI_LOG_ARG_INVALID), + ("L3L4: Wildcard config success"), (max_filter_no)); + } + } +} +#endif /* L3L4_WILDCARD_FILTER */ +#endif /* !OSI_STRIPPED_LIB */ + +/** + * @brief configure_l3l4_filter - function to configure l3l4 filter. + * + * @note + * Algorithm: + * - For filter enable case, + * -> If filter already enabled, return -1 to report error. + * -> Otherwise find free index and configure filter using configure_l3l4_filter_helper(). + * - For filter disable case, + * -> If filter match not found, return 0 to report caller that filter already removed. + * -> Otherwise disable filter using configure_l3l4_filter_helper(). + * - Return -1 if configure_l3l4_filter_helper() fails. + * - Return 0 on success. + * + * @param[in] osi_core: OSI Core private data structure. + * @param[in] l3_l4: Pointer to l3 l4 filter structure (#osi_l3_l4_filter) + * + * @pre + * - MAC should be initialized and started. see osi_start_mac() + * + * @retval 0 on success + * @retval -1 on failure. + */ +static nve32_t configure_l3l4_filter(struct osi_core_priv_data *const osi_core, + const struct osi_l3_l4_filter *const l3_l4) +{ + nve32_t err; + nveu32_t filter_no = 0; + nveu32_t free_filter_no = UINT_MAX; + const struct core_local *l_core = (struct core_local *)(void *)osi_core; + const nveu32_t max_filter_no[2] = { + /* max usable filter number is less by 1 for accommodating + * wildcard filter at last index. + */ + EQOS_MAX_L3_L4_FILTER - 1U, + OSI_MGBE_MAX_L3_L4_FILTER - 1U, + }; + nve32_t ret = -1; + + /* search for a duplicate filter request or find for free index */ + err = l3l4_find_match(l_core, l3_l4, &filter_no, &free_filter_no, + max_filter_no[osi_core->mac]); + + if (l3_l4->filter_enb_dis == OSI_TRUE) { + if (err == 0) { + /* duplicate filter request */ + OSI_CORE_ERR((osi_core->osd), (OSI_LOG_ARG_HW_FAIL), + ("L3L4: Failed: duplicate filter: "), (filter_no)); + goto exit_func; + } + + /* check free index */ + if (free_filter_no >= max_filter_no[osi_core->mac]) { + /* no free entry found */ + OSI_CORE_INFO((osi_core->osd), (OSI_LOG_ARG_HW_FAIL), + ("L3L4: Failed: no free filter: "), (free_filter_no)); + goto exit_func; + } + filter_no = free_filter_no; + } else { + if (err < 0) { + /* no match found */ + OSI_CORE_INFO((osi_core->osd), (OSI_LOG_ARG_HW_FAIL), + ("L3L4: delete: no filter match: "), (filter_no)); + /* filter already deleted, return success */ + ret = 0; + goto exit_func; + } + } + +#ifndef OSI_STRIPPED_LIB +#ifdef L3L4_WILDCARD_FILTER + /* setup l3l4 wildcard filter for l3l4 */ + l3l4_add_wildcard_filter(osi_core, max_filter_no[osi_core->mac]); + if (l_core->l3l4_wildcard_filter_configured != OSI_ENABLE) { + OSI_CORE_ERR((osi_core->osd), (OSI_LOG_ARG_HW_FAIL), + ("L3L4: Rejected: wildcard is not enabled: "), (filter_no)); + goto exit_func; + } +#endif /* L3L4_WILDCARD_FILTER */ +#endif /* !OSI_STRIPPED_LIB */ + + /* configure l3l4 filter */ + err = configure_l3l4_filter_helper(osi_core, filter_no, l3_l4); + if (err < 0) { + /* filter config failed */ + OSI_CORE_ERR((osi_core->osd), (OSI_LOG_ARG_HW_FAIL), + ("L3L4: configure_l3l4_filter_helper() failed"), (filter_no)); + goto exit_func; + } + + /* success */ + ret = 0; + +exit_func: + return ret; } @@ -1723,16 +1921,23 @@ static void cfg_l3_l4_filter(struct core_local *l_core) nveu32_t i = 0U; for (i = 0U; i < OSI_MGBE_MAX_L3_L4_FILTER; i++) { - if (l_core->cfg.l3_l4[i].used == OSI_DISABLE) { + if (l_core->cfg.l3_l4[i].filter_enb_dis == OSI_FALSE) { + /* filter not enabled */ continue; } - (void)osi_l3l4_filter((struct osi_core_priv_data *)(void *)l_core, - &l_core->cfg.l3_l4[i].l3l4_filter, - l_core->cfg.l3_l4[i].type, - l_core->cfg.l3_l4[i].dma_routing_enable, - l_core->cfg.l3_l4[i].dma_chan, - l_core->cfg.l3_l4[i].is_l4_filter); + (void)configure_l3l4_filter_helper( + (struct osi_core_priv_data *)(void *)l_core, + i, &l_core->cfg.l3_l4[i]); + +#ifdef L3L4_WILDCARD_FILTER +#ifndef OSI_STRIPPED_LIB + if (i == (OSI_MGBE_MAX_L3_L4_FILTER - 1U)) { + /* last filter supposed to be wildcard filter */ + l_core->l3l4_wildcard_filter_configured = OSI_ENABLE; + } +#endif /* L3L4_WILDCARD_FILTER */ +#endif /* !OSI_STRIPPED_LIB */ } } @@ -1856,27 +2061,6 @@ static void apply_dynamic_cfg(struct osi_core_priv_data *osi_core) } } -static void store_l3l4_filter(struct osi_core_priv_data *osi_core, - struct osi_l3_l4_filter *l3l4_filter, - nveu32_t type, nveu32_t dma_routing_enable, - nveu32_t dma_chan, nveu32_t is_l4_filter) -{ - struct core_local *l_core = (struct core_local *)(void *)osi_core; - struct l3_l4_filters *l3_l4 = &l_core->cfg.l3_l4[l3l4_filter->filter_no]; - - if (l3l4_filter->filter_enb_dis == OSI_ENABLE) { - l3_l4->type = type; - l3_l4->dma_routing_enable = dma_routing_enable; - l3_l4->dma_chan = dma_chan; - l3_l4->is_l4_filter = is_l4_filter; - (void)osi_memcpy(&l3_l4->l3l4_filter, l3l4_filter, - sizeof(struct osi_l3_l4_filter)); - l3_l4->used = OSI_ENABLE; - } else { - l3_l4->used = OSI_DISABLE; - } -} - static void store_l2_filter(struct osi_core_priv_data *osi_core, struct osi_filter *filter) { @@ -2081,16 +2265,10 @@ static nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, switch (data->cmd) { 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); + ret = configure_l3l4_filter(osi_core, &data->l3l4_filter); if (ret == 0) { - store_l3l4_filter(osi_core, &data->l3l4_filter, - data->arg1_u32, data->arg2_u32, - data->arg3_u32, data->arg4_u32); l_core->cfg.flags |= DYNAMIC_CFG_L3_L4; } - break; #ifndef OSI_STRIPPED_LIB From d26a80340176ad365e8e737b97793553f5a44e2b Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Tue, 29 Nov 2022 16:07:53 +0530 Subject: [PATCH 429/458] osi: remove Makefile.sdk remove Makefile.sdk since no longer valid as AUTOSAR support is deprecated Bug 3871403 Change-Id: Ie4d984fd3d6a447a3da7fd0ec62441ac21a45a03 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2818388 Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Sachin Nikam <snikam@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- osi/dma/Makefile.sdk | 38 -------------------------------------- 1 file changed, 38 deletions(-) delete mode 100644 osi/dma/Makefile.sdk diff --git a/osi/dma/Makefile.sdk b/osi/dma/Makefile.sdk deleted file mode 100644 index 6415826..0000000 --- a/osi/dma/Makefile.sdk +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright (c) 2020 NVIDIA CORPORATION. All Rights Reserved. -# -# NVIDIA CORPORATION and its licensors retain all intellectual property -# and proprietary rights in and to this software, related documentation -# and any modifications thereto. Any use, reproduction, disclosure or -# distribution of this software and related documentation without an express -# license agreement from NVIDIA CORPORATION is strictly prohibited. - -include $(PDK_TOP)/drive-t186ref-qnx/make/nvdefs.mk - -TARGETS = libnvethernetcl.so - -CFLAGS += -g -Wall $(NV_PLATFORM_OPT) $(NV_PLATFORM_CFLAGS) -CPPFLAGS = $(NV_PLATFORM_SDK_INC) $(NV_PLATFORM_CPPFLAGS) -I../../../include -I../core -I../common/include -CPPFLAGS += -DNV_IS_SAFETY=$(NV_PLATFORM_SAFETY) -LDFLAGS := \ - $(NV_PLATFORM_SDK_LIB) \ - $(NV_PLATFORM_LDFLAGS) -LDFLAGS += -shared - -OBJS := eqos_dma.o -OBJS += osi_dma.o -OBJS += osi_dma_txrx.o -OBJS += mgbe_dma.o -OBJS += eqos_desc.o -OBJS += mgbe_desc.o -OBJS += ./../common/osi_common.o -OBJS += ./../common/eqos_common.o -OBJS += ./../common/mgbe_common.o - -CFLAGS += -D_FILE_OFFSET_BITS=64 - -$(TARGETS): $(OBJS) - $(LD) $(LDFLAGS) -o $@ $^ $(LDLIBS) - $(STRIP) --strip-unneeded -R .comment -R .GCC.command.line $@ - -clean clobber: - rm -rf $(OBJS) $(TARGETS) From c220b78d89b2c0d38f0e34e5ef6c02a446370634 Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Fri, 25 Nov 2022 05:48:59 +0530 Subject: [PATCH 430/458] osi: core: remove condition to compiled code for QNX If there is no request from PTP application to read Tx timestamp to OSD driver, OSD driver don't read time to local OSI structure and it may lead to wrong TX time on request from OSD. Any PTP time stamp after 2 sync time is not useful. As POR 2 sync time can be max equal to 1sec. Remove old timestamp from driver structure if it older than 1 sec. Bug 3810821 Bug 3759976 Change-Id: I3173104b60bb50de05285ba1993291c489c34079 Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2814646 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/core_local.h | 7 ---- osi/core/osi_hal.c | 74 +++++++++++++++---------------------------- 2 files changed, 26 insertions(+), 55 deletions(-) diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 1b3af20..248206c 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -250,14 +250,7 @@ struct core_ops { #define DRIFT_CAL 0 #endif -#if (!defined(ETHERNET_SERVER) && !defined(__QNX__)) || DRIFT_CAL -#define EQOS_SEC_OFFSET 0xB08 -#define EQOS_NSEC_OFFSET 0xB0C -#define MGBE_SEC_OFFSET 0xD08 -#define MGBE_NSEC_OFFSET 0xD0C #define ETHER_NSEC_MASK 0x7FFFFFFFU -#define OSI_1SEC_TO_NSEC 1000000000LL -#endif #if DRIFT_CAL /** diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index c298739..61175fd 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -1660,45 +1660,28 @@ static inline void free_tx_ts(struct osi_core_priv_data *osi_core, } } -#if (!defined(ETHERNET_SERVER) && !defined(__QNX__)) || DRIFT_CAL /** - * @brief read time counters from HW register - * + * @brief Return absolute difference * Algorithm: - * - read HW time counters and take care of roll-over + * - calculate absolute positive difference * - * @param[in] addr: base address - * @param[in] mac: IP type - * @param[out] sec: sec counter - * @param[out] nsec: nsec counter + * @param[in] a - First input argument + * @param[in] b - Second input argument + * + * @retval absolute difference */ -static void read_sec_ns(void *addr, nveu32_t mac, - nveu32_t *sec, - nveu32_t *nsec) +static inline nveul64_t eth_abs(nveul64_t a, nveul64_t b) { - nveu32_t ns1, ns2; - nveu32_t time_reg_offset[][2] = {{EQOS_SEC_OFFSET, EQOS_NSEC_OFFSET}, - {MGBE_SEC_OFFSET, MGBE_NSEC_OFFSET}}; + nveul64_t temp = 0ULL; - 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; + if (a > b) { + temp = (a - b); } else { - *nsec = ns1; + temp = (b - a); } + + return temp; } -#endif /** * @brief Parses internal ts structure array and update time stamp if packet @@ -1722,14 +1705,12 @@ static inline nve32_t get_tx_ts(struct osi_core_priv_data *osi_core, struct osi_core_tx_ts const *head = &l_core->tx_ts_head; nve32_t ret = -1; nveu32_t count = 0U; -#if !defined(ETHERNET_SERVER) && !defined(__QNX__) nveu32_t nsec, sec, temp_nsec; - nvel64_t temp_val = 0LL; - nvel64_t ts_val = 0LL; + nveul64_t temp_val = 0ULL; + nveul64_t ts_val = 0ULL; - read_sec_ns(osi_core->base, osi_core->mac, &sec, &nsec); - ts_val = (nvel64_t)(sec * OSI_1SEC_TO_NSEC) + (nvel64_t)nsec; -#endif + common_get_systime_from_mac(osi_core->base, osi_core->mac, &sec, &nsec); + ts_val = (sec * OSI_NSEC_PER_SEC) + nsec; if (__sync_fetch_and_add(&l_core->ts_lock, 1) == 1U) { /* mask return as initial value is returned always */ @@ -1743,11 +1724,10 @@ static inline nve32_t get_tx_ts(struct osi_core_priv_data *osi_core, } while ((temp != head) && (count < MAX_TX_TS_CNT)) { -#if !defined(ETHERNET_SERVER) && !defined(__QNX__) temp_nsec = temp->nsec & ETHER_NSEC_MASK; - temp_val = (nvel64_t)(temp->sec * OSI_1SEC_TO_NSEC) + (nvel64_t)temp_nsec; + temp_val = (temp->sec * OSI_NSEC_PER_SEC) + temp_nsec; - if (((ts_val - temp_val) > (2LL * OSI_1SEC_TO_NSEC)) && + if ((eth_abs(ts_val, temp_val) > OSI_NSEC_PER_SEC) && (temp->in_use != OSI_NONE)) { /* remove old node from the link */ temp->next->prev = temp->prev; @@ -1756,13 +1736,11 @@ static inline nve32_t get_tx_ts(struct osi_core_priv_data *osi_core, temp->in_use = OSI_DISABLE; OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, "Removing stale TS from queue pkt_id\n", - temp->pkt_id); + (nveul64_t)temp->pkt_id); count++; temp = temp->next; continue; - } else -#endif - if ((temp->pkt_id == ts->pkt_id) && + } else if ((temp->pkt_id == ts->pkt_id) && (temp->in_use != OSI_NONE)) { ts->sec = temp->sec; ts->nsec = temp->nsec; @@ -2442,9 +2420,9 @@ static nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, 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, + common_get_systime_from_mac(sec_osi_core->base, sec_osi_core->mac, &secondary_sec, &secondary_nsec); - read_sec_ns(osi_core->base, + common_get_systime_from_mac(osi_core->base, osi_core->mac, &sec, &nsec); osi_unlock_irq_enabled(&secondary_osi_lcore->serv.m2m_lock); @@ -2499,9 +2477,9 @@ static nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, 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, + common_get_systime_from_mac(sec_osi_core->base, sec_osi_core->mac, &secondary_sec, &secondary_nsec); - read_sec_ns(osi_core->base, + common_get_systime_from_mac(osi_core->base, osi_core->mac, &sec, &nsec); osi_unlock_irq_enabled(&secondary_osi_lcore->serv.m2m_lock); drift_value = dirft_calculation(sec, nsec, @@ -2587,7 +2565,7 @@ static nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, if (l_core->ether_m2m_role == OSI_PTP_M2M_PRIMARY) { osi_lock_irq_enabled(&secondary_osi_lcore->serv.m2m_lock); - read_sec_ns(osi_core->base, + common_get_systime_from_mac(osi_core->base, osi_core->mac, &sec, &nsec); osi_unlock_irq_enabled(&secondary_osi_lcore->serv.m2m_lock); ret = hw_set_systime_to_mac(sec_osi_core, sec, nsec); From 5a50d75a133c5f69522f6606782047572e6cb845 Mon Sep 17 00:00:00 2001 From: Bibhay Ranjan <bibhayr@nvidia.com> Date: Mon, 14 Nov 2022 12:19:13 +0530 Subject: [PATCH 431/458] nvethernetrm: Universal config.tmk for all OS Issue: Currently each OS defines OSI CFLAGS locally which creates issues in structure memory, if mismatched Fix: Move all the shared CFLAGS to OSI controlled config.tmk Bug 3759976 Change-Id: I9d957ebbc2fc8a176ef70d42b5ae6a9ccb7f342f Signed-off-by: Bibhay Ranjan <bibhayr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2808840 Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- include/config.tmk | 31 +++++++++++++++++++++++++++++++ osi/core/Makefile.tmk | 19 ++----------------- osi/dma/Makefile.tmk | 6 +----- 3 files changed, 34 insertions(+), 22 deletions(-) create mode 100644 include/config.tmk diff --git a/include/config.tmk b/include/config.tmk new file mode 100644 index 0000000..363e7df --- /dev/null +++ b/include/config.tmk @@ -0,0 +1,31 @@ +# 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. +# +############################################################################### +ifeq ($(NV_BUILD_CONFIGURATION_IS_SAFETY),1) + NV_COMPONENT_CFLAGS += -DOSI_STRIPPED_LIB +else + NV_COMPONENT_CFLAGS += -DOSI_DEBUG + NV_COMPONENT_CFLAGS += -DDEBUG_MACSEC +endif +NV_COMPONENT_CFLAGS += -DHSI_SUPPORT +NV_COMPONENT_CFLAGS += -DMACSEC_SUPPORT +#NV_COMPONENT_CFLAGS += -DMACSEC_KEY_PROGRAM +ccflags-y += $(NV_COMPONENT_CFLAGS) diff --git a/osi/core/Makefile.tmk b/osi/core/Makefile.tmk index 21b9bce..d6389ff 100644 --- a/osi/core/Makefile.tmk +++ b/osi/core/Makefile.tmk @@ -47,27 +47,12 @@ NV_COMPONENT_SOURCES := \ $(NV_SOURCE)/nvethernetrm/osi/common/mgbe_common.c \ $(NV_SOURCE)/nvethernetrm/osi/core/macsec.c -NV_COMPONENT_CFLAGS += -DHSI_SUPPORT -NV_COMPONENT_CFLAGS += -DMACSEC_SUPPORT -#NV_COMPONENT_CFLAGS += -DMACSEC_KEY_PROGRAM - -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 -NV_COMPONENT_CFLAGS += -DDEBUG_MACSEC -else -NV_COMPONENT_CFLAGS += -DOSI_STRIPPED_LIB -endif - NV_COMPONENT_INCLUDES := \ $(NV_SOURCE)/nvethernetrm/include \ $(NV_SOURCE)/nvethernetrm/osi/common/include +include $(NV_SOURCE)/nvethernetrm/include/config.tmk + include $(NV_BUILD_STATIC_LIBRARY) endif diff --git a/osi/dma/Makefile.tmk b/osi/dma/Makefile.tmk index 7b82994..9fd16ae 100644 --- a/osi/dma/Makefile.tmk +++ b/osi/dma/Makefile.tmk @@ -45,11 +45,7 @@ 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 -else -NV_COMPONENT_CFLAGS += -DOSI_STRIPPED_LIB -endif +include $(NV_SOURCE)/nvethernetrm/include/config.tmk include $(NV_BUILD_SHARED_LIBRARY) endif From 424f7987df78da2b9522a7aaa9b9f9c8fa9d8327 Mon Sep 17 00:00:00 2001 From: Bibhay Ranjan <bibhayr@nvidia.com> Date: Fri, 18 Nov 2022 19:42:54 +0530 Subject: [PATCH 432/458] nvethernet: Fix the incorrect code in CFLAGS Issue: Few places incorrect CFLAGS are used. OSD based flags cannot be used in OSI Fix: Move the code under correct CFLAGS remove the OSD based codes Note: The OSD based logging need to be reimplemnedted by the macsec module. Bug 3759976 Change-Id: I407b945a24028792f146bc08adf67428612978c3 Signed-off-by: Bibhay Ranjan <bibhayr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2811917 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- include/osi_macsec.h | 4 ++-- osi/core/macsec.c | 14 -------------- osi/core/macsec.h | 4 ++-- osi/dma/debug.c | 2 ++ 4 files changed, 6 insertions(+), 18 deletions(-) diff --git a/include/osi_macsec.h b/include/osi_macsec.h index 441cc9e..8bb0f86 100644 --- a/include/osi_macsec.h +++ b/include/osi_macsec.h @@ -116,7 +116,7 @@ #define OSI_SA_LUT_MAX_INDEX OSI_TABLE_INDEX_MAX /** @} */ -#ifndef OSI_STRIPPED_LIB +#ifdef DEBUG_MACSEC /** * @addtogroup Debug buffer table CONFIG register helpers macros * @@ -141,7 +141,7 @@ #define OSI_RX_DBG_ICV_ERROR_EVT OSI_BIT(10) #define OSI_RX_DBG_CAPTURE_EVT OSI_BIT(11) /** @} */ -#endif /* !OSI_STRIPPED_LIB */ +#endif /* DEBUG_MACSEC*/ /** * @addtogroup AES ciphers diff --git a/osi/core/macsec.c b/osi/core/macsec.c index 50e7175..1078752 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -26,21 +26,7 @@ #include "../osi/common/common.h" #include "core_local.h" -#if defined(DEBUG_MACSEC) && defined(QNX_OS) -#define LOG(...) \ - { \ - slogf(0, 6, ##__VA_ARGS__); \ - } - -#elif defined(DEBUG_MACSEC) && defined(LINUX_OS) -#include <linux/printk.h> -#define LOG(...) \ - { \ - pr_debug(__VA_ARGS__); \ - } -#else #define LOG(...) -#endif #ifdef DEBUG_MACSEC /** diff --git a/osi/core/macsec.h b/osi/core/macsec.h index 380413e..95ba892 100644 --- a/osi/core/macsec.h +++ b/osi/core/macsec.h @@ -453,10 +453,10 @@ #define MACSEC_RX_SCI_LUT_PREEMPT_INACTIVE OSI_BIT(9) /** @} */ -#ifndef OSI_STRIPPED_LIB +#ifdef DEBUG_MACSEC /* debug buffer data read/write length */ #define DBG_BUF_LEN 4U -#endif /* !OSI_STRIPPED_LIB */ +#endif /* DEBUG_MACSEC */ #ifdef MACSEC_KEY_PROGRAM #define INTEGER_LEN 4U #endif /* MACSEC_KEY_PROGRAM */ diff --git a/osi/dma/debug.c b/osi/dma/debug.c index 8c29763..fc14ef7 100644 --- a/osi/dma/debug.c +++ b/osi/dma/debug.c @@ -129,7 +129,9 @@ void reg_dump(struct osi_dma_priv_data *osi_dma) max_addr = 0x14EC; break; case OSI_MGBE_MAC_3_10: +#ifndef OSI_STRIPPED_LIB case OSI_MGBE_MAC_4_00: +#endif addr = 0x3100; max_addr = 0x35FC; break; From e2cf4313dc1727949ee7bde0872af03f165ea09a Mon Sep 17 00:00:00 2001 From: Hareesh Kesireddy <hkesireddy@nvidia.com> Date: Fri, 2 Dec 2022 13:19:02 +0530 Subject: [PATCH 433/458] osi: l3l4: split perfect inv bit for each field - HW has separate Inverse Match bits in l3l4 control register for each source address, destination address, source port and destination port. - Hence, added separate Inverse match bits for all the 4 fields in osi l3l4 structure to provide flexibility for l3l4 users. - Fixed validation parameter sequence to validate l3l4 parameters before processing filter data. Bug 3576506 Bug 3825731 Change-Id: Id7f8939acd92ad5799f2ad0d7cef5d4fcb7e00c5 Signed-off-by: Hareesh Kesireddy <hkesireddy@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2820517 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/nvethernetrm_l3l4.h | 10 ++- osi/core/core_common.c | 21 ++--- osi/core/core_common.h | 5 +- osi/core/osi_hal.c | 168 +++++++++++++++++++++--------------- 4 files changed, 117 insertions(+), 87 deletions(-) diff --git a/include/nvethernetrm_l3l4.h b/include/nvethernetrm_l3l4.h index 65e8c7b..dd8619a 100644 --- a/include/nvethernetrm_l3l4.h +++ b/include/nvethernetrm_l3l4.h @@ -42,8 +42,6 @@ struct osi_l3_l4_filter { nveu32_t is_udp; /** ipv6 (OSI_TRUE) or ipv4 (OSI_FALSE) */ nveu32_t is_ipv6; - /** perfect(OSI_FALSE) or inverse(OSI_TRUE) */ - nveu32_t perfect_inverse_match; #endif /* !OSI_STRIPPED_LIB */ /** destination ip address information */ struct { @@ -56,8 +54,12 @@ struct osi_l3_l4_filter { nveu16_t port_no; /** addr match enable (OSI_TRUE) or disable (OSI_FALSE) */ nveu32_t addr_match; + /** perfect(OSI_FALSE) or inverse(OSI_TRUE) match for address */ + nveu32_t addr_match_inv; /** port match enable (OSI_TRUE) or disable (OSI_FALSE) */ nveu32_t port_match; + /** perfect(OSI_FALSE) or inverse(OSI_TRUE) match for port */ + nveu32_t port_match_inv; #endif /* !OSI_STRIPPED_LIB */ } dst; #ifndef OSI_STRIPPED_LIB @@ -71,8 +73,12 @@ struct osi_l3_l4_filter { nveu16_t port_no; /** addr match enable (OSI_TRUE) or disable (OSI_FALSE) */ nveu32_t addr_match; + /** perfect(OSI_FALSE) or inverse(OSI_TRUE) match for address */ + nveu32_t addr_match_inv; /** port match enable (OSI_TRUE) or disable (OSI_FALSE) */ nveu32_t port_match; + /** perfect(OSI_FALSE) or inverse(OSI_TRUE) match for port */ + nveu32_t port_match_inv; } src; #endif /* !OSI_STRIPPED_LIB */ } data; diff --git a/osi/core/core_common.c b/osi/core/core_common.c index c977db5..309efbd 100644 --- a/osi/core/core_common.c +++ b/osi/core/core_common.c @@ -1516,19 +1516,12 @@ static void prepare_l3l4_ctr_reg(const struct osi_core_priv_data *const osi_core nveu32_t *ctr_reg) { #ifndef OSI_STRIPPED_LIB - nveu32_t perfect_inverse_match = l3_l4->data.perfect_inverse_match; nveu32_t dma_routing_enable = l3_l4->dma_routing_enable; nveu32_t dst_addr_match = l3_l4->data.dst.addr_match; #else - nveu32_t perfect_inverse_match = OSI_FALSE; nveu32_t dma_routing_enable = OSI_TRUE; nveu32_t dst_addr_match = OSI_TRUE; #endif /* !OSI_STRIPPED_LIB */ - const nveu32_t dma_chan_shift[2] = { - EQOS_MAC_L3L4_CTR_DMCHN_SHIFT, - MGBE_MAC_L3L4_CTR_DMCHN_SHIFT - }; - const nveu32_t dma_chan_en_shift[2] = { EQOS_MAC_L3L4_CTR_DMCHEN_SHIFT, MGBE_MAC_L3L4_CTR_DMCHEN_SHIFT @@ -1537,24 +1530,26 @@ static void prepare_l3l4_ctr_reg(const struct osi_core_priv_data *const osi_core /* set routing dma channel */ value |= dma_routing_enable << (dma_chan_en_shift[osi_core->mac] & 0x1FU); - value |= l3_l4->dma_chan << (dma_chan_shift[osi_core->mac] & 0x1FU); + value |= l3_l4->dma_chan << MAC_L3L4_CTR_DMCHN_SHIFT; /* Enable L3 filters for IPv4 DESTINATION addr matching */ - value |= (dst_addr_match << MAC_L3L4_CTR_L3DAM_SHIFT) | - (perfect_inverse_match << MAC_L3L4_CTR_L3DAIM_SHIFT); + value |= dst_addr_match << MAC_L3L4_CTR_L3DAM_SHIFT; #ifndef OSI_STRIPPED_LIB + /* Enable L3 filters for IPv4 DESTINATION addr INV matching */ + value |= l3_l4->data.dst.addr_match_inv << MAC_L3L4_CTR_L3DAIM_SHIFT; + /* Enable L3 filters for IPv4 SOURCE addr matching */ value |= (l3_l4->data.src.addr_match << MAC_L3L4_CTR_L3SAM_SHIFT) | - (perfect_inverse_match << MAC_L3L4_CTR_L3SAIM_SHIFT); + (l3_l4->data.src.addr_match_inv << MAC_L3L4_CTR_L3SAIM_SHIFT); /* Enable L4 filters for DESTINATION port No matching */ value |= (l3_l4->data.dst.port_match << MAC_L3L4_CTR_L4DPM_SHIFT) | - (perfect_inverse_match << MAC_L3L4_CTR_L4DPIM_SHIFT); + (l3_l4->data.dst.port_match_inv << MAC_L3L4_CTR_L4DPIM_SHIFT); /* Enable L4 filters for SOURCE Port No matching */ value |= (l3_l4->data.src.port_match << MAC_L3L4_CTR_L4SPM_SHIFT) | - (perfect_inverse_match << MAC_L3L4_CTR_L4SPIM_SHIFT); + (l3_l4->data.src.port_match_inv << MAC_L3L4_CTR_L4SPIM_SHIFT); /* set udp / tcp port matching bit (for l4) */ value |= l3_l4->data.is_udp << MAC_L3L4_CTR_L4PEN_SHIFT; diff --git a/osi/core/core_common.h b/osi/core/core_common.h index 58fe13a..5634966 100644 --- a/osi/core/core_common.h +++ b/osi/core/core_common.h @@ -105,17 +105,16 @@ #define MAC_L3L4_CTR_L3SAIM_SHIFT 3 #endif /* !OSI_STRIPPED_LIB */ #define MAC_L3L4_CTR_L3DAM_SHIFT 4 -#define MAC_L3L4_CTR_L3DAIM_SHIFT 5 #ifndef OSI_STRIPPED_LIB +#define MAC_L3L4_CTR_L3DAIM_SHIFT 5 #define MAC_L3L4_CTR_L4PEN_SHIFT 16 #define MAC_L3L4_CTR_L4SPM_SHIFT 18 #define MAC_L3L4_CTR_L4SPIM_SHIFT 19 #define MAC_L3L4_CTR_L4DPM_SHIFT 20 #define MAC_L3L4_CTR_L4DPIM_SHIFT 21 #endif /* !OSI_STRIPPED_LIB */ -#define EQOS_MAC_L3L4_CTR_DMCHN_SHIFT 24 /* 3 bits */ +#define MAC_L3L4_CTR_DMCHN_SHIFT 24 #define EQOS_MAC_L3L4_CTR_DMCHEN_SHIFT 28 -#define MGBE_MAC_L3L4_CTR_DMCHN_SHIFT 24 /* 4 bits */ #define MGBE_MAC_L3L4_CTR_DMCHEN_SHIFT 31 /** diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 61175fd..2161e64 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -793,12 +793,94 @@ static nve32_t l3l4_find_match(const struct core_local *const l_core, } /** - * @brief configure_l3l4_filter_helper - helper function for l3l4 configuration + * @brief configure_l3l4_filter_valid_params - parameter validation function for l3l4 configuration * * @note * Algorithm: * - Validate all the l3_l4 structure parameter. - * Return -1 if parameter validation fails. + * - Verify routing dma channel id value. + * - Vefify each enable/disable parameters is <= OSI_TRUE. + * - Return -1 if parameter validation fails. + * - Return 0 on success. + * + * @param[inout] l_core: OSI local core data structure. + * @param[in] l3_l4: Pointer to l3 l4 filter structure (#osi_l3_l4_filter) + * + * @pre + * - MAC should be initialized and started. see osi_start_mac() + * + * @retval 0 on success + * @retval -1 on failure. + */ +static nve32_t configure_l3l4_filter_valid_params(const struct osi_core_priv_data *const osi_core, + const struct osi_l3_l4_filter *const l3_l4) +{ + const nveu32_t max_dma_chan[2] = { + OSI_EQOS_MAX_NUM_CHANS, + OSI_MGBE_MAX_NUM_CHANS + }; + nve32_t ret = -1; + + /* validate dma channel */ + if (l3_l4->dma_chan > max_dma_chan[osi_core->mac]) { + OSI_CORE_ERR((osi_core->osd), (OSI_LOG_ARG_OUTOFBOUND), + ("L3L4: Wrong DMA channel: "), (l3_l4->dma_chan)); + goto exit_func; + } + + /* valate enb parameters */ + if ((l3_l4->filter_enb_dis +#ifndef OSI_STRIPPED_LIB + | l3_l4->dma_routing_enable | + l3_l4->data.is_udp | + l3_l4->data.is_ipv6 | + l3_l4->data.src.port_match | + l3_l4->data.src.addr_match | + l3_l4->data.dst.port_match | + l3_l4->data.dst.addr_match | + l3_l4->data.src.port_match_inv | + l3_l4->data.src.addr_match_inv | + l3_l4->data.dst.port_match_inv | + l3_l4->data.dst.addr_match_inv +#endif /* !OSI_STRIPPED_LIB */ + ) > OSI_TRUE) { + OSI_CORE_ERR((osi_core->osd), (OSI_LOG_ARG_OUTOFBOUND), + ("L3L4: one of the enb param > OSI_TRUE: "), 0); + goto exit_func; + } + +#ifndef OSI_STRIPPED_LIB + /* validate port/addr enb bits */ + if (l3_l4->filter_enb_dis == OSI_TRUE) { + if ((l3_l4->data.src.port_match | l3_l4->data.src.addr_match | + l3_l4->data.dst.port_match | l3_l4->data.dst.addr_match) + == OSI_FALSE) { + OSI_CORE_ERR((osi_core->osd), (OSI_LOG_ARG_OUTOFBOUND), + ("L3L4: None of the enb bits are not set: "), 0); + goto exit_func; + } + if ((l3_l4->data.is_ipv6 & l3_l4->data.src.addr_match & + l3_l4->data.dst.addr_match) != OSI_FALSE) { + OSI_CORE_ERR((osi_core->osd), (OSI_LOG_ARG_OUTOFBOUND), + ("L3L4: Both ip6 addr match bits are set\n"), 0); + goto exit_func; + } + } +#endif /* !OSI_STRIPPED_LIB */ + + /* success */ + ret = 0; + +exit_func: + + return ret; +} + +/** + * @brief configure_l3l4_filter_helper - helper function for l3l4 configuration + * + * @note + * Algorithm: * - Confifure l3l4 filter using l_core->ops_p->config_l3l4_filters(). * Return -1 if config_l3l4_filters() fails. * - Store the filter into l_core->cfg.l3_l4[] and enable @@ -820,69 +902,7 @@ static nve32_t configure_l3l4_filter_helper(struct osi_core_priv_data *const osi { struct osi_l3_l4_filter *cfg_l3_l4; struct core_local *const l_core = (struct core_local *)(void *)osi_core; - const nveu32_t max_filter_no[2] = { - EQOS_MAX_L3_L4_FILTER, - OSI_MGBE_MAX_L3_L4_FILTER - }; - const nveu32_t max_dma_chan[2] = { - OSI_EQOS_MAX_NUM_CHANS, - OSI_MGBE_MAX_NUM_CHANS - }; - nve32_t ret = -1; - - /* validate filter index */ - if (filter_no >= max_filter_no[osi_core->mac]) { - OSI_CORE_ERR((osi_core->osd), (OSI_LOG_ARG_OUTOFBOUND), - ("invalid filter index for L3/L4 filter\n"), (filter_no)); - goto exit_func; - } - - /* validate dma channel */ - if (l3_l4->dma_chan > max_dma_chan[osi_core->mac]) { - OSI_CORE_ERR((osi_core->osd), (OSI_LOG_ARG_OUTOFBOUND), - ("L3L4: Wrong DMA channel: "), (l3_l4->dma_chan)); - goto exit_func; - } - - /* valate enb parameters */ - if (( -#ifndef OSI_STRIPPED_LIB - l3_l4->dma_routing_enable | - l3_l4->data.is_udp | - l3_l4->data.is_ipv6 | - l3_l4->data.perfect_inverse_match | - l3_l4->data.src.port_match | - l3_l4->data.src.addr_match | - l3_l4->data.dst.port_match | - l3_l4->data.dst.addr_match | -#endif /* !OSI_STRIPPED_LIB */ - l3_l4->filter_enb_dis - ) > OSI_TRUE) { - OSI_CORE_ERR((osi_core->osd), (OSI_LOG_ARG_OUTOFBOUND), - ("L3L4: one of the enb param > OSI_TRUE: "), (filter_no)); - goto exit_func; - } - -#ifndef OSI_STRIPPED_LIB - /* validate port/addr enb bits */ - if (l3_l4->filter_enb_dis == OSI_TRUE) { - if ((l3_l4->data.src.port_match | l3_l4->data.src.addr_match | - l3_l4->data.dst.port_match | l3_l4->data.dst.addr_match) - == OSI_FALSE) { - OSI_CORE_ERR((osi_core->osd), (OSI_LOG_ARG_OUTOFBOUND), - ("L3L4: None of the enb bits are not set: "), - (filter_no)); - goto exit_func; - } - if ((l3_l4->data.is_ipv6 & l3_l4->data.src.addr_match & - l3_l4->data.dst.addr_match) != OSI_FALSE) { - OSI_CORE_ERR((osi_core->osd), (OSI_LOG_ARG_OUTOFBOUND), - ("L3L4: Both ip6 addr match bits are set\n"), - (filter_no)); - goto exit_func; - } - } -#endif /* !OSI_STRIPPED_LIB */ + nve32_t ret; ret = l_core->ops_p->config_l3l4_filters(osi_core, filter_no, l3_l4); if (ret < 0) { @@ -902,7 +922,7 @@ static nve32_t configure_l3l4_filter_helper(struct osi_core_priv_data *const osi ("L3L4: ADD: "), (filter_no)); /* update filter mask bit */ - osi_core->l3l4_filter_bitmask |= (((nveu32_t)1U << filter_no) & 0x1FU); + osi_core->l3l4_filter_bitmask |= ((nveu32_t)1U << (filter_no & 0x1FU)); } else { /* Clear the filter data. * osi_memset is an internal function and it cannot fail, hence @@ -913,7 +933,7 @@ static nve32_t configure_l3l4_filter_helper(struct osi_core_priv_data *const osi ("L3L4: DELETE: "), (filter_no)); /* update filter mask bit */ - osi_core->l3l4_filter_bitmask &= ~(((nveu32_t)1U << filter_no) & 0x1FU); + osi_core->l3l4_filter_bitmask &= ~((nveu32_t)1U << (filter_no & 0x1FU)); } if (osi_core->l3l4_filter_bitmask != 0U) { @@ -960,11 +980,14 @@ static void l3l4_add_wildcard_filter(struct osi_core_priv_data *const osi_core, osi_memset(l3l4_filter, 0, sizeof(struct osi_l3_l4_filter)); l3l4_filter->filter_enb_dis = OSI_TRUE; l3l4_filter->data.is_udp = OSI_TRUE; - l3l4_filter->data.perfect_inverse_match = OSI_TRUE; l3l4_filter->data.src.port_match = OSI_TRUE; - l3l4_filter->data.dst.port_match = OSI_TRUE; + l3l4_filter->data.src.port_match_inv = OSI_TRUE; l3l4_filter->data.src.addr_match = OSI_TRUE; + l3l4_filter->data.src.addr_match_inv = OSI_TRUE; + l3l4_filter->data.dst.port_match = OSI_TRUE; + l3l4_filter->data.dst.port_match_inv = OSI_TRUE; l3l4_filter->data.dst.addr_match = OSI_TRUE; + l3l4_filter->data.dst.addr_match_inv = OSI_TRUE; /* configure wildcard at last filter index */ err = configure_l3l4_filter_helper(osi_core, max_filter_no, l3l4_filter); @@ -988,6 +1011,8 @@ static void l3l4_add_wildcard_filter(struct osi_core_priv_data *const osi_core, * * @note * Algorithm: + * - Validate all the l3_l4 structure parameter using configure_l3l4_filter_valid_params(). + * Return -1 if parameter validation fails. * - For filter enable case, * -> If filter already enabled, return -1 to report error. * -> Otherwise find free index and configure filter using configure_l3l4_filter_helper(). @@ -1022,6 +1047,11 @@ static nve32_t configure_l3l4_filter(struct osi_core_priv_data *const osi_core, }; nve32_t ret = -1; + if (configure_l3l4_filter_valid_params(osi_core, l3_l4) < 0) { + /* parameter validation failed */ + goto exit_func; + } + /* search for a duplicate filter request or find for free index */ err = l3l4_find_match(l_core, l3_l4, &filter_no, &free_filter_no, max_filter_no[osi_core->mac]); From a0afcf8463fec5d8e6be94a12d9ecdcab1579494 Mon Sep 17 00:00:00 2001 From: Mahesh Patil <maheshp@nvidia.com> Date: Tue, 8 Nov 2022 22:42:11 -0800 Subject: [PATCH 434/458] osi: core: eqos pad calibration reg offsets Make eqos pad calibration reg ETHER_QOS_AUTO_CAL_CONFIG_0 offsets AUTO_CAL_PD_OFFSET and AUTO_CAL_PU_OFFSET configurable as per customer boards tuning Bug 3846183 Change-Id: Ic305ced0d8324d7b9f5a03ffa7d6c21f7a12d9e5 Signed-off-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2805651 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Nagaraj Annaiah <nannaiah@nvidia.com> Reviewed-by: Ajay Gupta <ajayg@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- include/osi_core.h | 6 ++++++ osi/core/eqos_core.c | 11 +++++++++++ osi/core/eqos_core.h | 2 ++ 3 files changed, 19 insertions(+) diff --git a/include/osi_core.h b/include/osi_core.h index 5e65d26..2bf6fe5 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -174,6 +174,8 @@ typedef my_lint_64 nvel64_t; #define OSI_CHAN_ANY 0xFFU #define OSI_DFLT_MTU_SIZE 1500U #define OSI_MTU_SIZE_9000 9000U +/* Reg ETHER_QOS_AUTO_CAL_CONFIG_0[AUTO_CAL_PD/PU_OFFSET] max value */ +#define OSI_PAD_CAL_CONFIG_PD_PU_OFFSET_MAX 0x1FU #ifndef OSI_STRIPPED_LIB /* HW supports 8 Hash table regs, but eqos_validate_core_regs only checks 4 */ @@ -1191,6 +1193,10 @@ struct core_padctrl { nveu32_t is_pad_cal_in_progress; /** This flag set/reset using priv ioctl and DT entry */ nveu32_t pad_calibration_enable; + /** Reg ETHER_QOS_AUTO_CAL_CONFIG_0[AUTO_CAL_PD_OFFSET] value */ + nveu32_t pad_auto_cal_pd_offset; + /** Reg ETHER_QOS_AUTO_CAL_CONFIG_0[AUTO_CAL_PU_OFFSET] value */ + nveu32_t pad_auto_cal_pu_offset; }; #ifdef HSI_SUPPORT diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index d59f991..968848e 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -186,9 +186,14 @@ static nve32_t eqos_pad_calibrate(struct osi_core_priv_data *const osi_core) /* 3. Set AUTO_CAL_ENABLE and AUTO_CAL_START in * reg ETHER_QOS_AUTO_CAL_CONFIG_0. + * Set pad_auto_cal pd/pu offset values */ value = osi_readla(osi_core, (nveu8_t *)ioaddr + EQOS_PAD_AUTO_CAL_CFG); + value &= ~EQOS_PAD_CRTL_PU_OFFSET_MASK; + value &= ~EQOS_PAD_CRTL_PD_OFFSET_MASK; + value |= osi_core->padctrl.pad_auto_cal_pu_offset; + value |= (osi_core->padctrl.pad_auto_cal_pd_offset << 8U); value |= EQOS_PAD_AUTO_CAL_CFG_START | EQOS_PAD_AUTO_CAL_CFG_ENABLE; osi_writela(osi_core, value, (nveu8_t *)ioaddr + EQOS_PAD_AUTO_CAL_CFG); @@ -276,9 +281,15 @@ static nve32_t eqos_pad_calibrate(struct osi_core_priv_data *const osi_core) 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. + * Set pad_auto_cal pd/pu offset values */ + value = osi_readla(osi_core, (nveu8_t *)ioaddr + EQOS_PAD_AUTO_CAL_CFG); + value &= ~EQOS_PAD_CRTL_PU_OFFSET_MASK; + value &= ~EQOS_PAD_CRTL_PD_OFFSET_MASK; + value |= osi_core->padctrl.pad_auto_cal_pu_offset; + value |= (osi_core->padctrl.pad_auto_cal_pd_offset << 8U); value |= EQOS_PAD_AUTO_CAL_CFG_START | EQOS_PAD_AUTO_CAL_CFG_ENABLE; osi_writela(osi_core, value, (nveu8_t *)ioaddr + EQOS_PAD_AUTO_CAL_CFG); diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index 92bd66f..b3229d9 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -349,6 +349,8 @@ #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_PAD_CRTL_PD_OFFSET_MASK 0x1F00U +#define EQOS_PAD_CRTL_PU_OFFSET_MASK 0x1FU #define EQOS_MCR_IPC OSI_BIT(27) #define EQOS_MMC_CNTRL_CNTRST OSI_BIT(0) #define EQOS_MMC_CNTRL_RSTONRD OSI_BIT(2) From d3126492c3bde92fdf24d7cdfc51c516f80fa189 Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Fri, 25 Nov 2022 05:48:59 +0530 Subject: [PATCH 435/458] osi: core: enable m2m by default Mac2Mac sync code enable by default. Bug 3883951 Change-Id: Iaf09dba80be0d180bf23dff70c65a8e6f34ab9d2 Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2814598 Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- include/osi_common.h | 3 ++ osi/core/core_local.h | 17 ++----- osi/core/osi_core.c | 15 +++--- osi/core/osi_hal.c | 106 +++++++++++++++++++++++++++++------------- 4 files changed, 87 insertions(+), 54 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index 8dd1a13..667b6a3 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -146,6 +146,9 @@ #endif #ifndef INT_MAX #define INT_MAX (0x7FFFFFFF) +#ifndef OSI_LLONG_MAX +#define OSI_LLONG_MAX (0x7FFFFFFFFFFFFFFF) +#endif #endif /** @} */ diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 248206c..fac7c8b 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -237,22 +237,16 @@ struct core_ops { * @brief constant values for drift MAC to MAC sync. */ /* No longer needed since DRIFT CAL is not used */ -#ifdef ENABLE_DRIFT_CAL -#define DRIFT_CAL 1 -#define I_COMPONENT_BY_10 3 -#define P_COMPONENT_BY_10 7 -#define WEIGHT_BY_10 10 +#define I_COMPONENT_BY_10 3LL +#define P_COMPONENT_BY_10 7LL +#define WEIGHT_BY_10 10LL #define MAX_FREQ 85000000LL #define SERVO_STATS_0 0U #define SERVO_STATS_1 1U #define SERVO_STATS_2 2U -#else -#define DRIFT_CAL 0 -#endif #define ETHER_NSEC_MASK 0x7FFFFFFFU -#if DRIFT_CAL /** * @brief servo data structure. */ @@ -277,7 +271,6 @@ struct core_ptp_servo { /* MAC to MAC locking to access HW time register within OSI calls */ nveu32_t m2m_lock; }; -#endif /** * @brief AVB dynamic config storage structure @@ -367,10 +360,8 @@ struct core_local { nveu32_t ts_lock; /** Controller mac to mac role */ nveu32_t ether_m2m_role; -#if DRIFT_CAL /** Servo structure */ struct core_ptp_servo serv; -#endif /** 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 */ @@ -483,7 +474,6 @@ void hw_interface_init_core_ops(struct if_core_ops *if_ops_p); */ void ivc_interface_init_core_ops(struct if_core_ops *if_ops_p); -#ifdef ENABLE_DRIFT_CAL /** * @brief get osi pointer for PTP primary/sec interface * @@ -515,5 +505,4 @@ void ivc_interface_init_core_ops(struct if_core_ops *if_ops_p); * @retval NULL on failure. */ struct osi_core_priv_data *get_role_pointer(nveu32_t role); -#endif #endif /* INCLUDED_CORE_LOCAL_H */ diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index e73872a..c04339f 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -25,6 +25,8 @@ #include "core_local.h" #include "../osi/common/common.h" +static struct core_local g_core[MAX_CORE_INSTANCES]; + /** * @brief Function to validate function pointers. * @@ -96,7 +98,6 @@ static inline nve32_t validate_if_args(struct osi_core_priv_data *const osi_core struct osi_core_priv_data *osi_get_core(void) { nveu32_t i; - static struct core_local g_core[MAX_CORE_INSTANCES]; for (i = 0U; i < MAX_CORE_INSTANCES; i++) { if (g_core[i].if_init_done == OSI_ENABLE) { @@ -119,27 +120,27 @@ struct osi_core_priv_data *osi_get_core(void) return &g_core[i].osi_core; } -#ifdef ENABLE_DRIFT_CAL struct osi_core_priv_data *get_role_pointer(nveu32_t role) { nveu32_t i; + struct osi_core_priv_data *ret_ptr = OSI_NULL; if ((role != OSI_PTP_M2M_PRIMARY) && (role != OSI_PTP_M2M_SECONDARY)) { - return OSI_NULL; + goto done; } /* 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; + ret_ptr = &g_core[i].osi_core; } } - return OSI_NULL; +done: + return ret_ptr; } -#endif nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core) { @@ -182,12 +183,10 @@ nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core) } l_core->ts_lock = OSI_DISABLE; l_core->ether_m2m_role = osi_core->m2m_role; -#if DRIFT_CAL 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); -#endif #ifdef MACSEC_SUPPORT osi_lock_init(&osi_core->macsec_fpe_lock); #endif /* MACSEC_SUPPORT */ diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 2161e64..2dc835a 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -37,7 +37,6 @@ * @brief g_ops - Static core operations array. */ -#if DRIFT_CAL /** * @brief Function to validate input arguments of API. * @@ -54,17 +53,18 @@ * @retval -1 on Failure */ static inline nve32_t validate_args(struct osi_core_priv_data *const osi_core, - struct core_local *l_core) + struct core_local *const l_core) { + nve32_t ret = 0; + 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; + ret = -1; } - return 0; + return ret; } -#endif /** * @brief Function to validate function pointers. @@ -1795,7 +1795,6 @@ done: return ret; } -#if DRIFT_CAL /** * @brief calculate time drift between primary and secondary * interface. @@ -1839,10 +1838,11 @@ static inline nvel64_t dirft_calculation(nveu32_t sec, nveu32_t nsec, * @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) + nvel64_t offset, + nvel64_t secondary_time) { struct core_ptp_servo *s; - struct core_local *secondary_osi_lcore = (struct core_local *)sec_osi_core; + struct core_local *secondary_osi_lcore = (struct core_local *)(void *)sec_osi_core; nvel64_t ki_term, ppb = 0; nvel64_t cofficient; @@ -1853,9 +1853,9 @@ static inline nve32_t freq_offset_calculate(struct osi_core_priv_data *sec_osi_c * it should be corrected with adjust time * threshold value 1 sec */ - if ((offset >= 1000000000) || (offset <= -1000000000)) { + if ((offset >= 1000000000LL) || (offset <= -1000000000LL)) { s->count = SERVO_STATS_0; /* JUMP */ - return (nve32_t) s->last_ppb; + goto fail; } switch (s->count) { @@ -1871,14 +1871,29 @@ static inline nve32_t freq_offset_calculate(struct osi_core_priv_data *sec_osi_c /* Make sure the first sample is older than the second. */ if (s->local[0] >= s->local[1]) { + s->offset[0] = s->offset[1]; + 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]; + if ((cofficient == 0) || + (((cofficient < 0) && (s->offset[1] < 0)) && + ((OSI_LLONG_MAX / cofficient) < s->offset[1])) || + ((cofficient < 0) && ((-OSI_LLONG_MAX / cofficient) > s->offset[1])) || + ((s->offset[1] < 0) && ((-OSI_LLONG_MAX / cofficient) > s->offset[1]))) { + /* do nothing */ + } else { + if (((s->drift >= 0) && ((OSI_LLONG_MAX - s->drift) < (cofficient * s->offset[1]))) || + ((s->drift < 0) && ((-OSI_LLONG_MAX - s->drift) > (cofficient * s->offset[1])))) { + /* Do nothing */ + } else { + s->drift += cofficient * s->offset[1]; + } + } /* update this with constant */ if (s->drift < -MAX_FREQ) { s->drift = -MAX_FREQ; @@ -1897,10 +1912,31 @@ static inline nve32_t freq_offset_calculate(struct osi_core_priv_data *sec_osi_c case SERVO_STATS_2: s->offset[1] = offset; s->local[1] = secondary_time; + if (s->local[0] >= s->local[1]) { + s->offset[0] = s->offset[1]; + s->local[0] = s->local[1]; + s->count = SERVO_STATS_0; + break; + } + cofficient = (1000000000LL) / (s->local[1] - s->local[0]); + + if ((cofficient != 0) && (offset < 0) && + ((s->const_i > (-OSI_LLONG_MAX / (WEIGHT_BY_10 * cofficient * offset))) || + (s->const_p > (-OSI_LLONG_MAX / (WEIGHT_BY_10 * cofficient * offset))))) { + s->count = SERVO_STATS_0; + break; + } + if ((cofficient != 0) && (offset > 0) && + ((s->const_i > (OSI_LLONG_MAX / (WEIGHT_BY_10 * cofficient * offset))) || + (s->const_p > (OSI_LLONG_MAX / (WEIGHT_BY_10 * cofficient * offset))))) { + s->count = SERVO_STATS_0; + break; + } + /* calculate ppb */ - ki_term = (s->const_i * cofficient * offset * WEIGHT_BY_10) / (100); - ppb = ((s->const_p * cofficient * offset * WEIGHT_BY_10) / (100)) + s->drift + + ki_term = ((s->const_i * cofficient * offset) / WEIGHT_BY_10); + ppb = (s->const_p * cofficient * offset / WEIGHT_BY_10) + s->drift + ki_term; /* FIXME tune cofficients */ @@ -1909,10 +1945,15 @@ static inline nve32_t freq_offset_calculate(struct osi_core_priv_data *sec_osi_c } else if (ppb > MAX_FREQ) { ppb = MAX_FREQ; } else { - s->drift += ki_term; + if (((s->drift >= 0) && ((OSI_LLONG_MAX - s->drift) < ki_term)) || + ((s->drift < 0) && ((-OSI_LLONG_MAX - s->drift) > ki_term))) { + } else { + + s->drift += ki_term; + } + s->offset[0] = s->offset[1]; + s->local[0] = s->local[1]; } - s->offset[0] = s->offset[1]; - s->local[0] = s->local[1]; break; default: break; @@ -1920,9 +1961,13 @@ static inline nve32_t freq_offset_calculate(struct osi_core_priv_data *sec_osi_c s->last_ppb = ppb; +fail: + if ((ppb > INT_MAX) || (ppb < -INT_MAX)) { + ppb = 0LL; + } + return (nve32_t)ppb; } -#endif static void cfg_l3_l4_filter(struct core_local *l_core) { @@ -2257,7 +2302,6 @@ static nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, struct core_local *l_core = (struct core_local *)(void *)osi_core; const 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; nvel64_t drift_value = 0x0; @@ -2267,7 +2311,6 @@ static nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, nveu32_t secondary_nsec = 0x0; nve32_t freq_adj_value = 0x0; nvel64_t secondary_time; -#endif ops_p = l_core->ops_p; @@ -2427,7 +2470,6 @@ static nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, case OSI_CMD_ADJ_FREQ: ret = osi_adjust_freq(osi_core, data->arg6_32); -#if DRIFT_CAL if (ret < 0) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "CORE: adjust freq failed\n", 0ULL); @@ -2440,7 +2482,7 @@ static nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, } sec_osi_core = get_role_pointer(OSI_PTP_M2M_SECONDARY); - secondary_osi_lcore = (struct core_local *)sec_osi_core; + secondary_osi_lcore = (struct core_local *)(void *)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)) { @@ -2457,7 +2499,7 @@ static nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, 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_time = ((nvel64_t)secondary_sec * 1000000000LL) + (nvel64_t)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, @@ -2479,12 +2521,12 @@ static nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, 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_core->osd, OSI_LOG_ARG_INVALID, "CORE: adjust_time failed\n", 0ULL); @@ -2497,7 +2539,7 @@ static nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, } sec_osi_core = get_role_pointer(OSI_PTP_M2M_SECONDARY); - secondary_osi_lcore = (struct core_local *)sec_osi_core; + secondary_osi_lcore = (struct core_local *)(void *)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)) { @@ -2529,7 +2571,7 @@ static nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, 0ULL); ret = 0; } -#endif + break; case OSI_CMD_CONFIG_PTP: @@ -2538,7 +2580,7 @@ static nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, l_core->cfg.ptp = data->arg1_u32; l_core->cfg.flags |= DYNAMIC_CFG_PTP; } -#if DRIFT_CAL + if (ret < 0) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "CORE: configure_ptp failed\n", 0ULL); @@ -2551,7 +2593,7 @@ static nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, } sec_osi_core = get_role_pointer(OSI_PTP_M2M_SECONDARY); - secondary_osi_lcore = (struct core_local *)sec_osi_core; + secondary_osi_lcore = (struct core_local *)(void *)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)) { @@ -2564,7 +2606,7 @@ static nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, secondary_osi_lcore->serv.drift = 0; secondary_osi_lcore->serv.last_ppb = 0; } -#endif + break; case OSI_CMD_GET_HW_FEAT: @@ -2573,7 +2615,7 @@ static nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, case OSI_CMD_SET_SYSTOHW_TIME: ret = hw_set_systime_to_mac(osi_core, data->arg1_u32, data->arg2_u32); -#if DRIFT_CAL + if (ret < 0) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "CORE: set systohw time failed\n", 0ULL); @@ -2586,7 +2628,7 @@ static nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, } sec_osi_core = get_role_pointer(OSI_PTP_M2M_SECONDARY); - secondary_osi_lcore = (struct core_local *)sec_osi_core; + secondary_osi_lcore = (struct core_local *)(void *)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)) { @@ -2611,7 +2653,7 @@ static nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, 0ULL); ret = 0; } -#endif + break; #ifndef OSI_STRIPPED_LIB case OSI_CMD_CONFIG_PTP_OFFLOAD: From 5971a8a4dfa2b4eab65d6f8190416422a5e0de10 Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Tue, 6 Dec 2022 10:22:23 +0000 Subject: [PATCH 436/458] osi: core: fix CERT INT31-C Bug 3745813 Change-Id: I7d686c45ae5e74f3bfc3c4e6642fc38ee312d6a1 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2821888 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/core_common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osi/core/core_common.c b/osi/core/core_common.c index 309efbd..08d906f 100644 --- a/osi/core/core_common.c +++ b/osi/core/core_common.c @@ -453,7 +453,7 @@ void hw_config_tscr(struct osi_core_priv_data *const osi_core, OSI_UNUSED const void hw_config_ssir(struct osi_core_priv_data *const osi_core) { - nveul64_t val = 0U; + nveu32_t val = 0U; void *addr = osi_core->base; const struct core_local *l_core = (struct core_local *)(void *)osi_core; const nveu32_t mac_ssir[2] = { EQOS_MAC_SSIR, MGBE_MAC_SSIR}; @@ -465,7 +465,7 @@ void hw_config_ssir(struct osi_core_priv_data *const osi_core) val |= val << MAC_SSIR_SSINC_SHIFT; /* update Sub-second Increment Value */ - osi_writela(osi_core, (nveu32_t)val, ((nveu8_t *)addr + mac_ssir[osi_core->mac])); + osi_writela(osi_core, val, ((nveu8_t *)addr + mac_ssir[osi_core->mac])); } nve32_t hw_ptp_tsc_capture(struct osi_core_priv_data *const osi_core, From 82f49383950680fb46dd81ee0fe30c3e8155e691 Mon Sep 17 00:00:00 2001 From: Mahesh Patil <maheshp@nvidia.com> Date: Wed, 26 Oct 2022 17:19:51 -0700 Subject: [PATCH 437/458] macsec: Rename LOG to MACSEC_LOG Rename LOG to MACSEC_LOG to avoid conflicts with other modules LOG macro Bug 3338608 Change-Id: Ib746dc4cddd835308cf6a6da8e79135c566a8135 Signed-off-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2798519 Reviewed-by: Nagaraj Annaiah <nannaiah@nvidia.com> Reviewed-by: Ajay Gupta <ajayg@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- osi/core/macsec.c | 127 ++++++++++++++++++++++++++-------------------- 1 file changed, 71 insertions(+), 56 deletions(-) diff --git a/osi/core/macsec.c b/osi/core/macsec.c index 1078752..3b1331f 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -26,7 +26,21 @@ #include "../osi/common/common.h" #include "core_local.h" -#define LOG(...) +#if defined(DEBUG_MACSEC) && defined(QNX_OS) +#define MACSEC_LOG(...) \ + { \ + slogf(0, 6, ##__VA_ARGS__); \ + } + +#elif defined(DEBUG_MACSEC) && defined(LINUX_OS) +#include <linux/printk.h> +#define MACSEC_LOG(...) \ + { \ + pr_debug(__VA_ARGS__); \ + } +#else +#define MACSEC_LOG(...) +#endif #ifdef DEBUG_MACSEC /** @@ -225,7 +239,7 @@ static void write_tx_dbg_trigger_evts( tx_trigger_evts &= ~MACSEC_TX_DBG_CAPTURE; } - LOG("%s: 0x%x", __func__, tx_trigger_evts); + MACSEC_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) { @@ -233,7 +247,7 @@ static void write_tx_dbg_trigger_evts( 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__, + MACSEC_LOG("%s: debug_ctrl_reg 0x%x", __func__, debug_ctrl_reg); osi_writela(osi_core, debug_ctrl_reg, base + MACSEC_TX_DEBUG_CONTROL_0); @@ -275,7 +289,7 @@ static void tx_dbg_trigger_evts( } else { tx_trigger_evts = osi_readla(osi_core, base + MACSEC_TX_DEBUG_TRIGGER_EN_0); - LOG("%s: 0x%x", __func__, tx_trigger_evts); + MACSEC_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; } @@ -367,7 +381,7 @@ static void write_rx_dbg_trigger_evts( } else { rx_trigger_evts &= ~MACSEC_RX_DBG_CAPTURE; } - LOG("%s: 0x%x", __func__, rx_trigger_evts); + MACSEC_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) { @@ -375,7 +389,7 @@ static void write_rx_dbg_trigger_evts( 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__, + MACSEC_LOG("%s: debug_ctrl_reg 0x%x", __func__, debug_ctrl_reg); osi_writela(osi_core, debug_ctrl_reg, base + MACSEC_RX_DEBUG_CONTROL_0); @@ -417,7 +431,7 @@ static void rx_dbg_trigger_evts( } else { rx_trigger_evts = osi_readla(osi_core, base + MACSEC_RX_DEBUG_TRIGGER_EN_0); - LOG("%s: 0x%x", __func__, rx_trigger_evts); + MACSEC_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; } @@ -789,21 +803,21 @@ static nve32_t macsec_enable(struct osi_core_priv_data *const osi_core, } val = osi_readla(osi_core, base + MACSEC_CONTROL0); - LOG("Read MACSEC_CONTROL0: 0x%x \n", val); + MACSEC_LOG("Read MACSEC_CONTROL0: 0x%x \n", val); if ((enable & OSI_MACSEC_TX_EN) == OSI_MACSEC_TX_EN) { - LOG("Enabling macsec TX\n"); + MACSEC_LOG("Enabling macsec TX\n"); val |= (MACSEC_TX_EN); } else { - LOG("Disabling macsec TX\n"); + MACSEC_LOG("Disabling macsec TX\n"); val &= ~(MACSEC_TX_EN); } if ((enable & OSI_MACSEC_RX_EN) == OSI_MACSEC_RX_EN) { - LOG("Enabling macsec RX\n"); + MACSEC_LOG("Enabling macsec RX\n"); val |= (MACSEC_RX_EN); } else { - LOG("Disabling macsec RX\n"); + MACSEC_LOG("Disabling macsec RX\n"); val &= ~(MACSEC_RX_EN); } @@ -814,7 +828,7 @@ static nve32_t macsec_enable(struct osi_core_priv_data *const osi_core, osi_core->is_macsec_enabled = OSI_DISABLE; } - LOG("Write MACSEC_CONTROL0: 0x%x\n", val); + MACSEC_LOG("Write MACSEC_CONTROL0: 0x%x\n", val); osi_writela(osi_core, val, base + MACSEC_CONTROL0); exit: @@ -2972,7 +2986,7 @@ static nve32_t validate_lut_conf(const struct osi_macsec_lut_config *const lut_c (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," + MACSEC_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, @@ -3100,7 +3114,7 @@ static inline void handle_rx_sc_invalid_key( nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; nveu32_t clear = 0; - LOG("%s()\n", __func__); + MACSEC_LOG("%s()\n", __func__); /** check which SC/AN had triggered and clear */ /* rx_sc0_7 */ @@ -3136,7 +3150,7 @@ static inline void handle_tx_sc_invalid_key( nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; nveu32_t clear = 0; - LOG("%s()\n", __func__); + MACSEC_LOG("%s()\n", __func__); /** check which SC/AN had triggered and clear */ /* tx_sc0_7 */ @@ -3171,7 +3185,7 @@ static inline void handle_safety_err_irq( { OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, "Safety Error Handler \n", 0ULL); - LOG("%s()\n", __func__); + MACSEC_LOG("%s()\n", __func__); } /** @@ -3445,7 +3459,7 @@ static inline void handle_tx_irq(struct osi_core_priv_data *const osi_core) #endif tx_isr = osi_readla(osi_core, addr + MACSEC_TX_ISR); - LOG("%s(): tx_isr 0x%x\n", __func__, tx_isr); + MACSEC_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); @@ -3546,7 +3560,7 @@ static inline void handle_rx_irq(struct osi_core_priv_data *const osi_core) #endif rx_isr = osi_readla(osi_core, addr + MACSEC_RX_ISR); - LOG("%s(): rx_isr 0x%x\n", __func__, rx_isr); + MACSEC_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) { @@ -3650,7 +3664,7 @@ static inline void handle_common_irq(struct osi_core_priv_data *const osi_core) 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); + MACSEC_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); @@ -3721,7 +3735,7 @@ static void macsec_handle_irq(struct osi_core_priv_data *const osi_core) 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); + MACSEC_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); } @@ -4259,17 +4273,17 @@ static nve32_t macsec_update_mtu(struct osi_core_priv_data *const osi_core, } /* Set MTU */ val = osi_readla(osi_core, addr + MACSEC_TX_MTU_LEN); - LOG("Read MACSEC_TX_MTU_LEN: 0x%x\n", val); + MACSEC_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); + MACSEC_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); + MACSEC_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); + MACSEC_LOG("Write MACSEC_RX_MTU_LEN: 0x%x\n", val); osi_writela(osi_core, val, addr + MACSEC_RX_MTU_LEN); exit: return ret; @@ -4365,7 +4379,7 @@ static void macsec_intr_config(struct osi_core_priv_data *const osi_core, nveu32 if (enable == OSI_ENABLE) { val = osi_readla(osi_core, addr + MACSEC_TX_IMR); - LOG("Read MACSEC_TX_IMR: 0x%x\n", val); + MACSEC_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_SC_AN_NOT_VALID_INT_EN | @@ -4373,10 +4387,10 @@ static void macsec_intr_config(struct osi_core_priv_data *const osi_core, nveu32 MACSEC_TX_PN_EXHAUSTED_INT_EN | MACSEC_TX_PN_THRSHLD_RCHD_INT_EN); osi_writela(osi_core, val, addr + MACSEC_TX_IMR); - LOG("Write MACSEC_TX_IMR: 0x%x\n", val); + MACSEC_LOG("Write MACSEC_TX_IMR: 0x%x\n", val); val = osi_readla(osi_core, addr + MACSEC_RX_IMR); - LOG("Read MACSEC_RX_IMR: 0x%x\n", val); + MACSEC_LOG("Read MACSEC_RX_IMR: 0x%x\n", val); val |= (MACSEC_RX_DBG_BUF_CAPTURE_DONE_INT_EN | RX_REPLAY_ERROR_INT_EN | @@ -4385,19 +4399,19 @@ static void macsec_intr_config(struct osi_core_priv_data *const osi_core, nveu32 MACSEC_RX_PN_EXHAUSTED_INT_EN ); osi_writela(osi_core, val, addr + MACSEC_RX_IMR); - LOG("Write MACSEC_RX_IMR: 0x%x\n", val); + MACSEC_LOG("Write MACSEC_RX_IMR: 0x%x\n", val); val = osi_readla(osi_core, addr + MACSEC_COMMON_IMR); - LOG("Read MACSEC_COMMON_IMR: 0x%x\n", val); + MACSEC_LOG("Read MACSEC_COMMON_IMR: 0x%x\n", val); val |= (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); osi_writela(osi_core, val, addr + MACSEC_COMMON_IMR); - LOG("Write MACSEC_COMMON_IMR: 0x%x\n", val); + MACSEC_LOG("Write MACSEC_COMMON_IMR: 0x%x\n", val); } else { val = osi_readla(osi_core, addr + MACSEC_TX_IMR); - LOG("Read MACSEC_TX_IMR: 0x%x\n", val); + MACSEC_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_SC_AN_NOT_VALID_INT_EN & @@ -4405,10 +4419,10 @@ static void macsec_intr_config(struct osi_core_priv_data *const osi_core, nveu32 ~MACSEC_TX_PN_EXHAUSTED_INT_EN & ~MACSEC_TX_PN_THRSHLD_RCHD_INT_EN); osi_writela(osi_core, val, addr + MACSEC_TX_IMR); - LOG("Write MACSEC_TX_IMR: 0x%x\n", val); + MACSEC_LOG("Write MACSEC_TX_IMR: 0x%x\n", val); val = osi_readla(osi_core, addr + MACSEC_RX_IMR); - LOG("Read MACSEC_RX_IMR: 0x%x\n", val); + MACSEC_LOG("Read MACSEC_RX_IMR: 0x%x\n", val); val &= (~MACSEC_RX_DBG_BUF_CAPTURE_DONE_INT_EN & ~RX_REPLAY_ERROR_INT_EN & ~MACSEC_RX_MTU_CHECK_FAIL_INT_EN & @@ -4416,16 +4430,16 @@ static void macsec_intr_config(struct osi_core_priv_data *const osi_core, nveu32 ~MACSEC_RX_PN_EXHAUSTED_INT_EN ); osi_writela(osi_core, val, addr + MACSEC_RX_IMR); - LOG("Write MACSEC_RX_IMR: 0x%x\n", val); + MACSEC_LOG("Write MACSEC_RX_IMR: 0x%x\n", val); val = osi_readla(osi_core, addr + MACSEC_COMMON_IMR); - LOG("Read MACSEC_COMMON_IMR: 0x%x\n", val); + MACSEC_LOG("Read MACSEC_COMMON_IMR: 0x%x\n", val); val &= (~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); osi_writela(osi_core, val, addr + MACSEC_COMMON_IMR); - LOG("Write MACSEC_COMMON_IMR: 0x%x\n", val); + MACSEC_LOG("Write MACSEC_COMMON_IMR: 0x%x\n", val); } } #endif /* DEBUG_MACSEC */ @@ -4496,65 +4510,66 @@ static nve32_t macsec_initialize(struct osi_core_priv_data *const osi_core, nveu */ 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); + MACSEC_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); + MACSEC_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); + MACSEC_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); + MACSEC_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); + MACSEC_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); + MACSEC_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); + MACSEC_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); + MACSEC_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); + MACSEC_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); + MACSEC_LOG("Write MACSEC_STATS_CONTROL_0: 0x%x\n", val); osi_writela(osi_core, val, addr + MACSEC_STATS_CONTROL_0); /* Enable default HSI related interrupts needed */ val = osi_readla(osi_core, addr + MACSEC_TX_IMR); - LOG("Read MACSEC_TX_IMR: 0x%x\n", val); + MACSEC_LOG("Read MACSEC_TX_IMR: 0x%x\n", val); val |= MACSEC_TX_MAC_CRC_ERROR_INT_EN; - LOG("Write MACSEC_TX_IMR: 0x%x\n", val); + MACSEC_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); /* Enabling interrupts only related to HSI */ val = osi_readla(osi_core, addr + MACSEC_RX_IMR); - LOG("Read MACSEC_RX_IMR: 0x%x\n", val); + MACSEC_LOG("Read MACSEC_RX_IMR: 0x%x\n", val); val |= (MACSEC_RX_ICV_ERROR_INT_EN | MACSEC_RX_MAC_CRC_ERROR_INT_EN); - LOG("Write MACSEC_RX_IMR: 0x%x\n", val); + MACSEC_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); val |= MACSEC_SECURE_REG_VIOL_INT_EN; osi_writela(osi_core, val, addr + MACSEC_COMMON_IMR); + /* Set AES mode * Default power on reset is AES-GCM128, leave it. */ @@ -5294,7 +5309,7 @@ static nve32_t add_new_sc(struct osi_core_priv_data *const osi_core, } else { /* Update lut status */ lut_status_ptr->num_of_sc_used++; - LOG("%s: Added new SC ctlr: %u " + MACSEC_LOG("%s: Added new SC ctlr: %u " "Total active SCs: %u", __func__, ctlr, lut_status_ptr->num_of_sc_used); @@ -5364,14 +5379,14 @@ static nve32_t macsec_configure(struct osi_core_priv_data *const osi_core, ret = -1; goto exit; } else { - LOG("%s: Adding new SC/SA: ctlr: %hu", __func__, ctlr); + MACSEC_LOG("%s: Adding new SC/SA: ctlr: %hu", __func__, ctlr); ret = add_new_sc(osi_core, sc, ctlr, kt_idx); goto exit; } } else { - LOG("%s: Updating existing SC", __func__); + MACSEC_LOG("%s: Updating existing SC", __func__); if (enable == OSI_DISABLE) { - LOG("%s: Deleting existing SA", __func__); + MACSEC_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, @@ -5415,7 +5430,7 @@ static nve32_t macsec_configure(struct osi_core_priv_data *const osi_core, ret = -1; goto exit; } else { - LOG("%s: Updated new SC ctlr: %u " + MACSEC_LOG("%s: Updated new SC ctlr: %u " "Total active SCs: %u", __func__, ctlr, lut_status_ptr->num_of_sc_used); From 58b4a6abb85147e2c52293e774e7ba66f3dec857 Mon Sep 17 00:00:00 2001 From: Mahesh Patil <maheshp@nvidia.com> Date: Fri, 2 Dec 2022 02:16:32 +0000 Subject: [PATCH 438/458] osi: core: Macsec hw access when disabled - Do not allow macsec reg read/write when macsec is not supported or macsec is disabled in DT - Fix macsec ops null access crash during mtu when macsec disabled Bug 3889865 Change-Id: Ia111027c7f880a9697470b4118a9c98483575871 Signed-off-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2820321 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/eqos_core.c | 31 ++++++++++++++++++++++++++----- osi/core/osi_hal.c | 3 ++- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 968848e..5ae8432 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -2944,12 +2944,23 @@ static nveu32_t eqos_write_reg(struct osi_core_priv_data *const osi_core, * - Initialization: Yes * - Run time: Yes * - De-initialization: Yes - * @retval data from register on success + * @retval data from register on success and 0xffffffff on failure */ 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); + nveu32_t ret = 0; + + if (osi_core->macsec_ops != OSI_NULL) { + ret = osi_readla(osi_core, (nveu8_t *)osi_core->macsec_base + + reg); + } else { + /* macsec is not supported or not enabled in DT */ + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "read reg failed", 0ULL); + ret = 0xffffffff; + } + return ret; } /** @@ -2964,13 +2975,23 @@ static nveu32_t eqos_read_macsec_reg(struct osi_core_priv_data *const osi_core, * - Initialization: Yes * - Run time: Yes * - De-initialization: Yes - * @retval 0 + * @retval 0 on success or 0xffffffff on error */ 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; + nveu32_t ret = 0; + + if (osi_core->macsec_ops != OSI_NULL) { + osi_writela(osi_core, val, (nveu8_t *)osi_core->macsec_base + + reg); + } else { + /* macsec is not supported or not enabled in DT */ + OSI_CORE_ERR(osi_core->osd, + OSI_LOG_ARG_HW_FAIL, "write reg failed", 0ULL); + ret = 0xffffffff; + } + return ret; } #endif /* MACSEC_SUPPORT */ diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 2dc835a..dc506ed 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -2723,7 +2723,8 @@ static nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, case OSI_CMD_MAC_MTU: ret = 0; #ifdef MACSEC_SUPPORT - if (osi_core->macsec_ops->update_mtu != OSI_NULL) { + if ((osi_core->macsec_ops != OSI_NULL) && + (osi_core->macsec_ops->update_mtu != OSI_NULL)) { ret = osi_core->macsec_ops->update_mtu(osi_core, data->arg1_u32); } #endif /* MACSEC_SUPPORT */ From 4477838ca3946bcdce49ca008fa731eacedbaf22 Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Fri, 2 Dec 2022 16:38:43 +0000 Subject: [PATCH 439/458] osi: core: fix MISRA rule 15.5 JIRA NET-520 Bug 3899804 Change-Id: Ibec55a06c960aec5550cdea77dbaf89210f49b9e Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2820748 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/eqos_core.c | 435 ++++++++++++++++++++++--------------------- osi/core/eqos_mmc.c | 6 +- osi/core/ivc_core.c | 5 +- osi/core/mgbe_core.c | 255 +++++++++++++------------ osi/core/mgbe_mmc.c | 6 +- osi/core/osi_core.c | 81 +++++--- osi/core/osi_hal.c | 59 +++--- osi/core/xpcs.c | 190 ++++++++++--------- osi/core/xpcs.h | 28 ++- 9 files changed, 568 insertions(+), 497 deletions(-) diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 5ae8432..b1db023 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -392,7 +392,7 @@ static nve32_t eqos_configure_mtl_queue(struct osi_core_priv_data *const osi_cor ret = hw_flush_mtl_tx_queue(osi_core, que_idx); if (ret < 0) { - return ret; + goto fail; } value = (tx_fifo_sz_t << EQOS_MTL_TXQ_SIZE_SHIFT); @@ -436,7 +436,8 @@ static nve32_t eqos_configure_mtl_queue(struct osi_core_priv_data *const osi_cor value |= ((osi_core->rxq_ctrl[que_idx] & EQOS_RXQ_EN_MASK) << (que_idx * 2U)); osi_writela(osi_core, value, (nveu8_t *)osi_core->base + EQOS_MAC_RQC0R); - return 0; +fail: + return ret; } /** \endcond */ @@ -1210,10 +1211,6 @@ static void eqos_dma_chan_to_vmirq_map(struct osi_core_priv_data *osi_core) 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++) { @@ -1226,7 +1223,7 @@ static void eqos_dma_chan_to_vmirq_map(struct osi_core_priv_data *osi_core) EQOS_VIRT_INTR_APB_CHX_CNTRL(chan)); } osi_writel(OSI_BIT(irq_data->vm_num), - (nveu8_t *)osi_core->base + VIRTUAL_APB_ERR_CTRL); + (nveu8_t *)osi_core->base + VIRTUAL_APB_ERR_CTRL); } } @@ -1276,7 +1273,7 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core) if (ret < 0) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "eqos pad calibration failed\n", 0ULL); - return ret; + goto fail; } #endif /* !UPDATED_PAD_CAL */ @@ -1330,7 +1327,8 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core) if (osi_unlikely(osi_core->num_mtl_queues > OSI_EQOS_MAX_NUM_QUEUES)) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Number of queues is incorrect\n", 0ULL); - return -1; + ret = -1; + goto fail; } /* Configure MTL Queues */ @@ -1339,11 +1337,12 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core) OSI_EQOS_MAX_NUM_QUEUES)) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Incorrect queues number\n", 0ULL); - return -1; + ret = -1; + goto fail; } ret = eqos_configure_mtl_queue(osi_core, osi_core->mtl_queues[qinx]); if (ret < 0) { - return ret; + goto fail; } /* Enable by default to configure forward error packets. * Since this is a local function this will always return sucess, @@ -1367,8 +1366,10 @@ static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core) /* initialize L3L4 Filters variable */ osi_core->l3l4_filter_bitmask = OSI_NONE; - eqos_dma_chan_to_vmirq_map(osi_core); - + if (osi_core->mac_ver >= OSI_EQOS_MAC_5_30) { + eqos_dma_chan_to_vmirq_map(osi_core); + } +fail: return ret; } @@ -1425,6 +1426,57 @@ static void eqos_handle_mac_fpe_intrs(struct osi_core_priv_data *osi_core) (nveu8_t *)osi_core->base + EQOS_MAC_FPE_CTS); } +/** + * @brief eqos_handle_mac_link_intrs + * + * Algorithm: This function takes care of handling the + * MAC link interrupts. + * + * @param[in] osi_core: OSI core private data structure. + * + * @note MAC interrupts need to be enabled + */ +static void eqos_handle_mac_link_intrs(struct osi_core_priv_data *osi_core) +{ + nveu32_t mac_pcs = 0; + nve32_t ret = 0; + + 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) { + /* check for Link mode (full/half duplex) */ + if ((mac_pcs & EQOS_MAC_PCS_LNKMOD) == EQOS_MAC_PCS_LNKMOD) { + ret = hw_set_mode(osi_core, OSI_FULL_DUPLEX); + if (osi_unlikely(ret < 0)) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "set mode in full duplex failed\n", 0ULL); + } + } else { + ret = hw_set_mode(osi_core, OSI_HALF_DUPLEX); + if (osi_unlikely(ret < 0)) { + OSI_CORE_ERR(osi_core->osd, 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 */ + /* hw_set_speed is treated as void since it is + * an internal functin which will be always success + */ + if ((mac_pcs & EQOS_MAC_PCS_LNKSPEED) == EQOS_MAC_PCS_LNKSPEED_10) { + (void)hw_set_speed(osi_core, OSI_SPEED_10); + } else if ((mac_pcs & EQOS_MAC_PCS_LNKSPEED) == EQOS_MAC_PCS_LNKSPEED_100) { + (void)hw_set_speed(osi_core, OSI_SPEED_100); + } else if ((mac_pcs & EQOS_MAC_PCS_LNKSPEED) == EQOS_MAC_PCS_LNKSPEED_1000) { + (void)hw_set_speed(osi_core, OSI_SPEED_1000); + } else { + /* Nothing here */ + } + } +} + /** * @brief eqos_handle_mac_intrs - Handle MAC interrupts * @@ -1455,96 +1507,48 @@ 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); + mac_isr = osi_readla(osi_core, (nveu8_t *)osi_core->base + EQOS_MAC_ISR); /* Handle MAC interrupts */ - if ((dma_isr & EQOS_DMA_ISR_MACIS) != EQOS_DMA_ISR_MACIS) { - return; - } - + if ((dma_isr & EQOS_DMA_ISR_MACIS) == EQOS_DMA_ISR_MACIS) { #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; + 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; } - osi_core->hsi.err_code[TX_FRAME_ERR_IDX] = - OSI_TX_FRAME_ERR; - osi_core->hsi.report_err = OSI_ENABLE; } - } #endif + /* 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); - /* 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_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 = hw_set_mode(osi_core, OSI_FULL_DUPLEX); - if (osi_unlikely(ret < 0)) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "set mode in full duplex failed\n", 0ULL); + 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); } - } else { - ret = hw_set_mode(osi_core, OSI_HALF_DUPLEX); - if (osi_unlikely(ret < 0)) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "set mode in half duplex failed\n", 0ULL); + + if ((mac_isr & EQOS_MAC_ISR_RGSMIIS) == EQOS_MAC_ISR_RGSMIIS) { + eqos_handle_mac_link_intrs(osi_core); } } - /* set speed at MAC level */ - /* TODO: set_tx_clk needs to be done */ - /* Maybe through workqueue for QNX */ - /* hw_set_speed is treated as void since it is - * an internal functin which will be always success - */ - if ((mac_pcs & EQOS_MAC_PCS_LNKSPEED) == EQOS_MAC_PCS_LNKSPEED_10) { - (void)hw_set_speed(osi_core, OSI_SPEED_10); - } else if ((mac_pcs & EQOS_MAC_PCS_LNKSPEED) == - EQOS_MAC_PCS_LNKSPEED_100) { - (void)hw_set_speed(osi_core, OSI_SPEED_100); - } else if ((mac_pcs & EQOS_MAC_PCS_LNKSPEED) == - EQOS_MAC_PCS_LNKSPEED_1000) { - (void)hw_set_speed(osi_core, OSI_SPEED_1000); - } else { - /* Nothing here */ - } - + return; } #ifndef OSI_STRIPPED_LIB @@ -1869,69 +1873,63 @@ static void eqos_handle_common_intr(struct osi_core_priv_data *const osi_core) } dma_isr = osi_readla(osi_core, (nveu8_t *)base + EQOS_DMA_ISR); - if (dma_isr == 0U) { - return; - } + if (dma_isr != 0U) { + //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; + } - //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)); - /* read dma channel status register */ - dma_sr = osi_readla(osi_core, (nveu8_t *)base + + /* 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)); - /* 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)); #ifndef OSI_STRIPPED_LIB - update_dma_sr_stats(osi_core, dma_sr, qinx); + update_dma_sr_stats(osi_core, dma_sr, qinx); #endif /* !OSI_STRIPPED_LIB */ + } } + + eqos_handle_mac_intrs(osi_core, dma_isr); + + /* Handle MTL inerrupts */ + mtl_isr = osi_readla(osi_core, (nveu8_t *)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, (nveu8_t *)base + EQOS_MTL_INTR_STATUS); + } + + /* Clear FRP Interrupt MTL_RXP_Interrupt_Control_Status */ + frp_isr = osi_readla(osi_core, (nveu8_t *)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, (nveu8_t *)base + EQOS_MTL_RXP_INTR_CS); + } else { + /* Do Nothing */ } - - eqos_handle_mac_intrs(osi_core, dma_isr); - - /* Handle MTL inerrupts */ - mtl_isr = osi_readla(osi_core, - (nveu8_t *)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, (nveu8_t *)base + - EQOS_MTL_INTR_STATUS); - } - - /* Clear FRP Interrupt MTL_RXP_Interrupt_Control_Status */ - frp_isr = osi_readla(osi_core, - (nveu8_t *)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, - (nveu8_t *)base + EQOS_MTL_RXP_INTR_CS); } #if defined(MACSEC_SUPPORT) && !defined(OSI_STRIPPED_LIB) @@ -2016,6 +2014,7 @@ static inline nve32_t eqos_update_mac_addr_helper( OSI_UNUSED const nveu32_t src_dest) { nveu32_t temp; + nve32_t ret = 0; /* PDC bit of MAC_Ext_Configuration register is set so binary * value representation form index 32-127 else hot-bit @@ -2047,11 +2046,11 @@ static inline nve32_t eqos_update_mac_addr_helper( OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "invalid address index for MBC\n", 0ULL); - return -1; + ret = -1; } } - return 0; + return ret; } /** @@ -2098,28 +2097,28 @@ static void eqos_l2_filter_delete(struct osi_core_priv_data *osi_core, *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))); + 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; @@ -2174,7 +2173,8 @@ static nve32_t eqos_update_mac_addr_low_high_reg( OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "invalid MAC filter index or channel number\n", 0ULL); - return -1; + ret = -1; + goto fail; } /* read current value at index preserve DCS current value */ @@ -2185,39 +2185,36 @@ static nve32_t eqos_update_mac_addr_low_high_reg( 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; + } else { + 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) { + goto fail; + } + + /* 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))); } - - 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))); - +fail: return ret; } @@ -2425,6 +2422,7 @@ static inline nve32_t eqos_poll_for_update_ts_complete( nveu32_t retry = RETRY_COUNT; nveu32_t count; nve32_t cond = COND_NOT_MET; + nve32_t ret = 0; /* Wait for previous(if any) time stamp value update to complete */ count = 0; @@ -2432,7 +2430,8 @@ static inline nve32_t eqos_poll_for_update_ts_complete( if (count > retry) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "poll_for_update_ts: timeout\n", 0ULL); - return -1; + ret = -1; + goto fail; } /* Read and Check TSUPDT in MAC_Timestamp_Control register */ *mac_tcr = osi_readla(osi_core, (nveu8_t *)osi_core->base + @@ -2444,8 +2443,8 @@ static inline nve32_t eqos_poll_for_update_ts_complete( count++; osi_core->osd_ops.udelay(OSI_DELAY_1000US); } - - return 0; +fail: + return ret; } @@ -2490,11 +2489,11 @@ static nve32_t eqos_adjust_mactime(struct osi_core_priv_data *const osi_core, nveul64_t temp = 0; nveu32_t sec1 = sec; nveu32_t nsec1 = nsec; - nve32_t ret; + nve32_t ret = 0; ret = eqos_poll_for_update_ts_complete(osi_core, &mac_tcr); if (ret == -1) { - return -1; + goto fail; } if (add_sub != 0U) { @@ -2543,11 +2542,9 @@ static nve32_t eqos_adjust_mactime(struct osi_core_priv_data *const osi_core, osi_writela(osi_core, mac_tcr, (nveu8_t *)addr + EQOS_MAC_TCR); ret = eqos_poll_for_update_ts_complete(osi_core, &mac_tcr); - if (ret == -1) { - return -1; - } - return 0; +fail: + return ret; } #ifndef OSI_STRIPPED_LIB @@ -2664,13 +2661,15 @@ static inline nve32_t poll_for_mii_idle(struct osi_core_priv_data *osi_core) nveu32_t mac_gmiiar; nveu32_t count; nve32_t cond = COND_NOT_MET; + nve32_t ret = 0; 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; + ret = -1; + goto fail; } count++; @@ -2684,8 +2683,8 @@ static inline nve32_t poll_for_mii_idle(struct osi_core_priv_data *osi_core) osi_core->osd_ops.udelay(10U); } } - - return 0; +fail: + return ret; } /** \endcond */ @@ -2735,7 +2734,7 @@ static nve32_t eqos_write_phy_reg(struct osi_core_priv_data *const osi_core, ret = poll_for_mii_idle(osi_core); if (ret < 0) { /* poll_for_mii_idle fail */ - return ret; + goto fail; } /* C45 register access */ @@ -2788,7 +2787,9 @@ static nve32_t eqos_write_phy_reg(struct osi_core_priv_data *const osi_core, 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); + ret = poll_for_mii_idle(osi_core); +fail: + return ret; } /** @@ -2836,7 +2837,7 @@ static nve32_t eqos_read_phy_reg(struct osi_core_priv_data *const osi_core, ret = poll_for_mii_idle(osi_core); if (ret < 0) { /* poll_for_mii_idle fail */ - return ret; + goto fail; } /* C45 register access */ if ((phyreg & OSI_MII_ADDR_C45) == OSI_MII_ADDR_C45) { @@ -2883,14 +2884,16 @@ static nve32_t eqos_read_phy_reg(struct osi_core_priv_data *const osi_core, ret = poll_for_mii_idle(osi_core); if (ret < 0) { /* poll_for_mii_idle fail */ - return ret; + goto fail; } 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; + ret = (nve32_t)data; +fail: + return ret; } /** diff --git a/osi/core/eqos_mmc.c b/osi/core/eqos_mmc.c index e0de057..670d702 100644 --- a/osi/core/eqos_mmc.c +++ b/osi/core/eqos_mmc.c @@ -54,7 +54,7 @@ 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; + nveu64_t temp = 0; nveu32_t value = osi_readla(osi_core, (nveu8_t *)osi_core->base + offset); @@ -65,11 +65,9 @@ static inline nveu64_t update_mmc_val(struct osi_core_priv_data *const osi_core, "Value overflow resetting all counters\n", (nveul64_t)offset); eqos_reset_mmc(osi_core); - } else { - return temp; } - return 0; + return temp; } /** diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index da9c5a7..5d77efe 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -328,11 +328,10 @@ static nve32_t ivc_get_sc_lut_key_index(struct osi_core_priv_data *const osi_cor msg.data.macsec_cfg.ctlr = ctlr; ret = osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); - if (ret != 0) { - return ret; + if (ret == 0) { + *key_index = msg.data.macsec_cfg.key_index; } - *key_index = msg.data.macsec_cfg.key_index; return ret; } diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 2a550c3..59b8c69 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -50,6 +50,7 @@ static nve32_t mgbe_poll_for_mac_acrtl(struct osi_core_priv_data *osi_core) { nveu32_t count = 0U; nveu32_t mac_indir_addr_ctrl = 0U; + nve32_t ret = -1; /* Poll Until MAC_Indir_Access_Ctrl OB is clear */ while (count < MGBE_MAC_INDIR_AC_OB_RETRY) { @@ -58,7 +59,8 @@ static nve32_t mgbe_poll_for_mac_acrtl(struct osi_core_priv_data *osi_core) MGBE_MAC_INDIR_AC); if ((mac_indir_addr_ctrl & MGBE_MAC_INDIR_AC_OB) == OSI_NONE) { /* OB is clear exit the loop */ - return 0; + ret = 0; + break; } /* wait for 10 usec for OB clear and retry */ @@ -66,7 +68,7 @@ static nve32_t mgbe_poll_for_mac_acrtl(struct osi_core_priv_data *osi_core) count++; } - return -1; + return ret; } /** @@ -91,6 +93,7 @@ static nve32_t mgbe_mac_indir_addr_write(struct osi_core_priv_data *osi_core, { void *base = osi_core->base; nveu32_t addr = 0; + nve32_t ret = 0; /* Write MAC_Indir_Access_Data register value */ osi_writela(osi_core, value, (nveu8_t *)base + MGBE_MAC_INDIR_DATA); @@ -121,10 +124,10 @@ static nve32_t mgbe_mac_indir_addr_write(struct osi_core_priv_data *osi_core, if (mgbe_poll_for_mac_acrtl(osi_core) < 0) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Fail to write MAC_Indir_Access_Ctrl\n", mc_no); - return -1; + ret = -1; } - return 0; + return ret; } /** @@ -149,6 +152,7 @@ static nve32_t mgbe_mac_indir_addr_read(struct osi_core_priv_data *osi_core, { void *base = osi_core->base; nveu32_t addr = 0; + nve32_t ret = 0; /* Program MAC_Indir_Access_Ctrl */ addr = osi_readla(osi_core, (nveu8_t *)base + MGBE_MAC_INDIR_AC); @@ -176,12 +180,14 @@ static nve32_t mgbe_mac_indir_addr_read(struct osi_core_priv_data *osi_core, if (mgbe_poll_for_mac_acrtl(osi_core) < 0) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Fail to write MAC_Indir_Access_Ctrl\n", mc_no); - return -1; + ret = -1; + goto fail; } /* Read MAC_Indir_Access_Data register value */ *value = osi_readla(osi_core, (nveu8_t *)base + MGBE_MAC_INDIR_DATA); - return 0; +fail: + return ret; } /** @@ -208,13 +214,15 @@ static nve32_t mgbe_filter_args_validate(struct osi_core_priv_data *const osi_co nveu32_t addr_mask = filter->addr_mask; nveu32_t src_dest = filter->src_dest; nveu32_t dma_chansel = filter->dma_chansel; + nve32_t ret = 0; /* 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; + ret = -1; + goto fail; } /* check for DMA channel index (0 to 9) */ @@ -223,7 +231,8 @@ static nve32_t mgbe_filter_args_validate(struct osi_core_priv_data *const osi_co OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, "invalid dma channel\n", (nveul64_t)dma_chan); - return -1; + ret = -1; + goto fail; } /* validate dma_chansel argument */ @@ -231,7 +240,8 @@ static nve32_t mgbe_filter_args_validate(struct osi_core_priv_data *const osi_co OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, "invalid dma_chansel value\n", dma_chansel); - return -1; + ret = -1; + goto fail; } /* validate addr_mask argument */ @@ -239,7 +249,8 @@ static nve32_t mgbe_filter_args_validate(struct osi_core_priv_data *const osi_co OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid addr_mask value\n", addr_mask); - return -1; + ret = -1; + goto fail; } /* validate src_dest argument */ @@ -247,7 +258,8 @@ static nve32_t mgbe_filter_args_validate(struct osi_core_priv_data *const osi_co OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid src_dest value\n", src_dest); - return -1; + ret = -1; + goto fail; } /* validate dma_routing_enable argument */ @@ -256,10 +268,10 @@ static nve32_t mgbe_filter_args_validate(struct osi_core_priv_data *const osi_co OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid dma_routing value\n", dma_routing_enable); - return -1; + ret = -1; } - - return 0; +fail: + return ret; } /** @@ -297,7 +309,8 @@ static nve32_t mgbe_update_mac_addr_low_high_reg( /* Validate filter values */ if (mgbe_filter_args_validate(osi_core, filter) < 0) { /* Filter argments validation got failed */ - return -1; + ret = -1; + goto fail; } value = osi_readla(osi_core, (nveu8_t *)osi_core->base + @@ -311,7 +324,7 @@ static nve32_t mgbe_update_mac_addr_low_high_reg( if (ret < 0) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "indirect register read failed\n", 0ULL); - return -1; + goto fail; } /* preserve last XDCS bits */ @@ -334,45 +347,37 @@ static nve32_t mgbe_update_mac_addr_low_high_reg( MGBE_MAC_ADDRH((idx))); osi_writela(osi_core, OSI_MAX_32BITS, (nveu8_t *)osi_core->base + MGBE_MAC_ADDRL((idx))); + } else { + /* Add DMA channel to value in binary */ + value = OSI_NONE; + value |= ((dma_chan << MGBE_MAC_ADDRH_DCS_SHIFT) & MGBE_MAC_ADDRH_DCS); - return ret; + 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, + ((nveu32_t)addr[4] | ((nveu32_t)addr[5] << 8) | + MGBE_MAC_ADDRH_AE | value), + (nveu8_t *)osi_core->base + MGBE_MAC_ADDRH((idx))); + + osi_writela(osi_core, + ((nveu32_t)addr[0] | ((nveu32_t)addr[1] << 8) | + ((nveu32_t)addr[2] << 16) | ((nveu32_t)addr[3] << 24)), + (nveu8_t *)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); } - - /* 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, ((nveu32_t)addr[4] | - ((nveu32_t)addr[5] << 8) | - MGBE_MAC_ADDRH_AE | - value), - (nveu8_t *)osi_core->base + MGBE_MAC_ADDRH((idx))); - - osi_writela(osi_core, ((nveu32_t)addr[0] | - ((nveu32_t)addr[1] << 8) | - ((nveu32_t)addr[2] << 16) | - ((nveu32_t)addr[3] << 24)), - (nveu8_t *)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); - +fail: return ret; } @@ -395,13 +400,15 @@ static nve32_t mgbe_poll_for_l3l4crtl(struct osi_core_priv_data *osi_core) nveu32_t count; nveu32_t l3l4_addr_ctrl = 0; nve32_t cond = 1; + nve32_t ret = 0; /* Poll Until L3_L4_Address_Control XB is clear */ count = 0; while (cond == 1) { if (count > retry) { /* Return error after max retries */ - return -1; + ret = -1; + goto fail; } count++; @@ -417,8 +424,8 @@ static nve32_t mgbe_poll_for_l3l4crtl(struct osi_core_priv_data *osi_core) osi_core->osd_ops.udelay(MGBE_MAC_XB_WAIT); } } - - return 0; +fail: + return ret; } /** @@ -443,6 +450,7 @@ static nve32_t mgbe_l3l4_filter_write(struct osi_core_priv_data *osi_core, { void *base = osi_core->base; nveu32_t addr = 0; + nve32_t ret = 0; /* Write MAC_L3_L4_Data register value */ osi_writela(osi_core, value, @@ -477,10 +485,10 @@ static nve32_t mgbe_l3l4_filter_write(struct osi_core_priv_data *osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Fail to write L3_L4_Address_Control\n", filter_type); - return -1; + ret = -1; } - return 0; + return ret; } /** @@ -1231,7 +1239,7 @@ static nve32_t mgbe_configure_mtl_queue(struct osi_core_priv_data *osi_core, */ ret = hw_flush_mtl_tx_queue(osi_core, qinx); if (ret < 0) { - return ret; + goto fail; } if (osi_unlikely((qinx >= OSI_MGBE_MAX_NUM_QUEUES) || @@ -1239,7 +1247,7 @@ static nve32_t mgbe_configure_mtl_queue(struct osi_core_priv_data *osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Incorrect queues/TC number\n", 0ULL); ret = -1; - goto end; + goto fail; } value = (tx_fifo_sz[qinx] << MGBE_MTL_TXQ_SIZE_SHIFT); @@ -1299,7 +1307,7 @@ static nve32_t mgbe_configure_mtl_queue(struct osi_core_priv_data *osi_core, (MGBE_MAC_RXQC0_RXQEN_SHIFT(qinx))); osi_writela(osi_core, value, (nveu8_t *)osi_core->base + MGBE_MAC_RQC0R); -end: +fail: return ret; } @@ -2044,7 +2052,7 @@ static nve32_t mgbe_core_init(struct osi_core_priv_data *const osi_core) for (qinx = 0; qinx < osi_core->num_mtl_queues; qinx++) { ret = mgbe_configure_mtl_queue(osi_core, osi_core->mtl_queues[qinx]); if (ret < 0) { - return ret; + goto fail; } /* Enable by default to configure forward error packets. * Since this is a local function this will always return sucess, @@ -2052,14 +2060,14 @@ static nve32_t mgbe_core_init(struct osi_core_priv_data *const osi_core) */ ret = hw_config_fw_err_pkts(osi_core, osi_core->mtl_queues[qinx], OSI_ENABLE); if (ret < 0) { - return ret; + goto fail; } } /* configure MGBE MAC HW */ ret = mgbe_configure_mac(osi_core); if (ret < 0) { - return ret; + goto fail; } /* configure MGBE DMA */ @@ -2071,7 +2079,9 @@ static nve32_t mgbe_core_init(struct osi_core_priv_data *const osi_core) osi_core->hw_feature->fpe_sel); } - return mgbe_dma_chan_to_vmirq_map(osi_core); + ret = mgbe_dma_chan_to_vmirq_map(osi_core); +fail: + return ret; } /** @@ -2161,8 +2171,7 @@ static inline nveu32_t get_free_ts_idx(struct core_local *l_core) * * @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) +static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core) { struct core_local *l_core = (struct core_local *)(void *)osi_core; nveu32_t mac_isr = 0; @@ -2171,12 +2180,7 @@ static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core, nveu32_t tx_errors = 0; #endif /* !OSI_STRIPPED_LIB */ - mac_isr = osi_readla(osi_core, - (nveu8_t *)osi_core->base + MGBE_MAC_ISR); - /* Handle MAC interrupts */ - if ((dma_isr & MGBE_DMA_ISR_MACIS) != MGBE_DMA_ISR_MACIS) { - return; - } + mac_isr = osi_readla(osi_core, (nveu8_t *)osi_core->base + MGBE_MAC_ISR); /* Check for Link status change interrupt */ if ((mac_isr & MGBE_MAC_ISR_LSI) == OSI_ENABLE) { @@ -2190,8 +2194,7 @@ static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core, } } - mac_ier = osi_readla(osi_core, - (nveu8_t *)osi_core->base + MGBE_MAC_IER); + mac_ier = osi_readla(osi_core, (nveu8_t *)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); @@ -2203,28 +2206,27 @@ static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core, /* Check for the type of Tx error by reading MAC_Rx_Tx_Status * register */ - tx_errors = osi_readl((nveu8_t *)osi_core->base + - MGBE_MAC_RX_TX_STS); + tx_errors = osi_readl((nveu8_t *)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->stats.mgbe_jabber_timeout_err = osi_update_stats_counter( - osi_core->stats.mgbe_jabber_timeout_err, - 1UL); + osi_core->stats.mgbe_jabber_timeout_err, + 1UL); } if ((tx_errors & MGBE_MAC_TX_IHE) == MGBE_MAC_TX_IHE) { /* IP Header Error */ osi_core->stats.mgbe_ip_header_err = osi_update_stats_counter( - osi_core->stats.mgbe_ip_header_err, - 1UL); + osi_core->stats.mgbe_ip_header_err, + 1UL); } if ((tx_errors & MGBE_MAC_TX_PCE) == MGBE_MAC_TX_PCE) { /* Payload Checksum error */ osi_core->stats.mgbe_payload_cs_err = osi_update_stats_counter( - osi_core->stats.mgbe_payload_cs_err, - 1UL); + osi_core->stats.mgbe_payload_cs_err, + 1UL); } } #endif /* !OSI_STRIPPED_LIB */ @@ -2237,23 +2239,24 @@ static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core, (void)__sync_fetch_and_sub(&l_core->ts_lock, 1); #ifndef OSI_STRIPPED_LIB osi_core->stats.ts_lock_add_fail = - osi_update_stats_counter( - osi_core->stats.ts_lock_add_fail, 1U); + osi_update_stats_counter(osi_core->stats.ts_lock_add_fail, 1U); #endif /* !OSI_STRIPPED_LIB */ 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)) { + 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 */ + /* 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); + "Removing TS from queue pkt_id\n", + temp->pkt_id); temp->in_use = OSI_DISABLE; /* remove temp node from the link */ @@ -2262,22 +2265,22 @@ static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core, 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); + "TS queue is full\n", i); break; } } l_core->ts[i].nsec = osi_readla(osi_core, - (nveu8_t *)osi_core->base + - MGBE_MAC_TSNSSEC); + (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); + (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); + (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]; @@ -2289,7 +2292,6 @@ static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core, (void)__sync_fetch_and_sub(&l_core->ts_lock, 1); } done: - /* TODO: Duplex/speed settigs - Its not same as EQOS for MGBE */ return; } @@ -2527,7 +2529,7 @@ static nve32_t mgbe_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; + nve32_t ret = 0; nveu32_t qinx = 0U; nveu32_t tcinx = 0U; @@ -2535,14 +2537,16 @@ static nve32_t mgbe_get_avb_algorithm(struct osi_core_priv_data *const osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "avb structure is NULL\n", 0ULL); - return ret; + ret = -1; + goto fail; } if (avb->qindex >= OSI_MGBE_MAX_NUM_QUEUES) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid Queue index\n", (nveul64_t)avb->qindex); - return ret; + ret = -1; + goto fail; } qinx = avb->qindex; @@ -2589,8 +2593,8 @@ static nve32_t mgbe_get_avb_algorithm(struct osi_core_priv_data *const osi_core, MGBE_MTL_TCQ_ETS_LCR(tcinx)); avb->low_credit = value & MGBE_MTL_TCQ_ETS_LCR_LC_MASK; } - - return 0; +fail: + return ret; } /** @@ -3058,7 +3062,10 @@ static void mgbe_handle_common_intr(struct osi_core_priv_data *const osi_core) } } - mgbe_handle_mac_intrs(osi_core, dma_isr); + /* Handle MAC interrupts */ + if ((dma_isr & MGBE_DMA_ISR_MACIS) == MGBE_DMA_ISR_MACIS) { + mgbe_handle_mac_intrs(osi_core); + } /* Handle MTL inerrupts */ mtl_isr = osi_readla(osi_core, @@ -3149,11 +3156,13 @@ static nve32_t mgbe_mdio_busy_wait(struct osi_core_priv_data *const osi_core) nveu32_t mac_gmiiar; nveu32_t count; nve32_t cond = 1; + nve32_t ret = 0; count = 0; while (cond == 1) { if (count > retry) { - return -1; + ret = -1; + goto fail; } count++; @@ -3166,8 +3175,8 @@ static nve32_t mgbe_mdio_busy_wait(struct osi_core_priv_data *const osi_core) osi_core->osd_ops.udelay(10U); } } - - return 0; +fail: + return ret; } /** @@ -3200,7 +3209,7 @@ static nve32_t mgbe_write_phy_reg(struct osi_core_priv_data *const osi_core, OSI_LOG_ARG_HW_FAIL, "MII operation timed out\n", 0ULL); - return ret; + goto fail; } /* set MDIO address register */ @@ -3237,10 +3246,9 @@ static nve32_t mgbe_write_phy_reg(struct osi_core_priv_data *const osi_core, OSI_LOG_ARG_HW_FAIL, "MII operation timed out\n", 0ULL); - return ret; } - - return 0; +fail: + return ret; } /** @@ -3271,7 +3279,7 @@ static nve32_t mgbe_read_phy_reg(struct osi_core_priv_data *const osi_core, OSI_LOG_ARG_HW_FAIL, "MII operation timed out\n", 0ULL); - return ret; + goto fail; } /* set MDIO address register */ @@ -3306,14 +3314,16 @@ static nve32_t mgbe_read_phy_reg(struct osi_core_priv_data *const osi_core, OSI_LOG_ARG_HW_FAIL, "MII operation timed out\n", 0ULL); - return ret; + goto fail; } reg = osi_readla(osi_core, (nveu8_t *) osi_core->base + MGBE_MDIO_SCCD); data = (reg & MGBE_MDIO_SCCD_SDATA_MASK); - return (nve32_t)data; + ret = (nve32_t)data; +fail: + return ret; } #ifndef OSI_STRIPPED_LIB @@ -3629,20 +3639,22 @@ static inline nve32_t mgbe_poll_for_update_ts_complete( nveu32_t *mac_tcr) { nveu32_t retry = 0U; + nve32_t ret = -1; while (retry < OSI_POLL_COUNT) { /* Read and Check TSUPDT in MAC_Timestamp_Control register */ *mac_tcr = osi_readla(osi_core, (nveu8_t *) osi_core->base + MGBE_MAC_TCR); if ((*mac_tcr & MGBE_MAC_TCR_TSUPDT) == 0U) { - return 0; + ret = 0; + break; } retry++; osi_core->osd_ops.udelay(OSI_DELAY_1000US); } - return -1; + return ret; } /** @@ -3674,14 +3686,14 @@ static nve32_t mgbe_adjust_mactime(struct osi_core_priv_data *const osi_core, nveul64_t temp = 0; nveu32_t temp_sec; nveu32_t temp_nsec; - nve32_t ret; + nve32_t ret = 0; temp_sec = sec; temp_nsec = nsec; /* 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; + goto fail; } if (add_sub != 0U) { @@ -3730,11 +3742,8 @@ static nve32_t mgbe_adjust_mactime(struct osi_core_priv_data *const osi_core, osi_writela(osi_core, mac_tcr, (nveu8_t *)addr + MGBE_MAC_TCR); ret = mgbe_poll_for_update_ts_complete(osi_core, &mac_tcr); - if (ret == -1) { - return -1; - } - - return 0; +fail: + return ret; } /** diff --git a/osi/core/mgbe_mmc.c b/osi/core/mgbe_mmc.c index 3a522f2..57e65bb 100644 --- a/osi/core/mgbe_mmc.c +++ b/osi/core/mgbe_mmc.c @@ -47,7 +47,7 @@ static inline nveu64_t mgbe_update_mmc_val(struct osi_core_priv_data *osi_core, nveu64_t last_value, nveu64_t offset) { - nveu64_t temp; + nveu64_t temp = 0; nveu32_t value = osi_readl((nveu8_t *)osi_core->base + offset); @@ -58,11 +58,9 @@ static inline nveu64_t mgbe_update_mmc_val(struct osi_core_priv_data *osi_core, "Value overflow resetting all counters\n", (nveul64_t)offset); mgbe_reset_mmc(osi_core); - } else { - return temp; } - return 0ULL; + return temp; } /** diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index c04339f..dbc3036 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -46,6 +46,7 @@ static nve32_t validate_if_func_ptrs(struct osi_core_priv_data *const osi_core, { nveu32_t i = 0; void *temp_ops = (void *)if_ops_p; + nve32_t ret = 0; #if __SIZEOF_POINTER__ == 8 nveu64_t *l_ops = (nveu64_t *)temp_ops; #elif __SIZEOF_POINTER__ == 4 @@ -53,7 +54,8 @@ static nve32_t validate_if_func_ptrs(struct osi_core_priv_data *const osi_core, #else OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Undefined architecture\n", 0ULL); - return -1; + ret = -1; + goto fail; #endif for (i = 0; i < (sizeof(*if_ops_p) / (nveu64_t)__SIZEOF_POINTER__); @@ -61,13 +63,14 @@ static nve32_t validate_if_func_ptrs(struct osi_core_priv_data *const osi_core, if (*l_ops == 0U) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "failed at index : ", i); - return -1; + ret = -1; + goto fail; } l_ops++; } - - return 0; +fail: + return ret; } /** @@ -87,17 +90,20 @@ static nve32_t validate_if_func_ptrs(struct osi_core_priv_data *const osi_core, static inline nve32_t validate_if_args(struct osi_core_priv_data *const osi_core, struct core_local *l_core) { + nve32_t ret = 0; + if ((osi_core == OSI_NULL) || (l_core->if_init_done == OSI_DISABLE) || (l_core->magic_num != (nveu64_t)osi_core)) { - return -1; + ret = -1; } - return 0; + return ret; } struct osi_core_priv_data *osi_get_core(void) { nveu32_t i; + struct osi_core_priv_data *osi_core = OSI_NULL; for (i = 0U; i < MAX_CORE_INSTANCES; i++) { if (g_core[i].if_init_done == OSI_ENABLE) { @@ -108,7 +114,7 @@ struct osi_core_priv_data *osi_get_core(void) } if (i == MAX_CORE_INSTANCES) { - return OSI_NULL; + goto fail; } g_core[i].magic_num = (nveu64_t)&g_core[i].osi_core; @@ -117,7 +123,9 @@ struct osi_core_priv_data *osi_get_core(void) 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; + osi_core = &g_core[i].osi_core; +fail: + return osi_core; } struct osi_core_priv_data *get_role_pointer(nveu32_t role) @@ -135,6 +143,7 @@ struct osi_core_priv_data *get_role_pointer(nveu32_t role) if ((g_core[i].if_init_done == OSI_ENABLE) && (g_core[i].ether_m2m_role == role)) { ret_ptr = &g_core[i].osi_core; + break; } } @@ -146,19 +155,22 @@ nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core) { struct core_local *l_core = (struct core_local *)(void *)osi_core; static struct if_core_ops if_ops[MAX_INTERFACE_OPS]; - nve32_t ret = -1; + nve32_t ret = 0; if (osi_core == OSI_NULL) { - return -1; + ret = -1; + goto fail; } if (osi_core->use_virtualization > OSI_ENABLE) { - return ret; + ret = -1; + goto fail; } if ((l_core->magic_num != (nveu64_t)osi_core) || (l_core->if_init_done == OSI_ENABLE)) { - return -1; + ret = -1; + goto fail; } l_core->if_ops_p = &if_ops[osi_core->use_virtualization]; @@ -172,14 +184,15 @@ nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core) if (validate_if_func_ptrs(osi_core, l_core->if_ops_p) < 0) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Interface function validation failed\n", 0ULL); - return -1; + ret = -1; + goto fail; } ret = l_core->if_ops_p->if_init_core_ops(osi_core); if (ret < 0) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "if_init_core_ops failed\n", 0ULL); - return ret; + goto fail; } l_core->ts_lock = OSI_DISABLE; l_core->ether_m2m_role = osi_core->m2m_role; @@ -207,7 +220,7 @@ nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core) "invalid pps_frq\n", (nveu64_t)osi_core->pps_frq); ret = -1; } - +fail: return ret; } @@ -215,48 +228,60 @@ 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) { + nve32_t ret = -1; struct core_local *l_core = (struct core_local *)(void *)osi_core; if (validate_if_args(osi_core, l_core) < 0) { - return -1; + goto fail; } - return l_core->if_ops_p->if_write_phy_reg(osi_core, phyaddr, phyreg, - phydata); + ret = l_core->if_ops_p->if_write_phy_reg(osi_core, phyaddr, phyreg, + phydata); +fail: + return ret; } nve32_t osi_read_phy_reg(struct osi_core_priv_data *const osi_core, const nveu32_t phyaddr, const nveu32_t phyreg) { + nve32_t ret = -1; struct core_local *l_core = (struct core_local *)(void *)osi_core; if (validate_if_args(osi_core, l_core) < 0) { - return -1; + goto fail; } - return l_core->if_ops_p->if_read_phy_reg(osi_core, phyaddr, phyreg); + ret = l_core->if_ops_p->if_read_phy_reg(osi_core, phyaddr, phyreg); +fail: + return ret; } nve32_t osi_hw_core_init(struct osi_core_priv_data *const osi_core) { + nve32_t ret = -1; struct core_local *l_core = (struct core_local *)(void *)osi_core; if (validate_if_args(osi_core, l_core) < 0) { - return -1; + goto fail; } - return l_core->if_ops_p->if_core_init(osi_core); + ret = l_core->if_ops_p->if_core_init(osi_core); +fail: + return ret; } nve32_t osi_hw_core_deinit(struct osi_core_priv_data *const osi_core) { + nve32_t ret = -1; struct core_local *l_core = (struct core_local *)(void *)osi_core; if (validate_if_args(osi_core, l_core) < 0) { - return -1; + goto fail; } - return l_core->if_ops_p->if_core_deinit(osi_core); + ret = l_core->if_ops_p->if_core_deinit(osi_core); +fail: + return ret; } nve32_t osi_handle_ioctl(struct osi_core_priv_data *osi_core, @@ -266,14 +291,16 @@ nve32_t osi_handle_ioctl(struct osi_core_priv_data *osi_core, nve32_t ret = -1; if (validate_if_args(osi_core, l_core) < 0) { - return ret; + goto fail; } if (data == OSI_NULL) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "CORE: Invalid argument\n", 0ULL); - return ret; + goto fail; } - return l_core->if_ops_p->if_handle_ioctl(osi_core, data); + ret = l_core->if_ops_p->if_handle_ioctl(osi_core, data); +fail: + return ret; } diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index dc506ed..e567b07 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -85,6 +85,7 @@ static nve32_t validate_func_ptrs(struct osi_core_priv_data *const osi_core, struct core_ops *ops_p) { nveu32_t i = 0; + nve32_t ret = 0; void *temp_ops = (void *)ops_p; #if __SIZEOF_POINTER__ == 8 nveu64_t *l_ops = (nveu64_t *)temp_ops; @@ -93,7 +94,8 @@ static nve32_t validate_func_ptrs(struct osi_core_priv_data *const osi_core, #else OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Undefined architecture\n", 0ULL); - return -1; + ret = -1; + goto fail; #endif for (i = 0; i < (sizeof(*ops_p) / (nveu64_t)__SIZEOF_POINTER__); i++) { @@ -101,13 +103,14 @@ static nve32_t validate_func_ptrs(struct osi_core_priv_data *const osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "core: fn ptr validation failed at\n", (nveu64_t)i); - return -1; + ret = -1; + goto fail; } l_ops++; } - - return 0; +fail: + return ret; } /** @@ -211,6 +214,7 @@ static nve32_t osi_hal_read_phy_reg(struct osi_core_priv_data *const osi_core, static nve32_t osi_hal_init_core_ops(struct osi_core_priv_data *const osi_core) { + nve32_t ret = -1; struct core_local *l_core = (struct core_local *)(void *)osi_core; typedef void (*init_core_ops_arr)(struct core_ops *local_ops); static struct core_ops g_ops[MAX_MAC_IP_TYPES]; @@ -220,12 +224,12 @@ static nve32_t osi_hal_init_core_ops(struct osi_core_priv_data *const osi_core) }; if (osi_core == OSI_NULL) { - return -1; + goto exit; } if ((l_core->magic_num != (nveu64_t)osi_core) || (l_core->init_done == OSI_ENABLE)) { - return -1; + goto exit; } if ((osi_core->osd_ops.ops_log == OSI_NULL) || @@ -235,19 +239,19 @@ static nve32_t osi_hal_init_core_ops(struct osi_core_priv_data *const osi_core) (osi_core->osd_ops.printf == OSI_NULL) || #endif /* OSI_DEBUG */ (osi_core->osd_ops.usleep_range == OSI_NULL)) { - return -1; + goto exit; } if (osi_core->mac > OSI_MAC_HW_MGBE) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid MAC HW type\n", 0ULL); - return -1; + goto exit; } if (osi_core->use_virtualization > OSI_ENABLE) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid use_virtualization value\n", 0ULL); - return -1; + goto exit; } if (i_ops[osi_core->mac][osi_core->use_virtualization] != OSI_NULL) { @@ -257,13 +261,15 @@ static nve32_t osi_hal_init_core_ops(struct osi_core_priv_data *const osi_core) if (validate_func_ptrs(osi_core, &g_ops[osi_core->mac]) < 0) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "core: function ptrs validation failed\n", 0ULL); - return -1; + goto exit; } l_core->ops_p = &g_ops[osi_core->mac]; l_core->init_done = OSI_ENABLE; - return 0; + ret = 0; +exit: + return ret; } #ifndef OSI_STRIPPED_LIB @@ -465,7 +471,8 @@ static nve32_t osi_ptp_configuration(struct osi_core_priv_data *const osi_core, } else { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "core: temp2 >= UINT_MAX\n", 0ULL); - return -1; + ret = -1; + goto fail; } /* Program addend value */ @@ -488,7 +495,7 @@ static nve32_t osi_ptp_configuration(struct osi_core_priv_data *const osi_core, #ifndef OSI_STRIPPED_LIB } #endif /* !OSI_STRIPPED_LIB */ - +fail: return ret; } @@ -700,14 +707,14 @@ static 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 *)(void *)osi_core; - nve32_t ret; + nve32_t ret = 0; ret = hw_config_mac_pkt_filter_reg(osi_core, filter); if (ret < 0) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "failed to configure MAC packet filter register\n", 0ULL); - return ret; + goto fail; } if (((filter->oper_mode & OSI_OPER_ADDR_UPDATE) != OSI_NONE) || @@ -719,13 +726,14 @@ static nve32_t osi_l2_filter(struct osi_core_priv_data *const osi_core, OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "DCS requested. Conflicts with DT config\n", 0ULL); - return ret; + goto fail; } ret = l_core->ops_p->update_mac_addr_low_high_reg(osi_core, filter); } +fail: return ret; } @@ -1174,7 +1182,7 @@ static nve32_t osi_adjust_freq(struct osi_core_priv_data *const osi_core, nve32_ } else { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "temp > UINT_MAX\n", 0ULL); - return ret; + goto fail; } if (neg_adj == 0U) { @@ -1183,7 +1191,7 @@ static nve32_t osi_adjust_freq(struct osi_core_priv_data *const osi_core, nve32_ } else { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "addend > UINT_MAX\n", 0ULL); - return ret; + goto fail; } } else { if (addend > diff) { @@ -1196,7 +1204,10 @@ static nve32_t osi_adjust_freq(struct osi_core_priv_data *const osi_core, nve32_ } } - return hw_config_addend(osi_core, addend); + ret = hw_config_addend(osi_core, addend); + +fail: + return ret; } static nve32_t osi_adjust_time(struct osi_core_priv_data *const osi_core, @@ -1225,7 +1236,7 @@ static nve32_t osi_adjust_time(struct osi_core_priv_data *const osi_core, } else { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "quotient > UINT_MAX\n", 0ULL); - return ret; + goto fail; } if (reminder <= UINT_MAX) { @@ -1233,11 +1244,13 @@ static nve32_t osi_adjust_time(struct osi_core_priv_data *const osi_core, } else { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "reminder > UINT_MAX\n", 0ULL); - return ret; + goto fail; } - return l_core->ops_p->adjust_mactime(osi_core, sec, nsec, neg_adj, - osi_core->ptp_config.one_nsec_accuracy); + ret = l_core->ops_p->adjust_mactime(osi_core, sec, nsec, neg_adj, + osi_core->ptp_config.one_nsec_accuracy); +fail: + return ret; } diff --git a/osi/core/xpcs.c b/osi/core/xpcs.c index 2a3b652..e749dc5 100644 --- a/osi/core/xpcs.c +++ b/osi/core/xpcs.c @@ -60,7 +60,8 @@ static inline nve32_t xpcs_poll_for_an_complete(struct osi_core_priv_data *osi_c osi_core->hsi.report_count_err[AUTONEG_ERR_IDX] = OSI_ENABLE; } #endif - return -1; + ret = -1; + goto fail; } count++; @@ -74,7 +75,7 @@ static inline nve32_t xpcs_poll_for_an_complete(struct osi_core_priv_data *osi_c 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; + goto fail; } cond = 0; } @@ -83,11 +84,13 @@ static inline nve32_t xpcs_poll_for_an_complete(struct osi_core_priv_data *osi_c if ((status & XPCS_USXG_AN_STS_SPEED_MASK) == 0U) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "XPCS AN completed with zero speed\n", 0ULL); - return -1; + ret = -1; + goto fail; } *an_status = status; - return 0; +fail: + return ret; } /** @@ -155,8 +158,8 @@ nve32_t xpcs_start(struct osi_core_priv_data *osi_core) if (osi_core->xpcs_base == OSI_NULL) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "XPCS base is NULL", 0ULL); - /* TODO: Remove this once silicon arrives */ - return 0; + ret = -1; + goto fail; } if ((osi_core->phy_iface_mode == OSI_USXGMII_MODE_10G) || @@ -165,16 +168,16 @@ nve32_t xpcs_start(struct osi_core_priv_data *osi_core) ctrl |= XPCS_SR_MII_CTRL_AN_ENABLE; ret = xpcs_write_safety(osi_core, XPCS_SR_MII_CTRL, ctrl); if (ret != 0) { - return ret; + goto fail; } ret = xpcs_poll_for_an_complete(osi_core, &an_status); if (ret < 0) { - return ret; + goto fail; } ret = xpcs_set_speed(osi_core, an_status); if (ret != 0) { - return ret; + goto fail; } /* USXGMII Rate Adaptor Reset before data transfer */ ctrl = xpcs_read(xpcs_base, XPCS_VR_XS_PCS_DIG_CTRL1); @@ -182,7 +185,8 @@ nve32_t xpcs_start(struct osi_core_priv_data *osi_core) xpcs_write(xpcs_base, XPCS_VR_XS_PCS_DIG_CTRL1, ctrl); while (cond == COND_NOT_MET) { if (count > retry) { - return -1; + ret = -1; + goto fail; } count++; @@ -201,7 +205,8 @@ nve32_t xpcs_start(struct osi_core_priv_data *osi_core) count = 0; while (cond == COND_NOT_MET) { if (count > retry) { - return -1; + ret = -1; + break; } count++; @@ -214,8 +219,8 @@ nve32_t xpcs_start(struct osi_core_priv_data *osi_core) osi_core->osd_ops.udelay(1000U); } } - - return 0; +fail: + return ret; } /** @@ -238,39 +243,39 @@ static nve32_t xpcs_uphy_lane_bring_up(struct osi_core_priv_data *osi_core, nve32_t cond = COND_NOT_MET; nveu32_t val = 0; nveu32_t count; + nve32_t ret = 0; val = osi_readla(osi_core, (nveu8_t *)xpcs_base + XPCS_WRAP_UPHY_STATUS); - if ((val & XPCS_WRAP_UPHY_STATUS_TX_P_UP_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(5U); + (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) { + ret = -1; + goto fail; + } + 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(5U); + } } } - return 0; +fail: + return ret; } /** @@ -290,11 +295,13 @@ static nve32_t xpcs_check_pcs_lock_status(struct osi_core_priv_data *osi_core) nve32_t cond = COND_NOT_MET; nveu32_t val = 0; nveu32_t count; + nve32_t ret = 0; count = 0; while (cond == COND_NOT_MET) { if (count > retry) { - return -1; + ret = -1; + goto fail; } count++; @@ -311,8 +318,8 @@ static nve32_t xpcs_check_pcs_lock_status(struct osi_core_priv_data *osi_core) /* Clear the status */ osi_writela(osi_core, val, (nveu8_t *)xpcs_base + XPCS_WRAP_IRQ_STATUS); - - return 0; +fail: + return ret; } /** @@ -333,12 +340,14 @@ static nve32_t xpcs_lane_bring_up(struct osi_core_priv_data *osi_core) nveu32_t count; nveu32_t val = 0; nve32_t cond; + nve32_t ret = 0; if (xpcs_uphy_lane_bring_up(osi_core, XPCS_WRAP_UPHY_HW_INIT_CTRL_TX_EN) < 0) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "UPHY TX lane bring-up failed\n", 0ULL); - return -1; + ret = -1; + goto fail; } val = osi_readla(osi_core, @@ -391,7 +400,8 @@ static nve32_t xpcs_lane_bring_up(struct osi_core_priv_data *osi_core) count = 0; while (cond == COND_NOT_MET) { if (count > retry) { - return -1; + ret = -1; + goto fail; } count++; @@ -440,14 +450,15 @@ static nve32_t xpcs_lane_bring_up(struct osi_core_priv_data *osi_core) "Failed to get PCS block lock\n", 0ULL); l_core->lane_status = OSI_DISABLE; } - return -1; + ret = -1; + goto fail; } else { OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "PCS block lock SUCCESS\n", 0ULL); l_core->lane_status = OSI_ENABLE; } - - return 0; +fail: + return ret; } /** @@ -472,12 +483,13 @@ nve32_t xpcs_init(struct osi_core_priv_data *osi_core) if (osi_core->xpcs_base == OSI_NULL) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "XPCS base is NULL", 0ULL); - /* TODO: Remove this once silicon arrives */ - return 0; + ret = -1; + goto fail; } if (xpcs_lane_bring_up(osi_core) < 0) { - return -1; + ret = -1; + goto fail; } /* Switching to USXGMII Mode based on @@ -489,7 +501,7 @@ nve32_t xpcs_init(struct osi_core_priv_data *osi_core) 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; + goto fail; } /* 2. enable USXGMII Mode inside DWC_xpcs */ @@ -506,7 +518,7 @@ nve32_t xpcs_init(struct osi_core_priv_data *osi_core) ret = xpcs_write_safety(osi_core, XPCS_VR_XS_PCS_KR_CTRL, ctrl); if (ret != 0) { - return ret; + goto fail; } /* 4. Program PHY to operate at 10Gbps/5Gbps/2Gbps * this step not required since PHY speed programming @@ -517,7 +529,7 @@ nve32_t xpcs_init(struct osi_core_priv_data *osi_core) 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; + goto fail; } /* XPCS_VR_XS_PCS_DIG_CTRL1_VR_RST bit is self clearing @@ -533,7 +545,8 @@ nve32_t xpcs_init(struct osi_core_priv_data *osi_core) count = 0; while (cond == 1) { if (count > retry) { - return -1; + ret = -1; + goto fail; } count++; @@ -556,13 +569,13 @@ nve32_t xpcs_init(struct osi_core_priv_data *osi_core) ctrl &= ~XPCS_SR_AN_CTRL_AN_EN; ret = xpcs_write_safety(osi_core, XPCS_SR_AN_CTRL, ctrl); if (ret != 0) { - return ret; + goto fail; } 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; + goto fail; } } @@ -574,10 +587,11 @@ nve32_t xpcs_init(struct osi_core_priv_data *osi_core) /* 11. XPCS configured as MAC-side USGMII - NA */ /* 13. TODO: If there is interrupt enabled for AN interrupt */ - - return 0; +fail: + return ret; } +#ifndef OSI_STRIPPED_LIB /** * @brief xpcs_eee - XPCS enable/disable EEE * @@ -597,11 +611,13 @@ nve32_t xpcs_eee(struct osi_core_priv_data *osi_core, nveu32_t en_dis) nve32_t ret = 0; if ((en_dis != OSI_ENABLE) && (en_dis != OSI_DISABLE)) { - return -1; + ret = -1; + goto fail; } if (xpcs_base == OSI_NULL) { - return -1; + ret = -1; + goto fail; } if (en_dis == OSI_DISABLE) { @@ -609,36 +625,34 @@ nve32_t xpcs_eee(struct osi_core_priv_data *osi_core, nveu32_t en_dis) 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); + } else { + + /* 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; + goto fail; } - return 0; + /* 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); } - - /* 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; +fail: + return ret; } +#endif /* !OSI_STRIPPED_LIB */ diff --git a/osi/core/xpcs.h b/osi/core/xpcs.h index 0246db8..345fc27 100644 --- a/osi/core/xpcs.h +++ b/osi/core/xpcs.h @@ -49,14 +49,20 @@ #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 /** @} */ +#ifndef OSI_STRIPPED_LIB +#define XPCS_VR_XS_PCS_EEE_MCTRL0 0xE0018 +#define XPCS_VR_XS_PCS_EEE_MCTRL1 0xE002C + +#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) +#endif /* !OSI_STRIPPED_LIB */ /** * @addtogroup XPCS-BIT Register bit fileds @@ -70,9 +76,6 @@ #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) @@ -119,7 +122,9 @@ nve32_t xpcs_init(struct osi_core_priv_data *osi_core); nve32_t xpcs_start(struct osi_core_priv_data *osi_core); +#ifndef OSI_STRIPPED_LIB nve32_t xpcs_eee(struct osi_core_priv_data *osi_core, nveu32_t en_dis); +#endif /* !OSI_STRIPPED_LIB */ /** * @brief xpcs_read - read from xpcs. @@ -178,18 +183,23 @@ static inline nve32_t xpcs_write_safety(struct osi_core_priv_data *osi_core, void *xpcs_base = osi_core->xpcs_base; nveu32_t read_val; nve32_t retry = 10; + nve32_t ret = XPCS_WRITE_FAIL_CODE; while (--retry > 0) { xpcs_write(xpcs_base, reg_addr, val); read_val = xpcs_read(xpcs_base, reg_addr); if (val == read_val) { - return 0; + ret = 0; + break; } osi_core->osd_ops.udelay(OSI_DELAY_1US); } - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "xpcs_write_safety failed", reg_addr); - return XPCS_WRITE_FAIL_CODE; + if (ret != 0) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "xpcs_write_safety failed", reg_addr); + } + + return ret; } #endif From b38ca1d2f69ae92cd07a09961eadc79b3fefc34d Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Thu, 8 Dec 2022 10:56:59 +0530 Subject: [PATCH 440/458] osi: hsi: Add return code for HSI Error injection Issue: HSI error injection IOCTL does not return failure on invalid error codes. Fix: Handle invalid HSI error codes for HSI error injection IOCTL. Bug 3806923 Change-Id: I317b15e9a3ac98ab3d8d5c3ab37dd6782760bec3 Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2823800 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/core_common.c | 12 ++++++++++-- osi/core/core_common.h | 4 ++-- osi/core/core_local.h | 4 ++-- osi/core/eqos_core.c | 7 +++++-- osi/core/mgbe_core.c | 9 +++++++-- osi/core/osi_hal.c | 3 +-- 6 files changed, 27 insertions(+), 12 deletions(-) diff --git a/osi/core/core_common.c b/osi/core/core_common.c index 08d906f..e9acd50 100644 --- a/osi/core/core_common.c +++ b/osi/core/core_common.c @@ -1438,10 +1438,15 @@ void hw_tsn_init(struct osi_core_priv_data *osi_core, * @param[in] error_code: Ethernet HSI error code * * @note MAC should be init and started. see osi_start_mac() + * + * @retval 0 on success + * @retval -1 on failure. */ -void hsi_common_error_inject(struct osi_core_priv_data *osi_core, - nveu32_t error_code) +nve32_t hsi_common_error_inject(struct osi_core_priv_data *osi_core, + nveu32_t error_code) { + nve32_t ret = 0; + switch (error_code) { case OSI_INBOUND_BUS_CRC_ERR: osi_core->hsi.inject_crc_err_count = @@ -1491,8 +1496,11 @@ void hsi_common_error_inject(struct osi_core_priv_data *osi_core, default: OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Invalid error code\n", (nveu32_t)error_code); + ret = -1; break; } + + return ret; } #endif diff --git a/osi/core/core_common.h b/osi/core/core_common.h index 5634966..e5544b9 100644 --- a/osi/core/core_common.h +++ b/osi/core/core_common.h @@ -173,7 +173,7 @@ void prepare_l3l4_registers(const struct osi_core_priv_data *const osi_core, nveu32_t *l3_addr1_reg, nveu32_t *ctr_reg); #ifdef HSI_SUPPORT -void hsi_common_error_inject(struct osi_core_priv_data *osi_core, - nveu32_t error_code); +nve32_t hsi_common_error_inject(struct osi_core_priv_data *osi_core, + nveu32_t error_code); #endif #endif /* INCLUDED_CORE_COMMON_H */ diff --git a/osi/core/core_local.h b/osi/core/core_local.h index fac7c8b..685ee9a 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -228,8 +228,8 @@ struct core_ops { nve32_t (*core_hsi_configure)(struct osi_core_priv_data *const osi_core, const nveu32_t enable); /** Interface function called to inject error */ - void (*core_hsi_inject_err)(struct osi_core_priv_data *const osi_core, - const nveu32_t error_code); + nve32_t (*core_hsi_inject_err)(struct osi_core_priv_data *const osi_core, + const nveu32_t error_code); #endif }; diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index b1db023..32c076c 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -957,10 +957,11 @@ static nve32_t eqos_hsi_configure(struct osi_core_priv_data *const osi_core, * @retval -1 on failure */ -static void eqos_hsi_inject_err(struct osi_core_priv_data *const osi_core, +static nve32_t eqos_hsi_inject_err(struct osi_core_priv_data *const osi_core, const nveu32_t error_code) { nveu32_t value; + nve32_t ret = 0; switch (error_code) { case OSI_HSI_EQOS0_CE_CODE: @@ -978,9 +979,11 @@ static void eqos_hsi_inject_err(struct osi_core_priv_data *const osi_core, EQOS_MTL_DBG_CTL); break; default: - hsi_common_error_inject(osi_core, error_code); + ret = hsi_common_error_inject(osi_core, error_code); break; } + + return ret; } #endif diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 59b8c69..a510cb9 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -1687,8 +1687,10 @@ fail: * @param[in] osi_core: OSI core private data structure. * @param[in] error_code: HSI Error code * + * @retval 0 on success + * @retval -1 on failure */ -static void mgbe_hsi_inject_err(struct osi_core_priv_data *const osi_core, +static nve32_t mgbe_hsi_inject_err(struct osi_core_priv_data *const osi_core, const nveu32_t error_code) { const nveu32_t val_ce = (MGBE_MTL_DEBUG_CONTROL_FDBGEN | @@ -1701,6 +1703,7 @@ static void mgbe_hsi_inject_err(struct osi_core_priv_data *const osi_core, MGBE_MTL_DEBUG_CONTROL_DBGMOD | MGBE_MTL_DEBUG_CONTROL_FIFORDEN | MGBE_MTL_DEBUG_CONTROL_EIEE); + nve32_t ret = 0; switch (error_code) { case OSI_HSI_MGBE0_CE_CODE: @@ -1718,9 +1721,11 @@ static void mgbe_hsi_inject_err(struct osi_core_priv_data *const osi_core, MGBE_MTL_DEBUG_CONTROL); break; default: - hsi_common_error_inject(osi_core, error_code); + ret = hsi_common_error_inject(osi_core, error_code); break; } + + return ret; } #endif diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index e567b07..211988a 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -2768,8 +2768,7 @@ static nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, ret = ops_p->core_hsi_configure(osi_core, data->arg1_u32); break; case OSI_CMD_HSI_INJECT_ERR: - ops_p->core_hsi_inject_err(osi_core, data->arg1_u32); - ret = 0; + ret = ops_p->core_hsi_inject_err(osi_core, data->arg1_u32); break; #endif From f0af726970c1caaf063bd9a3c5c963ed2ebd8cf1 Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Wed, 30 Nov 2022 15:55:32 +0530 Subject: [PATCH 441/458] osi: core: Cleanup MAC start and stop ioctls Issue: Observed STOP MAC ioctl failure on standard builds. Fix: -Update ivc_core_deinit to call core_deinit command - As MAC start and stop is part of init/deinit clean up these IOCTLs Bug 3889287 Change-Id: I07ba4dd5dc2e9630a4e4001199c6aae24ade6c70 Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2819152 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_core.h | 6 ------ osi/core/ivc_core.c | 3 +-- osi/core/osi_hal.c | 13 ------------- 3 files changed, 1 insertion(+), 21 deletions(-) diff --git a/include/osi_core.h b/include/osi_core.h index 2bf6fe5..3d2d094 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -78,7 +78,6 @@ typedef my_lint_64 nvel64_t; #define OSI_CMD_PTP_RXQ_ROUTE 35U #define OSI_CMD_CONFIG_RSS 37U #define OSI_CMD_CONFIG_FW_ERR 29U -#define OSI_CMD_START_MAC 5U #define OSI_CMD_SET_MODE 16U #define OSI_CMD_POLL_FOR_MAC_RST 4U #define OSI_CMD_GET_MAC_VER 10U @@ -232,7 +231,6 @@ typedef my_lint_64 nvel64_t; * @{ */ #define OSI_CMD_L3L4_FILTER 3U -#define OSI_CMD_STOP_MAC 6U #define OSI_CMD_COMMON_ISR 7U #define OSI_CMD_PAD_CALIBRATION 8U #define OSI_CMD_READ_MMC 9U @@ -1582,10 +1580,6 @@ nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core); * arg1_u32 - CSR (AXI CBB) clock rate. * - 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 diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index 5d77efe..7b4a2a5 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -123,8 +123,7 @@ static void ivc_core_deinit(struct osi_core_priv_data *const osi_core) osi_memset(&msg, 0, sizeof(msg)); - msg.cmd = handle_ioctl; - msg.data.ioctl_data.cmd = OSI_CMD_STOP_MAC; + msg.cmd = core_deinit; ret = osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); if (ret < 0) { diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 211988a..cc4eace 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -2157,10 +2157,6 @@ static void store_l2_filter(struct osi_core_priv_data *osi_core, * 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 @@ -2413,15 +2409,6 @@ static nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, ret = hw_poll_for_swr(osi_core); break; - case OSI_CMD_START_MAC: - hw_start_mac(osi_core); - ret = 0; - break; - - case OSI_CMD_STOP_MAC: - hw_stop_mac(osi_core); - ret = 0; - break; case OSI_CMD_GET_MAC_VER: ret = osi_get_mac_version(osi_core, &data->arg1_u32); break; From 29242b7c120daaced5b6ee0dab45db963dae3958 Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Mon, 12 Dec 2022 12:54:11 +0530 Subject: [PATCH 442/458] osi: core: Add a BYPASS FRP entry for XDCS Issue: MAC Filters DCH/XDCS is not routing to the proper DMA channel after FRP enable. Fix: As per HW's suggestion add a BYPASS entry after user entries. Bug 3899802 Change-Id: I330490ff94ed719ba3fc27f38b6dfaf1bc37369b Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2826024 Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- osi/core/frp.c | 66 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 19 deletions(-) diff --git a/osi/core/frp.c b/osi/core/frp.c index dab09d1..8ed426d 100644 --- a/osi/core/frp.c +++ b/osi/core/frp.c @@ -370,8 +370,10 @@ done: static nve32_t frp_hw_write(struct osi_core_priv_data *const osi_core, struct core_ops *const ops_p) { - nve32_t ret, tmp; + nve32_t ret = 0; + nve32_t tmp = 0; struct osi_core_frp_entry *entry; + struct osi_core_frp_data bypass_entry = {}; nveu32_t frp_cnt = osi_core->frp_cnt, i = OSI_NONE; /* Disable the FRP in HW */ @@ -384,29 +386,55 @@ static nve32_t frp_hw_write(struct osi_core_priv_data *const osi_core, 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); + /* Check space for XCS BYPASS rule */ + if ((frp_cnt + 1U) > OSI_FRP_MAX_ENTRY) { + ret = -1; + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "No space for rules\n", OSI_NONE); + goto error; + } + + /* Check HW table size for non-zero */ + if (frp_cnt != 0U) { + /* 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; + } + } + + /* Write BYPASS rule for XDCS */ + bypass_entry.match_en = 0x0U; + bypass_entry.accept_frame = 1; + bypass_entry.reject_frame = 1; + ret = ops_p->update_frp_entry(osi_core, frp_cnt, &bypass_entry); if (ret < 0) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Fail to update FRP entry\n", + "Fail to update BYPASS 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); - } + /* Update the NVE */ + ret = ops_p->update_frp_nve(osi_core, frp_cnt); + 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 */ + /* Enable the FRP in HW */ hw_write_enable_frp: - tmp = ops_p->config_frp(osi_core, OSI_ENABLE); + tmp = ops_p->config_frp(osi_core, OSI_ENABLE); + } + +error: return (ret < 0) ? ret : tmp; } @@ -616,6 +644,9 @@ static nve32_t frp_delete(struct osi_core_priv_data *const osi_core, pos++; } + /* Update the frp_cnt entry */ + osi_core->frp_cnt = (frp_cnt - count); + /* Write FRP Table into HW */ ret = frp_hw_write(osi_core, ops_p); if (ret < 0) { @@ -624,9 +655,6 @@ static nve32_t frp_delete(struct osi_core_priv_data *const osi_core, OSI_NONE); } - /* Update the frp_cnt entry */ - osi_core->frp_cnt = (frp_cnt - count); - done: return ret; } From 07fa184d00adb6d3bec37ce9e02e9f91ec98fbe4 Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Tue, 13 Dec 2022 18:27:10 +0530 Subject: [PATCH 443/458] osi: core: validate input argument Validate input argument for exported data structures Bug 3789594 Change-Id: Ib16ace8cc933fcfce635f82ad0c89dc5791c999b Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2827045 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/nvethernetrm_export.h | 41 +++++++++---- osi/core/core_common.c | 111 ++++++++++++++++++++++++++++++++++ osi/core/core_common.h | 2 + osi/core/frp.c | 10 +++ osi/core/mgbe_core.c | 2 +- osi/core/osi_hal.c | 7 +++ 6 files changed, 160 insertions(+), 13 deletions(-) diff --git a/include/nvethernetrm_export.h b/include/nvethernetrm_export.h index abecbbd..f8d1d84 100644 --- a/include/nvethernetrm_export.h +++ b/include/nvethernetrm_export.h @@ -109,7 +109,11 @@ struct osi_core_frp_cmd { nveu8_t filter_mode; /** OSD FRP Link ID */ nve32_t next_frp_id; - /** OSD DMA Channel Selection */ + /** OSD DMA Channel Selection + * Bit selection of DMA channels to route the frame + * Bit[0] - DMA channel 0 + * .. + * Bit [N] - DMA channel N] */ nveu32_t dma_sel; }; @@ -127,13 +131,19 @@ struct osi_core_avb_algorithm { * * Expected values are enable(1) or disable(0) */ nveu32_t credit_control; - /** idleSlopeCredit value required for CBS */ + /** idleSlopeCredit value required for CBS + * Max value for EQOS - 0x000FFFFFU + * Max value for MGBE - 0x001FFFFFU */ nveu32_t idle_slope; - /** sendSlopeCredit value required for CBS */ + /** sendSlopeCredit value required for CBS + * Max value for EQOS - 0x0000FFFFU + * Max value for MGBE - 0x00003FFFU */ nveu32_t send_slope; - /** hiCredit value required for CBS */ + /** hiCredit value required for CBS + * Max value - 0x1FFFFFFFU */ nveu32_t hi_credit; - /** lowCredit value required for CBS */ + /** lowCredit value required for CBS + * Max value - 0x1FFFFFFFU */ nveu32_t low_credit; /** Transmit queue operating mode * @@ -143,7 +153,8 @@ struct osi_core_avb_algorithm { * * 10: enable */ nveu32_t oper_mode; - /** TC index */ + /** TC index + * value 0 to 7 represent 8 TC */ nveu32_t tcindex; }; @@ -158,13 +169,17 @@ struct osi_est_config { * index 0 for nsec, index 1 for sec */ nveu32_t btr[2]; - /** 64 bit base time offset index 0 for nsec, index 1 for sec */ + /** 64 bit base time offset index 0 for nsec, index 1 for sec + * 32 bits for Seconds, 32 bits for nanoseconds (max 10^9) */ nveu32_t btr_offset[2]; - /** 40 bit cycle time register, index 0 for nsec, index 1 for sec */ + /** 40 bits cycle time register, index 0 for nsec, index 1 for sec + * 8 bits for Seconds, 32 bits for nanoseconds (max 10^9) */ nveu32_t ctr[2]; - /** Configured Time Interval width + 7 bit extension register */ + /** Configured Time Interval width(24 bits) + 7 bits + * extension register */ nveu32_t ter; - /** size of the gate control list */ + /** size of the gate control list Max 256 entries + * valid value range (1-255)*/ nveu32_t llr; /** data array 8 bit gate op + 24 execution time * MGBE HW support GCL depth 256 */ @@ -175,11 +190,13 @@ struct osi_est_config { * @brief OSI Core FPE structure */ struct osi_fpe_config { - /** Queue Mask 1 preemption 0- express bit representation */ + /** Queue Mask 1 - preemption 0 - express + * bit representation*/ nveu32_t tx_queue_preemption_enable; /** RQ for all preemptable packets which are not filtered * based on user priority or SA-DA - */ + * Value range for EQOS 1-7 + * Value range for MGBE 1-9 */ nveu32_t rq; }; diff --git a/osi/core/core_common.c b/osi/core/core_common.c index e9acd50..0c65a0c 100644 --- a/osi/core/core_common.c +++ b/osi/core/core_common.c @@ -721,6 +721,14 @@ static nve32_t gcl_validate(struct osi_core_priv_data *const osi_core, {&ctr_l, MTL_EST_CTR_LOW[mac]}, {&ctr_h, MTL_EST_CTR_HIGH[mac]}}; + if (est->en_dis > OSI_ENABLE) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "input argument en_dis value\n", + (nveul64_t)est->en_dis); + ret = -1; + goto done; + } + if (est->llr > l_core->gcl_dep) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "input argument more than GCL depth\n", @@ -729,6 +737,36 @@ static nve32_t gcl_validate(struct osi_core_priv_data *const osi_core, goto done; } + /* 24 bit configure time in GCL + 7) */ + if (est->ter > 0x7FFFFFFFU) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "invalid TER value\n", + (nveul64_t)est->ter); + ret = -1; + goto done; + } + + /* nenosec register value can't be more than 10^9 nsec */ + if ((est->ctr[0] > OSI_NSEC_PER_SEC) || + (est->btr[0] > OSI_NSEC_PER_SEC) || + (est->ctr[1] > 0xFFU)) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "input argument CTR/BTR nsec is invalid\n", + 0ULL); + ret = -1; + goto done; + } + + /* if btr + offset is more than limit */ + if ((est->btr[0] > (OSI_NSEC_PER_SEC - est->btr_offset[0])) || + (est->btr[1] > (UINT_MAX - est->btr_offset[1]))) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "input argument BTR offset is invalid\n", + 0ULL); + ret = -1; + goto done; + } + 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]); @@ -1074,6 +1112,15 @@ nve32_t hw_config_fpe(struct osi_core_priv_data *const osi_core, goto error; } + /* Only 8 TC */ + if (fpe->tx_queue_preemption_enable > 0xFFU) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "FPE input tx_queue_preemption_enable is invalid\n", + (nveul64_t)fpe->tx_queue_preemption_enable); + ret = -1; + goto error; + } + if (osi_core->mac == OSI_MAC_HW_MGBE) { #ifdef MACSEC_SUPPORT osi_lock_irq_enabled(&osi_core->macsec_fpe_lock); @@ -1722,3 +1769,67 @@ void prepare_l3l4_registers(const struct osi_core_priv_data *const osi_core, prepare_l3l4_ctr_reg(osi_core, l3_l4, ctr_reg); } } + +/** + * @brief hw_validate_avb_input- validate input arguments + * + * Algorithm: + * 1) Check if idle slope is valid + * 2) Check if send slope is valid + * 3) Check if hi credit is valid + * 4) Check if low credit is valid + * + * @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() + * + * @retval 0 on success + * @retval -1 on failure. + */ +nve32_t hw_validate_avb_input(struct osi_core_priv_data *const osi_core, + const struct osi_core_avb_algorithm *const avb) +{ + nve32_t ret = 0; + nveu32_t ETS_QW_ISCQW_MASK[MAX_MAC_IP_TYPES] = {EQOS_MTL_TXQ_ETS_QW_ISCQW_MASK, + MGBE_MTL_TCQ_ETS_QW_ISCQW_MASK}; + nveu32_t ETS_SSCR_SSC_MASK[MAX_MAC_IP_TYPES] = {EQOS_MTL_TXQ_ETS_SSCR_SSC_MASK, + MGBE_MTL_TCQ_ETS_SSCR_SSC_MASK}; + nveu32_t ETS_HCR_HC_MASK[MAX_MAC_IP_TYPES] = {EQOS_MTL_TXQ_ETS_HCR_HC_MASK, + MGBE_MTL_TCQ_ETS_HCR_HC_MASK}; + nveu32_t ETS_LCR_LC_MASK[MAX_MAC_IP_TYPES] = {EQOS_MTL_TXQ_ETS_LCR_LC_MASK, + MGBE_MTL_TCQ_ETS_LCR_LC_MASK}; + nveu32_t mac = osi_core->mac; + + if (avb->idle_slope > ETS_QW_ISCQW_MASK[mac]) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "Invalid idle_slope\n", + (nveul64_t)avb->idle_slope); + ret = -1; + goto fail; + } + if (avb->send_slope > ETS_SSCR_SSC_MASK[mac]) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "Invalid send_slope\n", + (nveul64_t)avb->send_slope); + ret = -1; + goto fail; + } + if (avb->hi_credit > ETS_HCR_HC_MASK[mac]) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "Invalid hi credit\n", + (nveul64_t)avb->hi_credit); + ret = -1; + goto fail; + } + if (avb->low_credit > ETS_LCR_LC_MASK[mac]) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "Invalid low credit\n", + (nveul64_t)avb->low_credit); + ret = -1; + goto fail; + } + +fail: + return ret; +} diff --git a/osi/core/core_common.h b/osi/core/core_common.h index e5544b9..190d0c6 100644 --- a/osi/core/core_common.h +++ b/osi/core/core_common.h @@ -176,4 +176,6 @@ void prepare_l3l4_registers(const struct osi_core_priv_data *const osi_core, nve32_t hsi_common_error_inject(struct osi_core_priv_data *osi_core, nveu32_t error_code); #endif +nve32_t hw_validate_avb_input(struct osi_core_priv_data *const osi_core, + const struct osi_core_avb_algorithm *const avb); #endif /* INCLUDED_CORE_COMMON_H */ diff --git a/osi/core/frp.c b/osi/core/frp.c index 8ed426d..4af72b3 100644 --- a/osi/core/frp.c +++ b/osi/core/frp.c @@ -239,6 +239,7 @@ static nve32_t frp_entry_add(struct osi_core_priv_data *const osi_core, nveu8_t i = 0U, j = 0U, md_pos = 0U; nveu8_t temp_pos = pos; nve32_t ret; + nveu32_t dma_sel_val[MAX_MAC_IP_TYPES] = {0xFFU, 0x3FF}; /* Validate length */ if (length > OSI_FRP_MATCH_DATA_MAX) { @@ -267,6 +268,15 @@ static nve32_t frp_entry_add(struct osi_core_priv_data *const osi_core, goto done; } + /* Validate channel selection */ + if (dma_sel > dma_sel_val[osi_core->mac]) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "Invalid DMA selection\n", + (nveu64_t)dma_sel); + ret = -1; + goto done; + } + /* Check for avilable space */ req_entries = frp_req_entries(offset, length); if ((req_entries >= OSI_FRP_MAX_ENTRY) || diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index a510cb9..4d078db 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -2402,7 +2402,7 @@ static nve32_t mgbe_set_avb_algorithm( if (avb->algo > OSI_MTL_TXQ_AVALG_CBS) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid Algo input\n", - (nveul64_t)avb->tcindex); + (nveul64_t)avb->algo); goto done; } diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index cc4eace..cf03b84 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -2423,6 +2423,13 @@ static nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, break; case OSI_CMD_SET_AVB: + if (data->avb.algo == OSI_MTL_TXQ_AVALG_CBS) { + ret = hw_validate_avb_input(osi_core, &data->avb); + if (ret != 0) { + break; + } + } + ret = ops_p->set_avb_algorithm(osi_core, &data->avb); if (ret == 0) { (void)osi_memcpy(&l_core->cfg.avb[data->avb.qindex].avb_info, From 9ec9b39748afb867d83ad47d0608188e1ca0d286 Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Wed, 23 Nov 2022 14:56:32 +0530 Subject: [PATCH 444/458] osi: core: mgbe: Enable HSI for TXESIE interrupt Issue: Need HSI support for TXESIE interrupt Fix: Handle TXESIE interrupt for safety builds and update HSI CE counters Bug 3846917 Change-Id: Ie431f4b166d8adb524fba74e0da80570aa162bf1 Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2827634 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/mgbe_core.c | 48 ++++++++++++++++++++++++++++---------------- osi/core/mgbe_core.h | 10 ++++----- 2 files changed, 36 insertions(+), 22 deletions(-) diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index 4d078db..f7ade6a 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -2181,11 +2181,13 @@ static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core) struct core_local *l_core = (struct core_local *)(void *)osi_core; nveu32_t mac_isr = 0; nveu32_t mac_ier = 0; -#ifndef OSI_STRIPPED_LIB nveu32_t tx_errors = 0; -#endif /* !OSI_STRIPPED_LIB */ + nveu8_t *base = (nveu8_t *)osi_core->base; +#ifdef HSI_SUPPORT + nveu64_t tx_frame_err = 0; +#endif - mac_isr = osi_readla(osi_core, (nveu8_t *)osi_core->base + MGBE_MAC_ISR); + mac_isr = osi_readla(osi_core, base + MGBE_MAC_ISR); /* Check for Link status change interrupt */ if ((mac_isr & MGBE_MAC_ISR_LSI) == OSI_ENABLE) { @@ -2199,19 +2201,19 @@ static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core) } } - mac_ier = osi_readla(osi_core, (nveu8_t *)osi_core->base + MGBE_MAC_IER); + mac_ier = osi_readla(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); } -#ifndef OSI_STRIPPED_LIB /* 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((nveu8_t *)osi_core->base + MGBE_MAC_RX_TX_STS); + tx_errors = osi_readl(base + MGBE_MAC_RX_TX_STS); +#ifndef OSI_STRIPPED_LIB if ((tx_errors & MGBE_MAC_TX_TJT) == MGBE_MAC_TX_TJT) { /* increment Tx Jabber timeout stats */ osi_core->stats.mgbe_jabber_timeout_err = @@ -2233,9 +2235,27 @@ static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core) osi_core->stats.mgbe_payload_cs_err, 1UL); } - } #endif /* !OSI_STRIPPED_LIB */ +#ifdef HSI_SUPPORT + tx_errors &= (MGBE_MAC_TX_TJT | MGBE_MAC_TX_IHE | MGBE_MAC_TX_PCE); + if (tx_errors != OSI_NONE) { + 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 + } + if ((mac_isr & MGBE_ISR_TSIS) == MGBE_ISR_TSIS) { struct osi_core_tx_ts *head = &l_core->tx_ts_head; @@ -2250,7 +2270,7 @@ static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core) } /* TXTSC bit should get reset when all timestamp read */ - while (((osi_readla(osi_core, (nveu8_t *)osi_core->base + MGBE_MAC_TSS) & + while (((osi_readla(osi_core, base + MGBE_MAC_TSS) & MGBE_MAC_TSS_TXTSC) == MGBE_MAC_TSS_TXTSC)) { nveu32_t i = get_free_ts_idx(l_core); @@ -2275,17 +2295,11 @@ static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core) } } - l_core->ts[i].nsec = osi_readla(osi_core, - (nveu8_t *)osi_core->base + - MGBE_MAC_TSNSSEC); + l_core->ts[i].nsec = osi_readla(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); + l_core->ts[i].pkt_id = osi_readla(osi_core, base + MGBE_MAC_TSPKID); + l_core->ts[i].sec = osi_readla(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]; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 42f42eb..2be5f41 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -43,7 +43,6 @@ #define MGBE_MAC_PIDR2 0x0DCC #define MGBE_MAC_PMTCSR 0x00C0 #define MGBE_MAC_HTR_REG(x) ((0x0004U * (x)) + 0x0010U) -#define MGBE_MAC_RX_TX_STS 0x00B8 #define MGBE_WRAP_AXI_ASID0_CTRL 0x8400 #define MGBE_WRAP_AXI_ASID1_CTRL 0x8404 #define MGBE_WRAP_AXI_ASID2_CTRL 0x8408 @@ -62,8 +61,6 @@ #define MGBE3_SID ((nveu32_t)0x4BU) #define MGBE_MAC_PAUSE_TIME 0xFFFF0000U #define MGBE_MAC_PAUSE_TIME_MASK 0xFFFF0000U -#define MGBE_MAC_TX_TJT OSI_BIT(0) -#define MGBE_MAC_TX_IHE OSI_BIT(12) #define MGBE_MAC_VLAN_TR_VTHM OSI_BIT(25) #define MGBE_MAC_VLAN_TR_VTIM OSI_BIT(17) #define MGBE_MAC_VLAN_TR_VTIM_SHIFT 17 @@ -100,7 +97,6 @@ #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_PCE OSI_BIT(13) /** * @addtogroup - MGBE-LPI LPI configuration macros * @@ -156,9 +152,9 @@ #define MGBE_MTL_RXP_BYPASS_CNT 2U #define MGBE_MAC_FPE_CTS_SVER OSI_BIT(1) -#define MGBE_IMR_TXESIE OSI_BIT(13) #endif /* !OSI_STRIPPED_LIB */ +#define MGBE_MAC_RX_TX_STS 0x00B8 #define MGBE_MTL_EST_CONTROL 0x1050 #define MGBE_MTL_EST_OVERHEAD 0x1054 #define MGBE_MTL_EST_STATUS 0x1058 @@ -174,6 +170,9 @@ #define MGBE_MTL_RXP_IND_CS 0x10B0 #define MGBE_MTL_RXP_IND_DATA 0x10B4 +#define MGBE_MAC_TX_PCE OSI_BIT(13) +#define MGBE_MAC_TX_IHE OSI_BIT(12) +#define MGBE_MAC_TX_TJT OSI_BIT(0) #define MGBE_MTL_TCQ_ETS_HCR(x) ((0x0080U * (x)) + 0x1120U) #define MGBE_MTL_TCQ_ETS_LCR(x) ((0x0080U * (x)) + 0x1124U) #define MGBE_MTL_TCQ_ETS_SSCR(x) ((0x0080U * (x)) + 0x111CU) @@ -200,6 +199,7 @@ #define MGBE_8PTP_CYCLE 26U #define MGBE_PTP_CLK_SPEED 312500000U #define MGBE_DMA_ISR_MTLIS OSI_BIT(16) +#define MGBE_IMR_TXESIE OSI_BIT(13) #define MGBE_IMR_FPEIE OSI_BIT(15) #ifndef OSI_STRIPPED_LIB #define MGBE_MAC_EXT_CNF_EIPG 0x1U From 98fdc8526aa260e7c340d4af83ac5dfdfde01902 Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Mon, 12 Dec 2022 13:23:51 +0000 Subject: [PATCH 445/458] osi: xpcs: add delays as per HW team suggestion Issue: Random delays were added in xpcs_start and xpcs_init which can lead to increase in the boot time Fix: Instead of adding random delays and retries add the exact delays suggested by HW team Bug 3806700 Change-Id: If6f781d86c7de4019883e4b02dc89b2d04ecc768 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2826256 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Zuyu Liao <zuyul@nvidia.com> Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Tested-by: Zuyu Liao <zuyul@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- osi/core/xpcs.c | 35 ++++++++++++++++++++++++++++------- osi/core/xpcs.h | 9 --------- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/osi/core/xpcs.c b/osi/core/xpcs.c index e749dc5..b61cacb 100644 --- a/osi/core/xpcs.c +++ b/osi/core/xpcs.c @@ -216,7 +216,12 @@ nve32_t xpcs_start(struct osi_core_priv_data *osi_core) XPCS_SR_XS_PCS_STS1_RLU) { cond = COND_MET; } else { - osi_core->osd_ops.udelay(1000U); + /* Maximum wait delay as per HW team is 1msec. + * So add a loop for 1000 iterations with 1usec delay, + * so that if check get satisfies before 1msec will come + * out of loop and it can save some boot time + */ + osi_core->osd_ops.udelay(1U); } } fail: @@ -239,7 +244,7 @@ static nve32_t xpcs_uphy_lane_bring_up(struct osi_core_priv_data *osi_core, nveu32_t lane_init_en) { void *xpcs_base = osi_core->xpcs_base; - nveu32_t retry = XPCS_RETRY_COUNT; + nveu32_t retry = 5U; nve32_t cond = COND_NOT_MET; nveu32_t val = 0; nveu32_t count; @@ -269,7 +274,11 @@ static nve32_t xpcs_uphy_lane_bring_up(struct osi_core_priv_data *osi_core, /* exit loop */ cond = COND_MET; } else { - osi_core->osd_ops.udelay(5U); + /* Max wait time is 1usec. + * Most of the time loop got exited in first iteration. + * but added an extra count of 4 for safer side + */ + osi_core->osd_ops.udelay(1U); } } } @@ -291,7 +300,7 @@ fail: 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; + nveu32_t retry = RETRY_COUNT; nve32_t cond = COND_NOT_MET; nveu32_t val = 0; nveu32_t count; @@ -312,7 +321,12 @@ static nve32_t xpcs_check_pcs_lock_status(struct osi_core_priv_data *osi_core) /* exit loop */ cond = COND_MET; } else { - osi_core->osd_ops.udelay(5U); + /* Maximum wait delay as per HW team is 1msec. + * So add a loop for 1000 iterations with 1usec delay, + * so that if check get satisfies before 1msec will come + * out of loop and it can save some boot time + */ + osi_core->osd_ops.udelay(1U); } } @@ -336,7 +350,7 @@ fail: static nve32_t xpcs_lane_bring_up(struct osi_core_priv_data *osi_core) { struct core_local *l_core = (struct core_local *)(void *)osi_core; - nveu32_t retry = 1000; + nveu32_t retry = 7U; nveu32_t count; nveu32_t val = 0; nve32_t cond; @@ -412,7 +426,14 @@ static nve32_t xpcs_lane_bring_up(struct osi_core_priv_data *osi_core) if ((val & XPCS_WRAP_UPHY_RX_CONTROL_0_0_RX_CAL_EN) == 0U) { cond = COND_MET; } else { - osi_core->osd_ops.udelay(1000U); + /* Maximum wait delay as per HW team is 100 usec. + * But most of the time as per experiments it takes + * around 14usec to satisy the condition, so add a + * minimum delay of 14usec and loop it for 7times. + * With this 14usec delay condition gets satifies + * in first iteration itself. + */ + osi_core->osd_ops.udelay(14U); } } diff --git a/osi/core/xpcs.h b/osi/core/xpcs.h index 345fc27..be788e3 100644 --- a/osi/core/xpcs.h +++ b/osi/core/xpcs.h @@ -26,15 +26,6 @@ #include "../osi/common/common.h" #include <osi_core.h> -/** - * @addtogroup XPCS helper macros - * - * @brief XPCS helper macros. - * @{ - */ -#define XPCS_RETRY_COUNT (RETRY_COUNT * (2U)) -/** @} */ - /** * @addtogroup XPCS Register offsets * From d88b634d0736bec43050759bacde2dded487db6e Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Sun, 18 Dec 2022 16:54:52 +0530 Subject: [PATCH 446/458] osi: core: adjust_time boundary check 1) Add check for adjust_time boundary 2) Fix functional issue introduced while fixing Cert-C issue. 3) Update MAX frequency Bug 3909337 Change-Id: Ib2402827219d512cd5fd9f6bb6638b21510d86ff Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2830043 Reviewed-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- osi/core/core_local.h | 4 +++- osi/core/osi_hal.c | 54 +++++++++++++++++++++++++++++++------------ 2 files changed, 42 insertions(+), 16 deletions(-) diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 685ee9a..0a8510e 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -240,10 +240,12 @@ struct core_ops { #define I_COMPONENT_BY_10 3LL #define P_COMPONENT_BY_10 7LL #define WEIGHT_BY_10 10LL -#define MAX_FREQ 85000000LL +#define MAX_FREQ_POS 250000000LL +#define MAX_FREQ_NEG -250000000LL #define SERVO_STATS_0 0U #define SERVO_STATS_1 1U #define SERVO_STATS_2 2U +#define OSI_NSEC_PER_SEC_SIGNED 1000000000LL #define ETHER_NSEC_MASK 0x7FFFFFFFU diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index cf03b84..8484a24 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -1181,7 +1181,7 @@ static nve32_t osi_adjust_freq(struct osi_core_priv_data *const osi_core, nve32_ diff = (nveu32_t)temp; } else { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "temp > UINT_MAX\n", - 0ULL); + (nvel64_t)temp); goto fail; } @@ -1216,11 +1216,13 @@ static nve32_t osi_adjust_time(struct osi_core_priv_data *const osi_core, struct core_local *l_core = (struct core_local *)(void *)osi_core; nveu32_t neg_adj = 0; nveu32_t sec = 0, nsec = 0; + nveu32_t cur_sec = 0, cur_nsec = 0; nveu64_t quotient; nveu64_t reminder = 0; nveu64_t udelta = 0; nve32_t ret = -1; nvel64_t nsec_delta1 = nsec_delta; + nvel64_t calculate; if (nsec_delta1 < 0) { neg_adj = 1; @@ -1247,14 +1249,33 @@ static nve32_t osi_adjust_time(struct osi_core_priv_data *const osi_core, goto fail; } + common_get_systime_from_mac(osi_core->base, + osi_core->mac, &cur_sec, &cur_nsec); + calculate = ((nvel64_t)cur_sec * OSI_NSEC_PER_SEC_SIGNED) + (nvel64_t)cur_nsec; + + if (neg_adj == 1U) { + if ((calculate + nsec_delta) < 0LL) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "Wrong delta, put time in -ve\n", 0ULL); + ret = -1; + goto fail; + } + } else { + /* Addition of 2 sec for compensate Max nanosec factors*/ + if (cur_sec > (UINT_MAX - sec - 2U)) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "Not Supported sec beyond UINT_max\n", 0ULL); + ret = -1; + goto fail; + } + } + ret = l_core->ops_p->adjust_mactime(osi_core, sec, nsec, neg_adj, osi_core->ptp_config.one_nsec_accuracy); fail: return ret; } - - #ifndef OSI_STRIPPED_LIB /** * @brief rxq_route_config - Enable PTP RX packets routing @@ -1868,6 +1889,8 @@ static inline nve32_t freq_offset_calculate(struct osi_core_priv_data *sec_osi_c */ if ((offset >= 1000000000LL) || (offset <= -1000000000LL)) { s->count = SERVO_STATS_0; /* JUMP */ + s->drift = 0; + s->last_ppb = 0; goto fail; } @@ -1908,10 +1931,10 @@ static inline nve32_t freq_offset_calculate(struct osi_core_priv_data *sec_osi_c } } /* update this with constant */ - if (s->drift < -MAX_FREQ) { - s->drift = -MAX_FREQ; - } else if (s->drift > MAX_FREQ) { - s->drift = MAX_FREQ; + if (s->drift < MAX_FREQ_NEG) { + s->drift = MAX_FREQ_NEG; + } else if (s->drift > MAX_FREQ_POS) { + s->drift = MAX_FREQ_POS; } else { /* Do Nothing */ } @@ -1935,14 +1958,15 @@ static inline nve32_t freq_offset_calculate(struct osi_core_priv_data *sec_osi_c cofficient = (1000000000LL) / (s->local[1] - s->local[0]); if ((cofficient != 0) && (offset < 0) && - ((s->const_i > (-OSI_LLONG_MAX / (WEIGHT_BY_10 * cofficient * offset))) || - (s->const_p > (-OSI_LLONG_MAX / (WEIGHT_BY_10 * cofficient * offset))))) { + (((offset / WEIGHT_BY_10) < (-OSI_LLONG_MAX / (s->const_i * cofficient))) || + ((offset / WEIGHT_BY_10) < (-OSI_LLONG_MAX / (s->const_p * cofficient))))) { s->count = SERVO_STATS_0; break; } + if ((cofficient != 0) && (offset > 0) && - ((s->const_i > (OSI_LLONG_MAX / (WEIGHT_BY_10 * cofficient * offset))) || - (s->const_p > (OSI_LLONG_MAX / (WEIGHT_BY_10 * cofficient * offset))))) { + (((offset / WEIGHT_BY_10) > (OSI_LLONG_MAX / (cofficient * s->const_i))) || + ((offset / WEIGHT_BY_10) > (OSI_LLONG_MAX / (cofficient * s->const_p))))) { s->count = SERVO_STATS_0; break; } @@ -1953,10 +1977,10 @@ static inline nve32_t freq_offset_calculate(struct osi_core_priv_data *sec_osi_c ki_term; /* FIXME tune cofficients */ - if (ppb < -MAX_FREQ) { - ppb = -MAX_FREQ; - } else if (ppb > MAX_FREQ) { - ppb = MAX_FREQ; + if (ppb < MAX_FREQ_NEG) { + ppb = MAX_FREQ_NEG; + } else if (ppb > MAX_FREQ_POS) { + ppb = MAX_FREQ_POS; } else { if (((s->drift >= 0) && ((OSI_LLONG_MAX - s->drift) < ki_term)) || ((s->drift < 0) && ((-OSI_LLONG_MAX - s->drift) > ki_term))) { From a32e093d11944f1493688386aca09f779fb6deb9 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Wed, 14 Dec 2022 21:56:15 +0530 Subject: [PATCH 447/458] nvethernetrm: Convert OSD core as a static library Issue: OSD core needs to be converted as a static library for the data path support in servers. Fix: Convert OSD core as a static library. Bug 3691486 Change-Id: If904be9f886b2149dd247d0672eb933891a437ba Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2827987 Reviewed-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Tested-by: Nagaraj Annaiah <nannaiah@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- osi/dma/staticlib/Makefile.interface.tmk | 38 +++++++++++++++++ osi/dma/staticlib/Makefile.tmk | 54 ++++++++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 osi/dma/staticlib/Makefile.interface.tmk create mode 100644 osi/dma/staticlib/Makefile.tmk diff --git a/osi/dma/staticlib/Makefile.interface.tmk b/osi/dma/staticlib/Makefile.interface.tmk new file mode 100644 index 0000000..c87a743 --- /dev/null +++ b/osi/dma/staticlib/Makefile.interface.tmk @@ -0,0 +1,38 @@ +################################### 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 makefile fragment +# +############################################################################### + +ifdef NV_INTERFACE_FLAG_STATIC_LIBRARY_SECTION +NV_INTERFACE_NAME := nvethernetcl +NV_INTERFACE_COMPONENT_DIR := . +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/staticlib/Makefile.tmk b/osi/dma/staticlib/Makefile.tmk new file mode 100644 index 0000000..c033b19 --- /dev/null +++ b/osi/dma/staticlib/Makefile.tmk @@ -0,0 +1,54 @@ +################################### 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_STATIC_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 := \ + $(NV_SOURCE)/nvethernetrm/osi/dma/eqos_dma.c \ + $(NV_SOURCE)/nvethernetrm/osi/dma/osi_dma.c \ + $(NV_SOURCE)/nvethernetrm/osi/dma/osi_dma_txrx.c \ + $(NV_SOURCE)/nvethernetrm/osi/dma/mgbe_dma.c \ + $(NV_SOURCE)/nvethernetrm/osi/dma/eqos_desc.c \ + $(NV_SOURCE)/nvethernetrm/osi/dma/mgbe_desc.c \ + $(NV_SOURCE)/nvethernetrm/osi/dma/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 +else + NV_COMPONENT_CFLAGS += -DOSI_STRIPPED_LIB +endif +include $(NV_BUILD_STATIC_LIBRARY) +endif From 485cd6df30ee724ee2863960ee48eb2c4a0e43a2 Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Wed, 4 Jan 2023 12:25:43 +0530 Subject: [PATCH 448/458] osi: core: update boundary for lo and hi credit As per HW specification update boundary check for locredit and hicredit. Bug 3927833 Change-Id: I3b6efeba52a7c40d3f4d276dea50e95310011d5f Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2837043 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- osi/core/core_common.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/osi/core/core_common.c b/osi/core/core_common.c index 0c65a0c..485fb52 100644 --- a/osi/core/core_common.c +++ b/osi/core/core_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2022-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"), @@ -1795,10 +1795,8 @@ nve32_t hw_validate_avb_input(struct osi_core_priv_data *const osi_core, MGBE_MTL_TCQ_ETS_QW_ISCQW_MASK}; nveu32_t ETS_SSCR_SSC_MASK[MAX_MAC_IP_TYPES] = {EQOS_MTL_TXQ_ETS_SSCR_SSC_MASK, MGBE_MTL_TCQ_ETS_SSCR_SSC_MASK}; - nveu32_t ETS_HCR_HC_MASK[MAX_MAC_IP_TYPES] = {EQOS_MTL_TXQ_ETS_HCR_HC_MASK, - MGBE_MTL_TCQ_ETS_HCR_HC_MASK}; - nveu32_t ETS_LCR_LC_MASK[MAX_MAC_IP_TYPES] = {EQOS_MTL_TXQ_ETS_LCR_LC_MASK, - MGBE_MTL_TCQ_ETS_LCR_LC_MASK}; + nveu32_t ETS_HC_BOUND = 0x8000000U; + nveu32_t ETS_LC_BOUND = 0xF8000000U; nveu32_t mac = osi_core->mac; if (avb->idle_slope > ETS_QW_ISCQW_MASK[mac]) { @@ -1815,21 +1813,21 @@ nve32_t hw_validate_avb_input(struct osi_core_priv_data *const osi_core, ret = -1; goto fail; } - if (avb->hi_credit > ETS_HCR_HC_MASK[mac]) { + if (avb->hi_credit > ETS_HC_BOUND) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid hi credit\n", (nveul64_t)avb->hi_credit); ret = -1; goto fail; } - if (avb->low_credit > ETS_LCR_LC_MASK[mac]) { + if ((avb->low_credit < ETS_LC_BOUND) && + (avb->low_credit != 0U)) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, "Invalid low credit\n", (nveul64_t)avb->low_credit); ret = -1; goto fail; } - fail: return ret; } From 106d58fdd20a8d65de1d2da99f49df423107a7f6 Mon Sep 17 00:00:00 2001 From: Rakesh Goyal <rgoyal@nvidia.com> Date: Sun, 18 Dec 2022 17:50:27 +0530 Subject: [PATCH 449/458] osi: core: improve MAC-2-MAC accuracy Use PTP-TSC timestamp capture feature instead of PTP HW register read to improve MAC-2-MAC sync accuracy. Bug 3893803 Change-Id: I5b5876cedf9b2fd200749623d9b047dc27eeb0a8 Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2835302 Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- osi/core/osi_hal.c | 147 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 113 insertions(+), 34 deletions(-) diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 8484a24..ea6cc12 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2021-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"), @@ -1831,30 +1831,113 @@ done: /** * @brief calculate time drift between primary and secondary - * interface. + * interface and update current time. * 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 + * @param[in] osi_core: OSI core data structure for primary interface. + * @param[in] sec_osi_core: OSI core data structure for seconday interface. + * @param[out] primary_time: primary interface time pointer + * @param[out] secondary_time: Secondary interface time pointer * * @retval calculated drift value */ -static inline nvel64_t dirft_calculation(nveu32_t sec, nveu32_t nsec, - nveu32_t secondary_sec, - nveu32_t secondary_nsec) +static inline nvel64_t dirft_calculation(struct osi_core_priv_data *const osi_core, + struct osi_core_priv_data *const sec_osi_core, + nvel64_t *primary_time, + nvel64_t *secondary_time) { + nve32_t ret; + nveu32_t sec = 0x0; + nveu32_t nsec = 0x0; + nveu32_t secondary_sec = 0x0; + nveu32_t secondary_nsec = 0x0; nvel64_t val = 0LL; + nveul64_t temp = 0x0U; + nveul64_t time1 = 0x0U; + nveul64_t time2 = 0x0U; + struct osi_core_ptp_tsc_data ptp_tsc1; + struct osi_core_ptp_tsc_data ptp_tsc2; - val = (nvel64_t)sec - (nvel64_t)secondary_sec; - val = (nvel64_t)(val * 1000000000LL); - val += (nvel64_t)nsec - (nvel64_t)secondary_nsec; + ret = hw_ptp_tsc_capture(osi_core, &ptp_tsc1); + if (ret != 0) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "CORE: TSC PTP capture failed for primary\n", 0ULL); + goto fail; + } + ret = hw_ptp_tsc_capture(sec_osi_core, &ptp_tsc2); + if (ret != 0) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "CORE: TSC PTP capture failed for secondary\n", 0ULL); + goto fail; + } + + time1 = ((nveul64_t)((nveul64_t)ptp_tsc1.tsc_high_bits << 32) + + (nveul64_t)ptp_tsc1.tsc_low_bits); + sec = ptp_tsc1.ptp_high_bits; + nsec = ptp_tsc1.ptp_low_bits; + if ((OSI_LLONG_MAX - (nvel64_t)nsec) > ((nvel64_t)sec * OSI_NSEC_PER_SEC_SIGNED)) { + *primary_time = ((nvel64_t)sec * OSI_NSEC_PER_SEC_SIGNED) + (nvel64_t)nsec; + } else { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "CORE: Negative primary PTP time\n", 0ULL); + goto fail; + } + + time2 = ((nveul64_t)((nveul64_t)ptp_tsc2.tsc_high_bits << 32) + + (nveul64_t)ptp_tsc2.tsc_low_bits); + secondary_sec = ptp_tsc2.ptp_high_bits; + secondary_nsec = ptp_tsc2.ptp_low_bits; + + if ((OSI_LLONG_MAX - (nvel64_t)secondary_nsec) > + ((nvel64_t)secondary_sec * OSI_NSEC_PER_SEC_SIGNED)) { + *secondary_time = ((nvel64_t)secondary_sec * OSI_NSEC_PER_SEC_SIGNED) + + (nvel64_t)secondary_nsec; + } else { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "CORE: Negative secondary PTP time\n", 0ULL); + goto fail; + } + + if (time2 > time1) { + temp = time2 - time1; + if ((OSI_LLONG_MAX - (nvel64_t)temp) > *secondary_time) { + *secondary_time -= (nvel64_t)temp; + } else { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "CORE: sec time crossing limit\n", 0ULL); + goto fail; + } + } else if (time1 >= time2) { + temp = time1 - time2; + if ((OSI_LLONG_MAX - (nvel64_t)temp) > *secondary_time) { + *secondary_time += (nvel64_t)temp; + } else { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "CORE: sec time crossing limit\n", 0ULL); + goto fail; + } + } else { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "CORE: wrong drift\n", 0ULL); + goto fail; + } + /* 0 is lowest possible valid time value which represent + * 1 Jan, 1970 + */ + if ((*primary_time >= 0) && (*secondary_time >= 0)) { + val = (*primary_time - *secondary_time); + } else { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "CORE: negative time\n", 0ULL); + goto fail; + } + +fail: return val; } @@ -2337,13 +2420,12 @@ static nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, nve32_t ret = -1; struct osi_core_priv_data *sec_osi_core; struct core_local *secondary_osi_lcore; - nvel64_t drift_value = 0x0; nveu32_t sec = 0x0; nveu32_t nsec = 0x0; - nveu32_t secondary_sec = 0x0; - nveu32_t secondary_nsec = 0x0; + nvel64_t drift_value = 0x0; nve32_t freq_adj_value = 0x0; - nvel64_t secondary_time; + nvel64_t secondary_time = 0x0; + nvel64_t primary_time = 0x0; ops_p = l_core->ops_p; @@ -2521,16 +2603,10 @@ static nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, } if (l_core->ether_m2m_role == OSI_PTP_M2M_PRIMARY) { - drift_value = 0x0; - osi_lock_irq_enabled(&secondary_osi_lcore->serv.m2m_lock); - common_get_systime_from_mac(sec_osi_core->base, - sec_osi_core->mac, &secondary_sec, &secondary_nsec); - common_get_systime_from_mac(osi_core->base, - osi_core->mac, &sec, &nsec); - osi_unlock_irq_enabled(&secondary_osi_lcore->serv.m2m_lock); + drift_value = dirft_calculation(osi_core, sec_osi_core, + &primary_time, + &secondary_time); - drift_value = dirft_calculation(sec, nsec, secondary_sec, secondary_nsec); - secondary_time = ((nvel64_t)secondary_sec * 1000000000LL) + (nvel64_t)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, @@ -2540,6 +2616,13 @@ static nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, /* call adjust time as JUMP happened */ ret = osi_adjust_time(sec_osi_core, drift_value); + if (ret < 0) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, + "CORE: adjust_time failed\n", + 0ULL); + } else { + ret = osi_adjust_freq(sec_osi_core, 0); + } } else { ret = osi_adjust_freq(sec_osi_core, freq_adj_value); @@ -2579,20 +2662,15 @@ static nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, if (l_core->ether_m2m_role == OSI_PTP_M2M_PRIMARY) { drift_value = 0x0; - osi_lock_irq_enabled(&secondary_osi_lcore->serv.m2m_lock); - common_get_systime_from_mac(sec_osi_core->base, - sec_osi_core->mac, &secondary_sec, &secondary_nsec); - common_get_systime_from_mac(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); + drift_value = dirft_calculation(osi_core, sec_osi_core, + &primary_time, + &secondary_time); 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; + ret = osi_adjust_freq(sec_osi_core, 0); } } @@ -2676,6 +2754,7 @@ static nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, secondary_osi_lcore->serv.count = SERVO_STATS_0; secondary_osi_lcore->serv.drift = 0; secondary_osi_lcore->serv.last_ppb = 0; + ret = osi_adjust_freq(sec_osi_core, 0); } } if (ret < 0) { From 305cc3e56529276b9be23f3e95ac6532edc3f6fe Mon Sep 17 00:00:00 2001 From: Diptanshu Jamgade <djamgade@nvidia.com> Date: Mon, 9 Jan 2023 08:49:23 +0000 Subject: [PATCH 450/458] osi: core: Update OSI_PAUSE_FRAMES_DISABLE Issue: Wrong value of OSI_PAUSE_FRAMES_DISABLE enabling flow control at probe. Fix: Update OSI_PAUSE_FRAMES_DISABLE as per dt-bindings to disable pause frame support as a default Bug 3932946 Change-Id: I0d5227c06b4b5627dc47f5542bbf5d2a0e7ed3bf Signed-off-by: Diptanshu Jamgade <djamgade@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2839839 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: Ashutosh Jha <ajha@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- include/osi_common.h | 3 ++- include/osi_core.h | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index 667b6a3..9d825c6 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2022, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -77,6 +77,7 @@ #define OSI_GCL_SIZE_1024 1024U /** @} */ +#define OSI_PAUSE_FRAMES_DISABLE 0U #ifndef OSI_STRIPPED_LIB /** diff --git a/include/osi_core.h b/include/osi_core.h index 3d2d094..644c918 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2022, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -198,7 +198,6 @@ typedef my_lint_64 nvel64_t; #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_SA_MATCH 1U From d77b5a2068557e13ad912df172e9e98d8310b3c8 Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Mon, 16 Jan 2023 10:13:10 +0530 Subject: [PATCH 451/458] nvethernetrm: move pause-frame macros Pause frames not programmed in safety builds so move those macros under non safety builds. Bug 3932946 Change-Id: Iff89373c4ffd20b35589f3f3852ef191f5f54acf Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2844105 Reviewed-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- include/osi_common.h | 5 ++--- include/osi_core.h | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index 9d825c6..4ac83ca 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -53,6 +53,8 @@ #define OSI_MAX_TX_COALESCE_USEC 1020U #define OSI_MIN_TX_COALESCE_USEC 32U #define OSI_MIN_TX_COALESCE_FRAMES 1U +#define OSI_PAUSE_FRAMES_DISABLE 0U +#define OSI_PAUSE_FRAMES_ENABLE 1U #endif /* !OSI_STRIPPED_LIB */ /* Compiler hints for branch prediction */ @@ -77,16 +79,13 @@ #define OSI_GCL_SIZE_1024 1024U /** @} */ -#define OSI_PAUSE_FRAMES_DISABLE 0U #ifndef OSI_STRIPPED_LIB - /** * @addtogroup Helper MACROS * * @brief EQOS generic helper MACROS. * @{ */ -#define OSI_PAUSE_FRAMES_ENABLE 1U #define OSI_PTP_REQ_CLK_FREQ 250000000U #define OSI_FLOW_CTRL_DISABLE 0U #define OSI_ADDRESS_32BIT 0 diff --git a/include/osi_core.h b/include/osi_core.h index 644c918..b7fe608 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -1301,8 +1301,6 @@ struct osi_core_priv_data { 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 */ @@ -1329,6 +1327,8 @@ struct osi_core_priv_data { nveu16_t vlan_filter_cnt; /** RSS core structure */ struct osi_core_rss rss; + /** DT entry to enable(1) or disable(0) pause frame support */ + nveu32_t pause_frames; #endif /** Residual queue valid with FPE support */ nveu32_t residual_queue; From 5a41280c4b5ee56233abd84cf47319fcdcbafb8e Mon Sep 17 00:00:00 2001 From: Bhadram Varka <vbhadram@nvidia.com> Date: Fri, 20 Jan 2023 16:54:29 +0530 Subject: [PATCH 452/458] osi: dma: move *_dma.c and debug.c out of safety eqos_dma.c, mgbe_dma.c and debug.c files not used for safety builds. Move this out of safety build compilation Bug 3949980 Change-Id: I5922446e0098717061ae1c181ccd462b4566f299 Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2846847 Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: Krishna Thota <kthota@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- include/config.tmk | 13 ++++++++++++- osi/dma/Makefile.tmk | 21 ++++++++++++++------- osi/dma/dma_local.h | 4 +++- osi/dma/eqos_dma.c | 12 +++--------- osi/dma/mgbe_dma.c | 12 +++--------- osi/dma/osi_dma.c | 13 +++++++------ 6 files changed, 42 insertions(+), 33 deletions(-) diff --git a/include/config.tmk b/include/config.tmk index 363e7df..02027bf 100644 --- a/include/config.tmk +++ b/include/config.tmk @@ -1,4 +1,4 @@ -# copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. +# copyright (c) 2022-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"), @@ -19,13 +19,24 @@ # DEALINGS IN THE SOFTWARE. # ############################################################################### + +# Set the Makefile config macros to zero by default +OSI_STRIPPED_LIB := 0 +OSI_DEBUG := 0 +DEBUG_MACSEC := 0 + ifeq ($(NV_BUILD_CONFIGURATION_IS_SAFETY),1) NV_COMPONENT_CFLAGS += -DOSI_STRIPPED_LIB + OSI_STRIPPED_LIB := 1 else NV_COMPONENT_CFLAGS += -DOSI_DEBUG NV_COMPONENT_CFLAGS += -DDEBUG_MACSEC + OSI_DEBUG := 1 + DEBUG_MACSEC := 1 endif NV_COMPONENT_CFLAGS += -DHSI_SUPPORT NV_COMPONENT_CFLAGS += -DMACSEC_SUPPORT #NV_COMPONENT_CFLAGS += -DMACSEC_KEY_PROGRAM +HSI_SUPPORT := 1 +MACSEC_SUPPORT := 1 ccflags-y += $(NV_COMPONENT_CFLAGS) diff --git a/osi/dma/Makefile.tmk b/osi/dma/Makefile.tmk index 9fd16ae..fbb585a 100644 --- a/osi/dma/Makefile.tmk +++ b/osi/dma/Makefile.tmk @@ -30,13 +30,10 @@ 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/dma/osi_dma.c \ + $(NV_SOURCE)/nvethernetrm/osi/dma/osi_dma_txrx.c \ + $(NV_SOURCE)/nvethernetrm/osi/dma/eqos_desc.c \ + $(NV_SOURCE)/nvethernetrm/osi/dma/mgbe_desc.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 @@ -47,6 +44,16 @@ NV_COMPONENT_INCLUDES := \ include $(NV_SOURCE)/nvethernetrm/include/config.tmk +ifeq ($(OSI_DEBUG),1) +NV_COMPONENT_SOURCES += $(NV_SOURCE)/nvethernetrm/osi/dma/debug.c +endif + +ifeq ($(OSI_STRIPPED_LIB),0) +NV_COMPONENT_SOURCES += \ + $(NV_SOURCE)/nvethernetrm/osi/dma/mgbe_dma.c \ + $(NV_SOURCE)/nvethernetrm/osi/dma/eqos_dma.c +endif + include $(NV_BUILD_SHARED_LIBRARY) endif diff --git a/osi/dma/dma_local.h b/osi/dma/dma_local.h index f2001b4..b73d6af 100644 --- a/osi/dma/dma_local.h +++ b/osi/dma/dma_local.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2019-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"), @@ -112,6 +112,7 @@ struct dma_local { nveu32_t l_mac_ver; }; +#ifndef OSI_STRIPPED_LIB /** * @brief eqos_init_dma_chan_ops - Initialize eqos DMA operations. * @@ -137,6 +138,7 @@ void eqos_init_dma_chan_ops(struct dma_chan_ops *ops); * - De-initialization: No */ void mgbe_init_dma_chan_ops(struct dma_chan_ops *ops); +#endif /* !OSI_STRIPPED_LIB */ /** * @brief eqos_get_desc_ops - EQOS init DMA descriptor operations diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c index cca4687..6f6fc6d 100644 --- a/osi/dma/eqos_dma.c +++ b/osi/dma/eqos_dma.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2022, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -20,11 +20,11 @@ * DEALINGS IN THE SOFTWARE. */ +#ifndef OSI_STRIPPED_LIB #include "../osi/common/common.h" #include "dma_local.h" #include "eqos_dma.h" -#ifndef OSI_STRIPPED_LIB /** * @brief eqos_config_slot - Configure slot Checking for DMA channel * @@ -80,7 +80,6 @@ static void eqos_config_slot(struct osi_dma_priv_data *osi_dma, EQOS_DMA_CHX_SLOT_CTRL(chan)); } } -#endif /* !OSI_STRIPPED_LIB */ #ifdef OSI_DEBUG /** @@ -136,16 +135,11 @@ static void eqos_debug_intr_config(struct osi_dma_priv_data *osi_dma) * * @param[in] ops: DMA channel operations pointer. */ -#ifndef OSI_STRIPPED_LIB void eqos_init_dma_chan_ops(struct dma_chan_ops *ops) -#else -void eqos_init_dma_chan_ops(OSI_UNUSED struct dma_chan_ops *ops) -#endif /* !OSI_STRIPPED_LIB */ { -#ifndef OSI_STRIPPED_LIB ops->config_slot = eqos_config_slot; -#endif /* !OSI_STRIPPED_LIB */ #ifdef OSI_DEBUG ops->debug_intr_config = eqos_debug_intr_config; #endif } +#endif /* !OSI_STRIPPED_LIB */ diff --git a/osi/dma/mgbe_dma.c b/osi/dma/mgbe_dma.c index c061e31..997d49e 100644 --- a/osi/dma/mgbe_dma.c +++ b/osi/dma/mgbe_dma.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2022, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2020-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"), @@ -20,12 +20,12 @@ * DEALINGS IN THE SOFTWARE. */ +#ifndef OSI_STRIPPED_LIB #include "../osi/common/common.h" #include <osi_common.h> #include "mgbe_dma.h" #include "dma_local.h" -#ifndef OSI_STRIPPED_LIB /** * @brief mgbe_config_slot - Configure slot Checking for DMA channel * @@ -67,7 +67,6 @@ static void mgbe_config_slot(struct osi_dma_priv_data *osi_dma, MGBE_DMA_CHX_SLOT_CTRL(chan)); } } -#endif #ifdef OSI_DEBUG /** @@ -118,16 +117,11 @@ static void mgbe_debug_intr_config(struct osi_dma_priv_data *osi_dma) } #endif -#ifndef OSI_STRIPPED_LIB void mgbe_init_dma_chan_ops(struct dma_chan_ops *ops) -#else -void mgbe_init_dma_chan_ops(OSI_UNUSED struct dma_chan_ops *ops) -#endif { -#ifndef OSI_STRIPPED_LIB ops->config_slot = mgbe_config_slot; -#endif #ifdef OSI_DEBUG ops->debug_intr_config = mgbe_debug_intr_config; #endif }; +#endif /* !OSI_STRIPPED_LIB */ diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 337aa43..64b39e0 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2022, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -280,13 +280,14 @@ nve32_t osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) const nveu32_t default_rz[] = { EQOS_DEFAULT_RING_SZ, MGBE_DEFAULT_RING_SZ }; const nveu32_t max_rz[] = { EQOS_DEFAULT_RING_SZ, MGBE_MAX_RING_SZ }; struct dma_local *l_dma = (struct dma_local *)(void *)osi_dma; - typedef void (*init_ops_arr)(struct dma_chan_ops *temp); static struct dma_chan_ops dma_gops[MAX_MAC_IP_TYPES]; - nve32_t ret = 0; - +#ifndef OSI_STRIPPED_LIB + typedef void (*init_ops_arr)(struct dma_chan_ops *temp); const init_ops_arr i_ops[MAX_MAC_IP_TYPES] = { eqos_init_dma_chan_ops, mgbe_init_dma_chan_ops }; +#endif + nve32_t ret = 0; if (osi_dma == OSI_NULL) { ret = -1; @@ -340,9 +341,9 @@ nve32_t osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) ret = -1; goto fail; } - +#ifndef OSI_STRIPPED_LIB i_ops[osi_dma->mac](&dma_gops[osi_dma->mac]); - +#endif if (init_desc_ops(osi_dma) < 0) { OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, "DMA desc ops init failed\n", 0ULL); From e72eaed099c9d82359b075522af68ba9ba77e94c Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Mon, 23 Jan 2023 10:57:31 +0530 Subject: [PATCH 453/458] osi: core: move vlan_filter.c and debug.c out of safety vlan_filter.c and debug.c files not used for safety builds. Move this out of safety build compilation Bug 3949980 Change-Id: I1bc177dc62be55b409d9a2dd5db551fc20828ac1 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2847416 Reviewed-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> --- osi/core/Makefile.tmk | 31 +++++++++++++++++++------------ osi/core/eqos_core.c | 3 +-- osi/core/mgbe_core.c | 3 +-- osi/core/osi_hal.c | 5 +++-- osi/core/vlan_filter.c | 4 ++-- 5 files changed, 26 insertions(+), 20 deletions(-) diff --git a/osi/core/Makefile.tmk b/osi/core/Makefile.tmk index d6389ff..ecb6fcf 100644 --- a/osi/core/Makefile.tmk +++ b/osi/core/Makefile.tmk @@ -30,18 +30,16 @@ 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/core/eqos_core.c \ + $(NV_SOURCE)/nvethernetrm/osi/core/eqos_mmc.c \ + $(NV_SOURCE)/nvethernetrm/osi/core/osi_core.c \ + $(NV_SOURCE)/nvethernetrm/osi/core/osi_hal.c \ + $(NV_SOURCE)/nvethernetrm/osi/core/ivc_core.c \ + $(NV_SOURCE)/nvethernetrm/osi/core/frp.c \ + $(NV_SOURCE)/nvethernetrm/osi/core/mgbe_core.c \ + $(NV_SOURCE)/nvethernetrm/osi/core/xpcs.c \ + $(NV_SOURCE)/nvethernetrm/osi/core/mgbe_mmc.c \ + $(NV_SOURCE)/nvethernetrm/osi/core/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 \ @@ -53,6 +51,15 @@ NV_COMPONENT_INCLUDES := \ include $(NV_SOURCE)/nvethernetrm/include/config.tmk +ifeq ($(OSI_DEBUG),1) +NV_COMPONENT_SOURCES += $(NV_SOURCE)/nvethernetrm/osi/core/debug.c +endif + +ifeq ($(OSI_STRIPPED_LIB),0) +NV_COMPONENT_SOURCES += \ + $(NV_SOURCE)/nvethernetrm/osi/core/vlan_filter.c +endif + include $(NV_BUILD_STATIC_LIBRARY) endif diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 32c076c..2af3580 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2022, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -26,7 +26,6 @@ #include "eqos_core.h" #include "eqos_mmc.h" #include "core_local.h" -#include "vlan_filter.h" #include "core_common.h" #include "macsec.h" diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index f7ade6a..a2e1a5b 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2022, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2020-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"), @@ -28,7 +28,6 @@ #include "core_local.h" #include "xpcs.h" #include "mgbe_mmc.h" -#include "vlan_filter.h" #include "core_common.h" #include "macsec.h" diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index ea6cc12..b3916d4 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -24,7 +24,6 @@ #include <ivc_core.h> #include "core_local.h" #include "../osi/common/common.h" -#include "vlan_filter.h" #include "core_common.h" #include "eqos_core.h" #include "mgbe_core.h" @@ -32,7 +31,9 @@ #ifdef OSI_DEBUG #include "debug.h" #endif /* OSI_DEBUG */ - +#ifndef OSI_STRIPPED_LIB +#include "vlan_filter.h" +#endif /** * @brief g_ops - Static core operations array. */ diff --git a/osi/core/vlan_filter.c b/osi/core/vlan_filter.c index 03ea908..9f8fdaf 100644 --- a/osi/core/vlan_filter.c +++ b/osi/core/vlan_filter.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2022, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2020-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"), @@ -20,10 +20,10 @@ * DEALINGS IN THE SOFTWARE. */ +#ifndef OSI_STRIPPED_LIB #include "../osi/common/common.h" #include "vlan_filter.h" -#ifndef OSI_STRIPPED_LIB /** * @brief get_vlan_filter_idx - Get VLAN HW filter index which match vlan_id * From e7cfc9816e001d917e4e91078cd6a04133ec5a31 Mon Sep 17 00:00:00 2001 From: Bibhay Ranjan <bibhayr@nvidia.com> Date: Thu, 17 Nov 2022 16:39:49 +0530 Subject: [PATCH 454/458] nvethernetrm: Log compilation using LOG_OSI flag Based on the cflag LOG_OSI logging code will be compiled Bug 3759976 Bug 3954687 Change-Id: Ief57c926bc4d3b1d0d251e5da77d0eb73d928d62 Signed-off-by: Bibhay Ranjan <bibhayr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2811077 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/config.tmk | 2 ++ include/osi_core.h | 5 +++++ include/osi_dma.h | 7 ++++++- osi/core/eqos_core.c | 1 + osi/core/macsec.c | 9 ++++++--- osi/core/mgbe_core.c | 1 + osi/core/osi_core.c | 3 ++- osi/core/osi_hal.c | 1 + osi/dma/osi_dma.c | 1 + osi/dma/osi_dma_txrx.c | 3 ++- 10 files changed, 27 insertions(+), 6 deletions(-) diff --git a/include/config.tmk b/include/config.tmk index 02027bf..8df4e70 100644 --- a/include/config.tmk +++ b/include/config.tmk @@ -36,6 +36,8 @@ else endif NV_COMPONENT_CFLAGS += -DHSI_SUPPORT NV_COMPONENT_CFLAGS += -DMACSEC_SUPPORT +NV_COMPONENT_CFLAGS += -DLOG_OSI + #NV_COMPONENT_CFLAGS += -DMACSEC_KEY_PROGRAM HSI_SUPPORT := 1 MACSEC_SUPPORT := 1 diff --git a/include/osi_core.h b/include/osi_core.h index b7fe608..f5e08f5 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -275,6 +275,7 @@ typedef my_lint_64 nvel64_t; #define OSI_CMD_READ_STATS 56U /** @} */ +#ifdef LOG_OSI /** * @brief OSI error macro definition, * @param[in] priv: OSD private data OR NULL @@ -300,6 +301,10 @@ typedef my_lint_64 nvel64_t; osi_core->osd_ops.ops_log(priv, __func__, __LINE__, \ OSI_LOG_INFO, type, err, loga); \ } +#else +#define OSI_CORE_ERR(priv, type, err, loga) +#define OSI_CORE_INFO(priv, type, err, loga) +#endif #define VLAN_NUM_VID 4096U #define OSI_DELAY_1000US 1000U diff --git a/include/osi_dma.h b/include/osi_dma.h index 1a8871f..9151c39 100644 --- a/include/osi_dma.h +++ b/include/osi_dma.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2022, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -66,6 +66,7 @@ #define OSI_VM_IRQ_RX_CHAN_MASK(x) OSI_BIT(((x) * 2U) + 1U) /** @} */ +#ifdef LOG_OSI /** * OSI error macro definition, * @param[in] priv: OSD private data OR NULL @@ -93,6 +94,10 @@ OSI_LOG_INFO, type, err, loga);\ } #endif /* !OSI_STRIPPED_LIB */ +#else +#define OSI_DMA_ERR(priv, type, err, loga) +#endif /* LOG_OSI */ + /** * @addtogroup EQOS-PKT Packet context fields * diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 2af3580..f1a28fe 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -4106,6 +4106,7 @@ static nve32_t eqos_post_pad_calibrate( */ static nve32_t eqos_config_rss(struct osi_core_priv_data *osi_core) { + (void) osi_core; OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "RSS not supported by EQOS\n", 0ULL); diff --git a/osi/core/macsec.c b/osi/core/macsec.c index 3b1331f..9c0e9d3 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2021-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"), @@ -26,13 +26,13 @@ #include "../osi/common/common.h" #include "core_local.h" -#if defined(DEBUG_MACSEC) && defined(QNX_OS) +#if 0 /* Qnx */ #define MACSEC_LOG(...) \ { \ slogf(0, 6, ##__VA_ARGS__); \ } -#elif defined(DEBUG_MACSEC) && defined(LINUX_OS) +#elif 0 /* Linux */ #include <linux/printk.h> #define MACSEC_LOG(...) \ { \ @@ -484,6 +484,7 @@ static nve32_t validate_inputs_macsec_dbg_buf_conf( { nve32_t ret = 0; + (void) osi_core; /* Validate inputs */ if ((dbg_buf_config->rw > OSI_RW_MAX) || (dbg_buf_config->ctlr_sel > OSI_CTLR_SEL_MAX)) { @@ -3183,6 +3184,7 @@ static inline void handle_tx_sc_invalid_key( static inline void handle_safety_err_irq( const struct osi_core_priv_data *const osi_core) { + (void) osi_core; OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, "Safety Error Handler \n", 0ULL); MACSEC_LOG("%s()\n", __func__); @@ -4877,6 +4879,7 @@ exit: static void print_error(const struct osi_core_priv_data *const osi_core, nve32_t ret) { + (void) osi_core; if (ret < 0) { OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, "Failed to config macsec\n", (nveul64_t)ret); diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index a2e1a5b..e2e1d28 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -215,6 +215,7 @@ static nve32_t mgbe_filter_args_validate(struct osi_core_priv_data *const osi_co nveu32_t dma_chansel = filter->dma_chansel; nve32_t ret = 0; + (void) osi_core; /* 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, diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index dbc3036..6248188 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2022, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -57,6 +57,7 @@ static nve32_t validate_if_func_ptrs(struct osi_core_priv_data *const osi_core, ret = -1; goto fail; #endif + (void) osi_core; for (i = 0; i < (sizeof(*if_ops_p) / (nveu64_t)__SIZEOF_POINTER__); i++) { diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index b3916d4..828d7a1 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -98,6 +98,7 @@ static nve32_t validate_func_ptrs(struct osi_core_priv_data *const osi_core, ret = -1; goto fail; #endif + (void) osi_core; for (i = 0; i < (sizeof(*ops_p) / (nveu64_t)__SIZEOF_POINTER__); i++) { if (*l_ops == 0U) { diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c index 64b39e0..be19708 100644 --- a/osi/dma/osi_dma.c +++ b/osi/dma/osi_dma.c @@ -259,6 +259,7 @@ static nve32_t validate_func_ptrs(struct osi_dma_priv_data *osi_dma, "DMA: Undefined architecture\n", 0ULL); return -1; #endif + (void) osi_dma; for (i = 0; i < (sizeof(*ops_p) / (nveu64_t)__SIZEOF_POINTER__); i++) { if (*l_ops == 0U) { diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c index 6cd651f..93c529e 100644 --- a/osi/dma/osi_dma_txrx.c +++ b/osi/dma/osi_dma_txrx.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2022, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -930,6 +930,7 @@ static inline nve32_t validate_ctx(const struct osi_dma_priv_data *const osi_dma { nve32_t ret = 0; + (void) osi_dma; 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)) { From 42e38be8fa379df17009e966c8991addecceaffa Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Tue, 24 Jan 2023 17:15:04 +0530 Subject: [PATCH 455/458] osi: core: mgbe: Fix 9K Jumbo issue Issue: Not able to transfer 9K Jumbo frame. Currently each TxQ is divided into 12KB of size which leads to not making use of 8KB in total which is affecting 9K Jumbo Fix: Instead of using 12KB per TxQ, 128KB is equally divided among 10 Tx Ques. Bug 3934258 Change-Id: I86623e2726789d42a683aa755f47d77e04391dc1 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2848255 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/mgbe_core.c | 4 ++-- osi/core/mgbe_core.h | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index e2e1d28..a106c99 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -1200,8 +1200,8 @@ static nve32_t mgbe_configure_mtl_queue(struct osi_core_priv_data *osi_core, FIFO_SZ(2U), FIFO_SZ(2U), FIFO_SZ(2U), FIFO_SZ(2U), FIFO_SZ(16U), }; const nveu32_t tx_fifo_sz[OSI_MGBE_MAX_NUM_QUEUES] = { - FIFO_SZ(12U), FIFO_SZ(12U), FIFO_SZ(12U), FIFO_SZ(12U), FIFO_SZ(12U), - FIFO_SZ(12U), FIFO_SZ(12U), FIFO_SZ(12U), FIFO_SZ(12U), FIFO_SZ(12U), + TX_FIFO_SZ, TX_FIFO_SZ, TX_FIFO_SZ, TX_FIFO_SZ, TX_FIFO_SZ, + TX_FIFO_SZ, TX_FIFO_SZ, TX_FIFO_SZ, TX_FIFO_SZ, TX_FIFO_SZ, }; const nveu32_t rfd_rfa[OSI_MGBE_MAX_NUM_QUEUES] = { FULL_MINUS_32_K, diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 2be5f41..728c7ec 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2022, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2020-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"), @@ -738,6 +738,9 @@ /** @} */ #endif /* !OSI_STRIPPED_LIB */ +/* TXQ Size 128KB is divided equally across 10 MTL Queues*/ +#define TX_FIFO_SZ (((((128U * 1024U)/OSI_MGBE_MAX_NUM_QUEUES)) / 256U) - 1U) + /** * @addtogroup MGBE-MAC MGBE MAC HW feature registers * From 20a37c52104ec954bc7ef70121d8ed83000f7a4e Mon Sep 17 00:00:00 2001 From: Narayan Reddy <narayanr@nvidia.com> Date: Mon, 23 Jan 2023 01:03:54 +0530 Subject: [PATCH 456/458] osi: core: fix Doxygen warnings 1) Fix Doxygen warnings 2) include debug.h code only when OSI_DEBUG is defined JIRA NET-570 Change-Id: I5d002b959925bec3898cc2faafe3f506b3c9bd22 Signed-off-by: Narayan Reddy<narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2847327 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- include/osi_common.h | 5 +++-- include/osi_core.h | 6 ++---- include/osi_macsec.h | 9 +++++---- osi/common/common.h | 10 ++++++---- osi/common/mgbe_common.h | 4 ++-- osi/core/core_common.c | 8 +++++--- osi/core/debug.h | 4 +++- osi/core/eqos_core.c | 8 +++----- osi/core/eqos_core.h | 6 +++--- osi/core/frp.c | 8 +++++++- osi/core/ivc_core.c | 13 +++++-------- osi/core/macsec.c | 4 +++- osi/core/macsec.h | 12 ++---------- osi/core/mgbe_core.c | 27 ++++++++++++--------------- osi/core/mgbe_core.h | 10 +++++----- osi/core/osi_core.c | 2 ++ osi/core/osi_hal.c | 4 ++-- 17 files changed, 70 insertions(+), 70 deletions(-) diff --git a/include/osi_common.h b/include/osi_common.h index 4ac83ca..14050eb 100644 --- a/include/osi_common.h +++ b/include/osi_common.h @@ -153,9 +153,9 @@ /** @} */ /** - * @addtogroup Helper Helper MACROS + * @addtogroup Generic helper MACROS * - * @brief EQOS generic helper MACROS. + * @brief These are Generic helper macros used at various places. * @{ */ #define OSI_UCHAR_MAX (0xFFU) @@ -253,6 +253,7 @@ #define OSI_DEBUG_TYPE_REG 2U #define OSI_DEBUG_TYPE_STRUCTS 3U #endif /* OSI_DEBUG */ +/** @} */ /** * @brief unused function attribute diff --git a/include/osi_core.h b/include/osi_core.h index f5e08f5..97e13b7 100644 --- a/include/osi_core.h +++ b/include/osi_core.h @@ -155,7 +155,7 @@ typedef my_lint_64 nvel64_t; /** @} */ /** - * @addtogroup Helper Helper MACROS + * @addtogroup Helper MACROS * * @brief EQOS generic helper MACROS. * @{ @@ -311,7 +311,7 @@ typedef my_lint_64 nvel64_t; #define OSI_DELAY_1US 1U /** - * @addtogroup PTP related information + * @addtogroup PTP PTP related information * * @brief PTP SSINC values * @{ @@ -1396,8 +1396,6 @@ struct osi_core_priv_data { * - 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() diff --git a/include/osi_macsec.h b/include/osi_macsec.h index 8bb0f86..d3598cd 100644 --- a/include/osi_macsec.h +++ b/include/osi_macsec.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2021-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"), @@ -99,7 +99,7 @@ /** @} */ /** - * @addtogroup Generic table CONFIG register helpers macros + * @addtogroup MACSEC-Generic table CONFIG register helpers macros * * @brief Helper macros for generic table CONFIG register programming * @{ @@ -154,9 +154,9 @@ /** @} */ /** - * @addtogroup MACSEC Misc helper macro's + * @addtogroup MACSEC related helper MACROs * - * @brief MACSEC Helper macro's + * @brief MACSEC generic helper MACROs * @{ */ #define OSI_MACSEC_TX_EN OSI_BIT(0) @@ -644,6 +644,7 @@ nve32_t osi_macsec_en(struct osi_core_priv_data *const osi_core, * * @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] enable: macsec enable/disable selection * @param[in] ctlr: Controller selected * @param[out] kt_idx: Pointer to the kt_index passed to OSD * diff --git a/osi/common/common.h b/osi/common/common.h index 8bdfebe..31de8d2 100644 --- a/osi/common/common.h +++ b/osi/common/common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2022, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2020-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"), @@ -26,7 +26,7 @@ #include <osi_common.h> /** - * @addtogroup Generic helper macros + * @addtogroup Generic helper MACROS * * @brief These are Generic helper macros used at various places. * @{ @@ -54,8 +54,9 @@ * a condition is met or a timeout occurs * * @param[in] addr: Memory mapped address. + * @param[in] fn: function to be used. * @param[in] val: Variable to read the value. - * @param[in] cond: Break condition (usually involving @val). + * @param[in] cond: Break condition. * @param[in] delay_us: Maximum time to sleep between reads in us. * @param[in] retry: Retry count. @@ -240,7 +241,8 @@ static inline void osi_writela(OSI_UNUSED void *priv, nveu32_t val, void *addr) * @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. + * @param[out] num_max_chans: Maximum channel number. + * @param[out] l_mac_ver: local mac version. * * @note MAC has to be out of reset. * diff --git a/osi/common/mgbe_common.h b/osi/common/mgbe_common.h index 7ebffeb..5ba8380 100644 --- a/osi/common/mgbe_common.h +++ b/osi/common/mgbe_common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2020-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"), @@ -24,7 +24,7 @@ #define INCLUDED_MGBE_COMMON_H /** - * @addtogroup MGBE-MAC MGBE MAC common HW feature registers + * @addtogroup MGBE-MAC MAC register offsets * * @{ */ diff --git a/osi/core/core_common.c b/osi/core/core_common.c index 485fb52..02fbfaf 100644 --- a/osi/core/core_common.c +++ b/osi/core/core_common.c @@ -613,7 +613,7 @@ fail: * @brief hw_est_read - indirect read the GCL to Software own list * (SWOL) * - * @param[in] base: MAC base IOVA address. + * @param[in] osi_core: OSI core private data structure. * @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. @@ -677,6 +677,7 @@ err: * * @param[in] osi_core: OSI core private data structure. * @param[in] est: Configuration input argument. + * @param[in] btr: Base time register value. * @param[in] mac: MAC index * * @note MAC should be init and started. see osi_start_mac() @@ -858,7 +859,7 @@ done: * @brief hw_est_write - indirect write the GCL to Software own list * (SWOL) * - * @param[in] base: MAC base IOVA address. + * @param[in] osi_core: OSI core private data structure. * @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. @@ -1732,7 +1733,8 @@ static void prepare_l4_port_register(const struct osi_l3_l4_filter *const l3_l4, * * @param[in] osi_core: OSI core private data structure. * @param[in] l3_l4: Pointer to l3 l4 filter structure (#osi_l3_l4_filter) - * @param[out] l4_addr_reg: Pointer to L3 ADDR0 register value + * @param[out] l3_addr1_reg: Pointer to L3 ADDR1 register value + * @param[out] ctr_reg: Pointer to L3L4 CTR register value * * @note 1) MAC should be init and started. see osi_start_mac() * 2) osi_core->osd should be populated diff --git a/osi/core/debug.h b/osi/core/debug.h index 5029510..60d06e1 100644 --- a/osi/core/debug.h +++ b/osi/core/debug.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2021-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"), @@ -20,6 +20,7 @@ * DEALINGS IN THE SOFTWARE. */ +#ifdef OSI_DEBUG #ifndef INCLUDED_CORE_DEBUG_H #define INCLUDED_CORE_DEBUG_H @@ -32,3 +33,4 @@ 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*/ +#endif /* OSI_DEBUG */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index f1a28fe..2d987fe 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -533,7 +533,7 @@ done: * Algorithm: * * @param[in] osi_core: OSI core private data. - * @param[in] enabled: Flag to indicate feature is to be enabled/disabled. + * @param[in] nve: Number of Valid Entries. * * @note MAC should be init and started. see osi_start_mac() * @@ -1243,8 +1243,6 @@ static void eqos_dma_chan_to_vmirq_map(struct osi_core_priv_data *osi_core) * @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() @@ -1990,9 +1988,9 @@ static void eqos_config_mac_tx(struct osi_core_priv_data *const osi_core, * @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. + * @param[in] src_dest: source/destination MAC address. * * @pre * - MAC should be initialized and started. see osi_start_mac() @@ -2066,7 +2064,7 @@ static inline nve32_t eqos_update_mac_addr_helper( * * @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] filter_idx: filter index * @param[in] dma_routing_enable: dma channel routing enable(1) * @param[in] dma_chan: dma channel number * diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h index b3229d9..68000e8 100644 --- a/osi/core/eqos_core.h +++ b/osi/core/eqos_core.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2022, NVIDIA CORPORATION. All rights reserved. + * 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"), @@ -158,9 +158,9 @@ #define EQOS_MTL_FRP_IE2_DCH_SHIFT 24U #define EQOS_DMA_ISR_MTLIS OSI_BIT(16) /** - * @addtogroup EQOS-MTL FRP Indirect Access register defines + * @addtogroup EQOS-MTL-FRP FRP Indirect Access register defines * - * @brief EQOS MTL register offsets + * @brief EQOS MTL FRP register defines * @{ */ #define EQOS_MTL_FRP_READ_UDELAY 1U diff --git a/osi/core/frp.c b/osi/core/frp.c index 4af72b3..dcf825c 100644 --- a/osi/core/frp.c +++ b/osi/core/frp.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2022, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2020-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"), @@ -210,6 +210,7 @@ static void frp_entry_mode_parse(nveu8_t filter_mode, * * @param[in] osi_core: OSI core private data structure. * @param[in] frp_id: FRP ID to add. + * @param[in] pos: FRP entry position. * @param[in] match: Pointer to match data. * @param[in] length: Match data length. * @param[in] offset: Actual match data offset position. @@ -373,6 +374,7 @@ done: * Algorithm: Update FRP table into HW. * * @param[in] osi_core: OSI core private data structure. + * @param[in] ops_p: Core operations data structure. * * @retval 0 on success. * @retval -1 on failure. @@ -602,6 +604,7 @@ static void frp_parse_mtype(struct osi_core_frp_cmd *const cmd) * 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] ops_p: Core operations data structure. * @param[in] cmd: OSI FRP command structure. * * @retval 0 on success. @@ -675,6 +678,7 @@ done: * 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] ops_p: Core operations data structure. * @param[in] cmd: OSI FRP command structure. * * @retval 0 on success. @@ -763,6 +767,7 @@ done: * 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] ops_p: Core operations data structure. * @param[in] cmd: OSI FRP command structure. * * @retval 0 on success. @@ -840,6 +845,7 @@ done: * Algorithm: Parse give FRP command and update it on OSI data and HW. * * @param[in] osi_core: OSI core private data structure. + * @param[in] ops_p: Core operations data structure. * @param[in] cmd: OSI FRP command structure. * * @retval 0 on success. diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c index 7b4a2a5..555b023 100644 --- a/osi/core/ivc_core.c +++ b/osi/core/ivc_core.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2022, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2020-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"), @@ -91,8 +91,6 @@ static nve32_t ivc_handle_ioctl(struct osi_core_priv_data *osi_core, * @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. @@ -303,10 +301,9 @@ static void ivc_macsec_read_mmc(struct osi_core_priv_data *const osi_core) * @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] sci: Secure Channel info. + * @param[out] key_index: Key table index to program SAK. * @param[in] ctlr: Controller instance. - * @param[[out] kt_idx: Key table index to program SAK. * * @retval 0 on Success * @retval -1 on Failure @@ -341,7 +338,7 @@ static nve32_t ivc_get_sc_lut_key_index(struct osi_core_priv_data *const osi_cor * @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. + * @param[out] kt_idx: Key table index to program SAK. * * @retval 0 on Success * @retval -1 on Failure @@ -556,7 +553,7 @@ static nve32_t ivc_macsec_deinit(struct osi_core_priv_data *const osi_core) * @brief ivc_macsec_init -Initialize. * * @param[in] osi_core: OSI Core private data structure. - * @param[in] genl_info: Generic netlink information structure. + * @param[in] mtu: mtu to be set. * * @retval 0 on Success * @retval -1 on Failure diff --git a/osi/core/macsec.c b/osi/core/macsec.c index 9c0e9d3..e2f039f 100644 --- a/osi/core/macsec.c +++ b/osi/core/macsec.c @@ -4927,7 +4927,7 @@ static void copy_rev_order(nveu8_t *dst_buff, const nveu8_t *src_buff, nveu16_t * - TraceID: *********** * * @param[in] osi_core: OSI core private data structure. used param macsec_base - * @param[in] error_mask: Error mask that indicate which LUTs need to be cleared + * @param[in] mask: Error mask that indicate which LUTs need to be cleared * @param[in] ctlr: Controller to be selected * @param[in] sc: Pointer to the SC that was intended to be added * @@ -5339,6 +5339,7 @@ exit: * * @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] enable: enable or disable * @param[in] ctlr: Controller to be selected * @param[out] kt_idx: Key index to be passed to osd * @@ -5899,6 +5900,7 @@ exit: * * @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] enable: enable or disable * @param[in] ctlr: Controller selected * @param[out] kt_idx: Pointer to the kt_index passed to OSD * diff --git a/osi/core/macsec.h b/osi/core/macsec.h index 95ba892..aabe9a2 100644 --- a/osi/core/macsec.h +++ b/osi/core/macsec.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2021-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"), @@ -381,15 +381,7 @@ #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 + * @addtogroup MACSEC-LUT TX/RX LUT bit fields in LUT_DATA registers * * @brief Helper macros for LUT data programming * @{ diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index a106c99..ebb0660 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -38,7 +38,7 @@ * 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. + * @param[in] osi_core: osi core priv data structure * * @note MAC needs to be out of reset and proper clock configured. * @@ -75,7 +75,7 @@ static nve32_t mgbe_poll_for_mac_acrtl(struct osi_core_priv_data *osi_core) * * Algorithm: writes MAC Indirect AC register * - * @param[in] base: MGBE virtual base address. + * @param[in] osi_core: osi core priv data structure * @param[in] mc_no: MAC AC Mode Select number * @param[in] addr_offset: MAC AC Address Offset. * @param[in] value: MAC AC register value @@ -134,7 +134,7 @@ static nve32_t mgbe_mac_indir_addr_write(struct osi_core_priv_data *osi_core, * * Algorithm: Reads MAC Indirect AC register * - * @param[in] base: MGBE virtual base address. + * @param[in] osi_core: osi core priv data structure * @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 @@ -387,7 +387,7 @@ fail: * 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. + * @param[in] osi_core: osi core priv data structure * * @note MAC needs to be out of reset and proper clock configured. * @@ -433,7 +433,7 @@ fail: * * Algorithm: writes L3_L4 filter register * - * @param[in] base: MGBE virtual base address. + * @param[in] osi_core: osi core priv data structure * @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 @@ -1119,8 +1119,8 @@ done: * * Algorithm: * - * @param[in] addr: MGBE virtual base address. - * @param[in] enabled: Flag to indicate feature is to be enabled/disabled. + * @param[in] osi_core: osi core priv data structure + * @param[in] nve: Number of Valid Entries. * * @note MAC should be init and started. see osi_start_mac() * @@ -1171,9 +1171,8 @@ done: * 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] osi_core: OSI core private data structure. + * @param[in] hw_qinx: Queue number that need to be configured. * * @note MAC has to be out of reset. * @@ -2172,7 +2171,6 @@ static inline nveu32_t get_free_ts_idx(struct core_local *l_core) * 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 */ @@ -2629,6 +2627,7 @@ fail: * There is one status interrupt which says swich to SWOL complete. * * @param[in] osi_core: osi core priv data structure + * @param[in] mtl_isr: MTL interrupt status value * * @note MAC should be init and started. see osi_start_mac() */ @@ -3644,8 +3643,7 @@ static nve32_t mgbe_get_hw_features(struct osi_core_priv_data *const osi_core, * 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] osi_core: OSI core private data structure. * @param[in] mac_tcr: Address to store time stamp control register read value * * @note MAC should be init and started. see osi_start_mac() @@ -3681,8 +3679,7 @@ static inline nve32_t mgbe_poll_for_update_ts_complete( * * 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] osi_core: OSI core private data structure. * @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 diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h index 728c7ec..691432b 100644 --- a/osi/core/mgbe_core.h +++ b/osi/core/mgbe_core.h @@ -249,9 +249,9 @@ OSI_BIT(5) | OSI_BIT(4)) /** - * @addtogroup MGBE-MTL FRP Indirect Access register defines + * @addtogroup MGBE-MTL-FRP FRP Indirect Access register defines * - * @brief MGBE MTL register offsets + * @brief MGBE MTL FRP register defines * @{ */ #define MGBE_MTL_FRP_READ_UDELAY 1U @@ -390,7 +390,7 @@ /** - * @addtogroup MGBE MAC Mode Select Group + * @addtogroup MGBE-MAC-MODE MAC Mode Select Group * * @brief MGBE MAC Indirect Access control and status for * Mode Select type defines. @@ -416,7 +416,7 @@ /** @} */ /** - * @addtogroup MGBE MAC L3L4 defines + * @addtogroup MGBE-L3L4 MAC L3L4 defines * * @brief MGBE L3L4 Address Control register * IDDR filter filed type defines @@ -742,7 +742,7 @@ #define TX_FIFO_SZ (((((128U * 1024U)/OSI_MGBE_MAX_NUM_QUEUES)) / 256U) - 1U) /** - * @addtogroup MGBE-MAC MGBE MAC HW feature registers + * @addtogroup MGBE-MAC-HWFR MGBE MAC HW feature registers * * @brief Helps in identifying the features that are set in MAC HW * @{ diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 6248188..5726985 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -31,6 +31,7 @@ static struct core_local g_core[MAX_CORE_INSTANCES]; * @brief Function to validate function pointers. * * @param[in] osi_core: OSI Core private data structure. + * @param[in] if_ops_p: pointer to interface core operations. * * @note * API Group: @@ -78,6 +79,7 @@ fail: * @brief Function to validate input arguments of API. * * @param[in] osi_core: OSI Core private data structure. + * @param[in] l_core: Core local private data structure. * * @note * API Group: diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 828d7a1..bc16017 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -813,7 +813,7 @@ static nve32_t l3l4_find_match(const struct core_local *const l_core, * - Return -1 if parameter validation fails. * - Return 0 on success. * - * @param[inout] l_core: OSI local core data structure. + * @param[in] osi_core: OSI core private data structure. * @param[in] l3_l4: Pointer to l3 l4 filter structure (#osi_l3_l4_filter) * * @pre @@ -896,7 +896,7 @@ exit_func: * - Store the filter into l_core->cfg.l3_l4[] and enable * l3l4 filter if any of the filter index enabled currently. * - * @param[inout] l_core: OSI local core data structure. + * @param[in] osi_core: OSI core private data structure. * @param[in] filter_no: pointer to filter number * @param[in] l3_l4: Pointer to l3 l4 filter structure (#osi_l3_l4_filter) * From dbe4bb73da774dd11394d75ffcf0ec98038e68eb Mon Sep 17 00:00:00 2001 From: Hareesh Kesireddy <hkesireddy@nvidia.com> Date: Sun, 4 Dec 2022 20:47:33 +0530 Subject: [PATCH 457/458] osi: l3l4: fix wildcard filter setup Issue description: - If a filter index is configured for L3+L4(UDP) with 4 tuple to route packets to a dma channel, then all incoming TCP packets are also getting routed to the same dma channel as Hw is finding match for L3 filter and ignoring L4 filter since it is configured for UDP. Fix description: - To avoid above issue, configured TCP wildcard filter at index 0 with below configuration. L3 (IP4): Inverse SA (0x0) + Inverse DA (0x0). L4 (UDP): Perfect SP (0x0) + Perfect DP (x0). - If IPFE is not enabled, HW is not dropping any udp/tcp packets irrespective of l3l4 match status. Hence generic l3l4 wildcard filter at highest filter index is not needed. Removed generic l3l4 wildcard filter. Bug 3576506 Bug 3825731 Change-Id: I49d0072c269294822f0984f33756aed04207f6ed Signed-off-by: Hareesh Kesireddy <hkesireddy@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2821504 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/core_local.h | 6 ++-- osi/core/osi_hal.c | 64 +++++++++++++++++++++---------------------- 2 files changed, 34 insertions(+), 36 deletions(-) diff --git a/osi/core/core_local.h b/osi/core/core_local.h index 0a8510e..fce6b6d 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2021-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"), @@ -380,12 +380,10 @@ struct core_local { nveu32_t lane_status; /** Exact MAC used across SOCs 0:Legacy EQOS, 1:Orin EQOS, 2:Orin MGBE */ nveu32_t l_mac_ver; -#ifndef OSI_STRIPPED_LIB -#ifdef L3L4_WILDCARD_FILTER +#if defined(L3L4_WILDCARD_FILTER) /** l3l4 wildcard filter configured (OSI_ENABLE) / not configured (OSI_DISABLE) */ nveu32_t l3l4_wildcard_filter_configured; #endif /* L3L4_WILDCARD_FILTER */ -#endif /* OSI_STRIPPED_LIB */ }; /** diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index bc16017..99c463e 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -773,11 +773,16 @@ static nve32_t l3l4_find_match(const struct core_local *const l_core, nve32_t ret = -1; nveu32_t found_free_index = 0; nve32_t filter_size = (nve32_t)sizeof(l3_l4->data); +#if defined(L3L4_WILDCARD_FILTER) + nveu32_t start_idx = 1; /* leave first one for TCP wildcard */ +#else + nveu32_t start_idx = 0; +#endif /* L3L4_WILDCARD_FILTER */ /* init free index value to invalid value */ *free_filter_no = UINT_MAX; - for (i = 0; i < max_filter_no; i++) { + for (i = start_idx; i <= max_filter_no; i++) { if (l_core->cfg.l3_l4[i].filter_enb_dis == OSI_FALSE) { /* filter not enabled, save free index */ if (found_free_index == 0U) { @@ -959,14 +964,13 @@ exit_func: return ret; } -#ifndef OSI_STRIPPED_LIB -#ifdef L3L4_WILDCARD_FILTER +#if defined(L3L4_WILDCARD_FILTER) /** * @brief l3l4_add_wildcard_filter - function to configure wildcard filter. * * @note * Algorithm: - * - Configure wildcard filter with all 4 tuple as 0s using configure_l3l4_filter_helper(). + * - Configure TCP wildcard filter at index 0 using configure_l3l4_filter_helper(). * * @param[in] osi_core: OSI Core private data structure. * @param[in] max_filter_no: maximum allowed filter number @@ -977,44 +981,47 @@ exit_func: static void l3l4_add_wildcard_filter(struct osi_core_priv_data *const osi_core, nveu32_t max_filter_no) { - nve32_t err; + nve32_t err = -1; struct osi_l3_l4_filter *l3l4_filter; struct core_local *l_core = (struct core_local *)(void *)osi_core; /* use max filter index to confiture wildcard filter */ if (l_core->l3l4_wildcard_filter_configured != OSI_ENABLE) { - /* configure INV filter for IPV4/UDP with DA(0) + SP (0) + - * DP (0) with routing not enabled + /* Configure TCP wildcard filter at index 0. + * INV IP4 filter with SA (0) + DA (0) with UDP perfect match with + * SP (0) + DP (0) with no routing enabled. + * - TCP packets will have a IP filter match and will be routed to default DMA. + * - UDP packets will have a IP match but no L4 match, hence HW goes for + * next filter index for finding match. */ - l3l4_filter = &(l_core->cfg.l3_l4[max_filter_no]); + l3l4_filter = &(l_core->cfg.l3_l4[0]); osi_memset(l3l4_filter, 0, sizeof(struct osi_l3_l4_filter)); l3l4_filter->filter_enb_dis = OSI_TRUE; l3l4_filter->data.is_udp = OSI_TRUE; - l3l4_filter->data.src.port_match = OSI_TRUE; - l3l4_filter->data.src.port_match_inv = OSI_TRUE; l3l4_filter->data.src.addr_match = OSI_TRUE; l3l4_filter->data.src.addr_match_inv = OSI_TRUE; - l3l4_filter->data.dst.port_match = OSI_TRUE; - l3l4_filter->data.dst.port_match_inv = OSI_TRUE; + l3l4_filter->data.src.port_match = OSI_TRUE; l3l4_filter->data.dst.addr_match = OSI_TRUE; l3l4_filter->data.dst.addr_match_inv = OSI_TRUE; + l3l4_filter->data.dst.port_match = OSI_TRUE; /* configure wildcard at last filter index */ - err = configure_l3l4_filter_helper(osi_core, max_filter_no, l3l4_filter); + err = configure_l3l4_filter_helper(osi_core, 0, l3l4_filter); if (err < 0) { /* wildcard config failed */ OSI_CORE_ERR((osi_core->osd), (OSI_LOG_ARG_INVALID), - ("L3L4: Wildcard config failed: "), (max_filter_no)); - } else { - /* wildcard config success */ - l_core->l3l4_wildcard_filter_configured = OSI_ENABLE; - OSI_CORE_INFO((osi_core->osd), (OSI_LOG_ARG_INVALID), - ("L3L4: Wildcard config success"), (max_filter_no)); + ("L3L4: TCP wildcard config failed: "), (0UL)); } } + + if (err >= 0) { + /* wildcard config success */ + l_core->l3l4_wildcard_filter_configured = OSI_ENABLE; + OSI_CORE_INFO((osi_core->osd), (OSI_LOG_ARG_INVALID), + ("L3L4: Wildcard config success"), (0UL)); + } } #endif /* L3L4_WILDCARD_FILTER */ -#endif /* !OSI_STRIPPED_LIB */ /** * @brief configure_l3l4_filter - function to configure l3l4 filter. @@ -1049,9 +1056,6 @@ static nve32_t configure_l3l4_filter(struct osi_core_priv_data *const osi_core, nveu32_t free_filter_no = UINT_MAX; const struct core_local *l_core = (struct core_local *)(void *)osi_core; const nveu32_t max_filter_no[2] = { - /* max usable filter number is less by 1 for accommodating - * wildcard filter at last index. - */ EQOS_MAX_L3_L4_FILTER - 1U, OSI_MGBE_MAX_L3_L4_FILTER - 1U, }; @@ -1075,7 +1079,7 @@ static nve32_t configure_l3l4_filter(struct osi_core_priv_data *const osi_core, } /* check free index */ - if (free_filter_no >= max_filter_no[osi_core->mac]) { + if (free_filter_no > max_filter_no[osi_core->mac]) { /* no free entry found */ OSI_CORE_INFO((osi_core->osd), (OSI_LOG_ARG_HW_FAIL), ("L3L4: Failed: no free filter: "), (free_filter_no)); @@ -1093,8 +1097,7 @@ static nve32_t configure_l3l4_filter(struct osi_core_priv_data *const osi_core, } } -#ifndef OSI_STRIPPED_LIB -#ifdef L3L4_WILDCARD_FILTER +#if defined(L3L4_WILDCARD_FILTER) /* setup l3l4 wildcard filter for l3l4 */ l3l4_add_wildcard_filter(osi_core, max_filter_no[osi_core->mac]); if (l_core->l3l4_wildcard_filter_configured != OSI_ENABLE) { @@ -1103,7 +1106,6 @@ static nve32_t configure_l3l4_filter(struct osi_core_priv_data *const osi_core, goto exit_func; } #endif /* L3L4_WILDCARD_FILTER */ -#endif /* !OSI_STRIPPED_LIB */ /* configure l3l4 filter */ err = configure_l3l4_filter_helper(osi_core, filter_no, l3_l4); @@ -2105,14 +2107,12 @@ static void cfg_l3_l4_filter(struct core_local *l_core) (struct osi_core_priv_data *)(void *)l_core, i, &l_core->cfg.l3_l4[i]); -#ifdef L3L4_WILDCARD_FILTER -#ifndef OSI_STRIPPED_LIB - if (i == (OSI_MGBE_MAX_L3_L4_FILTER - 1U)) { - /* last filter supposed to be wildcard filter */ +#if defined(L3L4_WILDCARD_FILTER) + if (i == 0U) { + /* first filter supposed to be tcp wildcard filter */ l_core->l3l4_wildcard_filter_configured = OSI_ENABLE; } #endif /* L3L4_WILDCARD_FILTER */ -#endif /* !OSI_STRIPPED_LIB */ } } From 7f3c147bdb4f592d31d065a56c446cc49877c9f9 Mon Sep 17 00:00:00 2001 From: Mohan Thadikamalla <mohant@nvidia.com> Date: Tue, 24 Jan 2023 18:26:40 +0530 Subject: [PATCH 458/458] osi: core: Restore FRP rules on resume Issue: FRP rules got lost during SC7 suspend and resume transition. Fix: Restore FRP rules after resume Bug 3928364 Change-Id: If38ed1c54c19f6cfb9bb00f56c524712e24c1f59 Signed-off-by: Mohan Thadikamalla <mohant@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2848286 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> --- osi/core/core_local.h | 2 ++ osi/core/frp.c | 21 ++------------------- osi/core/frp.h | 15 +++++++-------- osi/core/osi_core.c | 1 + osi/core/osi_hal.c | 15 +++++++++++---- 5 files changed, 23 insertions(+), 31 deletions(-) diff --git a/osi/core/core_local.h b/osi/core/core_local.h index fce6b6d..3677475 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -59,6 +59,7 @@ #define DYNAMIC_CFG_PTP OSI_BIT(7) #define DYNAMIC_CFG_EST OSI_BIT(8) #define DYNAMIC_CFG_FPE OSI_BIT(9) +#define DYNAMIC_CFG_FRP OSI_BIT(10) #ifndef OSI_STRIPPED_LIB #define DYNAMIC_CFG_FC OSI_BIT(1) @@ -76,6 +77,7 @@ #define DYNAMIC_CFG_PTP_IDX 7U #define DYNAMIC_CFG_EST_IDX 8U #define DYNAMIC_CFG_FPE_IDX 9U +#define DYNAMIC_CFG_FRP_IDX 10U #define OSI_SUSPENDED OSI_BIT(0) diff --git a/osi/core/frp.c b/osi/core/frp.c index dcf825c..2dea183 100644 --- a/osi/core/frp.c +++ b/osi/core/frp.c @@ -379,8 +379,8 @@ done: * @retval 0 on success. * @retval -1 on failure. */ -static nve32_t frp_hw_write(struct osi_core_priv_data *const osi_core, - struct core_ops *const ops_p) +nve32_t frp_hw_write(struct osi_core_priv_data *const osi_core, + struct core_ops *const ops_p) { nve32_t ret = 0; nve32_t tmp = 0; @@ -886,20 +886,3 @@ nve32_t setup_frp(struct osi_core_priv_data *const osi_core, 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 index aefdb10..0e902c1 100644 --- a/osi/core/frp.h +++ b/osi/core/frp.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2022, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2020-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"), @@ -69,16 +69,15 @@ nve32_t setup_frp(struct osi_core_priv_data *const osi_core, struct osi_core_frp_cmd *const cmd); /** - * @brief init_frp - Init the FRP Instruction Table. + * @brief frp_hw_write - Update HW FRP table. + * + * Algorithm: Update FRP table into HW. * * @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 0 on success. * @retval -1 on failure. */ -void init_frp(struct osi_core_priv_data *const osi_core); - +nve32_t frp_hw_write(struct osi_core_priv_data *const osi_core, + struct core_ops *const ops_p); #endif /* FRP_H */ diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c index 5726985..f59884d 100644 --- a/osi/core/osi_core.c +++ b/osi/core/osi_core.c @@ -127,6 +127,7 @@ struct osi_core_priv_data *osi_get_core(void) g_core[i].pps_freq = OSI_DISABLE; osi_core = &g_core[i].osi_core; + osi_memset(osi_core, 0, sizeof(struct osi_core_priv_data)); fail: return osi_core; } diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index 99c463e..4364127 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -540,8 +540,6 @@ static nve32_t osi_hal_hw_core_init(struct osi_core_priv_data *const osi_core) #ifndef OSI_STRIPPED_LIB init_vlan_filters(osi_core); - /* Init FRP */ - init_frp(osi_core); #endif /* !OSI_STRIPPED_LIB */ ret = l_core->ops_p->core_init(osi_core); @@ -2205,11 +2203,18 @@ static void cfg_ptp(struct core_local *l_core) (void)osi_handle_ioctl(osi_core, &ioctl_data); } +static void cfg_frp(struct core_local *l_core) +{ + struct osi_core_priv_data *osi_core = (struct osi_core_priv_data *)(void *)l_core; + + (void)frp_hw_write(osi_core, l_core->ops_p); +} + static void apply_dynamic_cfg(struct osi_core_priv_data *osi_core) { struct core_local *l_core = (struct core_local *)(void *)osi_core; typedef void (*cfg_fn)(struct core_local *local_core); - const cfg_fn fn[10] = { + const cfg_fn fn[11] = { [DYNAMIC_CFG_L3_L4_IDX] = cfg_l3_l4_filter, [DYNAMIC_CFG_L2_IDX] = cfg_l2_filter, [DYNAMIC_CFG_RXCSUM_IDX] = cfg_rxcsum, @@ -2221,7 +2226,8 @@ static void apply_dynamic_cfg(struct osi_core_priv_data *osi_core) [DYNAMIC_CFG_AVB_IDX] = cfg_avb, [DYNAMIC_CFG_EST_IDX] = cfg_est, [DYNAMIC_CFG_FPE_IDX] = cfg_fpe, - [DYNAMIC_CFG_PTP_IDX] = cfg_ptp + [DYNAMIC_CFG_PTP_IDX] = cfg_ptp, + [DYNAMIC_CFG_FRP_IDX] = cfg_frp }; nveu32_t flags = l_core->cfg.flags; nveu32_t i = 0U; @@ -2783,6 +2789,7 @@ static nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, #endif /* !OSI_STRIPPED_LIB */ case OSI_CMD_CONFIG_FRP: ret = configure_frp(osi_core, &data->frp_cmd); + l_core->cfg.flags |= DYNAMIC_CFG_FRP; break; case OSI_CMD_CONFIG_EST: