i40e/base: fix proxy for X722
[dpdk.git] / drivers / net / mlx5 / mlx5_rxmode.c
index 79e31fb..096fd18 100644 (file)
@@ -73,21 +73,18 @@ static void hash_rxq_allmulticast_disable(struct hash_rxq *);
 static int
 hash_rxq_promiscuous_enable(struct hash_rxq *hash_rxq)
 {
-       struct ibv_flow *flow;
-       struct ibv_flow_attr attr = {
-               .type = IBV_FLOW_ATTR_ALL_DEFAULT,
-               .num_of_specs = 0,
-               .port = hash_rxq->priv->port,
-               .flags = 0
-       };
+       struct ibv_exp_flow *flow;
+       FLOW_ATTR_SPEC_ETH(data, hash_rxq_flow_attr(hash_rxq, NULL, 0));
+       struct ibv_exp_flow_attr *attr = &data->attr;
 
-       if (hash_rxq->priv->vf)
-               return 0;
        if (hash_rxq->promisc_flow != NULL)
                return 0;
        DEBUG("%p: enabling promiscuous mode", (void *)hash_rxq);
+       /* Promiscuous flows only differ from normal flows by not filtering
+        * on specific MAC addresses. */
+       hash_rxq_flow_attr(hash_rxq, attr, sizeof(data));
        errno = 0;
-       flow = ibv_create_flow(hash_rxq->qp, &attr);
+       flow = ibv_exp_create_flow(hash_rxq->qp, attr);
        if (flow == NULL) {
                /* It's not clear whether errno is always set in this case. */
                ERROR("%p: flow configuration failed, errno=%d: %s",
@@ -116,6 +113,8 @@ priv_promiscuous_enable(struct priv *priv)
 {
        unsigned int i;
 
+       if (!priv_allow_flow_type(priv, HASH_RXQ_FLOW_TYPE_PROMISC))
+               return 0;
        for (i = 0; (i != priv->hash_rxqs_n); ++i) {
                struct hash_rxq *hash_rxq = &(*priv->hash_rxqs)[i];
                int ret;
@@ -150,6 +149,10 @@ mlx5_promiscuous_enable(struct rte_eth_dev *dev)
        ret = priv_promiscuous_enable(priv);
        if (ret)
                ERROR("cannot enable promiscuous mode: %s", strerror(ret));
+       else {
+               priv_mac_addrs_disable(priv);
+               priv_allmulticast_disable(priv);
+       }
        priv_unlock(priv);
 }
 
@@ -162,12 +165,10 @@ mlx5_promiscuous_enable(struct rte_eth_dev *dev)
 static void
 hash_rxq_promiscuous_disable(struct hash_rxq *hash_rxq)
 {
-       if (hash_rxq->priv->vf)
-               return;
        if (hash_rxq->promisc_flow == NULL)
                return;
        DEBUG("%p: disabling promiscuous mode", (void *)hash_rxq);
-       claim_zero(ibv_destroy_flow(hash_rxq->promisc_flow));
+       claim_zero(ibv_exp_destroy_flow(hash_rxq->promisc_flow));
        hash_rxq->promisc_flow = NULL;
        DEBUG("%p: promiscuous mode disabled", (void *)hash_rxq);
 }
@@ -201,6 +202,8 @@ mlx5_promiscuous_disable(struct rte_eth_dev *dev)
        priv_lock(priv);
        priv->promisc_req = 0;
        priv_promiscuous_disable(priv);
+       priv_mac_addrs_enable(priv);
+       priv_allmulticast_enable(priv);
        priv_unlock(priv);
 }
 
@@ -216,19 +219,32 @@ mlx5_promiscuous_disable(struct rte_eth_dev *dev)
 static int
 hash_rxq_allmulticast_enable(struct hash_rxq *hash_rxq)
 {
-       struct ibv_flow *flow;
-       struct ibv_flow_attr attr = {
-               .type = IBV_FLOW_ATTR_MC_DEFAULT,
-               .num_of_specs = 0,
-               .port = hash_rxq->priv->port,
-               .flags = 0
-       };
+       struct ibv_exp_flow *flow;
+       FLOW_ATTR_SPEC_ETH(data, hash_rxq_flow_attr(hash_rxq, NULL, 0));
+       struct ibv_exp_flow_attr *attr = &data->attr;
+       struct ibv_exp_flow_spec_eth *spec = &data->spec;
 
        if (hash_rxq->allmulti_flow != NULL)
                return 0;
        DEBUG("%p: enabling allmulticast mode", (void *)hash_rxq);
+       /*
+        * No padding must be inserted by the compiler between attr and spec.
+        * This layout is expected by libibverbs.
+        */
+       assert(((uint8_t *)attr + sizeof(*attr)) == (uint8_t *)spec);
+       hash_rxq_flow_attr(hash_rxq, attr, sizeof(data));
+       *spec = (struct ibv_exp_flow_spec_eth){
+               .type = IBV_EXP_FLOW_SPEC_ETH,
+               .size = sizeof(*spec),
+               .val = {
+                       .dst_mac = "\x01\x00\x00\x00\x00\x00",
+               },
+               .mask = {
+                       .dst_mac = "\x01\x00\x00\x00\x00\x00",
+               },
+       };
        errno = 0;
-       flow = ibv_create_flow(hash_rxq->qp, &attr);
+       flow = ibv_exp_create_flow(hash_rxq->qp, attr);
        if (flow == NULL) {
                /* It's not clear whether errno is always set in this case. */
                ERROR("%p: flow configuration failed, errno=%d: %s",
@@ -258,6 +274,8 @@ priv_allmulticast_enable(struct priv *priv)
 {
        unsigned int i;
 
+       if (!priv_allow_flow_type(priv, HASH_RXQ_FLOW_TYPE_ALLMULTI))
+               return 0;
        for (i = 0; (i != priv->hash_rxqs_n); ++i) {
                struct hash_rxq *hash_rxq = &(*priv->hash_rxqs)[i];
                int ret;
@@ -310,7 +328,7 @@ hash_rxq_allmulticast_disable(struct hash_rxq *hash_rxq)
        if (hash_rxq->allmulti_flow == NULL)
                return;
        DEBUG("%p: disabling allmulticast mode", (void *)hash_rxq);
-       claim_zero(ibv_destroy_flow(hash_rxq->allmulti_flow));
+       claim_zero(ibv_exp_destroy_flow(hash_rxq->allmulti_flow));
        hash_rxq->allmulti_flow = NULL;
        DEBUG("%p: allmulticast mode disabled", (void *)hash_rxq);
 }