[eth6] Add first version of ipoib NDIS 6.0 driver.
authortzachid <tzachid@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Tue, 23 Jun 2009 15:58:00 +0000 (15:58 +0000)
committertzachid <tzachid@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Tue, 23 Jun 2009 15:58:00 +0000 (15:58 +0000)
Signed off by: xalex@mellanox.co.il

git-svn-id: svn://openib.tc.cornell.edu/gen1/trunk@2263 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

49 files changed:
ulp/ipoib/kernel6/SOURCES [new file with mode: 0644]
ulp/ipoib/kernel6/ipoib.cdf [new file with mode: 0644]
ulp/ipoib/kernel6/ipoib.rc [new file with mode: 0644]
ulp/ipoib/kernel6/ipoib32-xp.cdf [new file with mode: 0644]
ulp/ipoib/kernel6/ipoib32.cdf [new file with mode: 0644]
ulp/ipoib/kernel6/ipoib_adapter.c [new file with mode: 0644]
ulp/ipoib/kernel6/ipoib_adapter.h [new file with mode: 0644]
ulp/ipoib/kernel6/ipoib_cm.c [new file with mode: 0644]
ulp/ipoib/kernel6/ipoib_debug.h [new file with mode: 0644]
ulp/ipoib/kernel6/ipoib_driver.c [new file with mode: 0644]
ulp/ipoib/kernel6/ipoib_driver.h [new file with mode: 0644]
ulp/ipoib/kernel6/ipoib_endpoint.c [new file with mode: 0644]
ulp/ipoib/kernel6/ipoib_endpoint.h [new file with mode: 0644]
ulp/ipoib/kernel6/ipoib_ibat.c [new file with mode: 0644]
ulp/ipoib/kernel6/ipoib_ibat.h [new file with mode: 0644]
ulp/ipoib/kernel6/ipoib_log.mc [new file with mode: 0644]
ulp/ipoib/kernel6/ipoib_port.c [new file with mode: 0644]
ulp/ipoib/kernel6/ipoib_port.h [new file with mode: 0644]
ulp/ipoib/kernel6/ipoib_xfr_mgr.c [new file with mode: 0644]
ulp/ipoib/kernel6/ipoib_xfr_mgr.h [new file with mode: 0644]
ulp/ipoib/kernel6/makefile [new file with mode: 0644]
ulp/ipoib/kernel6/makefile.inc [new file with mode: 0644]
ulp/ipoib/kernel6/netipoib-xp32.inf [new file with mode: 0644]
ulp/ipoib/kernel6/netipoib.inx [new file with mode: 0644]
ulp/ipoib/kernel6/offload.h [new file with mode: 0644]
ulp/ipoib_NDIS6_CM/dirs [new file with mode: 0644]
ulp/ipoib_NDIS6_CM/ip_stats.h [new file with mode: 0644]
ulp/ipoib_NDIS6_CM/kernel/SOURCES [new file with mode: 0644]
ulp/ipoib_NDIS6_CM/kernel/ipoib.cdf [new file with mode: 0644]
ulp/ipoib_NDIS6_CM/kernel/ipoib.rc [new file with mode: 0644]
ulp/ipoib_NDIS6_CM/kernel/ipoib32.cdf [new file with mode: 0644]
ulp/ipoib_NDIS6_CM/kernel/ipoib_adapter.c [new file with mode: 0644]
ulp/ipoib_NDIS6_CM/kernel/ipoib_adapter.h [new file with mode: 0644]
ulp/ipoib_NDIS6_CM/kernel/ipoib_debug.h [new file with mode: 0644]
ulp/ipoib_NDIS6_CM/kernel/ipoib_driver.c [new file with mode: 0644]
ulp/ipoib_NDIS6_CM/kernel/ipoib_driver.h [new file with mode: 0644]
ulp/ipoib_NDIS6_CM/kernel/ipoib_endpoint.c [new file with mode: 0644]
ulp/ipoib_NDIS6_CM/kernel/ipoib_endpoint.h [new file with mode: 0644]
ulp/ipoib_NDIS6_CM/kernel/ipoib_ibat.c [new file with mode: 0644]
ulp/ipoib_NDIS6_CM/kernel/ipoib_ibat.h [new file with mode: 0644]
ulp/ipoib_NDIS6_CM/kernel/ipoib_log.mc [new file with mode: 0644]
ulp/ipoib_NDIS6_CM/kernel/ipoib_port.c [new file with mode: 0644]
ulp/ipoib_NDIS6_CM/kernel/ipoib_port.h [new file with mode: 0644]
ulp/ipoib_NDIS6_CM/kernel/ipoib_xfr_mgr.c [new file with mode: 0644]
ulp/ipoib_NDIS6_CM/kernel/ipoib_xfr_mgr.h [new file with mode: 0644]
ulp/ipoib_NDIS6_CM/kernel/makefile [new file with mode: 0644]
ulp/ipoib_NDIS6_CM/kernel/makefile.inc [new file with mode: 0644]
ulp/ipoib_NDIS6_CM/kernel/netipoib.inx [new file with mode: 0644]
ulp/ipoib_NDIS6_CM/kernel/offload.h [new file with mode: 0644]

diff --git a/ulp/ipoib/kernel6/SOURCES b/ulp/ipoib/kernel6/SOURCES
new file mode 100644 (file)
index 0000000..a528904
--- /dev/null
@@ -0,0 +1,59 @@
+TARGETNAME=ipoib\r
+TARGETPATH=..\..\..\bin\kernel\obj$(BUILD_ALT_DIR)\r
+TARGETTYPE=DRIVER\r
+\r
+!if $(_NT_TOOLS_VERSION) != 0x700\r
+# WDK build only - transform .inx --> .inf adding date & version stamp.\r
+# see .\makefile.inc\r
+INF_NAME=netipoib\r
+INF_TARGET=..\..\..\bin\kernel\$(O)\$(INF_NAME).inf\r
+NTTARGETFILES=$(INF_TARGET)\r
+!endif\r
+\r
+!if $(FREEBUILD)\r
+ENABLE_EVENT_TRACING=1\r
+!else\r
+#ENABLE_EVENT_TRACING=1\r
+!endif\r
+\r
+\r
+SOURCES=       ipoib_log.mc \\r
+               ipoib.rc \\r
+               ipoib_driver.c \\r
+               ipoib_adapter.c \\r
+               ipoib_endpoint.c \\r
+               ipoib_port.c \\r
+               ipoib_ibat.c \\r
+#              ipoib_cm.c      \\r
+               ipoib_xfr_mgr.c\r
+\r
+INCLUDES=..;..\..\..\inc;..\..\..\inc\kernel;\r
+\r
+C_DEFINES=$(C_DEFINES) -DNDIS_MINIPORT_DRIVER -DNDIS_WDM=1 \\r
+       -DDEPRECATE_DDK_FUNCTIONS -DNDIS60_MINIPORT=1 -DNEED_CL_OBJ -DBINARY_COMPATIBLE=0 -DVER_FILEREV=42\r
+\r
+TARGETLIBS= \\r
+       $(TARGETPATH)\*\complib.lib \\r
+       $(DDK_LIB_PATH)\ndis.lib \\r
+       $(DDK_LIB_PATH)\ntstrsafe.lib \\r
+       $(DDK_LIB_PATH)\strsafe.lib\r
+\r
+!if !defined(DDK_TARGET_OS) || "$(DDK_TARGET_OS)"=="Win2K"\r
+#\r
+# The driver is built in the Win2K build environment\r
+# - use the library version of safe strings \r
+#\r
+#TARGETLIBS= $(TARGETLIBS) $(DDK_LIB_PATH)\ntstrsafe.lib\r
+!endif\r
+\r
+!IFDEF ENABLE_EVENT_TRACING\r
+\r
+C_DEFINES = $(C_DEFINES) -DEVENT_TRACING\r
+\r
+RUN_WPP = $(SOURCES) -km -ext: .c .h .C .H \\r
+       -scan:ipoib_debug.h \\r
+       -func:IPOIB_PRINT(LEVEL,FLAGS,(MSG,...)) \\r
+       -func:IPOIB_PRINT_EXIT(LEVEL,FLAGS,(MSG,...))\r
+!ENDIF\r
+\r
+MSC_WARNING_LEVEL= /W4\r
diff --git a/ulp/ipoib/kernel6/ipoib.cdf b/ulp/ipoib/kernel6/ipoib.cdf
new file mode 100644 (file)
index 0000000..eb21da9
--- /dev/null
@@ -0,0 +1,13 @@
+[CatalogHeader]\r
+Name=ipoib.cat\r
+PublicVersion=0x0000001\r
+EncodingType=0x00010001\r
+CATATTR1=0x10010001:OSAttr:2:6.0\r
+[CatalogFiles]\r
+<hash>netipoib.inf=netipoib.inf\r
+<hash>ipoib.sys=ipoib.sys\r
+<hash>ibwsd.dll=ibwsd.dll\r
+<hash>ibwsd32.dll=ibwsd32.dll\r
+<hash>ibndprov.dll=ibndprov.dll\r
+<hash>ibndprov32.dll=ibndprov32.dll\r
+<hash>ndinstall.exe=ndinstall.exe\r
diff --git a/ulp/ipoib/kernel6/ipoib.rc b/ulp/ipoib/kernel6/ipoib.rc
new file mode 100644 (file)
index 0000000..330f19e
--- /dev/null
@@ -0,0 +1,48 @@
+/*\r
+ * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.\r
+ *\r
+ * This software is available to you under the OpenIB.org BSD license\r
+ * below:\r
+ *\r
+ *     Redistribution and use in source and binary forms, with or\r
+ *     without modification, are permitted provided that the following\r
+ *     conditions are met:\r
+ *\r
+ *      - Redistributions of source code must retain the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer.\r
+ *\r
+ *      - Redistributions in binary form must reproduce the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer in the documentation and/or other materials\r
+ *        provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ * $Id: ipoib.rc 1611 2006-08-20 14:48:55Z sleybo $\r
+ */\r
+\r
+\r
+#include <oib_ver.h>\r
+\r
+#define VER_FILETYPE                           VFT_DRV\r
+#define VER_FILESUBTYPE                                VFT2_UNKNOWN\r
+\r
+#ifdef _DEBUG_\r
+#define VER_FILEDESCRIPTION_STR                "IP over InfiniBand NDIS Miniport (Debug)"\r
+#else\r
+#define VER_FILEDESCRIPTION_STR                "IP over InfiniBand NDIS Miniport"\r
+#endif\r
+\r
+#define VER_INTERNALNAME_STR           "ipoib.sys"\r
+#define VER_ORIGINALFILENAME_STR       "ipoib.sys"\r
+\r
+#include <common.ver>\r
+#include "ipoib_log.rc"\r
diff --git a/ulp/ipoib/kernel6/ipoib32-xp.cdf b/ulp/ipoib/kernel6/ipoib32-xp.cdf
new file mode 100644 (file)
index 0000000..faf8ea6
--- /dev/null
@@ -0,0 +1,10 @@
+[CatalogHeader]\r
+Name=ipoib.cat\r
+PublicVersion=0x0000001\r
+EncodingType=0x00010001\r
+CATATTR1=0x10010001:OSAttr:2:6.0\r
+[CatalogFiles]\r
+<hash>netipoib.inf=netipoib.inf\r
+<hash>ipoib.sys=ipoib.sys\r
+<hash>ibndprov.dll=ibndprov.dll\r
+<hash>ndinstall.exe=ndinstall.exe\r
diff --git a/ulp/ipoib/kernel6/ipoib32.cdf b/ulp/ipoib/kernel6/ipoib32.cdf
new file mode 100644 (file)
index 0000000..50225ba
--- /dev/null
@@ -0,0 +1,11 @@
+[CatalogHeader]\r
+Name=ipoib.cat\r
+PublicVersion=0x0000001\r
+EncodingType=0x00010001\r
+CATATTR1=0x10010001:OSAttr:2:6.0\r
+[CatalogFiles]\r
+<hash>netipoib.inf=netipoib.inf\r
+<hash>ipoib.sys=ipoib.sys\r
+<hash>ibwsd.dll=ibwsd.dll\r
+<hash>ibndprov.dll=ibndprov.dll\r
+<hash>ndinstall.exe=ndinstall.exe\r
diff --git a/ulp/ipoib/kernel6/ipoib_adapter.c b/ulp/ipoib/kernel6/ipoib_adapter.c
new file mode 100644 (file)
index 0000000..78eff26
--- /dev/null
@@ -0,0 +1,1632 @@
+/*\r
+ * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.\r
+ * Copyright (c) 2006 Mellanox Technologies.  All rights reserved.\r
+ * Portions Copyright (c) 2008 Microsoft Corporation.  All rights reserved.\r
+ *\r
+ * This software is available to you under the OpenIB.org BSD license\r
+ * below:\r
+ *\r
+ *     Redistribution and use in source and binary forms, with or\r
+ *     without modification, are permitted provided that the following\r
+ *     conditions are met:\r
+ *\r
+ *      - Redistributions of source code must retain the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer.\r
+ *\r
+ *      - Redistributions in binary form must reproduce the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer in the documentation and/or other materials\r
+ *        provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ * $Id: ipoib_adapter.c 4226 2009-04-06 06:01:03Z xalex $\r
+ */\r
+\r
+\r
+\r
+#include "ipoib_adapter.h"\r
+#include "ipoib_port.h"\r
+#include "ipoib_driver.h"\r
+#include "ipoib_debug.h"\r
+\r
+#if defined(EVENT_TRACING)\r
+#ifdef offsetof\r
+#undef offsetof\r
+#endif\r
+#include "ipoib_adapter.tmh"\r
+#endif\r
+\r
+\r
+#define ITEM_POOL_START                16\r
+#define ITEM_POOL_GROW         16\r
+\r
+\r
+/* IB Link speeds in 100bps */\r
+#define ONE_X_IN_100BPS                25000000\r
+#define FOUR_X_IN_100BPS       100000000\r
+#define TWELVE_X_IN_100BPS     300000000\r
+\r
+\r
+/* Declarations */\r
+static void\r
+adapter_construct(\r
+       IN                              ipoib_adapter_t* const          p_adapter );\r
+\r
+\r
+static ib_api_status_t\r
+adapter_init(\r
+       IN                              ipoib_adapter_t* const          p_adapter );\r
+\r
+\r
+static void\r
+__adapter_destroying(\r
+       IN                              cl_obj_t* const                         p_obj );\r
+\r
+\r
+static void\r
+__adapter_free(\r
+       IN                              cl_obj_t* const                         p_obj );\r
+\r
+\r
+static ib_api_status_t\r
+__ipoib_pnp_reg(\r
+       IN                              ipoib_adapter_t* const          p_adapter,\r
+       IN                              ib_pnp_class_t                          flags );\r
+\r
+\r
+static void\r
+__ipoib_pnp_dereg(\r
+       IN                              void*                                           context );\r
+\r
+\r
+static void\r
+__ipoib_adapter_reset(\r
+       IN                              void*   context);\r
+\r
+\r
+static ib_api_status_t\r
+__ipoib_pnp_cb(\r
+       IN                              ib_pnp_rec_t                            *p_pnp_rec );\r
+\r
+\r
+void\r
+ipoib_join_mcast(\r
+       IN                              ipoib_adapter_t* const          p_adapter );\r
+\r
+\r
+/* Leaves all mcast groups when port goes down. */\r
+static void\r
+ipoib_clear_mcast(\r
+       IN                              ipoib_port_t* const                     p_port );\r
+\r
+NDIS_STATUS\r
+ipoib_get_adapter_guids(\r
+       IN                              NDIS_HANDLE* const                      h_adapter,\r
+       IN      OUT                     ipoib_adapter_t                         *p_adapter );\r
+\r
+NDIS_STATUS\r
+ipoib_get_adapter_params(\r
+       IN                              NDIS_HANDLE* const                      wrapper_config_context,\r
+       IN      OUT                     ipoib_adapter_t                         *p_adapter,\r
+       OUT                             PUCHAR                                          *p_mac,\r
+       OUT                             UINT                                            *p_len);\r
+\r
+\r
+/* Implementation */\r
+ib_api_status_t\r
+ipoib_create_adapter(\r
+       IN                              NDIS_HANDLE                                     wrapper_config_context,\r
+       IN                              void* const                                     h_adapter,\r
+               OUT                     ipoib_adapter_t** const         pp_adapter )\r
+{\r
+       ipoib_adapter_t         *p_adapter;\r
+       ib_api_status_t         status;\r
+       cl_status_t                     cl_status;\r
+       PUCHAR                          mac;\r
+       UINT                            len;\r
+\r
+       IPOIB_ENTER( IPOIB_DBG_INIT );\r
+\r
+       p_adapter = cl_zalloc( sizeof(ipoib_adapter_t) );\r
+       if( !p_adapter )\r
+       {\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                       ("Failed to allocate ipoib_adapter_t (%d bytes)",\r
+                       sizeof(ipoib_adapter_t)) );\r
+               return IB_INSUFFICIENT_MEMORY;\r
+       }\r
+\r
+       adapter_construct( p_adapter );\r
+\r
+       p_adapter->h_adapter = h_adapter;\r
+\r
+       p_adapter->p_ifc = cl_zalloc( sizeof(ib_al_ifc_t) );\r
+       if( !p_adapter->p_ifc )\r
+       {\r
+               __adapter_free( &p_adapter->obj );\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                       ("ipoib_create_adapter failed to alloc ipoib_ifc_t %d bytes\n",\r
+                       sizeof(ib_al_ifc_t)) );\r
+               return IB_INSUFFICIENT_MEMORY;\r
+       }\r
+\r
+       /* Get the CA and port GUID from the bus driver. */\r
+       status = ipoib_get_adapter_guids( h_adapter,  p_adapter );\r
+       if( status != NDIS_STATUS_SUCCESS )\r
+       {\r
+               __adapter_free( &p_adapter->obj );\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                       ("ipoib_get_adapter_guids returned 0x%.8X.\n", status) );\r
+               return status;\r
+       }\r
+\r
+       IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,\r
+                       ("Port %016I64x (CA %016I64x port %d) initializing\n",\r
+                       p_adapter->guids.port_guid.guid, p_adapter->guids.ca_guid,\r
+                       p_adapter->guids.port_num) );\r
+\r
+       cl_status = cl_obj_init( &p_adapter->obj, CL_DESTROY_SYNC,\r
+               __adapter_destroying, NULL, __adapter_free );\r
+       if( cl_status != CL_SUCCESS )\r
+       {\r
+               __adapter_free( &p_adapter->obj );\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                       ("cl_obj_init returned %#x\n", cl_status) );\r
+               return IB_ERROR;\r
+       }\r
+\r
+       /* Read configuration parameters. */\r
+       status = ipoib_get_adapter_params( wrapper_config_context,\r
+               p_adapter , &mac, &len);\r
+       if( status != NDIS_STATUS_SUCCESS )\r
+       {\r
+               cl_obj_destroy( &p_adapter->obj );\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                       ("ipoib_get_adapter_params returned 0x%.8x.\n", status) );\r
+               return status;\r
+       }\r
+               \r
+       status = adapter_init( p_adapter );\r
+       if( status != IB_SUCCESS )\r
+       {\r
+               cl_obj_destroy( &p_adapter->obj );\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                       ("adapter_init returned %s.\n", \r
+                       p_adapter->p_ifc->get_err_str( status )) );\r
+               return status;\r
+       }\r
+\r
+       ETH_COPY_NETWORK_ADDRESS( p_adapter->params.conf_mac.addr, p_adapter->mac.addr );\r
+       /* If there is a NetworkAddress override in registry, use it */\r
+       if( (status == NDIS_STATUS_SUCCESS) && (len == HW_ADDR_LEN) )\r
+       {\r
+               if( ETH_IS_MULTICAST(mac) || ETH_IS_BROADCAST(mac) ||\r
+                       !ETH_IS_LOCALLY_ADMINISTERED(mac) )\r
+               {\r
+                       IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_INIT,\r
+                               ("Overriding NetworkAddress is invalid - "\r
+                               "%02x-%02x-%02x-%02x-%02x-%02x\n",\r
+                               mac[0], mac[1], mac[2],\r
+                               mac[3], mac[4], mac[5]) );\r
+               }\r
+               else\r
+       {\r
+                       ETH_COPY_NETWORK_ADDRESS( p_adapter->params.conf_mac.addr, mac );\r
+               }\r
+       }\r
+\r
+       *pp_adapter = p_adapter;\r
+\r
+       IPOIB_EXIT( IPOIB_DBG_INIT );\r
+       return status;\r
+}\r
+\r
+\r
+ib_api_status_t\r
+ipoib_start_adapter(\r
+       IN                              ipoib_adapter_t* const          p_adapter )\r
+{\r
+       ib_api_status_t status;\r
+\r
+       IPOIB_ENTER( IPOIB_DBG_INIT );\r
+\r
+       status = __ipoib_pnp_reg( p_adapter,\r
+               IB_PNP_FLAG_REG_SYNC | IB_PNP_FLAG_REG_COMPLETE );\r
+\r
+       IPOIB_EXIT( IPOIB_DBG_INIT );\r
+       return status;\r
+}\r
+\r
+\r
+void\r
+ipoib_destroy_adapter(\r
+       IN                              ipoib_adapter_t* const          p_adapter )\r
+{\r
+       IPOIB_ENTER( IPOIB_DBG_INIT );\r
+\r
+       CL_ASSERT( p_adapter );\r
+\r
+       /*\r
+        * Flag the adapter as being removed.  We use the IB_PNP_PORT_REMOVE state\r
+        * for this purpose.  Note that we protect this state change with both the\r
+        * mutex and the lock.  The mutex provides synchronization as a whole\r
+        * between destruction and AL callbacks (PnP, Query, Destruction).\r
+        * The lock provides protection\r
+        */\r
+       KeWaitForMutexObject(\r
+               &p_adapter->mutex, Executive, KernelMode, FALSE, NULL );\r
+       cl_obj_lock( &p_adapter->obj );\r
+       p_adapter->state = IB_PNP_PORT_REMOVE;\r
+\r
+       /*\r
+        * Clear the pointer to the port object since the object destruction\r
+        * will cascade to child objects.  This prevents potential duplicate\r
+        * destruction (or worse, stale pointer usage).\r
+        */\r
+       p_adapter->p_port = NULL;\r
+\r
+       cl_obj_unlock( &p_adapter->obj );\r
+\r
+       KeReleaseMutex( &p_adapter->mutex, FALSE );\r
+\r
+       cl_obj_destroy( &p_adapter->obj );\r
+\r
+       IPOIB_EXIT( IPOIB_DBG_INIT );\r
+}\r
+\r
+\r
+static void\r
+adapter_construct(\r
+       IN                              ipoib_adapter_t* const          p_adapter )\r
+{\r
+       cl_obj_construct( &p_adapter->obj, IPOIB_OBJ_INSTANCE );\r
+       cl_spinlock_construct( &p_adapter->send_stat_lock );\r
+       cl_spinlock_construct( &p_adapter->recv_stat_lock );\r
+       cl_qpool_construct( &p_adapter->item_pool );\r
+       KeInitializeMutex( &p_adapter->mutex, 0 );\r
+\r
+       cl_thread_construct(&p_adapter->destroy_thread);\r
+       \r
+       cl_vector_construct( &p_adapter->ip_vector );\r
+\r
+       cl_perf_construct( &p_adapter->perf );\r
+\r
+       p_adapter->state = IB_PNP_PORT_ADD;\r
+       p_adapter->port_rate = FOUR_X_IN_100BPS;\r
+}\r
+\r
+\r
+static ib_api_status_t\r
+adapter_init(\r
+       IN                              ipoib_adapter_t* const          p_adapter )\r
+{\r
+       cl_status_t                     cl_status;\r
+       ib_api_status_t         status;\r
+\r
+       IPOIB_ENTER( IPOIB_DBG_INIT );\r
+\r
+       cl_status = cl_perf_init( &p_adapter->perf, MaxPerf );\r
+       if( cl_status != CL_SUCCESS )\r
+       {\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                       ("cl_perf_init returned %#x\n", cl_status) );\r
+               return IB_ERROR;\r
+       }\r
+\r
+       cl_status = cl_spinlock_init( &p_adapter->send_stat_lock );\r
+       if( cl_status != CL_SUCCESS )\r
+       {\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                       ("cl_spinlock_init returned %#x\n", cl_status) );\r
+               return IB_ERROR;\r
+       }\r
+\r
+       cl_status = cl_spinlock_init( &p_adapter->recv_stat_lock );\r
+       if( cl_status != CL_SUCCESS )\r
+       {\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                       ("cl_spinlock_init returned %#x\n", cl_status) );\r
+               return IB_ERROR;\r
+       }\r
+\r
+       cl_status = cl_qpool_init( &p_adapter->item_pool, ITEM_POOL_START, 0,\r
+               ITEM_POOL_GROW, sizeof(cl_pool_obj_t), NULL, NULL, NULL );\r
+       if( cl_status != CL_SUCCESS )\r
+       {\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                       ("cl_qpool_init returned %#x\n", cl_status) );\r
+               return IB_ERROR;\r
+       }\r
+\r
+\r
+       /* We manually manage the size and capacity of the vector. */\r
+       cl_status = cl_vector_init( &p_adapter->ip_vector, 0,\r
+               0, sizeof(net_address_item_t), NULL, NULL, p_adapter );\r
+       if( cl_status != CL_SUCCESS )\r
+       {\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                       ("cl_vector_init for ip_vector returned %#x\n",\r
+                       cl_status) );\r
+               return IB_ERROR;\r
+       }\r
+\r
+       /* Validate the port GUID and generate the MAC address. */\r
+       status =\r
+               ipoib_mac_from_guid( p_adapter->guids.port_guid.guid, p_adapter->params.guid_mask, &p_adapter->mac);\r
+       if( status != IB_SUCCESS )\r
+       {\r
+               if( status == IB_INVALID_GUID_MASK )\r
+               {\r
+                       IPOIB_PRINT( TRACE_LEVEL_WARNING, IPOIB_DBG_ERROR,\r
+                               ("Invalid GUID mask received, rejecting it") );\r
+                       ipoib_create_log(p_adapter->h_adapter, GUID_MASK_LOG_INDEX, EVENT_IPOIB_WRONG_PARAMETER_WRN);\r
+               }\r
+\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                       ("ipoib_mac_from_guid returned %s\n", \r
+                       p_adapter->p_ifc->get_err_str( status )) );\r
+               return status;\r
+       }\r
+\r
+       /* Open AL. */\r
+       status = p_adapter->p_ifc->open_al( &p_adapter->h_al );\r
+       if( status != IB_SUCCESS )\r
+       {\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                       ("ib_open_al returned %s\n", \r
+                       p_adapter->p_ifc->get_err_str( status )) );\r
+               return status;\r
+       }\r
+\r
+       IPOIB_EXIT( IPOIB_DBG_INIT );\r
+       return status;\r
+}\r
+\r
+\r
+static ib_api_status_t\r
+__ipoib_pnp_reg(\r
+       IN                              ipoib_adapter_t* const          p_adapter,\r
+       IN                              ib_pnp_class_t                          flags )\r
+{\r
+       ib_api_status_t         status;\r
+       ib_pnp_req_t            pnp_req;\r
+       \r
+       IPOIB_ENTER( IPOIB_DBG_INIT );\r
+\r
+       CL_ASSERT( !p_adapter->h_pnp );\r
+       CL_ASSERT( !p_adapter->registering );\r
+\r
+       p_adapter->registering = TRUE;\r
+       \r
+       /* Register for PNP events. */\r
+       cl_memclr( &pnp_req, sizeof(pnp_req) );\r
+       pnp_req.pnp_class = IB_PNP_PORT | flags;\r
+       /*\r
+        * Context is the cl_obj of the adapter to allow passing cl_obj_deref\r
+        * to ib_dereg_pnp.\r
+        */\r
+       pnp_req.pnp_context = &p_adapter->obj;\r
+       pnp_req.pfn_pnp_cb = __ipoib_pnp_cb;\r
+       status = p_adapter->p_ifc->reg_pnp( p_adapter->h_al, &pnp_req, &p_adapter->h_pnp );\r
+       if( status != IB_SUCCESS )\r
+       {\r
+               p_adapter->registering = FALSE;\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                       ("ib_reg_pnp returned %s\n", \r
+                       p_adapter->p_ifc->get_err_str( status )) );\r
+               return status;\r
+       }\r
+       /*\r
+        * Reference the adapter on behalf of the PNP registration.\r
+        * This allows the destruction to block until the PNP deregistration\r
+        * completes.\r
+        */\r
+       cl_obj_ref( &p_adapter->obj );\r
+\r
+       IPOIB_EXIT( IPOIB_DBG_INIT );\r
+       return status;\r
+}\r
+\r
+\r
+static void\r
+__adapter_destroying(\r
+       IN                              cl_obj_t* const                         p_obj )\r
+{\r
+       ipoib_adapter_t         *p_adapter;\r
+       KLOCK_QUEUE_HANDLE      hdl;\r
+\r
+       IPOIB_ENTER( IPOIB_DBG_INIT );\r
+\r
+       p_adapter = PARENT_STRUCT( p_obj, ipoib_adapter_t, obj );\r
+\r
+       /*\r
+        * The adapter's object will be dereferenced when the deregistration\r
+        * completes.  No need to lock here since all PnP related API calls\r
+        * are driven by NDIS (via the Init/Reset/Destroy paths).\r
+        */\r
+       if( p_adapter->h_pnp )\r
+       {\r
+               p_adapter->p_ifc->dereg_pnp( p_adapter->h_pnp, cl_obj_deref );\r
+               p_adapter->h_pnp = NULL;\r
+       }\r
+\r
+       if( p_adapter->packet_filter )\r
+       {\r
+               KeAcquireInStackQueuedSpinLock( &g_ipoib.lock, &hdl );\r
+               cl_obj_lock( &p_adapter->obj );\r
+\r
+               ASSERT( cl_qlist_count( &g_ipoib.adapter_list ) );\r
+               cl_qlist_remove_item( &g_ipoib.adapter_list, &p_adapter->entry );\r
+\r
+               p_adapter->packet_filter = 0;\r
+\r
+               cl_obj_unlock( &p_adapter->obj );\r
+               KeReleaseInStackQueuedSpinLock( &hdl );\r
+       }\r
+\r
+       IPOIB_EXIT( IPOIB_DBG_INIT );\r
+}\r
+\r
+\r
+static void\r
+__adapter_free(\r
+       IN                              cl_obj_t* const                         p_obj )\r
+{\r
+       ipoib_adapter_t *p_adapter;\r
+\r
+       IPOIB_ENTER( IPOIB_DBG_INIT );\r
+\r
+       p_adapter = PARENT_STRUCT( p_obj, ipoib_adapter_t, obj );\r
+\r
+       if( p_adapter->p_ifc )\r
+       {\r
+               if( p_adapter->h_al )\r
+                       p_adapter->p_ifc->close_al( p_adapter->h_al );\r
+\r
+               cl_free( p_adapter->p_ifc );\r
+               p_adapter->p_ifc = NULL;\r
+       }\r
+\r
+       cl_vector_destroy( &p_adapter->ip_vector );\r
+       cl_qpool_destroy( &p_adapter->item_pool );\r
+       cl_spinlock_destroy( &p_adapter->recv_stat_lock );\r
+       cl_spinlock_destroy( &p_adapter->send_stat_lock );\r
+       cl_obj_deinit( p_obj );\r
+\r
+       cl_perf_destroy( &p_adapter->perf, TRUE );\r
+\r
+       cl_free( p_adapter );\r
+\r
+       IPOIB_EXIT( IPOIB_DBG_INIT );\r
+}\r
+\r
+\r
+static ib_api_status_t\r
+ipoib_query_pkey_index(ipoib_adapter_t *p_adapter)\r
+{\r
+       ib_api_status_t                 status;\r
+       ib_ca_attr_t                *ca_attr;\r
+       uint32_t                            ca_size;\r
+       uint16_t index = 0;\r
+\r
+       /* Query the CA for Pkey table */\r
+       status = p_adapter->p_ifc->query_ca(p_adapter->p_port->ib_mgr.h_ca, NULL, &ca_size);\r
+       if(status != IB_INSUFFICIENT_MEMORY)\r
+       {\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                                               ("ib_query_ca failed\n"));\r
+               return status;\r
+       }\r
+\r
+       ca_attr = (ib_ca_attr_t*)cl_zalloc(ca_size);\r
+       if      (!ca_attr)\r
+       {\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                                               ("cl_zalloc can't allocate %d\n",ca_size));\r
+               return IB_INSUFFICIENT_MEMORY;\r
+       }\r
+\r
+       status = p_adapter->p_ifc->query_ca(p_adapter->p_port->ib_mgr.h_ca, ca_attr,&ca_size);  \r
+       if( status != IB_SUCCESS )\r
+       {\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                                               ("ib_query_ca returned %s\n", \r
+                                                p_adapter->p_ifc->get_err_str( status )) );\r
+               goto pkey_end;\r
+       }\r
+       CL_ASSERT(ca_attr->p_port_attr[p_adapter->p_port->port_num -1].p_pkey_table[0] == IB_DEFAULT_PKEY);\r
+       for(index = 0; index < ca_attr->p_port_attr[p_adapter->p_port->port_num -1].num_pkeys; index++)\r
+       {\r
+               if(cl_hton16(p_adapter->guids.port_guid.pkey) == ca_attr->p_port_attr[p_adapter->p_port->port_num -1].p_pkey_table[index])\r
+                       break;\r
+       }\r
+       if(index >= ca_attr->p_port_attr[p_adapter->p_port->port_num -1].num_pkeys)\r
+       {\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                                               ("Pkey table is invalid, index not found\n"));\r
+               NdisWriteErrorLogEntry( p_adapter->h_adapter,\r
+                       EVENT_IPOIB_PARTITION_ERR, 1, p_adapter->guids.port_guid.pkey );\r
+               status = IB_NOT_FOUND;\r
+               p_adapter->p_port->pkey_index = PKEY_INVALID_INDEX;\r
+               goto pkey_end;\r
+       }\r
+\r
+       p_adapter->p_port->pkey_index = index;\r
+       IPOIB_PRINT_EXIT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_IB,\r
+                                       ("for PKEY = 0x%04X got index = %d\n",p_adapter->guids.port_guid.pkey,index));\r
+\r
+pkey_end:\r
+       if(ca_attr)\r
+               cl_free(ca_attr);\r
+       return status;\r
+}\r
+\r
+static ib_api_status_t\r
+__ipoib_pnp_cb(\r
+       IN                              ib_pnp_rec_t                            *p_pnp_rec )\r
+{\r
+       ipoib_adapter_t         *p_adapter;\r
+       ipoib_port_t            *p_port;\r
+       ib_pnp_event_t          old_state;\r
+       ib_pnp_port_rec_t       *p_port_rec;\r
+       ib_api_status_t         status = IB_SUCCESS;\r
+       NDIS_LINK_STATE         link_state;\r
+       NDIS_STATUS_INDICATION  status_indication;\r
+\r
+       IPOIB_ENTER( IPOIB_DBG_PNP );\r
+\r
+       CL_ASSERT( p_pnp_rec );\r
+       NdisZeroMemory(&link_state, sizeof(NDIS_LINK_STATE));\r
+       p_adapter =\r
+               PARENT_STRUCT( p_pnp_rec->pnp_context, ipoib_adapter_t, obj );\r
+\r
+       CL_ASSERT( p_adapter );\r
+\r
+       /* Synchronize with destruction */\r
+       KeWaitForMutexObject(\r
+               &p_adapter->mutex, Executive, KernelMode, FALSE, NULL );\r
+       cl_obj_lock( &p_adapter->obj );\r
+       old_state = p_adapter->state;\r
+       cl_obj_unlock( &p_adapter->obj );\r
+       if( old_state == IB_PNP_PORT_REMOVE )\r
+       {\r
+               KeReleaseMutex( &p_adapter->mutex, FALSE );\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_PNP,\r
+                       ("Aborting - Adapter destroying.\n") );\r
+               return IB_NOT_DONE;\r
+       }\r
+\r
+       IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_PNP,\r
+               ("p_pnp_rec->pnp_event = 0x%x (%s)\n",\r
+               p_pnp_rec->pnp_event, ib_get_pnp_event_str( p_pnp_rec->pnp_event )) );\r
+\r
+       p_port_rec = (ib_pnp_port_rec_t*)p_pnp_rec;\r
+\r
+       switch( p_pnp_rec->pnp_event )\r
+       {\r
+       case IB_PNP_PORT_ADD:\r
+               CL_ASSERT( !p_pnp_rec->context );\r
+               /* Only process our port GUID. */\r
+               if( p_pnp_rec->guid != p_adapter->guids.port_guid.guid )\r
+               {\r
+                       status = IB_NOT_DONE;\r
+                       break;\r
+               }\r
+\r
+               /* Don't process if we're destroying. */\r
+               if( p_adapter->obj.state == CL_DESTROYING )\r
+               {\r
+                       status = IB_NOT_DONE;\r
+                       break;\r
+               }\r
+\r
+               CL_ASSERT( !p_adapter->p_port );\r
+               /* Allocate all IB resources. */\r
+               cl_obj_lock( &p_adapter->obj );\r
+               p_adapter->state = IB_PNP_PORT_ADD;\r
+               cl_obj_unlock( &p_adapter->obj );\r
+               status = ipoib_create_port( p_adapter, p_port_rec, &p_port );\r
+               cl_obj_lock( &p_adapter->obj );\r
+               if( status != IB_SUCCESS )\r
+               {\r
+                       p_adapter->state = old_state;\r
+                       cl_obj_unlock( &p_adapter->obj );\r
+                       p_adapter->hung = TRUE;\r
+                       break;\r
+               }\r
+\r
+               p_pnp_rec->context = p_port;\r
+\r
+               p_adapter->p_port = p_port;\r
+               cl_obj_unlock( &p_adapter->obj );\r
+               break;\r
+\r
+       case IB_PNP_PORT_REMOVE:\r
+               /* Release all IB resources. */\r
+               CL_ASSERT( p_pnp_rec->context );\r
+\r
+               cl_obj_lock( &p_adapter->obj );\r
+               p_adapter->state = IB_PNP_PORT_REMOVE;\r
+               p_port = p_adapter->p_port;\r
+               p_adapter->p_port = NULL;\r
+               cl_obj_unlock( &p_adapter->obj );\r
+               ipoib_port_destroy( p_port );\r
+               p_pnp_rec->context = NULL;\r
+               status = IB_SUCCESS;\r
+               break;\r
+\r
+       case IB_PNP_PORT_ACTIVE:\r
+               /* Join multicast groups and put QP in RTS. */\r
+               CL_ASSERT( p_pnp_rec->context );\r
+\r
+               cl_obj_lock( &p_adapter->obj );\r
+               p_adapter->state = IB_PNP_PORT_INIT;\r
+               cl_obj_unlock( &p_adapter->obj );\r
+               ipoib_port_up( p_adapter->p_port, p_port_rec );\r
+\r
+               status = IB_SUCCESS;\r
+               break;\r
+\r
+       case IB_PNP_PORT_ARMED:\r
+               status = IB_SUCCESS;\r
+               break;\r
+\r
+       case IB_PNP_PORT_INIT:\r
+               /*\r
+                * Init could happen if the SM brings the port down\r
+                * without changing the physical link.\r
+                */\r
+       case IB_PNP_PORT_DOWN:\r
+               CL_ASSERT( p_pnp_rec->context );\r
+\r
+               cl_obj_lock( &p_adapter->obj );\r
+               old_state = p_adapter->state;\r
+               p_adapter->state = IB_PNP_PORT_DOWN;\r
+               cl_obj_unlock( &p_adapter->obj );\r
+               status = IB_SUCCESS;\r
+\r
+               if( !p_adapter->registering && old_state != IB_PNP_PORT_DOWN )\r
+               {\r
+                       link_state.Header.Revision = NDIS_LINK_STATE_REVISION_1;\r
+                       link_state.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;\r
+                       link_state.Header.Size = sizeof(NDIS_LINK_STATE);\r
+                       link_state.MediaConnectState = MediaConnectStateDisconnected;\r
+                       link_state.MediaDuplexState = MediaDuplexStateFull;\r
+                       link_state.XmitLinkSpeed = link_state.RcvLinkSpeed = IPOIB_MEDIA_MAX_SPEED;\r
+\r
+                       IPOIB_INIT_NDIS_STATUS_INDICATION(&status_indication,\r
+                                   p_adapter->h_adapter,\r
+                                   NDIS_STATUS_LINK_STATE,\r
+                                   (PVOID)&link_state,\r
+                                   sizeof(link_state));\r
+\r
+                       NdisMIndicateStatusEx(p_adapter->h_adapter,&status_indication);\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,\r
+                               ("Link DOWN!\n") );\r
+\r
+                       ipoib_port_down( p_adapter->p_port );\r
+               }\r
+               break;\r
+\r
+       case IB_PNP_REG_COMPLETE:\r
+               if( p_adapter->registering )\r
+               {\r
+                       p_adapter->registering = FALSE;\r
+                       cl_obj_lock( &p_adapter->obj );\r
+                       old_state = p_adapter->state;\r
+                       cl_obj_unlock( &p_adapter->obj );\r
+\r
+                       if( old_state == IB_PNP_PORT_DOWN )\r
+                       {\r
+                               /* If we were initializing, we might have pended some OIDs. */\r
+                               ipoib_resume_oids( p_adapter );\r
+\r
+                               link_state.Header.Revision = NDIS_LINK_STATE_REVISION_1;\r
+                               link_state.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;\r
+                               link_state.Header.Size = sizeof(NDIS_LINK_STATE);\r
+                               link_state.MediaConnectState = MediaConnectStateDisconnected;\r
+                               link_state.MediaDuplexState = MediaDuplexStateFull;\r
+                               link_state.XmitLinkSpeed = link_state.RcvLinkSpeed = IPOIB_MEDIA_MAX_SPEED;\r
+\r
+                               IPOIB_INIT_NDIS_STATUS_INDICATION(&status_indication,\r
+                                                                          p_adapter->h_adapter,\r
+                                                                          NDIS_STATUS_LINK_STATE,\r
+                                                                          (PVOID)&link_state,\r
+                                                                          sizeof(link_state));\r
+                               IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_INIT,\r
+                       ("Indicate DISCONNECT\n") );\r
+                               NdisMIndicateStatusEx(p_adapter->h_adapter,&status_indication);                 \r
+                       }\r
+               }\r
+\r
+               if( p_adapter->reset && p_adapter->state != IB_PNP_PORT_INIT )\r
+               {\r
+                       p_adapter->reset = FALSE;\r
+                       NdisMResetComplete(\r
+                               p_adapter->h_adapter, NDIS_STATUS_SUCCESS, TRUE );\r
+               }\r
+               status = IB_SUCCESS;\r
+               break;\r
+\r
+       default:\r
+               IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,\r
+                       ("IPOIB: Received unhandled PnP event 0x%x (%s)\n",\r
+                       p_pnp_rec->pnp_event, ib_get_pnp_event_str( p_pnp_rec->pnp_event )) );\r
+               /* Fall through. */\r
+\r
+               status = IB_SUCCESS;\r
+\r
+               /* We ignore events below if the link is not active. */\r
+               if( p_port_rec->p_port_attr->link_state != IB_LINK_ACTIVE )\r
+                       break;\r
+\r
+               case IB_PNP_PKEY_CHANGE:\r
+                       if(p_pnp_rec->pnp_event == IB_PNP_PKEY_CHANGE && \r
+                          p_adapter->guids.port_guid.pkey != IB_DEFAULT_PKEY)\r
+                       {\r
+                               status = ipoib_query_pkey_index(p_adapter);\r
+                               if(status != IB_SUCCESS)\r
+                               {\r
+                                  cl_obj_lock( &p_adapter->obj );\r
+                                  p_adapter->state = IB_PNP_PORT_INIT;\r
+                                  cl_obj_unlock( &p_adapter->obj );\r
+                               }\r
+                       }\r
+\r
+               case IB_PNP_SM_CHANGE:\r
+               case IB_PNP_GID_CHANGE:\r
+               case IB_PNP_LID_CHANGE:\r
+\r
+               cl_obj_lock( &p_adapter->obj );\r
+               old_state = p_adapter->state;\r
+               switch( old_state )\r
+               {\r
+               case IB_PNP_PORT_DOWN:\r
+                       p_adapter->state = IB_PNP_PORT_INIT;\r
+                       break;\r
+\r
+               default:\r
+                       p_adapter->state = IB_PNP_PORT_DOWN;\r
+               }\r
+               cl_obj_unlock( &p_adapter->obj );\r
+               \r
+               if( p_adapter->registering )\r
+                       break;\r
+\r
+               switch( old_state )\r
+               {\r
+               case IB_PNP_PORT_ACTIVE:\r
+               case IB_PNP_PORT_INIT:\r
+                       link_state.Header.Revision = NDIS_LINK_STATE_REVISION_1;\r
+                       link_state.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;\r
+                       link_state.Header.Size = sizeof(NDIS_LINK_STATE);\r
+                       link_state.MediaConnectState = MediaConnectStateDisconnected;\r
+                       link_state.MediaDuplexState = MediaDuplexStateFull;\r
+                       link_state.XmitLinkSpeed = link_state.RcvLinkSpeed = IPOIB_MEDIA_MAX_SPEED;\r
+\r
+                       IPOIB_INIT_NDIS_STATUS_INDICATION(&status_indication,\r
+                                                                  p_adapter->h_adapter,\r
+                                                                  NDIS_STATUS_LINK_STATE,\r
+                                                                  (PVOID)&link_state,\r
+                                                                  sizeof(link_state));\r
+\r
+                       NdisMIndicateStatusEx(p_adapter->h_adapter,&status_indication);         \r
+\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,\r
+                               ("Link DOWN!\n") );\r
+                       IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_INIT,\r
+                       ("Indicate DISCONNECT\n") );\r
+\r
+                       ipoib_port_down( p_adapter->p_port );\r
+                       /* Fall through. */\r
+\r
+               case IB_PNP_PORT_DOWN:\r
+                       cl_obj_lock( &p_adapter->obj );\r
+                       p_adapter->state = IB_PNP_PORT_INIT;\r
+                       cl_obj_unlock( &p_adapter->obj );\r
+                       ipoib_port_up( p_adapter->p_port, (ib_pnp_port_rec_t*)p_pnp_rec );\r
+               }\r
+               break;\r
+       }\r
+\r
+       KeReleaseMutex( &p_adapter->mutex, FALSE );\r
+\r
+       IPOIB_EXIT( IPOIB_DBG_PNP );\r
+       return status;\r
+}\r
+\r
+\r
+/* Joins/leaves mcast groups based on currently programmed mcast MACs. */\r
+void\r
+ipoib_refresh_mcast(\r
+       IN                              ipoib_adapter_t* const          p_adapter,\r
+       IN                              mac_addr_t* const                       p_mac_array,\r
+       IN              const   uint8_t                                         num_macs )\r
+{\r
+       uint8_t                         i, j;\r
+       ipoib_port_t            *p_port = NULL;\r
+\r
+       IPOIB_ENTER( IPOIB_DBG_MCAST );\r
+       cl_obj_lock( &p_adapter->obj );\r
+       if( p_adapter->state == IB_PNP_PORT_ACTIVE )\r
+       {\r
+               p_port = p_adapter->p_port;\r
+               ipoib_port_ref( p_port, ref_refresh_mcast );\r
+       }\r
+       cl_obj_unlock( &p_adapter->obj );\r
+\r
+       if( p_port )\r
+       {\r
+               /* Purge old entries. */\r
+               for( i = 0; i < p_adapter->mcast_array_size; i++ )\r
+               {\r
+                       for( j = 0; j < num_macs; j++ )\r
+                       {\r
+                               if( !cl_memcmp( &p_adapter->mcast_array[i], &p_mac_array[j],\r
+                                       sizeof(mac_addr_t) ) )\r
+                               {\r
+                                       break;\r
+                               }\r
+                       }\r
+                       if( j != num_macs )\r
+                               continue;\r
+\r
+                       ipoib_port_remove_endpt( p_port, p_adapter->mcast_array[i] );\r
+               }\r
+\r
+               /* Add new entries */\r
+               for( i = 0; i < num_macs; i++ )\r
+               {\r
+                       for( j = 0; j < p_adapter->mcast_array_size; j++ )\r
+                       {\r
+                               if( !cl_memcmp( &p_adapter->mcast_array[j], &p_mac_array[i],\r
+                                       sizeof(mac_addr_t) ) )\r
+                               {\r
+                                       break;\r
+                               }\r
+                       }\r
+\r
+                       if( j != p_adapter->mcast_array_size )\r
+                               continue;\r
+                       if ( ( p_mac_array[i].addr[0] == 1 && p_mac_array[i].addr[1] == 0 && p_mac_array[i].addr[2] == 0x5e &&\r
+                                  p_mac_array[i].addr[3] == 0 && p_mac_array[i].addr[4] == 0 && p_mac_array[i].addr[5] == 1 ) ||\r
+                                 !( p_mac_array[i].addr[0] == 1 && p_mac_array[i].addr[1] == 0 && p_mac_array[i].addr[2] == 0x5e )\r
+                               )\r
+                       {\r
+                               ipoib_port_join_mcast( p_port, p_mac_array[i], IB_MC_REC_STATE_FULL_MEMBER );\r
+                       }\r
+               }\r
+       }\r
+\r
+       /* Copy the MAC array. */\r
+       NdisMoveMemory( p_adapter->mcast_array, p_mac_array,\r
+               num_macs * sizeof(mac_addr_t) );\r
+       p_adapter->mcast_array_size = num_macs;\r
+\r
+       if( p_port )\r
+               ipoib_port_deref( p_port, ref_refresh_mcast );\r
+\r
+       IPOIB_EXIT( IPOIB_DBG_MCAST );\r
+}\r
+\r
+\r
+ib_api_status_t\r
+ipoib_reset_adapter(\r
+       IN                              ipoib_adapter_t* const          p_adapter )\r
+{\r
+       ib_api_status_t         status;\r
+       ib_pnp_handle_t         h_pnp;\r
+\r
+       IPOIB_ENTER( IPOIB_DBG_INIT );\r
+\r
+       if( p_adapter->reset )\r
+               return IB_INVALID_STATE;\r
+\r
+       p_adapter->hung = FALSE;\r
+       p_adapter->reset = TRUE;\r
+\r
+       if( p_adapter->h_pnp )\r
+       {\r
+               h_pnp = p_adapter->h_pnp;\r
+               p_adapter->h_pnp  = NULL;\r
+               status = p_adapter->p_ifc->dereg_pnp( h_pnp, __ipoib_pnp_dereg );\r
+               if( status == IB_SUCCESS )\r
+                       status = IB_NOT_DONE;\r
+       }\r
+       else\r
+       {\r
+               status = __ipoib_pnp_reg( p_adapter, IB_PNP_FLAG_REG_COMPLETE );\r
+               if( status == IB_SUCCESS )\r
+                       p_adapter->hung = FALSE;\r
+       }\r
+       if (status == IB_NOT_DONE) {\r
+               p_adapter->reset = TRUE;\r
+       }\r
+       else {\r
+               p_adapter->reset = FALSE;\r
+       }\r
+       IPOIB_EXIT( IPOIB_DBG_INIT );\r
+       return status;\r
+}\r
+\r
+\r
+static void\r
+__ipoib_pnp_dereg(\r
+       IN                              void*                                           context )\r
+{\r
+       ipoib_adapter_t*        p_adapter;\r
+\r
+       IPOIB_ENTER( IPOIB_DBG_INIT );\r
+\r
+       p_adapter = PARENT_STRUCT( context, ipoib_adapter_t, obj );\r
+\r
+       cl_thread_init(&p_adapter->destroy_thread, __ipoib_adapter_reset, (void*)p_adapter, "destroy_thread");\r
+       \r
+       IPOIB_ENTER( IPOIB_DBG_INIT );\r
+\r
+}\r
+\r
+static void\r
+__ipoib_adapter_reset(\r
+       IN                              void*   context)\r
+{\r
+\r
+       ipoib_adapter_t *p_adapter;\r
+       ipoib_port_t            *p_port;\r
+       ib_api_status_t         status;\r
+       ib_pnp_event_t          state;\r
+       \r
+       IPOIB_ENTER( IPOIB_DBG_INIT );\r
+\r
+       p_adapter = (ipoib_adapter_t*)context;\r
+       \r
+       /* Synchronize with destruction */\r
+       KeWaitForMutexObject(\r
+               &p_adapter->mutex, Executive, KernelMode, FALSE, NULL );\r
+\r
+       cl_obj_lock( &p_adapter->obj );\r
+\r
+       CL_ASSERT( !p_adapter->h_pnp );\r
+\r
+       if( p_adapter->state != IB_PNP_PORT_REMOVE )\r
+               p_adapter->state = IB_PNP_PORT_ADD;\r
+\r
+       state = p_adapter->state;\r
+\r
+       /* Destroy the current port instance if it still exists. */\r
+       p_port = p_adapter->p_port;\r
+       p_adapter->p_port = NULL;\r
+       cl_obj_unlock( &p_adapter->obj );\r
+\r
+       if( p_port )\r
+               ipoib_port_destroy( p_port );\r
+       ASSERT(p_adapter->reset == TRUE);\r
+       if( state != IB_PNP_PORT_REMOVE )\r
+       {\r
+               status = __ipoib_pnp_reg( p_adapter, IB_PNP_FLAG_REG_COMPLETE );\r
+               if( status != IB_SUCCESS )\r
+               {\r
+                       p_adapter->reset = FALSE;\r
+                       IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                               ("__ipoib_pnp_reg returned %s\n",\r
+                               p_adapter->p_ifc->get_err_str( status )) );\r
+                       NdisMResetComplete( \r
+                               p_adapter->h_adapter, NDIS_STATUS_HARD_ERRORS, TRUE );\r
+               }\r
+       }\r
+       else\r
+       {\r
+               p_adapter->reset = FALSE;\r
+               NdisMResetComplete(\r
+                       p_adapter->h_adapter, NDIS_STATUS_SUCCESS, TRUE );\r
+               status = IB_SUCCESS;\r
+       }\r
+\r
+       /* Dereference the adapter since the previous registration is now gone. */\r
+       cl_obj_deref( &p_adapter->obj );\r
+\r
+       KeReleaseMutex( &p_adapter->mutex, FALSE );\r
+\r
+       IPOIB_EXIT( IPOIB_DBG_INIT );\r
+}\r
+\r
+\r
+void\r
+ipoib_set_rate(\r
+       IN                              ipoib_adapter_t* const          p_adapter,\r
+       IN              const   uint8_t                                         link_width, \r
+       IN              const   uint8_t                                         link_speed )\r
+{\r
+       uint32_t        rate;\r
+\r
+       IPOIB_ENTER( IPOIB_DBG_INIT );\r
+\r
+       /* Set the link speed based on the IB link speed (1x vs 4x, etc). */\r
+       switch( link_speed )\r
+       {\r
+       case IB_LINK_SPEED_ACTIVE_2_5:\r
+               IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,\r
+                       ("Link speed is 2.5Gs\n") );\r
+               rate = IB_LINK_SPEED_ACTIVE_2_5;\r
+               break;\r
+\r
+       case IB_LINK_SPEED_ACTIVE_5:\r
+               IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,\r
+                       ("Link speed is 5G\n") );\r
+               rate = IB_LINK_SPEED_ACTIVE_5;\r
+               break;\r
+\r
+       case IB_LINK_SPEED_ACTIVE_10:\r
+               IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,\r
+                       ("Link speed is 10G\n") );\r
+               rate = IB_LINK_SPEED_ACTIVE_10;\r
+               break;\r
+\r
+       default:\r
+               IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                       ("Invalid link speed %d.\n", link_speed) );\r
+               rate = 0;\r
+       }\r
+\r
+       switch( link_width )\r
+       {\r
+       case IB_LINK_WIDTH_ACTIVE_1X:\r
+               IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,\r
+                       ("Link width is 1X\n") );\r
+               rate *= ONE_X_IN_100BPS;\r
+               break;\r
+\r
+       case IB_LINK_WIDTH_ACTIVE_4X:\r
+               IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,\r
+                       ("Link width is 4X\n") );\r
+               rate *= FOUR_X_IN_100BPS;\r
+               break;\r
+\r
+       case IB_LINK_WIDTH_ACTIVE_12X:\r
+               IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,\r
+                       ("Link width is 12X\n") );\r
+               rate *= TWELVE_X_IN_100BPS;\r
+               break;\r
+\r
+       default:\r
+               IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                       ("Invalid link rate (%d).\n", link_width) );\r
+               rate = 0;\r
+       }\r
+\r
+       p_adapter->port_rate = rate;\r
+       IPOIB_EXIT( IPOIB_DBG_INIT );\r
+}\r
+\r
+\r
+ib_api_status_t\r
+ipoib_set_active(\r
+       IN                              ipoib_adapter_t* const          p_adapter )\r
+{\r
+       ib_pnp_event_t  old_state;\r
+       uint8_t                 i;\r
+       ib_api_status_t status = IB_SUCCESS;\r
+       NDIS_LINK_STATE         link_state;\r
+       NDIS_STATUS_INDICATION  status_indication;\r
+       IPOIB_ENTER( IPOIB_DBG_INIT );\r
+\r
+       NdisZeroMemory(&link_state, sizeof(NDIS_LINK_STATE));\r
+       cl_obj_lock( &p_adapter->obj );\r
+       old_state = p_adapter->state;\r
+\r
+       /* Change the state to indicate that we are now connected and live. */\r
+       if( old_state == IB_PNP_PORT_INIT )\r
+               p_adapter->state = IB_PNP_PORT_ACTIVE;\r
+\r
+       cl_obj_unlock( &p_adapter->obj );\r
+\r
+       /*\r
+        * If we had a pending OID request for OID_GEN_LINK_SPEED,\r
+        * complete it now.\r
+        */\r
+       switch( old_state )\r
+       {\r
+       case IB_PNP_PORT_ADD:\r
+               ipoib_reg_addrs( p_adapter );\r
+               /* Fall through. */\r
+\r
+       case IB_PNP_PORT_REMOVE:\r
+               ipoib_resume_oids( p_adapter );\r
+               break;\r
+\r
+       default:\r
+               if (p_adapter->guids.port_guid.pkey != IB_DEFAULT_PKEY)\r
+               {\r
+                       status = ipoib_query_pkey_index(p_adapter);\r
+                       if( IB_SUCCESS != status)\r
+                       {\r
+                               break;\r
+                       }\r
+               }\r
+               /* Join all programmed multicast groups. */\r
+               for( i = 0; i < p_adapter->mcast_array_size; i++ )\r
+               {\r
+                       ipoib_port_join_mcast(\r
+                               p_adapter->p_port, p_adapter->mcast_array[i] ,IB_MC_REC_STATE_FULL_MEMBER);\r
+               }\r
+\r
+               /* Register all existing addresses. */\r
+               ipoib_reg_addrs( p_adapter );\r
+\r
+               ipoib_resume_oids( p_adapter );\r
+\r
+               /*\r
+                * Now that we're in the broadcast group, notify that\r
+                * we have a link.\r
+                */\r
+               IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT, ("Link UP!\n") );\r
+               NdisWriteErrorLogEntry( p_adapter->h_adapter,\r
+                       EVENT_IPOIB_PORT_UP + (p_adapter->port_rate/ONE_X_IN_100BPS),\r
+                       1, p_adapter->port_rate );\r
+\r
+               if( !p_adapter->reset )\r
+               {\r
+                       link_state.Header.Revision = NDIS_LINK_STATE_REVISION_1;\r
+                       link_state.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;\r
+                       link_state.Header.Size = sizeof(NDIS_LINK_STATE);\r
+                       link_state.MediaConnectState = MediaConnectStateConnected;\r
+                       link_state.MediaDuplexState = MediaDuplexStateFull;\r
+                       link_state.XmitLinkSpeed = \r
+                       link_state.RcvLinkSpeed = IPOIB_MEDIA_MAX_SPEED;\r
+                       link_state.PauseFunctions = NdisPauseFunctionsSendAndReceive;\r
+                       IPOIB_INIT_NDIS_STATUS_INDICATION(&status_indication,\r
+                                                                  p_adapter->h_adapter,\r
+                                                                  NDIS_STATUS_LINK_STATE,\r
+                                                                  (PVOID)&link_state,\r
+                                                                  sizeof(link_state));\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT, ("***************Indicate connect!\n") );\r
+                       NdisMIndicateStatusEx(p_adapter->h_adapter,&status_indication);\r
+               }\r
+       }\r
+\r
+       if( p_adapter->reset )\r
+       {\r
+               ASSERT(FALSE);\r
+               p_adapter->reset = FALSE;\r
+               NdisMResetComplete(\r
+                       p_adapter->h_adapter, NDIS_STATUS_SUCCESS, TRUE );\r
+       }\r
+\r
+       IPOIB_EXIT( IPOIB_DBG_INIT );\r
+       return  status;\r
+}\r
+\r
+/*\r
+ * If something goes wrong after the port goes active, e.g.\r
+ *     - PortInfo query failure\r
+ *     - MC Join timeout\r
+ *     - etc\r
+ * Mark the port state as down, resume any pended OIDS, etc.\r
+ */\r
+void\r
+ipoib_set_inactive(\r
+       IN                              ipoib_adapter_t* const          p_adapter )\r
+{\r
+       ib_pnp_event_t  old_state;\r
+       NDIS_LINK_STATE         link_state;\r
+       NDIS_STATUS_INDICATION  status_indication;\r
+\r
+       IPOIB_ENTER( IPOIB_DBG_INIT );\r
+\r
+       NdisZeroMemory(&link_state, sizeof(NDIS_LINK_STATE));\r
+       cl_obj_lock( &p_adapter->obj );\r
+       old_state = p_adapter->state;\r
+       if( old_state != IB_PNP_PORT_REMOVE )\r
+               p_adapter->state = IB_PNP_PORT_DOWN;\r
+       cl_obj_unlock( &p_adapter->obj );\r
+\r
+       /*\r
+        * If we had a pending OID request for OID_GEN_LINK_SPEED,\r
+        * complete it now.\r
+        */\r
+       if( old_state == IB_PNP_PORT_INIT )\r
+       {\r
+               link_state.Header.Revision = NDIS_LINK_STATE_REVISION_1;\r
+               link_state.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;\r
+               link_state.Header.Size = sizeof(NDIS_LINK_STATE);\r
+               link_state.MediaConnectState = MediaConnectStateDisconnected;\r
+               link_state.MediaDuplexState = MediaDuplexStateFull;\r
+               link_state.XmitLinkSpeed = link_state.RcvLinkSpeed = IPOIB_MEDIA_MAX_SPEED;\r
+\r
+               IPOIB_INIT_NDIS_STATUS_INDICATION(&status_indication,\r
+                                                          p_adapter->h_adapter,\r
+                                                          NDIS_STATUS_LINK_STATE,\r
+                                                          (PVOID)&link_state,\r
+                                                          sizeof(link_state));\r
+               IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT, ("Indicate Disconnect!\n") );\r
+               NdisMIndicateStatusEx(p_adapter->h_adapter,&status_indication);\r
+\r
+               ipoib_resume_oids( p_adapter );\r
+       }\r
+\r
+       if( p_adapter->reset )\r
+       {\r
+               p_adapter->reset = FALSE;\r
+               NdisMResetComplete(\r
+                       p_adapter->h_adapter, NDIS_STATUS_SUCCESS, TRUE );\r
+       }\r
+\r
+       IPOIB_EXIT( IPOIB_DBG_INIT );\r
+}\r
+\r
+NDIS_STATUS\r
+ipoib_get_gen_stat(\r
+       IN                              ipoib_adapter_t* const          p_adapter,\r
+       OUT             pending_oid_t* const            p_oid_info)\r
+{\r
+       PNDIS_STATISTICS_INFO StatisticsInfo;\r
+       IPOIB_ENTER( IPOIB_DBG_STAT );\r
+\r
+       if (p_oid_info->buf_len < sizeof(StatisticsInfo))\r
+       {\r
+               *p_oid_info->p_bytes_needed = sizeof(NDIS_STATISTICS_INFO);\r
+               return NDIS_STATUS_INVALID_LENGTH;\r
+       }\r
+\r
+       StatisticsInfo = (PNDIS_STATISTICS_INFO)p_oid_info->p_buf;\r
+    StatisticsInfo->Header.Revision = NDIS_OBJECT_REVISION_1;\r
+    StatisticsInfo->Header.Type = NDIS_OBJECT_TYPE_DEFAULT;\r
+    StatisticsInfo->Header.Size = sizeof(NDIS_STATISTICS_INFO);\r
+    /*StatisticsInfo->SupportedStatistics = NDIS_STATISTICS_FLAGS_VALID_RCV_DISCARDS          |\r
+                                          NDIS_STATISTICS_FLAGS_VALID_RCV_ERROR             |\r
+                                                                                 NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_RCV   |\r
+                                          NDIS_STATISTICS_FLAGS_VALID_MULTICAST_FRAMES_RCV  |\r
+                                                                                 NDIS_STATISTICS_FLAGS_VALID_BROADCAST_FRAMES_RCV  |\r
+                                          NDIS_STATISTICS_FLAGS_VALID_BYTES_RCV             | \r
+                                          NDIS_STATISTICS_FLAGS_VALID_MULTICAST_BYTES_RCV   |\r
+                                                                                 NDIS_STATISTICS_FLAGS_VALID_BROADCAST_BYTES_RCV       |\r
+                                                                                 NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_RCV        |\r
+\r
+                                                                                 NDIS_STATISTICS_FLAGS_VALID_XMIT_DISCARDS                     |\r
+                                                                                 NDIS_STATISTICS_FLAGS_VALID_XMIT_ERROR            |\r
+                                                                                 NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_XMIT  | \r
+                                          NDIS_STATISTICS_FLAGS_VALID_MULTICAST_FRAMES_XMIT |\r
+                                                                                 NDIS_STATISTICS_FLAGS_VALID_BROADCAST_FRAMES_XMIT |\r
+                                                                                 NDIS_STATISTICS_FLAGS_VALID_BYTES_XMIT                        |\r
+                                                                                 NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_XMIT       |\r
+                                                                                 NDIS_STATISTICS_FLAGS_VALID_MULTICAST_BYTES_XMIT      |\r
+                                                                                 NDIS_STATISTICS_FLAGS_VALID_BROADCAST_BYTES_XMIT; */\r
+                                                                                 \r
+                                                                                 \r
+       StatisticsInfo->SupportedStatistics =  NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_RCV |\r
+                                                                                       //The data in the ifHCInUcastPkts member is valid. \r
+                                                                                       NDIS_STATISTICS_FLAGS_VALID_MULTICAST_FRAMES_RCV |\r
+                                                                                       //The data in the ifHCInMulticastPkts member is valid. \r
+                                                                                       NDIS_STATISTICS_FLAGS_VALID_BROADCAST_FRAMES_RCV |\r
+                                                                                       //The data in the ifHCInBroadcastPkts member is valid. \r
+                                                                                       NDIS_STATISTICS_FLAGS_VALID_BYTES_RCV |\r
+                                                                                       //The data in the ifHCInOctets member is valid. \r
+                                                                                       NDIS_STATISTICS_FLAGS_VALID_RCV_DISCARDS |\r
+                                                                                       //The data in the ifInDiscards member is valid. \r
+                                                                                       NDIS_STATISTICS_FLAGS_VALID_RCV_ERROR |\r
+                                                                                       //The data in the ifInErrors member is valid. \r
+                                                                                       NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_XMIT |\r
+                                                                                       //The data in the ifHCOutUcastPkts member is valid. \r
+                                                                                       NDIS_STATISTICS_FLAGS_VALID_MULTICAST_FRAMES_XMIT |\r
+                                                                                       //The data in the ifHCOutMulticastPkts member is valid. \r
+                                                                                       NDIS_STATISTICS_FLAGS_VALID_BROADCAST_FRAMES_XMIT |\r
+                                                                                       //The data in the ifHCOutBroadcastPkts member is valid. \r
+                                                                                       NDIS_STATISTICS_FLAGS_VALID_BYTES_XMIT |\r
+                                                                                       //The data in the ifHCOutOctets member is valid. \r
+                                                                                       NDIS_STATISTICS_FLAGS_VALID_XMIT_ERROR |\r
+                                                                                       //The data in the ifOutErrors member is valid. \r
+                                                                                       NDIS_STATISTICS_FLAGS_VALID_XMIT_DISCARDS |\r
+                                                                                       //The data in the ifOutDiscards member is valid. \r
+                                                                                       NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_RCV |\r
+                                                                                       //The data in the ifHCInUcastOctets member is valid. \r
+                                                                                       NDIS_STATISTICS_FLAGS_VALID_MULTICAST_BYTES_RCV |\r
+                                                                                       //The data in the ifHCInMulticastOctets member is valid. \r
+                                                                                       NDIS_STATISTICS_FLAGS_VALID_BROADCAST_BYTES_RCV |\r
+                                                                                       //The data in the ifHCInBroadcastOctets member is valid. \r
+                                                                                       NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_XMIT |\r
+                                                                                       //The data in the ifHCOutUcastOctets member is valid. \r
+                                                                                       NDIS_STATISTICS_FLAGS_VALID_MULTICAST_BYTES_XMIT |\r
+                                                                                       //The data in the ifHCOutMulticastOctets member is valid. \r
+                                                                                       NDIS_STATISTICS_FLAGS_VALID_BROADCAST_BYTES_XMIT ;\r
+                                                                                       //The data in the ifHCOutBroadcastOctets member is valid\r
+\r
+    cl_spinlock_acquire( &p_adapter->recv_stat_lock );\r
+    StatisticsInfo->ifInDiscards = p_adapter->recv_stats.comp.dropped +\r
+                                   p_adapter->recv_stats.comp.error;            \r
+    StatisticsInfo->ifInErrors = p_adapter->recv_stats.comp.error;\r
+    StatisticsInfo->ifHCInOctets = p_adapter->recv_stats.ucast.bytes + \r
+                                                                  p_adapter->recv_stats.bcast.bytes + \r
+                                                                  p_adapter->recv_stats.mcast.bytes;       \r
+    StatisticsInfo->ifHCInUcastPkts       = p_adapter->recv_stats.ucast.frames;\r
+    StatisticsInfo->ifHCInMulticastPkts   = p_adapter->recv_stats.mcast.frames;  \r
+    StatisticsInfo->ifHCInBroadcastPkts   = p_adapter->recv_stats.bcast.frames;  \r
+       StatisticsInfo->ifHCInMulticastOctets = p_adapter->recv_stats.mcast.bytes;\r
+       StatisticsInfo->ifHCInBroadcastOctets = p_adapter->recv_stats.bcast.bytes;\r
+       StatisticsInfo->ifHCInUcastOctets     = p_adapter->recv_stats.ucast.bytes;\r
+       cl_spinlock_release( &p_adapter->recv_stat_lock );\r
+\r
+    cl_spinlock_acquire( &p_adapter->send_stat_lock ); \r
+    StatisticsInfo->ifHCOutOctets = p_adapter->send_stats.ucast.bytes + \r
+                                                                       p_adapter->send_stats.mcast.bytes + \r
+                                                                       p_adapter->send_stats.bcast.bytes;        \r
+    StatisticsInfo->ifHCOutUcastPkts       = p_adapter->send_stats.ucast.frames;     \r
+    StatisticsInfo->ifHCOutMulticastPkts   = p_adapter->send_stats.mcast.frames; \r
+    StatisticsInfo->ifHCOutBroadcastPkts   = p_adapter->send_stats.bcast.frames; \r
+    StatisticsInfo->ifOutErrors            = p_adapter->send_stats.comp.error;                                      \r
+    StatisticsInfo->ifOutDiscards          = p_adapter->send_stats.comp.dropped;\r
+       StatisticsInfo->ifHCOutUcastOctets     = p_adapter->send_stats.ucast.bytes;\r
+       StatisticsInfo->ifHCOutMulticastOctets = p_adapter->send_stats.mcast.bytes;\r
+       StatisticsInfo->ifHCOutBroadcastOctets = p_adapter->send_stats.bcast.bytes;\r
+    cl_spinlock_release( &p_adapter->send_stat_lock );\r
+\r
+       *p_oid_info->p_bytes_used = sizeof(NDIS_STATISTICS_INFO);\r
+\r
+       IPOIB_EXIT( IPOIB_DBG_INIT );\r
+       return NDIS_STATUS_SUCCESS;\r
+}\r
+\r
+NDIS_STATUS\r
+ipoib_get_recv_stat(\r
+       IN                              ipoib_adapter_t* const          p_adapter,\r
+       IN              const   ip_stat_sel_t                           stat_sel,\r
+       IN                              pending_oid_t* const            p_oid_info )\r
+{\r
+       uint64_t        stat;\r
+\r
+       IPOIB_ENTER( IPOIB_DBG_STAT );\r
+\r
+       CL_ASSERT( p_adapter );\r
+\r
+       cl_spinlock_acquire( &p_adapter->recv_stat_lock );\r
+       switch( stat_sel )\r
+       {\r
+       case IP_STAT_SUCCESS:\r
+               stat = p_adapter->recv_stats.comp.success;\r
+               break;\r
+\r
+       case IP_STAT_ERROR:\r
+               stat = p_adapter->recv_stats.comp.error;\r
+               break;\r
+\r
+       case IP_STAT_DROPPED:\r
+               stat = p_adapter->recv_stats.comp.dropped;\r
+               break;\r
+\r
+       case IP_STAT_UCAST_BYTES:\r
+               stat = p_adapter->recv_stats.ucast.bytes;\r
+               break;\r
+\r
+       case IP_STAT_UCAST_FRAMES:\r
+               stat = p_adapter->recv_stats.ucast.frames;\r
+               break;\r
+\r
+       case IP_STAT_BCAST_BYTES:\r
+               stat = p_adapter->recv_stats.bcast.bytes;\r
+               break;\r
+\r
+       case IP_STAT_BCAST_FRAMES:\r
+               stat = p_adapter->recv_stats.bcast.frames;\r
+               break;\r
+\r
+       case IP_STAT_MCAST_BYTES:\r
+               stat = p_adapter->recv_stats.mcast.bytes;\r
+               break;\r
+\r
+       case IP_STAT_MCAST_FRAMES:\r
+               stat = p_adapter->recv_stats.mcast.frames;\r
+               break;\r
+\r
+       default:\r
+               stat = 0;\r
+       }\r
+       cl_spinlock_release( &p_adapter->recv_stat_lock );\r
+\r
+       *p_oid_info->p_bytes_needed = sizeof(uint64_t);\r
+\r
+       if( p_oid_info->buf_len >= sizeof(uint64_t) )\r
+       {\r
+               *((uint64_t*)p_oid_info->p_buf) = stat;\r
+               *p_oid_info->p_bytes_used = sizeof(uint64_t);\r
+       }\r
+       else if( p_oid_info->buf_len >= sizeof(uint32_t) )\r
+       {\r
+               *((uint32_t*)p_oid_info->p_buf) = (uint32_t)stat;\r
+               *p_oid_info->p_bytes_used = sizeof(uint32_t);\r
+       }\r
+       else\r
+       {\r
+               *p_oid_info->p_bytes_used = 0;\r
+               IPOIB_EXIT( IPOIB_DBG_STAT );\r
+               return NDIS_STATUS_INVALID_LENGTH;\r
+       }\r
+\r
+       IPOIB_EXIT( IPOIB_DBG_STAT );\r
+       return NDIS_STATUS_SUCCESS;\r
+}\r
+\r
+\r
+void\r
+ipoib_inc_recv_stat(\r
+       IN                              ipoib_adapter_t* const          p_adapter,\r
+       IN              const   ip_stat_sel_t                           stat_sel,\r
+       IN              const   size_t                                          bytes OPTIONAL,\r
+       IN              const   size_t                                          packets OPTIONAL )\r
+{\r
+       IPOIB_ENTER( IPOIB_DBG_STAT );\r
+\r
+       cl_spinlock_acquire( &p_adapter->recv_stat_lock );\r
+       switch( stat_sel )\r
+       {\r
+       case IP_STAT_ERROR:\r
+               p_adapter->recv_stats.comp.error++;\r
+               break;\r
+\r
+       case IP_STAT_DROPPED:\r
+               p_adapter->recv_stats.comp.dropped++;\r
+               break;\r
+\r
+       case IP_STAT_UCAST_BYTES:\r
+       case IP_STAT_UCAST_FRAMES:\r
+               p_adapter->recv_stats.comp.success++;\r
+               p_adapter->recv_stats.ucast.frames += packets;\r
+               p_adapter->recv_stats.ucast.bytes += bytes;\r
+               break;\r
+\r
+       case IP_STAT_BCAST_BYTES:\r
+       case IP_STAT_BCAST_FRAMES:\r
+               p_adapter->recv_stats.comp.success++;\r
+               p_adapter->recv_stats.bcast.frames += packets;\r
+               p_adapter->recv_stats.bcast.bytes += bytes;\r
+               break;\r
+\r
+       case IP_STAT_MCAST_BYTES:\r
+       case IP_STAT_MCAST_FRAMES:\r
+               p_adapter->recv_stats.comp.success++;\r
+               p_adapter->recv_stats.mcast.frames += packets;\r
+               p_adapter->recv_stats.mcast.bytes += bytes;\r
+               break;\r
+\r
+       default:\r
+               break;\r
+       }\r
+       cl_spinlock_release( &p_adapter->recv_stat_lock );\r
+\r
+       IPOIB_EXIT( IPOIB_DBG_STAT );\r
+}\r
+\r
+NDIS_STATUS\r
+ipoib_get_send_stat(\r
+       IN                              ipoib_adapter_t* const          p_adapter,\r
+       IN              const   ip_stat_sel_t                           stat_sel,\r
+       IN                              pending_oid_t* const            p_oid_info )\r
+{\r
+       uint64_t        stat;\r
+\r
+       IPOIB_ENTER( IPOIB_DBG_STAT );\r
+\r
+       CL_ASSERT( p_adapter );\r
+\r
+       cl_spinlock_acquire( &p_adapter->send_stat_lock );\r
+       switch( stat_sel )\r
+       {\r
+       case IP_STAT_SUCCESS:\r
+               stat = p_adapter->send_stats.comp.success;\r
+               break;\r
+\r
+       case IP_STAT_ERROR:\r
+               stat = p_adapter->send_stats.comp.error;\r
+               break;\r
+\r
+       case IP_STAT_DROPPED:\r
+               stat = p_adapter->send_stats.comp.dropped;\r
+               break;\r
+\r
+       case IP_STAT_UCAST_BYTES:\r
+               stat = p_adapter->send_stats.ucast.bytes;\r
+               break;\r
+\r
+       case IP_STAT_UCAST_FRAMES:\r
+               stat = p_adapter->send_stats.ucast.frames;\r
+               break;\r
+\r
+       case IP_STAT_BCAST_BYTES:\r
+               stat = p_adapter->send_stats.bcast.bytes;\r
+               break;\r
+\r
+       case IP_STAT_BCAST_FRAMES:\r
+               stat = p_adapter->send_stats.bcast.frames;\r
+               break;\r
+\r
+       case IP_STAT_MCAST_BYTES:\r
+               stat = p_adapter->send_stats.mcast.bytes;\r
+               break;\r
+\r
+       case IP_STAT_MCAST_FRAMES:\r
+               stat = p_adapter->send_stats.mcast.frames;\r
+               break;\r
+\r
+       default:\r
+               stat = 0;\r
+       }\r
+       cl_spinlock_release( &p_adapter->send_stat_lock );\r
+\r
+       *p_oid_info->p_bytes_needed = sizeof(uint64_t);\r
+\r
+       if( p_oid_info->buf_len >= sizeof(uint64_t) )\r
+       {\r
+               *((uint64_t*)p_oid_info->p_buf) = stat;\r
+               *p_oid_info->p_bytes_used = sizeof(uint64_t);\r
+       }\r
+       else if( p_oid_info->buf_len >= sizeof(uint32_t) )\r
+       {\r
+               *((uint32_t*)p_oid_info->p_buf) = (uint32_t)stat;\r
+               *p_oid_info->p_bytes_used = sizeof(uint32_t);\r
+       }\r
+       else\r
+       {\r
+               *p_oid_info->p_bytes_used = 0;\r
+               IPOIB_EXIT( IPOIB_DBG_STAT );\r
+               return NDIS_STATUS_INVALID_LENGTH;\r
+       }\r
+\r
+       IPOIB_EXIT( IPOIB_DBG_STAT );\r
+       return NDIS_STATUS_SUCCESS;\r
+}\r
+\r
+\r
+void\r
+ipoib_inc_send_stat(\r
+       IN                              ipoib_adapter_t* const          p_adapter,\r
+       IN              const   ip_stat_sel_t                           stat_sel,\r
+       IN              const   size_t                                          bytes OPTIONAL )\r
+{\r
+       IPOIB_ENTER( IPOIB_DBG_STAT );\r
+\r
+       cl_spinlock_acquire( &p_adapter->send_stat_lock );\r
+       switch( stat_sel )\r
+       {\r
+       case IP_STAT_ERROR:\r
+               p_adapter->send_stats.comp.error++;\r
+               break;\r
+\r
+       case IP_STAT_DROPPED:\r
+               p_adapter->send_stats.comp.dropped++;\r
+               break;\r
+\r
+       case IP_STAT_UCAST_BYTES:\r
+       case IP_STAT_UCAST_FRAMES:\r
+               p_adapter->send_stats.comp.success++;\r
+               p_adapter->send_stats.ucast.frames++;\r
+               p_adapter->send_stats.ucast.bytes += bytes;\r
+               break;\r
+\r
+       case IP_STAT_BCAST_BYTES:\r
+       case IP_STAT_BCAST_FRAMES:\r
+               p_adapter->send_stats.comp.success++;\r
+               p_adapter->send_stats.bcast.frames++;\r
+               p_adapter->send_stats.bcast.bytes += bytes;\r
+               break;\r
+\r
+       case IP_STAT_MCAST_BYTES:\r
+       case IP_STAT_MCAST_FRAMES:\r
+               p_adapter->send_stats.comp.success++;\r
+               p_adapter->send_stats.mcast.frames++;\r
+               p_adapter->send_stats.mcast.bytes += bytes;\r
+               break;\r
+\r
+       default:\r
+               break;\r
+       }\r
+       cl_spinlock_release( &p_adapter->send_stat_lock );\r
+\r
+       IPOIB_EXIT( IPOIB_DBG_STAT );\r
+}\r
diff --git a/ulp/ipoib/kernel6/ipoib_adapter.h b/ulp/ipoib/kernel6/ipoib_adapter.h
new file mode 100644 (file)
index 0000000..f8ab4c4
--- /dev/null
@@ -0,0 +1,483 @@
+/*\r
+ * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.\r
+ * Copyright (c) 2006 Mellanox Technologies.  All rights reserved.\r
+ * Portions Copyright (c) 2008 Microsoft Corporation.  All rights reserved.\r
+ *\r
+ * This software is available to you under the OpenIB.org BSD license\r
+ * below:\r
+ *\r
+ *     Redistribution and use in source and binary forms, with or\r
+ *     without modification, are permitted provided that the following\r
+ *     conditions are met:\r
+ *\r
+ *      - Redistributions of source code must retain the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer.\r
+ *\r
+ *      - Redistributions in binary form must reproduce the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer in the documentation and/or other materials\r
+ *        provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ * $Id: ipoib_adapter.h 4226 2009-04-06 06:01:03Z xalex $\r
+ */\r
+\r
+\r
+#ifndef _IPOIB_ADAPTER_H_\r
+#define _IPOIB_ADAPTER_H_\r
+\r
+#include <iba/ipoib_ifc.h>\r
+#include <iba/ib_al.h>\r
+#include <complib/cl_obj.h>\r
+#include <complib/cl_spinlock.h>\r
+#include <complib/cl_mutex.h>\r
+#include <complib/cl_qpool.h>\r
+#include <complib/cl_atomic.h>\r
+#include <complib/cl_perf.h>\r
+#include <complib/cl_vector.h>\r
+#include <ip_packet.h>\r
+#include "ip_stats.h"\r
+\r
+\r
+/*\r
+ * Definitions\r
+ */\r
+#define MAX_MCAST                              32\r
+\r
+#define IPV4_ADDR_SIZE                 4\r
+\r
+#define PORT_NUM_INDEX_IN_GUID 3 /* 0 based index into big endian GUID to get port number */\r
+\r
+/*\r
+ * Macros\r
+ */\r
+typedef enum \r
+{\r
+       CSUM_DISABLED = 0, \r
+       CSUM_ENABLED, \r
+       CSUM_BYPASS\r
+} csum_flag_t;\r
+\r
+typedef enum _ipoib_state\r
+{\r
+    IPOIB_PAUSED,\r
+    IPOIB_PAUSING,\r
+    IPOIB_RUNNING\r
+} ipoib_state_t;\r
+\r
+typedef struct _ipoib_params\r
+{\r
+       int32_t         rq_depth;\r
+       int32_t         rq_low_watermark;\r
+       int32_t         sq_depth;\r
+       csum_flag_t     send_chksum_offload;\r
+       csum_flag_t     recv_chksum_offload;\r
+       uint32_t        sa_timeout;\r
+       uint32_t        sa_retry_cnt;\r
+       uint32_t        recv_pool_ratio;\r
+       uint32_t        payload_mtu;\r
+       boolean_t       lso;\r
+       uint32_t        xfer_block_size;\r
+       mac_addr_t      conf_mac;\r
+       uint32_t        mc_leave_rescan;\r
+       uint32_t        guid_mask;\r
+       uint32_t        bc_join_retry;\r
+       boolean_t       cm_enabled;\r
+       uint32_t        cm_payload_mtu;\r
+       uint32_t        cm_xfer_block_size;\r
+}      ipoib_params_t;\r
+/*\r
+* FIELDS\r
+*      rq_depth\r
+*              Number of receive WQEs to allocate.\r
+*\r
+*      rq_low_watermark\r
+*              Receives are indicated with NDIS_STATUS_RESOURCES when the number of\r
+*              receives posted to the RQ falls bellow this value.\r
+*\r
+*      sq_depth\r
+*              Number of send WQEs to allocate.\r
+*\r
+*      send_chksum_offload\r
+*      recv_chksum_offload\r
+*              Flags to indicate whether to offload send/recv checksums.\r
+*              0 - No hardware cheksum\r
+*              1 - Try to offload if the device support it\r
+*              2 - Always report success (checksum bypass)\r
+*\r
+*      wsdp_enabled\r
+*              Flag to indicate whether WSDP is enabled for an adapter adapter.\r
+*\r
+*      static_lid\r
+*              LID to assign to the port if that port is down (not init) and has none.\r
+*              This feature allows a LID to be assigned, alowing locally targetted\r
+*              traffic to occur even on ports that are not plugged in.\r
+*\r
+*      sa_timeout\r
+*              Time, in milliseconds, to wait for a response before retransmitting an\r
+*              SA query request.\r
+*\r
+*      sa_retry_cnt\r
+*              Number of times to retry an SA query request.\r
+*\r
+*      recv_pool_ratio\r
+*              Initial ratio of receive pool size to receive queue depth.\r
+*\r
+*      grow_thresh\r
+*              Threshold at which to grow the receive pool.  Valid values start are\r
+*              powers of 2, excluding 1.  When zero, grows only when the pool is\r
+*              exhausted.  Other values indicate fractional values\r
+*              (i.e. 2 indicates 1/2, 4 indicates 1/4, etc.)\r
+*\r
+*      payload_mtu\r
+               The maximum available size of IPoIB transfer unit.\r
+               \r
+               If using UD mode:\r
+*              It should be decremented by size of IPoIB header (==4B)\r
+*              For example, if the HCA support 4K MTU, \r
+*              upper threshold for payload mtu is 4092B and not 4096B\r
+\r
+               If using CM mode:\r
+               MTU will be not limited by 4K threshold.\r
+               UD QP still may be used for different protocols (like ARP).\r
+               For these situations the threshold for the UD QP will take the default value\r
+               \r
+*\r
+*      lso\r
+*      It indicates if there's a support for hardware large/giant send offload\r
+*              \r
+*********/\r
+\r
+\r
+typedef struct _pending_oid\r
+{\r
+       NDIS_OID                        oid;\r
+       PVOID                           p_buf;\r
+       ULONG                           buf_len;\r
+       PULONG                          p_bytes_used;\r
+       PULONG                          p_bytes_needed;\r
+       PNDIS_OID_REQUEST       p_pending_oid;\r
+}      pending_oid_t;\r
+\r
+\r
+typedef struct _ipoib_adapter\r
+{\r
+       cl_obj_t                                obj;\r
+       NDIS_HANDLE                             h_adapter;\r
+       ipoib_ifc_data_t                guids;\r
+\r
+       cl_list_item_t                  entry;\r
+\r
+       ib_al_handle_t                  h_al;\r
+       ib_pnp_handle_t                 h_pnp;\r
+\r
+       ib_pnp_event_t                  state;\r
+       boolean_t                               hung;\r
+       boolean_t                               reset;\r
+       boolean_t                               registering;\r
+\r
+       boolean_t                               pending_query;\r
+       pending_oid_t                   query_oid;\r
+       boolean_t                               pending_set;\r
+       pending_oid_t                   set_oid;\r
+\r
+       struct _ipoib_port              *p_port;\r
+\r
+       uint32_t                                port_rate;\r
+\r
+       ipoib_params_t                  params;\r
+       cl_spinlock_t                   recv_stat_lock;\r
+       ip_stats_t                              recv_stats;\r
+       cl_spinlock_t                   send_stat_lock;\r
+       ip_stats_t                              send_stats;\r
+\r
+       boolean_t                               is_primary;\r
+       struct _ipoib_adapter   *p_primary;\r
+\r
+       uint32_t                                packet_filter;\r
+\r
+       mac_addr_t                              mac;\r
+       mac_addr_t                              mcast_array[MAX_MCAST];\r
+       uint8_t                                 mcast_array_size;\r
+\r
+       cl_qpool_t                              item_pool;\r
+\r
+       KMUTEX                                  mutex;\r
+\r
+       cl_thread_t                             destroy_thread;\r
+       cl_vector_t                             ip_vector;\r
+\r
+       cl_perf_t                               perf;\r
+    NDIS_HANDLE                        NdisMiniportDmaHandle;\r
+       ipoib_state_t                   ipoib_state;\r
+       ib_al_ifc_t                             *p_ifc;\r
+\r
+       ULONG                                   sg_list_size;\r
+\r
+}      ipoib_adapter_t;\r
+/*\r
+* FIELDS\r
+*      obj\r
+*              Complib object for reference counting and destruction synchronization.\r
+*\r
+*      h_adapter\r
+*              NDIS adapter handle.\r
+*\r
+*      guids\r
+*              CA and port GUIDs returned by the bus driver.\r
+*\r
+*      entry\r
+*              List item for storing all adapters in a list for address translation.\r
+*              We add adapters when their packet filter is set to a non-zero value,\r
+*              and remove them when their packet filter is cleared.  This is needed\r
+*              since user-mode removal events are generated after the packet filter\r
+*              is cleared, but before the adapter is destroyed.\r
+*\r
+*      h_al\r
+*              AL handle for all IB resources.\r
+*\r
+*      h_pnp\r
+*              PNP registration handle for port events.\r
+*\r
+*      state\r
+*              State of the adapter.  IB_PNP_PORT_ADD indicates that the adapter\r
+*              is ready to transfer data.\r
+*\r
+*      hung\r
+*              Boolean flag used to return whether we are hung or not.\r
+*\r
+*      p_port\r
+*              Pointer to an ipoib_port_t representing all resources for moving data\r
+*              on the IB fabric.\r
+*\r
+*      rate\r
+*              Rate, in 100bps increments, of the link.\r
+*\r
+*      params\r
+*              Configuration parameters.\r
+*\r
+*      pending_query\r
+*              Indicates that an query OID request is being processed asynchronously.\r
+*\r
+*      query_oid\r
+*              Information about the pended query OID request.\r
+*              Valid only if pending_query is TRUE.\r
+*\r
+*      pending_set\r
+*              Indicates that an set OID request is being processed asynchronously.\r
+*\r
+*      set_oid\r
+*              Information about the pended set OID request.\r
+*              Valid only if pending_set is TRUE.\r
+*\r
+*      recv_lock\r
+*              Spinlock protecting receive processing.\r
+*\r
+*      recv_stats\r
+*              Receive statistics.\r
+*\r
+*      send_lock\r
+*              Spinlock protecting send processing.\r
+*\r
+*      send_stats\r
+*              Send statistics.\r
+*\r
+*      is_primary\r
+*              Boolean flag to indicate if an adapter is the primary adapter\r
+*              of a bundle.\r
+*\r
+*      p_primary\r
+*              Pointer to the primary adapter for a bundle.\r
+*\r
+*      packet_filter\r
+*              Packet filter set by NDIS.\r
+*\r
+*      mac_addr\r
+*              Ethernet MAC address reported to NDIS.\r
+*\r
+*      mcast_array\r
+*              List of multicast MAC addresses programmed by NDIS.\r
+*\r
+*      mcast_array_size\r
+*              Number of entries in the multicat MAC address array;\r
+*\r
+*      item_pool\r
+*              Pool of cl_pool_obj_t structures to use for queueing pending\r
+*              packets for transmission.\r
+*\r
+*      mutex\r
+*              Mutex to synchronized PnP callbacks with destruction.\r
+*\r
+*      ip_vector\r
+*              Vector of assigned IP addresses.\r
+*\r
+*      p_ifc\r
+*              Pointer to transport interface.\r
+*\r
+*********/\r
+\r
+\r
+typedef struct _ats_reg\r
+{\r
+       ipoib_adapter_t         *p_adapter;\r
+       ib_reg_svc_handle_t     h_reg_svc;\r
+\r
+}      ats_reg_t;\r
+/*\r
+* FIELDS\r
+*      p_adapter\r
+*              Pointer to the adapter to which this address is assigned.\r
+*\r
+*      h_reg_svc\r
+*              Service registration handle.\r
+*********/\r
+\r
+\r
+typedef struct _net_address_item\r
+{\r
+       ats_reg_t                       *p_reg;\r
+       union _net_address_item_address\r
+       {\r
+               ULONG                   as_ulong;\r
+               UCHAR                   as_bytes[IPV4_ADDR_SIZE];\r
+       }       address;\r
+\r
+}      net_address_item_t;\r
+/*\r
+* FIELDS\r
+*      p_reg\r
+*              Pointer to the ATS registration assigned to this address.\r
+*\r
+*      address\r
+*              Union representing the IP address as an unsigned long or as\r
+*              an array of bytes.\r
+*\r
+*      as_ulong\r
+*              The IP address represented as an unsigned long.  Windows stores\r
+*              IPs this way.\r
+*\r
+*      as_bytes\r
+*              The IP address represented as an array of bytes.\r
+*********/\r
+\r
+\r
+ib_api_status_t\r
+ipoib_create_adapter(\r
+       IN              NDIS_HANDLE                     wrapper_config_context,\r
+       IN              void* const                     h_adapter,\r
+       OUT             ipoib_adapter_t**  const        pp_adapter );\r
+\r
+\r
+ib_api_status_t\r
+ipoib_start_adapter(\r
+       IN                              ipoib_adapter_t* const          p_adapter );\r
+\r
+\r
+void\r
+ipoib_destroy_adapter(\r
+       IN                              ipoib_adapter_t* const          p_adapter );\r
+\r
+\r
+/* Joins/leaves mcast groups based on currently programmed mcast MACs. */\r
+void\r
+ipoib_refresh_mcast(\r
+       IN                              ipoib_adapter_t* const          p_adapter,\r
+       IN                              mac_addr_t* const                       p_mac_array,\r
+       IN              const   uint8_t                                         num_macs );\r
+/*\r
+* PARAMETERS\r
+*      p_adapter\r
+*              Instance whose multicast MAC address list to modify.\r
+*\r
+*      p_mac_array\r
+*              Array of multicast MAC addresses assigned to the adapter.\r
+*\r
+*      num_macs\r
+*              Number of MAC addresses in the array.\r
+*********/\r
+NDIS_STATUS\r
+ipoib_get_gen_stat(\r
+       IN                              ipoib_adapter_t* const          p_adapter,\r
+       OUT             pending_oid_t* const            p_oid_info );\r
+\r
+NDIS_STATUS\r
+ipoib_get_recv_stat(\r
+       IN                              ipoib_adapter_t* const          p_adapter,\r
+       IN              const   ip_stat_sel_t                           stat_sel,\r
+       IN                              pending_oid_t* const            p_oid_info );\r
+\r
+\r
+void\r
+ipoib_inc_recv_stat(\r
+       IN                              ipoib_adapter_t* const          p_adapter,\r
+       IN              const   ip_stat_sel_t                           stat_sel,\r
+       IN              const   size_t                                          bytes OPTIONAL,\r
+       IN              const   size_t                                          packets OPTIONAL );\r
+\r
+\r
+NDIS_STATUS\r
+ipoib_get_send_stat(\r
+       IN                              ipoib_adapter_t* const          p_adapter,\r
+       IN              const   ip_stat_sel_t                           stat_sel,\r
+       IN                              pending_oid_t* const            p_oid_info );\r
+\r
+\r
+void\r
+ipoib_inc_send_stat(\r
+       IN                              ipoib_adapter_t* const          p_adapter,\r
+       IN              const   ip_stat_sel_t                           stat_sel,\r
+       IN              const   size_t                                          bytes OPTIONAL );\r
+\r
+\r
+void\r
+ipoib_set_rate(\r
+       IN                              ipoib_adapter_t* const          p_adapter,\r
+       IN              const   uint8_t                                         link_width,\r
+       IN              const   uint8_t                                         link_speed );\r
+\r
+\r
+ib_api_status_t\r
+ipoib_set_active(\r
+       IN                              ipoib_adapter_t* const          p_adapter );\r
+\r
+void\r
+ipoib_set_inactive(\r
+       IN                              ipoib_adapter_t* const          p_adapter );\r
+\r
+ib_api_status_t\r
+ipoib_reset_adapter(\r
+       IN                              ipoib_adapter_t* const          p_adapter );\r
+\r
+void\r
+ipoib_reg_addrs(\r
+       IN                              ipoib_adapter_t* const          p_adapter );\r
+\r
+void\r
+ipoib_dereg_addrs(\r
+       IN                              ipoib_adapter_t* const          p_adapter );\r
+\r
+#define IPOIB_INIT_NDIS_STATUS_INDICATION(_pStatusIndication, _M, _St, _Buf, _BufSize)        \\r
+    {                                                                                      \\r
+        NdisZeroMemory(_pStatusIndication, sizeof(NDIS_STATUS_INDICATION));                \\r
+        (_pStatusIndication)->Header.Type = NDIS_OBJECT_TYPE_STATUS_INDICATION;            \\r
+        (_pStatusIndication)->Header.Revision = NDIS_STATUS_INDICATION_REVISION_1;         \\r
+        (_pStatusIndication)->Header.Size = sizeof(NDIS_STATUS_INDICATION);                \\r
+        (_pStatusIndication)->SourceHandle = _M;                                           \\r
+        (_pStatusIndication)->StatusCode = _St;                                            \\r
+        (_pStatusIndication)->StatusBuffer = _Buf;                                         \\r
+        (_pStatusIndication)->StatusBufferSize = _BufSize;                                 \\r
+    }\r
+\r
+//TODO rename to 4\r
+#define IPOIB_MEDIA_MAX_SPEED  10000000000\r
+\r
+#endif /* _IPOIB_ADAPTER_H_ */\r
diff --git a/ulp/ipoib/kernel6/ipoib_cm.c b/ulp/ipoib/kernel6/ipoib_cm.c
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/ulp/ipoib/kernel6/ipoib_debug.h b/ulp/ipoib/kernel6/ipoib_debug.h
new file mode 100644 (file)
index 0000000..69ec3c5
--- /dev/null
@@ -0,0 +1,303 @@
+/*\r
+ * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.\r
+ * Copyright (c) 2006 Mellanox Technologies.  All rights reserved.\r
+ *\r
+ * This software is available to you under the OpenIB.org BSD license\r
+ * below:\r
+ *\r
+ *     Redistribution and use in source and binary forms, with or\r
+ *     without modification, are permitted provided that the following\r
+ *     conditions are met:\r
+ *\r
+ *      - Redistributions of source code must retain the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer.\r
+ *\r
+ *      - Redistributions in binary form must reproduce the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer in the documentation and/or other materials\r
+ *        provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ * $Id: ipoib_debug.h 3719 2009-01-07 12:31:52Z reuven $\r
+ */\r
+\r
+\r
+#ifndef _IPOIB_DEBUG_H_\r
+#define _IPOIB_DEBUG_H_\r
+\r
+#if defined __MODULE__\r
+#undef __MODULE__\r
+#endif\r
+\r
+#define __MODULE__     "[IPoIB]"\r
+\r
+#include <complib/cl_debug.h>\r
+\r
+\r
+/* Object types for passing into complib. */\r
+#define IPOIB_OBJ_INSTANCE             1\r
+#define IPOIB_OBJ_PORT                 2\r
+#define IPOIB_OBJ_ENDPOINT             3\r
+\r
+\r
+extern uint32_t                g_ipoib_dbg_level;\r
+extern uint32_t                g_ipoib_dbg_flags;\r
+\r
+\r
+#if defined(EVENT_TRACING)\r
+//\r
+// Software Tracing Definitions\r
+//\r
+#define WPP_CONTROL_GUIDS \\r
+       WPP_DEFINE_CONTROL_GUID( \\r
+               IPOIBCtlGuid,(3F9BC73D, EB03, 453a, B27B, 20F9A664211A), \\r
+       WPP_DEFINE_BIT(IPOIB_DBG_ERROR) \\r
+       WPP_DEFINE_BIT(IPOIB_DBG_INIT) \\r
+       WPP_DEFINE_BIT(IPOIB_DBG_PNP) \\r
+       WPP_DEFINE_BIT(IPOIB_DBG_SEND) \\r
+       WPP_DEFINE_BIT(IPOIB_DBG_RECV) \\r
+       WPP_DEFINE_BIT(IPOIB_DBG_ENDPT) \\r
+       WPP_DEFINE_BIT(IPOIB_DBG_IB) \\r
+       WPP_DEFINE_BIT(IPOIB_DBG_BUF) \\r
+       WPP_DEFINE_BIT(IPOIB_DBG_MCAST) \\r
+       WPP_DEFINE_BIT(IPOIB_DBG_ALLOC) \\r
+       WPP_DEFINE_BIT(IPOIB_DBG_OID) \\r
+       WPP_DEFINE_BIT(IPOIB_DBG_IOCTL) \\r
+       WPP_DEFINE_BIT(IPOIB_DBG_STAT) \\r
+       WPP_DEFINE_BIT(IPOIB_DBG_OBJ))\r
+\r
+\r
+\r
+#define WPP_LEVEL_FLAGS_ENABLED(lvl, flags) \\r
+       (WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_ ## flags).Level  >= lvl)\r
+#define WPP_LEVEL_FLAGS_LOGGER(lvl,flags) WPP_LEVEL_LOGGER(flags)\r
+#define WPP_FLAG_ENABLED(flags) \\r
+       (WPP_LEVEL_ENABLED(flags) && \\r
+       WPP_CONTROL(WPP_BIT_ ## flags).Level  >= TRACE_LEVEL_VERBOSE)\r
+#define WPP_FLAG_LOGGER(flags) WPP_LEVEL_LOGGER(flags)\r
+\r
+// begin_wpp config\r
+// IPOIB_ENTER(FLAG);\r
+// IPOIB_EXIT(FLAG);\r
+// USEPREFIX(IPOIB_PRINT, "%!STDPREFIX! [IPoIB] :%!FUNC!() :");\r
+// USEPREFIX(IPOIB_PRINT_EXIT, "%!STDPREFIX! [IPoIB] :%!FUNC!() :");\r
+// USESUFFIX(IPOIB_PRINT_EXIT, "[IpoIB] :%!FUNC!():]");\r
+// USESUFFIX(IPOIB_ENTER, " [IPoIB] :%!FUNC!():[");\r
+// USESUFFIX(IPOIB_EXIT, " [IPoIB] :%!FUNC!():]");\r
+// end_wpp\r
+\r
+#else\r
+\r
+#include <evntrace.h>\r
+\r
+\r
+/*\r
+ * Debug macros\r
+ */\r
+#define IPOIB_DBG_ERR  (1 << 0)\r
+#define IPOIB_DBG_INIT (1 << 1)\r
+#define IPOIB_DBG_PNP  (1 << 2)\r
+#define IPOIB_DBG_SEND (1 << 3)\r
+#define IPOIB_DBG_RECV (1 << 4)\r
+#define IPOIB_DBG_ENDPT        (1 << 5)\r
+#define IPOIB_DBG_IB   (1 << 6)\r
+#define IPOIB_DBG_BUF  (1 << 7)\r
+#define IPOIB_DBG_MCAST        (1 << 8)\r
+#define IPOIB_DBG_ALLOC        (1 << 9)\r
+#define IPOIB_DBG_OID  (1 << 10)\r
+#define IPOIB_DBG_IOCTL        (1 << 11)\r
+#define IPOIB_DBG_STAT (1 << 12)\r
+#define IPOIB_DBG_OBJ  (1 << 13)\r
+\r
+#define IPOIB_DBG_ERROR        (CL_DBG_ERROR | IPOIB_DBG_ERR)\r
+#define IPOIB_DBG_ALL  CL_DBG_ALL\r
+\r
+\r
+#if DBG\r
+\r
+// assignment of _level_ is need to to overcome warning C4127\r
+#define IPOIB_PRINT(_level_,_flag_,_msg_) \\r
+       { \\r
+               __pragma(warning(suppress:6326)) \\r
+               if( g_ipoib_dbg_level >= (_level_) ) \\r
+                       CL_TRACE( _flag_, g_ipoib_dbg_flags, _msg_ ); \\r
+       }\r
+\r
+#define IPOIB_PRINT_EXIT(_level_,_flag_,_msg_) \\r
+       { \\r
+               __pragma(warning(suppress:6326)) \\r
+               if( g_ipoib_dbg_level >= (_level_) ) \\r
+                       CL_TRACE( _flag_, g_ipoib_dbg_flags, _msg_ );\\r
+               IPOIB_EXIT(_flag_);\\r
+       }\r
+\r
+#define IPOIB_ENTER(_flag_) \\r
+       { \\r
+               __pragma(warning(suppress:6326)) \\r
+               if( g_ipoib_dbg_level >= TRACE_LEVEL_VERBOSE ) \\r
+                       CL_ENTER( _flag_, g_ipoib_dbg_flags ); \\r
+       }\r
+\r
+#define IPOIB_EXIT(_flag_)\\r
+       { \\r
+               __pragma(warning(suppress:6326)) \\r
+               if( g_ipoib_dbg_level >= TRACE_LEVEL_VERBOSE ) \\r
+                       CL_EXIT( _flag_, g_ipoib_dbg_flags ); \\r
+       }\r
+\r
+#define IPOIB_TRACE_BYTES( lvl, ptr, len )                                                                     \\r
+       {                                                                                                                                               \\r
+               __pragma(warning(suppress:6326))                                                                        \\r
+               if( g_ipoib_dbg_level >= (_level_) &&                                                           \\r
+                       (g_ipoib_dbg_flags & (_flag_)) )                                                                \\r
+               {                                                                                                                                       \\r
+                       size_t _loop_;                                                                                                  \\r
+                       for( _loop_ = 0; _loop_ < (len); ++_loop_ )                                             \\r
+                       {                                                                                                                               \\r
+                               cl_dbg_out( "0x%.2X ", ((uint8_t*)(ptr))[_loop_] );                     \\r
+                               if( (_loop_ + 1)% 16 == 0 )                                                                     \\r
+                                       cl_dbg_out("\n");                                                                                       \\r
+                               else if( (_loop_ % 4 + 1) == 0 )                                                        \\r
+                                       cl_dbg_out("  ");                                                                                       \\r
+                       }                                                                                                                               \\r
+                       cl_dbg_out("\n");                                                                                                       \\r
+               }                                                                                                                                       \\r
+       }\r
+\r
+#else\r
+\r
+#define IPOIB_PRINT(lvl, flags, msg)\r
+\r
+#define IPOIB_PRINT_EXIT(_level_,_flag_,_msg_)\r
+\r
+#define IPOIB_ENTER(_flag_)\r
+\r
+#define IPOIB_EXIT(_flag_)\r
+\r
+#define IPOIB_TRACE_BYTES( lvl, ptr, len )\r
+\r
+#endif\r
+\r
+#endif //EVENT_TRACING\r
+\r
+\r
+enum ipoib_perf_counters\r
+{\r
+       SendBundle,\r
+       SendPackets,\r
+               PortSend,\r
+                       GetEthHdr,\r
+                       SendMgrQueue,\r
+                               GetEndpt,\r
+                                       EndptQueue,\r
+                       QueuePacket,\r
+                       BuildSendDesc,\r
+                               SendMgrFilter,\r
+                                       FilterIp,\r
+                                               QueryIp,\r
+                                               SendTcp,\r
+                                               FilterUdp,\r
+                                                       QueryUdp,\r
+                                                       SendUdp,\r
+                                                       FilterDhcp,\r
+                                       FilterArp,\r
+                                       SendGen,\r
+                                               SendCopy,\r
+                       PostSend,\r
+                       ProcessFailedSends,\r
+       SendCompBundle,\r
+       SendCb,\r
+               PollSend,\r
+               SendComp,\r
+               FreeSendBuf,\r
+               RearmSend,\r
+               PortResume,\r
+       RecvCompBundle,\r
+       RecvCb,\r
+               PollRecv,\r
+               FilterRecv,\r
+                       GetRecvEndpts,\r
+                               GetEndptByGid,\r
+                               GetEndptByLid,\r
+                               EndptInsert,\r
+                       RecvTcp,\r
+                       RecvUdp,\r
+                       RecvDhcp,\r
+                       RecvArp,\r
+                       RecvGen,\r
+       BuildPktArray,\r
+               PreparePkt,\r
+                       GetNdisPkt,\r
+       RecvNdisIndicate,\r
+       PutRecvList,\r
+       RepostRecv,\r
+               GetRecv,\r
+               PostRecv,\r
+       RearmRecv,\r
+               ReturnPacket,\r
+               ReturnPutRecv,\r
+               ReturnRepostRecv,\r
+               ReturnPreparePkt,\r
+               ReturnNdisIndicate,\r
+\r
+       /* Must be last! */\r
+       MaxPerf\r
+\r
+};\r
+\r
+\r
+enum ref_cnt_buckets\r
+{\r
+       ref_init = 0,\r
+       ref_refresh_mcast,      /* only used in refresh_mcast */\r
+       ref_send_packets,       /* only in send_packets */\r
+       ref_get_recv,\r
+       ref_repost,             /* only in __recv_mgr_repost */\r
+       ref_recv_cb,    /* only in __recv_cb */\r
+       ref_send_cb,    /* only in __send_cb */\r
+       ref_port_up,\r
+       ref_get_bcast,\r
+       ref_bcast,              /* join and create, used as base only */\r
+       ref_join_mcast,\r
+       ref_leave_mcast,\r
+       ref_endpt_track,        /* used when endpt is in port's child list. */\r
+\r
+       ref_array_size, /* Used to size the array of ref buckets. */\r
+       ref_mask = 100, /* Used to differentiate derefs. */\r
+\r
+       ref_failed_recv_wc = 100 + ref_get_recv,\r
+       ref_recv_inv_len = 200 + ref_get_recv,\r
+       ref_recv_loopback = 300 + ref_get_recv,\r
+       ref_recv_filter = 400 + ref_get_recv,\r
+\r
+       ref_bcast_get_cb = 100 + ref_get_bcast,\r
+\r
+       ref_join_bcast = 100 + ref_bcast,\r
+       ref_create_bcast = 200 + ref_bcast,\r
+       ref_bcast_inv_state = 300 + ref_bcast,\r
+       ref_bcast_req_failed = 400 + ref_bcast,\r
+       ref_bcast_error = 500 + ref_bcast,\r
+       ref_bcast_join_failed = 600 + ref_bcast,\r
+       ref_bcast_create_failed = 700 + ref_bcast,\r
+\r
+       ref_mcast_inv_state = 100 + ref_join_mcast,\r
+       ref_mcast_req_failed = 200 + ref_join_mcast,\r
+       ref_mcast_no_endpt = 300 + ref_join_mcast,\r
+       ref_mcast_av_failed = 400 + ref_join_mcast,\r
+       ref_mcast_join_failed = 500 + ref_join_mcast,\r
+\r
+       ref_port_info_cb = 100 + ref_port_up\r
+\r
+};\r
+\r
+\r
+#endif /* _IPOIB_DEBUG_H_ */\r
diff --git a/ulp/ipoib/kernel6/ipoib_driver.c b/ulp/ipoib/kernel6/ipoib_driver.c
new file mode 100644 (file)
index 0000000..95d67cd
--- /dev/null
@@ -0,0 +1,4057 @@
+/*\r
+ * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.\r
+ * Copyright (c) 2006 Mellanox Technologies.  All rights reserved.\r
+ * Portions Copyright (c) 2008 Microsoft Corporation.  All rights reserved.\r
+ *\r
+ * This software is available to you under the OpenIB.org BSD license\r
+ * below:\r
+ *\r
+ *     Redistribution and use in source and binary forms, with or\r
+ *     without modification, are permitted provided that the following\r
+ *     conditions are met:\r
+ *\r
+ *      - Redistributions of source code must retain the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer.\r
+ *\r
+ *      - Redistributions in binary form must reproduce the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer in the documentation and/or other materials\r
+ *        provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ * $Id: ipoib_driver.c 4226 2009-04-06 06:01:03Z xalex $\r
+ */\r
+\r
+#include "limits.h"\r
+#include "ipoib_driver.h"\r
+#include "ipoib_debug.h"\r
+\r
+#if defined(EVENT_TRACING)\r
+#ifdef offsetof\r
+#undef offsetof\r
+#endif\r
+#include "ipoib_driver.tmh"\r
+#endif\r
+\r
+#include "ipoib_port.h"\r
+#include "ipoib_ibat.h"\r
+#include <complib/cl_bus_ifc.h>\r
+#include <complib/cl_init.h>\r
+#include <initguid.h>\r
+#include <iba/ipoib_ifc.h>\r
+#include "ntstrsafe.h"\r
+#include "strsafe.h"\r
+#include <offload.h>\r
+\r
+\r
+\r
+#define MAJOR_DRIVER_VERSION 2\r
+#define MINOR_DRIVER_VERSION 1\r
+#if defined(NDIS60_MINIPORT)\r
+#define MAJOR_NDIS_VERSION 6\r
+#define MINOR_NDIS_VERSION 0\r
+\r
+#else\r
+#error NDIS Version not defined, try defining NDIS60_MINIPORT\r
+#endif\r
+\r
+PDRIVER_OBJECT                         g_p_drv_obj;\r
+\r
+\r
+\r
+static const NDIS_OID SUPPORTED_OIDS[] =\r
+{\r
+       OID_GEN_SUPPORTED_LIST,\r
+       OID_GEN_HARDWARE_STATUS,\r
+       OID_GEN_MEDIA_SUPPORTED,\r
+       OID_GEN_MEDIA_IN_USE,\r
+       OID_GEN_MAXIMUM_LOOKAHEAD,\r
+       OID_GEN_MAXIMUM_FRAME_SIZE,\r
+       OID_GEN_LINK_SPEED,\r
+       OID_GEN_TRANSMIT_BUFFER_SPACE,\r
+       OID_GEN_RECEIVE_BUFFER_SPACE,\r
+       OID_GEN_TRANSMIT_BLOCK_SIZE,\r
+       OID_GEN_RECEIVE_BLOCK_SIZE,\r
+       OID_GEN_VENDOR_ID,\r
+       OID_GEN_VENDOR_DESCRIPTION,\r
+       OID_GEN_CURRENT_PACKET_FILTER,\r
+       OID_GEN_CURRENT_LOOKAHEAD,\r
+       OID_GEN_DRIVER_VERSION,\r
+       OID_GEN_MAXIMUM_TOTAL_SIZE,\r
+       OID_GEN_PROTOCOL_OPTIONS,\r
+       OID_GEN_MAC_OPTIONS,\r
+       OID_GEN_MEDIA_CONNECT_STATUS,\r
+       OID_GEN_MAXIMUM_SEND_PACKETS,\r
+       OID_GEN_NETWORK_LAYER_ADDRESSES,\r
+       OID_GEN_VENDOR_DRIVER_VERSION,\r
+       OID_GEN_PHYSICAL_MEDIUM,\r
+       OID_GEN_XMIT_OK,\r
+       OID_GEN_RCV_OK,\r
+       OID_GEN_XMIT_ERROR,\r
+       OID_GEN_RCV_ERROR,\r
+       OID_GEN_RCV_NO_BUFFER,\r
+       OID_GEN_DIRECTED_BYTES_XMIT,\r
+       OID_GEN_DIRECTED_FRAMES_XMIT,\r
+       OID_GEN_MULTICAST_BYTES_XMIT,\r
+       OID_GEN_MULTICAST_FRAMES_XMIT,\r
+       OID_GEN_BROADCAST_BYTES_XMIT,\r
+       OID_GEN_BROADCAST_FRAMES_XMIT,\r
+       OID_GEN_DIRECTED_BYTES_RCV,\r
+       OID_GEN_DIRECTED_FRAMES_RCV,\r
+       OID_GEN_MULTICAST_BYTES_RCV,\r
+       OID_GEN_MULTICAST_FRAMES_RCV,\r
+       OID_GEN_BROADCAST_BYTES_RCV,\r
+       OID_GEN_BROADCAST_FRAMES_RCV,\r
+       OID_802_3_PERMANENT_ADDRESS,\r
+       OID_802_3_CURRENT_ADDRESS,\r
+       OID_802_3_MULTICAST_LIST,\r
+       OID_802_3_MAXIMUM_LIST_SIZE,\r
+       OID_802_3_MAC_OPTIONS,\r
+       OID_802_3_RCV_ERROR_ALIGNMENT,\r
+       OID_802_3_XMIT_ONE_COLLISION,\r
+       OID_802_3_XMIT_MORE_COLLISIONS,\r
+       OID_TCP_TASK_OFFLOAD\r
+};\r
+\r
+static const unsigned char VENDOR_ID[] = {0x00, 0x06, 0x6A, 0x00};\r
+\r
+#define VENDOR_DESCRIPTION "Internet Protocol over InfiniBand"\r
+\r
+#define IB_INFINITE_SERVICE_LEASE      0xFFFFFFFF\r
+\r
+//The mask is 8 bit and can't contain more than 6 non-zero bits\r
+#define MAX_GUID_MAX 0xFC\r
+\r
+\r
+/* Global driver debug level */\r
+uint32_t               g_ipoib_dbg_level = TRACE_LEVEL_ERROR;\r
+uint32_t               g_ipoib_dbg_flags = 0x00000fff;\r
+ipoib_globals_t        g_ipoib = {0};\r
+NDIS_HANDLE            g_IpoibMiniportDriverHandle = NULL;\r
+NDIS_HANDLE            g_IpoibDriverContext = NULL;\r
+\r
+\r
+\r
+typedef struct _IPOIB_REG_ENTRY\r
+{\r
+       NDIS_STRING RegName;                // variable name text\r
+       BOOLEAN     bRequired;              // 1 -> required, 0 -> optional\r
+       UINT        FieldOffset;            // offset in parent struct\r
+       UINT        FieldSize;              // size (in bytes) of the field\r
+       UINT        Default;                // default value to use\r
+       UINT        Min;                    // minimum value allowed\r
+       UINT        Max;                    // maximum value allowed\r
+} IPOIB_REG_ENTRY, *PIPOIB_REG_ENTRY;\r
+\r
+IPOIB_REG_ENTRY HCARegTable[] = {\r
+       // reg value name             If Required  Offset in parentr struct             Field size                  Default         Min     Max\r
+       {NDIS_STRING_CONST("GUIDMask"),         0, IPOIB_OFFSET(guid_mask),             IPOIB_SIZE(guid_mask),          0,          0,    MAX_GUID_MAX},\r
+       /* GUIDMask should be the first element */\r
+       {NDIS_STRING_CONST("RqDepth"),          1, IPOIB_OFFSET(rq_depth),              IPOIB_SIZE(rq_depth),           512,        128,    1024},\r
+       {NDIS_STRING_CONST("RqLowWatermark"),   0, IPOIB_OFFSET(rq_low_watermark),      IPOIB_SIZE(rq_low_watermark),   4,          2,      8},\r
+       {NDIS_STRING_CONST("SqDepth"),          1, IPOIB_OFFSET(sq_depth),              IPOIB_SIZE(sq_depth),           512,        128,    1024},\r
+       {NDIS_STRING_CONST("SendChksum"),       1, IPOIB_OFFSET(send_chksum_offload),   IPOIB_SIZE(send_chksum_offload),CSUM_ENABLED,CSUM_DISABLED,CSUM_BYPASS},\r
+       {NDIS_STRING_CONST("RecvChksum"),       1, IPOIB_OFFSET(recv_chksum_offload),   IPOIB_SIZE(recv_chksum_offload),CSUM_ENABLED,CSUM_DISABLED,CSUM_BYPASS},\r
+       {NDIS_STRING_CONST("SaTimeout"),        1, IPOIB_OFFSET(sa_timeout),            IPOIB_SIZE(sa_timeout),         1000,       250,    UINT_MAX},\r
+       {NDIS_STRING_CONST("SaRetries"),        1, IPOIB_OFFSET(sa_retry_cnt),          IPOIB_SIZE(sa_retry_cnt),       10,         1,      UINT_MAX},\r
+       {NDIS_STRING_CONST("RecvRatio"),        1, IPOIB_OFFSET(recv_pool_ratio),       IPOIB_SIZE(recv_pool_ratio),    1,          1,      10},\r
+       {NDIS_STRING_CONST("PayloadMtu"),       1, IPOIB_OFFSET(payload_mtu),           IPOIB_SIZE(payload_mtu),        2044,       512,   MAX_UD_PAYLOAD_MTU},\r
+       {NDIS_STRING_CONST("lso"),              0, IPOIB_OFFSET(lso),                   IPOIB_SIZE(lso),                0,          0,      1},\r
+       {NDIS_STRING_CONST("MCLeaveRescan"),    1, IPOIB_OFFSET(mc_leave_rescan),       IPOIB_SIZE(mc_leave_rescan),    260,        1,    3600},\r
+       {NDIS_STRING_CONST("BCJoinRetry"),          1, IPOIB_OFFSET(bc_join_retry),                 IPOIB_SIZE(bc_join_retry),      50,         0,    1000},\r
+       {NDIS_STRING_CONST("CmEnabled"),        0, IPOIB_OFFSET(cm_enabled),            IPOIB_SIZE(cm_enabled),         FALSE,     FALSE, TRUE},\r
+       {NDIS_STRING_CONST("CmPayloadMtu"),     1, IPOIB_OFFSET(cm_payload_mtu),        IPOIB_SIZE(cm_payload_mtu),     MAX_CM_PAYLOAD_MTU, 512, MAX_CM_PAYLOAD_MTU}\r
+\r
+};  \r
+\r
+#define IPOIB_NUM_REG_PARAMS (sizeof (HCARegTable) / sizeof(IPOIB_REG_ENTRY))\r
+\r
+\r
+void\r
+ipoib_create_log(\r
+       NDIS_HANDLE h_adapter,\r
+       UINT ind,\r
+       ULONG eventLogMsgId)\r
+\r
+{\r
+#define cMaxStrLen  40\r
+#define cArrLen  3\r
+\r
+       PWCHAR logMsgArray[cArrLen]; \r
+       WCHAR strVal[cMaxStrLen];\r
+       NDIS_STRING AdapterInstanceName;\r
+\r
+       IPOIB_INIT_NDIS_STRING(&AdapterInstanceName);\r
+       if (NdisMQueryAdapterInstanceName(&AdapterInstanceName, h_adapter)!= NDIS_STATUS_SUCCESS ){\r
+               ASSERT(FALSE);\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR,IPOIB_DBG_ERROR, ("[IPoIB] Init:Failed to retreive adapter name.\n"));\r
+               return;\r
+       }\r
+       logMsgArray[0] = AdapterInstanceName.Buffer;\r
+       \r
+       if (RtlStringCbPrintfW(strVal, sizeof(strVal), L"0x%x", HCARegTable[ind].Default) != STATUS_SUCCESS) {\r
+               ASSERT(FALSE);\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR,IPOIB_DBG_ERROR,\r
+               ("[IPoIB] Init: Problem copying string value: exiting\n"));   \r
+               return;\r
+       }\r
+       \r
+       logMsgArray[0] = AdapterInstanceName.Buffer;\r
+       logMsgArray[1] = HCARegTable[ind].RegName.Buffer;\r
+       logMsgArray[2] = strVal;\r
+       \r
+       NdisWriteEventLogEntry(g_p_drv_obj, eventLogMsgId, 0, cArrLen, &logMsgArray, 0, NULL);\r
+\r
+}\r
+\r
+\r
+\r
+NTSTATUS\r
+DriverEntry(\r
+       IN                              PDRIVER_OBJECT                          p_drv_obj,\r
+       IN                              PUNICODE_STRING                         p_reg_path );\r
+\r
+VOID\r
+ipoib_unload(\r
+       IN                              PDRIVER_OBJECT                          p_drv_obj );\r
+\r
+NDIS_STATUS\r
+ipoib_initialize_ex(\r
+       IN                              NDIS_HANDLE                     h_adapter,\r
+    IN                                 NDIS_HANDLE             config_context,\r
+    IN PNDIS_MINIPORT_INIT_PARAMETERS  MiniportInitParameters);\r
+\r
+BOOLEAN\r
+ipoib_check_for_hang(\r
+       IN                              NDIS_HANDLE                                     adapter_context );\r
+\r
+void\r
+ipoib_halt_ex(\r
+       IN NDIS_HANDLE  adapter_context,\r
+       IN                      NDIS_HALT_ACTION            HaltAction);\r
+\r
+NDIS_STATUS\r
+ipoib_query_info(\r
+       IN                              NDIS_HANDLE                                     adapter_context,\r
+       IN                              NDIS_OID                                        oid,\r
+       IN                              PVOID                                           info_buf,\r
+       IN                              ULONG                                           info_buf_len,\r
+               OUT                     PULONG                                          p_bytes_written,\r
+               OUT                     PULONG                                          p_bytes_needed );\r
+\r
+\r
+\r
+NDIS_STATUS\r
+ipoib_reset(\r
+    IN  NDIS_HANDLE     adapter_context,\r
+    OUT PBOOLEAN        p_addr_reset);\r
+\r
+NDIS_STATUS\r
+ipoib_set_info(\r
+       IN                              NDIS_HANDLE                                     adapter_context,\r
+       IN                              NDIS_OID                                        oid,\r
+       IN                              PVOID                                           info_buf,\r
+       IN                              ULONG                                           info_buf_length,\r
+               OUT                     PULONG                                          p_bytes_read,\r
+               OUT                     PULONG                                          p_bytes_needed );\r
+\r
+//NDIS60\r
+void\r
+ipoib_send_net_buffer_list(\r
+    IN  NDIS_HANDLE         adapter_context,\r
+    IN  PNET_BUFFER_LIST    net_buffer_list,\r
+    IN  NDIS_PORT_NUMBER    port_num,\r
+    IN  ULONG               send_flags);\r
+\r
+void\r
+ipoib_pnp_notify(\r
+       IN                              NDIS_HANDLE                                     adapter_context,\r
+       IN PNET_DEVICE_PNP_EVENT  pnp_event);\r
+\r
+VOID\r
+ipoib_shutdown_ex(\r
+       IN NDIS_HANDLE  adapter_context,\r
+       IN NDIS_SHUTDOWN_ACTION  shutdown_action);\r
+\r
+\r
+void\r
+ipoib_cancel_xmit(\r
+       IN                              NDIS_HANDLE                                     adapter_context,\r
+       IN                              PVOID                                           cancel_id );\r
+\r
+\r
+static void\r
+ipoib_complete_query(\r
+       IN                              ipoib_adapter_t* const          p_adapter,\r
+       IN                              pending_oid_t* const            p_oid_info,\r
+       IN              const   NDIS_STATUS                                     status,\r
+       IN              const   void* const                                     p_buf,\r
+       IN              const   ULONG                                           buf_len );\r
+\r
+static NDIS_STATUS\r
+__ipoib_set_net_addr(\r
+       IN              ipoib_adapter_t *       p_adapter,\r
+       IN              PVOID                           info_buf,\r
+       IN              ULONG                           info_buf_len,\r
+               OUT     PULONG                          p_bytes_read,\r
+               OUT     PULONG                          p_bytes_needed );\r
+\r
+static NDIS_STATUS\r
+__ipoib_get_tcp_task_offload(\r
+       IN                              ipoib_adapter_t*                        p_adapter,\r
+       OUT                             pending_oid_t                           *pNdisRequest);\r
+\r
+static void\r
+__ipoib_ats_reg_cb(\r
+       IN                              ib_reg_svc_rec_t                        *p_reg_svc_rec );\r
+\r
+static void\r
+__ipoib_ats_dereg_cb(\r
+       IN                              void                                            *context );\r
+\r
+static NTSTATUS\r
+__ipoib_read_registry(\r
+       IN                              UNICODE_STRING* const           p_registry_path );\r
+\r
+static NDIS_STATUS\r
+ipoib_set_options(\r
+    IN NDIS_HANDLE  NdisMiniportDriverHandle,\r
+    IN NDIS_HANDLE  MiniportDriverContext);\r
+\r
+static NDIS_STATUS\r
+ipoib_oid_handler(\r
+    IN  NDIS_HANDLE         adapter_context,\r
+    IN  PNDIS_OID_REQUEST   pNdisRequest);\r
+\r
+static void\r
+ipoib_cancel_oid_request(\r
+    IN  NDIS_HANDLE            adapter_context,\r
+    IN  PVOID                  requestId);\r
+        \r
+static NDIS_STATUS \r
+ipoib_pause(\r
+    IN  NDIS_HANDLE                         adapter_context,    \r
+    IN  PNDIS_MINIPORT_PAUSE_PARAMETERS     pause_parameters);\r
+\r
+static NDIS_STATUS \r
+ipoib_restart(\r
+    IN  NDIS_HANDLE                         adapter_context,    \r
+    IN  PNDIS_MINIPORT_RESTART_PARAMETERS   restart_parameters);\r
+\r
+\r
+\r
+//! Standard Windows Device Driver Entry Point\r
+/*! DriverEntry is the first routine called after a driver is loaded, and\r
+is responsible for initializing the driver.  On W2k this occurs when the PnP\r
+Manager matched a PnP ID to one in an INF file that references this driver.\r
+Any not success return value will cause the driver to fail to load.\r
+IRQL = PASSIVE_LEVEL\r
+\r
+@param p_drv_obj Pointer to Driver Object for this device driver\r
+@param p_registry_path Pointer to unicode string containing path to this driver's registry area\r
+@return STATUS_SUCCESS, NDIS_STATUS_BAD_CHARACTERISTICS, NDIS_STATUS_BAD_VERSION,\r
+NDIS_STATUS_RESOURCES, or NDIS_STATUS_FAILURE\r
+*/\r
+NTSTATUS\r
+DriverEntry(\r
+       IN                              PDRIVER_OBJECT                          p_drv_obj,\r
+       IN                              PUNICODE_STRING                         p_registry_path )\r
+{\r
+       NDIS_STATUS                                             status;\r
+       NDIS_MINIPORT_DRIVER_CHARACTERISTICS characteristics;\r
+\r
+       IPOIB_ENTER( IPOIB_DBG_INIT );\r
+       g_p_drv_obj = p_drv_obj;\r
+\r
+#ifdef _DEBUG_\r
+       PAGED_CODE();\r
+#endif\r
+#if defined(EVENT_TRACING)\r
+       WPP_INIT_TRACING(p_drv_obj, p_registry_path);\r
+#endif\r
+       status = CL_INIT;\r
+       if( !NT_SUCCESS( status ) )\r
+       {\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                       ("cl_init failed.\n") );\r
+               return status;\r
+       }\r
+\r
+       __ipoib_read_registry(p_registry_path);\r
+       \r
+       KeInitializeSpinLock( &g_ipoib.lock );\r
+       cl_qlist_init( &g_ipoib.adapter_list );\r
+\r
+    NdisZeroMemory(&characteristics, sizeof(characteristics));\r
+\r
+    characteristics.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_DRIVER_CHARACTERISTICS,\r
+    characteristics.Header.Size = sizeof(NDIS_MINIPORT_DRIVER_CHARACTERISTICS);\r
+    characteristics.Header.Revision = NDIS_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_1;\r
+\r
+       characteristics.MajorNdisVersion                = MAJOR_NDIS_VERSION;\r
+       characteristics.MinorNdisVersion                = MINOR_NDIS_VERSION;\r
+    characteristics.MajorDriverVersion         = MAJOR_DRIVER_VERSION;\r
+    characteristics.MinorDriverVersion         = MINOR_DRIVER_VERSION;\r
+\r
+\r
+       characteristics.CheckForHangHandlerEx           = ipoib_check_for_hang;\r
+       characteristics.HaltHandlerEx                           = ipoib_halt_ex;\r
+       characteristics.InitializeHandlerEx             = ipoib_initialize_ex;\r
+       characteristics.OidRequestHandler                       = ipoib_oid_handler;\r
+       characteristics.CancelOidRequestHandler         = ipoib_cancel_oid_request;\r
+       characteristics.ResetHandlerEx                          = ipoib_reset;\r
+       characteristics.DevicePnPEventNotifyHandler     = ipoib_pnp_notify;\r
+       characteristics.ReturnNetBufferListsHandler     = ipoib_return_net_buffer_list;\r
+       characteristics.SendNetBufferListsHandler       = ipoib_send_net_buffer_list;\r
+\r
+       characteristics.SetOptionsHandler                       = ipoib_set_options;\r
+       characteristics.PauseHandler                            = ipoib_pause;\r
+       characteristics.RestartHandler                          = ipoib_restart;\r
+       characteristics.UnloadHandler                           = ipoib_unload;\r
+       characteristics.CancelSendHandler                       = ipoib_cancel_xmit;\r
+       characteristics.ShutdownHandlerEx                       = ipoib_shutdown_ex;\r
+\r
+\r
+\r
+//TODO NDIS60 set g_ prefix to global variables\r
+       status = NdisMRegisterMiniportDriver(\r
+               p_drv_obj, p_registry_path,(PNDIS_HANDLE)g_IpoibDriverContext, &characteristics,&g_IpoibMiniportDriverHandle );\r
+       if( status != NDIS_STATUS_SUCCESS )\r
+       {\r
+               IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR, \r
+                       ("NdisMRegisterMiniportDriver failed with status of %d\n", status) );\r
+               CL_DEINIT;\r
+       }\r
+\r
+       IPOIB_EXIT( IPOIB_DBG_INIT );\r
+       return status;\r
+}\r
+\r
+static NDIS_STATUS\r
+ipoib_set_options(\r
+    IN NDIS_HANDLE  NdisMiniportDriverHandle,\r
+    IN NDIS_HANDLE  MiniportDriverContext\r
+    )\r
+{\r
+       IPOIB_ENTER( IPOIB_DBG_INIT );\r
+\r
+    UNREFERENCED_PARAMETER(NdisMiniportDriverHandle);\r
+    UNREFERENCED_PARAMETER(MiniportDriverContext);\r
+   \r
+       IPOIB_EXIT( IPOIB_DBG_INIT );\r
+    return NDIS_STATUS_SUCCESS;\r
+}\r
+\r
+static NTSTATUS\r
+__ipoib_read_registry(\r
+       IN                              UNICODE_STRING* const           p_registry_path )\r
+{\r
+       NTSTATUS                                                status;\r
+       /* Remember the terminating entry in the table below. */\r
+       RTL_QUERY_REGISTRY_TABLE                table[4];\r
+       UNICODE_STRING                                  param_path;\r
+\r
+       IPOIB_ENTER( IPOIB_DBG_INIT );\r
+       RtlInitUnicodeString( &param_path, NULL );\r
+       param_path.MaximumLength = p_registry_path->Length + \r
+               sizeof(L"\\Parameters");\r
+       param_path.Buffer = cl_zalloc( param_path.MaximumLength );\r
+       if( !param_path.Buffer )\r
+       {\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR, \r
+                       ("Failed to allocate parameters path buffer.\n") );\r
+               return STATUS_INSUFFICIENT_RESOURCES;\r
+       }\r
+\r
+       RtlAppendUnicodeStringToString( &param_path, p_registry_path );\r
+       RtlAppendUnicodeToString( &param_path, L"\\Parameters" );\r
+\r
+       /*\r
+        * Clear the table.  This clears all the query callback pointers,\r
+        * and sets up the terminating table entry.\r
+        */\r
+       cl_memclr( table, sizeof(table) );\r
+\r
+       /* Setup the table entries. */\r
+       table[0].Flags = RTL_QUERY_REGISTRY_DIRECT;\r
+       table[0].Name = L"DebugLevel";\r
+       table[0].EntryContext = &g_ipoib_dbg_level;\r
+       table[0].DefaultType = REG_DWORD;\r
+       table[0].DefaultData = &g_ipoib_dbg_level;\r
+       table[0].DefaultLength = sizeof(ULONG);\r
+\r
+       table[1].Flags = RTL_QUERY_REGISTRY_DIRECT;\r
+       table[1].Name = L"DebugFlags";\r
+       table[1].EntryContext = &g_ipoib_dbg_flags;\r
+       table[1].DefaultType = REG_DWORD;\r
+       table[1].DefaultData = &g_ipoib_dbg_flags;\r
+       table[1].DefaultLength = sizeof(ULONG);\r
+\r
+       table[2].Flags = RTL_QUERY_REGISTRY_DIRECT;\r
+       table[2].Name = L"bypass_check_bcast_rate";\r
+       table[2].EntryContext = &g_ipoib.bypass_check_bcast_rate;\r
+       table[2].DefaultType = REG_DWORD;\r
+       table[2].DefaultData = &g_ipoib.bypass_check_bcast_rate;\r
+       table[2].DefaultLength = sizeof(ULONG);\r
+\r
+       /* Have at it! */\r
+       status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE, \r
+               param_path.Buffer, table, NULL, NULL );\r
+\r
+       IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                       ("debug level %d debug flags 0x%.8x\n",\r
+                       g_ipoib_dbg_level,\r
+                       g_ipoib_dbg_flags));\r
+\r
+#if DBG\r
+       if( g_ipoib_dbg_flags & IPOIB_DBG_ERR )\r
+               g_ipoib_dbg_flags |= CL_DBG_ERROR;\r
+#endif\r
+\r
+       cl_free( param_path.Buffer );\r
+       IPOIB_EXIT( IPOIB_DBG_INIT );\r
+       return status;\r
+}\r
+\r
+\r
+VOID\r
+ipoib_unload(\r
+       IN                              PDRIVER_OBJECT                          p_drv_obj )\r
+{\r
+       IPOIB_ENTER( IPOIB_DBG_INIT );\r
+       UNREFERENCED_PARAMETER(p_drv_obj);\r
+       #if defined(EVENT_TRACING)\r
+       WPP_CLEANUP(p_drv_obj);\r
+       #endif\r
+       //NDIS6.0\r
+       NdisMDeregisterMiniportDriver(g_IpoibMiniportDriverHandle);\r
+       UNREFERENCED_PARAMETER( p_drv_obj );\r
+       CL_DEINIT;\r
+       IPOIB_EXIT( IPOIB_DBG_INIT );\r
+}\r
+\r
+\r
+\r
+NDIS_STATUS\r
+ipoib_get_adapter_params(\r
+       IN                              NDIS_HANDLE* const                      wrapper_config_context,\r
+       IN      OUT                     ipoib_adapter_t                         *p_adapter,\r
+       OUT                             PUCHAR                                          *p_mac,\r
+       OUT                             UINT                                            *p_len)\r
+{\r
+       NDIS_STATUS                                             status;\r
+       NDIS_HANDLE                                             h_config;\r
+    NDIS_CONFIGURATION_OBJECT          config_obj;\r
+       NDIS_CONFIGURATION_PARAMETER    *p_param;\r
+       UINT                                                    value;\r
+       PIPOIB_REG_ENTRY                                pRegEntry;\r
+       UINT                                                    i;\r
+       PUCHAR                                                  structPointer;\r
+       \r
+       int sq_depth_step = 128;\r
+\r
+       UNUSED_PARAM(wrapper_config_context);\r
+       IPOIB_ENTER( IPOIB_DBG_INIT );\r
+\r
+    config_obj.Header.Type = NDIS_OBJECT_TYPE_CONFIGURATION_OBJECT;\r
+    config_obj.Header.Revision = NDIS_CONFIGURATION_OBJECT_REVISION_1;\r
+    config_obj.Header.Size = sizeof(NDIS_CONFIGURATION_OBJECT);\r
+    config_obj.NdisHandle = p_adapter->h_adapter;\r
+    config_obj.Flags = 0;\r
+\r
+       status = NdisOpenConfigurationEx( &config_obj, &h_config);\r
+       if( status != NDIS_STATUS_SUCCESS )\r
+       {\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                       ("NdisOpenConfigurationEx returned 0x%.8x\n", status) );\r
+               return status;\r
+       }\r
+\r
+       // read all the registry values \r
+       for (i = 0, pRegEntry = HCARegTable; i < IPOIB_NUM_REG_PARAMS; ++i)\r
+       {\r
+               // initialize pointer to appropriate place inside 'params'\r
+               structPointer = (PUCHAR) &p_adapter->params + pRegEntry[i].FieldOffset;\r
+\r
+               // Get the configuration value for a specific parameter.  Under NT the\r
+               // parameters are all read in as DWORDs.\r
+               NdisReadConfiguration(\r
+                       &status,\r
+                       &p_param,\r
+                       h_config,\r
+                       &pRegEntry[i].RegName,\r
+                       NdisParameterInteger);\r
+\r
+               // If the parameter was present, then check its value for validity.\r
+               if (status == NDIS_STATUS_SUCCESS)\r
+               {\r
+                       // Check that param value is not too small or too large\r
+                       if (p_param->ParameterData.IntegerData < pRegEntry[i].Min ||\r
+                               p_param->ParameterData.IntegerData > pRegEntry[i].Max)\r
+                       {\r
+                               value = pRegEntry[i].Default;\r
+                               ipoib_create_log(p_adapter->h_adapter, i, EVENT_IPOIB_WRONG_PARAMETER_WRN);\r
+                               IPOIB_PRINT(TRACE_LEVEL_VERBOSE, IPOIB_DBG_INIT, ("Read configuration.Registry %S value is out of range, setting default value= 0x%x\n", pRegEntry[i].RegName.Buffer, value));                                \r
+\r
+                       }\r
+                       else\r
+                       {\r
+                               value = p_param->ParameterData.IntegerData;\r
+                               IPOIB_PRINT(TRACE_LEVEL_VERBOSE, IPOIB_DBG_INIT, ("Read configuration. Registry %S, Value= 0x%x\n", pRegEntry[i].RegName.Buffer, value));\r
+                       }\r
+               }\r
+\r
+               else\r
+               {\r
+                       value = pRegEntry[i].Default;\r
+                       status = NDIS_STATUS_SUCCESS;\r
+                       if (pRegEntry[i].bRequired)\r
+                       {\r
+                               ipoib_create_log(p_adapter->h_adapter, i, EVENT_IPOIB_WRONG_PARAMETER_ERR);\r
+                               IPOIB_PRINT(TRACE_LEVEL_ERROR, IPOIB_DBG_INIT, ("Read configuration.Registry %S value not found, setting default value= 0x%x\n", pRegEntry[i].RegName.Buffer, value));\r
+                       }\r
+                       else\r
+                       {\r
+                               ipoib_create_log(p_adapter->h_adapter, i, EVENT_IPOIB_WRONG_PARAMETER_INFO);\r
+                               IPOIB_PRINT(TRACE_LEVEL_VERBOSE, IPOIB_DBG_INIT, ("Read configuration. Registry %S value not found, Value= 0x%x\n", pRegEntry[i].RegName.Buffer, value));\r
+                       }\r
+\r
+               }\r
+               //\r
+               // Store the value in the adapter structure.\r
+               //\r
+               switch(pRegEntry[i].FieldSize)\r
+               {\r
+                       case 1:\r
+                               *((PUCHAR) structPointer) = (UCHAR) value;\r
+                               break;\r
+\r
+                       case 2:\r
+                               *((PUSHORT) structPointer) = (USHORT) value;\r
+                               break;\r
+\r
+                       case 4:\r
+                               *((PULONG) structPointer) = (ULONG) value;\r
+                               break;\r
+\r
+                       default:\r
+                               IPOIB_PRINT(TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR, ("Bogus field size %d\n", pRegEntry[i].FieldSize));\r
+                               break;\r
+               }\r
+       }\r
+\r
+       // Send queue depth needs to be a power of two\r
+       //static const INT sq_depth_step = 128;\r
+\r
+       if (p_adapter->params.sq_depth % sq_depth_step) {\r
+               static const c_sq_ind = 2;\r
+               p_adapter->params.sq_depth = sq_depth_step *(\r
+                       p_adapter->params.sq_depth / sq_depth_step + !!( (p_adapter->params.sq_depth % sq_depth_step) > (sq_depth_step/2) ));\r
+               ipoib_create_log(p_adapter->h_adapter, c_sq_ind, EVENT_IPOIB_WRONG_PARAMETER_WRN);\r
+               IPOIB_PRINT(TRACE_LEVEL_VERBOSE, IPOIB_DBG_INIT, ("SQ DEPTH value was rounded to the closest acceptable value of  0x%x\n", p_adapter->params.sq_depth ));\r
+\r
+       }\r
+\r
+\r
+       // Adjusting the low watermark parameter\r
+       p_adapter->params.rq_low_watermark =\r
+                       p_adapter->params.rq_depth / p_adapter->params.rq_low_watermark;\r
+       \r
+       /* disable CM if LSO is active */\r
+       if( p_adapter->params.cm_enabled )\r
+       {\r
+               p_adapter->params.cm_enabled = !p_adapter->params.lso;\r
+               if( !p_adapter->params.cm_enabled )\r
+               {\r
+                       NdisWriteErrorLogEntry( p_adapter->h_adapter,\r
+                               EVENT_IPOIB_CONNECTED_MODE_ERR, 1, 0xbadc0de0 );\r
+               }\r
+       }\r
+\r
+       if( p_adapter->params.cm_enabled )\r
+       {\r
+               p_adapter->params.cm_xfer_block_size = \r
+                       (sizeof(eth_hdr_t) + p_adapter->params.cm_payload_mtu);\r
+       }\r
+\r
+               p_adapter->params.xfer_block_size = \r
+                       (sizeof(eth_hdr_t) + p_adapter->params.payload_mtu);\r
+\r
+       NdisReadNetworkAddress( &status, p_mac, p_len, h_config );\r
+\r
+       NdisCloseConfiguration( h_config );\r
+\r
+       IPOIB_EXIT( IPOIB_DBG_INIT );\r
+       return NDIS_STATUS_SUCCESS;\r
+}\r
+\r
+\r
+NDIS_STATUS\r
+ipoib_get_adapter_guids(\r
+       IN                              NDIS_HANDLE* const                      h_adapter,\r
+       IN      OUT                     ipoib_adapter_t                         *p_adapter )\r
+{\r
+       NTSTATUS                        status;\r
+       ib_al_ifc_data_t        data;\r
+       IO_STACK_LOCATION       io_stack, *p_fwd_io_stack;\r
+       DEVICE_OBJECT           *p_pdo;\r
+       IRP                                     *p_irp;\r
+       KEVENT                          event;\r
+       IO_STATUS_BLOCK         io_status;\r
+\r
+       IPOIB_ENTER( IPOIB_DBG_INIT );\r
+\r
+       NdisMGetDeviceProperty( h_adapter, &p_pdo, NULL, NULL, NULL, NULL );\r
+\r
+       /* Query for our interface */\r
+       data.size = sizeof(ipoib_ifc_data_t);\r
+       data.version = IPOIB_INTERFACE_DATA_VERSION;\r
+       data.type = &GUID_IPOIB_INTERFACE_DATA;\r
+       data.p_data = &p_adapter->guids;\r
+\r
+       io_stack.MinorFunction = IRP_MN_QUERY_INTERFACE;\r
+       io_stack.Parameters.QueryInterface.Version = AL_INTERFACE_VERSION;\r
+       io_stack.Parameters.QueryInterface.Size = sizeof(ib_al_ifc_t);\r
+       io_stack.Parameters.QueryInterface.Interface =\r
+               (INTERFACE*)p_adapter->p_ifc;\r
+       io_stack.Parameters.QueryInterface.InterfaceSpecificData = &data;\r
+       io_stack.Parameters.QueryInterface.InterfaceType = \r
+               &GUID_IB_AL_INTERFACE;\r
+\r
+       KeInitializeEvent( &event, NotificationEvent, FALSE );\r
+\r
+       /* Build the IRP for the HCA. */\r
+       p_irp = IoBuildSynchronousFsdRequest( IRP_MJ_PNP, p_pdo,\r
+               NULL, 0, NULL, &event, &io_status );\r
+       if( !p_irp )\r
+       {\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                       ("Failed to allocate query interface IRP.\n") );\r
+               return STATUS_INSUFFICIENT_RESOURCES;\r
+       }\r
+\r
+       /* Copy the request query parameters. */\r
+       p_fwd_io_stack = IoGetNextIrpStackLocation( p_irp );\r
+       p_fwd_io_stack->MinorFunction = IRP_MN_QUERY_INTERFACE;\r
+       p_fwd_io_stack->Parameters.QueryInterface =\r
+               io_stack.Parameters.QueryInterface;\r
+       p_irp->IoStatus.Status = STATUS_NOT_SUPPORTED;\r
+\r
+       /* Send the IRP. */\r
+       status = IoCallDriver( p_pdo, p_irp );\r
+       if( status == STATUS_PENDING )\r
+       {\r
+               KeWaitForSingleObject( &event, Executive, KernelMode,\r
+                       FALSE, NULL );\r
+               status = io_status.Status;\r
+       }\r
+\r
+       if( !NT_SUCCESS( status ) )\r
+       {\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                       ("Query interface for IPOIB interface returned %08x.\n", status) );\r
+               return status;\r
+       }\r
+\r
+       /*\r
+        * Dereference the interface now so that the bus driver doesn't fail a\r
+        * query remove IRP.  We will always get unloaded before the bus driver\r
+        * since we're a child device.\r
+        */\r
+       if (p_adapter->p_ifc)\r
+       p_adapter->p_ifc->wdm.InterfaceDereference(\r
+               p_adapter->p_ifc->wdm.Context );\r
+       IPOIB_EXIT( IPOIB_DBG_INIT );\r
+       return NDIS_STATUS_SUCCESS;\r
+}\r
+\r
+\r
+//! Initialization function called for each IOC discovered\r
+/*  The MiniportInitialize function is a required function that sets up a\r
+NIC (or virtual NIC) for network I/O operations, claims all hardware\r
+resources necessary to the NIC in the registry, and allocates resources\r
+the driver needs to carry out network I/O operations.\r
+IRQL = PASSIVE_LEVEL\r
+\r
+@param p_open_status Pointer to a status field set if this function returns NDIS_STATUS_OPEN_ERROR\r
+@param p_selected_medium_index Pointer to unsigned integer noting index into medium_array for this NIC\r
+@param medium_array Array of mediums for this NIC\r
+@param medium_array_size Number of elements in medium_array\r
+@param h_adapter Handle assigned by NDIS for this NIC\r
+@param wrapper_config_context Handle used for Ndis initialization functions\r
+@return NDIS_STATUS_SUCCESS, NDIS_STATUS_UNSUPPORTED_MEDIA, NDIS_STATUS_RESOURCES,\r
+NDIS_STATUS_NOT_SUPPORTED \r
+*/\r
+\r
+/*void foo1(int i)\r
+{\r
+               char temp[5200];\r
+               if (i ==0) return;\r
+               cl_msg_out("i = %d\n", i);\r
+               foo1(i-1);\r
+        \r
+}*/\r
+       \r
+NDIS_STATUS\r
+SetDeviceRegistrationAttributes(\r
+       ipoib_adapter_t *p_adapter,\r
+    NDIS_HANDLE        h_adapter\r
+    )\r
+{\r
+    NDIS_MINIPORT_ADD_DEVICE_REGISTRATION_ATTRIBUTES atr;\r
+    NTSTATUS Status;\r
+\r
+    NdisZeroMemory(&atr, sizeof(NDIS_MINIPORT_ADD_DEVICE_REGISTRATION_ATTRIBUTES));\r
+\r
+    //\r
+    // setting registration attributes\r
+    //\r
+    atr.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADD_DEVICE_REGISTRATION_ATTRIBUTES;\r
+    atr.Header.Revision = NDIS_MINIPORT_ADD_DEVICE_REGISTRATION_ATTRIBUTES_REVISION_1;\r
+    atr.Header.Size = NDIS_SIZEOF_MINIPORT_ADD_DEVICE_REGISTRATION_ATTRIBUTES_REVISION_1;\r
+\r
+\r
+    atr.MiniportAddDeviceContext = (NDIS_HANDLE)p_adapter;\r
+    atr.Flags = 0; \r
+\r
+    Status = NdisMSetMiniportAttributes(h_adapter,\r
+                    (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&atr);\r
+\r
+    return Status;\r
+}\r
+\r
+//NDIS 6.1\r
+#if 0\r
+NDIS_STATUS\r
+SetHardwareAssistAttributes(\r
+    ipoib_adapter_t *p_adapter,\r
+    NDIS_HANDLE        h_adapter\r
+    )\r
+{\r
+    NDIS_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES atr;\r
+    NTSTATUS Status;\r
+\r
+    NdisZeroMemory(&atr, sizeof(NDIS_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES));\r
+\r
+    //\r
+    // setting registration attributes\r
+    //\r
+    atr.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES;\r
+    atr.Header.Revision = NDIS_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES_REVISION_1;\r
+    atr.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES_REVISION_1;\r
+\r
+    NDIS_HD_SPLIT_ATTRIBUTES nhsa;\r
+    NdisZeroMemory(&nhsa, sizeof(nhsa));\r
+\r
+    nhsa.Header.Type = NDIS_OBJECT_TYPE_HD_SPLIT_ATTRIBUTES;\r
+    nhsa.Header.Revision = NDIS_OFFLOAD_REVISION_1;\r
+    nhsa.Header.Size = NDIS_SIZEOF_HD_SPLIT_ATTRIBUTES_REVISION_1;\r
+\r
+    // BUGBUG: We are just cheating here ...\r
+    nhsa.HardwareCapabilities = NDIS_HD_SPLIT_CAPS_SUPPORTS_HEADER_DATA_SPLIT;\r
+#if 0\r
+    ... Only supported on B0\r
+\r
+                                 NDIS_HD_SPLIT_CAPS_SUPPORTS_IPV4_OPTIONS |\r
+                                 NDIS_HD_SPLIT_CAPS_SUPPORTS_IPV6_EXTENSION_HEADERS |\r
+                                 NDIS_HD_SPLIT_CAPS_SUPPORTS_TCP_OPTIONS;\r
+#endif\r
+\r
+    // The bellow should be left zero\r
+    if (pPort->Config.HeaderDataSplit) {\r
+        nhsa.CurrentCapabilities = NDIS_HD_SPLIT_CAPS_SUPPORTS_HEADER_DATA_SPLIT;\r
+    } else {\r
+        nhsa.CurrentCapabilities = 0;\r
+    }\r
+\r
+    nhsa.HDSplitFlags = 0;\r
+    nhsa.BackfillSize = 0;\r
+    nhsa.MaxHeaderSize = 0;    \r
+\r
+    atr.HDSplitAttributes = &nhsa;\r
+\r
+    Status = NdisMSetMiniportAttributes(h_adapter,\r
+                    (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&atr);\r
+\r
+    if (nhsa.HDSplitFlags & NDIS_HD_SPLIT_ENABLE_HEADER_DATA_SPLIT) {\r
+        ASSERT(pPort->Config.HeaderDataSplit == TRUE);\r
+        pPort->Config.HeaderDataSplit = TRUE;\r
+    } \r
+    else {\r
+        ASSERT(pPort->Config.HeaderDataSplit == FALSE);\r
+        pPort->Config.HeaderDataSplit = FALSE;\r
+    }\r
+\r
+    return Status;\r
+}\r
+#endif\r
+\r
+/*++\r
+Routine Description:\r
+    the routine sets attributes that are associated with a miniport adapter.\r
+\r
+Arguments:\r
+    pPort - Pointer to port object\r
+\r
+Return Value:\r
+    NDIS_STATUS\r
+\r
+Note:\r
+    Should be called in PASSIVE_LEVEL\r
+    \r
+--*/\r
+NDIS_STATUS\r
+SetAdapterRegistrationAttributes(\r
+       ipoib_adapter_t *p_adapter,\r
+       NDIS_HANDLE     h_adapter\r
+       )\r
+       {\r
+       NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES atr;\r
+       NTSTATUS Status;\r
+\r
+       NdisZeroMemory(&atr, sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES));\r
+\r
+       /* setting registration attributes */\r
+\r
+       atr.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES;\r
+       atr.Header.Revision = NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1;\r
+       atr.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1;\r
+       //TODO NDIS60 Port or adapter\r
+       atr.MiniportAdapterContext = (NDIS_HANDLE)p_adapter; //(NDIS_HANDLE)pPort->p_adapter;\r
+       atr.AttributeFlags = NDIS_MINIPORT_ATTRIBUTES_BUS_MASTER;\r
+       atr.CheckForHangTimeInSeconds = 10;\r
+       atr.InterfaceType = NdisInterfacePci ;   // ???? UH\r
+       //TODO NDIS60 PNP or PCI ?\r
+       //RegistrationAttributes.InterfaceType = NdisInterfacePNPBus;\r
+\r
+       Status = NdisMSetMiniportAttributes(h_adapter,\r
+                       (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&atr);\r
+\r
+       return Status;\r
+}\r
+\r
+\r
+/*++\r
+Routine Description:\r
+    the routine sets generic attributes that are associated with a miniport \r
+    adapter.\r
+\r
+Arguments:\r
+    pPort - Pointer to port object\r
+\r
+Return Value:\r
+    NDIS_STATUS\r
+\r
+Note:\r
+    Should be called in PASSIVE_LEVEL\r
+    \r
+--*/\r
+NDIS_STATUS\r
+SetGenericAttributes(\r
+    ipoib_adapter_t *p_adapter,\r
+    NDIS_HANDLE        h_adapter\r
+    )\r
+{\r
+    NDIS_STATUS Status;\r
+\r
+    NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES gat;\r
+    NdisZeroMemory(&gat, sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES));\r
+\r
+       /* set up generic attributes */\r
+\r
+       gat.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES;\r
+       gat.Header.Revision = NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_1;\r
+       gat.Header.Size = sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES);\r
+\r
+       gat.MediaType = NdisMedium802_3;    \r
+       gat.MaxXmitLinkSpeed = IPOIB_MEDIA_MAX_SPEED;\r
+       gat.MaxRcvLinkSpeed = IPOIB_MEDIA_MAX_SPEED;\r
+       gat.XmitLinkSpeed = IPOIB_MEDIA_MAX_SPEED; //TODO NDIS60 NDIS_LINK_SPEED_UNKNOWN\r
+       gat.RcvLinkSpeed = IPOIB_MEDIA_MAX_SPEED; // TODO NDIS60 NDIS_LINK_SPEED_UNKNOWN ???\r
+\r
+       gat.MediaConnectState = MediaConnectStateConnected; //TODO NDIS60 Check the current state\r
+       gat.MediaDuplexState = MediaDuplexStateFull;\r
+\r
+       gat.MtuSize = MAX_IB_MTU;\r
+       gat.LookaheadSize = MAX_XFER_BLOCK_SIZE;\r
+       gat.MacOptions = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | \r
+                                        NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |\r
+                                        NDIS_MAC_OPTION_NO_LOOPBACK |\r
+                                        NDIS_MAC_OPTION_FULL_DUPLEX;\r
+                                       //NDIS_MAC_OPTION_8021P_PRIORITY; //TODO NDIS60\r
+                                       // DT: Enable for Header Data Split WHQL\r
+                                       // |  NDIS_MAC_OPTION_8021Q_VLAN;\r
+\r
+       gat.SupportedPacketFilters =    NDIS_PACKET_TYPE_DIRECTED |\r
+                                                                       NDIS_PACKET_TYPE_MULTICAST |\r
+                                                                       //NDIS_PACKET_TYPE_ALL_MULTICAST |\r
+                                                                       NDIS_PACKET_TYPE_BROADCAST;\r
+                                        \r
+       gat.MaxMulticastListSize = MAX_MCAST;\r
+\r
+       gat.MacAddressLength = HW_ADDR_LEN;\r
+       \r
+       NdisMoveMemory(gat.PermanentMacAddress,\r
+                                       p_adapter->mac.addr,\r
+                                       HW_ADDR_LEN);\r
+\r
+       NdisMoveMemory(gat.CurrentMacAddress,\r
+                                       p_adapter->params.conf_mac.addr,\r
+                                       HW_ADDR_LEN);\r
+\r
+\r
+       gat.PhysicalMediumType = NdisPhysicalMedium802_3;\r
+       gat.AccessType = NET_IF_ACCESS_BROADCAST; \r
+\r
+       gat.SupportedOidList = (PNDIS_OID)SUPPORTED_OIDS;\r
+       gat.SupportedOidListLength = sizeof(SUPPORTED_OIDS);\r
+\r
+\r
+       gat.DirectionType = NET_IF_DIRECTION_SENDRECEIVE; \r
+       gat.ConnectionType = NET_IF_CONNECTION_DEDICATED; \r
+       gat.IfType = IF_TYPE_ETHERNET_CSMACD; \r
+       gat.IfConnectorPresent = TRUE; \r
+       //TODO NDIS60 This value is absent for ETH driver\r
+       gat.AccessType = NET_IF_ACCESS_BROADCAST; // NET_IF_ACCESS_BROADCAST for a typical ethernet adapter\r
+\r
+\r
+       //TODO NDIS60 is it possible to reduce unsupported statistics\r
+       gat.SupportedStatistics = \r
+                               NDIS_STATISTICS_XMIT_OK_SUPPORTED |\r
+                               NDIS_STATISTICS_RCV_OK_SUPPORTED |\r
+                               NDIS_STATISTICS_XMIT_ERROR_SUPPORTED |\r
+                               NDIS_STATISTICS_RCV_ERROR_SUPPORTED |\r
+                               NDIS_STATISTICS_RCV_CRC_ERROR_SUPPORTED |\r
+                               NDIS_STATISTICS_RCV_NO_BUFFER_SUPPORTED |\r
+                               NDIS_STATISTICS_TRANSMIT_QUEUE_LENGTH_SUPPORTED;\r
+\r
+       //SupportedStatistics = NDIS_STATISTICS_XMIT_OK_SUPPORTED |\r
+                                                       // NDIS_STATISTICS_GEN_STATISTICS_SUPPORTED;\r
+\r
+\r
+    //\r
+    // Set power management capabilities\r
+    //\r
+    gat.PowerManagementCapabilities = NULL;\r
+#if 0\r
+    NDIS_PNP_CAPABILITIES PowerManagementCapabilities;\r
+    NdisZeroMemory(&PowerManagementCapabilities, sizeof(NDIS_PNP_CAPABILITIES));\r
+    if (MPIsPoMgmtSupported(pPort))\r
+    {\r
+        MPFillPoMgmtCaps(pPort, &PowerManagementCapabilities, &Status, &unUsed);\r
+        ASSERT(NT_SUCCESS(Status)); \r
+        gat.PowerManagementCapabilities = &PowerManagementCapabilities;\r
+    } \r
+    else\r
+    {\r
+        \r
+    }\r
+#endif\r
+\r
+    //\r
+    // Set RSS attributes\r
+    //\r
+    gat.RecvScaleCapabilities = NULL;\r
+#if 0\r
+    NDIS_RECEIVE_SCALE_CAPABILITIES RssCapabilities;\r
+    NdisZeroMemory(&RssCapabilities, sizeof(PNDIS_RECEIVE_SCALE_CAPABILITIES));\r
+    Status = MPFillRssCapabilities(pPort, &RssCapabilities, &unUsed);\r
+    if (NT_SUCCESS(Status)) \r
+    {\r
+        gat.RecvScaleCapabilities = &RssCapabilities;\r
+    } \r
+    else\r
+    {\r
+        //\r
+        // do not fail the call because of failure to get PM caps\r
+        //\r
+        Status = NDIS_STATUS_SUCCESS;\r
+        gat.RecvScaleCapabilities = NULL;\r
+    }\r
+#endif\r
+\r
+       Status = NdisMSetMiniportAttributes(h_adapter,\r
+                       (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&gat);\r
+\r
+       return Status;\r
+}\r
+\r
+\r
+/*++\r
+Routine Description:\r
+    The routine sets an NDIS_OFFLOAD structure indicates the current offload \r
+    capabilities that are provided by the miniport adapter \r
+    \r
+Arguments:\r
+    pPort - a pointer to port object\r
+    offload - reference to NDIS_OFFLOAD object that should be filled\r
+\r
+Return Value:\r
+    None.\r
+    \r
+--*/\r
+static\r
+void\r
+OffloadConfig(\r
+       ipoib_adapter_t *p_adapter,\r
+       NDIS_OFFLOAD *p_offload\r
+       )\r
+{ \r
+\r
+       ULONG ulEncapsulation = NDIS_ENCAPSULATION_IEEE_802_3 | NDIS_ENCAPSULATION_IEEE_802_3_P_AND_Q;\r
+\r
+       NdisZeroMemory(p_offload, NDIS_SIZEOF_NDIS_OFFLOAD_REVISION_1);\r
+\r
+       p_offload->Header.Type = NDIS_OBJECT_TYPE_OFFLOAD;\r
+       p_offload->Header.Revision = NDIS_OFFLOAD_REVISION_1; // BUGBUG: do we need to support revision 2? UH 17-May-2008\r
+       p_offload->Header.Size = NDIS_SIZEOF_NDIS_OFFLOAD_REVISION_1;\r
+\r
+       p_offload->Checksum.IPv4Transmit.Encapsulation = ulEncapsulation;\r
+       p_offload->Checksum.IPv4Transmit.IpOptionsSupported = \r
+       p_offload->Checksum.IPv4Transmit.TcpOptionsSupported = \r
+       p_offload->Checksum.IPv4Transmit.TcpChecksum = \r
+       p_offload->Checksum.IPv4Transmit.UdpChecksum = \r
+       p_offload->Checksum.IPv4Transmit.IpChecksum =!!(p_adapter->params.send_chksum_offload);\r
+\r
+       p_offload->Checksum.IPv4Receive.Encapsulation = ulEncapsulation;\r
+       p_offload->Checksum.IPv4Receive.IpOptionsSupported = \r
+       p_offload->Checksum.IPv4Receive.TcpOptionsSupported = \r
+       p_offload->Checksum.IPv4Receive.TcpChecksum = \r
+       p_offload->Checksum.IPv4Receive.UdpChecksum = \r
+       p_offload->Checksum.IPv4Receive.IpChecksum = !!(p_adapter->params.recv_chksum_offload); //TODO NDIS60\r
+\r
+\r
+       p_offload->Checksum.IPv6Transmit.Encapsulation = ulEncapsulation;\r
+       p_offload->Checksum.IPv6Transmit.IpExtensionHeadersSupported = \r
+       p_offload->Checksum.IPv6Transmit.TcpOptionsSupported =\r
+       p_offload->Checksum.IPv6Transmit.TcpChecksum = \r
+       p_offload->Checksum.IPv6Transmit.UdpChecksum = FALSE;\r
+\r
+\r
+       p_offload->Checksum.IPv6Receive.Encapsulation = ulEncapsulation;\r
+       p_offload->Checksum.IPv6Receive.IpExtensionHeadersSupported = \r
+       p_offload->Checksum.IPv6Receive.TcpOptionsSupported = \r
+       p_offload->Checksum.IPv6Receive.TcpChecksum = \r
+       p_offload->Checksum.IPv6Receive.UdpChecksum = FALSE;\r
+\r
+       if (p_adapter->params.lso)\r
+       {\r
+               p_offload->LsoV1.IPv4.Encapsulation = ulEncapsulation;\r
+               p_offload->LsoV1.IPv4.MaxOffLoadSize = LARGE_SEND_OFFLOAD_SIZE;\r
+#define LSO_MIN_SEG_COUNT 2\r
+               p_offload->LsoV1.IPv4.MinSegmentCount = LSO_MIN_SEG_COUNT;\r
+       \r
+               \r
+               p_offload->LsoV1.IPv4.TcpOptions = NDIS_OFFLOAD_SUPPORTED;\r
+               p_offload->LsoV1.IPv4.IpOptions = NDIS_OFFLOAD_SUPPORTED;\r
+\r
+               p_offload->LsoV2.IPv4.Encapsulation = ulEncapsulation;\r
+               p_offload->LsoV2.IPv4.MaxOffLoadSize = LARGE_SEND_OFFLOAD_SIZE;\r
+               p_offload->LsoV2.IPv4.MinSegmentCount = LSO_MIN_SEG_COUNT;\r
+\r
+               p_offload->LsoV2.IPv6.Encapsulation = ulEncapsulation;\r
+               p_offload->LsoV2.IPv6.MaxOffLoadSize = LARGE_SEND_OFFLOAD_SIZE;\r
+               p_offload->LsoV2.IPv6.MinSegmentCount = LSO_MIN_SEG_COUNT;\r
+\r
+               p_offload->LsoV2.IPv6.IpExtensionHeadersSupported = NDIS_OFFLOAD_NOT_SUPPORTED;\r
+               p_offload->LsoV2.IPv6.TcpOptionsSupported = NDIS_OFFLOAD_SUPPORTED;\r
+       }\r
+\r
+}\r
+\r
+\r
+/*++\r
+Routine Description:\r
+    The routine sets an NDIS_OFFLOAD structure that indicates all the task \r
+    offload capabilites that are supported by the NIC. These capabilities include\r
+    capabilities that are currently disabled by standardized keywords in the registry. \r
+    \r
+Arguments:\r
+    offload - reference to NDIS_OFFLOAD object that should be filled\r
+\r
+Return Value:\r
+    None.\r
+    \r
+--*/\r
+static\r
+void\r
+OffloadCapabilities(\r
+       NDIS_OFFLOAD    *p_offload\r
+       )\r
+{ \r
+       ULONG ulEncapsulation = NDIS_ENCAPSULATION_IEEE_802_3 | NDIS_ENCAPSULATION_IEEE_802_3_P_AND_Q ;\r
+       NdisZeroMemory(p_offload, NDIS_SIZEOF_NDIS_OFFLOAD_REVISION_1);    \r
+\r
+       p_offload->Header.Type = NDIS_OBJECT_TYPE_OFFLOAD;\r
+       p_offload->Header.Revision = NDIS_OFFLOAD_REVISION_1; // BUGBUG: do we need to support revision 2? UH 17-May-2008\r
+       p_offload->Header.Size = NDIS_SIZEOF_NDIS_OFFLOAD_REVISION_1;\r
+\r
+       p_offload->Checksum.IPv4Transmit.Encapsulation = ulEncapsulation;\r
+       p_offload->Checksum.IPv4Transmit.IpOptionsSupported = TRUE;\r
+       p_offload->Checksum.IPv4Transmit.TcpOptionsSupported = TRUE;\r
+       p_offload->Checksum.IPv4Transmit.TcpChecksum = TRUE;\r
+       p_offload->Checksum.IPv4Transmit.UdpChecksum = TRUE;\r
+       p_offload->Checksum.IPv4Transmit.IpChecksum = TRUE;\r
+\r
+       p_offload->Checksum.IPv4Receive.Encapsulation = ulEncapsulation;\r
+       p_offload->Checksum.IPv4Receive.IpOptionsSupported = TRUE;\r
+       p_offload->Checksum.IPv4Receive.TcpOptionsSupported = TRUE;\r
+       p_offload->Checksum.IPv4Receive.TcpChecksum = TRUE;\r
+       p_offload->Checksum.IPv4Receive.UdpChecksum = TRUE; \r
+       p_offload->Checksum.IPv4Receive.IpChecksum = TRUE;\r
+\r
+\r
+       //\r
+       //  BUGBUG::\r
+       //  During a HW bug that didn't handle correctly packets with \r
+       //  IPv6 Extension Headers -> we set IpExtensionHeadersSupported to TRUE\r
+       //\r
+       p_offload->Checksum.IPv6Transmit.Encapsulation = ulEncapsulation;\r
+       p_offload->Checksum.IPv6Transmit.IpExtensionHeadersSupported = TRUE;\r
+       p_offload->Checksum.IPv6Transmit.TcpOptionsSupported = TRUE;\r
+       p_offload->Checksum.IPv6Transmit.TcpChecksum = TRUE;\r
+       p_offload->Checksum.IPv6Transmit.UdpChecksum = TRUE;\r
+\r
+\r
+       p_offload->Checksum.IPv6Receive.Encapsulation = ulEncapsulation;\r
+       p_offload->Checksum.IPv6Receive.IpExtensionHeadersSupported = TRUE;\r
+       p_offload->Checksum.IPv6Receive.TcpOptionsSupported = TRUE;\r
+       p_offload->Checksum.IPv6Receive.TcpChecksum = TRUE;\r
+       p_offload->Checksum.IPv6Receive.UdpChecksum = TRUE;\r
+\r
+       p_offload->LsoV1.IPv4.Encapsulation = ulEncapsulation;\r
+       p_offload->LsoV1.IPv4.MaxOffLoadSize = LARGE_SEND_OFFLOAD_SIZE;\r
+       p_offload->LsoV1.IPv4.MinSegmentCount = 2;\r
+       p_offload->LsoV1.IPv4.TcpOptions = NDIS_OFFLOAD_SUPPORTED;\r
+       p_offload->LsoV1.IPv4.IpOptions = NDIS_OFFLOAD_SUPPORTED;\r
+\r
+       p_offload->LsoV2.IPv4.Encapsulation = ulEncapsulation;\r
+       p_offload->LsoV2.IPv4.MaxOffLoadSize = LARGE_SEND_OFFLOAD_SIZE;\r
+       p_offload->LsoV2.IPv4.MinSegmentCount = 2;\r
+\r
+       p_offload->LsoV2.IPv6.Encapsulation = ulEncapsulation;\r
+       p_offload->LsoV2.IPv6.MaxOffLoadSize = LARGE_SEND_OFFLOAD_SIZE;\r
+       p_offload->LsoV2.IPv6.MinSegmentCount = 2;\r
+\r
+       p_offload->LsoV2.IPv6.IpExtensionHeadersSupported = NDIS_OFFLOAD_NOT_SUPPORTED;\r
+       p_offload->LsoV2.IPv6.TcpOptionsSupported = NDIS_OFFLOAD_SUPPORTED;\r
+\r
+       }\r
+\r
+\r
+/*++\r
+Routine Description:\r
+    The routine sets offload attributes that are associated with a miniport \r
+    adapter.\r
+\r
+Arguments:\r
+    pPort - Pointer to port object\r
+\r
+Return Value:\r
+    NDIS_STATUS\r
+\r
+Note:\r
+    Should be called in PASSIVE_LEVEL\r
+    \r
+--*/\r
+NDIS_STATUS\r
+SetOffloadAttributes(\r
+       ipoib_adapter_t *p_adapter,\r
+       NDIS_HANDLE     h_adapter\r
+       )\r
+{\r
+       NDIS_STATUS Status;\r
+       NDIS_OFFLOAD offload,hwOffload;\r
+       //ULONG ulEncapsulation = NDIS_ENCAPSULATION_IEEE_802_3 | NDIS_ENCAPSULATION_IEEE_802_3_P_AND_Q;\r
+\r
+       NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES oat;    \r
+       NdisZeroMemory(&oat, sizeof(NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES));\r
+\r
+       oat.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES;\r
+       oat.Header.Revision = NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES_REVISION_1;\r
+       oat.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES_REVISION_1;\r
+\r
+\r
+       OffloadConfig(p_adapter, &offload);\r
+\r
+\r
+       OffloadCapabilities(&hwOffload);\r
+\r
+       oat.DefaultOffloadConfiguration = &offload;\r
+       oat.HardwareOffloadCapabilities = &hwOffload;\r
+\r
+       Status = NdisMSetMiniportAttributes(h_adapter,\r
+                               (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&oat);\r
+\r
+       return Status;\r
+}\r
+\r
+\r
+/*++\r
+\r
+Routine Description:\r
+    An NDIS 6.0 miniport driver must call NdisMSetMiniportAttributes\r
+    at least twice. The first call is to register itself with NDIS.\r
+    The second call is to register the miniport driver's general\r
+    attributes with NDIS.\r
+\r
+    NdisMSetMiniportAttributes takes a parameter of type\r
+    NDIS_MINIPORT_ADAPTER_ATTRIBUTES, which is a union of several miniport\r
+    adapter attributes. Miniport drivers must first call\r
+    NdisMSetMiniportAttributes and pass in an\r
+    NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES structure\r
+    that contains the pointer to its own context area, attribute flags,\r
+    check-for-hang time, and interface type.\r
+\r
+    All NDIS 6.0 miniport drivers are deserialized by default.\r
+\r
+Arguments:\r
+    pPort - Pointer to port object\r
+\r
+Return Value:\r
+    NDIS_STATUS\r
+\r
+Note:\r
+    Should be called in PASSIVE_LEVEL\r
+    \r
+--*/\r
+       NDIS_STATUS\r
+       SetAttributes(\r
+       ipoib_adapter_t *p_adapter,\r
+       NDIS_HANDLE     h_adapter\r
+       )\r
+       {\r
+       NTSTATUS Status;\r
+\r
+\r
+       Status = SetDeviceRegistrationAttributes(p_adapter, h_adapter);\r
+       if (Status != NDIS_STATUS_SUCCESS)\r
+       {\r
+               //ETH_PRINT(TRACE_LEVEL_ERROR, ETH_INIT, "Set device registration failed Error=0x%x\n", Status);\r
+               return Status;\r
+       }\r
+\r
+\r
+       Status = SetAdapterRegistrationAttributes(p_adapter, h_adapter);\r
+       if (Status != NDIS_STATUS_SUCCESS)\r
+       {\r
+               //ETH_PRINT(TRACE_LEVEL_ERROR, ETH_INIT, "Set adapter attributes failed Error=0x%x\n", Status);\r
+               return Status;\r
+       }\r
+\r
+       Status = SetOffloadAttributes(p_adapter, h_adapter);\r
+       if (Status != NDIS_STATUS_SUCCESS)\r
+       {\r
+               //ETH_PRINT(TRACE_LEVEL_ERROR, ETH_INIT, "Set OFFLOAD attributes failed Error=0x%x\n", Status);\r
+               return Status;\r
+       }\r
+       \r
+#if 0\r
+       if(!pPort->Config.fWHQL)\r
+       {\r
+               Status = SetHardwareAssistAttributes(pPort);\r
+               if (Status != NDIS_STATUS_SUCCESS)\r
+               {\r
+                   //ETH_PRINT(TRACE_LEVEL_ERROR, ETH_INIT, "Set Hardware Assist Attributes failed Error=0x%x\n", Status);\r
+                   return Status;\r
+               }\r
+       }\r
+#endif\r
+\r
+       Status = SetGenericAttributes(p_adapter, h_adapter);\r
+       if (Status != NDIS_STATUS_SUCCESS)\r
+       {\r
+           //ETH_PRINT(TRACE_LEVEL_ERROR, ETH_INIT, "Set generic attributes failed Error=0x%x\n", Status);\r
+           return Status;\r
+       }\r
+\r
+       return Status;\r
+}\r
+\r
+\r
+//TODO Don't pass h_adapter inside the function, use pPort->p_adapter->h_adapter\r
+NDIS_STATUS\r
+InitNdisScatterGatherDma(\r
+       ipoib_adapter_t *p_adapter,\r
+       NDIS_HANDLE             h_adapter\r
+       )\r
+{\r
+       NDIS_STATUS                                             status;\r
+       NDIS_SG_DMA_DESCRIPTION                 DmaDescription;\r
+       \r
+       NdisZeroMemory(&DmaDescription, sizeof(DmaDescription));\r
+\r
+       DmaDescription.Header.Type = NDIS_OBJECT_TYPE_SG_DMA_DESCRIPTION;\r
+       DmaDescription.Header.Revision = NDIS_SG_DMA_DESCRIPTION_REVISION_1;\r
+       DmaDescription.Header.Size = sizeof(NDIS_SG_DMA_DESCRIPTION);\r
+       DmaDescription.Flags = NDIS_SG_DMA_64_BIT_ADDRESS; \r
+       //\r
+       // Even if offload is enabled, the packet size for mapping shouldn't change\r
+       //\r
+       DmaDescription.MaximumPhysicalMapping = LARGE_SEND_OFFLOAD_SIZE + LSO_MAX_HEADER;\r
+\r
+       DmaDescription.ProcessSGListHandler = ipoib_process_sg_list;\r
+       DmaDescription.SharedMemAllocateCompleteHandler = NULL;\r
+\r
+       DmaDescription.Header.Type = NDIS_OBJECT_TYPE_SG_DMA_DESCRIPTION;\r
+       DmaDescription.Header.Revision = NDIS_SG_DMA_DESCRIPTION_REVISION_1;\r
+       DmaDescription.Header.Size = sizeof(NDIS_SG_DMA_DESCRIPTION);//NDIS_SIZEOF_SG_DMA_DESCRIPTION_REVISION_1;\r
+\r
+       DmaDescription.Flags = NDIS_SG_DMA_64_BIT_ADDRESS;\r
+       //DmaDescription.MaximumPhysicalMapping = pPort->p_adapter->params.xfer_block_size;\r
+\r
+       DmaDescription.ProcessSGListHandler = ipoib_process_sg_list;\r
+       DmaDescription.SharedMemAllocateCompleteHandler = NULL;\r
+       \r
+       status = NdisMRegisterScatterGatherDma(\r
+                                       h_adapter,\r
+                                       &DmaDescription,\r
+                                       &p_adapter->NdisMiniportDmaHandle);\r
+\r
+       if( status != NDIS_STATUS_SUCCESS )\r
+       {\r
+               //TODO NDIS60\r
+               //ipoib_destroy_adapter( p_adapter );\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                                                ("NdisMRegisterScatterGatherDma returned 0x%.8x.\n", status) );\r
+               \r
+       }\r
+       //NDIS sets this value before it returns from NdisMRegisterScatterGatherDma. \r
+               //Miniport drivers should use this size to preallocate memory for each scatter/gather list. \r
+       p_adapter->sg_list_size = DmaDescription.ScatterGatherListSize ;\r
+       \r
+       return status;\r
+}\r
+\r
+\r
+NDIS_STATUS\r
+ipoib_initialize_ex(\r
+               IN NDIS_HANDLE  h_adapter,\r
+               IN NDIS_HANDLE  config_context,\r
+               IN PNDIS_MINIPORT_INIT_PARAMETERS  MiniportInitParameters)\r
+       {\r
+               NDIS_STATUS             status;\r
+               ib_api_status_t         ib_status;\r
+               ipoib_adapter_t         *p_adapter;\r
+               //NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES RegistrationAttributes;\r
+               //NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES              GeneralAttributes;\r
+#if IPOIB_USE_DMA\r
+               //NDIS_SG_DMA_DESCRIPTION       DmaDescription;\r
+#endif\r
+               IPOIB_ENTER( IPOIB_DBG_INIT );\r
+       \r
+#ifdef _DEBUG_\r
+               PAGED_CODE();\r
+#endif\r
+               \r
+               UNUSED_PARAM( config_context );\r
+               UNUSED_PARAM( MiniportInitParameters );\r
+               \r
+               //foo1(100);\r
+               /* Create the adapter adapter */\r
+               ib_status = ipoib_create_adapter(config_context, h_adapter, &p_adapter );\r
+               if( ib_status != IB_SUCCESS )\r
+               {\r
+                       IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                               ("ipoib_create_adapter returned status %d.\n", ib_status ) );\r
+                       return NDIS_STATUS_FAILURE;\r
+               }\r
+               p_adapter->ipoib_state = IPOIB_PAUSED;\r
+               status  = SetAttributes(p_adapter, h_adapter);\r
+               if (status != NDIS_STATUS_SUCCESS) {\r
+                       ASSERT(FALSE);\r
+               }\r
+#if 0\r
+               NdisZeroMemory(&RegistrationAttributes, sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES));\r
+               NdisZeroMemory(&GeneralAttributes, sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES));\r
+       \r
+               /* setting registration attributes */\r
+               RegistrationAttributes.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES;\r
+               RegistrationAttributes.Header.Revision = NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1;\r
+               RegistrationAttributes.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1;\r
+       \r
+               RegistrationAttributes.MiniportAdapterContext = (NDIS_HANDLE)p_adapter;\r
+               RegistrationAttributes.AttributeFlags = NDIS_MINIPORT_ATTRIBUTES_BUS_MASTER;\r
+                                                                                                               \r
+               RegistrationAttributes.CheckForHangTimeInSeconds = 10;\r
+               RegistrationAttributes.InterfaceType = NdisInterfacePNPBus;\r
+       \r
+               status = NdisMSetMiniportAttributes(h_adapter,\r
+                                                                                  (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&RegistrationAttributes);\r
+       \r
+               if (status != NDIS_STATUS_SUCCESS)\r
+               {\r
+                       ipoib_destroy_adapter( p_adapter );\r
+                       IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                               ("NdisMSetMiniportAttributes returned 0x%.8x.\n", status) );\r
+                       return status;\r
+               }\r
+       \r
+               /* set up generic attributes */\r
+       \r
+                GeneralAttributes.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES;\r
+                GeneralAttributes.Header.Revision = NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_1;\r
+                GeneralAttributes.Header.Size = sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES);\r
+       \r
+                GeneralAttributes.MediaType = NdisMedium802_3;\r
+               //TODO\r
+                GeneralAttributes.MtuSize = MAX_IB_MTU;\r
+                GeneralAttributes.MaxXmitLinkSpeed = IPOIB_MEDIA_MAX_SPEED;\r
+                GeneralAttributes.MaxRcvLinkSpeed = IPOIB_MEDIA_MAX_SPEED;\r
+                GeneralAttributes.XmitLinkSpeed = NDIS_LINK_SPEED_UNKNOWN;\r
+                GeneralAttributes.RcvLinkSpeed = NDIS_LINK_SPEED_UNKNOWN;\r
+                GeneralAttributes.MediaConnectState = MediaConnectStateUnknown;\r
+                GeneralAttributes.MediaDuplexState = MediaDuplexStateUnknown;\r
+                GeneralAttributes.LookaheadSize = MAX_XFER_BLOCK_SIZE;\r
+       \r
+                GeneralAttributes.PowerManagementCapabilities = NULL;\r
+       \r
+                GeneralAttributes.MacOptions = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |\r
+                                                                               NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |\r
+                                                                               NDIS_MAC_OPTION_NO_LOOPBACK |\r
+                                                                               NDIS_MAC_OPTION_FULL_DUPLEX;\r
+       \r
+                GeneralAttributes.SupportedPacketFilters = NDIS_PACKET_TYPE_DIRECTED |\r
+                                                                                                       NDIS_PACKET_TYPE_MULTICAST |\r
+                                                                                                       NDIS_PACKET_TYPE_ALL_MULTICAST |\r
+                                                                                                       NDIS_PACKET_TYPE_BROADCAST;\r
+                       \r
+                GeneralAttributes.MaxMulticastListSize = MAX_MCAST;\r
+                GeneralAttributes.MacAddressLength = HW_ADDR_LEN;\r
+       \r
+                NdisMoveMemory(GeneralAttributes.PermanentMacAddress,\r
+                                               p_adapter->mac.addr,\r
+                                               HW_ADDR_LEN);\r
+       \r
+                NdisMoveMemory(GeneralAttributes.CurrentMacAddress,\r
+                                               p_adapter->params.conf_mac.addr,\r
+                                               HW_ADDR_LEN);\r
+       \r
+                       \r
+                GeneralAttributes.PhysicalMediumType = NdisPhysicalMediumUnspecified;\r
+                GeneralAttributes.RecvScaleCapabilities = NULL;\r
+                GeneralAttributes.AccessType = NET_IF_ACCESS_BROADCAST; // NET_IF_ACCESS_BROADCAST for a typical ethernet adapter\r
+                GeneralAttributes.DirectionType = NET_IF_DIRECTION_SENDRECEIVE; // NET_IF_DIRECTION_SENDRECEIVE for a typical ethernet adapter\r
+                GeneralAttributes.ConnectionType = NET_IF_CONNECTION_DEDICATED;  // NET_IF_CONNECTION_DEDICATED for a typical ethernet adapter\r
+                GeneralAttributes.IfType = IF_TYPE_ETHERNET_CSMACD; // IF_TYPE_ETHERNET_CSMACD for a typical ethernet adapter (regardless of speed)\r
+                GeneralAttributes.IfConnectorPresent = TRUE; // RFC 2665 TRUE if physical adapter\r
+       \r
+                GeneralAttributes.SupportedStatistics = NDIS_STATISTICS_XMIT_OK_SUPPORTED |\r
+                                                                                                NDIS_STATISTICS_RCV_OK_SUPPORTED |\r
+                                                                                                NDIS_STATISTICS_XMIT_ERROR_SUPPORTED |\r
+                                                                                                NDIS_STATISTICS_RCV_ERROR_SUPPORTED |\r
+                                                                                                NDIS_STATISTICS_RCV_CRC_ERROR_SUPPORTED |\r
+                                                                                                NDIS_STATISTICS_RCV_NO_BUFFER_SUPPORTED |\r
+                                                                                                NDIS_STATISTICS_TRANSMIT_QUEUE_LENGTH_SUPPORTED |\r
+                                                                                                NDIS_STATISTICS_GEN_STATISTICS_SUPPORTED;\r
+                                                 \r
+                GeneralAttributes.SupportedOidList = (PNDIS_OID)SUPPORTED_OIDS;\r
+                GeneralAttributes.SupportedOidListLength = sizeof(SUPPORTED_OIDS);\r
+       \r
+                status = NdisMSetMiniportAttributes(h_adapter,\r
+                                                                                       (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&GeneralAttributes);\r
+       \r
+                if (status != NDIS_STATUS_SUCCESS)\r
+                {\r
+                        IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                                ("NdisMSetMiniportAttributes returned 0x%.8x.\n", status) );\r
+                }\r
+       \r
+#if IPOIB_USE_DMA\r
+       \r
+                NdisZeroMemory(&DmaDescription, sizeof(DmaDescription));\r
+       \r
+                DmaDescription.Header.Type = NDIS_OBJECT_TYPE_SG_DMA_DESCRIPTION;\r
+                DmaDescription.Header.Revision = NDIS_SG_DMA_DESCRIPTION_REVISION_1;\r
+                DmaDescription.Header.Size = sizeof(NDIS_SG_DMA_DESCRIPTION);//NDIS_SIZEOF_SG_DMA_DESCRIPTION_REVISION_1;\r
+       \r
+                DmaDescription.Flags = NDIS_SG_DMA_64_BIT_ADDRESS;\r
+                DmaDescription.MaximumPhysicalMapping = p_adapter->params.xfer_block_size;\r
+               \r
+                DmaDescription.ProcessSGListHandler = ipoib_process_sg_list;\r
+                DmaDescription.SharedMemAllocateCompleteHandler = NULL;\r
+       \r
+                status = NdisMRegisterScatterGatherDma(\r
+                                               p_adapter->h_adapter,\r
+                                               &DmaDescription,\r
+                                               &p_adapter->NdisMiniportDmaHandle);\r
+                                               \r
+                if( status != NDIS_STATUS_SUCCESS )\r
+                {\r
+                        ipoib_destroy_adapter( p_adapter );\r
+                        IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                                                        ("NdisMRegisterScatterGatherDma returned 0x%.8x.\n", status) );\r
+                        return status;\r
+                }\r
+\r
+               \r
+               \r
+#endif\r
+#endif //if 0\r
+\r
+\r
+\r
+#if IPOIB_USE_DMA\r
+\r
+               InitNdisScatterGatherDma(p_adapter, h_adapter);\r
+\r
+\r
+\r
+#endif\r
+               /* Create the adapter adapter */\r
+               ib_status = ipoib_start_adapter( p_adapter );\r
+               if( ib_status != IB_SUCCESS )\r
+               {\r
+                       NdisWriteErrorLogEntry( h_adapter,\r
+                               NDIS_ERROR_CODE_HARDWARE_FAILURE, 0 );\r
+#if  IPOIB_USE_DMA\r
+                       NdisMDeregisterScatterGatherDma(p_adapter->NdisMiniportDmaHandle);\r
+#endif\r
+                       ipoib_destroy_adapter( p_adapter );\r
+                       IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                               ("ipoib_start_adapter returned status %d.\n", ib_status ) );\r
+                       return NDIS_STATUS_FAILURE;\r
+               }\r
+       \r
+               ipoib_ref_ibat();\r
+       \r
+               IPOIB_EXIT( IPOIB_DBG_INIT );\r
+               return status;\r
+       }\r
+\r
+\r
+//! Deallocates resources when the NIC is removed and halts the NIC..\r
+//TODO: Dispatch or Passive ?\r
+/*  IRQL = DISPATCH_LEVEL\r
+\r
+@param adapter_context The adapter context allocated at start\r
+*/\r
+void\r
+ipoib_halt_ex(\r
+       IN                              NDIS_HANDLE                                     adapter_context,\r
+       IN                      NDIS_HALT_ACTION            HaltAction )\r
+{\r
+       ipoib_adapter_t *p_adapter;\r
+\r
+       IPOIB_ENTER( IPOIB_DBG_INIT );\r
+\r
+       UNUSED_PARAM(HaltAction);\r
+               \r
+       ipoib_deref_ibat();\r
+\r
+       CL_ASSERT( adapter_context );\r
+       p_adapter = (ipoib_adapter_t*)adapter_context;\r
+\r
+       IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,\r
+                       ("Port %016I64x (CA %016I64x port %d) halting\n",\r
+                       p_adapter->guids.port_guid.guid, p_adapter->guids.ca_guid,\r
+                       p_adapter->guids.port_num) );\r
+\r
+#if IPOIB_USE_DMA\r
+       if (p_adapter->NdisMiniportDmaHandle != NULL)\r
+       {\r
+               NdisMDeregisterScatterGatherDma(p_adapter->NdisMiniportDmaHandle);\r
+               p_adapter->NdisMiniportDmaHandle = NULL;\r
+       }\r
+#endif\r
+       ipoib_destroy_adapter( p_adapter );\r
+\r
+       IPOIB_EXIT( IPOIB_DBG_INIT );\r
+}\r
+\r
+\r
+//! Reports the state of the NIC, or monitors the responsiveness of an underlying device driver.\r
+/*  IRQL = DISPATCH_LEVEL\r
+\r
+@param adapter_context The adapter context allocated at start\r
+@return TRUE if the driver determines that its NIC is not operating\r
+*/\r
+BOOLEAN\r
+ipoib_check_for_hang(\r
+       IN                              NDIS_HANDLE                                     adapter_context )\r
+{\r
+       ipoib_adapter_t *p_adapter;\r
+\r
+       IPOIB_ENTER( IPOIB_DBG_INIT );\r
+\r
+       CL_ASSERT( adapter_context );\r
+       p_adapter = (ipoib_adapter_t*)adapter_context;\r
+\r
+       if( p_adapter->reset )\r
+       {\r
+               IPOIB_EXIT( IPOIB_DBG_INIT );\r
+               return FALSE;\r
+       }\r
+       if (p_adapter->hung) {\r
+               ipoib_resume_oids(p_adapter);\r
+       }\r
+\r
+       IPOIB_EXIT( IPOIB_DBG_INIT );\r
+       return (p_adapter->hung? TRUE:FALSE);\r
+}\r
+\r
+\r
+/*++\r
+Routine Description:\r
+       The routine sets an NDIS_OFFLOAD structure indicates the current offload \r
+       capabilities that are provided by the miniport adapter \r
+\r
+Arguments:\r
+       pPort - a pointer to port object\r
+       offload - reference to NDIS_OFFLOAD object that should be filled\r
+\r
+Return Value:\r
+       None.\r
+\r
+--*/\r
+//TODO\r
+#if 0\r
+static\r
+void\r
+__ipoib_get_offload_config(\r
+       ipoib_port_t *pPort,\r
+       NDIS_OFFLOAD *p_offload\r
+       )\r
+{\r
+       NDIS_STATUS Status;\r
+       ULONG TxChksumOffload = ((MP_GET_PORT_CONFIG(pPort, TxChksumOffload) == TRUE) ? NDIS_OFFLOAD_SET_ON : NDIS_OFFLOAD_SET_OFF);\r
+       ULONG RxChksumOffload = ((MP_GET_PORT_CONFIG(pPort, RxChksumOffload) == TRUE) ? NDIS_OFFLOAD_SET_ON : NDIS_OFFLOAD_SET_OFF);\r
+       BOOLEAN fLargeSendOffload = MP_GET_PORT_CONFIG(pPort, LargeSendOffload);\r
+       ULONG ulEncapsulation = NDIS_ENCAPSULATION_IEEE_802_3 | NDIS_ENCAPSULATION_IEEE_802_3_P_AND_Q;\r
+           \r
+       NdisZeroMemory(&*p_offload, sizeof(NDIS_OFFLOAD));\r
+       *p_offload.Header.Type = NDIS_OBJECT_TYPE_OFFLOAD;\r
+       *p_offload.Header.Revision = NDIS_OFFLOAD_REVISION_1; // BUGBUG: do we need to support revision 2? UH 17-May-2008\r
+       *p_offload.Header.Size = NDIS_SIZEOF_NDIS_OFFLOAD_REVISION_1;\r
+\r
+       *p_offload.Checksum.IPv4Transmit.Encapsulation = ulEncapsulation;\r
+       *p_offload.Checksum.IPv4Transmit.IpOptionsSupported = TxChksumOffload;\r
+       *p_offload.Checksum.IPv4Transmit.TcpOptionsSupported = TxChksumOffload;\r
+       *p_offload.Checksum.IPv4Transmit.TcpChecksum = TxChksumOffload;\r
+       *p_offload.Checksum.IPv4Transmit.UdpChecksum = NDIS_OFFLOAD_NOT_SUPPORTED;\r
+       *p_offload.Checksum.IPv4Transmit.IpChecksum = TxChksumOffload;\r
+\r
+       *p_offload.Checksum.IPv4Receive.Encapsulation = ulEncapsulation;\r
+       *p_offload.Checksum.IPv4Receive.IpOptionsSupported = RxChksumOffload;\r
+       *p_offload.Checksum.IPv4Receive.TcpOptionsSupported = RxChksumOffload;\r
+       *p_offload.Checksum.IPv4Receive.TcpChecksum = RxChksumOffload;\r
+       *p_offload.Checksum.IPv4Receive.UdpChecksum = NDIS_OFFLOAD_NOT_SUPPORTED; \r
+       *p_offload.Checksum.IPv4Receive.IpChecksum = RxChksumOffload;\r
+\r
+       *p_offload.Checksum.IPv6Transmit.Encapsulation = ulEncapsulation;\r
+       *p_offload.Checksum.IPv6Transmit.IpExtensionHeadersSupported = TxChksumOffload;\r
+       *p_offload.Checksum.IPv6Transmit.TcpOptionsSupported = TxChksumOffload;\r
+       *p_offload.Checksum.IPv6Transmit.TcpChecksum = TxChksumOffload;\r
+       *p_offload.Checksum.IPv6Transmit.UdpChecksum = NDIS_OFFLOAD_NOT_SUPPORTED;\r
+\r
+\r
+       *p_offload.Checksum.IPv6Receive.Encapsulation = ulEncapsulation;\r
+       *p_offload.Checksum.IPv6Receive.IpExtensionHeadersSupported = RxChksumOffload;\r
+       *p_offload.Checksum.IPv6Receive.TcpOptionsSupported = RxChksumOffload;\r
+       *p_offload.Checksum.IPv6Receive.TcpChecksum = RxChksumOffload;\r
+       *p_offload.Checksum.IPv6Receive.UdpChecksum = NDIS_OFFLOAD_NOT_SUPPORTED;\r
+\r
+       if (fLargeSendOffload)\r
+       {\r
+           *p_offload.LsoV1.IPv4.Encapsulation = ulEncapsulation;\r
+           *p_offload.LsoV1.IPv4.MaxOffLoadSize = LARGE_SEND_OFFLOAD_SIZE;\r
+           *p_offload.LsoV1.IPv4.MinSegmentCount = 1;\r
+           *p_offload.LsoV1.IPv4.TcpOptions = NDIS_OFFLOAD_SUPPORTED;\r
+           *p_offload.LsoV1.IPv4.IpOptions = NDIS_OFFLOAD_SUPPORTED;\r
+       }\r
+}\r
+#endif\r
+\r
+//! Returns information about the capabilities and status of the driver and/or its NIC.\r
+/*  IRQL = DISPATCH_LEVEL\r
+\r
+@param adapter_context The adapter context allocated at start\r
+@param oid Object ID representing the query operation to be carried out\r
+@param info_buf Buffer containing any input for this query and location for output\r
+@param info_buf_len Number of bytes available in info_buf\r
+@param p_bytes_written Pointer to number of bytes written into info_buf\r
+@param p_bytes_needed Pointer to number of bytes needed to satisfy this oid\r
+@return NDIS_STATUS_SUCCESS, NDIS_STATUS_PENDING, NDIS_STATUS_INVALID_OID,\r
+NDIS_STATUS_INVALID_LENGTH, NDIS_STATUS_NOT_ACCEPTED, NDIS_STATUS_NOT_SUPPORTED,\r
+NDIS_STATUS_RESOURCES\r
+*/\r
+       NDIS_STATUS\r
+ipoib_query_info(\r
+       IN                              NDIS_HANDLE                                     adapter_context,\r
+       IN                              NDIS_OID                                        oid,\r
+       IN                              PVOID                                           info_buf,\r
+       IN                              ULONG                                           info_buf_len,\r
+               OUT                     PULONG                                          p_bytes_written,\r
+               OUT                     PULONG                                          p_bytes_needed )\r
+       {\r
+       ipoib_adapter_t         *p_adapter;\r
+               NDIS_STATUS             status;\r
+               USHORT                          version;\r
+       ULONG                           info;\r
+               PVOID                           src_buf;\r
+               ULONG                           buf_len;\r
+               pending_oid_t           oid_info;\r
+       uint8_t                         port_num;\r
+               \r
+               IPOIB_ENTER( IPOIB_DBG_OID );\r
+               \r
+               oid_info.oid = oid;\r
+               oid_info.p_buf = info_buf;\r
+               oid_info.buf_len = info_buf_len;\r
+               oid_info.p_bytes_used = p_bytes_written;\r
+               oid_info.p_bytes_needed = p_bytes_needed;\r
+               \r
+               CL_ASSERT( adapter_context );\r
+               p_adapter = (ipoib_adapter_t*)adapter_context;\r
+\r
+               CL_ASSERT( p_bytes_written );\r
+               CL_ASSERT( p_bytes_needed );\r
+               CL_ASSERT( !p_adapter->pending_query );\r
+               \r
+                       status = NDIS_STATUS_SUCCESS;\r
+                       src_buf = &info;\r
+               buf_len = sizeof(info);\r
+       \r
+               port_num = p_adapter->guids.port_num;\r
+       \r
+               switch( oid )\r
+               {\r
+               /* Required General */\r
+               case OID_GEN_SUPPORTED_LIST:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_GEN_SUPPORTED_LIST\n", port_num) );\r
+                       src_buf = (PVOID)SUPPORTED_OIDS;\r
+                       buf_len = sizeof(SUPPORTED_OIDS);\r
+                       break;\r
+       \r
+               case OID_GEN_HARDWARE_STATUS:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_GEN_HARDWARE_STATUS\n", port_num) );\r
+                       cl_obj_lock( &p_adapter->obj );\r
+                       switch( p_adapter->state )\r
+                       {\r
+                       case IB_PNP_PORT_ADD:\r
+                               IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                                       ("Port %d returning NdisHardwareStatusInitializing\n", port_num) );\r
+                               info = NdisHardwareStatusInitializing;\r
+                               break;\r
+                               \r
+                       case IB_PNP_PORT_ACTIVE:\r
+                               IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                                       ("Port %d returning NdisHardwareStatusReady\n", port_num) );\r
+                               info = NdisHardwareStatusReady;\r
+                               break;\r
+       \r
+                       default:\r
+                               IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                                       ("Port %d returning NdisHardwareStatusNotReady\n", port_num) );\r
+                               info = NdisHardwareStatusNotReady;\r
+                       }\r
+                       cl_obj_unlock( &p_adapter->obj );\r
+                       break;\r
+       \r
+               case OID_GEN_MEDIA_SUPPORTED:\r
+               case OID_GEN_MEDIA_IN_USE:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_GEN_MEDIA_SUPPORTED "\r
+                               "or OID_GEN_MEDIA_IN_USE\n", port_num) );\r
+                       info = NdisMedium802_3;\r
+                       break;\r
+       \r
+               case OID_GEN_MAXIMUM_FRAME_SIZE:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_GEN_MAXIMUM_FRAME_SIZE\n", port_num) );\r
+                       if( p_adapter->params.cm_enabled )\r
+                       {\r
+                               info = p_adapter->params.cm_payload_mtu;\r
+                       }\r
+                       else\r
+                       {\r
+                               info = p_adapter->params.payload_mtu;\r
+                       }\r
+                       break;\r
+       \r
+               case OID_GEN_LINK_SPEED:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_GEN_LINK_SPEED\n", port_num) );\r
+                       if (info_buf_len < buf_len)\r
+                       {\r
+                               break;\r
+                       }\r
+       \r
+                       cl_obj_lock( &p_adapter->obj );\r
+                       switch( p_adapter->state )\r
+                       {\r
+                       case IB_PNP_PORT_ADD:\r
+                               /* Mark the adapter as pending an OID */\r
+                               p_adapter->pending_query = TRUE;\r
+       \r
+                               /* Save the request parameters. */\r
+                               p_adapter->query_oid = oid_info;\r
+       \r
+                               IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                                       ("Port %d returning NDIS_STATUS_PENDING\n", port_num) );\r
+                               status = NDIS_STATUS_PENDING;\r
+                               break;\r
+       \r
+                       case IB_PNP_PORT_REMOVE:\r
+                               IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                                       ("Port %d returning NDIS_STATUS_NOT_ACCEPTED\n", port_num) );\r
+                               status = NDIS_STATUS_NOT_ACCEPTED;\r
+                               break;\r
+       \r
+                       default:\r
+                               CL_ASSERT( p_adapter->p_port );\r
+                               info = p_adapter->port_rate;\r
+                               break;\r
+                       }\r
+                       cl_obj_unlock( &p_adapter->obj );\r
+                       break;\r
+       \r
+               case OID_GEN_TRANSMIT_BUFFER_SPACE:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_GEN_TRANSMIT_BUFFER_SPACE\n", port_num) );\r
+                       if( p_adapter->params.cm_enabled )\r
+                               info = p_adapter->params.sq_depth * p_adapter->params.cm_xfer_block_size;\r
+                       else\r
+                               info = p_adapter->params.sq_depth * p_adapter->params.xfer_block_size;\r
+                       break;\r
+       \r
+               case OID_GEN_RECEIVE_BUFFER_SPACE:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_GEN_TRANSMIT_BUFFER_SPACE "\r
+                               "or OID_GEN_RECEIVE_BUFFER_SPACE\n", port_num) );\r
+                       if( p_adapter->params.cm_enabled )\r
+                               info = p_adapter->params.rq_depth * p_adapter->params.cm_xfer_block_size;\r
+                       else\r
+                               info = p_adapter->params.rq_depth * p_adapter->params.xfer_block_size;\r
+                       break;\r
+       \r
+               case OID_GEN_MAXIMUM_LOOKAHEAD:\r
+               case OID_GEN_CURRENT_LOOKAHEAD:\r
+               case OID_GEN_TRANSMIT_BLOCK_SIZE:\r
+               case OID_GEN_RECEIVE_BLOCK_SIZE:\r
+               case OID_GEN_MAXIMUM_TOTAL_SIZE:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_GEN_MAXIMUM_LOOKAHEAD "\r
+                               "or OID_GEN_CURRENT_LOOKAHEAD or "\r
+                               "OID_GEN_TRANSMIT_BLOCK_SIZE or "\r
+                               "OID_GEN_RECEIVE_BLOCK_SIZE or "\r
+                               "OID_GEN_MAXIMUM_TOTAL_SIZE\n", port_num) );\r
+                       if( p_adapter->params.cm_enabled )\r
+                               info = p_adapter->params.cm_xfer_block_size;\r
+                       else\r
+                               info = p_adapter->params.xfer_block_size;\r
+                       break;\r
+       \r
+               case OID_GEN_VENDOR_ID:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_GEN_VENDOR_ID\n", port_num) );\r
+                       src_buf = (void*)VENDOR_ID;\r
+               buf_len = sizeof(VENDOR_ID);\r
+                       break;\r
+       \r
+               case OID_GEN_VENDOR_DESCRIPTION:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID, \r
+                               ("Port %d received query for OID_GEN_VENDOR_DESCRIPTION\n", port_num) );\r
+                       src_buf = VENDOR_DESCRIPTION;\r
+               buf_len = sizeof(VENDOR_DESCRIPTION);\r
+                       break;\r
+       \r
+               case OID_GEN_VENDOR_DRIVER_VERSION:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_GEN_VENDOR_DRIVER_VERSION\n", port_num) );\r
+                       src_buf = &version;\r
+               buf_len = sizeof(version);\r
+                       //TODO: Figure out what the right version is.\r
+                       version = 1 << 8 | 1;\r
+                       break;\r
+       \r
+               case OID_GEN_PHYSICAL_MEDIUM:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_GEN_PHYSICAL_MEDIUM\n", port_num) );\r
+                       info = NdisPhysicalMediumUnspecified;\r
+                       break;\r
+       \r
+               case OID_GEN_CURRENT_PACKET_FILTER:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_GEN_CURRENT_PACKET_FILTER\n", port_num) );\r
+                       info = p_adapter->packet_filter;\r
+                       break;\r
+       \r
+               case OID_GEN_DRIVER_VERSION:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_GEN_DRIVER_VERSION\n", port_num) );\r
+                       src_buf = &version;\r
+               buf_len = sizeof(version);\r
+                       version = MAJOR_NDIS_VERSION << 8 | MINOR_NDIS_VERSION;\r
+                       break;\r
+       \r
+               case OID_GEN_MAC_OPTIONS:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_GEN_MAC_OPTIONS\n", port_num) );\r
+                       info = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |\r
+                               NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |\r
+                               NDIS_MAC_OPTION_NO_LOOPBACK |\r
+                               NDIS_MAC_OPTION_FULL_DUPLEX;\r
+       //TODO: Figure out if we will support priority and VLANs.\r
+       //                              NDIS_MAC_OPTION_8021P_PRIORITY;\r
+       //#ifdef NDIS51_MINIPORT\r
+       //                      info |= NDIS_MAC_OPTION_8021Q_VLAN;\r
+       //#endif\r
+                       break;\r
+       \r
+               case OID_GEN_MEDIA_CONNECT_STATUS:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_GEN_MEDIA_CONNECT_STATUS\n", port_num) );\r
+                       cl_obj_lock( &p_adapter->obj );\r
+                       switch( p_adapter->state )\r
+                       {\r
+                       case IB_PNP_PORT_ADD:\r
+                       case IB_PNP_PORT_INIT:\r
+                               /*\r
+                                * Delay reporting media state until we know whether the port is\r
+                                * either up or down.\r
+                                */\r
+                               p_adapter->pending_query = TRUE;\r
+                               p_adapter->query_oid = oid_info;\r
+       \r
+                               IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                                       ("Port %d returning NDIS_STATUS_PENDING\n", port_num) );\r
+                               status = NDIS_STATUS_PENDING;\r
+                               break;\r
+       \r
+                       case IB_PNP_PORT_ACTIVE:\r
+                               IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                                       ("Port %d returning NdisMediaStateConnected\n", port_num) );\r
+                               info = NdisMediaStateConnected;\r
+                               break;\r
+       \r
+                       case IB_PNP_PORT_REMOVE:\r
+                               IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                                       ("Port %d returning NDIS_STATUS_NOT_ACCEPTED\n", port_num) );\r
+                               status = NDIS_STATUS_NOT_ACCEPTED;\r
+                               break;\r
+       \r
+                       default:\r
+                               IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                                       ("Port %d returning NdisMediaStateDisconnected\n", port_num) );\r
+                               info = NdisMediaStateDisconnected;\r
+                       }\r
+                       cl_obj_unlock( &p_adapter->obj );\r
+                       break;\r
+       \r
+               case OID_GEN_MAXIMUM_SEND_PACKETS:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_GEN_MAXIMUM_SEND_PACKETS\n", port_num) );\r
+                       info = MINIPORT_MAX_SEND_PACKETS;\r
+                       break;\r
+       \r
+               /* Required General Statistics */\r
+               case OID_GEN_STATISTICS:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_GEN_STATISTICS\n", port_num) );\r
+                       src_buf = NULL;   \r
+                        buf_len =  sizeof(NDIS_STATISTICS_INFO);\r
+                       if (info_buf_len < buf_len)\r
+                       {\r
+                          break;\r
+                       } \r
+                       status = ipoib_get_gen_stat(p_adapter, &oid_info );\r
+                       break;\r
+       \r
+               case OID_GEN_XMIT_OK:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_GEN_XMIT_OK\n", port_num) );\r
+                       src_buf = NULL;\r
+                       status = ipoib_get_send_stat( p_adapter, IP_STAT_SUCCESS, &oid_info );\r
+                       break;\r
+       \r
+               case OID_GEN_RCV_OK:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_GEN_RCV_OK\n", port_num) );\r
+                       src_buf = NULL;\r
+                       status = ipoib_get_recv_stat( p_adapter, IP_STAT_SUCCESS, &oid_info );\r
+                       break;\r
+       \r
+               case OID_GEN_XMIT_ERROR:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_GEN_XMIT_ERROR\n", port_num) );\r
+                       src_buf = NULL;\r
+                       status = ipoib_get_send_stat( p_adapter, IP_STAT_ERROR, &oid_info );\r
+                       break;\r
+       \r
+               case OID_GEN_RCV_ERROR:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_GEN_RCV_ERROR\n", port_num) );\r
+                       src_buf = NULL;\r
+                       status = ipoib_get_recv_stat( p_adapter, IP_STAT_ERROR, &oid_info );\r
+                       break;\r
+       \r
+               case OID_GEN_RCV_NO_BUFFER:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_GEN_RCV_NO_BUFFER\n", port_num) );\r
+                       src_buf = NULL;\r
+                       status = ipoib_get_recv_stat( p_adapter, IP_STAT_DROPPED, &oid_info );\r
+                       break;\r
+       \r
+               case OID_GEN_DIRECTED_BYTES_XMIT:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_GEN_DIRECTED_BYTES_XMIT\n", port_num) );\r
+                       src_buf = NULL;\r
+                       status = ipoib_get_send_stat( p_adapter, IP_STAT_UCAST_BYTES, &oid_info );\r
+                       break;\r
+       \r
+               case OID_GEN_DIRECTED_FRAMES_XMIT:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_GEN_DIRECTED_FRAMES_XMIT\n", port_num) );\r
+                       src_buf = NULL;\r
+                       status = ipoib_get_send_stat( p_adapter, IP_STAT_UCAST_FRAMES, &oid_info );\r
+                       break;\r
+       \r
+               case OID_GEN_MULTICAST_BYTES_XMIT:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_GEN_MULTICAST_BYTES_XMIT\n", port_num) );\r
+                       src_buf = NULL;\r
+                       status = ipoib_get_send_stat( p_adapter, IP_STAT_MCAST_BYTES, &oid_info );\r
+                       break;\r
+       \r
+               case OID_GEN_MULTICAST_FRAMES_XMIT:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_GEN_MULTICAST_FRAMES_XMIT\n", port_num) );\r
+                       src_buf = NULL;\r
+                       status = ipoib_get_send_stat( p_adapter, IP_STAT_MCAST_FRAMES, &oid_info );\r
+                       break;\r
+       \r
+               case OID_GEN_BROADCAST_BYTES_XMIT:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_GEN_BROADCAST_BYTES_XMIT\n", port_num) );\r
+                       src_buf = NULL;\r
+                       status = ipoib_get_send_stat( p_adapter, IP_STAT_BCAST_BYTES, &oid_info );\r
+                       break;\r
+       \r
+               case OID_GEN_BROADCAST_FRAMES_XMIT:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_GEN_BROADCAST_FRAMES_XMIT\n", port_num) );\r
+                       src_buf = NULL;\r
+                       status = ipoib_get_send_stat( p_adapter, IP_STAT_BCAST_FRAMES, &oid_info );\r
+                       break;\r
+       \r
+               case OID_GEN_DIRECTED_BYTES_RCV:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_GEN_DIRECTED_BYTES_RCV\n", port_num) );\r
+                       src_buf = NULL;\r
+                       status = ipoib_get_recv_stat( p_adapter, IP_STAT_UCAST_BYTES, &oid_info );\r
+                       break;\r
+       \r
+               case OID_GEN_DIRECTED_FRAMES_RCV:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_GEN_DIRECTED_FRAMES_RCV\n", port_num) );\r
+                       src_buf = NULL;\r
+                       status = ipoib_get_recv_stat( p_adapter, IP_STAT_UCAST_FRAMES, &oid_info );\r
+                       break;\r
+       \r
+               case OID_GEN_MULTICAST_BYTES_RCV:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_GEN_MULTICAST_BYTES_RCV\n", port_num) );\r
+                       src_buf = NULL;\r
+                       status = ipoib_get_recv_stat( p_adapter, IP_STAT_MCAST_BYTES, &oid_info );\r
+                       break;\r
+       \r
+               case OID_GEN_MULTICAST_FRAMES_RCV:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_GEN_MULTICAST_FRAMES_RCV\n", port_num) );\r
+                       src_buf = NULL;\r
+                       status = ipoib_get_recv_stat( p_adapter, IP_STAT_MCAST_FRAMES, &oid_info );\r
+                       break;\r
+       \r
+               case OID_GEN_BROADCAST_BYTES_RCV:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_GEN_BROADCAST_BYTES_RCV\n", port_num) );\r
+                       src_buf = NULL;\r
+                       status = ipoib_get_recv_stat( p_adapter, IP_STAT_BCAST_BYTES, &oid_info );\r
+                       break;\r
+       \r
+               case OID_GEN_BROADCAST_FRAMES_RCV:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_GEN_BROADCAST_FRAMES_RCV\n", port_num) );\r
+                       src_buf = NULL;\r
+                       status = ipoib_get_recv_stat( p_adapter, IP_STAT_BCAST_FRAMES, &oid_info );\r
+                       break;\r
+       \r
+               /* Required Ethernet operational characteristics */\r
+               case OID_802_3_PERMANENT_ADDRESS:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_802_3_PERMANENT_ADDRESS\n", port_num) );\r
+                       src_buf = &p_adapter->mac;\r
+               buf_len = sizeof(p_adapter->mac);\r
+                       break;\r
+       \r
+               case OID_802_3_CURRENT_ADDRESS:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_802_3_CURRENT_ADDRESS\n", port_num) );\r
+                       src_buf = &p_adapter->params.conf_mac;\r
+               buf_len = sizeof(p_adapter->params.conf_mac);\r
+                       break;\r
+       \r
+               case OID_802_3_MULTICAST_LIST:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_802_3_MULTICAST_LIST\n", port_num) );\r
+                       src_buf = p_adapter->mcast_array;\r
+               buf_len = p_adapter->mcast_array_size * sizeof(mac_addr_t);\r
+                       break;\r
+       \r
+               case OID_802_3_MAXIMUM_LIST_SIZE:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_802_3_MAXIMUM_LIST_SIZE\n", port_num) );\r
+                       info = MAX_MCAST;\r
+                       break;\r
+       \r
+               case OID_802_3_MAC_OPTIONS:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_802_3_MAC_OPTIONS\n", port_num) );\r
+                       info = 0;\r
+                       break;\r
+       \r
+               /* Required Ethernet stats */\r
+               case OID_802_3_RCV_ERROR_ALIGNMENT:\r
+               case OID_802_3_XMIT_ONE_COLLISION:\r
+               case OID_802_3_XMIT_MORE_COLLISIONS:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_802_3_RCV_ERROR_ALIGNMENT or "\r
+                               "OID_802_3_XMIT_ONE_COLLISION or "\r
+                               "OID_802_3_XMIT_MORE_COLLISIONS\n", port_num) );\r
+                       info = 0;\r
+                       break;\r
+       \r
+               case OID_TCP_TASK_OFFLOAD:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_TCP_TASK_OFFLOAD\n", port_num) );\r
+                       src_buf = NULL;\r
+                       status = __ipoib_get_tcp_task_offload( p_adapter, &oid_info );\r
+                       break;\r
+       \r
+               /* Optional General */\r
+               case OID_GEN_SUPPORTED_GUIDS:\r
+#ifdef NDIS51_MINIPORT\r
+               case OID_GEN_VLAN_ID:\r
+#endif\r
+       \r
+               /* Optional General Stats */\r
+               case OID_GEN_RCV_CRC_ERROR:\r
+               case OID_GEN_TRANSMIT_QUEUE_LENGTH:\r
+       \r
+               /* Optional Ethernet Stats */\r
+               case OID_802_3_XMIT_DEFERRED:\r
+               case OID_802_3_XMIT_MAX_COLLISIONS:\r
+               case OID_802_3_RCV_OVERRUN:\r
+               case OID_802_3_XMIT_UNDERRUN:\r
+               case OID_802_3_XMIT_HEARTBEAT_FAILURE:\r
+               case OID_802_3_XMIT_TIMES_CRS_LOST:\r
+               case OID_802_3_XMIT_LATE_COLLISIONS:\r
+               case OID_PNP_CAPABILITIES:\r
+                       status = NDIS_STATUS_NOT_SUPPORTED;\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received an unsupported oid of 0x%.8X!\n", port_num, oid) );\r
+                       break;\r
+       \r
+               case OID_GEN_PROTOCOL_OPTIONS:\r
+               case OID_GEN_NETWORK_LAYER_ADDRESSES:\r
+               case OID_GEN_TRANSPORT_HEADER_OFFSET:\r
+               case OID_PNP_ENABLE_WAKE_UP:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_GEN_PROTOCOL_OPTIONS or OID_GEN_NETWORK_LAYER_ADDRESSES or OID_GEN_TRANSPORT_HEADER_OFFSET  OID_PNP_ENABLE_WAKE_UPn", port_num) );\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Number of OID: 0x%.8X!\n", oid) );\r
+                       status = NDIS_STATUS_SUCCESS; \r
+                       break;\r
+                       \r
+               case OID_PNP_QUERY_POWER:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_TCP_TASK_OFFLOAD\n", port_num) );\r
+                       // Status is pre-set in this routine to Success\r
+                       status = NDIS_STATUS_SUCCESS; \r
+                       break;\r
+       \r
+               case OID_TCP_OFFLOAD_CURRENT_CONFIG:\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d received query for OID_PNP_QUERY_POWER\n", port_num) );\r
+                               //ulBytesAvailable = ulInfoLen = sizeof(NDIS_OFFLOAD);\r
+                               if (info_buf_len <  sizeof(NDIS_OFFLOAD))\r
+                               {\r
+                                       status = NDIS_STATUS_BUFFER_TOO_SHORT;\r
+                                       *p_bytes_needed = sizeof(NDIS_OFFLOAD) ;\r
+                                       break;\r
+                               }\r
+       \r
+                               //ipoib_offload_config(pPort, &offload);\r
+                               //pInfo = &offload;\r
+                               break;\r
+       \r
+               default:\r
+                       status = NDIS_STATUS_INVALID_OID;\r
+               //      IPOIB_PRINT( TRACE_LEVEL_ERROR,IPOIB_DBG_OID,\r
+                       //      ("Port %d received an invalid oid of 0x%.8X!\n", port_num, oid) );\r
+                       break;\r
+               }\r
+       \r
+               /*\r
+                * Complete the request as if it was handled asynchronously to maximize\r
+                * code reuse for when we really handle the requests asynchronously.\r
+                * Note that this requires the QueryInformation entry point to always\r
+                * return NDIS_STATUS_PENDING\r
+                */\r
+               if( status != NDIS_STATUS_PENDING )\r
+               {\r
+                       ipoib_complete_query(\r
+                               p_adapter, &oid_info, status, src_buf, buf_len );\r
+                       return status;\r
+               }\r
+       \r
+               IPOIB_EXIT( IPOIB_DBG_OID );\r
+               return NDIS_STATUS_PENDING;\r
+       }\r
+       \r
+\r
+static void\r
+ipoib_complete_query(\r
+       IN                              ipoib_adapter_t* const          p_adapter,\r
+       IN                              pending_oid_t* const            p_oid_info,\r
+       IN              const   NDIS_STATUS                                     status,\r
+       IN              const   void* const                                     p_buf,\r
+       IN              const   ULONG                                           buf_len )\r
+{\r
+       NDIS_STATUS             oid_status = status;\r
+\r
+       IPOIB_ENTER( IPOIB_DBG_OID );\r
+\r
+       CL_ASSERT( status != NDIS_STATUS_PENDING );\r
+\r
+       if( status == NDIS_STATUS_SUCCESS )\r
+       {\r
+               if( p_oid_info->buf_len < buf_len )\r
+               {\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Insufficient buffer space.  "\r
+                               "Returning NDIS_STATUS_INVALID_LENGTH.\n") );\r
+                       oid_status = NDIS_STATUS_INVALID_LENGTH;\r
+                       *p_oid_info->p_bytes_needed = buf_len;\r
+                       *p_oid_info->p_bytes_used = 0;\r
+               }\r
+               else if( p_oid_info->p_buf )\r
+               {\r
+                       /* Only copy if we have a distinct source buffer. */\r
+                       if( p_buf )\r
+                       {\r
+                               NdisMoveMemory( p_oid_info->p_buf, p_buf, buf_len );\r
+                               *p_oid_info->p_bytes_used = buf_len;\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Returning NDIS_NOT_ACCEPTED") );\r
+                       oid_status = NDIS_STATUS_NOT_ACCEPTED;\r
+               }\r
+       }\r
+       else\r
+       {\r
+               *p_oid_info->p_bytes_used = 0;\r
+       }\r
+\r
+       if (p_adapter->query_oid.p_pending_oid)\r
+       {\r
+               NdisMOidRequestComplete(p_adapter->h_adapter,p_adapter->query_oid.p_pending_oid,oid_status); \r
+               p_adapter->query_oid.p_pending_oid = NULL;\r
+       }\r
+       p_adapter->pending_query = FALSE;\r
+\r
+       IPOIB_EXIT( IPOIB_DBG_OID );\r
+}\r
+\r
+\r
+static NDIS_STATUS\r
+__ipoib_get_tcp_task_offload(\r
+       IN                              ipoib_adapter_t*                        p_adapter,\r
+       OUT                             pending_oid_t                           *pNdisRequest )\r
+{\r
+#ifndef NDIS60_MINIPORT\r
+       NDIS_TASK_OFFLOAD_HEADER        *p_offload_hdr;\r
+       NDIS_TASK_OFFLOAD                       *p_offload_task;\r
+       NDIS_TASK_TCP_IP_CHECKSUM       *p_offload_chksum;\r
+\r
+       NDIS_TASK_TCP_LARGE_SEND        *p_offload_lso;\r
+       ULONG                                           buf_len;\r
+\r
+       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+               ("Port %d received query for OID_TCP_TASK_OFFLOAD\n",\r
+               p_adapter->guids.port_num) );\r
+\r
+       buf_len = sizeof(NDIS_TASK_OFFLOAD_HEADER) +\r
+               offsetof( NDIS_TASK_OFFLOAD, TaskBuffer ) +\r
+               sizeof(NDIS_TASK_TCP_IP_CHECKSUM) +\r
+               (p_adapter->params.lso  ? \r
+                       sizeof(NDIS_TASK_OFFLOAD) + sizeof(NDIS_TASK_TCP_LARGE_SEND)\r
+                       : 0);\r
+\r
+       pNdisRequest->DATA.QUERY_INFORMATION.BytesNeeded = buf_len;\r
+\r
+       if( pNdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength < buf_len )\r
+               return NDIS_STATUS_INVALID_LENGTH;\r
+\r
+       p_offload_hdr = (NDIS_TASK_OFFLOAD_HEADER*)pNdisRequest->DATA.QUERY_INFORMATION.InformationBuffer;\r
+       if( p_offload_hdr->Version != NDIS_TASK_OFFLOAD_VERSION )\r
+               return NDIS_STATUS_INVALID_DATA;\r
+\r
+       if( p_offload_hdr->EncapsulationFormat.Encapsulation !=\r
+               IEEE_802_3_Encapsulation )\r
+       {\r
+               return NDIS_STATUS_INVALID_DATA;\r
+       }\r
+\r
+       p_offload_hdr->OffsetFirstTask = sizeof(NDIS_TASK_OFFLOAD_HEADER);\r
+       p_offload_task = (NDIS_TASK_OFFLOAD*)(p_offload_hdr + 1);\r
+       p_offload_task->Version = NDIS_TASK_OFFLOAD_VERSION;\r
+       p_offload_task->Size = sizeof(NDIS_TASK_OFFLOAD);\r
+       p_offload_task->Task = TcpIpChecksumNdisTask;\r
+       p_offload_task->OffsetNextTask = 0;\r
+       p_offload_task->TaskBufferLength = sizeof(NDIS_TASK_TCP_IP_CHECKSUM);\r
+       p_offload_chksum =\r
+               (NDIS_TASK_TCP_IP_CHECKSUM*)p_offload_task->TaskBuffer;\r
+       \r
+       p_offload_chksum->V4Transmit.IpOptionsSupported =\r
+       p_offload_chksum->V4Transmit.TcpOptionsSupported =\r
+       p_offload_chksum->V4Transmit.TcpChecksum =\r
+       p_offload_chksum->V4Transmit.UdpChecksum =\r
+       p_offload_chksum->V4Transmit.IpChecksum =\r
+               !!(p_adapter->params.send_chksum_offload);\r
+\r
+       p_offload_chksum->V4Receive.IpOptionsSupported =\r
+       p_offload_chksum->V4Receive.TcpOptionsSupported =\r
+       p_offload_chksum->V4Receive.TcpChecksum =\r
+       p_offload_chksum->V4Receive.UdpChecksum =\r
+       p_offload_chksum->V4Receive.IpChecksum =\r
+               !!(p_adapter->params.recv_chksum_offload);\r
+\r
+       p_offload_chksum->V6Transmit.IpOptionsSupported = FALSE;\r
+       p_offload_chksum->V6Transmit.TcpOptionsSupported = FALSE;\r
+       p_offload_chksum->V6Transmit.TcpChecksum = FALSE;\r
+       p_offload_chksum->V6Transmit.UdpChecksum = FALSE;\r
+\r
+       p_offload_chksum->V6Receive.IpOptionsSupported = FALSE;\r
+       p_offload_chksum->V6Receive.TcpOptionsSupported = FALSE;\r
+       p_offload_chksum->V6Receive.TcpChecksum = FALSE;\r
+       p_offload_chksum->V6Receive.UdpChecksum = FALSE;\r
+\r
+\r
+       if (p_adapter->params.lso) {\r
+               // set the previous pointer to the correct place\r
+               p_offload_task->OffsetNextTask = FIELD_OFFSET(NDIS_TASK_OFFLOAD, TaskBuffer) +\r
+                                               p_offload_task->TaskBufferLength;\r
+               // set the LSO packet\r
+               p_offload_task = (PNDIS_TASK_OFFLOAD)\r
+                                               ((PUCHAR)p_offload_task + p_offload_task->OffsetNextTask);\r
+\r
+               p_offload_task->Version = NDIS_TASK_OFFLOAD_VERSION;\r
+               p_offload_task->Size = sizeof(NDIS_TASK_OFFLOAD);\r
+               p_offload_task->Task = TcpLargeSendNdisTask;\r
+               p_offload_task->OffsetNextTask = 0;\r
+               p_offload_task->TaskBufferLength = sizeof(NDIS_TASK_TCP_LARGE_SEND);\r
+\r
+               p_offload_lso = (PNDIS_TASK_TCP_LARGE_SEND) p_offload_task->TaskBuffer;\r
+\r
+               p_offload_lso->Version = 0;\r
+               //TODO optimal size: 60000, 64000 or 65536\r
+               //TODO LSO_MIN_SEG_COUNT to be 1\r
+               p_offload_lso->MaxOffLoadSize = LARGE_SEND_OFFLOAD_SIZE; \r
+#define LSO_MIN_SEG_COUNT 2\r
+               p_offload_lso->MinSegmentCount = LSO_MIN_SEG_COUNT;\r
+               p_offload_lso->TcpOptions = TRUE;\r
+               p_offload_lso->IpOptions = TRUE;\r
+       }\r
+\r
+               pNdisRequest->DATA.QUERY_INFORMATION.BytesWritten = buf_len\r
+\r
+       return NDIS_STATUS_SUCCESS;\r
+#endif\r
+       UNUSED_PARAM(p_adapter);\r
+       UNUSED_PARAM(pNdisRequest);\r
+       return NDIS_STATUS_NOT_SUPPORTED;\r
+\r
+}\r
+\r
+\r
+static NDIS_STATUS\r
+__ipoib_set_tcp_task_offload(\r
+       IN                              ipoib_adapter_t*                        p_adapter,\r
+       IN                              void* const                                     p_info_buf,\r
+       IN                              ULONG* const                            p_info_len )\r
+{\r
+#ifndef NDIS60_MINIPORT\r
+       NDIS_TASK_OFFLOAD_HEADER        *p_offload_hdr;\r
+       NDIS_TASK_OFFLOAD                       *p_offload_task;\r
+       NDIS_TASK_TCP_IP_CHECKSUM       *p_offload_chksum;\r
+\r
+       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+               ("Port %d received set for OID_TCP_TASK_OFFLOAD\n",\r
+               p_adapter->guids.port_num) );\r
+\r
+       p_offload_hdr = (NDIS_TASK_OFFLOAD_HEADER*)p_info_buf;\r
+\r
+       if( *p_info_len < sizeof(NDIS_TASK_OFFLOAD_HEADER) )\r
+               return NDIS_STATUS_INVALID_LENGTH;\r
+\r
+       if( p_offload_hdr->Version != NDIS_TASK_OFFLOAD_VERSION )\r
+               return NDIS_STATUS_INVALID_DATA;\r
+\r
+       if( p_offload_hdr->Size != sizeof(NDIS_TASK_OFFLOAD_HEADER) )\r
+               return NDIS_STATUS_INVALID_LENGTH;\r
+\r
+       if( !p_offload_hdr->OffsetFirstTask )\r
+               return NDIS_STATUS_SUCCESS;\r
+\r
+       if( p_offload_hdr->EncapsulationFormat.Encapsulation !=\r
+               IEEE_802_3_Encapsulation )\r
+       {\r
+               return NDIS_STATUS_INVALID_DATA;\r
+       }\r
+\r
+       p_offload_task = (NDIS_TASK_OFFLOAD*)\r
+               (((UCHAR*)p_offload_hdr) + p_offload_hdr->OffsetFirstTask);\r
+\r
+       if( *p_info_len < sizeof(NDIS_TASK_OFFLOAD_HEADER) +\r
+               offsetof( NDIS_TASK_OFFLOAD, TaskBuffer ) +\r
+               sizeof(NDIS_TASK_TCP_IP_CHECKSUM) )\r
+       {\r
+               return NDIS_STATUS_INVALID_LENGTH;\r
+       }\r
+\r
+       if( p_offload_task->Version != NDIS_TASK_OFFLOAD_VERSION )\r
+               return NDIS_STATUS_INVALID_DATA;\r
+       p_offload_chksum =\r
+               (NDIS_TASK_TCP_IP_CHECKSUM*)p_offload_task->TaskBuffer;\r
+\r
+       if( !p_adapter->params.send_chksum_offload &&\r
+               (p_offload_chksum->V4Transmit.IpOptionsSupported ||\r
+               p_offload_chksum->V4Transmit.TcpOptionsSupported ||\r
+               p_offload_chksum->V4Transmit.TcpChecksum ||\r
+               p_offload_chksum->V4Transmit.UdpChecksum ||\r
+               p_offload_chksum->V4Transmit.IpChecksum) )\r
+       {\r
+               return NDIS_STATUS_NOT_SUPPORTED;\r
+       }\r
+\r
+       if( !p_adapter->params.recv_chksum_offload &&\r
+               (p_offload_chksum->V4Receive.IpOptionsSupported ||\r
+               p_offload_chksum->V4Receive.TcpOptionsSupported ||\r
+               p_offload_chksum->V4Receive.TcpChecksum ||\r
+               p_offload_chksum->V4Receive.UdpChecksum ||\r
+               p_offload_chksum->V4Receive.IpChecksum) )\r
+       {\r
+               return NDIS_STATUS_NOT_SUPPORTED;\r
+       }\r
+\r
+       return NDIS_STATUS_SUCCESS;\r
+#endif \r
+       UNUSED_PARAM(p_adapter);\r
+       UNUSED_PARAM(p_info_buf);\r
+       UNUSED_PARAM(p_info_len);\r
+       return NDIS_STATUS_NOT_SUPPORTED;\r
+}\r
+\r
+\r
+//! Issues a hardware reset to the NIC and/or resets the driver's software state.\r
+/*  Tear down the connection and start over again.  This is only called when there is a problem.\r
+For example, if a send, query info, or set info had a time out.  MiniportCheckForHang will\r
+be called first.\r
+IRQL = DISPATCH_LEVEL\r
+\r
+@param p_addr_resetPointer to BOOLLEAN that is set to TRUE if the NDIS\r
+library should call MiniportSetInformation to restore addressing information to the current values.\r
+@param adapter_context The adapter context allocated at start\r
+@return NDIS_STATUS_SUCCESS, NDIS_STATUS_PENDING, NDIS_STATUS_NOT_RESETTABLE,\r
+NDIS_STATUS_RESET_IN_PROGRESS, NDIS_STATUS_SOFT_ERRORS, NDIS_STATUS_HARD_ERRORS\r
+*/\r
+NDIS_STATUS\r
+ipoib_reset(\r
+    IN  NDIS_HANDLE     adapter_context,\r
+    OUT PBOOLEAN        p_addr_reset)\r
+{\r
+       ipoib_adapter_t* p_adapter;\r
+\r
+       IPOIB_ENTER( IPOIB_DBG_INIT );\r
+\r
+       CL_ASSERT( p_addr_reset );\r
+       CL_ASSERT( adapter_context );\r
+       p_adapter = (ipoib_adapter_t*)adapter_context;\r
+\r
+       switch( ipoib_reset_adapter( p_adapter ) )\r
+       {\r
+       case IB_NOT_DONE:\r
+               IPOIB_EXIT( IPOIB_DBG_INIT );\r
+               return NDIS_STATUS_PENDING;\r
+\r
+       case IB_SUCCESS:\r
+               IPOIB_EXIT( IPOIB_DBG_INIT );\r
+               *p_addr_reset = TRUE;\r
+               return NDIS_STATUS_SUCCESS;\r
+\r
+       case IB_INVALID_STATE:\r
+               IPOIB_EXIT( IPOIB_DBG_INIT );\r
+               return NDIS_STATUS_RESET_IN_PROGRESS;\r
+\r
+       default:\r
+               IPOIB_EXIT( IPOIB_DBG_INIT );\r
+               return NDIS_STATUS_HARD_ERRORS;\r
+       }\r
+}\r
+\r
+\r
+//! Request changes in the state information that the miniport driver maintains\r
+/*  For example, this is used to set multicast addresses and the packet filter.\r
+IRQL = DISPATCH_LEVEL\r
+\r
+@param adapter_context The adapter context allocated at start\r
+@param oid Object ID representing the set operation to be carried out\r
+@param info_buf Buffer containing input for this set and location for any output\r
+@param info_buf_len Number of bytes available in info_buf\r
+@param p_bytes_read Pointer to number of bytes read from info_buf\r
+@param p_bytes_needed Pointer to number of bytes needed to satisfy this oid\r
+@return NDIS_STATUS_SUCCESS, NDIS_STATUS_PENDING, NDIS_STATUS_INVALID_OID,\r
+NDIS_STATUS_INVALID_LENGTH, NDIS_STATUS_INVALID_DATA, NDIS_STATUS_NOT_ACCEPTED,\r
+NDIS_STATUS_NOT_SUPPORTED, NDIS_STATUS_RESOURCES\r
+*/\r
+NDIS_STATUS\r
+ipoib_set_info(\r
+       IN                              NDIS_HANDLE                                     adapter_context,\r
+       IN                              NDIS_OID                                        oid,\r
+       IN                              PVOID                                           info_buf,\r
+       IN                              ULONG                                           info_buf_len,\r
+               OUT                     PULONG                                          p_bytes_read,\r
+               OUT                     PULONG                                          p_bytes_needed )\r
+{\r
+       ipoib_adapter_t*        p_adapter;\r
+       NDIS_STATUS                     status;\r
+\r
+       ULONG                           buf_len;\r
+       uint8_t                         port_num;\r
+\r
+       KLOCK_QUEUE_HANDLE      hdl;\r
+       \r
+       IPOIB_ENTER( IPOIB_DBG_OID );\r
+\r
+       CL_ASSERT( adapter_context );\r
+       p_adapter = (ipoib_adapter_t*)adapter_context;\r
+\r
+       CL_ASSERT( p_bytes_read );\r
+       CL_ASSERT( p_bytes_needed );\r
+       CL_ASSERT( !p_adapter->pending_set );\r
+\r
+       status = NDIS_STATUS_SUCCESS;\r
+       *p_bytes_needed = 0;\r
+       buf_len = sizeof(ULONG);\r
+\r
+       port_num = p_adapter->guids.port_num;\r
+       \r
+       cl_obj_lock( &p_adapter->obj );\r
+\r
+       if( p_adapter->state == IB_PNP_PORT_REMOVE )\r
+       {\r
+               *p_bytes_read = 0;\r
+               cl_obj_unlock( &p_adapter->obj );\r
+               return NDIS_STATUS_NOT_ACCEPTED;\r
+       }\r
+\r
+       cl_obj_unlock( &p_adapter->obj );\r
+\r
+       switch( oid )\r
+       {\r
+       /* Required General */\r
+       case OID_GEN_CURRENT_PACKET_FILTER:\r
+               IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                       ("Port %d received set for OID_GEN_CURRENT_PACKET_FILTER\n", port_num));\r
+               if( info_buf_len < sizeof(p_adapter->packet_filter) )\r
+               {\r
+                       status = NDIS_STATUS_INVALID_LENGTH;\r
+               }\r
+               else if( !info_buf )\r
+               {\r
+                       status = NDIS_STATUS_INVALID_DATA;\r
+               }\r
+               else\r
+               {\r
+                       KeAcquireInStackQueuedSpinLock( &g_ipoib.lock, &hdl );\r
+                       cl_obj_lock( &p_adapter->obj );\r
+                       switch( p_adapter->state )\r
+                       {\r
+                       case IB_PNP_PORT_ADD:\r
+                               p_adapter->set_oid.oid = oid;\r
+                               p_adapter->set_oid.p_buf = info_buf;\r
+                               p_adapter->set_oid.buf_len = info_buf_len;\r
+                               p_adapter->set_oid.p_bytes_used = p_bytes_read;\r
+                               p_adapter->set_oid.p_bytes_needed = p_bytes_needed;\r
+                               p_adapter->pending_set = TRUE;\r
+                               status = NDIS_STATUS_PENDING;\r
+                               break;\r
+\r
+                       case IB_PNP_PORT_REMOVE:\r
+                               status = NDIS_STATUS_NOT_ACCEPTED;\r
+                               break;\r
+\r
+                       default:\r
+                               if( !p_adapter->packet_filter && (*(uint32_t*)info_buf) )\r
+                               {\r
+                                       cl_qlist_insert_tail(\r
+                                               &g_ipoib.adapter_list, &p_adapter->entry );\r
+\r
+                                       /*\r
+                                        * Filter was zero, now non-zero.  Register IP addresses\r
+                                        * with SA.\r
+                                        */\r
+                                       ipoib_reg_addrs( p_adapter );\r
+                               }\r
+                               else if( p_adapter->packet_filter && !(*(uint32_t*)info_buf) )\r
+                               {\r
+                                       /*\r
+                                        * Filter was non-zero, now zero.  Deregister IP addresses.\r
+                                        */\r
+                                       ipoib_dereg_addrs( p_adapter );\r
+\r
+                                       ASSERT( cl_qlist_count( &g_ipoib.adapter_list ) );\r
+                                       cl_qlist_remove_item(\r
+                                               &g_ipoib.adapter_list, &p_adapter->entry );\r
+                               }\r
+\r
+                               p_adapter->packet_filter = *(uint32_t*)info_buf;\r
+                       }\r
+                       cl_obj_unlock( &p_adapter->obj );\r
+                       KeReleaseInStackQueuedSpinLock( &hdl );\r
+               }\r
+               break;\r
+\r
+       case OID_GEN_CURRENT_LOOKAHEAD:\r
+               IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                       ("Port %d received set for OID_GEN_CURRENT_LOOKAHEAD\n", port_num));\r
+               if( info_buf_len < buf_len )\r
+                       status = NDIS_STATUS_INVALID_LENGTH;\r
+               break;\r
+\r
+       case OID_GEN_PROTOCOL_OPTIONS:\r
+               IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                       ("Port %d received set for OID_GEN_PROTOCOL_OPTIONS\n", port_num));\r
+               if( info_buf_len < buf_len )\r
+                       status = NDIS_STATUS_INVALID_LENGTH;\r
+               break;\r
+\r
+       case OID_GEN_NETWORK_LAYER_ADDRESSES:\r
+               status = __ipoib_set_net_addr( p_adapter, info_buf, info_buf_len, p_bytes_read, p_bytes_needed);\r
+               break;\r
+\r
+#ifdef NDIS51_MINIPORT\r
+       case OID_GEN_MACHINE_NAME:\r
+               IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_OID,\r
+                       ("Port %d received set for OID_GEN_MACHINE_NAME\n", port_num) );\r
+               break;\r
+#endif\r
+\r
+       /* Required Ethernet operational characteristics */\r
+       case OID_802_3_MULTICAST_LIST:\r
+               IPOIB_PRINT(TRACE_LEVEL_INFORMATION, IPOIB_DBG_OID,\r
+                       ("Port %d received set for OID_802_3_MULTICAST_LIST\n", port_num) );\r
+               if( info_buf_len > MAX_MCAST * sizeof(mac_addr_t) )\r
+               {\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d OID_802_3_MULTICAST_LIST - Multicast list full.\n", port_num) );\r
+                       status = NDIS_STATUS_MULTICAST_FULL;\r
+                       *p_bytes_needed = MAX_MCAST * sizeof(mac_addr_t);\r
+               }\r
+               else if( info_buf_len % sizeof(mac_addr_t) )\r
+               {\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d OID_802_3_MULTICAST_LIST - Invalid input buffer.\n", port_num) );\r
+                       status = NDIS_STATUS_INVALID_DATA;\r
+               }\r
+               else if( !info_buf && info_buf_len )\r
+               {\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d OID_802_3_MULTICAST_LIST - Invalid input buffer.\n", port_num) );\r
+                       status = NDIS_STATUS_INVALID_DATA;\r
+               }\r
+               else\r
+               {\r
+                       ipoib_refresh_mcast( p_adapter, (mac_addr_t*)info_buf,\r
+                               (uint8_t)(info_buf_len / sizeof(mac_addr_t)) );\r
+\r
+                       buf_len = info_buf_len;\r
+                       /*\r
+                        * Note that we don't return pending.  It will likely take longer\r
+                        * for our SA transactions to complete than NDIS will give us\r
+                        * before reseting the adapter.  If an SA failure is encountered,\r
+                        * the adapter will be marked as hung and we will get reset.\r
+                        */\r
+                       status = NDIS_STATUS_SUCCESS;\r
+               }\r
+               break;\r
+\r
+       case OID_TCP_TASK_OFFLOAD:\r
+               IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                       ("Port %d received set for OID_TCP_TASK_OFFLOAD\n", port_num) );\r
+\r
+               buf_len = info_buf_len;\r
+               status =\r
+                       __ipoib_set_tcp_task_offload( p_adapter, info_buf, &buf_len );\r
+               break;\r
+\r
+       /* Optional General */\r
+       case OID_GEN_TRANSPORT_HEADER_OFFSET:\r
+#ifdef NDIS51_MINIPORT\r
+       case OID_GEN_RNDIS_CONFIG_PARAMETER:\r
+       case OID_GEN_VLAN_ID:\r
+#endif\r
+               status = NDIS_STATUS_NOT_SUPPORTED;\r
+               IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                       ("Port %d received an unsupported oid of 0x%.8X!\n", port_num, oid));\r
+               break;\r
+\r
+       case OID_GEN_SUPPORTED_LIST:\r
+       case OID_GEN_HARDWARE_STATUS:\r
+       case OID_GEN_MEDIA_SUPPORTED:\r
+       case OID_GEN_MEDIA_IN_USE:\r
+       case OID_GEN_MAXIMUM_FRAME_SIZE:\r
+       case OID_GEN_LINK_SPEED:\r
+       case OID_GEN_TRANSMIT_BUFFER_SPACE:\r
+       case OID_GEN_RECEIVE_BUFFER_SPACE:\r
+       case OID_GEN_MAXIMUM_LOOKAHEAD:\r
+       case OID_GEN_TRANSMIT_BLOCK_SIZE:\r
+       case OID_GEN_RECEIVE_BLOCK_SIZE:\r
+       case OID_GEN_MAXIMUM_TOTAL_SIZE:\r
+       case OID_GEN_VENDOR_ID:\r
+       case OID_GEN_VENDOR_DESCRIPTION:\r
+       case OID_GEN_VENDOR_DRIVER_VERSION:\r
+       case OID_GEN_DRIVER_VERSION:\r
+       case OID_GEN_MAC_OPTIONS:\r
+       case OID_GEN_MEDIA_CONNECT_STATUS:\r
+       case OID_GEN_MAXIMUM_SEND_PACKETS:\r
+       case OID_GEN_SUPPORTED_GUIDS:\r
+       case OID_GEN_PHYSICAL_MEDIUM:\r
+       default:\r
+               status = NDIS_STATUS_INVALID_OID;\r
+               IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                       ("Port %d received an invalid oid of 0x%.8X!\n", port_num, oid));\r
+               break;\r
+       }\r
+\r
+       if( status == NDIS_STATUS_SUCCESS )\r
+       {\r
+               *p_bytes_read = buf_len;\r
+       }\r
+       else\r
+       {\r
+               if( status == NDIS_STATUS_INVALID_LENGTH )\r
+               {\r
+                       if ( !*p_bytes_needed )\r
+                       {\r
+                               *p_bytes_needed = buf_len;\r
+                       }\r
+               }\r
+\r
+               *p_bytes_read = 0;\r
+       }\r
+\r
+       IPOIB_EXIT( IPOIB_DBG_OID );\r
+       return status;\r
+}\r
+\r
+#ifdef NNN\r
+NDIS_STATUS\r
+ipoib_set_info(\r
+       ipoib_adapter_t*           p_adapter,\r
+       IN PNDIS_OID_REQUEST   pNdisRequest)\r
+{\r
+       NDIS_STATUS                     status;\r
+       NDIS_OID            oid;\r
+       UINT                            info_buf_len;\r
+       UINT                            buf_len;\r
+       uint8_t                         port_num;\r
+       PVOID                           info_buf;\r
+       UINT                            *p_bytes_needed;\r
+       KLOCK_QUEUE_HANDLE      hdl;\r
+\r
+       IPOIB_ENTER( IPOIB_DBG_OID );\r
+\r
+    oid                        = pNdisRequest->DATA.SET_INFORMATION.Oid;\r
+    info_buf           = pNdisRequest->DATA.QUERY_INFORMATION.InformationBuffer;\r
+    info_buf_len       = pNdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength;\r
+       p_bytes_needed  = &pNdisRequest->DATA.QUERY_INFORMATION.BytesNeeded;\r
+       status = NDIS_STATUS_SUCCESS;\r
+\r
+       buf_len = sizeof(UINT);\r
+       port_num = p_adapter->guids.port_num;\r
+\r
+       switch( oid )\r
+       {\r
+       /* Required General */\r
+       case OID_GEN_CURRENT_PACKET_FILTER:\r
+               IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                       ("Port %d received set for OID_GEN_CURRENT_PACKET_FILTER\n", port_num));\r
+               if( info_buf_len < sizeof(p_adapter->packet_filter) )\r
+               {\r
+                       status = NDIS_STATUS_INVALID_LENGTH;\r
+               }\r
+               else if( !info_buf )\r
+               {\r
+                       status = NDIS_STATUS_INVALID_DATA;\r
+               }\r
+               else\r
+               {\r
+                       KeAcquireInStackQueuedSpinLock( &g_ipoib.lock, &hdl );\r
+                       cl_obj_lock( &p_adapter->obj );\r
+                       switch( p_adapter->state )\r
+                       {\r
+                       case IB_PNP_PORT_ADD:\r
+                               p_adapter->p_oid_request = pNdisRequest;\r
+                               status = NDIS_STATUS_PENDING;\r
+                               break;\r
+\r
+                       case IB_PNP_PORT_REMOVE:\r
+                               status = NDIS_STATUS_NOT_ACCEPTED;\r
+                               break;\r
+\r
+                       default:\r
+                               if( !p_adapter->packet_filter && (*(uint32_t*)info_buf) )\r
+                               {\r
+                                       cl_qlist_insert_tail(\r
+                                               &g_ipoib.adapter_list, &p_adapter->entry );\r
+\r
+                                       /*\r
+                                        * Filter was zero, now non-zero.  Register IP addresses\r
+                                        * with SA.\r
+                                        */\r
+                                       ipoib_reg_addrs( p_adapter );\r
+                               }\r
+                               else if( p_adapter->packet_filter && !(*(uint32_t*)info_buf) )\r
+                               {\r
+                                       /*\r
+                                        * Filter was non-zero, now zero.  Deregister IP addresses.\r
+                                        */\r
+                                       ipoib_dereg_addrs( p_adapter );\r
+\r
+                                       ASSERT( cl_qlist_count( &g_ipoib.adapter_list ) );\r
+                                       cl_qlist_remove_item(\r
+                                               &g_ipoib.adapter_list, &p_adapter->entry );\r
+                               }\r
+\r
+                               p_adapter->packet_filter = *(uint32_t*)info_buf;\r
+                       }\r
+                       cl_obj_unlock( &p_adapter->obj );\r
+                       KeReleaseInStackQueuedSpinLock( &hdl );\r
+               }\r
+               break;\r
+\r
+       case OID_GEN_CURRENT_LOOKAHEAD:\r
+               IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                       ("Port %d received set for OID_GEN_CURRENT_LOOKAHEAD\n", port_num));\r
+               if( info_buf_len < buf_len )\r
+                       status = NDIS_STATUS_INVALID_LENGTH;\r
+               break;\r
+\r
+       case OID_GEN_PROTOCOL_OPTIONS:\r
+               IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                       ("Port %d received set for OID_GEN_PROTOCOL_OPTIONS\n", port_num));\r
+               if( info_buf_len < buf_len )\r
+                       status = NDIS_STATUS_INVALID_LENGTH;\r
+               break;\r
+\r
+       case OID_GEN_NETWORK_LAYER_ADDRESSES:\r
+               status = __ipoib_set_net_addr( p_adapter, pNdisRequest);\r
+               break;\r
+\r
+       case OID_GEN_MACHINE_NAME:\r
+               IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_OID,\r
+                       ("Port %d received set for OID_GEN_MACHINE_NAME\n", port_num) );\r
+               break;\r
+\r
+\r
+       /* Required Ethernet operational characteristics */\r
+       case OID_802_3_MULTICAST_LIST:\r
+               IPOIB_PRINT(TRACE_LEVEL_INFORMATION, IPOIB_DBG_OID,\r
+                       ("Port %d received set for OID_802_3_MULTICAST_LIST\n", port_num) );\r
+               if( info_buf_len > MAX_MCAST * sizeof(mac_addr_t) )\r
+               {\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d OID_802_3_MULTICAST_LIST - Multicast list full.\n", port_num) );\r
+                       status = NDIS_STATUS_MULTICAST_FULL;\r
+                       *p_bytes_needed = MAX_MCAST * sizeof(mac_addr_t);\r
+               }\r
+               else if( info_buf_len % sizeof(mac_addr_t) )\r
+               {\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d OID_802_3_MULTICAST_LIST - Invalid input buffer.\n", port_num) );\r
+                       status = NDIS_STATUS_INVALID_DATA;\r
+               }\r
+               else if( !info_buf && info_buf_len )\r
+               {\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                               ("Port %d OID_802_3_MULTICAST_LIST - Invalid input buffer.\n", port_num) );\r
+                       status = NDIS_STATUS_INVALID_DATA;\r
+               }\r
+               else\r
+               {\r
+                       ipoib_refresh_mcast( p_adapter, (mac_addr_t*)info_buf,\r
+                               (uint8_t)(info_buf_len / sizeof(mac_addr_t)) );\r
+\r
+                       buf_len = info_buf_len;\r
+                       /*\r
+                        * Note that we don't return pending.  It will likely take longer\r
+                        * for our SA transactions to complete than NDIS will give us\r
+                        * before reseting the adapter.  If an SA failure is encountered,\r
+                        * the adapter will be marked as hung and we will get reset.\r
+                        */\r
+                       status = NDIS_STATUS_SUCCESS;\r
+               }\r
+               break;\r
+\r
+       case OID_TCP_TASK_OFFLOAD:\r
+               IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                       ("Port %d received set for OID_TCP_TASK_OFFLOAD\n", port_num) );\r
+\r
+               buf_len = info_buf_len;\r
+               status =\r
+                       __ipoib_set_tcp_task_offload( p_adapter, pNdisRequest );\r
+               break;\r
+\r
+       /* Optional General */\r
+       case OID_GEN_TRANSPORT_HEADER_OFFSET:\r
+#ifdef NDIS51_MINIPORT\r
+       case OID_GEN_RNDIS_CONFIG_PARAMETER:\r
+       case OID_GEN_VLAN_ID:\r
+#endif\r
+               status = NDIS_STATUS_NOT_SUPPORTED;\r
+               IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                       ("Port %d received an unsupported oid of 0x%.8X!\n", port_num, oid));\r
+               break;\r
+\r
+       case OID_GEN_SUPPORTED_LIST:\r
+       case OID_GEN_HARDWARE_STATUS:\r
+       case OID_GEN_MEDIA_SUPPORTED:\r
+       case OID_GEN_MEDIA_IN_USE:\r
+       case OID_GEN_MAXIMUM_FRAME_SIZE:\r
+       case OID_GEN_LINK_SPEED:\r
+       case OID_GEN_TRANSMIT_BUFFER_SPACE:\r
+       case OID_GEN_RECEIVE_BUFFER_SPACE:\r
+       case OID_GEN_MAXIMUM_LOOKAHEAD:\r
+       case OID_GEN_TRANSMIT_BLOCK_SIZE:\r
+       case OID_GEN_RECEIVE_BLOCK_SIZE:\r
+       case OID_GEN_MAXIMUM_TOTAL_SIZE:\r
+       case OID_GEN_VENDOR_ID:\r
+       case OID_GEN_VENDOR_DESCRIPTION:\r
+       case OID_GEN_VENDOR_DRIVER_VERSION:\r
+       case OID_GEN_DRIVER_VERSION:\r
+       case OID_GEN_MAC_OPTIONS:\r
+       case OID_GEN_MEDIA_CONNECT_STATUS:\r
+       case OID_GEN_MAXIMUM_SEND_PACKETS:\r
+       case OID_GEN_SUPPORTED_GUIDS:\r
+       case OID_GEN_PHYSICAL_MEDIUM:\r
+       default:\r
+               status = NDIS_STATUS_INVALID_OID;\r
+               IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+                       ("Port %d received an invalid oid of 0x%.8X!\n", port_num, oid));\r
+               break;\r
+       }\r
+\r
+       if( status == NDIS_STATUS_SUCCESS )\r
+       {\r
+               pNdisRequest->DATA.SET_INFORMATION.BytesRead = buf_len;\r
+       }\r
+       else\r
+       {\r
+               if( status == NDIS_STATUS_INVALID_LENGTH )\r
+               {\r
+                       if ( !*p_bytes_needed )\r
+                       {\r
+                               *p_bytes_needed = buf_len;\r
+                       }\r
+               }\r
+\r
+               pNdisRequest->DATA.SET_INFORMATION.BytesRead = 0;\r
+       }\r
+\r
+       IPOIB_EXIT( IPOIB_DBG_OID );\r
+       return status;\r
+}\r
+#endif\r
+static NDIS_STATUS\r
+ipoib_oid_handler(\r
+    IN  NDIS_HANDLE         adapter_context,\r
+    IN  PNDIS_OID_REQUEST   pNdisRequest)\r
+{\r
+    NDIS_REQUEST_TYPE       RequestType;\r
+       NDIS_STATUS     status = NDIS_STATUS_SUCCESS;\r
+\r
+       IPOIB_ENTER( IPOIB_DBG_OID );\r
+\r
+       RequestType = pNdisRequest->RequestType;\r
+\r
+       switch(RequestType)\r
+       {\r
+        case NdisRequestSetInformation:            \r
+            status = ipoib_set_info(adapter_context,\r
+                                               pNdisRequest->DATA.SET_INFORMATION.Oid,\r
+                                               pNdisRequest->DATA.SET_INFORMATION.InformationBuffer,\r
+                                               pNdisRequest->DATA.SET_INFORMATION.InformationBufferLength,\r
+                                               (PULONG)&pNdisRequest->DATA.SET_INFORMATION.BytesRead,\r
+                                               (PULONG)&pNdisRequest->DATA.SET_INFORMATION.BytesNeeded);\r
+            break;\r
+                \r
+        case NdisRequestQueryInformation:\r
+        case NdisRequestQueryStatistics:\r
+            status = ipoib_query_info(adapter_context,\r
+                                               pNdisRequest->DATA.QUERY_INFORMATION.Oid,\r
+                                               pNdisRequest->DATA.QUERY_INFORMATION.InformationBuffer,\r
+                                               pNdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength,\r
+                                               (PULONG)&pNdisRequest->DATA.QUERY_INFORMATION.BytesWritten,\r
+                                               (PULONG)&pNdisRequest->DATA.QUERY_INFORMATION.BytesNeeded);\r
+                                               \r
+            break;\r
+\r
+        default:\r
+            status = NDIS_STATUS_NOT_SUPPORTED;\r
+            break;\r
+       }\r
+       IPOIB_EXIT( IPOIB_DBG_OID );\r
+       return status;\r
+}\r
+\r
+//! Transfers some number of packets, specified as an array of packet pointers, over the network. \r
+/*  For a deserialized driver, these packets are completed asynchronously\r
+using NdisMSendComplete.\r
+IRQL <= DISPATCH_LEVEL\r
+\r
+@param adapter_context Pointer to ipoib_adapter_t structure with per NIC state\r
+@param packet_array Array of packets to send\r
+@param numPackets Number of packets in the array\r
+*/\r
+void\r
+ipoib_send_net_buffer_list(\r
+    IN  NDIS_HANDLE         adapter_context,\r
+    IN  PNET_BUFFER_LIST    net_buffer_list,\r
+    IN  NDIS_PORT_NUMBER    port_num,\r
+    IN  ULONG               send_flags\r
+    )\r
+{\r
+       ipoib_adapter_t         *p_adapter;\r
+       ipoib_port_t            *p_port;\r
+       ULONG                           send_complete_flags;\r
+    PNET_BUFFER_LIST    curr_net_buffer_list;\r
+    PNET_BUFFER_LIST    next_net_buffer_list;\r
+       NDIS_STATUS     status = NDIS_STATUS_SUCCESS;\r
+       \r
+       UNREFERENCED_PARAMETER(port_num);\r
+       PERF_DECLARE( SendPackets );\r
+       PERF_DECLARE( PortSend );\r
+\r
+       IPOIB_ENTER( IPOIB_DBG_SEND );\r
+       cl_perf_start( SendPackets );\r
+\r
+       CL_ASSERT( adapter_context );\r
+       p_adapter = (ipoib_adapter_t*)adapter_context;\r
+       p_port = p_adapter->p_port;\r
+\r
+       cl_obj_lock( &p_adapter->obj );\r
+       if( p_adapter->ipoib_state == IPOIB_PAUSING ||\r
+               p_adapter->ipoib_state == IPOIB_PAUSED)\r
+       {\r
+               status = NDIS_STATUS_PAUSED; \r
+               cl_obj_unlock( &p_adapter->obj );\r
+               goto compl_status;\r
+       }\r
+\r
+       if( p_adapter->state != IB_PNP_PORT_ACTIVE || !p_adapter->p_port )\r
+       {\r
+               cl_obj_unlock( &p_adapter->obj );\r
+               status = NDIS_STATUS_FAILURE; \r
+               goto compl_status;\r
+       }\r
+\r
+       p_port = p_adapter->p_port;\r
+       ipoib_port_ref( p_port, ref_send_packets );\r
+       cl_obj_unlock( &p_adapter->obj );\r
+       //IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+       //                      ("Starting NET BUFFER LIST \n") );\r
+       for (curr_net_buffer_list = net_buffer_list;\r
+               curr_net_buffer_list != NULL;\r
+               curr_net_buffer_list = next_net_buffer_list)\r
+       {\r
+               next_net_buffer_list = NET_BUFFER_LIST_NEXT_NBL(curr_net_buffer_list);\r
+               cl_perf_start( PortSend );\r
+               \r
+               ipoib_port_send( p_port, curr_net_buffer_list, send_flags);\r
+               cl_perf_stop( &adapter->perf, PortSend );\r
+       }\r
+       ipoib_port_deref( p_port, ref_send_packets );\r
+\r
+       cl_perf_stop( &p_adapter->perf, SendPackets );\r
+\r
+       cl_perf_log( &p_adapter->perf, SendBundle, num_packets );\r
+\r
+compl_status:\r
+    if (status != NDIS_STATUS_SUCCESS)\r
+       {\r
+               //ASSERT(FALSE); //????\r
+               IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                               ("Got bad status \n") );\r
+               send_complete_flags = 0;\r
+           \r
+               for (curr_net_buffer_list = net_buffer_list;\r
+                                curr_net_buffer_list != NULL;\r
+                                curr_net_buffer_list = next_net_buffer_list)\r
+               {\r
+                       next_net_buffer_list = NET_BUFFER_LIST_NEXT_NBL(curr_net_buffer_list);\r
+     &n