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; }
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; }
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; }
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; }
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; }
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; }
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; }