Commit abfe9039 authored by Ben Hutchings's avatar Ben Hutchings

sfc: Implement generic features interface

Signed-off-by: default avatarBen Hutchings <bhutchings@solarflare.com>
parent f82d9a67
...@@ -1874,6 +1874,17 @@ static void efx_set_multicast_list(struct net_device *net_dev) ...@@ -1874,6 +1874,17 @@ static void efx_set_multicast_list(struct net_device *net_dev)
/* Otherwise efx_start_port() will do this */ /* Otherwise efx_start_port() will do this */
} }
static int efx_set_features(struct net_device *net_dev, u32 data)
{
struct efx_nic *efx = netdev_priv(net_dev);
/* If disabling RX n-tuple filtering, clear existing filters */
if (net_dev->features & ~data & NETIF_F_NTUPLE)
efx_filter_clear_rx(efx, EFX_FILTER_PRI_MANUAL);
return 0;
}
static const struct net_device_ops efx_netdev_ops = { static const struct net_device_ops efx_netdev_ops = {
.ndo_open = efx_net_open, .ndo_open = efx_net_open,
.ndo_stop = efx_net_stop, .ndo_stop = efx_net_stop,
...@@ -1885,6 +1896,7 @@ static const struct net_device_ops efx_netdev_ops = { ...@@ -1885,6 +1896,7 @@ static const struct net_device_ops efx_netdev_ops = {
.ndo_change_mtu = efx_change_mtu, .ndo_change_mtu = efx_change_mtu,
.ndo_set_mac_address = efx_set_mac_address, .ndo_set_mac_address = efx_set_mac_address,
.ndo_set_multicast_list = efx_set_multicast_list, .ndo_set_multicast_list = efx_set_multicast_list,
.ndo_set_features = efx_set_features,
#ifdef CONFIG_NET_POLL_CONTROLLER #ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = efx_netpoll, .ndo_poll_controller = efx_netpoll,
#endif #endif
...@@ -2269,7 +2281,6 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, ...@@ -2269,7 +2281,6 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
strlcpy(efx->name, pci_name(pci_dev), sizeof(efx->name)); strlcpy(efx->name, pci_name(pci_dev), sizeof(efx->name));
efx->net_dev = net_dev; efx->net_dev = net_dev;
efx->rx_checksum_enabled = true;
spin_lock_init(&efx->stats_lock); spin_lock_init(&efx->stats_lock);
mutex_init(&efx->mac_lock); mutex_init(&efx->mac_lock);
efx->mac_op = type->default_mac_ops; efx->mac_op = type->default_mac_ops;
...@@ -2452,12 +2463,15 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev, ...@@ -2452,12 +2463,15 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev,
return -ENOMEM; return -ENOMEM;
net_dev->features |= (type->offload_features | NETIF_F_SG | net_dev->features |= (type->offload_features | NETIF_F_SG |
NETIF_F_HIGHDMA | NETIF_F_TSO | NETIF_F_HIGHDMA | NETIF_F_TSO |
NETIF_F_GRO); NETIF_F_RXCSUM);
if (type->offload_features & NETIF_F_V6_CSUM) if (type->offload_features & NETIF_F_V6_CSUM)
net_dev->features |= NETIF_F_TSO6; net_dev->features |= NETIF_F_TSO6;
/* Mask for features that also apply to VLAN devices */ /* Mask for features that also apply to VLAN devices */
net_dev->vlan_features |= (NETIF_F_ALL_CSUM | NETIF_F_SG | net_dev->vlan_features |= (NETIF_F_ALL_CSUM | NETIF_F_SG |
NETIF_F_HIGHDMA | NETIF_F_ALL_TSO); NETIF_F_HIGHDMA | NETIF_F_ALL_TSO |
NETIF_F_RXCSUM);
/* All offloads can be toggled */
net_dev->hw_features = net_dev->features & ~NETIF_F_HIGHDMA;
efx = netdev_priv(net_dev); efx = netdev_priv(net_dev);
pci_set_drvdata(pci_dev, efx); pci_set_drvdata(pci_dev, efx);
SET_NETDEV_DEV(net_dev, &pci_dev->dev); SET_NETDEV_DEV(net_dev, &pci_dev->dev);
......
...@@ -518,72 +518,6 @@ static void efx_ethtool_get_stats(struct net_device *net_dev, ...@@ -518,72 +518,6 @@ static void efx_ethtool_get_stats(struct net_device *net_dev,
} }
} }
static int efx_ethtool_set_tso(struct net_device *net_dev, u32 enable)
{
struct efx_nic *efx __attribute__ ((unused)) = netdev_priv(net_dev);
u32 features;
features = NETIF_F_TSO;
if (efx->type->offload_features & NETIF_F_V6_CSUM)
features |= NETIF_F_TSO6;
if (enable)
net_dev->features |= features;
else
net_dev->features &= ~features;
return 0;
}
static int efx_ethtool_set_tx_csum(struct net_device *net_dev, u32 enable)
{
struct efx_nic *efx = netdev_priv(net_dev);
u32 features = efx->type->offload_features & NETIF_F_ALL_CSUM;
if (enable)
net_dev->features |= features;
else
net_dev->features &= ~features;
return 0;
}
static int efx_ethtool_set_rx_csum(struct net_device *net_dev, u32 enable)
{
struct efx_nic *efx = netdev_priv(net_dev);
/* No way to stop the hardware doing the checks; we just
* ignore the result.
*/
efx->rx_checksum_enabled = !!enable;
return 0;
}
static u32 efx_ethtool_get_rx_csum(struct net_device *net_dev)
{
struct efx_nic *efx = netdev_priv(net_dev);
return efx->rx_checksum_enabled;
}
static int efx_ethtool_set_flags(struct net_device *net_dev, u32 data)
{
struct efx_nic *efx = netdev_priv(net_dev);
u32 supported = (efx->type->offload_features &
(ETH_FLAG_RXHASH | ETH_FLAG_NTUPLE));
int rc;
rc = ethtool_op_set_flags(net_dev, data, supported);
if (rc)
return rc;
if (!(data & ETH_FLAG_NTUPLE))
efx_filter_clear_rx(efx, EFX_FILTER_PRI_MANUAL);
return 0;
}
static void efx_ethtool_self_test(struct net_device *net_dev, static void efx_ethtool_self_test(struct net_device *net_dev,
struct ethtool_test *test, u64 *data) struct ethtool_test *test, u64 *data)
{ {
...@@ -1070,18 +1004,6 @@ const struct ethtool_ops efx_ethtool_ops = { ...@@ -1070,18 +1004,6 @@ const struct ethtool_ops efx_ethtool_ops = {
.set_ringparam = efx_ethtool_set_ringparam, .set_ringparam = efx_ethtool_set_ringparam,
.get_pauseparam = efx_ethtool_get_pauseparam, .get_pauseparam = efx_ethtool_get_pauseparam,
.set_pauseparam = efx_ethtool_set_pauseparam, .set_pauseparam = efx_ethtool_set_pauseparam,
.get_rx_csum = efx_ethtool_get_rx_csum,
.set_rx_csum = efx_ethtool_set_rx_csum,
.get_tx_csum = ethtool_op_get_tx_csum,
/* Need to enable/disable IPv6 too */
.set_tx_csum = efx_ethtool_set_tx_csum,
.get_sg = ethtool_op_get_sg,
.set_sg = ethtool_op_set_sg,
.get_tso = ethtool_op_get_tso,
/* Need to enable/disable TSO-IPv6 too */
.set_tso = efx_ethtool_set_tso,
.get_flags = ethtool_op_get_flags,
.set_flags = efx_ethtool_set_flags,
.get_sset_count = efx_ethtool_get_sset_count, .get_sset_count = efx_ethtool_get_sset_count,
.self_test = efx_ethtool_self_test, .self_test = efx_ethtool_self_test,
.get_strings = efx_ethtool_get_strings, .get_strings = efx_ethtool_get_strings,
......
...@@ -681,7 +681,6 @@ struct efx_filter_state; ...@@ -681,7 +681,6 @@ struct efx_filter_state;
* @port_inhibited: If set, the netif_carrier is always off. Hold the mac_lock * @port_inhibited: If set, the netif_carrier is always off. Hold the mac_lock
* @port_initialized: Port initialized? * @port_initialized: Port initialized?
* @net_dev: Operating system network device. Consider holding the rtnl lock * @net_dev: Operating system network device. Consider holding the rtnl lock
* @rx_checksum_enabled: RX checksumming enabled
* @stats_buffer: DMA buffer for statistics * @stats_buffer: DMA buffer for statistics
* @mac_op: MAC interface * @mac_op: MAC interface
* @phy_type: PHY type * @phy_type: PHY type
...@@ -771,7 +770,6 @@ struct efx_nic { ...@@ -771,7 +770,6 @@ struct efx_nic {
bool port_initialized; bool port_initialized;
struct net_device *net_dev; struct net_device *net_dev;
bool rx_checksum_enabled;
struct efx_buffer stats_buffer; struct efx_buffer stats_buffer;
......
...@@ -605,7 +605,7 @@ void __efx_rx_packet(struct efx_channel *channel, ...@@ -605,7 +605,7 @@ void __efx_rx_packet(struct efx_channel *channel,
skb_record_rx_queue(skb, channel->channel); skb_record_rx_queue(skb, channel->channel);
} }
if (unlikely(!efx->rx_checksum_enabled)) if (unlikely(!(efx->net_dev->features & NETIF_F_RXCSUM)))
checksummed = false; checksummed = false;
if (likely(checksummed || rx_buf->is_page)) { if (likely(checksummed || rx_buf->is_page)) {
......
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