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:
Rakesh Goyal
2021-06-09 16:50:47 +05:30
committed by mobile promotions
parent a0c20c02f6
commit 972305578c
7 changed files with 179 additions and 0 deletions

View File

@@ -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
*

View File

@@ -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);
};

View File

@@ -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;
}

View File

@@ -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
/** @} */
/**

View File

@@ -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

View File

@@ -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
/** @} */
/**

View File

@@ -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",