Extend the ENA PHC communication layer to retrieve error bound from the device.
Update ena_com_phc_get_timestamp() to retrieve error_bound alongside timestamps. Add error handling and statistics for error_bound retrieval failures. Signed-off-by: Amit Bernstein <[email protected]> Signed-off-by: Arthur Kiyanovski <[email protected]> --- .../device_drivers/ethernet/amazon/ena.rst | 2 ++ drivers/net/ethernet/amazon/ena/ena_com.c | 36 ++++++++++++------- drivers/net/ethernet/amazon/ena/ena_com.h | 5 ++- drivers/net/ethernet/amazon/ena/ena_debugfs.c | 3 ++ drivers/net/ethernet/amazon/ena/ena_phc.c | 3 +- 5 files changed, 34 insertions(+), 15 deletions(-) diff --git a/Documentation/networking/device_drivers/ethernet/amazon/ena.rst b/Documentation/networking/device_drivers/ethernet/amazon/ena.rst index 14784a0..ce9ba84 100644 --- a/Documentation/networking/device_drivers/ethernet/amazon/ena.rst +++ b/Documentation/networking/device_drivers/ethernet/amazon/ena.rst @@ -306,6 +306,8 @@ PHC errors must remain below 1% of all PHC requests to maintain the desired leve **phc_err_dv** | Number of failed get time attempts due to device errors (entering into block state). **phc_err_ts** | Number of failed get time attempts due to timestamp errors (entering into block state), | This occurs if driver exceeded the request limit or device received an invalid timestamp. +**phc_err_eb** | Number of failed get time attempts due to error bound errors (entering into block state), + | This occurs if device received an excessively high or invalid error bound. ================= ====================================================== PHC timeouts: diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c b/drivers/net/ethernet/amazon/ena/ena_com.c index 2579104..832c4c1 100644 --- a/drivers/net/ethernet/amazon/ena/ena_com.c +++ b/drivers/net/ethernet/amazon/ena/ena_com.c @@ -45,7 +45,8 @@ #define ENA_PHC_DEFAULT_EXPIRE_TIMEOUT_USEC 10 #define ENA_PHC_DEFAULT_BLOCK_TIMEOUT_USEC 1000 #define ENA_PHC_REQ_ID_OFFSET 0xDEAD -#define ENA_PHC_ERROR_FLAGS (ENA_ADMIN_PHC_ERROR_FLAG_TIMESTAMP) +#define ENA_PHC_ERROR_FLAGS (ENA_ADMIN_PHC_ERROR_FLAG_TIMESTAMP | \ + ENA_ADMIN_PHC_ERROR_FLAG_ERROR_BOUND) /*****************************************************************************/ /*****************************************************************************/ @@ -1726,7 +1727,7 @@ int ena_com_phc_config(struct ena_com_dev *ena_dev) if (phc->expire_timeout_usec > phc->block_timeout_usec) phc->expire_timeout_usec = phc->block_timeout_usec; - /* Prepare PHC feature command */ + /* Prepare PHC config feature command */ memset(&set_feat_cmd, 0x0, sizeof(set_feat_cmd)); set_feat_cmd.aq_common_descriptor.opcode = ENA_ADMIN_SET_FEATURE; set_feat_cmd.feat_common.feature_id = ENA_ADMIN_PHC_CONFIG; @@ -1781,7 +1782,8 @@ void ena_com_phc_destroy(struct ena_com_dev *ena_dev) phc->virt_addr = NULL; } -int ena_com_phc_get_timestamp(struct ena_com_dev *ena_dev, u64 *timestamp) +int ena_com_phc_get_timestamp(struct ena_com_dev *ena_dev, u64 *timestamp, + u32 *error_bound) { const ktime_t zero_system_time = ktime_set(0, 0); struct ena_com_phc_info *phc = &ena_dev->phc; @@ -1828,6 +1830,8 @@ int ena_com_phc_get_timestamp(struct ena_com_dev *ena_dev, u64 *timestamp) * a PHC error, this occurs if device: * - exceeded the get time request limit * - received an invalid timestamp + * - received an excessively high error bound + * - received an invalid error bound */ netdev_err(ena_dev->net_device, "PHC get time request 0x%x failed (error 0x%x)\n", @@ -1835,9 +1839,11 @@ int ena_com_phc_get_timestamp(struct ena_com_dev *ena_dev, u64 *timestamp) resp->error_flags); phc->stats.phc_err_ts += !!(resp->error_flags & ENA_ADMIN_PHC_ERROR_FLAG_TIMESTAMP); + phc->stats.phc_err_eb += !!(resp->error_flags & + ENA_ADMIN_PHC_ERROR_FLAG_ERROR_BOUND); } else { /* Device updated req_id during blocking time - * with valid timestamp + * with valid timestamp and error bound */ phc->stats.phc_exp++; } @@ -1864,9 +1870,9 @@ int ena_com_phc_get_timestamp(struct ena_com_dev *ena_dev, u64 *timestamp) /* Stalling until the device updates req_id */ while (1) { if (unlikely(ktime_after(ktime_get(), expire_time))) { - /* Gave up waiting for updated req_id, PHC enters into - * blocked state until passing blocking time, - * during this time any get PHC timestamp will fail with + /* Gave up waiting for updated req_id, + * PHC enters into blocked state until passing blocking + * time, during this time, any request will fail with * device busy error */ ret = -EBUSY; @@ -1882,14 +1888,15 @@ int ena_com_phc_get_timestamp(struct ena_com_dev *ena_dev, u64 *timestamp) } /* req_id was updated by the device which indicates that - * PHC timestamp and error_flags are updated too, - * checking errors before retrieving timestamp + * PHC timestamp, error_bound and error_flags are updated too, + * checking error flags before retrieving timestamp and + * error_bound values */ if (unlikely(resp->error_flags & ENA_PHC_ERROR_FLAGS)) { - /* Retrieved invalid PHC timestamp, PHC enters into - * blocked state until passing blocking time, - * during this time any get PHC timestamp requests - * will fail with device busy error + /* Retrieved timestamp or error bound errors, + * PHC enters into blocked state until passing blocking + * time, during this time, any request will fail with + * device busy error */ ret = -EBUSY; break; @@ -1897,12 +1904,15 @@ int ena_com_phc_get_timestamp(struct ena_com_dev *ena_dev, u64 *timestamp) /* PHC timestamp value is returned to the caller */ *timestamp = resp->timestamp; + if (error_bound) + *error_bound = resp->error_bound; /* Update statistic on valid PHC timestamp retrieval */ phc->stats.phc_cnt++; /* This indicates PHC state is active */ phc->system_time = zero_system_time; + break; } diff --git a/drivers/net/ethernet/amazon/ena/ena_com.h b/drivers/net/ethernet/amazon/ena/ena_com.h index 64df2c4..fcbff1a 100644 --- a/drivers/net/ethernet/amazon/ena/ena_com.h +++ b/drivers/net/ethernet/amazon/ena/ena_com.h @@ -216,6 +216,7 @@ struct ena_com_stats_phc { u64 phc_skp; u64 phc_err_dv; u64 phc_err_ts; + u64 phc_err_eb; }; struct ena_com_admin_queue { @@ -462,9 +463,11 @@ void ena_com_phc_destroy(struct ena_com_dev *ena_dev); /* ena_com_phc_get_timestamp - Retrieve PHC timestamp * @ena_dev: ENA communication layer struct * @timestamp: Retrieved PHC timestamp + * @error_bound: maximum possible deviation of the timestamp (nanosecond) * @return - 0 on success, negative value on failure */ -int ena_com_phc_get_timestamp(struct ena_com_dev *ena_dev, u64 *timestamp); +int ena_com_phc_get_timestamp(struct ena_com_dev *ena_dev, u64 *timestamp, + u32 *error_bound); /* ena_com_set_mmio_read_mode - Enable/disable the indirect mmio reg read mechanism * @ena_dev: ENA communication layer struct diff --git a/drivers/net/ethernet/amazon/ena/ena_debugfs.c b/drivers/net/ethernet/amazon/ena/ena_debugfs.c index 46ed809..db9d184 100644 --- a/drivers/net/ethernet/amazon/ena/ena_debugfs.c +++ b/drivers/net/ethernet/amazon/ena/ena_debugfs.c @@ -32,6 +32,9 @@ static int phc_stats_show(struct seq_file *file, void *priv) seq_printf(file, "phc_err_ts: %llu\n", adapter->ena_dev->phc.stats.phc_err_ts); + seq_printf(file, + "phc_err_eb: %llu\n", + adapter->ena_dev->phc.stats.phc_err_eb); return 0; } diff --git a/drivers/net/ethernet/amazon/ena/ena_phc.c b/drivers/net/ethernet/amazon/ena/ena_phc.c index c2a3ff1..2bcb5af 100644 --- a/drivers/net/ethernet/amazon/ena/ena_phc.c +++ b/drivers/net/ethernet/amazon/ena/ena_phc.c @@ -40,7 +40,8 @@ static int ena_phc_gettimex64(struct ptp_clock_info *clock_info, ptp_read_system_prets(sts); rc = ena_com_phc_get_timestamp(phc_info->adapter->ena_dev, - ×tamp_nsec); + ×tamp_nsec, + NULL); ptp_read_system_postts(sts); -- 2.47.3
