Message ID | 20200714162802.11926-1-sorganov@gmail.com |
---|---|
State | Accepted |
Delegated to: | David Miller |
Headers | show |
Series | [v3,net] net: fec: fix hardware time stamping by external devices | expand |
On Tue, 14 Jul 2020 19:28:02 +0300 Sergey Organov wrote: > Fix support for external PTP-aware devices such as DSA or PTP PHY: > > Make sure we never time stamp tx packets when hardware time stamping > is disabled. > > Check for PTP PHY being in use and then pass ioctls related to time > stamping of Ethernet packets to the PTP PHY rather than handle them > ourselves. In addition, disable our own hardware time stamping in this > case. > > Fixes: 6605b730c061 ("FEC: Add time stamping code and a PTP hardware clock") > Signed-off-by: Sergey Organov <sorganov@gmail.com> > Acked-by: Richard Cochran <richardcochran@gmail.com> > Acked-by: Vladimir Oltean <olteanv@gmail.com> > --- > > v3: > - Fixed SHA1 length of Fixes: tag > - Added Acked-by: tags > > v2: > - Extracted from larger patch series > - Description/comments updated according to discussions > - Added Fixes: tag FWIW in the networking subsystem we like the changelog to be part of the commit. Applied, and added to the stable queue, thanks!
Jakub Kicinski <kuba@kernel.org> writes: > On Tue, 14 Jul 2020 19:28:02 +0300 Sergey Organov wrote: >> Fix support for external PTP-aware devices such as DSA or PTP PHY: >> >> Make sure we never time stamp tx packets when hardware time stamping >> is disabled. >> >> Check for PTP PHY being in use and then pass ioctls related to time >> stamping of Ethernet packets to the PTP PHY rather than handle them >> ourselves. In addition, disable our own hardware time stamping in this >> case. >> >> Fixes: 6605b730c061 ("FEC: Add time stamping code and a PTP hardware >> clock") >> Signed-off-by: Sergey Organov <sorganov@gmail.com> >> Acked-by: Richard Cochran <richardcochran@gmail.com> >> Acked-by: Vladimir Oltean <olteanv@gmail.com> >> --- >> >> v3: >> - Fixed SHA1 length of Fixes: tag >> - Added Acked-by: tags >> >> v2: >> - Extracted from larger patch series >> - Description/comments updated according to discussions >> - Added Fixes: tag > > FWIW in the networking subsystem we like the changelog to be part of the > commit. Thanks, Jakub, I took a notice for myself! > > Applied, and added to the stable queue, thanks! Thanks, and I've also got a no-brainer patch that lets this bug fix compile as-is with older kernels, where there were no phy_has_hwtstamp() function. Dunno how to properly handle this. Here is the patch (on top of v4.9.146), just in case: --- >8 --- commit eee1f92bbc83ad59c83935a21f635e088cf7aa02 Author: Sergey Organov <sorganov@gmail.com> Date: Tue Jun 30 17:12:16 2020 +0300 phy: add phy_has_hwtstamp() for compatibility with newer kernels Signed-off-by: Sergey Organov <sorganov@gmail.com> diff --git a/include/linux/phy.h b/include/linux/phy.h index 867110c9d707..aa01ed4e8e1f 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -595,6 +595,15 @@ struct phy_driver { #define PHY_ANY_ID "MATCH ANY PHY" #define PHY_ANY_UID 0xffffffff +/** + * phy_has_hwtstamp - Tests whether a PHY supports time stamp configuration. + * @phydev: the phy_device struct + */ +static inline bool phy_has_hwtstamp(struct phy_device *phydev) +{ + return phydev && phydev->drv && phydev->drv->hwtstamp; +} + /* A Structure for boards to register fixups with the PHY Lib */ struct phy_fixup { struct list_head list; -- Sergey
On Thu, 16 Jul 2020 23:38:13 +0300 Sergey Organov wrote: > > Applied, and added to the stable queue, thanks! > > Thanks, and I've also got a no-brainer patch that lets this bug fix > compile as-is with older kernels, where there were no phy_has_hwtstamp() > function. Dunno how to properly handle this. Here is the patch (on > top of v4.9.146), just in case: I see, I'll only add it to 5.7. By default we backport net fixes to the two most recent releases, anyway. Could you send a patch that will work on 4.4 or 4.9 - 5.4 to Greg yourself once this hits Linus's tree in a week or two?
Jakub Kicinski <kuba@kernel.org> writes: > On Thu, 16 Jul 2020 23:38:13 +0300 Sergey Organov wrote: >> > Applied, and added to the stable queue, thanks! >> >> Thanks, and I've also got a no-brainer patch that lets this bug fix >> compile as-is with older kernels, where there were no phy_has_hwtstamp() >> function. Dunno how to properly handle this. Here is the patch (on >> top of v4.9.146), just in case: > > I see, I'll only add it to 5.7. By default we backport net fixes to > the two most recent releases, anyway. Could you send a patch that will > work on 4.4 or 4.9 - 5.4 to Greg yourself once this hits Linus's tree > in a week or two? Sure. Hopefully I get it right that I'll need to send it to Greg as a backport of this one to older kernel trees. Thanks, -- Sergey
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h index d8d76da..832a217 100644 --- a/drivers/net/ethernet/freescale/fec.h +++ b/drivers/net/ethernet/freescale/fec.h @@ -590,6 +590,7 @@ struct fec_enet_private { void fec_ptp_init(struct platform_device *pdev, int irq_idx); void fec_ptp_stop(struct platform_device *pdev); void fec_ptp_start_cyclecounter(struct net_device *ndev); +void fec_ptp_disable_hwts(struct net_device *ndev); int fec_ptp_set(struct net_device *ndev, struct ifreq *ifr); int fec_ptp_get(struct net_device *ndev, struct ifreq *ifr); diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 3982285..cc7fbfc 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -1294,8 +1294,13 @@ fec_enet_tx_queue(struct net_device *ndev, u16 queue_id) ndev->stats.tx_bytes += skb->len; } - if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS) && - fep->bufdesc_ex) { + /* NOTE: SKBTX_IN_PROGRESS being set does not imply it's we who + * are to time stamp the packet, so we still need to check time + * stamping enabled flag. + */ + if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS && + fep->hwts_tx_en) && + fep->bufdesc_ex) { struct skb_shared_hwtstamps shhwtstamps; struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp; @@ -2723,10 +2728,16 @@ static int fec_enet_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd) return -ENODEV; if (fep->bufdesc_ex) { - if (cmd == SIOCSHWTSTAMP) - return fec_ptp_set(ndev, rq); - if (cmd == SIOCGHWTSTAMP) - return fec_ptp_get(ndev, rq); + bool use_fec_hwts = !phy_has_hwtstamp(phydev); + + if (cmd == SIOCSHWTSTAMP) { + if (use_fec_hwts) + return fec_ptp_set(ndev, rq); + fec_ptp_disable_hwts(ndev); + } else if (cmd == SIOCGHWTSTAMP) { + if (use_fec_hwts) + return fec_ptp_get(ndev, rq); + } } return phy_mii_ioctl(phydev, rq, cmd); diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c index 945643c..f8a592c 100644 --- a/drivers/net/ethernet/freescale/fec_ptp.c +++ b/drivers/net/ethernet/freescale/fec_ptp.c @@ -452,6 +452,18 @@ static int fec_ptp_enable(struct ptp_clock_info *ptp, return -EOPNOTSUPP; } +/** + * fec_ptp_disable_hwts - disable hardware time stamping + * @ndev: pointer to net_device + */ +void fec_ptp_disable_hwts(struct net_device *ndev) +{ + struct fec_enet_private *fep = netdev_priv(ndev); + + fep->hwts_tx_en = 0; + fep->hwts_rx_en = 0; +} + int fec_ptp_set(struct net_device *ndev, struct ifreq *ifr) { struct fec_enet_private *fep = netdev_priv(ndev);