net/enic: support drop flow action
authorHyong Youb Kim <hyonkim@cisco.com>
Wed, 4 Apr 2018 23:54:54 +0000 (16:54 -0700)
committerFerruh Yigit <ferruh.yigit@intel.com>
Fri, 13 Apr 2018 22:41:44 +0000 (00:41 +0200)
1330 and 1400 series adapters support the drop action. Check for its
availability and set the necessary flag when creating NIC filters.

Signed-off-by: Hyong Youb Kim <hyonkim@cisco.com>
Reviewed-by: John Daley <johndale@cisco.com>
doc/guides/nics/enic.rst
drivers/net/enic/base/vnic_dev.c
drivers/net/enic/base/vnic_dev.h
drivers/net/enic/base/vnic_devcmd.h
drivers/net/enic/enic.h
drivers/net/enic/enic_flow.c
drivers/net/enic/enic_res.c

index bbf18ac..b8cfac4 100644 (file)
@@ -247,7 +247,7 @@ Generic Flow API is supported. The baseline support is:
 
   - Attributes: ingress
   - Items: eth, ipv4, ipv6, udp, tcp, vxlan, inner eth, ipv4, ipv6, udp, tcp
-  - Actions: queue, mark, flag and void
+  - Actions: queue, mark, drop, flag and void
   - Selectors: 'is', 'spec' and 'mask'. 'last' is not supported
   - In total, up to 64 bytes of mask is allowed across all headers
 
index eccbb30..364458a 100644 (file)
@@ -485,7 +485,7 @@ int vnic_dev_capable_adv_filters(struct vnic_dev *vdev)
  *   Retrun true in filter_tags if supported
  */
 int vnic_dev_capable_filter_mode(struct vnic_dev *vdev, u32 *mode,
-                                u8 *filter_tags)
+                                u8 *filter_actions)
 {
        u64 args[4];
        int err;
@@ -493,14 +493,10 @@ int vnic_dev_capable_filter_mode(struct vnic_dev *vdev, u32 *mode,
 
        err = vnic_dev_advanced_filters_cap(vdev, args, 4);
 
-       /* determine if filter tags are available */
-       if (err)
-               *filter_tags = 0;
-       if ((args[2] == FILTER_CAP_MODE_V1) &&
-           (args[3] & FILTER_ACTION_FILTER_ID_FLAG))
-               *filter_tags = 1;
-       else
-               *filter_tags = 0;
+       /* determine supported filter actions */
+       *filter_actions = FILTER_ACTION_RQ_STEERING_FLAG; /* always available */
+       if (args[2] == FILTER_CAP_MODE_V1)
+               *filter_actions = args[3];
 
        if (err || ((args[0] == 1) && (args[1] == 0))) {
                /* Adv filter Command not supported or adv filters available but
index fb3dd3c..90833c7 100644 (file)
@@ -108,7 +108,7 @@ int vnic_dev_fw_info(struct vnic_dev *vdev,
 int vnic_dev_capable_adv_filters(struct vnic_dev *vdev);
 int vnic_dev_capable(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd);
 int vnic_dev_capable_filter_mode(struct vnic_dev *vdev, u32 *mode,
-                                u8 *filter_tags);
+                                u8 *filter_actions);
 int vnic_dev_capable_udp_rss(struct vnic_dev *vdev);
 int vnic_dev_asic_info(struct vnic_dev *vdev, u16 *asic_type, u16 *asic_rev);
 int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, size_t size,
index a636245..2294b55 100644 (file)
@@ -841,7 +841,9 @@ struct filter_action {
 
 #define FILTER_ACTION_RQ_STEERING_FLAG (1 << 0)
 #define FILTER_ACTION_FILTER_ID_FLAG   (1 << 1)
+#define FILTER_ACTION_DROP_FLAG                (1 << 2)
 #define FILTER_ACTION_V2_ALL           (FILTER_ACTION_RQ_STEERING_FLAG \
+                                        | FILTER_ACTION_DROP_FLAG \
                                         | FILTER_ACTION_FILTER_ID_FLAG)
 
 /* Version 2 of filter action must be a strict extension of struct filter_action
index adccc8a..751ddc7 100644 (file)
@@ -118,7 +118,7 @@ struct enic {
        u16 max_mtu;
        u8 adv_filters;
        u32 flow_filter_mode;
-       u8 filter_tags;
+       u8 filter_actions; /* HW supported actions */
 
        unsigned int flags;
        unsigned int priv_flags;
index 28923b0..b9f3658 100644 (file)
@@ -273,21 +273,33 @@ static const enum rte_flow_action_type enic_supported_actions_v1[] = {
 };
 
 /** Supported actions for newer NICs */
-static const enum rte_flow_action_type enic_supported_actions_v2[] = {
+static const enum rte_flow_action_type enic_supported_actions_v2_id[] = {
        RTE_FLOW_ACTION_TYPE_QUEUE,
        RTE_FLOW_ACTION_TYPE_MARK,
        RTE_FLOW_ACTION_TYPE_FLAG,
        RTE_FLOW_ACTION_TYPE_END,
 };
 
+static const enum rte_flow_action_type enic_supported_actions_v2_drop[] = {
+       RTE_FLOW_ACTION_TYPE_QUEUE,
+       RTE_FLOW_ACTION_TYPE_MARK,
+       RTE_FLOW_ACTION_TYPE_FLAG,
+       RTE_FLOW_ACTION_TYPE_DROP,
+       RTE_FLOW_ACTION_TYPE_END,
+};
+
 /** Action capabilities indexed by NIC version information */
 static const struct enic_action_cap enic_action_cap[] = {
        [FILTER_ACTION_RQ_STEERING_FLAG] = {
                .actions = enic_supported_actions_v1,
                .copy_fn = enic_copy_action_v1,
        },
-       [FILTER_ACTION_V2_ALL] = {
-               .actions = enic_supported_actions_v2,
+       [FILTER_ACTION_FILTER_ID_FLAG] = {
+               .actions = enic_supported_actions_v2_id,
+               .copy_fn = enic_copy_action_v2,
+       },
+       [FILTER_ACTION_DROP_FLAG] = {
+               .actions = enic_supported_actions_v2_drop,
                .copy_fn = enic_copy_action_v2,
        },
 };
@@ -1021,6 +1033,10 @@ enic_copy_action_v2(const struct rte_flow_action actions[],
                        enic_action->flags |= FILTER_ACTION_FILTER_ID_FLAG;
                        break;
                }
+               case RTE_FLOW_ACTION_TYPE_DROP: {
+                       enic_action->flags |= FILTER_ACTION_DROP_FLAG;
+                       break;
+               }
                case RTE_FLOW_ACTION_TYPE_VOID:
                        continue;
                default:
@@ -1059,10 +1075,14 @@ enic_get_filter_cap(struct enic *enic)
 static const struct enic_action_cap *
 enic_get_action_cap(struct enic *enic)
 {
-       static const struct enic_action_cap *ea;
-
-       if (enic->filter_tags)
-               ea = &enic_action_cap[FILTER_ACTION_V2_ALL];
+       const struct enic_action_cap *ea;
+       uint8_t actions;
+
+       actions = enic->filter_actions;
+       if (actions & FILTER_ACTION_DROP_FLAG)
+               ea = &enic_action_cap[FILTER_ACTION_DROP_FLAG];
+       else if (actions & FILTER_ACTION_FILTER_ID_FLAG)
+               ea = &enic_action_cap[FILTER_ACTION_FILTER_ID_FLAG];
        else
                ea = &enic_action_cap[FILTER_ACTION_RQ_STEERING_FLAG];
        return ea;
index abe6929..9b5baf3 100644 (file)
@@ -76,19 +76,24 @@ int enic_get_vnic_config(struct enic *enic)
                 ? "" : "not "));
 
        err = vnic_dev_capable_filter_mode(enic->vdev, &enic->flow_filter_mode,
-                                          &enic->filter_tags);
+                                          &enic->filter_actions);
        if (err) {
                dev_err(enic_get_dev(enic),
                        "Error getting filter modes, %d\n", err);
                return err;
        }
 
-       dev_info(enic, "Flow api filter mode: %s, Filter tagging %savailable\n",
+       dev_info(enic, "Flow api filter mode: %s Actions: %s%s%s\n",
                ((enic->flow_filter_mode == FILTER_DPDK_1) ? "DPDK" :
                ((enic->flow_filter_mode == FILTER_USNIC_IP) ? "USNIC" :
                ((enic->flow_filter_mode == FILTER_IPV4_5TUPLE) ? "5TUPLE" :
                "NONE"))),
-               ((enic->filter_tags) ? "" : "not "));
+               ((enic->filter_actions & FILTER_ACTION_RQ_STEERING_FLAG) ?
+                "steer " : ""),
+               ((enic->filter_actions & FILTER_ACTION_FILTER_ID_FLAG) ?
+                "tag " : ""),
+               ((enic->filter_actions & FILTER_ACTION_DROP_FLAG) ?
+                "drop " : ""));
 
        c->wq_desc_count =
                min_t(u32, ENIC_MAX_WQ_DESCS,