net: hns: add uniform interface for phy connection

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>
This commit is contained in:
Kejian Yan 2016-06-03 10:55:16 +08:00 committed by David S. Miller
parent 7b2acae6fb
commit 652d39b0d5
8 changed files with 49 additions and 25 deletions

View 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)

View 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;

View 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;

View 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));

View 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;
};

View 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

View 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;

View 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) {