Skip to content
Snippets Groups Projects
Commit 08e2e5fc authored by Grzegorz Bernacki's avatar Grzegorz Bernacki Committed by Rafal Jaworowski
Browse files

[MPC512x] Proper handling of larger frames in the FEC driver


When frame larger than local RX buffer is received, it is split and handled
by two buffer descriptors. Prior to this patch the FEC driver discarded
contents of a buffer descriptor without the 'LAST' bit set, so the first
part of the frame was lost in case of larger frames. This fix allows to
safely combine the two pieces into the whole frame.

Signed-off-by: default avatarGrzegorz Bernacki <gjb@semihalf.com>
parent 8d17979d
No related branches found
No related tags found
No related merge requests found
...@@ -32,6 +32,9 @@ int fec512x_miiphy_read(char *devname, uint8 phyAddr, uint8 regAddr, uint16 * re ...@@ -32,6 +32,9 @@ int fec512x_miiphy_read(char *devname, uint8 phyAddr, uint8 regAddr, uint16 * re
int fec512x_miiphy_write(char *devname, uint8 phyAddr, uint8 regAddr, uint16 data); int fec512x_miiphy_write(char *devname, uint8 phyAddr, uint8 regAddr, uint16 data);
int mpc512x_fec_init_phy(struct eth_device *dev, bd_t * bis); int mpc512x_fec_init_phy(struct eth_device *dev, bd_t * bis);
static uchar rx_buff[FEC_MAX_PKT_SIZE];
static int rx_buff_idx = 0;
/********************************************************************/ /********************************************************************/
#if (DEBUG & 0x2) #if (DEBUG & 0x2)
static void mpc512x_fec_phydump (char *devname) static void mpc512x_fec_phydump (char *devname)
...@@ -235,7 +238,7 @@ static int mpc512x_fec_init (struct eth_device *dev, bd_t * bis) ...@@ -235,7 +238,7 @@ static int mpc512x_fec_init (struct eth_device *dev, bd_t * bis)
fec->eth->op_pause = 0x00010020; fec->eth->op_pause = 0x00010020;
/* Frame length=1518; MII mode */ /* Frame length=1518; MII mode */
fec->eth->r_cntrl = 0x05ee000c; fec->eth->r_cntrl = 0x05ee0024;
/* Half-duplex, heartbeat disabled */ /* Half-duplex, heartbeat disabled */
fec->eth->x_cntrl = 0x00000000; fec->eth->x_cntrl = 0x00000000;
...@@ -520,8 +523,7 @@ static int mpc512x_fec_recv (struct eth_device *dev) ...@@ -520,8 +523,7 @@ static int mpc512x_fec_recv (struct eth_device *dev)
mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv; mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv;
volatile FEC_RBD *pRbd = &fec->bdBase->rbd[fec->rbdIndex]; volatile FEC_RBD *pRbd = &fec->bdBase->rbd[fec->rbdIndex];
unsigned long ievent; unsigned long ievent;
int frame_length, len = 0; int frame_length = 0;
uchar buff[FEC_MAX_PKT_SIZE];
#if (DEBUG & 0x1) #if (DEBUG & 0x1)
printf ("mpc512x_fec_recv %d Start...\n", fec->rbdIndex); printf ("mpc512x_fec_recv %d Start...\n", fec->rbdIndex);
...@@ -555,31 +557,37 @@ static int mpc512x_fec_recv (struct eth_device *dev) ...@@ -555,31 +557,37 @@ static int mpc512x_fec_recv (struct eth_device *dev)
} }
if (!(pRbd->status & FEC_RBD_EMPTY)) { if (!(pRbd->status & FEC_RBD_EMPTY)) {
if ((pRbd->status & FEC_RBD_LAST) && if (!(pRbd->status & FEC_RBD_ERR) &&
!(pRbd->status & FEC_RBD_ERR) &&
((pRbd->dataLength - 4) > 14)) { ((pRbd->dataLength - 4) > 14)) {
/* /*
* Get buffer size * Get buffer size
*/ */
frame_length = pRbd->dataLength - 4; if (pRbd->status & FEC_RBD_LAST)
frame_length = pRbd->dataLength - 4;
else
frame_length = pRbd->dataLength;
#if (DEBUG & 0x20) #if (DEBUG & 0x20)
{ {
int i; int i;
printf ("recv data hdr:"); printf ("recv data length 0x%08x data hdr: ",
pRbd->dataLength);
for (i = 0; i < 14; i++) for (i = 0; i < 14; i++)
printf ("%x ", *((uint8*)pRbd->dataPointer + i)); printf ("%x ", *((uint8*)pRbd->dataPointer + i));
printf("\n"); printf("\n");
} }
#endif #endif
/* /*
* Fill the buffer and pass it to upper layers * Fill the buffer and pass it to upper layers
*/ */
memcpy (buff, (void*)pRbd->dataPointer, frame_length); memcpy (&rx_buff[rx_buff_idx], (void*)pRbd->dataPointer,
NetReceive ((uchar*)buff, frame_length); frame_length - rx_buff_idx);
len = frame_length; rx_buff_idx = frame_length;
if (pRbd->status & FEC_RBD_LAST) {
NetReceive ((uchar*)rx_buff, frame_length);
rx_buff_idx = 0;
}
} }
/* /*
...@@ -590,7 +598,7 @@ static int mpc512x_fec_recv (struct eth_device *dev) ...@@ -590,7 +598,7 @@ static int mpc512x_fec_recv (struct eth_device *dev)
/* Try to fill Buffer Descriptors */ /* Try to fill Buffer Descriptors */
fec->eth->r_des_active = 0x01000000; /* Descriptor polling active */ fec->eth->r_des_active = 0x01000000; /* Descriptor polling active */
return len; return frame_length;
} }
/********************************************************************/ /********************************************************************/
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment