📄 mp_req.c
字号:
PNDIS_TASK_OFFLOAD_HEADER pNdisTaskOffloadHdr;
NDIS_MEDIA_STATE CurrMediaState;
NDIS_STATUS IndicateStatus;
#if OFFLOAD
PNDIS_TASK_OFFLOAD pTaskOffload;
PNDIS_TASK_TCP_IP_CHECKSUM pTcpIpChecksumTask;
PNDIS_TASK_TCP_LARGE_SEND pTcpLargeSendTask;
ULONG ulHeadersLen;
ULONG ulMaxOffloadSize;
UINT i;
#endif
#if !BUILD_W2K
NDIS_PHYSICAL_MEDIUM PhysMedium = NdisPhysicalMediumUnspecified;
#endif
DBGPRINT(MP_TRACE, ("====> MPQueryInformation\n"));
Adapter = (PMP_ADAPTER) MiniportAdapterContext;
//
// Initialize the result
//
*BytesWritten = 0;
*BytesNeeded = 0;
//
// Process different type of requests
//
switch(Oid)
{
case OID_GEN_SUPPORTED_LIST:
pInfo = (PVOID) NICSupportedOids;
ulBytesAvailable = ulInfoLen = sizeof(NICSupportedOids);
break;
case OID_GEN_HARDWARE_STATUS:
pInfo = (PVOID) &HardwareStatus;
ulBytesAvailable = ulInfoLen = sizeof(NDIS_HARDWARE_STATUS);
break;
case OID_GEN_MEDIA_SUPPORTED:
case OID_GEN_MEDIA_IN_USE:
pInfo = (PVOID) &Medium;
ulBytesAvailable = ulInfoLen = sizeof(NDIS_MEDIUM);
break;
#if !BUILD_W2K
case OID_GEN_PHYSICAL_MEDIUM:
pInfo = (PVOID) &PhysMedium;
ulBytesAvailable = ulInfoLen = sizeof(NDIS_PHYSICAL_MEDIUM);
break;
#endif
case OID_GEN_CURRENT_LOOKAHEAD:
case OID_GEN_MAXIMUM_LOOKAHEAD:
if (Adapter->ulLookAhead == 0)
{
Adapter->ulLookAhead = NIC_MAX_PACKET_SIZE - NIC_HEADER_SIZE;
}
ulInfo = Adapter->ulLookAhead;
break;
case OID_GEN_MAXIMUM_FRAME_SIZE:
ulInfo = NIC_MAX_PACKET_SIZE - NIC_HEADER_SIZE;
break;
case OID_GEN_MAXIMUM_TOTAL_SIZE:
case OID_GEN_TRANSMIT_BLOCK_SIZE:
case OID_GEN_RECEIVE_BLOCK_SIZE:
ulInfo = (ULONG) NIC_MAX_PACKET_SIZE;
break;
case OID_GEN_MAC_OPTIONS:
// Notes:
// The protocol driver is free to access indicated data by any means.
// Some fast-copy functions have trouble accessing on-board device
// memory. NIC drivers that indicate data out of mapped device memory
// should never set this flag. If a NIC driver does set this flag, it
// relaxes the restriction on fast-copy functions.
// This miniport indicates receive with NdisMIndicateReceivePacket
// function. It has no MiniportTransferData function. Such a driver
// should set this flag.
ulInfo = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |
NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |
NDIS_MAC_OPTION_NO_LOOPBACK;
break;
case OID_GEN_LINK_SPEED:
case OID_GEN_MEDIA_CONNECT_STATUS:
if (InformationBufferLength < ulInfoLen)
{
break;
}
NdisAcquireSpinLock(&Adapter->Lock);
if (MP_TEST_FLAG(Adapter, fMP_ADAPTER_LINK_DETECTION))
{
ASSERT(!Adapter->bQueryPending);
Adapter->bQueryPending = TRUE;
Adapter->QueryRequest.Oid = Oid;
Adapter->QueryRequest.InformationBuffer = InformationBuffer;
Adapter->QueryRequest.InformationBufferLength = InformationBufferLength;
Adapter->QueryRequest.BytesWritten = BytesWritten;
Adapter->QueryRequest.BytesNeeded = BytesNeeded;
NdisReleaseSpinLock(&Adapter->Lock);
DBGPRINT(MP_WARN, ("MPQueryInformation: OID 0x%08x is pended\n", Oid));
Status = NDIS_STATUS_PENDING;
break;
}
else
{
NdisReleaseSpinLock(&Adapter->Lock);
if (Oid == OID_GEN_LINK_SPEED)
{
ulInfo = Adapter->usLinkSpeed * 10000;
}
else // OID_GEN_MEDIA_CONNECT_STATUS
{
CurrMediaState = NICGetMediaState(Adapter);
NdisAcquireSpinLock(&Adapter->Lock);
if (Adapter->MediaState != CurrMediaState)
{
Adapter->MediaState = CurrMediaState;
DBGPRINT(MP_WARN, ("Media state changed to %s\n",
((CurrMediaState == NdisMediaStateConnected)?
"Connected": "Disconnected")));
IndicateStatus = (CurrMediaState == NdisMediaStateConnected) ?
NDIS_STATUS_MEDIA_CONNECT : NDIS_STATUS_MEDIA_DISCONNECT;
if (IndicateStatus == NDIS_STATUS_MEDIA_CONNECT)
{
MP_CLEAR_FLAG(Adapter, fMP_ADAPTER_NO_CABLE);
}
else
{
MP_SET_FLAG(Adapter, fMP_ADAPTER_NO_CABLE);
}
NdisReleaseSpinLock(&Adapter->Lock);
// Indicate the media event
NdisMIndicateStatus(Adapter->AdapterHandle, IndicateStatus, (PVOID)0, 0);
NdisMIndicateStatusComplete(Adapter->AdapterHandle);
}
else
{
NdisReleaseSpinLock(&Adapter->Lock);
}
ulInfo = CurrMediaState;
}
}
break;
case OID_GEN_TRANSMIT_BUFFER_SPACE:
ulInfo = NIC_MAX_PACKET_SIZE * Adapter->NumTcb;
break;
case OID_GEN_RECEIVE_BUFFER_SPACE:
ulInfo = NIC_MAX_PACKET_SIZE * Adapter->CurrNumRfd;
break;
case OID_GEN_VENDOR_ID:
NdisMoveMemory(&ulInfo, Adapter->PermanentAddress, 3);
break;
case OID_GEN_VENDOR_DESCRIPTION:
pInfo = VendorDesc;
ulBytesAvailable = ulInfoLen = sizeof(VendorDesc);
break;
case OID_GEN_VENDOR_DRIVER_VERSION:
ulInfo = VendorDriverVersion;
break;
case OID_GEN_DRIVER_VERSION:
usInfo = (USHORT) NIC_DRIVER_VERSION;
pInfo = (PVOID) &usInfo;
ulBytesAvailable = ulInfoLen = sizeof(USHORT);
break;
// WMI support
case OID_GEN_SUPPORTED_GUIDS:
pInfo = (PUCHAR) &NICGuidList;
ulBytesAvailable = ulInfoLen = sizeof(NICGuidList);
break;
#if OFFLOAD
// Task Offload
case OID_TCP_TASK_OFFLOAD:
DBGPRINT(MP_WARN, ("Query Offloading.\n"));
//
// If the miniport supports LBFO, it can't support task offload
//
#if LBFO
return NDIS_STATUS_NOT_SUPPORTED;
#endif
//
// Because this miniport uses shared memory to do the offload tasks, if
// allocation of memory is failed, then the miniport can't do the offloading
//
if (Adapter->OffloadEnable == FALSE)
{
Status = NDIS_STATUS_NOT_SUPPORTED;
break;
}
//
// Calculate the information buffer length we need to write the offload
// capabilities
//
ulInfoLen = sizeof(NDIS_TASK_OFFLOAD_HEADER) +
FIELD_OFFSET(NDIS_TASK_OFFLOAD, TaskBuffer) +
sizeof(NDIS_TASK_TCP_IP_CHECKSUM) +
FIELD_OFFSET(NDIS_TASK_OFFLOAD, TaskBuffer) +
sizeof(NDIS_TASK_TCP_LARGE_SEND);
if (ulInfoLen > InformationBufferLength)
{
*BytesNeeded = ulInfoLen;
Status = NDIS_STATUS_BUFFER_TOO_SHORT;
break;
}
//
// check version and Encapsulation Type
//
pNdisTaskOffloadHdr = (PNDIS_TASK_OFFLOAD_HEADER)InformationBuffer;
//
// Assume the miniport only supports IEEE_802_3_Encapsulation type
//
if (pNdisTaskOffloadHdr->EncapsulationFormat.Encapsulation != IEEE_802_3_Encapsulation)
{
DBGPRINT(MP_WARN, ("Encapsulation type is not supported.\n"));
pNdisTaskOffloadHdr->OffsetFirstTask = 0;
Status = NDIS_STATUS_NOT_SUPPORTED;
break;
}
//
// Assume the miniport only supports task version of NDIS_TASK_OFFLOAD_VERSION
//
if (pNdisTaskOffloadHdr->Size != sizeof(NDIS_TASK_OFFLOAD_HEADER)
|| pNdisTaskOffloadHdr->Version != NDIS_TASK_OFFLOAD_VERSION)
{
DBGPRINT(MP_WARN, ("Size or Version is not correct.\n"));
pNdisTaskOffloadHdr->OffsetFirstTask = 0;
Status = NDIS_STATUS_NOT_SUPPORTED;
break;
}
//
// If no capabilities supported, OffsetFirstTask should be set to 0
// Currently we support TCP/IP checksum and TCP large send, so set
// OffsetFirstTask to indicate the offset of the first offload task
//
pNdisTaskOffloadHdr->OffsetFirstTask = pNdisTaskOffloadHdr->Size;
//
// Fill TCP/IP checksum and TCP large send task offload structures
//
pTaskOffload = (PNDIS_TASK_OFFLOAD)((PUCHAR)(InformationBuffer) +
pNdisTaskOffloadHdr->Size);
//
// Fill all the offload capabilities the miniport supports.
//
for (i = 0; i < OffloadTasksCount; i++)
{
pTaskOffload->Size = OffloadTasks[i].Size;
pTaskOffload->Version = OffloadTasks[i].Version;
pTaskOffload->Task = OffloadTasks[i].Task;
pTaskOffload->TaskBufferLength = OffloadTasks[i].TaskBufferLength;
//
// Not the last task
//
if (i != OffloadTasksCount - 1)
{
pTaskOffload->OffsetNextTask = FIELD_OFFSET(NDIS_TASK_OFFLOAD, TaskBuffer) +
pTaskOffload->TaskBufferLength;
}
else
{
pTaskOffload->OffsetNextTask = 0;
}
switch (OffloadTasks[i].Task)
{
//
// TCP/IP checksum task offload
//
case TcpIpChecksumNdisTask:
pTcpIpChecksumTask = (PNDIS_TASK_TCP_IP_CHECKSUM) pTaskOffload->TaskBuffer;
NdisMoveMemory(pTcpIpChecksumTask,
&TcpIpChecksumTask,
sizeof(TcpIpChecksumTask));
break;
//
// TCP large send task offload
//
case TcpLargeSendNdisTask:
pTcpLargeSendTask = (PNDIS_TASK_TCP_LARGE_SEND) pTaskOffload->TaskBuffer;
NdisMoveMemory(pTcpLargeSendTask,
&TcpLargeSendTask,
sizeof(TcpLargeSendTask));
ulHeadersLen = TCP_IP_MAX_HEADER_SIZE +
pNdisTaskOffloadHdr->EncapsulationFormat.EncapsulationHeaderSize;
ulMaxOffloadSize = (NIC_MAX_PACKET_SIZE - ulHeadersLen) * (ULONG)(Adapter->NumTcb);
//
// The maximum offload size depends on the size of allocated shared memory
// and the number of TCB available, because this driver doesn't use a queue
// to store the small packets splited from the large packet, so the number
// of small packets must be less than or equal to the number of TCB the
// miniport has, so all the small packets can be sent out at one time.
//
pTcpLargeSendTask->MaxOffLoadSize = (ulMaxOffloadSize > Adapter->OffloadSharedMemSize) ?
Adapter->OffloadSharedMemSize: ulMaxOffloadSize;
//
// Store the maximum offload size
//
TcpLargeSendTask.MaxOffLoadSize = pTcpLargeSendTask->MaxOffLoadSize;
break;
}
//
// Points to the next task offload
//
if (i != OffloadTasksCount)
{
pTaskOffload = (PNDIS_TASK_OFFLOAD)
((PUCHAR)pTaskOffload + pTaskOffload->OffsetNextTask);
}
}
//
// So far, everything is setup, so return to the caller
//
*BytesWritten = ulInfoLen;
*BytesNeeded = 0;
DBGPRINT (MP_WARN, ("Offloading is set.\n"));
return NDIS_STATUS_SUCCESS;
#endif //OFFLOAD
case OID_802_3_PERMANENT_ADDRESS:
pInfo = Adapter->PermanentAddress;
ulBytesAvailable = ulInfoLen = ETH_LENGTH_OF_ADDRESS;
break;
case OID_802_3_CURRENT_ADDRESS:
pInfo = Adapter->CurrentAddress;
ulBytesAvailable = ulInfoLen = ETH_LENGTH_OF_ADDRESS;
break;
case OID_802_3_MAXIMUM_LIST_SIZE:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -