diff options
| author | Haiyang Zhang <haiyangz@microsoft.com> | 2026-07-02 15:01:04 -0700 |
|---|---|---|
| committer | Paolo Abeni <pabeni@redhat.com> | 2026-07-09 10:54:00 +0200 |
| commit | 433f482add31b8f81c79fcafa739a5e7ab71daf2 (patch) | |
| tree | fa8b2e5fda2d29e0dde77e7957f730245c428a20 /include | |
| parent | 08030ddb87b4c6c6a2c03c82731b5e188f02f5b9 (diff) | |
net: mana: Add Interrupt Moderation support
Add Static and Dynamic Interrupt Moderation (DIM) support for
Rx and Tx.
Update queue creation procedure with new data struct with the related
settings.
Add functions to collect stat for DIM, and workers to update DIM data
and settings.
Update ethtool handler to get/set the moderation settings from a user.
To avoid detach/re-attach ops, ring DIM doorbell to change settings
at run time.
By default, adaptive-rx/tx (DIM) are enabled if supported by HW.
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260702220123.815018-1-haiyangz@linux.microsoft.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Diffstat (limited to 'include')
| -rw-r--r-- | include/net/mana/gdma.h | 24 | ||||
| -rw-r--r-- | include/net/mana/mana.h | 54 |
2 files changed, 77 insertions, 1 deletions
diff --git a/include/net/mana/gdma.h b/include/net/mana/gdma.h index 0c395917b214..8529cef0d7c4 100644 --- a/include/net/mana/gdma.h +++ b/include/net/mana/gdma.h @@ -47,6 +47,7 @@ enum gdma_queue_type { GDMA_RQ, GDMA_CQ, GDMA_EQ, + GDMA_DIM, }; enum gdma_work_request_flags { @@ -126,6 +127,17 @@ union gdma_doorbell_entry { u64 tail_ptr : 31; u64 arm : 1; } eq; + + struct { + u64 id : 24; + u64 reserved : 8; + u64 mod_usec : 10; + u64 reserve1 : 5; + u64 mod_usec_vld : 1; + u64 mod_comps : 8; + u64 reserve2 : 7; + u64 mod_comps_vld: 1; + } dim; }; /* HW DATA */ struct gdma_msg_hdr { @@ -502,6 +514,9 @@ void mana_gd_ring_cq(struct gdma_queue *cq, u8 arm_bit); int mana_schedule_serv_work(struct gdma_context *gc, enum gdma_eqe_type type); +void mana_gd_ring_dim(struct gdma_queue *cq, u32 mod_usec, bool mod_usec_vld, + u32 mod_comps, bool mod_comps_vld); + struct gdma_wqe { u32 reserved :24; u32 last_vbytes :8; @@ -650,6 +665,9 @@ enum { /* Driver supports self recovery on Hardware Channel timeouts */ #define GDMA_DRV_CAP_FLAG_1_HWC_TIMEOUT_RECOVERY BIT(25) +/* Driver supports dynamic interrupt moderation - DIM */ +#define GDMA_DRV_CAP_FLAG_1_DYN_INTERRUPT_MODERATION BIT(28) + #define GDMA_DRV_CAP_FLAGS1 \ (GDMA_DRV_CAP_FLAG_1_EQ_SHARING_MULTI_VPORT | \ GDMA_DRV_CAP_FLAG_1_NAPI_WKDONE_FIX | \ @@ -665,7 +683,8 @@ enum { GDMA_DRV_CAP_FLAG_1_PROBE_RECOVERY | \ GDMA_DRV_CAP_FLAG_1_HANDLE_STALL_SQ_RECOVERY | \ GDMA_DRV_CAP_FLAG_1_HWC_TIMEOUT_RECOVERY | \ - GDMA_DRV_CAP_FLAG_1_EQ_MSI_UNSHARE_MULTI_VPORT) + GDMA_DRV_CAP_FLAG_1_EQ_MSI_UNSHARE_MULTI_VPORT | \ + GDMA_DRV_CAP_FLAG_1_DYN_INTERRUPT_MODERATION) #define GDMA_DRV_CAP_FLAGS2 0 @@ -701,6 +720,9 @@ struct gdma_verify_ver_req { u8 os_ver_str4[128]; }; /* HW DATA */ +/* HW supports dynamic interrupt moderation - DIM */ +#define GDMA_PF_CAP_FLAG_1_DYN_INTERRUPT_MODERATION BIT(15) + struct gdma_verify_ver_resp { struct gdma_resp_hdr hdr; u64 gdma_protocol_ver; diff --git a/include/net/mana/mana.h b/include/net/mana/mana.h index 13c87baf018e..48f4445aa87a 100644 --- a/include/net/mana/mana.h +++ b/include/net/mana/mana.h @@ -4,6 +4,7 @@ #ifndef _MANA_H #define _MANA_H +#include <linux/dim.h> #include <net/xdp.h> #include <net/net_shaper.h> @@ -64,6 +65,19 @@ enum TRI_STATE { /* Maximum number of packets per coalesced CQE */ #define MANA_RXCOMP_OOB_NUM_PPI 4 +/* Default/max interrupt moderation settings */ +#define MANA_INTR_MODR_USEC_DEF 0 +#define MANA_INTR_MODR_COMP_DEF 0 + +#define MANA_ADAPTIVE_RX_DEF true +#define MANA_ADAPTIVE_TX_DEF true + +/* DIM doorbell value field layout */ +#define MANA_INTR_MODR_USEC_MAX GENMASK(9, 0) +#define MANA_INTR_MODR_USEC_VLD BIT(15) +#define MANA_INTR_MODR_COMP_MAX GENMASK(7, 0) +#define MANA_INTR_MODR_COMP_MASK GENMASK(23, 16) + /* Update this count whenever the respective structures are changed */ #define MANA_STATS_RX_COUNT (6 + MANA_RXCOMP_OOB_NUM_PPI - 1) #define MANA_STATS_TX_COUNT 11 @@ -297,6 +311,17 @@ struct mana_cq { int work_done; int work_done_since_doorbell; int budget; + + /* DIM - Dynamic Interrupt Moderation */ + struct dim dim; + u16 dim_event_ctr; + + /* Cumulative TX completions fed to DIM. Updated and read only in + * NAPI context (mana_poll_tx_cq() / mana_update_tx_dim()), so they + * measure the hardware completion rate and need no u64_stats_sync. + */ + u64 tx_dim_pkts; + u64 tx_dim_bytes; }; struct mana_recv_buf_oob { @@ -573,6 +598,15 @@ struct mana_port_context { u8 cqe_coalescing_enable; u32 cqe_coalescing_timeout_ns; + /* Interrupt moderation settings */ + u16 intr_modr_rx_usec; + u16 intr_modr_rx_comp; + u16 intr_modr_tx_usec; + u16 intr_modr_tx_comp; + + bool rx_dim_enabled; + bool tx_dim_enabled; + struct mana_ethtool_stats eth_stats; struct mana_ethtool_phy_stats phy_stats; @@ -598,6 +632,8 @@ int mana_alloc_queues(struct net_device *ndev); int mana_attach(struct net_device *ndev); int mana_detach(struct net_device *ndev, bool from_close); +void mana_dim_change(struct mana_cq *cq, bool enable); + int mana_probe(struct gdma_dev *gd, bool resuming); void mana_remove(struct gdma_dev *gd, bool suspending); @@ -633,6 +669,9 @@ struct mana_obj_spec { u32 queue_size; u32 attached_eq; u32 modr_ctx_id; + u8 req_cq_moderation; + u16 cq_moderation_comp; + u16 cq_moderation_usec; }; enum mana_command_code { @@ -764,6 +803,15 @@ struct mana_create_wqobj_req { u32 cq_size; u32 cq_moderation_ctx_id; u32 cq_parent_qid; + + /* V2 */ + u8 allow_rqwqe_chain; + + /* V3 */ + u8 req_cq_moderation; + u16 cq_moderation_comp; + u16 cq_moderation_usec; + u8 reserved2[2]; }; /* HW DATA */ struct mana_create_wqobj_resp { @@ -771,6 +819,12 @@ struct mana_create_wqobj_resp { u32 wq_id; u32 cq_id; mana_handle_t wq_obj; + + /* V2 */ + u16 cq_moderation_comp; + u16 cq_moderation_usec; + u8 cq_moderation_enabled; + u8 reserved1[3]; }; /* HW DATA */ /* Destroy WQ Object */ |
