From a19a5a80bde7eb8274d49d85a25a756dbd55ab7e Mon Sep 17 00:00:00 2001 From: Narayan Reddy Date: Thu, 30 Jun 2022 20:57:51 +0000 Subject: [PATCH] osi: core: combine set_speed Bug 3701869 Change-Id: Ie41b31e94f0ec0fb0b8d2d52cca7fafa81fd54c2 Signed-off-by: Narayan Reddy Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2738062 Tested-by: mobile promotions Reviewed-by: mobile promotions --- osi/core/core_common.c | 68 ++++++++++++++++++++++++++++++++++++++ osi/core/core_common.h | 1 + osi/core/core_local.h | 3 -- osi/core/eqos_core.c | 75 +++--------------------------------------- osi/core/mgbe_core.c | 49 --------------------------- osi/core/osi_hal.c | 4 +-- 6 files changed, 75 insertions(+), 125 deletions(-) diff --git a/osi/core/core_common.c b/osi/core/core_common.c index 49715b0..8b93162 100644 --- a/osi/core/core_common.c +++ b/osi/core/core_common.c @@ -24,6 +24,7 @@ #include "core_common.h" #include "mgbe_core.h" #include "eqos_core.h" +#include "xpcs.h" static inline nve32_t poll_check(struct osi_core_priv_data *const osi_core, nveu8_t *addr, nveu32_t bit_check, nveu32_t *value) @@ -129,6 +130,73 @@ fail: return ret; } +nve32_t hw_set_speed(struct osi_core_priv_data *const osi_core, const nve32_t speed) +{ + nveu32_t value; + nve32_t ret = 0; + void *base = osi_core->base; + const nveu32_t mac_mcr[2] = { EQOS_MAC_MCR, MGBE_MAC_TMCR }; + + if ((osi_core->mac == OSI_MAC_HW_EQOS && speed > OSI_SPEED_1000) || + (osi_core->mac == OSI_MAC_HW_MGBE && (speed < OSI_SPEED_2500 || + speed > OSI_SPEED_10000))) { + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "unsupported speed\n", (nveul64_t)speed); + ret = -1; + goto fail; + } + + value = osi_readla(osi_core, ((nveu8_t *)base + mac_mcr[osi_core->mac])); + switch (speed) { + default: + OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, + "unsupported speed\n", (nveul64_t)speed); + ret = -1; + goto fail; + case OSI_SPEED_10: + value |= EQOS_MCR_PS; + value &= ~EQOS_MCR_FES; + break; + case OSI_SPEED_100: + value |= EQOS_MCR_PS; + value |= EQOS_MCR_FES; + break; + case OSI_SPEED_1000: + value &= ~EQOS_MCR_PS; + value &= ~EQOS_MCR_FES; + break; + case OSI_SPEED_2500: + value |= MGBE_MAC_TMCR_SS_2_5G; + break; + case OSI_SPEED_5000: + value |= MGBE_MAC_TMCR_SS_5G; + break; + case OSI_SPEED_10000: + value &= ~MGBE_MAC_TMCR_SS_10G; + break; + + } + osi_writela(osi_core, value, ((nveu8_t *)osi_core->base + mac_mcr[osi_core->mac])); + + if (osi_core->mac == OSI_MAC_HW_MGBE) { + if (xpcs_init(osi_core) < 0) { + OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, + "xpcs_init failed\n", OSI_NONE); + ret = -1; + goto fail; + } + + ret = xpcs_start(osi_core); + if (ret < 0) { + goto fail; + } + } +fail: + return ret; +} + + + /** * @brief hw_est_read - indirect read the GCL to Software own list * (SWOL) diff --git a/osi/core/core_common.h b/osi/core/core_common.h index 268a094..3dd0efa 100644 --- a/osi/core/core_common.h +++ b/osi/core/core_common.h @@ -63,4 +63,5 @@ nve32_t hw_poll_for_swr(struct osi_core_priv_data *const osi_core); void hw_start_mac(struct osi_core_priv_data *const osi_core); void hw_stop_mac(struct osi_core_priv_data *const osi_core); nve32_t hw_set_mode(struct osi_core_priv_data *const osi_core, const nve32_t mode); +nve32_t hw_set_speed(struct osi_core_priv_data *const osi_core, const nve32_t speed); #endif /* INCLUDED_CORE_COMMON_H */ diff --git a/osi/core/core_local.h b/osi/core/core_local.h index e82d1b2..8dc99af 100644 --- a/osi/core/core_local.h +++ b/osi/core/core_local.h @@ -95,9 +95,6 @@ struct core_ops { void (*core_deinit)(struct osi_core_priv_data *const osi_core); /** Called to handle common interrupt */ void (*handle_common_intr)(struct osi_core_priv_data *const osi_core); - /** Called to set the speed at MAC */ - nve32_t (*set_speed)(struct osi_core_priv_data *const osi_core, - const nve32_t speed); /** Called to do pad caliberation */ nve32_t (*pad_calibrate)(struct osi_core_priv_data *const osi_core); /** Called to configure MTL RxQ to forward the err pkt */ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c index 008323c..f0fd3b4 100644 --- a/osi/core/eqos_core.c +++ b/osi/core/eqos_core.c @@ -552,60 +552,6 @@ static nve32_t eqos_config_fw_err_pkts( return 0; } -/** - * @brief eqos_set_speed - Set operating speed - * - * @note - * Algorithm: - * - Based on the speed (10/100/1000Mbps) MAC will be configured - * accordingly. - * - If invalid value for speed, configure for 1000Mbps. - * - Refer to EQOS column of <> for API details. - * - TraceID: ETHERNET_NVETHERNETRM_012 - * - * @param[in] base: EQOS virtual base address. - * @param[in] speed: Operating speed. Valid values are OSI_SPEED_* - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @pre MAC should be initialized and started. see osi_start_mac() - */ -static int eqos_set_speed(struct osi_core_priv_data *const osi_core, - const nve32_t speed) -{ - nveu32_t mcr_val; - void *base = osi_core->base; - - mcr_val = osi_readla(osi_core, (nveu8_t *)base + EQOS_MAC_MCR); - switch (speed) { - default: - mcr_val &= ~EQOS_MCR_PS; - mcr_val &= ~EQOS_MCR_FES; - break; - case OSI_SPEED_1000: - mcr_val &= ~EQOS_MCR_PS; - mcr_val &= ~EQOS_MCR_FES; - break; - case OSI_SPEED_100: - mcr_val |= EQOS_MCR_PS; - mcr_val |= EQOS_MCR_FES; - break; - case OSI_SPEED_10: - mcr_val |= EQOS_MCR_PS; - mcr_val &= ~EQOS_MCR_FES; - break; - } - - eqos_core_safety_writel(osi_core, mcr_val, - (unsigned char *)osi_core->base + EQOS_MAC_MCR, - EQOS_MAC_MCR_IDX); - return 0; -} - /** * @brief eqos_calculate_per_queue_fifo - Calculate per queue FIFO size * @@ -2385,7 +2331,7 @@ static void eqos_handle_mac_fpe_intrs(struct osi_core_priv_data *osi_core) * - RGMII/SMII MAC interrupt * - If link is down * - Identify speed and mode changes from EQOS_MAC_PCS register and configure the same by calling - * eqos_set_speed(), hw_set_mode()(proceed even on error for this call) API's. + * hw_set_speed(), hw_set_mode()(proceed even on error for this call) API's. * - SWUD_ID: ETHERNET_NVETHERNETRM_010_1 * * @param[in] osi_core: OSI core private data structure. Used param base. @@ -2479,25 +2425,13 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, /* TODO: set_tx_clk needs to be done */ /* Maybe through workqueue for QNX */ if ((mac_pcs & EQOS_MAC_PCS_LNKSPEED) == EQOS_MAC_PCS_LNKSPEED_10) { - ret = eqos_set_speed(osi_core, OSI_SPEED_10); - if (osi_unlikely(ret < 0)) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "set speed in 10Mbps failed\n", 0ULL); - } + hw_set_speed(osi_core, OSI_SPEED_10); } else if ((mac_pcs & EQOS_MAC_PCS_LNKSPEED) == EQOS_MAC_PCS_LNKSPEED_100) { - ret = eqos_set_speed(osi_core, OSI_SPEED_100); - if (osi_unlikely(ret < 0)) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "set speed in 100Mbps failed\n", 0ULL); - } + hw_set_speed(osi_core, OSI_SPEED_100); } else if ((mac_pcs & EQOS_MAC_PCS_LNKSPEED) == EQOS_MAC_PCS_LNKSPEED_1000) { - ret = eqos_set_speed(osi_core, OSI_SPEED_1000); - if (osi_unlikely(ret < 0)) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "set speed in 1000Mbps failed\n", 0ULL); - } + hw_set_speed(osi_core, OSI_SPEED_1000); } else { /* Nothing here */ } @@ -6688,7 +6622,6 @@ void eqos_init_core_ops(struct core_ops *ops) ops->core_init = eqos_core_init; ops->core_deinit = eqos_core_deinit; ops->handle_common_intr = eqos_handle_common_intr; - ops->set_speed = eqos_set_speed; ops->pad_calibrate = eqos_pad_calibrate; ops->config_fw_err_pkts = eqos_config_fw_err_pkts; ops->config_rxcsum_offload = eqos_config_rxcsum_offload; diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c index f337588..ef820f5 100644 --- a/osi/core/mgbe_core.c +++ b/osi/core/mgbe_core.c @@ -4365,53 +4365,6 @@ static void mgbe_core_deinit(struct osi_core_priv_data *const osi_core) hw_stop_mac(osi_core); } -/** - * @brief mgbe_set_speed - Set operating speed - * - * Algorithm: Based on the speed (2.5G/5G/10G) MAC will be configured - * accordingly. - * - * @param[in] osi_core: OSI core private data. - * @param[in] speed: Operating speed. - * - * @note MAC should be init and started. see osi_start_mac() - */ -static int mgbe_set_speed(struct osi_core_priv_data *const osi_core, - const int speed) -{ - unsigned int value = 0; - - value = osi_readla(osi_core, - (unsigned char *) osi_core->base + MGBE_MAC_TMCR); - - switch (speed) { - case OSI_SPEED_2500: - value |= MGBE_MAC_TMCR_SS_2_5G; - break; - case OSI_SPEED_5000: - value |= MGBE_MAC_TMCR_SS_5G; - break; - case OSI_SPEED_10000: - value &= ~MGBE_MAC_TMCR_SS_10G; - break; - default: - /* setting default to 10G */ - value &= ~MGBE_MAC_TMCR_SS_10G; - break; - } - - osi_writela(osi_core, value, (unsigned char *) - osi_core->base + MGBE_MAC_TMCR); - - if (xpcs_init(osi_core) < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "xpcs_init failed\n", OSI_NONE); - return -1; - } - - return xpcs_start(osi_core); -} - /** * @brief mgbe_mdio_busy_wait - MDIO busy wait loop * @@ -6089,8 +6042,6 @@ void mgbe_init_core_ops(struct core_ops *ops) ops->core_deinit = mgbe_core_deinit; ops->validate_regs = mgbe_validate_core_regs; ops->handle_common_intr = mgbe_handle_common_intr; - /* by default speed is 10G */ - ops->set_speed = mgbe_set_speed; ops->pad_calibrate = mgbe_pad_calibrate; ops->set_mdc_clk_rate = mgbe_set_mdc_clk_rate; ops->flush_mtl_tx_queue = mgbe_flush_mtl_tx_queue; diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c index e81f4c1..3f40b08 100644 --- a/osi/core/osi_hal.c +++ b/osi/core/osi_hal.c @@ -328,7 +328,7 @@ nve32_t osi_set_speed(struct osi_core_priv_data *const osi_core, return -1; } - return l_core->ops_p->set_speed(osi_core, speed); + return hw_set_speed(osi_core, speed); } nve32_t osi_pad_calibrate(struct osi_core_priv_data *const osi_core) @@ -2007,7 +2007,7 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, break; case OSI_CMD_SET_SPEED: - ret = ops_p->set_speed(osi_core, data->arg6_32); + ret = hw_set_speed(osi_core, data->arg6_32); break; case OSI_CMD_L2_FILTER: