Re: playing with qemu's 8139 nic and FreeBSD (loopback mode missing?

From: Juergen Lock <nox_at_jelal.kn-bremen.de>
Date: Mon, 15 May 2006 21:14:20 +0200
On Mon, May 15, 2006 at 04:47:40AM +0400, Igor Kovalenko wrote:
> Juergen Lock wrote:
> > On Mon, May 08, 2006 at 12:44:43AM +0400, Igor Kovalenko wrote:
> >> Hi Juergen,
> >>
> >> Juergen Lock wrote:
> >>> On Sun, May 07, 2006 at 12:38:06AM +0400, Igor Kovalenko wrote:
> >>>> Hi Juergen,
> >>>>
> >>>> Juergen Lock wrote:
> >>>>> [Cc'ing glebius_at_ because he did most of the recent re(4) commits, and
> >>>>> -current in case possible other driver developers didn't see this thread
> >>>>> in -emulation]
> >>>>>
> >>>>> On Wed, May 03, 2006 at 07:46:07AM +0400, Igor Kovalenko wrote:
> >>>>>> Juergen Lock wrote:
> >>>>>>> On Sat, Apr 29, 2006 at 10:48:48AM +0400, Igor Kovalenko wrote:
> >>>>>>>> Juergen Lock wrote:
> >>>>>>>>> On Fri, Apr 28, 2006 at 08:25:02PM +0400, Igor Kovalenko wrote:
> >>>>>>>>>> Juergen Lock wrote:
> >>>>>>>>>>> I played with
> >>>>>>>>>>> 	qemu -monitor stdio -m 256 -cdrom 6.1-RC1-i386-disc1.iso 
> >>>>>>>>>>> 	-usb -soundhw es1370 -kernel-kqemu -net nic,model=rtl8139 
> >>>>>>>>>>> 	-net user
> >>>>>>>>>>> and got it as far as
> >>>>>>>>>>> 	re0: diagnostic failed, failed to receive packet in loopback 
> >>>>>>>>>>> 	mode
> >>>>>>>>>>> (followed by a panic :) with the (experimental) patches below.
> >>>>>>>>>>>
> >>>>>>>>>>> Anyone in the mood to implement loopback mode for this nic?
> >>>>>>>>>>>
> >>>>>>>>>>> Hmm actually...  I just found the original posting in the archive,
> >>>>>>>>>>> is C+ mode implemented now?  If not re is probably not what I want,
> >>>>>>>>>> The rtl8139 is set up with PCI rev ID 0x20 which should be enough for 
> >>>>>>>>>> OS driver
> >>>>>>>>>> to detect C+ mode features. C+ mode is OK, tested with Linux driver.
> >>>>>>>>> Cool, so I want FreeBSD's re driver.  That one checks TxConfig
> >>>>>>>>> tho, as changed in my patch (inside #if 0).  And when changed,
> >>>>>>>>> it still doesn't work as mentioned above because the driver expects
> >>>>>>>>> loopback mode to be working.
> >>>>>>>>>>> but the rl driver that it attaches without that #if 0'd (now) hunk
> >>>>>>>>>>> below doesnt seem to be able to get data thru either and I get
> >>>>>>>>>>> 	rl0: watchdog timeout
> >>>>>>>>>>> in dmesg, which usually means the driver doesnt receive interrupts.
> >>>>>>>>>>>
> >>>>>>>>>>> What the heck, I'll append a log of a run just doing in 
> >>>>>>>>>>> fixit->cdrom:
> >>>>>>>>>>> 	ifconfig rl0 10.0.2.15
> >>>>>>>>>>> and then exiting (which is enough to trigger the watchdog timeout...)
> >>>>>>>>>>>
> >>>>>>>>>> I'm too lasy to test with fresh freebsd installation :)
> >>>>>>>>> No need to install FreeBSD, you can get away by just using
> >>>>>>>>> fixit mode of an install iso, i.e. disc1.  (which actually is
> >>>>>>>>> what I did above. :)
> >>>>>>>>>
> >>>>>>>>> You can look at 6.1RC's re driver here:
> >>>>>>>>> http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/dev/re/if_re.c?annotate=1.46.2.14
> >>>>>>>>> which includes:
> >>>>>>>>> http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/pci/if_rlreg.h?annotate=1.51.2.3
> >>>>>>>>>
> >>>>>>>>> And 6.1RC disc1 iso is e.g. here:
> >>>>>>>>> ftp://ftp.ru.freebsd.org:/pub/FreeBSD/ISO-IMAGES-i386/6.1/6.1-RC1-i386-disc1.iso
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>> Thanks, that iso pointer made it.
> >>>>>>>>
> >>>>>>> :)
> >>>>>>>
> >>>>>>>> Please try the following on top of your patch, at least ping should now 
> >>>>>>>> work:
> >>>>>>> Thanks, that seems to get the rl driver going.  Now to fix C+ mode
> >>>>>>> (re driver) change the #if 0 in my patch to #if 1...
> >>>>>>>
> >>>>>>>
> >>>>>> I believe freebsd re driver is somewhat broken, e.g. it does not follow 
> >>>>>> documented
> >>>>>> procedure to detect hardware features (e.g. 8139 c+ mode)
> >>>>> Hmm, a bit of googling didn't reveal docs about this, do you have
> >>>>> a pointer?  (I only found the data sheet at
> >>>>> 	http://people.freebsd.org/~wpaul/RealTek/spec-8139cp(150).pdf
> >>>>> which doesnt seem to mention detecting c+ hardware specifically)
> >>>> Well, I might have misread some docs; please do not consider this as an 
> >>>> assault :)
> >>>> I remember PCI rev id >= 0x20 is C+ mode for realtek 8139.
> >>> I don't.  It may well be the doc you saw this in just is no longer
> >>> online, or I didn't came up with the right search terms...
> >>>>>> and in tries to use 8169
> >>>>>> registers (e.g. 0xda) on 8139 hardware etc.
> >>>>> Oh, then it must have mis-detected the nic as a 8169 because
> >>>>> the code in question reads:
> >>>>>
> >>>>>        if (sc->rl_type == RL_8169)
> >>>>>                CSR_WRITE_2(sc, RL_MAXRXPKTLEN, 16383);
> >>>  And with your patch i get
> >>> 	RTL8139: not implemented write(b) addr=0xda val=0x00
> >>> but that can't be this line anyway because it seems to be a byte access...
> >>> Any of the re(4) experts have an idea where this comes from?
> >>> (log generated by defining DEBUG_RTL8139 in the patched hw/rtl8139.c)
> >>>
> >> I see the re driver actually is doing 2 byte write at RL_TXSTART so the second
> >> byte goes to RL_MAXRXPKTLEN. Comment in if_rlreg.h says RL_TXSTART is 8bit
> >> so this is a bug in if_re.c line 2063
> >>
> >> This is not affecting qemu's card emulation (the extra byte write is ignored)
> >> so I think the problem is somewhere else.
> > 
> > I finally got around to playing with this a bit again, the following
> > patch gets ping and small fetch (http) going but is not enough for scp:
> > 
> > Index: hw/rtl8139.c
> > _at__at_ -1008,15 +1038,22 _at__at_
> >          val = cpu_to_le32(rxdw1);
> >          cpu_physical_memory_write(cplus_rx_ring_desc+4,  (uint8_t *)&val, 4);
> >  
> > -        /* seek to next Rx descriptor */
> > -        if (rxdw0 & CP_RX_EOR)
> > -        {
> > -            s->currCPlusRxDesc = 0;
> > -        }
> > -        else
> > -        {
> > -            ++s->currCPlusRxDesc;
> > -        }
> > +#ifdef DEBUG_RTL8139
> > +        printf("RTL8139: +++ written C+ mode RX descriptor %d %08x %08x %08x %08x\n",
> > +               descriptor,
> > +               rxdw0, rxdw1, rxbufLO, rxbufHI);
> > +#endif
> > +	/* seek to next Rx descriptor unless in loopback mode */
> > +	if (!(TxLoopBack == (s->TxConfig & TxLoopBack))) {
> > +		if (rxdw0 & CP_RX_EOR)
> > +		{
> > +		    s->currCPlusRxDesc = 0;
> > +		}
> > +		else
> > +		{
> > +		    ++s->currCPlusRxDesc;
> > +		}
> > +	}
> >  
> >  #if defined(DEBUG_RTL8139)
> >          printf("RTL8139: done C+ Rx mode ----------------\n");
> > 
> > 
> 
> That is strange; I must be missing docs pointer about loopback mode
> operation again. What makes you believe that RX descriptor should not
> advance in loopback mode?

Oh, only that re(4) expects it to be that way. :)  It may also be that
it gets reset by the turning off of loopback mode or by something else
at that time, I dont know...
Received on Mon May 15 2006 - 17:16:23 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:38:55 UTC