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

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
...@@ -2,7 +2,8 @@ obj-$(CONFIG_AMD_XGBE) += amd-xgbe.o ...@@ -2,7 +2,8 @@ obj-$(CONFIG_AMD_XGBE) += amd-xgbe.o
amd-xgbe-objs := xgbe-main.o xgbe-drv.o xgbe-dev.o \ amd-xgbe-objs := xgbe-main.o xgbe-drv.o xgbe-dev.o \
xgbe-desc.o xgbe-ethtool.o xgbe-mdio.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_AMD_XGBE_DCB) += xgbe-dcb.o
amd-xgbe-$(CONFIG_DEBUG_FS) += xgbe-debugfs.o amd-xgbe-$(CONFIG_DEBUG_FS) += xgbe-debugfs.o
...@@ -717,32 +717,26 @@ static void xgbe_enable_mac_interrupts(struct xgbe_prv_data *pdata) ...@@ -717,32 +717,26 @@ static void xgbe_enable_mac_interrupts(struct xgbe_prv_data *pdata)
XGMAC_IOWRITE_BITS(pdata, MMC_TIER, ALL_INTERRUPTS, 0xffffffff); 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) unsigned int ss;
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;
XGMAC_IOWRITE_BITS(pdata, MAC_TCR, SS, 0x2); switch (speed) {
case SPEED_1000:
return 0; ss = 0x03;
} break;
case SPEED_2500:
static int xgbe_set_xgmii_speed(struct xgbe_prv_data *pdata) ss = 0x02;
{ break;
if (XGMAC_IOREAD_BITS(pdata, MAC_TCR, SS) == 0) case SPEED_10000:
return 0; ss = 0x00;
break;
default:
return -EINVAL;
}
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; return 0;
} }
...@@ -2469,19 +2463,7 @@ static void xgbe_config_jumbo_enable(struct xgbe_prv_data *pdata) ...@@ -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) static void xgbe_config_mac_speed(struct xgbe_prv_data *pdata)
{ {
switch (pdata->phy_speed) { xgbe_set_speed(pdata, 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;
}
} }
static void xgbe_config_checksum_offload(struct xgbe_prv_data *pdata) 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) ...@@ -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->read_mmd_regs = xgbe_read_mmd_regs;
hw_if->write_mmd_regs = xgbe_write_mmd_regs; hw_if->write_mmd_regs = xgbe_write_mmd_regs;
hw_if->set_gmii_speed = xgbe_set_gmii_speed; hw_if->set_speed = xgbe_set_speed;
hw_if->set_gmii_2500_speed = xgbe_set_gmii_2500_speed;
hw_if->set_xgmii_speed = xgbe_set_xgmii_speed;
hw_if->enable_tx = xgbe_enable_tx; hw_if->enable_tx = xgbe_enable_tx;
hw_if->disable_tx = xgbe_disable_tx; hw_if->disable_tx = xgbe_disable_tx;
......
...@@ -778,7 +778,7 @@ static void xgbe_free_rx_data(struct xgbe_prv_data *pdata) ...@@ -778,7 +778,7 @@ static void xgbe_free_rx_data(struct xgbe_prv_data *pdata)
DBGPR("<--xgbe_free_rx_data\n"); 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_link = -1;
pdata->phy_speed = SPEED_UNKNOWN; pdata->phy_speed = SPEED_UNKNOWN;
...@@ -1292,8 +1292,8 @@ static int xgbe_open(struct net_device *netdev) ...@@ -1292,8 +1292,8 @@ static int xgbe_open(struct net_device *netdev)
DBGPR("-->xgbe_open\n"); DBGPR("-->xgbe_open\n");
/* Initialize the phy */ /* Reset the phy settings */
ret = xgbe_phy_init(pdata); ret = xgbe_phy_reset(pdata);
if (ret) if (ret)
return ret; return ret;
......
...@@ -316,24 +316,7 @@ static int xgbe_set_settings(struct net_device *netdev, ...@@ -316,24 +316,7 @@ static int xgbe_set_settings(struct net_device *netdev,
} }
if (cmd->autoneg == AUTONEG_DISABLE) { if (cmd->autoneg == AUTONEG_DISABLE) {
switch (speed) { if (!pdata->phy_if.phy_valid_speed(pdata, 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:
netdev_err(netdev, "unsupported speed %u\n", speed); netdev_err(netdev, "unsupported speed %u\n", speed);
return -EINVAL; return -EINVAL;
} }
......
...@@ -125,6 +125,7 @@ ...@@ -125,6 +125,7 @@
#include <linux/of_net.h> #include <linux/of_net.h>
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/of_device.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/property.h> #include <linux/property.h>
#include <linux/acpi.h> #include <linux/acpi.h>
...@@ -145,42 +146,6 @@ MODULE_PARM_DESC(debug, " Network interface message level setting"); ...@@ -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 | static const u32 default_msg_level = (NETIF_MSG_LINK | NETIF_MSG_IFDOWN |
NETIF_MSG_IFUP); 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) static void xgbe_default_config(struct xgbe_prv_data *pdata)
{ {
DBGPR("-->xgbe_default_config\n"); DBGPR("-->xgbe_default_config\n");
...@@ -207,9 +172,22 @@ static void xgbe_init_all_fptrs(struct xgbe_prv_data *pdata) ...@@ -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_dev(&pdata->hw_if);
xgbe_init_function_ptrs_phy(&pdata->phy_if); xgbe_init_function_ptrs_phy(&pdata->phy_if);
xgbe_init_function_ptrs_desc(&pdata->desc_if); xgbe_init_function_ptrs_desc(&pdata->desc_if);
pdata->vdata->init_function_ptrs_phy_impl(&pdata->phy_if);
} }
#ifdef CONFIG_ACPI #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) static int xgbe_acpi_support(struct xgbe_prv_data *pdata)
{ {
struct device *dev = pdata->dev; struct device *dev = pdata->dev;
...@@ -237,6 +215,11 @@ static int xgbe_acpi_support(struct xgbe_prv_data *pdata) ...@@ -237,6 +215,11 @@ static int xgbe_acpi_support(struct xgbe_prv_data *pdata)
return 0; return 0;
} }
#else /* CONFIG_ACPI */ #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) static int xgbe_acpi_support(struct xgbe_prv_data *pdata)
{ {
return -EINVAL; return -EINVAL;
...@@ -244,6 +227,17 @@ static int xgbe_acpi_support(struct xgbe_prv_data *pdata) ...@@ -244,6 +227,17 @@ static int xgbe_acpi_support(struct xgbe_prv_data *pdata)
#endif /* CONFIG_ACPI */ #endif /* CONFIG_ACPI */
#ifdef CONFIG_OF #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) static int xgbe_of_support(struct xgbe_prv_data *pdata)
{ {
struct device *dev = pdata->dev; struct device *dev = pdata->dev;
...@@ -292,6 +286,11 @@ static struct platform_device *xgbe_of_get_phy_pdev(struct xgbe_prv_data *pdata) ...@@ -292,6 +286,11 @@ static struct platform_device *xgbe_of_get_phy_pdev(struct xgbe_prv_data *pdata)
return phy_pdev; return phy_pdev;
} }
#else /* CONFIG_OF */ #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) static int xgbe_of_support(struct xgbe_prv_data *pdata)
{ {
return -EINVAL; return -EINVAL;
...@@ -333,11 +332,17 @@ static struct platform_device *xgbe_get_phy_pdev(struct xgbe_prv_data *pdata) ...@@ -333,11 +332,17 @@ static struct platform_device *xgbe_get_phy_pdev(struct xgbe_prv_data *pdata)
return phy_pdev; 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) static int xgbe_probe(struct platform_device *pdev)
{ {
struct xgbe_prv_data *pdata; struct xgbe_prv_data *pdata;
struct net_device *netdev; struct net_device *netdev;
struct device *dev = &pdev->dev, *phy_dev; struct device *dev = &pdev->dev;
struct platform_device *phy_pdev; struct platform_device *phy_pdev;
struct resource *res; struct resource *res;
const char *phy_mode; const char *phy_mode;
...@@ -374,13 +379,17 @@ static int xgbe_probe(struct platform_device *pdev) ...@@ -374,13 +379,17 @@ static int xgbe_probe(struct platform_device *pdev)
/* Check if we should use ACPI or DT */ /* Check if we should use ACPI or DT */
pdata->use_acpi = dev->of_node ? 0 : 1; 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); phy_pdev = xgbe_get_phy_pdev(pdata);
if (!phy_pdev) { if (!phy_pdev) {
dev_err(dev, "unable to obtain phy device\n"); dev_err(dev, "unable to obtain phy device\n");
ret = -EINVAL; ret = -EINVAL;
goto err_phydev; goto err_phydev;
} }
phy_dev = &phy_pdev->dev; pdata->phy_pdev = phy_pdev;
pdata->phy_dev = &phy_pdev->dev;
if (pdev == phy_pdev) { if (pdev == phy_pdev) {
/* New style device tree or ACPI: /* New style device tree or ACPI:
...@@ -492,115 +501,6 @@ static int xgbe_probe(struct platform_device *pdev) ...@@ -492,115 +501,6 @@ static int xgbe_probe(struct platform_device *pdev)
if (device_property_present(dev, XGBE_DMA_IRQS_PROPERTY)) if (device_property_present(dev, XGBE_DMA_IRQS_PROPERTY))
pdata->per_channel_irq = 1; 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 */ /* Obtain device settings unique to ACPI/OF */
if (pdata->use_acpi) if (pdata->use_acpi)
ret = xgbe_acpi_support(pdata); ret = xgbe_acpi_support(pdata);
...@@ -705,7 +605,9 @@ static int xgbe_probe(struct platform_device *pdev) ...@@ -705,7 +605,9 @@ static int xgbe_probe(struct platform_device *pdev)
XGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, UDP4TE, 1); XGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, UDP4TE, 1);
/* Call MDIO/PHY initialization routine */ /* 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 */ /* Set device operations */
netdev->netdev_ops = xgbe_get_netdev_ops(); netdev->netdev_ops = xgbe_get_netdev_ops();
...@@ -780,8 +682,6 @@ static int xgbe_probe(struct platform_device *pdev) ...@@ -780,8 +682,6 @@ static int xgbe_probe(struct platform_device *pdev)
xgbe_debugfs_init(pdata); xgbe_debugfs_init(pdata);
platform_device_put(phy_pdev);
netdev_notice(netdev, "net device enabled\n"); netdev_notice(netdev, "net device enabled\n");
DBGPR("<-- xgbe_probe\n"); DBGPR("<-- xgbe_probe\n");
...@@ -817,6 +717,8 @@ static int xgbe_remove(struct platform_device *pdev) ...@@ -817,6 +717,8 @@ static int xgbe_remove(struct platform_device *pdev)
xgbe_ptp_unregister(pdata); xgbe_ptp_unregister(pdata);
pdata->phy_if.phy_exit(pdata);
flush_workqueue(pdata->an_workqueue); flush_workqueue(pdata->an_workqueue);
destroy_workqueue(pdata->an_workqueue); destroy_workqueue(pdata->an_workqueue);
...@@ -825,6 +727,8 @@ static int xgbe_remove(struct platform_device *pdev) ...@@ -825,6 +727,8 @@ static int xgbe_remove(struct platform_device *pdev)
unregister_netdev(netdev); unregister_netdev(netdev);
platform_device_put(pdata->phy_pdev);
free_netdev(netdev); free_netdev(netdev);
DBGPR("<--xgbe_remove\n"); DBGPR("<--xgbe_remove\n");
...@@ -879,9 +783,14 @@ static int xgbe_resume(struct device *dev) ...@@ -879,9 +783,14 @@ static int xgbe_resume(struct device *dev)
} }
#endif /* CONFIG_PM */ #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 #ifdef CONFIG_ACPI
static const struct acpi_device_id xgbe_acpi_match[] = { 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); ...@@ -890,7 +799,8 @@ MODULE_DEVICE_TABLE(acpi, xgbe_acpi_match);
#ifdef CONFIG_OF #ifdef CONFIG_OF
static const struct of_device_id xgbe_of_match[] = { static const struct of_device_id xgbe_of_match[] = {
{ .compatible = "amd,xgbe-seattle-v1a", }, { .compatible = "amd,xgbe-seattle-v1a",
.data = &xgbe_v1 },
{}, {},
}; };
......
This diff is collapsed.
This diff is collapsed.
...@@ -129,7 +129,7 @@ ...@@ -129,7 +129,7 @@
#include <net/dcbnl.h> #include <net/dcbnl.h>
#define XGBE_DRV_NAME "amd-xgbe" #define XGBE_DRV_NAME "amd-xgbe"
#define XGBE_DRV_VERSION "1.0.2" #define XGBE_DRV_VERSION "1.0.3"
#define XGBE_DRV_DESC "AMD 10 Gigabit Ethernet Driver" #define XGBE_DRV_DESC "AMD 10 Gigabit Ethernet Driver"
/* Descriptor related defines */ /* Descriptor related defines */
...@@ -191,12 +191,6 @@ ...@@ -191,12 +191,6 @@
#define XGBE_PHY_MODE_PROPERTY "phy-mode" #define XGBE_PHY_MODE_PROPERTY "phy-mode"
#define XGBE_DMA_IRQS_PROPERTY "amd,per-channel-interrupt" #define XGBE_DMA_IRQS_PROPERTY "amd,per-channel-interrupt"
#define XGBE_SPEEDSET_PROPERTY "amd,speed-set" #define XGBE_SPEEDSET_PROPERTY "amd,speed-set"
#define XGBE_BLWC_PROPERTY "amd,serdes-blwc"
#define XGBE_CDR_RATE_PROPERTY "amd,serdes-cdr-rate"
#define XGBE_PQ_SKEW_PROPERTY "amd,serdes-pq-skew"
#define XGBE_TX_AMP_PROPERTY "amd,serdes-tx-amp"
#define XGBE_DFE_CFG_PROPERTY "amd,serdes-dfe-tap-config"
#define XGBE_DFE_ENA_PROPERTY "amd,serdes-dfe-tap-enable"
/* Device-tree clock names */ /* Device-tree clock names */
#define XGBE_DMA_CLOCK "dma_clk" #define XGBE_DMA_CLOCK "dma_clk"
...@@ -274,40 +268,6 @@ ...@@ -274,40 +268,6 @@
#define XGBE_AN_PG_RCV 0x04 #define XGBE_AN_PG_RCV 0x04
#define XGBE_AN_INT_MASK 0x07 #define XGBE_AN_INT_MASK 0x07
/* Rate-change complete wait/retry count */
#define XGBE_RATECHANGE_COUNT 500
/* Default SerDes settings */
#define XGBE_SPEED_10000_BLWC 0
#define XGBE_SPEED_10000_CDR 0x7
#define XGBE_SPEED_10000_PLL 0x1
#define XGBE_SPEED_10000_PQ 0x12
#define XGBE_SPEED_10000_RATE 0x0
#define XGBE_SPEED_10000_TXAMP 0xa
#define XGBE_SPEED_10000_WORD 0x7
#define XGBE_SPEED_10000_DFE_TAP_CONFIG 0x1
#define XGBE_SPEED_10000_DFE_TAP_ENABLE 0x7f
#define XGBE_SPEED_2500_BLWC 1
#define XGBE_SPEED_2500_CDR 0x2
#define XGBE_SPEED_2500_PLL 0x0
#define XGBE_SPEED_2500_PQ 0xa
#define XGBE_SPEED_2500_RATE 0x1
#define XGBE_SPEED_2500_TXAMP 0xf
#define XGBE_SPEED_2500_WORD 0x1
#define XGBE_SPEED_2500_DFE_TAP_CONFIG 0x3
#define XGBE_SPEED_2500_DFE_TAP_ENABLE 0x0
#define XGBE_SPEED_1000_BLWC 1
#define XGBE_SPEED_1000_CDR 0x2
#define XGBE_SPEED_1000_PLL 0x0
#define XGBE_SPEED_1000_PQ 0xa
#define XGBE_SPEED_1000_RATE 0x3
#define XGBE_SPEED_1000_TXAMP 0xf
#define XGBE_SPEED_1000_WORD 0x1
#define XGBE_SPEED_1000_DFE_TAP_CONFIG 0x3
#define XGBE_SPEED_1000_DFE_TAP_ENABLE 0x0
struct xgbe_prv_data; struct xgbe_prv_data;
struct xgbe_packet_data { struct xgbe_packet_data {
...@@ -527,8 +487,10 @@ enum xgbe_rx { ...@@ -527,8 +487,10 @@ enum xgbe_rx {
}; };
enum xgbe_mode { enum xgbe_mode {
XGBE_MODE_KR = 0, XGBE_MODE_KX_1000 = 0,
XGBE_MODE_KX, XGBE_MODE_KX_2500,
XGBE_MODE_KR,
XGBE_MODE_UNKNOWN,
}; };
enum xgbe_speedset { enum xgbe_speedset {
...@@ -624,9 +586,7 @@ struct xgbe_hw_if { ...@@ -624,9 +586,7 @@ struct xgbe_hw_if {
int (*read_mmd_regs)(struct xgbe_prv_data *, int, int); int (*read_mmd_regs)(struct xgbe_prv_data *, int, int);
void (*write_mmd_regs)(struct xgbe_prv_data *, int, int, int); void (*write_mmd_regs)(struct xgbe_prv_data *, int, int, int);
int (*set_gmii_speed)(struct xgbe_prv_data *); int (*set_speed)(struct xgbe_prv_data *, int);
int (*set_gmii_2500_speed)(struct xgbe_prv_data *);
int (*set_xgmii_speed)(struct xgbe_prv_data *);
void (*enable_tx)(struct xgbe_prv_data *); void (*enable_tx)(struct xgbe_prv_data *);
void (*disable_tx)(struct xgbe_prv_data *); void (*disable_tx)(struct xgbe_prv_data *);
...@@ -707,9 +667,50 @@ struct xgbe_hw_if { ...@@ -707,9 +667,50 @@ struct xgbe_hw_if {
int (*set_rss_lookup_table)(struct xgbe_prv_data *, const u32 *); int (*set_rss_lookup_table)(struct xgbe_prv_data *, const u32 *);
}; };
/* This structure represents implementation specific routines for an
* implementation of a PHY. All routines are required unless noted below.
* Optional routines:
* kr_training_pre, kr_training_post
*/
struct xgbe_phy_impl_if {
/* Perform Setup/teardown actions */
int (*init)(struct xgbe_prv_data *);
void (*exit)(struct xgbe_prv_data *);
/* Perform start/stop specific actions */
int (*reset)(struct xgbe_prv_data *);
int (*start)(struct xgbe_prv_data *);
void (*stop)(struct xgbe_prv_data *);
/* Return the link status */
int (*link_status)(struct xgbe_prv_data *);
/* Indicate if a particular speed is valid */
bool (*valid_speed)(struct xgbe_prv_data *, int);
/* Check if the specified mode can/should be used */
bool (*use_mode)(struct xgbe_prv_data *, enum xgbe_mode);
/* Switch the PHY into various modes */
void (*set_mode)(struct xgbe_prv_data *, enum xgbe_mode);
/* Retrieve mode needed for a specific speed */
enum xgbe_mode (*get_mode)(struct xgbe_prv_data *, int);
/* Retrieve new/next mode when trying to auto-negotiate */
enum xgbe_mode (*switch_mode)(struct xgbe_prv_data *);
/* Retrieve current mode */
enum xgbe_mode (*cur_mode)(struct xgbe_prv_data *);
/* Process results of auto-negotiation */
enum xgbe_mode (*an_outcome)(struct xgbe_prv_data *);
/* Pre/Post KR training enablement support */
void (*kr_training_pre)(struct xgbe_prv_data *);
void (*kr_training_post)(struct xgbe_prv_data *);
};
struct xgbe_phy_if { struct xgbe_phy_if {
/* For initial PHY setup */ /* For PHY setup/teardown */
void (*phy_init)(struct xgbe_prv_data *); int (*phy_init)(struct xgbe_prv_data *);
void (*phy_exit)(struct xgbe_prv_data *);
/* For PHY support when setting device up/down */ /* For PHY support when setting device up/down */
int (*phy_reset)(struct xgbe_prv_data *); int (*phy_reset)(struct xgbe_prv_data *);
...@@ -719,6 +720,12 @@ struct xgbe_phy_if { ...@@ -719,6 +720,12 @@ struct xgbe_phy_if {
/* For PHY support while device is up */ /* For PHY support while device is up */
void (*phy_status)(struct xgbe_prv_data *); void (*phy_status)(struct xgbe_prv_data *);
int (*phy_config_aneg)(struct xgbe_prv_data *); int (*phy_config_aneg)(struct xgbe_prv_data *);
/* For PHY settings validation */
bool (*phy_valid_speed)(struct xgbe_prv_data *, int);
/* PHY implementation specific services */
struct xgbe_phy_impl_if phy_impl;
}; };
struct xgbe_desc_if { struct xgbe_desc_if {
...@@ -778,11 +785,20 @@ struct xgbe_hw_features { ...@@ -778,11 +785,20 @@ struct xgbe_hw_features {
unsigned int aux_snap_num; /* Number of Aux snapshot inputs */ unsigned int aux_snap_num; /* Number of Aux snapshot inputs */
}; };
struct xgbe_version_data {
void (*init_function_ptrs_phy_impl)(struct xgbe_phy_if *);
};
struct xgbe_prv_data { struct xgbe_prv_data {
struct net_device *netdev; struct net_device *netdev;
struct platform_device *pdev; struct platform_device *pdev;
struct acpi_device *adev; struct acpi_device *adev;
struct device *dev; struct device *dev;
struct platform_device *phy_pdev;
struct device *phy_dev;
/* Version related data */
struct xgbe_version_data *vdata;
/* ACPI or DT flag */ /* ACPI or DT flag */
unsigned int use_acpi; unsigned int use_acpi;
...@@ -928,6 +944,8 @@ struct xgbe_prv_data { ...@@ -928,6 +944,8 @@ struct xgbe_prv_data {
int phy_speed; int phy_speed;
/* MDIO/PHY related settings */ /* MDIO/PHY related settings */
unsigned int phy_started;
void *phy_data;
struct xgbe_phy phy; struct xgbe_phy phy;
int mdio_mmd; int mdio_mmd;
unsigned long link_check; unsigned long link_check;
...@@ -938,21 +956,6 @@ struct xgbe_prv_data { ...@@ -938,21 +956,6 @@ struct xgbe_prv_data {
int an_irq; int an_irq;
struct work_struct an_irq_work; struct work_struct an_irq_work;
unsigned int speed_set;
/* SerDes UEFI configurable settings.
* Switching between modes/speeds requires new values for some
* SerDes settings. The values can be supplied as device
* properties in array format. The first array entry is for
* 1GbE, second for 2.5GbE and third for 10GbE
*/
u32 serdes_blwc[XGBE_SPEEDS];
u32 serdes_cdr_rate[XGBE_SPEEDS];
u32 serdes_pq_skew[XGBE_SPEEDS];
u32 serdes_tx_amp[XGBE_SPEEDS];
u32 serdes_dfe_tap_cfg[XGBE_SPEEDS];
u32 serdes_dfe_tap_ena[XGBE_SPEEDS];
/* Auto-negotiation state machine support */ /* Auto-negotiation state machine support */
unsigned int an_int; unsigned int an_int;
struct mutex an_mutex; struct mutex an_mutex;
...@@ -982,6 +985,7 @@ struct xgbe_prv_data { ...@@ -982,6 +985,7 @@ struct xgbe_prv_data {
void xgbe_init_function_ptrs_dev(struct xgbe_hw_if *); void xgbe_init_function_ptrs_dev(struct xgbe_hw_if *);
void xgbe_init_function_ptrs_phy(struct xgbe_phy_if *); void xgbe_init_function_ptrs_phy(struct xgbe_phy_if *);
void xgbe_init_function_ptrs_phy_v1(struct xgbe_phy_if *);
void xgbe_init_function_ptrs_desc(struct xgbe_desc_if *); void xgbe_init_function_ptrs_desc(struct xgbe_desc_if *);
const struct net_device_ops *xgbe_get_netdev_ops(void); const struct net_device_ops *xgbe_get_netdev_ops(void);
const struct ethtool_ops *xgbe_get_ethtool_ops(void); const struct ethtool_ops *xgbe_get_ethtool_ops(void);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment