X-Git-Url: https://git.kernelconcepts.de/?p=karo-tx-uboot.git;a=blobdiff_plain;f=drivers%2Fnet%2Ffec_mxc.c;h=19eb25c6173813aa4393db84a2c11ca1bb42df92;hp=7e732d4df487ea39bd984f9908d42504b539e2d1;hb=82f0c70208fb8b36f733e0d615104e94e0f9d801;hpb=3d5920a31bb846249385e1ca5c086662c39bc44e diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c index 7e732d4df4..19eb25c617 100644 --- a/drivers/net/fec_mxc.c +++ b/drivers/net/fec_mxc.c @@ -69,15 +69,6 @@ DECLARE_GLOBAL_DATA_PTR; #undef DEBUG -struct nbuf { - uint8_t data[1500]; /**< actual data */ - int length; /**< actual length */ - int used; /**< buffer in use or not */ - uint8_t head[16]; /**< MAC header(6 + 6 + 2) + 2(aligned) */ -}; - -static int rx_idx; - #ifdef CONFIG_FEC_MXC_SWAP_PACKET static void swap_packet(uint32_t *packet, int length) { @@ -119,7 +110,7 @@ static int fec_mdio_read(struct ethernet_regs *eth, uint8_t phyAddr, if (readl(ð->ievent) & FEC_IEVENT_MII) break; printf("Read MDIO failed...\n"); - return -1; + return -ETIMEDOUT; } } @@ -174,7 +165,7 @@ static int fec_mdio_write(struct ethernet_regs *eth, uint8_t phyAddr, if (readl(ð->ievent) & FEC_IEVENT_MII) break; printf("Write MDIO failed...\n"); - return -1; + return -ETIMEDOUT; } } @@ -236,7 +227,7 @@ static int miiphy_restart_aneg(struct eth_device *dev) 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; @@ -248,14 +239,14 @@ static int miiphy_wait_aneg(struct eth_device *dev) 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)); @@ -265,7 +256,7 @@ static int miiphy_wait_aneg(struct eth_device *dev) static inline void fec_rx_task_enable(struct fec_priv *fec) { - writel(1 << 24, &fec->eth->r_des_active); + writel(FEC_X_DES_ACTIVE_TDAR, &fec->eth->r_des_active); } static inline void fec_rx_task_disable(struct fec_priv *fec) @@ -274,7 +265,7 @@ static inline void fec_rx_task_disable(struct fec_priv *fec) static inline void fec_tx_task_enable(struct fec_priv *fec) { - writel(1 << 24, &fec->eth->x_des_active); + writel(FEC_X_DES_ACTIVE_TDAR, &fec->eth->x_des_active); } static inline void fec_tx_task_disable(struct fec_priv *fec) @@ -292,19 +283,20 @@ static inline void fec_tx_task_disable(struct fec_priv *fec) */ 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; @@ -314,8 +306,9 @@ static void fec_rbd_init(struct fec_priv *fec, int count, int dsize) 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); } /** @@ -332,7 +325,7 @@ static void fec_rbd_init(struct fec_priv *fec, int count, int dsize) */ 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); @@ -361,13 +354,13 @@ static int fec_get_hwaddr(struct eth_device *dev, int dev_id, unsigned char *mac) { imx_get_mac_from_fuse(dev_id, mac); - return !is_valid_ether_addr(mac); + return !is_valid_ethaddr(mac); } 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); @@ -540,8 +533,6 @@ static int fec_open(struct eth_device *edev) 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); @@ -570,14 +561,11 @@ static int fec_init(struct eth_device *dev, bd_t* bd) 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); @@ -597,7 +585,7 @@ static int fec_init(struct eth_device *dev, bd_t* bd) */ 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; /* @@ -656,7 +644,7 @@ static int fec_send(struct eth_device *dev, void *packet, int length) */ if ((length > 1500) || (length <= 0)) { printf("Payload (%d) too large\n", length); - return -1; + return -EINVAL; } /* @@ -665,7 +653,7 @@ static int fec_send(struct eth_device *dev, void *packet, int length) * 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; @@ -733,10 +721,11 @@ static int fec_send(struct eth_device *dev, void *packet, int length) 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; } @@ -760,10 +749,11 @@ static int fec_send(struct eth_device *dev, void *packet, int length) 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", @@ -785,14 +775,14 @@ out: */ 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; - struct nbuf *frame; uint16_t bd_status; uint32_t addr, size, end; int i; + ALLOC_CACHE_ALIGN_BUFFER(uchar, buff, FEC_MAX_PKT_SIZE); /* * Check if any critical events have happened @@ -851,13 +841,12 @@ static int fec_recv(struct eth_device *dev) /* * Get buffer address and size */ - frame = (struct nbuf *)readl(&rbd->data_pointer); + addr = readl(&rbd->data_pointer); frame_length = readw(&rbd->data_length) - 4; /* * Invalidate data cache over the buffer */ - addr = (uint32_t)frame; end = roundup(addr + frame_length, ARCH_DMA_MINALIGN); addr &= ~(ARCH_DMA_MINALIGN - 1); invalidate_dcache_range(addr, end); @@ -866,17 +855,15 @@ static int fec_recv(struct eth_device *dev) * Fill the buffer and pass it to upper layers */ #ifdef CONFIG_FEC_MXC_SWAP_PACKET - swap_packet((uint32_t *)frame->data, frame_length); + swap_packet((uint32_t *)addr, frame_length); #endif - memcpy((void *)NetRxPackets[rx_idx], frame->data, frame_length); - NetReceive(NetRxPackets[rx_idx], frame_length); - rx_idx = (rx_idx + 1) % PKTBUFSRX; + memcpy(buff, (char *)addr, frame_length); + net_process_received_packet(buff, frame_length); len = frame_length; } else { if (bd_status & FEC_RBD_ERR) - printf("error frame: 0x%08lx 0x%08x\n", - (ulong)rbd->data_pointer, - bd_status); + printf("error frame: 0x%08x 0x%08x\n", + addr, bd_status); } /* @@ -912,46 +899,47 @@ static void fec_set_dev_name(char *dest, int dev_id) 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; @@ -1104,12 +1092,14 @@ int fecmxc_initialize_multi(bd_t *bd, int dev_id, int phy_id, uint32_t addr) #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 @@ -1118,11 +1108,14 @@ int fecmxc_initialize_multi(bd_t *bd, int dev_id, int phy_id, uint32_t addr) if (!bus) return -ENOMEM; #ifdef CONFIG_PHYLIB - phydev = phy_find_by_mask(bus, 1 << phy_id, PHY_INTERFACE_MODE_RGMII); + 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); @@ -1147,7 +1140,7 @@ int fecmxc_initialize(bd_t *bd) #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; }