halether.c
资源名称:SMDK2440.rar [点击查看]
上传用户:qiulin1960
上传日期:2013-10-16
资源大小:2844k
文件大小:19k
源码类别:
Windows CE
开发平台:
Windows_Unix
- /******************************************************************************
- *
- * System On Chip(SOC)
- *
- * Copyright (c) 2002 Software Center, Samsung Electronics, Inc.
- * All rights reserved.
- *
- * This software is the confidential and proprietary information of Samsung
- * Electronics, Inc("Confidential Information"). You Shall not disclose such
- * Confidential Information and shall use it only in accordance with the terms
- * of the license agreement you entered into Samsung.
- *
- *-----------------------------------------------------------------------------
- *
- * S3C2440 BSP
- *
- * halether.c :
- *
- * Platform specific code for debug ethernet services (debug messages,
- * kernel debugger, text shell (CESH)). These functions are all called
- * from ethdbg.lib. They are non-preemptible, and cannot make any system calls.
- *
- *
- * @author zartoven@samsung.com (SOC, SWC, SAMSUNG Electronics)
- *
- * @date 2002/04/04
- *
- * Log:
- * 2002/04/04 Start(From ODO's BSP)
- *
- ******************************************************************************
- */
- #include <windows.h>
- #include <nkintr.h>
- #include <ethdbg.h>
- #include <halether.h>
- #include <kitl.h>
- #include "s2440.h"
- #include "drv_glob.h"
- #include "oalintr.h"
- #define pDriverGlobals ((PDRIVER_GLOBALS) DRIVER_GLOBALS_PHYSICAL_MEMORY_START)
- BOOL CS8900DBG_Init(BYTE *iobase, DWORD membase, USHORT MacAddr[3]);
- BOOL CS8900DBG_IsReceivedPacket(void);
- UINT16 CS8900DBG_GetFrame(BYTE *pbData, UINT16 *pwLength);
- UINT16 CS8900DBG_SendFrame( BYTE *pbData, DWORD dwLength );
- BOOL CS8900DBG_ReInit(DWORD iobase, DWORD membase);
- BOOL CS8900DBG_MulticastList(PUCHAR pucMulticastAddresses, DWORD dwNumAddresses);
- void CS8900DBG_CurrentPacketFilter(DWORD dwFilter);
- void CS8900DBG_EnableInts(void);
- void CS8900DBG_DisableInts(void);
- DWORD CS8900DBG_GetPendingInts(void);
- PVOID PCMCIA_Init(void);
- //
- // Function pointers to the support library functions of the currently installed debug ethernet controller.
- //
- PFN_EDBG_INIT pfnEDbgInit;
- PFN_EDBG_ENABLE_INTS pfnEDbgEnableInts;
- PFN_EDBG_DISABLE_INTS pfnEDbgDisableInts;
- PFN_EDBG_GET_PENDING_INTS pfnEDbgGetPendingInts;
- PFN_EDBG_GET_FRAME pfnEDbgGetFrame;
- PFN_EDBG_SEND_FRAME pfnEDbgSendFrame;
- PFN_EDBG_READ_EEPROM pfnEDbgReadEEPROM;
- PFN_EDBG_WRITE_EEPROM pfnEDbgWriteEEPROM;
- PFN_EDBG_SET_OPTIONS pfnEDbgSetOptions;
- #ifdef IMGSHAREETH
- PFN_EDBG_CURRENT_PACKET_FILTER pfnCurrentPacketFilter;
- PFN_EDBG_MULTICAST_LIST pfnMulticastList;
- BOOL OEMEthCurrentPacketFilter(PDWORD pdwRequestedFilter);
- // Multicast list - Vmini assumes a maximum of 8 entries.
- //
- #define MAX_MULTICAST_LIST 8
- BOOL ucMultiAddr[MAX_MULTICAST_LIST][6];
- BOOL bNewFilter = FALSE; // User mode --> Kernel mode to set new filter.
- DWORD dwFilter; // The filter..
- BOOL bNewMulticast = FALSE; // User mode --> Kernel mode for new list
- DWORD dwNoOfEntry;
- /* ProcessVMiniSend()
- *
- * This routine drains the pending VMINI TX.
- *
- */
- void ProcessVMiniSend(void)
- {
- PBYTE pVMiniData;
- DWORD dwVMiniDataLength;
- ////////////////////////////////////////////////////////////////////////////
- // Handle the filter if we need to..
- //
- if (bNewFilter && pfnCurrentPacketFilter)
- {
- bNewFilter = FALSE;
- pfnCurrentPacketFilter(dwFilter);
- }
- //
- // Handle new multicast list..
- //
- if (bNewMulticast && pfnMulticastList)
- {
- bNewMulticast = FALSE;
- pfnMulticastList((PUCHAR)ucMultiAddr, dwNoOfEntry);
- }
- ////////////////////////////////////////////////////////////////////////////
- // Consume all the client packets.
- //
- while (VBridgeKGetOneTxBuffer(&pVMiniData, &dwVMiniDataLength) == TRUE)
- {
- pfnEDbgSendFrame (pVMiniData, dwVMiniDataLength);
- VBridgeKGetOneTxBufferComplete(pVMiniData);
- }
- } // ProcessVMiniSend()
- #endif //IMGSHAREETH
- /* OEMEthInit
- *
- * Initialization routine
- *
- * Return Value:
- * Return TRUE if init is successful, FALSE if error.
- */
- BOOL
- OEMEthInit(EDBG_ADAPTER *pAdapter)
- {
- PBYTE pBaseIOAddress;
- // Driver globals from the bootloader.
- //
- if (pDriverGlobals->eth.EbootMagicNum == EBOOT_MAGIC_NUM)
- {
- memcpy(pAdapter, &pDriverGlobals->eth.TargetAddr, sizeof(EDBG_ADAPTER));
- switch(pDriverGlobals->misc.EbootDevice)
- {
- case(DOWNLOAD_DEVICE_PCMCIA): // NE2000 CF card.
- pBaseIOAddress = (PBYTE)PCMCIA_Init();
- if (pBaseIOAddress)
- {
- // Initialize the built-in Ethenet controller.
- //
- if (!NE2000Init((PBYTE)pBaseIOAddress, 1, pAdapter->Addr.wMAC))
- {
- EdbgOutputDebugString("ERROR: OEMEthInit: Failed to initialize Ethernet controller.rn");
- return(FALSE);
- }
- }
- pfnEDbgInit = NE2000Init;
- pfnEDbgEnableInts = NE2000EnableInts;
- pfnEDbgDisableInts = NE2000DisableInts;
- pfnEDbgGetPendingInts = NE2000GetPendingInts;
- pfnEDbgGetFrame = NE2000GetFrame;
- pfnEDbgSendFrame = NE2000SendFrame;
- pfnEDbgReadEEPROM = NE2000ReadEEPROM;
- pfnEDbgWriteEEPROM = NE2000WriteEEPROM;
- pfnEDbgSetOptions = NE2000SetOptions;
- #ifdef IMGSHAREETH
- pfnCurrentPacketFilter = Ne2000CurrentPacketFilter;
- pfnMulticastList = NE2000MulticastList;
- #endif // IMGSHAREETH.
- break;
- case(DOWNLOAD_DEVICE_CS8900): // CS8900A.
- // Initialize the CS8900.
- //
- if (!CS8900DBG_Init((PBYTE)CS8900DBG_IOBASE, CS8900DBG_MEMBASE, pAdapter->Addr.wMAC))
- {
- EdbgOutputDebugString("ERROR: OEMEthInit: CS8900 initialization failed.rn");
- return(FALSE);
- }
- pfnEDbgInit = CS8900DBG_Init;
- pfnEDbgEnableInts = CS8900DBG_EnableInts;
- pfnEDbgDisableInts = CS8900DBG_DisableInts;
- pfnEDbgGetFrame = CS8900DBG_GetFrame;
- pfnEDbgSendFrame = CS8900DBG_SendFrame;
- pfnEDbgGetPendingInts = CS8900DBG_GetPendingInts;
- #ifdef IMGSHAREETH
- pfnCurrentPacketFilter = CS8900DBG_CurrentPacketFilter;
- pfnMulticastList = CS8900DBG_MulticastList;
- #endif // IMGSHAREETH.
- break;
- default:
- EdbgOutputDebugString("ERROR: OEMInit: Unknown download NIC (0x%x).rn", pDriverGlobals->misc.EbootDevice);
- return(FALSE);
- }
- }
- else
- {
- // TODO - retrieve CS8900 MAC address from flash...
- // TODO - intialize the CS8900 from scratch...
- }
- EdbgOutputDebugString("::: OEMEthInit() IP Address : %srn", inet_ntoa(pAdapter->Addr.dwIP));
- EdbgOutputDebugString("::: OEMEthInit() Netmask : %srn", inet_ntoa(pDriverGlobals->eth.SubnetMask));
- // Setup SYSINTR used for KITL NIC.
- //
- if (pDriverGlobals->misc.EbootDevice == DOWNLOAD_DEVICE_PCMCIA)
- pAdapter->SysIntrVal = SYSINTR_PCMCIA_LEVEL;
- else
- pAdapter->SysIntrVal = SYSINTR_ETHER;
- pAdapter->DHCPLeaseTime = DEFAULT_DHCP_LEASE;
- pAdapter->EdbgFlags = pDriverGlobals->eth.EdbgFlags;
- #ifdef IMGSHAREETH
- VBridgeInit();
- VBridgeKSetLocalMacAddress((char *)pAdapter->Addr.wMAC);
- #endif // IMGSHAREETH.
- return(TRUE);
- }
- /* OEMEthEnableInts
- *
- * Turn on HW interrupts.
- */
- void
- OEMEthEnableInts()
- {
- if (pfnEDbgEnableInts)
- {
- pfnEDbgEnableInts();
- }
- }
- /* OEMEthDisableInts
- *
- * Disable HW interrupts.
- */
- void
- OEMEthDisableInts()
- {
- if (pfnEDbgDisableInts)
- {
- pfnEDbgDisableInts();
- }
- }
- /* OEMEthISR
- *
- * ISR routine, called by EDBG IST when Ethernet controller interrupts. Also
- * called in polling mode, to check for received data.
- *
- * Return Value:
- * Return bitmask indicating which interrupts are pending. Currently, the ones
- * that EDBG cares about are the following (others should be handled internally):
- * INTR_TYPE_RX -- Receive interrupt. IST will call into GetFrame to read data.
- */
- DWORD
- OEMEthISR()
- {
- #ifdef IMGSHAREETH
- ProcessVMiniSend();
- #endif // IMGSHAREETH.
- return (pfnEDbgGetPendingInts());
- }
- /* OEMEthGetFrame
- *
- * Check to see if a frame has been received, and if so copy to buffer. An optimization
- * which may be performed in the Ethernet driver is to filter out all received broadcast
- * packets except for ARPs. This is done in the SMC9000 driver.
- *
- * Return Value:
- * Return TRUE if frame has been received, FALSE if not.
- */
- BOOL
- OEMEthGetFrame(
- BYTE *pData, // OUT - Receives frame data
- UINT16 *pwLength) // IN - Length of Rx buffer
- // OUT - Number of bytes received
- {
- #ifdef IMGSHAREETH
- BOOL bStatus;
- BOOL bTaken;
- UINT16 wOriginalLength = *pwLength;
- ProcessVMiniSend();
- while (1)
- {
- *pwLength = wOriginalLength;
- bStatus = pfnEDbgGetFrame(pData, pwLength);
- if (bStatus)
- {
- ////////////////////////////////////////////////////////////////////
- VBridgeKIndicateOneRxBuffer(pData, *pwLength, FALSE, &bTaken);
- if (!bTaken)
- return bStatus;
- }
- else
- break;
- }
- return (FALSE);
- #else
- return pfnEDbgGetFrame(pData, pwLength);
- #endif // IMGSHAREETH.
- }
- /* OEMEthSendFrame
- *
- * Send Ethernet frame.
- *
- * Return Value:
- * TRUE if frame successfully sent, FALSE otherwise.
- */
- BOOL
- OEMEthSendFrame(
- BYTE *pData, // IN - Data buffer
- DWORD dwLength) // IN - Length of buffer
- {
- int retries = 0;
- while (retries++ < 4) {
- if (!pfnEDbgSendFrame(pData, dwLength))
- {
- #ifdef IMGSHAREETH
- ProcessVMiniSend();
- #endif //IMGSHAREETH
- return TRUE;
- }
- else
- EdbgOutputDebugString("!OEMEthSendFrame failure, retry %un",retries);
- }
- return FALSE;
- }
- /* OEMEthQueryClientInfo
- *
- * Return address information for default ethernet services, plus a buffer pool to use
- * for formatting and receiving EDBG packets (single buffer pool specified, divided in
- * two for Rx and Tx buffers). By specifying a smaller window size, less memory can be
- * used (but the protocol will be less efficient...). The amount of memory required per
- * client is (2*WindowSize*1500) bytes.
- *
- * For Odo, we reserve 3 buffer pools worth of memory in the bib file, based on the IMGEBOOT
- * flag being set.
- *
- * Return Value:
- * If client can be configured, return TRUE and fill in addressing and buffer info. Otherwise
- * return FALSE. For Odo, configure clients based on the flags set by Eshell (received in the
- * JUMPIMG command by eboot, and placed in the uninitalized driver globals section).
- */
- /* OEMEthQueryClientInfo
- *
- * Return address information for default ethernet services, plus a buffer pool to use
- * for formatting and receiving EDBG packets (single buffer pool specified, divided in
- * two for Rx and Tx buffers). By specifying a smaller window size, less memory can be
- * used (but the protocol will be less efficient...). The amount of memory required per
- * client is (2*WindowSize*1500) bytes.
- *
- * For Odo, we reserve 3 buffer pools worth of memory in the bib file, based on the IMGEBOOT
- * flag being set.
- *
- * Return Value:
- * If client can be configured, return TRUE and fill in addressing and buffer info. Otherwise
- * return FALSE. For Odo, configure clients based on the flags set by Eshell (received in the
- * JUMPIMG command by eboot, and placed in the uninitalized driver globals section).
- */
- BOOL
- OEMEthQueryClientInfo(
- UCHAR Service, // IN - Service ID (one of EDBG_SVC defs from ethdbg.h).
- EDBG_ADDR *pPeerAddr, // OUT -Filled in with the peer Ether/IP address and UDP port number.
- PUCHAR pWindowSize, // OUT -Filled in with the client window size.
- PUCHAR *ppBufferPool) // OUT -Filled in with the packet buffer pool address.
- {
- // We use the default window size (8) for all services
- *pWindowSize = EDBG_WINDOW_SIZE;
- switch (Service)
- {
- // Check the flag in driver globals (set by eboot when it receives the JUMPIMG command)
- case EDBG_SVC_DBGMSG:
- if (! (pDriverGlobals->eth.etherFlags & EDBG_FL_DBGMSG)) {
- EdbgOutputDebugString("FAIL : EDBG_SVC_DBGMSG n");
- return FALSE;
- }
- memcpy(pPeerAddr, &pDriverGlobals->eth.DbgHostAddr,sizeof(EDBG_ADDR));
- *ppBufferPool = (UCHAR *)EDBG_PHYSICAL_MEMORY_START;
- EdbgOutputDebugString("Querying to ethernet for debug messages, host: %s, port: %d rnn",
- inet_ntoa(pDriverGlobals->eth.DbgHostAddr.dwIP),
- ntohs(pDriverGlobals->eth.DbgHostAddr.wPort));
- break;
- case EDBG_SVC_PPSH:
- if (! (pDriverGlobals->eth.etherFlags & EDBG_FL_PPSH)) {
- EdbgOutputDebugString("FAIL : EDBG_SVC_PPSH n");
- return FALSE;
- }
- memcpy(pPeerAddr, &pDriverGlobals->eth.PpshHostAddr,sizeof(EDBG_ADDR));
- *ppBufferPool = (UCHAR *)EDBG_PHYSICAL_MEMORY_START + EDBG_DFLT_BUFFER_POOL_SIZE;
- EdbgOutputDebugString("Querying ethernet for PPSH, host: %s, port: %d rnn",
- inet_ntoa(pDriverGlobals->eth.PpshHostAddr.dwIP),
- ntohs(pDriverGlobals->eth.PpshHostAddr.wPort));
- break;
- case EDBG_SVC_KDBG:
- if (! (pDriverGlobals->eth.etherFlags & EDBG_FL_KDBG)) {
- EdbgOutputDebugString("FAIL : EDBG_SVC_KDBG n");
- return FALSE;
- }
- memcpy(pPeerAddr, &pDriverGlobals->eth.KdbgHostAddr,sizeof(EDBG_ADDR));
- *ppBufferPool = (UCHAR *)EDBG_PHYSICAL_MEMORY_START + 2*EDBG_DFLT_BUFFER_POOL_SIZE;
- EdbgOutputDebugString("Querying ethernet for KDBG, host: %s, port: %d rnn",
- inet_ntoa(pDriverGlobals->eth.KdbgHostAddr.dwIP),
- ntohs(pDriverGlobals->eth.KdbgHostAddr.wPort));
- break;
- default:
- return FALSE;
- }
- return TRUE;
- }
- /* OEMEthGetSecs
- *
- * Return a count of seconds from some arbitrary time (the absolute value is not important,
- * so long as it increments appropriately).
- */
- DWORD
- OEMEthGetSecs( void )
- {
- SYSTEMTIME st;
- DWORD ti;
- OEMGetRealTime( &st );
- ti = ((60UL * (60UL * (24UL * (31UL * st.wMonth + st.wDay) + st.wHour) + st.wMinute)) + st.wSecond);
- return ti;
- }
- #ifdef IMGSHAREETH
- //
- // These functions are only needed if vmini is in.
- // i.e. if IMGSHAREETH is set.
- //
- ////////////////////////////////////////////////////////////////////////////////
- // OEMEthSetFilter()
- //
- // Description:
- //
- // This function is used by VMINI to inform the underlying ethernet
- // library on the filtering mode it requires.
- //
- // Arguments:
- //
- // pdwRequestedFilter :: The requested filter.
- // Identical constants have been added in
- // that mimics NDIS_PACKET_TYPE_XXX constants.
- //
- // Return Value:
- //
- // TRUE :: if we can set the filter.
- // FALSE :: otherwise..
- //
- //
- // Note:
- //
- // As a minimum to get vmini to work, we need to support
- // PACKET_TYPE_DIRECTED
- // PACKET_TYPE_BROADCAST
- //
- //
- BOOL
- OEMEthCurrentPacketFilter(PDWORD pdwRequestedFilter)
- {
- //EdbgOutputDebugString(
- //"OEMEthCurrentPacketFilter set to [0x%x]rn",
- //*pdwRequestedFilter);
- //
- // Note that we can't do it immediately here, since we are called
- // by user mode code.
- // So what we do is to set the flag here for the kernel mode code
- // to pick up.
- //
- dwFilter = *pdwRequestedFilter;
- bNewFilter = TRUE;
- return TRUE;
- } // OEMEthCurrentPacketFilter()
- ////////////////////////////////////////////////////////////////////////////////
- // OEMEthMulticastList()
- //
- // Description:
- //
- // This function is used by VMINI to inform the underlying ethernet
- // library on multicast addresses that winsock app is interested in.
- //
- // Arguments:
- //
- // pucMulticastAddressList :: Pointer to an array of multicast addresses.
- // dwNoOfAddresses :: Number of addresses passed in to us.
- //
- // Return Value:
- //
- // TRUE :: if we can set the underlying edbg ethernet libary to start
- // filtering on these multicast addresses.
- //
- // FALSE :: otherwise.
- //
- BOOL
- OEMEthMulticastList(PUCHAR pucMulticastAddressList, DWORD dwNoOfAddresses)
- {
- //
- // This platform does not support multicast yet..
- //
- DWORD i;
- BOOL bReturnValue;
- EdbgOutputDebugString(
- "OEMEthMulticastList():: No of Entries [%d]rn",
- dwNoOfAddresses);
- //
- // We can check how many entries an adapter that are attached to
- // can support.
- // To make things simple, we just assume we can support minimum that
- // vmini thinks we support (i.e. 8).
- //
- if (dwNoOfAddresses > 8)
- {
- //
- // This should never happen, since VMINI is known to support
- // 8 entries only...
- //
- EdbgOutputDebugString(
- "Multicast list requeste [%d] > 8 !!!rn",
- dwNoOfAddresses);
- return FALSE;
- }
- //
- // 8 entries, 6 bytes each..
- //
- memset(
- ucMultiAddr,
- 0x00,
- 8 * 6);
- //
- // 6 bytes per entry..
- //
- memcpy(
- ucMultiAddr,
- pucMulticastAddressList,
- dwNoOfAddresses * 6);
- for (i = 0 ; i < dwNoOfAddresses ; i++)
- {
- EdbgOutputDebugString(
- "[%d] : %x - %x - %x - %x - %x - %xrn",
- i,
- pucMulticastAddressList[6*i+0],
- pucMulticastAddressList[6*i+1],
- pucMulticastAddressList[6*i+2],
- pucMulticastAddressList[6*i+3],
- pucMulticastAddressList[6*i+4],
- pucMulticastAddressList[6*i+5]);
- }
- //
- // We are in KernelIOCTL call, some h/w requires the
- // setting of the MULTICAST addresses in interrupt service routine.
- // So we will do it later, and mark it so the ISR will know about it..
- // Note:
- // Order is important here. Don't set bNewMulticast to true until
- // all the entries and the dwNoOfEntry are properly set up.
- // This is because we can be switched out in the middle of
- /// KernelIOCTL!!
- //
- dwNoOfEntry = dwNoOfAddresses;
- bNewMulticast = TRUE;
- bReturnValue = TRUE;
- EdbgOutputDebugString(
- "OEMEthMulticastList returning [%d]rn",
- bReturnValue);
- return bReturnValue;
- } // OEMEthMulticastList()
- #endif