Ejemplo n.º 1
0
/* Eth device open */
static int davinci_eth_open(struct eth_device *dev, bd_t *bis)
{
	dv_reg_p		addr;
	u_int32_t		clkdiv, cnt;
	volatile emac_desc	*rx_desc;
	u_int16_t		lpa_val;

	debug_emac("+ emac_open\n");

	/* Reset EMAC module and disable interrupts in wrapper */
	adap_emac->SOFTRESET = 1;
	while (adap_emac->SOFTRESET != 0) {;}

#if (defined(CONFIG_SOC_DM646x) || defined(CONFIG_SOC_DM365) || \
     defined(CONFIG_OMAP3_AM3517EVM) || defined(CONFIG_OMAP3_AM3517CRANE))

	adap_ewrap->SOFTRST = 1;
	while (adap_ewrap->SOFTRST != 0) {;}
#else
	adap_ewrap->EWCTL = 0;
	for (cnt = 0; cnt < 5; cnt++) {
		clkdiv = adap_ewrap->EWCTL;
	}
#endif

	rx_desc = emac_rx_desc;

	adap_emac->TXCONTROL = 0x01;
	adap_emac->RXCONTROL = 0x01;

	/* Set MAC Addresses & Init multicast Hash to 0 (disable any multicast receive) */
	/* Using channel 0 only - other channels are disabled */
	adap_emac->MACINDEX = 0;
	adap_emac->MACADDRHI =
		(davinci_eth_mac_addr[3] << 24) |
		(davinci_eth_mac_addr[2] << 16) |
		(davinci_eth_mac_addr[1] << 8)  |
		(davinci_eth_mac_addr[0]);
#if (defined(CONFIG_SOC_DM646x) || defined(CONFIG_SOC_DM365) || \
     defined(CONFIG_OMAP3_AM3517EVM) || defined(CONFIG_OMAP3_AM3517CRANE))
	adap_emac->MACADDRLO =
		(davinci_eth_mac_addr[5] << 8) |
		(davinci_eth_mac_addr[4]| (1 << 19) | (1 << 20));
#else
	adap_emac->MACADDRLO =
		(davinci_eth_mac_addr[5] << 8) |
		(davinci_eth_mac_addr[4]);
#endif

	adap_emac->MACHASH1 = 0;
	adap_emac->MACHASH2 = 0;

	/* Set source MAC address - REQUIRED */
	adap_emac->MACSRCADDRHI =
		(davinci_eth_mac_addr[3] << 24) |
		(davinci_eth_mac_addr[2] << 16) |
		(davinci_eth_mac_addr[1] << 8)  |
		(davinci_eth_mac_addr[0]);
	adap_emac->MACSRCADDRLO =
		(davinci_eth_mac_addr[4] << 8) |
		(davinci_eth_mac_addr[5]);

	/* Set DMA 8 TX / 8 RX Head pointers to 0 */
	addr = &adap_emac->TX0HDP;
	for(cnt = 0; cnt < 16; cnt++)
		*addr++ = 0;
	addr = &adap_emac->RX0HDP;
	for(cnt = 0; cnt < 16; cnt++)
		*addr++ = 0;

	/* Clear Statistics (do this before setting MacControl register) */
	addr = &adap_emac->RXGOODFRAMES;
	for(cnt = 0; cnt < EMAC_NUM_STATS; cnt++)
		*addr++ = 0;

	/* No multicast addressing */
	adap_emac->MACHASH1 = 0;
	adap_emac->MACHASH2 = 0;

	/* Create RX queue and set receive process in place */
	emac_rx_active_head = emac_rx_desc;
	for (cnt = 0; cnt < EMAC_MAX_RX_BUFFERS; cnt++) {
		rx_desc->next = BD_TO_HW((u_int32_t)(rx_desc + 1));
		rx_desc->buffer = &emac_rx_buffers[cnt * (EMAC_MAX_ETHERNET_PKT_SIZE + EMAC_PKT_ALIGN)];
		rx_desc->buff_off_len = EMAC_MAX_ETHERNET_PKT_SIZE;
		rx_desc->pkt_flag_len = EMAC_CPPI_OWNERSHIP_BIT;
		rx_desc++;
	}

	/* Set the last descriptor's "next" parameter to 0 to end the RX desc list */
	rx_desc--;
	rx_desc->next = 0;
	emac_rx_active_tail = rx_desc;
	emac_rx_queue_active = 1;

	/* Enable TX/RX */
	adap_emac->RXMAXLEN = EMAC_MAX_ETHERNET_PKT_SIZE;
	adap_emac->RXBUFFEROFFSET = 0;

	/* No fancy configs - Use this for promiscous for debug - EMAC_RXMBPENABLE_RXCAFEN_ENABLE */
	adap_emac->RXMBPENABLE = EMAC_RXMBPENABLE_RXBROADEN;

	/* Enable ch 0 only */
	adap_emac->RXUNICASTSET = 0x01;

	/* Init MDIO & get link state */
	clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
	adap_mdio->CONTROL = ((clkdiv & 0xff) | MDIO_CONTROL_ENABLE | MDIO_CONTROL_FAULT);

	if (!phy.auto_negotiate(active_phy_addr))
		return(0);

	davinci_eth_phy_read(active_phy_addr,PHY_ANLPAR,&lpa_val);
	if (lpa_val & (PHY_ANLPAR_10FD | PHY_ANLPAR_TXFD) ) {
		/* set EMAC for Full Duplex  */
		adap_emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE |
					 EMAC_MACCONTROL_FULLDUPLEX_ENABLE;
	}else{
		/*set EMAC for Half Duplex  */
		adap_emac->MACCONTROL = EMAC_MACCONTROL_MIIEN_ENABLE;
	}

#ifdef CONFIG_DRIVER_TI_EMAC_USE_RMII
	if (lpa_val & (PHY_ANLPAR_TXFD | PHY_ANLPAR_TX) ) {
		adap_emac->MACCONTROL |= EMAC_MACCONTROL_RMIISPEED_100;
	} else {
		adap_emac->MACCONTROL &= ~EMAC_MACCONTROL_RMIISPEED_100;
	}
#endif

	/* Start receive process */
	adap_emac->RX0HDP = BD_TO_HW((u_int32_t)emac_rx_desc);

	debug_emac("- emac_open\n");

	return(1);
}