diff mbox

PATCH: mcf_fec.c sends packet with incorrect length

Message ID 4AA71E20.2060302@TU-Berlin.de
State Superseded
Headers show

Commit Message

Till Straumann Sept. 9, 2009, 3:16 a.m. UTC
mcf_fec passes the length stored in the last BD's 'length' member instead
of the full frame size to 'qemu_send_packet'.

The first hunk of the attached patch fixes this.

The patch also includes dummy-read + writes for the MIB counters
so that qemu doesn't crash if these counters are accessed
(the counters themselves are not implemented, however. Sorry.)

Finally, the patch also raises a MII interrupt when writing MMFR
but again, MII itself is not implemented. Raising an interrupt
at least lets drivers proceed who wait for an IRQ.

Please CC me for any comments - I'm not on the qemu list.

Thanks for qemu.

-- Till
diff mbox

Patch

*** qemu-0.11.0-rc1.orig/hw/mcf_fec.c	2009-07-29 19:38:19.000000000 -0500
--- qemu-0.11.0-rc1/hw/mcf_fec.c	2009-09-08 21:55:24.000000000 -0500
***************
*** 11,17 ****
  /* For crc32 */
  #include <zlib.h>
  
! //#define DEBUG_FEC 1
  
  #ifdef DEBUG_FEC
  #define DPRINTF(fmt, ...) \
--- 11,17 ----
  /* For crc32 */
  #include <zlib.h>
  
! #define DEBUG_FEC 1
  
  #ifdef DEBUG_FEC
  #define DPRINTF(fmt, ...) \
***************
*** 172,178 ****
          if (bd.flags & FEC_BD_L) {
              /* Last buffer in frame.  */
              DPRINTF("Sending packet\n");
!             qemu_send_packet(s->vc, frame, len);
              ptr = frame;
              frame_size = 0;
              s->eir |= FEC_INT_TXF;
--- 172,178 ----
          if (bd.flags & FEC_BD_L) {
              /* Last buffer in frame.  */
              DPRINTF("Sending packet\n");
!             qemu_send_packet(s->vc, frame, frame_size);
              ptr = frame;
              frame_size = 0;
              s->eir |= FEC_INT_TXF;
***************
*** 217,223 ****
  static uint32_t mcf_fec_read(void *opaque, target_phys_addr_t addr)
  {
      mcf_fec_state *s = (mcf_fec_state *)opaque;
!     switch (addr & 0x3ff) {
      case 0x004: return s->eir;
      case 0x008: return s->eimr;
      case 0x010: return s->rx_enabled ? (1 << 24) : 0; /* RDAR */
--- 217,224 ----
  static uint32_t mcf_fec_read(void *opaque, target_phys_addr_t addr)
  {
      mcf_fec_state *s = (mcf_fec_state *)opaque;
! 	addr &= 0x3ff;
!     switch (addr) {
      case 0x004: return s->eir;
      case 0x008: return s->eimr;
      case 0x010: return s->rx_enabled ? (1 << 24) : 0; /* RDAR */
***************
*** 246,251 ****
--- 247,254 ----
      case 0x184: return s->etdsr;
      case 0x188: return s->emrbr;
      default:
+ 		if ( addr >= 0x200 && addr < 0x2e4 )
+ 			return 0xdeadbeef; /* FIXME: MIB counters not implemented */
          hw_error("mcf_fec_read: Bad address 0x%x\n", (int)addr);
          return 0;
      }
***************
*** 254,260 ****
  static void mcf_fec_write(void *opaque, target_phys_addr_t addr, uint32_t value)
  {
      mcf_fec_state *s = (mcf_fec_state *)opaque;
!     switch (addr & 0x3ff) {
      case 0x004:
          s->eir &= ~value;
          break;
--- 257,264 ----
  static void mcf_fec_write(void *opaque, target_phys_addr_t addr, uint32_t value)
  {
      mcf_fec_state *s = (mcf_fec_state *)opaque;
! 	addr &= 0x3ff;
!     switch (addr) {
      case 0x004:
          s->eir &= ~value;
          break;
***************
*** 285,290 ****
--- 289,295 ----
      case 0x040:
          /* TODO: Implement MII.  */
          s->mmfr = value;
+ 		s->eir |= FEC_INT_MII;
          break;
      case 0x044:
          s->mscr = value & 0xfe;
***************
*** 342,347 ****
--- 347,354 ----
          s->emrbr = value & 0x7f0;
          break;
      default:
+ 		if ( addr >= 0x200 && addr < 0x2e4 )
+ 			return; /* FIXME: MIB counters not implemented */
          hw_error("mcf_fec_write Bad address 0x%x\n", (int)addr);
      }
      mcf_fec_update(s);