net/mlx5e: Add support to get ethtool flow rules

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>
This commit is contained in:
Maor Gottlieb 2016-07-04 17:23:10 +03:00 committed by David S. Miller
parent 1174fce8d1
commit f913a72aa0
3 changed files with 47 additions and 0 deletions

View 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_destroy_flow_steering(struct mlx5e_priv *priv);
void mlx5e_init_l2_addr(struct mlx5e_priv *priv); void mlx5e_init_l2_addr(struct mlx5e_priv *priv);
void mlx5e_destroy_flow_table(struct mlx5e_flow_table *ft); 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, int mlx5e_ethtool_flow_replace(struct mlx5e_priv *priv,
struct ethtool_rx_flow_spec *fs); struct ethtool_rx_flow_spec *fs);
int mlx5e_ethtool_flow_remove(struct mlx5e_priv *priv, int mlx5e_ethtool_flow_remove(struct mlx5e_priv *priv,

View File

@ -931,6 +931,15 @@ static int mlx5e_get_rxnfc(struct net_device *netdev,
case ETHTOOL_GRXRINGS: case ETHTOOL_GRXRINGS:
info->data = priv->params.num_channels; info->data = priv->params.num_channels;
break; 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: default:
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
break; break;

View File

@ -537,6 +537,40 @@ out:
return err; 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) void mlx5e_ethtool_cleanup_steering(struct mlx5e_priv *priv)
{ {
struct mlx5e_ethtool_rule *iter; struct mlx5e_ethtool_rule *iter;