对qmgr的整体理解:
其中包括3个核心数据结构,包括硬件队列读写信息结构、配置信息结构、dispatch信息结构。分别对应3个初始化过程ixQMgrHwQIfInit(), ixQMgrInit(), ixQMgrDispatcherInit()。
通过函数ixQMgrDispatcherLoopRunB0()来轮询所有的队列,
函数调用关系ixEthAccQMgrQueuesConfig(portID)->ixEthAccQMgrQueueSetup(qInfoDes)->ixQMgrNotificationCallbackSet()会把网卡收发数据相关的队列配置信息都配置好。如果要查看某个队列对应的callback函数,应该到函数ixEthAccQMgrQueuesConfig()中去找,而这个函数有依赖于结构
i).tx队列对应的函数为ixEthTxFrameQMCallback(),,对应的callbackID是portID。因为该队列设置为每个npe一个Tx队列,因此,参数是有用的。
ii). txDone队列对应的函数为ixEthTxFrameDoneQMCallback,对应callbackID为portID;然后通过数据结构IxEthAccPortDataInfo机制来调用函数npe_tx_callback()
iii).RxFree队列对应的函数为ixEthRxFreeQMCallback(),对应的CallbackID是portID;因为该队列设置为每个npe一个RxFree队列,因此,参数是有用的。
iv). Rx队列对应的函数为ixEthRxFrameQMCallback,对应的CallbackID是portID; 在通过数据结构ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn的机制调用函数npe_rx_callback(),
qmgr的队列默认设置为IX_QMGR_DISPATCHER_POLLING_MODE,
现在发现的队列对应关系:Rx Free NPEA 26,npeB 27,npeC 28;Tx frame npeA 23,npeB 24,npeC 25; Tx done queue for all 31(即3个npe使用一个队列表示txDone).
队列0~31的中断可以设为E,NE,F,NF状态,而队列32~63的中断只能设为NE状态;队列0~31的E,NE,F,NF状态位都可以观察到,而队列32~63只有NE,F状态位可以观察到。
一、文件IxQMgrHwQIfIxp400.c主要queue管理中和硬件相关的代码
1、全局变量
UINT32 hwQBaseAddress = 0;代表硬件队列的基地址
/* * This flag indicates to the dispatcher that sticky interrupts are currently enabled.
*/
extern BOOL stickyEnabled;
/* Store addresses and bit-masks for certain queue access and status registers.
* This is to facilitate inlining of QRead, QWrite and QStatusGet functions
* in IxQMgr,h
*/
extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
UINT32 * ixQMgrHwQIfQueAccRegAddr[IX_QMGR_MAX_NUM_QUEUES];//作为队列的访问地址
UINT32 ixQMgrHwQIfQueLowStatRegAddr[IX_QMGR_NUM_QUEUES_PER_GROUP];
UINT32 ixQMgrHwQIfQueLowStatBitsOffset[IX_QMGR_NUM_QUEUES_PER_GROUP];
UINT32 ixQMgrHwQIfQueLowStatBitsMask;
UINT32 ixQMgrHwQIfQueUppStat0RegAddr;
UINT32 ixQMgrHwQIfQueUppStat1RegAddr;
UINT32 ixQMgrHwQIfQueUppStat0BitMask[IX_QMGR_NUM_QUEUES_PER_GROUP];
UINT32 ixQMgrHwQIfQueUppStat1BitMask[IX_QMGR_NUM_QUEUES_PER_GROUP];
2. 函数
i).函数ixQMgrHwQIfInit()首先调用函数IX_OSAL_MEM_MAP()映射I/O缓冲区到内存地址,调用函数ixQMgrHwQIfRegistersReset()初始化所有的队列相关寄存器为复位值,接下来配置数组ixQMgrQInlinedReadWriteInfo[64]中的每一项的各个值,以方便访问。
i).函数ixQMgrHwQIfQInterruptEnable(qID)使能队列qID的中断掩码位
ii). 函数ixQMgrHwQIfInit()设置各个硬件访问地址变量的值,
函数ixQMgrQRead(qId,UINT32 *entry)从队列qID中读取一个entry。
函数ixQMgrHwQIfRegistersReset()把queue相关的寄存器设置为初始化时的值
函数ixQMgrHwQIfQPoke()往一个queue中写值,但不更新write pointer
二、文件IxQMgrQCfg.c
在对队列初始化时,除了waterMark以外,所有的配置项都只能设置一次,即只能在初始化时调用一次。
1. 函数ixQMgrQCfgInit (void)用于初始化队列的配置信息,首先初始化数组ixQMgrQInlinedReadWriteInfo[],接着调用函数ixQMgrHwQIfInit()设置各个硬件访问地址变量的值,并把queue相关的寄存器设置为初始化时的值;接着初始化数组cfgQueueInfo[64],表示未配置队列;,;接着设置freeSramAddress[blockIndex]为queue内部sram的基地址值。而数组freeSramAddress[blockIndex]只有一项,就是sram的基地址(可以不考虑其中的机制)。
2. 函数ixQMgrQConfig (char *qName,IxQMgrQId qId,IxQMgrQSizeInWords qSizeInWords, IxQMgrQEntrySizeInWords qEntrySizeInWords)会设置队列qID的配置信息。首先调用函数ixQMgrHwQIfQueCfgWrite(qID,qSizeInWords,qEntrySizeInWords,freeSramAddress)把配置信息写入寄存器和把队列在sram中的地址写入寄存器,然后设置变量freeSramAddress[0]的值(注意一个误区:各个qID在sram中设置的空间,并不是顺序的,即队列2在sram中的内容不一定比队列23在sram中的内容靠前),然后设置数组项ixQMgrQInlinedReadWriteInfo[qID]和cfgQueueInfo[qID]
3.函数ixQMgrHwQIfQueCfgWrite(qID,qSizeInWords,qEntrySizeInWords,freeSramAddress)把配置信息写入寄存器和把队列在sram中的地址写入寄存器,
4.函数ixQMgrHwQIfRegistersReset()把队列的所有寄存器重置成复位值。
三、文件IxQMgrInit.c
1. 函数ixQMgrInit(),qmgr组件的初始化函数。首先调用函数ixQMgrQCfgInit()初始化队列的配置信息;调用函数ixQMgrDispatcherInit()初始化队列的分配dispatcher;调用函数ixQMgrQAccessInit()初始化访问组件(该函数是一个空函数)。