From 2a873b3f3dade8cc59b81c564d3f760c150e9df1 Mon Sep 17 00:00:00 2001 From: nannaiah Date: Thu, 22 Oct 2020 13:20:56 -0700 Subject: [PATCH] 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 Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2435281 Tested-by: mobile promotions Reviewed-by: mobile promotions --- 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 +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 +#include +#include +#include +#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 #include #include +#include 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);