struct mii_dev *fec_get_miibus(uint32_t base_addr, int dev_id) { struct ethernet_regs *eth = (struct ethernet_regs *)base_addr; struct mii_dev *bus; int ret; bus = mdio_alloc(); if (!bus) { printf("mdio_alloc failed\n"); return NULL; } bus->read = fec_phy_read; bus->write = fec_phy_write; bus->priv = eth; fec_set_dev_name(bus->name, dev_id); ret = mdio_register(bus); if (ret) { printf("mdio_register failed\n"); free(bus); return NULL; } fec_mii_setspeed(eth); return bus; }
static int fec_init(struct eth_device *dev, bd_t *bd) #endif { #ifdef CONFIG_DM_ETH struct fec_priv *fec = dev_get_priv(dev); #else struct fec_priv *fec = (struct fec_priv *)dev->priv; #endif uint32_t mib_ptr = (uint32_t)&fec->eth->rmon_t_drop; int i; /* Initialize MAC address */ #ifdef CONFIG_DM_ETH fecmxc_set_hwaddr(dev); #else fec_set_hwaddr(dev); #endif /* Setup transmit descriptors, there are two in total. */ fec_tbd_init(fec); /* Setup receive descriptors. */ fec_rbd_init(fec, FEC_RBD_NUM, FEC_MAX_PKT_SIZE); fec_reg_setup(fec); if (fec->xcv_type != SEVENWIRE) fec_mii_setspeed(fec->bus->priv); /* Set Opcode/Pause Duration Register */ writel(0x00010020, &fec->eth->op_pause); /* FIXME 0xffff0020; */ writel(0x2, &fec->eth->x_wmrk); /* Set multicast address filter */ writel(0x00000000, &fec->eth->gaddr1); writel(0x00000000, &fec->eth->gaddr2); /* Do not access reserved register for i.MX6UL */ if (!is_mx6ul()) { /* clear MIB RAM */ for (i = mib_ptr; i <= mib_ptr + 0xfc; i += 4) writel(0, i); /* FIFO receive start register */ writel(0x520, &fec->eth->r_fstart); } /* size and address of each buffer */ writel(FEC_MAX_PKT_SIZE, &fec->eth->emrbr); writel((uint32_t)fec->tbd_base, &fec->eth->etdsr); writel((uint32_t)fec->rbd_base, &fec->eth->erdsr); #ifndef CONFIG_PHYLIB if (fec->xcv_type != SEVENWIRE) miiphy_restart_aneg(dev); #endif fec_open(dev); return 0; }
static int fec_probe(bd_t *bd, int dev_id, int phy_id, uint32_t base_addr) { 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)); 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 err3; } udelay(10); } /* * Set interrupt mask register */ writel(0x00000000, &fec->eth->imask); /* * Clear FEC-Lite interrupt event register(IEVENT) */ writel(0xffffffff, &fec->eth->ievent); /* * Set FEC-Lite receive control register(R_CNTRL): */ /* * Frame length=1518; MII mode; */ writel((PKTSIZE << FEC_RCNTRL_MAX_FL_SHIFT) | FEC_RCNTRL_FCE | FEC_RCNTRL_MII_MODE, &fec->eth->r_cntrl); fec_mii_setspeed(fec); if (dev_id == -1) { sprintf(edev->name, "FEC"); fec->dev_id = 0; } else { sprintf(edev->name, "FEC%i", dev_id); fec->dev_id = dev_id; } fec->phy_id = phy_id; miiphy_register(edev->name, fec_miiphy_read, fec_miiphy_write); 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); } return ret; err3: free(fec); err2: free(edev); err1: return ret; }
static int fec_init(struct eth_device *dev, bd_t* bd) { uint32_t base; struct fec_priv *fec = (struct fec_priv *)dev->priv; uint32_t mib_ptr = (uint32_t)&fec->eth->rmon_t_drop; uint32_t rcntrl; int i; /* Initialize MAC address */ fec_set_hwaddr(dev); /* * reserve memory for both buffer descriptor chains at once * Datasheet forces the startaddress of each chain is 16 byte * aligned */ if (fec->base_ptr == NULL) fec->base_ptr = malloc((2 + FEC_RBD_NUM) * sizeof(struct fec_bd) + DB_ALIGNMENT); base = (uint32_t)fec->base_ptr; if (!base) { puts("fec_mxc: not enough malloc memory\n"); return -ENOMEM; } memset((void *)base, 0, (2 + FEC_RBD_NUM) * sizeof(struct fec_bd) + DB_ALIGNMENT); base += (DB_ALIGNMENT-1); base &= ~(DB_ALIGNMENT-1); fec->rbd_base = (struct fec_bd *)base; base += FEC_RBD_NUM * sizeof(struct fec_bd); fec->tbd_base = (struct fec_bd *)base; /* * Set interrupt mask register */ writel(0x00000000, &fec->eth->imask); /* * Clear FEC-Lite interrupt event register(IEVENT) */ writel(0xffffffff, &fec->eth->ievent); /* * Set FEC-Lite receive control register(R_CNTRL): */ /* Start with frame length = 1518, common for all modes. */ rcntrl = PKTSIZE << FEC_RCNTRL_MAX_FL_SHIFT; if (fec->xcv_type == SEVENWIRE) rcntrl |= FEC_RCNTRL_FCE; else if (fec->xcv_type == RGMII) rcntrl |= FEC_RCNTRL_RGMII; else if (fec->xcv_type == RMII) rcntrl |= FEC_RCNTRL_RMII; else /* MII mode */ rcntrl |= FEC_RCNTRL_FCE | FEC_RCNTRL_MII_MODE; writel(rcntrl, &fec->eth->r_cntrl); if (fec->xcv_type == MII10 || fec->xcv_type == MII100) fec_mii_setspeed(fec); /* * Set Opcode/Pause Duration Register */ writel(0x00010020, &fec->eth->op_pause); /* FIXME 0xffff0020; */ writel(0x2, &fec->eth->x_wmrk); /* * Set multicast address filter */ writel(0x00000000, &fec->eth->gaddr1); writel(0x00000000, &fec->eth->gaddr2); /* clear MIB RAM */ for (i = mib_ptr; i <= mib_ptr + 0xfc; i += 4) writel(0, i); /* FIFO receive start register */ writel(0x520, &fec->eth->r_fstart); /* size and address of each buffer */ writel(FEC_MAX_PKT_SIZE, &fec->eth->emrbr); writel((uint32_t)fec->tbd_base, &fec->eth->etdsr); writel((uint32_t)fec->rbd_base, &fec->eth->erdsr); /* * Initialize RxBD/TxBD rings */ if (fec_rbd_init(fec, FEC_RBD_NUM, FEC_MAX_PKT_SIZE) < 0) { free(fec->base_ptr); fec->base_ptr = NULL; return -ENOMEM; } fec_tbd_init(fec); if (fec->xcv_type != SEVENWIRE) miiphy_restart_aneg(dev); fec_open(dev); 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 fec_init(struct eth_device *dev, bd_t* bd) { struct fec_priv *fec = (struct fec_priv *)dev->priv; uint32_t mib_ptr = (uint32_t)&fec->eth->rmon_t_drop; uint32_t size; int i, ret; /* Initialize MAC address */ fec_set_hwaddr(dev); /* * Allocate transmit descriptors, there are two in total. This * allocation respects cache alignment. */ if (!fec->tbd_base) { size = roundup(2 * sizeof(struct fec_bd), ARCH_DMA_MINALIGN); fec->tbd_base = memalign(ARCH_DMA_MINALIGN, size); if (!fec->tbd_base) { ret = -ENOMEM; goto err1; } memset(fec->tbd_base, 0, size); fec_tbd_init(fec); } /* * Allocate receive descriptors. This allocation respects cache * alignment. */ if (!fec->rbd_base) { size = roundup(FEC_RBD_NUM * sizeof(struct fec_bd), ARCH_DMA_MINALIGN); fec->rbd_base = memalign(ARCH_DMA_MINALIGN, size); if (!fec->rbd_base) { ret = -ENOMEM; goto err2; } memset(fec->rbd_base, 0, size); /* * Initialize RxBD ring */ if (fec_rbd_init(fec, FEC_RBD_NUM, FEC_MAX_PKT_SIZE) < 0) { ret = -ENOMEM; goto err3; } flush_dcache_range((unsigned)fec->rbd_base, (unsigned)fec->rbd_base + size); } fec_reg_setup(fec); if (fec->xcv_type != SEVENWIRE) fec_mii_setspeed(fec->bus->priv); /* * Set Opcode/Pause Duration Register */ writel(0x00010020, &fec->eth->op_pause); /* FIXME 0xffff0020; */ writel(0x2, &fec->eth->x_wmrk); /* * Set multicast address filter */ writel(0x00000000, &fec->eth->gaddr1); writel(0x00000000, &fec->eth->gaddr2); /* clear MIB RAM */ for (i = mib_ptr; i <= mib_ptr + 0xfc; i += 4) writel(0, i); /* FIFO receive start register */ writel(0x520, &fec->eth->r_fstart); /* size and address of each buffer */ writel(FEC_MAX_PKT_SIZE, &fec->eth->emrbr); writel((uint32_t)fec->tbd_base, &fec->eth->etdsr); writel((uint32_t)fec->rbd_base, &fec->eth->erdsr); #ifndef CONFIG_PHYLIB if (fec->xcv_type != SEVENWIRE) miiphy_restart_aneg(dev); #endif fec_open(dev); return 0; err3: free(fec->rbd_base); err2: free(fec->tbd_base); err1: return ret; }