net/mlx4_en: Fix wrong indication of Wake-on-LAN (WoL) support
authorInbar Karmy <inbark@mellanox.com>
Tue, 1 Aug 2017 13:43:43 +0000 (16:43 +0300)
committerDavid S. Miller <davem@davemloft.net>
Wed, 2 Aug 2017 17:44:09 +0000 (10:44 -0700)
Currently when WoL is supported but disabled, ethtool reports:
"Supports Wake-on: d".
Fix the indication of Wol support, so that the indication
remains "g" all the time if the NIC supports WoL.

Tested:
As accepted, when NIC supports WoL- ethtool reports:
Supports Wake-on: g
Wake-on: d
when NIC doesn't support WoL- ethtool reports:
        Supports Wake-on: d
        Wake-on: d

Fixes: 14c07b1358ed ("mlx4: Wake on LAN support")
Signed-off-by: Inbar Karmy <inbark@mellanox.com>
Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
drivers/net/ethernet/mellanox/mlx4/fw.c
drivers/net/ethernet/mellanox/mlx4/fw.h
drivers/net/ethernet/mellanox/mlx4/main.c
include/linux/mlx4/device.h

index c751a1d434ad7167e6b65a62f46b7295044860f8..3d4e4a5d00d1c5f81267c4a4a9675bc667709211 100644 (file)
@@ -223,6 +223,7 @@ static void mlx4_en_get_wol(struct net_device *netdev,
                            struct ethtool_wolinfo *wol)
 {
        struct mlx4_en_priv *priv = netdev_priv(netdev);
+       struct mlx4_caps *caps = &priv->mdev->dev->caps;
        int err = 0;
        u64 config = 0;
        u64 mask;
@@ -235,24 +236,24 @@ static void mlx4_en_get_wol(struct net_device *netdev,
        mask = (priv->port == 1) ? MLX4_DEV_CAP_FLAG_WOL_PORT1 :
                MLX4_DEV_CAP_FLAG_WOL_PORT2;
 
-       if (!(priv->mdev->dev->caps.flags & mask)) {
+       if (!(caps->flags & mask)) {
                wol->supported = 0;
                wol->wolopts = 0;
                return;
        }
 
+       if (caps->wol_port[priv->port])
+               wol->supported = WAKE_MAGIC;
+       else
+               wol->supported = 0;
+
        err = mlx4_wol_read(priv->mdev->dev, &config, priv->port);
        if (err) {
                en_err(priv, "Failed to get WoL information\n");
                return;
        }
 
-       if (config & MLX4_EN_WOL_MAGIC)
-               wol->supported = WAKE_MAGIC;
-       else
-               wol->supported = 0;
-
-       if (config & MLX4_EN_WOL_ENABLED)
+       if ((config & MLX4_EN_WOL_ENABLED) && (config & MLX4_EN_WOL_MAGIC))
                wol->wolopts = WAKE_MAGIC;
        else
                wol->wolopts = 0;
index 37e84a59e751d8ad44c34f5a0c7b16337a207c9e..c165f16623a95428cf23d38ce40487667f87c094 100644 (file)
@@ -764,6 +764,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
 #define QUERY_DEV_CAP_CQ_TS_SUPPORT_OFFSET     0x3e
 #define QUERY_DEV_CAP_MAX_PKEY_OFFSET          0x3f
 #define QUERY_DEV_CAP_EXT_FLAGS_OFFSET         0x40
+#define QUERY_DEV_CAP_WOL_OFFSET               0x43
 #define QUERY_DEV_CAP_FLAGS_OFFSET             0x44
 #define QUERY_DEV_CAP_RSVD_UAR_OFFSET          0x48
 #define QUERY_DEV_CAP_UAR_SZ_OFFSET            0x49
@@ -920,6 +921,9 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
        MLX4_GET(ext_flags, outbox, QUERY_DEV_CAP_EXT_FLAGS_OFFSET);
        MLX4_GET(flags, outbox, QUERY_DEV_CAP_FLAGS_OFFSET);
        dev_cap->flags = flags | (u64)ext_flags << 32;
+       MLX4_GET(field, outbox, QUERY_DEV_CAP_WOL_OFFSET);
+       dev_cap->wol_port[1] = !!(field & 0x20);
+       dev_cap->wol_port[2] = !!(field & 0x40);
        MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_UAR_OFFSET);
        dev_cap->reserved_uars = field >> 4;
        MLX4_GET(field, outbox, QUERY_DEV_CAP_UAR_SZ_OFFSET);
index 5343a0599253b98d6f2b9b77b65210a4e1e0abf9..b52ba01aa486a0b492cdb623cbe253c7a2e583d0 100644 (file)
@@ -129,6 +129,7 @@ struct mlx4_dev_cap {
        u32 dmfs_high_rate_qpn_range;
        struct mlx4_rate_limit_caps rl_caps;
        struct mlx4_port_cap port_cap[MLX4_MAX_PORTS + 1];
+       bool wol_port[MLX4_MAX_PORTS + 1];
 };
 
 struct mlx4_func_cap {
index a27c9c13a36ed11d577e7cd9cff1e2a9daec137d..09b9bc17bce998a99f360577a92a0211b552bf38 100644 (file)
@@ -424,6 +424,8 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
        dev->caps.stat_rate_support  = dev_cap->stat_rate_support;
        dev->caps.max_gso_sz         = dev_cap->max_gso_sz;
        dev->caps.max_rss_tbl_sz     = dev_cap->max_rss_tbl_sz;
+       dev->caps.wol_port[1]          = dev_cap->wol_port[1];
+       dev->caps.wol_port[2]          = dev_cap->wol_port[2];
 
        /* Save uar page shift */
        if (!mlx4_is_slave(dev)) {
index aad5d81dfb444aeb0dcb4b92aef475023aa897c1..b54517c05e9ab20fff33e3526fe0ea8de1e702bb 100644 (file)
@@ -620,6 +620,7 @@ struct mlx4_caps {
        u32                     dmfs_high_rate_qpn_base;
        u32                     dmfs_high_rate_qpn_range;
        u32                     vf_caps;
+       bool                    wol_port[MLX4_MAX_PORTS + 1];
        struct mlx4_rate_limit_caps rl_caps;
 };