Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'octeontx2-cn10k-ptp'

From: Naveen Mamindlapalli <naveenm@marvell.com>
To: <kuba@kernel.org>, <davem@davemloft.net>, <edumazet@google.com>,
<pabeni@redhat.com>, <richardcochran@gmail.com>,
<netdev@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
<sgoutham@marvell.com>, <hkelam@marvell.com>
Cc: Naveen Mamindlapalli <naveenm@marvell.com>
Subject: [net-next PATCH 0/4] Add PTP support for CN10K silicon
Date: Sat, 10 Sep 2022 13:24:12 +0530 [thread overview]
Message-ID: <20220910075416.22887-1-naveenm@marvell.com> (raw)

This patchset adds PTP support for CN10K silicon, specifically
to workaround few hardware issues and to add 1-step mode.

Patchset overview:

Patch #1 returns correct ptp timestamp in nanoseconds captured
when external timestamp event occurs.

Patch #2 adds 1-step mode support.

Patch #3 implements software workaround to generate PPS output properly.

Patch #4 provides a software workaround for the rollover register default
value, which causes ptp to return the wrong timestamp.
====================

Acked-by: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

+359 -41
+2
drivers/net/ethernet/marvell/octeontx2/af/mbox.h
··· 1471 1471 PTP_OP_GET_CLOCK = 1, 1472 1472 PTP_OP_GET_TSTMP = 2, 1473 1473 PTP_OP_SET_THRESH = 3, 1474 + PTP_OP_EXTTS_ON = 4, 1474 1475 }; 1475 1476 1476 1477 struct ptp_req { ··· 1479 1478 u8 op; 1480 1479 s64 scaled_ppm; 1481 1480 u64 thresh; 1481 + int extts_on; 1482 1482 }; 1483 1483 1484 1484 struct ptp_rsp {
+104 -2
drivers/net/ethernet/marvell/octeontx2/af/ptp.c
··· 9 9 #include <linux/device.h> 10 10 #include <linux/module.h> 11 11 #include <linux/pci.h> 12 + #include <linux/hrtimer.h> 13 + #include <linux/ktime.h> 12 14 13 15 #include "ptp.h" 14 16 #include "mbox.h" ··· 52 50 #define PTP_CLOCK_COMP 0xF18ULL 53 51 #define PTP_TIMESTAMP 0xF20ULL 54 52 #define PTP_CLOCK_SEC 0xFD0ULL 53 + #define PTP_SEC_ROLLOVER 0xFD8ULL 55 54 56 55 #define CYCLE_MULT 1000 57 56 58 57 static struct ptp *first_ptp_block; 59 58 static const struct pci_device_id ptp_id_table[]; 59 + 60 + static bool is_ptp_dev_cnf10kb(struct ptp *ptp) 61 + { 62 + return (ptp->pdev->subsystem_device == PCI_SUBSYS_DEVID_CNF10K_B_PTP) ? true : false; 63 + } 64 + 65 + static bool is_ptp_dev_cn10k(struct ptp *ptp) 66 + { 67 + return (ptp->pdev->device == PCI_DEVID_CN10K_PTP) ? true : false; 68 + } 60 69 61 70 static bool cn10k_ptp_errata(struct ptp *ptp) 62 71 { ··· 83 70 ptp->pdev->subsystem_device == PCI_SUBSYS_DEVID_CNF10K_A_PTP) 84 71 return true; 85 72 return false; 73 + } 74 + 75 + static enum hrtimer_restart ptp_reset_thresh(struct hrtimer *hrtimer) 76 + { 77 + struct ptp *ptp = container_of(hrtimer, struct ptp, hrtimer); 78 + ktime_t curr_ts = ktime_get(); 79 + ktime_t delta_ns, period_ns; 80 + u64 ptp_clock_hi; 81 + 82 + /* calculate the elapsed time since last restart */ 83 + delta_ns = ktime_to_ns(ktime_sub(curr_ts, ptp->last_ts)); 84 + 85 + /* if the ptp clock value has crossed 0.5 seconds, 86 + * its too late to update pps threshold value, so 87 + * update threshold after 1 second. 88 + */ 89 + ptp_clock_hi = readq(ptp->reg_base + PTP_CLOCK_HI); 90 + if (ptp_clock_hi > 500000000) { 91 + period_ns = ktime_set(0, (NSEC_PER_SEC + 100 - ptp_clock_hi)); 92 + } else { 93 + writeq(500000000, ptp->reg_base + PTP_PPS_THRESH_HI); 94 + period_ns = ktime_set(0, (NSEC_PER_SEC + 100 - delta_ns)); 95 + } 96 + 97 + hrtimer_forward_now(hrtimer, period_ns); 98 + ptp->last_ts = curr_ts; 99 + 100 + return HRTIMER_RESTART; 101 + } 102 + 103 + static void ptp_hrtimer_start(struct ptp *ptp, ktime_t start_ns) 104 + { 105 + ktime_t period_ns; 106 + 107 + period_ns = ktime_set(0, (NSEC_PER_SEC + 100 - start_ns)); 108 + hrtimer_start(&ptp->hrtimer, period_ns, HRTIMER_MODE_REL); 109 + ptp->last_ts = ktime_get(); 86 110 } 87 111 88 112 static u64 read_ptp_tstmp_sec_nsec(struct ptp *ptp) ··· 296 246 /* sclk is in MHz */ 297 247 ptp->clock_rate = sclk * 1000000; 298 248 249 + /* Program the seconds rollover value to 1 second */ 250 + if (is_ptp_dev_cnf10kb(ptp)) 251 + writeq(0x3b9aca00, ptp->reg_base + PTP_SEC_ROLLOVER); 252 + 299 253 /* Enable PTP clock */ 300 254 clock_cfg = readq(ptp->reg_base + PTP_CLOCK_CFG); 301 255 ··· 324 270 /* Set 50% duty cycle for 1Hz output */ 325 271 writeq(0x1dcd650000000000, ptp->reg_base + PTP_PPS_HI_INCR); 326 272 writeq(0x1dcd650000000000, ptp->reg_base + PTP_PPS_LO_INCR); 273 + if (cn10k_ptp_errata(ptp)) { 274 + /* The ptp_clock_hi rollsover to zero once clock cycle before it 275 + * reaches one second boundary. so, program the pps_lo_incr in 276 + * such a way that the pps threshold value comparison at one 277 + * second boundary will succeed and pps edge changes. After each 278 + * one second boundary, the hrtimer handler will be invoked and 279 + * reprograms the pps threshold value. 280 + */ 281 + ptp->clock_period = NSEC_PER_SEC / ptp->clock_rate; 282 + writeq((0x1dcd6500ULL - ptp->clock_period) << 32, 283 + ptp->reg_base + PTP_PPS_LO_INCR); 284 + } 327 285 328 286 if (cn10k_ptp_errata(ptp)) 329 287 clock_comp = ptp_calc_adjusted_comp(ptp->clock_rate); ··· 348 282 349 283 static int ptp_get_tstmp(struct ptp *ptp, u64 *clk) 350 284 { 351 - *clk = readq(ptp->reg_base + PTP_TIMESTAMP); 285 + u64 timestamp; 286 + 287 + if (is_ptp_dev_cn10k(ptp)) { 288 + timestamp = readq(ptp->reg_base + PTP_TIMESTAMP); 289 + *clk = (timestamp >> 32) * NSEC_PER_SEC + (timestamp & 0xFFFFFFFF); 290 + } else { 291 + *clk = readq(ptp->reg_base + PTP_TIMESTAMP); 292 + } 352 293 353 294 return 0; 354 295 } 355 296 356 297 static int ptp_set_thresh(struct ptp *ptp, u64 thresh) 357 298 { 358 - writeq(thresh, ptp->reg_base + PTP_PPS_THRESH_HI); 299 + if (!cn10k_ptp_errata(ptp)) 300 + writeq(thresh, ptp->reg_base + PTP_PPS_THRESH_HI); 301 + 302 + return 0; 303 + } 304 + 305 + static int ptp_extts_on(struct ptp *ptp, int on) 306 + { 307 + u64 ptp_clock_hi; 308 + 309 + if (cn10k_ptp_errata(ptp)) { 310 + if (on) { 311 + ptp_clock_hi = readq(ptp->reg_base + PTP_CLOCK_HI); 312 + ptp_hrtimer_start(ptp, (ktime_t)ptp_clock_hi); 313 + } else { 314 + if (hrtimer_active(&ptp->hrtimer)) 315 + hrtimer_cancel(&ptp->hrtimer); 316 + } 317 + } 359 318 360 319 return 0; 361 320 } ··· 420 329 else 421 330 ptp->read_ptp_tstmp = &read_ptp_tstmp_nsec; 422 331 332 + if (cn10k_ptp_errata(ptp)) { 333 + hrtimer_init(&ptp->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 334 + ptp->hrtimer.function = ptp_reset_thresh; 335 + } 336 + 423 337 return 0; 424 338 425 339 error_free: ··· 448 352 { 449 353 struct ptp *ptp = pci_get_drvdata(pdev); 450 354 u64 clock_cfg; 355 + 356 + if (cn10k_ptp_errata(ptp) && hrtimer_active(&ptp->hrtimer)) 357 + hrtimer_cancel(&ptp->hrtimer); 451 358 452 359 if (IS_ERR_OR_NULL(ptp)) 453 360 return; ··· 518 419 break; 519 420 case PTP_OP_SET_THRESH: 520 421 err = ptp_set_thresh(rvu->ptp, req->thresh); 422 + break; 423 + case PTP_OP_EXTTS_ON: 424 + err = ptp_extts_on(rvu->ptp, req->extts_on); 521 425 break; 522 426 default: 523 427 err = -EINVAL;
+3
drivers/net/ethernet/marvell/octeontx2/af/ptp.h
··· 17 17 void __iomem *reg_base; 18 18 u64 (*read_ptp_tstmp)(struct ptp *ptp); 19 19 spinlock_t ptp_lock; /* lock */ 20 + struct hrtimer hrtimer; 21 + ktime_t last_ts; 20 22 u32 clock_rate; 23 + u32 clock_period; 21 24 }; 22 25 23 26 struct ptp *ptp_get(void);
+17 -2
drivers/net/ethernet/marvell/octeontx2/af/rpm.c
··· 415 415 return; 416 416 417 417 cfg = rpm_read(rpm, lmac_id, RPMX_CMRX_CFG); 418 - if (enable) 418 + if (enable) { 419 419 cfg |= RPMX_RX_TS_PREPEND; 420 - else 420 + cfg |= RPMX_TX_PTP_1S_SUPPORT; 421 + } else { 421 422 cfg &= ~RPMX_RX_TS_PREPEND; 423 + cfg &= ~RPMX_TX_PTP_1S_SUPPORT; 424 + } 425 + 422 426 rpm_write(rpm, lmac_id, RPMX_CMRX_CFG, cfg); 427 + 428 + cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_XIF_MODE); 429 + 430 + if (enable) { 431 + cfg |= RPMX_ONESTEP_ENABLE; 432 + cfg &= ~RPMX_TS_BINARY_MODE; 433 + } else { 434 + cfg &= ~RPMX_ONESTEP_ENABLE; 435 + } 436 + 437 + rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_XIF_MODE, cfg); 423 438 } 424 439 425 440 int rpm_lmac_pfc_config(void *rpmd, int lmac_id, u8 tx_pause, u8 rx_pause, u16 pfc_en)
+5
drivers/net/ethernet/marvell/octeontx2/af/rpm.h
··· 16 16 /* Registers */ 17 17 #define RPMX_CMRX_CFG 0x00 18 18 #define RPMX_RX_TS_PREPEND BIT_ULL(22) 19 + #define RPMX_TX_PTP_1S_SUPPORT BIT_ULL(17) 19 20 #define RPMX_CMRX_SW_INT 0x180 20 21 #define RPMX_CMRX_SW_INT_W1S 0x188 21 22 #define RPMX_CMRX_SW_INT_ENA_W1S 0x198 ··· 72 71 #define RPMX_MTI_MAC100X_CL01_PAUSE_QUANTA 0x80A8 73 72 #define RPMX_MTI_MAC100X_CL89_PAUSE_QUANTA 0x8108 74 73 #define RPM_DEFAULT_PAUSE_TIME 0x7FF 74 + 75 + #define RPMX_MTI_MAC100X_XIF_MODE 0x8100 76 + #define RPMX_ONESTEP_ENABLE BIT_ULL(5) 77 + #define RPMX_TS_BINARY_MODE BIT_ULL(11) 75 78 76 79 /* Function Declarations */ 77 80 int rpm_get_nr_lmacs(void *rpmd);
+7 -1
drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
··· 4296 4296 /* Restore CINT timer delay to HW reset values */ 4297 4297 rvu_write64(rvu, blkaddr, NIX_AF_CINT_DELAY, 0x0ULL); 4298 4298 4299 + cfg = rvu_read64(rvu, blkaddr, NIX_AF_SEB_CFG); 4300 + 4299 4301 /* For better performance use NDC TX instead of NDC RX for SQ's SQEs" */ 4300 - rvu_write64(rvu, blkaddr, NIX_AF_SEB_CFG, 0x1ULL); 4302 + cfg |= 1ULL; 4303 + if (!is_rvu_otx2(rvu)) 4304 + cfg |= NIX_PTP_1STEP_EN; 4305 + 4306 + rvu_write64(rvu, blkaddr, NIX_AF_SEB_CFG, cfg); 4301 4307 4302 4308 if (is_block_implemented(hw, blkaddr)) { 4303 4309 err = nix_setup_txschq(rvu, nix_hw, blkaddr);
+1
drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.h
··· 266 266 #define NIX_AF_TX_NPC_CAPTURE_CONFIG (0x0660) 267 267 #define NIX_AF_TX_NPC_CAPTURE_INFO (0x0670) 268 268 #define NIX_AF_SEB_CFG (0x05F0) 269 + #define NIX_PTP_1STEP_EN BIT_ULL(2) 269 270 270 271 #define NIX_AF_DEBUG_NPC_RESP_DATAX(a) (0x680 | (a) << 3) 271 272 #define NIX_AF_SMQX_CFG(a) (0x700 | (a) << 16)
+13
drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
··· 243 243 #define CN10K_MBOX 1 244 244 #define CN10K_LMTST 2 245 245 #define CN10K_RPM 3 246 + #define CN10K_PTP_ONESTEP 4 246 247 unsigned long cap_flag; 247 248 248 249 #define LMT_LINE_SIZE 128 ··· 277 276 struct otx2_nic *pf; 278 277 }; 279 278 279 + /* PTPv2 originTimestamp structure */ 280 + struct ptpv2_tstamp { 281 + __be16 seconds_msb; /* 16 bits + */ 282 + __be32 seconds_lsb; /* 32 bits = 48 bits*/ 283 + __be32 nanoseconds; 284 + } __packed; 285 + 280 286 struct otx2_ptp { 281 287 struct ptp_clock_info ptp_info; 282 288 struct ptp_clock *ptp_clock; ··· 299 291 struct ptp_pin_desc extts_config; 300 292 u64 (*convert_rx_ptp_tstmp)(u64 timestamp); 301 293 u64 (*convert_tx_ptp_tstmp)(u64 timestamp); 294 + struct delayed_work synctstamp_work; 295 + u64 tstamp; 296 + u32 base_ns; 302 297 }; 303 298 304 299 #define OTX2_HW_TIMESTAMP_LEN 8 ··· 374 363 #define OTX2_FLAG_TC_MATCHALL_EGRESS_ENABLED BIT_ULL(12) 375 364 #define OTX2_FLAG_TC_MATCHALL_INGRESS_ENABLED BIT_ULL(13) 376 365 #define OTX2_FLAG_DMACFLTR_SUPPORT BIT_ULL(14) 366 + #define OTX2_FLAG_PTP_ONESTEP_SYNC BIT_ULL(15) 377 367 #define OTX2_FLAG_ADPTV_INT_COAL_ENABLED BIT_ULL(16) 378 368 u64 flags; 379 369 u64 *cq_op_addr; ··· 506 494 __set_bit(CN10K_MBOX, &hw->cap_flag); 507 495 __set_bit(CN10K_LMTST, &hw->cap_flag); 508 496 __set_bit(CN10K_RPM, &hw->cap_flag); 497 + __set_bit(CN10K_PTP_ONESTEP, &hw->cap_flag); 509 498 } 510 499 } 511 500
+5 -3
drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c
··· 963 963 964 964 info->phc_index = otx2_ptp_clock_index(pfvf); 965 965 966 - info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON); 966 + info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON); 967 + if (test_bit(CN10K_PTP_ONESTEP, &pfvf->hw.cap_flag)) 968 + info->tx_types |= BIT(HWTSTAMP_TX_ONESTEP_SYNC); 967 969 968 - info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) | 969 - (1 << HWTSTAMP_FILTER_ALL); 970 + info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) | 971 + BIT(HWTSTAMP_FILTER_ALL); 970 972 971 973 return 0; 972 974 }
+11
drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
··· 2038 2038 2039 2039 switch (config.tx_type) { 2040 2040 case HWTSTAMP_TX_OFF: 2041 + if (pfvf->flags & OTX2_FLAG_PTP_ONESTEP_SYNC) 2042 + pfvf->flags &= ~OTX2_FLAG_PTP_ONESTEP_SYNC; 2043 + 2044 + cancel_delayed_work(&pfvf->ptp->synctstamp_work); 2041 2045 otx2_config_hw_tx_tstamp(pfvf, false); 2042 2046 break; 2047 + case HWTSTAMP_TX_ONESTEP_SYNC: 2048 + if (!test_bit(CN10K_PTP_ONESTEP, &pfvf->hw.cap_flag)) 2049 + return -ERANGE; 2050 + pfvf->flags |= OTX2_FLAG_PTP_ONESTEP_SYNC; 2051 + schedule_delayed_work(&pfvf->ptp->synctstamp_work, 2052 + msecs_to_jiffies(500)); 2053 + fallthrough; 2043 2054 case HWTSTAMP_TX_ON: 2044 2055 otx2_config_hw_tx_tstamp(pfvf, true); 2045 2056 break;
+77 -26
drivers/net/ethernet/marvell/octeontx2/nic/otx2_ptp.c
··· 10 10 #include "otx2_common.h" 11 11 #include "otx2_ptp.h" 12 12 13 + static u64 otx2_ptp_get_clock(struct otx2_ptp *ptp) 14 + { 15 + struct ptp_req *req; 16 + struct ptp_rsp *rsp; 17 + int err; 18 + 19 + if (!ptp->nic) 20 + return 0; 21 + 22 + req = otx2_mbox_alloc_msg_ptp_op(&ptp->nic->mbox); 23 + if (!req) 24 + return 0; 25 + 26 + req->op = PTP_OP_GET_CLOCK; 27 + 28 + err = otx2_sync_mbox_msg(&ptp->nic->mbox); 29 + if (err) 30 + return 0; 31 + 32 + rsp = (struct ptp_rsp *)otx2_mbox_get_rsp(&ptp->nic->mbox.mbox, 0, 33 + &req->hdr); 34 + if (IS_ERR(rsp)) 35 + return 0; 36 + 37 + return rsp->clk; 38 + } 39 + 13 40 static int otx2_ptp_adjfine(struct ptp_clock_info *ptp_info, long scaled_ppm) 14 41 { 15 42 struct otx2_ptp *ptp = container_of(ptp_info, struct otx2_ptp, ··· 73 46 return otx2_sync_mbox_msg(&ptp->nic->mbox); 74 47 } 75 48 76 - static u64 ptp_cc_read(const struct cyclecounter *cc) 49 + static int ptp_extts_on(struct otx2_ptp *ptp, int on) 77 50 { 78 - struct otx2_ptp *ptp = container_of(cc, struct otx2_ptp, cycle_counter); 79 51 struct ptp_req *req; 80 - struct ptp_rsp *rsp; 81 - int err; 82 52 83 53 if (!ptp->nic) 84 - return 0; 54 + return -ENODEV; 85 55 86 56 req = otx2_mbox_alloc_msg_ptp_op(&ptp->nic->mbox); 87 57 if (!req) 88 - return 0; 58 + return -ENOMEM; 89 59 90 - req->op = PTP_OP_GET_CLOCK; 60 + req->op = PTP_OP_EXTTS_ON; 61 + req->extts_on = on; 91 62 92 - err = otx2_sync_mbox_msg(&ptp->nic->mbox); 93 - if (err) 94 - return 0; 63 + return otx2_sync_mbox_msg(&ptp->nic->mbox); 64 + } 95 65 96 - rsp = (struct ptp_rsp *)otx2_mbox_get_rsp(&ptp->nic->mbox.mbox, 0, 97 - &req->hdr); 98 - if (IS_ERR(rsp)) 99 - return 0; 66 + static u64 ptp_cc_read(const struct cyclecounter *cc) 67 + { 68 + struct otx2_ptp *ptp = container_of(cc, struct otx2_ptp, cycle_counter); 100 69 101 - return rsp->clk; 70 + return otx2_ptp_get_clock(ptp); 102 71 } 103 72 104 73 static u64 ptp_tstmp_read(struct otx2_ptp *ptp) ··· 124 101 return rsp->clk; 125 102 } 126 103 104 + static void otx2_get_ptpclock(struct otx2_ptp *ptp, u64 *tstamp) 105 + { 106 + struct otx2_nic *pfvf = ptp->nic; 107 + 108 + mutex_lock(&pfvf->mbox.lock); 109 + *tstamp = timecounter_read(&ptp->time_counter); 110 + mutex_unlock(&pfvf->mbox.lock); 111 + } 112 + 127 113 static int otx2_ptp_adjtime(struct ptp_clock_info *ptp_info, s64 delta) 128 114 { 129 115 struct otx2_ptp *ptp = container_of(ptp_info, struct otx2_ptp, ··· 151 119 { 152 120 struct otx2_ptp *ptp = container_of(ptp_info, struct otx2_ptp, 153 121 ptp_info); 154 - struct otx2_nic *pfvf = ptp->nic; 155 - u64 nsec; 122 + u64 tstamp; 156 123 157 - mutex_lock(&pfvf->mbox.lock); 158 - nsec = timecounter_read(&ptp->time_counter); 159 - mutex_unlock(&pfvf->mbox.lock); 160 - 161 - *ts = ns_to_timespec64(nsec); 124 + otx2_get_ptpclock(ptp, &tstamp); 125 + *ts = ns_to_timespec64(tstamp); 162 126 163 127 return 0; 164 128 } ··· 206 178 event.index = 0; 207 179 event.timestamp = timecounter_cyc2time(&ptp->time_counter, tstmp); 208 180 ptp_clock_event(ptp->ptp_clock, &event); 209 - ptp->last_extts = tstmp; 210 - 211 181 new_thresh = tstmp % 500000000; 212 182 if (ptp->thresh != new_thresh) { 213 183 mutex_lock(&ptp->nic->mbox.lock); ··· 213 187 mutex_unlock(&ptp->nic->mbox.lock); 214 188 ptp->thresh = new_thresh; 215 189 } 190 + ptp->last_extts = tstmp; 216 191 } 217 192 schedule_delayed_work(&ptp->extts_work, msecs_to_jiffies(200)); 193 + } 194 + 195 + static void otx2_sync_tstamp(struct work_struct *work) 196 + { 197 + struct otx2_ptp *ptp = container_of(work, struct otx2_ptp, 198 + synctstamp_work.work); 199 + struct otx2_nic *pfvf = ptp->nic; 200 + u64 tstamp; 201 + 202 + mutex_lock(&pfvf->mbox.lock); 203 + tstamp = otx2_ptp_get_clock(ptp); 204 + mutex_unlock(&pfvf->mbox.lock); 205 + 206 + ptp->tstamp = timecounter_cyc2time(&pfvf->ptp->time_counter, tstamp); 207 + ptp->base_ns = tstamp % NSEC_PER_SEC; 208 + 209 + schedule_delayed_work(&ptp->synctstamp_work, msecs_to_jiffies(250)); 218 210 } 219 211 220 212 static int otx2_ptp_enable(struct ptp_clock_info *ptp_info, ··· 251 207 rq->extts.index); 252 208 if (pin < 0) 253 209 return -EBUSY; 254 - if (on) 210 + if (on) { 211 + ptp_extts_on(ptp, on); 255 212 schedule_delayed_work(&ptp->extts_work, msecs_to_jiffies(200)); 256 - else 213 + } else { 214 + ptp_extts_on(ptp, on); 257 215 cancel_delayed_work_sync(&ptp->extts_work); 216 + } 258 217 return 0; 259 218 default: 260 219 break; ··· 349 302 ptp_ptr->convert_tx_ptp_tstmp = &cn10k_ptp_convert_timestamp; 350 303 } 351 304 305 + INIT_DELAYED_WORK(&ptp_ptr->synctstamp_work, otx2_sync_tstamp); 306 + 352 307 pfvf->ptp = ptp_ptr; 353 308 354 309 error: ··· 364 315 365 316 if (!ptp) 366 317 return; 318 + 319 + cancel_delayed_work(&pfvf->ptp->synctstamp_work); 367 320 368 321 ptp_clock_unregister(ptp->ptp_clock); 369 322 kfree(ptp);
+9 -2
drivers/net/ethernet/marvell/octeontx2/nic/otx2_struct.h
··· 236 236 237 237 /* NIX send memory subdescriptor structure */ 238 238 struct nix_sqe_mem_s { 239 - u64 offset : 16; /* W0 */ 240 - u64 rsvd_51_16 : 36; 239 + u64 start_offset : 8; 240 + u64 rsvd_11_8 : 4; 241 + u64 rsvd_12 : 1; 242 + u64 udp_csum_crt : 1; 243 + u64 update64 : 1; 244 + u64 rsvd_15_16 : 1; 245 + u64 base_ns : 32; 246 + u64 step_type : 1; 247 + u64 rsvd_51_49 : 3; 241 248 u64 per_lso_seg : 1; 242 249 u64 wmem : 1; 243 250 u64 dsz : 2;
+105 -5
drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
··· 19 19 #include "cn10k.h" 20 20 21 21 #define CQE_ADDR(CQ, idx) ((CQ)->cqe_base + ((CQ)->cqe_size * (idx))) 22 + #define PTP_PORT 0x13F 23 + /* PTPv2 header Original Timestamp starts at byte offset 34 and 24 + * contains 6 byte seconds field and 4 byte nano seconds field. 25 + */ 26 + #define PTP_SYNC_SEC_OFFSET 34 27 + 22 28 static bool otx2_xdp_rcv_pkt_handler(struct otx2_nic *pfvf, 23 29 struct bpf_prog *prog, 24 30 struct nix_cqe_rx_s *cqe, ··· 692 686 } 693 687 694 688 static void otx2_sqe_add_mem(struct otx2_snd_queue *sq, int *offset, 695 - int alg, u64 iova) 689 + int alg, u64 iova, int ptp_offset, 690 + u64 base_ns, int udp_csum) 696 691 { 697 692 struct nix_sqe_mem_s *mem; 698 693 ··· 702 695 mem->alg = alg; 703 696 mem->wmem = 1; /* wait for the memory operation */ 704 697 mem->addr = iova; 698 + 699 + if (ptp_offset) { 700 + mem->start_offset = ptp_offset; 701 + mem->udp_csum_crt = udp_csum; 702 + mem->base_ns = base_ns; 703 + mem->step_type = 1; 704 + } 705 705 706 706 *offset += sizeof(*mem); 707 707 } ··· 966 952 return skb_shinfo(skb)->gso_segs; 967 953 } 968 954 955 + static bool otx2_validate_network_transport(struct sk_buff *skb) 956 + { 957 + if ((ip_hdr(skb)->protocol == IPPROTO_UDP) || 958 + (ipv6_hdr(skb)->nexthdr == IPPROTO_UDP)) { 959 + struct udphdr *udph = udp_hdr(skb); 960 + 961 + if (udph->source == htons(PTP_PORT) && 962 + udph->dest == htons(PTP_PORT)) 963 + return true; 964 + } 965 + 966 + return false; 967 + } 968 + 969 + static bool otx2_ptp_is_sync(struct sk_buff *skb, int *offset, int *udp_csum) 970 + { 971 + struct ethhdr *eth = (struct ethhdr *)(skb->data); 972 + u16 nix_offload_hlen = 0, inner_vhlen = 0; 973 + u8 *data = skb->data, *msgtype; 974 + __be16 proto = eth->h_proto; 975 + int network_depth = 0; 976 + 977 + /* NIX is programmed to offload outer VLAN header 978 + * in case of single vlan protocol field holds Network header ETH_IP/V6 979 + * in case of stacked vlan protocol field holds Inner vlan (8100) 980 + */ 981 + if (skb->dev->features & NETIF_F_HW_VLAN_CTAG_TX && 982 + skb->dev->features & NETIF_F_HW_VLAN_STAG_TX) { 983 + if (skb->vlan_proto == htons(ETH_P_8021AD)) { 984 + /* Get vlan protocol */ 985 + proto = __vlan_get_protocol(skb, eth->h_proto, NULL); 986 + /* SKB APIs like skb_transport_offset does not include 987 + * offloaded vlan header length. Need to explicitly add 988 + * the length 989 + */ 990 + nix_offload_hlen = VLAN_HLEN; 991 + inner_vhlen = VLAN_HLEN; 992 + } else if (skb->vlan_proto == htons(ETH_P_8021Q)) { 993 + nix_offload_hlen = VLAN_HLEN; 994 + } 995 + } else if (eth_type_vlan(eth->h_proto)) { 996 + proto = __vlan_get_protocol(skb, eth->h_proto, &network_depth); 997 + } 998 + 999 + switch (ntohs(proto)) { 1000 + case ETH_P_1588: 1001 + if (network_depth) 1002 + *offset = network_depth; 1003 + else 1004 + *offset = ETH_HLEN + nix_offload_hlen + 1005 + inner_vhlen; 1006 + break; 1007 + case ETH_P_IP: 1008 + case ETH_P_IPV6: 1009 + if (!otx2_validate_network_transport(skb)) 1010 + return false; 1011 + 1012 + *udp_csum = 1; 1013 + *offset = nix_offload_hlen + skb_transport_offset(skb) + 1014 + sizeof(struct udphdr); 1015 + } 1016 + 1017 + msgtype = data + *offset; 1018 + 1019 + /* Check PTP messageId is SYNC or not */ 1020 + return (*msgtype & 0xf) == 0; 1021 + } 1022 + 969 1023 static void otx2_set_txtstamp(struct otx2_nic *pfvf, struct sk_buff *skb, 970 1024 struct otx2_snd_queue *sq, int *offset) 971 1025 { 1026 + struct ptpv2_tstamp *origin_tstamp; 1027 + int ptp_offset = 0, udp_csum = 0; 1028 + struct timespec64 ts; 972 1029 u64 iova; 973 1030 974 - if (!skb_shinfo(skb)->gso_size && 975 - skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) { 976 - skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; 1031 + if (unlikely(!skb_shinfo(skb)->gso_size && 1032 + (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))) { 1033 + if (unlikely(pfvf->flags & OTX2_FLAG_PTP_ONESTEP_SYNC)) { 1034 + if (otx2_ptp_is_sync(skb, &ptp_offset, &udp_csum)) { 1035 + origin_tstamp = (struct ptpv2_tstamp *) 1036 + ((u8 *)skb->data + ptp_offset + 1037 + PTP_SYNC_SEC_OFFSET); 1038 + ts = ns_to_timespec64(pfvf->ptp->tstamp); 1039 + origin_tstamp->seconds_msb = htons((ts.tv_sec >> 32) & 0xffff); 1040 + origin_tstamp->seconds_lsb = htonl(ts.tv_sec & 0xffffffff); 1041 + origin_tstamp->nanoseconds = htonl(ts.tv_nsec); 1042 + /* Point to correction field in PTP packet */ 1043 + ptp_offset += 8; 1044 + } 1045 + } else { 1046 + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; 1047 + } 977 1048 iova = sq->timestamps->iova + (sq->head * sizeof(u64)); 978 - otx2_sqe_add_mem(sq, offset, NIX_SENDMEMALG_E_SETTSTMP, iova); 1049 + otx2_sqe_add_mem(sq, offset, NIX_SENDMEMALG_E_SETTSTMP, iova, 1050 + ptp_offset, pfvf->ptp->base_ns, udp_csum); 979 1051 } else { 980 1052 skb_tx_timestamp(skb); 981 1053 }