From: Rafał Miłecki Date: Wed, 17 Aug 2016 07:30:44 +0000 (+0200) Subject: kernel: bgmac: backport patch adding platform support X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=93f2aa44f7833bd8d762ae4ef62c9f681ed58eef;p=openwrt%2Fstaging%2Fneocturne.git 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 --- diff --git a/target/linux/bcm53xx/config-4.4 b/target/linux/bcm53xx/config-4.4 index 625b7e7e87..2eeafc816b 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 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 +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 +Acked-by: Arnd Bergmann +Reviewed-by: Florian Fainelli +Tested-by: Florian Fainelli +Signed-off-by: David S. Miller +--- + 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 ++ * ++ * Licensed under the GNU/GPL. See COPYING for details. ++ */ ++ ++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt ++ ++#include ++#include ++#include ++#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 ++#include ++#include ++#include ++#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 +-#include +-#include ++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt ++ ++#include + #include +-#include +-#include +-#include +-#include +-#include + #include ++#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 +-#include + #include + + #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 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c -@@ -17,6 +17,7 @@ - #include - #include - #include +@@ -11,6 +11,7 @@ + + #include + #include +#include #include + #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 /************************************************** * 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 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 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;