[net-next 2/3] net: mscc: ocelot: convert to ocelot_port_txtstamp_request()

2021-04-16 Thread Yangbo Lu
Convert to a common ocelot_port_txtstamp_request() for TX timestamp
request handling.

Signed-off-by: Yangbo Lu 
---
 drivers/net/dsa/ocelot/felix.c | 14 +-
 drivers/net/ethernet/mscc/ocelot.c | 24 +---
 drivers/net/ethernet/mscc/ocelot_net.c | 18 +++---
 include/soc/mscc/ocelot.h  |  5 +++--
 4 files changed, 36 insertions(+), 25 deletions(-)

diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c
index cdec2f5e271c..5f2cf0f31253 100644
--- a/drivers/net/dsa/ocelot/felix.c
+++ b/drivers/net/dsa/ocelot/felix.c
@@ -1399,18 +1399,14 @@ static bool felix_txtstamp(struct dsa_switch *ds, int 
port,
   struct sk_buff *skb, struct sk_buff **clone)
 {
struct ocelot *ocelot = ds->priv;
-   struct ocelot_port *ocelot_port = ocelot->ports[port];
 
-   if (ocelot->ptp && ocelot_port->ptp_cmd == IFH_REW_OP_TWO_STEP_PTP) {
-   *clone = skb_clone_sk(skb);
-   if (!(*clone))
-   return false;
+   if (!ocelot->ptp)
+   return false;
 
-   ocelot_port_add_txtstamp_skb(ocelot, port, *clone);
-   return true;
-   }
+   if (ocelot_port_txtstamp_request(ocelot, port, skb, clone))
+   return false;
 
-   return false;
+   return true;
 }
 
 static int felix_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
diff --git a/drivers/net/ethernet/mscc/ocelot.c 
b/drivers/net/ethernet/mscc/ocelot.c
index 8d06ffaf318a..541d3b4076be 100644
--- a/drivers/net/ethernet/mscc/ocelot.c
+++ b/drivers/net/ethernet/mscc/ocelot.c
@@ -530,8 +530,8 @@ void ocelot_port_disable(struct ocelot *ocelot, int port)
 }
 EXPORT_SYMBOL(ocelot_port_disable);
 
-void ocelot_port_add_txtstamp_skb(struct ocelot *ocelot, int port,
- struct sk_buff *clone)
+static void ocelot_port_add_txtstamp_skb(struct ocelot *ocelot, int port,
+struct sk_buff *clone)
 {
struct ocelot_port *ocelot_port = ocelot->ports[port];
 
@@ -545,7 +545,25 @@ void ocelot_port_add_txtstamp_skb(struct ocelot *ocelot, 
int port,
 
spin_unlock(&ocelot_port->ts_id_lock);
 }
-EXPORT_SYMBOL(ocelot_port_add_txtstamp_skb);
+
+int ocelot_port_txtstamp_request(struct ocelot *ocelot, int port,
+struct sk_buff *skb,
+struct sk_buff **clone)
+{
+   struct ocelot_port *ocelot_port = ocelot->ports[port];
+   u8 ptp_cmd = ocelot_port->ptp_cmd;
+
+   if (ptp_cmd == IFH_REW_OP_TWO_STEP_PTP) {
+   *clone = skb_clone_sk(skb);
+   if (!(*clone))
+   return -ENOMEM;
+
+   ocelot_port_add_txtstamp_skb(ocelot, port, *clone);
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL(ocelot_port_txtstamp_request);
 
 static void ocelot_get_hwtimestamp(struct ocelot *ocelot,
   struct timespec64 *ts)
diff --git a/drivers/net/ethernet/mscc/ocelot_net.c 
b/drivers/net/ethernet/mscc/ocelot_net.c
index 36f32a4d9b0f..8293152a6dc1 100644
--- a/drivers/net/ethernet/mscc/ocelot_net.c
+++ b/drivers/net/ethernet/mscc/ocelot_net.c
@@ -507,19 +507,15 @@ static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, 
struct net_device *dev)
 
/* Check if timestamping is needed */
if (ocelot->ptp && (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
-   rew_op = ocelot_port->ptp_cmd;
+   struct sk_buff *clone;
 
-   if (ocelot_port->ptp_cmd == IFH_REW_OP_TWO_STEP_PTP) {
-   struct sk_buff *clone;
-
-   clone = skb_clone_sk(skb);
-   if (!clone) {
-   kfree_skb(skb);
-   return NETDEV_TX_OK;
-   }
-
-   ocelot_port_add_txtstamp_skb(ocelot, port, clone);
+   if (ocelot_port_txtstamp_request(ocelot, port, skb, &clone)) {
+   kfree_skb(skb);
+   return NETDEV_TX_OK;
+   }
 
+   if (ocelot_port->ptp_cmd == IFH_REW_OP_TWO_STEP_PTP) {
+   rew_op = ocelot_port->ptp_cmd;
rew_op |= clone->cb[0] << 3;
}
}
diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h
index 68cdc7ceaf4d..9cdaf1d9199f 100644
--- a/include/soc/mscc/ocelot.h
+++ b/include/soc/mscc/ocelot.h
@@ -820,8 +820,9 @@ int ocelot_vlan_add(struct ocelot *ocelot, int port, u16 
vid, bool pvid,
 int ocelot_vlan_del(struct ocelot *ocelot, int port, u16 vid);
 int ocelot_hwstamp_get(struct ocelot *ocelot, int port, struct ifreq *ifr);
 int ocelot_hwstamp_set(struct ocelot *ocelot, int port, struct ifreq *ifr);
-void ocelot_port_add_txtstamp_skb(struct ocelot

[net-next 3/3] net: mscc: ocelot: support PTP Sync one-step timestamping

2021-04-16 Thread Yangbo Lu
Although HWTSTAMP_TX_ONESTEP_SYNC existed in ioctl for hardware timestamp
configuration, the PTP Sync one-step timestamping had never been supported.

This patch is to truely support it. The hardware timestamp request type is
stored in DSA_SKB_CB_PRIV first byte per skb, so that corresponding
configuration could be done during transmitting. Non-onestep-Sync packet
with one-step timestamp request should fall back to use two-step timestamp.

Signed-off-by: Yangbo Lu 
---
 drivers/net/ethernet/mscc/ocelot.c | 57 ++
 drivers/net/ethernet/mscc/ocelot_net.c |  5 +--
 include/soc/mscc/ocelot.h  |  1 +
 net/dsa/tag_ocelot.c   | 25 ++-
 net/dsa/tag_ocelot_8021q.c | 39 +-
 5 files changed, 72 insertions(+), 55 deletions(-)

diff --git a/drivers/net/ethernet/mscc/ocelot.c 
b/drivers/net/ethernet/mscc/ocelot.c
index 541d3b4076be..69d36b6241ff 100644
--- a/drivers/net/ethernet/mscc/ocelot.c
+++ b/drivers/net/ethernet/mscc/ocelot.c
@@ -6,6 +6,7 @@
  */
 #include 
 #include 
+#include 
 #include 
 #include "ocelot.h"
 #include "ocelot_vcap.h"
@@ -546,6 +547,50 @@ static void ocelot_port_add_txtstamp_skb(struct ocelot 
*ocelot, int port,
spin_unlock(&ocelot_port->ts_id_lock);
 }
 
+bool ocelot_ptp_rew_op(struct sk_buff *skb, struct sk_buff *clone, u32 *rew_op)
+{
+   /* For two-step timestamp, retrieve ptp_cmd in DSA_SKB_CB_PRIV
+* and timestamp ID in clone->cb[0].
+* For one-step timestamp, retrieve ptp_cmd in DSA_SKB_CB_PRIV.
+*/
+   u8 *ptp_cmd = DSA_SKB_CB_PRIV(skb);
+
+   if (clone) {
+   *rew_op = *ptp_cmd;
+   *rew_op |= clone->cb[0] << 3;
+   } else if (*ptp_cmd) {
+   *rew_op = *ptp_cmd;
+   } else {
+   return false;
+   }
+
+   return true;
+}
+EXPORT_SYMBOL(ocelot_ptp_rew_op);
+
+static bool ocelot_ptp_is_onestep_sync(struct sk_buff *skb)
+{
+   struct ptp_header *hdr;
+   unsigned int ptp_class;
+   u8 msgtype, twostep;
+
+   ptp_class = ptp_classify_raw(skb);
+   if (ptp_class == PTP_CLASS_NONE)
+   return false;
+
+   hdr = ptp_parse_header(skb, ptp_class);
+   if (!hdr)
+   return false;
+
+   msgtype = ptp_get_msgtype(hdr, ptp_class);
+   twostep = hdr->flag_field[0] & 0x2;
+
+   if (msgtype == PTP_MSGTYPE_SYNC && twostep == 0)
+   return true;
+
+   return false;
+}
+
 int ocelot_port_txtstamp_request(struct ocelot *ocelot, int port,
 struct sk_buff *skb,
 struct sk_buff **clone)
@@ -553,12 +598,24 @@ int ocelot_port_txtstamp_request(struct ocelot *ocelot, 
int port,
struct ocelot_port *ocelot_port = ocelot->ports[port];
u8 ptp_cmd = ocelot_port->ptp_cmd;
 
+   /* Store ptp_cmd in first byte of DSA_SKB_CB_PRIV per skb */
+   if (ptp_cmd == IFH_REW_OP_ORIGIN_PTP) {
+   if (ocelot_ptp_is_onestep_sync(skb)) {
+   *(u8 *)DSA_SKB_CB_PRIV(skb) = ptp_cmd;
+   return 0;
+   }
+
+   /* Fall back to two-step timestamping */
+   ptp_cmd = IFH_REW_OP_TWO_STEP_PTP;
+   }
+
if (ptp_cmd == IFH_REW_OP_TWO_STEP_PTP) {
*clone = skb_clone_sk(skb);
if (!(*clone))
return -ENOMEM;
 
ocelot_port_add_txtstamp_skb(ocelot, port, *clone);
+   *(u8 *)DSA_SKB_CB_PRIV(skb) = ptp_cmd;
}
 
return 0;
diff --git a/drivers/net/ethernet/mscc/ocelot_net.c 
b/drivers/net/ethernet/mscc/ocelot_net.c
index 8293152a6dc1..eb3d525731da 100644
--- a/drivers/net/ethernet/mscc/ocelot_net.c
+++ b/drivers/net/ethernet/mscc/ocelot_net.c
@@ -514,10 +514,7 @@ static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, 
struct net_device *dev)
return NETDEV_TX_OK;
}
 
-   if (ocelot_port->ptp_cmd == IFH_REW_OP_TWO_STEP_PTP) {
-   rew_op = ocelot_port->ptp_cmd;
-   rew_op |= clone->cb[0] << 3;
-   }
+   ocelot_ptp_rew_op(skb, clone, &rew_op);
}
 
ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb);
diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h
index 9cdaf1d9199f..19413532db0b 100644
--- a/include/soc/mscc/ocelot.h
+++ b/include/soc/mscc/ocelot.h
@@ -820,6 +820,7 @@ int ocelot_vlan_add(struct ocelot *ocelot, int port, u16 
vid, bool pvid,
 int ocelot_vlan_del(struct ocelot *ocelot, int port, u16 vid);
 int ocelot_hwstamp_get(struct ocelot *ocelot, int port, struct ifreq *ifr);
 int ocelot_hwstamp_set(struct ocelot *ocelot, int port, struct ifreq *ifr);
+bool ocelot_ptp_rew_op(struct sk_buff *skb, struct sk_buff *clone, u32 
*rew_op);
 int ocelot_port_txtstamp_request(s

[net-next 0/3] Support ocelot PTP Sync one-step timestamping

2021-04-16 Thread Yangbo Lu
This patch-set is to support ocelot PTP Sync one-step timestamping.
Actually before that, this patch-set cleans up and optimizes the
DSA slave tx timestamp request handling process.

Yangbo Lu (3):
  net: dsa: optimize tx timestamp request handling
  net: mscc: ocelot: convert to ocelot_port_txtstamp_request()
  net: mscc: ocelot: support PTP Sync one-step timestamping

 Documentation/networking/timestamping.rst |  7 +-
 .../net/dsa/hirschmann/hellcreek_hwtstamp.c   | 20 +++--
 .../net/dsa/hirschmann/hellcreek_hwtstamp.h   |  2 +-
 drivers/net/dsa/mv88e6xxx/hwtstamp.c  | 21 +++--
 drivers/net/dsa/mv88e6xxx/hwtstamp.h  |  6 +-
 drivers/net/dsa/ocelot/felix.c| 15 ++--
 drivers/net/dsa/sja1105/sja1105_ptp.c |  6 +-
 drivers/net/dsa/sja1105/sja1105_ptp.h |  2 +-
 drivers/net/ethernet/mscc/ocelot.c| 81 ++-
 drivers/net/ethernet/mscc/ocelot_net.c| 19 ++---
 include/net/dsa.h |  2 +-
 include/soc/mscc/ocelot.h |  6 +-
 net/dsa/slave.c   | 20 ++---
 net/dsa/tag_ocelot.c  | 25 +-
 net/dsa/tag_ocelot_8021q.c| 39 +++--
 15 files changed, 158 insertions(+), 113 deletions(-)


base-commit: 392c36e5be1dee19ffce8c8ba8f07f90f5aa3f7c
-- 
2.25.1



[net-next 1/3] net: dsa: optimize tx timestamp request handling

2021-04-16 Thread Yangbo Lu
Optimization could be done on dsa_skb_tx_timestamp(), and dsa device
drivers should adapt to it.

- Check SKBTX_HW_TSTAMP request flag at the very beginning, instead of in
  port_txtstamp, so that most skbs not requiring tx timestamp just return.

- No longer to identify PTP packets, and limit tx timestamping only for PTP
  packets. If device driver likes, let device driver do.

- It is a waste to clone skb directly in dsa_skb_tx_timestamp().
  For one-step timestamping, a clone is not needed. For any failure of
  port_txtstamp (this may usually happen), the skb clone has to be freed.
  So put skb cloning into port_txtstamp where it really needs.

Signed-off-by: Yangbo Lu 
---
 Documentation/networking/timestamping.rst |  7 +--
 .../net/dsa/hirschmann/hellcreek_hwtstamp.c   | 20 --
 .../net/dsa/hirschmann/hellcreek_hwtstamp.h   |  2 +-
 drivers/net/dsa/mv88e6xxx/hwtstamp.c  | 21 +--
 drivers/net/dsa/mv88e6xxx/hwtstamp.h  |  6 +++---
 drivers/net/dsa/ocelot/felix.c| 11 ++
 drivers/net/dsa/sja1105/sja1105_ptp.c |  6 +-
 drivers/net/dsa/sja1105/sja1105_ptp.h |  2 +-
 include/net/dsa.h |  2 +-
 net/dsa/slave.c   | 20 +-
 10 files changed, 57 insertions(+), 40 deletions(-)

diff --git a/Documentation/networking/timestamping.rst 
b/Documentation/networking/timestamping.rst
index f682e88fa87e..7f04a699a5d1 100644
--- a/Documentation/networking/timestamping.rst
+++ b/Documentation/networking/timestamping.rst
@@ -635,8 +635,8 @@ in generic code: a BPF classifier (``ptp_classify_raw``) is 
used to identify
 PTP event messages (any other packets, including PTP general messages, are not
 timestamped), and provides two hooks to drivers:
 
-- ``.port_txtstamp()``: The driver is passed a clone of the timestampable skb
-  to be transmitted, before actually transmitting it. Typically, a switch will
+- ``.port_txtstamp()``: A clone of the timestampable skb to be transmitted
+  is needed, before actually transmitting it. Typically, a switch will
   have a PTP TX timestamp register (or sometimes a FIFO) where the timestamp
   becomes available. There may be an IRQ that is raised upon this timestamp's
   availability, or the driver might have to poll after invoking
@@ -645,6 +645,9 @@ timestamped), and provides two hooks to drivers:
   later use (when the timestamp becomes available). Each skb is annotated with
   a pointer to its clone, in ``DSA_SKB_CB(skb)->clone``, to ease the driver's
   job of keeping track of which clone belongs to which skb.
+  But one-step timestamping request is handled differently with above two-step
+  timestamping. The skb clone is no longer needed since hardware will insert
+  TX time information on packet during egress.
 
 - ``.port_rxtstamp()``: The original (and only) timestampable skb is provided
   to the driver, for it to annotate it with a timestamp, if that is immediately
diff --git a/drivers/net/dsa/hirschmann/hellcreek_hwtstamp.c 
b/drivers/net/dsa/hirschmann/hellcreek_hwtstamp.c
index 69dd9a2e8bb6..2ff4b7c08b72 100644
--- a/drivers/net/dsa/hirschmann/hellcreek_hwtstamp.c
+++ b/drivers/net/dsa/hirschmann/hellcreek_hwtstamp.c
@@ -374,31 +374,39 @@ long hellcreek_hwtstamp_work(struct ptp_clock_info *ptp)
 }
 
 bool hellcreek_port_txtstamp(struct dsa_switch *ds, int port,
-struct sk_buff *clone, unsigned int type)
+struct sk_buff *skb, struct sk_buff **clone)
 {
struct hellcreek *hellcreek = ds->priv;
struct hellcreek_port_hwtstamp *ps;
struct ptp_header *hdr;
+   unsigned int type;
 
ps = &hellcreek->ports[port].port_hwtstamp;
 
-   /* Check if the driver is expected to do HW timestamping */
-   if (!(skb_shinfo(clone)->tx_flags & SKBTX_HW_TSTAMP))
+   type = ptp_classify_raw(skb);
+   if (type == PTP_CLASS_NONE)
return false;
 
/* Make sure the message is a PTP message that needs to be timestamped
 * and the interaction with the HW timestamping is enabled. If not, stop
 * here
 */
-   hdr = hellcreek_should_tstamp(hellcreek, port, clone, type);
+   hdr = hellcreek_should_tstamp(hellcreek, port, skb, type);
if (!hdr)
return false;
 
+   *clone = skb_clone_sk(skb);
+   if (!(*clone))
+   return false;
+
if (test_and_set_bit_lock(HELLCREEK_HWTSTAMP_TX_IN_PROGRESS,
- &ps->state))
+ &ps->state)) {
+   kfree_skb(*clone);
+   *clone = NULL;
return false;
+   }
 
-   ps->tx_skb = clone;
+   ps->tx_skb = *clone;
 
/* store the number of ticks occurred since system start-up till this
 * moment
diff --git a/drivers/net/dsa/hirschmann/

[net-next] enetc: convert to schedule_work()

2021-04-14 Thread Yangbo Lu
Convert system_wq queue_work() to schedule_work() which is
a wrapper around it, since the former is a rare construct.

Fixes: 7294380c5211 ("enetc: support PTP Sync packet one-step timestamping")
Signed-off-by: Yangbo Lu 
---
 drivers/net/ethernet/freescale/enetc/enetc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c 
b/drivers/net/ethernet/freescale/enetc/enetc.c
index 4a0adb0b8bd7..9a726085841d 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc.c
@@ -552,7 +552,7 @@ static bool enetc_clean_tx_ring(struct enetc_bdr *tx_ring, 
int napi_budget)
 * timestamping packet. And send one skb in
 * tx_skbs queue if has.
 */
-   queue_work(system_wq, &priv->tx_onestep_tstamp);
+   schedule_work(&priv->tx_onestep_tstamp);
} else if (unlikely(do_twostep_tstamp)) {
enetc_tstamp_tx(skb, tstamp);
do_twostep_tstamp = false;

base-commit: 3a1aa533f7f676aad68f8da10b9502903770
-- 
2.25.1



[net-next] enetc: fix locking for one-step timestamping packet transfer

2021-04-12 Thread Yangbo Lu
The previous patch to support PTP Sync packet one-step timestamping
described one-step timestamping packet handling logic as below in
commit message:

- Trasmit packet immediately if no other one in transfer, or queue to
  skb queue if there is already one in transfer.
  The test_and_set_bit_lock() is used here to lock and check state.
- Start a work when complete transfer on hardware, to release the bit
  lock and to send one skb in skb queue if has.

There was not problem of the description, but there was a mistake in
implementation. The locking/test_and_set_bit_lock() should be put in
enetc_start_xmit() which may be called by worker, rather than in
enetc_xmit(). Otherwise, the worker calling enetc_start_xmit() after
bit lock released is not able to lock again for transfer.

Fixes: 7294380c5211 ("enetc: support PTP Sync packet one-step timestamping")
Signed-off-by: Yangbo Lu 
---
 drivers/net/ethernet/freescale/enetc/enetc.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c 
b/drivers/net/ethernet/freescale/enetc/enetc.c
index 4a0adb0b8bd7..65f1772c5740 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc.c
@@ -301,6 +301,15 @@ static netdev_tx_t enetc_start_xmit(struct sk_buff *skb,
struct enetc_bdr *tx_ring;
int count;
 
+   /* Queue one-step Sync packet if already locked */
+   if (skb->cb[0] & ENETC_F_TX_ONESTEP_SYNC_TSTAMP) {
+   if (test_and_set_bit_lock(ENETC_TX_ONESTEP_TSTAMP_IN_PROGRESS,
+ &priv->flags)) {
+   skb_queue_tail(&priv->tx_skbs, skb);
+   return NETDEV_TX_OK;
+   }
+   }
+
tx_ring = priv->tx_ring[skb->queue_mapping];
 
if (unlikely(skb_shinfo(skb)->nr_frags > ENETC_MAX_SKB_FRAGS))
@@ -352,15 +361,6 @@ netdev_tx_t enetc_xmit(struct sk_buff *skb, struct 
net_device *ndev)
skb->cb[0] = ENETC_F_TX_TSTAMP;
}
 
-   /* Queue one-step Sync packet if already locked */
-   if (skb->cb[0] & ENETC_F_TX_ONESTEP_SYNC_TSTAMP) {
-   if (test_and_set_bit_lock(ENETC_TX_ONESTEP_TSTAMP_IN_PROGRESS,
- &priv->flags)) {
-   skb_queue_tail(&priv->tx_skbs, skb);
-   return NETDEV_TX_OK;
-   }
-   }
-
return enetc_start_xmit(skb, ndev);
 }
 

base-commit: 8ef7adc6beb2ef0bce83513dc9e4505e7b21e8c2
-- 
2.25.1



[net-next, v3, 2/2] enetc: support PTP Sync packet one-step timestamping

2021-04-12 Thread Yangbo Lu
This patch is to add support for PTP Sync packet one-step timestamping.
Since ENETC single-step register has to be configured dynamically per
packet for correctionField offeset and UDP checksum update, current
one-step timestamping packet has to be sent only when the last one
completes transmitting on hardware. So, on the TX, this patch handles
one-step timestamping packet as below:

- Trasmit packet immediately if no other one in transfer, or queue to
  skb queue if there is already one in transfer.
  The test_and_set_bit_lock() is used here to lock and check state.
- Start a work when complete transfer on hardware, to release the bit
  lock and to send one skb in skb queue if has.

And the configuration for one-step timestamping on ENETC before
transmitting is,

- Set one-step timestamping flag in extension BD.
- Write 30 bits current timestamp in tstamp field of extension BD.
- Update PTP Sync packet originTimestamp field with current timestamp.
- Configure single-step register for correctionField offeset and UDP
  checksum update.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- Rebased.
- Fixed issues from patchwork checks.
- netif_tx_lock for one-step timestamping packet sending.
Changes for v3:
- Used system workqueue.
- Set bit lock when transmitted one-step packet, and scheduled
  work when completed. The worker cleared the bit lock, and
  transmitted one skb in skb queue if has, instead of a loop.
---
 drivers/net/ethernet/freescale/enetc/enetc.c  | 191 --
 drivers/net/ethernet/freescale/enetc/enetc.h  |  20 +-
 .../ethernet/freescale/enetc/enetc_ethtool.c  |   3 +-
 .../net/ethernet/freescale/enetc/enetc_hw.h   |   7 +
 4 files changed, 195 insertions(+), 26 deletions(-)

diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c 
b/drivers/net/ethernet/freescale/enetc/enetc.c
index 6e3a5303e2bb..4a0adb0b8bd7 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc.c
@@ -6,6 +6,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 static struct sk_buff *enetc_tx_swbd_get_skb(struct enetc_tx_swbd *tx_swbd)
@@ -67,15 +68,52 @@ static void enetc_update_tx_ring_tail(struct enetc_bdr 
*tx_ring)
enetc_wr_reg_hot(tx_ring->tpir, tx_ring->next_to_use);
 }
 
+static int enetc_ptp_parse(struct sk_buff *skb, u8 *udp,
+  u8 *msgtype, u8 *twostep,
+  u16 *correction_offset, u16 *body_offset)
+{
+   unsigned int ptp_class;
+   struct ptp_header *hdr;
+   unsigned int type;
+   u8 *base;
+
+   ptp_class = ptp_classify_raw(skb);
+   if (ptp_class == PTP_CLASS_NONE)
+   return -EINVAL;
+
+   hdr = ptp_parse_header(skb, ptp_class);
+   if (!hdr)
+   return -EINVAL;
+
+   type = ptp_class & PTP_CLASS_PMASK;
+   if (type == PTP_CLASS_IPV4 || type == PTP_CLASS_IPV6)
+   *udp = 1;
+   else
+   *udp = 0;
+
+   *msgtype = ptp_get_msgtype(hdr, ptp_class);
+   *twostep = hdr->flag_field[0] & 0x2;
+
+   base = skb_mac_header(skb);
+   *correction_offset = (u8 *)&hdr->correction - base;
+   *body_offset = (u8 *)hdr + sizeof(struct ptp_header) - base;
+
+   return 0;
+}
+
 static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb)
 {
+   bool do_vlan, do_onestep_tstamp = false, do_twostep_tstamp = false;
+   struct enetc_ndev_priv *priv = netdev_priv(tx_ring->ndev);
+   struct enetc_hw *hw = &priv->si->hw;
struct enetc_tx_swbd *tx_swbd;
-   skb_frag_t *frag;
int len = skb_headlen(skb);
union enetc_tx_bd temp_bd;
+   u8 msgtype, twostep, udp;
union enetc_tx_bd *txbd;
-   bool do_vlan, do_tstamp;
+   u16 offset1, offset2;
int i, count = 0;
+   skb_frag_t *frag;
unsigned int f;
dma_addr_t dma;
u8 flags = 0;
@@ -100,12 +138,21 @@ static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, 
struct sk_buff *skb)
count++;
 
do_vlan = skb_vlan_tag_present(skb);
-   do_tstamp = (skb->cb[0] & ENETC_F_TX_TSTAMP) &&
-   (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP);
-   tx_swbd->do_tstamp = do_tstamp;
-   tx_swbd->check_wb = tx_swbd->do_tstamp;
+   if (skb->cb[0] & ENETC_F_TX_ONESTEP_SYNC_TSTAMP) {
+   if (enetc_ptp_parse(skb, &udp, &msgtype, &twostep, &offset1,
+   &offset2) ||
+   msgtype != PTP_MSGTYPE_SYNC || twostep)
+   WARN_ONCE(1, "Bad packet for one-step timestamping\n");
+   else
+   do_onestep_tstamp = true;
+   } else if (skb->cb[0] & ENETC_F_TX_TSTAMP) {
+   do_twostep_tstamp = true;
+   }
+
+   tx_swbd->do_twostep_tst

[net-next, v3, 1/2] enetc: mark TX timestamp type per skb

2021-04-12 Thread Yangbo Lu
Mark TX timestamp type per skb on skb->cb[0], instead of
global variable for all skbs. This is a preparation for
one step timestamp support.

For one-step timestamping enablement, there will be both
one-step and two-step PTP messages to transfer. And a skb
queue is needed for one-step PTP messages making sure
start to send current message only after the last one
completed on hardware. (ENETC single-step register has to
be dynamically configured per message.) So, marking TX
timestamp type per skb is required.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- Rebased.
Changes for v3:
- None.
---
 drivers/net/ethernet/freescale/enetc/enetc.c | 10 ++
 drivers/net/ethernet/freescale/enetc/enetc.h | 11 +++
 2 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c 
b/drivers/net/ethernet/freescale/enetc/enetc.c
index 41bfc6e623bf..6e3a5303e2bb 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc.c
@@ -67,8 +67,7 @@ static void enetc_update_tx_ring_tail(struct enetc_bdr 
*tx_ring)
enetc_wr_reg_hot(tx_ring->tpir, tx_ring->next_to_use);
 }
 
-static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb,
- int active_offloads)
+static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb)
 {
struct enetc_tx_swbd *tx_swbd;
skb_frag_t *frag;
@@ -101,7 +100,7 @@ static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, 
struct sk_buff *skb,
count++;
 
do_vlan = skb_vlan_tag_present(skb);
-   do_tstamp = (active_offloads & ENETC_F_TX_TSTAMP) &&
+   do_tstamp = (skb->cb[0] & ENETC_F_TX_TSTAMP) &&
(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP);
tx_swbd->do_tstamp = do_tstamp;
tx_swbd->check_wb = tx_swbd->do_tstamp;
@@ -221,6 +220,9 @@ netdev_tx_t enetc_xmit(struct sk_buff *skb, struct 
net_device *ndev)
struct enetc_bdr *tx_ring;
int count;
 
+   /* cb[0] used for TX timestamp type */
+   skb->cb[0] = priv->active_offloads & ENETC_F_TX_TSTAMP_MASK;
+
tx_ring = priv->tx_ring[skb->queue_mapping];
 
if (unlikely(skb_shinfo(skb)->nr_frags > ENETC_MAX_SKB_FRAGS))
@@ -234,7 +236,7 @@ netdev_tx_t enetc_xmit(struct sk_buff *skb, struct 
net_device *ndev)
}
 
enetc_lock_mdio();
-   count = enetc_map_tx_buffs(tx_ring, skb, priv->active_offloads);
+   count = enetc_map_tx_buffs(tx_ring, skb);
enetc_unlock_mdio();
 
if (unlikely(!count))
diff --git a/drivers/net/ethernet/freescale/enetc/enetc.h 
b/drivers/net/ethernet/freescale/enetc/enetc.h
index 05474f46b0d9..96889529383e 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc.h
@@ -271,12 +271,15 @@ struct psfp_cap {
u32 max_psfp_meter;
 };
 
+#define ENETC_F_TX_TSTAMP_MASK 0xff
 /* TODO: more hardware offloads */
 enum enetc_active_offloads {
-   ENETC_F_RX_TSTAMP   = BIT(0),
-   ENETC_F_TX_TSTAMP   = BIT(1),
-   ENETC_F_QBV = BIT(2),
-   ENETC_F_QCI = BIT(3),
+   /* 8 bits reserved for TX timestamp types (hwtstamp_tx_types) */
+   ENETC_F_TX_TSTAMP   = BIT(0),
+
+   ENETC_F_RX_TSTAMP   = BIT(8),
+   ENETC_F_QBV = BIT(9),
+   ENETC_F_QCI = BIT(10),
 };
 
 /* interrupt coalescing modes */
-- 
2.25.1



[net-next, v3, 0/2] enetc: support PTP Sync packet one-step timestamping

2021-04-12 Thread Yangbo Lu
This patch-set is to add support for PTP Sync packet one-step timestamping.
Since ENETC single-step register has to be configured dynamically per
packet for correctionField offeset and UDP checksum update, current
one-step timestamping packet has to be sent only when the last one
completes transmitting on hardware. So, on the TX, this patch handles
one-step timestamping packet as below:

- Trasmit packet immediately if no other one in transfer, or queue to
  skb queue if there is already one in transfer.
  The test_and_set_bit_lock() is used here to lock and check state.
- Start a work when complete transfer on hardware, to release the bit
  lock and to send one skb in skb queue if has.

Changes for v2:
- Rebased.
- Fixed issues from patchwork checks.
- netif_tx_lock for one-step timestamping packet sending.
Changes for v3:
- Used system workqueue.
- Set bit lock when transmitted one-step packet, and scheduled
  work when completed. The worker cleared the bit lock, and
  transmitted one skb in skb queue if has, instead of a loop.

Yangbo Lu (2):
  enetc: mark TX timestamp type per skb
  enetc: support PTP Sync packet one-step timestamping

 drivers/net/ethernet/freescale/enetc/enetc.c  | 193 --
 drivers/net/ethernet/freescale/enetc/enetc.h  |  23 ++-
 .../ethernet/freescale/enetc/enetc_ethtool.c  |   3 +-
 .../net/ethernet/freescale/enetc/enetc_hw.h   |   7 +
 4 files changed, 200 insertions(+), 26 deletions(-)


base-commit: 5b489fea977c2b23e26e2f630478da0f4bfdc879
-- 
2.25.1



[net-next, v2, 2/2] enetc: support PTP Sync packet one-step timestamping

2021-04-08 Thread Yangbo Lu
This patch is to add support for PTP Sync packet one-step timestamping.
Since ENETC single-step register has to be configured dynamically per
packet for correctionField offeset and UDP checksum update, current
one-step timestamping packet has to be sent only when the last one
completes transmitting on hardware. So, on the TX below things are done
by the patch:

- For one-step timestamping packet, queue to skb queue.
- Start a work to transmit skbs in queue.
- For other skbs, transmit immediately.
- mutex lock used to ensure the last one-step timestamping packet has
  already been transmitted on hardware before transmitting current one.

And the configuration for one-step timestamping on ENETC before
transmitting is,

- Set one-step timestamping flag in extension BD.
- Write 30 bits current timestamp in tstamp field of extension BD.
- Update PTP Sync packet originTimestamp field with current timestamp.
- Configure single-step register for correctionField offeset and UDP
  checksum update.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- Rebased.
- Fixed issues from patchwork checks.
- netif_tx_lock for one-step timestamping packet sending.
---
 drivers/net/ethernet/freescale/enetc/enetc.c  | 210 --
 drivers/net/ethernet/freescale/enetc/enetc.h  |  21 +-
 .../ethernet/freescale/enetc/enetc_ethtool.c  |   3 +-
 .../net/ethernet/freescale/enetc/enetc_hw.h   |   7 +
 4 files changed, 215 insertions(+), 26 deletions(-)

diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c 
b/drivers/net/ethernet/freescale/enetc/enetc.c
index 61bd2981517c..a14ce943e14c 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc.c
@@ -6,6 +6,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 static struct sk_buff *enetc_tx_swbd_get_skb(struct enetc_tx_swbd *tx_swbd)
@@ -67,15 +68,52 @@ static void enetc_update_tx_ring_tail(struct enetc_bdr 
*tx_ring)
enetc_wr_reg_hot(tx_ring->tpir, tx_ring->next_to_use);
 }
 
+static int enetc_ptp_parse(struct sk_buff *skb, u8 *udp,
+  u8 *msgtype, u8 *twostep,
+  u16 *correction_offset, u16 *body_offset)
+{
+   unsigned int ptp_class;
+   struct ptp_header *hdr;
+   unsigned int type;
+   u8 *base;
+
+   ptp_class = ptp_classify_raw(skb);
+   if (ptp_class == PTP_CLASS_NONE)
+   return -EINVAL;
+
+   hdr = ptp_parse_header(skb, ptp_class);
+   if (!hdr)
+   return -EINVAL;
+
+   type = ptp_class & PTP_CLASS_PMASK;
+   if (type == PTP_CLASS_IPV4 || type == PTP_CLASS_IPV6)
+   *udp = 1;
+   else
+   *udp = 0;
+
+   *msgtype = ptp_get_msgtype(hdr, ptp_class);
+   *twostep = hdr->flag_field[0] & 0x2;
+
+   base = skb_mac_header(skb);
+   *correction_offset = (u8 *)&hdr->correction - base;
+   *body_offset = (u8 *)hdr + sizeof(struct ptp_header) - base;
+
+   return 0;
+}
+
 static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb)
 {
+   bool do_vlan, do_onestep_tstamp = false, do_twostep_tstamp = false;
+   struct enetc_ndev_priv *priv = netdev_priv(tx_ring->ndev);
+   struct enetc_hw *hw = &priv->si->hw;
struct enetc_tx_swbd *tx_swbd;
-   skb_frag_t *frag;
int len = skb_headlen(skb);
union enetc_tx_bd temp_bd;
+   u8 msgtype, twostep, udp;
union enetc_tx_bd *txbd;
-   bool do_vlan, do_tstamp;
+   u16 offset1, offset2;
int i, count = 0;
+   skb_frag_t *frag;
unsigned int f;
dma_addr_t dma;
u8 flags = 0;
@@ -100,12 +138,21 @@ static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, 
struct sk_buff *skb)
count++;
 
do_vlan = skb_vlan_tag_present(skb);
-   do_tstamp = (skb->cb[0] & ENETC_F_TX_TSTAMP) &&
-   (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP);
-   tx_swbd->do_tstamp = do_tstamp;
-   tx_swbd->check_wb = tx_swbd->do_tstamp;
+   if (skb->cb[0] & ENETC_F_TX_ONESTEP_SYNC_TSTAMP) {
+   if (enetc_ptp_parse(skb, &udp, &msgtype, &twostep, &offset1,
+   &offset2) ||
+   msgtype != PTP_MSGTYPE_SYNC || twostep)
+   WARN_ONCE(1, "Bad packet for one-step timestamping\n");
+   else
+   do_onestep_tstamp = true;
+   } else if (skb->cb[0] & ENETC_F_TX_TSTAMP) {
+   do_twostep_tstamp = true;
+   }
+
+   tx_swbd->do_twostep_tstamp = do_twostep_tstamp;
+   tx_swbd->check_wb = tx_swbd->do_twostep_tstamp;
 
-   if (do_vlan || do_tstamp)
+   if (do_vlan || do_onestep_tstamp || do_twostep_tstamp)
flags |= ENETC_TXBD_FLAGS_EX;
 
if (tx_ring->tsd_enable)
@@ -142,7 +189,40 @@ static int enetc_

[net-next, v2, 1/2] enetc: mark TX timestamp type per skb

2021-04-08 Thread Yangbo Lu
Mark TX timestamp type per skb on skb->cb[0], instead of
global variable for all skbs. This is a preparation for
one step timestamp support.

For one-step timestamping enablement, there will be both
one-step and two-step PTP messages to transfer. And a skb
queue is needed for one-step PTP messages making sure
start to send current message only after the last one
completed on hardware. (ENETC single-step register has to
be dynamically configured per message.) So, marking TX
timestamp type per skb is required.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- Rebased.
---
 drivers/net/ethernet/freescale/enetc/enetc.c | 10 ++
 drivers/net/ethernet/freescale/enetc/enetc.h | 11 +++
 2 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c 
b/drivers/net/ethernet/freescale/enetc/enetc.c
index 57049ae97201..61bd2981517c 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc.c
@@ -67,8 +67,7 @@ static void enetc_update_tx_ring_tail(struct enetc_bdr 
*tx_ring)
enetc_wr_reg_hot(tx_ring->tpir, tx_ring->next_to_use);
 }
 
-static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb,
- int active_offloads)
+static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb)
 {
struct enetc_tx_swbd *tx_swbd;
skb_frag_t *frag;
@@ -101,7 +100,7 @@ static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, 
struct sk_buff *skb,
count++;
 
do_vlan = skb_vlan_tag_present(skb);
-   do_tstamp = (active_offloads & ENETC_F_TX_TSTAMP) &&
+   do_tstamp = (skb->cb[0] & ENETC_F_TX_TSTAMP) &&
(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP);
tx_swbd->do_tstamp = do_tstamp;
tx_swbd->check_wb = tx_swbd->do_tstamp;
@@ -221,6 +220,9 @@ netdev_tx_t enetc_xmit(struct sk_buff *skb, struct 
net_device *ndev)
struct enetc_bdr *tx_ring;
int count;
 
+   /* cb[0] used for TX timestamp type */
+   skb->cb[0] = priv->active_offloads & ENETC_F_TX_TSTAMP_MASK;
+
tx_ring = priv->tx_ring[skb->queue_mapping];
 
if (unlikely(skb_shinfo(skb)->nr_frags > ENETC_MAX_SKB_FRAGS))
@@ -234,7 +236,7 @@ netdev_tx_t enetc_xmit(struct sk_buff *skb, struct 
net_device *ndev)
}
 
enetc_lock_mdio();
-   count = enetc_map_tx_buffs(tx_ring, skb, priv->active_offloads);
+   count = enetc_map_tx_buffs(tx_ring, skb);
enetc_unlock_mdio();
 
if (unlikely(!count))
diff --git a/drivers/net/ethernet/freescale/enetc/enetc.h 
b/drivers/net/ethernet/freescale/enetc/enetc.h
index 05474f46b0d9..96889529383e 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc.h
@@ -271,12 +271,15 @@ struct psfp_cap {
u32 max_psfp_meter;
 };
 
+#define ENETC_F_TX_TSTAMP_MASK 0xff
 /* TODO: more hardware offloads */
 enum enetc_active_offloads {
-   ENETC_F_RX_TSTAMP   = BIT(0),
-   ENETC_F_TX_TSTAMP   = BIT(1),
-   ENETC_F_QBV = BIT(2),
-   ENETC_F_QCI = BIT(3),
+   /* 8 bits reserved for TX timestamp types (hwtstamp_tx_types) */
+   ENETC_F_TX_TSTAMP   = BIT(0),
+
+   ENETC_F_RX_TSTAMP   = BIT(8),
+   ENETC_F_QBV = BIT(9),
+   ENETC_F_QCI = BIT(10),
 };
 
 /* interrupt coalescing modes */
-- 
2.25.1



[net-next, v2, 0/2] enetc: support PTP Sync packet one-step timestamping

2021-04-08 Thread Yangbo Lu
This patch-set is to add one-step timestamping support for PTP Sync
packet. Since ENETC single-step register has to be configured dynamically
per packet for correctionField offeset and UDP checksum update, current
one-step timestamping packet has to be sent only when the last one
completes transmitting on hardware. So, on the TX the patch implements
below process:

- For one-step timestamping packet, queue to skb queue.
- Start a work to transmit skbs in queue.
- For other skbs, transmit immediately.
- mutex lock used to ensure the last one-step timestamping packet has
  already been transmitted on hardware before transmitting current one.

Changes for v2:
- Rebased.
- Fixed issues from patchwork checks.
- netif_tx_lock for one-step timestamping packet sending.

Yangbo Lu (2):
  enetc: mark TX timestamp type per skb
  enetc: support PTP Sync packet one-step timestamping

 drivers/net/ethernet/freescale/enetc/enetc.c  | 212 --
 drivers/net/ethernet/freescale/enetc/enetc.h  |  24 +-
 .../ethernet/freescale/enetc/enetc_ethtool.c  |   3 +-
 .../net/ethernet/freescale/enetc/enetc_hw.h   |   7 +
 4 files changed, 220 insertions(+), 26 deletions(-)


base-commit: 3cd52c1e32fe7dfee09815ced702db9ee9f84ec9
-- 
2.25.1



[PATCH 0/2] enetc: support PTP Sync packet one-step timestamping

2021-03-26 Thread Yangbo Lu
This patch-set is to add one-step timestamping support for PTP Sync
packet. Since ENETC single-step register has to be configured dynamically
per packet for correctionField offeset and UDP checksum update, current
one-step timestamping packet has to be sent only when the last one
completes transmitting on hardware. So, on the TX the patch implements
below process:

- For one-step timestamping packet, queue to skb queue.
- Start a work to transmit skbs in queue.
- For other skbs, transmit immediately.
- mutex lock used to ensure the last one-step timestamping packet has
  already been transmitted on hardware before transmitting current one.

Yangbo Lu (2):
  enetc: mark TX timestamp type per skb
  enetc: support PTP Sync packet one-step timestamping

 drivers/net/ethernet/freescale/enetc/enetc.c  | 206 --
 drivers/net/ethernet/freescale/enetc/enetc.h  |  24 +-
 .../ethernet/freescale/enetc/enetc_ethtool.c  |   3 +-
 .../net/ethernet/freescale/enetc/enetc_hw.h   |   7 +
 4 files changed, 214 insertions(+), 26 deletions(-)

-- 
2.25.1



[PATCH 2/2] enetc: support PTP Sync packet one-step timestamping

2021-03-26 Thread Yangbo Lu
This patch is to add support for PTP Sync packet one-step timestamping.
Since ENETC single-step register has to be configured dynamically per
packet for correctionField offeset and UDP checksum update, current
one-step timestamping packet has to be sent only when the last one
completes transmitting on hardware. So, on the TX below things are done
by the patch:

- For one-step timestamping packet, queue to skb queue.
- Start a work to transmit skbs in queue.
- For other skbs, transmit immediately.
- mutex lock used to ensure the last one-step timestamping packet has
  already been transmitted on hardware before transmitting current one.

And the configuration for one-step timestamping on ENETC before
transmitting is,

- Set one-step timestamping flag in extension BD.
- Write 30 bits current timestamp in tstamp field of extension BD.
- Update PTP Sync packet originTimestamp field with current timestamp.
- Configure single-step register for correctionField offeset and UDP
  checksum update.

Signed-off-by: Yangbo Lu 
---
 drivers/net/ethernet/freescale/enetc/enetc.c  | 204 --
 drivers/net/ethernet/freescale/enetc/enetc.h  |  21 +-
 .../ethernet/freescale/enetc/enetc_ethtool.c  |   3 +-
 .../net/ethernet/freescale/enetc/enetc_hw.h   |   7 +
 4 files changed, 209 insertions(+), 26 deletions(-)

diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c 
b/drivers/net/ethernet/freescale/enetc/enetc.c
index 61d684086432..7e33842d265e 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc.c
@@ -5,6 +5,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 /* ENETC overhead: optional extension BD + 1 BD gap */
@@ -37,15 +38,52 @@ static void enetc_free_tx_skb(struct enetc_bdr *tx_ring,
}
 }
 
+static int enetc_ptp_parse(struct sk_buff *skb, u8 *udp,
+  u8 *msgtype, u8 *twostep,
+  u16 *correction_offset, u16 *body_offset)
+{
+   unsigned int ptp_class;
+   struct ptp_header *hdr;
+   unsigned int type;
+   u8 *base;
+
+   ptp_class = ptp_classify_raw(skb);
+   if (ptp_class == PTP_CLASS_NONE)
+   return -EINVAL;
+
+   hdr = ptp_parse_header(skb, ptp_class);
+   if (!hdr)
+   return -EINVAL;
+
+   type = ptp_class & PTP_CLASS_PMASK;
+   if (type == PTP_CLASS_IPV4 || type == PTP_CLASS_IPV6)
+   *udp = 1;
+   else
+   *udp = 0;
+
+   *msgtype = ptp_get_msgtype(hdr, ptp_class);
+   *twostep = hdr->flag_field[0] & 0x2;
+
+   base = skb_mac_header(skb);
+   *correction_offset = (u8 *)&hdr->correction - base;
+   *body_offset = (u8 *)hdr + sizeof(struct ptp_header) - base;
+
+   return 0;
+}
+
 static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb)
 {
+   bool do_vlan, do_onestep_tstamp = false, do_twostep_tstamp = false;
+   struct enetc_ndev_priv *priv = netdev_priv(tx_ring->ndev);
+   struct enetc_hw *hw = &priv->si->hw;
struct enetc_tx_swbd *tx_swbd;
-   skb_frag_t *frag;
int len = skb_headlen(skb);
union enetc_tx_bd temp_bd;
+   u8 msgtype, twostep, udp;
union enetc_tx_bd *txbd;
-   bool do_vlan, do_tstamp;
+   u16 offset1, offset2;
int i, count = 0;
+   skb_frag_t *frag;
unsigned int f;
dma_addr_t dma;
u8 flags = 0;
@@ -69,12 +107,21 @@ static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, 
struct sk_buff *skb)
count++;
 
do_vlan = skb_vlan_tag_present(skb);
-   do_tstamp = (skb->cb[0] & ENETC_F_TX_TSTAMP) &&
-   (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP);
-   tx_swbd->do_tstamp = do_tstamp;
-   tx_swbd->check_wb = tx_swbd->do_tstamp;
+   if (skb->cb[0] & ENETC_F_TX_ONESTEP_SYNC_TSTAMP) {
+   if (enetc_ptp_parse(skb, &udp, &msgtype, &twostep, &offset1,
+   &offset2) ||
+   msgtype != PTP_MSGTYPE_SYNC || twostep)
+   WARN_ONCE(1, "Bad packet for one-step timestamping\n");
+   else
+   do_onestep_tstamp = true;
+   } else if (skb->cb[0] & ENETC_F_TX_TSTAMP) {
+   do_twostep_tstamp = true;
+   }
+
+   tx_swbd->do_twostep_tstamp = do_twostep_tstamp;
+   tx_swbd->check_wb = tx_swbd->do_twostep_tstamp;
 
-   if (do_vlan || do_tstamp)
+   if (do_vlan || do_onestep_tstamp || do_twostep_tstamp)
flags |= ENETC_TXBD_FLAGS_EX;
 
if (tx_ring->tsd_enable)
@@ -111,7 +158,38 @@ static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, 
struct sk_buff *skb)
e_flags |= ENETC_TXBD_E_FLAGS_VLAN_INS;
}
 
-   if (do_tstamp) {
+   if (do_onestep_tstamp) {
+   

[PATCH 1/2] enetc: mark TX timestamp type per skb

2021-03-26 Thread Yangbo Lu
Mark TX timestamp type per skb on skb->cb[0], instead of
global variable for all skbs. This is a preparation for
one step timestamp support.

For one-step timestamping enablement, there will be both
one-step and two-step PTP messages to transfer. And a skb
queue is needed for one-step PTP messages making sure
start to send current message only after the last one
completed on hardware. (ENETC single-step register has to
be dynamically configured per message.) So, marking TX
timestamp type per skb is required.

Signed-off-by: Yangbo Lu 
---
 drivers/net/ethernet/freescale/enetc/enetc.c | 10 ++
 drivers/net/ethernet/freescale/enetc/enetc.h | 11 +++
 2 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c 
b/drivers/net/ethernet/freescale/enetc/enetc.c
index 5a54976e6a28..61d684086432 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc.c
@@ -37,8 +37,7 @@ static void enetc_free_tx_skb(struct enetc_bdr *tx_ring,
}
 }
 
-static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb,
- int active_offloads)
+static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb)
 {
struct enetc_tx_swbd *tx_swbd;
skb_frag_t *frag;
@@ -70,7 +69,7 @@ static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, 
struct sk_buff *skb,
count++;
 
do_vlan = skb_vlan_tag_present(skb);
-   do_tstamp = (active_offloads & ENETC_F_TX_TSTAMP) &&
+   do_tstamp = (skb->cb[0] & ENETC_F_TX_TSTAMP) &&
(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP);
tx_swbd->do_tstamp = do_tstamp;
tx_swbd->check_wb = tx_swbd->do_tstamp;
@@ -189,6 +188,9 @@ netdev_tx_t enetc_xmit(struct sk_buff *skb, struct 
net_device *ndev)
struct enetc_bdr *tx_ring;
int count;
 
+   /* cb[0] used for TX timestamp type */
+   skb->cb[0] = priv->active_offloads & ENETC_F_TX_TSTAMP_MASK;
+
tx_ring = priv->tx_ring[skb->queue_mapping];
 
if (unlikely(skb_shinfo(skb)->nr_frags > ENETC_MAX_SKB_FRAGS))
@@ -202,7 +204,7 @@ netdev_tx_t enetc_xmit(struct sk_buff *skb, struct 
net_device *ndev)
}
 
enetc_lock_mdio();
-   count = enetc_map_tx_buffs(tx_ring, skb, priv->active_offloads);
+   count = enetc_map_tx_buffs(tx_ring, skb);
enetc_unlock_mdio();
 
if (unlikely(!count))
diff --git a/drivers/net/ethernet/freescale/enetc/enetc.h 
b/drivers/net/ethernet/freescale/enetc/enetc.h
index 773e412b9f4e..24d77768932b 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc.h
@@ -227,12 +227,15 @@ struct psfp_cap {
u32 max_psfp_meter;
 };
 
+#define ENETC_F_TX_TSTAMP_MASK 0xff
 /* TODO: more hardware offloads */
 enum enetc_active_offloads {
-   ENETC_F_RX_TSTAMP   = BIT(0),
-   ENETC_F_TX_TSTAMP   = BIT(1),
-   ENETC_F_QBV = BIT(2),
-   ENETC_F_QCI = BIT(3),
+   /* 8 bits reserved for TX timestamp types (hwtstamp_tx_types) */
+   ENETC_F_TX_TSTAMP   = BIT(0),
+
+   ENETC_F_RX_TSTAMP   = BIT(8),
+   ENETC_F_QBV = BIT(9),
+   ENETC_F_QCI = BIT(10),
 };
 
 /* interrupt coalescing modes */
-- 
2.25.1



[PATCH] ptp_qoriq: fix overflow in ptp_qoriq_adjfine() u64 calcalation

2021-03-23 Thread Yangbo Lu
Current calculation for diff of TMR_ADD register value may have
64-bit overflow in this code line, when long type scaled_ppm is
large.

adj *= scaled_ppm;

This patch is to resolve it by using mul_u64_u64_div_u64().

Signed-off-by: Yangbo Lu 
---
 drivers/ptp/ptp_qoriq.c | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/ptp/ptp_qoriq.c b/drivers/ptp/ptp_qoriq.c
index 68beb1bd07c0..f7f220700cb5 100644
--- a/drivers/ptp/ptp_qoriq.c
+++ b/drivers/ptp/ptp_qoriq.c
@@ -189,15 +189,16 @@ int ptp_qoriq_adjfine(struct ptp_clock_info *ptp, long 
scaled_ppm)
tmr_add = ptp_qoriq->tmr_add;
adj = tmr_add;
 
-   /* calculate diff as adj*(scaled_ppm/65536)/100
-* and round() to the nearest integer
+   /*
+* Calculate diff and round() to the nearest integer
+*
+* diff = adj * (ppb / 10)
+*  = adj * scaled_ppm / 6553600
 */
-   adj *= scaled_ppm;
-   diff = div_u64(adj, 800);
-   diff = (diff >> 13) + ((diff >> 12) & 1);
+   diff = mul_u64_u64_div_u64(adj, scaled_ppm, 3276800);
+   diff = DIV64_U64_ROUND_UP(diff, 2);
 
tmr_add = neg_adj ? tmr_add - diff : tmr_add + diff;
-
ptp_qoriq->write(®s->ctrl_regs->tmr_add, tmr_add);
 
return 0;
-- 
2.25.1



[PATCH] dpaa_eth: copy timestamp fields to new skb in A-050385 workaround

2020-11-30 Thread Yangbo Lu
The timestamp fields should be copied to new skb too in
A-050385 workaround for later TX timestamping handling.

Fixes: 3c68b8fffb48 ("dpaa_eth: FMan erratum A050385 workaround")
Signed-off-by: Yangbo Lu 
---
 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index d9c2859..cb7c028 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -2120,6 +2120,15 @@ static int dpaa_a050385_wa(struct net_device *net_dev, 
struct sk_buff **s)
skb_copy_header(new_skb, skb);
new_skb->dev = skb->dev;
 
+   /* Copy relevant timestamp info from the old skb to the new */
+   if (priv->tx_tstamp) {
+   skb_shinfo(new_skb)->tx_flags = skb_shinfo(skb)->tx_flags;
+   skb_shinfo(new_skb)->hwtstamps = skb_shinfo(skb)->hwtstamps;
+   skb_shinfo(new_skb)->tskey = skb_shinfo(skb)->tskey;
+   if (skb->sk)
+   skb_set_owner_w(new_skb, skb->sk);
+   }
+
/* We move the headroom when we align it so we have to reset the
 * network and transport header offsets relative to the new data
 * pointer. The checksum offload relies on these offsets.
@@ -2127,7 +2136,6 @@ static int dpaa_a050385_wa(struct net_device *net_dev, 
struct sk_buff **s)
skb_set_network_header(new_skb, skb_network_offset(skb));
skb_set_transport_header(new_skb, skb_transport_offset(skb));
 
-   /* TODO: does timestamping need the result in the old skb? */
dev_kfree_skb(skb);
*s = new_skb;
 
-- 
2.7.4



[PATCH] ptp: add stub function for ptp_get_msgtype()

2020-09-27 Thread Yangbo Lu
Added the missing stub function for ptp_get_msgtype().

Reported-by: Randy Dunlap 
Fixes: 036c508ba95e ("ptp: Add generic ptp message type function")
Signed-off-by: Yangbo Lu 
---
 include/linux/ptp_classify.h | 8 
 1 file changed, 8 insertions(+)

diff --git a/include/linux/ptp_classify.h b/include/linux/ptp_classify.h
index 8437307..c6487b7 100644
--- a/include/linux/ptp_classify.h
+++ b/include/linux/ptp_classify.h
@@ -134,5 +134,13 @@ static inline struct ptp_header *ptp_parse_header(struct 
sk_buff *skb,
 {
return NULL;
 }
+static inline u8 ptp_get_msgtype(const struct ptp_header *hdr,
+unsigned int type)
+{
+   /* The return is meaningless. The stub function would not be
+* executed since no available header from ptp_parse_header.
+*/
+   return 0;
+}
 #endif
 #endif /* _PTP_CLASSIFY_H_ */
-- 
2.7.4



[v2, 2/2] ptp_qoriq: support FIPER3

2020-09-18 Thread Yangbo Lu
The FIPER3 (fixed interval period pulse generator) is supported on
DPAA2 and ENETC network controller hardware. This patch is to support
it in ptp_qoriq driver.

Signed-off-by: Yangbo Lu 
Acked-by: Vladimir Oltean 
---
Changes for v2:
- Some improvement in code.
- Added ACK from Vladimir.
---
 drivers/ptp/ptp_qoriq.c   | 20 +++-
 include/linux/fsl/ptp_qoriq.h |  3 +++
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/drivers/ptp/ptp_qoriq.c b/drivers/ptp/ptp_qoriq.c
index c09c16be..beb5f74 100644
--- a/drivers/ptp/ptp_qoriq.c
+++ b/drivers/ptp/ptp_qoriq.c
@@ -72,6 +72,10 @@ static void set_fipers(struct ptp_qoriq *ptp_qoriq)
set_alarm(ptp_qoriq);
ptp_qoriq->write(®s->fiper_regs->tmr_fiper1, ptp_qoriq->tmr_fiper1);
ptp_qoriq->write(®s->fiper_regs->tmr_fiper2, ptp_qoriq->tmr_fiper2);
+
+   if (ptp_qoriq->fiper3_support)
+   ptp_qoriq->write(®s->fiper_regs->tmr_fiper3,
+ptp_qoriq->tmr_fiper3);
 }
 
 int extts_clean_up(struct ptp_qoriq *ptp_qoriq, int index, bool update_event)
@@ -366,6 +370,7 @@ static u32 ptp_qoriq_nominal_freq(u32 clk_src)
  *   "fsl,tmr-add"
  *   "fsl,tmr-fiper1"
  *   "fsl,tmr-fiper2"
+ *   "fsl,tmr-fiper3" (required only for DPAA2 and ENETC hardware)
  *   "fsl,max-adj"
  *
  * Return 0 if success
@@ -412,6 +417,7 @@ static int ptp_qoriq_auto_config(struct ptp_qoriq 
*ptp_qoriq,
ptp_qoriq->tmr_add = freq_comp;
ptp_qoriq->tmr_fiper1 = DEFAULT_FIPER1_PERIOD - ptp_qoriq->tclk_period;
ptp_qoriq->tmr_fiper2 = DEFAULT_FIPER2_PERIOD - ptp_qoriq->tclk_period;
+   ptp_qoriq->tmr_fiper3 = DEFAULT_FIPER3_PERIOD - ptp_qoriq->tclk_period;
 
/* max_adj = 10 * (freq_ratio - 1.0) - 1
 * freq_ratio = reference_clock_freq / nominal_freq
@@ -446,6 +452,10 @@ int ptp_qoriq_init(struct ptp_qoriq *ptp_qoriq, void 
__iomem *base,
else
ptp_qoriq->extts_fifo_support = false;
 
+   if (of_device_is_compatible(node, "fsl,dpaa2-ptp") ||
+   of_device_is_compatible(node, "fsl,enetc-ptp"))
+   ptp_qoriq->fiper3_support = true;
+
if (of_property_read_u32(node,
 "fsl,tclk-period", &ptp_qoriq->tclk_period) ||
of_property_read_u32(node,
@@ -457,7 +467,10 @@ int ptp_qoriq_init(struct ptp_qoriq *ptp_qoriq, void 
__iomem *base,
of_property_read_u32(node,
 "fsl,tmr-fiper2", &ptp_qoriq->tmr_fiper2) ||
of_property_read_u32(node,
-"fsl,max-adj", &ptp_qoriq->caps.max_adj)) {
+"fsl,max-adj", &ptp_qoriq->caps.max_adj) ||
+   (ptp_qoriq->fiper3_support &&
+of_property_read_u32(node, "fsl,tmr-fiper3",
+ &ptp_qoriq->tmr_fiper3))) {
pr_warn("device tree node missing required elements, try 
automatic configuration\n");
 
if (ptp_qoriq_auto_config(ptp_qoriq, node))
@@ -502,6 +515,11 @@ int ptp_qoriq_init(struct ptp_qoriq *ptp_qoriq, void 
__iomem *base,
ptp_qoriq->write(®s->ctrl_regs->tmr_prsc, ptp_qoriq->tmr_prsc);
ptp_qoriq->write(®s->fiper_regs->tmr_fiper1, ptp_qoriq->tmr_fiper1);
ptp_qoriq->write(®s->fiper_regs->tmr_fiper2, ptp_qoriq->tmr_fiper2);
+
+   if (ptp_qoriq->fiper3_support)
+   ptp_qoriq->write(®s->fiper_regs->tmr_fiper3,
+ptp_qoriq->tmr_fiper3);
+
set_alarm(ptp_qoriq);
ptp_qoriq->write(®s->ctrl_regs->tmr_ctrl,
 tmr_ctrl|FIPERST|RTPE|TE|FRD);
diff --git a/include/linux/fsl/ptp_qoriq.h b/include/linux/fsl/ptp_qoriq.h
index 884b8f8..01acebe 100644
--- a/include/linux/fsl/ptp_qoriq.h
+++ b/include/linux/fsl/ptp_qoriq.h
@@ -136,6 +136,7 @@ struct ptp_qoriq_registers {
 #define DEFAULT_TMR_PRSC   2
 #define DEFAULT_FIPER1_PERIOD  10
 #define DEFAULT_FIPER2_PERIOD  10
+#define DEFAULT_FIPER3_PERIOD  10
 
 struct ptp_qoriq {
void __iomem *base;
@@ -147,6 +148,7 @@ struct ptp_qoriq {
struct dentry *debugfs_root;
struct device *dev;
bool extts_fifo_support;
+   bool fiper3_support;
int irq;
int phc_index;
u32 tclk_period;  /* nanoseconds */
@@ -155,6 +157,7 @@ struct ptp_qoriq {
u32 cksel;
u32 tmr_fiper1;
u32 tmr_fiper2;
+   u32 tmr_fiper3;
u32 (*read)(unsigned __iomem *addr);
void (*write)(unsigned __iomem *addr, u32 val);
 };
-- 
2.7.4



[v2, 0/2] ptp_qoriq: support FIPER3

2020-09-18 Thread Yangbo Lu
The FIPER3 (fixed interval period pulse generator) is supported on
DPAA2 and ENETC network controller hardware. This patch-set is to
support it in ptp_qoriq driver and dt-binding.

Changes for v2:
- Some improvement in code.
- Added ACK from Vladimir.

Yangbo Lu (2):
  dt-binding: ptp_qoriq: support fsl,tmr-fiper3 property
  ptp_qoriq: support FIPER3

 Documentation/devicetree/bindings/ptp/ptp-qoriq.txt |  2 ++
 drivers/ptp/ptp_qoriq.c | 20 +++-
 include/linux/fsl/ptp_qoriq.h   |  3 +++
 3 files changed, 24 insertions(+), 1 deletion(-)

-- 
2.7.4



[v2, 1/2] dt-binding: ptp_qoriq: support fsl,tmr-fiper3 property

2020-09-18 Thread Yangbo Lu
Add fsl,tmr-fiper3 property definition which is supported only
on DPAA2 and ENETC network controller hardware.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
---
 Documentation/devicetree/bindings/ptp/ptp-qoriq.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/ptp/ptp-qoriq.txt 
b/Documentation/devicetree/bindings/ptp/ptp-qoriq.txt
index d48f9eb..743eda7 100644
--- a/Documentation/devicetree/bindings/ptp/ptp-qoriq.txt
+++ b/Documentation/devicetree/bindings/ptp/ptp-qoriq.txt
@@ -18,6 +18,8 @@ Clock Properties:
   - fsl,tmr-add  Frequency compensation value.
   - fsl,tmr-fiper1   Fixed interval period pulse generator.
   - fsl,tmr-fiper2   Fixed interval period pulse generator.
+  - fsl,tmr-fiper3   Fixed interval period pulse generator.
+ Supported only on DPAA2 and ENETC hardware.
   - fsl,max-adj  Maximum frequency adjustment in parts per billion.
   - fsl,extts-fifo   The presence of this property indicates hardware
 support for the external trigger stamp FIFO.
-- 
2.7.4



[v2] dpaa2-eth: fix a build warning in dpmac.c

2020-09-18 Thread Yangbo Lu
Fix below sparse warning in dpmac.c.
warning: cast to restricted __le64

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- Fixed in right way.
---
 drivers/net/ethernet/freescale/dpaa2/dpmac-cmd.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa2/dpmac-cmd.h 
b/drivers/net/ethernet/freescale/dpaa2/dpmac-cmd.h
index 3ea51dd..a24b20f 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpmac-cmd.h
+++ b/drivers/net/ethernet/freescale/dpaa2/dpmac-cmd.h
@@ -66,8 +66,8 @@ struct dpmac_cmd_get_counter {
 };
 
 struct dpmac_rsp_get_counter {
-   u64 pad;
-   u64 counter;
+   __le64 pad;
+   __le64 counter;
 };
 
 #endif /* _FSL_DPMAC_CMD_H */
-- 
2.7.4



[v4, 5/5] dpaa2-eth: support PTP Sync packet one-step timestamping

2020-09-18 Thread Yangbo Lu
This patch is to add PTP sync packet one-step timestamping support.
Before egress, one-step timestamping enablement needs,

- Enabling timestamp and FAS (Frame Annotation Status) in
  dpni buffer layout.

- Write timestamp to frame annotation and set PTP bit in
  FAS to mark as one-step timestamping event.

- Enabling one-step timestamping by dpni_set_single_step_cfg()
  API, with offset provided to insert correction time on frame.
  The offset must respect all MAC headers, VLAN tags and other
  protocol headers accordingly. The correction field update can
  consider delays up to one second. So PTP frame needs to be
  filtered and parsed, and written timestamp into Sync frame
  originTimestamp field.

The operation of API dpni_set_single_step_cfg() has to be done
when no one-step timestamping frames are in flight. So we have
to make sure the last one-step timestamping frame has already
been transmitted on hardware before starting to send the current
one. The resolution is,

- Utilize skb->cb[0] to mark timestamping request per packet.
  If it is one-step timestamping PTP sync packet, queue to skb queue.
  If not, transmit immediately.

- Schedule a work to transmit skbs in skb queue.

- mutex lock is used to ensure the last one-step timestamping packet
  has already been transmitted on hardware through TX confirmation queue
  before transmitting current packet.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
Changes for v3:
- Fixed build issue on 32-bit.
- Converted to use ptp_parse_header.
Changes for v4:
- Used WARN_ONCE instead of netdev_err in data path.
- Enabled timestamping only when PTP driver is ready.
- Added comments in using onestep_tstamp_lock.
---
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c   | 186 +++--
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h   |  32 +++-
 .../net/ethernet/freescale/dpaa2/dpaa2-ethtool.c   |   7 +-
 3 files changed, 209 insertions(+), 16 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c 
b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index eab9470..b6cdf84 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -563,11 +564,57 @@ static int dpaa2_eth_consume_frames(struct 
dpaa2_eth_channel *ch,
return cleaned;
 }
 
+static int dpaa2_eth_ptp_parse(struct sk_buff *skb,
+  u8 *msgtype, u8 *twostep, u8 *udp,
+  u16 *correction_offset,
+  u16 *origintimestamp_offset)
+{
+   unsigned int ptp_class;
+   struct ptp_header *hdr;
+   unsigned int type;
+   u8 *base;
+
+   ptp_class = ptp_classify_raw(skb);
+   if (ptp_class == PTP_CLASS_NONE)
+   return -EINVAL;
+
+   hdr = ptp_parse_header(skb, ptp_class);
+   if (!hdr)
+   return -EINVAL;
+
+   *msgtype = ptp_get_msgtype(hdr, ptp_class);
+   *twostep = hdr->flag_field[0] & 0x2;
+
+   type = ptp_class & PTP_CLASS_PMASK;
+   if (type == PTP_CLASS_IPV4 ||
+   type == PTP_CLASS_IPV6)
+   *udp = 1;
+   else
+   *udp = 0;
+
+   base = skb_mac_header(skb);
+   *correction_offset = (u8 *)&hdr->correction - base;
+   *origintimestamp_offset = (u8 *)hdr + sizeof(struct ptp_header) - base;
+
+   return 0;
+}
+
 /* Configure the egress frame annotation for timestamp update */
-static void dpaa2_eth_enable_tx_tstamp(struct dpaa2_fd *fd, void *buf_start)
+static void dpaa2_eth_enable_tx_tstamp(struct dpaa2_eth_priv *priv,
+  struct dpaa2_fd *fd,
+  void *buf_start,
+  struct sk_buff *skb)
 {
+   struct ptp_tstamp origin_timestamp;
+   struct dpni_single_step_cfg cfg;
+   u8 msgtype, twostep, udp;
struct dpaa2_faead *faead;
+   struct dpaa2_fas *fas;
+   struct timespec64 ts;
+   u16 offset1, offset2;
u32 ctrl, frc;
+   __le64 *ns;
+   u8 *data;
 
/* Mark the egress frame annotation area as valid */
frc = dpaa2_fd_get_frc(fd);
@@ -583,6 +630,45 @@ static void dpaa2_eth_enable_tx_tstamp(struct dpaa2_fd 
*fd, void *buf_start)
ctrl = DPAA2_FAEAD_A2V | DPAA2_FAEAD_UPDV | DPAA2_FAEAD_UPD;
faead = dpaa2_get_faead(buf_start, true);
faead->ctrl = cpu_to_le32(ctrl);
+
+   if (skb->cb[0] == TX_TSTAMP_ONESTEP_SYNC) {
+   if (dpaa2_eth_ptp_parse(skb, &msgtype, &twostep, &udp,
+   &offset1, &offset2) ||
+   msgtype != 0 || twostep) {
+   WARN_ONCE(1, "Bad packet for one-step timestamping\n");
+   return;
+   }
+
+  

[v4, 1/5] dpaa2-eth: add APIs of 1588 single step timestamping

2020-09-18 Thread Yangbo Lu
This patch is to add APIs of 1588 single step timestamping.

- dpni_set_single_step_cfg
- dpni_get_single_step_cfg

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
Changes for v3:
- Fixed sparse warnings.
Changes for v4:
- None.
---
 drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h | 21 +++
 drivers/net/ethernet/freescale/dpaa2/dpni.c | 79 +
 drivers/net/ethernet/freescale/dpaa2/dpni.h | 31 ++
 3 files changed, 131 insertions(+)

diff --git a/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h 
b/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h
index 593e381..1222a4e 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h
+++ b/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
 /* Copyright 2013-2016 Freescale Semiconductor Inc.
  * Copyright 2016 NXP
+ * Copyright 2020 NXP
  */
 #ifndef _FSL_DPNI_CMD_H
 #define _FSL_DPNI_CMD_H
@@ -90,6 +91,9 @@
 #define DPNI_CMDID_SET_RX_HASH_DISTDPNI_CMD(0x274)
 #define DPNI_CMDID_GET_LINK_CFGDPNI_CMD(0x278)
 
+#define DPNI_CMDID_SET_SINGLE_STEP_CFG DPNI_CMD(0x279)
+#define DPNI_CMDID_GET_SINGLE_STEP_CFG DPNI_CMD(0x27a)
+
 /* Macros for accessing command fields smaller than 1byte */
 #define DPNI_MASK(field)   \
GENMASK(DPNI_##field##_SHIFT + DPNI_##field##_SIZE - 1, \
@@ -639,4 +643,21 @@ struct dpni_cmd_set_tx_shaping {
u8 coupled;
 };
 
+#define DPNI_PTP_ENABLE_SHIFT  0
+#define DPNI_PTP_ENABLE_SIZE   1
+#define DPNI_PTP_CH_UPDATE_SHIFT   1
+#define DPNI_PTP_CH_UPDATE_SIZE1
+
+struct dpni_cmd_single_step_cfg {
+   __le16 flags;
+   __le16 offset;
+   __le32 peer_delay;
+};
+
+struct dpni_rsp_single_step_cfg {
+   __le16 flags;
+   __le16 offset;
+   __le32 peer_delay;
+};
+
 #endif /* _FSL_DPNI_CMD_H */
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpni.c 
b/drivers/net/ethernet/freescale/dpaa2/dpni.c
index 68ed4c4..6ea7db66 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpni.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpni.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /* Copyright 2013-2016 Freescale Semiconductor Inc.
  * Copyright 2016 NXP
+ * Copyright 2020 NXP
  */
 #include 
 #include 
@@ -1999,3 +2000,81 @@ int dpni_set_tx_shaping(struct fsl_mc_io *mc_io,
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
 }
+
+/**
+ * dpni_get_single_step_cfg() - return current configuration for
+ *  single step PTP
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @ptp_cfg:   ptp single step configuration
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ */
+int dpni_get_single_step_cfg(struct fsl_mc_io *mc_io,
+u32 cmd_flags,
+u16 token,
+struct dpni_single_step_cfg *ptp_cfg)
+{
+   struct dpni_rsp_single_step_cfg *rsp_params;
+   struct fsl_mc_command cmd = { 0 };
+   int err;
+
+   /* prepare command */
+   cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_SINGLE_STEP_CFG,
+ cmd_flags, token);
+   /* send command to mc*/
+   err =  mc_send_command(mc_io, &cmd);
+   if (err)
+   return err;
+
+   /* read command response */
+   rsp_params = (struct dpni_rsp_single_step_cfg *)cmd.params;
+   ptp_cfg->offset = le16_to_cpu(rsp_params->offset);
+   ptp_cfg->en = dpni_get_field(le16_to_cpu(rsp_params->flags),
+PTP_ENABLE) ? 1 : 0;
+   ptp_cfg->ch_update = dpni_get_field(le16_to_cpu(rsp_params->flags),
+   PTP_CH_UPDATE) ? 1 : 0;
+   ptp_cfg->peer_delay = le32_to_cpu(rsp_params->peer_delay);
+
+   return err;
+}
+
+/**
+ * dpni_set_single_step_cfg() - enable/disable and configure single step PTP
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @ptp_cfg:   ptp single step configuration
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ * The function has effect only when dpni object is connected to a dpmac
+ * object. If the dpni is not connected to a dpmac the configuration will
+ * be stored inside and applied when connection is made.
+ */
+int dpni_set_single_step_cfg(struct fsl_mc_io *mc_io,
+u32 cmd_flags,
+u16 token,
+struct dpni_single_step_cfg *ptp_cfg)
+{
+   struct dpni_cmd_single_

[v4, 4/5] dpaa2-eth: utilize skb->cb[0] for hardware timestamping

2020-09-18 Thread Yangbo Lu
This patch is a preparation for next hardware one-step timestamping
support. For DPAA2, the one step timestamping configuration on
hardware registers has to be done when there is no one-step timestamping
packet in flight. So we will have to use workqueue and skb queue
for such packets transmitting, to make sure waiting the last packet has
already been sent on hardware, and starting to transmit the current one.

So the tx timestamping flag in private data may not reflect the actual
request for the one-step timestamping packets of skb queue. This also
affects skb headroom allocation. Let's use skb->cb[0] to mark the
timestamping request for each skb.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- Removed unused variable priv in dpaa2_eth_xdp_create_fd().
Changes for v3:
- None.
Changes for v4:
- None.
---
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 26 +++-
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 13 ++--
 2 files changed, 23 insertions(+), 16 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c 
b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index a8c311fb..eab9470 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -11,7 +11,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -780,7 +779,7 @@ static int dpaa2_eth_build_single_fd(struct dpaa2_eth_priv 
*priv,
struct dpaa2_eth_swa *swa;
dma_addr_t addr;
 
-   buffer_start = skb->data - dpaa2_eth_needed_headroom(priv, skb);
+   buffer_start = skb->data - dpaa2_eth_needed_headroom(skb);
 
/* If there's enough room to align the FD address, do it.
 * It will help hardware optimize accesses.
@@ -894,7 +893,7 @@ static void dpaa2_eth_free_tx_fd(const struct 
dpaa2_eth_priv *priv,
}
 
/* Get the timestamp value */
-   if (priv->tx_tstamp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) {
+   if (skb->cb[0] == TX_TSTAMP) {
struct skb_shared_hwtstamps shhwtstamps;
__le64 *ts = dpaa2_get_ts(buffer_start, true);
u64 ns;
@@ -938,10 +937,17 @@ static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, 
struct net_device *net_dev)
int err, i;
void *swa;
 
+   /* Utilize skb->cb[0] for timestamping request per skb */
+   skb->cb[0] = 0;
+
+   if (priv->tx_tstamp_type == HWTSTAMP_TX_ON &&
+   skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
+   skb->cb[0] = TX_TSTAMP;
+
percpu_stats = this_cpu_ptr(priv->percpu_stats);
percpu_extras = this_cpu_ptr(priv->percpu_extras);
 
-   needed_headroom = dpaa2_eth_needed_headroom(priv, skb);
+   needed_headroom = dpaa2_eth_needed_headroom(skb);
 
/* We'll be holding a back-reference to the skb until Tx Confirmation;
 * we don't want that overwritten by a concurrent Tx with a cloned skb.
@@ -975,7 +981,7 @@ static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, struct 
net_device *net_dev)
goto err_build_fd;
}
 
-   if (priv->tx_tstamp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
+   if (skb->cb[0] == TX_TSTAMP)
dpaa2_eth_enable_tx_tstamp(&fd, swa);
 
/* Tracing point */
@@ -1899,10 +1905,8 @@ static int dpaa2_eth_ts_ioctl(struct net_device *dev, 
struct ifreq *rq, int cmd)
 
switch (config.tx_type) {
case HWTSTAMP_TX_OFF:
-   priv->tx_tstamp = false;
-   break;
case HWTSTAMP_TX_ON:
-   priv->tx_tstamp = true;
+   priv->tx_tstamp_type = config.tx_type;
break;
default:
return -ERANGE;
@@ -2097,7 +2101,6 @@ static int dpaa2_eth_xdp_create_fd(struct net_device 
*net_dev,
   struct xdp_frame *xdpf,
   struct dpaa2_fd *fd)
 {
-   struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
struct device *dev = net_dev->dev.parent;
unsigned int needed_headroom;
struct dpaa2_eth_swa *swa;
@@ -2107,7 +2110,7 @@ static int dpaa2_eth_xdp_create_fd(struct net_device 
*net_dev,
/* We require a minimum headroom to be able to transmit the frame.
 * Otherwise return an error and let the original net_device handle it
 */
-   needed_headroom = dpaa2_eth_needed_headroom(priv, NULL);
+   needed_headroom = dpaa2_eth_needed_headroom(NULL);
if (xdpf->headroom < needed_headroom)
return -EINVAL;
 
@@ -3963,6 +3966,9 @@ static int dpaa2_eth_probe(struct fsl_mc_device *dpni_dev)
 
priv->iommu_domain = iommu_get_domain_for_dev(dev);
 
+   priv->tx_tstamp_type = HWTSTAMP_TX_OFF;
+   priv->rx_tstamp = false;
+
/* Obtain a 

[v4, 2/5] dpaa2-eth: define a global ptp_qoriq structure pointer

2020-09-18 Thread Yangbo Lu
Define a global ptp_qoriq structure pointer, and export to use.
The ptp clock operations will be used in dpaa2-eth driver.
For example, supporting one step timestamping needs to write
current time to hardware frame annotation before sending and
then hardware inserts the delay time on frame during sending.
So in driver, at least clock gettime operation will be needed
to make sure right time is written to hardware frame annotation
for one step timestamping.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
Changes for v3:
- Fixed sparse warning.
Changes for v4:
- None.
---
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 4 
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 1 +
 drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c | 3 ++-
 drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.h | 4 
 4 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c 
b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index ceaf761..daf8fd4 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -30,6 +31,9 @@ MODULE_LICENSE("Dual BSD/GPL");
 MODULE_AUTHOR("Freescale Semiconductor, Inc");
 MODULE_DESCRIPTION("Freescale DPAA2 Ethernet Driver");
 
+struct ptp_qoriq *dpaa2_ptp;
+EXPORT_SYMBOL(dpaa2_ptp);
+
 static void *dpaa2_iova_to_virt(struct iommu_domain *domain,
dma_addr_t iova_addr)
 {
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h 
b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
index 7f3c41d..7be684b 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
@@ -491,6 +491,7 @@ struct dpaa2_eth_priv {
 
 extern const struct ethtool_ops dpaa2_ethtool_ops;
 extern int dpaa2_phc_index;
+extern struct ptp_qoriq *dpaa2_ptp;
 
 static inline int dpaa2_eth_cmp_dpni_ver(struct dpaa2_eth_priv *priv,
 u16 ver_major, u16 ver_minor)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c 
b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c
index cc1b7f8..32b5faa 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c
@@ -2,6 +2,7 @@
 /*
  * Copyright 2013-2016 Freescale Semiconductor Inc.
  * Copyright 2016-2018 NXP
+ * Copyright 2020 NXP
  */
 
 #include 
@@ -9,7 +10,6 @@
 #include 
 #include 
 #include 
-#include 
 
 #include "dpaa2-ptp.h"
 
@@ -201,6 +201,7 @@ static int dpaa2_ptp_probe(struct fsl_mc_device *mc_dev)
goto err_free_threaded_irq;
 
dpaa2_phc_index = ptp_qoriq->phc_index;
+   dpaa2_ptp = ptp_qoriq;
dev_set_drvdata(dev, ptp_qoriq);
 
return 0;
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.h 
b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.h
index df2458a..e102353 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.h
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.h
@@ -1,14 +1,18 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright 2018 NXP
+ * Copyright 2020 NXP
  */
 
 #ifndef __RTC_H
 #define __RTC_H
 
+#include 
+
 #include "dprtc.h"
 #include "dprtc-cmd.h"
 
 extern int dpaa2_phc_index;
+extern struct ptp_qoriq *dpaa2_ptp;
 
 #endif
-- 
2.7.4



[v4, 3/5] dpaa2-eth: invoke dpaa2_eth_enable_tx_tstamp() once in code

2020-09-18 Thread Yangbo Lu
Invoke dpaa2_eth_enable_tx_tstamp() once in code after building FD,
rather than calling it in dpaa2_eth_build_single_fd(),
dpaa2_eth_build_sg_fd_single_buf(), and dpaa2_eth_build_sg_fd().

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
Changes for v3:
- None.
Changes for v4:
- None.
---
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 31 
 1 file changed, 16 insertions(+), 15 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c 
b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index daf8fd4..a8c311fb 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -589,7 +589,8 @@ static void dpaa2_eth_enable_tx_tstamp(struct dpaa2_fd *fd, 
void *buf_start)
 /* Create a frame descriptor based on a fragmented skb */
 static int dpaa2_eth_build_sg_fd(struct dpaa2_eth_priv *priv,
 struct sk_buff *skb,
-struct dpaa2_fd *fd)
+struct dpaa2_fd *fd,
+void **swa_addr)
 {
struct device *dev = priv->net_dev->dev.parent;
void *sgt_buf = NULL;
@@ -658,6 +659,7 @@ static int dpaa2_eth_build_sg_fd(struct dpaa2_eth_priv 
*priv,
 * skb backpointer in the software annotation area. We'll need
 * all of them on Tx Conf.
 */
+   *swa_addr = (void *)sgt_buf;
swa = (struct dpaa2_eth_swa *)sgt_buf;
swa->type = DPAA2_ETH_SWA_SG;
swa->sg.skb = skb;
@@ -677,9 +679,6 @@ static int dpaa2_eth_build_sg_fd(struct dpaa2_eth_priv 
*priv,
dpaa2_fd_set_len(fd, skb->len);
dpaa2_fd_set_ctrl(fd, FD_CTRL_PTA);
 
-   if (priv->tx_tstamp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
-   dpaa2_eth_enable_tx_tstamp(fd, sgt_buf);
-
return 0;
 
 dma_map_single_failed:
@@ -699,7 +698,8 @@ static int dpaa2_eth_build_sg_fd(struct dpaa2_eth_priv 
*priv,
  */
 static int dpaa2_eth_build_sg_fd_single_buf(struct dpaa2_eth_priv *priv,
struct sk_buff *skb,
-   struct dpaa2_fd *fd)
+   struct dpaa2_fd *fd,
+   void **swa_addr)
 {
struct device *dev = priv->net_dev->dev.parent;
struct dpaa2_eth_sgt_cache *sgt_cache;
@@ -737,6 +737,7 @@ static int dpaa2_eth_build_sg_fd_single_buf(struct 
dpaa2_eth_priv *priv,
dpaa2_sg_set_final(sgt, true);
 
/* Store the skb backpointer in the SGT buffer */
+   *swa_addr = (void *)sgt_buf;
swa = (struct dpaa2_eth_swa *)sgt_buf;
swa->type = DPAA2_ETH_SWA_SINGLE;
swa->single.skb = skb;
@@ -755,9 +756,6 @@ static int dpaa2_eth_build_sg_fd_single_buf(struct 
dpaa2_eth_priv *priv,
dpaa2_fd_set_len(fd, skb->len);
dpaa2_fd_set_ctrl(fd, FD_CTRL_PTA);
 
-   if (priv->tx_tstamp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
-   dpaa2_eth_enable_tx_tstamp(fd, sgt_buf);
-
return 0;
 
 sgt_map_failed:
@@ -774,7 +772,8 @@ static int dpaa2_eth_build_sg_fd_single_buf(struct 
dpaa2_eth_priv *priv,
 /* Create a frame descriptor based on a linear skb */
 static int dpaa2_eth_build_single_fd(struct dpaa2_eth_priv *priv,
 struct sk_buff *skb,
-struct dpaa2_fd *fd)
+struct dpaa2_fd *fd,
+void **swa_addr)
 {
struct device *dev = priv->net_dev->dev.parent;
u8 *buffer_start, *aligned_start;
@@ -795,6 +794,7 @@ static int dpaa2_eth_build_single_fd(struct dpaa2_eth_priv 
*priv,
 * (in the private data area) such that we can release it
 * on Tx confirm
 */
+   *swa_addr = (void *)buffer_start;
swa = (struct dpaa2_eth_swa *)buffer_start;
swa->type = DPAA2_ETH_SWA_SINGLE;
swa->single.skb = skb;
@@ -811,9 +811,6 @@ static int dpaa2_eth_build_single_fd(struct dpaa2_eth_priv 
*priv,
dpaa2_fd_set_format(fd, dpaa2_fd_single);
dpaa2_fd_set_ctrl(fd, FD_CTRL_PTA);
 
-   if (priv->tx_tstamp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
-   dpaa2_eth_enable_tx_tstamp(fd, buffer_start);
-
return 0;
 }
 
@@ -939,6 +936,7 @@ static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, struct 
net_device *net_dev)
u32 fd_len;
u8 prio = 0;
int err, i;
+   void *swa;
 
percpu_stats = this_cpu_ptr(priv->percpu_stats);
percpu_extras = this_cpu_ptr(priv->percpu_extras);
@@ -959,17 +957,17 @@ static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, 
struct net_device *net_dev)
memset(&fd, 0, sizeof(fd));
 
if (skb_is_nonlinear(skb)) {
-   

[v4, 0/5] dpaa2_eth: support 1588 one-step timestamping

2020-09-18 Thread Yangbo Lu
This patch-set is to add MC APIs of 1588 one-step timestamping, and
support one-step timestamping for PTP Sync packet on DPAA2.

Before egress, one-step timestamping enablement needs,

- Enabling timestamp and FAS (Frame Annotation Status) in
  dpni buffer layout.

- Write timestamp to frame annotation and set PTP bit in
  FAS to mark as one-step timestamping event.

- Enabling one-step timestamping by dpni_set_single_step_cfg()
  API, with offset provided to insert correction time on frame.
  The offset must respect all MAC headers, VLAN tags and other
  protocol headers accordingly. The correction field update can
  consider delays up to one second. So PTP frame needs to be
  filtered and parsed, and written timestamp into Sync frame
  originTimestamp field.

The operation of API dpni_set_single_step_cfg() has to be done
when no one-step timestamping frames are in flight. So we have
to make sure the last one-step timestamping frame has already
been transmitted on hardware before starting to send the current
one. The resolution is,

- Utilize skb->cb[0] to mark timestamping request per packet.
  If it is one-step timestamping PTP sync packet, queue to skb queue.
  If not, transmit immediately.

- Schedule a work to transmit skbs in skb queue.

- mutex lock is used to ensure the last one-step timestamping packet
  has already been transmitted on hardware through TX confirmation queue
  before transmitting current packet.

Changes for v2:
- Removed unused variable priv in dpaa2_eth_xdp_create_fd().
Changes for v3:
- Fixed sparse warnings.
- Fix build issue on 32-bit.
- Converted to use ptp_parse_header.
Changes for v4:
- Used WARN_ONCE instead of netdev_err in data path.
- Enabled timestamping only when PTP driver is ready.
- Added comments in using onestep_tstamp_lock.
- Dropped dpmac.c sparse warning fix-up patch.

Yangbo Lu (5):
  dpaa2-eth: add APIs of 1588 single step timestamping
  dpaa2-eth: define a global ptp_qoriq structure pointer
  dpaa2-eth: invoke dpaa2_eth_enable_tx_tstamp() once in code
  dpaa2-eth: utilize skb->cb[0] for hardware timestamping
  dpaa2-eth: support PTP Sync packet one-step timestamping

 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c   | 227 ++---
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h   |  44 +++-
 .../net/ethernet/freescale/dpaa2/dpaa2-ethtool.c   |   7 +-
 drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c   |   3 +-
 drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.h   |   4 +
 drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h|  21 ++
 drivers/net/ethernet/freescale/dpaa2/dpni.c|  79 +++
 drivers/net/ethernet/freescale/dpaa2/dpni.h|  31 +++
 8 files changed, 379 insertions(+), 37 deletions(-)

-- 
2.7.4



[v3, 2/6] dpaa2-eth: define a global ptp_qoriq structure pointer

2020-09-16 Thread Yangbo Lu
Define a global ptp_qoriq structure pointer, and export to use.
The ptp clock operations will be used in dpaa2-eth driver.
For example, supporting one step timestamping needs to write
current time to hardware frame annotation before sending and
then hardware inserts the delay time on frame during sending.
So in driver, at least clock gettime operation will be needed
to make sure right time is written to hardware frame annotation
for one step timestamping.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
Changes for v3:
- Fixed sparse warning.
---
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 4 
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 1 +
 drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c | 3 ++-
 drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.h | 4 
 4 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c 
b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index ceaf761..daf8fd4 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -30,6 +31,9 @@ MODULE_LICENSE("Dual BSD/GPL");
 MODULE_AUTHOR("Freescale Semiconductor, Inc");
 MODULE_DESCRIPTION("Freescale DPAA2 Ethernet Driver");
 
+struct ptp_qoriq *dpaa2_ptp;
+EXPORT_SYMBOL(dpaa2_ptp);
+
 static void *dpaa2_iova_to_virt(struct iommu_domain *domain,
dma_addr_t iova_addr)
 {
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h 
b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
index 7f3c41d..7be684b 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
@@ -491,6 +491,7 @@ struct dpaa2_eth_priv {
 
 extern const struct ethtool_ops dpaa2_ethtool_ops;
 extern int dpaa2_phc_index;
+extern struct ptp_qoriq *dpaa2_ptp;
 
 static inline int dpaa2_eth_cmp_dpni_ver(struct dpaa2_eth_priv *priv,
 u16 ver_major, u16 ver_minor)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c 
b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c
index cc1b7f8..32b5faa 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c
@@ -2,6 +2,7 @@
 /*
  * Copyright 2013-2016 Freescale Semiconductor Inc.
  * Copyright 2016-2018 NXP
+ * Copyright 2020 NXP
  */
 
 #include 
@@ -9,7 +10,6 @@
 #include 
 #include 
 #include 
-#include 
 
 #include "dpaa2-ptp.h"
 
@@ -201,6 +201,7 @@ static int dpaa2_ptp_probe(struct fsl_mc_device *mc_dev)
goto err_free_threaded_irq;
 
dpaa2_phc_index = ptp_qoriq->phc_index;
+   dpaa2_ptp = ptp_qoriq;
dev_set_drvdata(dev, ptp_qoriq);
 
return 0;
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.h 
b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.h
index df2458a..e102353 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.h
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.h
@@ -1,14 +1,18 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright 2018 NXP
+ * Copyright 2020 NXP
  */
 
 #ifndef __RTC_H
 #define __RTC_H
 
+#include 
+
 #include "dprtc.h"
 #include "dprtc-cmd.h"
 
 extern int dpaa2_phc_index;
+extern struct ptp_qoriq *dpaa2_ptp;
 
 #endif
-- 
2.7.4



[v3, 3/6] dpaa2-eth: invoke dpaa2_eth_enable_tx_tstamp() once in code

2020-09-16 Thread Yangbo Lu
Invoke dpaa2_eth_enable_tx_tstamp() once in code after building FD,
rather than calling it in dpaa2_eth_build_single_fd(),
dpaa2_eth_build_sg_fd_single_buf(), and dpaa2_eth_build_sg_fd().

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
Changes for v3:
- None.
---
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 31 
 1 file changed, 16 insertions(+), 15 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c 
b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index daf8fd4..a8c311fb 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -589,7 +589,8 @@ static void dpaa2_eth_enable_tx_tstamp(struct dpaa2_fd *fd, 
void *buf_start)
 /* Create a frame descriptor based on a fragmented skb */
 static int dpaa2_eth_build_sg_fd(struct dpaa2_eth_priv *priv,
 struct sk_buff *skb,
-struct dpaa2_fd *fd)
+struct dpaa2_fd *fd,
+void **swa_addr)
 {
struct device *dev = priv->net_dev->dev.parent;
void *sgt_buf = NULL;
@@ -658,6 +659,7 @@ static int dpaa2_eth_build_sg_fd(struct dpaa2_eth_priv 
*priv,
 * skb backpointer in the software annotation area. We'll need
 * all of them on Tx Conf.
 */
+   *swa_addr = (void *)sgt_buf;
swa = (struct dpaa2_eth_swa *)sgt_buf;
swa->type = DPAA2_ETH_SWA_SG;
swa->sg.skb = skb;
@@ -677,9 +679,6 @@ static int dpaa2_eth_build_sg_fd(struct dpaa2_eth_priv 
*priv,
dpaa2_fd_set_len(fd, skb->len);
dpaa2_fd_set_ctrl(fd, FD_CTRL_PTA);
 
-   if (priv->tx_tstamp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
-   dpaa2_eth_enable_tx_tstamp(fd, sgt_buf);
-
return 0;
 
 dma_map_single_failed:
@@ -699,7 +698,8 @@ static int dpaa2_eth_build_sg_fd(struct dpaa2_eth_priv 
*priv,
  */
 static int dpaa2_eth_build_sg_fd_single_buf(struct dpaa2_eth_priv *priv,
struct sk_buff *skb,
-   struct dpaa2_fd *fd)
+   struct dpaa2_fd *fd,
+   void **swa_addr)
 {
struct device *dev = priv->net_dev->dev.parent;
struct dpaa2_eth_sgt_cache *sgt_cache;
@@ -737,6 +737,7 @@ static int dpaa2_eth_build_sg_fd_single_buf(struct 
dpaa2_eth_priv *priv,
dpaa2_sg_set_final(sgt, true);
 
/* Store the skb backpointer in the SGT buffer */
+   *swa_addr = (void *)sgt_buf;
swa = (struct dpaa2_eth_swa *)sgt_buf;
swa->type = DPAA2_ETH_SWA_SINGLE;
swa->single.skb = skb;
@@ -755,9 +756,6 @@ static int dpaa2_eth_build_sg_fd_single_buf(struct 
dpaa2_eth_priv *priv,
dpaa2_fd_set_len(fd, skb->len);
dpaa2_fd_set_ctrl(fd, FD_CTRL_PTA);
 
-   if (priv->tx_tstamp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
-   dpaa2_eth_enable_tx_tstamp(fd, sgt_buf);
-
return 0;
 
 sgt_map_failed:
@@ -774,7 +772,8 @@ static int dpaa2_eth_build_sg_fd_single_buf(struct 
dpaa2_eth_priv *priv,
 /* Create a frame descriptor based on a linear skb */
 static int dpaa2_eth_build_single_fd(struct dpaa2_eth_priv *priv,
 struct sk_buff *skb,
-struct dpaa2_fd *fd)
+struct dpaa2_fd *fd,
+void **swa_addr)
 {
struct device *dev = priv->net_dev->dev.parent;
u8 *buffer_start, *aligned_start;
@@ -795,6 +794,7 @@ static int dpaa2_eth_build_single_fd(struct dpaa2_eth_priv 
*priv,
 * (in the private data area) such that we can release it
 * on Tx confirm
 */
+   *swa_addr = (void *)buffer_start;
swa = (struct dpaa2_eth_swa *)buffer_start;
swa->type = DPAA2_ETH_SWA_SINGLE;
swa->single.skb = skb;
@@ -811,9 +811,6 @@ static int dpaa2_eth_build_single_fd(struct dpaa2_eth_priv 
*priv,
dpaa2_fd_set_format(fd, dpaa2_fd_single);
dpaa2_fd_set_ctrl(fd, FD_CTRL_PTA);
 
-   if (priv->tx_tstamp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
-   dpaa2_eth_enable_tx_tstamp(fd, buffer_start);
-
return 0;
 }
 
@@ -939,6 +936,7 @@ static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, struct 
net_device *net_dev)
u32 fd_len;
u8 prio = 0;
int err, i;
+   void *swa;
 
percpu_stats = this_cpu_ptr(priv->percpu_stats);
percpu_extras = this_cpu_ptr(priv->percpu_extras);
@@ -959,17 +957,17 @@ static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, 
struct net_device *net_dev)
memset(&fd, 0, sizeof(fd));
 
if (skb_is_nonlinear(skb)) {
- 

[v3, 4/6] dpaa2-eth: utilize skb->cb[0] for hardware timestamping

2020-09-16 Thread Yangbo Lu
This patch is a preparation for next hardware one-step timestamping
support. For DPAA2, the one step timestamping configuration on
hardware registers has to be done when there is no one-step timestamping
packet in flight. So we will have to use workqueue and skb queue
for such packets transmitting, to make sure waiting the last packet has
already been sent on hardware, and starting to transmit the current one.

So the tx timestamping flag in private data may not reflect the actual
request for the one-step timestamping packets of skb queue. This also
affects skb headroom allocation. Let's use skb->cb[0] to mark the
timestamping request for each skb.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- Removed unused variable priv in dpaa2_eth_xdp_create_fd().
Changes for v3:
- None.
---
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 26 +++-
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 13 ++--
 2 files changed, 23 insertions(+), 16 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c 
b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index a8c311fb..eab9470 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -11,7 +11,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -780,7 +779,7 @@ static int dpaa2_eth_build_single_fd(struct dpaa2_eth_priv 
*priv,
struct dpaa2_eth_swa *swa;
dma_addr_t addr;
 
-   buffer_start = skb->data - dpaa2_eth_needed_headroom(priv, skb);
+   buffer_start = skb->data - dpaa2_eth_needed_headroom(skb);
 
/* If there's enough room to align the FD address, do it.
 * It will help hardware optimize accesses.
@@ -894,7 +893,7 @@ static void dpaa2_eth_free_tx_fd(const struct 
dpaa2_eth_priv *priv,
}
 
/* Get the timestamp value */
-   if (priv->tx_tstamp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) {
+   if (skb->cb[0] == TX_TSTAMP) {
struct skb_shared_hwtstamps shhwtstamps;
__le64 *ts = dpaa2_get_ts(buffer_start, true);
u64 ns;
@@ -938,10 +937,17 @@ static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, 
struct net_device *net_dev)
int err, i;
void *swa;
 
+   /* Utilize skb->cb[0] for timestamping request per skb */
+   skb->cb[0] = 0;
+
+   if (priv->tx_tstamp_type == HWTSTAMP_TX_ON &&
+   skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
+   skb->cb[0] = TX_TSTAMP;
+
percpu_stats = this_cpu_ptr(priv->percpu_stats);
percpu_extras = this_cpu_ptr(priv->percpu_extras);
 
-   needed_headroom = dpaa2_eth_needed_headroom(priv, skb);
+   needed_headroom = dpaa2_eth_needed_headroom(skb);
 
/* We'll be holding a back-reference to the skb until Tx Confirmation;
 * we don't want that overwritten by a concurrent Tx with a cloned skb.
@@ -975,7 +981,7 @@ static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, struct 
net_device *net_dev)
goto err_build_fd;
}
 
-   if (priv->tx_tstamp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
+   if (skb->cb[0] == TX_TSTAMP)
dpaa2_eth_enable_tx_tstamp(&fd, swa);
 
/* Tracing point */
@@ -1899,10 +1905,8 @@ static int dpaa2_eth_ts_ioctl(struct net_device *dev, 
struct ifreq *rq, int cmd)
 
switch (config.tx_type) {
case HWTSTAMP_TX_OFF:
-   priv->tx_tstamp = false;
-   break;
case HWTSTAMP_TX_ON:
-   priv->tx_tstamp = true;
+   priv->tx_tstamp_type = config.tx_type;
break;
default:
return -ERANGE;
@@ -2097,7 +2101,6 @@ static int dpaa2_eth_xdp_create_fd(struct net_device 
*net_dev,
   struct xdp_frame *xdpf,
   struct dpaa2_fd *fd)
 {
-   struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
struct device *dev = net_dev->dev.parent;
unsigned int needed_headroom;
struct dpaa2_eth_swa *swa;
@@ -2107,7 +2110,7 @@ static int dpaa2_eth_xdp_create_fd(struct net_device 
*net_dev,
/* We require a minimum headroom to be able to transmit the frame.
 * Otherwise return an error and let the original net_device handle it
 */
-   needed_headroom = dpaa2_eth_needed_headroom(priv, NULL);
+   needed_headroom = dpaa2_eth_needed_headroom(NULL);
if (xdpf->headroom < needed_headroom)
return -EINVAL;
 
@@ -3963,6 +3966,9 @@ static int dpaa2_eth_probe(struct fsl_mc_device *dpni_dev)
 
priv->iommu_domain = iommu_get_domain_for_dev(dev);
 
+   priv->tx_tstamp_type = HWTSTAMP_TX_OFF;
+   priv->rx_tstamp = false;
+
/* Obtain a MC portal */
err = fsl_mc_

[v3, 6/6] dpaa2-eth: fix a build warning in dpmac.c

2020-09-16 Thread Yangbo Lu
Fix below sparse warning in dpmac.c.
warning: cast to restricted __le64

Signed-off-by: Yangbo Lu 
---
Changes for v3:
- Added this patch.
---
 drivers/net/ethernet/freescale/dpaa2/dpmac.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/dpaa2/dpmac.c 
b/drivers/net/ethernet/freescale/dpaa2/dpmac.c
index d5997b6..71f165c 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpmac.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpmac.c
@@ -177,7 +177,7 @@ int dpmac_get_counter(struct fsl_mc_io *mc_io, u32 
cmd_flags, u16 token,
return err;
 
dpmac_rsp = (struct dpmac_rsp_get_counter *)cmd.params;
-   *value = le64_to_cpu(dpmac_rsp->counter);
+   *value = dpmac_rsp->counter;
 
return 0;
 }
-- 
2.7.4



[v3, 1/6] dpaa2-eth: add APIs of 1588 single step timestamping

2020-09-16 Thread Yangbo Lu
This patch is to add APIs of 1588 single step timestamping.

- dpni_set_single_step_cfg
- dpni_get_single_step_cfg

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
Changes for v3:
- Fixed sparse warnings.
---
 drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h | 21 +++
 drivers/net/ethernet/freescale/dpaa2/dpni.c | 79 +
 drivers/net/ethernet/freescale/dpaa2/dpni.h | 31 ++
 3 files changed, 131 insertions(+)

diff --git a/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h 
b/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h
index 593e381..1222a4e 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h
+++ b/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
 /* Copyright 2013-2016 Freescale Semiconductor Inc.
  * Copyright 2016 NXP
+ * Copyright 2020 NXP
  */
 #ifndef _FSL_DPNI_CMD_H
 #define _FSL_DPNI_CMD_H
@@ -90,6 +91,9 @@
 #define DPNI_CMDID_SET_RX_HASH_DISTDPNI_CMD(0x274)
 #define DPNI_CMDID_GET_LINK_CFGDPNI_CMD(0x278)
 
+#define DPNI_CMDID_SET_SINGLE_STEP_CFG DPNI_CMD(0x279)
+#define DPNI_CMDID_GET_SINGLE_STEP_CFG DPNI_CMD(0x27a)
+
 /* Macros for accessing command fields smaller than 1byte */
 #define DPNI_MASK(field)   \
GENMASK(DPNI_##field##_SHIFT + DPNI_##field##_SIZE - 1, \
@@ -639,4 +643,21 @@ struct dpni_cmd_set_tx_shaping {
u8 coupled;
 };
 
+#define DPNI_PTP_ENABLE_SHIFT  0
+#define DPNI_PTP_ENABLE_SIZE   1
+#define DPNI_PTP_CH_UPDATE_SHIFT   1
+#define DPNI_PTP_CH_UPDATE_SIZE1
+
+struct dpni_cmd_single_step_cfg {
+   __le16 flags;
+   __le16 offset;
+   __le32 peer_delay;
+};
+
+struct dpni_rsp_single_step_cfg {
+   __le16 flags;
+   __le16 offset;
+   __le32 peer_delay;
+};
+
 #endif /* _FSL_DPNI_CMD_H */
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpni.c 
b/drivers/net/ethernet/freescale/dpaa2/dpni.c
index 68ed4c4..6ea7db66 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpni.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpni.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /* Copyright 2013-2016 Freescale Semiconductor Inc.
  * Copyright 2016 NXP
+ * Copyright 2020 NXP
  */
 #include 
 #include 
@@ -1999,3 +2000,81 @@ int dpni_set_tx_shaping(struct fsl_mc_io *mc_io,
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
 }
+
+/**
+ * dpni_get_single_step_cfg() - return current configuration for
+ *  single step PTP
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @ptp_cfg:   ptp single step configuration
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ */
+int dpni_get_single_step_cfg(struct fsl_mc_io *mc_io,
+u32 cmd_flags,
+u16 token,
+struct dpni_single_step_cfg *ptp_cfg)
+{
+   struct dpni_rsp_single_step_cfg *rsp_params;
+   struct fsl_mc_command cmd = { 0 };
+   int err;
+
+   /* prepare command */
+   cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_SINGLE_STEP_CFG,
+ cmd_flags, token);
+   /* send command to mc*/
+   err =  mc_send_command(mc_io, &cmd);
+   if (err)
+   return err;
+
+   /* read command response */
+   rsp_params = (struct dpni_rsp_single_step_cfg *)cmd.params;
+   ptp_cfg->offset = le16_to_cpu(rsp_params->offset);
+   ptp_cfg->en = dpni_get_field(le16_to_cpu(rsp_params->flags),
+PTP_ENABLE) ? 1 : 0;
+   ptp_cfg->ch_update = dpni_get_field(le16_to_cpu(rsp_params->flags),
+   PTP_CH_UPDATE) ? 1 : 0;
+   ptp_cfg->peer_delay = le32_to_cpu(rsp_params->peer_delay);
+
+   return err;
+}
+
+/**
+ * dpni_set_single_step_cfg() - enable/disable and configure single step PTP
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @ptp_cfg:   ptp single step configuration
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ * The function has effect only when dpni object is connected to a dpmac
+ * object. If the dpni is not connected to a dpmac the configuration will
+ * be stored inside and applied when connection is made.
+ */
+int dpni_set_single_step_cfg(struct fsl_mc_io *mc_io,
+u32 cmd_flags,
+u16 token,
+struct dpni_single_step_cfg *ptp_cfg)
+{
+   struct dpni_cmd_single_step_cfg *cmd_params;
+   

[v3, 0/6] dpaa2_eth: support 1588 one-step timestamping

2020-09-16 Thread Yangbo Lu
This patch-set is to add MC APIs of 1588 one-step timestamping, and
support one-step timestamping for PTP Sync packet on DPAA2.

Before egress, one-step timestamping enablement needs,

- Enabling timestamp and FAS (Frame Annotation Status) in
  dpni buffer layout.

- Write timestamp to frame annotation and set PTP bit in
  FAS to mark as one-step timestamping event.

- Enabling one-step timestamping by dpni_set_single_step_cfg()
  API, with offset provided to insert correction time on frame.
  The offset must respect all MAC headers, VLAN tags and other
  protocol headers accordingly. The correction field update can
  consider delays up to one second. So PTP frame needs to be
  filtered and parsed, and written timestamp into Sync frame
  originTimestamp field.

The operation of API dpni_set_single_step_cfg() has to be done
when no one-step timestamping frames are in flight. So we have
to make sure the last one-step timestamping frame has already
been transmitted on hardware before starting to send the current
one. The resolution is,

- Utilize skb->cb[0] to mark timestamping request per packet.
  If it is one-step timestamping PTP sync packet, queue to skb queue.
  If not, transmit immediately.

- Schedule a work to transmit skbs in skb queue.

- mutex lock is used to ensure the last one-step timestamping packet
  has already been transmitted on hardware through TX confirmation queue
  before transmitting current packet.

Changes for v2:
- Removed unused variable priv in dpaa2_eth_xdp_create_fd().
Changes for v3:
- Fixed sparse warnings.
- Fix build issue on 32-bit.
- Converted to use ptp_parse_header.

Yangbo Lu (6):
  dpaa2-eth: add APIs of 1588 single step timestamping
  dpaa2-eth: define a global ptp_qoriq structure pointer
  dpaa2-eth: invoke dpaa2_eth_enable_tx_tstamp() once in code
  dpaa2-eth: utilize skb->cb[0] for hardware timestamping
  dpaa2-eth: support PTP Sync packet one-step timestamping
  dpaa2-eth: fix a build warning in dpmac.c

 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c   | 232 ++---
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h   |  44 +++-
 .../net/ethernet/freescale/dpaa2/dpaa2-ethtool.c   |   4 +-
 drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c   |   3 +-
 drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.h   |   4 +
 drivers/net/ethernet/freescale/dpaa2/dpmac.c   |   2 +-
 drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h|  21 ++
 drivers/net/ethernet/freescale/dpaa2/dpni.c|  79 +++
 drivers/net/ethernet/freescale/dpaa2/dpni.h|  31 +++
 9 files changed, 382 insertions(+), 38 deletions(-)

-- 
2.7.4



[v3, 5/6] dpaa2-eth: support PTP Sync packet one-step timestamping

2020-09-16 Thread Yangbo Lu
This patch is to add PTP sync packet one-step timestamping support.
Before egress, one-step timestamping enablement needs,

- Enabling timestamp and FAS (Frame Annotation Status) in
  dpni buffer layout.

- Write timestamp to frame annotation and set PTP bit in
  FAS to mark as one-step timestamping event.

- Enabling one-step timestamping by dpni_set_single_step_cfg()
  API, with offset provided to insert correction time on frame.
  The offset must respect all MAC headers, VLAN tags and other
  protocol headers accordingly. The correction field update can
  consider delays up to one second. So PTP frame needs to be
  filtered and parsed, and written timestamp into Sync frame
  originTimestamp field.

The operation of API dpni_set_single_step_cfg() has to be done
when no one-step timestamping frames are in flight. So we have
to make sure the last one-step timestamping frame has already
been transmitted on hardware before starting to send the current
one. The resolution is,

- Utilize skb->cb[0] to mark timestamping request per packet.
  If it is one-step timestamping PTP sync packet, queue to skb queue.
  If not, transmit immediately.

- Schedule a work to transmit skbs in skb queue.

- mutex lock is used to ensure the last one-step timestamping packet
  has already been transmitted on hardware through TX confirmation queue
  before transmitting current packet.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
Changes for v3:
- Fixed build issue on 32-bit.
- Converted to use ptp_parse_header.
---
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c   | 191 +++--
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h   |  32 +++-
 .../net/ethernet/freescale/dpaa2/dpaa2-ethtool.c   |   4 +-
 3 files changed, 211 insertions(+), 16 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c 
b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index eab9470..ba570f6 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -563,11 +564,57 @@ static int dpaa2_eth_consume_frames(struct 
dpaa2_eth_channel *ch,
return cleaned;
 }
 
+static int dpaa2_eth_ptp_parse(struct sk_buff *skb,
+  u8 *msgtype, u8 *twostep, u8 *udp,
+  u16 *correction_offset,
+  u16 *origintimestamp_offset)
+{
+   unsigned int ptp_class;
+   struct ptp_header *hdr;
+   unsigned int type;
+   u8 *base;
+
+   ptp_class = ptp_classify_raw(skb);
+   if (ptp_class == PTP_CLASS_NONE)
+   return -EINVAL;
+
+   hdr = ptp_parse_header(skb, ptp_class);
+   if (!hdr)
+   return -EINVAL;
+
+   *msgtype = ptp_get_msgtype(hdr, ptp_class);
+   *twostep = hdr->flag_field[0] & 0x2;
+
+   type = ptp_class & PTP_CLASS_PMASK;
+   if (type == PTP_CLASS_IPV4 ||
+   type == PTP_CLASS_IPV6)
+   *udp = 1;
+   else
+   *udp = 0;
+
+   base = skb_mac_header(skb);
+   *correction_offset = (u8 *)&hdr->correction - base;
+   *origintimestamp_offset = (u8 *)hdr + sizeof(struct ptp_header) - base;
+
+   return 0;
+}
+
 /* Configure the egress frame annotation for timestamp update */
-static void dpaa2_eth_enable_tx_tstamp(struct dpaa2_fd *fd, void *buf_start)
+static void dpaa2_eth_enable_tx_tstamp(struct dpaa2_eth_priv *priv,
+  struct dpaa2_fd *fd,
+  void *buf_start,
+  struct sk_buff *skb)
 {
+   struct ptp_tstamp origin_timestamp;
+   struct dpni_single_step_cfg cfg;
+   u8 msgtype, twostep, udp;
struct dpaa2_faead *faead;
+   struct dpaa2_fas *fas;
+   struct timespec64 ts;
+   u16 offset1, offset2;
u32 ctrl, frc;
+   __le64 *ns;
+   u8 *data;
 
/* Mark the egress frame annotation area as valid */
frc = dpaa2_fd_get_frc(fd);
@@ -583,6 +630,58 @@ static void dpaa2_eth_enable_tx_tstamp(struct dpaa2_fd 
*fd, void *buf_start)
ctrl = DPAA2_FAEAD_A2V | DPAA2_FAEAD_UPDV | DPAA2_FAEAD_UPD;
faead = dpaa2_get_faead(buf_start, true);
faead->ctrl = cpu_to_le32(ctrl);
+
+   if (skb->cb[0] == TX_TSTAMP_ONESTEP_SYNC) {
+   if (dpaa2_eth_ptp_parse(skb, &msgtype, &twostep, &udp,
+   &offset1, &offset2)) {
+   netdev_err(priv->net_dev,
+  "bad packet for one-step timestamping\n");
+   return;
+   }
+
+   if (msgtype != 0 || twostep) {
+   netdev_err(priv->net_dev,
+  "bad packet for one-step timestamping\n");
+ 

[PATCH 2/2] ptp_qoriq: support FIPER3

2020-09-11 Thread Yangbo Lu
The FIPER3 (fixed interval period pulse generator) is supported on
DPAA2 and ENETC network controller hardware. This patch is to support
it in ptp_qoriq driver.

Signed-off-by: Yangbo Lu 
---
 drivers/ptp/ptp_qoriq.c   | 23 ++-
 include/linux/fsl/ptp_qoriq.h |  3 +++
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/drivers/ptp/ptp_qoriq.c b/drivers/ptp/ptp_qoriq.c
index c09c16be..68beb1b 100644
--- a/drivers/ptp/ptp_qoriq.c
+++ b/drivers/ptp/ptp_qoriq.c
@@ -72,6 +72,10 @@ static void set_fipers(struct ptp_qoriq *ptp_qoriq)
set_alarm(ptp_qoriq);
ptp_qoriq->write(®s->fiper_regs->tmr_fiper1, ptp_qoriq->tmr_fiper1);
ptp_qoriq->write(®s->fiper_regs->tmr_fiper2, ptp_qoriq->tmr_fiper2);
+
+   if (ptp_qoriq->fiper3_support)
+   ptp_qoriq->write(®s->fiper_regs->tmr_fiper3,
+ptp_qoriq->tmr_fiper3);
 }
 
 int extts_clean_up(struct ptp_qoriq *ptp_qoriq, int index, bool update_event)
@@ -366,6 +370,7 @@ static u32 ptp_qoriq_nominal_freq(u32 clk_src)
  *   "fsl,tmr-add"
  *   "fsl,tmr-fiper1"
  *   "fsl,tmr-fiper2"
+ *   "fsl,tmr-fiper3" (required only for DPAA2 and ENETC hardware)
  *   "fsl,max-adj"
  *
  * Return 0 if success
@@ -412,6 +417,7 @@ static int ptp_qoriq_auto_config(struct ptp_qoriq 
*ptp_qoriq,
ptp_qoriq->tmr_add = freq_comp;
ptp_qoriq->tmr_fiper1 = DEFAULT_FIPER1_PERIOD - ptp_qoriq->tclk_period;
ptp_qoriq->tmr_fiper2 = DEFAULT_FIPER2_PERIOD - ptp_qoriq->tclk_period;
+   ptp_qoriq->tmr_fiper3 = DEFAULT_FIPER3_PERIOD - ptp_qoriq->tclk_period;
 
/* max_adj = 10 * (freq_ratio - 1.0) - 1
 * freq_ratio = reference_clock_freq / nominal_freq
@@ -446,6 +452,13 @@ int ptp_qoriq_init(struct ptp_qoriq *ptp_qoriq, void 
__iomem *base,
else
ptp_qoriq->extts_fifo_support = false;
 
+   if (of_device_is_compatible(node, "fsl,dpaa2-ptp") ||
+   of_device_is_compatible(node, "fsl,enetc-ptp")) {
+   ptp_qoriq->fiper3_support = true;
+   } else {
+   ptp_qoriq->fiper3_support = false;
+   }
+
if (of_property_read_u32(node,
 "fsl,tclk-period", &ptp_qoriq->tclk_period) ||
of_property_read_u32(node,
@@ -457,7 +470,10 @@ int ptp_qoriq_init(struct ptp_qoriq *ptp_qoriq, void 
__iomem *base,
of_property_read_u32(node,
 "fsl,tmr-fiper2", &ptp_qoriq->tmr_fiper2) ||
of_property_read_u32(node,
-"fsl,max-adj", &ptp_qoriq->caps.max_adj)) {
+"fsl,max-adj", &ptp_qoriq->caps.max_adj) ||
+   (of_property_read_u32(node,
+"fsl,tmr-fiper3", &ptp_qoriq->tmr_fiper3) &&
+ptp_qoriq->fiper3_support)) {
pr_warn("device tree node missing required elements, try 
automatic configuration\n");
 
if (ptp_qoriq_auto_config(ptp_qoriq, node))
@@ -502,6 +518,11 @@ int ptp_qoriq_init(struct ptp_qoriq *ptp_qoriq, void 
__iomem *base,
ptp_qoriq->write(®s->ctrl_regs->tmr_prsc, ptp_qoriq->tmr_prsc);
ptp_qoriq->write(®s->fiper_regs->tmr_fiper1, ptp_qoriq->tmr_fiper1);
ptp_qoriq->write(®s->fiper_regs->tmr_fiper2, ptp_qoriq->tmr_fiper2);
+
+   if (ptp_qoriq->fiper3_support)
+   ptp_qoriq->write(®s->fiper_regs->tmr_fiper3,
+ptp_qoriq->tmr_fiper3);
+
set_alarm(ptp_qoriq);
ptp_qoriq->write(®s->ctrl_regs->tmr_ctrl,
 tmr_ctrl|FIPERST|RTPE|TE|FRD);
diff --git a/include/linux/fsl/ptp_qoriq.h b/include/linux/fsl/ptp_qoriq.h
index 884b8f8..01acebe 100644
--- a/include/linux/fsl/ptp_qoriq.h
+++ b/include/linux/fsl/ptp_qoriq.h
@@ -136,6 +136,7 @@ struct ptp_qoriq_registers {
 #define DEFAULT_TMR_PRSC   2
 #define DEFAULT_FIPER1_PERIOD  10
 #define DEFAULT_FIPER2_PERIOD  10
+#define DEFAULT_FIPER3_PERIOD  10
 
 struct ptp_qoriq {
void __iomem *base;
@@ -147,6 +148,7 @@ struct ptp_qoriq {
struct dentry *debugfs_root;
struct device *dev;
bool extts_fifo_support;
+   bool fiper3_support;
int irq;
int phc_index;
u32 tclk_period;  /* nanoseconds */
@@ -155,6 +157,7 @@ struct ptp_qoriq {
u32 cksel;
u32 tmr_fiper1;
u32 tmr_fiper2;
+   u32 tmr_fiper3;
u32 (*read)(unsigned __iomem *addr);
void (*write)(unsigned __iomem *addr, u32 val);
 };
-- 
2.7.4



[PATCH 1/2] dt-binding: ptp_qoriq: support fsl,tmr-fiper3 property

2020-09-11 Thread Yangbo Lu
Add fsl,tmr-fiper3 property definition which is supported only
on DPAA2 and ENETC network controller hardware.

Signed-off-by: Yangbo Lu 
---
 Documentation/devicetree/bindings/ptp/ptp-qoriq.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/ptp/ptp-qoriq.txt 
b/Documentation/devicetree/bindings/ptp/ptp-qoriq.txt
index d48f9eb..743eda7 100644
--- a/Documentation/devicetree/bindings/ptp/ptp-qoriq.txt
+++ b/Documentation/devicetree/bindings/ptp/ptp-qoriq.txt
@@ -18,6 +18,8 @@ Clock Properties:
   - fsl,tmr-add  Frequency compensation value.
   - fsl,tmr-fiper1   Fixed interval period pulse generator.
   - fsl,tmr-fiper2   Fixed interval period pulse generator.
+  - fsl,tmr-fiper3   Fixed interval period pulse generator.
+ Supported only on DPAA2 and ENETC hardware.
   - fsl,max-adj  Maximum frequency adjustment in parts per billion.
   - fsl,extts-fifo   The presence of this property indicates hardware
 support for the external trigger stamp FIFO.
-- 
2.7.4



[PATCH 0/2] ptp_qoriq: support FIPER3

2020-09-11 Thread Yangbo Lu
The FIPER3 (fixed interval period pulse generator) is supported on
DPAA2 and ENETC network controller hardware. This patch-set is to
support it in ptp_qoriq driver and dt-binding.

Yangbo Lu (2):
  dt-binding: ptp_qoriq: support fsl,tmr-fiper3 property
  ptp_qoriq: support FIPER3

 .../devicetree/bindings/ptp/ptp-qoriq.txt  |  2 ++
 drivers/ptp/ptp_qoriq.c| 23 +-
 include/linux/fsl/ptp_qoriq.h  |  3 +++
 3 files changed, 27 insertions(+), 1 deletion(-)

-- 
2.7.4



[v2, 2/5] dpaa2-eth: define a global ptp_qoriq structure pointer

2020-09-10 Thread Yangbo Lu
Define a global ptp_qoriq structure pointer, and export to use.
The ptp clock operations will be used in dpaa2-eth driver.
For example, supporting one step timestamping needs to write
current time to hardware frame annotation before sending and
then hardware inserts the delay time on frame during sending.
So in driver, at least clock gettime operation will be needed
to make sure right time is written to hardware frame annotation
for one step timestamping.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
---
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 4 
 drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c | 3 ++-
 drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.h | 4 
 3 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c 
b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index ceaf761..daf8fd4 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -30,6 +31,9 @@ MODULE_LICENSE("Dual BSD/GPL");
 MODULE_AUTHOR("Freescale Semiconductor, Inc");
 MODULE_DESCRIPTION("Freescale DPAA2 Ethernet Driver");
 
+struct ptp_qoriq *dpaa2_ptp;
+EXPORT_SYMBOL(dpaa2_ptp);
+
 static void *dpaa2_iova_to_virt(struct iommu_domain *domain,
dma_addr_t iova_addr)
 {
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c 
b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c
index cc1b7f8..32b5faa 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c
@@ -2,6 +2,7 @@
 /*
  * Copyright 2013-2016 Freescale Semiconductor Inc.
  * Copyright 2016-2018 NXP
+ * Copyright 2020 NXP
  */
 
 #include 
@@ -9,7 +10,6 @@
 #include 
 #include 
 #include 
-#include 
 
 #include "dpaa2-ptp.h"
 
@@ -201,6 +201,7 @@ static int dpaa2_ptp_probe(struct fsl_mc_device *mc_dev)
goto err_free_threaded_irq;
 
dpaa2_phc_index = ptp_qoriq->phc_index;
+   dpaa2_ptp = ptp_qoriq;
dev_set_drvdata(dev, ptp_qoriq);
 
return 0;
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.h 
b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.h
index df2458a..e102353 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.h
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.h
@@ -1,14 +1,18 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright 2018 NXP
+ * Copyright 2020 NXP
  */
 
 #ifndef __RTC_H
 #define __RTC_H
 
+#include 
+
 #include "dprtc.h"
 #include "dprtc-cmd.h"
 
 extern int dpaa2_phc_index;
+extern struct ptp_qoriq *dpaa2_ptp;
 
 #endif
-- 
2.7.4



[v2, 3/5] dpaa2-eth: invoke dpaa2_eth_enable_tx_tstamp() once in code

2020-09-10 Thread Yangbo Lu
Invoke dpaa2_eth_enable_tx_tstamp() once in code after building FD,
rather than calling it in dpaa2_eth_build_single_fd(),
dpaa2_eth_build_sg_fd_single_buf(), and dpaa2_eth_build_sg_fd().

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
---
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 31 
 1 file changed, 16 insertions(+), 15 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c 
b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index daf8fd4..a8c311fb 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -589,7 +589,8 @@ static void dpaa2_eth_enable_tx_tstamp(struct dpaa2_fd *fd, 
void *buf_start)
 /* Create a frame descriptor based on a fragmented skb */
 static int dpaa2_eth_build_sg_fd(struct dpaa2_eth_priv *priv,
 struct sk_buff *skb,
-struct dpaa2_fd *fd)
+struct dpaa2_fd *fd,
+void **swa_addr)
 {
struct device *dev = priv->net_dev->dev.parent;
void *sgt_buf = NULL;
@@ -658,6 +659,7 @@ static int dpaa2_eth_build_sg_fd(struct dpaa2_eth_priv 
*priv,
 * skb backpointer in the software annotation area. We'll need
 * all of them on Tx Conf.
 */
+   *swa_addr = (void *)sgt_buf;
swa = (struct dpaa2_eth_swa *)sgt_buf;
swa->type = DPAA2_ETH_SWA_SG;
swa->sg.skb = skb;
@@ -677,9 +679,6 @@ static int dpaa2_eth_build_sg_fd(struct dpaa2_eth_priv 
*priv,
dpaa2_fd_set_len(fd, skb->len);
dpaa2_fd_set_ctrl(fd, FD_CTRL_PTA);
 
-   if (priv->tx_tstamp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
-   dpaa2_eth_enable_tx_tstamp(fd, sgt_buf);
-
return 0;
 
 dma_map_single_failed:
@@ -699,7 +698,8 @@ static int dpaa2_eth_build_sg_fd(struct dpaa2_eth_priv 
*priv,
  */
 static int dpaa2_eth_build_sg_fd_single_buf(struct dpaa2_eth_priv *priv,
struct sk_buff *skb,
-   struct dpaa2_fd *fd)
+   struct dpaa2_fd *fd,
+   void **swa_addr)
 {
struct device *dev = priv->net_dev->dev.parent;
struct dpaa2_eth_sgt_cache *sgt_cache;
@@ -737,6 +737,7 @@ static int dpaa2_eth_build_sg_fd_single_buf(struct 
dpaa2_eth_priv *priv,
dpaa2_sg_set_final(sgt, true);
 
/* Store the skb backpointer in the SGT buffer */
+   *swa_addr = (void *)sgt_buf;
swa = (struct dpaa2_eth_swa *)sgt_buf;
swa->type = DPAA2_ETH_SWA_SINGLE;
swa->single.skb = skb;
@@ -755,9 +756,6 @@ static int dpaa2_eth_build_sg_fd_single_buf(struct 
dpaa2_eth_priv *priv,
dpaa2_fd_set_len(fd, skb->len);
dpaa2_fd_set_ctrl(fd, FD_CTRL_PTA);
 
-   if (priv->tx_tstamp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
-   dpaa2_eth_enable_tx_tstamp(fd, sgt_buf);
-
return 0;
 
 sgt_map_failed:
@@ -774,7 +772,8 @@ static int dpaa2_eth_build_sg_fd_single_buf(struct 
dpaa2_eth_priv *priv,
 /* Create a frame descriptor based on a linear skb */
 static int dpaa2_eth_build_single_fd(struct dpaa2_eth_priv *priv,
 struct sk_buff *skb,
-struct dpaa2_fd *fd)
+struct dpaa2_fd *fd,
+void **swa_addr)
 {
struct device *dev = priv->net_dev->dev.parent;
u8 *buffer_start, *aligned_start;
@@ -795,6 +794,7 @@ static int dpaa2_eth_build_single_fd(struct dpaa2_eth_priv 
*priv,
 * (in the private data area) such that we can release it
 * on Tx confirm
 */
+   *swa_addr = (void *)buffer_start;
swa = (struct dpaa2_eth_swa *)buffer_start;
swa->type = DPAA2_ETH_SWA_SINGLE;
swa->single.skb = skb;
@@ -811,9 +811,6 @@ static int dpaa2_eth_build_single_fd(struct dpaa2_eth_priv 
*priv,
dpaa2_fd_set_format(fd, dpaa2_fd_single);
dpaa2_fd_set_ctrl(fd, FD_CTRL_PTA);
 
-   if (priv->tx_tstamp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
-   dpaa2_eth_enable_tx_tstamp(fd, buffer_start);
-
return 0;
 }
 
@@ -939,6 +936,7 @@ static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, struct 
net_device *net_dev)
u32 fd_len;
u8 prio = 0;
int err, i;
+   void *swa;
 
percpu_stats = this_cpu_ptr(priv->percpu_stats);
percpu_extras = this_cpu_ptr(priv->percpu_extras);
@@ -959,17 +957,17 @@ static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, 
struct net_device *net_dev)
memset(&fd, 0, sizeof(fd));
 
if (skb_is_nonlinear(skb)) {
-   err = dpaa2_eth_build_sg_fd(priv, skb, &

[v2, 4/5] dpaa2-eth: utilize skb->cb[0] for hardware timestamping

2020-09-10 Thread Yangbo Lu
This patch is a preparation for next hardware one-step timestamping
support. For DPAA2, the one step timestamping configuration on
hardware registers has to be done when there is no one-step timestamping
packet in flight. So we will have to use workqueue and skb queue
for such packets transmitting, to make sure waiting the last packet has
already been sent on hardware, and starting to transmit the current one.

So the tx timestamping flag in private data may not reflect the actual
request for the one-step timestamping packets of skb queue. This also
affects skb headroom allocation. Let's use skb->cb[0] to mark the
timestamping request for each skb.

Signed-off-by: Yangbo Lu 
---
Change for v2:
- Removed unused variable priv in dpaa2_eth_xdp_create_fd().
---
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 26 +++-
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 13 ++--
 2 files changed, 23 insertions(+), 16 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c 
b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index a8c311fb..eab9470 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -11,7 +11,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -780,7 +779,7 @@ static int dpaa2_eth_build_single_fd(struct dpaa2_eth_priv 
*priv,
struct dpaa2_eth_swa *swa;
dma_addr_t addr;
 
-   buffer_start = skb->data - dpaa2_eth_needed_headroom(priv, skb);
+   buffer_start = skb->data - dpaa2_eth_needed_headroom(skb);
 
/* If there's enough room to align the FD address, do it.
 * It will help hardware optimize accesses.
@@ -894,7 +893,7 @@ static void dpaa2_eth_free_tx_fd(const struct 
dpaa2_eth_priv *priv,
}
 
/* Get the timestamp value */
-   if (priv->tx_tstamp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) {
+   if (skb->cb[0] == TX_TSTAMP) {
struct skb_shared_hwtstamps shhwtstamps;
__le64 *ts = dpaa2_get_ts(buffer_start, true);
u64 ns;
@@ -938,10 +937,17 @@ static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, 
struct net_device *net_dev)
int err, i;
void *swa;
 
+   /* Utilize skb->cb[0] for timestamping request per skb */
+   skb->cb[0] = 0;
+
+   if (priv->tx_tstamp_type == HWTSTAMP_TX_ON &&
+   skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
+   skb->cb[0] = TX_TSTAMP;
+
percpu_stats = this_cpu_ptr(priv->percpu_stats);
percpu_extras = this_cpu_ptr(priv->percpu_extras);
 
-   needed_headroom = dpaa2_eth_needed_headroom(priv, skb);
+   needed_headroom = dpaa2_eth_needed_headroom(skb);
 
/* We'll be holding a back-reference to the skb until Tx Confirmation;
 * we don't want that overwritten by a concurrent Tx with a cloned skb.
@@ -975,7 +981,7 @@ static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, struct 
net_device *net_dev)
goto err_build_fd;
}
 
-   if (priv->tx_tstamp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
+   if (skb->cb[0] == TX_TSTAMP)
dpaa2_eth_enable_tx_tstamp(&fd, swa);
 
/* Tracing point */
@@ -1899,10 +1905,8 @@ static int dpaa2_eth_ts_ioctl(struct net_device *dev, 
struct ifreq *rq, int cmd)
 
switch (config.tx_type) {
case HWTSTAMP_TX_OFF:
-   priv->tx_tstamp = false;
-   break;
case HWTSTAMP_TX_ON:
-   priv->tx_tstamp = true;
+   priv->tx_tstamp_type = config.tx_type;
break;
default:
return -ERANGE;
@@ -2097,7 +2101,6 @@ static int dpaa2_eth_xdp_create_fd(struct net_device 
*net_dev,
   struct xdp_frame *xdpf,
   struct dpaa2_fd *fd)
 {
-   struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
struct device *dev = net_dev->dev.parent;
unsigned int needed_headroom;
struct dpaa2_eth_swa *swa;
@@ -2107,7 +2110,7 @@ static int dpaa2_eth_xdp_create_fd(struct net_device 
*net_dev,
/* We require a minimum headroom to be able to transmit the frame.
 * Otherwise return an error and let the original net_device handle it
 */
-   needed_headroom = dpaa2_eth_needed_headroom(priv, NULL);
+   needed_headroom = dpaa2_eth_needed_headroom(NULL);
if (xdpf->headroom < needed_headroom)
return -EINVAL;
 
@@ -3963,6 +3966,9 @@ static int dpaa2_eth_probe(struct fsl_mc_device *dpni_dev)
 
priv->iommu_domain = iommu_get_domain_for_dev(dev);
 
+   priv->tx_tstamp_type = HWTSTAMP_TX_OFF;
+   priv->rx_tstamp = false;
+
/* Obtain a MC portal */
err = fsl_mc_portal_allocate(dpni_dev, FSL_M

[v2, 5/5] dpaa2-eth: support PTP Sync packet one-step timestamping

2020-09-10 Thread Yangbo Lu
This patch is to add PTP sync packet one-step timestamping support.
Before egress, one-step timestamping enablement needs,

- Enabling timestamp and FAS (Frame Annotation Status) in
  dpni buffer layout.

- Write timestamp to frame annotation and set PTP bit in
  FAS to mark as one-step timestamping event.

- Enabling one-step timestamping by dpni_set_single_step_cfg()
  API, with offset provided to insert correction time on frame.
  The offset must respect all MAC headers, VLAN tags and other
  protocol headers accordingly. The correction field update can
  consider delays up to one second. So PTP frame needs to be
  filtered and parsed, and written timestamp into Sync frame
  originTimestamp field.

The operation of API dpni_set_single_step_cfg() has to be done
when no one-step timestamping frames are in flight. So we have
to make sure the last one-step timestamping frame has already
been transmitted on hardware before starting to send the current
one. The resolution is,

- Utilize skb->cb[0] to mark timestamping request per packet.
  If it is one-step timestamping PTP sync packet, queue to skb queue.
  If not, transmit immediately.

- Schedule a work to transmit skbs in skb queue.

- mutex lock is used to ensure the last one-step timestamping packet
  has already been transmitted on hardware through TX confirmation queue
  before transmitting current packet.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
---
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c   | 206 +++--
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h   |  32 +++-
 .../net/ethernet/freescale/dpaa2/dpaa2-ethtool.c   |   4 +-
 3 files changed, 226 insertions(+), 16 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c 
b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index eab9470..e54381c 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -563,11 +564,72 @@ static int dpaa2_eth_consume_frames(struct 
dpaa2_eth_channel *ch,
return cleaned;
 }
 
+static int dpaa2_eth_ptp_parse(struct sk_buff *skb, u8 *msg_type, u8 *two_step,
+  u8 *udp, u16 *correction_offset,
+  u16 *origin_timestamp_offset)
+{
+   unsigned int ptp_class;
+   u16 offset = 0;
+   u8 *data;
+
+   data = skb_mac_header(skb);
+   ptp_class = ptp_classify_raw(skb);
+
+   switch (ptp_class & PTP_CLASS_VMASK) {
+   case PTP_CLASS_V1:
+   case PTP_CLASS_V2:
+   break;
+   default:
+   return -ERANGE;
+   }
+
+   if (ptp_class & PTP_CLASS_VLAN)
+   offset += VLAN_HLEN;
+
+   switch (ptp_class & PTP_CLASS_PMASK) {
+   case PTP_CLASS_IPV4:
+   offset += ETH_HLEN + IPV4_HLEN(data + offset) + UDP_HLEN;
+   *udp = 1;
+   break;
+   case PTP_CLASS_IPV6:
+   offset += ETH_HLEN + IP6_HLEN + UDP_HLEN;
+   *udp = 1;
+   break;
+   case PTP_CLASS_L2:
+   offset += ETH_HLEN;
+   *udp = 0;
+   break;
+   default:
+   return -ERANGE;
+   }
+
+   /* PTP header is 34 bytes. */
+   if (skb->len < offset + 34)
+   return -EINVAL;
+
+   *msg_type = data[offset] & 0x0f;
+   *two_step = data[offset + 6] & 0x2;
+   *correction_offset = offset + 8;
+   *origin_timestamp_offset = offset + 34;
+   return 0;
+}
+
 /* Configure the egress frame annotation for timestamp update */
-static void dpaa2_eth_enable_tx_tstamp(struct dpaa2_fd *fd, void *buf_start)
+static void dpaa2_eth_enable_tx_tstamp(struct dpaa2_eth_priv *priv,
+  struct dpaa2_fd *fd,
+  void *buf_start,
+  struct sk_buff *skb)
 {
+   struct ptp_tstamp origin_timestamp;
+   struct dpni_single_step_cfg cfg;
+   u8 msg_type, two_step, udp;
struct dpaa2_faead *faead;
+   struct dpaa2_fas *fas;
+   struct timespec64 ts;
+   u16 offset1, offset2;
u32 ctrl, frc;
+   __le64 *ns;
+   u8 *data;
 
/* Mark the egress frame annotation area as valid */
frc = dpaa2_fd_get_frc(fd);
@@ -583,6 +645,58 @@ static void dpaa2_eth_enable_tx_tstamp(struct dpaa2_fd 
*fd, void *buf_start)
ctrl = DPAA2_FAEAD_A2V | DPAA2_FAEAD_UPDV | DPAA2_FAEAD_UPD;
faead = dpaa2_get_faead(buf_start, true);
faead->ctrl = cpu_to_le32(ctrl);
+
+   if (skb->cb[0] == TX_TSTAMP_ONESTEP_SYNC) {
+   if (dpaa2_eth_ptp_parse(skb, &msg_type, &two_step, &udp,
+   &offset1, &offset2)) {
+   netdev_err(priv->net_dev,
+   

[v2, 0/5] dpaa2_eth: support 1588 one-step timestamping

2020-09-10 Thread Yangbo Lu
This patch-set is to add MC APIs of 1588 one-step timestamping, and
support one-step timestamping for PTP Sync packet on DPAA2.

Before egress, one-step timestamping enablement needs,

- Enabling timestamp and FAS (Frame Annotation Status) in
  dpni buffer layout.

- Write timestamp to frame annotation and set PTP bit in
  FAS to mark as one-step timestamping event.

- Enabling one-step timestamping by dpni_set_single_step_cfg()
  API, with offset provided to insert correction time on frame.
  The offset must respect all MAC headers, VLAN tags and other
  protocol headers accordingly. The correction field update can
  consider delays up to one second. So PTP frame needs to be
  filtered and parsed, and written timestamp into Sync frame
  originTimestamp field.

The operation of API dpni_set_single_step_cfg() has to be done
when no one-step timestamping frames are in flight. So we have
to make sure the last one-step timestamping frame has already
been transmitted on hardware before starting to send the current
one. The resolution is,

- Utilize skb->cb[0] to mark timestamping request per packet.
  If it is one-step timestamping PTP sync packet, queue to skb queue.
  If not, transmit immediately.

- Schedule a work to transmit skbs in skb queue.

- mutex lock is used to ensure the last one-step timestamping packet
  has already been transmitted on hardware through TX confirmation queue
  before transmitting current packet.

Change for v2:
- Removed unused variable priv in dpaa2_eth_xdp_create_fd().

Yangbo Lu (5):
  dpaa2-eth: add APIs of 1588 single step timestamping
  dpaa2-eth: define a global ptp_qoriq structure pointer
  dpaa2-eth: invoke dpaa2_eth_enable_tx_tstamp() once in code
  dpaa2-eth: utilize skb->cb[0] for hardware timestamping
  dpaa2-eth: support PTP Sync packet one-step timestamping

 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c   | 247 ++---
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h   |  43 +++-
 .../net/ethernet/freescale/dpaa2/dpaa2-ethtool.c   |   4 +-
 drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c   |   3 +-
 drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.h   |   4 +
 drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h|  21 ++
 drivers/net/ethernet/freescale/dpaa2/dpni.c|  73 ++
 drivers/net/ethernet/freescale/dpaa2/dpni.h|  31 +++
 8 files changed, 389 insertions(+), 37 deletions(-)

-- 
2.7.4



[v2, 1/5] dpaa2-eth: add APIs of 1588 single step timestamping

2020-09-10 Thread Yangbo Lu
This patch is to add APIs of 1588 single step timestamping.

- dpni_set_single_step_cfg
- dpni_get_single_step_cfg

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
---
 drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h | 21 +++
 drivers/net/ethernet/freescale/dpaa2/dpni.c | 73 +
 drivers/net/ethernet/freescale/dpaa2/dpni.h | 31 +++
 3 files changed, 125 insertions(+)

diff --git a/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h 
b/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h
index 593e381..1222a4e 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h
+++ b/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
 /* Copyright 2013-2016 Freescale Semiconductor Inc.
  * Copyright 2016 NXP
+ * Copyright 2020 NXP
  */
 #ifndef _FSL_DPNI_CMD_H
 #define _FSL_DPNI_CMD_H
@@ -90,6 +91,9 @@
 #define DPNI_CMDID_SET_RX_HASH_DISTDPNI_CMD(0x274)
 #define DPNI_CMDID_GET_LINK_CFGDPNI_CMD(0x278)
 
+#define DPNI_CMDID_SET_SINGLE_STEP_CFG DPNI_CMD(0x279)
+#define DPNI_CMDID_GET_SINGLE_STEP_CFG DPNI_CMD(0x27a)
+
 /* Macros for accessing command fields smaller than 1byte */
 #define DPNI_MASK(field)   \
GENMASK(DPNI_##field##_SHIFT + DPNI_##field##_SIZE - 1, \
@@ -639,4 +643,21 @@ struct dpni_cmd_set_tx_shaping {
u8 coupled;
 };
 
+#define DPNI_PTP_ENABLE_SHIFT  0
+#define DPNI_PTP_ENABLE_SIZE   1
+#define DPNI_PTP_CH_UPDATE_SHIFT   1
+#define DPNI_PTP_CH_UPDATE_SIZE1
+
+struct dpni_cmd_single_step_cfg {
+   __le16 flags;
+   __le16 offset;
+   __le32 peer_delay;
+};
+
+struct dpni_rsp_single_step_cfg {
+   __le16 flags;
+   __le16 offset;
+   __le32 peer_delay;
+};
+
 #endif /* _FSL_DPNI_CMD_H */
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpni.c 
b/drivers/net/ethernet/freescale/dpaa2/dpni.c
index 68ed4c4..6a36d47 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpni.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpni.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /* Copyright 2013-2016 Freescale Semiconductor Inc.
  * Copyright 2016 NXP
+ * Copyright 2020 NXP
  */
 #include 
 #include 
@@ -1999,3 +2000,75 @@ int dpni_set_tx_shaping(struct fsl_mc_io *mc_io,
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
 }
+
+/**
+ * dpni_get_single_step_cfg() - return current configuration for
+ *  single step PTP
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @ptp_cfg:   ptp single step configuration
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ */
+int dpni_get_single_step_cfg(struct fsl_mc_io *mc_io,
+u32 cmd_flags,
+u16 token,
+struct dpni_single_step_cfg *ptp_cfg)
+{
+   struct dpni_rsp_single_step_cfg *rsp_params;
+   struct fsl_mc_command cmd = { 0 };
+   int err;
+
+   /* prepare command */
+   cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_SINGLE_STEP_CFG,
+ cmd_flags, token);
+   /* send command to mc*/
+   err =  mc_send_command(mc_io, &cmd);
+   if (err)
+   return err;
+
+   /* read command response */
+   rsp_params = (struct dpni_rsp_single_step_cfg *)cmd.params;
+   ptp_cfg->offset = le16_to_cpu(rsp_params->offset);
+   ptp_cfg->en = dpni_get_field(rsp_params->flags, PTP_ENABLE);
+   ptp_cfg->ch_update = dpni_get_field(rsp_params->flags, PTP_CH_UPDATE);
+   ptp_cfg->peer_delay = le32_to_cpu(rsp_params->peer_delay);
+
+   return err;
+}
+
+/**
+ * dpni_set_single_step_cfg() - enable/disable and configure single step PTP
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @ptp_cfg:   ptp single step configuration
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ * The function has effect only when dpni object is connected to a dpmac
+ * object. If the dpni is not connected to a dpmac the configuration will
+ * be stored inside and applied when connection is made.
+ */
+int dpni_set_single_step_cfg(struct fsl_mc_io *mc_io,
+u32 cmd_flags,
+u16 token,
+struct dpni_single_step_cfg *ptp_cfg)
+{
+   struct dpni_cmd_single_step_cfg *cmd_params;
+   struct fsl_mc_command cmd = { 0 };
+
+   /* prepare command */
+   cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_SINGLE_STEP_CFG,
+   

[PATCH 1/5] dpaa2-eth: add APIs of 1588 single step timestamping

2020-09-10 Thread Yangbo Lu
This patch is to add APIs of 1588 single step timestamping.

- dpni_set_single_step_cfg
- dpni_get_single_step_cfg

Signed-off-by: Yangbo Lu 
---
 drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h | 21 +++
 drivers/net/ethernet/freescale/dpaa2/dpni.c | 73 +
 drivers/net/ethernet/freescale/dpaa2/dpni.h | 31 +++
 3 files changed, 125 insertions(+)

diff --git a/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h 
b/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h
index 593e381..1222a4e 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h
+++ b/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
 /* Copyright 2013-2016 Freescale Semiconductor Inc.
  * Copyright 2016 NXP
+ * Copyright 2020 NXP
  */
 #ifndef _FSL_DPNI_CMD_H
 #define _FSL_DPNI_CMD_H
@@ -90,6 +91,9 @@
 #define DPNI_CMDID_SET_RX_HASH_DISTDPNI_CMD(0x274)
 #define DPNI_CMDID_GET_LINK_CFGDPNI_CMD(0x278)
 
+#define DPNI_CMDID_SET_SINGLE_STEP_CFG DPNI_CMD(0x279)
+#define DPNI_CMDID_GET_SINGLE_STEP_CFG DPNI_CMD(0x27a)
+
 /* Macros for accessing command fields smaller than 1byte */
 #define DPNI_MASK(field)   \
GENMASK(DPNI_##field##_SHIFT + DPNI_##field##_SIZE - 1, \
@@ -639,4 +643,21 @@ struct dpni_cmd_set_tx_shaping {
u8 coupled;
 };
 
+#define DPNI_PTP_ENABLE_SHIFT  0
+#define DPNI_PTP_ENABLE_SIZE   1
+#define DPNI_PTP_CH_UPDATE_SHIFT   1
+#define DPNI_PTP_CH_UPDATE_SIZE1
+
+struct dpni_cmd_single_step_cfg {
+   __le16 flags;
+   __le16 offset;
+   __le32 peer_delay;
+};
+
+struct dpni_rsp_single_step_cfg {
+   __le16 flags;
+   __le16 offset;
+   __le32 peer_delay;
+};
+
 #endif /* _FSL_DPNI_CMD_H */
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpni.c 
b/drivers/net/ethernet/freescale/dpaa2/dpni.c
index 68ed4c4..6a36d47 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpni.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpni.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /* Copyright 2013-2016 Freescale Semiconductor Inc.
  * Copyright 2016 NXP
+ * Copyright 2020 NXP
  */
 #include 
 #include 
@@ -1999,3 +2000,75 @@ int dpni_set_tx_shaping(struct fsl_mc_io *mc_io,
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
 }
+
+/**
+ * dpni_get_single_step_cfg() - return current configuration for
+ *  single step PTP
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @ptp_cfg:   ptp single step configuration
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ */
+int dpni_get_single_step_cfg(struct fsl_mc_io *mc_io,
+u32 cmd_flags,
+u16 token,
+struct dpni_single_step_cfg *ptp_cfg)
+{
+   struct dpni_rsp_single_step_cfg *rsp_params;
+   struct fsl_mc_command cmd = { 0 };
+   int err;
+
+   /* prepare command */
+   cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_SINGLE_STEP_CFG,
+ cmd_flags, token);
+   /* send command to mc*/
+   err =  mc_send_command(mc_io, &cmd);
+   if (err)
+   return err;
+
+   /* read command response */
+   rsp_params = (struct dpni_rsp_single_step_cfg *)cmd.params;
+   ptp_cfg->offset = le16_to_cpu(rsp_params->offset);
+   ptp_cfg->en = dpni_get_field(rsp_params->flags, PTP_ENABLE);
+   ptp_cfg->ch_update = dpni_get_field(rsp_params->flags, PTP_CH_UPDATE);
+   ptp_cfg->peer_delay = le32_to_cpu(rsp_params->peer_delay);
+
+   return err;
+}
+
+/**
+ * dpni_set_single_step_cfg() - enable/disable and configure single step PTP
+ * @mc_io: Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token: Token of DPNI object
+ * @ptp_cfg:   ptp single step configuration
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ * The function has effect only when dpni object is connected to a dpmac
+ * object. If the dpni is not connected to a dpmac the configuration will
+ * be stored inside and applied when connection is made.
+ */
+int dpni_set_single_step_cfg(struct fsl_mc_io *mc_io,
+u32 cmd_flags,
+u16 token,
+struct dpni_single_step_cfg *ptp_cfg)
+{
+   struct dpni_cmd_single_step_cfg *cmd_params;
+   struct fsl_mc_command cmd = { 0 };
+
+   /* prepare command */
+   cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_SINGLE_STEP_CFG,
+ cmd_flags, token);
+   cmd_

[PATCH 5/5] dpaa2-eth: support PTP Sync packet one-step timestamping

2020-09-10 Thread Yangbo Lu
This patch is to add PTP sync packet one-step timestamping support.
Before egress, one-step timestamping enablement needs,

- Enabling timestamp and FAS (Frame Annotation Status) in
  dpni buffer layout.

- Write timestamp to frame annotation and set PTP bit in
  FAS to mark as one-step timestamping event.

- Enabling one-step timestamping by dpni_set_single_step_cfg()
  API, with offset provided to insert correction time on frame.
  The offset must respect all MAC headers, VLAN tags and other
  protocol headers accordingly. The correction field update can
  consider delays up to one second. So PTP frame needs to be
  filtered and parsed, and written timestamp into Sync frame
  originTimestamp field.

The operation of API dpni_set_single_step_cfg() has to be done
when no one-step timestamping frames are in flight. So we have
to make sure the last one-step timestamping frame has already
been transmitted on hardware before starting to send the current
one. The resolution is,

- Utilize skb->cb[0] to mark timestamping request per packet.
  If it is one-step timestamping PTP sync packet, queue to skb queue.
  If not, transmit immediately.

- Schedule a work to transmit skbs in skb queue.

- mutex lock is used to ensure the last one-step timestamping packet
  has already been transmitted on hardware through TX confirmation queue
  before transmitting current packet.

Signed-off-by: Yangbo Lu 
---
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c   | 206 +++--
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h   |  32 +++-
 .../net/ethernet/freescale/dpaa2/dpaa2-ethtool.c   |   4 +-
 3 files changed, 226 insertions(+), 16 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c 
b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index 2514543..b33afc3 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -563,11 +564,72 @@ static int dpaa2_eth_consume_frames(struct 
dpaa2_eth_channel *ch,
return cleaned;
 }
 
+static int dpaa2_eth_ptp_parse(struct sk_buff *skb, u8 *msg_type, u8 *two_step,
+  u8 *udp, u16 *correction_offset,
+  u16 *origin_timestamp_offset)
+{
+   unsigned int ptp_class;
+   u16 offset = 0;
+   u8 *data;
+
+   data = skb_mac_header(skb);
+   ptp_class = ptp_classify_raw(skb);
+
+   switch (ptp_class & PTP_CLASS_VMASK) {
+   case PTP_CLASS_V1:
+   case PTP_CLASS_V2:
+   break;
+   default:
+   return -ERANGE;
+   }
+
+   if (ptp_class & PTP_CLASS_VLAN)
+   offset += VLAN_HLEN;
+
+   switch (ptp_class & PTP_CLASS_PMASK) {
+   case PTP_CLASS_IPV4:
+   offset += ETH_HLEN + IPV4_HLEN(data + offset) + UDP_HLEN;
+   *udp = 1;
+   break;
+   case PTP_CLASS_IPV6:
+   offset += ETH_HLEN + IP6_HLEN + UDP_HLEN;
+   *udp = 1;
+   break;
+   case PTP_CLASS_L2:
+   offset += ETH_HLEN;
+   *udp = 0;
+   break;
+   default:
+   return -ERANGE;
+   }
+
+   /* PTP header is 34 bytes. */
+   if (skb->len < offset + 34)
+   return -EINVAL;
+
+   *msg_type = data[offset] & 0x0f;
+   *two_step = data[offset + 6] & 0x2;
+   *correction_offset = offset + 8;
+   *origin_timestamp_offset = offset + 34;
+   return 0;
+}
+
 /* Configure the egress frame annotation for timestamp update */
-static void dpaa2_eth_enable_tx_tstamp(struct dpaa2_fd *fd, void *buf_start)
+static void dpaa2_eth_enable_tx_tstamp(struct dpaa2_eth_priv *priv,
+  struct dpaa2_fd *fd,
+  void *buf_start,
+  struct sk_buff *skb)
 {
+   struct ptp_tstamp origin_timestamp;
+   struct dpni_single_step_cfg cfg;
+   u8 msg_type, two_step, udp;
struct dpaa2_faead *faead;
+   struct dpaa2_fas *fas;
+   struct timespec64 ts;
+   u16 offset1, offset2;
u32 ctrl, frc;
+   __le64 *ns;
+   u8 *data;
 
/* Mark the egress frame annotation area as valid */
frc = dpaa2_fd_get_frc(fd);
@@ -583,6 +645,58 @@ static void dpaa2_eth_enable_tx_tstamp(struct dpaa2_fd 
*fd, void *buf_start)
ctrl = DPAA2_FAEAD_A2V | DPAA2_FAEAD_UPDV | DPAA2_FAEAD_UPD;
faead = dpaa2_get_faead(buf_start, true);
faead->ctrl = cpu_to_le32(ctrl);
+
+   if (skb->cb[0] == TX_TSTAMP_ONESTEP_SYNC) {
+   if (dpaa2_eth_ptp_parse(skb, &msg_type, &two_step, &udp,
+   &offset1, &offset2)) {
+   netdev_err(priv->net_dev,
+  "bad packe

[PATCH 4/5] dpaa2-eth: utilize skb->cb[0] for hardware timestamping

2020-09-10 Thread Yangbo Lu
This patch is a preparation for next hardware one-step timestamping
support. For DPAA2, the one step timestamping configuration on
hardware registers has to be done when there is no one-step timestamping
packet in flight. So we will have to use workqueue and skb queue
for such packets transmitting, to make sure waiting the last packet has
already been sent on hardware, and starting to transmit the current one.

So the tx timestamping flag in private data may not reflect the actual
request for the one-step timestamping packets of skb queue. This also
affects skb headroom allocation. Let's use skb->cb[0] to mark the
timestamping request for each skb.

Signed-off-by: Yangbo Lu 
---
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 25 +++-
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 13 ++--
 2 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c 
b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index a8c311fb..2514543 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -11,7 +11,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -780,7 +779,7 @@ static int dpaa2_eth_build_single_fd(struct dpaa2_eth_priv 
*priv,
struct dpaa2_eth_swa *swa;
dma_addr_t addr;
 
-   buffer_start = skb->data - dpaa2_eth_needed_headroom(priv, skb);
+   buffer_start = skb->data - dpaa2_eth_needed_headroom(skb);
 
/* If there's enough room to align the FD address, do it.
 * It will help hardware optimize accesses.
@@ -894,7 +893,7 @@ static void dpaa2_eth_free_tx_fd(const struct 
dpaa2_eth_priv *priv,
}
 
/* Get the timestamp value */
-   if (priv->tx_tstamp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) {
+   if (skb->cb[0] == TX_TSTAMP) {
struct skb_shared_hwtstamps shhwtstamps;
__le64 *ts = dpaa2_get_ts(buffer_start, true);
u64 ns;
@@ -938,10 +937,17 @@ static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, 
struct net_device *net_dev)
int err, i;
void *swa;
 
+   /* Utilize skb->cb[0] for timestamping request per skb */
+   skb->cb[0] = 0;
+
+   if (priv->tx_tstamp_type == HWTSTAMP_TX_ON &&
+   skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
+   skb->cb[0] = TX_TSTAMP;
+
percpu_stats = this_cpu_ptr(priv->percpu_stats);
percpu_extras = this_cpu_ptr(priv->percpu_extras);
 
-   needed_headroom = dpaa2_eth_needed_headroom(priv, skb);
+   needed_headroom = dpaa2_eth_needed_headroom(skb);
 
/* We'll be holding a back-reference to the skb until Tx Confirmation;
 * we don't want that overwritten by a concurrent Tx with a cloned skb.
@@ -975,7 +981,7 @@ static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, struct 
net_device *net_dev)
goto err_build_fd;
}
 
-   if (priv->tx_tstamp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
+   if (skb->cb[0] == TX_TSTAMP)
dpaa2_eth_enable_tx_tstamp(&fd, swa);
 
/* Tracing point */
@@ -1899,10 +1905,8 @@ static int dpaa2_eth_ts_ioctl(struct net_device *dev, 
struct ifreq *rq, int cmd)
 
switch (config.tx_type) {
case HWTSTAMP_TX_OFF:
-   priv->tx_tstamp = false;
-   break;
case HWTSTAMP_TX_ON:
-   priv->tx_tstamp = true;
+   priv->tx_tstamp_type = config.tx_type;
break;
default:
return -ERANGE;
@@ -2107,7 +2111,7 @@ static int dpaa2_eth_xdp_create_fd(struct net_device 
*net_dev,
/* We require a minimum headroom to be able to transmit the frame.
 * Otherwise return an error and let the original net_device handle it
 */
-   needed_headroom = dpaa2_eth_needed_headroom(priv, NULL);
+   needed_headroom = dpaa2_eth_needed_headroom(NULL);
if (xdpf->headroom < needed_headroom)
return -EINVAL;
 
@@ -3963,6 +3967,9 @@ static int dpaa2_eth_probe(struct fsl_mc_device *dpni_dev)
 
priv->iommu_domain = iommu_get_domain_for_dev(dev);
 
+   priv->tx_tstamp_type = HWTSTAMP_TX_OFF;
+   priv->rx_tstamp = false;
+
/* Obtain a MC portal */
err = fsl_mc_portal_allocate(dpni_dev, FSL_MC_IO_ATOMIC_CONTEXT_PORTAL,
 &priv->mc_io);
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h 
b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
index 7f3c41d..57e6e6e 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
@@ -10,6 +10,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -433,8 +434,8 @@ struct dpaa2_eth_priv {
   

[PATCH 2/5] dpaa2-eth: define a global ptp_qoriq structure pointer

2020-09-10 Thread Yangbo Lu
Define a global ptp_qoriq structure pointer, and export to use.
The ptp clock operations will be used in dpaa2-eth driver.
For example, supporting one step timestamping needs to write
current time to hardware frame annotation before sending and
then hardware inserts the delay time on frame during sending.
So in driver, at least clock gettime operation will be needed
to make sure right time is written to hardware frame annotation
for one step timestamping.

Signed-off-by: Yangbo Lu 
---
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 4 
 drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c | 3 ++-
 drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.h | 4 
 3 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c 
b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index ceaf761..daf8fd4 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -30,6 +31,9 @@ MODULE_LICENSE("Dual BSD/GPL");
 MODULE_AUTHOR("Freescale Semiconductor, Inc");
 MODULE_DESCRIPTION("Freescale DPAA2 Ethernet Driver");
 
+struct ptp_qoriq *dpaa2_ptp;
+EXPORT_SYMBOL(dpaa2_ptp);
+
 static void *dpaa2_iova_to_virt(struct iommu_domain *domain,
dma_addr_t iova_addr)
 {
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c 
b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c
index cc1b7f8..32b5faa 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c
@@ -2,6 +2,7 @@
 /*
  * Copyright 2013-2016 Freescale Semiconductor Inc.
  * Copyright 2016-2018 NXP
+ * Copyright 2020 NXP
  */
 
 #include 
@@ -9,7 +10,6 @@
 #include 
 #include 
 #include 
-#include 
 
 #include "dpaa2-ptp.h"
 
@@ -201,6 +201,7 @@ static int dpaa2_ptp_probe(struct fsl_mc_device *mc_dev)
goto err_free_threaded_irq;
 
dpaa2_phc_index = ptp_qoriq->phc_index;
+   dpaa2_ptp = ptp_qoriq;
dev_set_drvdata(dev, ptp_qoriq);
 
return 0;
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.h 
b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.h
index df2458a..e102353 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.h
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.h
@@ -1,14 +1,18 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright 2018 NXP
+ * Copyright 2020 NXP
  */
 
 #ifndef __RTC_H
 #define __RTC_H
 
+#include 
+
 #include "dprtc.h"
 #include "dprtc-cmd.h"
 
 extern int dpaa2_phc_index;
+extern struct ptp_qoriq *dpaa2_ptp;
 
 #endif
-- 
2.7.4



[PATCH 3/5] dpaa2-eth: invoke dpaa2_eth_enable_tx_tstamp() once in code

2020-09-10 Thread Yangbo Lu
Invoke dpaa2_eth_enable_tx_tstamp() once in code after building FD,
rather than calling it in dpaa2_eth_build_single_fd(),
dpaa2_eth_build_sg_fd_single_buf(), and dpaa2_eth_build_sg_fd().

Signed-off-by: Yangbo Lu 
---
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 31 
 1 file changed, 16 insertions(+), 15 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c 
b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index daf8fd4..a8c311fb 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -589,7 +589,8 @@ static void dpaa2_eth_enable_tx_tstamp(struct dpaa2_fd *fd, 
void *buf_start)
 /* Create a frame descriptor based on a fragmented skb */
 static int dpaa2_eth_build_sg_fd(struct dpaa2_eth_priv *priv,
 struct sk_buff *skb,
-struct dpaa2_fd *fd)
+struct dpaa2_fd *fd,
+void **swa_addr)
 {
struct device *dev = priv->net_dev->dev.parent;
void *sgt_buf = NULL;
@@ -658,6 +659,7 @@ static int dpaa2_eth_build_sg_fd(struct dpaa2_eth_priv 
*priv,
 * skb backpointer in the software annotation area. We'll need
 * all of them on Tx Conf.
 */
+   *swa_addr = (void *)sgt_buf;
swa = (struct dpaa2_eth_swa *)sgt_buf;
swa->type = DPAA2_ETH_SWA_SG;
swa->sg.skb = skb;
@@ -677,9 +679,6 @@ static int dpaa2_eth_build_sg_fd(struct dpaa2_eth_priv 
*priv,
dpaa2_fd_set_len(fd, skb->len);
dpaa2_fd_set_ctrl(fd, FD_CTRL_PTA);
 
-   if (priv->tx_tstamp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
-   dpaa2_eth_enable_tx_tstamp(fd, sgt_buf);
-
return 0;
 
 dma_map_single_failed:
@@ -699,7 +698,8 @@ static int dpaa2_eth_build_sg_fd(struct dpaa2_eth_priv 
*priv,
  */
 static int dpaa2_eth_build_sg_fd_single_buf(struct dpaa2_eth_priv *priv,
struct sk_buff *skb,
-   struct dpaa2_fd *fd)
+   struct dpaa2_fd *fd,
+   void **swa_addr)
 {
struct device *dev = priv->net_dev->dev.parent;
struct dpaa2_eth_sgt_cache *sgt_cache;
@@ -737,6 +737,7 @@ static int dpaa2_eth_build_sg_fd_single_buf(struct 
dpaa2_eth_priv *priv,
dpaa2_sg_set_final(sgt, true);
 
/* Store the skb backpointer in the SGT buffer */
+   *swa_addr = (void *)sgt_buf;
swa = (struct dpaa2_eth_swa *)sgt_buf;
swa->type = DPAA2_ETH_SWA_SINGLE;
swa->single.skb = skb;
@@ -755,9 +756,6 @@ static int dpaa2_eth_build_sg_fd_single_buf(struct 
dpaa2_eth_priv *priv,
dpaa2_fd_set_len(fd, skb->len);
dpaa2_fd_set_ctrl(fd, FD_CTRL_PTA);
 
-   if (priv->tx_tstamp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
-   dpaa2_eth_enable_tx_tstamp(fd, sgt_buf);
-
return 0;
 
 sgt_map_failed:
@@ -774,7 +772,8 @@ static int dpaa2_eth_build_sg_fd_single_buf(struct 
dpaa2_eth_priv *priv,
 /* Create a frame descriptor based on a linear skb */
 static int dpaa2_eth_build_single_fd(struct dpaa2_eth_priv *priv,
 struct sk_buff *skb,
-struct dpaa2_fd *fd)
+struct dpaa2_fd *fd,
+void **swa_addr)
 {
struct device *dev = priv->net_dev->dev.parent;
u8 *buffer_start, *aligned_start;
@@ -795,6 +794,7 @@ static int dpaa2_eth_build_single_fd(struct dpaa2_eth_priv 
*priv,
 * (in the private data area) such that we can release it
 * on Tx confirm
 */
+   *swa_addr = (void *)buffer_start;
swa = (struct dpaa2_eth_swa *)buffer_start;
swa->type = DPAA2_ETH_SWA_SINGLE;
swa->single.skb = skb;
@@ -811,9 +811,6 @@ static int dpaa2_eth_build_single_fd(struct dpaa2_eth_priv 
*priv,
dpaa2_fd_set_format(fd, dpaa2_fd_single);
dpaa2_fd_set_ctrl(fd, FD_CTRL_PTA);
 
-   if (priv->tx_tstamp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
-   dpaa2_eth_enable_tx_tstamp(fd, buffer_start);
-
return 0;
 }
 
@@ -939,6 +936,7 @@ static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, struct 
net_device *net_dev)
u32 fd_len;
u8 prio = 0;
int err, i;
+   void *swa;
 
percpu_stats = this_cpu_ptr(priv->percpu_stats);
percpu_extras = this_cpu_ptr(priv->percpu_extras);
@@ -959,17 +957,17 @@ static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, 
struct net_device *net_dev)
memset(&fd, 0, sizeof(fd));
 
if (skb_is_nonlinear(skb)) {
-   err = dpaa2_eth_build_sg_fd(priv, skb, &fd);
+   err = dpaa2_eth_build_sg_

[PATCH 0/5] dpaa2_eth: support 1588 one-step timestamping

2020-09-10 Thread Yangbo Lu
This patch-set is to add MC APIs of 1588 one-step timestamping, and
support one-step timestamping for PTP Sync packet on DPAA2.

Before egress, one-step timestamping enablement needs,

- Enabling timestamp and FAS (Frame Annotation Status) in
  dpni buffer layout.

- Write timestamp to frame annotation and set PTP bit in
  FAS to mark as one-step timestamping event.

- Enabling one-step timestamping by dpni_set_single_step_cfg()
  API, with offset provided to insert correction time on frame.
  The offset must respect all MAC headers, VLAN tags and other
  protocol headers accordingly. The correction field update can
  consider delays up to one second. So PTP frame needs to be
  filtered and parsed, and written timestamp into Sync frame
  originTimestamp field.

The operation of API dpni_set_single_step_cfg() has to be done
when no one-step timestamping frames are in flight. So we have
to make sure the last one-step timestamping frame has already
been transmitted on hardware before starting to send the current
one. The resolution is,

- Utilize skb->cb[0] to mark timestamping request per packet.
  If it is one-step timestamping PTP sync packet, queue to skb queue.
  If not, transmit immediately.

- Schedule a work to transmit skbs in skb queue.

- mutex lock is used to ensure the last one-step timestamping packet
  has already been transmitted on hardware through TX confirmation queue
  before transmitting current packet.

Yangbo Lu (5):
  dpaa2-eth: add APIs of 1588 single step timestamping
  dpaa2-eth: define a global ptp_qoriq structure pointer
  dpaa2-eth: invoke dpaa2_eth_enable_tx_tstamp() once in code
  dpaa2-eth: utilize skb->cb[0] for hardware timestamping
  dpaa2-eth: support PTP Sync packet one-step timestamping

 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c   | 246 ++---
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h   |  43 +++-
 .../net/ethernet/freescale/dpaa2/dpaa2-ethtool.c   |   4 +-
 drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c   |   3 +-
 drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.h   |   4 +
 drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h|  21 ++
 drivers/net/ethernet/freescale/dpaa2/dpni.c|  73 ++
 drivers/net/ethernet/freescale/dpaa2/dpni.h|  31 +++
 8 files changed, 389 insertions(+), 36 deletions(-)

-- 
2.7.4



[PATCH] net: mscc: ocelot: fix hardware timestamp dequeue logic

2020-07-27 Thread Yangbo Lu
From: laurent brando 

The next hw timestamp should be snapshoot to the read registers
only once the current timestamp has been read.
If none of the pending skbs matches the current HW timestamp
just gracefully flush the available timestamp by reading it.

Signed-off-by: laurent brando 
Signed-off-by: Vladimir Oltean 
Signed-off-by: Yangbo Lu 
---
 drivers/net/ethernet/mscc/ocelot.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/mscc/ocelot.c 
b/drivers/net/ethernet/mscc/ocelot.c
index e05a48c..82bde07 100644
--- a/drivers/net/ethernet/mscc/ocelot.c
+++ b/drivers/net/ethernet/mscc/ocelot.c
@@ -731,21 +731,21 @@ void ocelot_get_txtstamp(struct ocelot *ocelot)
 
spin_unlock_irqrestore(&port->tx_skbs.lock, flags);
 
-   /* Next ts */
-   ocelot_write(ocelot, SYS_PTP_NXT_PTP_NXT, SYS_PTP_NXT);
+   /* Get the h/w timestamp */
+   ocelot_get_hwtimestamp(ocelot, &ts);
 
if (unlikely(!skb_match))
continue;
 
-   /* Get the h/w timestamp */
-   ocelot_get_hwtimestamp(ocelot, &ts);
-
/* Set the timestamp into the skb */
memset(&shhwtstamps, 0, sizeof(shhwtstamps));
shhwtstamps.hwtstamp = ktime_set(ts.tv_sec, ts.tv_nsec);
skb_tstamp_tx(skb_match, &shhwtstamps);
 
dev_kfree_skb_any(skb_match);
+
+   /* Next ts */
+   ocelot_write(ocelot, SYS_PTP_NXT_PTP_NXT, SYS_PTP_NXT);
}
 }
 EXPORT_SYMBOL(ocelot_get_txtstamp);
-- 
2.7.4



[v4] ocelot_ace: fix action of trap

2019-08-20 Thread Yangbo Lu
The trap action should be copying the frame to CPU and
dropping it for forwarding, but current setting was just
copying frame to CPU.

Fixes: b596229448dd ("net: mscc: ocelot: Add support for tcam")
Signed-off-by: Yangbo Lu 
Acked-by: Allan W. Nielsen 
---
Changes for v4:
- Added ACK and Fixes info in commit message.
Changes for v3:
- Set MASK_MODE to 1 for dropping forwarding.
- Dropped other patches of patch-set.
Changes for v2:
- None.
---
 drivers/net/ethernet/mscc/ocelot_ace.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mscc/ocelot_ace.c 
b/drivers/net/ethernet/mscc/ocelot_ace.c
index 39aca1a..86fc6e6 100644
--- a/drivers/net/ethernet/mscc/ocelot_ace.c
+++ b/drivers/net/ethernet/mscc/ocelot_ace.c
@@ -317,7 +317,7 @@ static void is2_action_set(struct vcap_data *data,
break;
case OCELOT_ACL_ACTION_TRAP:
VCAP_ACT_SET(PORT_MASK, 0x0);
-   VCAP_ACT_SET(MASK_MODE, 0x0);
+   VCAP_ACT_SET(MASK_MODE, 0x1);
VCAP_ACT_SET(POLICE_ENA, 0x0);
VCAP_ACT_SET(POLICE_IDX, 0x0);
VCAP_ACT_SET(CPU_QU_NUM, 0x0);
-- 
2.7.4



[v3] ocelot_ace: fix action of trap

2019-08-19 Thread Yangbo Lu
The trap action should be copying the frame to CPU and
dropping it for forwarding, but current setting was just
copying frame to CPU.

Signed-off-by: Yangbo Lu 
---
 drivers/net/ethernet/mscc/ocelot_ace.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mscc/ocelot_ace.c 
b/drivers/net/ethernet/mscc/ocelot_ace.c
index 39aca1a..86fc6e6 100644
--- a/drivers/net/ethernet/mscc/ocelot_ace.c
+++ b/drivers/net/ethernet/mscc/ocelot_ace.c
@@ -317,7 +317,7 @@ static void is2_action_set(struct vcap_data *data,
break;
case OCELOT_ACL_ACTION_TRAP:
VCAP_ACT_SET(PORT_MASK, 0x0);
-   VCAP_ACT_SET(MASK_MODE, 0x0);
+   VCAP_ACT_SET(MASK_MODE, 0x1);
VCAP_ACT_SET(POLICE_ENA, 0x0);
VCAP_ACT_SET(POLICE_IDX, 0x0);
VCAP_ACT_SET(CPU_QU_NUM, 0x0);
-- 
2.7.4



[v2, 2/4] ocelot_ace: fix ingress ports setting for rule

2019-08-12 Thread Yangbo Lu
The ingress ports setting of rule should support covering all ports.
This patch is to use u16 ingress_port for ingress port mask setting
for ace rule. One bit corresponds one port.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
---
 drivers/net/ethernet/mscc/ocelot_ace.c| 2 +-
 drivers/net/ethernet/mscc/ocelot_ace.h| 2 +-
 drivers/net/ethernet/mscc/ocelot_flower.c | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/mscc/ocelot_ace.c 
b/drivers/net/ethernet/mscc/ocelot_ace.c
index 5580a58..91250f3 100644
--- a/drivers/net/ethernet/mscc/ocelot_ace.c
+++ b/drivers/net/ethernet/mscc/ocelot_ace.c
@@ -352,7 +352,7 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
data.type = IS2_ACTION_TYPE_NORMAL;
 
VCAP_KEY_ANY_SET(PAG);
-   VCAP_KEY_SET(IGR_PORT_MASK, 0, ~BIT(ace->chip_port));
+   VCAP_KEY_SET(IGR_PORT_MASK, 0, ~ace->ingress_port);
VCAP_KEY_BIT_SET(FIRST, OCELOT_VCAP_BIT_1);
VCAP_KEY_BIT_SET(HOST_MATCH, OCELOT_VCAP_BIT_ANY);
VCAP_KEY_BIT_SET(L2_MC, ace->dmac_mc);
diff --git a/drivers/net/ethernet/mscc/ocelot_ace.h 
b/drivers/net/ethernet/mscc/ocelot_ace.h
index ce72f02..0fe23e0 100644
--- a/drivers/net/ethernet/mscc/ocelot_ace.h
+++ b/drivers/net/ethernet/mscc/ocelot_ace.h
@@ -193,7 +193,7 @@ struct ocelot_ace_rule {
 
enum ocelot_ace_action action;
struct ocelot_ace_stats stats;
-   int chip_port;
+   u16 ingress_port;
 
enum ocelot_vcap_bit dmac_mc;
enum ocelot_vcap_bit dmac_bc;
diff --git a/drivers/net/ethernet/mscc/ocelot_flower.c 
b/drivers/net/ethernet/mscc/ocelot_flower.c
index 7c60e8c..bfddc50 100644
--- a/drivers/net/ethernet/mscc/ocelot_flower.c
+++ b/drivers/net/ethernet/mscc/ocelot_flower.c
@@ -184,7 +184,7 @@ struct ocelot_ace_rule *ocelot_ace_rule_create(struct 
flow_cls_offload *f,
return NULL;
 
rule->ocelot = block->port->ocelot;
-   rule->chip_port = block->port->chip_port;
+   rule->ingress_port = BIT(block->port->chip_port);
return rule;
 }
 
-- 
2.7.4



[v2, 4/4] ocelot: add VCAP IS2 rule to trap PTP Ethernet frames

2019-08-12 Thread Yangbo Lu
All the PTP messages over Ethernet have etype 0x88f7 on them.
Use etype as the key to trap PTP messages.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- Added this patch.
---
 drivers/net/ethernet/mscc/ocelot.c | 28 
 1 file changed, 28 insertions(+)

diff --git a/drivers/net/ethernet/mscc/ocelot.c 
b/drivers/net/ethernet/mscc/ocelot.c
index 6932e61..40f4e0d 100644
--- a/drivers/net/ethernet/mscc/ocelot.c
+++ b/drivers/net/ethernet/mscc/ocelot.c
@@ -1681,6 +1681,33 @@ int ocelot_probe_port(struct ocelot *ocelot, u8 port,
 }
 EXPORT_SYMBOL(ocelot_probe_port);
 
+static int ocelot_ace_add_ptp_rule(struct ocelot *ocelot)
+{
+   struct ocelot_ace_rule *rule;
+
+   rule = kzalloc(sizeof(*rule), GFP_KERNEL);
+   if (!rule)
+   return -ENOMEM;
+
+   /* Entry for PTP over Ethernet (etype 0x88f7)
+* Action: trap to CPU port
+*/
+   rule->ocelot = ocelot;
+   rule->prio = 1;
+   rule->type = OCELOT_ACE_TYPE_ETYPE;
+   /* Available on all ingress port except CPU port */
+   rule->ingress_port = ~BIT(ocelot->num_phys_ports);
+   rule->dmac_mc = OCELOT_VCAP_BIT_1;
+   rule->frame.etype.etype.value[0] = 0x88;
+   rule->frame.etype.etype.value[1] = 0xf7;
+   rule->frame.etype.etype.mask[0] = 0xff;
+   rule->frame.etype.etype.mask[1] = 0xff;
+   rule->action = OCELOT_ACL_ACTION_TRAP;
+
+   ocelot_ace_rule_offload_add(rule);
+   return 0;
+}
+
 int ocelot_init(struct ocelot *ocelot)
 {
u32 port;
@@ -1708,6 +1735,7 @@ int ocelot_init(struct ocelot *ocelot)
ocelot_mact_init(ocelot);
ocelot_vlan_init(ocelot);
ocelot_ace_init(ocelot);
+   ocelot_ace_add_ptp_rule(ocelot);
 
for (port = 0; port < ocelot->num_phys_ports; port++) {
/* Clear all counters (5 groups) */
-- 
2.7.4



[v2, 3/4] ocelot_ace: fix action of trap

2019-08-12 Thread Yangbo Lu
The trap action should be copying the frame to CPU and
dropping it for forwarding, but current setting was just
copying frame to CPU.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
---
 drivers/net/ethernet/mscc/ocelot_ace.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/mscc/ocelot_ace.c 
b/drivers/net/ethernet/mscc/ocelot_ace.c
index 91250f3..59ad590 100644
--- a/drivers/net/ethernet/mscc/ocelot_ace.c
+++ b/drivers/net/ethernet/mscc/ocelot_ace.c
@@ -317,9 +317,9 @@ static void is2_action_set(struct vcap_data *data,
break;
case OCELOT_ACL_ACTION_TRAP:
VCAP_ACT_SET(PORT_MASK, 0x0);
-   VCAP_ACT_SET(MASK_MODE, 0x0);
-   VCAP_ACT_SET(POLICE_ENA, 0x0);
-   VCAP_ACT_SET(POLICE_IDX, 0x0);
+   VCAP_ACT_SET(MASK_MODE, 0x1);
+   VCAP_ACT_SET(POLICE_ENA, 0x1);
+   VCAP_ACT_SET(POLICE_IDX, OCELOT_POLICER_DISCARD);
VCAP_ACT_SET(CPU_QU_NUM, 0x0);
VCAP_ACT_SET(CPU_COPY_ENA, 0x1);
break;
-- 
2.7.4



[v2, 1/4] ocelot_ace: drop member port from ocelot_ace_rule structure

2019-08-12 Thread Yangbo Lu
The ocelot_ace_rule is not port specific. We don't need a member port
in ocelot_ace_rule structure. Drop it and use member ocelot instead.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
---
 drivers/net/ethernet/mscc/ocelot_ace.c| 12 ++--
 drivers/net/ethernet/mscc/ocelot_ace.h|  2 +-
 drivers/net/ethernet/mscc/ocelot_flower.c |  6 +++---
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/mscc/ocelot_ace.c 
b/drivers/net/ethernet/mscc/ocelot_ace.c
index 39aca1a..5580a58 100644
--- a/drivers/net/ethernet/mscc/ocelot_ace.c
+++ b/drivers/net/ethernet/mscc/ocelot_ace.c
@@ -576,7 +576,7 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
 
 static void is2_entry_get(struct ocelot_ace_rule *rule, int ix)
 {
-   struct ocelot *op = rule->port->ocelot;
+   struct ocelot *op = rule->ocelot;
struct vcap_data data;
int row = (ix / 2);
u32 cnt;
@@ -655,11 +655,11 @@ int ocelot_ace_rule_offload_add(struct ocelot_ace_rule 
*rule)
/* Move down the rules to make place for the new rule */
for (i = acl_block->count - 1; i > index; i--) {
ace = ocelot_ace_rule_get_rule_index(acl_block, i);
-   is2_entry_set(rule->port->ocelot, i, ace);
+   is2_entry_set(rule->ocelot, i, ace);
}
 
/* Now insert the new rule */
-   is2_entry_set(rule->port->ocelot, index, rule);
+   is2_entry_set(rule->ocelot, index, rule);
return 0;
 }
 
@@ -697,11 +697,11 @@ int ocelot_ace_rule_offload_del(struct ocelot_ace_rule 
*rule)
/* Move up all the blocks over the deleted rule */
for (i = index; i < acl_block->count; i++) {
ace = ocelot_ace_rule_get_rule_index(acl_block, i);
-   is2_entry_set(rule->port->ocelot, i, ace);
+   is2_entry_set(rule->ocelot, i, ace);
}
 
/* Now delete the last rule, because it is duplicated */
-   is2_entry_set(rule->port->ocelot, acl_block->count, &del_ace);
+   is2_entry_set(rule->ocelot, acl_block->count, &del_ace);
 
return 0;
 }
@@ -717,7 +717,7 @@ int ocelot_ace_rule_stats_update(struct ocelot_ace_rule 
*rule)
/* After we get the result we need to clear the counters */
tmp = ocelot_ace_rule_get_rule_index(acl_block, index);
tmp->stats.pkts = 0;
-   is2_entry_set(rule->port->ocelot, index, tmp);
+   is2_entry_set(rule->ocelot, index, tmp);
 
return 0;
 }
diff --git a/drivers/net/ethernet/mscc/ocelot_ace.h 
b/drivers/net/ethernet/mscc/ocelot_ace.h
index e98944c..ce72f02 100644
--- a/drivers/net/ethernet/mscc/ocelot_ace.h
+++ b/drivers/net/ethernet/mscc/ocelot_ace.h
@@ -186,7 +186,7 @@ struct ocelot_ace_stats {
 
 struct ocelot_ace_rule {
struct list_head list;
-   struct ocelot_port *port;
+   struct ocelot *ocelot;
 
u16 prio;
u32 id;
diff --git a/drivers/net/ethernet/mscc/ocelot_flower.c 
b/drivers/net/ethernet/mscc/ocelot_flower.c
index 59487d4..7c60e8c 100644
--- a/drivers/net/ethernet/mscc/ocelot_flower.c
+++ b/drivers/net/ethernet/mscc/ocelot_flower.c
@@ -183,7 +183,7 @@ struct ocelot_ace_rule *ocelot_ace_rule_create(struct 
flow_cls_offload *f,
if (!rule)
return NULL;
 
-   rule->port = block->port;
+   rule->ocelot = block->port->ocelot;
rule->chip_port = block->port->chip_port;
return rule;
 }
@@ -219,7 +219,7 @@ static int ocelot_flower_destroy(struct flow_cls_offload *f,
int ret;
 
rule.prio = get_prio(f->common.prio);
-   rule.port = port_block->port;
+   rule.ocelot = port_block->port->ocelot;
rule.id = f->cookie;
 
ret = ocelot_ace_rule_offload_del(&rule);
@@ -237,7 +237,7 @@ static int ocelot_flower_stats_update(struct 
flow_cls_offload *f,
int ret;
 
rule.prio = get_prio(f->common.prio);
-   rule.port = port_block->port;
+   rule.ocelot = port_block->port->ocelot;
rule.id = f->cookie;
ret = ocelot_ace_rule_stats_update(&rule);
if (ret)
-- 
2.7.4



[v2, 0/4] ocelot: support PTP Ethernet frames trapping

2019-08-12 Thread Yangbo Lu
This patch-set is to support PTP Ethernet frames trapping.
Before that, fix some issues and improve the ocelot_ace driver
for using.

---
Changes for v2:
- Added PTP Ethernet frames trapping support patch.

Yangbo Lu (4):
  ocelot_ace: drop member port from ocelot_ace_rule structure
  ocelot_ace: fix ingress ports setting for rule
  ocelot_ace: fix action of trap
  ocelot: add VCAP IS2 rule to trap PTP Ethernet frames

 drivers/net/ethernet/mscc/ocelot.c| 28 
 drivers/net/ethernet/mscc/ocelot_ace.c| 20 ++--
 drivers/net/ethernet/mscc/ocelot_ace.h|  4 ++--
 drivers/net/ethernet/mscc/ocelot_flower.c |  8 
 4 files changed, 44 insertions(+), 16 deletions(-)

-- 
2.7.4



[PATCH 1/3] ocelot_ace: drop member port from ocelot_ace_rule structure

2019-08-12 Thread Yangbo Lu
The ocelot_ace_rule is not port specific. We don't need a member port
in ocelot_ace_rule structure. Drop it and use member ocelot instead.

Signed-off-by: Yangbo Lu 
---
 drivers/net/ethernet/mscc/ocelot_ace.c| 12 ++--
 drivers/net/ethernet/mscc/ocelot_ace.h|  2 +-
 drivers/net/ethernet/mscc/ocelot_flower.c |  6 +++---
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/mscc/ocelot_ace.c 
b/drivers/net/ethernet/mscc/ocelot_ace.c
index 39aca1a..5580a58 100644
--- a/drivers/net/ethernet/mscc/ocelot_ace.c
+++ b/drivers/net/ethernet/mscc/ocelot_ace.c
@@ -576,7 +576,7 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
 
 static void is2_entry_get(struct ocelot_ace_rule *rule, int ix)
 {
-   struct ocelot *op = rule->port->ocelot;
+   struct ocelot *op = rule->ocelot;
struct vcap_data data;
int row = (ix / 2);
u32 cnt;
@@ -655,11 +655,11 @@ int ocelot_ace_rule_offload_add(struct ocelot_ace_rule 
*rule)
/* Move down the rules to make place for the new rule */
for (i = acl_block->count - 1; i > index; i--) {
ace = ocelot_ace_rule_get_rule_index(acl_block, i);
-   is2_entry_set(rule->port->ocelot, i, ace);
+   is2_entry_set(rule->ocelot, i, ace);
}
 
/* Now insert the new rule */
-   is2_entry_set(rule->port->ocelot, index, rule);
+   is2_entry_set(rule->ocelot, index, rule);
return 0;
 }
 
@@ -697,11 +697,11 @@ int ocelot_ace_rule_offload_del(struct ocelot_ace_rule 
*rule)
/* Move up all the blocks over the deleted rule */
for (i = index; i < acl_block->count; i++) {
ace = ocelot_ace_rule_get_rule_index(acl_block, i);
-   is2_entry_set(rule->port->ocelot, i, ace);
+   is2_entry_set(rule->ocelot, i, ace);
}
 
/* Now delete the last rule, because it is duplicated */
-   is2_entry_set(rule->port->ocelot, acl_block->count, &del_ace);
+   is2_entry_set(rule->ocelot, acl_block->count, &del_ace);
 
return 0;
 }
@@ -717,7 +717,7 @@ int ocelot_ace_rule_stats_update(struct ocelot_ace_rule 
*rule)
/* After we get the result we need to clear the counters */
tmp = ocelot_ace_rule_get_rule_index(acl_block, index);
tmp->stats.pkts = 0;
-   is2_entry_set(rule->port->ocelot, index, tmp);
+   is2_entry_set(rule->ocelot, index, tmp);
 
return 0;
 }
diff --git a/drivers/net/ethernet/mscc/ocelot_ace.h 
b/drivers/net/ethernet/mscc/ocelot_ace.h
index e98944c..ce72f02 100644
--- a/drivers/net/ethernet/mscc/ocelot_ace.h
+++ b/drivers/net/ethernet/mscc/ocelot_ace.h
@@ -186,7 +186,7 @@ struct ocelot_ace_stats {
 
 struct ocelot_ace_rule {
struct list_head list;
-   struct ocelot_port *port;
+   struct ocelot *ocelot;
 
u16 prio;
u32 id;
diff --git a/drivers/net/ethernet/mscc/ocelot_flower.c 
b/drivers/net/ethernet/mscc/ocelot_flower.c
index 59487d4..7c60e8c 100644
--- a/drivers/net/ethernet/mscc/ocelot_flower.c
+++ b/drivers/net/ethernet/mscc/ocelot_flower.c
@@ -183,7 +183,7 @@ struct ocelot_ace_rule *ocelot_ace_rule_create(struct 
flow_cls_offload *f,
if (!rule)
return NULL;
 
-   rule->port = block->port;
+   rule->ocelot = block->port->ocelot;
rule->chip_port = block->port->chip_port;
return rule;
 }
@@ -219,7 +219,7 @@ static int ocelot_flower_destroy(struct flow_cls_offload *f,
int ret;
 
rule.prio = get_prio(f->common.prio);
-   rule.port = port_block->port;
+   rule.ocelot = port_block->port->ocelot;
rule.id = f->cookie;
 
ret = ocelot_ace_rule_offload_del(&rule);
@@ -237,7 +237,7 @@ static int ocelot_flower_stats_update(struct 
flow_cls_offload *f,
int ret;
 
rule.prio = get_prio(f->common.prio);
-   rule.port = port_block->port;
+   rule.ocelot = port_block->port->ocelot;
rule.id = f->cookie;
ret = ocelot_ace_rule_stats_update(&rule);
if (ret)
-- 
2.7.4



[PATCH 2/3] ocelot_ace: fix ingress ports setting for rule

2019-08-12 Thread Yangbo Lu
The ingress ports setting of rule should support covering all ports.
This patch is to use u16 ingress_port for ingress port mask setting
for ace rule. One bit corresponds one port.

Signed-off-by: Yangbo Lu 
---
 drivers/net/ethernet/mscc/ocelot_ace.c| 2 +-
 drivers/net/ethernet/mscc/ocelot_ace.h| 2 +-
 drivers/net/ethernet/mscc/ocelot_flower.c | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/mscc/ocelot_ace.c 
b/drivers/net/ethernet/mscc/ocelot_ace.c
index 5580a58..91250f3 100644
--- a/drivers/net/ethernet/mscc/ocelot_ace.c
+++ b/drivers/net/ethernet/mscc/ocelot_ace.c
@@ -352,7 +352,7 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
data.type = IS2_ACTION_TYPE_NORMAL;
 
VCAP_KEY_ANY_SET(PAG);
-   VCAP_KEY_SET(IGR_PORT_MASK, 0, ~BIT(ace->chip_port));
+   VCAP_KEY_SET(IGR_PORT_MASK, 0, ~ace->ingress_port);
VCAP_KEY_BIT_SET(FIRST, OCELOT_VCAP_BIT_1);
VCAP_KEY_BIT_SET(HOST_MATCH, OCELOT_VCAP_BIT_ANY);
VCAP_KEY_BIT_SET(L2_MC, ace->dmac_mc);
diff --git a/drivers/net/ethernet/mscc/ocelot_ace.h 
b/drivers/net/ethernet/mscc/ocelot_ace.h
index ce72f02..0fe23e0 100644
--- a/drivers/net/ethernet/mscc/ocelot_ace.h
+++ b/drivers/net/ethernet/mscc/ocelot_ace.h
@@ -193,7 +193,7 @@ struct ocelot_ace_rule {
 
enum ocelot_ace_action action;
struct ocelot_ace_stats stats;
-   int chip_port;
+   u16 ingress_port;
 
enum ocelot_vcap_bit dmac_mc;
enum ocelot_vcap_bit dmac_bc;
diff --git a/drivers/net/ethernet/mscc/ocelot_flower.c 
b/drivers/net/ethernet/mscc/ocelot_flower.c
index 7c60e8c..bfddc50 100644
--- a/drivers/net/ethernet/mscc/ocelot_flower.c
+++ b/drivers/net/ethernet/mscc/ocelot_flower.c
@@ -184,7 +184,7 @@ struct ocelot_ace_rule *ocelot_ace_rule_create(struct 
flow_cls_offload *f,
return NULL;
 
rule->ocelot = block->port->ocelot;
-   rule->chip_port = block->port->chip_port;
+   rule->ingress_port = BIT(block->port->chip_port);
return rule;
 }
 
-- 
2.7.4



[PATCH 0/3] ocelot_ace: fix and improve the driver

2019-08-12 Thread Yangbo Lu
This patch-set is to fix some issues and improve the ocelot_ace driver
for using.

Yangbo Lu (3):
  ocelot_ace: drop member port from ocelot_ace_rule structure
  ocelot_ace: fix ingress ports setting for rule
  ocelot_ace: fix action of trap

 drivers/net/ethernet/mscc/ocelot_ace.c| 20 ++--
 drivers/net/ethernet/mscc/ocelot_ace.h|  4 ++--
 drivers/net/ethernet/mscc/ocelot_flower.c |  8 
 3 files changed, 16 insertions(+), 16 deletions(-)

-- 
2.7.4



[PATCH 3/3] ocelot_ace: fix action of trap

2019-08-12 Thread Yangbo Lu
The trap action should be copying the frame to CPU and
dropping it for forwarding, but current setting was just
copying frame to CPU.

Signed-off-by: Yangbo Lu 
---
 drivers/net/ethernet/mscc/ocelot_ace.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/mscc/ocelot_ace.c 
b/drivers/net/ethernet/mscc/ocelot_ace.c
index 91250f3..59ad590 100644
--- a/drivers/net/ethernet/mscc/ocelot_ace.c
+++ b/drivers/net/ethernet/mscc/ocelot_ace.c
@@ -317,9 +317,9 @@ static void is2_action_set(struct vcap_data *data,
break;
case OCELOT_ACL_ACTION_TRAP:
VCAP_ACT_SET(PORT_MASK, 0x0);
-   VCAP_ACT_SET(MASK_MODE, 0x0);
-   VCAP_ACT_SET(POLICE_ENA, 0x0);
-   VCAP_ACT_SET(POLICE_IDX, 0x0);
+   VCAP_ACT_SET(MASK_MODE, 0x1);
+   VCAP_ACT_SET(POLICE_ENA, 0x1);
+   VCAP_ACT_SET(POLICE_IDX, OCELOT_POLICER_DISCARD);
VCAP_ACT_SET(CPU_QU_NUM, 0x0);
VCAP_ACT_SET(CPU_COPY_ENA, 0x1);
break;
-- 
2.7.4



[v3, 9/9] MAINTAINERS: add enetc_ptp driver into QorIQ PTP list

2019-02-11 Thread Yangbo Lu
This patch to add enetc_ptp driver into QorIQ PTP list
for maintaining.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
Changes for v3:
- None.
---
 MAINTAINERS |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 604bca2..d6a8475 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6104,6 +6104,7 @@ FREESCALE QORIQ PTP CLOCK DRIVER
 M: Yangbo Lu 
 L: netdev@vger.kernel.org
 S: Maintained
+F: drivers/net/ethernet/freescale/enetc/enetc_ptp.c
 F: drivers/ptp/ptp_qoriq.c
 F: drivers/ptp/ptp_qoriq_debugfs.c
 F: include/linux/fsl/ptp_qoriq.h
-- 
1.7.1



[v3, 6/9] ptp_qoriq: fix register memory map

2019-02-11 Thread Yangbo Lu
The 1588 timer on eTSEC Ethernet controller uses different
register memory map with DPAA Ethernet controller.
Now the new ENETC Ethernet controller uses same reigster
memory map with DPAA. To support ENETC, let's use register
memory map of DPAA/ENETC in default.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
Changes for v3:
- None.
---
 drivers/ptp/ptp_qoriq.c   |   11 ++-
 include/linux/fsl/ptp_qoriq.h |   16 
 2 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/drivers/ptp/ptp_qoriq.c b/drivers/ptp/ptp_qoriq.c
index ed4dc39..42d3654 100644
--- a/drivers/ptp/ptp_qoriq.c
+++ b/drivers/ptp/ptp_qoriq.c
@@ -504,11 +504,12 @@ int ptp_qoriq_init(struct ptp_qoriq *ptp_qoriq, void 
__iomem *base,
ptp_qoriq->write = qoriq_write_be;
}
 
-   if (of_device_is_compatible(node, "fsl,fman-ptp-timer")) {
-   ptp_qoriq->regs.ctrl_regs = base + FMAN_CTRL_REGS_OFFSET;
-   ptp_qoriq->regs.alarm_regs = base + FMAN_ALARM_REGS_OFFSET;
-   ptp_qoriq->regs.fiper_regs = base + FMAN_FIPER_REGS_OFFSET;
-   ptp_qoriq->regs.etts_regs = base + FMAN_ETTS_REGS_OFFSET;
+   /* The eTSEC uses differnt memory map with DPAA/ENETC */
+   if (of_device_is_compatible(node, "fsl,etsec-ptp")) {
+   ptp_qoriq->regs.ctrl_regs = base + ETSEC_CTRL_REGS_OFFSET;
+   ptp_qoriq->regs.alarm_regs = base + ETSEC_ALARM_REGS_OFFSET;
+   ptp_qoriq->regs.fiper_regs = base + ETSEC_FIPER_REGS_OFFSET;
+   ptp_qoriq->regs.etts_regs = base + ETSEC_ETTS_REGS_OFFSET;
} else {
ptp_qoriq->regs.ctrl_regs = base + CTRL_REGS_OFFSET;
ptp_qoriq->regs.alarm_regs = base + ALARM_REGS_OFFSET;
diff --git a/include/linux/fsl/ptp_qoriq.h b/include/linux/fsl/ptp_qoriq.h
index 1f8bb6a..f127adb 100644
--- a/include/linux/fsl/ptp_qoriq.h
+++ b/include/linux/fsl/ptp_qoriq.h
@@ -58,15 +58,15 @@ struct ptp_qoriq_registers {
 };
 
 /* Offset definitions for the four register groups */
-#define CTRL_REGS_OFFSET   0x0
-#define ALARM_REGS_OFFSET  0x40
-#define FIPER_REGS_OFFSET  0x80
-#define ETTS_REGS_OFFSET   0xa0
-
-#define FMAN_CTRL_REGS_OFFSET  0x80
-#define FMAN_ALARM_REGS_OFFSET 0xb8
-#define FMAN_FIPER_REGS_OFFSET 0xd0
-#define FMAN_ETTS_REGS_OFFSET  0xe0
+#define ETSEC_CTRL_REGS_OFFSET 0x0
+#define ETSEC_ALARM_REGS_OFFSET0x40
+#define ETSEC_FIPER_REGS_OFFSET0x80
+#define ETSEC_ETTS_REGS_OFFSET 0xa0
+
+#define CTRL_REGS_OFFSET   0x80
+#define ALARM_REGS_OFFSET  0xb8
+#define FIPER_REGS_OFFSET  0xd0
+#define ETTS_REGS_OFFSET   0xe0
 
 
 /* Bit definitions for the TMR_CTRL register */
-- 
1.7.1



[v3, 8/9] enetc: add PTP clock driver

2019-02-11 Thread Yangbo Lu
This patch is to add PTP clock driver for ENETC.
The driver reused QorIQ PTP clock driver.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
Changes for v3:
- Converted to use ptp_qoriq_free().
---
 drivers/net/ethernet/freescale/enetc/Kconfig |   12 ++
 drivers/net/ethernet/freescale/enetc/Makefile|3 +
 drivers/net/ethernet/freescale/enetc/enetc_hw.h  |5 +-
 drivers/net/ethernet/freescale/enetc/enetc_ptp.c |  144 ++
 4 files changed, 162 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/ethernet/freescale/enetc/enetc_ptp.c

diff --git a/drivers/net/ethernet/freescale/enetc/Kconfig 
b/drivers/net/ethernet/freescale/enetc/Kconfig
index f9dd26f..8429f5c 100644
--- a/drivers/net/ethernet/freescale/enetc/Kconfig
+++ b/drivers/net/ethernet/freescale/enetc/Kconfig
@@ -17,3 +17,15 @@ config FSL_ENETC_VF
  virtual function (VF) devices enabled by the ENETC PF driver.
 
  If compiled as module (M), the module name is fsl-enetc-vf.
+
+config FSL_ENETC_PTP_CLOCK
+   tristate "ENETC PTP clock driver"
+   depends on PTP_1588_CLOCK_QORIQ && (FSL_ENETC || FSL_ENETC_VF)
+   default y
+   help
+ This driver adds support for using the ENETC 1588 timer
+ as a PTP clock. This clock is only useful if your PTP
+ programs are getting hardware time stamps on the PTP Ethernet
+ packets using the SO_TIMESTAMPING API.
+
+ If compiled as module (M), the module name is fsl-enetc-ptp.
diff --git a/drivers/net/ethernet/freescale/enetc/Makefile 
b/drivers/net/ethernet/freescale/enetc/Makefile
index 9529b01..6976602 100644
--- a/drivers/net/ethernet/freescale/enetc/Makefile
+++ b/drivers/net/ethernet/freescale/enetc/Makefile
@@ -13,3 +13,6 @@ fsl-enetc-vf-$(CONFIG_FSL_ENETC_VF) += enetc.o enetc_cbdr.o \
   enetc_ethtool.o
 fsl-enetc-vf-objs := enetc_vf.o $(fsl-enetc-vf-y)
 endif
+
+obj-$(CONFIG_FSL_ENETC_PTP_CLOCK) += fsl-enetc-ptp.o
+fsl-enetc-ptp-$(CONFIG_FSL_ENETC_PTP_CLOCK) += enetc_ptp.o
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_hw.h 
b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
index efa0b1a..df8eb88 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
@@ -4,8 +4,9 @@
 #include 
 
 /* ENETC device IDs */
-#define ENETC_DEV_ID_PF0xe100
-#define ENETC_DEV_ID_VF0xef00
+#define ENETC_DEV_ID_PF0xe100
+#define ENETC_DEV_ID_VF0xef00
+#define ENETC_DEV_ID_PTP   0xee02
 
 /* ENETC register block BAR */
 #define ENETC_BAR_REGS 0
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_ptp.c 
b/drivers/net/ethernet/freescale/enetc/enetc_ptp.c
new file mode 100644
index 000..dc2f58a
--- /dev/null
+++ b/drivers/net/ethernet/freescale/enetc/enetc_ptp.c
@@ -0,0 +1,144 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/* Copyright 2019 NXP */
+
+#include 
+#include 
+#include 
+
+#include "enetc.h"
+
+static struct ptp_clock_info enetc_ptp_caps = {
+   .owner  = THIS_MODULE,
+   .name   = "ENETC PTP clock",
+   .max_adj= 512000,
+   .n_alarm= 0,
+   .n_ext_ts   = 2,
+   .n_per_out  = 0,
+   .n_pins = 0,
+   .pps= 1,
+   .adjfine= ptp_qoriq_adjfine,
+   .adjtime= ptp_qoriq_adjtime,
+   .gettime64  = ptp_qoriq_gettime,
+   .settime64  = ptp_qoriq_settime,
+   .enable = ptp_qoriq_enable,
+};
+
+static int enetc_ptp_probe(struct pci_dev *pdev,
+  const struct pci_device_id *ent)
+{
+   struct ptp_qoriq *ptp_qoriq;
+   void __iomem *base;
+   int err, len, n;
+
+   if (pdev->dev.of_node && !of_device_is_available(pdev->dev.of_node)) {
+   dev_info(&pdev->dev, "device is disabled, skipping\n");
+   return -ENODEV;
+   }
+
+   err = pci_enable_device_mem(pdev);
+   if (err) {
+   dev_err(&pdev->dev, "device enable failed\n");
+   return err;
+   }
+
+   /* set up for high or low dma */
+   err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
+   if (err) {
+   err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+   if (err) {
+   dev_err(&pdev->dev,
+   "DMA configuration failed: 0x%x\n", err);
+   goto err_dma;
+   }
+   }
+
+   err = pci_request_mem_regions(pdev, KBUILD_MODNAME);
+   if (err) {
+   dev_err(&pdev->dev, "pci_request_regions failed err=%d\n", err);
+   goto err_pci_mem_reg;
+   }
+
+   pci_set_master(pdev);
+
+   ptp_qoriq = kzalloc(sizeof(*ptp_qor

[v3, 7/9] ptp: add QorIQ PTP support for ENETC

2019-02-11 Thread Yangbo Lu
This patch is to add QorIQ PTP support for ENETC.
ENETC PTP driver which is a PCI driver for same
1588 timer IP block will reuse QorIQ PTP driver.

Signed-off-by: Yangbo Lu 
---
Chanbges for v2:
- None.
Chanbges for v3:
- None.
---
 drivers/ptp/Kconfig |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/ptp/Kconfig b/drivers/ptp/Kconfig
index aeb4a8b..7fe1863 100644
--- a/drivers/ptp/Kconfig
+++ b/drivers/ptp/Kconfig
@@ -43,7 +43,7 @@ config PTP_1588_CLOCK_DTE
 
 config PTP_1588_CLOCK_QORIQ
tristate "Freescale QorIQ 1588 timer as PTP clock"
-   depends on GIANFAR || FSL_DPAA_ETH
+   depends on GIANFAR || FSL_DPAA_ETH || FSL_ENETC || FSL_ENETC_VF
depends on PTP_1588_CLOCK
default y
help
-- 
1.7.1



[v3, 4/9] ptp_qoriq: add little enadian support

2019-02-11 Thread Yangbo Lu
There is QorIQ 1588 timer IP block on the new ENETC Ethernet
controller. However it uses little endian mode which is different
with before. This patch is to add little endian support for the
driver by using "little-endian" dts node property.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
Changes for v3:
- Rebased.
---
 drivers/ptp/ptp_qoriq.c |   69 ++-
 drivers/ptp/ptp_qoriq_debugfs.c |   12 +++---
 include/linux/fsl/ptp_qoriq.h   |   21 ---
 3 files changed, 60 insertions(+), 42 deletions(-)

diff --git a/drivers/ptp/ptp_qoriq.c b/drivers/ptp/ptp_qoriq.c
index db4f929..ed4dc39 100644
--- a/drivers/ptp/ptp_qoriq.c
+++ b/drivers/ptp/ptp_qoriq.c
@@ -43,8 +43,8 @@ static u64 tmr_cnt_read(struct ptp_qoriq *ptp_qoriq)
u64 ns;
u32 lo, hi;
 
-   lo = qoriq_read(®s->ctrl_regs->tmr_cnt_l);
-   hi = qoriq_read(®s->ctrl_regs->tmr_cnt_h);
+   lo = ptp_qoriq->read(®s->ctrl_regs->tmr_cnt_l);
+   hi = ptp_qoriq->read(®s->ctrl_regs->tmr_cnt_h);
ns = ((u64) hi) << 32;
ns |= lo;
return ns;
@@ -57,8 +57,8 @@ static void tmr_cnt_write(struct ptp_qoriq *ptp_qoriq, u64 ns)
u32 hi = ns >> 32;
u32 lo = ns & 0x;
 
-   qoriq_write(®s->ctrl_regs->tmr_cnt_l, lo);
-   qoriq_write(®s->ctrl_regs->tmr_cnt_h, hi);
+   ptp_qoriq->write(®s->ctrl_regs->tmr_cnt_l, lo);
+   ptp_qoriq->write(®s->ctrl_regs->tmr_cnt_h, hi);
 }
 
 /* Caller must hold ptp_qoriq->lock. */
@@ -73,8 +73,8 @@ static void set_alarm(struct ptp_qoriq *ptp_qoriq)
ns -= ptp_qoriq->tclk_period;
hi = ns >> 32;
lo = ns & 0x;
-   qoriq_write(®s->alarm_regs->tmr_alarm1_l, lo);
-   qoriq_write(®s->alarm_regs->tmr_alarm1_h, hi);
+   ptp_qoriq->write(®s->alarm_regs->tmr_alarm1_l, lo);
+   ptp_qoriq->write(®s->alarm_regs->tmr_alarm1_h, hi);
 }
 
 /* Caller must hold ptp_qoriq->lock. */
@@ -83,8 +83,8 @@ static void set_fipers(struct ptp_qoriq *ptp_qoriq)
struct ptp_qoriq_registers *regs = &ptp_qoriq->regs;
 
set_alarm(ptp_qoriq);
-   qoriq_write(®s->fiper_regs->tmr_fiper1, ptp_qoriq->tmr_fiper1);
-   qoriq_write(®s->fiper_regs->tmr_fiper2, ptp_qoriq->tmr_fiper2);
+   ptp_qoriq->write(®s->fiper_regs->tmr_fiper1, ptp_qoriq->tmr_fiper1);
+   ptp_qoriq->write(®s->fiper_regs->tmr_fiper2, ptp_qoriq->tmr_fiper2);
 }
 
 static int extts_clean_up(struct ptp_qoriq *ptp_qoriq, int index,
@@ -115,8 +115,8 @@ static int extts_clean_up(struct ptp_qoriq *ptp_qoriq, int 
index,
event.index = index;
 
do {
-   lo = qoriq_read(reg_etts_l);
-   hi = qoriq_read(reg_etts_h);
+   lo = ptp_qoriq->read(reg_etts_l);
+   hi = ptp_qoriq->read(reg_etts_h);
 
if (update_event) {
event.timestamp = ((u64) hi) << 32;
@@ -124,7 +124,7 @@ static int extts_clean_up(struct ptp_qoriq *ptp_qoriq, int 
index,
ptp_clock_event(ptp_qoriq->clock, &event);
}
 
-   stat = qoriq_read(®s->ctrl_regs->tmr_stat);
+   stat = ptp_qoriq->read(®s->ctrl_regs->tmr_stat);
} while (ptp_qoriq->extts_fifo_support && (stat & valid));
 
return 0;
@@ -144,8 +144,8 @@ irqreturn_t ptp_qoriq_isr(int irq, void *priv)
 
spin_lock(&ptp_qoriq->lock);
 
-   val = qoriq_read(®s->ctrl_regs->tmr_tevent);
-   mask = qoriq_read(®s->ctrl_regs->tmr_temask);
+   val = ptp_qoriq->read(®s->ctrl_regs->tmr_tevent);
+   mask = ptp_qoriq->read(®s->ctrl_regs->tmr_temask);
 
spin_unlock(&ptp_qoriq->lock);
 
@@ -173,14 +173,14 @@ irqreturn_t ptp_qoriq_isr(int irq, void *priv)
ns = ptp_qoriq->alarm_value + ptp_qoriq->alarm_interval;
hi = ns >> 32;
lo = ns & 0x;
-   qoriq_write(®s->alarm_regs->tmr_alarm2_l, lo);
-   qoriq_write(®s->alarm_regs->tmr_alarm2_h, hi);
+   ptp_qoriq->write(®s->alarm_regs->tmr_alarm2_l, lo);
+   ptp_qoriq->write(®s->alarm_regs->tmr_alarm2_h, hi);
ptp_qoriq->alarm_value = ns;
} else {
spin_lock(&ptp_qoriq->lock);
-   mask = qoriq_read(®s->ctrl_regs->tmr_temask);
+   mask = ptp_qoriq->read(®s->ctrl_regs->tmr_temask);
mask &= ~ALM2EN;
-   qoriq_write(®s->ctrl_regs->tmr_temask, mask);
+   ptp_qoriq-&

[v3, 0/9] Add ENETC PTP clock driver

2019-02-11 Thread Yangbo Lu
There is same QorIQ 1588 timer IP block on the new ENETC Ethernet
controller with eTSEC/DPAA Ethernet controllers. However it's
different endianness (little-endian) and using PCI driver.

To support ENETC PTP driver, ptp_qoriq driver needed to be
reworked to make functions global for reusing, to add little-
endian support, to add ENETC memory map support, and to add
ENETC dependency for ptp_qoriq driver.

In addition, although ENETC PTP driver is a PCI driver, the dts
node still could be used. Currently the ls1028a dtsi which is
the only platform by now using ENETC is not complete, so there
is still dependency for ENETC PTP node upstreaming. This will
be done in the near future. The hardware timestamping support
for ENETC is done but needs to be reworked with new method in
internal git tree, and will be sent out soon.

Yangbo Lu (9):
  ptp_qoriq: make structure/function names more consistent
  ptp_qoriq: make ptp operations global
  ptp_qoriq: convert to use ptp_qoriq_init/free
  ptp_qoriq: add little enadian support
  dt-binding: ptp_qoriq: add little-endian support
  ptp_qoriq: fix register memory map
  ptp: add QorIQ PTP support for ENETC
  enetc: add PTP clock driver
  MAINTAINERS: add enetc_ptp driver into QorIQ PTP list

 .../devicetree/bindings/ptp/ptp-qoriq.txt  |3 +
 MAINTAINERS|1 +
 drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c |2 +-
 drivers/net/ethernet/freescale/enetc/Kconfig   |   12 +
 drivers/net/ethernet/freescale/enetc/Makefile  |3 +
 drivers/net/ethernet/freescale/enetc/enetc_hw.h|5 +-
 drivers/net/ethernet/freescale/enetc/enetc_ptp.c   |  144 +++
 drivers/net/ethernet/freescale/gianfar_ethtool.c   |2 +-
 drivers/ptp/Kconfig|2 +-
 drivers/ptp/ptp_qoriq.c|  437 +++-
 drivers/ptp/ptp_qoriq_debugfs.c|   48 ++--
 include/linux/fsl/ptp_qoriq.h  |   63 ++-
 12 files changed, 466 insertions(+), 256 deletions(-)
 create mode 100644 drivers/net/ethernet/freescale/enetc/enetc_ptp.c



[v3, 5/9] dt-binding: ptp_qoriq: add little-endian support

2019-02-11 Thread Yangbo Lu
Specify "little-endian" property if the 1588 timer IP block
is little-endian mode. The default endian mode is big-endian.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
Changes for v3:
- None.
---
 .../devicetree/bindings/ptp/ptp-qoriq.txt  |3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/Documentation/devicetree/bindings/ptp/ptp-qoriq.txt 
b/Documentation/devicetree/bindings/ptp/ptp-qoriq.txt
index 8e7f855..454c937 100644
--- a/Documentation/devicetree/bindings/ptp/ptp-qoriq.txt
+++ b/Documentation/devicetree/bindings/ptp/ptp-qoriq.txt
@@ -19,6 +19,9 @@ Clock Properties:
   - fsl,max-adj  Maximum frequency adjustment in parts per billion.
   - fsl,extts-fifo   The presence of this property indicates hardware
 support for the external trigger stamp FIFO.
+  - little-endianThe presence of this property indicates the 1588 timer
+IP block is little-endian mode. The default endian mode
+is big-endian.
 
   These properties set the operational parameters for the PTP
   clock. You must choose these carefully for the clock to work right.
-- 
1.7.1



[v3, 1/9] ptp_qoriq: make structure/function names more consistent

2019-02-11 Thread Yangbo Lu
Strings containing "ptp_qoriq" or "qoriq_ptp" which were used for
structure/function names were complained by users. Let's just use
the unique "ptp_qoriq" to make these names more consistent.
This patch is just to unify the names using "ptp_qoriq". It hasn't
changed any functions.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- Fixed build issue in gianfar/dpaa ethtool driver.
Changes for v3:
- None.
---
 drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c |2 +-
 drivers/net/ethernet/freescale/gianfar_ethtool.c   |2 +-
 drivers/ptp/ptp_qoriq.c|  288 ++--
 drivers/ptp/ptp_qoriq_debugfs.c|   36 ++--
 include/linux/fsl/ptp_qoriq.h  |   14 +-
 5 files changed, 171 insertions(+), 171 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
index 6249711..bdee441 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
@@ -501,7 +501,7 @@ static int dpaa_get_ts_info(struct net_device *net_dev,
struct device_node *mac_node = dev->of_node;
struct device_node *fman_node = NULL, *ptp_node = NULL;
struct platform_device *ptp_dev = NULL;
-   struct qoriq_ptp *ptp = NULL;
+   struct ptp_qoriq *ptp = NULL;
 
info->phc_index = -1;
 
diff --git a/drivers/net/ethernet/freescale/gianfar_ethtool.c 
b/drivers/net/ethernet/freescale/gianfar_ethtool.c
index 241325c..27ed995 100644
--- a/drivers/net/ethernet/freescale/gianfar_ethtool.c
+++ b/drivers/net/ethernet/freescale/gianfar_ethtool.c
@@ -1492,7 +1492,7 @@ static int gfar_get_ts_info(struct net_device *dev,
struct gfar_private *priv = netdev_priv(dev);
struct platform_device *ptp_dev;
struct device_node *ptp_node;
-   struct qoriq_ptp *ptp = NULL;
+   struct ptp_qoriq *ptp = NULL;
 
info->phc_index = -1;
 
diff --git a/drivers/ptp/ptp_qoriq.c b/drivers/ptp/ptp_qoriq.c
index 43416b2..8c10d0f 100644
--- a/drivers/ptp/ptp_qoriq.c
+++ b/drivers/ptp/ptp_qoriq.c
@@ -37,10 +37,10 @@
  * Register access functions
  */
 
-/* Caller must hold qoriq_ptp->lock. */
-static u64 tmr_cnt_read(struct qoriq_ptp *qoriq_ptp)
+/* Caller must hold ptp_qoriq->lock. */
+static u64 tmr_cnt_read(struct ptp_qoriq *ptp_qoriq)
 {
-   struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
+   struct ptp_qoriq_registers *regs = &ptp_qoriq->regs;
u64 ns;
u32 lo, hi;
 
@@ -51,10 +51,10 @@ static u64 tmr_cnt_read(struct qoriq_ptp *qoriq_ptp)
return ns;
 }
 
-/* Caller must hold qoriq_ptp->lock. */
-static void tmr_cnt_write(struct qoriq_ptp *qoriq_ptp, u64 ns)
+/* Caller must hold ptp_qoriq->lock. */
+static void tmr_cnt_write(struct ptp_qoriq *ptp_qoriq, u64 ns)
 {
-   struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
+   struct ptp_qoriq_registers *regs = &ptp_qoriq->regs;
u32 hi = ns >> 32;
u32 lo = ns & 0x;
 
@@ -62,36 +62,36 @@ static void tmr_cnt_write(struct qoriq_ptp *qoriq_ptp, u64 
ns)
qoriq_write(®s->ctrl_regs->tmr_cnt_h, hi);
 }
 
-/* Caller must hold qoriq_ptp->lock. */
-static void set_alarm(struct qoriq_ptp *qoriq_ptp)
+/* Caller must hold ptp_qoriq->lock. */
+static void set_alarm(struct ptp_qoriq *ptp_qoriq)
 {
-   struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
+   struct ptp_qoriq_registers *regs = &ptp_qoriq->regs;
u64 ns;
u32 lo, hi;
 
-   ns = tmr_cnt_read(qoriq_ptp) + 15ULL;
+   ns = tmr_cnt_read(ptp_qoriq) + 15ULL;
ns = div_u64(ns, 10UL) * 10ULL;
-   ns -= qoriq_ptp->tclk_period;
+   ns -= ptp_qoriq->tclk_period;
hi = ns >> 32;
lo = ns & 0x;
qoriq_write(®s->alarm_regs->tmr_alarm1_l, lo);
qoriq_write(®s->alarm_regs->tmr_alarm1_h, hi);
 }
 
-/* Caller must hold qoriq_ptp->lock. */
-static void set_fipers(struct qoriq_ptp *qoriq_ptp)
+/* Caller must hold ptp_qoriq->lock. */
+static void set_fipers(struct ptp_qoriq *ptp_qoriq)
 {
-   struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
+   struct ptp_qoriq_registers *regs = &ptp_qoriq->regs;
 
-   set_alarm(qoriq_ptp);
-   qoriq_write(®s->fiper_regs->tmr_fiper1, qoriq_ptp->tmr_fiper1);
-   qoriq_write(®s->fiper_regs->tmr_fiper2, qoriq_ptp->tmr_fiper2);
+   set_alarm(ptp_qoriq);
+   qoriq_write(®s->fiper_regs->tmr_fiper1, ptp_qoriq->tmr_fiper1);
+   qoriq_write(®s->fiper_regs->tmr_fiper2, ptp_qoriq->tmr_fiper2);
 }
 
-static int extts_clean_up(struct qoriq_ptp *qoriq_ptp, int index,
+static int extts_clean_up(struct ptp_qoriq *ptp_qoriq, int index,
 

[v3, 2/9] ptp_qoriq: make ptp operations global

2019-02-11 Thread Yangbo Lu
This patch is to make functions of ptp operations global,
so that ENETC PTP driver which is a PCI driver for same
1588 timer IP block could reuse them.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
Changes for v3:
- None.
---
 drivers/ptp/ptp_qoriq.c   |   27 ---
 include/linux/fsl/ptp_qoriq.h |9 +
 2 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/drivers/ptp/ptp_qoriq.c b/drivers/ptp/ptp_qoriq.c
index 8c10d0f..1f3e73e 100644
--- a/drivers/ptp/ptp_qoriq.c
+++ b/drivers/ptp/ptp_qoriq.c
@@ -22,7 +22,6 @@
 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -135,7 +134,7 @@ static int extts_clean_up(struct ptp_qoriq *ptp_qoriq, int 
index,
  * Interrupt service routine
  */
 
-static irqreturn_t isr(int irq, void *priv)
+irqreturn_t ptp_qoriq_isr(int irq, void *priv)
 {
struct ptp_qoriq *ptp_qoriq = priv;
struct ptp_qoriq_registers *regs = &ptp_qoriq->regs;
@@ -200,12 +199,13 @@ static irqreturn_t isr(int irq, void *priv)
} else
return IRQ_NONE;
 }
+EXPORT_SYMBOL_GPL(ptp_qoriq_isr);
 
 /*
  * PTP clock operations
  */
 
-static int ptp_qoriq_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
+int ptp_qoriq_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
 {
u64 adj, diff;
u32 tmr_add;
@@ -233,8 +233,9 @@ static int ptp_qoriq_adjfine(struct ptp_clock_info *ptp, 
long scaled_ppm)
 
return 0;
 }
+EXPORT_SYMBOL_GPL(ptp_qoriq_adjfine);
 
-static int ptp_qoriq_adjtime(struct ptp_clock_info *ptp, s64 delta)
+int ptp_qoriq_adjtime(struct ptp_clock_info *ptp, s64 delta)
 {
s64 now;
unsigned long flags;
@@ -251,9 +252,9 @@ static int ptp_qoriq_adjtime(struct ptp_clock_info *ptp, 
s64 delta)
 
return 0;
 }
+EXPORT_SYMBOL_GPL(ptp_qoriq_adjtime);
 
-static int ptp_qoriq_gettime(struct ptp_clock_info *ptp,
-  struct timespec64 *ts)
+int ptp_qoriq_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
 {
u64 ns;
unsigned long flags;
@@ -269,9 +270,10 @@ static int ptp_qoriq_gettime(struct ptp_clock_info *ptp,
 
return 0;
 }
+EXPORT_SYMBOL_GPL(ptp_qoriq_gettime);
 
-static int ptp_qoriq_settime(struct ptp_clock_info *ptp,
-  const struct timespec64 *ts)
+int ptp_qoriq_settime(struct ptp_clock_info *ptp,
+ const struct timespec64 *ts)
 {
u64 ns;
unsigned long flags;
@@ -288,9 +290,10 @@ static int ptp_qoriq_settime(struct ptp_clock_info *ptp,
 
return 0;
 }
+EXPORT_SYMBOL_GPL(ptp_qoriq_settime);
 
-static int ptp_qoriq_enable(struct ptp_clock_info *ptp,
- struct ptp_clock_request *rq, int on)
+int ptp_qoriq_enable(struct ptp_clock_info *ptp,
+struct ptp_clock_request *rq, int on)
 {
struct ptp_qoriq *ptp_qoriq = container_of(ptp, struct ptp_qoriq, caps);
struct ptp_qoriq_registers *regs = &ptp_qoriq->regs;
@@ -336,6 +339,7 @@ static int ptp_qoriq_enable(struct ptp_clock_info *ptp,
spin_unlock_irqrestore(&ptp_qoriq->lock, flags);
return 0;
 }
+EXPORT_SYMBOL_GPL(ptp_qoriq_enable);
 
 static const struct ptp_clock_info ptp_qoriq_caps = {
.owner  = THIS_MODULE,
@@ -508,7 +512,8 @@ static int ptp_qoriq_probe(struct platform_device *dev)
pr_err("irq not in device tree\n");
goto no_node;
}
-   if (request_irq(ptp_qoriq->irq, isr, IRQF_SHARED, DRIVER, ptp_qoriq)) {
+   if (request_irq(ptp_qoriq->irq, ptp_qoriq_isr, IRQF_SHARED,
+   DRIVER, ptp_qoriq)) {
pr_err("request_irq failed\n");
goto no_node;
}
diff --git a/include/linux/fsl/ptp_qoriq.h b/include/linux/fsl/ptp_qoriq.h
index c2a32d9..75e6f05 100644
--- a/include/linux/fsl/ptp_qoriq.h
+++ b/include/linux/fsl/ptp_qoriq.h
@@ -7,6 +7,7 @@
 #define __PTP_QORIQ_H__
 
 #include 
+#include 
 #include 
 
 /*
@@ -171,6 +172,14 @@ static inline void qoriq_write(unsigned __iomem *addr, u32 
val)
iowrite32be(val, addr);
 }
 
+irqreturn_t ptp_qoriq_isr(int irq, void *priv);
+int ptp_qoriq_adjfine(struct ptp_clock_info *ptp, long scaled_ppm);
+int ptp_qoriq_adjtime(struct ptp_clock_info *ptp, s64 delta);
+int ptp_qoriq_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts);
+int ptp_qoriq_settime(struct ptp_clock_info *ptp,
+ const struct timespec64 *ts);
+int ptp_qoriq_enable(struct ptp_clock_info *ptp,
+struct ptp_clock_request *rq, int on);
 #ifdef CONFIG_DEBUG_FS
 void ptp_qoriq_create_debugfs(struct ptp_qoriq *ptp_qoriq);
 void ptp_qoriq_remove_debugfs(struct ptp_qoriq *ptp_qoriq);
-- 
1.7.1



[v3, 3/9] ptp_qoriq: convert to use ptp_qoriq_init/free

2019-02-11 Thread Yangbo Lu
Moved QorIQ PTP clock initialization/free into new functions
ptp_qoriq_init()/ptp_qoriq_free(). These functions could also
be reused by ENETC PTP drvier which is a PCI driver for same
1588 timer IP block.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
Changes for v3:
- Added ptp_qoriq_free().
---
 drivers/ptp/ptp_qoriq.c   |  144 ++---
 include/linux/fsl/ptp_qoriq.h |3 +
 2 files changed, 80 insertions(+), 67 deletions(-)

diff --git a/drivers/ptp/ptp_qoriq.c b/drivers/ptp/ptp_qoriq.c
index 1f3e73e..db4f929 100644
--- a/drivers/ptp/ptp_qoriq.c
+++ b/drivers/ptp/ptp_qoriq.c
@@ -458,25 +458,17 @@ static int ptp_qoriq_auto_config(struct ptp_qoriq 
*ptp_qoriq,
return 0;
 }
 
-static int ptp_qoriq_probe(struct platform_device *dev)
+int ptp_qoriq_init(struct ptp_qoriq *ptp_qoriq, void __iomem *base,
+  const struct ptp_clock_info caps)
 {
-   struct device_node *node = dev->dev.of_node;
-   struct ptp_qoriq *ptp_qoriq;
+   struct device_node *node = ptp_qoriq->dev->of_node;
struct ptp_qoriq_registers *regs;
struct timespec64 now;
-   int err = -ENOMEM;
-   u32 tmr_ctrl;
unsigned long flags;
-   void __iomem *base;
-
-   ptp_qoriq = kzalloc(sizeof(*ptp_qoriq), GFP_KERNEL);
-   if (!ptp_qoriq)
-   goto no_memory;
-
-   err = -EINVAL;
+   u32 tmr_ctrl;
 
-   ptp_qoriq->dev = &dev->dev;
-   ptp_qoriq->caps = ptp_qoriq_caps;
+   ptp_qoriq->base = base;
+   ptp_qoriq->caps = caps;
 
if (of_property_read_u32(node, "fsl,cksel", &ptp_qoriq->cksel))
ptp_qoriq->cksel = DEFAULT_CKSEL;
@@ -501,44 +493,9 @@ static int ptp_qoriq_probe(struct platform_device *dev)
pr_warn("device tree node missing required elements, try 
automatic configuration\n");
 
if (ptp_qoriq_auto_config(ptp_qoriq, node))
-   goto no_config;
+   return -ENODEV;
}
 
-   err = -ENODEV;
-
-   ptp_qoriq->irq = platform_get_irq(dev, 0);
-
-   if (ptp_qoriq->irq < 0) {
-   pr_err("irq not in device tree\n");
-   goto no_node;
-   }
-   if (request_irq(ptp_qoriq->irq, ptp_qoriq_isr, IRQF_SHARED,
-   DRIVER, ptp_qoriq)) {
-   pr_err("request_irq failed\n");
-   goto no_node;
-   }
-
-   ptp_qoriq->rsrc = platform_get_resource(dev, IORESOURCE_MEM, 0);
-   if (!ptp_qoriq->rsrc) {
-   pr_err("no resource\n");
-   goto no_resource;
-   }
-   if (request_resource(&iomem_resource, ptp_qoriq->rsrc)) {
-   pr_err("resource busy\n");
-   goto no_resource;
-   }
-
-   spin_lock_init(&ptp_qoriq->lock);
-
-   base = ioremap(ptp_qoriq->rsrc->start,
-  resource_size(ptp_qoriq->rsrc));
-   if (!base) {
-   pr_err("ioremap ptp registers failed\n");
-   goto no_ioremap;
-   }
-
-   ptp_qoriq->base = base;
-
if (of_device_is_compatible(node, "fsl,fman-ptp-timer")) {
ptp_qoriq->regs.ctrl_regs = base + FMAN_CTRL_REGS_OFFSET;
ptp_qoriq->regs.alarm_regs = base + FMAN_ALARM_REGS_OFFSET;
@@ -558,6 +515,7 @@ static int ptp_qoriq_probe(struct platform_device *dev)
  (ptp_qoriq->tclk_period & TCLK_PERIOD_MASK) << TCLK_PERIOD_SHIFT |
  (ptp_qoriq->cksel & CKSEL_MASK) << CKSEL_SHIFT;
 
+   spin_lock_init(&ptp_qoriq->lock);
spin_lock_irqsave(&ptp_qoriq->lock, flags);
 
regs = &ptp_qoriq->regs;
@@ -571,16 +529,77 @@ static int ptp_qoriq_probe(struct platform_device *dev)
 
spin_unlock_irqrestore(&ptp_qoriq->lock, flags);
 
-   ptp_qoriq->clock = ptp_clock_register(&ptp_qoriq->caps, &dev->dev);
-   if (IS_ERR(ptp_qoriq->clock)) {
-   err = PTR_ERR(ptp_qoriq->clock);
-   goto no_clock;
-   }
-   ptp_qoriq->phc_index = ptp_clock_index(ptp_qoriq->clock);
+   ptp_qoriq->clock = ptp_clock_register(&ptp_qoriq->caps, ptp_qoriq->dev);
+   if (IS_ERR(ptp_qoriq->clock))
+   return PTR_ERR(ptp_qoriq->clock);
 
+   ptp_qoriq->phc_index = ptp_clock_index(ptp_qoriq->clock);
ptp_qoriq_create_debugfs(ptp_qoriq);
-   platform_set_drvdata(dev, ptp_qoriq);
+   return 0;
+}
+EXPORT_SYMBOL_GPL(ptp_qoriq_init);
+
+void ptp_qoriq_free(struct ptp_qoriq *ptp_qoriq)
+{
+   struct ptp_qoriq_registers *regs = &ptp_qoriq->regs;
+
+   qoriq_write(®s->ctrl_regs->tmr_temask, 0);
+   qoriq_write(®s->ctrl_regs->tmr_ctrl,   0);
+
+   ptp_qoriq_remove_debug

[v2, 7/9] ptp: add QorIQ PTP support for ENETC

2019-02-01 Thread Yangbo Lu
This patch is to add QorIQ PTP support for ENETC.
ENETC PTP driver which is a PCI driver for same
1588 timer IP block will reuse QorIQ PTP driver.

Signed-off-by: Yangbo Lu 
---
Chanbges for v2:
- None.
---
 drivers/ptp/Kconfig |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/ptp/Kconfig b/drivers/ptp/Kconfig
index aeb4a8b..7fe1863 100644
--- a/drivers/ptp/Kconfig
+++ b/drivers/ptp/Kconfig
@@ -43,7 +43,7 @@ config PTP_1588_CLOCK_DTE
 
 config PTP_1588_CLOCK_QORIQ
tristate "Freescale QorIQ 1588 timer as PTP clock"
-   depends on GIANFAR || FSL_DPAA_ETH
+   depends on GIANFAR || FSL_DPAA_ETH || FSL_ENETC || FSL_ENETC_VF
depends on PTP_1588_CLOCK
default y
help
-- 
1.7.1



[v2, 9/9] MAINTAINERS: add enetc_ptp driver into QorIQ PTP list

2019-02-01 Thread Yangbo Lu
This patch to add enetc_ptp driver into QorIQ PTP list
for maintaining.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
---
 MAINTAINERS |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 019a2bc..f0b50f8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6093,6 +6093,7 @@ FREESCALE QORIQ PTP CLOCK DRIVER
 M: Yangbo Lu 
 L: netdev@vger.kernel.org
 S: Maintained
+F: drivers/net/ethernet/freescale/enetc/enetc_ptp.c
 F: drivers/ptp/ptp_qoriq.c
 F: drivers/ptp/ptp_qoriq_debugfs.c
 F: include/linux/fsl/ptp_qoriq.h
-- 
1.7.1



[v2, 8/9] enetc: add PTP clock driver

2019-02-01 Thread Yangbo Lu
This patch is to add PTP clock driver for ENETC.
The driver reused QorIQ PTP clock driver.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
---
 drivers/net/ethernet/freescale/enetc/Kconfig |   12 ++
 drivers/net/ethernet/freescale/enetc/Makefile|3 +
 drivers/net/ethernet/freescale/enetc/enetc_hw.h  |5 +-
 drivers/net/ethernet/freescale/enetc/enetc_ptp.c |  151 ++
 4 files changed, 169 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/ethernet/freescale/enetc/enetc_ptp.c

diff --git a/drivers/net/ethernet/freescale/enetc/Kconfig 
b/drivers/net/ethernet/freescale/enetc/Kconfig
index f9dd26f..8429f5c 100644
--- a/drivers/net/ethernet/freescale/enetc/Kconfig
+++ b/drivers/net/ethernet/freescale/enetc/Kconfig
@@ -17,3 +17,15 @@ config FSL_ENETC_VF
  virtual function (VF) devices enabled by the ENETC PF driver.
 
  If compiled as module (M), the module name is fsl-enetc-vf.
+
+config FSL_ENETC_PTP_CLOCK
+   tristate "ENETC PTP clock driver"
+   depends on PTP_1588_CLOCK_QORIQ && (FSL_ENETC || FSL_ENETC_VF)
+   default y
+   help
+ This driver adds support for using the ENETC 1588 timer
+ as a PTP clock. This clock is only useful if your PTP
+ programs are getting hardware time stamps on the PTP Ethernet
+ packets using the SO_TIMESTAMPING API.
+
+ If compiled as module (M), the module name is fsl-enetc-ptp.
diff --git a/drivers/net/ethernet/freescale/enetc/Makefile 
b/drivers/net/ethernet/freescale/enetc/Makefile
index 9529b01..6976602 100644
--- a/drivers/net/ethernet/freescale/enetc/Makefile
+++ b/drivers/net/ethernet/freescale/enetc/Makefile
@@ -13,3 +13,6 @@ fsl-enetc-vf-$(CONFIG_FSL_ENETC_VF) += enetc.o enetc_cbdr.o \
   enetc_ethtool.o
 fsl-enetc-vf-objs := enetc_vf.o $(fsl-enetc-vf-y)
 endif
+
+obj-$(CONFIG_FSL_ENETC_PTP_CLOCK) += fsl-enetc-ptp.o
+fsl-enetc-ptp-$(CONFIG_FSL_ENETC_PTP_CLOCK) += enetc_ptp.o
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_hw.h 
b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
index efa0b1a..df8eb88 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
@@ -4,8 +4,9 @@
 #include 
 
 /* ENETC device IDs */
-#define ENETC_DEV_ID_PF0xe100
-#define ENETC_DEV_ID_VF0xef00
+#define ENETC_DEV_ID_PF0xe100
+#define ENETC_DEV_ID_VF0xef00
+#define ENETC_DEV_ID_PTP   0xee02
 
 /* ENETC register block BAR */
 #define ENETC_BAR_REGS 0
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_ptp.c 
b/drivers/net/ethernet/freescale/enetc/enetc_ptp.c
new file mode 100644
index 000..1cebb4c
--- /dev/null
+++ b/drivers/net/ethernet/freescale/enetc/enetc_ptp.c
@@ -0,0 +1,151 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/* Copyright 2019 NXP */
+
+#include 
+#include 
+#include 
+
+#include "enetc.h"
+
+static struct ptp_clock_info enetc_ptp_caps = {
+   .owner  = THIS_MODULE,
+   .name   = "ENETC PTP clock",
+   .max_adj= 512000,
+   .n_alarm= 0,
+   .n_ext_ts   = 2,
+   .n_per_out  = 0,
+   .n_pins = 0,
+   .pps= 1,
+   .adjfine= ptp_qoriq_adjfine,
+   .adjtime= ptp_qoriq_adjtime,
+   .gettime64  = ptp_qoriq_gettime,
+   .settime64  = ptp_qoriq_settime,
+   .enable = ptp_qoriq_enable,
+};
+
+static int enetc_ptp_probe(struct pci_dev *pdev,
+  const struct pci_device_id *ent)
+{
+   struct ptp_qoriq *ptp_qoriq;
+   void __iomem *base;
+   int err, len, n;
+
+   if (pdev->dev.of_node && !of_device_is_available(pdev->dev.of_node)) {
+   dev_info(&pdev->dev, "device is disabled, skipping\n");
+   return -ENODEV;
+   }
+
+   err = pci_enable_device_mem(pdev);
+   if (err) {
+   dev_err(&pdev->dev, "device enable failed\n");
+   return err;
+   }
+
+   /* set up for high or low dma */
+   err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
+   if (err) {
+   err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+   if (err) {
+   dev_err(&pdev->dev,
+   "DMA configuration failed: 0x%x\n", err);
+   goto err_dma;
+   }
+   }
+
+   err = pci_request_mem_regions(pdev, KBUILD_MODNAME);
+   if (err) {
+   dev_err(&pdev->dev, "pci_request_regions failed err=%d\n", err);
+   goto err_pci_mem_reg;
+   }
+
+   pci_set_master(pdev);
+
+   ptp_qoriq = kzalloc(sizeof(*ptp_qoriq), GFP_KERNEL);
+   if (!ptp_qoriq) {
+   err = -

[v2, 3/9] ptp_qoriq: convert to use ptp_qoriq_init()

2019-02-01 Thread Yangbo Lu
Moved QorIQ PTP clock initialization into new function
qoriq_ptp_init(). This function could also be reused
by ENETC PTP drvier which is a PCI driver for same 1588
timer IP block.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
---
 drivers/ptp/ptp_qoriq.c   |  120 +
 include/linux/fsl/ptp_qoriq.h |2 +
 2 files changed, 64 insertions(+), 58 deletions(-)

diff --git a/drivers/ptp/ptp_qoriq.c b/drivers/ptp/ptp_qoriq.c
index 1f3e73e..63896b5 100644
--- a/drivers/ptp/ptp_qoriq.c
+++ b/drivers/ptp/ptp_qoriq.c
@@ -458,25 +458,17 @@ static int ptp_qoriq_auto_config(struct ptp_qoriq 
*ptp_qoriq,
return 0;
 }
 
-static int ptp_qoriq_probe(struct platform_device *dev)
+int ptp_qoriq_init(struct ptp_qoriq *ptp_qoriq, void __iomem *base,
+  const struct ptp_clock_info caps)
 {
-   struct device_node *node = dev->dev.of_node;
-   struct ptp_qoriq *ptp_qoriq;
+   struct device_node *node = ptp_qoriq->dev->of_node;
struct ptp_qoriq_registers *regs;
struct timespec64 now;
-   int err = -ENOMEM;
-   u32 tmr_ctrl;
unsigned long flags;
-   void __iomem *base;
-
-   ptp_qoriq = kzalloc(sizeof(*ptp_qoriq), GFP_KERNEL);
-   if (!ptp_qoriq)
-   goto no_memory;
-
-   err = -EINVAL;
+   u32 tmr_ctrl;
 
-   ptp_qoriq->dev = &dev->dev;
-   ptp_qoriq->caps = ptp_qoriq_caps;
+   ptp_qoriq->base = base;
+   ptp_qoriq->caps = caps;
 
if (of_property_read_u32(node, "fsl,cksel", &ptp_qoriq->cksel))
ptp_qoriq->cksel = DEFAULT_CKSEL;
@@ -501,44 +493,9 @@ static int ptp_qoriq_probe(struct platform_device *dev)
pr_warn("device tree node missing required elements, try 
automatic configuration\n");
 
if (ptp_qoriq_auto_config(ptp_qoriq, node))
-   goto no_config;
+   return -ENODEV;
}
 
-   err = -ENODEV;
-
-   ptp_qoriq->irq = platform_get_irq(dev, 0);
-
-   if (ptp_qoriq->irq < 0) {
-   pr_err("irq not in device tree\n");
-   goto no_node;
-   }
-   if (request_irq(ptp_qoriq->irq, ptp_qoriq_isr, IRQF_SHARED,
-   DRIVER, ptp_qoriq)) {
-   pr_err("request_irq failed\n");
-   goto no_node;
-   }
-
-   ptp_qoriq->rsrc = platform_get_resource(dev, IORESOURCE_MEM, 0);
-   if (!ptp_qoriq->rsrc) {
-   pr_err("no resource\n");
-   goto no_resource;
-   }
-   if (request_resource(&iomem_resource, ptp_qoriq->rsrc)) {
-   pr_err("resource busy\n");
-   goto no_resource;
-   }
-
-   spin_lock_init(&ptp_qoriq->lock);
-
-   base = ioremap(ptp_qoriq->rsrc->start,
-  resource_size(ptp_qoriq->rsrc));
-   if (!base) {
-   pr_err("ioremap ptp registers failed\n");
-   goto no_ioremap;
-   }
-
-   ptp_qoriq->base = base;
-
if (of_device_is_compatible(node, "fsl,fman-ptp-timer")) {
ptp_qoriq->regs.ctrl_regs = base + FMAN_CTRL_REGS_OFFSET;
ptp_qoriq->regs.alarm_regs = base + FMAN_ALARM_REGS_OFFSET;
@@ -558,6 +515,7 @@ static int ptp_qoriq_probe(struct platform_device *dev)
  (ptp_qoriq->tclk_period & TCLK_PERIOD_MASK) << TCLK_PERIOD_SHIFT |
  (ptp_qoriq->cksel & CKSEL_MASK) << CKSEL_SHIFT;
 
+   spin_lock_init(&ptp_qoriq->lock);
spin_lock_irqsave(&ptp_qoriq->lock, flags);
 
regs = &ptp_qoriq->regs;
@@ -571,16 +529,63 @@ static int ptp_qoriq_probe(struct platform_device *dev)
 
spin_unlock_irqrestore(&ptp_qoriq->lock, flags);
 
-   ptp_qoriq->clock = ptp_clock_register(&ptp_qoriq->caps, &dev->dev);
-   if (IS_ERR(ptp_qoriq->clock)) {
-   err = PTR_ERR(ptp_qoriq->clock);
-   goto no_clock;
-   }
-   ptp_qoriq->phc_index = ptp_clock_index(ptp_qoriq->clock);
+   ptp_qoriq->clock = ptp_clock_register(&ptp_qoriq->caps, ptp_qoriq->dev);
+   if (IS_ERR(ptp_qoriq->clock))
+   return PTR_ERR(ptp_qoriq->clock);
 
+   ptp_qoriq->phc_index = ptp_clock_index(ptp_qoriq->clock);
ptp_qoriq_create_debugfs(ptp_qoriq);
-   platform_set_drvdata(dev, ptp_qoriq);
+   return 0;
+}
+EXPORT_SYMBOL_GPL(ptp_qoriq_init);
+
+static int ptp_qoriq_probe(struct platform_device *dev)
+{
+   struct ptp_qoriq *ptp_qoriq;
+   int err = -ENOMEM;
+   void __iomem *base;
+
+   ptp_qoriq = kzalloc(sizeof(*ptp_qoriq), GFP_KERNEL);
+   if (!ptp_qoriq)
+   goto no_memory;
+
+   ptp_qoriq->dev = &dev->dev;
+
+   err = -ENODEV;
+

[v2, 5/9] dt-binding: ptp_qoriq: add little-endian support

2019-02-01 Thread Yangbo Lu
Specify "little-endian" property if the 1588 timer IP block
is little-endian mode. The default endian mode is big-endian.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
---
 .../devicetree/bindings/ptp/ptp-qoriq.txt  |3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/Documentation/devicetree/bindings/ptp/ptp-qoriq.txt 
b/Documentation/devicetree/bindings/ptp/ptp-qoriq.txt
index 8e7f855..454c937 100644
--- a/Documentation/devicetree/bindings/ptp/ptp-qoriq.txt
+++ b/Documentation/devicetree/bindings/ptp/ptp-qoriq.txt
@@ -19,6 +19,9 @@ Clock Properties:
   - fsl,max-adj  Maximum frequency adjustment in parts per billion.
   - fsl,extts-fifo   The presence of this property indicates hardware
 support for the external trigger stamp FIFO.
+  - little-endianThe presence of this property indicates the 1588 timer
+IP block is little-endian mode. The default endian mode
+is big-endian.
 
   These properties set the operational parameters for the PTP
   clock. You must choose these carefully for the clock to work right.
-- 
1.7.1



[v2, 4/9] ptp_qoriq: add little enadian support

2019-02-01 Thread Yangbo Lu
There is QorIQ 1588 timer IP block on the new ENETC Ethernet
controller. However it uses little endian mode which is different
with before. This patch is to add little endian support for the
driver by using "little-endian" dts node property.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
---
 drivers/ptp/ptp_qoriq.c |   69 ++-
 drivers/ptp/ptp_qoriq_debugfs.c |   12 +++---
 include/linux/fsl/ptp_qoriq.h   |   21 ---
 3 files changed, 60 insertions(+), 42 deletions(-)

diff --git a/drivers/ptp/ptp_qoriq.c b/drivers/ptp/ptp_qoriq.c
index 63896b5..4308e25 100644
--- a/drivers/ptp/ptp_qoriq.c
+++ b/drivers/ptp/ptp_qoriq.c
@@ -43,8 +43,8 @@ static u64 tmr_cnt_read(struct ptp_qoriq *ptp_qoriq)
u64 ns;
u32 lo, hi;
 
-   lo = qoriq_read(®s->ctrl_regs->tmr_cnt_l);
-   hi = qoriq_read(®s->ctrl_regs->tmr_cnt_h);
+   lo = ptp_qoriq->read(®s->ctrl_regs->tmr_cnt_l);
+   hi = ptp_qoriq->read(®s->ctrl_regs->tmr_cnt_h);
ns = ((u64) hi) << 32;
ns |= lo;
return ns;
@@ -57,8 +57,8 @@ static void tmr_cnt_write(struct ptp_qoriq *ptp_qoriq, u64 ns)
u32 hi = ns >> 32;
u32 lo = ns & 0x;
 
-   qoriq_write(®s->ctrl_regs->tmr_cnt_l, lo);
-   qoriq_write(®s->ctrl_regs->tmr_cnt_h, hi);
+   ptp_qoriq->write(®s->ctrl_regs->tmr_cnt_l, lo);
+   ptp_qoriq->write(®s->ctrl_regs->tmr_cnt_h, hi);
 }
 
 /* Caller must hold ptp_qoriq->lock. */
@@ -73,8 +73,8 @@ static void set_alarm(struct ptp_qoriq *ptp_qoriq)
ns -= ptp_qoriq->tclk_period;
hi = ns >> 32;
lo = ns & 0x;
-   qoriq_write(®s->alarm_regs->tmr_alarm1_l, lo);
-   qoriq_write(®s->alarm_regs->tmr_alarm1_h, hi);
+   ptp_qoriq->write(®s->alarm_regs->tmr_alarm1_l, lo);
+   ptp_qoriq->write(®s->alarm_regs->tmr_alarm1_h, hi);
 }
 
 /* Caller must hold ptp_qoriq->lock. */
@@ -83,8 +83,8 @@ static void set_fipers(struct ptp_qoriq *ptp_qoriq)
struct ptp_qoriq_registers *regs = &ptp_qoriq->regs;
 
set_alarm(ptp_qoriq);
-   qoriq_write(®s->fiper_regs->tmr_fiper1, ptp_qoriq->tmr_fiper1);
-   qoriq_write(®s->fiper_regs->tmr_fiper2, ptp_qoriq->tmr_fiper2);
+   ptp_qoriq->write(®s->fiper_regs->tmr_fiper1, ptp_qoriq->tmr_fiper1);
+   ptp_qoriq->write(®s->fiper_regs->tmr_fiper2, ptp_qoriq->tmr_fiper2);
 }
 
 static int extts_clean_up(struct ptp_qoriq *ptp_qoriq, int index,
@@ -115,8 +115,8 @@ static int extts_clean_up(struct ptp_qoriq *ptp_qoriq, int 
index,
event.index = index;
 
do {
-   lo = qoriq_read(reg_etts_l);
-   hi = qoriq_read(reg_etts_h);
+   lo = ptp_qoriq->read(reg_etts_l);
+   hi = ptp_qoriq->read(reg_etts_h);
 
if (update_event) {
event.timestamp = ((u64) hi) << 32;
@@ -124,7 +124,7 @@ static int extts_clean_up(struct ptp_qoriq *ptp_qoriq, int 
index,
ptp_clock_event(ptp_qoriq->clock, &event);
}
 
-   stat = qoriq_read(®s->ctrl_regs->tmr_stat);
+   stat = ptp_qoriq->read(®s->ctrl_regs->tmr_stat);
} while (ptp_qoriq->extts_fifo_support && (stat & valid));
 
return 0;
@@ -144,8 +144,8 @@ irqreturn_t ptp_qoriq_isr(int irq, void *priv)
 
spin_lock(&ptp_qoriq->lock);
 
-   val = qoriq_read(®s->ctrl_regs->tmr_tevent);
-   mask = qoriq_read(®s->ctrl_regs->tmr_temask);
+   val = ptp_qoriq->read(®s->ctrl_regs->tmr_tevent);
+   mask = ptp_qoriq->read(®s->ctrl_regs->tmr_temask);
 
spin_unlock(&ptp_qoriq->lock);
 
@@ -173,14 +173,14 @@ irqreturn_t ptp_qoriq_isr(int irq, void *priv)
ns = ptp_qoriq->alarm_value + ptp_qoriq->alarm_interval;
hi = ns >> 32;
lo = ns & 0x;
-   qoriq_write(®s->alarm_regs->tmr_alarm2_l, lo);
-   qoriq_write(®s->alarm_regs->tmr_alarm2_h, hi);
+   ptp_qoriq->write(®s->alarm_regs->tmr_alarm2_l, lo);
+   ptp_qoriq->write(®s->alarm_regs->tmr_alarm2_h, hi);
ptp_qoriq->alarm_value = ns;
} else {
spin_lock(&ptp_qoriq->lock);
-   mask = qoriq_read(®s->ctrl_regs->tmr_temask);
+   mask = ptp_qoriq->read(®s->ctrl_regs->tmr_temask);
mask &= ~ALM2EN;
-   qoriq_write(®s->ctrl_regs->tmr_temask, mask);
+   ptp_qoriq->write(®s->ctrl_regs->tmr_temask, mask);

[v2, 1/9] ptp_qoriq: make structure/function names more consistent

2019-02-01 Thread Yangbo Lu
Strings containing "ptp_qoriq" or "qoriq_ptp" which were used for
structure/function names were complained by users. Let's just use
the unique "ptp_qoriq" to make these names more consistent.
This patch is just to unify the names using "ptp_qoriq". It hasn't
changed any functions.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- Fixed build issue in gianfar/dpaa ethtool driver.
---
 drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c |2 +-
 drivers/net/ethernet/freescale/gianfar_ethtool.c   |2 +-
 drivers/ptp/ptp_qoriq.c|  288 ++--
 drivers/ptp/ptp_qoriq_debugfs.c|   36 ++--
 include/linux/fsl/ptp_qoriq.h  |   14 +-
 5 files changed, 171 insertions(+), 171 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c 
b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
index 6249711..bdee441 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
@@ -501,7 +501,7 @@ static int dpaa_get_ts_info(struct net_device *net_dev,
struct device_node *mac_node = dev->of_node;
struct device_node *fman_node = NULL, *ptp_node = NULL;
struct platform_device *ptp_dev = NULL;
-   struct qoriq_ptp *ptp = NULL;
+   struct ptp_qoriq *ptp = NULL;
 
info->phc_index = -1;
 
diff --git a/drivers/net/ethernet/freescale/gianfar_ethtool.c 
b/drivers/net/ethernet/freescale/gianfar_ethtool.c
index 241325c..27ed995 100644
--- a/drivers/net/ethernet/freescale/gianfar_ethtool.c
+++ b/drivers/net/ethernet/freescale/gianfar_ethtool.c
@@ -1492,7 +1492,7 @@ static int gfar_get_ts_info(struct net_device *dev,
struct gfar_private *priv = netdev_priv(dev);
struct platform_device *ptp_dev;
struct device_node *ptp_node;
-   struct qoriq_ptp *ptp = NULL;
+   struct ptp_qoriq *ptp = NULL;
 
info->phc_index = -1;
 
diff --git a/drivers/ptp/ptp_qoriq.c b/drivers/ptp/ptp_qoriq.c
index 43416b2..8c10d0f 100644
--- a/drivers/ptp/ptp_qoriq.c
+++ b/drivers/ptp/ptp_qoriq.c
@@ -37,10 +37,10 @@
  * Register access functions
  */
 
-/* Caller must hold qoriq_ptp->lock. */
-static u64 tmr_cnt_read(struct qoriq_ptp *qoriq_ptp)
+/* Caller must hold ptp_qoriq->lock. */
+static u64 tmr_cnt_read(struct ptp_qoriq *ptp_qoriq)
 {
-   struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
+   struct ptp_qoriq_registers *regs = &ptp_qoriq->regs;
u64 ns;
u32 lo, hi;
 
@@ -51,10 +51,10 @@ static u64 tmr_cnt_read(struct qoriq_ptp *qoriq_ptp)
return ns;
 }
 
-/* Caller must hold qoriq_ptp->lock. */
-static void tmr_cnt_write(struct qoriq_ptp *qoriq_ptp, u64 ns)
+/* Caller must hold ptp_qoriq->lock. */
+static void tmr_cnt_write(struct ptp_qoriq *ptp_qoriq, u64 ns)
 {
-   struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
+   struct ptp_qoriq_registers *regs = &ptp_qoriq->regs;
u32 hi = ns >> 32;
u32 lo = ns & 0x;
 
@@ -62,36 +62,36 @@ static void tmr_cnt_write(struct qoriq_ptp *qoriq_ptp, u64 
ns)
qoriq_write(®s->ctrl_regs->tmr_cnt_h, hi);
 }
 
-/* Caller must hold qoriq_ptp->lock. */
-static void set_alarm(struct qoriq_ptp *qoriq_ptp)
+/* Caller must hold ptp_qoriq->lock. */
+static void set_alarm(struct ptp_qoriq *ptp_qoriq)
 {
-   struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
+   struct ptp_qoriq_registers *regs = &ptp_qoriq->regs;
u64 ns;
u32 lo, hi;
 
-   ns = tmr_cnt_read(qoriq_ptp) + 15ULL;
+   ns = tmr_cnt_read(ptp_qoriq) + 15ULL;
ns = div_u64(ns, 10UL) * 10ULL;
-   ns -= qoriq_ptp->tclk_period;
+   ns -= ptp_qoriq->tclk_period;
hi = ns >> 32;
lo = ns & 0x;
qoriq_write(®s->alarm_regs->tmr_alarm1_l, lo);
qoriq_write(®s->alarm_regs->tmr_alarm1_h, hi);
 }
 
-/* Caller must hold qoriq_ptp->lock. */
-static void set_fipers(struct qoriq_ptp *qoriq_ptp)
+/* Caller must hold ptp_qoriq->lock. */
+static void set_fipers(struct ptp_qoriq *ptp_qoriq)
 {
-   struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
+   struct ptp_qoriq_registers *regs = &ptp_qoriq->regs;
 
-   set_alarm(qoriq_ptp);
-   qoriq_write(®s->fiper_regs->tmr_fiper1, qoriq_ptp->tmr_fiper1);
-   qoriq_write(®s->fiper_regs->tmr_fiper2, qoriq_ptp->tmr_fiper2);
+   set_alarm(ptp_qoriq);
+   qoriq_write(®s->fiper_regs->tmr_fiper1, ptp_qoriq->tmr_fiper1);
+   qoriq_write(®s->fiper_regs->tmr_fiper2, ptp_qoriq->tmr_fiper2);
 }
 
-static int extts_clean_up(struct qoriq_ptp *qoriq_ptp, int index,
+static int extts_clean_up(struct ptp_qoriq *ptp_qoriq, int index,
  bool update_event)
 {
-  

[v2, 6/9] ptp_qoriq: fix register memory map

2019-02-01 Thread Yangbo Lu
The 1588 timer on eTSEC Ethernet controller uses different
register memory map with DPAA Ethernet controller.
Now the new ENETC Ethernet controller uses same reigster
memory map with DPAA. To support ENETC, let's use register
memory map of DPAA/ENETC in default.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
---
 drivers/ptp/ptp_qoriq.c   |   11 ++-
 include/linux/fsl/ptp_qoriq.h |   16 
 2 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/drivers/ptp/ptp_qoriq.c b/drivers/ptp/ptp_qoriq.c
index 4308e25..af7a70e 100644
--- a/drivers/ptp/ptp_qoriq.c
+++ b/drivers/ptp/ptp_qoriq.c
@@ -504,11 +504,12 @@ int ptp_qoriq_init(struct ptp_qoriq *ptp_qoriq, void 
__iomem *base,
ptp_qoriq->write = qoriq_write_be;
}
 
-   if (of_device_is_compatible(node, "fsl,fman-ptp-timer")) {
-   ptp_qoriq->regs.ctrl_regs = base + FMAN_CTRL_REGS_OFFSET;
-   ptp_qoriq->regs.alarm_regs = base + FMAN_ALARM_REGS_OFFSET;
-   ptp_qoriq->regs.fiper_regs = base + FMAN_FIPER_REGS_OFFSET;
-   ptp_qoriq->regs.etts_regs = base + FMAN_ETTS_REGS_OFFSET;
+   /* The eTSEC uses differnt memory map with DPAA/ENETC */
+   if (of_device_is_compatible(node, "fsl,etsec-ptp")) {
+   ptp_qoriq->regs.ctrl_regs = base + ETSEC_CTRL_REGS_OFFSET;
+   ptp_qoriq->regs.alarm_regs = base + ETSEC_ALARM_REGS_OFFSET;
+   ptp_qoriq->regs.fiper_regs = base + ETSEC_FIPER_REGS_OFFSET;
+   ptp_qoriq->regs.etts_regs = base + ETSEC_ETTS_REGS_OFFSET;
} else {
ptp_qoriq->regs.ctrl_regs = base + CTRL_REGS_OFFSET;
ptp_qoriq->regs.alarm_regs = base + ALARM_REGS_OFFSET;
diff --git a/include/linux/fsl/ptp_qoriq.h b/include/linux/fsl/ptp_qoriq.h
index b44b466..902d3b1 100644
--- a/include/linux/fsl/ptp_qoriq.h
+++ b/include/linux/fsl/ptp_qoriq.h
@@ -58,15 +58,15 @@ struct ptp_qoriq_registers {
 };
 
 /* Offset definitions for the four register groups */
-#define CTRL_REGS_OFFSET   0x0
-#define ALARM_REGS_OFFSET  0x40
-#define FIPER_REGS_OFFSET  0x80
-#define ETTS_REGS_OFFSET   0xa0
-
-#define FMAN_CTRL_REGS_OFFSET  0x80
-#define FMAN_ALARM_REGS_OFFSET 0xb8
-#define FMAN_FIPER_REGS_OFFSET 0xd0
-#define FMAN_ETTS_REGS_OFFSET  0xe0
+#define ETSEC_CTRL_REGS_OFFSET 0x0
+#define ETSEC_ALARM_REGS_OFFSET0x40
+#define ETSEC_FIPER_REGS_OFFSET0x80
+#define ETSEC_ETTS_REGS_OFFSET 0xa0
+
+#define CTRL_REGS_OFFSET   0x80
+#define ALARM_REGS_OFFSET  0xb8
+#define FIPER_REGS_OFFSET  0xd0
+#define ETTS_REGS_OFFSET   0xe0
 
 
 /* Bit definitions for the TMR_CTRL register */
-- 
1.7.1



[v2, 0/9] Add ENETC PTP clock driver

2019-02-01 Thread Yangbo Lu
There is same QorIQ 1588 timer IP block on the new ENETC Ethernet
controller with eTSEC/DPAA Ethernet controllers. However it's
different endianness (little-endian) and using PCI driver.

To support ENETC PTP driver, ptp_qoriq driver needed to be
reworked to make functions global for reusing, to add little-
endian support, to add ENETC memory map support, and to add
ENETC dependency for ptp_qoriq driver.

In addition, although ENETC PTP driver is a PCI driver, the dts
node still could be used. Currently the ls1028a dtsi which is
the only platform by now using ENETC is not complete, so there
is still dependency for ENETC PTP node upstreaming. This will
be done in the near future. The hardware timestamping support
for ENETC is done but needs to be reworked with new method in
internal git tree, and will be sent out soon.

Yangbo Lu (9):
  ptp_qoriq: make structure/function names more consistent
  ptp_qoriq: make ptp operations global
  ptp_qoriq: convert to use ptp_qoriq_init()
  ptp_qoriq: add little enadian support
  dt-binding: ptp_qoriq: add little-endian support
  ptp_qoriq: fix register memory map
  ptp: add QorIQ PTP support for ENETC
  enetc: add PTP clock driver
  MAINTAINERS: add enetc_ptp driver into QorIQ PTP list

 .../devicetree/bindings/ptp/ptp-qoriq.txt  |3 +
 MAINTAINERS|1 +
 drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c |2 +-
 drivers/net/ethernet/freescale/enetc/Kconfig   |   12 +
 drivers/net/ethernet/freescale/enetc/Makefile  |3 +
 drivers/net/ethernet/freescale/enetc/enetc_hw.h|5 +-
 drivers/net/ethernet/freescale/enetc/enetc_ptp.c   |  151 +++
 drivers/net/ethernet/freescale/gianfar_ethtool.c   |2 +-
 drivers/ptp/Kconfig|2 +-
 drivers/ptp/ptp_qoriq.c|  427 ++--
 drivers/ptp/ptp_qoriq_debugfs.c|   48 ++--
 include/linux/fsl/ptp_qoriq.h  |   62 ++-
 12 files changed, 464 insertions(+), 254 deletions(-)
 create mode 100644 drivers/net/ethernet/freescale/enetc/enetc_ptp.c



[v2, 2/9] ptp_qoriq: make ptp operations global

2019-02-01 Thread Yangbo Lu
This patch is to make functions of ptp operations global,
so that ENETC PTP driver which is a PCI driver for same
1588 timer IP block could reuse them.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
---
 drivers/ptp/ptp_qoriq.c   |   27 ---
 include/linux/fsl/ptp_qoriq.h |9 +
 2 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/drivers/ptp/ptp_qoriq.c b/drivers/ptp/ptp_qoriq.c
index 8c10d0f..1f3e73e 100644
--- a/drivers/ptp/ptp_qoriq.c
+++ b/drivers/ptp/ptp_qoriq.c
@@ -22,7 +22,6 @@
 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -135,7 +134,7 @@ static int extts_clean_up(struct ptp_qoriq *ptp_qoriq, int 
index,
  * Interrupt service routine
  */
 
-static irqreturn_t isr(int irq, void *priv)
+irqreturn_t ptp_qoriq_isr(int irq, void *priv)
 {
struct ptp_qoriq *ptp_qoriq = priv;
struct ptp_qoriq_registers *regs = &ptp_qoriq->regs;
@@ -200,12 +199,13 @@ static irqreturn_t isr(int irq, void *priv)
} else
return IRQ_NONE;
 }
+EXPORT_SYMBOL_GPL(ptp_qoriq_isr);
 
 /*
  * PTP clock operations
  */
 
-static int ptp_qoriq_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
+int ptp_qoriq_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
 {
u64 adj, diff;
u32 tmr_add;
@@ -233,8 +233,9 @@ static int ptp_qoriq_adjfine(struct ptp_clock_info *ptp, 
long scaled_ppm)
 
return 0;
 }
+EXPORT_SYMBOL_GPL(ptp_qoriq_adjfine);
 
-static int ptp_qoriq_adjtime(struct ptp_clock_info *ptp, s64 delta)
+int ptp_qoriq_adjtime(struct ptp_clock_info *ptp, s64 delta)
 {
s64 now;
unsigned long flags;
@@ -251,9 +252,9 @@ static int ptp_qoriq_adjtime(struct ptp_clock_info *ptp, 
s64 delta)
 
return 0;
 }
+EXPORT_SYMBOL_GPL(ptp_qoriq_adjtime);
 
-static int ptp_qoriq_gettime(struct ptp_clock_info *ptp,
-  struct timespec64 *ts)
+int ptp_qoriq_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
 {
u64 ns;
unsigned long flags;
@@ -269,9 +270,10 @@ static int ptp_qoriq_gettime(struct ptp_clock_info *ptp,
 
return 0;
 }
+EXPORT_SYMBOL_GPL(ptp_qoriq_gettime);
 
-static int ptp_qoriq_settime(struct ptp_clock_info *ptp,
-  const struct timespec64 *ts)
+int ptp_qoriq_settime(struct ptp_clock_info *ptp,
+ const struct timespec64 *ts)
 {
u64 ns;
unsigned long flags;
@@ -288,9 +290,10 @@ static int ptp_qoriq_settime(struct ptp_clock_info *ptp,
 
return 0;
 }
+EXPORT_SYMBOL_GPL(ptp_qoriq_settime);
 
-static int ptp_qoriq_enable(struct ptp_clock_info *ptp,
- struct ptp_clock_request *rq, int on)
+int ptp_qoriq_enable(struct ptp_clock_info *ptp,
+struct ptp_clock_request *rq, int on)
 {
struct ptp_qoriq *ptp_qoriq = container_of(ptp, struct ptp_qoriq, caps);
struct ptp_qoriq_registers *regs = &ptp_qoriq->regs;
@@ -336,6 +339,7 @@ static int ptp_qoriq_enable(struct ptp_clock_info *ptp,
spin_unlock_irqrestore(&ptp_qoriq->lock, flags);
return 0;
 }
+EXPORT_SYMBOL_GPL(ptp_qoriq_enable);
 
 static const struct ptp_clock_info ptp_qoriq_caps = {
.owner  = THIS_MODULE,
@@ -508,7 +512,8 @@ static int ptp_qoriq_probe(struct platform_device *dev)
pr_err("irq not in device tree\n");
goto no_node;
}
-   if (request_irq(ptp_qoriq->irq, isr, IRQF_SHARED, DRIVER, ptp_qoriq)) {
+   if (request_irq(ptp_qoriq->irq, ptp_qoriq_isr, IRQF_SHARED,
+   DRIVER, ptp_qoriq)) {
pr_err("request_irq failed\n");
goto no_node;
}
diff --git a/include/linux/fsl/ptp_qoriq.h b/include/linux/fsl/ptp_qoriq.h
index c2a32d9..75e6f05 100644
--- a/include/linux/fsl/ptp_qoriq.h
+++ b/include/linux/fsl/ptp_qoriq.h
@@ -7,6 +7,7 @@
 #define __PTP_QORIQ_H__
 
 #include 
+#include 
 #include 
 
 /*
@@ -171,6 +172,14 @@ static inline void qoriq_write(unsigned __iomem *addr, u32 
val)
iowrite32be(val, addr);
 }
 
+irqreturn_t ptp_qoriq_isr(int irq, void *priv);
+int ptp_qoriq_adjfine(struct ptp_clock_info *ptp, long scaled_ppm);
+int ptp_qoriq_adjtime(struct ptp_clock_info *ptp, s64 delta);
+int ptp_qoriq_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts);
+int ptp_qoriq_settime(struct ptp_clock_info *ptp,
+ const struct timespec64 *ts);
+int ptp_qoriq_enable(struct ptp_clock_info *ptp,
+struct ptp_clock_request *rq, int on);
 #ifdef CONFIG_DEBUG_FS
 void ptp_qoriq_create_debugfs(struct ptp_qoriq *ptp_qoriq);
 void ptp_qoriq_remove_debugfs(struct ptp_qoriq *ptp_qoriq);
-- 
1.7.1



[PATCH 3/9] ptp_qoriq: convert to use ptp_qoriq_init()

2019-01-30 Thread Yangbo Lu
Moved QorIQ PTP clock initialization into new function
qoriq_ptp_init(). This function could also be reused
by ENETC PTP drvier which is a PCI driver for same 1588
timer IP block.

Signed-off-by: Yangbo Lu 
---
 drivers/ptp/ptp_qoriq.c   |  120 +
 include/linux/fsl/ptp_qoriq.h |2 +
 2 files changed, 64 insertions(+), 58 deletions(-)

diff --git a/drivers/ptp/ptp_qoriq.c b/drivers/ptp/ptp_qoriq.c
index 1f3e73e..63896b5 100644
--- a/drivers/ptp/ptp_qoriq.c
+++ b/drivers/ptp/ptp_qoriq.c
@@ -458,25 +458,17 @@ static int ptp_qoriq_auto_config(struct ptp_qoriq 
*ptp_qoriq,
return 0;
 }
 
-static int ptp_qoriq_probe(struct platform_device *dev)
+int ptp_qoriq_init(struct ptp_qoriq *ptp_qoriq, void __iomem *base,
+  const struct ptp_clock_info caps)
 {
-   struct device_node *node = dev->dev.of_node;
-   struct ptp_qoriq *ptp_qoriq;
+   struct device_node *node = ptp_qoriq->dev->of_node;
struct ptp_qoriq_registers *regs;
struct timespec64 now;
-   int err = -ENOMEM;
-   u32 tmr_ctrl;
unsigned long flags;
-   void __iomem *base;
-
-   ptp_qoriq = kzalloc(sizeof(*ptp_qoriq), GFP_KERNEL);
-   if (!ptp_qoriq)
-   goto no_memory;
-
-   err = -EINVAL;
+   u32 tmr_ctrl;
 
-   ptp_qoriq->dev = &dev->dev;
-   ptp_qoriq->caps = ptp_qoriq_caps;
+   ptp_qoriq->base = base;
+   ptp_qoriq->caps = caps;
 
if (of_property_read_u32(node, "fsl,cksel", &ptp_qoriq->cksel))
ptp_qoriq->cksel = DEFAULT_CKSEL;
@@ -501,44 +493,9 @@ static int ptp_qoriq_probe(struct platform_device *dev)
pr_warn("device tree node missing required elements, try 
automatic configuration\n");
 
if (ptp_qoriq_auto_config(ptp_qoriq, node))
-   goto no_config;
+   return -ENODEV;
}
 
-   err = -ENODEV;
-
-   ptp_qoriq->irq = platform_get_irq(dev, 0);
-
-   if (ptp_qoriq->irq < 0) {
-   pr_err("irq not in device tree\n");
-   goto no_node;
-   }
-   if (request_irq(ptp_qoriq->irq, ptp_qoriq_isr, IRQF_SHARED,
-   DRIVER, ptp_qoriq)) {
-   pr_err("request_irq failed\n");
-   goto no_node;
-   }
-
-   ptp_qoriq->rsrc = platform_get_resource(dev, IORESOURCE_MEM, 0);
-   if (!ptp_qoriq->rsrc) {
-   pr_err("no resource\n");
-   goto no_resource;
-   }
-   if (request_resource(&iomem_resource, ptp_qoriq->rsrc)) {
-   pr_err("resource busy\n");
-   goto no_resource;
-   }
-
-   spin_lock_init(&ptp_qoriq->lock);
-
-   base = ioremap(ptp_qoriq->rsrc->start,
-  resource_size(ptp_qoriq->rsrc));
-   if (!base) {
-   pr_err("ioremap ptp registers failed\n");
-   goto no_ioremap;
-   }
-
-   ptp_qoriq->base = base;
-
if (of_device_is_compatible(node, "fsl,fman-ptp-timer")) {
ptp_qoriq->regs.ctrl_regs = base + FMAN_CTRL_REGS_OFFSET;
ptp_qoriq->regs.alarm_regs = base + FMAN_ALARM_REGS_OFFSET;
@@ -558,6 +515,7 @@ static int ptp_qoriq_probe(struct platform_device *dev)
  (ptp_qoriq->tclk_period & TCLK_PERIOD_MASK) << TCLK_PERIOD_SHIFT |
  (ptp_qoriq->cksel & CKSEL_MASK) << CKSEL_SHIFT;
 
+   spin_lock_init(&ptp_qoriq->lock);
spin_lock_irqsave(&ptp_qoriq->lock, flags);
 
regs = &ptp_qoriq->regs;
@@ -571,16 +529,63 @@ static int ptp_qoriq_probe(struct platform_device *dev)
 
spin_unlock_irqrestore(&ptp_qoriq->lock, flags);
 
-   ptp_qoriq->clock = ptp_clock_register(&ptp_qoriq->caps, &dev->dev);
-   if (IS_ERR(ptp_qoriq->clock)) {
-   err = PTR_ERR(ptp_qoriq->clock);
-   goto no_clock;
-   }
-   ptp_qoriq->phc_index = ptp_clock_index(ptp_qoriq->clock);
+   ptp_qoriq->clock = ptp_clock_register(&ptp_qoriq->caps, ptp_qoriq->dev);
+   if (IS_ERR(ptp_qoriq->clock))
+   return PTR_ERR(ptp_qoriq->clock);
 
+   ptp_qoriq->phc_index = ptp_clock_index(ptp_qoriq->clock);
ptp_qoriq_create_debugfs(ptp_qoriq);
-   platform_set_drvdata(dev, ptp_qoriq);
+   return 0;
+}
+EXPORT_SYMBOL_GPL(ptp_qoriq_init);
+
+static int ptp_qoriq_probe(struct platform_device *dev)
+{
+   struct ptp_qoriq *ptp_qoriq;
+   int err = -ENOMEM;
+   void __iomem *base;
+
+   ptp_qoriq = kzalloc(sizeof(*ptp_qoriq), GFP_KERNEL);
+   if (!ptp_qoriq)
+   goto no_memory;
+
+   ptp_qoriq->dev = &dev->dev;
+
+   err = -ENODEV;
+
+   ptp_qoriq->irq =

[PATCH 6/9] ptp_qoriq: fix register memory map

2019-01-30 Thread Yangbo Lu
The 1588 timer on eTSEC Ethernet controller uses different
register memory map with DPAA Ethernet controller.
Now the new ENETC Ethernet controller uses same reigster
memory map with DPAA. To support ENETC, let's use register
memory map of DPAA/ENETC in default.

Signed-off-by: Yangbo Lu 
---
 drivers/ptp/ptp_qoriq.c   |   11 ++-
 include/linux/fsl/ptp_qoriq.h |   16 
 2 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/drivers/ptp/ptp_qoriq.c b/drivers/ptp/ptp_qoriq.c
index 4308e25..af7a70e 100644
--- a/drivers/ptp/ptp_qoriq.c
+++ b/drivers/ptp/ptp_qoriq.c
@@ -504,11 +504,12 @@ int ptp_qoriq_init(struct ptp_qoriq *ptp_qoriq, void 
__iomem *base,
ptp_qoriq->write = qoriq_write_be;
}
 
-   if (of_device_is_compatible(node, "fsl,fman-ptp-timer")) {
-   ptp_qoriq->regs.ctrl_regs = base + FMAN_CTRL_REGS_OFFSET;
-   ptp_qoriq->regs.alarm_regs = base + FMAN_ALARM_REGS_OFFSET;
-   ptp_qoriq->regs.fiper_regs = base + FMAN_FIPER_REGS_OFFSET;
-   ptp_qoriq->regs.etts_regs = base + FMAN_ETTS_REGS_OFFSET;
+   /* The eTSEC uses differnt memory map with DPAA/ENETC */
+   if (of_device_is_compatible(node, "fsl,etsec-ptp")) {
+   ptp_qoriq->regs.ctrl_regs = base + ETSEC_CTRL_REGS_OFFSET;
+   ptp_qoriq->regs.alarm_regs = base + ETSEC_ALARM_REGS_OFFSET;
+   ptp_qoriq->regs.fiper_regs = base + ETSEC_FIPER_REGS_OFFSET;
+   ptp_qoriq->regs.etts_regs = base + ETSEC_ETTS_REGS_OFFSET;
} else {
ptp_qoriq->regs.ctrl_regs = base + CTRL_REGS_OFFSET;
ptp_qoriq->regs.alarm_regs = base + ALARM_REGS_OFFSET;
diff --git a/include/linux/fsl/ptp_qoriq.h b/include/linux/fsl/ptp_qoriq.h
index b44b466..902d3b1 100644
--- a/include/linux/fsl/ptp_qoriq.h
+++ b/include/linux/fsl/ptp_qoriq.h
@@ -58,15 +58,15 @@ struct ptp_qoriq_registers {
 };
 
 /* Offset definitions for the four register groups */
-#define CTRL_REGS_OFFSET   0x0
-#define ALARM_REGS_OFFSET  0x40
-#define FIPER_REGS_OFFSET  0x80
-#define ETTS_REGS_OFFSET   0xa0
-
-#define FMAN_CTRL_REGS_OFFSET  0x80
-#define FMAN_ALARM_REGS_OFFSET 0xb8
-#define FMAN_FIPER_REGS_OFFSET 0xd0
-#define FMAN_ETTS_REGS_OFFSET  0xe0
+#define ETSEC_CTRL_REGS_OFFSET 0x0
+#define ETSEC_ALARM_REGS_OFFSET0x40
+#define ETSEC_FIPER_REGS_OFFSET0x80
+#define ETSEC_ETTS_REGS_OFFSET 0xa0
+
+#define CTRL_REGS_OFFSET   0x80
+#define ALARM_REGS_OFFSET  0xb8
+#define FIPER_REGS_OFFSET  0xd0
+#define ETTS_REGS_OFFSET   0xe0
 
 
 /* Bit definitions for the TMR_CTRL register */
-- 
1.7.1



[PATCH 5/9] dt-binding: ptp_qoriq: add little-endian support

2019-01-30 Thread Yangbo Lu
Specify "little-endian" property if the 1588 timer IP block
is little-endian mode. The default endian mode is big-endian.

Signed-off-by: Yangbo Lu 
---
 .../devicetree/bindings/ptp/ptp-qoriq.txt  |3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/Documentation/devicetree/bindings/ptp/ptp-qoriq.txt 
b/Documentation/devicetree/bindings/ptp/ptp-qoriq.txt
index 8e7f855..454c937 100644
--- a/Documentation/devicetree/bindings/ptp/ptp-qoriq.txt
+++ b/Documentation/devicetree/bindings/ptp/ptp-qoriq.txt
@@ -19,6 +19,9 @@ Clock Properties:
   - fsl,max-adj  Maximum frequency adjustment in parts per billion.
   - fsl,extts-fifo   The presence of this property indicates hardware
 support for the external trigger stamp FIFO.
+  - little-endianThe presence of this property indicates the 1588 timer
+IP block is little-endian mode. The default endian mode
+is big-endian.
 
   These properties set the operational parameters for the PTP
   clock. You must choose these carefully for the clock to work right.
-- 
1.7.1



[PATCH 2/9] ptp_qoriq: make ptp operations global

2019-01-30 Thread Yangbo Lu
This patch is to make functions of ptp operations global,
so that ENETC PTP driver which is a PCI driver for same
1588 timer IP block could reuse them.

Signed-off-by: Yangbo Lu 
---
 drivers/ptp/ptp_qoriq.c   |   27 ---
 include/linux/fsl/ptp_qoriq.h |9 +
 2 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/drivers/ptp/ptp_qoriq.c b/drivers/ptp/ptp_qoriq.c
index 8c10d0f..1f3e73e 100644
--- a/drivers/ptp/ptp_qoriq.c
+++ b/drivers/ptp/ptp_qoriq.c
@@ -22,7 +22,6 @@
 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -135,7 +134,7 @@ static int extts_clean_up(struct ptp_qoriq *ptp_qoriq, int 
index,
  * Interrupt service routine
  */
 
-static irqreturn_t isr(int irq, void *priv)
+irqreturn_t ptp_qoriq_isr(int irq, void *priv)
 {
struct ptp_qoriq *ptp_qoriq = priv;
struct ptp_qoriq_registers *regs = &ptp_qoriq->regs;
@@ -200,12 +199,13 @@ static irqreturn_t isr(int irq, void *priv)
} else
return IRQ_NONE;
 }
+EXPORT_SYMBOL_GPL(ptp_qoriq_isr);
 
 /*
  * PTP clock operations
  */
 
-static int ptp_qoriq_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
+int ptp_qoriq_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
 {
u64 adj, diff;
u32 tmr_add;
@@ -233,8 +233,9 @@ static int ptp_qoriq_adjfine(struct ptp_clock_info *ptp, 
long scaled_ppm)
 
return 0;
 }
+EXPORT_SYMBOL_GPL(ptp_qoriq_adjfine);
 
-static int ptp_qoriq_adjtime(struct ptp_clock_info *ptp, s64 delta)
+int ptp_qoriq_adjtime(struct ptp_clock_info *ptp, s64 delta)
 {
s64 now;
unsigned long flags;
@@ -251,9 +252,9 @@ static int ptp_qoriq_adjtime(struct ptp_clock_info *ptp, 
s64 delta)
 
return 0;
 }
+EXPORT_SYMBOL_GPL(ptp_qoriq_adjtime);
 
-static int ptp_qoriq_gettime(struct ptp_clock_info *ptp,
-  struct timespec64 *ts)
+int ptp_qoriq_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
 {
u64 ns;
unsigned long flags;
@@ -269,9 +270,10 @@ static int ptp_qoriq_gettime(struct ptp_clock_info *ptp,
 
return 0;
 }
+EXPORT_SYMBOL_GPL(ptp_qoriq_gettime);
 
-static int ptp_qoriq_settime(struct ptp_clock_info *ptp,
-  const struct timespec64 *ts)
+int ptp_qoriq_settime(struct ptp_clock_info *ptp,
+ const struct timespec64 *ts)
 {
u64 ns;
unsigned long flags;
@@ -288,9 +290,10 @@ static int ptp_qoriq_settime(struct ptp_clock_info *ptp,
 
return 0;
 }
+EXPORT_SYMBOL_GPL(ptp_qoriq_settime);
 
-static int ptp_qoriq_enable(struct ptp_clock_info *ptp,
- struct ptp_clock_request *rq, int on)
+int ptp_qoriq_enable(struct ptp_clock_info *ptp,
+struct ptp_clock_request *rq, int on)
 {
struct ptp_qoriq *ptp_qoriq = container_of(ptp, struct ptp_qoriq, caps);
struct ptp_qoriq_registers *regs = &ptp_qoriq->regs;
@@ -336,6 +339,7 @@ static int ptp_qoriq_enable(struct ptp_clock_info *ptp,
spin_unlock_irqrestore(&ptp_qoriq->lock, flags);
return 0;
 }
+EXPORT_SYMBOL_GPL(ptp_qoriq_enable);
 
 static const struct ptp_clock_info ptp_qoriq_caps = {
.owner  = THIS_MODULE,
@@ -508,7 +512,8 @@ static int ptp_qoriq_probe(struct platform_device *dev)
pr_err("irq not in device tree\n");
goto no_node;
}
-   if (request_irq(ptp_qoriq->irq, isr, IRQF_SHARED, DRIVER, ptp_qoriq)) {
+   if (request_irq(ptp_qoriq->irq, ptp_qoriq_isr, IRQF_SHARED,
+   DRIVER, ptp_qoriq)) {
pr_err("request_irq failed\n");
goto no_node;
}
diff --git a/include/linux/fsl/ptp_qoriq.h b/include/linux/fsl/ptp_qoriq.h
index c2a32d9..75e6f05 100644
--- a/include/linux/fsl/ptp_qoriq.h
+++ b/include/linux/fsl/ptp_qoriq.h
@@ -7,6 +7,7 @@
 #define __PTP_QORIQ_H__
 
 #include 
+#include 
 #include 
 
 /*
@@ -171,6 +172,14 @@ static inline void qoriq_write(unsigned __iomem *addr, u32 
val)
iowrite32be(val, addr);
 }
 
+irqreturn_t ptp_qoriq_isr(int irq, void *priv);
+int ptp_qoriq_adjfine(struct ptp_clock_info *ptp, long scaled_ppm);
+int ptp_qoriq_adjtime(struct ptp_clock_info *ptp, s64 delta);
+int ptp_qoriq_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts);
+int ptp_qoriq_settime(struct ptp_clock_info *ptp,
+ const struct timespec64 *ts);
+int ptp_qoriq_enable(struct ptp_clock_info *ptp,
+struct ptp_clock_request *rq, int on);
 #ifdef CONFIG_DEBUG_FS
 void ptp_qoriq_create_debugfs(struct ptp_qoriq *ptp_qoriq);
 void ptp_qoriq_remove_debugfs(struct ptp_qoriq *ptp_qoriq);
-- 
1.7.1



[PATCH 7/9] ptp: add QorIQ PTP support for ENETC

2019-01-30 Thread Yangbo Lu
This patch is to add QorIQ PTP support for ENETC.
ENETC PTP driver which is a PCI driver for same
1588 timer IP block will reuse QorIQ PTP driver.

Signed-off-by: Yangbo Lu 
---
 drivers/ptp/Kconfig |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/ptp/Kconfig b/drivers/ptp/Kconfig
index aeb4a8b..7fe1863 100644
--- a/drivers/ptp/Kconfig
+++ b/drivers/ptp/Kconfig
@@ -43,7 +43,7 @@ config PTP_1588_CLOCK_DTE
 
 config PTP_1588_CLOCK_QORIQ
tristate "Freescale QorIQ 1588 timer as PTP clock"
-   depends on GIANFAR || FSL_DPAA_ETH
+   depends on GIANFAR || FSL_DPAA_ETH || FSL_ENETC || FSL_ENETC_VF
depends on PTP_1588_CLOCK
default y
help
-- 
1.7.1



[PATCH 0/9] Add ENETC PTP clock driver

2019-01-30 Thread Yangbo Lu
There is same QorIQ 1588 timer IP block on the new ENETC Ethernet
controller with eTSEC/DPAA Ethernet controllers. However it's
different endianness (little-endian) and using PCI driver.

To support ENETC PTP driver, ptp_qoriq driver needed to be
reworked to make functions global for reusing, to add little-
endian support, to add ENETC memory map support, and to add
ENETC dependency for ptp_qoriq driver.

In addition, although ENETC PTP driver is a PCI driver, the dts
node still could be used. Currently the ls1028a dtsi which is
the only platform by now using ENETC is not complete, so there
is still dependency for ENETC PTP node upstreaming. This will
be done in the near future. The hardware timestamping support
for ENETC is done but needs to be reworked with new method in
internal git tree, and will be sent out soon.

Yangbo Lu (9):
  ptp_qoriq: make structure/function names more consistent
  ptp_qoriq: make ptp operations global
  ptp_qoriq: convert to use ptp_qoriq_init()
  ptp_qoriq: add little enadian support
  dt-binding: ptp_qoriq: add little-endian support
  ptp_qoriq: fix register memory map
  ptp: add QorIQ PTP support for ENETC
  enetc: add PTP clock driver
  MAINTAINERS: add enetc_ptp driver into QorIQ PTP list

 .../devicetree/bindings/ptp/ptp-qoriq.txt  |3 +
 MAINTAINERS|1 +
 drivers/net/ethernet/freescale/enetc/Kconfig   |   12 +
 drivers/net/ethernet/freescale/enetc/Makefile  |3 +
 drivers/net/ethernet/freescale/enetc/enetc_hw.h|5 +-
 drivers/net/ethernet/freescale/enetc/enetc_ptp.c   |  151 +++
 drivers/ptp/Kconfig|2 +-
 drivers/ptp/ptp_qoriq.c|  427 ++--
 drivers/ptp/ptp_qoriq_debugfs.c|   48 ++--
 include/linux/fsl/ptp_qoriq.h  |   62 ++-
 10 files changed, 462 insertions(+), 252 deletions(-)
 create mode 100644 drivers/net/ethernet/freescale/enetc/enetc_ptp.c



[PATCH 1/9] ptp_qoriq: make structure/function names more consistent

2019-01-30 Thread Yangbo Lu
Strings containing "ptp_qoriq" or "qoriq_ptp" which were used for
structure/function names were complained by users. Let's just use
the unique "ptp_qoriq" to make these names more consistent.
This patch is just to unify the names using "ptp_qoriq". It hasn't
changed any functions.

Signed-off-by: Yangbo Lu 
---
 drivers/ptp/ptp_qoriq.c |  288 +++---
 drivers/ptp/ptp_qoriq_debugfs.c |   36 +++---
 include/linux/fsl/ptp_qoriq.h   |   14 +-
 3 files changed, 169 insertions(+), 169 deletions(-)

diff --git a/drivers/ptp/ptp_qoriq.c b/drivers/ptp/ptp_qoriq.c
index 43416b2..8c10d0f 100644
--- a/drivers/ptp/ptp_qoriq.c
+++ b/drivers/ptp/ptp_qoriq.c
@@ -37,10 +37,10 @@
  * Register access functions
  */
 
-/* Caller must hold qoriq_ptp->lock. */
-static u64 tmr_cnt_read(struct qoriq_ptp *qoriq_ptp)
+/* Caller must hold ptp_qoriq->lock. */
+static u64 tmr_cnt_read(struct ptp_qoriq *ptp_qoriq)
 {
-   struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
+   struct ptp_qoriq_registers *regs = &ptp_qoriq->regs;
u64 ns;
u32 lo, hi;
 
@@ -51,10 +51,10 @@ static u64 tmr_cnt_read(struct qoriq_ptp *qoriq_ptp)
return ns;
 }
 
-/* Caller must hold qoriq_ptp->lock. */
-static void tmr_cnt_write(struct qoriq_ptp *qoriq_ptp, u64 ns)
+/* Caller must hold ptp_qoriq->lock. */
+static void tmr_cnt_write(struct ptp_qoriq *ptp_qoriq, u64 ns)
 {
-   struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
+   struct ptp_qoriq_registers *regs = &ptp_qoriq->regs;
u32 hi = ns >> 32;
u32 lo = ns & 0x;
 
@@ -62,36 +62,36 @@ static void tmr_cnt_write(struct qoriq_ptp *qoriq_ptp, u64 
ns)
qoriq_write(®s->ctrl_regs->tmr_cnt_h, hi);
 }
 
-/* Caller must hold qoriq_ptp->lock. */
-static void set_alarm(struct qoriq_ptp *qoriq_ptp)
+/* Caller must hold ptp_qoriq->lock. */
+static void set_alarm(struct ptp_qoriq *ptp_qoriq)
 {
-   struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
+   struct ptp_qoriq_registers *regs = &ptp_qoriq->regs;
u64 ns;
u32 lo, hi;
 
-   ns = tmr_cnt_read(qoriq_ptp) + 15ULL;
+   ns = tmr_cnt_read(ptp_qoriq) + 15ULL;
ns = div_u64(ns, 10UL) * 10ULL;
-   ns -= qoriq_ptp->tclk_period;
+   ns -= ptp_qoriq->tclk_period;
hi = ns >> 32;
lo = ns & 0x;
qoriq_write(®s->alarm_regs->tmr_alarm1_l, lo);
qoriq_write(®s->alarm_regs->tmr_alarm1_h, hi);
 }
 
-/* Caller must hold qoriq_ptp->lock. */
-static void set_fipers(struct qoriq_ptp *qoriq_ptp)
+/* Caller must hold ptp_qoriq->lock. */
+static void set_fipers(struct ptp_qoriq *ptp_qoriq)
 {
-   struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
+   struct ptp_qoriq_registers *regs = &ptp_qoriq->regs;
 
-   set_alarm(qoriq_ptp);
-   qoriq_write(®s->fiper_regs->tmr_fiper1, qoriq_ptp->tmr_fiper1);
-   qoriq_write(®s->fiper_regs->tmr_fiper2, qoriq_ptp->tmr_fiper2);
+   set_alarm(ptp_qoriq);
+   qoriq_write(®s->fiper_regs->tmr_fiper1, ptp_qoriq->tmr_fiper1);
+   qoriq_write(®s->fiper_regs->tmr_fiper2, ptp_qoriq->tmr_fiper2);
 }
 
-static int extts_clean_up(struct qoriq_ptp *qoriq_ptp, int index,
+static int extts_clean_up(struct ptp_qoriq *ptp_qoriq, int index,
  bool update_event)
 {
-   struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
+   struct ptp_qoriq_registers *regs = &ptp_qoriq->regs;
struct ptp_clock_event event;
void __iomem *reg_etts_l;
void __iomem *reg_etts_h;
@@ -122,11 +122,11 @@ static int extts_clean_up(struct qoriq_ptp *qoriq_ptp, 
int index,
if (update_event) {
event.timestamp = ((u64) hi) << 32;
event.timestamp |= lo;
-   ptp_clock_event(qoriq_ptp->clock, &event);
+   ptp_clock_event(ptp_qoriq->clock, &event);
}
 
stat = qoriq_read(®s->ctrl_regs->tmr_stat);
-   } while (qoriq_ptp->extts_fifo_support && (stat & valid));
+   } while (ptp_qoriq->extts_fifo_support && (stat & valid));
 
return 0;
 }
@@ -137,61 +137,61 @@ static int extts_clean_up(struct qoriq_ptp *qoriq_ptp, 
int index,
 
 static irqreturn_t isr(int irq, void *priv)
 {
-   struct qoriq_ptp *qoriq_ptp = priv;
-   struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
+   struct ptp_qoriq *ptp_qoriq = priv;
+   struct ptp_qoriq_registers *regs = &ptp_qoriq->regs;
struct ptp_clock_event event;
u64 ns;
u32 ack = 0, lo, hi, mask, val, irqs;
 
-   spin_lock(&qoriq_ptp->lock);
+   sp

[PATCH 4/9] ptp_qoriq: add little enadian support

2019-01-30 Thread Yangbo Lu
There is QorIQ 1588 timer IP block on the new ENETC Ethernet
controller. However it uses little endian mode which is different
with before. This patch is to add little endian support for the
driver by using "little-endian" dts node property.

Signed-off-by: Yangbo Lu 
---
 drivers/ptp/ptp_qoriq.c |   69 ++-
 drivers/ptp/ptp_qoriq_debugfs.c |   12 +++---
 include/linux/fsl/ptp_qoriq.h   |   21 ---
 3 files changed, 60 insertions(+), 42 deletions(-)

diff --git a/drivers/ptp/ptp_qoriq.c b/drivers/ptp/ptp_qoriq.c
index 63896b5..4308e25 100644
--- a/drivers/ptp/ptp_qoriq.c
+++ b/drivers/ptp/ptp_qoriq.c
@@ -43,8 +43,8 @@ static u64 tmr_cnt_read(struct ptp_qoriq *ptp_qoriq)
u64 ns;
u32 lo, hi;
 
-   lo = qoriq_read(®s->ctrl_regs->tmr_cnt_l);
-   hi = qoriq_read(®s->ctrl_regs->tmr_cnt_h);
+   lo = ptp_qoriq->read(®s->ctrl_regs->tmr_cnt_l);
+   hi = ptp_qoriq->read(®s->ctrl_regs->tmr_cnt_h);
ns = ((u64) hi) << 32;
ns |= lo;
return ns;
@@ -57,8 +57,8 @@ static void tmr_cnt_write(struct ptp_qoriq *ptp_qoriq, u64 ns)
u32 hi = ns >> 32;
u32 lo = ns & 0x;
 
-   qoriq_write(®s->ctrl_regs->tmr_cnt_l, lo);
-   qoriq_write(®s->ctrl_regs->tmr_cnt_h, hi);
+   ptp_qoriq->write(®s->ctrl_regs->tmr_cnt_l, lo);
+   ptp_qoriq->write(®s->ctrl_regs->tmr_cnt_h, hi);
 }
 
 /* Caller must hold ptp_qoriq->lock. */
@@ -73,8 +73,8 @@ static void set_alarm(struct ptp_qoriq *ptp_qoriq)
ns -= ptp_qoriq->tclk_period;
hi = ns >> 32;
lo = ns & 0x;
-   qoriq_write(®s->alarm_regs->tmr_alarm1_l, lo);
-   qoriq_write(®s->alarm_regs->tmr_alarm1_h, hi);
+   ptp_qoriq->write(®s->alarm_regs->tmr_alarm1_l, lo);
+   ptp_qoriq->write(®s->alarm_regs->tmr_alarm1_h, hi);
 }
 
 /* Caller must hold ptp_qoriq->lock. */
@@ -83,8 +83,8 @@ static void set_fipers(struct ptp_qoriq *ptp_qoriq)
struct ptp_qoriq_registers *regs = &ptp_qoriq->regs;
 
set_alarm(ptp_qoriq);
-   qoriq_write(®s->fiper_regs->tmr_fiper1, ptp_qoriq->tmr_fiper1);
-   qoriq_write(®s->fiper_regs->tmr_fiper2, ptp_qoriq->tmr_fiper2);
+   ptp_qoriq->write(®s->fiper_regs->tmr_fiper1, ptp_qoriq->tmr_fiper1);
+   ptp_qoriq->write(®s->fiper_regs->tmr_fiper2, ptp_qoriq->tmr_fiper2);
 }
 
 static int extts_clean_up(struct ptp_qoriq *ptp_qoriq, int index,
@@ -115,8 +115,8 @@ static int extts_clean_up(struct ptp_qoriq *ptp_qoriq, int 
index,
event.index = index;
 
do {
-   lo = qoriq_read(reg_etts_l);
-   hi = qoriq_read(reg_etts_h);
+   lo = ptp_qoriq->read(reg_etts_l);
+   hi = ptp_qoriq->read(reg_etts_h);
 
if (update_event) {
event.timestamp = ((u64) hi) << 32;
@@ -124,7 +124,7 @@ static int extts_clean_up(struct ptp_qoriq *ptp_qoriq, int 
index,
ptp_clock_event(ptp_qoriq->clock, &event);
}
 
-   stat = qoriq_read(®s->ctrl_regs->tmr_stat);
+   stat = ptp_qoriq->read(®s->ctrl_regs->tmr_stat);
} while (ptp_qoriq->extts_fifo_support && (stat & valid));
 
return 0;
@@ -144,8 +144,8 @@ irqreturn_t ptp_qoriq_isr(int irq, void *priv)
 
spin_lock(&ptp_qoriq->lock);
 
-   val = qoriq_read(®s->ctrl_regs->tmr_tevent);
-   mask = qoriq_read(®s->ctrl_regs->tmr_temask);
+   val = ptp_qoriq->read(®s->ctrl_regs->tmr_tevent);
+   mask = ptp_qoriq->read(®s->ctrl_regs->tmr_temask);
 
spin_unlock(&ptp_qoriq->lock);
 
@@ -173,14 +173,14 @@ irqreturn_t ptp_qoriq_isr(int irq, void *priv)
ns = ptp_qoriq->alarm_value + ptp_qoriq->alarm_interval;
hi = ns >> 32;
lo = ns & 0x;
-   qoriq_write(®s->alarm_regs->tmr_alarm2_l, lo);
-   qoriq_write(®s->alarm_regs->tmr_alarm2_h, hi);
+   ptp_qoriq->write(®s->alarm_regs->tmr_alarm2_l, lo);
+   ptp_qoriq->write(®s->alarm_regs->tmr_alarm2_h, hi);
ptp_qoriq->alarm_value = ns;
} else {
spin_lock(&ptp_qoriq->lock);
-   mask = qoriq_read(®s->ctrl_regs->tmr_temask);
+   mask = ptp_qoriq->read(®s->ctrl_regs->tmr_temask);
mask &= ~ALM2EN;
-   qoriq_write(®s->ctrl_regs->tmr_temask, mask);
+   ptp_qoriq->write(®s->ctrl_regs->tmr_temask, mask);
 

[PATCH 9/9] MAINTAINERS: add enetc_ptp driver into QorIQ PTP list

2019-01-30 Thread Yangbo Lu
This patch to add enetc_ptp driver into QorIQ PTP list
for maintaining.

Signed-off-by: Yangbo Lu 
---
 MAINTAINERS |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 019a2bc..f0b50f8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6093,6 +6093,7 @@ FREESCALE QORIQ PTP CLOCK DRIVER
 M: Yangbo Lu 
 L: netdev@vger.kernel.org
 S: Maintained
+F: drivers/net/ethernet/freescale/enetc/enetc_ptp.c
 F: drivers/ptp/ptp_qoriq.c
 F: drivers/ptp/ptp_qoriq_debugfs.c
 F: include/linux/fsl/ptp_qoriq.h
-- 
1.7.1



[PATCH 8/9] enetc: add PTP clock driver

2019-01-30 Thread Yangbo Lu
This patch is to add PTP clock driver for ENETC.
The driver reused QorIQ PTP clock driver.

Signed-off-by: Yangbo Lu 
---
 drivers/net/ethernet/freescale/enetc/Kconfig |   12 ++
 drivers/net/ethernet/freescale/enetc/Makefile|3 +
 drivers/net/ethernet/freescale/enetc/enetc_hw.h  |5 +-
 drivers/net/ethernet/freescale/enetc/enetc_ptp.c |  151 ++
 4 files changed, 169 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/ethernet/freescale/enetc/enetc_ptp.c

diff --git a/drivers/net/ethernet/freescale/enetc/Kconfig 
b/drivers/net/ethernet/freescale/enetc/Kconfig
index f9dd26f..8429f5c 100644
--- a/drivers/net/ethernet/freescale/enetc/Kconfig
+++ b/drivers/net/ethernet/freescale/enetc/Kconfig
@@ -17,3 +17,15 @@ config FSL_ENETC_VF
  virtual function (VF) devices enabled by the ENETC PF driver.
 
  If compiled as module (M), the module name is fsl-enetc-vf.
+
+config FSL_ENETC_PTP_CLOCK
+   tristate "ENETC PTP clock driver"
+   depends on PTP_1588_CLOCK_QORIQ && (FSL_ENETC || FSL_ENETC_VF)
+   default y
+   help
+ This driver adds support for using the ENETC 1588 timer
+ as a PTP clock. This clock is only useful if your PTP
+ programs are getting hardware time stamps on the PTP Ethernet
+ packets using the SO_TIMESTAMPING API.
+
+ If compiled as module (M), the module name is fsl-enetc-ptp.
diff --git a/drivers/net/ethernet/freescale/enetc/Makefile 
b/drivers/net/ethernet/freescale/enetc/Makefile
index 9529b01..6976602 100644
--- a/drivers/net/ethernet/freescale/enetc/Makefile
+++ b/drivers/net/ethernet/freescale/enetc/Makefile
@@ -13,3 +13,6 @@ fsl-enetc-vf-$(CONFIG_FSL_ENETC_VF) += enetc.o enetc_cbdr.o \
   enetc_ethtool.o
 fsl-enetc-vf-objs := enetc_vf.o $(fsl-enetc-vf-y)
 endif
+
+obj-$(CONFIG_FSL_ENETC_PTP_CLOCK) += fsl-enetc-ptp.o
+fsl-enetc-ptp-$(CONFIG_FSL_ENETC_PTP_CLOCK) += enetc_ptp.o
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_hw.h 
b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
index efa0b1a..df8eb88 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h
+++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
@@ -4,8 +4,9 @@
 #include 
 
 /* ENETC device IDs */
-#define ENETC_DEV_ID_PF0xe100
-#define ENETC_DEV_ID_VF0xef00
+#define ENETC_DEV_ID_PF0xe100
+#define ENETC_DEV_ID_VF0xef00
+#define ENETC_DEV_ID_PTP   0xee02
 
 /* ENETC register block BAR */
 #define ENETC_BAR_REGS 0
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_ptp.c 
b/drivers/net/ethernet/freescale/enetc/enetc_ptp.c
new file mode 100644
index 000..1cebb4c
--- /dev/null
+++ b/drivers/net/ethernet/freescale/enetc/enetc_ptp.c
@@ -0,0 +1,151 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/* Copyright 2019 NXP */
+
+#include 
+#include 
+#include 
+
+#include "enetc.h"
+
+static struct ptp_clock_info enetc_ptp_caps = {
+   .owner  = THIS_MODULE,
+   .name   = "ENETC PTP clock",
+   .max_adj= 512000,
+   .n_alarm= 0,
+   .n_ext_ts   = 2,
+   .n_per_out  = 0,
+   .n_pins = 0,
+   .pps= 1,
+   .adjfine= ptp_qoriq_adjfine,
+   .adjtime= ptp_qoriq_adjtime,
+   .gettime64  = ptp_qoriq_gettime,
+   .settime64  = ptp_qoriq_settime,
+   .enable = ptp_qoriq_enable,
+};
+
+static int enetc_ptp_probe(struct pci_dev *pdev,
+  const struct pci_device_id *ent)
+{
+   struct ptp_qoriq *ptp_qoriq;
+   void __iomem *base;
+   int err, len, n;
+
+   if (pdev->dev.of_node && !of_device_is_available(pdev->dev.of_node)) {
+   dev_info(&pdev->dev, "device is disabled, skipping\n");
+   return -ENODEV;
+   }
+
+   err = pci_enable_device_mem(pdev);
+   if (err) {
+   dev_err(&pdev->dev, "device enable failed\n");
+   return err;
+   }
+
+   /* set up for high or low dma */
+   err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
+   if (err) {
+   err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+   if (err) {
+   dev_err(&pdev->dev,
+   "DMA configuration failed: 0x%x\n", err);
+   goto err_dma;
+   }
+   }
+
+   err = pci_request_mem_regions(pdev, KBUILD_MODNAME);
+   if (err) {
+   dev_err(&pdev->dev, "pci_request_regions failed err=%d\n", err);
+   goto err_pci_mem_reg;
+   }
+
+   pci_set_master(pdev);
+
+   ptp_qoriq = kzalloc(sizeof(*ptp_qoriq), GFP_KERNEL);
+   if (!ptp_qoriq) {
+   err = -ENOMEM;
+   goto err_alloc_ptp;
+ 

[v3, 5/6] ptp: add debugfs support for ptp_qoriq

2019-01-21 Thread Yangbo Lu
This patch is to add debugfs support for ptp_qoriq. Current debugfs
supports to control fiper1/fiper2 loopback mode. If the loopback mode
is enabled, the fiper1/fiper2 pulse is looped back into trigger1/
trigger2 input. This is very useful for validating hardware and driver
without external hardware. Below is an example to enable fiper1 loopback.

echo 1 > /sys/kernel/debug/2d10e00.ptp_clock/fiper1-loopback

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
Changes for v3:
- Converted to use debugfs.
---
 drivers/ptp/Kconfig |2 +-
 drivers/ptp/Makefile|4 +-
 drivers/ptp/ptp_qoriq.c |3 +
 drivers/ptp/ptp_qoriq_debugfs.c |  101 +++
 include/linux/fsl/ptp_qoriq.h   |   12 +
 5 files changed, 120 insertions(+), 2 deletions(-)
 create mode 100644 drivers/ptp/ptp_qoriq_debugfs.c

diff --git a/drivers/ptp/Kconfig b/drivers/ptp/Kconfig
index d137c48..aeb4a8b 100644
--- a/drivers/ptp/Kconfig
+++ b/drivers/ptp/Kconfig
@@ -53,7 +53,7 @@ config PTP_1588_CLOCK_QORIQ
  packets using the SO_TIMESTAMPING API.
 
  To compile this driver as a module, choose M here: the module
- will be called ptp_qoriq.
+ will be called ptp-qoriq.
 
 config PTP_1588_CLOCK_IXP46X
tristate "Intel IXP46x as PTP clock"
diff --git a/drivers/ptp/Makefile b/drivers/ptp/Makefile
index 19efa9c..677d1d1 100644
--- a/drivers/ptp/Makefile
+++ b/drivers/ptp/Makefile
@@ -9,4 +9,6 @@ obj-$(CONFIG_PTP_1588_CLOCK_DTE)+= ptp_dte.o
 obj-$(CONFIG_PTP_1588_CLOCK_IXP46X)+= ptp_ixp46x.o
 obj-$(CONFIG_PTP_1588_CLOCK_PCH)   += ptp_pch.o
 obj-$(CONFIG_PTP_1588_CLOCK_KVM)   += ptp_kvm.o
-obj-$(CONFIG_PTP_1588_CLOCK_QORIQ) += ptp_qoriq.o
+obj-$(CONFIG_PTP_1588_CLOCK_QORIQ) += ptp-qoriq.o
+ptp-qoriq-y+= ptp_qoriq.o
+ptp-qoriq-$(CONFIG_DEBUG_FS)   += ptp_qoriq_debugfs.o
diff --git a/drivers/ptp/ptp_qoriq.c b/drivers/ptp/ptp_qoriq.c
index a2e7702..43416b2 100644
--- a/drivers/ptp/ptp_qoriq.c
+++ b/drivers/ptp/ptp_qoriq.c
@@ -471,6 +471,7 @@ static int qoriq_ptp_probe(struct platform_device *dev)
 
err = -EINVAL;
 
+   qoriq_ptp->dev = &dev->dev;
qoriq_ptp->caps = ptp_qoriq_caps;
 
if (of_property_read_u32(node, "fsl,cksel", &qoriq_ptp->cksel))
@@ -572,6 +573,7 @@ static int qoriq_ptp_probe(struct platform_device *dev)
}
qoriq_ptp->phc_index = ptp_clock_index(qoriq_ptp->clock);
 
+   ptp_qoriq_create_debugfs(qoriq_ptp);
platform_set_drvdata(dev, qoriq_ptp);
 
return 0;
@@ -597,6 +599,7 @@ static int qoriq_ptp_remove(struct platform_device *dev)
qoriq_write(®s->ctrl_regs->tmr_temask, 0);
qoriq_write(®s->ctrl_regs->tmr_ctrl,   0);
 
+   ptp_qoriq_remove_debugfs(qoriq_ptp);
ptp_clock_unregister(qoriq_ptp->clock);
iounmap(qoriq_ptp->base);
release_resource(qoriq_ptp->rsrc);
diff --git a/drivers/ptp/ptp_qoriq_debugfs.c b/drivers/ptp/ptp_qoriq_debugfs.c
new file mode 100644
index 000..d904332
--- /dev/null
+++ b/drivers/ptp/ptp_qoriq_debugfs.c
@@ -0,0 +1,101 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* Copyright 2019 NXP
+ */
+#include 
+#include 
+#include 
+
+static int ptp_qoriq_fiper1_lpbk_get(void *data, u64 *val)
+{
+   struct qoriq_ptp *qoriq_ptp = data;
+   struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
+   u32 ctrl;
+
+   ctrl = qoriq_read(®s->ctrl_regs->tmr_ctrl);
+   *val = ctrl & PP1L ? 1 : 0;
+
+   return 0;
+}
+
+static int ptp_qoriq_fiper1_lpbk_set(void *data, u64 val)
+{
+   struct qoriq_ptp *qoriq_ptp = data;
+   struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
+   u32 ctrl;
+
+   ctrl = qoriq_read(®s->ctrl_regs->tmr_ctrl);
+   if (val == 0)
+   ctrl &= ~PP1L;
+   else
+   ctrl |= PP1L;
+
+   qoriq_write(®s->ctrl_regs->tmr_ctrl, ctrl);
+   return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(ptp_qoriq_fiper1_fops, ptp_qoriq_fiper1_lpbk_get,
+   ptp_qoriq_fiper1_lpbk_set, "%llu\n");
+
+static int ptp_qoriq_fiper2_lpbk_get(void *data, u64 *val)
+{
+   struct qoriq_ptp *qoriq_ptp = data;
+   struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
+   u32 ctrl;
+
+   ctrl = qoriq_read(®s->ctrl_regs->tmr_ctrl);
+   *val = ctrl & PP2L ? 1 : 0;
+
+   return 0;
+}
+
+static int ptp_qoriq_fiper2_lpbk_set(void *data, u64 val)
+{
+   struct qoriq_ptp *qoriq_ptp = data;
+   struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
+   u32 ctrl;
+
+   ctrl = qoriq_read(®s->ctrl_regs->tmr_ctrl);
+   if (val == 0)
+   ctrl &= ~PP2L;
+   else
+   ctrl |= PP2L;
+
+   qoriq_write(®s->ctrl_regs->tmr_ctrl, ctrl);
+   return 0;
+}
+
+DEFINE_S

[v3, 3/6] dt-binding: ptp_qoriq: document "fsl,extts-fifo" property

2019-01-21 Thread Yangbo Lu
Documented "fsl,extts-fifo" property.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- Modified binding description.
Changes for v3:
- Rephrased fsl,extts-fifo.
---
 .../devicetree/bindings/ptp/ptp-qoriq.txt  |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/Documentation/devicetree/bindings/ptp/ptp-qoriq.txt 
b/Documentation/devicetree/bindings/ptp/ptp-qoriq.txt
index c5d0e79..8e7f855 100644
--- a/Documentation/devicetree/bindings/ptp/ptp-qoriq.txt
+++ b/Documentation/devicetree/bindings/ptp/ptp-qoriq.txt
@@ -17,6 +17,8 @@ Clock Properties:
   - fsl,tmr-fiper1   Fixed interval period pulse generator.
   - fsl,tmr-fiper2   Fixed interval period pulse generator.
   - fsl,max-adj  Maximum frequency adjustment in parts per billion.
+  - fsl,extts-fifo   The presence of this property indicates hardware
+support for the external trigger stamp FIFO.
 
   These properties set the operational parameters for the PTP
   clock. You must choose these carefully for the clock to work right.
-- 
1.7.1



[v3, 1/6] ptp_qoriq: fix interrupt enabling and handling

2019-01-21 Thread Yangbo Lu
The tmr_tevent register would update event bits
no matter tmr_temask bits were set or not. So we
should get interrupts by tmr_tevent & tmr_temask,
and clean up interrupts in tmr_tevent before
enabling them.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- Remove useless lock/register operations.
Changes for v3:
- None.
---
 drivers/ptp/ptp_qoriq.c |   62 +++---
 1 files changed, 31 insertions(+), 31 deletions(-)

diff --git a/drivers/ptp/ptp_qoriq.c b/drivers/ptp/ptp_qoriq.c
index fdd49c2..2743214 100644
--- a/drivers/ptp/ptp_qoriq.c
+++ b/drivers/ptp/ptp_qoriq.c
@@ -98,11 +98,18 @@ static irqreturn_t isr(int irq, void *priv)
struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
struct ptp_clock_event event;
u64 ns;
-   u32 ack = 0, lo, hi, mask, val;
+   u32 ack = 0, lo, hi, mask, val, irqs;
+
+   spin_lock(&qoriq_ptp->lock);
 
val = qoriq_read(®s->ctrl_regs->tmr_tevent);
+   mask = qoriq_read(®s->ctrl_regs->tmr_temask);
+
+   spin_unlock(&qoriq_ptp->lock);
+
+   irqs = val & mask;
 
-   if (val & ETS1) {
+   if (irqs & ETS1) {
ack |= ETS1;
hi = qoriq_read(®s->etts_regs->tmr_etts1_h);
lo = qoriq_read(®s->etts_regs->tmr_etts1_l);
@@ -113,7 +120,7 @@ static irqreturn_t isr(int irq, void *priv)
ptp_clock_event(qoriq_ptp->clock, &event);
}
 
-   if (val & ETS2) {
+   if (irqs & ETS2) {
ack |= ETS2;
hi = qoriq_read(®s->etts_regs->tmr_etts2_h);
lo = qoriq_read(®s->etts_regs->tmr_etts2_l);
@@ -124,7 +131,7 @@ static irqreturn_t isr(int irq, void *priv)
ptp_clock_event(qoriq_ptp->clock, &event);
}
 
-   if (val & ALM2) {
+   if (irqs & ALM2) {
ack |= ALM2;
if (qoriq_ptp->alarm_value) {
event.type = PTP_CLOCK_ALARM;
@@ -136,13 +143,10 @@ static irqreturn_t isr(int irq, void *priv)
ns = qoriq_ptp->alarm_value + qoriq_ptp->alarm_interval;
hi = ns >> 32;
lo = ns & 0x;
-   spin_lock(&qoriq_ptp->lock);
qoriq_write(®s->alarm_regs->tmr_alarm2_l, lo);
qoriq_write(®s->alarm_regs->tmr_alarm2_h, hi);
-   spin_unlock(&qoriq_ptp->lock);
qoriq_ptp->alarm_value = ns;
} else {
-   qoriq_write(®s->ctrl_regs->tmr_tevent, ALM2);
spin_lock(&qoriq_ptp->lock);
mask = qoriq_read(®s->ctrl_regs->tmr_temask);
mask &= ~ALM2EN;
@@ -153,7 +157,7 @@ static irqreturn_t isr(int irq, void *priv)
}
}
 
-   if (val & PP1) {
+   if (irqs & PP1) {
ack |= PP1;
event.type = PTP_CLOCK_PPS;
ptp_clock_event(qoriq_ptp->clock, &event);
@@ -260,7 +264,7 @@ static int ptp_qoriq_enable(struct ptp_clock_info *ptp,
struct qoriq_ptp *qoriq_ptp = container_of(ptp, struct qoriq_ptp, caps);
struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
unsigned long flags;
-   u32 bit, mask;
+   u32 bit, mask = 0;
 
switch (rq->type) {
case PTP_CLK_REQ_EXTTS:
@@ -274,32 +278,28 @@ static int ptp_qoriq_enable(struct ptp_clock_info *ptp,
default:
return -EINVAL;
}
-   spin_lock_irqsave(&qoriq_ptp->lock, flags);
-   mask = qoriq_read(®s->ctrl_regs->tmr_temask);
-   if (on)
-   mask |= bit;
-   else
-   mask &= ~bit;
-   qoriq_write(®s->ctrl_regs->tmr_temask, mask);
-   spin_unlock_irqrestore(&qoriq_ptp->lock, flags);
-   return 0;
-
+   break;
case PTP_CLK_REQ_PPS:
-   spin_lock_irqsave(&qoriq_ptp->lock, flags);
-   mask = qoriq_read(®s->ctrl_regs->tmr_temask);
-   if (on)
-   mask |= PP1EN;
-   else
-   mask &= ~PP1EN;
-   qoriq_write(®s->ctrl_regs->tmr_temask, mask);
-   spin_unlock_irqrestore(&qoriq_ptp->lock, flags);
-   return 0;
-
-   default:
+   bit = PP1EN;
break;
+   default:
+   return -EOPNOTSUPP;
}
 
-   return -EOPNOTSUPP;
+   spin_lock_irqsave(&qoriq_ptp->lock, flags);
+
+   mask = qoriq_read(®s->ctrl_regs->tmr_temask);
+   if (on) {
+   mask |= bi

[v3, 2/6] ptp_qoriq: support external trigger stamp FIFO

2019-01-21 Thread Yangbo Lu
The external trigger stamp FIFO was introduced as a new feature
for QorIQ 1588 timer IP block. This patch is to support it by
adding a new dts property "fsl,extts-fifo". Any QorIQ 1588 timer
supporting this feature is required to add this property in its
dts node.

In addition, the FIFO should be cleaned up before enabling external
trigger interrupts. Otherwise, there will be interrupts immediately
just after enabling external trigger interrupts.

Signed-off-by: Yangbo Lu 
Signed-off-by: Vladimir Oltean 
---
Changes for v2:
- Converted to use extts_clean_up instead.
Changes for v3:
- None.
---
 drivers/ptp/ptp_qoriq.c   |   68 
 include/linux/fsl/ptp_qoriq.h |3 ++
 2 files changed, 57 insertions(+), 14 deletions(-)

diff --git a/drivers/ptp/ptp_qoriq.c b/drivers/ptp/ptp_qoriq.c
index 2743214..a2e7702 100644
--- a/drivers/ptp/ptp_qoriq.c
+++ b/drivers/ptp/ptp_qoriq.c
@@ -88,6 +88,49 @@ static void set_fipers(struct qoriq_ptp *qoriq_ptp)
qoriq_write(®s->fiper_regs->tmr_fiper2, qoriq_ptp->tmr_fiper2);
 }
 
+static int extts_clean_up(struct qoriq_ptp *qoriq_ptp, int index,
+ bool update_event)
+{
+   struct qoriq_ptp_registers *regs = &qoriq_ptp->regs;
+   struct ptp_clock_event event;
+   void __iomem *reg_etts_l;
+   void __iomem *reg_etts_h;
+   u32 valid, stat, lo, hi;
+
+   switch (index) {
+   case 0:
+   valid = ETS1_VLD;
+   reg_etts_l = ®s->etts_regs->tmr_etts1_l;
+   reg_etts_h = ®s->etts_regs->tmr_etts1_h;
+   break;
+   case 1:
+   valid = ETS2_VLD;
+   reg_etts_l = ®s->etts_regs->tmr_etts2_l;
+   reg_etts_h = ®s->etts_regs->tmr_etts2_h;
+   break;
+   default:
+   return -EINVAL;
+   }
+
+   event.type = PTP_CLOCK_EXTTS;
+   event.index = index;
+
+   do {
+   lo = qoriq_read(reg_etts_l);
+   hi = qoriq_read(reg_etts_h);
+
+   if (update_event) {
+   event.timestamp = ((u64) hi) << 32;
+   event.timestamp |= lo;
+   ptp_clock_event(qoriq_ptp->clock, &event);
+   }
+
+   stat = qoriq_read(®s->ctrl_regs->tmr_stat);
+   } while (qoriq_ptp->extts_fifo_support && (stat & valid));
+
+   return 0;
+}
+
 /*
  * Interrupt service routine
  */
@@ -111,24 +154,12 @@ static irqreturn_t isr(int irq, void *priv)
 
if (irqs & ETS1) {
ack |= ETS1;
-   hi = qoriq_read(®s->etts_regs->tmr_etts1_h);
-   lo = qoriq_read(®s->etts_regs->tmr_etts1_l);
-   event.type = PTP_CLOCK_EXTTS;
-   event.index = 0;
-   event.timestamp = ((u64) hi) << 32;
-   event.timestamp |= lo;
-   ptp_clock_event(qoriq_ptp->clock, &event);
+   extts_clean_up(qoriq_ptp, 0, true);
}
 
if (irqs & ETS2) {
ack |= ETS2;
-   hi = qoriq_read(®s->etts_regs->tmr_etts2_h);
-   lo = qoriq_read(®s->etts_regs->tmr_etts2_l);
-   event.type = PTP_CLOCK_EXTTS;
-   event.index = 1;
-   event.timestamp = ((u64) hi) << 32;
-   event.timestamp |= lo;
-   ptp_clock_event(qoriq_ptp->clock, &event);
+   extts_clean_up(qoriq_ptp, 1, true);
}
 
if (irqs & ALM2) {
@@ -278,6 +309,10 @@ static int ptp_qoriq_enable(struct ptp_clock_info *ptp,
default:
return -EINVAL;
}
+
+   if (on)
+   extts_clean_up(qoriq_ptp, rq->extts.index, false);
+
break;
case PTP_CLK_REQ_PPS:
bit = PP1EN;
@@ -441,6 +476,11 @@ static int qoriq_ptp_probe(struct platform_device *dev)
if (of_property_read_u32(node, "fsl,cksel", &qoriq_ptp->cksel))
qoriq_ptp->cksel = DEFAULT_CKSEL;
 
+   if (of_property_read_bool(node, "fsl,extts-fifo"))
+   qoriq_ptp->extts_fifo_support = true;
+   else
+   qoriq_ptp->extts_fifo_support = false;
+
if (of_property_read_u32(node,
 "fsl,tclk-period", &qoriq_ptp->tclk_period) ||
of_property_read_u32(node,
diff --git a/include/linux/fsl/ptp_qoriq.h b/include/linux/fsl/ptp_qoriq.h
index c1f003a..43b4b44 100644
--- a/include/linux/fsl/ptp_qoriq.h
+++ b/include/linux/fsl/ptp_qoriq.h
@@ -120,6 +120,8 @@ struct qoriq_ptp_registers {
 /* Bit definitions for the TMR_STAT register */
 #define STAT_VEC_SHIFT(0) /* Timer general purpose status vector */
 #define STAT_VEC_MASK (0x3f)
+#define ETS1_VL

[v3, 6/6] MAINTAINERS: add drivers/ptp/ptp_qoriq_debugfs.c into QorIQ PTP list

2019-01-21 Thread Yangbo Lu
Added drivers/ptp/ptp_qoriq_debugfs.c into QorIQ PTP clock driver list.

Signed-off-by: Yangbo Lu 
---
Changes for v3:
- Added this patch.
---
 MAINTAINERS |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index a592b99..098d0eb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6088,6 +6088,7 @@ M:Yangbo Lu 
 L: netdev@vger.kernel.org
 S: Maintained
 F: drivers/ptp/ptp_qoriq.c
+F: drivers/ptp/ptp_qoriq_debugfs.c
 F: include/linux/fsl/ptp_qoriq.h
 F: Documentation/devicetree/bindings/ptp/ptp-qoriq.txt
 
-- 
1.7.1



[v3, 0/6] External trigger stamp fifo support for ptp_qoriq

2019-01-21 Thread Yangbo Lu
This patch-set is to add external trigger stamp fifo support by a new
binding "fsl,extts-fifo", and to add fiper pulse loopback support which
is very useful for validating trigger without external hardware.
Also fixed issues in interrupt enabling/handling.

"fsl,extts-fifo" is required to be added into 1588 timer dts node whose
hardware supports it. The work will be done for some QorIQ platforms dts in
the near future.

Yangbo Lu (6):
  ptp_qoriq: fix interrupt enabling and handling
  ptp_qoriq: support external trigger stamp FIFO
  dt-binding: ptp_qoriq: document "fsl,extts-fifo" property
  ARM: dts: ls1021a: add 1588 external trigger stamp fifo support
  ptp: add debugfs support for ptp_qoriq
  MAINTAINERS: add drivers/ptp/ptp_qoriq_debugfs.c into QorIQ PTP list

 .../devicetree/bindings/ptp/ptp-qoriq.txt  |2 +
 MAINTAINERS|1 +
 arch/arm/boot/dts/ls1021a.dtsi |1 +
 drivers/ptp/Kconfig|2 +-
 drivers/ptp/Makefile   |4 +-
 drivers/ptp/ptp_qoriq.c|  129 +---
 drivers/ptp/ptp_qoriq_debugfs.c|  101 +++
 include/linux/fsl/ptp_qoriq.h  |   15 +++
 8 files changed, 210 insertions(+), 45 deletions(-)
 create mode 100644 drivers/ptp/ptp_qoriq_debugfs.c



[v3, 4/6] ARM: dts: ls1021a: add 1588 external trigger stamp fifo support

2019-01-21 Thread Yangbo Lu
This patch is to add external trigger stamp fifo support
for 1588 timer.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- None.
Changes for v3:
- None.
---
 arch/arm/boot/dts/ls1021a.dtsi |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
index ed09412..ad75959 100644
--- a/arch/arm/boot/dts/ls1021a.dtsi
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -706,6 +706,7 @@
fsl,tmr-fiper1  = <5>;
fsl,tmr-fiper2  = <0>;
fsl,max-adj = <4>;
+   fsl,extts-fifo;
};
 
enet0: ethernet@2d1 {
-- 
1.7.1



[v2] net: dpaa2: improve PTP Kconfig option

2019-01-20 Thread Yangbo Lu
Converted to use "imply" instead of "select" for PTP_1588_CLOCK
driver selecting. This could break the hard dependency between
the PTP clock subsystem and ethernet drivers.
This patch also set "default y" for dpaa2 ptp driver building to
provide user an available ptp clock in default.

Signed-off-by: Yangbo Lu 
---
Changes for v2:
- Converted to use imply for PTP_1588_CLOCK.
- Modified commit message.
---
 drivers/net/ethernet/freescale/dpaa2/Kconfig |5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa2/Kconfig 
b/drivers/net/ethernet/freescale/dpaa2/Kconfig
index 809a155..f6d244c 100644
--- a/drivers/net/ethernet/freescale/dpaa2/Kconfig
+++ b/drivers/net/ethernet/freescale/dpaa2/Kconfig
@@ -9,8 +9,9 @@ config FSL_DPAA2_ETH
 
 config FSL_DPAA2_PTP_CLOCK
tristate "Freescale DPAA2 PTP Clock"
-   depends on FSL_DPAA2_ETH && POSIX_TIMERS
-   select PTP_1588_CLOCK
+   depends on FSL_DPAA2_ETH
+   imply PTP_1588_CLOCK
+   default y
help
  This driver adds support for using the DPAA2 1588 timer module
  as a PTP clock.
-- 
1.7.1



  1   2   3   >