Skip to content

Commit

Permalink
[NetKVM] Review the offload options in the driver. Clean up old code …
Browse files Browse the repository at this point in the history
…and enable TCP\UDP checksum TX offload by default. Fix Win7 WHQL offload issued with NDIS6.2 driver.
  • Loading branch information
YanVugenfirer committed Feb 27, 2012
1 parent 51d20f0 commit 2a84ea5
Show file tree
Hide file tree
Showing 9 changed files with 689 additions and 312 deletions.
291 changes: 210 additions & 81 deletions NetKVM/Common/ParaNdis-Common.c

Large diffs are not rendered by default.

19 changes: 18 additions & 1 deletion NetKVM/Common/ParaNdis-Oid.c
Original file line number Diff line number Diff line change
Expand Up @@ -493,14 +493,31 @@ const char *ParaNdis_OidName(NDIS_OID oid)
MAKECASE(OID_802_3_XMIT_LATE_COLLISIONS)
MAKECASE(OID_GEN_MACHINE_NAME)
MAKECASE(OID_TCP_TASK_OFFLOAD)
#if NDIS60_MINIPORT || NDIS620_MINIPORT
#if NDIS_SUPPORT_NDIS6
MAKECASE(OID_GEN_STATISTICS)
MAKECASE(OID_GEN_INTERRUPT_MODERATION)
#endif
MAKECASE(OID_TCP_OFFLOAD_PARAMETERS)
MAKECASE(OID_OFFLOAD_ENCAPSULATION)
MAKECASE(OID_IP4_OFFLOAD_STATS)
MAKECASE(OID_IP6_OFFLOAD_STATS)
#if NDIS_SUPPORT_NDIS61
MAKECASE(OID_TCP_TASK_IPSEC_OFFLOAD_V2_ADD_SA)
MAKECASE(OID_TCP_TASK_IPSEC_OFFLOAD_V2_DELETE_SA)
MAKECASE(OID_TCP_TASK_IPSEC_OFFLOAD_V2_UPDATE_SA)
#endif
#if NDIS_SUPPORT_NDIS620
MAKECASE(OID_PM_CURRENT_CAPABILITIES)
MAKECASE(OID_PM_HARDWARE_CAPABILITIES)
MAKECASE(OID_PM_PARAMETERS)
MAKECASE(OID_PM_ADD_WOL_PATTERN)
MAKECASE(OID_PM_REMOVE_WOL_PATTERN)
MAKECASE(OID_PM_WOL_PATTERN_LIST)
MAKECASE(OID_PM_ADD_PROTOCOL_OFFLOAD)
MAKECASE(OID_PM_GET_PROTOCOL_OFFLOAD)
MAKECASE(OID_PM_REMOVE_PROTOCOL_OFFLOAD)
MAKECASE(OID_PM_PROTOCOL_OFFLOAD_LIST)
#endif
default:
{
static UCHAR buffer[9];
Expand Down
56 changes: 44 additions & 12 deletions NetKVM/Common/ndis56common.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,11 @@ typedef enum _tagOffloadSettingsBit
osbT4Lso = 0x20,
osbT4LsoIp = 0x40,
osbT4LsoTcp = 0x80,
osbT4IpRxChecksum = 0x100,
osbT4IpRxOptionsChecksum = 0x200,
osbT4RxTCPChecksum = 0x100,
osbT4RxTCPOptionsChecksum = 0x200,
osbT4RxIPChecksum = 0x400,
osbT4RxIPOptionsChecksum = 0x800,
osbT4RxUDPChecksum = 0x1000,
}tOffloadSettingsBit;

typedef struct _tagOffloadSettingsFlags
Expand Down Expand Up @@ -183,10 +186,27 @@ typedef struct _tagOffloadSettings
ULONG maxPacketSize;
}tOffloadSettings;

typedef struct _tagChecksumCheckResult
{
union
{
struct
{
ULONG TcpFailed :1;
ULONG UdpFailed :1;
ULONG IpFailed :1;
ULONG TcpOK :1;
ULONG UdpOK :1;
ULONG IpOK :1;
} flags;
ULONG value;
};
}tChecksumCheckResult;

/*
for simplicity, we use for NDIS5 the same statistics as native NDIS6 uses
*/
#if !NDIS60_MINIPORT && !NDIS620_MINIPORT
#if !NDIS_SUPPORT_NDIS6
typedef struct _tagNdisStatustics
{
ULONG64 ifHCInOctets;
Expand Down Expand Up @@ -225,13 +245,13 @@ typedef struct _tagNdisOffloadParams
UCHAR LsoV2IPv6;
}NDIS_OFFLOAD_PARAMETERS;

#else // NDIS60_MINIPORT
#else // NDIS_SUPPORT_NDIS6

typedef PNET_BUFFER tPacketType;
typedef PMDL tPacketHolderType;
typedef PNET_BUFFER_LIST tPacketIndicationType;

#endif //!NDIS60_MINIPORT
#endif //!NDIS_SUPPORT_NDIS6

//#define UNIFY_LOCKS

Expand Down Expand Up @@ -276,15 +296,14 @@ typedef struct _tagPARANDIS_ADAPTER
BOOLEAN bEnableInterruptHandlingDPC;
BOOLEAN bEnableInterruptChecking;
BOOLEAN bDoInterruptRecovery;
BOOLEAN bDoHardReset;
BOOLEAN bDoSupportPriority;
BOOLEAN bDoPacketFiltering;
BOOLEAN bUseScatterGather;
BOOLEAN bBatchReceive;
BOOLEAN bLinkDetectSupported;
BOOLEAN bDoHardwareOffload;
BOOLEAN bDoIPCheck;
BOOLEAN bFixIPChecksum;
BOOLEAN bDoHardwareChecksum;
BOOLEAN bDoIPCheckTx;
BOOLEAN bDoIPCheckRx;
BOOLEAN bUseMergedBuffers;
BOOLEAN bDoPublishIndices;
BOOLEAN bDoKickOnNoBuffer;
Expand Down Expand Up @@ -326,6 +345,16 @@ typedef struct _tagPARANDIS_ADAPTER
};
#endif
NDIS_STATISTICS_INFO Statistics;
struct
{
ULONG framesCSOffload;
ULONG framesLSO;
ULONG framesIndirect;
ULONG framesRxPriority;
ULONG framesRxCSHwOK;
ULONG framesRxCSHwMissedBad;
ULONG framesRxCSHwMissedGood;
} extraStatistics;
tOurCounters Counters;
tOurCounters Limits;
UINT uRXPacketsDPCLimit;
Expand Down Expand Up @@ -372,7 +401,7 @@ typedef struct _tagPARANDIS_ADAPTER
ULONG ulTxMessage;
ULONG ulControlMessage;

#if NDIS60_MINIPORT || NDIS620_MINIPORT
#if NDIS_SUPPORT_NDIS6
// Vista +
PIO_INTERRUPT_MESSAGE_INFO pMSIXInfoTable;
PNET_BUFFER_LIST SendHead;
Expand Down Expand Up @@ -401,7 +430,7 @@ typedef struct _tagPARANDIS_ADAPTER
#endif
}PARANDIS_ADAPTER, *PPARANDIS_ADAPTER;

typedef enum { cpeOK, cpeNoBuffer, cpeInternalError, cpeTooLarge, cpeNoIndirect } tCopyPacketError;
typedef enum { cpeOK, cpeNoBuffer, cpeInternalError, cpeTooLarge, cpeNoIndirect } tCopyPacketError;
typedef struct _tagCopyPacketResult
{
ULONG size;
Expand Down Expand Up @@ -550,12 +579,13 @@ typedef struct _tagTxOperationParameters
UINT nofSGFragments;
ULONG ulDataSize;
ULONG offloalMss;
ULONG tcpHeaderOffset;
ULONG flags; //see tPacketOffloadRequest
}tTxOperationParameters;

tCopyPacketResult ParaNdis_DoCopyPacketData(
PARANDIS_ADAPTER *pContext,
const tTxOperationParameters *pParams);
tTxOperationParameters *pParams);

typedef struct _tagMapperResult
{
Expand All @@ -569,6 +599,8 @@ tCopyPacketResult ParaNdis_DoSubmitPacket(PARANDIS_ADAPTER *pContext, tTxOperati

void ParaNdis_ResetOffloadSettings(PARANDIS_ADAPTER *pContext, tOffloadSettingsFlags *pDest, PULONG from);

tChecksumCheckResult ParaNdis_CheckRxChecksum(PARANDIS_ADAPTER *pContext, ULONG virtioFlags, PVOID pRxPacket, ULONG len);

void ParaNdis_CallOnBugCheck(PARANDIS_ADAPTER *pContext);

/*****************************************************
Expand Down
89 changes: 39 additions & 50 deletions NetKVM/wlh/ParaNdis6-Driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@
* the COPYING file in the top-level directory.
*
**********************************************************************/


#include "ParaNdis6.h"
#include "ParaNdis-Oid.h"

#if NDIS60_MINIPORT || NDIS620_MINIPORT
#if NDIS_SUPPORT_NDIS6

//#define NO_VISTA_POWER_MANAGEMENT

Expand Down Expand Up @@ -107,7 +109,7 @@ void ParaNdis_IndicateConnect(PARANDIS_ADAPTER *pContext, BOOLEAN bConnected, BO
NdisZeroMemory(&state, sizeof(state));
state.Header.Revision = NDIS_LINK_STATE_REVISION_1;
state.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
state.Header.Size = sizeof(state);
state.Header.Size = NDIS_SIZEOF_LINK_STATE_REVISION_1;
state.MediaConnectState =
pContext->bConnected ?
MediaConnectStateConnected :
Expand All @@ -123,7 +125,7 @@ void ParaNdis_IndicateConnect(PARANDIS_ADAPTER *pContext, BOOLEAN bConnected, BO

indication.Header.Type = NDIS_OBJECT_TYPE_STATUS_INDICATION;
indication.Header.Revision = NDIS_STATUS_INDICATION_REVISION_1;
indication.Header.Size = sizeof(indication);
indication.Header.Size = NDIS_SIZEOF_STATUS_INDICATION_REVISION_1;
indication.SourceHandle = pContext->MiniportHandle;
indication.StatusCode = NDIS_STATUS_LINK_STATE;
indication.StatusBuffer = &state;
Expand Down Expand Up @@ -175,7 +177,7 @@ static NDIS_STATUS CreateTimers(PARANDIS_ADAPTER *pContext)
DEBUG_ENTRY(4);
tch.Header.Type = NDIS_OBJECT_TYPE_TIMER_CHARACTERISTICS;
tch.Header.Revision = NDIS_TIMER_CHARACTERISTICS_REVISION_1;
tch.Header.Size = sizeof(tch);
tch.Header.Size = NDIS_SIZEOF_TIMER_CHARACTERISTICS_REVISION_1;
tch.AllocationTag = PARANDIS_MEMORY_TAG;
tch.FunctionContext = pContext;
tch.TimerFunction = ConnectTimerCallback;
Expand Down Expand Up @@ -232,7 +234,7 @@ static NDIS_STATUS ParaNdis6_Initialize(
NdisZeroMemory(&miniportAttributes, sizeof(miniportAttributes));
miniportAttributes.RegistrationAttributes.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES;
miniportAttributes.RegistrationAttributes.Header.Revision = NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1;
miniportAttributes.RegistrationAttributes.Header.Size = sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES);
miniportAttributes.RegistrationAttributes.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1;
miniportAttributes.RegistrationAttributes.MiniportAdapterContext = pContext;
miniportAttributes.RegistrationAttributes.AttributeFlags =
#ifndef NO_VISTA_POWER_MANAGEMENT
Expand Down Expand Up @@ -261,7 +263,7 @@ static NDIS_STATUS ParaNdis6_Initialize(
/* prepare statistics struct for further reports */
pContext->Statistics.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
pContext->Statistics.Header.Revision = NDIS_STATISTICS_INFO_REVISION_1;
pContext->Statistics.Header.Size = sizeof(pContext->Statistics);
pContext->Statistics.Header.Size = NDIS_SIZEOF_STATISTICS_INFO_REVISION_1;
/* let Common do all the rest */
status = ParaNdis_InitializeContext(pContext, miniportInitParameters->AllocatedResources);
if (status != NDIS_STATUS_SUCCESS)
Expand All @@ -282,16 +284,27 @@ static NDIS_STATUS ParaNdis6_Initialize(

if (status == NDIS_STATUS_SUCCESS)
{
NDIS_PNP_CAPABILITIES powerCaps;
PNDIS_PNP_CAPABILITIES pPowerCaps = &powerCaps;
ParaNdis_FillPowerCapabilities(&powerCaps);
NDIS_PNP_CAPABILITIES power60Caps;
#if NDIS_SUPPORT_NDIS620
NDIS_PM_CAPABILITIES power620Caps;
#endif
#ifdef NO_VISTA_POWER_MANAGEMENT
pPowerCaps = NULL;
#endif
ParaNdis_FillPowerCapabilities(&power60Caps);

NdisZeroMemory(&miniportAttributes, sizeof(miniportAttributes));
miniportAttributes.GeneralAttributes.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES;
miniportAttributes.GeneralAttributes.Header.Revision = NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_1;
miniportAttributes.GeneralAttributes.Header.Size = sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES);
miniportAttributes.GeneralAttributes.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_1;
#if NDIS_SUPPORT_NDIS620
miniportAttributes.GeneralAttributes.Header.Revision = NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_2;
miniportAttributes.GeneralAttributes.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_2;
miniportAttributes.GeneralAttributes.PowerManagementCapabilitiesEx = &power620Caps;
ParaNdis6_Fill620PowerCapabilities(pContext, &power620Caps);
#else
miniportAttributes.GeneralAttributes.PowerManagementCapabilities = &power60Caps;
#endif
miniportAttributes.GeneralAttributes.MediaType = NdisMedium802_3;
miniportAttributes.GeneralAttributes.PhysicalMediumType = NdisPhysicalMedium802_3;
miniportAttributes.GeneralAttributes.MtuSize = pContext->MaxPacketSize.nMaxDataSize;
Expand All @@ -304,7 +317,6 @@ static NDIS_STATUS ParaNdis6_Initialize(
miniportAttributes.GeneralAttributes.RcvLinkSpeed = pContext->bConnected ?
PARANDIS_FORMAL_LINK_SPEED : NDIS_LINK_SPEED_UNKNOWN;
miniportAttributes.GeneralAttributes.MediaDuplexState = MediaDuplexStateFull;
miniportAttributes.GeneralAttributes.PowerManagementCapabilities = pPowerCaps;
miniportAttributes.GeneralAttributes.MacOptions =
NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | /* NIC has no internal loopback support */
NDIS_MAC_OPTION_TRANSFERS_NOT_PEND | /* Must be set since using NdisMIndicateReceivePacket */
Expand Down Expand Up @@ -577,21 +589,12 @@ static void OnResetWorkItem(PVOID WorkItemContext, NDIS_HANDLE NdisIoWorkItemH
DEBUG_ENTRY(0);
bSendActive = pContext->SendState == srsEnabled;
bReceiveActive = pContext->ReceiveState == srsEnabled;
if (!pContext->bDoHardReset)
{
ParaNdis_IndicateConnect(pContext, FALSE, FALSE);
ParaNdis_Suspend(pContext);
if (bSendActive) ParaNdis6_SendPauseRestart(pContext, FALSE, NULL);
if (bReceiveActive) ParaNdis6_ReceivePauseRestart(pContext, FALSE, NULL);
ParaNdis_ReportLinkStatus(pContext);
}
else
{
ParaNdis_PowerOff(pContext);
ParaNdis_PowerOn(pContext);
if (bSendActive) ParaNdis6_SendPauseRestart(pContext, FALSE, NULL);
if (bReceiveActive) ParaNdis6_ReceivePauseRestart(pContext, FALSE, NULL);
}

ParaNdis_PowerOff(pContext);
ParaNdis_PowerOn(pContext);
if (bSendActive) ParaNdis6_SendPauseRestart(pContext, FALSE, NULL);
if (bReceiveActive) ParaNdis6_ReceivePauseRestart(pContext, FALSE, NULL);

NdisFreeMemory(pwi, 0, 0);
NdisFreeIoWorkItem(NdisIoWorkItemHandle);
ParaNdis_DebugHistory(pContext, hopSysReset, NULL, 0, NDIS_STATUS_SUCCESS, 0);
Expand Down Expand Up @@ -958,7 +961,7 @@ static void RetrieveDriverConfiguration()
DEBUG_ENTRY(2);
co.Header.Type = NDIS_OBJECT_TYPE_CONFIGURATION_OBJECT;
co.Header.Revision = NDIS_CONFIGURATION_OBJECT_REVISION_1;
co.Header.Size = sizeof(co);
co.Header.Size = NDIS_SIZEOF_CONFIGURATION_OBJECT_REVISION_1;
co.Flags = 0;
co.NdisHandle = DriverHandle;
status = NdisOpenConfigurationEx(&co, &cfg);
Expand All @@ -977,28 +980,15 @@ static void RetrieveDriverConfiguration()
}
}

#if !NDIS60_MINIPORT
#if NDIS_SUPPORT_NDIS61
static NDIS_STATUS ParaNdis6x_DirectOidRequest(IN NDIS_HANDLE miniportAdapterContext, IN PNDIS_OID_REQUEST OidRequest)
{
NDIS_STATUS status = NDIS_STATUS_NOT_SUPPORTED;
PARANDIS_ADAPTER *pContext = (PARANDIS_ADAPTER *)miniportAdapterContext;

if (pContext->bSurprizeRemoved) status = NDIS_STATUS_NOT_ACCEPTED;

switch(OidRequest->DATA.SET_INFORMATION.Oid) {
case OID_TCP_TASK_IPSEC_OFFLOAD_V2_ADD_SA:
DPrintf(1, ("Received: OID_TCP_TASK_IPSEC_OFFLOAD_V2_ADD_SA"));
break;
case OID_TCP_TASK_IPSEC_OFFLOAD_V2_DELETE_SA:
DPrintf(1, ("Received: OID_TCP_TASK_IPSEC_OFFLOAD_V2_DELETE_SA"));
break;
case OID_TCP_TASK_IPSEC_OFFLOAD_V2_UPDATE_SA:
DPrintf(1, ("Received: OID_TCP_TASK_IPSEC_OFFLOAD_V2_UPDATE_SA"));
break;
default:
DPrintf(0, ("%s> Unknown OID received: %x", __FUNCTION__, OidRequest->DATA.SET_INFORMATION.Oid));
break;
}
DPrintf(1, ("[%s] came %s", __FUNCTION__, ParaNdis_OidName(OidRequest->DATA.SET_INFORMATION.Oid)));

return status;
}
Expand Down Expand Up @@ -1031,6 +1021,7 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath

DEBUG_ENTRY(0);
_LogOutString(0, __DATE__ " " __TIME__);
DPrintf(0, (__DATE__ " " __TIME__ "built %d.%d", NDIS_MINIPORT_MAJOR_VERSION, NDIS_MINIPORT_MINOR_VERSION));
#ifdef DEBUG_TIMING
KeQueryTickCount(&TickCount);
NdisGetCurrentSystemTime(&SysTime);
Expand All @@ -1040,13 +1031,8 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath
NdisZeroMemory(&chars, sizeof(chars));

chars.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_DRIVER_CHARACTERISTICS;
chars.Header.Size = sizeof(NDIS_MINIPORT_DRIVER_CHARACTERISTICS);
#if NDIS60_MINIPORT
chars.Header.Revision = NDIS_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_1;
#else
chars.Header.Revision = NDIS_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_2;
#endif

chars.Header.Size = NDIS_SIZEOF_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_1;
chars.MajorNdisVersion = NDIS_MINIPORT_MAJOR_VERSION;
chars.MinorNdisVersion = NDIS_MINIPORT_MINOR_VERSION;
/* stupid thing, they are at least short */
Expand All @@ -1071,7 +1057,10 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath
chars.ShutdownHandlerEx = ParaNdis6_AdapterShutdown;
chars.DevicePnPEventNotifyHandler = ParaNdis6_DevicePnPEvent;
chars.SetOptionsHandler = ParaNdis6_SetOptions;
#if !NDIS60_MINIPORT

#if NDIS_SUPPORT_NDIS61
chars.Header.Revision = NDIS_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_2;
chars.Header.Size = NDIS_SIZEOF_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_2;
chars.DirectOidRequestHandler = ParaNdis6x_DirectOidRequest;
chars.CancelDirectOidRequestHandler = ParaNdis6x_CancelDirectOidRequest;
#endif
Expand Down Expand Up @@ -1109,4 +1098,4 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath
return status;
}

#endif //NDIS60_MINIPORT || NDIS620_MINIPORT
#endif //NDIS_SUPPORT_NDIS6

0 comments on commit 2a84ea5

Please sign in to comment.