123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260 |
- 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))
- @@ -643,7 +619,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;
- }
- @@ -875,12 +851,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);
- @@ -900,12 +874,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;
- @@ -923,7 +896,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;
-
- @@ -935,21 +908,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;
- @@ -968,16 +940,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
- @@ -1013,8 +984,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);
- @@ -1059,8 +1030,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)) {
- @@ -1082,8 +1053,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);
- @@ -1178,7 +1148,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);
- @@ -1204,7 +1174,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);
- @@ -1399,7 +1369,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 = {
- @@ -1483,116 +1453,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");
- @@ -1603,103 +1498,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;
- @@ -1718,56 +1525,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,
|