mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-26 14:40:41 +00:00
net: dm9000: Receive one packet per recv call
Instead of reading out the entire FIFO and possibly overwriting U-Boot memory, read out one packet per recv call, pass it to U-Boot network stack, and repeat. Reviewed-by: Ramon Fried <rfried.dev@gmail.com> Signed-off-by: Marek Vasut <marex@denx.de> Cc: Joe Hershberger <joe.hershberger@ni.com> Cc: Ramon Fried <rfried.dev@gmail.com>
This commit is contained in:
parent
85a7260186
commit
84bf20f6ce
1 changed files with 50 additions and 52 deletions
|
@ -481,10 +481,9 @@ static void dm9000_halt_common(struct dm9000_priv *db)
|
||||||
/*
|
/*
|
||||||
* Received a packet and pass to upper layer
|
* Received a packet and pass to upper layer
|
||||||
*/
|
*/
|
||||||
static int dm9000_recv_common(struct dm9000_priv *db)
|
static int dm9000_recv_common(struct dm9000_priv *db, uchar *rdptr)
|
||||||
{
|
{
|
||||||
u8 rxbyte;
|
u8 rxbyte;
|
||||||
u8 *rdptr = (u8 *)net_rx_packets[0];
|
|
||||||
u16 rxstatus, rxlen = 0;
|
u16 rxstatus, rxlen = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -497,7 +496,6 @@ static int dm9000_recv_common(struct dm9000_priv *db)
|
||||||
dm9000_iow(db, DM9000_ISR, 0x01); /* clear PR status latched in bit 0 */
|
dm9000_iow(db, DM9000_ISR, 0x01); /* clear PR status latched in bit 0 */
|
||||||
|
|
||||||
/* There is _at least_ 1 package in the fifo, read them all */
|
/* There is _at least_ 1 package in the fifo, read them all */
|
||||||
for (;;) {
|
|
||||||
dm9000_ior(db, DM9000_MRCMDX); /* Dummy read */
|
dm9000_ior(db, DM9000_MRCMDX); /* Dummy read */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -512,7 +510,7 @@ static int dm9000_recv_common(struct dm9000_priv *db)
|
||||||
dm9000_iow(db, DM9000_ISR, 0x80); /* Stop INT request */
|
dm9000_iow(db, DM9000_ISR, 0x80); /* Stop INT request */
|
||||||
printf("DM9000 error: status check fail: 0x%x\n",
|
printf("DM9000 error: status check fail: 0x%x\n",
|
||||||
rxbyte);
|
rxbyte);
|
||||||
return 0;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rxbyte != DM9000_PKT_RDY)
|
if (rxbyte != DM9000_PKT_RDY)
|
||||||
|
@ -529,8 +527,7 @@ static int dm9000_recv_common(struct dm9000_priv *db)
|
||||||
/* Read received packet from RX SRAM */
|
/* Read received packet from RX SRAM */
|
||||||
db->inblk(db, rdptr, rxlen);
|
db->inblk(db, rdptr, rxlen);
|
||||||
|
|
||||||
if (rxstatus & 0xbf00 || rxlen < 0x40 ||
|
if (rxstatus & 0xbf00 || rxlen < 0x40 || rxlen > DM9000_PKT_MAX) {
|
||||||
rxlen > DM9000_PKT_MAX) {
|
|
||||||
if (rxstatus & 0x100)
|
if (rxstatus & 0x100)
|
||||||
printf("rx fifo error\n");
|
printf("rx fifo error\n");
|
||||||
if (rxstatus & 0x200)
|
if (rxstatus & 0x200)
|
||||||
|
@ -541,14 +538,10 @@ static int dm9000_recv_common(struct dm9000_priv *db)
|
||||||
printf("rx length too big\n");
|
printf("rx length too big\n");
|
||||||
dm9000_reset(db);
|
dm9000_reset(db);
|
||||||
}
|
}
|
||||||
} else {
|
return -EINVAL;
|
||||||
dm9000_dump_packet(__func__, rdptr, rxlen);
|
}
|
||||||
|
|
||||||
debug("passing packet to upper layer\n");
|
return rxlen;
|
||||||
net_process_received_packet(net_rx_packets[0], rxlen);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -600,8 +593,13 @@ static int dm9000_send(struct eth_device *dev, void *packet, int length)
|
||||||
static int dm9000_recv(struct eth_device *dev)
|
static int dm9000_recv(struct eth_device *dev)
|
||||||
{
|
{
|
||||||
struct dm9000_priv *db = container_of(dev, struct dm9000_priv, dev);
|
struct dm9000_priv *db = container_of(dev, struct dm9000_priv, dev);
|
||||||
|
int ret;
|
||||||
|
|
||||||
return dm9000_recv_common(db);
|
ret = dm9000_recv_common(db, net_rx_packets[0]);
|
||||||
|
if (ret > 0)
|
||||||
|
net_process_received_packet(net_rx_packets[0], ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dm9000_initialize(struct bd_info *bis)
|
int dm9000_initialize(struct bd_info *bis)
|
||||||
|
|
Loading…
Reference in a new issue