osi: create new lib for T26x EQoS XPCS programming

To support N1Auto platformw hich has different XPCS, seperated out the
T26x EQoS xpcs programming

Bug 4997903

Change-Id: I47d75b66b7c3e7a5b7f2ad2abe8452dd3c2e5656
Signed-off-by: Sanath Kumar Gampa <sgampa@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/3268488
Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Sanath Kumar Gampa
2024-12-16 03:58:26 +00:00
committed by mobile promotions
parent 907228f277
commit 3b9355578b
15 changed files with 752 additions and 288 deletions

View File

@@ -1,6 +1,6 @@
################################### tell Emacs this is a -*- makefile-gmake -*- ################################### tell Emacs this is a -*- makefile-gmake -*-
# #
# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. # Copyright (c) 2019-2025, NVIDIA CORPORATION. All rights reserved.
# #
# Permission is hereby granted, free of charge, to any person obtaining a # Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"), # copy of this software and associated documentation files (the "Software"),
@@ -26,6 +26,7 @@
NV_REPOSITORY_COMPONENTS := \ NV_REPOSITORY_COMPONENTS := \
osi/core \ osi/core \
osi/dma \ osi/dma \
osi/nvxpcsrm \
osi/nvmacsecrm osi/nvmacsecrm
# Local Variables: # Local Variables:

View File

@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: LicenseRef-NvidiaProprietary /* SPDX-License-Identifier: LicenseRef-NvidiaProprietary
* SPDX-FileCopyrightText: Copyright (c) 2018-2024 NVIDIA CORPORATION & AFFILIATES. * SPDX-FileCopyrightText: Copyright (c) 2018-2025 NVIDIA CORPORATION & AFFILIATES.
* All rights reserved. * All rights reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
@@ -349,7 +349,7 @@ static inline void osi_memset(void *s, nveu8_t c, nveu64_t count)
#define OSI_UNUSED __attribute__((__unused__)) #define OSI_UNUSED __attribute__((__unused__))
/** @brief macro for 1 micro second delay */ /** @brief macro for 1 micro second delay */
#define OSI_DELAY_1US 1U #define OSI_DELAY_1US 1U
/** /**
* @addtogroup MGBE PBL settings. * @addtogroup MGBE PBL settings.

View File

@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: LicenseRef-NvidiaProprietary /* SPDX-License-Identifier: LicenseRef-NvidiaProprietary
* SPDX-FileCopyrightText: Copyright (c) 2018-2024 NVIDIA CORPORATION. All rights reserved. * SPDX-FileCopyrightText: Copyright (c) 2018-2025 NVIDIA CORPORATION. All rights reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"), * copy of this software and associated documentation files (the "Software"),
@@ -145,6 +145,40 @@ typedef my_lint_64 nvel64_t;
#endif /* !OSI_STRIPPED_LIB */ #endif /* !OSI_STRIPPED_LIB */
/**
* @addtogroup XPCS related defines
* @{
*/
#define XPCS_REG_ADDR_SHIFT 10U
#define XPCS_REG_ADDR_MASK 0x1FFFU
#define XPCS_ADDRESS 0x03FC
#define XPCS_REG_VALUE_MASK 0x3FFU
#ifndef OSI_STRIPPED_LIB
#define XPCS_VR_XS_PCS_EEE_MCTRL0 0xE0018
#define XPCS_VR_XS_PCS_EEE_MCTRL1 0xE002C
#define XLGPCS_VR_PCS_EEE_MCTRL 0xe0018
#define XLGPCS_VR_PCS_DIG_STS 0xe0040
#define XPCS_VR_XS_PCS_EEE_MCTRL1_TRN_LPI OSI_BIT(0)
#define XPCS_VR_XS_PCS_EEE_MCTRL0_LTX_EN OSI_BIT(0)
#define XPCS_VR_XS_PCS_EEE_MCTRL0_LRX_EN OSI_BIT(1)
#define XLGPCS_VR_PCS_DIG_STSLTXRX_STATE (OSI_BIT(15) | OSI_BIT(14) | \
OSI_BIT(13) | OSI_BIT(12) | \
OSI_BIT(11) | OSI_BIT(10))
#endif /* !OSI_STRIPPED_LIB */
/** @} */
/**
* @addtogroup Status readback related defines
* @{
*/
#define COND_MET 0
#define COND_NOT_MET 1
#define RETRY_ONCE 1U
/* 7usec is minimum to use usleep, anything less should use udelay, set to 10us */
#define MIN_USLEEP_10US 10U
/** @} */
#ifdef MACSEC_SUPPORT #ifdef MACSEC_SUPPORT
/** /**
@@ -2214,4 +2248,87 @@ struct osi_core_priv_data *osi_get_core(void);
nve32_t osi_release_core(struct osi_core_priv_data *osi_core); nve32_t osi_release_core(struct osi_core_priv_data *osi_core);
#endif #endif
/**
* @brief
* Description: Initialiation of EQoS XPCS IP.
*
* @param[in] osi_core: A pointer to the osi_core_priv_data structure
* * Range: A non-null pointer to NVETHERNETRM_PIF$osi_core_priv_data structure.
* * Refer NVETHERNETRM_PIF$osi_core_priv_data
*
* @usage
* - Allowed context for the API call
* - Interrupt handler: No
* - Signal handler: No
* - Thread safe: No
* - Async/Sync: Sync
* - Required Privileges: None
* - API Group:
* - Initialization: Yes
* - Run time: No
* - De-initialization: No
*
* @return
* 0 on success
* -1 on failure
*
*/
nve32_t eqos_xpcs_init(struct osi_core_priv_data *osi_core);
#ifndef OSI_STRIPPED_LIB
/**
* @brief xpcs_eee - XPCS enable/disable EEE
*
* Algorithm: This routine update register related to EEE
* for XPCS.
*
* @param[in] osi_core: OSI core data structure.
* @param[in] en_dis: enable - 1 or disable - 0
*
* @retval 0 on success
* @retval -1 on failure.
*/
nve32_t xpcs_eee(struct osi_core_priv_data *osi_core, nveu32_t en_dis);
#endif
/**
* @brief mixed_bank_reg_prog - programs the mixed bank registers in non-Tegra chips
*
* Algorithm: This routine update the mixed bank registers
* for XPCS.
*
* @param[in] osi_core: OSI core data structure.
*
* @retval 0 on success
* @retval -1 on failure.
*/
nve32_t mixed_bank_reg_prog(struct osi_core_priv_data *osi_core);
/**
* @brief
* Description: Lane bringup of XPCS IP.
*
* @param[in] osi_core: A pointer to the osi_core_priv_data structure
* * Range: A non-null pointer to NVETHERNETRM_PIF$osi_core_priv_data structure.
* * Refer NVETHERNETRM_PIF$osi_core_priv_data
*
* @usage
* - Allowed context for the API call
* - Interrupt handler: No
* - Signal handler: No
* - Thread safe: No
* - Async/Sync: Sync
* - Required Privileges: None
* - API Group:
* - Initialization: Yes
* - Run time: No
* - De-initialization: No
*
* @return
* 0 on success
* -1 on failure
*
*/
nve32_t xpcs_lane_bring_up(struct osi_core_priv_data *osi_core);
#endif /* INCLUDED_OSI_CORE_H */ #endif /* INCLUDED_OSI_CORE_H */

View File

@@ -1,6 +1,6 @@
################################### tell Emacs this is a -*- makefile-gmake -*- ################################### tell Emacs this is a -*- makefile-gmake -*-
# #
# Copyright (c) 2019-2024, NVIDIA CORPORATION. All rights reserved. # Copyright (c) 2019-2025, NVIDIA CORPORATION. All rights reserved.
# #
# Permission is hereby granted, free of charge, to any person obtaining a # Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"), # copy of this software and associated documentation files (the "Software"),
@@ -46,7 +46,8 @@ NV_COMPONENT_INCLUDES := \
$(NV_SOURCE)/nvethernetrm/include \ $(NV_SOURCE)/nvethernetrm/include \
NV_COMPONENT_NEEDED_STATIC_INTERFACE_DIRS += \ NV_COMPONENT_NEEDED_STATIC_INTERFACE_DIRS += \
$(NV_SOURCE)/nvethernetrm/osi/nvmacsecrm $(NV_SOURCE)/nvethernetrm/osi/nvmacsecrm \
$(NV_SOURCE)/nvethernetrm/osi/nvxpcsrm
ifeq ($(EN_OSI_RM_FTRACE),1) ifeq ($(EN_OSI_RM_FTRACE),1)
# Enable below for function trace logs # Enable below for function trace logs

View File

@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: LicenseRef-NvidiaProprietary /* SPDX-License-Identifier: LicenseRef-NvidiaProprietary
* SPDX-FileCopyrightText: Copyright (c) 2021-2024 NVIDIA CORPORATION. All rights reserved. * SPDX-FileCopyrightText: Copyright (c) 2021-2025 NVIDIA CORPORATION. All rights reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"), * copy of this software and associated documentation files (the "Software"),
@@ -579,9 +579,6 @@ static inline nveu64_t osi_update_stats_counter(nveu64_t last_value,
* atleast 1 iteration. * atleast 1 iteration.
*/ */
#define RETRY_COUNT 1000U #define RETRY_COUNT 1000U
#define RETRY_ONCE 1U
#define COND_MET 0
#define COND_NOT_MET 1
#define RETRY_DELAY 1U #define RETRY_DELAY 1U
#define OSI_DELAY_4US 4U #define OSI_DELAY_4US 4U
#define OSI_DELAY_10US 10U #define OSI_DELAY_10US 10U
@@ -592,8 +589,6 @@ static inline nveu64_t osi_update_stats_counter(nveu64_t last_value,
#define OSI_DELAY_1000US 1000U #define OSI_DELAY_1000US 1000U
#define OSI_DELAY_10000US 10000U #define OSI_DELAY_10000US 10000U
#define OSI_DELAY_30000US 30000U #define OSI_DELAY_30000US 30000U
/* 7usec is minimum to use usleep, anything less should use udelay, set to 10us */
#define MIN_USLEEP_10US 10U
/** @} */ /** @} */

View File

@@ -1,6 +1,6 @@
################################### ###################################
# #
# Copyright (c) 2023-2024, NVIDIA CORPORATION. All rights reserved. # Copyright (c) 2023-2025, NVIDIA CORPORATION. All rights reserved.
# #
# Permission is hereby granted, free of charge, to any person obtaining a # Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"), # copy of this software and associated documentation files (the "Software"),
@@ -41,6 +41,7 @@ GLOBAL_INCLUDES += \
$(NVETHERNETRM)/osi/core/ \ $(NVETHERNETRM)/osi/core/ \
$(NVETHERNETRM)/osi/dma/ \ $(NVETHERNETRM)/osi/dma/ \
$(NVETHERNETRM)/osi/nvmacsecrm/ \ $(NVETHERNETRM)/osi/nvmacsecrm/ \
$(NVETHERNETRM)/osi/nvxpcsrm/ \
$(TEGRA_TOP)/fsi-internal/fw/include \ $(TEGRA_TOP)/fsi-internal/fw/include \
MODULE_SRCS += \ MODULE_SRCS += \

View File

@@ -99,69 +99,6 @@ fail:
return ret; return ret;
} }
/**
* @brief eqos_xpcs_poll_for_an_complete - Polling for AN complete.
*
* Algorithm: This routine poll for AN completion status from
* EQOS XPCS IP.
*
* @param[in] osi_core: OSI core data structure.
* @param[out] an_status: AN status from XPCS
*
* @retval 0 on success
* @retval -1 on failure.
*/
#if 0 // FIXME: Not used for SLT EQOS bring up
static inline nve32_t eqos_xpcs_poll_for_an_complete(
struct osi_core_priv_data *osi_core,
nveu32_t *an_status)
{
void *xpcs_base = osi_core->xpcs_base;
nveu32_t status = 0;
nveu32_t retry = 1000;
nveu32_t count;
nve32_t cond = 1;
nve32_t ret = 0;
/* Poll for AN complete */
cond = 1;
count = 0;
while (cond == 1) {
if (count > retry) {
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL,
"EQOS XPCS AN completion timed out\n", 0ULL);
ret = -1;
goto fail;
}
count++;
status = xpcs_read(xpcs_base, XPCS_VR_MII_AN_INTR_STS);
if ((status & XPCS_VR_MII_AN_INTR_STS_CL37_ANCMPLT_INTR) == 0U) {
/* autoneg not completed - poll */
osi_core->osd_ops.udelay(1000U);
} else {
/* Clear interrupt */
status &= ~XPCS_VR_MII_AN_INTR_STS_CL37_ANCMPLT_INTR;
ret = xpcs_write_safety(osi_core, XPCS_VR_MII_AN_INTR_STS, status);
if (ret != 0) {
goto fail;
}
cond = 0;
}
}
if ((status & EQOS_XPCS_VR_MII_AN_INTR_STS_LINK_UP) == 0U) {
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL,
"EQOS XPCS AN completed but link is down\n", 0ULL);
ret = -1;
goto fail;
}
*an_status = status;
fail:
return ret;
}
#endif
/** /**
* @brief xpcs_set_speed - Set speed at XPCS * @brief xpcs_set_speed - Set speed at XPCS
* *
@@ -610,7 +547,7 @@ fail:
* @retval 0 on success * @retval 0 on success
* @retval -1 on failure. * @retval -1 on failure.
*/ */
static nve32_t xpcs_lane_bring_up(struct osi_core_priv_data *osi_core) nve32_t xpcs_lane_bring_up(struct osi_core_priv_data *osi_core)
{ {
struct core_local *l_core = (struct core_local *)(void *)osi_core; struct core_local *l_core = (struct core_local *)(void *)osi_core;
nveu32_t retry = 7U; nveu32_t retry = 7U;
@@ -797,126 +734,6 @@ fail:
return ret; return ret;
} }
/**
* @brief eqos_xpcs_init - EQOS XPCS initialization
*
* Algorithm: This routine initialize XPCS in SGMII mode.
*
* @param[in] osi_core: OSI core data structure.
*
* @retval 0 on success
* @retval -1 on failure.
*/
nve32_t eqos_xpcs_init(struct osi_core_priv_data *osi_core)
{
void *xpcs_base = osi_core->xpcs_base;
// nveu32_t an_status = 0;
nveu32_t retry = 1000;
nveu32_t count;
nveu32_t ctrl = 0;
nve32_t cond = 1;
nve32_t ret = 0;
if (osi_core->xpcs_base == OSI_NULL) {
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL,
"XPCS base is NULL", 0ULL);
ret = -1;
goto fail;
}
if (osi_core->pre_sil == 0x1U) {
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL,
"Pre-silicon, skipping lane bring up", 0ULL);
} else {
if (xpcs_lane_bring_up(osi_core) < 0) {
ret = -1;
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL,
"XPCS bring up failed", 0ULL);
goto fail;
}
}
/* Init XPCS controller based on
* DWC XPCS programming guideline 7.1
*/
/* 1. NA, Switch on power supply */
/* 2. NA, Wait as per PHY requirements */
/* 3. NA, De-assert reset */
/* 4. NA, Configure multi-protocol */
/* 5. Read SR_MII_CTRL register and wait for 15 bit read as 0 */
cond = 1;
count = 0;
while (cond == 1) {
if (count > retry) {
ret = -1;
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL,
"XPCS timeout!!", 0ULL);
goto fail;
}
count++;
ctrl = xpcs_read(xpcs_base, XPCS_SR_MII_CTRL);
if ((ctrl & XPCS_SR_MII_CTRL_RST) == 0U) {
cond = 0;
} else {
osi_core->osd_ops.udelay(100U);
}
}
#if 0 // FIXME: Re-visit below steps, not required for SLT EQOS
ctrl = xpcs_read(xpcs_base, XPCS_VS_MII_MMD_VR_MII_AN_CTRL_0);
ctrl |= (XPCS_VS_MII_MMD_VR_MII_AN_CTRL_AN_INTR_EN |
XPCS_VS_MII_MMD_VR_MII_AN_CTRL_PCS_MODE);
ret = xpcs_write_safety(osi_core, XPCS_VS_MII_MMD_VR_MII_AN_CTRL_0, ctrl);
if (ret != 0) {
goto fail;
}
ctrl = xpcs_read(xpcs_base, XPCS_SR_MII_CTRL);
ctrl |= XPCS_SR_MII_CTRL_RESTART_AN;
xpcs_write_safety(osi_core, XPCS_SR_MII_CTRL, ctrl);
osi_core->osd_ops.udelay(1000*100U);
ret = eqos_xpcs_poll_for_an_complete(osi_core, &an_status);
if (ret < 0) {
goto fail;
}
OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_HW_FAIL,
"EQOS XPCS AN Status", an_status);
ret = eqos_xpcs_set_speed(osi_core, an_status);
if (ret != 0) {
goto fail;
}
#endif
/* 7. NA */
/* 8. NA */
/* 9. Wait for LINK_STS of SR_MII_STS Register bit to become 1 */
cond = 1;
count = 0;
while (cond == 1) {
if (count > retry) {
ret = -1;
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL,
"XPCS LINK_STS timeout!!", 0ULL);
goto fail;
}
count++;
ctrl = xpcs_read(xpcs_base, XPCS_SR_MII_STS_0);
if ((ctrl & XPCS_SR_MII_STS_0_LINK_STS) ==
XPCS_SR_MII_STS_0_LINK_STS) {
cond = 0;
} else {
osi_core->osd_ops.udelay(100U);
}
}
fail:
return ret;
}
static nve32_t vendor_specifc_sw_rst_usxgmii_an_en(struct osi_core_priv_data *osi_core) static nve32_t vendor_specifc_sw_rst_usxgmii_an_en(struct osi_core_priv_data *osi_core)
{ {
void *xpcs_base = osi_core->xpcs_base; void *xpcs_base = osi_core->xpcs_base;
@@ -1283,69 +1100,6 @@ fail:
} }
#ifndef OSI_STRIPPED_LIB #ifndef OSI_STRIPPED_LIB
/**
* @brief xpcs_eee - XPCS enable/disable EEE
*
* Algorithm: This routine update register related to EEE
* for XPCS.
*
* @param[in] osi_core: OSI core data structure.
* @param[in] en_dis: enable - 1 or disable - 0
*
* @retval 0 on success
* @retval -1 on failure.
*/
nve32_t xpcs_eee(struct osi_core_priv_data *osi_core, nveu32_t en_dis)
{
void *xpcs_base = osi_core->xpcs_base;
nveu32_t val = 0x0U;
nve32_t ret = 0;
if ((en_dis != OSI_ENABLE) && (en_dis != OSI_DISABLE)) {
ret = -1;
goto fail;
}
if (xpcs_base == OSI_NULL) {
ret = -1;
goto fail;
}
if (en_dis == OSI_DISABLE) {
val = xpcs_read(xpcs_base, XPCS_VR_XS_PCS_EEE_MCTRL0);
val &= ~XPCS_VR_XS_PCS_EEE_MCTRL0_LTX_EN;
val &= ~XPCS_VR_XS_PCS_EEE_MCTRL0_LRX_EN;
ret = xpcs_write_safety(osi_core, XPCS_VR_XS_PCS_EEE_MCTRL0, val);
} else {
/* 1. Check if DWC_xpcs supports the EEE feature by
* reading the SR_XS_PCS_EEE_ABL register
* 1000BASEX-Only is different config then else so can (skip)
*/
/* 2. Program various timers used in the EEE mode depending on the
* clk_eee_i clock frequency. default times are same as IEEE std
* clk_eee_i() is 102MHz. MULT_FACT_100NS = 9 because 9.8ns*10 = 98
* which is between 80 and 120 this leads to default setting match
*/
val = xpcs_read(xpcs_base, XPCS_VR_XS_PCS_EEE_MCTRL0);
/* 3. If FEC is enabled in the KR mode (skip in FPGA)*/
/* 4. enable the EEE feature on the Tx path and Rx path */
val |= (XPCS_VR_XS_PCS_EEE_MCTRL0_LTX_EN |
XPCS_VR_XS_PCS_EEE_MCTRL0_LRX_EN);
ret = xpcs_write_safety(osi_core, XPCS_VR_XS_PCS_EEE_MCTRL0, val);
if (ret != 0) {
goto fail;
}
/* Transparent Tx LPI Mode Enable */
val = xpcs_read(xpcs_base, XPCS_VR_XS_PCS_EEE_MCTRL1);
val |= XPCS_VR_XS_PCS_EEE_MCTRL1_TRN_LPI;
ret = xpcs_write_safety(osi_core, XPCS_VR_XS_PCS_EEE_MCTRL1, val);
}
fail:
return ret;
}
/** /**
* @brief xlgpcs_eee - XLGPCS enable/disable EEE * @brief xlgpcs_eee - XLGPCS enable/disable EEE

View File

@@ -33,7 +33,6 @@
* @brief XPCS register offsets * @brief XPCS register offsets
* @{ * @{
*/ */
#define XPCS_ADDRESS 0x03FC
#define XPCS_SR_XS_PCS_STS1 0xC0004 #define XPCS_SR_XS_PCS_STS1 0xC0004
#define XPCS_SR_XS_PCS_CTRL2 0xC001C #define XPCS_SR_XS_PCS_CTRL2 0xC001C
#define XPCS_VR_XS_PCS_DIG_CTRL1 0xE0000 #define XPCS_VR_XS_PCS_DIG_CTRL1 0xE0000
@@ -41,7 +40,6 @@
#define XPCS_SR_AN_CTRL 0x1C0000 #define XPCS_SR_AN_CTRL 0x1C0000
#define XPCS_SR_PMA_KR_FEC_CTRL 0x402ac #define XPCS_SR_PMA_KR_FEC_CTRL 0x402ac
#define XPCS_SR_MII_CTRL 0x7C0000 #define XPCS_SR_MII_CTRL 0x7C0000
#define XPCS_SR_MII_STS_0 0x7C0004
#define XPCS_VR_MII_AN_INTR_STS 0x7E0008 #define XPCS_VR_MII_AN_INTR_STS 0x7E0008
#define XPCS_VS_MII_MMD_VR_MII_AN_CTRL_0 0x7E0004 #define XPCS_VS_MII_MMD_VR_MII_AN_CTRL_0 0x7E0004
#define XPCS_WRAP_UPHY_HW_INIT_CTRL 0x8020 #define XPCS_WRAP_UPHY_HW_INIT_CTRL 0x8020
@@ -139,21 +137,6 @@
#define EQOS_XPCS_WRAP_UPHY_INTERRUPT_STATUS 0x8070 #define EQOS_XPCS_WRAP_UPHY_INTERRUPT_STATUS 0x8070
/** @} */ /** @} */
#ifndef OSI_STRIPPED_LIB
#define XPCS_VR_XS_PCS_EEE_MCTRL0 0xE0018
#define XPCS_VR_XS_PCS_EEE_MCTRL1 0xE002C
#define XLGPCS_VR_PCS_EEE_MCTRL 0xe0018
#define XLGPCS_VR_PCS_DIG_STS 0xe0040
#define XPCS_VR_XS_PCS_EEE_MCTRL1_TRN_LPI OSI_BIT(0)
#define XPCS_VR_XS_PCS_EEE_MCTRL0_LTX_EN OSI_BIT(0)
#define XPCS_VR_XS_PCS_EEE_MCTRL0_LRX_EN OSI_BIT(1)
#define XLGPCS_VR_PCS_DIG_STSLTXRX_STATE (OSI_BIT(15) | OSI_BIT(14) | \
OSI_BIT(13) | OSI_BIT(12) | \
OSI_BIT(11) | OSI_BIT(10))
#endif /* !OSI_STRIPPED_LIB */
/** /**
* @addtogroup XPCS-BIT Register bit fileds * @addtogroup XPCS-BIT Register bit fileds
* *
@@ -173,8 +156,6 @@
#define XPCS_SR_AN_CTRL_AN_EN OSI_BIT(12) #define XPCS_SR_AN_CTRL_AN_EN OSI_BIT(12)
#define XPCS_SR_MII_CTRL_RESTART_AN OSI_BIT(9) #define XPCS_SR_MII_CTRL_RESTART_AN OSI_BIT(9)
#define XPCS_SR_MII_CTRL_AN_ENABLE OSI_BIT(12) #define XPCS_SR_MII_CTRL_AN_ENABLE OSI_BIT(12)
#define XPCS_SR_MII_CTRL_RST OSI_BIT(15)
#define XPCS_SR_MII_STS_0_LINK_STS OSI_BIT(2)
#define XPCS_VR_MII_AN_INTR_STS_CL37_ANCMPLT_INTR OSI_BIT(0) #define XPCS_VR_MII_AN_INTR_STS_CL37_ANCMPLT_INTR OSI_BIT(0)
#define EQOS_XPCS_VR_MII_AN_INTR_STS_LINK_UP OSI_BIT(4) #define EQOS_XPCS_VR_MII_AN_INTR_STS_LINK_UP OSI_BIT(4)
#define XPCS_SR_MII_CTRL_SS5 OSI_BIT(5) #define XPCS_SR_MII_CTRL_SS5 OSI_BIT(5)
@@ -188,9 +169,6 @@
#define XPCS_USXG_AN_STS_SPEED_2500 0x1000U #define XPCS_USXG_AN_STS_SPEED_2500 0x1000U
#define XPCS_USXG_AN_STS_SPEED_5000 0x1400U #define XPCS_USXG_AN_STS_SPEED_5000 0x1400U
#define XPCS_USXG_AN_STS_SPEED_10000 0xC00U #define XPCS_USXG_AN_STS_SPEED_10000 0xC00U
#define XPCS_REG_ADDR_SHIFT 10U
#define XPCS_REG_ADDR_MASK 0x1FFFU
#define XPCS_REG_VALUE_MASK 0x3FFU
#define XPCS_VR_XS_PCS_KR_CTRL_USXG_MODE_MASK (OSI_BIT(12) | \ #define XPCS_VR_XS_PCS_KR_CTRL_USXG_MODE_MASK (OSI_BIT(12) | \
OSI_BIT(11) | \ OSI_BIT(11) | \
OSI_BIT(10)) OSI_BIT(10))
@@ -234,10 +212,8 @@ nve32_t xpcs_start(struct osi_core_priv_data *osi_core);
nve32_t xlgpcs_init(struct osi_core_priv_data *osi_core); nve32_t xlgpcs_init(struct osi_core_priv_data *osi_core);
nve32_t xlgpcs_start(struct osi_core_priv_data *osi_core); nve32_t xlgpcs_start(struct osi_core_priv_data *osi_core);
#ifndef OSI_STRIPPED_LIB #ifndef OSI_STRIPPED_LIB
nve32_t xpcs_eee(struct osi_core_priv_data *osi_core, nveu32_t en_dis);
nve32_t xlgpcs_eee(struct osi_core_priv_data *osi_core, nveu32_t en_dis); nve32_t xlgpcs_eee(struct osi_core_priv_data *osi_core, nveu32_t en_dis);
#endif /* !OSI_STRIPPED_LIB */ #endif /* !OSI_STRIPPED_LIB */
nve32_t eqos_xpcs_init(struct osi_core_priv_data *osi_core);
/** /**
* @brief xpcs_read - read from xpcs. * @brief xpcs_read - read from xpcs.

View File

@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: LicenseRef-NvidiaProprietary /* SPDX-License-Identifier: LicenseRef-NvidiaProprietary
* SPDX-FileCopyrightText: Copyright (c) 2021-2024 NVIDIA CORPORATION. All rights reserved. * SPDX-FileCopyrightText: Copyright (c) 2021-2025 NVIDIA CORPORATION. All rights reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"), * copy of this software and associated documentation files (the "Software"),
@@ -544,10 +544,7 @@
* @{ * @{
*/ */
#define RETRY_COUNT 1000U #define RETRY_COUNT 1000U
#define COND_MET 0
#define COND_NOT_MET 1
#define RETRY_DELAY 1U #define RETRY_DELAY 1U
#define MIN_USLEEP_10US 10U
/** @} */ /** @} */
/** /**

View File

@@ -0,0 +1,38 @@
################################### tell Emacs this is a -*- makefile-gmake -*-
#
# Copyright (c) 2025, NVIDIA CORPORATION. All 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.
#
# libnvxpcsrm interface makefile fragment
#
###############################################################################
ifdef NV_INTERFACE_FLAG_STATIC_LIBRARY_SECTION
NV_INTERFACE_NAME := nvxpcsrm
NV_INTERFACE_COMPONENT_DIR := .
NV_INTERFACE_PUBLIC_INCLUDES := \
./include
endif
# Local Variables:
# indent-tabs-mode: t
# tab-width: 8
# End:
# vi: set tabstop=8 noexpandtab:

47
osi/nvxpcsrm/Makefile.tmk Normal file
View File

@@ -0,0 +1,47 @@
################################### tell Emacs this is a -*- makefile-gmake -*-
#
# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
#
###############################################################################
ifdef NV_COMPONENT_FLAG_STATIC_LIBRARY_SECTION
include $(NV_BUILD_START_COMPONENT)
NV_COMPONENT_STRICT_WARNINGS_qnx_64 := 1
NV_COMPONENT_NAME := nvxpcsrm
NV_COMPONENT_OWN_INTERFACE_DIR := .
NV_COMPONENT_SOURCES := \
$(NV_SOURCE)/nvethernetrm/osi/nvxpcsrm/nvxpcs.c
NV_COMPONENT_INCLUDES := \
$(NV_SOURCE)/nvethernetrm/include
include $(NV_SOURCE)/nvethernetrm/include/config.tmk
include $(NV_BUILD_STATIC_LIBRARY)
endif
# Local Variables:
# indent-tabs-mode: t
# tab-width: 8
# End:
# vi: set tabstop=8 noexpandtab:

View File

@@ -0,0 +1,27 @@
################################### tell Emacs this is a -*- makefile-gmake -*-
#
# Copyright (c) 2025, NVIDIA CORPORATION. All 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.
#
# libnvxpcsrm interface export
#
###############################################################################
eqos_xpcs_init
xpcs_eee

293
osi/nvxpcsrm/nvxpcs.c Normal file
View File

@@ -0,0 +1,293 @@
// SPDX-License-Identifier: LicenseRef-NvidiaProprietary
/* SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <osi_core.h>
#include "nvxpcs.h"
/**
* @brief eqos_xpcs_poll_for_an_complete - Polling for AN complete.
*
* Algorithm: This routine poll for AN completion status from
* EQOS XPCS IP.
*
* @param[in] osi_core: OSI core data structure.
* @param[out] an_status: AN status from XPCS
*
* @retval 0 on success
* @retval -1 on failure.
*/
#if 0 // FIXME: Not used for SLT EQOS bring up
static inline nve32_t eqos_xpcs_poll_for_an_complete(
struct osi_core_priv_data *osi_core,
nveu32_t *an_status)
{
void *xpcs_base = osi_core->xpcs_base;
nveu32_t status = 0;
nveu32_t retry = 1000;
nveu32_t count;
nve32_t cond = 1;
nve32_t ret = 0;
/* Poll for AN complete */
cond = 1;
count = 0;
while (cond == 1) {
if (count > retry) {
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL,
"EQOS XPCS AN completion timed out\n", 0ULL);
ret = -1;
goto fail;
}
count++;
status = nv_xpcs_read(xpcs_base, XPCS_VR_MII_AN_INTR_STS);
if ((status & XPCS_VR_MII_AN_INTR_STS_CL37_ANCMPLT_INTR) == 0U) {
/* autoneg not completed - poll */
osi_core->osd_ops.udelay(1000U);
} else {
/* Clear interrupt */
status &= ~XPCS_VR_MII_AN_INTR_STS_CL37_ANCMPLT_INTR;
ret = nv_xpcs_write_safety(osi_core, XPCS_VR_MII_AN_INTR_STS, status);
if (ret != 0) {
goto fail;
}
cond = 0;
}
}
if ((status & EQOS_XPCS_VR_MII_AN_INTR_STS_LINK_UP) == 0U) {
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL,
"EQOS XPCS AN completed but link is down\n", 0ULL);
ret = -1;
goto fail;
}
*an_status = status;
fail:
return ret;
}
#endif
/**
* @brief eqos_xpcs_init - EQOS XPCS initialization
*
* Algorithm: This routine initialize XPCS in SGMII mode.
*
* @param[in] osi_core: OSI core data structure.
*
* @retval 0 on success
* @retval -1 on failure.
*/
nve32_t eqos_xpcs_init(struct osi_core_priv_data *osi_core)
{
void *xpcs_base = osi_core->xpcs_base;
// nveu32_t an_status = 0;
nveu32_t retry = 1000;
nveu32_t count;
nveu32_t ctrl = 0;
nve32_t cond = 1;
nve32_t ret = 0;
if (osi_core->xpcs_base == OSI_NULL) {
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL,
"XPCS base is NULL", 0ULL);
ret = -1;
goto fail;
}
if (osi_core->pre_sil == 0x1U) {
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL,
"Pre-silicon, skipping lane bring up", 0ULL);
} else {
if (xpcs_lane_bring_up(osi_core) < 0) {
ret = -1;
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL,
"XPCS bring up failed", 0ULL);
goto fail;
}
}
/* Init XPCS controller based on
* DWC XPCS programming guideline 7.1
*/
/* 1. NA, Switch on power supply */
/* 2. NA, Wait as per PHY requirements */
/* 3. NA, De-assert reset */
/* 4. NA, Configure multi-protocol */
/* 5. Read SR_MII_CTRL register and wait for 15 bit read as 0 */
cond = 1;
count = 0;
while (cond == 1) {
if (count > retry) {
ret = -1;
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL,
"XPCS timeout!!", 0ULL);
goto fail;
}
count++;
ctrl = nv_xpcs_read(xpcs_base, NV_XPCS_SR_MII_CTRL);
if ((ctrl & XPCS_SR_MII_CTRL_RST) == 0U) {
cond = 0;
} else {
osi_core->osd_ops.udelay(100U);
}
}
#if 0 // FIXME: Re-visit below steps, not required for SLT EQOS
ctrl = nv_xpcs_read(xpcs_base, XPCS_VS_MII_MMD_VR_MII_AN_CTRL_0);
ctrl |= (XPCS_VS_MII_MMD_VR_MII_AN_CTRL_AN_INTR_EN |
XPCS_VS_MII_MMD_VR_MII_AN_CTRL_PCS_MODE);
ret = nv_xpcs_write_safety(osi_core, XPCS_VS_MII_MMD_VR_MII_AN_CTRL_0, ctrl);
if (ret != 0) {
goto fail;
}
ctrl = nv_xpcs_read(xpcs_base, XPCS_SR_MII_CTRL);
ctrl |= XPCS_SR_MII_CTRL_RESTART_AN;
nv_xpcs_write_safety(osi_core, XPCS_SR_MII_CTRL, ctrl);
osi_core->osd_ops.udelay(1000*100U);
ret = eqos_xpcs_poll_for_an_complete(osi_core, &an_status);
if (ret < 0) {
goto fail;
}
OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_HW_FAIL,
"EQOS XPCS AN Status", an_status);
ret = eqos_xpcs_set_speed(osi_core, an_status);
if (ret != 0) {
goto fail;
}
#endif
/* 7. NA */
/* 8. NA */
/* 9. Wait for LINK_STS of SR_MII_STS Register bit to become 1 */
cond = 1;
count = 0;
while (cond == 1) {
if (count > retry) {
ret = -1;
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL,
"XPCS LINK_STS timeout!!", 0ULL);
goto fail;
}
count++;
ctrl = nv_xpcs_read(xpcs_base, XPCS_SR_MII_STS_0);
if ((ctrl & XPCS_SR_MII_STS_0_LINK_STS) ==
XPCS_SR_MII_STS_0_LINK_STS) {
cond = 0;
} else {
osi_core->osd_ops.udelay(100U);
}
}
fail:
return ret;
}
#ifndef OSI_STRIPPED_LIB
/**
* @brief xpcs_eee - XPCS enable/disable EEE
*
* Algorithm: This routine update register related to EEE
* for XPCS.
*
* @param[in] osi_core: OSI core data structure.
* @param[in] en_dis: enable - 1 or disable - 0
*
* @retval 0 on success
* @retval -1 on failure.
*/
nve32_t xpcs_eee(struct osi_core_priv_data *osi_core, nveu32_t en_dis)
{
void *xpcs_base = osi_core->xpcs_base;
nveu32_t val = 0x0U;
nve32_t ret = 0;
if ((en_dis != OSI_ENABLE) && (en_dis != OSI_DISABLE)) {
ret = -1;
goto fail;
}
if (xpcs_base == OSI_NULL) {
ret = -1;
goto fail;
}
if (en_dis == OSI_DISABLE) {
val = nv_xpcs_read(xpcs_base, XPCS_VR_XS_PCS_EEE_MCTRL0);
val &= ~XPCS_VR_XS_PCS_EEE_MCTRL0_LTX_EN;
val &= ~XPCS_VR_XS_PCS_EEE_MCTRL0_LRX_EN;
ret = nv_xpcs_write_safety(osi_core, XPCS_VR_XS_PCS_EEE_MCTRL0, val);
} else {
/* 1. Check if DWC_xpcs supports the EEE feature by
* reading the SR_XS_PCS_EEE_ABL register
* 1000BASEX-Only is different config then else so can (skip)
*/
/* 2. Program various timers used in the EEE mode depending on the
* clk_eee_i clock frequency. default times are same as IEEE std
* clk_eee_i() is 102MHz. MULT_FACT_100NS = 9 because 9.8ns*10 = 98
* which is between 80 and 120 this leads to default setting match
*/
val = nv_xpcs_read(xpcs_base, XPCS_VR_XS_PCS_EEE_MCTRL0);
/* 3. If FEC is enabled in the KR mode (skip in FPGA)*/
/* 4. enable the EEE feature on the Tx path and Rx path */
val |= (XPCS_VR_XS_PCS_EEE_MCTRL0_LTX_EN |
XPCS_VR_XS_PCS_EEE_MCTRL0_LRX_EN);
ret = nv_xpcs_write_safety(osi_core, XPCS_VR_XS_PCS_EEE_MCTRL0, val);
if (ret != 0) {
goto fail;
}
/* Transparent Tx LPI Mode Enable */
val = nv_xpcs_read(xpcs_base, XPCS_VR_XS_PCS_EEE_MCTRL1);
val |= XPCS_VR_XS_PCS_EEE_MCTRL1_TRN_LPI;
ret = nv_xpcs_write_safety(osi_core, XPCS_VR_XS_PCS_EEE_MCTRL1, val);
}
fail:
return ret;
}
#endif
/**
* @brief mixed_bank_reg_prog - programs the mixed bank registers in non-Tegra chips
*
* Algorithm: This routine update the mixed bank registers
* for XPCS.
*
* @param[in] osi_core: OSI core data structure.
*
* @retval 0 on success
* @retval -1 on failure.
*/
nve32_t mixed_bank_reg_prog(struct osi_core_priv_data *osi_core)
{
(void)osi_core;
return 0;
}

169
osi/nvxpcsrm/nvxpcs.h Normal file
View File

@@ -0,0 +1,169 @@
/* SPDX-License-Identifier: LicenseRef-NvidiaProprietary
* SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef INCLUDED_NVXPCS_H
#define INCLUDED_NVXPCS_H
#define NV_XPCS_SR_MII_CTRL 0x7C0000
#define XPCS_SR_MII_CTRL_RST OSI_BIT(15)
#define XPCS_SR_MII_STS_0 0x7C0004
#define XPCS_SR_MII_STS_0_LINK_STS OSI_BIT(2)
/**
* @brief nv_osi_readl - Read a memory mapped register.
*
* @param[in] addr: Memory mapped address.
*
* @pre Physical address has to be memory mapped.
*
* @return Data from memory mapped register - success.
*
* @note
* API Group:
* - Initialization: Yes
* - Run time: Yes
* - De-initialization: Yes
*/
static inline nveu32_t nv_osi_readl(void *addr)
{
return *(volatile nveu32_t *)addr;
}
/**
* @brief nv_osi_writel - Write to a memory mapped register.
*
* @param[in] val: Value to be written.
* @param[in] addr: Memory mapped address.
*
* @pre Physical address has to be memory mapped.
*
* @note
* API Group:
* - Initialization: Yes
* - Run time: Yes
* - De-initialization: Yes
*/
static inline void nv_osi_writel(nveu32_t val, void *addr)
{
*(volatile nveu32_t *)addr = val;
}
/**
* @brief nv_xpcs_read - read from xpcs.
*
* Algorithm: This routine reads data from XPCS register.
*
* @param[in] xpcs_base: XPCS virtual base address
* @param[in] reg_addr: register address to be read
*
* @retval value read from xpcs register.
*/
static inline nveu32_t nv_xpcs_read(void *xpcs_base, nveu32_t reg_addr)
{
nv_osi_writel(((reg_addr >> XPCS_REG_ADDR_SHIFT) & XPCS_REG_ADDR_MASK),
((nveu8_t *)xpcs_base + XPCS_ADDRESS));
return nv_osi_readl((nveu8_t *)xpcs_base +
((reg_addr) & XPCS_REG_VALUE_MASK));
}
#ifndef OSI_STRIPPED_LIB
/**
* @brief nv_xpcs_write - write to xpcs.
*
* Algorithm: This routine writes data to XPCS register.
*
* @param[in] xpcs_base: XPCS virtual base address
* @param[in] reg_addr: register address for writing
* @param[in] val: write value to register address
*/
static inline void nv_xpcs_write(void *xpcs_base, nveu32_t reg_addr,
nveu32_t val)
{
nv_osi_writel(((reg_addr >> XPCS_REG_ADDR_SHIFT) & XPCS_REG_ADDR_MASK),
((nveu8_t *)xpcs_base + XPCS_ADDRESS));
nv_osi_writel(val, (nveu8_t *)xpcs_base +
(((reg_addr) & XPCS_REG_VALUE_MASK)));
}
/**
* @brief nv_xpcs_write_safety - write to xpcs.
*
* Algorithm: This routine writes data to XPCS register.
* And verifiy by reading back the value
*
* @param[in] osi_core: OSI core data structure
* @param[in] reg_addr: register address for writing
* @param[in] val: write value to register address
*
* @retval 0 on success
* @retval XPCS_WRITE_FAIL_CODE on failure
*
*/
static inline nve32_t nv_xpcs_write_safety(struct osi_core_priv_data *osi_core,
nveu32_t reg_addr,
nveu32_t val)
{
void *xpcs_base = osi_core->xpcs_base;
nveu32_t read_val;
/* 1 busy wait, and the remaining retries are sleeps of granularity MIN_USLEEP_10US */
nveu32_t retry = RETRY_ONCE;
nveu32_t count = 0;
nveu32_t once = 0U;
nve32_t ret = XPCS_WRITE_FAIL_CODE;
nve32_t cond = COND_NOT_MET;
while (cond == COND_NOT_MET) {
nv_xpcs_write(xpcs_base, reg_addr, val);
read_val = nv_xpcs_read(xpcs_base, reg_addr);
if (val == read_val) {
ret = 0;
cond = COND_MET;
} else {
if (count > retry) {
break;
}
count++;
if (once == 0U) {
osi_core->osd_ops.udelay(OSI_DELAY_1US);
/* udelay is a busy wait, so don't call it too frequently.
* call it once to be optimistic, and then use usleep with
* a longer timeout to yield to other CPU users.
*/
once = 1U;
} else {
osi_core->osd_ops.usleep_range(MIN_USLEEP_10US,
MIN_USLEEP_10US + MIN_USLEEP_10US);
}
}
}
#ifndef OSI_STRIPPED_LIB
if (ret != 0) {
OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL,
"xpcs_write_safety failed", reg_addr);
}
#endif /* !OSI_STRIPPED_LIB */
return ret;
}
#endif
#endif /* INCLUDED_NVXPCS_H */

48
osi/nvxpcsrm/rules.mk Normal file
View File

@@ -0,0 +1,48 @@
###################################
#
# Copyright (c) 2025, NVIDIA CORPORATION. All 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.
#
###############################################################################
LOCAL_DIR := $(GET_LOCAL_DIR)
MODULE := $(LOCAL_DIR)
ifeq ($(NV_L4T_BUILD),1)
NVETHERNETRM := $(TEGRA_TOP)/kernel/nvethernetrm
else
NVETHERNETRM := $(TEGRA_TOP)/nvethernetrm
endif
include $(NVETHERNETRM)/include/config.tmk
GLOBAL_INCLUDES += \
$(NVETHERNETRM)/ \
$(NVETHERNETRM)/include/ \
MODULE_SRCS += \
$(NVETHERNETRM)/osi/nvxpcsrm/nvxpcs.c
MODULE_COMPILEFLAGS += -Wno-format
MODULE_COMPILEFLAGS += -mgeneral-regs-only
#MODULE_COMPILEFLAGS += -DOSI_STRIPPED_LIB
#MODULE_COMPILEFLAGS += -DLOG_OSI
include make/module.mk