Commit db43b30c authored by Vishal Kulkarni's avatar Vishal Kulkarni Committed by David S. Miller

cxgb4: add ethtool n-tuple filter deletion

Add support to delete ethtool n-tuple filter. Fetch the appropriate
filter region (HPFILTER, HASH, NORMAL) in which the filter exists,
and delete it from the respective region, accordingly.
Signed-off-by: default avatarRahul Lakkireddy <rahul.lakkireddy@chelsio.com>
Signed-off-by: default avatarVishal Kulkarni <vishal@chelsio.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c8729cac
......@@ -1573,6 +1573,22 @@ static int set_rss_table(struct net_device *dev, const u32 *p, const u8 *key,
return -EPERM;
}
static struct filter_entry *cxgb4_get_filter_entry(struct adapter *adap,
u32 ftid)
{
struct tid_info *t = &adap->tids;
struct filter_entry *f;
if (ftid < t->nhpftids)
f = &adap->tids.hpftid_tab[ftid];
else if (ftid < t->nftids)
f = &adap->tids.ftid_tab[ftid - t->nhpftids];
else
f = lookup_tid(&adap->tids, ftid);
return f;
}
static int get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info,
u32 *rules)
{
......@@ -1636,6 +1652,48 @@ static int get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info,
return -EOPNOTSUPP;
}
static int cxgb4_ntuple_del_filter(struct net_device *dev,
struct ethtool_rxnfc *cmd)
{
struct cxgb4_ethtool_filter_info *filter_info;
struct adapter *adapter = netdev2adap(dev);
struct port_info *pi = netdev_priv(dev);
struct filter_entry *f;
u32 filter_id;
int ret;
if (!(adapter->flags & CXGB4_FULL_INIT_DONE))
return -EAGAIN; /* can still change nfilters */
if (!adapter->ethtool_filters)
return -EOPNOTSUPP;
if (cmd->fs.location >= adapter->ethtool_filters->nentries) {
dev_err(adapter->pdev_dev,
"Location must be < %u",
adapter->ethtool_filters->nentries);
return -ERANGE;
}
filter_info = &adapter->ethtool_filters->port[pi->port_id];
if (!test_bit(cmd->fs.location, filter_info->bmap))
return -ENOENT;
filter_id = filter_info->loc_array[cmd->fs.location];
f = cxgb4_get_filter_entry(adapter, filter_id);
ret = cxgb4_flow_rule_destroy(dev, f->fs.tc_prio, &f->fs, filter_id);
if (ret)
goto err;
clear_bit(cmd->fs.location, filter_info->bmap);
filter_info->in_use--;
err:
return ret;
}
/* Add Ethtool n-tuple filters. */
static int cxgb4_ntuple_set_filter(struct net_device *netdev,
struct ethtool_rxnfc *cmd)
......@@ -1702,6 +1760,9 @@ static int set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
case ETHTOOL_SRXCLSRLINS:
ret = cxgb4_ntuple_set_filter(dev, cmd);
break;
case ETHTOOL_SRXCLSRLDEL:
ret = cxgb4_ntuple_del_filter(dev, cmd);
break;
default:
break;
}
......
......@@ -797,23 +797,38 @@ int cxgb4_tc_flower_replace(struct net_device *dev,
return ret;
}
int cxgb4_flow_rule_destroy(struct net_device *dev, u32 tc_prio,
struct ch_filter_specification *fs, int tid)
{
struct adapter *adap = netdev2adap(dev);
u8 hash;
int ret;
hash = fs->hash;
ret = cxgb4_del_filter(dev, tid, fs);
if (ret)
return ret;
if (hash)
cxgb4_tc_flower_hash_prio_del(adap, tc_prio);
return ret;
}
int cxgb4_tc_flower_destroy(struct net_device *dev,
struct flow_cls_offload *cls)
{
struct adapter *adap = netdev2adap(dev);
struct ch_tc_flower_entry *ch_flower;
u32 tc_prio;
bool hash;
int ret;
ch_flower = ch_flower_lookup(adap, cls->cookie);
if (!ch_flower)
return -ENOENT;
hash = ch_flower->fs.hash;
tc_prio = ch_flower->fs.tc_prio;
ret = cxgb4_del_filter(dev, ch_flower->filter_id, &ch_flower->fs);
ret = cxgb4_flow_rule_destroy(dev, ch_flower->fs.tc_prio,
&ch_flower->fs, ch_flower->filter_id);
if (ret)
goto err;
......@@ -825,9 +840,6 @@ int cxgb4_tc_flower_destroy(struct net_device *dev,
}
kfree_rcu(ch_flower, rcu);
if (hash)
cxgb4_tc_flower_hash_prio_del(adap, tc_prio);
err:
return ret;
}
......
......@@ -124,6 +124,8 @@ int cxgb4_tc_flower_stats(struct net_device *dev,
int cxgb4_flow_rule_replace(struct net_device *dev, struct flow_rule *rule,
u32 tc_prio, struct netlink_ext_ack *extack,
struct ch_filter_specification *fs, u32 *tid);
int cxgb4_flow_rule_destroy(struct net_device *dev, u32 tc_prio,
struct ch_filter_specification *fs, int tid);
int cxgb4_init_tc_flower(struct adapter *adap);
void cxgb4_cleanup_tc_flower(struct adapter *adap);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment