net/sfc/base: rename firmware update verify result cap field
[dpdk.git] / drivers / net / mlx4 / mlx4_flow.c
index 5af6efb..8b87b29 100644 (file)
@@ -404,7 +404,7 @@ mlx4_flow_merge_udp(struct rte_flow *flow,
        struct ibv_flow_spec_tcp_udp *udp;
        const char *msg;
 
-       if (!mask ||
+       if (mask &&
            ((uint16_t)(mask->hdr.src_port + 1) > UINT16_C(1) ||
             (uint16_t)(mask->hdr.dst_port + 1) > UINT16_C(1))) {
                msg = "mlx4 does not support matching partial UDP fields";
@@ -464,7 +464,7 @@ mlx4_flow_merge_tcp(struct rte_flow *flow,
        struct ibv_flow_spec_tcp_udp *tcp;
        const char *msg;
 
-       if (!mask ||
+       if (mask &&
            ((uint16_t)(mask->hdr.src_port + 1) > UINT16_C(1) ||
             (uint16_t)(mask->hdr.dst_port + 1) > UINT16_C(1))) {
                msg = "mlx4 does not support matching partial TCP fields";
@@ -734,6 +734,11 @@ fill:
                        if (flow->rss)
                                break;
                        queue = action->conf;
+                       if (queue->index >= priv->dev->data->nb_rx_queues) {
+                               msg = "queue target index beyond number of"
+                                       " configured Rx queues";
+                               goto exit_action_not_supported;
+                       }
                        flow->rss = mlx4_rss_get
                                (priv, 0, mlx4_rss_hash_key_default, 1,
                                 &queue->index);
@@ -760,6 +765,15 @@ fill:
                                                   ETH_RSS_NONFRAG_IPV6_TCP),
                                };
                        /* Sanity checks. */
+                       for (i = 0; i < rss->num; ++i)
+                               if (rss->queue[i] >=
+                                   priv->dev->data->nb_rx_queues)
+                                       break;
+                       if (i != rss->num) {
+                               msg = "queue index target beyond number of"
+                                       " configured Rx queues";
+                               goto exit_action_not_supported;
+                       }
                        if (!rte_is_power_of_2(rss->num)) {
                                msg = "for RSS, mlx4 requires the number of"
                                        " queues to be a power of two";
@@ -1290,6 +1304,9 @@ mlx4_flow_internal(struct priv *priv, struct rte_flow_error *error)
        unsigned int i;
        int err = 0;
 
+       /* Nothing to be done if there are no Rx queues. */
+       if (!queues)
+               goto error;
        /* Prepare default RSS configuration. */
        *rss_conf = (struct rte_flow_action_rss){
                .rss_conf = NULL, /* Rely on default fallback settings. */
@@ -1339,6 +1356,7 @@ next_vlan:
                        assert(flow->ibv_attr->type == IBV_FLOW_ATTR_NORMAL);
                        assert(flow->ibv_attr->num_of_specs == 1);
                        assert(eth->type == IBV_FLOW_SPEC_ETH);
+                       assert(flow->rss);
                        if (rule_vlan &&
                            (eth->val.vlan_tag != *rule_vlan ||
                             eth->mask.vlan_tag != RTE_BE16(0x0fff)))
@@ -1351,8 +1369,13 @@ next_vlan:
                                    eth->val.src_mac[j] != UINT8_C(0x00) ||
                                    eth->mask.src_mac[j] != UINT8_C(0x00))
                                        break;
-                       if (j == sizeof(mac->addr_bytes))
-                               break;
+                       if (j != sizeof(mac->addr_bytes))
+                               continue;
+                       if (flow->rss->queues != queues ||
+                           memcmp(flow->rss->queue_id, rss_conf->queue,
+                                  queues * sizeof(flow->rss->queue_id[0])))
+                               continue;
+                       break;
                }
                if (!flow || !flow->internal) {
                        /* Not found, create a new flow rule. */
@@ -1386,6 +1409,13 @@ next_vlan:
                                        break;
                        }
                }
+               if (flow && flow->internal) {
+                       assert(flow->rss);
+                       if (flow->rss->queues != queues ||
+                           memcmp(flow->rss->queue_id, rss_conf->queue,
+                                  queues * sizeof(flow->rss->queue_id[0])))
+                               flow = NULL;
+               }
                if (!flow || !flow->internal) {
                        /* Not found, create a new flow rule. */
                        if (priv->dev->data->promiscuous) {