[source] kernel: bgmac: backport patch adding platform support

LEDE Commits lede-commits at lists.infradead.org
Wed Aug 17 04:09:37 PDT 2016


rmilecki pushed a commit to source.git, branch master:
https://git.lede-project.org/?p=source.git;a=commitdiff;h=93f2aa44f7833bd8d762ae4ef62c9f681ed58eef

commit 93f2aa44f7833bd8d762ae4ef62c9f681ed58eef
Author: Rafał Miłecki <rafal at milecki.pl>
AuthorDate: Wed Aug 17 09:30:44 2016 +0200

    kernel: bgmac: backport patch adding platform support
    
    It also reworks bcma support by moving specific code to separated file.
    
    Signed-off-by: Rafał Miłecki <rafal at milecki.pl>
---
 target/linux/bcm53xx/config-4.4                    |    2 +
 ...thernet-bgmac-Add-platform-device-support.patch | 1260 ++++++++++++++++++++
 .../patches-4.4/773-bgmac-add-srab-switch.patch    |   52 +-
 3 files changed, 1289 insertions(+), 25 deletions(-)

diff --git a/target/linux/bcm53xx/config-4.4 b/target/linux/bcm53xx/config-4.4
index 625b7e7..2eeafc8 100644
--- a/target/linux/bcm53xx/config-4.4
+++ b/target/linux/bcm53xx/config-4.4
@@ -70,6 +70,8 @@ CONFIG_BCMA_HOST_PCI_POSSIBLE=y
 CONFIG_BCMA_HOST_SOC=y
 CONFIG_BCMA_SFLASH=y
 CONFIG_BGMAC=y
+CONFIG_BGMAC_BCMA=y
+# CONFIG_BGMAC_PLATFORM is not set
 CONFIG_BOUNCE=y
 CONFIG_CACHE_L2X0=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
diff --git a/target/linux/generic/patches-4.4/075-0005-net-ethernet-bgmac-Add-platform-device-support.patch b/target/linux/generic/patches-4.4/075-0005-net-ethernet-bgmac-Add-platform-device-support.patch
new file mode 100644
index 0000000..4a69524
--- /dev/null
+++ b/target/linux/generic/patches-4.4/075-0005-net-ethernet-bgmac-Add-platform-device-support.patch
@@ -0,0 +1,1260 @@
+From f6a95a24957aec5bb488c3f978c4ed508177998f Mon Sep 17 00:00:00 2001
+From: Jon Mason <jon.mason at broadcom.com>
+Date: Thu, 7 Jul 2016 19:08:57 -0400
+Subject: [PATCH 5/5] net: ethernet: bgmac: Add platform device support
+
+The bcma portion of the driver has been split off into a bcma specific
+driver.  This has been mirrored for the platform driver.  The last
+references to the bcma core struct have been changed into a generic
+function call.  These function calls are wrappers to either the original
+bcma code or new platform functions that access the same areas via MMIO.
+This necessitated adding function pointers for both platform and bcma to
+hide which backend is being used from the generic bgmac code.
+
+Signed-off-by: Jon Mason <jon.mason at broadcom.com>
+Acked-by: Arnd Bergmann <arnd at arndb.de>
+Reviewed-by: Florian Fainelli <f.fainelli at gmail.com>
+Tested-by: Florian Fainelli <f.fainelli at gmail.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/broadcom/Kconfig           |  23 +-
+ drivers/net/ethernet/broadcom/Makefile          |   4 +-
+ drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c |   2 +
+ drivers/net/ethernet/broadcom/bgmac-bcma.c      | 315 +++++++++++++++++++++++
+ drivers/net/ethernet/broadcom/bgmac-platform.c  | 189 ++++++++++++++
+ drivers/net/ethernet/broadcom/bgmac.c           | 329 ++++--------------------
+ drivers/net/ethernet/broadcom/bgmac.h           |  73 +++++-
+ 7 files changed, 650 insertions(+), 285 deletions(-)
+ create mode 100644 drivers/net/ethernet/broadcom/bgmac-bcma.c
+ create mode 100644 drivers/net/ethernet/broadcom/bgmac-platform.c
+
+--- a/drivers/net/ethernet/broadcom/Kconfig
++++ b/drivers/net/ethernet/broadcom/Kconfig
+@@ -150,10 +150,18 @@ config BNX2X_VXLAN
+ 	  Virtual eXtensible Local Area Network (VXLAN) in the driver.
+ 
+ config BGMAC
+-	tristate "BCMA bus GBit core support"
++	tristate
++	help
++	  This enables the integrated ethernet controller support for many
++	  Broadcom (mostly iProc) SoCs. An appropriate bus interface driver
++	  needs to be enabled to select this.
++
++config BGMAC_BCMA
++	tristate "Broadcom iProc GBit BCMA support"
+ 	depends on BCMA && BCMA_HOST_SOC
+ 	depends on HAS_DMA
+ 	depends on BCM47XX || ARCH_BCM_5301X || COMPILE_TEST
++	select BGMAC
+ 	select PHYLIB
+ 	select FIXED_PHY
+ 	---help---
+@@ -162,6 +170,19 @@ config BGMAC
+ 	  In case of using this driver on BCM4706 it's also requires to enable
+ 	  BCMA_DRIVER_GMAC_CMN to make it work.
+ 
++config BGMAC_PLATFORM
++	tristate "Broadcom iProc GBit platform support"
++	depends on HAS_DMA
++	depends on ARCH_BCM_IPROC || COMPILE_TEST
++	depends on OF
++	select BGMAC
++	select PHYLIB
++	select FIXED_PHY
++	default ARCH_BCM_IPROC
++	---help---
++	  Say Y here if you want to use the Broadcom iProc Gigabit Ethernet
++	  controller through the generic platform interface
++
+ config SYSTEMPORT
+ 	tristate "Broadcom SYSTEMPORT internal MAC support"
+ 	depends on OF
+--- a/drivers/net/ethernet/broadcom/Makefile
++++ b/drivers/net/ethernet/broadcom/Makefile
+@@ -10,6 +10,8 @@ obj-$(CONFIG_CNIC) += cnic.o
+ obj-$(CONFIG_BNX2X) += bnx2x/
+ obj-$(CONFIG_SB1250_MAC) += sb1250-mac.o
+ obj-$(CONFIG_TIGON3) += tg3.o
+-obj-$(CONFIG_BGMAC) += bgmac.o bgmac-bcma-mdio.o
++obj-$(CONFIG_BGMAC) += bgmac.o
++obj-$(CONFIG_BGMAC_BCMA) += bgmac-bcma.o bgmac-bcma-mdio.o
++obj-$(CONFIG_BGMAC_PLATFORM) += bgmac-platform.o
+ obj-$(CONFIG_SYSTEMPORT) += bcmsysport.o
+ obj-$(CONFIG_BNXT) += bnxt/
+--- a/drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c
++++ b/drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c
+@@ -255,6 +255,7 @@ err:
+ 	kfree(bcma_mdio);
+ 	return ERR_PTR(err);
+ }
++EXPORT_SYMBOL_GPL(bcma_mdio_mii_register);
+ 
+ void bcma_mdio_mii_unregister(struct mii_bus *mii_bus)
+ {
+@@ -270,6 +271,7 @@ void bcma_mdio_mii_unregister(struct mii
+ 	mdiobus_free(mii_bus);
+ 	kfree(bcma_mdio);
+ }
++EXPORT_SYMBOL_GPL(bcma_mdio_mii_unregister);
+ 
+ MODULE_AUTHOR("Rafał Miłecki");
+ MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c
+@@ -0,0 +1,315 @@
++/*
++ * Driver for (BCM4706)? GBit MAC core on BCMA bus.
++ *
++ * Copyright (C) 2012 Rafał Miłecki <zajec5 at gmail.com>
++ *
++ * Licensed under the GNU/GPL. See COPYING for details.
++ */
++
++#define pr_fmt(fmt)		KBUILD_MODNAME ": " fmt
++
++#include <linux/bcma/bcma.h>
++#include <linux/brcmphy.h>
++#include <linux/etherdevice.h>
++#include "bgmac.h"
++
++static inline bool bgmac_is_bcm4707_family(struct bcma_device *core)
++{
++	switch (core->bus->chipinfo.id) {
++	case BCMA_CHIP_ID_BCM4707:
++	case BCMA_CHIP_ID_BCM47094:
++	case BCMA_CHIP_ID_BCM53018:
++		return true;
++	default:
++		return false;
++	}
++}
++
++/**************************************************
++ * BCMA bus ops
++ **************************************************/
++
++static u32 bcma_bgmac_read(struct bgmac *bgmac, u16 offset)
++{
++	return bcma_read32(bgmac->bcma.core, offset);
++}
++
++static void bcma_bgmac_write(struct bgmac *bgmac, u16 offset, u32 value)
++{
++	bcma_write32(bgmac->bcma.core, offset, value);
++}
++
++static u32 bcma_bgmac_idm_read(struct bgmac *bgmac, u16 offset)
++{
++	return bcma_aread32(bgmac->bcma.core, offset);
++}
++
++static void bcma_bgmac_idm_write(struct bgmac *bgmac, u16 offset, u32 value)
++{
++	return bcma_awrite32(bgmac->bcma.core, offset, value);
++}
++
++static bool bcma_bgmac_clk_enabled(struct bgmac *bgmac)
++{
++	return bcma_core_is_enabled(bgmac->bcma.core);
++}
++
++static void bcma_bgmac_clk_enable(struct bgmac *bgmac, u32 flags)
++{
++	bcma_core_enable(bgmac->bcma.core, flags);
++}
++
++static void bcma_bgmac_cco_ctl_maskset(struct bgmac *bgmac, u32 offset,
++				       u32 mask, u32 set)
++{
++	struct bcma_drv_cc *cc = &bgmac->bcma.core->bus->drv_cc;
++
++	bcma_chipco_chipctl_maskset(cc, offset, mask, set);
++}
++
++static u32 bcma_bgmac_get_bus_clock(struct bgmac *bgmac)
++{
++	struct bcma_drv_cc *cc = &bgmac->bcma.core->bus->drv_cc;
++
++	return bcma_pmu_get_bus_clock(cc);
++}
++
++static void bcma_bgmac_cmn_maskset32(struct bgmac *bgmac, u16 offset, u32 mask,
++				     u32 set)
++{
++	bcma_maskset32(bgmac->bcma.cmn, offset, mask, set);
++}
++
++static const struct bcma_device_id bgmac_bcma_tbl[] = {
++	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_4706_MAC_GBIT,
++		  BCMA_ANY_REV, BCMA_ANY_CLASS),
++	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_MAC_GBIT, BCMA_ANY_REV,
++		  BCMA_ANY_CLASS),
++	{},
++};
++MODULE_DEVICE_TABLE(bcma, bgmac_bcma_tbl);
++
++/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipattach */
++static int bgmac_probe(struct bcma_device *core)
++{
++	struct ssb_sprom *sprom = &core->bus->sprom;
++	struct mii_bus *mii_bus;
++	struct bgmac *bgmac;
++	u8 *mac;
++	int err;
++
++	bgmac = kzalloc(sizeof(*bgmac), GFP_KERNEL);
++	if (!bgmac)
++		return -ENOMEM;
++
++	bgmac->bcma.core = core;
++	bgmac->dev = &core->dev;
++	bgmac->dma_dev = core->dma_dev;
++	bgmac->irq = core->irq;
++
++	bcma_set_drvdata(core, bgmac);
++
++	switch (core->core_unit) {
++	case 0:
++		mac = sprom->et0mac;
++		break;
++	case 1:
++		mac = sprom->et1mac;
++		break;
++	case 2:
++		mac = sprom->et2mac;
++		break;
++	default:
++		dev_err(bgmac->dev, "Unsupported core_unit %d\n",
++			core->core_unit);
++		err = -ENOTSUPP;
++		goto err;
++	}
++
++	ether_addr_copy(bgmac->mac_addr, mac);
++
++	/* On BCM4706 we need common core to access PHY */
++	if (core->id.id == BCMA_CORE_4706_MAC_GBIT &&
++	    !core->bus->drv_gmac_cmn.core) {
++		dev_err(bgmac->dev, "GMAC CMN core not found (required for BCM4706)\n");
++		err = -ENODEV;
++		goto err;
++	}
++	bgmac->bcma.cmn = core->bus->drv_gmac_cmn.core;
++
++	switch (core->core_unit) {
++	case 0:
++		bgmac->phyaddr = sprom->et0phyaddr;
++		break;
++	case 1:
++		bgmac->phyaddr = sprom->et1phyaddr;
++		break;
++	case 2:
++		bgmac->phyaddr = sprom->et2phyaddr;
++		break;
++	}
++	bgmac->phyaddr &= BGMAC_PHY_MASK;
++	if (bgmac->phyaddr == BGMAC_PHY_MASK) {
++		dev_err(bgmac->dev, "No PHY found\n");
++		err = -ENODEV;
++		goto err;
++	}
++	dev_info(bgmac->dev, "Found PHY addr: %d%s\n", bgmac->phyaddr,
++		 bgmac->phyaddr == BGMAC_PHY_NOREGS ? " (NOREGS)" : "");
++
++	if (!bgmac_is_bcm4707_family(core)) {
++		mii_bus = bcma_mdio_mii_register(core, bgmac->phyaddr);
++		if (!IS_ERR(mii_bus)) {
++			err = PTR_ERR(mii_bus);
++			goto err;
++		}
++
++		bgmac->mii_bus = mii_bus;
++	}
++
++	if (core->bus->hosttype == BCMA_HOSTTYPE_PCI) {
++		dev_err(bgmac->dev, "PCI setup not implemented\n");
++		err = -ENOTSUPP;
++		goto err1;
++	}
++
++	bgmac->has_robosw = !!(core->bus->sprom.boardflags_lo &
++			       BGMAC_BFL_ENETROBO);
++	if (bgmac->has_robosw)
++		dev_warn(bgmac->dev, "Support for Roboswitch not implemented\n");
++
++	if (core->bus->sprom.boardflags_lo & BGMAC_BFL_ENETADM)
++		dev_warn(bgmac->dev, "Support for ADMtek ethernet switch not implemented\n");
++
++	/* Feature Flags */
++	switch (core->bus->chipinfo.id) {
++	case BCMA_CHIP_ID_BCM5357:
++		bgmac->feature_flags |= BGMAC_FEAT_SET_RXQ_CLK;
++		bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;
++		bgmac->feature_flags |= BGMAC_FEAT_FLW_CTRL1;
++		bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_PHY;
++		if (core->bus->chipinfo.pkg == BCMA_PKG_ID_BCM47186) {
++			bgmac->feature_flags |= BGMAC_FEAT_IOST_ATTACHED;
++			bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_RGMII;
++		}
++		if (core->bus->chipinfo.pkg == BCMA_PKG_ID_BCM5358)
++			bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_EPHYRMII;
++		break;
++	case BCMA_CHIP_ID_BCM53572:
++		bgmac->feature_flags |= BGMAC_FEAT_SET_RXQ_CLK;
++		bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;
++		bgmac->feature_flags |= BGMAC_FEAT_FLW_CTRL1;
++		bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_PHY;
++		if (core->bus->chipinfo.pkg == BCMA_PKG_ID_BCM47188) {
++			bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_RGMII;
++			bgmac->feature_flags |= BGMAC_FEAT_IOST_ATTACHED;
++		}
++		break;
++	case BCMA_CHIP_ID_BCM4749:
++		bgmac->feature_flags |= BGMAC_FEAT_SET_RXQ_CLK;
++		bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;
++		bgmac->feature_flags |= BGMAC_FEAT_FLW_CTRL1;
++		bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_PHY;
++		if (core->bus->chipinfo.pkg == 10) {
++			bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_RGMII;
++			bgmac->feature_flags |= BGMAC_FEAT_IOST_ATTACHED;
++		}
++		break;
++	case BCMA_CHIP_ID_BCM4716:
++		bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;
++		/* fallthrough */
++	case BCMA_CHIP_ID_BCM47162:
++		bgmac->feature_flags |= BGMAC_FEAT_FLW_CTRL2;
++		bgmac->feature_flags |= BGMAC_FEAT_SET_RXQ_CLK;
++		break;
++	/* bcm4707_family */
++	case BCMA_CHIP_ID_BCM4707:
++	case BCMA_CHIP_ID_BCM47094:
++	case BCMA_CHIP_ID_BCM53018:
++		bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;
++		bgmac->feature_flags |= BGMAC_FEAT_NO_RESET;
++		bgmac->feature_flags |= BGMAC_FEAT_FORCE_SPEED_2500;
++		break;
++	default:
++		bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;
++		bgmac->feature_flags |= BGMAC_FEAT_SET_RXQ_CLK;
++	}
++
++	if (!bgmac_is_bcm4707_family(core) && core->id.rev > 2)
++		bgmac->feature_flags |= BGMAC_FEAT_MISC_PLL_REQ;
++
++	if (core->id.id == BCMA_CORE_4706_MAC_GBIT) {
++		bgmac->feature_flags |= BGMAC_FEAT_CMN_PHY_CTL;
++		bgmac->feature_flags |= BGMAC_FEAT_NO_CLR_MIB;
++	}
++
++	if (core->id.rev >= 4) {
++		bgmac->feature_flags |= BGMAC_FEAT_CMDCFG_SR_REV4;
++		bgmac->feature_flags |= BGMAC_FEAT_TX_MASK_SETUP;
++		bgmac->feature_flags |= BGMAC_FEAT_RX_MASK_SETUP;
++	}
++
++	bgmac->read = bcma_bgmac_read;
++	bgmac->write = bcma_bgmac_write;
++	bgmac->idm_read = bcma_bgmac_idm_read;
++	bgmac->idm_write = bcma_bgmac_idm_write;
++	bgmac->clk_enabled = bcma_bgmac_clk_enabled;
++	bgmac->clk_enable = bcma_bgmac_clk_enable;
++	bgmac->cco_ctl_maskset = bcma_bgmac_cco_ctl_maskset;
++	bgmac->get_bus_clock = bcma_bgmac_get_bus_clock;
++	bgmac->cmn_maskset32 = bcma_bgmac_cmn_maskset32;
++
++	err = bgmac_enet_probe(bgmac);
++	if (err)
++		goto err1;
++
++	return 0;
++
++err1:
++	bcma_mdio_mii_unregister(bgmac->mii_bus);
++err:
++	kfree(bgmac);
++	bcma_set_drvdata(core, NULL);
++
++	return err;
++}
++
++static void bgmac_remove(struct bcma_device *core)
++{
++	struct bgmac *bgmac = bcma_get_drvdata(core);
++
++	bcma_mdio_mii_unregister(bgmac->mii_bus);
++	bgmac_enet_remove(bgmac);
++	bcma_set_drvdata(core, NULL);
++	kfree(bgmac);
++}
++
++static struct bcma_driver bgmac_bcma_driver = {
++	.name		= KBUILD_MODNAME,
++	.id_table	= bgmac_bcma_tbl,
++	.probe		= bgmac_probe,
++	.remove		= bgmac_remove,
++};
++
++static int __init bgmac_init(void)
++{
++	int err;
++
++	err = bcma_driver_register(&bgmac_bcma_driver);
++	if (err)
++		return err;
++	pr_info("Broadcom 47xx GBit MAC driver loaded\n");
++
++	return 0;
++}
++
++static void __exit bgmac_exit(void)
++{
++	bcma_driver_unregister(&bgmac_bcma_driver);
++}
++
++module_init(bgmac_init)
++module_exit(bgmac_exit)
++
++MODULE_AUTHOR("Rafał Miłecki");
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/drivers/net/ethernet/broadcom/bgmac-platform.c
+@@ -0,0 +1,189 @@
++/*
++ * Copyright (C) 2016 Broadcom
++ *
++ * 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.
++ */
++
++#define pr_fmt(fmt)		KBUILD_MODNAME ": " fmt
++
++#include <linux/bcma/bcma.h>
++#include <linux/etherdevice.h>
++#include <linux/of_address.h>
++#include <linux/of_net.h>
++#include "bgmac.h"
++
++static u32 platform_bgmac_read(struct bgmac *bgmac, u16 offset)
++{
++	return readl(bgmac->plat.base + offset);
++}
++
++static void platform_bgmac_write(struct bgmac *bgmac, u16 offset, u32 value)
++{
++	writel(value, bgmac->plat.base + offset);
++}
++
++static u32 platform_bgmac_idm_read(struct bgmac *bgmac, u16 offset)
++{
++	return readl(bgmac->plat.idm_base + offset);
++}
++
++static void platform_bgmac_idm_write(struct bgmac *bgmac, u16 offset, u32 value)
++{
++	return writel(value, bgmac->plat.idm_base + offset);
++}
++
++static bool platform_bgmac_clk_enabled(struct bgmac *bgmac)
++{
++	if ((bgmac_idm_read(bgmac, BCMA_IOCTL) &
++	     (BCMA_IOCTL_CLK | BCMA_IOCTL_FGC)) != BCMA_IOCTL_CLK)
++		return false;
++	if (bgmac_idm_read(bgmac, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET)
++		return false;
++	return true;
++}
++
++static void platform_bgmac_clk_enable(struct bgmac *bgmac, u32 flags)
++{
++	bgmac_idm_write(bgmac, BCMA_IOCTL,
++			(BCMA_IOCTL_CLK | BCMA_IOCTL_FGC | flags));
++	bgmac_idm_read(bgmac, BCMA_IOCTL);
++
++	bgmac_idm_write(bgmac, BCMA_RESET_CTL, 0);
++	bgmac_idm_read(bgmac, BCMA_RESET_CTL);
++	udelay(1);
++
++	bgmac_idm_write(bgmac, BCMA_IOCTL, (BCMA_IOCTL_CLK | flags));
++	bgmac_idm_read(bgmac, BCMA_IOCTL);
++	udelay(1);
++}
++
++static void platform_bgmac_cco_ctl_maskset(struct bgmac *bgmac, u32 offset,
++					   u32 mask, u32 set)
++{
++	/* This shouldn't be encountered */
++	WARN_ON(1);
++}
++
++static u32 platform_bgmac_get_bus_clock(struct bgmac *bgmac)
++{
++	/* This shouldn't be encountered */
++	WARN_ON(1);
++
++	return 0;
++}
++
++static void platform_bgmac_cmn_maskset32(struct bgmac *bgmac, u16 offset,
++					 u32 mask, u32 set)
++{
++	/* This shouldn't be encountered */
++	WARN_ON(1);
++}
++
++static int bgmac_probe(struct platform_device *pdev)
++{
++	struct device_node *np = pdev->dev.of_node;
++	struct bgmac *bgmac;
++	struct resource *regs;
++	const u8 *mac_addr;
++
++	bgmac = devm_kzalloc(&pdev->dev, sizeof(*bgmac), GFP_KERNEL);
++	if (!bgmac)
++		return -ENOMEM;
++
++	platform_set_drvdata(pdev, bgmac);
++
++	/* Set the features of the 4707 family */
++	bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;
++	bgmac->feature_flags |= BGMAC_FEAT_NO_RESET;
++	bgmac->feature_flags |= BGMAC_FEAT_FORCE_SPEED_2500;
++	bgmac->feature_flags |= BGMAC_FEAT_CMDCFG_SR_REV4;
++	bgmac->feature_flags |= BGMAC_FEAT_TX_MASK_SETUP;
++	bgmac->feature_flags |= BGMAC_FEAT_RX_MASK_SETUP;
++
++	bgmac->dev = &pdev->dev;
++	bgmac->dma_dev = &pdev->dev;
++
++	mac_addr = of_get_mac_address(np);
++	if (mac_addr)
++		ether_addr_copy(bgmac->mac_addr, mac_addr);
++	else
++		dev_warn(&pdev->dev, "MAC address not present in device tree\n");
++
++	bgmac->irq = platform_get_irq(pdev, 0);
++	if (bgmac->irq < 0) {
++		dev_err(&pdev->dev, "Unable to obtain IRQ\n");
++		return bgmac->irq;
++	}
++
++	regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "amac_base");
++	if (!regs) {
++		dev_err(&pdev->dev, "Unable to obtain base resource\n");
++		return -EINVAL;
++	}
++
++	bgmac->plat.base = devm_ioremap_resource(&pdev->dev, regs);
++	if (IS_ERR(bgmac->plat.base)) {
++		dev_err(&pdev->dev, "Unable to map base resource\n");
++		return PTR_ERR(bgmac->plat.base);
++	}
++
++	regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "idm_base");
++	if (!regs) {
++		dev_err(&pdev->dev, "Unable to obtain idm resource\n");
++		return -EINVAL;
++	}
++
++	bgmac->plat.idm_base = devm_ioremap_resource(&pdev->dev, regs);
++	if (!bgmac->plat.idm_base) {
++		dev_err(&pdev->dev, "Unable to map idm resource\n");
++		return PTR_ERR(bgmac->plat.idm_base);
++	}
++
++	bgmac->read = platform_bgmac_read;
++	bgmac->write = platform_bgmac_write;
++	bgmac->idm_read = platform_bgmac_idm_read;
++	bgmac->idm_write = platform_bgmac_idm_write;
++	bgmac->clk_enabled = platform_bgmac_clk_enabled;
++	bgmac->clk_enable = platform_bgmac_clk_enable;
++	bgmac->cco_ctl_maskset = platform_bgmac_cco_ctl_maskset;
++	bgmac->get_bus_clock = platform_bgmac_get_bus_clock;
++	bgmac->cmn_maskset32 = platform_bgmac_cmn_maskset32;
++
++	return bgmac_enet_probe(bgmac);
++}
++
++static int bgmac_remove(struct platform_device *pdev)
++{
++	struct bgmac *bgmac = platform_get_drvdata(pdev);
++
++	bgmac_enet_remove(bgmac);
++
++	return 0;
++}
++
++static const struct of_device_id bgmac_of_enet_match[] = {
++	{.compatible = "brcm,amac",},
++	{.compatible = "brcm,nsp-amac",},
++	{},
++};
++
++MODULE_DEVICE_TABLE(of, bgmac_of_enet_match);
++
++static struct platform_driver bgmac_enet_driver = {
++	.driver = {
++		.name  = "bgmac-enet",
++		.of_match_table = bgmac_of_enet_match,
++	},
++	.probe = bgmac_probe,
++	.remove = bgmac_remove,
++};
++
++module_platform_driver(bgmac_enet_driver);
++MODULE_LICENSE("GPL");
+--- a/drivers/net/ethernet/broadcom/bgmac.c
++++ b/drivers/net/ethernet/broadcom/bgmac.c
+@@ -6,51 +6,27 @@
+  * Licensed under the GNU/GPL. See COPYING for details.
+  */
+ 
+-#include "bgmac.h"
+ 
+-#include <linux/kernel.h>
+-#include <linux/module.h>
+-#include <linux/delay.h>
++#define pr_fmt(fmt)		KBUILD_MODNAME ": " fmt
++
++#include <linux/bcma/bcma.h>
+ #include <linux/etherdevice.h>
+-#include <linux/mii.h>
+-#include <linux/phy.h>
+-#include <linux/phy_fixed.h>
+-#include <linux/interrupt.h>
+-#include <linux/dma-mapping.h>
+ #include <linux/bcm47xx_nvram.h>
++#include "bgmac.h"
+ 
+-static const struct bcma_device_id bgmac_bcma_tbl[] = {
+-	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_4706_MAC_GBIT, BCMA_ANY_REV, BCMA_ANY_CLASS),
+-	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_MAC_GBIT, BCMA_ANY_REV, BCMA_ANY_CLASS),
+-	{},
+-};
+-MODULE_DEVICE_TABLE(bcma, bgmac_bcma_tbl);
+-
+-static inline bool bgmac_is_bcm4707_family(struct bgmac *bgmac)
+-{
+-	switch (bgmac->core->bus->chipinfo.id) {
+-	case BCMA_CHIP_ID_BCM4707:
+-	case BCMA_CHIP_ID_BCM47094:
+-	case BCMA_CHIP_ID_BCM53018:
+-		return true;
+-	default:
+-		return false;
+-	}
+-}
+-
+-static bool bgmac_wait_value(struct bcma_device *core, u16 reg, u32 mask,
++static bool bgmac_wait_value(struct bgmac *bgmac, u16 reg, u32 mask,
+ 			     u32 value, int timeout)
+ {
+ 	u32 val;
+ 	int i;
+ 
+ 	for (i = 0; i < timeout / 10; i++) {
+-		val = bcma_read32(core, reg);
++		val = bgmac_read(bgmac, reg);
+ 		if ((val & mask) == value)
+ 			return true;
+ 		udelay(10);
+ 	}
+-	dev_err(&core->dev, "Timeout waiting for reg 0x%X\n", reg);
++	dev_err(bgmac->dev, "Timeout waiting for reg 0x%X\n", reg);
+ 	return false;
+ }
+ 
+@@ -89,7 +65,7 @@ static void bgmac_dma_tx_reset(struct bg
+ 
+ 	/* Remove SUSPEND bit */
+ 	bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_CTL, 0);
+-	if (!bgmac_wait_value(bgmac->core,
++	if (!bgmac_wait_value(bgmac,
+ 			      ring->mmio_base + BGMAC_DMA_TX_STATUS,
+ 			      BGMAC_DMA_TX_STAT, BGMAC_DMA_TX_STAT_DISABLED,
+ 			      10000)) {
+@@ -317,7 +293,7 @@ static void bgmac_dma_rx_reset(struct bg
+ 		return;
+ 
+ 	bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_CTL, 0);
+-	if (!bgmac_wait_value(bgmac->core,
++	if (!bgmac_wait_value(bgmac,
+ 			      ring->mmio_base + BGMAC_DMA_RX_STATUS,
+ 			      BGMAC_DMA_RX_STAT, BGMAC_DMA_RX_STAT_DISABLED,
+ 			      10000))
+@@ -640,7 +616,7 @@ static int bgmac_dma_alloc(struct bgmac
+ 	BUILD_BUG_ON(BGMAC_MAX_TX_RINGS > ARRAY_SIZE(ring_base));
+ 	BUILD_BUG_ON(BGMAC_MAX_RX_RINGS > ARRAY_SIZE(ring_base));
+ 
+-	if (!(bcma_aread32(bgmac->core, BCMA_IOST) & BCMA_IOST_DMA64)) {
++	if (!(bgmac_idm_read(bgmac, BCMA_IOST) & BCMA_IOST_DMA64)) {
+ 		dev_err(bgmac->dev, "Core does not report 64-bit DMA\n");
+ 		return -ENOTSUPP;
+ 	}
+@@ -872,12 +848,10 @@ static void bgmac_mac_speed(struct bgmac
+ 
+ static void bgmac_miiconfig(struct bgmac *bgmac)
+ {
+-	struct bcma_device *core = bgmac->core;
+-
+ 	if (bgmac->feature_flags & BGMAC_FEAT_FORCE_SPEED_2500) {
+-		bcma_awrite32(core, BCMA_IOCTL,
+-			      bcma_aread32(core, BCMA_IOCTL) | 0x40 |
+-			      BGMAC_BCMA_IOCTL_SW_CLKEN);
++		bgmac_idm_write(bgmac, BCMA_IOCTL,
++				bgmac_idm_read(bgmac, BCMA_IOCTL) | 0x40 |
++				BGMAC_BCMA_IOCTL_SW_CLKEN);
+ 		bgmac->mac_speed = SPEED_2500;
+ 		bgmac->mac_duplex = DUPLEX_FULL;
+ 		bgmac_mac_speed(bgmac);
+@@ -897,12 +871,11 @@ static void bgmac_miiconfig(struct bgmac
+ /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipreset */
+ static void bgmac_chip_reset(struct bgmac *bgmac)
+ {
+-	struct bcma_device *core = bgmac->core;
+ 	u32 cmdcfg_sr;
+ 	u32 iost;
+ 	int i;
+ 
+-	if (bcma_core_is_enabled(core)) {
++	if (bgmac_clk_enabled(bgmac)) {
+ 		if (!bgmac->stats_grabbed) {
+ 			/* bgmac_chip_stats_update(bgmac); */
+ 			bgmac->stats_grabbed = true;
+@@ -920,7 +893,7 @@ static void bgmac_chip_reset(struct bgma
+ 		/* TODO: Clear software multicast filter list */
+ 	}
+ 
+-	iost = bcma_aread32(core, BCMA_IOST);
++	iost = bgmac_idm_read(bgmac, BCMA_IOST);
+ 	if (bgmac->feature_flags & BGMAC_FEAT_IOST_ATTACHED)
+ 		iost &= ~BGMAC_BCMA_IOST_ATTACHED;
+ 
+@@ -932,21 +905,20 @@ static void bgmac_chip_reset(struct bgma
+ 			if (!bgmac->has_robosw)
+ 				flags |= BGMAC_BCMA_IOCTL_SW_RESET;
+ 		}
+-		bcma_core_enable(core, flags);
++		bgmac_clk_enable(bgmac, flags);
+ 	}
+ 
+ 	/* Request Misc PLL for corerev > 2 */
+ 	if (bgmac->feature_flags & BGMAC_FEAT_MISC_PLL_REQ) {
+ 		bgmac_set(bgmac, BCMA_CLKCTLST,
+ 			  BGMAC_BCMA_CLKCTLST_MISC_PLL_REQ);
+-		bgmac_wait_value(bgmac->core, BCMA_CLKCTLST,
++		bgmac_wait_value(bgmac, BCMA_CLKCTLST,
+ 				 BGMAC_BCMA_CLKCTLST_MISC_PLL_ST,
+ 				 BGMAC_BCMA_CLKCTLST_MISC_PLL_ST,
+ 				 1000);
+ 	}
+ 
+ 	if (bgmac->feature_flags & BGMAC_FEAT_SW_TYPE_PHY) {
+-		struct bcma_drv_cc *cc = &bgmac->core->bus->drv_cc;
+ 		u8 et_swtype = 0;
+ 		u8 sw_type = BGMAC_CHIPCTL_1_SW_TYPE_EPHY |
+ 			     BGMAC_CHIPCTL_1_IF_TYPE_MII;
+@@ -965,16 +937,15 @@ static void bgmac_chip_reset(struct bgma
+ 			sw_type = BGMAC_CHIPCTL_1_IF_TYPE_RGMII |
+ 				  BGMAC_CHIPCTL_1_SW_TYPE_RGMII;
+ 		}
+-		bcma_chipco_chipctl_maskset(cc, 1,
+-					    ~(BGMAC_CHIPCTL_1_IF_TYPE_MASK |
+-					      BGMAC_CHIPCTL_1_SW_TYPE_MASK),
+-					    sw_type);
++		bgmac_cco_ctl_maskset(bgmac, 1, ~(BGMAC_CHIPCTL_1_IF_TYPE_MASK |
++						  BGMAC_CHIPCTL_1_SW_TYPE_MASK),
++				      sw_type);
+ 	}
+ 
+ 	if (iost & BGMAC_BCMA_IOST_ATTACHED && !bgmac->has_robosw)
+-		bcma_awrite32(core, BCMA_IOCTL,
+-			      bcma_aread32(core, BCMA_IOCTL) &
+-			      ~BGMAC_BCMA_IOCTL_SW_RESET);
++		bgmac_idm_write(bgmac, BCMA_IOCTL,
++				bgmac_idm_read(bgmac, BCMA_IOCTL) &
++				~BGMAC_BCMA_IOCTL_SW_RESET);
+ 
+ 	/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/gmac_reset
+ 	 * Specs don't say about using BGMAC_CMDCFG_SR, but in this routine
+@@ -1010,8 +981,8 @@ static void bgmac_chip_reset(struct bgma
+ 
+ 	bgmac_clear_mib(bgmac);
+ 	if (bgmac->feature_flags & BGMAC_FEAT_CMN_PHY_CTL)
+-		bcma_maskset32(bgmac->cmn, BCMA_GMAC_CMN_PHY_CTL, ~0,
+-			       BCMA_GMAC_CMN_PC_MTE);
++		bgmac_cmn_maskset32(bgmac, BCMA_GMAC_CMN_PHY_CTL, ~0,
++				    BCMA_GMAC_CMN_PC_MTE);
+ 	else
+ 		bgmac_set(bgmac, BGMAC_PHY_CNTL, BGMAC_PC_MTE);
+ 	bgmac_miiconfig(bgmac);
+@@ -1056,8 +1027,8 @@ static void bgmac_enable(struct bgmac *b
+ 	if (bgmac->feature_flags & BGMAC_FEAT_CLKCTLST || mode != 0)
+ 		bgmac_set(bgmac, BCMA_CLKCTLST, BCMA_CLKCTLST_FORCEHT);
+ 	if (bgmac->feature_flags & BGMAC_FEAT_CLKCTLST && mode == 2)
+-		bcma_chipco_chipctl_maskset(&bgmac->core->bus->drv_cc, 1, ~0,
+-					    BGMAC_CHIPCTL_1_RXC_DLL_BYPASS);
++		bgmac_cco_ctl_maskset(bgmac, 1, ~0,
++				      BGMAC_CHIPCTL_1_RXC_DLL_BYPASS);
+ 
+ 	if (bgmac->feature_flags & (BGMAC_FEAT_FLW_CTRL1 |
+ 				    BGMAC_FEAT_FLW_CTRL2)) {
+@@ -1079,8 +1050,7 @@ static void bgmac_enable(struct bgmac *b
+ 
+ 		rxq_ctl = bgmac_read(bgmac, BGMAC_RXQ_CTL);
+ 		rxq_ctl &= ~BGMAC_RXQ_CTL_MDP_MASK;
+-		bp_clk = bcma_pmu_get_bus_clock(&bgmac->core->bus->drv_cc) /
+-				1000000;
++		bp_clk = bgmac_get_bus_clock(bgmac) / 1000000;
+ 		mdp = (bp_clk * 128 / 1000) - 3;
+ 		rxq_ctl |= (mdp << BGMAC_RXQ_CTL_MDP_SHIFT);
+ 		bgmac_write(bgmac, BGMAC_RXQ_CTL, rxq_ctl);
+@@ -1175,7 +1145,7 @@ static int bgmac_open(struct net_device
+ 	/* Specs say about reclaiming rings here, but we do that in DMA init */
+ 	bgmac_chip_init(bgmac);
+ 
+-	err = request_irq(bgmac->core->irq, bgmac_interrupt, IRQF_SHARED,
++	err = request_irq(bgmac->irq, bgmac_interrupt, IRQF_SHARED,
+ 			  KBUILD_MODNAME, net_dev);
+ 	if (err < 0) {
+ 		dev_err(bgmac->dev, "IRQ request error: %d!\n", err);
+@@ -1201,7 +1171,7 @@ static int bgmac_stop(struct net_device
+ 
+ 	napi_disable(&bgmac->napi);
+ 	bgmac_chip_intrs_off(bgmac);
+-	free_irq(bgmac->core->irq, net_dev);
++	free_irq(bgmac->irq, net_dev);
+ 
+ 	bgmac_chip_reset(bgmac);
+ 	bgmac_dma_cleanup(bgmac);
+@@ -1396,7 +1366,7 @@ static void bgmac_get_drvinfo(struct net
+ 			      struct ethtool_drvinfo *info)
+ {
+ 	strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));
+-	strlcpy(info->bus_info, "BCMA", sizeof(info->bus_info));
++	strlcpy(info->bus_info, "AXI", sizeof(info->bus_info));
+ }
+ 
+ static const struct ethtool_ops bgmac_ethtool_ops = {
+@@ -1480,116 +1450,41 @@ static int bgmac_phy_connect(struct bgma
+ 	return 0;
+ }
+ 
+-static int bgmac_probe(struct bcma_device *core)
++int bgmac_enet_probe(struct bgmac *info)
+ {
+ 	struct net_device *net_dev;
+ 	struct bgmac *bgmac;
+-	struct ssb_sprom *sprom = &core->bus->sprom;
+-	u8 *mac;
+ 	int err;
+ 
+-	switch (core->core_unit) {
+-	case 0:
+-		mac = sprom->et0mac;
+-		break;
+-	case 1:
+-		mac = sprom->et1mac;
+-		break;
+-	case 2:
+-		mac = sprom->et2mac;
+-		break;
+-	default:
+-		dev_err(&core->dev, "Unsupported core_unit %d\n",
+-			core->core_unit);
+-		return -ENOTSUPP;
+-	}
+-
+-	if (!is_valid_ether_addr(mac)) {
+-		dev_err(&core->dev, "Invalid MAC addr: %pM\n", mac);
+-		eth_random_addr(mac);
+-		dev_warn(&core->dev, "Using random MAC: %pM\n", mac);
+-	}
+-
+-	/* This (reset &) enable is not preset in specs or reference driver but
+-	 * Broadcom does it in arch PCI code when enabling fake PCI device.
+-	 */
+-	bcma_core_enable(core, 0);
+-
+ 	/* Allocation and references */
+ 	net_dev = alloc_etherdev(sizeof(*bgmac));
+ 	if (!net_dev)
+ 		return -ENOMEM;
++
+ 	net_dev->netdev_ops = &bgmac_netdev_ops;
+-	net_dev->irq = core->irq;
+ 	net_dev->ethtool_ops = &bgmac_ethtool_ops;
+ 	bgmac = netdev_priv(net_dev);
+-	bgmac->dev = &core->dev;
+-	bgmac->dma_dev = core->dma_dev;
++	memcpy(bgmac, info, sizeof(*bgmac));
+ 	bgmac->net_dev = net_dev;
+-	bgmac->core = core;
+-	bcma_set_drvdata(core, bgmac);
+-	SET_NETDEV_DEV(net_dev, &core->dev);
+-
+-	/* Defaults */
+-	memcpy(bgmac->net_dev->dev_addr, mac, ETH_ALEN);
+-
+-	/* On BCM4706 we need common core to access PHY */
+-	if (core->id.id == BCMA_CORE_4706_MAC_GBIT &&
+-	    !core->bus->drv_gmac_cmn.core) {
+-		dev_err(bgmac->dev, "GMAC CMN core not found (required for BCM4706)\n");
+-		err = -ENODEV;
+-		goto err_netdev_free;
+-	}
+-	bgmac->cmn = core->bus->drv_gmac_cmn.core;
++	net_dev->irq = bgmac->irq;
++	SET_NETDEV_DEV(net_dev, bgmac->dev);
+ 
+-	switch (core->core_unit) {
+-	case 0:
+-		bgmac->phyaddr = sprom->et0phyaddr;
+-		break;
+-	case 1:
+-		bgmac->phyaddr = sprom->et1phyaddr;
+-		break;
+-	case 2:
+-		bgmac->phyaddr = sprom->et2phyaddr;
+-		break;
++	if (!is_valid_ether_addr(bgmac->mac_addr)) {
++		dev_err(bgmac->dev, "Invalid MAC addr: %pM\n",
++			bgmac->mac_addr);
++		eth_random_addr(bgmac->mac_addr);
++		dev_warn(bgmac->dev, "Using random MAC: %pM\n",
++			 bgmac->mac_addr);
+ 	}
+-	bgmac->phyaddr &= BGMAC_PHY_MASK;
+-	if (bgmac->phyaddr == BGMAC_PHY_MASK) {
+-		dev_err(bgmac->dev, "No PHY found\n");
+-		err = -ENODEV;
+-		goto err_netdev_free;
+-	}
+-	dev_info(bgmac->dev, "Found PHY addr: %d%s\n", bgmac->phyaddr,
+-		 bgmac->phyaddr == BGMAC_PHY_NOREGS ? " (NOREGS)" : "");
++	ether_addr_copy(net_dev->dev_addr, bgmac->mac_addr);
+ 
+-	if (core->bus->hosttype == BCMA_HOSTTYPE_PCI) {
+-		dev_err(bgmac->dev, "PCI setup not implemented\n");
+-		err = -ENOTSUPP;
+-		goto err_netdev_free;
+-	}
++	/* This (reset &) enable is not preset in specs or reference driver but
++	 * Broadcom does it in arch PCI code when enabling fake PCI device.
++	 */
++	bgmac_clk_enable(bgmac, 0);
+ 
+ 	bgmac_chip_reset(bgmac);
+ 
+-	/* For Northstar, we have to take all GMAC core out of reset */
+-	if (bgmac_is_bcm4707_family(bgmac)) {
+-		struct bcma_device *ns_core;
+-		int ns_gmac;
+-
+-		/* Northstar has 4 GMAC cores */
+-		for (ns_gmac = 0; ns_gmac < 4; ns_gmac++) {
+-			/* As Northstar requirement, we have to reset all GMACs
+-			 * before accessing one. bgmac_chip_reset() call
+-			 * bcma_core_enable() for this core. Then the other
+-			 * three GMACs didn't reset.  We do it here.
+-			 */
+-			ns_core = bcma_find_core_unit(core->bus,
+-						      BCMA_CORE_MAC_GBIT,
+-						      ns_gmac);
+-			if (ns_core && !bcma_core_is_enabled(ns_core))
+-				bcma_core_enable(ns_core, 0);
+-		}
+-	}
+-
+ 	err = bgmac_dma_alloc(bgmac);
+ 	if (err) {
+ 		dev_err(bgmac->dev, "Unable to alloc memory for DMA\n");
+@@ -1600,103 +1495,15 @@ static int bgmac_probe(struct bcma_devic
+ 	if (bcm47xx_nvram_getenv("et0_no_txint", NULL, 0) == 0)
+ 		bgmac->int_mask &= ~BGMAC_IS_TX_MASK;
+ 
+-	bgmac->has_robosw = !!(core->bus->sprom.boardflags_lo &
+-			       BGMAC_BFL_ENETROBO);
+-	if (bgmac->has_robosw)
+-		dev_warn(bgmac->dev, "Support for Roboswitch not implemented\n");
+-
+-	if (core->bus->sprom.boardflags_lo & BGMAC_BFL_ENETADM)
+-		dev_warn(bgmac->dev, "Support for ADMtek ethernet switch not implemented\n");
+-
+-	/* Feature Flags */
+-	switch (core->bus->chipinfo.id) {
+-	case BCMA_CHIP_ID_BCM5357:
+-		bgmac->feature_flags |= BGMAC_FEAT_SET_RXQ_CLK;
+-		bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;
+-		bgmac->feature_flags |= BGMAC_FEAT_FLW_CTRL1;
+-		bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_PHY;
+-		if (core->bus->chipinfo.pkg == BCMA_PKG_ID_BCM47186) {
+-			bgmac->feature_flags |= BGMAC_FEAT_IOST_ATTACHED;
+-			bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_RGMII;
+-		}
+-		if (core->bus->chipinfo.pkg == BCMA_PKG_ID_BCM5358)
+-			bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_EPHYRMII;
+-		break;
+-	case BCMA_CHIP_ID_BCM53572:
+-		bgmac->feature_flags |= BGMAC_FEAT_SET_RXQ_CLK;
+-		bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;
+-		bgmac->feature_flags |= BGMAC_FEAT_FLW_CTRL1;
+-		bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_PHY;
+-		if (core->bus->chipinfo.pkg == BCMA_PKG_ID_BCM47188) {
+-			bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_RGMII;
+-			bgmac->feature_flags |= BGMAC_FEAT_IOST_ATTACHED;
+-		}
+-		break;
+-	case BCMA_CHIP_ID_BCM4749:
+-		bgmac->feature_flags |= BGMAC_FEAT_SET_RXQ_CLK;
+-		bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;
+-		bgmac->feature_flags |= BGMAC_FEAT_FLW_CTRL1;
+-		bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_PHY;
+-		if (core->bus->chipinfo.pkg == 10) {
+-			bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_RGMII;
+-			bgmac->feature_flags |= BGMAC_FEAT_IOST_ATTACHED;
+-		}
+-		break;
+-	case BCMA_CHIP_ID_BCM4716:
+-		bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;
+-		/* fallthrough */
+-	case BCMA_CHIP_ID_BCM47162:
+-		bgmac->feature_flags |= BGMAC_FEAT_FLW_CTRL2;
+-		bgmac->feature_flags |= BGMAC_FEAT_SET_RXQ_CLK;
+-		break;
+-	/* bcm4707_family */
+-	case BCMA_CHIP_ID_BCM4707:
+-	case BCMA_CHIP_ID_BCM47094:
+-	case BCMA_CHIP_ID_BCM53018:
+-		bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;
+-		bgmac->feature_flags |= BGMAC_FEAT_NO_RESET;
+-		bgmac->feature_flags |= BGMAC_FEAT_FORCE_SPEED_2500;
+-		break;
+-	default:
+-		bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;
+-		bgmac->feature_flags |= BGMAC_FEAT_SET_RXQ_CLK;
+-	}
+-
+-	if (!bgmac_is_bcm4707_family(bgmac) && core->id.rev > 2)
+-		bgmac->feature_flags |= BGMAC_FEAT_MISC_PLL_REQ;
+-
+-	if (core->id.id == BCMA_CORE_4706_MAC_GBIT) {
+-		bgmac->feature_flags |= BGMAC_FEAT_CMN_PHY_CTL;
+-		bgmac->feature_flags |= BGMAC_FEAT_NO_CLR_MIB;
+-	}
+-
+-	if (core->id.rev >= 4) {
+-		bgmac->feature_flags |= BGMAC_FEAT_CMDCFG_SR_REV4;
+-		bgmac->feature_flags |= BGMAC_FEAT_TX_MASK_SETUP;
+-		bgmac->feature_flags |= BGMAC_FEAT_RX_MASK_SETUP;
+-	}
+-
+ 	netif_napi_add(net_dev, &bgmac->napi, bgmac_poll, BGMAC_WEIGHT);
+ 
+-	if (!bgmac_is_bcm4707_family(bgmac)) {
+-		struct mii_bus *mii_bus;
+-
+-		mii_bus = bcma_mdio_mii_register(core, bgmac->phyaddr);
+-		if (!IS_ERR(mii_bus)) {
+-			err = PTR_ERR(mii_bus);
+-			goto err_dma_free;
+-		}
+-
+-		bgmac->mii_bus = mii_bus;
+-	}
+-
+ 	if (!bgmac->mii_bus)
+ 		err = bgmac_phy_connect_direct(bgmac);
+ 	else
+ 		err = bgmac_phy_connect(bgmac);
+ 	if (err) {
+ 		dev_err(bgmac->dev, "Cannot connect to phy\n");
+-		goto err_mii_unregister;
++		goto err_dma_free;
+ 	}
+ 
+ 	net_dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+@@ -1715,56 +1522,24 @@ static int bgmac_probe(struct bcma_devic
+ 
+ err_phy_disconnect:
+ 	phy_disconnect(net_dev->phydev);
+-err_mii_unregister:
+-	bcma_mdio_mii_unregister(bgmac->mii_bus);
+ err_dma_free:
+ 	bgmac_dma_free(bgmac);
+ err_netdev_free:
+-	bcma_set_drvdata(core, NULL);
+ 	free_netdev(net_dev);
+ 
+ 	return err;
+ }
++EXPORT_SYMBOL_GPL(bgmac_enet_probe);
+ 
+-static void bgmac_remove(struct bcma_device *core)
++void bgmac_enet_remove(struct bgmac *bgmac)
+ {
+-	struct bgmac *bgmac = bcma_get_drvdata(core);
+-
+ 	unregister_netdev(bgmac->net_dev);
+ 	phy_disconnect(bgmac->net_dev->phydev);
+-	bcma_mdio_mii_unregister(bgmac->mii_bus);
+ 	netif_napi_del(&bgmac->napi);
+ 	bgmac_dma_free(bgmac);
+-	bcma_set_drvdata(core, NULL);
+ 	free_netdev(bgmac->net_dev);
+ }
+-
+-static struct bcma_driver bgmac_bcma_driver = {
+-	.name		= KBUILD_MODNAME,
+-	.id_table	= bgmac_bcma_tbl,
+-	.probe		= bgmac_probe,
+-	.remove		= bgmac_remove,
+-};
+-
+-static int __init bgmac_init(void)
+-{
+-	int err;
+-
+-	err = bcma_driver_register(&bgmac_bcma_driver);
+-	if (err)
+-		return err;
+-	pr_info("Broadcom 47xx GBit MAC driver loaded\n");
+-
+-	return 0;
+-}
+-
+-static void __exit bgmac_exit(void)
+-{
+-	bcma_driver_unregister(&bgmac_bcma_driver);
+-}
+-
+-module_init(bgmac_init)
+-module_exit(bgmac_exit)
++EXPORT_SYMBOL_GPL(bgmac_enet_remove);
+ 
+ MODULE_AUTHOR("Rafał Miłecki");
+ MODULE_LICENSE("GPL");
+--- a/drivers/net/ethernet/broadcom/bgmac.h
++++ b/drivers/net/ethernet/broadcom/bgmac.h
+@@ -1,8 +1,6 @@
+ #ifndef _BGMAC_H
+ #define _BGMAC_H
+ 
+-#include <linux/bcma/bcma.h>
+-#include <linux/brcmphy.h>
+ #include <linux/netdevice.h>
+ 
+ #define BGMAC_DEV_CTL				0x000
+@@ -442,11 +440,21 @@ struct bgmac_rx_header {
+ };
+ 
+ struct bgmac {
+-	struct bcma_device *core;
+-	struct bcma_device *cmn; /* Reference to CMN core for BCM4706 */
++	union {
++		struct {
++			void *base;
++			void *idm_base;
++		} plat;
++		struct {
++			struct bcma_device *core;
++			/* Reference to CMN core for BCM4706 */
++			struct bcma_device *cmn;
++		} bcma;
++	};
+ 
+ 	struct device *dev;
+ 	struct device *dma_dev;
++	unsigned char mac_addr[ETH_ALEN];
+ 	u32 feature_flags;
+ 
+ 	struct net_device *net_dev;
+@@ -463,6 +471,7 @@ struct bgmac {
+ 	u32 mib_rx_regs[BGMAC_NUM_MIB_RX_REGS];
+ 
+ 	/* Int */
++	int irq;
+ 	u32 int_mask;
+ 
+ 	/* Current MAC state */
+@@ -473,19 +482,71 @@ struct bgmac {
+ 	bool has_robosw;
+ 
+ 	bool loopback;
++
++	u32 (*read)(struct bgmac *bgmac, u16 offset);
++	void (*write)(struct bgmac *bgmac, u16 offset, u32 value);
++	u32 (*idm_read)(struct bgmac *bgmac, u16 offset);
++	void (*idm_write)(struct bgmac *bgmac, u16 offset, u32 value);
++	bool (*clk_enabled)(struct bgmac *bgmac);
++	void (*clk_enable)(struct bgmac *bgmac, u32 flags);
++	void (*cco_ctl_maskset)(struct bgmac *bgmac, u32 offset, u32 mask,
++				u32 set);
++	u32 (*get_bus_clock)(struct bgmac *bgmac);
++	void (*cmn_maskset32)(struct bgmac *bgmac, u16 offset, u32 mask,
++			      u32 set);
+ };
+ 
++int bgmac_enet_probe(struct bgmac *info);
++void bgmac_enet_remove(struct bgmac *bgmac);
++
+ struct mii_bus *bcma_mdio_mii_register(struct bcma_device *core, u8 phyaddr);
+ void bcma_mdio_mii_unregister(struct mii_bus *mii_bus);
+ 
+ static inline u32 bgmac_read(struct bgmac *bgmac, u16 offset)
+ {
+-	return bcma_read32(bgmac->core, offset);
++	return bgmac->read(bgmac, offset);
+ }
+ 
+ static inline void bgmac_write(struct bgmac *bgmac, u16 offset, u32 value)
+ {
+-	bcma_write32(bgmac->core, offset, value);
++	bgmac->write(bgmac, offset, value);
++}
++
++static inline u32 bgmac_idm_read(struct bgmac *bgmac, u16 offset)
++{
++	return bgmac->idm_read(bgmac, offset);
++}
++
++static inline void bgmac_idm_write(struct bgmac *bgmac, u16 offset, u32 value)
++{
++	bgmac->idm_write(bgmac, offset, value);
++}
++
++static inline bool bgmac_clk_enabled(struct bgmac *bgmac)
++{
++	return bgmac->clk_enabled(bgmac);
++}
++
++static inline void bgmac_clk_enable(struct bgmac *bgmac, u32 flags)
++{
++	bgmac->clk_enable(bgmac, flags);
++}
++
++static inline void bgmac_cco_ctl_maskset(struct bgmac *bgmac, u32 offset,
++					 u32 mask, u32 set)
++{
++	bgmac->cco_ctl_maskset(bgmac, offset, mask, set);
++}
++
++static inline u32 bgmac_get_bus_clock(struct bgmac *bgmac)
++{
++	return bgmac->get_bus_clock(bgmac);
++}
++
++static inline void bgmac_cmn_maskset32(struct bgmac *bgmac, u16 offset,
++				       u32 mask, u32 set)
++{
++	bgmac->cmn_maskset32(bgmac, offset, mask, set);
+ }
+ 
+ static inline void bgmac_maskset(struct bgmac *bgmac, u16 offset, u32 mask,
diff --git a/target/linux/generic/patches-4.4/773-bgmac-add-srab-switch.patch b/target/linux/generic/patches-4.4/773-bgmac-add-srab-switch.patch
index 13d3305..d578978 100644
--- a/target/linux/generic/patches-4.4/773-bgmac-add-srab-switch.patch
+++ b/target/linux/generic/patches-4.4/773-bgmac-add-srab-switch.patch
@@ -4,15 +4,15 @@ Signed-off-by: Hauke Mehrtens <hauke at hauke-m.de>
 
 --- a/drivers/net/ethernet/broadcom/bgmac.c
 +++ b/drivers/net/ethernet/broadcom/bgmac.c
-@@ -17,6 +17,7 @@
- #include <linux/phy_fixed.h>
- #include <linux/interrupt.h>
- #include <linux/dma-mapping.h>
+@@ -11,6 +11,7 @@
+ 
+ #include <linux/bcma/bcma.h>
+ #include <linux/etherdevice.h>
 +#include <linux/platform_data/b53.h>
  #include <linux/bcm47xx_nvram.h>
+ #include "bgmac.h"
  
- static const struct bcma_device_id bgmac_bcma_tbl[] = {
-@@ -1408,6 +1409,17 @@ static const struct ethtool_ops bgmac_et
+@@ -1378,6 +1379,17 @@ static const struct ethtool_ops bgmac_et
  	.get_drvinfo		= bgmac_get_drvinfo,
  };
  
@@ -30,15 +30,7 @@ Signed-off-by: Hauke Mehrtens <hauke at hauke-m.de>
  /**************************************************
   * MII
   **************************************************/
-@@ -1656,6 +1668,7 @@ static int bgmac_probe(struct bcma_devic
- 		bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;
- 		bgmac->feature_flags |= BGMAC_FEAT_NO_RESET;
- 		bgmac->feature_flags |= BGMAC_FEAT_FORCE_SPEED_2500;
-+		bgmac->feature_flags |= BGMAC_FEAT_SRAB;
- 		break;
- 	default:
- 		bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;
-@@ -1703,6 +1716,14 @@ static int bgmac_probe(struct bcma_devic
+@@ -1510,6 +1522,14 @@ int bgmac_enet_probe(struct bgmac *info)
  	net_dev->hw_features = net_dev->features;
  	net_dev->vlan_features = net_dev->features;
  
@@ -53,20 +45,20 @@ Signed-off-by: Hauke Mehrtens <hauke at hauke-m.de>
  	err = register_netdev(bgmac->net_dev);
  	if (err) {
  		dev_err(bgmac->dev, "Cannot register net device\n");
-@@ -1730,6 +1751,10 @@ static void bgmac_remove(struct bcma_dev
- {
- 	struct bgmac *bgmac = bcma_get_drvdata(core);
+@@ -1533,6 +1553,10 @@ EXPORT_SYMBOL_GPL(bgmac_enet_probe);
  
+ void bgmac_enet_remove(struct bgmac *bgmac)
+ {
 +	if (bgmac->b53_device)
 +		platform_device_unregister(&bgmac_b53_dev);
 +	bgmac->b53_device = NULL;
 +
  	unregister_netdev(bgmac->net_dev);
  	phy_disconnect(bgmac->net_dev->phydev);
- 	bcma_mdio_mii_unregister(bgmac->mii_bus);
+ 	netif_napi_del(&bgmac->napi);
 --- a/drivers/net/ethernet/broadcom/bgmac.h
 +++ b/drivers/net/ethernet/broadcom/bgmac.h
-@@ -392,6 +392,7 @@
+@@ -390,6 +390,7 @@
  #define BGMAC_FEAT_NO_CLR_MIB		BIT(13)
  #define BGMAC_FEAT_FORCE_SPEED_2500	BIT(14)
  #define BGMAC_FEAT_CMDCFG_SR_REV4	BIT(15)
@@ -74,13 +66,23 @@ Signed-off-by: Hauke Mehrtens <hauke at hauke-m.de>
  
  struct bgmac_slot_info {
  	union {
-@@ -473,6 +474,9 @@ struct bgmac {
- 	bool has_robosw;
- 
- 	bool loopback;
+@@ -494,6 +495,9 @@ struct bgmac {
+ 	u32 (*get_bus_clock)(struct bgmac *bgmac);
+ 	void (*cmn_maskset32)(struct bgmac *bgmac, u16 offset, u32 mask,
+ 			      u32 set);
 +
 +	/* platform device for associated switch */
 +	struct platform_device *b53_device;
  };
  
- struct mii_bus *bcma_mdio_mii_register(struct bcma_device *core, u8 phyaddr);
+ int bgmac_enet_probe(struct bgmac *info);
+--- a/drivers/net/ethernet/broadcom/bgmac-bcma.c
++++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c
+@@ -229,6 +229,7 @@ static int bgmac_probe(struct bcma_devic
+ 		bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;
+ 		bgmac->feature_flags |= BGMAC_FEAT_NO_RESET;
+ 		bgmac->feature_flags |= BGMAC_FEAT_FORCE_SPEED_2500;
++		bgmac->feature_flags |= BGMAC_FEAT_SRAB;
+ 		break;
+ 	default:
+ 		bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;



More information about the lede-commits mailing list