📄 sysmotfcc2end.c
字号:
/* sysMotFcc2End.c - system configuration module for motFccEnd driver *//* Copyright 1984-2003 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01f,03may06,dtr SPR#120513 - check enet address.01e,02sep05,dtr Fix phy interrupt handling.01d,04apr05,dtr Support SNOOP in system.01c,24mar05,dtr SPR 105404 - Davicom phy fixes01b,04oct04,dtr SPR 99953.01a,18dec03,dtr created from ads85xx.*//*DESCRIPTIONThis is the WRS-supplied configuration module for the VxWorksm8260FccEnd END driver.It performs the dynamic parameterization of the motFccEnd driver.This technique of 'just-in-time' parameterization allows driverparameter values to be declared as any other defined constants ratherthan as static strings.*/#include "vxWorks.h"#include "config.h"#include "sysNet.h"#include "vmLib.h"#include "stdio.h"#include "sysLib.h"#include "logLib.h"#include "stdlib.h"#include "string.h"#include "end.h"#include "intLib.h"#include "lstLib.h"#include "drv/mem/m82xxDpramLib.h"#include "miiLib.h"#include "drv/end/motFcc2End.h"/* defines */#ifdef INCLUDE_MOTFCCEND#define MOT_FCC_BASE_NUM 0x01 /* First FCC to be used */#define MOT_FCC_TBD_NUM 0x40 /* transmit buffer descriptors (TBD)*/#define MOT_FCC_RBD_NUM 0x20 /* receive buffer descriptors (RBD)*/#define MOT_FCC_DEF_PHY_MODE 0x2 /* PHY's default operating mode */#define MOT_FCC_BDS_SIZE (2 * 1024)#define MOT_FCC_MBLK_RBD_RATIO 0x03 /* Driver allocates (3* MOT_FCC_RBD_NUM) mBlk's */#define MOT_FCC_CLUS_RBD_RATIO 0x04 /* Driver allocates (4* MOT_FCC_RBD_NUM) Clusters*//* imports */IMPORT END_OBJ * motFcc2EndLoad (char *);IMPORT UINT32 sysPCGet (void);FUNCPTR _func_m82xxDpramFree;FUNCPTR _func_m82xxDpramFccMalloc;FUNCPTR _func_m82xxDpramFccFree;IMPORT STATUS miiPhyInit (PHY_INFO * phyInfo);/* globals */UINT32 miiNumLinkChgInts = 0;UINT32 miiBitRdCount = 0;UINT32 miiBitWrCount = 0;/* locals */UINT32 fccPhyAdrs[] = { 0x0 /* FCC1 */, 0x3 /* FCC2 */};PHY_INFO * pPhyInfo1 = NULL;PHY_INFO * pPhyInfo2 = NULL;/* * this table may be customized by the user to force a * particular order how different technology abilities may be * negotiated by the PHY. Entries in this table may be freely combined * and even OR'd together. */LOCAL INT16 motFccAnOrderTbl [] = { MII_TECH_100BASE_TX_FD, /* 10Base-T FD */ MII_TECH_100BASE_TX, /* 100Base-T */ MII_TECH_100BASE_T4, /* 10Base-T */ MII_TECH_10BASE_T, /* 100Base-T4 */ MII_TECH_10BASE_FD, /* 100Base-T FD*/ -1 /* end of table */ };/* forward declarations */STATUS sysFccEnetEnable (UINT32 immrVal, UINT8 fccNum);STATUS sysFccEnetCommand(UINT32 immrVal, UINT8 fccNum, UINT16 command);STATUS sysFccMiiBitWr (UINT32 immrVal, UINT8 fccNum, INT32 bitVal);STATUS sysFccMiiBitRd (UINT32 immrVal, UINT8 fccNum, INT8 * bitVal);STATUS sysFccEnetDisable (UINT32 immrVal, UINT8 fccNum);LOCAL STATUS sysMiiPhyInit (PHY_INFO * pPhyInfo);LOCAL void sysMiiInt(PHY_INFO * pPhyInfo);LOCAL STATUS sysMiiPhyDuplex(PHY_INFO * pPhyInfo,int * pDuplex);LOCAL STATUS sysMiiPhySpeed(PHY_INFO * pPhyInfo,int * pSpeed);FCC_END_FUNCS fccFuncs;/************************************************************************* sysMotFccEndLoad - load an istance of the motFccEnd driver** This routine loads the motFccEnd driver with proper parameters. It also* reads the BCSR3 to find out which type of processor is being used, and* sets up the load string accordingly.** The END device load string formed by this routine is in the following* format.* <immrVal>:<fccNum>:<bdBase>:<bdSize>:<bufBase>:<bufSize>:<fifoTxBase>* :<fifoRxBase>:<tbdNum>:<rbdNum>:<phyAddr>:<phyDefMode>:<pAnOrderTbl>:* <userFlags>:<mBlkRatio>:<mBlkRatio>** .IP <immrVal>* Internal memory address* .IP <fccNum>* FCC number being used* .IP <bdBase>* buffer descriptors base address* .IP <bdSize>* buffer descriptors space size* .IP <bufBase>* data buffers base address* .IP <bufSize>* data buffers space size* .IP <fifoTxBase>* tx buffer in internal memory* .IP <fifoRxBase>* rx buffer in internal memory* .IP <tbdNum>* number of TBDs or NONE* .IP <rbdNum>* number of RBDs or NONE* .IP <phyAddr>* address of a MII-compliant PHY device* .IP <phyDefMode>* default operating mode of a MII-compliant PHY device* .IP <pAnOrderTbl>* auto-negotiation order table for a MII-compliant PHY device or NONE* .IP <userFlags>* User flages* .IP <mBlkRatio>* Ratio between mBlk's and Rx BD's* .IP <clusterRatio>* Ratio between Clusters and Rx BD's** This routine only loads and initializes one instance of the device.* If the user wishes to use more than one motFccEnd devices, this routine* should be changed.** RETURNS: pointer to END object or NULL.** SEE ALSO: motFccEndLoad ()*/END_OBJ * sysMotFccEndLoad ( char * pParamStr, /* ptr to initialization parameter string */ void * unused /* unused optional argument */ ) { /* * The motFccEnd driver END_LOAD_STRING should be: * <immrVal>:<fccNum>:<bdBase>:<bdSize>:<bufBase>:<bufSize>:<fifoTxBase> * :<fifoRxBase>:<tbdNum>:<rbdNum>:<phyAddr>:<phyDefMode> * :<pAnOrderTbl>:<userFlags>:<mBlkRatio>:<clusterRatio> * Note that unit string is prepended by the mux, so we * don't put it here. */ char * pStr = NULL; char paramStr [300]; UINT32 regPC; UINT32 motFccBufsDescAdr; UINT32 motFccBufsDescSize; UINT32 motFccBufsAdr; UINT32 motFccBufsSize; UINT32 motFccFlags; static char motFccEndParamTemplate [] = "0x%x:0x%x:0x%x:0x%x:0x%x:0x%x:0x%x:0x%x:0x%x:0x%x:0x%x:0x%x:0x%x:0x%x:0x%x:0x%x:0x%x"; END_OBJ * pEnd; int fccUnit=0; char * tok; /* an initString token */ char * holder = NULL; /* points to pParamStr fragment beyond tok */ char enet[MAC_ADRS_LEN+2]; fccFuncs.miiPhyInit = sysMiiPhyInit; /* bsp MiiPhy init function */ fccFuncs.miiPhyInt = NULL; /* Driver function for BSP to call */ fccFuncs.miiPhyBitRead = (FUNCPTR)sysFccMiiBitRd; /* Bit Read funtion */ fccFuncs.miiPhyBitWrite = (FUNCPTR)sysFccMiiBitWr; /* Bit Write function */ fccFuncs.miiPhyDuplex = sysMiiPhyDuplex; /* duplex status call back */ fccFuncs.miiPhySpeed = sysMiiPhySpeed; /* speed status call back */ fccFuncs.hbFail = NULL; /* heart beat fail */ fccFuncs.intDisc = NULL; /* disconnect Function */ fccFuncs.dpramFree = NULL; fccFuncs.dpramFccMalloc = NULL; fccFuncs.dpramFccFree = NULL; _func_m82xxDpramFree = (FUNCPTR)m82xxDpramFree; _func_m82xxDpramFccMalloc = (FUNCPTR)m82xxDpramFccMalloc; _func_m82xxDpramFccFree = (FUNCPTR)m82xxDpramFccFree; if (strlen (pParamStr) == 0) { /* * muxDevLoad() calls us twice. If the string is * zero length, then this is the first time through * this routine. */ pEnd = (END_OBJ *) motFcc2EndLoad (pParamStr); } else { regPC = sysPCGet (); if ((regPC & ROM_BASE_ADRS) == ROM_BASE_ADRS) { /* We are running from ROM */ /* * ROM resident applications MUST use the option, wail RAM resident * MAY use the option, which forces all * driver buffers (rx and tx) to reside in local bus space. The * drawback to having buffers on the local bus is that the driver * MUST copy all transmit packets to the local bus -- so zcopy * must be inhibited. The driver still passes rx data zcopy. */ /* for ROM apps, specify local bus space for the buffers */ motFccBufsAdr = LOCAL_MEM_LOCAL_ADRS + (LOCAL_MEM_SIZE >> 1); motFccBufsSize = LOCAL_MEM_SIZE >> 1; /* for ROM apps, MOT_FCC_FLAGS *must* include the following. */ motFccFlags = 0x0000D000; /*(MOT_FCC_USR_BUF_LBUS|MOT_FCC_USR_NO_ZCOPY|MOT_FCC_USR_DPRAM_ALOC)*/ /* * NOTE! The FCC driver internally forces MOT_FCC_USR_NO_ZCOPY if * MOT_FCC_USR_BUF_LBUS is set in MOT_FCC_FLAGS, making the * inclusion of 'NO_ZCOPY not strictly required. The 'NO_ZCOPY * flag can be used independently of the bus on which buffers * reside -- for those rare apps that might need this option. */ } else { /* We are running from RAM */ /* for RAM apps, let the driver find space for the buffers */ motFccBufsAdr = -1UL; motFccBufsSize = -1UL;#if (USER_D_CACHE_MODE == (CACHE_COPYBACK | CACHE_SNOOP_ENABLE)) motFccFlags = MOT_FCC_USR_SNOOP_ENABLE;#else motFccFlags = 0x00008000; /* DPRAM ALOC */#endif } /* * NOTE! Regarding bus choices for BDs and buffers. * If you give a local bus address for BDs and don't include * MOT_FCC_USR_BD_LBUS in MOT_FCC_FLAGS, the CPM will hang. * If you give a local bus address for buffers and don't include * MOT_FCC_USR_BUF_LBUS in MOT_FCC_FLAGS, the CPM will hang. * If you give a 60x bus address for buffers and/or BDs and * mistakenly include either a 'LBUS flag, the CPM will hang. */ /* * If you want the driver to decide where to put the BDs, set BOTH of the * following motFccBufsDescAdr & motFccBufsDescSize to -1UL. * If you decide to force the driver to use BDs on the local bus, set the * following motFccBufsDescAdr to a local bus address and size AND be sure to add * MOT_FCC_USR_BD_LBUS to the definition of MOT_FCC_FLAGS below. * The defaults use internal DPRAM for BDS. You may optionally specify * a 60x bus address for BDS. In these cases do not set the LBUS flag. * Because the Wind River ATM driver need as much as posible free DPRAM, when using * the ATM driver the BDs will be on the 60x bus. */ motFccBufsDescSize = MOT_FCC_BDS_SIZE;# ifdef INCLUDE_ATM motFccBufsDescAdr = -1UL;# else /* INCLUDE_ATM is not defined */# if (USER_D_CACHE_MODE == (CACHE_COPYBACK | CACHE_SNOOP_ENABLE)) motFccBufsDescAdr = -1UL;# else if ((motFccBufsDescAdr = (UINT32)m82xxDpramAlignedMalloc (MOT_FCC_BDS_SIZE,8)) == 0) { motFccBufsDescAdr = -1UL; }# endif# endif /* INCLUDE_ATM */ /* * On the second pass through here, we actually create * the initialization parameter string on the fly. * Note that we will be handed our unit number on the * second pass and we need to preserve that information. * So we use the unit number handed from the input string. */ pStr = strcpy (paramStr, pParamStr); /* Now, we get to the end of the string */ pStr += strlen (paramStr); tok = strtok_r (pParamStr, ":", &holder); if (tok == NULL) { return (END_OBJ*)NULL; } fccUnit = ((int) strtoul (tok, NULL, 16)); if (sysNetMacNVRamAddrGet ("motfcc", fccUnit, enet, MAC_ADRS_LEN) == ERROR) { logMsg ("Error: motFcc2EndLoad illegal MAC address - use M command\n", 0, 0, 0, 0, 0, 0); return(NULL); } /* finish off the initialization parameter string */ sprintf (pStr, motFccEndParamTemplate, (UINT) vxImmrGet (), fccUnit + MOT_FCC_BASE_NUM, motFccBufsDescAdr, motFccBufsDescSize, motFccBufsAdr, motFccBufsSize, -1UL,-1UL, MOT_FCC_TBD_NUM, MOT_FCC_RBD_NUM, fccPhyAdrs[fccUnit], MOT_FCC_DEF_PHY_MODE, &motFccAnOrderTbl, motFccFlags, &fccFuncs, MOT_FCC_MBLK_RBD_RATIO, MOT_FCC_CLUS_RBD_RATIO ); if ((pEnd = (END_OBJ *) motFcc2EndLoad (paramStr)) == (END_OBJ *)NULL) { logMsg ("Error: motFccEndLoad failed to load driver\n", 0, 0, 0, 0, 0, 0); } } return pEnd; }/** Note:* The ADS827x have Davicom 9161 10/100 PHYs on them. The following* two routines are used to detect the current link speed and duplex* setting via a vendor-specific MII register at offset 17. The register* layout is shown below. For more info, refer to the 9161 datasheet* available from http://www.davicom.com.tw*/#define DAVICOM_DSCSR 17#define DAVICOM_DSCSR_100FDX 0x8000#define DAVICOM_DSCSR_100HDX 0x4000#define DAVICOM_DSCSR_10FDX 0x2000#define DAVICOM_DSCSR_10HDX 0x1000#define DAVICOM_DSCSR_PHYADDR 0x01d0#define DAVICOM_DSCSR_ANEGMON 0x0008#define DAVICOM_ANEG_DONE_OK 0x8#define DAVICOM_ANEG_PARALLEL_NOSIGNAL 0x7#define DAVICOM_ANEG_PARALLEL_SIGNAL 0x6#define DAVICOM_ANEG_CONSISTENCY_FAIL 0x5#define DAVICOM_ANEG_CONSISTENCY_OK 0x4#define DAVICOM_ANEG_ACK_MATCH_FAIL 0x3#define DAVICOM_ANEG_ACK_MATCH_OK 0x2#define DAVICOM_ANEG_ABILITY_MATCH 0x1#define DAVICOM_ANEG_IDLE 0x0 /************************************************************************* sysMiiPhySpeed - check the link speed ** This routine check if the link is 100BaseT or not** RETURNS: 1 if 100BaseT or 0 if not.*/LOCAL STATUS sysMiiPhySpeed ( PHY_INFO * pPhyInfo, int * pSpeed ) { UINT16 miiStat; int retVal; MII_READ(pPhyInfo->phyAddr,DAVICOM_DSCSR,&miiStat,retVal); if (retVal == OK) { if ( (miiStat & (DAVICOM_DSCSR_100HDX|DAVICOM_DSCSR_100FDX)) !=0 ) * pSpeed = 1; else * pSpeed = 0; } return retVal; }/************************************************************************* sysMiiPhyDuplex - check if link is Full Duplex** This routine check if the link is Full Duplex or not** RETURNS: 1 if Full Duplex or 0 if not.*/LOCAL STATUS sysMiiPhyDuplex ( PHY_INFO * pPhyInfo, int * pDuplex ) { UINT16 miiStat; int retVal; MII_READ(pPhyInfo->phyAddr,DAVICOM_DSCSR,&miiStat,retVal); if (retVal == OK) { if ( (miiStat & (DAVICOM_DSCSR_10HDX|DAVICOM_DSCSR_100HDX)) !=0 ) * pDuplex = 0; else * pDuplex = 1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -