On Wed, Dec 07, 2016 at 08:21:51PM +0200, Andrei Pistirica wrote: > +#ifdef CONFIG_MACB_USE_HWSTAMP > +void gem_ptp_init(struct net_device *ndev); > +void gem_ptp_remove(struct net_device *ndev); > + > +void gem_ptp_do_txstamp(struct macb *bp, struct sk_buff *skb); > +void gem_ptp_do_rxstamp(struct macb *bp, struct sk_buff *skb);
These are in the hot path, and so you should do the test before calling the global function, something like this: void gem_ptp_txstamp(struct macb *bp, struct sk_buff *skb); static void gem_ptp_do_txstamp(struct macb *bp, struct sk_buff *skb) { if (!bp->hwts_tx_en) return; gem_ptp_txstamp(bp, skb); } Ditto for Rx. > +#else > +static inline void gem_ptp_init(struct net_device *ndev) { } > +static inline void gem_ptp_remove(struct net_device *ndev) { } > + > +static inline void gem_ptp_do_txstamp(struct macb *bp, struct sk_buff *skb) > { } > +static inline void gem_ptp_do_rxstamp(struct macb *bp, struct sk_buff *skb) > { } > +#endif > + > +static int gem_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) > +{ > + struct macb *bp = container_of(ptp, struct macb, ptp_caps); > + u32 word, diff; > + u64 adj, rate; > + int neg_adj = 0; > + > + if (scaled_ppm < 0) { > + neg_adj = 1; > + scaled_ppm = -scaled_ppm; > + } > + rate = scaled_ppm; > + > + /* word: unused(8bit) | ns(8bit) | fractions(16bit) */ > + word = (bp->ns_incr << 16) + bp->subns_incr; > + > + adj = word; > + adj *= rate; > + adj >>= 16; /* remove fractions */ > + adj += 500000UL; > + diff = div_u64(adj, 1000000UL); In order to round correctly, shouldn't this be? adj *= rate; adj += 500000UL << 16; adj >>= 16; diff = div_u64(adj, 1000000UL); > + word = neg_adj ? word - diff : word + diff; > + > + spin_lock(&bp->tsu_clk_lock); > + > + gem_writel(bp, TISUBN, GEM_BF(SUBNSINCR, (word & 0xffff))); > + gem_writel(bp, TI, GEM_BF(NSINCR, (word >> 16))); > + > + spin_unlock(&bp->tsu_clk_lock); > + return 0; > +} > +static s32 gem_ptp_max_adj(unsigned int f_nom) > +{ > + u64 adj; > + > + /* The 48 bits of seconds for the GEM overflows every: > + * 2^48/(365.25 * 24 * 60 *60) =~ 8 925 512 years (~= 9 mil years), > + * thus the maximum adjust frequency must not overflow CNS register: > + * > + * addend = 10^9/nominal_freq > + * adj_max = +/- addend*ppb_max/10^9 > + * max_ppb = (2^8-1)*nominal_freq-10^9 > + */ > + adj = f_nom; > + adj *= 0xffff; > + adj -= 1000000000ULL; What is this computation, and how does it relate to the comment? > + return adj; > +} > +/* While GEM can timestamp PTP packets, it does not mark the RX descriptor Does it timestamp PTP event packets only, or all packets? (See my comment in patch 2/2) > + * to identify them. UDP packets must be parsed to identify PTP packets. > + * > + * Note: Inspired from drivers/net/ethernet/ti/cpts.c > + */ Thanks, Richard