if (readl(ð->ievent) & FEC_IEVENT_MII)
break;
printf("Read MDIO failed...\n");
- return -1;
+ return -ETIMEDOUT;
}
}
if (readl(ð->ievent) & FEC_IEVENT_MII)
break;
printf("Write MDIO failed...\n");
- return -1;
+ return -ETIMEDOUT;
}
}
static int miiphy_wait_aneg(struct eth_device *dev)
{
- uint32_t start;
+ ulong start;
int status;
struct fec_priv *fec = (struct fec_priv *)dev->priv;
struct ethernet_regs *eth = fec->bus->priv;
do {
if (get_timer(start) > (CONFIG_SYS_HZ * 5)) {
printf("%s: Autonegotiation timeout\n", dev->name);
- return -1;
+ return -ETIMEDOUT;
}
status = fec_mdio_read(eth, fec->phy_id, MII_BMSR);
if (status < 0) {
printf("%s: Autonegotiation failed. status: %d\n",
dev->name, status);
- return -1;
+ return status;
}
} while (!(status & BMSR_LSTATUS));
*/
static void fec_rbd_init(struct fec_priv *fec, int count, int dsize)
{
- uint32_t size;
- uint8_t *data;
+ size_t rbd_size, pkt_size;
+ void *data;
int i;
/*
* Reload the RX descriptors with default values and wipe
* the RX buffers.
*/
- size = roundup(dsize, ARCH_DMA_MINALIGN);
+ pkt_size = roundup(dsize, ARCH_DMA_MINALIGN);
for (i = 0; i < count; i++) {
- data = (uint8_t *)fec->rbd_base[i].data_pointer;
+ data = (void *)fec->rbd_base[i].data_pointer;
memset(data, 0, dsize);
- flush_dcache_range((uint32_t)data, (uint32_t)data + size);
+ flush_dcache_range((unsigned long)data,
+ (unsigned long)data + pkt_size);
fec->rbd_base[i].status = FEC_RBD_EMPTY;
fec->rbd_base[i].data_length = 0;
fec->rbd_base[i - 1].status = FEC_RBD_WRAP | FEC_RBD_EMPTY;
fec->rbd_index = 0;
- flush_dcache_range((unsigned)fec->rbd_base,
- (unsigned)fec->rbd_base + size);
+ rbd_size = roundup(sizeof(struct fec_bd) * count, ARCH_DMA_MINALIGN);
+ flush_dcache_range((unsigned long)fec->rbd_base,
+ (unsigned long)fec->rbd_base + rbd_size);
}
/**
*/
static void fec_tbd_init(struct fec_priv *fec)
{
- unsigned addr = (unsigned)fec->tbd_base;
+ unsigned long addr = (unsigned long)fec->tbd_base;
unsigned size = roundup(2 * sizeof(struct fec_bd),
ARCH_DMA_MINALIGN);
static int fec_set_hwaddr(struct eth_device *dev)
{
uchar *mac = dev->enetaddr;
- struct fec_priv *fec = (struct fec_priv *)dev->priv;
+ struct fec_priv *fec = dev->priv;
writel(0, &fec->eth->iaddr1);
writel(0, &fec->eth->iaddr2);
static int fec_init(struct eth_device *dev, bd_t* bd)
{
struct fec_priv *fec = dev->priv;
- uint32_t *mib_ptr = (uint32_t *)&fec->eth->rmon_t_drop;
- int i;
/* Initialize MAC address */
fec_set_hwaddr(dev);
writel(0x00000000, &fec->eth->gaddr1);
writel(0x00000000, &fec->eth->gaddr2);
-
- /* clear MIB RAM */
- for (i = 0; i <= 0xfc >> 2; i++)
- writel(0, &mib_ptr[i]);
-
+ /* Do not access reserved register for i.MX6UL */
+#ifndef CONFIG_SOC_MX6UL
/* FIFO receive start register */
writel(0x520, &fec->eth->r_fstart);
-
+#endif
/* size and address of each buffer */
writel(FEC_MAX_PKT_SIZE, &fec->eth->emrbr);
writel((uint32_t)fec->tbd_base, &fec->eth->etdsr);
*/
static void fec_halt(struct eth_device *dev)
{
- struct fec_priv *fec = (struct fec_priv *)dev->priv;
+ struct fec_priv *fec = dev->priv;
int counter = 1000;
/*
*/
if ((length > 1500) || (length <= 0)) {
printf("Payload (%d) too large\n", length);
- return -1;
+ return -EINVAL;
}
/*
* engine. We also flush the packet to RAM here to avoid cache trouble.
*/
#ifdef CONFIG_FEC_MXC_SWAP_PACKET
- swap_packet((uint32_t *)packet, length);
+ swap_packet(packet, length);
#endif
addr = (uint32_t)packet;
while (--timeout) {
if (!(readl(&fec->eth->x_des_active) & FEC_X_DES_ACTIVE_TDAR))
break;
+ udelay(1);
}
if (!timeout) {
- ret = -EINVAL;
+ ret = -ETIMEDOUT;
goto out;
}
if (!(readw(&fec->tbd_base[fec->tbd_index].status) &
FEC_TBD_READY))
break;
+ udelay(1);
}
if (!timeout)
- ret = -EINVAL;
+ ret = -ETIMEDOUT;
out:
debug("fec_send: status 0x%x index %d ret %i\n",
*/
static int fec_recv(struct eth_device *dev)
{
- struct fec_priv *fec = (struct fec_priv *)dev->priv;
+ struct fec_priv *fec = dev->priv;
struct fec_bd *rbd = &fec->rbd_base[fec->rbd_index];
unsigned long ievent;
int frame_length, len = 0;
static int fec_alloc_descs(struct fec_priv *fec)
{
- unsigned int size;
+ size_t tbd_size, rbd_size, pkt_size;
int i;
- uint8_t *data;
+ void *data;
/* Allocate TX descriptors. */
- size = roundup(2 * sizeof(struct fec_bd), ARCH_DMA_MINALIGN);
- fec->tbd_base = memalign(ARCH_DMA_MINALIGN, size);
+ tbd_size = roundup(2 * sizeof(struct fec_bd), ARCH_DMA_MINALIGN);
+ fec->tbd_base = memalign(ARCH_DMA_MINALIGN, tbd_size);
if (!fec->tbd_base)
goto err_tx;
/* Allocate RX descriptors. */
- size = roundup(FEC_RBD_NUM * sizeof(struct fec_bd), ARCH_DMA_MINALIGN);
- fec->rbd_base = memalign(ARCH_DMA_MINALIGN, size);
+ rbd_size = roundup(FEC_RBD_NUM * sizeof(struct fec_bd), ARCH_DMA_MINALIGN);
+ fec->rbd_base = memalign(ARCH_DMA_MINALIGN, rbd_size);
if (!fec->rbd_base)
goto err_rx;
- memset(fec->rbd_base, 0, size);
+ memset(fec->rbd_base, 0, rbd_size);
/* Allocate RX buffers. */
/* Maximum RX buffer size. */
- size = roundup(FEC_MAX_PKT_SIZE, FEC_DMA_RX_MINALIGN);
+ pkt_size = roundup(FEC_MAX_PKT_SIZE, FEC_DMA_RX_MINALIGN);
for (i = 0; i < FEC_RBD_NUM; i++) {
- data = memalign(FEC_DMA_RX_MINALIGN, size);
+ data = memalign(FEC_DMA_RX_MINALIGN, pkt_size);
if (!data) {
printf("%s: error allocating rxbuf %d\n", __func__, i);
goto err_ring;
}
- memset(data, 0, size);
+ memset(data, 0, pkt_size);
fec->rbd_base[i].data_pointer = (uint32_t)data;
fec->rbd_base[i].status = FEC_RBD_EMPTY;
fec->rbd_base[i].data_length = 0;
/* Flush the buffer to memory. */
- flush_dcache_range((uint32_t)data, (uint32_t)data + size);
+ flush_dcache_range((uint32_t)data, (uint32_t)data + pkt_size);
}
/* Mark the last RBD to close the ring. */
fec->rbd_base[i - 1].status = FEC_RBD_WRAP | FEC_RBD_EMPTY;
+ flush_dcache_range((unsigned long)fec->rbd_base, rbd_size);
fec->rbd_index = 0;
fec->tbd_index = 0;
#endif
int ret;
-#ifdef CONFIG_SOC_MX28
+#if defined(CONFIG_SOC_MX28)
/*
* The i.MX28 has two ethernet interfaces, but they are not equal.
* Only the first one can access the MDIO bus.
*/
base_mii = MXS_ENET0_BASE;
+#elif defined(FEC_MDIO_BASE_ADDR)
+ base_mii = FEC_MDIO_BASE_ADDR;
#else
base_mii = addr;
#endif
if (!bus)
return -ENOMEM;
#ifdef CONFIG_PHYLIB
- phydev = phy_find_by_mask(bus, phy_id < 0 ? 0xff : (1 << phy_id),
+ static u8 phy_mask = 0xff;
+ phydev = phy_find_by_mask(bus, phy_id < 0 ? phy_mask : (1 << phy_id),
PHY_INTERFACE_MODE_RGMII);
if (!phydev) {
free(bus);
return -ENOMEM;
}
+ phy_mask &= ~(1 << phydev->addr);
ret = fec_probe(bd, dev_id, addr, bus, phydev);
#else
ret = fec_probe(bd, dev_id, addr, bus, phy_id);
#ifndef CONFIG_PHYLIB
int fecmxc_register_mii_postcall(struct eth_device *dev, int (*cb)(int))
{
- struct fec_priv *fec = (struct fec_priv *)dev->priv;
+ struct fec_priv *fec = dev->priv;
fec->mii_postcall = cb;
return 0;
}