[BSP][dm365] Fixed net link down issue.

This commit is contained in:
weety 2017-11-05 00:33:51 +08:00
parent 06e84c8f30
commit 76e1c8029d

View File

@ -62,7 +62,6 @@ static inline rt_uint32_t virt_to_phys(void *addr)
static struct emac_priv davinci_emac_device; static struct emac_priv davinci_emac_device;
static struct rt_semaphore sem_ack;
/* clock frequency for EMAC */ /* clock frequency for EMAC */
static unsigned long emac_bus_frequency; static unsigned long emac_bus_frequency;
@ -240,6 +239,7 @@ static int davinci_emac_phy_init(rt_device_t dev)
rt_kprintf("%s: link down (status: 0x%04x)\n", rt_kprintf("%s: link down (status: 0x%04x)\n",
dev->parent.name, status); dev->parent.name, status);
priv->link = 0; priv->link = 0;
eth_device_linkchange(&priv->parent, RT_FALSE);
return 0; return 0;
} else { } else {
adv = emac_mii_read(priv, priv->phy_addr, MII_ADVERTISE); adv = emac_mii_read(priv, priv->phy_addr, MII_ADVERTISE);
@ -256,6 +256,7 @@ static int davinci_emac_phy_init(rt_device_t dev)
priv->speed = speed; priv->speed = speed;
priv->duplex = duplex; priv->duplex = duplex;
priv->link = 1; priv->link = 1;
eth_device_linkchange(&priv->parent, RT_TRUE);
return 1; return 1;
} }
@ -387,7 +388,7 @@ static int emac_net_tx_complete(struct emac_priv *priv,
priv->net_dev_stats.tx_bytes += p->len; priv->net_dev_stats.tx_bytes += p->len;
//free pbuf //free pbuf
} }
rt_sem_release(&sem_ack);
return 0; return 0;
} }
@ -553,6 +554,8 @@ static int emac_send(struct emac_priv *priv, struct emac_netpktobj *pkt, rt_uint
struct emac_tx_bd __iomem *curr_bd; struct emac_tx_bd __iomem *curr_bd;
struct emac_txch *txch; struct emac_txch *txch;
struct emac_netbufobj *buf_list; struct emac_netbufobj *buf_list;
rt_uint32_t num_pkts = 0;
int retry = 0;
txch = priv->txch[ch]; txch = priv->txch[ch];
buf_list = pkt->buf_list; /* get handle to the buffer array */ buf_list = pkt->buf_list; /* get handle to the buffer array */
@ -563,12 +566,21 @@ static int emac_send(struct emac_priv *priv, struct emac_netpktobj *pkt, rt_uint
pkt->pkt_length = EMAC_DEF_MIN_ETHPKTSIZE; pkt->pkt_length = EMAC_DEF_MIN_ETHPKTSIZE;
} }
try:
rt_sem_take(&priv->tx_lock, RT_WAITING_FOREVER); rt_sem_take(&priv->tx_lock, RT_WAITING_FOREVER);
curr_bd = txch->bd_pool_head; curr_bd = txch->bd_pool_head;
if (curr_bd == RT_NULL) { if (curr_bd == RT_NULL) {
txch->out_of_tx_bd++; txch->out_of_tx_bd++;
rt_sem_release(&priv->tx_lock); 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; return EMAC_ERR_TX_OUT_OF_BD;
rt_thread_delay(1);
}
goto try;
} }
txch->bd_pool_head = curr_bd->next; txch->bd_pool_head = curr_bd->next;
@ -713,38 +725,14 @@ static void emac_dev_tx_timeout(struct emac_priv *priv)
/* transmit packet. */ /* transmit packet. */
rt_err_t rt_davinci_emac_tx( rt_device_t dev, struct pbuf* p) rt_err_t rt_davinci_emac_tx( rt_device_t dev, struct pbuf* p)
{ {
/*struct pbuf* q;
rt_uint8_t* bufptr, *buf = RT_NULL;
unsigned long ctrl;
rt_uint32_t addr;*/
rt_err_t err; rt_err_t err;
struct emac_priv *priv = dev->user_data; struct emac_priv *priv = dev->user_data;
emac_dev_xmit(p, priv); err = emac_dev_xmit(p, priv);
#if 0
buf = rt_malloc(p->tot_len);
if (!buf) {
rt_kprintf("%s:alloc buf failed\n", __func__);
return -RT_ENOMEM;
}
bufptr = buf;
/*for (q = p; q != RT_NULL; q = q->next)
{
memcpy(bufptr, q->payload, q->len);
bufptr += q->len;
}*/
#endif
/* wait ack */
err = rt_sem_take(&sem_ack, RT_TICK_PER_SECOND*5);
if (err != RT_EOK) if (err != RT_EOK)
{ {
emac_dev_tx_timeout(priv); emac_dev_tx_timeout(priv);
} }
//rt_free(buf);
return RT_EOK; return RT_EOK;
} }
@ -1672,7 +1660,6 @@ void rt_hw_davinci_emac_init()
davinci_emac_device.version = EMAC_VERSION_2; davinci_emac_device.version = EMAC_VERSION_2;
davinci_emac_device.rmii_en = 0; davinci_emac_device.rmii_en = 0;
davinci_emac_device.phy_addr = 0x09; davinci_emac_device.phy_addr = 0x09;
rt_sem_init(&sem_ack, "tx_ack", 0, RT_IPC_FLAG_FIFO);
rt_sem_init(&priv->tx_lock, "tx_lock", 1, RT_IPC_FLAG_FIFO); 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); rt_sem_init(&priv->rx_lock, "rx_lock", 1, RT_IPC_FLAG_FIFO);