Message ID | 1386287555.1516.135.camel@bwh-desktop.uk.level5networks.com |
---|---|
State | Accepted, archived |
Delegated to: | David Miller |
Headers | show |
From: Ben Hutchings <bhutchings@solarflare.com> Sent: Friday, December 06, 2013 7:53 AM >To: David Miller >Cc: netdev@vger.kernel.org; linux-net-drivers@solarflare.com; Richard Cochran; >Frank Li; Duan Fugang-B38611; Estevam Fabio-R49496 >Subject: [PATCH net-next 08/16] fec: Implement the SIOCGHWTSTAMP ioctl > >This is untested. > >Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> >--- > drivers/net/ethernet/freescale/fec.h | 3 ++- > drivers/net/ethernet/freescale/fec_main.c | 8 ++++++-- >drivers/net/ethernet/freescale/fec_ptp.c | 16 +++++++++++++++- > 3 files changed, 23 insertions(+), 4 deletions(-) > >diff --git a/drivers/net/ethernet/freescale/fec.h >b/drivers/net/ethernet/freescale/fec.h >index 0120217a16dd..3b8d6d19ff05 100644 >--- a/drivers/net/ethernet/freescale/fec.h >+++ b/drivers/net/ethernet/freescale/fec.h >@@ -339,7 +339,8 @@ struct fec_enet_private { > > void fec_ptp_init(struct platform_device *pdev); void >fec_ptp_start_cyclecounter(struct net_device *ndev); -int fec_ptp_ioctl(struct >net_device *ndev, struct ifreq *ifr, int cmd); >+int fec_ptp_set(struct net_device *ndev, struct ifreq *ifr); int >+fec_ptp_get(struct net_device *ndev, struct ifreq *ifr); > > /****************************************************************************/ > #endif /* FEC_H */ >diff --git a/drivers/net/ethernet/freescale/fec_main.c >b/drivers/net/ethernet/freescale/fec_main.c >index 4cbebf3d80eb..40e953e81eb5 100644 >--- a/drivers/net/ethernet/freescale/fec_main.c >+++ b/drivers/net/ethernet/freescale/fec_main.c >@@ -1684,8 +1684,12 @@ static int fec_enet_ioctl(struct net_device *ndev, >struct ifreq *rq, int cmd) > if (!phydev) > return -ENODEV; > >- if (cmd == SIOCSHWTSTAMP && fep->bufdesc_ex) >- return fec_ptp_ioctl(ndev, rq, cmd); >+ if (fep->bufdesc_ex) { >+ if (cmd == SIOCSHWTSTAMP) >+ return fec_ptp_set(ndev, rq); >+ if (cmd == SIOCGHWTSTAMP) >+ 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 5007e4f9fff9..3a74ea48fd40 100644 >--- a/drivers/net/ethernet/freescale/fec_ptp.c >+++ b/drivers/net/ethernet/freescale/fec_ptp.c >@@ -274,7 +274,7 @@ static int fec_ptp_enable(struct ptp_clock_info *ptp, > * @ifreq: ioctl data > * @cmd: particular ioctl requested > */ >-int fec_ptp_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd) >+int fec_ptp_set(struct net_device *ndev, struct ifreq *ifr) > { > struct fec_enet_private *fep = netdev_priv(ndev); > >@@ -321,6 +321,20 @@ int fec_ptp_ioctl(struct net_device *ndev, struct ifreq >*ifr, int cmd) > -EFAULT : 0; > } > >+int fec_ptp_get(struct net_device *ndev, struct ifreq *ifr) { >+ struct fec_enet_private *fep = netdev_priv(ndev); >+ struct hwtstamp_config config; >+ >+ config.flags = 0; >+ config.tx_type = fep->hwts_tx_en ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF; >+ config.rx_filter = (fep->hwts_rx_en ? >+ HWTSTAMP_FILTER_ALL : HWTSTAMP_FILTER_NONE); >+ >+ return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? >+ -EFAULT : 0; >+} >+ > /** > * fec_time_keep - call timecounter_read every second to avoid timer overrun > * because ENET just support 32bit counter, will timeout in 4s > > After apply the patch set, and test Linuxptp stack show it work fine, test result as below: ... ptp4l[260.495]: master offset 17 s2 adj -85012 path delay 703 ptp4l[260.744]: master offset 0 s2 adj -85024 path delay 705 ptp4l[260.993]: master offset -57 s2 adj -85081 path delay 710 ptp4l[261.242]: master offset -13 s2 adj -85054 path delay 709 ptp4l[261.490]: master offset 5 s2 adj -85040 path delay 708 ptp4l[261.739]: master offset -42 s2 adj -85085 path delay 707 ptp4l[261.988]: master offset -19 s2 adj -85075 path delay 707 ptp4l[262.236]: master offset 41 s2 adj -85021 path delay 704 ptp4l[262.484]: master offset -11 s2 adj -85060 path delay 704 ptp4l[262.733]: master offset 10 s2 adj -85043 path delay 701 ptp4l[262.982]: master offset 23 s2 adj -85027 path delay 701 ptp4l[263.231]: master offset -27 s2 adj -85070 path delay 700 ptp4l[263.479]: master offset 19 s2 adj -85032 path delay 695 ptp4l[263.728]: master offset -14 s2 adj -85059 path delay 698 ptp4l[263.976]: master offset 40 s2 adj -85009 path delay 697 ptp4l[264.225]: master offset 26 s2 adj -85011 path delay 697 ptp4l[264.473]: master offset 30 s2 adj -85000 path delay 699 ptp4l[264.722]: master offset -32 s2 adj -85053 path delay 704 ptp4l[264.971]: master offset 23 s2 adj -85007 path delay 704 ptp4l[265.220]: master offset 5 s2 adj -85018 path delay 708 ptp4l[265.468]: master offset -71 s2 adj -85093 path delay 711 ptp4l[265.716]: master offset -7 s2 adj -85050 path delay 708 ptp4l[265.965]: master offset -31 s2 adj -85076 path delay 708 ptp4l[266.214]: master offset -29 s2 adj -85084 path delay 708 ptp4l[266.462]: master offset 16 s2 adj -85047 path delay 707 ptp4l[266.711]: master offset -30 s2 adj -85088 path delay 708 ptp4l[266.960]: master offset -5 s2 adj -85072 path delay 708 ... Tested-by: Fugang Duan <B38611@freescale.com>
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h index 0120217a16dd..3b8d6d19ff05 100644 --- a/drivers/net/ethernet/freescale/fec.h +++ b/drivers/net/ethernet/freescale/fec.h @@ -339,7 +339,8 @@ struct fec_enet_private { void fec_ptp_init(struct platform_device *pdev); void fec_ptp_start_cyclecounter(struct net_device *ndev); -int fec_ptp_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd); +int fec_ptp_set(struct net_device *ndev, struct ifreq *ifr); +int fec_ptp_get(struct net_device *ndev, struct ifreq *ifr); /****************************************************************************/ #endif /* FEC_H */ diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 4cbebf3d80eb..40e953e81eb5 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -1684,8 +1684,12 @@ static int fec_enet_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd) if (!phydev) return -ENODEV; - if (cmd == SIOCSHWTSTAMP && fep->bufdesc_ex) - return fec_ptp_ioctl(ndev, rq, cmd); + if (fep->bufdesc_ex) { + if (cmd == SIOCSHWTSTAMP) + return fec_ptp_set(ndev, rq); + if (cmd == SIOCGHWTSTAMP) + 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 5007e4f9fff9..3a74ea48fd40 100644 --- a/drivers/net/ethernet/freescale/fec_ptp.c +++ b/drivers/net/ethernet/freescale/fec_ptp.c @@ -274,7 +274,7 @@ static int fec_ptp_enable(struct ptp_clock_info *ptp, * @ifreq: ioctl data * @cmd: particular ioctl requested */ -int fec_ptp_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd) +int fec_ptp_set(struct net_device *ndev, struct ifreq *ifr) { struct fec_enet_private *fep = netdev_priv(ndev); @@ -321,6 +321,20 @@ int fec_ptp_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd) -EFAULT : 0; } +int fec_ptp_get(struct net_device *ndev, struct ifreq *ifr) +{ + struct fec_enet_private *fep = netdev_priv(ndev); + struct hwtstamp_config config; + + config.flags = 0; + config.tx_type = fep->hwts_tx_en ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF; + config.rx_filter = (fep->hwts_rx_en ? + HWTSTAMP_FILTER_ALL : HWTSTAMP_FILTER_NONE); + + return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? + -EFAULT : 0; +} + /** * fec_time_keep - call timecounter_read every second to avoid timer overrun * because ENET just support 32bit counter, will timeout in 4s
This is untested. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> --- drivers/net/ethernet/freescale/fec.h | 3 ++- drivers/net/ethernet/freescale/fec_main.c | 8 ++++++-- drivers/net/ethernet/freescale/fec_ptp.c | 16 +++++++++++++++- 3 files changed, 23 insertions(+), 4 deletions(-)