1/* 2 * Fast Ethernet Controller (ENET) PTP driver for MX6x. 3 * 4 * Copyright (C) 2012 Freescale Semiconductor, Inc. 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms and conditions of the GNU General Public License, 8 * version 2, as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 * more details. 14 * 15 * You should have received a copy of the GNU General Public License along with 16 * this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 18 */ 19 20#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 21 22#include <linux/module.h> 23#include <linux/kernel.h> 24#include <linux/string.h> 25#include <linux/ptrace.h> 26#include <linux/errno.h> 27#include <linux/ioport.h> 28#include <linux/slab.h> 29#include <linux/interrupt.h> 30#include <linux/pci.h> 31#include <linux/delay.h> 32#include <linux/netdevice.h> 33#include <linux/etherdevice.h> 34#include <linux/skbuff.h> 35#include <linux/spinlock.h> 36#include <linux/workqueue.h> 37#include <linux/bitops.h> 38#include <linux/io.h> 39#include <linux/irq.h> 40#include <linux/clk.h> 41#include <linux/platform_device.h> 42#include <linux/phy.h> 43#include <linux/fec.h> 44#include <linux/of.h> 45#include <linux/of_device.h> 46#include <linux/of_gpio.h> 47#include <linux/of_net.h> 48 49#include "fec.h" 50 51/* FEC 1588 register bits */ 52#define FEC_T_CTRL_SLAVE 0x00002000 53#define FEC_T_CTRL_CAPTURE 0x00000800 54#define FEC_T_CTRL_RESTART 0x00000200 55#define FEC_T_CTRL_PERIOD_RST 0x00000030 56#define FEC_T_CTRL_PERIOD_EN 0x00000010 57#define FEC_T_CTRL_ENABLE 0x00000001 58 59#define FEC_T_INC_MASK 0x0000007f 60#define FEC_T_INC_OFFSET 0 61#define FEC_T_INC_CORR_MASK 0x00007f00 62#define FEC_T_INC_CORR_OFFSET 8 63 64#define FEC_T_CTRL_PINPER 0x00000080 65#define FEC_T_TF0_MASK 0x00000001 66#define FEC_T_TF0_OFFSET 0 67#define FEC_T_TF1_MASK 0x00000002 68#define FEC_T_TF1_OFFSET 1 69#define FEC_T_TF2_MASK 0x00000004 70#define FEC_T_TF2_OFFSET 2 71#define FEC_T_TF3_MASK 0x00000008 72#define FEC_T_TF3_OFFSET 3 73#define FEC_T_TDRE_MASK 0x00000001 74#define FEC_T_TDRE_OFFSET 0 75#define FEC_T_TMODE_MASK 0x0000003C 76#define FEC_T_TMODE_OFFSET 2 77#define FEC_T_TIE_MASK 0x00000040 78#define FEC_T_TIE_OFFSET 6 79#define FEC_T_TF_MASK 0x00000080 80#define FEC_T_TF_OFFSET 7 81 82#define FEC_ATIME_CTRL 0x400 83#define FEC_ATIME 0x404 84#define FEC_ATIME_EVT_OFFSET 0x408 85#define FEC_ATIME_EVT_PERIOD 0x40c 86#define FEC_ATIME_CORR 0x410 87#define FEC_ATIME_INC 0x414 88#define FEC_TS_TIMESTAMP 0x418 89 90#define FEC_TGSR 0x604 91#define FEC_TCSR(n) (0x608 + n * 0x08) 92#define FEC_TCCR(n) (0x60C + n * 0x08) 93#define MAX_TIMER_CHANNEL 3 94#define FEC_TMODE_TOGGLE 0x05 95#define FEC_HIGH_PULSE 0x0F 96 97#define FEC_CC_MULT (1 << 31) 98#define FEC_COUNTER_PERIOD (1 << 31) 99#define PPS_OUPUT_RELOAD_PERIOD NSEC_PER_SEC 100#define FEC_CHANNLE_0 0 101#define DEFAULT_PPS_CHANNEL FEC_CHANNLE_0 102 103/** 104 * fec_ptp_enable_pps 105 * @fep: the fec_enet_private structure handle 106 * @enable: enable the channel pps output 107 * 108 * This function enble the PPS ouput on the timer channel. 109 */ 110static int fec_ptp_enable_pps(struct fec_enet_private *fep, uint enable) 111{ 112 unsigned long flags; 113 u32 val, tempval; 114 int inc; 115 struct timespec64 ts; 116 u64 ns; 117 val = 0; 118 119 if (!(fep->hwts_tx_en || fep->hwts_rx_en)) { 120 dev_err(&fep->pdev->dev, "No ptp stack is running\n"); 121 return -EINVAL; 122 } 123 124 if (fep->pps_enable == enable) 125 return 0; 126 127 fep->pps_channel = DEFAULT_PPS_CHANNEL; 128 fep->reload_period = PPS_OUPUT_RELOAD_PERIOD; 129 inc = fep->ptp_inc; 130 131 spin_lock_irqsave(&fep->tmreg_lock, flags); 132 133 if (enable) { 134 /* clear capture or output compare interrupt status if have. 135 */ 136 writel(FEC_T_TF_MASK, fep->hwp + FEC_TCSR(fep->pps_channel)); 137 138 /* It is recommended to double check the TMODE field in the 139 * TCSR register to be cleared before the first compare counter 140 * is written into TCCR register. Just add a double check. 141 */ 142 val = readl(fep->hwp + FEC_TCSR(fep->pps_channel)); 143 do { 144 val &= ~(FEC_T_TMODE_MASK); 145 writel(val, fep->hwp + FEC_TCSR(fep->pps_channel)); 146 val = readl(fep->hwp + FEC_TCSR(fep->pps_channel)); 147 } while (val & FEC_T_TMODE_MASK); 148 149 /* Dummy read counter to update the counter */ 150 timecounter_read(&fep->tc); 151 /* We want to find the first compare event in the next 152 * second point. So we need to know what the ptp time 153 * is now and how many nanoseconds is ahead to get next second. 154 * The remaining nanosecond ahead before the next second would be 155 * NSEC_PER_SEC - ts.tv_nsec. Add the remaining nanoseconds 156 * to current timer would be next second. 157 */ 158 tempval = readl(fep->hwp + FEC_ATIME_CTRL); 159 tempval |= FEC_T_CTRL_CAPTURE; 160 writel(tempval, fep->hwp + FEC_ATIME_CTRL); 161 162 tempval = readl(fep->hwp + FEC_ATIME); 163 /* Convert the ptp local counter to 1588 timestamp */ 164 ns = timecounter_cyc2time(&fep->tc, tempval); 165 ts = ns_to_timespec64(ns); 166 167 /* The tempval is less than 3 seconds, and so val is less than 168 * 4 seconds. No overflow for 32bit calculation. 169 */ 170 val = NSEC_PER_SEC - (u32)ts.tv_nsec + tempval; 171 172 /* Need to consider the situation that the current time is 173 * very close to the second point, which means NSEC_PER_SEC 174 * - ts.tv_nsec is close to be zero(For example 20ns); Since the timer 175 * is still running when we calculate the first compare event, it is 176 * possible that the remaining nanoseonds run out before the compare 177 * counter is calculated and written into TCCR register. To avoid 178 * this possibility, we will set the compare event to be the next 179 * of next second. The current setting is 31-bit timer and wrap 180 * around over 2 seconds. So it is okay to set the next of next 181 * seond for the timer. 182 */ 183 val += NSEC_PER_SEC; 184 185 /* We add (2 * NSEC_PER_SEC - (u32)ts.tv_nsec) to current 186 * ptp counter, which maybe cause 32-bit wrap. Since the 187 * (NSEC_PER_SEC - (u32)ts.tv_nsec) is less than 2 second. 188 * We can ensure the wrap will not cause issue. If the offset 189 * is bigger than fep->cc.mask would be a error. 190 */ 191 val &= fep->cc.mask; 192 writel(val, fep->hwp + FEC_TCCR(fep->pps_channel)); 193 194 /* Calculate the second the compare event timestamp */ 195 fep->next_counter = (val + fep->reload_period) & fep->cc.mask; 196 197 /* * Enable compare event when overflow */ 198 val = readl(fep->hwp + FEC_ATIME_CTRL); 199 val |= FEC_T_CTRL_PINPER; 200 writel(val, fep->hwp + FEC_ATIME_CTRL); 201 202 /* Compare channel setting. */ 203 val = readl(fep->hwp + FEC_TCSR(fep->pps_channel)); 204 val |= (1 << FEC_T_TF_OFFSET | 1 << FEC_T_TIE_OFFSET); 205 val &= ~(1 << FEC_T_TDRE_OFFSET); 206 val &= ~(FEC_T_TMODE_MASK); 207 val |= (FEC_HIGH_PULSE << FEC_T_TMODE_OFFSET); 208 writel(val, fep->hwp + FEC_TCSR(fep->pps_channel)); 209 210 /* Write the second compare event timestamp and calculate 211 * the third timestamp. Refer the TCCR register detail in the spec. 212 */ 213 writel(fep->next_counter, fep->hwp + FEC_TCCR(fep->pps_channel)); 214 fep->next_counter = (fep->next_counter + fep->reload_period) & fep->cc.mask; 215 } else { 216 writel(0, fep->hwp + FEC_TCSR(fep->pps_channel)); 217 } 218 219 fep->pps_enable = enable; 220 spin_unlock_irqrestore(&fep->tmreg_lock, flags); 221 222 return 0; 223} 224 225/** 226 * fec_ptp_read - read raw cycle counter (to be used by time counter) 227 * @cc: the cyclecounter structure 228 * 229 * this function reads the cyclecounter registers and is called by the 230 * cyclecounter structure used to construct a ns counter from the 231 * arbitrary fixed point registers 232 */ 233static cycle_t fec_ptp_read(const struct cyclecounter *cc) 234{ 235 struct fec_enet_private *fep = 236 container_of(cc, struct fec_enet_private, cc); 237 const struct platform_device_id *id_entry = 238 platform_get_device_id(fep->pdev); 239 u32 tempval; 240 241 tempval = readl(fep->hwp + FEC_ATIME_CTRL); 242 tempval |= FEC_T_CTRL_CAPTURE; 243 writel(tempval, fep->hwp + FEC_ATIME_CTRL); 244 245 if (id_entry->driver_data & FEC_QUIRK_BUG_CAPTURE) 246 udelay(1); 247 248 return readl(fep->hwp + FEC_ATIME); 249} 250 251/** 252 * fec_ptp_start_cyclecounter - create the cycle counter from hw 253 * @ndev: network device 254 * 255 * this function initializes the timecounter and cyclecounter 256 * structures for use in generated a ns counter from the arbitrary 257 * fixed point cycles registers in the hardware. 258 */ 259void fec_ptp_start_cyclecounter(struct net_device *ndev) 260{ 261 struct fec_enet_private *fep = netdev_priv(ndev); 262 unsigned long flags; 263 int inc; 264 265 inc = 1000000000 / fep->cycle_speed; 266 267 /* grab the ptp lock */ 268 spin_lock_irqsave(&fep->tmreg_lock, flags); 269 270 /* 1ns counter */ 271 writel(inc << FEC_T_INC_OFFSET, fep->hwp + FEC_ATIME_INC); 272 273 /* use 31-bit timer counter */ 274 writel(FEC_COUNTER_PERIOD, fep->hwp + FEC_ATIME_EVT_PERIOD); 275 276 writel(FEC_T_CTRL_ENABLE | FEC_T_CTRL_PERIOD_RST, 277 fep->hwp + FEC_ATIME_CTRL); 278 279 memset(&fep->cc, 0, sizeof(fep->cc)); 280 fep->cc.read = fec_ptp_read; 281 fep->cc.mask = CLOCKSOURCE_MASK(31); 282 fep->cc.shift = 31; 283 fep->cc.mult = FEC_CC_MULT; 284 285 /* reset the ns time counter */ 286 timecounter_init(&fep->tc, &fep->cc, ktime_to_ns(ktime_get_real())); 287 288 spin_unlock_irqrestore(&fep->tmreg_lock, flags); 289} 290 291/** 292 * fec_ptp_adjfreq - adjust ptp cycle frequency 293 * @ptp: the ptp clock structure 294 * @ppb: parts per billion adjustment from base 295 * 296 * Adjust the frequency of the ptp cycle counter by the 297 * indicated ppb from the base frequency. 298 * 299 * Because ENET hardware frequency adjust is complex, 300 * using software method to do that. 301 */ 302static int fec_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb) 303{ 304 unsigned long flags; 305 int neg_adj = 0; 306 u32 i, tmp; 307 u32 corr_inc, corr_period; 308 u32 corr_ns; 309 u64 lhs, rhs; 310 311 struct fec_enet_private *fep = 312 container_of(ptp, struct fec_enet_private, ptp_caps); 313 314 if (ppb == 0) 315 return 0; 316 317 if (ppb < 0) { 318 ppb = -ppb; 319 neg_adj = 1; 320 } 321 322 /* In theory, corr_inc/corr_period = ppb/NSEC_PER_SEC; 323 * Try to find the corr_inc between 1 to fep->ptp_inc to 324 * meet adjustment requirement. 325 */ 326 lhs = NSEC_PER_SEC; 327 rhs = (u64)ppb * (u64)fep->ptp_inc; 328 for (i = 1; i <= fep->ptp_inc; i++) { 329 if (lhs >= rhs) { 330 corr_inc = i; 331 corr_period = div_u64(lhs, rhs); 332 break; 333 } 334 lhs += NSEC_PER_SEC; 335 } 336 /* Not found? Set it to high value - double speed 337 * correct in every clock step. 338 */ 339 if (i > fep->ptp_inc) { 340 corr_inc = fep->ptp_inc; 341 corr_period = 1; 342 } 343 344 if (neg_adj) 345 corr_ns = fep->ptp_inc - corr_inc; 346 else 347 corr_ns = fep->ptp_inc + corr_inc; 348 349 spin_lock_irqsave(&fep->tmreg_lock, flags); 350 351 tmp = readl(fep->hwp + FEC_ATIME_INC) & FEC_T_INC_MASK; 352 tmp |= corr_ns << FEC_T_INC_CORR_OFFSET; 353 writel(tmp, fep->hwp + FEC_ATIME_INC); 354 corr_period = corr_period > 1 ? corr_period - 1 : corr_period; 355 writel(corr_period, fep->hwp + FEC_ATIME_CORR); 356 /* dummy read to update the timer. */ 357 timecounter_read(&fep->tc); 358 359 spin_unlock_irqrestore(&fep->tmreg_lock, flags); 360 361 return 0; 362} 363 364/** 365 * fec_ptp_adjtime 366 * @ptp: the ptp clock structure 367 * @delta: offset to adjust the cycle counter by 368 * 369 * adjust the timer by resetting the timecounter structure. 370 */ 371static int fec_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) 372{ 373 struct fec_enet_private *fep = 374 container_of(ptp, struct fec_enet_private, ptp_caps); 375 unsigned long flags; 376 377 spin_lock_irqsave(&fep->tmreg_lock, flags); 378 timecounter_adjtime(&fep->tc, delta); 379 spin_unlock_irqrestore(&fep->tmreg_lock, flags); 380 381 return 0; 382} 383 384/** 385 * fec_ptp_gettime 386 * @ptp: the ptp clock structure 387 * @ts: timespec structure to hold the current time value 388 * 389 * read the timecounter and return the correct value on ns, 390 * after converting it into a struct timespec. 391 */ 392static int fec_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts) 393{ 394 struct fec_enet_private *adapter = 395 container_of(ptp, struct fec_enet_private, ptp_caps); 396 u64 ns; 397 unsigned long flags; 398 399 spin_lock_irqsave(&adapter->tmreg_lock, flags); 400 ns = timecounter_read(&adapter->tc); 401 spin_unlock_irqrestore(&adapter->tmreg_lock, flags); 402 403 *ts = ns_to_timespec64(ns); 404 405 return 0; 406} 407 408/** 409 * fec_ptp_settime 410 * @ptp: the ptp clock structure 411 * @ts: the timespec containing the new time for the cycle counter 412 * 413 * reset the timecounter to use a new base value instead of the kernel 414 * wall timer value. 415 */ 416static int fec_ptp_settime(struct ptp_clock_info *ptp, 417 const struct timespec64 *ts) 418{ 419 struct fec_enet_private *fep = 420 container_of(ptp, struct fec_enet_private, ptp_caps); 421 422 u64 ns; 423 unsigned long flags; 424 u32 counter; 425 426 mutex_lock(&fep->ptp_clk_mutex); 427 /* Check the ptp clock */ 428 if (!fep->ptp_clk_on) { 429 mutex_unlock(&fep->ptp_clk_mutex); 430 return -EINVAL; 431 } 432 433 ns = timespec64_to_ns(ts); 434 /* Get the timer value based on timestamp. 435 * Update the counter with the masked value. 436 */ 437 counter = ns & fep->cc.mask; 438 439 spin_lock_irqsave(&fep->tmreg_lock, flags); 440 writel(counter, fep->hwp + FEC_ATIME); 441 timecounter_init(&fep->tc, &fep->cc, ns); 442 spin_unlock_irqrestore(&fep->tmreg_lock, flags); 443 mutex_unlock(&fep->ptp_clk_mutex); 444 return 0; 445} 446 447/** 448 * fec_ptp_enable 449 * @ptp: the ptp clock structure 450 * @rq: the requested feature to change 451 * @on: whether to enable or disable the feature 452 * 453 */ 454static int fec_ptp_enable(struct ptp_clock_info *ptp, 455 struct ptp_clock_request *rq, int on) 456{ 457 struct fec_enet_private *fep = 458 container_of(ptp, struct fec_enet_private, ptp_caps); 459 int ret = 0; 460 461 if (rq->type == PTP_CLK_REQ_PPS) { 462 ret = fec_ptp_enable_pps(fep, on); 463 464 return ret; 465 } 466 return -EOPNOTSUPP; 467} 468 469/** 470 * fec_ptp_hwtstamp_ioctl - control hardware time stamping 471 * @ndev: pointer to net_device 472 * @ifreq: ioctl data 473 * @cmd: particular ioctl requested 474 */ 475int fec_ptp_set(struct net_device *ndev, struct ifreq *ifr) 476{ 477 struct fec_enet_private *fep = netdev_priv(ndev); 478 479 struct hwtstamp_config config; 480 481 if (copy_from_user(&config, ifr->ifr_data, sizeof(config))) 482 return -EFAULT; 483 484 /* reserved for future extensions */ 485 if (config.flags) 486 return -EINVAL; 487 488 switch (config.tx_type) { 489 case HWTSTAMP_TX_OFF: 490 fep->hwts_tx_en = 0; 491 break; 492 case HWTSTAMP_TX_ON: 493 fep->hwts_tx_en = 1; 494 break; 495 default: 496 return -ERANGE; 497 } 498 499 switch (config.rx_filter) { 500 case HWTSTAMP_FILTER_NONE: 501 if (fep->hwts_rx_en) 502 fep->hwts_rx_en = 0; 503 config.rx_filter = HWTSTAMP_FILTER_NONE; 504 break; 505 506 default: 507 fep->hwts_rx_en = 1; 508 config.rx_filter = HWTSTAMP_FILTER_ALL; 509 break; 510 } 511 512 return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? 513 -EFAULT : 0; 514} 515 516int fec_ptp_get(struct net_device *ndev, struct ifreq *ifr) 517{ 518 struct fec_enet_private *fep = netdev_priv(ndev); 519 struct hwtstamp_config config; 520 521 config.flags = 0; 522 config.tx_type = fep->hwts_tx_en ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF; 523 config.rx_filter = (fep->hwts_rx_en ? 524 HWTSTAMP_FILTER_ALL : HWTSTAMP_FILTER_NONE); 525 526 return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? 527 -EFAULT : 0; 528} 529 530/** 531 * fec_time_keep - call timecounter_read every second to avoid timer overrun 532 * because ENET just support 32bit counter, will timeout in 4s 533 */ 534static void fec_time_keep(struct work_struct *work) 535{ 536 struct delayed_work *dwork = to_delayed_work(work); 537 struct fec_enet_private *fep = container_of(dwork, struct fec_enet_private, time_keep); 538 u64 ns; 539 unsigned long flags; 540 541 mutex_lock(&fep->ptp_clk_mutex); 542 if (fep->ptp_clk_on) { 543 spin_lock_irqsave(&fep->tmreg_lock, flags); 544 ns = timecounter_read(&fep->tc); 545 spin_unlock_irqrestore(&fep->tmreg_lock, flags); 546 } 547 mutex_unlock(&fep->ptp_clk_mutex); 548 549 schedule_delayed_work(&fep->time_keep, HZ); 550} 551 552/** 553 * fec_ptp_init 554 * @ndev: The FEC network adapter 555 * 556 * This function performs the required steps for enabling ptp 557 * support. If ptp support has already been loaded it simply calls the 558 * cyclecounter init routine and exits. 559 */ 560 561void fec_ptp_init(struct platform_device *pdev) 562{ 563 struct net_device *ndev = platform_get_drvdata(pdev); 564 struct fec_enet_private *fep = netdev_priv(ndev); 565 566 fep->ptp_caps.owner = THIS_MODULE; 567 snprintf(fep->ptp_caps.name, 16, "fec ptp"); 568 569 fep->ptp_caps.max_adj = 250000000; 570 fep->ptp_caps.n_alarm = 0; 571 fep->ptp_caps.n_ext_ts = 0; 572 fep->ptp_caps.n_per_out = 0; 573 fep->ptp_caps.n_pins = 0; 574 fep->ptp_caps.pps = 1; 575 fep->ptp_caps.adjfreq = fec_ptp_adjfreq; 576 fep->ptp_caps.adjtime = fec_ptp_adjtime; 577 fep->ptp_caps.gettime64 = fec_ptp_gettime; 578 fep->ptp_caps.settime64 = fec_ptp_settime; 579 fep->ptp_caps.enable = fec_ptp_enable; 580 581 fep->cycle_speed = clk_get_rate(fep->clk_ptp); 582 fep->ptp_inc = NSEC_PER_SEC / fep->cycle_speed; 583 584 spin_lock_init(&fep->tmreg_lock); 585 586 fec_ptp_start_cyclecounter(ndev); 587 588 INIT_DELAYED_WORK(&fep->time_keep, fec_time_keep); 589 590 fep->ptp_clock = ptp_clock_register(&fep->ptp_caps, &pdev->dev); 591 if (IS_ERR(fep->ptp_clock)) { 592 fep->ptp_clock = NULL; 593 pr_err("ptp_clock_register failed\n"); 594 } 595 596 schedule_delayed_work(&fep->time_keep, HZ); 597} 598 599void fec_ptp_stop(struct platform_device *pdev) 600{ 601 struct net_device *ndev = platform_get_drvdata(pdev); 602 struct fec_enet_private *fep = netdev_priv(ndev); 603 604 cancel_delayed_work_sync(&fep->time_keep); 605 if (fep->ptp_clock) 606 ptp_clock_unregister(fep->ptp_clock); 607} 608 609/** 610 * fec_ptp_check_pps_event 611 * @fep: the fec_enet_private structure handle 612 * 613 * This function check the pps event and reload the timer compare counter. 614 */ 615uint fec_ptp_check_pps_event(struct fec_enet_private *fep) 616{ 617 u32 val; 618 u8 channel = fep->pps_channel; 619 struct ptp_clock_event event; 620 621 val = readl(fep->hwp + FEC_TCSR(channel)); 622 if (val & FEC_T_TF_MASK) { 623 /* Write the next next compare(not the next according the spec) 624 * value to the register 625 */ 626 writel(fep->next_counter, fep->hwp + FEC_TCCR(channel)); 627 do { 628 writel(val, fep->hwp + FEC_TCSR(channel)); 629 } while (readl(fep->hwp + FEC_TCSR(channel)) & FEC_T_TF_MASK); 630 631 /* Update the counter; */ 632 fep->next_counter = (fep->next_counter + fep->reload_period) & fep->cc.mask; 633 634 event.type = PTP_CLOCK_PPS; 635 ptp_clock_event(fep->ptp_clock, &event); 636 return 1; 637 } 638 639 return 0; 640} 641