X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=drivers%2Fnet%2Fcpsw.c;h=52f8da67e1d9049da108238e8955ae2de3d0fce5;hb=11709e7af121b59b45d3a15bfefba34898274396;hp=db04795dfc97c55db137d5af2a92bd31364ce43b;hpb=91c038f087d7f643c85609897af3710d5f8b42a9;p=u-boot diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c index db04795dfc..52f8da67e1 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; }; @@ -206,6 +211,8 @@ struct cpdma_chan { #define chan_read(chan, fld) __raw_readl((chan)->fld) #define chan_read_ptr(chan, fld) ((void *)__raw_readl((chan)->fld)) +#define for_active_slave(slave, priv) \ + slave = (priv)->slaves + (priv)->data.active_slave; if (slave) #define for_each_slave(slave, priv) \ for (slave = (priv)->slaves; slave != (priv)->slaves + \ (priv)->data.slaves; slave++) @@ -227,6 +234,8 @@ struct cpsw_priv { struct cpsw_slave *slaves; struct phy_device *phydev; struct mii_dev *bus; + + u32 phy_mask; }; static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits) @@ -479,7 +488,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 +569,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; @@ -596,7 +610,7 @@ static int cpsw_update_link(struct cpsw_priv *priv) int link = 0; struct cpsw_slave *slave; - for_each_slave(slave, priv) + for_active_slave(slave, priv) cpsw_slave_update_link(slave, priv, &link); return link; @@ -631,6 +645,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_addr; } static struct cpdma_desc *cpdma_desc_alloc(struct cpsw_priv *priv) @@ -751,6 +767,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); @@ -758,7 +775,7 @@ static int cpsw_init(struct eth_device *dev, bd_t *bis) ALE_SECURE); cpsw_ale_add_mcast(priv, NetBcastAddr, 1 << priv->host_port); - for_each_slave(slave, priv) + for_active_slave(slave, priv) cpsw_slave_init(slave, priv); cpsw_update_link(priv); @@ -862,9 +879,6 @@ static int cpsw_send(struct eth_device *dev, void *packet, int length) int len; int timeout = CPDMA_TIMEOUT; - if (!cpsw_update_link(priv)) - return -EIO; - flush_dcache_range((unsigned long)packet, (unsigned long)packet + length); @@ -887,8 +901,6 @@ static int cpsw_recv(struct eth_device *dev) void *buffer; int len; - cpsw_update_link(priv); - while (cpdma_process(priv, &priv->rx_chan, &buffer, &len) >= 0) { invalidate_dcache_range((unsigned long)buffer, (unsigned long)buffer + PKTSIZE_ALIGN); @@ -914,17 +926,16 @@ static int cpsw_phy_init(struct eth_device *dev, struct cpsw_slave *slave) { struct cpsw_priv *priv = (struct cpsw_priv *)dev->priv; struct phy_device *phydev; - u32 supported = (SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_100baseT_Half | - SUPPORTED_100baseT_Full | - SUPPORTED_1000baseT_Full); + u32 supported = PHY_GBIT_FEATURES; phydev = phy_connect(priv->bus, - CONFIG_PHY_ADDR, + slave->data->phy_addr, dev, slave->data->phy_if); + if (!phydev) + return -1; + phydev->supported &= supported; phydev->advertising = phydev->supported; @@ -961,12 +972,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; @@ -987,7 +998,7 @@ int cpsw_register(struct cpsw_platform_data *data) cpsw_mdio_init(dev->name, data->mdio_base, data->mdio_div); priv->bus = miiphy_get_dev_by_name(dev->name); - for_each_slave(slave, priv) + for_active_slave(slave, priv) cpsw_phy_init(dev, slave); return 1;