From: Hauke Mehrtens Date: Sun, 28 Jul 2013 21:20:15 +0000 (+0000) Subject: bcm53xx: add initial bgmac patches X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=3e8c39f23928beba50fa1f7e7f0b171a790810ae;p=openwrt%2Fstaging%2Fdedeckeh.git bcm53xx: add initial bgmac patches Signed-off-by: Hauke Mehrtens SVN-Revision: 37584 --- diff --git a/target/linux/bcm53xx/patches-3.10/201-bgmac-add-dependency-to-phylib.patch b/target/linux/bcm53xx/patches-3.10/201-bgmac-add-dependency-to-phylib.patch new file mode 100644 index 0000000000..e4172ae59b --- /dev/null +++ b/target/linux/bcm53xx/patches-3.10/201-bgmac-add-dependency-to-phylib.patch @@ -0,0 +1,22 @@ +From d29611892717def1628f2677f7b0bd6eb2c58565 Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens +Date: Wed, 10 Jul 2013 17:54:33 +0200 +Subject: [PATCH 16/18] bgmac: add dependency to phylib + +bgmac is using functions from phylib, add the dependency. + +Signed-off-by: Hauke Mehrtens +--- + drivers/net/ethernet/broadcom/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/ethernet/broadcom/Kconfig ++++ b/drivers/net/ethernet/broadcom/Kconfig +@@ -133,6 +133,7 @@ config BNX2X_SRIOV + config BGMAC + tristate "BCMA bus GBit core support" + depends on BCMA_HOST_SOC && HAS_DMA ++ select PHYLIB + ---help--- + This driver supports GBit MAC and BCM4706 GBit MAC cores on BCMA bus. + They can be found on BCM47xx SoCs and provide gigabit ethernet. diff --git a/target/linux/bcm53xx/patches-3.10/202-bgmac-make-bgmac-work-on-systems-without-nvram.patch b/target/linux/bcm53xx/patches-3.10/202-bgmac-make-bgmac-work-on-systems-without-nvram.patch new file mode 100644 index 0000000000..4ebb942ec0 --- /dev/null +++ b/target/linux/bcm53xx/patches-3.10/202-bgmac-make-bgmac-work-on-systems-without-nvram.patch @@ -0,0 +1,24 @@ +From e484cca2387df0878d55d8f3e8e4543aa668dd52 Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens +Date: Wed, 10 Jul 2013 17:55:34 +0200 +Subject: [PATCH 17/18] bgmac: make bgmac work on systems without nvram + +Signed-off-by: Hauke Mehrtens +--- + drivers/net/ethernet/broadcom/bgmac.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/net/ethernet/broadcom/bgmac.c ++++ b/drivers/net/ethernet/broadcom/bgmac.c +@@ -16,7 +16,11 @@ + #include + #include + #include ++#ifdef CONFIG_BCM47XX + #include ++#else ++#define bcm47xx_nvram_getenv(a, b, c) -1 ++#endif + + 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), diff --git a/target/linux/bcm53xx/patches-3.10/203-bgmac-register-phy.patch b/target/linux/bcm53xx/patches-3.10/203-bgmac-register-phy.patch new file mode 100644 index 0000000000..1bc267145e --- /dev/null +++ b/target/linux/bcm53xx/patches-3.10/203-bgmac-register-phy.patch @@ -0,0 +1,209 @@ +From a145c561b9ba9ef402fbc3aa295b31521aa8591d Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens +Date: Sun, 14 Jul 2013 00:04:21 +0200 +Subject: [PATCH 18/18] bgmac: register phy + +Signed-off-by: Hauke Mehrtens +--- + drivers/net/ethernet/broadcom/bgmac.c | 137 ++++++++++++++++----------------- + drivers/net/ethernet/broadcom/bgmac.h | 3 + + 2 files changed, 71 insertions(+), 69 deletions(-) + +--- a/drivers/net/ethernet/broadcom/bgmac.c ++++ b/drivers/net/ethernet/broadcom/bgmac.c +@@ -1205,27 +1205,14 @@ static int bgmac_set_mac_address(struct + static int bgmac_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd) + { + struct bgmac *bgmac = netdev_priv(net_dev); +- struct mii_ioctl_data *data = if_mii(ifr); + +- switch (cmd) { +- case SIOCGMIIPHY: +- data->phy_id = bgmac->phyaddr; +- /* fallthru */ +- case SIOCGMIIREG: +- if (!netif_running(net_dev)) +- return -EAGAIN; +- data->val_out = bgmac_phy_read(bgmac, data->phy_id, +- data->reg_num & 0x1f); +- return 0; +- case SIOCSMIIREG: +- if (!netif_running(net_dev)) +- return -EAGAIN; +- bgmac_phy_write(bgmac, data->phy_id, data->reg_num & 0x1f, +- data->val_in); +- return 0; +- default: +- return -EOPNOTSUPP; +- } ++ if (!netif_running(net_dev)) ++ return -EINVAL; ++ ++ if (!bgmac->phydev) ++ return -EINVAL; ++ ++ return phy_mii_ioctl(bgmac->phydev, ifr, cmd); + } + + static const struct net_device_ops bgmac_netdev_ops = { +@@ -1247,61 +1234,18 @@ static int bgmac_get_settings(struct net + { + struct bgmac *bgmac = netdev_priv(net_dev); + +- cmd->supported = SUPPORTED_10baseT_Half | +- SUPPORTED_10baseT_Full | +- SUPPORTED_100baseT_Half | +- SUPPORTED_100baseT_Full | +- SUPPORTED_1000baseT_Half | +- SUPPORTED_1000baseT_Full | +- SUPPORTED_Autoneg; +- +- if (bgmac->autoneg) { +- WARN_ON(cmd->advertising); +- if (bgmac->full_duplex) { +- if (bgmac->speed & BGMAC_SPEED_10) +- cmd->advertising |= ADVERTISED_10baseT_Full; +- if (bgmac->speed & BGMAC_SPEED_100) +- cmd->advertising |= ADVERTISED_100baseT_Full; +- if (bgmac->speed & BGMAC_SPEED_1000) +- cmd->advertising |= ADVERTISED_1000baseT_Full; +- } else { +- if (bgmac->speed & BGMAC_SPEED_10) +- cmd->advertising |= ADVERTISED_10baseT_Half; +- if (bgmac->speed & BGMAC_SPEED_100) +- cmd->advertising |= ADVERTISED_100baseT_Half; +- if (bgmac->speed & BGMAC_SPEED_1000) +- cmd->advertising |= ADVERTISED_1000baseT_Half; +- } +- } else { +- switch (bgmac->speed) { +- case BGMAC_SPEED_10: +- ethtool_cmd_speed_set(cmd, SPEED_10); +- break; +- case BGMAC_SPEED_100: +- ethtool_cmd_speed_set(cmd, SPEED_100); +- break; +- case BGMAC_SPEED_1000: +- ethtool_cmd_speed_set(cmd, SPEED_1000); +- break; +- } +- } +- +- cmd->duplex = bgmac->full_duplex ? DUPLEX_FULL : DUPLEX_HALF; +- +- cmd->autoneg = bgmac->autoneg; +- +- return 0; ++ return phy_ethtool_gset(bgmac->phydev, cmd); + } + +-#if 0 ++ + static int bgmac_set_settings(struct net_device *net_dev, + struct ethtool_cmd *cmd) + { + struct bgmac *bgmac = netdev_priv(net_dev); + +- return -1; ++ return phy_ethtool_sset(bgmac->phydev, cmd); + } +-#endif ++ + + static void bgmac_get_drvinfo(struct net_device *net_dev, + struct ethtool_drvinfo *info) +@@ -1312,6 +1256,7 @@ static void bgmac_get_drvinfo(struct net + + static const struct ethtool_ops bgmac_ethtool_ops = { + .get_settings = bgmac_get_settings, ++ .set_settings = bgmac_set_settings, + .get_drvinfo = bgmac_get_drvinfo, + }; + +@@ -1330,10 +1275,42 @@ static int bgmac_mii_write(struct mii_bu + return bgmac_phy_write(bus->priv, mii_id, regnum, value); + } + ++static void bgmac_adjust_link(struct net_device *dev) ++{ ++ struct bgmac *bgmac = netdev_priv(dev); ++ struct phy_device *phydev = bgmac->phydev; ++ int status_changed = 0; ++ ++ BUG_ON(!phydev); ++ ++ if (bgmac->old_link != phydev->link) { ++ status_changed = 1; ++ bgmac->old_link = phydev->link; ++ } ++ ++ /* reflect duplex change */ ++ if (phydev->link && (bgmac->old_duplex != phydev->duplex)) { ++ status_changed = 1; ++ bgmac->old_duplex = phydev->duplex; ++ } ++ ++ if (status_changed) { ++ pr_info("%s: link %s", dev->name, phydev->link ? ++ "UP" : "DOWN"); ++ if (phydev->link) ++ pr_cont(" - %d/%s", phydev->speed, ++ phydev->duplex == DUPLEX_FULL ? "full" : "half"); ++ pr_cont("\n"); ++ } ++} ++ + static int bgmac_mii_register(struct bgmac *bgmac) + { + struct mii_bus *mii_bus; + int i, err = 0; ++ struct phy_device *phydev = NULL; ++ char phy_id[MII_BUS_ID_SIZE + 3]; ++ struct net_device *net_dev = bgmac->net_dev; + + mii_bus = mdiobus_alloc(); + if (!mii_bus) +@@ -1364,7 +1341,29 @@ static int bgmac_mii_register(struct bgm + + bgmac->mii_bus = mii_bus; + +- return err; ++ /* connect to PHY */ ++ snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, ++ mii_bus->id, bgmac->phyaddr); ++ ++ phydev = phy_connect(net_dev, phy_id, &bgmac_adjust_link, ++ PHY_INTERFACE_MODE_MII); ++ ++ if (IS_ERR(phydev)) { ++ netdev_err(net_dev, "could not attach PHY: %s", phy_id); ++ bgmac->phyaddr = BGMAC_PHY_NOREGS; ++ return PTR_ERR(phydev); ++ } ++ ++ bgmac->phydev = phydev; ++ bgmac->old_link = 0; ++ bgmac->old_duplex = -1; ++ bgmac->phyaddr = phydev->addr; ++ ++ netdev_info(net_dev, "attached PHY driver [%s] " ++ "(mii_bus:phy_addr=%s)\n", ++ phydev->drv->name, dev_name(&phydev->dev)); ++ ++ return 0; + + err_free_irq: + kfree(mii_bus->irq); +--- a/drivers/net/ethernet/broadcom/bgmac.h ++++ b/drivers/net/ethernet/broadcom/bgmac.h +@@ -399,7 +399,10 @@ struct bgmac { + struct bcma_device *cmn; /* Reference to CMN core for BCM4706 */ + struct net_device *net_dev; + struct napi_struct napi; ++ struct phy_device *phydev; + struct mii_bus *mii_bus; ++ int old_link; ++ int old_duplex; + + /* DMA */ + struct bgmac_dma_ring tx_ring[BGMAC_MAX_TX_RINGS]; diff --git a/target/linux/bcm53xx/patches-3.10/204-bgmac-add-supprot-for-BCM4707.patch b/target/linux/bcm53xx/patches-3.10/204-bgmac-add-supprot-for-BCM4707.patch new file mode 100644 index 0000000000..7bbfa3f552 --- /dev/null +++ b/target/linux/bcm53xx/patches-3.10/204-bgmac-add-supprot-for-BCM4707.patch @@ -0,0 +1,125 @@ +From 91c50931fd696fa8d2f9888482f89a6a0683fe6f Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens +Date: Mon, 15 Jul 2013 22:22:25 +0200 +Subject: [PATCH 19/20] bgmac: add supprot for BCM4707 + + +Signed-off-by: Hauke Mehrtens +--- + drivers/net/ethernet/broadcom/bgmac.c | 56 +++++++++++++++++++++++---------- + drivers/net/ethernet/broadcom/bgmac.h | 2 ++ + 2 files changed, 42 insertions(+), 16 deletions(-) + +--- a/drivers/net/ethernet/broadcom/bgmac.c ++++ b/drivers/net/ethernet/broadcom/bgmac.c +@@ -842,6 +842,8 @@ static void bgmac_speed(struct bgmac *bg + set |= BGMAC_CMDCFG_ES_100; + if (speed & BGMAC_SPEED_1000) + set |= BGMAC_CMDCFG_ES_1000; ++ if (speed & BGMAC_SPEED_2500) ++ set |= BGMAC_CMDCFG_ES_2500; + if (!bgmac->full_duplex) + set |= BGMAC_CMDCFG_HD; + bgmac_cmdcfg_maskset(bgmac, mask, set, true); +@@ -849,13 +851,28 @@ static void bgmac_speed(struct bgmac *bg + + static void bgmac_miiconfig(struct bgmac *bgmac) + { +- u8 imode = (bgmac_read(bgmac, BGMAC_DEV_STATUS) & BGMAC_DS_MM_MASK) >> +- BGMAC_DS_MM_SHIFT; +- if (imode == 0 || imode == 1) { +- if (bgmac->autoneg) +- bgmac_speed(bgmac, BGMAC_SPEED_100); +- else ++ struct bcma_device *core = bgmac->core; ++ struct bcma_chipinfo *ci = &core->bus->chipinfo; ++ ++ if (ci->id != BCMA_CHIP_ID_BCM4707 && ++ ci->id != BCMA_CHIP_ID_BCM53018) { ++ if (bgmac->autoneg) { ++ bcma_awrite32(core, BCMA_IOCTL, ++ bcma_aread32(core, BCMA_IOCTL) | 0x44); ++ ++ bgmac_speed(bgmac, BGMAC_SPEED_2500); ++ } else { + bgmac_speed(bgmac, bgmac->speed); ++ } ++ } else { ++ u8 imode = (bgmac_read(bgmac, BGMAC_DEV_STATUS) & ++ BGMAC_DS_MM_MASK) >> BGMAC_DS_MM_SHIFT; ++ if (imode == 0 || imode == 1) { ++ if (bgmac->autoneg) ++ bgmac_speed(bgmac, BGMAC_SPEED_100); ++ else ++ bgmac_speed(bgmac, bgmac->speed); ++ } + } + } + +@@ -901,7 +918,8 @@ static void bgmac_chip_reset(struct bgma + + bcma_core_enable(core, flags); + +- if (core->id.rev > 2) { ++ if (core->id.rev > 2 && ci->id != BCMA_CHIP_ID_BCM4707 && ++ ci->id != BCMA_CHIP_ID_BCM53018) { + bgmac_set(bgmac, BCMA_CLKCTLST, 1 << 8); + bgmac_wait_value(bgmac->core, BCMA_CLKCTLST, 1 << 24, 1 << 24, + 1000); +@@ -922,10 +940,13 @@ static void bgmac_chip_reset(struct bgma + et_swtype &= 0x0f; + et_swtype <<= 4; + sw_type = et_swtype; +- } else if (ci->id == BCMA_CHIP_ID_BCM5357 && ci->pkg == 9) { ++ } else if (ci->id == BCMA_CHIP_ID_BCM5357 && ++ ci->pkg == BCMA_PKG_ID_BCM5358) { + sw_type = BGMAC_CHIPCTL_1_SW_TYPE_EPHYRMII; +- } else if ((ci->id != BCMA_CHIP_ID_BCM53572 && ci->pkg == 10) || +- (ci->id == BCMA_CHIP_ID_BCM53572 && ci->pkg == 9)) { ++ } else if ((ci->id != BCMA_CHIP_ID_BCM53572 && ++ ci->pkg == BCMA_PKG_ID_BCM47186) || ++ (ci->id == BCMA_CHIP_ID_BCM53572 && ++ ci->pkg == BCMA_PKG_ID_BCM47188)) { + sw_type = BGMAC_CHIPCTL_1_IF_TYPE_RGMII | + BGMAC_CHIPCTL_1_SW_TYPE_RGMII; + } +@@ -1030,12 +1051,15 @@ static void bgmac_enable(struct bgmac *b + break; + } + +- 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; +- mdp = (bp_clk * 128 / 1000) - 3; +- rxq_ctl |= (mdp << BGMAC_RXQ_CTL_MDP_SHIFT); +- bgmac_write(bgmac, BGMAC_RXQ_CTL, rxq_ctl); ++ if (ci->id != BCMA_CHIP_ID_BCM4707 && ++ ci->id != BCMA_CHIP_ID_BCM53018) { ++ 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; ++ mdp = (bp_clk * 128 / 1000) - 3; ++ rxq_ctl |= (mdp << BGMAC_RXQ_CTL_MDP_SHIFT); ++ bgmac_write(bgmac, BGMAC_RXQ_CTL, rxq_ctl); ++ } + } + + /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipinit */ +--- a/drivers/net/ethernet/broadcom/bgmac.h ++++ b/drivers/net/ethernet/broadcom/bgmac.h +@@ -185,6 +185,7 @@ + #define BGMAC_CMDCFG_ES_10 0x00000000 + #define BGMAC_CMDCFG_ES_100 0x00000004 + #define BGMAC_CMDCFG_ES_1000 0x00000008 ++#define BGMAC_CMDCFG_ES_2500 0x0000000C + #define BGMAC_CMDCFG_PROM 0x00000010 /* Set to activate promiscuous mode */ + #define BGMAC_CMDCFG_PAD_EN 0x00000020 + #define BGMAC_CMDCFG_CF 0x00000040 +@@ -345,6 +346,7 @@ + #define BGMAC_SPEED_10 0x0001 + #define BGMAC_SPEED_100 0x0002 + #define BGMAC_SPEED_1000 0x0004 ++#define BGMAC_SPEED_2500 0x0008 + + #define BGMAC_WEIGHT 64 +