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); }
void ls2085a_handle_phy_interface_sgmii(int dpmac_id) { int lane, slot; struct mii_dev *bus; struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) & FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK) >> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT; int serdes2_prtcl = (in_le32(&gur->rcwsr[28]) & FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK) >> FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT; switch (serdes1_prtcl) { } switch (serdes2_prtcl) { case 0x07: case 0x08: case 0x49: lane = serdes_get_first_lane(FSL_SRDS_2, SGMII9 + (dpmac_id - 9)); slot = lane_to_slot_fsm2[lane]; switch (++slot) { case 1: break; case 3: break; case 4: /* Slot housing a SGMII riser card? */ wriop_set_phy_address(dpmac_id, riser_phy_addr[dpmac_id - 9]); dpmac_info[dpmac_id].board_mux = EMI1_SLOT4; bus = mii_dev_for_muxval(EMI1_SLOT4); wriop_set_mdio(dpmac_id, bus); dpmac_info[dpmac_id].phydev = phy_connect( dpmac_info[dpmac_id].bus, dpmac_info[dpmac_id].phy_addr, NULL, dpmac_info[dpmac_id].enet_if); phy_config(dpmac_info[dpmac_id].phydev); break; case 5: break; case 6: /* Slot housing a SGMII riser card? */ wriop_set_phy_address(dpmac_id, riser_phy_addr[dpmac_id - 13]); dpmac_info[dpmac_id].board_mux = EMI1_SLOT6; bus = mii_dev_for_muxval(EMI1_SLOT6); wriop_set_mdio(dpmac_id, bus); break; } break; default: printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n", serdes2_prtcl); break; } }
/* * This function initializes the EMAC hardware. */ int keystone2_emac_initialize(struct eth_priv_t *eth_priv) { int res; struct eth_device *dev; struct phy_device *phy_dev; dev = malloc(sizeof(struct eth_device)); if (dev == NULL) return -1; memset(dev, 0, sizeof(struct eth_device)); strcpy(dev->name, eth_priv->int_name); dev->priv = eth_priv; keystone2_eth_read_mac_addr(dev); dev->iobase = 0; dev->init = keystone2_eth_open; dev->halt = keystone2_eth_close; dev->send = keystone2_eth_send_packet; dev->recv = keystone2_eth_rcv_packet; #ifdef CONFIG_MCAST_TFTP dev->mcast = keystone2_eth_bcast_addr; #endif eth_register(dev); /* Register MDIO bus if it's not registered yet */ if (!mdio_bus) { mdio_bus = mdio_alloc(); mdio_bus->read = keystone2_mdio_read; mdio_bus->write = keystone2_mdio_write; mdio_bus->reset = keystone2_mdio_reset; mdio_bus->priv = (void *)EMAC_MDIO_BASE_ADDR; sprintf(mdio_bus->name, "ethernet-mdio"); res = mdio_register(mdio_bus); if (res) return res; } #ifndef CONFIG_SOC_K2G keystone2_net_serdes_setup(); #endif /* Create phy device and bind it with driver */ #ifdef CONFIG_KSNET_MDIO_PHY_CONFIG_ENABLE phy_dev = phy_connect(mdio_bus, eth_priv->phy_addr, dev, eth_priv->phy_if); phy_config(phy_dev); #else phy_dev = phy_find_by_mask(mdio_bus, 1 << eth_priv->phy_addr, eth_priv->phy_if); phy_dev->dev = dev; #endif eth_priv->phy_dev = phy_dev; return 0; }
/* Discover which PHY is attached to the device, and configure it * properly. If the PHY is not recognized, then return 0 * (failure). Otherwise, return 1 */ static int init_phy(struct eth_device *dev) { struct tsec_private *priv = (struct tsec_private *)dev->priv; struct phy_device *phydev; tsec_t *regs = priv->regs; u32 supported = (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full); if (priv->flags & TSEC_GIGABIT) supported |= SUPPORTED_1000baseT_Full; /* Assign a Physical address to the TBI */ out_be32(®s->tbipa, CONFIG_SYS_TBIPA_VALUE); priv->interface = tsec_get_interface(priv); if (priv->interface == PHY_INTERFACE_MODE_SGMII) tsec_configure_serdes(priv); phydev = phy_connect(priv->bus, priv->phyaddr, dev, priv->interface); phydev->supported &= supported; phydev->advertising = phydev->supported; priv->phydev = phydev; phy_config(phydev); return 1; }
static int bcm_sf2_eth_init(struct eth_device *dev) { struct eth_info *eth = (struct eth_info *)(dev->priv); struct eth_dma *dma = &(eth->dma); struct phy_device *phydev; int rc = 0; int i; rc = eth->mac_init(dev); if (rc) { error("%s: Couldn't cofigure MAC!\n", __func__); return rc; } /* disable DMA */ dma->disable_dma(dma, MAC_DMA_RX); dma->disable_dma(dma, MAC_DMA_TX); eth->port_num = 0; debug("Connecting PHY 0...\n"); phydev = phy_connect(miiphy_get_dev_by_name(dev->name), 0, dev, eth->phy_interface); if (phydev != NULL) { eth->port[0] = phydev; eth->port_num += 1; } else { debug("No PHY found for port 0\n"); } for (i = 0; i < eth->port_num; i++) phy_config(eth->port[i]); return rc; }
static int zynq_phy_init(struct udevice *dev) { int ret; struct zynq_gem_priv *priv = dev_get_priv(dev); struct zynq_gem_regs *regs = priv->iobase; const u32 supported = SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full; /* Enable only MDIO bus */ writel(ZYNQ_GEM_NWCTRL_MDEN_MASK, ®s->nwctrl); if (priv->interface != PHY_INTERFACE_MODE_SGMII) { ret = phy_detection(dev); if (ret) { printf("GEM PHY init failed\n"); return ret; } } priv->phydev = phy_connect(priv->bus, priv->phyaddr, dev, priv->interface); if (!priv->phydev) return -ENODEV; priv->phydev->supported = supported | ADVERTISED_Pause | ADVERTISED_Asym_Pause; priv->phydev->advertising = priv->phydev->supported; phy_config(priv->phydev); return 0; }
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; }
static void fec_eth_phy_config(struct eth_device *dev) { #ifdef CONFIG_PHYLIB struct fec_priv *fec = (struct fec_priv *)dev->priv; struct phy_device *phydev; phydev = phy_connect(fec->bus, fec->phy_id, dev, PHY_INTERFACE_MODE_RGMII); if (phydev) { fec->phydev = phydev; phy_config(phydev); } #endif }
void init_host_phys(struct mii_dev *bus) { uint k; for (k = 0; k < 2; ++k) { struct phy_device *phydev; phydev = phy_find_by_mask(bus, 1 << k, PHY_INTERFACE_MODE_SGMII); if (phydev) phy_config(phydev); } }
static int sh_eth_phy_config(struct sh_eth_dev *eth) { int port = eth->port, ret = 0; struct sh_eth_info *port_info = ð->port_info[port]; struct eth_device *dev = port_info->dev; struct phy_device *phydev; phydev = phy_connect(miiphy_get_dev_by_name(dev->name), port_info->phy_addr, dev, PHY_INTERFACE_MODE_MII); port_info->phydev = phydev; phy_config(phydev); return ret; }
static int init_phy(struct eth_device *dev) { struct fm_eth *fm_eth = dev->priv; #ifdef CONFIG_PHYLIB struct phy_device *phydev = NULL; u32 supported; #endif if (fm_eth->type == FM_ETH_1G_E) dtsec_init_phy(dev); #ifdef CONFIG_PHYLIB if (fm_eth->bus) { phydev = phy_connect(fm_eth->bus, fm_eth->phyaddr, dev, fm_eth->enet_if); if (!phydev) { printf("Failed to connect\n"); return -1; } } else { return 0; } if (fm_eth->type == FM_ETH_1G_E) { supported = (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full); } else { supported = SUPPORTED_10000baseT_Full; if (tgec_is_fibre(dev)) phydev->port = PORT_FIBRE; } phydev->supported &= supported; phydev->advertising = phydev->supported; fm_eth->phydev = phydev; phy_config(phydev); #endif return 0; }
/* * Discover which PHY is attached to the device, and configure it * properly. If the PHY is not recognized, then return 0 * (failure). Otherwise, return 1 */ static int ll_temac_phy_init(struct eth_device *dev) { struct ll_temac *ll_temac = dev->priv; struct phy_device *phydev; unsigned int supported = PHY_GBIT_FEATURES; /* interface - look at driver/net/tsec.c */ phydev = phy_connect(ll_temac->bus, ll_temac->phyaddr, dev, PHY_INTERFACE_MODE_NONE); phydev->supported &= supported; phydev->advertising = phydev->supported; ll_temac->phydev = phydev; phy_config(phydev); return 1; }
static int axiemac_phy_init(struct udevice *dev) { u16 phyreg; u32 i, ret; struct axidma_priv *priv = dev_get_priv(dev); struct axi_regs *regs = priv->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; /* Set default MDIO divisor */ writel(XAE_MDIO_DIV_DFT | XAE_MDIO_MC_MDIOEN_MASK, ®s->mdio_mc); if (priv->phyaddr == -1) { /* Detect the PHY address */ for (i = 31; i >= 0; i--) { ret = phyread(priv, 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", i); break; } } } /* Interface - look at tsec */ phydev = phy_connect(priv->bus, priv->phyaddr, dev, priv->interface); phydev->supported &= supported; phydev->advertising = phydev->supported; priv->phydev = phydev; phy_config(phydev); return 0; }
static int fec_phy_init(struct fec_priv *priv, struct udevice *dev) { struct phy_device *phydev; int mask = 0xffffffff; #ifdef CONFIG_PHYLIB mask = 1 << CONFIG_FEC_MXC_PHYADDR; #endif phydev = phy_find_by_mask(priv->bus, mask, priv->interface); if (!phydev) return -ENODEV; phy_connect_dev(phydev, dev); priv->phydev = phydev; phy_config(phydev); return 0; }
static int init_phy(struct eth_device *dev) { struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv; struct phy_device *phydev = NULL; struct mii_dev *bus; bus = wriop_get_mdio(priv->dpmac_id); if (bus == NULL) return 0; phydev = phy_connect(bus, wriop_get_phy_address(priv->dpmac_id), dev, wriop_get_enet_if(priv->dpmac_id)); if (!phydev) { printf("Failed to connect\n"); return -1; } priv->phydev = phydev; return phy_config(phydev); }
static int tse_phy_init(struct altera_tse_priv *priv, void *dev) { struct phy_device *phydev; unsigned int mask = 0xffffffff; if (priv->phyaddr) mask = 1 << priv->phyaddr; phydev = phy_find_by_mask(priv->bus, mask, priv->interface); if (!phydev) return -ENODEV; phy_connect_dev(phydev, dev); phydev->supported &= PHY_GBIT_FEATURES; phydev->advertising = phydev->supported; priv->phydev = phydev; phy_config(phydev); return 0; }
static int ftgmac100_phy_init(struct udevice *dev) { struct ftgmac100_data *priv = dev_get_priv(dev); struct phy_device *phydev; int ret; phydev = phy_connect(priv->bus, priv->phy_addr, dev, priv->phy_mode); if (!phydev) return -ENODEV; phydev->supported &= PHY_GBIT_FEATURES; if (priv->max_speed) { ret = phy_set_supported(phydev, priv->max_speed); if (ret) return ret; } phydev->advertising = phydev->supported; priv->phydev = phydev; phy_config(phydev); return 0; }
static int pch_gbe_phy_init(struct eth_device *dev) { struct pch_gbe_priv *priv = dev->priv; struct phy_device *phydev; int mask = 0xffffffff; phydev = phy_find_by_mask(priv->bus, mask, priv->interface); if (!phydev) { printf("pch_gbe: cannot find the phy\n"); return -1; } phy_connect_dev(phydev, dev); phydev->supported &= PHY_GBIT_FEATURES; phydev->advertising = phydev->supported; priv->phydev = phydev; phy_config(phydev); return 1; }
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; }
static int fec_probe(bd_t *bd, int dev_id, uint32_t base_addr, struct mii_dev *bus, int phy_id) #endif { struct eth_device *edev; struct fec_priv *fec; unsigned char ethaddr[6]; uint32_t start; int ret = 0; /* create and fill edev struct */ edev = (struct eth_device *)malloc(sizeof(struct eth_device)); if (!edev) { puts("fec_mxc: not enough malloc memory for eth_device\n"); ret = -ENOMEM; goto err1; } fec = (struct fec_priv *)malloc(sizeof(struct fec_priv)); if (!fec) { puts("fec_mxc: not enough malloc memory for fec_priv\n"); ret = -ENOMEM; goto err2; } memset(edev, 0, sizeof(*edev)); memset(fec, 0, sizeof(*fec)); ret = fec_alloc_descs(fec); if (ret) goto err3; edev->priv = fec; edev->init = fec_init; edev->send = fec_send; edev->recv = fec_recv; edev->halt = fec_halt; edev->write_hwaddr = fec_set_hwaddr; fec->eth = (struct ethernet_regs *)base_addr; fec->bd = bd; fec->xcv_type = CONFIG_FEC_XCV_TYPE; /* Reset chip. */ writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_RESET, &fec->eth->ecntrl); start = get_timer(0); while (readl(&fec->eth->ecntrl) & FEC_ECNTRL_RESET) { if (get_timer(start) > (CONFIG_SYS_HZ * 5)) { printf("FEC MXC: Timeout reseting chip\n"); goto err4; } udelay(10); } fec_reg_setup(fec); fec_set_dev_name(edev->name, dev_id); fec->dev_id = (dev_id == -1) ? 0 : dev_id; fec->bus = bus; fec_mii_setspeed(bus->priv); #ifdef CONFIG_PHYLIB fec->phydev = phydev; phy_connect_dev(phydev, edev); /* Configure phy */ phy_config(phydev); #else fec->phy_id = phy_id; #endif eth_register(edev); if (fec_get_hwaddr(edev, dev_id, ethaddr) == 0) { debug("got MAC%d address from fuse: %pM\n", dev_id, ethaddr); memcpy(edev->enetaddr, ethaddr, 6); if (!getenv("ethaddr")) eth_setenv_enetaddr("ethaddr", ethaddr); } return ret; err4: fec_free_descs(fec); err3: free(fec); err2: free(edev); err1: return ret; }
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 macb_phy_init(struct macb_device *macb, const char *name) #endif { #ifdef CONFIG_DM_ETH struct macb_device *macb = dev_get_priv(dev); #endif u32 ncfgr; u16 phy_id, status, adv, lpa; int media, speed, duplex; int i; arch_get_mdio_control(name); /* Auto-detect phy_addr */ if (!macb_phy_find(macb, name)) return 0; /* Check if the PHY is up to snuff... */ phy_id = macb_mdio_read(macb, MII_PHYSID1); if (phy_id == 0xffff) { printf("%s: No PHY present\n", name); return 0; } #ifdef CONFIG_PHYLIB #ifdef CONFIG_DM_ETH macb->phydev = phy_connect(macb->bus, macb->phy_addr, dev, macb->phy_interface); #else /* need to consider other phy interface mode */ macb->phydev = phy_connect(macb->bus, macb->phy_addr, &macb->netdev, PHY_INTERFACE_MODE_RGMII); #endif if (!macb->phydev) { printf("phy_connect failed\n"); return -ENODEV; } phy_config(macb->phydev); #endif status = macb_mdio_read(macb, MII_BMSR); if (!(status & BMSR_LSTATUS)) { /* Try to re-negotiate if we don't have link already. */ macb_phy_reset(macb, name); for (i = 0; i < MACB_AUTONEG_TIMEOUT / 100; i++) { status = macb_mdio_read(macb, MII_BMSR); if (status & BMSR_LSTATUS) break; udelay(100); } } if (!(status & BMSR_LSTATUS)) { printf("%s: link down (status: 0x%04x)\n", name, status); return 0; } /* First check for GMAC and that it is GiB capable */ if (gem_is_gigabit_capable(macb)) { lpa = macb_mdio_read(macb, MII_STAT1000); if (lpa & (LPA_1000FULL | LPA_1000HALF)) { duplex = ((lpa & LPA_1000FULL) ? 1 : 0); printf("%s: link up, 1000Mbps %s-duplex (lpa: 0x%04x)\n", name, duplex ? "full" : "half", lpa); ncfgr = macb_readl(macb, NCFGR); ncfgr &= ~(MACB_BIT(SPD) | MACB_BIT(FD)); ncfgr |= GEM_BIT(GBE); if (duplex) ncfgr |= MACB_BIT(FD); macb_writel(macb, NCFGR, ncfgr); return 1; } } /* fall back for EMAC checking */ adv = macb_mdio_read(macb, MII_ADVERTISE); lpa = macb_mdio_read(macb, MII_LPA); media = mii_nway_result(lpa & adv); speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF) ? 1 : 0); duplex = (media & ADVERTISE_FULL) ? 1 : 0; printf("%s: link up, %sMbps %s-duplex (lpa: 0x%04x)\n", name, speed ? "100" : "10", duplex ? "full" : "half", lpa); ncfgr = macb_readl(macb, NCFGR); ncfgr &= ~(MACB_BIT(SPD) | MACB_BIT(FD) | GEM_BIT(GBE)); if (speed) ncfgr |= MACB_BIT(SPD); if (duplex) ncfgr |= MACB_BIT(FD); macb_writel(macb, NCFGR, ncfgr); return 1; }
/* 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 macb_phy_init(struct macb_device *macb) { struct eth_device *netdev = &macb->netdev; #ifdef CONFIG_PHYLIB struct phy_device *phydev; #endif u32 ncfgr; u16 phy_id, status, adv, lpa; int media, speed, duplex; int i; arch_get_mdio_control(netdev->name); #ifdef CONFIG_MACB_SEARCH_PHY /* Auto-detect phy_addr */ if (!macb_phy_find(macb)) { return 0; } #endif /* CONFIG_MACB_SEARCH_PHY */ /* Check if the PHY is up to snuff... */ phy_id = macb_mdio_read(macb, MII_PHYSID1); if (phy_id == 0xffff) { printf("%s: No PHY present\n", netdev->name); return 0; } #ifdef CONFIG_PHYLIB phydev->bus = macb->bus; phydev->dev = netdev; phydev->addr = macb->phy_addr; phy_config(phydev); #endif status = macb_mdio_read(macb, MII_BMSR); if (!(status & BMSR_LSTATUS)) { /* Try to re-negotiate if we don't have link already. */ macb_phy_reset(macb); for (i = 0; i < CONFIG_SYS_MACB_AUTONEG_TIMEOUT / 100; i++) { status = macb_mdio_read(macb, MII_BMSR); if (status & BMSR_LSTATUS) break; udelay(100); } } if (!(status & BMSR_LSTATUS)) { printf("%s: link down (status: 0x%04x)\n", netdev->name, status); return 0; } /* First check for GMAC */ if (macb_is_gem(macb)) { lpa = macb_mdio_read(macb, MII_STAT1000); if (lpa & (1 << 11)) { speed = 1000; duplex = 1; } else { if (lpa & (1 << 10)) { speed = 1000; duplex = 1; } else { speed = 0; } } if (speed == 1000) { printf("%s: link up, %dMbps %s-duplex (lpa: 0x%04x)\n", netdev->name, speed, duplex ? "full" : "half", lpa); ncfgr = macb_readl(macb, NCFGR); ncfgr &= ~(GEM_BIT(GBE) | MACB_BIT(SPD) | MACB_BIT(FD)); if (speed) ncfgr |= GEM_BIT(GBE); if (duplex) ncfgr |= MACB_BIT(FD); macb_writel(macb, NCFGR, ncfgr); return 1; } } /* fall back for EMAC checking */ adv = macb_mdio_read(macb, MII_ADVERTISE); lpa = macb_mdio_read(macb, MII_LPA); media = mii_nway_result(lpa & adv); speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF) ? 1 : 0); duplex = (media & ADVERTISE_FULL) ? 1 : 0; printf("%s: link up, %sMbps %s-duplex (lpa: 0x%04x)\n", netdev->name, speed ? "100" : "10", duplex ? "full" : "half", lpa); ncfgr = macb_readl(macb, NCFGR); ncfgr &= ~(MACB_BIT(SPD) | MACB_BIT(FD)); if (speed) ncfgr |= MACB_BIT(SPD); if (duplex) ncfgr |= MACB_BIT(FD); macb_writel(macb, NCFGR, ncfgr); return 1; }
static int ks2_eth_probe(struct udevice *dev) { struct ks2_eth_priv *priv = dev_get_priv(dev); struct mii_dev *mdio_bus; int ret; priv->dev = dev; /* These clock enables has to be moved to common location */ if (cpu_is_k2g()) writel(KS2_ETHERNET_RGMII, KS2_ETHERNET_CFG); /* By default, select PA PLL clock as PA clock source */ #ifndef CONFIG_SOC_K2G if (psc_enable_module(KS2_LPSC_PA)) return -EACCES; #endif if (psc_enable_module(KS2_LPSC_CPGMAC)) return -EACCES; if (psc_enable_module(KS2_LPSC_CRYPTO)) return -EACCES; if (cpu_is_k2e() || cpu_is_k2l()) pll_pa_clk_sel(); priv->net_rx_buffs.buff_ptr = rx_buffs; priv->net_rx_buffs.num_buffs = RX_BUFF_NUMS; priv->net_rx_buffs.buff_len = RX_BUFF_LEN; if (priv->slave_port == 1) { /* * Register MDIO bus for slave 0 only, other slave have * to re-use the same */ mdio_bus = mdio_alloc(); if (!mdio_bus) { error("MDIO alloc failed\n"); return -ENOMEM; } priv->mdio_bus = mdio_bus; mdio_bus->read = keystone2_mdio_read; mdio_bus->write = keystone2_mdio_write; mdio_bus->reset = keystone2_mdio_reset; mdio_bus->priv = priv->mdio_base; sprintf(mdio_bus->name, "ethernet-mdio"); ret = mdio_register(mdio_bus); if (ret) { error("MDIO bus register failed\n"); return ret; } } else { /* Get the MDIO bus from slave 0 device */ struct ks2_eth_priv *parent_priv; parent_priv = dev_get_priv(dev->parent); priv->mdio_bus = parent_priv->mdio_bus; } #ifndef CONFIG_SOC_K2G keystone2_net_serdes_setup(); #endif priv->netcp_pktdma = &netcp_pktdma; if (priv->has_mdio) { priv->phydev = phy_connect(priv->mdio_bus, priv->phy_addr, dev, priv->phy_if); phy_config(priv->phydev); } return 0; }
void ls2080a_handle_phy_interface_sgmii(int dpmac_id) { int lane, slot; struct mii_dev *bus; struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) & FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK) >> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT; int serdes2_prtcl = (in_le32(&gur->rcwsr[28]) & FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK) >> FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT; int *riser_phy_addr; char *env_hwconfig = getenv("hwconfig"); if (hwconfig_f("xqsgmii", env_hwconfig)) riser_phy_addr = &xqsgii_riser_phy_addr[0]; else riser_phy_addr = &sgmii_riser_phy_addr[0]; if (dpmac_id > WRIOP1_DPMAC9) goto serdes2; switch (serdes1_prtcl) { case 0x07: lane = serdes_get_first_lane(FSL_SRDS_1, SGMII1 + dpmac_id); slot = lane_to_slot_fsm1[lane]; switch (++slot) { case 1: /* Slot housing a SGMII riser card? */ wriop_set_phy_address(dpmac_id, riser_phy_addr[dpmac_id - 1]); dpmac_info[dpmac_id].board_mux = EMI1_SLOT1; bus = mii_dev_for_muxval(EMI1_SLOT1); wriop_set_mdio(dpmac_id, bus); dpmac_info[dpmac_id].phydev = phy_connect( dpmac_info[dpmac_id].bus, dpmac_info[dpmac_id].phy_addr, NULL, dpmac_info[dpmac_id].enet_if); phy_config(dpmac_info[dpmac_id].phydev); break; case 2: /* Slot housing a SGMII riser card? */ wriop_set_phy_address(dpmac_id, riser_phy_addr[dpmac_id - 1]); dpmac_info[dpmac_id].board_mux = EMI1_SLOT2; bus = mii_dev_for_muxval(EMI1_SLOT2); wriop_set_mdio(dpmac_id, bus); dpmac_info[dpmac_id].phydev = phy_connect( dpmac_info[dpmac_id].bus, dpmac_info[dpmac_id].phy_addr, NULL, dpmac_info[dpmac_id].enet_if); phy_config(dpmac_info[dpmac_id].phydev); break; case 3: break; case 4: break; case 5: break; case 6: break; } break; default: printf("%s qds: WRIOP: Unsupported SerDes1 Protocol 0x%02x\n", __func__ , serdes1_prtcl); break; } serdes2: switch (serdes2_prtcl) { case 0x07: case 0x08: case 0x49: lane = serdes_get_first_lane(FSL_SRDS_2, SGMII9 + (dpmac_id - 9)); slot = lane_to_slot_fsm2[lane]; switch (++slot) { case 1: break; case 3: break; case 4: /* Slot housing a SGMII riser card? */ wriop_set_phy_address(dpmac_id, riser_phy_addr[dpmac_id - 9]); dpmac_info[dpmac_id].board_mux = EMI1_SLOT4; bus = mii_dev_for_muxval(EMI1_SLOT4); wriop_set_mdio(dpmac_id, bus); dpmac_info[dpmac_id].phydev = phy_connect( dpmac_info[dpmac_id].bus, dpmac_info[dpmac_id].phy_addr, NULL, dpmac_info[dpmac_id].enet_if); phy_config(dpmac_info[dpmac_id].phydev); break; case 5: break; case 6: /* Slot housing a SGMII riser card? */ wriop_set_phy_address(dpmac_id, riser_phy_addr[dpmac_id - 13]); dpmac_info[dpmac_id].board_mux = EMI1_SLOT6; bus = mii_dev_for_muxval(EMI1_SLOT6); wriop_set_mdio(dpmac_id, bus); break; } break; default: printf("%s qds: WRIOP: Unsupported SerDes2 Protocol 0x%02x\n", __func__, serdes2_prtcl); break; } }
void ls2080a_handle_phy_interface_qsgmii(int dpmac_id) { int lane = 0, slot; struct mii_dev *bus; struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) & FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK) >> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT; switch (serdes1_prtcl) { case 0x33: switch (dpmac_id) { case 1: case 2: case 3: case 4: lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_A); break; case 5: case 6: case 7: case 8: lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_B); break; case 9: case 10: case 11: case 12: lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_C); break; case 13: case 14: case 15: case 16: lane = serdes_get_first_lane(FSL_SRDS_1, QSGMII_D); break; } slot = lane_to_slot_fsm1[lane]; switch (++slot) { case 1: /* Slot housing a QSGMII riser card? */ wriop_set_phy_address(dpmac_id, dpmac_id - 1); dpmac_info[dpmac_id].board_mux = EMI1_SLOT1; bus = mii_dev_for_muxval(EMI1_SLOT1); wriop_set_mdio(dpmac_id, bus); dpmac_info[dpmac_id].phydev = phy_connect( dpmac_info[dpmac_id].bus, dpmac_info[dpmac_id].phy_addr, NULL, dpmac_info[dpmac_id].enet_if); phy_config(dpmac_info[dpmac_id].phydev); break; case 3: break; case 4: break; case 5: break; case 6: break; } break; default: printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n", serdes1_prtcl); break; } qsgmii_configure_repeater(dpmac_id); }
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; }