Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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;
}