Example #1
0
/*
 * This function sends a single packet on the network and returns
 * positive number (number of bytes transmitted) or negative for error
 */
static int davinci_eth_send_packet (struct eth_device *dev,
					volatile void *packet, int length)
{
	int ret_status = -1;

	tx_send_loop = 0;

	/* Return error if no link */
	if (!phy.get_link_speed (active_phy_addr)) {
		printf ("WARN: emac_send_packet: No link\n");
		return (ret_status);
	}

	emac_gigabit_enable();

	/* Check packet size and if < EMAC_MIN_ETHERNET_PKT_SIZE, pad it up */
	if (length < EMAC_MIN_ETHERNET_PKT_SIZE) {
		length = EMAC_MIN_ETHERNET_PKT_SIZE;
	}

	/* Populate the TX descriptor */
	emac_tx_desc->next = 0;
	emac_tx_desc->buffer = (u_int8_t *) packet;
	emac_tx_desc->buff_off_len = (length & 0xffff);
	emac_tx_desc->pkt_flag_len = ((length & 0xffff) |
				      EMAC_CPPI_SOP_BIT |
				      EMAC_CPPI_OWNERSHIP_BIT |
				      EMAC_CPPI_EOP_BIT);
	/* Send the packet */
	writel((unsigned long)emac_tx_desc, &adap_emac->TX0HDP);

	/* Wait for packet to complete or link down */
	while (1) {
		if (!phy.get_link_speed (active_phy_addr)) {
			davinci_eth_ch_teardown (EMAC_CH_TX);
			return (ret_status);
		}

		emac_gigabit_enable();

		if (readl(&adap_emac->TXINTSTATRAW) & 0x01) {
			ret_status = length;
			break;
		}
		tx_send_loop++;
	}

	return (ret_status);
}
/* 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);
}
Example #3
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;

	debug_emac("+ emac_open\n");

	/* Reset EMAC module and disable interrupts in wrapper */
	writel(1, &adap_emac->SOFTRESET);
	while (readl(&adap_emac->SOFTRESET) != 0)
		;
#if defined(DAVINCI_EMAC_VERSION2)
	writel(1, &adap_ewrap->softrst);
	while (readl(&adap_ewrap->softrst) != 0)
		;
#else
	writel(0, &adap_ewrap->EWCTL);
	for (cnt = 0; cnt < 5; cnt++) {
		clkdiv = readl(&adap_ewrap->EWCTL);
	}
#endif

#if defined(CONFIG_DRIVER_TI_EMAC_USE_RMII) && \
	defined(CONFIG_MACH_DAVINCI_DA850_EVM)
	adap_ewrap->c0rxen = adap_ewrap->c1rxen = adap_ewrap->c2rxen = 0;
	adap_ewrap->c0txen = adap_ewrap->c1txen = adap_ewrap->c2txen = 0;
	adap_ewrap->c0miscen = adap_ewrap->c1miscen = adap_ewrap->c2miscen = 0;
#endif
	rx_desc = emac_rx_desc;

	writel(1, &adap_emac->TXCONTROL);
	writel(1, &adap_emac->RXCONTROL);

	davinci_eth_set_mac_addr(dev);

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

	addr = &adap_emac->RX0HDP;
	for(cnt = 0; cnt < 16; cnt++)
		writel(0, addr++);

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

	/* No multicast addressing */
	writel(0, &adap_emac->MACHASH1);
	writel(0, &adap_emac->MACHASH2);

	/* 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 = (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++;
	}

	/* Finalize the rx desc list */
	rx_desc--;
	rx_desc->next = 0;
	emac_rx_active_tail = rx_desc;
	emac_rx_queue_active = 1;

	/* Enable TX/RX */
	writel(EMAC_MAX_ETHERNET_PKT_SIZE, &adap_emac->RXMAXLEN);
	writel(0, &adap_emac->RXBUFFEROFFSET);

	/*
	 * No fancy configs - Use this for promiscous debug
	 *   - EMAC_RXMBPENABLE_RXCAFEN_ENABLE
	 */
	writel(EMAC_RXMBPENABLE_RXBROADEN, &adap_emac->RXMBPENABLE);

	/* Enable ch 0 only */
	writel(1, &adap_emac->RXUNICASTSET);

	/* Enable MII interface and Full duplex mode */
#ifdef CONFIG_SOC_DA8XX
	writel((EMAC_MACCONTROL_MIIEN_ENABLE |
		EMAC_MACCONTROL_FULLDUPLEX_ENABLE |
		EMAC_MACCONTROL_RMIISPEED_100),
	       &adap_emac->MACCONTROL);
#else
	writel((EMAC_MACCONTROL_MIIEN_ENABLE |
		EMAC_MACCONTROL_FULLDUPLEX_ENABLE),
	       &adap_emac->MACCONTROL);
#endif

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

	/* We need to wait for MDIO to start */
	udelay(1000);

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

	emac_gigabit_enable();

	/* Start receive process */
	writel((u_int32_t)emac_rx_desc, &adap_emac->RX0HDP);

	debug_emac("- emac_open\n");

	return(1);
}
Example #4
0
/* Eth device open */
static int dm644x_eth_open(void)
{
	dv_reg_p		addr;
	u_int32_t		clkdiv, cnt;
	volatile emac_desc	*rx_desc;

	debug_emac("+ emac_open\n");

	/* Reset EMAC module and disable interrupts in wrapper */
	adap_emac->SOFTRESET = 1;
	while (adap_emac->SOFTRESET != 0) {;}
	adap_ewrap->EWCTL = 0;
	for (cnt = 0; cnt < 5; cnt++) {
		clkdiv = adap_ewrap->EWCTL;
	}

	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 =
		(dm644x_eth_mac_addr[3] << 24) |
		(dm644x_eth_mac_addr[2] << 16) |
		(dm644x_eth_mac_addr[1] << 8)  |
		(dm644x_eth_mac_addr[0]);
	adap_emac->MACADDRLO =
		(dm644x_eth_mac_addr[5] << 8) |
		(dm644x_eth_mac_addr[4]);

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

	/* Set source MAC address - REQUIRED */
	adap_emac->MACSRCADDRHI =
		(dm644x_eth_mac_addr[3] << 24) |
		(dm644x_eth_mac_addr[2] << 16) |
		(dm644x_eth_mac_addr[1] << 8)  |
		(dm644x_eth_mac_addr[0]);
	adap_emac->MACSRCADDRLO =
		(dm644x_eth_mac_addr[4] << 8) |
		(dm644x_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 = (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;

	/* Enable MII interface and Full duplex mode */
	adap_emac->MACCONTROL = (EMAC_MACCONTROL_MIIEN_ENABLE | EMAC_MACCONTROL_FULLDUPLEX_ENABLE);

	/* 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.get_link_speed(active_phy_addr))
		return(0);

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

	debug_emac("- emac_open\n");

	return(1);
}