123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676 |
- From 55954f3bfdacc5908515b0c306cea23e77fab740 Mon Sep 17 00:00:00 2001
- From: Jon Mason <jon.mason@broadcom.com>
- Date: Thu, 7 Jul 2016 19:08:55 -0400
- Subject: [PATCH 3/5] net: ethernet: bgmac: move BCMA MDIO Phy code into a
- separate file
- Move the BCMA MDIO phy into a separate file, as it is very tightly
- coupled with the BCMA bus. This will help with the upcoming BCMA
- removal from the bgmac driver. Optimally, this should be moved into
- phy drivers, but it is too tightly coupled with the bgmac driver to
- effectively move it without more changes to the driver.
- Note: the phy_reset was intentionally removed, as the mdio phy subsystem
- automatically resets the phy if a reset function pointer is present. In
- addition to the moving of the driver, this reset function is added.
- 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/Makefile | 2 +-
- drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c | 264 ++++++++++++++++++++++++
- drivers/net/ethernet/broadcom/bgmac.c | 246 +++-------------------
- drivers/net/ethernet/broadcom/bgmac.h | 3 +
- 4 files changed, 298 insertions(+), 217 deletions(-)
- create mode 100644 drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c
- --- a/drivers/net/ethernet/broadcom/Makefile
- +++ b/drivers/net/ethernet/broadcom/Makefile
- @@ -10,6 +10,6 @@ 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
- +obj-$(CONFIG_BGMAC) += bgmac.o bgmac-bcma-mdio.o
- obj-$(CONFIG_SYSTEMPORT) += bcmsysport.o
- obj-$(CONFIG_BNXT) += bnxt/
- --- /dev/null
- +++ b/drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c
- @@ -0,0 +1,275 @@
- +/*
- + * 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 "bgmac.h"
- +
- +struct bcma_mdio {
- + struct bcma_device *core;
- + u8 phyaddr;
- +};
- +
- +static bool bcma_mdio_wait_value(struct bcma_device *core, u16 reg, u32 mask,
- + u32 value, int timeout)
- +{
- + u32 val;
- + int i;
- +
- + for (i = 0; i < timeout / 10; i++) {
- + val = bcma_read32(core, reg);
- + if ((val & mask) == value)
- + return true;
- + udelay(10);
- + }
- + dev_err(&core->dev, "Timeout waiting for reg 0x%X\n", reg);
- + return false;
- +}
- +
- +/**************************************************
- + * PHY ops
- + **************************************************/
- +
- +static u16 bcma_mdio_phy_read(struct bcma_mdio *bcma_mdio, u8 phyaddr, u8 reg)
- +{
- + struct bcma_device *core;
- + u16 phy_access_addr;
- + u16 phy_ctl_addr;
- + u32 tmp;
- +
- + BUILD_BUG_ON(BGMAC_PA_DATA_MASK != BCMA_GMAC_CMN_PA_DATA_MASK);
- + BUILD_BUG_ON(BGMAC_PA_ADDR_MASK != BCMA_GMAC_CMN_PA_ADDR_MASK);
- + BUILD_BUG_ON(BGMAC_PA_ADDR_SHIFT != BCMA_GMAC_CMN_PA_ADDR_SHIFT);
- + BUILD_BUG_ON(BGMAC_PA_REG_MASK != BCMA_GMAC_CMN_PA_REG_MASK);
- + BUILD_BUG_ON(BGMAC_PA_REG_SHIFT != BCMA_GMAC_CMN_PA_REG_SHIFT);
- + BUILD_BUG_ON(BGMAC_PA_WRITE != BCMA_GMAC_CMN_PA_WRITE);
- + BUILD_BUG_ON(BGMAC_PA_START != BCMA_GMAC_CMN_PA_START);
- + BUILD_BUG_ON(BGMAC_PC_EPA_MASK != BCMA_GMAC_CMN_PC_EPA_MASK);
- + BUILD_BUG_ON(BGMAC_PC_MCT_MASK != BCMA_GMAC_CMN_PC_MCT_MASK);
- + BUILD_BUG_ON(BGMAC_PC_MCT_SHIFT != BCMA_GMAC_CMN_PC_MCT_SHIFT);
- + BUILD_BUG_ON(BGMAC_PC_MTE != BCMA_GMAC_CMN_PC_MTE);
- +
- + if (bcma_mdio->core->id.id == BCMA_CORE_4706_MAC_GBIT) {
- + core = bcma_mdio->core->bus->drv_gmac_cmn.core;
- + phy_access_addr = BCMA_GMAC_CMN_PHY_ACCESS;
- + phy_ctl_addr = BCMA_GMAC_CMN_PHY_CTL;
- + } else {
- + core = bcma_mdio->core;
- + phy_access_addr = BGMAC_PHY_ACCESS;
- + phy_ctl_addr = BGMAC_PHY_CNTL;
- + }
- +
- + tmp = bcma_read32(core, phy_ctl_addr);
- + tmp &= ~BGMAC_PC_EPA_MASK;
- + tmp |= phyaddr;
- + bcma_write32(core, phy_ctl_addr, tmp);
- +
- + tmp = BGMAC_PA_START;
- + tmp |= phyaddr << BGMAC_PA_ADDR_SHIFT;
- + tmp |= reg << BGMAC_PA_REG_SHIFT;
- + bcma_write32(core, phy_access_addr, tmp);
- +
- + if (!bcma_mdio_wait_value(core, phy_access_addr, BGMAC_PA_START, 0,
- + 1000)) {
- + dev_err(&core->dev, "Reading PHY %d register 0x%X failed\n",
- + phyaddr, reg);
- + return 0xffff;
- + }
- +
- + return bcma_read32(core, phy_access_addr) & BGMAC_PA_DATA_MASK;
- +}
- +
- +/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphywr */
- +static int bcma_mdio_phy_write(struct bcma_mdio *bcma_mdio, u8 phyaddr, u8 reg,
- + u16 value)
- +{
- + struct bcma_device *core;
- + u16 phy_access_addr;
- + u16 phy_ctl_addr;
- + u32 tmp;
- +
- + if (bcma_mdio->core->id.id == BCMA_CORE_4706_MAC_GBIT) {
- + core = bcma_mdio->core->bus->drv_gmac_cmn.core;
- + phy_access_addr = BCMA_GMAC_CMN_PHY_ACCESS;
- + phy_ctl_addr = BCMA_GMAC_CMN_PHY_CTL;
- + } else {
- + core = bcma_mdio->core;
- + phy_access_addr = BGMAC_PHY_ACCESS;
- + phy_ctl_addr = BGMAC_PHY_CNTL;
- + }
- +
- + tmp = bcma_read32(core, phy_ctl_addr);
- + tmp &= ~BGMAC_PC_EPA_MASK;
- + tmp |= phyaddr;
- + bcma_write32(core, phy_ctl_addr, tmp);
- +
- + bcma_write32(bcma_mdio->core, BGMAC_INT_STATUS, BGMAC_IS_MDIO);
- + if (bcma_read32(bcma_mdio->core, BGMAC_INT_STATUS) & BGMAC_IS_MDIO)
- + dev_warn(&core->dev, "Error setting MDIO int\n");
- +
- + tmp = BGMAC_PA_START;
- + tmp |= BGMAC_PA_WRITE;
- + tmp |= phyaddr << BGMAC_PA_ADDR_SHIFT;
- + tmp |= reg << BGMAC_PA_REG_SHIFT;
- + tmp |= value;
- + bcma_write32(core, phy_access_addr, tmp);
- +
- + if (!bcma_mdio_wait_value(core, phy_access_addr, BGMAC_PA_START, 0,
- + 1000)) {
- + dev_err(&core->dev, "Writing to PHY %d register 0x%X failed\n",
- + phyaddr, reg);
- + return -ETIMEDOUT;
- + }
- +
- + return 0;
- +}
- +
- +/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphyinit */
- +static void bcma_mdio_phy_init(struct bcma_mdio *bcma_mdio)
- +{
- + struct bcma_chipinfo *ci = &bcma_mdio->core->bus->chipinfo;
- + u8 i;
- +
- + if (ci->id == BCMA_CHIP_ID_BCM5356) {
- + for (i = 0; i < 5; i++) {
- + bcma_mdio_phy_write(bcma_mdio, i, 0x1f, 0x008b);
- + bcma_mdio_phy_write(bcma_mdio, i, 0x15, 0x0100);
- + bcma_mdio_phy_write(bcma_mdio, i, 0x1f, 0x000f);
- + bcma_mdio_phy_write(bcma_mdio, i, 0x12, 0x2aaa);
- + bcma_mdio_phy_write(bcma_mdio, i, 0x1f, 0x000b);
- + }
- + }
- + if ((ci->id == BCMA_CHIP_ID_BCM5357 && ci->pkg != 10) ||
- + (ci->id == BCMA_CHIP_ID_BCM4749 && ci->pkg != 10) ||
- + (ci->id == BCMA_CHIP_ID_BCM53572 && ci->pkg != 9)) {
- + struct bcma_drv_cc *cc = &bcma_mdio->core->bus->drv_cc;
- +
- + bcma_chipco_chipctl_maskset(cc, 2, ~0xc0000000, 0);
- + bcma_chipco_chipctl_maskset(cc, 4, ~0x80000000, 0);
- + for (i = 0; i < 5; i++) {
- + bcma_mdio_phy_write(bcma_mdio, i, 0x1f, 0x000f);
- + bcma_mdio_phy_write(bcma_mdio, i, 0x16, 0x5284);
- + bcma_mdio_phy_write(bcma_mdio, i, 0x1f, 0x000b);
- + bcma_mdio_phy_write(bcma_mdio, i, 0x17, 0x0010);
- + bcma_mdio_phy_write(bcma_mdio, i, 0x1f, 0x000f);
- + bcma_mdio_phy_write(bcma_mdio, i, 0x16, 0x5296);
- + bcma_mdio_phy_write(bcma_mdio, i, 0x17, 0x1073);
- + bcma_mdio_phy_write(bcma_mdio, i, 0x17, 0x9073);
- + bcma_mdio_phy_write(bcma_mdio, i, 0x16, 0x52b6);
- + bcma_mdio_phy_write(bcma_mdio, i, 0x17, 0x9273);
- + bcma_mdio_phy_write(bcma_mdio, i, 0x1f, 0x000b);
- + }
- + }
- +}
- +
- +/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphyreset */
- +static int bcma_mdio_phy_reset(struct mii_bus *bus)
- +{
- + struct bcma_mdio *bcma_mdio = bus->priv;
- + u8 phyaddr = bcma_mdio->phyaddr;
- +
- + if (bcma_mdio->phyaddr == BGMAC_PHY_NOREGS)
- + return 0;
- +
- + bcma_mdio_phy_write(bcma_mdio, phyaddr, MII_BMCR, BMCR_RESET);
- + udelay(100);
- + if (bcma_mdio_phy_read(bcma_mdio, phyaddr, MII_BMCR) & BMCR_RESET)
- + dev_err(&bcma_mdio->core->dev, "PHY reset failed\n");
- + bcma_mdio_phy_init(bcma_mdio);
- +
- + return 0;
- +}
- +
- +/**************************************************
- + * MII
- + **************************************************/
- +
- +static int bcma_mdio_mii_read(struct mii_bus *bus, int mii_id, int regnum)
- +{
- + return bcma_mdio_phy_read(bus->priv, mii_id, regnum);
- +}
- +
- +static int bcma_mdio_mii_write(struct mii_bus *bus, int mii_id, int regnum,
- + u16 value)
- +{
- + return bcma_mdio_phy_write(bus->priv, mii_id, regnum, value);
- +}
- +
- +struct mii_bus *bcma_mdio_mii_register(struct bcma_device *core, u8 phyaddr)
- +{
- + struct bcma_mdio *bcma_mdio;
- + struct mii_bus *mii_bus;
- + int i, err;
- +
- + bcma_mdio = kzalloc(sizeof(*bcma_mdio), GFP_KERNEL);
- + if (!bcma_mdio)
- + return ERR_PTR(-ENOMEM);
- +
- + mii_bus = mdiobus_alloc();
- + if (!mii_bus) {
- + err = -ENOMEM;
- + goto err;
- + }
- +
- + mii_bus->name = "bcma_mdio mii bus";
- + sprintf(mii_bus->id, "%s-%d-%d", "bcma_mdio", core->bus->num,
- + core->core_unit);
- + mii_bus->priv = bcma_mdio;
- + mii_bus->read = bcma_mdio_mii_read;
- + mii_bus->write = bcma_mdio_mii_write;
- + mii_bus->reset = bcma_mdio_phy_reset;
- + mii_bus->parent = &core->dev;
- + mii_bus->phy_mask = ~(1 << phyaddr);
- +
- + mii_bus->irq = kmalloc_array(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL);
- + if (!mii_bus->irq) {
- + err = -ENOMEM;
- + goto err_free_bus;
- + }
- + for (i = 0; i < PHY_MAX_ADDR; i++)
- + mii_bus->irq[i] = PHY_POLL;
- +
- + bcma_mdio->core = core;
- + bcma_mdio->phyaddr = phyaddr;
- +
- + err = mdiobus_register(mii_bus);
- + if (err) {
- + dev_err(&core->dev, "Registration of mii bus failed\n");
- + goto err_free_irq;
- + }
- +
- + return mii_bus;
- +
- +err_free_irq:
- + kfree(mii_bus->irq);
- +err_free_bus:
- + mdiobus_free(mii_bus);
- +err:
- + kfree(bcma_mdio);
- + return ERR_PTR(err);
- +}
- +
- +void bcma_mdio_mii_unregister(struct mii_bus *mii_bus)
- +{
- + struct bcma_mdio *bcma_mdio;
- +
- + if (!mii_bus)
- + return;
- +
- + bcma_mdio = mii_bus->priv;
- +
- + mdiobus_unregister(mii_bus);
- + kfree(mii_bus->irq);
- + mdiobus_free(mii_bus);
- + kfree(bcma_mdio);
- +}
- +
- +MODULE_AUTHOR("Rafał Miłecki");
- +MODULE_LICENSE("GPL");
- --- a/drivers/net/ethernet/broadcom/bgmac.c
- +++ b/drivers/net/ethernet/broadcom/bgmac.c
- @@ -760,150 +760,6 @@ error:
- return err;
- }
-
- -/**************************************************
- - * PHY ops
- - **************************************************/
- -
- -static u16 bgmac_phy_read(struct bgmac *bgmac, u8 phyaddr, u8 reg)
- -{
- - struct bcma_device *core;
- - u16 phy_access_addr;
- - u16 phy_ctl_addr;
- - u32 tmp;
- -
- - BUILD_BUG_ON(BGMAC_PA_DATA_MASK != BCMA_GMAC_CMN_PA_DATA_MASK);
- - BUILD_BUG_ON(BGMAC_PA_ADDR_MASK != BCMA_GMAC_CMN_PA_ADDR_MASK);
- - BUILD_BUG_ON(BGMAC_PA_ADDR_SHIFT != BCMA_GMAC_CMN_PA_ADDR_SHIFT);
- - BUILD_BUG_ON(BGMAC_PA_REG_MASK != BCMA_GMAC_CMN_PA_REG_MASK);
- - BUILD_BUG_ON(BGMAC_PA_REG_SHIFT != BCMA_GMAC_CMN_PA_REG_SHIFT);
- - BUILD_BUG_ON(BGMAC_PA_WRITE != BCMA_GMAC_CMN_PA_WRITE);
- - BUILD_BUG_ON(BGMAC_PA_START != BCMA_GMAC_CMN_PA_START);
- - BUILD_BUG_ON(BGMAC_PC_EPA_MASK != BCMA_GMAC_CMN_PC_EPA_MASK);
- - BUILD_BUG_ON(BGMAC_PC_MCT_MASK != BCMA_GMAC_CMN_PC_MCT_MASK);
- - BUILD_BUG_ON(BGMAC_PC_MCT_SHIFT != BCMA_GMAC_CMN_PC_MCT_SHIFT);
- - BUILD_BUG_ON(BGMAC_PC_MTE != BCMA_GMAC_CMN_PC_MTE);
- -
- - if (bgmac->core->id.id == BCMA_CORE_4706_MAC_GBIT) {
- - core = bgmac->core->bus->drv_gmac_cmn.core;
- - phy_access_addr = BCMA_GMAC_CMN_PHY_ACCESS;
- - phy_ctl_addr = BCMA_GMAC_CMN_PHY_CTL;
- - } else {
- - core = bgmac->core;
- - phy_access_addr = BGMAC_PHY_ACCESS;
- - phy_ctl_addr = BGMAC_PHY_CNTL;
- - }
- -
- - tmp = bcma_read32(core, phy_ctl_addr);
- - tmp &= ~BGMAC_PC_EPA_MASK;
- - tmp |= phyaddr;
- - bcma_write32(core, phy_ctl_addr, tmp);
- -
- - tmp = BGMAC_PA_START;
- - tmp |= phyaddr << BGMAC_PA_ADDR_SHIFT;
- - tmp |= reg << BGMAC_PA_REG_SHIFT;
- - bcma_write32(core, phy_access_addr, tmp);
- -
- - if (!bgmac_wait_value(core, phy_access_addr, BGMAC_PA_START, 0, 1000)) {
- - dev_err(bgmac->dev, "Reading PHY %d register 0x%X failed\n",
- - phyaddr, reg);
- - return 0xffff;
- - }
- -
- - return bcma_read32(core, phy_access_addr) & BGMAC_PA_DATA_MASK;
- -}
- -
- -/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphywr */
- -static int bgmac_phy_write(struct bgmac *bgmac, u8 phyaddr, u8 reg, u16 value)
- -{
- - struct bcma_device *core;
- - u16 phy_access_addr;
- - u16 phy_ctl_addr;
- - u32 tmp;
- -
- - if (bgmac->core->id.id == BCMA_CORE_4706_MAC_GBIT) {
- - core = bgmac->core->bus->drv_gmac_cmn.core;
- - phy_access_addr = BCMA_GMAC_CMN_PHY_ACCESS;
- - phy_ctl_addr = BCMA_GMAC_CMN_PHY_CTL;
- - } else {
- - core = bgmac->core;
- - phy_access_addr = BGMAC_PHY_ACCESS;
- - phy_ctl_addr = BGMAC_PHY_CNTL;
- - }
- -
- - tmp = bcma_read32(core, phy_ctl_addr);
- - tmp &= ~BGMAC_PC_EPA_MASK;
- - tmp |= phyaddr;
- - bcma_write32(core, phy_ctl_addr, tmp);
- -
- - bgmac_write(bgmac, BGMAC_INT_STATUS, BGMAC_IS_MDIO);
- - if (bgmac_read(bgmac, BGMAC_INT_STATUS) & BGMAC_IS_MDIO)
- - dev_warn(bgmac->dev, "Error setting MDIO int\n");
- -
- - tmp = BGMAC_PA_START;
- - tmp |= BGMAC_PA_WRITE;
- - tmp |= phyaddr << BGMAC_PA_ADDR_SHIFT;
- - tmp |= reg << BGMAC_PA_REG_SHIFT;
- - tmp |= value;
- - bcma_write32(core, phy_access_addr, tmp);
- -
- - if (!bgmac_wait_value(core, phy_access_addr, BGMAC_PA_START, 0, 1000)) {
- - dev_err(bgmac->dev, "Writing to PHY %d register 0x%X failed\n",
- - phyaddr, reg);
- - return -ETIMEDOUT;
- - }
- -
- - return 0;
- -}
- -
- -/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphyinit */
- -static void bgmac_phy_init(struct bgmac *bgmac)
- -{
- - struct bcma_chipinfo *ci = &bgmac->core->bus->chipinfo;
- - struct bcma_drv_cc *cc = &bgmac->core->bus->drv_cc;
- - u8 i;
- -
- - if (ci->id == BCMA_CHIP_ID_BCM5356) {
- - for (i = 0; i < 5; i++) {
- - bgmac_phy_write(bgmac, i, 0x1f, 0x008b);
- - bgmac_phy_write(bgmac, i, 0x15, 0x0100);
- - bgmac_phy_write(bgmac, i, 0x1f, 0x000f);
- - bgmac_phy_write(bgmac, i, 0x12, 0x2aaa);
- - bgmac_phy_write(bgmac, i, 0x1f, 0x000b);
- - }
- - }
- - if ((ci->id == BCMA_CHIP_ID_BCM5357 && ci->pkg != 10) ||
- - (ci->id == BCMA_CHIP_ID_BCM4749 && ci->pkg != 10) ||
- - (ci->id == BCMA_CHIP_ID_BCM53572 && ci->pkg != 9)) {
- - bcma_chipco_chipctl_maskset(cc, 2, ~0xc0000000, 0);
- - bcma_chipco_chipctl_maskset(cc, 4, ~0x80000000, 0);
- - for (i = 0; i < 5; i++) {
- - bgmac_phy_write(bgmac, i, 0x1f, 0x000f);
- - bgmac_phy_write(bgmac, i, 0x16, 0x5284);
- - bgmac_phy_write(bgmac, i, 0x1f, 0x000b);
- - bgmac_phy_write(bgmac, i, 0x17, 0x0010);
- - bgmac_phy_write(bgmac, i, 0x1f, 0x000f);
- - bgmac_phy_write(bgmac, i, 0x16, 0x5296);
- - bgmac_phy_write(bgmac, i, 0x17, 0x1073);
- - bgmac_phy_write(bgmac, i, 0x17, 0x9073);
- - bgmac_phy_write(bgmac, i, 0x16, 0x52b6);
- - bgmac_phy_write(bgmac, i, 0x17, 0x9273);
- - bgmac_phy_write(bgmac, i, 0x1f, 0x000b);
- - }
- - }
- -}
- -
- -/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphyreset */
- -static void bgmac_phy_reset(struct bgmac *bgmac)
- -{
- - if (bgmac->phyaddr == BGMAC_PHY_NOREGS)
- - return;
- -
- - bgmac_phy_write(bgmac, bgmac->phyaddr, MII_BMCR, BMCR_RESET);
- - udelay(100);
- - if (bgmac_phy_read(bgmac, bgmac->phyaddr, MII_BMCR) & BMCR_RESET)
- - dev_err(bgmac->dev, "PHY reset failed\n");
- - bgmac_phy_init(bgmac);
- -}
-
- /**************************************************
- * Chip ops
- @@ -1160,7 +1016,8 @@ static void bgmac_chip_reset(struct bgma
- else
- bgmac_set(bgmac, BGMAC_PHY_CNTL, BGMAC_PC_MTE);
- bgmac_miiconfig(bgmac);
- - bgmac_phy_init(bgmac);
- + if (bgmac->mii_bus)
- + bgmac->mii_bus->reset(bgmac->mii_bus);
-
- netdev_reset_queue(bgmac->net_dev);
- }
- @@ -1554,17 +1411,6 @@ static const struct ethtool_ops bgmac_et
- * MII
- **************************************************/
-
- -static int bgmac_mii_read(struct mii_bus *bus, int mii_id, int regnum)
- -{
- - return bgmac_phy_read(bus->priv, mii_id, regnum);
- -}
- -
- -static int bgmac_mii_write(struct mii_bus *bus, int mii_id, int regnum,
- - u16 value)
- -{
- - return bgmac_phy_write(bus->priv, mii_id, regnum, value);
- -}
- -
- static void bgmac_adjust_link(struct net_device *net_dev)
- {
- struct bgmac *bgmac = netdev_priv(net_dev);
- @@ -1589,7 +1435,7 @@ static void bgmac_adjust_link(struct net
- }
- }
-
- -static int bgmac_fixed_phy_register(struct bgmac *bgmac)
- +static int bgmac_phy_connect_direct(struct bgmac *bgmac)
- {
- struct fixed_phy_status fphy_status = {
- .link = 1,
- @@ -1615,81 +1461,24 @@ static int bgmac_fixed_phy_register(stru
- return err;
- }
-
- -static int bgmac_mii_register(struct bgmac *bgmac)
- +static int bgmac_phy_connect(struct bgmac *bgmac)
- {
- - struct mii_bus *mii_bus;
- struct phy_device *phy_dev;
- char bus_id[MII_BUS_ID_SIZE + 3];
- - int i, err = 0;
- -
- - if (bgmac_is_bcm4707_family(bgmac))
- - return bgmac_fixed_phy_register(bgmac);
- -
- - mii_bus = mdiobus_alloc();
- - if (!mii_bus)
- - return -ENOMEM;
- -
- - mii_bus->name = "bgmac mii bus";
- - sprintf(mii_bus->id, "%s-%d-%d", "bgmac", bgmac->core->bus->num,
- - bgmac->core->core_unit);
- - mii_bus->priv = bgmac;
- - mii_bus->read = bgmac_mii_read;
- - mii_bus->write = bgmac_mii_write;
- - mii_bus->parent = &bgmac->core->dev;
- - mii_bus->phy_mask = ~(1 << bgmac->phyaddr);
- -
- - mii_bus->irq = kmalloc_array(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL);
- - if (!mii_bus->irq) {
- - err = -ENOMEM;
- - goto err_free_bus;
- - }
- - for (i = 0; i < PHY_MAX_ADDR; i++)
- - mii_bus->irq[i] = PHY_POLL;
- -
- - err = mdiobus_register(mii_bus);
- - if (err) {
- - dev_err(bgmac->dev, "Registration of mii bus failed\n");
- - goto err_free_irq;
- - }
- -
- - bgmac->mii_bus = mii_bus;
-
- /* Connect to the PHY */
- - snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, mii_bus->id,
- + snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, bgmac->mii_bus->id,
- bgmac->phyaddr);
- phy_dev = phy_connect(bgmac->net_dev, bus_id, &bgmac_adjust_link,
- PHY_INTERFACE_MODE_MII);
- if (IS_ERR(phy_dev)) {
- dev_err(bgmac->dev, "PHY connecton failed\n");
- - err = PTR_ERR(phy_dev);
- - goto err_unregister_bus;
- + return PTR_ERR(phy_dev);
- }
-
- - return err;
- -
- -err_unregister_bus:
- - mdiobus_unregister(mii_bus);
- -err_free_irq:
- - kfree(mii_bus->irq);
- -err_free_bus:
- - mdiobus_free(mii_bus);
- - return err;
- -}
- -
- -static void bgmac_mii_unregister(struct bgmac *bgmac)
- -{
- - struct mii_bus *mii_bus = bgmac->mii_bus;
- -
- - mdiobus_unregister(mii_bus);
- - kfree(mii_bus->irq);
- - mdiobus_free(mii_bus);
- + return 0;
- }
-
- -/**************************************************
- - * BCMA bus ops
- - **************************************************/
- -
- -/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipattach */
- static int bgmac_probe(struct bcma_device *core)
- {
- struct net_device *net_dev;
- @@ -1810,9 +1599,6 @@ static int bgmac_probe(struct bcma_devic
- if (bcm47xx_nvram_getenv("et0_no_txint", NULL, 0) == 0)
- bgmac->int_mask &= ~BGMAC_IS_TX_MASK;
-
- - /* TODO: reset the external phy. Specs are needed */
- - bgmac_phy_reset(bgmac);
- -
- bgmac->has_robosw = !!(core->bus->sprom.boardflags_lo &
- BGMAC_BFL_ENETROBO);
- if (bgmac->has_robosw)
- @@ -1823,10 +1609,25 @@ static int bgmac_probe(struct bcma_devic
-
- netif_napi_add(net_dev, &bgmac->napi, bgmac_poll, BGMAC_WEIGHT);
-
- - err = bgmac_mii_register(bgmac);
- + 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_dma_free;
- + goto err_mii_unregister;
- }
-
- net_dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
- @@ -1836,18 +1637,19 @@ static int bgmac_probe(struct bcma_devic
- err = register_netdev(bgmac->net_dev);
- if (err) {
- dev_err(bgmac->dev, "Cannot register net device\n");
- - goto err_mii_unregister;
- + goto err_phy_disconnect;
- }
-
- netif_carrier_off(net_dev);
-
- return 0;
-
- +err_phy_disconnect:
- + phy_disconnect(net_dev->phydev);
- err_mii_unregister:
- - bgmac_mii_unregister(bgmac);
- + 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);
- @@ -1860,7 +1662,8 @@ static void bgmac_remove(struct bcma_dev
- struct bgmac *bgmac = bcma_get_drvdata(core);
-
- unregister_netdev(bgmac->net_dev);
- - bgmac_mii_unregister(bgmac);
- + 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);
- --- a/drivers/net/ethernet/broadcom/bgmac.h
- +++ b/drivers/net/ethernet/broadcom/bgmac.h
- @@ -456,6 +456,9 @@ struct bgmac {
- bool loopback;
- };
-
- +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);
|