/* Eth device close */ static void davinci_eth_close(struct eth_device *dev) { debug_emac("+ emac_close\n"); davinci_eth_ch_teardown(EMAC_CH_TX); /* TX Channel teardown */ davinci_eth_ch_teardown(EMAC_CH_RX); /* RX Channel teardown */ /* Reset EMAC module and disable interrupts in wrapper */ writel(1, &adap_emac->SOFTRESET); #if defined(DAVINCI_EMAC_VERSION2) writel(1, &adap_ewrap->softrst); #else writel(0, &adap_ewrap->EWCTL); #endif /* #if defined(CONFIG_DRIVER_TI_EMAC_USE_RMII) && \ defined(CONFIG_MACH_DAVINCI_DA850_EVM) */ #if defined(CONFIG_DRIVER_TI_EMAC_USE_RMII) && \ defined(CONFIG_MACH_ATLAS_BOSPHORUSI) 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 debug_emac("- emac_close\n"); }
static void davinci_emac_halt(struct eth_device *edev) { struct davinci_emac_priv *priv = edev->priv; dev_dbg(priv->dev, "+ emac_halt\n"); davinci_eth_ch_teardown(priv, EMAC_CH_TX); /* TX Channel teardown */ davinci_eth_ch_teardown(priv, EMAC_CH_RX); /* RX Channel teardown */ /* Reset EMAC module and disable interrupts in wrapper */ writel(1, priv->adap_emac + EMAC_SOFTRESET); writel(1, priv->adap_ewrap + EMAC_EWRAP_SOFTRESET); writel(0, priv->adap_ewrap + EMAC_EWRAP_C0RXEN); writel(0, priv->adap_ewrap + EMAC_EWRAP_C1RXEN); writel(0, priv->adap_ewrap + EMAC_EWRAP_C2RXEN); writel(0, priv->adap_ewrap + EMAC_EWRAP_C0TXEN); writel(0, priv->adap_ewrap + EMAC_EWRAP_C1TXEN); writel(0, priv->adap_ewrap + EMAC_EWRAP_C2TXEN); writel(0, priv->adap_ewrap + EMAC_EWRAP_C0MISCEN); writel(0, priv->adap_ewrap + EMAC_EWRAP_C1MISCEN); writel(0, priv->adap_ewrap + EMAC_EWRAP_C2MISCEN); dev_dbg(priv->dev, "- emac_halt\n"); }
/* Eth device close */ static void davinci_eth_close(struct eth_device *dev) { debug_emac("+ emac_close\n"); davinci_eth_ch_teardown(EMAC_CH_TX); /* TX Channel teardown */ davinci_eth_ch_teardown(EMAC_CH_RX); /* RX Channel teardown */ /* Reset EMAC module and disable interrupts in wrapper */ adap_emac->SOFTRESET = 1; adap_ewrap->EWCTL = 0; debug_emac("- emac_close\n"); }
/* Eth device close */ static void davinci_eth_close(struct eth_device *dev) { debug_emac("+ emac_close\n"); davinci_eth_ch_teardown(EMAC_CH_TX); /* TX Channel teardown */ davinci_eth_ch_teardown(EMAC_CH_RX); /* RX Channel teardown */ /* Reset EMAC module and disable interrupts in wrapper */ writel(1, &adap_emac->SOFTRESET); #if defined(DAVINCI_EMAC_VERSION2) writel(1, &adap_ewrap->softrst); #else writel(0, &adap_ewrap->EWCTL); #endif debug_emac("- emac_close\n"); }
/* Eth device close */ static void davinci_eth_close(struct eth_device *dev) { debug_emac("+ emac_close\n"); davinci_eth_ch_teardown(EMAC_CH_TX); /* TX Channel teardown */ davinci_eth_ch_teardown(EMAC_CH_RX); /* RX Channel teardown */ /* Reset EMAC module and disable interrupts in wrapper */ adap_emac->SOFTRESET = 1; #if (defined(CONFIG_SOC_DM646x) || defined(CONFIG_SOC_DM365) || \ defined(CONFIG_OMAP3_AM3517EVM) || defined(CONFIG_OMAP3_AM3517CRANE)) adap_ewrap->SOFTRST = 1; #else adap_ewrap->EWCTL = 0; #endif debug_emac("- emac_close\n"); }
/* * 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, void *packet, int length) { int ret_status = -1; int index; tx_send_loop = 0; index = get_active_phy(); if (index == -1) { printf(" WARN: emac_send_packet: No link\n"); return (ret_status); } /* 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); flush_dcache_range((unsigned long)packet, (unsigned long)packet + ALIGN(length, PKTALIGN)); /* Send the packet */ writel(BD_TO_HW((unsigned long)emac_tx_desc), &adap_emac->TX0HDP); /* Wait for packet to complete or link down */ while (1) { if (!phy[index].get_link_speed(active_phy_addr[index])) { davinci_eth_ch_teardown (EMAC_CH_TX); return (ret_status); } if (readl(&adap_emac->TXINTSTATRAW) & 0x01) { ret_status = length; break; } tx_send_loop++; } return (ret_status); }
/* * 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); }