X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fcpsw.c;h=39240d9662143e2c33a1e90f6309e9ab83e61666;hb=55aea84b1db277bd86edadb37d11b78d36db7608;hp=af3d8593eb6933e42207717913f6b27fc31ec8d8;hpb=7cdcaef0b286fa20926d750304442ad770a1fca8;p=oweals%2Fu-boot.git diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c index af3d8593eb..39240d9662 100644 --- a/drivers/net/cpsw.c +++ b/drivers/net/cpsw.c @@ -24,6 +24,7 @@ #include #include #include +#include #define BITMASK(bits) (BIT(bits) - 1) #define PHY_REG_MASK 0x1f @@ -50,8 +51,6 @@ #define CPDMA_RXCP_VER1 0x160 #define CPDMA_RXCP_VER2 0x260 -#define CPDMA_RAM_ADDR 0x4a102000 - /* Descriptor mode bits */ #define CPDMA_DESC_SOP BIT(31) #define CPDMA_DESC_EOP BIT(30) @@ -108,7 +107,13 @@ struct cpsw_slave_regs { u32 flow_thresh; u32 port_vlan; u32 tx_pri_map; +#ifdef CONFIG_AM33XX u32 gap_thresh; +#elif defined(CONFIG_TI814X) + u32 ts_ctl; + u32 ts_seq_ltype; + u32 ts_vlan; +#endif u32 sa_lo; u32 sa_hi; }; @@ -227,6 +232,9 @@ struct cpsw_priv { struct cpsw_slave *slaves; struct phy_device *phydev; struct mii_dev *bus; + + u32 mdio_link; + u32 phy_mask; }; static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits) @@ -479,7 +487,7 @@ static inline void wait_for_idle(void) static int cpsw_mdio_read(struct mii_dev *bus, int phy_id, int dev_addr, int phy_reg) { - unsigned short data; + int data; u32 reg; if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK) @@ -560,9 +568,14 @@ static void cpsw_set_slave_mac(struct cpsw_slave *slave, static void cpsw_slave_update_link(struct cpsw_slave *slave, struct cpsw_priv *priv, int *link) { - struct phy_device *phy = priv->phydev; + struct phy_device *phy; u32 mac_control = 0; + phy = priv->phydev; + + if (!phy) + return; + phy_startup(phy); *link = phy->link; @@ -598,10 +611,21 @@ static int cpsw_update_link(struct cpsw_priv *priv) for_each_slave(slave, priv) cpsw_slave_update_link(slave, priv, &link); - + priv->mdio_link = readl(&mdio_regs->link); return link; } +static int cpsw_check_link(struct cpsw_priv *priv) +{ + u32 link = 0; + + link = __raw_readl(&mdio_regs->link) & priv->phy_mask; + if ((link) && (link == priv->mdio_link)) + return 1; + + return cpsw_update_link(priv); +} + static inline u32 cpsw_get_slave_port(struct cpsw_priv *priv, u32 slave_num) { if (priv->host_port == 0) @@ -631,6 +655,8 @@ static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv) cpsw_ale_port_state(priv, slave_port, ALE_PORT_STATE_FORWARD); cpsw_ale_add_mcast(priv, NetBcastAddr, 1 << slave_port); + + priv->phy_mask |= 1 << slave->data->phy_id; } static struct cpdma_desc *cpdma_desc_alloc(struct cpsw_priv *priv) @@ -751,6 +777,7 @@ static int cpsw_init(struct eth_device *dev, bd_t *bis) /* enable statistics collection only on the host port */ __raw_writel(BIT(priv->host_port), &priv->regs->stat_port_en); + __raw_writel(0x7, &priv->regs->stat_port_en); cpsw_ale_port_state(priv, priv->host_port, ALE_PORT_STATE_FORWARD); @@ -862,7 +889,7 @@ static int cpsw_send(struct eth_device *dev, void *packet, int length) int len; int timeout = CPDMA_TIMEOUT; - if (!cpsw_update_link(priv)) + if (!cpsw_check_link(priv)) return -EIO; flush_dcache_range((unsigned long)packet, @@ -920,7 +947,13 @@ static int cpsw_phy_init(struct eth_device *dev, struct cpsw_slave *slave) SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full); - phydev = phy_connect(priv->bus, 0, dev, slave->data->phy_if); + phydev = phy_connect(priv->bus, + CONFIG_PHY_ADDR, + dev, + slave->data->phy_if); + + if (!phydev) + return -1; phydev->supported &= supported; phydev->advertising = phydev->supported; @@ -958,12 +991,12 @@ int cpsw_register(struct cpsw_platform_data *data) return -ENOMEM; } - priv->descs = (void *)CPDMA_RAM_ADDR; priv->host_port = data->host_port_num; priv->regs = regs; priv->host_port_regs = regs + data->host_port_reg_ofs; priv->dma_regs = regs + data->cpdma_reg_ofs; priv->ale_regs = regs + data->ale_reg_ofs; + priv->descs = (void *)regs + data->bd_ram_ofs; int idx = 0;