//以下仅是本人的一些理解。
/*
Marvell 98DX51xx / 98DX81xx 系列交换芯片 内部初始化
现在一些高端防火墙,流量管理等工业级网络设备使用的交换芯片几乎都来自于broadcom或marvell公司,
一些高端的交换芯片售价高达数千美金,再加上几颗专用于处理报文业务的CPU(多核),
还要有一颗用于管理控制系统资源(承载linux)的CPU, 这就是系统的核心的架构, 其他的外设都围绕以上三者展开.
一般的硬件成本在几万美金以上。
现在的千兆/万兆以太网三层交换机等设备用也会使用一些高端的交换芯片,这类交换芯片内部一般会集成CPU ,
外部再加上FPGA或CPU的配合, 就可组成产品的硬件核心, 硬件成本为几百美金到几千美金之间。
无论是哪种网络设备产品, 都离不开交换芯片(或称为数据包处理芯片 Packet processor)或者的使用,
而在交换芯片的市场上, 引领者无疑是Broadcom 和 Marvell .如今随着千兆/万兆以太网的推广,
以太网的市场发展一日千里, 交换芯片也将承载更强更多的业务能力和管理能力,
所以理解并熟悉以太网交换芯片的驱动将是驱动工程师的重要工作之一.
我们的系统就使用2颗marvell 交换芯片98DX5128 和98DX8110.
98DX5128 集成了24个千兆端口 和 4个万兆端口, 管理接口为PCI-Express.
98DX8110 集成了10 个万兆端口.管理接口为PCI-Express.
实现marvell 交换芯片的驱动是基于marvell的SDK,SDK中提供了操作该芯片的API,
其中硬件初始化部分是比较重要的阶段,在后续的开发过程中很多bug的出现都可能关联在此,
需要驱动工作者对此有一定的理解。而且这部分不会在芯片的datasheet 上给以说明,
只能靠对SDK中代码的阅读,来大致理解整个过程.
初始化过程不同于其他的配置过程,如自动协商,地址学习,PVID,VLAN表配置,转发规则等等.
这些只要根据datasheet上的相应描述,找到SDK中的相应API ,经过封装后调用即可.
SDK 框架如此庞大, 是为了做到兼容不同的芯片。增加了结构的复杂性,但实现了最大的兼容性。
阅读SDK是有非常难度的, 刚接触linux时候,感觉linux的kernel就够复杂了. 看过了这套SDK再看linux,
你会感觉linux的driver的脉络是那么清晰,她的架构都是那么有层次感,无论是总线还是设备,
几乎每个module 都可以按照一个架构思路来分析和观察。但是SDK 中没有结构感,
经常能见到一个 .c 文件中就装了上万行的代码, 其中一大半用来实现复用, 细细品来,真的把兼容性做到了极致。
SDK 是我们在我们自定义的架构下,根据我们的操作,来实现硬件芯片的 drive ,
但是这个driver 完全是在用户层上实现的。 不同与 linux 内核中的driver 。
SDK 不选择添加到linux driver 中的原因是, 因为需要经常调试,如果添加在driver 中,
那么每次修改后都要重新 make kernel , 假如新的kernel运行不起来,
只能用串口或网口在bootloader阶段重新load,这个过程非常耗时费力。
根据SDK 中提供的API , 使得驱动工程师可以在用户层修改各种硬件配置参数,
修改好后只需compile 和 install 就可以,进而在shell中直接操作硬件寄存器。
SDK 中提供了特有的,针对具体的芯片的软件接口,这种接口的底层一般都是经过严密封装的,
几乎无法看到是怎么样具体操作寄存器的(也没必要去关心)。
SDK 的使用也是需要得到授权的,一款高端芯片的授权费用可能高达数十万美金。
如此高昂的价格在于它集成了多少优秀的工程师多少年的汗水的智慧,是一个商业公司的核心技术的结晶。
那么对于有着这样价值的代码, 有些部分是着重阅读的, 想把SDK中的代码完全读完读懂几乎是不可能的,
也完全没有必要,我们的目的只是如下:
一,软件兼容性. 我们可以观察它是怎么使用一套代码兼容数十种不同型号的芯片。
这样可以使得我们实现API时,实现代码更精炼,更有兼容性.
二,SDK不是针对某一个特定芯片而做,在实际使用中或多或少会有些需要修改的地方,
这就需要对关键的部分有所了解,这样在出现bug的时候可以快速定位,进而解决(这也是实际工作中老板支付你工资的原因).
三,目前很多国外的芯片, 性能和稳定性的确高于国产芯片. 就比如在交换芯片,
只有broadcom,marvell. 但一个小公司若想使用, 难以得到厂商的技术支持,
如果这种芯片在国内市场上还没有多数使用,找不到参考资料,那
只能阅读芯片的英文datasheet来学习, 再到理解这款芯片,
这是需要很长时间的, 不仅开发周期变长,还有很多很多不可预知的风险,
这对一个小公司的生存是种考验. 但若要等到市场上开始接受了这款芯片,
可以获取更多的信息和资料时, 很可能失去了先发优势, 延误了市场的最佳战机.
即便产品研发成功, 销售又成了压力.
其实这点痛苦了我很久, 所以我希望我今天的一点点理解和简陋的表达,
能为将来某位苦恼在这款芯片的嵌入式linux驱动工作者提供那怕一点点帮助.
所谓前人栽树后人乘凉, 毕竟开放和分享是这个时代的主流.如果哪位前辈能够给我以指导,我将不胜感激。
SDK 的使用:
一,既然此 driver 也是linux 的一部分,肯定是需要Makefile来组织,来使其融入linux。
在Makefile 中也要有TARGET,export变量,INCLUDES, LIB_PATH, ,LIBCPSS,CFLAGS等的描述,
比如在export 中就需要有相应的宏定义, 程序在运行时就可以根据定义的宏,来执行 #ifdef xxx等判断。
执行特定芯片需要执行的部分。
如果要使用此SDK支持的其他芯片,那么只需要修改Makefile,而不用改动SDK .
二, SDK 是提供API给我们使用的, 那么我们应该设计一套软件架构来作为承载,
可将我们的软件做为一个守护进程 , 完成自身的初始化后, 等待shell 的调用,
根据具体的命令,来调用SDK中的具体API,实现相应的配置。
*/
/*
by: 韩大卫 @吉林师范大学
转载请标明出处
*/
/*
芯片硬件初始化的过程为如下代码, 不足实际代码的1%. 省略了很多无关的部分,只为澄清脉络.
本文仅是展开硬件初始化部分的代码.
关于此芯片的具体功能描述或数据包处理流程等, 请参考作者的其他文章.
*/
api的使用 :rc = cpssInitSystem(1,3,0);
cpssInitSystem() 定义如下:
* INPUTS:
* boardIdx
- The index of the board to be initialized from the board
list.
* boardRevId
- Board revision Id.
* reloadEeprom
- Whether the Eeprom should be reloaded when
*
corePpHwStartInit() is called.
GT_STATUS cpssInitSystem
(
IN GT_U32 boardIdx,
IN GT_U32 boardRevId,
IN GT_U32 reloadEeprom
}
{
….
GT_BOARD_LIST_ELEMENT *pBoardInfo; /* Holds the board information*/
GT_BOARD_CONFIG_FUNCS boardCfgFuncs; /* Board specific configuration functions. */
/*
GT_BOARD_LIST_ELEMENT 定义是:
typedef struct
{
FUNCP_REGISTER_BOARD_FUNCS registerFunc;
GT_CHAR boardName[GT_BOARD_LIST_STRING_LEN_CNS];
GT_U8 numOfRevs;
GT_CHAR boardRevs[GT_BOARD_LIST_NUM_OF_BORAD_INITS_CNS][GT_BOARD_LIST_STRING_LEN_CNS];
}GT_BOARD_LIST_ELEMENT;
GT_BOARD_CONFIG_FUNCS 包含了芯片特定的控制功能,定义如下:
typedef struct
{
FUNCP_GET_BOARD_MEMORY_INFO boardGetMemInfo;
FUNCP_GET_BOARD_INFO boardGetInfo;
FUNCP_BEFORE_PHASE1_CONFIG boardBeforePhase1Config;
FUNCP_GET_PP_PHASE1_PARAMS boardGetPpPh1Params;
FUNCP_AFTER_PHASE1_CONFIG boardAfterPhase1Config;
FUNCP_GET_PP_PHASE2_PARAMS boardGetPpPh2Params;
FUNCP_AFTER_PHASE2_CONFIG boardAfterPhase2Config;
FUNCP_GET_PP_LOGICAL_INIT_PARAMS boardGetPpLogInitParams;
FUNCP_GET_LIB_INIT_PARAMS boardGetLibInitParams;
FUNCP_AFTER_INIT_CONFIG boardAfterInitConfig;
FUNCP_GET_PP_REG_CFG_LIST boardGetPpRegCfgList;
FUNCP_GET_STACK_CONFIG_PARAMS boardGetStackConfigParams;
FUNCP_GET_MNG_PORT_NAME boardGetMngPortName;
FUNCP_AFTER_STACK_READY_CONFIG boardAfterStackReadyConfig;
}GT_BOARD_CONFIG_FUNCS;
函数的功能概括如下:
* Fields:
* boardGetMemInfo - Returns memory size for the board.
* boardGetInfo - Returns general board information.
* boardGetXbarCfgParams - Returns parameters for the xbarSysConfig()
* function.
* boardGetPpPh1Params - Returns parameters for the
* corePpHwPhase1Init() function.
* boardGetFaPh1Params - Returns parameters for the
* coreFaHwPhase1Init() function.
* boardGetXbarPh1Params - Returns parameters for the
* coreXbarHwPhase1Init() function.
* boardAfterPhase1Config - Board specific configurations that should
* be done after core phase1 initialization.
* boardGetPpPh2Params - Returns parameters for the
* corePpHwPhase2Init() function.
* boardGetFaPh2Params - Returns parameters for the
* coreFaHwPhase2Init() function.
* boardGetXbarPh2Params - Returns parameters for the
* coreXbarHwPhase2Init() function.
* boardAfterPhase2Config - Board specific configurations that should
* be done after core phase2 initialization.
* boardGetSysCfgParams - Returns parameters for the sysConfig()
* function.
* boardGetPpLogInitParams - Returns parameters for the
* sysPpLogicalInit() function.
* boardGetLibInitParams - Returns parameters for Tapi libraries
* initialization.
* afterInitConfig - Board specific configurations that should
* be done after board initialization.
*
* boardGetPpRegCfgList - The following pointers were added to
* boardGetFaRegCfgList support stack.
* boardGetStackConfigParams
* boardGetMngPortName
* boardAfterStackReadyConfig
*/
...
pBoardInfo = &(boardsList[boardIdx – 1]);
/*
boardsList 中我们关心的部分定义如下:
GT_BOARD_LIST_ELEMENT boardsList[] =
...
////根据cpssInitSystem(1,3,0) 中的 参数1 找到此的成员。
// //根据参数 3 要与此成员中的 “3” 对应。
{gtDbDx348GE4HGSBoardReg ,"DB-DX3-GP" ,3,{"Rev 0.1",
"Rev 0.2 - RDE tests",
"Rev 0.3 - FC OFF"}},
...
gtDbDx348GE4HGSBoardReg 定义是:
GT_STATUS gtDbDx348GE4HGSBoardReg
(
IN GT_U8 boardRevId,
OUT GT_BOARD_CONFIG_FUNCS *boardCfgFuncs
)
{
if(boardCfgFuncs == NULL)
{
return GT_FAIL;
}
boardCfgFuncs->boardGetInfo = getBoardInfo;
/*boardCfgFuncs->boardGetCoreCfgPh1Params = getCoreSysCfgPhase1;*/
boardCfgFuncs->boardGetPpPh1Params = getPpPhase1Config;
boardCfgFuncs->boardAfterPhase1Config = configBoardAfterPhase1;
/*boardCfgFuncs->boardGetCoreCfgPh2Params = getCoreSysCfgPhase2;*/
boardCfgFuncs->boardGetPpPh2Params = getPpPhase2Config;
boardCfgFuncs->boardAfterPhase2Config = configBoardAfterPhase2;
/*boardCfgFuncs->boardGetSysCfgParams = getSysConfigParams;*/
boardCfgFuncs->boardGetPpLogInitParams = getPpLogicalInitParams;
boardCfgFuncs->boardGetLibInitParams = getTapiLibInitParams;
boardCfgFuncs->boardAfterInitConfig = afterInitBoardConfig;
/*boardCfgFuncs->boardGetUserPorts = getUserPorts;*/
return GT_OK;
}
用特定的,针对此芯片的配置函数 填充结构体 boardCfgFuncs中的成员函数。
此后的每一步初始化过程中, 具体的配置函数都是基于以上。
*/
...
/* Get board specific functions accordingly to board rev. id */
rc = pBoardInfo->registerFunc((GT_U8)boardRevId, &boardCfgFuncs);
// 此时registerFunc() 的实现函数就是gtDbDx348GE4HGSBoardReg
rc = appDemoInitGlobalModuls(numOfMem, reloadEeprom);
/*
appDemoInitGlobalModuls 定义如下:
static GT_STATUS appDemoInitGlobalModuls
(
IN GT_U32 numOfMemBytes,
IN GT_U32 reloadEeprom
)
{
GT_STATUS rc; /* To hold funcion return code */
GT_U32 i; /* Loop index */
/* Initialize memory pool. It must be done before any memory allocations */
rc = osMemInit(numOfMemBytes, GT_TRUE);
if (rc != GT_OK)
{
return rc;
}
/* save reload eeprom for future use */
gReloadEeprom = (reloadEeprom == 1 ? GT_TRUE : GT_FALSE);
/* Initialize the PP array with default parameters */
for (i = 0; i < PRV_CPSS_MAX_PP_DEVICES_CNS; i++)
{
osMemSet(&appDemoPpConfigList[i], 0, sizeof(appDemoPpConfigList[i]));
appDemoPpConfigList[i].ppPhase1Done = GT_FALSE;
appDemoPpConfigList[i].ppPhase2Done = GT_FALSE;
appDemoPpConfigList[i].ppLogicalInitDone = GT_FALSE;
appDemoPpConfigList[i].ppGeneralInitDone = GT_FALSE;
appDemoPpConfigList[i].valid = GT_FALSE;
/* default value for cpu tx/rx mode */
appDemoPpConfigList[i].cpuPortMode = PRV_CPSS_GEN_NETIF_CPU_PORT_MODE_SDMA_E;
/* cascading information */
appDemoPpConfigList[i].numberOfCscdTrunks = 0;
appDemoPpConfigList[i].numberOfCscdPorts = 0;
appDemoPpConfigList[i].numberOfCscdTargetDevs = 0;
appDemoPpConfigList[i].numberOf10GPortsToConfigure = 0;
appDemoPpConfigList[i].internal10GPortConfigFuncPtr = NULL;
appDemoPpConfigList[i].internalCscdPortConfigFuncPtr = NULL;
}
return GT_OK;
}
初始化一个全局结构体数组 :
PP_DEMO_PP_CONFIG appDemoPpConfigList[PRV_CPSS_MAX_PP_DEVICES_CNS];
PP_DEMO_PP_CONFIG 定义如下:
typedef struct
{
CPSS_PP_DEVICE_TYPE deviceId;
GT_U32 apiSupportedBmp;
CPSS_PP_FAMILY_TYPE_ENT devFamily; /*added*/
GT_BOOL ppPhase1Done;
GT_BOOL ppPhase2Done;
GT_BOOL ppLogicalInitDone;
GT_BOOL ppGeneralInitDone;
CPSS_PP_INTERFACE_CHANNEL_ENT channel;
GT_PCI_INFO pciInfo;
GT_SMI_INFO smiInfo;
GT_TWSI_INFO twsiInfo;
GT_U8 devNum;
GT_U8 oldDevNum;
GT_U8 hwDevNum;
GT_PCI_INT intLine;
GT_BOOL valid;
APP_DEMO_SYS_CONFIG_FUNCS sysConfigFuncs;
/*XG support*/
FUNCP_PORT_CONFIG internal10GPortConfigFuncPtr;
GT_U8 ports10GToConfigureArr[PRV_CPSS_MAX_PP_PORTS_NUM_CNS];
GT_U8 numberOf10GPortsToConfigure;
/* Cascading support */
GT_U8 numberOfCscdTrunks;
GT_U8 numberOfCscdTargetDevs;
GT_U8 numberOfCscdPorts;
CSCD_INIT_UC_TBL_STC cscdTargetDevsArr[CPSS_CSCD_MAX_DEV_IN_CSCD_CNS];
CSCD_INIT_PORT_DESC_STC cscdPortsArr[PRV_CPSS_MAX_PP_PORTS_NUM_CNS];
FUNCP_PORT_CONFIG internalCscdPortConfigFuncPtr;
GT_BOOL externalTcamUsed;
struct APP_DEMO_EXTERNAL_TCAM_KEY_LOOKUP_STCT *extTcamMngPtr;
GT_BOOL flowControlDisable;
/* start - multi-port-groups support */
GT_U32 numOfPortGroups;
struct{
GT_BOOL portGroupActive;
GT_PCI_INFO portGroupPciInfo;
GT_PORT_GROUPS_BMP unifiedFdbPortGroupsBmp;
} portGroupsInfo[APP_DEMO_CPSS_MAX_NUM_PORT_GROUPS_CNS];
CPSS_PORTS_BMP_STC multiPortGroupRingPortsBmp;/* debug info */
APP_DEMO_CPSS_MULTI_PORT_GROUP_FDB_MODE_ENT fdbMode;
/* end - multi-port-groups support */
PRV_CPSS_GEN_NETIF_CPU_PORT_MODE_ENT cpuPortMode;
struct{
GT_BOOL trunkToCpuPortNum;
}wa;
}APP_DEMO_PP_CONFIG;
这个结构体 大致表述如下:
/*
* Typedef: struct APP_DEMO_PP_CONFIG
*
* Description: Holds Pp configuration parameters for initialization.
*
* Fields:
* deviceId - HW device ID of the PP
* apiSupportedBmp - bmp of supported type of API to call
* ppPhase1Done - Indicates whether the corePpHwPhase1Init() function was
* already called.
* ppPhase2Done - Indicates whether the corePpHwPhase2Init() function was
* already called.
* ppLogicalInitDone - Indicates whether the sysPpLogicalInit() function was
* already called.
* ppGeneralInitDone - Indicates whether the general initialization was done.
* channel - smi / pci channel to the PP.
* pciInfo - Device pci mapping info.
* smiInfo - Device smi mapping info.
* twsiInfo - Device twsi mapping info.
* devNum - The device's software device number.
* oldDevNum - The old device number that was assigned to the device in
* phase1.
* hwDevNum - The device's hardware device number.
* flowGroup - The flow group to which this device belongs.
* intLine - The interrupt line on which the device is connected.
* valid - If this entry holds valid data.
* active - Is the device active.
* XG support:
* internal10GPortConfigFuncPtr - Board-specific configuration for 10G ports
* (if not required - NULL)
* ports10GToConfigureArr - Array of numbers of XG ports to configure
* numberOf10GPortsToConfigure - number of valid elements in ports10GToConfigureArr
* numberOfCscdTrunks - (should be lower than number of trunks supported in HW)
* numberOfCscdTargetDevs - Number of valid elements in cscdTargetDevsArr
* (id of the first invalid)
* numberOfCscdPorts - Number of valid elements in cscdPortsArr
* (id of the first invalid)
* cscdTargetDevsArr - Information required to fill cascade map table
* (target device numbers, link type and number)
* cscdPortsArr - Cascade ports info (port numbers, cascade type, trunkId)
* internalCscdPortConfigFuncPtr - board-specific additional configuration
* for cascade ports (if not required - NULL)
* externalTcamUsed - indicate whether external Tcam is used.
* extTcamMngPtr - (pointer to) external TCAM management database.
* flowControlDisable - Defines system Flow Control settings of
* Tail Drop and Buffer Management to be:
* GT_TRUE - per ingress port disable FC
* and enable HOL system mode.
* GT_FALSE - per ingress port enable FC
* and enable Flow Control system mode
* numOfPortGroups - The number of port-groupss in the device.
* 0 --> a non multi-port-groups device .
* 1,2.. --> multi-port-groups device with 1,2.. cores.
* Set by getBoardInfo --> set 4 for Lion
* portGroupsInfo[] - info needed per port group.
* Set by getBoardInfo
* portGroupActive - is the port group active
* portGroupPciInfo - port group PCI info. ('per port group' PCI info)
* For non active port group set all parameters with CPSS_PARAM_NOT_USED_CNS
* unifiedFdbPortGroupsBmp - bitmap of port groups that need to be accessed
* when set/get fdb entry in current port group.
* Set by getBoardInfo
* portGroupActive - is the port group active
* portGroupPciInfo - port group PCI info. ('per port group' PCI info)
* For non active port group set all parameters with CPSS_PARAM_NOT_USED_CNS
* unifiedFdbPortGroupsBmp - bitmap of port groups that need to be accessed
* when set/get fdb entry in current port group.
* multiPortGroupRingPortsBmp - bmp of ring ports . -- debug info --
* this is needed for auto add of those ports to
* vlan (used by UT enhanced and can be used by Galtis wrappers )
* (relevant to multi port groups device)
* fdbMode - fdb mode - unified / linked unified / linked
* (relevant to multi port groups device)
* cpuPortMode - which way CPU TX/RX goes - MII, SDMA, NONE(current ASIC isn't connected to CPU)
* wa - info about WA (workarounds used)
* trunkToCpuPortNum - do we use the trunk WA : traffic to CPU from
* trunk member get wrong port num indication
*
*/
// 调用getBoardInfo() ,显示芯片配置信息。
/* Get board information */
rc = boardCfgFuncs.boardGetInfo((GT_U8)boardRevId,
&numOfPp,
&numOfFa,
&numOfXbar,
&gIsB2bSystem);
//如果在初始化阶段1执行之前需要有特定配置,then do it.
/* Does board specific settings before phase 1 */
if (boardCfgFuncs.boardBeforePhase1Config != NULL)
{
rc = boardCfgFuncs.boardBeforePhase1Config((GT_U8)boardRevId);
CPSS_ENABLER_DBG_TRACE_RC_MAC("boardCfgFuncs.boardBeforePhase1Config", rc);
if (rc != GT_OK)
{
return rc;
}
}
//执行芯片初始化阶段1.
/*****************************************************************/
/* HW phase 1 initialization */
/*****************************************************************/
rc = appDemoBoardPhase1Init((GT_U8)boardRevId,
&boardCfgFuncs,
numOfPp,
numOfFa,
numOfXbar);
/*
appDemoBoardPhase1Init 定义如下:
static GT_STATUS appDemoBoardPhase1Init(...)
{
...
#ifdef IMPL_PP
//此宏在Makefile中得到定义
/* Set Pp Phase1 configuration parameters. */
for (devIdx = SYSTEM_DEV_NUM_MAC(0); devIdx < SYSTEM_DEV_NUM_MAC(numOfDev); devIdx++)
{
APP_DEMO_SYS_CONFIG_FUNCS* sysCfgFuncs;
/*
APP_DEMO_SYS_CONFIG_FUNCS 定义如下:
typedef struct
{
FUNCP_CPSS_HW_PP_PHASE1_INIT cpssHwPpPhase1Init;
FUNCP_CPSS_HW_PP_START_INIT cpssHwPpStartInit;
FUNCP_CPSS_HW_PP_PHASE2_INIT cpssHwPpPhase2Init;
FUNCP_CPSS_PP_LOGICAL_INIT cpssPpLogicalInit;
FUNCP_CPSS_LIBRARIES_INIT cpssLibrariesInit;
FUNCP_CPSS_TRAFFIC_ENABLE cpssTrafficEnable;
FUNCP_CPSS_PP_GENERAL_INIT cpssPpGeneralInit;
} APP_DEMO_SYS_CONFIG_FUNCS;
* Fields:
* cpssHwPpPhase1Init - HW phase 1 init
* cpssHwPpStartInit - PP start init
* cpssHwPpPhase2Init - HW phase 2 init
* cpssLibrariesInit - All CPSS libraries init
* cpssPpLogicalInit - Logical init for device
* cpssNetworkIfInit - network interface init
* cpssTrafficEnable - enable ports and devices
* cpssPpGeneralInit - General initialization
*
*/
/* Get PP config of this device */
rc = boardCfgFuncs->boardGetPpPh1Params((GT_U8)boardRevId,
devIdx,
&corePpPhase1Params);
//此处调用了getPpPhase1Config() 来实现
…
/* override PP phase 1 parameters according to app demo database */
rc = appDemoUpdatePpPhase1Params(&corePpPhase1Params);
...
/* Update PP config list device number */
appDemoPpConfigList[devIdx].devNum = corePpPhase1Params.devNum;
appDemoPpConfigList[devIdx].valid = GT_TRUE;
// 根据参数,得到针对特定芯片的初始化配置函数
/* get family type to understand which API should be used below */
/* There are two type of API here: EX and DX */
rc = appDemoSysConfigFuncsGet(corePpPhase1Params.deviceId,
&appDemoPpConfigList[devIdx].sysConfigFuncs,
/*
GT_STATUS appDemoSysConfigFuncsGet
(
IN GT_U32 deviceType,
OUT APP_DEMO_SYS_CONFIG_FUNCS *sysConfigFuncsPtr,
OUT GT_U32 *apiSupportedBmpPtr
)
{
…
// 在 Makefile 中 只有对 CHX_FAMILY 的定义。
#if (defined CHX_FAMILY)
*apiSupportedBmpPtr = APP_DEMO_DXCH_FUNCTIONS_SUPPORT_CNS;
...
if(devFamily >= CPSS_PP_FAMILY_CHEETAH3_E)
{
/*ch3 ...*/
*apiSupportedBmpPtr |= APP_DEMO_DXCH3_FUNCTIONS_SUPPORT_CNS;
}
…
sysConfigFuncsPtr->cpssHwPpPhase1Init = FORCE_FUNC_CAST appDemoDxHwPpPhase1Init;
sysConfigFuncsPtr->cpssHwPpStartInit = FORCE_FUNC_CAST appDemoDxHwPpStartInit;
sysConfigFuncsPtr->cpssHwPpPhase2Init = FORCE_FUNC_CAST appDemoDxHwPpPhase2Init;
sysConfigFuncsPtr->cpssLibrariesInit = FORCE_FUNC_CAST appDemoDxLibrariesInit;
sysConfigFuncsPtr->cpssPpLogicalInit = FORCE_FUNC_CAST appDemoDxPpLogicalInit;
sysConfigFuncsPtr->cpssTrafficEnable = FORCE_FUNC_CAST appDemoDxTrafficEnable;
sysConfigFuncsPtr->cpssPpGeneralInit = FORCE_FUNC_CAST appDemoDxPpGeneralInit;
/*
上面的填充函数在之后的初始化过程中都会分别得到调用. 接下来的初始化过程中,具体的执行函数都是以上。
*/
#endif /* (defined CHX_FAMILY) */
...
}
*/
…
/* Do HW phase 1 */
rc = sysCfgFuncs->cpssHwPpPhase1Init(appDemoPpConfigList[devIdx].devNum,
&corePpPhase1Params,
&ppDevType);
// 实际上调用了appDemoDxHwPpPhase1Init () 来做具体实现。
/*
appDemoDxHwPpPhase1Init() 定义如下:
* INPUTS:
* dev - temp device id, could be changed later
* coreSysCfgPh1ParamsPtr - phase 1 core specific parameters
* corePpPhase1ParamsPtr - PP phase 1 init parameters
GT_STATUS appDemoDxHwPpPhase1Init
(
IN GT_U8 dev,
IN CPSS_PP_PHASE1_INIT_PARAMS *appCpssPpPhase1ParamsPtr,
OUT CPSS_PP_DEVICE_TYPE *ppDevTypePtr
)
{
GT_STATUS rc = GT_OK;
CPSS_DXCH_PP_PHASE1_INIT_INFO_STC cpssPpPhase1Params; /* CPSS phase 1 PP params */
GT_U32 value;
CPSS_DXCH_IMPLEMENT_WA_ENT waFromCpss[CPSS_DXCH_IMPLEMENT_WA_LAST_E];
GT_U32 waIndex=0;
GT_U32 ii;
GT_BOOL trunkToCpuWaEnabled = GT_FALSE;
...
/* fill CPSS Phase1 init parameters */
rc = appDemoConvert2DxChPhase1Info(dev,
appCpssPpPhase1ParamsPtr,
&cpssPpPhase1Params);
//////////////////////////
/*
appDemoConvert2DxChPhase1Info 定义如下:
* DESCRIPTION:
* Set CPSS info from the core format.
static GT_STATUS appDemoConvert2DxChPhase1Info
(
IN GT_U8 dev,
IN CPSS_PP_PHASE1_INIT_PARAMS *appCpssPpPhase1ParamsPtr,
OUT CPSS_DXCH_PP_PHASE1_INIT_INFO_STC *cpssPpPhase1InfoPtr
)
{
GT_STATUS rc = GT_OK;
GT_U32 ii;
if ((NULL == appCpssPpPhase1ParamsPtr) ||
(NULL == cpssPpPhase1InfoPtr))
{
return GT_BAD_PTR;
}
osMemSet(cpssPpPhase1InfoPtr, 0, sizeof(*cpssPpPhase1InfoPtr));
cpssPpPhase1InfoPtr->devNum = dev;
cpssPpPhase1InfoPtr->busBaseAddr = appCpssPpPhase1ParamsPtr->baseAddr;
cpssPpPhase1InfoPtr->internalPciBase = appCpssPpPhase1ParamsPtr->internalPciBase;
cpssPpPhase1InfoPtr->intVecNum = appCpssPpPhase1ParamsPtr->intVecNum;
cpssPpPhase1InfoPtr->intMask = appCpssPpPhase1ParamsPtr->intMask;
cpssPpPhase1InfoPtr->coreClock =
(appCpssPpPhase1ParamsPtr->coreClk == APP_DEMO_CPSS_AUTO_DETECT_CORE_CLOCK_CNS) ?
CPSS_DXCH_AUTO_DETECT_CORE_CLOCK_CNS : appCpssPpPhase1ParamsPtr->coreClk;
cpssPpPhase1InfoPtr->mngInterfaceType = appCpssPpPhase1ParamsPtr->mngInterfaceType;
cpssPpPhase1InfoPtr->ppHAState = appCpssPpPhase1ParamsPtr->sysHAState;
cpssPpPhase1InfoPtr->powerDownPortsBmp = appCpssPpPhase1ParamsPtr->powerDownPortsBmp;
cpssPpPhase1InfoPtr->serdesRefClock = appCpssPpPhase1ParamsPtr->serdesRefClock;
cpssPpPhase1InfoPtr->initSerdesDefaults = appCpssPpPhase1ParamsPtr->initSerdesDefaults;
if(appCpssPpPhase1ParamsPtr->numOfPortGroups)
{
cpssPpPhase1InfoPtr->busBaseAddr = CPSS_PARAM_NOT_USED_CNS;
cpssPpPhase1InfoPtr->numOfPortGroups = appCpssPpPhase1ParamsPtr->numOfPortGroups;
if(appCpssPpPhase1ParamsPtr->numOfPortGroups > APP_DEMO_CPSS_MAX_NUM_PORT_GROUPS_CNS)
{
return GT_BAD_STATE;
}
cpssPpPhase1InfoPtr->multiPortGroupsInfoPtr = portGroupsPhase1InfoArr;
for(ii = 0 ; ii < appCpssPpPhase1ParamsPtr->numOfPortGroups ; ii++)
{
portGroupsPhase1InfoArr[ii].busBaseAddr = appCpssPpPhase1ParamsPtr->portGroupsInfo[ii].busBaseAddr;
portGroupsPhase1InfoArr[ii].internalPciBase = appCpssPpPhase1ParamsPtr->portGroupsInfo[ii].internalPciBase;
portGroupsPhase1InfoArr[ii].intVecNum = appCpssPpPhase1ParamsPtr->portGroupsInfo[ii].intVecNum;
portGroupsPhase1InfoArr[ii].intMask = appCpssPpPhase1ParamsPtr->portGroupsInfo[ii].intMask;
}
}
cpssPpPhase1InfoPtr->isExternalCpuConnected = appCpssPpPhase1ParamsPtr->isExternalCpuConnected;
return rc;
}
*/
////////////////////////////////////
...
/* use same string as for PSS */
if(appDemoDbEntryGet("GT_CORE_SYS_WA_OPTION_TRUNK_WRONG_SOURCE_PORT_TO_CPU_WA_E", &value) == GT_OK)
{
if(value)
{
trunkToCpuWaEnabled = GT_TRUE;
waFromCpss[waIndex++] =
CPSS_DXCH_IMPLEMENT_WA_TRUNK_WRONG_SOURCE_PORT_TO_CPU_WA_E;
}
}
if(appDemoDbEntryGet("GT_CORE_SYS_WA_OPTION_SDMA_PKTS_FROM_CPU_STACK_WA_E", &value) == GT_OK)
{
if(value)
{
waFromCpss[waIndex++] =
CPSS_DXCH_IMPLEMENT_WA_SDMA_PKTS_FROM_CPU_STACK_E;
}
}
if(appDemoDbEntryGet("GT_CORE_SYS_WA_OPTION_SDMA_PKTS_FROM_CPU_STACK_PADDING_WA_E", &value) == GT_OK)
{
if(value)
{
waFromCpss[waIndex++] =
CPSS_DXCH_IMPLEMENT_WA_SDMA_PKTS_FROM_CPU_STACK_PADDING_E;
}
}
if(appDemoDbEntryGet("GT_CORE_SYS_WA_RESTRICTED_ADDRESS_FILTERING_WA_E", &value) == GT_OK)
{
if(value)
{
waFromCpss[waIndex++] =
CPSS_DXCH_IMPLEMENT_WA_RESTRICTED_ADDRESS_FILTERING_E;
}
}
...
// 打印设备ID 和 版本信息。
rc = appDemoDxChDeviceIdAndRevisionPrint(dev);
...
if(waIndex)
{
rc = cpssDxChHwPpImplementWaInit(dev,waIndex,&waFromCpss[0],0);
...
if (trunkToCpuWaEnabled == GT_TRUE)
{
for(ii = SYSTEM_DEV_NUM_MAC(0) ; ii < SYSTEM_DEV_NUM_MAC(appDemoPpConfigDevAmount);ii++)
{
if(appDemoPpConfigList[ii].valid && appDemoPpConfigList[ii].devNum == dev)
{
/* save to DB --> will be used by the galtis Wrappers */
appDemoPpConfigList[ii].wa.trunkToCpuPortNum = GT_TRUE;
break;
}
}
}
}
return GT_OK;
} /* appDemoDxHwPpPhase1Init */
*/
...
/* Update PP config list element of device */
appDemoPpConfigList[devIdx].ppPhase1Done = GT_TRUE;
appDemoPpConfigList[devIdx].deviceId = ppDevType;
/* Get list of registers to be configured. */
if (boardCfgFuncs->boardGetPpRegCfgList == NULL)
{
/* if there is no board-specific function, call the common one */
rc = appDemoGetPpRegCfgList(ppDevType,
gIsB2bSystem,
®CfgList,
®CfgListSize);
...
}
else
{
rc =
boardCfgFuncs>boardGetPpRegCfgList(boardRevId,appDemoPpConfigList[devIdx].devNum,
...
}
if (appDemoPrePhase1Init == GT_FALSE)
{
if(sysCfgFuncs->cpssHwPpStartInit)
{
/* Set PP's registers */
rc = sysCfgFuncs->cpssHwPpStartInit(appDemoPpConfigList[devIdx].devNum,
gReloadEeprom,
regCfgList,
regCfgListSize);
// 实际上调用了appDemoDxHwPpStartInit()
...
}
}
}
#endif /* IMPL_PP */
…
}
////////////////////////////
...
rc = boardCfgFuncs.boardAfterPhase1Config((GT_U8)boardRevId);
...
/*
此处执行的函数是configBoardAfterPhase1()
*/
// 芯片初始化阶段2
/*****************************************************************/
/* HW phase 2 initialization */
/*****************************************************************/
rc = appDemoBoardPhase2Init((GT_U8)boardRevId,
&boardCfgFuncs,
numOfPp,
numOfFa,
numOfXbar);
...
//初始化阶段2执行后需要执行的配置。
rc = boardCfgFuncs.boardAfterPhase2Config((GT_U8)boardRevId);
...
/*
static GT_STATUS appDemoBoardPhase2Init
/* Set Pp Phase2 configuration parameters */
for (devIdx = SYSTEM_DEV_NUM_MAC(0); devIdx < SYSTEM_DEV_NUM_MAC(numOfDev); devIdx++)
{
APP_DEMO_SYS_CONFIG_FUNCS* sysCfgFuncs;
/* Get PP phase 2 params */
rc = boardCfgFuncs->boardGetPpPh2Params(boardRevId,
appDemoPpConfigList[devIdx].devNum,
//////////////////////////////////////////////
/* 此处的调用函数是 getPpPhase2Config() 定义如下:
static GT_STATUS getPpPhase2Config
(
IN GT_U8 boardRevId,
IN GT_U8 oldDevNum,
OUT CPSS_PP_PHASE2_INIT_PARAMS *phase2Params
)
{
CPSS_PP_PHASE2_INIT_PARAMS localPpPh2Config = CPSS_PP_PHASE2_DEFAULT;
GT_STATUS retVal;
localPpPh2Config.devNum = oldDevNum;
if(appDemoPpConfigList[oldDevNum].channel == CPSS_CHANNEL_SMI_E)
{
localPpPh2Config.baseAddr =
appDemoPpConfigList[oldDevNum].smiInfo.smiIdSel;
}
localPpPh2Config.deviceId = appDemoPpConfigList[oldDevNum].deviceId;
localPpPh2Config.fuqUseSeparate = GT_TRUE;
retVal = appDemoAllocateDmaMem(localPpPh2Config.deviceId,RX_DESC_NUM_DEF,
RX_BUFF_SIZE_DEF,RX_BUFF_ALLIGN_DEF,
TX_DESC_NUM_DEF,AU_DESC_NUM_DEF,
&localPpPh2Config);
osMemCpy(phase2Params,&localPpPh2Config,sizeof(CPSS_PP_PHASE2_INIT_PARAMS));
return retVal;
}
*/
///////////////////////////////////////////////
…
/* override PP phase 2 parameters according to app demo database */
rc = appDemoUpdatePpPhase2Params(&cpssPpPhase2Params);
…
appDemoPpConfigList[devIdx].oldDevNum =
appDemoPpConfigList[devIdx].devNum;
sysCfgFuncs = &appDemoPpConfigList[devIdx].sysConfigFuncs;
if(sysCfgFuncs->cpssHwPpPhase2Init)
{
/* Lock the interrupts, this phase changes the interrupts nodes pool data */
extDrvSetIntLockUnlock(INTR_MODE_LOCK, &intKey);
/* PP HW phase 2 Init */
rc = sysCfgFuncs->cpssHwPpPhase2Init(appDemoPpConfigList[devIdx].oldDevNum,
&cpssPpPhase2Params);
/*
此处的调用函数是appDemoDxHwPpPhase2Init() ,定义如下:
////////////////////////////////////////
GT_STATUS appDemoDxHwPpPhase2Init
(
IN GT_U8 oldDev,
IN CPSS_PP_PHASE2_INIT_PARAMS *appCpssPpPhase2ParamsPtr
)
{
GT_STATUS rc = GT_OK;
CPSS_DXCH_PP_PHASE2_INIT_INFO_STC cpssPpPhase2Info; /* Cpss phase 2 info */
GT_U8 hwDevNum; /* HW device number */
if (NULL == appCpssPpPhase2ParamsPtr)
{
return GT_BAD_PTR;
}
/* Fill CPSS phase2 init structure */
rc = appDemoConvert2DxChPhase2Info(appCpssPpPhase2ParamsPtr,
&cpssPpPhase2Info);
CPSS_ENABLER_DBG_TRACE_RC_MAC("appDemoConvert2DxChPhase2Info", rc);
if (GT_OK != rc)
{
return rc;
}
rc = cpssDxChHwPpPhase2Init(oldDev, &cpssPpPhase2Info);
CPSS_ENABLER_DBG_TRACE_RC_MAC("cpssDxChHwPpPhase2Init", rc);
if (GT_OK != rc)
{
return rc;
}
/* In order to configure HW device ID different from SW device ID the following */
/* logic is used: HW_device_ID = (SW_device_ID + appDemoHwDevNumOffset) modulo 32 */
/* (this insures diffrent HW and SW device IDs since the HW device ID is 5 */
/* bits length). */
hwDevNum = (GT_U8)((cpssPpPhase2Info.newDevNum + appDemoHwDevNumOffset) & 0x1F);
rc = cpssDxChCfgHwDevNumSet(cpssPpPhase2Info.newDevNum, hwDevNum);
CPSS_ENABLER_DBG_TRACE_RC_MAC("cpssDxChCfgHwDevNumSet", rc);
return rc;
}
extDrvSetIntLockUnlock(INTR_MODE_UNLOCK, &intKey);
...
}
/* Current PP init completed */
appDemoPpConfigList[devIdx].ppPhase2Done = GT_TRUE;
}
#endif
return GT_OK;
}
*/
/*****************************************************************/
/* Logic phase initialization */
/*****************************************************************/
rc = appDemoBoardLogicalInit((GT_U8)boardRevId,
&boardCfgFuncs,
numOfPp,
numOfFa,
numOfXbar);
/*
static GT_STATUS appDemoBoardLogicalInit
(
IN GT_U8 boardRevId,
IN GT_BOARD_CONFIG_FUNCS *boardCfgFuncs,
IN GT_U8 numOfDev,
IN GT_U8 numOfFa,
IN GT_U8 numOfXbar
)
{
GT_STATUS rc;
CPSS_PP_CONFIG_INIT_STC ppLogicalConfigParams;
GT_U8 devIdx;
/* Set Pp Logical configuration parameters */
for (devIdx = SYSTEM_DEV_NUM_MAC(0); devIdx < SYSTEM_DEV_NUM_MAC(numOfDev); devIdx++)
{
APP_DEMO_SYS_CONFIG_FUNCS* sysCfgFuncs;
/* update device config list */
sysCfgFuncs = &appDemoPpConfigList[devIdx].sysConfigFuncs;
/* Get PP logical init configuration */
rc = boardCfgFuncs->boardGetPpLogInitParams(boardRevId,
appDemoPpConfigList[devIdx].devNum,
&ppLogicalConfigParams);
...
/* override logical init configuration according to app demo database */
rc = appDemoUpdatePpLogicalInitParams(&ppLogicalConfigParams);
...
/* Do CPSS logical init and fill PP_INFO structure */
rc = sysCfgFuncs->cpssPpLogicalInit(appDemoPpConfigList[devIdx].devNum,
&ppLogicalConfigParams);
...
appDemoPpConfigList[devIdx].ppLogicalInitDone = GT_TRUE;
osMemCpy(&ppUserLogicalConfigParams[appDemoPpConfigList[devIdx].devNum],
&ppLogicalConfigParams,
sizeof(CPSS_PP_CONFIG_INIT_STC));
}
return GT_OK;
} /* appDemoBoardLogicalInit */
*/
/*****************************************************************/
/* General phase initialization */
/*****************************************************************/
rc = appDemoBoardGeneralInit((GT_U8)boardRevId,
&boardCfgFuncs,
numOfPp,
numOfFa,
numOfXbar);
/*
* DESCRIPTION:
* Perform general initialization for all devices (Pp, Fa, Xbar).
* This function includes initializations that common for all devices.
static GT_STATUS appDemoBoardGeneralInit
(
IN GT_U8 boardRevId, /* Revision of this board */
IN GT_BOARD_CONFIG_FUNCS *boardCfgFuncs, /* Config functions for this board */
IN GT_U8 numOfDev, /* Number of devices in this board */
IN GT_U8 numOfFa, /* Number of FAs in this board */
IN GT_U8 numOfXbar /* Number of xbars in this board */
)
{
GT_STATUS rc = GT_OK;
GT_U8 devIdx;
APP_DEMO_LIB_INIT_PARAMS libInitParams;
CPSS_PP_CONFIG_INIT_STC ppLogicalConfigParams;
/* Do general configuration for all devices */
for (devIdx = SYSTEM_DEV_NUM_MAC(0); devIdx < SYSTEM_DEV_NUM_MAC(numOfDev); devIdx++)
{
APP_DEMO_SYS_CONFIG_FUNCS* sysCfgFuncs;
GT_U8 dev;
/* get init parameters from appdemo init array */
sysCfgFuncs = &appDemoPpConfigList[devIdx].sysConfigFuncs;
dev = appDemoPpConfigList[devIdx].devNum;
/* Get PP logical init configuration */
rc = boardCfgFuncs->boardGetPpLogInitParams(boardRevId,
appDemoPpConfigList[devIdx].devNum,
// 调用的是 getPpLogicalInitParams(),定义如下:
/*
* DESCRIPTION:
* Returns the parameters needed for sysPpLogicalInit() function.
static GT_STATUS getPpLogicalInitParams
(
IN GT_U8 boardRevId,
IN GT_U8 devNum,
OUT CPSS_PP_CONFIG_INIT_STC *ppLogInitParams
)
{
CPSS_PP_CONFIG_INIT_STC localPpCfgParams = PP_LOGICAL_CONFIG_DEFAULT;
localPpCfgParams.maxNumOfIpv4Prefixes = 3920;
localPpCfgParams.numOfTrunks = APP_DEMO_127_TRUNKS_CNS;
/* Ch2 without Vr support case */
localPpCfgParams.maxNumOfVirtualRouters = 1;
localPpCfgParams.lpmDbFirstTcamLine = 100;
localPpCfgParams.lpmDbLastTcamLine = 1204;
osMemCpy(ppLogInitParams,&localPpCfgParams,sizeof(CPSS_PP_CONFIG_INIT_STC));
return GT_OK;
}
*/
…
/* override logical init configuration according to app demo database */
rc = appDemoUpdatePpLogicalInitParams(&ppLogicalConfigParams);
…
/* Get library initialization parameters */
rc = boardCfgFuncs->boardGetLibInitParams(boardRevId,
appDemoPpConfigList[devIdx].devNum,
* Returns Tapi library initialization parameters.
static GT_STATUS getTapiLibInitParams
(
IN GT_U8 boardRevId,
IN GT_U8 devNum,
OUT APP_DEMO_LIB_INIT_PARAMS *libInitParams
)
{
APP_DEMO_LIB_INIT_PARAMS localLibInitParams = LIB_INIT_PARAMS_DEFAULT;
localLibInitParams.initClassifier = GT_FALSE;
localLibInitParams.initIpv6 = GT_TRUE;
localLibInitParams.initIpv4Filter = GT_FALSE;
localLibInitParams.initIpv4Tunnel = GT_FALSE;
localLibInitParams.initMpls = GT_FALSE;
localLibInitParams.initMplsTunnel = GT_FALSE;
localLibInitParams.initPcl = GT_TRUE;
localLibInitParams.initNst = GT_TRUE;
/* there is no Policer lib init for CH3 devices */
localLibInitParams.initPolicer = GT_FALSE;
osMemCpy(libInitParams,&localLibInitParams,
sizeof(APP_DEMO_LIB_INIT_PARAMS));
return GT_OK;
}
*/
…
/* override library initialization parameters according to app demo database */
rc = appDemoUpdateLibInitParams(&libInitParams);
…
/* Initialize CPSS libraries accordingly to a given parameters */
if(sysCfgFuncs->cpssLibrariesInit)
{
rc = sysCfgFuncs->cpssLibrariesInit(appDemoPpConfigList[devIdx].devNum,
&libInitParams,
&ppLogicalConfigParams);
…
/* Initialize CPSS libraries accordingly to a given parameters */
if(sysCfgFuncs->cpssLibrariesInit)
{
rc = sysCfgFuncs->cpssLibrariesInit(appDemoPpConfigList[devIdx].devNum,
&libInitParams,
&ppLogicalConfigParams);
...
}
if(sysCfgFuncs->cpssPpGeneralInit)
{
/* Do CPSS general initialization for given device id */
rc = sysCfgFuncs->cpssPpGeneralInit(dev);
…
}
if(sysCfgFuncs->cpssTrafficEnable)
{
/* Enable traffic for given device */
rc = sysCfgFuncs->cpssTrafficEnable(appDemoPpConfigList[devIdx].devNum);
...
}
appDemoPpConfigList[devIdx].ppGeneralInitDone = GT_TRUE;
}
return GT_OK;
} /* appDemoBoardGeneralInit */
*/
//////////////////////////////////////////
if(appDemoOnDistributedSimAsicSide == 0)
{
/*****************************************************************/
/* Perform board specific settings after logical phase */
/*****************************************************************/
if (boardCfgFuncs.boardAfterInitConfig != NULL)
{
rc = boardCfgFuncs.boardAfterInitConfig((GT_U8)boardRevId);
// 调用了 afterInitBoardConfig()
...
}
if ((numOfPp + numOfFa + numOfXbar) != 0 &&
(appDemoBypassEventInitialize == GT_FALSE) &&
(hsuInfo.hsuState == CPSS_HSU_STATE_COMPLETED_E))
{
/* spawn the user event handler processes */
rc = appDemoEventRequestDrvnModeInit();
/*
appDemoEventRequestDrvnModeInit() 定义如下:
GT_STATUS appDemoEventRequestDrvnModeInit
(
IN GT_VOID
)
{
GT_STATUS rc; /* The returned code */
GT_TASK eventHandlerTid; /* The task Tid */
GT_U32 i; /* Iterator */
GT_CHAR name[30]; /* The task/msgQ name */
GT_32 intKey; /* The interrupt lock key */
GT_U32 value;
unsigned (__TASKCONV *start_addr)(GT_VOID*);
CPSS_UNI_EV_CAUSE_ENT *evHndlrCauseAllArr[APP_DEMO_PROCESS_NUMBER];
GT_U32 evHndlrCauseAllArrSize[APP_DEMO_PROCESS_NUMBER];
/* Note - should be only static (global), cannot resides in stack! */
static EV_HNDLR_PARAM taskParamArr[APP_DEMO_PROCESS_NUMBER];
if (appDemoDbEntryGet("singleRxTask",&value) == GT_OK)
{
singleTaskRxEnable = (value == 1) ? GT_TRUE : GT_FALSE;
}
if (appDemoDbEntryGet("singleRxTaskRandom",&value) == GT_OK)
{
singleTaskRxRandomEnable = (value == 1) ? GT_TRUE : GT_FALSE;
}
/* set default arrays and sizes */
evHndlrCauseAllArr[0] = evHndlr0CauseDefaultArr;
evHndlrCauseAllArr[1] = evHndlr1CauseDefaultArr;
evHndlrCauseAllArr[2] = evHndlr2CauseDefaultArr;
evHndlrCauseAllArr[3] = evHndlr3CauseDefaultArr;
evHndlrCauseAllArr[4] = evHndlr4CauseDefaultArr;
evHndlrCauseAllArr[5] = evHndlr5CauseDefaultArr;
evHndlrCauseAllArr[6] = evHndlr6CauseDefaultArr;
evHndlrCauseAllArr[7] = evHndlr7CauseDefaultArr;
evHndlrCauseAllArr[8] = evHndlr8CauseDefaultArr;
evHndlrCauseAllArr[9] = evHndlr9CauseDefaultArr;
evHndlrCauseAllArrSize[0] = evHndlr0CauseDefaultArrSize;
evHndlrCauseAllArrSize[1] = evHndlr1CauseDefaultArrSize;
evHndlrCauseAllArrSize[2] = evHndlr2CauseDefaultArrSize;
evHndlrCauseAllArrSize[3] = evHndlr3CauseDefaultArrSize;
evHndlrCauseAllArrSize[4] = evHndlr4CauseDefaultArrSize;
evHndlrCauseAllArrSize[5] = evHndlr5CauseDefaultArrSize;
evHndlrCauseAllArrSize[6] = evHndlr6CauseDefaultArrSize;
evHndlrCauseAllArrSize[7] = evHndlr7CauseDefaultArrSize;
evHndlrCauseAllArrSize[8] = evHndlr8CauseDefaultArrSize;
evHndlrCauseAllArrSize[9] = evHndlr9CauseDefaultArrSize;
/* override defaults */
#ifdef SHARED_MEMORY
if(multiProcessAppDemo == 1)
{
evHndlrCauseAllArrSize[1] = 0;
evHndlrCauseAllArrSize[2] = 0;
evHndlrCauseAllArrSize[3] = 0;
evHndlrCauseAllArrSize[4] = 0;
evHndlrCauseAllArrSize[5] = 0;
evHndlrCauseAllArrSize[6] = 0;
evHndlrCauseAllArrSize[7] = 0;
evHndlrCauseAllArrSize[8] = 0;
}
else
#endif
if (singleTaskRxEnable == GT_TRUE)
{
evHndlrCauseAllArrSize[1] = evHndlrCauseAllArrSize[2] = evHndlrCauseAllArrSize[3] =
evHndlrCauseAllArrSize[4] = evHndlrCauseAllArrSize[5] = 0;
evHndlrCauseAllArr[APP_DEMO_SINGLE_RX_TASK_NUMBER] = evHndlr6CauseSingleTaskRxArr;
evHndlrCauseAllArrSize[APP_DEMO_SINGLE_RX_TASK_NUMBER] = evHndlr6CauseSingleTaskRxArrSize;
}
{
/* silent the next events that are part of the ' controlled learning' .
this event cause when we add/delete mac from the FDB and the FDB notify
us , that the action done ,
we get those from 4 port groups and it slows the operations */
if (appDemoPpConfigList[SYSTEM_DEV_NUM_MAC(0)].devFamily ==
CPSS_PP_FAMILY_DXCH_LION_E)
{
for(i = 0 ; i < evHndlrCauseAllArrSize[0];i++)
{
if(evHndlr0CauseDefaultArr[i] == CPSS_PP_MAC_NA_LEARNED_E)
{
evHndlr0CauseDefaultArr[i] = evHndlr0CauseDefaultArr[evHndlrCauseAllArrSize[0] - 1];
break;
}
}
if(i != evHndlrCauseAllArrSize[0])
{
/* we removed CPSS_PP_MAC_NA_LEARNED_E */
/* so need to decrement the number of elements */
evHndlrCauseAllArrSize[0] --;
}
}
}
/* Get event increment CB routine. */
wrCpssGenEventCountersCbGet(&eventIncrementFunc);
INT_LOCK(intKey);
for (i = 0; i < APP_DEMO_PROCESS_NUMBER; i++)
{
if(evHndlrCauseAllArrSize[i] == 0 || evHndlrCauseAllArr[i][0] == CPSS_UNI_RSRVD_EVENT_E)
continue;
taskParamArr[i].hndlrIndex = i;
DBG_LOG(("appDemoEventRequestDrvnModeInit: subscribed group #%d for %d events\n", i, evHndlrCauseAllArrSize[i], 3, 4, 5, 6));
/* call CPSS to bind the events under single handler */
rc = cpssEventBind(evHndlrCauseAllArr[i],
evHndlrCauseAllArrSize[i],
&taskParamArr[i].evHndl);
…
/* call the CPSS to enable those interrupts in the HW of the device */
rc = prvUniEvMaskAllSet(evHndlrCauseAllArr[i],
evHndlrCauseAllArrSize[i],
CPSS_EVENT_UNMASK_E);
…
}
INT_UNLOCK(intKey);
if (singleTaskRxEnable == GT_TRUE)
{
for (i = 0; i < treatTasksNum; i++)
{
/* create msgQ */
osSprintf(name, "msgQ_%d", i);
rc = cpssOsMsgQCreate(name,APP_DEMO_MSGQ_SIZE,
sizeof(APP_DEMO_RX_PACKET_PARAMS),
&(singleRxMsgQIds[i]));
…
rc = cpssOsMutexCreate("rxMutex",&rxMutex);
…
/* spawn rx treat task */
osSprintf(name, "treatRx_%d", i);
rc = osTaskCreate(name,
EV_HANDLER_MAX_PRIO - APP_DEMO_SINGLE_RX_TASK_NUMBER - 1,
_8KB,
appDemoSingleRxTreatTask,
&(singleRxMsgQIds[i]),
&eventHandlerTid);
...
}
}
/* spawn all the event handler processes */
for (i = 0; i < APP_DEMO_PROCESS_NUMBER; i++)
{
if(evHndlrCauseAllArrSize[i] == 0 || evHndlrCauseAllArr[i][0] == CPSS_UNI_RSRVD_EVENT_E)
continue;
osSprintf(name, "evHndl_%d", i);
if (singleTaskRxEnable == GT_TRUE && i == APP_DEMO_SINGLE_RX_TASK_NUMBER)
{
start_addr = appDemoSingleRxEvHndlr;
}
else
{
start_addr = appDemoEvHndlr;
}
rc = osTaskCreate(name,
EV_HANDLER_MAX_PRIO - i,
_8KB,
start_addr,
&taskParamArr[i],
&eventHandlerTid);
...
}
return GT_OK;
}
*/
...
}
}
systemInitialized = GT_TRUE;
…..
}