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

📄 smc.c

📁 该BSP是基于PXA270+WINCE的BSP
💻 C
字号:
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright (c) 1995-2000 Microsoft Corporation.  All rights reserved.

Module Name:  

Abstract:  
    Routines for the SMC9000 ethernet controller used for the Windows CE
    debug ethernet services, and bootloaders.

Functions:


Notes: 
    These routines are called at system init and other times when system calls aren't allowed, so
    they can't make any system calls.
    
--*/


// Note : The Odo SMC implementation sometimes encounters read errors if we
// optimize this routine.  So for now I'm just going to turn of all 
// optimizations.
#pragma optimize("", off)

#include <windows.h>
#include <ethdbg.h>
#include <halether.h>
#include "bvd1.h"
#include "bvd1bd.h"
#include "drv_glob.h"
#include "udp.h"
#include "xllp_ethernet.h"

DWORD dwConfigOptions;

BOOL SMCInit( BYTE *pbBaseAddress, DWORD dwMultiplier, USHORT MacAddr[3])
{
	XllpEthernetSWInit((void *)pbBaseAddress);
	return XllpEthernetHWSetup((P_XLLP_UINT16_T) MacAddr, TRUE, TRUE, XLLP_ETHERNET_LOOPBACK_DISABLE);
}

void SMCEnableInts()
{
	XllpEthernetEnableRxInterrupt();
}

void SMCDisableInts()
{
	XllpEthernetDisableRxInterrupt();
}

DWORD SMCGetPendingInterrupts()
{
	return 0;
}

UINT16 SMCGetFrame( BYTE *pbData, UINT16 *pwLength )
{
	*pwLength = 0;
	XllpEthernetReceivePacket((P_XLLP_UINT32_T)pbData, (P_XLLP_INT32_T)pwLength);
	if (*pwLength > 0)
		return 1;
	return 0;

}

UINT16 SMCSendFrame( BYTE *pbData, DWORD dwLength )
{
    return (UINT16)(XllpEthernetTransmitPacket((P_XLLP_UINT16_T) pbData, (XLLP_UINT32_T) dwLength));
}

BOOL SMCReadEEPROM( UINT16 EEPROMAddress , UINT16 *pwVal)
{
	return FALSE;
}

BOOL SMCWriteEEPROM( UINT16 EEPROMAddress, UINT16 Data )
{
	return FALSE;
}

DWORD SMCSetOptions(DWORD dwOptions)
{
    DWORD dwOldOptions = dwConfigOptions;
    dwConfigOptions = dwOptions;
	EdbgOutputDebugString("SMCSetOptions()\n");
    return dwOldOptions;

}

void SMCCurrentPacketFilter(DWORD dwFilter)
{
	EdbgOutputDebugString("SMCCurrentPacketFilter()\n");
}

BOOL SMCMulticastList(PUCHAR pucMulticastAddresses, DWORD dwNoOfAddresses)
{
	EdbgOutputDebugString("SMCMulticastList()\n");
	XllpEthernetSetMulticastList ((P_XLLP_UINT8_T) pucMulticastAddresses, (XLLP_UINT32_T) dwNoOfAddresses);
	return TRUE;
}




#if 0
#if (WINCEOSVER >= 400)
////////////////////////////////////////////////////////////////////////////////
//	SMCComputeCrc()
//	
//	Description:
//
//		Runs the AUTODIN II CRC algorithm on buffer Buffer of length Length.
//
//	Arguments:
//
//		Buffer - the input buffer
//		Length - the length of Buffer
//
//	Return value:
//
//		The 32-bit CRC value.
//
//	Note:
//
//		This function is adopted from netcard\ne2000 miniport driver.
//		
ULONG
SMCComputeCrc(
             IN PUCHAR Buffer,
             IN UINT Length)
{
    ULONG Crc, Carry;
    UINT i, j;
    UCHAR CurByte;

    Crc = 0xffffffff;

    for(i = 0; i < Length; i++)
    {
        CurByte = Buffer[i];

        for(j = 0; j < 8; j++)
        {
            Carry = ((Crc & 0x80000000) ? 1 : 0) ^ (CurByte & 0x01);
            Crc <<= 1;
            CurByte >>= 1;

            if(Carry)
            {
                Crc = (Crc ^ 0x04c11db6) | Carry;
            }
        }
    }

    return Crc;

}   //	SMCComputeCrc()


////////////////////////////////////////////////////////////////////////////////
//	SMCMulticastList()
//	
//	Description:
//
//		This function is used to insert multicast addresses to the h/w.
//
//	Arguments:
//
//		pucMulticastAddresses	:: The list of multicast addressses.
//		dwNoOfAddresses			:: The number of addresses in the list.
//
//	Return value:
//
//		TRUE if successful, FALSE otherwise.
//

BOOL
SMCMulticastList(PUCHAR pucMulticastAddresses, DWORD dwNoOfAddresses)
{
    UCHAR   NicMulticastRegs[8];        // contents of card multicast registers
    UINT    i;
    DWORD   dwCRC;

    EdbgOutputDebugString(
                         "SMC91C94:: SMCMulticastList() set [%d] multicast list addrs.\r\n",
                         dwNoOfAddresses);

    for(i = 0 ; i < dwNoOfAddresses ; i++)
    {
        EdbgOutputDebugString(
                             "SMC9000:: Multicast[%d]  = %x-%x-%x-%x-%x-%x\r\n",
                             i,
                             pucMulticastAddresses[6*i + 0],
                             pucMulticastAddresses[6*i + 1],
                             pucMulticastAddresses[6*i + 2],
                             pucMulticastAddresses[6*i + 3],
                             pucMulticastAddresses[6*i + 4],
                             pucMulticastAddresses[6*i + 5]);
    }

    //
    //	First turn all bits off.
    //

    memset (NicMulticastRegs, 0x00, sizeof(NicMulticastRegs));

    //
    // Now turn on the bit for each address in the multicast list.
    //

    for(i = 0 ; i < dwNoOfAddresses ; i++)
    {
        dwCRC = SMCComputeCrc(
                             &pucMulticastAddresses[6*i],
                             6);


        //
        //	Here is what the spec says:
        //	The hash value is defined as the six MSB of the CRC of the
        //	destination addr.
        //	The three MSB determine the register to be used (MT0..MT7)
        //	The other three determine the bit within the register.
        //

        NicMulticastRegs[dwCRC >> 29] |= (1 << ((dwCRC >> 26) & 0x07));
    }

    EdbgOutputDebugString(
                         "SMC9000:: MulticastRegs = %x-%x-%x-%x-%x-%x-%x-%x\r\n",        
                         NicMulticastRegs[0],
                         NicMulticastRegs[1],
                         NicMulticastRegs[2],
                         NicMulticastRegs[3],
                         NicMulticastRegs[4],
                         NicMulticastRegs[5],
                         NicMulticastRegs[6],
                         NicMulticastRegs[7]);

    //
    //	Finally, burn that in the h/w..
    //

    WriteWord (BANKSEL_REG, BANK3);

    WriteWord (MULTITAB_REG0, NicMulticastRegs[0]);
    WriteWord (MULTITAB_REG1, NicMulticastRegs[2]);
    WriteWord (MULTITAB_REG2, NicMulticastRegs[4]);
    WriteWord (MULTITAB_REG3, NicMulticastRegs[6]); 

    return TRUE;

}   //	SMCMulticastList()



////////////////////////////////////////////////////////////////////////////////
//	SMCCurrentPacketFilter()
//	
//	Description:
//
//		This function is called to set the h/w filter.
//		We support:
//			PROMISCUOUS, ALL MULTICAST, BROADCAST, DIRECTED.
//
//	Arguments:
//
//		dwFilter::	The filter mode 
//
//	Return value:
//
//		TRUE if successful, FALSE otherwise.
//
void
SMCCurrentPacketFilter(DWORD    dwFilter)
{
    //
    //	EDBG always receive directed and broadcast as a minimum.
    //	So our default will be RCR_REG_INIT..
    //

    WORD    wRxControlReg = RCR_REG_INIT;

    if(dwFilter & PACKET_TYPE_ALL_MULTICAST)
        wRxControlReg |= 0x04;

    if(dwFilter & PACKET_TYPE_PROMISCUOUS)
        wRxControlReg |= 0x02;


    //
    //	I think Broadcast is always received for smc9000, so we don't
    //	need to do anything to this flag..
    //    

    EdbgOutputDebugString("SMC9000:: Set filter to : [0x%x]\r\n",
                          wRxControlReg);

    WriteWord (BANKSEL_REG, BANK0);
    WriteWord (RCR_REG, wRxControlReg);

}   //	SMCCurrentPacketFilter()

#endif //WINCEOSVER >= 400
#endif


⌨️ 快捷键说明

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