static void __lpc_params_setup(struct netdata_local *pldat) { u32 tmp; if (pldat->duplex == DUPLEX_FULL) { tmp = readl(LPC_ENET_MAC2(pldat->net_base)); tmp |= LPC_MAC2_FULL_DUPLEX; writel(tmp, LPC_ENET_MAC2(pldat->net_base)); tmp = readl(LPC_ENET_COMMAND(pldat->net_base)); tmp |= LPC_COMMAND_FULLDUPLEX; writel(tmp, LPC_ENET_COMMAND(pldat->net_base)); writel(LPC_IPGT_LOAD(0x15), LPC_ENET_IPGT(pldat->net_base)); } else { tmp = readl(LPC_ENET_MAC2(pldat->net_base)); tmp &= ~LPC_MAC2_FULL_DUPLEX; writel(tmp, LPC_ENET_MAC2(pldat->net_base)); tmp = readl(LPC_ENET_COMMAND(pldat->net_base)); tmp &= ~LPC_COMMAND_FULLDUPLEX; writel(tmp, LPC_ENET_COMMAND(pldat->net_base)); writel(LPC_IPGT_LOAD(0x12), LPC_ENET_IPGT(pldat->net_base)); } if (pldat->speed == SPEED_100) writel(LPC_SUPP_SPEED, LPC_ENET_SUPP(pldat->net_base)); else writel(0, LPC_ENET_SUPP(pldat->net_base)); }
static void __lpc_eth_init(struct netdata_local *pldat) { u32 tmp; /* Disable controller and reset */ tmp = readl(LPC_ENET_COMMAND(pldat->net_base)); tmp &= ~LPC_COMMAND_RXENABLE | LPC_COMMAND_TXENABLE; writel(tmp, LPC_ENET_COMMAND(pldat->net_base)); tmp = readl(LPC_ENET_MAC1(pldat->net_base)); tmp &= ~LPC_MAC1_RECV_ENABLE; writel(tmp, LPC_ENET_MAC1(pldat->net_base)); /* Initial MAC setup */ writel(LPC_MAC1_PASS_ALL_RX_FRAMES, LPC_ENET_MAC1(pldat->net_base)); writel((LPC_MAC2_PAD_CRC_ENABLE | LPC_MAC2_CRC_ENABLE), LPC_ENET_MAC2(pldat->net_base)); writel(ENET_MAXF_SIZE, LPC_ENET_MAXF(pldat->net_base)); /* Collision window, gap */ writel((LPC_CLRT_LOAD_RETRY_MAX(0xF) | LPC_CLRT_LOAD_COLLISION_WINDOW(0x37)), LPC_ENET_CLRT(pldat->net_base)); writel(LPC_IPGR_LOAD_PART2(0x12), LPC_ENET_IPGR(pldat->net_base)); if (lpc_phy_interface_mode(&pldat->pdev->dev) == PHY_INTERFACE_MODE_MII) writel(LPC_COMMAND_PASSRUNTFRAME, LPC_ENET_COMMAND(pldat->net_base)); else { writel((LPC_COMMAND_PASSRUNTFRAME | LPC_COMMAND_RMII), LPC_ENET_COMMAND(pldat->net_base)); writel(LPC_SUPP_RESET_RMII, LPC_ENET_SUPP(pldat->net_base)); } __lpc_params_setup(pldat); /* Setup TX and RX descriptors */ __lpc_txrx_desc_setup(pldat); /* Setup packet filtering */ writel((LPC_RXFLTRW_ACCEPTUBROADCAST | LPC_RXFLTRW_ACCEPTPERFECT), LPC_ENET_RXFILTER_CTRL(pldat->net_base)); /* Get the next TX buffer output index */ pldat->num_used_tx_buffs = 0; pldat->last_tx_idx = readl(LPC_ENET_TXCONSUMEINDEX(pldat->net_base)); /* Clear and enable interrupts */ writel(0xFFFF, LPC_ENET_INTCLEAR(pldat->net_base)); smp_wmb(); lpc_eth_enable_int(pldat->net_base); /* Enable controller */ tmp = readl(LPC_ENET_COMMAND(pldat->net_base)); tmp |= LPC_COMMAND_RXENABLE | LPC_COMMAND_TXENABLE; writel(tmp, LPC_ENET_COMMAND(pldat->net_base)); tmp = readl(LPC_ENET_MAC1(pldat->net_base)); tmp |= LPC_MAC1_RECV_ENABLE; writel(tmp, LPC_ENET_MAC1(pldat->net_base)); }
static int lpc_mii_init(struct netdata_local *pldat) { int err = -ENXIO, i; pldat->mii_bus = mdiobus_alloc(); if (!pldat->mii_bus) { err = -ENOMEM; goto err_out; } /* Setup MII mode */ if (lpc_phy_interface_mode(&pldat->pdev->dev) == PHY_INTERFACE_MODE_MII) writel(LPC_COMMAND_PASSRUNTFRAME, LPC_ENET_COMMAND(pldat->net_base)); else { writel((LPC_COMMAND_PASSRUNTFRAME | LPC_COMMAND_RMII), LPC_ENET_COMMAND(pldat->net_base)); writel(LPC_SUPP_RESET_RMII, LPC_ENET_SUPP(pldat->net_base)); } pldat->mii_bus->name = "lpc_mii_bus"; pldat->mii_bus->read = &lpc_mdio_read; pldat->mii_bus->write = &lpc_mdio_write; pldat->mii_bus->reset = &lpc_mdio_reset; snprintf(pldat->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x", pldat->pdev->name, pldat->pdev->id); pldat->mii_bus->priv = pldat; pldat->mii_bus->parent = &pldat->pdev->dev; pldat->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); if (!pldat->mii_bus->irq) { err = -ENOMEM; goto err_out_1; } for (i = 0; i < PHY_MAX_ADDR; i++) pldat->mii_bus->irq[i] = PHY_POLL; platform_set_drvdata(pldat->pdev, pldat->mii_bus); if (mdiobus_register(pldat->mii_bus)) goto err_out_free_mdio_irq; if (lpc_mii_probe(pldat->ndev) != 0) goto err_out_unregister_bus; return 0; err_out_unregister_bus: mdiobus_unregister(pldat->mii_bus); err_out_free_mdio_irq: kfree(pldat->mii_bus->irq); err_out_1: mdiobus_free(pldat->mii_bus); err_out: return err; }