Commit 8a769c65 authored by David S. Miller's avatar David S. Miller

Merge branch 'stmmac-intel-Fixes-and-cleanups-after-dwmac-intel-split'

Andy Shevchenko says:

====================
stmmac: intel: Fixes and cleanups after dwmac-intel split

Seems the split of dwmac-intel didn't go well and on top of that new
functionality in the driver has not been properly tested.

Patch 1 fixes a nasty kernel crash due to missed error handling.
Patches 2 and 3 fix the incorrect split (clock and PCI bar handling).

Patch 4 converts driver to use new PCI IRQ allocation API.

The rest is a set of clean ups that may have been done in the initial
submission.

Series has been tested on couple of Elkhart Lake platforms with different
behaviour of ethernet hardware.

Changelog v3:
- added the cover letter (David)
- appended separate fix as a first patch
- marked patches 2 and 3 with Fixes tag
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents fe4f961e 29e0c2f3
......@@ -30,6 +30,6 @@ obj-$(CONFIG_DWMAC_GENERIC) += dwmac-generic.o
stmmac-platform-objs:= stmmac_platform.o
dwmac-altr-socfpga-objs := altr_tse_pcs.o dwmac-socfpga.o
obj-$(CONFIG_DWMAC_INTEL) += dwmac-intel.o
obj-$(CONFIG_STMMAC_PCI) += stmmac-pci.o
obj-$(CONFIG_DWMAC_INTEL) += dwmac-intel.o
stmmac-pci-objs:= stmmac_pci.o
......@@ -83,13 +83,9 @@ static int intel_serdes_powerup(struct net_device *ndev, void *priv_data)
serdes_phy_addr = intel_priv->mdio_adhoc_addr;
/* assert clk_req */
data = mdiobus_read(priv->mii, serdes_phy_addr,
SERDES_GCR0);
data = mdiobus_read(priv->mii, serdes_phy_addr, SERDES_GCR0);
data |= SERDES_PLL_CLK;
mdiobus_write(priv->mii, serdes_phy_addr,
SERDES_GCR0, data);
mdiobus_write(priv->mii, serdes_phy_addr, SERDES_GCR0, data);
/* check for clk_ack assertion */
data = serdes_status_poll(priv, serdes_phy_addr,
......@@ -103,13 +99,9 @@ static int intel_serdes_powerup(struct net_device *ndev, void *priv_data)
}
/* assert lane reset */
data = mdiobus_read(priv->mii, serdes_phy_addr,
SERDES_GCR0);
data = mdiobus_read(priv->mii, serdes_phy_addr, SERDES_GCR0);
data |= SERDES_RST;
mdiobus_write(priv->mii, serdes_phy_addr,
SERDES_GCR0, data);
mdiobus_write(priv->mii, serdes_phy_addr, SERDES_GCR0, data);
/* check for assert lane reset reflection */
data = serdes_status_poll(priv, serdes_phy_addr,
......@@ -123,14 +115,12 @@ static int intel_serdes_powerup(struct net_device *ndev, void *priv_data)
}
/* move power state to P0 */
data = mdiobus_read(priv->mii, serdes_phy_addr,
SERDES_GCR0);
data = mdiobus_read(priv->mii, serdes_phy_addr, SERDES_GCR0);
data &= ~SERDES_PWR_ST_MASK;
data |= SERDES_PWR_ST_P0 << SERDES_PWR_ST_SHIFT;
mdiobus_write(priv->mii, serdes_phy_addr,
SERDES_GCR0, data);
mdiobus_write(priv->mii, serdes_phy_addr, SERDES_GCR0, data);
/* Check for P0 state */
data = serdes_status_poll(priv, serdes_phy_addr,
......@@ -159,14 +149,12 @@ static void intel_serdes_powerdown(struct net_device *ndev, void *intel_data)
serdes_phy_addr = intel_priv->mdio_adhoc_addr;
/* move power state to P3 */
data = mdiobus_read(priv->mii, serdes_phy_addr,
SERDES_GCR0);
data = mdiobus_read(priv->mii, serdes_phy_addr, SERDES_GCR0);
data &= ~SERDES_PWR_ST_MASK;
data |= SERDES_PWR_ST_P3 << SERDES_PWR_ST_SHIFT;
mdiobus_write(priv->mii, serdes_phy_addr,
SERDES_GCR0, data);
mdiobus_write(priv->mii, serdes_phy_addr, SERDES_GCR0, data);
/* Check for P3 state */
data = serdes_status_poll(priv, serdes_phy_addr,
......@@ -180,13 +168,9 @@ static void intel_serdes_powerdown(struct net_device *ndev, void *intel_data)
}
/* de-assert clk_req */
data = mdiobus_read(priv->mii, serdes_phy_addr,
SERDES_GCR0);
data = mdiobus_read(priv->mii, serdes_phy_addr, SERDES_GCR0);
data &= ~SERDES_PLL_CLK;
mdiobus_write(priv->mii, serdes_phy_addr,
SERDES_GCR0, data);
mdiobus_write(priv->mii, serdes_phy_addr, SERDES_GCR0, data);
/* check for clk_ack de-assert */
data = serdes_status_poll(priv, serdes_phy_addr,
......@@ -200,13 +184,9 @@ static void intel_serdes_powerdown(struct net_device *ndev, void *intel_data)
}
/* de-assert lane reset */
data = mdiobus_read(priv->mii, serdes_phy_addr,
SERDES_GCR0);
data = mdiobus_read(priv->mii, serdes_phy_addr, SERDES_GCR0);
data &= ~SERDES_RST;
mdiobus_write(priv->mii, serdes_phy_addr,
SERDES_GCR0, data);
mdiobus_write(priv->mii, serdes_phy_addr, SERDES_GCR0, data);
/* check for de-assert lane reset reflection */
data = serdes_status_poll(priv, serdes_phy_addr,
......@@ -252,6 +232,7 @@ static void common_default_data(struct plat_stmmacenet_data *plat)
static int intel_mgbe_common_data(struct pci_dev *pdev,
struct plat_stmmacenet_data *plat)
{
int ret;
int i;
plat->clk_csr = 5;
......@@ -324,7 +305,12 @@ static int intel_mgbe_common_data(struct pci_dev *pdev,
dev_warn(&pdev->dev, "Fail to register stmmac-clk\n");
plat->stmmac_clk = NULL;
}
clk_prepare_enable(plat->stmmac_clk);
ret = clk_prepare_enable(plat->stmmac_clk);
if (ret) {
clk_unregister_fixed_rate(plat->stmmac_clk);
return ret;
}
/* Set default value for multicast hash bins */
plat->multicast_filter_bins = HASH_TABLE_SIZE;
......@@ -341,16 +327,11 @@ static int intel_mgbe_common_data(struct pci_dev *pdev,
static int ehl_common_data(struct pci_dev *pdev,
struct plat_stmmacenet_data *plat)
{
int ret;
plat->rx_queues_to_use = 8;
plat->tx_queues_to_use = 8;
plat->clk_ptp_rate = 200000000;
ret = intel_mgbe_common_data(pdev, plat);
if (ret)
return ret;
return 0;
return intel_mgbe_common_data(pdev, plat);
}
static int ehl_sgmii_data(struct pci_dev *pdev,
......@@ -366,7 +347,7 @@ static int ehl_sgmii_data(struct pci_dev *pdev,
return ehl_common_data(pdev, plat);
}
static struct stmmac_pci_info ehl_sgmii1g_pci_info = {
static struct stmmac_pci_info ehl_sgmii1g_info = {
.setup = ehl_sgmii_data,
};
......@@ -380,7 +361,7 @@ static int ehl_rgmii_data(struct pci_dev *pdev,
return ehl_common_data(pdev, plat);
}
static struct stmmac_pci_info ehl_rgmii1g_pci_info = {
static struct stmmac_pci_info ehl_rgmii1g_info = {
.setup = ehl_rgmii_data,
};
......@@ -399,7 +380,7 @@ static int ehl_pse0_rgmii1g_data(struct pci_dev *pdev,
return ehl_pse0_common_data(pdev, plat);
}
static struct stmmac_pci_info ehl_pse0_rgmii1g_pci_info = {
static struct stmmac_pci_info ehl_pse0_rgmii1g_info = {
.setup = ehl_pse0_rgmii1g_data,
};
......@@ -412,7 +393,7 @@ static int ehl_pse0_sgmii1g_data(struct pci_dev *pdev,
return ehl_pse0_common_data(pdev, plat);
}
static struct stmmac_pci_info ehl_pse0_sgmii1g_pci_info = {
static struct stmmac_pci_info ehl_pse0_sgmii1g_info = {
.setup = ehl_pse0_sgmii1g_data,
};
......@@ -431,7 +412,7 @@ static int ehl_pse1_rgmii1g_data(struct pci_dev *pdev,
return ehl_pse1_common_data(pdev, plat);
}
static struct stmmac_pci_info ehl_pse1_rgmii1g_pci_info = {
static struct stmmac_pci_info ehl_pse1_rgmii1g_info = {
.setup = ehl_pse1_rgmii1g_data,
};
......@@ -444,23 +425,18 @@ static int ehl_pse1_sgmii1g_data(struct pci_dev *pdev,
return ehl_pse1_common_data(pdev, plat);
}
static struct stmmac_pci_info ehl_pse1_sgmii1g_pci_info = {
static struct stmmac_pci_info ehl_pse1_sgmii1g_info = {
.setup = ehl_pse1_sgmii1g_data,
};
static int tgl_common_data(struct pci_dev *pdev,
struct plat_stmmacenet_data *plat)
{
int ret;
plat->rx_queues_to_use = 6;
plat->tx_queues_to_use = 4;
plat->clk_ptp_rate = 200000000;
ret = intel_mgbe_common_data(pdev, plat);
if (ret)
return ret;
return 0;
return intel_mgbe_common_data(pdev, plat);
}
static int tgl_sgmii_data(struct pci_dev *pdev,
......@@ -474,7 +450,7 @@ static int tgl_sgmii_data(struct pci_dev *pdev,
return tgl_common_data(pdev, plat);
}
static struct stmmac_pci_info tgl_sgmii1g_pci_info = {
static struct stmmac_pci_info tgl_sgmii1g_info = {
.setup = tgl_sgmii_data,
};
......@@ -577,7 +553,7 @@ static int quark_default_data(struct pci_dev *pdev,
return 0;
}
static const struct stmmac_pci_info quark_pci_info = {
static const struct stmmac_pci_info quark_info = {
.setup = quark_default_data,
};
......@@ -600,11 +576,9 @@ static int intel_eth_pci_probe(struct pci_dev *pdev,
struct intel_priv_data *intel_priv;
struct plat_stmmacenet_data *plat;
struct stmmac_resources res;
int i;
int ret;
intel_priv = devm_kzalloc(&pdev->dev, sizeof(*intel_priv),
GFP_KERNEL);
intel_priv = devm_kzalloc(&pdev->dev, sizeof(*intel_priv), GFP_KERNEL);
if (!intel_priv)
return -ENOMEM;
......@@ -631,15 +605,9 @@ static int intel_eth_pci_probe(struct pci_dev *pdev,
return ret;
}
/* Get the base address of device */
for (i = 0; i < PCI_STD_NUM_BARS; i++) {
if (pci_resource_len(pdev, i) == 0)
continue;
ret = pcim_iomap_regions(pdev, BIT(i), pci_name(pdev));
ret = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev));
if (ret)
return ret;
break;
}
pci_set_master(pdev);
......@@ -650,14 +618,23 @@ static int intel_eth_pci_probe(struct pci_dev *pdev,
if (ret)
return ret;
pci_enable_msi(pdev);
ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
if (ret < 0)
return ret;
memset(&res, 0, sizeof(res));
res.addr = pcim_iomap_table(pdev)[i];
res.wol_irq = pdev->irq;
res.irq = pdev->irq;
res.addr = pcim_iomap_table(pdev)[0];
res.wol_irq = pci_irq_vector(pdev, 0);
res.irq = pci_irq_vector(pdev, 0);
return stmmac_dvr_probe(&pdev->dev, plat, &res);
ret = stmmac_dvr_probe(&pdev->dev, plat, &res);
if (ret) {
pci_free_irq_vectors(pdev);
clk_disable_unprepare(plat->stmmac_clk);
clk_unregister_fixed_rate(plat->stmmac_clk);
}
return ret;
}
/**
......@@ -671,19 +648,15 @@ static void intel_eth_pci_remove(struct pci_dev *pdev)
{
struct net_device *ndev = dev_get_drvdata(&pdev->dev);
struct stmmac_priv *priv = netdev_priv(ndev);
int i;
stmmac_dvr_remove(&pdev->dev);
if (priv->plat->stmmac_clk)
pci_free_irq_vectors(pdev);
clk_disable_unprepare(priv->plat->stmmac_clk);
clk_unregister_fixed_rate(priv->plat->stmmac_clk);
for (i = 0; i < PCI_STD_NUM_BARS; i++) {
if (pci_resource_len(pdev, i) == 0)
continue;
pcim_iounmap_regions(pdev, BIT(i));
break;
}
pcim_iounmap_regions(pdev, BIT(0));
pci_disable_device(pdev);
}
......@@ -742,26 +715,19 @@ static SIMPLE_DEV_PM_OPS(intel_eth_pm_ops, intel_eth_pci_suspend,
#define PCI_DEVICE_ID_INTEL_TGL_SGMII1G_ID 0xa0ac
static const struct pci_device_id intel_eth_pci_id_table[] = {
{ PCI_DEVICE_DATA(INTEL, QUARK_ID, &quark_pci_info) },
{ PCI_DEVICE_DATA(INTEL, EHL_RGMII1G_ID, &ehl_rgmii1g_pci_info) },
{ PCI_DEVICE_DATA(INTEL, EHL_SGMII1G_ID, &ehl_sgmii1g_pci_info) },
{ PCI_DEVICE_DATA(INTEL, EHL_SGMII2G5_ID, &ehl_sgmii1g_pci_info) },
{ PCI_DEVICE_DATA(INTEL, EHL_PSE0_RGMII1G_ID,
&ehl_pse0_rgmii1g_pci_info) },
{ PCI_DEVICE_DATA(INTEL, EHL_PSE0_SGMII1G_ID,
&ehl_pse0_sgmii1g_pci_info) },
{ PCI_DEVICE_DATA(INTEL, EHL_PSE0_SGMII2G5_ID,
&ehl_pse0_sgmii1g_pci_info) },
{ PCI_DEVICE_DATA(INTEL, EHL_PSE1_RGMII1G_ID,
&ehl_pse1_rgmii1g_pci_info) },
{ PCI_DEVICE_DATA(INTEL, EHL_PSE1_SGMII1G_ID,
&ehl_pse1_sgmii1g_pci_info) },
{ PCI_DEVICE_DATA(INTEL, EHL_PSE1_SGMII2G5_ID,
&ehl_pse1_sgmii1g_pci_info) },
{ PCI_DEVICE_DATA(INTEL, TGL_SGMII1G_ID, &tgl_sgmii1g_pci_info) },
{ PCI_DEVICE_DATA(INTEL, QUARK_ID, &quark_info) },
{ PCI_DEVICE_DATA(INTEL, EHL_RGMII1G_ID, &ehl_rgmii1g_info) },
{ PCI_DEVICE_DATA(INTEL, EHL_SGMII1G_ID, &ehl_sgmii1g_info) },
{ PCI_DEVICE_DATA(INTEL, EHL_SGMII2G5_ID, &ehl_sgmii1g_info) },
{ PCI_DEVICE_DATA(INTEL, EHL_PSE0_RGMII1G_ID, &ehl_pse0_rgmii1g_info) },
{ PCI_DEVICE_DATA(INTEL, EHL_PSE0_SGMII1G_ID, &ehl_pse0_sgmii1g_info) },
{ PCI_DEVICE_DATA(INTEL, EHL_PSE0_SGMII2G5_ID, &ehl_pse0_sgmii1g_info) },
{ PCI_DEVICE_DATA(INTEL, EHL_PSE1_RGMII1G_ID, &ehl_pse1_rgmii1g_info) },
{ PCI_DEVICE_DATA(INTEL, EHL_PSE1_SGMII1G_ID, &ehl_pse1_sgmii1g_info) },
{ PCI_DEVICE_DATA(INTEL, EHL_PSE1_SGMII2G5_ID, &ehl_pse1_sgmii1g_info) },
{ PCI_DEVICE_DATA(INTEL, TGL_SGMII1G_ID, &tgl_sgmii1g_info) },
{}
};
MODULE_DEVICE_TABLE(pci, intel_eth_pci_id_table);
static struct pci_driver intel_eth_pci_driver = {
......
......@@ -4991,7 +4991,7 @@ int stmmac_dvr_probe(struct device *device,
priv->plat->bsp_priv);
if (ret < 0)
return ret;
goto error_serdes_powerup;
}
#ifdef CONFIG_DEBUG_FS
......@@ -5000,6 +5000,8 @@ int stmmac_dvr_probe(struct device *device,
return ret;
error_serdes_powerup:
unregister_netdev(ndev);
error_netdev_register:
phylink_destroy(priv->phylink);
error_phy_setup:
......
......@@ -217,15 +217,10 @@ static int stmmac_pci_probe(struct pci_dev *pdev,
*/
static void stmmac_pci_remove(struct pci_dev *pdev)
{
struct net_device *ndev = dev_get_drvdata(&pdev->dev);
struct stmmac_priv *priv = netdev_priv(ndev);
int i;
stmmac_dvr_remove(&pdev->dev);
if (priv->plat->stmmac_clk)
clk_unregister_fixed_rate(priv->plat->stmmac_clk);
for (i = 0; i < PCI_STD_NUM_BARS; i++) {
if (pci_resource_len(pdev, i) == 0)
continue;
......
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