368650 |
14-Dec-2020 |
brooks |
MFC r368561:
ndis(4): expand deprecation to the whole driver
nids(4) was a clever idea in the early 2000's when the market was flooded with 10/100 NICs with Windows-only drivers, but that hasn't been the case for ages and the driver has had no meaningful maintenance in ages. It only supports Windows-XP era drivers.
Reviewed by: imp, bcr Sponsored by: DARPA Differential Revision: https://reviews.freebsd.org/D27527 |
343819 |
06-Feb-2019 |
avos |
MFC r343574: Fix compilation with 'option NDISAPI + device ndis' and without 'device pccard' in the kernel config file.
PR: 171532 Reported by: Robert Bonomi <bonomi@host128.r-bonomi.com> |
332288 |
08-Apr-2018 |
brooks |
MFC r331797:
Use an accessor function to access ifr_data.
This fixes 32-bit compat (no ioctl command defintions are required as struct ifreq is the same size).
Reviewed by: kib Obtained from: CheriBSD Sponsored by: DARPA, AFRL Differential Revision: https://reviews.freebsd.org/D14900 |
331722 |
29-Mar-2018 |
eadler |
Revert r330897:
This was intended to be a non-functional change. It wasn't. The commit message was thus wrong. In addition it broke arm, and merged crypto related code.
Revert with prejudice.
This revert skips files touched in r316370 since that commit was since MFCed. This revert also skips files that require $FreeBSD$ property changes.
Thank you to those who helped me get out of this mess including but not limited to gonzo, kevans, rgrimes.
Requested by: gjb (re) |
330897 |
14-Mar-2018 |
eadler |
Partial merge of the SPDX changes
These changes are incomplete but are making it difficult to determine what other changes can/should be merged.
No objections from: pfg |
319726 |
08-Jun-2017 |
glebius |
MFC r318677: Fix regression in ndis(4) after r286410. This adds a bunch of checks for whether this is a Ethernet or 802.11 device and does proper dereferencing.
PR: 213237 Submitted by: <ota j.email.ne.jp> Approved by: re (marius) |
302408 |
08-Jul-2016 |
gjb |
Copy head@r302406 to stable/11 as part of the 11.0-RELEASE cycle. Prune svn:mergeinfo from the new branch, as nothing has been merged here.
Additional commits post-branch will follow.
Approved by: re (implicit) Sponsored by: The FreeBSD Foundation |
298955 |
03-May-2016 |
pfg |
sys/dev: minor spelling fixes.
Most affect comments, very few have user-visible effects.
|
298818 |
29-Apr-2016 |
avos |
net80211 + drivers: hide size of 'bands' array behind a macro.
Auto-replace 'howmany(IEEE80211_MODE_MAX, 8)' with 'IEEE80211_MODE_BYTES'. No functional changes.
|
298307 |
19-Apr-2016 |
pfg |
sys/dev: use our nitems() macro when it is avaliable through param.h.
No functional change, only trivial cases are done in this sweep, Drivers that can get further enhancements will be done independently.
Discussed in: freebsd-current
|
296137 |
27-Feb-2016 |
jhibbits |
Migrate many bus_alloc_resource() calls to bus_alloc_resource_anywhere().
Most calls to bus_alloc_resource() use "anywhere" as the range, with a given count. Migrate these to use the new bus_alloc_resource_anywhere() API.
Reviewed by: jhb Differential Revision: https://reviews.freebsd.org/D5370
|
293339 |
07-Jan-2016 |
avos |
net80211 drivers: fix ieee80211_init_channels() usage
Fix out-of-bounds read (all) / write (11n capable) for drivers that are using ieee80211_init_channels() to initialize channel list.
Tested with: * RTL8188EU, STA mode. * RTL8188CUS, STA mode. * WUSB54GC, HOSTAP mode.
Approved by: adrian (mentor) MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D4818
|
292411 |
17-Dec-2015 |
glebius |
Fix regression in if_ndis in r280347.
Submitted by: avos Reported by: Ev Bogdanov <evbogdanov yahoo.com> Tested by: Ivan Kormachev <ikormachev depit.ru> MFC after: 3 days
|
288635 |
03-Oct-2015 |
adrian |
net80211: drop redundant 3rd parameter from iv_key_set().
The MAC can be fetched from the key struct.
I added the ndis updates to make it compile.
Submitted by: <s3erios@gmail.com> Differential Revision: https://reviews.freebsd.org/D3657
|
287197 |
27-Aug-2015 |
glebius |
Replay r286410. Change KPI of how device drivers that provide wireless connectivity interact with the net80211 stack.
Historical background: originally wireless devices created an interface, just like Ethernet devices do. Name of an interface matched the name of the driver that created. Later, wlan(4) layer was introduced, and the wlanX interfaces become the actual interface, leaving original ones as "a parent interface" of wlanX. Kernelwise, the KPI between net80211 layer and a driver became a mix of methods that pass a pointer to struct ifnet as identifier and methods that pass pointer to struct ieee80211com. From user point of view, the parent interface just hangs on in the ifconfig list, and user can't do anything useful with it.
Now, the struct ifnet goes away. The struct ieee80211com is the only KPI between a device driver and net80211. Details:
- The struct ieee80211com is embedded into drivers softc. - Packets are sent via new ic_transmit method, which is very much like the previous if_transmit. - Bringing parent up/down is done via new ic_parent method, which notifies driver about any changes: number of wlan(4) interfaces, number of them in promisc or allmulti state. - Device specific ioctls (if any) are received on new ic_ioctl method. - Packets/errors accounting are done by the stack. In certain cases, when driver experiences errors and can not attribute them to any specific interface, driver updates ic_oerrors or ic_ierrors counters.
Details on interface configuration with new world order: - A sequence of commands needed to bring up wireless DOESN"T change. - /etc/rc.conf parameters DON'T change. - List of devices that can be used to create wlan(4) interfaces is now provided by net.wlan.devices sysctl.
Most drivers in this change were converted by me, except of wpi(4), that was done by Andriy Voskoboinyk. Big thanks to Kevin Lo for testing changes to at least 8 drivers. Thanks to pluknet@, Oliver Hartmann, Olivier Cochard, gjb@, mmoll@, op@ and lev@, who also participated in testing.
Reviewed by: adrian Sponsored by: Netflix Sponsored by: Nginx, Inc.
|
286437 |
08-Aug-2015 |
adrian |
Revert the wifi ifnet changes until things are more baked and tested.
* 286410 * 286413 * 286416
The initial commit broke a variety of debug and features that aren't in the GENERIC kernels but are enabled in other platforms.
|
286410 |
07-Aug-2015 |
glebius |
Change KPI of how device drivers that provide wireless connectivity interact with the net80211 stack.
Historical background: originally wireless devices created an interface, just like Ethernet devices do. Name of an interface matched the name of the driver that created. Later, wlan(4) layer was introduced, and the wlanX interfaces become the actual interface, leaving original ones as "a parent interface" of wlanX. Kernelwise, the KPI between net80211 layer and a driver became a mix of methods that pass a pointer to struct ifnet as identifier and methods that pass pointer to struct ieee80211com. From user point of view, the parent interface just hangs on in the ifconfig list, and user can't do anything useful with it.
Now, the struct ifnet goes away. The struct ieee80211com is the only KPI between a device driver and net80211. Details:
- The struct ieee80211com is embedded into drivers softc. - Packets are sent via new ic_transmit method, which is very much like the previous if_transmit. - Bringing parent up/down is done via new ic_parent method, which notifies driver about any changes: number of wlan(4) interfaces, number of them in promisc or allmulti state. - Device specific ioctls (if any) are received on new ic_ioctl method. - Packets/errors accounting are done by the stack. In certain cases, when driver experiences errors and can not attribute them to any specific interface, driver updates ic_oerrors or ic_ierrors counters.
Details on interface configuration with new world order: - A sequence of commands needed to bring up wireless DOESN"T change. - /etc/rc.conf parameters DON'T change. - List of devices that can be used to create wlan(4) interfaces is now provided by net.wlan.devices sysctl.
Most drivers in this change were converted by me, except of wpi(4), that was done by Andriy Voskoboinyk. Big thanks to Kevin Lo for testing changes to at least 8 drivers. Thanks to Olivier Cochard, gjb@, mmoll@, op@ and lev@, who also participated in testing. Details here:
https://wiki.freebsd.org/projects/ifnet/net80211
Still, drivers: ndis, wtap, mwl, ipw, bwn, wi, upgt, uath were not tested. Changes to mwl, ipw, bwn, wi, upgt are trivial and chances of problems are low. The wtap wasn't compilable even before this change. But the ndis driver is complex, and it is likely to be broken with this commit. Help with testing and debugging it is appreciated.
Differential Revision: D2655, D2740 Sponsored by: Nginx, Inc. Sponsored by: Netflix
|
283540 |
25-May-2015 |
glebius |
Change three methods in struct ieee80211com, namely ic_updateslot, ic_update_mcast and ic_update_promisc, to pass pointer to the ieee80211com, not to the ifnet.
Sponsored by: Netflix Sponsored by: Nginx, Inc.
|
283537 |
25-May-2015 |
glebius |
Set ic_softc in all 802.11 drivers. Not required right now, but will be used quite soon.
Sponsored by: Netflix Sponsored by: Nginx, Inc.
|
283527 |
25-May-2015 |
glebius |
Make net80211 drivers supply their device name to the net80211 layer, so that the latter doesn't need to go through struct ifnet to get their name.
Sponsored by: Netflix Sponsored by: Nginx, Inc.
|
283291 |
22-May-2015 |
jkim |
CALLOUT_MPSAFE has lost its meaning since r141428, i.e., for more than ten years for head. However, it is continuously misused as the mpsafe argument for callout_init(9). Deprecate the flag and clean up callout_init() calls to make them more consistent.
Differential Revision: https://reviews.freebsd.org/D2613 Reviewed by: jhb MFC after: 2 weeks
|
282742 |
10-May-2015 |
adrian |
Prepare for supporting driver-overridden curchan when submitting scan results.
Right now the scan infrastructure assumes the channel is under net80211 control, and that when receiving beacon frames for scanning, the current channel is indeed what ic_curchan is set to.
But firmware NICs with firmware scan support need more than this - they can do background scans whilst hiding the off-channel behaviour from net80211. Ie, net80211 still thinks everything is associated and on the main channel, but it's getting scan results from all the background traffic.
However sta_add() pays attention to ic_curchan and discards scan results that aren't on the right channel. CCK beacon frames can be decoded from adjacent channels so the receive path and sta_add discard these as appropriate. This is fine for software scanning like for ath(4), but not for firmware NICs. So with those, the whole concept of background firmware scanning won't work without major hacks (eg, overriding ic_curchan before calling the beacon input / scan add.)
As part of my scan overhaul, modify sta_add() and the scan_add() APIs to take an explicit current channel. The normal RX path will set it to ic_curchan so it's a no-op. However, drivers may decide to (eventually!) override the scan method to set the "right" current channel based on what the firmware reports the scan state is.
So for example, iwn, rsu and other NICs will eventually do this:
* driver issues scan start firmware command; * firmware sends a "scan start on channel X" notify; * firmware sends a bunch of beacon RX's as part of the scan results; * .. and the driver will replace scan_add() curchan with channel X, so scan results are correct. * firmware sends a "scan start on channel Y" notify; * firmware sends more beacons... * .. the driver replaces scan_add() curchan with channel Y.
Note:
* Eventually, net80211 should eventually grow the idea of a per-packet current channel. It's possible in various modes (eg WAVE, P2P, etc) that individual frames can come in from different channels and that is under firmware control rather than driver/net80211 control, so we should support that.
|
280347 |
22-Mar-2015 |
mav |
Remove MAXBSIZE use from drivers where it has nothing to do.
In some cases limits are just not needed, in others -- DFLTPHYS is the right constant to use instead.
MFC after: 1 month
|
271849 |
19-Sep-2014 |
glebius |
Mechanically convert to if_inc_counter().
|
270830 |
29-Aug-2014 |
jhb |
When anouncing link state changes on an 802.11 interface with a vap, announce the change on the vap's ifnet instead of the main ifnet. This matches the behavior of other wireless drivers in the tree and allows the default devd configuration to correctly start dhclient automatically after an ndis wireless device associates.
MFC after: 2 weeks
|
257241 |
28-Oct-2013 |
glebius |
Include necessary headers that now are available due to pollution via if_var.h.
Sponsored by: Netflix Sponsored by: Nginx, Inc.
|
257176 |
26-Oct-2013 |
glebius |
The r48589 promised to remove implicit inclusion of if_var.h soon. Prepare to this event, adding if_var.h to files that do need it. Also, include all includes that now are included due to implicit pollution via if_var.h
Sponsored by: Netflix Sponsored by: Nginx, Inc.
|
254842 |
25-Aug-2013 |
andre |
Give (*ext_free) an int return value allowing for very sophisticated external mbuf buffer management capabilities in the future.
For now only EXT_FREE_OK is defined with current legacy behavior.
Sponsored by: The FreeBSD Foundation
|
243857 |
04-Dec-2012 |
glebius |
Mechanically substitute flags from historic mbuf allocator with malloc(9) flags in sys/dev.
|
232854 |
12-Mar-2012 |
scottl |
Convert a number of drivers to obtaining their parent DMA tag from their PCI device attachment.
|
229767 |
07-Jan-2012 |
kevlo |
ether_ifattach() sets if_mtu to ETHERMTU, don't bother set it again
Reviewed by: yongari
|
229401 |
03-Jan-2012 |
dim |
In sys/dev/if_ndis/if_ndis_pccard.c, fix a bug where a garbage rid was passed to resource_list_add(). The rid that was just returned by bus_alloc_resource_any() should have been used instead.
Reviewed by: jhb MFC after: 1 week
|
228621 |
17-Dec-2011 |
bschmidt |
Fix some net80211 enum nits: - ic_vap_create() uses an ieee80211_opmode argument - ieee80211_rate2media() takes an ieee80211_phymode argument - ieee80211_plcp2rate() takes an ieee80211_phytype argument - cast to enum ieee80211_protmode and ieee80211_roamingmode to silence compiler warnings
Submitted by: arundel@
|
227843 |
22-Nov-2011 |
marius |
- There's no need to overwrite the default device method with the default one. Interestingly, these are actually the default for quite some time (bus_generic_driver_added(9) since r52045 and bus_generic_print_child(9) since r52045) but even recently added device drivers do this unnecessarily. Discussed with: jhb, marcel - While at it, use DEVMETHOD_END. Discussed with: jhb - Also while at it, use __FBSDID.
|
217727 |
22-Jan-2011 |
thompsa |
Revert the ndis part of r212122, windrv_stub.c already adds a MODULE_VERSION and this breaks loading miniport drivers from loader.conf
Reported by: Yuri <yuri^rawbw^com> Submitted by: Paul B Mahol MFC after: 3 days
|
217118 |
07-Jan-2011 |
bschmidt |
Don't try to free an unassigned pointer.
Submitted by: Paul B Mahol <onemda at gmail.com> MFC after: 1 week
|
216558 |
19-Dec-2010 |
tijl |
Fix a bug introduced in r216518. The ndis_subsys field holds the PCI subdevice ID in addition to the subvendor ID.
Reported by: Paul B Mahol 'onemda gmail com' Approved by: kib (mentor)
|
216518 |
18-Dec-2010 |
tijl |
Use convenience functions where possible instead of accessing the PCI configuration registers directly.
Remove pci_enable_io calls where they are redundant. The PCI bus driver will set the right bits when the corresponding bus resource is activated.
Remove redundant pci_* function calls from suspend/resume methods. The bus driver already saves and restores the PCI configuration.
Reviewed by: jhb Approved by: kib (mentor)
|
216486 |
16-Dec-2010 |
jhb |
Use bus_alloc_resource_any() instead of bus_alloc_resource(). Besides being cleaner, this fixes problems where the code was using ~0 instead of ~0ul for the upper bound on "any" resources.
MFC after: 1 month
|
214070 |
19-Oct-2010 |
bschmidt |
There is no reason to call rt_ifmsg(), remove it.
Submitted by: Paul B Mahol <onemda at gmail.com> MFC after: 1 week
|
213778 |
13-Oct-2010 |
rpaulo |
WPA_CSE_WEP104 was being incorrectly checked.
Found with: clang
|
212122 |
01-Sep-2010 |
thompsa |
Add missing MODULE_VERSION() definitions, this resolves problems around duplicate module loads.
PR: usb/125736 Submitted by: danger, mm Reviewed by: hselasky
|
201758 |
07-Jan-2010 |
mbr |
Remove extraneous semicolons, no functional changes.
Submitted by: Marc Balmer <marc@msys.ch> MFC after: 1 week
|
201644 |
06-Jan-2010 |
rpaulo |
len must be int, not size_t
Submitted by: novel
|
201620 |
05-Jan-2010 |
rpaulo |
Add net80211 media status reporting.
PR: 142197 Submitted by: Paul <onemda at gmail.com>
|
200824 |
22-Dec-2009 |
thompsa |
Set correct USB device description
Submitted by: Paul B Mahol
|
200524 |
14-Dec-2009 |
rpaulo |
Pass all IEs to net80211.
PR: 141376 Submitted by: Paul <onemda at gmail.com> MFC after: 1 week
|
200037 |
02-Dec-2009 |
jhb |
ndis_scan_results() can sleep if the scan results are not ready when ndis_scan() is called. However, ndis_scan() is invoked from softclock() and cannot sleep. Move ndis_scan_results() to the ndis' driver's scan_end hook instead.
Submitted by: Paul B Mahol onemda of gmail MFC after: 1 week
|
198786 |
02-Nov-2009 |
rpaulo |
Big style cleanup. While there remove references to FreeBSD versions older than 6.0.
Submitted by: Paul B Mahol <onemda at gmail.com>
|
197659 |
01-Oct-2009 |
cokane |
Fix a bad use of NULL instead of zero for int comparison. Sorry for the breakage.
Submitted by: bz, des, onemda MFC after: 3 days
|
197654 |
01-Oct-2009 |
cokane |
style(9) fixes (always compare pointers to NULL)
Also, the previous commit to sys/dev/if_ndis/if_ndis.c also included the removal of a call to ndis_setstate_80211 that is no longer needed.
Submitted by: sam MFC after: 3 days
|
197644 |
30-Sep-2009 |
cokane |
Correct a bug that could lead to a kernel panic if a user attempted to perform 802.11 operations directly on the ndis0 interface before the first VAP (wlan0) had been created. This would lead to a NULL-pointer dereference in the kernel.
Submitted by: Paul B. Mahol <onemda@gmail.com> MFC after: 3 days
|
197403 |
22-Sep-2009 |
cokane |
The ndis_scan function may be started after ndis vap have been destroyed
PR: kern/138632 Submitted by: Paul B. Mahol <onemda at gmail.com> MFC after: 3 days
|
195791 |
20-Jul-2009 |
cokane |
Fix regression in last set of commits. Submitted via e-mail and then nagged again via PR. Thank Paul for his persistence and contributions.
PR: 136895 Submitted by: Paul B. Mahol <onemda@gmail.com> Reviewed by: sam (timeout, 10 days), weongyo (timeout, 10 days), me Approved by: re (Kostik Belousov <kostikbel@gmail.com>)
|
195049 |
26-Jun-2009 |
rwatson |
Use if_maddr_rlock()/if_maddr_runlock() rather than IF_ADDR_LOCK()/ IF_ADDR_UNLOCK() across network device drivers when accessing the per-interface multicast address list, if_multiaddrs. This will allow us to change the locking strategy without affecting our driver programming interface or binary interface.
For two wireless drivers, remove unnecessary locking, since they don't actually access the multicast address list.
Approved by: re (kib) MFC after: 6 weeks
|
194706 |
23-Jun-2009 |
cokane |
Code cleanup by moving some repetitive code into an ndis_get_bssid_list helper function. Also, add ieee80211_announce() call for bootverbose case.
Submitted by: Paul B. Mahol <onemda@gmail.com>
|
194677 |
23-Jun-2009 |
thompsa |
- Make struct usb_xfer opaque so that drivers can not access the internals - Reduce the number of headers needed for a usb driver, the common case is just usb.h and usbdi.h
|
194432 |
18-Jun-2009 |
cokane |
Replace use of ic->ic_flags with vap->iv_flags to operate on per-vap flags for ndis 802.11 work.
Submitted by: Paul B. Mahol <onemda@gmail.com>
|
194228 |
15-Jun-2009 |
thompsa |
s/usb2_/usb_|usbd_/ on all function names for the USB stack.
|
193937 |
10-Jun-2009 |
cokane |
Fix an LOR
Submitted by: Paul B. Mahol <onemda@gmail.com> MFC after: 1 week
|
193742 |
08-Jun-2009 |
thompsa |
Commit missed driver_info to driver_ivar change in usb_attach_args.
Pointed out by: kib
|
193342 |
02-Jun-2009 |
sam |
fix setting of ni_txrate
Submitted by: "Paul B. Mahol" <onemda@gmail.com>
|
193045 |
29-May-2009 |
thompsa |
s/usb2_/usb_/ on all typedefs for the USB stack.
|
192984 |
28-May-2009 |
thompsa |
s/usb2_/usb_/ on all C structs for the USB stack.
|
192505 |
21-May-2009 |
thompsa |
Fix a few variable renames of usb2_mode outside dev/usb.
|
192497 |
20-May-2009 |
sam |
update for net80211 rx api change
|
191746 |
02-May-2009 |
thompsa |
Create a taskqueue for each wireless interface which provides a serialised sleepable context for net80211 driver callbacks. This removes the need for USB and firmware based drivers to roll their own code to defer the chip programming for state changes, scan requests, channel changes and mcast/promisc updates. When a driver callback completes the hardware state is now guaranteed to have been updated and is in sync with net80211 layer.
This nukes around 1300 lines of code from the wireless device drivers making them more readable and less race prone.
The net80211 layer has been updated as follows - all state/channel changes are serialised on the taskqueue. - ieee80211_new_state() always queues and can now be called from any context - scanning runs from a single taskq function and executes to completion. driver callbacks are synchronous so the channel, phy mode and rx filters are guaranteed to be set in hardware before probe request frames are transmitted.
Help and contributions from Sam Leffler.
Reviewed by: sam
|
191163 |
16-Apr-2009 |
thompsa |
Only call ieee80211_start_all() if its a 80211 device.
Submitted by: Paul B. Mahol
|
190850 |
08-Apr-2009 |
sam |
o add a capability for drivers that require 802.3 encapsulation of frames passed down through the transmit path o mark ndis requiring 802.3 encap'd frames
Reviewed by: "Paul B. Mahol" <onemda@gmail.com>, thompsa
|
190526 |
29-Mar-2009 |
sam |
Eliminate ic_myaddr so changing the mac address of a device works correctly: o remove ic_myaddr from ieee80211com o change ieee80211_ifattach to take the mac address of the physical device and use that to setup the lladdr. o replace all references to ic_myaddr in drivers by IF_LLADDR o related cleanups (e.g. kill dead code)
PR: kern/133178 Reviewed by: thompsa, rpaulo
|
190367 |
24-Mar-2009 |
weongyo |
set NULL after free to avoid duplicate free.
Tested by: Ganbold <ganbold_at_micom.mng.net>
|
189950 |
18-Mar-2009 |
weongyo |
Some NDIS USB drivers try to call URB funcs like URB_FUNCTION_VENDOR_xxx or URB_FUNCTION_CLASS_xxx with HAL preemption lock that means it's non-sleepable during USB requests though usb2_do_request() requires a sleep so it needs to send queries to the default pipe without those interfaces to avoid sleep.
|
189719 |
12-Mar-2009 |
weongyo |
o change a lock model based on HAL preemption lock to a normal mtx. Based on the HAL preemption lock there is a problem on SMP machines and causes a panic. o When a device detached the current tactic to detach NDIS USB driver is to call SURPRISE_REMOVED event. So it don't need to call ndis_halt_nic() again. This fixes some page faults when some drivers work abnormal. o it assumes now that URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER is in DISPATCH_LEVEL (non-sleepable) and as further work URB_FUNCTION_VENDOR_XXX and URB_FUNCTION_CLASS_XXX should be.
Reviewed by: Hans Petter Selasky <hselasky_at_freebsd.org> Tested by: Paul B. Mahol <onemda_at_gmail.com>
|
189575 |
09-Mar-2009 |
imp |
remove now-redunant cardbus attachment.
|
189550 |
09-Mar-2009 |
sam |
Fix TXPMGT handling: o correct dBm<->mW conversion logic o set net80211 TXPMGT capability only if driver reports it is capable
PR: kern/132342 Submitted by: "Paul B. Mahol" <onemda@gmail.com>
|
189488 |
07-Mar-2009 |
weongyo |
o port NDIS USB support from USB1 to the new usb(USB2). o implement URB_FUNCTION_ABORT_PIPE handling. o remove unused code related with canceling the timer list for USB drivers. o whitespace cleanup and style(9)
Obtained from: hps's original patch
|
188939 |
23-Feb-2009 |
thompsa |
Move usb to a graveyard location under sys/legacy/dev, it is intended that the new USB2 stack will fully replace this for 8.0.
Remove kernel modules, a subsequent commit will update conf/files. Unhook usbdevs from the build.
|
187104 |
12-Jan-2009 |
thompsa |
Provide a NDIS tx power level converstion to/from net80211, this uses a loookup table to approximate mW<->dBM.
Submitted by: Paul B. Mahol
|
186919 |
09-Jan-2009 |
weongyo |
fix a typo to set the 48Mbps data rate.
PR: kern/130189 Submitted by: Paul B. Mahol <onemda_at_gmail.com> Reviewed by: sam MFC after: 3 weeks
|
186507 |
27-Dec-2008 |
weongyo |
Integrate the NDIS USB support code to CURRENT.
Now the NDISulator supports NDIS USB drivers that it've tested with devices as follows:
- Anygate XM-142 (Conexant) - Netgear WG111v2 (Realtek) - U-Khan UW-2054u (Marvell) - Shuttle XPC Accessory PN20 (Realtek) - ipTIME G054U2 (Ralink) - UNiCORN WL-54G (ZyDAS) - ZyXEL G-200v2 (ZyDAS)
All of them succeeded to attach and worked though there are still some problems that it's expected to be solved.
To use NDIS USB support, you should rebuild and install ndiscvt(8) and if you encounter a problem to attach please set `hw.ndisusb.halt' to 0 then retry.
I expect no changes of the NDIS code for PCI, PCMCIA devices.
Obtained from: //depot/projects/ndisusb/...
|
185485 |
30-Nov-2008 |
sam |
hookup mcast and promisc callbacks
Submitted by: "Paul B. Mahol" <onemda@gmail.com>
|
184833 |
11-Nov-2008 |
thompsa |
Fake the assoc id so that ndis can work on the latest net80211.
PR: kern/128750 Submitted by: Paul B. Mahol
|
183587 |
04-Oct-2008 |
weongyo |
sc->ndis_txidx should be cycle between 0 and sc->ndis_maxpkts, not NDIS_TXPKTS and don't allocate unused extra spaces for sc->ndis_txarray and sc->ndis_txpool.
PR: kern/127644 Submitted by: Antoine Pelisse <apelisse_at_gmail.com> MFC after: 1 week
|
180375 |
09-Jul-2008 |
cokane |
Fix a mutex LOR introduced by the conversion of if_ndis from spinlocks to mutexes and replacing the obsolete if_watchdog interface. The ndis_ticktask function calls into ieee80211_new_state under one condition with NDIS_LOCK held. The ieee80211_new_state would call into ndis_start in some cases too, resulting in the occasional case where ndis_start acquires NDIS_LOCK from inside the NDIS_LOCK held by ndis_ticktask.
Obtained from: Paul B. Mahol <onemda@gmail.com> MFC after: 1 week
|
179723 |
11-Jun-2008 |
cokane |
Convert ndis_spinlock to ndis_mtx and start using the sleepable mtx interface for NDIS_LOCK/UNLOCK. This should result in less CPU utilization on behalf of the ndis driver. Additionally, this commit also fixes a potential LOR in the ndis_tick code, by not locking inside the ndis_tick function, but instead delegating that work to the helpers called through IoQueueWorkItem. The way that this is currently set up for NDIS prevents us from simply implementing a callout_init_mtx mechanism.
However, the helper functions that handle the various timeout cases implement fine-grained locking using the spinlocks provided by the NDIS-compat layer, and using the mtx that is added with this commit. This leaves the following ndis_softc members operated on in ndis_tick in an unlocked context:
* ndis_hang_timer - Only modified outside of ndis_tick once, before the first callout_reset to schedule ndis_tick * ifp->if_oerrors - Only incremented in two places, which should be an atomic op * ndis_tx_timer - Assigned to 5 (when guaranteed to be 0) or 0 (in txeof), to indicate to ndis_tick what to do. This is the only member of which I was suspicious for needing the NDIS_LOCK here. My testing (and another's) have been fine so far. * ndis_stat_callout - Only uses a simple set of callout routines, callout_reset only called by ndis_tick after the initial reset, and then callout_drain is used exactly once in shutdown code.
The benefit is that ndis_tick doesn't acquire NDIS_LOCK unless one of the timeout conditions is flagged, and it still obeys the locking order semantics that are dictated by the NDIS layer at the moment. I have been investigating a more thorough s/spinlock/mtx/ of the NDIS layer, but the simplest naive approach (replace KeAcquireSpinLock with an mtx implementation) has anti-succeeded for me so far. This is a good first step though.
Tested by: onemda@gmail.com Reviewed by: current@, jhb, thompsa Proposed by: jhb
|
179498 |
03-Jun-2008 |
cokane |
Update if_ndis to remove the legacy if_watchdog interface and bring it more up to date. The watchdog timer, and its associated code, is all collapsed into the ndis_tick function that was implemented for the NDIS-subsystem watchdog. This implementation is similar to what numerous other drivers use to implement the watchdog.
Reviewed by: thompsa, jhb MFC after: 2 weeks
|
179424 |
30-May-2008 |
weongyo |
Fix a panic that it's occurred when NDIS init handler returned a error by unknown reasons. In this case, sc->ifp is still NULL so it will cause a page fault during calling ndis_detach()
|
178957 |
12-May-2008 |
sam |
Minor cleanup of vap create work: o add IEEE80211_C_STA capability to indicate sta mode is supported (was previously assumed) and mark drivers as capable o add ieee80211_opcap array to map an opmode to the equivalent capability bit o move IEEE80211_C_OPMODE definition to where capabilities are defined so it's clear it should be kept in sync (on future additions) o check device capabilities in clone create before trying to create a vap; this makes driver checks unneeded o make error codes return on failed clone request unique o temporarily add console printfs on clone request failures to aid in debugging; these will move under DIAGNOSTIC or similar before release
|
178930 |
10-May-2008 |
thompsa |
- Associate from a taskq as we can deadlock on the ndis hal and the com lock. - Remove double vap init (ieee80211_start_all) - Keep ic_curchan in sync with the scan results.
|
178929 |
10-May-2008 |
thompsa |
Partially revert the last rev. Do call ndis_setstate_80211() when we up the interface but break out the associate code into a separate function. This fixes association with an 11b Apple Airport.
Reported by: Ted Lindgreen
|
178705 |
01-May-2008 |
thompsa |
Do not call ndis_setstate_80211() until we are ready to associate, the vap may not have been created yet and will panic. This requires ndis_scan() to always set the SSID.
Reported by: Ben Kaduk
|
178704 |
01-May-2008 |
thompsa |
Unify all the wifi *_ioctl routines - Limit grabbing the lock to SIOCSIFFLAGS. - Move ieee80211_start_all() to SIOCSIFFLAGS. - Remove SIOCSIFMEDIA as it is not useful. - Limit ether_ioctl to only SIOCGIFADDR. SIOCSIFADDR and SIOCSIFMTU have no affect as there is no input/output path in the vap parent. The vap code will handle the reinit of the mac address changes. - Split off ndis_ioctl_80211 as it was getting too different to wired devices.
This fixes a copyout while locked and a lock recursion.
Reviewed by: sam
|
178354 |
20-Apr-2008 |
sam |
Multi-bss (aka vap) support for 802.11 devices.
Note this includes changes to all drivers and moves some device firmware loading to use firmware(9) and a separate module (e.g. ral). Also there no longer are separate wlan_scan* modules; this functionality is now bundled into the wlan module.
Supported by: Hobnob and Marvell Reviewed by: many Obtained from: Atheros (some bits)
|
178288 |
17-Apr-2008 |
cokane |
Change the 1 in callout_init to CALLOUT_MPSAFE. I made the change in my tree, but never committed it into git before making my patch!
Submitted by: thompsa MFC after: 1 month
|
178286 |
17-Apr-2008 |
cokane |
Change the timeout(9) usage in if_ndis to a callout(9) implementation, as the former is becoming deprecated and exhibits some extraneous Giant-locking. The new callout(9) is declared MPSAFE, so it may improve concurrency.
Tested by: matteo Silence from: wpaul MFC after: 1 month
|
175410 |
17-Jan-2008 |
jhb |
Use pause(9) instead of a tsleep() on a stack variable.
MFC after: 1 week
|
174490 |
09-Dec-2007 |
thompsa |
sc->ndis_tq variable is only initialized when a driver module is for wireless NICs.
PR: kern/118439 Submitted by: Weongyo Jeong
|
174401 |
07-Dec-2007 |
thompsa |
Preallocate some space to return the scan results, some drivers do not properly pass back the desired buffer length. This fixes scanning with the Marvell 88W8335 and BCM4328 wireless cards.
PR: kern/118370 Submitted by: Weongyo Jeong Tested by: Ed Schouten
|
174270 |
04-Dec-2007 |
wkoszek |
Cast address of 'bssid' to uint8_t since printf() expects to get unsigned argument in %6D case.
Submitted by: thompsa Compile-tested: wkoszek Reviewed by: cognet (mentor) Approved by: cognet (mentor)
|
174234 |
03-Dec-2007 |
thompsa |
Remove compatibilty defines to simplify reading the code, this is around 10% of the total LOC. These are mostly for the 6.x branch and it will be easier to cherrypick any changes (if at all).
|
174157 |
02-Dec-2007 |
thompsa |
Hide a debug printf, NDIS_DEBUG is always defined and we test the sysctl.
MFC after: 3 days
|
172836 |
20-Oct-2007 |
julian |
Rename the kthread_xxx (e.g. kthread_create()) calls to kproc_xxx as they actually make whole processes. Thos makes way for us to add REAL kthread_create() and friends that actually make theads. it turns out that most of these calls actually end up being moved back to the thread version when it's added. but we need to make this cosmetic change first.
I'd LOVE to do this rename in 7.0 so that we can eventually MFC the new kthread_xxx() calls.
|
171602 |
26-Jul-2007 |
thompsa |
Fix up ndis interaction with net80211 - make NDIS_DEBUG a sysctl - default to IEEE80211_MODE_11B if the card doesnt tell us the channels - dont mess with ic_des_chan when we assosciate - Allow a directed scan by setting the ESSID before scanning (verified with wireshark). Hidden APs probably wouldnt have worked before. - Grab the channel type and use it to look up the correct curchan for the scan results (mistakenly used 11B before) - Fix memory leak in the ndis_scan_results
Tested by: matteo Reviewed by: sam Approved by: re (rwatson)
|
171390 |
12-Jul-2007 |
thompsa |
Improve the net80211 handling within ndis - use net80211 for scanning and pass the results back to the scan cache - use ieee80211_init_channels to fill our channel list - fix up state transitions - depreciate the old wicontrol ioctls - add some debugging lines (#define NDIS_DEBUG)
Reviewed by: sam Approved by: re (kensmith)
|
170934 |
18-Jun-2007 |
imp |
finish removing usb_port.h macros. Use device_foo_t to declare functions a little de-k&r
|
170612 |
12-Jun-2007 |
imp |
Expand USB_ATTACH_{ERROR,SUCCESS}_RETURN inline and eliminate from usb_port.h. They aren't needed, and are a legacy of this code's past.
|
170530 |
11-Jun-2007 |
sam |
Update 802.11 wireless support: o major overhaul of the way channels are handled: channels are now fully enumerated and uniquely identify the operating characteristics; these changes are visible to user applications which require changes o make scanning support independent of the state machine to enable background scanning and roaming o move scanning support into loadable modules based on the operating mode to enable different policies and reduce the memory footprint on systems w/ constrained resources o add background scanning in station mode (no support for adhoc/ibss mode yet) o significantly speedup sta mode scanning with a variety of techniques o add roaming support when background scanning is supported; for now we use a simple algorithm to trigger a roam: we threshold the rssi and tx rate, if either drops too low we try to roam to a new ap o add tx fragmentation support o add first cut at 802.11n support: this code works with forthcoming drivers but is incomplete; it's included now to establish a baseline for other drivers to be developed and for user applications o adjust max_linkhdr et. al. to reflect 802.11 requirements; this eliminates prepending mbufs for traffic generated locally o add support for Atheros protocol extensions; mainly the fast frames encapsulation (note this can be used with any card that can tx+rx large frames correctly) o add sta support for ap's that beacon both WPA1+2 support o change all data types from bsd-style to posix-style o propagate noise floor data from drivers to net80211 and on to user apps o correct various issues in the sta mode state machine related to handling authentication and association failures o enable the addition of sta mode power save support for drivers that need net80211 support (not in this commit) o remove old WI compatibility ioctls (wicontrol is officially dead) o change the data structures returned for get sta info and get scan results so future additions will not break user apps o fixed tx rate is now maintained internally as an ieee rate and not an index into the rate set; this needs to be extended to deal with multi-mode operation o add extended channel specifications to radiotap to enable 11n sniffing
Drivers: o ath: add support for bg scanning, tx fragmentation, fast frames, dynamic turbo (lightly tested), 11n (sniffing only and needs new hal) o awi: compile tested only o ndis: lightly tested o ipw: lightly tested o iwi: add support for bg scanning (well tested but may have some rough edges) o ral, ural, rum: add suppoort for bg scanning, calibrate rssi data o wi: lightly tested
This work is based on contributions by Atheros, kmacy, sephe, thompsa, mlaier, kevlo, and others. Much of the scanning work was supported by Atheros. The 11n work was supported by Marvell.
|
169800 |
20-May-2007 |
mjacob |
Initialize irql to something prior to calls that (might) set it. Whined about: gcc 4.2
|
168423 |
06-Apr-2007 |
pjd |
Use strcasecmp() from libkern.
|
167468 |
11-Mar-2007 |
sam |
change ic_modecaps to a bit vector and use setbit, et. al.
|
165573 |
28-Dec-2006 |
jkim |
Fix shared authentication mode.
|
164033 |
06-Nov-2006 |
rwatson |
Sweep kernel replacing suser(9) calls with priv(9) calls, assigning specific privilege names to a broad range of privileges. These may require some future tweaking.
Sponsored by: nCircle Network Security, Inc. Obtained from: TrustedBSD Project Discussed on: arch@ Reviewed (at least in part) by: mlaier, jmg, pjd, bde, ceri, Alex Lyashkov <umka at sevcity dot net>, Skip Ford <skip dot ford at verizon dot net>, Antoine Brodin <antoine dot brodin at laposte dot net>
|
162102 |
07-Sep-2006 |
mjacob |
Static -> static.
|
162101 |
07-Sep-2006 |
trhodes |
Catch up with USB changes, device_ptr_t was removed, we need device_t here.
|
155311 |
04-Feb-2006 |
wpaul |
When ndis_attach() runs, it has to very briefly initialize the card in order to query the underlying Windows driver for the station address and some other properties. There is a slim chance that the card may receive a packet and indicate it up to us before ndis_attach() can call ndis_halt_nic(). This is bad, because both the softc structure and the ifnet structure aren't fully initialized yet: many pointers are still NULL, so if we make it into ndis_rxeof(), we will panic.
To fix this, we need to do the following:
- Move the calls to IoAllocateWorkItem() to before the call to ndis_init_nic(). - Move the initialization of the RX DPC and status callback function pointers to before ndis_init_nic() as well. - Modify ndis_rxeof() to check if the IFF_DRV_RUNNING flag is set. If it isn't, we return any supplied NDIS_PACKETs to the NIC without processing them.
This fixes a crash than can occur when activating a wireless NIC in close proximity to a very busy wireless network, reported by Ryan Beasley (ryan%^$!ATgoddamnbastard-****!!!DOTorg.
MFC after: 3 days
|
153480 |
16-Dec-2005 |
wpaul |
In ndis_rxeof_eth(), avoid acquiring the NDIS miniport block spinlock for serialized miniports when updating the packet list.
This fixes a deadlock that can occur with the Ralink RT2500 driver when using wpa_supplicant.
|
152136 |
06-Nov-2005 |
wpaul |
The latest version of the Intel 2200BG/2915ABG driver (9.0.0.3-9) from Intel's web site requires some minor tweaks to get it to work:
- The driver seems to have been released with full WMI tracing enabled, and makes references to some WMI APIs, namely IoWMIRegistrationControl(), WmiQueryTraceInformation() and WmiTraceMessage(). Only the first one is ever called (during intialization). These have been implemented as do-nothing stubs for now. Also added a definition for STATUS_NOT_FOUND to ntoskrnl_var.h, which is used as a return code for one of the WMI routines.
- The driver references KeRaiseIrqlToDpcLevel() and KeLowerIrql() (the latter as a function, which is unusual because normally KeLowerIrql() is a macro in the Windows DDK that calls KfLowewIrql()). I'm not sure why these are being called since they're not really part of WDM. Presumeably they're being used for backwards compatibility with old versions of Windows. These have been implemented in subr_hal.c. (Note that they're _stdcall routines instead of _fastcall.)
- When querying the OID_802_11_BSSID_LIST OID to get a BSSID list, you don't know ahead of time how many networks the NIC has found during scanning, so you're allowed to pass 0 as the list length. This should cause the driver to return an 'insufficient resources' error and set the length to indicate how many bytes are actually needed. However for some reason, the Intel driver does not honor this convention: if you give it a length of 0, it returns some other error and doesn't tell you how much space is really needed. To get around this, if using a length of 0 yields anything besides the expected error case, we arbitrarily assume a length of 64K. This is similar to the hack that wpa_supplicant uses when doing a BSSID list query.
|
151977 |
02-Nov-2005 |
wpaul |
Tests with my dual Opteron system have shown that it's possible for code to start out on one CPU when thunking into Windows mode in ctxsw_utow(), and then be pre-empted and migrated to another CPU before thunking back to UNIX mode in ctxsw_wtou(). This is bad, because then we can end up looking at the wrong 'thread environment block' when trying to come back to UNIX mode. To avoid this, we now pin ourselves to the current CPU when thunking into Windows code.
Few other cleanups, since I'm here:
- Get rid of the ndis_isr(), ndis_enable_interrupt() and ndis_disable_interrupt() wrappers from kern_ndis.c and just invoke the miniport's methods directly in the interrupt handling routines in subr_ndis.c. We may as well lose the function call overhead, since we don't need to export these things outside of ndis.ko now anyway.
- Remove call to ndis_enable_interrupt() from ndis_init() in if_ndis.c. We don't need to do it there anyway (the miniport init routine handles it, if needed).
- Fix the logic in NdisWriteErrorLogEntry() a little.
- Change some NDIS_STATUS_xxx codes in subr_ntoskrnl.c into STATUS_xxx codes.
- Handle kthread_create() failure correctly in PsCreateSystemThread().
|
151832 |
29-Oct-2005 |
wpaul |
Fix ndis_getstate_80211() so that it properly reports the authmode and channel to ifconfig. Also use the SSID and channel info from the association info that we already have instead of using ndis_get_info() to ask the driver for it again.
|
151652 |
25-Oct-2005 |
wpaul |
Correct some __FreeBSD_version conditionals to use version bumps closer to the actual dates when code actually changed. Also add special case link state change handling for RELENG_5, which doesn't have if_link_state_change(). No actual operational changes are done.
|
151625 |
24-Oct-2005 |
wpaul |
Do not allow ndis_ticktask() to run after ndis_halt_nic() has been called. (It may have been queued up in one of the workitem threads, and letting it fire after the NIC has been halted will cause a crash in some cases.)
|
151460 |
19-Oct-2005 |
wpaul |
Correct the size used to allocate ndis_txarray. It should be NDIS_TXPKTS now, not ndis_maxpkts.
|
151451 |
18-Oct-2005 |
wpaul |
Another round of cleanups and fixes:
- Change ndis_return() from a DPC to a workitem so that it doesn't run at DISPATCH_LEVEL (with the dispatcher lock held).
- In if_ndis.c, submit packets to the stack via (*ifp->if_input)() in a workitem instead of doing it directly in ndis_rxeof(), because ndis_rxeof() runs in a DPC, and hence at DISPATCH_LEVEL. This implies that the 'dispatch level' mutex for the current CPU is being held, and we don't want to call if_input while holding any locks.
- Reimplement IoConnectInterrupt()/IoDisconnectInterrupt(). The original approach I used to track down the interrupt resource (by scanning the device tree starting at the nexus) is prone to problems when two devices share an interrupt. (E.g removing ndis1 might disable interrupts for ndis0.) The new approach is to multiplex all the NDIS interrupts through a common internal dispatcher (ntoskrnl_intr()) and allow IoConnectInterrupt()/IoDisconnectInterrupt() to add or remove interrupts from the dispatch list.
- Implement KeAcquireInterruptSpinLock() and KeReleaseInterruptSpinLock().
- Change the DPC and workitem threads to use the KeXXXSpinLock API instead of mtx_lock_spin()/mtx_unlock_spin().
- Simplify the NdisXXXPacket routines by creating an actual packet pool structure and using the InterlockedSList routines to manage the packet queue.
- Only honor the value returned by OID_GEN_MAXIMUM_SEND_PACKETS for serialized drivers. For deserialized drivers, we now create a packet array of 64 entries. (The Microsoft DDK documentation says that for deserialized miniports, OID_GEN_MAXIMUM_SEND_PACKETS is ignored, and the driver for the Marvell 8335 chip, which is a deserialized miniport, returns 1 when queried.)
- Clean up timer handling in subr_ntoskrnl.
- Add the following conditional debugging code: NTOSKRNL_DEBUG_TIMERS - add debugging and stats for timers NDIS_DEBUG_PACKETS - add extra sanity checking for NdisXXXPacket API NTOSKRNL_DEBUG_SPINLOCKS - add test for spinning too long
- In kern_ndis.c, always start the HAL first and shut it down last, since Windows spinlocks depend on it. Ntoskrnl should similarly be started second and shut down next to last.
|
151241 |
11-Oct-2005 |
wpaul |
Fix build: remove stale KASSERT() for mutex that no longer exists.
|
151217 |
10-Oct-2005 |
wpaul |
Grrr. Add one more missing NDIS_UNLOCK().
|
151216 |
10-Oct-2005 |
wpaul |
Add missing NDIS_UNLOCK() in one of the failure cases in SIOCGPRIVATE_0.
|
151207 |
10-Oct-2005 |
wpaul |
This commit makes a big round of updates and fixes many, many things.
First and most importantly, I threw out the thread priority-twiddling implementation of KeRaiseIrql()/KeLowerIrq()/KeGetCurrentIrql() in favor of a new scheme that uses sleep mutexes. The old scheme was really very naughty and sought to provide the same behavior as Windows spinlocks (i.e. blocking pre-emption) but in a way that wouldn't raise the ire of WITNESS. The new scheme represents 'DISPATCH_LEVEL' as the acquisition of a per-cpu sleep mutex. If a thread on cpu0 acquires the 'dispatcher mutex,' it will block any other thread on the same processor that tries to acquire it, in effect only allowing one thread on the processor to be at 'DISPATCH_LEVEL' at any given time. It can then do the 'atomic sit and spin' routine on the spinlock variable itself. If a thread on cpu1 wants to acquire the same spinlock, it acquires the 'dispatcher mutex' for cpu1 and then it too does an atomic sit and spin to try acquiring the spinlock.
Unlike real spinlocks, this does not disable pre-emption of all threads on the CPU, but it does put any threads involved with the NDISulator to sleep, which is just as good for our purposes.
This means I can now play nice with WITNESS, and I can safely do things like call malloc() when I'm at 'DISPATCH_LEVEL,' which you're allowed to do in Windows.
Next, I completely re-wrote most of the event/timer/mutex handling and wait code. KeWaitForSingleObject() and KeWaitForMultipleObjects() have been re-written to use condition variables instead of msleep(). This allows us to use the Windows convention whereby thread A can tell thread B "wake up with a boosted priority." (With msleep(), you instead have thread B saying "when I get woken up, I'll use this priority here," and thread A can't tell it to do otherwise.) The new KeWaitForMultipleObjects() has been better tested and better duplicates the semantics of its Windows counterpart.
I also overhauled the IoQueueWorkItem() API and underlying code. Like KeInsertQueueDpc(), IoQueueWorkItem() must insure that the same work item isn't put on the queue twice. ExQueueWorkItem(), which in my implementation is built on top of IoQueueWorkItem(), was also modified to perform a similar test.
I renamed the doubly-linked list macros to give them the same names as their Windows counterparts and fixed RemoveListTail() and RemoveListHead() so they properly return the removed item.
I also corrected the list handling code in ntoskrnl_dpc_thread() and ntoskrnl_workitem_thread(). I realized that the original logic did not correctly handle the case where a DPC callout tries to queue up another DPC. It works correctly now.
I implemented IoConnectInterrupt() and IoDisconnectInterrupt() and modified NdisMRegisterInterrupt() and NdisMDisconnectInterrupt() to use them. I also tried to duplicate the interrupt handling scheme used in Windows. The interrupt handling is now internal to ndis.ko, and the ndis_intr() function has been removed from if_ndis.c. (In the USB case, interrupt handling isn't needed in if_ndis.c anyway.)
NdisMSleep() has been rewritten to use a KeWaitForSingleObject() and a KeTimer, which is how it works in Windows. (This is mainly to insure that the NDISulator uses the KeTimer API so I can spot any problems with it that may arise.)
KeCancelTimer() has been changed so that it only cancels timers, and does not attempt to cancel a DPC if the timer managed to fire and queue one up before KeCancelTimer() was called. The Windows DDK documentation seems to imply that KeCantelTimer() will also call KeRemoveQueueDpc() if necessary, but it really doesn't.
The KeTimer implementation has been rewritten to use the callout API directly instead of timeout()/untimeout(). I still cheat a little in that I have to manage my own small callout timer wheel, but the timer code works more smoothly now. I discovered a race condition using timeout()/untimeout() with periodic timers where untimeout() fails to actually cancel a timer. I don't quite understand where the race is, using callout_init()/callout_reset()/callout_stop() directly seems to fix it.
I also discovered and fixed a bug in winx32_wrap.S related to translating _stdcall calls. There are a couple of routines (i.e. the 64-bit arithmetic intrinsics in subr_ntoskrnl) that return 64-bit quantities. On the x86 arch, 64-bit values are returned in the %eax and %edx registers. However, it happens that the ctxsw_utow() routine uses %edx as a scratch register, and x86_stdcall_wrap() and x86_stdcall_call() were only preserving %eax before branching to ctxsw_utow(). This means %edx was getting clobbered in some cases. Curiously, the most noticeable effect of this bug is that the driver for the TI AXC110 chipset would constantly drop and reacquire its link for no apparent reason. Both %eax and %edx are preserved on the stack now. The _fastcall and _regparm wrappers already handled everything correctly.
I changed if_ndis to use IoAllocateWorkItem() and IoQueueWorkItem() instead of the NdisScheduleWorkItem() API. This is to avoid possible deadlocks with any drivers that use NdisScheduleWorkItem() themselves.
The unicode/ansi conversion handling code has been cleaned up. The internal routines have been moved to subr_ntoskrnl and the RtlXXX routines have been exported so that subr_ndis can call them. This removes the incestuous relationship between the two modules regarding this code and fixes the implementation so that it honors the 'maxlen' fields correctly. (Previously it was possible for NdisUnicodeStringToAnsiString() to possibly clobber memory it didn't own, which was causing many mysterious crashes in the Marvell 8335 driver.)
The registry handling code (NdisOpen/Close/ReadConfiguration()) has been fixed to allocate memory for all the parameters it hands out to callers and delete whem when NdisCloseConfiguration() is called. (Previously, it would secretly use a single static buffer.)
I also substantially updated if_ndis so that the source can now be built on FreeBSD 7, 6 and 5 without any changes. On FreeBSD 5, only WEP support is enabled. On FreeBSD 6 and 7, WPA-PSK support is enabled.
The original WPA code has been updated to fit in more cleanly with the net80211 API, and to eleminate the use of magic numbers. The ndis_80211_setstate() routine now sets a default authmode of OPEN and initializes the RTS threshold and fragmentation threshold. The WPA routines were changed so that the authentication mode is always set first, followed by the cipher. Some drivers depend on the operations being performed in this order.
I also added passthrough ioctls that allow application code to directly call the MiniportSetInformation()/MiniportQueryInformation() methods via ndis_set_info() and ndis_get_info(). The ndis_linksts() routine also caches the last 4 events signalled by the driver via NdisMIndicateStatus(), and they can be queried by an application via a separate ioctl. This is done to allow wpa_supplicant to directly program the various crypto and key management options in the driver, allowing things like WPA2 support to work.
Whew.
|
150636 |
27-Sep-2005 |
mlaier |
Remove bridge(4) from the tree. if_bridge(4) is a full functional replacement and has additional features which make it superior.
Discussed on: -arch Reviewed by: thompsa X-MFC-after: never (RELENG_6 as transition period)
|
150306 |
19-Sep-2005 |
imp |
Make sure that we call if_free(ifp) after bus_teardown_intr. Since we could get an interrupt after we free the ifp, and the interrupt handler depended on the ifp being still alive, this could, in theory, cause a crash. Eliminate this possibility by moving the if_free to after the bus_teardown_intr() call.
|
148887 |
09-Aug-2005 |
rwatson |
Propagate rename of IFF_OACTIVE and IFF_RUNNING to IFF_DRV_OACTIVE and IFF_DRV_RUNNING, as well as the move from ifnet.if_flags to ifnet.if_drv_flags. Device drivers are now responsible for synchronizing access to these flags, as they are in if_drv_flags. This helps prevent races between the network stack and device driver in maintaining the interface flags field.
Many __FreeBSD__ and __FreeBSD_version checks maintained and continued; some less so.
Reviewed by: pjd, bz MFC after: 7 days
|
148654 |
03-Aug-2005 |
rwatson |
Modify device drivers supporting multicast addresses to lock if_addr_mtx over iteration of their multicast address lists when synchronizing the hardware address filter with the network stack-maintained list.
Problem reported by: Ed Maste (emaste at phaedrus dot sandvine dot ca> MFC after: 1 week
|
147386 |
14-Jun-2005 |
brooks |
Move if_alloc() higher in the attach function so sc->ifp is populated early. I've moved it all the way to the top rather than part way up as the submitter did.
Submitted by: Jung-uk Kim <jkim at niksun dot com> Reported by: submitter, le, dougb Approved by: re (ifnet blanket)
|
147256 |
10-Jun-2005 |
brooks |
Stop embedding struct ifnet at the top of driver softcs. Instead the struct ifnet or the layer 2 common structure it was embedded in have been replaced with a struct ifnet pointer to be filled by a call to the new function, if_alloc(). The layer 2 common structure is also allocated via if_alloc() based on the interface type. It is hung off the new struct ifnet member, if_l2com.
This change removes the size of these structures from the kernel ABI and will allow us to better manage them as interfaces come and go.
Other changes of note: - Struct arpcom is no longer referenced in normal interface code. Instead the Ethernet address is accessed via the IFP2ENADDR() macro. To enforce this ac_enaddr has been renamed to _ac_enaddr. - The second argument to ether_ifattach is now always the mac address from driver private storage rather than sometimes being ac_enaddr.
Reviewed by: sobomax, sam
|
146734 |
29-May-2005 |
nyan |
Remove bus_{mem,p}io.h and related code for a micro-optimization on i386 and amd64. The optimization is a trivial on recent machines.
Reviewed by: -arch (imp, marcel, dfr)
|
146427 |
20-May-2005 |
wpaul |
Deal with a few bootstrap issues:
We can't call KeFlushQueuedDpcs() during bootstrap (cold == 1), since the flush operation sleeps to wait for completion, and we can't sleep here (clowns will eat us).
On an i386 SMP system, if we're loaded/probed/attached during bootstrap, smp_rendezvous() won't run us anywhere except CPU 0 (since the other CPUs aren't launched until later), which means we won't be able to set up the GDTs anywhere except CPU 0. To deal with this case, ctxsw_utow() now checks to see if the TID for the current processor has been properly initialized and sets up the GTD for the current CPU if not.
Lastly, in if_ndis.c:ndis_shutdown(), do an ndis_stop() to insure we really halt the NIC and stop interrupts from happening.
Note that loading a driver during bootstrap is, unfortunately, kind of a hit or miss sort of proposition. In Windows, the expectation is that by the time a given driver's MiniportInitialize() method is called, the system is already in 'multiuser' state, i.e. it's up and running enough to support all the stuff specified in the NDIS API, which includes the underlying OS-supplied facilities it implicitly depends on, such as having all CPUs running, having the DPC queues initialized, WorkItem threads running, etc. But in UNIX, a lot of that stuff won't work during bootstrap. This causes a problem since we need to call MiniportInitialize() at least once during ndis_attach() in order to find out what kind of NIC we have and learn its station address.
What this means is that some cards just plain won't work right if you try to pre-load the driver along with the kernel: they'll only be probed/attach correctly if the driver is kldloaded _after_ the system has reached multiuser. I can't really think of a way around this that would still preserve the ability to use an NDIS device for diskless booting.
|
146424 |
20-May-2005 |
wpaul |
In ndis_halt_nic(), invalidate the miniportadapterctx early to try and prevent anything from making calls to the NIC while it's being shut down. This is yet another attempt to stop things like mdnsd from trying to poke at the card while it's not properly initialized and panicking the system.
Also, remove unneeded debug message from if_ndis.c.
|
146279 |
16-May-2005 |
wpaul |
Correct type for workitem routines.
|
146230 |
15-May-2005 |
wpaul |
Add support for NdisMEthIndicateReceive() and MiniportTransferData(). The Ralink RT2500 driver uses this API instead of NdisMIndicateReceivePacket().
Drivers use NdisMEthIndicateReceive() when they know they support 802.3 media and expect to hand their packets only protocols that want to deal with that particular media type. With this API, the driver does not manage its own NDIS_PACKET/NDIS_BUFFER structures. Instead, it lets bound protocols have a peek at the data, and then they supply an NDIS_PACKET/NDIS_BUFFER combo to the miniport driver, into which it copies the packet data.
Drivers use NdisMIndicateReceivePacket() to allow their packets to be read by any protocol, not just those bound to 802.3 media devices.
To make this work, we need an internal pool of NDIS_PACKETS for receives. Currently, we check to see if the driver exports a MiniportTransferData() method in its characteristics structure, and only allocate the pool for drivers that have this method.
This should allow the RT2500 driver to work correctly, though I still have to fix ndiscvt(8) to parse its .inf file properly.
Also, change kern_ndis.c:ndis_halt_nic() to reap timers before acquiring NDIS_LOCK(), since the reaping process might entail sleeping briefly (and we can't sleep with a lock held).
|
146016 |
08-May-2005 |
wpaul |
More fixes for multibus drivers. When calling out to the match function in if_ndis_pci.c and if_ndis_pccard.c, provide the bustype too so the stubs can ignore devlists that don't concern them.
|
146015 |
08-May-2005 |
wpaul |
Fix support for Windows drivers that support both PCI and PCMCIA devices at the same time.
Fix if_ndis_pccard.c so that it sets sc->ndis_dobj and sc->ndis_regvals.
Correct IMPORT_SFUNC() macros for the READ_PORT_BUFFER_xxx() routines, which take 3 arguments, not 2.
This fixes it so that the Windows driver for my Cisco Aironet 340 PCMCIA card works again. (Yes, I know the an(4) driver supports this card natively, but it's the only PCMCIA device I have with a Windows XP driver.)
|
146000 |
08-May-2005 |
wpaul |
Avoid trying to queue up an interrupt handler DPC if the driver hasn't called NdisMRegisterInterrupt() yet.
|
145995 |
08-May-2005 |
wpaul |
Minor correction to the logic for selecting the proper device index.
|
145898 |
05-May-2005 |
wpaul |
Avoid sleeping with mutex held in kern_ndis.c.
Remove unused fields from ndis_miniport_block.
Fix a bug in KeFlushQueuedDpcs() (we weren't calculating the kq pointer correctly).
In if_ndis.c, clear the IFF_RUNNING flag before calling ndis_halt_nic().
Add some guards in kern_ndis.c to avoid letting anyone invoke ndis_get_info() or ndis_set_info() if the NIC isn't fully initialized. Apparently, mdnsd will sometimes try to invoke the ndis_ioctl() routine at exactly the wrong moment (to futz with its multicast filters) when the interface comes up, and can trigger a crash unless we guard against it.
|
145895 |
05-May-2005 |
wpaul |
This commit makes a bunch of changes, some big, some not so big.
- Remove the old task threads from kern_ndis.c and reimplement them in subr_ntoskrnl.c, in order to more properly emulate the Windows DPC API. Each CPU gets its own DPC queue/thread, and each queue can have low, medium and high importance DPCs. New APIs implemented: KeSetTargetProcessorDpc(), KeSetImportanceDpc() and KeFlushQueuedDpcs(). (This is the biggest change.)
- Fix a bug in NdisMInitializeTimer(): the k_dpc pointer in the nmt_timer embedded in the ndis_miniport_timer struct must be set to point to the DPC, also embedded in the struct. Failing to do this breaks dequeueing of DPCs submitted via timers, and in turn breaks cancelling timers.
- Fix a bug in KeCancelTimer(): if the timer is interted in the timer queue (i.e. the timeout callback is still pending), we have to both untimeout() the timer _and_ call KeRemoveQueueDpc() to nuke the DPC that might be pending. Failing to do this breaks cancellation of periodic timers, which always appear to be inserted in the timer queue.
- Make use of the nmt_nexttimer field in ndis_miniport_timer: keep a queue of pending timers and cancel them all in ndis_halt_nic(), prior to calling MiniportHalt(). Also call KeFlushQueuedDpcs() to make sure any DPCs queued by the timers have expired.
- Modify NdisMAllocateSharedMemory() and NdisMFreeSharedMemory() to keep track of both the virtual and physical addresses of the shared memory buffers that get handed out. The AirGo MIMO driver appears to have a bug in it: for one of the segments is allocates, it returns the wrong virtual address. This would confuse NdisMFreeSharedMemory() and cause a crash. Why it doesn't crash Windows too I have no idea (from reading the documentation for NdisMFreeSharedMemory(), it appears to be a violation of the API).
- Implement strstr(), strchr() and MmIsAddressValid().
- Implement IoAllocateWorkItem(), IoFreeWorkItem(), IoQueueWorkItem() and ExQueueWorkItem(). (This is the second biggest change.)
- Make NdisScheduleWorkItem() call ExQueueWorkItem(). (Note that the ExQueueWorkItem() API is deprecated by Microsoft, but NDIS still uses it, since NdisScheduleWorkItem() is incompatible with the IoXXXWorkItem() API.)
- Change if_ndis.c to use the NdisScheduleWorkItem() interface for scheduling tasks.
With all these changes and fixes, the AirGo MIMO driver for the Belkin F5D8010 Pre-N card now works. Special thanks to Paul Robinson (paul dawt robinson at pwermedia dawt net) for the loan of a card for testing.
|
145485 |
24-Apr-2005 |
wpaul |
Throw the switch on the new driver generation/loading mechanism. From here on in, if_ndis.ko will be pre-built as a module, and can be built into a static kernel (though it's not part of GENERIC). Drivers are created using the new ndisgen(8) script, which uses ndiscvt(8) under the covers, along with a few other tools. The result is a driver module that can be kldloaded into the kernel.
A driver with foo.inf and foo.sys files will be converted into foo_sys.ko (and foo_sys.o, for those who want/need to make static kernels). This module contains all of the necessary info from the .INF file and the driver binary image, converted into an ELF module. You can kldload this module (or add it to /boot/loader.conf) to have it loaded automatically. Any required firmware files can be bundled into the module as well (or converted/loaded separately).
Also, add a workaround for a problem in NdisMSleep(). During system bootstrap (cold == 1), msleep() always returns 0 without actually sleeping. The Intel 2200BG driver uses NdisMSleep() to wait for the NIC's firmware to come to life, and fails to load if NdisMSleep() doesn't actually delay. As a workaround, if msleep() (and hence ndis_thsuspend()) returns 0, use a hard DELAY() to sleep instead). This is not really the right thing to do, but we can't really do much else. At the very least, this makes the Intel driver happy.
There are probably other drivers that fail in this way during bootstrap. Unfortunately, the only workaround for those is to avoid pre-loading them and kldload them once the system is running instead.
|
145310 |
20-Apr-2005 |
wpaul |
Small cleanup of the WPA code additions. The SIOCG80211 and SIOCS80211 ioctls are now handled explicitly, but we can't really do anything with them unless the NIC is up (trying to get/set a parameter when the NDIS driver isn't running always yields an error). If something invokes either of these ioctls and the NIC isn't initialized, punt to the default ieee80211_ioctl() routine.
|
145283 |
19-Apr-2005 |
wpaul |
Add preliminary support for WPA-PSK using wpa_supplicant and the net80211 code, graciously contributed by Arvind Srinivasan.
Submitted by: Arvind Srinivasan arvind at celar daht us
|
144888 |
11-Apr-2005 |
wpaul |
Create new i386 windows/bsd thunking layer, similar to the amd64 thunking layer, but with a twist.
The twist has to do with the fact that Microsoft supports structured exception handling in kernel mode. On the i386 arch, exception handling is implemented by hanging an exception registration list off the Thread Environment Block (TEB), and the TEB is accessed via the %fs register. The problem is, we use %fs as a pointer to the pcpu stucture, which means any driver that tries to write through %fs:0 will overwrite the curthread pointer and make a serious mess of things.
To get around this, Project Evil now creates a special entry in the GDT on each processor. When we call into Windows code, a context switch routine will fix up %fs so it points to our new descriptor, which in turn points to a fake TEB. When the Windows code returns, or calls out to an external routine, we swap %fs back again. Currently, Project Evil makes use of GDT slot 7, which is all 0s by default. I fully expect someone to jump up and say I can't do that, but I couldn't find any code that makes use of this entry anywhere. Sadly, this was the only method I could come up with that worked on both UP and SMP. (Modifying the LDT works on UP, but becomes incredibly complicated on SMP.) If necessary, the context switching stuff can be yanked out while preserving the convention calling wrappers.
(Fortunately, it looks like Microsoft uses some special epilog/prolog code on amd64 to implement exception handling, so the same nastiness won't be necessary on that arch.)
The advantages are:
- Any driver that uses %fs as though it were a TEB pointer won't clobber pcpu. - All the __stdcall/__fastcall/__regparm stuff that's specific to gcc goes away.
Also, while I'm here, switch NdisGetSystemUpTime() back to using nanouptime() again. It turns out nanouptime() is way more accurate than just using ticks(). On slower machines, the Atheros drivers I tested seem to take a long time to associate due to the loss in accuracy.
|
144255 |
28-Mar-2005 |
wpaul |
Remove the last vestiges of the "wait for link down event" hack.
|
144176 |
27-Mar-2005 |
wpaul |
Argh. PCI resource list became an STAILQ instead of an SLIST. Try to deal with this while maintaining backards source compatibility with stable.
|
144174 |
27-Mar-2005 |
wpaul |
Finally bring an end to the great "make the Atheros NDIS driver work on SMP" saga. After several weeks and much gnashing of teeth, I have finally tracked down all the problems, despite their best efforts to confound and annoy me.
Problem nunmber one: the Atheros windows driver is _NOT_ a de-serialized miniport! It used to be that NDIS drivers relied on the NDIS library itself for all their locking and serialization needs. Transmit packet queues were all handled internally by NDIS, and all calls to MiniportXXX() routines were guaranteed to be appropriately serialized. This proved to be a performance problem however, and Microsoft introduced de-serialized miniports with the NDIS 5.x spec. Microsoft still supports serialized miniports, but recommends that all new drivers written for Windows XP and later be deserialized. Apparently Atheros wasn't listening when they said this.
This means (among other things) that we have to serialize calls to MiniportSendPackets(). We also have to serialize calls to MiniportTimer() that are triggered via the NdisMInitializeTimer() routine. It finally dawned on me why NdisMInitializeTimer() takes a special NDIS_MINIPORT_TIMER structure and a pointer to the miniport block: the timer callback must be serialized, and it's only by saving the miniport block handle that we can get access to the serialization lock during the timer callback.
Problem number two: haunted hardware. The thing that was _really_ driving me absolutely bonkers for the longest time is that, for some reason I couldn't understand, my test machine would occasionally freeze or more frustratingly, reset completely. That's reset and in *pow!* back to the BIOS startup. No panic, no crashdump, just a reset. This appeared to happen most often when MiniportReset() was called. (As to why MiniportReset() was being called, see problem three below.) I thought maybe I had created some sort of horrible deadlock condition in the process of adding the serialization, but after three weeks, at least 6 different locking implementations and heroic efforts to debug the spinlock code, the machine still kept resetting. Finally, I started single stepping through the MiniportReset() routine in the driver using the kernel debugger, and this ultimately led me to the source of the problem.
One of the last things the Atheros MiniportReset() routine does is call NdisReadPciSlotInformation() several times to inspect a portion of the device's PCI config space. It reads the same chunk of config space repeatedly, in rapid succession. Presumeably, it's polling the hardware for some sort of event. The reset occurs partway through this process. I discovered that when I single-stepped through this portion of the routine, the reset didn't occur. So I inserted a 1 microsecond delay into the read loop in NdisReadPciSlotInformation(). Suddenly, the reset was gone!!
I'm still very puzzled by the whole thing. What I suspect is happening is that reading the PCI config space so quickly is causing a severe PCI bus error. My test system is a Sun w2100z dual Opteron system, and the NIC is a miniPCI card mounted in a miniPCI-to-PCI carrier card, plugged into a 100Mhz PCI slot. It's possible that this combination of hardware causes a bus protocol violation in this scenario which leads to a fatal machine check. This is pure speculation though. Really all I know for sure is that inserting the delay makes the problem go away. (To quote Homer Simpson: "I don't know how it works, but fire makes it good!")
Problem number three: NdisAllocatePacket() needs to make sure to initialize the npp_validcounts field in the 'private' section of the NDIS_PACKET structure. The reason if_ndis was calling the MiniportReset() routine in the first place is that packet transmits were sometimes hanging. When sending a packet, an NDIS driver will call NdisQueryPacket() to learn how many physical buffers the packet resides in. NdisQueryPacket() is actually a macro, which traverses the NDIS_BUFFER list attached to the NDIS_PACKET and stashes some of the results in the 'private' section of the NDIS_PACKET. It also sets the npp_validcounts field to TRUE To indicate that the results are now valid. The problem is, now that if_ndis creates a pool of transmit packets via NdisAllocatePacketPool(), it's important that each time a new packet is allocated via NdisAllocatePacket() that validcounts be initialized to FALSE. If it isn't, and a previously transmitted NDIS_PACKET is pulled out of the pool, it may contain stale data from a previous transmission which won't get updated by NdisQueryPacket(). This would cause the driver to miscompute the number of fragments for a given packet, and botch the transmission.
Fixing these three problems seems to make the Atheros driver happy on SMP, which hopefully means other serialized miniports will be happy too.
And there was much rejoicing.
Other stuff fixed along the way:
- Modified ndis_thsuspend() to take a mutex as an argument. This allows KeWaitForSingleObject() and KeWaitForMultipleObjects() to avoid any possible race conditions with other routines that use the dispatcher lock.
- Fixed KeCancelTimer() so that it returns the correct value for 'pending' according to the Microsoft documentation
- Modfied NdisGetSystemUpTime() to use ticks and hz rather than calling nanouptime(). Also added comment that this routine wraps after 49.7 days.
- Added macros for KeAcquireSpinLock()/KeReleaseSpinLock() to hide all the MSCALL() goop.
- For x86, KeAcquireSpinLockRaiseToDpc() needs to be a separate function. This is because it's supposed to be _stdcall on the x86 arch, whereas KeAcquireSpinLock() is supposed to be _fastcall. On amd64, all routines use the same calling convention so we can just map KeAcquireSpinLockRaiseToDpc() directly to KfAcquireSpinLock() and it will work. (The _fastcall attribute is a no-op on amd64.)
- Implement and use IoInitializeDpcRequest() and IoRequestDpc() (they're just macros) and use them for interrupt handling. This allows us to move the ndis_intrtask() routine from if_ndis.c to kern_ndis.c.
- Fix the MmInitializeMdl() macro so that is uses sizeof(vm_offset_t) when computing mdl_size instead of uint32_t, so that it matches the MmSizeOfMdl() routine.
- Change a could of M_WAITOKs to M_NOWAITs in the unicode routines in subr_ndis.c.
- Use the dispatcher lock a little more consistently in subr_ntoskrnl.c.
- Get rid of the "wait for link event" hack in ndis_init(). Now that I fixed NdisReadPciSlotInformation(), it seems I don't need it anymore. This should fix the witness panic a couple of people have reported.
- Use MSCALL1() when calling the MiniportHangCheck() function in ndis_ticktask(). I accidentally missed this one when adding the wrapping for amd64.
|
143848 |
19-Mar-2005 |
maxim |
s/SLIST/STAILQ/
Spotted by: clive
|
143204 |
07-Mar-2005 |
wpaul |
When you call MiniportInitialize() for an 802.11 driver, it will at some point result in a status event being triggered (it should be a link down event: the Microsoft driver design guide says you should generate one when the NIC is initialized). Some drivers generate the event during MiniportInitialize(), such that by the time MiniportInitialize() completes, the NIC is ready to go. But some drivers, in particular the ones for Atheros wireless NICs, don't generate the event until after a device interrupt occurs at some point after MiniportInitialize() has completed.
The gotcha is that you have to wait until the link status event occurs one way or the other before you try to fiddle with any settings (ssid, channel, etc...). For the drivers that set the event sycnhronously this isn't a problem, but for the others we have to pause after calling ndis_init_nic() and wait for the event to arrive before continuing. Failing to wait can cause big trouble: on my SMP system, calling ndis_setstate_80211() after ndis_init_nic() completes, but _before_ the link event arrives, will lock up or reset the system.
What we do now is check to see if a link event arrived while ndis_init_nic() was running, and if it didn't we msleep() until it does.
Along the way, I discovered a few other problems:
- Defered procedure calls run at PASSIVE_LEVEL, not DISPATCH_LEVEL. ntoskrnl_run_dpc() has been fixed accordingly. (I read the documentation wrong.)
- Similarly, the NDIS interrupt handler, which is essentially a DPC, also doesn't need to run at DISPATCH_LEVEL. ndis_intrtask() has been fixed accordingly.
- MiniportQueryInformation() and MiniportSetInformation() run at DISPATCH_LEVEL, and each request must complete before another can be submitted. ndis_get_info() and ndis_set_info() have been fixed accordingly.
- Turned the sleep lock that guards the NDIS thread job list into a spin lock. We never do anything with this lock held except manage the job list (no other locks are held), so it's safe to do this, and it's possible that ndis_sched() and ndis_unsched() can be called from DISPATCH_LEVEL, so using a sleep lock here is semantically incorrect. Also updated subr_witness.c to add the lock to the order list.
|
142804 |
28-Feb-2005 |
wpaul |
Use 0 instead if NULL for vm_offset_t argument to windrv_lookup() to silence compiler warnings.
|
142415 |
25-Feb-2005 |
wpaul |
Correct e-mail address in copyright.
|
142408 |
24-Feb-2005 |
wpaul |
Apparently, the probe routine in if_ndis_usb.c can be called twice for a given device in some circumstances, so move the PDO creation to the attach routine so we don't end up creating two PDOs.
Also, when we skip the call to ndis_convert_res() in if_ndis.c:ndis_attach(), initialize sc->ndis_block->nmb_rlist to NULL. We don't explicitly zero the miniport block, so this will make sure ndis_unload_driver() does the right thing.
|
142399 |
24-Feb-2005 |
wpaul |
- Correct one aspect of the driver_object/device_object/IRP framework: when we create a PDO, the driver_object associated with it is that of the parent driver, not the driver we're trying to attach. For example, if we attach a PCI device, the PDO we pass to the NdisAddDevice() function should contain a pointer to fake_pci_driver, not to the NDIS driver itself. For PCI or PCMCIA devices this doesn't matter because the child never needs to talk to the parent bus driver, but for USB, the child needs to be able to send IRPs to the parent USB bus driver, and for that to work the parent USB bus driver has to be hung off the PDO.
This involves modifying windrv_lookup() so that we can search for bus drivers by name, if necessary. Our fake bus drivers attach themselves as "PCI Bus," "PCCARD Bus" and "USB Bus," so we can search for them using those names.
The individual attachment stubs now create and attach PDOs to the parent bus drivers instead of hanging them off the NDIS driver's object, and in if_ndis.c, we now search for the correct driver object depending on the bus type, and use that to find the correct PDO.
With this fix, I can get my sample USB ethernet driver to deliver an IRP to my fake parent USB bus driver's dispatch routines.
- Add stub modules for USB support: subr_usbd.c, usbd_var.h and if_ndis_usb.c. The subr_usbd.c module is hooked up the build but currently doesn't do very much. It provides the stub USB parent driver object and a dispatch routine for IRM_MJ_INTERNAL_DEVICE_CONTROL. The only exported function at the moment is USBD_GetUSBDIVersion(). The if_ndis_usb.c stub compiles, but is not hooked up to the build yet. I'm putting these here so I can keep them under source code control as I flesh them out.
|
141963 |
16-Feb-2005 |
wpaul |
Add support for Windows/x86-64 binaries to Project Evil. Ville-Pertti Keinonen (will at exomi dot comohmygodnospampleasekthx) deserves a big thanks for submitting initial patches to make it work. I have mangled his contributions appropriately.
The main gotcha with Windows/x86-64 is that Microsoft uses a different calling convention than everyone else. The standard ABI requires using 6 registers for argument passing, with other arguments on the stack. Microsoft uses only 4 registers, and requires the caller to leave room on the stack for the register arguments incase the callee needs to spill them. Unlike x86, where Microsoft uses a mix of _cdecl, _stdcall and _fastcall, all routines on Windows/x86-64 uses the same convention. This unfortunately means that all the functions we export to the driver require an intermediate translation wrapper. Similarly, we have to wrap all calls back into the driver binary itself.
The original patches provided macros to wrap every single routine at compile time, providing a secondary jump table with a customized wrapper for each exported routine. I decided to use a different approach: the call wrapper for each function is created from a template at runtime, and the routine to jump to is patched into the wrapper as it is created. The subr_pe module has been modified to patch in the wrapped function instead of the original. (On x86, the wrapping routine is a no-op.)
There are some minor API differences that had to be accounted for:
- KeAcquireSpinLock() is a real function on amd64, not a macro wrapper around KfAcquireSpinLock() - NdisFreeBuffer() is actually IoFreeMdl(). I had to change the whole NDIS_BUFFER API a bit to accomodate this.
Bugs fixed along the way: - IoAllocateMdl() always returned NULL - kern_windrv.c:windrv_unload() wasn't releasing private driver object extensions correctly (found thanks to memguard)
This has only been tested with the driver for the Broadcom 802.11g chipset, which was the only Windows/x86-64 driver I could find.
|
141677 |
11-Feb-2005 |
wpaul |
Merge in patch to support AP scanning via ifconfig and the new net80211 API.
Submitted by: Stephane E. Potvin sepotvin at videotron dot ca
|
141524 |
08-Feb-2005 |
wpaul |
Next step on the road to IRPs: create and use an imitation of the Windows DRIVER_OBJECT and DEVICE_OBJECT mechanism so that we can simulate driver stacking.
In Windows, each loaded driver image is attached to a DRIVER_OBJECT structure. Windows uses the registry to match up a given vendor/device ID combination with a corresponding DRIVER_OBJECT. When a driver image is first loaded, its DriverEntry() routine is invoked, which sets up the AddDevice() function pointer in the DRIVER_OBJECT and creates a dispatch table (based on IRP major codes). When a Windows bus driver detects a new device, it creates a Physical Device Object (PDO) for it. This is a DEVICE_OBJECT structure, with semantics analagous to that of a device_t in FreeBSD. The Windows PNP manager will invoke the driver's AddDevice() function and pass it pointers to the DRIVER_OBJECT and the PDO.
The AddDevice() function then creates a new DRIVER_OBJECT structure of its own. This is known as the Functional Device Object (FDO) and corresponds roughly to a private softc instance. The driver uses IoAttachDeviceToDeviceStack() to add this device object to the driver stack for this PDO. Subsequent drivers (called filter drivers in Windows-speak) can be loaded which add themselves to the stack. When someone issues an IRP to a device, it travel along the stack passing through several possible filter drivers until it reaches the functional driver (which actually knows how to talk to the hardware) at which point it will be completed. This is how Windows achieves driver layering.
Project Evil now simulates most of this. if_ndis now has a modevent handler which will use MOD_LOAD and MOD_UNLOAD events to drive the creation and destruction of DRIVER_OBJECTs. (The load event also does the relocation/dynalinking of the image.) We don't have a registry, so the DRIVER_OBJECTS are stored in a linked list for now. Eventually, the list entry will contain the vendor/device ID list extracted from the .INF file. When ndis_probe() is called and detectes a supported device, it will create a PDO for the device instance and attach it to the DRIVER_OBJECT just as in Windows. ndis_attach() will then call our NdisAddDevice() handler to create the FDO. The NDIS miniport block is now a device extension hung off the FDO, just as it is in Windows. The miniport characteristics table is now an extension hung off the DRIVER_OBJECT as well (the characteristics are the same for all devices handled by a given driver, so they don't need to be per-instance.) We also do an IoAttachDeviceToDeviceStack() to put the FDO on the stack for the PDO. There are a couple of fake bus drivers created for the PCI and pccard buses. Eventually, there will be one for USB, which will actually accept USB IRP.s
Things should still work just as before, only now we do things in the proper order and maintain the correct framework to support passing IRPs between drivers.
Various changes:
- corrected the comments about IRQL handling in subr_hal.c to more accurately reflect reality - update ndiscvt to make the drv_data symbol in ndis_driver_data.h a global so that if_ndis_pci.o and/or if_ndis_pccard.o can see it. - Obtain the softc pointer from the miniport block by referencing the PDO rather than a private pointer of our own (nmb_ifp is no longer used) - implement IoAttachDeviceToDeviceStack(), IoDetachDevice(), IoGetAttachedDevice(), IoAllocateDriverObjectExtension(), IoGetDriverObjectExtension(), IoCreateDevice(), IoDeleteDevice(), IoAllocateIrp(), IoReuseIrp(), IoMakeAssociatedIrp(), IoFreeIrp(), IoInitializeIrp() - fix a few mistakes in the driver_object and device_object definitions - add a new module, kern_windrv.c, to handle the driver registration and relocation/dynalinkign duties (which don't really belong in kern_ndis.c). - made ndis_block and ndis_chars in the ndis_softc stucture pointers and modified all references to it - fixed NdisMRegisterMiniport() and NdisInitializeWrapper() so they work correctly with the new driver_object mechanism - changed ndis_attach() to call NdisAddDevice() instead of ndis_load_driver() (which is now deprecated) - used ExAllocatePoolWithTag()/ExFreePool() in lookaside list routines instead of kludged up alloc/free routines - added kern_windrv.c to sys/modules/ndis/Makefile and files.i386.
|
140751 |
24-Jan-2005 |
wpaul |
Begin the first phase of trying to add IRP support (and ultimately USB device support):
- Convert all of my locally chosen function names to their actual Windows equivalents, where applicable. This is a big no-op change since it doesn't affect functionality, but it helps avoid a bit of confusion (it's now a lot easier to see which functions are emulated Windows API routines and which are just locally defined).
- Turn ndis_buffer into an mdl, like it should have been. The structure is the same, but now it belongs to the subr_ntoskrnl module.
- Implement a bunch of MDL handling macros from Windows and use them where applicable.
- Correct the implementation of IoFreeMdl().
- Properly implement IoAllocateMdl() and MmBuildMdlForNonPagedPool().
- Add the definitions for struct irp and struct driver_object.
- Add IMPORT_FUNC() and IMPORT_FUNC_MAP() macros to make formatting the module function tables a little cleaner. (Should also help with AMD64 support later on.)
- Fix if_ndis.c to use KeRaiseIrql() and KeLowerIrql() instead of the previous calls to hal_raise_irql() and hal_lower_irql() which have been renamed.
The function renaming generated a lot of churn here, but there should be very little operational effect.
|
139749 |
06-Jan-2005 |
imp |
Start each of the license/copyright comments with /*-, minor shuffle of lines
|
138728 |
12-Dec-2004 |
sam |
record the bssid for an association
Tested by: Daniel O'Connor
|
138641 |
10-Dec-2004 |
sam |
Fix compilation and correct mapping from struct ifnet to struct ieee80211com after net80211 import.
Submitted by: Tor Egge
|
138572 |
08-Dec-2004 |
sam |
Update for net80211 changes.
|
136677 |
18-Oct-2004 |
le |
Drop the NDIS lock before returning from ndis_start().
PR: i386/72795 Submitted by: Frank Mayhar <frank@exit.com> MFC in: 3 days
|
136269 |
08-Oct-2004 |
mlaier |
Fix sis, bfe and ndis in the same way dc was fixed: Do not tell the hardware to send when there were no packets enqueued.
Found and reviewed by: green MFC after: 1 days
|
133876 |
16-Aug-2004 |
wpaul |
Make the Texas Instruments 802.11g chipset work with the NDISulator. This was tested with a Netgear WG311v2 802.11b/g PCI card. Things that were fixed:
- This chip has two memory mapped regions, one at PCIR_BAR(0) and the other at PCIR_BAR(1). This is a little different from the other chips I've seen with two PCI shared memory regions, since they tend to have the second BAR ad PCIR_BAR(2). if_ndis_pci.c tests explicitly for PCIR_BAR(2). This has been changed to simply fill in ndis_res_mem first and ndis_res_altmem second, if a second shared memory range exists. Given that NDIS drivers seem to scan for BARs in ascending order, I think this should be ok.
- Fixed the code that tries to process firmware images that have been loaded as .ko files. To save a step, I was setting up the address mapping in ndis_open_file(), but ndis_map_file() flags pre-existing mappings as an error (to avoid duplicate mappings). Changed this so that the mapping is now donw in ndis_map_file() as expected.
- Made the typedef for 'driver_entry' explicitly include __stdcall to silence gcc warning in ndis_load_driver().
NOTE: the Texas Instruments ACX111 driver needs firmware. With my card, there were 3 .bin files shipped with the driver. You must either put these files in /compat/ndis or convert them with ndiscvt -f and kldload them so the driver can use them. Without the firmware image, the NIC won't work.
|
133080 |
03-Aug-2004 |
wpaul |
Minor cleanups:
- Fix typo in comment - Remember to free() sc->ndis_txarray on detach - Remember to do an ifmedia_removeall() for ethernet devices
|
132986 |
01-Aug-2004 |
mlaier |
Second part of ALTQ driver modifications, covering: an(4), ath(4), hme(4), ndis(4), vr(4) and wi(4)
Please help testing: http://people.freebsd.org/~mlaier/ALTQ_driver/
Tested by: Vaidas Damosevicius (an, ath, wi) Roman Divacky (vr) Submitted by: yongari (hme)
|
132983 |
01-Aug-2004 |
wpaul |
The watchdog callout executes with the (non-sleepable) ifnet lock held now, but it's possible for ndis_reset_nic() to sleep (sometimes the MiniportReset() method returns NDIS_STATUS_PENDING and we have to wait for completion). To get around this, execute the ndis_reset_nic() routine in the NDIS_TASKQUEUE thread.
|
132953 |
01-Aug-2004 |
wpaul |
Add some minor changes related to PCMCIA attribute memory mapping (which I apparently forgot to commit earlier).
Acquire NDIS_LOCK() in ndis_linksts_done().
|
131953 |
11-Jul-2004 |
wpaul |
Make NdisReadPcmciaAttributeMemory() and NdisWritePcmciaAttributeMemory() actually work.
Make the PCI and PCCARD attachments provide a bus_get_resource_list() method so that resource listing for PCCARD works. PCCARD does not have a bus_get_resource_list() method (yet), so I faked up the resource list management in if_ndis_pccard.c, and added bus_get_resource_list() methods to both if_ndis_pccard.c and if_ndis_pci.c. The one in the PCI attechment just hands off to the PCI bus code. The difference is transparent to the NDIS resource handler code.
Fixed ndis_open_file() so that opening files which live on NFS filesystems work: pass an actual ucred structure to VOP_GETATTR() (NFS explodes if the ucred structure is NOCRED).
Make NdisMMapIoSpace() handle mapping of PCMCIA attribute memory resources correctly.
Turn subr_ndis.c:my_strcasecmp() into ndis_strcasecmp() and export it so that if_ndis_pccard.c can use it, and junk the other copy of my_strcasecmp() from if_ndis_pccard.c.
|
131750 |
07-Jul-2004 |
wpaul |
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.
|
130097 |
04-Jun-2004 |
des |
Take advantage of the dev sysctl tree.
Approved by: wpaul
|
130051 |
04-Jun-2004 |
wpaul |
Unbreak the Intel 2100 Centrino wireless driver (and probably others):
- In subr_ndis.c, my_strcasecmp() actually behaved like my_strncasecmp(): we really need it to behave like the former, not the latter. (It was falsely matching "RadioEnable", which defaults to 1 with "RadioEnableHW" which the driver creates itself and to 0, because we were using strlen("RadioEnable") as the length to test. This caused the radio to always be turned off. :( )
- In if_ndis.c, only set IEEE80211_CHAN_A for channels if we actually set any IEEE80211_MODE_11A rates. (ieee80211_attach() will "helpfully" add IEEE80211_MODE_11A to ic_modecaps for you if you initialize any 802.11a channels. This caused "ndis0: 11a rates:" to erroneously be displayed during driver load.)
- Also in if_ndis.c, when using TESTSETRATE() to add in any missing 802.11b rates, remember to OR the rates with IEEE80211_RATE_BASIC, otherwise comparing against existing basic rates won't match. (1, 2, 5.5 and 11Mbps are basic rates, according to the 802.11b spec.) This erroneously cause 11Mbps to be added to the 11b rate list twice.
|
129972 |
01-Jun-2004 |
wpaul |
Explicitly #include <sys/module.h> in these files too (they use MODULE_DEPEND()).
|
129834 |
29-May-2004 |
wpaul |
In subr_ndis.c, when searching for keys in our make-pretend registry, make the key name matching case-insensitive. There are some drivers and .inf files that have mismatched cases, e.g. the driver will look for "AdhocBand" whereas the .inf file specifies a registry key to be created called "AdHocBand." The mismatch is probably a typo that went undetected (so much for QA), but since Windows seems to be case-insensitive, we should be too.
In if_ndis.c, initialize rates and channels correctly so that specify frequences correctly when trying to set channels in the 5Ghz band, and so that 802.11b rates show up for some a/b/g cards (which otherwise appear to have no 802.11b modes).
Also, when setting OID_802_11_CONFIGURATION in ndis_80211_setstate(), provide default values for the beacon interval, ATIM window and dwelltime. The Atheros "Aries" driver will crash if you try to select ad-hoc mode and leave the beacon interval set to 0: it blindly uses this value and does a division by 0 in the interrupt handler, causing an integer divide trap.
|
129155 |
12-May-2004 |
wpaul |
Restore source code compatibility with 5.2-RELEASE.
|
129002 |
06-May-2004 |
andre |
Link state change notification of ethernet media to the routing socket.
o The ndis_ticktask() function updates the ifi_link_state field and calls rt_ifmsg() to notify listeners on the routing socket.
Approved by: wpaul
|
128780 |
30-Apr-2004 |
wpaul |
Small timer cleanups:
- Use the dh_inserted member of the dispatch header in the Windows timer structure to indicate that the timer has been "inserted into the timer queue" (i.e. armed via timeout()). Use this as the value to return to the caller in KeCancelTimer(). Previously, I was using callout_pending(), but you can't use that with timeout()/untimeout() without creating a potential race condition.
- Make ntoskrnl_init_timer() just a wrapper around ntoskrnl_init_timer_ex() (reduces some code duplication).
- Drop Giant when entering if_ndis.c:ndis_tick() and subr_ntorkrnl.c:ntoskrnl_timercall(). At the moment, I'm forced to use system callwheel via timeout()/untimeout() to handle timers rather than the callout API (struct callout is too big to fit inside the Windows struct KTIMER, so I'm kind of hosed). Unfortunately, all the callouts in the callwhere are not marked as MPSAFE, so when one of them fires, it implicitly acquires Giant before invoking the callback routine (and releases it when it returns). I don't need to hold Giant, but there's no way to stop the callout code from acquiring it as long as I'm using timeout()/untimeout(), so for now we cheat by just dropping Giant right away (and re-acquiring it right before the routine returns so keep the callout code happy). At some point, I will need to solve this better, but for now this should be a suitable workaround.
|
128719 |
28-Apr-2004 |
wpaul |
Remove code that fiddles with Giant in ndis_ticktask() that snuck in during previous commit.
|
128585 |
23-Apr-2004 |
wpaul |
Correct KASSERT()s that check for initialization of mutexes in ndis_detach(), which are different now that I'm not using mutex pools anymore.
Noticed by: des
|
128565 |
22-Apr-2004 |
wpaul |
Set the INTR_MPSAFE flag.
|
128546 |
22-Apr-2004 |
wpaul |
Ok, _really_ fix the Intel 2100B Centrino deadlock problems this time. (I hope.)
My original instinct to make ndis_return_packet() asynchronous was correct. Making ndis_rxeof() submit packets to the stack asynchronously fixes one recursive spinlock acquisition, but it's also possible for it to happen via the ndis_txeof() path too. So:
- In if_ndis.c, revert ndis_rxeof() to its old behavior (and don't bother putting ndis_rxeof_serial() back since we don't need it anymore).
- In kern_ndis.c, make ndis_return_packet() submit the call to the MiniportReturnPacket() function to the "ndis swi" thread so that it always happens in another context no matter who calls it.
|
128510 |
21-Apr-2004 |
wpaul |
Fix the problems people have been having with the Intel 2100B Centrino wireless ever since I added the new spinlock code. Previously, I added a special ndis_rxeof_serial() function to insure that when we receive a packet, we never end up calling the MiniportReturnPacket() routine until after the receive handler has finished. I set things up so that ndis_rxeof_serial() would only be used for serialized miniports since they depend on this property. Well, it turns out deserialized miniports depend on a similar property: you can't let MiniportReturnPacket() be called from the same context as the receive handler at all. The 2100B driver happens to use a single spinlock for all of its synchronization, and it tries to acquire it both while in MiniportHandleInterrupt() and in MiniportReturnPacket(), so if we call MiniportReturnPacket() from the MiniportHandleInterrupt() context, we will end up trying to acquire the spinlock recursively, which you can't do.
To fix this, I made the ndis_rxeof_serial() handler the default. An alternate solution would be to make ndis_return_packet() submit the call to MiniportReturnPacket() to the NDIS task queue thread. I may do that in the future, after I've tested things a bit more.
|
128229 |
14-Apr-2004 |
wpaul |
Continue my efforts to imitate Windows as closely as possible by attempting to duplicate Windows spinlocks. Windows spinlocks differ from FreeBSD spinlocks in the way they block preemption. FreeBSD spinlocks use critical_enter(), which masks off _all_ interrupts. This prevents any other threads from being scheduled, but it also prevents ISRs from running. In Windows, preemption is achieved by raising the processor IRQL to DISPATCH_LEVEL, which prevents other threads from preempting you, but does _not_ prevent device ISRs from running. (This is essentially what Solaris calls dispatcher locks.) The Windows spinlock itself (kspin_lock) is just an integer value which is atomically set when you acquire the lock and atomically cleared when you release it.
FreeBSD doesn't have IRQ levels, so we have to cheat a little by using thread priorities: normal thread priority is PASSIVE_LEVEL, lowest interrupt thread priority is DISPATCH_LEVEL, highest thread priority is DEVICE_LEVEL (PI_REALTIME) and critical_enter() is HIGH_LEVEL. In practice, only PASSIVE_LEVEL and DISPATCH_LEVEL matter to us. The immediate benefit of all this is that I no longer have to rely on a mutex pool.
Now, I'm sure many people will be seized by the urge to criticize me for doing an end run around our own spinlock implementation, but it makes more sense to do it this way. Well, it does to me anyway.
Overview of the changes:
- Properly implement hal_lock(), hal_unlock(), hal_irql(), hal_raise_irql() and hal_lower_irql() so that they more closely resemble their Windows counterparts. The IRQL is determined by thread priority.
- Make ntoskrnl_lock_dpc() and ntoskrnl_unlock_dpc() do what they do in Windows, which is to atomically set/clear the lock value. These routines are designed to be called from DISPATCH_LEVEL, and are actually half of the work involved in acquiring/releasing spinlocks.
- Add FASTCALL1(), FASTCALL2() and FASTCALL3() macros/wrappers that allow us to call a _fastcall function in spite of the fact that our version of gcc doesn't support __attribute__((__fastcall__)) yet. The macros take 1, 2 or 3 arguments, respectively. We need to call hal_lock(), hal_unlock() etc... ourselves, but can't really invoke the function directly. I could have just made the underlying functions native routines and put _fastcall wrappers around them for the benefit of Windows binaries, but that would create needless bloat.
- Remove ndis_mtxpool and all references to it. We don't need it anymore.
- Re-implement the NdisSpinLock routines so that they use hal_lock() and friends like they do in Windows.
- Use the new spinlock methods for handling lookaside lists and linked list updates in place of the mutex locks that were there before.
- Remove mutex locking from ndis_isr() and ndis_intrhand() since they're already called with ndis_intrmtx held in if_ndis.c.
- Put ndis_destroy_lock() code under explicit #ifdef notdef/#endif. It turns out there are some drivers which stupidly free the memory in which their spinlocks reside before calling ndis_destroy_lock() on them (touch-after-free bug). The ADMtek wireless driver is guilty of this faux pas. (Why this doesn't clobber Windows I have no idea.)
- Make NdisDprAcquireSpinLock() and NdisDprReleaseSpinLock() into real functions instead of aliasing them to NdisAcaquireSpinLock() and NdisReleaseSpinLock(). The Dpr routines use KeAcquireSpinLockAtDpcLevel() level and KeReleaseSpinLockFromDpcLevel(), which acquires the lock without twiddling the IRQL.
- In ndis_linksts_done(), do _not_ call ndis_80211_getstate(). Some drivers may call the status/status done callbacks as the result of setting an OID: ndis_80211_getstate() gets OIDs, which means we might cause the driver to recursively access some of its internal structures unexpectedly. The ndis_ticktask() routine will call ndis_80211_getstate() for us eventually anyway.
- Fix the channel setting code a little in ndis_80211_setstate(), and initialize the channel to IEEE80211_CHAN_ANYC. (The Microsoft spec says you're not supposed to twiddle the channel in BSS mode; I may need to enforce this later.) This fixes the problems I was having with the ADMtek adm8211 driver: we were setting the channel to a non-standard default, which would cause it to fail to associate in BSS mode.
- Use hal_raise_irql() to raise our IRQL to DISPATCH_LEVEL when calling certain miniport routines, per the Microsoft documentation.
I think that's everything. Hopefully, other than fixing the ADMtek driver, there should be no apparent change in behavior.
|
127887 |
05-Apr-2004 |
wpaul |
- The MiniportReset() function can return NDIS_STATUS_PENDING, in which case we should wait for the resetdone handler to be called before returning.
- When providing resources via ndis_query_resources(), uses the computed rsclen when using bcopy() to copy out the resource data rather than the caller-supplied buffer length.
- Avoid using ndis_reset_nic() in if_ndis.c unless we really need to reset the NIC because of a problem.
- Allow interrupts to be fielded during ndis_attach(), at least as far as allowing ndis_isr() and ndis_intrhand() to run.
- Use ndis_80211_rates_ex when probing for supported rates. Technically, this isn't supposed to work since, although Microsoft added the extended rate structure with the NDIS 5.1 update, the spec still says that the OID_802_11_SUPPORTED_RATES OID uses ndis_80211_rates. In spite of this, it appears some drivers use it anyway.
- When adding in our guessed rates, check to see if they already exist so that we avoid any duplicates.
- Add a printf() to ndis_open_file() that alerts the user when a driver attempts to open a file under /compat/ndis.
With these changes, I can get the driver for the SMC 2802W 54g PCI card to load and run. This board uses a Prism54G chip. Note that in order for this driver to work, you must place the supplied smc2802w.arm firmware image under /compat/ndis. (The firmware is not resident on the device.)
Note that this should also allow the 3Com 3CRWE154G72 card to work as well; as far as I can tell, these cards also use a Prism54G chip.
|
127552 |
29-Mar-2004 |
wpaul |
Add missing cprd_flags member to partial resource structure in resource_var.h.
In kern_ndis.c:ndis_convert_res(), fill in the cprd_flags and cprd_sharedisp fields as best we can.
In if_ndis.c:ndis_setmulti(), don't bother updating the multicast filter if our multicast address list is empty.
Add some missing updates to ndis_var.h and ntoskrnl_var.h that I forgot to check in when I added the KeDpc stuff.
|
127349 |
24-Mar-2004 |
wpaul |
The ndis_wlan_bssid_ex structure we retrieve in ndis_get_assoc() is variable length, so we should not be trying to copy it into a fixed length buffer, especially one on the stack. malloc() a buffer of the right size and return a pointer to that instead.
Fixes a crash I discovered when testing whe a Cisco AP in infrastructure mode, which returns several information elements that make the ndis_wlan_bssid_ex structure larger than expected.
|
127336 |
23-Mar-2004 |
wpaul |
Recently I realized that the ADMtek 8211 driver wasn't working correctly (NIC would claim to establish a link with an ad-hoc net but it couldn't send/receive packets). It turns out that every time the checkforhang handler was called by ndis_ticktask(), the driver would generate a new media connect event. The NDIS spec says the checkforhang handler is called "approximately every 2 seconds" but using exactly 2 seconds seems too fast. Using 3 seconds makes it happy again, so we'll go with that for now.
|
127281 |
21-Mar-2004 |
wpaul |
Make if_ndis_pci.c and if_ndis_pccard.c use bus_alloc_resource() again instead of bus_alloc_resource_any() to restore source compatibility with 5.2-REL and 5.2.1-REL systems. bus_alloc_resource_any() doesn't really do anything besides hide some of bus_alloc_resource()'s arguments from us, and in my opinion this isn't worth breaking backwards compatibility for people who want to use the NDISulator code on 5.2.x.
|
127249 |
21-Mar-2004 |
wpaul |
Fix another Intel 2200BG bug: don't schedule ndis_ticktask() on media disconnect events if the link wasn't even up yet.
|
127248 |
20-Mar-2004 |
wpaul |
- Rewrite the timer and event API routines in subr_ndis.c so that they are actually layered on top of the KeTimer API in subr_ntoskrnl.c, just as it is in Windows. This reduces code duplication and more closely imitates the way things are done in Windows.
- Modify ndis_encode_parm() to deal with the case where we have a registry key expressed as a hex value ("0x1") which is being read via NdisReadConfiguration() as an int. Previously, we tried to decode things like "0x1" with strtol() using a base of 10, which would always yield 0. This is what was causing problems with the Intel 2200BG Centrino 802.11g driver: the .inf file that comes with it has a key called RadioEnable with a value of 0x1. We incorrectly decoded this value to '0' when it was queried, hence the driver thought we wanted the radio turned off.
- In if_ndis.c, most drivers don't accept NDIS_80211_AUTHMODE_AUTO, but NDIS_80211_AUTHMODE_SHARED may not be right in some cases, so for now always use NDIS_80211_AUTHMODE_OPEN.
NOTE: There is still one problem with the Intel 2200BG driver: it happens that the kernel stack in Windows is larger than the kernel stack in FreeBSD. The 2200BG driver sometimes eats up more than 2 pages of stack space, which can lead to a double fault panic. For the moment, I got things to work by adding the following to my kernel config file:
options KSTACK_PAGES=8
I'm pretty sure 8 is too big; I just picked this value out of a hat as a test, and it happened to work, so I left it. 4 pages might be enough. Unfortunately, I don't think you can dynamically give a thread a larger stack, so I'm not sure how to handle this short of putting a note in the man page about it and dealing with the flood of mail from people who never read man pages.
|
127237 |
20-Mar-2004 |
mdodd |
Don't announce MAC addresses twice. (ieee80211_ifattach() calls ether_ifattach().)
|
127135 |
17-Mar-2004 |
njl |
Convert callers to the new bus_alloc_resource_any(9) API.
Submitted by: Mark Santcroos <marks@ripe.net> Reviewed by: imp, dfr, bde
|
126880 |
12-Mar-2004 |
mux |
Don't set ifp->if_output to ether_output(), since ether_ifattach() will do it for us (we either call ether_ifattach() directly, or it gets called within ieee80211_ifattach()).
Approved by: wpaul
|
126833 |
11-Mar-2004 |
wpaul |
Fix the problem with the Cisco Aironet 340 PCMCIA card. Most newer drivers for Windows are deserialized miniports. Such drivers maintain their own queues and do their own locking. This particular driver is not deserialized though, and we need special support to handle it correctly.
Typically, in the ndis_rxeof() handler, we pass all incoming packets directly to (*ifp->if_input)(). This in turn may cause another thread to run and preempt us, and the packet may actually be processed and then released before we even exit the ndis_rxeof() routine. The problem with this is that releasing a packet calls the ndis_return_packet() function, which hands the packet and its buffers back to the driver. Calling ndis_return_packet() before ndis_rxeof() returns will screw up the driver's internal queues since, not being deserialized, it does no locking.
To avoid this problem, if we detect a serialized driver (by checking the attribute flags passed to NdisSetAttributesEx(), we use an alternate ndis_rxeof() handler, ndis_rxeof_serial(), which puts the call to (*ifp->if_input)() on the NDIS SWI work queue. This guarantees the packet won't be processed until after ndis_rxeof_serial() returns.
Note that another approach is to always copy the packet data into another mbuf and just let the driver retain ownership of the ndis_packet structure (ndis_return_packet() never needs to be called in this case). I'm not sure which method is faster.
|
126784 |
09-Mar-2004 |
wpaul |
Trim unneeded includes from if_ndis_pccard.c and if_ndis_pci.c. Also removed unused variables from if_ndis_pccard.c
|
126780 |
09-Mar-2004 |
wpaul |
If the resource listing obtained from BUS_GET_RESOURCE_LIST() in ndis_probe_pci() doesn't contain an entry for an IRQ resource, try to force one to be routed to us anyway by adding an extra call to bus_alloc_resource(). If this fails, then we have to abort the attach.
Patch provided by jhb, tweaked by me.
|
126706 |
07-Mar-2004 |
wpaul |
Add preliminary support for PCMCIA devices in addition to PCI/cardbus. if_ndis.c has been split into if_ndis_pci.c and if_ndis_pccard.c. The ndiscvt(8) utility should be able to parse device info for PCMCIA devices now. The ndis_alloc_amem() has moved from kern_ndis.c to if_ndis_pccard.c so that kern_ndis.c no longer depends on pccard.
NOTE: this stuff is not guaranteed to work 100% correctly yet. So far I have been able to load/init my PCMCIA Cisco Aironet 340 card, but it crashes in the interrupt handler. The existing support for PCI/cardbus devices should still work as before.
|
125718 |
11-Feb-2004 |
wpaul |
Add yet more bulletproofing. This is to guard against the case that ndis_init_nic() works one during attach, but fails later. Many things will blow up if ndis_init_nic() fails and we aren't careful.
|
125583 |
07-Feb-2004 |
wpaul |
Don't hold NDIS_LOCK() around call to ndis_getstate_80211() since it may block on ndis_get_info().
|
125377 |
03-Feb-2004 |
wpaul |
Implement support for single packet sends. The Intel Centrino driver that Asus provides on its CDs has both a MiniportSend() routine and a MiniportSendPackets() function. The Microsoft NDIS docs say that if a driver has both, only the MiniportSendPackets() routine will be used. Although I think I implemented the support correctly, calling the MiniportSend() routine seems to result in no packets going out on the air, even though no error status is returned. The MiniportSendPackets() function does work though, so at least in this case it doesn't matter.
In if_ndis.c:ndis_getstate_80211(), if ndis_get_assoc() returns an error, don't bother trying to obtain any other state since the calls may fail, or worse cause the underlying driver to crash.
(The above two changes make the Asus-supplied Centrino work.)
Also, when calling the OID_802_11_CONFIGURATION OID, remember to initialize the structure lengths correctly.
In subr_ndis.c:ndis_open_file(), set the current working directory to rootvnode if we're in a thread that doesn't have a current working directory set.
|
125309 |
01-Feb-2004 |
wpaul |
Use the OID_802_11_CONFIGURATION OID when deciding if the underlying driver is for an 802.11 device or not. At least one driver I have does not support the OID_802_11_NETWORK_TYPES_SUPPORTED OID.
Also, for now, don't do anything special in the ndis_suspend() method. I originally wanted to shut down the NIC but leave the IFF_UP flag alone since technically the interface is meant to remain up, but an interrupt may be delivered to the ISR on suspend, and if this happens while the NIC is halted, we will crash, since none of the miniport driver methods will function.
This needs to be dealt with properly later, but for now this prevents a panic, and the resume method properly re-inits the NIC.
|
125188 |
29-Jan-2004 |
wpaul |
Go back to using AUTHMODE_AUTO if WEP is on. In some cases, the Centrino won't associate in BSS mode if you use AUTHMODE_SHARED. I probably don't understand enough to know when SHARED should be used vs. OPEN or WPA. For now, go back to what works.
|
125076 |
27-Jan-2004 |
wpaul |
This should have been checked in as part of the last update to if_ndis.c: add yet another member to the ndis_softc as part of the workaround for the net80211 dain bramage.
|
125068 |
27-Jan-2004 |
wpaul |
Add a kludge to avoid having ndis_init() called needlessly by dhclient on an SIOCSIFADDR (by way of brain damage in net80211).
Also, avoid trying to set NDIS_80211_AUTHMODE_AUTO since the Microsoft documentation I have recommends not using it, and the Centrino driver seems to dislike being told to use it.
|
125061 |
27-Jan-2004 |
wpaul |
Use the M_BZERO flag with malloc() in a couple of places.
|
124940 |
25-Jan-2004 |
wpaul |
Correct KASSERT() in ndis_destroy(): ndis_mtx is a pointer now. Also add KASSERT() for ndis_intrmtx().
|
124899 |
24-Jan-2004 |
wpaul |
Add missing newlines to some device_printf()s.
Don't do anything in ndis_get_assoc() if the link isn't up (avoids spurrious "couldn't get bssid" messages on the console).
|
124822 |
22-Jan-2004 |
wpaul |
Add suspend and resume methods. I'm not certain this work correctly since I can't easily test them on my laptop right now, but they should do the right thing.
|
124821 |
22-Jan-2004 |
wpaul |
Add support for TCP/IP checksum offload.
No, really.
|
124744 |
20-Jan-2004 |
wpaul |
Correct instances of mtx_lock()/mtx_unlock() that should have been mtx_pool_lock()/mtx_pool_unlock().
|
124709 |
19-Jan-2004 |
wpaul |
Properly program the multicast filter in ndis_setmulti(), and fix promisc mode in ndis_ioctl().
|
124697 |
18-Jan-2004 |
wpaul |
Convert from using taskqueue_swi to using private kernel threads. The problem with using taskqueue_swi is that some of the things we defer into threads might block for up to several seconds. This is an unfriendly thing to do to taskqueue_swi, since it is assumed the taskqueue threads will execute fairly quickly once a task is submitted. Reorganized the locking in if_ndis.c in the process.
Cleaned up ndis_write_cfg() and ndis_decode_parm() a little.
|
124576 |
15-Jan-2004 |
wpaul |
The definition for __stdcall logically belongs in pe_var.h, but the definitions for NDIS_BUS_SPACE_IO and NDIS_BUS_SPACE_MEM logically belong in hal_var.h. At least, that's my story, and I'm sticking to it.
Also, remove definition of __stdcall from if_ndis.c now that it's pulled in from pe_var.h.
|
124448 |
12-Jan-2004 |
wpaul |
Ugh. Last commit went horribly wrong. Back out changes to subr_ntoskrnl.c, make sure if_ndis.c really gets checked in this time.
|
124409 |
12-Jan-2004 |
wpaul |
Merge in some changes submitted by Brian Feldman. Among other things, these add support for listing BSSIDs via wicontrol -l. I added code to call OID_802_11_BSSID_LIST_SCAN to allow scanning for any nearby wirelsss nets.
Convert from using individual mutexes to a mutex pool, created in subr_ndis.c. This deals with the problem of drivers creating locks in their DriverEntry() routines which might get trashed later.
Put some messages under IFF_DEBUG.
|
124278 |
09-Jan-2004 |
wpaul |
The private data section of ndis_packets has a 'packet flags' byte which has two important flags in it: the 'allocated by NDIS' flag and the 'media specific info present' flag. There are two Windows macros for getting/setting media specific info fields within the ndis_packet structure which can behave improperly if these flags are not initialized correctly when a packet is allocated. It seems the correct thing to do is always set the NDIS_PACKET_ALLOCATED_BY_NDIS flag on all newly allocated packets.
This fixes the crashes with the Intel Centrino wireless driver. My sample card now seems to work correctly.
Also, fix a potential LOR involving ndis_txeof() in if_ndis.c.
|
124246 |
08-Jan-2004 |
wpaul |
Correct the definition of the ndis_miniport_interrupt structure: the ni_dpccountlock member is an ndis_kspin_lock, not an ndis_spin_lock (the latter is too big).
Run if_ndis.c:ndis_tick() via taskqueue_schedule(). Also run ndis_start() via taskqueue in certain circumstances.
Using these tweaks, I can now get the Broadcom BCM5701 NDIS driver to load and run. Unfortunately, the version I have seems to suffer from the same bug as the SMC 83820 driver, which is that it creates a spinlock during its DriverEntry() routine. I'm still debating the right way to deal with this.
|
124165 |
06-Jan-2004 |
wpaul |
- Add pe_get_message() and pe_get_messagetable() for processing the RT_MESSAGETABLE resources that some driver binaries have. This allows us to print error messages in ndis_syslog().
- Correct the implementation of InterlockedIncrement() and InterlockedDecrement() -- they return uint32_t, not void.
- Correct the declarations of the 64-bit arithmetic shift routines in subr_ntoskrnl.c (_allshr, allshl, etc...). These do not follow the _stdcall convention: instead, they appear to be __attribute__((regparm(3)).
- Change the implementation of KeInitializeSpinLock(). There is no complementary KeFreeSpinLock() function, so creating a new mutex on each call to KeInitializeSpinLock() leaks resources when a driver is unloaded. For now, KeInitializeSpinLock() returns a handle to the ntoskrnl interlock mutex.
- Use a driver's MiniportDisableInterrupt() and MiniportEnableInterrupt() routines if they exist. I'm not sure if I'm doing this right yet, but at the very least this shouldn't break any currently working drivers, and it makes the Intel PRO/1000 driver work.
- In ndis_register_intr(), save some state that might be needed later, and save a pointer to the driver's interrupt structure in the ndis_miniport_block.
- Save a pointer to the driver image for use by ndis_syslog() when it calls pe_get_message().
|
124135 |
04-Jan-2004 |
wpaul |
Modify if_ndis.c so that the MiniportISR function runs in ndis_intr() and MiniportHandleInterrupt() is fired off later via a task queue in ndis_intrtask(). This more accurately follows the NDIS interrupt handling model, where the ISR does a minimal amount of work in interrupt context and the handler is defered and run at a lower priority.
Create a separate ndis_intrmtx mutex just for the guarding the ISR.
Modify NdisSynchronizeWithInterrupt() to aquire the ndis_intrmtx mutex before invoking the synchronized procedure. (The purpose of this function is to provide mutual exclusion for code that shares variables with the ISR.)
Modify NdisMRegisterInterrupt() to save a pointer to the miniport block in the ndis_miniport_interrupt structure so that NdisSynchronizeWithInterrupt() can grab it later and derive ndis_intrmtx from it.
|
124116 |
04-Jan-2004 |
wpaul |
In ndis_attach(), report the NDIS API level that the Windows miniport driver was compiled with.
Remove debug printf from ndis_assicn_pcirsc(). It doesn't serve much purpose.
Implement NdisMIndicateStatus() and NdisMIndicateStatusComplete() as functions in subr_ndis.c. In NDIS 4.0, they were functions. In NDIS 5.0 and later, they're just macros.
Allocate a few extra packets/buffers beyond what the driver asks for since sometimes it seems they can lie about how many they really need, and some extra stupid ones don't check to see if NdisAllocatePacket() and/or NdisAllocateBuffer() actually succeed.
|
124100 |
03-Jan-2004 |
wpaul |
In if_ndis.c:ndis_attach(), temporarily set the IFF_UP flag while calling the haltfunc. If an interrupt is triggered by the init or halt func, the IFF_UP flag must be set in order for us to be able to service it.
In kern_ndis.c: implement a handler for NdisMSendResourcesAvailable() (currently does nothing since we don't really need it).
In subr_ndis.c: - Correct ndis_init_string() and ndis_unicode_to_ansi(), which were both horribly broken. - Implement NdisImmediateReadPciSlotInformation() and NdisImmediateWritePciSlotInformation(). - Implement NdisBufferLength(). - Work around my first confirmed NDIS driver bug. The SMC 9462 gigE driver (natsemi 83820-based copper) incorrectly creates a spinlock in its DriverEntry() routine and then destroys it in its MiniportHalt() handler. This is wrong: spinlocks should be created in MiniportInit(). In a Windows environment, this is often not a problem because DriverEntry()/MiniportInit() are called once when the system boots and MiniportHalt() or the shutdown handler is called when the system halts.
With this stuff in place, this driver now seems to work:
ndis0: <SMC EZ Card 1000> port 0xe000-0xe0ff mem 0xda000000-0xda000fff irq 10 at device 9.0 on pci0 ndis0: assign PCI resources... ndis_open_file("FLASH9.hex", 18446744073709551615) ndis0: Ethernet address: 00:04:e2:0e:d3:f0
|
124060 |
02-Jan-2004 |
wpaul |
Clean up ndiscvt a bit (leaving out the -i flag didn't work) and add copyrights to the inf parser files.
Add a -n flag to ndiscvt to allow the user to override the default device name of NDIS devices. Instead of "ndis0, ndis1, etc..." you can have "foo0, foo1, etc..." This allows you to have more than one kind of NDIS device in the kernel at the same time.
Convert from printf() to device_printf() in if_ndis.c, kern_ndis.c and subr_ndis.c.
Create UMA zones for ndis_packet and ndis_buffer structs allocated on transmit. The zones are created and destroyed in the modevent handler in kern_ndis.c.
printf() and UMA changes submitted by green@freebsd.org
|
124014 |
31-Dec-2003 |
wpaul |
- subr_ntoskrnl.c: improve the _fastcall hack based on suggestions from peter and jhb: use __volatile__ to prevent gcc from possibly reordering code, use a null inline instruction instead of a no-op movl (I would have done this myself if I knew it was allowed) and combine two register assignments into a single asm statement. - if_ndis.c: set the NDIS_STATUS_PENDING flag on all outgoing packets in ndis_start(), make the resource allocation code a little smarter about how it selects the altmem range, correct a lock order reversal in ndis_tick().
|
124005 |
30-Dec-2003 |
wpaul |
- Add new 802.11 OID information obtained from NDIS 5.1 update to ndis_var.h - In kern_ndis.c:ndis_send_packets(), avoid dereferencing NULL pointers created when the driver's send routine immediately calls the txeof handler (which releases the packets for us anyway). - In if_ndis.c:ndis_80211_setstate(), implement WEP support.
|
123976 |
29-Dec-2003 |
wpaul |
Rework resource allocation. Replace the "feel around like a blind man" method with something a little more intelligent: use BUS_GET_RESOURCE_LIST() to run through all resources allocated to us and map them as needed. This way we know exactly what resources need to be mapped and what their RIDs are without having to guess. This simplifies both ndis_attach() and ndis_convert_res(), and eliminates the unfriendly "ndisX: couldn't map <foo>" messages that are sometimes emitted during driver load.
|
123858 |
26-Dec-2003 |
wpaul |
Attempt to handle the status field in the ndis_packet oob area correctly.
For received packets, an status of NDIS_STATUS_RESOURCES means we need to copy the packet data and return the ndis_packet to the driver immediatel. NDIS_STATUS_SUCCESS means we get to hold onto the packet, but we have to set the status to NDIS_STATUS_PENDING so the driver knows we're going to hang onto it for a while.
For transmit packets, NDIS_STATUS_PENDING means the driver will asynchronously return the packet to us via the ndis_txeof() routine, and NDIS_STATUS_SUCCESS means the driver sent the frame, and NDIS (i.e. the OS) retains ownership of the packet and can free it right away.
|
123848 |
26-Dec-2003 |
wpaul |
Back out the last batch of changes until I have a chance to properly evaluate them. Whatever they're meant to do, they're doing it wrong.
Also:
- Clean up last bits of NULL fallout in subr_pe - Don't let ndis_ifmedia_sts() do anything if the IFF_UP flag isn't set - Implement NdisSystemProcessorCount() and NdisQueryMapRegisterCount().
|
123827 |
25-Dec-2003 |
wpaul |
- In ndis_intr(), don't do any interrupt processing if the IFF_UP flag isn't set. - In ndis_attach(), halt the NIC before exiting the routine. Calling ndis_init() will bring it up again, and we don't want it running (and potentially generating interrupts) until we're ready to deal with it.
|
123826 |
25-Dec-2003 |
wpaul |
Avoid using any of the ndis_packet/ndis_packet_private fields for mbuf<->packet housekeeping. Instead, add a couple of extra fields to the end of ndis_packet. These should be invisible to the Windows driver module.
This also lets me get rid of a little bit of evil from ndis_ptom() (frobbing of the ext_buf field instead of relying on the MEXTADD() macro).
|
123822 |
25-Dec-2003 |
wpaul |
- Add stubs for Ndis*File() functions - Fix ndis_time(). - Implement NdisGetSystemUpTime(). - Implement RtlCopyUnicodeString() and RtlUnicodeStringToAnsiString(). - In ndis_getstate_80211(), use sc->ndis_link to determine connect status.
Submitted by: Brian Feldman <green@freebsd.org>
|
123821 |
24-Dec-2003 |
wpaul |
- Fix some compiler warnings in subr_pe.c - Add explicit cardbus attachment in if_ndis.c - Clean up after moving bus_setup_intr() in ndis_attach(). - When setting an ssid, program an empty ssid as a 1-byte string with a single 0 byte. The Microsoft documentation says this is how you're supposed to tell the NIC to attach to 'any' ssid. - Keep trace of callout handles for timers externally from the ndis_miniport_timer structs, and run through and clobber them all after invoking the haltfunc just in case the driver left one running. (We need to make sure all timers are cancelled on driver unload.) - Handle the 'cancelled' argument in ndis_cancel_timer() correctly.
|
123779 |
23-Dec-2003 |
wpaul |
Set up the interrupt earlier in ndis_attach(), because calling the driver's initfunc may cause an interrupt to be generated. This avoids the occasional 'stray irqXXX' messages on load.
|
123772 |
23-Dec-2003 |
wpaul |
Make the NDIS driver depend on the wlan module now that it has some 802.11 support.
|
123757 |
23-Dec-2003 |
wpaul |
Re-do the handling of ndis_buffers. The NDIS_BUFFER structure is supposed to be opaque to the driver, however it is exposed through several macros which expect certain behavior. In my original implementation, I used the mappedsystemva member of the structure to hold a pointer to the buffer and bytecount to hold the length. It turns out you must use the startva pointer to point to the page containing the start of the buffer and set byteoffset to the offset within the page where the buffer starts. So, for a buffer with address 'baseva,' startva is baseva & ~(PAGE_SIZE -1) and byteoffset is baseva & (PAGE_SIZE -1). We have to maintain this convention everywhere that ndis_buffers are used.
Fortunately, Microsoft defines some macros for initializing and manipulating NDIS_BUFFER structures in ntddk.h. I adapted some of them for use here and used them where appropriate.
This fixes the discrepancy I observed between how RX'ed packet sizes were being reported in the Broadcom wireless driver and the sample ethernet drivers that I've tested. This should also help the Intel Centrino wireless driver work.
Also try to properly initialize the 802.11 BSS and IBSS channels. (Sadly, the channel value is meaningless since there's no way in the existing NDIS API to get/set the channel, but this should take care of any 'invalid channel (NULL)' messages printed on the console.
|
123695 |
21-Dec-2003 |
wpaul |
Big round of updates:
- Make ndis_get_info()/ndis_set_info() sleep on the setdone/getdone routines if they get back NDIS_STATUS_PENDING.
- Add a bunch of net80211 support so that 802.11 cards can be twiddled with ifconfig. This still needs more work and is not guaranteed to work for everyone. It works on my 802.11b/g card anyway.
The problem here is Microsoft doesn't provide a good way to a) learn all the rates that a card supports (if it has more than 8, you're kinda hosed) and b) doesn't provide a good way to distinguish between 802.11b, 802.11b/g an 802.11a/b/g cards, so you sort of have to guess.
Setting the SSID and switching between infrastructure/adhoc modes should work. WEP still needs to be implemented. I can't find any API for getting/setting the channel other than the registry/sysctl keys.
|
123622 |
18-Dec-2003 |
wpaul |
Fix wildcard subsystem case in ndis_probe().
|
123620 |
18-Dec-2003 |
wpaul |
Deal with the duplicate sysctl leaf problem. A .inf file may contain definitions for more than one device (usually differentiated by the PCI subvendor/subdevice ID). Each device also has its own tree of registry keys. In some cases, each device has the same keys, but sometimes each device has a unique tree but with overlap. Originally, I just had ndiscvt(8) dump out all the keys it could find, and we would try to apply them to every device we could find. Now, each key has an index number that matches it to a device in the device ID list. This lets us create just the keys that apply to a particular device.
I also added an extra field to the device list to hold the subvendor and subdevice ID.
Some devices are generic, i.e. there is no subsystem definition. If we have a device that doesn't match a specific subsystem value and we have a generic entry, we use the generic entry.
|
123537 |
14-Dec-2003 |
wpaul |
Silence irritating watchdog timeout messages: if we call ndis_send_packets() but there's no link yet, we get an immediate callback to ndis_txeof(), which clears if_timer. But ndis_start() sets if_timer right after the call to ndis_send_packets(). Set if_timer before calling ndis_send_packets().
Also fix mutex locking to prevent ndis_txeof() from running in the middle of ndis_start().
|
123535 |
14-Dec-2003 |
wpaul |
Rework mbuf<->ndis_packet/ndis_packet<->mbuf translation a little to make it more robust. This should fix problems with crashes under heavy traffic loads that have been reported. Also add a 'query done' callback handler to satisfy the e100bex.sys sample Intel driver.
|
123474 |
11-Dec-2003 |
wpaul |
Commit the first cut of Project Evil, also known as the NDISulator.
Yes, it's what you think it is. Yes, you should run away now.
This is a special compatibility module for allowing Windows NDIS miniport network drivers to be used with FreeBSD/x86. This provides _binary_ NDIS compatibility (not source): you can run NDIS driver code, but you can't build it. There are three main parts:
sys/compat/ndis: the NDIS compat API, which provides binary compatibility functions for many routines in NDIS.SYS, HAL.dll and ntoskrnl.exe in Windows (these are the three modules that most NDIS miniport drivers use). The compat module also contains a small PE relocator/dynalinker which relocates the Windows .SYS image and then patches in our native routines.
sys/dev/if_ndis: the if_ndis driver wrapper. This module makes use of the ndis compat API and can be compiled with a specially prepared binary image file (ndis_driver_data.h) containing the Windows .SYS image and registry key information parsed out of the accompanying .INF file. Once if_ndis.ko is built, it can be loaded and unloaded just like a native FreeBSD kenrel module.
usr.sbin/ndiscvt: a special utility that converts foo.sys and foo.inf into an ndis_driver_data.h file that can be compiled into if_ndis.o. Contains an .inf file parser graciously provided by Matt Dodd (and mercilessly hacked upon by me) that strips out device ID info and registry key info from a .INF file and packages it up with a binary image array. The ndiscvt(8) utility also does some manipulation of the segments within the .sys file to make life easier for the kernel loader. (Doing the manipulation here saves the kernel code from having to move things around later, which would waste memory.)
ndiscvt is only built for the i386 arch. Only files.i386 has been updated, and none of this is turned on in GENERIC. It should probably work on pc98. I have no idea about amd64 or ia64 at this point.
This is still a work in progress. I estimate it's about %85 done, but I want it under CVS control so I can track subsequent changes. It has been tested with exactly three drivers: the LinkSys LNE100TX v4 driver (Lne100v4.sys), the sample Intel 82559 driver from the Windows DDK (e100bex.sys) and the Broadcom BCM43xx wireless driver (bcmwl5.sys). It still needs to have a net80211 stuff added to it. To use it, you would do something like this:
# cd /sys/modules/ndis # make; make load # cd /sys/modules/if_ndis # ndiscvt -i /path/to/foo.inf -s /path/to/foo.sys -o ndis_driver_data.h # make; make load # sysctl -a | grep ndis
All registry keys are mapped to sysctl nodes. Sometimes drivers refer to registry keys that aren't mentioned in foo.inf. If this happens, the NDIS API module creates sysctl nodes for these keys on the fly so you can tweak them.
An example usage of the Broadcom wireless driver would be:
# sysctl hw.ndis0.EnableAutoConnect=1 # sysctl hw.ndis0.SSID="MY_SSID" # sysctl hw.ndis0.NetworkType=0 (0 for bss, 1 for adhoc) # ifconfig ndis0 <my ipaddr> netmask 0xffffff00 up
Things to be done:
- get rid of debug messages - add in ndis80211 support - defer transmissions until after a status update with NDIS_STATUS_CONNECTED occurs - Create smarter lookaside list support - Split off if_ndis_pci.c and if_ndis_pccard.c attachments - Make sure PCMCIA support works - Fix ndiscvt to properly parse PCMCIA device IDs from INF files - write ndisapi.9 man page
|