net/mlx5e: Add support to get ethtool flow rules
authorMaor Gottlieb <maorg@mellanox.com>
Mon, 4 Jul 2016 14:23:10 +0000 (17:23 +0300)
committerDavid S. Miller <davem@davemloft.net>
Tue, 5 Jul 2016 07:06:03 +0000 (00:06 -0700)
Enhance the existing get_rxnfc callback:
1. Get flow rule of specific ID.
2. Get all flow rules.
3. Get number of rules.

Signed-off-by: Maor Gottlieb <maorg@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlx5/core/en.h
drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c

index 9842594f5980448bb923c6cc6aec42b68e4852b1..1365cdc81838dcb3f7b6094a9a979658a44b6eef 100644 (file)
@@ -717,6 +717,10 @@ int mlx5e_create_flow_steering(struct mlx5e_priv *priv);
 void mlx5e_destroy_flow_steering(struct mlx5e_priv *priv);
 void mlx5e_init_l2_addr(struct mlx5e_priv *priv);
 void mlx5e_destroy_flow_table(struct mlx5e_flow_table *ft);
+int mlx5e_ethtool_get_flow(struct mlx5e_priv *priv, struct ethtool_rxnfc *info,
+                          int location);
+int mlx5e_ethtool_get_all_flows(struct mlx5e_priv *priv,
+                               struct ethtool_rxnfc *info, u32 *rule_locs);
 int mlx5e_ethtool_flow_replace(struct mlx5e_priv *priv,
                               struct ethtool_rx_flow_spec *fs);
 int mlx5e_ethtool_flow_remove(struct mlx5e_priv *priv,
index edbb665f4d22a7686b4dae6616bfb225945a84e0..d652aa917130816f564819d58254f12260153689 100644 (file)
@@ -931,6 +931,15 @@ static int mlx5e_get_rxnfc(struct net_device *netdev,
        case ETHTOOL_GRXRINGS:
                info->data = priv->params.num_channels;
                break;
+       case ETHTOOL_GRXCLSRLCNT:
+               info->rule_cnt = priv->fs.ethtool.tot_num_rules;
+               break;
+       case ETHTOOL_GRXCLSRULE:
+               err = mlx5e_ethtool_get_flow(priv, info, info->fs.location);
+               break;
+       case ETHTOOL_GRXCLSRLALL:
+               err = mlx5e_ethtool_get_all_flows(priv, info, rule_locs);
+               break;
        default:
                err = -EOPNOTSUPP;
                break;
index 830106ede872ba4eafc88d5198682f6e391bdb71..d17c242279003bcc5a867b464c6f531c2fd6ff7e 100644 (file)
@@ -537,6 +537,40 @@ out:
        return err;
 }
 
+int mlx5e_ethtool_get_flow(struct mlx5e_priv *priv, struct ethtool_rxnfc *info,
+                          int location)
+{
+       struct mlx5e_ethtool_rule *eth_rule;
+
+       if (location < 0 || location >= MAX_NUM_OF_ETHTOOL_RULES)
+               return -EINVAL;
+
+       list_for_each_entry(eth_rule, &priv->fs.ethtool.rules, list) {
+               if (eth_rule->flow_spec.location == location) {
+                       info->fs = eth_rule->flow_spec;
+                       return 0;
+               }
+       }
+
+       return -ENOENT;
+}
+
+int mlx5e_ethtool_get_all_flows(struct mlx5e_priv *priv, struct ethtool_rxnfc *info,
+                               u32 *rule_locs)
+{
+       int location = 0;
+       int idx = 0;
+       int err = 0;
+
+       while ((!err || err == -ENOENT) && idx < info->rule_cnt) {
+               err = mlx5e_ethtool_get_flow(priv, info, location);
+               if (!err)
+                       rule_locs[idx++] = location;
+               location++;
+       }
+       return err;
+}
+
 void mlx5e_ethtool_cleanup_steering(struct mlx5e_priv *priv)
 {
        struct mlx5e_ethtool_rule *iter;