diff options
Diffstat (limited to 'drivers/net/ethernet/intel/igc/igc_ethtool.c')
| -rw-r--r-- | drivers/net/ethernet/intel/igc/igc_ethtool.c | 49 | 
1 files changed, 36 insertions, 13 deletions
| diff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c index fa4171860623..e0a76ac1bbbc 100644 --- a/drivers/net/ethernet/intel/igc/igc_ethtool.c +++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c @@ -862,7 +862,9 @@ static void igc_ethtool_get_stats(struct net_device *netdev,  }  static int igc_ethtool_get_coalesce(struct net_device *netdev, -				    struct ethtool_coalesce *ec) +				    struct ethtool_coalesce *ec, +				    struct kernel_ethtool_coalesce *kernel_coal, +				    struct netlink_ext_ack *extack)  {  	struct igc_adapter *adapter = netdev_priv(netdev); @@ -882,7 +884,9 @@ static int igc_ethtool_get_coalesce(struct net_device *netdev,  }  static int igc_ethtool_set_coalesce(struct net_device *netdev, -				    struct ethtool_coalesce *ec) +				    struct ethtool_coalesce *ec, +				    struct kernel_ethtool_coalesce *kernel_coal, +				    struct netlink_ext_ack *extack)  {  	struct igc_adapter *adapter = netdev_priv(netdev);  	int i; @@ -979,6 +983,12 @@ static int igc_ethtool_get_nfc_rule(struct igc_adapter *adapter,  		eth_broadcast_addr(fsp->m_u.ether_spec.h_source);  	} +	if (rule->filter.match_flags & IGC_FILTER_FLAG_USER_DATA) { +		fsp->flow_type |= FLOW_EXT; +		memcpy(fsp->h_ext.data, rule->filter.user_data, sizeof(fsp->h_ext.data)); +		memcpy(fsp->m_ext.data, rule->filter.user_mask, sizeof(fsp->m_ext.data)); +	} +  	mutex_unlock(&adapter->nfc_rule_lock);  	return 0; @@ -1215,6 +1225,30 @@ static void igc_ethtool_init_nfc_rule(struct igc_nfc_rule *rule,  		ether_addr_copy(rule->filter.dst_addr,  				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)); +	} + +	/* 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;  }  /** @@ -1244,11 +1278,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)) && @@ -1280,12 +1309,6 @@ static int igc_ethtool_add_nfc_rule(struct igc_adapter *adapter,  		return -EOPNOTSUPP;  	} -	if ((fsp->flow_type & FLOW_EXT) && -	    fsp->m_ext.vlan_tci != htons(VLAN_PRIO_MASK)) { -		netdev_dbg(netdev, "VLAN mask not supported\n"); -		return -EOPNOTSUPP; -	} -  	if (fsp->ring_cookie >= adapter->num_rx_queues) {  		netdev_dbg(netdev, "Invalid action\n");  		return -EINVAL; |