Skip to content

Commit eec9de0

Browse files
committed
Merge branch 'mlx5-ptm-cross-timestamping-support'
Tariq Toukan says: ==================== mlx5 PTM cross timestamping support This patchset by Rahul and Carolina adds PTM (Precision Time Measurement) support to the mlx5 driver. PTM is a PCI extended capability introduced by PCI-SIG for providing an accurate read of the device clock offset without being impacted by asymmetric bus transfer rates. The performance of PTM on ConnectX-7 was evaluated using both real-time (RTC) and free-running (FRC) clocks under traffic and no traffic conditions. Tests with phc2sys measured the maximum offset values at a 50Hz rate, with and without PTM. Results: 1. No traffic +-----+--------+--------+ | | No-PTM | PTM | +-----+--------+--------+ | FRC | 125 ns | <29 ns | +-----+--------+--------+ | RTC | 248 ns | <34 ns | +-----+--------+--------+ 2. With traffic +-----+--------+--------+ | | No-PTM | PTM | +-----+--------+--------+ | FRC | 254 ns | <40 ns | +-----+--------+--------+ | RTC | 255 ns | <45 ns | +-----+--------+--------+ v2: https://lore.kernel.org/[email protected] ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents e8fc78e + d17125f commit eec9de0

File tree

6 files changed

+149
-1
lines changed

6 files changed

+149
-1
lines changed

drivers/net/ethernet/mellanox/mlx5/core/fw.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ int mlx5_query_hca_caps(struct mlx5_core_dev *dev)
224224
if (MLX5_CAP_GEN(dev, mcam_reg)) {
225225
mlx5_get_mcam_access_reg_group(dev, MLX5_MCAM_REGS_FIRST_128);
226226
mlx5_get_mcam_access_reg_group(dev, MLX5_MCAM_REGS_0x9100_0x917F);
227+
mlx5_get_mcam_access_reg_group(dev, MLX5_MCAM_REGS_0x9180_0x91FF);
227228
}
228229

229230
if (MLX5_CAP_GEN(dev, qcam_reg))

drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@
3838
#include "lib/eq.h"
3939
#include "en.h"
4040
#include "clock.h"
41+
#ifdef CONFIG_X86
42+
#include <linux/timekeeping.h>
43+
#include <linux/cpufeature.h>
44+
#endif /* CONFIG_X86 */
4145

4246
enum {
4347
MLX5_PIN_MODE_IN = 0x0,
@@ -148,6 +152,87 @@ static int mlx5_set_mtutc(struct mlx5_core_dev *dev, u32 *mtutc, u32 size)
148152
MLX5_REG_MTUTC, 0, 1);
149153
}
150154

155+
#ifdef CONFIG_X86
156+
static bool mlx5_is_ptm_source_time_available(struct mlx5_core_dev *dev)
157+
{
158+
u32 out[MLX5_ST_SZ_DW(mtptm_reg)] = {0};
159+
u32 in[MLX5_ST_SZ_DW(mtptm_reg)] = {0};
160+
int err;
161+
162+
if (!MLX5_CAP_MCAM_REG3(dev, mtptm))
163+
return false;
164+
165+
err = mlx5_core_access_reg(dev, in, sizeof(in), out, sizeof(out), MLX5_REG_MTPTM,
166+
0, 0);
167+
if (err)
168+
return false;
169+
170+
return !!MLX5_GET(mtptm_reg, out, psta);
171+
}
172+
173+
static int mlx5_mtctr_syncdevicetime(ktime_t *device_time,
174+
struct system_counterval_t *sys_counterval,
175+
void *ctx)
176+
{
177+
u32 out[MLX5_ST_SZ_DW(mtctr_reg)] = {0};
178+
u32 in[MLX5_ST_SZ_DW(mtctr_reg)] = {0};
179+
struct mlx5_core_dev *mdev = ctx;
180+
bool real_time_mode;
181+
u64 host, device;
182+
int err;
183+
184+
real_time_mode = mlx5_real_time_mode(mdev);
185+
186+
MLX5_SET(mtctr_reg, in, first_clock_timestamp_request,
187+
MLX5_MTCTR_REQUEST_PTM_ROOT_CLOCK);
188+
MLX5_SET(mtctr_reg, in, second_clock_timestamp_request,
189+
real_time_mode ? MLX5_MTCTR_REQUEST_REAL_TIME_CLOCK :
190+
MLX5_MTCTR_REQUEST_FREE_RUNNING_COUNTER);
191+
192+
err = mlx5_core_access_reg(mdev, in, sizeof(in), out, sizeof(out), MLX5_REG_MTCTR,
193+
0, 0);
194+
if (err)
195+
return err;
196+
197+
if (!MLX5_GET(mtctr_reg, out, first_clock_valid) ||
198+
!MLX5_GET(mtctr_reg, out, second_clock_valid))
199+
return -EINVAL;
200+
201+
host = MLX5_GET64(mtctr_reg, out, first_clock_timestamp);
202+
*sys_counterval = (struct system_counterval_t) {
203+
.cycles = host,
204+
.cs_id = CSID_X86_ART,
205+
.use_nsecs = true,
206+
};
207+
208+
device = MLX5_GET64(mtctr_reg, out, second_clock_timestamp);
209+
if (real_time_mode)
210+
*device_time = ns_to_ktime(REAL_TIME_TO_NS(device >> 32, device & U32_MAX));
211+
else
212+
*device_time = mlx5_timecounter_cyc2time(&mdev->clock, device);
213+
214+
return 0;
215+
}
216+
217+
static int mlx5_ptp_getcrosststamp(struct ptp_clock_info *ptp,
218+
struct system_device_crosststamp *cts)
219+
{
220+
struct mlx5_clock *clock = container_of(ptp, struct mlx5_clock, ptp_info);
221+
struct system_time_snapshot history_begin = {0};
222+
struct mlx5_core_dev *mdev;
223+
224+
mdev = container_of(clock, struct mlx5_core_dev, clock);
225+
226+
if (!mlx5_is_ptm_source_time_available(mdev))
227+
return -EBUSY;
228+
229+
ktime_get_snapshot(&history_begin);
230+
231+
return get_device_system_crosststamp(mlx5_mtctr_syncdevicetime, mdev,
232+
&history_begin, cts);
233+
}
234+
#endif /* CONFIG_X86 */
235+
151236
static u64 mlx5_read_time(struct mlx5_core_dev *dev,
152237
struct ptp_system_timestamp *sts,
153238
bool real_time)
@@ -1034,6 +1119,12 @@ static void mlx5_init_timer_clock(struct mlx5_core_dev *mdev)
10341119
if (MLX5_CAP_MCAM_REG(mdev, mtutc))
10351120
mlx5_init_timer_max_freq_adjustment(mdev);
10361121

1122+
#ifdef CONFIG_X86
1123+
if (MLX5_CAP_MCAM_REG3(mdev, mtptm) &&
1124+
MLX5_CAP_MCAM_REG3(mdev, mtctr) && boot_cpu_has(X86_FEATURE_ART))
1125+
clock->ptp_info.getcrosststamp = mlx5_ptp_getcrosststamp;
1126+
#endif /* CONFIG_X86 */
1127+
10371128
mlx5_timecounter_init(mdev);
10381129
mlx5_init_clock_info(mdev);
10391130
mlx5_init_overflow_period(clock);

drivers/net/ethernet/mellanox/mlx5/core/main.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -923,6 +923,11 @@ static int mlx5_pci_init(struct mlx5_core_dev *dev, struct pci_dev *pdev,
923923
}
924924

925925
mlx5_pci_vsc_init(dev);
926+
927+
err = pci_enable_ptm(pdev, NULL);
928+
if (err)
929+
mlx5_core_info(dev, "PTM is not supported by PCIe\n");
930+
926931
return 0;
927932

928933
err_clr_master:
@@ -939,6 +944,7 @@ static void mlx5_pci_close(struct mlx5_core_dev *dev)
939944
* before removing the pci bars
940945
*/
941946
mlx5_drain_health_wq(dev);
947+
pci_disable_ptm(dev->pdev);
942948
iounmap(dev->iseg);
943949
release_bar(dev->pdev);
944950
mlx5_pci_disable_device(dev);

include/linux/mlx5/device.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1243,7 +1243,8 @@ enum mlx5_pcam_feature_groups {
12431243
enum mlx5_mcam_reg_groups {
12441244
MLX5_MCAM_REGS_FIRST_128 = 0x0,
12451245
MLX5_MCAM_REGS_0x9100_0x917F = 0x2,
1246-
MLX5_MCAM_REGS_NUM = 0x3,
1246+
MLX5_MCAM_REGS_0x9180_0x91FF = 0x3,
1247+
MLX5_MCAM_REGS_NUM = 0x4,
12471248
};
12481249

12491250
enum mlx5_mcam_feature_groups {
@@ -1392,6 +1393,10 @@ enum mlx5_qcam_feature_groups {
13921393
MLX5_GET(mcam_reg, (mdev)->caps.mcam[MLX5_MCAM_REGS_0x9100_0x917F], \
13931394
mng_access_reg_cap_mask.access_regs2.reg)
13941395

1396+
#define MLX5_CAP_MCAM_REG3(mdev, reg) \
1397+
MLX5_GET(mcam_reg, (mdev)->caps.mcam[MLX5_MCAM_REGS_0x9180_0x91FF], \
1398+
mng_access_reg_cap_mask.access_regs3.reg)
1399+
13951400
#define MLX5_CAP_MCAM_FEATURE(mdev, fld) \
13961401
MLX5_GET(mcam_reg, (mdev)->caps.mcam, mng_feature_cap_mask.enhanced_features.fld)
13971402

include/linux/mlx5/driver.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,8 @@ enum {
159159
MLX5_REG_MSECQ = 0x9155,
160160
MLX5_REG_MSEES = 0x9156,
161161
MLX5_REG_MIRC = 0x9162,
162+
MLX5_REG_MTPTM = 0x9180,
163+
MLX5_REG_MTCTR = 0x9181,
162164
MLX5_REG_SBCAM = 0xB01F,
163165
MLX5_REG_RESOURCE_DUMP = 0xC000,
164166
MLX5_REG_DTOR = 0xC00E,

include/linux/mlx5/mlx5_ifc.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10401,6 +10401,18 @@ struct mlx5_ifc_mcam_access_reg_bits2 {
1040110401
u8 regs_31_to_0[0x20];
1040210402
};
1040310403

10404+
struct mlx5_ifc_mcam_access_reg_bits3 {
10405+
u8 regs_127_to_96[0x20];
10406+
10407+
u8 regs_95_to_64[0x20];
10408+
10409+
u8 regs_63_to_32[0x20];
10410+
10411+
u8 regs_31_to_2[0x1e];
10412+
u8 mtctr[0x1];
10413+
u8 mtptm[0x1];
10414+
};
10415+
1040410416
struct mlx5_ifc_mcam_reg_bits {
1040510417
u8 reserved_at_0[0x8];
1040610418
u8 feature_group[0x8];
@@ -10413,6 +10425,7 @@ struct mlx5_ifc_mcam_reg_bits {
1041310425
struct mlx5_ifc_mcam_access_reg_bits access_regs;
1041410426
struct mlx5_ifc_mcam_access_reg_bits1 access_regs1;
1041510427
struct mlx5_ifc_mcam_access_reg_bits2 access_regs2;
10428+
struct mlx5_ifc_mcam_access_reg_bits3 access_regs3;
1041610429
u8 reserved_at_0[0x80];
1041710430
} mng_access_reg_cap_mask;
1041810431

@@ -11166,6 +11179,34 @@ struct mlx5_ifc_mtmp_reg_bits {
1116611179
u8 sensor_name_lo[0x20];
1116711180
};
1116811181

11182+
struct mlx5_ifc_mtptm_reg_bits {
11183+
u8 reserved_at_0[0x10];
11184+
u8 psta[0x1];
11185+
u8 reserved_at_11[0xf];
11186+
11187+
u8 reserved_at_20[0x60];
11188+
};
11189+
11190+
enum {
11191+
MLX5_MTCTR_REQUEST_NOP = 0x0,
11192+
MLX5_MTCTR_REQUEST_PTM_ROOT_CLOCK = 0x1,
11193+
MLX5_MTCTR_REQUEST_FREE_RUNNING_COUNTER = 0x2,
11194+
MLX5_MTCTR_REQUEST_REAL_TIME_CLOCK = 0x3,
11195+
};
11196+
11197+
struct mlx5_ifc_mtctr_reg_bits {
11198+
u8 first_clock_timestamp_request[0x8];
11199+
u8 second_clock_timestamp_request[0x8];
11200+
u8 reserved_at_10[0x10];
11201+
11202+
u8 first_clock_valid[0x1];
11203+
u8 second_clock_valid[0x1];
11204+
u8 reserved_at_22[0x1e];
11205+
11206+
u8 first_clock_timestamp[0x40];
11207+
u8 second_clock_timestamp[0x40];
11208+
};
11209+
1116911210
union mlx5_ifc_ports_control_registers_document_bits {
1117011211
struct mlx5_ifc_bufferx_reg_bits bufferx_reg;
1117111212
struct mlx5_ifc_eth_2819_cntrs_grp_data_layout_bits eth_2819_cntrs_grp_data_layout;
@@ -11230,6 +11271,8 @@ union mlx5_ifc_ports_control_registers_document_bits {
1123011271
struct mlx5_ifc_mrtc_reg_bits mrtc_reg;
1123111272
struct mlx5_ifc_mtcap_reg_bits mtcap_reg;
1123211273
struct mlx5_ifc_mtmp_reg_bits mtmp_reg;
11274+
struct mlx5_ifc_mtptm_reg_bits mtptm_reg;
11275+
struct mlx5_ifc_mtctr_reg_bits mtctr_reg;
1123311276
u8 reserved_at_0[0x60e0];
1123411277
};
1123511278

0 commit comments

Comments
 (0)