]>
git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/dpdk/drivers/net/mlx5/mlx5_rss.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright 2015 6WIND S.A.
3 * Copyright 2015 Mellanox Technologies, Ltd
13 /* ISO C doesn't support unnamed structs/unions, disabling -pedantic. */
15 #pragma GCC diagnostic ignored "-Wpedantic"
17 #include <infiniband/verbs.h>
19 #pragma GCC diagnostic error "-Wpedantic"
22 #include <rte_malloc.h>
23 #include <rte_ethdev_driver.h>
26 #include "mlx5_defs.h"
27 #include "mlx5_rxtx.h"
30 * DPDK callback to update the RSS hash configuration.
33 * Pointer to Ethernet device structure.
35 * RSS configuration data.
38 * 0 on success, a negative errno value otherwise and rte_errno is set.
41 mlx5_rss_hash_update(struct rte_eth_dev
*dev
,
42 struct rte_eth_rss_conf
*rss_conf
)
44 struct mlx5_priv
*priv
= dev
->data
->dev_private
;
48 if (rss_conf
->rss_hf
& MLX5_RSS_HF_MASK
) {
52 if (rss_conf
->rss_key
&& rss_conf
->rss_key_len
) {
53 if (rss_conf
->rss_key_len
!= MLX5_RSS_HASH_KEY_LEN
) {
55 "port %u RSS key len must be %s Bytes long",
57 RTE_STR(MLX5_RSS_HASH_KEY_LEN
));
61 priv
->rss_conf
.rss_key
= rte_realloc(priv
->rss_conf
.rss_key
,
62 rss_conf
->rss_key_len
, 0);
63 if (!priv
->rss_conf
.rss_key
) {
67 memcpy(priv
->rss_conf
.rss_key
, rss_conf
->rss_key
,
68 rss_conf
->rss_key_len
);
69 priv
->rss_conf
.rss_key_len
= rss_conf
->rss_key_len
;
71 priv
->rss_conf
.rss_hf
= rss_conf
->rss_hf
;
72 /* Enable the RSS hash in all Rx queues. */
73 for (i
= 0, idx
= 0; idx
!= priv
->rxqs_n
; ++i
) {
74 if (!(*priv
->rxqs
)[i
])
76 (*priv
->rxqs
)[i
]->rss_hash
= !!rss_conf
->rss_hf
&&
77 !!(dev
->data
->dev_conf
.rxmode
.mq_mode
& ETH_MQ_RX_RSS
);
84 * DPDK callback to get the RSS hash configuration.
87 * Pointer to Ethernet device structure.
88 * @param[in, out] rss_conf
89 * RSS configuration data.
92 * 0 on success, a negative errno value otherwise and rte_errno is set.
95 mlx5_rss_hash_conf_get(struct rte_eth_dev
*dev
,
96 struct rte_eth_rss_conf
*rss_conf
)
98 struct mlx5_priv
*priv
= dev
->data
->dev_private
;
104 if (rss_conf
->rss_key
&&
105 (rss_conf
->rss_key_len
>= priv
->rss_conf
.rss_key_len
)) {
106 memcpy(rss_conf
->rss_key
, priv
->rss_conf
.rss_key
,
107 priv
->rss_conf
.rss_key_len
);
109 rss_conf
->rss_key_len
= priv
->rss_conf
.rss_key_len
;
110 rss_conf
->rss_hf
= priv
->rss_conf
.rss_hf
;
115 * Allocate/reallocate RETA index table.
118 * Pointer to Ethernet device.
120 * The size of the array to allocate.
123 * 0 on success, a negative errno value otherwise and rte_errno is set.
126 mlx5_rss_reta_index_resize(struct rte_eth_dev
*dev
, unsigned int reta_size
)
128 struct mlx5_priv
*priv
= dev
->data
->dev_private
;
130 unsigned int old_size
= priv
->reta_idx_n
;
132 if (priv
->reta_idx_n
== reta_size
)
135 mem
= rte_realloc(priv
->reta_idx
,
136 reta_size
* sizeof((*priv
->reta_idx
)[0]), 0);
141 priv
->reta_idx
= mem
;
142 priv
->reta_idx_n
= reta_size
;
143 if (old_size
< reta_size
)
144 memset(&(*priv
->reta_idx
)[old_size
], 0,
145 (reta_size
- old_size
) *
146 sizeof((*priv
->reta_idx
)[0]));
151 * DPDK callback to get the RETA indirection table.
154 * Pointer to Ethernet device structure.
156 * Pointer to RETA configuration structure array.
158 * Size of the RETA table.
161 * 0 on success, a negative errno value otherwise and rte_errno is set.
164 mlx5_dev_rss_reta_query(struct rte_eth_dev
*dev
,
165 struct rte_eth_rss_reta_entry64
*reta_conf
,
168 struct mlx5_priv
*priv
= dev
->data
->dev_private
;
172 if (!reta_size
|| reta_size
> priv
->reta_idx_n
) {
176 /* Fill each entry of the table even if its bit is not set. */
177 for (idx
= 0, i
= 0; (i
!= reta_size
); ++i
) {
178 idx
= i
/ RTE_RETA_GROUP_SIZE
;
179 reta_conf
[idx
].reta
[i
% RTE_RETA_GROUP_SIZE
] =
180 (*priv
->reta_idx
)[i
];
186 * DPDK callback to update the RETA indirection table.
189 * Pointer to Ethernet device structure.
191 * Pointer to RETA configuration structure array.
193 * Size of the RETA table.
196 * 0 on success, a negative errno value otherwise and rte_errno is set.
199 mlx5_dev_rss_reta_update(struct rte_eth_dev
*dev
,
200 struct rte_eth_rss_reta_entry64
*reta_conf
,
204 struct mlx5_priv
*priv
= dev
->data
->dev_private
;
213 ret
= mlx5_rss_reta_index_resize(dev
, reta_size
);
216 for (idx
= 0, i
= 0; (i
!= reta_size
); ++i
) {
217 idx
= i
/ RTE_RETA_GROUP_SIZE
;
218 pos
= i
% RTE_RETA_GROUP_SIZE
;
219 if (((reta_conf
[idx
].mask
>> i
) & 0x1) == 0)
221 assert(reta_conf
[idx
].reta
[pos
] < priv
->rxqs_n
);
222 (*priv
->reta_idx
)[i
] = reta_conf
[idx
].reta
[pos
];
224 if (dev
->data
->dev_started
) {
226 return mlx5_dev_start(dev
);