mirror of
git://nv-tegra.nvidia.com/kernel/nvethernetrm.git
synced 2025-12-22 09:12:10 +03:00
core: add CMD_PTP_TSC_CAP to capture time
issue: Requirement is to have a method by which
TSC-PTP-CAPTURE can be initiated.
fix: Having osi_core ioctl to trigger and capture
TSC-PTP timestamp using HW logic.
Caller need to call osi_handle_ioctl with
command as OSI_CMD_CAP_TSC_PTP,
osi_core pointer and osi_core_ptp_tsc_data
structure.
Bug 200736396
Change-Id: I511dc4f490fdef81655a62c18268764741855fe4
Signed-off-by: Rakesh Goyal <rgoyal@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2554284
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
a0c20c02f6
commit
972305578c
@@ -220,6 +220,7 @@ typedef my_lint_64 nvel64_t;
|
||||
#define OSI_CMD_REG_DUMP 44U
|
||||
#define OSI_CMD_STRUCTS_DUMP 45U
|
||||
#endif /* OSI_DEBUG */
|
||||
#define OSI_CMD_CAP_TSC_PTP 46U
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
@@ -942,6 +943,21 @@ struct osi_core_rss {
|
||||
unsigned int table[OSI_RSS_MAX_TABLE_SIZE];
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief osi_core_ptp_tsc_data - Struture used to store TSC and PTP time
|
||||
* information.
|
||||
*/
|
||||
struct osi_core_ptp_tsc_data {
|
||||
/** high bits of MAC */
|
||||
nveu32_t ptp_high_bits;
|
||||
/** low bits of MAC */
|
||||
nveu32_t ptp_low_bits;
|
||||
/** high bits of TSC */
|
||||
nveu32_t tsc_high_bits;
|
||||
/** low bits of TSC */
|
||||
nveu32_t tsc_low_bits;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Max num of MAC core registers to backup. It should be max of or >=
|
||||
* (EQOS_MAX_BAK_IDX=380, coreX,...etc) backup registers.
|
||||
@@ -1115,6 +1131,8 @@ struct osi_ioctl {
|
||||
struct osi_ptp_config ptp_config;
|
||||
/** TX Timestamp structure */
|
||||
struct osi_core_tx_ts tx_ts;
|
||||
/** PTP TSC data */
|
||||
struct osi_core_ptp_tsc_data ptp_tsc;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -2277,6 +2295,10 @@ nve32_t osi_get_hw_features(struct osi_core_priv_data *const osi_core,
|
||||
* Command to free old timestamp for PTP packet
|
||||
* chan - DMA channel number +1. 0 will be used for onestep
|
||||
*
|
||||
* - OSI_CMD_CAP_TSC_PTP
|
||||
* Capture TSC and PTP time stamp
|
||||
* ptp_tsc_data - output structure with time
|
||||
*
|
||||
* @param[in] osi_core: OSI core private data structure.
|
||||
* @param[in] data: void pointer pointing to osi_ioctl
|
||||
*
|
||||
@@ -2469,6 +2491,10 @@ struct osi_core_priv_data *osi_get_core(void);
|
||||
* Command to free old timestamp for PTP packet
|
||||
* chan - DMA channel number +1. 0 will be used for onestep
|
||||
*
|
||||
* - OSI_CMD_CAP_TSC_PTP
|
||||
* Capture TSC and PTP time stamp
|
||||
* ptp_tsc_data - output structure with time
|
||||
*
|
||||
* @param[in] osi_core: OSI core private data structure.
|
||||
* @param[in] data: void pointer pointing to osi_ioctl
|
||||
*
|
||||
|
||||
@@ -270,6 +270,8 @@ struct core_ops {
|
||||
void (*config_macsec_ipg)(struct osi_core_priv_data *const osi_core,
|
||||
const nveu32_t enable);
|
||||
#endif /* MACSEC_SUPPORT */
|
||||
int (*ptp_tsc_capture)(struct osi_core_priv_data *const osi_core,
|
||||
struct osi_core_ptp_tsc_data *data);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -43,6 +43,75 @@ static nve32_t eqos_pre_pad_calibrate(
|
||||
*/
|
||||
static struct core_func_safety eqos_core_safety_config;
|
||||
|
||||
/**
|
||||
* @brief eqos_ptp_tsc_capture - read PTP and TSC registers
|
||||
*
|
||||
* Algorithm:
|
||||
* - write 1 to ETHER_QOS_WRAP_SYNC_TSC_PTP_CAPTURE_0
|
||||
* - wait till ETHER_QOS_WRAP_SYNC_TSC_PTP_CAPTURE_0 is 0x0
|
||||
* - read and return following registers
|
||||
* ETHER_QOS_WRAP_TSC_CAPTURE_LOW_0
|
||||
* ETHER_QOS_WRAP_TSC_CAPTURE_HIGH_0
|
||||
* ETHER_QOS_WRAP_PTP_CAPTURE_LOW_0
|
||||
* ETHER_QOS_WRAP_PTP_CAPTURE_HIGH_0
|
||||
*
|
||||
* @param[in] base: EQOS virtual base address.
|
||||
* @param[out]: osi_core_ptp_tsc_data register
|
||||
*
|
||||
* @note MAC needs to be out of reset and proper clock configured. TSC and PTP
|
||||
* registers should be configured.
|
||||
*
|
||||
* @retval 0 on success
|
||||
* @retval -1 on failure.
|
||||
*/
|
||||
static nve32_t eqos_ptp_tsc_capture(struct osi_core_priv_data *const osi_core,
|
||||
struct osi_core_ptp_tsc_data *data)
|
||||
{
|
||||
nveu32_t retry = 1000U;
|
||||
nveu32_t count = 0U, val = 0U;
|
||||
nve32_t cond = COND_NOT_MET;
|
||||
nve32_t ret = -1;
|
||||
|
||||
if (osi_core->mac_ver < OSI_EQOS_MAC_5_30) {
|
||||
OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID,
|
||||
"ptp_tsc: older IP\n", 0ULL);
|
||||
goto done;
|
||||
}
|
||||
osi_writela(osi_core, OSI_ENABLE, (nveu8_t *)osi_core->base +
|
||||
EQOS_WRAP_SYNC_TSC_PTP_CAPTURE);
|
||||
|
||||
/* Poll Until Poll Condition */
|
||||
while (cond == COND_NOT_MET) {
|
||||
if (count > retry) {
|
||||
/* Max retries reached */
|
||||
goto done;
|
||||
}
|
||||
|
||||
count++;
|
||||
|
||||
val = osi_readla(osi_core, (nveu8_t *)osi_core->base +
|
||||
EQOS_WRAP_SYNC_TSC_PTP_CAPTURE);
|
||||
if ((val & OSI_ENABLE) == OSI_NONE) {
|
||||
cond = COND_MET;
|
||||
} else {
|
||||
/* sleep if SWR is set */
|
||||
osi_core->osd_ops.msleep(1U);
|
||||
}
|
||||
}
|
||||
|
||||
data->tsc_low_bits = osi_readla(osi_core, (nveu8_t *)osi_core->base +
|
||||
EQOS_WRAP_TSC_CAPTURE_LOW);
|
||||
data->tsc_high_bits = osi_readla(osi_core, (nveu8_t *)osi_core->base +
|
||||
EQOS_WRAP_TSC_CAPTURE_HIGH);
|
||||
data->ptp_low_bits = osi_readla(osi_core, (nveu8_t *)osi_core->base +
|
||||
EQOS_WRAP_PTP_CAPTURE_LOW);
|
||||
data->ptp_high_bits = osi_readla(osi_core, (nveu8_t *)osi_core->base +
|
||||
EQOS_WRAP_PTP_CAPTURE_HIGH);
|
||||
ret = 0;
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief eqos_core_safety_writel - Write to safety critical register.
|
||||
*
|
||||
@@ -6461,4 +6530,5 @@ void eqos_init_core_ops(struct core_ops *ops)
|
||||
#ifdef MACSEC_SUPPORT
|
||||
ops->config_macsec_ipg = eqos_config_macsec_ipg;
|
||||
#endif /* MACSEC_SUPPORT */
|
||||
ops->ptp_tsc_capture = eqos_ptp_tsc_capture;
|
||||
}
|
||||
|
||||
@@ -189,6 +189,12 @@
|
||||
#define EQOS_WRAP_COMMON_INTR_ENABLE 0x8704
|
||||
#define EQOS_WRAP_COMMON_INTR_STATUS 0x8708
|
||||
#define EQOS_MAC_SBD_INTR 0x4
|
||||
#define EQOS_WRAP_SYNC_TSC_PTP_CAPTURE 0x800CU
|
||||
#define EQOS_WRAP_TSC_CAPTURE_LOW 0x8010U
|
||||
#define EQOS_WRAP_TSC_CAPTURE_HIGH 0x8014U
|
||||
#define EQOS_WRAP_PTP_CAPTURE_LOW 0x801CU
|
||||
#define EQOS_WRAP_PTP_CAPTURE_HIGH 0x8018U
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
|
||||
@@ -31,6 +31,70 @@
|
||||
#include "mgbe_mmc.h"
|
||||
#include "vlan_filter.h"
|
||||
|
||||
/**
|
||||
* @brief mgbe_ptp_tsc_capture - read PTP and TSC registers
|
||||
*
|
||||
* Algorithm:
|
||||
* - write 1 to MGBE_WRAP_SYNC_TSC_PTP_CAPTURE_0
|
||||
* - wait till MGBE_WRAP_SYNC_TSC_PTP_CAPTURE_0 is 0x0
|
||||
* - read and return following registers
|
||||
* MGBE_WRAP _TSC_CAPTURE_LOW_0
|
||||
* MGBE_WRAP _TSC_CAPTURE_HIGH_0
|
||||
* MGBE_WRAP _PTP_CAPTURE_LOW_0
|
||||
* MGBE_WRAP _PTP_CAPTURE_HIGH_0
|
||||
*
|
||||
* @param[in] base: MGBE virtual base address.
|
||||
* @param[out]: osi_core_ptp_tsc_data register
|
||||
*
|
||||
* @note MAC needs to be out of reset and proper clock configured. TSC and PTP
|
||||
* registers should be configured.
|
||||
*
|
||||
* @retval 0 on success
|
||||
* @retval -1 on failure.
|
||||
*/
|
||||
static nve32_t mgbe_ptp_tsc_capture(struct osi_core_priv_data *const osi_core,
|
||||
struct osi_core_ptp_tsc_data *data)
|
||||
{
|
||||
nveu32_t retry = 1000U;
|
||||
nveu32_t count = 0U, val = 0U;
|
||||
nve32_t cond = COND_NOT_MET;
|
||||
nve32_t ret = -1;
|
||||
|
||||
osi_writela(osi_core, OSI_ENABLE, (nveu8_t *)osi_core->base +
|
||||
MGBE_WRAP_SYNC_TSC_PTP_CAPTURE);
|
||||
|
||||
/* Poll Until Poll Condition */
|
||||
while (cond == COND_NOT_MET) {
|
||||
if (count > retry) {
|
||||
/* Max retries reached */
|
||||
goto done;
|
||||
}
|
||||
|
||||
count++;
|
||||
|
||||
val = osi_readla(osi_core, (nveu8_t *)osi_core->base +
|
||||
MGBE_WRAP_SYNC_TSC_PTP_CAPTURE);
|
||||
if ((val & OSI_ENABLE) == OSI_NONE) {
|
||||
cond = COND_MET;
|
||||
} else {
|
||||
/* sleep if SWR is set */
|
||||
osi_core->osd_ops.msleep(1U);
|
||||
}
|
||||
}
|
||||
|
||||
data->tsc_low_bits = osi_readla(osi_core, (nveu8_t *)osi_core->base +
|
||||
MGBE_WRAP_TSC_CAPTURE_LOW);
|
||||
data->tsc_high_bits = osi_readla(osi_core, (nveu8_t *)osi_core->base +
|
||||
MGBE_WRAP_TSC_CAPTURE_HIGH);
|
||||
data->ptp_low_bits = osi_readla(osi_core, (nveu8_t *)osi_core->base +
|
||||
MGBE_WRAP_PTP_CAPTURE_LOW);
|
||||
data->ptp_high_bits = osi_readla(osi_core, (nveu8_t *)osi_core->base +
|
||||
MGBE_WRAP_PTP_CAPTURE_HIGH);
|
||||
ret = 0;
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief mgbe_config_fw_err_pkts - Configure forwarding of error packets
|
||||
*
|
||||
@@ -5836,6 +5900,7 @@ void mgbe_init_core_ops(struct core_ops *ops)
|
||||
ops->config_frp = mgbe_config_frp;
|
||||
ops->update_frp_entry = mgbe_update_frp_entry;
|
||||
ops->update_frp_nve = mgbe_update_frp_nve;
|
||||
ops->ptp_tsc_capture = mgbe_ptp_tsc_capture;
|
||||
ops->write_reg = mgbe_write_reg;
|
||||
ops->read_reg = mgbe_read_reg;
|
||||
#ifdef MACSEC_SUPPORT
|
||||
|
||||
@@ -129,6 +129,11 @@
|
||||
#define MGBE_WRAP_COMMON_INTR_ENABLE 0x8704
|
||||
#define MGBE_WRAP_COMMON_INTR_STATUS 0x8708
|
||||
#define MGBE_VIRT_INTR_APB_CHX_CNTRL(x) (0x8200U + ((x) * 4U))
|
||||
#define MGBE_WRAP_SYNC_TSC_PTP_CAPTURE 0x800CU
|
||||
#define MGBE_WRAP_TSC_CAPTURE_LOW 0x8010U
|
||||
#define MGBE_WRAP_TSC_CAPTURE_HIGH 0x8014U
|
||||
#define MGBE_WRAP_PTP_CAPTURE_LOW 0x8018U
|
||||
#define MGBE_WRAP_PTP_CAPTURE_HIGH 0x801CU
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
|
||||
@@ -1665,6 +1665,7 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core,
|
||||
free_tx_ts(osi_core, data->arg1_u32);
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
#ifdef OSI_DEBUG
|
||||
case OSI_CMD_REG_DUMP:
|
||||
core_reg_dump(osi_core);
|
||||
@@ -1675,6 +1676,10 @@ nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core,
|
||||
ret = 0;
|
||||
break;
|
||||
#endif /* OSI_DEBUG */
|
||||
case OSI_CMD_CAP_TSC_PTP:
|
||||
ret = ops_p->ptp_tsc_capture(osi_core, &data->ptp_tsc);
|
||||
break;
|
||||
|
||||
default:
|
||||
OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID,
|
||||
"CORE: Incorrect command\n",
|
||||
|
||||
Reference in New Issue
Block a user