Commit 73744262 authored by Kurt Kanzenbach's avatar Kurt Kanzenbach Committed by Tony Nguyen

igc: Make flex filter more flexible

Currently flex filters are only used for filters containing user data.
However, it makes sense to utilize them also for filters having
multiple conditions, because that's not supported by the driver at the
moment. Add it.
Signed-off-by: Kurt Kanzenbach's avatarKurt Kanzenbach <kurt@linutronix.de>
Reviewed-by: default avatarSebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: default avatarVinicius Costa Gomes <vinicius.gomes@intel.com>
Tested-by: default avatarDvora Fuxbrumer <dvorax.fuxbrumer@linux.intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent 7991487e
......@@ -507,6 +507,7 @@ struct igc_nfc_rule {
struct igc_nfc_filter filter;
u32 location;
u16 action;
bool flex;
};
/* IGC supports a total of 32 NFC rules: 16 MAC address based, 8 VLAN priority
......
......@@ -1222,19 +1222,29 @@ static void igc_ethtool_init_nfc_rule(struct igc_nfc_rule *rule,
fsp->h_u.ether_spec.h_dest);
}
/* VLAN etype matching */
if ((fsp->flow_type & FLOW_EXT) && fsp->h_ext.vlan_etype) {
rule->filter.vlan_etype = fsp->h_ext.vlan_etype;
rule->filter.match_flags |= IGC_FILTER_FLAG_VLAN_ETYPE;
}
/* Check for user defined data */
if ((fsp->flow_type & FLOW_EXT) &&
(fsp->h_ext.data[0] || fsp->h_ext.data[1])) {
rule->filter.match_flags |= IGC_FILTER_FLAG_USER_DATA;
memcpy(rule->filter.user_data, fsp->h_ext.data, sizeof(fsp->h_ext.data));
memcpy(rule->filter.user_mask, fsp->m_ext.data, sizeof(fsp->m_ext.data));
/* VLAN etype matching is only valid using flex filter */
if ((fsp->flow_type & FLOW_EXT) && fsp->h_ext.vlan_etype) {
rule->filter.vlan_etype = fsp->h_ext.vlan_etype;
rule->filter.match_flags |= IGC_FILTER_FLAG_VLAN_ETYPE;
}
}
/* When multiple filter options or user data or vlan etype is set, use a
* flex filter.
*/
if ((rule->filter.match_flags & IGC_FILTER_FLAG_USER_DATA) ||
(rule->filter.match_flags & IGC_FILTER_FLAG_VLAN_ETYPE) ||
(rule->filter.match_flags & (rule->filter.match_flags - 1)))
rule->flex = true;
else
rule->flex = false;
}
/**
......@@ -1264,11 +1274,6 @@ static int igc_ethtool_check_nfc_rule(struct igc_adapter *adapter,
return -EINVAL;
}
if (flags & (flags - 1)) {
netdev_dbg(dev, "Rule with multiple matches not supported\n");
return -EOPNOTSUPP;
}
list_for_each_entry(tmp, &adapter->nfc_rule_list, list) {
if (!memcmp(&rule->filter, &tmp->filter,
sizeof(rule->filter)) &&
......
......@@ -3385,14 +3385,8 @@ static int igc_enable_nfc_rule(struct igc_adapter *adapter,
{
int err;
/* Check for user data first: When user data is set, the only option is
* to use a flex filter. When more options are set (ethertype, vlan tci,
* ...) construct a flex filter matching all of that.
*/
if (rule->filter.match_flags & IGC_FILTER_FLAG_USER_DATA) {
err = igc_add_flex_filter(adapter, rule);
if (err)
return err;
if (rule->flex) {
return igc_add_flex_filter(adapter, rule);
}
if (rule->filter.match_flags & IGC_FILTER_FLAG_ETHER_TYPE) {
......@@ -3431,8 +3425,10 @@ static int igc_enable_nfc_rule(struct igc_adapter *adapter,
static void igc_disable_nfc_rule(struct igc_adapter *adapter,
const struct igc_nfc_rule *rule)
{
if (rule->filter.match_flags & IGC_FILTER_FLAG_USER_DATA)
if (rule->flex) {
igc_del_flex_filter(adapter, rule->filter.flex_index);
return;
}
if (rule->filter.match_flags & IGC_FILTER_FLAG_ETHER_TYPE)
igc_del_etype_filter(adapter, rule->filter.etype);
......
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