📄 ixethaccsysend.c
字号:
/* ixEthAccSysEnd.c - Intel IXDP425 ixEth Init Module *//* Copyright 2002 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01m,04apr03,m_h Major revision supports CSR 1.2.1 (mostly MII, polled mode)01k,07oct02,jb Fix numbering01j,07oct02,jb Fix naming01i,07oct02,jb fix IP address01h,23sep02,jb Adding default IP addresses from config.h01g,05sep02,jb Changes to support Gold release of Intel Lib01f,19aug02,jb Fix double inclusion01e,01aug02,jb Continued developement01d,31jul02,jb Fixing name errors01c,17jul02,jb Renamed file, renaming bsp specific routines to segregate Intel library01b,10jun02,jb Modifying to integrate ixEth01a,27may02,jb Initial version from Intel*//*DESCRIPTIONThis file contains the board-specific routines for Ethernet adapterinitialisation of Intel ixEthAcc devices.*/#include <stddef.h>#include <stdio.h>#include <stdlib.h>#include <assert.h>#include "vxWorks.h"#include "sysLib.h"#include "ctype.h"#include "end.h" /* Common END structures. */#include "endLib.h"#include "inetLib.h"#undef ETHER_MAP_IP_MULTICAST#include "etherMultiLib.h" /* multicast stuff. */#include "ipProto.h" /* IP prototypes */#include "logLib.h"#include "net/mbuf.h"#include "net/unixLib.h"#include "net/protosw.h"#include "net/systm.h"#include "net/if_subr.h"#include "net/route.h"#include <inetLib.h>#include <ipProto.h>#include <netinet/in.h>#include <netinet/ip.h>#include <netinet/if_ether.h>#include "sys/socket.h"#include "sys/ioctl.h"#include "sys/times.h"#undef FORCE_CODELETS#include "IxTypes.h"#include "IxEthAcc.h"#include "IxQMgr.h"#include "IxNpeDl.h"#include "IxNpeMh.h"#ifndef FORCE_CODELETS #include "IxNpeMicrocode.h"#endif /* FORCE_CODELETS */#include "IxOsServices.h"#include "IxEthAcc.h"#include "ixp425.h" /* Chip level definitions required */#include "config.h"#ifdef INCLUDE_IXETHACCEND/* DEBUG MACROS */#undef SYS_END_DEBUG#ifdef SYS_END_DEBUG #define DRV_LOG printf#else #define DRV_LOG#endif /* SYS_END_DEBUG */#ifndef END_LD_STR_SIZE#define END_LD_STR_SIZE 80#endif/** * @def NPE_B_BUILD * @brief NPE B build to load for the required features * * 1 means Ethernet and Fast Path */#define NPE_B_BUILD 1/** * @def NPE_C_BUILD * @brief NPE C build to load for the required features * * 0 means Ethernet */#define NPE_C_BUILD 0/**< Location of NPE image to download */#define IX_ETHACC_CODELET_NPE_IMG IX_NPEDL_MicrocodeImage #ifdef FORCE_CODELETSIMPORT unsigned IX_NPEDL_MicrocodeImage[];#endif#define NUM_ELEM(vector) (sizeof (vector) / sizeof ((vector)[0]))/* Imports from Monsoon */struct { int number; const char *string; } ixIpProtoValues[] = { {IPPROTO_IP, "IP"}, {IPPROTO_TCP, "TCP"}, {IPPROTO_UDP, "UDP"}, {IPPROTO_ICMP, "ICMP"}, {IPPROTO_IGMP, "IGMP"} };/* These are to simplify includes */#define IX_ETH_ACC_MII_STAT_REG 0x1 /* Status Register */#define IX_ETH_ACC_MII_STAT2_REG 0x11 /* Status Register 2*/#define IX_ETH_ACC_MII_SR_AUTO_NEG 0x0020 /* auto negotiation complete */#define IX_ETH_ACC_MII_SR2_FD 0x0200IMPORT END_OBJ* ixEthAccEndLoad (char *, void *);IMPORT END_TBL_ENTRY endDevTbl[];IMPORT unsigned char sysMacBase[];/* unsigned char sysIxEthAccEndEnetAddr[6] = { 0x00, 0x02,0xb3,0x3c,0x16,0x95}; */unsigned char sysIxEthAccEndEnetAddr[6] = { 0x00, 0xe0,0x8e,0x3c,0x16,0x95};#if defined(IXDP_ETHACC_IP0_DEFAULT) && defined(IXDP_ETHACC_IP1_DEFAULT)LOCAL char *sysIxEthAccEndIpAddr[IX_ETH_ACC_NUMBER_OF_PORTS] = { IXDP_ETHACC_IP0_DEFAULT, IXDP_ETHACC_IP1_DEFAULT };#endifLOCAL char ixpEndLoadStr[IX_ETH_ACC_NUMBER_OF_PORTS][END_LD_STR_SIZE] = { { "0:"}, { "0:"}, };typedef struct _IXDP_ETHACC_PHY_CONF { BOOL speed100; /**< 100 Mbits */ BOOL fullDuplex; /**< Full Duplex */ BOOL autonegotiate; /**< Autonegotiation */ } IXDP_ETHACC_PHY_CONF;PRIVATE IXDP_ETHACC_PHY_CONF ixdp425phyConf[IX_ETH_ACC_NUMBER_OF_PORTS] = { /* * Ethernet 0 */ {TRUE, /* 100 Mbits */ TRUE, /* Full duplex */ TRUE}, /* Auto Negotiate */ /* * Ethernet 1 */ {TRUE, /* 100 Mbits */ TRUE, /* Full duplex */ TRUE} /* Auto Negotiate */};#ifdef IXDP_ETHACC_USE_NVRAM_MAC static UCHAR ixdp425IntelMacPrefix[6] = { 0x00, 0x02, 0xB3, 0x00, 0x00, 0x00, }; static UINT32 nvRamNpeMacAddr[IX_ETH_ACC_NUMBER_OF_PORTS] = { NV_MAC_ADRS_NPE1, NV_MAC_ADRS_NPE2, };#endif /* IXDP_ETHACC_USE_NVRAM_MAC */void ixEthAccEndEthernetLinkStatusMonitor(void);void ixEthernetHdrDump(const char * const mData);void ixIpHdrDump(const char * const mData);IxEthAccStatus ixEthAccMiiReadRtn (UINT8, UINT8, UINT16 *);extern void sysMicroDelay(int microseconds);BOOL ixdp425EthLibInitialised = FALSE;VUINT32 ixEthAccPhyAddresses[IX_ETH_ACC_NUMBER_OF_PORTS];PRIVATE BOOL phyPresent[IXP425_ETH_ACC_MII_MAX_ADDR];PRIVATE char ixnpeMaddrStr[IX_ETH_ACC_NUMBER_OF_PORTS][64];PRIVATE BOOL ixdp425EthAccNPEStarted[IX_ETH_ACC_NUMBER_OF_PORTS];PRIVATE IxQMgrDispatcherFuncPtr dispatcherFunc = 0; #ifdef FORCE_CODELETS/* Do Not call this routine - It is used to force code inclusion */PRIVATE void ixdp425ForceCodlets() { ixEthAccCodeletInit(); }#endif /* FORCE_CODELETS */PRIVATE IX_STATUS ixdp425EthAccPhyDetect(void) { UINT32 phyNo; UINT32 phyNoAddr; for (phyNo=0; phyNo<IX_ETH_ACC_NUMBER_OF_PORTS; phyNo++) { ixEthAccPhyAddresses[phyNo] = 0xffffffff; } if (ixEthAccMiiPhyScan(phyPresent) == ERROR) { return(IX_FAIL); } else { for (phyNoAddr=0, phyNo=0; phyNoAddr<IXP425_ETH_ACC_MII_MAX_ADDR; phyNoAddr++) { if (phyPresent[phyNoAddr] == TRUE) { ixEthAccPhyAddresses[phyNo] = phyNoAddr; if (++phyNo >= IX_ETH_ACC_NUMBER_OF_PORTS) break; } } } ixEthAccPhyAddresses[0] = 0x0d; ixEthAccPhyAddresses[1] = 0x0; /* Reset each phy */ for (phyNo=0; phyNo<IX_ETH_ACC_NUMBER_OF_PORTS; phyNo++) { if (ixEthAccPhyAddresses[phyNo] == 0xffffffff) continue; /* reset the phys */ ixEthAccMiiPhyReset(ixEthAccPhyAddresses[phyNo]); /* update the phy configuration */ ixEthAccMiiPhyConfig(ixEthAccPhyAddresses[phyNo], ixdp425phyConf[phyNo].speed100, ixdp425phyConf[phyNo].fullDuplex, ixdp425phyConf[phyNo].autonegotiate); } return IX_SUCCESS; }PRIVATE IX_STATUS ixdp425EthAccPhyConfig(int port) { UINT32 phyNo; /* Set the phy properties */ for (phyNo=0; phyNo<IX_ETH_ACC_NUMBER_OF_PORTS; phyNo++) { if (phyNo != port || ixEthAccPhyAddresses[phyNo] == 0xffffffff) continue; /* update the current configuration */ ixEthAccMiiPhyConfig(ixEthAccPhyAddresses[phyNo], ixdp425phyConf[phyNo].speed100, ixdp425phyConf[phyNo].fullDuplex, ixdp425phyConf[phyNo].autonegotiate); } return IX_SUCCESS; }PRIVATE IX_STATUS ixdp425EthAccPhyInit(int port) { UINT32 phyNo; UINT16 regval; UINT32 timeout; static BOOL ethStateMonitorTaskSpawnPassed = FALSE; /* Set the phy properties */ for (phyNo=0; phyNo<IX_ETH_ACC_NUMBER_OF_PORTS; phyNo++) { if (phyNo != port || ixEthAccPhyAddresses[phyNo] == 0xffffffff) continue; if (ixdp425phyConf[phyNo].autonegotiate) { /* We need to delay here until Autonegotiate is complete */ for ( timeout = 10; timeout; timeout-- ) { /* A short delay */ sysMicroDelay(500); /* Must do this read twice */ ixEthAccMiiReadRtn(ixEthAccPhyAddresses[phyNo], IX_ETH_ACC_MII_STAT_REG, ®val); ixEthAccMiiReadRtn(ixEthAccPhyAddresses[phyNo], IX_ETH_ACC_MII_STAT_REG, ®val); if ((regval & IX_ETH_ACC_MII_SR_AUTO_NEG) != 0) break; } /* If connect failed, then report it */ if ( (regval & IX_ETH_ACC_MII_SR_AUTO_NEG) == 0 ) { printf("\nixe ETH PHY %d Autonegotiate failed: Disabling\n" , ixEthAccPhyAddresses[phyNo]); /* printf("\nixe ETH port %d Autonegotiate failed: Disabling\n" , phyNo); */#if 0/* allow autonegotiate for later */ ixEthAccPhyAddresses[phyNo] = 0xffffffff;#endif } } } /* * Start up the Ethernet Link monitoring task - This will poll * the link status and update the duplex mode accordingly. */ if (!ethStateMonitorTaskSpawnPassed) { if (ERROR == taskSpawn("ethState", /* Name */ 200, /* Priority */ 0, /* Options */ 1024 * 2, /* Stack Size */ (FUNCPTR)(ixEthAccEndEthernetLinkStatusMonitor), 0,0,0,0,0,0,0,0,0,0) ) { printf("%s: Warning - Ethernet State monitoring task failed\n" "to start. No MAC mode updates can be made.\n", "ixdp425EthAccPhyInit"); ethStateMonitorTaskSpawnPassed = FALSE; } else { /* * Prevent this task being spawned again */ ethStateMonitorTaskSpawnPassed = TRUE; } } /* Set the MAC to the same duplex mode as the phy */ for (phyNo=0; phyNo<IX_ETH_ACC_NUMBER_OF_PORTS; phyNo++) { if (phyNo != port || ixEthAccPhyAddresses[phyNo] == 0xffffffff) continue; /* * If Ethernet is auto negotiating then we don't need to set the duplex * mode now - the link monitoring task will take care of this. * Unless of course the link monitoring task failed to start... */ if (!ixdp425phyConf[phyNo].autonegotiate || !ethStateMonitorTaskSpawnPassed) { if (ixdp425phyConf[phyNo].fullDuplex) { ixEthAccPortDuplexModeSet (ixEthAccPhyAddresses[phyNo], IX_ETH_ACC_FULL_DUPLEX); } else { ixEthAccPortDuplexModeSet (ixEthAccPhyAddresses[phyNo], IX_ETH_ACC_HALF_DUPLEX); } } /* Do a read status to add a delay. Must do this read twice */ ixEthAccMiiReadRtn(ixEthAccPhyAddresses[phyNo], IX_ETH_ACC_MII_STAT_REG, ®val); ixEthAccMiiReadRtn(ixEthAccPhyAddresses[phyNo], IX_ETH_ACC_MII_STAT_REG, ®val);#ifdef SYS_END_DEBUG printf("\nixe ETH PHY %d configuration:\n" , ixEthAccPhyAddresses[phyNo] ); ixEthAccMiiShow(ixEthAccPhyAddresses[phyNo]);#endif /* SYS_END_DEBUG */ } return(IX_SUCCESS); }/** * @fn IX_STATUS ixdp425EthAccNpeInit(IxNpeDlNpeId npeId) * * @param npeId - ID of ixe to initialise * * Download microcode to the IXE. This function always downloads the latest * version of NPE microcode available. * * @return IX_SUCCESS - NPE successfuly initialised * @return IX_FAIL - Error initialising NPE */PRIVATE IX_STATUS ixdp425EthAccNpeInit(IxNpeDlNpeId npeId) { UINT32 numVersions = 0; IxNpeDlVersionId versionIdList[IX_NPE_MICROCODE_AVAILABLE_VERSIONS_COUNT]; IxNpeDlVersionId downloadVersionId; IxNpeDlVersionId uploadVersionId; UINT32 listSize = 0; IX_STATUS status; int i; downloadVersionId.npeId = npeId; if (npeId == IX_NPEDL_NPEID_NPEB) { downloadVersionId.buildId = NPE_B_BUILD; } else { downloadVersionId.buildId = NPE_C_BUILD; } downloadVersionId.major = 0x0; downloadVersionId.minor = 0x0; /* get the version count - there should be at most maxVersions */ status = ixNpeDlAvailableVersionsCountGet (&numVersions); if (status != IX_SUCCESS) { ixOsServLog (LOG_ERROR, "Failed to get version count\n", 0, 0, 0, 0, 0, 0); return IX_FAIL; } else if (numVersions > IX_NPE_MICROCODE_AVAILABLE_VERSIONS_COUNT) { ixOsServLog (LOG_ERROR, "Version count is not equal to %d\n", numVersions, 0, 0, 0, 0, 0); return IX_FAIL; } listSize = numVersions; /* get the list of available versions */ status = ixNpeDlAvailableVersionsListGet (versionIdList, &listSize); if (status != IX_SUCCESS) { ixOsServLog (LOG_ERROR, "Failed to get version list\n", 0, 0, 0, 0, 0, 0); return IX_FAIL; } assert(numVersions == listSize); /* Get the latest version of NPE code for this feature */ for (i = 0; i < listSize; i++) { if (versionIdList[i].npeId == npeId) { if (versionIdList[i].buildId == downloadVersionId.buildId) { if (versionIdList[i].major > downloadVersionId.major) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -