Example #1
0
static int
ramips_phy_connect_multi(struct raeth_priv *re)
{
    struct net_device *netdev = re->netdev;
    struct ramips_eth_platform_data *pdata;
    struct phy_device *phydev = NULL;
    int phy_addr;
    int ret = 0;

    pdata = re->parent->platform_data;
    for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
        if (!(pdata->phy_mask & (1 << phy_addr)))
            continue;

        if (re->mii_bus->phy_map[phy_addr] == NULL)
            continue;

        RADEBUG("%s: PHY found at %s, uid=%08x\n",
                netdev->name,
                dev_name(&re->mii_bus->phy_map[phy_addr]->dev),
                re->mii_bus->phy_map[phy_addr]->phy_id);

        if (phydev == NULL)
            phydev = re->mii_bus->phy_map[phy_addr];
    }

    if (!phydev) {
        netdev_err(netdev, "no PHY found with phy_mask=%08x\n",
                   pdata->phy_mask);
        return -ENODEV;
    }

    re->phy_dev = phy_connect(netdev, dev_name(&phydev->dev),
                              ramips_phy_link_adjust, 0,
                              pdata->phy_if_mode);

    if (IS_ERR(re->phy_dev)) {
        netdev_err(netdev, "could not connect to PHY at %s\n",
                   dev_name(&phydev->dev));
        return PTR_ERR(re->phy_dev);
    }

    phydev->supported &= PHY_GBIT_FEATURES;
    phydev->advertising = phydev->supported;

    RADEBUG("%s: connected to PHY at %s [uid=%08x, driver=%s]\n",
            netdev->name, dev_name(&phydev->dev),
            phydev->phy_id, phydev->drv->name);

    re->link = 0;
    re->speed = 0;
    re->duplex = -1;
    re->rx_fc = 0;
    re->tx_fc = 0;

    return ret;
}
Example #2
0
static int
ramips_phy_connect_fixed(struct raeth_priv *re)
{
    struct ramips_eth_platform_data *pdata;

    pdata = re->parent->platform_data;
    switch (pdata->speed) {
    case SPEED_10:
    case SPEED_100:
    case SPEED_1000:
        break;
    default:
        netdev_err(re->netdev, "invalid speed specified\n");
        return -EINVAL;
    }

    RADEBUG("%s: using fixed link parameters\n", re->netdev->name);

    re->speed = pdata->speed;
    re->duplex = pdata->duplex;
    re->tx_fc = pdata->tx_fc;
    re->rx_fc = pdata->tx_fc;

    return 0;
}
Example #3
0
static int
ramips_mdio_read(struct mii_bus *bus, int phy_addr, int phy_reg)
{
    struct raeth_priv *re = bus->priv;
    int err;
    u32 t;

    err = ramips_mdio_wait_ready(re);
    if (err)
        return 0xffff;

    t = (phy_addr << 24) | (phy_reg << 16);
    ramips_fe_wr(t, RAMIPS_MDIO_ACCESS);
    t |= (1 << 31);
    ramips_fe_wr(t, RAMIPS_MDIO_ACCESS);

    err = ramips_mdio_wait_ready(re);
    if (err)
        return 0xffff;

    RADEBUG("%s: addr=%04x, reg=%04x, value=%04x\n", __func__,
            phy_addr, phy_reg, ramips_fe_rr(RAMIPS_MDIO_ACCESS) & 0xffff);

    return ramips_fe_rr(RAMIPS_MDIO_ACCESS) & 0xffff;
}
Example #4
0
static int
ramips_eth_plat_remove(struct platform_device *plat)
{
    unregister_netdev(ramips_dev);
    free_netdev(ramips_dev);
    RADEBUG("ramips_eth: unloaded\n");
    return 0;
}
Example #5
0
static int
ramips_eth_stop(struct net_device *dev)
{
	struct raeth_priv *re = netdev_priv(dev);

	ramips_fe_twr(ramips_fe_trr(RAETH_REG_PDMA_GLO_CFG) &
		     ~(RAMIPS_TX_WB_DDONE | RAMIPS_RX_DMA_EN | RAMIPS_TX_DMA_EN),
		     RAETH_REG_PDMA_GLO_CFG);

	netif_stop_queue(dev);
	ramips_phy_stop(re);
	RADEBUG("ramips_eth: stopped\n");
	return 0;
}
Example #6
0
static int
ramips_eth_stop(struct net_device *dev)
{
    struct raeth_priv *priv = netdev_priv(dev);

    ramips_fe_wr(ramips_fe_rr(RAMIPS_PDMA_GLO_CFG) &
                 ~(RAMIPS_TX_WB_DDONE | RAMIPS_RX_DMA_EN | RAMIPS_TX_DMA_EN),
                 RAMIPS_PDMA_GLO_CFG);

    /* disable all interrupts in the hw */
    ramips_fe_wr(0, RAMIPS_FE_INT_ENABLE);

    ramips_phy_stop(priv);
    free_irq(dev->irq, dev);
    netif_stop_queue(dev);
    tasklet_kill(&priv->tx_housekeeping_tasklet);
    tasklet_kill(&priv->rx_tasklet);
    ramips_cleanup_dma(priv);
    RADEBUG("ramips_eth: stopped\n");
    return 0;
}
Example #7
0
static int
ramips_eth_plat_probe(struct platform_device *plat)
{
    struct raeth_priv *priv;
    struct ramips_eth_platform_data *data = plat->dev.platform_data;
    struct resource *res;
    int err;

    if (!data) {
        dev_err(&plat->dev, "no platform data specified\n");
        return -EINVAL;
    }

    res = platform_get_resource(plat, IORESOURCE_MEM, 0);
    if (!res) {
        dev_err(&plat->dev, "no memory resource found\n");
        return -ENXIO;
    }

    ramips_fe_base = ioremap_nocache(res->start, res->end - res->start + 1);
    if (!ramips_fe_base)
        return -ENOMEM;

    ramips_dev = alloc_etherdev(sizeof(struct raeth_priv));
    if (!ramips_dev) {
        dev_err(&plat->dev, "alloc_etherdev failed\n");
        err = -ENOMEM;
        goto err_unmap;
    }

    strcpy(ramips_dev->name, "eth%d");
    ramips_dev->irq = platform_get_irq(plat, 0);
    if (ramips_dev->irq < 0) {
        dev_err(&plat->dev, "no IRQ resource found\n");
        err = -ENXIO;
        goto err_free_dev;
    }
    ramips_dev->addr_len = ETH_ALEN;
    ramips_dev->base_addr = (unsigned long)ramips_fe_base;
    ramips_dev->netdev_ops = &ramips_eth_netdev_ops;

    priv = netdev_priv(ramips_dev);

    priv->netdev = ramips_dev;
    priv->parent = &plat->dev;
    priv->speed = data->speed;
    priv->duplex = data->duplex;
    priv->rx_fc = data->rx_fc;
    priv->tx_fc = data->tx_fc;
    priv->plat = data;

    err = register_netdev(ramips_dev);
    if (err) {
        dev_err(&plat->dev, "error bringing up device\n");
        goto err_free_dev;
    }

    RADEBUG("ramips_eth: loaded\n");
    return 0;

err_free_dev:
    kfree(ramips_dev);
err_unmap:
    iounmap(ramips_fe_base);
    return err;
}