All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next 00/12] ionic: add PTP and hw clock support
@ 2021-04-01 17:55 Shannon Nelson
  2021-04-01 17:55 ` [PATCH net-next 01/12] ionic: add new queue features to interface Shannon Nelson
                   ` (13 more replies)
  0 siblings, 14 replies; 35+ messages in thread
From: Shannon Nelson @ 2021-04-01 17:55 UTC (permalink / raw)
  To: netdev, davem, kuba; +Cc: drivers, Shannon Nelson

This patchset adds support for accessing the DSC hardware clock and
for offloading PTP timestamping.

Tx packet timestamping happens through a separate Tx queue set up with
expanded completion descriptors that can report the timestamp.

Rx timestamping can happen either on all queues, or on a separate
timestamping queue when specific filtering is requested.  Again, the
timestamps are reported with the expanded completion descriptors.

The timestamping offload ability is advertised but not enabled until an
OS service asks for it.  At that time the driver's queues are reconfigured
to use the different completion descriptors and the private processing
queues as needed.

Reading the raw clock value comes through a new pair of values in the
device info registers in BAR0.  These high and low values are interpreted
with help from new clock mask, mult, and shift values in the device
identity information.

First we add the ability to detect new queue features, then the handling
of the new descriptor sizes.  After adding the new interface structures,
we start adding the support code, saving the advertising to the stack
for last.

Shannon Nelson (12):
  ionic: add new queue features to interface
  ionic: add handling of larger descriptors
  ionic: add hw timestamp structs to interface
  ionic: split adminq post and wait calls
  ionic: add hw timestamp support files
  ionic: link in the new hw timestamp code
  ionic: add rx filtering for hw timestamp steering
  ionic: set up hw timestamp queues
  ionic: add and enable tx and rx timestamp handling
  ionic: add ethtool support for PTP
  ionic: ethtool ptp stats
  ionic: advertise support for hardware timestamps

 drivers/net/ethernet/pensando/ionic/Makefile  |   1 +
 drivers/net/ethernet/pensando/ionic/ionic.h   |   6 +
 .../net/ethernet/pensando/ionic/ionic_dev.c   |   2 +
 .../net/ethernet/pensando/ionic/ionic_dev.h   |   3 +
 .../ethernet/pensando/ionic/ionic_ethtool.c   |  93 +++
 .../net/ethernet/pensando/ionic/ionic_if.h    | 214 ++++++-
 .../net/ethernet/pensando/ionic/ionic_lif.c   | 439 ++++++++++++-
 .../net/ethernet/pensando/ionic/ionic_lif.h   |  75 +++
 .../net/ethernet/pensando/ionic/ionic_main.c  |  17 +-
 .../net/ethernet/pensando/ionic/ionic_phc.c   | 589 ++++++++++++++++++
 .../ethernet/pensando/ionic/ionic_rx_filter.c |  21 +
 .../ethernet/pensando/ionic/ionic_rx_filter.h |   1 +
 .../net/ethernet/pensando/ionic/ionic_stats.c |  38 +-
 .../net/ethernet/pensando/ionic/ionic_txrx.c  | 138 +++-
 .../net/ethernet/pensando/ionic/ionic_txrx.h  |   3 +
 15 files changed, 1565 insertions(+), 75 deletions(-)
 create mode 100644 drivers/net/ethernet/pensando/ionic/ionic_phc.c

-- 
2.17.1


^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH net-next 01/12] ionic: add new queue features to interface
  2021-04-01 17:55 [PATCH net-next 00/12] ionic: add PTP and hw clock support Shannon Nelson
@ 2021-04-01 17:55 ` Shannon Nelson
  2021-04-01 17:56 ` [PATCH net-next 02/12] ionic: add handling of larger descriptors Shannon Nelson
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 35+ messages in thread
From: Shannon Nelson @ 2021-04-01 17:55 UTC (permalink / raw)
  To: netdev, davem, kuba; +Cc: drivers, Shannon Nelson, Allen Hubbe

Add queue feature extensions to prepare for features that
can be queue specific, in addition to the general queue
features already defined.  While we're here, change the
existing feature ids from #defines to enum.

Signed-off-by: Allen Hubbe <allenbh@pensando.io>
Signed-off-by: Shannon Nelson <snelson@pensando.io>
---
 .../net/ethernet/pensando/ionic/ionic_dev.h   |  1 +
 .../net/ethernet/pensando/ionic/ionic_if.h    | 27 ++++++++++++++-----
 .../net/ethernet/pensando/ionic/ionic_lif.c   |  3 +++
 3 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.h b/drivers/net/ethernet/pensando/ionic/ionic_dev.h
index 0c0533737b2b..68e5e7a97801 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_dev.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.h
@@ -222,6 +222,7 @@ struct ionic_queue {
 	u64 stop;
 	u64 wake;
 	u64 drop;
+	u64 features;
 	struct ionic_dev *idev;
 	unsigned int type;
 	unsigned int hw_index;
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_if.h b/drivers/net/ethernet/pensando/ionic/ionic_if.h
index 88210142395d..23043ce0a5d8 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_if.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_if.h
@@ -345,6 +345,23 @@ enum ionic_logical_qtype {
 	IONIC_QTYPE_MAX     = 16,
 };
 
+/**
+ * enum ionic_q_feature - Common Features for most queue types
+ *
+ * Common features use bits 0-15. Per-queue-type features use higher bits.
+ *
+ * @IONIC_QIDENT_F_CQ:      Queue has completion ring
+ * @IONIC_QIDENT_F_SG:      Queue has scatter/gather ring
+ * @IONIC_QIDENT_F_EQ:      Queue can use event queue
+ * @IONIC_QIDENT_F_CMB:     Queue is in cmb bar
+ */
+enum ionic_q_feature {
+	IONIC_QIDENT_F_CQ		= BIT_ULL(0),
+	IONIC_QIDENT_F_SG		= BIT_ULL(1),
+	IONIC_QIDENT_F_EQ		= BIT_ULL(2),
+	IONIC_QIDENT_F_CMB		= BIT_ULL(3),
+};
+
 /**
  * struct ionic_lif_logical_qtype - Descriptor of logical to HW queue type
  * @qtype:          Hardware Queue Type
@@ -529,7 +546,7 @@ struct ionic_q_identify_comp {
  * union ionic_q_identity - queue identity information
  *     @version:        Queue type version that can be used with FW
  *     @supported:      Bitfield of queue versions, first bit = ver 0
- *     @features:       Queue features
+ *     @features:       Queue features (enum ionic_q_feature, etc)
  *     @desc_sz:        Descriptor size
  *     @comp_sz:        Completion descriptor size
  *     @sg_desc_sz:     Scatter/Gather descriptor size
@@ -541,10 +558,6 @@ union ionic_q_identity {
 		u8      version;
 		u8      supported;
 		u8      rsvd[6];
-#define IONIC_QIDENT_F_CQ	0x01	/* queue has completion ring */
-#define IONIC_QIDENT_F_SG	0x02	/* queue has scatter/gather ring */
-#define IONIC_QIDENT_F_EQ	0x04	/* queue can use event queue */
-#define IONIC_QIDENT_F_CMB	0x08	/* queue is in cmb bar */
 		__le64  features;
 		__le16  desc_sz;
 		__le16  comp_sz;
@@ -585,6 +598,7 @@ union ionic_q_identity {
  * @ring_base:    Queue ring base address
  * @cq_ring_base: Completion queue ring base address
  * @sg_ring_base: Scatter/Gather ring base address
+ * @features:     Mask of queue features to enable, if not in the flags above.
  */
 struct ionic_q_init_cmd {
 	u8     opcode;
@@ -608,7 +622,8 @@ struct ionic_q_init_cmd {
 	__le64 ring_base;
 	__le64 cq_ring_base;
 	__le64 sg_ring_base;
-	u8     rsvd2[20];
+	u8     rsvd2[12];
+	__le64 features;
 } __packed;
 
 /**
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index a51be25723a5..1b89549b243b 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -731,6 +731,7 @@ static int ionic_lif_txq_init(struct ionic_lif *lif, struct ionic_qcq *qcq)
 			.ring_base = cpu_to_le64(q->base_pa),
 			.cq_ring_base = cpu_to_le64(cq->base_pa),
 			.sg_ring_base = cpu_to_le64(q->sg_base_pa),
+			.features = cpu_to_le64(q->features),
 		},
 	};
 	unsigned int intr_index;
@@ -791,6 +792,7 @@ static int ionic_lif_rxq_init(struct ionic_lif *lif, struct ionic_qcq *qcq)
 			.ring_base = cpu_to_le64(q->base_pa),
 			.cq_ring_base = cpu_to_le64(cq->base_pa),
 			.sg_ring_base = cpu_to_le64(q->sg_base_pa),
+			.features = cpu_to_le64(q->features),
 		},
 	};
 	int err;
@@ -2214,6 +2216,7 @@ static const struct net_device_ops ionic_netdev_ops = {
 static void ionic_swap_queues(struct ionic_qcq *a, struct ionic_qcq *b)
 {
 	/* only swapping the queues, not the napi, flags, or other stuff */
+	swap(a->q.features,   b->q.features);
 	swap(a->q.num_descs,  b->q.num_descs);
 	swap(a->q.base,       b->q.base);
 	swap(a->q.base_pa,    b->q.base_pa);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH net-next 02/12] ionic: add handling of larger descriptors
  2021-04-01 17:55 [PATCH net-next 00/12] ionic: add PTP and hw clock support Shannon Nelson
  2021-04-01 17:55 ` [PATCH net-next 01/12] ionic: add new queue features to interface Shannon Nelson
@ 2021-04-01 17:56 ` Shannon Nelson
  2021-04-04 22:50   ` Richard Cochran
  2021-04-01 17:56 ` [PATCH net-next 03/12] ionic: add hw timestamp structs to interface Shannon Nelson
                   ` (11 subsequent siblings)
  13 siblings, 1 reply; 35+ messages in thread
From: Shannon Nelson @ 2021-04-01 17:56 UTC (permalink / raw)
  To: netdev, davem, kuba; +Cc: drivers, Shannon Nelson, Allen Hubbe

In preparating for hardware timestamping, we need to support
large Tx and Rx completion descriptors.  Here we add the new
queue feature ids and handling for the completion descriptor
sizes.

We only are adding support for the Rx 2x sized completion
descriptors in the general Rx queues for now as we will be
using it for PTP Rx support, and we don't have an immediate
use for the large descriptors in the general Tx queues yet;
it will be used in a special Tx queues added in one of the
next few patches.

Signed-off-by: Allen Hubbe <allenbh@pensando.io>
Signed-off-by: Shannon Nelson <snelson@pensando.io>
---
 .../net/ethernet/pensando/ionic/ionic_if.h    | 12 +++
 .../net/ethernet/pensando/ionic/ionic_lif.c   | 75 ++++++++++++-------
 .../net/ethernet/pensando/ionic/ionic_lif.h   |  3 +
 .../net/ethernet/pensando/ionic/ionic_txrx.c  | 12 ++-
 4 files changed, 73 insertions(+), 29 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_if.h b/drivers/net/ethernet/pensando/ionic/ionic_if.h
index 23043ce0a5d8..1299630fcde8 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_if.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_if.h
@@ -354,12 +354,24 @@ enum ionic_logical_qtype {
  * @IONIC_QIDENT_F_SG:      Queue has scatter/gather ring
  * @IONIC_QIDENT_F_EQ:      Queue can use event queue
  * @IONIC_QIDENT_F_CMB:     Queue is in cmb bar
+ * @IONIC_Q_F_2X_DESC:      Double main descriptor size
+ * @IONIC_Q_F_2X_CQ_DESC:   Double cq descriptor size
+ * @IONIC_Q_F_2X_SG_DESC:   Double sg descriptor size
+ * @IONIC_Q_F_4X_DESC:      Quadruple main descriptor size
+ * @IONIC_Q_F_4X_CQ_DESC:   Quadruple cq descriptor size
+ * @IONIC_Q_F_4X_SG_DESC:   Quadruple sg descriptor size
  */
 enum ionic_q_feature {
 	IONIC_QIDENT_F_CQ		= BIT_ULL(0),
 	IONIC_QIDENT_F_SG		= BIT_ULL(1),
 	IONIC_QIDENT_F_EQ		= BIT_ULL(2),
 	IONIC_QIDENT_F_CMB		= BIT_ULL(3),
+	IONIC_Q_F_2X_DESC		= BIT_ULL(4),
+	IONIC_Q_F_2X_CQ_DESC		= BIT_ULL(5),
+	IONIC_Q_F_2X_SG_DESC		= BIT_ULL(6),
+	IONIC_Q_F_4X_DESC		= BIT_ULL(7),
+	IONIC_Q_F_4X_CQ_DESC		= BIT_ULL(8),
+	IONIC_Q_F_4X_SG_DESC		= BIT_ULL(9),
 };
 
 /**
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index 1b89549b243b..9a61b2bbb652 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -1722,11 +1722,15 @@ static void ionic_txrx_free(struct ionic_lif *lif)
 
 static int ionic_txrx_alloc(struct ionic_lif *lif)
 {
-	unsigned int sg_desc_sz;
+	unsigned int num_desc, desc_sz, comp_sz, sg_desc_sz;
 	unsigned int flags;
 	unsigned int i;
 	int err = 0;
 
+	num_desc = lif->ntxq_descs;
+	desc_sz = sizeof(struct ionic_txq_desc);
+	comp_sz = sizeof(struct ionic_txq_comp);
+
 	if (lif->qtype_info[IONIC_QTYPE_TXQ].version >= 1 &&
 	    lif->qtype_info[IONIC_QTYPE_TXQ].sg_desc_sz ==
 					  sizeof(struct ionic_txq_sg_desc_v1))
@@ -1739,10 +1743,7 @@ static int ionic_txrx_alloc(struct ionic_lif *lif)
 		flags |= IONIC_QCQ_F_INTR;
 	for (i = 0; i < lif->nxqs; i++) {
 		err = ionic_qcq_alloc(lif, IONIC_QTYPE_TXQ, i, "tx", flags,
-				      lif->ntxq_descs,
-				      sizeof(struct ionic_txq_desc),
-				      sizeof(struct ionic_txq_comp),
-				      sg_desc_sz,
+				      num_desc, desc_sz, comp_sz, sg_desc_sz,
 				      lif->kern_pid, &lif->txqcqs[i]);
 		if (err)
 			goto err_out;
@@ -1759,16 +1760,24 @@ static int ionic_txrx_alloc(struct ionic_lif *lif)
 	}
 
 	flags = IONIC_QCQ_F_RX_STATS | IONIC_QCQ_F_SG | IONIC_QCQ_F_INTR;
+
+	num_desc = lif->nrxq_descs;
+	desc_sz = sizeof(struct ionic_rxq_desc);
+	comp_sz = sizeof(struct ionic_rxq_comp);
+	sg_desc_sz = sizeof(struct ionic_rxq_sg_desc);
+
+	if (lif->rxq_features & IONIC_Q_F_2X_CQ_DESC)
+		comp_sz *= 2;
+
 	for (i = 0; i < lif->nxqs; i++) {
 		err = ionic_qcq_alloc(lif, IONIC_QTYPE_RXQ, i, "rx", flags,
-				      lif->nrxq_descs,
-				      sizeof(struct ionic_rxq_desc),
-				      sizeof(struct ionic_rxq_comp),
-				      sizeof(struct ionic_rxq_sg_desc),
+				      num_desc, desc_sz, comp_sz, sg_desc_sz,
 				      lif->kern_pid, &lif->rxqcqs[i]);
 		if (err)
 			goto err_out;
 
+		lif->rxqcqs[i]->q.features = lif->rxq_features;
+
 		ionic_intr_coal_init(lif->ionic->idev.intr_ctrl,
 				     lif->rxqcqs[i]->intr.index,
 				     lif->rx_coalesce_hw);
@@ -2218,6 +2227,7 @@ static void ionic_swap_queues(struct ionic_qcq *a, struct ionic_qcq *b)
 	/* only swapping the queues, not the napi, flags, or other stuff */
 	swap(a->q.features,   b->q.features);
 	swap(a->q.num_descs,  b->q.num_descs);
+	swap(a->q.desc_size,  b->q.desc_size);
 	swap(a->q.base,       b->q.base);
 	swap(a->q.base_pa,    b->q.base_pa);
 	swap(a->q.info,       b->q.info);
@@ -2225,6 +2235,7 @@ static void ionic_swap_queues(struct ionic_qcq *a, struct ionic_qcq *b)
 	swap(a->q_base_pa,    b->q_base_pa);
 	swap(a->q_size,       b->q_size);
 
+	swap(a->q.sg_desc_size, b->q.sg_desc_size);
 	swap(a->q.sg_base,    b->q.sg_base);
 	swap(a->q.sg_base_pa, b->q.sg_base_pa);
 	swap(a->sg_base,      b->sg_base);
@@ -2232,6 +2243,7 @@ static void ionic_swap_queues(struct ionic_qcq *a, struct ionic_qcq *b)
 	swap(a->sg_size,      b->sg_size);
 
 	swap(a->cq.num_descs, b->cq.num_descs);
+	swap(a->cq.desc_size, b->cq.desc_size);
 	swap(a->cq.base,      b->cq.base);
 	swap(a->cq.base_pa,   b->cq.base_pa);
 	swap(a->cq.info,      b->cq.info);
@@ -2246,9 +2258,9 @@ static void ionic_swap_queues(struct ionic_qcq *a, struct ionic_qcq *b)
 int ionic_reconfigure_queues(struct ionic_lif *lif,
 			     struct ionic_queue_params *qparam)
 {
+	unsigned int num_desc, desc_sz, comp_sz, sg_desc_sz;
 	struct ionic_qcq **tx_qcqs = NULL;
 	struct ionic_qcq **rx_qcqs = NULL;
-	unsigned int sg_desc_sz;
 	unsigned int flags;
 	int err = -ENOMEM;
 	unsigned int i;
@@ -2260,7 +2272,9 @@ int ionic_reconfigure_queues(struct ionic_lif *lif,
 		if (!tx_qcqs)
 			goto err_out;
 	}
-	if (qparam->nxqs != lif->nxqs || qparam->nrxq_descs != lif->nrxq_descs) {
+	if (qparam->nxqs != lif->nxqs ||
+	    qparam->nrxq_descs != lif->nrxq_descs ||
+	    qparam->rxq_features != lif->rxq_features) {
 		rx_qcqs = devm_kcalloc(lif->ionic->dev, lif->ionic->nrxqs_per_lif,
 				       sizeof(struct ionic_qcq *), GFP_KERNEL);
 		if (!rx_qcqs)
@@ -2270,21 +2284,22 @@ int ionic_reconfigure_queues(struct ionic_lif *lif,
 	/* allocate new desc_info and rings, but leave the interrupt setup
 	 * until later so as to not mess with the still-running queues
 	 */
-	if (lif->qtype_info[IONIC_QTYPE_TXQ].version >= 1 &&
-	    lif->qtype_info[IONIC_QTYPE_TXQ].sg_desc_sz ==
-					  sizeof(struct ionic_txq_sg_desc_v1))
-		sg_desc_sz = sizeof(struct ionic_txq_sg_desc_v1);
-	else
-		sg_desc_sz = sizeof(struct ionic_txq_sg_desc);
-
 	if (tx_qcqs) {
+		num_desc = qparam->ntxq_descs;
+		desc_sz = sizeof(struct ionic_txq_desc);
+		comp_sz = sizeof(struct ionic_txq_comp);
+
+		if (lif->qtype_info[IONIC_QTYPE_TXQ].version >= 1 &&
+		    lif->qtype_info[IONIC_QTYPE_TXQ].sg_desc_sz ==
+		    sizeof(struct ionic_txq_sg_desc_v1))
+			sg_desc_sz = sizeof(struct ionic_txq_sg_desc_v1);
+		else
+			sg_desc_sz = sizeof(struct ionic_txq_sg_desc);
+
 		for (i = 0; i < qparam->nxqs; i++) {
 			flags = lif->txqcqs[i]->flags & ~IONIC_QCQ_F_INTR;
 			err = ionic_qcq_alloc(lif, IONIC_QTYPE_TXQ, i, "tx", flags,
-					      qparam->ntxq_descs,
-					      sizeof(struct ionic_txq_desc),
-					      sizeof(struct ionic_txq_comp),
-					      sg_desc_sz,
+					      num_desc, desc_sz, comp_sz, sg_desc_sz,
 					      lif->kern_pid, &tx_qcqs[i]);
 			if (err)
 				goto err_out;
@@ -2292,16 +2307,23 @@ int ionic_reconfigure_queues(struct ionic_lif *lif,
 	}
 
 	if (rx_qcqs) {
+		num_desc = qparam->nrxq_descs;
+		desc_sz = sizeof(struct ionic_rxq_desc);
+		comp_sz = sizeof(struct ionic_rxq_comp);
+		sg_desc_sz = sizeof(struct ionic_rxq_sg_desc);
+
+		if (qparam->rxq_features & IONIC_Q_F_2X_CQ_DESC)
+			comp_sz *= 2;
+
 		for (i = 0; i < qparam->nxqs; i++) {
 			flags = lif->rxqcqs[i]->flags & ~IONIC_QCQ_F_INTR;
 			err = ionic_qcq_alloc(lif, IONIC_QTYPE_RXQ, i, "rx", flags,
-					      qparam->nrxq_descs,
-					      sizeof(struct ionic_rxq_desc),
-					      sizeof(struct ionic_rxq_comp),
-					      sizeof(struct ionic_rxq_sg_desc),
+					      num_desc, desc_sz, comp_sz, sg_desc_sz,
 					      lif->kern_pid, &rx_qcqs[i]);
 			if (err)
 				goto err_out;
+
+			rx_qcqs[i]->q.features = qparam->rxq_features;
 		}
 	}
 
@@ -2388,6 +2410,7 @@ int ionic_reconfigure_queues(struct ionic_lif *lif,
 	}
 
 	swap(lif->nxqs, qparam->nxqs);
+	swap(lif->rxq_features, qparam->rxq_features);
 
 err_out_reinit_unlock:
 	/* re-init the queues, but don't lose an error code */
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.h b/drivers/net/ethernet/pensando/ionic/ionic_lif.h
index be5cc89b2bd9..93d3058aed77 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.h
@@ -183,6 +183,7 @@ struct ionic_lif {
 	unsigned int ntxq_descs;
 	unsigned int nrxq_descs;
 	u32 rx_copybreak;
+	u64 rxq_features;
 	unsigned int rx_mode;
 	u64 hw_features;
 	bool registered;
@@ -221,6 +222,7 @@ struct ionic_queue_params {
 	unsigned int ntxq_descs;
 	unsigned int nrxq_descs;
 	unsigned int intr_split;
+	u64 rxq_features;
 };
 
 static inline void ionic_init_queue_params(struct ionic_lif *lif,
@@ -230,6 +232,7 @@ static inline void ionic_init_queue_params(struct ionic_lif *lif,
 	qparam->ntxq_descs = lif->ntxq_descs;
 	qparam->nrxq_descs = lif->nrxq_descs;
 	qparam->intr_split = test_bit(IONIC_LIF_F_SPLIT_INTR, lif->state);
+	qparam->rxq_features = lif->rxq_features;
 }
 
 static inline u32 ionic_coal_usec_to_hw(struct ionic *ionic, u32 usecs)
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
index 42d29cd2ca47..4859120eec72 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
@@ -229,12 +229,14 @@ static void ionic_rx_clean(struct ionic_queue *q,
 			   struct ionic_cq_info *cq_info,
 			   void *cb_arg)
 {
-	struct ionic_rxq_comp *comp = cq_info->rxcq;
 	struct net_device *netdev = q->lif->netdev;
 	struct ionic_qcq *qcq = q_to_qcq(q);
 	struct ionic_rx_stats *stats;
+	struct ionic_rxq_comp *comp;
 	struct sk_buff *skb;
 
+	comp = cq_info->cq_desc + qcq->cq.desc_size - sizeof(*comp);
+
 	stats = q_to_rx_stats(q);
 
 	if (comp->status) {
@@ -304,9 +306,11 @@ static void ionic_rx_clean(struct ionic_queue *q,
 
 static bool ionic_rx_service(struct ionic_cq *cq, struct ionic_cq_info *cq_info)
 {
-	struct ionic_rxq_comp *comp = cq_info->rxcq;
 	struct ionic_queue *q = cq->bound_q;
 	struct ionic_desc_info *desc_info;
+	struct ionic_rxq_comp *comp;
+
+	comp = cq_info->cq_desc + cq->desc_size - sizeof(*comp);
 
 	if (!color_match(comp->pkt_type_color, cq->done_color))
 		return false;
@@ -693,13 +697,15 @@ static void ionic_tx_clean(struct ionic_queue *q,
 
 static bool ionic_tx_service(struct ionic_cq *cq, struct ionic_cq_info *cq_info)
 {
-	struct ionic_txq_comp *comp = cq_info->txcq;
 	struct ionic_queue *q = cq->bound_q;
 	struct ionic_desc_info *desc_info;
+	struct ionic_txq_comp *comp;
 	int bytes = 0;
 	int pkts = 0;
 	u16 index;
 
+	comp = cq_info->cq_desc + cq->desc_size - sizeof(*comp);
+
 	if (!color_match(comp->color, cq->done_color))
 		return false;
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH net-next 03/12] ionic: add hw timestamp structs to interface
  2021-04-01 17:55 [PATCH net-next 00/12] ionic: add PTP and hw clock support Shannon Nelson
  2021-04-01 17:55 ` [PATCH net-next 01/12] ionic: add new queue features to interface Shannon Nelson
  2021-04-01 17:56 ` [PATCH net-next 02/12] ionic: add handling of larger descriptors Shannon Nelson
@ 2021-04-01 17:56 ` Shannon Nelson
  2021-04-01 17:56 ` [PATCH net-next 04/12] ionic: split adminq post and wait calls Shannon Nelson
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 35+ messages in thread
From: Shannon Nelson @ 2021-04-01 17:56 UTC (permalink / raw)
  To: netdev, davem, kuba; +Cc: drivers, Shannon Nelson, Allen Hubbe

The interface for hardware timestamping includes a new FW
request, device identity fields, Tx and Rx queue feature bits, a
new Rx filter type, the beginnings of Rx packet classifications,
and hardware timestamp registers.

If the IONIC_ETH_HW_TIMESTAMP bit is shown in the
ionic_lif_config features bit string, then we have support
for the hw clock registers.  If the IONIC_RXQ_F_HWSTAMP and
IONIC_TXQ_F_HWSTAMP features are shown in the ionic_q_identity
features, then the queues can support HW timestamps on packets.

Signed-off-by: Allen Hubbe <allenbh@pensando.io>
Signed-off-by: Shannon Nelson <snelson@pensando.io>
---
 .../net/ethernet/pensando/ionic/ionic_dev.h   |   1 +
 .../net/ethernet/pensando/ionic/ionic_if.h    | 175 +++++++++++++++++-
 2 files changed, 170 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.h b/drivers/net/ethernet/pensando/ionic/ionic_dev.h
index 68e5e7a97801..25c52c042246 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_dev.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.h
@@ -59,6 +59,7 @@ static_assert(sizeof(struct ionic_dev_getattr_cmd) == 64);
 static_assert(sizeof(struct ionic_dev_getattr_comp) == 16);
 static_assert(sizeof(struct ionic_dev_setattr_cmd) == 64);
 static_assert(sizeof(struct ionic_dev_setattr_comp) == 16);
+static_assert(sizeof(struct ionic_lif_setphc_cmd) == 64);
 
 /* Port commands */
 static_assert(sizeof(struct ionic_port_identify_cmd) == 64);
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_if.h b/drivers/net/ethernet/pensando/ionic/ionic_if.h
index 1299630fcde8..0478b48d9895 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_if.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_if.h
@@ -34,6 +34,7 @@ enum ionic_cmd_opcode {
 	IONIC_CMD_LIF_RESET			= 22,
 	IONIC_CMD_LIF_GETATTR			= 23,
 	IONIC_CMD_LIF_SETATTR			= 24,
+	IONIC_CMD_LIF_SETPHC			= 25,
 
 	IONIC_CMD_RX_MODE_SET			= 30,
 	IONIC_CMD_RX_FILTER_ADD			= 31,
@@ -269,6 +270,9 @@ union ionic_drv_identity {
  *                    value in usecs to device units using:
  *                    device units = usecs * mult / div
  * @eq_count:         Number of shared event queues
+ * @hwstamp_mask:     Bitmask for subtraction of hardware tick values.
+ * @hwstamp_mult:     Hardware tick to nanosecond multiplier.
+ * @hwstamp_shift:    Hardware tick to nanosecond divisor (power of two).
  */
 union ionic_dev_identity {
 	struct {
@@ -283,6 +287,9 @@ union ionic_dev_identity {
 		__le32 intr_coal_mult;
 		__le32 intr_coal_div;
 		__le32 eq_count;
+		__le64 hwstamp_mask;
+		__le32 hwstamp_mult;
+		__le32 hwstamp_shift;
 	};
 	__le32 words[478];
 };
@@ -374,6 +381,39 @@ enum ionic_q_feature {
 	IONIC_Q_F_4X_SG_DESC		= BIT_ULL(9),
 };
 
+/**
+ * enum ionic_rxq_feature - RXQ-specific Features
+ *
+ * Per-queue-type features use bits 16 and higher.
+ *
+ * @IONIC_RXQ_F_HWSTAMP:   Queue supports Hardware Timestamping
+ */
+enum ionic_rxq_feature {
+	IONIC_RXQ_F_HWSTAMP		= BIT_ULL(16),
+};
+
+/**
+ * enum ionic_txq_feature - TXQ-specific Features
+ *
+ * Per-queue-type features use bits 16 and higher.
+ *
+ * @IONIC_TXQ_F_HWSTAMP:   Queue supports Hardware Timestamping
+ */
+enum ionic_txq_feature {
+	IONIC_TXQ_F_HWSTAMP		= BIT(16),
+};
+
+/**
+ * struct ionic_hwstamp_bits - Hardware timestamp decoding bits
+ * @IONIC_HWSTAMP_INVALID:          Invalid hardware timestamp value
+ * @IONIC_HWSTAMP_CQ_NEGOFFSET:     Timestamp field negative offset
+ *                                  from the base cq descriptor.
+ */
+enum ionic_hwstamp_bits {
+	IONIC_HWSTAMP_INVALID	    = ~0ull,
+	IONIC_HWSTAMP_CQ_NEGOFFSET  = 8,
+};
+
 /**
  * struct ionic_lif_logical_qtype - Descriptor of logical to HW queue type
  * @qtype:          Hardware Queue Type
@@ -434,6 +474,8 @@ union ionic_lif_config {
  *     @max_mcast_filters:  Number of perfect multicast addresses supported
  *     @min_frame_size:     Minimum size of frames to be sent
  *     @max_frame_size:     Maximum size of frames to be sent
+ *     @hwstamp_tx_modes:   Bitmask of BIT_ULL(enum ionic_txstamp_mode)
+ *     @hwstamp_rx_filters: Bitmask of enum ionic_pkt_class
  *     @config:             LIF config struct with features, mtu, mac, q counts
  *
  * @rdma:                RDMA identify structure
@@ -467,7 +509,10 @@ union ionic_lif_identity {
 			__le16 rss_ind_tbl_sz;
 			__le32 min_frame_size;
 			__le32 max_frame_size;
-			u8 rsvd2[106];
+			u8 rsvd2[2];
+			__le64 hwstamp_tx_modes;
+			__le64 hwstamp_rx_filters;
+			u8 rsvd3[88];
 			union ionic_lif_config config;
 		} __packed eth;
 
@@ -1046,7 +1091,64 @@ enum ionic_eth_hw_features {
 	IONIC_ETH_HW_TSO_UDP_CSUM	= BIT(16),
 	IONIC_ETH_HW_RX_CSUM_GENEVE	= BIT(17),
 	IONIC_ETH_HW_TX_CSUM_GENEVE	= BIT(18),
-	IONIC_ETH_HW_TSO_GENEVE		= BIT(19)
+	IONIC_ETH_HW_TSO_GENEVE		= BIT(19),
+	IONIC_ETH_HW_TIMESTAMP		= BIT(20),
+};
+
+/**
+ * enum ionic_pkt_class - Packet classification mask.
+ *
+ * Used with rx steering filter, packets indicated by the mask can be steered
+ * toward a specific receive queue.
+ *
+ * @IONIC_PKT_CLS_NTP_ALL:          All NTP packets.
+ * @IONIC_PKT_CLS_PTP1_SYNC:        PTPv1 sync
+ * @IONIC_PKT_CLS_PTP1_DREQ:        PTPv1 delay-request
+ * @IONIC_PKT_CLS_PTP1_ALL:         PTPv1 all packets
+ * @IONIC_PKT_CLS_PTP2_L4_SYNC:     PTPv2-UDP sync
+ * @IONIC_PKT_CLS_PTP2_L4_DREQ:     PTPv2-UDP delay-request
+ * @IONIC_PKT_CLS_PTP2_L4_ALL:      PTPv2-UDP all packets
+ * @IONIC_PKT_CLS_PTP2_L2_SYNC:     PTPv2-ETH sync
+ * @IONIC_PKT_CLS_PTP2_L2_DREQ:     PTPv2-ETH delay-request
+ * @IONIC_PKT_CLS_PTP2_L2_ALL:      PTPv2-ETH all packets
+ * @IONIC_PKT_CLS_PTP2_SYNC:        PTPv2 sync
+ * @IONIC_PKT_CLS_PTP2_DREQ:        PTPv2 delay-request
+ * @IONIC_PKT_CLS_PTP2_ALL:         PTPv2 all packets
+ * @IONIC_PKT_CLS_PTP_SYNC:         PTP sync
+ * @IONIC_PKT_CLS_PTP_DREQ:         PTP delay-request
+ * @IONIC_PKT_CLS_PTP_ALL:          PTP all packets
+ */
+enum ionic_pkt_class {
+	IONIC_PKT_CLS_NTP_ALL		= BIT(0),
+
+	IONIC_PKT_CLS_PTP1_SYNC		= BIT(1),
+	IONIC_PKT_CLS_PTP1_DREQ		= BIT(2),
+	IONIC_PKT_CLS_PTP1_ALL		= BIT(3) |
+		IONIC_PKT_CLS_PTP1_SYNC | IONIC_PKT_CLS_PTP1_DREQ,
+
+	IONIC_PKT_CLS_PTP2_L4_SYNC	= BIT(4),
+	IONIC_PKT_CLS_PTP2_L4_DREQ	= BIT(5),
+	IONIC_PKT_CLS_PTP2_L4_ALL	= BIT(6) |
+		IONIC_PKT_CLS_PTP2_L4_SYNC | IONIC_PKT_CLS_PTP2_L4_DREQ,
+
+	IONIC_PKT_CLS_PTP2_L2_SYNC	= BIT(7),
+	IONIC_PKT_CLS_PTP2_L2_DREQ	= BIT(8),
+	IONIC_PKT_CLS_PTP2_L2_ALL	= BIT(9) |
+		IONIC_PKT_CLS_PTP2_L2_SYNC | IONIC_PKT_CLS_PTP2_L2_DREQ,
+
+	IONIC_PKT_CLS_PTP2_SYNC		=
+		IONIC_PKT_CLS_PTP2_L4_SYNC | IONIC_PKT_CLS_PTP2_L2_SYNC,
+	IONIC_PKT_CLS_PTP2_DREQ		=
+		IONIC_PKT_CLS_PTP2_L4_DREQ | IONIC_PKT_CLS_PTP2_L2_DREQ,
+	IONIC_PKT_CLS_PTP2_ALL		=
+		IONIC_PKT_CLS_PTP2_L4_ALL | IONIC_PKT_CLS_PTP2_L2_ALL,
+
+	IONIC_PKT_CLS_PTP_SYNC		=
+		IONIC_PKT_CLS_PTP1_SYNC | IONIC_PKT_CLS_PTP2_SYNC,
+	IONIC_PKT_CLS_PTP_DREQ		=
+		IONIC_PKT_CLS_PTP1_DREQ | IONIC_PKT_CLS_PTP2_DREQ,
+	IONIC_PKT_CLS_PTP_ALL		=
+		IONIC_PKT_CLS_PTP1_ALL | IONIC_PKT_CLS_PTP2_ALL,
 };
 
 /**
@@ -1355,6 +1457,20 @@ enum ionic_stats_ctl_cmd {
 	IONIC_STATS_CTL_RESET		= 0,
 };
 
+/**
+ * enum ionic_txstamp_mode - List of TX Timestamping Modes
+ * @IONIC_TXSTAMP_OFF:           Disable TX hardware timetamping.
+ * @IONIC_TXSTAMP_ON:            Enable local TX hardware timetamping.
+ * @IONIC_TXSTAMP_ONESTEP_SYNC:  Modify TX PTP Sync packets.
+ * @IONIC_TXSTAMP_ONESTEP_P2P:   Modify TX PTP Sync and PDelayResp.
+ */
+enum ionic_txstamp_mode {
+	IONIC_TXSTAMP_OFF		= 0,
+	IONIC_TXSTAMP_ON		= 1,
+	IONIC_TXSTAMP_ONESTEP_SYNC	= 2,
+	IONIC_TXSTAMP_ONESTEP_P2P	= 3,
+};
+
 /**
  * enum ionic_port_attr - List of device attributes
  * @IONIC_PORT_ATTR_STATE:      Port state attribute
@@ -1597,6 +1713,7 @@ enum ionic_rss_hash_types {
  * @IONIC_LIF_ATTR_FEATURES:    LIF features attribute
  * @IONIC_LIF_ATTR_RSS:         LIF RSS attribute
  * @IONIC_LIF_ATTR_STATS_CTRL:  LIF statistics control attribute
+ * @IONIC_LIF_ATTR_TXSTAMP:     LIF TX timestamping mode
  */
 enum ionic_lif_attr {
 	IONIC_LIF_ATTR_STATE        = 0,
@@ -1606,6 +1723,7 @@ enum ionic_lif_attr {
 	IONIC_LIF_ATTR_FEATURES     = 4,
 	IONIC_LIF_ATTR_RSS          = 5,
 	IONIC_LIF_ATTR_STATS_CTRL   = 6,
+	IONIC_LIF_ATTR_TXSTAMP      = 7,
 };
 
 /**
@@ -1623,6 +1741,7 @@ enum ionic_lif_attr {
  *              @key:       The hash secret key
  *              @addr:      Address for the indirection table shared memory
  * @stats_ctl:  stats control commands (enum ionic_stats_ctl_cmd)
+ * @txstamp:    TX Timestamping Mode (enum ionic_txstamp_mode)
  */
 struct ionic_lif_setattr_cmd {
 	u8     opcode;
@@ -1641,6 +1760,7 @@ struct ionic_lif_setattr_cmd {
 			__le64 addr;
 		} rss;
 		u8      stats_ctl;
+		__le16 txstamp_mode;
 		u8      rsvd[60];
 	} __packed;
 };
@@ -1685,6 +1805,7 @@ struct ionic_lif_getattr_cmd {
  * @mtu:        Mtu
  * @mac:        Station mac
  * @features:   Features (enum ionic_eth_hw_features)
+ * @txstamp:    TX Timestamping Mode (enum ionic_txstamp_mode)
  * @color:      Color bit
  */
 struct ionic_lif_getattr_comp {
@@ -1696,11 +1817,35 @@ struct ionic_lif_getattr_comp {
 		__le32  mtu;
 		u8      mac[6];
 		__le64  features;
+		__le16  txstamp_mode;
 		u8      rsvd2[11];
 	} __packed;
 	u8     color;
 };
 
+/**
+ * struct ionic_lif_setphc_cmd - Set LIF PTP Hardware Clock
+ * @opcode:     Opcode
+ * @lif_index:  LIF index
+ * @tick:       Hardware stamp tick of an instant in time.
+ * @nsec:       Nanosecond stamp of the same instant.
+ * @frac:       Fractional nanoseconds at the same instant.
+ * @mult:       Cycle to nanosecond multiplier.
+ * @shift:      Cycle to nanosecond divisor (power of two).
+ */
+struct ionic_lif_setphc_cmd {
+	u8	opcode;
+	u8	rsvd1;
+	__le16  lif_index;
+	u8      rsvd2[4];
+	__le64	tick;
+	__le64	nsec;
+	__le64	frac;
+	__le32	mult;
+	__le32	shift;
+	u8     rsvd3[24];
+};
+
 enum ionic_rx_mode {
 	IONIC_RX_MODE_F_UNICAST		= BIT(0),
 	IONIC_RX_MODE_F_MULTICAST	= BIT(1),
@@ -1733,9 +1878,10 @@ struct ionic_rx_mode_set_cmd {
 typedef struct ionic_admin_comp ionic_rx_mode_set_comp;
 
 enum ionic_rx_filter_match_type {
-	IONIC_RX_FILTER_MATCH_VLAN = 0,
-	IONIC_RX_FILTER_MATCH_MAC,
-	IONIC_RX_FILTER_MATCH_MAC_VLAN,
+	IONIC_RX_FILTER_MATCH_VLAN	= 0x0,
+	IONIC_RX_FILTER_MATCH_MAC	= 0x1,
+	IONIC_RX_FILTER_MATCH_MAC_VLAN	= 0x2,
+	IONIC_RX_FILTER_STEER_PKTCLASS	= 0x10,
 };
 
 /**
@@ -1752,6 +1898,7 @@ enum ionic_rx_filter_match_type {
  * @mac_vlan:   MACVLAN filter
  *              @vlan:  VLAN ID
  *              @addr:  MAC address (network-byte order)
+ * @pkt_class:  Packet classification filter
  */
 struct ionic_rx_filter_add_cmd {
 	u8     opcode;
@@ -1770,8 +1917,9 @@ struct ionic_rx_filter_add_cmd {
 			__le16 vlan;
 			u8     addr[6];
 		} mac_vlan;
+		__le64 pkt_class;
 		u8 rsvd[54];
-	};
+	} __packed;
 };
 
 /**
@@ -2771,6 +2919,16 @@ union ionic_dev_cmd_comp {
 	struct ionic_fw_control_comp fw_control;
 };
 
+/**
+ * struct ionic_hwstamp_regs - Hardware current timestamp registers
+ * @tick_low:        Low 32 bits of hardware timestamp
+ * @tick_high:       High 32 bits of hardware timestamp
+ */
+struct ionic_hwstamp_regs {
+	u32    tick_low;
+	u32    tick_high;
+};
+
 /**
  * union ionic_dev_info_regs - Device info register format (read-only)
  * @signature:       Signature value of 0x44455649 ('DEVI')
@@ -2781,6 +2939,7 @@ union ionic_dev_cmd_comp {
  * @fw_heartbeat:    Firmware heartbeat counter
  * @serial_num:      Serial number
  * @fw_version:      Firmware version
+ * @hwstamp_regs:    Hardware current timestamp registers
  */
 union ionic_dev_info_regs {
 #define IONIC_DEVINFO_FWVERS_BUFLEN 32
@@ -2795,6 +2954,8 @@ union ionic_dev_info_regs {
 		u32    fw_heartbeat;
 		char   fw_version[IONIC_DEVINFO_FWVERS_BUFLEN];
 		char   serial_num[IONIC_DEVINFO_SERIAL_BUFLEN];
+		u8     rsvd_pad1024[948];
+		struct ionic_hwstamp_regs hwstamp;
 	};
 	u32 words[512];
 };
@@ -2842,6 +3003,7 @@ union ionic_adminq_cmd {
 	struct ionic_q_control_cmd q_control;
 	struct ionic_lif_setattr_cmd lif_setattr;
 	struct ionic_lif_getattr_cmd lif_getattr;
+	struct ionic_lif_setphc_cmd lif_setphc;
 	struct ionic_rx_mode_set_cmd rx_mode_set;
 	struct ionic_rx_filter_add_cmd rx_filter_add;
 	struct ionic_rx_filter_del_cmd rx_filter_del;
@@ -2858,6 +3020,7 @@ union ionic_adminq_comp {
 	struct ionic_q_init_comp q_init;
 	struct ionic_lif_setattr_comp lif_setattr;
 	struct ionic_lif_getattr_comp lif_getattr;
+	struct ionic_admin_comp lif_setphc;
 	struct ionic_rx_filter_add_comp rx_filter_add;
 	struct ionic_fw_control_comp fw_control;
 };
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH net-next 04/12] ionic: split adminq post and wait calls
  2021-04-01 17:55 [PATCH net-next 00/12] ionic: add PTP and hw clock support Shannon Nelson
                   ` (2 preceding siblings ...)
  2021-04-01 17:56 ` [PATCH net-next 03/12] ionic: add hw timestamp structs to interface Shannon Nelson
@ 2021-04-01 17:56 ` Shannon Nelson
  2021-04-01 17:56 ` [PATCH net-next 05/12] ionic: add hw timestamp support files Shannon Nelson
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 35+ messages in thread
From: Shannon Nelson @ 2021-04-01 17:56 UTC (permalink / raw)
  To: netdev, davem, kuba; +Cc: drivers, Shannon Nelson, Allen Hubbe

Split the wait part out of adminq_post_wait() into a separate
function so that a caller can have finer grain control over
the sequencing of operations and locking.

Signed-off-by: Allen Hubbe <allenbh@pensando.io>
Signed-off-by: Shannon Nelson <snelson@pensando.io>
---
 drivers/net/ethernet/pensando/ionic/ionic.h      |  2 ++
 drivers/net/ethernet/pensando/ionic/ionic_main.c | 15 +++++++++++----
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic.h b/drivers/net/ethernet/pensando/ionic/ionic.h
index 084a924431d5..18e92103c711 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic.h
@@ -64,6 +64,8 @@ struct ionic_admin_ctx {
 	union ionic_adminq_comp comp;
 };
 
+int ionic_adminq_post(struct ionic_lif *lif, struct ionic_admin_ctx *ctx);
+int ionic_adminq_wait(struct ionic_lif *lif, struct ionic_admin_ctx *ctx, int err);
 int ionic_adminq_post_wait(struct ionic_lif *lif, struct ionic_admin_ctx *ctx);
 int ionic_dev_cmd_wait(struct ionic *ionic, unsigned long max_wait);
 int ionic_set_dma_mask(struct ionic *ionic);
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_main.c b/drivers/net/ethernet/pensando/ionic/ionic_main.c
index c4b2906a2ae6..8c27fbe0e312 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_main.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_main.c
@@ -256,7 +256,7 @@ static void ionic_adminq_cb(struct ionic_queue *q,
 	complete_all(&ctx->work);
 }
 
-static int ionic_adminq_post(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
+int ionic_adminq_post(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
 {
 	struct ionic_desc_info *desc_info;
 	unsigned long irqflags;
@@ -295,14 +295,12 @@ static int ionic_adminq_post(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
 	return err;
 }
 
-int ionic_adminq_post_wait(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
+int ionic_adminq_wait(struct ionic_lif *lif, struct ionic_admin_ctx *ctx, int err)
 {
 	struct net_device *netdev = lif->netdev;
 	unsigned long remaining;
 	const char *name;
-	int err;
 
-	err = ionic_adminq_post(lif, ctx);
 	if (err) {
 		if (!test_bit(IONIC_LIF_F_FW_RESET, lif->state)) {
 			name = ionic_opcode_to_str(ctx->cmd.cmd.opcode);
@@ -317,6 +315,15 @@ int ionic_adminq_post_wait(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
 	return ionic_adminq_check_err(lif, ctx, (remaining == 0));
 }
 
+int ionic_adminq_post_wait(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
+{
+	int err;
+
+	err = ionic_adminq_post(lif, ctx);
+
+	return ionic_adminq_wait(lif, ctx, err);
+}
+
 static void ionic_dev_cmd_clean(struct ionic *ionic)
 {
 	union __iomem ionic_dev_cmd_regs *regs = ionic->idev.dev_cmd_regs;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH net-next 05/12] ionic: add hw timestamp support files
  2021-04-01 17:55 [PATCH net-next 00/12] ionic: add PTP and hw clock support Shannon Nelson
                   ` (3 preceding siblings ...)
  2021-04-01 17:56 ` [PATCH net-next 04/12] ionic: split adminq post and wait calls Shannon Nelson
@ 2021-04-01 17:56 ` Shannon Nelson
  2021-04-04 23:05   ` Richard Cochran
  2021-04-04 23:21   ` Richard Cochran
  2021-04-01 17:56 ` [PATCH net-next 06/12] ionic: link in the new hw timestamp code Shannon Nelson
                   ` (8 subsequent siblings)
  13 siblings, 2 replies; 35+ messages in thread
From: Shannon Nelson @ 2021-04-01 17:56 UTC (permalink / raw)
  To: netdev, davem, kuba; +Cc: drivers, Shannon Nelson, Allen Hubbe

This adds the file of code for supporting Tx and Rx hardware
timestamps and the raw clock interface, but does not yet link
it in for compiling or use.

Signed-off-by: Allen Hubbe <allenbh@pensando.io>
Signed-off-by: Shannon Nelson <snelson@pensando.io>
---
 .../net/ethernet/pensando/ionic/ionic_phc.c   | 589 ++++++++++++++++++
 1 file changed, 589 insertions(+)
 create mode 100644 drivers/net/ethernet/pensando/ionic/ionic_phc.c

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_phc.c b/drivers/net/ethernet/pensando/ionic/ionic_phc.c
new file mode 100644
index 000000000000..86ae5011ac9b
--- /dev/null
+++ b/drivers/net/ethernet/pensando/ionic/ionic_phc.c
@@ -0,0 +1,589 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2017 - 2021 Pensando Systems, Inc */
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+
+#include "ionic.h"
+#include "ionic_bus.h"
+#include "ionic_lif.h"
+#include "ionic_ethtool.h"
+
+static int ionic_hwstamp_tx_mode(int config_tx_type)
+{
+	switch (config_tx_type) {
+	case HWTSTAMP_TX_OFF:
+		return IONIC_TXSTAMP_OFF;
+	case HWTSTAMP_TX_ON:
+		return IONIC_TXSTAMP_ON;
+	case HWTSTAMP_TX_ONESTEP_SYNC:
+		return IONIC_TXSTAMP_ONESTEP_SYNC;
+#ifdef HAVE_HWSTAMP_TX_ONESTEP_P2P
+	case HWTSTAMP_TX_ONESTEP_P2P:
+		return IONIC_TXSTAMP_ONESTEP_P2P;
+#endif
+	default:
+		return -ERANGE;
+	}
+}
+
+static u64 ionic_hwstamp_rx_filt(int config_rx_filter)
+{
+	switch (config_rx_filter) {
+	case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
+		return IONIC_PKT_CLS_PTP1_ALL;
+	case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
+		return IONIC_PKT_CLS_PTP1_SYNC;
+	case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
+		return IONIC_PKT_CLS_PTP1_SYNC | IONIC_PKT_CLS_PTP1_DREQ;
+
+	case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
+		return IONIC_PKT_CLS_PTP2_L4_ALL;
+	case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
+		return IONIC_PKT_CLS_PTP2_L4_SYNC;
+	case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
+		return IONIC_PKT_CLS_PTP2_L4_SYNC | IONIC_PKT_CLS_PTP2_L4_DREQ;
+
+	case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
+		return IONIC_PKT_CLS_PTP2_L2_ALL;
+	case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
+		return IONIC_PKT_CLS_PTP2_L2_SYNC;
+	case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
+		return IONIC_PKT_CLS_PTP2_L2_SYNC | IONIC_PKT_CLS_PTP2_L2_DREQ;
+
+	case HWTSTAMP_FILTER_PTP_V2_EVENT:
+		return IONIC_PKT_CLS_PTP2_ALL;
+	case HWTSTAMP_FILTER_PTP_V2_SYNC:
+		return IONIC_PKT_CLS_PTP2_SYNC;
+	case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
+		return IONIC_PKT_CLS_PTP2_SYNC | IONIC_PKT_CLS_PTP2_DREQ;
+
+	case HWTSTAMP_FILTER_NTP_ALL:
+		return IONIC_PKT_CLS_NTP_ALL;
+
+	default:
+		return 0;
+	}
+}
+
+int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct ifreq *ifr)
+{
+	struct ionic *ionic = lif->ionic;
+	struct hwtstamp_config config;
+	int tx_mode = 0;
+	u64 rx_filt = 0;
+	int err, err2;
+	bool rx_all;
+	__le64 mask;
+
+	if (!lif->phc || !lif->phc->ptp)
+		return -EOPNOTSUPP;
+
+	if (ifr) {
+		if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
+			return -EFAULT;
+	} else {
+		/* if called with ifr == NULL, behave as if called with the
+		 * current ts_config from the initial cleared state.
+		 */
+		memcpy(&config, &lif->phc->ts_config, sizeof(config));
+		memset(&lif->phc->ts_config, 0, sizeof(config));
+	}
+
+	tx_mode = ionic_hwstamp_tx_mode(config.tx_type);
+	if (tx_mode < 0)
+		return tx_mode;
+
+	mask = cpu_to_le64(BIT_ULL(tx_mode));
+	if ((ionic->ident.lif.eth.hwstamp_tx_modes & mask) != mask)
+		return -ERANGE;
+
+	rx_filt = ionic_hwstamp_rx_filt(config.rx_filter);
+	rx_all = config.rx_filter != HWTSTAMP_FILTER_NONE && !rx_filt;
+
+	mask = cpu_to_le64(rx_filt);
+	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) != mask) {
+		rx_filt = 0;
+		rx_all = true;
+		config.rx_filter = HWTSTAMP_FILTER_ALL;
+	}
+
+	dev_dbg(ionic->dev, "config_rx_filter %d rx_filt %#llx rx_all %d\n",
+		config.rx_filter, rx_filt, rx_all);
+
+	mutex_lock(&lif->phc->config_lock);
+
+	if (tx_mode) {
+		err = ionic_lif_create_hwstamp_txq(lif);
+		if (err)
+			goto err_queues;
+	}
+
+	if (rx_filt) {
+		err = ionic_lif_create_hwstamp_rxq(lif);
+		if (err)
+			goto err_queues;
+	}
+
+	if (tx_mode != lif->phc->ts_config_tx_mode) {
+		err = ionic_lif_set_hwstamp_txmode(lif, tx_mode);
+		if (err)
+			goto err_txmode;
+	}
+
+	if (rx_filt != lif->phc->ts_config_rx_filt) {
+		err = ionic_lif_set_hwstamp_rxfilt(lif, rx_filt);
+		if (err)
+			goto err_rxfilt;
+	}
+
+	if (rx_all != (lif->phc->ts_config.rx_filter == HWTSTAMP_FILTER_ALL)) {
+		err = ionic_lif_config_hwstamp_rxq_all(lif, rx_all);
+		if (err)
+			goto err_rxall;
+	}
+
+	if (ifr) {
+		err = copy_to_user(ifr->ifr_data, &config, sizeof(config));
+		if (err) {
+			err = -EFAULT;
+			goto err_final;
+		}
+	}
+
+	memcpy(&lif->phc->ts_config, &config, sizeof(config));
+	lif->phc->ts_config_rx_filt = rx_filt;
+	lif->phc->ts_config_tx_mode = tx_mode;
+
+	mutex_unlock(&lif->phc->config_lock);
+
+	return 0;
+
+err_final:
+	if (rx_all != (lif->phc->ts_config.rx_filter == HWTSTAMP_FILTER_ALL)) {
+		rx_all = lif->phc->ts_config.rx_filter == HWTSTAMP_FILTER_ALL;
+		err2 = ionic_lif_config_hwstamp_rxq_all(lif, rx_all);
+		if (err2)
+			dev_err(ionic->dev,
+				"Failed to revert all-rxq timestamp config: %d\n", err2);
+	}
+err_rxall:
+	if (rx_filt != lif->phc->ts_config_rx_filt) {
+		rx_filt = lif->phc->ts_config_rx_filt;
+		err2 = ionic_lif_set_hwstamp_rxfilt(lif, rx_filt);
+		if (err2)
+			dev_err(ionic->dev,
+				"Failed to revert rx timestamp filter: %d\n", err2);
+	}
+err_rxfilt:
+	if (tx_mode != lif->phc->ts_config_tx_mode) {
+		tx_mode = lif->phc->ts_config_tx_mode;
+		err2 = ionic_lif_set_hwstamp_txmode(lif, tx_mode);
+		if (err2)
+			dev_err(ionic->dev,
+				"Failed to revert tx timestamp mode: %d\n", err2);
+	}
+err_txmode:
+	/* special queues remain allocated, just unused */
+err_queues:
+	mutex_unlock(&lif->phc->config_lock);
+	return err;
+}
+
+int ionic_lif_hwstamp_get(struct ionic_lif *lif, struct ifreq *ifr)
+{
+	struct hwtstamp_config config;
+
+	if (!lif->phc || !lif->phc->ptp)
+		return -EOPNOTSUPP;
+
+	mutex_lock(&lif->phc->config_lock);
+	memcpy(&config, &lif->phc->ts_config, sizeof(config));
+	mutex_unlock(&lif->phc->config_lock);
+
+	return copy_to_user(ifr->ifr_data, &config, sizeof(config));
+}
+
+static u64 ionic_hwstamp_read(struct ionic *ionic,
+			      struct ptp_system_timestamp *sts)
+{
+	u32 tick_high_before, tick_high, tick_low;
+
+	/* read and discard low part to defeat hw staging of high part */
+	(void)ioread32(&ionic->idev.hwstamp_regs->tick_low);
+
+	tick_high_before = ioread32(&ionic->idev.hwstamp_regs->tick_high);
+
+	ptp_read_system_prets(sts);
+	tick_low = ioread32(&ionic->idev.hwstamp_regs->tick_low);
+	ptp_read_system_postts(sts);
+
+	tick_high = ioread32(&ionic->idev.hwstamp_regs->tick_high);
+
+	/* If tick_high changed, re-read tick_low once more.  Assume tick_high
+	 * cannot change again so soon as in the span of re-reading tick_low.
+	 */
+	if (tick_high != tick_high_before) {
+		ptp_read_system_prets(sts);
+		tick_low = ioread32(&ionic->idev.hwstamp_regs->tick_low);
+		ptp_read_system_postts(sts);
+	}
+
+	return (u64)tick_low | ((u64)tick_high << 32);
+}
+
+static u64 ionic_cc_read(const struct cyclecounter *cc)
+{
+	struct ionic_phc *phc = container_of(cc, struct ionic_phc, cc);
+	struct ionic *ionic = phc->lif->ionic;
+
+	return ionic_hwstamp_read(ionic, NULL);
+}
+
+static int ionic_setphc_cmd(struct ionic_phc *phc, struct ionic_admin_ctx *ctx)
+{
+	ctx->work = COMPLETION_INITIALIZER_ONSTACK(ctx->work);
+
+	ctx->cmd.lif_setphc.opcode = IONIC_CMD_LIF_SETPHC;
+	ctx->cmd.lif_setphc.lif_index = cpu_to_le16(phc->lif->index);
+
+	ctx->cmd.lif_setphc.tick = cpu_to_le64(phc->tc.cycle_last);
+	ctx->cmd.lif_setphc.nsec = cpu_to_le64(phc->tc.nsec);
+	ctx->cmd.lif_setphc.frac = cpu_to_le64(phc->tc.frac);
+	ctx->cmd.lif_setphc.mult = cpu_to_le32(phc->cc.mult);
+	ctx->cmd.lif_setphc.shift = cpu_to_le32(phc->cc.shift);
+
+	return ionic_adminq_post(phc->lif, ctx);
+}
+
+static int ionic_phc_adjfine(struct ptp_clock_info *info, long scaled_ppm)
+{
+	struct ionic_phc *phc = container_of(info, struct ionic_phc, ptp_info);
+	struct ionic_admin_ctx ctx = {};
+	unsigned long irqflags;
+	s64 adj;
+	int err;
+
+	/* Reject phc adjustments during device upgrade */
+	if (test_bit(IONIC_LIF_F_FW_RESET, phc->lif->state))
+		return -EBUSY;
+
+	/* Adjustment value scaled by 2^16 million */
+	adj = (s64)scaled_ppm * phc->init_cc_mult;
+
+	/* Adjustment value to scale */
+	adj /= (s64)SCALED_PPM;
+
+	/* Final adjusted multiplier */
+	adj += phc->init_cc_mult;
+
+	spin_lock_irqsave(&phc->lock, irqflags);
+
+	/* update the point-in-time basis to now, before adjusting the rate */
+	timecounter_read(&phc->tc);
+	phc->cc.mult = adj;
+
+	/* Setphc commands are posted in-order, sequenced by phc->lock.  We
+	 * need to drop the lock before waiting for the command to complete.
+	 */
+	err = ionic_setphc_cmd(phc, &ctx);
+
+	spin_unlock_irqrestore(&phc->lock, irqflags);
+
+	return ionic_adminq_wait(phc->lif, &ctx, err);
+}
+
+static int ionic_phc_adjtime(struct ptp_clock_info *info, s64 delta)
+{
+	struct ionic_phc *phc = container_of(info, struct ionic_phc, ptp_info);
+	struct ionic_admin_ctx ctx = {};
+	unsigned long irqflags;
+	int err;
+
+	/* Reject phc adjustments during device upgrade */
+	if (test_bit(IONIC_LIF_F_FW_RESET, phc->lif->state))
+		return -EBUSY;
+
+	spin_lock_irqsave(&phc->lock, irqflags);
+
+	timecounter_adjtime(&phc->tc, delta);
+
+	/* Setphc commands are posted in-order, sequenced by phc->lock.  We
+	 * need to drop the lock before waiting for the command to complete.
+	 */
+	err = ionic_setphc_cmd(phc, &ctx);
+
+	spin_unlock_irqrestore(&phc->lock, irqflags);
+
+	return ionic_adminq_wait(phc->lif, &ctx, err);
+}
+
+static int ionic_phc_settime64(struct ptp_clock_info *info,
+			       const struct timespec64 *ts)
+{
+	struct ionic_phc *phc = container_of(info, struct ionic_phc, ptp_info);
+	struct ionic_admin_ctx ctx = {};
+	unsigned long irqflags;
+	int err;
+	u64 ns;
+
+	/* Reject phc adjustments during device upgrade */
+	if (test_bit(IONIC_LIF_F_FW_RESET, phc->lif->state))
+		return -EBUSY;
+
+	ns = timespec64_to_ns(ts);
+
+	spin_lock_irqsave(&phc->lock, irqflags);
+
+	timecounter_init(&phc->tc, &phc->cc, ns);
+
+	/* Setphc commands are posted in-order, sequenced by phc->lock.  We
+	 * need to drop the lock before waiting for the command to complete.
+	 */
+	err = ionic_setphc_cmd(phc, &ctx);
+
+	spin_unlock_irqrestore(&phc->lock, irqflags);
+
+	return ionic_adminq_wait(phc->lif, &ctx, err);
+}
+
+static int ionic_phc_gettimex64(struct ptp_clock_info *info,
+				struct timespec64 *ts,
+				struct ptp_system_timestamp *sts)
+{
+	struct ionic_phc *phc = container_of(info, struct ionic_phc, ptp_info);
+	struct ionic *ionic = phc->lif->ionic;
+	unsigned long irqflags;
+	u64 tick, ns;
+
+	/* Do not attempt to read device time during upgrade */
+	if (test_bit(IONIC_LIF_F_FW_RESET, phc->lif->state))
+		return -EBUSY;
+
+	spin_lock_irqsave(&phc->lock, irqflags);
+
+	tick = ionic_hwstamp_read(ionic, sts);
+
+	ns = timecounter_cyc2time(&phc->tc, tick);
+
+	spin_unlock_irqrestore(&phc->lock, irqflags);
+
+	*ts = ns_to_timespec64(ns);
+
+	return 0;
+}
+
+static long ionic_phc_aux_work(struct ptp_clock_info *info)
+{
+	struct ionic_phc *phc = container_of(info, struct ionic_phc, ptp_info);
+	struct ionic_admin_ctx ctx = {};
+	unsigned long irqflags;
+	int err;
+
+	/* Do not update phc during device upgrade, but keep polling to resume
+	 * after upgrade.  Since we don't update the point in time basis, there
+	 * is no expectation that we are maintaining the phc time during the
+	 * upgrade.  After upgrade, it will need to be readjusted back to the
+	 * correct time by the ptp daemon.
+	 */
+	if (test_bit(IONIC_LIF_F_FW_RESET, phc->lif->state))
+		return phc->aux_work_delay;
+
+	spin_lock_irqsave(&phc->lock, irqflags);
+
+	/* update point-in-time basis to now */
+	timecounter_read(&phc->tc);
+
+	/* Setphc commands are posted in-order, sequenced by phc->lock.  We
+	 * need to drop the lock before waiting for the command to complete.
+	 */
+	err = ionic_setphc_cmd(phc, &ctx);
+
+	spin_unlock_irqrestore(&phc->lock, irqflags);
+
+	ionic_adminq_wait(phc->lif, &ctx, err);
+
+	return phc->aux_work_delay;
+}
+
+ktime_t ionic_lif_phc_ktime(struct ionic_lif *lif, u64 tick)
+{
+	unsigned long irqflags;
+	u64 ns;
+
+	if (!lif->phc)
+		return 0;
+
+	spin_lock_irqsave(&lif->phc->lock, irqflags);
+	ns = timecounter_cyc2time(&lif->phc->tc, tick);
+	spin_unlock_irqrestore(&lif->phc->lock, irqflags);
+
+	return ns_to_ktime(ns);
+}
+
+static const struct ptp_clock_info ionic_ptp_info = {
+	.owner		= THIS_MODULE,
+	.name		= "ionic_ptp",
+	.adjfine	= ionic_phc_adjfine,
+	.adjtime	= ionic_phc_adjtime,
+	.gettimex64	= ionic_phc_gettimex64,
+	.settime64	= ionic_phc_settime64,
+	.do_aux_work	= ionic_phc_aux_work,
+};
+
+void ionic_lif_register_phc(struct ionic_lif *lif)
+{
+	if (!lif->phc || !(lif->hw_features & IONIC_ETH_HW_TIMESTAMP))
+		return;
+
+	lif->phc->ptp = ptp_clock_register(&lif->phc->ptp_info, lif->ionic->dev);
+
+	if (IS_ERR(lif->phc->ptp)) {
+		dev_warn(lif->ionic->dev, "Cannot register phc device: %ld\n",
+			 PTR_ERR(lif->phc->ptp));
+
+		lif->phc->ptp = NULL;
+	}
+
+	if (lif->phc->ptp)
+		ptp_schedule_worker(lif->phc->ptp, lif->phc->aux_work_delay);
+}
+
+void ionic_lif_unregister_phc(struct ionic_lif *lif)
+{
+	if (!lif->phc || !lif->phc->ptp)
+		return;
+
+	ptp_clock_unregister(lif->phc->ptp);
+
+	lif->phc->ptp = NULL;
+}
+
+void ionic_lif_alloc_phc(struct ionic_lif *lif)
+{
+	struct ionic *ionic = lif->ionic;
+	struct ionic_phc *phc;
+	u64 delay, diff, mult;
+	u64 frac = 0;
+	u64 features;
+	u32 shift;
+
+	if (!ionic->idev.hwstamp_regs)
+		return;
+
+	features = le64_to_cpu(ionic->ident.lif.eth.config.features);
+	if (!(features & IONIC_ETH_HW_TIMESTAMP))
+		return;
+
+	phc = devm_kzalloc(ionic->dev, sizeof(*phc), GFP_KERNEL);
+	if (!phc)
+		return;
+
+	phc->lif = lif;
+
+	phc->cc.read = ionic_cc_read;
+	phc->cc.mask = le64_to_cpu(ionic->ident.dev.hwstamp_mask);
+	phc->cc.mult = le32_to_cpu(ionic->ident.dev.hwstamp_mult);
+	phc->cc.shift = le32_to_cpu(ionic->ident.dev.hwstamp_shift);
+
+	if (!phc->cc.mult) {
+		dev_err(lif->ionic->dev,
+			"Invalid device PHC mask multiplier %u, disabling HW timestamp support\n",
+			phc->cc.mult);
+		devm_kfree(lif->ionic->dev, phc);
+		lif->phc = NULL;
+		return;
+	}
+
+	dev_dbg(lif->ionic->dev, "Device PHC mask %#llx mult %u shift %u\n",
+		phc->cc.mask, phc->cc.mult, phc->cc.shift);
+
+	spin_lock_init(&phc->lock);
+	mutex_init(&phc->config_lock);
+
+	/* max ticks is limited by the multiplier, or by the update period. */
+	if (phc->cc.shift + 2 + ilog2(IONIC_PHC_UPDATE_NS) >= 64) {
+		/* max ticks that do not overflow when multiplied by max
+		 * adjusted multiplier (twice the initial multiplier)
+		 */
+		diff = U64_MAX / phc->cc.mult / 2;
+	} else {
+		/* approx ticks at four times the update period */
+		diff = (u64)IONIC_PHC_UPDATE_NS << (phc->cc.shift + 2);
+		diff = DIV_ROUND_UP(diff, phc->cc.mult);
+	}
+
+	/* transform to bitmask */
+	diff |= diff >> 1;
+	diff |= diff >> 2;
+	diff |= diff >> 4;
+	diff |= diff >> 8;
+	diff |= diff >> 16;
+	diff |= diff >> 32;
+
+	/* constrain to the hardware bitmask, and use this as the bitmask */
+	diff &= phc->cc.mask;
+	phc->cc.mask = diff;
+
+	/* the wrap period is now defined by diff (or phc->cc.mask)
+	 *
+	 * we will update the time basis at about 1/4 the wrap period, so
+	 * should not see a difference of more than +/- diff/4.
+	 *
+	 * this is sufficient not see a difference of more than +/- diff/2, as
+	 * required by timecounter_cyc2time, to detect an old time stamp.
+	 *
+	 * adjust the initial multiplier, being careful to avoid overflow:
+	 *  - do not overflow 63 bits: init_cc_mult * SCALED_PPM
+	 *  - do not overflow 64 bits: max_mult * (diff / 2)
+	 *
+	 * we want to increase the initial multiplier as much as possible, to
+	 * allow for more precise adjustment in ionic_phc_adjfine.
+	 *
+	 * only adjust the multiplier if we can double it or more.
+	 */
+	mult = U64_MAX / 2 / max(diff / 2, SCALED_PPM);
+	shift = mult / phc->cc.mult;
+	if (shift >= 2) {
+		/* initial multiplier will be 2^n of hardware cc.mult */
+		shift = fls(shift);
+		/* increase cc.mult and cc.shift by the same 2^n and n. */
+		phc->cc.mult <<= shift;
+		phc->cc.shift += shift;
+	}
+
+	dev_dbg(lif->ionic->dev, "Initial PHC mask %#llx mult %u shift %u\n",
+		phc->cc.mask, phc->cc.mult, phc->cc.shift);
+
+	/* frequency adjustments are relative to the initial multiplier */
+	phc->init_cc_mult = phc->cc.mult;
+
+	timecounter_init(&phc->tc, &phc->cc, ktime_get_real_ns());
+
+	/* Update cycle_last at 1/4 the wrap period, or IONIC_PHC_UPDATE_NS */
+	delay = min_t(u64, IONIC_PHC_UPDATE_NS,
+		      cyclecounter_cyc2ns(&phc->cc, diff / 4, 0, &frac));
+	dev_dbg(lif->ionic->dev, "Work delay %llu ms\n", delay / NSEC_PER_MSEC);
+
+	phc->aux_work_delay = nsecs_to_jiffies(delay);
+
+	phc->ptp_info = ionic_ptp_info;
+
+	/* We have allowed to adjust the multiplier up to +/- 1 part per 1.
+	 * Here expressed as NORMAL_PPB (1 billion parts per billion).
+	 */
+	phc->ptp_info.max_adj = NORMAL_PPB;
+
+	lif->phc = phc;
+}
+
+void ionic_lif_free_phc(struct ionic_lif *lif)
+{
+	if (!lif->phc)
+		return;
+
+	mutex_destroy(&lif->phc->config_lock);
+
+	devm_kfree(lif->ionic->dev, lif->phc);
+	lif->phc = NULL;
+}
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH net-next 06/12] ionic: link in the new hw timestamp code
  2021-04-01 17:55 [PATCH net-next 00/12] ionic: add PTP and hw clock support Shannon Nelson
                   ` (4 preceding siblings ...)
  2021-04-01 17:56 ` [PATCH net-next 05/12] ionic: add hw timestamp support files Shannon Nelson
@ 2021-04-01 17:56 ` Shannon Nelson
  2021-04-01 17:56 ` [PATCH net-next 07/12] ionic: add rx filtering for hw timestamp steering Shannon Nelson
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 35+ messages in thread
From: Shannon Nelson @ 2021-04-01 17:56 UTC (permalink / raw)
  To: netdev, davem, kuba; +Cc: drivers, Shannon Nelson, Allen Hubbe

These are changes to compile and link the new code, but no
new feature support is available or advertised yet.

Signed-off-by: Allen Hubbe <allenbh@pensando.io>
Signed-off-by: Shannon Nelson <snelson@pensando.io>
---
 drivers/net/ethernet/pensando/ionic/Makefile  |  1 +
 drivers/net/ethernet/pensando/ionic/ionic.h   |  4 ++
 .../net/ethernet/pensando/ionic/ionic_dev.c   |  2 +
 .../net/ethernet/pensando/ionic/ionic_dev.h   |  1 +
 .../net/ethernet/pensando/ionic/ionic_lif.c   | 25 +++++++
 .../net/ethernet/pensando/ionic/ionic_lif.h   | 72 +++++++++++++++++++
 .../net/ethernet/pensando/ionic/ionic_main.c  |  2 +
 7 files changed, 107 insertions(+)

diff --git a/drivers/net/ethernet/pensando/ionic/Makefile b/drivers/net/ethernet/pensando/ionic/Makefile
index 8d3c2d3cb10d..4e7642a2d25f 100644
--- a/drivers/net/ethernet/pensando/ionic/Makefile
+++ b/drivers/net/ethernet/pensando/ionic/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_IONIC) := ionic.o
 ionic-y := ionic_main.o ionic_bus_pci.o ionic_devlink.o ionic_dev.o \
 	   ionic_debugfs.o ionic_lif.o ionic_rx_filter.o ionic_ethtool.o \
 	   ionic_txrx.o ionic_stats.o ionic_fw.o
+ionic-$(CONFIG_PTP_1588_CLOCK) += ionic_phc.o
diff --git a/drivers/net/ethernet/pensando/ionic/ionic.h b/drivers/net/ethernet/pensando/ionic/ionic.h
index 18e92103c711..66204106f83e 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic.h
@@ -20,6 +20,10 @@ struct ionic_lif;
 
 #define DEVCMD_TIMEOUT  10
 
+#define IONIC_PHC_UPDATE_NS	10000000000	    /* 10s in nanoseconds */
+#define NORMAL_PPB		1000000000	    /* one billion parts per billion */
+#define SCALED_PPM		(1000000ull << 16)  /* 2^16 million parts per 2^16 million */
+
 struct ionic_vf {
 	u16	 index;
 	u8	 macaddr[6];
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.c b/drivers/net/ethernet/pensando/ionic/ionic_dev.c
index 0e8e88c69e1c..1dfe962e22e0 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_dev.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.c
@@ -79,6 +79,8 @@ int ionic_dev_setup(struct ionic *ionic)
 	idev->intr_status = bar->vaddr + IONIC_BAR0_INTR_STATUS_OFFSET;
 	idev->intr_ctrl = bar->vaddr + IONIC_BAR0_INTR_CTRL_OFFSET;
 
+	idev->hwstamp_regs = &idev->dev_info_regs->hwstamp;
+
 	sig = ioread32(&idev->dev_info_regs->signature);
 	if (sig != IONIC_DEV_INFO_SIGNATURE) {
 		dev_err(dev, "Incompatible firmware signature %x", sig);
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.h b/drivers/net/ethernet/pensando/ionic/ionic_dev.h
index 25c52c042246..28994e01fa0a 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_dev.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.h
@@ -136,6 +136,7 @@ struct ionic_devinfo {
 struct ionic_dev {
 	union ionic_dev_info_regs __iomem *dev_info_regs;
 	union ionic_dev_cmd_regs __iomem *dev_cmd_regs;
+	struct ionic_hwstamp_regs __iomem *hwstamp_regs;
 
 	atomic_long_t last_check_time;
 	unsigned long last_hb_time;
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index 9a61b2bbb652..ced80de4d92a 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -830,6 +830,31 @@ static int ionic_lif_rxq_init(struct ionic_lif *lif, struct ionic_qcq *qcq)
 	return 0;
 }
 
+int ionic_lif_create_hwstamp_txq(struct ionic_lif *lif)
+{
+	return 0;
+}
+
+int ionic_lif_create_hwstamp_rxq(struct ionic_lif *lif)
+{
+	return 0;
+}
+
+int ionic_lif_config_hwstamp_rxq_all(struct ionic_lif *lif, bool rx_all)
+{
+	return 0;
+}
+
+int ionic_lif_set_hwstamp_txmode(struct ionic_lif *lif, u16 txstamp_mode)
+{
+	return 0;
+}
+
+int ionic_lif_set_hwstamp_rxfilt(struct ionic_lif *lif, u64 pkt_class)
+{
+	return 0;
+}
+
 static bool ionic_notifyq_service(struct ionic_cq *cq,
 				  struct ionic_cq_info *cq_info)
 {
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.h b/drivers/net/ethernet/pensando/ionic/ionic_lif.h
index 93d3058aed77..ea3b086af179 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.h
@@ -4,6 +4,9 @@
 #ifndef _IONIC_LIF_H_
 #define _IONIC_LIF_H_
 
+#include <linux/ptp_clock_kernel.h>
+#include <linux/timecounter.h>
+#include <uapi/linux/net_tstamp.h>
 #include <linux/dim.h>
 #include <linux/pci.h>
 #include "ionic_rx_filter.h"
@@ -36,6 +39,8 @@ struct ionic_tx_stats {
 	u64 crc32_csum;
 	u64 sg_cntr[IONIC_MAX_NUM_SG_CNTR];
 	u64 dma_map_err;
+	u64 hwstamp_valid;
+	u64 hwstamp_invalid;
 };
 
 struct ionic_rx_stats {
@@ -49,6 +54,8 @@ struct ionic_rx_stats {
 	u64 csum_error;
 	u64 dma_map_err;
 	u64 alloc_err;
+	u64 hwstamp_valid;
+	u64 hwstamp_invalid;
 };
 
 #define IONIC_QCQ_F_INITED		BIT(0)
@@ -125,6 +132,10 @@ struct ionic_lif_sw_stats {
 	u64 rx_csum_none;
 	u64 rx_csum_complete;
 	u64 rx_csum_error;
+	u64 tx_hwstamp_valid;
+	u64 tx_hwstamp_invalid;
+	u64 rx_hwstamp_valid;
+	u64 rx_hwstamp_invalid;
 	u64 hw_tx_dropped;
 	u64 hw_rx_dropped;
 	u64 hw_rx_over_errors;
@@ -158,6 +169,8 @@ struct ionic_qtype_info {
 	u16 sg_desc_stride;
 };
 
+struct ionic_phc;
+
 #define IONIC_LIF_NAME_MAX_SZ		32
 struct ionic_lif {
 	struct net_device *netdev;
@@ -170,8 +183,10 @@ struct ionic_lif {
 	struct ionic_qcq *adminqcq;
 	struct ionic_qcq *notifyqcq;
 	struct ionic_qcq **txqcqs;
+	struct ionic_qcq *hwstamp_txq;
 	struct ionic_tx_stats *txqstats;
 	struct ionic_qcq **rxqcqs;
+	struct ionic_qcq *hwstamp_rxq;
 	struct ionic_rx_stats *rxqstats;
 	struct ionic_deferred deferred;
 	struct work_struct tx_timeout_work;
@@ -214,9 +229,29 @@ struct ionic_lif {
 	unsigned long *dbid_inuse;
 	unsigned int dbid_count;
 
+	struct ionic_phc *phc;
+
 	struct dentry *dentry;
 };
 
+struct ionic_phc {
+	spinlock_t lock; /* lock for cc and tc */
+	struct cyclecounter cc;
+	struct timecounter tc;
+
+	struct mutex config_lock; /* lock for ts_config */
+	struct hwtstamp_config ts_config;
+	u64 ts_config_rx_filt;
+	u32 ts_config_tx_mode;
+
+	u32 init_cc_mult;
+	long aux_work_delay;
+
+	struct ptp_clock_info ptp_info;
+	struct ptp_clock *ptp;
+	struct ionic_lif *lif;
+};
+
 struct ionic_queue_params {
 	unsigned int nxqs;
 	unsigned int ntxq_descs;
@@ -265,6 +300,43 @@ void ionic_lif_unregister(struct ionic_lif *lif);
 int ionic_lif_identify(struct ionic *ionic, u8 lif_type,
 		       union ionic_lif_identity *lif_ident);
 int ionic_lif_size(struct ionic *ionic);
+
+#if IS_ENABLED(CONFIG_PTP_1588_CLOCK)
+int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct ifreq *ifr);
+int ionic_lif_hwstamp_get(struct ionic_lif *lif, struct ifreq *ifr);
+ktime_t ionic_lif_phc_ktime(struct ionic_lif *lif, u64 counter);
+void ionic_lif_register_phc(struct ionic_lif *lif);
+void ionic_lif_unregister_phc(struct ionic_lif *lif);
+void ionic_lif_alloc_phc(struct ionic_lif *lif);
+void ionic_lif_free_phc(struct ionic_lif *lif);
+#else
+static inline int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct ifreq *ifr)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int ionic_lif_hwstamp_get(struct ionic_lif *lif, struct ifreq *ifr)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline ktime_t ionic_lif_phc_ktime(struct ionic_lif *lif, u64 counter)
+{
+	return ns_to_ktime(0);
+}
+
+static inline void ionic_lif_register_phc(struct ionic_lif *lif) {}
+static inline void ionic_lif_unregister_phc(struct ionic_lif *lif) {}
+static inline void ionic_lif_alloc_phc(struct ionic_lif *lif) {}
+static inline void ionic_lif_free_phc(struct ionic_lif *lif) {}
+#endif
+
+int ionic_lif_create_hwstamp_txq(struct ionic_lif *lif);
+int ionic_lif_create_hwstamp_rxq(struct ionic_lif *lif);
+int ionic_lif_config_hwstamp_rxq_all(struct ionic_lif *lif, bool rx_all);
+int ionic_lif_set_hwstamp_txmode(struct ionic_lif *lif, u16 txstamp_mode);
+int ionic_lif_set_hwstamp_rxfilt(struct ionic_lif *lif, u64 pkt_class);
+
 int ionic_lif_rss_config(struct ionic_lif *lif, u16 types,
 			 const u8 *key, const u32 *indir);
 int ionic_reconfigure_queues(struct ionic_lif *lif,
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_main.c b/drivers/net/ethernet/pensando/ionic/ionic_main.c
index 8c27fbe0e312..61cfe2120817 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_main.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_main.c
@@ -148,6 +148,8 @@ static const char *ionic_opcode_to_str(enum ionic_cmd_opcode opcode)
 		return "IONIC_CMD_LIF_SETATTR";
 	case IONIC_CMD_LIF_GETATTR:
 		return "IONIC_CMD_LIF_GETATTR";
+	case IONIC_CMD_LIF_SETPHC:
+		return "IONIC_CMD_LIF_SETPHC";
 	case IONIC_CMD_RX_MODE_SET:
 		return "IONIC_CMD_RX_MODE_SET";
 	case IONIC_CMD_RX_FILTER_ADD:
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH net-next 07/12] ionic: add rx filtering for hw timestamp steering
  2021-04-01 17:55 [PATCH net-next 00/12] ionic: add PTP and hw clock support Shannon Nelson
                   ` (5 preceding siblings ...)
  2021-04-01 17:56 ` [PATCH net-next 06/12] ionic: link in the new hw timestamp code Shannon Nelson
@ 2021-04-01 17:56 ` Shannon Nelson
  2021-04-01 17:56 ` [PATCH net-next 08/12] ionic: set up hw timestamp queues Shannon Nelson
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 35+ messages in thread
From: Shannon Nelson @ 2021-04-01 17:56 UTC (permalink / raw)
  To: netdev, davem, kuba; +Cc: drivers, Shannon Nelson, Allen Hubbe

Add handling of the new Rx packet classification filter type.
This simple bit of classification allows for steering packets
to a separate Rx queue for processing.

Signed-off-by: Allen Hubbe <allenbh@pensando.io>
Signed-off-by: Shannon Nelson <snelson@pensando.io>
---
 .../ethernet/pensando/ionic/ionic_rx_filter.c | 21 +++++++++++++++++++
 .../ethernet/pensando/ionic/ionic_rx_filter.h |  1 +
 2 files changed, 22 insertions(+)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_rx_filter.c b/drivers/net/ethernet/pensando/ionic/ionic_rx_filter.c
index cd0076fc3044..d71316d9ded2 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_rx_filter.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_rx_filter.c
@@ -140,6 +140,9 @@ int ionic_rx_filter_save(struct ionic_lif *lif, u32 flow_id, u16 rxq_index,
 	case IONIC_RX_FILTER_MATCH_MAC_VLAN:
 		key = le16_to_cpu(ac->mac_vlan.vlan);
 		break;
+	case IONIC_RX_FILTER_STEER_PKTCLASS:
+		key = 0;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -210,3 +213,21 @@ struct ionic_rx_filter *ionic_rx_filter_by_addr(struct ionic_lif *lif,
 
 	return NULL;
 }
+
+struct ionic_rx_filter *ionic_rx_filter_rxsteer(struct ionic_lif *lif)
+{
+	struct ionic_rx_filter *f;
+	struct hlist_head *head;
+	unsigned int key;
+
+	key = hash_32(0, IONIC_RX_FILTER_HASH_BITS);
+	head = &lif->rx_filters.by_hash[key];
+
+	hlist_for_each_entry(f, head, by_hash) {
+		if (le16_to_cpu(f->cmd.match) != IONIC_RX_FILTER_STEER_PKTCLASS)
+			continue;
+		return f;
+	}
+
+	return NULL;
+}
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_rx_filter.h b/drivers/net/ethernet/pensando/ionic/ionic_rx_filter.h
index cf8f4c0a961c..1ead48be3c83 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_rx_filter.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_rx_filter.h
@@ -31,5 +31,6 @@ int ionic_rx_filter_save(struct ionic_lif *lif, u32 flow_id, u16 rxq_index,
 			 u32 hash, struct ionic_admin_ctx *ctx);
 struct ionic_rx_filter *ionic_rx_filter_by_vlan(struct ionic_lif *lif, u16 vid);
 struct ionic_rx_filter *ionic_rx_filter_by_addr(struct ionic_lif *lif, const u8 *addr);
+struct ionic_rx_filter *ionic_rx_filter_rxsteer(struct ionic_lif *lif);
 
 #endif /* _IONIC_RX_FILTER_H_ */
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH net-next 08/12] ionic: set up hw timestamp queues
  2021-04-01 17:55 [PATCH net-next 00/12] ionic: add PTP and hw clock support Shannon Nelson
                   ` (6 preceding siblings ...)
  2021-04-01 17:56 ` [PATCH net-next 07/12] ionic: add rx filtering for hw timestamp steering Shannon Nelson
@ 2021-04-01 17:56 ` Shannon Nelson
  2021-04-01 17:56 ` [PATCH net-next 09/12] ionic: add and enable tx and rx timestamp handling Shannon Nelson
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 35+ messages in thread
From: Shannon Nelson @ 2021-04-01 17:56 UTC (permalink / raw)
  To: netdev, davem, kuba; +Cc: drivers, Shannon Nelson, Allen Hubbe

We do hardware timestamping through a separate Tx queue,
and optionally through a separate Rx queue.  These queues
are allocated, freed, and tracked separately from the basic
queue arrays.

Signed-off-by: Allen Hubbe <allenbh@pensando.io>
Signed-off-by: Shannon Nelson <snelson@pensando.io>
---
 .../net/ethernet/pensando/ionic/ionic_lif.c   | 266 +++++++++++++++++-
 1 file changed, 261 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index ced80de4d92a..26c066ed74c4 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -684,11 +684,11 @@ static int ionic_qcqs_alloc(struct ionic_lif *lif)
 	if (!lif->rxqcqs)
 		goto err_out;
 
-	lif->txqstats = devm_kcalloc(dev, lif->ionic->ntxqs_per_lif,
+	lif->txqstats = devm_kcalloc(dev, lif->ionic->ntxqs_per_lif + 1,
 				     sizeof(*lif->txqstats), GFP_KERNEL);
 	if (!lif->txqstats)
 		goto err_out;
-	lif->rxqstats = devm_kcalloc(dev, lif->ionic->nrxqs_per_lif,
+	lif->rxqstats = devm_kcalloc(dev, lif->ionic->nrxqs_per_lif + 1,
 				     sizeof(*lif->rxqstats), GFP_KERNEL);
 	if (!lif->rxqstats)
 		goto err_out;
@@ -832,27 +832,250 @@ static int ionic_lif_rxq_init(struct ionic_lif *lif, struct ionic_qcq *qcq)
 
 int ionic_lif_create_hwstamp_txq(struct ionic_lif *lif)
 {
+	unsigned int num_desc, desc_sz, comp_sz, sg_desc_sz;
+	unsigned int txq_i, flags;
+	struct ionic_qcq *txq;
+	u64 features;
+	int err;
+
+	mutex_lock(&lif->queue_lock);
+
+	if (lif->hwstamp_txq)
+		goto out;
+
+	features = IONIC_Q_F_2X_CQ_DESC | IONIC_TXQ_F_HWSTAMP;
+
+	num_desc = IONIC_MIN_TXRX_DESC;
+	desc_sz = sizeof(struct ionic_txq_desc);
+	comp_sz = 2 * sizeof(struct ionic_txq_comp);
+
+	if (lif->qtype_info[IONIC_QTYPE_TXQ].version >= 1 &&
+	    lif->qtype_info[IONIC_QTYPE_TXQ].sg_desc_sz == sizeof(struct ionic_txq_sg_desc_v1))
+		sg_desc_sz = sizeof(struct ionic_txq_sg_desc_v1);
+	else
+		sg_desc_sz = sizeof(struct ionic_txq_sg_desc);
+
+	txq_i = lif->ionic->ntxqs_per_lif;
+	flags = IONIC_QCQ_F_TX_STATS | IONIC_QCQ_F_SG;
+
+	err = ionic_qcq_alloc(lif, IONIC_QTYPE_TXQ, txq_i, "hwstamp_tx", flags,
+			      num_desc, desc_sz, comp_sz, sg_desc_sz,
+			      lif->kern_pid, &txq);
+	if (err)
+		goto err_qcq_alloc;
+
+	txq->q.features = features;
+
+	ionic_link_qcq_interrupts(lif->adminqcq, txq);
+	ionic_debugfs_add_qcq(lif, txq);
+
+	lif->hwstamp_txq = txq;
+
+	if (netif_running(lif->netdev)) {
+		err = ionic_lif_txq_init(lif, txq);
+		if (err)
+			goto err_qcq_init;
+
+		if (test_bit(IONIC_LIF_F_UP, lif->state)) {
+			err = ionic_qcq_enable(txq);
+			if (err)
+				goto err_qcq_enable;
+		}
+	}
+
+out:
+	mutex_unlock(&lif->queue_lock);
+
 	return 0;
+
+err_qcq_enable:
+	ionic_lif_qcq_deinit(lif, txq);
+err_qcq_init:
+	lif->hwstamp_txq = NULL;
+	ionic_debugfs_del_qcq(txq);
+	ionic_qcq_free(lif, txq);
+	devm_kfree(lif->ionic->dev, txq);
+err_qcq_alloc:
+	mutex_unlock(&lif->queue_lock);
+	return err;
 }
 
 int ionic_lif_create_hwstamp_rxq(struct ionic_lif *lif)
 {
+	unsigned int num_desc, desc_sz, comp_sz, sg_desc_sz;
+	unsigned int rxq_i, flags;
+	struct ionic_qcq *rxq;
+	u64 features;
+	int err;
+
+	mutex_lock(&lif->queue_lock);
+
+	if (lif->hwstamp_rxq)
+		goto out;
+
+	features = IONIC_Q_F_2X_CQ_DESC | IONIC_RXQ_F_HWSTAMP;
+
+	num_desc = IONIC_MIN_TXRX_DESC;
+	desc_sz = sizeof(struct ionic_rxq_desc);
+	comp_sz = 2 * sizeof(struct ionic_rxq_comp);
+	sg_desc_sz = sizeof(struct ionic_rxq_sg_desc);
+
+	rxq_i = lif->ionic->nrxqs_per_lif;
+	flags = IONIC_QCQ_F_RX_STATS | IONIC_QCQ_F_SG;
+
+	err = ionic_qcq_alloc(lif, IONIC_QTYPE_RXQ, rxq_i, "hwstamp_rx", flags,
+			      num_desc, desc_sz, comp_sz, sg_desc_sz,
+			      lif->kern_pid, &rxq);
+	if (err)
+		goto err_qcq_alloc;
+
+	rxq->q.features = features;
+
+	ionic_link_qcq_interrupts(lif->adminqcq, rxq);
+	ionic_debugfs_add_qcq(lif, rxq);
+
+	lif->hwstamp_rxq = rxq;
+
+	if (netif_running(lif->netdev)) {
+		err = ionic_lif_rxq_init(lif, rxq);
+		if (err)
+			goto err_qcq_init;
+
+		if (test_bit(IONIC_LIF_F_UP, lif->state)) {
+			ionic_rx_fill(&rxq->q);
+			err = ionic_qcq_enable(rxq);
+			if (err)
+				goto err_qcq_enable;
+		}
+	}
+
+out:
+	mutex_unlock(&lif->queue_lock);
+
 	return 0;
+
+err_qcq_enable:
+	ionic_lif_qcq_deinit(lif, rxq);
+err_qcq_init:
+	lif->hwstamp_rxq = NULL;
+	ionic_debugfs_del_qcq(rxq);
+	ionic_qcq_free(lif, rxq);
+	devm_kfree(lif->ionic->dev, rxq);
+err_qcq_alloc:
+	mutex_unlock(&lif->queue_lock);
+	return err;
 }
 
 int ionic_lif_config_hwstamp_rxq_all(struct ionic_lif *lif, bool rx_all)
 {
-	return 0;
+	struct ionic_queue_params qparam;
+
+	ionic_init_queue_params(lif, &qparam);
+
+	if (rx_all)
+		qparam.rxq_features = IONIC_Q_F_2X_CQ_DESC | IONIC_RXQ_F_HWSTAMP;
+	else
+		qparam.rxq_features = 0;
+
+	/* if we're not running, just set the values and return */
+	if (!netif_running(lif->netdev)) {
+		lif->rxq_features = qparam.rxq_features;
+		return 0;
+	}
+
+	return ionic_reconfigure_queues(lif, &qparam);
 }
 
 int ionic_lif_set_hwstamp_txmode(struct ionic_lif *lif, u16 txstamp_mode)
 {
-	return 0;
+	struct ionic_admin_ctx ctx = {
+		.work = COMPLETION_INITIALIZER_ONSTACK(ctx.work),
+		.cmd.lif_setattr = {
+			.opcode = IONIC_CMD_LIF_SETATTR,
+			.index = cpu_to_le16(lif->index),
+			.attr = IONIC_LIF_ATTR_TXSTAMP,
+			.txstamp_mode = cpu_to_le16(txstamp_mode),
+		},
+	};
+
+	return ionic_adminq_post_wait(lif, &ctx);
+}
+
+static void ionic_lif_del_hwstamp_rxfilt(struct ionic_lif *lif)
+{
+	struct ionic_admin_ctx ctx = {
+		.work = COMPLETION_INITIALIZER_ONSTACK(ctx.work),
+		.cmd.rx_filter_del = {
+			.opcode = IONIC_CMD_RX_FILTER_DEL,
+			.lif_index = cpu_to_le16(lif->index),
+		},
+	};
+	struct ionic_rx_filter *f;
+	u32 filter_id;
+	int err;
+
+	spin_lock_bh(&lif->rx_filters.lock);
+
+	f = ionic_rx_filter_rxsteer(lif);
+	if (!f) {
+		spin_unlock_bh(&lif->rx_filters.lock);
+		return;
+	}
+
+	filter_id = f->filter_id;
+	ionic_rx_filter_free(lif, f);
+
+	spin_unlock_bh(&lif->rx_filters.lock);
+
+	netdev_dbg(lif->netdev, "rx_filter del RXSTEER (id %d)\n", filter_id);
+
+	ctx.cmd.rx_filter_del.filter_id = cpu_to_le32(filter_id);
+
+	err = ionic_adminq_post_wait(lif, &ctx);
+	if (err && err != -EEXIST)
+		netdev_dbg(lif->netdev, "failed to delete rx_filter RXSTEER (id %d)\n", filter_id);
+}
+
+static int ionic_lif_add_hwstamp_rxfilt(struct ionic_lif *lif, u64 pkt_class)
+{
+	struct ionic_admin_ctx ctx = {
+		.work = COMPLETION_INITIALIZER_ONSTACK(ctx.work),
+		.cmd.rx_filter_add = {
+			.opcode = IONIC_CMD_RX_FILTER_ADD,
+			.lif_index = cpu_to_le16(lif->index),
+			.match = cpu_to_le16(IONIC_RX_FILTER_STEER_PKTCLASS),
+			.pkt_class = cpu_to_le64(pkt_class),
+		},
+	};
+	u8 qtype;
+	u32 qid;
+	int err;
+
+	if (!lif->hwstamp_rxq)
+		return -EINVAL;
+
+	qtype = lif->hwstamp_rxq->q.type;
+	ctx.cmd.rx_filter_add.qtype = qtype;
+
+	qid = lif->hwstamp_rxq->q.index;
+	ctx.cmd.rx_filter_add.qid = cpu_to_le32(qid);
+
+	netdev_dbg(lif->netdev, "rx_filter add RXSTEER\n");
+	err = ionic_adminq_post_wait(lif, &ctx);
+	if (err && err != -EEXIST)
+		return err;
+
+	return ionic_rx_filter_save(lif, 0, qid, 0, &ctx);
 }
 
 int ionic_lif_set_hwstamp_rxfilt(struct ionic_lif *lif, u64 pkt_class)
 {
-	return 0;
+	ionic_lif_del_hwstamp_rxfilt(lif);
+
+	if (!pkt_class)
+		return 0;
+
+	return ionic_lif_add_hwstamp_rxfilt(lif, pkt_class);
 }
 
 static bool ionic_notifyq_service(struct ionic_cq *cq,
@@ -1695,11 +1918,17 @@ static void ionic_txrx_disable(struct ionic_lif *lif)
 			err = ionic_qcq_disable(lif->txqcqs[i], (err != -ETIMEDOUT));
 	}
 
+	if (lif->hwstamp_txq)
+		err = ionic_qcq_disable(lif->hwstamp_txq, (err != -ETIMEDOUT));
+
 	if (lif->rxqcqs) {
 		for (i = 0; i < lif->nxqs; i++)
 			err = ionic_qcq_disable(lif->rxqcqs[i], (err != -ETIMEDOUT));
 	}
 
+	if (lif->hwstamp_rxq)
+		err = ionic_qcq_disable(lif->hwstamp_rxq, (err != -ETIMEDOUT));
+
 	ionic_lif_quiesce(lif);
 }
 
@@ -1743,6 +1972,18 @@ static void ionic_txrx_free(struct ionic_lif *lif)
 			lif->rxqcqs[i] = NULL;
 		}
 	}
+
+	if (lif->hwstamp_txq) {
+		ionic_qcq_free(lif, lif->hwstamp_txq);
+		devm_kfree(lif->ionic->dev, lif->hwstamp_txq);
+		lif->hwstamp_txq = NULL;
+	}
+
+	if (lif->hwstamp_rxq) {
+		ionic_qcq_free(lif, lif->hwstamp_rxq);
+		devm_kfree(lif->ionic->dev, lif->hwstamp_rxq);
+		lif->hwstamp_rxq = NULL;
+	}
 }
 
 static int ionic_txrx_alloc(struct ionic_lif *lif)
@@ -2587,6 +2828,8 @@ int ionic_lif_alloc(struct ionic *ionic)
 	}
 	netdev_rss_key_fill(lif->rss_hash_key, IONIC_RSS_HASH_KEY_SIZE);
 
+	ionic_lif_alloc_phc(lif);
+
 	return 0;
 
 err_out_free_qcqs:
@@ -2707,6 +2950,8 @@ void ionic_lif_free(struct ionic_lif *lif)
 {
 	struct device *dev = lif->ionic->dev;
 
+	ionic_lif_free_phc(lif);
+
 	/* free rss indirection table */
 	dma_free_coherent(dev, lif->rss_ind_tbl_sz, lif->rss_ind_tbl,
 			  lif->rss_ind_tbl_pa);
@@ -3075,6 +3320,7 @@ void ionic_lif_unregister(struct ionic_lif *lif)
 
 	if (lif->netdev->reg_state == NETREG_REGISTERED)
 		unregister_netdev(lif->netdev);
+
 	lif->registered = false;
 }
 
@@ -3214,6 +3460,16 @@ int ionic_lif_size(struct ionic *ionic)
 	ntxqs_per_lif = le32_to_cpu(lc->queue_count[IONIC_QTYPE_TXQ]);
 	nrxqs_per_lif = le32_to_cpu(lc->queue_count[IONIC_QTYPE_RXQ]);
 
+	/* reserve last queue id for hardware timestamping */
+	if (lc->features & cpu_to_le64(IONIC_ETH_HW_TIMESTAMP)) {
+		if (ntxqs_per_lif <= 1 || nrxqs_per_lif <= 1) {
+			lc->features &= cpu_to_le64(~IONIC_ETH_HW_TIMESTAMP);
+		} else {
+			ntxqs_per_lif -= 1;
+			nrxqs_per_lif -= 1;
+		}
+	}
+
 	nxqs = min(ntxqs_per_lif, nrxqs_per_lif);
 	nxqs = min(nxqs, num_online_cpus());
 	neqs = min(neqs_per_lif, num_online_cpus());
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH net-next 09/12] ionic: add and enable tx and rx timestamp handling
  2021-04-01 17:55 [PATCH net-next 00/12] ionic: add PTP and hw clock support Shannon Nelson
                   ` (7 preceding siblings ...)
  2021-04-01 17:56 ` [PATCH net-next 08/12] ionic: set up hw timestamp queues Shannon Nelson
@ 2021-04-01 17:56 ` Shannon Nelson
  2021-04-04 23:41   ` Richard Cochran
  2021-04-01 17:56 ` [PATCH net-next 10/12] ionic: add ethtool support for PTP Shannon Nelson
                   ` (4 subsequent siblings)
  13 siblings, 1 reply; 35+ messages in thread
From: Shannon Nelson @ 2021-04-01 17:56 UTC (permalink / raw)
  To: netdev, davem, kuba; +Cc: drivers, Shannon Nelson, Allen Hubbe

The Tx and Rx timestamped packets are handled through separate
queues.  Here we set them up, service them, and tear them down
along with the normal Tx and Rx queues.

Signed-off-by: Allen Hubbe <allenbh@pensando.io>
Signed-off-by: Shannon Nelson <snelson@pensando.io>
---
 .../net/ethernet/pensando/ionic/ionic_dev.h   |   2 +-
 .../net/ethernet/pensando/ionic/ionic_lif.c   |  51 ++++++-
 .../net/ethernet/pensando/ionic/ionic_txrx.c  | 126 +++++++++++++++---
 .../net/ethernet/pensando/ionic/ionic_txrx.h  |   3 +
 4 files changed, 157 insertions(+), 25 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.h b/drivers/net/ethernet/pensando/ionic/ionic_dev.h
index 28994e01fa0a..c25cf9b744c5 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_dev.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.h
@@ -220,11 +220,11 @@ struct ionic_queue {
 	unsigned int index;
 	unsigned int num_descs;
 	unsigned int max_sg_elems;
+	u64 features;
 	u64 dbell_count;
 	u64 stop;
 	u64 wake;
 	u64 drop;
-	u64 features;
 	struct ionic_dev *idev;
 	unsigned int type;
 	unsigned int hw_index;
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index 26c066ed74c4..e14c93fbbd68 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -1145,9 +1145,12 @@ static int ionic_adminq_napi(struct napi_struct *napi, int budget)
 	struct ionic_dev *idev = &lif->ionic->idev;
 	unsigned long irqflags;
 	unsigned int flags = 0;
+	int rx_work = 0;
+	int tx_work = 0;
 	int n_work = 0;
 	int a_work = 0;
 	int work_done;
+	int credits;
 
 	if (lif->notifyqcq && lif->notifyqcq->flags & IONIC_QCQ_F_INITED)
 		n_work = ionic_cq_service(&lif->notifyqcq->cq, budget,
@@ -1159,7 +1162,15 @@ static int ionic_adminq_napi(struct napi_struct *napi, int budget)
 					  ionic_adminq_service, NULL, NULL);
 	spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
 
-	work_done = max(n_work, a_work);
+	if (lif->hwstamp_rxq)
+		rx_work = ionic_cq_service(&lif->hwstamp_rxq->cq, budget,
+					   ionic_rx_service, NULL, NULL);
+
+	if (lif->hwstamp_txq)
+		tx_work = ionic_cq_service(&lif->hwstamp_txq->cq, budget,
+					   ionic_tx_service, NULL, NULL);
+
+	work_done = max(max(n_work, a_work), max(rx_work, tx_work));
 	if (work_done < budget && napi_complete_done(napi, work_done)) {
 		flags |= IONIC_INTR_CRED_UNMASK;
 		intr->rearm_count++;
@@ -1167,9 +1178,8 @@ static int ionic_adminq_napi(struct napi_struct *napi, int budget)
 
 	if (work_done || flags) {
 		flags |= IONIC_INTR_CRED_RESET_COALESCE;
-		ionic_intr_credits(idev->intr_ctrl,
-				   intr->index,
-				   n_work + a_work, flags);
+		credits = n_work + a_work + rx_work + tx_work;
+		ionic_intr_credits(idev->intr_ctrl, intr->index, credits, flags);
 	}
 
 	return work_done;
@@ -1529,6 +1539,7 @@ static int ionic_set_nic_features(struct ionic_lif *lif,
 	int err;
 
 	ctx.cmd.lif_setattr.features = ionic_netdev_features_to_nic(features);
+
 	err = ionic_adminq_post_wait(lif, &ctx);
 	if (err)
 		return err;
@@ -1951,6 +1962,17 @@ static void ionic_txrx_deinit(struct ionic_lif *lif)
 		}
 	}
 	lif->rx_mode = 0;
+
+	if (lif->hwstamp_txq) {
+		ionic_lif_qcq_deinit(lif, lif->hwstamp_txq);
+		ionic_tx_flush(&lif->hwstamp_txq->cq);
+		ionic_tx_empty(&lif->hwstamp_txq->q);
+	}
+
+	if (lif->hwstamp_rxq) {
+		ionic_lif_qcq_deinit(lif, lif->hwstamp_rxq);
+		ionic_rx_empty(&lif->hwstamp_rxq->q);
+	}
 }
 
 static void ionic_txrx_free(struct ionic_lif *lif)
@@ -2122,8 +2144,26 @@ static int ionic_txrx_enable(struct ionic_lif *lif)
 		}
 	}
 
+	if (lif->hwstamp_rxq) {
+		ionic_rx_fill(&lif->hwstamp_rxq->q);
+		err = ionic_qcq_enable(lif->hwstamp_rxq);
+		if (err)
+			goto err_out_hwstamp_rx;
+	}
+
+	if (lif->hwstamp_txq) {
+		err = ionic_qcq_enable(lif->hwstamp_txq);
+		if (err)
+			goto err_out_hwstamp_tx;
+	}
+
 	return 0;
 
+err_out_hwstamp_tx:
+	if (lif->hwstamp_rxq)
+		derr = ionic_qcq_disable(lif->hwstamp_rxq, (derr != -ETIMEDOUT));
+err_out_hwstamp_rx:
+	i = lif->nxqs;
 err_out:
 	while (i--) {
 		derr = ionic_qcq_disable(lif->txqcqs[i], (derr != -ETIMEDOUT));
@@ -2929,6 +2969,9 @@ static void ionic_lif_handle_fw_up(struct ionic_lif *lif)
 			goto err_txrx_free;
 	}
 
+	/* restore the hardware timestamping queues */
+	ionic_lif_hwstamp_set(lif, NULL);
+
 	clear_bit(IONIC_LIF_F_FW_RESET, lif->state);
 	ionic_link_status_check_request(lif, CAN_SLEEP);
 	netif_device_attach(lif->netdev);
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
index 4859120eec72..3478b0f2495f 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
@@ -11,8 +11,6 @@
 #include "ionic_txrx.h"
 
 
-static bool ionic_tx_service(struct ionic_cq *cq, struct ionic_cq_info *cq_info);
-
 static inline void ionic_txq_post(struct ionic_queue *q, bool ring_dbell,
 				  ionic_desc_cb cb_func, void *cb_arg)
 {
@@ -298,13 +296,33 @@ static void ionic_rx_clean(struct ionic_queue *q,
 		stats->vlan_stripped++;
 	}
 
+	if (unlikely(q->features & IONIC_RXQ_F_HWSTAMP)) {
+		__le64 *cq_desc_hwstamp;
+		u64 hwstamp;
+
+		cq_desc_hwstamp =
+			cq_info->cq_desc +
+			qcq->cq.desc_size -
+			sizeof(struct ionic_rxq_comp) -
+			IONIC_HWSTAMP_CQ_NEGOFFSET;
+
+		hwstamp = le64_to_cpu(*cq_desc_hwstamp);
+
+		if (hwstamp != IONIC_HWSTAMP_INVALID) {
+			skb_hwtstamps(skb)->hwtstamp = ionic_lif_phc_ktime(q->lif, hwstamp);
+			stats->hwstamp_valid++;
+		} else {
+			stats->hwstamp_invalid++;
+		}
+	}
+
 	if (le16_to_cpu(comp->len) <= q->lif->rx_copybreak)
 		napi_gro_receive(&qcq->napi, skb);
 	else
 		napi_gro_frags(&qcq->napi);
 }
 
-static bool ionic_rx_service(struct ionic_cq *cq, struct ionic_cq_info *cq_info)
+bool ionic_rx_service(struct ionic_cq *cq, struct ionic_cq_info *cq_info)
 {
 	struct ionic_queue *q = cq->bound_q;
 	struct ionic_desc_info *desc_info;
@@ -665,9 +683,11 @@ static void ionic_tx_clean(struct ionic_queue *q,
 {
 	struct ionic_buf_info *buf_info = desc_info->bufs;
 	struct ionic_tx_stats *stats = q_to_tx_stats(q);
+	struct ionic_qcq *qcq = q_to_qcq(q);
+	struct sk_buff *skb = cb_arg;
 	struct device *dev = q->dev;
-	u16 queue_index;
 	unsigned int i;
+	u16 qi;
 
 	if (desc_info->nbufs) {
 		dma_unmap_single(dev, (dma_addr_t)buf_info->dma_addr,
@@ -678,24 +698,49 @@ static void ionic_tx_clean(struct ionic_queue *q,
 				       buf_info->len, DMA_TO_DEVICE);
 	}
 
-	if (cb_arg) {
-		struct sk_buff *skb = cb_arg;
+	if (!skb)
+		return;
 
-		queue_index = skb_get_queue_mapping(skb);
-		if (unlikely(__netif_subqueue_stopped(q->lif->netdev,
-						      queue_index))) {
-			netif_wake_subqueue(q->lif->netdev, queue_index);
-			q->wake++;
-		}
+	qi = skb_get_queue_mapping(skb);
+
+	if (unlikely(q->features & IONIC_TXQ_F_HWSTAMP)) {
+		if (cq_info) {
+			struct skb_shared_hwtstamps hwts = {};
+			__le64 *cq_desc_hwstamp;
+			u64 hwstamp;
+
+			cq_desc_hwstamp =
+				cq_info->cq_desc +
+				qcq->cq.desc_size -
+				sizeof(struct ionic_txq_comp) -
+				IONIC_HWSTAMP_CQ_NEGOFFSET;
+
+			hwstamp = le64_to_cpu(*cq_desc_hwstamp);
 
-		desc_info->bytes = skb->len;
-		stats->clean++;
+			if (hwstamp != IONIC_HWSTAMP_INVALID) {
+				hwts.hwtstamp = ionic_lif_phc_ktime(q->lif, hwstamp);
 
-		dev_consume_skb_any(skb);
+				skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
+				skb_tstamp_tx(skb, &hwts);
+
+				stats->hwstamp_valid++;
+			} else {
+				stats->hwstamp_invalid++;
+			}
+		}
+
+	} else if (unlikely(__netif_subqueue_stopped(q->lif->netdev, qi))) {
+		netif_wake_subqueue(q->lif->netdev, qi);
+		q->wake++;
 	}
+
+	desc_info->bytes = skb->len;
+	stats->clean++;
+
+	dev_consume_skb_any(skb);
 }
 
-static bool ionic_tx_service(struct ionic_cq *cq, struct ionic_cq_info *cq_info)
+bool ionic_tx_service(struct ionic_cq *cq, struct ionic_cq_info *cq_info)
 {
 	struct ionic_queue *q = cq->bound_q;
 	struct ionic_desc_info *desc_info;
@@ -726,7 +771,7 @@ static bool ionic_tx_service(struct ionic_cq *cq, struct ionic_cq_info *cq_info)
 		desc_info->cb_arg = NULL;
 	} while (index != le16_to_cpu(comp->comp_index));
 
-	if (pkts && bytes)
+	if (pkts && bytes && !unlikely(q->features & IONIC_TXQ_F_HWSTAMP))
 		netdev_tx_completed_queue(q_to_ndq(q), pkts, bytes);
 
 	return true;
@@ -764,7 +809,7 @@ void ionic_tx_empty(struct ionic_queue *q)
 		desc_info->cb_arg = NULL;
 	}
 
-	if (pkts && bytes)
+	if (pkts && bytes && !unlikely(q->features & IONIC_TXQ_F_HWSTAMP))
 		netdev_tx_completed_queue(q_to_ndq(q), pkts, bytes);
 }
 
@@ -838,7 +883,8 @@ static void ionic_tx_tso_post(struct ionic_queue *q, struct ionic_txq_desc *desc
 
 	if (start) {
 		skb_tx_timestamp(skb);
-		netdev_tx_sent_queue(q_to_ndq(q), skb->len);
+		if (!unlikely(q->features & IONIC_TXQ_F_HWSTAMP))
+			netdev_tx_sent_queue(q_to_ndq(q), skb->len);
 		ionic_txq_post(q, false, ionic_tx_clean, skb);
 	} else {
 		ionic_txq_post(q, done, NULL, NULL);
@@ -1085,7 +1131,8 @@ static int ionic_tx(struct ionic_queue *q, struct sk_buff *skb)
 	stats->pkts++;
 	stats->bytes += skb->len;
 
-	netdev_tx_sent_queue(q_to_ndq(q), skb->len);
+	if (!unlikely(q->features & IONIC_TXQ_F_HWSTAMP))
+		netdev_tx_sent_queue(q_to_ndq(q), skb->len);
 	ionic_txq_post(q, !netdev_xmit_more(), ionic_tx_clean, skb);
 
 	return 0;
@@ -1137,6 +1184,41 @@ static int ionic_maybe_stop_tx(struct ionic_queue *q, int ndescs)
 	return stopped;
 }
 
+static netdev_tx_t ionic_start_hwstamp_xmit(struct sk_buff *skb,
+					    struct net_device *netdev)
+{
+	struct ionic_lif *lif = netdev_priv(netdev);
+	struct ionic_queue *q = &lif->hwstamp_txq->q;
+	int err, ndescs;
+
+	/* Does not stop/start txq, because we post to a separate tx queue
+	 * for timestamping, and if a packet can't be posted immediately to
+	 * the timestamping queue, it is dropped.
+	 */
+
+	ndescs = ionic_tx_descs_needed(q, skb);
+	if (unlikely(ndescs < 0))
+		goto err_out_drop;
+
+	if (unlikely(!ionic_q_has_space(q, ndescs)))
+		goto err_out_drop;
+
+	if (skb_is_gso(skb))
+		err = ionic_tx_tso(q, skb);
+	else
+		err = ionic_tx(q, skb);
+
+	if (err)
+		goto err_out_drop;
+
+	return NETDEV_TX_OK;
+
+err_out_drop:
+	q->drop++;
+	dev_kfree_skb(skb);
+	return NETDEV_TX_OK;
+}
+
 netdev_tx_t ionic_start_xmit(struct sk_buff *skb, struct net_device *netdev)
 {
 	u16 queue_index = skb_get_queue_mapping(skb);
@@ -1150,6 +1232,10 @@ netdev_tx_t ionic_start_xmit(struct sk_buff *skb, struct net_device *netdev)
 		return NETDEV_TX_OK;
 	}
 
+	if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))
+		if (lif->hwstamp_txq)
+			return ionic_start_hwstamp_xmit(skb, netdev);
+
 	if (unlikely(queue_index >= lif->nxqs))
 		queue_index = 0;
 	q = &lif->txqcqs[queue_index]->q;
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.h b/drivers/net/ethernet/pensando/ionic/ionic_txrx.h
index 7667b72232b8..d7cbaad8a6fb 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.h
+++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.h
@@ -14,4 +14,7 @@ int ionic_tx_napi(struct napi_struct *napi, int budget);
 int ionic_txrx_napi(struct napi_struct *napi, int budget);
 netdev_tx_t ionic_start_xmit(struct sk_buff *skb, struct net_device *netdev);
 
+bool ionic_rx_service(struct ionic_cq *cq, struct ionic_cq_info *cq_info);
+bool ionic_tx_service(struct ionic_cq *cq, struct ionic_cq_info *cq_info);
+
 #endif /* _IONIC_TXRX_H_ */
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH net-next 10/12] ionic: add ethtool support for PTP
  2021-04-01 17:55 [PATCH net-next 00/12] ionic: add PTP and hw clock support Shannon Nelson
                   ` (8 preceding siblings ...)
  2021-04-01 17:56 ` [PATCH net-next 09/12] ionic: add and enable tx and rx timestamp handling Shannon Nelson
@ 2021-04-01 17:56 ` Shannon Nelson
  2021-04-01 17:56 ` [PATCH net-next 11/12] ionic: ethtool ptp stats Shannon Nelson
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 35+ messages in thread
From: Shannon Nelson @ 2021-04-01 17:56 UTC (permalink / raw)
  To: netdev, davem, kuba; +Cc: drivers, Shannon Nelson, Allen Hubbe

Add the get_ts_info() callback for ethtool support of
timestamping information.

Signed-off-by: Allen Hubbe <allenbh@pensando.io>
Signed-off-by: Shannon Nelson <snelson@pensando.io>
---
 .../ethernet/pensando/ionic/ionic_ethtool.c   | 93 +++++++++++++++++++
 1 file changed, 93 insertions(+)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
index b1e78b452fad..71db1e2c7d8a 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
@@ -849,6 +849,98 @@ static int ionic_get_module_eeprom(struct net_device *netdev,
 	return 0;
 }
 
+static int ionic_get_ts_info(struct net_device *netdev,
+			     struct ethtool_ts_info *info)
+{
+	struct ionic_lif *lif = netdev_priv(netdev);
+	struct ionic *ionic = lif->ionic;
+	__le64 mask;
+
+	if (!lif->phc || !lif->phc->ptp)
+		return ethtool_op_get_ts_info(netdev, info);
+
+	info->phc_index = ptp_clock_index(lif->phc->ptp);
+
+	info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE |
+				SOF_TIMESTAMPING_RX_SOFTWARE |
+				SOF_TIMESTAMPING_SOFTWARE |
+				SOF_TIMESTAMPING_TX_HARDWARE |
+				SOF_TIMESTAMPING_RX_HARDWARE |
+				SOF_TIMESTAMPING_RAW_HARDWARE;
+
+	/* tx modes */
+
+	info->tx_types = BIT(HWTSTAMP_TX_OFF) |
+			 BIT(HWTSTAMP_TX_ON);
+
+	mask = cpu_to_le64(BIT_ULL(IONIC_TXSTAMP_ONESTEP_SYNC));
+	if (ionic->ident.lif.eth.hwstamp_tx_modes & mask)
+		info->tx_types |= BIT(HWTSTAMP_TX_ONESTEP_SYNC);
+
+	mask = cpu_to_le64(BIT_ULL(IONIC_TXSTAMP_ONESTEP_P2P));
+	if (ionic->ident.lif.eth.hwstamp_tx_modes & mask)
+		info->tx_types |= BIT(HWTSTAMP_TX_ONESTEP_P2P);
+
+	/* rx filters */
+
+	info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
+			   BIT(HWTSTAMP_FILTER_ALL);
+
+	mask = cpu_to_le64(IONIC_PKT_CLS_NTP_ALL);
+	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
+		info->rx_filters |= HWTSTAMP_FILTER_NTP_ALL;
+
+	mask = cpu_to_le64(IONIC_PKT_CLS_PTP1_SYNC);
+	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
+		info->rx_filters |= HWTSTAMP_FILTER_PTP_V1_L4_SYNC;
+
+	mask = cpu_to_le64(IONIC_PKT_CLS_PTP1_DREQ);
+	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
+		info->rx_filters |= HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ;
+
+	mask = cpu_to_le64(IONIC_PKT_CLS_PTP1_ALL);
+	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
+		info->rx_filters |= HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
+
+	mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_L4_SYNC);
+	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
+		info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_L4_SYNC;
+
+	mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_L4_DREQ);
+	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
+		info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ;
+
+	mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_L4_ALL);
+	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
+		info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
+
+	mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_L2_SYNC);
+	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
+		info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_L2_SYNC;
+
+	mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_L2_DREQ);
+	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
+		info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ;
+
+	mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_L2_ALL);
+	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
+		info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
+
+	mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_SYNC);
+	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
+		info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_SYNC;
+
+	mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_DREQ);
+	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
+		info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_DELAY_REQ;
+
+	mask = cpu_to_le64(IONIC_PKT_CLS_PTP2_ALL);
+	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) == mask)
+		info->rx_filters |= HWTSTAMP_FILTER_PTP_V2_EVENT;
+
+	return 0;
+}
+
 static int ionic_nway_reset(struct net_device *netdev)
 {
 	struct ionic_lif *lif = netdev_priv(netdev);
@@ -906,6 +998,7 @@ static const struct ethtool_ops ionic_ethtool_ops = {
 	.set_pauseparam		= ionic_set_pauseparam,
 	.get_fecparam		= ionic_get_fecparam,
 	.set_fecparam		= ionic_set_fecparam,
+	.get_ts_info		= ionic_get_ts_info,
 	.nway_reset		= ionic_nway_reset,
 };
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH net-next 11/12] ionic: ethtool ptp stats
  2021-04-01 17:55 [PATCH net-next 00/12] ionic: add PTP and hw clock support Shannon Nelson
                   ` (9 preceding siblings ...)
  2021-04-01 17:56 ` [PATCH net-next 10/12] ionic: add ethtool support for PTP Shannon Nelson
@ 2021-04-01 17:56 ` Shannon Nelson
  2021-04-01 17:56 ` [PATCH net-next 12/12] ionic: advertise support for hardware timestamps Shannon Nelson
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 35+ messages in thread
From: Shannon Nelson @ 2021-04-01 17:56 UTC (permalink / raw)
  To: netdev, davem, kuba; +Cc: drivers, Shannon Nelson, Allen Hubbe

Add the new hwstamp stats to our ethtool stats output.

Signed-off-by: Allen Hubbe <allenbh@pensando.io>
Signed-off-by: Shannon Nelson <snelson@pensando.io>
---
 .../net/ethernet/pensando/ionic/ionic_stats.c | 38 +++++++++++++++++--
 1 file changed, 34 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_stats.c b/drivers/net/ethernet/pensando/ionic/ionic_stats.c
index ed9cf93d9acd..58a854666c62 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_stats.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_stats.c
@@ -130,6 +130,8 @@ static const struct ionic_stat_desc ionic_tx_stats_desc[] = {
 	IONIC_TX_STAT_DESC(frags),
 	IONIC_TX_STAT_DESC(tso),
 	IONIC_TX_STAT_DESC(tso_bytes),
+	IONIC_TX_STAT_DESC(hwstamp_valid),
+	IONIC_TX_STAT_DESC(hwstamp_invalid),
 	IONIC_TX_STAT_DESC(csum_none),
 	IONIC_TX_STAT_DESC(csum),
 	IONIC_TX_STAT_DESC(vlan_inserted),
@@ -143,6 +145,8 @@ static const struct ionic_stat_desc ionic_rx_stats_desc[] = {
 	IONIC_RX_STAT_DESC(csum_none),
 	IONIC_RX_STAT_DESC(csum_complete),
 	IONIC_RX_STAT_DESC(csum_error),
+	IONIC_RX_STAT_DESC(hwstamp_valid),
+	IONIC_RX_STAT_DESC(hwstamp_invalid),
 	IONIC_RX_STAT_DESC(dropped),
 	IONIC_RX_STAT_DESC(vlan_stripped),
 };
@@ -188,6 +192,8 @@ static void ionic_add_lif_txq_stats(struct ionic_lif *lif, int q_num,
 	stats->tx_tso_bytes += txstats->tso_bytes;
 	stats->tx_csum_none += txstats->csum_none;
 	stats->tx_csum += txstats->csum;
+	stats->tx_hwstamp_valid += txstats->hwstamp_valid;
+	stats->tx_hwstamp_invalid += txstats->hwstamp_invalid;
 }
 
 static void ionic_add_lif_rxq_stats(struct ionic_lif *lif, int q_num,
@@ -200,6 +206,8 @@ static void ionic_add_lif_rxq_stats(struct ionic_lif *lif, int q_num,
 	stats->rx_csum_none += rxstats->csum_none;
 	stats->rx_csum_complete += rxstats->csum_complete;
 	stats->rx_csum_error += rxstats->csum_error;
+	stats->rx_hwstamp_valid += rxstats->hwstamp_valid;
+	stats->rx_hwstamp_invalid += rxstats->hwstamp_invalid;
 }
 
 static void ionic_get_lif_stats(struct ionic_lif *lif,
@@ -215,6 +223,12 @@ static void ionic_get_lif_stats(struct ionic_lif *lif,
 		ionic_add_lif_rxq_stats(lif, q_num, stats);
 	}
 
+	if (lif->hwstamp_txq)
+		ionic_add_lif_txq_stats(lif, lif->hwstamp_txq->q.index, stats);
+
+	if (lif->hwstamp_rxq)
+		ionic_add_lif_rxq_stats(lif, lif->hwstamp_rxq->q.index, stats);
+
 	ionic_get_stats64(lif->netdev, &ns);
 	stats->hw_tx_dropped = ns.tx_dropped;
 	stats->hw_rx_dropped = ns.rx_dropped;
@@ -227,14 +241,18 @@ static u64 ionic_sw_stats_get_count(struct ionic_lif *lif)
 {
 	u64 total = 0, tx_queues = MAX_Q(lif), rx_queues = MAX_Q(lif);
 
-	/* lif stats */
+	if (lif->hwstamp_txq)
+		tx_queues += 1;
+
+	if (lif->hwstamp_rxq)
+		rx_queues += 1;
+
 	total += IONIC_NUM_LIF_STATS;
+	total += IONIC_NUM_PORT_STATS;
+
 	total += tx_queues * IONIC_NUM_TX_STATS;
 	total += rx_queues * IONIC_NUM_RX_STATS;
 
-	/* port stats */
-	total += IONIC_NUM_PORT_STATS;
-
 	if (test_bit(IONIC_LIF_F_UP, lif->state) &&
 	    test_bit(IONIC_LIF_F_SW_DEBUG_STATS, lif->state)) {
 		/* tx debug stats */
@@ -318,8 +336,14 @@ static void ionic_sw_stats_get_strings(struct ionic_lif *lif, u8 **buf)
 	for (q_num = 0; q_num < MAX_Q(lif); q_num++)
 		ionic_sw_stats_get_tx_strings(lif, buf, q_num);
 
+	if (lif->hwstamp_txq)
+		ionic_sw_stats_get_tx_strings(lif, buf, lif->hwstamp_txq->q.index);
+
 	for (q_num = 0; q_num < MAX_Q(lif); q_num++)
 		ionic_sw_stats_get_rx_strings(lif, buf, q_num);
+
+	if (lif->hwstamp_rxq)
+		ionic_sw_stats_get_rx_strings(lif, buf, lif->hwstamp_rxq->q.index);
 }
 
 static void ionic_sw_stats_get_txq_values(struct ionic_lif *lif, u64 **buf,
@@ -434,8 +458,14 @@ static void ionic_sw_stats_get_values(struct ionic_lif *lif, u64 **buf)
 	for (q_num = 0; q_num < MAX_Q(lif); q_num++)
 		ionic_sw_stats_get_txq_values(lif, buf, q_num);
 
+	if (lif->hwstamp_txq)
+		ionic_sw_stats_get_txq_values(lif, buf, lif->hwstamp_txq->q.index);
+
 	for (q_num = 0; q_num < MAX_Q(lif); q_num++)
 		ionic_sw_stats_get_rxq_values(lif, buf, q_num);
+
+	if (lif->hwstamp_rxq)
+		ionic_sw_stats_get_rxq_values(lif, buf, lif->hwstamp_rxq->q.index);
 }
 
 const struct ionic_stats_group_intf ionic_stats_groups[] = {
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH net-next 12/12] ionic: advertise support for hardware timestamps
  2021-04-01 17:55 [PATCH net-next 00/12] ionic: add PTP and hw clock support Shannon Nelson
                   ` (10 preceding siblings ...)
  2021-04-01 17:56 ` [PATCH net-next 11/12] ionic: ethtool ptp stats Shannon Nelson
@ 2021-04-01 17:56 ` Shannon Nelson
  2021-04-04 23:43   ` Richard Cochran
  2021-04-01 21:02 ` [PATCH net-next 00/12] ionic: add PTP and hw clock support Andrew Lunn
  2021-04-02 21:30 ` patchwork-bot+netdevbpf
  13 siblings, 1 reply; 35+ messages in thread
From: Shannon Nelson @ 2021-04-01 17:56 UTC (permalink / raw)
  To: netdev, davem, kuba; +Cc: drivers, Shannon Nelson, Allen Hubbe

Let the network stack know we've got support for timestamping
the packets.

Signed-off-by: Allen Hubbe <allenbh@pensando.io>
Signed-off-by: Shannon Nelson <snelson@pensando.io>
---
 .../net/ethernet/pensando/ionic/ionic_lif.c   | 25 +++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
index e14c93fbbd68..ee56fed12e07 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -1540,6 +1540,9 @@ static int ionic_set_nic_features(struct ionic_lif *lif,
 
 	ctx.cmd.lif_setattr.features = ionic_netdev_features_to_nic(features);
 
+	if (lif->phc)
+		ctx.cmd.lif_setattr.features |= cpu_to_le64(IONIC_ETH_HW_TIMESTAMP);
+
 	err = ionic_adminq_post_wait(lif, &ctx);
 	if (err)
 		return err;
@@ -1587,6 +1590,8 @@ static int ionic_set_nic_features(struct ionic_lif *lif,
 		dev_dbg(dev, "feature ETH_HW_TSO_UDP\n");
 	if (lif->hw_features & IONIC_ETH_HW_TSO_UDP_CSUM)
 		dev_dbg(dev, "feature ETH_HW_TSO_UDP_CSUM\n");
+	if (lif->hw_features & IONIC_ETH_HW_TIMESTAMP)
+		dev_dbg(dev, "feature ETH_HW_TIMESTAMP\n");
 
 	return 0;
 }
@@ -2260,6 +2265,20 @@ static int ionic_stop(struct net_device *netdev)
 	return 0;
 }
 
+static int ionic_do_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+	struct ionic_lif *lif = netdev_priv(netdev);
+
+	switch (cmd) {
+	case SIOCSHWTSTAMP:
+		return ionic_lif_hwstamp_set(lif, ifr);
+	case SIOCGHWTSTAMP:
+		return ionic_lif_hwstamp_get(lif, ifr);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
 static int ionic_get_vf_config(struct net_device *netdev,
 			       int vf, struct ifla_vf_info *ivf)
 {
@@ -2508,6 +2527,7 @@ static int ionic_set_vf_link_state(struct net_device *netdev, int vf, int set)
 static const struct net_device_ops ionic_netdev_ops = {
 	.ndo_open               = ionic_open,
 	.ndo_stop               = ionic_stop,
+	.ndo_do_ioctl		= ionic_do_ioctl,
 	.ndo_start_xmit		= ionic_start_xmit,
 	.ndo_get_stats64	= ionic_get_stats64,
 	.ndo_set_rx_mode	= ionic_ndo_set_rx_mode,
@@ -3331,6 +3351,8 @@ int ionic_lif_register(struct ionic_lif *lif)
 {
 	int err;
 
+	ionic_lif_register_phc(lif);
+
 	INIT_WORK(&lif->ionic->nb_work, ionic_lif_notify_work);
 
 	lif->ionic->nb.notifier_call = ionic_lif_notify;
@@ -3343,6 +3365,7 @@ int ionic_lif_register(struct ionic_lif *lif)
 	err = register_netdev(lif->netdev);
 	if (err) {
 		dev_err(lif->ionic->dev, "Cannot register net device, aborting\n");
+		ionic_lif_unregister_phc(lif);
 		return err;
 	}
 
@@ -3364,6 +3387,8 @@ void ionic_lif_unregister(struct ionic_lif *lif)
 	if (lif->netdev->reg_state == NETREG_REGISTERED)
 		unregister_netdev(lif->netdev);
 
+	ionic_lif_unregister_phc(lif);
+
 	lif->registered = false;
 }
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next 00/12] ionic: add PTP and hw clock support
  2021-04-01 17:55 [PATCH net-next 00/12] ionic: add PTP and hw clock support Shannon Nelson
                   ` (11 preceding siblings ...)
  2021-04-01 17:56 ` [PATCH net-next 12/12] ionic: advertise support for hardware timestamps Shannon Nelson
@ 2021-04-01 21:02 ` Andrew Lunn
  2021-04-01 21:11   ` Shannon Nelson
  2021-04-02 21:30 ` patchwork-bot+netdevbpf
  13 siblings, 1 reply; 35+ messages in thread
From: Andrew Lunn @ 2021-04-01 21:02 UTC (permalink / raw)
  To: Shannon Nelson; +Cc: netdev, davem, kuba, drivers, Richard Cochran

On Thu, Apr 01, 2021 at 10:55:58AM -0700, Shannon Nelson wrote:
> This patchset adds support for accessing the DSC hardware clock and
> for offloading PTP timestamping.

Hi Shannon

Please always Cc: the PTP maintainer for PTP patches.
Richard Cochran <richardcochran@gmail.com>

	Andrew

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next 00/12] ionic: add PTP and hw clock support
  2021-04-01 21:02 ` [PATCH net-next 00/12] ionic: add PTP and hw clock support Andrew Lunn
@ 2021-04-01 21:11   ` Shannon Nelson
  0 siblings, 0 replies; 35+ messages in thread
From: Shannon Nelson @ 2021-04-01 21:11 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: netdev, davem, kuba, drivers, Richard Cochran

On 4/1/21 2:02 PM, Andrew Lunn wrote:
> On Thu, Apr 01, 2021 at 10:55:58AM -0700, Shannon Nelson wrote:
>> This patchset adds support for accessing the DSC hardware clock and
>> for offloading PTP timestamping.
> Hi Shannon
>
> Please always Cc: the PTP maintainer for PTP patches.
> Richard Cochran <richardcochran@gmail.com>
>
> 	Andrew

Thanks for the heads-up, Andrew, I will do so on any followups.
sln


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next 00/12] ionic: add PTP and hw clock support
  2021-04-01 17:55 [PATCH net-next 00/12] ionic: add PTP and hw clock support Shannon Nelson
                   ` (12 preceding siblings ...)
  2021-04-01 21:02 ` [PATCH net-next 00/12] ionic: add PTP and hw clock support Andrew Lunn
@ 2021-04-02 21:30 ` patchwork-bot+netdevbpf
  13 siblings, 0 replies; 35+ messages in thread
From: patchwork-bot+netdevbpf @ 2021-04-02 21:30 UTC (permalink / raw)
  To: Shannon Nelson; +Cc: netdev, davem, kuba, drivers

Hello:

This series was applied to netdev/net-next.git (refs/heads/master):

On Thu,  1 Apr 2021 10:55:58 -0700 you wrote:
> This patchset adds support for accessing the DSC hardware clock and
> for offloading PTP timestamping.
> 
> Tx packet timestamping happens through a separate Tx queue set up with
> expanded completion descriptors that can report the timestamp.
> 
> Rx timestamping can happen either on all queues, or on a separate
> timestamping queue when specific filtering is requested.  Again, the
> timestamps are reported with the expanded completion descriptors.
> 
> [...]

Here is the summary with links:
  - [net-next,01/12] ionic: add new queue features to interface
    https://git.kernel.org/netdev/net-next/c/57a3a98d7c0a
  - [net-next,02/12] ionic: add handling of larger descriptors
    https://git.kernel.org/netdev/net-next/c/0ec9f6669a7d
  - [net-next,03/12] ionic: add hw timestamp structs to interface
    https://git.kernel.org/netdev/net-next/c/3da258439e89
  - [net-next,04/12] ionic: split adminq post and wait calls
    https://git.kernel.org/netdev/net-next/c/4f1704faa013
  - [net-next,05/12] ionic: add hw timestamp support files
    https://git.kernel.org/netdev/net-next/c/fee6efce565d
  - [net-next,06/12] ionic: link in the new hw timestamp code
    https://git.kernel.org/netdev/net-next/c/61db421da31b
  - [net-next,07/12] ionic: add rx filtering for hw timestamp steering
    https://git.kernel.org/netdev/net-next/c/ab470bbe7aba
  - [net-next,08/12] ionic: set up hw timestamp queues
    https://git.kernel.org/netdev/net-next/c/f0790bcd3606
  - [net-next,09/12] ionic: add and enable tx and rx timestamp handling
    https://git.kernel.org/netdev/net-next/c/a8771bfe0554
  - [net-next,10/12] ionic: add ethtool support for PTP
    https://git.kernel.org/netdev/net-next/c/f8ba81da73fc
  - [net-next,11/12] ionic: ethtool ptp stats
    https://git.kernel.org/netdev/net-next/c/196f56c07f91
  - [net-next,12/12] ionic: advertise support for hardware timestamps
    https://git.kernel.org/netdev/net-next/c/afeefec67736

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next 02/12] ionic: add handling of larger descriptors
  2021-04-01 17:56 ` [PATCH net-next 02/12] ionic: add handling of larger descriptors Shannon Nelson
@ 2021-04-04 22:50   ` Richard Cochran
  2021-04-05 16:17     ` Shannon Nelson
  0 siblings, 1 reply; 35+ messages in thread
From: Richard Cochran @ 2021-04-04 22:50 UTC (permalink / raw)
  To: Shannon Nelson; +Cc: netdev, davem, kuba, drivers, Allen Hubbe

On Thu, Apr 01, 2021 at 10:56:00AM -0700, Shannon Nelson wrote:
> @@ -1722,11 +1722,15 @@ static void ionic_txrx_free(struct ionic_lif *lif)
>  
>  static int ionic_txrx_alloc(struct ionic_lif *lif)
>  {
> -	unsigned int sg_desc_sz;
> +	unsigned int num_desc, desc_sz, comp_sz, sg_desc_sz;
>  	unsigned int flags;
>  	unsigned int i;

Coding Style nit: List of ints wants alphabetically order,
List can also fir 'flags' and 'i' with the others.

> @@ -2246,9 +2258,9 @@ static void ionic_swap_queues(struct ionic_qcq *a, struct ionic_qcq *b)
>  int ionic_reconfigure_queues(struct ionic_lif *lif,
>  			     struct ionic_queue_params *qparam)
>  {
> +	unsigned int num_desc, desc_sz, comp_sz, sg_desc_sz;
>  	struct ionic_qcq **tx_qcqs = NULL;
>  	struct ionic_qcq **rx_qcqs = NULL;
> -	unsigned int sg_desc_sz;
>  	unsigned int flags;

Ditto.

Thanks,
Richard

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next 05/12] ionic: add hw timestamp support files
  2021-04-01 17:56 ` [PATCH net-next 05/12] ionic: add hw timestamp support files Shannon Nelson
@ 2021-04-04 23:05   ` Richard Cochran
  2021-04-05  4:53     ` Leon Romanovsky
  2021-04-05 16:16     ` Shannon Nelson
  2021-04-04 23:21   ` Richard Cochran
  1 sibling, 2 replies; 35+ messages in thread
From: Richard Cochran @ 2021-04-04 23:05 UTC (permalink / raw)
  To: Shannon Nelson; +Cc: netdev, davem, kuba, drivers, Allen Hubbe

On Thu, Apr 01, 2021 at 10:56:03AM -0700, Shannon Nelson wrote:
> @@ -0,0 +1,589 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* Copyright(c) 2017 - 2021 Pensando Systems, Inc */
> +
> +#include <linux/netdevice.h>
> +#include <linux/etherdevice.h>
> +
> +#include "ionic.h"
> +#include "ionic_bus.h"
> +#include "ionic_lif.h"
> +#include "ionic_ethtool.h"
> +
> +static int ionic_hwstamp_tx_mode(int config_tx_type)
> +{
> +	switch (config_tx_type) {
> +	case HWTSTAMP_TX_OFF:
> +		return IONIC_TXSTAMP_OFF;
> +	case HWTSTAMP_TX_ON:
> +		return IONIC_TXSTAMP_ON;
> +	case HWTSTAMP_TX_ONESTEP_SYNC:
> +		return IONIC_TXSTAMP_ONESTEP_SYNC;
> +#ifdef HAVE_HWSTAMP_TX_ONESTEP_P2P
> +	case HWTSTAMP_TX_ONESTEP_P2P:
> +		return IONIC_TXSTAMP_ONESTEP_P2P;
> +#endif

This ifdef is not needed.  (I guess you have to support older kernel
versions, but my understanding of the policy is that new code
shouldn't carry such stuff).

> +	default:
> +		return -ERANGE;
> +	}
> +}


> +int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct ifreq *ifr)
> +{
> +	struct ionic *ionic = lif->ionic;
> +	struct hwtstamp_config config;
> +	int tx_mode = 0;
> +	u64 rx_filt = 0;
> +	int err, err2;
> +	bool rx_all;
> +	__le64 mask;
> +
> +	if (!lif->phc || !lif->phc->ptp)
> +		return -EOPNOTSUPP;
> +
> +	if (ifr) {
> +		if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
> +			return -EFAULT;
> +	} else {
> +		/* if called with ifr == NULL, behave as if called with the
> +		 * current ts_config from the initial cleared state.
> +		 */

This check is unneeded, because the ioctl layer never passes NULL here.

> +		memcpy(&config, &lif->phc->ts_config, sizeof(config));
> +		memset(&lif->phc->ts_config, 0, sizeof(config));
> +	}

Thanks,
Richard

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next 05/12] ionic: add hw timestamp support files
  2021-04-01 17:56 ` [PATCH net-next 05/12] ionic: add hw timestamp support files Shannon Nelson
  2021-04-04 23:05   ` Richard Cochran
@ 2021-04-04 23:21   ` Richard Cochran
  2021-04-05 16:19     ` Shannon Nelson
  1 sibling, 1 reply; 35+ messages in thread
From: Richard Cochran @ 2021-04-04 23:21 UTC (permalink / raw)
  To: Shannon Nelson; +Cc: netdev, davem, kuba, drivers, Allen Hubbe

On Thu, Apr 01, 2021 at 10:56:03AM -0700, Shannon Nelson wrote:

> +int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct ifreq *ifr)
> +{
> +	struct ionic *ionic = lif->ionic;
> +	struct hwtstamp_config config;
> +	int tx_mode = 0;
> +	u64 rx_filt = 0;
> +	int err, err2;
> +	bool rx_all;
> +	__le64 mask;
> +
> +	if (!lif->phc || !lif->phc->ptp)
> +		return -EOPNOTSUPP;
> +
> +	if (ifr) {
> +		if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
> +			return -EFAULT;
> +	} else {
> +		/* if called with ifr == NULL, behave as if called with the
> +		 * current ts_config from the initial cleared state.
> +		 */
> +		memcpy(&config, &lif->phc->ts_config, sizeof(config));
> +		memset(&lif->phc->ts_config, 0, sizeof(config));
> +	}
> +
> +	tx_mode = ionic_hwstamp_tx_mode(config.tx_type);
> +	if (tx_mode < 0)
> +		return tx_mode;
> +
> +	mask = cpu_to_le64(BIT_ULL(tx_mode));
> +	if ((ionic->ident.lif.eth.hwstamp_tx_modes & mask) != mask)
> +		return -ERANGE;
> +
> +	rx_filt = ionic_hwstamp_rx_filt(config.rx_filter);
> +	rx_all = config.rx_filter != HWTSTAMP_FILTER_NONE && !rx_filt;
> +
> +	mask = cpu_to_le64(rx_filt);
> +	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) != mask) {
> +		rx_filt = 0;
> +		rx_all = true;
> +		config.rx_filter = HWTSTAMP_FILTER_ALL;
> +	}
> +
> +	dev_dbg(ionic->dev, "config_rx_filter %d rx_filt %#llx rx_all %d\n",
> +		config.rx_filter, rx_filt, rx_all);
> +
> +	mutex_lock(&lif->phc->config_lock);
> +
> +	if (tx_mode) {
> +		err = ionic_lif_create_hwstamp_txq(lif);

This function NDE yet.  It first appears in Patch #6.  Please make
sure each patch compiles.  That way, bisection always works.

Thanks,
Richard

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next 09/12] ionic: add and enable tx and rx timestamp handling
  2021-04-01 17:56 ` [PATCH net-next 09/12] ionic: add and enable tx and rx timestamp handling Shannon Nelson
@ 2021-04-04 23:41   ` Richard Cochran
  2021-04-05 16:28     ` Shannon Nelson
  0 siblings, 1 reply; 35+ messages in thread
From: Richard Cochran @ 2021-04-04 23:41 UTC (permalink / raw)
  To: Shannon Nelson; +Cc: netdev, davem, kuba, drivers, Allen Hubbe

On Thu, Apr 01, 2021 at 10:56:07AM -0700, Shannon Nelson wrote:

> @@ -1150,6 +1232,10 @@ netdev_tx_t ionic_start_xmit(struct sk_buff *skb, struct net_device *netdev)
>  		return NETDEV_TX_OK;
>  	}
>  
> +	if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))
> +		if (lif->hwstamp_txq)
> +			return ionic_start_hwstamp_xmit(skb, netdev);

The check for SKBTX_HW_TSTAMP and hwstamp_txq is good, but I didn't
see hwstamp_txq getting cleared in ionic_lif_hwstamp_set() when the
user turns off Tx time stamping via the SIOCSHWTSTAMP ioctl.

In addition, the code should set

	skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;

once the above tests pass.

Thanks,
Richard



^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next 12/12] ionic: advertise support for hardware timestamps
  2021-04-01 17:56 ` [PATCH net-next 12/12] ionic: advertise support for hardware timestamps Shannon Nelson
@ 2021-04-04 23:43   ` Richard Cochran
  2021-04-05 16:33     ` Shannon Nelson
  0 siblings, 1 reply; 35+ messages in thread
From: Richard Cochran @ 2021-04-04 23:43 UTC (permalink / raw)
  To: Shannon Nelson; +Cc: netdev, davem, kuba, drivers, Allen Hubbe

On Thu, Apr 01, 2021 at 10:56:10AM -0700, Shannon Nelson wrote:
> Let the network stack know we've got support for timestamping
> the packets.

Actually, you already advertised the support to user space in Patch 10,
so this present patch should go before that one (or together).

Thanks,
Richard

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next 05/12] ionic: add hw timestamp support files
  2021-04-04 23:05   ` Richard Cochran
@ 2021-04-05  4:53     ` Leon Romanovsky
  2021-04-05 16:16     ` Shannon Nelson
  1 sibling, 0 replies; 35+ messages in thread
From: Leon Romanovsky @ 2021-04-05  4:53 UTC (permalink / raw)
  To: Richard Cochran; +Cc: Shannon Nelson, netdev, davem, kuba, drivers, Allen Hubbe

On Sun, Apr 04, 2021 at 04:05:26PM -0700, Richard Cochran wrote:
> On Thu, Apr 01, 2021 at 10:56:03AM -0700, Shannon Nelson wrote:
> > @@ -0,0 +1,589 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/* Copyright(c) 2017 - 2021 Pensando Systems, Inc */
> > +
> > +#include <linux/netdevice.h>
> > +#include <linux/etherdevice.h>
> > +
> > +#include "ionic.h"
> > +#include "ionic_bus.h"
> > +#include "ionic_lif.h"
> > +#include "ionic_ethtool.h"
> > +
> > +static int ionic_hwstamp_tx_mode(int config_tx_type)
> > +{
> > +	switch (config_tx_type) {
> > +	case HWTSTAMP_TX_OFF:
> > +		return IONIC_TXSTAMP_OFF;
> > +	case HWTSTAMP_TX_ON:
> > +		return IONIC_TXSTAMP_ON;
> > +	case HWTSTAMP_TX_ONESTEP_SYNC:
> > +		return IONIC_TXSTAMP_ONESTEP_SYNC;
> > +#ifdef HAVE_HWSTAMP_TX_ONESTEP_P2P
> > +	case HWTSTAMP_TX_ONESTEP_P2P:
> > +		return IONIC_TXSTAMP_ONESTEP_P2P;
> > +#endif
> 
> This ifdef is not needed.  (I guess you have to support older kernel
> versions, but my understanding of the policy is that new code
> shouldn't carry such stuff).

The HAVE_HWSTAMP_TX_ONESTEP_P2P don't exist in the kernel and the ifdef should
be deleted.

Thanks

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next 05/12] ionic: add hw timestamp support files
  2021-04-04 23:05   ` Richard Cochran
  2021-04-05  4:53     ` Leon Romanovsky
@ 2021-04-05 16:16     ` Shannon Nelson
  2021-04-05 18:17       ` Richard Cochran
  1 sibling, 1 reply; 35+ messages in thread
From: Shannon Nelson @ 2021-04-05 16:16 UTC (permalink / raw)
  To: Richard Cochran; +Cc: netdev, davem, kuba, drivers, Allen Hubbe

On 4/4/21 4:05 PM, Richard Cochran wrote:
> On Thu, Apr 01, 2021 at 10:56:03AM -0700, Shannon Nelson wrote:
>> @@ -0,0 +1,589 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/* Copyright(c) 2017 - 2021 Pensando Systems, Inc */
>> +
>> +#include <linux/netdevice.h>
>> +#include <linux/etherdevice.h>
>> +
>> +#include "ionic.h"
>> +#include "ionic_bus.h"
>> +#include "ionic_lif.h"
>> +#include "ionic_ethtool.h"
>> +
>> +static int ionic_hwstamp_tx_mode(int config_tx_type)
>> +{
>> +	switch (config_tx_type) {
>> +	case HWTSTAMP_TX_OFF:
>> +		return IONIC_TXSTAMP_OFF;
>> +	case HWTSTAMP_TX_ON:
>> +		return IONIC_TXSTAMP_ON;
>> +	case HWTSTAMP_TX_ONESTEP_SYNC:
>> +		return IONIC_TXSTAMP_ONESTEP_SYNC;
>> +#ifdef HAVE_HWSTAMP_TX_ONESTEP_P2P
>> +	case HWTSTAMP_TX_ONESTEP_P2P:
>> +		return IONIC_TXSTAMP_ONESTEP_P2P;
>> +#endif
> This ifdef is not needed.  (I guess you have to support older kernel
> versions, but my understanding of the policy is that new code
> shouldn't carry such stuff).

Yep, good catch - that's a carry over from our out-of-tree driver. I'll 
follow up with a patch to remove that bit of cruft.

>
>> +	default:
>> +		return -ERANGE;
>> +	}
>> +}
>
>> +int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct ifreq *ifr)
>> +{
>> +	struct ionic *ionic = lif->ionic;
>> +	struct hwtstamp_config config;
>> +	int tx_mode = 0;
>> +	u64 rx_filt = 0;
>> +	int err, err2;
>> +	bool rx_all;
>> +	__le64 mask;
>> +
>> +	if (!lif->phc || !lif->phc->ptp)
>> +		return -EOPNOTSUPP;
>> +
>> +	if (ifr) {
>> +		if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
>> +			return -EFAULT;
>> +	} else {
>> +		/* if called with ifr == NULL, behave as if called with the
>> +		 * current ts_config from the initial cleared state.
>> +		 */
> This check is unneeded, because the ioctl layer never passes NULL here.

Yes, the ioctl layer never calls this with NULL, but we call it from 
within the driver when we spin operations back up after a FW reset.

Thanks,
sln

>
>> +		memcpy(&config, &lif->phc->ts_config, sizeof(config));
>> +		memset(&lif->phc->ts_config, 0, sizeof(config));
>> +	}
> Thanks,
> Richard


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next 02/12] ionic: add handling of larger descriptors
  2021-04-04 22:50   ` Richard Cochran
@ 2021-04-05 16:17     ` Shannon Nelson
  0 siblings, 0 replies; 35+ messages in thread
From: Shannon Nelson @ 2021-04-05 16:17 UTC (permalink / raw)
  To: Richard Cochran; +Cc: netdev, davem, kuba, drivers, Allen Hubbe

On 4/4/21 3:50 PM, Richard Cochran wrote:
> On Thu, Apr 01, 2021 at 10:56:00AM -0700, Shannon Nelson wrote:
>> @@ -1722,11 +1722,15 @@ static void ionic_txrx_free(struct ionic_lif *lif)
>>   
>>   static int ionic_txrx_alloc(struct ionic_lif *lif)
>>   {
>> -	unsigned int sg_desc_sz;
>> +	unsigned int num_desc, desc_sz, comp_sz, sg_desc_sz;
>>   	unsigned int flags;
>>   	unsigned int i;
> Coding Style nit: List of ints wants alphabetically order,
> List can also fir 'flags' and 'i' with the others.
>
>> @@ -2246,9 +2258,9 @@ static void ionic_swap_queues(struct ionic_qcq *a, struct ionic_qcq *b)
>>   int ionic_reconfigure_queues(struct ionic_lif *lif,
>>   			     struct ionic_queue_params *qparam)
>>   {
>> +	unsigned int num_desc, desc_sz, comp_sz, sg_desc_sz;
>>   	struct ionic_qcq **tx_qcqs = NULL;
>>   	struct ionic_qcq **rx_qcqs = NULL;
>> -	unsigned int sg_desc_sz;
>>   	unsigned int flags;
> Ditto.
>
> Thanks,
> Richard

I can tweak this is a followup patch.  Thanks for your review time.
sln


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next 05/12] ionic: add hw timestamp support files
  2021-04-04 23:21   ` Richard Cochran
@ 2021-04-05 16:19     ` Shannon Nelson
  0 siblings, 0 replies; 35+ messages in thread
From: Shannon Nelson @ 2021-04-05 16:19 UTC (permalink / raw)
  To: Richard Cochran; +Cc: netdev, davem, kuba, drivers, Allen Hubbe

On 4/4/21 4:21 PM, Richard Cochran wrote:
> On Thu, Apr 01, 2021 at 10:56:03AM -0700, Shannon Nelson wrote:
>
>> +int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct ifreq *ifr)
>> +{
>> +	struct ionic *ionic = lif->ionic;
>> +	struct hwtstamp_config config;
>> +	int tx_mode = 0;
>> +	u64 rx_filt = 0;
>> +	int err, err2;
>> +	bool rx_all;
>> +	__le64 mask;
>> +
>> +	if (!lif->phc || !lif->phc->ptp)
>> +		return -EOPNOTSUPP;
>> +
>> +	if (ifr) {
>> +		if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
>> +			return -EFAULT;
>> +	} else {
>> +		/* if called with ifr == NULL, behave as if called with the
>> +		 * current ts_config from the initial cleared state.
>> +		 */
>> +		memcpy(&config, &lif->phc->ts_config, sizeof(config));
>> +		memset(&lif->phc->ts_config, 0, sizeof(config));
>> +	}
>> +
>> +	tx_mode = ionic_hwstamp_tx_mode(config.tx_type);
>> +	if (tx_mode < 0)
>> +		return tx_mode;
>> +
>> +	mask = cpu_to_le64(BIT_ULL(tx_mode));
>> +	if ((ionic->ident.lif.eth.hwstamp_tx_modes & mask) != mask)
>> +		return -ERANGE;
>> +
>> +	rx_filt = ionic_hwstamp_rx_filt(config.rx_filter);
>> +	rx_all = config.rx_filter != HWTSTAMP_FILTER_NONE && !rx_filt;
>> +
>> +	mask = cpu_to_le64(rx_filt);
>> +	if ((ionic->ident.lif.eth.hwstamp_rx_filters & mask) != mask) {
>> +		rx_filt = 0;
>> +		rx_all = true;
>> +		config.rx_filter = HWTSTAMP_FILTER_ALL;
>> +	}
>> +
>> +	dev_dbg(ionic->dev, "config_rx_filter %d rx_filt %#llx rx_all %d\n",
>> +		config.rx_filter, rx_filt, rx_all);
>> +
>> +	mutex_lock(&lif->phc->config_lock);
>> +
>> +	if (tx_mode) {
>> +		err = ionic_lif_create_hwstamp_txq(lif);
> This function NDE yet.  It first appears in Patch #6.  Please make
> sure each patch compiles.  That way, bisection always works.
>
> Thanks,
> Richard

This patch simply gets the file into the repo, it isn't yet mentioned in 
the Makefile so there is no broken compile.  This was just as a way of 
making patch 6 a little smaller.

sln


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next 09/12] ionic: add and enable tx and rx timestamp handling
  2021-04-04 23:41   ` Richard Cochran
@ 2021-04-05 16:28     ` Shannon Nelson
  2021-04-05 18:20       ` Richard Cochran
  0 siblings, 1 reply; 35+ messages in thread
From: Shannon Nelson @ 2021-04-05 16:28 UTC (permalink / raw)
  To: Richard Cochran; +Cc: netdev, davem, kuba, drivers, Allen Hubbe

On 4/4/21 4:41 PM, Richard Cochran wrote:
> On Thu, Apr 01, 2021 at 10:56:07AM -0700, Shannon Nelson wrote:
>
>> @@ -1150,6 +1232,10 @@ netdev_tx_t ionic_start_xmit(struct sk_buff *skb, struct net_device *netdev)
>>   		return NETDEV_TX_OK;
>>   	}
>>   
>> +	if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))
>> +		if (lif->hwstamp_txq)
>> +			return ionic_start_hwstamp_xmit(skb, netdev);
> The check for SKBTX_HW_TSTAMP and hwstamp_txq is good, but I didn't
> see hwstamp_txq getting cleared in ionic_lif_hwstamp_set() when the
> user turns off Tx time stamping via the SIOCSHWTSTAMP ioctl.

Once the hwstamp queues are up, we leave them there for future use until 
the interface is stopped, assuming that the stack isn't going to send us 
SKBTX_HW_STAMP after it has disabled the offload.

>
> In addition, the code should set
>
> 	skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
>
> once the above tests pass.

I can add that in a followup patch.

Thanks,
sln

>
> Thanks,
> Richard
>
>


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next 12/12] ionic: advertise support for hardware timestamps
  2021-04-04 23:43   ` Richard Cochran
@ 2021-04-05 16:33     ` Shannon Nelson
  2021-04-05 18:23       ` Richard Cochran
  0 siblings, 1 reply; 35+ messages in thread
From: Shannon Nelson @ 2021-04-05 16:33 UTC (permalink / raw)
  To: Richard Cochran; +Cc: netdev, davem, kuba, drivers, Allen Hubbe

On 4/4/21 4:43 PM, Richard Cochran wrote:
> On Thu, Apr 01, 2021 at 10:56:10AM -0700, Shannon Nelson wrote:
>> Let the network stack know we've got support for timestamping
>> the packets.
> Actually, you already advertised the support to user space in Patch 10,
> so this present patch should go before that one (or together).
>
> Thanks,
> Richard

Yes, I supposed they could have gone together.  However, I believe that 
in a bisection this will only slightly confuse the user space tools, but 
won't cause any kernel pain.

sln


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next 05/12] ionic: add hw timestamp support files
  2021-04-05 16:16     ` Shannon Nelson
@ 2021-04-05 18:17       ` Richard Cochran
  2021-04-06 23:18         ` Shannon Nelson
  0 siblings, 1 reply; 35+ messages in thread
From: Richard Cochran @ 2021-04-05 18:17 UTC (permalink / raw)
  To: Shannon Nelson; +Cc: netdev, davem, kuba, drivers, Allen Hubbe

On Mon, Apr 05, 2021 at 09:16:39AM -0700, Shannon Nelson wrote:
> On 4/4/21 4:05 PM, Richard Cochran wrote:
> > This check is unneeded, because the ioctl layer never passes NULL here.
> 
> Yes, the ioctl layer never calls this with NULL, but we call it from within
> the driver when we spin operations back up after a FW reset.

So why not avoid the special case and pass a proper request?

Thanks,
Richard

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next 09/12] ionic: add and enable tx and rx timestamp handling
  2021-04-05 16:28     ` Shannon Nelson
@ 2021-04-05 18:20       ` Richard Cochran
  2021-04-06 23:06         ` Shannon Nelson
  0 siblings, 1 reply; 35+ messages in thread
From: Richard Cochran @ 2021-04-05 18:20 UTC (permalink / raw)
  To: Shannon Nelson; +Cc: netdev, davem, kuba, drivers, Allen Hubbe

On Mon, Apr 05, 2021 at 09:28:44AM -0700, Shannon Nelson wrote:
> On 4/4/21 4:41 PM, Richard Cochran wrote:
> > On Thu, Apr 01, 2021 at 10:56:07AM -0700, Shannon Nelson wrote:
> > 
> > > @@ -1150,6 +1232,10 @@ netdev_tx_t ionic_start_xmit(struct sk_buff *skb, struct net_device *netdev)
> > >   		return NETDEV_TX_OK;
> > >   	}
> > > +	if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))
> > > +		if (lif->hwstamp_txq)
> > > +			return ionic_start_hwstamp_xmit(skb, netdev);
> > The check for SKBTX_HW_TSTAMP and hwstamp_txq is good, but I didn't
> > see hwstamp_txq getting cleared in ionic_lif_hwstamp_set() when the
> > user turns off Tx time stamping via the SIOCSHWTSTAMP ioctl.
> 
> Once the hwstamp queues are up, we leave them there for future use until the
> interface is stopped,

Fine, but

> assuming that the stack isn't going to send us
> SKBTX_HW_STAMP after it has disabled the offload.

you can't assume that.  This is an important point, especially
considering the possibiliy of stacked HW time stamp providers.  I'm
working on a patch set that will allow the user to switch between MAC
and PHY time stamping at run time.

Thanks,
Richard

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next 12/12] ionic: advertise support for hardware timestamps
  2021-04-05 16:33     ` Shannon Nelson
@ 2021-04-05 18:23       ` Richard Cochran
  0 siblings, 0 replies; 35+ messages in thread
From: Richard Cochran @ 2021-04-05 18:23 UTC (permalink / raw)
  To: Shannon Nelson; +Cc: netdev, davem, kuba, drivers, Allen Hubbe

On Mon, Apr 05, 2021 at 09:33:46AM -0700, Shannon Nelson wrote:
> Yes, I supposed they could have gone together.  However, I believe that in a
> bisection this will only slightly confuse the user space tools, but won't
> cause any kernel pain.

Bisection typically involves running tests from user space.  The test
failing or passing determines whether the commit will be marked GOOD
or BAD.  This use case is a real thing.

Thanks,
Richard

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next 09/12] ionic: add and enable tx and rx timestamp handling
  2021-04-05 18:20       ` Richard Cochran
@ 2021-04-06 23:06         ` Shannon Nelson
  2021-04-07  0:29           ` Richard Cochran
  0 siblings, 1 reply; 35+ messages in thread
From: Shannon Nelson @ 2021-04-06 23:06 UTC (permalink / raw)
  To: Richard Cochran; +Cc: netdev, davem, kuba, drivers, Allen Hubbe

On 4/5/21 11:20 AM, Richard Cochran wrote:
> On Mon, Apr 05, 2021 at 09:28:44AM -0700, Shannon Nelson wrote:
>> On 4/4/21 4:41 PM, Richard Cochran wrote:
>>> On Thu, Apr 01, 2021 at 10:56:07AM -0700, Shannon Nelson wrote:
>>>
>>>> @@ -1150,6 +1232,10 @@ netdev_tx_t ionic_start_xmit(struct sk_buff *skb, struct net_device *netdev)
>>>>    		return NETDEV_TX_OK;
>>>>    	}
>>>> +	if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))
>>>> +		if (lif->hwstamp_txq)
>>>> +			return ionic_start_hwstamp_xmit(skb, netdev);
>>> The check for SKBTX_HW_TSTAMP and hwstamp_txq is good, but I didn't
>>> see hwstamp_txq getting cleared in ionic_lif_hwstamp_set() when the
>>> user turns off Tx time stamping via the SIOCSHWTSTAMP ioctl.
>> Once the hwstamp queues are up, we leave them there for future use until the
>> interface is stopped,
> Fine, but
>
>> assuming that the stack isn't going to send us
>> SKBTX_HW_STAMP after it has disabled the offload.
> you can't assume that.  This is an important point, especially
> considering the possibiliy of stacked HW time stamp providers.  I'm
> working on a patch set that will allow the user to switch between MAC
> and PHY time stamping at run time.
>
> Thanks,
> Richard

Interesting... I doubt that our particular MAC and PHY will ever be 
separate, but it makes sense to watch for this in the general case. I've 
got an update coming for this.

Thanks,
sln


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next 05/12] ionic: add hw timestamp support files
  2021-04-05 18:17       ` Richard Cochran
@ 2021-04-06 23:18         ` Shannon Nelson
  2021-04-07  0:27           ` Richard Cochran
  0 siblings, 1 reply; 35+ messages in thread
From: Shannon Nelson @ 2021-04-06 23:18 UTC (permalink / raw)
  To: Richard Cochran; +Cc: netdev, davem, kuba, drivers, Allen Hubbe

On 4/5/21 11:17 AM, Richard Cochran wrote:
> On Mon, Apr 05, 2021 at 09:16:39AM -0700, Shannon Nelson wrote:
>> On 4/4/21 4:05 PM, Richard Cochran wrote:
>>> This check is unneeded, because the ioctl layer never passes NULL here.
>> Yes, the ioctl layer never calls this with NULL, but we call it from within
>> the driver when we spin operations back up after a FW reset.
> So why not avoid the special case and pass a proper request?

We do this because our firmware reset path is a special case that we 
have to handle, and we do so by replaying the previous configuration 
request.  Passing the NULL request gives the code the ability to watch 
for this case while keeping the special case handling simple: the code 
that drives the replay logic doesn't need to know the hwstamp details, 
it just needs to signal the replay and let the hwstamp code keep track 
of its own data and request history.

I can update the comment to make that replay case more obvious.

sln




^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next 05/12] ionic: add hw timestamp support files
  2021-04-06 23:18         ` Shannon Nelson
@ 2021-04-07  0:27           ` Richard Cochran
  2021-04-07  4:55             ` Shannon Nelson
  0 siblings, 1 reply; 35+ messages in thread
From: Richard Cochran @ 2021-04-07  0:27 UTC (permalink / raw)
  To: Shannon Nelson; +Cc: netdev, davem, kuba, drivers, Allen Hubbe

On Tue, Apr 06, 2021 at 04:18:00PM -0700, Shannon Nelson wrote:
> On 4/5/21 11:17 AM, Richard Cochran wrote:
> > On Mon, Apr 05, 2021 at 09:16:39AM -0700, Shannon Nelson wrote:
> > > On 4/4/21 4:05 PM, Richard Cochran wrote:
> > > > This check is unneeded, because the ioctl layer never passes NULL here.
> > > Yes, the ioctl layer never calls this with NULL, but we call it from within
> > > the driver when we spin operations back up after a FW reset.
> > So why not avoid the special case and pass a proper request?
> 
> We do this because our firmware reset path is a special case that we have to
> handle, and we do so by replaying the previous configuration request. 
> Passing the NULL request gives the code the ability to watch for this case
> while keeping the special case handling simple: the code that drives the
> replay logic doesn't need to know the hwstamp details, it just needs to
> signal the replay and let the hwstamp code keep track of its own data and
> request history.
> 
> I can update the comment to make that replay case more obvious.

No, please, I am asking you to provide a hwtstamp_config from your
driver.  What is so hard about that?

Thanks,
Richard

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next 09/12] ionic: add and enable tx and rx timestamp handling
  2021-04-06 23:06         ` Shannon Nelson
@ 2021-04-07  0:29           ` Richard Cochran
  0 siblings, 0 replies; 35+ messages in thread
From: Richard Cochran @ 2021-04-07  0:29 UTC (permalink / raw)
  To: Shannon Nelson; +Cc: netdev, davem, kuba, drivers, Allen Hubbe

On Tue, Apr 06, 2021 at 04:06:09PM -0700, Shannon Nelson wrote:
> Interesting... I doubt that our particular MAC and PHY will ever be
> separate, but it makes sense to watch for this in the general case. I've got
> an update coming for this.

Even if your HW can never support stacked MAC/PHY HW time stamping,
still your driver should conform to the correct pattern.

Why?  Because new driver authors copy/paste stuff they find in the tree.

Thanks,
Richard

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next 05/12] ionic: add hw timestamp support files
  2021-04-07  0:27           ` Richard Cochran
@ 2021-04-07  4:55             ` Shannon Nelson
  0 siblings, 0 replies; 35+ messages in thread
From: Shannon Nelson @ 2021-04-07  4:55 UTC (permalink / raw)
  To: Richard Cochran; +Cc: netdev, davem, kuba, drivers, Allen Hubbe

On 4/6/21 5:27 PM, Richard Cochran wrote:
> On Tue, Apr 06, 2021 at 04:18:00PM -0700, Shannon Nelson wrote:
>> On 4/5/21 11:17 AM, Richard Cochran wrote:
>>> On Mon, Apr 05, 2021 at 09:16:39AM -0700, Shannon Nelson wrote:
>>>> On 4/4/21 4:05 PM, Richard Cochran wrote:
>>>>> This check is unneeded, because the ioctl layer never passes NULL here.
>>>> Yes, the ioctl layer never calls this with NULL, but we call it from within
>>>> the driver when we spin operations back up after a FW reset.
>>> So why not avoid the special case and pass a proper request?
>> We do this because our firmware reset path is a special case that we have to
>> handle, and we do so by replaying the previous configuration request.
>> Passing the NULL request gives the code the ability to watch for this case
>> while keeping the special case handling simple: the code that drives the
>> replay logic doesn't need to know the hwstamp details, it just needs to
>> signal the replay and let the hwstamp code keep track of its own data and
>> request history.
>>
>> I can update the comment to make that replay case more obvious.
> No, please, I am asking you to provide a hwtstamp_config from your
> driver.  What is so hard about that?
>

What I think you are asking is that we not extend the current assumption 
that *ifr will always be a useful pointer, a perfectly reasonable 
request.  Our ioctl() handler follows this as expected. It is our 
internal usage that might look like an extension.

We'd like to keep the replay related code and data to a minimum, and 
this current implementation is a simple way to do so, keeping the state 
and config info within the ptp side.

I suppose one alternative is that we pull the copy_from_user() bits into 
ionic_ioctl() and hand a hwtstamp_config struct pointer to 
ionic_lif_hwstamp_set().  In our reset case we can either hand a NULL 
pointer to ionic_lif_hwstamp_set() or add a reset parameter to the call 
where ionic_lif_hwstamp_set() simply won't inspect the hwtstamp_config 
pointer.

Another alternative would be to split the top layer of 
ionic_lif_hwstamp_set() into two different functions, one called by the 
ioctl handler with an *ifr, the other called by the fw reset logic 
without an *ifr, that both call into the remaining with a 
hwtstamp_config pointer.  This seems somewhat similar to the ixgbe approach.

Either way, in the end it seems like extra code to get to the same result.

sln


^ permalink raw reply	[flat|nested] 35+ messages in thread

end of thread, other threads:[~2021-04-07  4:55 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-01 17:55 [PATCH net-next 00/12] ionic: add PTP and hw clock support Shannon Nelson
2021-04-01 17:55 ` [PATCH net-next 01/12] ionic: add new queue features to interface Shannon Nelson
2021-04-01 17:56 ` [PATCH net-next 02/12] ionic: add handling of larger descriptors Shannon Nelson
2021-04-04 22:50   ` Richard Cochran
2021-04-05 16:17     ` Shannon Nelson
2021-04-01 17:56 ` [PATCH net-next 03/12] ionic: add hw timestamp structs to interface Shannon Nelson
2021-04-01 17:56 ` [PATCH net-next 04/12] ionic: split adminq post and wait calls Shannon Nelson
2021-04-01 17:56 ` [PATCH net-next 05/12] ionic: add hw timestamp support files Shannon Nelson
2021-04-04 23:05   ` Richard Cochran
2021-04-05  4:53     ` Leon Romanovsky
2021-04-05 16:16     ` Shannon Nelson
2021-04-05 18:17       ` Richard Cochran
2021-04-06 23:18         ` Shannon Nelson
2021-04-07  0:27           ` Richard Cochran
2021-04-07  4:55             ` Shannon Nelson
2021-04-04 23:21   ` Richard Cochran
2021-04-05 16:19     ` Shannon Nelson
2021-04-01 17:56 ` [PATCH net-next 06/12] ionic: link in the new hw timestamp code Shannon Nelson
2021-04-01 17:56 ` [PATCH net-next 07/12] ionic: add rx filtering for hw timestamp steering Shannon Nelson
2021-04-01 17:56 ` [PATCH net-next 08/12] ionic: set up hw timestamp queues Shannon Nelson
2021-04-01 17:56 ` [PATCH net-next 09/12] ionic: add and enable tx and rx timestamp handling Shannon Nelson
2021-04-04 23:41   ` Richard Cochran
2021-04-05 16:28     ` Shannon Nelson
2021-04-05 18:20       ` Richard Cochran
2021-04-06 23:06         ` Shannon Nelson
2021-04-07  0:29           ` Richard Cochran
2021-04-01 17:56 ` [PATCH net-next 10/12] ionic: add ethtool support for PTP Shannon Nelson
2021-04-01 17:56 ` [PATCH net-next 11/12] ionic: ethtool ptp stats Shannon Nelson
2021-04-01 17:56 ` [PATCH net-next 12/12] ionic: advertise support for hardware timestamps Shannon Nelson
2021-04-04 23:43   ` Richard Cochran
2021-04-05 16:33     ` Shannon Nelson
2021-04-05 18:23       ` Richard Cochran
2021-04-01 21:02 ` [PATCH net-next 00/12] ionic: add PTP and hw clock support Andrew Lunn
2021-04-01 21:11   ` Shannon Nelson
2021-04-02 21:30 ` patchwork-bot+netdevbpf

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.