⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mp_req.c

📁 Intel EtherExpressTM PRO/100+ Ethernet 网卡在Windows2000/xp下的PCI驱动程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    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 + -