From: Igor Romanov <igor.roma...@oktetlabs.ru>

The information about the number of pushed Rx buffers is required
for counter Rx queue to know when to give credits to counter
stream.

Signed-off-by: Igor Romanov <igor.roma...@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <andrew.rybche...@oktetlabs.ru>
Reviewed-by: Andy Moreton <amore...@xilinx.com>
Reviewed-by: Ivan Malov <ivan.ma...@oktetlabs.ru>
---
 drivers/net/sfc/sfc_dp_rx.h    |  4 ++++
 drivers/net/sfc/sfc_ef100_rx.c | 15 +++++++++++++++
 drivers/net/sfc/sfc_rx.c       |  9 +++++++++
 drivers/net/sfc/sfc_rx.h       |  3 +++
 4 files changed, 31 insertions(+)

diff --git a/drivers/net/sfc/sfc_dp_rx.h b/drivers/net/sfc/sfc_dp_rx.h
index 3f6857b1ff..b6c44085ce 100644
--- a/drivers/net/sfc/sfc_dp_rx.h
+++ b/drivers/net/sfc/sfc_dp_rx.h
@@ -204,6 +204,9 @@ typedef int (sfc_dp_rx_intr_enable_t)(struct sfc_dp_rxq 
*dp_rxq);
 /** Disable Rx interrupts */
 typedef int (sfc_dp_rx_intr_disable_t)(struct sfc_dp_rxq *dp_rxq);
 
+/** Get number of pushed Rx buffers */
+typedef unsigned int (sfc_dp_rx_get_pushed_t)(struct sfc_dp_rxq *dp_rxq);
+
 /** Receive datapath definition */
 struct sfc_dp_rx {
        struct sfc_dp                           dp;
@@ -238,6 +241,7 @@ struct sfc_dp_rx {
        sfc_dp_rx_qdesc_status_t                *qdesc_status;
        sfc_dp_rx_intr_enable_t                 *intr_enable;
        sfc_dp_rx_intr_disable_t                *intr_disable;
+       sfc_dp_rx_get_pushed_t                  *get_pushed;
        eth_rx_burst_t                          pkt_burst;
 };
 
diff --git a/drivers/net/sfc/sfc_ef100_rx.c b/drivers/net/sfc/sfc_ef100_rx.c
index 8cde24c585..7447f8b9de 100644
--- a/drivers/net/sfc/sfc_ef100_rx.c
+++ b/drivers/net/sfc/sfc_ef100_rx.c
@@ -892,6 +892,20 @@ sfc_ef100_rx_intr_disable(struct sfc_dp_rxq *dp_rxq)
        return 0;
 }
 
+static sfc_dp_rx_get_pushed_t sfc_ef100_rx_get_pushed;
+static unsigned int
+sfc_ef100_rx_get_pushed(struct sfc_dp_rxq *dp_rxq)
+{
+       struct sfc_ef100_rxq *rxq = sfc_ef100_rxq_by_dp_rxq(dp_rxq);
+
+       /*
+        * The datapath keeps track only of added descriptors, since
+        * the number of pushed descriptors always equals the number
+        * of added descriptors due to enforced alignment.
+        */
+       return rxq->added;
+}
+
 struct sfc_dp_rx sfc_ef100_rx = {
        .dp = {
                .name           = SFC_KVARG_DATAPATH_EF100,
@@ -919,5 +933,6 @@ struct sfc_dp_rx sfc_ef100_rx = {
        .qdesc_status           = sfc_ef100_rx_qdesc_status,
        .intr_enable            = sfc_ef100_rx_intr_enable,
        .intr_disable           = sfc_ef100_rx_intr_disable,
+       .get_pushed             = sfc_ef100_rx_get_pushed,
        .pkt_burst              = sfc_ef100_recv_pkts,
 };
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index 0532f77082..f6a8ac68e8 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -53,6 +53,15 @@ sfc_rx_qflush_failed(struct sfc_rxq_info *rxq_info)
        rxq_info->state &= ~SFC_RXQ_FLUSHING;
 }
 
+/* This returns the running counter, which is not bounded by ring size */
+unsigned int
+sfc_rx_get_pushed(struct sfc_adapter *sa, struct sfc_dp_rxq *dp_rxq)
+{
+       SFC_ASSERT(sa->priv.dp_rx->get_pushed != NULL);
+
+       return sa->priv.dp_rx->get_pushed(dp_rxq);
+}
+
 static int
 sfc_efx_rx_qprime(struct sfc_efx_rxq *rxq)
 {
diff --git a/drivers/net/sfc/sfc_rx.h b/drivers/net/sfc/sfc_rx.h
index e5a6fde79b..4ab513915e 100644
--- a/drivers/net/sfc/sfc_rx.h
+++ b/drivers/net/sfc/sfc_rx.h
@@ -145,6 +145,9 @@ uint64_t sfc_rx_get_queue_offload_caps(struct sfc_adapter 
*sa);
 void sfc_rx_qflush_done(struct sfc_rxq_info *rxq_info);
 void sfc_rx_qflush_failed(struct sfc_rxq_info *rxq_info);
 
+unsigned int sfc_rx_get_pushed(struct sfc_adapter *sa,
+                              struct sfc_dp_rxq *dp_rxq);
+
 int sfc_rx_hash_init(struct sfc_adapter *sa);
 void sfc_rx_hash_fini(struct sfc_adapter *sa);
 int sfc_rx_hf_rte_to_efx(struct sfc_adapter *sa, uint64_t rte,
-- 
2.30.2

Reply via email to