[VNIC] Changes include support for jumbo frames, 802.1q/p vlan and priority, IPv4...
authoraestrin <aestrin@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Mon, 21 Jan 2008 21:49:28 +0000 (21:49 +0000)
committeraestrin <aestrin@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Mon, 21 Jan 2008 21:49:28 +0000 (21:49 +0000)
git-svn-id: svn://openib.tc.cornell.edu/gen1/trunk@928 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

22 files changed:
inc/kernel/ip_packet.h
ulp/inic/kernel/SOURCES
ulp/inic/kernel/inic.rc
ulp/inic/kernel/netvnic.inf
ulp/inic/kernel/vnic_adapter.c
ulp/inic/kernel/vnic_adapter.h
ulp/inic/kernel/vnic_config.h
ulp/inic/kernel/vnic_control.c
ulp/inic/kernel/vnic_control.h
ulp/inic/kernel/vnic_controlpkt.h
ulp/inic/kernel/vnic_data.c
ulp/inic/kernel/vnic_data.h
ulp/inic/kernel/vnic_debug.h
ulp/inic/kernel/vnic_driver.c
ulp/inic/kernel/vnic_driver.h
ulp/inic/kernel/vnic_ib.c
ulp/inic/kernel/vnic_ib.h
ulp/inic/kernel/vnic_netpath.c
ulp/inic/kernel/vnic_trailer.h
ulp/inic/kernel/vnic_util.h
ulp/inic/kernel/vnic_viport.c
ulp/inic/kernel/vnic_viport.h

index 60421ed..481cb9c 100644 (file)
@@ -45,6 +45,7 @@
 \r
 #define ETH_PROT_TYPE_IP       CL_HTON16(0x800)\r
 #define ETH_PROT_TYPE_ARP      CL_HTON16(0x806)\r
+#define ETH_PROT_VLAN_TAG      CL_HTON16(0x8100)\r
 \r
 \r
 #define ETH_IS_LOCALLY_ADMINISTERED(addr) \\r
index d56ea8c..481cdaf 100644 (file)
@@ -7,7 +7,7 @@
 \r
 # The TARGETNAME.  This is name of the item being built (without the\r
 #  extension.  \r
-TARGETNAME=vnic\r
+TARGETNAME=qlc_vnic\r
 \r
 ########################################################################\r
 # The path where all binaries are built.  \r
@@ -51,13 +51,14 @@ SOURCES=    inic.rc \
 INCLUDES=..;..\..\..\inc;..\..\..\inc\kernel;\r
 \r
 C_DEFINES=$(C_DEFINES) -DNDIS_MINIPORT_DRIVER -DNDIS_WDM=1 \\r
-       -DDEPRECATE_DDK_FUNCTIONS -DNDIS51_MINIPORT -DNEED_CL_OBJ -DBINARY_COMPATIBLE=0\r
+       -DDEPRECATE_DDK_FUNCTIONS -DNDIS51_MINIPORT -DBINARY_COMPATIBLE=0 -DLBFO_ENABLED\r
 \r
 TARGETLIBS= \\r
        $(DDK_LIB_PATH)\ntoskrnl.lib \\r
        $(DDK_LIB_PATH)\hal.lib         \\r
        $(DDK_LIB_PATH)\ndis.lib        \\r
-       $(TARGETPATH)\*\complib.lib \r
+       $(TARGETPATH)\*\complib.lib \\r
+       $(TARGETPATH)\*\ibal.lib\r
 \r
 #!if !defined(DDK_TARGET_OS) || "$(DDK_TARGET_OS)"=="Win2K"\r
 #\r
index 93bede1..79f1796 100644 (file)
@@ -41,7 +41,7 @@
 #define VER_FILEDESCRIPTION_STR                "Virtual Nic NDIS Miniport"\r
 #endif\r
 \r
-#define VER_INTERNALNAME_STR           "vnic.sys"\r
-#define VER_ORIGINALFILENAME_STR       "vnic.sys"\r
+#define VER_INTERNALNAME_STR           "qlc_vnic.sys"\r
+#define VER_ORIGINALFILENAME_STR       "qlc_vnic.sys"\r
 \r
 #include <common.ver>\r
index 42482a2..8948bbc 100644 (file)
@@ -1,12 +1,12 @@
-; SilverStorm Technologies Ethernet over Infiniband NIC.\r
-; Copyright 2006 SilverStorm Technologies all Rights Reserved.\r
+; QLogic Corporation Ethernet over Infiniband NIC.\r
+; Copyright (c) QLogic Corporation all Rights Reserved.\r
 \r
 [Version]\r
 Signature="$Windows NT$"\r
 Class=Net\r
 ClassGUID={4d36e972-e325-11ce-bfc1-08002be10318}\r
 Provider=%Inf_Provider%\r
-DriverVer=03/08/2006,1.0.0000.614\r
+DriverVer=01/21/2008,1.0.0000.927\r
 \r
 [ControlFlags]\r
 ExcludeFromSelect = IBA\V00066aP00000030\r
@@ -17,130 +17,190 @@ ExcludeFromSelect = IBA\V00066aP00000030
 DefaultDestDir=12\r
 \r
 [SourceDisksNames.x86]\r
-1=%DiskId%,,,\x86\r
+1=%DiskId%,,,""\r
 \r
 [SourceDisksNames.amd64]\r
-1=%DiskId%,,,\amd64\r
+1=%DiskId%,,,""\r
 \r
 [SourceDisksNames.ia64]\r
-1=%DiskId%,,,\ia64\r
+1=%DiskId%,,,""\r
 \r
 [SourceDisksFiles]\r
-vnic.sys=1\r
+qlc_vnic.sys=1\r
 \r
 [Manufacturer]\r
-%Inf_Provider% = VNIC.DeviceSection,ntx86,ntamd64,ntia64\r
+%Inf_Provider% = vnic.DeviceSection,ntx86,ntamd64,ntia64\r
 \r
-[VNIC.DeviceSection]\r
+[vnic.DeviceSection]\r
 ; empty since we don't support W9x/Me\r
 \r
-[VNIC.DeviceSection.ntx86]\r
-%VNIC.DeviceDesc% = VNIC.DDInstall,IBA\V00066aP00000030S00066as00000030v0001, \\r
+[vnic.DeviceSection.ntx86]\r
+%vnic.DeviceDesc% = VNIC.DDInstall,IBA\V00066aP00000030S00066as00000030v0001, \\r
                                                                IBA\V00066aP00000030S00066as00000030, \\r
                                                                IBA\V00066aP00000030v0001, \\r
                                                                IBA\V00066aP00000030\r
 \r
-[VNIC.DeviceSection.ntamd64]\r
-%VNIC.DeviceDesc% = VNIC.DDInstall,IBA\V00066aP00000030S00066as00000030v0001, \\r
+[vnic.DeviceSection.ntamd64]\r
+%vnic.DeviceDesc% = vnic.DDInstall,IBA\V00066aP00000030S00066as00000030v0001, \\r
                                                                IBA\V00066aP00000030S00066as00000030, \\r
                                                                IBA\V00066aP00000030v0001, \\r
                                                                IBA\V00066aP00000030\r
 \r
-[VNIC.DeviceSection.ntia64]\r
-%VNIC.DeviceDesc% = VNIC.DDInstall,IBA\V00066aP00000030S00066as00000030v0001, \\r
+[vnic.DeviceSection.ntia64]\r
+%vnic.DeviceDesc% = vnic.DDInstall,IBA\V00066aP00000030S00066as00000030v0001, \\r
                                                                IBA\V00066aP00000030S00066as00000030, \\r
                                                                IBA\V00066aP00000030v0001, \\r
                                                                IBA\V00066aP00000030\r
 \r
-[VNIC.DDInstall.ntx86]\r
+[vnic.DDInstall.ntx86]\r
 Characteristics = %CHARACTERISTICS%\r
-AddReg = VNIC.AddReg\r
-CopyFiles = VNIC.CopyFiles\r
+AddReg = vnic.AddReg\r
+CopyFiles = vnic.CopyFiles\r
 \r
-[VNIC.DDInstall.ntamd64]\r
+[vnic.DDInstall.ntamd64]\r
 Characteristics = %CHARACTERISTICS%\r
-AddReg = VNIC.AddReg\r
-CopyFiles = VNIC.CopyFiles\r
+AddReg = vnic.AddReg\r
+CopyFiles = vnic.CopyFiles\r
 \r
-[VNIC.DDInstall.ntia64]\r
+[vnic.DDInstall.ntia64]\r
 Characteristics = %CHARACTERISTICS%\r
-AddReg = VNIC.AddReg\r
-CopyFiles = VNIC.CopyFiles\r
+AddReg = vnic.AddReg\r
+CopyFiles = vnic.CopyFiles\r
 \r
-[VNIC.DDInstall.ntx86.Services]\r
-AddService = vnic,%SPSVCINST_ASSOCSERVICE%,VNIC.ServiceInstall,VNIC.EventLogInstall\r
+[vnic.DDInstall.ntx86.Services]\r
+AddService = vnic,%SPSVCINST_ASSOCSERVICE%,vnic.ServiceInstall,vnic.EventLogInstall\r
 \r
-[VNIC.DDInstall.ntamd64.Services]\r
-AddService = vnic,%SPSVCINST_ASSOCSERVICE%,VNIC.ServiceInstall,VNIC.EventLogInstall\r
+[vnic.DDInstall.ntamd64.Services]\r
+AddService = vnic,%SPSVCINST_ASSOCSERVICE%,vnic.ServiceInstall,vnic.EventLogInstall\r
 \r
-[VNIC.DDInstall.ntia64.Services]\r
-AddService = vnic,%SPSVCINST_ASSOCSERVICE%,VNIC.ServiceInstall,VNIC.EventLogInstall\r
+[vnic.DDInstall.ntia64.Services]\r
+AddService = vnic,%SPSVCINST_ASSOCSERVICE%,vnic.ServiceInstall,vnic.EventLogInstall\r
 \r
-[VNIC.CopyFiles]\r
-vnic.sys\r
+[vnic.CopyFiles]\r
+qlc_vnic.sys,,,2\r
 \r
-[VNIC.AddReg]\r
-HKR, Ndi,                       Service,    0, "vnic"\r
+[vnic.AddReg]\r
+HKR, Ndi,                       Service,    0, "qlc_vnic"\r
 HKR, Ndi\Interfaces,            UpperRange, 0, "ndis5"\r
 HKR, Ndi\Interfaces,            LowerRange, 0, "ethernet"\r
 \r
-\r
+HKR, Ndi\params\VlanId,     ParamDesc,     0, "802.1q VlanId"\r
+HKR, Ndi\params\VlanId,     Type,          0, "dword"\r
+HKR, Ndi\params\VlanId,     Optional,      0, "1"\r
+HKR, Ndi\params\VlanId,     Default,       0, "1"\r
+HKR, Ndi\params\VlanId,     Min,           0, "1"\r
+HKR, Ndi\params\VlanId,     Max,           0, "4094"\r
+HKR, Ndi\params\VlanId,     Step,          0, "1"\r
+HKR, Ndi\params\VlanId,     Base,          0, "10"\r
+\r
+HKR, Ndi\params\UserPriority,     ParamDesc,     0, "802.1p Priority"\r
+HKR, Ndi\params\UserPriority,     Type,          0, "dword"\r
+HKR, Ndi\Params\UserPriority,     Optional,      0, "1"\r
+HKR, Ndi\params\UserPriority,     Default,       0, "0"\r
+HKR, Ndi\params\UserPriority,     Min,           0, "0"\r
+HKR, Ndi\params\UserPriority,     Max,           0, "7"\r
+HKR, Ndi\params\UserPriority,     Step,          0, "1"\r
+\r
+HKR, Ndi\Params\PayloadMtu,       ParamDesc,      0, "Payload Mtu size"\r
+HKR, Ndi\Params\PayloadMtu,       Type,           0, "dword"\r
+HKR, Ndi\Params\PayloadMtu,       Default,        0, "1500"\r
+HKR, Ndi\Params\PayloadMtu,       Min,            0, "1500"\r
+HKR, Ndi\Params\PayloadMtu,       Max,            0, "9500"\r
+HKR, Ndi\Params\PayloadMtu,       Step,           0, "500"\r
+HKR, Ndi\Params\PayloadMtu,       Base,           0, "10"\r
+\r
+HKR, Ndi\Params\UseTxCsum,        ParamDesc,      0, "Send Chksum Offload"\r
+HKR, Ndi\Params\UseTxCsum,        Type,           0, "enum"\r
+HKR, Ndi\Params\UseTxCsum,        Default,        0, "1"\r
+HKR, Ndi\Params\UseTxCsum,        Optional,       0, "0"\r
+HKR, Ndi\Params\UseTxCsum\enum,  "0",             0, "Disabled"\r
+HKR, Ndi\Params\UseTxCsum\enum,  "1",             0, "Enabled"\r
+\r
+HKR, Ndi\Params\UseRxCsum,ParamDesc,    0, "Recv Chksum Offload"\r
+HKR, Ndi\Params\UseRxCsum,Type,                0, "enum"\r
+HKR, Ndi\Params\UseRxCsum,Default,      0, "1"\r
+HKR, Ndi\Params\UseRxCsum,Optional,     0, "0"\r
+HKR, Ndi\Params\UseRxCsum\enum, "0",    0, "Disabled"\r
+HKR, Ndi\Params\UseRxCsum\enum, "1",    0, "Enabled"\r
+\r
+HKR, Ndi\Params\SecondaryPath,       ParamDesc,      0, "Secondary path"\r
+HKR, Ndi\Params\SecondaryPath,       Type,           0, "enum"\r
+HKR, Ndi\Params\SecondaryPath,       Default,        0, "0"\r
+HKR, Ndi\Params\SecondaryPath,       Optional,       0, "0"\r
+HKR, Ndi\Params\SecondaryPath\enum, "0",             0, "Disabled"\r
+HKR, Ndi\Params\SecondaryPath\enum, "1",             0, "Enabled"\r
+\r
+HKR, Ndi\Params\Heartbeat,       ParamDesc,      0, "Heartbeat interval (ms)"\r
+HKR, Ndi\Params\Heartbeat,       Type,           0, "dword"\r
+HKR, Ndi\Params\Heartbeat,       Default,        0, "2000"\r
+HKR, Ndi\Params\Heartbeat,       Min,            0, "0"\r
+HKR, Ndi\Params\Heartbeat,       Max,            0, "10000"\r
+HKR, Ndi\Params\Heartbeat,       Step,           0, "1000"\r
+HKR, Ndi\Params\Heartbeat,       Base,           0, "10"\r
+\r
+HKR, Ndi\Params\BundleId,       ParamDesc,      0, "LBFO Bundle Id"\r
+HKR, Ndi\Params\BundleId,       Type,           0, "enum"\r
+HKR, Ndi\Params\BundleId,       Default,        0, "1"\r
+HKR, Ndi\Params\BundleId,       Optional,       0, "1"\r
+HKR, Ndi\Params\BundleId\enum,  "1",            0, "Bundle 1"\r
+HKR, Ndi\Params\BundleId\enum,  "2",            0, "Bundle 2"\r
+HKR, Ndi\Params\BundleId\enum,  "3",            0, "Bundle 3"\r
+HKR, Ndi\Params\BundleId\enum,  "4",            0, "Bundle 4"\r
+;\r
+;\r
 ; ============= Service Install section ==============\r
+;\r
 \r
-[VNIC.ServiceInstall]\r
-DisplayName     = %VNIC.ServiceDesc%\r
+[vnic.ServiceInstall]\r
+DisplayName     = %vnic.ServiceDesc%\r
 ServiceType     = %SERVICE_KERNEL_DRIVER%\r
 StartType       = %SERVICE_DEMAND_START%\r
 ErrorControl    = %SERVICE_ERROR_NORMAL%\r
-ServiceBinary   = %12%\vnic.sys\r
+ServiceBinary   = %12%\qlc_vnic.sys\r
 LoadOrderGroup  = NDIS\r
-AddReg          = VNIC.ParamsReg\r
-\r
-[VNIC.ParamsReg]\r
-HKR,"Params\PnpInterface",%InternalBus%,%REG_DWORD%,1\r
-HKR,"Params\PnpInterface",%PNPBus%,%REG_DWORD%,1\r
-\r
-HKR, Params,   MinMtu,,                                        "1500"\r
-HKR, Params,   MaxMtu,,                                        "9500"\r
-HKR, Params,   MinHostPoolSz,,                         "256"\r
-HKR, Params,   HostRecvPoolEntries,,           "512"\r
-HKR, Params,   MinEiocPoolSz,,                         "256"\r
-HKR, Params,   MaxEiocPoolSz,,                         "512"\r
-HKR, Params,   MinHostKickTimeout,,            "50"\r
-HKR, Params,   MaxHostKickTimeout,,            "100"\r
-HKR, Params,   MinHostKickEntries,,            "1"\r
-HKR, Params,   MaxHostKickEntries,,            "64"\r
-HKR, Params,   MinHostKickBytes,,                      "0"\r
-HKR, Params,   MaxHostKickBytes,,                      "5000"\r
-HKR, Params,   MinHostUpdateSz,,                       "8"\r
-HKR, Params,   MaxHostUpdateSz,,                       "32"\r
-HKR, Params,   MinEiocUpdateSz,,                       "8"\r
-HKR, Params,   MaxEiocUpdateSz,,                       "32"\r
-HKR, Params,   UseRxCsum,                              %REG_DWORD%,1\r
-HKR, Params,   UseTxCsum,                              %REG_DWORD%,1\r
-\r
-[VNIC.EventLogInstall]\r
-AddReg = VNIC.EventLogAddReg\r
-\r
-[VNIC.EventLogAddReg]\r
+AddReg          = vnic.ParamsReg\r
+\r
+[vnic.ParamsReg]\r
+\r
+HKR,"Parameters","DebugFlags",%REG_DWORD%,0x00000003\r
+\r
+HKR,"Parameters","MinHostPoolSz",%REG_DWORD%,256\r
+HKR, "Parameters","HostRecvPoolEntries",%REG_DWORD%,512\r
+HKR, "Parameters","MinEiocPoolSz",%REG_DWORD%,256\r
+HKR, "Parameters","MaxEiocPoolSz",%REG_DWORD%,512\r
+HKR, "Parameters","MinHostKickTimeout",%REG_DWORD%,50\r
+HKR, "Parameters","MaxHostKickTimeout",%REG_DWORD%,100\r
+HKR, "Parameters","MinHostKickEntries",%REG_DWORD%,1\r
+HKR, "Parameters","MaxHostKickEntries",%REG_DWORD%,64\r
+HKR, "Parameters","MinHostKickBytes",%REG_DWORD%,0\r
+HKR, "Parameters","MaxHostKickBytes",%REG_DWORD%,5000\r
+HKR, "Parameters","MinHostUpdateSz",%REG_DWORD%,8\r
+HKR, "Parameters","MaxHostUpdateSz",%REG_DWORD%,32\r
+HKR, "Parameters","MinEiocUpdateSz",%REG_DWORD%,8\r
+HKR, "Parameters","MaxEiocUpdateSz",%REG_DWORD%,32\r
+HKR, "Parameters","HeartbeatTimeout",%REG_DWORD%,40000\r
+\r
+[vnic.EventLogInstall]\r
+AddReg = vnic.EventLogAddReg\r
+\r
+[vnic.EventLogAddReg]\r
 HKR,,EventMessageFile,%REG_EXPAND_SZ%,"%%SystemRoot%%\System32\netevent.dll"\r
 HKR,,TypesSupported,%REG_DWORD%,7\r
 \r
 [Strings]\r
-NetClassGuid = "{4d36e972-e325-11ce-bfc1-08002be10318}"\r
-Inf_Provider = "SilverStorm Technologies"\r
-VNIC.DeviceDesc = "Ethernet over InfiniBand Virtual NIC"\r
-VNIC.ServiceDesc = "Virtual NIC"\r
-DiskId = "SilverStorm Ethernet over InfiniBand Virtual NIC installation disk"\r
-InternalBus                            = 0\r
-PNPBus                                 = 15\r
-SPSVCINST_NULL                 = 0x0\r
-SPSVCINST_ASSOCSERVICE = 0x00000002\r
-SERVICE_KERNEL_DRIVER  = 1\r
-SERVICE_DEMAND_START   = 3\r
-SERVICE_ERROR_NORMAL   = 1\r
-REG_DWORD                              = 0x00010001\r
-REG_DWORD_NO_CLOBBER   = 0x00010003\r
-REG_EXPAND_SZ                  = 0x00020000\r
-CHARACTERISTICS                        = 0x81 ; NCF_VIRTUAL | NCF_HAS_UI\r
-\r
+NetClassGuid="{4d36e972-e325-11ce-bfc1-08002be10318}"\r
+Inf_Provider="QLogic Corporation"\r
+vnic.DeviceDesc="Ethernet over InfiniBand Virtual NIC"\r
+vnic.ServiceDesc="Virtual NIC"\r
+DiskId="QLogic Ethernet over InfiniBand Disk"\r
+InternalBus=0\r
+PNPBus=15\r
+SPSVCINST_NULL=0x0\r
+SPSVCINST_ASSOCSERVICE=0x00000002\r
+SERVICE_KERNEL_DRIVER=1\r
+SERVICE_DEMAND_START=3\r
+SERVICE_ERROR_NORMAL=1\r
+REG_DWORD=0x00010001\r
+REG_DWORD_NO_CLOBBER=0x00010003\r
+REG_EXPAND_SZ=0x00020000\r
+CHARACTERISTICS=0x81; NCF_VIRTUAL | NCF_HAS_UI\r
index afe2579..1b5c14c 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
- * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.\r
+ * Copyright (c) 2007 QLogic Corporation.  All rights reserved.\r
  *\r
  * This software is available to you under the OpenIB.org BSD license\r
  * below:\r
@@ -40,49 +40,114 @@ extern struct _vnic_globals        g_vnic;
 \r
 NDIS_STATUS\r
 vnic_get_adapter_params(\r
-       IN                              NDIS_HANDLE                             h_handle,\r
-       OUT                             vnic_params_t* const    p_params );\r
+       IN              NDIS_HANDLE                             h_handle,\r
+       OUT             vnic_params_t* const    p_params );\r
+\r
+static\r
+NDIS_STATUS\r
+_adapter_set_sg_size(\r
+       IN              NDIS_HANDLE             h_handle,\r
+       IN              ULONG                   mtu_size );\r
 \r
 NDIS_STATUS\r
 vnic_get_adapter_interface(\r
-       IN                              NDIS_HANDLE                     h_handle,\r
-       IN                              vnic_adapter_t          *p_adapter);\r
+       IN              NDIS_HANDLE                     h_handle,\r
+       IN              vnic_adapter_t          *p_adapter);\r
 \r
-static ib_api_status_t\r
+static\r
+vnic_path_record_t*\r
 __path_record_add(\r
-       IN                              vnic_adapter_t          *p_adapter,\r
-       IN                              ib_path_rec_t           *p_path_rec );\r
+       IN              vnic_adapter_t* const   p_adapter,\r
+       IN              ib_path_rec_t* const    p_path_rec );\r
 \r
-static ib_api_status_t\r
+static \r
+vnic_path_record_t*\r
 __path_record_remove(\r
-       IN                              vnic_adapter_t          *p_adapter,\r
-       IN                              ib_path_rec_t           *p_path_rec );\r
+       IN              vnic_adapter_t* const   p_adapter,\r
+       IN              ib_path_rec_t* const    p_path_rec );\r
 \r
 static BOOLEAN\r
 __path_records_match(\r
-       IN                              ib_path_rec_t           *p_path1,\r
-       IN                              ib_path_rec_t           *p_path2 );\r
+       IN              ib_path_rec_t* const    p_path1,\r
+       IN              ib_path_rec_t* const    p_path2 );\r
+\r
+static\r
+vnic_path_record_t *\r
+__path_record_find( \r
+       IN              vnic_adapter_t* const   p_adapter,\r
+       IN              ib_path_rec_t* const    p_path_rec );\r
+\r
+static\r
+vnic_path_record_t*\r
+__path_record_get(\r
+       IN              vnic_adapter_t* const   p_adapter );\r
 \r
 static void\r
 __path_records_cleanup(\r
-       IN         vnic_adapter_t       *p_adapter );\r
+       IN      vnic_adapter_t  *p_adapter );\r
+\r
+static ib_api_status_t\r
+_adapter_open_ca(\r
+       IN              vnic_adapter_t* const   p_adapter );\r
+\r
 \r
 static ib_api_status_t\r
-_vnic_get_ca_info(\r
-                       IN              vnic_adapter_t          *p_adapter );\r
+_adapter_close_ca(\r
+       IN              vnic_adapter_t* const   p_adapter );\r
+\r
+static \r
+ib_api_status_t\r
+_adapter_netpath_update(\r
+       IN              vnic_adapter_t* const   p_adapter,\r
+       IN              viport_t* const                 p_viport,\r
+       IN              vnic_path_record_t*             p_path );\r
+\r
+static\r
+ib_api_status_t\r
+adapter_netpath_update_and_connect(\r
+       IN              vnic_adapter_t* const   p_adapter,\r
+       IN              vnic_path_record_t              *p_path );\r
 \r
 static inline uint8_t\r
 _get_ioc_num_from_iocguid(\r
-                       IN              ib_net64_t              *p_iocguid );\r
+       IN              ib_net64_t              *p_iocguid );\r
 \r
 static BOOLEAN\r
 __sid_valid(\r
-               IN              vnic_adapter_t          *p_adapter,\r
-               IN              ib_net64_t                      sid );\r
+       IN              vnic_adapter_t          *p_adapter,\r
+       IN              ib_net64_t                      sid );\r
+\r
+static void\r
+__adapter_cleanup(\r
+       IN      vnic_adapter_t          *p_adapter );\r
+\r
+#if defined( LBFO_ENABLED )\r
+\r
+static NDIS_STATUS\r
+__adapter_set_failover_primary(\r
+        IN             vnic_adapter_t*  const p_adapter,\r
+        IN             BOOLEAN                 promote_secondary );\r
+\r
+static NDIS_STATUS\r
+__adapter_set_failover_secondary(\r
+        IN             vnic_adapter_t* const   p_adapter,\r
+        IN             NDIS_HANDLE                             primary_handle );\r
 \r
 static void\r
-_vnic_viport_free(\r
-               IN       vnic_adapter_t* const          p_adapter );\r
+__adapter_add_to_failover_list(\r
+        IN             vnic_adapter_t* const   p_adapter,\r
+        IN             lbfo_state_t            failover_state );\r
+static void\r
+__adapter_remove_from_failover_list(\r
+        IN             vnic_adapter_t* const   p_adapter );\r
+\r
+static\r
+vnic_adapter_t*\r
+__adapter_find_on_failover_list(\r
+       IN              int                             list_flag,\r
+       IN              uint32_t                bundle_id );\r
+\r
+#endif // LBFO_ENABLED\r
 \r
 ib_api_status_t\r
 vnic_create_adapter(\r
@@ -93,7 +158,6 @@ vnic_create_adapter(
        NDIS_STATUS                     status;\r
        ib_api_status_t         ib_status;\r
        vnic_adapter_t          *p_adapter;\r
-       KIRQL                           irql;\r
 \r
        VNIC_ENTER( VNIC_DBG_ADAPTER );\r
 \r
@@ -108,8 +172,17 @@ vnic_create_adapter(
        NdisZeroMemory( p_adapter, sizeof(vnic_adapter_t) );\r
 \r
        NdisAllocateSpinLock( &p_adapter->lock );\r
+       NdisAllocateSpinLock( &p_adapter->path_records_lock );\r
+       NdisAllocateSpinLock( &p_adapter->pending_list_lock );\r
+       NdisAllocateSpinLock( &p_adapter->cancel_list_lock );\r
+       \r
+       InitializeListHead( &p_adapter->send_pending_list );\r
+       InitializeListHead( &p_adapter->cancel_send_list );\r
 \r
-       status = vnic_get_adapter_params( wrapper_config_context, &p_adapter->params );\r
+       cl_qlist_init( &p_adapter->path_records_list );\r
+\r
+       status = \r
+               vnic_get_adapter_params( wrapper_config_context, &p_adapter->params );\r
 \r
        if ( status != NDIS_STATUS_SUCCESS )\r
        {\r
@@ -133,25 +206,27 @@ vnic_create_adapter(
        if ( ib_status != IB_SUCCESS )\r
        {\r
                VNIC_TRACE( VNIC_DBG_ERROR,\r
-                       ("ib_open_al returned %s\n", p_adapter->ifc.get_err_str( ib_status )) );\r
+                       ("ib_open_al returned %s\n", \r
+                               p_adapter->ifc.get_err_str( ib_status )) );\r
                NdisFreeMemory( p_adapter, sizeof(vnic_adapter_t), 0 );\r
                return ib_status;\r
        }\r
 \r
-       /* ca is opened here */\r
-       ib_status = _vnic_get_ca_info( p_adapter );\r
-       if( ib_status != IB_SUCCESS )\r
-       {\r
-               VNIC_TRACE ( VNIC_DBG_ERROR,\r
-                       ("_get_ca_info return status %s\n", p_adapter->ifc.get_err_str( ib_status )) );\r
-               NdisFreeMemory( p_adapter, sizeof(vnic_adapter_t), 0 );\r
-               return ib_status;\r
-       }\r
+       /* we will use these indexes later as an viport instance ID for connect request\r
+       *  since target requires unique instance per connection per IOC.\r
+       */\r
+       p_adapter->primaryPath.instance = NETPATH_PRIMARY;\r
+       p_adapter->secondaryPath.instance = NETPATH_SECONDARY;\r
+       \r
+       /* set adapter level params here */\r
+       p_adapter->vlan_info = p_adapter->params.VlanInfo;\r
 \r
-       KeAcquireSpinLock( &g_vnic.lock, &irql );\r
-       InsertTailList( &g_vnic.adapter_list, &p_adapter->list_entry );\r
-       InterlockedIncrement( &g_vnic.adapters );\r
-       KeReleaseSpinLock( &g_vnic.lock, irql );\r
+#if defined (LBFO_ENABLED)\r
+\r
+       p_adapter->failover.bundle_id = p_adapter->params.bundle_id;\r
+       p_adapter->failover.fo_state = _ADAPTER_NOT_BUNDLED;\r
+\r
+#endif\r
 \r
        p_adapter->h_handle = h_handle;\r
        *pp_adapter = p_adapter;\r
@@ -166,62 +241,53 @@ vnic_destroy_adapter(
         IN      vnic_adapter_t         *p_adapter)\r
 {\r
        ib_api_status_t ib_status = IB_SUCCESS;\r
-       KIRQL                   irql;\r
+       ib_pnp_handle_t  h_pnp;\r
+       ib_al_handle_t   h_al;\r
 \r
        VNIC_ENTER( VNIC_DBG_ADAPTER );\r
 \r
        ASSERT( KeGetCurrentIrql() < DISPATCH_LEVEL );\r
 \r
-       KeAcquireSpinLock( &g_vnic.lock, &irql );\r
-       RemoveEntryList( &p_adapter->list_entry );\r
-       InterlockedDecrement( &g_vnic.adapters );\r
-       KeReleaseSpinLock( &g_vnic.lock, irql );\r
-\r
-       if( p_adapter->h_pnp )\r
+       if( ( h_pnp = InterlockedExchangePointer( (void *)&p_adapter->h_pnp, NULL ) ) != NULL )\r
        {\r
                ib_status =\r
-                       p_adapter->ifc.dereg_pnp( p_adapter->h_pnp, ib_sync_destroy );\r
+                       p_adapter->ifc.dereg_pnp( h_pnp, NULL );\r
        }\r
 \r
-       vnic_viport_cleanup( p_adapter );\r
+               /* should not receive new path notifications anymore, safe to cleanup */\r
 \r
-       if ( p_adapter->ca.region.h_mr )\r
+       if( InterlockedCompareExchange( (volatile LONG *)&p_adapter->state,\r
+                               INIC_DEREGISTERING, INIC_REGISTERED ) == INIC_REGISTERED )\r
        {\r
-               ib_status = p_adapter->ifc.dereg_mr(p_adapter->ca.region.h_mr );\r
-               ASSERT( ib_status == IB_SUCCESS );\r
+               __adapter_cleanup( p_adapter );\r
        }\r
 \r
-       if( p_adapter->ca.hPd )\r
-       {\r
-               ib_status = p_adapter->ifc.dealloc_pd( p_adapter->ca.hPd, NULL );\r
-               ASSERT( ib_status == IB_SUCCESS );\r
-       }\r
+       _adapter_close_ca( p_adapter );\r
 \r
-       if ( p_adapter->h_ca )\r
-       {\r
-               ib_status = p_adapter->ifc.close_ca( p_adapter->h_ca, NULL );\r
-               ASSERT( ib_status == IB_SUCCESS );\r
-       }\r
+#if defined( LBFO_ENABLED )\r
+\r
+       __adapter_remove_from_failover_list( p_adapter );\r
 \r
-       if ( p_adapter->h_al )\r
+#endif\r
+\r
+       InterlockedExchange( (volatile LONG *)&p_adapter->state, INIC_UNINITIALIZED );\r
+       if( ( h_al = InterlockedExchangePointer( (void *)&p_adapter->h_al, NULL ) ) != NULL )\r
        {\r
-               ib_status = p_adapter->ifc.close_al( p_adapter->h_al );\r
+               ib_status = p_adapter->ifc.close_al( h_al );\r
                ASSERT( ib_status == IB_SUCCESS );\r
        }\r
 \r
-       if ( p_adapter->p_svc_entries )\r
-               cl_free ( p_adapter->p_svc_entries );\r
-\r
        NdisFreeSpinLock( &p_adapter->lock );\r
+       NdisFreeSpinLock( &p_adapter->path_records_lock );\r
        NdisFreeMemory( p_adapter, sizeof(vnic_adapter_t), 0 );\r
+       p_adapter = NULL;\r
 \r
        VNIC_EXIT( VNIC_DBG_ADAPTER );\r
 }\r
 \r
-\r
 static ib_api_status_t\r
-_vnic_get_ca_info(\r
-                       IN                      vnic_adapter_t          *p_adapter )\r
+_adapter_open_ca(\r
+               IN              vnic_adapter_t* const   p_adapter )\r
 {\r
        ib_api_status_t         ib_status = IB_SUCCESS;\r
        ib_al_ifc_t                     *p_ifc  = &p_adapter->ifc;\r
@@ -229,10 +295,13 @@ _vnic_get_ca_info(
        ib_ca_attr_t            *p_ca_attrs;\r
        uint32_t                        num;\r
        uint64_t        start_addr      = 0;\r
+       \r
+       if( p_adapter->h_ca )\r
+               return ib_status;\r
 \r
        ib_status = p_ifc->open_ca( p_adapter->h_al,\r
                                                                p_adapter->ifc_data.ca_guid,\r
-                                                               ib_asyncEvent,\r
+                                                               NULL, //ib_asyncEvent,\r
                                                                p_adapter,\r
                                                                &p_adapter->h_ca );\r
 \r
@@ -249,7 +318,9 @@ _vnic_get_ca_info(
                VNIC_TRACE( VNIC_DBG_ERROR,\r
                        ("ib_query_ca failed status %s\n",\r
                        p_ifc->get_err_str( ib_status )) );\r
-               return IB_INSUFFICIENT_RESOURCES;\r
+               \r
+               ib_status = IB_INSUFFICIENT_RESOURCES;\r
+               goto ca_failure;\r
        }\r
 \r
        ASSERT( attr_size );\r
@@ -259,16 +330,18 @@ _vnic_get_ca_info(
        {\r
                VNIC_TRACE( VNIC_DBG_ERROR,\r
                        ("Allocate %d bytes failed for Channel adapter\n", attr_size ));\r
-               return IB_INSUFFICIENT_MEMORY;\r
+\r
+               ib_status = IB_INSUFFICIENT_MEMORY;\r
+               goto ca_failure;\r
        }\r
 \r
        ib_status = p_ifc->query_ca( p_adapter->h_ca, p_ca_attrs , &attr_size );\r
        if ( ib_status != IB_SUCCESS )\r
        {\r
                VNIC_TRACE( VNIC_DBG_ERROR,\r
-                       ("Query failed for channel adapter\n") );\r
+                       ("CA attributes query failed\n") );\r
                cl_free ( p_ca_attrs );\r
-               return  ib_status;\r
+               goto ca_failure;\r
        }\r
 \r
        p_adapter->ca.numPorts = p_ca_attrs->num_ports;\r
@@ -287,9 +360,9 @@ _vnic_get_ca_info(
        if ( ib_status != IB_SUCCESS )\r
        {\r
                VNIC_TRACE_EXIT ( VNIC_DBG_ERROR,\r
-                       ("alloc PD failed status %s(%d)\n",\r
+                       ("Alloc PD failed status %s(%d)\n",\r
                        p_adapter->ifc.get_err_str(ib_status), ib_status ));\r
-               return ib_status;\r
+               goto ca_failure;\r
        }\r
 \r
        if ( ( ib_status = ibregion_physInit( p_adapter,\r
@@ -301,103 +374,109 @@ _vnic_get_ca_info(
                VNIC_TRACE_EXIT ( VNIC_DBG_ERROR,\r
                        ("phys region init failed status %s(%d)\n",\r
                        p_adapter->ifc.get_err_str(ib_status), ib_status ));\r
-\r
                p_adapter->ifc.dealloc_pd( p_adapter->ca.hPd, NULL );\r
+               goto ca_failure;\r
        }\r
 \r
        return ib_status;\r
+\r
+ca_failure:\r
+       if( p_adapter->h_ca )\r
+               p_ifc->close_ca( p_adapter->h_ca, NULL );\r
+\r
+       return ib_status;\r
 }\r
 \r
 static BOOLEAN\r
-_vnic_params_sanity_check(vnic_params_t *p_params)\r
+_adapter_params_sanity_check(vnic_params_t *p_params)\r
 {\r
-        DEFAULT_PARAM( p_params->MaxAddressEntries, MAX_ADDRESS_ENTRIES );\r
-        DEFAULT_PARAM( p_params->MinAddressEntries, MIN_ADDRESS_ENTRIES );\r
-     \r
-               DEFAULT_PARAM( p_params->ViportStatsInterval, VIPORT_STATS_INTERVAL );\r
-        DEFAULT_PARAM( p_params->ViportHbInterval, VIPORT_HEARTBEAT_INTERVAL );\r
-        DEFAULT_PARAM( p_params->ViportHbTimeout, VIPORT_HEARTBEAT_TIMEOUT );\r
-       \r
-               DEFAULT_PARAM( p_params->ControlRspTimeout, CONTROL_RSP_TIMEOUT );\r
-        DEFAULT_PARAM( p_params->ControlReqRetryCount, CONTROL_REQ_RETRY_COUNT );\r
-       \r
-               DEFAULT_PARAM( p_params->RetryCount, RETRY_COUNT );\r
-        DEFAULT_PARAM( p_params->MinRnrTimer, MIN_RNR_TIMER );\r
-       \r
-               DEFAULT_PARAM( p_params->MaxViportsPerNetpath, MAX_VIPORTS_PER_NETPATH );\r
-        DEFAULT_PARAM( p_params->DefaultViportsPerNetpath, DEFAULT_VIPORTS_PER_NETPATH );\r
-\r
-               DEFAULT_PARAM( p_params->DefaultPkey, DEFAULT_PKEY );\r
-        DEFAULT_PARAM( p_params->NotifyBundleSz, NOTIFY_BUNDLE_SZ );\r
-               DEFAULT_PARAM( p_params->DefaultNoPathTimeout, DEFAULT_NO_PATH_TIMEOUT );\r
-        DEFAULT_PARAM( p_params->DefaultPrimaryConnectTimeout, DEFAULT_PRI_CON_TIMEOUT );\r
-        DEFAULT_PARAM( p_params->DefaultPrimaryReconnectTimeout, DEFAULT_PRI_RECON_TIMEOUT );\r
-        DEFAULT_PARAM( p_params->DefaultPrimarySwitchTimeout, DEFAULT_PRI_SWITCH_TIMEOUT );\r
-               DEFAULT_PARAM( p_params->DefaultPreferPrimary, DEFAULT_PREFER_PRIMARY );\r
-\r
-        U32_RANGE( p_params->MaxAddressEntries );\r
-        U32_RANGE( p_params->MinAddressEntries );\r
-               RANGE_CHECK( p_params->MinMtu, MIN_MTU, MAX_MTU );\r
-        RANGE_CHECK( p_params->MaxMtu, MIN_MTU, MAX_MTU );\r
-        U32_RANGE( p_params->HostRecvPoolEntries );\r
-        U32_RANGE( p_params->MinHostPoolSz );\r
-        U32_RANGE( p_params->MinEiocPoolSz );\r
-        U32_RANGE( p_params->MaxEiocPoolSz );\r
-        U32_ZERO_RANGE( p_params->MinHostKickTimeout );\r
-        U32_ZERO_RANGE( p_params->MaxHostKickTimeout );\r
-        U32_ZERO_RANGE( p_params->MinHostKickEntries );\r
-        U32_ZERO_RANGE( p_params->MaxHostKickEntries );\r
-        U32_ZERO_RANGE( p_params->MinHostKickBytes );\r
-        U32_ZERO_RANGE( p_params->MaxHostKickBytes );\r
-        U32_RANGE( p_params->MinHostUpdateSz );\r
-        U32_RANGE( p_params->MaxHostUpdateSz );\r
-        U32_RANGE( p_params->MinEiocUpdateSz );\r
-        U32_RANGE( p_params->MaxEiocUpdateSz );\r
-        U8_RANGE( p_params->NotifyBundleSz );\r
-        U32_ZERO_RANGE( p_params->ViportStatsInterval );\r
-        U32_ZERO_RANGE( p_params->ViportHbInterval );\r
-        U32_ZERO_RANGE( p_params->ViportHbTimeout );\r
-        U32_RANGE( p_params->ControlRspTimeout );\r
-        U8_RANGE( p_params->ControlReqRetryCount );\r
-        ZERO_RANGE_CHECK( p_params->RetryCount, 0, 7 );\r
-        ZERO_RANGE_CHECK( p_params->MinRnrTimer, 0, 31 );\r
-        U32_RANGE( p_params->DefaultViportsPerNetpath );\r
-        U8_RANGE( p_params->MaxViportsPerNetpath );\r
-        U16_ZERO_RANGE( p_params->DefaultPkey );\r
-        U32_RANGE( p_params->DefaultNoPathTimeout );\r
-        U32_RANGE( p_params->DefaultPrimaryConnectTimeout );\r
-        U32_RANGE( p_params->DefaultPrimaryReconnectTimeout );\r
-        U32_RANGE( p_params->DefaultPrimarySwitchTimeout );\r
-        BOOLEAN_RANGE( p_params->DefaultPreferPrimary );\r
-        BOOLEAN_RANGE( p_params->UseRxCsum );\r
-        BOOLEAN_RANGE( p_params->UseTxCsum );\r
-\r
-        LESS_THAN_OR_EQUAL( p_params->MinAddressEntries, p_params->MaxAddressEntries );\r
-        LESS_THAN_OR_EQUAL( p_params->MinMtu, p_params->MaxMtu );\r
-        LESS_THAN_OR_EQUAL( p_params->MinHostPoolSz, p_params->HostRecvPoolEntries );\r
-        POWER_OF_2( p_params->HostRecvPoolEntries );\r
-        POWER_OF_2( p_params->MinHostPoolSz );\r
-        POWER_OF_2( p_params->NotifyBundleSz );\r
-        LESS_THAN( p_params->NotifyBundleSz, p_params->MinEiocPoolSz );\r
-        LESS_THAN_OR_EQUAL( p_params->MinEiocPoolSz, p_params->MaxEiocPoolSz );\r
-        POWER_OF_2( p_params->MinEiocPoolSz );\r
-        POWER_OF_2( p_params->MaxEiocPoolSz );\r
-        LESS_THAN_OR_EQUAL( p_params->MinHostKickTimeout, p_params->MaxHostKickTimeout );\r
-        LESS_THAN_OR_EQUAL( p_params->MinHostKickEntries, p_params->MaxHostKickEntries );\r
-        LESS_THAN_OR_EQUAL( p_params->MinHostKickBytes, p_params->MaxHostKickBytes );\r
-        LESS_THAN_OR_EQUAL( p_params->MinHostUpdateSz, p_params->MaxHostUpdateSz );\r
-        POWER_OF_2( p_params->MinHostUpdateSz );\r
-        POWER_OF_2( p_params->MaxHostUpdateSz );\r
-        LESS_THAN( p_params->MinHostUpdateSz, p_params->MinHostPoolSz );\r
-        LESS_THAN( p_params->MaxHostUpdateSz, p_params->HostRecvPoolEntries );\r
-        LESS_THAN_OR_EQUAL( p_params->MinEiocUpdateSz, p_params->MaxEiocUpdateSz );\r
-        POWER_OF_2( p_params->MinEiocUpdateSz );\r
-        POWER_OF_2( p_params->MaxEiocUpdateSz );\r
-        LESS_THAN( p_params->MinEiocUpdateSz, p_params->MinEiocPoolSz );\r
-        LESS_THAN( p_params->MaxEiocUpdateSz, p_params->MaxEiocPoolSz );\r
-        LESS_THAN_OR_EQUAL( p_params->DefaultViportsPerNetpath, p_params->MaxViportsPerNetpath );\r
-\r
-        return TRUE;\r
+       DEFAULT_PARAM( p_params->MaxAddressEntries, MAX_ADDRESS_ENTRIES );\r
+       DEFAULT_PARAM( p_params->MinAddressEntries, MIN_ADDRESS_ENTRIES );\r
+\r
+       DEFAULT_PARAM( p_params->ViportStatsInterval, VIPORT_STATS_INTERVAL );\r
+       DEFAULT_PARAM( p_params->ViportHbInterval, VIPORT_HEARTBEAT_INTERVAL );\r
+       DEFAULT_PARAM( p_params->ViportHbTimeout, VIPORT_HEARTBEAT_TIMEOUT );\r
+\r
+       DEFAULT_PARAM( p_params->ControlRspTimeout, CONTROL_RSP_TIMEOUT );\r
+       DEFAULT_PARAM( p_params->ControlReqRetryCount, CONTROL_REQ_RETRY_COUNT );\r
+\r
+       DEFAULT_PARAM( p_params->RetryCount, RETRY_COUNT );\r
+       DEFAULT_PARAM( p_params->MinRnrTimer, MIN_RNR_TIMER );\r
+\r
+       DEFAULT_PARAM( p_params->MaxViportsPerNetpath, MAX_VIPORTS_PER_NETPATH );\r
+       DEFAULT_PARAM( p_params->DefaultViportsPerNetpath, DEFAULT_VIPORTS_PER_NETPATH );\r
+\r
+       DEFAULT_PARAM( p_params->DefaultPkey, DEFAULT_PKEY );\r
+       DEFAULT_PARAM( p_params->NotifyBundleSz, NOTIFY_BUNDLE_SZ );\r
+       DEFAULT_PARAM( p_params->DefaultNoPathTimeout, DEFAULT_NO_PATH_TIMEOUT );\r
+       DEFAULT_PARAM( p_params->DefaultPrimaryConnectTimeout, DEFAULT_PRI_CON_TIMEOUT );\r
+       DEFAULT_PARAM( p_params->DefaultPrimaryReconnectTimeout, DEFAULT_PRI_RECON_TIMEOUT );\r
+       DEFAULT_PARAM( p_params->DefaultPrimarySwitchTimeout, DEFAULT_PRI_SWITCH_TIMEOUT );\r
+       DEFAULT_PARAM( p_params->DefaultPreferPrimary, DEFAULT_PREFER_PRIMARY );\r
+\r
+       U32_RANGE( p_params->MaxAddressEntries );\r
+       U32_RANGE( p_params->MinAddressEntries );\r
+       RANGE_CHECK( p_params->MinMtu, MIN_MTU, MAX_MTU );\r
+       RANGE_CHECK( p_params->MaxMtu, MIN_MTU, MAX_MTU );\r
+       U32_RANGE( p_params->HostRecvPoolEntries );\r
+       U32_RANGE( p_params->MinHostPoolSz );\r
+       U32_RANGE( p_params->MinEiocPoolSz );\r
+       U32_RANGE( p_params->MaxEiocPoolSz );\r
+       U32_ZERO_RANGE( p_params->MinHostKickTimeout );\r
+       U32_ZERO_RANGE( p_params->MaxHostKickTimeout );\r
+       U32_ZERO_RANGE( p_params->MinHostKickEntries );\r
+       U32_ZERO_RANGE( p_params->MaxHostKickEntries );\r
+       U32_ZERO_RANGE( p_params->MinHostKickBytes );\r
+       U32_ZERO_RANGE( p_params->MaxHostKickBytes );\r
+       U32_RANGE( p_params->MinHostUpdateSz );\r
+       U32_RANGE( p_params->MaxHostUpdateSz );\r
+       U32_RANGE( p_params->MinEiocUpdateSz );\r
+       U32_RANGE( p_params->MaxEiocUpdateSz );\r
+       U8_RANGE( p_params->NotifyBundleSz );\r
+       U32_ZERO_RANGE( p_params->ViportStatsInterval );\r
+       U32_ZERO_RANGE( p_params->ViportHbInterval );\r
+       U32_ZERO_RANGE( p_params->ViportHbTimeout );\r
+       U32_RANGE( p_params->ControlRspTimeout );\r
+       U8_RANGE( p_params->ControlReqRetryCount );\r
+       ZERO_RANGE_CHECK( p_params->RetryCount, 0, 7 );\r
+       ZERO_RANGE_CHECK( p_params->MinRnrTimer, 0, 31 );\r
+       U32_RANGE( p_params->DefaultViportsPerNetpath );\r
+       U8_RANGE( p_params->MaxViportsPerNetpath );\r
+       U16_ZERO_RANGE( p_params->DefaultPkey );\r
+       U32_RANGE( p_params->DefaultNoPathTimeout );\r
+       U32_RANGE( p_params->DefaultPrimaryConnectTimeout );\r
+       U32_RANGE( p_params->DefaultPrimaryReconnectTimeout );\r
+       U32_RANGE( p_params->DefaultPrimarySwitchTimeout );\r
+       BOOLEAN_RANGE( p_params->DefaultPreferPrimary );\r
+       BOOLEAN_RANGE( p_params->UseRxCsum );\r
+       BOOLEAN_RANGE( p_params->UseTxCsum );\r
+\r
+       LESS_THAN_OR_EQUAL( p_params->MinAddressEntries, p_params->MaxAddressEntries );\r
+       LESS_THAN_OR_EQUAL( p_params->MinMtu, p_params->MaxMtu );\r
+       LESS_THAN_OR_EQUAL( p_params->MinHostPoolSz, p_params->HostRecvPoolEntries );\r
+       POWER_OF_2( p_params->HostRecvPoolEntries );\r
+       POWER_OF_2( p_params->MinHostPoolSz );\r
+       POWER_OF_2( p_params->NotifyBundleSz );\r
+       LESS_THAN( p_params->NotifyBundleSz, p_params->MinEiocPoolSz );\r
+       LESS_THAN_OR_EQUAL( p_params->MinEiocPoolSz, p_params->MaxEiocPoolSz );\r
+       POWER_OF_2( p_params->MinEiocPoolSz );\r
+       POWER_OF_2( p_params->MaxEiocPoolSz );\r
+       LESS_THAN_OR_EQUAL( p_params->MinHostKickTimeout, p_params->MaxHostKickTimeout );\r
+       LESS_THAN_OR_EQUAL( p_params->MinHostKickEntries, p_params->MaxHostKickEntries );\r
+       LESS_THAN_OR_EQUAL( p_params->MinHostKickBytes, p_params->MaxHostKickBytes );\r
+       LESS_THAN_OR_EQUAL( p_params->MinHostUpdateSz, p_params->MaxHostUpdateSz );\r
+       POWER_OF_2( p_params->MinHostUpdateSz );\r
+       POWER_OF_2( p_params->MaxHostUpdateSz );\r
+       LESS_THAN( p_params->MinHostUpdateSz, p_params->MinHostPoolSz );\r
+       LESS_THAN( p_params->MaxHostUpdateSz, p_params->HostRecvPoolEntries );\r
+       LESS_THAN_OR_EQUAL( p_params->MinEiocUpdateSz, p_params->MaxEiocUpdateSz );\r
+       POWER_OF_2( p_params->MinEiocUpdateSz );\r
+       POWER_OF_2( p_params->MaxEiocUpdateSz );\r
+       LESS_THAN( p_params->MinEiocUpdateSz, p_params->MinEiocPoolSz );\r
+       LESS_THAN( p_params->MaxEiocUpdateSz, p_params->MaxEiocPoolSz );\r
+       LESS_THAN_OR_EQUAL( p_params->DefaultViportsPerNetpath, p_params->MaxViportsPerNetpath );\r
+\r
+       return TRUE;\r
 \r
 }\r
 NDIS_STATUS\r
@@ -428,26 +507,13 @@ vnic_get_adapter_params(
        status = NDIS_STATUS_FAILURE;\r
        p_reg_prm = NULL;\r
 \r
-       RtlInitUnicodeString( &keyword, L"DebugFlags" );\r
-\r
-       NdisReadConfiguration(\r
-               &status, &p_reg_prm, h_config, &keyword, NdisParameterInteger );\r
-       if( status == NDIS_STATUS_SUCCESS )\r
-                       g_vnic_dbg_lvl |= p_reg_prm->ParameterData.IntegerData;\r
-\r
-       RtlInitUnicodeString( &keyword, L"MinMtu" );\r
+       RtlInitUnicodeString( &keyword, L"PayloadMtu" );\r
        NdisReadConfiguration(\r
                &status, &p_reg_prm, h_config, &keyword, NdisParameterInteger );\r
 \r
        p_params->MinMtu = ( status != NDIS_STATUS_SUCCESS ) ? MIN_MTU:\r
                                                p_reg_prm->ParameterData.IntegerData;\r
-\r
-       RtlInitUnicodeString( &keyword, L"MaxMtu" );\r
-       NdisReadConfiguration(\r
-               &status, &p_reg_prm, h_config, &keyword, NdisParameterInteger );\r
-\r
-       p_params->MaxMtu =( status != NDIS_STATUS_SUCCESS )? MAX_MTU:\r
-                                               p_reg_prm->ParameterData.IntegerData;\r
+       p_params->MaxMtu = MAX_MTU;\r
 \r
        RtlInitUnicodeString( &keyword, L"UseRxCsum" );\r
        NdisReadConfiguration(\r
@@ -463,108 +529,104 @@ vnic_get_adapter_params(
        /* turn it on by default, if not present */\r
        p_params->UseTxCsum = ( status != NDIS_STATUS_SUCCESS ) ?\r
                TRUE : ( p_reg_prm->ParameterData.IntegerData )? TRUE : FALSE;\r
-\r
-       RtlInitUnicodeString( &keyword, L"MinEiocUpdateSz" );\r
-       NdisReadConfiguration(\r
-               &status, &p_reg_prm, h_config, &keyword, NdisParameterInteger );\r
-\r
-       p_params->MinEiocUpdateSz = ( status != NDIS_STATUS_SUCCESS ) ?\r
-                       MIN_EIOC_UPDATE_SZ : p_reg_prm->ParameterData.IntegerData;\r
-\r
-       RtlInitUnicodeString( &keyword, L"MaxEiocUpdateSz" );\r
-       NdisReadConfiguration(\r
-               &status, &p_reg_prm, h_config, &keyword, NdisParameterInteger );\r
-\r
-       p_params->MaxEiocUpdateSz = ( status != NDIS_STATUS_SUCCESS ) ?\r
-                       MAX_EIOC_UPDATE_SZ : p_reg_prm->ParameterData.IntegerData;\r
-\r
-       RtlInitUnicodeString( &keyword, L"MinHostUpdateSz" );\r
-       NdisReadConfiguration(\r
-               &status, &p_reg_prm, h_config, &keyword, NdisParameterInteger );\r
-\r
-       p_params->MinHostUpdateSz = ( status != NDIS_STATUS_SUCCESS ) ?\r
-                       MIN_HOST_UPDATE_SZ : p_reg_prm->ParameterData.IntegerData;\r
-\r
-       RtlInitUnicodeString( &keyword, L"MaxHostUpdateSz" );\r
-       NdisReadConfiguration(\r
-               &status, &p_reg_prm, h_config, &keyword, NdisParameterInteger );\r
-\r
-       p_params->MaxHostUpdateSz = ( status != NDIS_STATUS_SUCCESS ) ?\r
-                       MAX_HOST_UPDATE_SZ : p_reg_prm->ParameterData.IntegerData;\r
-\r
-       RtlInitUnicodeString( &keyword, L"MinHostKickBytes" );\r
-       NdisReadConfiguration(\r
-               &status, &p_reg_prm, h_config, &keyword, NdisParameterInteger );\r
-\r
-       p_params->MinHostKickBytes = ( status != NDIS_STATUS_SUCCESS ) ?\r
-                       MIN_HOST_KICK_BYTES : p_reg_prm->ParameterData.IntegerData;\r
-\r
-       RtlInitUnicodeString( &keyword, L"MaxHostKickBytes" );\r
-       NdisReadConfiguration(\r
-               &status, &p_reg_prm, h_config, &keyword, NdisParameterInteger );\r
-\r
-       p_params->MaxHostKickBytes = ( status != NDIS_STATUS_SUCCESS ) ?\r
-                       MAX_HOST_KICK_BYTES : p_reg_prm->ParameterData.IntegerData;\r
-\r
-       RtlInitUnicodeString( &keyword, L"MinHostKickEntries" );\r
+       \r
+       /* handle VLAN + Priority paramters */\r
+       RtlInitUnicodeString( &keyword, L"VlanId" );\r
        NdisReadConfiguration(\r
                &status, &p_reg_prm, h_config, &keyword, NdisParameterInteger );\r
 \r
-       p_params->MinHostKickEntries =  ( status != NDIS_STATUS_SUCCESS ) ?\r
-                       MIN_HOST_KICK_ENTRIES : p_reg_prm->ParameterData.IntegerData;\r
-\r
-       RtlInitUnicodeString( &keyword, L"MaxHostKickEntries" );\r
-       NdisReadConfiguration(\r
-               &status, &p_reg_prm, h_config, &keyword, NdisParameterInteger );\r
+       if( status == NDIS_STATUS_SUCCESS )\r
+       {\r
+               p_params->VlanInfo = \r
+                       ( p_reg_prm->ParameterData.IntegerData & 0x00000fff );\r
 \r
-       p_params->MaxHostKickEntries =  ( status != NDIS_STATUS_SUCCESS ) ?\r
-                       MAX_HOST_KICK_ENTRIES : p_reg_prm->ParameterData.IntegerData;\r
+               RtlInitUnicodeString( &keyword, L"UserPriority" );\r
+               NdisReadConfiguration(\r
+                       &status, &p_reg_prm, h_config, &keyword, NdisParameterInteger );\r
+       \r
+               p_params->VlanInfo |= ( status != NDIS_STATUS_SUCCESS ) ? 0 :\r
+               ( ( p_reg_prm->ParameterData.IntegerData & 0x00000007 ) << 13 );\r
+       }\r
+       else\r
+       {\r
+               p_params->VlanInfo = 0;\r
+       }\r
 \r
-       RtlInitUnicodeString( &keyword, L"MinHostKickTimeout" );\r
+       RtlInitUnicodeString( &keyword, L"SecondaryPath" );\r
        NdisReadConfiguration(\r
                &status, &p_reg_prm, h_config, &keyword, NdisParameterInteger );\r
 \r
-       p_params->MinHostKickTimeout =  ( status != NDIS_STATUS_SUCCESS ) ?\r
-                       MIN_HOST_KICK_TIMEOUT : p_reg_prm->ParameterData.IntegerData;\r
+       /* disable, if not set. Save extra viport slot */\r
+       p_params->SecondaryPath = ( status != NDIS_STATUS_SUCCESS ) ?\r
+               FALSE : ( p_reg_prm->ParameterData.IntegerData )? TRUE : FALSE;\r
 \r
-       RtlInitUnicodeString( &keyword, L"MaxHostKickTimeout" );\r
+       RtlInitUnicodeString( &keyword, L"Heartbeat" );\r
        NdisReadConfiguration(\r
                &status, &p_reg_prm, h_config, &keyword, NdisParameterInteger );\r
 \r
-       p_params->MaxHostKickTimeout =  ( status != NDIS_STATUS_SUCCESS ) ?\r
-                       MAX_HOST_KICK_TIMEOUT : p_reg_prm->ParameterData.IntegerData;\r
+       p_params->ViportHbInterval = ( status != NDIS_STATUS_SUCCESS ) ?\r
+               VIPORT_HEARTBEAT_INTERVAL : p_reg_prm->ParameterData.IntegerData;\r
 \r
-       RtlInitUnicodeString( &keyword, L"MinEiocPoolSz" );\r
-       NdisReadConfiguration(\r
-               &status, &p_reg_prm, h_config, &keyword, NdisParameterInteger );\r
+#if defined(LBFO_ENABLED)\r
+       /* read Failover group Name/Number */\r
 \r
-       p_params->MinEiocPoolSz =  ( status != NDIS_STATUS_SUCCESS ) ?\r
-                       MIN_EIOC_POOL_SZ : p_reg_prm->ParameterData.IntegerData;\r
-\r
-       RtlInitUnicodeString( &keyword, L"MaxEiocPoolSz" );\r
+       RtlInitUnicodeString( &keyword, L"BundleId" );\r
        NdisReadConfiguration(\r
                &status, &p_reg_prm, h_config, &keyword, NdisParameterInteger );\r
+       \r
+       p_params->bundle_id = ( status != NDIS_STATUS_SUCCESS ) ? 0 :\r
+       p_reg_prm->ParameterData.IntegerData;\r
+#endif // LBFO_ENABLED\r
 \r
-       p_params->MaxEiocPoolSz =  ( status != NDIS_STATUS_SUCCESS ) ?\r
-                       MAX_EIOC_POOL_SZ : p_reg_prm->ParameterData.IntegerData;\r
+       NdisCloseConfiguration( h_config );\r
+       \r
+       /* initialize the rest of  adapter parameters with driver's global set */\r
+       if( g_vnic.p_params != NULL )\r
+       {\r
+               /* get global parameters from service entry */\r
+               p_params->MinHostPoolSz = g_vnic.p_params[INDEX_MIN_HOST_POOL_SZ].value;\r
+               p_params->HostRecvPoolEntries = g_vnic.p_params[INDEX_HOST_RECV_POOL_ENTRIES].value;\r
 \r
-       RtlInitUnicodeString( &keyword, L"MinHostPoolSz" );\r
-       NdisReadConfiguration(\r
-               &status, &p_reg_prm, h_config, &keyword, NdisParameterInteger );\r
+               p_params->MinEiocPoolSz = g_vnic.p_params[INDEX_MIN_EIOC_POOL_SZ].value;\r
+               p_params->MaxEiocPoolSz = g_vnic.p_params[INDEX_MAX_EIOC_POOL_SZ].value;\r
 \r
-       p_params->MinHostPoolSz =  ( status != NDIS_STATUS_SUCCESS ) ?\r
-                       MIN_HOST_POOL_SZ : p_reg_prm->ParameterData.IntegerData;\r
+               p_params->MinHostKickTimeout = g_vnic.p_params[INDEX_MIN_HOST_KICK_TIMEOUT].value;\r
+               p_params->MaxHostKickTimeout = g_vnic.p_params[INDEX_MAX_HOST_KICK_TIMEOUT].value;\r
 \r
-       RtlInitUnicodeString( &keyword, L"HostRecvPoolEntries" );\r
-       NdisReadConfiguration(\r
-               &status, &p_reg_prm, h_config, &keyword, NdisParameterInteger );\r
+               p_params->MinHostKickEntries = g_vnic.p_params[INDEX_MIN_HOST_KICK_ENTRIES].value;\r
+               p_params->MaxHostKickEntries = g_vnic.p_params[INDEX_MAX_HOST_KICK_ENTRIES].value;\r
 \r
-       p_params->HostRecvPoolEntries =  ( status != NDIS_STATUS_SUCCESS ) ?\r
-                       HOST_RECV_POOL_ENTRIES : p_reg_prm->ParameterData.IntegerData;\r
+               p_params->MinHostKickBytes = g_vnic.p_params[INDEX_MIN_HOST_KICK_BYTES].value;\r
+               p_params->MaxHostKickBytes = g_vnic.p_params[INDEX_MAX_HOST_KICK_BYTES].value;\r
+       \r
+               p_params->MinHostUpdateSz = g_vnic.p_params[INDEX_MIN_HOST_UPDATE_SZ].value;\r
+               p_params->MaxHostUpdateSz = g_vnic.p_params[INDEX_MAX_HOST_UPDATE_SZ].value;\r
 \r
-       NdisCloseConfiguration( h_config );\r
+               p_params->MinEiocUpdateSz = g_vnic.p_params[INDEX_MIN_EIOC_UPDATE_SZ].value;\r
+               p_params->MaxEiocUpdateSz = g_vnic.p_params[INDEX_MAX_EIOC_UPDATE_SZ].value;\r
+               \r
+               p_params->ViportHbTimeout = g_vnic.p_params[INDEX_HEARTBEAT_TIMEOUT].value;\r
+       }\r
+       else\r
+       {\r
+               /* set default constants */\r
+               p_params->MinHostPoolSz = MIN_HOST_POOL_SZ;\r
+               p_params->HostRecvPoolEntries = HOST_RECV_POOL_ENTRIES;\r
+               p_params->MinEiocPoolSz = MIN_EIOC_POOL_SZ;\r
+               p_params->MaxEiocPoolSz = MAX_EIOC_POOL_SZ;\r
+               p_params->MinHostKickTimeout = MIN_HOST_KICK_TIMEOUT;\r
+               p_params->MaxHostKickTimeout = MAX_HOST_KICK_TIMEOUT;\r
+               p_params->MinHostKickEntries = MIN_HOST_KICK_ENTRIES;\r
+               p_params->MaxHostKickEntries = MAX_HOST_KICK_ENTRIES;\r
+               p_params->MinHostKickBytes = MIN_HOST_KICK_BYTES;\r
+               p_params->MaxHostKickBytes = MAX_HOST_KICK_BYTES;\r
+               p_params->MinHostUpdateSz = MIN_HOST_UPDATE_SZ;\r
+               p_params->MaxHostUpdateSz = MAX_HOST_UPDATE_SZ;\r
+               p_params->MinEiocUpdateSz = MIN_EIOC_UPDATE_SZ;\r
+               p_params->MaxEiocUpdateSz = MAX_EIOC_UPDATE_SZ;\r
+       }\r
 \r
-       status = ( _vnic_params_sanity_check(p_params)?\r
+       status = ( _adapter_params_sanity_check(p_params)?\r
                                NDIS_STATUS_SUCCESS: NDIS_STATUS_FAILURE );\r
 \r
        VNIC_EXIT( VNIC_DBG_ADAPTER );\r
@@ -572,17 +634,18 @@ vnic_get_adapter_params(
 }\r
 \r
 ib_api_status_t\r
-vnic_viport_allocate(\r
+adapter_viport_allocate(\r
        IN                      vnic_adapter_t* const           p_adapter,\r
        IN OUT          viport_t**              const           pp_viport )\r
 {\r
        viport_t        *p_viport;\r
        NDIS_STATUS      status;\r
+\r
        VNIC_ENTER( VNIC_DBG_ADAPTER );\r
 \r
        NdisAcquireSpinLock( &p_adapter->lock );\r
-       status = NdisAllocateMemoryWithTag( &p_viport, sizeof(viport_t), 'trop' );\r
 \r
+       status = NdisAllocateMemoryWithTag( &p_viport, sizeof(viport_t), 'trop' );\r
        if( status != NDIS_STATUS_SUCCESS )\r
        {\r
                NdisReleaseSpinLock( &p_adapter->lock );\r
@@ -592,79 +655,87 @@ vnic_viport_allocate(
        }\r
 \r
        NdisZeroMemory( p_viport, sizeof(viport_t) );\r
-\r
-       KeInitializeSpinLock( &p_viport->lock );\r
+       NdisAllocateSpinLock( &p_viport->lock );\r
        InitializeListHead( &p_viport->listPtrs );\r
-       InitializeListHead( &p_viport->send_pending_list );\r
-       NdisAllocateSpinLock(&p_viport->pending_list_lock );\r
-\r
-       KeInitializeEvent( &p_viport->conn_event, SynchronizationEvent, FALSE );\r
+       KeInitializeEvent( &p_viport->sync_event, SynchronizationEvent, FALSE );\r
 \r
        p_viport->p_adapter = p_adapter;\r
-\r
-       viport_get_adapter_name( p_viport );\r
-\r
        viport_config_defaults ( p_viport );\r
-       VNIC_TRACE( VNIC_DBG_PNP, ("Configure Viport default values\n") );\r
 \r
        control_construct( &p_viport->control, p_viport );\r
        data_construct( &p_viport->data, p_viport );\r
 \r
        p_viport->ioc_num = _get_ioc_num_from_iocguid( &p_adapter->ifc_data.guid );\r
-       p_adapter->ioc_num = p_viport->ioc_num;\r
+       if( !p_adapter->ioc_num )\r
+       {\r
+               p_adapter->ioc_num = p_viport->ioc_num;\r
+       }\r
+\r
+       CL_ASSERT( p_adapter->ioc_num == p_viport->ioc_num );\r
        \r
        *pp_viport = p_viport;\r
 \r
        NdisReleaseSpinLock( &p_adapter->lock );\r
+\r
        VNIC_EXIT( VNIC_DBG_ADAPTER );\r
        return IB_SUCCESS;\r
 }\r
+\r
+\r
 static void\r
-_vnic_viport_free(\r
-       IN       vnic_adapter_t* const          p_adapter )\r
+_adapter_netpath_free(\r
+       IN              vnic_adapter_t* const   p_adapter,\r
+       IN              Netpath_t*                              p_netpath )\r
 {\r
-       viport_t        *p_viport = p_adapter->p_viport;\r
-       VNIC_ENTER( VNIC_DBG_ADAPTER );\r
 \r
-       if ( p_viport )\r
+       UNREFERENCED_PARAMETER( p_adapter );\r
+\r
+       if( netpath_is_valid( p_netpath ) )\r
        {\r
-               p_adapter->p_viport = NULL;\r
-               NdisFreeMemory( p_viport, sizeof(viport_t), 0 );\r
-       }\r
-       p_adapter->state = INIC_UNINITIALIZED;\r
+               VNIC_TRACE( VNIC_DBG_INFO,\r
+                                       ("IOC[%d] instance %d Free Path\n",\r
+                                       p_adapter->ioc_num, p_netpath->instance ));\r
 \r
-       VNIC_EXIT( VNIC_DBG_ADAPTER );\r
+               netpath_free( p_netpath );\r
+               netpath_init( p_netpath, NULL );\r
+       }\r
 }\r
 \r
-\r
 NDIS_STATUS\r
-vnic_set_mcast(\r
+adapter_set_mcast(\r
        IN                              vnic_adapter_t* const           p_adapter,\r
        IN                              mac_addr_t* const                       p_mac_array,\r
        IN              const   uint8_t                                         mc_count )\r
 {\r
        NDIS_STATUS     status;\r
-\r
+       int i;\r
        VNIC_ENTER( VNIC_DBG_MCAST );\r
 \r
-       VNIC_TRACE( VNIC_DBG_INIT,\r
-               ("MCAST COUNT to set = %d\n", mc_count));\r
+       if( !netpath_is_valid( p_adapter->p_currentPath ) )\r
+               return NDIS_STATUS_NOT_ACCEPTED;\r
+\r
+       VNIC_TRACE( VNIC_DBG_MCAST,\r
+               ("IOC[%d] MCAST COUNT to set = %d\n", \r
+                                               p_adapter->ioc_num, mc_count));\r
+\r
        /* Copy the MC address list into the adapter. */\r
        if( mc_count )\r
        {\r
                RtlCopyMemory(\r
                        p_adapter->mcast_array, p_mac_array, mc_count * MAC_ADDR_LEN );\r
+               for( i = 0; i < mc_count; i++ )\r
+               VNIC_TRACE( VNIC_DBG_MCAST,\r
+                       ("[%d] %02x:%02x:%02x:%02x:%02x:%02x\n", i,\r
+                       p_mac_array->addr[0], p_mac_array->addr[1],     p_mac_array->addr[2],\r
+                       p_mac_array->addr[3], p_mac_array->addr[4],     p_mac_array->addr[5] ));\r
        }\r
        p_adapter->mc_count = mc_count;\r
 \r
-       if( !p_adapter->p_currentPath->pViport )\r
-               return NDIS_STATUS_SUCCESS;\r
-\r
-       ++p_adapter->pending_set;\r
-       status = viport_setMulticast( p_adapter->p_currentPath->pViport );\r
+       p_adapter->pending_set = TRUE;\r
+       status = netpath_setMulticast( p_adapter->p_currentPath );\r
        if( status != NDIS_STATUS_PENDING )\r
        {\r
-               --p_adapter->pending_set;\r
+               p_adapter->pending_set = FALSE;\r
        }\r
 \r
        VNIC_EXIT( VNIC_DBG_MCAST );\r
@@ -674,18 +745,30 @@ vnic_set_mcast(
 \r
 static BOOLEAN\r
 __path_records_match(\r
-       IN                      ib_path_rec_t           *p_path1,\r
-       IN                      ib_path_rec_t           *p_path2 )\r
+       IN                      ib_path_rec_t* const    p_path1,\r
+       IN                      ib_path_rec_t* const    p_path2 )\r
 {\r
-       if ( p_path1->dgid.unicast.prefix != p_path2->dgid.unicast.prefix )\r
+       if( p_path1->dgid.unicast.prefix != p_path2->dgid.unicast.prefix )\r
+               return FALSE;\r
+       if( p_path1->dgid.unicast.interface_id != p_path2->dgid.unicast.interface_id )\r
+               return FALSE;\r
+       if( p_path1->dlid != p_path2->dlid )\r
                return FALSE;\r
-       if ( p_path1->dgid.unicast.interface_id != p_path2->dgid.unicast.interface_id )\r
+\r
+       if( p_path1->sgid.unicast.prefix != p_path2->sgid.unicast.prefix )\r
+               return FALSE;\r
+       if( p_path1->sgid.unicast.interface_id != p_path2->sgid.unicast.interface_id )\r
+               return FALSE;\r
+       if( p_path1->slid != p_path2->slid )\r
+               return FALSE;\r
+\r
+       if( p_path1->pkey != p_path2->pkey )\r
                return FALSE;\r
-       if ( p_path1->dlid != p_path2->dlid )\r
+       if( p_path1->rate != p_path2->rate )\r
                return FALSE;\r
-       if ( p_path1->pkey != p_path2->pkey )\r
+       if( p_path1->sl != p_path2->sl )\r
                return FALSE;\r
-       if ( p_path1->rate != p_path2->rate )\r
+       if( p_path1->tclass != p_path2->tclass )\r
                return FALSE;\r
 \r
        return TRUE;\r
@@ -718,40 +801,146 @@ _get_ioc_num_from_iocguid(
        return ( (vnic_ioc_guid_t *)p_iocguid)->s.ioc_num;\r
 }\r
 \r
-static ib_api_status_t\r
+static\r
+vnic_path_record_t*\r
 __path_record_add(\r
-       IN                              vnic_adapter_t          *p_adapter,\r
-       IN                              ib_path_rec_t           *p_path_rec )\r
+       IN                              vnic_adapter_t* const   p_adapter,\r
+       IN                              ib_path_rec_t* const    p_path_rec )\r
 {\r
 \r
-       NdisAcquireSpinLock( &p_adapter->lock );\r
+       vnic_path_record_t              *p_path;\r
+\r
+       p_path = __path_record_find( p_adapter, p_path_rec );\r
 \r
-       if ( !__path_records_match( &p_adapter->path_record.path_rec, p_path_rec ) )\r
+       if( !p_path )\r
        {\r
-                       p_adapter->path_record.path_rec = *p_path_rec;\r
-                       p_adapter->path_record.num_entries++;\r
+               p_path = cl_zalloc( sizeof( vnic_path_record_t ) );\r
+               if( !p_path )\r
+                       return NULL;\r
+\r
+               NdisAcquireSpinLock( &p_adapter->path_records_lock );\r
+               \r
+               p_path->path_rec = *p_path_rec;\r
+               cl_qlist_insert_tail( &p_adapter->path_records_list, &p_path->list_entry );\r
+\r
+               NdisReleaseSpinLock( &p_adapter->path_records_lock );\r
+\r
+               VNIC_TRACE( VNIC_DBG_PNP,\r
+                       ("New path Added to the list[ list size %d]\n", \r
+                               cl_qlist_count(&p_adapter->path_records_list) ));\r
+               \r
+               return p_path;\r
        }\r
+       VNIC_TRACE( VNIC_DBG_PNP,\r
+                       ( "Path to add is already on the List\n" ) );\r
 \r
-       NdisReleaseSpinLock( &p_adapter->lock );\r
-       return IB_SUCCESS;\r
+       return NULL;\r
 }\r
 \r
-static ib_api_status_t\r
+static\r
+vnic_path_record_t*\r
+__path_record_get(\r
+       IN                              vnic_adapter_t* const   p_adapter )\r
+{\r
+       cl_list_item_t          *p_item;\r
+\r
+       p_item = cl_qlist_head( &p_adapter->path_records_list );\r
+\r
+       if( p_item != cl_qlist_end( &p_adapter->path_records_list ) )\r
+       {\r
+               return ( vnic_path_record_t *)p_item;\r
+       }\r
+       return NULL;\r
+}\r
+\r
+static \r
+vnic_path_record_t*\r
 __path_record_remove(\r
-               IN                      vnic_adapter_t          *p_adapter,\r
-               IN                      ib_path_rec_t           *p_path_rec )\r
+               IN                      vnic_adapter_t* const   p_adapter,\r
+               IN                      ib_path_rec_t* const    p_path_rec )\r
 {\r
 \r
-       NdisAcquireSpinLock( &p_adapter->lock );\r
+       vnic_path_record_t      *p_path;\r
 \r
-       if ( __path_records_match( &p_adapter->path_record.path_rec, p_path_rec ) )\r
+\r
+       p_path = __path_record_find( p_adapter, p_path_rec );\r
+\r
+       if ( p_path )\r
        {\r
-               --p_adapter->path_record.num_entries;\r
-               cl_memclr( &p_adapter->path_record.path_rec, sizeof( ib_path_rec_t ));\r
+               NdisAcquireSpinLock( &p_adapter->path_records_lock );\r
+\r
+               cl_qlist_remove_item( &p_adapter->path_records_list, &p_path->list_entry );\r
+\r
+               NdisReleaseSpinLock( &p_adapter->path_records_lock );\r
        }\r
+       \r
+       return p_path;\r
+}\r
 \r
-       NdisReleaseSpinLock( &p_adapter->lock );\r
-       return IB_SUCCESS;\r
+static\r
+vnic_path_record_t *\r
+__path_record_find( \r
+       IN              vnic_adapter_t* const   p_adapter,\r
+       IN              ib_path_rec_t* const    p_path_rec )\r
+{\r
+       cl_list_item_t          *p_item;\r
+       vnic_path_record_t      *p_path = NULL;\r
+\r
+       NdisAcquireSpinLock( &p_adapter->path_records_lock );\r
+\r
+       if( !cl_qlist_count( &p_adapter->path_records_list ) )\r
+       {\r
+               NdisReleaseSpinLock( &p_adapter->path_records_lock );\r
+               return NULL;\r
+       }\r
+       \r
+       p_item = cl_qlist_head( &p_adapter->path_records_list );\r
+\r
+       while( p_item != cl_qlist_end( &p_adapter->path_records_list ) )\r
+       {\r
+               p_path = ( vnic_path_record_t *)p_item;\r
+               \r
+               if ( __path_records_match( &p_path->path_rec, p_path_rec ) )\r
+               {\r
+                       break;\r
+               }\r
+\r
+               p_item = cl_qlist_next( p_item );\r
+       }\r
+\r
+       NdisReleaseSpinLock( &p_adapter->path_records_lock );\r
+\r
+       if( p_item == cl_qlist_end( &p_adapter->path_records_list ) )\r
+       {\r
+               p_path = NULL;\r
+       }\r
+       return p_path;\r
+}\r
+\r
+void\r
+__pending_queue_cleanup( \r
+       IN              vnic_adapter_t  *p_adapter )\r
+{\r
+       LIST_ENTRY              *p_list_item;\r
+       NDIS_PACKET             *p_packet;\r
+\r
+       VNIC_ENTER( VNIC_DBG_ADAPTER );\r
+\r
+       /* clear pending queue if any */\r
+\r
+       while( ( p_list_item = NdisInterlockedRemoveHeadList(\r
+               &p_adapter->send_pending_list,\r
+               &p_adapter->pending_list_lock )) != NULL )\r
+       {\r
+               p_packet = VNIC_PACKET_FROM_LIST_ITEM( p_list_item );\r
+               if ( p_packet )\r
+               {\r
+                       NDIS_SET_PACKET_STATUS( p_packet, NDIS_STATUS_FAILURE );\r
+                       NdisMSendComplete( p_adapter->h_handle, p_packet, NDIS_STATUS_FAILURE );\r
+               }\r
+       }\r
+\r
+       VNIC_EXIT( VNIC_DBG_ADAPTER );\r
 }\r
 \r
 static void\r
@@ -759,14 +948,23 @@ __path_records_cleanup(
                   vnic_adapter_t       *p_adapter )\r
 {\r
 \r
-       NdisAcquireSpinLock( &p_adapter->lock );\r
+       vnic_path_record_t      *p_path;\r
+       cl_list_item_t  *p_item;\r
 \r
-       cl_memclr( &p_adapter->path_record.path_rec, sizeof( ib_path_rec_t ));\r
-       p_adapter->path_record.num_entries = 0;\r
+       p_item = cl_qlist_remove_head( &p_adapter->path_records_list );\r
 \r
-       NdisReleaseSpinLock( &p_adapter->lock );\r
+       while( p_item != cl_qlist_end( &p_adapter->path_records_list ) )\r
+       {\r
+               p_path = (vnic_path_record_t *)p_item;\r
+\r
+               cl_free( p_path );\r
+\r
+               p_item = cl_qlist_remove_head( &p_adapter->path_records_list );\r
+       }\r
+       \r
        return;\r
 }\r
+\r
 ib_api_status_t\r
 __vnic_pnp_cb(\r
        IN              ib_pnp_rec_t                *p_pnp_rec )\r
@@ -774,6 +972,12 @@ __vnic_pnp_cb(
        ib_api_status_t                 ib_status = IB_SUCCESS;\r
        ib_pnp_ioc_rec_t                *p_ioc_rec;\r
        ib_pnp_ioc_path_rec_t   *p_ioc_path;\r
+       vnic_path_record_t              *p_path_record;\r
+       Netpath_t*                              p_netpath = NULL;\r
+\r
+#if defined( LBFO_ENABLED )\r
+       vnic_adapter_t                  *p_primary_adapter;     \r
+#endif\r
 \r
        vnic_adapter_t * __ptr64 p_adapter = (vnic_adapter_t * __ptr64)p_pnp_rec->pnp_context;\r
        \r
@@ -786,61 +990,47 @@ __vnic_pnp_cb(
                case IB_PNP_IOC_ADD:\r
                        p_ioc_rec = (ib_pnp_ioc_rec_t*)p_pnp_rec;\r
 \r
-                       VNIC_TRACE( VNIC_DBG_PNP, ("IB_PNP_IOC_ADD for %s.\n", p_ioc_rec->info.profile.id_string) );\r
-\r
                        if( p_adapter->ifc_data.ca_guid != p_ioc_rec->ca_guid )\r
                        {\r
-                               VNIC_TRACE_EXIT( VNIC_DBG_WARN, ("Invalid CA GUID.\n") );\r
                                ib_status = IB_INVALID_GUID;\r
                                break;\r
                        }\r
                        if( p_adapter->ifc_data.guid != p_ioc_rec->info.profile.ioc_guid )\r
                        {\r
-                               VNIC_TRACE_EXIT( VNIC_DBG_WARN, ("Invalid IOC GUID.\n") );\r
                                ib_status = IB_INVALID_GUID;\r
                                break;\r
                        }\r
+                       InterlockedExchange( (volatile LONG*)&p_adapter->pnp_state, IB_PNP_IOC_ADD );\r
+\r
+                       VNIC_TRACE( VNIC_DBG_PNP, ("IB_PNP_IOC_ADD for %s.\n",\r
+                               p_ioc_rec->info.profile.id_string) );\r
+\r
                        /* get ioc profile data */\r
                        NdisAcquireSpinLock( &p_adapter->lock );\r
                \r
-                       InterlockedExchange( (volatile LONG*)&p_adapter->pnp_state, IB_PNP_IOC_ADD );\r
-               \r
-                       p_adapter->ioc_info = p_ioc_rec->info;\r
-                       p_adapter->num_svc_entries = p_ioc_rec->info.profile.num_svc_entries;\r
-               \r
-                       CL_ASSERT(p_adapter->num_svc_entries >= 2 );\r
-\r
                        if( !__sid_valid( p_adapter, p_ioc_rec->svc_entry_array[0].id ) )\r
                        {\r
                                NdisReleaseSpinLock( &p_adapter->lock );\r
 \r
-                               VNIC_TRACE_EXIT( VNIC_DBG_WARN,\r
+                               VNIC_TRACE_EXIT( VNIC_DBG_ERROR,\r
                                        ("Invalid Service ID %#I64x\n",p_ioc_rec->svc_entry_array[0].id ) );\r
 \r
                                ib_status = IB_INVALID_GUID; // should it be set INVALID_SERVICE_TYPE ?\r
                                break;\r
                        }\r
 \r
-                       p_adapter->p_svc_entries =\r
-                                       cl_zalloc( sizeof(ib_svc_entry_t) *\r
-                                       p_adapter->ioc_info.profile.num_svc_entries );\r
-\r
-                       if( p_adapter->p_svc_entries == NULL )\r
-                       {\r
-                               NdisReleaseSpinLock( &p_adapter->lock );\r
-\r
-                               VNIC_TRACE_EXIT( VNIC_DBG_ERROR, ("Insufficient Memory.\n") );\r
-                               ib_status = IB_INSUFFICIENT_MEMORY;\r
-                               break;\r
-                       }\r
-\r
-                       cl_memcpy( p_adapter->p_svc_entries,\r
-                                               p_ioc_rec->svc_entry_array,\r
-                                               sizeof(ib_svc_entry_t) * p_adapter->ioc_info.profile.num_svc_entries);\r
+                       p_adapter->ioc_info = p_ioc_rec->info;\r
+                       CL_ASSERT(p_adapter->ioc_info.profile.num_svc_entries == 2 );\r
+                       \r
+                       p_adapter->svc_entries[0] = p_ioc_rec->svc_entry_array[0];\r
+                       p_adapter->svc_entries[1] = p_ioc_rec->svc_entry_array[1];\r
+                       p_adapter->ioc_num = _get_ioc_num_from_iocguid( &p_adapter->ifc_data.guid );\r
 \r
                        VNIC_TRACE( VNIC_DBG_PNP,\r
                                ("Found %d Service Entries.\n", p_adapter->ioc_info.profile.num_svc_entries));\r
+\r
                        NdisReleaseSpinLock( &p_adapter->lock );\r
+                       \r
                        break;\r
 \r
                case IB_PNP_IOC_REMOVE:\r
@@ -848,12 +1038,28 @@ __vnic_pnp_cb(
                \r
                        p_ioc_rec = (ib_pnp_ioc_rec_t*)p_pnp_rec;\r
 \r
-                       InterlockedExchange( (volatile LONG*)&p_adapter->pnp_state, IB_PNP_IOC_REMOVE );\r
-               \r
-                       VNIC_TRACE( VNIC_DBG_PNP, ("IB_PNP_IOC_REMOVE for %s.\n",\r
+                       if( InterlockedExchange( (volatile LONG*)&p_adapter->pnp_state, IB_PNP_IOC_REMOVE ) == IB_PNP_IOC_ADD )\r
+                       {\r
+                               VNIC_TRACE( VNIC_DBG_INIT, ("IB_PNP_IOC_REMOVE for %s.\n",\r
                                                        p_adapter->ioc_info.profile.id_string) );\r
-               \r
-                       viport_linkDown( p_adapter->p_viport );\r
+                       \r
+                               if( netpath_is_valid( p_adapter->p_currentPath ) )\r
+                               {\r
+                                       netpath_stopXmit( p_adapter->p_currentPath );\r
+                                       InterlockedExchange( &p_adapter->p_currentPath->carrier, (LONG)FALSE );\r
+                                       netpath_linkDown( p_adapter->p_currentPath );\r
+                                       __pending_queue_cleanup( p_adapter );\r
+                               }\r
+                               /*\r
+                               if( p_adapter->p_currentPath == &p_adapter->primaryPath )\r
+                                       p_netpath = &p_adapter->secondaryPath;\r
+                               else\r
+                                       p_netpath = &p_adapter->primaryPath;\r
+\r
+                               netpath_free( p_adapter->p_currentPath );\r
+                               netpath_free( p_netpath );\r
+                               */\r
+                       }\r
                        break;\r
 \r
                case IB_PNP_IOC_PATH_ADD:\r
@@ -867,55 +1073,69 @@ __vnic_pnp_cb(
                        }\r
                        p_ioc_path = (ib_pnp_ioc_path_rec_t*)p_pnp_rec;\r
 \r
-                       if( p_adapter->state != INIC_UNINITIALIZED )\r
-                               break;\r
-\r
-                       ib_status = __path_record_add( p_adapter, &p_ioc_path->path );\r
-                       if ( ib_status != IB_SUCCESS )\r
+                       p_path_record = __path_record_add( p_adapter, &p_ioc_path->path );\r
+                       if ( p_path_record == NULL )\r
                        {\r
                                VNIC_TRACE( VNIC_DBG_ERROR,\r
                                        ("Failed to add path record\n") );\r
                                break;\r
                        }\r
 \r
-                       netpath_init( &p_adapter->primaryPath, p_adapter );\r
-                       p_adapter->p_currentPath = &p_adapter->primaryPath;\r
-\r
-                       ib_status = vnic_viport_allocate( p_adapter, &p_adapter->p_viport );\r
-\r
-                       if( ib_status != IB_SUCCESS )\r
+                       if( p_adapter->state == INIC_REGISTERED )\r
                        {\r
-                               VNIC_TRACE ( VNIC_DBG_ERROR,\r
-                                                       ("Failed status %s\n", p_adapter->ifc.get_err_str( ib_status )) );\r
-                               _vnic_viport_free( p_adapter );\r
-                               return ib_status;\r
+                               if(     p_adapter->num_paths > 0 )\r
+                               {\r
+                                       if( p_adapter->params.SecondaryPath != TRUE )\r
+                                       {\r
+                                               VNIC_TRACE ( VNIC_DBG_WARN,\r
+                                               ("Allowed one path at a time\n") );\r
+                                               break;\r
+                                       }\r
+                               }\r
+\r
+                               if( p_adapter->num_paths > 1 )\r
+                               {\r
+                                       VNIC_TRACE ( VNIC_DBG_WARN,\r
+                                       ("Max Paths[%d] Connected already\n", p_adapter->num_paths) );\r
+                                       break;\r
+                               }\r
                        }\r
-               \r
-                       netpath_addPath( p_adapter->p_currentPath, p_adapter->p_viport );\r
-                       viport_setPath( p_adapter->p_viport,\r
-                                                       &p_adapter->path_record.path_rec,\r
-                                                       &p_adapter->ioc_info.profile.ioc_guid );\r
-               \r
-                       ib_status = viport_control_connect( p_adapter->p_viport );\r
+                       \r
+                       ib_status = adapter_netpath_update_and_connect( \r
+                                                                                               p_adapter, p_path_record );\r
                        if( ib_status != IB_SUCCESS )\r
                        {\r
                                VNIC_TRACE( VNIC_DBG_ERROR,\r
-                                               ("Control connect return %s\n", p_adapter->ifc.get_err_str( ib_status )) );\r
-                               vnic_viport_cleanup( p_adapter );\r
+                                       ("IOC[%d] adapter_netpath_update_and_connect return %s\n",      \r
+                                       p_adapter->ioc_num,\r
+                                       p_adapter->ifc.get_err_str( ib_status )) );\r
                                break;\r
                        }\r
 \r
-                       ib_status = viport_data_connect( p_adapter->p_viport );\r
-                       if( ib_status != IB_SUCCESS )\r
+                       if( ( InterlockedCompareExchange( (volatile LONG *)&p_adapter->state,   \r
+                                               INIC_REGISTERED, INIC_UNINITIALIZED ) == INIC_UNINITIALIZED )\r
+#if defined( LBFO_ENABLED )\r
+                                               || ( p_adapter->failover.fo_state == _ADAPTER_NOT_BUNDLED )\r
+#endif\r
+                               )\r
                        {\r
-                               VNIC_TRACE( VNIC_DBG_ERROR,\r
-                                       ("Data path connect failed status %s\n",\r
-                                       p_adapter->ifc.get_err_str( ib_status )) );\r
-                               vnic_viport_cleanup( p_adapter );\r
-                               break;\r
+#if defined( LBFO_ENABLED )\r
+                               /* we don't look for zero id, since it meant to be primary by default */\r
+                               if( p_adapter->failover.bundle_id != 0 && \r
+                                       ( p_primary_adapter = __adapter_find_on_failover_list( _ADAPTER_PRIMARY,\r
+                                         p_adapter->failover.bundle_id ) ) != NULL )\r
+                               {\r
+                                               /* found matching primary */\r
+                                               __adapter_set_failover_secondary(\r
+                                                               p_adapter, p_primary_adapter->h_handle );\r
+                               }\r
+                               else\r
+                               {\r
+                                       /* bundle_id '0' , all go to primary */\r
+                                       __adapter_set_failover_primary( p_adapter, FALSE );\r
+                               }\r
+#endif // LBFO_ENABLED\r
                        }\r
-\r
-                       p_adapter->state = INIC_REGISTERED;\r
                        break;\r
 \r
                case IB_PNP_IOC_PATH_REMOVE:\r
@@ -927,13 +1147,87 @@ __vnic_pnp_cb(
                                ntoh16( p_ioc_path->path.dlid ),\r
                                p_adapter->ioc_info.profile.id_string));\r
 \r
-                       ib_status = __path_record_remove( p_adapter, &p_ioc_path->path );\r
-               \r
-                       if ( ib_status != IB_SUCCESS )\r
+                       p_path_record = __path_record_remove( p_adapter, &p_ioc_path->path );\r
+\r
+                       if ( p_path_record != NULL )\r
                        {\r
+                               int fail_over = 0;\r
+\r
+                               if( p_adapter->p_currentPath->p_path_rec != &p_path_record->path_rec )\r
+                               {\r
+                                       VNIC_TRACE( VNIC_DBG_INFO,\r
+                                               ("IOC[%d] Standby Path lost\n", p_adapter->ioc_num ));\r
+\r
+                                       if( p_adapter->p_currentPath !=  &p_adapter->primaryPath )\r
+                                       {\r
+                                               _adapter_netpath_free( p_adapter,  &p_adapter->primaryPath );\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               _adapter_netpath_free( p_adapter, &p_adapter->secondaryPath );\r
+                                       }\r
+\r
+                                       cl_free( p_path_record );\r
+                                       break;\r
+                               }\r
+\r
                                VNIC_TRACE( VNIC_DBG_ERROR,\r
-                                       ("Failed to remove path record\n") );\r
+                                       ("IOC[%d]Current Path lost\n", p_adapter->ioc_num ));\r
+                               \r
+                               p_netpath = p_adapter->p_currentPath;\r
+                               netpath_stopXmit( p_netpath );\r
+                               viport_timerStop( p_netpath->pViport );\r
+\r
+                               if( !p_adapter->params.SecondaryPath )\r
+                               {\r
+                                       vnic_path_record_t* p_record;\r
+\r
+                                       netpath_linkDown( p_netpath );\r
+                                       _adapter_netpath_free(p_adapter, p_netpath );\r
+\r
+                                       p_record = __path_record_get( p_adapter );\r
+                                       if( p_record )\r
+                                       {\r
+                                               ib_status = adapter_netpath_update_and_connect( p_adapter, p_record );\r
+                                       }\r
+                                       \r
+                                       cl_free( p_path_record );\r
+                                       break;\r
+                               }\r
+\r
+                               if( p_netpath == &p_adapter->primaryPath )\r
+                               {\r
+                                       if( netpath_is_connected( &p_adapter->secondaryPath ) )\r
+                                       {\r
+                                               netpath_stopXmit( &p_adapter->secondaryPath );\r
+                                               p_adapter->p_currentPath = &p_adapter->secondaryPath;\r
+                                               fail_over = 1;\r
+                                               VNIC_TRACE( VNIC_DBG_ERROR,\r
+                                                       ("IOC[%d]Switch to Secondary Path\n", p_adapter->ioc_num ));\r
+                                       }\r
+                               }\r
+                               else\r
+                               {\r
+                                       if( netpath_is_connected( &p_adapter->primaryPath ) )\r
+                                       {\r
+                                               netpath_stopXmit( &p_adapter->primaryPath );\r
+                                               p_adapter->p_currentPath = &p_adapter->primaryPath;\r
+                                               fail_over = 1;\r
+                                               VNIC_TRACE( VNIC_DBG_ERROR,\r
+                                                       ("IOC[%d]Switch to Primary Path\n", p_adapter->ioc_num ));\r
+                                       }\r
+                               }\r
+                               if( fail_over )\r
+                               {\r
+                                       viport_setLink( p_adapter->p_currentPath->pViport,\r
+                                                               INIC_FLAG_ENABLE_NIC| INIC_FLAG_SET_MTU,\r
+                                                               (uint16_t)p_adapter->params.MinMtu, FALSE );\r
+                               }\r
+\r
+                               _adapter_netpath_free(p_adapter, p_netpath );\r
+                               cl_free( p_path_record );\r
                        }\r
+\r
                        break;\r
 \r
                default:\r
@@ -994,26 +1288,16 @@ vnic_get_adapter_interface(
 }\r
 \r
 \r
-void\r
-vnic_viport_cleanup(\r
+static void\r
+__adapter_cleanup(\r
                IN      vnic_adapter_t          *p_adapter )\r
 {\r
-       VNIC_ENTER( VNIC_DBG_ADAPTER );\r
+       __pending_queue_cleanup( p_adapter );\r
 \r
-       if ( p_adapter->p_viport )\r
-       {\r
-               if( ( InterlockedExchange( (volatile LONG *)&p_adapter->state,\r
-                                                       INIC_DEREGISTERING )) == INIC_DEREGISTERING )\r
-               {\r
-                       VNIC_TRACE(VNIC_DBG_INIT,\r
-                                       ("vnic viport cleanup - already destroying\n" ));\r
-                       return;\r
-               }\r
-               viport_timerStop( p_adapter->p_viport );\r
-               InterlockedExchange( (volatile LONG *)&p_adapter->p_viport->disconnect, TRUE );\r
-               viport_cleanup(p_adapter->p_viport );\r
-       }\r
-       p_adapter->p_viport = NULL;\r
+       __path_records_cleanup( p_adapter );\r
+\r
+       _adapter_netpath_free( p_adapter, &p_adapter->primaryPath );\r
+       _adapter_netpath_free( p_adapter, &p_adapter->secondaryPath );\r
 \r
        VNIC_EXIT( VNIC_DBG_ADAPTER );\r
 }\r
@@ -1024,9 +1308,9 @@ __vnic_pnp_dereg_cb(
 {\r
        vnic_adapter_t*         p_adapter;\r
        ib_api_status_t         ib_status;\r
-       ib_pnp_event_t          state;\r
        ib_pnp_req_t            pnp_req;\r
-       viport_t                        *p_viport;\r
+\r
+       NDIS_STATUS                     ndis_status = NDIS_STATUS_SUCCESS;\r
 \r
        VNIC_ENTER( VNIC_DBG_INIT );\r
 \r
@@ -1034,43 +1318,36 @@ __vnic_pnp_dereg_cb(
 \r
        CL_ASSERT( !p_adapter->h_pnp );\r
 \r
+       /* Destroy port instances if still exist. */\r
+       __adapter_cleanup( p_adapter );\r
+       \r
        if( p_adapter->pnp_state != IB_PNP_IOC_REMOVE )\r
-               p_adapter->pnp_state = IB_PNP_IOC_ADD;\r
-\r
-       state = p_adapter->pnp_state;\r
-\r
-       /* Destroy the current port instance if it still exists. */\r
-       p_viport = InterlockedExchangePointer( (void *)&p_adapter->p_viport, NULL );\r
-\r
-       if( p_viport )\r
        {\r
-               viport_cleanup( p_viport );\r
-       }\r
 \r
-       if( state != IB_PNP_IOC_REMOVE )\r
-       {\r
                /* Register for IOC events */\r
                pnp_req.pfn_pnp_cb = __vnic_pnp_cb;\r
                pnp_req.pnp_class = IB_PNP_IOC | IB_PNP_FLAG_REG_SYNC;\r
-               pnp_req.pnp_context = p_adapter;\r
+               pnp_req.pnp_context = (const void *)p_adapter;\r
 \r
                ib_status = p_adapter->ifc.reg_pnp( p_adapter->h_al, &pnp_req, &p_adapter->h_pnp );\r
                if( ib_status != IB_SUCCESS )\r
                {\r
-                       p_adapter->reset = FALSE;\r
                        VNIC_TRACE( VNIC_DBG_ERROR,\r
                                                ("pnp_reg returned %s\n",\r
                                                                p_adapter->ifc.get_err_str( ib_status )) );\r
-                       NdisMResetComplete( \r
-                               p_adapter->h_handle, NDIS_STATUS_HARD_ERRORS, TRUE );\r
+                       ndis_status = NDIS_STATUS_HARD_ERRORS;\r
                }\r
        }\r
        else\r
+       {\r
+               ndis_status = NDIS_STATUS_HARD_ERRORS;\r
+       }\r
+\r
+       if( p_adapter->reset )\r
        {\r
                p_adapter->reset = FALSE;\r
-               NdisMResetComplete(\r
-                                       p_adapter->h_handle, NDIS_STATUS_SUCCESS, TRUE );\r
-               ib_status = IB_SUCCESS;\r
+               NdisMResetComplete( \r
+                       p_adapter->h_handle, ndis_status, TRUE );\r
        }\r
 \r
        VNIC_EXIT( VNIC_DBG_INIT );\r
@@ -1078,43 +1355,465 @@ __vnic_pnp_dereg_cb(
 \r
 \r
 ib_api_status_t\r
-vnic_reset_adapter(\r
+adapter_reset(\r
           IN   vnic_adapter_t* const   p_adapter )\r
 {\r
 \r
        ib_api_status_t         status;\r
        ib_pnp_handle_t         h_pnp;\r
-       ib_pnp_req_t            pnp_req;\r
 \r
        VNIC_ENTER( VNIC_DBG_INIT );\r
 \r
        if( p_adapter->reset )\r
                return IB_INVALID_STATE;\r
 \r
-       p_adapter->hung = 0;\r
        p_adapter->reset = TRUE;\r
 \r
+       __adapter_remove_from_failover_list( p_adapter );\r
+\r
        if( p_adapter->h_pnp )\r
        {\r
                h_pnp = p_adapter->h_pnp;\r
                p_adapter->h_pnp  = NULL;\r
+\r
+               p_adapter->hung = 0;\r
                status = p_adapter->ifc.dereg_pnp( h_pnp, __vnic_pnp_dereg_cb );\r
-               if( status == IB_SUCCESS )\r
-                       status = IB_NOT_DONE;\r
        }\r
        else\r
        {\r
-               /* Register for IOC events */\r
-               pnp_req.pfn_pnp_cb = __vnic_pnp_cb;\r
-               pnp_req.pnp_class = IB_PNP_IOC | IB_PNP_FLAG_REG_SYNC;\r
-               pnp_req.pnp_context = p_adapter;\r
+               status = IB_NOT_FOUND;\r
+       }\r
+\r
+       if( status == IB_SUCCESS )\r
+               status = IB_NOT_DONE;\r
+\r
+       VNIC_EXIT( VNIC_DBG_INIT );\r
+       return status;\r
+}\r
+\r
+static\r
+NDIS_STATUS\r
+_adapter_set_sg_size(\r
+                IN             NDIS_HANDLE             h_handle,\r
+                IN             ULONG                   mtu_size )\r
+{\r
+       NDIS_STATUS             status;\r
+       ULONG                   buf_size;\r
+\r
+       VNIC_ENTER( VNIC_DBG_INIT );\r
+\r
+       buf_size = mtu_size + ETH_VLAN_HLEN;\r
+\r
+       status = NdisMInitializeScatterGatherDma( h_handle, TRUE, buf_size );\r
+\r
+       if ( status != NDIS_STATUS_SUCCESS )\r
+       {\r
+               VNIC_TRACE( VNIC_DBG_ERROR,\r
+                       ("Init ScatterGatherDma failed status %#x\n", status ) );\r
+       }\r
+\r
+       VNIC_EXIT( VNIC_DBG_INIT );\r
+       return status;\r
+}\r
+\r
+static ib_api_status_t\r
+_adapter_close_ca(\r
+               IN              vnic_adapter_t* const   p_adapter )\r
+{\r
+       ib_api_status_t         ib_status = IB_SUCCESS;\r
+       ib_ca_handle_t          h_ca;\r
+\r
+       VNIC_ENTER( VNIC_DBG_INIT );\r
 \r
-               status = p_adapter->ifc.reg_pnp( p_adapter->h_al, &pnp_req, &p_adapter->h_pnp );\r
-               if( status == IB_SUCCESS )\r
+       if( !p_adapter )\r
+               return ib_status;\r
+\r
+       VNIC_TRACE(VNIC_DBG_INIT,\r
+               ("IOC[%d] Close CA\n", p_adapter->ioc_num ));\r
+\r
+       if( p_adapter->ca.region.h_mr )\r
+       {\r
+               ib_status = p_adapter->ifc.dereg_mr( p_adapter->ca.region.h_mr );\r
+               if( ib_status != IB_SUCCESS )\r
+               {\r
+                       VNIC_TRACE( VNIC_DBG_ERROR,\r
+                               ("Failed to dereg MR\n"));\r
+               }\r
+               p_adapter->ca.region.h_mr = NULL;\r
+       }\r
+\r
+       if( p_adapter->ca.hPd )\r
+       {\r
+               ib_status = p_adapter->ifc.dealloc_pd( p_adapter->ca.hPd, NULL );\r
+               if( ib_status != IB_SUCCESS )\r
+               {\r
+                       VNIC_TRACE( VNIC_DBG_ERROR,\r
+                               ("Failed to dealloc PD\n"));\r
+               }\r
+               p_adapter->ca.hPd = NULL;\r
+       }\r
+\r
+       if( ( h_ca = InterlockedExchangePointer( (void *)&p_adapter->h_ca, NULL ) ) != NULL )\r
+       {\r
+\r
+               ib_status = p_adapter->ifc.close_ca( h_ca, NULL );\r
+               if( ib_status != IB_SUCCESS )\r
                {\r
-                       p_adapter->hung = FALSE;\r
+                       VNIC_TRACE( VNIC_DBG_ERROR,\r
+                               ("Failed to close CA\n"));\r
                }\r
        }\r
+\r
        VNIC_EXIT( VNIC_DBG_INIT );\r
+       return ib_status;\r
+}\r
+\r
+static \r
+ib_api_status_t\r
+_adapter_netpath_update(\r
+       IN              vnic_adapter_t* const   p_adapter,\r
+       IN              viport_t* const                 p_viport,\r
+       IN              vnic_path_record_t*             p_path )\r
+{\r
+\r
+       Netpath_t                       *p_netpath_init;\r
+\r
+       VNIC_ENTER( VNIC_DBG_PNP );\r
+\r
+       NdisAcquireSpinLock( &p_adapter->lock );\r
+       /* set primary first */\r
+       if( !netpath_is_valid( p_adapter->p_currentPath ) )\r
+       {\r
+               p_netpath_init = &p_adapter->primaryPath;\r
+               p_adapter->p_currentPath = p_netpath_init;\r
+       }\r
+\r
+       else \r
+       {\r
+               if( p_adapter->p_currentPath != &p_adapter->primaryPath )\r
+               {\r
+                       p_netpath_init = &p_adapter->primaryPath;\r
+               }\r
+               else\r
+               {\r
+                       p_netpath_init = &p_adapter->secondaryPath;\r
+               }\r
+       }\r
+\r
+       /* shouldn't really happened ?? */\r
+       if( netpath_is_connected( p_netpath_init ) )\r
+       {\r
+               VNIC_TRACE( VNIC_DBG_WARN,\r
+                       ("No available Netpath found for update\n"));\r
+\r
+               NdisReleaseSpinLock( &p_adapter->lock );\r
+               return IB_NO_MATCH;\r
+       }\r
+\r
+       p_netpath_init->p_path_rec = &p_path->path_rec;\r
+\r
+       /* netpath initialization */\r
+\r
+       p_netpath_init->p_adapter = p_adapter;\r
+       p_netpath_init->pViport = p_viport;\r
+       p_netpath_init->carrier = FALSE;\r
+\r
+       /* viport initialization */\r
+       p_viport->p_netpath = p_netpath_init;\r
+\r
+       p_viport->portGuid = p_netpath_init->p_path_rec->sgid.unicast.interface_id;\r
+       p_viport->port_config.dataConfig.ibConfig.pathInfo = *p_netpath_init->p_path_rec;\r
+       p_viport->port_config.controlConfig.ibConfig.pathInfo = *p_netpath_init->p_path_rec;\r
+       \r
+       /* set our instance id per IOC */\r
+       p_viport->port_config.controlConfig.ibConfig.connData.inicInstance = (uint8_t)p_netpath_init->instance;\r
+       p_viport->port_config.dataConfig.ibConfig.connData.inicInstance = (uint8_t)p_netpath_init->instance;\r
+       /* save for later use */\r
+       p_viport->port_config.controlConfig.inicInstance = (uint8_t)p_netpath_init->instance;\r
+               \r
+       p_viport->iocGuid  = p_adapter->ioc_info.profile.ioc_guid;\r
+       p_viport->port_config.controlConfig.ibConfig.sid = p_adapter->svc_entries[0].id;\r
+       p_viport->port_config.dataConfig.ibConfig.sid = p_adapter->svc_entries[1].id;\r
+\r
+               VNIC_TRACE( VNIC_DBG_INFO,\r
+               ("IOC[%d] instance %d [%s] is using SLID=%d DLID=%d Target:%s\n",\r
+               p_viport->ioc_num,\r
+               p_netpath_init->instance,\r
+               netpath_to_string( p_netpath_init ),\r
+               cl_ntoh16( p_path->path_rec.slid ),\r
+               cl_ntoh16( p_path->path_rec.dlid),\r
+               p_adapter->ioc_info.profile.id_string) );\r
+       \r
+       NdisReleaseSpinLock( &p_adapter->lock );\r
+\r
+       VNIC_EXIT( VNIC_DBG_PNP );\r
+       return IB_SUCCESS;\r
+}\r
+\r
+static\r
+ib_api_status_t\r
+adapter_netpath_update_and_connect(\r
+       IN              vnic_adapter_t* const   p_adapter,\r
+       IN              vnic_path_record_t*             p_path )\r
+{\r
+       ib_api_status_t         ib_status;\r
+       viport_t*                       p_viport;\r
+\r
+       ib_status = adapter_viport_allocate( p_adapter, &p_viport );\r
+       if( ib_status != IB_SUCCESS )\r
+       {\r
+               VNIC_TRACE ( VNIC_DBG_ERROR,\r
+                       ("IOC[%] Viport allocate Failed status %s\n",\r
+                       p_adapter->ioc_num,     p_adapter->ifc.get_err_str( ib_status )) );\r
+               goto err;\r
+       }\r
+\r
+       ib_status = _adapter_open_ca( p_adapter );\r
+       if( ib_status != IB_SUCCESS )\r
+       {\r
+               VNIC_TRACE( VNIC_DBG_ERROR,\r
+                               ("IOC[%d]Open CA failed %s\n", p_adapter->ioc_num,\r
+                               p_adapter->ifc.get_err_str( ib_status )) );\r
+               goto err;\r
+       }\r
+\r
+       ib_status = _adapter_netpath_update( p_adapter, p_viport, p_path );\r
+       if( ib_status != IB_SUCCESS )\r
+       {\r
+               VNIC_TRACE( VNIC_DBG_ERROR,\r
+                               ("IOC[%d]Update New Path failed %s\n", p_adapter->ioc_num,\r
+                               p_adapter->ifc.get_err_str( ib_status )) );\r
+               goto err;\r
+       }\r
+\r
+       ib_status = viport_control_connect( p_viport );\r
+       if( ib_status != IB_SUCCESS )\r
+       {\r
+               VNIC_TRACE( VNIC_DBG_ERROR,\r
+                               ("IOC[%d]Control QP connect return %s\n", p_adapter->ioc_num,\r
+                               p_adapter->ifc.get_err_str( ib_status )) );\r
+               goto err;\r
+       }\r
+\r
+       /* should call this only once */\r
+       if( p_adapter->state == INIC_UNINITIALIZED )\r
+       {\r
+               if( _adapter_set_sg_size( p_adapter->h_handle, \r
+                       p_adapter->params.MinMtu ) != NDIS_STATUS_SUCCESS )\r
+               {\r
+                       VNIC_TRACE( VNIC_DBG_ERROR,\r
+                               ("IOC[%d]ScatterGather Init using MTU size %d failed\n", p_adapter->ioc_num,\r
+                               p_adapter->params.MinMtu ) );\r
+                       goto err;\r
+               }\r
+       }\r
+\r
+       ib_status = viport_data_connect( p_viport );\r
+       if( ib_status != IB_SUCCESS )\r
+       {\r
+               VNIC_TRACE( VNIC_DBG_ERROR,\r
+                               ("IOC[%d]Data QP connect return %s\n", p_adapter->ioc_num,\r
+                               p_adapter->ifc.get_err_str( ib_status )) );\r
+               goto err;\r
+       }\r
+       \r
+       VNIC_TRACE( VNIC_DBG_INFO,\r
+                       ("IOC[%d] instance %d %s is CONNECTED\n",\r
+                       p_viport->ioc_num,\r
+                       p_viport->p_netpath->instance,\r
+                       netpath_to_string( p_viport->p_netpath ) ));\r
+\r
+       p_adapter->num_paths++;\r
+\r
+       if( p_adapter->num_paths > 1 &&\r
+               p_viport->p_netpath != p_adapter->p_currentPath )\r
+       {\r
+               if ( !netpath_setUnicast( p_viport->p_netpath, \r
+                       p_adapter->p_currentPath->pViport->hwMacAddress ) )\r
+               {\r
+                       ib_status = IB_ERROR;\r
+                       goto err;\r
+               }\r
+       }\r
+\r
+       return ib_status;\r
+\r
+err:\r
+       VNIC_TRACE( VNIC_DBG_ERROR,\r
+               ("IOC[%d] allocate return %#x (%s)\n", p_adapter->ioc_num,\r
+                               ib_status, p_adapter->ifc.get_err_str( ib_status )) );\r
+\r
+       if( p_viport != NULL &&  \r
+               p_viport->p_netpath != NULL )\r
+       {\r
+               netpath_free( p_viport->p_netpath );\r
+       }\r
+       return ib_status;\r
+}\r
+\r
+#if defined( LBFO_ENABLED )\r
+\r
+static void\r
+__adapter_add_to_failover_list(\r
+        IN             vnic_adapter_t* const   p_adapter,\r
+        IN             lbfo_state_t                    state )\r
+{\r
+\r
+       CL_ASSERT( p_adapter );\r
+       CL_ASSERT( state == _ADAPTER_PRIMARY || state == _ADAPTER_SECONDARY );\r
+\r
+       p_adapter->failover.fo_state = state;\r
+\r
+       if( state == _ADAPTER_PRIMARY )\r
+       {       \r
+               p_adapter->failover.primary_handle = p_adapter;\r
+               cl_qlist_insert_tail( &g_vnic.primary_list, &p_adapter->list_item );\r
+       }\r
+       else\r
+       {\r
+               cl_qlist_insert_tail( &g_vnic.secondary_list, &p_adapter->list_item );\r
+       }\r
+}\r
+\r
+static void\r
+__adapter_remove_from_failover_list(\r
+        IN             vnic_adapter_t* const   p_adapter )\r
+{\r
+       lbfo_state_t lbfo_state;\r
+       vnic_adapter_t  *p_adapter_to_promote;\r
+       uint32_t                bundle_id;\r
+\r
+       CL_ASSERT( p_adapter );\r
+\r
+       lbfo_state = p_adapter->failover.fo_state;\r
+       p_adapter->failover.fo_state = _ADAPTER_NOT_BUNDLED;\r
+       bundle_id = p_adapter->failover.bundle_id;\r
+\r
+       if( lbfo_state == _ADAPTER_PRIMARY )\r
+       {\r
+               cl_qlist_remove_item( &g_vnic.primary_list, &p_adapter->list_item );\r
+               NdisMRemoveMiniport( p_adapter->h_handle );\r
+\r
+               /* search for secondary adapter with same id && (id != 0 ) */\r
+               if( bundle_id != 0 )\r
+               {\r
+                       p_adapter_to_promote =\r
+                               __adapter_find_on_failover_list( _ADAPTER_SECONDARY, bundle_id );\r
+               \r
+                       if( p_adapter_to_promote &&\r
+                               p_adapter_to_promote->pnp_state != IB_PNP_IOC_REMOVE &&\r
+                               ( p_adapter_to_promote->reset == FALSE || \r
+                               p_adapter_to_promote->hung  < p_adapter_to_promote->num_paths ) )\r
+                       {\r
+                               /* a small recursion */\r
+                               __adapter_set_failover_primary( p_adapter_to_promote, TRUE );\r
+                       }\r
+               }\r
+       }\r
+       else if( lbfo_state == _ADAPTER_SECONDARY )\r
+       {\r
+               cl_qlist_remove_item( &g_vnic.secondary_list, &p_adapter->list_item );\r
+               VNIC_TRACE( VNIC_DBG_INFO,\r
+                               ("IOC[%d]  LBFO bundle %d Secondary Adapter Removed\n", \r
+                               p_adapter->ioc_num, p_adapter->failover.bundle_id ));\r
+       }\r
+       else\r
+               VNIC_TRACE( VNIC_DBG_ERROR,\r
+               ("IOC[%d] Adapter not bundled\n", p_adapter->ioc_num ));\r
+\r
+       return;\r
+}\r
+\r
+\r
+static vnic_adapter_t*\r
+__adapter_find_on_failover_list(\r
+       IN              lbfo_state_t    list_flag,\r
+       IN              uint32_t                bundle_id )\r
+{\r
+       vnic_adapter_t          *p_adapter = NULL;\r
+       cl_list_item_t          *p_item;\r
+       cl_qlist_t                      *p_qlist = ( list_flag == _ADAPTER_PRIMARY ) ?\r
+               &g_vnic.primary_list : &g_vnic.secondary_list;\r
+       \r
+       p_item = cl_qlist_head( p_qlist );\r
+\r
+       while( p_item != cl_qlist_end( p_qlist ) )\r
+       {\r
+               p_adapter = PARENT_STRUCT( p_item, vnic_adapter_t, list_item );\r
+\r
+               if( p_adapter &&\r
+                       p_adapter->failover.bundle_id == bundle_id )\r
+               {\r
+                       return p_adapter;\r
+               }\r
+\r
+               p_item = cl_qlist_next( p_item );\r
+       }\r
+       return NULL;\r
+}\r
+\r
+static NDIS_STATUS\r
+__adapter_set_failover_primary(\r
+        IN             vnic_adapter_t*  const p_adapter,\r
+        IN             BOOLEAN                 promote_secondary )\r
+{\r
+       NDIS_STATUS status = NDIS_STATUS_SUCCESS;\r
+       \r
+       CL_ASSERT( p_adapter );\r
+       \r
+       if( promote_secondary )\r
+       {\r
+               if( p_adapter->failover.fo_state != _ADAPTER_SECONDARY )\r
+               {\r
+                       VNIC_TRACE( VNIC_DBG_ERROR,\r
+                               ("LBFO Can't promote NON_SECONDARY\n"));\r
+                       return NDIS_STATUS_NOT_ACCEPTED;\r
+               }\r
+               __adapter_remove_from_failover_list( p_adapter );\r
+               status = NdisMPromoteMiniport( p_adapter->h_handle );\r
+       }\r
+\r
+       if( status == NDIS_STATUS_SUCCESS )\r
+       {\r
+               p_adapter->failover.p_adapter = p_adapter;\r
+               p_adapter->failover.fo_state = _ADAPTER_PRIMARY;\r
+               p_adapter->failover.primary_handle = p_adapter->h_handle;\r
+               __adapter_add_to_failover_list( p_adapter, _ADAPTER_PRIMARY );\r
+\r
+               VNIC_TRACE( VNIC_DBG_INFO,\r
+                       ("IOC[%d] Set LBFO bundle %d Primary Adapter\n", \r
+                       p_adapter->ioc_num, p_adapter->failover.bundle_id ));\r
+       }\r
+       else\r
+               VNIC_TRACE( VNIC_DBG_ERROR,\r
+                               ("LBFO Set to Primary Failed\n"));\r
+\r
        return status;\r
 }\r
+\r
+static NDIS_STATUS\r
+__adapter_set_failover_secondary(\r
+        IN             vnic_adapter_t* const   p_adapter,\r
+        IN             NDIS_HANDLE                             primary_handle )\r
+{\r
+       NDIS_STATUS     status;\r
+\r
+       CL_ASSERT( p_adapter );\r
+\r
+       status = NdisMSetMiniportSecondary( p_adapter->h_handle, primary_handle );\r
+       \r
+       if ( status == NDIS_STATUS_SUCCESS )\r
+       {\r
+               p_adapter->failover.fo_state = _ADAPTER_SECONDARY;\r
+               p_adapter->failover.primary_handle = primary_handle;\r
+               __adapter_add_to_failover_list( p_adapter, _ADAPTER_SECONDARY );\r
+\r
+               VNIC_TRACE( VNIC_DBG_INFO,\r
+                               ("IOC[%d] Set LBFO bundle %d Secondary Adapter\n", \r
+                               p_adapter->ioc_num, p_adapter->failover.bundle_id ));\r
+       }\r
+\r
+       return status;\r
+}\r
+\r
+#endif //LBFO_ENABLED\r
index 5cd9f28..969c363 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
- * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.\r
+ * Copyright (c) 2007 QLogic Corporation.  All rights reserved.\r
  *\r
  * This software is available to you under the OpenIB.org BSD license\r
  * below:\r
@@ -64,6 +64,13 @@ typedef struct _ipv4_address_item
 \r
 }      ipv4_address_item_t;\r
 \r
+typedef struct _lbfo_failover {\r
+       struct _vnic_adapter *p_adapter;\r
+       NDIS_HANDLE                     primary_handle;\r
+       uint32_t                        bundle_id;\r
+       lbfo_state_t            fo_state;\r
+} lbfo_failover_t;\r
+\r
 typedef struct _vnic_params {\r
        uint32_t        MaxAddressEntries;\r
        uint32_t        MinAddressEntries;\r
@@ -101,31 +108,38 @@ typedef struct _vnic_params {
        uint32_t        DefaultPreferPrimary;\r
        uint32_t        UseRxCsum;\r
        uint32_t        UseTxCsum;\r
+       uint32_t        VlanInfo;\r
+       uint32_t        SecondaryPath;\r
+       uint32_t        bundle_id;\r
        mac_addr_t      conf_mac;\r
 }      vnic_params_t;\r
 \r
 \r
 typedef struct _vnic_adapter {\r
-       LIST_ENTRY                              list_entry;\r
+       cl_list_item_t                  list_item;\r
        NDIS_HANDLE                             h_handle;\r
        DEVICE_OBJECT                   *p_pdo;\r
        NDIS_SPIN_LOCK                  lock;\r
        ib_al_ifc_t                             ifc;\r
        ioc_ifc_data_t                  ifc_data;\r
        ib_ioc_info_t                   ioc_info;\r
-       vnic_path_record_t              path_record;\r
+       LIST_ENTRY                              send_pending_list;\r
+       LIST_ENTRY                              cancel_send_list;\r
+       NDIS_SPIN_LOCK                  pending_list_lock;\r
+       NDIS_SPIN_LOCK                  cancel_list_lock;\r
+       NDIS_SPIN_LOCK                  path_records_lock;\r
+       cl_qlist_t                              path_records_list;\r
        ib_al_handle_t                  h_al;\r
        ib_ca_handle_t                  h_ca;\r
        ib_pnp_handle_t                 h_pnp;\r
        ib_pnp_event_t                  pnp_state;\r
        IbCa_t                                  ca;\r
-       struct _viport                  *p_viport;\r
        InicState_t                             state;\r
        struct Netpath                  primaryPath;\r
        struct Netpath                  secondaryPath;\r
        struct Netpath                  *p_currentPath;\r
        vnic_params_t                   params;\r
-       int                                             open;\r
+       int                                             num_paths;\r
        int                                             macSet;\r
        int                                             mc_count;\r
        mac_addr_t                              mcast_array[MAX_MCAST];\r
@@ -134,16 +148,18 @@ typedef struct _vnic_adapter {
        uint32_t                                ioc_num;\r
        uint32_t                                link_speed;\r
        uint32_t                                packet_filter;\r
+       uint32_t                                vlan_info;\r
        int                                             hung;\r
        BOOLEAN                                 reset;\r
-       int                                             pending_set;\r
+       BOOLEAN                                 pending_set;\r
        BOOLEAN                                 pending_query;\r
        pending_oid_t                   query_oid;\r
        pending_oid_t                   set_oid;\r
-       uint8_t                                 num_svc_entries;\r
-       ib_svc_entry_t                  *p_svc_entries;\r
-       char                                    name[65];\r
-       InicNPEvent_t                   np_event[INICNP_NUM_EVENTS];\r
+       ib_svc_entry_t                  svc_entries[2];\r
+\r
+#if defined( LBFO_ENABLED )\r
+       lbfo_failover_t                 failover;\r
+#endif\r
 #ifdef VNIC_STATISTIC\r
        struct {\r
                uint64_t                        startTime;\r
@@ -182,20 +198,16 @@ vnic_construct_adapter(
        IN              vnic_adapter_t          *p_adapter);\r
 \r
 NDIS_STATUS\r
-vnic_set_mcast(\r
+adapter_set_mcast(\r
        IN                              vnic_adapter_t* const           p_adapter,\r
        IN                              mac_addr_t* const                       p_mac_array,\r
        IN              const   uint8_t                                         mc_count );\r
 \r
 ib_api_status_t\r
-vnic_viport_allocate(\r
+adapter_viport_allocate(\r
        IN                      vnic_adapter_t* const           p_adapter,\r
        IN OUT          viport_t**              const           pp_viport );\r
 \r
-void\r
-vnic_viport_cleanup(\r
-       IN                      vnic_adapter_t                  *p_adapter );\r
-\r
 void\r
 vnic_resume_set_oids(\r
        IN                              vnic_adapter_t* const           p_adapter );\r
@@ -221,7 +233,10 @@ __vnic_pnp_dereg_cb(
        IN              void*                   context );\r
 \r
 ib_api_status_t\r
-vnic_reset_adapter(\r
+adapter_reset(\r
        IN              vnic_adapter_t* const           p_adapter );\r
+void\r
+__pending_queue_cleanup( \r
+       IN              vnic_adapter_t  *p_adapter );\r
 \r
 #endif /* !defined _VNIC_ADAPTER_H_ */\r
index 3dccc7e..96dad84 100644 (file)
@@ -1,3 +1,33 @@
+/*\r
+ * Copyright (c) 2007 QLogic 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$\r
+ */\r
 #ifndef _VNIC_CONFIG_H_\r
 #define _VNIC_CONFIG_H_\r
 \r
@@ -12,6 +42,8 @@
 #define INIC_MAJORVERSION 1\r
 #define INIC_MINORVERSION 1\r
 \r
+#define LIMIT_OUTSTANDING_SENDS 0\r
+\r
 #define MAX_ADDRESS_ENTRIES             64   /* max entries to negotiate with remote */\r
 #define MIN_ADDRESS_ENTRIES             16   /* min entries remote can return to us that we agree with */\r
 #define MAX_ADDR_ARRAY                  32   /* address array we can handle. for now */\r
@@ -57,7 +89,7 @@
    some later will be converted to microseconds */\r
 #define VIPORT_STATS_INTERVAL           5000   /* 5 sec */\r
 #define VIPORT_HEARTBEAT_INTERVAL       2000 /* 2 seconds */\r
-#define VIPORT_HEARTBEAT_TIMEOUT        64000 /* 64 sec  */\r
+#define VIPORT_HEARTBEAT_TIMEOUT        60000 /* 60 sec  */\r
 #define CONTROL_RSP_TIMEOUT             2000  /* 2 sec */\r
 \r
 #define _100NS_IN_1MS                                  (10000)\r
@@ -117,6 +149,33 @@ get_time_stamp_ms( void )
 #define U8_ZERO_RANGE(x)  ZERO_RANGE_CHECK(x, 0, 0xFF)\r
 #define U8_RANGE(x)       RANGE_CHECK(x, 1, 0xFF)\r
 \r
+enum {\r
+       INDEX_RESERVED,\r
+       INDEX_MIN_HOST_POOL_SZ,\r
+       INDEX_HOST_RECV_POOL_ENTRIES,\r
+       INDEX_MIN_EIOC_POOL_SZ,\r
+       INDEX_MAX_EIOC_POOL_SZ,\r
+       INDEX_MIN_HOST_KICK_TIMEOUT,\r
+       INDEX_MAX_HOST_KICK_TIMEOUT,\r
+       INDEX_MIN_HOST_KICK_ENTRIES,\r
+       INDEX_MAX_HOST_KICK_ENTRIES,\r
+       INDEX_MIN_HOST_KICK_BYTES,\r
+       INDEX_MAX_HOST_KICK_BYTES,\r
+       INDEX_MIN_HOST_UPDATE_SZ,\r
+       INDEX_MAX_HOST_UPDATE_SZ,\r
+       INDEX_MIN_EIOC_UPDATE_SZ,\r
+       INDEX_MAX_EIOC_UPDATE_SZ,\r
+       INDEX_HEARTBEAT_TIMEOUT,\r
+       INDEX_LAST // keep it the last entry\r
+};\r
+\r
+typedef struct _g_registry_params {\r
+       PWSTR           name;\r
+       uint32_t        value;\r
+}g_registry_params_t;\r
+\r
+#define ENTRY_INIT_VALUE                       MAXULONG\r
+#define VNIC_REGISTRY_TBL_SIZE         INDEX_LAST\r
 \r
 typedef struct {\r
         uint64_t ioc_guid;\r
@@ -130,20 +189,16 @@ typedef struct {
 } PathParam_t;\r
 \r
 typedef struct _vnic_globals {\r
-       NDIS_HANDLE             ndis_handle; // ndis wrapper handle\r
-       volatile LONG   dev_reg;     // dev register counter\r
-       volatile LONG   adapters;    // created adapters counter\r
-       KSPIN_LOCK              lock;\r
-       LIST_ENTRY              adapter_list;\r
-       uint8_t                 host_name[IB_NODE_DESCRIPTION_SIZE + 1];\r
+       NDIS_HANDLE                     ndis_handle; // ndis wrapper handle\r
+       NDIS_SPIN_LOCK          lock;\r
+#if defined (LBFO_ENABLED)\r
+       cl_qlist_t                      primary_list;\r
+       cl_qlist_t                      secondary_list;\r
+#endif\r
+       uint32_t                        shutdown;\r
+       uint8_t                         host_name[IB_NODE_DESCRIPTION_SIZE];\r
+       g_registry_params_t     *p_params;\r
 } vnic_globals_t;\r
-/*\r
-struct members:\r
-       lock:\r
-               take this lock before access to adapter_list\r
-       adapter_list:\r
-                head of list of virtual adapters initialized by driver\r
-*/\r
 \r
 typedef struct IbConfig {\r
         ib_path_rec_t       pathInfo;\r
@@ -194,7 +249,7 @@ typedef struct ViportConfig {
         uint32_t           hbTimeout;  /* heartbeat timeout */\r
         uint64_t           portGuid;\r
         uint64_t           guid;\r
-        size_t          pathIdx;\r
+        size_t          instance;\r
         char            ioc_string[65];\r
 \r
 #define HB_INTERVAL_OVERRIDE 0x1\r
@@ -211,7 +266,7 @@ typedef struct ViportConfig {
  *                         give the primary?\r
  * primaryReconnectTimeout - Same as above, but used when recovering when\r
  *                         both paths fail\r
- * primaryReconnectTimeout - How long do we wait before switching to the\r
+ * primarySwitchTimeout    - How long do we wait before switching to the\r
  *                         primary when it comes back?\r
  */\r
 #define IFNAMSIZ 65\r
@@ -236,5 +291,11 @@ typedef enum {
        INIC_REGISTERED,\r
 } InicState_t;\r
 \r
+typedef enum {\r
+       _ADAPTER_NOT_BUNDLED = 0,\r
+       _ADAPTER_PRIMARY,\r
+       _ADAPTER_SECONDARY\r
+} lbfo_state_t;\r
+\r
 #endif /* _VNIC_CONFIG_H_ */\r
 \r
index 799c7a7..f3fb07f 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
- * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.\r
+ * Copyright (c) 2007 QLogic Corporation.  All rights reserved.\r
  *\r
  * This software is available to you under the OpenIB.org BSD license\r
  * below:\r
@@ -176,6 +176,7 @@ control_init(
 \r
                ibqp_cleanup( &pControl->qp );\r
                cl_free( pControl->pLocalStorage );\r
+               pControl->pLocalStorage = NULL;\r
                goto failure;\r
        }\r
        pIo                                             = &pControl->sendIo.io;\r
@@ -210,7 +211,7 @@ control_init(
                {\r
                        control_cleanup( pControl );\r
                        ib_status = IB_ERROR;\r
-                       goto failure;\r
+                       break;\r
                }\r
        }\r
 \r
@@ -268,8 +269,8 @@ control_processAsync(
                        {\r
                        case INIC_STATUS_LINK_UP:\r
                                VNIC_TRACE( VNIC_DBG_CTRL,\r
-                                       ("IOC %d: Link Up\n", pControl->p_viport->ioc_num ) );\r
-                               /* renew link speed info */\r
+                                       ("IOC %d: STATUS LINK UP\n", pControl->p_viport->ioc_num ) );\r
+                               /* renew link speed info since it can change */\r
                                pControl->p_viport->p_adapter->link_speed =\r
                                                        ntoh32( pPkt->cmd.reportStatus.statusInfo );\r
                                viport_linkUp( pControl->p_viport );\r
@@ -277,15 +278,22 @@ control_processAsync(
 \r
                        case INIC_STATUS_LINK_DOWN:\r
                                VNIC_TRACE( VNIC_DBG_CTRL,\r
-                                       ("IOC %d: Link Down\n", pControl->p_viport->ioc_num ) );\r
+                                       ("IOC %d: STATUS LINK DOWN\n", pControl->p_viport->ioc_num ) );\r
 \r
                                viport_linkDown( pControl->p_viport );\r
                                break;\r
-\r
+                       case INIC_STATUS_EIOC_ERROR:\r
+                       case INIC_STATUS_EIOC_SHUTDOWN:\r
+                               viport_failure( pControl->p_viport );\r
+                               VNIC_TRACE( VNIC_DBG_ERROR,\r
+                                               ("IOC %d: STATUS EIOC ERROR\n",\r
+                                                                       pControl->p_viport->ioc_num ) );\r
+                               break;\r
                        default:\r
                                VNIC_TRACE( VNIC_DBG_CTRL | VNIC_DBG_ERROR,\r
-                                               ("IOC %d: Asynchronous status received from EIOC\n",\r
-                                                                        pControl->p_viport->ioc_num ) );\r
+                                       ("IOC %d: Asynchronous status %#x received\n",\r
+                                                                        pControl->p_viport->ioc_num,\r
+                                                                        ntoh32(pPkt->cmd.reportStatus.statusNumber)) );\r
                                __control_logControlPacket( pPkt );\r
                                break;\r
                        }\r
@@ -322,6 +330,7 @@ control_processAsync(
                     ( pPkt->cmd.reportStatus.isFatal ) )\r
                {\r
                        viport_failure( pControl->p_viport );\r
+                       break;\r
                }\r
 \r
                control_recv( pControl, pRecvIo );\r
@@ -401,6 +410,20 @@ control_initInicRsp(
                __control_logControlPacket( pPkt );\r
                goto failure;\r
        }\r
+#ifdef _DEBUG_\r
+               VNIC_TRACE( VNIC_DBG_CTRL_PKT,\r
+                               ("IOC %d: instance %d Sent initINIC request:\n",\r
+                                       pControl->p_viport->ioc_num,\r
+                                       pControl->p_viport->p_netpath->instance ) );\r
+               __control_logControlPacket( control_lastReq( pControl ) );\r
+       \r
+               VNIC_TRACE(VNIC_DBG_CTRL_PKT,\r
+                       ("IOC %d: instance %d Received initInic response:\n",\r
+                               pControl->p_viport->ioc_num,\r
+                               pControl->p_viport->p_netpath->instance ) );\r
+               __control_logControlPacket( pPkt );\r
+#endif\r
+\r
        pInitInicRsp     = &pPkt->cmd.initInicRsp;\r
        pControl->majVer = ntoh16( pInitInicRsp->inicMajorVersion );\r
        pControl->minVer = ntoh16( pInitInicRsp->inicMinorVersion );\r
@@ -548,7 +571,19 @@ control_configDataPathRsp(
                __control_logControlPacket( pPkt );\r
                goto failure;\r
        }\r
-\r
+#ifdef _DEBUG_\r
+               VNIC_TRACE( VNIC_DBG_CTRL_PKT,\r
+                               ("IOC %d: instance %d Sent configDATAPATH request:\n",\r
+                                       pControl->p_viport->ioc_num,\r
+                                       pControl->p_viport->p_netpath->instance ) );\r
+               __control_logControlPacket( control_lastReq( pControl ) );\r
+       \r
+               VNIC_TRACE(VNIC_DBG_CTRL_PKT,\r
+                       ("IOC %d: instance %d Received configDATAPATH response:\n",\r
+                               pControl->p_viport->ioc_num,\r
+                               pControl->p_viport->p_netpath->instance ) );\r
+               __control_logControlPacket( pPkt );\r
+#endif\r
        pConfigDataPath = &pPkt->cmd.configDataPathRsp;\r
 \r
        if ( pConfigDataPath->dataPath  != 0 )\r
@@ -643,6 +678,19 @@ control_exchangePoolsRsp(
                goto failure;\r
        }\r
 \r
+#ifdef _DEBUG_\r
+               VNIC_TRACE( VNIC_DBG_CTRL_PKT,\r
+                               ("IOC %d: instance %d Sent exchangePOOLS request:\n",\r
+                                       pControl->p_viport->ioc_num,\r
+                                       pControl->p_viport->p_netpath->instance ) );\r
+               __control_logControlPacket( control_lastReq( pControl ) );\r
+       \r
+               VNIC_TRACE(VNIC_DBG_CTRL_PKT,\r
+                       ("IOC %d: instance %d Received exchangePOOLS response:\n",\r
+                               pControl->p_viport->ioc_num,\r
+                               pControl->p_viport->p_netpath->instance ) );\r
+               __control_logControlPacket( pPkt );\r
+#endif\r
        pExchangePools = &pPkt->cmd.exchangePoolsRsp;\r
        *pRkey         = pExchangePools->poolRKey;\r
        *pAddr         = ntoh64( pExchangePools->poolAddr );\r
@@ -688,7 +736,6 @@ control_configLinkReq(
        pConfigLinkReq               = &pPkt->cmd.configLinkReq;\r
        NdisZeroMemory( pConfigLinkReq, sizeof( Inic_CmdConfigLink_t ) );\r
        pConfigLinkReq->lanSwitchNum = pControl->lanSwitch.lanSwitchNum;\r
-       pConfigLinkReq->cmdFlags     = INIC_FLAG_SET_MTU;\r
 \r
        if ( flags & INIC_FLAG_ENABLE_NIC )\r
        {\r
@@ -722,7 +769,12 @@ control_configLinkReq(
        {\r
                pConfigLinkReq->cmdFlags |= INIC_FLAG_DISABLE_PROMISC;\r
        }\r
-       pConfigLinkReq->mtuSize      = hton16( mtu );\r
+\r
+       if( flags & INIC_FLAG_SET_MTU )\r
+       {\r
+               pConfigLinkReq->cmdFlags     |= INIC_FLAG_SET_MTU;\r
+               pConfigLinkReq->mtuSize      = hton16( mtu );\r
+       }\r
 \r
        ib_status = control_send( pControl );\r
        VNIC_EXIT( VNIC_DBG_CTRL );\r
@@ -762,7 +814,19 @@ control_configLinkRsp(
                __control_logControlPacket( pPkt );\r
                goto failure;\r
        }\r
-\r
+#ifdef _DEBUG_\r
+               VNIC_TRACE( VNIC_DBG_CTRL_PKT,\r
+                               ("IOC %d: instance %d Sent configLINK request:\n",\r
+                                       pControl->p_viport->ioc_num,\r
+                                       pControl->p_viport->p_netpath->instance ) );\r
+               __control_logControlPacket( control_lastReq( pControl ) );\r
+       \r
+               VNIC_TRACE(VNIC_DBG_CTRL_PKT,\r
+                       ("IOC %d: instance %d Received configLINK response:\n",\r
+                               pControl->p_viport->ioc_num,\r
+                               pControl->p_viport->p_netpath->instance ) );\r
+               __control_logControlPacket( pPkt );\r
+#endif\r
        pConfigLinkRsp = &pPkt->cmd.configLinkRsp;\r
 \r
        *pFlags = pConfigLinkRsp->cmdFlags;\r
@@ -874,6 +938,20 @@ control_configAddrsRsp(
                goto failure;\r
        }\r
 \r
+#ifdef _DEBUG_\r
+               VNIC_TRACE( VNIC_DBG_CTRL_PKT,\r
+                               ("IOC %d: instance %d Sent configADDRS request:\n",\r
+                                       pControl->p_viport->ioc_num,\r
+                                       pControl->p_viport->p_netpath->instance ) );\r
+               __control_logControlPacket( control_lastReq( pControl ) );\r
+       \r
+               VNIC_TRACE(VNIC_DBG_CTRL_PKT,\r
+                       ("IOC %d: instance %d Received configADDRS response:\n",\r
+                               pControl->p_viport->ioc_num,\r
+                               pControl->p_viport->p_netpath->instance ) );\r
+               __control_logControlPacket( pPkt );\r
+#endif\r
+\r
        pConfigAddrsRsp = &pPkt->cmd.configAddressesRsp;\r
 \r
        control_recv( pControl, pRecvIo );\r
@@ -1226,17 +1304,21 @@ control_recvComplete(
 \r
                        if( p_viport->flags & INIC_FLAG_ENABLE_NIC )\r
                        {\r
-                               InterlockedExchange( &p_viport->p_netpath->carrier, TRUE );\r
                                /* don't indicate media state yet if in sync query */\r
-                               if( !( p_viport->updates & SYNC_QUERY ) )\r
+                               if( ( InterlockedExchange( &p_viport->p_netpath->carrier, TRUE ) == FALSE ) &&\r
+                                       !( p_viport->updates & SYNC_QUERY ) )\r
                                {       \r
-                                       viport_linkUp( p_viport );\r
+                                       viport_restartXmit( p_viport );\r
+                                       //viport_linkUp( p_viport );\r
                                }\r
                        }\r
-                       else\r
+                       else if( p_viport->flags & INIC_FLAG_DISABLE_NIC )\r
                        {\r
-                               InterlockedExchange( &p_viport->p_netpath->carrier, FALSE );\r
-                               viport_linkDown( p_viport );\r
+                               if( InterlockedExchange( &p_viport->p_netpath->carrier, FALSE ) == TRUE )\r
+                               {\r
+                                       viport_stopXmit( p_viport );\r
+                                       viport_linkDown( p_viport );\r
+                               }\r
                        }\r
                        InterlockedAnd( &p_viport->updates, ~NEED_LINK_CONFIG );\r
                }\r
@@ -1312,15 +1394,15 @@ control_recvComplete(
        default:\r
                break;\r
        }\r
-\r
-       if( _viport_process_query( p_viport, FALSE ) == STATUS_SUCCESS )\r
+       \r
+       if( _viport_process_query( p_viport, FALSE ) != NDIS_STATUS_PENDING )\r
        {\r
                /* Complete any pending set OID. */\r
                vnic_resume_set_oids( p_viport->p_adapter );\r
        }\r
 \r
        if(     InterlockedAnd( &p_viport->updates, ~SYNC_QUERY ) & SYNC_QUERY )\r
-               cl_event_signal( &p_viport->conn_event );\r
+               cl_event_signal( &p_viport->sync_event );\r
 }\r
 \r
 \r
@@ -1348,7 +1430,7 @@ control_send(
        }\r
 \r
 #ifdef _DEBUG_\r
-       __control_logControlPacket( pPkt );\r
+       //__control_logControlPacket( pPkt );\r
 #endif\r
 \r
        InterlockedExchange( (volatile LONG*)&pControl->rspExpected,\r
@@ -1487,7 +1569,7 @@ control_getRsp(
                Inic_ControlPacket_t *pPkt = control_packet( &pControl->sendIo );\r
                Inic_ControlHeader_t *pHdr = &pPkt->hdr;\r
 \r
-               VNIC_TRACE( VNIC_DBG_CTRL| VNIC_DBG_ERROR,\r
+               VNIC_TRACE( VNIC_DBG_ERROR,\r
                                ("IOC %d: No response received from EIOC\n",\r
                                                pControl->p_viport->ioc_num ) );\r
 #ifdef VNIC_STATISTIC\r
@@ -1498,7 +1580,7 @@ control_getRsp(
 \r
                if ( pControl->reqRetryCounter >= pControl->p_conf->reqRetryCount )\r
                {\r
-                       VNIC_TRACE( VNIC_DBG_CTRL| VNIC_DBG_ERROR,\r
+                       VNIC_TRACE( VNIC_DBG_ERROR,\r
                                ("IOC %d: Control packet retry exceeded\n",\r
                                                pControl->p_viport->ioc_num ) );\r
                        viport_failure(pControl->p_viport );\r
@@ -1547,13 +1629,13 @@ checkRecvPoolConfigValue(
 \r
        if (value > *p_max )\r
        {\r
-               VNIC_TRACE( VNIC_DBG_CTRL| VNIC_DBG_ERROR,\r
+               VNIC_TRACE(  VNIC_DBG_ERROR,\r
                                        ("Value %s too large\n", name) );\r
                return FALSE;\r
        }\r
        else if (value < *p_min )\r
        {\r
-               VNIC_TRACE( VNIC_DBG_CTRL| VNIC_DBG_ERROR,\r
+               VNIC_TRACE( VNIC_DBG_ERROR,\r
                                ("Value %s too small\n", name) );\r
                return FALSE;\r
        }\r
@@ -1588,28 +1670,28 @@ checkRecvPoolConfig(
 \r
        if ( !IsPowerOf2( pDst->numRecvPoolEntries ) )\r
        {\r
-               VNIC_TRACE( VNIC_DBG_CTRL| VNIC_DBG_ERROR,\r
+               VNIC_TRACE( VNIC_DBG_ERROR,\r
                        ("numRecvPoolEntries (%d) must be power of 2\n",\r
                                        pDst->numRecvPoolEntries) );\r
                return FALSE;\r
        }\r
        if ( !IsPowerOf2( pDst->freeRecvPoolEntriesPerUpdate ) )\r
        {\r
-               VNIC_TRACE( VNIC_DBG_CTRL| VNIC_DBG_ERROR,\r
+               VNIC_TRACE( VNIC_DBG_ERROR,\r
                        ("freeRecvPoolEntriesPerUpdate (%d) must be power of 2\n",\r
                                        pDst->freeRecvPoolEntriesPerUpdate) );\r
                return FALSE;\r
        }\r
        if ( pDst->freeRecvPoolEntriesPerUpdate >= pDst->numRecvPoolEntries )\r
        {\r
-               VNIC_TRACE( VNIC_DBG_CTRL| VNIC_DBG_ERROR,\r
+               VNIC_TRACE( VNIC_DBG_ERROR,\r
                        ("freeRecvPoolEntriesPerUpdate (%d) must be less than numRecvPoolEntries (%d)\n",\r
                        pDst->freeRecvPoolEntriesPerUpdate, pDst->numRecvPoolEntries) );\r
                        return FALSE;\r
        }\r
        if ( pDst->numRecvPoolEntriesBeforeKick >= pDst->numRecvPoolEntries )\r
        {\r
-               VNIC_TRACE( VNIC_DBG_CTRL| VNIC_DBG_ERROR,\r
+               VNIC_TRACE( VNIC_DBG_ERROR,\r
                        ("numRecvPoolEntriesBeforeKick (%d) must be less than numRecvPoolEntries (%d)\n",\r
                                pDst->numRecvPoolEntriesBeforeKick, pDst->numRecvPoolEntries) );\r
                        return FALSE;\r
@@ -1647,7 +1729,7 @@ __control_logControlPacket(
        case CMD_INIT_INIC:\r
                VNIC_PRINT( VNIC_DBG_CTRL_PKT,\r
                        ("ControlPacket: pktType = %s, pktCmd = CMD_INIT_INIC\n", type ) );\r
-               VNIC_PRINT( VNIC_DBG_CTRL,\r
+               VNIC_PRINT( VNIC_DBG_CTRL_PKT,\r
                        ("               pktSeqNum = %u, pktRetryCount = %u\n",\r
                                                                pPkt->hdr.pktSeqNum,\r
                                                                pPkt->hdr.pktRetryCount) );\r
index f6c2ce3..b18372b 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
- * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.\r
+ * Copyright (c) 2007 QLogic Corporation.  All rights reserved.\r
  *\r
  * This software is available to you under the OpenIB.org BSD license\r
  * below:\r
index 2c8b430..1242726 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
- * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.\r
+ * Copyright (c) 2007 QLogic Corporation.  All rights reserved.\r
  *\r
  * This software is available to you under the OpenIB.org BSD license\r
  * below:\r
@@ -118,6 +118,7 @@ typedef struct Inic_CmdInitInicRsp {
 #define INIC_FEAT_CHASH_OFFLOAD                        0x00004000\r
 #define INIC_FEAT_RDMA_IMMED                   0x00008000 \r
 #define INIC_FEAT_IGNORE_VLAN                  0x00010000\r
+#define INIC_FEAT_INBOUND_IB_MC                        0x00200000\r
 \r
 /* pktCmd CMD_CONFIG_DATA_PATH subdata format */\r
 typedef struct  Inic_RecvPoolConfig {\r
index fc69fba..8f007a5 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
- * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.\r
+ * Copyright (c) 2007 QLogic Corporation.  All rights reserved.\r
  *\r
  * This software is available to you under the OpenIB.org BSD license\r
  * below:\r
@@ -47,7 +47,7 @@ data_rdmaPacket(
                                BufferPoolEntry_t       *pBpe,\r
                                RdmaIo_t                        *pRdmaIo );\r
 static \r
-NDIS_PACKET *\r
+BOOLEAN\r
 _data_recv_to_ndis_pkt( \r
                                Data_t                  *pData,\r
                                RdmaDest_t              *pRdmaDest );\r
@@ -75,14 +75,6 @@ static uint8_t
 _tx_chksum_flags(\r
  IN            NDIS_PACKET* const              p_packet );\r
 \r
-\r
-static void\r
-_get_first_buffer(\r
-               IN              NDIS_PACKET             *p_packet,\r
-               IN OUT  NDIS_BUFFER             **pp_buf_desc,\r
-               OUT             void                    **pp_buf,\r
-               OUT             ULONG                   *p_packet_sz );\r
-\r
 static void\r
 _data_return_recv(\r
          IN    NDIS_PACKET             *p_packet );\r
@@ -116,8 +108,9 @@ data_construct(
        pData->p_viport = pViport;\r
        pData->p_phy_region = &pViport->p_adapter->ca.region;\r
        InitializeListHead( &pData->recvIos );\r
-       KeInitializeSpinLock ( &pData->recvIosLock );\r
-       KeInitializeSpinLock ( &pData->xmitBufLock );\r
+       KeInitializeSpinLock( &pData->recvListLock );\r
+       NdisAllocateSpinLock( &pData->recvIosLock );\r
+       NdisAllocateSpinLock( &pData->xmitBufLock );\r
        cl_timer_construct( &pData->kickTimer );\r
 \r
        ibqp_construct( &pData->qp, pViport );\r
@@ -190,7 +183,7 @@ data_connect(
        pXmitPool->notifyBundle     = pData->p_conf->notifyBundle;\r
        pXmitPool->nextXmitPool     = 0;\r
 \r
-#if TRUE // LIMIT_OUTSTANDING_SENDS\r
+#if LIMIT_OUTSTANDING_SENDS\r
        pXmitPool->numXmitBufs      = pXmitPool->notifyBundle * 2;\r
 #else /* !LIMIT_OUTSTANDING_SENDS */\r
        pXmitPool->numXmitBufs      = pXmitPool->poolSz;\r
@@ -293,8 +286,9 @@ data_connect(
                pRecvIo[i].dsList.length      = 4;\r
                pRecvIo[i].dsList.vaddr       = PTR64( pRegionData );\r
                pRecvIo[i].dsList.lkey        = pData->region.lkey;\r
-       \r
-               ExInterlockedInsertTailList( &pData->recvIos, &pRecvIo[i].io.listPtrs, &pData->recvIosLock );\r
+               \r
+               InitializeListHead( &pRecvIo[i].io.listPtrs );\r
+               ExInterlockedInsertTailList( &pData->recvIos, &pRecvIo[i].io.listPtrs, &pData->recvListLock );\r
         /* Do not need to move pointer since the receive info\r
          * is not read.  Note, we could reduce the amount\r
          * of memory allocated and the size of the region.\r
@@ -362,6 +356,7 @@ data_connect(
        for ( i = 0; i < pRecvPool->poolSz; i++ )\r
        {\r
                pRdmaDest = &pRecvPool->pRecvBufs[i];\r
+               pRdmaDest->p_viport = pData->p_viport;\r
                pRdmaDest->data = pData->p_recv_bufs + (i * pRecvPool->bufferSz );\r
                pRdmaDest->region = pData->rbuf_region;\r
                InsertTailList( &pRecvPool->availRecvBufs, &pRdmaDest->listPtrs );\r
@@ -420,7 +415,7 @@ err1:
 }\r
 \r
 \r
-void\r
+ib_api_status_t\r
 data_connected(\r
                IN              Data_t          *pData )\r
 {\r
@@ -431,10 +426,16 @@ data_connected(
 \r
        _data_allocBuffers(pData, TRUE);\r
        _data_sendFreeRecvBuffers(pData);\r
+       \r
+       if( pData->p_viport->errored )\r
+       {\r
+               return IB_ERROR;\r
+       }\r
+       \r
        pData->connected = TRUE;\r
 \r
        VNIC_EXIT( VNIC_DBG_DATA );\r
-       return;\r
+       return IB_SUCCESS;\r
 }\r
 \r
 void\r
@@ -444,7 +445,7 @@ data_disconnect(
        RecvPool_t *pRecvPool = &pData->recvPool;\r
        viport_t        *p_viport = pData->p_viport;\r
        NDIS_PACKET             *p_packet;\r
-       LIST_ENTRY              *p_list_item;\r
+       NDIS_BUFFER             *p_buf;\r
        unsigned int        i;\r
 \r
        VNIC_ENTER( VNIC_DBG_DATA );\r
@@ -464,21 +465,13 @@ data_disconnect(
                if ( p_packet != NULL )\r
                {\r
                        pRecvPool->pRecvBufs[i].p_packet = NULL;\r
-                       _data_return_recv( p_packet );\r
-               }\r
-       }\r
-       /* clear pending queue if any */\r
-       while( ( p_list_item = NdisInterlockedRemoveHeadList(\r
-               &p_viport->send_pending_list,\r
-               &p_viport->pending_list_lock )) != NULL )\r
-       {\r
-               p_packet = VNIC_PACKET_FROM_LIST_ITEM( p_list_item );\r
-               if ( p_packet )\r
-               {\r
-                       NDIS_SET_PACKET_STATUS( p_packet, NDIS_STATUS_FAILURE );\r
-                       NdisMSendComplete( p_viport->p_adapter->h_handle,\r
-                               p_packet, NDIS_STATUS_FAILURE );\r
-                       p_viport->stats.ifOutErrors++;\r
+                       NdisUnchainBufferAtFront( p_packet, &p_buf );\r
+                       if( p_buf )\r
+                       {\r
+                       /* Return the NDIS packet and NDIS buffer to their pools. */\r
+                               NdisFreeBuffer( p_buf );\r
+                       }\r
+                       NdisFreePacket( p_packet );\r
                }\r
        }\r
 \r
@@ -491,25 +484,24 @@ data_xmitPacket(
                IN              Data_t                          *pData,\r
                IN              NDIS_PACKET* const      p_packet )\r
 {\r
-       XmitPool_t              *p_xmitPool = &pData->xmitPool;\r
+       XmitPool_t              *p_xmitPool;\r
        RdmaIo_t                *pRdmaIo;\r
        BufferPoolEntry_t *pBpe;\r
        BOOLEAN                 last;\r
        uint8_t                 *p_buf;\r
        uint32_t                buf_len;\r
+       uint32_t                pkt_size;\r
        NDIS_BUFFER             *p_buf_desc;\r
        eth_hdr_t*              p_eth_hdr;\r
        int                             pad;\r
        SCATTER_GATHER_LIST             *p_sgl;\r
        uint32_t                i;\r
        PHYSICAL_ADDRESS phy_addr;\r
+       NDIS_PACKET_8021Q_INFO vlanInfo;\r
+       net16_t                 pri_vlan = 0;\r
 \r
        VNIC_ENTER( VNIC_DBG_DATA );\r
 \r
-       if( !data_allocXmitBuffer( pData, &pBpe, &pRdmaIo, &last ) )\r
-       {\r
-               return FALSE;\r
-       }\r
        p_sgl = NDIS_PER_PACKET_INFO_FROM_PACKET( p_packet,\r
                                                                                        ScatterGatherListPacketInfo );\r
        if ( p_sgl == NULL )\r
@@ -521,12 +513,13 @@ data_xmitPacket(
                                                                        &p_buf_desc,\r
                                                                        &p_buf,\r
                                                                        &buf_len,\r
-                                                                       &pRdmaIo->packet_sz,\r
+                                                                       &pkt_size,\r
                                                                        NormalPagePriority );\r
-       if( pRdmaIo->packet_sz > p_xmitPool->bufferSz )\r
+\r
+       if( pkt_size > pData->xmitPool.bufferSz )\r
        {\r
                VNIC_TRACE_EXIT( VNIC_DBG_ERROR,\r
-                       ("Outbound packet too large, size = %d\n", pRdmaIo->packet_sz ) );\r
+                       ("Outbound packet too large, size = %d\n", pkt_size ) );\r
                return FALSE;\r
        }\r
 \r
@@ -537,81 +530,85 @@ data_xmitPacket(
                                                                                p_sgl->NumberOfElements ) );\r
                return FALSE;\r
        }\r
-       pRdmaIo->p_packet = p_packet;\r
 \r
-       for( i=0; i < p_sgl->NumberOfElements; i++ )\r
+       vlanInfo.Value = NDIS_PER_PACKET_INFO_FROM_PACKET( p_packet, Ieee8021QInfo );\r
+       p_eth_hdr = (eth_hdr_t *)p_buf;\r
+\r
+       if( vlanInfo.Value ) /* there is VLAN_ID specified the packet */\r
        {\r
-               pRdmaIo->dsList[i].vaddr = p_sgl->Elements[i].Address.QuadPart;\r
-               pRdmaIo->dsList[i].length = p_sgl->Elements[i].Length;\r
+               if( vlanInfo.TagHeader.VlanId != 0 )\r
+               {\r
+                       /* packet vlanId does not match */\r
+                       if( pData->p_viport->p_adapter->vlan_info &&\r
+                               ( pData->p_viport->p_adapter->vlan_info & 0x00000fff ) != vlanInfo.TagHeader.VlanId )\r
+                       {\r
+                               return FALSE;\r
+                       }\r
+                       pri_vlan = (uint16_t)vlanInfo.TagHeader.VlanId;\r
+                       pri_vlan |= (uint16_t)( vlanInfo.TagHeader.UserPriority << 13 );\r
+               }\r
+               else if( pData->p_viport->p_adapter->vlan_info )\r
+               {\r
+                       pri_vlan = (uint16_t)( pData->p_viport->p_adapter->vlan_info );\r
+               }\r
        }\r
+       else  /* no VLAN_ID info in a packet */\r
+       {\r
+               if( pData->p_viport->p_adapter->vlan_info )\r
+               {\r
+                       pri_vlan = (uint16_t)( pData->p_viport->p_adapter->vlan_info );\r
+               }\r
+       }\r
+\r
+       if( !data_allocXmitBuffer( pData, &pBpe, &pRdmaIo, &last ) )\r
+       {\r
+               return FALSE;\r
+       }\r
+\r
+       pRdmaIo->p_packet = p_packet;\r
+       pRdmaIo->packet_sz = pkt_size;\r
 \r
        pRdmaIo->len = (uint32_t)ROUNDUPP2(\r
-               max(60, pRdmaIo->packet_sz), VIPORT_TRAILER_ALIGNMENT );\r
+               max(MIN_PACKET_LEN, pRdmaIo->packet_sz), VIPORT_TRAILER_ALIGNMENT );\r
        pad = pRdmaIo->len - pRdmaIo->packet_sz;\r
 \r
-       p_eth_hdr = (eth_hdr_t *)p_buf;\r
-\r
        pRdmaIo->p_trailer = (ViportTrailer_t *)&pRdmaIo->data[pad];\r
+       \r
        cl_memclr( pRdmaIo->data, pad + sizeof( ViportTrailer_t ) );\r
        cl_memcpy( pRdmaIo->p_trailer->destMacAddr, p_eth_hdr->dst.addr, MAC_ADDR_LEN );\r
-\r
+       \r
        pRdmaIo->p_trailer->dataLength =\r
-                                       hton16( (uint16_t)max( 60, pRdmaIo->packet_sz ) );\r
-\r
-       NdisGetNextBuffer( p_buf_desc, &p_buf_desc );\r
-\r
-       /* should handle VLAN tag */\r
-       if( pRdmaIo->packet_sz > 16 )\r
+                                       cl_hton16( (uint16_t)max( MIN_PACKET_LEN, pRdmaIo->packet_sz ) );\r
+       \r
+       if( pri_vlan )\r
        {\r
-               if(     p_eth_hdr->type == hton16(0x8100) )\r
+               /* if tagged frame */\r
+               if( *(uint16_t *)(p_buf + 12 ) == ETH_PROT_VLAN_TAG )\r
                {\r
-                       if( p_sgl->Elements[0].Length > sizeof(eth_hdr_t) )\r
-                       {\r
-                               pRdmaIo->p_trailer->vLan = *(uint16_t *)((uint8_t *)p_eth_hdr + 14 );\r
-                               pRdmaIo->p_trailer->pktFlags |= PF_VLAN_INSERT;\r
-                       }\r
-                       else\r
-                       {\r
-                               if( p_buf_desc )\r
-                               {\r
-                                       NdisQueryBufferSafe( p_buf_desc, &p_buf, &buf_len, NormalPagePriority );\r
-\r
-                                       pad = sizeof(eth_hdr_t) - p_sgl->Elements[0].Length;\r
-                                       pRdmaIo->p_trailer->vLan = *(uint16_t *)(p_buf + pad + 2);\r
-                                       pRdmaIo->p_trailer->pktFlags |= PF_VLAN_INSERT;\r
-                               }\r
-                       }\r
+                       /* strip vlan tag from header */\r
+                       RtlMoveMemory( p_buf + 4, p_buf, 12 );\r
+                       /* adjust data length */\r
+                       pRdmaIo->p_trailer->dataLength = \r
+                               cl_hton16( (uint16_t)max( MIN_PACKET_LEN, pRdmaIo->packet_sz ) - 4 );\r
                }\r
-               /* hash operation seem quite expensive\r
-               * should figure out anther way to do this\r
-               * meanwhile let's embedded do it for us.\r
-               ********************************************\r
-               else if( p_eth_hdr->type == ETH_PROT_TYPE_IP &&\r
-                               !( p_eth_hdr->dst.addr[0] & 0x01 ) )\r
-               {\r
-                       if( p_buf_desc )\r
-                       {\r
-                               NdisQueryBufferSafe( p_buf_desc, &p_buf, &buf_len, NormalPagePriority );\r
-\r
-                               if( ((ip_pkt_t*)p_buf)->hdr.prot == IP_PROT_UDP ||\r
-                                       ((ip_pkt_t*)p_buf)->hdr.prot == IP_PROT_TCP )\r
-                               {\r
-                                       // use socket src port + dest port to generate hash value\r
-                                       // for link aggregation distribution function.\r
-                                       //\r
-                                       pRdmaIo->p_trailer->connectionHashAndValid = CHV_VALID |\r
-                                               ((uint8_t)ntoh16(((ip_pkt_t*)p_buf)->prot.tcp.src_port ) +\r
-                                               (uint8_t)ntoh16(((ip_pkt_t*)p_buf)->prot.tcp.dst_port )) & CHV_HASH_MASH;\r
-                                       pRdmaIo->p_trailer->pktFlags |= PF_CHASH_VALID;\r
-                               }\r
-                               else\r
-                                       pRdmaIo->p_trailer->pktFlags &= ~PF_CHASH_VALID;\r
-                       }\r
-               }\r
-               **********************/\r
+               pRdmaIo->p_trailer->vLan = cl_hton16( pri_vlan );\r
+               pRdmaIo->p_trailer->pktFlags |= PF_VLAN_INSERT;\r
        }\r
 \r
-       pRdmaIo->p_trailer->txChksumFlags = _tx_chksum_flags( p_packet );\r
+       for( i=0; i < p_sgl->NumberOfElements; i++ )\r
+       {\r
+               pRdmaIo->dsList[i].vaddr = p_sgl->Elements[i].Address.QuadPart;\r
+               pRdmaIo->dsList[i].length = p_sgl->Elements[i].Length;\r
+       }\r
+       if( viport_canTxCsum( pData->p_viport ) && \r
+               pData->p_viport->p_adapter->params.UseTxCsum )\r
+       {\r
+               pRdmaIo->p_trailer->txChksumFlags = _tx_chksum_flags( p_packet );\r
+       }\r
+       else\r
+       {\r
+               pRdmaIo->p_trailer->txChksumFlags = 0;\r
+       }\r
        pRdmaIo->p_trailer->connectionHashAndValid |= CHV_VALID;\r
 \r
        if( last )\r
@@ -633,7 +630,7 @@ data_xmitPacket(
                                        ("RDMA WRITE Failed\n"));\r
                return FALSE;\r
        }\r
-\r
+       p_xmitPool = &pData->xmitPool;\r
        if( p_xmitPool->sendKicks )\r
        {\r
                /* EIOC needs kicks to inform it of sent packets */\r
@@ -652,6 +649,7 @@ data_xmitPacket(
        }\r
        return TRUE;\r
 }\r
+\r
 static uint8_t\r
 _tx_chksum_flags(\r
                  IN    NDIS_PACKET* const              p_packet )\r
@@ -688,25 +686,6 @@ _tx_chksum_flags(
        return txChksumFlags;\r
 }\r
 \r
-static void\r
-_get_first_buffer(\r
-               IN              NDIS_PACKET             *p_packet,\r
-               IN OUT  NDIS_BUFFER             **pp_buf_desc,\r
-               OUT             void                    **pp_buf,\r
-               OUT             ULONG                   *p_packet_sz )\r
-{\r
-       UINT            buf_len;\r
-       VNIC_ENTER( VNIC_DBG_DATA );\r
-\r
-       NdisGetFirstBufferFromPacketSafe( p_packet,\r
-                                                                       pp_buf_desc,\r
-                                                                       pp_buf,\r
-                                                                       &buf_len,\r
-                                                                       p_packet_sz,\r
-                                                                       NormalPagePriority );\r
-       VNIC_EXIT( VNIC_DBG_DATA );\r
-}\r
-\r
 static void\r
 data_postRecvs(\r
                IN              Data_t          *pData )\r
@@ -714,12 +693,13 @@ data_postRecvs(
        RecvIo_t                *pRecvIo;\r
        LIST_ENTRY              *p_list_entry;\r
        ib_api_status_t ib_status;\r
-\r
+       \r
        VNIC_ENTER ( VNIC_DBG_DATA );\r
 \r
-       while( ( p_list_entry = ExInterlockedRemoveHeadList( &pData->recvIos,\r
-                                                                                                                &pData->recvIosLock ))\r
-                                                                                                               != NULL )\r
+       if( pData->p_viport->errored )\r
+               return;\r
+\r
+       while( ( p_list_entry = ExInterlockedRemoveHeadList( &pData->recvIos, &pData->recvListLock  ) ) != NULL )\r
        {\r
                pRecvIo = (RecvIo_t *)p_list_entry;\r
 \r
@@ -741,40 +721,40 @@ static void
 _data_receivedKick(\r
                        IN              Io_t            *pIo )\r
 {\r
-       Data_t        *pData = &pIo->pViport->data;\r
-       uint32_t                num_pkts = 0;\r
+\r
+       uint32_t        num_pkts = 0;\r
 \r
        VNIC_ENTER( VNIC_DBG_DATA );\r
 \r
+       NdisAcquireSpinLock( &pIo->pViport->data.recvIosLock );\r
+\r
 #ifdef VNIC_STATISTIC\r
        recvRef = cl_get_tick_count();\r
 #endif /* VNIC_STATISTIC */\r
 \r
-       ExInterlockedInsertTailList( &pData->recvIos, &pIo->listPtrs, &pData->recvIosLock );\r
+       ExInterlockedInsertTailList( &pIo->pViport->data.recvIos, \r
+                                                               &pIo->listPtrs, \r
+                                                               &pIo->pViport->data.recvListLock );\r
 \r
-       data_postRecvs( pData );\r
+       data_postRecvs( &pIo->pViport->data );\r
 \r
 #ifdef VNIC_STATISTIC\r
-       pData->statistics.kickRecvs++;\r
+       pIo->pViport->data.statistics.kickRecvs++;\r
 #endif /* VNIC_STATISTIC */\r
 \r
-       data_checkXmitBuffers( pData );\r
+       data_checkXmitBuffers( &pIo->pViport->data );\r
+\r
+       num_pkts = _data_incomingRecv( &pIo->pViport->data );\r
 \r
-       num_pkts = _data_incomingRecv( pData );\r
+       NdisReleaseSpinLock(&pIo->pViport->data.recvIosLock );\r
 \r
        if( num_pkts )\r
        {\r
-               NdisMIndicateReceivePacket( pData->p_viport->p_adapter->h_handle,\r
-                                                                       pData->recvPool.recv_pkt_array,\r
-                                                                       num_pkts );\r
-               pData->p_viport->stats.ifInOk += num_pkts;\r
-       }\r
+               viport_recvPacket( pIo->pViport,\r
+                       pIo->pViport->data.recvPool.recv_pkt_array,\r
+                       num_pkts );\r
 \r
-       if( pData->p_viport->data.connected == TRUE &&\r
-               !pData->p_viport->errored )\r
-       {\r
-               _data_allocBuffers( pData, FALSE );\r
-               _data_sendFreeRecvBuffers( pData );\r
+               pIo->pViport->stats.ifInOk += num_pkts;\r
        }\r
 \r
        VNIC_EXIT( VNIC_DBG_DATA );\r
@@ -785,17 +765,25 @@ static void
 _data_xmitComplete(\r
                        IN              Io_t            *pIo )\r
 {\r
-       RdmaIo_t       *pRdmaIo = (RdmaIo_t *)pIo;\r
-       Data_t         *pData = &pIo->pViport->data;\r
-       XmitPool_t     *p_xmitPool = &pData->xmitPool;\r
+\r
+       Data_t         *pData;\r
+       XmitPool_t     *p_xmitPool;\r
        NDIS_PACKET             *p_packet;\r
        NDIS_STATUS             ndis_status;\r
+       uint32_t                io_index;\r
 \r
        VNIC_ENTER( VNIC_DBG_DATA );\r
+       \r
+       NdisAcquireSpinLock( &pIo->pViport->data.xmitBufLock );\r
+       \r
+       io_index = ((RdmaIo_t *)pIo)->index;\r
+       pData = &pIo->pViport->data;\r
+       p_xmitPool = &pData->xmitPool;\r
 \r
-       while ( p_xmitPool->lastCompBuf != pRdmaIo->index )\r
+       while ( p_xmitPool->lastCompBuf != io_index )\r
        {\r
                INC(p_xmitPool->lastCompBuf, 1, p_xmitPool->numXmitBufs);\r
+       \r
                p_packet = p_xmitPool->pXmitBufs[p_xmitPool->lastCompBuf].p_packet;\r
        \r
                p_xmitPool->pXmitBufs[p_xmitPool->lastCompBuf].p_packet = NULL;\r
@@ -818,6 +806,7 @@ _data_xmitComplete(
                                                                p_packet, ndis_status );\r
                }\r
        }\r
+       NdisReleaseSpinLock( &pData->xmitBufLock );\r
 \r
        if( !pData->p_viport->errored )\r
        {\r
@@ -876,13 +865,13 @@ data_allocXmitBuffer(
                OUT             RdmaIo_t                        **ppRdmaIo,\r
                OUT             BOOLEAN                         *pLast )\r
 {\r
-       XmitPool_t    *p_xmitPool = &pData->xmitPool;\r
-       KIRQL flags;\r
+       XmitPool_t    *p_xmitPool;\r
 \r
        VNIC_ENTER( VNIC_DBG_DATA );\r
 \r
-       KeAcquireSpinLock( &pData->xmitBufLock, &flags );\r
-\r
+       NdisAcquireSpinLock( &pData->xmitBufLock );\r
+       \r
+       p_xmitPool = &pData->xmitPool;\r
        *pLast = FALSE;\r
        *ppRdmaIo = &p_xmitPool->pXmitBufs[p_xmitPool->nextXmitBuf];\r
        *ppBpe = &p_xmitPool->bufPool[p_xmitPool->nextXmitPool];\r
@@ -915,7 +904,7 @@ data_allocXmitBuffer(
 \r
                (*ppBpe)->valid  = 0;\r
 \r
-               KeReleaseSpinLock( &pData->xmitBufLock, flags );\r
+               NdisReleaseSpinLock( &pData->xmitBufLock );\r
                return TRUE;\r
        }\r
        else\r
@@ -929,7 +918,7 @@ data_allocXmitBuffer(
 \r
                viport_stopXmit( pData->p_viport );\r
 \r
-               KeReleaseSpinLock( &pData->xmitBufLock, flags );\r
+               NdisReleaseSpinLock( &pData->xmitBufLock );\r
                return FALSE;\r
        }\r
 }\r
@@ -938,16 +927,13 @@ static void
 data_checkXmitBuffers(\r
                IN                      Data_t          *pData )\r
 {\r
-       XmitPool_t      *p_xmitPool = &pData->xmitPool;\r
-       KIRQL           flags;\r
-\r
        VNIC_ENTER( VNIC_DBG_DATA );\r
 \r
-       KeAcquireSpinLock( &pData->xmitBufLock, &flags );\r
+       NdisAcquireSpinLock( &pData->xmitBufLock );\r
 \r
        if ( pData->xmitPool.needBuffers\r
-               && p_xmitPool->bufPool[p_xmitPool->nextXmitPool].valid\r
-               && p_xmitPool->nextXmitBuf != p_xmitPool->lastCompBuf )\r
+               && pData->xmitPool.bufPool[pData->xmitPool.nextXmitPool].valid\r
+               && pData->xmitPool.nextXmitBuf != pData->xmitPool.lastCompBuf )\r
        {\r
                pData->xmitPool.needBuffers = FALSE;\r
                viport_restartXmit( pData->p_viport );\r
@@ -956,7 +942,7 @@ data_checkXmitBuffers(
                                                ("There are free xmit buffers\n") );\r
        }\r
 \r
-       KeReleaseSpinLock( &pData->xmitBufLock, flags );\r
+       NdisReleaseSpinLock( &pData->xmitBufLock );\r
 \r
        VNIC_EXIT( VNIC_DBG_DATA );\r
        return;\r
@@ -1016,35 +1002,29 @@ data_rdmaPacket(
        return IB_SUCCESS;\r
 }\r
 \r
-static NDIS_PACKET *\r
+static BOOLEAN\r
 _data_recv_to_ndis_pkt(\r
                IN              Data_t                  *pData,\r
                IN              RdmaDest_t              *pRdmaDest )\r
 {\r
        struct ViportTrailer *pTrailer;\r
-       NDIS_PACKET             *p_packet;\r
-       NDIS_STATUS             ndis_status;\r
-       int                  start;\r
-       unsigned int         len;\r
-       uint8_t rxChksumFlags;\r
+       NDIS_PACKET                     *p_packet;\r
+       NDIS_STATUS                     ndis_status;\r
+       int                                     start;\r
+       unsigned int            len;\r
        NDIS_TCP_IP_CHECKSUM_PACKET_INFO  packet_info;\r
+       NDIS_PACKET_8021Q_INFO vlan_info;\r
+       uint16_t                        vlanId;\r
+       uint8_t                         rxChksumFlags;\r
 \r
        VNIC_ENTER( VNIC_DBG_DATA );\r
 \r
        pTrailer = pRdmaDest->pTrailer;\r
+       p_packet = pRdmaDest->p_packet;\r
+\r
        start = (int)data_offset(pData, pTrailer);\r
        len = data_len(pData, pTrailer);\r
 \r
-       NdisAllocatePacket( &ndis_status,\r
-                                               &p_packet,\r
-                                               pData->h_recv_pkt_pool );\r
-\r
-       if ( ndis_status != NDIS_STATUS_SUCCESS )\r
-       {\r
-               VNIC_TRACE_EXIT( VNIC_DBG_ERROR,\r
-                       ( "NdisAllocatePacket failed %#x\n", ndis_status ) );\r
-               return NULL;\r
-       }\r
        NdisAllocateBuffer( &ndis_status,\r
                                                &pRdmaDest->p_buf,\r
                                                pData->h_recv_buf_pool,\r
@@ -1055,63 +1035,81 @@ _data_recv_to_ndis_pkt(
        {\r
                VNIC_TRACE_EXIT( VNIC_DBG_ERROR,\r
                        ( "NdisAllocateBuffer failed %#x\n", ndis_status ) );\r
-               NdisFreePacket( p_packet );\r
-               return NULL;\r
+               return FALSE;\r
        }\r
 \r
        NdisChainBufferAtFront( p_packet, pRdmaDest->p_buf );\r
-       pRdmaDest->p_packet = p_packet;\r
+       pRdmaDest->buf_sz = len;\r
 \r
        if ( pTrailer->pktFlags & PF_VLAN_INSERT &&\r
                !( pData->p_viport->featuresSupported & INIC_FEAT_IGNORE_VLAN ) )\r
        {\r
-               /*      TODO:\r
-                *      add OID_GEN_VLAN_ID\r
-                *      handle VLAN     tag insertion\r
-                *      set packet header size = eth_hdr + 4\r
-                */\r
-       }\r
+               /*      handle VLAN     tag insertion */\r
+               vlan_info.Value = NDIS_PER_PACKET_INFO_FROM_PACKET( p_packet, Ieee8021QInfo );\r
+               vlanId = cl_ntoh16( pTrailer->vLan );\r
 \r
-       NDIS_SET_PACKET_HEADER_SIZE( p_packet, sizeof(eth_hdr_t) );\r
+               if( !( vlanId & 0xfff ) ||\r
+                       ( ( (vlanId & 0xfff ) != 0 ) && \r
+                         (vlanId & 0xfff ) == ((uint16_t)pData->p_viport->p_adapter->vlan_info & 0xfff ) ))\r
+               {\r
+                       if( pTrailer->pktFlags & PF_PVID_OVERRIDDEN )\r
+                       {\r
+                               vlan_info.TagHeader.VlanId =  0;\r
+                       }\r
+                       else\r
+                       {\r
+                               vlan_info.TagHeader.VlanId =  vlanId & 0xfff;\r
+                       }\r
+                       vlan_info.TagHeader.UserPriority = vlanId & 0xe000;\r
+                       vlan_info.TagHeader.CanonicalFormatId = 0;\r
+                       vlan_info.TagHeader.Reserved = 0;\r
+                       NDIS_PER_PACKET_INFO_FROM_PACKET( p_packet, Ieee8021QInfo ) = vlan_info.Value;\r
+               }\r
+       }\r
 \r
-       rxChksumFlags = pTrailer->rxChksumFlags;\r
+       if( viport_canRxCsum( pData->p_viport ) &&\r
+               pData->p_viport->p_adapter->params.UseRxCsum )\r
+       {\r
+               rxChksumFlags = pTrailer->rxChksumFlags;\r
 \r
-       VNIC_TRACE( VNIC_DBG_DATA,\r
-               ("rxChksumFlags = %d, LOOP = %c, IP = %c, TCP = %c, UDP = %c\n",\r
-               rxChksumFlags,\r
-               (rxChksumFlags & RX_CHKSUM_FLAGS_LOOPBACK)? 'Y': 'N',\r
-               (rxChksumFlags & RX_CHKSUM_FLAGS_IP_CHECKSUM_SUCCEEDED)? 'Y':\r
+               VNIC_TRACE( VNIC_DBG_DATA,\r
+                       ("rxChksumFlags = %d, LOOP = %c, IP = %c, TCP = %c, UDP = %c\n",\r
+                       rxChksumFlags,\r
+                       (rxChksumFlags & RX_CHKSUM_FLAGS_LOOPBACK)? 'Y': 'N',\r
+                       (rxChksumFlags & RX_CHKSUM_FLAGS_IP_CHECKSUM_SUCCEEDED)? 'Y':\r
                (rxChksumFlags & RX_CHKSUM_FLAGS_IP_CHECKSUM_FAILED)? 'N': '-',\r
-               (rxChksumFlags & RX_CHKSUM_FLAGS_TCP_CHECKSUM_SUCCEEDED)? 'Y':\r
+                       (rxChksumFlags & RX_CHKSUM_FLAGS_TCP_CHECKSUM_SUCCEEDED)? 'Y':\r
                (rxChksumFlags & RX_CHKSUM_FLAGS_TCP_CHECKSUM_FAILED)? 'N': '-',\r
-               (rxChksumFlags & RX_CHKSUM_FLAGS_UDP_CHECKSUM_SUCCEEDED)? 'Y':\r
+                       (rxChksumFlags & RX_CHKSUM_FLAGS_UDP_CHECKSUM_SUCCEEDED)? 'Y':\r
                (rxChksumFlags & RX_CHKSUM_FLAGS_UDP_CHECKSUM_FAILED)? 'N': '-') );\r
 \r
-       packet_info.Value = 0;\r
+               packet_info.Value = 0;\r
 \r
-       if( rxChksumFlags & RX_CHKSUM_FLAGS_IP_CHECKSUM_SUCCEEDED )\r
-               packet_info.Receive.NdisPacketIpChecksumSucceeded = TRUE;\r
-       else if( rxChksumFlags & RX_CHKSUM_FLAGS_IP_CHECKSUM_FAILED )\r
-               packet_info.Receive.NdisPacketIpChecksumFailed = TRUE;\r
+               if( rxChksumFlags & RX_CHKSUM_FLAGS_IP_CHECKSUM_SUCCEEDED )\r
+                       packet_info.Receive.NdisPacketIpChecksumSucceeded = TRUE;\r
+               else if( rxChksumFlags & RX_CHKSUM_FLAGS_IP_CHECKSUM_FAILED )\r
+                       packet_info.Receive.NdisPacketIpChecksumFailed = TRUE;\r
 \r
-       if( rxChksumFlags & RX_CHKSUM_FLAGS_TCP_CHECKSUM_SUCCEEDED )\r
-               packet_info.Receive.NdisPacketTcpChecksumSucceeded = TRUE;\r
-       else if( rxChksumFlags & RX_CHKSUM_FLAGS_TCP_CHECKSUM_FAILED )\r
-               packet_info.Receive.NdisPacketTcpChecksumFailed = TRUE;\r
+               if( rxChksumFlags & RX_CHKSUM_FLAGS_TCP_CHECKSUM_SUCCEEDED )\r
+                       packet_info.Receive.NdisPacketTcpChecksumSucceeded = TRUE;\r
+               else if( rxChksumFlags & RX_CHKSUM_FLAGS_TCP_CHECKSUM_FAILED )\r
+                       packet_info.Receive.NdisPacketTcpChecksumFailed = TRUE;\r
 \r
-       if( rxChksumFlags & RX_CHKSUM_FLAGS_TCP_CHECKSUM_SUCCEEDED )\r
-               packet_info.Receive.NdisPacketUdpChecksumSucceeded = TRUE;\r
-       else if( rxChksumFlags & RX_CHKSUM_FLAGS_TCP_CHECKSUM_FAILED )\r
-               packet_info.Receive.NdisPacketUdpChecksumFailed = TRUE;\r
+               if( rxChksumFlags & RX_CHKSUM_FLAGS_TCP_CHECKSUM_SUCCEEDED )\r
+                       packet_info.Receive.NdisPacketUdpChecksumSucceeded = TRUE;\r
+               else if( rxChksumFlags & RX_CHKSUM_FLAGS_TCP_CHECKSUM_FAILED )\r
+                       packet_info.Receive.NdisPacketUdpChecksumFailed = TRUE;\r
 \r
-       NDIS_PER_PACKET_INFO_FROM_PACKET( p_packet, TcpIpChecksumPacketInfo )=\r
-                                                                               (void *)(uintn_t)packet_info.Value;\r
+               NDIS_PER_PACKET_INFO_FROM_PACKET( p_packet, TcpIpChecksumPacketInfo )=\r
+                       (void *)(uintn_t)packet_info.Value;\r
+       }\r
 \r
-       VNIC_RECV_FROM_PACKET( p_packet ) = pRdmaDest;\r
        NDIS_SET_PACKET_STATUS( p_packet, NDIS_STATUS_SUCCESS );\r
+       NDIS_SET_PACKET_HEADER_SIZE( p_packet, sizeof(eth_hdr_t) );\r
+       VNIC_RECV_FROM_PACKET( p_packet ) = pRdmaDest;\r
 \r
        VNIC_EXIT( VNIC_DBG_DATA );\r
-       return p_packet;\r
+       return TRUE;\r
 }\r
 \r
 /* NOTE: This routine is not reentrant */\r
@@ -1120,6 +1118,7 @@ _data_allocBuffers(
                IN                      Data_t          *pData,\r
                IN                      BOOLEAN         initialAllocation )\r
 {\r
+       NDIS_STATUS             ndis_status;\r
        RecvPool_t     *p_recvPool = &pData->recvPool;\r
        RdmaDest_t     *pRdmaDest;\r
        LIST_ENTRY              *p_list_entry;\r
@@ -1141,10 +1140,20 @@ _data_allocBuffers(
                                (struct ViportTrailer*)(pRdmaDest->data + pRdmaDest->buf_sz\r
                                - sizeof(struct ViportTrailer));\r
                        pRdmaDest->pTrailer->connectionHashAndValid = 0;\r
+\r
+                       NdisAllocatePacket( &ndis_status,\r
+                                                               &pRdmaDest->p_packet,\r
+                                                               pData->h_recv_pkt_pool );\r
+\r
+                       if ( ndis_status != NDIS_STATUS_SUCCESS )\r
+                       {\r
+                               VNIC_TRACE_EXIT( VNIC_DBG_ERROR,\r
+                                       ( "NdisAllocatePacket failed %#x\n", ndis_status ) );\r
+                               return;\r
+                       }\r
                }\r
 \r
-               pRdmaDest->p_packet = NULL;\r
-               _data_addFreeBuffer(pData, index, pRdmaDest);\r
+               _data_addFreeBuffer( pData, index, pRdmaDest );\r
                index = NEXT(index,p_recvPool->eiocPoolSz);\r
        }\r
 \r
@@ -1180,7 +1189,6 @@ _data_incomingRecv(
        RdmaDest_t        *pRdmaDest;\r
        ViportTrailer_t   *pTrailer;\r
        BufferPoolEntry_t *pBpe;\r
-       NDIS_PACKET             *p_packet = NULL;\r
        uint32_t                idx = 0;\r
        BOOLEAN status = FALSE;\r
 \r
@@ -1192,6 +1200,9 @@ _data_incomingRecv(
                        return idx;\r
 \r
                pBpe = &p_recvPool->bufPool[p_recvPool->nextFullBuf];\r
+\r
+               CL_ASSERT(pBpe->valid != 0 );\r
+\r
                pRdmaDest = &p_recvPool->pRecvBufs[pBpe->valid - 1];\r
                pTrailer = pRdmaDest->pTrailer;\r
 \r
@@ -1203,14 +1214,14 @@ _data_incomingRecv(
                        {\r
                                p_recvPool->kickOnFree = TRUE;\r
                        }\r
-                       /* we do not want to indicate packet if  no filter is set */\r
-                       if( pData->p_viport->p_adapter->packet_filter &&\r
+                       /* we do not want to indicate packet if filter is not set */\r
+                       if( pData->p_viport->p_adapter->xmitStarted &&\r
+                               pData->p_viport->p_adapter->packet_filter &&\r
                                p_recvPool->numPostedBufs > 0 )\r
                        {\r
-                               p_packet = _data_recv_to_ndis_pkt( pData, pRdmaDest );\r
-                               if ( p_packet != NULL )\r
+                               if ( _data_recv_to_ndis_pkt( pData, pRdmaDest ) )\r
                                {\r
-                                       p_recvPool->recv_pkt_array[idx++] = p_packet;\r
+                                       p_recvPool->recv_pkt_array[idx++] = pRdmaDest->p_packet;\r
                                }\r
                        }\r
                        else\r
@@ -1238,30 +1249,50 @@ vnic_return_packet(
        IN              NDIS_PACKET     * const p_packet )\r
 {\r
 \r
+       RdmaDest_t      *p_rdma_dest;\r
+       viport_t        *p_viport;\r
+       \r
+       VNIC_ENTER( VNIC_DBG_DATA );\r
 \r
-       vnic_adapter_t  *p_adapter = (vnic_adapter_t *)adapter_context;\r
-       viport_t        *p_viport = p_adapter->p_currentPath->pViport;\r
-       RdmaDest_t      *p_rdma_dest = VNIC_RECV_FROM_PACKET( p_packet );\r
+       UNREFERENCED_PARAMETER( adapter_context );\r
 \r
-       ASSERT( p_rdma_dest->p_packet == p_packet );\r
-       _data_return_recv( p_packet );\r
-       p_rdma_dest->p_packet = NULL;\r
+       p_rdma_dest = VNIC_RECV_FROM_PACKET( p_packet );\r
+       p_viport = p_rdma_dest->p_viport;\r
 \r
+       ASSERT( p_rdma_dest->p_packet == p_packet );    \r
+\r
+       NdisAcquireSpinLock( &p_viport->data.recvIosLock );\r
+       \r
+       _data_return_recv( p_packet );\r
+       \r
+       NdisReinitializePacket( p_packet );\r
+       \r
        InsertTailList( &p_viport->data.recvPool.availRecvBufs,\r
                                        &p_rdma_dest->listPtrs );\r
+       _data_allocBuffers( &p_viport->data, FALSE );\r
+       _data_sendFreeRecvBuffers( &p_viport->data );\r
 \r
+       NdisReleaseSpinLock(&p_viport->data.recvIosLock );\r
+\r
+       VNIC_EXIT( VNIC_DBG_DATA );\r
 }\r
 static void\r
 _data_return_recv(\r
          IN    NDIS_PACKET             *p_packet )\r
 {\r
        NDIS_BUFFER             *p_buf;\r
+       PNDIS_PACKET_OOB_DATA p_oob_data;\r
+  \r
        /* Unchain the NDIS buffer. */\r
        NdisUnchainBufferAtFront( p_packet, &p_buf );\r
-       CL_ASSERT( p_buf );\r
-       /* Return the NDIS packet and NDIS buffer to their pools. */\r
-       NdisFreeBuffer( p_buf );\r
-       NdisFreePacket( p_packet );\r
+       if( p_buf )\r
+       {\r
+               /* Return the NDIS packet and NDIS buffer to their pools. */\r
+               NdisFreeBuffer( p_buf );\r
+       }\r
+       /* take care of OOB_DATA block since NdisReinitializePacket doesn't */\r
+       p_oob_data = NDIS_OOB_DATA_FROM_PACKET( p_packet );\r
+       NdisZeroMemory( p_oob_data, sizeof( NDIS_PACKET_OOB_DATA ));\r
 }\r
 \r
 static void\r
@@ -1279,13 +1310,13 @@ _data_sendFreeRecvBuffers(
 \r
        VNIC_ENTER( VNIC_DBG_DATA );\r
 \r
-       for (   numToSend = MIN_EIOC_UPDATE_SZ;\r
+       for (   numToSend = p_recvPool->szFreeBundle;\r
                        numToSend <= p_recvPool->numFreeBufs;\r
-                       numToSend += MIN_EIOC_UPDATE_SZ )\r
+                       numToSend += p_recvPool->szFreeBundle )\r
        {\r
 \r
                /* Handle multiple bundles as one when possible. */\r
-               nextIncrement = numToSend + MIN_EIOC_UPDATE_SZ;\r
+               nextIncrement = numToSend + p_recvPool->szFreeBundle;\r
                if (( nextIncrement <= p_recvPool->numFreeBufs )\r
                                && ( p_recvPool->nextFreeBuf + nextIncrement <= p_recvPool->eiocPoolSz ) )\r
                {\r
@@ -1325,8 +1356,10 @@ _data_sendFreeRecvBuffers(
        if( p_recvPool->numPostedBufs == 0 )\r
        {\r
                VNIC_TRACE( VNIC_DBG_ERROR,\r
-                               ("IOC %d: Unable to allocate receive buffers\n",\r
-                                       pData->p_viport->ioc_num ) );\r
+                       ("IOC %d: Unable to allocate receive buffers NumFreeBufs: %d nextFreeBuf: %d nextFullBuf %d eiocPoolSz: %d\n",\r
+                       pData->p_viport->ioc_num, p_recvPool->numFreeBufs,\r
+                       p_recvPool->nextFreeBuf, p_recvPool->nextFullBuf,\r
+                       p_recvPool->eiocPoolSz ) );\r
        \r
                //viport_failure( pData->p_viport );\r
        }\r
@@ -1340,7 +1373,7 @@ data_cleanup(
 {\r
        VNIC_ENTER( VNIC_DBG_DATA );\r
 \r
-       VNIC_TRACE(VNIC_DBG_INIT,\r
+       VNIC_TRACE(VNIC_DBG_DATA,\r
                        ("IOC[%d]data cleanup\n", pData->p_viport->ioc_num ));\r
 \r
        if( pData->p_recv_bufs )\r
index 4f156e3..14bc0c1 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
- * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.\r
+ * Copyright (c) 2007 QLogic Corporation.  All rights reserved.\r
  *\r
  * This software is available to you under the OpenIB.org BSD license\r
  * below:\r
@@ -37,6 +37,7 @@
 typedef struct RdmaDest {\r
        LIST_ENTRY                      listPtrs;\r
        IbRegion_t                      region;\r
+       struct _viport          *p_viport;\r
        NDIS_PACKET                     *p_packet;\r
        NDIS_BUFFER                     *p_buf;\r
        uint32_t                        buf_sz;\r
@@ -107,8 +108,9 @@ typedef struct Data {
        RdmaIo_t                                freeBufsIo;\r
        SendIo_t                                kickIo;\r
        LIST_ENTRY                              recvIos;\r
-       KSPIN_LOCK                              recvIosLock;\r
-       KSPIN_LOCK                              xmitBufLock;\r
+       KSPIN_LOCK                              recvListLock;\r
+       NDIS_SPIN_LOCK                  recvIosLock;\r
+       NDIS_SPIN_LOCK                  xmitBufLock;\r
        volatile LONG                   kickTimerOn;\r
        BOOLEAN                                 connected;\r
        cl_timer_t                              kickTimer;\r
@@ -149,7 +151,7 @@ ib_api_status_t
 data_connect(\r
                        Data_t          *pData );\r
 \r
-void\r
+ib_api_status_t\r
 data_connected(\r
                        Data_t          *pData );\r
 \r
@@ -201,4 +203,4 @@ data_cleanup(
 #define VNIC_PACKET_FROM_LIST_ITEM( I ) \\r
                (PARENT_STRUCT( I, NDIS_PACKET, MiniportReservedEx ))\r
 \r
-#endif /* _VNIC_DATA_H_ */
\ No newline at end of file
+#endif /* _VNIC_DATA_H_ */\r
index 9a69dd4..a5df64f 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
- * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.\r
+ * Copyright (c) 2007 QLogic Corporation.  All rights reserved.\r
  *\r
  * This software is available to you under the OpenIB.org BSD license\r
  * below:\r
@@ -66,7 +66,7 @@ extern uint32_t               g_vnic_dbg_lvl;
 #define VNIC_DBG_ERROR         CL_DBG_ERROR\r
 #define VNIC_DBG_ALL           CL_DBG_ALL\r
 \r
-#define VNIC_DEBUG_FLAGS ( VNIC_DBG_ERROR | VNIC_DBG_WARN |    VNIC_DBG_INFO | VNIC_DBG_PNP | VNIC_DBG_INIT )\r
+#define VNIC_DEBUG_FLAGS ( VNIC_DBG_ERROR | VNIC_DBG_WARN |    VNIC_DBG_INFO )\r
 /* Enter and exit macros automatically add VNIC_DBG_FUNC bit */\r
 #define VNIC_ENTER( lvl )      \\r
        CL_ENTER( (lvl | VNIC_DBG_FUNC), g_vnic_dbg_lvl )\r
@@ -74,12 +74,39 @@ extern uint32_t             g_vnic_dbg_lvl;
 #define VNIC_EXIT( lvl )       \\r
        CL_EXIT( (lvl | VNIC_DBG_FUNC), g_vnic_dbg_lvl )\r
 \r
+#if defined FREE_BUILD_DBG\r
+#define VNIC_TRACE( lvl, msg )                                                 \\r
+       {                                                                                                       \\r
+               switch( (lvl) & VNIC_DBG_ERROR )                                \\r
+               {                                                                                               \\r
+               case VNIC_DBG_ERROR:                                                    \\r
+                       cl_msg_out msg;                                                         \\r
+               default:                                                                                \\r
+                       CL_TRACE( (lvl), g_vnic_dbg_lvl, msg );         \\r
+               }                                                                                               \\r
+       }\r
+\r
+#define VNIC_TRACE_EXIT( lvl, msg )                                             \\r
+       {                                                                                                        \\r
+               switch( (lvl) & VNIC_DBG_ERROR )                                 \\r
+               {                                                                                                \\r
+               case VNIC_DBG_ERROR:                                                     \\r
+                       cl_msg_out msg;                                                          \\r
+               default:                                                                                 \\r
+                       CL_TRACE_EXIT( (lvl), g_vnic_dbg_lvl, msg ); \\r
+               }                                                                                                \\r
+       }\r
+\r
+#else // ! FREE_BUILD_DBG\r
+\r
 #define VNIC_TRACE( lvl, msg ) \\r
        CL_TRACE( (lvl), g_vnic_dbg_lvl, msg )\r
 \r
 #define VNIC_TRACE_EXIT( lvl, msg )    \\r
        CL_TRACE_EXIT( (lvl), g_vnic_dbg_lvl, msg )\r
 \r
+#endif // FREE_BUILD_DBG\r
+\r
 #define VNIC_PRINT( lvl, msg ) \\r
        CL_PRINT ( (lvl), g_vnic_dbg_lvl, msg )\r
 \r
index cba109e..e5ede83 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
- * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.\r
+ * Copyright (c) 2007 QLogic Corporation.  All rights reserved.\r
  *\r
  * This software is available to you under the OpenIB.org BSD license\r
  * below:\r
 \r
 vnic_globals_t g_vnic;\r
 \r
+g_registry_params_t    reg_array[VNIC_REGISTRY_TBL_SIZE] = {\r
+       {L"", 0},\r
+       {L"MinHostPoolSz",                      ENTRY_INIT_VALUE},\r
+       {L"HostRecvPoolEntries",        ENTRY_INIT_VALUE},\r
+       {L"MinEiocPoolSz",                      ENTRY_INIT_VALUE},\r
+       {L"MaxEiocPoolSz",                      ENTRY_INIT_VALUE},\r
+       {L"MinHostKickTimeout",         ENTRY_INIT_VALUE},\r
+       {L"MaxHostKickTimeout",         ENTRY_INIT_VALUE},\r
+       {L"MinHostKickEntries",         ENTRY_INIT_VALUE},\r
+       {L"MaxHostKickEntries",         ENTRY_INIT_VALUE},\r
+       {L"MinHostKickBytes",           ENTRY_INIT_VALUE},\r
+       {L"MaxHostKickBytes",           ENTRY_INIT_VALUE},\r
+       {L"MinHostUpdateSz",            ENTRY_INIT_VALUE},\r
+       {L"MaxHostUpdateSz",            ENTRY_INIT_VALUE},\r
+       {L"MinEiocUpdateSz",            ENTRY_INIT_VALUE},\r
+       {L"MaxEiocUpdateSz",            ENTRY_INIT_VALUE},\r
+       {L"HeartbeatTimeout",           ENTRY_INIT_VALUE},\r
+};\r
+\r
 #define DEFAULT_HOST_NAME "VNIC Host"\r
 \r
 uint32_t g_vnic_dbg_lvl = VNIC_DEBUG_FLAGS;\r
@@ -68,6 +87,10 @@ _vnic_process_packet_filter(
 static void\r
 __vnic_read_machine_name( void );\r
 \r
+static NTSTATUS\r
+__vnic_read_service_registry(\r
+               IN              UNICODE_STRING* const   p_registry_path );\r
+\r
 static NDIS_STATUS\r
 __vnic_set_machine_name(\r
                IN              VOID    *p_uni_array,\r
@@ -96,7 +119,7 @@ DriverEntry(
 #ifdef _DEBUG_\r
        PAGED_CODE();\r
 #endif\r
-\r
+/*\r
        status = CL_INIT;\r
 \r
        if( !NT_SUCCESS( status ) )\r
@@ -105,14 +128,12 @@ DriverEntry(
                        ("cl_init failed.\n") );\r
                return status;\r
        }\r
-\r
+*/\r
        status          = NDIS_STATUS_SUCCESS;\r
 \r
-       KeInitializeSpinLock( &g_vnic.lock );\r
-       InitializeListHead( &g_vnic.adapter_list );\r
-\r
-       g_vnic.adapters = 0;\r
        g_vnic.ndis_handle = NULL;\r
+       g_vnic.shutdown = 0;\r
+       g_vnic.p_params = NULL;\r
 \r
        NdisMInitializeWrapper( &g_vnic.ndis_handle, p_drv_obj, p_registry_path, NULL );\r
 \r
@@ -128,7 +149,7 @@ DriverEntry(
 \r
        characteristics.MajorNdisVersion                = MAJOR_NDIS_VERSION;\r
        characteristics.MinorNdisVersion                = MINOR_NDIS_VERSION;\r
-       //characteristics.CheckForHangHandler           = vnic_check_for_hang;\r
+       characteristics.CheckForHangHandler             = vnic_check_for_hang;\r
        characteristics.HaltHandler                             = vnic_halt;\r
        characteristics.InitializeHandler               = vnic_initialize;\r
        characteristics.QueryInformationHandler = vnic_oid_query_info;\r
@@ -138,6 +159,7 @@ DriverEntry(
        characteristics.SendPacketsHandler              = vnic_send_packets;\r
 \r
 #ifdef NDIS51_MINIPORT\r
+       characteristics.CancelSendPacketsHandler = vnic_cancel_xmit;\r
        characteristics.PnPEventNotifyHandler   = vnic_pnp_notify;\r
        characteristics.AdapterShutdownHandler  = vnic_shutdown;\r
 #endif\r
@@ -157,6 +179,12 @@ DriverEntry(
                NdisMRegisterUnloadHandler( g_vnic.ndis_handle, vnic_unload );\r
        \r
                __vnic_read_machine_name();\r
+               __vnic_read_service_registry( p_registry_path );\r
+\r
+#if defined (LBFO_ENABLED)\r
+               cl_qlist_init( &g_vnic.primary_list );\r
+               cl_qlist_init( &g_vnic.secondary_list );\r
+#endif\r
        }\r
 \r
        VNIC_EXIT( VNIC_DBG_INIT );\r
@@ -171,9 +199,10 @@ vnic_unload(
        VNIC_ENTER( VNIC_DBG_INIT );\r
 \r
        UNREFERENCED_PARAMETER( p_drv_obj );\r
-       CL_DEINIT;\r
 \r
-       VNIC_EXIT( VNIC_DBG_INIT );\r
+       VNIC_TRACE_EXIT( VNIC_DBG_INFO,\r
+               (" Driver Unloaded....\n"));\r
+       //CL_DEINIT;\r
 }\r
 \r
 \r
@@ -207,7 +236,6 @@ vnic_initialize(
        ib_pnp_req_t            pnp_req;\r
        UINT                            medium_index;\r
        vnic_adapter_t          *p_adapter;\r
-       ULONG                           buffer_size;\r
 \r
        VNIC_ENTER( VNIC_DBG_INIT );\r
 \r
@@ -245,23 +273,13 @@ vnic_initialize(
        /* set NDIS features we support */\r
        NdisMSetAttributesEx( h_handle,\r
                                                (NDIS_HANDLE)p_adapter,\r
-                                               2,                                              /*check for hung t-out */\r
+                                               0,                                              /*check for hung timeout, 2 sec */\r
                                                NDIS_ATTRIBUTE_BUS_MASTER |\r
                                                NDIS_ATTRIBUTE_DESERIALIZE |\r
                                                NDIS_ATTRIBUTE_SURPRISE_REMOVE_OK |\r
                                                NDIS_ATTRIBUTE_USES_SAFE_BUFFER_APIS,\r
                                                NdisInterfacePNPBus );\r
 \r
-       buffer_size = ROUNDUPP2(p_adapter->params.MinMtu + sizeof(eth_hdr_t), 8 );\r
-\r
-       status = NdisMInitializeScatterGatherDma( h_handle, TRUE, buffer_size );\r
-       if ( status != NDIS_STATUS_SUCCESS )\r
-       {\r
-               VNIC_TRACE( VNIC_DBG_ERROR,\r
-                       ("Init ScatterGatherDma failed status %#x\n", status ) );\r
-               goto failure;\r
-       }\r
-\r
        /* Register for IOC events */\r
        pnp_req.pfn_pnp_cb = __vnic_pnp_cb;\r
        pnp_req.pnp_class = IB_PNP_IOC | IB_PNP_FLAG_REG_SYNC;\r
@@ -277,7 +295,7 @@ vnic_initialize(
                goto failure;\r
        }\r
 \r
-       if( p_adapter->state == INIC_UNINITIALIZED )\r
+       if( p_adapter->state != INIC_REGISTERED )\r
        {\r
                status = NDIS_STATUS_FAILURE;\r
 failure:\r
@@ -300,14 +318,10 @@ void
 vnic_halt(\r
        IN                      NDIS_HANDLE                     adapter_context )\r
 {\r
-       vnic_adapter_t  *p_adapter;\r
-\r
        VNIC_ENTER( VNIC_DBG_INIT );\r
        CL_ASSERT( adapter_context );\r
 \r
-       p_adapter = (vnic_adapter_t*)adapter_context;\r
-\r
-       vnic_destroy_adapter( p_adapter );\r
+       vnic_destroy_adapter( (vnic_adapter_t*)adapter_context );\r
 \r
        VNIC_EXIT( VNIC_DBG_INIT );\r
 }\r
@@ -319,7 +333,7 @@ vnic_halt(
 @param adapter_context The adapter context allocated at start\r
 @return TRUE if the driver determines that its NIC is not operating\r
 */\r
-#define VNIC_MAX_HUNG_CHK      3\r
+\r
 BOOLEAN\r
 vnic_check_for_hang(\r
        IN                              NDIS_HANDLE                                     adapter_context )\r
@@ -329,17 +343,20 @@ vnic_check_for_hang(
        CL_ASSERT( adapter_context );\r
        p_adapter = (vnic_adapter_t*)adapter_context;\r
 \r
-       if( p_adapter->p_viport )\r
+       /* current path is Ok */\r
+       if( netpath_is_connected( p_adapter->p_currentPath ) )\r
        {\r
-               if( p_adapter->p_viport->errored != 0 )\r
-                       p_adapter->hung++;\r
+               return FALSE;\r
        }\r
-       if( p_adapter->hung > VNIC_MAX_HUNG_CHK )\r
+\r
+       if( p_adapter->hung != 0 && \r
+               p_adapter->hung >= p_adapter->num_paths )\r
        {\r
-               VNIC_TRACE( VNIC_DBG_WARN, ("Adapter Hung\n"));\r
-               p_adapter->hung = 0;\r
-               return TRUE;\r
+                       VNIC_TRACE( VNIC_DBG_WARN, \r
+                               ("IOC[%d] Adapter Hung\n", p_adapter->ioc_num ));\r
+                       return TRUE;\r
        }\r
+\r
        return FALSE;\r
 }\r
 \r
@@ -367,10 +384,12 @@ vnic_oid_query_info(
                OUT                     PULONG                                          p_bytes_needed )\r
 {\r
        vnic_adapter_t          *p_adapter;\r
+       Netpath_t                       *p_netpath;\r
+\r
        NDIS_STATUS                     status;\r
        USHORT                          version;\r
-       uint32_t                        info32;\r
-       uint64_t                        info64;\r
+       uint32_t                        info32 = 0;\r
+       uint64_t                        info64 = 0;\r
        PVOID                           src_buf;\r
        ULONG                           buf_len;\r
        pending_oid_t           oid_info;\r
@@ -393,8 +412,14 @@ vnic_oid_query_info(
        src_buf = &info32;\r
        buf_len = sizeof(info32);\r
 \r
-       if( !p_adapter->p_viport ||\r
-               !p_adapter->p_currentPath->carrier )\r
+       if( g_vnic.shutdown != 0 )\r
+       {\r
+               *p_bytes_written = 0;\r
+               return NDIS_STATUS_NOT_ACCEPTED;\r
+       }\r
+\r
+       p_netpath = p_adapter->p_currentPath;\r
+       if( !p_netpath || !p_netpath->carrier )\r
        {\r
                status = NDIS_STATUS_NOT_ACCEPTED;\r
                goto complete;\r
@@ -414,7 +439,7 @@ vnic_oid_query_info(
                VNIC_TRACE( VNIC_DBG_OID,\r
                        ("received query for OID_GEN_HARDWARE_STATUS\n") );\r
 \r
-               if( p_adapter->p_currentPath->carrier )\r
+               if( p_netpath->carrier )\r
                {\r
                        VNIC_TRACE( VNIC_DBG_OID,\r
                                ("returning NdisHardwareStatusReady\n") );\r
@@ -435,18 +460,19 @@ vnic_oid_query_info(
                        "or OID_GEN_MEDIA_IN_USE\n") );\r
                info32 = NdisMedium802_3;\r
                break;\r
-\r
-       case OID_GEN_MAXIMUM_FRAME_SIZE:\r
+                       \r
+       case OID_GEN_MAXIMUM_TOTAL_SIZE:        /* frame size inlcuding header */\r
+                       info32  = sizeof( eth_hdr_t );\r
+       case OID_GEN_MAXIMUM_FRAME_SIZE:        /* wihout header */\r
                VNIC_TRACE( VNIC_DBG_OID,\r
                        ("received query for OID_GEN_MAXIMUM_FRAME_SIZE\n") );\r
-               if( !p_adapter->p_currentPath->carrier )\r
+               if( !p_netpath->carrier )\r
                {\r
-                       info32 = p_adapter->params.MinMtu;\r
+                       info32 += MIN_MTU;\r
                }\r
                else\r
                {\r
-                       info32 = p_adapter->p_currentPath->pViport->mtu;\r
-                       /*TODO: add VLAN tag size if support request */\r
+                       info32 += p_adapter->p_currentPath->pViport->mtu;\r
                }\r
                break;\r
 \r
@@ -454,7 +480,7 @@ vnic_oid_query_info(
                VNIC_TRACE( VNIC_DBG_OID,\r
                                ("received query for OID_GEN_LINK_SPEED\n") );\r
 \r
-               if( p_adapter->p_currentPath->carrier )\r
+               if( p_netpath->carrier )\r
                {\r
                        /* if we get link speed value - it is in Mbps units - have to convert to 100bps*/\r
                        info32 = ( p_adapter->link_speed )?     \r
@@ -470,14 +496,14 @@ vnic_oid_query_info(
        case OID_GEN_TRANSMIT_BUFFER_SPACE:\r
                VNIC_TRACE( VNIC_DBG_OID,\r
                        ("received query for OID_GEN_TRANSMIT_BUFFER_SPACE\n") );\r
-               if ( !p_adapter->p_currentPath->carrier )\r
+               if ( !p_netpath->carrier )\r
                {\r
                        status= NDIS_STATUS_NOT_ACCEPTED;\r
                }\r
                else\r
                {\r
-                       info32 = p_adapter->p_viport->data.xmitPool.bufferSz *\r
-                               p_adapter->p_viport->data.xmitPool.poolSz;\r
+                       info32 = p_netpath->pViport->data.xmitPool.bufferSz *\r
+                               p_netpath->pViport->data.xmitPool.poolSz;\r
                }\r
                break;\r
 \r
@@ -485,30 +511,28 @@ vnic_oid_query_info(
                VNIC_TRACE( VNIC_DBG_OID,\r
                        ("received query for OID_GEN_RECEIVE_BUFFER_SPACE "\r
                        "or OID_GEN_RECEIVE_BUFFER_SPACE\n") );\r
-               if ( !p_adapter->p_currentPath->carrier )\r
+               if ( !p_netpath->carrier )\r
                {\r
                        status = NDIS_STATUS_NOT_ACCEPTED;\r
                }\r
                else\r
                {\r
-                       info32 = p_adapter->p_viport->data.recvPool.bufferSz *\r
-                               p_adapter->p_viport->data.recvPool.poolSz;\r
+                       info32 = p_netpath->pViport->data.recvPool.bufferSz *\r
+                               p_netpath->pViport->data.recvPool.poolSz;\r
                }\r
                break;\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
                VNIC_TRACE( VNIC_DBG_OID,\r
                        ("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") );\r
-               if( !p_adapter->p_currentPath->carrier )\r
+                       "OID_GEN_RECEIVE_BLOCK_SIZE\n") );\r
+               if( !p_netpath->carrier )\r
                {\r
-                       info32 = p_adapter->params.MinMtu;\r
+                       info32 = MIN_MTU;\r
                }\r
                else\r
                {\r
@@ -568,12 +592,10 @@ vnic_oid_query_info(
                info32 = 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
+                               NDIS_MAC_OPTION_FULL_DUPLEX |\r
+                               NDIS_MAC_OPTION_8021P_PRIORITY |\r
+                               NDIS_MAC_OPTION_8021Q_VLAN;\r
+\r
                break;\r
 \r
        case OID_GEN_MEDIA_CONNECT_STATUS:\r
@@ -595,13 +617,13 @@ vnic_oid_query_info(
        case OID_GEN_XMIT_OK:\r
                VNIC_TRACE( VNIC_DBG_OID,\r
                        ("  received query for OID_GEN_XMIT_OK\n" ) );\r
-               if ( !p_adapter->p_currentPath->carrier )\r
+               if ( !p_netpath->carrier )\r
                {\r
                        info32 = 0;\r
                }\r
                else\r
                {\r
-                       info64  = p_adapter->p_viport->stats.ifOutOk;\r
+                       info64  = p_netpath->pViport->stats.ifOutOk;\r
                        src_buf = &info64;\r
                        buf_len = sizeof(info64);\r
                }\r
@@ -610,18 +632,18 @@ vnic_oid_query_info(
        case OID_GEN_RCV_OK:\r
                VNIC_TRACE( VNIC_DBG_OID,\r
                        ("  received query for OID_GEN_RCV_OK\n" ) );\r
-               if ( !p_adapter->p_currentPath->carrier)\r
+               if ( !p_netpath->carrier)\r
                {\r
                        info32 = 0;\r
                        break;\r
                }\r
                if ( info_buf_len == sizeof(info32) )\r
                {\r
-                       info32 = (uint32_t)p_adapter->p_viport->stats.ifInOk;\r
+                       info32 = (uint32_t)p_netpath->pViport->stats.ifInOk;\r
                }\r
                else\r
                {\r
-                       info64  = p_adapter->p_viport->stats.ifInOk;\r
+                       info64  = p_netpath->pViport->stats.ifInOk;\r
                        src_buf = &info64;\r
                        buf_len = sizeof(info64);\r
                }\r
@@ -630,13 +652,13 @@ vnic_oid_query_info(
        case OID_GEN_XMIT_ERROR:\r
                VNIC_TRACE( VNIC_DBG_OID,\r
                        ("  received query for OID_GEN_XMIT_ERROR\n" ) );\r
-               if ( !p_adapter->p_currentPath->carrier )\r
+               if ( !p_netpath->carrier )\r
                {\r
                        info32 = 0;\r
                }\r
                else\r
                {\r
-               info64  = p_adapter->p_viport->stats.ifOutErrors;\r
+               info64  = p_netpath->pViport->stats.ifOutErrors;\r
                src_buf = &info64;\r
                buf_len = sizeof(info64);\r
                }\r
@@ -645,13 +667,13 @@ vnic_oid_query_info(
        case OID_GEN_RCV_ERROR:\r
                VNIC_TRACE( VNIC_DBG_OID,\r
                        ("  received query for OID_GEN_RCV_ERROR\n" ) );\r
-               if ( !p_adapter->p_currentPath->carrier )\r
+               if ( !p_netpath->carrier )\r
                {\r
                        info32 = 0;\r
                }\r
                else\r
                {\r
-               info64 = p_adapter->p_viport->stats.ifInErrors;\r
+               info64 = p_netpath->pViport->stats.ifInErrors;\r
                src_buf = &info64;\r
                buf_len = sizeof(info64);\r
                }\r
@@ -666,13 +688,13 @@ vnic_oid_query_info(
        case OID_GEN_DIRECTED_BYTES_XMIT:\r
                VNIC_TRACE( VNIC_DBG_OID,\r
                        ("  received query for OID_GEN_DIRECTED_BYTES_XMIT\n" ) );\r
-               if ( !p_adapter->p_currentPath->carrier )\r
+               if ( !p_netpath->carrier )\r
                {\r
                        info32 = 0;\r
                }\r
                else\r
                {\r
-               info64 = p_adapter->p_viport->stats.ifOutUcastBytes;\r
+               info64 = p_netpath->pViport->stats.ifOutUcastBytes;\r
                src_buf = &info64;\r
                buf_len = sizeof(info64);\r
                }\r
@@ -681,13 +703,13 @@ vnic_oid_query_info(
        case OID_GEN_DIRECTED_FRAMES_XMIT:\r
                VNIC_TRACE( VNIC_DBG_OID,\r
                        ("  received query for OID_GEN_DIRECTED_FRAMES_XMIT\n" ) );\r
-               if ( !p_adapter->p_currentPath->carrier )\r
+               if ( !p_netpath->carrier )\r
                {\r
                        info32 = 0;\r
                }\r
                else\r
                {\r
-               info64 = p_adapter->p_viport->stats.ifOutNUcastPkts;\r
+               info64 = p_netpath->pViport->stats.ifOutNUcastPkts;\r
                src_buf = &info64;\r
                buf_len = sizeof(info64);\r
                }\r
@@ -696,13 +718,13 @@ vnic_oid_query_info(
        case OID_GEN_MULTICAST_BYTES_XMIT:\r
                VNIC_TRACE( VNIC_DBG_OID,\r
                        ("  received query for OID_GEN_MULTICAST_BYTES_XMIT\n" ) );\r
-               if ( !p_adapter->p_currentPath->carrier )\r
+               if ( !p_netpath->carrier )\r
                {\r
                        info32 = 0;\r
                }\r
                else\r
                {\r
-               info64 = p_adapter->p_viport->stats.ifOutMulticastBytes;\r
+               info64 = p_netpath->pViport->stats.ifOutMulticastBytes;\r
                src_buf = &info64;\r
                buf_len = sizeof(info64);\r
                }\r
@@ -711,13 +733,13 @@ vnic_oid_query_info(
        case OID_GEN_MULTICAST_FRAMES_XMIT:\r
                VNIC_TRACE( VNIC_DBG_OID,\r
                        ("  received query for OID_GEN_MULTICAST_FRAMES_XMIT\n" ) );\r
-               if ( !p_adapter->p_currentPath->carrier )\r
+               if ( !p_netpath->carrier )\r
                {\r
                        info32 = 0;\r
                }\r
                else\r
                {\r
-               info64 = p_adapter->p_viport->stats.ifOutMulticastPkts;\r
+               info64 = p_netpath->pViport->stats.ifOutMulticastPkts;\r
                src_buf = &info64;\r
                buf_len = sizeof(info64);\r
                }\r
@@ -726,13 +748,13 @@ vnic_oid_query_info(
        case OID_GEN_BROADCAST_BYTES_XMIT:\r
                VNIC_TRACE( VNIC_DBG_OID,\r
                        ("  received query for OID_GEN_BROADCAST_BYTES_XMIT\n" ) );\r
-               if ( !p_adapter->p_currentPath->carrier )\r
+               if ( !p_netpath->carrier )\r
                {\r
                        info32 = 0;\r
                }\r
                else\r
                {\r
-                       info64 = p_adapter->p_viport->stats.ifOutBroadcastBytes;\r
+                       info64 = p_netpath->pViport->stats.ifOutBroadcastBytes;\r
                        src_buf = &info64;\r
                        buf_len = sizeof(info64);\r
                }\r
@@ -741,13 +763,13 @@ vnic_oid_query_info(
        case OID_GEN_BROADCAST_FRAMES_XMIT:\r
                VNIC_TRACE( VNIC_DBG_OID,\r
                        ("  received query for OID_GEN_BROADCAST_FRAMES_XMIT\n" ) );\r
-               if ( !p_adapter->p_currentPath->carrier )\r
+               if ( !p_netpath->carrier )\r
                {\r
                        info32 = 0;\r
                }\r
                else\r
                {\r
-               info64 = p_adapter->p_viport->stats.ifOutBroadcastPkts;\r
+               info64 = p_netpath->pViport->stats.ifOutBroadcastPkts;\r
                src_buf = &info64;\r
                buf_len = sizeof(info64);\r
                }\r
@@ -755,13 +777,13 @@ vnic_oid_query_info(
        case OID_GEN_DIRECTED_BYTES_RCV:\r
                VNIC_TRACE( VNIC_DBG_OID,\r
                        ("  received query for OID_GEN_DIRECTED_BYTES_RCV\n" ) );\r
-               if ( !p_adapter->p_currentPath->carrier )\r
+               if ( !p_netpath->carrier )\r
                {\r
                        info32 = 0;\r
                }\r
                else\r
                {\r
-               info64 = p_adapter->p_viport->stats.ifInUcastBytes;\r
+               info64 = p_netpath->pViport->stats.ifInUcastBytes;\r
                src_buf = &info64;\r
                buf_len = sizeof(info64);\r
                }\r
@@ -770,13 +792,13 @@ vnic_oid_query_info(
        case OID_GEN_DIRECTED_FRAMES_RCV:\r
                VNIC_TRACE( VNIC_DBG_OID,\r
                        ("  received query for OID_GEN_DIRECTED_FRAMES_RCV\n" ) );\r
-               if ( !p_adapter->p_currentPath->carrier )\r
+               if ( !p_netpath->carrier )\r
                {\r
                        info32 = 0;\r
                }\r
                else\r
                {\r
-               info64 = p_adapter->p_viport->stats.ifInNUcastPkts;\r
+               info64 = p_netpath->pViport->stats.ifInNUcastPkts;\r
                src_buf = &info64;\r
                buf_len = sizeof(info64);\r
                }\r
@@ -785,13 +807,13 @@ vnic_oid_query_info(
        case OID_GEN_MULTICAST_BYTES_RCV:\r
                VNIC_TRACE( VNIC_DBG_OID,\r
                        ("  received query for OID_GEN_MULTICAST_BYTES_RCV\n" ) );\r
-               if ( !p_adapter->p_currentPath->carrier )\r
+               if ( !p_netpath->carrier )\r
                {\r
                        info32 = 0;\r
                }\r
                else\r
                {\r
-               info64 = p_adapter->p_viport->stats.ifInMulticastBytes;\r
+               info64 = p_netpath->pViport->stats.ifInMulticastBytes;\r
                src_buf = &info64;\r
                buf_len = sizeof(info64);\r
                }\r
@@ -800,13 +822,13 @@ vnic_oid_query_info(
        case OID_GEN_MULTICAST_FRAMES_RCV:\r
                VNIC_TRACE( VNIC_DBG_OID,\r
                        ("  received query for OID_GEN_MULTICAST_FRAMES_RCV\n" ) );\r
-               if ( !p_adapter->p_currentPath->carrier )\r
+               if ( !p_netpath->carrier )\r
                {\r
                        info32 = 0;\r
                }\r
                else\r
                {\r
-               info64 = p_adapter->p_viport->stats.ifInMulticastPkts;\r
+               info64 = p_netpath->pViport->stats.ifInMulticastPkts;\r
                src_buf = &info64;\r
                buf_len = sizeof(info64);\r
                }\r
@@ -815,13 +837,13 @@ vnic_oid_query_info(
        case OID_GEN_BROADCAST_BYTES_RCV:\r
                VNIC_TRACE( VNIC_DBG_OID,\r
                        ("  received query for OID_GEN_BROADCAST_BYTES_RCV\n" ) );\r
-               if ( !p_adapter->p_currentPath->carrier )\r
+               if ( !p_netpath->carrier )\r
                {\r
                        info32 = 0;\r
                }\r
                else\r
                {\r
-               info64 = p_adapter->p_viport->stats.ifInBroadcastBytes;\r
+               info64 = p_netpath->pViport->stats.ifInBroadcastBytes;\r
                src_buf = &info64;\r
                buf_len = sizeof(info64);\r
                }\r
@@ -830,13 +852,13 @@ vnic_oid_query_info(
        case OID_GEN_BROADCAST_FRAMES_RCV:\r
                VNIC_TRACE( VNIC_DBG_OID,\r
                        ("  received query for OID_GEN_BROADCAST_FRAMES_RCV\n" ) );\r
-               if ( !p_adapter->p_currentPath->carrier )\r
+               if ( !p_netpath->carrier )\r
                {\r
                        info32 = 0;\r
                }\r
                else\r
                {\r
-               info64 = p_adapter->p_viport->stats.ifInBroadcastPkts;\r
+               info64 = p_netpath->pViport->stats.ifInBroadcastPkts;\r
                src_buf = &info64;\r
                buf_len = sizeof(info64);\r
                }\r
@@ -857,9 +879,9 @@ vnic_oid_query_info(
                                ("  received query for OID_802_3_CURRENT_ADDRESS\n" ) );\r
                }\r
 #endif /* defined( _DEBUG_ )*/\r
-               if( !p_adapter->p_viport ||\r
-                       p_adapter->p_viport->errored ||\r
-                       p_adapter->p_viport->disconnect )\r
+               if( !p_netpath->pViport ||\r
+                       p_netpath->pViport->errored ||\r
+                       p_netpath->pViport->disconnect )\r
                {\r
                        status = NDIS_STATUS_NOT_ACCEPTED;\r
                        break;\r
@@ -875,7 +897,7 @@ vnic_oid_query_info(
                }\r
                else\r
                {\r
-                       src_buf = &p_adapter->p_viport->hwMacAddress;\r
+                       src_buf = &p_netpath->pViport->hwMacAddress;\r
                        buf_len = HW_ADDR_LEN;\r
                }\r
                break;\r
@@ -884,17 +906,20 @@ vnic_oid_query_info(
                VNIC_TRACE( VNIC_DBG_OID,\r
                        ("  received query for OID_802_3_MULTICAST_LIST\n" ) );\r
        \r
-               if (!p_adapter->p_currentPath->carrier ||\r
-                       !(p_adapter->p_viport->flags & INIC_FLAG_ENABLE_NIC) )\r
+               if( !p_netpath->carrier ||\r
+                       !(p_netpath->pViport->flags & INIC_FLAG_ENABLE_NIC) )\r
                {\r
-                       p_adapter->pending_query = TRUE;\r
+/*                     p_adapter->pending_query = TRUE;\r
                        p_adapter->query_oid = oid_info;\r
 \r
                        VNIC_TRACE( VNIC_DBG_OID,\r
                                ("returning NDIS_STATUS_PENDING\n") );\r
-                       status = NDIS_STATUS_PENDING;\r
+                       status = NDIS_STATUS_PENDING; \r
+*/\r
+                       status = NDIS_STATUS_NOT_ACCEPTED;\r
+                       break;\r
                }\r
-               else if ( p_adapter->mc_count > 0 )\r
+               if( p_adapter->mc_count > 0 )\r
                {\r
                        buf_len = p_adapter->mc_count * sizeof( mac_addr_t );\r
                        src_buf = &p_adapter->mcast_array;\r
@@ -914,7 +939,7 @@ vnic_oid_query_info(
                }\r
                else\r
                {\r
-                       info32 = p_adapter->p_viport->numMacAddresses - MCAST_ADDR_START;\r
+                       info32 = p_netpath->pViport->numMacAddresses - MCAST_ADDR_START;\r
                }\r
                break;\r
        case OID_802_3_MAC_OPTIONS:\r
@@ -942,12 +967,12 @@ vnic_oid_query_info(
                status = __vnic_get_tcp_task_offload( p_adapter, &oid_info );\r
                break;\r
 \r
+       case OID_GEN_VLAN_ID:\r
+               /* return current vlan info */\r
+               info32 =( p_adapter->vlan_info & 0x00000fff );\r
+               break;\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
@@ -1059,8 +1084,11 @@ __vnic_get_tcp_task_offload(
        NDIS_TASK_OFFLOAD_HEADER        *p_offload_hdr;\r
        NDIS_TASK_OFFLOAD                       *p_offload_task;\r
        NDIS_TASK_TCP_IP_CHECKSUM       *p_offload_chksum;\r
-       //uint8_t                                               port_num;\r
+\r
        ULONG                                           buf_len;\r
+       uint32_t                                        enabled_TxCsum;\r
+       uint32_t                                        enabled_RxCsum;\r
+       viport_t                                        *p_viport;\r
 \r
        buf_len = sizeof(NDIS_TASK_OFFLOAD_HEADER) +\r
                sizeof(NDIS_TASK_OFFLOAD) +\r
@@ -1080,6 +1108,20 @@ __vnic_get_tcp_task_offload(
        {\r
                return NDIS_STATUS_INVALID_DATA;\r
        }\r
+       p_viport = p_adapter->p_currentPath->pViport;\r
+\r
+       /* too early, we didn't get response on CMD_INIT_INIC yet */\r
+       if( !p_viport || !viport_features( p_viport ) )\r
+       {\r
+               return NDIS_STATUS_NOT_ACCEPTED;\r
+       }\r
+\r
+       enabled_RxCsum = \r
+               (uint32_t)( p_adapter->params.UseRxCsum && \r
+                                       viport_canRxCsum( p_adapter->p_currentPath->pViport ) );\r
+       enabled_TxCsum = \r
+               (uint32_t)( p_adapter->params.UseTxCsum && \r
+                                       viport_canTxCsum( p_adapter->p_currentPath->pViport ) );\r
 \r
        p_offload_hdr->OffsetFirstTask = sizeof(NDIS_TASK_OFFLOAD_HEADER);\r
        p_offload_task = (NDIS_TASK_OFFLOAD*)(p_offload_hdr + 1);\r
@@ -1091,25 +1133,17 @@ __vnic_get_tcp_task_offload(
        p_offload_chksum =\r
                (NDIS_TASK_TCP_IP_CHECKSUM*)p_offload_task->TaskBuffer;\r
 \r
-       p_offload_chksum->V4Transmit.IpOptionsSupported =\r
-                                                               p_adapter->params.UseTxCsum;\r
-       p_offload_chksum->V4Transmit.TcpOptionsSupported =\r
-                                                               p_adapter->params.UseTxCsum;\r
-       p_offload_chksum->V4Transmit.TcpChecksum =\r
-                                                               p_adapter->params.UseTxCsum;\r
-       p_offload_chksum->V4Transmit.UdpChecksum =\r
-                                                               p_adapter->params.UseTxCsum;\r
-       p_offload_chksum->V4Transmit.IpChecksum =\r
-                                                               p_adapter->params.UseTxCsum;\r
-\r
-       p_offload_chksum->V4Receive.IpOptionsSupported = TRUE;\r
-       p_offload_chksum->V4Receive.TcpOptionsSupported = TRUE;\r
-       p_offload_chksum->V4Receive.TcpChecksum =\r
-                                                               p_adapter->params.UseRxCsum;\r
-       p_offload_chksum->V4Receive.UdpChecksum =\r
-                                                               p_adapter->params.UseRxCsum;\r
-       p_offload_chksum->V4Receive.IpChecksum =\r
-                                                               p_adapter->params.UseRxCsum;\r
+       p_offload_chksum->V4Transmit.IpOptionsSupported = enabled_TxCsum;\r
+       p_offload_chksum->V4Transmit.TcpOptionsSupported = enabled_TxCsum;\r
+       p_offload_chksum->V4Transmit.TcpChecksum = enabled_TxCsum;\r
+       p_offload_chksum->V4Transmit.UdpChecksum = enabled_TxCsum;\r
+       p_offload_chksum->V4Transmit.IpChecksum = enabled_TxCsum;\r
+\r
+       p_offload_chksum->V4Receive.IpOptionsSupported = enabled_RxCsum;\r
+       p_offload_chksum->V4Receive.TcpOptionsSupported = enabled_RxCsum;\r
+       p_offload_chksum->V4Receive.TcpChecksum = enabled_RxCsum;\r
+       p_offload_chksum->V4Receive.UdpChecksum = enabled_RxCsum;\r
+       p_offload_chksum->V4Receive.IpChecksum = enabled_RxCsum;\r
 \r
        p_offload_chksum->V6Transmit.IpOptionsSupported = FALSE;\r
        p_offload_chksum->V6Transmit.TcpOptionsSupported = FALSE;\r
@@ -1136,6 +1170,9 @@ __vnic_set_tcp_task_offload(
        NDIS_TASK_OFFLOAD                       *p_offload_task;\r
        NDIS_TASK_TCP_IP_CHECKSUM       *p_offload_chksum;\r
 \r
+       ULONG                                           enabled_TxCsum;\r
+       ULONG                                           enabled_RxCsum;\r
+\r
        VNIC_ENTER( VNIC_DBG_OID );\r
 \r
        p_offload_hdr = (NDIS_TASK_OFFLOAD_HEADER*)p_info_buf;\r
@@ -1173,7 +1210,12 @@ __vnic_set_tcp_task_offload(
        p_offload_chksum =\r
                (NDIS_TASK_TCP_IP_CHECKSUM*)p_offload_task->TaskBuffer;\r
 \r
-       if( !p_adapter->params.UseTxCsum &&\r
+       enabled_TxCsum = \r
+               ( p_adapter->params.UseTxCsum && viport_canTxCsum( p_adapter->p_currentPath->pViport ) );\r
+       enabled_RxCsum = \r
+               ( p_adapter->params.UseRxCsum && viport_canRxCsum( p_adapter->p_currentPath->pViport ) );\r
+       \r
+       if( !enabled_TxCsum &&\r
                (p_offload_chksum->V4Transmit.IpOptionsSupported ||\r
                p_offload_chksum->V4Transmit.TcpOptionsSupported ||\r
                p_offload_chksum->V4Transmit.TcpChecksum ||\r
@@ -1183,7 +1225,7 @@ __vnic_set_tcp_task_offload(
                return NDIS_STATUS_NOT_SUPPORTED;\r
        }\r
 \r
-       if( !p_adapter->params.UseRxCsum &&\r
+       if( !enabled_RxCsum &&\r
                (p_offload_chksum->V4Receive.IpOptionsSupported ||\r
                p_offload_chksum->V4Receive.TcpOptionsSupported ||\r
                p_offload_chksum->V4Receive.TcpChecksum ||\r
@@ -1192,6 +1234,7 @@ __vnic_set_tcp_task_offload(
        {\r
                return NDIS_STATUS_NOT_SUPPORTED;\r
        }\r
+\r
        if( p_offload_chksum->V6Receive.IpOptionsSupported ||\r
                p_offload_chksum->V6Receive.TcpOptionsSupported ||\r
                p_offload_chksum->V6Receive.TcpChecksum ||\r
@@ -1236,7 +1279,7 @@ vnic_reset(
 \r
        p_adapter = (vnic_adapter_t*)adapter_context;\r
 \r
-       status = vnic_reset_adapter( p_adapter );\r
+       status = adapter_reset( p_adapter );\r
        VNIC_EXIT( VNIC_DBG_INIT );\r
        switch( status )\r
        {\r
@@ -1279,6 +1322,7 @@ vnic_oid_set_info(
                OUT                     PULONG                                          p_bytes_needed )\r
 {\r
        vnic_adapter_t*         p_adapter;\r
+       Netpath_t*                      p_netpath;                      \r
        NDIS_STATUS                     status;\r
        ULONG                           buf_len;\r
        pending_oid_t           oid_info;\r
@@ -1287,10 +1331,11 @@ vnic_oid_set_info(
 \r
        CL_ASSERT( adapter_context );\r
        p_adapter = (vnic_adapter_t*)adapter_context;\r
+       p_netpath= p_adapter->p_currentPath;\r
 \r
        CL_ASSERT( p_bytes_read );\r
        CL_ASSERT( p_bytes_needed );\r
-       CL_ASSERT( p_adapter->pending_set == 0 );\r
+       CL_ASSERT( !p_adapter->pending_set );\r
 \r
        status = NDIS_STATUS_SUCCESS;\r
        *p_bytes_needed = 0;\r
@@ -1317,11 +1362,11 @@ vnic_oid_set_info(
                        ("  IOC %d received set for OID_GEN_CURRENT_PACKET_FILTER, %#x\n",\r
                                                p_adapter->p_currentPath->pViport->ioc_num,\r
                                                *(uint32_t*)info_buf  ));\r
-               if ( !p_adapter->p_currentPath->carrier )\r
-               {\r
-                       status = NDIS_STATUS_NOT_ACCEPTED;\r
-                       break;\r
-               }\r
+//             if ( !p_adapter->p_currentPath->carrier )\r
+//             {\r
+//                     status = NDIS_STATUS_NOT_ACCEPTED;\r
+//                     break;\r
+//             }\r
                if( info_buf_len < sizeof( p_adapter->packet_filter ) )\r
                {\r
                        status = NDIS_STATUS_INVALID_LENGTH;\r
@@ -1333,7 +1378,7 @@ vnic_oid_set_info(
                else\r
                {\r
                        p_adapter->set_oid = oid_info;\r
-                       status = _vnic_process_packet_filter( p_adapter, *((uint32_t*)info_buf) );\r
+                       status = _vnic_process_packet_filter( p_adapter, *((ULONG*)info_buf) );\r
                }\r
                break;\r
 \r
@@ -1395,7 +1440,7 @@ vnic_oid_set_info(
                else\r
                {\r
                        p_adapter->set_oid = oid_info;\r
-                       status = vnic_set_mcast( p_adapter, (mac_addr_t*)info_buf,\r
+                       status = adapter_set_mcast( p_adapter, (mac_addr_t*)info_buf,\r
                                                (uint8_t)(info_buf_len / sizeof(mac_addr_t)) );\r
                }\r
                break;\r
@@ -1412,13 +1457,20 @@ vnic_oid_set_info(
                        VNIC_TRACE( VNIC_DBG_OID,\r
                                ("Set for OID_GEN_TRANSPORT_HEADER_OFFSET\n") );\r
                break;\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
-               VNIC_TRACE( VNIC_DBG_OID,\r
-                       ("  received an unsupported oid of 0x%.8X!\n" , oid));\r
+               if( info_buf_len != 4 )\r
+               {\r
+                       status = NDIS_STATUS_INVALID_LENGTH;\r
+                       break;\r
+               }\r
+               if( *(( uint32_t *)info_buf) < 4095 )\r
+               {\r
+                       p_adapter->vlan_info = *((uint32_t*)info_buf );\r
+               }\r
+               else\r
+               {\r
+                       status = NDIS_STATUS_INVALID_DATA;\r
+               }\r
                break;\r
 \r
        case OID_GEN_SUPPORTED_LIST:\r
@@ -1501,6 +1553,19 @@ vnic_send_packets(
        VNIC_EXIT( VNIC_DBG_SEND );\r
 }\r
 \r
+void vnic_cancel_xmit(\r
+       IN                              NDIS_HANDLE                                     adapter_context,\r
+    IN                         PVOID                                           cancel_id )\r
+{\r
+       vnic_adapter_t*  const  p_adapter =(vnic_adapter_t* const )adapter_context;\r
+\r
+       if( p_adapter && \r
+               p_adapter->p_currentPath )\r
+       {\r
+               netpath_cancel_xmit( p_adapter->p_currentPath, cancel_id );\r
+       }\r
+}\r
+\r
 void\r
 vnic_pnp_notify(\r
        IN                              NDIS_HANDLE                                     adapter_context,\r
@@ -1508,7 +1573,7 @@ vnic_pnp_notify(
        IN                              PVOID                                           info_buf,\r
        IN                              ULONG                                           info_buf_len )\r
 {\r
-       vnic_adapter_t  *p_adapter;\r
+       vnic_adapter_t  *p_adapter;     \r
 \r
        VNIC_ENTER( VNIC_DBG_PNP );\r
 \r
@@ -1517,11 +1582,34 @@ vnic_pnp_notify(
 \r
        p_adapter = (vnic_adapter_t*)adapter_context;\r
 \r
-       VNIC_TRACE( VNIC_DBG_PNP, ("Event %d IOC[%d]\n", pnp_event, p_adapter->ioc_num ) );\r
-       if( pnp_event != NdisDevicePnPEventPowerProfileChanged )\r
+       CL_ASSERT( p_adapter );\r
+\r
+       VNIC_TRACE( VNIC_DBG_PNP, ("Event %d for IOC[%d] in state %#x\n", \r
+               pnp_event, p_adapter->ioc_num, p_adapter->pnp_state ) );\r
+\r
+       switch ( pnp_event )\r
        {\r
-               InterlockedExchange( (volatile LONG *)&p_adapter->pnp_state, IB_PNP_IOC_REMOVE );\r
+       case NdisDevicePnPEventPowerProfileChanged: \r
+               break;\r
+       case NdisDevicePnPEventQueryRemoved:\r
+       case NdisDevicePnPEventRemoved:\r
+       case NdisDevicePnPEventSurpriseRemoved:\r
+       case NdisDevicePnPEventQueryStopped:\r
+       case NdisDevicePnPEventStopped:\r
+       case NdisDevicePnPEventMaximum:\r
+\r
+               if( InterlockedExchange( (volatile LONG*)&p_adapter->pnp_state, IB_PNP_IOC_REMOVE ) == IB_PNP_IOC_ADD )\r
+               {\r
+                       if( netpath_is_valid( p_adapter->p_currentPath ) )\r
+                       {\r
+                               netpath_stopXmit( p_adapter->p_currentPath );\r
+                               InterlockedExchange( &p_adapter->p_currentPath->carrier, (LONG)FALSE );\r
+                               netpath_linkDown( p_adapter->p_currentPath );\r
+                               __pending_queue_cleanup( p_adapter );\r
+                       }\r
+               }\r
                vnic_resume_oids( p_adapter );\r
+               break;\r
        }\r
 \r
        VNIC_EXIT( VNIC_DBG_PNP );\r
@@ -1533,21 +1621,25 @@ vnic_shutdown(
        IN              PVOID           adapter_context )\r
 {\r
        vnic_adapter_t  *p_adapter;\r
+       Netpath_t       *p_netpath;\r
+\r
        VNIC_ENTER( VNIC_DBG_INIT );\r
        p_adapter = (vnic_adapter_t *)adapter_context;\r
 \r
        if( p_adapter )\r
        {\r
+               g_vnic.shutdown = p_adapter->ioc_num;\r
                VNIC_TRACE( VNIC_DBG_INIT, \r
-                       ("IOC[%d]Shutdown -early retierement\n", p_adapter->ioc_num ));\r
+                       ("IOC[%d] going to Shutdown\n", p_adapter->ioc_num ));\r
+               p_netpath = p_adapter->p_currentPath;\r
 \r
-               if( p_adapter->p_currentPath &&\r
-                       p_adapter->p_currentPath->pViport )\r
+               if( p_netpath && p_netpath->pViport )\r
                {\r
-                       viport_stopXmit( p_adapter->p_currentPath->pViport );\r
-                       viport_linkDown( p_adapter->p_currentPath->pViport );\r
-                       InterlockedExchange( &p_adapter->p_currentPath->carrier, (LONG)FALSE );\r
+                       netpath_stopXmit( p_netpath );\r
+                       InterlockedExchange( &p_netpath->carrier, (LONG)FALSE );\r
+                       netpath_linkDown( p_netpath );\r
                }\r
+\r
                vnic_destroy_adapter( p_adapter );\r
        }\r
 \r
@@ -1560,61 +1652,72 @@ vnic_resume_set_oids(
        IN                              vnic_adapter_t* const           p_adapter )\r
 {\r
        NDIS_STATUS             status = NDIS_STATUS_SUCCESS;\r
-       int                                     pending_set;\r
+       BOOLEAN                                 pending_set;\r
        pending_oid_t   set_oid = {0};\r
 \r
+       Netpath_t*      p_netpath;\r
        VNIC_ENTER( VNIC_DBG_OID );\r
 \r
+       if( !p_adapter->pending_set )\r
+       {\r
+               VNIC_EXIT( VNIC_DBG_OID );\r
+               return;\r
+       }\r
        NdisAcquireSpinLock( &p_adapter->lock );\r
+       p_netpath = p_adapter->p_currentPath;\r
+               VNIC_TRACE( VNIC_DBG_OID,\r
+                                       ("IOC[%d]Resume Set OID %#x\n",\r
+                                               p_adapter->ioc_num, p_adapter->set_oid.oid ));\r
        /*\r
         * Set the status depending on our state.  Fail OID requests that\r
         * are pending while we reset the adapter.\r
         */\r
-       switch( p_adapter->pnp_state )\r
+       if( p_adapter->pnp_state != IB_PNP_IOC_REMOVE && \r
+               netpath_is_connected( p_netpath ) )\r
+       {\r
+               status = NDIS_STATUS_SUCCESS;\r
+       }\r
+       else\r
        {\r
-       case IB_PNP_IOC_ADD:\r
-               break;\r
-\r
-       case IB_PNP_IOC_REMOVE:\r
-       default:\r
                status = NDIS_STATUS_NOT_ACCEPTED;\r
-               break;\r
+               if( p_adapter->pending_set )\r
+               {\r
+                       VNIC_TRACE( VNIC_DBG_PNP,\r
+                               ("IOC[%d]Pending set OID %#x while removing \n",\r
+                               p_adapter->ioc_num, p_adapter->set_oid.oid ));\r
+               }\r
        }\r
 \r
        pending_set = p_adapter->pending_set;\r
        if( pending_set )\r
        {\r
                set_oid = p_adapter->set_oid;\r
-               --p_adapter->pending_set;\r
+               p_adapter->pending_set = FALSE;\r
        }\r
        NdisReleaseSpinLock( &p_adapter->lock );\r
 \r
        ASSERT( KeGetCurrentIrql() == DISPATCH_LEVEL );\r
 \r
-       if( pending_set )\r
+       if( pending_set && status == NDIS_STATUS_SUCCESS )\r
        {\r
                switch( set_oid.oid )\r
                {\r
                case OID_GEN_CURRENT_PACKET_FILTER:\r
                                VNIC_TRACE( VNIC_DBG_OID,\r
                                        ("  IOC %d resume PACKET_FILTER set \n",\r
-                                               p_adapter->p_currentPath->pViport->ioc_num ) );\r
+                                               p_netpath->pViport->ioc_num ) );\r
                        /* Validation already performed in the SetInformation path. */\r
                        p_adapter->packet_filter = *(PULONG)set_oid.p_buf;\r
-                       NdisMSetInformationComplete( p_adapter->h_handle, status );\r
                        break;\r
 \r
                case OID_GEN_MACHINE_NAME:\r
                        status = __vnic_set_machine_name ( p_adapter->set_oid.p_buf, (USHORT)p_adapter->set_oid.buf_len );\r
-                       NdisMSetInformationComplete( p_adapter->h_handle, status );\r
                        break;\r
 \r
                case OID_802_3_MULTICAST_LIST:\r
                                        VNIC_TRACE( VNIC_DBG_OID,\r
                                                ("  IOC %d resume MULTICAST_LIST\n",\r
-                                               p_adapter->p_currentPath->pViport->ioc_num ) );\r
-\r
-                       NdisMSetInformationComplete( p_adapter->h_handle, status );\r
+                                               p_netpath->pViport->ioc_num ) );\r
                        break;\r
 \r
                default:\r
@@ -1623,6 +1726,14 @@ vnic_resume_set_oids(
                }\r
        }\r
 \r
+       if( !netpath_is_connected( p_netpath ) )\r
+       {\r
+               NdisMSetInformationComplete( p_adapter->h_handle, \r
+                       NDIS_STATUS_NOT_ACCEPTED );\r
+       }\r
+       else\r
+               NdisMSetInformationComplete( p_adapter->h_handle, status );\r
+\r
        VNIC_EXIT( VNIC_DBG_OID );\r
 }\r
 \r
@@ -1637,6 +1748,8 @@ vnic_resume_oids(
        pending_oid_t   query_oid = {0};\r
        KIRQL                   irql;\r
 \r
+       Netpath_t*              p_netpath = p_adapter->p_currentPath;\r
+\r
        uint8_t         mac[HW_ADDR_LEN];\r
 \r
        VNIC_ENTER( VNIC_DBG_OID );\r
@@ -1646,9 +1759,7 @@ vnic_resume_oids(
         * Set the status depending on our state.  Fail OID requests that\r
         * are pending while we reset the adapter.\r
         */\r
-       if( !p_adapter->p_viport ||\r
-               p_adapter->p_viport->disconnect == TRUE ||\r
-               p_adapter->p_viport->errored == TRUE )\r
+       if( !netpath_is_connected( p_netpath ) )\r
        {\r
                status = NDIS_STATUS_NOT_ACCEPTED;\r
        }\r
@@ -1688,7 +1799,7 @@ vnic_resume_oids(
                case OID_802_3_PERMANENT_ADDRESS:\r
                        if ( status == NDIS_STATUS_SUCCESS )\r
                        {\r
-                               cl_memcpy( mac, p_adapter->p_viport->hwMacAddress, HW_ADDR_LEN );\r
+                               cl_memcpy( mac, p_netpath->pViport->hwMacAddress, HW_ADDR_LEN );\r
                        }\r
                        _vnic_complete_query( p_adapter,\r
                                                        &query_oid,\r
@@ -1715,17 +1826,22 @@ vnic_resume_oids(
                                                        sizeof( info ) );\r
                        break;\r
                case OID_802_3_MULTICAST_LIST:\r
-                       ASSERT( p_adapter->p_viport );\r
-                        _vnic_complete_query( p_adapter,\r
+                               _vnic_complete_query( p_adapter,\r
                                                        &query_oid,\r
                                                        status,\r
-                                                       &p_adapter->p_viport->macAddresses[MCAST_ADDR_START],\r
-                                                       (p_adapter->p_viport->numMacAddresses -\r
-                                                       MCAST_ADDR_START) * sizeof( mac_addr_t ) );\r
+                                                       p_netpath->p_adapter->mcast_array,\r
+                                                       ( sizeof( p_netpath->p_adapter->mcast_array ) * sizeof( mac_addr_t ) ) );\r
                         break;\r
                case OID_GEN_TRANSMIT_BUFFER_SPACE:\r
-                               info = p_adapter->p_viport->data.xmitPool.bufferSz *\r
-                                               p_adapter->p_viport->data.xmitPool.numXmitBufs;\r
+                       if( status == NDIS_STATUS_SUCCESS )\r
+                       {\r
+                               info = p_netpath->pViport->data.xmitPool.bufferSz *\r
+                                               p_netpath->pViport->data.xmitPool.numXmitBufs;\r
+                       }\r
+                       else\r
+                       {\r
+                               info = 0;\r
+                       }\r
                                _vnic_complete_query( p_adapter,\r
                                                        &query_oid,\r
                                                        status,\r
@@ -1733,8 +1849,15 @@ vnic_resume_oids(
                                                        sizeof( info ) );\r
                        break;\r
                case OID_GEN_RECEIVE_BUFFER_SPACE:\r
-                               info = p_adapter->p_viport->data.recvPool.bufferSz *\r
-                                               p_adapter->p_viport->data.recvPool.poolSz;\r
+                       if( status == NDIS_STATUS_SUCCESS )\r
+                       {\r
+                               info = p_netpath->pViport->data.recvPool.bufferSz *\r
+                                               p_netpath->pViport->data.recvPool.poolSz;\r
+                       }\r
+                       else\r
+                       {\r
+                               info = 0;\r
+                       }\r
                                _vnic_complete_query( p_adapter,\r
                                                        &query_oid,\r
                                                        status,\r
@@ -1767,14 +1890,17 @@ __vnic_set_machine_name(
 {\r
        NDIS_STATUS             status = NDIS_STATUS_SUCCESS;\r
        uint8_t *p_src_buf = (uint8_t *)p_uni_array;\r
-       int i;\r
+       uint32_t i;\r
 \r
        VNIC_ENTER( VNIC_DBG_OID );\r
 \r
-       cl_memclr(g_vnic.host_name, 65 );\r
-       for( i = 0; i < ( buf_size >1 ); i++ )\r
+       if( buf_size > 0 )\r
        {\r
-               g_vnic.host_name[i] = *(p_src_buf + i*2);\r
+               cl_memclr(g_vnic.host_name, sizeof( g_vnic.host_name ) );\r
+               for( i = 0; i < min( ( buf_size > 1 ), sizeof( g_vnic.host_name ) ); i++ )\r
+               {\r
+                       g_vnic.host_name[i] = *(p_src_buf + i*2);\r
+               }\r
        }\r
 \r
        return status;\r
@@ -1867,56 +1993,153 @@ _vnic_process_packet_filter(
                IN      vnic_adapter_t* const   p_adapter,\r
                IN      ULONG                                   pkt_filter )\r
 {\r
-       NDIS_STATUS     status;\r
+       NDIS_STATUS     status = NDIS_STATUS_SUCCESS;\r
+       viport_t        *p_viport;\r
+       ULONG           need_updates = 0;\r
 \r
        VNIC_ENTER(VNIC_DBG_FUNC );\r
 \r
        ASSERT( p_adapter );\r
-       ASSERT( p_adapter->p_viport );\r
-       ASSERT( !(p_adapter->p_viport->updates & SYNC_QUERY) );\r
 \r
-       InterlockedExchange((volatile LONG*)&p_adapter->packet_filter, pkt_filter );\r
+       p_viport = p_adapter->p_currentPath->pViport;\r
 \r
-       ASSERT( (p_adapter->p_viport->updates & ~MCAST_OVERFLOW) == 0 );\r
+       ASSERT( p_viport );\r
+       ASSERT( !( p_viport->updates & SYNC_QUERY ) );\r
 \r
-       if( !( p_adapter->p_viport->flags & INIC_FLAG_ENABLE_NIC ) )\r
+       if( ( InterlockedExchange( \r
+               (volatile LONG*)&p_adapter->packet_filter, pkt_filter )) == (LONG)pkt_filter )\r
        {\r
-               p_adapter->p_viport->newFlags &= ~INIC_FLAG_DISABLE_NIC;\r
-               p_adapter->p_viport->newFlags |= INIC_FLAG_ENABLE_NIC;\r
-               InterlockedOr( &p_adapter->p_viport->updates, NEED_LINK_CONFIG );\r
+               InterlockedExchange( &p_viport->updates, 0 );\r
+               return status;\r
        }\r
 \r
-       if( pkt_filter & NDIS_PACKET_TYPE_ALL_MULTICAST )\r
+       ASSERT( (p_viport->updates & ~MCAST_OVERFLOW) == 0 );\r
+\r
+       if( pkt_filter )\r
        {\r
-               if( !( p_adapter->p_viport->flags & INIC_FLAG_ENABLE_MCAST_ALL ) )\r
+               if( !( p_viport->flags & INIC_FLAG_ENABLE_NIC ) )\r
                {\r
-                       p_adapter->p_viport->newFlags |= INIC_FLAG_ENABLE_MCAST_ALL;\r
-                       // TODO: Shouldn't MCAST_OVERFLOW be a flag bit, not an update bit?\r
-                       InterlockedOr( &p_adapter->p_viport->updates,\r
-                               NEED_LINK_CONFIG | MCAST_OVERFLOW );\r
+                       p_viport->newFlags &= ~INIC_FLAG_DISABLE_NIC;\r
+                       p_viport->newFlags |= INIC_FLAG_ENABLE_NIC;\r
+                       InterlockedOr( (volatile LONG*)&need_updates, NEED_LINK_CONFIG );\r
                }\r
-       }\r
 \r
-       if ( pkt_filter & NDIS_PACKET_TYPE_PROMISCUOUS )\r
-       {\r
-               if( !( p_adapter->p_viport->flags & INIC_FLAG_ENABLE_PROMISC ) )\r
+               if( pkt_filter & NDIS_PACKET_TYPE_ALL_MULTICAST )\r
                {\r
-                       p_adapter->p_viport->newFlags |= INIC_FLAG_ENABLE_PROMISC;\r
-                       InterlockedOr( &p_adapter->p_viport->updates, NEED_LINK_CONFIG );\r
+                       if( !( p_viport->flags & INIC_FLAG_ENABLE_MCAST_ALL ) )\r
+                       {\r
+                               p_viport->newFlags &= ~INIC_FLAG_DISABLE_MCAST_ALL;\r
+                               p_viport->newFlags |= INIC_FLAG_ENABLE_MCAST_ALL;\r
+                               InterlockedOr( (volatile LONG*)&need_updates,\r
+                                                               NEED_LINK_CONFIG | MCAST_OVERFLOW );\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       if( p_viport->flags & NDIS_PACKET_TYPE_ALL_MULTICAST )\r
+                       {\r
+                               p_viport->newFlags &= ~INIC_FLAG_ENABLE_MCAST_ALL;