net: Implement SFEATURES compatibility for not updated drivers
Use discrete setting ops for not updated drivers. This will not make them conform to full G/SFEATURES semantics, though. Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
4e4db20054
commit
39fc0ce571
|
@ -591,6 +591,9 @@ struct ethtool_sfeatures {
|
|||
* Probably there are other device-specific constraints on some features
|
||||
* in the set. When %ETHTOOL_F_UNSUPPORTED is set, .valid is considered
|
||||
* here as though ignored bits were cleared.
|
||||
* %ETHTOOL_F_COMPAT - some or all changes requested were made by calling
|
||||
* compatibility functions. Requested offload state cannot be properly
|
||||
* managed by kernel.
|
||||
*
|
||||
* Meaning of bits in the masks are obtained by %ETHTOOL_GSSET_INFO (number of
|
||||
* bits in the arrays - always multiple of 32) and %ETHTOOL_GSTRINGS commands
|
||||
|
@ -600,10 +603,12 @@ struct ethtool_sfeatures {
|
|||
enum ethtool_sfeatures_retval_bits {
|
||||
ETHTOOL_F_UNSUPPORTED__BIT,
|
||||
ETHTOOL_F_WISH__BIT,
|
||||
ETHTOOL_F_COMPAT__BIT,
|
||||
};
|
||||
|
||||
#define ETHTOOL_F_UNSUPPORTED (1 << ETHTOOL_F_UNSUPPORTED__BIT)
|
||||
#define ETHTOOL_F_WISH (1 << ETHTOOL_F_WISH__BIT)
|
||||
#define ETHTOOL_F_COMPAT (1 << ETHTOOL_F_COMPAT__BIT)
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
|
|
|
@ -178,6 +178,64 @@ static void ethtool_get_features_compat(struct net_device *dev,
|
|||
if (dev->ethtool_ops->get_rx_csum)
|
||||
if (dev->ethtool_ops->get_rx_csum(dev))
|
||||
features[0].active |= NETIF_F_RXCSUM;
|
||||
|
||||
/* mark legacy-changeable features */
|
||||
if (dev->ethtool_ops->set_sg)
|
||||
features[0].available |= NETIF_F_SG;
|
||||
if (dev->ethtool_ops->set_tx_csum)
|
||||
features[0].available |= NETIF_F_ALL_CSUM;
|
||||
if (dev->ethtool_ops->set_tso)
|
||||
features[0].available |= NETIF_F_ALL_TSO;
|
||||
if (dev->ethtool_ops->set_rx_csum)
|
||||
features[0].available |= NETIF_F_RXCSUM;
|
||||
if (dev->ethtool_ops->set_flags)
|
||||
features[0].available |= flags_dup_features;
|
||||
}
|
||||
|
||||
static int ethtool_set_feature_compat(struct net_device *dev,
|
||||
int (*legacy_set)(struct net_device *, u32),
|
||||
struct ethtool_set_features_block *features, u32 mask)
|
||||
{
|
||||
u32 do_set;
|
||||
|
||||
if (!legacy_set)
|
||||
return 0;
|
||||
|
||||
if (!(features[0].valid & mask))
|
||||
return 0;
|
||||
|
||||
features[0].valid &= ~mask;
|
||||
|
||||
do_set = !!(features[0].requested & mask);
|
||||
|
||||
if (legacy_set(dev, do_set) < 0)
|
||||
netdev_info(dev,
|
||||
"Legacy feature change (%s) failed for 0x%08x\n",
|
||||
do_set ? "set" : "clear", mask);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ethtool_set_features_compat(struct net_device *dev,
|
||||
struct ethtool_set_features_block *features)
|
||||
{
|
||||
int compat;
|
||||
|
||||
if (!dev->ethtool_ops)
|
||||
return 0;
|
||||
|
||||
compat = ethtool_set_feature_compat(dev, dev->ethtool_ops->set_sg,
|
||||
features, NETIF_F_SG);
|
||||
compat |= ethtool_set_feature_compat(dev, dev->ethtool_ops->set_tx_csum,
|
||||
features, NETIF_F_ALL_CSUM);
|
||||
compat |= ethtool_set_feature_compat(dev, dev->ethtool_ops->set_tso,
|
||||
features, NETIF_F_ALL_TSO);
|
||||
compat |= ethtool_set_feature_compat(dev, dev->ethtool_ops->set_rx_csum,
|
||||
features, NETIF_F_RXCSUM);
|
||||
compat |= ethtool_set_feature_compat(dev, dev->ethtool_ops->set_flags,
|
||||
features, flags_dup_features);
|
||||
|
||||
return compat;
|
||||
}
|
||||
|
||||
static int ethtool_get_features(struct net_device *dev, void __user *useraddr)
|
||||
|
@ -234,6 +292,9 @@ static int ethtool_set_features(struct net_device *dev, void __user *useraddr)
|
|||
if (features[0].valid & ~NETIF_F_ETHTOOL_BITS)
|
||||
return -EINVAL;
|
||||
|
||||
if (ethtool_set_features_compat(dev, features))
|
||||
ret |= ETHTOOL_F_COMPAT;
|
||||
|
||||
if (features[0].valid & ~dev->hw_features) {
|
||||
features[0].valid &= dev->hw_features;
|
||||
ret |= ETHTOOL_F_UNSUPPORTED;
|
||||
|
|
Loading…
Reference in New Issue