summaryrefslogtreecommitdiffstats
path: root/target/linux/generic
diff options
context:
space:
mode:
authorRafał Miłecki <rafal@milecki.pl>2016-08-17 09:30:44 +0200
committerRafał Miłecki <rafal@milecki.pl>2016-08-17 12:41:20 +0200
commit93f2aa44f7833bd8d762ae4ef62c9f681ed58eef (patch)
tree99157b684ba6a7bcc4361b9bb18d766a44c6b88a /target/linux/generic
parent533d16822c84bf33ff5d18b775dafd3ab4810b17 (diff)
downloadmaster-31e0f0ae-93f2aa44f7833bd8d762ae4ef62c9f681ed58eef.tar.gz
master-31e0f0ae-93f2aa44f7833bd8d762ae4ef62c9f681ed58eef.tar.bz2
master-31e0f0ae-93f2aa44f7833bd8d762ae4ef62c9f681ed58eef.zip
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@milecki.pl>
Diffstat (limited to 'target/linux/generic')
-rw-r--r--target/linux/generic/patches-4.4/075-0005-net-ethernet-bgmac-Add-platform-device-support.patch1260
-rw-r--r--target/linux/generic/patches-4.4/773-bgmac-add-srab-switch.patch52
2 files changed, 1287 insertions, 25 deletions
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 0000000000..4a69524761
--- /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@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@broadcom.com>
+Acked-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Tested-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@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@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 13d3305dec..d57897808d 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@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@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@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@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;