Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 67cd9a99 authored by Lin Yun Sheng's avatar Lin Yun Sheng Committed by David S. Miller
Browse files

net: hns: Use phy_driver to setup Phy loopback



Use function set_loopback in phy_driver to setup phy loopback
when doing ethtool self test.

Signed-off-by: default avatarLin Yun Sheng <linyunsheng@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f0f9b4ed
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -360,6 +360,7 @@ enum hnae_loop {
	MAC_INTERNALLOOP_MAC = 0,
	MAC_INTERNALLOOP_SERDES,
	MAC_INTERNALLOOP_PHY,
	MAC_LOOP_PHY_NONE,
	MAC_LOOP_NONE,
};

+34 −71
Original line number Diff line number Diff line
@@ -259,67 +259,27 @@ static const char hns_nic_test_strs[][ETH_GSTRING_LEN] = {

static int hns_nic_config_phy_loopback(struct phy_device *phy_dev, u8 en)
{
#define COPPER_CONTROL_REG 0
#define PHY_POWER_DOWN BIT(11)
#define PHY_LOOP_BACK BIT(14)
	u16 val = 0;

	if (phy_dev->is_c45) /* c45 branch adding for XGE PHY */
		return -ENOTSUPP;
	int err;

	if (en) {
		/* speed : 1000M */
		phy_write(phy_dev, HNS_PHY_PAGE_REG, 2);
		phy_write(phy_dev, 21, 0x1046);

		phy_write(phy_dev, HNS_PHY_PAGE_REG, 0);
		/* Force Master */
		phy_write(phy_dev, 9, 0x1F00);

		/* Soft-reset */
		phy_write(phy_dev, 0, 0x9140);
		/* If autoneg disabled,two soft-reset operations */
		phy_write(phy_dev, 0, 0x9140);

		phy_write(phy_dev, HNS_PHY_PAGE_REG, 0xFA);

		/* Default is 0x0400 */
		phy_write(phy_dev, 1, 0x418);

		/* Force 1000M Link, Default is 0x0200 */
		phy_write(phy_dev, 7, 0x20C);

		/* Powerup Fiber */
		phy_write(phy_dev, HNS_PHY_PAGE_REG, 1);
		val = phy_read(phy_dev, COPPER_CONTROL_REG);
		val &= ~PHY_POWER_DOWN;
		phy_write(phy_dev, COPPER_CONTROL_REG, val);

		/* Enable Phy Loopback */
		phy_write(phy_dev, HNS_PHY_PAGE_REG, 0);
		val = phy_read(phy_dev, COPPER_CONTROL_REG);
		val |= PHY_LOOP_BACK;
		val &= ~PHY_POWER_DOWN;
		phy_write(phy_dev, COPPER_CONTROL_REG, val);
	} else {
		phy_write(phy_dev, HNS_PHY_PAGE_REG, 0xFA);
		phy_write(phy_dev, 1, 0x400);
		phy_write(phy_dev, 7, 0x200);

		phy_write(phy_dev, HNS_PHY_PAGE_REG, 1);
		val = phy_read(phy_dev, COPPER_CONTROL_REG);
		val |= PHY_POWER_DOWN;
		phy_write(phy_dev, COPPER_CONTROL_REG, val);
		/* Doing phy loopback in offline state, phy resuming is
		 * needed to power up the device.
		 */
		err = phy_resume(phy_dev);
		if (err)
			goto out;

		phy_write(phy_dev, HNS_PHY_PAGE_REG, 0);
		phy_write(phy_dev, 9, 0xF00);
		err = phy_loopback(phy_dev, true);
	} else {
		err = phy_loopback(phy_dev, false);
		if (err)
			goto out;

		val = phy_read(phy_dev, COPPER_CONTROL_REG);
		val &= ~PHY_LOOP_BACK;
		val |= PHY_POWER_DOWN;
		phy_write(phy_dev, COPPER_CONTROL_REG, val);
		err = phy_suspend(phy_dev);
	}
	return 0;

out:
	return err;
}

static int __lb_setup(struct net_device *ndev,
@@ -332,10 +292,9 @@ static int __lb_setup(struct net_device *ndev,

	switch (loop) {
	case MAC_INTERNALLOOP_PHY:
		if ((phy_dev) && (!phy_dev->is_c45)) {
		ret = hns_nic_config_phy_loopback(phy_dev, 0x1);
			ret |= h->dev->ops->set_loopback(h, loop, 0x1);
		}
		if (!ret)
			ret = h->dev->ops->set_loopback(h, loop, 0x1);
		break;
	case MAC_INTERNALLOOP_MAC:
		if ((h->dev->ops->set_loopback) &&
@@ -346,16 +305,16 @@ static int __lb_setup(struct net_device *ndev,
		if (h->dev->ops->set_loopback)
			ret = h->dev->ops->set_loopback(h, loop, 0x1);
		break;
	case MAC_LOOP_PHY_NONE:
		ret = hns_nic_config_phy_loopback(phy_dev, 0x0);
	case MAC_LOOP_NONE:
		if ((phy_dev) && (!phy_dev->is_c45))
			ret |= hns_nic_config_phy_loopback(phy_dev, 0x0);

		if (h->dev->ops->set_loopback) {
		if (!ret && h->dev->ops->set_loopback) {
			if (priv->ae_handle->phy_if != PHY_INTERFACE_MODE_XGMII)
				ret |= h->dev->ops->set_loopback(h,
				ret = h->dev->ops->set_loopback(h,
					MAC_INTERNALLOOP_MAC, 0x0);

			ret |= h->dev->ops->set_loopback(h,
			if (!ret)
				ret = h->dev->ops->set_loopback(h,
					MAC_INTERNALLOOP_SERDES, 0x0);
		}
		break;
@@ -582,12 +541,15 @@ static int __lb_run_test(struct net_device *ndev,
	return ret_val;
}

static int __lb_down(struct net_device *ndev)
static int __lb_down(struct net_device *ndev, enum hnae_loop loop)
{
	struct hns_nic_priv *priv = netdev_priv(ndev);
	struct hnae_handle *h = priv->ae_handle;
	int ret;

	if (loop == MAC_INTERNALLOOP_PHY)
		ret = __lb_setup(ndev, MAC_LOOP_PHY_NONE);
	else
		ret = __lb_setup(ndev, MAC_LOOP_NONE);
	if (ret)
		netdev_err(ndev, "%s: __lb_setup return error(%d)!\n",
@@ -644,7 +606,8 @@ static void hns_nic_self_test(struct net_device *ndev,
			if (!data[test_index]) {
				data[test_index] = __lb_run_test(
					ndev, (enum hnae_loop)st_param[i][0]);
				(void)__lb_down(ndev);
				(void)__lb_down(ndev,
						(enum hnae_loop)st_param[i][0]);
			}

			if (data[test_index])