kernel: backport bgmac patch moving MDIO code into separated file
This prepares bgmac for the biggest change: dropping bcma dependency. Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
This commit is contained in:
		@@ -0,0 +1,676 @@
 | 
				
			|||||||
 | 
					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
 | 
				
			||||||
 | 
					@@ -756,150 +756,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
 | 
				
			||||||
 | 
					@@ -1156,7 +1012,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);
 | 
				
			||||||
 | 
					 }
 | 
				
			||||||
 | 
					@@ -1550,17 +1407,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);
 | 
				
			||||||
 | 
					@@ -1585,7 +1431,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,
 | 
				
			||||||
 | 
					@@ -1611,81 +1457,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;
 | 
				
			||||||
 | 
					@@ -1806,9 +1595,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)
 | 
				
			||||||
 | 
					@@ -1819,10 +1605,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;
 | 
				
			||||||
 | 
					@@ -1832,18 +1633,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);
 | 
				
			||||||
 | 
					@@ -1856,7 +1658,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);
 | 
				
			||||||
@@ -12,9 +12,9 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
				
			|||||||
 #include <linux/bcm47xx_nvram.h>
 | 
					 #include <linux/bcm47xx_nvram.h>
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 static const struct bcma_device_id bgmac_bcma_tbl[] = {
 | 
					 static const struct bcma_device_id bgmac_bcma_tbl[] = {
 | 
				
			||||||
@@ -1681,6 +1682,17 @@ static void bgmac_mii_unregister(struct
 | 
					@@ -1403,6 +1404,17 @@ static const struct ethtool_ops bgmac_et
 | 
				
			||||||
 	mdiobus_free(mii_bus);
 | 
					 	.get_drvinfo		= bgmac_get_drvinfo,
 | 
				
			||||||
 }
 | 
					 };
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
+static struct b53_platform_data bgmac_b53_pdata = {
 | 
					+static struct b53_platform_data bgmac_b53_pdata = {
 | 
				
			||||||
+};
 | 
					+};
 | 
				
			||||||
@@ -28,9 +28,9 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
				
			|||||||
+};
 | 
					+};
 | 
				
			||||||
+
 | 
					+
 | 
				
			||||||
 /**************************************************
 | 
					 /**************************************************
 | 
				
			||||||
  * BCMA bus ops
 | 
					  * MII
 | 
				
			||||||
  **************************************************/
 | 
					  **************************************************/
 | 
				
			||||||
@@ -1829,6 +1841,14 @@ static int bgmac_probe(struct bcma_devic
 | 
					@@ -1630,6 +1642,14 @@ static int bgmac_probe(struct bcma_devic
 | 
				
			||||||
 	net_dev->hw_features = net_dev->features;
 | 
					 	net_dev->hw_features = net_dev->features;
 | 
				
			||||||
 	net_dev->vlan_features = net_dev->features;
 | 
					 	net_dev->vlan_features = net_dev->features;
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
@@ -45,7 +45,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
				
			|||||||
 	err = register_netdev(bgmac->net_dev);
 | 
					 	err = register_netdev(bgmac->net_dev);
 | 
				
			||||||
 	if (err) {
 | 
					 	if (err) {
 | 
				
			||||||
 		dev_err(bgmac->dev, "Cannot register net device\n");
 | 
					 		dev_err(bgmac->dev, "Cannot register net device\n");
 | 
				
			||||||
@@ -1855,6 +1875,10 @@ static void bgmac_remove(struct bcma_dev
 | 
					@@ -1657,6 +1677,10 @@ static void bgmac_remove(struct bcma_dev
 | 
				
			||||||
 {
 | 
					 {
 | 
				
			||||||
 	struct bgmac *bgmac = bcma_get_drvdata(core);
 | 
					 	struct bgmac *bgmac = bcma_get_drvdata(core);
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
@@ -54,8 +54,8 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
				
			|||||||
+	bgmac->b53_device = NULL;
 | 
					+	bgmac->b53_device = NULL;
 | 
				
			||||||
+
 | 
					+
 | 
				
			||||||
 	unregister_netdev(bgmac->net_dev);
 | 
					 	unregister_netdev(bgmac->net_dev);
 | 
				
			||||||
 	bgmac_mii_unregister(bgmac);
 | 
					 	phy_disconnect(bgmac->net_dev->phydev);
 | 
				
			||||||
 	netif_napi_del(&bgmac->napi);
 | 
					 	bcma_mdio_mii_unregister(bgmac->mii_bus);
 | 
				
			||||||
--- a/drivers/net/ethernet/broadcom/bgmac.h
 | 
					--- a/drivers/net/ethernet/broadcom/bgmac.h
 | 
				
			||||||
+++ b/drivers/net/ethernet/broadcom/bgmac.h
 | 
					+++ b/drivers/net/ethernet/broadcom/bgmac.h
 | 
				
			||||||
@@ -454,6 +454,9 @@ struct bgmac {
 | 
					@@ -454,6 +454,9 @@ struct bgmac {
 | 
				
			||||||
@@ -67,4 +67,4 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | 
				
			|||||||
+	struct platform_device *b53_device;
 | 
					+	struct platform_device *b53_device;
 | 
				
			||||||
 };
 | 
					 };
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 static inline u32 bgmac_read(struct bgmac *bgmac, u16 offset)
 | 
					 struct mii_bus *bcma_mdio_mii_register(struct bcma_device *core, u8 phyaddr);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user