Subject: Re: Stuff
To: Bill Paul <wpaul@FreeBSD.ORG>
From: Alan Ritter <rittera@cc.wwu.edu>
List: tech-kern
Date: 08/21/2005 15:29:01
>
>> Thanks, I was looking at the data sheet for the 82559
>> (http://www.intel.com/design/network/datashts/738259.htm) which looks to have
>> some
>> similar information, but I don't think it's exactly the same chip.  This looks
>> really helpful
>
> Traditionally, the 'datasheets' on Intel's site have very little in the
> way of useful progamming info in them. All the important stuff is
> usually in special 'yellow cover' manuals that you can only get after
> you execute an NDA. Last time I checked, the 8255x manuals they had
> there told you just a little bit about some of the registers. They
> didn't discuss the DMA descriptor formats at all, nor did they
> describe the config block. The manual from sourceforge has all that
> stuff in it.
>
>> Unfortuanately I can't seem to get DHCP to work, I'm not quite sure why.  I don't
>> know that much about networking stuff (I haven't taken the networking class yet.
>> Actuially it's the last one I need to graduate - I should have done this earlier)
>> anyway I suspect that this might have a problem to do with multicast.
>
> DHCP usually depends on promiscuous mode, not multicast. In BSD,
> this means that a) the driver has to properly turn on promiscuous
> mode when someone calls does a SIOCSIFFLAGS ioctl to set the
> IFF_PROMISC flag (trace through the ndis_ioctl() handler and you
> should see how this is done -- with NDIS, it uses ndis_set_info()
> to twiddle the receive filter OID to include the promisc mode
> bit), and b) the driver has to support BPF correctly, since the
> dhclient program relies on BPF to capture raw packets from the
> interface during the DHCP negotiation. Remember that you use DHCP
> to obtain an address; until you have a proper IP address, netmask
> default gateway, etc... set up, you can't use sockets. Hence
> dhclient uses BPF to send and receive packets.
>
> Note: traditionally, each driver would call bpf_mtap() for each
> received frame so that BPF could make a copy of it and send it to
> any BPF listeners that might be attached to the interface. In
> FreeBSD, the call to bpf_mtap() has been moved inside ether_input()
> in if_ethersubr.c (invoked via (*ifp->if_input)()), so the drivers
> don't need to explicitly invoke bpf_mtap() themselves anymore.
> I don't know if NetBSD has been similarly changed. If it hasn't,
> I can't remember if you said whether tcpdump -i ndis0 worked
> or not. If it does, then you've already got this right. If not,
> this is something to check.

Yes, this was exactly my problem, thanks so much for helping me solve it :-)

I just put a call to bpf_mtap() at the end of ndis_rxeof() right before it calls
ether_ioctl() via ifp->if_input.  After this I can get an IP address from DHCP, in
fact I'm using the driver I generated from the e100bex binary to write this email
right now :-)

>> I tried comparing the e100bex DbgPrint() trace output from FreeBSD to that from
>> NetBSD, and I noticed that in FreeBSD NICSetMulticastList() was getting called a
>> bunch, but in NetBSD it isn't.  I think this might just have to do with a
>> difference
>> in the FreeBSD/NetBSD networking code specifically in ndis_setmulti() I'm using
>> sc->arpcom.ec_multiaddrs in place of ifp->if_multiaddrs (the NetBSD ifnet
>> structure
>> dosen't have this field) and when ndis_setmulti() gets called in FreeBSD
>> ifp->if_multiaddrs seems to be non-empty, but sc->arpcom.ec_multiaddrs appears to
>> always be empty in NetBSD.
>
> At least in FreeBSD, if an interface has the IFF_MULTICAST flag set,
> the TCP/IP stack will join the 'all hosts' group (224.2.0,1, I
> think... something like that) as soon as the interface comes up.
> If you have IPv6 support built into the kernel (which is the default),
> it may join a bunch of other groups too. I wouldn't expect NetBSD
> to be too different. I'm not sure what's happening here.

I think I solved this problem too, it seems that in NetBSD I need to call
ether_ioctl() when it gets a SIOCADDMULTI ioctl.

>> I just wrote functions (orriginally #defines) mtx_lock(), mtx_unlock(),
>> mtx_lock_spin(), mtx_unlock_spin() to simulate the FreeBSD functions using NetBSD
>> calls.  I don't think NetBSD spinlocks (simplelock's) block off interrupts
>> automatically when they are held.  Right now in place of mtx_lock_spin() I'm
>> raising
>> the IPL to IPL_NET (using splnet()), and acquiring the lock.  I don't think
>> NetBSD
>> kernel threads can be preempted by anything other than interrupts right now, so I
>> don't think there's any reason to raise the IPL higher than IPL_NET, but I'm not
>> an
>> expert on this.  Also right now I'm just using a uniprocessor system, so I have
>> no
>> idea if this will work on anything else.
>
> Careful: mtx_lock() and so forth aren't the same as KeAcquireSpinLock()
> and friends. Locking is a very messy issue. I still don't think I've
> got it exactly right. Make sure you understand the difference
> between a spin lock and a sleep lock. And make sure your implementation
> of the Windows locking primitives work enough like they do in Windows.

Yes, I'm not confident at all that I have the locking done correctly right now. 
It's apparently good enough to make the driver functional, but from time to time the
OS freezes.  I'll spend some time on this soon.

Anyway, I'm not sure now what my next step should be.  I definately have more
debugging to do, but it seems that I now have a functional driver for the e100bex. 
I'm thinking I should spend some time cleaning up the code (it's rather messy right
now, with lots of commented out code, etc...) and try to get the LKM version of the
driver working again (right now it just compiles into the kernel so I can use the
debugger).  After that I'm thinking I might just try it out with a few other wired
PCI cards to try to excercise any ndis code that isn't used by the e100bex driver,
then start working on a wireless driver.

Just out of curiosity, I don't suppose you happen to know of any wireless cards that
have Windows driver source available?  I'm guessing not, but this would be so nice.

Thanks again for your help, I appreciate it greatly.  It is also helpfull that the
original FreeBSD source is structured so well, and there are so many informative
comments that explain everything :-)

> -Bill
>
> --
> =============================================================================
> -Bill Paul            (510) 749-2329 | Senior Engineer, Master of Unix-Fu
>                  wpaul@windriver.com | Wind River Systems
> =============================================================================
>               <adamw> you're just BEGGING to face the moose
> =============================================================================
>