static int pic32_eth_start(struct udevice *dev) { struct eth_pdata *pdata = dev_get_platdata(dev); struct pic32eth_dev *priv = dev_get_priv(dev); /* controller */ pic32_ctrl_reset(priv); /* reset MAC */ pic32_mac_reset(priv); /* configure PHY */ phy_config(priv->phydev); /* initialize MAC */ pic32_mac_init(priv, &pdata->enetaddr[0]); /* init RX descriptor; TX descriptors are handled in xmit */ pic32_rx_desc_init(priv); /* Start up & update link status of PHY */ phy_startup(priv->phydev); /* adjust mac with phy link status */ return pic32_mac_adjust_link(priv); }
static int ll_temac_init(struct eth_device *dev, bd_t *bis) { struct ll_temac *ll_temac = dev->priv; int ret; printf("%s: Xilinx XPS LocalLink Tri-Mode Ether MAC #%d at 0x%08X.\n", dev->name, dev->index, dev->iobase); if (!ll_temac_setup_ctrl(dev)) return -1; /* Start up the PHY */ ret = phy_startup(ll_temac->phydev); if (ret) { printf("%s: Could not initialize PHY %s\n", dev->name, ll_temac->phydev->dev->name); return ret; } if (!ll_temac_adjust_link(dev)) { ll_temac_halt(dev); return -1; } /* If there's no link, fail */ return ll_temac->phydev->link ? 0 : -1; }
static int mvneta_start(struct udevice *dev) { struct mvneta_port *pp = dev_get_priv(dev); struct phy_device *phydev; mvneta_port_power_up(pp, pp->phy_interface); if (!pp->init || pp->link == 0) { /* Set phy address of the port */ mvreg_write(pp, MVNETA_PHY_ADDR, pp->phyaddr); phydev = phy_connect(pp->bus, pp->phyaddr, dev, pp->phy_interface); pp->phydev = phydev; phy_config(phydev); phy_startup(phydev); if (!phydev->link) { printf("%s: No link.\n", phydev->dev->name); return -1; } /* Full init on first call */ mvneta_init(dev); pp->init = 1; } else { /* Upon all following calls, this is enough */ mvneta_port_up(pp); mvneta_port_enable(pp); } return 0; }
int designware_eth_init(struct dw_eth_dev *priv, u8 *enetaddr) { struct eth_mac_regs *mac_p = priv->mac_regs_p; struct eth_dma_regs *dma_p = priv->dma_regs_p; unsigned int start; int ret; writel(readl(&dma_p->busmode) | DMAMAC_SRST, &dma_p->busmode); start = get_timer(0); while (readl(&dma_p->busmode) & DMAMAC_SRST) { if (get_timer(start) >= CONFIG_MACRESET_TIMEOUT) { printf("DMA reset timeout\n"); return -ETIMEDOUT; } mdelay(100); }; /* * Soft reset above clears HW address registers. * So we have to set it here once again. */ _dw_write_hwaddr(priv, enetaddr); rx_descs_init(priv); tx_descs_init(priv); writel(FIXEDBURST | PRIORXTX_41 | DMA_PBL, &dma_p->busmode); #ifndef CONFIG_DW_MAC_FORCE_THRESHOLD_MODE writel(readl(&dma_p->opmode) | FLUSHTXFIFO | STOREFORWARD, &dma_p->opmode); #else writel(readl(&dma_p->opmode) | FLUSHTXFIFO, &dma_p->opmode); #endif writel(readl(&dma_p->opmode) | RXSTART | TXSTART, &dma_p->opmode); #ifdef CONFIG_DW_AXI_BURST_LEN writel((CONFIG_DW_AXI_BURST_LEN & 0x1FF >> 1), &dma_p->axibus); #endif /* Start up the PHY */ ret = phy_startup(priv->phydev); if (ret) { printf("Could not initialize PHY %s\n", priv->phydev->dev->name); return ret; } ret = dw_adjust_link(priv, mac_p, priv->phydev); if (ret) return ret; return 0; }
static int ks2_eth_start(struct udevice *dev) { struct ks2_eth_priv *priv = dev_get_priv(dev); #ifdef CONFIG_SOC_K2G keystone_rgmii_config(priv->phydev); #else keystone_sgmii_config(priv->phydev, priv->slave_port - 1, priv->sgmii_link_type); #endif udelay(10000); /* On chip switch configuration */ ethss_config(target_get_switch_ctl(), SWITCH_MAX_PKT_SIZE); qm_init(); if (ksnav_init(priv->netcp_pktdma, &priv->net_rx_buffs)) { error("ksnav_init failed\n"); goto err_knav_init; } /* * Streaming switch configuration. If not present this * statement is defined to void in target.h. * If present this is usually defined to a series of register writes */ hw_config_streaming_switch(); if (priv->has_mdio) { keystone2_mdio_reset(priv->mdio_bus); phy_startup(priv->phydev); if (priv->phydev->link == 0) { error("phy startup failed\n"); goto err_phy_start; } } emac_gigabit_enable(dev); ethss_start(); priv->emac_open = true; return 0; err_phy_start: ksnav_close(priv->netcp_pktdma); err_knav_init: qm_close(); return -EFAULT; }
static int fm_eth_open(struct eth_device *dev, bd_t *bd) { struct fm_eth *fm_eth; struct fsl_enet_mac *mac; #ifdef CONFIG_PHYLIB int ret; #endif fm_eth = (struct fm_eth *)dev->priv; mac = fm_eth->mac; /* setup the MAC address */ if (dev->enetaddr[0] & 0x01) { printf("%s: MacAddress is multcast address\n", __func__); return 1; } mac->set_mac_addr(mac, dev->enetaddr); /* enable bmi Rx port */ setbits_be32(&fm_eth->rx_port->fmbm_rcfg, FMBM_RCFG_EN); /* enable MAC rx/tx port */ mac->enable_mac(mac); /* enable bmi Tx port */ setbits_be32(&fm_eth->tx_port->fmbm_tcfg, FMBM_TCFG_EN); /* re-enable transmission of frame */ fmc_tx_port_graceful_stop_disable(fm_eth); #ifdef CONFIG_PHYLIB if (fm_eth->phydev) { ret = phy_startup(fm_eth->phydev); if (ret) { printf("%s: Could not initialize\n", fm_eth->phydev->dev->name); return ret; } } else { return 0; } #else fm_eth->phydev->speed = SPEED_1000; fm_eth->phydev->link = 1; fm_eth->phydev->duplex = DUPLEX_FULL; #endif /* set the MAC-PHY mode */ mac->set_if_mode(mac, fm_eth->enet_if, fm_eth->phydev->speed); if (!fm_eth->phydev->link) printf("%s: No link.\n", fm_eth->phydev->dev->name); return fm_eth->phydev->link ? 0 : -1; }
/* Setting axi emac and phy to proper setting */ static int setup_phy(struct udevice *dev) { u32 speed, emmc_reg; struct axidma_priv *priv = dev_get_priv(dev); struct axi_regs *regs = priv->iobase; struct phy_device *phydev = priv->phydev; if (phy_startup(phydev)) { printf("axiemac: could not initialize PHY %s\n", phydev->dev->name); return 0; } if (!phydev->link) { printf("%s: No link.\n", phydev->dev->name); return 0; } switch (phydev->speed) { case 1000: speed = XAE_EMMC_LINKSPD_1000; break; case 100: speed = XAE_EMMC_LINKSPD_100; break; case 10: speed = XAE_EMMC_LINKSPD_10; break; default: return 0; } /* Setup the emac for the phy speed */ emmc_reg = in_be32(®s->emmc); emmc_reg &= ~XAE_EMMC_LINKSPEED_MASK; emmc_reg |= speed; /* Write new speed setting out to Axi Ethernet */ out_be32(®s->emmc, emmc_reg); /* * Setting the operating speed of the MAC needs a delay. There * doesn't seem to be register to poll, so please consider this * during your application design. */ udelay(1); return 1; }
static int dw_eth_init(struct eth_device *dev, bd_t *bis) { struct dw_eth_dev *priv = dev->priv; struct eth_mac_regs *mac_p = priv->mac_regs_p; struct eth_dma_regs *dma_p = priv->dma_regs_p; unsigned int start; writel(readl(&dma_p->busmode) | DMAMAC_SRST, &dma_p->busmode); start = get_timer(0); while (readl(&dma_p->busmode) & DMAMAC_SRST) { if (get_timer(start) >= CONFIG_MACRESET_TIMEOUT) return -1; mdelay(100); }; /* Soft reset above clears HW address registers. * So we have to set it here once again */ dw_write_hwaddr(dev); rx_descs_init(dev); tx_descs_init(dev); writel(FIXEDBURST | PRIORXTX_41 | DMA_PBL, &dma_p->busmode); writel(readl(&dma_p->opmode) | FLUSHTXFIFO | STOREFORWARD, &dma_p->opmode); writel(readl(&dma_p->opmode) | RXSTART | TXSTART, &dma_p->opmode); /* Start up the PHY */ if (phy_startup(priv->phydev)) { printf("Could not initialize PHY %s\n", priv->phydev->dev->name); return -1; } dw_adjust_link(mac_p, priv->phydev); if (!priv->phydev->link) return -1; writel(readl(&mac_p->conf) | RXENABLE | TXENABLE, &mac_p->conf); return 0; }
static int altera_tse_start(struct udevice *dev) { struct altera_tse_priv *priv = dev_get_priv(dev); struct alt_tse_mac *mac_dev = priv->mac_dev; u32 val; int ret; /* need to create sgdma */ debug("Configuring rx desc\n"); altera_tse_free_pkt(dev, priv->rx_buf, PKTSIZE_ALIGN); /* start TSE */ debug("Configuring TSE Mac\n"); /* Initialize MAC registers */ writel(PKTSIZE_ALIGN, &mac_dev->max_frame_length); writel(priv->rx_fifo_depth - 16, &mac_dev->rx_sel_empty_threshold); writel(0, &mac_dev->rx_sel_full_threshold); writel(priv->tx_fifo_depth - 16, &mac_dev->tx_sel_empty_threshold); writel(0, &mac_dev->tx_sel_full_threshold); writel(8, &mac_dev->rx_almost_empty_threshold); writel(8, &mac_dev->rx_almost_full_threshold); writel(8, &mac_dev->tx_almost_empty_threshold); writel(3, &mac_dev->tx_almost_full_threshold); /* NO Shift */ writel(0, &mac_dev->rx_cmd_stat); writel(0, &mac_dev->tx_cmd_stat); /* enable MAC */ val = ALTERA_TSE_CMD_TX_ENA_MSK | ALTERA_TSE_CMD_RX_ENA_MSK; writel(val, &mac_dev->command_config); /* Start up the PHY */ ret = phy_startup(priv->phydev); if (ret) { debug("Could not initialize PHY %s\n", priv->phydev->dev->name); return ret; } tse_adjust_link(priv, priv->phydev); if (!priv->phydev->link) return -EIO; return 0; }
/* Initializes data structures and registers for the controller, * and brings the interface up. Returns the link status, meaning * that it returns success if the link is up, failure otherwise. * This allows u-boot to find the first active controller. */ static int tsec_init(struct eth_device *dev, bd_t * bd) { uint tempval; char tmpbuf[MAC_ADDR_LEN]; int i; struct tsec_private *priv = (struct tsec_private *)dev->priv; tsec_t *regs = priv->regs; /* Make sure the controller is stopped */ tsec_halt(dev); /* Init MACCFG2. Defaults to GMII */ out_be32(®s->maccfg2, MACCFG2_INIT_SETTINGS); /* Init ECNTRL */ out_be32(®s->ecntrl, ECNTRL_INIT_SETTINGS); /* Copy the station address into the address registers. * Backwards, because little endian MACS are dumb */ for (i = 0; i < MAC_ADDR_LEN; i++) tmpbuf[MAC_ADDR_LEN - 1 - i] = dev->enetaddr[i]; tempval = (tmpbuf[0] << 24) | (tmpbuf[1] << 16) | (tmpbuf[2] << 8) | tmpbuf[3]; out_be32(®s->macstnaddr1, tempval); tempval = *((uint *) (tmpbuf + 4)); out_be32(®s->macstnaddr2, tempval); /* Clear out (for the most part) the other registers */ init_registers(regs); /* Ready the device for tx/rx */ startup_tsec(dev); /* Start up the PHY */ phy_startup(priv->phydev); adjust_link(priv, priv->phydev); /* If there's no link, fail */ return priv->phydev->link ? 0 : -1; }
static int bcm_sf2_eth_open(struct eth_device *dev, bd_t *bt) { struct eth_info *eth = (struct eth_info *)(dev->priv); struct eth_dma *dma = &(eth->dma); int i; debug("Enabling BCM SF2 Ethernet.\n"); /* Set MAC address from env */ if (bcm_sf2_eth_write_hwaddr(dev) != 0) { error("%s: MAC set error when opening !\n", __func__); return -1; } eth->enable_mac(); /* enable tx and rx DMA */ dma->enable_dma(dma, MAC_DMA_RX); dma->enable_dma(dma, MAC_DMA_TX); /* * Need to start PHY here because link speed can change * before each ethernet operation */ for (i = 0; i < eth->port_num; i++) { if (phy_startup(eth->port[i])) { error("%s: PHY %d startup failed!\n", __func__, i); if (i == CONFIG_BCM_SF2_ETH_DEFAULT_PORT) { error("%s: No default port %d!\n", __func__, i); return -1; } } } /* Set MAC speed using default port */ i = CONFIG_BCM_SF2_ETH_DEFAULT_PORT; debug("PHY %d: speed:%d, duplex:%d, link:%d\n", i, eth->port[i]->speed, eth->port[i]->duplex, eth->port[i]->link); eth->set_mac_speed(eth->port[i]->speed, eth->port[i]->duplex); debug("Enable Ethernet Done.\n"); return 0; }
static int pch_gbe_start(struct udevice *dev) { struct pch_gbe_priv *priv = dev_get_priv(dev); struct pch_gbe_regs *mac_regs = priv->mac_regs; if (pch_gbe_reset(dev)) return -1; pch_gbe_rx_descs_init(dev); pch_gbe_tx_descs_init(dev); /* Enable frame bursting */ writel(PCH_GBE_MODE_FR_BST, &mac_regs->mode); /* Disable TCP/IP accelerator */ writel(PCH_GBE_RX_TCPIPACC_OFF, &mac_regs->tcpip_acc); /* Disable RX flow control */ writel(0, &mac_regs->rx_fctrl); /* Configure RX/TX mode */ writel(PCH_GBE_RH_ALM_EMP_16 | PCH_GBE_RH_ALM_FULL_16 | PCH_GBE_RH_RD_TRG_32, &mac_regs->rx_mode); writel(PCH_GBE_TM_TH_TX_STRT_32 | PCH_GBE_TM_TH_ALM_EMP_16 | PCH_GBE_TM_TH_ALM_FULL_32 | PCH_GBE_TM_ST_AND_FD | PCH_GBE_TM_SHORT_PKT, &mac_regs->tx_mode); /* Start up the PHY */ if (phy_startup(priv->phydev)) { printf("Could not initialize PHY %s\n", priv->phydev->dev->name); return -1; } pch_gbe_adjust_link(mac_regs, priv->phydev); if (!priv->phydev->link) return -1; /* Enable TX & RX */ writel(PCH_GBE_RX_DMA_EN | PCH_GBE_TX_DMA_EN, &mac_regs->dma_ctrl); writel(PCH_GBE_MRE_MAC_RX_EN, &mac_regs->mac_rx_en); return 0; }
static int ethoc_init_common(struct ethoc *priv) { int ret = 0; priv->num_tx = 1; priv->num_rx = PKTBUFSRX; ethoc_write(priv, TX_BD_NUM, priv->num_tx); ethoc_init_ring(priv); ethoc_reset(priv); #ifdef CONFIG_PHYLIB ret = phy_startup(priv->phydev); if (ret) { printf("Could not initialize PHY %s\n", priv->phydev->dev->name); return ret; } #endif return ret; }
int mvgbe_phylib_init(struct eth_device *dev, int phyid) { struct mii_dev *bus; struct phy_device *phydev; int ret; bus = mdio_alloc(); if (!bus) { printf("mdio_alloc failed\n"); return -ENOMEM; } bus->read = mvgbe_phy_read; bus->write = mvgbe_phy_write; sprintf(bus->name, dev->name); ret = mdio_register(bus); if (ret) { printf("mdio_register failed\n"); free(bus); return -ENOMEM; } /* Set phy address of the port */ mvgbe_phy_write(bus, MV_PHY_ADR_REQUEST, 0, MV_PHY_ADR_REQUEST, phyid); phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_RGMII); if (!phydev) { printf("phy_connect failed\n"); return -ENODEV; } phy_config(phydev); phy_startup(phydev); return 0; }
/** * Start the FEC engine * @param[in] dev Our device to handle */ static int fec_open(struct eth_device *edev) { struct fec_priv *fec = (struct fec_priv *)edev->priv; int speed; uint32_t addr, size; int i; debug("fec_open: fec_open(dev)\n"); /* full-duplex, heartbeat disabled */ writel(1 << 2, &fec->eth->x_cntrl); fec->rbd_index = 0; /* Invalidate all descriptors */ for (i = 0; i < FEC_RBD_NUM - 1; i++) fec_rbd_clean(0, &fec->rbd_base[i]); fec_rbd_clean(1, &fec->rbd_base[i]); /* Flush the descriptors into RAM */ size = roundup(FEC_RBD_NUM * sizeof(struct fec_bd), ARCH_DMA_MINALIGN); addr = (uint32_t)fec->rbd_base; flush_dcache_range(addr, addr + size); #ifdef FEC_QUIRK_ENET_MAC /* Enable ENET HW endian SWAP */ writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_DBSWAP, &fec->eth->ecntrl); /* Enable ENET store and forward mode */ writel(readl(&fec->eth->x_wmrk) | FEC_X_WMRK_STRFWD, &fec->eth->x_wmrk); #endif /* * Enable FEC-Lite controller */ writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_ETHER_EN, &fec->eth->ecntrl); #if defined(CONFIG_MX25) || defined(CONFIG_MX53) || defined(CONFIG_MX6SL) udelay(100); /* * setup the MII gasket for RMII mode */ /* disable the gasket */ writew(0, &fec->eth->miigsk_enr); /* wait for the gasket to be disabled */ while (readw(&fec->eth->miigsk_enr) & MIIGSK_ENR_READY) udelay(2); /* configure gasket for RMII, 50 MHz, no loopback, and no echo */ writew(MIIGSK_CFGR_IF_MODE_RMII, &fec->eth->miigsk_cfgr); /* re-enable the gasket */ writew(MIIGSK_ENR_EN, &fec->eth->miigsk_enr); /* wait until MII gasket is ready */ int max_loops = 10; while ((readw(&fec->eth->miigsk_enr) & MIIGSK_ENR_READY) == 0) { if (--max_loops <= 0) { printf("WAIT for MII Gasket ready timed out\n"); break; } } #endif #ifdef CONFIG_PHYLIB { /* Start up the PHY */ int ret = phy_startup(fec->phydev); if (ret) { printf("Could not initialize PHY %s\n", fec->phydev->dev->name); return ret; } speed = fec->phydev->speed; } #elif CONFIG_FEC_FIXED_SPEED speed = CONFIG_FEC_FIXED_SPEED; #else miiphy_wait_aneg(edev); speed = miiphy_speed(edev->name, fec->phy_id); miiphy_duplex(edev->name, fec->phy_id); #endif #ifdef FEC_QUIRK_ENET_MAC { u32 ecr = readl(&fec->eth->ecntrl) & ~FEC_ECNTRL_SPEED; u32 rcr = readl(&fec->eth->r_cntrl) & ~FEC_RCNTRL_RMII_10T; if (speed == _1000BASET) ecr |= FEC_ECNTRL_SPEED; else if (speed != _100BASET) rcr |= FEC_RCNTRL_RMII_10T; writel(ecr, &fec->eth->ecntrl); writel(rcr, &fec->eth->r_cntrl); } #endif debug("%s:Speed=%i\n", __func__, speed); /* * Enable SmartDMA receive task */ fec_rx_task_enable(fec); udelay(100000); return 0; }
static int sh_eth_config(struct sh_eth_dev *eth, bd_t *bd) { int port = eth->port, ret = 0; u32 val; struct sh_eth_info *port_info = ð->port_info[port]; struct eth_device *dev = port_info->dev; struct phy_device *phy; /* Configure e-dmac registers */ sh_eth_write(eth, (sh_eth_read(eth, EDMR) & ~EMDR_DESC_R) | EDMR_EL, EDMR); sh_eth_write(eth, 0, EESIPR); sh_eth_write(eth, 0, TRSCER); sh_eth_write(eth, 0, TFTR); sh_eth_write(eth, (FIFO_SIZE_T | FIFO_SIZE_R), FDR); sh_eth_write(eth, RMCR_RST, RMCR); #if defined(SH_ETH_TYPE_GETHER) sh_eth_write(eth, 0, RPADIR); #endif sh_eth_write(eth, (FIFO_F_D_RFF | FIFO_F_D_RFD), FCFTR); /* Configure e-mac registers */ sh_eth_write(eth, 0, ECSIPR); /* Set Mac address */ val = dev->enetaddr[0] << 24 | dev->enetaddr[1] << 16 | dev->enetaddr[2] << 8 | dev->enetaddr[3]; sh_eth_write(eth, val, MAHR); val = dev->enetaddr[4] << 8 | dev->enetaddr[5]; sh_eth_write(eth, val, MALR); sh_eth_write(eth, RFLR_RFL_MIN, RFLR); #if defined(SH_ETH_TYPE_GETHER) sh_eth_write(eth, 0, PIPR); sh_eth_write(eth, APR_AP, APR); sh_eth_write(eth, MPR_MP, MPR); sh_eth_write(eth, TPAUSER_TPAUSE, TPAUSER); #endif #if defined(CONFIG_CPU_SH7734) || defined(CONFIG_R8A7740) sh_eth_write(eth, CONFIG_SH_ETHER_SH7734_MII, RMII_MII); #endif /* Configure phy */ ret = sh_eth_phy_config(eth); if (ret) { printf(SHETHER_NAME ": phy config timeout\n"); goto err_phy_cfg; } phy = port_info->phydev; ret = phy_startup(phy); if (ret) { printf(SHETHER_NAME ": phy startup failure\n"); return ret; } val = 0; /* Set the transfer speed */ if (phy->speed == 100) { printf(SHETHER_NAME ": 100Base/"); #if defined(SH_ETH_TYPE_GETHER) sh_eth_write(eth, GECMR_100B, GECMR); #elif defined(CONFIG_CPU_SH7757) sh_eth_write(eth, 1, RTRATE); #elif defined(CONFIG_CPU_SH7724) val = ECMR_RTM; #endif } else if (phy->speed == 10) { printf(SHETHER_NAME ": 10Base/"); #if defined(SH_ETH_TYPE_GETHER) sh_eth_write(eth, GECMR_10B, GECMR); #elif defined(CONFIG_CPU_SH7757) sh_eth_write(eth, 0, RTRATE); #endif } #if defined(SH_ETH_TYPE_GETHER) else if (phy->speed == 1000) { printf(SHETHER_NAME ": 1000Base/"); sh_eth_write(eth, GECMR_1000B, GECMR); } #endif /* Check if full duplex mode is supported by the phy */ if (phy->duplex) { printf("Full\n"); sh_eth_write(eth, val | (ECMR_CHG_DM|ECMR_RE|ECMR_TE|ECMR_DM), ECMR); } else { printf("Half\n"); sh_eth_write(eth, val | (ECMR_CHG_DM|ECMR_RE|ECMR_TE), ECMR); } return ret; err_phy_cfg: return ret; }
static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd) { struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; struct dpni_queue_attr rx_queue_attr; uint8_t mac_addr[6]; int err; if (net_dev->state == ETH_STATE_ACTIVE) return 0; /* DPNI initialization */ err = ldpaa_dpni_setup(priv); if (err < 0) goto err_dpni_setup; err = ldpaa_dpbp_setup(); if (err < 0) goto err_dpbp_setup; /* DPNI binding DPBP */ err = ldpaa_dpni_bind(priv); if (err) goto err_bind; err = dpni_get_primary_mac_addr(dflt_mc_io, priv->dpni_handle, mac_addr); if (err) { printf("dpni_get_primary_mac_addr() failed\n"); return err; } memcpy(net_dev->enetaddr, mac_addr, 0x6); /* setup the MAC address */ if (net_dev->enetaddr[0] & 0x01) { printf("%s: MacAddress is multcast address\n", __func__); return 1; } #ifdef CONFIG_PHYLIB /* TODO Check this path */ err = phy_startup(priv->phydev); if (err) { printf("%s: Could not initialize\n", priv->phydev->dev->name); return err; } #else priv->phydev->speed = SPEED_1000; priv->phydev->link = 1; priv->phydev->duplex = DUPLEX_FULL; #endif err = dpni_enable(dflt_mc_io, priv->dpni_handle); if (err < 0) { printf("dpni_enable() failed\n"); return err; } /* TODO: support multiple Rx flows */ err = dpni_get_rx_flow(dflt_mc_io, priv->dpni_handle, 0, 0, &rx_queue_attr); if (err) { printf("dpni_get_rx_flow() failed\n"); goto err_rx_flow; } priv->rx_dflt_fqid = rx_queue_attr.fqid; err = dpni_get_qdid(dflt_mc_io, priv->dpni_handle, &priv->tx_qdid); if (err) { printf("dpni_get_qdid() failed\n"); goto err_qdid; } if (!priv->phydev->link) printf("%s: No link.\n", priv->phydev->dev->name); return priv->phydev->link ? 0 : -1; err_qdid: err_rx_flow: dpni_disable(dflt_mc_io, priv->dpni_handle); err_bind: ldpaa_dpbp_free(); err_dpbp_setup: dpni_close(dflt_mc_io, priv->dpni_handle); err_dpni_setup: return err; }
/* Setting axi emac and phy to proper setting */ static int setup_phy(struct udevice *dev) { u16 temp; u32 speed, emmc_reg, ret; struct axidma_priv *priv = dev_get_priv(dev); struct axi_regs *regs = priv->iobase; struct phy_device *phydev = priv->phydev; if (priv->interface == PHY_INTERFACE_MODE_SGMII) { /* * In SGMII cases the isolate bit might set * after DMA and ethernet resets and hence * check and clear if set. */ ret = phyread(priv, priv->phyaddr, MII_BMCR, &temp); if (ret) return 0; if (temp & BMCR_ISOLATE) { temp &= ~BMCR_ISOLATE; ret = phywrite(priv, priv->phyaddr, MII_BMCR, temp); if (ret) return 0; } } if (phy_startup(phydev)) { printf("axiemac: could not initialize PHY %s\n", phydev->dev->name); return 0; } if (!phydev->link) { printf("%s: No link.\n", phydev->dev->name); return 0; } switch (phydev->speed) { case 1000: speed = XAE_EMMC_LINKSPD_1000; break; case 100: speed = XAE_EMMC_LINKSPD_100; break; case 10: speed = XAE_EMMC_LINKSPD_10; break; default: return 0; } /* Setup the emac for the phy speed */ emmc_reg = readl(®s->emmc); emmc_reg &= ~XAE_EMMC_LINKSPEED_MASK; emmc_reg |= speed; /* Write new speed setting out to Axi Ethernet */ writel(emmc_reg, ®s->emmc); /* * Setting the operating speed of the MAC needs a delay. There * doesn't seem to be register to poll, so please consider this * during your application design. */ udelay(1); return 1; }
static int ftgmac100_start(struct udevice *dev) { struct eth_pdata *plat = dev_get_platdata(dev); struct ftgmac100_data *priv = dev_get_priv(dev); struct ftgmac100 *ftgmac100 = priv->iobase; struct phy_device *phydev = priv->phydev; unsigned int maccr; ulong start, end; int ret; int i; debug("%s()\n", __func__); ftgmac100_reset(priv); /* set the ethernet address */ ftgmac100_set_mac(priv, plat->enetaddr); /* disable all interrupts */ writel(0, &ftgmac100->ier); /* initialize descriptors */ priv->tx_index = 0; priv->rx_index = 0; for (i = 0; i < PKTBUFSTX; i++) { priv->txdes[i].txdes3 = 0; priv->txdes[i].txdes0 = 0; } priv->txdes[PKTBUFSTX - 1].txdes0 = priv->txdes0_edotr_mask; start = (ulong)&priv->txdes[0]; end = start + roundup(sizeof(priv->txdes), ARCH_DMA_MINALIGN); flush_dcache_range(start, end); for (i = 0; i < PKTBUFSRX; i++) { priv->rxdes[i].rxdes3 = (unsigned int)net_rx_packets[i]; priv->rxdes[i].rxdes0 = 0; } priv->rxdes[PKTBUFSRX - 1].rxdes0 = priv->rxdes0_edorr_mask; start = (ulong)&priv->rxdes[0]; end = start + roundup(sizeof(priv->rxdes), ARCH_DMA_MINALIGN); flush_dcache_range(start, end); /* transmit ring */ writel((u32)priv->txdes, &ftgmac100->txr_badr); /* receive ring */ writel((u32)priv->rxdes, &ftgmac100->rxr_badr); /* poll receive descriptor automatically */ writel(FTGMAC100_APTC_RXPOLL_CNT(1), &ftgmac100->aptc); /* config receive buffer size register */ writel(FTGMAC100_RBSR_SIZE(FTGMAC100_RBSR_DEFAULT), &ftgmac100->rbsr); /* enable transmitter, receiver */ maccr = FTGMAC100_MACCR_TXMAC_EN | FTGMAC100_MACCR_RXMAC_EN | FTGMAC100_MACCR_TXDMA_EN | FTGMAC100_MACCR_RXDMA_EN | FTGMAC100_MACCR_CRC_APD | FTGMAC100_MACCR_FULLDUP | FTGMAC100_MACCR_RX_RUNT | FTGMAC100_MACCR_RX_BROADPKT; writel(maccr, &ftgmac100->maccr); ret = phy_startup(phydev); if (ret) { dev_err(phydev->dev, "Could not start PHY\n"); return ret; } ret = ftgmac100_phy_adjust_link(priv); if (ret) { dev_err(phydev->dev, "Could not adjust link\n"); return ret; } printf("%s: link up, %d Mbps %s-duplex mac:%pM\n", phydev->dev->name, phydev->speed, phydev->duplex ? "full" : "half", plat->enetaddr); return 0; }
static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd) { struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; struct dpni_queue_attr rx_queue_attr; struct dpmac_link_state dpmac_link_state = { 0 }; #ifdef DEBUG struct dpni_link_state link_state; #endif int err = 0; struct mii_dev *bus; phy_interface_t enet_if; if (net_dev->state == ETH_STATE_ACTIVE) return 0; if (get_mc_boot_status() != 0) { printf("ERROR (MC is not booted)\n"); return -ENODEV; } if (get_dpl_apply_status() == 0) { printf("ERROR (DPL is deployed. No device available)\n"); return -ENODEV; } /* DPMAC initialization */ err = ldpaa_dpmac_setup(priv); if (err < 0) goto err_dpmac_setup; #ifdef CONFIG_PHYLIB if (priv->phydev) err = phy_startup(priv->phydev); if (err) { printf("%s: Could not initialize\n", priv->phydev->dev->name); goto err_dpamc_bind; } #else priv->phydev = (struct phy_device *)malloc(sizeof(struct phy_device)); memset(priv->phydev, 0, sizeof(struct phy_device)); priv->phydev->speed = SPEED_1000; priv->phydev->link = 1; priv->phydev->duplex = DUPLEX_FULL; #endif bus = wriop_get_mdio(priv->dpmac_id); enet_if = wriop_get_enet_if(priv->dpmac_id); if ((bus == NULL) && (enet_if == PHY_INTERFACE_MODE_XGMII)) { priv->phydev = (struct phy_device *) malloc(sizeof(struct phy_device)); memset(priv->phydev, 0, sizeof(struct phy_device)); priv->phydev->speed = SPEED_10000; priv->phydev->link = 1; priv->phydev->duplex = DUPLEX_FULL; } if (!priv->phydev->link) { printf("%s: No link.\n", priv->phydev->dev->name); err = -1; goto err_dpamc_bind; } /* DPMAC binding DPNI */ err = ldpaa_dpmac_bind(priv); if (err) goto err_dpamc_bind; /* DPNI initialization */ err = ldpaa_dpni_setup(priv); if (err < 0) goto err_dpni_setup; err = ldpaa_dpbp_setup(); if (err < 0) goto err_dpbp_setup; /* DPNI binding DPBP */ err = ldpaa_dpni_bind(priv); if (err) goto err_dpni_bind; err = dpni_add_mac_addr(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle, net_dev->enetaddr); if (err) { printf("dpni_add_mac_addr() failed\n"); return err; } err = dpni_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); if (err < 0) { printf("dpni_enable() failed\n"); return err; } dpmac_link_state.rate = priv->phydev->speed; if (priv->phydev->autoneg == AUTONEG_DISABLE) dpmac_link_state.options &= ~DPMAC_LINK_OPT_AUTONEG; else dpmac_link_state.options |= DPMAC_LINK_OPT_AUTONEG; if (priv->phydev->duplex == DUPLEX_HALF) dpmac_link_state.options |= DPMAC_LINK_OPT_HALF_DUPLEX; dpmac_link_state.up = priv->phydev->link; err = dpmac_set_link_state(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle, &dpmac_link_state); if (err < 0) { printf("dpmac_set_link_state() failed\n"); return err; } #ifdef DEBUG err = dpni_get_link_state(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle, &link_state); if (err < 0) { printf("dpni_get_link_state() failed\n"); return err; } printf("link status: %d - ", link_state.up); link_state.up == 0 ? printf("down\n") : link_state.up == 1 ? printf("up\n") : printf("error state\n"); #endif /* TODO: support multiple Rx flows */ err = dpni_get_rx_flow(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle, 0, 0, &rx_queue_attr); if (err) { printf("dpni_get_rx_flow() failed\n"); goto err_rx_flow; } priv->rx_dflt_fqid = rx_queue_attr.fqid; err = dpni_get_qdid(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle, &priv->tx_qdid); if (err) { printf("dpni_get_qdid() failed\n"); goto err_qdid; } return priv->phydev->link; err_qdid: err_rx_flow: dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); err_dpni_bind: ldpaa_dpbp_free(); err_dpbp_setup: dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); err_dpni_setup: err_dpamc_bind: dpmac_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle); err_dpmac_setup: return err; }
/* Eth device open */ static int keystone2_eth_open(struct eth_device *dev, bd_t *bis) { struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv; struct phy_device *phy_dev = eth_priv->phy_dev; debug("+ emac_open\n"); net_rx_buffs.rx_flow = eth_priv->rx_flow; sys_has_mdio = (eth_priv->sgmii_link_type == SGMII_LINK_MAC_PHY) ? 1 : 0; if (sys_has_mdio) keystone2_mdio_reset(mdio_bus); #ifdef CONFIG_SOC_K2G keystone_rgmii_config(phy_dev); #else keystone_sgmii_config(phy_dev, eth_priv->slave_port - 1, eth_priv->sgmii_link_type); #endif udelay(10000); /* On chip switch configuration */ ethss_config(target_get_switch_ctl(), SWITCH_MAX_PKT_SIZE); /* TODO: add error handling code */ if (qm_init()) { printf("ERROR: qm_init()\n"); return -1; } if (ksnav_init(&netcp_pktdma, &net_rx_buffs)) { qm_close(); printf("ERROR: netcp_init()\n"); return -1; } /* * Streaming switch configuration. If not present this * statement is defined to void in target.h. * If present this is usually defined to a series of register writes */ hw_config_streaming_switch(); if (sys_has_mdio) { keystone2_mdio_reset(mdio_bus); phy_startup(phy_dev); if (phy_dev->link == 0) { ksnav_close(&netcp_pktdma); qm_close(); return -1; } } emac_gigabit_enable(dev); ethss_start(); debug("- emac_open\n"); emac_open = 1; return 0; }
static int setup_phy(struct udevice *dev) { int i, ret; u16 phyreg; struct xemaclite *emaclite = dev_get_priv(dev); struct phy_device *phydev; u32 supported = SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full; if (emaclite->phyaddr != -1) { phyread(emaclite, emaclite->phyaddr, PHY_DETECT_REG, &phyreg); if ((phyreg != 0xFFFF) && ((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) { /* Found a valid PHY address */ debug("Default phy address %d is valid\n", emaclite->phyaddr); } else { debug("PHY address is not setup correctly %d\n", emaclite->phyaddr); emaclite->phyaddr = -1; } } if (emaclite->phyaddr == -1) { /* detect the PHY address */ for (i = 31; i >= 0; i--) { phyread(emaclite, i, PHY_DETECT_REG, &phyreg); if ((phyreg != 0xFFFF) && ((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) { /* Found a valid PHY address */ emaclite->phyaddr = i; debug("emaclite: Found valid phy address, %d\n", i); break; } } } /* interface - look at tsec */ phydev = phy_connect(emaclite->bus, emaclite->phyaddr, dev, PHY_INTERFACE_MODE_MII); /* * Phy can support 1000baseT but device NOT that's why phydev->supported * must be setup for 1000baseT. phydev->advertising setups what speeds * will be used for autonegotiation where 1000baseT must be disabled. */ phydev->supported = supported | SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full; phydev->advertising = supported; emaclite->phydev = phydev; phy_config(phydev); ret = phy_startup(phydev); if (ret) return ret; if (!phydev->link) { printf("%s: No link.\n", phydev->dev->name); return 0; } /* Do not setup anything */ return 1; }
static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd) { struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv; struct dpni_queue_attr rx_queue_attr; struct dpmac_link_state dpmac_link_state = { 0 }; #ifdef DEBUG struct dpni_link_state link_state; #endif int err; if (net_dev->state == ETH_STATE_ACTIVE) return 0; if (get_mc_boot_status() != 0) { printf("ERROR (MC is not booted)\n"); return -ENODEV; } if (get_dpl_apply_status() == 0) { printf("ERROR (DPL is deployed. No device available)\n"); return -ENODEV; } /* DPMAC initialization */ err = ldpaa_dpmac_setup(priv); if (err < 0) goto err_dpmac_setup; /* DPMAC binding DPNI */ err = ldpaa_dpmac_bind(priv); if (err) goto err_dpamc_bind; /* DPNI initialization */ err = ldpaa_dpni_setup(priv); if (err < 0) goto err_dpni_setup; err = ldpaa_dpbp_setup(); if (err < 0) goto err_dpbp_setup; /* DPNI binding DPBP */ err = ldpaa_dpni_bind(priv); if (err) goto err_dpni_bind; err = dpni_add_mac_addr(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle, net_dev->enetaddr); if (err) { printf("dpni_add_mac_addr() failed\n"); return err; } #ifdef CONFIG_PHYLIB /* TODO Check this path */ err = phy_startup(priv->phydev); if (err) { printf("%s: Could not initialize\n", priv->phydev->dev->name); return err; } #else priv->phydev->speed = SPEED_1000; priv->phydev->link = 1; priv->phydev->duplex = DUPLEX_FULL; #endif err = dpni_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); if (err < 0) { printf("dpni_enable() failed\n"); return err; } dpmac_link_state.rate = SPEED_1000; dpmac_link_state.options = DPMAC_LINK_OPT_AUTONEG; dpmac_link_state.up = 1; err = dpmac_set_link_state(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle, &dpmac_link_state); if (err < 0) { printf("dpmac_set_link_state() failed\n"); return err; } #ifdef DEBUG err = dpni_get_link_state(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle, &link_state); if (err < 0) { printf("dpni_get_link_state() failed\n"); return err; } printf("link status: %d - ", link_state.up); link_state.up == 0 ? printf("down\n") : link_state.up == 1 ? printf("up\n") : printf("error state\n"); #endif /* TODO: support multiple Rx flows */ err = dpni_get_rx_flow(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle, 0, 0, &rx_queue_attr); if (err) { printf("dpni_get_rx_flow() failed\n"); goto err_rx_flow; } priv->rx_dflt_fqid = rx_queue_attr.fqid; err = dpni_get_qdid(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle, &priv->tx_qdid); if (err) { printf("dpni_get_qdid() failed\n"); goto err_qdid; } if (!priv->phydev->link) printf("%s: No link.\n", priv->phydev->dev->name); return priv->phydev->link ? 0 : -1; err_qdid: err_rx_flow: dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); err_dpni_bind: ldpaa_dpbp_free(); err_dpbp_setup: err_dpamc_bind: dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle); err_dpni_setup: err_dpmac_setup: return err; }
/* Setting axi emac and phy to proper setting */ static int setup_phy(struct eth_device *dev) { u16 phyreg; u32 i, speed, emmc_reg, ret; struct axidma_priv *priv = dev->priv; struct axi_regs *regs = (struct axi_regs *)dev->iobase; struct phy_device *phydev; u32 supported = SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full; if (priv->phyaddr == -1) { /* Detect the PHY address */ for (i = 31; i >= 0; i--) { ret = phyread(dev, i, PHY_DETECT_REG, &phyreg); if (!ret && (phyreg != 0xFFFF) && ((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) { /* Found a valid PHY address */ priv->phyaddr = i; debug("axiemac: Found valid phy address, %x\n", phyreg); break; } } } /* Interface - look at tsec */ phydev = phy_connect(priv->bus, priv->phyaddr, dev, 0); phydev->supported &= supported; phydev->advertising = phydev->supported; priv->phydev = phydev; phy_config(phydev); if (phy_startup(phydev)) { printf("axiemac: could not initialize PHY %s\n", phydev->dev->name); return 0; } switch (phydev->speed) { case 1000: speed = XAE_EMMC_LINKSPD_1000; break; case 100: speed = XAE_EMMC_LINKSPD_100; break; case 10: speed = XAE_EMMC_LINKSPD_10; break; default: return 0; } /* Setup the emac for the phy speed */ emmc_reg = in_be32(®s->emmc); emmc_reg &= ~XAE_EMMC_LINKSPEED_MASK; emmc_reg |= speed; /* Write new speed setting out to Axi Ethernet */ out_be32(®s->emmc, emmc_reg); /* * Setting the operating speed of the MAC needs a delay. There * doesn't seem to be register to poll, so please consider this * during your application design. */ udelay(1); return 1; }
static int dw_eth_init(struct eth_device *dev, bd_t *bis) { struct dw_eth_dev *priv = dev->priv; struct eth_mac_regs *mac_p = priv->mac_regs_p; struct eth_dma_regs *dma_p = priv->dma_regs_p; u32 conf; #ifdef CONFIG_LARK_BOARD int ret; #endif if (priv->phy_configured != 1) { int ret = configure_phy(dev); if (ret < 0) { printf("failed to configure phy: %d\n", ret); return ret; } } #ifdef CONFIG_LARK_BOARD ret = phy_startup(priv->phy_dev); if (ret) { printf("%s: Could not initialize\n", priv->phy_dev->dev->name); return ret; } if(priv->phy_dev->speed == SPEED_1000){ priv->speed = _1000BASET; } else if(priv->phy_dev->speed == SPEED_100){ priv->speed = _100BASET; } else if(priv->phy_dev->speed == SPEED_10){ priv->speed =_10BASET; } #endif /* Print link status only once */ if (!priv->link_printed) { printf("ENET Speed is %d Mbps - %s duplex connection\n", priv->speed, (priv->duplex == HALF) ? "HALF" : "FULL"); priv->link_printed = 1; } /* Reset ethernet hardware */ if (mac_reset(dev) < 0) return -1; /* Resore the HW MAC address as it has been lost during MAC reset */ dw_write_hwaddr(dev); writel(FIXEDBURST | PRIORXTX_41 | BURST_16, &dma_p->busmode); writel(readl(&dma_p->opmode) | FLUSHTXFIFO | STOREFORWARD | TXSECONDFRAME, &dma_p->opmode); conf = FRAMEBURSTENABLE | DISABLERXOWN; if (priv->speed != 1000) conf |= MII_PORTSELECT; if ((priv->interface != PHY_INTERFACE_MODE_MII) && (priv->interface != PHY_INTERFACE_MODE_GMII)) { if (priv->speed == 100) conf |= FES_100; } if (priv->duplex == FULL) conf |= FULLDPLXMODE; writel(conf, &mac_p->conf); descs_init(dev); /* * Start/Enable xfer at dma as well as mac level */ writel(readl(&dma_p->opmode) | RXSTART, &dma_p->opmode); writel(readl(&dma_p->opmode) | TXSTART, &dma_p->opmode); writel(readl(&mac_p->conf) | RXENABLE | TXENABLE, &mac_p->conf); return 0; }
/** * Start the FEC engine * @param[in] dev Our device to handle */ static int fec_open(struct eth_device *edev) { struct fec_priv *fec = (struct fec_priv *)edev->priv; int speed; debug("fec_open: fec_open(dev)\n"); /* full-duplex, heartbeat disabled */ writel(1 << 2, &fec->eth->x_cntrl); fec->rbd_index = 0; #ifdef FEC_QUIRK_ENET_MAC /* Enable ENET HW endian SWAP */ writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_DBSWAP, &fec->eth->ecntrl); /* Enable ENET store and forward mode */ writel(readl(&fec->eth->x_wmrk) | FEC_X_WMRK_STRFWD, &fec->eth->x_wmrk); #endif /* * Enable FEC-Lite controller */ writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_ETHER_EN, &fec->eth->ecntrl); #if defined(CONFIG_MX25) || defined(CONFIG_MX53) udelay(100); /* * setup the MII gasket for RMII mode */ /* disable the gasket */ writew(0, &fec->eth->miigsk_enr); /* wait for the gasket to be disabled */ while (readw(&fec->eth->miigsk_enr) & MIIGSK_ENR_READY) udelay(2); /* configure gasket for RMII, 50 MHz, no loopback, and no echo */ writew(MIIGSK_CFGR_IF_MODE_RMII, &fec->eth->miigsk_cfgr); /* re-enable the gasket */ writew(MIIGSK_ENR_EN, &fec->eth->miigsk_enr); /* wait until MII gasket is ready */ int max_loops = 10; while ((readw(&fec->eth->miigsk_enr) & MIIGSK_ENR_READY) == 0) { if (--max_loops <= 0) { printf("WAIT for MII Gasket ready timed out\n"); break; } } #endif #ifdef CONFIG_PHYLIB if (!fec->phydev) fec_eth_phy_config(edev); if (fec->phydev) { /* Start up the PHY */ phy_startup(fec->phydev); speed = fec->phydev->speed; } else { speed = _100BASET; } #else miiphy_wait_aneg(edev); speed = miiphy_speed(edev->name, fec->phy_id); miiphy_duplex(edev->name, fec->phy_id); #endif #ifdef FEC_QUIRK_ENET_MAC { u32 ecr = readl(&fec->eth->ecntrl) & ~FEC_ECNTRL_SPEED; u32 rcr = (readl(&fec->eth->r_cntrl) & ~(FEC_RCNTRL_RMII | FEC_RCNTRL_RMII_10T)) | FEC_RCNTRL_RGMII | FEC_RCNTRL_MII_MODE; if (speed == _1000BASET) ecr |= FEC_ECNTRL_SPEED; else if (speed != _100BASET) rcr |= FEC_RCNTRL_RMII_10T; writel(ecr, &fec->eth->ecntrl); writel(rcr, &fec->eth->r_cntrl); } #endif debug("%s:Speed=%i\n", __func__, speed); /* * Enable SmartDMA receive task */ fec_rx_task_enable(fec); udelay(100000); return 0; }
static int zynq_gem_init(struct udevice *dev) { u32 i, nwconfig; unsigned long clk_rate = 0; struct zynq_gem_priv *priv = dev_get_priv(dev); struct zynq_gem_regs *regs = priv->iobase; struct emac_bd *dummy_tx_bd = &priv->tx_bd[TX_FREE_DESC]; struct emac_bd *dummy_rx_bd = &priv->tx_bd[TX_FREE_DESC + 2]; if (!priv->init) { /* Disable all interrupts */ writel(0xFFFFFFFF, ®s->idr); /* Disable the receiver & transmitter */ writel(0, ®s->nwctrl); writel(0, ®s->txsr); writel(0, ®s->rxsr); writel(0, ®s->phymntnc); /* Clear the Hash registers for the mac address * pointed by AddressPtr */ writel(0x0, ®s->hashl); /* Write bits [63:32] in TOP */ writel(0x0, ®s->hashh); /* Clear all counters */ for (i = 0; i < STAT_SIZE; i++) readl(®s->stat[i]); /* Setup RxBD space */ memset(priv->rx_bd, 0, RX_BUF * sizeof(struct emac_bd)); for (i = 0; i < RX_BUF; i++) { priv->rx_bd[i].status = 0xF0000000; priv->rx_bd[i].addr = ((ulong)(priv->rxbuffers) + (i * PKTSIZE_ALIGN)); } /* WRAP bit to last BD */ priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK; /* Write RxBDs to IP */ writel((ulong)priv->rx_bd, ®s->rxqbase); /* Setup for DMA Configuration register */ writel(ZYNQ_GEM_DMACR_INIT, ®s->dmacr); /* Setup for Network Control register, MDIO, Rx and Tx enable */ setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_MDEN_MASK); /* Disable the second priority queue */ dummy_tx_bd->addr = 0; dummy_tx_bd->status = ZYNQ_GEM_TXBUF_WRAP_MASK | ZYNQ_GEM_TXBUF_LAST_MASK| ZYNQ_GEM_TXBUF_USED_MASK; dummy_rx_bd->addr = ZYNQ_GEM_RXBUF_WRAP_MASK | ZYNQ_GEM_RXBUF_NEW_MASK; dummy_rx_bd->status = 0; flush_dcache_range((ulong)&dummy_tx_bd, (ulong)&dummy_tx_bd + sizeof(dummy_tx_bd)); flush_dcache_range((ulong)&dummy_rx_bd, (ulong)&dummy_rx_bd + sizeof(dummy_rx_bd)); writel((ulong)dummy_tx_bd, ®s->transmit_q1_ptr); writel((ulong)dummy_rx_bd, ®s->receive_q1_ptr); priv->init++; } phy_startup(priv->phydev); if (!priv->phydev->link) { printf("%s: No link.\n", priv->phydev->dev->name); return -1; } nwconfig = ZYNQ_GEM_NWCFG_INIT; if (priv->interface == PHY_INTERFACE_MODE_SGMII) { nwconfig |= ZYNQ_GEM_NWCFG_SGMII_ENBL | ZYNQ_GEM_NWCFG_PCS_SEL; #ifdef CONFIG_ARM64 writel(readl(®s->pcscntrl) | ZYNQ_GEM_PCS_CTL_ANEG_ENBL, ®s->pcscntrl); #endif } switch (priv->phydev->speed) { case SPEED_1000: writel(nwconfig | ZYNQ_GEM_NWCFG_SPEED1000, ®s->nwcfg); clk_rate = ZYNQ_GEM_FREQUENCY_1000; break; case SPEED_100: writel(nwconfig | ZYNQ_GEM_NWCFG_SPEED100, ®s->nwcfg); clk_rate = ZYNQ_GEM_FREQUENCY_100; break; case SPEED_10: clk_rate = ZYNQ_GEM_FREQUENCY_10; break; } /* Change the rclk and clk only not using EMIO interface */ if (!priv->emio) zynq_slcr_gem_clk_setup((ulong)priv->iobase != ZYNQ_GEM_BASEADDR0, clk_rate); setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK | ZYNQ_GEM_NWCTRL_TXEN_MASK); return 0; }
static int sh_eth_config(struct sh_eth_dev *eth, bd_t *bd) { int port = eth->port, ret = 0; u32 val; struct sh_eth_info *port_info = ð->port_info[port]; struct eth_device *dev = port_info->dev; struct phy_device *phy; /* Configure e-dmac registers */ outl((inl(EDMR(port)) & ~EMDR_DESC_R) | EDMR_EL, EDMR(port)); outl(0, EESIPR(port)); outl(0, TRSCER(port)); outl(0, TFTR(port)); outl((FIFO_SIZE_T | FIFO_SIZE_R), FDR(port)); outl(RMCR_RST, RMCR(port)); #if !defined(CONFIG_CPU_SH7757) && !defined(CONFIG_CPU_SH7724) outl(0, RPADIR(port)); #endif outl((FIFO_F_D_RFF | FIFO_F_D_RFD), FCFTR(port)); /* Configure e-mac registers */ #if defined(CONFIG_CPU_SH7757) outl(ECSIPR_BRCRXIP | ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | ECSIPR_MPDIP | ECSIPR_ICDIP, ECSIPR(port)); #else outl(0, ECSIPR(port)); #endif /* Set Mac address */ val = dev->enetaddr[0] << 24 | dev->enetaddr[1] << 16 | dev->enetaddr[2] << 8 | dev->enetaddr[3]; outl(val, MAHR(port)); val = dev->enetaddr[4] << 8 | dev->enetaddr[5]; outl(val, MALR(port)); outl(RFLR_RFL_MIN, RFLR(port)); #if !defined(CONFIG_CPU_SH7757) && !defined(CONFIG_CPU_SH7724) outl(0, PIPR(port)); #endif #if !defined(CONFIG_CPU_SH7724) outl(APR_AP, APR(port)); outl(MPR_MP, MPR(port)); #endif #if defined(CONFIG_CPU_SH7763) outl(TPAUSER_TPAUSE, TPAUSER(port)); #elif defined(CONFIG_CPU_SH7757) outl(TPAUSER_UNLIMITED, TPAUSER(port)); #endif /* Configure phy */ ret = sh_eth_phy_config(eth); if (ret) { printf(SHETHER_NAME ": phy config timeout\n"); goto err_phy_cfg; } phy = port_info->phydev; phy_startup(phy); val = 0; /* Set the transfer speed */ if (phy->speed == 100) { printf(SHETHER_NAME ": 100Base/"); #ifdef CONFIG_CPU_SH7763 outl(GECMR_100B, GECMR(port)); #elif defined(CONFIG_CPU_SH7757) outl(1, RTRATE(port)); #elif defined(CONFIG_CPU_SH7724) val = ECMR_RTM; #endif } else if (phy->speed == 10) { printf(SHETHER_NAME ": 10Base/"); #ifdef CONFIG_CPU_SH7763 outl(GECMR_10B, GECMR(port)); #elif defined(CONFIG_CPU_SH7757) outl(0, RTRATE(port)); #endif } /* Check if full duplex mode is supported by the phy */ if (phy->duplex) { printf("Full\n"); outl(val | (ECMR_CHG_DM|ECMR_RE|ECMR_TE|ECMR_DM), ECMR(port)); } else { printf("Half\n"); outl(val | (ECMR_CHG_DM|ECMR_RE|ECMR_TE), ECMR(port)); } return ret; err_phy_cfg: return ret; }
static int zynq_gem_init(struct udevice *dev) { u32 i, nwconfig; int ret; unsigned long clk_rate = 0; struct zynq_gem_priv *priv = dev_get_priv(dev); struct zynq_gem_regs *regs = priv->iobase; struct emac_bd *dummy_tx_bd = &priv->tx_bd[TX_FREE_DESC]; struct emac_bd *dummy_rx_bd = &priv->tx_bd[TX_FREE_DESC + 2]; if (!priv->init) { /* Disable all interrupts */ writel(0xFFFFFFFF, ®s->idr); /* Disable the receiver & transmitter */ writel(0, ®s->nwctrl); writel(0, ®s->txsr); writel(0, ®s->rxsr); writel(0, ®s->phymntnc); /* Clear the Hash registers for the mac address * pointed by AddressPtr */ writel(0x0, ®s->hashl); /* Write bits [63:32] in TOP */ writel(0x0, ®s->hashh); /* Clear all counters */ for (i = 0; i < STAT_SIZE; i++) readl(®s->stat[i]); /* Setup RxBD space */ memset(priv->rx_bd, 0, RX_BUF * sizeof(struct emac_bd)); for (i = 0; i < RX_BUF; i++) { priv->rx_bd[i].status = 0xF0000000; priv->rx_bd[i].addr = ((ulong)(priv->rxbuffers) + (i * PKTSIZE_ALIGN)); } /* WRAP bit to last BD */ priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK; /* Write RxBDs to IP */ writel((ulong)priv->rx_bd, ®s->rxqbase); /* Setup for DMA Configuration register */ writel(ZYNQ_GEM_DMACR_INIT, ®s->dmacr); /* Setup for Network Control register, MDIO, Rx and Tx enable */ setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_MDEN_MASK); /* Disable the second priority queue */ dummy_tx_bd->addr = 0; dummy_tx_bd->status = ZYNQ_GEM_TXBUF_WRAP_MASK | ZYNQ_GEM_TXBUF_LAST_MASK| ZYNQ_GEM_TXBUF_USED_MASK; dummy_rx_bd->addr = ZYNQ_GEM_RXBUF_WRAP_MASK | ZYNQ_GEM_RXBUF_NEW_MASK; dummy_rx_bd->status = 0; writel((ulong)dummy_tx_bd, ®s->transmit_q1_ptr); writel((ulong)dummy_rx_bd, ®s->receive_q1_ptr); priv->init++; } ret = phy_startup(priv->phydev); if (ret) return ret; if (!priv->phydev->link) { printf("%s: No link.\n", priv->phydev->dev->name); return -1; } nwconfig = ZYNQ_GEM_NWCFG_INIT; /* * Set SGMII enable PCS selection only if internal PCS/PMA * core is used and interface is SGMII. */ if (priv->interface == PHY_INTERFACE_MODE_SGMII && priv->int_pcs) { nwconfig |= ZYNQ_GEM_NWCFG_SGMII_ENBL | ZYNQ_GEM_NWCFG_PCS_SEL; #ifdef CONFIG_ARM64 writel(readl(®s->pcscntrl) | ZYNQ_GEM_PCS_CTL_ANEG_ENBL, ®s->pcscntrl); #endif } switch (priv->phydev->speed) { case SPEED_1000: writel(nwconfig | ZYNQ_GEM_NWCFG_SPEED1000, ®s->nwcfg); clk_rate = ZYNQ_GEM_FREQUENCY_1000; break; case SPEED_100: writel(nwconfig | ZYNQ_GEM_NWCFG_SPEED100, ®s->nwcfg); clk_rate = ZYNQ_GEM_FREQUENCY_100; break; case SPEED_10: clk_rate = ZYNQ_GEM_FREQUENCY_10; break; } #if !defined(CONFIG_ARCH_VERSAL) ret = clk_set_rate(&priv->clk, clk_rate); if (IS_ERR_VALUE(ret) && ret != (unsigned long)-ENOSYS) { dev_err(dev, "failed to set tx clock rate\n"); return ret; } ret = clk_enable(&priv->clk); if (ret && ret != -ENOSYS) { dev_err(dev, "failed to enable tx clock\n"); return ret; } #else debug("requested clk_rate %ld\n", clk_rate); #endif setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK | ZYNQ_GEM_NWCTRL_TXEN_MASK); return 0; }
static int zynq_gem_init(struct eth_device *dev, bd_t * bis) { u32 i; unsigned long __maybe_unused clk_rate = 0; struct phy_device *phydev; struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; struct zynq_gem_priv *priv = dev->priv; struct emac_bd *dummy_tx_bd = &priv->tx_bd[4]; struct emac_bd *dummy_rx_bd = &priv->tx_bd[6]; const u32 supported = SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full; if (!priv->init) { /* Disable all interrupts */ writel(0xFFFFFFFF, ®s->idr); /* Disable the receiver & transmitter */ writel(0, ®s->nwctrl); writel(0, ®s->txsr); writel(0, ®s->rxsr); writel(0, ®s->phymntnc); /* Clear the Hash registers for the mac address * pointed by AddressPtr */ writel(0x0, ®s->hashl); /* Write bits [63:32] in TOP */ writel(0x0, ®s->hashh); /* Clear all counters */ for (i = 0; i < STAT_SIZE; i++) readl(®s->stat[i]); /* Setup RxBD space */ memset(priv->rx_bd, 0, RX_BUF * sizeof(struct emac_bd)); for (i = 0; i < RX_BUF; i++) { priv->rx_bd[i].status = 0xF0000000; priv->rx_bd[i].addr = ((unsigned long)(priv->rxbuffers) + (i * PKTSIZE_ALIGN)); } /* WRAP bit to last BD */ priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK; /* Write RxBDs to IP */ writel((unsigned long)priv->rx_bd, ®s->rxqbase); /* Setup for DMA Configuration register */ writel(ZYNQ_GEM_DMACR_INIT, ®s->dmacr); /* Setup for Network Control register, MDIO, Rx and Tx enable */ setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_MDEN_MASK); /* * Disable the second priority queue. * FIXME: Consider GEMs with more than 2 queues. */ dummy_tx_bd->addr = 0; dummy_tx_bd->status = ZYNQ_GEM_TXBUF_WRAP_MASK | ZYNQ_GEM_TXBUF_LAST_MASK| ZYNQ_GEM_TXBUF_USED_MASK; dummy_rx_bd->addr = ZYNQ_GEM_RXBUF_WRAP_MASK | ZYNQ_GEM_RXBUF_NEW_MASK; dummy_rx_bd->status = 0; flush_dcache_range((ulong)&dummy_tx_bd, (ulong)&dummy_tx_bd + sizeof(dummy_tx_bd)); flush_dcache_range((ulong)&dummy_rx_bd, (ulong)&dummy_rx_bd + sizeof(dummy_rx_bd)); writel((unsigned long)dummy_tx_bd, ®s->transmit_q1_ptr); writel((unsigned long)dummy_rx_bd, ®s->receive_q1_ptr); priv->init++; } phy_detection(dev); /* interface - look at tsec */ phydev = phy_connect(priv->bus, priv->phyaddr, dev, priv->interface); phydev->supported = supported | ADVERTISED_Pause | ADVERTISED_Asym_Pause; phydev->advertising = phydev->supported; priv->phydev = phydev; phy_config(phydev); phy_startup(phydev); phydev->speed = SPEED_1000; if (!phydev->link) { printf("%s: No link.\n", phydev->dev->name); return -1; } switch (phydev->speed) { case SPEED_1000: writel(ZYNQ_GEM_NWCFG_INIT | ZYNQ_GEM_NWCFG_SPEED1000, ®s->nwcfg); clk_rate = ZYNQ_GEM_FREQUENCY_1000; break; case SPEED_100: writel(ZYNQ_GEM_NWCFG_INIT | ZYNQ_GEM_NWCFG_SPEED100, ®s->nwcfg); clk_rate = ZYNQ_GEM_FREQUENCY_100; break; case SPEED_10: clk_rate = ZYNQ_GEM_FREQUENCY_10; break; } /* Change the rclk and clk only not using EMIO interface */ if (!priv->emio) zynq_slcr_gem_clk_setup(dev->iobase != ZYNQ_GEM_BASEADDR0, clk_rate); /* set hardware address because of ... */ if (!is_valid_ethaddr(dev->enetaddr)) { printf("%s: mac address is not valid\n", dev->name); return -1; } zynq_gem_setup_mac(dev); setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK | ZYNQ_GEM_NWCTRL_TXEN_MASK); return 0; }