ena module for Driver Update Program
CentOS Sources
2019-01-09 fc384122a7a805dde4dbbf3c4c4ef94a5ca0f2fe
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
Date: Tue, 30 Oct 2018 13:25:32 -0400
From: linville@redhat.com
To: rhkernel-list@redhat.com
Cc: Lin Liu <linl@redhat.com>
Subject: [RHEL7 17/28] net: ena: introduce Low Latency Queues data structures
 according to ENA spec
 
From: "John W. Linville" <linville@redhat.com>
 
BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1633418
Brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=18850510
 
Low Latency Queues(LLQ) allow usage of device's memory for descriptors
and headers. Such queues decrease processing time since data is already
located on the device when driver rings the doorbell.
 
Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit a7982b8ec947052df6d4467b3a81571f02f528e0)
Signed-off-by: John W. Linville <linville@redhat.com>
---
 .../net/ethernet/amazon/ena/ena_admin_defs.h  | 90 ++++++++++++++++++-
 drivers/net/ethernet/amazon/ena/ena_com.h     | 38 ++++++++
 drivers/net/ethernet/amazon/ena/ena_netdev.c  |  6 +-
 3 files changed, 128 insertions(+), 6 deletions(-)
 
diff --git a/drivers/net/ethernet/amazon/ena/ena_admin_defs.h b/drivers/net/ethernet/amazon/ena/ena_admin_defs.h
index d735164efea3..b439ec1b3edb 100644
--- a/drivers/net/ethernet/amazon/ena/ena_admin_defs.h
+++ b/drivers/net/ethernet/amazon/ena/ena_admin_defs.h
@@ -74,6 +74,8 @@ enum ena_admin_aq_feature_id {
 
     ENA_ADMIN_HW_HINTS            = 3,
 
+    ENA_ADMIN_LLQ                           = 4,
+
     ENA_ADMIN_RSS_HASH_FUNCTION        = 10,
 
     ENA_ADMIN_STATELESS_OFFLOAD_CONFIG    = 11,
@@ -485,8 +487,85 @@ struct ena_admin_device_attr_feature_desc {
     u32 max_mtu;
 };
 
+enum ena_admin_llq_header_location {
+    /* header is in descriptor list */
+    ENA_ADMIN_INLINE_HEADER                     = 1,
+    /* header in a separate ring, implies 16B descriptor list entry */
+    ENA_ADMIN_HEADER_RING                       = 2,
+};
+
+enum ena_admin_llq_ring_entry_size {
+    ENA_ADMIN_LIST_ENTRY_SIZE_128B              = 1,
+    ENA_ADMIN_LIST_ENTRY_SIZE_192B              = 2,
+    ENA_ADMIN_LIST_ENTRY_SIZE_256B              = 4,
+};
+
+enum ena_admin_llq_num_descs_before_header {
+    ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_0     = 0,
+    ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_1     = 1,
+    ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_2     = 2,
+    ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_4     = 4,
+    ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_8     = 8,
+};
+
+/* packet descriptor list entry always starts with one or more descriptors,
+ * followed by a header. The rest of the descriptors are located in the
+ * beginning of the subsequent entry. Stride refers to how the rest of the
+ * descriptors are placed. This field is relevant only for inline header
+ * mode
+ */
+enum ena_admin_llq_stride_ctrl {
+    ENA_ADMIN_SINGLE_DESC_PER_ENTRY             = 1,
+    ENA_ADMIN_MULTIPLE_DESCS_PER_ENTRY          = 2,
+};
+
+struct ena_admin_feature_llq_desc {
+    u32 max_llq_num;
+
+    u32 max_llq_depth;
+
+    /*  specify the header locations the device supports. bitfield of
+     *    enum ena_admin_llq_header_location.
+     */
+    u16 header_location_ctrl_supported;
+
+    /* the header location the driver selected to use. */
+    u16 header_location_ctrl_enabled;
+
+    /* if inline header is specified - this is the size of descriptor
+     *    list entry. If header in a separate ring is specified - this is
+     *    the size of header ring entry. bitfield of enum
+     *    ena_admin_llq_ring_entry_size. specify the entry sizes the device
+     *    supports
+     */
+    u16 entry_size_ctrl_supported;
+
+    /* the entry size the driver selected to use. */
+    u16 entry_size_ctrl_enabled;
+
+    /* valid only if inline header is specified. First entry associated
+     *    with the packet includes descriptors and header. Rest of the
+     *    entries occupied by descriptors. This parameter defines the max
+     *    number of descriptors precedding the header in the first entry.
+     *    The field is bitfield of enum
+     *    ena_admin_llq_num_descs_before_header and specify the values the
+     *    device supports
+     */
+    u16 desc_num_before_header_supported;
+
+    /* the desire field the driver selected to use */
+    u16 desc_num_before_header_enabled;
+
+    /* valid only if inline was chosen. bitfield of enum
+     *    ena_admin_llq_stride_ctrl
+     */
+    u16 descriptors_stride_ctrl_supported;
+
+    /* the stride control the driver selected to use */
+    u16 descriptors_stride_ctrl_enabled;
+};
+
 struct ena_admin_queue_feature_desc {
-    /* including LLQs */
     u32 max_sq_num;
 
     u32 max_sq_depth;
@@ -495,9 +574,9 @@ struct ena_admin_queue_feature_desc {
 
     u32 max_cq_depth;
 
-    u32 max_llq_num;
+    u32 max_legacy_llq_num;
 
-    u32 max_llq_depth;
+    u32 max_legacy_llq_depth;
 
     u32 max_header_size;
 
@@ -822,6 +901,8 @@ struct ena_admin_get_feat_resp {
 
         struct ena_admin_device_attr_feature_desc dev_attr;
 
+        struct ena_admin_feature_llq_desc llq;
+
         struct ena_admin_queue_feature_desc max_queue;
 
         struct ena_admin_feature_aenq_desc aenq;
@@ -869,6 +950,9 @@ struct ena_admin_set_feat_cmd {
 
         /* rss indirection table */
         struct ena_admin_feature_rss_ind_table ind_table;
+
+        /* LLQ configuration */
+        struct ena_admin_feature_llq_desc llq;
     } u;
 };
 
diff --git a/drivers/net/ethernet/amazon/ena/ena_com.h b/drivers/net/ethernet/amazon/ena/ena_com.h
index 7b784f8a06a6..50e6c8f6f138 100644
--- a/drivers/net/ethernet/amazon/ena/ena_com.h
+++ b/drivers/net/ethernet/amazon/ena/ena_com.h
@@ -108,6 +108,14 @@ enum ena_intr_moder_level {
     ENA_INTR_MAX_NUM_OF_LEVELS,
 };
 
+struct ena_llq_configurations {
+    enum ena_admin_llq_header_location llq_header_location;
+    enum ena_admin_llq_ring_entry_size llq_ring_entry_size;
+    enum ena_admin_llq_stride_ctrl  llq_stride_ctrl;
+    enum ena_admin_llq_num_descs_before_header llq_num_decs_before_header;
+    u16 llq_ring_entry_size_value;
+};
+
 struct ena_intr_moder_entry {
     unsigned int intr_moder_interval;
     unsigned int pkts_per_interval;
@@ -142,6 +150,15 @@ struct ena_com_tx_meta {
     u16 l4_hdr_len; /* In words */
 };
 
+struct ena_com_llq_info {
+    u16 header_location_ctrl;
+    u16 desc_stride_ctrl;
+    u16 desc_list_entry_size_ctrl;
+    u16 desc_list_entry_size;
+    u16 descs_num_before_header;
+    u16 descs_per_entry;
+};
+
 struct ena_com_io_cq {
     struct ena_com_io_desc_addr cdesc_addr;
 
@@ -179,6 +196,20 @@ struct ena_com_io_cq {
 
 } ____cacheline_aligned;
 
+struct ena_com_io_bounce_buffer_control {
+    u8 *base_buffer;
+    u16 next_to_use;
+    u16 buffer_size;
+    u16 buffers_num;  /* Must be a power of 2 */
+};
+
+/* This struct is to keep tracking the current location of the next llq entry */
+struct ena_com_llq_pkt_ctrl {
+    u8 *curr_bounce_buf;
+    u16 idx;
+    u16 descs_left_in_line;
+};
+
 struct ena_com_io_sq {
     struct ena_com_io_desc_addr desc_addr;
 
@@ -190,6 +221,9 @@ struct ena_com_io_sq {
 
     u32 msix_vector;
     struct ena_com_tx_meta cached_tx_meta;
+    struct ena_com_llq_info llq_info;
+    struct ena_com_llq_pkt_ctrl llq_buf_ctrl;
+    struct ena_com_io_bounce_buffer_control bounce_buf_ctrl;
 
     u16 q_depth;
     u16 qid;
@@ -197,6 +231,7 @@ struct ena_com_io_sq {
     u16 idx;
     u16 tail;
     u16 next_to_comp;
+    u16 llq_last_copy_tail;
     u32 tx_max_header_size;
     u8 phase;
     u8 desc_entry_size;
@@ -334,6 +369,8 @@ struct ena_com_dev {
     u16 intr_delay_resolution;
     u32 intr_moder_tx_interval;
     struct ena_intr_moder_entry *intr_moder_tbl;
+
+    struct ena_com_llq_info llq_info;
 };
 
 struct ena_com_dev_get_features_ctx {
@@ -342,6 +379,7 @@ struct ena_com_dev_get_features_ctx {
     struct ena_admin_feature_aenq_desc aenq;
     struct ena_admin_feature_offload_desc offload;
     struct ena_admin_ena_hw_hints hw_hints;
+    struct ena_admin_feature_llq_desc llq;
 };
 
 struct ena_com_create_io_ctx {
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c
index 04a70b78091a..61595b8ea7e8 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -2953,7 +2953,7 @@ static int ena_calc_io_queue_num(struct pci_dev *pdev,
 
     /* In case of LLQ use the llq number in the get feature cmd */
     if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) {
-        io_sq_num = get_feat_ctx->max_queues.max_llq_num;
+        io_sq_num = get_feat_ctx->max_queues.max_legacy_llq_num;
 
         if (io_sq_num == 0) {
             dev_err(&pdev->dev,
@@ -2989,7 +2989,7 @@ static void ena_set_push_mode(struct pci_dev *pdev, struct ena_com_dev *ena_dev,
     has_mem_bar = pci_select_bars(pdev, IORESOURCE_MEM) & BIT(ENA_MEM_BAR);
 
     /* Enable push mode if device supports LLQ */
-    if (has_mem_bar && (get_feat_ctx->max_queues.max_llq_num > 0))
+    if (has_mem_bar && get_feat_ctx->max_queues.max_legacy_llq_num > 0)
         ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_DEV;
     else
         ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST;
@@ -3125,7 +3125,7 @@ static int ena_calc_queue_size(struct pci_dev *pdev,
 
     if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV)
         queue_size = min_t(u32, queue_size,
-                   get_feat_ctx->max_queues.max_llq_depth);
+                   get_feat_ctx->max_queues.max_legacy_llq_depth);
 
     queue_size = rounddown_pow_of_two(queue_size);
 
-- 
2.17.1