mirror of https://github.com/hak5/openwrt-owl.git
ipq806x: update stmmac to the version from linux 4.3
Signed-off-by: Felix Fietkau <nbd@openwrt.org> SVN-Revision: 47593owl
parent
b1a91ca57f
commit
3789b1f5a0
|
@ -106,8 +106,10 @@ CONFIG_CRC32_SLICEBY8=y
|
|||
CONFIG_CROSS_MEMORY_ATTACH=y
|
||||
CONFIG_CRYPTO_DEFLATE=y
|
||||
CONFIG_CRYPTO_LZO=y
|
||||
CONFIG_CRYPTO_RNG2=y
|
||||
# CONFIG_CRYPTO_SHA1_ARM_NEON is not set
|
||||
# CONFIG_CRYPTO_SHA512_ARM_NEON is not set
|
||||
CONFIG_CRYPTO_WORKQUEUE=y
|
||||
CONFIG_CRYPTO_XZ=y
|
||||
CONFIG_DCACHE_WORD_ACCESS=y
|
||||
CONFIG_DEBUG_BUGVERBOSE=y
|
||||
|
@ -123,7 +125,14 @@ CONFIG_DMA_ENGINE=y
|
|||
CONFIG_DMA_OF=y
|
||||
CONFIG_DMA_VIRTUAL_CHANNELS=y
|
||||
CONFIG_DTC=y
|
||||
# CONFIG_DWMAC_GENERIC is not set
|
||||
CONFIG_DWMAC_IPQ806X=y
|
||||
# CONFIG_DWMAC_LPC18XX is not set
|
||||
# CONFIG_DWMAC_MESON is not set
|
||||
# CONFIG_DWMAC_ROCKCHIP is not set
|
||||
# CONFIG_DWMAC_SOCFPGA is not set
|
||||
# CONFIG_DWMAC_STI is not set
|
||||
# CONFIG_DWMAC_SUNXI is not set
|
||||
# CONFIG_DW_DMAC_CORE is not set
|
||||
# CONFIG_DW_DMAC_PCI is not set
|
||||
CONFIG_DYNAMIC_DEBUG=y
|
||||
|
@ -234,7 +243,6 @@ CONFIG_KRAITCC=y
|
|||
CONFIG_KRAIT_CLOCKS=y
|
||||
CONFIG_KRAIT_L2_ACCESSORS=y
|
||||
# CONFIG_LEDS_REGULATOR is not set
|
||||
CONFIG_LEDS_TRIGGER_IDE_DISK=y
|
||||
CONFIG_LIBFDT=y
|
||||
CONFIG_LOCKUP_DETECTOR=y
|
||||
CONFIG_LZO_COMPRESS=y
|
||||
|
@ -387,8 +395,6 @@ CONFIG_SPI_MASTER=y
|
|||
CONFIG_SPI_QUP=y
|
||||
CONFIG_SPMI=y
|
||||
CONFIG_SPMI_MSM_PMIC_ARB=y
|
||||
# CONFIG_STMMAC_DA is not set
|
||||
CONFIG_STMMAC_DEBUG_FS=y
|
||||
CONFIG_STMMAC_ETH=y
|
||||
CONFIG_STMMAC_PLATFORM=y
|
||||
CONFIG_STOP_MACHINE=y
|
||||
|
|
|
@ -112,6 +112,8 @@ CONFIG_CRC32_SLICEBY8=y
|
|||
CONFIG_CROSS_MEMORY_ATTACH=y
|
||||
CONFIG_CRYPTO_DEFLATE=y
|
||||
CONFIG_CRYPTO_LZO=y
|
||||
CONFIG_CRYPTO_RNG2=y
|
||||
CONFIG_CRYPTO_WORKQUEUE=y
|
||||
CONFIG_CRYPTO_XZ=y
|
||||
CONFIG_DCACHE_WORD_ACCESS=y
|
||||
CONFIG_DEBUG_BUGVERBOSE=y
|
||||
|
@ -127,6 +129,14 @@ CONFIG_DMA_ENGINE=y
|
|||
CONFIG_DMA_OF=y
|
||||
CONFIG_DMA_VIRTUAL_CHANNELS=y
|
||||
CONFIG_DTC=y
|
||||
# CONFIG_DWMAC_GENERIC is not set
|
||||
CONFIG_DWMAC_IPQ806X=y
|
||||
# CONFIG_DWMAC_LPC18XX is not set
|
||||
# CONFIG_DWMAC_MESON is not set
|
||||
# CONFIG_DWMAC_ROCKCHIP is not set
|
||||
# CONFIG_DWMAC_SOCFPGA is not set
|
||||
# CONFIG_DWMAC_STI is not set
|
||||
# CONFIG_DWMAC_SUNXI is not set
|
||||
# CONFIG_DW_DMAC_PCI is not set
|
||||
CONFIG_DYNAMIC_DEBUG=y
|
||||
CONFIG_ETHERNET_PACKET_MANGLE=y
|
||||
|
@ -241,7 +251,6 @@ CONFIG_KPSS_XCC=y
|
|||
CONFIG_KRAITCC=y
|
||||
CONFIG_KRAIT_CLOCKS=y
|
||||
CONFIG_KRAIT_L2_ACCESSORS=y
|
||||
CONFIG_LEDS_TRIGGER_IDE_DISK=y
|
||||
CONFIG_LIBFDT=y
|
||||
CONFIG_LOCKUP_DETECTOR=y
|
||||
CONFIG_LOCK_SPIN_ON_OWNER=y
|
||||
|
|
|
@ -1,105 +0,0 @@
|
|||
From 4f09499bc1d9bb095caccbcd73ff951ee631e521 Mon Sep 17 00:00:00 2001
|
||||
From: Mathieu Olivari <mathieu@codeaurora.org>
|
||||
Date: Fri, 8 May 2015 15:42:40 -0700
|
||||
Subject: [PATCH 1/8] stmmac: add phy-handle support to the platform layer
|
||||
|
||||
On stmmac driver, PHY specification in device-tree was done using the
|
||||
non-standard property "snps,phy-addr". Specifying a PHY on a different
|
||||
MDIO bus that the one within the stmmac controller doesn't seem to be
|
||||
possible when device-tree is used.
|
||||
|
||||
This change adds support for the phy-handle property, as specified in
|
||||
Documentation/devicetree/bindings/net/ethernet.txt.
|
||||
|
||||
Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
||||
---
|
||||
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 28 ++++++++++++++--------
|
||||
.../net/ethernet/stmicro/stmmac/stmmac_platform.c | 6 ++++-
|
||||
include/linux/stmmac.h | 1 +
|
||||
3 files changed, 24 insertions(+), 11 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
|
||||
@@ -52,6 +52,7 @@
|
||||
#include "stmmac_ptp.h"
|
||||
#include "stmmac.h"
|
||||
#include <linux/reset.h>
|
||||
+#include <linux/of_mdio.h>
|
||||
|
||||
#define STMMAC_ALIGN(x) L1_CACHE_ALIGN(x)
|
||||
|
||||
@@ -818,18 +819,25 @@ static int stmmac_init_phy(struct net_de
|
||||
priv->speed = 0;
|
||||
priv->oldduplex = -1;
|
||||
|
||||
- if (priv->plat->phy_bus_name)
|
||||
- snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x",
|
||||
- priv->plat->phy_bus_name, priv->plat->bus_id);
|
||||
- else
|
||||
- snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x",
|
||||
- priv->plat->bus_id);
|
||||
-
|
||||
- snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
|
||||
- priv->plat->phy_addr);
|
||||
- pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id_fmt);
|
||||
+ if (priv->plat->phy_node) {
|
||||
+ phydev = of_phy_connect(dev, priv->plat->phy_node,
|
||||
+ &stmmac_adjust_link, 0, interface);
|
||||
+ } else {
|
||||
+ if (priv->plat->phy_bus_name)
|
||||
+ snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x",
|
||||
+ priv->plat->phy_bus_name, priv->plat->bus_id);
|
||||
+ else
|
||||
+ snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x",
|
||||
+ priv->plat->bus_id);
|
||||
+
|
||||
+ snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
|
||||
+ priv->plat->phy_addr);
|
||||
+ pr_debug("stmmac_init_phy: trying to attach to %s\n",
|
||||
+ phy_id_fmt);
|
||||
|
||||
- phydev = phy_connect(dev, phy_id_fmt, &stmmac_adjust_link, interface);
|
||||
+ phydev = phy_connect(dev, phy_id_fmt, &stmmac_adjust_link,
|
||||
+ interface);
|
||||
+ }
|
||||
|
||||
if (IS_ERR(phydev)) {
|
||||
pr_err("%s: Could not attach to PHY\n", dev->name);
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_net.h>
|
||||
#include <linux/of_device.h>
|
||||
+#include <linux/of_mdio.h>
|
||||
#include "stmmac.h"
|
||||
|
||||
static const struct of_device_id stmmac_dt_ids[] = {
|
||||
@@ -155,13 +156,16 @@ static int stmmac_probe_config_dt(struct
|
||||
/* Default to phy auto-detection */
|
||||
plat->phy_addr = -1;
|
||||
|
||||
+ /* If we find a phy-handle property, use it as the PHY */
|
||||
+ plat->phy_node = of_parse_phandle(np, "phy-handle", 0);
|
||||
+
|
||||
/* "snps,phy-addr" is not a standard property. Mark it as deprecated
|
||||
* and warn of its use. Remove this when phy node support is added.
|
||||
*/
|
||||
if (of_property_read_u32(np, "snps,phy-addr", &plat->phy_addr) == 0)
|
||||
dev_warn(&pdev->dev, "snps,phy-addr property is deprecated\n");
|
||||
|
||||
- if (plat->phy_bus_name)
|
||||
+ if (plat->phy_node || plat->phy_bus_name)
|
||||
plat->mdio_bus_data = NULL;
|
||||
else
|
||||
plat->mdio_bus_data =
|
||||
--- a/include/linux/stmmac.h
|
||||
+++ b/include/linux/stmmac.h
|
||||
@@ -99,6 +99,7 @@ struct plat_stmmacenet_data {
|
||||
int phy_addr;
|
||||
int interface;
|
||||
struct stmmac_mdio_bus_data *mdio_bus_data;
|
||||
+ struct device_node *phy_node;
|
||||
struct stmmac_dma_cfg *dma_cfg;
|
||||
int clk_csr;
|
||||
int has_gmac;
|
File diff suppressed because it is too large
Load Diff
|
@ -1,65 +0,0 @@
|
|||
From 0149d275415cd1b2382ce94e5eb32641590097d0 Mon Sep 17 00:00:00 2001
|
||||
From: Mathieu Olivari <mathieu@codeaurora.org>
|
||||
Date: Fri, 8 May 2015 15:57:12 -0700
|
||||
Subject: [PATCH 2/8] stmmac: move error path at the end of
|
||||
stmmac_probe_config_dt()
|
||||
|
||||
We will want to do additional clean-up on certain errors. Therefore,
|
||||
this change moves the error path at the end of the function for better
|
||||
code readability.
|
||||
|
||||
This patch doesn't change anything functionally.
|
||||
|
||||
Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
||||
---
|
||||
.../net/ethernet/stmicro/stmmac/stmmac_platform.c | 22 ++++++++++++++++------
|
||||
1 file changed, 16 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
||||
@@ -117,13 +117,18 @@ static int stmmac_probe_config_dt(struct
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct stmmac_dma_cfg *dma_cfg;
|
||||
const struct of_device_id *device;
|
||||
+ int ret;
|
||||
|
||||
- if (!np)
|
||||
- return -ENODEV;
|
||||
+ if (!np) {
|
||||
+ ret = -ENODEV;
|
||||
+ goto err;
|
||||
+ }
|
||||
|
||||
device = of_match_device(stmmac_dt_ids, &pdev->dev);
|
||||
- if (!device)
|
||||
- return -ENODEV;
|
||||
+ if (!device) {
|
||||
+ ret = -ENODEV;
|
||||
+ goto err;
|
||||
+ }
|
||||
|
||||
if (device->data) {
|
||||
const struct stmmac_of_data *data = device->data;
|
||||
@@ -219,8 +224,10 @@ static int stmmac_probe_config_dt(struct
|
||||
if (of_find_property(np, "snps,pbl", NULL)) {
|
||||
dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg),
|
||||
GFP_KERNEL);
|
||||
- if (!dma_cfg)
|
||||
- return -ENOMEM;
|
||||
+ if (!dma_cfg) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto err;
|
||||
+ }
|
||||
plat->dma_cfg = dma_cfg;
|
||||
of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl);
|
||||
dma_cfg->fixed_burst =
|
||||
@@ -235,6 +242,9 @@ static int stmmac_probe_config_dt(struct
|
||||
}
|
||||
|
||||
return 0;
|
||||
+
|
||||
+err:
|
||||
+ return ret;
|
||||
}
|
||||
#else
|
||||
static int stmmac_probe_config_dt(struct platform_device *pdev,
|
|
@ -1,64 +0,0 @@
|
|||
From 3a95f75867be562cb919ff23a738f70357188fbd Mon Sep 17 00:00:00 2001
|
||||
From: Mathieu Olivari <mathieu@codeaurora.org>
|
||||
Date: Fri, 8 May 2015 16:02:03 -0700
|
||||
Subject: [PATCH 3/8] stmmac: add fixed-link device-tree support
|
||||
|
||||
In case DT is used, this change adds the ability to the stmmac driver to
|
||||
detect a fixed-link PHY, instanciate it, and use it during
|
||||
phy_connect().
|
||||
|
||||
Fixed link PHYs DT usage is described in:
|
||||
Documentation/devicetree/bindings/net/fixed-link.txt
|
||||
|
||||
Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
||||
---
|
||||
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +-
|
||||
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 12 +++++++++++-
|
||||
2 files changed, 12 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
|
||||
@@ -858,7 +858,7 @@ static int stmmac_init_phy(struct net_de
|
||||
* device as well.
|
||||
* Note: phydev->phy_id is the result of reading the UID PHY registers.
|
||||
*/
|
||||
- if (phydev->phy_id == 0) {
|
||||
+ if (!priv->plat->phy_node && phydev->phy_id == 0) {
|
||||
phy_disconnect(phydev);
|
||||
return -ENODEV;
|
||||
}
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
||||
@@ -164,6 +164,14 @@ static int stmmac_probe_config_dt(struct
|
||||
/* If we find a phy-handle property, use it as the PHY */
|
||||
plat->phy_node = of_parse_phandle(np, "phy-handle", 0);
|
||||
|
||||
+ /* If phy-handle is not specified, check if we have a fixed-phy */
|
||||
+ if (!plat->phy_node && of_phy_is_fixed_link(np)) {
|
||||
+ if ((of_phy_register_fixed_link(np) < 0))
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ plat->phy_node = of_node_get(np);
|
||||
+ }
|
||||
+
|
||||
/* "snps,phy-addr" is not a standard property. Mark it as deprecated
|
||||
* and warn of its use. Remove this when phy node support is added.
|
||||
*/
|
||||
@@ -226,7 +234,7 @@ static int stmmac_probe_config_dt(struct
|
||||
GFP_KERNEL);
|
||||
if (!dma_cfg) {
|
||||
ret = -ENOMEM;
|
||||
- goto err;
|
||||
+ goto err2;
|
||||
}
|
||||
plat->dma_cfg = dma_cfg;
|
||||
of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl);
|
||||
@@ -243,6 +251,8 @@ static int stmmac_probe_config_dt(struct
|
||||
|
||||
return 0;
|
||||
|
||||
+err2:
|
||||
+ of_node_put(np);
|
||||
err:
|
||||
return ret;
|
||||
}
|
|
@ -1,427 +0,0 @@
|
|||
From 69fb970ad3fe05af7cb99ea78230c69c7ca0d03b Mon Sep 17 00:00:00 2001
|
||||
From: Mathieu Olivari <mathieu@codeaurora.org>
|
||||
Date: Fri, 8 May 2015 16:10:22 -0700
|
||||
Subject: [PATCH 4/8] stmmac: add ipq806x glue layer
|
||||
|
||||
The ethernet controller available in IPQ806x is a Synopsys DesignWare
|
||||
Gigabit MAC IP core, already supported by the stmmac driver.
|
||||
|
||||
This glue layer implements some platform specific settings required to
|
||||
get the controller working on an IPQ806x based platform.
|
||||
|
||||
Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
||||
---
|
||||
drivers/net/ethernet/stmicro/stmmac/Kconfig | 1 +
|
||||
drivers/net/ethernet/stmicro/stmmac/Makefile | 2 +-
|
||||
drivers/net/ethernet/stmicro/stmmac/dwmac-ipq.c | 324 +++++++++++++++++++++
|
||||
.../net/ethernet/stmicro/stmmac/stmmac_platform.c | 1 +
|
||||
.../net/ethernet/stmicro/stmmac/stmmac_platform.h | 1 +
|
||||
5 files changed, 328 insertions(+), 1 deletion(-)
|
||||
create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-ipq.c
|
||||
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
|
||||
@@ -16,6 +16,7 @@ if STMMAC_ETH
|
||||
config STMMAC_PLATFORM
|
||||
bool "STMMAC Platform bus support"
|
||||
depends on STMMAC_ETH
|
||||
+ select MFD_SYSCON
|
||||
default y
|
||||
---help---
|
||||
This selects the platform specific bus support for
|
||||
@@ -26,6 +27,15 @@ config STMMAC_PLATFORM
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
+config DWMAC_IPQ806X
|
||||
+ bool "QCA IPQ806x dwmac support"
|
||||
+ depends on STMMAC_PLATFORM && ARCH_QCOM
|
||||
+ help
|
||||
+ Support for Ethernet controller on QCA IPQ806x SoC.
|
||||
+
|
||||
+ This selects the QCA IPQ806x SoC glue layer support for
|
||||
+ the stmmac device driver.
|
||||
+
|
||||
config DWMAC_MESON
|
||||
bool "Amlogic Meson dwmac support"
|
||||
depends on STMMAC_PLATFORM && ARCH_MESON
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
|
||||
@@ -1,6 +1,7 @@
|
||||
obj-$(CONFIG_STMMAC_ETH) += stmmac.o
|
||||
stmmac-$(CONFIG_STMMAC_PLATFORM) += stmmac_platform.o
|
||||
stmmac-$(CONFIG_STMMAC_PCI) += stmmac_pci.o
|
||||
+stmmac-$(CONFIG_DWMAC_IPQ806X) += dwmac-ipq806x.o
|
||||
stmmac-$(CONFIG_DWMAC_MESON) += dwmac-meson.o
|
||||
stmmac-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o
|
||||
stmmac-$(CONFIG_DWMAC_STI) += dwmac-sti.o
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
||||
@@ -46,6 +46,9 @@ static const struct of_device_id stmmac_
|
||||
#ifdef CONFIG_DWMAC_SOCFPGA
|
||||
{ .compatible = "altr,socfpga-stmmac", .data = &socfpga_gmac_data },
|
||||
#endif
|
||||
+#ifdef CONFIG_DWMAC_IPQ806X
|
||||
+ { .compatible = "qcom,ipq806x-gmac", .data = &ipq806x_gmac_data },
|
||||
+#endif
|
||||
/* SoC specific glue layers should come before generic bindings */
|
||||
{ .compatible = "st,spear600-gmac"},
|
||||
{ .compatible = "snps,dwmac-3.610"},
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
|
||||
@@ -0,0 +1,343 @@
|
||||
+/*
|
||||
+ * Qualcomm Atheros IPQ806x GMAC glue layer
|
||||
+ *
|
||||
+ * Copyright (C) 2015 The Linux Foundation
|
||||
+ *
|
||||
+ * Permission to use, copy, modify, and/or distribute this software for any
|
||||
+ * purpose with or without fee is hereby granted, provided that the above
|
||||
+ * copyright notice and this permission notice appear in all copies.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/device.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/phy.h>
|
||||
+#include <linux/regmap.h>
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/reset.h>
|
||||
+#include <linux/of_net.h>
|
||||
+#include <linux/mfd/syscon.h>
|
||||
+#include <linux/stmmac.h>
|
||||
+#include <linux/of_mdio.h>
|
||||
+
|
||||
+#include "stmmac.h"
|
||||
+
|
||||
+#define NSS_COMMON_CLK_GATE 0x8
|
||||
+#define NSS_COMMON_CLK_GATE_PTP_EN(x) BIT(0x10 + x)
|
||||
+#define NSS_COMMON_CLK_GATE_RGMII_RX_EN(x) BIT(0x9 + (x * 2))
|
||||
+#define NSS_COMMON_CLK_GATE_RGMII_TX_EN(x) BIT(0x8 + (x * 2))
|
||||
+#define NSS_COMMON_CLK_GATE_GMII_RX_EN(x) BIT(0x4 + x)
|
||||
+#define NSS_COMMON_CLK_GATE_GMII_TX_EN(x) BIT(0x0 + x)
|
||||
+
|
||||
+#define NSS_COMMON_CLK_DIV0 0xC
|
||||
+#define NSS_COMMON_CLK_DIV_OFFSET(x) (x * 8)
|
||||
+#define NSS_COMMON_CLK_DIV_MASK 0x7f
|
||||
+
|
||||
+#define NSS_COMMON_CLK_SRC_CTRL 0x14
|
||||
+#define NSS_COMMON_CLK_SRC_CTRL_OFFSET(x) (1 << x)
|
||||
+/* Mode is coded on 1 bit but is different depending on the MAC ID:
|
||||
+ * MAC0: QSGMII=0 RGMII=1
|
||||
+ * MAC1: QSGMII=0 SGMII=0 RGMII=1
|
||||
+ * MAC2 & MAC3: QSGMII=0 SGMII=1
|
||||
+ */
|
||||
+#define NSS_COMMON_CLK_SRC_CTRL_RGMII(x) 1
|
||||
+#define NSS_COMMON_CLK_SRC_CTRL_SGMII(x) ((x >= 2) ? 1 : 0)
|
||||
+
|
||||
+#define NSS_COMMON_MACSEC_CTL 0x28
|
||||
+#define NSS_COMMON_MACSEC_CTL_EXT_BYPASS_EN(x) (1 << x)
|
||||
+
|
||||
+#define NSS_COMMON_GMAC_CTL(x) (0x30 + (x * 4))
|
||||
+#define NSS_COMMON_GMAC_CTL_CSYS_REQ BIT(19)
|
||||
+#define NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL BIT(16)
|
||||
+#define NSS_COMMON_GMAC_CTL_IFG_LIMIT_OFFSET 8
|
||||
+#define NSS_COMMON_GMAC_CTL_IFG_OFFSET 0
|
||||
+#define NSS_COMMON_GMAC_CTL_IFG_MASK 0x3f
|
||||
+
|
||||
+#define NSS_COMMON_CLK_DIV_RGMII_1000 1
|
||||
+#define NSS_COMMON_CLK_DIV_RGMII_100 9
|
||||
+#define NSS_COMMON_CLK_DIV_RGMII_10 99
|
||||
+#define NSS_COMMON_CLK_DIV_SGMII_1000 0
|
||||
+#define NSS_COMMON_CLK_DIV_SGMII_100 4
|
||||
+#define NSS_COMMON_CLK_DIV_SGMII_10 49
|
||||
+
|
||||
+#define QSGMII_PCS_MODE_CTL 0x68
|
||||
+#define QSGMII_PCS_MODE_CTL_AUTONEG_EN(x) BIT((x * 8) + 7)
|
||||
+
|
||||
+#define QSGMII_PCS_CAL_LCKDT_CTL 0x120
|
||||
+#define QSGMII_PCS_CAL_LCKDT_CTL_RST BIT(19)
|
||||
+
|
||||
+/* Only GMAC1/2/3 support SGMII and their CTL register are not contiguous */
|
||||
+#define QSGMII_PHY_SGMII_CTL(x) ((x == 1) ? 0x134 : \
|
||||
+ (0x13c + (4 * (x - 2))))
|
||||
+#define QSGMII_PHY_CDR_EN BIT(0)
|
||||
+#define QSGMII_PHY_RX_FRONT_EN BIT(1)
|
||||
+#define QSGMII_PHY_RX_SIGNAL_DETECT_EN BIT(2)
|
||||
+#define QSGMII_PHY_TX_DRIVER_EN BIT(3)
|
||||
+#define QSGMII_PHY_QSGMII_EN BIT(7)
|
||||
+#define QSGMII_PHY_PHASE_LOOP_GAIN_OFFSET 12
|
||||
+#define QSGMII_PHY_PHASE_LOOP_GAIN_MASK 0x7
|
||||
+#define QSGMII_PHY_RX_DC_BIAS_OFFSET 18
|
||||
+#define QSGMII_PHY_RX_DC_BIAS_MASK 0x3
|
||||
+#define QSGMII_PHY_RX_INPUT_EQU_OFFSET 20
|
||||
+#define QSGMII_PHY_RX_INPUT_EQU_MASK 0x3
|
||||
+#define QSGMII_PHY_CDR_PI_SLEW_OFFSET 22
|
||||
+#define QSGMII_PHY_CDR_PI_SLEW_MASK 0x3
|
||||
+#define QSGMII_PHY_TX_DRV_AMP_OFFSET 28
|
||||
+#define QSGMII_PHY_TX_DRV_AMP_MASK 0xf
|
||||
+
|
||||
+struct ipq806x_gmac {
|
||||
+ struct platform_device *pdev;
|
||||
+ struct regmap *nss_common;
|
||||
+ struct regmap *qsgmii_csr;
|
||||
+ uint32_t id;
|
||||
+ struct clk *core_clk;
|
||||
+ phy_interface_t phy_mode;
|
||||
+};
|
||||
+
|
||||
+static int get_clk_div_sgmii(struct ipq806x_gmac *gmac, unsigned int speed)
|
||||
+{
|
||||
+ struct device *dev = &gmac->pdev->dev;
|
||||
+ int div;
|
||||
+
|
||||
+ switch (speed) {
|
||||
+ case SPEED_1000:
|
||||
+ div = NSS_COMMON_CLK_DIV_SGMII_1000;
|
||||
+ break;
|
||||
+
|
||||
+ case SPEED_100:
|
||||
+ div = NSS_COMMON_CLK_DIV_SGMII_100;
|
||||
+ break;
|
||||
+
|
||||
+ case SPEED_10:
|
||||
+ div = NSS_COMMON_CLK_DIV_SGMII_10;
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ dev_err(dev, "Speed %dMbps not supported in SGMII\n", speed);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return div;
|
||||
+}
|
||||
+
|
||||
+static int get_clk_div_rgmii(struct ipq806x_gmac *gmac, unsigned int speed)
|
||||
+{
|
||||
+ struct device *dev = &gmac->pdev->dev;
|
||||
+ int div;
|
||||
+
|
||||
+ switch (speed) {
|
||||
+ case SPEED_1000:
|
||||
+ div = NSS_COMMON_CLK_DIV_RGMII_1000;
|
||||
+ break;
|
||||
+
|
||||
+ case SPEED_100:
|
||||
+ div = NSS_COMMON_CLK_DIV_RGMII_100;
|
||||
+ break;
|
||||
+
|
||||
+ case SPEED_10:
|
||||
+ div = NSS_COMMON_CLK_DIV_RGMII_10;
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ dev_err(dev, "Speed %dMbps not supported in RGMII\n", speed);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return div;
|
||||
+}
|
||||
+
|
||||
+static int ipq806x_gmac_set_speed(struct ipq806x_gmac *gmac, unsigned int speed)
|
||||
+{
|
||||
+ uint32_t clk_bits, val;
|
||||
+ int div;
|
||||
+
|
||||
+ switch (gmac->phy_mode) {
|
||||
+ case PHY_INTERFACE_MODE_RGMII:
|
||||
+ div = get_clk_div_rgmii(gmac, speed);
|
||||
+ clk_bits = NSS_COMMON_CLK_GATE_RGMII_RX_EN(gmac->id) |
|
||||
+ NSS_COMMON_CLK_GATE_RGMII_TX_EN(gmac->id);
|
||||
+ break;
|
||||
+
|
||||
+ case PHY_INTERFACE_MODE_SGMII:
|
||||
+ div = get_clk_div_sgmii(gmac, speed);
|
||||
+ clk_bits = NSS_COMMON_CLK_GATE_GMII_RX_EN(gmac->id) |
|
||||
+ NSS_COMMON_CLK_GATE_GMII_TX_EN(gmac->id);
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ dev_err(&gmac->pdev->dev, "Unsupported PHY mode: \"%s\"\n",
|
||||
+ phy_modes(gmac->phy_mode));
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ /* Disable the clocks */
|
||||
+ regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val);
|
||||
+ val &= ~clk_bits;
|
||||
+ regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);
|
||||
+
|
||||
+ /* Set the divider */
|
||||
+ regmap_read(gmac->nss_common, NSS_COMMON_CLK_DIV0, &val);
|
||||
+ val &= ~(NSS_COMMON_CLK_DIV_MASK
|
||||
+ << NSS_COMMON_CLK_DIV_OFFSET(gmac->id));
|
||||
+ val |= div << NSS_COMMON_CLK_DIV_OFFSET(gmac->id);
|
||||
+ regmap_write(gmac->nss_common, NSS_COMMON_CLK_DIV0, val);
|
||||
+
|
||||
+ /* Enable the clock back */
|
||||
+ regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val);
|
||||
+ val |= clk_bits;
|
||||
+ regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void *ipq806x_gmac_of_parse(struct ipq806x_gmac *gmac)
|
||||
+{
|
||||
+ struct device *dev = &gmac->pdev->dev;
|
||||
+
|
||||
+ gmac->phy_mode = of_get_phy_mode(dev->of_node);
|
||||
+ if (gmac->phy_mode < 0) {
|
||||
+ dev_err(dev, "missing phy mode property\n");
|
||||
+ return ERR_PTR(-EINVAL);
|
||||
+ }
|
||||
+
|
||||
+ if (of_property_read_u32(dev->of_node, "qcom,id", &gmac->id) < 0) {
|
||||
+ dev_err(dev, "missing qcom id property\n");
|
||||
+ return ERR_PTR(-EINVAL);
|
||||
+ }
|
||||
+
|
||||
+ /* The GMACs are called 1 to 4 in the documentation, but to simplify the
|
||||
+ * code and keep it consistent with the Linux convention, we'll number
|
||||
+ * them from 0 to 3 here.
|
||||
+ */
|
||||
+ if (gmac->id < 0 || gmac->id > 3) {
|
||||
+ dev_err(dev, "invalid gmac id\n");
|
||||
+ return ERR_PTR(-EINVAL);
|
||||
+ }
|
||||
+
|
||||
+ gmac->core_clk = devm_clk_get(dev, "stmmaceth");
|
||||
+ if (IS_ERR(gmac->core_clk)) {
|
||||
+ dev_err(dev, "missing stmmaceth clk property\n");
|
||||
+ return gmac->core_clk;
|
||||
+ }
|
||||
+ clk_set_rate(gmac->core_clk, 266000000);
|
||||
+
|
||||
+ /* Setup the register map for the nss common registers */
|
||||
+ gmac->nss_common = syscon_regmap_lookup_by_phandle(dev->of_node,
|
||||
+ "qcom,nss-common");
|
||||
+ if (IS_ERR(gmac->nss_common)) {
|
||||
+ dev_err(dev, "missing nss-common node\n");
|
||||
+ return gmac->nss_common;
|
||||
+ }
|
||||
+
|
||||
+ /* Setup the register map for the qsgmii csr registers */
|
||||
+ gmac->qsgmii_csr = syscon_regmap_lookup_by_phandle(dev->of_node,
|
||||
+ "qcom,qsgmii-csr");
|
||||
+ if (IS_ERR(gmac->qsgmii_csr)) {
|
||||
+ dev_err(dev, "missing qsgmii-csr node\n");
|
||||
+ return gmac->qsgmii_csr;
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static void *ipq806x_gmac_setup(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct device *dev = &pdev->dev;
|
||||
+ struct ipq806x_gmac *gmac;
|
||||
+ int val;
|
||||
+ void *err;
|
||||
+
|
||||
+ gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL);
|
||||
+ if (!gmac)
|
||||
+ return ERR_PTR(-ENOMEM);
|
||||
+
|
||||
+ gmac->pdev = pdev;
|
||||
+
|
||||
+ err = ipq806x_gmac_of_parse(gmac);
|
||||
+ if (err) {
|
||||
+ dev_err(dev, "device tree parsing error\n");
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ regmap_write(gmac->qsgmii_csr, QSGMII_PCS_CAL_LCKDT_CTL,
|
||||
+ QSGMII_PCS_CAL_LCKDT_CTL_RST);
|
||||
+
|
||||
+ /* Inter frame gap is set to 12 */
|
||||
+ val = 12 << NSS_COMMON_GMAC_CTL_IFG_OFFSET |
|
||||
+ 12 << NSS_COMMON_GMAC_CTL_IFG_LIMIT_OFFSET;
|
||||
+ /* We also initiate an AXI low power exit request */
|
||||
+ val |= NSS_COMMON_GMAC_CTL_CSYS_REQ;
|
||||
+ switch (gmac->phy_mode) {
|
||||
+ case PHY_INTERFACE_MODE_RGMII:
|
||||
+ val |= NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL;
|
||||
+ break;
|
||||
+ case PHY_INTERFACE_MODE_SGMII:
|
||||
+ val &= ~NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL;
|
||||
+ break;
|
||||
+ default:
|
||||
+ dev_err(&pdev->dev, "Unsupported PHY mode: \"%s\"\n",
|
||||
+ phy_modes(gmac->phy_mode));
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ regmap_write(gmac->nss_common, NSS_COMMON_GMAC_CTL(gmac->id), val);
|
||||
+
|
||||
+ /* Configure the clock src according to the mode */
|
||||
+ regmap_read(gmac->nss_common, NSS_COMMON_CLK_SRC_CTRL, &val);
|
||||
+ val &= ~NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id);
|
||||
+ switch (gmac->phy_mode) {
|
||||
+ case PHY_INTERFACE_MODE_RGMII:
|
||||
+ val |= NSS_COMMON_CLK_SRC_CTRL_RGMII(gmac->id) <<
|
||||
+ NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id);
|
||||
+ break;
|
||||
+ case PHY_INTERFACE_MODE_SGMII:
|
||||
+ val |= NSS_COMMON_CLK_SRC_CTRL_SGMII(gmac->id) <<
|
||||
+ NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id);
|
||||
+ break;
|
||||
+ default:
|
||||
+ dev_err(&pdev->dev, "Unsupported PHY mode: \"%s\"\n",
|
||||
+ phy_modes(gmac->phy_mode));
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ regmap_write(gmac->nss_common, NSS_COMMON_CLK_SRC_CTRL, val);
|
||||
+
|
||||
+ /* Enable PTP clock */
|
||||
+ regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val);
|
||||
+ val |= NSS_COMMON_CLK_GATE_PTP_EN(gmac->id);
|
||||
+ regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);
|
||||
+
|
||||
+ if (gmac->phy_mode == PHY_INTERFACE_MODE_SGMII) {
|
||||
+ regmap_write(gmac->qsgmii_csr, QSGMII_PHY_SGMII_CTL(gmac->id),
|
||||
+ QSGMII_PHY_CDR_EN |
|
||||
+ QSGMII_PHY_RX_FRONT_EN |
|
||||
+ QSGMII_PHY_RX_SIGNAL_DETECT_EN |
|
||||
+ QSGMII_PHY_TX_DRIVER_EN |
|
||||
+ QSGMII_PHY_QSGMII_EN |
|
||||
+ 0x4 << QSGMII_PHY_PHASE_LOOP_GAIN_OFFSET |
|
||||
+ 0x3 << QSGMII_PHY_RX_DC_BIAS_OFFSET |
|
||||
+ 0x1 << QSGMII_PHY_RX_INPUT_EQU_OFFSET |
|
||||
+ 0x2 << QSGMII_PHY_CDR_PI_SLEW_OFFSET |
|
||||
+ 0xC << QSGMII_PHY_TX_DRV_AMP_OFFSET);
|
||||
+ }
|
||||
+
|
||||
+ return gmac;
|
||||
+}
|
||||
+
|
||||
+static void ipq806x_gmac_fix_mac_speed(void *priv, unsigned int speed)
|
||||
+{
|
||||
+ struct ipq806x_gmac *gmac = priv;
|
||||
+
|
||||
+ ipq806x_gmac_set_speed(gmac, speed);
|
||||
+}
|
||||
+
|
||||
+const struct stmmac_of_data ipq806x_gmac_data = {
|
||||
+ .has_gmac = 1,
|
||||
+ .setup = ipq806x_gmac_setup,
|
||||
+ .fix_mac_speed = ipq806x_gmac_fix_mac_speed,
|
||||
+};
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
|
||||
@@ -137,6 +137,9 @@ void stmmac_disable_eee_mode(struct stmm
|
||||
bool stmmac_eee_init(struct stmmac_priv *priv);
|
||||
|
||||
#ifdef CONFIG_STMMAC_PLATFORM
|
||||
+#ifdef CONFIG_DWMAC_IPQ806X
|
||||
+extern const struct stmmac_of_data ipq806x_gmac_data;
|
||||
+#endif
|
||||
#ifdef CONFIG_DWMAC_MESON
|
||||
extern const struct stmmac_of_data meson6_dwmac_data;
|
||||
#endif
|
|
@ -1,52 +0,0 @@
|
|||
From 0f9605d9409b77a89daef91cc68239fc2ff50457 Mon Sep 17 00:00:00 2001
|
||||
From: Mathieu Olivari <mathieu@codeaurora.org>
|
||||
Date: Fri, 8 May 2015 16:51:25 -0700
|
||||
Subject: [PATCH 5/8] net: stmmac: ipq806x: document device tree bindings
|
||||
|
||||
Add the device tree bindings documentation for the QCA IPQ806x
|
||||
variant of the Synopsys DesignWare MAC.
|
||||
|
||||
Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
||||
---
|
||||
.../devicetree/bindings/net/ipq806x-dwmac.txt | 35 ++++++++++++++++++++++
|
||||
1 file changed, 35 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/net/ipq806x-dwmac.txt
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/net/ipq806x-dwmac.txt
|
||||
@@ -0,0 +1,35 @@
|
||||
+* IPQ806x DWMAC Ethernet controller
|
||||
+
|
||||
+The device inherits all the properties of the dwmac/stmmac devices
|
||||
+described in the file net/stmmac.txt with the following changes.
|
||||
+
|
||||
+Required properties:
|
||||
+
|
||||
+- compatible: should be "qcom,ipq806x-gmac" along with "snps,dwmac"
|
||||
+ and any applicable more detailed version number
|
||||
+ described in net/stmmac.txt
|
||||
+
|
||||
+- qcom,nss-common: should contain a phandle to a syscon device mapping the
|
||||
+ nss-common registers.
|
||||
+
|
||||
+- qcom,qsgmii-csr: should contain a phandle to a syscon device mapping the
|
||||
+ qsgmii-csr registers.
|
||||
+
|
||||
+Example:
|
||||
+
|
||||
+ gmac: ethernet@37000000 {
|
||||
+ device_type = "network";
|
||||
+ compatible = "qcom,ipq806x-gmac";
|
||||
+ reg = <0x37000000 0x200000>;
|
||||
+ interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ interrupt-names = "macirq";
|
||||
+
|
||||
+ qcom,nss-common = <&nss_common>;
|
||||
+ qcom,qsgmii-csr = <&qsgmii_csr>;
|
||||
+
|
||||
+ clocks = <&gcc GMAC_CORE1_CLK>;
|
||||
+ clock-names = "stmmaceth";
|
||||
+
|
||||
+ resets = <&gcc GMAC_CORE1_RESET>;
|
||||
+ reset-names = "stmmaceth";
|
||||
+ };
|
|
@ -1,171 +0,0 @@
|
|||
From df944689d491e6af533173bf2ef448c3dd334f15 Mon Sep 17 00:00:00 2001
|
||||
From: Mathieu Olivari <mathieu@codeaurora.org>
|
||||
Date: Mon, 11 May 2015 15:15:25 -0700
|
||||
Subject: [PATCH 6/8] net: stmmac: create one debugfs dir per net-device
|
||||
|
||||
stmmac DebugFS entries are currently global to the driver. As a result,
|
||||
having more than one stmmac device in the system creates the following
|
||||
error:
|
||||
* ERROR stmmaceth, debugfs create directory failed
|
||||
* stmmac_hw_setup: failed debugFS registration
|
||||
|
||||
This also results in being able to access the debugfs information for
|
||||
the first registered device only.
|
||||
|
||||
This patch changes the debugfs structure to have one sub-directory per
|
||||
net-device. Files under "/sys/kernel/debug/stmmaceth" will now show-up
|
||||
under /sys/kernel/debug/stmmaceth/ethN/.
|
||||
|
||||
Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
||||
---
|
||||
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 6 ++
|
||||
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 76 ++++++++++++++++-------
|
||||
2 files changed, 59 insertions(+), 23 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
|
||||
@@ -116,6 +116,12 @@ struct stmmac_priv {
|
||||
int use_riwt;
|
||||
int irq_wake;
|
||||
spinlock_t ptp_lock;
|
||||
+
|
||||
+#ifdef CONFIG_DEBUG_FS
|
||||
+ struct dentry *dbgfs_dir;
|
||||
+ struct dentry *dbgfs_rings_status;
|
||||
+ struct dentry *dbgfs_dma_cap;
|
||||
+#endif
|
||||
};
|
||||
|
||||
int stmmac_mdio_unregister(struct net_device *ndev);
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
|
||||
@@ -119,7 +119,7 @@ static irqreturn_t stmmac_interrupt(int
|
||||
|
||||
#ifdef CONFIG_STMMAC_DEBUG_FS
|
||||
static int stmmac_init_fs(struct net_device *dev);
|
||||
-static void stmmac_exit_fs(void);
|
||||
+static void stmmac_exit_fs(struct net_device *dev);
|
||||
#endif
|
||||
|
||||
#define STMMAC_COAL_TIMER(x) (jiffies + usecs_to_jiffies(x))
|
||||
@@ -1879,7 +1879,7 @@ static int stmmac_release(struct net_dev
|
||||
netif_carrier_off(dev);
|
||||
|
||||
#ifdef CONFIG_STMMAC_DEBUG_FS
|
||||
- stmmac_exit_fs();
|
||||
+ stmmac_exit_fs(dev);
|
||||
#endif
|
||||
|
||||
stmmac_release_ptp(priv);
|
||||
@@ -2467,8 +2467,6 @@ static int stmmac_ioctl(struct net_devic
|
||||
|
||||
#ifdef CONFIG_STMMAC_DEBUG_FS
|
||||
static struct dentry *stmmac_fs_dir;
|
||||
-static struct dentry *stmmac_rings_status;
|
||||
-static struct dentry *stmmac_dma_cap;
|
||||
|
||||
static void sysfs_display_ring(void *head, int size, int extend_desc,
|
||||
struct seq_file *seq)
|
||||
@@ -2607,36 +2605,39 @@ static const struct file_operations stmm
|
||||
|
||||
static int stmmac_init_fs(struct net_device *dev)
|
||||
{
|
||||
- /* Create debugfs entries */
|
||||
- stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL);
|
||||
+ struct stmmac_priv *priv = netdev_priv(dev);
|
||||
+
|
||||
+ /* Create per netdev entries */
|
||||
+ priv->dbgfs_dir = debugfs_create_dir(dev->name, stmmac_fs_dir);
|
||||
|
||||
- if (!stmmac_fs_dir || IS_ERR(stmmac_fs_dir)) {
|
||||
- pr_err("ERROR %s, debugfs create directory failed\n",
|
||||
- STMMAC_RESOURCE_NAME);
|
||||
+ if (!priv->dbgfs_dir || IS_ERR(priv->dbgfs_dir)) {
|
||||
+ pr_err("ERROR %s/%s, debugfs create directory failed\n",
|
||||
+ STMMAC_RESOURCE_NAME, dev->name);
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Entry to report DMA RX/TX rings */
|
||||
- stmmac_rings_status = debugfs_create_file("descriptors_status",
|
||||
- S_IRUGO, stmmac_fs_dir, dev,
|
||||
- &stmmac_rings_status_fops);
|
||||
+ priv->dbgfs_rings_status =
|
||||
+ debugfs_create_file("descriptors_status", S_IRUGO,
|
||||
+ priv->dbgfs_dir, dev,
|
||||
+ &stmmac_rings_status_fops);
|
||||
|
||||
- if (!stmmac_rings_status || IS_ERR(stmmac_rings_status)) {
|
||||
+ if (!priv->dbgfs_rings_status || IS_ERR(priv->dbgfs_rings_status)) {
|
||||
pr_info("ERROR creating stmmac ring debugfs file\n");
|
||||
- debugfs_remove(stmmac_fs_dir);
|
||||
+ debugfs_remove_recursive(priv->dbgfs_dir);
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Entry to report the DMA HW features */
|
||||
- stmmac_dma_cap = debugfs_create_file("dma_cap", S_IRUGO, stmmac_fs_dir,
|
||||
- dev, &stmmac_dma_cap_fops);
|
||||
+ priv->dbgfs_dma_cap = debugfs_create_file("dma_cap", S_IRUGO,
|
||||
+ priv->dbgfs_dir,
|
||||
+ dev, &stmmac_dma_cap_fops);
|
||||
|
||||
- if (!stmmac_dma_cap || IS_ERR(stmmac_dma_cap)) {
|
||||
+ if (!priv->dbgfs_dma_cap || IS_ERR(priv->dbgfs_dma_cap)) {
|
||||
pr_info("ERROR creating stmmac MMC debugfs file\n");
|
||||
- debugfs_remove(stmmac_rings_status);
|
||||
- debugfs_remove(stmmac_fs_dir);
|
||||
+ debugfs_remove_recursive(priv->dbgfs_dir);
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
@@ -2644,11 +2645,11 @@ static int stmmac_init_fs(struct net_dev
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static void stmmac_exit_fs(void)
|
||||
+static void stmmac_exit_fs(struct net_device *dev)
|
||||
{
|
||||
- debugfs_remove(stmmac_rings_status);
|
||||
- debugfs_remove(stmmac_dma_cap);
|
||||
- debugfs_remove(stmmac_fs_dir);
|
||||
+ struct stmmac_priv *priv = netdev_priv(dev);
|
||||
+
|
||||
+ debugfs_remove_recursive(priv->dbgfs_dir);
|
||||
}
|
||||
#endif /* CONFIG_STMMAC_DEBUG_FS */
|
||||
|
||||
@@ -3032,6 +3033,21 @@ static int __init stmmac_init(void)
|
||||
ret = stmmac_register_pci();
|
||||
if (ret)
|
||||
goto err_pci;
|
||||
+
|
||||
+#ifdef CONFIG_STMMAC_DEBUG_FS
|
||||
+ /* Create debugfs main directory if it doesn't exist yet */
|
||||
+ if (stmmac_fs_dir == NULL) {
|
||||
+ stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL);
|
||||
+
|
||||
+ if (!stmmac_fs_dir || IS_ERR(stmmac_fs_dir)) {
|
||||
+ pr_err("ERROR %s, debugfs create directory failed\n",
|
||||
+ STMMAC_RESOURCE_NAME);
|
||||
+
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
return 0;
|
||||
err_pci:
|
||||
stmmac_unregister_platform();
|
||||
@@ -3042,6 +3058,9 @@ err:
|
||||
|
||||
static void __exit stmmac_exit(void)
|
||||
{
|
||||
+#ifdef CONFIG_STMMAC_DEBUG_FS
|
||||
+ debugfs_remove_recursive(stmmac_fs_dir);
|
||||
+#endif
|
||||
stmmac_unregister_platform();
|
||||
stmmac_unregister_pci();
|
||||
}
|
|
@ -9,27 +9,23 @@ Subject: [PATCH] stmac: platform: add support for retreiving mac from mtd
|
|||
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
||||
@@ -284,6 +284,7 @@ static int stmmac_pltfr_probe(struct pla
|
||||
struct stmmac_priv *priv = NULL;
|
||||
struct plat_stmmacenet_data *plat_dat = NULL;
|
||||
const char *mac = NULL;
|
||||
+ u8 mtd_mac[ETH_ALEN] = { };
|
||||
@@ -116,6 +116,19 @@ stmmac_probe_config_dt(struct platform_d
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
addr = devm_ioremap_resource(dev, res);
|
||||
@@ -313,6 +314,15 @@ static int stmmac_pltfr_probe(struct pla
|
||||
pr_err("%s: main dt probe failed", __func__);
|
||||
return ret;
|
||||
}
|
||||
*mac = of_get_mac_address(np);
|
||||
+ if (!*mac) {
|
||||
+ u8 mtd_mac[ETH_ALEN];
|
||||
+ int ret;
|
||||
+
|
||||
+ if (!mac) {
|
||||
+ ret = of_get_mac_address_mtd(dev->of_node, &mtd_mac);
|
||||
+ ret = of_get_mac_address_mtd(np, mtd_mac);
|
||||
+ if (ret == -EPROBE_DEFER)
|
||||
+ return ret;
|
||||
+ return ERR_PTR(ret);
|
||||
+
|
||||
+ if (is_valid_ether_addr(&mtd_mac))
|
||||
+ mac = mtd_mac;
|
||||
+ if (is_valid_ether_addr(mtd_mac))
|
||||
+ *mac = devm_kmemdup(&pdev->dev, mtd_mac, ETH_ALEN,
|
||||
+ GFP_KERNEL);
|
||||
+ }
|
||||
}
|
||||
+
|
||||
plat->interface = of_get_phy_mode(np);
|
||||
|
||||
/* Custom setup (if needed) */
|
||||
/* Get max speed of operation from device tree */
|
||||
|
|
|
@ -1,105 +0,0 @@
|
|||
From 4f09499bc1d9bb095caccbcd73ff951ee631e521 Mon Sep 17 00:00:00 2001
|
||||
From: Mathieu Olivari <mathieu@codeaurora.org>
|
||||
Date: Fri, 8 May 2015 15:42:40 -0700
|
||||
Subject: [PATCH 1/8] stmmac: add phy-handle support to the platform layer
|
||||
|
||||
On stmmac driver, PHY specification in device-tree was done using the
|
||||
non-standard property "snps,phy-addr". Specifying a PHY on a different
|
||||
MDIO bus that the one within the stmmac controller doesn't seem to be
|
||||
possible when device-tree is used.
|
||||
|
||||
This change adds support for the phy-handle property, as specified in
|
||||
Documentation/devicetree/bindings/net/ethernet.txt.
|
||||
|
||||
Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
||||
---
|
||||
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 28 ++++++++++++++--------
|
||||
.../net/ethernet/stmicro/stmmac/stmmac_platform.c | 6 ++++-
|
||||
include/linux/stmmac.h | 1 +
|
||||
3 files changed, 24 insertions(+), 11 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
|
||||
@@ -52,6 +52,7 @@
|
||||
#include "stmmac_ptp.h"
|
||||
#include "stmmac.h"
|
||||
#include <linux/reset.h>
|
||||
+#include <linux/of_mdio.h>
|
||||
|
||||
#define STMMAC_ALIGN(x) L1_CACHE_ALIGN(x)
|
||||
|
||||
@@ -816,18 +817,25 @@ static int stmmac_init_phy(struct net_de
|
||||
priv->speed = 0;
|
||||
priv->oldduplex = -1;
|
||||
|
||||
- if (priv->plat->phy_bus_name)
|
||||
- snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x",
|
||||
- priv->plat->phy_bus_name, priv->plat->bus_id);
|
||||
- else
|
||||
- snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x",
|
||||
- priv->plat->bus_id);
|
||||
-
|
||||
- snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
|
||||
- priv->plat->phy_addr);
|
||||
- pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id_fmt);
|
||||
+ if (priv->plat->phy_node) {
|
||||
+ phydev = of_phy_connect(dev, priv->plat->phy_node,
|
||||
+ &stmmac_adjust_link, 0, interface);
|
||||
+ } else {
|
||||
+ if (priv->plat->phy_bus_name)
|
||||
+ snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x",
|
||||
+ priv->plat->phy_bus_name, priv->plat->bus_id);
|
||||
+ else
|
||||
+ snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x",
|
||||
+ priv->plat->bus_id);
|
||||
+
|
||||
+ snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
|
||||
+ priv->plat->phy_addr);
|
||||
+ pr_debug("stmmac_init_phy: trying to attach to %s\n",
|
||||
+ phy_id_fmt);
|
||||
|
||||
- phydev = phy_connect(dev, phy_id_fmt, &stmmac_adjust_link, interface);
|
||||
+ phydev = phy_connect(dev, phy_id_fmt, &stmmac_adjust_link,
|
||||
+ interface);
|
||||
+ }
|
||||
|
||||
if (IS_ERR_OR_NULL(phydev)) {
|
||||
pr_err("%s: Could not attach to PHY\n", dev->name);
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_net.h>
|
||||
#include <linux/of_device.h>
|
||||
+#include <linux/of_mdio.h>
|
||||
|
||||
#include "stmmac.h"
|
||||
#include "stmmac_platform.h"
|
||||
@@ -168,13 +169,16 @@ static int stmmac_probe_config_dt(struct
|
||||
/* Default to phy auto-detection */
|
||||
plat->phy_addr = -1;
|
||||
|
||||
+ /* If we find a phy-handle property, use it as the PHY */
|
||||
+ plat->phy_node = of_parse_phandle(np, "phy-handle", 0);
|
||||
+
|
||||
/* "snps,phy-addr" is not a standard property. Mark it as deprecated
|
||||
* and warn of its use. Remove this when phy node support is added.
|
||||
*/
|
||||
if (of_property_read_u32(np, "snps,phy-addr", &plat->phy_addr) == 0)
|
||||
dev_warn(&pdev->dev, "snps,phy-addr property is deprecated\n");
|
||||
|
||||
- if (plat->phy_bus_name)
|
||||
+ if (plat->phy_node || plat->phy_bus_name)
|
||||
plat->mdio_bus_data = NULL;
|
||||
else
|
||||
plat->mdio_bus_data =
|
||||
--- a/include/linux/stmmac.h
|
||||
+++ b/include/linux/stmmac.h
|
||||
@@ -99,6 +99,7 @@ struct plat_stmmacenet_data {
|
||||
int phy_addr;
|
||||
int interface;
|
||||
struct stmmac_mdio_bus_data *mdio_bus_data;
|
||||
+ struct device_node *phy_node;
|
||||
struct stmmac_dma_cfg *dma_cfg;
|
||||
int clk_csr;
|
||||
int has_gmac;
|
File diff suppressed because it is too large
Load Diff
|
@ -1,65 +0,0 @@
|
|||
From 0149d275415cd1b2382ce94e5eb32641590097d0 Mon Sep 17 00:00:00 2001
|
||||
From: Mathieu Olivari <mathieu@codeaurora.org>
|
||||
Date: Fri, 8 May 2015 15:57:12 -0700
|
||||
Subject: [PATCH 2/8] stmmac: move error path at the end of
|
||||
stmmac_probe_config_dt()
|
||||
|
||||
We will want to do additional clean-up on certain errors. Therefore,
|
||||
this change moves the error path at the end of the function for better
|
||||
code readability.
|
||||
|
||||
This patch doesn't change anything functionally.
|
||||
|
||||
Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
||||
---
|
||||
.../net/ethernet/stmicro/stmmac/stmmac_platform.c | 22 ++++++++++++++++------
|
||||
1 file changed, 16 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
||||
@@ -130,13 +130,18 @@ static int stmmac_probe_config_dt(struct
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct stmmac_dma_cfg *dma_cfg;
|
||||
const struct of_device_id *device;
|
||||
+ int ret;
|
||||
|
||||
- if (!np)
|
||||
- return -ENODEV;
|
||||
+ if (!np) {
|
||||
+ ret = -ENODEV;
|
||||
+ goto err;
|
||||
+ }
|
||||
|
||||
device = of_match_device(stmmac_dt_ids, &pdev->dev);
|
||||
- if (!device)
|
||||
- return -ENODEV;
|
||||
+ if (!device) {
|
||||
+ ret = -ENODEV;
|
||||
+ goto err;
|
||||
+ }
|
||||
|
||||
if (device->data) {
|
||||
const struct stmmac_of_data *data = device->data;
|
||||
@@ -236,8 +241,10 @@ static int stmmac_probe_config_dt(struct
|
||||
if (of_find_property(np, "snps,pbl", NULL)) {
|
||||
dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg),
|
||||
GFP_KERNEL);
|
||||
- if (!dma_cfg)
|
||||
- return -ENOMEM;
|
||||
+ if (!dma_cfg) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto err;
|
||||
+ }
|
||||
plat->dma_cfg = dma_cfg;
|
||||
of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl);
|
||||
dma_cfg->fixed_burst =
|
||||
@@ -255,6 +262,9 @@ static int stmmac_probe_config_dt(struct
|
||||
}
|
||||
|
||||
return 0;
|
||||
+
|
||||
+err:
|
||||
+ return ret;
|
||||
}
|
||||
#else
|
||||
static int stmmac_probe_config_dt(struct platform_device *pdev,
|
|
@ -1,64 +0,0 @@
|
|||
From 3a95f75867be562cb919ff23a738f70357188fbd Mon Sep 17 00:00:00 2001
|
||||
From: Mathieu Olivari <mathieu@codeaurora.org>
|
||||
Date: Fri, 8 May 2015 16:02:03 -0700
|
||||
Subject: [PATCH 3/8] stmmac: add fixed-link device-tree support
|
||||
|
||||
In case DT is used, this change adds the ability to the stmmac driver to
|
||||
detect a fixed-link PHY, instanciate it, and use it during
|
||||
phy_connect().
|
||||
|
||||
Fixed link PHYs DT usage is described in:
|
||||
Documentation/devicetree/bindings/net/fixed-link.txt
|
||||
|
||||
Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
||||
---
|
||||
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +-
|
||||
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 12 +++++++++++-
|
||||
2 files changed, 12 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
|
||||
@@ -859,7 +859,7 @@ static int stmmac_init_phy(struct net_de
|
||||
* device as well.
|
||||
* Note: phydev->phy_id is the result of reading the UID PHY registers.
|
||||
*/
|
||||
- if (phydev->phy_id == 0) {
|
||||
+ if (!priv->plat->phy_node && phydev->phy_id == 0) {
|
||||
phy_disconnect(phydev);
|
||||
return -ENODEV;
|
||||
}
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
||||
@@ -177,6 +177,14 @@ static int stmmac_probe_config_dt(struct
|
||||
/* If we find a phy-handle property, use it as the PHY */
|
||||
plat->phy_node = of_parse_phandle(np, "phy-handle", 0);
|
||||
|
||||
+ /* If phy-handle is not specified, check if we have a fixed-phy */
|
||||
+ if (!plat->phy_node && of_phy_is_fixed_link(np)) {
|
||||
+ if ((of_phy_register_fixed_link(np) < 0))
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ plat->phy_node = of_node_get(np);
|
||||
+ }
|
||||
+
|
||||
/* "snps,phy-addr" is not a standard property. Mark it as deprecated
|
||||
* and warn of its use. Remove this when phy node support is added.
|
||||
*/
|
||||
@@ -243,7 +251,7 @@ static int stmmac_probe_config_dt(struct
|
||||
GFP_KERNEL);
|
||||
if (!dma_cfg) {
|
||||
ret = -ENOMEM;
|
||||
- goto err;
|
||||
+ goto err2;
|
||||
}
|
||||
plat->dma_cfg = dma_cfg;
|
||||
of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl);
|
||||
@@ -263,6 +271,8 @@ static int stmmac_probe_config_dt(struct
|
||||
|
||||
return 0;
|
||||
|
||||
+err2:
|
||||
+ of_node_put(np);
|
||||
err:
|
||||
return ret;
|
||||
}
|
|
@ -1,407 +0,0 @@
|
|||
From 69fb970ad3fe05af7cb99ea78230c69c7ca0d03b Mon Sep 17 00:00:00 2001
|
||||
From: Mathieu Olivari <mathieu@codeaurora.org>
|
||||
Date: Fri, 8 May 2015 16:10:22 -0700
|
||||
Subject: [PATCH 4/8] stmmac: add ipq806x glue layer
|
||||
|
||||
The ethernet controller available in IPQ806x is a Synopsys DesignWare
|
||||
Gigabit MAC IP core, already supported by the stmmac driver.
|
||||
|
||||
This glue layer implements some platform specific settings required to
|
||||
get the controller working on an IPQ806x based platform.
|
||||
|
||||
Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
||||
---
|
||||
drivers/net/ethernet/stmicro/stmmac/Kconfig | 1 +
|
||||
drivers/net/ethernet/stmicro/stmmac/Makefile | 2 +-
|
||||
drivers/net/ethernet/stmicro/stmmac/dwmac-ipq.c | 324 +++++++++++++++++++++
|
||||
.../net/ethernet/stmicro/stmmac/stmmac_platform.c | 1 +
|
||||
.../net/ethernet/stmicro/stmmac/stmmac_platform.h | 1 +
|
||||
5 files changed, 328 insertions(+), 1 deletion(-)
|
||||
create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-ipq.c
|
||||
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
|
||||
@@ -16,6 +16,7 @@ if STMMAC_ETH
|
||||
config STMMAC_PLATFORM
|
||||
tristate "STMMAC Platform bus support"
|
||||
depends on STMMAC_ETH
|
||||
+ select MFD_SYSCON
|
||||
default y
|
||||
---help---
|
||||
This selects the platform specific bus support for the stmmac driver.
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
|
||||
@@ -6,7 +6,7 @@ stmmac-objs:= stmmac_main.o stmmac_ethto
|
||||
|
||||
obj-$(CONFIG_STMMAC_PLATFORM) += stmmac-platform.o
|
||||
stmmac-platform-objs:= stmmac_platform.o dwmac-meson.o dwmac-sunxi.o \
|
||||
- dwmac-sti.o dwmac-socfpga.o dwmac-rk.o
|
||||
+ dwmac-sti.o dwmac-socfpga.o dwmac-rk.o dwmac-ipq806x.o
|
||||
|
||||
obj-$(CONFIG_STMMAC_PCI) += stmmac-pci.o
|
||||
stmmac-pci-objs:= stmmac_pci.o
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
||||
@@ -43,6 +43,7 @@ static const struct of_device_id stmmac_
|
||||
{ .compatible = "st,stid127-dwmac", .data = &stid127_dwmac_data},
|
||||
{ .compatible = "st,stih407-dwmac", .data = &stih4xx_dwmac_data},
|
||||
{ .compatible = "altr,socfpga-stmmac", .data = &socfpga_gmac_data },
|
||||
+ { .compatible = "qcom,ipq806x-gmac", .data = &ipq806x_gmac_data },
|
||||
{ .compatible = "st,spear600-gmac"},
|
||||
{ .compatible = "snps,dwmac-3.610"},
|
||||
{ .compatible = "snps,dwmac-3.70a"},
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h
|
||||
@@ -25,5 +25,6 @@ extern const struct stmmac_of_data stih4
|
||||
extern const struct stmmac_of_data stid127_dwmac_data;
|
||||
extern const struct stmmac_of_data socfpga_gmac_data;
|
||||
extern const struct stmmac_of_data rk3288_gmac_data;
|
||||
+extern const struct stmmac_of_data ipq806x_gmac_data;
|
||||
|
||||
#endif /* __STMMAC_PLATFORM_H__ */
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
|
||||
@@ -0,0 +1,343 @@
|
||||
+/*
|
||||
+ * Qualcomm Atheros IPQ806x GMAC glue layer
|
||||
+ *
|
||||
+ * Copyright (C) 2015 The Linux Foundation
|
||||
+ *
|
||||
+ * Permission to use, copy, modify, and/or distribute this software for any
|
||||
+ * purpose with or without fee is hereby granted, provided that the above
|
||||
+ * copyright notice and this permission notice appear in all copies.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/device.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/phy.h>
|
||||
+#include <linux/regmap.h>
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/reset.h>
|
||||
+#include <linux/of_net.h>
|
||||
+#include <linux/mfd/syscon.h>
|
||||
+#include <linux/stmmac.h>
|
||||
+#include <linux/of_mdio.h>
|
||||
+
|
||||
+#include "stmmac_platform.h"
|
||||
+
|
||||
+#define NSS_COMMON_CLK_GATE 0x8
|
||||
+#define NSS_COMMON_CLK_GATE_PTP_EN(x) BIT(0x10 + x)
|
||||
+#define NSS_COMMON_CLK_GATE_RGMII_RX_EN(x) BIT(0x9 + (x * 2))
|
||||
+#define NSS_COMMON_CLK_GATE_RGMII_TX_EN(x) BIT(0x8 + (x * 2))
|
||||
+#define NSS_COMMON_CLK_GATE_GMII_RX_EN(x) BIT(0x4 + x)
|
||||
+#define NSS_COMMON_CLK_GATE_GMII_TX_EN(x) BIT(0x0 + x)
|
||||
+
|
||||
+#define NSS_COMMON_CLK_DIV0 0xC
|
||||
+#define NSS_COMMON_CLK_DIV_OFFSET(x) (x * 8)
|
||||
+#define NSS_COMMON_CLK_DIV_MASK 0x7f
|
||||
+
|
||||
+#define NSS_COMMON_CLK_SRC_CTRL 0x14
|
||||
+#define NSS_COMMON_CLK_SRC_CTRL_OFFSET(x) (1 << x)
|
||||
+/* Mode is coded on 1 bit but is different depending on the MAC ID:
|
||||
+ * MAC0: QSGMII=0 RGMII=1
|
||||
+ * MAC1: QSGMII=0 SGMII=0 RGMII=1
|
||||
+ * MAC2 & MAC3: QSGMII=0 SGMII=1
|
||||
+ */
|
||||
+#define NSS_COMMON_CLK_SRC_CTRL_RGMII(x) 1
|
||||
+#define NSS_COMMON_CLK_SRC_CTRL_SGMII(x) ((x >= 2) ? 1 : 0)
|
||||
+
|
||||
+#define NSS_COMMON_MACSEC_CTL 0x28
|
||||
+#define NSS_COMMON_MACSEC_CTL_EXT_BYPASS_EN(x) (1 << x)
|
||||
+
|
||||
+#define NSS_COMMON_GMAC_CTL(x) (0x30 + (x * 4))
|
||||
+#define NSS_COMMON_GMAC_CTL_CSYS_REQ BIT(19)
|
||||
+#define NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL BIT(16)
|
||||
+#define NSS_COMMON_GMAC_CTL_IFG_LIMIT_OFFSET 8
|
||||
+#define NSS_COMMON_GMAC_CTL_IFG_OFFSET 0
|
||||
+#define NSS_COMMON_GMAC_CTL_IFG_MASK 0x3f
|
||||
+
|
||||
+#define NSS_COMMON_CLK_DIV_RGMII_1000 1
|
||||
+#define NSS_COMMON_CLK_DIV_RGMII_100 9
|
||||
+#define NSS_COMMON_CLK_DIV_RGMII_10 99
|
||||
+#define NSS_COMMON_CLK_DIV_SGMII_1000 0
|
||||
+#define NSS_COMMON_CLK_DIV_SGMII_100 4
|
||||
+#define NSS_COMMON_CLK_DIV_SGMII_10 49
|
||||
+
|
||||
+#define QSGMII_PCS_MODE_CTL 0x68
|
||||
+#define QSGMII_PCS_MODE_CTL_AUTONEG_EN(x) BIT((x * 8) + 7)
|
||||
+
|
||||
+#define QSGMII_PCS_CAL_LCKDT_CTL 0x120
|
||||
+#define QSGMII_PCS_CAL_LCKDT_CTL_RST BIT(19)
|
||||
+
|
||||
+/* Only GMAC1/2/3 support SGMII and their CTL register are not contiguous */
|
||||
+#define QSGMII_PHY_SGMII_CTL(x) ((x == 1) ? 0x134 : \
|
||||
+ (0x13c + (4 * (x - 2))))
|
||||
+#define QSGMII_PHY_CDR_EN BIT(0)
|
||||
+#define QSGMII_PHY_RX_FRONT_EN BIT(1)
|
||||
+#define QSGMII_PHY_RX_SIGNAL_DETECT_EN BIT(2)
|
||||
+#define QSGMII_PHY_TX_DRIVER_EN BIT(3)
|
||||
+#define QSGMII_PHY_QSGMII_EN BIT(7)
|
||||
+#define QSGMII_PHY_PHASE_LOOP_GAIN_OFFSET 12
|
||||
+#define QSGMII_PHY_PHASE_LOOP_GAIN_MASK 0x7
|
||||
+#define QSGMII_PHY_RX_DC_BIAS_OFFSET 18
|
||||
+#define QSGMII_PHY_RX_DC_BIAS_MASK 0x3
|
||||
+#define QSGMII_PHY_RX_INPUT_EQU_OFFSET 20
|
||||
+#define QSGMII_PHY_RX_INPUT_EQU_MASK 0x3
|
||||
+#define QSGMII_PHY_CDR_PI_SLEW_OFFSET 22
|
||||
+#define QSGMII_PHY_CDR_PI_SLEW_MASK 0x3
|
||||
+#define QSGMII_PHY_TX_DRV_AMP_OFFSET 28
|
||||
+#define QSGMII_PHY_TX_DRV_AMP_MASK 0xf
|
||||
+
|
||||
+struct ipq806x_gmac {
|
||||
+ struct platform_device *pdev;
|
||||
+ struct regmap *nss_common;
|
||||
+ struct regmap *qsgmii_csr;
|
||||
+ uint32_t id;
|
||||
+ struct clk *core_clk;
|
||||
+ phy_interface_t phy_mode;
|
||||
+};
|
||||
+
|
||||
+static int get_clk_div_sgmii(struct ipq806x_gmac *gmac, unsigned int speed)
|
||||
+{
|
||||
+ struct device *dev = &gmac->pdev->dev;
|
||||
+ int div;
|
||||
+
|
||||
+ switch (speed) {
|
||||
+ case SPEED_1000:
|
||||
+ div = NSS_COMMON_CLK_DIV_SGMII_1000;
|
||||
+ break;
|
||||
+
|
||||
+ case SPEED_100:
|
||||
+ div = NSS_COMMON_CLK_DIV_SGMII_100;
|
||||
+ break;
|
||||
+
|
||||
+ case SPEED_10:
|
||||
+ div = NSS_COMMON_CLK_DIV_SGMII_10;
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ dev_err(dev, "Speed %dMbps not supported in SGMII\n", speed);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return div;
|
||||
+}
|
||||
+
|
||||
+static int get_clk_div_rgmii(struct ipq806x_gmac *gmac, unsigned int speed)
|
||||
+{
|
||||
+ struct device *dev = &gmac->pdev->dev;
|
||||
+ int div;
|
||||
+
|
||||
+ switch (speed) {
|
||||
+ case SPEED_1000:
|
||||
+ div = NSS_COMMON_CLK_DIV_RGMII_1000;
|
||||
+ break;
|
||||
+
|
||||
+ case SPEED_100:
|
||||
+ div = NSS_COMMON_CLK_DIV_RGMII_100;
|
||||
+ break;
|
||||
+
|
||||
+ case SPEED_10:
|
||||
+ div = NSS_COMMON_CLK_DIV_RGMII_10;
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ dev_err(dev, "Speed %dMbps not supported in RGMII\n", speed);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return div;
|
||||
+}
|
||||
+
|
||||
+static int ipq806x_gmac_set_speed(struct ipq806x_gmac *gmac, unsigned int speed)
|
||||
+{
|
||||
+ uint32_t clk_bits, val;
|
||||
+ int div;
|
||||
+
|
||||
+ switch (gmac->phy_mode) {
|
||||
+ case PHY_INTERFACE_MODE_RGMII:
|
||||
+ div = get_clk_div_rgmii(gmac, speed);
|
||||
+ clk_bits = NSS_COMMON_CLK_GATE_RGMII_RX_EN(gmac->id) |
|
||||
+ NSS_COMMON_CLK_GATE_RGMII_TX_EN(gmac->id);
|
||||
+ break;
|
||||
+
|
||||
+ case PHY_INTERFACE_MODE_SGMII:
|
||||
+ div = get_clk_div_sgmii(gmac, speed);
|
||||
+ clk_bits = NSS_COMMON_CLK_GATE_GMII_RX_EN(gmac->id) |
|
||||
+ NSS_COMMON_CLK_GATE_GMII_TX_EN(gmac->id);
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ dev_err(&gmac->pdev->dev, "Unsupported PHY mode: \"%s\"\n",
|
||||
+ phy_modes(gmac->phy_mode));
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ /* Disable the clocks */
|
||||
+ regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val);
|
||||
+ val &= ~clk_bits;
|
||||
+ regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);
|
||||
+
|
||||
+ /* Set the divider */
|
||||
+ regmap_read(gmac->nss_common, NSS_COMMON_CLK_DIV0, &val);
|
||||
+ val &= ~(NSS_COMMON_CLK_DIV_MASK
|
||||
+ << NSS_COMMON_CLK_DIV_OFFSET(gmac->id));
|
||||
+ val |= div << NSS_COMMON_CLK_DIV_OFFSET(gmac->id);
|
||||
+ regmap_write(gmac->nss_common, NSS_COMMON_CLK_DIV0, val);
|
||||
+
|
||||
+ /* Enable the clock back */
|
||||
+ regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val);
|
||||
+ val |= clk_bits;
|
||||
+ regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void *ipq806x_gmac_of_parse(struct ipq806x_gmac *gmac)
|
||||
+{
|
||||
+ struct device *dev = &gmac->pdev->dev;
|
||||
+
|
||||
+ gmac->phy_mode = of_get_phy_mode(dev->of_node);
|
||||
+ if (gmac->phy_mode < 0) {
|
||||
+ dev_err(dev, "missing phy mode property\n");
|
||||
+ return ERR_PTR(-EINVAL);
|
||||
+ }
|
||||
+
|
||||
+ if (of_property_read_u32(dev->of_node, "qcom,id", &gmac->id) < 0) {
|
||||
+ dev_err(dev, "missing qcom id property\n");
|
||||
+ return ERR_PTR(-EINVAL);
|
||||
+ }
|
||||
+
|
||||
+ /* The GMACs are called 1 to 4 in the documentation, but to simplify the
|
||||
+ * code and keep it consistent with the Linux convention, we'll number
|
||||
+ * them from 0 to 3 here.
|
||||
+ */
|
||||
+ if (gmac->id < 0 || gmac->id > 3) {
|
||||
+ dev_err(dev, "invalid gmac id\n");
|
||||
+ return ERR_PTR(-EINVAL);
|
||||
+ }
|
||||
+
|
||||
+ gmac->core_clk = devm_clk_get(dev, "stmmaceth");
|
||||
+ if (IS_ERR(gmac->core_clk)) {
|
||||
+ dev_err(dev, "missing stmmaceth clk property\n");
|
||||
+ return gmac->core_clk;
|
||||
+ }
|
||||
+ clk_set_rate(gmac->core_clk, 266000000);
|
||||
+
|
||||
+ /* Setup the register map for the nss common registers */
|
||||
+ gmac->nss_common = syscon_regmap_lookup_by_phandle(dev->of_node,
|
||||
+ "qcom,nss-common");
|
||||
+ if (IS_ERR(gmac->nss_common)) {
|
||||
+ dev_err(dev, "missing nss-common node\n");
|
||||
+ return gmac->nss_common;
|
||||
+ }
|
||||
+
|
||||
+ /* Setup the register map for the qsgmii csr registers */
|
||||
+ gmac->qsgmii_csr = syscon_regmap_lookup_by_phandle(dev->of_node,
|
||||
+ "qcom,qsgmii-csr");
|
||||
+ if (IS_ERR(gmac->qsgmii_csr)) {
|
||||
+ dev_err(dev, "missing qsgmii-csr node\n");
|
||||
+ return gmac->qsgmii_csr;
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static void *ipq806x_gmac_setup(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct device *dev = &pdev->dev;
|
||||
+ struct ipq806x_gmac *gmac;
|
||||
+ int val;
|
||||
+ void *err;
|
||||
+
|
||||
+ gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL);
|
||||
+ if (!gmac)
|
||||
+ return ERR_PTR(-ENOMEM);
|
||||
+
|
||||
+ gmac->pdev = pdev;
|
||||
+
|
||||
+ err = ipq806x_gmac_of_parse(gmac);
|
||||
+ if (err) {
|
||||
+ dev_err(dev, "device tree parsing error\n");
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ regmap_write(gmac->qsgmii_csr, QSGMII_PCS_CAL_LCKDT_CTL,
|
||||
+ QSGMII_PCS_CAL_LCKDT_CTL_RST);
|
||||
+
|
||||
+ /* Inter frame gap is set to 12 */
|
||||
+ val = 12 << NSS_COMMON_GMAC_CTL_IFG_OFFSET |
|
||||
+ 12 << NSS_COMMON_GMAC_CTL_IFG_LIMIT_OFFSET;
|
||||
+ /* We also initiate an AXI low power exit request */
|
||||
+ val |= NSS_COMMON_GMAC_CTL_CSYS_REQ;
|
||||
+ switch (gmac->phy_mode) {
|
||||
+ case PHY_INTERFACE_MODE_RGMII:
|
||||
+ val |= NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL;
|
||||
+ break;
|
||||
+ case PHY_INTERFACE_MODE_SGMII:
|
||||
+ val &= ~NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL;
|
||||
+ break;
|
||||
+ default:
|
||||
+ dev_err(&pdev->dev, "Unsupported PHY mode: \"%s\"\n",
|
||||
+ phy_modes(gmac->phy_mode));
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ regmap_write(gmac->nss_common, NSS_COMMON_GMAC_CTL(gmac->id), val);
|
||||
+
|
||||
+ /* Configure the clock src according to the mode */
|
||||
+ regmap_read(gmac->nss_common, NSS_COMMON_CLK_SRC_CTRL, &val);
|
||||
+ val &= ~NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id);
|
||||
+ switch (gmac->phy_mode) {
|
||||
+ case PHY_INTERFACE_MODE_RGMII:
|
||||
+ val |= NSS_COMMON_CLK_SRC_CTRL_RGMII(gmac->id) <<
|
||||
+ NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id);
|
||||
+ break;
|
||||
+ case PHY_INTERFACE_MODE_SGMII:
|
||||
+ val |= NSS_COMMON_CLK_SRC_CTRL_SGMII(gmac->id) <<
|
||||
+ NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id);
|
||||
+ break;
|
||||
+ default:
|
||||
+ dev_err(&pdev->dev, "Unsupported PHY mode: \"%s\"\n",
|
||||
+ phy_modes(gmac->phy_mode));
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ regmap_write(gmac->nss_common, NSS_COMMON_CLK_SRC_CTRL, val);
|
||||
+
|
||||
+ /* Enable PTP clock */
|
||||
+ regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val);
|
||||
+ val |= NSS_COMMON_CLK_GATE_PTP_EN(gmac->id);
|
||||
+ regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);
|
||||
+
|
||||
+ if (gmac->phy_mode == PHY_INTERFACE_MODE_SGMII) {
|
||||
+ regmap_write(gmac->qsgmii_csr, QSGMII_PHY_SGMII_CTL(gmac->id),
|
||||
+ QSGMII_PHY_CDR_EN |
|
||||
+ QSGMII_PHY_RX_FRONT_EN |
|
||||
+ QSGMII_PHY_RX_SIGNAL_DETECT_EN |
|
||||
+ QSGMII_PHY_TX_DRIVER_EN |
|
||||
+ QSGMII_PHY_QSGMII_EN |
|
||||
+ 0x4 << QSGMII_PHY_PHASE_LOOP_GAIN_OFFSET |
|
||||
+ 0x3 << QSGMII_PHY_RX_DC_BIAS_OFFSET |
|
||||
+ 0x1 << QSGMII_PHY_RX_INPUT_EQU_OFFSET |
|
||||
+ 0x2 << QSGMII_PHY_CDR_PI_SLEW_OFFSET |
|
||||
+ 0xC << QSGMII_PHY_TX_DRV_AMP_OFFSET);
|
||||
+ }
|
||||
+
|
||||
+ return gmac;
|
||||
+}
|
||||
+
|
||||
+static void ipq806x_gmac_fix_mac_speed(void *priv, unsigned int speed)
|
||||
+{
|
||||
+ struct ipq806x_gmac *gmac = priv;
|
||||
+
|
||||
+ ipq806x_gmac_set_speed(gmac, speed);
|
||||
+}
|
||||
+
|
||||
+const struct stmmac_of_data ipq806x_gmac_data = {
|
||||
+ .has_gmac = 1,
|
||||
+ .setup = ipq806x_gmac_setup,
|
||||
+ .fix_mac_speed = ipq806x_gmac_fix_mac_speed,
|
||||
+};
|
|
@ -1,52 +0,0 @@
|
|||
From 0f9605d9409b77a89daef91cc68239fc2ff50457 Mon Sep 17 00:00:00 2001
|
||||
From: Mathieu Olivari <mathieu@codeaurora.org>
|
||||
Date: Fri, 8 May 2015 16:51:25 -0700
|
||||
Subject: [PATCH 5/8] net: stmmac: ipq806x: document device tree bindings
|
||||
|
||||
Add the device tree bindings documentation for the QCA IPQ806x
|
||||
variant of the Synopsys DesignWare MAC.
|
||||
|
||||
Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
||||
---
|
||||
.../devicetree/bindings/net/ipq806x-dwmac.txt | 35 ++++++++++++++++++++++
|
||||
1 file changed, 35 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/net/ipq806x-dwmac.txt
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/net/ipq806x-dwmac.txt
|
||||
@@ -0,0 +1,35 @@
|
||||
+* IPQ806x DWMAC Ethernet controller
|
||||
+
|
||||
+The device inherits all the properties of the dwmac/stmmac devices
|
||||
+described in the file net/stmmac.txt with the following changes.
|
||||
+
|
||||
+Required properties:
|
||||
+
|
||||
+- compatible: should be "qcom,ipq806x-gmac" along with "snps,dwmac"
|
||||
+ and any applicable more detailed version number
|
||||
+ described in net/stmmac.txt
|
||||
+
|
||||
+- qcom,nss-common: should contain a phandle to a syscon device mapping the
|
||||
+ nss-common registers.
|
||||
+
|
||||
+- qcom,qsgmii-csr: should contain a phandle to a syscon device mapping the
|
||||
+ qsgmii-csr registers.
|
||||
+
|
||||
+Example:
|
||||
+
|
||||
+ gmac: ethernet@37000000 {
|
||||
+ device_type = "network";
|
||||
+ compatible = "qcom,ipq806x-gmac";
|
||||
+ reg = <0x37000000 0x200000>;
|
||||
+ interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ interrupt-names = "macirq";
|
||||
+
|
||||
+ qcom,nss-common = <&nss_common>;
|
||||
+ qcom,qsgmii-csr = <&qsgmii_csr>;
|
||||
+
|
||||
+ clocks = <&gcc GMAC_CORE1_CLK>;
|
||||
+ clock-names = "stmmaceth";
|
||||
+
|
||||
+ resets = <&gcc GMAC_CORE1_RESET>;
|
||||
+ reset-names = "stmmaceth";
|
||||
+ };
|
|
@ -9,27 +9,23 @@ Subject: [PATCH] stmac: platform: add support for retreiving mac from mtd
|
|||
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
||||
@@ -302,6 +302,7 @@ static int stmmac_pltfr_probe(struct pla
|
||||
struct stmmac_priv *priv = NULL;
|
||||
struct plat_stmmacenet_data *plat_dat = NULL;
|
||||
const char *mac = NULL;
|
||||
+ u8 mtd_mac[ETH_ALEN] = { };
|
||||
int irq, wol_irq, lpi_irq;
|
||||
@@ -116,6 +116,19 @@ stmmac_probe_config_dt(struct platform_d
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
/* Get IRQ information early to have an ability to ask for deferred
|
||||
@@ -362,6 +363,15 @@ static int stmmac_pltfr_probe(struct pla
|
||||
pr_err("%s: main dt probe failed", __func__);
|
||||
return ret;
|
||||
}
|
||||
*mac = of_get_mac_address(np);
|
||||
+ if (!*mac) {
|
||||
+ u8 mtd_mac[ETH_ALEN];
|
||||
+ int ret;
|
||||
+
|
||||
+ if (!mac) {
|
||||
+ ret = of_get_mac_address_mtd(dev->of_node, &mtd_mac);
|
||||
+ ret = of_get_mac_address_mtd(np, mtd_mac);
|
||||
+ if (ret == -EPROBE_DEFER)
|
||||
+ return ret;
|
||||
+ return ERR_PTR(ret);
|
||||
+
|
||||
+ if (is_valid_ether_addr(&mtd_mac))
|
||||
+ mac = mtd_mac;
|
||||
+ if (is_valid_ether_addr(mtd_mac))
|
||||
+ *mac = devm_kmemdup(&pdev->dev, mtd_mac, ETH_ALEN,
|
||||
+ GFP_KERNEL);
|
||||
+ }
|
||||
}
|
||||
+
|
||||
plat->interface = of_get_phy_mode(np);
|
||||
|
||||
/* Custom setup (if needed) */
|
||||
/* Get max speed of operation from device tree */
|
||||
|
|
Loading…
Reference in New Issue