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:
Marek Vasut 2022-04-13 04:15:36 +02:00 committed by Ramon Fried
parent 85a7260186
commit 84bf20f6ce

View file

@ -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)