diff -urN ../linux-2.4.36-alb25.2/addons/vmxnet/autoconf/geninclude.c ./addons/vmxnet/autoconf/geninclude.c --- ../linux-2.4.36-alb25.2/addons/vmxnet/autoconf/geninclude.c 1970-01-01 01:00:00.000000000 +0100 +++ ./addons/vmxnet/autoconf/geninclude.c 2008-02-26 15:55:34.000000000 +0100 @@ -0,0 +1,40 @@ +/********************************************************* + * 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 + diff -urN ../linux-2.4.36-alb25.2/addons/vmxnet/autoconf/skblin.c ./addons/vmxnet/autoconf/skblin.c --- ../linux-2.4.36-alb25.2/addons/vmxnet/autoconf/skblin.c 1970-01-01 01:00:00.000000000 +0100 +++ ./addons/vmxnet/autoconf/skblin.c 2008-02-26 15:55:34.000000000 +0100 @@ -0,0 +1,41 @@ +/********************************************************* + * 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 diff -urN ../linux-2.4.36-alb25.2/addons/vmxnet/bpf_meta.h ./addons/vmxnet/bpf_meta.h --- ../linux-2.4.36-alb25.2/addons/vmxnet/bpf_meta.h 1970-01-01 01:00:00.000000000 +0100 +++ ./addons/vmxnet/bpf_meta.h 2008-02-26 15:55:34.000000000 +0100 @@ -0,0 +1,59 @@ +/********************************************************* + * 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 _BPF_META_H_ +#define _BPF_META_H_ + +/* This file is to be shared between vmxnet and afpacket */ + +/* The Control byte flags of bpf_meta_data */ + +#define VMXNET_BPF_PROCESSED 0x01 + +/* The following is the definition for dev feature bpf in linux */ + +#ifndef NETIF_F_BPF +#define NETIF_F_BPF (1<<31) /* BPF Capable Virtual Nic */ +#endif /* NETIF_F_BPF */ + + +/* TODO: These three definitions are picked up from vmkernel/public/net_pkt.h. + * Reorg the code and take this from a common place + */ + +#define MAX_BPF_FILTERS 8 /* Maximum number of Filters supported */ +typedef unsigned int BpfSnapLen; +typedef unsigned int BpfSnapLens[MAX_BPF_FILTERS]; + +/* + * skb->cb[40] maps to this structure. The bpf Trailer in vmxnet is stashed to + * this structure in skb. + * + */ + +struct BPF_MetaData { + + BpfSnapLens bpfSnapLens; /* 4 * 8 = 32 bytes of SnapLens as recved from VMK*/ + + unsigned char unused[7]; /* 7 bytes unused */ + + unsigned char controlByte; /* 1 used as controlbyte. For now indicates + whether VMK processed BPF or not*/ +}; + +#endif diff -urN ../linux-2.4.36-alb25.2/addons/vmxnet/compat_ethtool.h ./addons/vmxnet/compat_ethtool.h --- ../linux-2.4.36-alb25.2/addons/vmxnet/compat_ethtool.h 1970-01-01 01:00:00.000000000 +0100 +++ ./addons/vmxnet/compat_ethtool.h 2008-02-26 15:55:34.000000000 +0100 @@ -0,0 +1,54 @@ +/********************************************************* + * 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 */ diff -urN ../linux-2.4.36-alb25.2/addons/vmxnet/compat_highmem.h ./addons/vmxnet/compat_highmem.h --- ../linux-2.4.36-alb25.2/addons/vmxnet/compat_highmem.h 1970-01-01 01:00:00.000000000 +0100 +++ ./addons/vmxnet/compat_highmem.h 2008-02-26 15:55:34.000000000 +0100 @@ -0,0 +1,40 @@ +/********************************************************* + * 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__ */ diff -urN ../linux-2.4.36-alb25.2/addons/vmxnet/compat_init.h ./addons/vmxnet/compat_init.h --- ../linux-2.4.36-alb25.2/addons/vmxnet/compat_init.h 1970-01-01 01:00:00.000000000 +0100 +++ ./addons/vmxnet/compat_init.h 2008-02-26 15:55:34.000000000 +0100 @@ -0,0 +1,38 @@ +/********************************************************* + * 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__ */ diff -urN ../linux-2.4.36-alb25.2/addons/vmxnet/compat_interrupt.h ./addons/vmxnet/compat_interrupt.h --- ../linux-2.4.36-alb25.2/addons/vmxnet/compat_interrupt.h 1970-01-01 01:00:00.000000000 +0100 +++ ./addons/vmxnet/compat_interrupt.h 2008-02-26 15:55:34.000000000 +0100 @@ -0,0 +1,50 @@ +/********************************************************* + * 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 + + +#endif /* __COMPAT_INTERRUPT_H__ */ diff -urN ../linux-2.4.36-alb25.2/addons/vmxnet/compat_ioport.h ./addons/vmxnet/compat_ioport.h --- ../linux-2.4.36-alb25.2/addons/vmxnet/compat_ioport.h 1970-01-01 01:00:00.000000000 +0100 +++ ./addons/vmxnet/compat_ioport.h 2008-02-26 15:55:34.000000000 +0100 @@ -0,0 +1,40 @@ +/********************************************************* + * 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 + + +#endif /* __COMPAT_IOPORT_H__ */ diff -urN ../linux-2.4.36-alb25.2/addons/vmxnet/compat_module.h ./addons/vmxnet/compat_module.h --- ../linux-2.4.36-alb25.2/addons/vmxnet/compat_module.h 1970-01-01 01:00:00.000000000 +0100 +++ ./addons/vmxnet/compat_module.h 2008-02-26 15:55:34.000000000 +0100 @@ -0,0 +1,72 @@ +/********************************************************* + * 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__ */ diff -urN ../linux-2.4.36-alb25.2/addons/vmxnet/compat_netdevice.h ./addons/vmxnet/compat_netdevice.h --- ../linux-2.4.36-alb25.2/addons/vmxnet/compat_netdevice.h 1970-01-01 01:00:00.000000000 +0100 +++ ./addons/vmxnet/compat_netdevice.h 2008-02-26 15:55:34.000000000 +0100 @@ -0,0 +1,173 @@ +/********************************************************* + * 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 + +/* + * 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 + + +#endif /* __COMPAT_NETDEVICE_H__ */ diff -urN ../linux-2.4.36-alb25.2/addons/vmxnet/compat_pci.h ./addons/vmxnet/compat_pci.h --- ../linux-2.4.36-alb25.2/addons/vmxnet/compat_pci.h 1970-01-01 01:00:00.000000000 +0100 +++ ./addons/vmxnet/compat_pci.h 2008-02-26 15:55:34.000000000 +0100 @@ -0,0 +1,441 @@ +/********************************************************* + * 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 +#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 + + +#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_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 + +#endif /* __COMPAT_PCI_H__ */ diff -urN ../linux-2.4.36-alb25.2/addons/vmxnet/compat_skbuff.h ./addons/vmxnet/compat_skbuff.h --- ../linux-2.4.36-alb25.2/addons/vmxnet/compat_skbuff.h 1970-01-01 01:00:00.000000000 +0100 +++ ./addons/vmxnet/compat_skbuff.h 2008-02-26 15:55:34.000000000 +0100 @@ -0,0 +1,89 @@ +/********************************************************* + * 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) +# else +# define compat_skb_linearize(skb) skb_linearize((skb), GFP_ATOMIC) +# 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 + +#endif /* __COMPAT_SKBUFF_H__ */ diff -urN ../linux-2.4.36-alb25.2/addons/vmxnet/compat_slab.h ./addons/vmxnet/compat_slab.h --- ../linux-2.4.36-alb25.2/addons/vmxnet/compat_slab.h 1970-01-01 01:00:00.000000000 +0100 +++ ./addons/vmxnet/compat_slab.h 2008-02-26 15:55:34.000000000 +0100 @@ -0,0 +1,70 @@ +/********************************************************* + * 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... + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) && !defined(VMW_KMEMCR_CTOR_HAS_3_ARGS) +# define VMW_KMEMCR_CTOR_HAS_3_ARGS +#endif +#ifdef VMW_KMEMCR_CTOR_HAS_3_ARGS +typedef void compat_kmem_cache_ctor(void *, compat_kmem_cache *, unsigned long); +#else +typedef void compat_kmem_cache_ctor(compat_kmem_cache *, void *); +#endif + +#endif /* __COMPAT_SLAB_H__ */ diff -urN ../linux-2.4.36-alb25.2/addons/vmxnet/compat_spinlock.h ./addons/vmxnet/compat_spinlock.h --- ../linux-2.4.36-alb25.2/addons/vmxnet/compat_spinlock.h 1970-01-01 01:00:00.000000000 +0100 +++ ./addons/vmxnet/compat_spinlock.h 2008-02-26 15:55:34.000000000 +0100 @@ -0,0 +1,68 @@ +/********************************************************* + * 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__ */ diff -urN ../linux-2.4.36-alb25.2/addons/vmxnet/compat_timer.h ./addons/vmxnet/compat_timer.h --- ../linux-2.4.36-alb25.2/addons/vmxnet/compat_timer.h 1970-01-01 01:00:00.000000000 +0100 +++ ./addons/vmxnet/compat_timer.h 2008-02-26 15:55:34.000000000 +0100 @@ -0,0 +1,95 @@ +/********************************************************* + * 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) +#else +# include +/* + * msecs_to_jiffies appeared in 2.6.7. 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, 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); +} +#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__ */ diff -urN ../linux-2.4.36-alb25.2/addons/vmxnet/compat_version.h ./addons/vmxnet/compat_version.h --- ../linux-2.4.36-alb25.2/addons/vmxnet/compat_version.h 1970-01-01 01:00:00.000000000 +0100 +++ ./addons/vmxnet/compat_version.h 2008-02-26 15:55:34.000000000 +0100 @@ -0,0 +1,121 @@ +/********************************************************* + * 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__ */ diff -urN ../linux-2.4.36-alb25.2/addons/vmxnet/COPYING ./addons/vmxnet/COPYING --- ../linux-2.4.36-alb25.2/addons/vmxnet/COPYING 1970-01-01 01:00:00.000000000 +0100 +++ ./addons/vmxnet/COPYING 2008-02-26 15:55:34.000000000 +0100 @@ -0,0 +1,339 @@ + 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. diff -urN ../linux-2.4.36-alb25.2/addons/vmxnet/driver-config.h ./addons/vmxnet/driver-config.h --- ../linux-2.4.36-alb25.2/addons/vmxnet/driver-config.h 1970-01-01 01:00:00.000000000 +0100 +++ ./addons/vmxnet/driver-config.h 2008-02-26 15:55:34.000000000 +0100 @@ -0,0 +1,78 @@ +/********************************************************* + * 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 diff -urN ../linux-2.4.36-alb25.2/addons/vmxnet/includeCheck.h ./addons/vmxnet/includeCheck.h --- ../linux-2.4.36-alb25.2/addons/vmxnet/includeCheck.h 1970-01-01 01:00:00.000000000 +0100 +++ ./addons/vmxnet/includeCheck.h 2008-02-26 15:55:34.000000000 +0100 @@ -0,0 +1,132 @@ +/********************************************************* + * 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 diff -urN ../linux-2.4.36-alb25.2/addons/vmxnet/Makefile ./addons/vmxnet/Makefile --- ../linux-2.4.36-alb25.2/addons/vmxnet/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ ./addons/vmxnet/Makefile 2008-02-26 15:55:34.000000000 +0100 @@ -0,0 +1,148 @@ +#!/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 + +# 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 $@ ]; 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)) + +$(DRIVER_KO): + make -C $(BUILD_DIR) SUBDIRS=$$PWD SRCROOT=$$PWD/$(SRCROOT) modules + +else + +ifneq ($(VM_CCVER), $(VMCCVER)) +$(warning *** Inappropriate build environment: you wanted to use gcc \ + version $(VM_CCVER) while kernel attempts to use gcc version $(VMCCVER).) +$(error For proper build you'll have to replace $(CC) with symbolic \ + link to $(VM_CC)) +endif + +endif + +vm_check_build = $(shell if $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) \ + $(CPPFLAGS) $(CFLAGS) $(CFLAGS_KERNEL) \ + $(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: diff -urN ../linux-2.4.36-alb25.2/addons/vmxnet/Makefile.kernel ./addons/vmxnet/Makefile.kernel --- ../linux-2.4.36-alb25.2/addons/vmxnet/Makefile.kernel 1970-01-01 01:00:00.000000000 +0100 +++ ./addons/vmxnet/Makefile.kernel 2008-02-26 15:55:34.000000000 +0100 @@ -0,0 +1,35 @@ +#!/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 \ + $(foreach dir,./,$(addprefix $(dir),.*.cmd .*.o.flags *.o))) diff -urN ../linux-2.4.36-alb25.2/addons/vmxnet/Makefile.normal ./addons/vmxnet/Makefile.normal --- ../linux-2.4.36-alb25.2/addons/vmxnet/Makefile.normal 1970-01-01 01:00:00.000000000 +0100 +++ ./addons/vmxnet/Makefile.normal 2008-02-26 15:55:34.000000000 +0100 @@ -0,0 +1,86 @@ +#!/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: diff -urN ../linux-2.4.36-alb25.2/addons/vmxnet/net.h ./addons/vmxnet/net.h --- ../linux-2.4.36-alb25.2/addons/vmxnet/net.h 1970-01-01 01:00:00.000000000 +0100 +++ ./addons/vmxnet/net.h 2008-02-26 15:55:34.000000000 +0100 @@ -0,0 +1,75 @@ +/********************************************************* + * 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 + +#endif // VMWARE_DEVICES_NET_H + diff -urN ../linux-2.4.36-alb25.2/addons/vmxnet/net_sg.h ./addons/vmxnet/net_sg.h --- ../linux-2.4.36-alb25.2/addons/vmxnet/net_sg.h 1970-01-01 01:00:00.000000000 +0100 +++ ./addons/vmxnet/net_sg.h 2008-02-26 15:55:34.000000000 +0100 @@ -0,0 +1,73 @@ +/********************************************************* + * 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 diff -urN ../linux-2.4.36-alb25.2/addons/vmxnet/README ./addons/vmxnet/README --- ../linux-2.4.36-alb25.2/addons/vmxnet/README 1970-01-01 01:00:00.000000000 +0100 +++ ./addons/vmxnet/README 2008-02-26 15:55:34.000000000 +0100 @@ -0,0 +1,11 @@ +The 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 diff -urN ../linux-2.4.36-alb25.2/addons/vmxnet/vm_basic_types.h ./addons/vmxnet/vm_basic_types.h --- ../linux-2.4.36-alb25.2/addons/vmxnet/vm_basic_types.h 1970-01-01 01:00:00.000000000 +0100 +++ ./addons/vmxnet/vm_basic_types.h 2008-02-26 15:55:34.000000000 +0100 @@ -0,0 +1,834 @@ +/********************************************************* + * Copyright (C) 1998-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 + * + *********************************************************/ + +/* + * + * 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(-1) + + +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 + +/* world page number */ +typedef uint32 WPN; + +/* The Xserver source compiles with -ansi -pendantic */ +#ifndef __STRICT_ANSI__ +typedef uint64 MA; +typedef uint32 MPN; +#endif + +/* + * 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. */ +#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)0x0fffffff) /* Maximal observable PPN value. */ +#define INVALID_PPN ((PPN)-1) + +#define INVALID_BPN ((BPN) 0x3fffffff) /* BPNs don't use the high two bits. */ + +#define INVALID_MPN ((MPN)-1) +#define MEMREF_MPN ((MPN)-2) +#define RESERVED_MPN ((MPN) 0) +/* Support 39 bits of address space, minus one page. */ +#define MAX_MPN ((MPN) 0x07ffffff) + +#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 + +/* + * 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 + +/* + * __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 + +#endif /* _VM_BASIC_TYPES_H_ */ diff -urN ../linux-2.4.36-alb25.2/addons/vmxnet/vm_device_version.h ./addons/vmxnet/vm_device_version.h --- ../linux-2.4.36-alb25.2/addons/vmxnet/vm_device_version.h 1970-01-01 01:00:00.000000000 +0100 +++ ./addons/vmxnet/vm_device_version.h 2008-02-26 15:55:34.000000000 +0100 @@ -0,0 +1,179 @@ +/********************************************************* + * 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 + +/* 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 + +/************* 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 + +/************* 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 */ diff -urN ../linux-2.4.36-alb25.2/addons/vmxnet/vmnet_def.h ./addons/vmxnet/vmnet_def.h --- ../linux-2.4.36-alb25.2/addons/vmxnet/vmnet_def.h 1970-01-01 01:00:00.000000000 +0100 +++ ./addons/vmxnet/vmnet_def.h 2008-02-26 15:55:34.000000000 +0100 @@ -0,0 +1,60 @@ +/********************************************************* + * 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 */ +#endif // _VMNET_DEF_H_ diff -urN ../linux-2.4.36-alb25.2/addons/vmxnet/vmxnet2_def.h ./addons/vmxnet/vmxnet2_def.h --- ../linux-2.4.36-alb25.2/addons/vmxnet/vmxnet2_def.h 1970-01-01 01:00:00.000000000 +0100 +++ ./addons/vmxnet/vmxnet2_def.h 2008-02-26 15:55:34.000000000 +0100 @@ -0,0 +1,415 @@ +/********************************************************* + * 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 2nd rx ring */ +#define VMXNET2_MAX_NUM_RX_BUFFERS2 512 +#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 + +#ifdef BPF_SUPPORT_ENABLED +#define VMXNET2_RX_BPF_TRAILER 0x08 +#endif /* BPF_SUPPORT_ENABLED */ + +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 + diff -urN ../linux-2.4.36-alb25.2/addons/vmxnet/vmxnet.c ./addons/vmxnet/vmxnet.c --- ../linux-2.4.36-alb25.2/addons/vmxnet/vmxnet.c 1970-01-01 01:00:00.000000000 +0100 +++ ./addons/vmxnet/vmxnet.c 2008-02-26 15:55:34.000000000 +0100 @@ -0,0 +1,2407 @@ +/********************************************************* + * 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 "compat_timer.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_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" + +#ifdef BPF_SUPPORT_ENABLED +#include "bpf_meta.h" +#include "compat_highmem.h" +#endif + +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_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 + + +/* + *---------------------------------------------------------------------------- + * + * 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; +} + + +/* + *----------------------------------------------------------------------------- + * + * 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) +{ + 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; + unsigned int numTxBuffers, maxNumTxBuffers, defNumTxBuffers; + Bool morphed = 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)) { + lp->lpd = TRUE; + printk(" lpd"); + } +#endif +#endif + +#ifdef BPF_SUPPORT_ENABLED + if(lp->capabilities & VMNET_CAP_BPF && + lp->features & VMXNET_FEATURE_BPF) { + dev->features |= NETIF_F_BPF; + printk(" bpf"); + } +#endif + + + + printk("\n"); + + /* determine rx/tx ring sizes */ + 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 > VMXNET2_MAX_NUM_RX_BUFFERS) { + numRxBuffers = VMXNET2_DEFAULT_NUM_RX_BUFFERS; + } + + if (lp->jumboFrame || lp->lpd) { + numRxBuffers2 = numRxBuffers * 4; + } else { + numRxBuffers2 = 1; + } + + 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; + dev->do_ioctl = vmxnet_ioctl; + + 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; + 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 (netif_queue_stopped(dev)) { + 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; + 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; + 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_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; + +#ifdef BPF_SUPPORT_ENABLED + struct BPF_MetaData *meta = NULL; +#endif + + 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; + } +#ifdef BPF_SUPPORT_ENABLED + + meta = (struct BPF_MetaData *)skb->cb; + + if(rre->flags & VMXNET2_RX_BPF_TRAILER) { + char *vaddr; + int numFrags = skb_shinfo(skb)->nr_frags; + + if (numFrags > 0) { + + /* If fragments are present, the trailer is present in the + * last fragement. Map it and remove the trailer + */ + vaddr = kmap_atomic(skb_shinfo(skb)->frags[numFrags - 1].page, + KM_USER0); + if (vaddr) { + + memcpy(meta->bpfSnapLens, + vaddr + skb_shinfo(skb)->frags[numFrags-1].size, + sizeof meta->bpfSnapLens); + kunmap_atomic((struct page *)vaddr, KM_USER0); + + } else { + printk(KERN_ERR"Error mapping Last Fragment of Packet\n"); + /* Act as if there was no bpf trailer at all*/ + meta->controlByte = 0; + goto error; + } + } else { + + /* The trailer is present in the linear data array */ + + vaddr = (char *)skb->data; + + memcpy(meta->bpfSnapLens, vaddr + skb->len, + sizeof meta->bpfSnapLens); + } + + meta->controlByte |= VMXNET_BPF_PROCESSED; + + } else { + meta->controlByte = 0; + } +error: +#endif + + 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 (netif_queue_stopped(dev) && !lp->dd->txStopped) { + 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 + + 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 (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); diff -urN ../linux-2.4.36-alb25.2/addons/vmxnet/vmxnet_def.h ./addons/vmxnet/vmxnet_def.h --- ../linux-2.4.36-alb25.2/addons/vmxnet/vmxnet_def.h 1970-01-01 01:00:00.000000000 +0100 +++ ./addons/vmxnet/vmxnet_def.h 2008-02-26 15:55:34.000000000 +0100 @@ -0,0 +1,201 @@ +/********************************************************* + * 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 VMXNET_FEATURE_BPF 0x10 + +/* + * 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_FEATURE_BPF_CAPS VMNET_CAP_BPF + +#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; + + +/* + * Max number of packet patterns in a single filter & maximum packet size + * that can match a filter. Used by vmxnet wake-on-packet-pattern-receive. + */ + +#define MAX_NUM_FILTER_PTTRNS 6 +#define MAX_PKT_FILTER_SIZE 128 + + +/* + * 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; + + +/* + * Representation for packet filter pattern set, needs to fit w/i an MPN + */ + +typedef struct Vmxnet_PttrnBytes { + uint8 byteOff; /* offset within packet of pattern byte */ + uint8 byteVal; /* value of pattern byte within packet */ +} Vmxnet_PttrnBytes; + +typedef struct Vmxnet_PktFltrPttrns { + uint8 prevCmd; /* to check sanity of VMXNET_PM_OPCODE_START..END sequence */ + uint8 nmPttrns; /* count patterns 1..MAX_NUM_FILTER_PTTRNS */ + uint8 nmPttrnBytes[MAX_NUM_FILTER_PTTRNS]; /* 1..MAX_PKT_FILTER_SIZE */ + Vmxnet_PttrnBytes pttrnBytes[MAX_NUM_FILTER_PTTRNS][MAX_PKT_FILTER_SIZE]; +} Vmxnet_PktFltrPttrns; + +#endif /* _VMXNET_DEF_H_ */ + + diff -urN ../linux-2.4.36-alb25.2/addons/vmxnet/vmxnetInt.h ./addons/vmxnet/vmxnetInt.h --- ../linux-2.4.36-alb25.2/addons/vmxnet/vmxnetInt.h 1970-01-01 01:00:00.000000000 +0100 +++ ./addons/vmxnet/vmxnetInt.h 2008-02-26 15:55:34.000000000 +0100 @@ -0,0 +1,172 @@ +/********************************************************* + * 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,3,14)) +# define net_device device +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43)) +static inline void +netif_start_queue(struct device *dev) +{ + clear_bit(0, &dev->tbusy); +} + +static inline void +netif_stop_queue(struct device *dev) +{ + set_bit(0, &dev->tbusy); +} + +static inline int +netif_queue_stopped(struct device *dev) +{ + return test_bit(0, &dev->tbusy); +} + +static inline void +netif_wake_queue(struct device *dev) +{ + clear_bit(0, &dev->tbusy); + mark_bh(NET_BH); +} + +static inline int +netif_running(struct device *dev) +{ + return dev->start == 0; +} +#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 (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 + +#if defined(BUG_ON) +#define VMXNET_ASSERT(cond) BUG_ON(!(cond)) +#else +#define VMXNET_ASSERT(cond) +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) && defined(CHECKSUM_HW) +# define VM_CHECKSUM_PARTIAL CHECKSUM_HW +# define VM_CHECKSUM_UNNECESSARY CHECKSUM_UNNECESSARY +#else +# define VM_CHECKSUM_PARTIAL CHECKSUM_PARTIAL +# define VM_CHECKSUM_UNNECESSARY CHECKSUM_UNNECESSARY +#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[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__ */ diff -urN ../linux-2.4.36-alb25.2/addons/vmxnet/vmxnet_version.h ./addons/vmxnet/vmxnet_version.h --- ../linux-2.4.36-alb25.2/addons/vmxnet/vmxnet_version.h 1970-01-01 01:00:00.000000000 +0100 +++ ./addons/vmxnet/vmxnet_version.h 2008-02-26 15:55:34.000000000 +0100 @@ -0,0 +1,32 @@ +/********************************************************* + * 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.0 +#define VMXNET_DRIVER_VERSION_COMMAS 2,0,1,0 +#define VMXNET_DRIVER_VERSION_STRING "2.0.1.0" + +#endif /* _VMXNET_VERSION_H_ */