]>
git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/dpdk/drivers/net/mlx5/mlx5_rss.c
4 * Copyright 2015 6WIND S.A.
5 * Copyright 2015 Mellanox.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of 6WIND S.A. nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 /* ISO C doesn't support unnamed structs/unions, disabling -pedantic. */
43 #pragma GCC diagnostic ignored "-Wpedantic"
45 #include <infiniband/verbs.h>
47 #pragma GCC diagnostic error "-Wpedantic"
50 /* DPDK headers don't like -pedantic. */
52 #pragma GCC diagnostic ignored "-Wpedantic"
54 #include <rte_malloc.h>
55 #include <rte_ethdev.h>
57 #pragma GCC diagnostic error "-Wpedantic"
61 #include "mlx5_rxtx.h"
64 * Get a RSS configuration hash key.
67 * Pointer to private structure.
69 * RSS hash functions configuration must be retrieved for.
72 * Pointer to a RSS configuration structure or NULL if rss_hf cannot
75 static struct rte_eth_rss_conf
*
76 rss_hash_get(struct priv
*priv
, uint64_t rss_hf
)
80 for (i
= 0; (i
!= hash_rxq_init_n
); ++i
) {
81 uint64_t dpdk_rss_hf
= hash_rxq_init
[i
].dpdk_rss_hf
;
83 if (!(dpdk_rss_hf
& rss_hf
))
85 return (*priv
->rss_conf
)[i
];
94 * Pointer to private structure.
96 * Hash key to register.
98 * Hash key length in bytes.
100 * RSS hash functions the provided key applies to.
103 * 0 on success, errno value on failure.
106 rss_hash_rss_conf_new_key(struct priv
*priv
, const uint8_t *key
,
107 unsigned int key_len
, uint64_t rss_hf
)
111 for (i
= 0; (i
!= hash_rxq_init_n
); ++i
) {
112 struct rte_eth_rss_conf
*rss_conf
;
113 uint64_t dpdk_rss_hf
= hash_rxq_init
[i
].dpdk_rss_hf
;
115 if (!(dpdk_rss_hf
& rss_hf
))
117 rss_conf
= rte_realloc((*priv
->rss_conf
)[i
],
118 (sizeof(*rss_conf
) + key_len
),
122 rss_conf
->rss_key
= (void *)(rss_conf
+ 1);
123 rss_conf
->rss_key_len
= key_len
;
124 rss_conf
->rss_hf
= dpdk_rss_hf
;
125 memcpy(rss_conf
->rss_key
, key
, key_len
);
126 (*priv
->rss_conf
)[i
] = rss_conf
;
132 * DPDK callback to update the RSS hash configuration.
135 * Pointer to Ethernet device structure.
136 * @param[in] rss_conf
137 * RSS configuration data.
140 * 0 on success, negative errno value on failure.
143 mlx5_rss_hash_update(struct rte_eth_dev
*dev
,
144 struct rte_eth_rss_conf
*rss_conf
)
146 struct priv
*priv
= dev
->data
->dev_private
;
151 assert(priv
->rss_conf
!= NULL
);
153 /* Apply configuration. */
154 if (rss_conf
->rss_key
)
155 err
= rss_hash_rss_conf_new_key(priv
,
157 rss_conf
->rss_key_len
,
159 /* Store protocols for which RSS is enabled. */
160 priv
->rss_hf
= rss_conf
->rss_hf
;
167 * DPDK callback to get the RSS hash configuration.
170 * Pointer to Ethernet device structure.
171 * @param[in, out] rss_conf
172 * RSS configuration data.
175 * 0 on success, negative errno value on failure.
178 mlx5_rss_hash_conf_get(struct rte_eth_dev
*dev
,
179 struct rte_eth_rss_conf
*rss_conf
)
181 struct priv
*priv
= dev
->data
->dev_private
;
182 struct rte_eth_rss_conf
*priv_rss_conf
;
186 assert(priv
->rss_conf
!= NULL
);
188 priv_rss_conf
= rss_hash_get(priv
, rss_conf
->rss_hf
);
189 if (!priv_rss_conf
) {
190 rss_conf
->rss_hf
= 0;
194 if (rss_conf
->rss_key
&&
195 rss_conf
->rss_key_len
>= priv_rss_conf
->rss_key_len
)
196 memcpy(rss_conf
->rss_key
,
197 priv_rss_conf
->rss_key
,
198 priv_rss_conf
->rss_key_len
);
199 rss_conf
->rss_key_len
= priv_rss_conf
->rss_key_len
;
200 rss_conf
->rss_hf
= priv_rss_conf
->rss_hf
;
207 * Allocate/reallocate RETA index table.
210 * Pointer to private structure.
212 * The size of the array to allocate.
215 * 0 on success, errno value on failure.
218 priv_rss_reta_index_resize(struct priv
*priv
, unsigned int reta_size
)
221 unsigned int old_size
= priv
->reta_idx_n
;
223 if (priv
->reta_idx_n
== reta_size
)
226 mem
= rte_realloc(priv
->reta_idx
,
227 reta_size
* sizeof((*priv
->reta_idx
)[0]), 0);
230 priv
->reta_idx
= mem
;
231 priv
->reta_idx_n
= reta_size
;
233 if (old_size
< reta_size
)
234 memset(&(*priv
->reta_idx
)[old_size
], 0,
235 (reta_size
- old_size
) *
236 sizeof((*priv
->reta_idx
)[0]));
244 * Pointer to private structure.
245 * @param[in, out] reta_conf
246 * Pointer to the first RETA configuration structure.
251 * 0 on success, errno value on failure.
254 priv_dev_rss_reta_query(struct priv
*priv
,
255 struct rte_eth_rss_reta_entry64
*reta_conf
,
256 unsigned int reta_size
)
261 if (!reta_size
|| reta_size
> priv
->reta_idx_n
)
263 /* Fill each entry of the table even if its bit is not set. */
264 for (idx
= 0, i
= 0; (i
!= reta_size
); ++i
) {
265 idx
= i
/ RTE_RETA_GROUP_SIZE
;
266 reta_conf
[idx
].reta
[i
% RTE_RETA_GROUP_SIZE
] =
267 (*priv
->reta_idx
)[i
];
276 * Pointer to private structure.
277 * @param[in] reta_conf
278 * Pointer to the first RETA configuration structure.
283 * 0 on success, errno value on failure.
286 priv_dev_rss_reta_update(struct priv
*priv
,
287 struct rte_eth_rss_reta_entry64
*reta_conf
,
288 unsigned int reta_size
)
297 ret
= priv_rss_reta_index_resize(priv
, reta_size
);
301 for (idx
= 0, i
= 0; (i
!= reta_size
); ++i
) {
302 idx
= i
/ RTE_RETA_GROUP_SIZE
;
303 pos
= i
% RTE_RETA_GROUP_SIZE
;
304 if (((reta_conf
[idx
].mask
>> i
) & 0x1) == 0)
306 assert(reta_conf
[idx
].reta
[pos
] < priv
->rxqs_n
);
307 (*priv
->reta_idx
)[i
] = reta_conf
[idx
].reta
[pos
];
313 * DPDK callback to get the RETA indirection table.
316 * Pointer to Ethernet device structure.
318 * Pointer to RETA configuration structure array.
320 * Size of the RETA table.
323 * 0 on success, negative errno value on failure.
326 mlx5_dev_rss_reta_query(struct rte_eth_dev
*dev
,
327 struct rte_eth_rss_reta_entry64
*reta_conf
,
331 struct priv
*priv
= dev
->data
->dev_private
;
334 ret
= priv_dev_rss_reta_query(priv
, reta_conf
, reta_size
);
340 * DPDK callback to update the RETA indirection table.
343 * Pointer to Ethernet device structure.
345 * Pointer to RETA configuration structure array.
347 * Size of the RETA table.
350 * 0 on success, negative errno value on failure.
353 mlx5_dev_rss_reta_update(struct rte_eth_dev
*dev
,
354 struct rte_eth_rss_reta_entry64
*reta_conf
,
358 struct priv
*priv
= dev
->data
->dev_private
;
362 ret
= priv_dev_rss_reta_update(priv
, reta_conf
, reta_size
);
366 return mlx5_dev_start(dev
);