📄 le1vefpgadma.c
字号:
char *pMem;
int descSize, loop;
LE1VE_RMD *pRmd;
/*
* |-------------------------------------|
* | The Rx descriptors |
* | (1<< le1veRsize)*sizeof(LE1VE_RMD) |
* |-------------------------------------|
* | The Tx descriptors |
* | (1<< le1veTsize)*sizeof(LE1VE_TMD) |
* |-------------------------------------|
*/
descSize = (1 << DMA_DES_RING_SIZE) * sizeof (LE1VE_RMD) +
(1 << DMA_DES_RING_SIZE) * sizeof (LE1VE_TMD) + 0x20;
if (NULL == (pMem = (char *)cacheDmaMalloc (descSize)))
return ERROR;
bzero(pMem, descSize);
pDrv->rmdIndex = 0; /* current RMD index */
pDrv->rringSize = (1 << DMA_DES_RING_SIZE); /* RMD ring size */
pDrv->rringLen = DMA_DES_RING_SIZE; /* RMD ring length (bytes) */
pDrv->pRring = (LE1VE_RMD *) (((int)pMem + 0x0f) & (~0x0f));
pDrv->tmdIndexC = 0;
pDrv->tmdIndex = 0; /* current RMD index */
pDrv->tringSize = (1 << DMA_DES_RING_SIZE); /* RMD ring size */
pDrv->tringLen = DMA_DES_RING_SIZE; /* RMD ring length (bytes) */
pDrv->pTring = (LE1VE_TMD *) (((int)pMem) + (1 << DMA_DES_RING_SIZE) * sizeof (LE1VE_RMD) + 0x10);
pDrv->pTring = (LE1VE_TMD *) (((int)pDrv->pTring + 0xf) & ~0xf);
pRmd = pDrv->pRring;
for (loop = 0; loop < pDrv->rringSize; loop++, pRmd++)
{
if ((pBuf = (char *)endPktAlloc()) == NULL)
{
printf("le1veMemInit: Could not get a buffer\n");
taskSuspend(0);
while (loop > 0)
{
pBuf = (char *)Drv_Swap32(mapPhysToVirt((UINT32)pRmd->RMD1));
if (NULL != pBuf)
endPktFree(pBuf);
loop --;
pRmd --;
}
cacheDmaFree(pMem);
return (ERROR);
}
pRmd->RMD1 = Drv_Swap32(mapVirtToPhys((UINT32)pBuf));
}
return OK;
}
/*------------------------------
* le1veMemConfig - config memory
*
* Argument: LE1VE_PCI_DRV_CTRL *pDrv - pointer to the LE1VE PCI Device
*
* 针对重启的情况在不改变表的情况下 清空表的内容并对pDrv中做相应的处理
* clean Tmd before changing tmdIndex and tmdIndexC
*
* RETURNS: OK or ERROR.
*/
LOCAL STATUS le1veMemConfig(LE1VE_PCI_DRV_CTRL *pDrv)
{
void **pParm;
int oldLevel;
while (pDrv->tmdIndexC != pDrv->tmdIndex)
{
oldLevel = intLock();
pParm = &(pDrv->freeData [pDrv->tmdIndexC].arg2);
if (*pParm != NULL)
{
endPktFree(*pParm);
pDrv->freeData [pDrv->tmdIndexC].arg1 = NULL;
pDrv->freeData [pDrv->tmdIndexC].arg2 = NULL;
}
intUnlock(oldLevel);
pDrv->tmdIndexC = (pDrv->tmdIndexC + 1) & (pDrv->tringSize - 1);
} /* end while */
/*初始化RX与TX描述符中的内容*/
cleanRmd(pDrv);
cleanTmd(pDrv);
/* Point the device to the initialization block */
/*write tx and rx bd table base to fpga*/
pDrv->pMem->rxDescBase = Drv_Swap32(mapVirtToPhys((UINT32)pDrv->pRring));
pDrv->pMem->txDescBase = Drv_Swap32(mapVirtToPhys((UINT32)pDrv->pTring));
/*write bd table size to fpga */
pDrv->pMem->descNum= Drv_Swap32(pDrv->rringSize);
return OK;
}
/*------------------------------
* cleanRmd - 清空接收BD表
*
* Argument:
* LE1VE_PCI_DRV_CTRL *pDrv - pointer to the LE1VE PCI Device
*
* RETURNS: void.
*/
LOCAL void cleanRmd(LE1VE_PCI_DRV_CTRL *pDrv)
{
int loop;
LE1VE_RMD *pRmd;
pRmd = pDrv->pRring;
for (loop = 0; loop < pDrv->rringSize; loop++, pRmd++)
LE1VE_CLEAN_RXD (pRmd);
pDrv->rmdIndex = 0;
}
/*------------------------------
* cleanTmd - 清空发送BD表
*
* Argument:
* LE1VE_PCI_DRV_CTRL *pDrv - pointer to the LE1VE PCI Device
*
* RETURNS: void.
*/
LOCAL void cleanTmd(LE1VE_PCI_DRV_CTRL *pDrv)
{
int loop;
LE1VE_TMD *pTmd;
pTmd = pDrv->pTring;
for (loop = 0; loop < pDrv->tringSize; loop++, pTmd++)
{
/* no message byte count yet */
LE1VE_TMD_CLR_ERR(pTmd);
}
pDrv->tmdIndex = 0;
pDrv->tmdIndexC = 0;
}
/*------------------------------
* le1veFpgaPciDevModInit - 预初始化LE1VE的PCI控制器
*
* Argument:
* void
*
* RETURNS: void.
*/
LOCAL void le1veFpgaPciDevModInit(void)
{
UINT32 dBaseAddress;
int nextDev, slot;
int BusNo,DeviceNo,FuncNo;
LE1VE_PCI_DRV_CTRL *pDrv;
for(nextDev=0; nextDev < LE1VE_PCI_MAX_NUM; nextDev++)
{
if (OK == pciFindDevice (LE1VE_VENDOR_ID, LE1VE_DEVICE_ID, nextDev, &BusNo, &DeviceNo, &FuncNo))
{
/*配置PCI设备,标准配置*/
pciConfigOutWord(BusNo, DeviceNo, 0, PCI_CFG_COMMAND_OFFSET, PCI_CFG_CMD_MEM_ENABLE | PCI_CFG_CMD_MASTER_ENABLE );
/* Get the base address from the corresponding register */
if (pciConfigInLong(BusNo, DeviceNo, FuncNo, PCI_MEM_BASE_OFFSET, &dBaseAddress) != OK)
{
printf("pciConfigInLong Error!\n");
return ;
}
dBaseAddress &=PCI_MEM_BASE_MASK;
#if INSTALL_ON_IXP1200
dBaseAddress += 0x60000000;
#endif
/*switch DeviceNo to slot Num 由底层提供*/
if (OK == b_ifPciIDToUnitNum(BusNo, DeviceNo,&slot))
{
if (NULL != (gpLe1veDrvCtrl[slot - 1] = (LE1VE_PCI_DRV_CTRL *)malloc(sizeof(LE1VE_PCI_DRV_CTRL))))
{
pDrv = gpLe1veDrvCtrl[slot - 1];
bzero ((char *)pDrv, sizeof(LE1VE_PCI_DRV_CTRL));
pDrv->deviceId = LE1VE_DEVICE_ID;
pDrv->vendorId = LE1VE_VENDOR_ID;
pDrv->busNo = BusNo;
pDrv->devNo = DeviceNo;
pDrv->functionNo = FuncNo;
pDrv->uintNo = nextDev;
pDrv->slotNo = slot;
pDrv->cpuMemBase = IF_CARD_CPU_REG_BASE(slot);
pDrv->pMem = (LE1VE_PCI_MEM_MAP *)dBaseAddress;
pDrv->TxSemaphore = semBCreate (SEM_Q_FIFO, SEM_FULL);
if (NULL == pDrv->TxSemaphore)
taskSuspend(0);
}
}
}
}
return ;
}
/*------------------------------
* le1ve_miiCtrlCrcCfg - config MII control register CRC operation
*
* Argument:
*
* LE1VE_PCI_DRV_CTRL *pDrv - pointer to the LE1VE PCI Device
* int value - LE1VE_CTRL_CRC_ENABLE or ~LE1VE_CTRL_CRC_ENABLE
*
* RETURNS: void.
*/
void le1ve_miiCtrlCrcCfg(LE1VE_PCI_DRV_CTRL *pDrv, int mode)
{
UINT32 value;
LE1VE_MII_CTRL_RD(pDrv, LE1VE_MII_CONTROL_REG, &value);
value &= (~LE1VE_CTRL_CRC_ENABLE);
value = value | (mode & LE1VE_CTRL_CRC_ENABLE);
LE1VE_MII_CTRL_WR(pDrv, LE1VE_MII_CONTROL_REG, value);
}
/*------------------------------
* le1ve_miiCtrlLoopBackCfg - config MII control register loop back operation
*
* Argument:
*
* LE1VE_PCI_DRV_CTRL *pDrv - pointer to the LE1VE PCI Device
* int value - LE1VE_CTRL_LOOP_BACK or ~LE1VE_CTRL_LOOP_BACK
*
* RETURNS: void.
*/
void le1ve_miiCtrlLoopBackCfg(LE1VE_PCI_DRV_CTRL *pDrv, int mode)
{
UINT32 value;
LE1VE_MII_CTRL_RD(pDrv, LE1VE_MII_CONTROL_REG, &value);
value &= (~LE1VE_CTRL_LOOP_BACK);
value = value | (mode & LE1VE_CTRL_LOOP_BACK);
LE1VE_MII_CTRL_WR(pDrv, LE1VE_MII_CONTROL_REG, value);
}
/*------------------------------
* le1ve_miiCtrlRxCfg - config MII control register Rx operation
*
* Argument:
*
* LE1VE_PCI_DRV_CTRL *pDrv - pointer to the LE1VE PCI Device
* int value - LE1VE_CTRL_RX_ENABLE or ~LE1VE_CTRL_RX_ENABLE
*
* RETURNS: void.
*/
void le1ve_miiCtrlRxCfg(LE1VE_PCI_DRV_CTRL *pDrv, int mode)
{
UINT32 value;
LE1VE_MII_CTRL_RD(pDrv, LE1VE_MII_CONTROL_REG, &value);
value &= (~LE1VE_CTRL_RX_ENABLE);
value = value | (mode & LE1VE_CTRL_RX_ENABLE);
LE1VE_MII_CTRL_WR(pDrv, LE1VE_MII_CONTROL_REG, value);
}
/*------------------------------
* le1ve_miiCtrlTxCfg - config MII control register Rx operation
*
* Argument:
*
* LE1VE_PCI_DRV_CTRL *pDrv - pointer to the LE1VE PCI Device
* int value - LE1VE_CTRL_TX_ENABLE or ~LE1VE_CTRL_TX_ENABLE
*
* RETURNS: void.
*/
void le1ve_miiCtrlTxCfg(LE1VE_PCI_DRV_CTRL *pDrv, int mode)
{
UINT32 value;
LE1VE_MII_CTRL_RD(pDrv, LE1VE_MII_CONTROL_REG, &value);
value &= (~LE1VE_CTRL_TX_ENABLE);
value = value | (mode & LE1VE_CTRL_TX_ENABLE);
LE1VE_MII_CTRL_WR(pDrv, LE1VE_MII_CONTROL_REG, value);
}
/*------------------------------
* le1ve_miiCtrlResetCfg - config MII Reset port
*
* Argument:
*
* LE1VE_PCI_DRV_CTRL *pDrv - pointer to the LE1VE PCI Device
* int value - LE1VE_CTRL_PORT_RESET or ~LE1VE_CTRL_PORT_RESET
*
* RETURNS: void.
*/
void le1ve_miiCtrlReset(LE1VE_PCI_DRV_CTRL *pDrv)
{
UINT32 value;
LE1VE_MII_CTRL_RD(pDrv, LE1VE_MII_CONTROL_REG, &value);
value &= (~LE1VE_CTRL_PORT_RESET);
value |= LE1VE_CTRL_PORT_RESET;
LE1VE_MII_CTRL_WR(pDrv, LE1VE_MII_CONTROL_REG, value);
value &= (~LE1VE_CTRL_PORT_RESET);
LE1VE_MII_CTRL_WR(pDrv, LE1VE_MII_CONTROL_REG, value);
}
/*------------------------------
* le1ve_miiCtrlPreamCfg - config MII control register preamble operation
*
* Argument:
*
* LE1VE_PCI_DRV_CTRL *pDrv - pointer to the LE1VE PCI Device
* int value - LE1VE_CTRL_PREAM_ENABLE or ~LE1VE_CTRL_PREAM_ENABLE
*
* RETURNS: void.
*/
#if 0
void le1ve_miiCtrlPreamCfg(LE1VE_PCI_DRV_CTRL *pDrv, int mode)
{
UINT32 value;
LE1VE_MII_CTRL_RD(pDrv, LE1VE_MII_CONTROL_REG, &value);
value &= (~LE1VE_CTRL_PREAM_ENABLE);
value = value | (mode & LE1VE_CTRL_PREAM_ENABLE);
LE1VE_MII_CTRL_WR(pDrv, LE1VE_MII_CONTROL_REG, value);
}
#endif
/*------------------------------
* le1ve_miiCtrlFullDuplexCfg - config MII control register Full duplex operation
*
* Argument:
*
* LE1VE_PCI_DRV_CTRL *pDrv - pointer to the LE1VE PCI Device
* int value - LE1VE_CTRL_FULL_DUPLEX or ~LE1VE_CTRL_FULL_DUPLEX
*
* RETURNS: void.
*/
#if 0
void le1ve_miiCtrlFullDuplexCfg(LE1VE_PCI_DRV_CTRL *pDrv, int mode)
{
UINT32 value;
LE1VE_MII_CTRL_RD(pDrv, LE1VE_MII_CONTROL_REG, &value);
value &= (~LE1VE_CTRL_FULL_DUPLEX);
value = value | (mode & LE1VE_CTRL_FULL_DUPLEX);
LE1VE_MII_CTRL_WR(pDrv, LE1VE_MII_CONTROL_REG, value);
}
#endif
/*=============================Debug Code=============================*/
/*
0 - 不用读清0
1 - 读清0
*/
void showLe1veDmaStatis(int slot, int mode)
{
LE1VE_FPGA_DMA_STATIS statis;
if ((mode != 0) && (mode != 1))
{
printf("Mode Error!\n");
return;
}
if (slot <1 || slot > LE1VE_PCI_MAX_NUM)
{
printf("Slot Number Error!\n");
}
readFpgaDmaStatis(slot, mode, &statis);
printf("MiiRxCnt MiiRxErr MiiTxCnt MiiTxErr PciRxCnt PciRxErr PciTxCnt PciTxErr\n");
printf("%-9d %-9d %-9d %-9d %-9d %-9d %-9d %-9d \n\n",
statis.MiiRxCnt, statis.MiiRxErrCnt, statis.MiiTxCnt, statis.MiiTxErrCnt,
statis.PciRxCnt, statis.PciRxErrCnt, statis.PciTxCnt, statis.PciTxErrCnt);
}
/*
0 - 不用读清0
1 - 读清0
*/
void showLe1veCnt(int slot, int mode )
{
LE1VE_PCI_DRV_CTRL *pDrv;
pDrv = gpLe1veDrvCtrl[slot - 1];
if ((slot < 1) || (slot > LE1VE_PCI_MAX_NUM) ||
(pDrv == NULL))
{
DRV_LOG(DRV_DEBUG_TX, "%s: Error argument\n", __FUNCTION__, 2, 3, 4, 5, 6);
return ;
}
printf("this is the int count for LE1VE_PCI card in slotNo:%u \n",pDrv->slotNo);
printf("le1vePciInt =%u \n",pDrv->le1vePciInt);
printf("le1vePciRxInt =%u \n",pDrv->le1veRxInt);
printf("le1vePciTxInt =%u \n",pDrv->le1vePciTxInt);
printf("le1vePciRxFullInt =%u \n",pDrv->le1vePciRxFullInt);
printf("le1vePciTxEmptyInt =%u \n",pDrv->le1vePciTxEmptyInt);
printf("le1vePciRxMemErr =%u \n",pDrv->le1vePciRxMemErr);
printf("le1vePciTxMemErr =%u \n",pDrv->le1vePciTxMemErr);
printf("le1vePciResetInt =%u \n\n",pDrv->le1vePciResetInt);
printf("le1vePciRx = %u\n",pDrv->le1vepciRx);
printf("le1vePciTx = %u\n",pDrv->le1vepciTx);
printf("le1vePciTxNoTmd = %u\n",pDrv->le1vePciTxNoTmd);
printf("le1vePciRxErrorPkt = %u\n",pDrv->le1vePciRxErrorPkt);
printf("le1veErrorAddJob = %u\n",pDrv->le1veErrorAddJob);
printf("le1veErrorAlloc = %u\n",pDrv->le1veErrorAlloc);
if (mode == 1)
{
pDrv->le1vePciInt = 0;
pDrv->le1veRxInt = 0;
pDrv->le1vePciTxInt = 0;
pDrv->le1vePciRxFullInt = 0;
pDrv->le1vePciTxEmptyInt= 0;
pDrv->le1vePciRxMemErr = 0;
pDrv->le1vePciTxMemErr = 0;
pDrv->le1vePciResetInt = 0;
pDrv->le1vepciRx = 0;
pDrv->le1vepciTx = 0;
pDrv->le1vePciTxNoTmd = 0;
pDrv->le1vePciRxErrorPkt= 0;
pDrv->le1veErrorAddJob = 0;
pDrv->le1veErrorAlloc = 0;
}
}
#ifdef DEBUG_DRV_RCV_SND
void drv_le1ve_send_test(UINT32 gPort, int len, int pktCnt, int offset)
{
char *pBuf;
char *pTemp;
int loop;
if ((pktCnt <= 0) || (len <= offset))
{
printf("Error argument!\n");
return ;
}
while (pktCnt >0)
{
if((pTemp = (char *) endPktAlloc()) == NULL)
{
printf("Cannot alloc buffer!\n");
return ;
}
pBuf = pTemp;
for (loop = 0; loop < offset; loop ++)
pTemp ++;
*pTemp++ = 0x7e;
for(loop = 1; loop < (len - 1); loop ++)
{
if ((loop % 2) == 0)
*pTemp = loop;
else
*pTemp = loop;
pTemp ++;
}
*pTemp = 0x7e;
if (ERROR == le1veFpgaPciDevSend(gPort, pBuf + offset, len, pBuf))
{
if (NULL != pBuf)
endPktFree(pBuf);
printf("Tx ERROR!\n");
}
pktCnt --;
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -