This patch adds the new phy affinity item support in PMD:
RTE_FLOW_ITEM_TYPE_PHY_AFFINITY.

This patch adds the validation function for the new item,
it works for NIC-RX and FDB rule on ROOT-table only.

Signed-off-by: Jiawei Wang <jiaw...@nvidia.com>
---
 doc/guides/nics/features/default.ini |   1 +
 doc/guides/nics/features/mlx5.ini    |   1 +
 doc/guides/nics/mlx5.rst             |   8 ++-
 drivers/net/mlx5/linux/mlx5_os.c     |   2 +
 drivers/net/mlx5/mlx5.h              |   1 +
 drivers/net/mlx5/mlx5_flow.h         |   3 +
 drivers/net/mlx5/mlx5_flow_dv.c      | 100 ++++++++++++++++++++++++++-
 drivers/net/mlx5/mlx5_flow_hw.c      |  14 ++++
 8 files changed, 127 insertions(+), 3 deletions(-)

diff --git a/doc/guides/nics/features/default.ini 
b/doc/guides/nics/features/default.ini
index 510cc6679d..fd5edd11c8 100644
--- a/doc/guides/nics/features/default.ini
+++ b/doc/guides/nics/features/default.ini
@@ -141,6 +141,7 @@ udp                  =
 vlan                 =
 vxlan                =
 vxlan_gpe            =
+phy_affinity         =
 
 [rte_flow actions]
 age                  =
diff --git a/doc/guides/nics/features/mlx5.ini 
b/doc/guides/nics/features/mlx5.ini
index 62fd330e2b..9142f04f93 100644
--- a/doc/guides/nics/features/mlx5.ini
+++ b/doc/guides/nics/features/mlx5.ini
@@ -87,6 +87,7 @@ vlan                 = Y
 vxlan                = Y
 vxlan_gpe            = Y
 represented_port     = Y
+phy_affinity         = Y
 
 [rte_flow actions]
 age                  = I
diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst
index f137f156f9..5569b045d7 100644
--- a/doc/guides/nics/mlx5.rst
+++ b/doc/guides/nics/mlx5.rst
@@ -106,6 +106,7 @@ Features
 - Sub-Function representors.
 - Sub-Function.
 - Matching on represented port.
+- Matching on phy affinity.
 
 
 Limitations
@@ -595,13 +596,18 @@ Limitations
   - key
   - sequence
 
-  Matching on checksum and sequence needs MLNX_OFED 5.6+.
+- Matching on checksum and sequence needs MLNX_OFED 5.6+.
 
 - The NIC egress flow rules on representor port are not supported.
 
 - When using DV/verbs flow engine (``dv_flow_en`` = 1/0 respectively), Match 
on SPI field
   in ESP header for group 0 needs MLNX_OFED 5.6+.
 
+- Match on phy affinity:
+
+  - Supports NIC ingress flow in group 0.
+  - Supports E-Switch flow in group 0 and depends on
+    device-managed flow steering (DMFS) mode.
 
 Statistics
 ----------
diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index 60462da39d..1c26b30702 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -1394,6 +1394,8 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
                        sh->lag_rx_port_affinity_en = 1;
                        DRV_LOG(DEBUG, "LAG Rx Port Affinity enabled");
                }
+               priv->num_lag_ports = hca_attr->num_lag_ports;
+               DRV_LOG(DEBUG, "The number of lag ports is %d", 
priv->num_lag_ports);
        }
        /* Process parameters and store port configuration on priv structure. */
        err = mlx5_port_args_config(priv, mkvlist, &priv->config);
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index bbd7262a51..c7a7b176b8 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -1668,6 +1668,7 @@ struct mlx5_priv {
        unsigned int mtr_reg_share:1; /* Whether support meter REG_C share. */
        unsigned int lb_used:1; /* Loopback queue is referred to. */
        uint32_t mark_enabled:1; /* If mark action is enabled on rxqs. */
+       uint32_t num_lag_ports:4; /* Number of ports can be bonded. */
        uint16_t domain_id; /* Switch domain identifier. */
        uint16_t vport_id; /* Associated VF vport index (if any). */
        uint32_t vport_meta_tag; /* Used for vport index match ove VF LAG. */
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index e376dcae93..64b1b7c37c 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -219,6 +219,9 @@ enum mlx5_feature_name {
 /* Meter color item */
 #define MLX5_FLOW_ITEM_METER_COLOR (UINT64_C(1) << 44)
 
+/* PHY affinity item */
+#define MLX5_FLOW_ITEM_PHY_AFFINITY (UINT64_C(1) << 49)
+
 /* Outer Masks. */
 #define MLX5_FLOW_LAYER_OUTER_L3 \
        (MLX5_FLOW_LAYER_OUTER_L3_IPV4 | MLX5_FLOW_LAYER_OUTER_L3_IPV6)
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 7ca909999b..994f184aaf 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -3764,6 +3764,75 @@ flow_dv_validate_item_meter_color(struct rte_eth_dev 
*dev,
        return 0;
 }
 
+/**
+ * Validate Phy affinity item.
+ *
+ * @param[in] dev
+ *   Pointer to the rte_eth_dev structure.
+ * @param[in] item
+ *   Item specification.
+ * @param[in] attr
+ *   Attributes of flow that includes this item.
+ * @param[out] error
+ *   Pointer to error structure.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+flow_dv_validate_item_phy_affinity(struct rte_eth_dev *dev,
+                                  const struct rte_flow_item *item,
+                                  const struct rte_flow_attr *attr,
+                                  struct rte_flow_error *error)
+{
+       struct mlx5_priv *priv = dev->data->dev_private;
+       const struct rte_flow_item_phy_affinity *spec = item->spec;
+       const struct rte_flow_item_phy_affinity *mask = item->mask;
+       struct rte_flow_item_phy_affinity nic_mask = {
+               .affinity = UINT8_MAX
+       };
+       int ret;
+
+       if (!priv->sh->lag_rx_port_affinity_en)
+               return rte_flow_error_set(error, EINVAL,
+                                         RTE_FLOW_ERROR_TYPE_ITEM, NULL,
+                                         "Unsupported phy affinity with Older 
FW");
+       if ((attr->transfer && priv->fdb_def_rule) ||
+           attr->egress || attr->group)
+               return rte_flow_error_set(error, ENOTSUP,
+                                         RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
+                                         item->spec,
+                                         "phy affinity is not supported with 
egress or FDB on non root table");
+       if (!spec)
+               return rte_flow_error_set(error, EINVAL,
+                                         RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
+                                         item->spec,
+                                         "data cannot be empty");
+       if (spec->affinity == 0)
+               return rte_flow_error_set(error, ENOTSUP,
+                                         RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
+                                         item->spec,
+                                         "zero affinity number not supported");
+       if (spec->affinity > priv->num_lag_ports)
+               return rte_flow_error_set(error, ENOTSUP,
+                                         RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
+                                         item->spec,
+                                         "exceed max affinity number in lag 
ports");
+       if (!mask)
+               mask = &rte_flow_item_phy_affinity_mask;
+       if (!mask->affinity)
+               return rte_flow_error_set(error, EINVAL,
+                                         RTE_FLOW_ERROR_TYPE_ITEM_SPEC, NULL,
+                                         "mask cannot be zero");
+       ret = mlx5_flow_item_acceptable(item, (const uint8_t *)mask,
+                               (const uint8_t *)&nic_mask,
+                               sizeof(struct rte_flow_item_phy_affinity),
+                               MLX5_ITEM_RANGE_NOT_ACCEPTED, error);
+       if (ret < 0)
+               return ret;
+       return 0;
+}
+
 int
 flow_dv_encap_decap_match_cb(void *tool_ctx __rte_unused,
                             struct mlx5_list_entry *entry, void *cb_ctx)
@@ -7443,6 +7512,13 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct 
rte_flow_attr *attr,
                                return ret;
                        last_item = MLX5_FLOW_ITEM_METER_COLOR;
                        break;
+               case RTE_FLOW_ITEM_TYPE_PHY_AFFINITY:
+                       ret = flow_dv_validate_item_phy_affinity(dev, items,
+                                                                attr, error);
+                       if (ret < 0)
+                               return ret;
+                       last_item = MLX5_FLOW_ITEM_PHY_AFFINITY;
+                       break;
                default:
                        return rte_flow_error_set(error, ENOTSUP,
                                                  RTE_FLOW_ERROR_TYPE_ITEM,
@@ -9981,7 +10057,7 @@ flow_dv_translate_item_tag(struct rte_eth_dev *dev, void 
*key,
        const struct rte_flow_item_tag *tag_vv = item->spec;
        const struct rte_flow_item_tag *tag_v;
        const struct rte_flow_item_tag *tag_m;
-       enum modify_reg reg;
+       int reg;
        uint32_t index;
 
        if (MLX5_ITEM_VALID(item, key_type))
@@ -9996,7 +10072,7 @@ flow_dv_translate_item_tag(struct rte_eth_dev *dev, void 
*key,
        else
                reg = flow_hw_get_reg_id(RTE_FLOW_ITEM_TYPE_TAG, index);
        MLX5_ASSERT(reg > 0);
-       flow_dv_match_meta_reg(key, reg, tag_v->data, tag_m->data);
+       flow_dv_match_meta_reg(key, (enum modify_reg)reg, tag_v->data, 
tag_m->data);
 }
 
 /**
@@ -10639,6 +10715,22 @@ flow_dv_translate_item_meter_color(struct rte_eth_dev 
*dev, void *key,
        flow_dv_match_meta_reg(key, (enum modify_reg)reg, value, mask);
 }
 
+static void
+flow_dv_translate_item_phy_affinity(void *key,
+                                   const struct rte_flow_item *item,
+                                   uint32_t key_type)
+{
+       const struct rte_flow_item_phy_affinity *affinity_v;
+       const struct rte_flow_item_phy_affinity *affinity_m;
+       void *misc_v;
+
+       MLX5_ITEM_UPDATE(item, key_type, affinity_v, affinity_m,
+                        &rte_flow_item_phy_affinity_mask);
+       misc_v = MLX5_ADDR_OF(fte_match_param, key, misc_parameters);
+       MLX5_SET(fte_match_set_misc, misc_v, lag_rx_port_affinity,
+                affinity_v->affinity & affinity_m->affinity);
+}
+
 static uint32_t matcher_zero[MLX5_ST_SZ_DW(fte_match_param)] = { 0 };
 
 #define HEADER_IS_ZERO(match_criteria, headers)                                
     \
@@ -13430,6 +13522,10 @@ flow_dv_translate_items(struct rte_eth_dev *dev,
                last_item = flow_dv_translate_item_integrity(items,
                                                             wks, key_type);
                break;
+       case RTE_FLOW_ITEM_TYPE_PHY_AFFINITY:
+               flow_dv_translate_item_phy_affinity(key, items, key_type);
+               last_item = MLX5_FLOW_ITEM_PHY_AFFINITY;
+               break;
        default:
                break;
        }
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index 20c71ff7f0..e5ca86ca4b 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -4715,6 +4715,20 @@ flow_hw_pattern_validate(struct rte_eth_dev *dev,
                                                          "Unsupported meter 
color register");
                        break;
                }
+               case RTE_FLOW_ITEM_TYPE_PHY_AFFINITY:
+               {
+                       if (!priv->sh->lag_rx_port_affinity_en)
+                               return rte_flow_error_set(error, EINVAL,
+                                                         
RTE_FLOW_ERROR_TYPE_ITEM, NULL,
+                                                         "Unsupported phy 
affinity with Older FW");
+                       if ((attr->transfer && priv->fdb_def_rule) || 
attr->egress)
+                               return rte_flow_error_set(error, EINVAL,
+                                                         
RTE_FLOW_ERROR_TYPE_ITEM, NULL,
+                                                         "Phy affinity item 
not supported"
+                                                         " with egress or 
transfer"
+                                                         " attribute");
+                       break;
+               }
                case RTE_FLOW_ITEM_TYPE_VOID:
                case RTE_FLOW_ITEM_TYPE_ETH:
                case RTE_FLOW_ITEM_TYPE_VLAN:
-- 
2.18.1

Reply via email to