📄 gei82543end.c
字号:
return ERROR;
}
DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndStart...\n", 1, 2, 3, 4, 5, 6);
if (pDrvCtrl->attach != TRUE)
{
DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndStart...driver not load\n", 1, 2, 3, 4, 5, 6);
return ERROR;
}
/* make sure the device start only once*/
if (pDrvCtrl->devStartFlag == TRUE)
{
DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndStart:Driver has been started!\n", 1, 2,3, 4, 5, 6);
return OK;
}
/* stop/reset the chip before configuration */
gei82543Reset (pDrvCtrl);
/*decide the card type*/
if(gei82545IsFx(slot))
{
if(ERROR==gei82543TBIModeSet(slot))
{
DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndStart:Init 82543 Serdes fail!\n",
1, 2, 3, 4, 5, 6);
return ERROR;
}
}
/* disable all chip interrupts */
gei82543DisableChipInt (pDrvCtrl);
/* initialize SW/HW structures for TX */
DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndStart: set up TX structure\n",
1, 2, 3, 4, 5, 6);
gei82543TxSetup (pDrvCtrl);
/* initialize SW/HW structure for RX */
DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndStart: set up RX structure\n",
1, 2, 3, 4, 5, 6);
gei82543RxSetup (pDrvCtrl);
/* turn off system interrupts */
b_pciUnitIntDisable((UINT8)pDrvCtrl->drvObj.slot);
/* initialize the hardware and set up link */
if (OK!= gei82543HwInit (pDrvCtrl) )
{
DRV_LOG (DRV_DEBUG_LOAD, ("gei82543EndStart: link setup fails\n"),
1, 2, 3, 4, 5, 6);
LOGMSG("link fails\n", 1, 2, 3, 4, 5, 6);
}
/* disable TX/RX now */
gei82543TxRxDisable (pDrvCtrl);
/* configure devices */
DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndStart: configure device\n",
1, 2, 3, 4, 5, 6);
gei82543EndConfigure (pDrvCtrl);
/* connect interrupt handler */
DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndStart: Connect interrupt\n",
1, 2, 3, 4, 5, 6);
b_pciUnitIntConnect((UINT8)pDrvCtrl->drvObj.slot, (VOIDFUNCPTR)gei82543EndInt, (int)pDrvCtrl);
/* clean up all statistic registers */
gei82543HwStatusDump (pDrvCtrl);
/* clean all pending interrupts */
gei82543DisableChipInt (pDrvCtrl);
/* turn on system interrupt */
b_pciUnitIntEnable((UINT8)pDrvCtrl->drvObj.slot);
/* enable interrupt in chip level */
gei82543EnableChipInt (pDrvCtrl);
DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndStart: Interrupt enable\n",
1, 2, 3, 4, 5, 6);
gei82543EndConfigure (pDrvCtrl);
/* wait for chip to settle down */
taskDelay (sysClkRateGet () / 20);
/* check link status again before really start */
if (gei82543linkStatusCheck (pDrvCtrl) != OK)
{
LOGMSG("gei82543EndStart:Link is down \n", 1, 2, 3, 4, 5, 6);
}
/* set the device start flag */
pDrvCtrl->devStartFlag = TRUE;
/* enable TX and RX operation */
gei82543TxRxEnable (pDrvCtrl);
DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndStart...Done\n", 1, 2, 3, 4, 5, 6);
return (OK);
}
/*************************************************************************
*
* gei82543EndInt - handle 82543 chip interrupt event
*
* This routine is called at interrupt level in response to an interrupt from
* the controller.
*
* RETURNS: N/A.
*/
LOCAL void gei82543EndInt
(
END_DEVICE * pDrvCtrl /* device to handle interrupt */
)
{
UINT32 stats; /* cause of interrupt */
/*UINT32 statusRegVal; status register value */
UINT32 intTypeChk;
DRV_CHG_CNT(pDrvCtrl->totalIntNum,1); /*statis total number*/
DRV_LOGMSG (DRV_DEBUG_INT, "gei82543EndInt ...\n", 1, 2, 3, 4, 5, 6);
if((END_DEVICE *)NULL==pDrvCtrl)
{
return (void)ERROR;
}
/* read the device status register */
GEI_READ_REG(INTEL_82543GC_ICR, stats);
stats &= INTEL_82543GC_VALID_INT;
/* return if not interrupt for this device */
if (0 ==stats )
{
DRV_LOGMSG (DRV_DEBUG_INT, "gei82543EndInt: PCI interrupt is not "
"caused by this GEI device\n", 1, 2, 3, 4, 5, 6);
return;
}
/* handle link interrupt event */
if (stats & INT_LINK_CHECK)
{
DRV_LOGMSG (DRV_DEBUG_INT, "gei82543EndInt: get a Link problem\n",
1, 2, 3, 4, 5, 6);
if(OK==fwdJobAdd((FUNCPTR)gei82543LinkIntHandle, (int)pDrvCtrl, 0, 0,0,0))
{
/*disable link change interrupt*/
GEI_WRITE_REG(INTEL_82543GC_IMC, (UINT32)AVAIL_LINK_INT); /*lint !e572*/
}
else
{
DRV_LOGMSG(DRV_DEBUG_INT,"Cannot add job (geiLink82543IntHandle) to Forward task ring!\n",0,0,0,0,0,0);
DRV_CHG_CNT(pDrvCtrl->linkJobAddErr,1);
GEI_WRITE_REG(INTEL_82543GC_IMS, (UINT32)AVAIL_LINK_INT); /*lint !e572*/
}
}
if (stats & INT_RXTO_BIT)
{
pDrvCtrl->rxTimerIntCount++;
}
if (stats & INT_RXO_BIT)
{
pDrvCtrl->rxORunIntCount++;
}
/* tNetTask handles RX/TX interrupts */
intTypeChk = INT_RXDMT0_BIT | INT_RXO_BIT |INT_RXTO_BIT;
if ((stats & (intTypeChk)) && (pDrvCtrl->rxtxHandling != TRUE))
{
/* disable receive / transmit interrupt */
GEI_WRITE_REG(INTEL_82543GC_IMC, intTypeChk);
/*
* NOTE: Read back any chip register to flush PCI
* bridge write buffer in case this adaptor is behind
* a PCI bridge.
*/
CACHE_PIPE_FLUSH ();/*lint !e522*/
GEI_READ_REG(INTEL_82543GC_IMS, stats);
/* defer the handling ... */
if (OK == fwdJobAdd ((FUNCPTR) gei82543RxIntHandle, (int)pDrvCtrl, 0, 0, 0, 0))
{
pDrvCtrl->rxtxHandling = TRUE;
}
else
{
DRV_LOGMSG(DRV_DEBUG_INT,"Cannot add job (gei82543RxIntHandle) to Forward task ring!\n",0,0,0,0,0,0);
DRV_CHG_CNT(pDrvCtrl->rxJobAddErr,1);
pDrvCtrl->rxtxHandling = FALSE;
GEI_WRITE_REG(INTEL_82543GC_IMS, intTypeChk);
}
}
DRV_LOGMSG (DRV_DEBUG_INT, "gei82543EndInt...Done\n", 1, 2, 3, 4, 5, 6);
return (void)NULL;
}
/*************************************************************************
*
* gei82543LinkIntHandle - handle the ling interrupt if needed
*
* This routine checks the status of the link,if the link status changes ,send the status
* RETURN: N/A
*/
LOCAL void gei82543LinkIntHandle ( END_DEVICE * pDrvCtrl )
{
int portNo;
UINT32 statusRegVal;
portNo=1;
if((END_DEVICE *)NULL==pDrvCtrl)
{
return (void)ERROR;
}
DRV_LOG (DRV_DEBUG_INT, "gei82543LinkIntHandle...\n", 1, 2, 3, 4, 5, 6);
DRV_CHG_CNT(pDrvCtrl->linkIntCount,1); /*statis link interrupt number*/
DRV_LOGMSG (DRV_DEBUG_INT, "gei82543LinkEndInt ...Copper!\n", 1, 2, 3, 4, 5, 6);
/* link status change, get status register */
GEI_READ_REG(INTEL_82543GC_STATUS, statusRegVal);
/*Link Up*/
if (statusRegVal & STATUS_LU_BIT)
{
Ros_PortStateSend(pDrvCtrl->drvObj.slot, portNo, 1);
}
else /*link down*/
{
Ros_PortStateSend(pDrvCtrl->drvObj.slot,portNo, 0);
}
/*Enable Link change interrupt*/
GEI_WRITE_REG(INTEL_82543GC_IMS, (UINT32)AVAIL_LINK_INT);/*lint !e572*/
DRV_LOG (DRV_DEBUG_INT, "gei82543LinkIntHandle...Done\n",
1, 2, 3, 4, 5, 6);
return;
}
/*************************************************************************
*
* gei82543RxTxIntHandle - receive/transmit interrupt handle in task mode
*
* This routine gets the receive packet and pass them to upper network stack.
* It also cleans up TX descriptor if necessary.
*
* RETURNS: N/A.
*/
LOCAL void gei82543RxIntHandle
(
END_DEVICE * pDrvCtrl /* device to handle RX/TX */
)
{
UINT32 rxCountPerInt = 0; /* maximum RX descriptors to handle a int */
UINT32 retry = 0; /* retry count */
char * pRxDesc; /* RX descriptor pointer */
UINT32 stats; /* cause of interrupt */
UINT8 rxdStat; /* status of recv descriptor */
UINT32 ims;
DRV_LOG (DRV_DEBUG_RX, "gei82543RxIntHandle...\n", 1, 2, 3, 4, 5, 6);
DRV_CHG_CNT(pDrvCtrl->rxIntCount,1); /*statis rx number*/
do
{
while (rxCountPerInt++ < (UINT32)pDrvCtrl->maxRxNumPerInt)
{
/* get the current RX descriptor */
pRxDesc = GEI_GET_RX_DESC_ADDR(pDrvCtrl->rxDescTail);
/* check RX descriptor status */
rxdStat = GEI_READ_DESC_BYTE(pRxDesc,RXDESC_STATUS_OFFSET);
if ((rxdStat & RXD_STAT_DD) == 0)
{
DRV_LOG (DRV_DEBUG_RX, "gei82543RxIntHandle: Hardware doesn't done with the Descriptor!\n", 1, 2, 3, 4, 5, 6);
DRV_CHG_CNT(pDrvCtrl->rxDesDoneErr,1);
break;
}
/* process an incoming packet */
if (gei82543Recv (pDrvCtrl, pRxDesc, rxdStat) != OK)
{
DRV_LOG (DRV_DEBUG_RX, "gei82543RxIntHandle: Receiving Fails!\n", 1, 2, 3, 4, 5, 6);
DRV_CHG_CNT(pDrvCtrl->recvPktFailNum,1);
break;
}
}
if (retry++ == 2 || rxCountPerInt >= (UINT32)pDrvCtrl->maxRxNumPerInt)
{
DRV_LOG (DRV_DEBUG_RX, "gei82543RxIntHandle:Retry Receiving Fails!\n", 1, 2, 3, 4, 5, 6);
DRV_CHG_CNT(pDrvCtrl->recvRetryFailNum,1);
break;
}
GEI_READ_REG(INTEL_82543GC_ICR, stats);
} while (stats & AVAIL_RX_INT);
/* handle case that TX stalls, free mBlks if desired */
/*MGEO TX doesnot use interrupt */
/*gei82543TxStallCheck (pDrvCtrl);*/
pDrvCtrl->rxtxHandling = FALSE;
/* enable RX/TX interrupts */
ims = AVAIL_RX_INT;
pDrvCtrl->rxtxHandlerNum++;
/*Enable Rx interrupt*/
GEI_WRITE_REG(INTEL_82543GC_IMS, ims);
CACHE_PIPE_FLUSH (); /*lint !e522*/
DRV_LOG (DRV_DEBUG_RX, "gei82543RxIntHandle...Done\n",
1, 2, 3, 4, 5, 6);
return;
}
/*************************************************************************
* gei82545EndIoctl - interface ioctl procedure
*
* Process an interface ioctl request.
*
* RETURNS: OK, or ERROR if the config command failed.
*/
int gei82545EndIoctl
( UINT32 gPort,
int cmd,
char* data
)
{
int slot;
int error=OK;
UINT32 statusregval;
END_DEVICE * pDrvCtrl;
int reconfig=0;
int datatmp;
DRV_LOG (DRV_DEBUG_IOCTL, ("IOCTL command begin\n"), 0,0,0,0,0,0);
slot=Ros_LocalPanel(gPort);
datatmp=(int)data;
if (slot<1||slot >MAX_IF_CARD_NUM)
{
return ERROR;
}
pDrvCtrl = geiEndDevice[slot];
if ((END_DEVICE *)NULL==pDrvCtrl )
{
return ERROR;
}
switch ((UINT32) cmd)
{
case DRV_GET_LINK_STATE:
case DRV_GET_TYPE_INFO:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -