int err = 0;
struct ibv_context *attr_ctx = NULL;
struct ibv_device_attr device_attr;
+ struct ibv_device_attr_ex device_attr_ex;
struct mlx4_conf conf = {
.ports.present = 0,
};
/* Use all ports when none are defined */
if (!conf.ports.enabled)
conf.ports.enabled = conf.ports.present;
+ /* Retrieve extended device attributes. */
+ if (ibv_query_device_ex(attr_ctx, NULL, &device_attr_ex)) {
+ rte_errno = ENODEV;
+ goto error;
+ }
for (i = 0; i < device_attr.phys_port_cnt; i++) {
uint32_t port = i + 1; /* ports are indexed from one */
struct ibv_context *ctx = NULL;
PCI_DEVICE_ID_MELLANOX_CONNECTX3PRO);
DEBUG("L2 tunnel checksum offloads are %ssupported",
(priv->hw_csum_l2tun ? "" : "not "));
+ priv->hw_rss_sup = device_attr_ex.rss_caps.rx_hash_fields_mask;
+ if (!priv->hw_rss_sup) {
+ WARN("no RSS capabilities reported; disabling support"
+ " for UDP RSS");
+ /* Fake support for all possible RSS hash fields. */
+ priv->hw_rss_sup = ~UINT64_C(0);
+ priv->hw_rss_sup = mlx4_conv_rss_hf(priv, -1);
+ /* Filter out known unsupported fields. */
+ priv->hw_rss_sup &=
+ ~(uint64_t)(IBV_RX_HASH_SRC_PORT_UDP |
+ IBV_RX_HASH_DST_PORT_UDP);
+ }
+ DEBUG("supported RSS hash fields mask: %016" PRIx64,
+ priv->hw_rss_sup);
/* Configure the first MAC address by default. */
if (mlx4_get_mac(priv, &mac.addr_bytes)) {
ERROR("cannot get MAC address, is mlx4_en loaded?"
uint32_t isolated:1; /**< Toggle isolated mode. */
uint32_t hw_csum:1; /**< Checksum offload is supported. */
uint32_t hw_csum_l2tun:1; /**< Checksum support for L2 tunnels. */
+ uint64_t hw_rss_sup; /**< Supported RSS hash fields (Verbs format). */
struct rte_intr_handle intr_handle; /**< Port interrupt handle. */
struct mlx4_drop *drop; /**< Shared resources for drop flow rules. */
LIST_HEAD(, mlx4_rss) rss; /**< Shared targets for Rx flow rules. */
* This function returns the supported (default) set when @p rss_hf has
* special value (uint64_t)-1.
*
+ * @param priv
+ * Pointer to private structure.
* @param rss_hf
* Hash fields in DPDK format (see struct rte_eth_rss_conf).
*
* A valid Verbs RSS hash fields mask for mlx4 on success, (uint64_t)-1
* otherwise and rte_errno is set.
*/
-static uint64_t
-mlx4_conv_rss_hf(uint64_t rss_hf)
+uint64_t
+mlx4_conv_rss_hf(struct priv *priv, uint64_t rss_hf)
{
enum { IPV4, IPV6, TCP, UDP, };
const uint64_t in[] = {
[TCP] = (ETH_RSS_NONFRAG_IPV4_TCP |
ETH_RSS_NONFRAG_IPV6_TCP |
ETH_RSS_IPV6_TCP_EX),
- /*
- * UDP support is temporarily disabled due to an
- * implementation issue in the kernel.
- */
- [UDP] = 0,
+ [UDP] = (ETH_RSS_NONFRAG_IPV4_UDP |
+ ETH_RSS_NONFRAG_IPV6_UDP |
+ ETH_RSS_IPV6_UDP_EX),
};
const uint64_t out[RTE_DIM(in)] = {
[IPV4] = IBV_RX_HASH_SRC_IPV4 | IBV_RX_HASH_DST_IPV4,
seen |= rss_hf & in[i];
conv |= out[i];
}
- if (rss_hf == (uint64_t)-1)
- return conv;
- if (!(rss_hf & ~seen))
- return conv;
+ if ((conv & priv->hw_rss_sup) == conv) {
+ if (rss_hf == (uint64_t)-1)
+ return conv;
+ if (!(rss_hf & ~seen))
+ return conv;
+ }
rte_errno = ENOTSUP;
return (uint64_t)-1;
}
goto exit_action_not_supported;
}
flow->rss = mlx4_rss_get
- (priv, mlx4_conv_rss_hf(rss_conf->rss_hf),
+ (priv,
+ mlx4_conv_rss_hf(priv, rss_conf->rss_hf),
rss_conf->rss_key, rss->num, rss->queue);
if (!flow->rss) {
msg = "either invalid parameters or not enough"
/* mlx4_flow.c */
+uint64_t mlx4_conv_rss_hf(struct priv *priv, uint64_t rss_hf);
int mlx4_flow_sync(struct priv *priv, struct rte_flow_error *error);
void mlx4_flow_clean(struct priv *priv);
int mlx4_filter_ctrl(struct rte_eth_dev *dev,