aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/layerscape/patches-4.14/710-pfe-eth-support-layerscape.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/layerscape/patches-4.14/710-pfe-eth-support-layerscape.patch')
-rw-r--r--target/linux/layerscape/patches-4.14/710-pfe-eth-support-layerscape.patch1350
1 files changed, 747 insertions, 603 deletions
diff --git a/target/linux/layerscape/patches-4.14/710-pfe-eth-support-layerscape.patch b/target/linux/layerscape/patches-4.14/710-pfe-eth-support-layerscape.patch
index ae64527f3d..80baa82f9a 100644
--- a/target/linux/layerscape/patches-4.14/710-pfe-eth-support-layerscape.patch
+++ b/target/linux/layerscape/patches-4.14/710-pfe-eth-support-layerscape.patch
@@ -1,7 +1,8 @@
-From 93febc09be23aa75cbc5bf5e76250c923f4004e5 Mon Sep 17 00:00:00 2001
+From 35745905430a4c9827c235d42f3a61bef34043e8 Mon Sep 17 00:00:00 2001
From: Biwen Li <biwen.li@nxp.com>
-Date: Tue, 30 Oct 2018 18:26:59 +0800
-Subject: [PATCH 16/40] pfe-eth: support layerscape
+Date: Fri, 19 Apr 2019 13:21:09 +0800
+Subject: [PATCH] pfe-eth: support layerscape
+
This is an integrated patch of pfe-eth for layerscape
Signed-off-by: Akhila Kavi <akhila.kavi@nxp.com>
@@ -9,15 +10,17 @@ Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com>
Signed-off-by: Anjaneyulu Jagarlmudi <anji.jagarlmudi@nxp.com>
Signed-off-by: Archana Madhavan <archana.madhavan@nxp.com>
Signed-off-by: Bhaskar Upadhaya <Bhaskar.Upadhaya@nxp.com>
+Signed-off-by: Biwen Li <biwen.li@nxp.com>
Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
Signed-off-by: Guanhua Gao <guanhua.gao@nxp.com>
+Signed-off-by: Sachin Saxena <sachin.saxena@nxp.com>
+Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
-Signed-off-by: Biwen Li <biwen.li@nxp.com>
---
- .../devicetree/bindings/net/fsl_ppfe/pfe.txt | 173 ++
- drivers/staging/fsl_ppfe/Kconfig | 20 +
- drivers/staging/fsl_ppfe/Makefile | 19 +
+ .../devicetree/bindings/net/fsl_ppfe/pfe.txt | 199 ++
+ drivers/staging/fsl_ppfe/Kconfig | 21 +
+ drivers/staging/fsl_ppfe/Makefile | 20 +
drivers/staging/fsl_ppfe/TODO | 2 +
drivers/staging/fsl_ppfe/include/pfe/cbus.h | 78 +
.../staging/fsl_ppfe/include/pfe/cbus/bmu.h | 55 +
@@ -28,29 +31,31 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
.../fsl_ppfe/include/pfe/cbus/hif_nocpy.h | 50 +
.../fsl_ppfe/include/pfe/cbus/tmu_csr.h | 168 ++
.../fsl_ppfe/include/pfe/cbus/util_csr.h | 61 +
- drivers/staging/fsl_ppfe/include/pfe/pfe.h | 373 +++
- drivers/staging/fsl_ppfe/pfe_ctrl.c | 238 ++
- drivers/staging/fsl_ppfe/pfe_ctrl.h | 112 +
- drivers/staging/fsl_ppfe/pfe_debugfs.c | 111 +
- drivers/staging/fsl_ppfe/pfe_debugfs.h | 25 +
- drivers/staging/fsl_ppfe/pfe_eth.c | 2521 +++++++++++++++++
- drivers/staging/fsl_ppfe/pfe_eth.h | 185 ++
- drivers/staging/fsl_ppfe/pfe_firmware.c | 314 ++
- drivers/staging/fsl_ppfe/pfe_firmware.h | 32 +
- drivers/staging/fsl_ppfe/pfe_hal.c | 1528 ++++++++++
- drivers/staging/fsl_ppfe/pfe_hif.c | 1072 +++++++
- drivers/staging/fsl_ppfe/pfe_hif.h | 212 ++
- drivers/staging/fsl_ppfe/pfe_hif_lib.c | 640 +++++
- drivers/staging/fsl_ppfe/pfe_hif_lib.h | 241 ++
- drivers/staging/fsl_ppfe/pfe_hw.c | 176 ++
- drivers/staging/fsl_ppfe/pfe_hw.h | 27 +
- .../staging/fsl_ppfe/pfe_ls1012a_platform.c | 385 +++
- drivers/staging/fsl_ppfe/pfe_mod.c | 156 +
- drivers/staging/fsl_ppfe/pfe_mod.h | 114 +
- drivers/staging/fsl_ppfe/pfe_perfmon.h | 38 +
- drivers/staging/fsl_ppfe/pfe_sysfs.c | 818 ++++++
- drivers/staging/fsl_ppfe/pfe_sysfs.h | 29 +
- 35 files changed, 10690 insertions(+)
+ drivers/staging/fsl_ppfe/include/pfe/pfe.h | 372 +++
+ drivers/staging/fsl_ppfe/pfe_cdev.c | 258 ++
+ drivers/staging/fsl_ppfe/pfe_cdev.h | 41 +
+ drivers/staging/fsl_ppfe/pfe_ctrl.c | 226 ++
+ drivers/staging/fsl_ppfe/pfe_ctrl.h | 100 +
+ drivers/staging/fsl_ppfe/pfe_debugfs.c | 99 +
+ drivers/staging/fsl_ppfe/pfe_debugfs.h | 13 +
+ drivers/staging/fsl_ppfe/pfe_eth.c | 2554 +++++++++++++++++
+ drivers/staging/fsl_ppfe/pfe_eth.h | 175 ++
+ drivers/staging/fsl_ppfe/pfe_firmware.c | 302 ++
+ drivers/staging/fsl_ppfe/pfe_firmware.h | 20 +
+ drivers/staging/fsl_ppfe/pfe_hal.c | 1516 ++++++++++
+ drivers/staging/fsl_ppfe/pfe_hif.c | 1060 +++++++
+ drivers/staging/fsl_ppfe/pfe_hif.h | 200 ++
+ drivers/staging/fsl_ppfe/pfe_hif_lib.c | 628 ++++
+ drivers/staging/fsl_ppfe/pfe_hif_lib.h | 229 ++
+ drivers/staging/fsl_ppfe/pfe_hw.c | 164 ++
+ drivers/staging/fsl_ppfe/pfe_hw.h | 15 +
+ .../staging/fsl_ppfe/pfe_ls1012a_platform.c | 368 +++
+ drivers/staging/fsl_ppfe/pfe_mod.c | 158 +
+ drivers/staging/fsl_ppfe/pfe_mod.h | 103 +
+ drivers/staging/fsl_ppfe/pfe_perfmon.h | 26 +
+ drivers/staging/fsl_ppfe/pfe_sysfs.c | 806 ++++++
+ drivers/staging/fsl_ppfe/pfe_sysfs.h | 17 +
+ 37 files changed, 10821 insertions(+)
create mode 100644 Documentation/devicetree/bindings/net/fsl_ppfe/pfe.txt
create mode 100644 drivers/staging/fsl_ppfe/Kconfig
create mode 100644 drivers/staging/fsl_ppfe/Makefile
@@ -65,6 +70,8 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/tmu_csr.h
create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/util_csr.h
create mode 100644 drivers/staging/fsl_ppfe/include/pfe/pfe.h
+ create mode 100644 drivers/staging/fsl_ppfe/pfe_cdev.c
+ create mode 100644 drivers/staging/fsl_ppfe/pfe_cdev.h
create mode 100644 drivers/staging/fsl_ppfe/pfe_ctrl.c
create mode 100644 drivers/staging/fsl_ppfe/pfe_ctrl.h
create mode 100644 drivers/staging/fsl_ppfe/pfe_debugfs.c
@@ -89,7 +96,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/fsl_ppfe/pfe.txt
-@@ -0,0 +1,173 @@
+@@ -0,0 +1,199 @@
+=============================================================================
+NXP Programmable Packet Forwarding Engine Device Bindings
+
@@ -219,11 +226,12 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ Definition: Must be present. Value should be the id of the bus
+ connected to gemac.
+
-+- fsl,gemac-phy-id
-+ Usage: required
-+ Value type: <u32>
-+ Definition: Must be present. Value should be the id of the phy
-+ connected to gemac.
++- fsl,gemac-phy-id (deprecated binding)
++ Usage: required
++ Value type: <u32>
++ Definition: This binding shouldn't be used with new platforms.
++ Must be present. Value should be the id of the phy
++ connected to gemac.
+
+- fsl,mdio-mux-val
+ Usage: required
@@ -236,15 +244,20 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ Value type: <string>
+ Definition: Must include "sgmii"
+
-+- fsl,pfe-phy-if-flags
-+ Usage: required
-+ Value type: <u32>
-+ Definition: Must be present. Value should be 0 by default.
-+ If there is not phy connected, this need to be 1.
++- fsl,pfe-phy-if-flags (deprecated binding)
++ Usage: required
++ Value type: <u32>
++ Definition: This binding shouldn't be used with new platforms.
++ Must be present. Value should be 0 by default.
++ If there is not phy connected, this need to be 1.
++
++- phy-handle
++ Usage: optional
++ Value type: <phandle>
++ Definition: phandle to the PHY device connected to this device.
+
-+- mdio
-+ optional subnode that specifies the mdio bus. This has reg
-+ property which is used to enable/disable the mdio bus.
++- mdio : A required subnode which specifies the mdio bus in the PFE and used as
++a container for phy nodes according to ../phy.txt.
+
+EXAMPLE
+
@@ -254,23 +267,44 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ #size-cells = <0>;
+ reg = <0x0>; /* GEM_ID */
+ fsl,gemac-bus-id = <0x0>; /* BUS_ID */
-+ fsl,gemac-phy-id = <0x2>; /* PHY_ID */
+ fsl,mdio-mux-val = <0x0>;
+ phy-mode = "sgmii";
-+ fsl,pfe-phy-if-flags = <0x0>;
++ phy-handle = <&sgmii_phy1>;
++};
++
++
++ethernet@1 {
++ compatible = "fsl,pfe-gemac-port";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x1>; /* GEM_ID */
++ fsl,gemac-bus-id = <0x1>; /* BUS_ID */
++ fsl,mdio-mux-val = <0x0>;
++ phy-mode = "sgmii";
++ phy-handle = <&sgmii_phy2>;
++};
+
-+ mdio@0 {
-+ reg = <0x1>; /* enabled/disabled */
++mdio@0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ sgmii_phy1: ethernet-phy@2 {
++ reg = <0x2>;
++ };
++
++ sgmii_phy2: ethernet-phy@1 {
++ reg = <0x1>;
+ };
+};
--- /dev/null
+++ b/drivers/staging/fsl_ppfe/Kconfig
-@@ -0,0 +1,20 @@
+@@ -0,0 +1,21 @@
+#
+# Freescale Programmable Packet Forwarding Engine driver
+#
+config FSL_PPFE
+ bool "Freescale PPFE Driver"
++ select FSL_GUTS
+ default n
+ ---help---
+ Freescale LS1012A SoC has a Programmable Packet Forwarding Engine.
@@ -288,7 +322,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+endif # FSL_PPFE
--- /dev/null
+++ b/drivers/staging/fsl_ppfe/Makefile
-@@ -0,0 +1,19 @@
+@@ -0,0 +1,20 @@
+#
+# Makefile for Freesecale PPFE driver
+#
@@ -307,7 +341,8 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ pfe_sysfs.o \
+ pfe_debugfs.o \
+ pfe_ls1012a_platform.o \
-+ pfe_hal.o
++ pfe_hal.o \
++ pfe_cdev.o
--- /dev/null
+++ b/drivers/staging/fsl_ppfe/TODO
@@ -0,0 +1,2 @@
@@ -1471,7 +1506,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+#endif /* _UTIL_CSR_H_ */
--- /dev/null
+++ b/drivers/staging/fsl_ppfe/include/pfe/pfe.h
-@@ -0,0 +1,373 @@
+@@ -0,0 +1,372 @@
+/*
+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
@@ -1742,7 +1777,6 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+void gemac_init(void *base, void *config);
+void gemac_disable_rx_checksum_offload(void *base);
+void gemac_enable_rx_checksum_offload(void *base);
-+void gemac_set_mdc_div(void *base, int mdc_div);
+void gemac_set_speed(void *base, enum mac_speed gem_speed);
+void gemac_set_duplex(void *base, int duplex);
+void gemac_set_mode(void *base, int mode);
@@ -1846,24 +1880,317 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+
+#endif /* _PFE_H_ */
--- /dev/null
++++ b/drivers/staging/fsl_ppfe/pfe_cdev.c
+@@ -0,0 +1,258 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * Copyright 2018 NXP
++ */
++
++/* @pfe_cdev.c.
++ * Dummy device representing the PFE US in userspace.
++ * - used for interacting with the kernel layer for link status
++ */
++
++#include <linux/eventfd.h>
++#include <linux/irqreturn.h>
++#include <linux/io.h>
++#include <asm/irq.h>
++
++#include "pfe_cdev.h"
++#include "pfe_mod.h"
++
++static int pfe_majno;
++static struct class *pfe_char_class;
++static struct device *pfe_char_dev;
++struct eventfd_ctx *g_trigger;
++
++struct pfe_shared_info link_states[PFE_CDEV_ETH_COUNT];
++
++static int pfe_cdev_open(struct inode *inp, struct file *fp)
++{
++ pr_debug("PFE CDEV device opened.\n");
++ return 0;
++}
++
++static ssize_t pfe_cdev_read(struct file *fp, char *buf,
++ size_t len, loff_t *off)
++{
++ int ret = 0;
++
++ pr_info("PFE CDEV attempt copying (%lu) size of user.\n",
++ sizeof(link_states));
++
++ pr_debug("Dump link_state on screen before copy_to_user\n");
++ for (; ret < PFE_CDEV_ETH_COUNT; ret++) {
++ pr_debug("%u %u", link_states[ret].phy_id,
++ link_states[ret].state);
++ pr_debug("\n");
++ }
++
++ /* Copy to user the value in buffer sized len */
++ ret = copy_to_user(buf, &link_states, sizeof(link_states));
++ if (ret != 0) {
++ pr_err("Failed to send (%d)bytes of (%lu) requested.\n",
++ ret, len);
++ return -EFAULT;
++ }
++
++ /* offset set back to 0 as there is contextual reading offset */
++ *off = 0;
++ pr_debug("Read of (%lu) bytes performed.\n", sizeof(link_states));
++
++ return sizeof(link_states);
++}
++
++/**
++ * This function is for getting some commands from user through non-IOCTL
++ * channel. It can used to configure the device.
++ * TODO: To be filled in future, if require duplex communication with user
++ * space.
++ */
++static ssize_t pfe_cdev_write(struct file *fp, const char *buf,
++ size_t len, loff_t *off)
++{
++ pr_info("PFE CDEV Write operation not supported!\n");
++
++ return -EFAULT;
++}
++
++static int pfe_cdev_release(struct inode *inp, struct file *fp)
++{
++ if (g_trigger) {
++ free_irq(pfe->hif_irq, g_trigger);
++ eventfd_ctx_put(g_trigger);
++ g_trigger = NULL;
++ }
++
++ pr_info("PFE_CDEV: Device successfully closed\n");
++ return 0;
++}
++
++/*
++ * hif_us_isr-
++ * This ISR routine processes Rx/Tx done interrupts from the HIF hardware block
++ */
++static irqreturn_t hif_us_isr(int irq, void *arg)
++{
++ struct eventfd_ctx *trigger = (struct eventfd_ctx *)arg;
++ int int_status;
++ int int_enable_mask;
++
++ /*Read hif interrupt source register */
++ int_status = readl_relaxed(HIF_INT_SRC);
++ int_enable_mask = readl_relaxed(HIF_INT_ENABLE);
++
++ if ((int_status & HIF_INT) == 0)
++ return IRQ_NONE;
++
++ if (int_status & HIF_RXPKT_INT) {
++ int_enable_mask &= ~(HIF_RXPKT_INT);
++ /* Disable interrupts, they will be enabled after
++ * they are serviced
++ */
++ writel_relaxed(int_enable_mask, HIF_INT_ENABLE);
++
++ eventfd_signal(trigger, 1);
++ }
++
++ return IRQ_HANDLED;
++}
++
++#define PFE_INTR_COAL_USECS 100
++static long pfe_cdev_ioctl(struct file *fp, unsigned int cmd,
++ unsigned long arg)
++{
++ int ret = -EFAULT;
++ int __user *argp = (int __user *)arg;
++
++ pr_debug("PFE CDEV IOCTL Called with cmd=(%u)\n", cmd);
++
++ switch (cmd) {
++ case PFE_CDEV_ETH0_STATE_GET:
++ /* Return an unsigned int (link state) for ETH0 */
++ *argp = link_states[0].state;
++ pr_debug("Returning state=%d for ETH0\n", *argp);
++ ret = 0;
++ break;
++ case PFE_CDEV_ETH1_STATE_GET:
++ /* Return an unsigned int (link state) for ETH0 */
++ *argp = link_states[1].state;
++ pr_debug("Returning state=%d for ETH1\n", *argp);
++ ret = 0;
++ break;
++ case PFE_CDEV_HIF_INTR_EN:
++ /* Return success/failure */
++ g_trigger = eventfd_ctx_fdget(*argp);
++ if (IS_ERR(g_trigger))
++ return PTR_ERR(g_trigger);
++ ret = request_irq(pfe->hif_irq, hif_us_isr, 0, "pfe_hif",
++ g_trigger);
++ if (ret) {
++ pr_err("%s: failed to get the hif IRQ = %d\n",
++ __func__, pfe->hif_irq);
++ eventfd_ctx_put(g_trigger);
++ g_trigger = NULL;
++ }
++ writel((PFE_INTR_COAL_USECS * (pfe->ctrl.sys_clk / 1000)) |
++ HIF_INT_COAL_ENABLE, HIF_INT_COAL);
++
++ pr_debug("request_irq for hif interrupt: %d\n", pfe->hif_irq);
++ ret = 0;
++ break;
++ default:
++ pr_info("Unsupport cmd (%d) for PFE CDEV.\n", cmd);
++ break;
++ };
++
++ return ret;
++}
++
++static unsigned int pfe_cdev_poll(struct file *fp,
++ struct poll_table_struct *wait)
++{
++ pr_info("PFE CDEV poll method not supported\n");
++ return 0;
++}
++
++static const struct file_operations pfe_cdev_fops = {
++ .open = pfe_cdev_open,
++ .read = pfe_cdev_read,
++ .write = pfe_cdev_write,
++ .release = pfe_cdev_release,
++ .unlocked_ioctl = pfe_cdev_ioctl,
++ .poll = pfe_cdev_poll,
++};
++
++int pfe_cdev_init(void)
++{
++ int ret;
++
++ pr_debug("PFE CDEV initialization begin\n");
++
++ /* Register the major number for the device */
++ pfe_majno = register_chrdev(0, PFE_CDEV_NAME, &pfe_cdev_fops);
++ if (pfe_majno < 0) {
++ pr_err("Unable to register PFE CDEV. PFE CDEV not available\n");
++ ret = pfe_majno;
++ goto cleanup;
++ }
++
++ pr_debug("PFE CDEV assigned major number: %d\n", pfe_majno);
++
++ /* Register the class for the device */
++ pfe_char_class = class_create(THIS_MODULE, PFE_CLASS_NAME);
++ if (IS_ERR(pfe_char_class)) {
++ pr_err(
++ "Failed to init class for PFE CDEV. PFE CDEV not available.\n");
++ goto cleanup;
++ }
++
++ pr_debug("PFE CDEV Class created successfully.\n");
++
++ /* Create the device without any parent and without any callback data */
++ pfe_char_dev = device_create(pfe_char_class, NULL,
++ MKDEV(pfe_majno, 0), NULL,
++ PFE_CDEV_NAME);
++ if (IS_ERR(pfe_char_dev)) {
++ pr_err("Unable to PFE CDEV device. PFE CDEV not available.\n");
++ ret = PTR_ERR(pfe_char_dev);
++ goto cleanup;
++ }
++
++ /* Information structure being shared with the userspace */
++ memset(link_states, 0, sizeof(struct pfe_shared_info) *
++ PFE_CDEV_ETH_COUNT);
++
++ pr_info("PFE CDEV created: %s\n", PFE_CDEV_NAME);
++
++ ret = 0;
++ return ret;
++
++cleanup:
++ if (!IS_ERR(pfe_char_class))
++ class_destroy(pfe_char_class);
++
++ if (pfe_majno > 0)
++ unregister_chrdev(pfe_majno, PFE_CDEV_NAME);
++
++ ret = -EFAULT;
++ return ret;
++}
++
++void pfe_cdev_exit(void)
++{
++ if (!IS_ERR(pfe_char_dev))
++ device_destroy(pfe_char_class, MKDEV(pfe_majno, 0));
++
++ if (!IS_ERR(pfe_char_class)) {
++ class_unregister(pfe_char_class);
++ class_destroy(pfe_char_class);
++ }
++
++ if (pfe_majno > 0)
++ unregister_chrdev(pfe_majno, PFE_CDEV_NAME);
++
++ /* reset the variables */
++ pfe_majno = 0;
++ pfe_char_class = NULL;
++ pfe_char_dev = NULL;
++
++ pr_info("PFE CDEV Removed.\n");
++}
+--- /dev/null
++++ b/drivers/staging/fsl_ppfe/pfe_cdev.h
+@@ -0,0 +1,41 @@
++/* SPDX-License-Identifier: GPL-2.0+ */
++/*
++ * Copyright 2018 NXP
++ */
++
++#ifndef _PFE_CDEV_H_
++#define _PFE_CDEV_H_
++
++#include <linux/init.h>
++#include <linux/device.h>
++#include <linux/err.h>
++#include <linux/kernel.h>
++#include <linux/fs.h>
++#include <linux/uaccess.h>
++#include <linux/poll.h>
++
++#define PFE_CDEV_NAME "pfe_us_cdev"
++#define PFE_CLASS_NAME "ppfe_us"
++
++/* Extracted from ls1012a_pfe_platform_data, there are 3 interfaces which are
++ * supported by PFE driver. Should be updated if number of eth devices are
++ * changed.
++ */
++#define PFE_CDEV_ETH_COUNT 3
++
++struct pfe_shared_info {
++ uint32_t phy_id; /* Link phy ID */
++ uint8_t state; /* Has either 0 or 1 */
++};
++
++extern struct pfe_shared_info link_states[PFE_CDEV_ETH_COUNT];
++
++/* IOCTL Commands */
++#define PFE_CDEV_ETH0_STATE_GET _IOR('R', 0, int)
++#define PFE_CDEV_ETH1_STATE_GET _IOR('R', 1, int)
++#define PFE_CDEV_HIF_INTR_EN _IOWR('R', 2, int)
++
++int pfe_cdev_init(void);
++void pfe_cdev_exit(void);
++
++#endif /* _PFE_CDEV_H_ */
+--- /dev/null
+++ b/drivers/staging/fsl_ppfe/pfe_ctrl.c
-@@ -0,0 +1,238 @@
+@@ -0,0 +1,226 @@
++// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
@@ -2088,23 +2415,11 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+}
--- /dev/null
+++ b/drivers/staging/fsl_ppfe/pfe_ctrl.h
-@@ -0,0 +1,112 @@
+@@ -0,0 +1,100 @@
++/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _PFE_CTRL_H_
@@ -2203,23 +2518,11 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+#endif /* _PFE_CTRL_H_ */
--- /dev/null
+++ b/drivers/staging/fsl_ppfe/pfe_debugfs.c
-@@ -0,0 +1,111 @@
+@@ -0,0 +1,99 @@
++// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/module.h>
@@ -2317,23 +2620,11 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+}
--- /dev/null
+++ b/drivers/staging/fsl_ppfe/pfe_debugfs.h
-@@ -0,0 +1,25 @@
+@@ -0,0 +1,13 @@
++/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _PFE_DEBUGFS_H_
@@ -2345,23 +2636,11 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+#endif /* _PFE_DEBUGFS_H_ */
--- /dev/null
+++ b/drivers/staging/fsl_ppfe/pfe_eth.c
-@@ -0,0 +1,2521 @@
+@@ -0,0 +1,2554 @@
++// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* @pfe_eth.c.
@@ -2387,6 +2666,9 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+#include <net/ip.h>
+#include <net/sock.h>
+
++#include <linux/of.h>
++#include <linux/of_mdio.h>
++
+#include <linux/io.h>
+#include <asm/irq.h>
+#include <linux/delay.h>
@@ -2400,9 +2682,11 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+
+#include "pfe_mod.h"
+#include "pfe_eth.h"
++#include "pfe_cdev.h"
+
+#define LS1012A_REV_1_0 0x87040010
+
++bool pfe_use_old_dts_phy;
+bool pfe_errata_a010897;
+
+static void *cbus_emac_base[3];
@@ -2414,6 +2698,36 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+static void pfe_eth_flush_txQ(struct pfe_eth_priv_s *priv, int tx_q_num, int
+ from_tx, int n_desc);
+
++/* MDIO registers */
++#define MDIO_SGMII_CR 0x00
++#define MDIO_SGMII_SR 0x01
++#define MDIO_SGMII_DEV_ABIL_SGMII 0x04
++#define MDIO_SGMII_LINK_TMR_L 0x12
++#define MDIO_SGMII_LINK_TMR_H 0x13
++#define MDIO_SGMII_IF_MODE 0x14
++
++/* SGMII Control defines */
++#define SGMII_CR_RST 0x8000
++#define SGMII_CR_AN_EN 0x1000
++#define SGMII_CR_RESTART_AN 0x0200
++#define SGMII_CR_FD 0x0100
++#define SGMII_CR_SPEED_SEL1_1G 0x0040
++#define SGMII_CR_DEF_VAL (SGMII_CR_AN_EN | SGMII_CR_FD | \
++ SGMII_CR_SPEED_SEL1_1G)
++
++/* SGMII IF Mode */
++#define SGMII_DUPLEX_HALF 0x10
++#define SGMII_SPEED_10MBPS 0x00
++#define SGMII_SPEED_100MBPS 0x04
++#define SGMII_SPEED_1GBPS 0x08
++#define SGMII_USE_SGMII_AN 0x02
++#define SGMII_EN 0x01
++
++/* SGMII Device Ability for SGMII */
++#define SGMII_DEV_ABIL_ACK 0x4000
++#define SGMII_DEV_ABIL_EEE_CLK_STP_EN 0x0100
++#define SGMII_DEV_ABIL_SGMII 0x0001
++
+unsigned int gemac_regs[] = {
+ 0x0004, /* Interrupt event */
+ 0x0008, /* Interrupt mask */
@@ -3115,10 +3429,9 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ */
+int pfe_eth_mdio_reset(struct mii_bus *bus)
+{
-+ struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv;
++ struct pfe_mdio_priv_s *priv = (struct pfe_mdio_priv_s *)bus->priv;
+ u32 phy_speed;
+
-+ netif_info(priv, hw, priv->ndev, "%s\n", __func__);
+
+ mutex_lock(&bus->mdio_lock);
+
@@ -3131,25 +3444,25 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ phy_speed = (DIV_ROUND_UP((pfe->ctrl.sys_clk * 1000), 4000000)
+ << EMAC_MII_SPEED_SHIFT);
+ phy_speed |= EMAC_HOLDTIME(0x5);
-+ __raw_writel(phy_speed, priv->PHY_baseaddr + EMAC_MII_CTRL_REG);
++ __raw_writel(phy_speed, priv->mdio_base + EMAC_MII_CTRL_REG);
+
+ mutex_unlock(&bus->mdio_lock);
+
+ return 0;
+}
+
-+/* pfe_eth_gemac_phy_timeout
++/* pfe_eth_mdio_timeout
+ *
+ */
-+static int pfe_eth_gemac_phy_timeout(struct pfe_eth_priv_s *priv, int timeout)
++static int pfe_eth_mdio_timeout(struct pfe_mdio_priv_s *priv, int timeout)
+{
-+ while (!(__raw_readl(priv->PHY_baseaddr + EMAC_IEVENT_REG) &
++ while (!(__raw_readl(priv->mdio_base + EMAC_IEVENT_REG) &
+ EMAC_IEVENT_MII)) {
+ if (timeout-- <= 0)
+ return -1;
+ usleep_range(10, 20);
+ }
-+ __raw_writel(EMAC_IEVENT_MII, priv->PHY_baseaddr + EMAC_IEVENT_REG);
++ __raw_writel(EMAC_IEVENT_MII, priv->mdio_base + EMAC_IEVENT_REG);
+ return 0;
+}
+
@@ -3181,16 +3494,15 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+static int pfe_eth_mdio_write_addr(struct mii_bus *bus, int mii_id,
+ int dev_addr, int regnum)
+{
-+ struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv;
++ struct pfe_mdio_priv_s *priv = (struct pfe_mdio_priv_s *)bus->priv;
+
+ __raw_writel(EMAC_MII_DATA_PA(mii_id) |
+ EMAC_MII_DATA_RA(dev_addr) |
+ EMAC_MII_DATA_TA | EMAC_MII_DATA(regnum),
-+ priv->PHY_baseaddr + EMAC_MII_DATA_REG);
++ priv->mdio_base + EMAC_MII_DATA_REG);
+
-+ if (pfe_eth_gemac_phy_timeout(priv, EMAC_MDIO_TIMEOUT)) {
-+ netdev_err(priv->ndev, "%s: phy MDIO address write timeout\n",
-+ __func__);
++ if (pfe_eth_mdio_timeout(priv, EMAC_MDIO_TIMEOUT)) {
++ dev_err(&bus->dev, "phy MDIO address write timeout\n");
+ return -1;
+ }
+
@@ -3200,7 +3512,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+static int pfe_eth_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
+ u16 value)
+{
-+ struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv;
++ struct pfe_mdio_priv_s *priv = (struct pfe_mdio_priv_s *)bus->priv;
+
+ /*To access external PHYs on QDS board mux needs to be configured*/
+ if ((mii_id) && (pfe->mdio_muxval[mii_id]))
@@ -3213,30 +3525,26 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ EMAC_MII_DATA_PA(mii_id) |
+ EMAC_MII_DATA_RA((regnum >> 16) & 0x1f) |
+ EMAC_MII_DATA_TA | EMAC_MII_DATA(value),
-+ priv->PHY_baseaddr + EMAC_MII_DATA_REG);
++ priv->mdio_base + EMAC_MII_DATA_REG);
+ } else {
+ /* start a write op */
+ __raw_writel(EMAC_MII_DATA_ST | EMAC_MII_DATA_OP_WR |
+ EMAC_MII_DATA_PA(mii_id) |
+ EMAC_MII_DATA_RA(regnum) |
+ EMAC_MII_DATA_TA | EMAC_MII_DATA(value),
-+ priv->PHY_baseaddr + EMAC_MII_DATA_REG);
++ priv->mdio_base + EMAC_MII_DATA_REG);
+ }
+
-+ if (pfe_eth_gemac_phy_timeout(priv, EMAC_MDIO_TIMEOUT)) {
-+ netdev_err(priv->ndev, "%s: phy MDIO write timeout\n",
-+ __func__);
++ if (pfe_eth_mdio_timeout(priv, EMAC_MDIO_TIMEOUT)) {
++ dev_err(&bus->dev, "%s: phy MDIO write timeout\n", __func__);
+ return -1;
+ }
-+ netif_info(priv, hw, priv->ndev, "%s: phy %x reg %x val %x\n", __func__,
-+ mii_id, regnum, value);
-+
+ return 0;
+}
+
+static int pfe_eth_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
+{
-+ struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv;
++ struct pfe_mdio_priv_s *priv = (struct pfe_mdio_priv_s *)bus->priv;
+ u16 value = 0;
+
+ /*To access external PHYs on QDS board mux needs to be configured*/
@@ -3250,117 +3558,102 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ EMAC_MII_DATA_PA(mii_id) |
+ EMAC_MII_DATA_RA((regnum >> 16) & 0x1f) |
+ EMAC_MII_DATA_TA,
-+ priv->PHY_baseaddr + EMAC_MII_DATA_REG);
++ priv->mdio_base + EMAC_MII_DATA_REG);
+ } else {
+ /* start a read op */
+ __raw_writel(EMAC_MII_DATA_ST | EMAC_MII_DATA_OP_RD |
+ EMAC_MII_DATA_PA(mii_id) |
+ EMAC_MII_DATA_RA(regnum) |
-+ EMAC_MII_DATA_TA, priv->PHY_baseaddr +
++ EMAC_MII_DATA_TA, priv->mdio_base +
+ EMAC_MII_DATA_REG);
+ }
+
-+ if (pfe_eth_gemac_phy_timeout(priv, EMAC_MDIO_TIMEOUT)) {
-+ netdev_err(priv->ndev, "%s: phy MDIO read timeout\n", __func__);
++ if (pfe_eth_mdio_timeout(priv, EMAC_MDIO_TIMEOUT)) {
++ dev_err(&bus->dev, "%s: phy MDIO read timeout\n", __func__);
+ return -1;
+ }
+
-+ value = EMAC_MII_DATA(__raw_readl(priv->PHY_baseaddr +
++ value = EMAC_MII_DATA(__raw_readl(priv->mdio_base +
+ EMAC_MII_DATA_REG));
-+ netif_info(priv, hw, priv->ndev, "%s: phy %x reg %x val %x\n", __func__,
-+ mii_id, regnum, value);
+ return value;
+}
+
-+static int pfe_eth_mdio_init(struct pfe_eth_priv_s *priv,
-+ struct ls1012a_mdio_platform_data *minfo)
++static int pfe_eth_mdio_init(struct pfe *pfe,
++ struct ls1012a_pfe_platform_data *pfe_info,
++ int ii)
+{
++ struct pfe_mdio_priv_s *priv = NULL;
++ struct ls1012a_mdio_platform_data *mdio_info;
+ struct mii_bus *bus;
-+ int rc, ii;
-+ struct phy_device *phydev;
++ struct device_node *mdio_node;
++ int rc = 0;
+
-+ netif_info(priv, drv, priv->ndev, "%s\n", __func__);
-+ pr_info("%s\n", __func__);
++ mdio_info = (struct ls1012a_mdio_platform_data *)
++ pfe_info->ls1012a_mdio_pdata;
++ mdio_info->id = ii;
+
-+ bus = mdiobus_alloc();
++ bus = mdiobus_alloc_size(sizeof(struct pfe_mdio_priv_s));
+ if (!bus) {
-+ netdev_err(priv->ndev, "mdiobus_alloc() failed\n");
++ pr_err("mdiobus_alloc() failed\n");
+ rc = -ENOMEM;
-+ goto err0;
++ goto err_mdioalloc;
+ }
+
+ bus->name = "ls1012a MDIO Bus";
++ snprintf(bus->id, MII_BUS_ID_SIZE, "ls1012a-%x", mdio_info->id);
++
+ bus->read = &pfe_eth_mdio_read;
+ bus->write = &pfe_eth_mdio_write;
+ bus->reset = &pfe_eth_mdio_reset;
-+ snprintf(bus->id, MII_BUS_ID_SIZE, "ls1012a-%x", priv->id);
-+ bus->priv = priv;
-+
-+ bus->phy_mask = minfo->phy_mask;
-+ priv->mdc_div = minfo->mdc_div;
++ bus->parent = pfe->dev;
++ bus->phy_mask = mdio_info->phy_mask;
++ bus->irq[0] = mdio_info->irq[0];
++ priv = bus->priv;
++ priv->mdio_base = cbus_emac_base[ii];
+
++ priv->mdc_div = mdio_info->mdc_div;
+ if (!priv->mdc_div)
+ priv->mdc_div = 64;
++ dev_info(bus->parent, "%s: mdc_div: %d, phy_mask: %x\n",
++ __func__, priv->mdc_div, bus->phy_mask);
+
-+ bus->irq[0] = minfo->irq[0];
-+
-+ bus->parent = priv->pfe->dev;
++ mdio_node = of_get_child_by_name(pfe->dev->of_node, "mdio");
++ if ((mdio_info->id == 0) && mdio_node) {
++ rc = of_mdiobus_register(bus, mdio_node);
++ of_node_put(mdio_node);
++ } else {
++ rc = mdiobus_register(bus);
++ }
+
-+ netif_info(priv, drv, priv->ndev, "%s: mdc_div: %d, phy_mask: %x\n",
-+ __func__, priv->mdc_div, bus->phy_mask);
-+ rc = mdiobus_register(bus);
+ if (rc) {
-+ netdev_err(priv->ndev, "mdiobus_register(%s) failed\n",
-+ bus->name);
-+ goto err1;
++ dev_err(bus->parent, "mdiobus_register(%s) failed\n",
++ bus->name);
++ goto err_mdioregister;
+ }
+
+ priv->mii_bus = bus;
-+
-+ /* For clause 45 we need to call get_phy_device() with it's
-+ * 3rd argument as true and then register the phy device
-+ * via phy_device_register()
-+ */
-+
-+ if (priv->einfo->mii_config == PHY_INTERFACE_MODE_2500SGMII) {
-+ for (ii = 0; ii < NUM_GEMAC_SUPPORT; ii++) {
-+ phydev = get_phy_device(priv->mii_bus,
-+ priv->einfo->phy_id + ii, true);
-+ if (!phydev || IS_ERR(phydev)) {
-+ rc = -EIO;
-+ netdev_err(priv->ndev, "fail to get device\n");
-+ goto err1;
-+ }
-+ rc = phy_device_register(phydev);
-+ if (rc) {
-+ phy_device_free(phydev);
-+ netdev_err(priv->ndev,
-+ "phy_device_register() failed\n");
-+ goto err1;
-+ }
-+ }
-+ }
++ pfe->mdio.mdio_priv[ii] = priv;
+
+ pfe_eth_mdio_reset(bus);
+
+ return 0;
+
-+err1:
++err_mdioregister:
+ mdiobus_free(bus);
-+err0:
++err_mdioalloc:
+ return rc;
+}
+
+/* pfe_eth_mdio_exit
+ */
-+static void pfe_eth_mdio_exit(struct mii_bus *bus)
++static void pfe_eth_mdio_exit(struct pfe *pfe,
++ int ii)
+{
++ struct pfe_mdio_priv_s *mdio_priv = pfe->mdio.mdio_priv[ii];
++ struct mii_bus *bus = mdio_priv->mii_bus;
++
+ if (!bus)
+ return;
-+
-+ netif_info((struct pfe_eth_priv_s *)bus->priv, drv, ((struct
-+ pfe_eth_priv_s *)(bus->priv))->ndev, "%s\n", __func__);
-+
+ mdiobus_unregister(bus);
+ mdiobus_free(bus);
+}
@@ -3390,6 +3683,10 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+#define SCFG_RGMIIPCR_SETSP_10M (0x00000002)
+#define SCFG_RGMIIPCR_SETFD (0x00000001)
+
++#define MDIOSELCR 0x484
++#define MDIOSEL_SERDES 0x0
++#define MDIOSEL_EXTPHY 0x80000000
++
+static void pfe_set_rgmii_speed(struct phy_device *phydev)
+{
+ u32 rgmii_pcr;
@@ -3471,6 +3768,19 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ phy_print_status(phydev);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
++
++ /* Now, dump the details to the cdev.
++ * XXX: Locking would be required? (uniprocess arch)
++ * Or, maybe move it in spinlock above
++ */
++ if (us && priv->einfo->gem_id < PFE_CDEV_ETH_COUNT) {
++ pr_debug("Changing link state from (%u) to (%u) for ID=(%u)\n",
++ link_states[priv->einfo->gem_id].state,
++ phydev->link,
++ priv->einfo->gem_id);
++ link_states[priv->einfo->gem_id].phy_id = priv->einfo->gem_id;
++ link_states[priv->einfo->gem_id].state = phydev->link;
++ }
+}
+
+/* pfe_phy_exit
@@ -3524,36 +3834,46 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ */
+static void ls1012a_configure_serdes(struct net_device *ndev)
+{
-+ struct pfe_eth_priv_s *priv = pfe->eth.eth_priv[0];
++ struct pfe_eth_priv_s *eth_priv = netdev_priv(ndev);
++ struct pfe_mdio_priv_s *mdio_priv = pfe->mdio.mdio_priv[eth_priv->id];
+ int sgmii_2500 = 0;
-+ struct mii_bus *bus = priv->mii_bus;
++ struct mii_bus *bus = mdio_priv->mii_bus;
+ u16 value = 0;
+
-+ if (priv->einfo->mii_config == PHY_INTERFACE_MODE_2500SGMII)
++ if (eth_priv->einfo->mii_config == PHY_INTERFACE_MODE_2500SGMII)
+ sgmii_2500 = 1;
+
-+ netif_info(priv, drv, ndev, "%s\n", __func__);
++ netif_info(eth_priv, drv, ndev, "%s\n", __func__);
+ /* PCS configuration done with corresponding GEMAC */
+
-+ pfe_eth_mdio_read(bus, 0, 0);
-+ pfe_eth_mdio_read(bus, 0, 1);
++ pfe_eth_mdio_read(bus, 0, MDIO_SGMII_CR);
++ pfe_eth_mdio_read(bus, 0, MDIO_SGMII_SR);
++
++ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_CR, SGMII_CR_RST);
+
-+ /*These settings taken from validtion team */
-+ pfe_eth_mdio_write(bus, 0, 0x0, 0x8000);
+ if (sgmii_2500) {
-+ pfe_eth_mdio_write(bus, 0, 0x14, 0x9);
-+ pfe_eth_mdio_write(bus, 0, 0x4, 0x4001);
-+ pfe_eth_mdio_write(bus, 0, 0x12, 0xa120);
-+ pfe_eth_mdio_write(bus, 0, 0x13, 0x7);
++ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_IF_MODE, SGMII_SPEED_1GBPS
++ | SGMII_EN);
++ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_DEV_ABIL_SGMII,
++ SGMII_DEV_ABIL_ACK | SGMII_DEV_ABIL_SGMII);
++ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_LINK_TMR_L, 0xa120);
++ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_LINK_TMR_H, 0x7);
+ /* Autonegotiation need to be disabled for 2.5G SGMII mode*/
-+ value = 0x0140;
-+ pfe_eth_mdio_write(bus, 0, 0x0, value);
++ value = SGMII_CR_FD | SGMII_CR_SPEED_SEL1_1G;
++ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_CR, value);
+ } else {
-+ pfe_eth_mdio_write(bus, 0, 0x14, 0xb);
-+ pfe_eth_mdio_write(bus, 0, 0x4, 0x1a1);
-+ pfe_eth_mdio_write(bus, 0, 0x12, 0x400);
-+ pfe_eth_mdio_write(bus, 0, 0x13, 0x0);
-+ pfe_eth_mdio_write(bus, 0, 0x0, 0x1140);
++ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_IF_MODE,
++ SGMII_SPEED_1GBPS
++ | SGMII_USE_SGMII_AN
++ | SGMII_EN);
++ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_DEV_ABIL_SGMII,
++ SGMII_DEV_ABIL_EEE_CLK_STP_EN
++ | 0xa0
++ | SGMII_DEV_ABIL_SGMII);
++ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_LINK_TMR_L, 0x400);
++ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_LINK_TMR_H, 0x0);
++ value = SGMII_CR_AN_EN | SGMII_CR_FD | SGMII_CR_SPEED_SEL1_1G;
++ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_CR, value);
+ }
+}
+
@@ -3576,33 +3896,44 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ snprintf(bus_id, MII_BUS_ID_SIZE, "ls1012a-%d", 0);
+ snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
+ priv->einfo->phy_id);
-+
+ netif_info(priv, drv, ndev, "%s: %s\n", __func__, phy_id);
+ interface = priv->einfo->mii_config;
+ if ((interface == PHY_INTERFACE_MODE_SGMII) ||
+ (interface == PHY_INTERFACE_MODE_2500SGMII)) {
+ /*Configure SGMII PCS */
+ if (pfe->scfg) {
-+ /*Config MDIO from serdes */
-+ regmap_write(pfe->scfg, 0x484, 0x00000000);
++ /* Config MDIO from serdes */
++ regmap_write(pfe->scfg, MDIOSELCR, MDIOSEL_SERDES);
+ }
+ ls1012a_configure_serdes(ndev);
+ }
+
+ if (pfe->scfg) {
+ /*Config MDIO from PAD */
-+ regmap_write(pfe->scfg, 0x484, 0x80000000);
++ regmap_write(pfe->scfg, MDIOSELCR, MDIOSEL_EXTPHY);
+ }
+
+ priv->oldlink = 0;
+ priv->oldspeed = 0;
+ priv->oldduplex = -1;
+ pr_info("%s interface %x\n", __func__, interface);
-+ phydev = phy_connect(ndev, phy_id, &pfe_eth_adjust_link, interface);
+
-+ if (IS_ERR(phydev)) {
-+ netdev_err(ndev, "phy_connect() failed\n");
-+ return PTR_ERR(phydev);
++ if (priv->phy_node) {
++ phydev = of_phy_connect(ndev, priv->phy_node,
++ pfe_eth_adjust_link, 0,
++ priv->einfo->mii_config);
++ if (!(phydev)) {
++ netdev_err(ndev, "Unable to connect to phy\n");
++ return -ENODEV;
++ }
++
++ } else {
++ phydev = phy_connect(ndev, phy_id,
++ &pfe_eth_adjust_link, interface);
++ if (IS_ERR(phydev)) {
++ netdev_err(ndev, "Unable to connect to phy\n");
++ return PTR_ERR(phydev);
++ }
+ }
+
+ priv->phydev = phydev;
@@ -4616,26 +4947,15 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+
+/* pfe_eth_init_one
+ */
-+static int pfe_eth_init_one(struct pfe *pfe, int id)
++static int pfe_eth_init_one(struct pfe *pfe,
++ struct ls1012a_pfe_platform_data *pfe_info,
++ int id)
+{
+ struct net_device *ndev = NULL;
+ struct pfe_eth_priv_s *priv = NULL;
+ struct ls1012a_eth_platform_data *einfo;
-+ struct ls1012a_mdio_platform_data *minfo;
-+ struct ls1012a_pfe_platform_data *pfe_info;
+ int err;
+
-+ /* Extract pltform data */
-+ pfe_info = (struct ls1012a_pfe_platform_data *)
-+ pfe->dev->platform_data;
-+ if (!pfe_info) {
-+ pr_err(
-+ "%s: pfe missing additional platform data\n"
-+ , __func__);
-+ err = -ENODEV;
-+ goto err0;
-+ }
-+
+ einfo = (struct ls1012a_eth_platform_data *)
+ pfe_info->ls1012a_eth_pdata;
+
@@ -4648,18 +4968,6 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ goto err0;
+ }
+
-+ minfo = (struct ls1012a_mdio_platform_data *)
-+ pfe_info->ls1012a_mdio_pdata;
-+
-+ /* einfo never be NULL, but no harm in having this check */
-+ if (!minfo) {
-+ pr_err(
-+ "%s: pfe missing additional mdios platform data\n",
-+ __func__);
-+ err = -ENODEV;
-+ goto err0;
-+ }
-+
+ if (us)
+ emac_txq_cnt = EMAC_TXQ_CNT;
+ /* Create an ethernet device instance */
@@ -4676,6 +4984,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ priv->ndev = ndev;
+ priv->id = einfo[id].gem_id;
+ priv->pfe = pfe;
++ priv->phy_node = einfo[id].phy_node;
+
+ SET_NETDEV_DEV(priv->ndev, priv->pfe->dev);
+
@@ -4684,13 +4993,8 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ /* Set the info in the priv to the current info */
+ priv->einfo = &einfo[id];
+ priv->EMAC_baseaddr = cbus_emac_base[id];
-+ priv->PHY_baseaddr = cbus_emac_base[0];
+ priv->GPI_baseaddr = cbus_gpi_base[id];
+
-+#define HIF_GEMAC_TMUQ_BASE 6
-+ priv->low_tmu_q = HIF_GEMAC_TMUQ_BASE + (id * 2);
-+ priv->high_tmu_q = priv->low_tmu_q + 1;
-+
+ spin_lock_init(&priv->lock);
+
+ pfe_eth_fast_tx_timeout_init(priv);
@@ -4698,16 +5002,6 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ /* Copy the station address into the dev structure, */
+ memcpy(ndev->dev_addr, einfo[id].mac_addr, ETH_ALEN);
+
-+ /* Initialize mdio */
-+ if (minfo[id].enabled) {
-+ err = pfe_eth_mdio_init(priv, &minfo[id]);
-+ if (err) {
-+ netdev_err(ndev, "%s: pfe_eth_mdio_init() failed\n",
-+ __func__);
-+ goto err2;
-+ }
-+ }
-+
+ if (us)
+ goto phy_init;
+
@@ -4725,9 +5019,6 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ else
+ ndev->max_mtu = JUMBO_FRAME_SIZE_V2 - ETH_HLEN - ETH_FCS_LEN;
+
-+ /* supported features */
-+ ndev->hw_features = NETIF_F_SG;
-+
+ /*Enable after checksum offload is validated */
+ ndev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM |
+ NETIF_F_IPV6_CSUM | NETIF_F_SG;
@@ -4753,22 +5044,26 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ HIF_RX_POLL_WEIGHT - 16);
+
+ err = register_netdev(ndev);
-+
+ if (err) {
+ netdev_err(ndev, "register_netdev() failed\n");
-+ goto err3;
++ goto err1;
++ }
++
++ if ((!(pfe_use_old_dts_phy) && !(priv->phy_node)) ||
++ ((pfe_use_old_dts_phy) &&
++ (priv->einfo->phy_flags & GEMAC_NO_PHY))) {
++ pr_info("%s: No PHY or fixed-link\n", __func__);
++ goto skip_phy_init;
+ }
+
+phy_init:
+ device_init_wakeup(&ndev->dev, WAKE_MAGIC);
+
-+ if (!(priv->einfo->phy_flags & GEMAC_NO_PHY)) {
-+ err = pfe_phy_init(ndev);
-+ if (err) {
-+ netdev_err(ndev, "%s: pfe_phy_init() failed\n",
-+ __func__);
-+ goto err4;
-+ }
++ err = pfe_phy_init(ndev);
++ if (err) {
++ netdev_err(ndev, "%s: pfe_phy_init() failed\n",
++ __func__);
++ goto err2;
+ }
+
+ if (us) {
@@ -4779,21 +5074,23 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+
+ netif_carrier_on(ndev);
+
++skip_phy_init:
+ /* Create all the sysfs files */
+ if (pfe_eth_sysfs_init(ndev))
-+ goto err4;
++ goto err3;
+
+ netif_info(priv, probe, ndev, "%s: created interface, baseaddr: %p\n",
+ __func__, priv->EMAC_baseaddr);
+
+ return 0;
-+err4:
-+ if (us)
-+ goto err3;
-+ unregister_netdev(ndev);
++
+err3:
-+ pfe_eth_mdio_exit(priv->mii_bus);
++ pfe_phy_exit(priv->ndev);
+err2:
++ if (us)
++ goto err1;
++ unregister_netdev(ndev);
++err1:
+ free_netdev(priv->ndev);
+err0:
+ return err;
@@ -4805,6 +5102,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+{
+ int ii = 0;
+ int err;
++ struct ls1012a_pfe_platform_data *pfe_info;
+
+ pr_info("%s\n", __func__);
+
@@ -4814,24 +5112,43 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ cbus_gpi_base[0] = EGPI1_BASE_ADDR;
+ cbus_gpi_base[1] = EGPI2_BASE_ADDR;
+
++ pfe_info = (struct ls1012a_pfe_platform_data *)
++ pfe->dev->platform_data;
++ if (!pfe_info) {
++ pr_err("%s: pfe missing additional platform data\n", __func__);
++ err = -ENODEV;
++ goto err_pdata;
++ }
++
++ for (ii = 0; ii < NUM_GEMAC_SUPPORT; ii++) {
++ err = pfe_eth_mdio_init(pfe, pfe_info, ii);
++ if (err) {
++ pr_err("%s: pfe_eth_mdio_init() failed\n", __func__);
++ goto err_mdio_init;
++ }
++ }
++
+ if (fsl_guts_get_svr() == LS1012A_REV_1_0)
+ pfe_errata_a010897 = true;
+ else
+ pfe_errata_a010897 = false;
+
+ for (ii = 0; ii < NUM_GEMAC_SUPPORT; ii++) {
-+ err = pfe_eth_init_one(pfe, ii);
++ err = pfe_eth_init_one(pfe, pfe_info, ii);
+ if (err)
-+ goto err0;
++ goto err_eth_init;
+ }
+
+ return 0;
+
-+err0:
-+ while (ii--)
++err_eth_init:
++ while (ii--) {
+ pfe_eth_exit_one(pfe->eth.eth_priv[ii]);
++ pfe_eth_mdio_exit(pfe, ii);
++ }
+
-+ /* Register three network devices in the kernel */
++err_mdio_init:
++err_pdata:
+ return err;
+}
+
@@ -4844,15 +5161,19 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ if (!us)
+ pfe_eth_sysfs_exit(priv->ndev);
+
-+ if (!(priv->einfo->phy_flags & GEMAC_NO_PHY))
-+ pfe_phy_exit(priv->ndev);
++ if ((!(pfe_use_old_dts_phy) && !(priv->phy_node)) ||
++ ((pfe_use_old_dts_phy) &&
++ (priv->einfo->phy_flags & GEMAC_NO_PHY))) {
++ pr_info("%s: No PHY or fixed-link\n", __func__);
++ goto skip_phy_exit;
++ }
++
++ pfe_phy_exit(priv->ndev);
+
++skip_phy_exit:
+ if (!us)
+ unregister_netdev(priv->ndev);
+
-+ if (priv->mii_bus)
-+ pfe_eth_mdio_exit(priv->mii_bus);
-+
+ free_netdev(priv->ndev);
+}
+
@@ -4866,26 +5187,17 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+
+ for (ii = NUM_GEMAC_SUPPORT - 1; ii >= 0; ii--)
+ pfe_eth_exit_one(pfe->eth.eth_priv[ii]);
++
++ for (ii = NUM_GEMAC_SUPPORT - 1; ii >= 0; ii--)
++ pfe_eth_mdio_exit(pfe, ii);
+}
--- /dev/null
+++ b/drivers/staging/fsl_ppfe/pfe_eth.h
-@@ -0,0 +1,185 @@
+@@ -0,0 +1,175 @@
++/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _PFE_ETH_H_
@@ -4921,22 +5233,18 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+#define GEMAC_NO_PHY BIT(0)
+
+struct ls1012a_eth_platform_data {
-+ /* device specific information */
-+ u32 device_flags;
-+ char name[16];
-+
+ /* board specific information */
+ u32 mii_config;
+ u32 phy_flags;
+ u32 gem_id;
-+ u32 bus_id;
+ u32 phy_id;
+ u32 mdio_muxval;
+ u8 mac_addr[ETH_ALEN];
++ struct device_node *phy_node;
+};
+
+struct ls1012a_mdio_platform_data {
-+ int enabled;
++ int id;
+ int irq[32];
+ u32 phy_mask;
+ int mdc_div;
@@ -5008,17 +5316,13 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ unsigned int event_status;
+ int irq;
+ void *EMAC_baseaddr;
-+ /* This points to the EMAC base from where we access PHY */
-+ void *PHY_baseaddr;
+ void *GPI_baseaddr;
+ /* PHY stuff */
+ struct phy_device *phydev;
+ int oldspeed;
+ int oldduplex;
+ int oldlink;
-+ /* mdio info */
-+ int mdc_div;
-+ struct mii_bus *mii_bus;
++ struct device_node *phy_node;
+ struct clk *gemtx_clk;
+ int wol;
+ int pause_flag;
@@ -5048,6 +5352,16 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ struct pfe_eth_priv_s *eth_priv[3];
+};
+
++struct pfe_mdio_priv_s {
++ void __iomem *mdio_base;
++ int mdc_div;
++ struct mii_bus *mii_bus;
++};
++
++struct pfe_mdio {
++ struct pfe_mdio_priv_s *mdio_priv[3];
++};
++
+int pfe_eth_init(struct pfe *pfe);
+void pfe_eth_exit(struct pfe *pfe);
+int pfe_eth_suspend(struct net_device *dev);
@@ -5057,23 +5371,11 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+#endif /* _PFE_ETH_H_ */
--- /dev/null
+++ b/drivers/staging/fsl_ppfe/pfe_firmware.c
-@@ -0,0 +1,314 @@
+@@ -0,0 +1,302 @@
++// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
@@ -5374,23 +5676,11 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+}
--- /dev/null
+++ b/drivers/staging/fsl_ppfe/pfe_firmware.h
-@@ -0,0 +1,32 @@
+@@ -0,0 +1,20 @@
++/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _PFE_FIRMWARE_H_
@@ -5409,23 +5699,11 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+#endif /* _PFE_FIRMWARE_H_ */
--- /dev/null
+++ b/drivers/staging/fsl_ppfe/pfe_hal.c
-@@ -0,0 +1,1528 @@
+@@ -0,0 +1,1516 @@
++// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "pfe_mod.h"
@@ -6940,23 +7218,11 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+}
--- /dev/null
+++ b/drivers/staging/fsl_ppfe/pfe_hif.c
-@@ -0,0 +1,1072 @@
+@@ -0,0 +1,1060 @@
++// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
@@ -8015,23 +8281,11 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+}
--- /dev/null
+++ b/drivers/staging/fsl_ppfe/pfe_hif.h
-@@ -0,0 +1,212 @@
+@@ -0,0 +1,200 @@
++/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _PFE_HIF_H_
@@ -8230,23 +8484,11 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+#endif /* _PFE_HIF_H_ */
--- /dev/null
+++ b/drivers/staging/fsl_ppfe/pfe_hif_lib.c
-@@ -0,0 +1,640 @@
+@@ -0,0 +1,628 @@
++// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/version.h>
@@ -8873,23 +9115,11 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+}
--- /dev/null
+++ b/drivers/staging/fsl_ppfe/pfe_hif_lib.h
-@@ -0,0 +1,241 @@
+@@ -0,0 +1,229 @@
++/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _PFE_HIF_LIB_H_
@@ -9117,23 +9347,11 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+#endif /* _PFE_HIF_LIB_H_ */
--- /dev/null
+++ b/drivers/staging/fsl_ppfe/pfe_hw.c
-@@ -0,0 +1,176 @@
+@@ -0,0 +1,164 @@
++// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "pfe_mod.h"
@@ -9296,23 +9514,11 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+}
--- /dev/null
+++ b/drivers/staging/fsl_ppfe/pfe_hw.h
-@@ -0,0 +1,27 @@
+@@ -0,0 +1,15 @@
++/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _PFE_HW_H_
@@ -9326,29 +9532,19 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+#endif /* _PFE_HW_H_ */
--- /dev/null
+++ b/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c
-@@ -0,0 +1,385 @@
+@@ -0,0 +1,368 @@
++// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
++#include <linux/of.h>
+#include <linux/of_net.h>
+#include <linux/of_address.h>
++#include <linux/of_mdio.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/clk.h>
@@ -9357,102 +9553,90 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+
+#include "pfe_mod.h"
+
++extern bool pfe_use_old_dts_phy;
+struct ls1012a_pfe_platform_data pfe_platform_data;
+
-+static int pfe_get_gemac_if_proprties(struct device_node *parent, int port, int
-+ if_cnt,
-+ struct ls1012a_pfe_platform_data
-+ *pdata)
++static int pfe_get_gemac_if_properties(struct device_node *gem,
++ int port,
++ struct ls1012a_pfe_platform_data *pdata)
+{
-+ struct device_node *gem = NULL, *phy = NULL;
++ struct device_node *phy_node = NULL;
+ int size;
-+ int ii = 0, phy_id = 0;
++ int phy_id = 0;
+ const u32 *addr;
+ const void *mac_addr;
+
-+ for (ii = 0; ii < if_cnt; ii++) {
-+ gem = of_get_next_child(parent, gem);
-+ if (!gem)
-+ goto err;
-+ addr = of_get_property(gem, "reg", &size);
-+ if (addr && (be32_to_cpup(addr) == port))
-+ break;
-+ }
-+
-+ if (ii >= if_cnt) {
-+ pr_err("%s:%d Failed to find interface = %d\n",
-+ __func__, __LINE__, if_cnt);
-+ goto err;
-+ }
++ addr = of_get_property(gem, "reg", &size);
++ port = be32_to_cpup(addr);
+
+ pdata->ls1012a_eth_pdata[port].gem_id = port;
+
+ mac_addr = of_get_mac_address(gem);
-+
+ if (mac_addr) {
+ memcpy(pdata->ls1012a_eth_pdata[port].mac_addr, mac_addr,
+ ETH_ALEN);
+ }
+
-+ pdata->ls1012a_eth_pdata[port].mii_config = of_get_phy_mode(gem);
++ phy_node = of_parse_phandle(gem, "phy-handle", 0);
++ pdata->ls1012a_eth_pdata[port].phy_node = phy_node;
++ if (phy_node) {
++ pfe_use_old_dts_phy = false;
++ goto process_phynode;
++ } else if (of_phy_is_fixed_link(gem)) {
++ pfe_use_old_dts_phy = false;
++ if (of_phy_register_fixed_link(gem) < 0) {
++ pr_err("broken fixed-link specification\n");
++ goto err;
++ }
++ phy_node = of_node_get(gem);
++ pdata->ls1012a_eth_pdata[port].phy_node = phy_node;
++ } else if (of_get_property(gem, "fsl,pfe-phy-if-flags", &size)) {
++ pfe_use_old_dts_phy = true;
++ /* Use old dts properties for phy handling */
++ addr = of_get_property(gem, "fsl,pfe-phy-if-flags", &size);
++ pdata->ls1012a_eth_pdata[port].phy_flags = be32_to_cpup(addr);
+
-+ if ((pdata->ls1012a_eth_pdata[port].mii_config) < 0)
-+ pr_err("%s:%d Incorrect Phy mode....\n", __func__,
-+ __LINE__);
++ addr = of_get_property(gem, "fsl,gemac-phy-id", &size);
++ if (!addr) {
++ pr_err("%s:%d Invalid gemac-phy-id....\n", __func__,
++ __LINE__);
++ } else {
++ phy_id = be32_to_cpup(addr);
++ pdata->ls1012a_eth_pdata[port].phy_id = phy_id;
++ pdata->ls1012a_mdio_pdata[0].phy_mask &= ~(1 << phy_id);
++ }
+
-+ addr = of_get_property(gem, "fsl,gemac-bus-id", &size);
-+ if (!addr)
-+ pr_err("%s:%d Invalid gemac-bus-id....\n", __func__,
-+ __LINE__);
-+ else
-+ pdata->ls1012a_eth_pdata[port].bus_id = be32_to_cpup(addr);
++ /* If PHY is enabled, read mdio properties */
++ if (pdata->ls1012a_eth_pdata[port].phy_flags & GEMAC_NO_PHY)
++ goto done;
+
-+ addr = of_get_property(gem, "fsl,gemac-phy-id", &size);
-+ if (!addr) {
-+ pr_err("%s:%d Invalid gemac-phy-id....\n", __func__,
-+ __LINE__);
+ } else {
-+ phy_id = be32_to_cpup(addr);
-+ pdata->ls1012a_eth_pdata[port].phy_id = phy_id;
-+ pdata->ls1012a_mdio_pdata[0].phy_mask &= ~(1 << phy_id);
++ pr_info("%s: No PHY or fixed-link\n", __func__);
++ return 0;
+ }
+
++process_phynode:
++ pdata->ls1012a_eth_pdata[port].mii_config = of_get_phy_mode(gem);
++ if ((pdata->ls1012a_eth_pdata[port].mii_config) < 0)
++ pr_err("%s:%d Incorrect Phy mode....\n", __func__,
++ __LINE__);
++
+ addr = of_get_property(gem, "fsl,mdio-mux-val", &size);
-+ if (!addr)
++ if (!addr) {
+ pr_err("%s: Invalid mdio-mux-val....\n", __func__);
-+ else
++ } else {
+ phy_id = be32_to_cpup(addr);
+ pdata->ls1012a_eth_pdata[port].mdio_muxval = phy_id;
++ }
+
+ if (pdata->ls1012a_eth_pdata[port].phy_id < 32)
+ pfe->mdio_muxval[pdata->ls1012a_eth_pdata[port].phy_id] =
+ pdata->ls1012a_eth_pdata[port].mdio_muxval;
+
-+ addr = of_get_property(gem, "fsl,pfe-phy-if-flags", &size);
-+ if (!addr)
-+ pr_err("%s:%d Invalid pfe-phy-if-flags....\n",
-+ __func__, __LINE__);
-+ else
-+ pdata->ls1012a_eth_pdata[port].phy_flags = be32_to_cpup(addr);
-+
-+ /* If PHY is enabled, read mdio properties */
-+ if (pdata->ls1012a_eth_pdata[port].phy_flags & GEMAC_NO_PHY)
-+ goto done;
-+
-+ phy = of_get_next_child(gem, NULL);
-+
-+ addr = of_get_property(phy, "reg", &size);
-+
-+ if (!addr)
-+ pr_err("%s:%d Invalid phy enable flag....\n",
-+ __func__, __LINE__);
-+ else
-+ pdata->ls1012a_mdio_pdata[port].enabled = be32_to_cpup(addr);
+
+ pdata->ls1012a_mdio_pdata[port].irq[0] = PHY_POLL;
+
+done:
-+
+ return 0;
+
+err:
@@ -9470,7 +9654,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ struct resource res;
+ int ii, rc, interface_count = 0, size = 0;
+ const u32 *prop;
-+ struct device_node *np;
++ struct device_node *np, *gem = NULL;
+ struct clk *pfe_clk;
+
+ np = pdev->dev.of_node;
@@ -9548,8 +9732,13 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ pfe_platform_data.ls1012a_mdio_pdata[0].phy_mask = 0xffffffff;
+
+ for (ii = 0; ii < interface_count; ii++) {
-+ pfe_get_gemac_if_proprties(np, ii, interface_count,
-+ &pfe_platform_data);
++ gem = of_get_next_child(np, gem);
++ if (gem)
++ pfe_get_gemac_if_properties(gem, ii,
++ &pfe_platform_data);
++ else
++ pr_err("Unable to find interface %d\n", ii);
++
+ }
+
+ pfe->dev = &pdev->dev;
@@ -9668,8 +9857,8 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ for (i = 0; i < (NUM_GEMAC_SUPPORT); i++) {
+ netdev = pfe->eth.eth_priv[i]->ndev;
+
-+ if (pfe->eth.eth_priv[i]->mii_bus)
-+ pfe_eth_mdio_reset(pfe->eth.eth_priv[i]->mii_bus);
++ if (pfe->mdio.mdio_priv[i]->mii_bus)
++ pfe_eth_mdio_reset(pfe->mdio.mdio_priv[i]->mii_bus);
+
+ if (netif_running(netdev))
+ pfe_eth_resume(netdev);
@@ -9714,27 +9903,16 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+MODULE_AUTHOR("NXP DNCPE");
--- /dev/null
+++ b/drivers/staging/fsl_ppfe/pfe_mod.c
-@@ -0,0 +1,156 @@
+@@ -0,0 +1,158 @@
++// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/dma-mapping.h>
+#include "pfe_mod.h"
++#include "pfe_cdev.h"
+
+unsigned int us;
+module_param(us, uint, 0444);
@@ -9809,8 +9987,18 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ if (rc < 0)
+ goto err_debugfs;
+
++ if (us) {
++ /* Creating a character device */
++ rc = pfe_cdev_init();
++ if (rc < 0)
++ goto err_cdev;
++ }
++
+ return 0;
+
++err_cdev:
++ pfe_debugfs_exit(pfe);
++
+err_debugfs:
+ pfe_sysfs_exit(pfe);
+
@@ -9846,6 +10034,9 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+{
+ pr_info("%s\n", __func__);
+
++ if (us)
++ pfe_cdev_exit();
++
+ pfe_debugfs_exit(pfe);
+
+ pfe_sysfs_exit(pfe);
@@ -9873,23 +10064,11 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+}
--- /dev/null
+++ b/drivers/staging/fsl_ppfe/pfe_mod.h
-@@ -0,0 +1,114 @@
+@@ -0,0 +1,103 @@
++/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _PFE_MOD_H_
@@ -9940,6 +10119,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+ struct pfe_ctrl ctrl;
+ struct pfe_hif hif;
+ struct pfe_eth eth;
++ struct pfe_mdio mdio;
+ struct hif_client_s *hif_client[HIF_CLIENTS_MAX];
+#if defined(CFG_DIAGS)
+ struct pfe_diags diags;
@@ -9990,23 +10170,11 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+#endif /* _PFE_MOD_H */
--- /dev/null
+++ b/drivers/staging/fsl_ppfe/pfe_perfmon.h
-@@ -0,0 +1,38 @@
+@@ -0,0 +1,26 @@
++/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _PFE_PERFMON_H_
@@ -10031,23 +10199,11 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+#endif /* _PFE_PERFMON_H_ */
--- /dev/null
+++ b/drivers/staging/fsl_ppfe/pfe_sysfs.c
-@@ -0,0 +1,818 @@
+@@ -0,0 +1,806 @@
++// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/module.h>
@@ -10852,23 +11008,11 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
+}
--- /dev/null
+++ b/drivers/staging/fsl_ppfe/pfe_sysfs.h
-@@ -0,0 +1,29 @@
+@@ -0,0 +1,17 @@
++/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _PFE_SYSFS_H_