vmxnet-only/0000755000000000000000000000000012025727017012057 5ustar rootrootvmxnet-only/autoconf/0000755000000000000000000000000012025727012013670 5ustar rootrootvmxnet-only/autoconf/geninclude.c0000444000000000000000000000226412025727017016160 0ustar rootroot/********************************************************* * Copyright (C) 2003 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #include #ifdef CONFIG_X86_VOYAGER APATH/mach-voyager #endif #ifdef CONFIG_X86_VISWS APATH/mach-visws #endif #ifdef CONFIG_X86_NUMAQ APATH/mach-numaq #endif #ifdef CONFIG_X86_BIGSMP APATH/mach-bigsmp #endif #ifdef CONFIG_X86_SUMMIT APATH/mach-summit #endif #ifdef CONFIG_X86_GENERICARCH APATH/mach-generic #endif APATH/mach-default vmxnet-only/autoconf/skblin.c0000444000000000000000000000257012025727017015325 0ustar rootroot/********************************************************* * Copyright (C) 2006 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * Detect whether skb_linearize takes one or two arguments. */ #include #include #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 17) /* * Since 2.6.18 all kernels have single-argument skb_linearize. For * older kernels use autodetection. Not using autodetection on newer * kernels saves us from compile failure on some post 2.6.18 kernels * which do not have selfcontained skbuff.h. */ #include int test_skb_linearize(struct sk_buff *skb) { return skb_linearize(skb); } #endif vmxnet-only/vm_basic_types.h0000444000000000000000000005624212025727017015246 0ustar rootroot/********************************************************* * Copyright (C) 1998-2008 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * * vm_basic_types.h -- * * basic data types. */ #ifndef _VM_BASIC_TYPES_H_ #define _VM_BASIC_TYPES_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMMEXT #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMMON #define INCLUDE_ALLOW_VMNIXMOD #define INCLUDE_ALLOW_VMKERNEL #define INCLUDE_ALLOW_VMKDRIVERS #define INCLUDE_ALLOW_VMK_MODULE #define INCLUDE_ALLOW_DISTRIBUTE #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_VMIROM #include "includeCheck.h" /* STRICT ANSI means the Xserver build and X defines Bool differently. */ #if !defined(__STRICT_ANSI__) || defined(__FreeBSD__) typedef char Bool; #endif #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE 1 #endif #define IsBool(x) (((x) & ~1) == 0) #define IsBool2(x, y) ((((x) | (y)) & ~1) == 0) /* * Macros __i386__ and __ia64 are intrinsically defined by GCC */ #ifdef __i386__ #define VM_I386 #endif #ifdef _WIN64 #define __x86_64__ #endif #ifdef __x86_64__ #define VM_X86_64 #define VM_I386 #define vm_x86_64 (1) #else #define vm_x86_64 (0) #endif #ifdef _WIN32 /* safe assumption for a while */ #define VM_I386 #endif #ifdef _MSC_VER typedef unsigned __int64 uint64; typedef signed __int64 int64; #pragma warning (3 :4505) // unreferenced local function #pragma warning (disable :4018) // signed/unsigned mismatch #pragma warning (disable :4761) // integral size mismatch in argument; conversion supplied #pragma warning (disable :4305) // truncation from 'const int' to 'short' #pragma warning (disable :4244) // conversion from 'unsigned short' to 'unsigned char' #pragma warning (disable :4267) // truncation of 'size_t' #if !defined VMX86_DEVEL // XXX until we clean up all the code -- edward #pragma warning (disable :4133) // incompatible types - from 'struct VM *' to 'int *' #pragma warning (disable :4047) // differs in levels of indirection #endif #pragma warning (disable :4146) // unary minus operator applied to unsigned type, result still unsigned #pragma warning (disable :4142) // benign redefinition of type #elif __GNUC__ /* The Xserver source compiles with -ansi -pendantic */ #ifndef __STRICT_ANSI__ #if defined(VM_X86_64) typedef unsigned long uint64; typedef long int64; #else typedef unsigned long long uint64; typedef long long int64; #endif #elif __FreeBSD__ typedef unsigned long long uint64; typedef long long int64; #endif #else #error - Need compiler define for int64/uint64 #endif typedef unsigned int uint32; typedef unsigned short uint16; typedef unsigned char uint8; typedef int int32; typedef short int16; typedef char int8; /* * FreeBSD (for the tools build) unconditionally defines these in * sys/inttypes.h so don't redefine them if this file has already * been included. [greg] * * This applies to Solaris as well. */ /* * Before trying to do the includes based on OS defines, see if we can use * feature-based defines to get as much functionality as possible */ #ifdef HAVE_INTTYPES_H #include #endif #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_SYS_INTTYPES_H #include #endif #ifdef HAVE_STDINT_H #include #endif #ifdef HAVE_STDLIB_H #include #endif #if !defined(USING_AUTOCONF) # if defined(__FreeBSD__) || defined(sun) # ifdef KLD_MODULE # include # else # if (BSD_VERSION >= 50) # include # include # else # include # endif # endif # elif defined __APPLE__ # if KERNEL # include # include /* mostly for size_t */ # include # else # include # include # include # include # endif # else # if !defined(__intptr_t_defined) && !defined(intptr_t) # define __intptr_t_defined # define intptr_t intptr_t # ifdef VM_I386 # ifdef VM_X86_64 typedef int64 intptr_t; # else typedef int32 intptr_t; # endif # endif # endif # ifndef _STDINT_H # ifdef VM_I386 # ifdef VM_X86_64 typedef uint64 uintptr_t; # else typedef uint32 uintptr_t; # endif # endif # endif # endif #endif /* * Time * XXX These should be cleaned up. -- edward */ typedef int64 VmTimeType; /* Time in microseconds */ typedef int64 VmTimeRealClock; /* Real clock kept in microseconds */ typedef int64 VmTimeVirtualClock; /* Virtual Clock kept in CPU cycles */ /* * Printf format specifiers for size_t and 64-bit number. * Use them like this: * printf("%"FMT64"d\n", big); * * FMTH is for handles/fds. */ #ifdef _MSC_VER #define FMT64 "I64" #ifdef VM_X86_64 #define FMTSZ "I64" #define FMTPD "I64" #define FMTH "I64" #else #define FMTSZ "I" #define FMTPD "I" #define FMTH "I" #endif #elif __GNUC__ #define FMTH "" #if defined(N_PLAT_NLM) || defined(sun) || \ (defined(__FreeBSD__) && (__FreeBSD__ + 0) && ((__FreeBSD__ + 0) < 5)) /* * Why (__FreeBSD__ + 0)? See bug 141008. * Yes, we really need to test both (__FreeBSD__ + 0) and * ((__FreeBSD__ + 0) < 5). No, we can't remove "+ 0" from * ((__FreeBSD__ + 0) < 5). */ #ifdef VM_X86_64 #define FMTSZ "l" #define FMTPD "l" #else #define FMTSZ "" #define FMTPD "" #endif #elif defined(__linux__) \ || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) \ || (defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L) \ || (defined(_POSIX2_VERSION) && _POSIX2_VERSION >= 200112L) /* BSD/Darwin, Linux */ #define FMTSZ "z" #define FMTPD "t" #else /* Systems with a pre-C99 libc */ #define FMTSZ "Z" #ifdef VM_X86_64 #define FMTPD "l" #else #define FMTPD "" #endif #endif #ifdef VM_X86_64 #define FMT64 "l" #elif defined(sun) || defined(__APPLE__) || defined(__FreeBSD__) #define FMT64 "ll" #else #define FMT64 "L" #endif #else #error - Need compiler define for FMT64 and FMTSZ #endif /* * Suffix for 64-bit constants. Use it like this: * CONST64(0x7fffffffffffffff) for signed or * CONST64U(0x7fffffffffffffff) for unsigned. * * 2004.08.30(thutt): * The vmcore/asm64/gen* programs are compiled as 32-bit * applications, but must handle 64 bit constants. If the * 64-bit-constant defining macros are already defined, the * definition will not be overwritten. */ #if !defined(CONST64) || !defined(CONST64U) #ifdef _MSC_VER #define CONST64(c) c##I64 #define CONST64U(c) c##uI64 #elif __GNUC__ #ifdef VM_X86_64 #define CONST64(c) c##L #define CONST64U(c) c##uL #else #define CONST64(c) c##LL #define CONST64U(c) c##uLL #endif #else #error - Need compiler define for CONST64 #endif #endif /* * Use CONST3264/CONST3264U if you want a constant to be * treated as a 32-bit number on 32-bit compiles and * a 64-bit number on 64-bit compiles. Useful in the case * of shifts, like (CONST3264U(1) << x), where x could be * more than 31 on a 64-bit compile. */ #ifdef VM_X86_64 #define CONST3264(a) CONST64(a) #define CONST3264U(a) CONST64U(a) #else #define CONST3264(a) (a) #define CONST3264U(a) (a) #endif #define MIN_INT32 ((int32)0x80000000) #define MAX_INT32 ((int32)0x7fffffff) #define MIN_UINT32 ((uint32)0) #define MAX_UINT32 ((uint32)0xffffffff) #define MIN_INT64 (CONST64(0x8000000000000000)) #define MAX_INT64 (CONST64(0x7fffffffffffffff)) #define MIN_UINT64 (CONST64U(0)) #define MAX_UINT64 (CONST64U(0xffffffffffffffff)) typedef uint8 *TCA; /* Pointer into TC (usually). */ /* * Type big enough to hold an integer between 0..100 */ typedef uint8 Percent; #define AsPercent(v) ((Percent)(v)) #define CHOOSE_PERCENT AsPercent(101) typedef uintptr_t VA; typedef uintptr_t VPN; typedef uint64 PA; typedef uint32 PPN; typedef uint64 PhysMemOff; typedef uint64 PhysMemSize; /* The Xserver source compiles with -ansi -pendantic */ #ifndef __STRICT_ANSI__ typedef uint64 BA; #endif typedef uint32 BPN; typedef uint32 PageNum; typedef unsigned MemHandle; typedef int32 World_ID; #define INVALID_WORLD_ID ((World_ID)0) typedef World_ID User_CartelID; #define INVALID_CARTEL_ID INVALID_WORLD_ID typedef User_CartelID User_SessionID; #define INVALID_SESSION_ID INVALID_CARTEL_ID typedef User_CartelID User_CartelGroupID; #define INVALID_CARTELGROUP_ID INVALID_CARTEL_ID typedef uint32 Worldlet_ID; #define INVALID_WORLDLET_ID ((Worldlet_ID)0) /* world page number */ typedef uint32 WPN; /* The Xserver source compiles with -ansi -pendantic */ #ifndef __STRICT_ANSI__ typedef uint64 MA; typedef uint32 MPN; #endif /* * This type should be used for variables that contain sector * position/quantity. */ typedef uint64 SectorType; /* * Linear address */ typedef uintptr_t LA; typedef uintptr_t LPN; #define LA_2_LPN(_la) ((_la) >> PAGE_SHIFT) #define LPN_2_LA(_lpn) ((_lpn) << PAGE_SHIFT) #define LAST_LPN ((((LA) 1) << (8 * sizeof(LA) - PAGE_SHIFT)) - 1) #define LAST_LPN32 ((((LA32)1) << (8 * sizeof(LA32) - PAGE_SHIFT)) - 1) #define LAST_LPN64 ((((LA64)1) << (8 * sizeof(LA64) - PAGE_SHIFT)) - 1) /* Valid bits in a LPN. */ #define LPN_MASK LAST_LPN #define LPN_MASK32 LAST_LPN32 #define LPN_MASK64 LAST_LPN64 /* * On 64 bit platform, address and page number types default * to 64 bit. When we need to represent a 32 bit address, we use * types defined below. * * On 32 bit platform, the following types are the same as the * default types. */ typedef uint32 VA32; typedef uint32 VPN32; typedef uint32 LA32; typedef uint32 LPN32; typedef uint32 PA32; typedef uint32 PPN32; typedef uint32 MA32; typedef uint32 MPN32; /* * On 64 bit platform, the following types are the same as the * default types. */ typedef uint64 VA64; typedef uint64 VPN64; typedef uint64 LA64; typedef uint64 LPN64; typedef uint64 PA64; typedef uint64 PPN64; typedef uint64 MA64; typedef uint64 MPN64; /* * VA typedefs for user world apps. */ typedef VA32 UserVA32; typedef VA64 UserVA64; typedef UserVA32 UserVAConst; /* Userspace ptr to data that we may only read. */ typedef UserVA64 UserVA64Const; /* Used by 64-bit syscalls until conversion is finished. */ #ifdef VMKERNEL typedef UserVA32 UserVA; #else typedef void * UserVA; #endif /* * Maximal possible PPN value (errors too) that PhysMem can handle. * Must be at least as large as MAX_PPN which is the maximum PPN * for any region other than buserror. */ #define PHYSMEM_MAX_PPN ((PPN)0xffffffff) #define MAX_PPN ((PPN)0x1fffffff) /* Maximal observable PPN value. */ #define INVALID_PPN ((PPN)0xffffffff) #define INVALID_BPN ((BPN) 0x1fffffff) #define INVALID_MPN ((MPN)-1) #define MEMREF_MPN ((MPN)-2) #define RESERVED_MPN ((MPN) 0) /* Support 43 bits of address space. */ #define MAX_MPN ((MPN)0x7fffffff) #define INVALID_LPN ((LPN)-1) #define INVALID_VPN ((VPN)-1) #define INVALID_LPN64 ((LPN64)-1) #define INVALID_PAGENUM ((PageNum)-1) #define INVALID_WPN ((WPN) -1) /* * Format modifier for printing VA, LA, and VPN. * Use them like this: Log("%#"FMTLA"x\n", laddr) */ #if defined(VMM64) || defined(FROBOS64) || vm_x86_64 || defined __APPLE__ # define FMTLA "l" # define FMTVA "l" # define FMTVPN "l" #else # define FMTLA "" # define FMTVA "" # define FMTVPN "" #endif #define EXTERN extern #define CONST const #ifndef INLINE # ifdef _MSC_VER # define INLINE __inline # else # define INLINE inline # endif #endif /* * Annotation for data that may be exported into a DLL and used by other * apps that load that DLL and import the data. */ #if defined(_WIN32) && defined(VMX86_IMPORT_DLLDATA) # define VMX86_EXTERN_DATA extern __declspec(dllimport) #else // !_WIN32 # define VMX86_EXTERN_DATA extern #endif #if defined(_WIN32) && !defined(VMX86_NO_THREADS) #define THREADSPECIFIC __declspec(thread) #else #define THREADSPECIFIC #endif /* * Due to the wonderful "registry redirection" feature introduced in * 64-bit Windows, if you access any key under HKLM\Software in 64-bit * code, you need to open/create/delete that key with * VMKEY_WOW64_32KEY if you want a consistent view with 32-bit code. */ #ifdef _WIN32 #ifdef _WIN64 #define VMW_KEY_WOW64_32KEY KEY_WOW64_32KEY #else #define VMW_KEY_WOW64_32KEY 0x0 #endif #endif /* * Consider the following reasons functions are inlined: * * 1) inlined for performance reasons * 2) inlined because it's a single-use function * * Functions which meet only condition 2 should be marked with this * inline macro; It is not critical to be inlined (but there is a * code-space & runtime savings by doing so), so when other callers * are added the inline-ness should be removed. */ #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) /* * Starting at version 3.3, gcc does not always inline functions marked * 'inline' (it depends on their size). To force gcc to do so, one must use the * extra __always_inline__ attribute. */ # define INLINE_SINGLE_CALLER INLINE __attribute__((__always_inline__)) # if defined(VMM) \ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 1)) # warning Verify INLINE_SINGLE_CALLER '__always_inline__' attribute (did \ monitor size change?) # endif #else # define INLINE_SINGLE_CALLER INLINE #endif /* * Used when a hard guaranteed of no inlining is needed. Very few * instances need this since the absence of INLINE is a good hint * that gcc will not do inlining. */ #if defined(__GNUC__) && defined(VMM) #define ABSOLUTELY_NOINLINE __attribute__((__noinline__)) #endif /* * Attributes placed on function declarations to tell the compiler * that the function never returns. */ #ifdef _MSC_VER #define NORETURN __declspec(noreturn) #elif __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 9) #define NORETURN __attribute__((__noreturn__)) #else #define NORETURN #endif /* * GCC 3.2 inline asm needs the + constraint for input/ouput memory operands. * Older GCCs don't know about it --hpreg */ #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 2) # define VM_ASM_PLUS 1 #else # define VM_ASM_PLUS 0 #endif /* * Branch prediction hints: * LIKELY(exp) - Expression exp is likely TRUE. * UNLIKELY(exp) - Expression exp is likely FALSE. * Usage example: * if (LIKELY(excCode == EXC_NONE)) { * or * if (UNLIKELY(REAL_MODE(vc))) { * * We know how to predict branches on gcc3 and later (hopefully), * all others we don't so we do nothing. */ #if (__GNUC__ >= 3) /* * gcc3 uses __builtin_expect() to inform the compiler of an expected value. * We use this to inform the static branch predictor. The '!!' in LIKELY * will convert any !=0 to a 1. */ #define LIKELY(_exp) __builtin_expect(!!(_exp), 1) #define UNLIKELY(_exp) __builtin_expect((_exp), 0) #else #define LIKELY(_exp) (_exp) #define UNLIKELY(_exp) (_exp) #endif /* * GCC's argument checking for printf-like functions * This is conditional until we have replaced all `"%x", void *' * with `"0x%08x", (uint32) void *'. Note that %p prints different things * on different platforms. Argument checking is enabled for the * vmkernel, which has already been cleansed. * * fmtPos is the position of the format string argument, beginning at 1 * varPos is the position of the variable argument, beginning at 1 */ #if defined(__GNUC__) # define PRINTF_DECL(fmtPos, varPos) __attribute__((__format__(__printf__, fmtPos, varPos))) #else # define PRINTF_DECL(fmtPos, varPos) #endif #if defined(__GNUC__) # define SCANF_DECL(fmtPos, varPos) __attribute__((__format__(__scanf__, fmtPos, varPos))) #else # define SCANF_DECL(fmtPos, varPos) #endif /* * UNUSED_PARAM should surround the parameter name and type declaration, * e.g. "int MyFunction(int var1, UNUSED_PARAM(int var2))" * */ #ifndef UNUSED_PARAM # if defined(__GNUC__) # define UNUSED_PARAM(_parm) _parm __attribute__((__unused__)) # else # define UNUSED_PARAM(_parm) _parm # endif #endif /* * REGPARM defaults to REGPARM3, i.e., a requent that gcc * puts the first three arguments in registers. (It is fine * if the function has fewer than three args.) Gcc only. * Syntactically, put REGPARM where you'd put INLINE or NORETURN. */ #if defined(__GNUC__) # define REGPARM0 __attribute__((regparm(0))) # define REGPARM1 __attribute__((regparm(1))) # define REGPARM2 __attribute__((regparm(2))) # define REGPARM3 __attribute__((regparm(3))) # define REGPARM REGPARM3 #else # define REGPARM0 # define REGPARM1 # define REGPARM2 # define REGPARM3 # define REGPARM #endif /* * ALIGNED specifies minimum alignment in "n" bytes. */ #ifdef __GNUC__ #define ALIGNED(n) __attribute__((__aligned__(n))) #else #define ALIGNED(n) #endif /* *********************************************************************** * STRUCT_OFFSET_CHECK -- */ /** * * \brief Check if the actual offsef of a member in a structure * is what is expected * * * \param[in] STRUCT Structure the member is a part of. * \param[in] MEMBER Member to check the offset of. * \param[in] OFFSET Expected offset of MEMBER in STRUCTURE. * \param[in] DEBUG_EXTRA Additional bytes to be added to OFFSET to * compensate for extra info in debug builds. * *********************************************************************** */ #ifdef VMX86_DEBUG #define STRUCT_OFFSET_CHECK(STRUCT, MEMBER, OFFSET, DEBUG_EXTRA) \ ASSERT_ON_COMPILE(vmk_offsetof(STRUCT, MEMBER) == (OFFSET + DEBUG_EXTRA)) #else #define STRUCT_OFFSET_CHECK(STRUCT, MEMBER, OFFSET, DEBUG_EXTRA) \ ASSERT_ON_COMPILE(vmk_offsetof(STRUCT, MEMBER) == OFFSET) #endif /* *********************************************************************** * STRUCT_SIZE_CHECK -- */ /** * * \brief Check if the actual size of a structure is what is expected * * * \param[in] STRUCT Structure whose size is to be checked. * \param[in] SIZE Expected size of STRUCT. * \param[in] DEBUG_EXTRA Additional bytes to be added to SIZE to * compensate for extra info in debug builds. * *********************************************************************** */ #ifdef VMX86_DEBUG #define STRUCT_SIZE_CHECK(STRUCT, SIZE, DEBUG_EXTRA) \ ASSERT_ON_COMPILE(sizeof(STRUCT) == (SIZE + DEBUG_EXTRA)) #else #define STRUCT_SIZE_CHECK(STRUCT, SIZE, DEBUG_EXTRA) \ ASSERT_ON_COMPILE(sizeof(STRUCT) == SIZE) #endif /* * __func__ is a stringified function name that is part of the C99 standard. The block * below defines __func__ on older systems where the compiler does not support that * macro. */ #if defined(__GNUC__) \ && ((__GNUC__ == 2 && __GNUC_MINOR < 96) \ || (__GNUC__ < 2)) # define __func__ __FUNCTION__ #endif /* * Once upon a time, this was used to silence compiler warnings that * get generated when the compiler thinks that a function returns * when it is marked noreturn. Don't do it. Use NOT_REACHED(). */ #define INFINITE_LOOP() do { } while (1) /* * On FreeBSD (for the tools build), size_t is typedef'd if _BSD_SIZE_T_ * is defined. Use the same logic here so we don't define it twice. [greg] */ #ifdef __FreeBSD__ # ifdef _BSD_SIZE_T_ # undef _BSD_SIZE_T_ # ifdef VM_I386 # ifdef VM_X86_64 typedef uint64 size_t; # else typedef uint32 size_t; # endif # endif /* VM_I386 */ # endif # ifdef _BSD_SSIZE_T_ # undef _BSD_SSIZE_T_ # define _SSIZE_T # define __ssize_t_defined # define _SSIZE_T_DECLARED # ifdef VM_I386 # ifdef VM_X86_64 typedef int64 ssize_t; # else typedef int32 ssize_t; # endif # endif /* VM_I386 */ # endif #else # ifndef _SIZE_T # define _SIZE_T # ifdef VM_I386 # ifdef VM_X86_64 typedef uint64 size_t; # else typedef uint32 size_t; # endif # endif /* VM_I386 */ # endif # if !defined(FROBOS) && !defined(_SSIZE_T) && !defined(ssize_t) && \ !defined(__ssize_t_defined) && !defined(_SSIZE_T_DECLARED) # define _SSIZE_T # define __ssize_t_defined # define _SSIZE_T_DECLARED # ifdef VM_I386 # ifdef VM_X86_64 typedef int64 ssize_t; # else typedef int32 ssize_t; # endif # endif /* VM_I386 */ # endif #endif /* * Format modifier for printing pid_t. On sun the pid_t is a ulong, but on * Linux it's an int. * Use this like this: printf("The pid is %"FMTPID".\n", pid); */ #ifdef sun # ifdef VM_X86_64 # define FMTPID "d" # else # define FMTPID "lu" # endif #else # define FMTPID "d" #endif /* * Format modifier for printing uid_t. On sun the uid_t is a ulong, but on * Linux it's an int. * Use this like this: printf("The uid is %"FMTUID".\n", uid); */ #ifdef sun # ifdef VM_X86_64 # define FMTUID "u" # else # define FMTUID "lu" # endif #else # define FMTUID "u" #endif /* * Format modifier for printing mode_t. On sun the mode_t is a ulong, but on * Linux it's an int. * Use this like this: printf("The mode is %"FMTMODE".\n", mode); */ #ifdef sun # ifdef VM_X86_64 # define FMTMODE "o" # else # define FMTMODE "lo" # endif #else # define FMTMODE "o" #endif /* * Format modifier for printing time_t. Most platforms define a time_t to be * a long int, but on FreeBSD (as of 5.0, it seems), the time_t is a signed * size quantity. Refer to the definition of FMTSZ to see why we need silly * preprocessor arithmetic. * Use this like this: printf("The mode is %"FMTTIME".\n", time); */ #if defined(__FreeBSD__) && (__FreeBSD__ + 0) && ((__FreeBSD__ + 0) >= 5) # define FMTTIME FMTSZ"d" #else # define FMTTIME "ld" #endif /* * Define MXSemaHandle here so both vmmon and vmx see this definition. */ #ifdef _WIN32 typedef uintptr_t MXSemaHandle; #else typedef int MXSemaHandle; #endif /* * Define type for poll device handles. */ #ifdef _WIN32 typedef uintptr_t PollDevHandle; #else typedef int PollDevHandle; #endif /* * Define the utf16_t type. */ #if defined(_WIN32) && defined(_NATIVE_WCHAR_T_DEFINED) typedef wchar_t utf16_t; #else typedef uint16 utf16_t; #endif #endif /* _VM_BASIC_TYPES_H_ */ vmxnet-only/vm_device_version.h0000444000000000000000000001611412025727017015737 0ustar rootroot/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef VM_DEVICE_VERSION_H #define VM_DEVICE_VERSION_H #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMMEXT #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMKERNEL #define INCLUDE_ALLOW_VMCORE #include "includeCheck.h" #ifdef _WIN32 #include "guiddef.h" #endif /* Our own PCI IDs * VMware SVGA II (Unified VGA) * VMware SVGA (PCI Accelerator) * VMware vmxnet (Idealized NIC) * VMware vmxscsi (Abortive idealized SCSI controller) * VMware chipset (Subsystem ID for our motherboards) * VMware e1000 (Subsystem ID) * VMware vmxnet3 (Uniform Pass Through NIC) */ #define PCI_VENDOR_ID_VMWARE 0x15AD #define PCI_DEVICE_ID_VMWARE_SVGA2 0x0405 #define PCI_DEVICE_ID_VMWARE_SVGA 0x0710 #define PCI_DEVICE_ID_VMWARE_NET 0x0720 #define PCI_DEVICE_ID_VMWARE_SCSI 0x0730 #define PCI_DEVICE_ID_VMWARE_VMCI 0x0740 #define PCI_DEVICE_ID_VMWARE_CHIPSET 0x1976 #define PCI_DEVICE_ID_VMWARE_82545EM 0x0750 /* single port */ #define PCI_DEVICE_ID_VMWARE_82546EB 0x0760 /* dual port */ #define PCI_DEVICE_ID_VMWARE_EHCI 0x0770 #define PCI_DEVICE_ID_VMWARE_1394 0x0780 #define PCI_DEVICE_ID_VMWARE_BRIDGE 0x0790 #define PCI_DEVICE_ID_VMWARE_ROOTPORT 0x07A0 #define PCI_DEVICE_ID_VMWARE_VMXNET3 0x07B0 #define PCI_DEVICE_ID_VMWARE_PVSCSI 0x07C0 /* The hypervisor device might grow. Please leave room * for 7 more subfunctions. */ #define PCI_DEVICE_ID_VMWARE_HYPER 0x0800 #define PCI_DEVICE_ID_VMWARE_VMI 0x0801 #define PCI_DEVICE_VMI_CLASS 0x05 #define PCI_DEVICE_VMI_SUBCLASS 0x80 #define PCI_DEVICE_VMI_INTERFACE 0x00 #define PCI_DEVICE_VMI_REVISION 0x01 /* From linux/pci_ids.h: * AMD Lance Ethernet controller * BusLogic SCSI controller * Ensoniq ES1371 sound controller */ #define PCI_VENDOR_ID_AMD 0x1022 #define PCI_DEVICE_ID_AMD_VLANCE 0x2000 #define PCI_VENDOR_ID_BUSLOGIC 0x104B #define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC 0x0140 #define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER 0x1040 #define PCI_VENDOR_ID_ENSONIQ 0x1274 #define PCI_DEVICE_ID_ENSONIQ_ES1371 0x1371 /* From linux/pci_ids.h: * Intel 82439TX (430 HX North Bridge) * Intel 82371AB (PIIX4 South Bridge) * Intel 82443BX (440 BX North Bridge and AGP Bridge) * Intel 82545EM (e1000, server adapter, single port) * Intel 82546EB (e1000, server adapter, dual port) */ #define PCI_VENDOR_ID_INTEL 0x8086 #define PCI_DEVICE_ID_INTEL_82439TX 0x7100 #define PCI_DEVICE_ID_INTEL_82371AB_0 0x7110 #define PCI_DEVICE_ID_INTEL_82371AB_2 0x7112 #define PCI_DEVICE_ID_INTEL_82371AB_3 0x7113 #define PCI_DEVICE_ID_INTEL_82371AB 0x7111 #define PCI_DEVICE_ID_INTEL_82443BX 0x7190 #define PCI_DEVICE_ID_INTEL_82443BX_1 0x7191 #define PCI_DEVICE_ID_INTEL_82443BX_2 0x7192 /* Used when no AGP support */ #define PCI_DEVICE_ID_INTEL_82545EM 0x100f #define PCI_DEVICE_ID_INTEL_82546EB 0x1010 /************* Strings for IDE Identity Fields **************************/ #define VIDE_ID_SERIAL_STR "00000000000000000001" /* Must be 20 Bytes */ #define VIDE_ID_FIRMWARE_STR "00000001" /* Must be 8 Bytes */ /* No longer than 40 Bytes */ #define VIDE_ATA_MODEL_STR PRODUCT_GENERIC_NAME " Virtual IDE Hard Drive" #define VIDE_ATAPI_MODEL_STR PRODUCT_GENERIC_NAME " Virtual IDE CDROM Drive" #define ATAPI_VENDOR_ID "NECVMWar" /* Must be 8 Bytes */ #define ATAPI_PRODUCT_ID PRODUCT_GENERIC_NAME " IDE CDROM" /* Must be 16 Bytes */ #define ATAPI_REV_LEVEL "1.00" /* Must be 4 Bytes */ #define IDE_NUM_INTERFACES 2 /* support for two interfaces */ #define IDE_DRIVES_PER_IF 2 /************* Strings for SCSI Identity Fields **************************/ #define SCSI_DISK_MODEL_STR PRODUCT_GENERIC_NAME " Virtual SCSI Hard Drive" #define SCSI_DISK_VENDOR_NAME COMPANY_NAME #define SCSI_DISK_REV_LEVEL "1.0" #define SCSI_CDROM_MODEL_STR PRODUCT_GENERIC_NAME " Virtual SCSI CDROM Drive" #define SCSI_CDROM_VENDOR_NAME COMPANY_NAME #define SCSI_CDROM_REV_LEVEL "1.0" /************* SCSI implementation limits ********************************/ #define SCSI_MAX_CONTROLLERS 4 // Need more than 1 for MSCS clustering #define SCSI_MAX_DEVICES 16 // BT-958 emulates only 16 #define SCSI_IDE_CHANNEL SCSI_MAX_CONTROLLERS #define SCSI_IDE_HOSTED_CHANNEL (SCSI_MAX_CONTROLLERS + 1) #define SCSI_MAX_CHANNELS (SCSI_MAX_CONTROLLERS + 2) /************* Strings for the VESA BIOS Identity Fields *****************/ #define VBE_OEM_STRING COMPANY_NAME " SVGA" #define VBE_VENDOR_NAME COMPANY_NAME #define VBE_PRODUCT_NAME PRODUCT_GENERIC_NAME /************* PCI implementation limits ********************************/ #define PCI_MAX_BRIDGES 15 /************* Ethernet implementation limits ***************************/ #define MAX_ETHERNET_CARDS 10 /************* PCI Passthrough implementation limits ********************/ #define MAX_PCI_PASSTHRU_DEVICES 2 /************* USB implementation limits ********************************/ #define MAX_USB_DEVICES_PER_HOST_CONTROLLER 127 /************* Strings for Host USB Driver *******************************/ #ifdef _WIN32 /* * Globally unique ID for the VMware device interface. Define INITGUID before including * this header file to instantiate the variable. */ DEFINE_GUID(GUID_DEVICE_INTERFACE_VMWARE_USB_DEVICES, 0x2da1fe75, 0xaab3, 0x4d2c, 0xac, 0xdf, 0x39, 0x8, 0x8c, 0xad, 0xa6, 0x65); /* * Globally unique ID for the VMware device setup class. */ DEFINE_GUID(GUID_CLASS_VMWARE_USB_DEVICES, 0x3b3e62a5, 0x3556, 0x4d7e, 0xad, 0xad, 0xf5, 0xfa, 0x3a, 0x71, 0x2b, 0x56); /* * This string defines the device ID string of a VMware USB device. * The format is USB\Vid_XXXX&Pid_YYYY, where XXXX and YYYY are the * hexadecimal representations of the vendor and product ids, respectively. * * The official vendor ID for VMware, Inc. is 0x0E0F. * The product id for USB generic devices is 0x0001. */ #define USB_VMWARE_DEVICE_ID_WIDE L"USB\\Vid_0E0F&Pid_0001" #define USB_DEVICE_ID_LENGTH (sizeof(USB_VMWARE_DEVICE_ID_WIDE) / sizeof(WCHAR)) #ifdef UNICODE #define USB_PNP_SETUP_CLASS_NAME L"VMwareUSBDevices" #define USB_PNP_DRIVER_NAME L"vmusb" #else #define USB_PNP_SETUP_CLASS_NAME "VMwareUSBDevices" #define USB_PNP_DRIVER_NAME "vmusb" #endif #endif #endif /* VM_DEVICE_VERSION_H */ vmxnet-only/vmnet_def.h0000444000000000000000000000615412025727017014203 0ustar rootroot/********************************************************* * Copyright (C) 2004 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmnet_def.h * * - definitions which are (mostly) not vmxnet or vlance specific */ #ifndef _VMNET_DEF_H_ #define _VMNET_DEF_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMMEXT #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMK_MODULE #define INCLUDE_ALLOW_VMKERNEL #define INCLUDE_ALLOW_DISTRIBUTE #define INCLUDE_ALLOW_VMNIXMOD #include "includeCheck.h" /* * capabilities - not all of these are implemented in the virtual HW * (eg VLAN support is in the virtual switch) so even vlance * can use them */ #define VMNET_CAP_SG 0x0001 /* Can do scatter-gather transmits. */ #define VMNET_CAP_IP4_CSUM 0x0002 /* Can checksum only TCP/UDP over IPv4. */ #define VMNET_CAP_HW_CSUM 0x0004 /* Can checksum all packets. */ #define VMNET_CAP_HIGH_DMA 0x0008 /* Can DMA to high memory. */ #define VMNET_CAP_TOE 0x0010 /* Supports TCP/IP offload. */ #define VMNET_CAP_TSO 0x0020 /* Supports TCP Segmentation offload */ #define VMNET_CAP_SW_TSO 0x0040 /* Supports SW TCP Segmentation */ #define VMNET_CAP_VMXNET_APROM 0x0080 /* Vmxnet APROM support */ #define VMNET_CAP_HW_TX_VLAN 0x0100 /* Can we do VLAN tagging in HW */ #define VMNET_CAP_HW_RX_VLAN 0x0200 /* Can we do VLAN untagging in HW */ #define VMNET_CAP_SW_VLAN 0x0400 /* Can we do VLAN tagging/untagging in SW */ #define VMNET_CAP_WAKE_PCKT_RCV 0x0800 /* Can wake on network packet recv? */ #define VMNET_CAP_ENABLE_INT_INLINE 0x1000 /* Enable Interrupt Inline */ #define VMNET_CAP_ENABLE_HEADER_COPY 0x2000 /* copy header for vmkernel */ #define VMNET_CAP_TX_CHAIN 0x4000 /* Guest can use multiple tx entries for a pkt */ #define VMNET_CAP_RX_CHAIN 0x8000 /* a pkt can span multiple rx entries */ #define VMNET_CAP_LPD 0x10000 /* large pkt delivery */ #define VMNET_CAP_BPF 0x20000 /* BPF Support in VMXNET Virtual Hardware */ #define VMNET_CAP_SG_SPAN_PAGES 0x40000 /* Can do scatter-gather span multiple pages transmits. */ #define VMNET_CAP_IP6_CSUM 0x80000 /* Can do IPv6 csum offload. */ #define VMNET_CAP_TSO6 0x100000 /* Can do TSO segmentation offload for IPv6 pkts. */ #define VMNET_CAP_TSO256k 0x200000 /* Can do TSO segmentation offload for pkts up to 256kB. */ #endif // _VMNET_DEF_H_ vmxnet-only/vmxnet_def.h0000444000000000000000000001330312025727017014365 0ustar rootroot/********************************************************* * Copyright (C) 1999 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef _VMXNET_DEF_H_ #define _VMXNET_DEF_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMMEXT #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMK_MODULE #define INCLUDE_ALLOW_VMKERNEL #define INCLUDE_ALLOW_DISTRIBUTE #include "includeCheck.h" #include "net_sg.h" #include "vmnet_def.h" /* * Vmxnet I/O ports, used by both the vmxnet driver and * the device emulation code. */ #define VMXNET_INIT_ADDR 0x00 #define VMXNET_INIT_LENGTH 0x04 #define VMXNET_TX_ADDR 0x08 #define VMXNET_COMMAND_ADDR 0x0c #define VMXNET_MAC_ADDR 0x10 #define VMXNET_LOW_VERSION 0x18 #define VMXNET_HIGH_VERSION 0x1c #define VMXNET_STATUS_ADDR 0x20 #define VMXNET_TOE_INIT_ADDR 0x24 #define VMXNET_APROM_ADDR 0x28 #define VMXNET_INT_ENABLE_ADDR 0x30 #define VMXNET_WAKE_PKT_PATTERNS 0x34 /* * Vmxnet command register values. */ #define VMXNET_CMD_INTR_ACK 0x0001 #define VMXNET_CMD_UPDATE_LADRF 0x0002 #define VMXNET_CMD_UPDATE_IFF 0x0004 #define VMXNET_CMD_UNUSED 1 0x0008 #define VMXNET_CMD_UNUSED_2 0x0010 #define VMXNET_CMD_INTR_DISABLE 0x0020 #define VMXNET_CMD_INTR_ENABLE 0x0040 #define VMXNET_CMD_UNUSED_3 0x0080 #define VMXNET_CMD_CHECK_TX_DONE 0x0100 #define VMXNET_CMD_GET_NUM_RX_BUFFERS 0x0200 #define VMXNET_CMD_GET_NUM_TX_BUFFERS 0x0400 #define VMXNET_CMD_PIN_TX_BUFFERS 0x0800 #define VMXNET_CMD_GET_CAPABILITIES 0x1000 #define VMXNET_CMD_GET_FEATURES 0x2000 #define VMXNET_CMD_SET_POWER_FULL 0x4000 #define VMXNET_CMD_SET_POWER_LOW 0x8000 /* * Vmxnet status register values. */ #define VMXNET_STATUS_CONNECTED 0x0001 #define VMXNET_STATUS_ENABLED 0x0002 #define VMXNET_STATUS_TX_PINNED 0x0004 /* * Values for the interface flags. */ #define VMXNET_IFF_PROMISC 0x01 #define VMXNET_IFF_BROADCAST 0x02 #define VMXNET_IFF_MULTICAST 0x04 #define VMXNET_IFF_DIRECTED 0x08 /* * Length of the multicast address filter. */ #define VMXNET_MAX_LADRF 2 /* * Size of Vmxnet APROM. */ #define VMXNET_APROM_SIZE 6 /* * An invalid ring index. */ #define VMXNET_INVALID_RING_INDEX -1 /* * Features that are implemented by the driver. These are driver * specific so not all features will be listed here. In addition not all * drivers have to pay attention to these feature flags. * * VMXNET_FEATURE_ZERO_COPY_TX The driver won't do any copies as long as * the packet length is > * Vmxnet_DriverData.minTxPhysLength. * * VMXNET_FEATURE_TSO The driver will use the TSO capabilities * of the underlying hardware if available * and enabled. * * VMXNET_FEATURE_JUMBO_FRAME The driver can send/rcv jumbo frame * * VMXNET_FEATURE_LPD The backend can deliver large pkts */ #define VMXNET_FEATURE_ZERO_COPY_TX 0x01 #define VMXNET_FEATURE_TSO 0x02 #define VMXNET_FEATURE_JUMBO_FRAME 0x04 #define VMXNET_FEATURE_LPD 0x08 /* * Define the set of capabilities required by each feature above */ #define VMXNET_FEATURE_ZERO_COPY_TX_CAPS VMXNET_CAP_SG #define VMXNET_FEATURE_TSO_CAPS VMXNET_CAP_TSO #define VMXNET_HIGHEST_FEATURE_BIT VMXNET_FEATURE_TSO #define VMXNET_INC(val, max) \ val++; \ if (UNLIKELY(val == max)) { \ val = 0; \ } /* * code that just wants to switch on the different versions of the * guest<->implementation protocol can cast driver data to this. */ typedef uint32 Vmxnet_DDMagic; /* * Wake packet pattern commands sent through VMXNET_WAKE_PKT_PATTERNS port */ #define VMXNET_PM_OPCODE_START 3 /* args: cnt of wake packet patterns */ #define VMXNET_PM_OPCODE_LEN 2 /* args: index of wake packet pattern */ /* number of pattern byte values */ #define VMXNET_PM_OPCODE_DATA 1 /* args: index of wake packet pattern */ /* offset in pattern byte values list */ /* packet byte offset */ /* packet byte value */ #define VMXNET_PM_OPCODE_END 0 /* args: */ typedef union Vmxnet_WakePktCmd { uint32 pktData : 32; struct { unsigned cmd : 2; /* wake packet pattern cmd [from list above] */ unsigned cnt : 3; /* cnt wk pkt pttrns 1..MAX_NUM_FILTER_PTTRNS */ unsigned ind : 3; /* ind wk pkt pttrn 0..MAX_NUM_FILTER_PTTRNS-1 */ unsigned lenOff : 8; /* num pttrn byte vals 1..MAX_PKT_FILTER_SIZE */ /* OR offset in pattern byte values list */ /* 0..MAX_PKT_FILTER_SIZE-1 */ unsigned byteOff : 8; /* pkt byte offset 0..MAX_PKT_FILTER_SIZE-1 */ unsigned byteVal : 8; /* packet byte value 0..255 */ } pktPttrn; } Vmxnet_WakePktCmd; #endif /* _VMXNET_DEF_H_ */ vmxnet-only/vmxnet2_def.h0000444000000000000000000003450712025727017014460 0ustar rootroot/********************************************************* * Copyright (C) 2004 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef _VMXNET2_DEF_H_ #define _VMXNET2_DEF_H_ #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMMEXT #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMK_MODULE #define INCLUDE_ALLOW_VMKERNEL #define INCLUDE_ALLOW_DISTRIBUTE #include "includeCheck.h" #include "net_sg.h" #include "vmxnet_def.h" /* * Magic number that identifies this version of the vmxnet protocol. */ #define VMXNET2_MAGIC 0xbabe864f /* size of the rx ring */ #define VMXNET2_MAX_NUM_RX_BUFFERS 128 #define VMXNET2_DEFAULT_NUM_RX_BUFFERS 100 /* size of the rx ring when enhanced vmxnet is used */ #define ENHANCED_VMXNET2_MAX_NUM_RX_BUFFERS 512 #define ENHANCED_VMXNET2_DEFAULT_NUM_RX_BUFFERS 150 /* size of the 2nd rx ring */ #define VMXNET2_MAX_NUM_RX_BUFFERS2 2048 #define VMXNET2_DEFAULT_NUM_RX_BUFFERS2 512 /* size of the tx ring */ #define VMXNET2_MAX_NUM_TX_BUFFERS 128 #define VMXNET2_DEFAULT_NUM_TX_BUFFERS 100 /* size of the tx ring when tso/jf is used */ #define VMXNET2_MAX_NUM_TX_BUFFERS_TSO 512 #define VMXNET2_DEFAULT_NUM_TX_BUFFERS_TSO 256 enum { VMXNET2_OWNERSHIP_DRIVER, VMXNET2_OWNERSHIP_DRIVER_PENDING, VMXNET2_OWNERSHIP_NIC, VMXNET2_OWNERSHIP_NIC_PENDING, VMXNET2_OWNERSHIP_NIC_FRAG, VMXNET2_OWNERSHIP_DRIVER_FRAG, }; #define VMXNET2_SG_DEFAULT_LENGTH 6 typedef struct Vmxnet2_SG_Array { uint16 addrType; uint16 length; NetSG_Elem sg[VMXNET2_SG_DEFAULT_LENGTH]; } Vmxnet2_SG_Array; typedef struct Vmxnet2_RxRingEntry { uint64 paddr; /* Physical address of the packet data. */ uint32 bufferLength; /* The length of the data at paddr. */ uint32 actualLength; /* The actual length of the received data. */ uint16 ownership; /* Who owns the packet. */ uint16 flags; /* Flags as defined below. */ uint32 index; /* * Currently: * * This is being used as an packet index to * rx buffers. * * Originally: * * was void* driverData ("Driver specific data.") * which was used for sk_buf**s in Linux and * VmxnetRxBuff*s in Windows. It could not be * here because the structure needs to be the * same size between architectures, and it was * not used on the device side, anyway. Look * for its replacement in * Vmxnet_Private.rxRingBuffPtr on Linux and * VmxnetAdapter.rxRingBuffPtr on Windows. */ } Vmxnet2_RxRingEntry; /* * Vmxnet2_RxRingEntry flags: * * VMXNET2_RX_HW_XSUM_OK The hardware verified the TCP/UDP checksum. * VMXNET2_RX_WITH_FRAG More data is in the 2nd ring * VMXNET2_RX_FRAG_EOP This is the last frag, the only valid flag for * 2nd ring entry * */ #define VMXNET2_RX_HW_XSUM_OK 0x01 #define VMXNET2_RX_WITH_FRAG 0x02 #define VMXNET2_RX_FRAG_EOP 0x04 typedef struct Vmxnet2_TxRingEntry { uint16 flags; /* Flags as defined below. */ uint16 ownership; /* Who owns this packet. */ uint32 extra; /* * was void* driverData ("Driver specific data.") * which was used for sk_buf*s in Linux and * VmxnetTxInfo*s in Windows. It could not be * here because the structure needs to be the * same size between architectures, and it was * not used on the device side, anyway. Look * for its replacement in * Vmxnet_Private.txRingBuffPtr on Linux and * VmxnetAdapter.txRingBuffPtr on Windows. */ uint32 tsoMss; /* TSO pkt MSS */ Vmxnet2_SG_Array sg; /* Packet data. */ } Vmxnet2_TxRingEntry; /* * Vmxnet2_TxRingEntry flags: * * VMXNET2_TX_CAN_KEEP The implementation can return the tx ring entry * to the driver when it is ready as opposed to * before the transmit call from the driver completes. * VMXNET2_TX_RING_LOW The driver's transmit ring buffer is low on free * slots. * VMXNET2_TX_HW_XSUM The hardware should perform the TCP/UDP checksum * VMXNET2_TX_TSO The hardware should do TCP segmentation. * VMXNET2_TX_PINNED_BUFFER The driver used one of the preallocated vmkernel * buffers *and* it has been pinned with Net_PinTxBuffers. * VMXNET2_TX_MORE This is *not* the last tx entry for the pkt. * All flags except VMXNET2_TX_MORE are ignored * for the subsequent tx entries. */ #define VMXNET2_TX_CAN_KEEP 0x0001 #define VMXNET2_TX_RING_LOW 0x0002 #define VMXNET2_TX_HW_XSUM 0x0004 #define VMXNET2_TX_TSO 0x0008 #define VMXNET2_TX_PINNED_BUFFER 0x0010 #define VMXNET2_TX_MORE 0x0020 /* * Structure used by implementations. This structure allows the inline * functions below to be used. */ typedef struct Vmxnet2_RxRingInfo { Vmxnet2_RxRingEntry *base; /* starting addr of the ring */ uint32 nicNext; /* next entry to use in the ring */ uint32 ringLength; /* # of entries in the ring */ PA startPA; /* PA of the starting addr of the ring */ #ifdef VMX86_DEBUG const char *name; #endif } Vmxnet2_RxRingInfo; typedef struct Vmxnet2_TxRingInfo { Vmxnet2_TxRingEntry *base; /* starting addr of the ring */ uint32 nicNext; /* next entry to use in the ring */ uint32 ringLength; /* # of entries in the ring */ PA startPA; /* PA of the starting addr of the ring */ #ifdef VMX86_DEBUG const char *name; #endif } Vmxnet2_TxRingInfo; typedef struct Vmxnet2_ImplData { Vmxnet2_RxRingInfo rxRing; Vmxnet2_RxRingInfo rxRing2; Vmxnet2_TxRingInfo txRing; struct PhysMem_Token *ddPhysMemToken; } Vmxnet2_ImplData; /* * Used internally for performance studies. By default this will be off so there * should be no compatibilty or other interferences. */ /* #define ENABLE_VMXNET2_PROFILING */ #ifdef ENABLE_VMXNET2_PROFILING typedef struct Vmxnet2_VmmStats { uint64 vIntTSC; /* the time that virtual int was posted */ uint64 actionsCount; /* Number of actions received */ uint64 numWasteActions; /* Number of non-productive actions */ } Vmxnet2_VmmStats; #endif typedef struct Vmxnet2_DriverStats { uint32 transmits; /* # of times that the drivers transmit function */ /* is called. The driver could transmit more */ /* than one packet per call. */ uint32 pktsTransmitted; /* # of packets transmitted. */ uint32 noCopyTransmits; /* # of packets that are transmitted without */ /* copying any data. */ uint32 copyTransmits; /* # of packets that are transmittted by copying */ /* the data into a buffer. */ uint32 maxTxsPending; /* Max # of transmits outstanding. */ uint32 txStopped; /* # of times that transmits got stopped because */ /* the tx ring was full. */ uint32 txRingOverflow; /* # of times that transmits got deferred bc */ /* the tx ring was full. This must be >= */ /* txStopped since there will be one */ /* txStopped when the ring fills up and then */ /* one txsRingOverflow for each packet that */ /* that gets deferred until there is space. */ uint32 interrupts; /* # of times interrupted. */ uint32 pktsReceived; /* # of packets received. */ uint32 rxBuffersLow; /* # of times that the driver was low on */ /* receive buffers. */ #ifdef ENABLE_VMXNET2_PROFILING Vmxnet2_VmmStats vmmStats; /* vmm related stats for perf study */ #endif } Vmxnet2_DriverStats; /* * Shared data structure between the vm, the vmm, and the vmkernel. * This structure was originally arranged to try to group common data * on 32-byte cache lines, but bit rot and the fact that we no longer * run on many CPUs with that cacheline size killed that optimization. * vmxnet3 should target 128 byte sizes and alignments to optimize for * the 64 byte cacheline pairs on P4. */ typedef struct Vmxnet2_DriverData { /* * Magic must be first. */ Vmxnet_DDMagic magic; /* * Receive fields. */ uint32 rxRingLength; /* Length of the receive ring. */ uint32 rxDriverNext; /* Index of the next packet that will */ /* be filled in by the impl */ uint32 rxRingLength2; /* Length of the 2nd receive ring. */ uint32 rxDriverNext2; /* Index of the next packet that will */ /* be filled in by the impl */ uint32 notUsed1; /* was "irq" */ /* * Interface flags and multicast filter. */ uint32 ifflags; uint32 LADRF[VMXNET_MAX_LADRF]; /* * Transmit fields */ uint32 txDontClusterSize; /* All packets <= this will be transmitted */ /* immediately, regardless of clustering */ /* settings [was fill[1]] */ uint32 txRingLength; /* Length of the transmit ring. */ uint32 txDriverCur; /* Index of the next packet to be */ /* returned by the implementation.*/ uint32 txDriverNext; /* Index of the entry in the ring */ /* buffer to use for the next packet.*/ uint32 txStopped; /* The driver has stopped transmitting */ /* because its ring buffer is full.*/ uint32 txClusterLength; /* Maximum number of packets to */ /* put in the ring buffer before */ /* asking the implementation to */ /* transmit the packets in the buffer.*/ uint32 txNumDeferred; /* Number of packets that have been */ /* queued in the ring buffer since */ /* the last time the implementation */ /* was asked to transmit. */ uint32 notUsed3; /* This field is deprecated but still used */ /* as minXmitPhysLength on the escher branch. */ /* It cannot be used for other purposes */ /* until escher vms no longer are allowed */ /* to install this driver. */ uint32 totalRxBuffers; /* used by esx for max rx buffers */ uint64 rxBufferPhysStart; /* used by esx for pinng rx buffers */ /* * Extra fields for future expansion. */ uint32 extra[2]; uint16 maxFrags; /* # of frags the driver can handle */ uint16 featureCtl; /* for driver to enable some feature */ /* * The following fields are used to save the nicNext indexes part * of implData in the vmkernel when disconnecting the adapter, we * need them when we reconnect. This mechanism is used for * checkpointing as well. */ uint32 savedRxNICNext; uint32 savedRxNICNext2; uint32 savedTxNICNext; /* * Fields used during initialization or debugging. */ uint32 length; uint32 rxRingOffset; uint32 rxRingOffset2; uint32 txRingOffset; uint32 debugLevel; uint32 txBufferPhysStart; uint32 txBufferPhysLength; uint32 txPktMaxSize; /* * Driver statistics. */ Vmxnet2_DriverStats stats; } Vmxnet2_DriverData; /* * Shared between VMM and Vmkernel part of vmxnet2 to optimize action posting * VMM writes 1 (don't post) or 0 (okay to post) and vmk reads this. */ typedef struct VmxnetVMKShared { uint32 dontPostActions; } VmxnetVMKShared; /* * Inline functions used to assist the implementation of the vmxnet interface. */ /* * Get the next empty packet out of the receive ring and move to * the next packet. */ static INLINE Vmxnet2_RxRingEntry * Vmxnet2_GetNextRx(Vmxnet2_RxRingInfo *ri, uint16 ownership) { Vmxnet2_RxRingEntry *rre = ri->base + ri->nicNext; if (rre->ownership == ownership) { VMXNET_INC(ri->nicNext, ri->ringLength); } else { rre = NULL; } return rre; } /* * Return ownership of a packet in the receive ring to the driver. */ static INLINE void Vmxnet2_PutRx(Vmxnet2_RxRingEntry *rre, uint32 pktLength, uint16 ownership) { rre->actualLength = pktLength; rre->ownership = ownership; } /* * Get the next pending packet out of the transmit ring. */ static INLINE Vmxnet2_TxRingEntry * Vmxnet2_GetNextTx(Vmxnet2_TxRingInfo *ri) { Vmxnet2_TxRingEntry *txre = ri->base + ri->nicNext; if (txre->ownership == VMXNET2_OWNERSHIP_NIC) { return txre; } else { return NULL; } } /* * Move to the next entry in the transmit ring. */ static INLINE unsigned int Vmxnet2_IncNextTx(Vmxnet2_TxRingInfo *ri) { unsigned int prev = ri->nicNext; Vmxnet2_TxRingEntry *txre = ri->base + ri->nicNext; txre->ownership = VMXNET2_OWNERSHIP_NIC_PENDING; VMXNET_INC(ri->nicNext, ri->ringLength); return prev; } /* * Get the indicated entry from transmit ring. */ static INLINE Vmxnet2_TxRingEntry * Vmxnet2_GetTxEntry(Vmxnet2_TxRingInfo *ri, unsigned int idx) { return ri->base + idx; } /* * Get the indicated entry from the given rx ring */ static INLINE Vmxnet2_RxRingEntry * Vmxnet2_GetRxEntry(Vmxnet2_RxRingInfo *ri, unsigned int idx) { return ri->base + idx; } #endif vmxnet-only/includeCheck.h0000444000000000000000000001024612025727017014612 0ustar rootroot/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * includeCheck.h -- * * Restrict include file use. * * In every .h file, define one or more of these * * INCLUDE_ALLOW_VMX * INCLUDE_ALLOW_USERLEVEL * INCLUDE_ALLOW_VMMEXT * INCLUDE_ALLOW_VMCORE * INCLUDE_ALLOW_MODULE * INCLUDE_ALLOW_VMNIXMOD * INCLUDE_ALLOW_VMKERNEL * INCLUDE_ALLOW_DISTRIBUTE * INCLUDE_ALLOW_VMK_MODULE * INCLUDE_ALLOW_VMKDRIVERS * INCLUDE_ALLOW_VMIROM * * Then include this file. * * Any file that has INCLUDE_ALLOW_DISTRIBUTE defined will potentially * be distributed in source form along with GPLed code. Ensure * that this is acceptable. */ /* * Declare a VMCORE-only variable to help classify object * files. The variable goes in the common block and does * not create multiple definition link-time conflicts. */ #if defined VMCORE && defined VMX86_DEVEL && defined VMX86_DEBUG && \ defined linux && !defined MODULE && \ !defined COMPILED_WITH_VMCORE #define COMPILED_WITH_VMCORE compiled_with_vmcore #ifdef ASM .comm compiled_with_vmcore, 0 #else asm(".comm compiled_with_vmcore, 0"); #endif /* ASM */ #endif #if defined VMCORE && \ !(defined VMX86_VMX || defined VMM || \ defined MONITOR_APP || defined VMMON) #error "Makefile problem: VMCORE without VMX86_VMX or \ VMM or MONITOR_APP or MODULE." #endif #if defined VMCORE && !defined INCLUDE_ALLOW_VMCORE #error "The surrounding include file is not allowed in vmcore." #endif #undef INCLUDE_ALLOW_VMCORE #if defined VMX86_VMX && !defined VMCORE && \ !(defined INCLUDE_ALLOW_VMX || defined INCLUDE_ALLOW_USERLEVEL) #error "The surrounding include file is not allowed in the VMX." #endif #undef INCLUDE_ALLOW_VMX #if defined USERLEVEL && !defined VMX86_VMX && !defined VMCORE && \ !defined INCLUDE_ALLOW_USERLEVEL #error "The surrounding include file is not allowed at userlevel." #endif #undef INCLUDE_ALLOW_USERLEVEL #if defined VMM && !defined VMCORE && \ !defined INCLUDE_ALLOW_VMMEXT #error "The surrounding include file is not allowed in the monitor." #endif #undef INCLUDE_ALLOW_VMMEXT #if defined MODULE && !defined VMKERNEL_MODULE && !defined VMNIXMOD && \ !defined VMMON && !defined INCLUDE_ALLOW_MODULE #error "The surrounding include file is not allowed in driver modules." #endif #undef INCLUDE_ALLOW_MODULE #if defined VMMON && !defined INCLUDE_ALLOW_VMMON #error "The surrounding include file is not allowed in vmmon." #endif #undef INCLUDE_ALLOW_VMMON #if defined VMKERNEL && !defined INCLUDE_ALLOW_VMKERNEL #error "The surrounding include file is not allowed in the vmkernel." #endif #undef INCLUDE_ALLOW_VMKERNEL #if defined GPLED_CODE && !defined INCLUDE_ALLOW_DISTRIBUTE #error "The surrounding include file is not allowed in GPL code." #endif #undef INCLUDE_ALLOW_DISTRIBUTE #if defined VMKERNEL_MODULE && !defined VMKERNEL && \ !defined INCLUDE_ALLOW_VMK_MODULE && !defined INCLUDE_ALLOW_VMKDRIVERS #error "The surrounding include file is not allowed in vmkernel modules." #endif #undef INCLUDE_ALLOW_VMK_MODULE #undef INCLUDE_ALLOW_VMKDRIVERS #if defined VMNIXMOD && !defined INCLUDE_ALLOW_VMNIXMOD #ifndef VMNIXMOD_VM #error "The surrounding include file is not allowed in vmnixmod." #endif #endif #undef INCLUDE_ALLOW_VMNIXMOD #if defined VMIROM && ! defined INCLUDE_ALLOW_VMIROM #error "The surrounding include file is not allowed in vmirom." #endif #undef INCLUDE_ALLOW_VMIROM vmxnet-only/net_sg.h0000444000000000000000000000430012025727017013502 0ustar rootroot/********************************************************* * Copyright (C) 2000 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * net_sg.h -- * * Network packet scatter gather structure. */ #ifndef _NET_SG_H #define _NET_SG_H #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_VMMEXT #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMNIXMOD #define INCLUDE_ALLOW_VMK_MODULE #define INCLUDE_ALLOW_VMKERNEL #define INCLUDE_ALLOW_DISTRIBUTE #include "includeCheck.h" #define NET_SG_DEFAULT_LENGTH 16 /* * A single scatter-gather element for a network packet. * The address is split into low and high to save space. * If we make it 64 bits then Windows pads things out such that * we lose a lot of space for each scatter gather array. * This adds up when you have embedded scatter-gather * arrays for transmit and receive ring buffers. */ typedef struct NetSG_Elem { uint32 addrLow; uint16 addrHi; uint16 length; } NetSG_Elem; typedef enum NetSG_AddrType { NET_SG_MACH_ADDR, NET_SG_PHYS_ADDR, NET_SG_VIRT_ADDR, NET_SG_VMM_STACK_OFFSET, } NetSG_AddrType; typedef struct NetSG_Array { uint16 addrType; uint16 length; NetSG_Elem sg[NET_SG_DEFAULT_LENGTH]; } NetSG_Array; #define NET_SG_SIZE(len) (sizeof(NetSG_Array) + (len - NET_SG_DEFAULT_LENGTH) * sizeof(NetSG_Elem)) #define NET_SG_MAKE_PA(elem) (((PA)elem.addrHi << 32) | (PA)elem.addrLow) #define NET_SG_MAKE_PTR(elem) \ ((char*)(uintptr_t)(((uint64)elem.addrHi << 32) | elem.addrLow)) #endif vmxnet-only/net.h0000444000000000000000000001020012025727017013005 0ustar rootroot/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /************************************************************ * * net.h * * This file should contain all network global defines. * No vlance/vmxnet/vnet/vmknet specific stuff should be * put here only defines used/usable by all network code. * --gustav * ************************************************************/ #ifndef VMWARE_DEVICES_NET_H #define VMWARE_DEVICES_NET_H #define INCLUDE_ALLOW_USERLEVEL #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMMEXT #include "includeCheck.h" #include "vm_device_version.h" #define ETHERNET_MTU 1518 #define ETH_MIN_FRAME_LEN 60 #ifndef ETHER_ADDR_LEN #define ETHER_ADDR_LEN 6 /* length of MAC address */ #endif #define ETH_HEADER_LEN 14 /* length of Ethernet header */ #define IP_ADDR_LEN 4 /* length of IPv4 address */ #define IP_HEADER_LEN 20 /* minimum length of IPv4 header */ #define ETHER_MAX_QUEUED_PACKET 1600 /* * State's that a NIC can be in currently we only use this * in VLance but if we implement/emulate new adapters that * we also want to be able to morph a new corresponding * state should be added. */ #define LANCE_CHIP 0x2934 #define VMXNET_CHIP 0x4392 /* * Size of reserved IO space needed by the LANCE adapter and * the VMXNET adapter. If you add more ports to Vmxnet than * there is reserved space you must bump VMXNET_CHIP_IO_RESV_SIZE. * The sizes must be powers of 2. */ #define LANCE_CHIP_IO_RESV_SIZE 0x20 #define VMXNET_CHIP_IO_RESV_SIZE 0x40 #define MORPH_PORT_SIZE 4 #ifdef USERLEVEL /* *---------------------------------------------------------------------------- * * Net_AddAddrToLADRF -- * * Given a MAC address, sets the corresponding bit in the LANCE style * Logical Address Filter 'ladrf'. * The caller should have initialized the ladrf to all 0's, as this * function only ORs on a bit in the array. * 'addr' is presumed to be ETHER_ADDR_LEN in size; * 'ladrf' is presumed to point to a 64-bit vector. * * Derived from a long history of derivations, originally inspired by * sample code from the AMD "Network Products: Ethernet Controllers 1998 * Data Book, Book 2", pages 1-53..1-55. * * Returns: * None. * * Side effects: * Updates 'ladrf'. * *---------------------------------------------------------------------------- */ static INLINE void Net_AddAddrToLadrf(const uint8 *addr, // IN: pointer to MAC address uint8 *ladrf) // IN/OUT: pointer to ladrf { #define CRC_POLYNOMIAL_BE 0x04c11db7UL /* Ethernet CRC, big endian */ uint16 hashcode; int32 crc = 0xffffffff; /* init CRC for each address */ int32 j; int32 bit; int32 byte; ASSERT(addr); ASSERT(ladrf); for (byte = 0; byte < ETHER_ADDR_LEN; byte++) { /* for each address byte */ /* process each address bit */ for (bit = *addr++, j = 0; j < 8; j++, bit >>= 1) { crc = (crc << 1) ^ ((((crc < 0 ? 1 : 0) ^ bit) & 0x01) ? CRC_POLYNOMIAL_BE : 0); } } hashcode = (crc & 1); /* hashcode is 6 LSb of CRC ... */ for (j = 0; j < 5; j++) { /* ... in reverse order. */ hashcode = (hashcode << 1) | ((crc>>=1) & 1); } ladrf[hashcode >> 3] |= 1 << (hashcode & 0x07); } #endif // USERLEVEL #endif // VMWARE_DEVICES_NET_H vmxnet-only/compat_ethtool.h0000444000000000000000000000330612025727017015251 0ustar rootroot/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef _COMPAT_ETHTOOL_H #define _COMPAT_ETHTOOL_H /* * ethtool is a userspace utility for getting and setting ethernet device * settings. Kernel support for it was first published in 2.4.0-test11, but * only in 2.4.15 were the ethtool_value struct and the ETHTOOL_GLINK ioctl * added to ethtool.h (together, because the ETHTOOL_GLINK ioctl expects a * single value response). * * Likewise, ioctls for getting and setting TSO were published in 2.4.22. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) # include # ifndef ETHTOOL_GLINK # define ETHTOOL_GLINK 0x0a typedef struct { __u32 cmd; __u32 data; } compat_ethtool_value; # else typedef struct ethtool_value compat_ethtool_value; # endif # ifndef ETHTOOL_GTSO # define ETHTOOL_GTSO 0x1E # define ETHTOOL_STSO 0x1F # endif #endif #endif /* _COMPAT_ETHTOOL_H */ vmxnet-only/compat_init.h0000444000000000000000000000235512025727017014541 0ustar rootroot/********************************************************* * Copyright (C) 1999 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * compat_init.h: Initialization compatibility wrappers. */ #ifndef __COMPAT_INIT_H__ #define __COMPAT_INIT_H__ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 2, 0) #include #endif #ifndef module_init #define module_init(x) int init_module(void) { return x(); } #endif #ifndef module_exit #define module_exit(x) void cleanup_module(void) { x(); } #endif #endif /* __COMPAT_INIT_H__ */ vmxnet-only/compat_interrupt.h0000444000000000000000000000357312025727017015635 0ustar rootroot/********************************************************* * Copyright (C) 2003 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_INTERRUPT_H__ # define __COMPAT_INTERRUPT_H__ #include #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 69) /* * We cannot just define irqreturn_t, as some 2.4.x kernels have * typedef void irqreturn_t; for "increasing" backward compatibility. */ typedef void compat_irqreturn_t; #define COMPAT_IRQ_NONE #define COMPAT_IRQ_HANDLED #define COMPAT_IRQ_RETVAL(x) #else typedef irqreturn_t compat_irqreturn_t; #define COMPAT_IRQ_NONE IRQ_NONE #define COMPAT_IRQ_HANDLED IRQ_HANDLED #define COMPAT_IRQ_RETVAL(x) IRQ_RETVAL(x) #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) #define COMPAT_IRQF_DISABLED SA_INTERRUPT #define COMPAT_IRQF_SHARED SA_SHIRQ #else #define COMPAT_IRQF_DISABLED IRQF_DISABLED #define COMPAT_IRQF_SHARED IRQF_SHARED #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) #define COMPAT_IRQ_HANDLER_ARGS(irq, devp) (int irq, void *devp, struct pt_regs *regs) #else #define COMPAT_IRQ_HANDLER_ARGS(irq, devp) (int irq, void *devp) #endif #endif /* __COMPAT_INTERRUPT_H__ */ vmxnet-only/compat_module.h0000444000000000000000000000437212025727017015064 0ustar rootroot/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * compat_module.h -- */ #ifndef __COMPAT_MODULE_H__ # define __COMPAT_MODULE_H__ #include /* * Modules wishing to use the GPL license are required to include a * MODULE_LICENSE definition in their module source as of 2.4.10. */ #ifndef MODULE_LICENSE #define MODULE_LICENSE(license) #endif /* * To make use of our own home-brewed MODULE_INFO, we need macros to * concatenate two expressions to "__mod_", and and to convert an * expression into a string. I'm sure we've got these in our codebase, * but I'd rather not introduce such a dependency in a compat header. */ #ifndef __module_cat #define __module_cat_1(a, b) __mod_ ## a ## b #define __module_cat(a, b) __module_cat_1(a, b) #endif #ifndef __stringify #define __stringify_1(x) #x #define __stringify(x) __stringify_1(x) #endif /* * MODULE_INFO was born in 2.5.69. */ #ifndef MODULE_INFO #define MODULE_INFO(tag, info) \ static const char __module_cat(tag, __LINE__)[] \ __attribute__((section(".modinfo"), unused)) = __stringify(tag) "=" info #endif /* * MODULE_VERSION was born in 2.6.4. The earlier form appends a long "\0xxx" * string to the module's version, but that was removed in 2.6.10, so we'll * ignore it in our wrapper. */ #ifndef MODULE_VERSION #define MODULE_VERSION(_version) MODULE_INFO(version, _version) #endif #endif /* __COMPAT_MODULE_H__ */ vmxnet-only/compat_netdevice.h0000444000000000000000000001767112025727017015553 0ustar rootroot/********************************************************* * Copyright (C) 2002 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_NETDEVICE_H__ # define __COMPAT_NETDEVICE_H__ #include #include #include #include /* * The enet_statistics structure moved from linux/if_ether.h to * linux/netdevice.h and is renamed net_device_stats in 2.1.25 --hpreg */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 1, 25) # include # define net_device_stats enet_statistics #endif /* The netif_rx_ni() API appeared in 2.4.8 --hpreg */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 8) # define netif_rx_ni netif_rx #endif /* The device struct was renamed net_device in 2.3.14 --hpreg */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 14) # define net_device device #endif /* * SET_MODULE_OWNER appeared sometime during 2.3.x. It was setting * dev->owner = THIS_MODULE until 2.5.70, where netdevice refcounting * was completely changed. SET_MODULE_OWNER was nop for whole * 2.6.x series, and finally disappeared in 2.6.24. * * MOD_xxx_USE_COUNT wrappers are here, as they must be mutually * exclusive with SET_MODULE_OWNER call. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) # define COMPAT_SET_MODULE_OWNER(dev) do {} while (0) # define COMPAT_NETDEV_MOD_INC_USE_COUNT MOD_INC_USE_COUNT # define COMPAT_NETDEV_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT #else # if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) # define COMPAT_SET_MODULE_OWNER(dev) SET_MODULE_OWNER(dev) # else # define COMPAT_SET_MODULE_OWNER(dev) do {} while (0) # endif # define COMPAT_NETDEV_MOD_INC_USE_COUNT do {} while (0) # define COMPAT_NETDEV_MOD_DEC_USE_COUNT do {} while (0) #endif /* * SET_NETDEV_DEV appeared sometime during 2.5.x, and later was * crossported to various 2.4.x kernels (as dummy macro). */ #ifdef SET_NETDEV_DEV # define COMPAT_SET_NETDEV_DEV(dev, pdev) SET_NETDEV_DEV(dev, pdev) #else # define COMPAT_SET_NETDEV_DEV(dev, pdev) do {} while (0) #endif /* * Build alloc_etherdev API on the top of init_etherdev. For 2.0.x kernels * we must provide dummy init method, otherwise register_netdev does * nothing. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 3) #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 0) int vmware_dummy_init(struct net_device *dev) { return 0; } #endif static inline struct net_device* compat_alloc_etherdev(int priv_size) { struct net_device* dev; int size = sizeof *dev + priv_size; /* * The name is dynamically allocated before 2.4.0, but * is an embedded array in later kernels. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) size += sizeof("ethXXXXXXX"); #endif dev = kmalloc(size, GFP_KERNEL); if (dev) { memset(dev, 0, size); if (priv_size) { dev->priv = dev + 1; } #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) dev->name = (char *)(dev + 1) + priv_size; #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 0) dev->init = vmware_dummy_init; #endif if (init_etherdev(dev, 0) != dev) { kfree(dev); dev = NULL; } } return dev; } #else #define compat_alloc_etherdev(sz) alloc_etherdev(sz) #endif /* * alloc_netdev and free_netdev are there since 2.4.23. Their use is mandatory * since 2.6.24. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 23) static inline struct net_device * compat_alloc_netdev(int priv_size, const char *mask, void (*setup)(struct net_device *)) { struct net_device *dev; int netdev_size = sizeof *dev; int alloc_size; # if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) netdev_size += IFNAMSIZ; # endif alloc_size = netdev_size + priv_size; dev = kmalloc(alloc_size, GFP_KERNEL); if (dev) { memset(dev, 0, alloc_size); dev->priv = (char*)dev + netdev_size; setup(dev); # if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) dev->name = (char*)(dev + 1); # endif strcpy(dev->name, mask); } return dev; } # define compat_free_netdev(dev) kfree(dev) #else # define compat_alloc_netdev(size, mask, setup) alloc_netdev(size, mask, setup) # define compat_free_netdev(dev) free_netdev(dev) #endif /* netdev_priv() appeared in 2.6.3 */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 3) # define compat_netdev_priv(netdev) (netdev)->priv #else # define compat_netdev_priv(netdev) netdev_priv(netdev) #endif #if defined(NETDEV_TX_OK) # define COMPAT_NETDEV_TX_OK NETDEV_TX_OK # define COMPAT_NETDEV_TX_BUSY NETDEV_TX_BUSY #else # define COMPAT_NETDEV_TX_OK 0 # define COMPAT_NETDEV_TX_BUSY 1 #endif #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43)) static inline void compat_netif_start_queue(struct device *dev) { clear_bit(0, &dev->tbusy); } static inline void compat_netif_stop_queue(struct device *dev) { set_bit(0, &dev->tbusy); } static inline int compat_netif_queue_stopped(struct device *dev) { return test_bit(0, &dev->tbusy); } static inline void compat_netif_wake_queue(struct device *dev) { clear_bit(0, &dev->tbusy); mark_bh(NET_BH); } static inline int compat_netif_running(struct device *dev) { return dev->start == 0; } static inline int compat_netif_carrier_ok(struct device *dev) { return 1; } static inline void compat_netif_carrier_on(struct device *dev) { } static inline void compat_netif_carrier_off(struct device *dev) { } #else #define compat_netif_start_queue(dev) netif_start_queue(dev) #define compat_netif_stop_queue(dev) netif_stop_queue(dev) #define compat_netif_queue_stopped(dev) netif_queue_stopped(dev) #define compat_netif_wake_queue(dev) netif_wake_queue(dev) #define compat_netif_running(dev) netif_running(dev) #define compat_netif_carrier_ok(dev) netif_carrier_ok(dev) #define compat_netif_carrier_on(dev) netif_carrier_on(dev) #define compat_netif_carrier_off(dev) netif_carrier_off(dev) #endif /* unregister_netdevice_notifier was not safe prior to 2.6.17 */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 17) && \ !defined(ATOMIC_NOTIFIER_INIT) /* pre 2.6.17 and not patched */ static inline int compat_unregister_netdevice_notifier(struct notifier_block *nb) { int err; rtnl_lock(); err = unregister_netdevice_notifier(nb); rtnl_unlock(); return err; } #else /* post 2.6.17 or patched */ #define compat_unregister_netdevice_notifier(_nb) \ unregister_netdevice_notifier(_nb); #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) #define compat_netif_napi_add(dev, napi, poll, quota) \ netif_napi_add(dev, napi, poll, quota) #define compat_netif_rx_schedule(dev, napi) netif_rx_schedule(dev, napi) #define compat_napi_enable(dev, napi) napi_enable(napi) #define compat_napi_disable(dev, napi) napi_disable(napi) #else struct napi_struct { int dummy; }; #define compat_netif_napi_add(dev, napi, pollcb, quota) \ do { \ (dev)->poll = (pollcb); \ (dev)->weight = (quota);\ } while (0) #define compat_netif_rx_schedule(dev, napi) netif_rx_schedule(dev) #define compat_napi_enable(dev, napi) netif_poll_enable(dev) #define compat_napi_disable(dev, napi) netif_poll_disable(dev) #endif #endif /* __COMPAT_NETDEVICE_H__ */ vmxnet-only/compat_ioport.h0000444000000000000000000000404112025727017015104 0ustar rootroot/********************************************************* * Copyright (C) 2003 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_IOPORT_H__ # define __COMPAT_IOPORT_H__ #include #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) static inline void * compat_request_region(unsigned long start, unsigned long len, const char *name) { if (check_region(start, len)) { return NULL; } request_region(start, len, name); return (void*)1; } #else #define compat_request_region(start, len, name) request_region(start, len, name) #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 7) /* mmap io support starts from 2.3.7, fail the call for kernel prior to that */ static inline void * compat_request_mem_region(unsigned long start, unsigned long len, const char *name) { return NULL; } static inline void compat_release_mem_region(unsigned long start, unsigned long len) { return; } #else #define compat_request_mem_region(start, len, name) request_mem_region(start, len, name) #define compat_release_mem_region(start, len) release_mem_region(start, len) #endif /* these two macro defs are needed by compat_pci_request_region */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 15) # define IORESOURCE_IO 0x00000100 # define IORESOURCE_MEM 0x00000200 #endif #endif /* __COMPAT_IOPORT_H__ */ vmxnet-only/compat_pci.h0000444000000000000000000004157512025727017014360 0ustar rootroot/********************************************************* * Copyright (C) 1999 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * compat_pci.h: PCI compatibility wrappers. */ #ifndef __COMPAT_PCI_H__ #define __COMPAT_PCI_H__ #include "compat_ioport.h" #include #ifndef KERNEL_2_1 # include #endif /* 2.0.x has useless struct pci_dev; remap it to our own */ #ifndef KERNEL_2_1 #define pci_dev vmw_pci_driver_instance #endif /* 2.0/2.2 does not have pci driver API */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) struct vmw_pci_driver_instance { struct vmw_pci_driver_instance *next; void *driver_data; struct pci_driver *pcidrv; #ifdef KERNEL_2_1 struct pci_dev *pcidev; #else unsigned char bus; unsigned char devfn; unsigned int irq; #endif }; #endif /* 2.0 has pcibios_* calls only... We have to provide pci_* compatible wrappers. */ #ifndef KERNEL_2_1 static inline int pci_read_config_byte(struct pci_dev *pdev, // IN: PCI slot unsigned char where, // IN: Byte to read u8 *value) // OUT: Value read { return pcibios_read_config_byte(pdev->bus, pdev->devfn, where, value); } static inline int pci_read_config_dword(struct pci_dev *pdev, // IN: PCI slot unsigned char where, // IN: Dword to read u32 *value) // OUT: Value read { return pcibios_read_config_dword(pdev->bus, pdev->devfn, where, value); } static inline int pci_write_config_dword(struct pci_dev *pdev, // IN: PCI slot unsigned char where, // IN: Dword to write u32 value) // IN: Value to write { return pcibios_write_config_dword(pdev->bus, pdev->devfn, where, value); } #endif /* *----------------------------------------------------------------------------- * * compat_pci_name -- * * Return human readable PCI slot name. Note that some implementations * return a pointer to the static storage, so returned value may be * overwritten by subsequent calls to this function. * * Results: * Returns pointer to the string with slot name. * * Side effects: * None. * *----------------------------------------------------------------------------- */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 22) #define compat_pci_name(pdev) pci_name(pdev) #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) #define compat_pci_name(pdev) (pdev)->slot_name #elif defined(KERNEL_2_1) static inline const char* compat_pci_name(struct pci_dev* pdev) { static char slot_name[12]; sprintf(slot_name, "%02X:%02X.%X", pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); return slot_name; } #else static inline const char* compat_pci_name(struct pci_dev* pdev) { static char slot_name[12]; sprintf(slot_name, "%02X:%02X.%X", pdev->bus, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); return slot_name; } #endif /* pci_resource_start comes in 4 flavors - 2.0, 2.2, early 2.3, 2.4+ */ #ifndef KERNEL_2_1 static inline unsigned long compat_pci_resource_start(struct pci_dev *pdev, unsigned int index) { u32 addr; if (pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0 + index * 4, &addr)) { printk(KERN_ERR "Unable to read base address %u from PCI slot %s!\n", index, compat_pci_name(pdev)); return ~0UL; } if (addr & PCI_BASE_ADDRESS_SPACE) { return addr & PCI_BASE_ADDRESS_IO_MASK; } else { return addr & PCI_BASE_ADDRESS_MEM_MASK; } } #elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 1) # define compat_pci_resource_start(dev, index) \ (((dev)->base_address[index] & PCI_BASE_ADDRESS_SPACE) \ ? ((dev)->base_address[index] & PCI_BASE_ADDRESS_IO_MASK) \ : ((dev)->base_address[index] & PCI_BASE_ADDRESS_MEM_MASK)) #elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 43) # define compat_pci_resource_start(dev, index) \ ((dev)->resource[index].start) #else # define compat_pci_resource_start(dev, index) \ pci_resource_start(dev, index) #endif /* since 2.3.15, a new set of s/w res flags IORESOURCE_ is introduced, * we fake them by returning either IORESOURCE_{IO, MEM} prior to 2.3.15 since * this is what compat_pci_request_region uses */ #ifndef KERNEL_2_1 static inline unsigned long compat_pci_resource_flags(struct pci_dev *pdev, unsigned int index) { u32 addr; if (pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0 + index * 4, &addr)) { printk(KERN_ERR "Unable to read base address %u from PCI slot %s!\n", index, compat_pci_name(pdev)); return ~0UL; } if (addr & PCI_BASE_ADDRESS_SPACE) { return IORESOURCE_IO; } else { return IORESOURCE_MEM; } } #elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 1) # define compat_pci_resource_flags(dev, index) \ (((dev)->base_address[index] & PCI_BASE_ADDRESS_SPACE) \ ? IORESOURCE_IO: IORESOURCE_MEM) #elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 15) /* IORESOURCE_xxx appeared in 2.3.15 and is set in resource[].flags */ # define compat_pci_resource_flags(dev, index) ((dev)->resource[index].flags) #else # define compat_pci_resource_flags(dev, index) pci_resource_flags(dev, index) #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18) static inline unsigned long compat_pci_resource_len(struct pci_dev *pdev, // IN unsigned int index) // IN { u32 addr, mask; unsigned char reg = PCI_BASE_ADDRESS_0 + index * 4; if (pci_read_config_dword(pdev, reg, &addr) || addr == 0xFFFFFFFF) { return 0; } pci_write_config_dword(pdev, reg, 0xFFFFFFFF); pci_read_config_dword(pdev, reg, &mask); pci_write_config_dword(pdev, reg, addr); if (mask == 0 || mask == 0xFFFFFFFF) { return 0; } if (addr & PCI_BASE_ADDRESS_SPACE) { return 65536 - (mask & PCI_BASE_ADDRESS_IO_MASK & 0xFFFF); } else { return -(mask & PCI_BASE_ADDRESS_MEM_MASK); } } #else #define compat_pci_resource_len(dev, index) pci_resource_len(dev, index) #endif /* pci_request_region appears in 2.4.20 */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 20) static inline int compat_pci_request_region(struct pci_dev *pdev, int bar, char *name) { if (compat_pci_resource_len(pdev, bar) == 0) { return 0; } if (compat_pci_resource_flags(pdev, bar) & IORESOURCE_IO) { if (!compat_request_region(compat_pci_resource_start(pdev, bar), compat_pci_resource_len(pdev, bar), name)) { return -EBUSY; } } else if (compat_pci_resource_flags(pdev, bar) & IORESOURCE_MEM) { if (!compat_request_mem_region(compat_pci_resource_start(pdev, bar), compat_pci_resource_len(pdev, bar), name)) { return -EBUSY; } } return 0; } static inline void compat_pci_release_region(struct pci_dev *pdev, int bar) { if (compat_pci_resource_len(pdev, bar) != 0) { if (compat_pci_resource_flags(pdev, bar) & IORESOURCE_IO) { release_region(compat_pci_resource_start(pdev, bar), compat_pci_resource_len(pdev, bar)); } else if (compat_pci_resource_flags(pdev, bar) & IORESOURCE_MEM) { compat_release_mem_region(compat_pci_resource_start(pdev, bar), compat_pci_resource_len(pdev, bar)); } } } #else #define compat_pci_request_region(pdev, bar, name) pci_request_region(pdev, bar, name) #define compat_pci_release_region(pdev, bar) pci_release_region(pdev, bar) #endif /* pci_request_regions appeears in 2.4.3 */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 3) static inline int compat_pci_request_regions(struct pci_dev *pdev, char *name) { int i; for (i = 0; i < 6; i++) { if (compat_pci_request_region(pdev, i, name)) { goto release; } } return 0; release: while (--i >= 0) { compat_pci_release_region(pdev, i); } return -EBUSY; } static inline void compat_pci_release_regions(struct pci_dev *pdev) { int i; for (i = 0; i < 6; i++) { compat_pci_release_region(pdev, i); } } #else #define compat_pci_request_regions(pdev, name) pci_request_regions(pdev, name) #define compat_pci_release_regions(pdev) pci_release_regions(pdev) #endif /* pci_enable_device is available since 2.4.0 */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) #define compat_pci_enable_device(pdev) (0) #else #define compat_pci_enable_device(pdev) pci_enable_device(pdev) #endif /* pci_set_master is available since 2.2.0 */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 0) #define compat_pci_set_master(pdev) (0) #else #define compat_pci_set_master(pdev) pci_set_master(pdev) #endif /* pci_disable_device is available since 2.4.4 */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 4) #define compat_pci_disable_device(pdev) do {} while (0) #else #define compat_pci_disable_device(pdev) pci_disable_device(pdev) #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) /* * Devices supported by particular pci driver. While 2.4+ kernels * can do match on subsystem and class too, we support match on * vendor/device IDs only. */ struct pci_device_id { unsigned int vendor, device; unsigned long driver_data; }; #define PCI_DEVICE(vend, dev) .vendor = (vend), .device = (dev) /* PCI driver */ struct pci_driver { const char *name; const struct pci_device_id *id_table; int (*probe)(struct pci_dev* dev, const struct pci_device_id* id); void (*remove)(struct pci_dev* dev); }; /* * Note that this is static variable. Maybe everything below should be in * separate compat_pci.c file, but currently only user of this file is vmxnet, * and vmxnet has only one file, so it is fine. Also with vmxnet all * functions below are called just once, so difference between 'inline' and * separate compat_pci.c should be very small. */ static struct vmw_pci_driver_instance *pci_driver_instances = NULL; #ifdef KERNEL_2_1 #define vmw_pci_device(instance) (instance)->pcidev #else #define vmw_pci_device(instance) (instance) #endif /* *----------------------------------------------------------------------------- * * pci_register_driver -- * * Create driver instances for all matching PCI devices in the box. * * Results: * Returns 0 for success, negative error value for failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static inline int pci_register_driver(struct pci_driver *drv) { const struct pci_device_id *chipID; for (chipID = drv->id_table; chipID->vendor; chipID++) { #ifdef KERNEL_2_1 struct pci_dev *pdev; for (pdev = NULL; (pdev = pci_find_device(chipID->vendor, chipID->device, pdev)) != NULL; ) { #else int adapter; unsigned char bus, devfn, irq; for (adapter = 0; pcibios_find_device(chipID->vendor, chipID->device, adapter, &bus, &devfn) == 0; adapter++) { #endif struct vmw_pci_driver_instance *pdi; int err; pdi = kmalloc(sizeof *pdi, GFP_KERNEL); if (!pdi) { printk(KERN_ERR "Not enough memory.\n"); break; } pdi->pcidrv = drv; #ifdef KERNEL_2_1 pdi->pcidev = pdev; #else pdi->bus = bus; pdi->devfn = devfn; if (pci_read_config_byte(pdi, PCI_INTERRUPT_LINE, &irq)) { pdi->irq = -1; } else { pdi->irq = irq; } #endif pdi->driver_data = NULL; pdi->next = pci_driver_instances; pci_driver_instances = pdi; err = drv->probe(vmw_pci_device(pdi), chipID); if (err) { pci_driver_instances = pdi->next; kfree(pdi); } } } return 0; } /* *----------------------------------------------------------------------------- * * compat_pci_unregister_driver -- * * Shut down PCI driver - unbind all device instances from driver. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static inline void pci_unregister_driver(struct pci_driver *drv) { struct vmw_pci_driver_instance **ppdi; ppdi = &pci_driver_instances; while (1) { struct vmw_pci_driver_instance *pdi = *ppdi; if (!pdi) { break; } if (pdi->pcidrv == drv) { drv->remove(vmw_pci_device(pdi)); *ppdi = pdi->next; kfree(pdi); } else { ppdi = &pdi->next; } } } #else /* provide PCI_DEVICE for early 2.4.x kernels */ #ifndef PCI_DEVICE #define PCI_DEVICE(vend, dev) .vendor = (vend), .device = (dev), \ .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID #endif #endif /* provide dummy MODULE_DEVICE_TABLE for 2.0/2.2 */ #ifndef MODULE_DEVICE_TABLE #define MODULE_DEVICE_TABLE(bus, devices) #endif /* *----------------------------------------------------------------------------- * * pci_set_drvdata -- * * Set per-device driver's private data. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ /* *----------------------------------------------------------------------------- * * pci_get_drvdata -- * * Retrieve per-device driver's private data. * * Results: * per-device driver's data previously set by pci_set_drvdata, * or NULL on failure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ #ifndef KERNEL_2_1 /* 2.0.x is simple, we have driver_data directly in pci_dev */ #define pci_set_drvdata(pdev, data) do { (pdev)->driver_data = (data); } while (0) #define pci_get_drvdata(pdev) (pdev)->driver_data #elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) /* 2.2.x is trickier, we have to find driver instance first */ static inline void pci_set_drvdata(struct pci_dev *pdev, void* data) { struct vmw_pci_driver_instance *pdi; for (pdi = pci_driver_instances; pdi; pdi = pdi->next) { if (pdi->pcidev == pdev) { pdi->driver_data = data; return; } } printk(KERN_ERR "pci_set_drvdata issued for unknown device %p\n", pdev); } static inline void * pci_get_drvdata(struct pci_dev *pdev) { struct vmw_pci_driver_instance *pdi; for (pdi = pci_driver_instances; pdi; pdi = pdi->next) { if (pdi->pcidev == pdev) { return pdi->driver_data; } } printk(KERN_ERR "pci_get_drvdata issued for unknown device %p\n", pdev); return NULL; } #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,48) # define PCI_DMA_BIDIRECTIONAL 0 # define PCI_DMA_TODEVICE 1 # define PCI_DMA_FROMDEVICE 2 # define PCI_DMA_NONE 3 #endif /* * Power Management related compat wrappers. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10) # define compat_pci_save_state(pdev) pci_save_state((pdev), NULL) # define compat_pci_restore_state(pdev) pci_restore_state((pdev), NULL) #else # define compat_pci_save_state(pdev) pci_save_state((pdev)) # define compat_pci_restore_state(pdev) pci_restore_state((pdev)) #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) # define pm_message_t u32 # define compat_pci_choose_state(pdev, state) (state) # define PCI_D0 0 # define PCI_D3hot 3 #else # define compat_pci_choose_state(pdev, state) pci_choose_state((pdev), (state)) #endif /* 2.6.14 changed the PCI shutdown callback */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) # define COMPAT_PCI_SHUTDOWN(func) .driver = { .shutdown = (func), } # define COMPAT_PCI_DECLARE_SHUTDOWN(func, var) (func)(struct device *(var)) # define COMPAT_PCI_TO_DEV(dev) (to_pci_dev(dev)) #else # define COMPAT_PCI_SHUTDOWN(func) .shutdown = (func) # define COMPAT_PCI_DECLARE_SHUTDOWN(func, var) (func)(struct pci_dev *(var)) # define COMPAT_PCI_TO_DEV(dev) (dev) #endif #endif /* __COMPAT_PCI_H__ */ vmxnet-only/compat_skbuff.h0000444000000000000000000001446512025727017015063 0ustar rootroot/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_SKBUFF_H__ # define __COMPAT_SKBUFF_H__ #include /* * When transition from mac/nh/h to skb_* accessors was made, also SKB_WITH_OVERHEAD * was introduced. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) || \ (LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 21) && defined(SKB_WITH_OVERHEAD)) #define compat_skb_mac_header(skb) skb_mac_header(skb) #define compat_skb_network_header(skb) skb_network_header(skb) #define compat_skb_network_offset(skb) skb_network_offset(skb) #define compat_skb_transport_header(skb) skb_transport_header(skb) #define compat_skb_transport_offset(skb) skb_transport_offset(skb) #define compat_skb_network_header_len(skb) skb_network_header_len(skb) #define compat_skb_tail_pointer(skb) skb_tail_pointer(skb) #define compat_skb_end_pointer(skb) skb_end_pointer(skb) #define compat_skb_ip_header(skb) ((struct iphdr *)skb_network_header(skb)) #define compat_skb_tcp_header(skb) ((struct tcphdr *)skb_transport_header(skb)) #define compat_skb_reset_mac_header(skb) skb_reset_mac_header(skb) #define compat_skb_set_network_header(skb, off) skb_set_network_header(skb, off) #define compat_skb_set_transport_header(skb, off) skb_set_transport_header(skb, off) #else #define compat_skb_mac_header(skb) (skb)->mac.raw #define compat_skb_network_header(skb) (skb)->nh.raw #define compat_skb_network_offset(skb) ((skb)->nh.raw - (skb)->data) #define compat_skb_transport_header(skb) (skb)->h.raw #define compat_skb_transport_offset(skb) ((skb)->h.raw - (skb)->data) #define compat_skb_network_header_len(skb) ((skb)->h.raw - (skb)->nh.raw) #define compat_skb_tail_pointer(skb) (skb)->tail #define compat_skb_end_pointer(skb) (skb)->end #define compat_skb_ip_header(skb) (skb)->nh.iph #define compat_skb_tcp_header(skb) (skb)->h.th #define compat_skb_reset_mac_header(skb) ((skb)->mac.raw = (skb)->data) #define compat_skb_set_network_header(skb, off) ((skb)->nh.raw = (skb)->data + (off)) #define compat_skb_set_transport_header(skb, off) ((skb)->h.raw = (skb)->data + (off)) #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) || defined(VMW_SKB_LINEARIZE_2618) # define compat_skb_linearize(skb) skb_linearize((skb)) #else # if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 0) # define compat_skb_linearize(skb) __skb_linearize((skb), GFP_ATOMIC) # elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 4) # define compat_skb_linearize(skb) skb_linearize((skb), GFP_ATOMIC) # else static inline int compat_skb_linearize(struct sk_buff *skb) { return 0; } # endif #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20) #define compat_skb_csum_offset(skb) (skb)->csum_offset #else #define compat_skb_csum_offset(skb) (skb)->csum #endif /* * Note that compat_skb_csum_start() has semantic different from kernel's csum_start: * kernel's skb->csum_start is offset between start of checksummed area and start of * complete skb buffer, while our compat_skb_csum_start(skb) is offset from start * of packet itself. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) #define compat_skb_csum_start(skb) ((skb)->csum_start - skb_headroom(skb)) #else #define compat_skb_csum_start(skb) compat_skb_transport_offset(skb) #endif #if defined(NETIF_F_GSO) /* 2.6.18 and upwards */ #define compat_skb_mss(skb) (skb_shinfo(skb)->gso_size) #else #define compat_skb_mss(skb) (skb_shinfo(skb)->tso_size) #endif /* used by both received pkts and outgoing ones */ #define VM_CHECKSUM_UNNECESSARY CHECKSUM_UNNECESSARY /* csum status of received pkts */ #if defined(CHECKSUM_COMPLETE) # define VM_RX_CHECKSUM_PARTIAL CHECKSUM_COMPLETE #elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) && defined(CHECKSUM_HW) # define VM_RX_CHECKSUM_PARTIAL CHECKSUM_HW #else # define VM_RX_CHECKSUM_PARTIAL CHECKSUM_PARTIAL #endif /* csum status of outgoing pkts */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) && defined(CHECKSUM_HW) # define VM_TX_CHECKSUM_PARTIAL CHECKSUM_HW #else # define VM_TX_CHECKSUM_PARTIAL CHECKSUM_PARTIAL #endif #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)) # define compat_kfree_skb(skb, type) kfree_skb(skb, type) # define compat_dev_kfree_skb(skb, type) dev_kfree_skb(skb, type) # define compat_dev_kfree_skb_any(skb, type) dev_kfree_skb(skb, type) # define compat_dev_kfree_skb_irq(skb, type) dev_kfree_skb(skb, type) #else # define compat_kfree_skb(skb, type) kfree_skb(skb) # define compat_dev_kfree_skb(skb, type) dev_kfree_skb(skb) # if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43)) # define compat_dev_kfree_skb_any(skb, type) dev_kfree_skb(skb) # define compat_dev_kfree_skb_irq(skb, type) dev_kfree_skb(skb) # else # define compat_dev_kfree_skb_any(skb, type) dev_kfree_skb_any(skb) # define compat_dev_kfree_skb_irq(skb, type) dev_kfree_skb_irq(skb) # endif #endif #ifndef NET_IP_ALIGN # define COMPAT_NET_IP_ALIGN 2 #else # define COMPAT_NET_IP_ALIGN NET_IP_ALIGN #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 4) # define compat_skb_headlen(skb) skb_headlen(skb) # define compat_pskb_may_pull(skb, len) pskb_may_pull(skb, len) #else # define compat_skb_headlen(skb) (skb)->len # define compat_pskb_may_pull(skb, len) 1 #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12) # define compat_skb_header_cloned(skb) skb_header_cloned(skb) #else # define compat_skb_header_cloned(skb) 0 #endif #endif /* __COMPAT_SKBUFF_H__ */ vmxnet-only/compat_slab.h0000444000000000000000000000665312025727017014524 0ustar rootroot/********************************************************* * Copyright (C) 2005 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_SLAB_H__ # define __COMPAT_SLAB_H__ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 2, 0) # include #else # include #endif /* * Before 2.6.20, kmem_cache_t was the accepted way to refer to a kmem_cache * structure. Prior to 2.6.15, this structure was called kmem_cache_s, and * afterwards it was renamed to kmem_cache. Here we keep things simple and use * the accepted typedef until it became deprecated, at which point we switch * over to the kmem_cache name. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20) # define compat_kmem_cache struct kmem_cache #else # define compat_kmem_cache kmem_cache_t #endif /* * Up to 2.6.22 kmem_cache_create has 6 arguments - name, size, alignment, flags, * constructor, and destructor. Then for some time kernel was asserting that * destructor is NULL, and since 2.6.23-pre1 kmem_cache_create takes only 5 * arguments - destructor is gone. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) || defined(VMW_KMEMCR_HAS_DTOR) #define compat_kmem_cache_create(name, size, align, flags, ctor) \ kmem_cache_create(name, size, align, flags, ctor, NULL) #else #define compat_kmem_cache_create(name, size, align, flags, ctor) \ kmem_cache_create(name, size, align, flags, ctor) #endif /* * Up to 2.6.23 kmem_cache constructor has three arguments - pointer to block to * prepare (aka "this"), from which cache it came, and some unused flags. After * 2.6.23 flags were removed, and order of "this" and cache parameters was swapped... * Since 2.6.27-rc2 everything is different again, and ctor has only one argument. * * HAS_3_ARGS has precedence over HAS_2_ARGS if both are defined. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) && !defined(VMW_KMEMCR_CTOR_HAS_3_ARGS) # define VMW_KMEMCR_CTOR_HAS_3_ARGS #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) && !defined(VMW_KMEMCR_CTOR_HAS_2_ARGS) # define VMW_KMEMCR_CTOR_HAS_2_ARGS #endif #if defined(VMW_KMEMCR_CTOR_HAS_3_ARGS) typedef void compat_kmem_cache_ctor(void *, compat_kmem_cache *, unsigned long); #define COMPAT_KMEM_CACHE_CTOR_ARGS(arg) void *arg, \ compat_kmem_cache *cache, \ unsigned long flags #elif defined(VMW_KMEMCR_CTOR_HAS_2_ARGS) typedef void compat_kmem_cache_ctor(compat_kmem_cache *, void *); #define COMPAT_KMEM_CACHE_CTOR_ARGS(arg) compat_kmem_cache *cache, \ void *arg #else typedef void compat_kmem_cache_ctor(void *); #define COMPAT_KMEM_CACHE_CTOR_ARGS(arg) void *arg #endif #endif /* __COMPAT_SLAB_H__ */ vmxnet-only/compat_spinlock.h0000444000000000000000000000460612025727017015421 0ustar rootroot/********************************************************* * Copyright (C) 2005 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_SPINLOCK_H__ # define __COMPAT_SPINLOCK_H__ /* * The spin_lock() API appeared in 2.1.25 in asm/smp_lock.h * It moved in 2.1.30 to asm/spinlock.h * It moved again in 2.3.18 to linux/spinlock.h * * --hpreg */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 18) # include #else # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 1, 30) # include # else typedef struct {} spinlock_t; # define spin_lock_init(lock) # define spin_lock(lock) # define spin_unlock(lock) # define spin_lock_irqsave(lock, flags) do { \ save_flags(flags); \ cli(); \ spin_lock(lock); \ } while (0) # define spin_unlock_irqrestore(lock, flags) do { \ spin_unlock(lock); \ restore_flags(flags); \ } while (0) # endif #endif /* * Preempt support was added during 2.5.x development cycle, and later * it was backported to 2.4.x. In 2.4.x backport these definitions * live in linux/spinlock.h, that's why we put them here (in 2.6.x they * are defined in linux/preempt.h which is included by linux/spinlock.h). */ #ifdef CONFIG_PREEMPT #define compat_preempt_disable() preempt_disable() #define compat_preempt_enable() preempt_enable() #else #define compat_preempt_disable() do { } while (0) #define compat_preempt_enable() do { } while (0) #endif #endif /* __COMPAT_SPINLOCK_H__ */ vmxnet-only/compat_timer.h0000444000000000000000000000607012025727017014714 0ustar rootroot/********************************************************* * Copyright (C) 2002 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_TIMER_H__ # define __COMPAT_TIMER_H__ /* * The del_timer_sync() API appeared in 2.3.43 * It became reliable in 2.4.0-test3 * * --hpreg */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) # define compat_del_timer_sync(timer) del_timer_sync(timer) #else # if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 43) /* 2.3.43 removed asm/softirq.h's reference to bh_base. */ # include # endif # include static inline int compat_del_timer_sync(struct timer_list *timer) // IN { int wasPending; start_bh_atomic(); wasPending = del_timer(timer); end_bh_atomic(); return wasPending; } #endif /* * The msleep_interruptible() API appeared in 2.6.9. * It is based on the msleep() API, which appeared in 2.4.29. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 9) # include # define compat_msleep_interruptible(msecs) msleep_interruptible(msecs) # define compat_msleep(msecs) msleep(msecs) #else # include /* * msecs_to_jiffies appeared in 2.6.7/2.4.29. For earlier kernels, * fall back to slow-case code (we don't use this operation * enough to need the performance). */ # if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 29) || \ (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0) && \ LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 7)) # define msecs_to_jiffies(msecs) (((msecs) * HZ + 999) / 1000) # endif /* * set_current_state appeared in 2.2.18. */ # if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18) # define set_current_state(a) do { current->state = (a); } while(0) # endif static inline void compat_msleep_interruptible(unsigned long msecs) // IN { set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(msecs_to_jiffies(msecs) + 1); } static inline void compat_msleep(unsigned long msecs) // IN { set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(msecs_to_jiffies(msecs) + 1); } #endif /* * There is init_timer_deferrable() since 2.6.22. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) # define compat_init_timer_deferrable(timer) init_timer_deferrable(timer) #else # define compat_init_timer_deferrable(timer) init_timer(timer) #endif #endif /* __COMPAT_TIMER_H__ */ vmxnet-only/compat_version.h0000444000000000000000000000616512025727017015266 0ustar rootroot/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_VERSION_H__ # define __COMPAT_VERSION_H__ #define INCLUDE_ALLOW_VMMON #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_VMNIXMOD #define INCLUDE_ALLOW_DISTRIBUTE #include "includeCheck.h" #ifndef __linux__ # error "linux-version.h" #endif #include /* Appeared in 2.1.90 --hpreg */ #ifndef KERNEL_VERSION # define KERNEL_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c)) #endif /* * Distinguish relevant classes of Linux kernels. * * The convention is that version X defines all * the KERNEL_Y symbols where Y <= X. * * XXX Do not add more definitions here. This way of doing things does not * scale, and we are going to phase it out soon --hpreg */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 1, 0) # define KERNEL_2_1 #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 2, 0) # define KERNEL_2_2 #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 1) # define KERNEL_2_3_1 #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 15) /* new networking */ # define KERNEL_2_3_15 #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 25) /* new procfs */ # define KERNEL_2_3_25 #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 29) /* even newer procfs */ # define KERNEL_2_3_29 #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 43) /* softnet changes */ # define KERNEL_2_3_43 #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 47) /* more softnet changes */ # define KERNEL_2_3_47 #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 99) /* name in netdevice struct is array and not pointer */ # define KERNEL_2_3_99 #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) /* New 'owner' member at the beginning of struct file_operations */ # define KERNEL_2_4_0 #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 8) /* New netif_rx_ni() --hpreg */ # define KERNEL_2_4_8 #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 22) /* New vmap() */ # define KERNEL_2_4_22 #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 2) /* New kdev_t, major()/minor() API --hpreg */ # define KERNEL_2_5_2 #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 5) /* New sk_alloc(), pte_offset_map()/pte_unmap() --hpreg */ # define KERNEL_2_5_5 #endif #endif /* __COMPAT_VERSION_H__ */ vmxnet-only/compat_highmem.h0000444000000000000000000000255712025727017015220 0ustar rootroot/********************************************************* * Copyright (C) 2002 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __COMPAT_HIGHMEM_H__ # define __COMPAT_HIGHMEM_H__ /* * BIGMEM (4 GB) support appeared in 2.3.16: kmap() API added * HIGHMEM (4 GB + 64 GB) support appeared in 2.3.23: kmap() API modified * In 2.3.27, kmap() API modified again * * --hpreg */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 27) # include #else /* For page_address --hpreg */ # include # define kmap(_page) (void*)page_address(_page) # define kunmap(_page) #endif #endif /* __COMPAT_HIGHMEM_H__ */ vmxnet-only/driver-config.h0000444000000000000000000000425012025727017014765 0ustar rootroot/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * Sets the proper defines from the Linux header files * * This file must be included before the inclusion of any kernel header file, * with the exception of linux/autoconf.h and linux/version.h --hpreg */ #ifndef __VMX_CONFIG_H__ #define __VMX_CONFIG_H__ #define INCLUDE_ALLOW_VMCORE #define INCLUDE_ALLOW_VMMON #define INCLUDE_ALLOW_MODULE #define INCLUDE_ALLOW_VMNIXMOD #include "includeCheck.h" #include #include "compat_version.h" /* * We rely on Kernel Module support. Check here. */ #ifndef CONFIG_MODULES # error "No Module support in this kernel. Please configure with CONFIG_MODULES" #endif /* * 2.2 kernels still use __SMP__ (derived from CONFIG_SMP * in the main Makefile), so we do it here. */ #ifdef CONFIG_SMP # define __SMP__ 1 #endif #if defined(CONFIG_MODVERSIONS) && defined(KERNEL_2_1) # if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,60) /* * MODVERSIONS might be already defined when using kernel's Makefiles. */ # ifndef MODVERSIONS # define MODVERSIONS # endif # include # endif #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) /* * Force the uintptr_t definition to come from linux/types.h instead of vm_basic_types.h. */ # include # define _STDINT_H 1 #endif #ifndef __KERNEL__ # define __KERNEL__ #endif #endif vmxnet-only/vmxnet.c0000444000000000000000000021300212025727017013540 0ustar rootroot/********************************************************* * Copyright (C) 1999 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmxnet.c: A virtual network driver for VMware. */ #include "driver-config.h" #include "compat_module.h" #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 9) #include #endif #include "compat_slab.h" #include "compat_spinlock.h" #include "compat_pci.h" #include "compat_init.h" #include #include #include #include "compat_ethtool.h" #include "compat_netdevice.h" #include "compat_skbuff.h" #include #include "compat_ioport.h" #ifndef KERNEL_2_1 #include #endif #include "compat_timer.h" #include "compat_interrupt.h" #include "vm_basic_types.h" #include "vmnet_def.h" #include "vmxnet_def.h" #include "vmxnet2_def.h" #include "vm_device_version.h" #include "vmxnetInt.h" #include "net.h" #include "vmxnet_version.h" static int vmxnet_debug = 1; #define VMXNET_WATCHDOG_TIMEOUT (5 * HZ) #if defined(CONFIG_NET_POLL_CONTROLLER) || defined(HAVE_POLL_CONTROLLER) #define VMW_HAVE_POLL_CONTROLLER #endif static int vmxnet_open(struct net_device *dev); static int vmxnet_start_tx(struct sk_buff *skb, struct net_device *dev); #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) static compat_irqreturn_t vmxnet_interrupt(int irq, void *dev_id, struct pt_regs * regs); #else static compat_irqreturn_t vmxnet_interrupt(int irq, void *dev_id); #endif #ifdef VMW_HAVE_POLL_CONTROLLER static void vmxnet_netpoll(struct net_device *dev); #endif static int vmxnet_close(struct net_device *dev); static void vmxnet_set_multicast_list(struct net_device *dev); static int vmxnet_set_mac_address(struct net_device *dev, void *addr); static struct net_device_stats *vmxnet_get_stats(struct net_device *dev); #ifdef HAVE_CHANGE_MTU static int vmxnet_change_mtu(struct net_device *dev, int new_mtu); #endif static int vmxnet_probe_device(struct pci_dev *pdev, const struct pci_device_id *id); static void vmxnet_remove_device(struct pci_dev *pdev); #ifdef MODULE static int debug = -1; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 9) module_param(debug, int, 0444); #else MODULE_PARM(debug, "i"); #endif #endif #ifdef VMXNET_DO_ZERO_COPY #undef VMXNET_DO_ZERO_COPY #endif #if defined(MAX_SKB_FRAGS) && ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,18) ) && ( LINUX_VERSION_CODE != KERNEL_VERSION(2, 6, 0) ) #define VMXNET_DO_ZERO_COPY #endif #ifdef VMXNET_DO_ZERO_COPY #include #include #include #include /* * Tx buffer size that we need for copying header * max header is: 14(ip) + 4(vlan) + ip (60) + tcp(60) = 138 * round it up to the power of 2 */ #define TX_PKT_HEADER_SIZE 256 /* Constants used for Zero Copy Tx */ #define ETHERNET_HEADER_SIZE 14 #define VLAN_TAG_LENGTH 4 #define ETH_FRAME_TYPE_LOCATION 12 #define ETH_TYPE_VLAN_TAG 0x0081 /* in NBO */ #define ETH_TYPE_IP 0x0008 /* in NBO */ #define PKT_OF_PROTO(skb, type) \ (*(uint16*)(skb->data + ETH_FRAME_TYPE_LOCATION) == (type) || \ (*(uint16*)(skb->data + ETH_FRAME_TYPE_LOCATION) == ETH_TYPE_VLAN_TAG && \ *(uint16*)(skb->data + ETH_FRAME_TYPE_LOCATION + VLAN_TAG_LENGTH) == (type))) #define PKT_OF_IPV4(skb) PKT_OF_PROTO(skb, ETH_TYPE_IP) #define VMXNET_GET_LO_ADDR(dma) ((uint32)(dma)) #define VMXNET_GET_HI_ADDR(dma) ((uint16)(((uint64)(dma)) >> 32)) #define VMXNET_GET_DMA_ADDR(sge) ((dma_addr_t)((((uint64)(sge).addrHi) << 32) | (sge).addrLow)) #define VMXNET_FILL_SG(sg, dma, size)\ do{\ (sg).addrLow = VMXNET_GET_LO_ADDR(dma);\ (sg).addrHi = VMXNET_GET_HI_ADDR(dma);\ (sg).length = size;\ } while (0) #if defined(NETIF_F_TSO) #define VMXNET_DO_TSO #if defined(NETIF_F_GSO) /* 2.6.18 and upwards */ #define VMXNET_SKB_MSS(skb) skb_shinfo(skb)->gso_size #else #define VMXNET_SKB_MSS(skb) skb_shinfo(skb)->tso_size #endif #endif #endif // VMXNET_DO_ZERO_COPY #ifdef VMXNET_DO_TSO static int disable_lro = 0; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 9) module_param(disable_lro, int, 0); #else MODULE_PARM(disable_lro, "i"); #endif #endif #ifdef VMXNET_DEBUG #define VMXNET_LOG(msg...) printk(KERN_ERR msg) #else #define VMXNET_LOG(msg...) #endif // VMXNET_DEBUG /* Data structure used when determining what hardware the driver supports. */ static const struct pci_device_id vmxnet_chips[] = { { PCI_DEVICE(PCI_VENDOR_ID_VMWARE, PCI_DEVICE_ID_VMWARE_NET), .driver_data = VMXNET_CHIP, }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE), .driver_data = LANCE_CHIP, }, { 0, }, }; static struct pci_driver vmxnet_driver = { .name = "vmxnet", .id_table = vmxnet_chips, .probe = vmxnet_probe_device, .remove = vmxnet_remove_device, }; #ifdef HAVE_CHANGE_MTU static int vmxnet_change_mtu(struct net_device *dev, int new_mtu) { struct Vmxnet_Private *lp = (struct Vmxnet_Private *)dev->priv; if (new_mtu < VMXNET_MIN_MTU || new_mtu > VMXNET_MAX_MTU) { return -EINVAL; } if (new_mtu > 1500 && !lp->jumboFrame) { return -EINVAL; } dev->mtu = new_mtu; return 0; } #endif #ifdef SET_ETHTOOL_OPS /* *---------------------------------------------------------------------------- * * vmxnet_get_settings -- * * Get device-specific settings. * * Results: * 0 on success, errno on failure. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int vmxnet_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) { ecmd->supported = SUPPORTED_1000baseT_Full | SUPPORTED_TP; ecmd->advertising = ADVERTISED_TP; ecmd->port = PORT_TP; ecmd->transceiver = XCVR_INTERNAL; if (netif_carrier_ok(dev)) { ecmd->speed = 1000; ecmd->duplex = DUPLEX_FULL; } else { ecmd->speed = -1; ecmd->duplex = -1; } return 0; } /* *---------------------------------------------------------------------------- * * vmxnet_get_drvinfo -- * * Ethtool callback to return driver information * * Results: * None. * * Side effects: * Updates *drvinfo * *---------------------------------------------------------------------------- */ static void vmxnet_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo) { struct Vmxnet_Private *lp = dev->priv; strncpy(drvinfo->driver, vmxnet_driver.name, sizeof(drvinfo->driver)); drvinfo->driver[sizeof(drvinfo->driver) - 1] = '\0'; strncpy(drvinfo->version, VMXNET_DRIVER_VERSION_STRING, sizeof(drvinfo->version)); drvinfo->driver[sizeof(drvinfo->version) - 1] = '\0'; strncpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version)); drvinfo->fw_version[sizeof(drvinfo->fw_version) - 1] = '\0'; strncpy(drvinfo->bus_info, compat_pci_name(lp->pdev), ETHTOOL_BUSINFO_LEN); } /* *---------------------------------------------------------------------------- * * vmxnet_set_tso -- * * Ethtool handler to set TSO. If the data is non-zero, TSO is * enabled. Othewrise, it is disabled. * * Results: * 0 if successful, error code otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ #ifdef VMXNET_DO_TSO static int vmxnet_set_tso(struct net_device *dev, u32 data) { if (data) { struct Vmxnet_Private *lp = (struct Vmxnet_Private *)dev->priv; if (!lp->tso) { return -EINVAL; } dev->features |= NETIF_F_TSO; } else { dev->features &= ~NETIF_F_TSO; } return 0; } #endif static struct ethtool_ops vmxnet_ethtool_ops = { .get_settings = vmxnet_get_settings, .get_drvinfo = vmxnet_get_drvinfo, .get_link = ethtool_op_get_link, .get_sg = ethtool_op_get_sg, .set_sg = ethtool_op_set_sg, #ifdef VMXNET_DO_TSO .get_tso = ethtool_op_get_tso, .set_tso = vmxnet_set_tso, #endif }; #else /* !defined(SET_ETHTOOL_OPS) */ /* *---------------------------------------------------------------------------- * * vmxnet_get_settings -- * * Ethtool handler to get device settings. * * Results: * 0 if successful, error code otherwise. Settings are copied to addr. * * Side effects: * None. * * *---------------------------------------------------------------------------- */ #ifdef ETHTOOL_GSET static int vmxnet_get_settings(struct net_device *dev, void *addr) { struct ethtool_cmd cmd; memset(&cmd, 0, sizeof(cmd)); cmd.speed = 1000; // 1 Gb cmd.duplex = 1; // full-duplex cmd.maxtxpkt = 1; // no tx coalescing cmd.maxrxpkt = 1; // no rx coalescing cmd.autoneg = 0; // no autoneg cmd.advertising = 0; // advertise nothing return copy_to_user(addr, &cmd, sizeof(cmd)); } #endif /* *---------------------------------------------------------------------------- * * vmxnet_get_link -- * * Ethtool handler to get the link state. * * Results: * 0 if successful, error code otherwise. The link status is copied to * addr. * * Side effects: * None. * *---------------------------------------------------------------------------- */ #ifdef ETHTOOL_GLINK static int vmxnet_get_link(struct net_device *dev, void *addr) { compat_ethtool_value value = {ETHTOOL_GLINK}; value.data = netif_carrier_ok(dev) ? 1 : 0; return copy_to_user(addr, &value, sizeof(value)); } #endif /* *---------------------------------------------------------------------------- * * vmxnet_get_tso -- * * Ethtool handler to get the TSO setting. * * Results: * 0 if successful, error code otherwise. The TSO setting is copied to * addr. * * Side effects: * None. * *---------------------------------------------------------------------------- */ #ifdef VMXNET_DO_TSO static int vmxnet_get_tso(struct net_device *dev, void *addr) { compat_ethtool_value value = { ETHTOOL_GTSO }; value.data = (dev->features & NETIF_F_TSO) ? 1 : 0; if (copy_to_user(addr, &value, sizeof(value))) { return -EFAULT; } return 0; } #endif /* *---------------------------------------------------------------------------- * * vmxnet_set_tso -- * * Ethtool handler to set TSO. If the data in addr is non-zero, TSO is * enabled. Othewrise, it is disabled. * * Results: * 0 if successful, error code otherwise. * * Side effects: * None. * *---------------------------------------------------------------------------- */ #ifdef VMXNET_DO_TSO static int vmxnet_set_tso(struct net_device *dev, void *addr) { compat_ethtool_value value; if (copy_from_user(&value, addr, sizeof(value))) { return -EFAULT; } if (value.data) { struct Vmxnet_Private *lp = (struct Vmxnet_Private *)dev->priv; if (!lp->tso) { return -EINVAL; } dev->features |= NETIF_F_TSO; } else { dev->features &= ~NETIF_F_TSO; } return 0; } #endif /* *---------------------------------------------------------------------------- * * vmxnet_ethtool_ioctl -- * * Handler for ethtool ioctl calls. * * Results: * If ethtool op is supported, the outcome of the op. Otherwise, * -EOPNOTSUPP. * * Side effects: * * *---------------------------------------------------------------------------- */ #ifdef SIOCETHTOOL static int vmxnet_ethtool_ioctl(struct net_device *dev, struct ifreq *ifr) { uint32_t cmd; if (copy_from_user(&cmd, ifr->ifr_data, sizeof(cmd))) { return -EFAULT; } switch (cmd) { #ifdef ETHTOOL_GSET case ETHTOOL_GSET: return vmxnet_get_settings(dev, ifr->ifr_data); #endif #ifdef ETHTOOL_GLINK case ETHTOOL_GLINK: return vmxnet_get_link(dev, ifr->ifr_data); #endif #ifdef VMXNET_DO_TSO case ETHTOOL_GTSO: return vmxnet_get_tso(dev, ifr->ifr_data); case ETHTOOL_STSO: return vmxnet_set_tso(dev, ifr->ifr_data); #endif default: printk(KERN_DEBUG" ethtool operation %d not supported\n", cmd); return -EOPNOTSUPP; } } #endif /* *---------------------------------------------------------------------------- * * vmxnet_ioctl -- * * Handler for ioctl calls. * * Results: * If ioctl is supported, the result of that operation. Otherwise, * -EOPNOTSUPP. * * Side effects: * None. * *---------------------------------------------------------------------------- */ static int vmxnet_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { switch (cmd) { #ifdef SIOCETHTOOL case SIOCETHTOOL: return vmxnet_ethtool_ioctl(dev, ifr); #endif } printk(KERN_DEBUG" ioctl operation %d not supported\n", cmd); return -EOPNOTSUPP; } #endif /* SET_ETHTOOL_OPS */ /* *----------------------------------------------------------------------------- * * vmxnet_init -- * * Initialization, called by Linux when the module is loaded. * * Results: * Returns 0 for success, negative errno value otherwise. * * Side effects: * See vmxnet_probe_device, which does all the work. * *----------------------------------------------------------------------------- */ static int vmxnet_init(void) { int err; if (vmxnet_debug > 0) { vmxnet_debug = debug; } printk(KERN_INFO "VMware vmxnet virtual NIC driver\n"); err = pci_register_driver(&vmxnet_driver); if (err < 0) { return err; } return 0; } /* *----------------------------------------------------------------------------- * * vmxnet_exit -- * * Cleanup, called by Linux when the module is unloaded. * * Results: * None. * * Side effects: * Unregisters all vmxnet devices with Linux and frees memory. * *----------------------------------------------------------------------------- */ static void vmxnet_exit(void) { pci_unregister_driver(&vmxnet_driver); } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,43) /* *----------------------------------------------------------------------------- * * vmxnet_tx_timeout -- * * Network device tx_timeout routine. Called by Linux when the tx * queue has been stopped for more than dev->watchdog_timeo jiffies. * * Results: * None. * * Side effects: * Tries to restart the transmit queue. * *----------------------------------------------------------------------------- */ static void vmxnet_tx_timeout(struct net_device *dev) { compat_netif_wake_queue(dev); } #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,43) */ /* *----------------------------------------------------------------------------- * * vmxnet_link_check -- * * Propagate device link status to netdev. * * Results: * None. * * Side effects: * Rearms timer for next check. * *----------------------------------------------------------------------------- */ static void vmxnet_link_check(unsigned long data) // IN: netdevice pointer { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,43) struct net_device *dev = (struct net_device *)data; struct Vmxnet_Private *lp; uint32 status; int ok; lp = dev->priv; status = inl(dev->base_addr + VMXNET_STATUS_ADDR); ok = (status & VMXNET_STATUS_CONNECTED) != 0; if (ok != netif_carrier_ok(dev)) { if (ok) { netif_carrier_on(dev); } else { netif_carrier_off(dev); } } /* * It would be great if vmxnet2 could generate interrupt when link * state changes. Maybe next time. Let's just poll media every * two seconds (2 seconds is same interval pcnet32 uses). */ mod_timer(&lp->linkCheckTimer, jiffies + 2 * HZ); #else /* * Nothing to do on kernels before 2.3.43. They do not have * netif_carrier_*, and as we've lived without link state for * years, let's live without it forever on these kernels. */ #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,43) */ } /* *----------------------------------------------------------------------------- * * vmxnet_probe_device -- * * Most of the initialization at module load time is done here. * * Results: * Returns 0 for success, an error otherwise. * * Side effects: * Switches device from vlance to vmxnet mode, creates ethernet * structure for device, and registers device with network stack. * *----------------------------------------------------------------------------- */ static int vmxnet_probe_device(struct pci_dev *pdev, // IN: vmxnet PCI device const struct pci_device_id *id) // IN: matching device ID { struct Vmxnet_Private *lp; struct net_device *dev; unsigned int ioaddr, reqIOAddr, reqIOSize; unsigned int irq_line; /* VMware's version of the magic number */ unsigned int low_vmware_version; unsigned int numRxBuffers, numRxBuffers2, maxNumRxBuffers, defNumRxBuffers; unsigned int numTxBuffers, maxNumTxBuffers, defNumTxBuffers; Bool morphed = FALSE; Bool enhanced = FALSE; int i; unsigned int driverDataSize; i = compat_pci_enable_device(pdev); if (i) { printk(KERN_ERR "Cannot enable vmxnet adapter %s: error %d\n", compat_pci_name(pdev), i); return i; } compat_pci_set_master(pdev); irq_line = pdev->irq; ioaddr = compat_pci_resource_start(pdev, 0); reqIOAddr = ioaddr; /* Found adapter, adjust ioaddr to match the adapter we found. */ if (id->driver_data == VMXNET_CHIP) { reqIOSize = VMXNET_CHIP_IO_RESV_SIZE; } else { /* * Since this is a vlance adapter we can only use it if * its I/0 space is big enough for the adapter to be * capable of morphing. This is the first requirement * for this adapter to potentially be morphable. The * layout of a morphable LANCE adapter is * * I/O space: * * |------------------| * | LANCE IO PORTS | * |------------------| * | MORPH PORT | * |------------------| * | VMXNET IO PORTS | * |------------------| * * VLance has 8 ports of size 4 bytes, the morph port is 4 bytes, and * Vmxnet has 10 ports of size 4 bytes. * * We shift up the ioaddr with the size of the LANCE I/O space since * we want to access the vmxnet ports. We also shift the ioaddr up by * the MORPH_PORT_SIZE so other port access can be independent of * whether we are Vmxnet or a morphed VLance. This means that when * we want to access the MORPH port we need to subtract the size * from ioaddr to get to it. */ ioaddr += LANCE_CHIP_IO_RESV_SIZE + MORPH_PORT_SIZE; reqIOSize = LANCE_CHIP_IO_RESV_SIZE + MORPH_PORT_SIZE + VMXNET_CHIP_IO_RESV_SIZE; } /* Do not attempt to morph non-morphable AMD PCnet */ if (reqIOSize > compat_pci_resource_len(pdev, 0)) { printk(KERN_INFO "vmxnet: Device in slot %s is not supported by this driver.\n", compat_pci_name(pdev)); goto pci_disable; } /* * Request I/O region with adjusted base address and size. The adjusted * values are needed and used if we release the region in case of failure. */ if (!compat_request_region(reqIOAddr, reqIOSize, VMXNET_CHIP_NAME)) { printk(KERN_INFO "vmxnet: Another driver already loaded for device in slot %s.\n", compat_pci_name(pdev)); goto pci_disable; } /* Morph the underlying hardware if we found a VLance adapter. */ if (id->driver_data == LANCE_CHIP) { uint16 magic; /* Read morph port to verify that we can morph the adapter. */ magic = inw(ioaddr - MORPH_PORT_SIZE); if (magic != LANCE_CHIP && magic != VMXNET_CHIP) { printk(KERN_ERR "Invalid magic, read: 0x%08X\n", magic); goto release_reg; } /* Morph adapter. */ outw(VMXNET_CHIP, ioaddr - MORPH_PORT_SIZE); morphed = TRUE; /* Verify that we morphed correctly. */ magic = inw(ioaddr - MORPH_PORT_SIZE); if (magic != VMXNET_CHIP) { printk(KERN_ERR "Couldn't morph adapter. Invalid magic, read: 0x%08X\n", magic); goto morph_back; } } printk(KERN_INFO "Found vmxnet/PCI at %#x, irq %u.\n", ioaddr, irq_line); low_vmware_version = inl(ioaddr + VMXNET_LOW_VERSION); if ((low_vmware_version & 0xffff0000) != (VMXNET2_MAGIC & 0xffff0000)) { printk(KERN_ERR "Driver version 0x%08X doesn't match version 0x%08X\n", VMXNET2_MAGIC, low_vmware_version); goto morph_back; } else { /* * The low version looked OK so get the high version and make sure that * our version is supported. */ unsigned int high_vmware_version = inl(ioaddr + VMXNET_HIGH_VERSION); if ((VMXNET2_MAGIC < low_vmware_version) || (VMXNET2_MAGIC > high_vmware_version)) { printk(KERN_ERR "Driver version 0x%08X doesn't match version 0x%08X, 0x%08X\n", VMXNET2_MAGIC, low_vmware_version, high_vmware_version); goto morph_back; } } dev = compat_alloc_etherdev(sizeof *lp); if (!dev) { printk(KERN_ERR "Unable to allocate ethernet device\n"); goto morph_back; } lp = dev->priv; lp->pdev = pdev; dev->base_addr = ioaddr; outl(VMXNET_CMD_GET_FEATURES, dev->base_addr + VMXNET_COMMAND_ADDR); lp->features = inl(dev->base_addr + VMXNET_COMMAND_ADDR); outl(VMXNET_CMD_GET_CAPABILITIES, dev->base_addr + VMXNET_COMMAND_ADDR); lp->capabilities = inl(dev->base_addr + VMXNET_COMMAND_ADDR); /* determine the features supported */ lp->zeroCopyTx = FALSE; lp->partialHeaderCopyEnabled = FALSE; lp->tso = FALSE; lp->chainTx = FALSE; lp->chainRx = FALSE; lp->jumboFrame = FALSE; lp->lpd = FALSE; printk(KERN_INFO "features:"); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) if (lp->capabilities & VMNET_CAP_IP4_CSUM) { dev->features |= NETIF_F_IP_CSUM; printk(" ipCsum"); } if (lp->capabilities & VMNET_CAP_HW_CSUM) { dev->features |= NETIF_F_HW_CSUM; printk(" hwCsum"); } #endif #ifdef VMXNET_DO_ZERO_COPY if (lp->capabilities & VMNET_CAP_SG && lp->features & VMXNET_FEATURE_ZERO_COPY_TX){ dev->features |= NETIF_F_SG; lp->zeroCopyTx = TRUE; printk(" zeroCopy"); if (lp->capabilities & VMNET_CAP_ENABLE_HEADER_COPY) { lp->partialHeaderCopyEnabled = TRUE; printk(" partialHeaderCopy"); } if (lp->capabilities & VMNET_CAP_TX_CHAIN) { lp->chainTx = TRUE; } if (lp->capabilities & VMNET_CAP_RX_CHAIN) { lp->chainRx = TRUE; } if (lp->chainRx && lp->chainTx && (lp->features & VMXNET_FEATURE_JUMBO_FRAME)) { lp->jumboFrame = TRUE; printk(" jumboFrame"); } } #ifdef VMXNET_DO_TSO if ((lp->capabilities & VMNET_CAP_TSO) && (lp->capabilities & (VMNET_CAP_IP4_CSUM | VMNET_CAP_HW_CSUM)) && // tso only makes sense if we have hw csum offload lp->chainTx && lp->zeroCopyTx && lp->features & VMXNET_FEATURE_TSO) { dev->features |= NETIF_F_TSO; lp->tso = TRUE; printk(" tso"); } if ((lp->capabilities & VMNET_CAP_LPD) && (lp->features & VMXNET_FEATURE_LPD) && !disable_lro) { lp->lpd = TRUE; printk(" lpd"); } #endif #endif printk("\n"); /* check if this is enhanced vmxnet device */ if ((lp->features & VMXNET_FEATURE_TSO) && (lp->features & VMXNET_FEATURE_JUMBO_FRAME)) { enhanced = TRUE; } /* determine rx/tx ring sizes */ if (enhanced) { maxNumRxBuffers = ENHANCED_VMXNET2_MAX_NUM_RX_BUFFERS; defNumRxBuffers = ENHANCED_VMXNET2_DEFAULT_NUM_RX_BUFFERS; } else { maxNumRxBuffers = VMXNET2_MAX_NUM_RX_BUFFERS; defNumRxBuffers = VMXNET2_DEFAULT_NUM_RX_BUFFERS; } outl(VMXNET_CMD_GET_NUM_RX_BUFFERS, dev->base_addr + VMXNET_COMMAND_ADDR); numRxBuffers = inl(dev->base_addr + VMXNET_COMMAND_ADDR); if (numRxBuffers == 0 || numRxBuffers > maxNumRxBuffers) { numRxBuffers = defNumRxBuffers; } if (lp->jumboFrame || lp->lpd) { numRxBuffers2 = numRxBuffers * 4; if (numRxBuffers2 > VMXNET2_MAX_NUM_RX_BUFFERS2) { numRxBuffers2 = VMXNET2_MAX_NUM_RX_BUFFERS2; } } else { numRxBuffers2 = 1; } printk("numRxBuffers = %d, numRxBuffers2 = %d\n", numRxBuffers, numRxBuffers2); if (lp->tso || lp->jumboFrame) { maxNumTxBuffers = VMXNET2_MAX_NUM_TX_BUFFERS_TSO; defNumTxBuffers = VMXNET2_DEFAULT_NUM_TX_BUFFERS_TSO; } else { maxNumTxBuffers = VMXNET2_MAX_NUM_TX_BUFFERS; defNumTxBuffers = VMXNET2_DEFAULT_NUM_TX_BUFFERS; } outl(VMXNET_CMD_GET_NUM_TX_BUFFERS, dev->base_addr + VMXNET_COMMAND_ADDR); numTxBuffers = inl(dev->base_addr + VMXNET_COMMAND_ADDR); if (numTxBuffers == 0 || numTxBuffers > maxNumTxBuffers) { numTxBuffers = defNumTxBuffers; } driverDataSize = sizeof(Vmxnet2_DriverData) + (numRxBuffers + numRxBuffers2) * sizeof(Vmxnet2_RxRingEntry) + numTxBuffers * sizeof(Vmxnet2_TxRingEntry); VMXNET_LOG("vmxnet: numRxBuffers=((%d+%d)*%d) numTxBuffers=(%d*%d) driverDataSize=%d\n", numRxBuffers, numRxBuffers2, (uint32)sizeof(Vmxnet2_RxRingEntry), numTxBuffers, (uint32)sizeof(Vmxnet2_TxRingEntry), driverDataSize); lp->ddAllocated = kmalloc(driverDataSize + 15, GFP_DMA | GFP_KERNEL); if (!lp->ddAllocated) { printk(KERN_ERR "Unable to allocate memory for driver data\n"); goto free_dev; } if ((uintptr_t)virt_to_bus(lp->ddAllocated) > SHARED_MEM_MAX) { printk(KERN_ERR "Unable to initialize driver data, address outside of shared area (0x%p)\n", (void*)virt_to_bus(lp->ddAllocated)); goto free_dev_dd; } /* Align on paragraph boundary */ lp->dd = (Vmxnet2_DriverData*)(((unsigned long)lp->ddAllocated + 15) & ~15UL); memset(lp->dd, 0, driverDataSize); spin_lock_init(&lp->txLock); lp->numRxBuffers = numRxBuffers; lp->numRxBuffers2 = numRxBuffers2; lp->numTxBuffers = numTxBuffers; /* So that the vmkernel can check it is compatible */ lp->dd->magic = VMXNET2_MAGIC; lp->dd->length = driverDataSize; lp->name = VMXNET_CHIP_NAME; /* * Store whether we are morphed so we can figure out how to * clean up when we unload. */ lp->morphed = morphed; if (lp->capabilities & VMNET_CAP_VMXNET_APROM) { for (i = 0; i < ETH_ALEN; i++) { dev->dev_addr[i] = inb(ioaddr + VMXNET_APROM_ADDR + i); } for (i = 0; i < ETH_ALEN; i++) { outb(dev->dev_addr[i], ioaddr + VMXNET_MAC_ADDR + i); } } else { /* * Be backwards compatible and use the MAC address register to * get MAC address. */ for (i = 0; i < ETH_ALEN; i++) { dev->dev_addr[i] = inb(ioaddr + VMXNET_MAC_ADDR + i); } } #ifdef VMXNET_DO_ZERO_COPY lp->txBufferStart = NULL; lp->dd->txBufferPhysStart = 0; lp->dd->txBufferPhysLength = 0; if (lp->partialHeaderCopyEnabled) { unsigned int txBufferSize; txBufferSize = numTxBuffers * TX_PKT_HEADER_SIZE; lp->txBufferStartRaw = kmalloc(txBufferSize + PAGE_SIZE, GFP_DMA | GFP_KERNEL); if (lp->txBufferStartRaw) { lp->txBufferStart = (char*)((unsigned long)(lp->txBufferStartRaw + PAGE_SIZE - 1) & (unsigned long)~(PAGE_SIZE - 1)); lp->dd->txBufferPhysStart = virt_to_phys(lp->txBufferStart); lp->dd->txBufferPhysLength = txBufferSize; lp->dd->txPktMaxSize = TX_PKT_HEADER_SIZE; } else { lp->partialHeaderCopyEnabled = FALSE; printk(KERN_INFO "failed to allocate tx buffer, disable partialHeaderCopy\n"); } } #endif dev->irq = irq_line; dev->open = &vmxnet_open; dev->hard_start_xmit = &vmxnet_start_tx; dev->stop = &vmxnet_close; dev->get_stats = &vmxnet_get_stats; dev->set_multicast_list = &vmxnet_set_multicast_list; #ifdef HAVE_CHANGE_MTU dev->change_mtu = &vmxnet_change_mtu; #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,43) dev->tx_timeout = &vmxnet_tx_timeout; dev->watchdog_timeo = VMXNET_WATCHDOG_TIMEOUT; #endif #ifdef VMW_HAVE_POLL_CONTROLLER dev->poll_controller = vmxnet_netpoll; #endif /* Do this after ether_setup(), which sets the default value. */ dev->set_mac_address = &vmxnet_set_mac_address; #ifdef SET_ETHTOOL_OPS SET_ETHTOOL_OPS(dev, &vmxnet_ethtool_ops); #else dev->do_ioctl = vmxnet_ioctl; #endif COMPAT_SET_MODULE_OWNER(dev); COMPAT_SET_NETDEV_DEV(dev, &pdev->dev); if (register_netdev(dev)) { printk(KERN_ERR "Unable to register device\n"); goto free_dev_dd; } /* * Use deferrable timer - we want 2s interval, but if it will * be 2 seconds or 10 seconds, we do not care. */ compat_init_timer_deferrable(&lp->linkCheckTimer); lp->linkCheckTimer.data = (unsigned long)dev; lp->linkCheckTimer.function = vmxnet_link_check; vmxnet_link_check(lp->linkCheckTimer.data); /* Do this after register_netdev(), which sets device name */ VMXNET_LOG("%s: %s at %#3lx assigned IRQ %d.\n", dev->name, lp->name, dev->base_addr, dev->irq); pci_set_drvdata(pdev, dev); return 0; free_dev_dd:; kfree(lp->ddAllocated); free_dev:; compat_free_netdev(dev); morph_back:; if (morphed) { /* Morph back to LANCE hw. */ outw(LANCE_CHIP, ioaddr - MORPH_PORT_SIZE); } release_reg:; release_region(reqIOAddr, reqIOSize); pci_disable:; compat_pci_disable_device(pdev); return -EBUSY; } /* *----------------------------------------------------------------------------- * * vmxnet_remove_device -- * * Cleanup, called for each device on unload. * * Results: * None. * * Side effects: * Unregisters vmxnet device with Linux and frees memory. * *----------------------------------------------------------------------------- */ static void vmxnet_remove_device(struct pci_dev* pdev) { struct net_device *dev = pci_get_drvdata(pdev); struct Vmxnet_Private *lp = dev->priv; /* * Do this before device is gone so we never call netif_carrier_* after * unregistering netdevice. */ compat_del_timer_sync(&lp->linkCheckTimer); unregister_netdev(dev); /* Unmorph adapter if it was morphed. */ if (lp->morphed) { uint16 magic; /* Read morph port to verify that we can morph the adapter. */ magic = inw(dev->base_addr - MORPH_PORT_SIZE); if (magic != VMXNET_CHIP) { printk(KERN_ERR "Adapter not morphed. read magic: 0x%08X\n", magic); } /* Morph adapter back to LANCE. */ outw(LANCE_CHIP, dev->base_addr - MORPH_PORT_SIZE); /* Verify that we unmorphed correctly. */ magic = inw(dev->base_addr - MORPH_PORT_SIZE); if (magic != LANCE_CHIP) { printk(KERN_ERR "Couldn't unmorph adapter. Invalid magic, read: 0x%08X\n", magic); } release_region(dev->base_addr - (LANCE_CHIP_IO_RESV_SIZE + MORPH_PORT_SIZE), VMXNET_CHIP_IO_RESV_SIZE + (LANCE_CHIP_IO_RESV_SIZE + MORPH_PORT_SIZE)); } else { release_region(dev->base_addr, VMXNET_CHIP_IO_RESV_SIZE); } #ifdef VMXNET_DO_ZERO_COPY if (lp->partialHeaderCopyEnabled){ kfree(lp->txBufferStartRaw); } #endif kfree(lp->ddAllocated); compat_free_netdev(dev); compat_pci_disable_device(pdev); } /* *----------------------------------------------------------------------------- * * vmxnet_init_ring -- * * Initializes buffer rings in Vmxnet_Private structure. Allocates skbs * to receive into. Called by vmxnet_open. * * Results: * 0 on success; -1 on failure to allocate skbs. * * Side effects: * *----------------------------------------------------------------------------- */ static int vmxnet_init_ring(struct net_device *dev) { struct Vmxnet_Private *lp = (Vmxnet_Private *)dev->priv; Vmxnet2_DriverData *dd = lp->dd; unsigned int i; size_t offset; offset = sizeof(*dd); dd->rxRingLength = lp->numRxBuffers; dd->rxRingOffset = offset; lp->rxRing = (Vmxnet2_RxRingEntry *)((uintptr_t)dd + offset); offset += lp->numRxBuffers * sizeof(Vmxnet2_RxRingEntry); dd->rxRingLength2 = lp->numRxBuffers2; dd->rxRingOffset2 = offset; lp->rxRing2 = (Vmxnet2_RxRingEntry *)((uintptr_t)dd + offset); offset += lp->numRxBuffers2 * sizeof(Vmxnet2_RxRingEntry); dd->txRingLength = lp->numTxBuffers; dd->txRingOffset = offset; lp->txRing = (Vmxnet2_TxRingEntry *)((uintptr_t)dd + offset); offset += lp->numTxBuffers * sizeof(Vmxnet2_TxRingEntry); VMXNET_LOG("vmxnet_init_ring: offset=%"FMT64"d length=%d\n", (uint64)offset, dd->length); for (i = 0; i < lp->numRxBuffers; i++) { lp->rxSkbuff[i] = dev_alloc_skb(PKT_BUF_SZ); if (lp->rxSkbuff[i] == NULL) { unsigned int j; printk (KERN_ERR "%s: vmxnet_init_ring dev_alloc_skb failed.\n", dev->name); for (j = 0; j < i; j++) { compat_dev_kfree_skb(lp->rxSkbuff[j], FREE_WRITE); lp->rxSkbuff[j] = NULL; } return -ENOMEM; } lp->rxRing[i].paddr = virt_to_bus(compat_skb_tail_pointer(lp->rxSkbuff[i])); lp->rxRing[i].bufferLength = PKT_BUF_SZ; lp->rxRing[i].actualLength = 0; lp->rxRing[i].ownership = VMXNET2_OWNERSHIP_NIC; } #ifdef VMXNET_DO_ZERO_COPY if (lp->jumboFrame || lp->lpd) { struct pci_dev *pdev = lp->pdev; dd->maxFrags = MAX_SKB_FRAGS; for (i = 0; i < lp->numRxBuffers2; i++) { lp->rxPages[i] = alloc_page(GFP_KERNEL); if (lp->rxPages[i] == NULL) { unsigned int j; printk (KERN_ERR "%s: vmxnet_init_ring alloc_page failed.\n", dev->name); for (j = 0; j < i; j++) { put_page(lp->rxPages[j]); lp->rxPages[j] = NULL; } for (j = 0; j < lp->numRxBuffers; j++) { compat_dev_kfree_skb(lp->rxSkbuff[j], FREE_WRITE); lp->rxSkbuff[j] = NULL; } return -ENOMEM; } lp->rxRing2[i].paddr = pci_map_page(pdev, lp->rxPages[i], 0, PAGE_SIZE, PCI_DMA_FROMDEVICE); lp->rxRing2[i].bufferLength = PAGE_SIZE; lp->rxRing2[i].actualLength = 0; lp->rxRing2[i].ownership = VMXNET2_OWNERSHIP_NIC_FRAG; } } else #endif { // dummy rxRing2 tacked on to the end, with a single unusable entry lp->rxRing2[0].paddr = 0; lp->rxRing2[0].bufferLength = 0; lp->rxRing2[0].actualLength = 0; lp->rxRing2[0].ownership = VMXNET2_OWNERSHIP_DRIVER; } dd->rxDriverNext = 0; dd->rxDriverNext2 = 0; for (i = 0; i < lp->numTxBuffers; i++) { lp->txRing[i].ownership = VMXNET2_OWNERSHIP_DRIVER; lp->txBufInfo[i].skb = NULL; lp->txBufInfo[i].eop = 0; lp->txRing[i].sg.sg[0].addrHi = 0; lp->txRing[i].sg.addrType = NET_SG_PHYS_ADDR; } dd->txDriverCur = dd->txDriverNext = 0; dd->savedRxNICNext = dd->savedRxNICNext2 = dd->savedTxNICNext = 0; dd->txStopped = FALSE; if (lp->lpd) { dd->featureCtl |= VMXNET_FEATURE_LPD; } return 0; } /* *----------------------------------------------------------------------------- * * vmxnet_open -- * * Network device open routine. Called by Linux when the interface is * brought up. * * Results: * 0 on success; else negative errno value. * * Side effects: * Allocates an IRQ if not already allocated. Sets our Vmxnet_Private * structure to be the shared area with the lower layer. * *----------------------------------------------------------------------------- */ static int vmxnet_open(struct net_device *dev) { struct Vmxnet_Private *lp = (Vmxnet_Private *)dev->priv; unsigned int ioaddr = dev->base_addr; u32 paddr; if (dev->irq == 0 || request_irq(dev->irq, &vmxnet_interrupt, COMPAT_IRQF_SHARED, lp->name, (void *)dev)) { return -EAGAIN; } if (vmxnet_debug > 1) { printk(KERN_DEBUG "%s: vmxnet_open() irq %d lp %#x.\n", dev->name, dev->irq, (u32) virt_to_bus(lp)); } if (vmxnet_init_ring(dev)) { return -ENOMEM; } paddr = virt_to_bus(lp->dd); outl(paddr, ioaddr + VMXNET_INIT_ADDR); outl(lp->dd->length, ioaddr + VMXNET_INIT_LENGTH); #ifdef VMXNET_DO_ZERO_COPY if (lp->partialHeaderCopyEnabled) { outl(VMXNET_CMD_PIN_TX_BUFFERS, ioaddr + VMXNET_COMMAND_ADDR); } // Pin the Tx buffers if partial header copy is enabled #endif lp->dd->txStopped = FALSE; compat_netif_start_queue(dev); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43) dev->interrupt = 0; dev->start = 1; #endif lp->devOpen = TRUE; COMPAT_NETDEV_MOD_INC_USE_COUNT; return 0; } #ifdef VMXNET_DO_ZERO_COPY /* *----------------------------------------------------------------------------- * * vmxnet_unmap_buf -- * * Unmap the PAs of the tx entry that we pinned for DMA. * * Results: * None. * * Side effects: * None *----------------------------------------------------------------------------- */ void vmxnet_unmap_buf(struct sk_buff *skb, struct Vmxnet2_TxBuf *tb, Vmxnet2_TxRingEntry *xre, struct pci_dev *pdev) { int sgIdx; // unmap the mapping for skb->data if needed if (tb->sgForLinear >= 0) { pci_unmap_single(pdev, VMXNET_GET_DMA_ADDR(xre->sg.sg[(int)tb->sgForLinear]), xre->sg.sg[(int)tb->sgForLinear].length, PCI_DMA_TODEVICE); VMXNET_LOG("vmxnet_unmap_buf: sg[%d] (%uB)\n", (int)tb->sgForLinear, xre->sg.sg[(int)tb->sgForLinear].length); } // unmap the mapping for skb->frags[] for (sgIdx = tb->firstSgForFrag; sgIdx < xre->sg.length; sgIdx++) { pci_unmap_page(pdev, VMXNET_GET_DMA_ADDR(xre->sg.sg[sgIdx]), xre->sg.sg[sgIdx].length, PCI_DMA_TODEVICE); VMXNET_LOG("vmxnet_unmap_buf: sg[%d] (%uB)\n", sgIdx, xre->sg.sg[sgIdx].length); } } /* *----------------------------------------------------------------------------- * * vmxnet_map_pkt -- * * Map the buffers/pages that we need for DMA and populate the SG. * * "offset" indicates the position inside the pkt where mapping should start. * "startSgIdx" indicates the first free sg slot of the first tx entry * (pointed to by txDriverNext). * * The caller should guarantee the first tx has at least one sg slot * available. The caller should also ensure that enough tx entries are * available for this pkt. * * Results: * None. * * Side effects: * 1. Ownership of all tx entries used (EXCEPT the 1st one) are updated. * The only flag set is VMXNET2_TX_MORE if needed. caller is * responsible to set up other flags after this call returns. * 2. lp->dd->numTxPending is updated * 3. txBufInfo corresponding to used tx entries (including the 1st one) * are updated * 4. txDriverNext is advanced accordingly * *----------------------------------------------------------------------------- */ void vmxnet_map_pkt(struct sk_buff *skb, int offset, struct Vmxnet_Private *lp, int startSgIdx) { int nextFrag = 0, nextSg = startSgIdx; struct skb_frag_struct *frag; Vmxnet2_DriverData *dd = lp->dd; Vmxnet2_TxRingEntry *xre; struct Vmxnet2_TxBuf *tb; dma_addr_t dma; VMXNET_ASSERT(startSgIdx < VMXNET2_SG_DEFAULT_LENGTH); lp->numTxPending ++; tb = &lp->txBufInfo[dd->txDriverNext]; xre = &lp->txRing[dd->txDriverNext]; if (offset == skb_headlen(skb)) { tb->sgForLinear = -1; tb->firstSgForFrag = nextSg; } else if (offset < skb_headlen(skb)) { /* we need to map some of the non-frag data. */ dma = pci_map_single(lp->pdev, skb->data + offset, skb_headlen(skb) - offset, PCI_DMA_TODEVICE); VMXNET_FILL_SG(xre->sg.sg[nextSg], dma, skb_headlen(skb) - offset); VMXNET_LOG("vmxnet_map_pkt: txRing[%u].sg[%d] -> data %p offset %u size %u\n", dd->txDriverNext, nextSg, skb->data, offset, skb_headlen(skb) - offset); tb->sgForLinear = nextSg++; tb->firstSgForFrag = nextSg; } else { // all non-frag data is copied, skip it tb->sgForLinear = -1; tb->firstSgForFrag = nextSg; offset -= skb_headlen(skb); for ( ; nextFrag < skb_shinfo(skb)->nr_frags; nextFrag++){ frag = &skb_shinfo(skb)->frags[nextFrag]; // skip those frags that are completely copied if (offset >= frag->size){ offset -= frag->size; } else { // map the part of the frag that is not copied dma = pci_map_page(lp->pdev, frag->page, frag->page_offset + offset, frag->size - offset, PCI_DMA_TODEVICE); VMXNET_FILL_SG(xre->sg.sg[nextSg], dma, frag->size - offset); VMXNET_LOG("vmxnet_map_tx: txRing[%u].sg[%d] -> frag[%d]+%u (%uB)\n", dd->txDriverNext, nextSg, nextFrag, offset, frag->size - offset); nextSg++; nextFrag++; break; } } } // map the remaining frags, we might need to use additional tx entries for ( ; nextFrag < skb_shinfo(skb)->nr_frags; nextFrag++) { frag = &skb_shinfo(skb)->frags[nextFrag]; dma = pci_map_page(lp->pdev, frag->page, frag->page_offset, frag->size, PCI_DMA_TODEVICE); if (nextSg == VMXNET2_SG_DEFAULT_LENGTH) { xre->flags = VMXNET2_TX_MORE; xre->sg.length = VMXNET2_SG_DEFAULT_LENGTH; tb->skb = skb; tb->eop = 0; // move to the next tx entry VMXNET_INC(dd->txDriverNext, dd->txRingLength); xre = &lp->txRing[dd->txDriverNext]; tb = &lp->txBufInfo[dd->txDriverNext]; // the new tx entry must be available VMXNET_ASSERT(xre->ownership == VMXNET2_OWNERSHIP_DRIVER && tb->skb == NULL); /* * we change it even before the sg are populated but this is * fine, because the first tx entry's ownership is not * changed yet */ xre->ownership = VMXNET2_OWNERSHIP_NIC; tb->sgForLinear = -1; tb->firstSgForFrag = 0; lp->numTxPending ++; nextSg = 0; } VMXNET_FILL_SG(xre->sg.sg[nextSg], dma, frag->size); VMXNET_LOG("vmxnet_map_tx: txRing[%u].sg[%d] -> frag[%d] (%uB)\n", dd->txDriverNext, nextSg, nextFrag, frag->size); nextSg++; } // setup the last tx entry xre->flags = 0; xre->sg.length = nextSg; tb->skb = skb; tb->eop = 1; VMXNET_ASSERT(nextSg <= VMXNET2_SG_DEFAULT_LENGTH); VMXNET_INC(dd->txDriverNext, dd->txRingLength); } #endif /* *----------------------------------------------------------------------------- * * check_tx_queue -- * * Loop through the tx ring looking for completed transmits. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static void check_tx_queue(struct net_device *dev) { Vmxnet_Private *lp = (Vmxnet_Private *)dev->priv; Vmxnet2_DriverData *dd = lp->dd; int completed = 0; while (1) { Vmxnet2_TxRingEntry *xre = &lp->txRing[dd->txDriverCur]; struct sk_buff *skb = lp->txBufInfo[dd->txDriverCur].skb; if (xre->ownership != VMXNET2_OWNERSHIP_DRIVER || skb == NULL) { break; } #ifdef VMXNET_DO_ZERO_COPY if (lp->zeroCopyTx){ VMXNET_LOG("unmap txRing[%u]\n", dd->txDriverCur); vmxnet_unmap_buf(skb, &lp->txBufInfo[dd->txDriverCur], xre, lp->pdev); } #endif if (lp->txBufInfo[dd->txDriverCur].eop) { compat_dev_kfree_skb_irq(skb, FREE_WRITE); } lp->txBufInfo[dd->txDriverCur].skb = NULL; completed ++; VMXNET_INC(dd->txDriverCur, dd->txRingLength); } if (completed){ lp->numTxPending -= completed; // XXX conditionally wake up the queue based on the # of freed entries if (compat_netif_queue_stopped(dev)) { compat_netif_wake_queue(dev); dd->txStopped = FALSE; } } } /* *----------------------------------------------------------------------------- * * vmxnet_tx -- * * Network device hard_start_xmit helper routine. This is called by * the drivers hard_start_xmit routine when it wants to send a packet. * * Results: * VMXNET_CALL_TRANSMIT: The driver should ask the virtual NIC to * transmit a packet. * VMXNET_DEFER_TRANSMIT: This transmit is deferred because of * transmit clustering. * VMXNET_STOP_TRANSMIT: We ran out of queue space so the caller * should stop transmitting. * * Side effects: * The drivers tx ring may get modified. * *----------------------------------------------------------------------------- */ Vmxnet_TxStatus vmxnet_tx(struct sk_buff *skb, struct net_device *dev) { Vmxnet_TxStatus status = VMXNET_DEFER_TRANSMIT; struct Vmxnet_Private *lp = (struct Vmxnet_Private *)dev->priv; Vmxnet2_DriverData *dd = lp->dd; unsigned long flags; Vmxnet2_TxRingEntry *xre; #ifdef VMXNET_DO_TSO int mss; #endif xre = &lp->txRing[dd->txDriverNext]; #ifdef VMXNET_DO_ZERO_COPY if (lp->zeroCopyTx) { int txEntries, sgCount; unsigned int headerSize; /* conservatively estimate the # of tx entries needed in the worse case */ sgCount = (lp->partialHeaderCopyEnabled ? 2 : 1) + skb_shinfo(skb)->nr_frags; txEntries = (sgCount + VMXNET2_SG_DEFAULT_LENGTH - 1) / VMXNET2_SG_DEFAULT_LENGTH; if (UNLIKELY(!lp->chainTx && txEntries > 1)) { /* * rare case, no tx desc chaining support but the pkt need more than 1 * tx entry, linearize it */ if (compat_skb_linearize(skb) != 0) { VMXNET_LOG("vmxnet_tx: skb_linearize failed\n"); compat_dev_kfree_skb(skb, FREE_WRITE); return VMXNET_DEFER_TRANSMIT; } txEntries = 1; } VMXNET_LOG("\n%d(%d) bytes, %d frags, %d tx entries\n", skb->len, skb_headlen(skb), skb_shinfo(skb)->nr_frags, txEntries); spin_lock_irqsave(&lp->txLock, flags); /* check for the availability of tx ring entries */ if (dd->txRingLength - lp->numTxPending < txEntries) { dd->txStopped = TRUE; compat_netif_stop_queue(dev); check_tx_queue(dev); spin_unlock_irqrestore(&lp->txLock, flags); VMXNET_LOG("queue stopped\n"); return VMXNET_STOP_TRANSMIT; } /* copy protocol headers if needed */ if (LIKELY(lp->partialHeaderCopyEnabled)) { unsigned int pos = dd->txDriverNext * dd->txPktMaxSize; char *header = lp->txBufferStart + pos; /* figure out the protocol and header sizes */ /* PR 171928 * compat_skb_ip_header isn't updated in rhel5 for * vlan tagging. using these macros causes incorrect * computation of the headerSize */ headerSize = ETHERNET_HEADER_SIZE; if (UNLIKELY((skb_headlen(skb) < headerSize))) { if (skb_is_nonlinear(skb)) { compat_skb_linearize(skb); } /* * drop here if we don't have a complete ETH header for delivery */ if (skb_headlen(skb) < headerSize) { compat_dev_kfree_skb(skb, FREE_WRITE); spin_unlock_irqrestore(&lp->txLock, flags); return VMXNET_DEFER_TRANSMIT; } } if (UNLIKELY(*(uint16*)(skb->data + ETH_FRAME_TYPE_LOCATION) == ETH_TYPE_VLAN_TAG)) { headerSize += VLAN_TAG_LENGTH; if (UNLIKELY(skb_headlen(skb) < headerSize)) { if (skb_is_nonlinear(skb)) { compat_skb_linearize(skb); } /* * drop here if we don't have a ETH header and a complete VLAN tag */ if (skb_headlen(skb) < headerSize) { compat_dev_kfree_skb(skb, FREE_WRITE); spin_unlock_irqrestore(&lp->txLock, flags); return VMXNET_DEFER_TRANSMIT; } } } if (LIKELY(PKT_OF_IPV4(skb))){ // PR 171928 -- compat_skb_ip_header broken with vconfig // please do not rewrite using compat_skb_ip_header struct iphdr *ipHdr = (struct iphdr *)(skb->data + headerSize); if (UNLIKELY(skb_headlen(skb) < headerSize + sizeof(*ipHdr))) { if (skb_is_nonlinear(skb)) { compat_skb_linearize(skb); } } if (LIKELY(skb_headlen(skb) > headerSize + sizeof(*ipHdr)) && (LIKELY(ipHdr->version == 4))) { headerSize += ipHdr->ihl << 2; if (LIKELY(ipHdr->protocol == IPPROTO_TCP)) { /* * tcp traffic, copy all protocol headers * refrain from using compat_skb macros PR 171928 */ struct tcphdr *tcpHdr = (struct tcphdr *) (skb->data + headerSize); /* * tcp->doff is near the end of the tcpHdr, use the * entire struct as the required size */ if (skb->len < headerSize + sizeof(*tcpHdr)) { compat_dev_kfree_skb(skb, FREE_WRITE); spin_unlock_irqrestore(&lp->txLock, flags); return VMXNET_DEFER_TRANSMIT; } if (skb_headlen(skb) < (headerSize + sizeof(*tcpHdr))) { /* * linearized portion of the skb doesn't have a tcp header */ compat_skb_linearize(skb); } headerSize += tcpHdr->doff << 2; } } } if (skb_copy_bits(skb, 0, header, headerSize) != 0) { compat_dev_kfree_skb(skb, FREE_WRITE); spin_unlock_irqrestore(&lp->txLock, flags); return VMXNET_DEFER_TRANSMIT; } xre->sg.sg[0].addrLow = (uint32)dd->txBufferPhysStart + pos; xre->sg.sg[0].addrHi = 0; xre->sg.sg[0].length = headerSize; vmxnet_map_pkt(skb, headerSize, lp, 1); } else { headerSize = 0; vmxnet_map_pkt(skb, 0, lp, 0); } #ifdef VMXNET_DO_TSO mss = VMXNET_SKB_MSS(skb); if (mss) { xre->flags |= VMXNET2_TX_TSO; xre->tsoMss = mss; dd->txNumDeferred += ((skb->len - headerSize) + mss - 1) / mss; } else #endif { dd->txNumDeferred++; } } else /* zero copy not enabled */ #endif { struct Vmxnet2_TxBuf *tb; spin_lock_irqsave(&lp->txLock, flags); if (lp->txBufInfo[dd->txDriverNext].skb != NULL) { dd->txStopped = TRUE; compat_netif_stop_queue(dev); check_tx_queue(dev); spin_unlock_irqrestore(&lp->txLock, flags); return VMXNET_STOP_TRANSMIT; } lp->numTxPending ++; xre->sg.sg[0].addrLow = virt_to_bus(skb->data); xre->sg.sg[0].addrHi = 0; xre->sg.sg[0].length = skb->len; xre->sg.length = 1; xre->flags = 0; tb = &lp->txBufInfo[dd->txDriverNext]; tb->skb = skb; tb->sgForLinear = -1; tb->firstSgForFrag = -1; tb->eop = 1; VMXNET_INC(dd->txDriverNext, dd->txRingLength); dd->txNumDeferred++; dd->stats.copyTransmits++; } /* at this point, xre must point to the 1st tx entry for the pkt */ if (skb->ip_summed == VM_TX_CHECKSUM_PARTIAL) { xre->flags |= VMXNET2_TX_HW_XSUM | VMXNET2_TX_CAN_KEEP; } else { xre->flags |= VMXNET2_TX_CAN_KEEP; } if (lp->numTxPending > dd->txRingLength - 5) { xre->flags |= VMXNET2_TX_RING_LOW; status = VMXNET_CALL_TRANSMIT; } wmb(); xre->ownership = VMXNET2_OWNERSHIP_NIC; if (dd->txNumDeferred >= dd->txClusterLength) { dd->txNumDeferred = 0; status = VMXNET_CALL_TRANSMIT; } dev->trans_start = jiffies; lp->stats.tx_packets++; dd->stats.pktsTransmitted++; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) lp->stats.tx_bytes += skb->len; #endif if (lp->numTxPending > dd->stats.maxTxsPending) { dd->stats.maxTxsPending = lp->numTxPending; } check_tx_queue(dev); spin_unlock_irqrestore(&lp->txLock, flags); return status; } /* *----------------------------------------------------------------------------- * * vmxnet_start_tx -- * * Network device hard_start_xmit routine. Called by Linux when it has * a packet for us to transmit. * * Results: * 0 on success; 1 if no resources. * * Side effects: * *----------------------------------------------------------------------------- */ static int vmxnet_start_tx(struct sk_buff *skb, struct net_device *dev) { int retVal = 0; Vmxnet_TxStatus xs = vmxnet_tx(skb, dev); switch (xs) { case VMXNET_CALL_TRANSMIT: inl(dev->base_addr + VMXNET_TX_ADDR); break; case VMXNET_DEFER_TRANSMIT: break; case VMXNET_STOP_TRANSMIT: retVal = 1; break; } return retVal; } #ifdef VMXNET_DO_ZERO_COPY /* *---------------------------------------------------------------------------- * * vmxnet_drop_frags -- * * return the entries in the 2nd ring to the hw. The entries returned are * from rxDriverNext2 to the entry with VMXNET2_RX_FRAG_EOP set. * * Result: * None * * Side-effects: * None * *---------------------------------------------------------------------------- */ static void vmxnet_drop_frags(Vmxnet_Private *lp) { Vmxnet2_DriverData *dd = lp->dd; Vmxnet2_RxRingEntry *rre2; uint16 flags; do { rre2 = &lp->rxRing2[dd->rxDriverNext2]; flags = rre2->flags; VMXNET_ASSERT(rre2->ownership == VMXNET2_OWNERSHIP_DRIVER_FRAG); rre2->ownership = VMXNET2_OWNERSHIP_NIC_FRAG; VMXNET_INC(dd->rxDriverNext2, dd->rxRingLength2); } while(!(flags & VMXNET2_RX_FRAG_EOP)); } /* *---------------------------------------------------------------------------- * * vmxnet_rx_frags -- * * get data from the 2nd rx ring and append the frags to the skb. Multiple * rx entries in the 2nd rx ring are processed until the one with * VMXNET2_RX_FRAG_EOP set. * * Result: * 0 on success * -1 on error * * Side-effects: * frags are appended to skb. related fields in skb are updated * *---------------------------------------------------------------------------- */ static int vmxnet_rx_frags(Vmxnet_Private *lp, struct sk_buff *skb) { Vmxnet2_DriverData *dd = lp->dd; struct pci_dev *pdev = lp->pdev; struct page *newPage; int numFrags = 0; Vmxnet2_RxRingEntry *rre2; uint16 flags; #ifdef VMXNET_DEBUG uint32 firstFrag = dd->rxDriverNext2; #endif do { rre2 = &lp->rxRing2[dd->rxDriverNext2]; flags = rre2->flags; VMXNET_ASSERT(rre2->ownership == VMXNET2_OWNERSHIP_DRIVER_FRAG); if (rre2->actualLength > 0) { newPage = alloc_page(GFP_ATOMIC); if (UNLIKELY(newPage == NULL)) { skb_shinfo(skb)->nr_frags = numFrags; skb->len += skb->data_len; skb->truesize += skb->data_len; compat_dev_kfree_skb(skb, FREE_WRITE); vmxnet_drop_frags(lp); return -1; } pci_unmap_page(pdev, rre2->paddr, PAGE_SIZE, PCI_DMA_FROMDEVICE); skb_shinfo(skb)->frags[numFrags].page = lp->rxPages[dd->rxDriverNext2]; skb_shinfo(skb)->frags[numFrags].page_offset = 0; skb_shinfo(skb)->frags[numFrags].size = rre2->actualLength; skb->data_len += rre2->actualLength; numFrags++; /* refill the buffer */ lp->rxPages[dd->rxDriverNext2] = newPage; rre2->paddr = pci_map_page(pdev, newPage, 0, PAGE_SIZE, PCI_DMA_FROMDEVICE); rre2->bufferLength = PAGE_SIZE; rre2->actualLength = 0; wmb(); } rre2->ownership = VMXNET2_OWNERSHIP_NIC_FRAG; VMXNET_INC(dd->rxDriverNext2, dd->rxRingLength2); } while (!(flags & VMXNET2_RX_FRAG_EOP)); VMXNET_ASSERT(numFrags > 0); skb_shinfo(skb)->nr_frags = numFrags; skb->len += skb->data_len; skb->truesize += skb->data_len; VMXNET_LOG("vmxnet_rx: %dB from rxRing[%d](%dB)+rxRing2[%d, %d)(%dB)\n", skb->len, dd->rxDriverNext, skb_headlen(skb), firstFrag, dd->rxDriverNext2, skb->data_len); return 0; } #endif /* *----------------------------------------------------------------------------- * * vmxnet_rx -- * * Receive a packet. * * Results: * 0 * * Side effects: * None. * *----------------------------------------------------------------------------- */ static int vmxnet_rx(struct net_device *dev) { Vmxnet_Private *lp = (Vmxnet_Private *)dev->priv; Vmxnet2_DriverData *dd = lp->dd; if (!lp->devOpen) { return 0; } while (1) { struct sk_buff *skb, *newSkb; Vmxnet2_RxRingEntry *rre; rre = &lp->rxRing[dd->rxDriverNext]; if (rre->ownership != VMXNET2_OWNERSHIP_DRIVER) { break; } if (UNLIKELY(rre->actualLength == 0)) { #ifdef VMXNET_DO_ZERO_COPY if (rre->flags & VMXNET2_RX_WITH_FRAG) { vmxnet_drop_frags(lp); } #endif lp->stats.rx_errors++; goto next_pkt; } skb = lp->rxSkbuff[dd->rxDriverNext]; /* refill the rx ring */ newSkb = dev_alloc_skb(PKT_BUF_SZ); if (UNLIKELY(newSkb == NULL)) { printk(KERN_DEBUG "%s: Memory squeeze, dropping packet.\n", dev->name); #ifdef VMXNET_DO_ZERO_COPY if (rre->flags & VMXNET2_RX_WITH_FRAG) { vmxnet_drop_frags(lp); } #endif lp->stats.rx_errors++; goto next_pkt; } lp->rxSkbuff[dd->rxDriverNext] = newSkb; rre->paddr = virt_to_bus(newSkb->data); rre->bufferLength = PKT_BUF_SZ; skb_put(skb, rre->actualLength); #ifdef VMXNET_DO_ZERO_COPY if (rre->flags & VMXNET2_RX_WITH_FRAG) { if (vmxnet_rx_frags(lp, skb) < 0) { lp->stats.rx_errors++; goto next_pkt; } } else #endif { VMXNET_LOG("vmxnet_rx: %dB from rxRing[%d]\n", skb->len, dd->rxDriverNext); } if (skb->len < (ETH_MIN_FRAME_LEN - 4)) { /* * Ethernet header vlan tags are 4 bytes. Some vendors generate * ETH_MIN_FRAME_LEN frames including vlan tags. When vlan tag * is stripped, such frames become ETH_MIN_FRAME_LEN - 4. (PR106153) */ if (skb->len != 0) { printk(KERN_DEBUG "%s: Runt pkt (%d bytes) entry %d!\n", dev->name, skb->len, dd->rxDriverNext); } lp->stats.rx_errors++; } else { if (rre->flags & VMXNET2_RX_HW_XSUM_OK) { skb->ip_summed = CHECKSUM_UNNECESSARY; } skb->dev = dev; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) lp->stats.rx_bytes += skb->len; #endif skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); lp->stats.rx_packets++; dd->stats.pktsReceived++; } next_pkt: rre->ownership = VMXNET2_OWNERSHIP_NIC; VMXNET_INC(dd->rxDriverNext, dd->rxRingLength); } return 0; } /* *----------------------------------------------------------------------------- * * vmxnet_interrupt -- * * Interrupt handler. Calls vmxnet_rx to receive a packet. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------------- */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) static compat_irqreturn_t vmxnet_interrupt(int irq, void *dev_id, struct pt_regs * regs) #else static compat_irqreturn_t vmxnet_interrupt(int irq, void *dev_id) #endif { struct net_device *dev = (struct net_device *)dev_id; struct Vmxnet_Private *lp; Vmxnet2_DriverData *dd; if (dev == NULL) { printk (KERN_DEBUG "vmxnet_interrupt(): irq %d for unknown device.\n", irq); return COMPAT_IRQ_NONE; } lp = (struct Vmxnet_Private *)dev->priv; outl(VMXNET_CMD_INTR_ACK, dev->base_addr + VMXNET_COMMAND_ADDR); dd = lp->dd; dd->stats.interrupts++; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43) if (dev->interrupt) { printk(KERN_DEBUG "%s: Re-entering the interrupt handler.\n", dev->name); } dev->interrupt = 1; #endif vmxnet_rx(dev); if (lp->numTxPending > 0) { spin_lock(&lp->txLock); check_tx_queue(dev); spin_unlock(&lp->txLock); } if (compat_netif_queue_stopped(dev) && !lp->dd->txStopped) { compat_netif_wake_queue(dev); } #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43) dev->interrupt = 0; #endif return COMPAT_IRQ_HANDLED; } #ifdef VMW_HAVE_POLL_CONTROLLER /* *----------------------------------------------------------------------------- * * vmxnet_netpoll -- * * Poll network controller. We reuse hardware interrupt for this. * * Results: * None. * * Side effects: * Packets received/transmitted/whatever. * *----------------------------------------------------------------------------- */ static void vmxnet_netpoll(struct net_device *dev) { disable_irq(dev->irq); #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) vmxnet_interrupt(dev->irq, dev, NULL); #else vmxnet_interrupt(dev->irq, dev); #endif enable_irq(dev->irq); } #endif /* VMW_HAVE_POLL_CONTROLLER */ /* *----------------------------------------------------------------------------- * * vmxnet_close -- * * Network device stop (close) routine. Called by Linux when the * interface is brought down. * * Results: * 0 for success (always). * * Side effects: * Flushes pending transmits. Frees IRQs and shared memory area. * *----------------------------------------------------------------------------- */ static int vmxnet_close(struct net_device *dev) { unsigned int ioaddr = dev->base_addr; Vmxnet_Private *lp = (Vmxnet_Private *)dev->priv; int i; unsigned long flags; if (vmxnet_debug > 1) { printk(KERN_DEBUG "%s: Shutting down ethercard\n", dev->name); } #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43) dev->start = 0; #endif compat_netif_stop_queue(dev); lp->devOpen = FALSE; spin_lock_irqsave(&lp->txLock, flags); if (lp->numTxPending > 0) { //Wait absurdly long (2sec) for all the pending packets to be returned. printk(KERN_DEBUG "vmxnet_close: Pending tx = %d\n", lp->numTxPending); for (i = 0; i < 200 && lp->numTxPending > 0; i++) { outl(VMXNET_CMD_CHECK_TX_DONE, dev->base_addr + VMXNET_COMMAND_ADDR); udelay(10000); check_tx_queue(dev); } //This can happen when the related vmxnet device is disabled or when //something's wrong with the pNIC, or even both. //Will go ahead and free these skb's anyways (possibly dangerous, //but seems to work in practice) if (lp->numTxPending > 0) { printk(KERN_EMERG "vmxnet_close: Failed to finish all pending tx.\n" "Is the related vmxnet device disabled?\n" "This virtual machine may be in an inconsistent state.\n"); lp->numTxPending = 0; } } spin_unlock_irqrestore(&lp->txLock, flags); outl(0, ioaddr + VMXNET_INIT_ADDR); free_irq(dev->irq, dev); for (i = 0; i < lp->dd->txRingLength; i++) { if (lp->txBufInfo[i].skb != NULL && lp->txBufInfo[i].eop) { compat_dev_kfree_skb(lp->txBufInfo[i].skb, FREE_WRITE); lp->txBufInfo[i].skb = NULL; } } for (i = 0; i < lp->numRxBuffers; i++) { if (lp->rxSkbuff[i] != NULL) { compat_dev_kfree_skb(lp->rxSkbuff[i], FREE_WRITE); lp->rxSkbuff[i] = NULL; } } #ifdef VMXNET_DO_ZERO_COPY if (lp->jumboFrame || lp->lpd) { for (i = 0; i < lp->numRxBuffers2; i++) { if (lp->rxPages[i] != NULL) { pci_unmap_page(lp->pdev, lp->rxRing2[i].paddr, PAGE_SIZE, PCI_DMA_FROMDEVICE); put_page(lp->rxPages[i]); lp->rxPages[i] = NULL; } } } #endif COMPAT_NETDEV_MOD_DEC_USE_COUNT; return 0; } /* *----------------------------------------------------------------------------- * * vmxnet_load_multicast -- * * Load the multicast filter. * * Results: * return number of entries used to compute LADRF * * Side effects: * *----------------------------------------------------------------------------- */ static int vmxnet_load_multicast (struct net_device *dev) { Vmxnet_Private *lp = (Vmxnet_Private *) dev->priv; volatile u16 *mcast_table = (u16 *)lp->dd->LADRF; struct dev_mc_list *dmi = dev->mc_list; char *addrs; int i, j, bit, byte; u32 crc, poly = CRC_POLYNOMIAL_LE; /* clear the multicast filter */ lp->dd->LADRF[0] = 0; lp->dd->LADRF[1] = 0; /* Add addresses */ for (i = 0; i < dev->mc_count; i++){ addrs = dmi->dmi_addr; dmi = dmi->next; /* multicast address? */ if (!(*addrs & 1)) continue; crc = 0xffffffff; for (byte = 0; byte < 6; byte++) { for (bit = *addrs++, j = 0; j < 8; j++, bit >>= 1) { int test; test = ((bit ^ crc) & 0x01); crc >>= 1; if (test) { crc = crc ^ poly; } } } crc = crc >> 26; mcast_table [crc >> 4] |= 1 << (crc & 0xf); } return i; } /* *----------------------------------------------------------------------------- * * vmxnet_set_multicast_list -- * * Network device set_multicast_list routine. Called by Linux when the * set of addresses to listen to changes, including both the multicast * list and the broadcast, promiscuous, multicast, and allmulti flags. * * Results: * None. * * Side effects: * Informs lower layer of the changes. * *----------------------------------------------------------------------------- */ static void vmxnet_set_multicast_list(struct net_device *dev) { unsigned int ioaddr = dev->base_addr; Vmxnet_Private *lp = (Vmxnet_Private *)dev->priv; lp->dd->ifflags = ~(VMXNET_IFF_PROMISC |VMXNET_IFF_BROADCAST |VMXNET_IFF_MULTICAST); if (dev->flags & IFF_PROMISC) { printk(KERN_DEBUG "%s: Promiscuous mode enabled.\n", dev->name); lp->dd->ifflags |= VMXNET_IFF_PROMISC; } if (dev->flags & IFF_BROADCAST) { lp->dd->ifflags |= VMXNET_IFF_BROADCAST; } if (dev->flags & IFF_ALLMULTI) { lp->dd->LADRF[0] = 0xffffffff; lp->dd->LADRF[1] = 0xffffffff; lp->dd->ifflags |= VMXNET_IFF_MULTICAST; } else { if (vmxnet_load_multicast(dev)) { lp->dd->ifflags |= VMXNET_IFF_MULTICAST; } } outl(VMXNET_CMD_UPDATE_LADRF, ioaddr + VMXNET_COMMAND_ADDR); outl(VMXNET_CMD_UPDATE_IFF, ioaddr + VMXNET_COMMAND_ADDR); } /* *----------------------------------------------------------------------------- * * vmxnet_set_mac_address -- * * Network device set_mac_address routine. Called by Linux when someone * asks to change the interface's MAC address. * * Results: * 0 for success; -EBUSY if interface is up. * * Side effects: * *----------------------------------------------------------------------------- */ static int vmxnet_set_mac_address(struct net_device *dev, void *p) { struct sockaddr *addr=p; unsigned int ioaddr = dev->base_addr; int i; if (compat_netif_running(dev)) return -EBUSY; memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); for (i = 0; i < ETH_ALEN; i++) { outb(addr->sa_data[i], ioaddr + VMXNET_MAC_ADDR + i); } return 0; } /* *----------------------------------------------------------------------------- * * vmxnet_get_stats -- * * Network device get_stats routine. Called by Linux when interface * statistics are requested. * * Results: * Returns a pointer to our private stats structure. * * Side effects: * None. * *----------------------------------------------------------------------------- */ static struct net_device_stats * vmxnet_get_stats(struct net_device *dev) { Vmxnet_Private *lp = (Vmxnet_Private *)dev->priv; return &lp->stats; } module_init(vmxnet_init); module_exit(vmxnet_exit); MODULE_DEVICE_TABLE(pci, vmxnet_chips); /* Module information. */ MODULE_AUTHOR("VMware, Inc."); MODULE_DESCRIPTION("VMware Virtual Ethernet driver"); MODULE_LICENSE("GPL v2"); MODULE_VERSION(VMXNET_DRIVER_VERSION_STRING); /* * Starting with SLE10sp2, Novell requires that IHVs sign a support agreement * with them and mark their kernel modules as externally supported via a * change to the module header. If this isn't done, the module will not load * by default (i.e., neither mkinitrd nor modprobe will accept it). */ MODULE_INFO(supported, "external"); vmxnet-only/vmxnetInt.h0000444000000000000000000000724012025727017014225 0ustar rootroot/********************************************************* * Copyright (C) 1998 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #ifndef __VMXNETINT_H__ #define __VMXNETINT_H__ #define INCLUDE_ALLOW_MODULE #include "includeCheck.h" #define VMXNET_CHIP_NAME "vmxnet ether" #define CRC_POLYNOMIAL_LE 0xedb88320UL /* Ethernet CRC, little endian */ #define PKT_BUF_SZ 1536 #define VMXNET_MIN_MTU (ETH_MIN_FRAME_LEN - 14) #define VMXNET_MAX_MTU (16 * 1024 - 18) /* Largest address able to be shared between the driver and the device */ #define SHARED_MEM_MAX 0xFFFFFFFF typedef enum Vmxnet_TxStatus { VMXNET_CALL_TRANSMIT, VMXNET_DEFER_TRANSMIT, VMXNET_STOP_TRANSMIT } Vmxnet_TxStatus; #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)) # define MODULE_PARM(var, type) # define net_device_stats enet_statistics #endif #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,2,0)) # define le16_to_cpu(x) ((__u16)(x)) # define le32_to_cpu(x) ((__u32)(x)) #endif #if defined(BUG_ON) #define VMXNET_ASSERT(cond) BUG_ON(!(cond)) #else #define VMXNET_ASSERT(cond) #endif struct Vmxnet2_TxBuf { struct sk_buff *skb; char sgForLinear; /* the sg entry mapping the linear part * of the skb, -1 means this tx entry only * mapps the frags of the skb */ char firstSgForFrag; /* the first sg entry mapping the frags */ Bool eop; }; /* * Private data area, pointed to by priv field of our struct net_device. * dd field is shared with the lower layer. */ typedef struct Vmxnet_Private { Vmxnet2_DriverData *dd; const char *name; struct net_device_stats stats; struct sk_buff *rxSkbuff[ENHANCED_VMXNET2_MAX_NUM_RX_BUFFERS]; struct page *rxPages[VMXNET2_MAX_NUM_RX_BUFFERS2]; struct Vmxnet2_TxBuf txBufInfo[VMXNET2_MAX_NUM_TX_BUFFERS_TSO]; spinlock_t txLock; int numTxPending; unsigned int numRxBuffers; unsigned int numRxBuffers2; unsigned int numTxBuffers; Vmxnet2_RxRingEntry *rxRing; Vmxnet2_RxRingEntry *rxRing2; Vmxnet2_TxRingEntry *txRing; Bool devOpen; uint32 portID; uint32 capabilities; uint32 features; Bool zeroCopyTx; Bool partialHeaderCopyEnabled; Bool tso; Bool chainTx; Bool chainRx; Bool jumboFrame; Bool lpd; Bool morphed; // Indicates whether adapter is morphed void *ddAllocated; char *txBufferStartRaw; char *txBufferStart; struct pci_dev *pdev; struct timer_list linkCheckTimer; } Vmxnet_Private; #endif /* __VMXNETINT_H__ */ vmxnet-only/vmxnet_version.h0000444000000000000000000000222012025727017015310 0ustar rootroot/********************************************************* * Copyright (C) 2007 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ /* * vmxnet_version.h -- * * Version definitions for the Linux vmxnet driver. */ #ifndef _VMXNET_VERSION_H_ #define _VMXNET_VERSION_H_ #define VMXNET_DRIVER_VERSION 2.0.1.2 #define VMXNET_DRIVER_VERSION_COMMAS 2,0,1,2 #define VMXNET_DRIVER_VERSION_STRING "2.0.1.2" #endif /* _VMXNET_VERSION_H_ */ vmxnet-only/Makefile.kernel0000444000000000000000000000243412025727017014777 0ustar rootroot#!/usr/bin/make -f ########################################################## # Copyright (C) 1998 VMware, Inc. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation version 2 and no later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # ########################################################## #### #### VMware vmxnet Makefile to be distributed externally #### INCLUDE := -I. EXTRA_CFLAGS := $(CC_OPTS) $(INCLUDE) EXTRA_CFLAGS += $(call vm_check_build, $(SRCROOT)/autoconf/skblin.c, -DVMW_SKB_LINEARIZE_2618, ) obj-m += $(DRIVER).o clean: rm -rf $(wildcard $(DRIVER).mod.c $(DRIVER).ko .tmp_versions \ Module.symvers Modules.symvers Module.markers modules.order \ $(foreach dir,./,$(addprefix $(dir),.*.cmd .*.o.flags *.o))) vmxnet-only/Makefile.normal0000444000000000000000000000515112025727017015006 0ustar rootroot#!/usr/bin/make -f ########################################################## # Copyright (C) 1998 VMware, Inc. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation version 2 and no later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # ########################################################## #### #### VMware vmxnet Makefile to be distributed externally #### vm_check_build = $(shell if $(CC) $(CC_OPTS) $(INCLUDE) -Werror -S -o /dev/null -xc $(1) \ > /dev/null 2>&1; then echo "$(2)"; else echo "$(3)"; fi) DRIVERNAME = $(DRIVER)-$(VM_UNAME) ifneq (,$(filter x86_64%, $(shell $(CC) -dumpmachine))) MACHINE := x86_64 else MACHINE := x386 endif #### #### You must compile with at least -O level of optimization #### or the module won't load. #### If desparate, I think that bringing in might #### suffice. #### CC_WARNINGS := -Wall -Wstrict-prototypes # Don't use -pipe or egcs-2.91.66 (shipped with RedHat) will die CC_KFLAGS := -D__KERNEL__ -fno-strength-reduce -fno-omit-frame-pointer \ -fno-common -DKBUILD_MODNAME=$(DRIVER) CC_KFLAGS += $(call vm_check_gcc,-falign-loops=2 -falign-jumps=2 -falign-functions=2, \ -malign-loops=2 -malign-jumps=2 -malign-functions=2) CC_KFLAGS += $(call vm_check_gcc,-fno-strict-aliasing,) ifeq ($(MACHINE),x86_64) CC_KFLAGS += -mno-red-zone -mcmodel=kernel else # Gcc 3.0 deprecates -m486 --hpreg CC_KFLAGS += -DCPU=586 $(call check_gcc,-march=i586,-m486) endif CC_OPTS := -g3 -O2 -DMODULE $(GLOBAL_DEFS) $(CC_KFLAGS) $(CC_WARNINGS) INCLUDE := -I$(HEADER_DIR) INCLUDE += $(shell $(CC) $(CC_OPTS) $(INCLUDE) \ -E $(SRCROOT)/autoconf/geninclude.c \ | sed -n -e 's!^APATH!-I$(HEADER_DIR)/asm!p') CC_OPTS += $(call vm_check_build, $(SRCROOT)/autoconf/skblin.c, -DVMW_SKB_LINEARIZE_2618, ) OBJS := vmxnet.o CFLAGS := $(CC_OPTS) $(INCLUDE) LIBS := default: all all: ../$(DRIVER).o $(DRIVERNAME): $(OBJS) $(LD) -r -o $@ $^ $(DRIVER) ../$(DRIVER).o: $(DRIVERNAME) cp -f $< $@ auto-build: ../$(DRIVER).o clean: rm -f $(DRIVERNAME) ../$(DRIVERNAME) $(DRIVER) ../$(DRIVER).o $(DRIVER).o $(OBJS) .SILENT: vmxnet-only/README0000444000000000000000000000071412025727012012732 0ustar rootrootThe files in this directory are the source files for the VMware Virtual Ethernet Adapter driver. In order to build, make certain the Makefile is correct, especially about whether or not your system is multi-processor or not, and then just type: make from this directory. A copy of the module will be left in 'vmxnet.o', which can then be installed in /lib/modules//net. If you have any problems or questions, send mail to support@vmware.com vmxnet-only/Makefile0000444000000000000000000000726412025727017013526 0ustar rootroot#!/usr/bin/make -f ########################################################## # Copyright (C) 1998 VMware, Inc. All rights reserved. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation version 2 and no later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # ########################################################## #### #### VMware kernel module Makefile to be distributed externally #### #### #### SRCROOT _must_ be a relative path. #### SRCROOT = . VM_UNAME = $(shell uname -r) # Header directory for the running kernel HEADER_DIR = /lib/modules/$(VM_UNAME)/build/include BUILD_DIR = $(HEADER_DIR)/.. DRIVER := vmxnet PRODUCT := @PRODUCT@ # Grep program GREP = /bin/grep vm_check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null \ > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi) vm_check_file = $(shell if test -f $(1); then echo "yes"; else echo "no"; fi) ifndef VM_KBUILD VM_KBUILD := no ifeq ($(call vm_check_file,$(BUILD_DIR)/Makefile), yes) ifneq ($(call vm_check_file,$(BUILD_DIR)/Rules.make), yes) VM_KBUILD := 26 endif endif export VM_KBUILD endif ifndef VM_KBUILD_SHOWN ifeq ($(VM_KBUILD), no) VM_DUMMY := $(shell echo >&2 "Using standalone build system.") else ifeq ($(VM_KBUILD), 24) VM_DUMMY := $(shell echo >&2 "Using 2.4.x kernel build system.") else VM_DUMMY := $(shell echo >&2 "Using 2.6.x kernel build system.") endif endif VM_KBUILD_SHOWN := yes export VM_KBUILD_SHOWN endif ifneq ($(VM_KBUILD), no) VMCCVER := $(shell $(CC) -dumpversion) # If there is no version defined, we are in toplevel pass, not yet in kernel makefiles... ifeq ($(VERSION),) ifeq ($(VM_KBUILD), 24) DRIVER_KO := $(DRIVER).o else DRIVER_KO := $(DRIVER).ko endif .PHONY: $(DRIVER_KO) auto-build: $(DRIVER_KO) cp -f $< $(SRCROOT)/../$(DRIVER).o # $(DRIVER_KO) is a phony target, so compare file times explicitly $(DRIVER): $(DRIVER_KO) if [ $< -nt $@ ] || [ ! -e $@ ] ; then cp -f $< $@; fi # Pass gcc version down the chain, so we can detect if kernel attempts to use unapproved compiler VM_CCVER := $(VMCCVER) export VM_CCVER VM_CC := $(CC) export VM_CC MAKEOVERRIDES := $(filter-out CC=%,$(MAKEOVERRIDES)) # # Define a setup target that gets built before the actual driver. # This target may not be used at all, but if it is then it will be defined # in Makefile.kernel # prebuild:: ; postbuild:: ; $(DRIVER_KO): prebuild make -C $(BUILD_DIR) SUBDIRS=$$PWD SRCROOT=$$PWD/$(SRCROOT) modules make -C $$PWD SRCROOT=$$PWD/$(SRCROOT) postbuild endif vm_check_build = $(shell if $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) \ $(CPPFLAGS) $(CFLAGS) $(CFLAGS_KERNEL) $(LINUXINCLUDE) \ $(EXTRA_CFLAGS) -Iinclude2/asm/mach-default \ -DKBUILD_BASENAME=\"$(DRIVER)\" \ -Werror -S -o /dev/null -xc $(1) \ > /dev/null 2>&1; then echo "$(2)"; else echo "$(3)"; fi) CC_WARNINGS := -Wall -Wstrict-prototypes CC_OPTS := $(GLOBAL_DEFS) $(CC_WARNINGS) -DVMW_USING_KBUILD ifdef VMX86_DEVEL CC_OPTS += -DVMX86_DEVEL endif ifdef VMX86_DEBUG CC_OPTS += -DVMX86_DEBUG endif include $(SRCROOT)/Makefile.kernel ifdef TOPDIR ifeq ($(VM_KBUILD), 24) O_TARGET := $(DRIVER).o obj-y := $($(DRIVER)-y) include $(TOPDIR)/Rules.make endif endif else include $(SRCROOT)/Makefile.normal endif #.SILENT: vmxnet-only/COPYING0000444000000000000000000004310312025727012013104 0ustar rootroot GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License.