drivers/net: enable promiscuous and multicast by default
[dpdk.git] / drivers / net / i40e / i40e_flow.c
index d62b32f..9e038fa 100644 (file)
@@ -2442,6 +2442,7 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev,
        uint64_t input_set = I40E_INSET_NONE;
        uint16_t frag_off;
        enum rte_flow_item_type item_type;
+       enum rte_flow_item_type next_type;
        enum rte_flow_item_type l3 = RTE_FLOW_ITEM_TYPE_END;
        enum rte_flow_item_type cus_proto = RTE_FLOW_ITEM_TYPE_END;
        uint32_t i, j;
@@ -2482,6 +2483,16 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev,
                case RTE_FLOW_ITEM_TYPE_ETH:
                        eth_spec = item->spec;
                        eth_mask = item->mask;
+                       next_type = (item + 1)->type;
+
+                       if (next_type == RTE_FLOW_ITEM_TYPE_END &&
+                                               (!eth_spec || !eth_mask)) {
+                               rte_flow_error_set(error, EINVAL,
+                                                  RTE_FLOW_ERROR_TYPE_ITEM,
+                                                  item,
+                                                  "NULL eth spec/mask.");
+                               return -rte_errno;
+                       }
 
                        if (eth_spec && eth_mask) {
                                if (!rte_is_zero_ether_addr(&eth_mask->src) ||
@@ -2494,8 +2505,6 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev,
                                }
                        }
                        if (eth_spec && eth_mask && eth_mask->type) {
-                               enum rte_flow_item_type next = (item + 1)->type;
-
                                if (eth_mask->type != RTE_BE16(0xffff)) {
                                        rte_flow_error_set(error, EINVAL,
                                                      RTE_FLOW_ERROR_TYPE_ITEM,
@@ -2506,7 +2515,7 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev,
 
                                ether_type = rte_be_to_cpu_16(eth_spec->type);
 
-                               if (next == RTE_FLOW_ITEM_TYPE_VLAN ||
+                               if (next_type == RTE_FLOW_ITEM_TYPE_VLAN ||
                                    ether_type == RTE_ETHER_TYPE_IPV4 ||
                                    ether_type == RTE_ETHER_TYPE_IPV6 ||
                                    ether_type == RTE_ETHER_TYPE_ARP ||
@@ -3096,7 +3105,7 @@ i40e_flow_parse_fdir_action(struct rte_eth_dev *dev,
        NEXT_ITEM_OF_ACTION(act, actions, index);
        switch (act->type) {
        case RTE_FLOW_ACTION_TYPE_MARK:
-               if (!mark_spec) {
+               if (mark_spec) {
                        /* Double MARK actions requested */
                        rte_flow_error_set(error, EINVAL,
                           RTE_FLOW_ERROR_TYPE_ACTION, act,
@@ -3108,7 +3117,7 @@ i40e_flow_parse_fdir_action(struct rte_eth_dev *dev,
                filter->soft_id = mark_spec->id;
                break;
        case RTE_FLOW_ACTION_TYPE_FLAG:
-               if (!mark_spec) {
+               if (mark_spec) {
                        /* MARK + FLAG not supported */
                        rte_flow_error_set(error, EINVAL,
                                           RTE_FLOW_ERROR_TYPE_ACTION, act,
@@ -3175,8 +3184,8 @@ i40e_flow_parse_fdir_filter(struct rte_eth_dev *dev,
 
        cons_filter_type = RTE_ETH_FILTER_FDIR;
 
-       if (dev->data->dev_conf.fdir_conf.mode !=
-           RTE_FDIR_MODE_PERFECT) {
+       if (dev->data->dev_conf.fdir_conf.mode != RTE_FDIR_MODE_PERFECT ||
+               pf->fdir.fdir_vsi == NULL) {
                /* Enable fdir when fdir flow is added at first time. */
                ret = i40e_fdir_setup(pf);
                if (ret != I40E_SUCCESS) {
@@ -4762,10 +4771,11 @@ i40e_flow_destroy(struct rte_eth_dev *dev,
                       &((struct i40e_fdir_filter *)flow->rule)->fdir, 0);
 
                /* If the last flow is destroyed, disable fdir. */
-               if (!ret && !TAILQ_EMPTY(&pf->fdir.fdir_list)) {
+               if (!ret && TAILQ_EMPTY(&pf->fdir.fdir_list)) {
                        i40e_fdir_teardown(pf);
                        dev->data->dev_conf.fdir_conf.mode =
                                   RTE_FDIR_MODE_NONE;
+                       i40e_fdir_rx_proc_enable(dev, 0);
                }
                break;
        case RTE_ETH_FILTER_HASH:
@@ -4922,6 +4932,9 @@ i40e_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error)
                return -rte_errno;
        }
 
+       /* Disable FDIR processing as all FDIR rules are now flushed */
+       i40e_fdir_rx_proc_enable(dev, 0);
+
        return ret;
 }