IPOIB_STOP_REAPER = 7,
IPOIB_FLAG_ADMIN_CM = 9,
IPOIB_FLAG_UMCAST = 10,
- IPOIB_FLAG_CSUM = 11,
IPOIB_MAX_BACKOFF_SECONDS = 16,
set_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags);
ipoib_warn(priv, "enabling connected mode "
"will cause multicast packet drops\n");
-
- dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO);
+ netdev_update_features(dev);
rtnl_unlock();
priv->tx_wr.send_flags &= ~IB_SEND_IP_CSUM;
if (!strcmp(buf, "datagram\n")) {
clear_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags);
-
- if (test_bit(IPOIB_FLAG_CSUM, &priv->flags)) {
- dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
- priv->dev->features |= NETIF_F_GRO;
- if (priv->hca_caps & IB_DEVICE_UD_TSO)
- dev->features |= NETIF_F_TSO;
- }
+ netdev_update_features(dev);
dev_set_mtu(dev, min(priv->mcast_mtu, dev->mtu));
rtnl_unlock();
ipoib_flush_paths(dev);
strncpy(drvinfo->driver, "ipoib", sizeof(drvinfo->driver) - 1);
}
-static u32 ipoib_get_rx_csum(struct net_device *dev)
-{
- struct ipoib_dev_priv *priv = netdev_priv(dev);
- return test_bit(IPOIB_FLAG_CSUM, &priv->flags) &&
- !test_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags);
-}
-
-static int ipoib_set_tso(struct net_device *dev, u32 data)
-{
- struct ipoib_dev_priv *priv = netdev_priv(dev);
-
- if (data) {
- if (!test_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags) &&
- (dev->features & NETIF_F_SG) &&
- (priv->hca_caps & IB_DEVICE_UD_TSO)) {
- dev->features |= NETIF_F_TSO;
- } else {
- ipoib_warn(priv, "can't set TSO on\n");
- return -EOPNOTSUPP;
- }
- } else
- dev->features &= ~NETIF_F_TSO;
-
- return 0;
-}
-
static int ipoib_get_coalesce(struct net_device *dev,
struct ethtool_coalesce *coal)
{
static const struct ethtool_ops ipoib_ethtool_ops = {
.get_drvinfo = ipoib_get_drvinfo,
- .get_rx_csum = ipoib_get_rx_csum,
- .set_tso = ipoib_set_tso,
.get_coalesce = ipoib_get_coalesce,
.set_coalesce = ipoib_set_coalesce,
};
dev->stats.rx_bytes += skb->len;
skb->dev = dev;
- if (test_bit(IPOIB_FLAG_CSUM, &priv->flags) && likely(wc->csum_ok))
+ if ((dev->features & NETIF_F_RXCSUM) && likely(wc->csum_ok))
skb->ip_summed = CHECKSUM_UNNECESSARY;
napi_gro_receive(&priv->napi, skb);
return 0;
}
+static u32 ipoib_fix_features(struct net_device *dev, u32 features)
+{
+ struct ipoib_dev_priv *priv = netdev_priv(dev);
+
+ if (test_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags))
+ features &= ~(NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO);
+
+ return features;
+}
+
static int ipoib_change_mtu(struct net_device *dev, int new_mtu)
{
struct ipoib_dev_priv *priv = netdev_priv(dev);
.ndo_open = ipoib_open,
.ndo_stop = ipoib_stop,
.ndo_change_mtu = ipoib_change_mtu,
+ .ndo_fix_features = ipoib_fix_features,
.ndo_start_xmit = ipoib_start_xmit,
.ndo_tx_timeout = ipoib_timeout,
.ndo_set_multicast_list = ipoib_set_mcast_list,
kfree(device_attr);
if (priv->hca_caps & IB_DEVICE_UD_IP_CSUM) {
- set_bit(IPOIB_FLAG_CSUM, &priv->flags);
- priv->dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
- }
+ priv->dev->hw_features = NETIF_F_SG |
+ NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
- priv->dev->features |= NETIF_F_GRO;
+ if (priv->hca_caps & IB_DEVICE_UD_TSO)
+ priv->dev->hw_features |= NETIF_F_TSO;
- if (priv->dev->features & NETIF_F_SG && priv->hca_caps & IB_DEVICE_UD_TSO)
- priv->dev->features |= NETIF_F_TSO;
+ priv->dev->features |= priv->dev->hw_features;
+ }
return 0;
}
-
static struct net_device *ipoib_add_port(const char *format,
struct ib_device *hca, u8 port)
{