net: hns: add uniform interface for phy connection
authorKejian Yan <yankejian@huawei.com>
Fri, 3 Jun 2016 02:55:16 +0000 (10:55 +0800)
committerDavid S. Miller <davem@davemloft.net>
Sun, 5 Jun 2016 01:32:40 +0000 (21:32 -0400)
As device_node is only used by DT case, HNS needs to treat the other
cases including ACPI. It needs to use uniform ways to handle both of
DT and ACPI. This patch chooses phy_device, and of_phy_connect and
of_phy_attach are only used by DT case. It needs to use uniform interface
to handle that sequence by both DT and ACPI.

Signed-off-by: Kejian Yan <yankejian@huawei.com>
Signed-off-by: Yisen Zhuang <Yisen.Zhuang@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/hisilicon/hns/hnae.c
drivers/net/ethernet/hisilicon/hns/hnae.h
drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c
drivers/net/ethernet/hisilicon/hns/hns_enet.c
drivers/net/ethernet/hisilicon/hns/hns_ethtool.c

index d630acdb07495d966dc92496a02c5b3089ebe005..5d3047cc8380728211c79f66b689397bee942173 100644 (file)
@@ -96,7 +96,13 @@ static int __ae_match(struct device *dev, const void *data)
 {
        struct hnae_ae_dev *hdev = cls_to_ae_dev(dev);
 
-       return (data == &hdev->dev->of_node->fwnode);
+       if (dev_of_node(hdev->dev))
+               return (data == &hdev->dev->of_node->fwnode);
+       else if (is_acpi_node(hdev->dev->fwnode))
+               return (data == hdev->dev->fwnode);
+
+       dev_err(dev, "__ae_match cannot read cfg data from OF or acpi\n");
+       return 0;
 }
 
 static struct hnae_ae_dev *find_ae(const struct fwnode_handle *fwnode)
index f5f814083809b81f6d4cf80120bd41e9f1c21d20..529cb1341270bf2398563fc38988ccd499674f81 100644 (file)
@@ -27,6 +27,7 @@
  * "cb" means control block
  */
 
+#include <linux/acpi.h>
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/module.h>
@@ -512,7 +513,7 @@ struct hnae_ae_dev {
 struct hnae_handle {
        struct device *owner_dev; /* the device which make use of this handle */
        struct hnae_ae_dev *dev;  /* the device who provides this handle */
-       struct device_node *phy_node;
+       struct phy_device *phy_dev;
        phy_interface_t phy_if;
        u32 if_support;
        int q_num;
index 7a757e88c89a78c0847a5abd0d83827c89bc3f67..8e009f4f0ee73dfcb3d67398080dd7b969c6523c 100644 (file)
@@ -131,7 +131,7 @@ struct hnae_handle *hns_ae_get_handle(struct hnae_ae_dev *dev,
        vf_cb->mac_cb = dsaf_dev->mac_cb[port_id];
 
        ae_handle->phy_if = vf_cb->mac_cb->phy_if;
-       ae_handle->phy_node = vf_cb->mac_cb->phy_node;
+       ae_handle->phy_dev = vf_cb->mac_cb->phy_dev;
        ae_handle->if_support = vf_cb->mac_cb->if_support;
        ae_handle->port_type = vf_cb->mac_cb->mac_type;
        ae_handle->dport_id = port_id;
index 611581fccf2a4eb1d569514d4c6613ebf54fee3e..527b49d3749e8a500b0395a77224a358d7c33bc2 100644 (file)
@@ -15,7 +15,8 @@
 #include <linux/netdevice.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
-#include <linux/phy_fixed.h>
+#include <linux/of_mdio.h>
+#include <linux/phy.h>
 #include <linux/platform_device.h>
 
 #include "hns_dsaf_main.h"
@@ -645,7 +646,7 @@ free_mac_drv:
  */
 static int  hns_mac_get_info(struct hns_mac_cb *mac_cb)
 {
-       struct device_node *np = mac_cb->dev->of_node;
+       struct device_node *np;
        struct regmap *syscon;
        struct of_phandle_args cpld_args;
        u32 ret;
@@ -672,21 +673,34 @@ static int  hns_mac_get_info(struct hns_mac_cb *mac_cb)
         * from dsaf node
         */
        if (!mac_cb->fw_port) {
-               mac_cb->phy_node = of_parse_phandle(np, "phy-handle",
-                                                   mac_cb->mac_id);
-               if (mac_cb->phy_node)
+               np = of_parse_phandle(mac_cb->dev->of_node, "phy-handle",
+                                     mac_cb->mac_id);
+               mac_cb->phy_dev = of_phy_find_device(np);
+               if (mac_cb->phy_dev) {
+                       /* refcount is held by of_phy_find_device()
+                        * if the phy_dev is found
+                        */
+                       put_device(&mac_cb->phy_dev->mdio.dev);
+
                        dev_dbg(mac_cb->dev, "mac%d phy_node: %s\n",
-                               mac_cb->mac_id, mac_cb->phy_node->name);
+                               mac_cb->mac_id, np->name);
+               }
+
                return 0;
        }
+
        if (!is_of_node(mac_cb->fw_port))
                return -EINVAL;
+
        /* parse property from port subnode in dsaf */
-       mac_cb->phy_node = of_parse_phandle(to_of_node(mac_cb->fw_port),
-                                           "phy-handle", 0);
-       if (mac_cb->phy_node)
+       np = of_parse_phandle(to_of_node(mac_cb->fw_port), "phy-handle", 0);
+       mac_cb->phy_dev = of_phy_find_device(np);
+       if (mac_cb->phy_dev) {
+               put_device(&mac_cb->phy_dev->mdio.dev);
                dev_dbg(mac_cb->dev, "mac%d phy_node: %s\n",
-                       mac_cb->mac_id, mac_cb->phy_node->name);
+                       mac_cb->mac_id, np->name);
+               }
+
        syscon = syscon_node_to_regmap(
                        of_parse_phandle(to_of_node(mac_cb->fw_port),
                                         "serdes-syscon", 0));
index 97ce9a750aaf47d39b5b0d604eb7845e42628676..89b49d7fa20fb05fcf91dfdd15ff7b983aa11f45 100644 (file)
@@ -338,7 +338,7 @@ struct hns_mac_cb {
        phy_interface_t phy_if;
        enum hnae_loop loop_mode;
 
-       struct device_node *phy_node;
+       struct phy_device *phy_dev;
 
        struct mac_hw_stats hw_stats;
 };
index a837bb9e3839fa3bb1c05410531e94d96f201a1e..a843a866455dbd8121b72c75b112ccccc6b844e0 100644 (file)
@@ -332,7 +332,7 @@ int hns_mac_config_sds_loopback(struct hns_mac_cb *mac_cb, u8 en)
        int sfp_prsnt;
        int ret = hns_mac_get_sfp_prsnt(mac_cb, &sfp_prsnt);
 
-       if (!mac_cb->phy_node) {
+       if (!mac_cb->phy_dev) {
                if (ret)
                        pr_info("please confirm sfp is present or not\n");
                else
index 93f6ccbb64337b41afe15d20172e7ad7e645164c..3ec3c27983798cf0d222f7d4468def4ebfde0221 100644 (file)
@@ -996,19 +996,22 @@ static void hns_nic_adjust_link(struct net_device *ndev)
 int hns_nic_init_phy(struct net_device *ndev, struct hnae_handle *h)
 {
        struct hns_nic_priv *priv = netdev_priv(ndev);
-       struct phy_device *phy_dev = NULL;
+       struct phy_device *phy_dev = h->phy_dev;
+       int ret;
 
-       if (!h->phy_node)
+       if (!h->phy_dev)
                return 0;
 
-       if (h->phy_if != PHY_INTERFACE_MODE_XGMII)
-               phy_dev = of_phy_connect(ndev, h->phy_node,
-                                        hns_nic_adjust_link, 0, h->phy_if);
-       else
-               phy_dev = of_phy_attach(ndev, h->phy_node, 0, h->phy_if);
+       if (h->phy_if != PHY_INTERFACE_MODE_XGMII) {
+               phy_dev->dev_flags = 0;
 
-       if (unlikely(!phy_dev) || IS_ERR(phy_dev))
-               return !phy_dev ? -ENODEV : PTR_ERR(phy_dev);
+               ret = phy_connect_direct(ndev, phy_dev, hns_nic_adjust_link,
+                                        h->phy_if);
+       } else {
+               ret = phy_attach_direct(ndev, phy_dev, 0, h->phy_if);
+       }
+       if (unlikely(ret))
+               return -ENODEV;
 
        phy_dev->supported &= h->if_support;
        phy_dev->advertising = phy_dev->supported;
index 67a648c7d3a9e14d51ebbe650ec9b72c8a61015d..a809f52f6c16c8dc6010bd88745797176b9d77cb 100644 (file)
@@ -596,7 +596,7 @@ static void hns_nic_self_test(struct net_device *ndev,
        st_param[1][0] = MAC_INTERNALLOOP_SERDES;
        st_param[1][1] = 1; /*serdes must exist*/
        st_param[2][0] = MAC_INTERNALLOOP_PHY; /* only supporte phy node*/
-       st_param[2][1] = ((!!(priv->ae_handle->phy_node)) &&
+       st_param[2][1] = ((!!(priv->ae_handle->phy_dev)) &&
                (priv->ae_handle->phy_if != PHY_INTERFACE_MODE_XGMII));
 
        if (eth_test->flags == ETH_TEST_FL_OFFLINE) {