1 | /* SPDX-License-Identifier: (GPL-2.0 OR MIT) |
2 | * Google virtual Ethernet (gve) driver |
3 | * |
4 | * Copyright (C) 2015-2021 Google, Inc. |
5 | */ |
6 | |
7 | #ifndef _GVE_DQO_H_ |
8 | #define _GVE_DQO_H_ |
9 | |
10 | #include "gve_adminq.h" |
11 | |
12 | #define GVE_ITR_ENABLE_BIT_DQO BIT(0) |
13 | #define GVE_ITR_CLEAR_PBA_BIT_DQO BIT(1) |
14 | #define GVE_ITR_NO_UPDATE_DQO (3 << 3) |
15 | |
16 | #define GVE_ITR_INTERVAL_DQO_SHIFT 5 |
17 | #define GVE_ITR_INTERVAL_DQO_MASK ((1 << 12) - 1) |
18 | |
19 | #define GVE_TX_IRQ_RATELIMIT_US_DQO 50 |
20 | #define GVE_RX_IRQ_RATELIMIT_US_DQO 20 |
21 | #define GVE_MAX_ITR_INTERVAL_DQO (GVE_ITR_INTERVAL_DQO_MASK * 2) |
22 | |
23 | /* Timeout in seconds to wait for a reinjection completion after receiving |
24 | * its corresponding miss completion. |
25 | */ |
26 | #define GVE_REINJECT_COMPL_TIMEOUT 1 |
27 | |
28 | /* Timeout in seconds to deallocate the completion tag for a packet that was |
29 | * prematurely freed for not receiving a valid completion. This should be large |
30 | * enough to rule out the possibility of receiving the corresponding valid |
31 | * completion after this interval. |
32 | */ |
33 | #define GVE_DEALLOCATE_COMPL_TIMEOUT 60 |
34 | |
35 | netdev_tx_t gve_tx_dqo(struct sk_buff *skb, struct net_device *dev); |
36 | netdev_features_t gve_features_check_dqo(struct sk_buff *skb, |
37 | struct net_device *dev, |
38 | netdev_features_t features); |
39 | bool gve_tx_poll_dqo(struct gve_notify_block *block, bool do_clean); |
40 | int gve_rx_poll_dqo(struct gve_notify_block *block, int budget); |
41 | int gve_tx_alloc_rings_dqo(struct gve_priv *priv, |
42 | struct gve_tx_alloc_rings_cfg *cfg); |
43 | void gve_tx_free_rings_dqo(struct gve_priv *priv, |
44 | struct gve_tx_alloc_rings_cfg *cfg); |
45 | void gve_tx_start_ring_dqo(struct gve_priv *priv, int idx); |
46 | void gve_tx_stop_ring_dqo(struct gve_priv *priv, int idx); |
47 | int gve_rx_alloc_rings_dqo(struct gve_priv *priv, |
48 | struct gve_rx_alloc_rings_cfg *cfg); |
49 | void gve_rx_free_rings_dqo(struct gve_priv *priv, |
50 | struct gve_rx_alloc_rings_cfg *cfg); |
51 | void gve_rx_start_ring_dqo(struct gve_priv *priv, int idx); |
52 | void gve_rx_stop_ring_dqo(struct gve_priv *priv, int idx); |
53 | int gve_clean_tx_done_dqo(struct gve_priv *priv, struct gve_tx_ring *tx, |
54 | struct napi_struct *napi); |
55 | void gve_rx_post_buffers_dqo(struct gve_rx_ring *rx); |
56 | void gve_rx_write_doorbell_dqo(const struct gve_priv *priv, int queue_idx); |
57 | |
58 | static inline void |
59 | gve_tx_put_doorbell_dqo(const struct gve_priv *priv, |
60 | const struct gve_queue_resources *q_resources, u32 val) |
61 | { |
62 | u64 index; |
63 | |
64 | index = be32_to_cpu(q_resources->db_index); |
65 | iowrite32(val, &priv->db_bar2[index]); |
66 | } |
67 | |
68 | /* Builds register value to write to DQO IRQ doorbell to enable with specified |
69 | * ITR interval. |
70 | */ |
71 | static inline u32 gve_setup_itr_interval_dqo(u32 interval_us) |
72 | { |
73 | u32 result = GVE_ITR_ENABLE_BIT_DQO; |
74 | |
75 | /* Interval has 2us granularity. */ |
76 | interval_us >>= 1; |
77 | |
78 | interval_us &= GVE_ITR_INTERVAL_DQO_MASK; |
79 | result |= (interval_us << GVE_ITR_INTERVAL_DQO_SHIFT); |
80 | |
81 | return result; |
82 | } |
83 | |
84 | static inline void |
85 | gve_write_irq_doorbell_dqo(const struct gve_priv *priv, |
86 | const struct gve_notify_block *block, u32 val) |
87 | { |
88 | u32 index = be32_to_cpu(*block->irq_db_index); |
89 | |
90 | iowrite32(val, &priv->db_bar2[index]); |
91 | } |
92 | |
93 | /* Sets interrupt throttling interval and enables interrupt |
94 | * by writing to IRQ doorbell. |
95 | */ |
96 | static inline void |
97 | gve_set_itr_coalesce_usecs_dqo(struct gve_priv *priv, |
98 | struct gve_notify_block *block, |
99 | u32 usecs) |
100 | { |
101 | gve_write_irq_doorbell_dqo(priv, block, |
102 | val: gve_setup_itr_interval_dqo(interval_us: usecs)); |
103 | } |
104 | |
105 | int gve_napi_poll_dqo(struct napi_struct *napi, int budget); |
106 | #endif /* _GVE_DQO_H_ */ |
107 | |