freebsd-nq/sys/dev/if_ndis
Bill Paul 06794990cb Fix two problems:
- In subr_ndis.c:ndis_allocate_sharemem(), create the busdma tags
  used for shared memory allocations with a lowaddr of 0x3E7FFFFF.
  This forces the buffers to be mapped to physical/bus addresses within
  the first 1GB of physical memory. It seems that at least one card
  (Linksys Instant Wireless PCI V2.7) depends on this behavior. I
  don't know if this is a hardware restriction, or if the NDIS
  driver for this card is truncating the addresses itself, but using
  physical/bus addresses beyong the 1GB limit causes initialization
  failures.

- Create am NDIS_INITIALIZED() macro in if_ndisvar.h and use it in
  if_ndis.c to test whether the device has been initialized rather
  than checking for the presence of the IFF_UP flag in if_flags.
  While debugging the previous problem, I noticed that bringing
  up the device would always produce failures from ndis_setmulti().
  It turns out that the following steps now occur during device
  initialization:

	- IFF_UP flag is set in if_flags
	- ifp->if_ioctl() called with SIOCSIFADDR (which we don't handle)
	- ifp->if_ioctl() called with SIOCADDMULTI
	- ifp->if_ioctl() called with SIOCADDMULTI (again)
	- ifp->if_ioctl() called with SIOCADDMULTI (yet again)
	- ifp->if_ioctl() called with SIOCSIFFLAGS

  Setting the receive filter and multicast filters can only be done
  when the underlying NDIS driver has been initialized, which is done
  by ifp->if_init(). However, we don't call ifp->if_init() until
  ifp->if_ioctl() is called with SIOCSIFFLAGS and IFF_UP has been
  set. It appears that now, the network stack tries to add multicast
  addresses to interface's filter before those steps occur. Normally,
  ndis_setmulti() would trap this condition by checking for the IFF_UP
  flag, but the network code has in fact set this flag already, so
  ndis_setmulti() is fooled into thinking the interface has been
  initialized when it really hasn't.

  It turns out this is usually harmless because the ifp->if_init()
  routine (in this case ndis_init()) will set up the multicast
  filter when it initializes the hardware anyway, and the underlying
  routines (ndis_get_info()/ndis_set_info()) know that the driver/NIC
  haven't been initialized yet, but you end up spurious error messages
  on the console all the time.

Something tells me this new behavior isn't really correct. I think
the intention was to fix it so that ifp->if_init() is only called
once when we ifconfig an interface up, but the end result seems a
little bogus: the change of the IFF_UP flag should be propagated
down to the driver before calling any other ioctl() that might actually
require the hardware to be up and running.
2004-07-07 17:46:30 +00:00
..
if_ndis_pccard.c Explicitly #include <sys/module.h> in these files too (they use 2004-06-01 23:27:36 +00:00
if_ndis_pci.c Explicitly #include <sys/module.h> in these files too (they use 2004-06-01 23:27:36 +00:00
if_ndis.c Fix two problems: 2004-07-07 17:46:30 +00:00
if_ndisvar.h Fix two problems: 2004-07-07 17:46:30 +00:00