X-Git-Url: http://git.openwrt.org/?p=openwrt%2Fopenwrt.git;a=blobdiff_plain;f=target%2Flinux%2Fath79%2Ffiles%2Fdrivers%2Fnet%2Fethernet%2Fatheros%2Fag71xx%2Fag71xx_main.c;h=70ca0248c35f8d8998f32d7fb6d3fc04241491f5;hp=e741bdfa7b60f523613dd82643ee4841379df071;hb=7bd2595b6761a52cb69b58b9be1a84d25cbe66e3;hpb=83d2dbc59924c90dd865de113a55d60826ac0c04 diff --git a/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c b/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c index e741bdfa7b..70ca0248c3 100644 --- a/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c +++ b/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "ag71xx.h" #define AG71XX_DEFAULT_MSG_ENABLE \ @@ -55,6 +56,32 @@ static void ag71xx_dump_dma_regs(struct ag71xx *ag) ag71xx_rr(ag, AG71XX_REG_RX_STATUS)); } +static void ag71xx_dump_regs(struct ag71xx *ag) +{ + DBG("%s: mac_cfg1=%08x, mac_cfg2=%08x, ipg=%08x, hdx=%08x, mfl=%08x\n", + ag->dev->name, + ag71xx_rr(ag, AG71XX_REG_MAC_CFG1), + ag71xx_rr(ag, AG71XX_REG_MAC_CFG2), + ag71xx_rr(ag, AG71XX_REG_MAC_IPG), + ag71xx_rr(ag, AG71XX_REG_MAC_HDX), + ag71xx_rr(ag, AG71XX_REG_MAC_MFL)); + DBG("%s: mac_ifctl=%08x, mac_addr1=%08x, mac_addr2=%08x\n", + ag->dev->name, + ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL), + ag71xx_rr(ag, AG71XX_REG_MAC_ADDR1), + ag71xx_rr(ag, AG71XX_REG_MAC_ADDR2)); + DBG("%s: fifo_cfg0=%08x, fifo_cfg1=%08x, fifo_cfg2=%08x\n", + ag->dev->name, + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG0), + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG1), + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG2)); + DBG("%s: fifo_cfg3=%08x, fifo_cfg4=%08x, fifo_cfg5=%08x\n", + ag->dev->name, + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG3), + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG4), + ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5)); +} + static inline void ag71xx_dump_intr(struct ag71xx *ag, char *label, u32 intr) { DBG("%s: %s intr=%08x %s%s%s%s%s%s\n", @@ -422,13 +449,6 @@ static void ag71xx_hw_init(struct ag71xx *ag) { ag71xx_hw_stop(ag); - if (ag->phy_reset) { - reset_control_assert(ag->phy_reset); - msleep(50); - reset_control_deassert(ag->phy_reset); - msleep(200); - } - ag71xx_sb(ag, AG71XX_REG_MAC_CFG1, MAC_CFG1_SR); udelay(20); @@ -535,6 +555,60 @@ static void ath79_set_pll(struct ag71xx *ag) udelay(100); } +static void ath79_mii_ctrl_set_if(struct ag71xx *ag, unsigned int mii_if) +{ + u32 t; + + t = __raw_readl(ag->mii_base); + t &= ~(AR71XX_MII_CTRL_IF_MASK); + t |= (mii_if & AR71XX_MII_CTRL_IF_MASK); + __raw_writel(t, ag->mii_base); +} + +static void ath79_mii0_ctrl_set_if(struct ag71xx *ag) +{ + unsigned int mii_if; + + switch (ag->phy_if_mode) { + case PHY_INTERFACE_MODE_MII: + mii_if = AR71XX_MII0_CTRL_IF_MII; + break; + case PHY_INTERFACE_MODE_GMII: + mii_if = AR71XX_MII0_CTRL_IF_GMII; + break; + case PHY_INTERFACE_MODE_RGMII: + mii_if = AR71XX_MII0_CTRL_IF_RGMII; + break; + case PHY_INTERFACE_MODE_RMII: + mii_if = AR71XX_MII0_CTRL_IF_RMII; + break; + default: + WARN(1, "Impossible PHY mode defined.\n"); + return; + } + + ath79_mii_ctrl_set_if(ag, mii_if); +} + +static void ath79_mii1_ctrl_set_if(struct ag71xx *ag) +{ + unsigned int mii_if; + + switch (ag->phy_if_mode) { + case PHY_INTERFACE_MODE_RMII: + mii_if = AR71XX_MII1_CTRL_IF_RMII; + break; + case PHY_INTERFACE_MODE_RGMII: + mii_if = AR71XX_MII1_CTRL_IF_RGMII; + break; + default: + WARN(1, "Impossible PHY mode defined.\n"); + return; + } + + ath79_mii_ctrl_set_if(ag, mii_if); +} + static void ath79_mii_ctrl_set_speed(struct ag71xx *ag) { unsigned int mii_speed; @@ -558,8 +632,8 @@ static void ath79_mii_ctrl_set_speed(struct ag71xx *ag) } t = __raw_readl(ag->mii_base); - t &= ~(AR71XX_MII_CTRL_IF_MASK); - t |= (mii_speed & AR71XX_MII_CTRL_IF_MASK); + t &= ~(AR71XX_MII_CTRL_SPEED_MASK << AR71XX_MII_CTRL_SPEED_SHIFT); + t |= mii_speed << AR71XX_MII_CTRL_SPEED_SHIFT; __raw_writel(t, ag->mii_base); } @@ -659,22 +733,7 @@ __ag71xx_link_adjust(struct ag71xx *ag, bool update) ag71xx_speed_str(ag), (DUPLEX_FULL == ag->duplex) ? "Full" : "Half"); - DBG("%s: fifo_cfg0=%#x, fifo_cfg1=%#x, fifo_cfg2=%#x\n", - ag->dev->name, - ag71xx_rr(ag, AG71XX_REG_FIFO_CFG0), - ag71xx_rr(ag, AG71XX_REG_FIFO_CFG1), - ag71xx_rr(ag, AG71XX_REG_FIFO_CFG2)); - - DBG("%s: fifo_cfg3=%#x, fifo_cfg4=%#x, fifo_cfg5=%#x\n", - ag->dev->name, - ag71xx_rr(ag, AG71XX_REG_FIFO_CFG3), - ag71xx_rr(ag, AG71XX_REG_FIFO_CFG4), - ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5)); - - DBG("%s: mac_cfg2=%#x, mac_ifctl=%#x\n", - ag->dev->name, - ag71xx_rr(ag, AG71XX_REG_MAC_CFG2), - ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL)); + ag71xx_dump_regs(ag); } void ag71xx_link_adjust(struct ag71xx *ag) @@ -1273,6 +1332,7 @@ static const char *ag71xx_get_phy_if_mode_name(phy_interface_t mode) static int ag71xx_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; + struct device_node *mdio_node; struct net_device *dev; struct resource *res; struct ag71xx *ag; @@ -1311,8 +1371,6 @@ static int ag71xx_probe(struct platform_device *pdev) goto err_free; } - ag->phy_reset = devm_reset_control_get_optional(&pdev->dev, "phy"); - if (of_property_read_u32_array(np, "fifo-data", ag->fifodata, 3)) { if (of_device_is_compatible(np, "qca,ar9130-eth") || of_device_is_compatible(np, "qca,ar7100-eth")) { @@ -1434,11 +1492,36 @@ static int ag71xx_probe(struct platform_device *pdev) goto err_free; } + if (of_property_read_u32(np, "qca,mac-idx", &ag->mac_idx)) + ag->mac_idx = -1; + if (ag->mii_base) + switch (ag->mac_idx) { + case 0: + ath79_mii0_ctrl_set_if(ag); + break; + case 1: + ath79_mii1_ctrl_set_if(ag); + break; + default: + break; + } + netif_napi_add(dev, &ag->napi, ag71xx_poll, AG71XX_NAPI_WEIGHT); + ag71xx_dump_regs(ag); + ag71xx_wr(ag, AG71XX_REG_MAC_CFG1, 0); + ag71xx_hw_init(ag); + ag71xx_dump_regs(ag); + + if (!of_device_is_compatible(np, "simple-mfd")) { + mdio_node = of_get_child_by_name(np, "mdio-bus"); + if (!IS_ERR(mdio_node)) + of_platform_device_create(mdio_node, NULL, NULL); + } + err = ag71xx_phy_connect(ag); if (err) goto err_free;