layerscape: update patches-4.14 to LSDK 19.03
[openwrt/staging/jogo.git] / target / linux / layerscape / patches-4.14 / 710-pfe-eth-support-layerscape.patch
index ae64527f3d9faceb64c04f836231f442954f3c94..80baa82f9a5fe81b6e3bb2908c975b2cb8e0cc9f 100644 (file)
@@ -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.
 +
-+- mdio
-+              optional subnode that specifies the mdio bus. This has reg
-+              property which is used to enable/disable the mdio bus.
++- phy-handle
++              Usage: optional
++              Value type: <phandle>
++              Definition: phandle to the PHY device connected to this device.
++
++- 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 {
++      #address-cells = <1>;
++      #size-cells = <0>;
++
++      sgmii_phy1: ethernet-phy@2 {
++              reg = <0x2>;
++      };
 +
-+      mdio@0 {
-+              reg = <0x1>; /* enabled/disabled */
++      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/>.
++ * Copyright 2015-2016 Freescale Semiconductor, Inc.
++ * Copyright 2017 NXP
 + */
 +
 +#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_