NDIS_STATUS ParaNdis6_RSSSetReceiveHash(PARANDIS_RSS_PARAMS *RSSParameters, const NDIS_RECEIVE_HASH_PARAMETERS* Params, UINT ParamsLength, PUINT ParamsBytesRead) { if (ParamsLength < sizeof(NDIS_RECEIVE_HASH_PARAMETERS)) return NDIS_STATUS_INVALID_LENGTH; *ParamsBytesRead += sizeof(NDIS_RECEIVE_HASH_PARAMETERS); if (RSSParameters->RSSMode == PARANDIS_RSS_FULL) { //Here we check that originator doesn't try to enable hashing while full RSS is on. //Disable hashing abd clear parameters is legitimate operation hovewer if(Params->Flags & NDIS_RECEIVE_HASH_FLAG_ENABLE_HASH) { if(!(Params->Flags & NDIS_RECEIVE_HASH_FLAG_HASH_INFO_UNCHANGED) && (Params->HashInformation != 0)) return NDIS_STATUS_NOT_SUPPORTED; if((Params->Flags & NDIS_RECEIVE_HASH_FLAG_HASH_INFO_UNCHANGED) && (RSSParameters->ReceiveHashingSettings.HashInformation != 0)) return NDIS_STATUS_NOT_SUPPORTED; } } if (!(Params->Flags & NDIS_RECEIVE_HASH_FLAG_HASH_INFO_UNCHANGED) && (!IsValidHashInfo(Params->HashInformation))) return NDIS_STATUS_INVALID_PARAMETER; if ( (!(Params->Flags & NDIS_RECEIVE_HASH_FLAG_HASH_KEY_UNCHANGED)) && ( (Params->HashSecretKeySize > NDIS_RSS_HASH_SECRET_KEY_MAX_SIZE_REVISION_2) || (ParamsLength < (Params->HashSecretKeyOffset + Params->HashSecretKeySize)) ) ) return NDIS_STATUS_INVALID_LENGTH; if (!(Params->Flags & NDIS_RECEIVE_HASH_FLAG_HASH_INFO_UNCHANGED)) { RSSParameters->ReceiveHashingSettings.HashInformation = Params->HashInformation; } if (!(Params->Flags & NDIS_RECEIVE_HASH_FLAG_HASH_KEY_UNCHANGED)) { RSSParameters->ReceiveHashingSettings.HashSecretKeySize = Params->HashSecretKeySize; NdisMoveMemory(RSSParameters->ReceiveHashingSettings.HashSecretKey, (char*)Params + Params->HashSecretKeyOffset, Params->HashSecretKeySize); *ParamsBytesRead += Params->HashSecretKeySize; } if(RSSParameters->RSSMode != PARANDIS_RSS_FULL) { ApplySettings(RSSParameters, ((Params->Flags & NDIS_RECEIVE_HASH_FLAG_ENABLE_HASH) && (Params->HashInformation != 0)) ? PARANDIS_RSS_HASHING : PARANDIS_RSS_DISABLED, &RSSParameters->ReceiveHashingSettings, NULL); } return NDIS_STATUS_SUCCESS; }
NDIS_STATUS ParaNdis6_RSSSetParameters( PARANDIS_RSS_PARAMS *RSSParameters, const NDIS_RECEIVE_SCALE_PARAMETERS* Params, UINT ParamsLength, PUINT ParamsBytesRead, NDIS_HANDLE NdisHandle) { ULONG ProcessorMasksSize; ULONG IndirectionTableEntries; CNdisPassiveWriteAutoLock autoLock(RSSParameters->rwLock); *ParamsBytesRead = 0; if((RSSParameters->RSSMode == PARANDIS_RSS_HASHING) && !(Params->Flags & NDIS_RSS_PARAM_FLAG_DISABLE_RSS) && (Params->HashInformation != 0)) return NDIS_STATUS_NOT_SUPPORTED; if (ParamsLength < sizeof(NDIS_RECEIVE_SCALE_PARAMETERS)) return NDIS_STATUS_INVALID_LENGTH; if (!(Params->Flags & NDIS_RSS_PARAM_FLAG_HASH_INFO_UNCHANGED) && !IsValidHashInfo(Params->HashInformation)) return NDIS_STATUS_INVALID_PARAMETER; IndirectionTableEntries = Params->IndirectionTableSize / sizeof(PROCESSOR_NUMBER); if (!(Params->Flags & NDIS_RSS_PARAM_FLAG_ITABLE_UNCHANGED) && ( (Params->IndirectionTableSize > sizeof(RSSParameters->RSSScalingSettings.IndirectionTable)) || (ParamsLength < (Params->IndirectionTableOffset + Params->IndirectionTableSize)) || !IsPowerOfTwo(IndirectionTableEntries) ) ) return NDIS_STATUS_INVALID_LENGTH; if (!(Params->Flags & NDIS_RSS_PARAM_FLAG_HASH_KEY_UNCHANGED) && ( (Params->HashSecretKeySize > sizeof(RSSParameters->RSSHashingSettings.HashSecretKey)) || (ParamsLength < (Params->HashSecretKeyOffset + Params->HashSecretKeySize)) ) ) return NDIS_STATUS_INVALID_LENGTH; ProcessorMasksSize = Params->NumberOfProcessorMasks * Params->ProcessorMasksEntrySize; if (ParamsLength < Params->ProcessorMasksOffset + ProcessorMasksSize) return NDIS_STATUS_INVALID_LENGTH; if(Params->Flags & NDIS_RSS_PARAM_FLAG_DISABLE_RSS || (Params->HashInformation == 0)) { ApplySettings(RSSParameters, PARANDIS_RSS_DISABLED, NULL, NULL); } else { if (!(Params->Flags & NDIS_RSS_PARAM_FLAG_ITABLE_UNCHANGED)) { if(!AllocateCPUMappingArray(NdisHandle, &RSSParameters->RSSScalingSettings)) return NDIS_STATUS_RESOURCES; RSSParameters->RSSScalingSettings.IndirectionTableSize = Params->IndirectionTableSize; NdisMoveMemory(RSSParameters->RSSScalingSettings.IndirectionTable, (char*)Params + Params->IndirectionTableOffset, Params->IndirectionTableSize); RSSParameters->RSSScalingSettings.RSSHashMask = IndirectionTableEntries - 1; *ParamsBytesRead += Params->IndirectionTableSize; *ParamsBytesRead += ProcessorMasksSize; FillCPUMappingArray(&RSSParameters->RSSScalingSettings, RSSParameters->ReceiveQueuesNumber); } if (!(Params->Flags & NDIS_RSS_PARAM_FLAG_HASH_INFO_UNCHANGED)) RSSParameters->RSSHashingSettings.HashInformation = Params->HashInformation; if (!(Params->Flags & NDIS_RSS_PARAM_FLAG_HASH_KEY_UNCHANGED)) { RSSParameters->RSSHashingSettings.HashSecretKeySize = Params->HashSecretKeySize; NdisMoveMemory(RSSParameters->RSSHashingSettings.HashSecretKey, (char*)Params + Params->HashSecretKeyOffset, Params->HashSecretKeySize); *ParamsBytesRead += Params->HashSecretKeySize; } ApplySettings(RSSParameters, PARANDIS_RSS_FULL, &RSSParameters->RSSHashingSettings, &RSSParameters->RSSScalingSettings); } *ParamsBytesRead += sizeof(NDIS_RECEIVE_SCALE_PARAMETERS); return NDIS_STATUS_SUCCESS; }