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

📄 interrup.c

📁 Wince4.2 BSP for SH4 engineering development board
💻 C
📖 第 1 页 / 共 2 页
字号:
        WriteWord(MMU_CMD,MC_FREEPKT);
    
        // Acknowledge the interrupt
        SelectBank(BANK2);
        WriteWord(INT_REG,ReadWord(INT_REG) & (0xff00 | TX_INT));

        // Re-enable Transmission
        SelectBank(BANK0);
        WriteWord(TCR,ReadWord(TCR)|TCR_ENABLE);

        // Get next interrupt, if any
            CardGetInterruptStatus(Adapter, &InterruptStatus);
    }

    while(InterruptStatus & RCV_INT) {
        USHORT  wStatusWord;
        USHORT  wControlWord;
        // PUSHORT  pwData = (PUSHORT)PacketBuffer;
        PUSHORT pwData = (PUSHORT)Adapter->Lookahead;
        UINT    PacketLength;
        UINT    i;
        
        Adapter->ReceivePacketCount++;

        // Setup pointer address register to point to first byte of Frame
        SelectBank(BANK2);
        WriteWord(POINTER,0xE000);

        // Check for an error
        wStatusWord = ReadWord(DATA_1);
            // DEBUGMSG(ZONE_INTR, (TEXT("CELAN:Statsu word = %04x \r\n"),wStatusWord));
        if(!(wStatusWord & 0xAC00)) {
            // Read packet length
            PacketLength = (0x07ff & ReadWord(DATA_1))-6;
            DEBUGMSG(ZONE_INTR, (TEXT("CELAN:Packet length = %04x \r\n"),PacketLength));

            if (PacketLength>1518) {
                    DEBUGMSG(ZONE_ERROR, (TEXT("CELAN:Packet too big.\r\n")));
                    DEBUGMSG(ZONE_ERROR, (TEXT("CELAN:Packet length = %04x \r\n"),PacketLength));
                PacketLength=1518;
            }

            // Read all data
            for(i=0;i<(PacketLength>>1);i++) {
                *pwData = ReadWord(DATA_1);
                DEBUGMSG(ZONE_INTR, (TEXT("%04x "),*pwData));
                pwData++;
            }

            wControlWord = ReadWord(DATA_1);
            if(wControlWord & 0x2000) {
                *pwData = wControlWord;
                DEBUGMSG(ZONE_INTR, (TEXT("Odd data %04x \r\n"),*pwData));
                PacketLength++;
            }

            DEBUGMSG(ZONE_INTR, (TEXT("\r\n"),*pwData));

            if(PacketLength < Adapter->MaxLookAhead + CELAN_HEADER_SIZE) {
                PacketLength = Adapter->MaxLookAhead + CELAN_HEADER_SIZE;
            }

            if(PacketLength < CELAN_HEADER_SIZE) {
                DEBUGMSG(ZONE_INTR,
                    (TEXT("Calling NdisMEtheIndicateReceive %x, %x, %x, %x, %x, %x, %x\r\n"),
                    Adapter->MiniportAdapterHandle,
                    Adapter,
                    Adapter->Lookahead,
                    PacketLength,
                    NULL,
                    0,
                    0
                    ));
                NdisMEthIndicateReceive(
                    Adapter->MiniportAdapterHandle,
                    (NDIS_HANDLE)Adapter,
                    (PCHAR)Adapter->Lookahead,
                    PacketLength,
                    NULL,
                    0,
                    0
                    );
            } else {
                DEBUGMSG(ZONE_INTR,
                    (TEXT("Calling NdisMEtheIndicateReceive %x, %x, %x, %x, %x, %x, %x\r\n"),
                    Adapter->MiniportAdapterHandle,
                    Adapter,
                    Adapter->Lookahead,
                    CELAN_HEADER_SIZE,
                    Adapter->Lookahead+CELAN_HEADER_SIZE,
                    PacketLength-CELAN_HEADER_SIZE,
                    PacketLength-CELAN_HEADER_SIZE
                    ));
                NdisMEthIndicateReceive(
                    Adapter->MiniportAdapterHandle,
                    (NDIS_HANDLE)Adapter,
                    (PCHAR)Adapter->Lookahead,
                    CELAN_HEADER_SIZE,
                    (PCHAR)Adapter->Lookahead+CELAN_HEADER_SIZE,
                    PacketLength-CELAN_HEADER_SIZE,
                    PacketLength-CELAN_HEADER_SIZE
                    );
            }

            Adapter->FramesRcvGood++;
            
            DEBUGMSG(ZONE_INTR, (TEXT("Calling NdisMEtheIndicateReceiveComplete\r\n")));
            NdisMEthIndicateReceiveComplete(Adapter->MiniportAdapterHandle);

        } else {
            DEBUGMSG(ZONE_ERROR,(TEXT("Receive frame status error (%04x)\r\n"),wStatusWord));
            if (wStatusWord & 0x8000)
                Adapter->FrameAlignmentErrors++;
            if (wStatusWord & 0x2000)
                Adapter->CrcErrors++;
        }

        // Release the memory for the received frame
        WriteWord(MMU_CMD,0x0080);
        while(ReadWord(MMU_CMD)&1);

        // Get next interrupt, if any
        CardGetInterruptStatus(Adapter, &InterruptStatus);
    }
    // Re-enable receiving
    SelectBank(BANK0);
    WriteWord(RCR,Adapter->NicReceiveConfig);

    SelectBank(Bank);

}

NDIS_STATUS
CelanSend(
    IN NDIS_HANDLE MiniportAdapterContext,
    IN PNDIS_PACKET Packet,
    IN UINT Flags
    )

/*++

Routine Description:


    The CelanSend request instructs a driver to transmit a packet through
    the adapter onto the medium.

Arguments:

    MiniportAdapterContext - Context registered with the wrapper, really
        a pointer to the adapter.

    Packet - A pointer to a descriptor for the packet that is to be
    transmitted.

    SendFlags - Optional send flags

Notes:

    This miniport driver will always accept a send.  This is because
    the Celan has limited send resources and the driver needs packets
    to copy to the adapter immediately after a transmit completes in
    order to keep the adapter as busy as possible.

    This is not required for other adapters, as they have enough
    resources to keep the transmitter busy until the wrapper submits
    the next packet.

--*/

{
    PUCHAR  CurBufAddress;
    UINT    CurBufLen;
    UINT    PacketLength;
    PNDIS_BUFFER    CurBuffer;
    int i;
    USHORT  wFrameHandle;
    USHORT  cwBufferSize;
    BOOL    CurHiByte=FALSE;
    USHORT  CurData;

#define WAIT_LOOP   1000000

    PCELAN_ADAPTER Adapter = (PCELAN_ADAPTER)(MiniportAdapterContext);
    DEBUGMSG(ZONE_FUNCTION, (TEXT("+CELAN:Send\r\n")));

    // Get the packet length and the first buffer
    NdisQueryPacket(Packet,NULL,NULL,&CurBuffer,&PacketLength);
    DEBUGMSG(ZONE_XMIT, (TEXT("The Packet length is %d bytes.\r\n"),PacketLength));
    
    // Skip 0 length copies
    if (PacketLength == 0) {
        return NDIS_STATUS_SUCCESS;
    }

    if (PacketLength >= 0x800) {
        DEBUGMSG(ZONE_ERROR, (TEXT("CelanSend : The Packet is too big(%d bytes)\r\n"),PacketLength));
        return NDIS_STATUS_FAILURE;
    }

    // Calcurate buffer size
    cwBufferSize = 2 + 2 + PacketLength + 1;
    if (cwBufferSize & 1) {
        cwBufferSize++;
    }

    // Allocate TX buffer
    DEBUGMSG(ZONE_XMIT, (TEXT("Allocationg buffers...\r\n")));
    SelectBank(BANK2);
    WriteWord(MMU_CMD,MC_ALLOC|(cwBufferSize>>8));

    // Loop here until the request is satisfied, or we timeout
    for (i=0;(i<WAIT_LOOP)&&!(ReadWord(INT_REG) & ALLOC_INT);i++);
    if(i==WAIT_LOOP) {
        PrintRegs;
        DEBUGMSG(ZONE_ERROR, (TEXT("Allocationg timeout.\r\n")));
        return NDIS_STATUS_FAILURE;
    }

    // Get the allocated packet number
    wFrameHandle = ReadWord(PNR_ARR) >> 8;
    DEBUGMSG(ZONE_XMIT, (TEXT(" Packet #%d is allocated.\r\n"),wFrameHandle));
    
    // Set the packet number to be accessed
    WriteWord(PNR_ARR,wFrameHandle);

    // Initialize pointer
    WriteWord(POINTER,PTR_AUTOINC); // Auto increment mode

    // Get the first non-zero buffer
    NdisQueryBuffer(CurBuffer,(PVOID*)&CurBufAddress,&CurBufLen);
    while(CurBuffer && (CurBufLen == 0)) {
        NdisGetNextBuffer(CurBuffer,&CurBuffer);
        NdisQueryBuffer(CurBuffer,(PVOID*)&CurBufAddress,&CurBufLen);
    }

    // Write the Status word
    WriteWord(DATA_1,0);

    // Write the byte count
    WriteWord(DATA_1,cwBufferSize);
    
    do {
        DEBUGMSG(ZONE_XMIT, (TEXT("Buffer %x = %d byte.\r\n"),CurBufAddress,CurBufLen));

        while(CurBufLen) {
            DEBUGMSG(ZONE_XMIT, (TEXT("%02x "),*CurBufAddress));
            if (CurHiByte) {
                CurData |= (*CurBufAddress)<<8;
                WriteWord(DATA_1,CurData);
                CurHiByte = FALSE;
            } else {
                CurData = *CurBufAddress;
                CurHiByte = TRUE;
            }
            CurBufAddress++;
            CurBufLen--;
            PacketLength--;
        }
        DEBUGMSG(ZONE_XMIT, (TEXT("\r\n")));

        //
        // Move to the next buffer
        //
        NdisGetNextBuffer(CurBuffer, &CurBuffer);

        if (CurBuffer){
            NdisQueryBuffer(CurBuffer, (PVOID *)&CurBufAddress, &CurBufLen);
        }
        //
        // Get address and length of the next buffer
        //
        while (CurBuffer && (CurBufLen == 0)) {
            NdisGetNextBuffer(CurBuffer, &CurBuffer);
            if (CurBuffer){
                NdisQueryBuffer(CurBuffer, (PVOID *)&CurBufAddress, &CurBufLen);
            }
        }
    } while (CurBuffer);
    
    if (PacketLength !=0 ) {
        DEBUGMSG(ZONE_ERROR,(TEXT("Fatal Error, packet length mismatch!!\r\r")));
    }

    // Write control byte
    if (CurHiByte) {
        CurData = CurData | 0x3000;
        WriteWord(DATA_1,CurData);
    } else {
        WriteWord(DATA_1,0x1000);
    }

    // Enqueue Frame number into TX FIFO
    DEBUGMSG(ZONE_XMIT, (TEXT("Start transmission.\r\n")));
    WriteWord(MMU_CMD, MC_ENQUEUE);

    Adapter->FramesXmitGood++;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("-CELAN:Send\r\n")));
    return(NDIS_STATUS_SUCCESS);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -