Commit 08e2e5fcd2e06670b62e1680a3934c0e55c72810

Authored by Grzegorz Bernacki
Committed by Rafal Jaworowski
1 parent 8d17979d03

[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: Grzegorz Bernacki <gjb@semihalf.com>

Showing 1 changed file with 21 additions and 13 deletions Side-by-side Diff

... ... @@ -32,6 +32,9 @@
32 32 int fec512x_miiphy_write(char *devname, uint8 phyAddr, uint8 regAddr, uint16 data);
33 33 int mpc512x_fec_init_phy(struct eth_device *dev, bd_t * bis);
34 34  
  35 +static uchar rx_buff[FEC_MAX_PKT_SIZE];
  36 +static int rx_buff_idx = 0;
  37 +
35 38 /********************************************************************/
36 39 #if (DEBUG & 0x2)
37 40 static void mpc512x_fec_phydump (char *devname)
... ... @@ -235,7 +238,7 @@
235 238 fec->eth->op_pause = 0x00010020;
236 239  
237 240 /* Frame length=1518; MII mode */
238   - fec->eth->r_cntrl = 0x05ee000c;
  241 + fec->eth->r_cntrl = 0x05ee0024;
239 242  
240 243 /* Half-duplex, heartbeat disabled */
241 244 fec->eth->x_cntrl = 0x00000000;
... ... @@ -520,8 +523,7 @@
520 523 mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv;
521 524 volatile FEC_RBD *pRbd = &fec->bdBase->rbd[fec->rbdIndex];
522 525 unsigned long ievent;
523   - int frame_length, len = 0;
524   - uchar buff[FEC_MAX_PKT_SIZE];
  526 + int frame_length = 0;
525 527  
526 528 #if (DEBUG & 0x1)
527 529 printf ("mpc512x_fec_recv %d Start...\n", fec->rbdIndex);
528 530  
529 531  
530 532  
531 533  
... ... @@ -555,31 +557,37 @@
555 557 }
556 558  
557 559 if (!(pRbd->status & FEC_RBD_EMPTY)) {
558   - if ((pRbd->status & FEC_RBD_LAST) &&
559   - !(pRbd->status & FEC_RBD_ERR) &&
  560 + if (!(pRbd->status & FEC_RBD_ERR) &&
560 561 ((pRbd->dataLength - 4) > 14)) {
561 562  
562 563 /*
563 564 * Get buffer size
564 565 */
565   - frame_length = pRbd->dataLength - 4;
566   -
  566 + if (pRbd->status & FEC_RBD_LAST)
  567 + frame_length = pRbd->dataLength - 4;
  568 + else
  569 + frame_length = pRbd->dataLength;
567 570 #if (DEBUG & 0x20)
568 571 {
569 572 int i;
570   - printf ("recv data hdr:");
  573 + printf ("recv data length 0x%08x data hdr: ",
  574 + pRbd->dataLength);
571 575 for (i = 0; i < 14; i++)
572 576 printf ("%x ", *((uint8*)pRbd->dataPointer + i));
573 577 printf("\n");
574 578 }
575 579 #endif
576   -
577 580 /*
578 581 * Fill the buffer and pass it to upper layers
579 582 */
580   - memcpy (buff, (void*)pRbd->dataPointer, frame_length);
581   - NetReceive ((uchar*)buff, frame_length);
582   - len = frame_length;
  583 + memcpy (&rx_buff[rx_buff_idx], (void*)pRbd->dataPointer,
  584 + frame_length - rx_buff_idx);
  585 + rx_buff_idx = frame_length;
  586 +
  587 + if (pRbd->status & FEC_RBD_LAST) {
  588 + NetReceive ((uchar*)rx_buff, frame_length);
  589 + rx_buff_idx = 0;
  590 + }
583 591 }
584 592  
585 593 /*
... ... @@ -590,7 +598,7 @@
590 598  
591 599 /* Try to fill Buffer Descriptors */
592 600 fec->eth->r_des_active = 0x01000000; /* Descriptor polling active */
593   - return len;
  601 + return frame_length;
594 602 }
595 603  
596 604 /********************************************************************/