net: ethernet: fix similar warning reported by kbuild test robot
[linux-2.6-microblaze.git] / drivers / net / ethernet / ti / cpsw.c
index a591583..634fc48 100644 (file)
@@ -1,16 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Texas Instruments Ethernet Switch Driver
  *
  * Copyright (C) 2012 Texas Instruments
  *
- * 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 version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
 
 #include <linux/kernel.h>
 
 #include "cpsw.h"
 #include "cpsw_ale.h"
+#include "cpsw_priv.h"
+#include "cpsw_sl.h"
 #include "cpts.h"
 #include "davinci_cpdma.h"
 
 #include <net/pkt_sched.h>
 
-#define CPSW_DEBUG     (NETIF_MSG_HW           | NETIF_MSG_WOL         | \
-                        NETIF_MSG_DRV          | NETIF_MSG_LINK        | \
-                        NETIF_MSG_IFUP         | NETIF_MSG_INTR        | \
-                        NETIF_MSG_PROBE        | NETIF_MSG_TIMER       | \
-                        NETIF_MSG_IFDOWN       | NETIF_MSG_RX_ERR      | \
-                        NETIF_MSG_TX_ERR       | NETIF_MSG_TX_DONE     | \
-                        NETIF_MSG_PKTDATA      | NETIF_MSG_TX_QUEUED   | \
-                        NETIF_MSG_RX_STATUS)
-
-#define cpsw_info(priv, type, format, ...)             \
-do {                                                           \
-       if (netif_msg_##type(priv) && net_ratelimit())          \
-               dev_info(priv->dev, format, ## __VA_ARGS__);    \
-} while (0)
-
-#define cpsw_err(priv, type, format, ...)              \
-do {                                                           \
-       if (netif_msg_##type(priv) && net_ratelimit())          \
-               dev_err(priv->dev, format, ## __VA_ARGS__);     \
-} while (0)
-
-#define cpsw_dbg(priv, type, format, ...)              \
-do {                                                           \
-       if (netif_msg_##type(priv) && net_ratelimit())          \
-               dev_dbg(priv->dev, format, ## __VA_ARGS__);     \
-} while (0)
-
-#define cpsw_notice(priv, type, format, ...)           \
-do {                                                           \
-       if (netif_msg_##type(priv) && net_ratelimit())          \
-               dev_notice(priv->dev, format, ## __VA_ARGS__);  \
-} while (0)
-
-#define ALE_ALL_PORTS          0x7
-
-#define CPSW_MAJOR_VERSION(reg)                (reg >> 8 & 0x7)
-#define CPSW_MINOR_VERSION(reg)                (reg & 0xff)
-#define CPSW_RTL_VERSION(reg)          ((reg >> 11) & 0x1f)
-
-#define CPSW_VERSION_1         0x19010a
-#define CPSW_VERSION_2         0x19010c
-#define CPSW_VERSION_3         0x19010f
-#define CPSW_VERSION_4         0x190112
-
-#define HOST_PORT_NUM          0
-#define CPSW_ALE_PORTS_NUM     3
-#define SLIVER_SIZE            0x40
-
-#define CPSW1_HOST_PORT_OFFSET 0x028
-#define CPSW1_SLAVE_OFFSET     0x050
-#define CPSW1_SLAVE_SIZE       0x040
-#define CPSW1_CPDMA_OFFSET     0x100
-#define CPSW1_STATERAM_OFFSET  0x200
-#define CPSW1_HW_STATS         0x400
-#define CPSW1_CPTS_OFFSET      0x500
-#define CPSW1_ALE_OFFSET       0x600
-#define CPSW1_SLIVER_OFFSET    0x700
-
-#define CPSW2_HOST_PORT_OFFSET 0x108
-#define CPSW2_SLAVE_OFFSET     0x200
-#define CPSW2_SLAVE_SIZE       0x100
-#define CPSW2_CPDMA_OFFSET     0x800
-#define CPSW2_HW_STATS         0x900
-#define CPSW2_STATERAM_OFFSET  0xa00
-#define CPSW2_CPTS_OFFSET      0xc00
-#define CPSW2_ALE_OFFSET       0xd00
-#define CPSW2_SLIVER_OFFSET    0xd80
-#define CPSW2_BD_OFFSET                0x2000
-
-#define CPDMA_RXTHRESH         0x0c0
-#define CPDMA_RXFREE           0x0e0
-#define CPDMA_TXHDP            0x00
-#define CPDMA_RXHDP            0x20
-#define CPDMA_TXCP             0x40
-#define CPDMA_RXCP             0x60
-
-#define CPSW_POLL_WEIGHT       64
-#define CPSW_RX_VLAN_ENCAP_HDR_SIZE            4
-#define CPSW_MIN_PACKET_SIZE   (VLAN_ETH_ZLEN)
-#define CPSW_MAX_PACKET_SIZE   (VLAN_ETH_FRAME_LEN +\
-                                ETH_FCS_LEN +\
-                                CPSW_RX_VLAN_ENCAP_HDR_SIZE)
-
-#define RX_PRIORITY_MAPPING    0x76543210
-#define TX_PRIORITY_MAPPING    0x33221100
-#define CPDMA_TX_PRIORITY_MAP  0x76543210
-
-#define CPSW_VLAN_AWARE                BIT(1)
-#define CPSW_RX_VLAN_ENCAP     BIT(2)
-#define CPSW_ALE_VLAN_AWARE    1
-
-#define CPSW_FIFO_NORMAL_MODE          (0 << 16)
-#define CPSW_FIFO_DUAL_MAC_MODE                (1 << 16)
-#define CPSW_FIFO_RATE_LIMIT_MODE      (2 << 16)
-
-#define CPSW_INTPACEEN         (0x3f << 16)
-#define CPSW_INTPRESCALE_MASK  (0x7FF << 0)
-#define CPSW_CMINTMAX_CNT      63
-#define CPSW_CMINTMIN_CNT      2
-#define CPSW_CMINTMAX_INTVL    (1000 / CPSW_CMINTMIN_CNT)
-#define CPSW_CMINTMIN_INTVL    ((1000 / CPSW_CMINTMAX_CNT) + 1)
-
-#define cpsw_slave_index(cpsw, priv)                           \
-               ((cpsw->data.dual_emac) ? priv->emac_port :     \
-               cpsw->data.active_slave)
-#define IRQ_NUM                        2
-#define CPSW_MAX_QUEUES                8
-#define CPSW_CPDMA_DESCS_POOL_SIZE_DEFAULT 256
-#define CPSW_FIFO_QUEUE_TYPE_SHIFT     16
-#define CPSW_FIFO_SHAPE_EN_SHIFT       16
-#define CPSW_FIFO_RATE_EN_SHIFT                20
-#define CPSW_TC_NUM                    4
-#define CPSW_FIFO_SHAPERS_NUM          (CPSW_TC_NUM - 1)
-#define CPSW_PCT_MASK                  0x7f
-
-#define CPSW_RX_VLAN_ENCAP_HDR_PRIO_SHIFT      29
-#define CPSW_RX_VLAN_ENCAP_HDR_PRIO_MSK                GENMASK(2, 0)
-#define CPSW_RX_VLAN_ENCAP_HDR_VID_SHIFT       16
-#define CPSW_RX_VLAN_ENCAP_HDR_PKT_TYPE_SHIFT  8
-#define CPSW_RX_VLAN_ENCAP_HDR_PKT_TYPE_MSK    GENMASK(1, 0)
-enum {
-       CPSW_RX_VLAN_ENCAP_HDR_PKT_VLAN_TAG = 0,
-       CPSW_RX_VLAN_ENCAP_HDR_PKT_RESERV,
-       CPSW_RX_VLAN_ENCAP_HDR_PKT_PRIO_TAG,
-       CPSW_RX_VLAN_ENCAP_HDR_PKT_UNTAG,
-};
-
 static int debug_level;
 module_param(debug_level, int, 0);
 MODULE_PARM_DESC(debug_level, "cpsw debug level (NETIF_MSG bits)");
@@ -192,369 +60,6 @@ static int descs_pool_size = CPSW_CPDMA_DESCS_POOL_SIZE_DEFAULT;
 module_param(descs_pool_size, int, 0444);
 MODULE_PARM_DESC(descs_pool_size, "Number of CPDMA CPPI descriptors in pool");
 
-struct cpsw_wr_regs {
-       u32     id_ver;
-       u32     soft_reset;
-       u32     control;
-       u32     int_control;
-       u32     rx_thresh_en;
-       u32     rx_en;
-       u32     tx_en;
-       u32     misc_en;
-       u32     mem_allign1[8];
-       u32     rx_thresh_stat;
-       u32     rx_stat;
-       u32     tx_stat;
-       u32     misc_stat;
-       u32     mem_allign2[8];
-       u32     rx_imax;
-       u32     tx_imax;
-
-};
-
-struct cpsw_ss_regs {
-       u32     id_ver;
-       u32     control;
-       u32     soft_reset;
-       u32     stat_port_en;
-       u32     ptype;
-       u32     soft_idle;
-       u32     thru_rate;
-       u32     gap_thresh;
-       u32     tx_start_wds;
-       u32     flow_control;
-       u32     vlan_ltype;
-       u32     ts_ltype;
-       u32     dlr_ltype;
-};
-
-/* CPSW_PORT_V1 */
-#define CPSW1_MAX_BLKS      0x00 /* Maximum FIFO Blocks */
-#define CPSW1_BLK_CNT       0x04 /* FIFO Block Usage Count (Read Only) */
-#define CPSW1_TX_IN_CTL     0x08 /* Transmit FIFO Control */
-#define CPSW1_PORT_VLAN     0x0c /* VLAN Register */
-#define CPSW1_TX_PRI_MAP    0x10 /* Tx Header Priority to Switch Pri Mapping */
-#define CPSW1_TS_CTL        0x14 /* Time Sync Control */
-#define CPSW1_TS_SEQ_LTYPE  0x18 /* Time Sync Sequence ID Offset and Msg Type */
-#define CPSW1_TS_VLAN       0x1c /* Time Sync VLAN1 and VLAN2 */
-
-/* CPSW_PORT_V2 */
-#define CPSW2_CONTROL       0x00 /* Control Register */
-#define CPSW2_MAX_BLKS      0x08 /* Maximum FIFO Blocks */
-#define CPSW2_BLK_CNT       0x0c /* FIFO Block Usage Count (Read Only) */
-#define CPSW2_TX_IN_CTL     0x10 /* Transmit FIFO Control */
-#define CPSW2_PORT_VLAN     0x14 /* VLAN Register */
-#define CPSW2_TX_PRI_MAP    0x18 /* Tx Header Priority to Switch Pri Mapping */
-#define CPSW2_TS_SEQ_MTYPE  0x1c /* Time Sync Sequence ID Offset and Msg Type */
-
-/* CPSW_PORT_V1 and V2 */
-#define SA_LO               0x20 /* CPGMAC_SL Source Address Low */
-#define SA_HI               0x24 /* CPGMAC_SL Source Address High */
-#define SEND_PERCENT        0x28 /* Transmit Queue Send Percentages */
-
-/* CPSW_PORT_V2 only */
-#define RX_DSCP_PRI_MAP0    0x30 /* Rx DSCP Priority to Rx Packet Mapping */
-#define RX_DSCP_PRI_MAP1    0x34 /* Rx DSCP Priority to Rx Packet Mapping */
-#define RX_DSCP_PRI_MAP2    0x38 /* Rx DSCP Priority to Rx Packet Mapping */
-#define RX_DSCP_PRI_MAP3    0x3c /* Rx DSCP Priority to Rx Packet Mapping */
-#define RX_DSCP_PRI_MAP4    0x40 /* Rx DSCP Priority to Rx Packet Mapping */
-#define RX_DSCP_PRI_MAP5    0x44 /* Rx DSCP Priority to Rx Packet Mapping */
-#define RX_DSCP_PRI_MAP6    0x48 /* Rx DSCP Priority to Rx Packet Mapping */
-#define RX_DSCP_PRI_MAP7    0x4c /* Rx DSCP Priority to Rx Packet Mapping */
-
-/* Bit definitions for the CPSW2_CONTROL register */
-#define PASS_PRI_TAGGED     BIT(24) /* Pass Priority Tagged */
-#define VLAN_LTYPE2_EN      BIT(21) /* VLAN LTYPE 2 enable */
-#define VLAN_LTYPE1_EN      BIT(20) /* VLAN LTYPE 1 enable */
-#define DSCP_PRI_EN         BIT(16) /* DSCP Priority Enable */
-#define TS_107              BIT(15) /* Tyme Sync Dest IP Address 107 */
-#define TS_320              BIT(14) /* Time Sync Dest Port 320 enable */
-#define TS_319              BIT(13) /* Time Sync Dest Port 319 enable */
-#define TS_132              BIT(12) /* Time Sync Dest IP Addr 132 enable */
-#define TS_131              BIT(11) /* Time Sync Dest IP Addr 131 enable */
-#define TS_130              BIT(10) /* Time Sync Dest IP Addr 130 enable */
-#define TS_129              BIT(9)  /* Time Sync Dest IP Addr 129 enable */
-#define TS_TTL_NONZERO      BIT(8)  /* Time Sync Time To Live Non-zero enable */
-#define TS_ANNEX_F_EN       BIT(6)  /* Time Sync Annex F enable */
-#define TS_ANNEX_D_EN       BIT(4)  /* Time Sync Annex D enable */
-#define TS_LTYPE2_EN        BIT(3)  /* Time Sync LTYPE 2 enable */
-#define TS_LTYPE1_EN        BIT(2)  /* Time Sync LTYPE 1 enable */
-#define TS_TX_EN            BIT(1)  /* Time Sync Transmit Enable */
-#define TS_RX_EN            BIT(0)  /* Time Sync Receive Enable */
-
-#define CTRL_V2_TS_BITS \
-       (TS_320 | TS_319 | TS_132 | TS_131 | TS_130 | TS_129 |\
-        TS_TTL_NONZERO  | TS_ANNEX_D_EN | TS_LTYPE1_EN | VLAN_LTYPE1_EN)
-
-#define CTRL_V2_ALL_TS_MASK (CTRL_V2_TS_BITS | TS_TX_EN | TS_RX_EN)
-#define CTRL_V2_TX_TS_BITS  (CTRL_V2_TS_BITS | TS_TX_EN)
-#define CTRL_V2_RX_TS_BITS  (CTRL_V2_TS_BITS | TS_RX_EN)
-
-
-#define CTRL_V3_TS_BITS \
-       (TS_107 | TS_320 | TS_319 | TS_132 | TS_131 | TS_130 | TS_129 |\
-        TS_TTL_NONZERO | TS_ANNEX_F_EN | TS_ANNEX_D_EN |\
-        TS_LTYPE1_EN | VLAN_LTYPE1_EN)
-
-#define CTRL_V3_ALL_TS_MASK (CTRL_V3_TS_BITS | TS_TX_EN | TS_RX_EN)
-#define CTRL_V3_TX_TS_BITS  (CTRL_V3_TS_BITS | TS_TX_EN)
-#define CTRL_V3_RX_TS_BITS  (CTRL_V3_TS_BITS | TS_RX_EN)
-
-/* Bit definitions for the CPSW2_TS_SEQ_MTYPE register */
-#define TS_SEQ_ID_OFFSET_SHIFT   (16)    /* Time Sync Sequence ID Offset */
-#define TS_SEQ_ID_OFFSET_MASK    (0x3f)
-#define TS_MSG_TYPE_EN_SHIFT     (0)     /* Time Sync Message Type Enable */
-#define TS_MSG_TYPE_EN_MASK      (0xffff)
-
-/* The PTP event messages - Sync, Delay_Req, Pdelay_Req, and Pdelay_Resp. */
-#define EVENT_MSG_BITS ((1<<0) | (1<<1) | (1<<2) | (1<<3))
-
-/* Bit definitions for the CPSW1_TS_CTL register */
-#define CPSW_V1_TS_RX_EN               BIT(0)
-#define CPSW_V1_TS_TX_EN               BIT(4)
-#define CPSW_V1_MSG_TYPE_OFS           16
-
-/* Bit definitions for the CPSW1_TS_SEQ_LTYPE register */
-#define CPSW_V1_SEQ_ID_OFS_SHIFT       16
-
-#define CPSW_MAX_BLKS_TX               15
-#define CPSW_MAX_BLKS_TX_SHIFT         4
-#define CPSW_MAX_BLKS_RX               5
-
-struct cpsw_host_regs {
-       u32     max_blks;
-       u32     blk_cnt;
-       u32     tx_in_ctl;
-       u32     port_vlan;
-       u32     tx_pri_map;
-       u32     cpdma_tx_pri_map;
-       u32     cpdma_rx_chan_map;
-};
-
-struct cpsw_sliver_regs {
-       u32     id_ver;
-       u32     mac_control;
-       u32     mac_status;
-       u32     soft_reset;
-       u32     rx_maxlen;
-       u32     __reserved_0;
-       u32     rx_pause;
-       u32     tx_pause;
-       u32     __reserved_1;
-       u32     rx_pri_map;
-};
-
-struct cpsw_hw_stats {
-       u32     rxgoodframes;
-       u32     rxbroadcastframes;
-       u32     rxmulticastframes;
-       u32     rxpauseframes;
-       u32     rxcrcerrors;
-       u32     rxaligncodeerrors;
-       u32     rxoversizedframes;
-       u32     rxjabberframes;
-       u32     rxundersizedframes;
-       u32     rxfragments;
-       u32     __pad_0[2];
-       u32     rxoctets;
-       u32     txgoodframes;
-       u32     txbroadcastframes;
-       u32     txmulticastframes;
-       u32     txpauseframes;
-       u32     txdeferredframes;
-       u32     txcollisionframes;
-       u32     txsinglecollframes;
-       u32     txmultcollframes;
-       u32     txexcessivecollisions;
-       u32     txlatecollisions;
-       u32     txunderrun;
-       u32     txcarriersenseerrors;
-       u32     txoctets;
-       u32     octetframes64;
-       u32     octetframes65t127;
-       u32     octetframes128t255;
-       u32     octetframes256t511;
-       u32     octetframes512t1023;
-       u32     octetframes1024tup;
-       u32     netoctets;
-       u32     rxsofoverruns;
-       u32     rxmofoverruns;
-       u32     rxdmaoverruns;
-};
-
-struct cpsw_slave_data {
-       struct device_node *phy_node;
-       char            phy_id[MII_BUS_ID_SIZE];
-       int             phy_if;
-       u8              mac_addr[ETH_ALEN];
-       u16             dual_emac_res_vlan;     /* Reserved VLAN for DualEMAC */
-       struct phy      *ifphy;
-};
-
-struct cpsw_platform_data {
-       struct cpsw_slave_data  *slave_data;
-       u32     ss_reg_ofs;     /* Subsystem control register offset */
-       u32     channels;       /* number of cpdma channels (symmetric) */
-       u32     slaves;         /* number of slave cpgmac ports */
-       u32     active_slave; /* time stamping, ethtool and SIOCGMIIPHY slave */
-       u32     ale_entries;    /* ale table size */
-       u32     bd_ram_size;  /*buffer descriptor ram size */
-       u32     mac_control;    /* Mac control register */
-       u16     default_vlan;   /* Def VLAN for ALE lookup in VLAN aware mode*/
-       bool    dual_emac;      /* Enable Dual EMAC mode */
-};
-
-struct cpsw_slave {
-       void __iomem                    *regs;
-       struct cpsw_sliver_regs __iomem *sliver;
-       int                             slave_num;
-       u32                             mac_control;
-       struct cpsw_slave_data          *data;
-       struct phy_device               *phy;
-       struct net_device               *ndev;
-       u32                             port_vlan;
-};
-
-static inline u32 slave_read(struct cpsw_slave *slave, u32 offset)
-{
-       return readl_relaxed(slave->regs + offset);
-}
-
-static inline void slave_write(struct cpsw_slave *slave, u32 val, u32 offset)
-{
-       writel_relaxed(val, slave->regs + offset);
-}
-
-struct cpsw_vector {
-       struct cpdma_chan *ch;
-       int budget;
-};
-
-struct cpsw_common {
-       struct device                   *dev;
-       struct cpsw_platform_data       data;
-       struct napi_struct              napi_rx;
-       struct napi_struct              napi_tx;
-       struct cpsw_ss_regs __iomem     *regs;
-       struct cpsw_wr_regs __iomem     *wr_regs;
-       u8 __iomem                      *hw_stats;
-       struct cpsw_host_regs __iomem   *host_port_regs;
-       u32                             version;
-       u32                             coal_intvl;
-       u32                             bus_freq_mhz;
-       int                             rx_packet_max;
-       struct cpsw_slave               *slaves;
-       struct cpdma_ctlr               *dma;
-       struct cpsw_vector              txv[CPSW_MAX_QUEUES];
-       struct cpsw_vector              rxv[CPSW_MAX_QUEUES];
-       struct cpsw_ale                 *ale;
-       bool                            quirk_irq;
-       bool                            rx_irq_disabled;
-       bool                            tx_irq_disabled;
-       u32 irqs_table[IRQ_NUM];
-       struct cpts                     *cpts;
-       int                             rx_ch_num, tx_ch_num;
-       int                             speed;
-       int                             usage_count;
-};
-
-struct cpsw_priv {
-       struct net_device               *ndev;
-       struct device                   *dev;
-       u32                             msg_enable;
-       u8                              mac_addr[ETH_ALEN];
-       bool                            rx_pause;
-       bool                            tx_pause;
-       bool                            mqprio_hw;
-       int                             fifo_bw[CPSW_TC_NUM];
-       int                             shp_cfg_speed;
-       int                             tx_ts_enabled;
-       int                             rx_ts_enabled;
-       u32 emac_port;
-       struct cpsw_common *cpsw;
-};
-
-struct cpsw_stats {
-       char stat_string[ETH_GSTRING_LEN];
-       int type;
-       int sizeof_stat;
-       int stat_offset;
-};
-
-enum {
-       CPSW_STATS,
-       CPDMA_RX_STATS,
-       CPDMA_TX_STATS,
-};
-
-#define CPSW_STAT(m)           CPSW_STATS,                             \
-                               FIELD_SIZEOF(struct cpsw_hw_stats, m), \
-                               offsetof(struct cpsw_hw_stats, m)
-#define CPDMA_RX_STAT(m)       CPDMA_RX_STATS,                            \
-                               FIELD_SIZEOF(struct cpdma_chan_stats, m), \
-                               offsetof(struct cpdma_chan_stats, m)
-#define CPDMA_TX_STAT(m)       CPDMA_TX_STATS,                            \
-                               FIELD_SIZEOF(struct cpdma_chan_stats, m), \
-                               offsetof(struct cpdma_chan_stats, m)
-
-static const struct cpsw_stats cpsw_gstrings_stats[] = {
-       { "Good Rx Frames", CPSW_STAT(rxgoodframes) },
-       { "Broadcast Rx Frames", CPSW_STAT(rxbroadcastframes) },
-       { "Multicast Rx Frames", CPSW_STAT(rxmulticastframes) },
-       { "Pause Rx Frames", CPSW_STAT(rxpauseframes) },
-       { "Rx CRC Errors", CPSW_STAT(rxcrcerrors) },
-       { "Rx Align/Code Errors", CPSW_STAT(rxaligncodeerrors) },
-       { "Oversize Rx Frames", CPSW_STAT(rxoversizedframes) },
-       { "Rx Jabbers", CPSW_STAT(rxjabberframes) },
-       { "Undersize (Short) Rx Frames", CPSW_STAT(rxundersizedframes) },
-       { "Rx Fragments", CPSW_STAT(rxfragments) },
-       { "Rx Octets", CPSW_STAT(rxoctets) },
-       { "Good Tx Frames", CPSW_STAT(txgoodframes) },
-       { "Broadcast Tx Frames", CPSW_STAT(txbroadcastframes) },
-       { "Multicast Tx Frames", CPSW_STAT(txmulticastframes) },
-       { "Pause Tx Frames", CPSW_STAT(txpauseframes) },
-       { "Deferred Tx Frames", CPSW_STAT(txdeferredframes) },
-       { "Collisions", CPSW_STAT(txcollisionframes) },
-       { "Single Collision Tx Frames", CPSW_STAT(txsinglecollframes) },
-       { "Multiple Collision Tx Frames", CPSW_STAT(txmultcollframes) },
-       { "Excessive Collisions", CPSW_STAT(txexcessivecollisions) },
-       { "Late Collisions", CPSW_STAT(txlatecollisions) },
-       { "Tx Underrun", CPSW_STAT(txunderrun) },
-       { "Carrier Sense Errors", CPSW_STAT(txcarriersenseerrors) },
-       { "Tx Octets", CPSW_STAT(txoctets) },
-       { "Rx + Tx 64 Octet Frames", CPSW_STAT(octetframes64) },
-       { "Rx + Tx 65-127 Octet Frames", CPSW_STAT(octetframes65t127) },
-       { "Rx + Tx 128-255 Octet Frames", CPSW_STAT(octetframes128t255) },
-       { "Rx + Tx 256-511 Octet Frames", CPSW_STAT(octetframes256t511) },
-       { "Rx + Tx 512-1023 Octet Frames", CPSW_STAT(octetframes512t1023) },
-       { "Rx + Tx 1024-Up Octet Frames", CPSW_STAT(octetframes1024tup) },
-       { "Net Octets", CPSW_STAT(netoctets) },
-       { "Rx Start of Frame Overruns", CPSW_STAT(rxsofoverruns) },
-       { "Rx Middle of Frame Overruns", CPSW_STAT(rxmofoverruns) },
-       { "Rx DMA Overruns", CPSW_STAT(rxdmaoverruns) },
-};
-
-static const struct cpsw_stats cpsw_gstrings_ch_stats[] = {
-       { "head_enqueue", CPDMA_RX_STAT(head_enqueue) },
-       { "tail_enqueue", CPDMA_RX_STAT(tail_enqueue) },
-       { "pad_enqueue", CPDMA_RX_STAT(pad_enqueue) },
-       { "misqueued", CPDMA_RX_STAT(misqueued) },
-       { "desc_alloc_fail", CPDMA_RX_STAT(desc_alloc_fail) },
-       { "pad_alloc_fail", CPDMA_RX_STAT(pad_alloc_fail) },
-       { "runt_receive_buf", CPDMA_RX_STAT(runt_receive_buff) },
-       { "runt_transmit_buf", CPDMA_RX_STAT(runt_transmit_buff) },
-       { "empty_dequeue", CPDMA_RX_STAT(empty_dequeue) },
-       { "busy_dequeue", CPDMA_RX_STAT(busy_dequeue) },
-       { "good_dequeue", CPDMA_RX_STAT(good_dequeue) },
-       { "requeue", CPDMA_RX_STAT(requeue) },
-       { "teardown_dequeue", CPDMA_RX_STAT(teardown_dequeue) },
-};
-
-#define CPSW_STATS_COMMON_LEN  ARRAY_SIZE(cpsw_gstrings_stats)
-#define CPSW_STATS_CH_LEN      ARRAY_SIZE(cpsw_gstrings_ch_stats)
-
-#define ndev_to_cpsw(ndev) (((struct cpsw_priv *)netdev_priv(ndev))->cpsw)
-#define napi_to_cpsw(napi)     container_of(napi, struct cpsw_common, napi)
 #define for_each_slave(priv, func, arg...)                             \
        do {                                                            \
                struct cpsw_slave *slave;                               \
@@ -572,11 +77,6 @@ static const struct cpsw_stats cpsw_gstrings_ch_stats[] = {
 static int cpsw_ndo_vlan_rx_add_vid(struct net_device *ndev,
                                    __be16 proto, u16 vid);
 
-static inline int cpsw_get_slave_port(u32 slave_num)
-{
-       return slave_num + 1;
-}
-
 static void cpsw_set_promiscious(struct net_device *ndev, bool enable)
 {
        struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
@@ -653,13 +153,6 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable)
        }
 }
 
-struct addr_sync_ctx {
-       struct net_device *ndev;
-       const u8 *addr;         /* address to be synched */
-       int consumed;           /* number of address instances */
-       int flush;              /* flush flag */
-};
-
 /**
  * cpsw_set_mc - adds multicast entry to the table if it's not added or deletes
  * if it's not deleted
@@ -800,12 +293,17 @@ static int cpsw_purge_all_mc(struct net_device *ndev, const u8 *addr, int num)
 
 static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
 {
-       struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
+       struct cpsw_priv *priv = netdev_priv(ndev);
+       struct cpsw_common *cpsw = priv->cpsw;
+       int slave_port = -1;
+
+       if (cpsw->data.dual_emac)
+               slave_port = priv->emac_port + 1;
 
        if (ndev->flags & IFF_PROMISC) {
                /* Enable promiscuous mode */
                cpsw_set_promiscious(ndev, true);
-               cpsw_ale_set_allmulti(cpsw->ale, IFF_ALLMULTI);
+               cpsw_ale_set_allmulti(cpsw->ale, IFF_ALLMULTI, slave_port);
                return;
        } else {
                /* Disable promiscuous mode */
@@ -813,14 +311,15 @@ static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
        }
 
        /* Restore allmulti on vlans if necessary */
-       cpsw_ale_set_allmulti(cpsw->ale, ndev->flags & IFF_ALLMULTI);
+       cpsw_ale_set_allmulti(cpsw->ale,
+                             ndev->flags & IFF_ALLMULTI, slave_port);
 
        /* add/remove mcast address either for real netdev or for vlan */
        __hw_addr_ref_sync_dev(&ndev->mc, ndev, cpsw_add_mc_addr,
                               cpsw_del_mc_addr);
 }
 
-static void cpsw_intr_enable(struct cpsw_common *cpsw)
+void cpsw_intr_enable(struct cpsw_common *cpsw)
 {
        writel_relaxed(0xFF, &cpsw->wr_regs->tx_en);
        writel_relaxed(0xFF, &cpsw->wr_regs->rx_en);
@@ -829,7 +328,7 @@ static void cpsw_intr_enable(struct cpsw_common *cpsw)
        return;
 }
 
-static void cpsw_intr_disable(struct cpsw_common *cpsw)
+void cpsw_intr_disable(struct cpsw_common *cpsw)
 {
        writel_relaxed(0, &cpsw->wr_regs->tx_en);
        writel_relaxed(0, &cpsw->wr_regs->rx_en);
@@ -838,7 +337,7 @@ static void cpsw_intr_disable(struct cpsw_common *cpsw)
        return;
 }
 
-static void cpsw_tx_handler(void *token, int len, int status)
+void cpsw_tx_handler(void *token, int len, int status)
 {
        struct netdev_queue     *txq;
        struct sk_buff          *skb = token;
@@ -970,11 +469,9 @@ requeue:
                dev_kfree_skb_any(new_skb);
 }
 
-static void cpsw_split_res(struct net_device *ndev)
+void cpsw_split_res(struct cpsw_common *cpsw)
 {
-       struct cpsw_priv *priv = netdev_priv(ndev);
        u32 consumed_rate = 0, bigest_rate = 0;
-       struct cpsw_common *cpsw = priv->cpsw;
        struct cpsw_vector *txv = cpsw->txv;
        int i, ch_weight, rlim_ch_num = 0;
        int budget, bigest_rate_ch = 0;
@@ -1254,29 +751,32 @@ static void _cpsw_adjust_link(struct cpsw_slave *slave,
        slave_port = cpsw_get_slave_port(slave->slave_num);
 
        if (phy->link) {
-               mac_control = cpsw->data.mac_control;
-
-               /* enable forwarding */
-               cpsw_ale_control_set(cpsw->ale, slave_port,
-                                    ALE_PORT_STATE, ALE_PORT_STATE_FORWARD);
+               mac_control = CPSW_SL_CTL_GMII_EN;
 
                if (phy->speed == 1000)
-                       mac_control |= BIT(7);  /* GIGABITEN    */
+                       mac_control |= CPSW_SL_CTL_GIG;
                if (phy->duplex)
-                       mac_control |= BIT(0);  /* FULLDUPLEXEN */
+                       mac_control |= CPSW_SL_CTL_FULLDUPLEX;
 
                /* set speed_in input in case RMII mode is used in 100Mbps */
                if (phy->speed == 100)
-                       mac_control |= BIT(15);
+                       mac_control |= CPSW_SL_CTL_IFCTL_A;
                /* in band mode only works in 10Mbps RGMII mode */
                else if ((phy->speed == 10) && phy_interface_is_rgmii(phy))
-                       mac_control |= BIT(18); /* In Band mode */
+                       mac_control |= CPSW_SL_CTL_EXT_EN; /* In Band mode */
 
                if (priv->rx_pause)
-                       mac_control |= BIT(3);
+                       mac_control |= CPSW_SL_CTL_RX_FLOW_EN;
 
                if (priv->tx_pause)
-                       mac_control |= BIT(4);
+                       mac_control |= CPSW_SL_CTL_TX_FLOW_EN;
+
+               if (mac_control != slave->mac_control)
+                       cpsw_sl_ctl_set(slave->mac_sl, mac_control);
+
+               /* enable forwarding */
+               cpsw_ale_control_set(cpsw->ale, slave_port,
+                                    ALE_PORT_STATE, ALE_PORT_STATE_FORWARD);
 
                *link = true;
 
@@ -1290,12 +790,14 @@ static void _cpsw_adjust_link(struct cpsw_slave *slave,
                /* disable forwarding */
                cpsw_ale_control_set(cpsw->ale, slave_port,
                                     ALE_PORT_STATE, ALE_PORT_STATE_DISABLE);
+
+               cpsw_sl_wait_for_idle(slave->mac_sl, 100);
+
+               cpsw_sl_ctl_reset(slave->mac_sl);
        }
 
-       if (mac_control != slave->mac_control) {
+       if (mac_control != slave->mac_control)
                phy_print_status(phy);
-               writel_relaxed(mac_control, &slave->sliver->mac_control);
-       }
 
        slave->mac_control = mac_control;
 }
@@ -1348,7 +850,7 @@ static void cpsw_adjust_link(struct net_device *ndev)
 
        if (link) {
                if (cpsw_need_resplit(cpsw))
-                       cpsw_split_res(ndev);
+                       cpsw_split_res(cpsw);
 
                netif_carrier_on(ndev);
                if (netif_running(ndev))
@@ -1359,167 +861,6 @@ static void cpsw_adjust_link(struct net_device *ndev)
        }
 }
 
-static int cpsw_get_coalesce(struct net_device *ndev,
-                               struct ethtool_coalesce *coal)
-{
-       struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
-
-       coal->rx_coalesce_usecs = cpsw->coal_intvl;
-       return 0;
-}
-
-static int cpsw_set_coalesce(struct net_device *ndev,
-                               struct ethtool_coalesce *coal)
-{
-       struct cpsw_priv *priv = netdev_priv(ndev);
-       u32 int_ctrl;
-       u32 num_interrupts = 0;
-       u32 prescale = 0;
-       u32 addnl_dvdr = 1;
-       u32 coal_intvl = 0;
-       struct cpsw_common *cpsw = priv->cpsw;
-
-       coal_intvl = coal->rx_coalesce_usecs;
-
-       int_ctrl =  readl(&cpsw->wr_regs->int_control);
-       prescale = cpsw->bus_freq_mhz * 4;
-
-       if (!coal->rx_coalesce_usecs) {
-               int_ctrl &= ~(CPSW_INTPRESCALE_MASK | CPSW_INTPACEEN);
-               goto update_return;
-       }
-
-       if (coal_intvl < CPSW_CMINTMIN_INTVL)
-               coal_intvl = CPSW_CMINTMIN_INTVL;
-
-       if (coal_intvl > CPSW_CMINTMAX_INTVL) {
-               /* Interrupt pacer works with 4us Pulse, we can
-                * throttle further by dilating the 4us pulse.
-                */
-               addnl_dvdr = CPSW_INTPRESCALE_MASK / prescale;
-
-               if (addnl_dvdr > 1) {
-                       prescale *= addnl_dvdr;
-                       if (coal_intvl > (CPSW_CMINTMAX_INTVL * addnl_dvdr))
-                               coal_intvl = (CPSW_CMINTMAX_INTVL
-                                               * addnl_dvdr);
-               } else {
-                       addnl_dvdr = 1;
-                       coal_intvl = CPSW_CMINTMAX_INTVL;
-               }
-       }
-
-       num_interrupts = (1000 * addnl_dvdr) / coal_intvl;
-       writel(num_interrupts, &cpsw->wr_regs->rx_imax);
-       writel(num_interrupts, &cpsw->wr_regs->tx_imax);
-
-       int_ctrl |= CPSW_INTPACEEN;
-       int_ctrl &= (~CPSW_INTPRESCALE_MASK);
-       int_ctrl |= (prescale & CPSW_INTPRESCALE_MASK);
-
-update_return:
-       writel(int_ctrl, &cpsw->wr_regs->int_control);
-
-       cpsw_notice(priv, timer, "Set coalesce to %d usecs.\n", coal_intvl);
-       cpsw->coal_intvl = coal_intvl;
-
-       return 0;
-}
-
-static int cpsw_get_sset_count(struct net_device *ndev, int sset)
-{
-       struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
-
-       switch (sset) {
-       case ETH_SS_STATS:
-               return (CPSW_STATS_COMMON_LEN +
-                      (cpsw->rx_ch_num + cpsw->tx_ch_num) *
-                      CPSW_STATS_CH_LEN);
-       default:
-               return -EOPNOTSUPP;
-       }
-}
-
-static void cpsw_add_ch_strings(u8 **p, int ch_num, int rx_dir)
-{
-       int ch_stats_len;
-       int line;
-       int i;
-
-       ch_stats_len = CPSW_STATS_CH_LEN * ch_num;
-       for (i = 0; i < ch_stats_len; i++) {
-               line = i % CPSW_STATS_CH_LEN;
-               snprintf(*p, ETH_GSTRING_LEN,
-                        "%s DMA chan %ld: %s", rx_dir ? "Rx" : "Tx",
-                        (long)(i / CPSW_STATS_CH_LEN),
-                        cpsw_gstrings_ch_stats[line].stat_string);
-               *p += ETH_GSTRING_LEN;
-       }
-}
-
-static void cpsw_get_strings(struct net_device *ndev, u32 stringset, u8 *data)
-{
-       struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
-       u8 *p = data;
-       int i;
-
-       switch (stringset) {
-       case ETH_SS_STATS:
-               for (i = 0; i < CPSW_STATS_COMMON_LEN; i++) {
-                       memcpy(p, cpsw_gstrings_stats[i].stat_string,
-                              ETH_GSTRING_LEN);
-                       p += ETH_GSTRING_LEN;
-               }
-
-               cpsw_add_ch_strings(&p, cpsw->rx_ch_num, 1);
-               cpsw_add_ch_strings(&p, cpsw->tx_ch_num, 0);
-               break;
-       }
-}
-
-static void cpsw_get_ethtool_stats(struct net_device *ndev,
-                                   struct ethtool_stats *stats, u64 *data)
-{
-       u8 *p;
-       struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
-       struct cpdma_chan_stats ch_stats;
-       int i, l, ch;
-
-       /* Collect Davinci CPDMA stats for Rx and Tx Channel */
-       for (l = 0; l < CPSW_STATS_COMMON_LEN; l++)
-               data[l] = readl(cpsw->hw_stats +
-                               cpsw_gstrings_stats[l].stat_offset);
-
-       for (ch = 0; ch < cpsw->rx_ch_num; ch++) {
-               cpdma_chan_get_stats(cpsw->rxv[ch].ch, &ch_stats);
-               for (i = 0; i < CPSW_STATS_CH_LEN; i++, l++) {
-                       p = (u8 *)&ch_stats +
-                               cpsw_gstrings_ch_stats[i].stat_offset;
-                       data[l] = *(u32 *)p;
-               }
-       }
-
-       for (ch = 0; ch < cpsw->tx_ch_num; ch++) {
-               cpdma_chan_get_stats(cpsw->txv[ch].ch, &ch_stats);
-               for (i = 0; i < CPSW_STATS_CH_LEN; i++, l++) {
-                       p = (u8 *)&ch_stats +
-                               cpsw_gstrings_ch_stats[i].stat_offset;
-                       data[l] = *(u32 *)p;
-               }
-       }
-}
-
-static inline int cpsw_tx_packet_submit(struct cpsw_priv *priv,
-                                       struct sk_buff *skb,
-                                       struct cpdma_chan *txch)
-{
-       struct cpsw_common *cpsw = priv->cpsw;
-
-       skb_tx_timestamp(skb);
-       return cpdma_chan_submit(txch, skb, skb->data, skb->len,
-                                priv->emac_port + cpsw->data.dual_emac);
-}
-
 static inline void cpsw_add_dual_emac_def_ale_entries(
                struct cpsw_priv *priv, struct cpsw_slave *slave,
                u32 slave_port)
@@ -1542,24 +883,18 @@ static inline void cpsw_add_dual_emac_def_ale_entries(
                             ALE_PORT_DROP_UNKNOWN_VLAN, 1);
 }
 
-static void soft_reset_slave(struct cpsw_slave *slave)
-{
-       char name[32];
-
-       snprintf(name, sizeof(name), "slave-%d", slave->slave_num);
-       soft_reset(name, &slave->sliver->soft_reset);
-}
-
 static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv)
 {
        u32 slave_port;
        struct phy_device *phy;
        struct cpsw_common *cpsw = priv->cpsw;
 
-       soft_reset_slave(slave);
+       cpsw_sl_reset(slave->mac_sl, 100);
+       cpsw_sl_ctl_reset(slave->mac_sl);
 
        /* setup priority mapping */
-       writel_relaxed(RX_PRIORITY_MAPPING, &slave->sliver->rx_pri_map);
+       cpsw_sl_reg_write(slave->mac_sl, CPSW_SL_RX_PRI_MAP,
+                         RX_PRIORITY_MAPPING);
 
        switch (cpsw->version) {
        case CPSW_VERSION_1:
@@ -1585,7 +920,8 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv)
        }
 
        /* setup max packet size, and mac address */
-       writel_relaxed(cpsw->rx_packet_max, &slave->sliver->rx_maxlen);
+       cpsw_sl_reg_write(slave->mac_sl, CPSW_SL_RX_MAXLEN,
+                         cpsw->rx_packet_max);
        cpsw_set_slave_mac(slave, priv);
 
        slave->mac_control = 0; /* no link yet */
@@ -1696,7 +1032,7 @@ static void cpsw_init_host_port(struct cpsw_priv *priv)
        }
 }
 
-static int cpsw_fill_rx_channels(struct cpsw_priv *priv)
+int cpsw_fill_rx_channels(struct cpsw_priv *priv)
 {
        struct cpsw_common *cpsw = priv->cpsw;
        struct sk_buff *skb;
@@ -1748,7 +1084,8 @@ static void cpsw_slave_stop(struct cpsw_slave *slave, struct cpsw_common *cpsw)
        slave->phy = NULL;
        cpsw_ale_control_set(cpsw->ale, slave_port,
                             ALE_PORT_STATE, ALE_PORT_STATE_DISABLE);
-       soft_reset_slave(slave);
+       cpsw_sl_reset(slave->mac_sl, 100);
+       cpsw_sl_ctl_reset(slave->mac_sl);
 }
 
 static int cpsw_tc_to_fifo(int tc, int num_tc)
@@ -2114,7 +1451,7 @@ static int cpsw_ndo_stop(struct net_device *ndev)
        for_each_slave(priv, cpsw_slave_stop, cpsw);
 
        if (cpsw_need_resplit(cpsw))
-               cpsw_split_res(ndev);
+               cpsw_split_res(cpsw);
 
        cpsw->usage_count--;
        pm_runtime_put_sync(cpsw->dev);
@@ -2147,7 +1484,9 @@ static netdev_tx_t cpsw_ndo_start_xmit(struct sk_buff *skb,
 
        txch = cpsw->txv[q_idx].ch;
        txq = netdev_get_tx_queue(ndev, q_idx);
-       ret = cpsw_tx_packet_submit(priv, skb, txch);
+       skb_tx_timestamp(skb);
+       ret = cpdma_chan_submit(txch, skb, skb->data, skb->len,
+                               priv->emac_port + cpsw->data.dual_emac);
        if (unlikely(ret != 0)) {
                cpsw_err(priv, tx_err, "desc submit failed\n");
                goto fail;
@@ -2418,18 +1757,6 @@ static int cpsw_ndo_set_mac_address(struct net_device *ndev, void *p)
        return 0;
 }
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-static void cpsw_ndo_poll_controller(struct net_device *ndev)
-{
-       struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
-
-       cpsw_intr_disable(cpsw);
-       cpsw_rx_interrupt(cpsw->irqs_table[0], cpsw);
-       cpsw_tx_interrupt(cpsw->irqs_table[1], cpsw);
-       cpsw_intr_enable(cpsw);
-}
-#endif
-
 static inline int cpsw_add_vlan_ale_entry(struct cpsw_priv *priv,
                                unsigned short vid)
 {
@@ -2601,7 +1928,7 @@ static int cpsw_ndo_set_tx_maxrate(struct net_device *ndev, int queue, u32 rate)
                netdev_get_tx_queue(slave->ndev, queue)->tx_maxrate = rate;
        }
 
-       cpsw_split_res(ndev);
+       cpsw_split_res(cpsw);
        return ret;
 }
 
@@ -2677,6 +2004,18 @@ static int cpsw_ndo_setup_tc(struct net_device *ndev, enum tc_setup_type type,
        }
 }
 
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void cpsw_ndo_poll_controller(struct net_device *ndev)
+{
+       struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
+
+       cpsw_intr_disable(cpsw);
+       cpsw_rx_interrupt(cpsw->irqs_table[0], cpsw);
+       cpsw_tx_interrupt(cpsw->irqs_table[1], cpsw);
+       cpsw_intr_enable(cpsw);
+}
+#endif
+
 static const struct net_device_ops cpsw_netdev_ops = {
        .ndo_open               = cpsw_ndo_open,
        .ndo_stop               = cpsw_ndo_stop,
@@ -2695,25 +2034,6 @@ static const struct net_device_ops cpsw_netdev_ops = {
        .ndo_setup_tc           = cpsw_ndo_setup_tc,
 };
 
-static int cpsw_get_regs_len(struct net_device *ndev)
-{
-       struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
-
-       return cpsw->data.ale_entries * ALE_ENTRY_WORDS * sizeof(u32);
-}
-
-static void cpsw_get_regs(struct net_device *ndev,
-                         struct ethtool_regs *regs, void *p)
-{
-       u32 *reg = p;
-       struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
-
-       /* update CPSW IP version */
-       regs->version = cpsw->version;
-
-       cpsw_ale_dump(cpsw->ale, reg);
-}
-
 static void cpsw_get_drvinfo(struct net_device *ndev,
                             struct ethtool_drvinfo *info)
 {
@@ -2725,119 +2045,6 @@ static void cpsw_get_drvinfo(struct net_device *ndev,
        strlcpy(info->bus_info, pdev->name, sizeof(info->bus_info));
 }
 
-static u32 cpsw_get_msglevel(struct net_device *ndev)
-{
-       struct cpsw_priv *priv = netdev_priv(ndev);
-       return priv->msg_enable;
-}
-
-static void cpsw_set_msglevel(struct net_device *ndev, u32 value)
-{
-       struct cpsw_priv *priv = netdev_priv(ndev);
-       priv->msg_enable = value;
-}
-
-#if IS_ENABLED(CONFIG_TI_CPTS)
-static int cpsw_get_ts_info(struct net_device *ndev,
-                           struct ethtool_ts_info *info)
-{
-       struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
-
-       info->so_timestamping =
-               SOF_TIMESTAMPING_TX_HARDWARE |
-               SOF_TIMESTAMPING_TX_SOFTWARE |
-               SOF_TIMESTAMPING_RX_HARDWARE |
-               SOF_TIMESTAMPING_RX_SOFTWARE |
-               SOF_TIMESTAMPING_SOFTWARE |
-               SOF_TIMESTAMPING_RAW_HARDWARE;
-       info->phc_index = cpsw->cpts->phc_index;
-       info->tx_types =
-               (1 << HWTSTAMP_TX_OFF) |
-               (1 << HWTSTAMP_TX_ON);
-       info->rx_filters =
-               (1 << HWTSTAMP_FILTER_NONE) |
-               (1 << HWTSTAMP_FILTER_PTP_V1_L4_EVENT) |
-               (1 << HWTSTAMP_FILTER_PTP_V2_EVENT);
-       return 0;
-}
-#else
-static int cpsw_get_ts_info(struct net_device *ndev,
-                           struct ethtool_ts_info *info)
-{
-       info->so_timestamping =
-               SOF_TIMESTAMPING_TX_SOFTWARE |
-               SOF_TIMESTAMPING_RX_SOFTWARE |
-               SOF_TIMESTAMPING_SOFTWARE;
-       info->phc_index = -1;
-       info->tx_types = 0;
-       info->rx_filters = 0;
-       return 0;
-}
-#endif
-
-static int cpsw_get_link_ksettings(struct net_device *ndev,
-                                  struct ethtool_link_ksettings *ecmd)
-{
-       struct cpsw_priv *priv = netdev_priv(ndev);
-       struct cpsw_common *cpsw = priv->cpsw;
-       int slave_no = cpsw_slave_index(cpsw, priv);
-
-       if (!cpsw->slaves[slave_no].phy)
-               return -EOPNOTSUPP;
-
-       phy_ethtool_ksettings_get(cpsw->slaves[slave_no].phy, ecmd);
-       return 0;
-}
-
-static int cpsw_set_link_ksettings(struct net_device *ndev,
-                                  const struct ethtool_link_ksettings *ecmd)
-{
-       struct cpsw_priv *priv = netdev_priv(ndev);
-       struct cpsw_common *cpsw = priv->cpsw;
-       int slave_no = cpsw_slave_index(cpsw, priv);
-
-       if (cpsw->slaves[slave_no].phy)
-               return phy_ethtool_ksettings_set(cpsw->slaves[slave_no].phy,
-                                                ecmd);
-       else
-               return -EOPNOTSUPP;
-}
-
-static void cpsw_get_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
-{
-       struct cpsw_priv *priv = netdev_priv(ndev);
-       struct cpsw_common *cpsw = priv->cpsw;
-       int slave_no = cpsw_slave_index(cpsw, priv);
-
-       wol->supported = 0;
-       wol->wolopts = 0;
-
-       if (cpsw->slaves[slave_no].phy)
-               phy_ethtool_get_wol(cpsw->slaves[slave_no].phy, wol);
-}
-
-static int cpsw_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
-{
-       struct cpsw_priv *priv = netdev_priv(ndev);
-       struct cpsw_common *cpsw = priv->cpsw;
-       int slave_no = cpsw_slave_index(cpsw, priv);
-
-       if (cpsw->slaves[slave_no].phy)
-               return phy_ethtool_set_wol(cpsw->slaves[slave_no].phy, wol);
-       else
-               return -EOPNOTSUPP;
-}
-
-static void cpsw_get_pauseparam(struct net_device *ndev,
-                               struct ethtool_pauseparam *pause)
-{
-       struct cpsw_priv *priv = netdev_priv(ndev);
-
-       pause->autoneg = AUTONEG_DISABLE;
-       pause->rx_pause = priv->rx_pause ? true : false;
-       pause->tx_pause = priv->tx_pause ? true : false;
-}
-
 static int cpsw_set_pauseparam(struct net_device *ndev,
                               struct ethtool_pauseparam *pause)
 {
@@ -2851,316 +2058,10 @@ static int cpsw_set_pauseparam(struct net_device *ndev,
        return 0;
 }
 
-static int cpsw_ethtool_op_begin(struct net_device *ndev)
+static int cpsw_set_channels(struct net_device *ndev,
+                            struct ethtool_channels *chs)
 {
-       struct cpsw_priv *priv = netdev_priv(ndev);
-       struct cpsw_common *cpsw = priv->cpsw;
-       int ret;
-
-       ret = pm_runtime_get_sync(cpsw->dev);
-       if (ret < 0) {
-               cpsw_err(priv, drv, "ethtool begin failed %d\n", ret);
-               pm_runtime_put_noidle(cpsw->dev);
-       }
-
-       return ret;
-}
-
-static void cpsw_ethtool_op_complete(struct net_device *ndev)
-{
-       struct cpsw_priv *priv = netdev_priv(ndev);
-       int ret;
-
-       ret = pm_runtime_put(priv->cpsw->dev);
-       if (ret < 0)
-               cpsw_err(priv, drv, "ethtool complete failed %d\n", ret);
-}
-
-static void cpsw_get_channels(struct net_device *ndev,
-                             struct ethtool_channels *ch)
-{
-       struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
-
-       ch->max_rx = cpsw->quirk_irq ? 1 : CPSW_MAX_QUEUES;
-       ch->max_tx = cpsw->quirk_irq ? 1 : CPSW_MAX_QUEUES;
-       ch->max_combined = 0;
-       ch->max_other = 0;
-       ch->other_count = 0;
-       ch->rx_count = cpsw->rx_ch_num;
-       ch->tx_count = cpsw->tx_ch_num;
-       ch->combined_count = 0;
-}
-
-static int cpsw_check_ch_settings(struct cpsw_common *cpsw,
-                                 struct ethtool_channels *ch)
-{
-       if (cpsw->quirk_irq) {
-               dev_err(cpsw->dev, "Maximum one tx/rx queue is allowed");
-               return -EOPNOTSUPP;
-       }
-
-       if (ch->combined_count)
-               return -EINVAL;
-
-       /* verify we have at least one channel in each direction */
-       if (!ch->rx_count || !ch->tx_count)
-               return -EINVAL;
-
-       if (ch->rx_count > cpsw->data.channels ||
-           ch->tx_count > cpsw->data.channels)
-               return -EINVAL;
-
-       return 0;
-}
-
-static int cpsw_update_channels_res(struct cpsw_priv *priv, int ch_num, int rx)
-{
-       struct cpsw_common *cpsw = priv->cpsw;
-       void (*handler)(void *, int, int);
-       struct netdev_queue *queue;
-       struct cpsw_vector *vec;
-       int ret, *ch, vch;
-
-       if (rx) {
-               ch = &cpsw->rx_ch_num;
-               vec = cpsw->rxv;
-               handler = cpsw_rx_handler;
-       } else {
-               ch = &cpsw->tx_ch_num;
-               vec = cpsw->txv;
-               handler = cpsw_tx_handler;
-       }
-
-       while (*ch < ch_num) {
-               vch = rx ? *ch : 7 - *ch;
-               vec[*ch].ch = cpdma_chan_create(cpsw->dma, vch, handler, rx);
-               queue = netdev_get_tx_queue(priv->ndev, *ch);
-               queue->tx_maxrate = 0;
-
-               if (IS_ERR(vec[*ch].ch))
-                       return PTR_ERR(vec[*ch].ch);
-
-               if (!vec[*ch].ch)
-                       return -EINVAL;
-
-               cpsw_info(priv, ifup, "created new %d %s channel\n", *ch,
-                         (rx ? "rx" : "tx"));
-               (*ch)++;
-       }
-
-       while (*ch > ch_num) {
-               (*ch)--;
-
-               ret = cpdma_chan_destroy(vec[*ch].ch);
-               if (ret)
-                       return ret;
-
-               cpsw_info(priv, ifup, "destroyed %d %s channel\n", *ch,
-                         (rx ? "rx" : "tx"));
-       }
-
-       return 0;
-}
-
-static int cpsw_update_channels(struct cpsw_priv *priv,
-                               struct ethtool_channels *ch)
-{
-       int ret;
-
-       ret = cpsw_update_channels_res(priv, ch->rx_count, 1);
-       if (ret)
-               return ret;
-
-       ret = cpsw_update_channels_res(priv, ch->tx_count, 0);
-       if (ret)
-               return ret;
-
-       return 0;
-}
-
-static void cpsw_suspend_data_pass(struct net_device *ndev)
-{
-       struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
-       struct cpsw_slave *slave;
-       int i;
-
-       /* Disable NAPI scheduling */
-       cpsw_intr_disable(cpsw);
-
-       /* Stop all transmit queues for every network device.
-        * Disable re-using rx descriptors with dormant_on.
-        */
-       for (i = cpsw->data.slaves, slave = cpsw->slaves; i; i--, slave++) {
-               if (!(slave->ndev && netif_running(slave->ndev)))
-                       continue;
-
-               netif_tx_stop_all_queues(slave->ndev);
-               netif_dormant_on(slave->ndev);
-       }
-
-       /* Handle rest of tx packets and stop cpdma channels */
-       cpdma_ctlr_stop(cpsw->dma);
-}
-
-static int cpsw_resume_data_pass(struct net_device *ndev)
-{
-       struct cpsw_priv *priv = netdev_priv(ndev);
-       struct cpsw_common *cpsw = priv->cpsw;
-       struct cpsw_slave *slave;
-       int i, ret;
-
-       /* Allow rx packets handling */
-       for (i = cpsw->data.slaves, slave = cpsw->slaves; i; i--, slave++)
-               if (slave->ndev && netif_running(slave->ndev))
-                       netif_dormant_off(slave->ndev);
-
-       /* After this receive is started */
-       if (cpsw->usage_count) {
-               ret = cpsw_fill_rx_channels(priv);
-               if (ret)
-                       return ret;
-
-               cpdma_ctlr_start(cpsw->dma);
-               cpsw_intr_enable(cpsw);
-       }
-
-       /* Resume transmit for every affected interface */
-       for (i = cpsw->data.slaves, slave = cpsw->slaves; i; i--, slave++)
-               if (slave->ndev && netif_running(slave->ndev))
-                       netif_tx_start_all_queues(slave->ndev);
-
-       return 0;
-}
-
-static int cpsw_set_channels(struct net_device *ndev,
-                            struct ethtool_channels *chs)
-{
-       struct cpsw_priv *priv = netdev_priv(ndev);
-       struct cpsw_common *cpsw = priv->cpsw;
-       struct cpsw_slave *slave;
-       int i, ret;
-
-       ret = cpsw_check_ch_settings(cpsw, chs);
-       if (ret < 0)
-               return ret;
-
-       cpsw_suspend_data_pass(ndev);
-       ret = cpsw_update_channels(priv, chs);
-       if (ret)
-               goto err;
-
-       for (i = cpsw->data.slaves, slave = cpsw->slaves; i; i--, slave++) {
-               if (!(slave->ndev && netif_running(slave->ndev)))
-                       continue;
-
-               /* Inform stack about new count of queues */
-               ret = netif_set_real_num_tx_queues(slave->ndev,
-                                                  cpsw->tx_ch_num);
-               if (ret) {
-                       dev_err(priv->dev, "cannot set real number of tx queues\n");
-                       goto err;
-               }
-
-               ret = netif_set_real_num_rx_queues(slave->ndev,
-                                                  cpsw->rx_ch_num);
-               if (ret) {
-                       dev_err(priv->dev, "cannot set real number of rx queues\n");
-                       goto err;
-               }
-       }
-
-       if (cpsw->usage_count)
-               cpsw_split_res(ndev);
-
-       ret = cpsw_resume_data_pass(ndev);
-       if (!ret)
-               return 0;
-err:
-       dev_err(priv->dev, "cannot update channels number, closing device\n");
-       dev_close(ndev);
-       return ret;
-}
-
-static int cpsw_get_eee(struct net_device *ndev, struct ethtool_eee *edata)
-{
-       struct cpsw_priv *priv = netdev_priv(ndev);
-       struct cpsw_common *cpsw = priv->cpsw;
-       int slave_no = cpsw_slave_index(cpsw, priv);
-
-       if (cpsw->slaves[slave_no].phy)
-               return phy_ethtool_get_eee(cpsw->slaves[slave_no].phy, edata);
-       else
-               return -EOPNOTSUPP;
-}
-
-static int cpsw_set_eee(struct net_device *ndev, struct ethtool_eee *edata)
-{
-       struct cpsw_priv *priv = netdev_priv(ndev);
-       struct cpsw_common *cpsw = priv->cpsw;
-       int slave_no = cpsw_slave_index(cpsw, priv);
-
-       if (cpsw->slaves[slave_no].phy)
-               return phy_ethtool_set_eee(cpsw->slaves[slave_no].phy, edata);
-       else
-               return -EOPNOTSUPP;
-}
-
-static int cpsw_nway_reset(struct net_device *ndev)
-{
-       struct cpsw_priv *priv = netdev_priv(ndev);
-       struct cpsw_common *cpsw = priv->cpsw;
-       int slave_no = cpsw_slave_index(cpsw, priv);
-
-       if (cpsw->slaves[slave_no].phy)
-               return genphy_restart_aneg(cpsw->slaves[slave_no].phy);
-       else
-               return -EOPNOTSUPP;
-}
-
-static void cpsw_get_ringparam(struct net_device *ndev,
-                              struct ethtool_ringparam *ering)
-{
-       struct cpsw_priv *priv = netdev_priv(ndev);
-       struct cpsw_common *cpsw = priv->cpsw;
-
-       /* not supported */
-       ering->tx_max_pending = 0;
-       ering->tx_pending = cpdma_get_num_tx_descs(cpsw->dma);
-       ering->rx_max_pending = descs_pool_size - CPSW_MAX_QUEUES;
-       ering->rx_pending = cpdma_get_num_rx_descs(cpsw->dma);
-}
-
-static int cpsw_set_ringparam(struct net_device *ndev,
-                             struct ethtool_ringparam *ering)
-{
-       struct cpsw_priv *priv = netdev_priv(ndev);
-       struct cpsw_common *cpsw = priv->cpsw;
-       int ret;
-
-       /* ignore ering->tx_pending - only rx_pending adjustment is supported */
-
-       if (ering->rx_mini_pending || ering->rx_jumbo_pending ||
-           ering->rx_pending < CPSW_MAX_QUEUES ||
-           ering->rx_pending > (descs_pool_size - CPSW_MAX_QUEUES))
-               return -EINVAL;
-
-       if (ering->rx_pending == cpdma_get_num_rx_descs(cpsw->dma))
-               return 0;
-
-       cpsw_suspend_data_pass(ndev);
-
-       cpdma_set_num_rx_descs(cpsw->dma, ering->rx_pending);
-
-       if (cpsw->usage_count)
-               cpdma_chan_split_pool(cpsw->dma);
-
-       ret = cpsw_resume_data_pass(ndev);
-       if (!ret)
-               return 0;
-
-       dev_err(&ndev->dev, "cannot set ring params, closing device\n");
-       dev_close(ndev);
-       return ret;
+       return cpsw_set_channels_common(ndev, chs, cpsw_rx_handler);
 }
 
 static const struct ethtool_ops cpsw_ethtool_ops = {
@@ -3193,19 +2094,6 @@ static const struct ethtool_ops cpsw_ethtool_ops = {
        .set_ringparam = cpsw_set_ringparam,
 };
 
-static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_common *cpsw,
-                           u32 slave_reg_ofs, u32 sliver_reg_ofs)
-{
-       void __iomem            *regs = cpsw->regs;
-       int                     slave_num = slave->slave_num;
-       struct cpsw_slave_data  *data = cpsw->data.slave_data + slave_num;
-
-       slave->data     = data;
-       slave->regs     = regs + slave_reg_ofs;
-       slave->sliver   = regs + sliver_reg_ofs;
-       slave->port_vlan = data->dual_emac_res_vlan;
-}
-
 static int cpsw_probe_dt(struct cpsw_platform_data *data,
                         struct platform_device *pdev)
 {
@@ -3344,8 +2232,8 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data,
 
 no_phy_slave:
                mac_addr = of_get_mac_address(slave_node);
-               if (mac_addr) {
-                       memcpy(slave_data->mac_addr, mac_addr, ETH_ALEN);
+               if (!IS_ERR(mac_addr)) {
+                       ether_addr_copy(slave_data->mac_addr, mac_addr);
                } else {
                        ret = ti_cm_get_macid(&pdev->dev, i,
                                              slave_data->mac_addr);
@@ -3408,7 +2296,8 @@ static int cpsw_probe_dual_emac(struct cpsw_priv *priv)
        struct cpsw_priv                *priv_sl2;
        int ret = 0;
 
-       ndev = alloc_etherdev_mq(sizeof(struct cpsw_priv), CPSW_MAX_QUEUES);
+       ndev = devm_alloc_etherdev_mqs(cpsw->dev, sizeof(struct cpsw_priv),
+                                      CPSW_MAX_QUEUES, CPSW_MAX_QUEUES);
        if (!ndev) {
                dev_err(cpsw->dev, "cpsw: error allocating net_device\n");
                return -ENOMEM;
@@ -3442,11 +2331,8 @@ static int cpsw_probe_dual_emac(struct cpsw_priv *priv)
        /* register the network device */
        SET_NETDEV_DEV(ndev, cpsw->dev);
        ret = register_netdev(ndev);
-       if (ret) {
+       if (ret)
                dev_err(cpsw->dev, "cpsw: error registering net device\n");
-               free_netdev(ndev);
-               ret = -ENODEV;
-       }
 
        return ret;
 }
@@ -3467,63 +2353,74 @@ static const struct soc_device_attribute cpsw_soc_devices[] = {
 
 static int cpsw_probe(struct platform_device *pdev)
 {
+       struct device                   *dev = &pdev->dev;
        struct clk                      *clk;
        struct cpsw_platform_data       *data;
        struct net_device               *ndev;
        struct cpsw_priv                *priv;
-       struct cpdma_params             dma_params;
-       struct cpsw_ale_params          ale_params;
        void __iomem                    *ss_regs;
-       void __iomem                    *cpts_regs;
        struct resource                 *res, *ss_res;
        struct gpio_descs               *mode;
-       u32 slave_offset, sliver_offset, slave_size;
        const struct soc_device_attribute *soc;
        struct cpsw_common              *cpsw;
-       int ret = 0, i, ch;
+       int ret = 0, ch;
        int irq;
 
-       cpsw = devm_kzalloc(&pdev->dev, sizeof(struct cpsw_common), GFP_KERNEL);
+       cpsw = devm_kzalloc(dev, sizeof(struct cpsw_common), GFP_KERNEL);
        if (!cpsw)
                return -ENOMEM;
 
-       cpsw->dev = &pdev->dev;
+       cpsw->dev = dev;
 
-       ndev = alloc_etherdev_mq(sizeof(struct cpsw_priv), CPSW_MAX_QUEUES);
-       if (!ndev) {
-               dev_err(&pdev->dev, "error allocating net_device\n");
-               return -ENOMEM;
-       }
-
-       platform_set_drvdata(pdev, ndev);
-       priv = netdev_priv(ndev);
-       priv->cpsw = cpsw;
-       priv->ndev = ndev;
-       priv->dev  = &ndev->dev;
-       priv->msg_enable = netif_msg_init(debug_level, CPSW_DEBUG);
-       cpsw->rx_packet_max = max(rx_packet_max, 128);
-
-       mode = devm_gpiod_get_array_optional(&pdev->dev, "mode", GPIOD_OUT_LOW);
+       mode = devm_gpiod_get_array_optional(dev, "mode", GPIOD_OUT_LOW);
        if (IS_ERR(mode)) {
                ret = PTR_ERR(mode);
-               dev_err(&pdev->dev, "gpio request failed, ret %d\n", ret);
-               goto clean_ndev_ret;
+               dev_err(dev, "gpio request failed, ret %d\n", ret);
+               return ret;
        }
 
+       clk = devm_clk_get(dev, "fck");
+       if (IS_ERR(clk)) {
+               ret = PTR_ERR(clk);
+               dev_err(dev, "fck is not found %d\n", ret);
+               return ret;
+       }
+       cpsw->bus_freq_mhz = clk_get_rate(clk) / 1000000;
+
+       ss_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       ss_regs = devm_ioremap_resource(dev, ss_res);
+       if (IS_ERR(ss_regs))
+               return PTR_ERR(ss_regs);
+       cpsw->regs = ss_regs;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+       cpsw->wr_regs = devm_ioremap_resource(dev, res);
+       if (IS_ERR(cpsw->wr_regs))
+               return PTR_ERR(cpsw->wr_regs);
+
+       /* RX IRQ */
+       irq = platform_get_irq(pdev, 1);
+       if (irq < 0)
+               return irq;
+       cpsw->irqs_table[0] = irq;
+
+       /* TX IRQ */
+       irq = platform_get_irq(pdev, 2);
+       if (irq < 0)
+               return irq;
+       cpsw->irqs_table[1] = irq;
+
        /*
         * This may be required here for child devices.
         */
-       pm_runtime_enable(&pdev->dev);
-
-       /* Select default pin state */
-       pinctrl_pm_select_default_state(&pdev->dev);
+       pm_runtime_enable(dev);
 
        /* Need to enable clocks with runtime PM api to access module
         * registers
         */
-       ret = pm_runtime_get_sync(&pdev->dev);
+       ret = pm_runtime_get_sync(dev);
        if (ret < 0) {
-               pm_runtime_put_noidle(&pdev->dev);
+               pm_runtime_put_noidle(dev);
                goto clean_runtime_disable_ret;
        }
 
@@ -3531,170 +2428,72 @@ static int cpsw_probe(struct platform_device *pdev)
        if (ret)
                goto clean_dt_ret;
 
-       data = &cpsw->data;
-       cpsw->rx_ch_num = 1;
-       cpsw->tx_ch_num = 1;
-
-       if (is_valid_ether_addr(data->slave_data[0].mac_addr)) {
-               memcpy(priv->mac_addr, data->slave_data[0].mac_addr, ETH_ALEN);
-               dev_info(&pdev->dev, "Detected MACID = %pM\n", priv->mac_addr);
-       } else {
-               eth_random_addr(priv->mac_addr);
-               dev_info(&pdev->dev, "Random MACID = %pM\n", priv->mac_addr);
-       }
-
-       memcpy(ndev->dev_addr, priv->mac_addr, ETH_ALEN);
+       soc = soc_device_match(cpsw_soc_devices);
+       if (soc)
+               cpsw->quirk_irq = 1;
 
-       cpsw->slaves = devm_kcalloc(&pdev->dev,
+       data = &cpsw->data;
+       cpsw->slaves = devm_kcalloc(dev,
                                    data->slaves, sizeof(struct cpsw_slave),
                                    GFP_KERNEL);
        if (!cpsw->slaves) {
                ret = -ENOMEM;
                goto clean_dt_ret;
        }
-       for (i = 0; i < data->slaves; i++)
-               cpsw->slaves[i].slave_num = i;
-
-       cpsw->slaves[0].ndev = ndev;
-       priv->emac_port = 0;
-
-       clk = devm_clk_get(&pdev->dev, "fck");
-       if (IS_ERR(clk)) {
-               dev_err(priv->dev, "fck is not found\n");
-               ret = -ENODEV;
-               goto clean_dt_ret;
-       }
-       cpsw->bus_freq_mhz = clk_get_rate(clk) / 1000000;
-
-       ss_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       ss_regs = devm_ioremap_resource(&pdev->dev, ss_res);
-       if (IS_ERR(ss_regs)) {
-               ret = PTR_ERR(ss_regs);
-               goto clean_dt_ret;
-       }
-       cpsw->regs = ss_regs;
-
-       cpsw->version = readl(&cpsw->regs->id_ver);
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-       cpsw->wr_regs = devm_ioremap_resource(&pdev->dev, res);
-       if (IS_ERR(cpsw->wr_regs)) {
-               ret = PTR_ERR(cpsw->wr_regs);
-               goto clean_dt_ret;
-       }
 
-       memset(&dma_params, 0, sizeof(dma_params));
-       memset(&ale_params, 0, sizeof(ale_params));
+       cpsw->rx_packet_max = max(rx_packet_max, CPSW_MAX_PACKET_SIZE);
+       cpsw->descs_pool_size = descs_pool_size;
 
-       switch (cpsw->version) {
-       case CPSW_VERSION_1:
-               cpsw->host_port_regs = ss_regs + CPSW1_HOST_PORT_OFFSET;
-               cpts_regs               = ss_regs + CPSW1_CPTS_OFFSET;
-               cpsw->hw_stats       = ss_regs + CPSW1_HW_STATS;
-               dma_params.dmaregs   = ss_regs + CPSW1_CPDMA_OFFSET;
-               dma_params.txhdp     = ss_regs + CPSW1_STATERAM_OFFSET;
-               ale_params.ale_regs  = ss_regs + CPSW1_ALE_OFFSET;
-               slave_offset         = CPSW1_SLAVE_OFFSET;
-               slave_size           = CPSW1_SLAVE_SIZE;
-               sliver_offset        = CPSW1_SLIVER_OFFSET;
-               dma_params.desc_mem_phys = 0;
-               break;
-       case CPSW_VERSION_2:
-       case CPSW_VERSION_3:
-       case CPSW_VERSION_4:
-               cpsw->host_port_regs = ss_regs + CPSW2_HOST_PORT_OFFSET;
-               cpts_regs               = ss_regs + CPSW2_CPTS_OFFSET;
-               cpsw->hw_stats       = ss_regs + CPSW2_HW_STATS;
-               dma_params.dmaregs   = ss_regs + CPSW2_CPDMA_OFFSET;
-               dma_params.txhdp     = ss_regs + CPSW2_STATERAM_OFFSET;
-               ale_params.ale_regs  = ss_regs + CPSW2_ALE_OFFSET;
-               slave_offset         = CPSW2_SLAVE_OFFSET;
-               slave_size           = CPSW2_SLAVE_SIZE;
-               sliver_offset        = CPSW2_SLIVER_OFFSET;
-               dma_params.desc_mem_phys =
-                       (u32 __force) ss_res->start + CPSW2_BD_OFFSET;
-               break;
-       default:
-               dev_err(priv->dev, "unknown version 0x%08x\n", cpsw->version);
-               ret = -ENODEV;
-               goto clean_dt_ret;
-       }
-       for (i = 0; i < cpsw->data.slaves; i++) {
-               struct cpsw_slave *slave = &cpsw->slaves[i];
-
-               cpsw_slave_init(slave, cpsw, slave_offset, sliver_offset);
-               slave_offset  += slave_size;
-               sliver_offset += SLIVER_SIZE;
-       }
-
-       dma_params.dev          = &pdev->dev;
-       dma_params.rxthresh     = dma_params.dmaregs + CPDMA_RXTHRESH;
-       dma_params.rxfree       = dma_params.dmaregs + CPDMA_RXFREE;
-       dma_params.rxhdp        = dma_params.txhdp + CPDMA_RXHDP;
-       dma_params.txcp         = dma_params.txhdp + CPDMA_TXCP;
-       dma_params.rxcp         = dma_params.txhdp + CPDMA_RXCP;
-
-       dma_params.num_chan             = data->channels;
-       dma_params.has_soft_reset       = true;
-       dma_params.min_packet_size      = CPSW_MIN_PACKET_SIZE;
-       dma_params.desc_mem_size        = data->bd_ram_size;
-       dma_params.desc_align           = 16;
-       dma_params.has_ext_regs         = true;
-       dma_params.desc_hw_addr         = dma_params.desc_mem_phys;
-       dma_params.bus_freq_mhz         = cpsw->bus_freq_mhz;
-       dma_params.descs_pool_size      = descs_pool_size;
-
-       cpsw->dma = cpdma_ctlr_create(&dma_params);
-       if (!cpsw->dma) {
-               dev_err(priv->dev, "error initializing dma\n");
-               ret = -ENOMEM;
+       ret = cpsw_init_common(cpsw, ss_regs, ale_ageout,
+                              ss_res->start + CPSW2_BD_OFFSET,
+                              descs_pool_size);
+       if (ret)
                goto clean_dt_ret;
-       }
-
-       soc = soc_device_match(cpsw_soc_devices);
-       if (soc)
-               cpsw->quirk_irq = 1;
 
        ch = cpsw->quirk_irq ? 0 : 7;
        cpsw->txv[0].ch = cpdma_chan_create(cpsw->dma, ch, cpsw_tx_handler, 0);
        if (IS_ERR(cpsw->txv[0].ch)) {
-               dev_err(priv->dev, "error initializing tx dma channel\n");
+               dev_err(dev, "error initializing tx dma channel\n");
                ret = PTR_ERR(cpsw->txv[0].ch);
-               goto clean_dma_ret;
+               goto clean_cpts;
        }
 
        cpsw->rxv[0].ch = cpdma_chan_create(cpsw->dma, 0, cpsw_rx_handler, 1);
        if (IS_ERR(cpsw->rxv[0].ch)) {
-               dev_err(priv->dev, "error initializing rx dma channel\n");
+               dev_err(dev, "error initializing rx dma channel\n");
                ret = PTR_ERR(cpsw->rxv[0].ch);
-               goto clean_dma_ret;
+               goto clean_cpts;
        }
+       cpsw_split_res(cpsw);
 
-       ale_params.dev                  = &pdev->dev;
-       ale_params.ale_ageout           = ale_ageout;
-       ale_params.ale_entries          = data->ale_entries;
-       ale_params.ale_ports            = CPSW_ALE_PORTS_NUM;
-
-       cpsw->ale = cpsw_ale_create(&ale_params);
-       if (!cpsw->ale) {
-               dev_err(priv->dev, "error initializing ale engine\n");
-               ret = -ENODEV;
-               goto clean_dma_ret;
+       /* setup netdev */
+       ndev = devm_alloc_etherdev_mqs(dev, sizeof(struct cpsw_priv),
+                                      CPSW_MAX_QUEUES, CPSW_MAX_QUEUES);
+       if (!ndev) {
+               dev_err(dev, "error allocating net_device\n");
+               goto clean_cpts;
        }
 
-       cpsw->cpts = cpts_create(cpsw->dev, cpts_regs, cpsw->dev->of_node);
-       if (IS_ERR(cpsw->cpts)) {
-               ret = PTR_ERR(cpsw->cpts);
-               goto clean_dma_ret;
-       }
+       platform_set_drvdata(pdev, ndev);
+       priv = netdev_priv(ndev);
+       priv->cpsw = cpsw;
+       priv->ndev = ndev;
+       priv->dev  = dev;
+       priv->msg_enable = netif_msg_init(debug_level, CPSW_DEBUG);
+       priv->emac_port = 0;
 
-       ndev->irq = platform_get_irq(pdev, 1);
-       if (ndev->irq < 0) {
-               dev_err(priv->dev, "error getting irq resource\n");
-               ret = ndev->irq;
-               goto clean_dma_ret;
+       if (is_valid_ether_addr(data->slave_data[0].mac_addr)) {
+               memcpy(priv->mac_addr, data->slave_data[0].mac_addr, ETH_ALEN);
+               dev_info(dev, "Detected MACID = %pM\n", priv->mac_addr);
+       } else {
+               eth_random_addr(priv->mac_addr);
+               dev_info(dev, "Random MACID = %pM\n", priv->mac_addr);
        }
 
+       memcpy(ndev->dev_addr, priv->mac_addr, ETH_ALEN);
+
+       cpsw->slaves[0].ndev = ndev;
+
        ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_CTAG_RX;
 
        ndev->netdev_ops = &cpsw_netdev_ops;
@@ -3705,15 +2504,14 @@ static int cpsw_probe(struct platform_device *pdev)
        netif_tx_napi_add(ndev, &cpsw->napi_tx,
                          cpsw->quirk_irq ? cpsw_tx_poll : cpsw_tx_mq_poll,
                          CPSW_POLL_WEIGHT);
-       cpsw_split_res(ndev);
 
        /* register the network device */
-       SET_NETDEV_DEV(ndev, &pdev->dev);
+       SET_NETDEV_DEV(ndev, dev);
        ret = register_netdev(ndev);
        if (ret) {
-               dev_err(priv->dev, "error registering net device\n");
+               dev_err(dev, "error registering net device\n");
                ret = -ENODEV;
-               goto clean_dma_ret;
+               goto clean_cpts;
        }
 
        if (cpsw->data.dual_emac) {
@@ -3731,40 +2529,24 @@ static int cpsw_probe(struct platform_device *pdev)
         * If anyone wants to implement support for those, make sure to
         * first request and append them to irqs_table array.
         */
-
-       /* RX IRQ */
-       irq = platform_get_irq(pdev, 1);
-       if (irq < 0) {
-               ret = irq;
-               goto clean_dma_ret;
-       }
-
-       cpsw->irqs_table[0] = irq;
-       ret = devm_request_irq(&pdev->dev, irq, cpsw_rx_interrupt,
-                              0, dev_name(&pdev->dev), cpsw);
+       ret = devm_request_irq(dev, cpsw->irqs_table[0], cpsw_rx_interrupt,
+                              0, dev_name(dev), cpsw);
        if (ret < 0) {
-               dev_err(priv->dev, "error attaching irq (%d)\n", ret);
-               goto clean_dma_ret;
+               dev_err(dev, "error attaching irq (%d)\n", ret);
+               goto clean_unregister_netdev_ret;
        }
 
-       /* TX IRQ */
-       irq = platform_get_irq(pdev, 2);
-       if (irq < 0) {
-               ret = irq;
-               goto clean_dma_ret;
-       }
 
-       cpsw->irqs_table[1] = irq;
-       ret = devm_request_irq(&pdev->dev, irq, cpsw_tx_interrupt,
+       ret = devm_request_irq(dev, cpsw->irqs_table[1], cpsw_tx_interrupt,
                               0, dev_name(&pdev->dev), cpsw);
        if (ret < 0) {
-               dev_err(priv->dev, "error attaching irq (%d)\n", ret);
-               goto clean_dma_ret;
+               dev_err(dev, "error attaching irq (%d)\n", ret);
+               goto clean_unregister_netdev_ret;
        }
 
        cpsw_notice(priv, probe,
                    "initialized device (regs %pa, irq %d, pool size %d)\n",
-                   &ss_res->start, ndev->irq, dma_params.descs_pool_size);
+                   &ss_res->start, cpsw->irqs_table[0], descs_pool_size);
 
        pm_runtime_put(&pdev->dev);
 
@@ -3772,15 +2554,14 @@ static int cpsw_probe(struct platform_device *pdev)
 
 clean_unregister_netdev_ret:
        unregister_netdev(ndev);
-clean_dma_ret:
+clean_cpts:
+       cpts_release(cpsw->cpts);
        cpdma_ctlr_destroy(cpsw->dma);
 clean_dt_ret:
        cpsw_remove_dt(pdev);
        pm_runtime_put_sync(&pdev->dev);
 clean_runtime_disable_ret:
        pm_runtime_disable(&pdev->dev);
-clean_ndev_ret:
-       free_netdev(priv->ndev);
        return ret;
 }
 
@@ -3805,9 +2586,6 @@ static int cpsw_remove(struct platform_device *pdev)
        cpsw_remove_dt(pdev);
        pm_runtime_put_sync(&pdev->dev);
        pm_runtime_disable(&pdev->dev);
-       if (cpsw->data.dual_emac)
-               free_netdev(cpsw->slaves[1].ndev);
-       free_netdev(ndev);
        return 0;
 }