layerscape: update patches-4.14 to LSDK 19.03
[openwrt/staging/dedeckeh.git] / target / linux / layerscape / patches-4.14 / 704-dpaa2-mac-phy-support-layerscape.patch
index d76c5abe5171bf4dc601f6e4e7a04fe702f8f1f2..f36da51fff8d64afdcb5cf8bb802f195ac513816 100644 (file)
@@ -1,28 +1,33 @@
-From 92cf25fe454dd42136e717ba679a9dba740db0e7 Mon Sep 17 00:00:00 2001
+From dd0cc8d0739a72ee5d85039a9ba7812383e8f555 Mon Sep 17 00:00:00 2001
 From: Biwen Li <biwen.li@nxp.com>
-Date: Tue, 30 Oct 2018 18:26:18 +0800
-Subject: [PATCH 10/40] dpaa2-mac-phy: support layerscape
-This is an integrated patch of dpaa2-mac-phy for
- layerscape
+Date: Wed, 17 Apr 2019 18:58:30 +0800
+Subject: [PATCH] dpaa2-mac-phy: support layerscape
+
+This is an integrated patch of dpaa2-mac-phy for layerscape
 
 Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
+Signed-off-by: Biwen Li <biwen.li@nxp.com>
 Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@nxp.com>
 Signed-off-by: Bogdan Purcareata <bogdan.purcareata@nxp.com>
+Signed-off-by: Catalin Neacsu <valentin-catalin.neacsu@nxp.com>
 Signed-off-by: Constantin Tudor <constantin.tudor@nxp.com>
+Signed-off-by: Florin Chiculita <florinlaurentiu.chiculita@nxp.com>
+Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
 Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
 Signed-off-by: Itai Katz <itai.katz@freescale.com>
 Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
+Signed-off-by: Pankaj Bansal <pankaj.bansal@nxp.com>
 Signed-off-by: Razvan Stefanescu <razvan.stefanescu@nxp.com>
 Signed-off-by: Stuart Yoder <stuart.yoder@freescale.com>
-Signed-off-by: Biwen Li <biwen.li@nxp.com>
+Signed-off-by: Valentin Catalin Neacsu <valentin-catalin.neacsu@nxp.com>
 ---
  drivers/staging/fsl-dpaa2/mac/Kconfig     |  23 +
  drivers/staging/fsl-dpaa2/mac/Makefile    |  10 +
- drivers/staging/fsl-dpaa2/mac/dpmac-cmd.h | 172 ++++++
- drivers/staging/fsl-dpaa2/mac/dpmac.c     | 619 ++++++++++++++++++++
- drivers/staging/fsl-dpaa2/mac/dpmac.h     | 342 +++++++++++
- drivers/staging/fsl-dpaa2/mac/mac.c       | 672 ++++++++++++++++++++++
- 6 files changed, 1838 insertions(+)
+ drivers/staging/fsl-dpaa2/mac/dpmac-cmd.h | 196 ++++++
+ drivers/staging/fsl-dpaa2/mac/dpmac.c     | 689 ++++++++++++++++++
+ drivers/staging/fsl-dpaa2/mac/dpmac.h     | 374 ++++++++++
+ drivers/staging/fsl-dpaa2/mac/mac.c       | 817 ++++++++++++++++++++++
+ 6 files changed, 2109 insertions(+)
  create mode 100644 drivers/staging/fsl-dpaa2/mac/Kconfig
  create mode 100644 drivers/staging/fsl-dpaa2/mac/Makefile
  create mode 100644 drivers/staging/fsl-dpaa2/mac/dpmac-cmd.h
@@ -71,7 +76,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +      make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
 --- /dev/null
 +++ b/drivers/staging/fsl-dpaa2/mac/dpmac-cmd.h
-@@ -0,0 +1,172 @@
+@@ -0,0 +1,196 @@
 +/* Copyright 2013-2016 Freescale Semiconductor Inc.
 + *
 + * Redistribution and use in source and binary forms, with or without
@@ -110,9 +115,11 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +#define DPMAC_VER_MAJOR                               4
 +#define DPMAC_VER_MINOR                               2
 +#define DPMAC_CMD_BASE_VERSION                        1
++#define DPMAC_CMD_2ND_VERSION                 2
 +#define DPMAC_CMD_ID_OFFSET                   4
 +
 +#define DPMAC_CMD(id) (((id) << DPMAC_CMD_ID_OFFSET) | DPMAC_CMD_BASE_VERSION)
++#define DPMAC_CMD_V2(id) (((id) << DPMAC_CMD_ID_OFFSET) | DPMAC_CMD_2ND_VERSION)
 +
 +/* Command IDs */
 +#define DPMAC_CMDID_CLOSE             DPMAC_CMD(0x800)
@@ -132,7 +139,9 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +#define DPMAC_CMDID_CLEAR_IRQ_STATUS  DPMAC_CMD(0x017)
 +
 +#define DPMAC_CMDID_GET_LINK_CFG      DPMAC_CMD(0x0c2)
++#define DPMAC_CMDID_GET_LINK_CFG_V2   DPMAC_CMD_V2(0x0c2)
 +#define DPMAC_CMDID_SET_LINK_STATE    DPMAC_CMD(0x0c3)
++#define DPMAC_CMDID_SET_LINK_STATE_V2 DPMAC_CMD_V2(0x0c3)
 +#define DPMAC_CMDID_GET_COUNTER               DPMAC_CMD(0x0c4)
 +
 +#define DPMAC_CMDID_SET_PORT_MAC_ADDR DPMAC_CMD(0x0c5)
@@ -213,8 +222,17 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +      u32 rate;
 +};
 +
++struct dpmac_rsp_get_link_cfg_v2 {
++      u64 options;
++      u32 rate;
++      u32 pad;
++      u64 advertising;
++};
++
 +#define DPMAC_STATE_SIZE      1
 +#define DPMAC_STATE_SHIFT     0
++#define DPMAC_STATE_VALID_SIZE        1
++#define DPMAC_STATE_VALID_SHIFT       1
 +
 +struct dpmac_cmd_set_link_state {
 +      u64 options;
@@ -224,6 +242,17 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +      u8 up;
 +};
 +
++struct dpmac_cmd_set_link_state_v2 {
++      u64 options;
++      u32 rate;
++      u32 pad0;
++      /* from lsb: up:1, state_valid:1 */
++      u8 state;
++      u8 pad1[7];
++      u64 supported;
++      u64 advertising;
++};
++
 +struct dpmac_cmd_get_counter {
 +      u8 type;
 +};
@@ -246,7 +275,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +#endif /* _FSL_DPMAC_CMD_H */
 --- /dev/null
 +++ b/drivers/staging/fsl-dpaa2/mac/dpmac.c
-@@ -0,0 +1,619 @@
+@@ -0,0 +1,689 @@
 +/* Copyright 2013-2016 Freescale Semiconductor Inc.
 + *
 + * Redistribution and use in source and binary forms, with or without
@@ -741,6 +770,42 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +}
 +
 +/**
++ * dpmac_get_link_cfg_v2() - Get Ethernet link configuration
++ * @mc_io:      Pointer to opaque I/O object
++ * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
++ * @token:      Token of DPMAC object
++ * @cfg:        Returned structure with the link configuration
++ *
++ * Return:      '0' on Success; Error code otherwise.
++ */
++int dpmac_get_link_cfg_v2(struct fsl_mc_io *mc_io,
++                        u32 cmd_flags,
++                        u16 token,
++                        struct dpmac_link_cfg *cfg)
++{
++      struct dpmac_rsp_get_link_cfg_v2 *rsp_params;
++      struct fsl_mc_command cmd = { 0 };
++      int err = 0;
++
++      /* prepare command */
++      cmd.header = mc_encode_cmd_header(DPMAC_CMDID_GET_LINK_CFG_V2,
++                                        cmd_flags,
++                                        token);
++
++      /* send command to mc*/
++      err = mc_send_command(mc_io, &cmd);
++      if (err)
++              return err;
++
++      rsp_params = (struct dpmac_rsp_get_link_cfg_v2 *)cmd.params;
++      cfg->options = le64_to_cpu(rsp_params->options);
++      cfg->rate = le32_to_cpu(rsp_params->rate);
++      cfg->advertising = le64_to_cpu(rsp_params->advertising);
++
++      return 0;
++}
++
++/**
 + * dpmac_set_link_state() - Set the Ethernet link status
 + * @mc_io:    Pointer to opaque I/O object
 + * @cmd_flags:        Command flags; one or more of 'MC_CMD_FLAG_'
@@ -764,7 +829,41 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +      cmd_params = (struct dpmac_cmd_set_link_state *)cmd.params;
 +      cmd_params->options = cpu_to_le64(link_state->options);
 +      cmd_params->rate = cpu_to_le32(link_state->rate);
-+      cmd_params->up = dpmac_get_field(link_state->up, STATE);
++      dpmac_set_field(cmd_params->up, STATE, link_state->up);
++
++      /* send command to mc*/
++      return mc_send_command(mc_io, &cmd);
++}
++
++/**
++ * dpmac_set_link_state_v2() - Set the Ethernet link status
++ * @mc_io:      Pointer to opaque I/O object
++ * @cmd_flags:  Command flags; one or more of 'MC_CMD_FLAG_'
++ * @token:      Token of DPMAC object
++ * @link_state: Link state configuration
++ *
++ * Return:      '0' on Success; Error code otherwise.
++ */
++int dpmac_set_link_state_v2(struct fsl_mc_io *mc_io,
++                          u32 cmd_flags,
++                          u16 token,
++                          struct dpmac_link_state *link_state)
++{
++      struct dpmac_cmd_set_link_state_v2 *cmd_params;
++      struct fsl_mc_command cmd = { 0 };
++
++      /* prepare command */
++      cmd.header = mc_encode_cmd_header(DPMAC_CMDID_SET_LINK_STATE_V2,
++                                        cmd_flags,
++                                        token);
++      cmd_params = (struct dpmac_cmd_set_link_state_v2 *)cmd.params;
++      cmd_params->options = cpu_to_le64(link_state->options);
++      cmd_params->rate = cpu_to_le32(link_state->rate);
++      dpmac_set_field(cmd_params->state, STATE, link_state->up);
++      dpmac_set_field(cmd_params->state, STATE_VALID,
++                      link_state->state_valid);
++      cmd_params->supported = cpu_to_le64(link_state->supported);
++      cmd_params->advertising = cpu_to_le64(link_state->advertising);
 +
 +      /* send command to mc*/
 +      return mc_send_command(mc_io, &cmd);
@@ -868,7 +967,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +}
 --- /dev/null
 +++ b/drivers/staging/fsl-dpaa2/mac/dpmac.h
-@@ -0,0 +1,342 @@
+@@ -0,0 +1,374 @@
 +/* Copyright 2013-2016 Freescale Semiconductor Inc.
 + *
 + * Redistribution and use in source and binary forms, with or without
@@ -1073,13 +1172,29 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +#define DPMAC_LINK_OPT_ASYM_PAUSE     0x0000000000000008ULL
 +
 +/**
++ * Advertised link speeds
++ */
++#define DPMAC_ADVERTISED_10BASET_FULL         0x0000000000000001ULL
++#define DPMAC_ADVERTISED_100BASET_FULL                0x0000000000000002ULL
++#define DPMAC_ADVERTISED_1000BASET_FULL               0x0000000000000004ULL
++#define DPMAC_ADVERTISED_10000BASET_FULL      0x0000000000000010ULL
++#define DPMAC_ADVERTISED_2500BASEX_FULL               0x0000000000000020ULL
++
++/**
++ * Advertise auto-negotiation enable
++ */
++#define DPMAC_ADVERTISED_AUTONEG              0x0000000000000008ULL
++
++/**
 + * struct dpmac_link_cfg - Structure representing DPMAC link configuration
 + * @rate: Link's rate - in Mbps
 + * @options: Enable/Disable DPMAC link cfg features (bitmap)
++ * @advertising: Speeds that are advertised for autoneg (bitmap)
 + */
 +struct dpmac_link_cfg {
 +      u32 rate;
 +      u64 options;
++      u64 advertising;
 +};
 +
 +int dpmac_get_link_cfg(struct fsl_mc_io *mc_io,
@@ -1087,16 +1202,27 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +                     u16 token,
 +                     struct dpmac_link_cfg *cfg);
 +
++int dpmac_get_link_cfg_v2(struct fsl_mc_io *mc_io,
++                        u32 cmd_flags,
++                        u16 token,
++                        struct dpmac_link_cfg *cfg);
++
 +/**
 + * struct dpmac_link_state - DPMAC link configuration request
 + * @rate: Rate in Mbps
 + * @options: Enable/Disable DPMAC link cfg features (bitmap)
 + * @up: Link state
++ * @state_valid: Ignore/Update the state of the link
++ * @supported: Speeds capability of the phy (bitmap)
++ * @advertising: Speeds that are advertised for autoneg (bitmap)
 + */
 +struct dpmac_link_state {
 +      u32 rate;
 +      u64 options;
 +      int up;
++      int state_valid;
++      u64 supported;
++      u64 advertising;
 +};
 +
 +int dpmac_set_link_state(struct fsl_mc_io *mc_io,
@@ -1104,6 +1230,11 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +                       u16 token,
 +                       struct dpmac_link_state *link_state);
 +
++int dpmac_set_link_state_v2(struct fsl_mc_io *mc_io,
++                          u32 cmd_flags,
++                          u16 token,
++                          struct dpmac_link_state *link_state);
++
 +/**
 + * enum dpmac_counter - DPMAC counter types
 + * @DPMAC_CNT_ING_FRAME_64: counts 64-bytes frames, good or bad.
@@ -1213,8 +1344,9 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +#endif /* __FSL_DPMAC_H */
 --- /dev/null
 +++ b/drivers/staging/fsl-dpaa2/mac/mac.c
-@@ -0,0 +1,672 @@
+@@ -0,0 +1,817 @@
 +/* Copyright 2015 Freescale Semiconductor Inc.
++ * Copyright 2018 NXP
 + *
 + * Redistribution and use in source and binary forms, with or without
 + * modification, are permitted provided that the following conditions are met:
@@ -1272,6 +1404,8 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +      struct fsl_mc_device            *mc_dev;
 +      struct dpmac_attr               attr;
 +      struct dpmac_link_state         old_state;
++      u16                             dpmac_ver_major;
++      u16                             dpmac_ver_minor;
 +};
 +
 +/* TODO: fix the 10G modes, mapping can't be right:
@@ -1292,8 +1426,62 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +      PHY_INTERFACE_MODE_QSGMII,      /* DPMAC_ETH_IF_QSGMII */
 +      PHY_INTERFACE_MODE_XGMII,       /* DPMAC_ETH_IF_XAUI */
 +      PHY_INTERFACE_MODE_XGMII,       /* DPMAC_ETH_IF_XFI */
++      PHY_INTERFACE_MODE_XGMII,        /* DPMAC_ETH_IF_CAUI */
++      PHY_INTERFACE_MODE_XGMII,       /* DPMAC_ETH_IF_1000BASEX */
++      PHY_INTERFACE_MODE_XGMII,       /* DPMAC_ETH_IF_USXGMII */
 +};
 +
++static int cmp_dpmac_ver(struct dpaa2_mac_priv *priv,
++                       u16 ver_major, u16 ver_minor)
++{
++      if (priv->dpmac_ver_major == ver_major)
++              return priv->dpmac_ver_minor - ver_minor;
++      return priv->dpmac_ver_major - ver_major;
++}
++
++#define DPMAC_LINK_AUTONEG_VER_MAJOR          4
++#define DPMAC_LINK_AUTONEG_VER_MINOR          3
++
++struct dpaa2_mac_link_mode_map {
++      u64 dpmac_lm;
++      u64 ethtool_lm;
++};
++
++static const struct dpaa2_mac_link_mode_map dpaa2_mac_lm_map[] = {
++      {DPMAC_ADVERTISED_10BASET_FULL, ETHTOOL_LINK_MODE_10baseT_Full_BIT},
++      {DPMAC_ADVERTISED_100BASET_FULL, ETHTOOL_LINK_MODE_100baseT_Full_BIT},
++      {DPMAC_ADVERTISED_1000BASET_FULL, ETHTOOL_LINK_MODE_1000baseT_Full_BIT},
++      {DPMAC_ADVERTISED_10000BASET_FULL, ETHTOOL_LINK_MODE_10000baseT_Full_BIT},
++      {DPMAC_ADVERTISED_2500BASEX_FULL, ETHTOOL_LINK_MODE_2500baseX_Full_BIT},
++      {DPMAC_ADVERTISED_AUTONEG, ETHTOOL_LINK_MODE_Autoneg_BIT},
++};
++
++static void link_mode_dpmac2phydev(u64 dpmac_lm, u32 *phydev_lm)
++{
++      __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
++      int i;
++
++      for (i = 0; i < ARRAY_SIZE(dpaa2_mac_lm_map); i++) {
++              if (dpmac_lm & dpaa2_mac_lm_map[i].dpmac_lm)
++                      __set_bit(dpaa2_mac_lm_map[i].ethtool_lm, mask);
++      }
++
++      ethtool_convert_link_mode_to_legacy_u32(phydev_lm, mask);
++}
++
++static void link_mode_phydev2dpmac(u32 phydev_lm, u64 *dpni_lm)
++{
++      unsigned long lm;
++      int i;
++
++      ethtool_convert_legacy_u32_to_link_mode(&lm, phydev_lm);
++
++      for (i = 0; i < ARRAY_SIZE(dpaa2_mac_lm_map); i++) {
++              if (test_bit(dpaa2_mac_lm_map[i].ethtool_lm, &lm))
++                      *dpni_lm |= dpaa2_mac_lm_map[i].dpmac_lm;
++      }
++}
++
 +static void dpaa2_mac_link_changed(struct net_device *netdev)
 +{
 +      struct phy_device       *phydev;
@@ -1313,6 +1501,12 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +              if (phydev->autoneg)
 +                      state.options |= DPMAC_LINK_OPT_AUTONEG;
 +
++              if (phydev->pause && (phydev->advertising & ADVERTISED_Pause))
++                      state.options |= DPMAC_LINK_OPT_PAUSE;
++              if (phydev->pause &&
++                  (phydev->advertising & ADVERTISED_Asym_Pause))
++                      state.options |= DPMAC_LINK_OPT_ASYM_PAUSE;
++
 +              netif_carrier_on(netdev);
 +      } else {
 +              netif_carrier_off(netdev);
@@ -1325,11 +1519,18 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +              phy_print_status(phydev);
 +      }
 +
-+      /* We must interrogate MC at all times, because we don't know
-+       * when and whether a potential DPNI may have read the link state.
-+       */
-+      err = dpmac_set_link_state(priv->mc_dev->mc_io, 0,
-+                                 priv->mc_dev->mc_handle, &state);
++      if (cmp_dpmac_ver(priv, DPMAC_LINK_AUTONEG_VER_MAJOR,
++                        DPMAC_LINK_AUTONEG_VER_MINOR) < 0) {
++              err = dpmac_set_link_state(priv->mc_dev->mc_io, 0,
++                                         priv->mc_dev->mc_handle, &state);
++      } else {
++              link_mode_phydev2dpmac(phydev->supported, &state.supported);
++              link_mode_phydev2dpmac(phydev->advertising, &state.advertising);
++              state.state_valid = 1;
++
++              err = dpmac_set_link_state_v2(priv->mc_dev->mc_io, 0,
++                                            priv->mc_dev->mc_handle, &state);
++      }
 +      if (unlikely(err))
 +              dev_err(&priv->mc_dev->dev, "dpmac_set_link_state: %d\n", err);
 +}
@@ -1367,6 +1568,18 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +      return NETDEV_TX_OK;
 +}
 +
++static void dpaa2_mac_get_drvinfo(struct net_device *net_dev,
++                                struct ethtool_drvinfo *drvinfo)
++{
++      struct dpaa2_mac_priv *priv = netdev_priv(net_dev);
++
++      strlcpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
++      snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
++               "%u.%u", priv->dpmac_ver_major, priv->dpmac_ver_minor);
++      strlcpy(drvinfo->bus_info, dev_name(net_dev->dev.parent->parent),
++              sizeof(drvinfo->bus_info));
++}
++
 +static int dpaa2_mac_get_link_ksettings(struct net_device *netdev,
 +                                      struct ethtool_link_ksettings *ks)
 +{
@@ -1536,6 +1749,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +};
 +
 +static const struct ethtool_ops dpaa2_mac_ethtool_ops = {
++      .get_drvinfo            = &dpaa2_mac_get_drvinfo,
 +      .get_link_ksettings     = &dpaa2_mac_get_link_ksettings,
 +      .set_link_ksettings     = &dpaa2_mac_set_link_ksettings,
 +      .get_strings            = &dpaa2_mac_get_strings,
@@ -1555,11 +1769,30 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +      phydev->speed = cfg->rate;
 +      phydev->duplex  = !!(cfg->options & DPMAC_LINK_OPT_HALF_DUPLEX);
 +
++      if (cfg->advertising != 0) {
++              phydev->advertising = 0;
++              link_mode_dpmac2phydev(cfg->advertising, &phydev->advertising);
++      }
++
++      if (phydev->supported & SUPPORTED_Pause) {
++              if (cfg->options & DPMAC_LINK_OPT_PAUSE)
++                      phydev->advertising |= ADVERTISED_Pause;
++              else
++                      phydev->advertising &= ~ADVERTISED_Pause;
++      }
++
++      if (phydev->supported & SUPPORTED_Asym_Pause) {
++              if (cfg->options & DPMAC_LINK_OPT_ASYM_PAUSE)
++                      phydev->advertising |= ADVERTISED_Asym_Pause;
++              else
++                      phydev->advertising &= ~ADVERTISED_Asym_Pause;
++      }
++
 +      if (cfg->options & DPMAC_LINK_OPT_AUTONEG) {
-+              phydev->autoneg = 1;
++              phydev->autoneg = AUTONEG_ENABLE;
 +              phydev->advertising |= ADVERTISED_Autoneg;
 +      } else {
-+              phydev->autoneg = 0;
++              phydev->autoneg = AUTONEG_DISABLE;
 +              phydev->advertising &= ~ADVERTISED_Autoneg;
 +      }
 +
@@ -1571,7 +1804,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +      struct device *dev = (struct device *)arg;
 +      struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
 +      struct dpaa2_mac_priv *priv = dev_get_drvdata(dev);
-+      struct dpmac_link_cfg link_cfg;
++      struct dpmac_link_cfg link_cfg = { 0 };
 +      u32 status;
 +      int err;
 +
@@ -1582,8 +1815,14 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +
 +      /* DPNI-initiated link configuration; 'ifconfig up' also calls this */
 +      if (status & DPMAC_IRQ_EVENT_LINK_CFG_REQ) {
-+              err = dpmac_get_link_cfg(mc_dev->mc_io, 0, mc_dev->mc_handle,
-+                                       &link_cfg);
++              if (cmp_dpmac_ver(priv, DPMAC_LINK_AUTONEG_VER_MAJOR,
++                                DPMAC_LINK_AUTONEG_VER_MINOR) < 0)
++                      err = dpmac_get_link_cfg(mc_dev->mc_io, 0,
++                                               mc_dev->mc_handle, &link_cfg);
++              else
++                      err = dpmac_get_link_cfg_v2(mc_dev->mc_io, 0,
++                                                  mc_dev->mc_handle,
++                                                  &link_cfg);
 +              if (unlikely(err))
 +                      goto out;
 +
@@ -1682,7 +1921,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +      struct dpaa2_mac_priv   *priv = NULL;
 +      struct device_node      *phy_node, *dpmac_node;
 +      struct net_device       *netdev;
-+      phy_interface_t         if_mode;
++      int                     if_mode;
 +      int                     err = 0;
 +
 +      dev = &mc_dev->dev;
@@ -1723,6 +1962,21 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +              goto err_free_mcp;
 +      }
 +
++      err = dpmac_get_api_version(mc_dev->mc_io, 0, &priv->dpmac_ver_major,
++                                  &priv->dpmac_ver_minor);
++      if (err) {
++              dev_err(dev, "dpmac_get_api_version failed\n");
++              goto err_version;
++      }
++
++      if (cmp_dpmac_ver(priv, DPMAC_VER_MAJOR, DPMAC_VER_MINOR) < 0) {
++              dev_err(dev, "DPMAC version %u.%u lower than supported %u.%u\n",
++                      priv->dpmac_ver_major, priv->dpmac_ver_minor,
++                      DPMAC_VER_MAJOR, DPMAC_VER_MINOR);
++              err = -ENOTSUPP;
++              goto err_version;
++      }
++
 +      err = dpmac_get_attributes(mc_dev->mc_io, 0,
 +                                 mc_dev->mc_handle, &priv->attr);
 +      if (err) {
@@ -1761,12 +2015,12 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +      }
 +#endif /* CONFIG_FSL_DPAA2_MAC_NETDEVS */
 +
-+      /* probe the PHY as a fixed-link if there's a phy-handle defined
-+       * in the device tree
-+       */
-+      phy_node = of_parse_phandle(dpmac_node, "phy-handle", 0);
-+      if (!phy_node) {
-+              goto probe_fixed_link;
++      /* get the interface mode from the dpmac of node or from the MC attributes */
++      if_mode = of_get_phy_mode(dpmac_node);
++      if (if_mode >= 0) {
++              dev_dbg(dev, "\tusing if mode %s for eth_if %d\n",
++                      phy_modes(if_mode), priv->attr.eth_if);
++              goto link_type;
 +      }
 +
 +      if (priv->attr.eth_if < ARRAY_SIZE(dpaa2_mac_iface_mode)) {
@@ -1774,8 +2028,20 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +              dev_dbg(dev, "\tusing if mode %s for eth_if %d\n",
 +                      phy_modes(if_mode), priv->attr.eth_if);
 +      } else {
-+              dev_warn(dev, "Unexpected interface mode %d, will probe as fixed link\n",
-+                       priv->attr.eth_if);
++              dev_err(dev, "Unexpected interface mode %d\n",
++                      priv->attr.eth_if);
++              err = -EINVAL;
++              goto err_no_if_mode;
++      }
++
++link_type:
++      /* probe the PHY as fixed-link if the DPMAC attribute indicates so */
++      if (priv->attr.link_type == DPMAC_LINK_TYPE_FIXED)
++              goto probe_fixed_link;
++
++      /* or if there's no phy-handle defined in the device tree */
++      phy_node = of_parse_phandle(dpmac_node, "phy-handle", 0);
++      if (!phy_node) {
 +              goto probe_fixed_link;
 +      }
 +
@@ -1812,6 +2078,14 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +                      err = -EFAULT;
 +                      goto err_no_phy;
 +              }
++
++              err = phy_connect_direct(netdev, netdev->phydev,
++                                       &dpaa2_mac_link_changed, if_mode);
++              if (err) {
++                      dev_err(dev, "error trying to connect to PHY\n");
++                      goto err_no_phy;
++              }
++
 +              dev_info(dev, "Registered fixed PHY.\n");
 +      }
 +
@@ -1819,6 +2093,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +
 +      return 0;
 +
++err_no_if_mode:
 +err_defer:
 +err_no_phy:
 +#ifdef CONFIG_FSL_DPAA2_MAC_NETDEVS
@@ -1826,6 +2101,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +err_free_irq:
 +#endif
 +      teardown_irqs(mc_dev);
++err_version:
 +err_close:
 +      dpmac_close(mc_dev->mc_io, 0, mc_dev->mc_handle);
 +err_free_mcp: