1c9c12d33SAleksey Makarov // SPDX-License-Identifier: GPL-2.0 2cb0e3ec4SSunil Goutham /* Marvell RVU Ethernet driver 3c9c12d33SAleksey Makarov * 4cb0e3ec4SSunil Goutham * Copyright (C) 2020 Marvell. 5cb0e3ec4SSunil Goutham * 6c9c12d33SAleksey Makarov */ 7c9c12d33SAleksey Makarov 88581fd40SJakub Kicinski #include <linux/module.h> 98581fd40SJakub Kicinski 10c9c12d33SAleksey Makarov #include "otx2_common.h" 11c9c12d33SAleksey Makarov #include "otx2_ptp.h" 12c9c12d33SAleksey Makarov 132958d17aSHariprasad Kelam static u64 otx2_ptp_get_clock(struct otx2_ptp *ptp) 142958d17aSHariprasad Kelam { 152958d17aSHariprasad Kelam struct ptp_req *req; 162958d17aSHariprasad Kelam struct ptp_rsp *rsp; 172958d17aSHariprasad Kelam int err; 182958d17aSHariprasad Kelam 192958d17aSHariprasad Kelam if (!ptp->nic) 202958d17aSHariprasad Kelam return 0; 212958d17aSHariprasad Kelam 222958d17aSHariprasad Kelam req = otx2_mbox_alloc_msg_ptp_op(&ptp->nic->mbox); 232958d17aSHariprasad Kelam if (!req) 242958d17aSHariprasad Kelam return 0; 252958d17aSHariprasad Kelam 262958d17aSHariprasad Kelam req->op = PTP_OP_GET_CLOCK; 272958d17aSHariprasad Kelam 282958d17aSHariprasad Kelam err = otx2_sync_mbox_msg(&ptp->nic->mbox); 292958d17aSHariprasad Kelam if (err) 302958d17aSHariprasad Kelam return 0; 312958d17aSHariprasad Kelam 322958d17aSHariprasad Kelam rsp = (struct ptp_rsp *)otx2_mbox_get_rsp(&ptp->nic->mbox.mbox, 0, 332958d17aSHariprasad Kelam &req->hdr); 342958d17aSHariprasad Kelam if (IS_ERR(rsp)) 352958d17aSHariprasad Kelam return 0; 362958d17aSHariprasad Kelam 372958d17aSHariprasad Kelam return rsp->clk; 382958d17aSHariprasad Kelam } 392958d17aSHariprasad Kelam 40c9c12d33SAleksey Makarov static int otx2_ptp_adjfine(struct ptp_clock_info *ptp_info, long scaled_ppm) 41c9c12d33SAleksey Makarov { 42c9c12d33SAleksey Makarov struct otx2_ptp *ptp = container_of(ptp_info, struct otx2_ptp, 43c9c12d33SAleksey Makarov ptp_info); 44c9c12d33SAleksey Makarov struct ptp_req *req; 45c9c12d33SAleksey Makarov 46c9c12d33SAleksey Makarov if (!ptp->nic) 47c9c12d33SAleksey Makarov return -ENODEV; 48c9c12d33SAleksey Makarov 49c9c12d33SAleksey Makarov req = otx2_mbox_alloc_msg_ptp_op(&ptp->nic->mbox); 50c9c12d33SAleksey Makarov if (!req) 51c9c12d33SAleksey Makarov return -ENOMEM; 52c9c12d33SAleksey Makarov 53c9c12d33SAleksey Makarov req->op = PTP_OP_ADJFINE; 54c9c12d33SAleksey Makarov req->scaled_ppm = scaled_ppm; 55c9c12d33SAleksey Makarov 56b8d90937SZheng Yongjun return otx2_sync_mbox_msg(&ptp->nic->mbox); 57c9c12d33SAleksey Makarov } 58c9c12d33SAleksey Makarov 5999bbc4aeSYi Guo static int ptp_set_thresh(struct otx2_ptp *ptp, u64 thresh) 6099bbc4aeSYi Guo { 6199bbc4aeSYi Guo struct ptp_req *req; 6299bbc4aeSYi Guo 6399bbc4aeSYi Guo if (!ptp->nic) 6499bbc4aeSYi Guo return -ENODEV; 6599bbc4aeSYi Guo 6699bbc4aeSYi Guo req = otx2_mbox_alloc_msg_ptp_op(&ptp->nic->mbox); 6799bbc4aeSYi Guo if (!req) 6899bbc4aeSYi Guo return -ENOMEM; 6999bbc4aeSYi Guo 7099bbc4aeSYi Guo req->op = PTP_OP_SET_THRESH; 7199bbc4aeSYi Guo req->thresh = thresh; 7299bbc4aeSYi Guo 7399bbc4aeSYi Guo return otx2_sync_mbox_msg(&ptp->nic->mbox); 7499bbc4aeSYi Guo } 7599bbc4aeSYi Guo 76*2ef4e45dSNaveen Mamindlapalli static int ptp_extts_on(struct otx2_ptp *ptp, int on) 77*2ef4e45dSNaveen Mamindlapalli { 78*2ef4e45dSNaveen Mamindlapalli struct ptp_req *req; 79*2ef4e45dSNaveen Mamindlapalli 80*2ef4e45dSNaveen Mamindlapalli if (!ptp->nic) 81*2ef4e45dSNaveen Mamindlapalli return -ENODEV; 82*2ef4e45dSNaveen Mamindlapalli 83*2ef4e45dSNaveen Mamindlapalli req = otx2_mbox_alloc_msg_ptp_op(&ptp->nic->mbox); 84*2ef4e45dSNaveen Mamindlapalli if (!req) 85*2ef4e45dSNaveen Mamindlapalli return -ENOMEM; 86*2ef4e45dSNaveen Mamindlapalli 87*2ef4e45dSNaveen Mamindlapalli req->op = PTP_OP_EXTTS_ON; 88*2ef4e45dSNaveen Mamindlapalli req->extts_on = on; 89*2ef4e45dSNaveen Mamindlapalli 90*2ef4e45dSNaveen Mamindlapalli return otx2_sync_mbox_msg(&ptp->nic->mbox); 91*2ef4e45dSNaveen Mamindlapalli } 92*2ef4e45dSNaveen Mamindlapalli 93c9c12d33SAleksey Makarov static u64 ptp_cc_read(const struct cyclecounter *cc) 94c9c12d33SAleksey Makarov { 95c9c12d33SAleksey Makarov struct otx2_ptp *ptp = container_of(cc, struct otx2_ptp, cycle_counter); 96c9c12d33SAleksey Makarov 972958d17aSHariprasad Kelam return otx2_ptp_get_clock(ptp); 98c9c12d33SAleksey Makarov } 99c9c12d33SAleksey Makarov 10099bbc4aeSYi Guo static u64 ptp_tstmp_read(struct otx2_ptp *ptp) 10199bbc4aeSYi Guo { 10299bbc4aeSYi Guo struct ptp_req *req; 10399bbc4aeSYi Guo struct ptp_rsp *rsp; 10499bbc4aeSYi Guo int err; 10599bbc4aeSYi Guo 10699bbc4aeSYi Guo if (!ptp->nic) 10799bbc4aeSYi Guo return 0; 10899bbc4aeSYi Guo 10999bbc4aeSYi Guo req = otx2_mbox_alloc_msg_ptp_op(&ptp->nic->mbox); 11099bbc4aeSYi Guo if (!req) 11199bbc4aeSYi Guo return 0; 11299bbc4aeSYi Guo 11399bbc4aeSYi Guo req->op = PTP_OP_GET_TSTMP; 11499bbc4aeSYi Guo 11599bbc4aeSYi Guo err = otx2_sync_mbox_msg(&ptp->nic->mbox); 11699bbc4aeSYi Guo if (err) 11799bbc4aeSYi Guo return 0; 11899bbc4aeSYi Guo 11999bbc4aeSYi Guo rsp = (struct ptp_rsp *)otx2_mbox_get_rsp(&ptp->nic->mbox.mbox, 0, 12099bbc4aeSYi Guo &req->hdr); 12199bbc4aeSYi Guo if (IS_ERR(rsp)) 12299bbc4aeSYi Guo return 0; 12399bbc4aeSYi Guo 12499bbc4aeSYi Guo return rsp->clk; 12599bbc4aeSYi Guo } 12699bbc4aeSYi Guo 1272958d17aSHariprasad Kelam static void otx2_get_ptpclock(struct otx2_ptp *ptp, u64 *tstamp) 1282958d17aSHariprasad Kelam { 1292958d17aSHariprasad Kelam struct otx2_nic *pfvf = ptp->nic; 1302958d17aSHariprasad Kelam 1312958d17aSHariprasad Kelam mutex_lock(&pfvf->mbox.lock); 1322958d17aSHariprasad Kelam *tstamp = timecounter_read(&ptp->time_counter); 1332958d17aSHariprasad Kelam mutex_unlock(&pfvf->mbox.lock); 1342958d17aSHariprasad Kelam } 1352958d17aSHariprasad Kelam 136c9c12d33SAleksey Makarov static int otx2_ptp_adjtime(struct ptp_clock_info *ptp_info, s64 delta) 137c9c12d33SAleksey Makarov { 138c9c12d33SAleksey Makarov struct otx2_ptp *ptp = container_of(ptp_info, struct otx2_ptp, 139c9c12d33SAleksey Makarov ptp_info); 140c9c12d33SAleksey Makarov struct otx2_nic *pfvf = ptp->nic; 141c9c12d33SAleksey Makarov 142c9c12d33SAleksey Makarov mutex_lock(&pfvf->mbox.lock); 143c9c12d33SAleksey Makarov timecounter_adjtime(&ptp->time_counter, delta); 144c9c12d33SAleksey Makarov mutex_unlock(&pfvf->mbox.lock); 145c9c12d33SAleksey Makarov 146c9c12d33SAleksey Makarov return 0; 147c9c12d33SAleksey Makarov } 148c9c12d33SAleksey Makarov 149c9c12d33SAleksey Makarov static int otx2_ptp_gettime(struct ptp_clock_info *ptp_info, 150c9c12d33SAleksey Makarov struct timespec64 *ts) 151c9c12d33SAleksey Makarov { 152c9c12d33SAleksey Makarov struct otx2_ptp *ptp = container_of(ptp_info, struct otx2_ptp, 153c9c12d33SAleksey Makarov ptp_info); 1542958d17aSHariprasad Kelam u64 tstamp; 155c9c12d33SAleksey Makarov 1562958d17aSHariprasad Kelam otx2_get_ptpclock(ptp, &tstamp); 1572958d17aSHariprasad Kelam *ts = ns_to_timespec64(tstamp); 158c9c12d33SAleksey Makarov 159c9c12d33SAleksey Makarov return 0; 160c9c12d33SAleksey Makarov } 161c9c12d33SAleksey Makarov 162c9c12d33SAleksey Makarov static int otx2_ptp_settime(struct ptp_clock_info *ptp_info, 163c9c12d33SAleksey Makarov const struct timespec64 *ts) 164c9c12d33SAleksey Makarov { 165c9c12d33SAleksey Makarov struct otx2_ptp *ptp = container_of(ptp_info, struct otx2_ptp, 166c9c12d33SAleksey Makarov ptp_info); 167c9c12d33SAleksey Makarov struct otx2_nic *pfvf = ptp->nic; 168c9c12d33SAleksey Makarov u64 nsec; 169c9c12d33SAleksey Makarov 170c9c12d33SAleksey Makarov nsec = timespec64_to_ns(ts); 171c9c12d33SAleksey Makarov 172c9c12d33SAleksey Makarov mutex_lock(&pfvf->mbox.lock); 173c9c12d33SAleksey Makarov timecounter_init(&ptp->time_counter, &ptp->cycle_counter, nsec); 174c9c12d33SAleksey Makarov mutex_unlock(&pfvf->mbox.lock); 175c9c12d33SAleksey Makarov 176c9c12d33SAleksey Makarov return 0; 177c9c12d33SAleksey Makarov } 178c9c12d33SAleksey Makarov 17999bbc4aeSYi Guo static int otx2_ptp_verify_pin(struct ptp_clock_info *ptp, unsigned int pin, 18099bbc4aeSYi Guo enum ptp_pin_function func, unsigned int chan) 18199bbc4aeSYi Guo { 18299bbc4aeSYi Guo switch (func) { 18399bbc4aeSYi Guo case PTP_PF_NONE: 18499bbc4aeSYi Guo case PTP_PF_EXTTS: 18599bbc4aeSYi Guo break; 18699bbc4aeSYi Guo case PTP_PF_PEROUT: 18799bbc4aeSYi Guo case PTP_PF_PHYSYNC: 18899bbc4aeSYi Guo return -1; 18999bbc4aeSYi Guo } 19099bbc4aeSYi Guo return 0; 19199bbc4aeSYi Guo } 19299bbc4aeSYi Guo 19399bbc4aeSYi Guo static void otx2_ptp_extts_check(struct work_struct *work) 19499bbc4aeSYi Guo { 19599bbc4aeSYi Guo struct otx2_ptp *ptp = container_of(work, struct otx2_ptp, 19699bbc4aeSYi Guo extts_work.work); 19799bbc4aeSYi Guo struct ptp_clock_event event; 19899bbc4aeSYi Guo u64 tstmp, new_thresh; 19999bbc4aeSYi Guo 20099bbc4aeSYi Guo mutex_lock(&ptp->nic->mbox.lock); 20199bbc4aeSYi Guo tstmp = ptp_tstmp_read(ptp); 20299bbc4aeSYi Guo mutex_unlock(&ptp->nic->mbox.lock); 20399bbc4aeSYi Guo 20499bbc4aeSYi Guo if (tstmp != ptp->last_extts) { 20599bbc4aeSYi Guo event.type = PTP_CLOCK_EXTTS; 20699bbc4aeSYi Guo event.index = 0; 20799bbc4aeSYi Guo event.timestamp = timecounter_cyc2time(&ptp->time_counter, tstmp); 20899bbc4aeSYi Guo ptp_clock_event(ptp->ptp_clock, &event); 20999bbc4aeSYi Guo new_thresh = tstmp % 500000000; 21099bbc4aeSYi Guo if (ptp->thresh != new_thresh) { 21199bbc4aeSYi Guo mutex_lock(&ptp->nic->mbox.lock); 21299bbc4aeSYi Guo ptp_set_thresh(ptp, new_thresh); 21399bbc4aeSYi Guo mutex_unlock(&ptp->nic->mbox.lock); 21499bbc4aeSYi Guo ptp->thresh = new_thresh; 21599bbc4aeSYi Guo } 216*2ef4e45dSNaveen Mamindlapalli ptp->last_extts = tstmp; 21799bbc4aeSYi Guo } 21899bbc4aeSYi Guo schedule_delayed_work(&ptp->extts_work, msecs_to_jiffies(200)); 21999bbc4aeSYi Guo } 22099bbc4aeSYi Guo 2212958d17aSHariprasad Kelam static void otx2_sync_tstamp(struct work_struct *work) 2222958d17aSHariprasad Kelam { 2232958d17aSHariprasad Kelam struct otx2_ptp *ptp = container_of(work, struct otx2_ptp, 2242958d17aSHariprasad Kelam synctstamp_work.work); 2252958d17aSHariprasad Kelam struct otx2_nic *pfvf = ptp->nic; 2262958d17aSHariprasad Kelam u64 tstamp; 2272958d17aSHariprasad Kelam 2282958d17aSHariprasad Kelam mutex_lock(&pfvf->mbox.lock); 2292958d17aSHariprasad Kelam tstamp = otx2_ptp_get_clock(ptp); 2302958d17aSHariprasad Kelam mutex_unlock(&pfvf->mbox.lock); 2312958d17aSHariprasad Kelam 2322958d17aSHariprasad Kelam ptp->tstamp = timecounter_cyc2time(&pfvf->ptp->time_counter, tstamp); 2332958d17aSHariprasad Kelam ptp->base_ns = tstamp % NSEC_PER_SEC; 2342958d17aSHariprasad Kelam 2352958d17aSHariprasad Kelam schedule_delayed_work(&ptp->synctstamp_work, msecs_to_jiffies(250)); 2362958d17aSHariprasad Kelam } 2372958d17aSHariprasad Kelam 238c9c12d33SAleksey Makarov static int otx2_ptp_enable(struct ptp_clock_info *ptp_info, 239c9c12d33SAleksey Makarov struct ptp_clock_request *rq, int on) 240c9c12d33SAleksey Makarov { 24199bbc4aeSYi Guo struct otx2_ptp *ptp = container_of(ptp_info, struct otx2_ptp, 24299bbc4aeSYi Guo ptp_info); 24375f81afbSColin Ian King int pin; 24499bbc4aeSYi Guo 24599bbc4aeSYi Guo if (!ptp->nic) 24699bbc4aeSYi Guo return -ENODEV; 24799bbc4aeSYi Guo 24899bbc4aeSYi Guo switch (rq->type) { 24999bbc4aeSYi Guo case PTP_CLK_REQ_EXTTS: 25099bbc4aeSYi Guo pin = ptp_find_pin(ptp->ptp_clock, PTP_PF_EXTTS, 25199bbc4aeSYi Guo rq->extts.index); 25299bbc4aeSYi Guo if (pin < 0) 25399bbc4aeSYi Guo return -EBUSY; 254*2ef4e45dSNaveen Mamindlapalli if (on) { 255*2ef4e45dSNaveen Mamindlapalli ptp_extts_on(ptp, on); 25699bbc4aeSYi Guo schedule_delayed_work(&ptp->extts_work, msecs_to_jiffies(200)); 257*2ef4e45dSNaveen Mamindlapalli } else { 258*2ef4e45dSNaveen Mamindlapalli ptp_extts_on(ptp, on); 25999bbc4aeSYi Guo cancel_delayed_work_sync(&ptp->extts_work); 260*2ef4e45dSNaveen Mamindlapalli } 26199bbc4aeSYi Guo return 0; 26299bbc4aeSYi Guo default: 26399bbc4aeSYi Guo break; 26499bbc4aeSYi Guo } 265c9c12d33SAleksey Makarov return -EOPNOTSUPP; 266c9c12d33SAleksey Makarov } 267c9c12d33SAleksey Makarov 268c9c12d33SAleksey Makarov int otx2_ptp_init(struct otx2_nic *pfvf) 269c9c12d33SAleksey Makarov { 270c9c12d33SAleksey Makarov struct otx2_ptp *ptp_ptr; 271c9c12d33SAleksey Makarov struct cyclecounter *cc; 272c9c12d33SAleksey Makarov struct ptp_req *req; 273c9c12d33SAleksey Makarov int err; 274c9c12d33SAleksey Makarov 27543510ef4SNaveen Mamindlapalli if (is_otx2_lbkvf(pfvf->pdev)) { 27643510ef4SNaveen Mamindlapalli pfvf->ptp = NULL; 27743510ef4SNaveen Mamindlapalli return 0; 27843510ef4SNaveen Mamindlapalli } 27943510ef4SNaveen Mamindlapalli 280c9c12d33SAleksey Makarov mutex_lock(&pfvf->mbox.lock); 281c9c12d33SAleksey Makarov /* check if PTP block is available */ 282c9c12d33SAleksey Makarov req = otx2_mbox_alloc_msg_ptp_op(&pfvf->mbox); 283c9c12d33SAleksey Makarov if (!req) { 284c9c12d33SAleksey Makarov mutex_unlock(&pfvf->mbox.lock); 285c9c12d33SAleksey Makarov return -ENOMEM; 286c9c12d33SAleksey Makarov } 287c9c12d33SAleksey Makarov 288c9c12d33SAleksey Makarov req->op = PTP_OP_GET_CLOCK; 289c9c12d33SAleksey Makarov 290c9c12d33SAleksey Makarov err = otx2_sync_mbox_msg(&pfvf->mbox); 291c9c12d33SAleksey Makarov if (err) { 292c9c12d33SAleksey Makarov mutex_unlock(&pfvf->mbox.lock); 293c9c12d33SAleksey Makarov return err; 294c9c12d33SAleksey Makarov } 295c9c12d33SAleksey Makarov mutex_unlock(&pfvf->mbox.lock); 296c9c12d33SAleksey Makarov 297c9c12d33SAleksey Makarov ptp_ptr = kzalloc(sizeof(*ptp_ptr), GFP_KERNEL); 298c9c12d33SAleksey Makarov if (!ptp_ptr) { 299c9c12d33SAleksey Makarov err = -ENOMEM; 300c9c12d33SAleksey Makarov goto error; 301c9c12d33SAleksey Makarov } 302c9c12d33SAleksey Makarov 303c9c12d33SAleksey Makarov ptp_ptr->nic = pfvf; 304c9c12d33SAleksey Makarov 305c9c12d33SAleksey Makarov cc = &ptp_ptr->cycle_counter; 306c9c12d33SAleksey Makarov cc->read = ptp_cc_read; 307c9c12d33SAleksey Makarov cc->mask = CYCLECOUNTER_MASK(64); 308c9c12d33SAleksey Makarov cc->mult = 1; 309c9c12d33SAleksey Makarov cc->shift = 0; 310c9c12d33SAleksey Makarov 311c9c12d33SAleksey Makarov timecounter_init(&ptp_ptr->time_counter, &ptp_ptr->cycle_counter, 312c9c12d33SAleksey Makarov ktime_to_ns(ktime_get_real())); 313c9c12d33SAleksey Makarov 31499bbc4aeSYi Guo snprintf(ptp_ptr->extts_config.name, sizeof(ptp_ptr->extts_config.name), "TSTAMP"); 31599bbc4aeSYi Guo ptp_ptr->extts_config.index = 0; 31699bbc4aeSYi Guo ptp_ptr->extts_config.func = PTP_PF_NONE; 31799bbc4aeSYi Guo 318c9c12d33SAleksey Makarov ptp_ptr->ptp_info = (struct ptp_clock_info) { 319c9c12d33SAleksey Makarov .owner = THIS_MODULE, 320c9c12d33SAleksey Makarov .name = "OcteonTX2 PTP", 321c9c12d33SAleksey Makarov .max_adj = 1000000000ull, 32299bbc4aeSYi Guo .n_ext_ts = 1, 32399bbc4aeSYi Guo .n_pins = 1, 324c9c12d33SAleksey Makarov .pps = 0, 32599bbc4aeSYi Guo .pin_config = &ptp_ptr->extts_config, 326c9c12d33SAleksey Makarov .adjfine = otx2_ptp_adjfine, 327c9c12d33SAleksey Makarov .adjtime = otx2_ptp_adjtime, 328c9c12d33SAleksey Makarov .gettime64 = otx2_ptp_gettime, 329c9c12d33SAleksey Makarov .settime64 = otx2_ptp_settime, 330c9c12d33SAleksey Makarov .enable = otx2_ptp_enable, 33199bbc4aeSYi Guo .verify = otx2_ptp_verify_pin, 332c9c12d33SAleksey Makarov }; 333c9c12d33SAleksey Makarov 33499bbc4aeSYi Guo INIT_DELAYED_WORK(&ptp_ptr->extts_work, otx2_ptp_extts_check); 33599bbc4aeSYi Guo 336c9c12d33SAleksey Makarov ptp_ptr->ptp_clock = ptp_clock_register(&ptp_ptr->ptp_info, pfvf->dev); 337c9c12d33SAleksey Makarov if (IS_ERR_OR_NULL(ptp_ptr->ptp_clock)) { 338c9c12d33SAleksey Makarov err = ptp_ptr->ptp_clock ? 339c9c12d33SAleksey Makarov PTR_ERR(ptp_ptr->ptp_clock) : -ENODEV; 340c9c12d33SAleksey Makarov kfree(ptp_ptr); 341c9c12d33SAleksey Makarov goto error; 342c9c12d33SAleksey Makarov } 343c9c12d33SAleksey Makarov 34474c1b233SNaveen Mamindlapalli if (is_dev_otx2(pfvf->pdev)) { 34574c1b233SNaveen Mamindlapalli ptp_ptr->convert_rx_ptp_tstmp = &otx2_ptp_convert_rx_timestamp; 34674c1b233SNaveen Mamindlapalli ptp_ptr->convert_tx_ptp_tstmp = &otx2_ptp_convert_tx_timestamp; 34774c1b233SNaveen Mamindlapalli } else { 34874c1b233SNaveen Mamindlapalli ptp_ptr->convert_rx_ptp_tstmp = &cn10k_ptp_convert_timestamp; 34974c1b233SNaveen Mamindlapalli ptp_ptr->convert_tx_ptp_tstmp = &cn10k_ptp_convert_timestamp; 35074c1b233SNaveen Mamindlapalli } 35174c1b233SNaveen Mamindlapalli 3522958d17aSHariprasad Kelam INIT_DELAYED_WORK(&ptp_ptr->synctstamp_work, otx2_sync_tstamp); 3532958d17aSHariprasad Kelam 354c9c12d33SAleksey Makarov pfvf->ptp = ptp_ptr; 355c9c12d33SAleksey Makarov 356c9c12d33SAleksey Makarov error: 357c9c12d33SAleksey Makarov return err; 358c9c12d33SAleksey Makarov } 3590e9e7598SArnd Bergmann EXPORT_SYMBOL_GPL(otx2_ptp_init); 360c9c12d33SAleksey Makarov 361c9c12d33SAleksey Makarov void otx2_ptp_destroy(struct otx2_nic *pfvf) 362c9c12d33SAleksey Makarov { 363c9c12d33SAleksey Makarov struct otx2_ptp *ptp = pfvf->ptp; 364c9c12d33SAleksey Makarov 365c9c12d33SAleksey Makarov if (!ptp) 366c9c12d33SAleksey Makarov return; 367c9c12d33SAleksey Makarov 3682958d17aSHariprasad Kelam cancel_delayed_work(&pfvf->ptp->synctstamp_work); 3692958d17aSHariprasad Kelam 370c9c12d33SAleksey Makarov ptp_clock_unregister(ptp->ptp_clock); 371c9c12d33SAleksey Makarov kfree(ptp); 372c9c12d33SAleksey Makarov pfvf->ptp = NULL; 373c9c12d33SAleksey Makarov } 3740e9e7598SArnd Bergmann EXPORT_SYMBOL_GPL(otx2_ptp_destroy); 375c9c12d33SAleksey Makarov 376c9c12d33SAleksey Makarov int otx2_ptp_clock_index(struct otx2_nic *pfvf) 377c9c12d33SAleksey Makarov { 378c9c12d33SAleksey Makarov if (!pfvf->ptp) 379c9c12d33SAleksey Makarov return -ENODEV; 380c9c12d33SAleksey Makarov 381c9c12d33SAleksey Makarov return ptp_clock_index(pfvf->ptp->ptp_clock); 382c9c12d33SAleksey Makarov } 3830e9e7598SArnd Bergmann EXPORT_SYMBOL_GPL(otx2_ptp_clock_index); 384c9c12d33SAleksey Makarov 385c9c12d33SAleksey Makarov int otx2_ptp_tstamp2time(struct otx2_nic *pfvf, u64 tstamp, u64 *tsns) 386c9c12d33SAleksey Makarov { 387c9c12d33SAleksey Makarov if (!pfvf->ptp) 388c9c12d33SAleksey Makarov return -ENODEV; 389c9c12d33SAleksey Makarov 390c9c12d33SAleksey Makarov *tsns = timecounter_cyc2time(&pfvf->ptp->time_counter, tstamp); 391c9c12d33SAleksey Makarov 392c9c12d33SAleksey Makarov return 0; 393c9c12d33SAleksey Makarov } 3940e9e7598SArnd Bergmann EXPORT_SYMBOL_GPL(otx2_ptp_tstamp2time); 3950e9e7598SArnd Bergmann 3960e9e7598SArnd Bergmann MODULE_AUTHOR("Sunil Goutham <sgoutham@marvell.com>"); 3970e9e7598SArnd Bergmann MODULE_DESCRIPTION("Marvell RVU NIC PTP Driver"); 3980e9e7598SArnd Bergmann MODULE_LICENSE("GPL v2"); 399