net: hns3: Fix speed/duplex information loss problem when executing ethtool ethx...
authorFuyun Liang <liangfuyun1@huawei.com>
Fri, 21 Sep 2018 15:41:47 +0000 (16:41 +0100)
committerDavid S. Miller <davem@davemloft.net>
Sat, 22 Sep 2018 02:29:32 +0000 (19:29 -0700)
Our VF has not implemented the ops for get_port_type. So when we executing
ethtool ethx cmd of VF, hns3_get_link_ksettings will return directly. And
we can not query anything.

To support get_link_ksettings for VF, this patch replaces get_port_type
with get_media_type. If the media type is HNAE3_MEDIA_TYPE_NONE,
hns3_get_link_ksettings will return link information of VF.

Fixes: 12f46bc1d447 ("net: hns3: Refine hns3_get_link_ksettings()")
Signed-off-by: Fuyun Liang <liangfuyun1@huawei.com>
Signed-off-by: Peng Li <lipeng321@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c

index 46701cf256db5ef1c4d98ea1d427007e694c2bfe..8803a8721c8e635ec45be1cce9b782675f9eb424 100644 (file)
@@ -545,55 +545,67 @@ static int hns3_set_pauseparam(struct net_device *netdev,
        return -EOPNOTSUPP;
 }
 
+static void hns3_get_ksettings(struct hnae3_handle *h,
+                              struct ethtool_link_ksettings *cmd)
+{
+       const struct hnae3_ae_ops *ops = h->ae_algo->ops;
+
+       /* 1.auto_neg & speed & duplex from cmd */
+       if (ops->get_ksettings_an_result)
+               ops->get_ksettings_an_result(h,
+                                            &cmd->base.autoneg,
+                                            &cmd->base.speed,
+                                            &cmd->base.duplex);
+
+       /* 2.get link mode*/
+       if (ops->get_link_mode)
+               ops->get_link_mode(h,
+                                  cmd->link_modes.supported,
+                                  cmd->link_modes.advertising);
+
+       /* 3.mdix_ctrl&mdix get from phy reg */
+       if (ops->get_mdix_mode)
+               ops->get_mdix_mode(h, &cmd->base.eth_tp_mdix_ctrl,
+                                  &cmd->base.eth_tp_mdix);
+}
+
 static int hns3_get_link_ksettings(struct net_device *netdev,
                                   struct ethtool_link_ksettings *cmd)
 {
        struct hnae3_handle *h = hns3_get_handle(netdev);
        const struct hnae3_ae_ops *ops;
+       u8 media_type;
        u8 link_stat;
 
        if (!h->ae_algo || !h->ae_algo->ops)
                return -EOPNOTSUPP;
 
        ops = h->ae_algo->ops;
-       if (ops->get_port_type)
-               ops->get_port_type(h, &cmd->base.port);
+       if (ops->get_media_type)
+               ops->get_media_type(h, &media_type);
        else
                return -EOPNOTSUPP;
 
-       switch (cmd->base.port) {
-       case PORT_FIBRE:
-               /* 1.auto_neg & speed & duplex from cmd */
-               if (ops->get_ksettings_an_result)
-                       ops->get_ksettings_an_result(h,
-                                                    &cmd->base.autoneg,
-                                                    &cmd->base.speed,
-                                                    &cmd->base.duplex);
-               else
-                       return -EOPNOTSUPP;
-
-               /* 2.get link mode*/
-               if (ops->get_link_mode)
-                       ops->get_link_mode(h,
-                                          cmd->link_modes.supported,
-                                          cmd->link_modes.advertising);
-
-               /* 3.mdix_ctrl&mdix get from phy reg */
-               if (ops->get_mdix_mode)
-                       ops->get_mdix_mode(h, &cmd->base.eth_tp_mdix_ctrl,
-                                          &cmd->base.eth_tp_mdix);
-
+       switch (media_type) {
+       case HNAE3_MEDIA_TYPE_NONE:
+               cmd->base.port = PORT_NONE;
+               hns3_get_ksettings(h, cmd);
+               break;
+       case HNAE3_MEDIA_TYPE_FIBER:
+               cmd->base.port = PORT_FIBRE;
+               hns3_get_ksettings(h, cmd);
                break;
-       case PORT_TP:
+       case HNAE3_MEDIA_TYPE_COPPER:
                if (!netdev->phydev)
                        return -EOPNOTSUPP;
 
+               cmd->base.port = PORT_TP;
                phy_ethtool_ksettings_get(netdev->phydev, cmd);
 
                break;
        default:
-               netdev_warn(netdev,
-                           "Unknown port type, neither Fibre/Copper detected");
+
+               netdev_warn(netdev, "Unknown media type");
                return 0;
        }