7e1ac58149
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
153 lines
4.4 KiB
C
153 lines
4.4 KiB
C
/*
|
|
* Copyright (c) 2003
|
|
* Bill Paul <wpaul@windriver.com>. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* 3. All advertising materials mentioning features or use of this software
|
|
* must display the following acknowledgement:
|
|
* This product includes software developed by Bill Paul.
|
|
* 4. Neither the name of the author nor the names of any co-contributors
|
|
* may be used to endorse or promote products derived from this software
|
|
* without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
|
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
|
* THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#include <sys/cdefs.h>
|
|
__FBSDID("$FreeBSD$");
|
|
|
|
#include <sys/param.h>
|
|
#include <sys/types.h>
|
|
#include <sys/errno.h>
|
|
|
|
#include <sys/callout.h>
|
|
#include <sys/kernel.h>
|
|
|
|
#include <sys/systm.h>
|
|
#include <machine/clock.h>
|
|
#include <machine/bus_memio.h>
|
|
#include <machine/bus_pio.h>
|
|
#include <machine/bus.h>
|
|
|
|
#include <sys/bus.h>
|
|
#include <sys/rman.h>
|
|
|
|
#include <compat/ndis/pe_var.h>
|
|
#include <compat/ndis/hal_var.h>
|
|
|
|
#define __stdcall __attribute__((__stdcall__))
|
|
#define FUNC void(*)(void)
|
|
|
|
__stdcall static void hal_stall_exec_cpu(uint32_t);
|
|
__stdcall static void hal_writeport_ulong(uint32_t *, uint32_t);
|
|
__stdcall static void hal_writeport_ushort(uint16_t *, uint16_t);
|
|
__stdcall static void hal_writeport_uchar(uint8_t *, uint8_t);
|
|
__stdcall static uint32_t hal_readport_ulong(uint32_t *);
|
|
__stdcall static uint16_t hal_readport_ushort(uint16_t *);
|
|
__stdcall static uint8_t hal_readport_uchar(uint8_t *);
|
|
__stdcall static void dummy (void);
|
|
|
|
__stdcall static void
|
|
hal_stall_exec_cpu(usecs)
|
|
uint32_t usecs;
|
|
{
|
|
DELAY(usecs);
|
|
return;
|
|
}
|
|
|
|
__stdcall static void
|
|
hal_writeport_ulong(port, val)
|
|
uint32_t *port;
|
|
uint32_t val;
|
|
{
|
|
bus_space_write_4(I386_BUS_SPACE_IO, 0x0, (uint32_t)port, val);
|
|
return;
|
|
}
|
|
|
|
__stdcall static void
|
|
hal_writeport_ushort(port, val)
|
|
uint16_t *port;
|
|
uint16_t val;
|
|
{
|
|
bus_space_write_2(I386_BUS_SPACE_IO, 0x0, (uint32_t)port, val);
|
|
return;
|
|
}
|
|
|
|
__stdcall static void
|
|
hal_writeport_uchar(port, val)
|
|
uint8_t *port;
|
|
uint8_t val;
|
|
{
|
|
bus_space_write_1(I386_BUS_SPACE_IO, 0x0, (uint32_t)port, val);
|
|
return;
|
|
}
|
|
|
|
__stdcall static uint16_t
|
|
hal_readport_ushort(port)
|
|
uint16_t *port;
|
|
{
|
|
return(bus_space_read_2(I386_BUS_SPACE_IO, 0x0, (uint32_t)port));
|
|
}
|
|
|
|
__stdcall static uint32_t
|
|
hal_readport_ulong(port)
|
|
uint32_t *port;
|
|
{
|
|
return(bus_space_read_4(I386_BUS_SPACE_IO, 0x0, (uint32_t)port));
|
|
}
|
|
|
|
__stdcall static uint8_t
|
|
hal_readport_uchar(port)
|
|
uint8_t *port;
|
|
{
|
|
return(bus_space_read_1(I386_BUS_SPACE_IO, 0x0, (uint32_t)port));
|
|
}
|
|
|
|
__stdcall
|
|
static void dummy()
|
|
{
|
|
printf ("hal dummy called...\n");
|
|
return;
|
|
}
|
|
|
|
|
|
image_patch_table hal_functbl[] = {
|
|
{ "KeStallExecutionProcessor", (FUNC)hal_stall_exec_cpu },
|
|
{ "WRITE_PORT_ULONG", (FUNC)hal_writeport_ulong },
|
|
{ "WRITE_PORT_USHORT", (FUNC)hal_writeport_ushort },
|
|
{ "WRITE_PORT_UCHAR", (FUNC)hal_writeport_uchar },
|
|
{ "READ_PORT_ULONG", (FUNC)hal_readport_ulong },
|
|
{ "READ_PORT_USHORT", (FUNC)hal_readport_ushort },
|
|
{ "READ_PORT_UCHAR", (FUNC)hal_readport_uchar },
|
|
|
|
/*
|
|
* This last entry is a catch-all for any function we haven't
|
|
* implemented yet. The PE import list patching routine will
|
|
* use it for any function that doesn't have an explicit match
|
|
* in this table.
|
|
*/
|
|
|
|
{ NULL, (FUNC)dummy },
|
|
|
|
/* End of list. */
|
|
|
|
{ NULL, NULL },
|
|
};
|