From: Jie Liu <[email protected]>

This patch implements the 'get_monitor_addr' ethdev ops in the sxe2
PMD. This interface allows the Ethernet device to provide the
address of the next expected Rx descriptor to the power management
library.

The implementation calculates the address of the next Rx descriptor
based on the receive queue's current hardware ring position and
descriptor size. Applications can then use this address with
rte_power_monitor() to put the CPU into a low-power state until
new packets are written to the descriptor by the hardware.

Signed-off-by: Jie Liu <[email protected]>
---
 drivers/net/sxe2/sxe2_ethdev.c |  2 ++
 drivers/net/sxe2/sxe2_rx.c     | 21 +++++++++++++++++++++
 drivers/net/sxe2/sxe2_rx.h     |  2 ++
 3 files changed, 25 insertions(+)

diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index 215ae772b5..45e245740b 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -184,6 +184,8 @@ static const struct eth_dev_ops sxe2_eth_dev_ops = {
        .queue_stats_mapping_set    = sxe2_queue_stats_mapping_set,
 
        .fw_version_get             = sxe2_fw_version_string_get,
+
+       .get_monitor_addr           = sxe2_get_monitor_addr,
 };
 
 static int32_t sxe2_dev_configure(struct rte_eth_dev *dev)
diff --git a/drivers/net/sxe2/sxe2_rx.c b/drivers/net/sxe2/sxe2_rx.c
index 007192c7d8..9055363ee3 100644
--- a/drivers/net/sxe2/sxe2_rx.c
+++ b/drivers/net/sxe2/sxe2_rx.c
@@ -557,3 +557,24 @@ void __rte_cold sxe2_rxqs_all_stop(struct rte_eth_dev *dev)
                }
        }
 }
+
+static int32_t sxe2_monitor_callback(const uint64_t value,
+                                const uint64_t 
arg[RTE_POWER_MONITOR_OPAQUE_SZ] __rte_unused)
+{
+       const uint64_t dd_state = rte_cpu_to_le_64(1 << 
SXE2_RX_DESC_STATUS_DD_SHIFT);
+       return (value & dd_state) == dd_state ? -1 : 0;
+}
+
+int32_t sxe2_get_monitor_addr(void *rx_queue, struct rte_power_monitor_cond 
*pmc)
+{
+       volatile union sxe2_rx_desc *rxdp;
+       struct sxe2_rx_queue *rxq = (struct sxe2_rx_queue *)rx_queue;
+
+       rxdp = &rxq->desc_ring[rxq->processing_idx];
+
+       pmc->addr = &rxdp->wb.status_err_ptype_len;
+       pmc->fn   = sxe2_monitor_callback;
+       pmc->size = sizeof(uint16_t);
+
+       return 0;
+}
diff --git a/drivers/net/sxe2/sxe2_rx.h b/drivers/net/sxe2/sxe2_rx.h
index 1c53f7f559..05b991e233 100644
--- a/drivers/net/sxe2/sxe2_rx.h
+++ b/drivers/net/sxe2/sxe2_rx.h
@@ -29,4 +29,6 @@ int32_t __rte_cold sxe2_rxqs_all_start(struct rte_eth_dev 
*dev);
 
 void __rte_cold sxe2_rxqs_all_stop(struct rte_eth_dev *dev);
 
+int32_t sxe2_get_monitor_addr(void *rx_queue, struct rte_power_monitor_cond 
*pmc);
+
 #endif /* __SXE2_RX_H__ */
-- 
2.47.3

Reply via email to