diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/ethernet/intel/igc/igc_ethtool.c | 32 |
1 files changed, 22 insertions, 10 deletions
diff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c index 6c27046a852d..42ecb493c1a2 100644 --- a/drivers/net/ethernet/intel/igc/igc_ethtool.c +++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c @@ -1188,16 +1188,8 @@ static int igc_set_rss_hash_opt(struct igc_adapter *adapter, int igc_add_filter(struct igc_adapter *adapter, struct igc_nfc_filter *input) { - struct igc_hw *hw = &adapter->hw; int err = -EINVAL; - if (hw->mac.type == igc_i225 && - !(input->filter.match_flags & ~IGC_FILTER_FLAG_SRC_MAC_ADDR)) { - netdev_err(adapter->netdev, - "i225 doesn't support flow classification rules specifying only source addresses\n"); - return -EOPNOTSUPP; - } - if (input->filter.match_flags & IGC_FILTER_FLAG_ETHER_TYPE) { u16 etype = ntohs(input->filter.etype); @@ -1206,6 +1198,14 @@ int igc_add_filter(struct igc_adapter *adapter, struct igc_nfc_filter *input) return err; } + if (input->filter.match_flags & IGC_FILTER_FLAG_SRC_MAC_ADDR) { + err = igc_add_mac_filter(adapter, IGC_MAC_FILTER_TYPE_SRC, + input->filter.src_addr, + input->action); + if (err) + return err; + } + if (input->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR) { err = igc_add_mac_filter(adapter, IGC_MAC_FILTER_TYPE_DST, input->filter.dst_addr, @@ -1239,6 +1239,10 @@ int igc_erase_filter(struct igc_adapter *adapter, struct igc_nfc_filter *input) igc_del_vlan_prio_filter(adapter, prio); } + if (input->filter.match_flags & IGC_FILTER_FLAG_SRC_MAC_ADDR) + igc_del_mac_filter(adapter, IGC_MAC_FILTER_TYPE_SRC, + input->filter.src_addr); + if (input->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR) igc_del_mac_filter(adapter, IGC_MAC_FILTER_TYPE_DST, input->filter.dst_addr); @@ -1334,20 +1338,28 @@ static int igc_add_ethtool_nfc_entry(struct igc_adapter *adapter, input->filter.match_flags = IGC_FILTER_FLAG_ETHER_TYPE; } - /* Only support matching addresses by the full mask */ + /* Both source and destination address filters only support the full + * mask. + */ if (is_broadcast_ether_addr(fsp->m_u.ether_spec.h_source)) { input->filter.match_flags |= IGC_FILTER_FLAG_SRC_MAC_ADDR; ether_addr_copy(input->filter.src_addr, fsp->h_u.ether_spec.h_source); } - /* Only support matching addresses by the full mask */ if (is_broadcast_ether_addr(fsp->m_u.ether_spec.h_dest)) { input->filter.match_flags |= IGC_FILTER_FLAG_DST_MAC_ADDR; ether_addr_copy(input->filter.dst_addr, fsp->h_u.ether_spec.h_dest); } + if (input->filter.match_flags & IGC_FILTER_FLAG_DST_MAC_ADDR && + input->filter.match_flags & IGC_FILTER_FLAG_SRC_MAC_ADDR) { + netdev_dbg(netdev, "Filters with both dst and src are not supported\n"); + err = -EOPNOTSUPP; + goto err_out; + } + if ((fsp->flow_type & FLOW_EXT) && fsp->m_ext.vlan_tci) { if (fsp->m_ext.vlan_tci != htons(VLAN_PRIO_MASK)) { netdev_dbg(netdev, "VLAN mask not supported\n"); |