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

Commit e57f7a3f authored by Lendacky, Thomas's avatar Lendacky, Thomas Committed by David S. Miller
Browse files

amd-xgbe: Prepare for working with more than one type of phy



Prepare the code to be able to work with more than one type of phy by
adding additional callable functions into the phy interface and removing
phy specific settings/functions from non-phy related files.

Signed-off-by: default avatarTom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 43e0dcf7
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -2,7 +2,8 @@ obj-$(CONFIG_AMD_XGBE) += amd-xgbe.o

amd-xgbe-objs := xgbe-main.o xgbe-drv.o xgbe-dev.o \
		 xgbe-desc.o xgbe-ethtool.o xgbe-mdio.o \
		 xgbe-ptp.o
		 xgbe-ptp.o \
		 xgbe-phy-v1.o

amd-xgbe-$(CONFIG_AMD_XGBE_DCB) += xgbe-dcb.o
amd-xgbe-$(CONFIG_DEBUG_FS) += xgbe-debugfs.o
+19 −39
Original line number Diff line number Diff line
@@ -717,32 +717,26 @@ static void xgbe_enable_mac_interrupts(struct xgbe_prv_data *pdata)
	XGMAC_IOWRITE_BITS(pdata, MMC_TIER, ALL_INTERRUPTS, 0xffffffff);
}

static int xgbe_set_gmii_speed(struct xgbe_prv_data *pdata)
static int xgbe_set_speed(struct xgbe_prv_data *pdata, int speed)
{
	if (XGMAC_IOREAD_BITS(pdata, MAC_TCR, SS) == 0x3)
		return 0;

	XGMAC_IOWRITE_BITS(pdata, MAC_TCR, SS, 0x3);

	return 0;
}

static int xgbe_set_gmii_2500_speed(struct xgbe_prv_data *pdata)
{
	if (XGMAC_IOREAD_BITS(pdata, MAC_TCR, SS) == 0x2)
		return 0;
	unsigned int ss;

	XGMAC_IOWRITE_BITS(pdata, MAC_TCR, SS, 0x2);

	return 0;
	switch (speed) {
	case SPEED_1000:
		ss = 0x03;
		break;
	case SPEED_2500:
		ss = 0x02;
		break;
	case SPEED_10000:
		ss = 0x00;
		break;
	default:
		return -EINVAL;
	}

static int xgbe_set_xgmii_speed(struct xgbe_prv_data *pdata)
{
	if (XGMAC_IOREAD_BITS(pdata, MAC_TCR, SS) == 0)
		return 0;

	XGMAC_IOWRITE_BITS(pdata, MAC_TCR, SS, 0);
	if (XGMAC_IOREAD_BITS(pdata, MAC_TCR, SS) != ss)
		XGMAC_IOWRITE_BITS(pdata, MAC_TCR, SS, ss);

	return 0;
}
@@ -2469,19 +2463,7 @@ static void xgbe_config_jumbo_enable(struct xgbe_prv_data *pdata)

static void xgbe_config_mac_speed(struct xgbe_prv_data *pdata)
{
	switch (pdata->phy_speed) {
	case SPEED_10000:
		xgbe_set_xgmii_speed(pdata);
		break;

	case SPEED_2500:
		xgbe_set_gmii_2500_speed(pdata);
		break;

	case SPEED_1000:
		xgbe_set_gmii_speed(pdata);
		break;
	}
	xgbe_set_speed(pdata, pdata->phy_speed);
}

static void xgbe_config_checksum_offload(struct xgbe_prv_data *pdata)
@@ -3195,9 +3177,7 @@ void xgbe_init_function_ptrs_dev(struct xgbe_hw_if *hw_if)
	hw_if->read_mmd_regs = xgbe_read_mmd_regs;
	hw_if->write_mmd_regs = xgbe_write_mmd_regs;

	hw_if->set_gmii_speed = xgbe_set_gmii_speed;
	hw_if->set_gmii_2500_speed = xgbe_set_gmii_2500_speed;
	hw_if->set_xgmii_speed = xgbe_set_xgmii_speed;
	hw_if->set_speed = xgbe_set_speed;

	hw_if->enable_tx = xgbe_enable_tx;
	hw_if->disable_tx = xgbe_disable_tx;
+3 −3
Original line number Diff line number Diff line
@@ -778,7 +778,7 @@ static void xgbe_free_rx_data(struct xgbe_prv_data *pdata)
	DBGPR("<--xgbe_free_rx_data\n");
}

static int xgbe_phy_init(struct xgbe_prv_data *pdata)
static int xgbe_phy_reset(struct xgbe_prv_data *pdata)
{
	pdata->phy_link = -1;
	pdata->phy_speed = SPEED_UNKNOWN;
@@ -1292,8 +1292,8 @@ static int xgbe_open(struct net_device *netdev)

	DBGPR("-->xgbe_open\n");

	/* Initialize the phy */
	ret = xgbe_phy_init(pdata);
	/* Reset the phy settings */
	ret = xgbe_phy_reset(pdata);
	if (ret)
		return ret;

+1 −18
Original line number Diff line number Diff line
@@ -316,24 +316,7 @@ static int xgbe_set_settings(struct net_device *netdev,
	}

	if (cmd->autoneg == AUTONEG_DISABLE) {
		switch (speed) {
		case SPEED_10000:
			break;
		case SPEED_2500:
			if (pdata->speed_set != XGBE_SPEEDSET_2500_10000) {
				netdev_err(netdev, "unsupported speed %u\n",
					   speed);
				return -EINVAL;
			}
			break;
		case SPEED_1000:
			if (pdata->speed_set != XGBE_SPEEDSET_1000_10000) {
				netdev_err(netdev, "unsupported speed %u\n",
					   speed);
				return -EINVAL;
			}
			break;
		default:
		if (!pdata->phy_if.phy_valid_speed(pdata, speed)) {
			netdev_err(netdev, "unsupported speed %u\n", speed);
			return -EINVAL;
		}
+62 −152
Original line number Diff line number Diff line
@@ -125,6 +125,7 @@
#include <linux/of_net.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/of_device.h>
#include <linux/clk.h>
#include <linux/property.h>
#include <linux/acpi.h>
@@ -145,42 +146,6 @@ MODULE_PARM_DESC(debug, " Network interface message level setting");
static const u32 default_msg_level = (NETIF_MSG_LINK | NETIF_MSG_IFDOWN |
				      NETIF_MSG_IFUP);

static const u32 xgbe_serdes_blwc[] = {
	XGBE_SPEED_1000_BLWC,
	XGBE_SPEED_2500_BLWC,
	XGBE_SPEED_10000_BLWC,
};

static const u32 xgbe_serdes_cdr_rate[] = {
	XGBE_SPEED_1000_CDR,
	XGBE_SPEED_2500_CDR,
	XGBE_SPEED_10000_CDR,
};

static const u32 xgbe_serdes_pq_skew[] = {
	XGBE_SPEED_1000_PQ,
	XGBE_SPEED_2500_PQ,
	XGBE_SPEED_10000_PQ,
};

static const u32 xgbe_serdes_tx_amp[] = {
	XGBE_SPEED_1000_TXAMP,
	XGBE_SPEED_2500_TXAMP,
	XGBE_SPEED_10000_TXAMP,
};

static const u32 xgbe_serdes_dfe_tap_cfg[] = {
	XGBE_SPEED_1000_DFE_TAP_CONFIG,
	XGBE_SPEED_2500_DFE_TAP_CONFIG,
	XGBE_SPEED_10000_DFE_TAP_CONFIG,
};

static const u32 xgbe_serdes_dfe_tap_ena[] = {
	XGBE_SPEED_1000_DFE_TAP_ENABLE,
	XGBE_SPEED_2500_DFE_TAP_ENABLE,
	XGBE_SPEED_10000_DFE_TAP_ENABLE,
};

static void xgbe_default_config(struct xgbe_prv_data *pdata)
{
	DBGPR("-->xgbe_default_config\n");
@@ -207,9 +172,22 @@ static void xgbe_init_all_fptrs(struct xgbe_prv_data *pdata)
	xgbe_init_function_ptrs_dev(&pdata->hw_if);
	xgbe_init_function_ptrs_phy(&pdata->phy_if);
	xgbe_init_function_ptrs_desc(&pdata->desc_if);

	pdata->vdata->init_function_ptrs_phy_impl(&pdata->phy_if);
}

#ifdef CONFIG_ACPI
static const struct acpi_device_id xgbe_acpi_match[];

static struct xgbe_version_data *xgbe_acpi_vdata(struct xgbe_prv_data *pdata)
{
	const struct acpi_device_id *id;

	id = acpi_match_device(xgbe_acpi_match, pdata->dev);

	return id ? (struct xgbe_version_data *)id->driver_data : NULL;
}

static int xgbe_acpi_support(struct xgbe_prv_data *pdata)
{
	struct device *dev = pdata->dev;
@@ -237,6 +215,11 @@ static int xgbe_acpi_support(struct xgbe_prv_data *pdata)
	return 0;
}
#else   /* CONFIG_ACPI */
static struct xgbe_version_data *xgbe_acpi_vdata(struct xgbe_prv_data *pdata)
{
	return NULL;
}

static int xgbe_acpi_support(struct xgbe_prv_data *pdata)
{
	return -EINVAL;
@@ -244,6 +227,17 @@ static int xgbe_acpi_support(struct xgbe_prv_data *pdata)
#endif  /* CONFIG_ACPI */

#ifdef CONFIG_OF
static const struct of_device_id xgbe_of_match[];

static struct xgbe_version_data *xgbe_of_vdata(struct xgbe_prv_data *pdata)
{
	const struct of_device_id *id;

	id = of_match_device(xgbe_of_match, pdata->dev);

	return id ? (struct xgbe_version_data *)id->data : NULL;
}

static int xgbe_of_support(struct xgbe_prv_data *pdata)
{
	struct device *dev = pdata->dev;
@@ -292,6 +286,11 @@ static struct platform_device *xgbe_of_get_phy_pdev(struct xgbe_prv_data *pdata)
	return phy_pdev;
}
#else   /* CONFIG_OF */
static struct xgbe_version_data *xgbe_of_vdata(struct xgbe_prv_data *pdata)
{
	return NULL;
}

static int xgbe_of_support(struct xgbe_prv_data *pdata)
{
	return -EINVAL;
@@ -333,11 +332,17 @@ static struct platform_device *xgbe_get_phy_pdev(struct xgbe_prv_data *pdata)
	return phy_pdev;
}

static struct xgbe_version_data *xgbe_get_vdata(struct xgbe_prv_data *pdata)
{
	return pdata->use_acpi ? xgbe_acpi_vdata(pdata)
			       : xgbe_of_vdata(pdata);
}

static int xgbe_probe(struct platform_device *pdev)
{
	struct xgbe_prv_data *pdata;
	struct net_device *netdev;
	struct device *dev = &pdev->dev, *phy_dev;
	struct device *dev = &pdev->dev;
	struct platform_device *phy_pdev;
	struct resource *res;
	const char *phy_mode;
@@ -374,13 +379,17 @@ static int xgbe_probe(struct platform_device *pdev)
	/* Check if we should use ACPI or DT */
	pdata->use_acpi = dev->of_node ? 0 : 1;

	/* Get the version data */
	pdata->vdata = xgbe_get_vdata(pdata);

	phy_pdev = xgbe_get_phy_pdev(pdata);
	if (!phy_pdev) {
		dev_err(dev, "unable to obtain phy device\n");
		ret = -EINVAL;
		goto err_phydev;
	}
	phy_dev = &phy_pdev->dev;
	pdata->phy_pdev = phy_pdev;
	pdata->phy_dev = &phy_pdev->dev;

	if (pdev == phy_pdev) {
		/* New style device tree or ACPI:
@@ -492,115 +501,6 @@ static int xgbe_probe(struct platform_device *pdev)
	if (device_property_present(dev, XGBE_DMA_IRQS_PROPERTY))
		pdata->per_channel_irq = 1;

	/* Retrieve the PHY speedset */
	ret = device_property_read_u32(phy_dev, XGBE_SPEEDSET_PROPERTY,
				       &pdata->speed_set);
	if (ret) {
		dev_err(dev, "invalid %s property\n", XGBE_SPEEDSET_PROPERTY);
		goto err_io;
	}

	switch (pdata->speed_set) {
	case XGBE_SPEEDSET_1000_10000:
	case XGBE_SPEEDSET_2500_10000:
		break;
	default:
		dev_err(dev, "invalid %s property\n", XGBE_SPEEDSET_PROPERTY);
		ret = -EINVAL;
		goto err_io;
	}

	/* Retrieve the PHY configuration properties */
	if (device_property_present(phy_dev, XGBE_BLWC_PROPERTY)) {
		ret = device_property_read_u32_array(phy_dev,
						     XGBE_BLWC_PROPERTY,
						     pdata->serdes_blwc,
						     XGBE_SPEEDS);
		if (ret) {
			dev_err(dev, "invalid %s property\n",
				XGBE_BLWC_PROPERTY);
			goto err_io;
		}
	} else {
		memcpy(pdata->serdes_blwc, xgbe_serdes_blwc,
		       sizeof(pdata->serdes_blwc));
	}

	if (device_property_present(phy_dev, XGBE_CDR_RATE_PROPERTY)) {
		ret = device_property_read_u32_array(phy_dev,
						     XGBE_CDR_RATE_PROPERTY,
						     pdata->serdes_cdr_rate,
						     XGBE_SPEEDS);
		if (ret) {
			dev_err(dev, "invalid %s property\n",
				XGBE_CDR_RATE_PROPERTY);
			goto err_io;
		}
	} else {
		memcpy(pdata->serdes_cdr_rate, xgbe_serdes_cdr_rate,
		       sizeof(pdata->serdes_cdr_rate));
	}

	if (device_property_present(phy_dev, XGBE_PQ_SKEW_PROPERTY)) {
		ret = device_property_read_u32_array(phy_dev,
						     XGBE_PQ_SKEW_PROPERTY,
						     pdata->serdes_pq_skew,
						     XGBE_SPEEDS);
		if (ret) {
			dev_err(dev, "invalid %s property\n",
				XGBE_PQ_SKEW_PROPERTY);
			goto err_io;
		}
	} else {
		memcpy(pdata->serdes_pq_skew, xgbe_serdes_pq_skew,
		       sizeof(pdata->serdes_pq_skew));
	}

	if (device_property_present(phy_dev, XGBE_TX_AMP_PROPERTY)) {
		ret = device_property_read_u32_array(phy_dev,
						     XGBE_TX_AMP_PROPERTY,
						     pdata->serdes_tx_amp,
						     XGBE_SPEEDS);
		if (ret) {
			dev_err(dev, "invalid %s property\n",
				XGBE_TX_AMP_PROPERTY);
			goto err_io;
		}
	} else {
		memcpy(pdata->serdes_tx_amp, xgbe_serdes_tx_amp,
		       sizeof(pdata->serdes_tx_amp));
	}

	if (device_property_present(phy_dev, XGBE_DFE_CFG_PROPERTY)) {
		ret = device_property_read_u32_array(phy_dev,
						     XGBE_DFE_CFG_PROPERTY,
						     pdata->serdes_dfe_tap_cfg,
						     XGBE_SPEEDS);
		if (ret) {
			dev_err(dev, "invalid %s property\n",
				XGBE_DFE_CFG_PROPERTY);
			goto err_io;
		}
	} else {
		memcpy(pdata->serdes_dfe_tap_cfg, xgbe_serdes_dfe_tap_cfg,
		       sizeof(pdata->serdes_dfe_tap_cfg));
	}

	if (device_property_present(phy_dev, XGBE_DFE_ENA_PROPERTY)) {
		ret = device_property_read_u32_array(phy_dev,
						     XGBE_DFE_ENA_PROPERTY,
						     pdata->serdes_dfe_tap_ena,
						     XGBE_SPEEDS);
		if (ret) {
			dev_err(dev, "invalid %s property\n",
				XGBE_DFE_ENA_PROPERTY);
			goto err_io;
		}
	} else {
		memcpy(pdata->serdes_dfe_tap_ena, xgbe_serdes_dfe_tap_ena,
		       sizeof(pdata->serdes_dfe_tap_ena));
	}

	/* Obtain device settings unique to ACPI/OF */
	if (pdata->use_acpi)
		ret = xgbe_acpi_support(pdata);
@@ -705,7 +605,9 @@ static int xgbe_probe(struct platform_device *pdev)
	XGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, UDP4TE, 1);

	/* Call MDIO/PHY initialization routine */
	pdata->phy_if.phy_init(pdata);
	ret = pdata->phy_if.phy_init(pdata);
	if (ret)
		goto err_io;

	/* Set device operations */
	netdev->netdev_ops = xgbe_get_netdev_ops();
@@ -780,8 +682,6 @@ static int xgbe_probe(struct platform_device *pdev)

	xgbe_debugfs_init(pdata);

	platform_device_put(phy_pdev);

	netdev_notice(netdev, "net device enabled\n");

	DBGPR("<-- xgbe_probe\n");
@@ -817,6 +717,8 @@ static int xgbe_remove(struct platform_device *pdev)

	xgbe_ptp_unregister(pdata);

	pdata->phy_if.phy_exit(pdata);

	flush_workqueue(pdata->an_workqueue);
	destroy_workqueue(pdata->an_workqueue);

@@ -825,6 +727,8 @@ static int xgbe_remove(struct platform_device *pdev)

	unregister_netdev(netdev);

	platform_device_put(pdata->phy_pdev);

	free_netdev(netdev);

	DBGPR("<--xgbe_remove\n");
@@ -879,9 +783,14 @@ static int xgbe_resume(struct device *dev)
}
#endif /* CONFIG_PM */

static const struct xgbe_version_data xgbe_v1 = {
	.init_function_ptrs_phy_impl	= xgbe_init_function_ptrs_phy_v1,
};

#ifdef CONFIG_ACPI
static const struct acpi_device_id xgbe_acpi_match[] = {
	{ "AMDI8001", 0 },
	{ .id = "AMDI8001",
	  .driver_data = (kernel_ulong_t)&xgbe_v1 },
	{},
};

@@ -890,7 +799,8 @@ MODULE_DEVICE_TABLE(acpi, xgbe_acpi_match);

#ifdef CONFIG_OF
static const struct of_device_id xgbe_of_match[] = {
	{ .compatible = "amd,xgbe-seattle-v1a", },
	{ .compatible = "amd,xgbe-seattle-v1a",
	  .data = &xgbe_v1 },
	{},
};

Loading