mirror of
git://nv-tegra.nvidia.com/kernel/nvethernetrm.git
synced 2025-12-24 02:22:16 +03:00
osi: core: combine set_speed
Bug 3701869 Change-Id: Ie41b31e94f0ec0fb0b8d2d52cca7fafa81fd54c2 Signed-off-by: Narayan Reddy <narayanr@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2738062 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
Bhadram Varka
parent
9ab0b61bfa
commit
a19a5a80bd
@@ -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)
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -552,60 +552,6 @@ static nve32_t eqos_config_fw_err_pkts(
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief eqos_set_speed - Set operating speed
|
||||
*
|
||||
* @note
|
||||
* Algorithm:
|
||||
* - Based on the speed (10/100/1000Mbps) MAC will be configured
|
||||
* accordingly.
|
||||
* - If invalid value for speed, configure for 1000Mbps.
|
||||
* - Refer to EQOS column of <<RM_12, (sequence diagram)>> for API details.
|
||||
* - TraceID: ETHERNET_NVETHERNETRM_012
|
||||
*
|
||||
* @param[in] base: EQOS virtual base address.
|
||||
* @param[in] speed: Operating speed. Valid values are OSI_SPEED_*
|
||||
*
|
||||
* @note
|
||||
* API Group:
|
||||
* - Initialization: Yes
|
||||
* - Run time: Yes
|
||||
* - De-initialization: No
|
||||
*
|
||||
* @pre MAC should be initialized and started. see osi_start_mac()
|
||||
*/
|
||||
static int eqos_set_speed(struct osi_core_priv_data *const osi_core,
|
||||
const nve32_t speed)
|
||||
{
|
||||
nveu32_t mcr_val;
|
||||
void *base = osi_core->base;
|
||||
|
||||
mcr_val = osi_readla(osi_core, (nveu8_t *)base + EQOS_MAC_MCR);
|
||||
switch (speed) {
|
||||
default:
|
||||
mcr_val &= ~EQOS_MCR_PS;
|
||||
mcr_val &= ~EQOS_MCR_FES;
|
||||
break;
|
||||
case OSI_SPEED_1000:
|
||||
mcr_val &= ~EQOS_MCR_PS;
|
||||
mcr_val &= ~EQOS_MCR_FES;
|
||||
break;
|
||||
case OSI_SPEED_100:
|
||||
mcr_val |= EQOS_MCR_PS;
|
||||
mcr_val |= EQOS_MCR_FES;
|
||||
break;
|
||||
case OSI_SPEED_10:
|
||||
mcr_val |= EQOS_MCR_PS;
|
||||
mcr_val &= ~EQOS_MCR_FES;
|
||||
break;
|
||||
}
|
||||
|
||||
eqos_core_safety_writel(osi_core, mcr_val,
|
||||
(unsigned char *)osi_core->base + EQOS_MAC_MCR,
|
||||
EQOS_MAC_MCR_IDX);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief eqos_calculate_per_queue_fifo - Calculate per queue FIFO size
|
||||
*
|
||||
@@ -2385,7 +2331,7 @@ static void eqos_handle_mac_fpe_intrs(struct osi_core_priv_data *osi_core)
|
||||
* - RGMII/SMII MAC interrupt
|
||||
* - If link is down
|
||||
* - Identify speed and mode changes from EQOS_MAC_PCS register and configure the same by calling
|
||||
* eqos_set_speed(), hw_set_mode()(proceed even on error for this call) API's.
|
||||
* hw_set_speed(), hw_set_mode()(proceed even on error for this call) API's.
|
||||
* - SWUD_ID: ETHERNET_NVETHERNETRM_010_1
|
||||
*
|
||||
* @param[in] osi_core: OSI core private data structure. Used param base.
|
||||
@@ -2479,25 +2425,13 @@ static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core,
|
||||
/* TODO: set_tx_clk needs to be done */
|
||||
/* Maybe through workqueue for QNX */
|
||||
if ((mac_pcs & EQOS_MAC_PCS_LNKSPEED) == EQOS_MAC_PCS_LNKSPEED_10) {
|
||||
ret = eqos_set_speed(osi_core, OSI_SPEED_10);
|
||||
if (osi_unlikely(ret < 0)) {
|
||||
OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL,
|
||||
"set speed in 10Mbps failed\n", 0ULL);
|
||||
}
|
||||
hw_set_speed(osi_core, OSI_SPEED_10);
|
||||
} else if ((mac_pcs & EQOS_MAC_PCS_LNKSPEED) ==
|
||||
EQOS_MAC_PCS_LNKSPEED_100) {
|
||||
ret = eqos_set_speed(osi_core, OSI_SPEED_100);
|
||||
if (osi_unlikely(ret < 0)) {
|
||||
OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL,
|
||||
"set speed in 100Mbps failed\n", 0ULL);
|
||||
}
|
||||
hw_set_speed(osi_core, OSI_SPEED_100);
|
||||
} else if ((mac_pcs & EQOS_MAC_PCS_LNKSPEED) ==
|
||||
EQOS_MAC_PCS_LNKSPEED_1000) {
|
||||
ret = eqos_set_speed(osi_core, OSI_SPEED_1000);
|
||||
if (osi_unlikely(ret < 0)) {
|
||||
OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL,
|
||||
"set speed in 1000Mbps failed\n", 0ULL);
|
||||
}
|
||||
hw_set_speed(osi_core, OSI_SPEED_1000);
|
||||
} else {
|
||||
/* Nothing here */
|
||||
}
|
||||
@@ -6688,7 +6622,6 @@ void eqos_init_core_ops(struct core_ops *ops)
|
||||
ops->core_init = eqos_core_init;
|
||||
ops->core_deinit = eqos_core_deinit;
|
||||
ops->handle_common_intr = eqos_handle_common_intr;
|
||||
ops->set_speed = eqos_set_speed;
|
||||
ops->pad_calibrate = eqos_pad_calibrate;
|
||||
ops->config_fw_err_pkts = eqos_config_fw_err_pkts;
|
||||
ops->config_rxcsum_offload = eqos_config_rxcsum_offload;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user