summaryrefslogtreecommitdiff
path: root/bsp/dm365/drivers/davinci_emac.c
diff options
context:
space:
mode:
Diffstat (limited to 'bsp/dm365/drivers/davinci_emac.c')
-rw-r--r--bsp/dm365/drivers/davinci_emac.c2142
1 files changed, 1071 insertions, 1071 deletions
diff --git a/bsp/dm365/drivers/davinci_emac.c b/bsp/dm365/drivers/davinci_emac.c
index 9043493290..7ad539fb09 100644
--- a/bsp/dm365/drivers/davinci_emac.c
+++ b/bsp/dm365/drivers/davinci_emac.c
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
- * Date Author Notes
- * 2011-01-13 weety first version
+ * Date Author Notes
+ * 2011-01-13 weety first version
*/
@@ -15,8 +15,8 @@
#include <dm36x.h>
#include "davinci_emac.h"
-#define MMU_NOCACHE_ADDR(a) ((rt_uint32_t)a | (1UL<<29))
-#define CACHE_LINE_SIZE 32
+#define MMU_NOCACHE_ADDR(a) ((rt_uint32_t)a | (1UL<<29))
+#define CACHE_LINE_SIZE 32
extern void mmu_clean_dcache(rt_uint32_t buffer, rt_uint32_t size);
extern void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size);
@@ -24,22 +24,22 @@ extern void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size);
/* EMAC internal utility function */
static inline rt_uint32_t emac_virt_to_phys(void *addr)
{
- return (rt_uint32_t)addr;
+ return (rt_uint32_t)addr;
}
static inline rt_uint32_t virt_to_phys(void *addr)
{
- return (rt_uint32_t)addr;
+ return (rt_uint32_t)addr;
}
/* Cache macros - Packet buffers would be from pbuf pool which is cached */
#define EMAC_VIRT_NOCACHE(addr) (addr)
#define EMAC_CACHE_INVALIDATE(addr, size) \
- mmu_invalidate_dcache(addr, size)
+ mmu_invalidate_dcache(addr, size)
#define EMAC_CACHE_WRITEBACK(addr, size) \
- mmu_clean_dcache(addr, size)
+ mmu_clean_dcache(addr, size)
#define EMAC_CACHE_WRITEBACK_INVALIDATE(addr, size) \
- mmu_clean_invalidated_dcache(addr, size)
+ mmu_clean_invalidated_dcache(addr, size)
/* DM644x does not have BD's in cached memory - so no cache functions */
#define BD_CACHE_INVALIDATE(addr, size)
@@ -53,34 +53,34 @@ static struct emac_priv davinci_emac_device;
static unsigned long emac_bus_frequency;
static unsigned long mdio_max_freq;
-#define EMAC_AUTONEG_TIMEOUT 5000000
-#define EMAC_LINK_TIMEOUT 500000
+#define EMAC_AUTONEG_TIMEOUT 5000000
+#define EMAC_LINK_TIMEOUT 500000
/* EMAC TX Host Error description strings */
static char *emac_txhost_errcodes[16] = {
- "No error", "SOP error", "Ownership bit not set in SOP buffer",
- "Zero Next Buffer Descriptor Pointer Without EOP",
- "Zero Buffer Pointer", "Zero Buffer Length", "Packet Length Error",
- "Reserved", "Reserved", "Reserved", "Reserved", "Reserved",
- "Reserved", "Reserved", "Reserved", "Reserved"
+ "No error", "SOP error", "Ownership bit not set in SOP buffer",
+ "Zero Next Buffer Descriptor Pointer Without EOP",
+ "Zero Buffer Pointer", "Zero Buffer Length", "Packet Length Error",
+ "Reserved", "Reserved", "Reserved", "Reserved", "Reserved",
+ "Reserved", "Reserved", "Reserved", "Reserved"
};
/* EMAC RX Host Error description strings */
static char *emac_rxhost_errcodes[16] = {
- "No error", "Reserved", "Ownership bit not set in input buffer",
- "Reserved", "Zero Buffer Pointer", "Reserved", "Reserved",
- "Reserved", "Reserved", "Reserved", "Reserved", "Reserved",
- "Reserved", "Reserved", "Reserved", "Reserved"
+ "No error", "Reserved", "Ownership bit not set in input buffer",
+ "Reserved", "Zero Buffer Pointer", "Reserved", "Reserved",
+ "Reserved", "Reserved", "Reserved", "Reserved", "Reserved",
+ "Reserved", "Reserved", "Reserved", "Reserved"
};
-#define emac_read(reg) davinci_readl(priv->emac_base + (reg))
+#define emac_read(reg) davinci_readl(priv->emac_base + (reg))
#define emac_write(reg, val) davinci_writel(val, priv->emac_base + (reg))
-#define emac_ctrl_read(reg) davinci_readl((priv->ctrl_base + (reg)))
+#define emac_ctrl_read(reg) davinci_readl((priv->ctrl_base + (reg)))
#define emac_ctrl_write(reg, val) davinci_writel(val, (priv->ctrl_base + (reg)))
-#define emac_mdio_read(reg) davinci_readl(priv->mdio_base + (reg))
+#define emac_mdio_read(reg) davinci_readl(priv->mdio_base + (reg))
#define emac_mdio_write(reg, val) davinci_writel(val, (priv->mdio_base + (reg)))
static void emac_int_enable(struct emac_priv *priv);
@@ -91,74 +91,74 @@ static int emac_init_txch(struct emac_priv *priv, rt_uint32_t ch);
/* Wait until mdio is ready for next command */
#define MDIO_WAIT_FOR_USER_ACCESS\
- while ((emac_mdio_read((MDIO_USERACCESS(0))) &\
- MDIO_USERACCESS_GO) != 0)
+ while ((emac_mdio_read((MDIO_USERACCESS(0))) &\
+ MDIO_USERACCESS_GO) != 0)
static int emac_mii_read(struct emac_priv *priv, int phy_id, int phy_reg)
{
- unsigned int phy_data = 0;
- unsigned int phy_control;
+ unsigned int phy_data = 0;
+ unsigned int phy_control;
- /* Wait until mdio is ready for next command */
- MDIO_WAIT_FOR_USER_ACCESS;
+ /* Wait until mdio is ready for next command */
+ MDIO_WAIT_FOR_USER_ACCESS;
- phy_control = (MDIO_USERACCESS_GO |
- MDIO_USERACCESS_READ |
- ((phy_reg << 21) & MDIO_USERACCESS_REGADR) |
- ((phy_id << 16) & MDIO_USERACCESS_PHYADR) |
- (phy_data & MDIO_USERACCESS_DATA));
- emac_mdio_write(MDIO_USERACCESS(0), phy_control);
+ phy_control = (MDIO_USERACCESS_GO |
+ MDIO_USERACCESS_READ |
+ ((phy_reg << 21) & MDIO_USERACCESS_REGADR) |
+ ((phy_id << 16) & MDIO_USERACCESS_PHYADR) |
+ (phy_data & MDIO_USERACCESS_DATA));
+ emac_mdio_write(MDIO_USERACCESS(0), phy_control);
- /* Wait until mdio is ready for next command */
- MDIO_WAIT_FOR_USER_ACCESS;
+ /* Wait until mdio is ready for next command */
+ MDIO_WAIT_FOR_USER_ACCESS;
- return emac_mdio_read(MDIO_USERACCESS(0)) & MDIO_USERACCESS_DATA;
+ return emac_mdio_read(MDIO_USERACCESS(0)) & MDIO_USERACCESS_DATA;
}
static int emac_mii_write(struct emac_priv *priv, int phy_id,
- int phy_reg, rt_uint16_t phy_data)
+ int phy_reg, rt_uint16_t phy_data)
{
- unsigned int control;
+ unsigned int control;
- /* until mdio is ready for next command */
- MDIO_WAIT_FOR_USER_ACCESS;
+ /* until mdio is ready for next command */
+ MDIO_WAIT_FOR_USER_ACCESS;
- control = (MDIO_USERACCESS_GO |
- MDIO_USERACCESS_WRITE |
- ((phy_reg << 21) & MDIO_USERACCESS_REGADR) |
- ((phy_id << 16) & MDIO_USERACCESS_PHYADR) |
- (phy_data & MDIO_USERACCESS_DATA));
- emac_mdio_write(MDIO_USERACCESS(0), control);
+ control = (MDIO_USERACCESS_GO |
+ MDIO_USERACCESS_WRITE |
+ ((phy_reg << 21) & MDIO_USERACCESS_REGADR) |
+ ((phy_id << 16) & MDIO_USERACCESS_PHYADR) |
+ (phy_data & MDIO_USERACCESS_DATA));
+ emac_mdio_write(MDIO_USERACCESS(0), control);
- return 0;
+ return 0;
}
static int emac_mii_reset(struct emac_priv *priv)
{
- unsigned int clk_div;
- int mdio_bus_freq = emac_bus_frequency;
+ unsigned int clk_div;
+ int mdio_bus_freq = emac_bus_frequency;
- if (mdio_max_freq && mdio_bus_freq)
- clk_div = ((mdio_bus_freq / mdio_max_freq) - 1);
- else
- clk_div = 0xFF;
+ if (mdio_max_freq && mdio_bus_freq)
+ clk_div = ((mdio_bus_freq / mdio_max_freq) - 1);
+ else
+ clk_div = 0xFF;
- clk_div &= MDIO_CONTROL_CLKDIV;
+ clk_div &= MDIO_CONTROL_CLKDIV;
- /* Set enable and clock divider in MDIOControl */
- emac_mdio_write(MDIO_CONTROL, (clk_div | MDIO_CONTROL_ENABLE));
+ /* Set enable and clock divider in MDIOControl */
+ emac_mdio_write(MDIO_CONTROL, (clk_div | MDIO_CONTROL_ENABLE));
- return 0;
+ return 0;
}
/* Duplex, half or full. */
-#define DUPLEX_HALF 0x00
-#define DUPLEX_FULL 0x01
+#define DUPLEX_HALF 0x00
+#define DUPLEX_FULL 0x01
static void udelay(rt_uint32_t us)
{
@@ -169,83 +169,83 @@ static void udelay(rt_uint32_t us)
static void davinci_emac_phy_reset(rt_device_t dev)
{
- int i;
- rt_uint16_t status, adv;
- struct emac_priv *priv = dev->user_data;;
+ int i;
+ rt_uint16_t status, adv;
+ struct emac_priv *priv = dev->user_data;;
- adv = ADVERTISE_CSMA | ADVERTISE_ALL;
- emac_mii_write(priv, priv->phy_addr, MII_ADVERTISE, adv);
- rt_kprintf("%s: Starting autonegotiation...\n", dev->parent.name);
- emac_mii_write(priv, priv->phy_addr, MII_BMCR, (BMCR_ANENABLE
- | BMCR_ANRESTART));
+ adv = ADVERTISE_CSMA | ADVERTISE_ALL;
+ emac_mii_write(priv, priv->phy_addr, MII_ADVERTISE, adv);
+ rt_kprintf("%s: Starting autonegotiation...\n", dev->parent.name);
+ emac_mii_write(priv, priv->phy_addr, MII_BMCR, (BMCR_ANENABLE
+ | BMCR_ANRESTART));
- for (i = 0; i < EMAC_AUTONEG_TIMEOUT / 100; i++) {
- status = emac_mii_read(priv, priv->phy_addr, MII_BMSR);
- if (status & BMSR_ANEGCOMPLETE)
- break;
- udelay(100);
- }
+ for (i = 0; i < EMAC_AUTONEG_TIMEOUT / 100; i++) {
+ status = emac_mii_read(priv, priv->phy_addr, MII_BMSR);
+ if (status & BMSR_ANEGCOMPLETE)
+ break;
+ udelay(100);
+ }
- if (status & BMSR_ANEGCOMPLETE)
- rt_kprintf("%s: Autonegotiation complete\n", dev->parent.name);
- else
- rt_kprintf("%s: Autonegotiation timed out (status=0x%04x)\n",
- dev->parent.name, status);
+ if (status & BMSR_ANEGCOMPLETE)
+ rt_kprintf("%s: Autonegotiation complete\n", dev->parent.name);
+ else
+ rt_kprintf("%s: Autonegotiation timed out (status=0x%04x)\n",
+ dev->parent.name, status);
}
static int davinci_emac_phy_init(rt_device_t dev)
{
- struct emac_priv *priv = dev->user_data;
- rt_uint16_t phy_id, status, adv, lpa;
- int media, speed, duplex;
- int i;
+ struct emac_priv *priv = dev->user_data;
+ rt_uint16_t phy_id, status, adv, lpa;
+ int media, speed, duplex;
+ int i;
- /* Check if the PHY is up to snuff... */
- phy_id = emac_mii_read(priv, priv->phy_addr, MII_PHYSID1);
- if (phy_id == 0xffff) {
- rt_kprintf("%s: No PHY present\n", dev->parent.name);
- return 0;
- }
+ /* Check if the PHY is up to snuff... */
+ phy_id = emac_mii_read(priv, priv->phy_addr, MII_PHYSID1);
+ if (phy_id == 0xffff) {
+ rt_kprintf("%s: No PHY present\n", dev->parent.name);
+ return 0;
+ }
- status = emac_mii_read(priv, priv->phy_addr, MII_BMSR);
- if (!(status & BMSR_LSTATUS)) {
- /* Try to re-negotiate if we don't have link already. */
- davinci_emac_phy_reset(dev);
+ status = emac_mii_read(priv, priv->phy_addr, MII_BMSR);
+ if (!(status & BMSR_LSTATUS)) {
+ /* Try to re-negotiate if we don't have link already. */
+ davinci_emac_phy_reset(dev);
- for (i = 0; i < EMAC_LINK_TIMEOUT / 100; i++) {
- status = emac_mii_read(priv, priv->phy_addr, MII_BMSR);
- if (status & BMSR_LSTATUS)
- break;
- udelay(100);
- }
- }
+ for (i = 0; i < EMAC_LINK_TIMEOUT / 100; i++) {
+ status = emac_mii_read(priv, priv->phy_addr, MII_BMSR);
+ if (status & BMSR_LSTATUS)
+ break;
+ udelay(100);
+ }
+ }
- if (!(status & BMSR_LSTATUS)) {
- rt_kprintf("%s: link down (status: 0x%04x)\n",
- dev->parent.name, status);
- priv->link = 0;
- eth_device_linkchange(&priv->parent, RT_FALSE);
- return 0;
- } else {
- adv = emac_mii_read(priv, priv->phy_addr, MII_ADVERTISE);
- lpa = emac_mii_read(priv, priv->phy_addr, MII_LPA);
- media = mii_nway_result(lpa & adv);
- speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF)
- ? 1 : 0);
- duplex = (media & ADVERTISE_FULL) ? 1 : 0;
- rt_kprintf("%s: link up, %sMbps %s-duplex (lpa: 0x%04x)\n",
- dev->parent.name,
- speed ? "100" : "10",
- duplex ? "full" : "half",
- lpa);
- priv->speed = speed;
- priv->duplex = duplex;
- priv->link = 1;
- eth_device_linkchange(&priv->parent, RT_TRUE);
+ if (!(status & BMSR_LSTATUS)) {
+ rt_kprintf("%s: link down (status: 0x%04x)\n",
+ dev->parent.name, status);
+ priv->link = 0;
+ eth_device_linkchange(&priv->parent, RT_FALSE);
+ return 0;
+ } else {
+ adv = emac_mii_read(priv, priv->phy_addr, MII_ADVERTISE);
+ lpa = emac_mii_read(priv, priv->phy_addr, MII_LPA);
+ media = mii_nway_result(lpa & adv);
+ speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF)
+ ? 1 : 0);
+ duplex = (media & ADVERTISE_FULL) ? 1 : 0;
+ rt_kprintf("%s: link up, %sMbps %s-duplex (lpa: 0x%04x)\n",
+ dev->parent.name,
+ speed ? "100" : "10",
+ duplex ? "full" : "half",
+ lpa);
+ priv->speed = speed;
+ priv->duplex = duplex;
+ priv->link = 1;
+ eth_device_linkchange(&priv->parent, RT_TRUE);
- return 1;
- }
+ return 1;
+ }
}
/**
@@ -258,94 +258,94 @@ static int davinci_emac_phy_init(rt_device_t dev)
*/
static void emac_update_phystatus(struct emac_priv *priv)
{
- rt_uint32_t mac_control;
- rt_uint32_t new_duplex;
- rt_uint32_t cur_duplex;
+ rt_uint32_t mac_control;
+ rt_uint32_t new_duplex;
+ rt_uint32_t cur_duplex;
- mac_control = emac_read(EMAC_MACCONTROL);
- cur_duplex = (mac_control & EMAC_MACCONTROL_FULLDUPLEXEN) ?
- DUPLEX_FULL : DUPLEX_HALF;
- if (priv->phy_mask)
- new_duplex = priv->duplex;
- else
- new_duplex = DUPLEX_FULL;
+ mac_control = emac_read(EMAC_MACCONTROL);
+ cur_duplex = (mac_control & EMAC_MACCONTROL_FULLDUPLEXEN) ?
+ DUPLEX_FULL : DUPLEX_HALF;
+ if (priv->phy_mask)
+ new_duplex = priv->duplex;
+ else
+ new_duplex = DUPLEX_FULL;
- /* We get called only if link has changed (speed/duplex/status) */
- if ((priv->link) && (new_duplex != cur_duplex)) {
- priv->duplex = new_duplex;
- if (DUPLEX_FULL == priv->duplex)
- mac_control |= (EMAC_MACCONTROL_FULLDUPLEXEN);
- else
- mac_control &= ~(EMAC_MACCONTROL_FULLDUPLEXEN);
- }
+ /* We get called only if link has changed (speed/duplex/status) */
+ if ((priv->link) && (new_duplex != cur_duplex)) {
+ priv->duplex = new_duplex;
+ if (DUPLEX_FULL == priv->duplex)
+ mac_control |= (EMAC_MACCONTROL_FULLDUPLEXEN);
+ else
+ mac_control &= ~(EMAC_MACCONTROL_FULLDUPLEXEN);
+ }
- if (priv->speed == SPEED_1000 && (priv->version == EMAC_VERSION_2)) {
- mac_control = emac_read(EMAC_MACCONTROL);
- mac_control |= (EMAC_DM646X_MACCONTORL_GIG |
- EMAC_DM646X_MACCONTORL_GIGFORCE);
- } else {
- /* Clear the GIG bit and GIGFORCE bit */
- mac_control &= ~(EMAC_DM646X_MACCONTORL_GIGFORCE |
- EMAC_DM646X_MACCONTORL_GIG);
+ if (priv->speed == SPEED_1000 && (priv->version == EMAC_VERSION_2)) {
+ mac_control = emac_read(EMAC_MACCONTROL);
+ mac_control |= (EMAC_DM646X_MACCONTORL_GIG |
+ EMAC_DM646X_MACCONTORL_GIGFORCE);
+ } else {
+ /* Clear the GIG bit and GIGFORCE bit */
+ mac_control &= ~(EMAC_DM646X_MACCONTORL_GIGFORCE |
+ EMAC_DM646X_MACCONTORL_GIG);
- if (priv->rmii_en && (priv->speed == SPEED_100))
- mac_control |= EMAC_MACCONTROL_RMIISPEED_MASK;
- else
- mac_control &= ~EMAC_MACCONTROL_RMIISPEED_MASK;
- }
+ if (priv->rmii_en && (priv->speed == SPEED_100))
+ mac_control |= EMAC_MACCONTROL_RMIISPEED_MASK;
+ else
+ mac_control &= ~EMAC_MACCONTROL_RMIISPEED_MASK;
+ }
- /* Update mac_control if changed */
- emac_write(EMAC_MACCONTROL, mac_control);
+ /* Update mac_control if changed */
+ emac_write(EMAC_MACCONTROL, mac_control);
#if 0
- if (priv->link) {
- /* link ON */
- /* reactivate the transmit queue if it is stopped */
- } else {
- /* link OFF */
- }
+ if (priv->link) {
+ /* link ON */
+ /* reactivate the transmit queue if it is stopped */
+ } else {
+ /* link OFF */
+ }
#endif
}
void davinci_emac_update_link(void *param)
{
- struct emac_priv *priv = param;
- rt_device_t dev = &(priv->parent.parent);
- rt_uint32_t status, status_change = 0;
- rt_uint32_t link;
- rt_uint32_t media;
- rt_uint16_t adv, lpa;
+ struct emac_priv *priv = param;
+ rt_device_t dev = &(priv->parent.parent);
+ rt_uint32_t status, status_change = 0;
+ rt_uint32_t link;
+ rt_uint32_t media;
+ rt_uint16_t adv, lpa;
- status = emac_mii_read(priv, priv->phy_addr, MII_BMSR);
- if ((status & BMSR_LSTATUS) == 0)
- link = 0;
- else
- link = 1;
+ status = emac_mii_read(priv, priv->phy_addr, MII_BMSR);
+ if ((status & BMSR_LSTATUS) == 0)
+ link = 0;
+ else
+ link = 1;
- if (link != priv->link) {
- priv->link = link;
- status_change = 1;
- }
+ if (link != priv->link) {
+ priv->link = link;
+ status_change = 1;
+ }
- if (status_change) {
- if (priv->link) {
- adv = emac_mii_read(priv, priv->phy_addr, MII_ADVERTISE);
- lpa = emac_mii_read(priv, priv->phy_addr, MII_LPA);
- media = mii_nway_result(lpa & adv);
- priv->speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF)
- ? 100 : 10);
- priv->duplex = (media & ADVERTISE_FULL) ? 1 : 0;
- rt_kprintf("%s: link up (%dMbps/%s-duplex)\n",
- dev->parent.name, priv->speed,
- DUPLEX_FULL == priv->duplex ? "Full":"Half");
- eth_device_linkchange(&priv->parent, RT_TRUE);
- } else {
- rt_kprintf("%s: link down\n", dev->parent.name);
- eth_device_linkchange(&priv->parent, RT_FALSE);
- }
- emac_update_phystatus(priv);
+ if (status_change) {
+ if (priv->link) {
+ adv = emac_mii_read(priv, priv->phy_addr, MII_ADVERTISE);
+ lpa = emac_mii_read(priv, priv->phy_addr, MII_LPA);
+ media = mii_nway_result(lpa & adv);
+ priv->speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF)
+ ? 100 : 10);
+ priv->duplex = (media & ADVERTISE_FULL) ? 1 : 0;
+ rt_kprintf("%s: link up (%dMbps/%s-duplex)\n",
+ dev->parent.name, priv->speed,
+ DUPLEX_FULL == priv->duplex ? "Full":"Half");
+ eth_device_linkchange(&priv->parent, RT_TRUE);
+ } else {
+ rt_kprintf("%s: link down\n", dev->parent.name);
+ eth_device_linkchange(&priv->parent, RT_FALSE);
+ }
+ emac_update_phystatus(priv);
- }
+ }
}
@@ -361,21 +361,21 @@ void davinci_emac_update_link(void *param)
*
*/
static int emac_net_tx_complete(struct emac_priv *priv,
- void **net_data_tokens,
- int num_tokens, rt_uint32_t ch)
+ void **net_data_tokens,
+ int num_tokens, rt_uint32_t ch)
{
- rt_uint32_t cnt;
+ rt_uint32_t cnt;
- for (cnt = 0; cnt < num_tokens; cnt++) {
- struct pbuf *p = (struct pbuf *)net_data_tokens[cnt];
- if (p == RT_NULL)
- continue;
- priv->net_dev_stats.tx_packets++;
- priv->net_dev_stats.tx_bytes += p->len;
- //free pbuf
- }
+ for (cnt = 0; cnt < num_tokens; cnt++) {
+ struct pbuf *p = (struct pbuf *)net_data_tokens[cnt];
+ if (p == RT_NULL)
+ continue;
+ priv->net_dev_stats.tx_packets++;
+ priv->net_dev_stats.tx_bytes += p->len;
+ //free pbuf
+ }
- return 0;
+ return 0;
}
/**
@@ -388,36 +388,36 @@ static int emac_net_tx_complete(struct emac_priv *priv,
*/
static void emac_txch_teardown(struct emac_priv *priv, rt_uint32_t ch)
{
- rt_uint32_t teardown_cnt = 0xFFFFFFF0; /* Some high value */
- struct emac_txch *txch = priv->txch[ch];
- struct emac_tx_bd __iomem *curr_bd;
+ rt_uint32_t teardown_cnt = 0xFFFFFFF0; /* Some high value */
+ struct emac_txch *txch = priv->txch[ch];
+ struct emac_tx_bd __iomem *curr_bd;
- while ((emac_read(EMAC_TXCP(ch)) & EMAC_TEARDOWN_VALUE) !=
- EMAC_TEARDOWN_VALUE) {
- /* wait till tx teardown complete */
- --teardown_cnt;
- if (0 == teardown_cnt) {
- rt_kprintf("EMAC: TX teardown aborted\n");
- break;
- }
- }
- emac_write(EMAC_TXCP(ch), EMAC_TEARDOWN_VALUE);
+ while ((emac_read(EMAC_TXCP(ch)) & EMAC_TEARDOWN_VALUE) !=
+ EMAC_TEARDOWN_VALUE) {
+ /* wait till tx teardown complete */
+ --teardown_cnt;
+ if (0 == teardown_cnt) {
+ rt_kprintf("EMAC: TX teardown aborted\n");
+ break;
+ }
+ }
+ emac_write(EMAC_TXCP(ch), EMAC_TEARDOWN_VALUE);
- /* process sent packets and return pbuf's to upper layer */
- if (1 == txch->queue_active) {
- curr_bd = txch->active_queue_head;
- while (curr_bd != RT_NULL) {
- emac_net_tx_complete(priv, (void *)
- &curr_bd->buf_token, 1, ch);
- if (curr_bd != txch->active_queue_tail)
- curr_bd = curr_bd->next;
- else
- break;
- }
- txch->bd_pool_head = txch->active_queue_head;
- txch->active_queue_head =
- txch->active_queue_tail = RT_NULL;
- }
+ /* process sent packets and return pbuf's to upper layer */
+ if (1 == txch->queue_active) {
+ curr_bd = txch->active_queue_head;
+ while (curr_bd != RT_NULL) {
+ emac_net_tx_complete(priv, (void *)
+ &curr_bd->buf_token, 1, ch);
+ if (curr_bd != txch->active_queue_tail)
+ curr_bd = curr_bd->next;
+ else
+ break;
+ }
+ txch->bd_pool_head = txch->active_queue_head;
+ txch->active_queue_head =
+ txch->active_queue_tail = RT_NULL;
+ }
}
@@ -431,15 +431,15 @@ static void emac_txch_teardown(struct emac_priv *priv, rt_uint32_t ch)
*/
static void emac_stop_txch(struct emac_priv *priv, rt_uint32_t ch)
{
- struct emac_txch *txch = priv->txch[ch];
+ struct emac_txch *txch = priv->txch[ch];
- if (txch) {
- txch->teardown_pending = 1;
- emac_write(EMAC_TXTEARDOWN, 0);
- emac_txch_teardown(priv, ch);
- txch->teardown_pending = 0;
- emac_write(EMAC_TXINTMASKCLEAR, BIT(ch));
- }
+ if (txch) {
+ txch->teardown_pending = 1;
+ emac_write(EMAC_TXTEARDOWN, 0);
+ emac_txch_teardown(priv, ch);
+ txch->teardown_pending = 0;
+ emac_write(EMAC_TXINTMASKCLEAR, BIT(ch));
+ }
}
@@ -460,65 +460,65 @@ static void emac_stop_txch(struct emac_priv *priv, rt_uint32_t ch)
*/
static int emac_tx_bdproc(struct emac_priv *priv, rt_uint32_t ch, rt_uint32_t budget)
{
- unsigned long flags;
- rt_uint32_t frame_status;
- rt_uint32_t pkts_processed = 0;
- rt_uint32_t tx_complete_cnt = 0;
- struct emac_tx_bd __iomem *curr_bd;
- struct emac_txch *txch = priv->txch[ch];
- rt_uint32_t *tx_complete_ptr = txch->tx_complete;
+ unsigned long flags;
+ rt_uint32_t frame_status;
+ rt_uint32_t pkts_processed = 0;
+ rt_uint32_t tx_complete_cnt = 0;
+ struct emac_tx_bd __iomem *curr_bd;
+ struct emac_txch *txch = priv->txch[ch];
+ rt_uint32_t *tx_complete_ptr = txch->tx_complete;
- if (1 == txch->teardown_pending) {
- rt_kprintf("DaVinci EMAC:emac_tx_bdproc: "\
- "teardown pending\n");
- return 0; /* dont handle any pkt completions */
- }
+ if (1 == txch->teardown_pending) {
+ rt_kprintf("DaVinci EMAC:emac_tx_bdproc: "\
+ "teardown pending\n");
+ return 0; /* dont handle any pkt completions */
+ }
- ++txch->proc_count;
- rt_sem_take(&priv->tx_lock, RT_WAITING_FOREVER);
- curr_bd = txch->active_queue_head;
- if (RT_NULL == curr_bd) {
- emac_write(EMAC_TXCP(ch),
- emac_virt_to_phys(txch->last_hw_bdprocessed));
- txch->no_active_pkts++;
- rt_sem_release(&priv->tx_lock);
- return 0;
- }
- BD_CACHE_INVALIDATE(curr_bd, EMAC_BD_LENGTH_FOR_CACHE);
- frame_status = curr_bd->mode;
- while ((curr_bd) &&
- ((frame_status & EMAC_CPPI_OWNERSHIP_BIT) == 0) &&
- (pkts_processed < budget)) {
- emac_write(EMAC_TXCP(ch), emac_virt_to_phys(curr_bd));
- txch->active_queue_head = curr_bd->next;
- if (frame_status & EMAC_CPPI_EOQ_BIT) {
- if (curr_bd->next) { /* misqueued packet */
- emac_write(EMAC_TXHDP(ch), curr_bd->h_next);
- ++txch->mis_queued_packets;
- } else {
- txch->queue_active = 0; /* end of queue */
- }
- }
- *tx_complete_ptr = (rt_uint32_t) curr_bd->buf_token;
- ++tx_complete_ptr;
- ++tx_complete_cnt;
- curr_bd->next = txch->bd_pool_head;
- txch->bd_pool_head = curr_bd;
- --txch->active_queue_count;
- pkts_processed++;
- txch->last_hw_bdprocessed = curr_bd;
- curr_bd = txch->active_queue_head;
- if (curr_bd) {
- BD_CACHE_INVALIDATE(curr_bd, EMAC_BD_LENGTH_FOR_CACHE);
- frame_status = curr_bd->mode;
- }
- } /* end of pkt processing loop */
+ ++txch->proc_count;
+ rt_sem_take(&priv->tx_lock, RT_WAITING_FOREVER);
+ curr_bd = txch->active_queue_head;
+ if (RT_NULL == curr_bd) {
+ emac_write(EMAC_TXCP(ch),
+ emac_virt_to_phys(txch->last_hw_bdprocessed));
+ txch->no_active_pkts++;
+ rt_sem_release(&priv->tx_lock);
+ return 0;
+ }
+ BD_CACHE_INVALIDATE(curr_bd, EMAC_BD_LENGTH_FOR_CACHE);
+ frame_status = curr_bd->mode;
+ while ((curr_bd) &&
+ ((frame_status & EMAC_CPPI_OWNERSHIP_BIT) == 0) &&
+ (pkts_processed < budget)) {
+ emac_write(EMAC_TXCP(ch), emac_virt_to_phys(curr_bd));
+ txch->active_queue_head = curr_bd->next;
+ if (frame_status & EMAC_CPPI_EOQ_BIT) {
+ if (curr_bd->next) { /* misqueued packet */
+ emac_write(EMAC_TXHDP(ch), curr_bd->h_next);
+ ++txch->mis_queued_packets;
+ } else {
+ txch->queue_active = 0; /* end of queue */
+ }
+ }
+ *tx_complete_ptr = (rt_uint32_t) curr_bd->buf_token;
+ ++tx_complete_ptr;
+ ++tx_complete_cnt;
+ curr_bd->next = txch->bd_pool_head;
+ txch->bd_pool_head = curr_bd;
+ --txch->active_queue_count;
+ pkts_processed++;
+ txch->last_hw_bdprocessed = curr_bd;
+ curr_bd = txch->active_queue_head;
+ if (curr_bd) {
+ BD_CACHE_INVALIDATE(curr_bd, EMAC_BD_LENGTH_FOR_CACHE);
+ frame_status = curr_bd->mode;
+ }
+ } /* end of pkt processing loop */
- emac_net_tx_complete(priv,
- (void *)&txch->tx_complete[0],
- tx_complete_cnt, ch);
- rt_sem_release(&priv->tx_lock);
- return pkts_processed;
+ emac_net_tx_complete(priv,
+ (void *)&txch->tx_complete[0],
+ tx_complete_cnt, ch);
+ rt_sem_release(&priv->tx_lock);
+ return pkts_processed;
}
@@ -536,81 +536,81 @@ static int emac_tx_bdproc(struct emac_priv *priv, rt_uint32_t ch, rt_uint32_t bu
*/
static int emac_send(struct emac_priv *priv, struct emac_netpktobj *pkt, rt_uint32_t ch)
{
- unsigned long flags;
- struct emac_tx_bd __iomem *curr_bd;
- struct emac_txch *txch;
- struct emac_netbufobj *buf_list;
- rt_uint32_t num_pkts = 0;
- int retry = 0;
+ unsigned long flags;
+ struct emac_tx_bd __iomem *curr_bd;
+ struct emac_txch *txch;
+ struct emac_netbufobj *buf_list;
+ rt_uint32_t num_pkts = 0;
+ int retry = 0;
- txch = priv->txch[ch];
- buf_list = pkt->buf_list; /* get handle to the buffer array */
+ txch = priv->txch[ch];
+ buf_list = pkt->buf_list; /* get handle to the buffer array */
- /* check packet size and pad if short */
- if (pkt->pkt_length < EMAC_DEF_MIN_ETHPKTSIZE) {
- buf_list->length += (EMAC_DEF_MIN_ETHPKTSIZE - pkt->pkt_length);
- pkt->pkt_length = EMAC_DEF_MIN_ETHPKTSIZE;
- }
+ /* check packet size and pad if short */
+ if (pkt->pkt_length < EMAC_DEF_MIN_ETHPKTSIZE) {
+ buf_list->length += (EMAC_DEF_MIN_ETHPKTSIZE - pkt->pkt_length);
+ pkt->pkt_length = EMAC_DEF_MIN_ETHPKTSIZE;
+ }
try:
- rt_sem_take(&priv->tx_lock, RT_WAITING_FOREVER);
- curr_bd = txch->bd_pool_head;
- if (curr_bd == RT_NULL) {
- txch->out_of_tx_bd++;
- rt_sem_release(&priv->tx_lock);
- num_pkts = emac_tx_bdproc(priv, EMAC_DEF_TX_CH,
- EMAC_DEF_TX_MAX_SERVICE);
- if (!num_pkts) {
- retry++;
- if (retry > 5)
- return EMAC_ERR_TX_OUT_OF_BD;
- rt_thread_delay(1);
- }
- goto try;
- }
+ rt_sem_take(&priv->tx_lock, RT_WAITING_FOREVER);
+ curr_bd = txch->bd_pool_head;
+ if (curr_bd == RT_NULL) {
+ txch->out_of_tx_bd++;
+ rt_sem_release(&priv->tx_lock);
+ num_pkts = emac_tx_bdproc(priv, EMAC_DEF_TX_CH,
+ EMAC_DEF_TX_MAX_SERVICE);
+ if (!num_pkts) {
+ retry++;
+ if (retry > 5)
+ return EMAC_ERR_TX_OUT_OF_BD;
+ rt_thread_delay(1);
+ }
+ goto try;
+ }
- txch->bd_pool_head = curr_bd->next;
- curr_bd->buf_token = buf_list->buf_token;
- curr_bd->buff_ptr = virt_to_phys(buf_list->data_ptr);
- curr_bd->off_b_len = buf_list->length;
- curr_bd->h_next = 0;
- curr_bd->next = RT_NULL;
- curr_bd->mode = (EMAC_CPPI_SOP_BIT | EMAC_CPPI_OWNERSHIP_BIT |
- EMAC_CPPI_EOP_BIT | pkt->pkt_length);
+ txch->bd_pool_head = curr_bd->next;
+ curr_bd->buf_token = buf_list->buf_token;
+ curr_bd->buff_ptr = virt_to_phys(buf_list->data_ptr);
+ curr_bd->off_b_len = buf_list->length;
+ curr_bd->h_next = 0;
+ curr_bd->next = RT_NULL;
+ curr_bd->mode = (EMAC_CPPI_SOP_BIT | EMAC_CPPI_OWNERSHIP_BIT |
+ EMAC_CPPI_EOP_BIT | pkt->pkt_length);
- /* flush the packet from cache if write back cache is present */
- BD_CACHE_WRITEBACK_INVALIDATE(curr_bd, EMAC_BD_LENGTH_FOR_CACHE);
+ /* flush the packet from cache if write back cache is present */
+ BD_CACHE_WRITEBACK_INVALIDATE(curr_bd, EMAC_BD_LENGTH_FOR_CACHE);
- /* send the packet */
- if (txch->active_queue_head == RT_NULL) {
- txch->active_queue_head = curr_bd;
- txch->active_queue_tail = curr_bd;
- if (1 != txch->queue_active) {
- emac_write(EMAC_TXHDP(ch),
- emac_virt_to_phys(curr_bd));
- txch->queue_active = 1;
- }
- ++txch->queue_reinit;
- } else {
- register struct emac_tx_bd __iomem *tail_bd;
- register rt_uint32_t frame_status;
+ /* send the packet */
+ if (txch->active_queue_head == RT_NULL) {
+ txch->active_queue_head = curr_bd;
+ txch->active_queue_tail = curr_bd;
+ if (1 != txch->queue_active) {
+ emac_write(EMAC_TXHDP(ch),
+ emac_virt_to_phys(curr_bd));
+ txch->queue_active = 1;
+ }
+ ++txch->queue_reinit;
+ } else {
+ register struct emac_tx_bd __iomem *tail_bd;
+ register rt_uint32_t frame_status;
- tail_bd = txch->active_queue_tail;
- tail_bd->next = curr_bd;
- txch->active_queue_tail = curr_bd;
- tail_bd = EMAC_VIRT_NOCACHE(tail_bd);
- tail_bd->h_next = (int)emac_virt_to_phys(curr_bd);
- frame_status = tail_bd->mode;
- if (frame_status & EMAC_CPPI_EOQ_BIT) {
- emac_write(EMAC_TXHDP(ch), emac_virt_to_phys(curr_bd));
- frame_status &= ~(EMAC_CPPI_EOQ_BIT);
- tail_bd->mode = frame_status;
- ++txch->end_of_queue_add;
- }
- }
- txch->active_queue_count++;
- rt_sem_release(&priv->tx_lock);
- return 0;
+ tail_bd = txch->active_queue_tail;
+ tail_bd->next = curr_bd;
+ txch->active_queue_tail = curr_bd;
+ tail_bd = EMAC_VIRT_NOCACHE(tail_bd);
+ tail_bd->h_next = (int)emac_virt_to_phys(curr_bd);
+ frame_status = tail_bd->mode;
+ if (frame_status & EMAC_CPPI_EOQ_BIT) {
+ emac_write(EMAC_TXHDP(ch), emac_virt_to_phys(curr_bd));
+ frame_status &= ~(EMAC_CPPI_EOQ_BIT);
+ tail_bd->mode = frame_status;
+ ++txch->end_of_queue_add;
+ }
+ }
+ txch->active_queue_count++;
+ rt_sem_release(&priv->tx_lock);
+ return 0;
}
/**
@@ -625,40 +625,40 @@ try:
*/
static int emac_dev_xmit(struct pbuf *p, struct emac_priv *priv)
{
- int ret_code;
- struct emac_netbufobj tx_buf; /* buffer obj-only single frame support */
- struct emac_netpktobj tx_packet; /* packet object */
+ int ret_code;
+ struct emac_netbufobj tx_buf; /* buffer obj-only single frame support */
+ struct emac_netpktobj tx_packet; /* packet object */
- /* If no link, return */
- if (!priv->link) {
- rt_kprintf("DaVinci EMAC: No link to transmit\n");
- return -RT_EBUSY;
- }
+ /* If no link, return */
+ if (!priv->link) {
+ rt_kprintf("DaVinci EMAC: No link to transmit\n");
+ return -RT_EBUSY;
+ }
- /* Build the buffer and packet objects - Since only single fragment is
- * supported, need not set length and token in both packet & object.
- * Doing so for completeness sake & to show that this needs to be done
- * in multifragment case
- */
- tx_packet.buf_list = &tx_buf;
- tx_packet.num_bufs = 1; /* only single fragment supported */
- tx_packet.pkt_length = p->len;
- tx_packet.pkt_token = (void *)p;
- tx_buf.length = p->len;
- tx_buf.buf_token = (void *)p;
- tx_buf.data_ptr = p->payload;
- EMAC_CACHE_WRITEBACK((unsigned long)p->payload, p->len);
- ret_code = emac_send(priv, &tx_packet, EMAC_DEF_TX_CH);
- if (ret_code != 0) {
- if (ret_code == EMAC_ERR_TX_OUT_OF_BD) {
- rt_kprintf("DaVinci EMAC: xmit() fatal"\
- " err. Out of TX BD's\n");
- }
- priv->net_dev_stats.tx_dropped++;
- return -RT_EBUSY;
- }
+ /* Build the buffer and packet objects - Since only single fragment is
+ * supported, need not set length and token in both packet & object.
+ * Doing so for completeness sake & to show that this needs to be done
+ * in multifragment case
+ */
+ tx_packet.buf_list = &tx_buf;
+ tx_packet.num_bufs = 1; /* only single fragment supported */
+ tx_packet.pkt_length = p->len;
+ tx_packet.pkt_token = (void *)p;
+ tx_buf.length = p->len;
+ tx_buf.buf_token = (void *)p;
+ tx_buf.data_ptr = p->payload;
+ EMAC_CACHE_WRITEBACK((unsigned long)p->payload, p->len);
+ ret_code = emac_send(priv, &tx_packet, EMAC_DEF_TX_CH);
+ if (ret_code != 0) {
+ if (ret_code == EMAC_ERR_TX_OUT_OF_BD) {
+ rt_kprintf("DaVinci EMAC: xmit() fatal"\
+ " err. Out of TX BD's\n");
+ }
+ priv->net_dev_stats.tx_dropped++;
+ return -RT_EBUSY;
+ }
- return RT_EOK;
+ return RT_EOK;
}
/**
@@ -671,15 +671,15 @@ static int emac_dev_xmit(struct pbuf *p, struct emac_priv *priv)
*/
static void emac_cleanup_txch(struct emac_priv *priv, rt_uint32_t ch)
{
- struct emac_txch *txch = priv->txch[ch];
+ struct emac_txch *txch = priv->txch[ch];
- if (txch) {
- if (txch->bd_mem)
- txch->bd_mem = NULL;
- rt_free(txch->tx_complete);
- rt_free(txch);
- priv->txch[ch] = NULL;
- }
+ if (txch) {
+ if (txch->bd_mem)
+ txch->bd_mem = NULL;
+ rt_free(txch->tx_complete);
+ rt_free(txch);
+ priv->txch[ch] = NULL;
+ }
}
@@ -695,15 +695,15 @@ static void emac_cleanup_txch(struct emac_priv *priv, rt_uint32_t ch)
*/
static void emac_dev_tx_timeout(struct emac_priv *priv)
{
- rt_kprintf("emac tx timeout.\n");
- priv->net_dev_stats.tx_errors++;
- emac_int_disable(priv);
- emac_stop_txch(priv, EMAC_DEF_TX_CH);
- emac_cleanup_txch(priv, EMAC_DEF_TX_CH);
- emac_init_txch(priv, EMAC_DEF_TX_CH);
- emac_write(EMAC_TXHDP(0), 0);
- emac_write(EMAC_TXINTMASKSET, BIT(EMAC_DEF_TX_CH));
- emac_int_enable(priv);
+ rt_kprintf("emac tx timeout.\n");
+ priv->net_dev_stats.tx_errors++;
+ emac_int_disable(priv);
+ emac_stop_txch(priv, EMAC_DEF_TX_CH);
+ emac_cleanup_txch(priv, EMAC_DEF_TX_CH);
+ emac_init_txch(priv, EMAC_DEF_TX_CH);
+ emac_write(EMAC_TXHDP(0), 0);
+ emac_write(EMAC_TXINTMASKSET, BIT(EMAC_DEF_TX_CH));
+ emac_int_enable(priv);
}
@@ -711,16 +711,16 @@ static void emac_dev_tx_timeout(struct emac_priv *priv)
/* transmit packet. */
rt_err_t rt_davinci_emac_tx( rt_device_t dev, struct pbuf* p)
{
- rt_err_t err;
- struct emac_priv *priv = dev->user_data;
+ rt_err_t err;
+ struct emac_priv *priv = dev->user_data;
- err = emac_dev_xmit(p, priv);
- if (err != RT_EOK)
- {
- emac_dev_tx_timeout(priv);
- }
+ err = emac_dev_xmit(p, priv);
+ if (err != RT_EOK)
+ {
+ emac_dev_tx_timeout(priv);
+ }
- return RT_EOK;
+ return RT_EOK;
}
/**
@@ -737,49 +737,49 @@ rt_err_t rt_davinci_emac_tx( rt_device_t dev, struct pbuf* p)
*
*/
static void emac_addbd_to_rx_queue(struct emac_priv *priv, rt_uint32_t ch,
- struct emac_rx_bd __iomem *curr_bd,
- char *buffer, void *buf_token)
+ struct emac_rx_bd __iomem *curr_bd,
+ char *buffer, void *buf_token)
{
- struct emac_rxch *rxch = priv->rxch[ch];
+ struct emac_rxch *rxch = priv->rxch[ch];
- /* populate the hardware descriptor */
- curr_bd->h_next = 0;
- curr_bd->buff_ptr = virt_to_phys(buffer);
- curr_bd->off_b_len = rxch->buf_size;
- curr_bd->mode = EMAC_CPPI_OWNERSHIP_BIT;
- curr_bd->next = RT_NULL;
- curr_bd->data_ptr = buffer;
- curr_bd->buf_token = buf_token;
+ /* populate the hardware descriptor */
+ curr_bd->h_next = 0;
+ curr_bd->buff_ptr = virt_to_phys(buffer);
+ curr_bd->off_b_len = rxch->buf_size;
+ curr_bd->mode = EMAC_CPPI_OWNERSHIP_BIT;
+ curr_bd->next = RT_NULL;
+ curr_bd->data_ptr = buffer;
+ curr_bd->buf_token = buf_token;
- /* write back */
- BD_CACHE_WRITEBACK_INVALIDATE(curr_bd, EMAC_BD_LENGTH_FOR_CACHE);
- if (rxch->active_queue_head == RT_NULL) {
- rxch->active_queue_head = curr_bd;
- rxch->active_queue_tail = curr_bd;
- if (0 != rxch->queue_active) {
- emac_write(EMAC_RXHDP(ch),
- emac_virt_to_phys(rxch->active_queue_head));
- rxch->queue_active = 1;
- }
- } else {
- struct emac_rx_bd __iomem *tail_bd;
- rt_uint32_t frame_status;
+ /* write back */
+ BD_CACHE_WRITEBACK_INVALIDATE(curr_bd, EMAC_BD_LENGTH_FOR_CACHE);
+ if (rxch->active_queue_head == RT_NULL) {
+ rxch->active_queue_head = curr_bd;
+ rxch->active_queue_tail = curr_bd;
+ if (0 != rxch->queue_active) {
+ emac_write(EMAC_RXHDP(ch),
+ emac_virt_to_phys(rxch->active_queue_head));
+ rxch->queue_active = 1;
+ }
+ } else {
+ struct emac_rx_bd __iomem *tail_bd;
+ rt_uint32_t frame_status;
- tail_bd = rxch->active_queue_tail;
- rxch->active_queue_tail = curr_bd;
- tail_bd->next = curr_bd;
- tail_bd = EMAC_VIRT_NOCACHE(tail_bd);
- tail_bd->h_next = emac_virt_to_phys(curr_bd);
- frame_status = tail_bd->mode;
- if (frame_status & EMAC_CPPI_EOQ_BIT) {
- emac_write(EMAC_RXHDP(ch),
- emac_virt_to_phys(curr_bd));
- frame_status &= ~(EMAC_CPPI_EOQ_BIT);
- tail_bd->mode = frame_status;
- ++rxch->end_of_queue_add;
- }
- }
- ++rxch->recycled_bd;
+ tail_bd = rxch->active_queue_tail;
+ rxch->active_queue_tail = curr_bd;
+ tail_bd->next = curr_bd;
+ tail_bd = EMAC_VIRT_NOCACHE(tail_bd);
+ tail_bd->h_next = emac_virt_to_phys(curr_bd);
+ frame_status = tail_bd->mode;
+ if (frame_status & EMAC_CPPI_EOQ_BIT) {
+ emac_write(EMAC_RXHDP(ch),
+ emac_virt_to_phys(curr_bd));
+ frame_status &= ~(EMAC_CPPI_EOQ_BIT);
+ tail_bd->mode = frame_status;
+ ++rxch->end_of_queue_add;
+ }
+ }
+ ++rxch->recycled_bd;
}
/**
@@ -793,22 +793,22 @@ static void emac_addbd_to_rx_queue(struct emac_priv *priv, rt_uint32_t ch,
* Returns success or appropriate error code (none as of now)
*/
static int emac_net_rx_cb(struct emac_priv *priv,
- struct emac_netpktobj *net_pkt_list)
+ struct emac_netpktobj *net_pkt_list)
{
- struct eth_device *device = &priv->parent;
- struct pbuf *p;
- p = (struct pbuf *)net_pkt_list->pkt_token;
- /* set length of packet */
- p->tot_len = net_pkt_list->pkt_length;
- p->len = net_pkt_list->pkt_length;
- EMAC_CACHE_INVALIDATE((unsigned long)p->payload, p->len);
- if (device->netif->input(p, device->netif) != RT_EOK)
- {
- pbuf_free(p);
- }
- priv->net_dev_stats.rx_bytes += net_pkt_list->pkt_length;
- priv->net_dev_stats.rx_packets++;
- return 0;
+ struct eth_device *device = &priv->parent;
+ struct pbuf *p;
+ p = (struct pbuf *)net_pkt_list->pkt_token;
+ /* set length of packet */
+ p->tot_len = net_pkt_list->pkt_length;
+ p->len = net_pkt_list->pkt_length;
+ EMAC_CACHE_INVALIDATE((unsigned long)p->payload, p->len);
+ if (device->netif->input(p, device->netif) != RT_EOK)
+ {
+ pbuf_free(p);
+ }
+ priv->net_dev_stats.rx_bytes += net_pkt_list->pkt_length;
+ priv->net_dev_stats.rx_packets++;
+ return 0;
}
/**
@@ -824,20 +824,20 @@ static int emac_net_rx_cb(struct emac_priv *priv,
* Returns pbuf data pointer or 0 on failure to alloc pbuf
*/
static void *emac_net_alloc_rx_buf(struct emac_priv *priv, int buf_size,
- void **data_token, rt_uint32_t ch)
+ void **data_token, rt_uint32_t ch)
{
- struct pbuf* p;
+ struct pbuf* p;
- p = pbuf_alloc(PBUF_LINK, buf_size, PBUF_RAM);
- if (RT_NULL == p) {
- rt_kprintf("DaVinci EMAC: failed to alloc pbuf\n");
- return RT_NULL;
- }
+ p = pbuf_alloc(PBUF_LINK, buf_size, PBUF_RAM);
+ if (RT_NULL == p) {
+ rt_kprintf("DaVinci EMAC: failed to alloc pbuf\n");
+ return RT_NULL;
+ }
- /* set device pointer in p and reserve space for extra bytes */
- *data_token = (void *) p;
- EMAC_CACHE_WRITEBACK_INVALIDATE((unsigned long)p->payload, buf_size);
- return p->payload;
+ /* set device pointer in p and reserve space for extra bytes */
+ *data_token = (void *) p;
+ EMAC_CACHE_WRITEBACK_INVALIDATE((unsigned long)p->payload, buf_size);
+ return p->payload;
}
@@ -857,160 +857,160 @@ static void *emac_net_alloc_rx_buf(struct emac_priv *priv, int buf_size,
*/
static int emac_rx_bdproc(struct emac_priv *priv, rt_uint32_t ch, rt_uint32_t budget)
{
- unsigned long flags;
- rt_uint32_t frame_status;
- rt_uint32_t pkts_processed = 0;
- char *new_buffer;
- struct emac_rx_bd __iomem *curr_bd;
- struct emac_rx_bd __iomem *last_bd;
- struct emac_netpktobj *curr_pkt, pkt_obj;
- struct emac_netbufobj buf_obj;
- struct emac_netbufobj *rx_buf_obj;
- void *new_buf_token;
- struct emac_rxch *rxch = priv->rxch[ch];
+ unsigned long flags;
+ rt_uint32_t frame_status;
+ rt_uint32_t pkts_processed = 0;
+ char *new_buffer;
+ struct emac_rx_bd __iomem *curr_bd;
+ struct emac_rx_bd __iomem *last_bd;
+ struct emac_netpktobj *curr_pkt, pkt_obj;
+ struct emac_netbufobj buf_obj;
+ struct emac_netbufobj *rx_buf_obj;
+ void *new_buf_token;
+ struct emac_rxch *rxch = priv->rxch[ch];
- if (1 == rxch->teardown_pending)
- return 0;
- ++rxch->proc_count;
- rt_sem_take(&priv->rx_lock, RT_WAITING_FOREVER);
- pkt_obj.buf_list = &buf_obj;
- curr_pkt = &pkt_obj;
- curr_bd = rxch->active_queue_head;
- BD_CACHE_INVALIDATE(curr_bd, EMAC_BD_LENGTH_FOR_CACHE);
- frame_status = curr_bd->mode;
+ if (1 == rxch->teardown_pending)
+ return 0;
+ ++rxch->proc_count;
+ rt_sem_take(&priv->rx_lock, RT_WAITING_FOREVER);
+ pkt_obj.buf_list = &buf_obj;
+ curr_pkt = &pkt_obj;
+ curr_bd = rxch->active_queue_head;
+ BD_CACHE_INVALIDATE(curr_bd, EMAC_BD_LENGTH_FOR_CACHE);
+ frame_status = curr_bd->mode;
- while ((curr_bd) &&
- ((frame_status & EMAC_CPPI_OWNERSHIP_BIT) == 0) &&
- (pkts_processed < budget)) {
+ while ((curr_bd) &&
+ ((frame_status & EMAC_CPPI_OWNERSHIP_BIT) == 0) &&
+ (pkts_processed < budget)) {
- new_buffer = emac_net_alloc_rx_buf(priv, rxch->buf_size,
- &new_buf_token, EMAC_DEF_RX_CH);
- if (RT_NULL == new_buffer) {
- ++rxch->out_of_rx_buffers;
- goto end_emac_rx_bdproc;
- }
+ new_buffer = emac_net_alloc_rx_buf(priv, rxch->buf_size,
+ &new_buf_token, EMAC_DEF_RX_CH);
+ if (RT_NULL == new_buffer) {
+ ++rxch->out_of_rx_buffers;
+ goto end_emac_rx_bdproc;
+ }
- /* populate received packet data structure */
- rx_buf_obj = &curr_pkt->buf_list[0];
- rx_buf_obj->data_ptr = (char *)curr_bd->data_ptr;
- rx_buf_obj->length = curr_bd->off_b_len & EMAC_RX_BD_BUF_SIZE;
- rx_buf_obj->buf_token = curr_bd->buf_token;
- curr_pkt->pkt_token = curr_pkt->buf_list->buf_token;
- curr_pkt->num_bufs = 1;
- curr_pkt->pkt_length =
- (frame_status & EMAC_RX_BD_PKT_LENGTH_MASK);
- emac_write(EMAC_RXCP(ch), emac_virt_to_phys(curr_bd));
- ++rxch->processed_bd;
- last_bd = curr_bd;
- curr_bd = last_bd->next;
- rxch->active_queue_head = curr_bd;
+ /* populate received packet data structure */
+ rx_buf_obj = &curr_pkt->buf_list[0];
+ rx_buf_obj->data_ptr = (char *)curr_bd->data_ptr;
+ rx_buf_obj->length = curr_bd->off_b_len & EMAC_RX_BD_BUF_SIZE;
+ rx_buf_obj->buf_token = curr_bd->buf_token;
+ curr_pkt->pkt_token = curr_pkt->buf_list->buf_token;
+ curr_pkt->num_bufs = 1;
+ curr_pkt->pkt_length =
+ (frame_status & EMAC_RX_BD_PKT_LENGTH_MASK);
+ emac_write(EMAC_RXCP(ch), emac_virt_to_phys(curr_bd));
+ ++rxch->processed_bd;
+ last_bd = curr_bd;
+ curr_bd = last_bd->next;
+ rxch->active_queue_head = curr_bd;
- /* check if end of RX queue ? */
- if (frame_status & EMAC_CPPI_EOQ_BIT) {
- if (curr_bd) {
- ++rxch->mis_queued_packets;
- emac_write(EMAC_RXHDP(ch),
- emac_virt_to_phys(curr_bd));
- } else {
- ++rxch->end_of_queue;
- rxch->queue_active = 0;
- }
- }
+ /* check if end of RX queue ? */
+ if (frame_status & EMAC_CPPI_EOQ_BIT) {
+ if (curr_bd) {
+ ++rxch->mis_queued_packets;
+ emac_write(EMAC_RXHDP(ch),
+ emac_virt_to_phys(curr_bd));
+ } else {
+ ++rxch->end_of_queue;
+ rxch->queue_active = 0;
+ }
+ }
- /* recycle BD */
- emac_addbd_to_rx_queue(priv, ch, last_bd, new_buffer,
- new_buf_token);
+ /* recycle BD */
+ emac_addbd_to_rx_queue(priv, ch, last_bd, new_buffer,
+ new_buf_token);
- /* return the packet to the user - BD ptr passed in
- * last parameter for potential *future* use */
- rt_sem_release(&priv->rx_lock);
- emac_net_rx_cb(priv, curr_pkt);//???
- rt_sem_take(&priv->rx_lock, RT_WAITING_FOREVER);
- curr_bd = rxch->active_queue_head;
- if (curr_bd) {
- BD_CACHE_INVALIDATE(curr_bd, EMAC_BD_LENGTH_FOR_CACHE);
- frame_status = curr_bd->mode;
- }
- ++pkts_processed;
- }
+ /* return the packet to the user - BD ptr passed in
+ * last parameter for potential *future* use */
+ rt_sem_release(&priv->rx_lock);
+ emac_net_rx_cb(priv, curr_pkt);//???
+ rt_sem_take(&priv->rx_lock, RT_WAITING_FOREVER);
+ curr_bd = rxch->active_queue_head;
+ if (curr_bd) {
+ BD_CACHE_INVALIDATE(curr_bd, EMAC_BD_LENGTH_FOR_CACHE);
+ frame_status = curr_bd->mode;
+ }
+ ++pkts_processed;
+ }
end_emac_rx_bdproc:
- rt_sem_release(&priv->rx_lock);
- return pkts_processed;
+ rt_sem_release(&priv->rx_lock);
+ return pkts_processed;
}
/* reception packet. */
struct pbuf *rt_davinci_emac_rx(rt_device_t dev)
{
- struct emac_priv *priv = dev->user_data;
- struct pbuf* p = RT_NULL;
- rt_uint32_t len;
- void *buffer;
+ struct emac_priv *priv = dev->user_data;
+ struct pbuf* p = RT_NULL;
+ rt_uint32_t len;
+ void *buffer;
- struct pbuf* q;
- rt_uint8_t *buf = RT_NULL;
- unsigned int mask;
- rt_uint32_t status = 0;
- rt_uint32_t num_pkts = 0;
+ struct pbuf* q;
+ rt_uint8_t *buf = RT_NULL;
+ unsigned int mask;
+ rt_uint32_t status = 0;
+ rt_uint32_t num_pkts = 0;
- /* Check interrupt vectors and call packet processing */
- status = emac_read(EMAC_MACINVECTOR);
+ /* Check interrupt vectors and call packet processing */
+ status = emac_read(EMAC_MACINVECTOR);
- mask = EMAC_DM644X_MAC_IN_VECTOR_TX_INT_VEC;
+ mask = EMAC_DM644X_MAC_IN_VECTOR_TX_INT_VEC;
- if (priv->version == EMAC_VERSION_2)
- mask = EMAC_DM646X_MAC_IN_VECTOR_TX_INT_VEC;
+ if (priv->version == EMAC_VERSION_2)
+ mask = EMAC_DM646X_MAC_IN_VECTOR_TX_INT_VEC;
- if (status & mask) {
- num_pkts = emac_tx_bdproc(priv, EMAC_DEF_TX_CH,
- EMAC_DEF_TX_MAX_SERVICE);
- } /* TX processing */
+ if (status & mask) {
+ num_pkts = emac_tx_bdproc(priv, EMAC_DEF_TX_CH,
+ EMAC_DEF_TX_MAX_SERVICE);
+ } /* TX processing */
- /*if (num_pkts)
- //return budget;
- return RT_NULL;*/
+ /*if (num_pkts)
+ //return budget;
+ return RT_NULL;*/
- mask = EMAC_DM644X_MAC_IN_VECTOR_RX_INT_VEC;
+ mask = EMAC_DM644X_MAC_IN_VECTOR_RX_INT_VEC;
- if (priv->version == EMAC_VERSION_2)
- mask = EMAC_DM646X_MAC_IN_VECTOR_RX_INT_VEC;
+ if (priv->version == EMAC_VERSION_2)
+ mask = EMAC_DM646X_MAC_IN_VECTOR_RX_INT_VEC;
- if (status & mask) {
- num_pkts = emac_rx_bdproc(priv, EMAC_DEF_RX_CH, EMAC_DEF_RX_MAX_SERVICE);
- } /* RX processing */
+ if (status & mask) {
+ num_pkts = emac_rx_bdproc(priv, EMAC_DEF_RX_CH, EMAC_DEF_RX_MAX_SERVICE);
+ } /* RX processing */
- /*if (num_pkts < EMAC_DEF_RX_MAX_SERVICE) {
- emac_int_enable(priv);
- }*/
+ /*if (num_pkts < EMAC_DEF_RX_MAX_SERVICE) {
+ emac_int_enable(priv);
+ }*/
- mask = EMAC_DM644X_MAC_IN_VECTOR_HOST_INT;
- if (priv->version == EMAC_VERSION_2)
- mask = EMAC_DM646X_MAC_IN_VECTOR_HOST_INT;
+ mask = EMAC_DM644X_MAC_IN_VECTOR_HOST_INT;
+ if (priv->version == EMAC_VERSION_2)
+ mask = EMAC_DM646X_MAC_IN_VECTOR_HOST_INT;
- if (status & mask) {
- rt_uint32_t ch, cause;
- rt_kprintf("DaVinci EMAC: Fatal Hardware Error\n");
+ if (status & mask) {
+ rt_uint32_t ch, cause;
+ rt_kprintf("DaVinci EMAC: Fatal Hardware Error\n");
- status = emac_read(EMAC_MACSTATUS);
- cause = ((status & EMAC_MACSTATUS_TXERRCODE_MASK) >>
- EMAC_MACSTATUS_TXERRCODE_SHIFT);
- if (cause) {
- ch = ((status & EMAC_MACSTATUS_TXERRCH_MASK) >>
- EMAC_MACSTATUS_TXERRCH_SHIFT);
- }
- cause = ((status & EMAC_MACSTATUS_RXERRCODE_MASK) >>
- EMAC_MACSTATUS_RXERRCODE_SHIFT);
- if (cause) {
- ch = ((status & EMAC_MACSTATUS_RXERRCH_MASK) >>
- EMAC_MACSTATUS_RXERRCH_SHIFT);
- }
- } /* Host error processing */
+ status = emac_read(EMAC_MACSTATUS);
+ cause = ((status & EMAC_MACSTATUS_TXERRCODE_MASK) >>
+ EMAC_MACSTATUS_TXERRCODE_SHIFT);
+ if (cause) {
+ ch = ((status & EMAC_MACSTATUS_TXERRCH_MASK) >>
+ EMAC_MACSTATUS_TXERRCH_SHIFT);
+ }
+ cause = ((status & EMAC_MACSTATUS_RXERRCODE_MASK) >>
+ EMAC_MACSTATUS_RXERRCODE_SHIFT);
+ if (cause) {
+ ch = ((status & EMAC_MACSTATUS_RXERRCH_MASK) >>
+ EMAC_MACSTATUS_RXERRCH_SHIFT);
+ }
+ } /* Host error processing */
- //return num_pkts;
- //return p;
- emac_int_enable(priv);
- return RT_NULL;
+ //return num_pkts;
+ //return p;
+ emac_int_enable(priv);
+ return RT_NULL;
}
@@ -1026,19 +1026,19 @@ struct pbuf *rt_davinci_emac_rx(rt_device_t dev)
*/
static void emac_set_type0addr(struct emac_priv *priv, rt_uint32_t ch, char *mac_addr)
{
- rt_uint32_t val;
- val = ((mac_addr[5] << 8) | (mac_addr[4]));
- emac_write(EMAC_MACSRCADDRLO, val);
+ rt_uint32_t val;
+ val = ((mac_addr[5] << 8) | (mac_addr[4]));
+ emac_write(EMAC_MACSRCADDRLO, val);
- val = ((mac_addr[3] << 24) | (mac_addr[2] << 16) | \
- (mac_addr[1] << 8) | (mac_addr[0]));
- emac_write(EMAC_MACSRCADDRHI, val);
- val = emac_read(EMAC_RXUNICASTSET);
- val |= BIT(ch);
- emac_write(EMAC_RXUNICASTSET, val);
- val = emac_read(EMAC_RXUNICASTCLEAR);
- val &= ~BIT(ch);
- emac_write(EMAC_RXUNICASTCLEAR, val);
+ val = ((mac_addr[3] << 24) | (mac_addr[2] << 16) | \
+ (mac_addr[1] << 8) | (mac_addr[0]));
+ emac_write(EMAC_MACSRCADDRHI, val);
+ val = emac_read(EMAC_RXUNICASTSET);
+ val |= BIT(ch);
+ emac_write(EMAC_RXUNICASTSET, val);
+ val = emac_read(EMAC_RXUNICASTCLEAR);
+ val &= ~BIT(ch);
+ emac_write(EMAC_RXUNICASTCLEAR, val);
}
/**
@@ -1053,14 +1053,14 @@ static void emac_set_type0addr(struct emac_priv *priv, rt_uint32_t ch, char *mac
*/
static void emac_set_type1addr(struct emac_priv *priv, rt_uint32_t ch, char *mac_addr)
{
- rt_uint32_t val;
- emac_write(EMAC_MACINDEX, ch);
- val = ((mac_addr[5] << 8) | mac_addr[4]);
- emac_write(EMAC_MACADDRLO, val);
- val = ((mac_addr[3] << 24) | (mac_addr[2] << 16) | \
- (mac_addr[1] << 8) | (mac_addr[0]));
- emac_write(EMAC_MACADDRHI, val);
- emac_set_type0addr(priv, ch, mac_addr);
+ rt_uint32_t val;
+ emac_write(EMAC_MACINDEX, ch);
+ val = ((mac_addr[5] << 8) | mac_addr[4]);
+ emac_write(EMAC_MACADDRLO, val);
+ val = ((mac_addr[3] << 24) | (mac_addr[2] << 16) | \
+ (mac_addr[1] << 8) | (mac_addr[0]));
+ emac_write(EMAC_MACADDRHI, val);
+ emac_set_type0addr(priv, ch, mac_addr);
}
/**
@@ -1076,17 +1076,17 @@ static void emac_set_type1addr(struct emac_priv *priv, rt_uint32_t ch, char *mac
* Returns success (0) or appropriate error code (none as of now)
*/
static void emac_set_type2addr(struct emac_priv *priv, rt_uint32_t ch,
- char *mac_addr, int index, int match)
+ char *mac_addr, int index, int match)
{
- rt_uint32_t val;
- emac_write(EMAC_MACINDEX, index);
- val = ((mac_addr[3] << 24) | (mac_addr[2] << 16) | \
- (mac_addr[1] << 8) | (mac_addr[0]));
- emac_write(EMAC_MACADDRHI, val);
- val = ((mac_addr[5] << 8) | mac_addr[4] | ((ch & 0x7) << 16) | \
- (match << 19) | BIT(20));
- emac_write(EMAC_MACADDRLO, val);
- emac_set_type0addr(priv, ch, mac_addr);
+ rt_uint32_t val;
+ emac_write(EMAC_MACINDEX, index);
+ val = ((mac_addr[3] << 24) | (mac_addr[2] << 16) | \
+ (mac_addr[1] << 8) | (mac_addr[0]));
+ emac_write(EMAC_MACADDRHI, val);
+ val = ((mac_addr[5] << 8) | mac_addr[4] | ((ch & 0x7) << 16) | \
+ (match << 19) | BIT(20));
+ emac_write(EMAC_MACADDRLO, val);
+ emac_set_type0addr(priv, ch, mac_addr);
}
/**
@@ -1101,18 +1101,18 @@ static void emac_set_type2addr(struct emac_priv *priv, rt_uint32_t ch,
*/
static void emac_setmac(struct emac_priv *priv, rt_uint32_t ch, char *mac_addr)
{
- if (priv->rx_addr_type == 0) {
- emac_set_type0addr(priv, ch, mac_addr);
- } else if (priv->rx_addr_type == 1) {
- rt_uint32_t cnt;
- for (cnt = 0; cnt < EMAC_MAX_TXRX_CHANNELS; cnt++)
- emac_set_type1addr(priv, ch, mac_addr);
- } else if (priv->rx_addr_type == 2) {
- emac_set_type2addr(priv, ch, mac_addr, ch, 1);
- emac_set_type0addr(priv, ch, mac_addr);
- } else {
- rt_kprintf("DaVinci EMAC: Wrong addressing\n");
- }
+ if (priv->rx_addr_type == 0) {
+ emac_set_type0addr(priv, ch, mac_addr);
+ } else if (priv->rx_addr_type == 1) {
+ rt_uint32_t cnt;
+ for (cnt = 0; cnt < EMAC_MAX_TXRX_CHANNELS; cnt++)
+ emac_set_type1addr(priv, ch, mac_addr);
+ } else if (priv->rx_addr_type == 2) {
+ emac_set_type2addr(priv, ch, mac_addr, ch, 1);
+ emac_set_type0addr(priv, ch, mac_addr);
+ } else {
+ rt_kprintf("DaVinci EMAC: Wrong addressing\n");
+ }
}
@@ -1125,9 +1125,9 @@ static void emac_setmac(struct emac_priv *priv, rt_uint32_t ch, char *mac_addr)
* pointer to the memory
*
*/
-#define EMAC_TX_BD_MEM(priv) ((priv)->emac_ctrl_ram)
-#define EMAC_RX_BD_MEM(priv) ((priv)->emac_ctrl_ram + \
- (((priv)->ctrl_ram_size) >> 1))
+#define EMAC_TX_BD_MEM(priv) ((priv)->emac_ctrl_ram)
+#define EMAC_RX_BD_MEM(priv) ((priv)->emac_ctrl_ram + \
+ (((priv)->ctrl_ram_size) >> 1))
/**
* emac_init_txch: TX channel initialization
@@ -1141,59 +1141,59 @@ static void emac_setmac(struct emac_priv *priv, rt_uint32_t ch, char *mac_addr)
*/
static int emac_init_txch(struct emac_priv *priv, rt_uint32_t ch)
{
- rt_uint32_t cnt, bd_size;
- void __iomem *mem;
- struct emac_tx_bd __iomem *curr_bd;
- struct emac_txch *txch = RT_NULL;
+ rt_uint32_t cnt, bd_size;
+ void __iomem *mem;
+ struct emac_tx_bd __iomem *curr_bd;
+ struct emac_txch *txch = RT_NULL;
- txch = rt_malloc(sizeof(struct emac_txch));
- if (RT_NULL == txch) {
- rt_kprintf("DaVinci EMAC: TX Ch mem alloc failed");
- return -RT_ENOMEM;
- }
- rt_memset(txch, 0, sizeof(struct emac_txch));
- priv->txch[ch] = txch;
- txch->service_max = EMAC_DEF_TX_MAX_SERVICE;
- txch->active_queue_head = RT_NULL;
- txch->active_queue_tail = RT_NULL;
- txch->queue_active = 0;
- txch->teardown_pending = 0;
+ txch = rt_malloc(sizeof(struct emac_txch));
+ if (RT_NULL == txch) {
+ rt_kprintf("DaVinci EMAC: TX Ch mem alloc failed");
+ return -RT_ENOMEM;
+ }
+ rt_memset(txch, 0, sizeof(struct emac_txch));
+ priv->txch[ch] = txch;
+ txch->service_max = EMAC_DEF_TX_MAX_SERVICE;
+ txch->active_queue_head = RT_NULL;
+ txch->active_queue_tail = RT_NULL;
+ txch->queue_active = 0;
+ txch->teardown_pending = 0;
- /* allocate memory for TX CPPI channel on a 4 byte boundry */
- txch->tx_complete = rt_malloc(txch->service_max * sizeof(rt_uint32_t));
- if (RT_NULL == txch->tx_complete) {
- rt_kprintf("DaVinci EMAC: Tx service mem alloc failed");
- rt_free(txch);
- return -RT_ENOMEM;
- }
- memset(txch->tx_complete, 0, txch->service_max * sizeof(rt_uint32_t));
+ /* allocate memory for TX CPPI channel on a 4 byte boundry */
+ txch->tx_complete = rt_malloc(txch->service_max * sizeof(rt_uint32_t));
+ if (RT_NULL == txch->tx_complete) {
+ rt_kprintf("DaVinci EMAC: Tx service mem alloc failed");
+ rt_free(txch);
+ return -RT_ENOMEM;
+ }
+ memset(txch->tx_complete, 0, txch->service_max * sizeof(rt_uint32_t));
- /* allocate buffer descriptor pool align every BD on four word
- * boundry for future requirements */
- bd_size = (sizeof(struct emac_tx_bd) + 0xF) & ~0xF;
- txch->num_bd = (priv->ctrl_ram_size >> 1) / bd_size;
- txch->alloc_size = (((bd_size * txch->num_bd) + 0xF) & ~0xF);
+ /* allocate buffer descriptor pool align every BD on four word
+ * boundry for future requirements */
+ bd_size = (sizeof(struct emac_tx_bd) + 0xF) & ~0xF;
+ txch->num_bd = (priv->ctrl_ram_size >> 1) / bd_size;
+ txch->alloc_size = (((bd_size * txch->num_bd) + 0xF) & ~0xF);
- /* alloc TX BD memory */
- txch->bd_mem = EMAC_TX_BD_MEM(priv);
- rt_memset((void *)txch->bd_mem, 0, txch->alloc_size);
+ /* alloc TX BD memory */
+ txch->bd_mem = EMAC_TX_BD_MEM(priv);
+ rt_memset((void *)txch->bd_mem, 0, txch->alloc_size);
- /* initialize the BD linked list */
- mem = (void __iomem *)
- (((rt_uint32_t) txch->bd_mem + 0xF) & ~0xF);
- txch->bd_pool_head = RT_NULL;
- for (cnt = 0; cnt < txch->num_bd; cnt++) {
- curr_bd = mem + (cnt * bd_size);
- curr_bd->next = txch->bd_pool_head;
- txch->bd_pool_head = curr_bd;
- }
+ /* initialize the BD linked list */
+ mem = (void __iomem *)
+ (((rt_uint32_t) txch->bd_mem + 0xF) & ~0xF);
+ txch->bd_pool_head = RT_NULL;
+ for (cnt = 0; cnt < txch->num_bd; cnt++) {
+ curr_bd = mem + (cnt * bd_size);
+ curr_bd->next = txch->bd_pool_head;
+ txch->bd_pool_head = curr_bd;
+ }
- /* reset statistics counters */
- txch->out_of_tx_bd = 0;
- txch->no_active_pkts = 0;
- txch->active_queue_count = 0;
+ /* reset statistics counters */
+ txch->out_of_tx_bd = 0;
+ txch->no_active_pkts = 0;
+ txch->active_queue_count = 0;
- return 0;
+ return 0;
}
/**
@@ -1209,74 +1209,74 @@ static int emac_init_txch(struct emac_priv *priv, rt_uint32_t ch)
*/
static int emac_init_rxch(struct emac_priv *priv, rt_uint32_t ch, char *param)
{
- rt_uint32_t cnt, bd_size;
- void __iomem *mem;
- struct emac_rx_bd __iomem *curr_bd;
- struct emac_rxch *rxch = RT_NULL;
+ rt_uint32_t cnt, bd_size;
+ void __iomem *mem;
+ struct emac_rx_bd __iomem *curr_bd;
+ struct emac_rxch *rxch = RT_NULL;
- rxch = rt_malloc(sizeof(struct emac_rxch));
- if (RT_NULL == rxch) {
- rt_kprintf("DaVinci EMAC: RX Ch mem alloc failed");
- return -ENOMEM;
- }
- rt_memset(rxch, 0, sizeof(struct emac_rxch));
- priv->rxch[ch] = rxch;
- rxch->buf_size = priv->rx_buf_size;
- rxch->service_max = EMAC_DEF_RX_MAX_SERVICE;
- rxch->queue_active = 0;
- rxch->teardown_pending = 0;
+ rxch = rt_malloc(sizeof(struct emac_rxch));
+ if (RT_NULL == rxch) {
+ rt_kprintf("DaVinci EMAC: RX Ch mem alloc failed");
+ return -ENOMEM;
+ }
+ rt_memset(rxch, 0, sizeof(struct emac_rxch));
+ priv->rxch[ch] = rxch;
+ rxch->buf_size = priv->rx_buf_size;
+ rxch->service_max = EMAC_DEF_RX_MAX_SERVICE;
+ rxch->queue_active = 0;
+ rxch->teardown_pending = 0;
- /* save mac address */
- for (cnt = 0; cnt < 6; cnt++)
- rxch->mac_addr[cnt] = param[cnt];
+ /* save mac address */
+ for (cnt = 0; cnt < 6; cnt++)
+ rxch->mac_addr[cnt] = param[cnt];
- /* allocate buffer descriptor pool align every BD on four word
- * boundry for future requirements */
- bd_size = (sizeof(struct emac_rx_bd) + 0xF) & ~0xF;
- rxch->num_bd = (priv->ctrl_ram_size >> 1) / bd_size;
- rxch->alloc_size = (((bd_size * rxch->num_bd) + 0xF) & ~0xF);
- rxch->bd_mem = EMAC_RX_BD_MEM(priv);
+ /* allocate buffer descriptor pool align every BD on four word
+ * boundry for future requirements */
+ bd_size = (sizeof(struct emac_rx_bd) + 0xF) & ~0xF;
+ rxch->num_bd = (priv->ctrl_ram_size >> 1) / bd_size;
+ rxch->alloc_size = (((bd_size * rxch->num_bd) + 0xF) & ~0xF);
+ rxch->bd_mem = EMAC_RX_BD_MEM(priv);
- rt_memset((void *)rxch->bd_mem, 0, rxch->alloc_size);
- rxch->pkt_queue.buf_list = &rxch->buf_queue;
+ rt_memset((void *)rxch->bd_mem, 0, rxch->alloc_size);
+ rxch->pkt_queue.buf_list = &rxch->buf_queue;
- /* allocate RX buffer and initialize the BD linked list */
- mem = (void __iomem *)
- (((rt_uint32_t) rxch->bd_mem + 0xF) & ~0xF);
- rxch->active_queue_head = RT_NULL;
- rxch->active_queue_tail = mem;
- for (cnt = 0; cnt < rxch->num_bd; cnt++) {
- curr_bd = mem + (cnt * bd_size);
- /* for future use the last parameter contains the BD ptr */
- curr_bd->data_ptr = emac_net_alloc_rx_buf(priv,
- rxch->buf_size,
- (void **)&curr_bd->buf_token,
- EMAC_DEF_RX_CH);
- if (curr_bd->data_ptr == RT_NULL) {
- rt_kprintf("DaVinci EMAC: RX buf mem alloc " \
- "failed for ch %d\n", ch);
- rt_free(rxch);
- return -RT_ENOMEM;
- }
+ /* allocate RX buffer and initialize the BD linked list */
+ mem = (void __iomem *)
+ (((rt_uint32_t) rxch->bd_mem + 0xF) & ~0xF);
+ rxch->active_queue_head = RT_NULL;
+ rxch->active_queue_tail = mem;
+ for (cnt = 0; cnt < rxch->num_bd; cnt++) {
+ curr_bd = mem + (cnt * bd_size);
+ /* for future use the last parameter contains the BD ptr */
+ curr_bd->data_ptr = emac_net_alloc_rx_buf(priv,
+ rxch->buf_size,
+ (void **)&curr_bd->buf_token,
+ EMAC_DEF_RX_CH);
+ if (curr_bd->data_ptr == RT_NULL) {
+ rt_kprintf("DaVinci EMAC: RX buf mem alloc " \
+ "failed for ch %d\n", ch);
+ rt_free(rxch);
+ return -RT_ENOMEM;
+ }
- /* populate the hardware descriptor */
- curr_bd->h_next = emac_virt_to_phys(rxch->active_queue_head);
- curr_bd->buff_ptr = virt_to_phys(curr_bd->data_ptr);
- curr_bd->off_b_len = rxch->buf_size;
- curr_bd->mode = EMAC_CPPI_OWNERSHIP_BIT;
+ /* populate the hardware descriptor */
+ curr_bd->h_next = emac_virt_to_phys(rxch->active_queue_head);
+ curr_bd->buff_ptr = virt_to_phys(curr_bd->data_ptr);
+ curr_bd->off_b_len = rxch->buf_size;
+ curr_bd->mode = EMAC_CPPI_OWNERSHIP_BIT;
- /* write back to hardware memory */
- BD_CACHE_WRITEBACK_INVALIDATE((rt_uint32_t) curr_bd,
- EMAC_BD_LENGTH_FOR_CACHE);
- curr_bd->next = rxch->active_queue_head;
- rxch->active_queue_head = curr_bd;
- }
+ /* write back to hardware memory */
+ BD_CACHE_WRITEBACK_INVALIDATE((rt_uint32_t) curr_bd,
+ EMAC_BD_LENGTH_FOR_CACHE);
+ curr_bd->next = rxch->active_queue_head;
+ rxch->active_queue_head = curr_bd;
+ }
- /* At this point rxCppi->activeQueueHead points to the first
- RX BD ready to be given to RX HDP and rxch->active_queue_tail
- points to the last RX BD
- */
- return 0;
+ /* At this point rxCppi->activeQueueHead points to the first
+ RX BD ready to be given to RX HDP and rxch->active_queue_tail
+ points to the last RX BD
+ */
+ return 0;
}
@@ -1289,23 +1289,23 @@ static int emac_init_rxch(struct emac_priv *priv, rt_uint32_t ch, char *param)
*/
static void emac_int_disable(struct emac_priv *priv)
{
- if (priv->version == EMAC_VERSION_2) {
- unsigned long flags;
+ if (priv->version == EMAC_VERSION_2) {
+ unsigned long flags;
- rt_interrupt_enter();
+ rt_interrupt_enter();
- /* Program C0_Int_En to zero to turn off
- * interrupts to the CPU */
- emac_ctrl_write(EMAC_DM646X_CMRXINTEN, 0x0);
- emac_ctrl_write(EMAC_DM646X_CMTXINTEN, 0x0);
- /* NOTE: Rx Threshold and Misc interrupts are not disabled */
+ /* Program C0_Int_En to zero to turn off
+ * interrupts to the CPU */
+ emac_ctrl_write(EMAC_DM646X_CMRXINTEN, 0x0);
+ emac_ctrl_write(EMAC_DM646X_CMTXINTEN, 0x0);
+ /* NOTE: Rx Threshold and Misc interrupts are not disabled */
- rt_interrupt_leave();
+ rt_interrupt_leave();
- } else {
- /* Set DM644x control registers for interrupt control */
- emac_ctrl_write(EMAC_CTRL_EWCTL, 0x0);
- }
+ } else {
+ /* Set DM644x control registers for interrupt control */
+ emac_ctrl_write(EMAC_CTRL_EWCTL, 0x0);
+ }
}
@@ -1318,31 +1318,31 @@ static void emac_int_disable(struct emac_priv *priv)
*/
static void emac_int_enable(struct emac_priv *priv)
{
- if (priv->version == EMAC_VERSION_2) {
- /*if (priv->int_enable)
- priv->int_enable();*/
+ if (priv->version == EMAC_VERSION_2) {
+ /*if (priv->int_enable)
+ priv->int_enable();*/
- emac_ctrl_write(EMAC_DM646X_CMRXINTEN, 0xff);
- emac_ctrl_write(EMAC_DM646X_CMTXINTEN, 0xff);
+ emac_ctrl_write(EMAC_DM646X_CMRXINTEN, 0xff);
+ emac_ctrl_write(EMAC_DM646X_CMTXINTEN, 0xff);
- /* In addition to turning on interrupt Enable, we need
- * ack by writing appropriate values to the EOI
- * register */
+ /* In addition to turning on interrupt Enable, we need
+ * ack by writing appropriate values to the EOI
+ * register */
- /* NOTE: Rx Threshold and Misc interrupts are not enabled */
+ /* NOTE: Rx Threshold and Misc interrupts are not enabled */
- /* ack rxen only then a new pulse will be generated */
- emac_write(EMAC_DM646X_MACEOIVECTOR,
- EMAC_DM646X_MAC_EOI_C0_RXEN);
+ /* ack rxen only then a new pulse will be generated */
+ emac_write(EMAC_DM646X_MACEOIVECTOR,
+ EMAC_DM646X_MAC_EOI_C0_RXEN);
- /* ack txen- only then a new pulse will be generated */
- emac_write(EMAC_DM646X_MACEOIVECTOR,
- EMAC_DM646X_MAC_EOI_C0_TXEN);
+ /* ack txen- only then a new pulse will be generated */
+ emac_write(EMAC_DM646X_MACEOIVECTOR,
+ EMAC_DM646X_MAC_EOI_C0_TXEN);
- } else {
- /* Set DM644x control registers for interrupt control */
- emac_ctrl_write(EMAC_CTRL_EWCTL, 0x1);
- }
+ } else {
+ /* Set DM644x control registers for interrupt control */
+ emac_ctrl_write(EMAC_CTRL_EWCTL, 0x1);
+ }
}
@@ -1354,11 +1354,11 @@ static void emac_int_enable(struct emac_priv *priv)
*/
static void emac_irq(int irq, void *param)
{
- struct emac_priv *priv = param;
+ struct emac_priv *priv = param;
- ++priv->isr_count;
- emac_int_disable(priv);
- eth_device_ready(&priv->parent);
+ ++priv->isr_count;
+ emac_int_disable(priv);
+ eth_device_ready(&priv->parent);
}
@@ -1374,77 +1374,77 @@ static void emac_irq(int irq, void *param)
*/
static int emac_hw_enable(struct emac_priv *priv)
{
- rt_uint32_t ch, val, mbp_enable, mac_control;
+ rt_uint32_t ch, val, mbp_enable, mac_control;
- /* Soft reset */
- emac_write(EMAC_SOFTRESET, 1);
- while (emac_read(EMAC_SOFTRESET));
+ /* Soft reset */
+ emac_write(EMAC_SOFTRESET, 1);
+ while (emac_read(EMAC_SOFTRESET));
- /* Disable interrupt & Set pacing for more interrupts initially */
- emac_int_disable(priv);
+ /* Disable interrupt & Set pacing for more interrupts initially */
+ emac_int_disable(priv);
- /* Full duplex enable bit set when auto negotiation happens */
- mac_control =
- (((EMAC_DEF_TXPRIO_FIXED) ? (EMAC_MACCONTROL_TXPTYPE) : 0x0) |
- ((priv->speed == 1000) ? EMAC_MACCONTROL_GIGABITEN : 0x0) |
- ((EMAC_DEF_TXPACING_EN) ? (EMAC_MACCONTROL_TXPACEEN) : 0x0) |
- ((priv->duplex == DUPLEX_FULL) ? 0x1 : 0));
- emac_write(EMAC_MACCONTROL, mac_control);
+ /* Full duplex enable bit set when auto negotiation happens */
+ mac_control =
+ (((EMAC_DEF_TXPRIO_FIXED) ? (EMAC_MACCONTROL_TXPTYPE) : 0x0) |
+ ((priv->speed == 1000) ? EMAC_MACCONTROL_GIGABITEN : 0x0) |
+ ((EMAC_DEF_TXPACING_EN) ? (EMAC_MACCONTROL_TXPACEEN) : 0x0) |
+ ((priv->duplex == DUPLEX_FULL) ? 0x1 : 0));
+ emac_write(EMAC_MACCONTROL, mac_control);
- mbp_enable =
- (((EMAC_DEF_PASS_CRC) ? (EMAC_RXMBP_PASSCRC_MASK) : 0x0) |
- ((EMAC_DEF_QOS_EN) ? (EMAC_RXMBP_QOSEN_MASK) : 0x0) |
- ((EMAC_DEF_NO_BUFF_CHAIN) ? (EMAC_RXMBP_NOCHAIN_MASK) : 0x0) |
- ((EMAC_DEF_MACCTRL_FRAME_EN) ? (EMAC_RXMBP_CMFEN_MASK) : 0x0) |
- ((EMAC_DEF_SHORT_FRAME_EN) ? (EMAC_RXMBP_CSFEN_MASK) : 0x0) |
- ((EMAC_DEF_ERROR_FRAME_EN) ? (EMAC_RXMBP_CEFEN_MASK) : 0x0) |
- ((EMAC_DEF_PROM_EN) ? (EMAC_RXMBP_CAFEN_MASK) : 0x0) |
- ((EMAC_DEF_PROM_CH & EMAC_RXMBP_CHMASK) << \
- EMAC_RXMBP_PROMCH_SHIFT) |
- ((EMAC_DEF_BCAST_EN) ? (EMAC_RXMBP_BROADEN_MASK) : 0x0) |
- ((EMAC_DEF_BCAST_CH & EMAC_RXMBP_CHMASK) << \
- EMAC_RXMBP_BROADCH_SHIFT) |
- ((EMAC_DEF_MCAST_EN) ? (EMAC_RXMBP_MULTIEN_MASK) : 0x0) |
- ((EMAC_DEF_MCAST_CH & EMAC_RXMBP_CHMASK) << \
- EMAC_RXMBP_MULTICH_SHIFT));
- emac_write(EMAC_RXMBPENABLE, mbp_enable);
- emac_write(EMAC_RXMAXLEN, (EMAC_DEF_MAX_FRAME_SIZE &
- EMAC_RX_MAX_LEN_MASK));
- emac_write(EMAC_RXBUFFEROFFSET, (EMAC_DEF_BUFFER_OFFSET &
- EMAC_RX_BUFFER_OFFSET_MASK));
- emac_write(EMAC_RXFILTERLOWTHRESH, 0);
- emac_write(EMAC_RXUNICASTCLEAR, EMAC_RX_UNICAST_CLEAR_ALL);
- priv->rx_addr_type = (emac_read(EMAC_MACCONFIG) >> 8) & 0xFF;
+ mbp_enable =
+ (((EMAC_DEF_PASS_CRC) ? (EMAC_RXMBP_PASSCRC_MASK) : 0x0) |
+ ((EMAC_DEF_QOS_EN) ? (EMAC_RXMBP_QOSEN_MASK) : 0x0) |
+ ((EMAC_DEF_NO_BUFF_CHAIN) ? (EMAC_RXMBP_NOCHAIN_MASK) : 0x0) |
+ ((EMAC_DEF_MACCTRL_FRAME_EN) ? (EMAC_RXMBP_CMFEN_MASK) : 0x0) |
+ ((EMAC_DEF_SHORT_FRAME_EN) ? (EMAC_RXMBP_CSFEN_MASK) : 0x0) |
+ ((EMAC_DEF_ERROR_FRAME_EN) ? (EMAC_RXMBP_CEFEN_MASK) : 0x0) |
+ ((EMAC_DEF_PROM_EN) ? (EMAC_RXMBP_CAFEN_MASK) : 0x0) |
+ ((EMAC_DEF_PROM_CH & EMAC_RXMBP_CHMASK) << \
+ EMAC_RXMBP_PROMCH_SHIFT) |
+ ((EMAC_DEF_BCAST_EN) ? (EMAC_RXMBP_BROADEN_MASK) : 0x0) |
+ ((EMAC_DEF_BCAST_CH & EMAC_RXMBP_CHMASK) << \
+ EMAC_RXMBP_BROADCH_SHIFT) |
+ ((EMAC_DEF_MCAST_EN) ? (EMAC_RXMBP_MULTIEN_MASK) : 0x0) |
+ ((EMAC_DEF_MCAST_CH & EMAC_RXMBP_CHMASK) << \
+ EMAC_RXMBP_MULTICH_SHIFT));
+ emac_write(EMAC_RXMBPENABLE, mbp_enable);
+ emac_write(EMAC_RXMAXLEN, (EMAC_DEF_MAX_FRAME_SIZE &
+ EMAC_RX_MAX_LEN_MASK));
+ emac_write(EMAC_RXBUFFEROFFSET, (EMAC_DEF_BUFFER_OFFSET &
+ EMAC_RX_BUFFER_OFFSET_MASK));
+ emac_write(EMAC_RXFILTERLOWTHRESH, 0);
+ emac_write(EMAC_RXUNICASTCLEAR, EMAC_RX_UNICAST_CLEAR_ALL);
+ priv->rx_addr_type = (emac_read(EMAC_MACCONFIG) >> 8) & 0xFF;
- val = emac_read(EMAC_TXCONTROL);
- val |= EMAC_TX_CONTROL_TX_ENABLE_VAL;
- emac_write(EMAC_TXCONTROL, val);
- val = emac_read(EMAC_RXCONTROL);
- val |= EMAC_RX_CONTROL_RX_ENABLE_VAL;
- emac_write(EMAC_RXCONTROL, val);
- emac_write(EMAC_MACINTMASKSET, EMAC_MAC_HOST_ERR_INTMASK_VAL);
+ val = emac_read(EMAC_TXCONTROL);
+ val |= EMAC_TX_CONTROL_TX_ENABLE_VAL;
+ emac_write(EMAC_TXCONTROL, val);
+ val = emac_read(EMAC_RXCONTROL);
+ val |= EMAC_RX_CONTROL_RX_ENABLE_VAL;
+ emac_write(EMAC_RXCONTROL, val);
+ emac_write(EMAC_MACINTMASKSET, EMAC_MAC_HOST_ERR_INTMASK_VAL);
- for (ch = 0; ch < EMAC_DEF_MAX_TX_CH; ch++) {
- emac_write(EMAC_TXHDP(ch), 0);
- emac_write(EMAC_TXINTMASKSET, BIT(ch));
- }
- for (ch = 0; ch < EMAC_DEF_MAX_RX_CH; ch++) {
- struct emac_rxch *rxch = priv->rxch[ch];
- emac_setmac(priv, ch, rxch->mac_addr);
- emac_write(EMAC_RXINTMASKSET, BIT(ch));
- rxch->queue_active = 1;
- emac_write(EMAC_RXHDP(ch),
- (unsigned int)(rxch->active_queue_head)); /* physcal addr */
- }
+ for (ch = 0; ch < EMAC_DEF_MAX_TX_CH; ch++) {
+ emac_write(EMAC_TXHDP(ch), 0);
+ emac_write(EMAC_TXINTMASKSET, BIT(ch));
+ }
+ for (ch = 0; ch < EMAC_DEF_MAX_RX_CH; ch++) {
+ struct emac_rxch *rxch = priv->rxch[ch];
+ emac_setmac(priv, ch, rxch->mac_addr);
+ emac_write(EMAC_RXINTMASKSET, BIT(ch));
+ rxch->queue_active = 1;
+ emac_write(EMAC_RXHDP(ch),
+ (unsigned int)(rxch->active_queue_head)); /* physcal addr */
+ }
- /* Enable MII */
- val = emac_read(EMAC_MACCONTROL);
- val |= (EMAC_MACCONTROL_GMIIEN);
- emac_write(EMAC_MACCONTROL, val);
+ /* Enable MII */
+ val = emac_read(EMAC_MACCONTROL);
+ val |= (EMAC_MACCONTROL_GMIIEN);
+ emac_write(EMAC_MACCONTROL, val);
- /* Enable interrupts */
- emac_int_enable(priv);
- return 0;
+ /* Enable interrupts */
+ emac_int_enable(priv);
+ return 0;
}
@@ -1458,51 +1458,51 @@ static int emac_hw_enable(struct emac_priv *priv)
*/
static struct net_device_stats *emac_dev_getnetstats(struct emac_priv *priv)
{
- rt_uint32_t mac_control;
- rt_uint32_t stats_clear_mask;
+ rt_uint32_t mac_control;
+ rt_uint32_t stats_clear_mask;
- /* update emac hardware stats and reset the registers*/
+ /* update emac hardware stats and reset the registers*/
- mac_control = emac_read(EMAC_MACCONTROL);
+ mac_control = emac_read(EMAC_MACCONTROL);
- if (mac_control & EMAC_MACCONTROL_GMIIEN)
- stats_clear_mask = EMAC_STATS_CLR_MASK;
- else
- stats_clear_mask = 0;
+ if (mac_control & EMAC_MACCONTROL_GMIIEN)
+ stats_clear_mask = EMAC_STATS_CLR_MASK;
+ else
+ stats_clear_mask = 0;
- priv->net_dev_stats.multicast += emac_read(EMAC_RXMCASTFRAMES);
- emac_write(EMAC_RXMCASTFRAMES, stats_clear_mask);
+ priv->net_dev_stats.multicast += emac_read(EMAC_RXMCASTFRAMES);
+ emac_write(EMAC_RXMCASTFRAMES, stats_clear_mask);
- priv->net_dev_stats.collisions += (emac_read(EMAC_TXCOLLISION) +
- emac_read(EMAC_TXSINGLECOLL) +
- emac_read(EMAC_TXMULTICOLL));
- emac_write(EMAC_TXCOLLISION, stats_clear_mask);
- emac_write(EMAC_TXSINGLECOLL, stats_clear_mask);
- emac_write(EMAC_TXMULTICOLL, stats_clear_mask);
+ priv->net_dev_stats.collisions += (emac_read(EMAC_TXCOLLISION) +
+ emac_read(EMAC_TXSINGLECOLL) +
+ emac_read(EMAC_TXMULTICOLL));
+ emac_write(EMAC_TXCOLLISION, stats_clear_mask);
+ emac_write(EMAC_TXSINGLECOLL, stats_clear_mask);
+ emac_write(EMAC_TXMULTICOLL, stats_clear_mask);
- priv->net_dev_stats.rx_length_errors += (emac_read(EMAC_RXOVERSIZED) +
- emac_read(EMAC_RXJABBER) +
- emac_read(EMAC_RXUNDERSIZED));
- emac_write(EMAC_RXOVERSIZED, stats_clear_mask);
- emac_write(EMAC_RXJABBER, stats_clear_mask);
- emac_write(EMAC_RXUNDERSIZED, stats_clear_mask);
+ priv->net_dev_stats.rx_length_errors += (emac_read(EMAC_RXOVERSIZED) +
+ emac_read(EMAC_RXJABBER) +
+ emac_read(EMAC_RXUNDERSIZED));
+ emac_write(EMAC_RXOVERSIZED, stats_clear_mask);
+ emac_write(EMAC_RXJABBER, stats_clear_mask);
+ emac_write(EMAC_RXUNDERSIZED, stats_clear_mask);
- priv->net_dev_stats.rx_over_errors += (emac_read(EMAC_RXSOFOVERRUNS) +
- emac_read(EMAC_RXMOFOVERRUNS));
- emac_write(EMAC_RXSOFOVERRUNS, stats_clear_mask);
- emac_write(EMAC_RXMOFOVERRUNS, stats_clear_mask);
+ priv->net_dev_stats.rx_over_errors += (emac_read(EMAC_RXSOFOVERRUNS) +
+ emac_read(EMAC_RXMOFOVERRUNS));
+ emac_write(EMAC_RXSOFOVERRUNS, stats_clear_mask);
+ emac_write(EMAC_RXMOFOVERRUNS, stats_clear_mask);
- priv->net_dev_stats.rx_fifo_errors += emac_read(EMAC_RXDMAOVERRUNS);
- emac_write(EMAC_RXDMAOVERRUNS, stats_clear_mask);
+ priv->net_dev_stats.rx_fifo_errors += emac_read(EMAC_RXDMAOVERRUNS);
+ emac_write(EMAC_RXDMAOVERRUNS, stats_clear_mask);
- priv->net_dev_stats.tx_carrier_errors +=
- emac_read(EMAC_TXCARRIERSENSE);
- emac_write(EMAC_TXCARRIERSENSE, stats_clear_mask);
+ priv->net_dev_stats.tx_carrier_errors +=
+ emac_read(EMAC_TXCARRIERSENSE);
+ emac_write(EMAC_TXCARRIERSENSE, stats_clear_mask);
- priv->net_dev_stats.tx_fifo_errors = emac_read(EMAC_TXUNDERRUN);
- emac_write(EMAC_TXUNDERRUN, stats_clear_mask);
+ priv->net_dev_stats.tx_fifo_errors = emac_read(EMAC_TXUNDERRUN);
+ emac_write(EMAC_TXUNDERRUN, stats_clear_mask);
- return &priv->net_dev_stats;
+ return &priv->net_dev_stats;
}
@@ -1511,164 +1511,164 @@ static struct net_device_stats *emac_dev_getnetstats(struct emac_priv *priv)
static rt_err_t rt_davinci_emac_init(rt_device_t dev)
{
- struct emac_priv *priv = dev->user_data;
- unsigned long paddr;
- rt_uint32_t ch, rc;
- int i;
+ struct emac_priv *priv = dev->user_data;
+ unsigned long paddr;
+ rt_uint32_t ch, rc;
+ int i;
+
+ /* Configuration items */
+ priv->rx_buf_size = EMAC_DEF_MAX_FRAME_SIZE + NET_IP_ALIGN;
- /* Configuration items */
- priv->rx_buf_size = EMAC_DEF_MAX_FRAME_SIZE + NET_IP_ALIGN;
+ /* Clear basic hardware */
+ for (ch = 0; ch < EMAC_MAX_TXRX_CHANNELS; ch++) {
+ emac_write(EMAC_TXHDP(ch), 0);
+ emac_write(EMAC_RXHDP(ch), 0);
+ emac_write(EMAC_RXHDP(ch), 0);
+ emac_write(EMAC_RXINTMASKCLEAR, EMAC_INT_MASK_CLEAR);
+ emac_write(EMAC_TXINTMASKCLEAR, EMAC_INT_MASK_CLEAR);
+ }
+ priv->mac_hash1 = 0;
+ priv->mac_hash2 = 0;
+ emac_write(EMAC_MACHASH1, 0);
+ emac_write(EMAC_MACHASH2, 0);
- /* Clear basic hardware */
- for (ch = 0; ch < EMAC_MAX_TXRX_CHANNELS; ch++) {
- emac_write(EMAC_TXHDP(ch), 0);
- emac_write(EMAC_RXHDP(ch), 0);
- emac_write(EMAC_RXHDP(ch), 0);
- emac_write(EMAC_RXINTMASKCLEAR, EMAC_INT_MASK_CLEAR);
- emac_write(EMAC_TXINTMASKCLEAR, EMAC_INT_MASK_CLEAR);
- }
- priv->mac_hash1 = 0;
- priv->mac_hash2 = 0;
- emac_write(EMAC_MACHASH1, 0);
- emac_write(EMAC_MACHASH2, 0);
+ /* multi ch not supported - open 1 TX, 1RX ch by default */
+ rc = emac_init_txch(priv, EMAC_DEF_TX_CH);
+ if (0 != rc) {
+ rt_kprintf("DaVinci EMAC: emac_init_txch() failed");
+ return rc;
+ }
+ rc = emac_init_rxch(priv, EMAC_DEF_RX_CH, priv->mac_addr);
+ if (0 != rc) {
+ rt_kprintf("DaVinci EMAC: emac_init_rxch() failed");
+ return rc;
+ }
- /* multi ch not supported - open 1 TX, 1RX ch by default */
- rc = emac_init_txch(priv, EMAC_DEF_TX_CH);
- if (0 != rc) {
- rt_kprintf("DaVinci EMAC: emac_init_txch() failed");
- return rc;
- }
- rc = emac_init_rxch(priv, EMAC_DEF_RX_CH, priv->mac_addr);
- if (0 != rc) {
- rt_kprintf("DaVinci EMAC: emac_init_rxch() failed");
- return rc;
- }
+ rt_hw_interrupt_install(IRQ_DM365_EMAC_RXPULSE, emac_irq,
+ (void *)priv, "EMAC_RXPULSE");
+ rt_hw_interrupt_umask(IRQ_DM365_EMAC_RXPULSE);
+ rt_hw_interrupt_install(IRQ_DM365_EMAC_TXPULSE, emac_irq,
+ (void *)priv, "EMAC_TXPULSE");
+ rt_hw_interrupt_umask(IRQ_DM365_EMAC_TXPULSE);
+ rt_hw_interrupt_install(IRQ_DM365_EMAC_RXTHRESH, emac_irq,
+ (void *)priv, "EMAC_RXTHRESH");
+ rt_hw_interrupt_umask(IRQ_DM365_EMAC_RXTHRESH);
+ rt_hw_interrupt_install(IRQ_DM365_EMAC_MISCPULSE, emac_irq,
+ (void *)priv, "EMAC_MISCPULSE");
+ rt_hw_interrupt_umask(IRQ_DM365_EMAC_MISCPULSE);
- rt_hw_interrupt_install(IRQ_DM365_EMAC_RXPULSE, emac_irq,
- (void *)priv, "EMAC_RXPULSE");
- rt_hw_interrupt_umask(IRQ_DM365_EMAC_RXPULSE);
- rt_hw_interrupt_install(IRQ_DM365_EMAC_TXPULSE, emac_irq,
- (void *)priv, "EMAC_TXPULSE");
- rt_hw_interrupt_umask(IRQ_DM365_EMAC_TXPULSE);
- rt_hw_interrupt_install(IRQ_DM365_EMAC_RXTHRESH, emac_irq,
- (void *)priv, "EMAC_RXTHRESH");
- rt_hw_interrupt_umask(IRQ_DM365_EMAC_RXTHRESH);
- rt_hw_interrupt_install(IRQ_DM365_EMAC_MISCPULSE, emac_irq,
- (void *)priv, "EMAC_MISCPULSE");
- rt_hw_interrupt_umask(IRQ_DM365_EMAC_MISCPULSE);
+ emac_mii_reset(priv);
+ davinci_emac_phy_init(dev);
- emac_mii_reset(priv);
- davinci_emac_phy_init(dev);
+ /* Start/Enable EMAC hardware */
+ emac_hw_enable(priv);
- /* Start/Enable EMAC hardware */
- emac_hw_enable(priv);
+ rt_timer_init(&priv->timer, "link_timer",
+ davinci_emac_update_link,
+ (void *)priv,
+ RT_TICK_PER_SECOND,
+ RT_TIMER_FLAG_PERIODIC);
- rt_timer_init(&priv->timer, "link_timer",
- davinci_emac_update_link,
- (void *)priv,
- RT_TICK_PER_SECOND,
- RT_TIMER_FLAG_PERIODIC);
+ rt_timer_start(&priv->timer);
+ rt_kprintf("davinci emac initialized\n");
- rt_timer_start(&priv->timer);
- rt_kprintf("davinci emac initialized\n");
-
- return RT_EOK;
+ return RT_EOK;
}
static rt_err_t rt_davinci_emac_open(rt_device_t dev, rt_uint16_t oflag)
{
- return RT_EOK;
+ return RT_EOK;
}
static rt_err_t rt_davinci_emac_close(rt_device_t dev)
{
- return RT_EOK;
+ return RT_EOK;
}
static rt_size_t rt_davinci_emac_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
{
- rt_set_errno(-RT_ENOSYS);
- return 0;
+ rt_set_errno(-RT_ENOSYS);
+ return 0;
}
static rt_size_t rt_davinci_emac_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
{
- rt_set_errno(-RT_ENOSYS);
- return 0;
+ rt_set_errno(-RT_ENOSYS);
+ return 0;
}
static rt_err_t rt_davinci_emac_control(rt_device_t dev, int cmd, void *args)
{
- struct emac_priv *priv = dev->user_data;
- switch(cmd)
- {
- case NIOCTL_GADDR:
- /* get mac address */
- if(args) rt_memcpy(args, priv->mac_addr, 6);
- else return -RT_ERROR;
- break;
+ struct emac_priv *priv = dev->user_data;
+ switch(cmd)
+ {
+ case NIOCTL_GADDR:
+ /* get mac address */
+ if(args) rt_memcpy(args, priv->mac_addr, 6);
+ else return -RT_ERROR;
+ break;
- default :
- break;
- }
+ default :
+ break;
+ }
- return RT_EOK;
+ return RT_EOK;
}
void dm365_emac_gpio_init(void)
{
- rt_uint32_t arm_intmux;
+ rt_uint32_t arm_intmux;
- /*
- * EMAC interrupts are multiplexed with GPIO interrupts
- * Details are available at the DM365 ARM
- * Subsystem Users Guide(sprufg5.pdf) pages 133 - 134
- */
- arm_intmux = davinci_readl(DM365_ARM_INTMUX);
- arm_intmux |= (1 << 14)|(1 << 15)|(1 << 16)|(1 << 17);
- davinci_writel(arm_intmux, DM365_ARM_INTMUX);
+ /*
+ * EMAC interrupts are multiplexed with GPIO interrupts
+ * Details are available at the DM365 ARM
+ * Subsystem Users Guide(sprufg5.pdf) pages 133 - 134
+ */
+ arm_intmux = davinci_readl(DM365_ARM_INTMUX);
+ arm_intmux |= (1 << 14)|(1 << 15)|(1 << 16)|(1 << 17);
+ davinci_writel(arm_intmux, DM365_ARM_INTMUX);
}
int rt_hw_davinci_emac_init()
{
- struct emac_priv *priv = &davinci_emac_device;
- struct clk *emac_clk;
- emac_clk = clk_get("EMACCLK");
- emac_bus_frequency = clk_get_rate(emac_clk);
- psc_change_state(DAVINCI_DM365_LPSC_CPGMAC, PSC_ENABLE);
- dm365_emac_gpio_init();
- rt_memset(&davinci_emac_device, 0, sizeof(davinci_emac_device));
- davinci_emac_device.emac_base = (void __iomem *)DM365_EMAC_CNTRL_BASE;
- davinci_emac_device.ctrl_base = (void __iomem *)DM365_EMAC_WRAP_CNTRL_BASE;
- davinci_emac_device.ctrl_ram_size = DM365_EMAC_CNTRL_RAM_SIZE;
- davinci_emac_device.emac_ctrl_ram = (void __iomem *)DM365_EMAC_WRAP_RAM_BASE;
- davinci_emac_device.mdio_base = (void __iomem *)DM365_EMAC_MDIO_BASE;
- davinci_emac_device.version = EMAC_VERSION_2;
- davinci_emac_device.rmii_en = 0;
- davinci_emac_device.phy_addr = 0x09;
- rt_sem_init(&priv->tx_lock, "tx_lock", 1, RT_IPC_FLAG_FIFO);
- rt_sem_init(&priv->rx_lock, "rx_lock", 1, RT_IPC_FLAG_FIFO);
+ struct emac_priv *priv = &davinci_emac_device;
+ struct clk *emac_clk;
+ emac_clk = clk_get("EMACCLK");
+ emac_bus_frequency = clk_get_rate(emac_clk);
+ psc_change_state(DAVINCI_DM365_LPSC_CPGMAC, PSC_ENABLE);
+ dm365_emac_gpio_init();
+ rt_memset(&davinci_emac_device, 0, sizeof(davinci_emac_device));
+ davinci_emac_device.emac_base = (void __iomem *)DM365_EMAC_CNTRL_BASE;
+ davinci_emac_device.ctrl_base = (void __iomem *)DM365_EMAC_WRAP_CNTRL_BASE;
+ davinci_emac_device.ctrl_ram_size = DM365_EMAC_CNTRL_RAM_SIZE;
+ davinci_emac_device.emac_ctrl_ram = (void __iomem *)DM365_EMAC_WRAP_RAM_BASE;
+ davinci_emac_device.mdio_base = (void __iomem *)DM365_EMAC_MDIO_BASE;
+ davinci_emac_device.version = EMAC_VERSION_2;
+ davinci_emac_device.rmii_en = 0;
+ davinci_emac_device.phy_addr = 0x09;
+ rt_sem_init(&priv->tx_lock, "tx_lock", 1, RT_IPC_FLAG_FIFO);
+ rt_sem_init(&priv->rx_lock, "rx_lock", 1, RT_IPC_FLAG_FIFO);
+
+ davinci_emac_device.mac_addr[0] = 0x00;
+ davinci_emac_device.mac_addr[1] = 0x60;
+ davinci_emac_device.mac_addr[2] = 0x6E;
+ davinci_emac_device.mac_addr[3] = 0x11;
+ davinci_emac_device.mac_addr[4] = 0x22;
+ davinci_emac_device.mac_addr[5] = 0x33;
+
+ davinci_emac_device.parent.parent.init = rt_davinci_emac_init;
+ davinci_emac_device.parent.parent.open = rt_davinci_emac_open;
+ davinci_emac_device.parent.parent.close = rt_davinci_emac_close;
+ davinci_emac_device.parent.parent.read = rt_davinci_emac_read;
+ davinci_emac_device.parent.parent.write = rt_davinci_emac_write;
+ davinci_emac_device.parent.parent.control = rt_davinci_emac_control;
+ davinci_emac_device.parent.parent.user_data = &davinci_emac_device;
- davinci_emac_device.mac_addr[0] = 0x00;
- davinci_emac_device.mac_addr[1] = 0x60;
- davinci_emac_device.mac_addr[2] = 0x6E;
- davinci_emac_device.mac_addr[3] = 0x11;
- davinci_emac_device.mac_addr[4] = 0x22;
- davinci_emac_device.mac_addr[5] = 0x33;
-
- davinci_emac_device.parent.parent.init = rt_davinci_emac_init;
- davinci_emac_device.parent.parent.open = rt_davinci_emac_open;
- davinci_emac_device.parent.parent.close = rt_davinci_emac_close;
- davinci_emac_device.parent.parent.read = rt_davinci_emac_read;
- davinci_emac_device.parent.parent.write = rt_davinci_emac_write;
- davinci_emac_device.parent.parent.control = rt_davinci_emac_control;
- davinci_emac_device.parent.parent.user_data = &davinci_emac_device;
+ davinci_emac_device.parent.eth_rx = rt_davinci_emac_rx;
+ davinci_emac_device.parent.eth_tx = rt_davinci_emac_tx;
- davinci_emac_device.parent.eth_rx = rt_davinci_emac_rx;
- davinci_emac_device.parent.eth_tx = rt_davinci_emac_tx;
+ eth_device_init(&(davinci_emac_device.parent), "e0");
- eth_device_init(&(davinci_emac_device.parent), "e0");
-
}
INIT_DEVICE_EXPORT(rt_hw_davinci_emac_init);
@@ -1679,68 +1679,68 @@ INIT_DEVICE_EXPORT(rt_hw_davinci_emac_init);
void dump_emac_stats(void)
{
- int i;
- struct emac_priv *emac;
- struct net_device_stats *stats;
- rt_device_t dev = rt_device_find("e0");
+ int i;
+ struct emac_priv *emac;
+ struct net_device_stats *stats;
+ rt_device_t dev = rt_device_find("e0");
- if(dev == RT_NULL)
- return;
+ if(dev == RT_NULL)
+ return;
- emac = (struct emac_priv *)dev->user_data;
+ emac = (struct emac_priv *)dev->user_data;
- stats = emac_dev_getnetstats(emac);
- rt_kprintf("rx_packets = %d\n"
- "tx_packets = %d\n"
- "rx_bytes = %d\n"
- "tx_bytes = %d\n"
- "rx_errors = %d\n"
- "tx_errors = %d\n"
- "rx_dropped = %d\n"
- "tx_dropped = %d\n"
- "multicast = %d\n"
- "collisions = %d\n",
- stats->rx_packets,
- stats->tx_packets,
- stats->rx_bytes,
- stats->tx_bytes,
- stats->rx_errors,
- stats->tx_errors,
- stats->rx_dropped,
- stats->tx_dropped,
- stats->multicast,
- stats->collisions);
+ stats = emac_dev_getnetstats(emac);
+ rt_kprintf("rx_packets = %d\n"
+ "tx_packets = %d\n"
+ "rx_bytes = %d\n"
+ "tx_bytes = %d\n"
+ "rx_errors = %d\n"
+ "tx_errors = %d\n"
+ "rx_dropped = %d\n"
+ "tx_dropped = %d\n"
+ "multicast = %d\n"
+ "collisions = %d\n",
+ stats->rx_packets,
+ stats->tx_packets,
+ stats->rx_bytes,
+ stats->tx_bytes,
+ stats->rx_errors,
+ stats->tx_errors,
+ stats->rx_dropped,
+ stats->tx_dropped,
+ stats->multicast,
+ stats->collisions);
- rt_kprintf("rx_length_errors = %d\n"
- "rx_over_errors = %d\n"
- "rx_crc_errors = %d\n"
- "rx_frame_errors = %d\n"
- "rx_fifo_errors = %d\n"
- "rx_missed_errors = %d\n",
- stats->rx_length_errors,
- stats->rx_over_errors,
- stats->rx_crc_errors,
- stats->rx_frame_errors,
- stats->rx_fifo_errors,
- stats->rx_missed_errors);
+ rt_kprintf("rx_length_errors = %d\n"
+ "rx_over_errors = %d\n"
+ "rx_crc_errors = %d\n"
+ "rx_frame_errors = %d\n"
+ "rx_fifo_errors = %d\n"
+ "rx_missed_errors = %d\n",
+ stats->rx_length_errors,
+ stats->rx_over_errors,
+ stats->rx_crc_errors,
+ stats->rx_frame_errors,
+ stats->rx_fifo_errors,
+ stats->rx_missed_errors);
- rt_kprintf("tx_aborted_errors = %d\n"
- "tx_carrier_errors = %d\n"
- "tx_fifo_errors = %d\n"
- "tx_heartbeat_errors = %d\n"
- "tx_window_errors = %d\n",
- stats->tx_aborted_errors,
- stats->tx_carrier_errors,
- stats->tx_fifo_errors,
- stats->tx_heartbeat_errors,
- stats->tx_window_errors);
+ rt_kprintf("tx_aborted_errors = %d\n"
+ "tx_carrier_errors = %d\n"
+ "tx_fifo_errors = %d\n"
+ "tx_heartbeat_errors = %d\n"
+ "tx_window_errors = %d\n",
+ stats->tx_aborted_errors,
+ stats->tx_carrier_errors,
+ stats->tx_fifo_errors,
+ stats->tx_heartbeat_errors,
+ stats->tx_window_errors);
- rt_kprintf("rx_compressed = %d\n"
- "tx_compressed = %d\n",
- stats->rx_compressed,
- stats->tx_compressed);
+ rt_kprintf("rx_compressed = %d\n"
+ "tx_compressed = %d\n",
+ stats->rx_compressed,
+ stats->tx_compressed);
- rt_kprintf("\n");
+ rt_kprintf("\n");
}
FINSH_FUNCTION_EXPORT(dump_emac_stats, dump emac statistics);
@@ -1748,8 +1748,8 @@ FINSH_FUNCTION_EXPORT(dump_emac_stats, dump emac statistics);
#ifdef FINSH_USING_MSH
int cmd_dump_emac_stats(int argc, char** argv)
{
- dump_emac_stats();
- return 0;
+ dump_emac_stats();
+ return 0;
}
FINSH_FUNCTION_EXPORT_ALIAS(cmd_dump_emac_stats, __cmd_dump_emac_stats, dump emac statistics.);
#endif