📄 motcpmend.c
字号:
LOCAL STATUS motCpmInitMem/*wuta*/
(
END_CTRL * pDrvCtrl /* pointer to END_CTRL structure */
)
{
int counter;
FUNCPTR allocFunc;
void * pData;
char* pTmpBuf;
int numBuf;
/* Set up the structures to allow us to free data after sending it. */
#if 1
for (counter = 0; counter < pDrvCtrl->ether.txBdNum; counter++)
{
pDrvCtrl->freeRtn[counter] = NULL;
pDrvCtrl->freeData[counter].arg1 = NULL;
pDrvCtrl->freeData[counter].arg2 = NULL;
}
#endif
if (pDrvCtrl->bufBase == NONE)
{
/* We must allocate memory for buffer descriptors */
pData = NULL;
allocFunc = (FUNCPTR) cacheDmaMalloc;
}
else
{
/* Memory for buffer descriptors is already allocated */
pData = (void *) pDrvCtrl->bufBase;
allocFunc = NULL;
}
/*
* calculate the number of buffers we need :
* receive buffers + transmit buffers + loaner buffers (= L_POOL)
*/
/* if ((pDrvCtrl->endObject.pNetPool = (NET_POOL) malloc (sizeof(NET_POOL))) == NULL)
return (ERROR); /*wutao ADD*/
numBuf = /*pDrvCtrl->ether.rxBdNum + pDrvCtrl->ether.txBdNum + L_POOL*/500;
/* Use the MUX's memory manager to get our buffers. */
pDrvCtrl->endObject.pNetPool = &motCpmNetPool;
motClDescTbl[0].clNum = numBuf;
motClDescTbl[0].memSize = (numBuf * (FRAME_MAX_AL + sizeof (long)));
motMclBlkConfig.mBlkNum = 2 * numBuf;
motMclBlkConfig.clBlkNum = numBuf;
motMclBlkConfig.memSize = ((motMclBlkConfig.mBlkNum *
(MSIZE + sizeof (long))) +
(motMclBlkConfig.clBlkNum *
(CL_BLK_SZ + sizeof (long))));
if ((motMclBlkConfig.memArea = (char *) memalign (sizeof (long),
motMclBlkConfig.memSize))
== NULL)
return (ERROR);
motClDescTbl[0].memArea = (char *) cacheDmaMalloc(motClDescTbl[0].memSize);
if ((int)motClDescTbl[0].memArea == NULL)
{
MOTCPMLOGMSG (( "system memory unavailable\n", 1, 2, 3, 4, 5, 6));
return (ERROR);
}
if (netPoolInit(pDrvCtrl->endObject.pNetPool, &motMclBlkConfig,
&motClDescTbl[0], motClDescTblNumEnt, NULL) == ERROR)
{
MOTCPMLOGMSG(("Could not init buffering\n", 1, 2, 3, 4, 5, 6));
return (ERROR);
}
#if 1
/* Store the cluster pool id as others need it later. */
pDrvCtrl->pClPoolId = clPoolIdGet(pDrvCtrl->endObject.pNetPool,
FRAME_MAX_AL, FALSE);
for (counter = 0; counter < pDrvCtrl->ether.rxBdNum; counter++)
{
if ((pTmpBuf = (char *)netClusterGet(pDrvCtrl->endObject.pNetPool,
pDrvCtrl->pClPoolId)) == NULL)
{
return (ERROR);
}
pDrvCtrl->ether.rxBdBase[counter].dataPointer = (u_char *) pTmpBuf;
}
#endif
return (OK);
}
/*******************************************************************************
*
* motCpmEndStart - start the device
*
* This function initializes the device and calls BSP functions to connect
* interrupts and start the device running in interrupt mode.
*
* The complement of this routine is motCpmEndStop(). Once a unit is reset by
* motCpmEndStop(), it may be re-initialized to a running state by this routine.
*
* RETURNS: OK if successful, otherwise ERROR.
*/
LOCAL STATUS motCpmEndStart
(
END_CTRL * pDrvCtrl /* pointer to END_CTRL structure */
)
{
int counter;
u_char * enetAddr;
ETHER_MULTI * pCurr;
MOTCPMLOGMSG(("motCpmEndStart \n", 0, 0, 0, 0, 0, 0));
/* initialize flag(s) */
pDrvCtrl->polling = FALSE;
pDrvCtrl->txStop = FALSE;
pDrvCtrl->txCleaning = FALSE;
pDrvCtrl->txBlocked = FALSE;
/* set up transmit buffer descriptors */
pDrvCtrl->ether.pScc->param.tbase = (UINT16)
((UINT32) pDrvCtrl->ether.txBdBase & 0xffff);
pDrvCtrl->ether.pScc->param.tbptr = (UINT16)
((UINT32) pDrvCtrl->ether.txBdBase & 0xffff);
pDrvCtrl->ether.txBdNext = 0;
/* initialize each transmit buffer descriptor */
for (counter = 0; counter < pDrvCtrl->ether.txBdNum; counter++)
pDrvCtrl->ether.txBdBase[counter].statusMode = SCC_ETHER_TX_BD_I |
SCC_ETHER_TX_BD_PAD |
SCC_ETHER_TX_BD_L |
SCC_ETHER_TX_BD_TC;
/* set the last BD to wrap to the first */
pDrvCtrl->ether.txBdBase[(counter - 1)].statusMode |= SCC_ETHER_TX_BD_W;
/* set up receive buffer descriptors */
pDrvCtrl->ether.pScc->param.rbase = (UINT16)
((UINT32) pDrvCtrl->ether.rxBdBase & 0xffff);
pDrvCtrl->ether.pScc->param.rbptr = (UINT16)
((UINT32) pDrvCtrl->ether.rxBdBase & 0xffff);
pDrvCtrl->ether.rxBdNext = 0;
/* initialize each receive buffer descriptor */
for (counter = 0; counter < pDrvCtrl->ether.rxBdNum; counter++)
pDrvCtrl->ether.rxBdBase[counter].statusMode = SCC_ETHER_RX_BD_I |
SCC_ETHER_RX_BD_E;
/* set the last BD to wrap to the first */
pDrvCtrl->ether.rxBdBase[(counter - 1)].statusMode |= SCC_ETHER_RX_BD_W;
/* set SCC attributes to Ethernet mode */
pDrvCtrl->ether.pSccReg->gsmrl = SCC_GSMRL_ETHERNET | SCC_GSMRL_TPP_10 |
SCC_GSMRL_TPL_48 | SCC_GSMRL_TCI;
pDrvCtrl->ether.pSccReg->gsmrh = 0x0;
pDrvCtrl->ether.pSccReg->psmr = SCC_ETHER_PSMR_CRC |
SCC_ETHER_PSMR_NIB_22;
if (END_FLAGS_GET(&pDrvCtrl->endObject) & IFF_PROMISC)
pDrvCtrl->ether.pSccReg->psmr |= SCC_ETHER_PSMR_PRO;
pDrvCtrl->ether.pSccReg->dsr = 0xd555;
pDrvCtrl->ether.pScc->param.rfcr = 0x18; /* supervisor data access */
pDrvCtrl->ether.pScc->param.tfcr = 0x18; /* supervisor data access */
pDrvCtrl->ether.pScc->param.mrblr = FRAME_MAX_AL; /* max rx buffer size */
/* initialize parameter the SCC RAM */
((SCC_ETHER_PROTO *)pDrvCtrl->ether.pScc->prot)->c_pres = 0xffffffff;
((SCC_ETHER_PROTO *)pDrvCtrl->ether.pScc->prot)->c_mask = 0xdebb20e3;
((SCC_ETHER_PROTO *)pDrvCtrl->ether.pScc->prot)->crcec = 0x00000000;
((SCC_ETHER_PROTO *)pDrvCtrl->ether.pScc->prot)->alec = 0x00000000;
((SCC_ETHER_PROTO *)pDrvCtrl->ether.pScc->prot)->disfc = 0x00000000;
((SCC_ETHER_PROTO *)pDrvCtrl->ether.pScc->prot)->pads = 0x8888;
((SCC_ETHER_PROTO *)pDrvCtrl->ether.pScc->prot)->ret_lim = 0x000f;
((SCC_ETHER_PROTO *)pDrvCtrl->ether.pScc->prot)->mflr = FRAME_MAX;
((SCC_ETHER_PROTO *)pDrvCtrl->ether.pScc->prot)->minflr = FRAME_MIN;
((SCC_ETHER_PROTO *)pDrvCtrl->ether.pScc->prot)->maxd1 = FRAME_MAX;
((SCC_ETHER_PROTO *)pDrvCtrl->ether.pScc->prot)->maxd2 = FRAME_MAX;
((SCC_ETHER_PROTO *)pDrvCtrl->ether.pScc->prot)->gaddr1 = 0x0000;
((SCC_ETHER_PROTO *)pDrvCtrl->ether.pScc->prot)->gaddr2 = 0x0000;
((SCC_ETHER_PROTO *)pDrvCtrl->ether.pScc->prot)->gaddr3 = 0x0000;
((SCC_ETHER_PROTO *)pDrvCtrl->ether.pScc->prot)->gaddr4 = 0x0000;
((SCC_ETHER_PROTO *)pDrvCtrl->ether.pScc->prot)->p_per = 0x0000;
((SCC_ETHER_PROTO *)pDrvCtrl->ether.pScc->prot)->iaddr1 = 0x0000;
((SCC_ETHER_PROTO *)pDrvCtrl->ether.pScc->prot)->iaddr2 = 0x0000;
((SCC_ETHER_PROTO *)pDrvCtrl->ether.pScc->prot)->iaddr3 = 0x0000;
((SCC_ETHER_PROTO *)pDrvCtrl->ether.pScc->prot)->iaddr4 = 0x0000;
((SCC_ETHER_PROTO *)pDrvCtrl->ether.pScc->prot)->taddr_h = 0x0000;
((SCC_ETHER_PROTO *)pDrvCtrl->ether.pScc->prot)->taddr_m = 0x0000;
((SCC_ETHER_PROTO *)pDrvCtrl->ether.pScc->prot)->taddr_l = 0x0000;
/* set the hardware Ethernet address of the board */
enetAddr = END_HADDR(&pDrvCtrl->endObject);
((SCC_ETHER_PROTO *)pDrvCtrl->ether.pScc->prot)->paddr1_h =
(enetAddr[5] << 8) + enetAddr[4];
((SCC_ETHER_PROTO *)pDrvCtrl->ether.pScc->prot)->paddr1_m =
(enetAddr[3] << 8) + enetAddr[2];
((SCC_ETHER_PROTO *)pDrvCtrl->ether.pScc->prot)->paddr1_l =
(enetAddr[1] << 8) + enetAddr[0];
/* Set the multicast addresses */
for (pCurr = END_MULTI_LST_FIRST(&pDrvCtrl->endObject); pCurr != NULL;
pCurr = (ETHER_MULTI *)lstNext(&pCurr->node))
{
/* add multicast address */
motCpmMCastFilterSet (pDrvCtrl, pCurr->addr);
}
/* enable Ethernet interrupts */
pDrvCtrl->ether.pSccReg->scce = 0xffff; /* clr events */
/* allow receive and transmit errors interrupts */
pDrvCtrl->ether.pSccReg->sccm = SCC_ETHER_SCCX_RXF | SCC_ETHER_SCCX_TXE |
SCC_ETHER_SCCX_TXB;
*CPM_CIMR(pDrvCtrl->regBase) |= pDrvCtrl->ether.intMask;
/* call the BSP to do any other initialization (e.g., connecting clocks) */
SYS_ENET_ENABLE;
/* raise the interface flags - mark the device as up */
END_FLAGS_SET (&pDrvCtrl->endObject, IFF_UP | IFF_RUNNING);
/* enable the transmitter */
pDrvCtrl->ether.pSccReg->gsmrl |= SCC_GSMRL_ENT;
/* issue the restart transmitter command to the CP */
while (*CPM_CPCR(pDrvCtrl->regBase) & CPM_CR_FLG);
*CPM_CPCR(pDrvCtrl->regBase) = ((pDrvCtrl->ether.sccNum - 1) << 6) |
CPM_CR_SCC_RESTART | CPM_CR_FLG;
while (*CPM_CPCR(pDrvCtrl->regBase) & CPM_CR_FLG);
/* enable the receiver */
pDrvCtrl->ether.pSccReg->gsmrl |= SCC_GSMRL_ENR;
return (OK);
}
/*******************************************************************************
*
* motCpmEndStop - stop the device
*
* This routine marks the interface as down and resets the device. This
* includes disabling interrupts, stopping the transmitter and receiver,
* and calling the bsp-specific LAN disable routine to do any target
* specific disabling.
*
* The complement of this routine is motCpmEndStart(). Once a unit is
* stop in this routine, it may be re-initialized to a running state by
* motCpmEndStart().
*
* RETURNS: OK or ERROR.
*/
LOCAL STATUS motCpmEndStop
(
END_CTRL * pDrvCtrl /* pointer to END_CTRL structure */
)
{
/* mark the driver as down */
END_FLAGS_CLR (&pDrvCtrl->endObject, IFF_UP | IFF_RUNNING);
/* Reset the device */
motCpmReset (pDrvCtrl);
return (OK);
}
/******************************************************************************
*
* motCpmEndUnload - unload a driver from the system
*
* This function first brings down the device, and then frees any
* stuff that was allocated by the driver in the load function.
*
* RETURN : OK or ERROR
*/
LOCAL STATUS motCpmEndUnload
(
END_CTRL *pDrvCtrl /* pointer to END_CTRL structure */
)
{
END_OBJECT_UNLOAD (&pDrvCtrl->endObject);
return (OK);
}
/*******************************************************************************
*
* motCpmEndSend - output packet to network interface device
*
* This routine() takes a M_BLK_ID and sends off the data in the M_BLK_ID.
* The buffer must already have the addressing information properly installed
* in it. This is done by a higher layer. The last arguments are a free
* routine to be called when the device is done with the buffer and a pointer
* to the argument to pass to the free routine.
*
* muxSend() calls this routine each time it wants to send a packet.
* Errors are detected at interrupt level.
*
* RETURNS: OK or ERROR.
*/
LOCAL STATUS motCpmEndSend123/*wut 2004.7.22modify*/
(
END_CTRL *pDrvCtrl, /* pointer to END_CTRL structure */
M_BLK_ID pMblk /* Data to send */
)
{
int length;
SCC_BUF * pTxBd;
u_char * pad;
char *pBuf;
int oldLevel;
int s;
MOTCPMLOGMSG(("motCpmEndSend \n", 0, 0, 0, 0, 0, 0));
if (pDrvCtrl->txBlocked)
{
if(send1==1)
MOTCPMLOGMSG(("motCpmEndSend1 \n", 0, 0, 0, 0, 0, 0));
return (END_ERR_BLOCK);
}
if (pDrvCtrl->polling)
{
if(send2==1)
MOTCPMLOGMSG(("motCpmEndSend2 \n", 0, 0, 0, 0, 0, 0));
return (ERROR);
}
/* gain exclusive access to the transmitter */
END_TX_SEM_TAKE (&pDrvCtrl->endObject, WAIT_FOREVER);
if((pMblk->mBlkPktHdr.len)<40)
{
END_TX_SEM_GIVE (&pDrvCtrl->endObject);
MOTCPMLOGMSG(("pMblk->mBlkPktHdr.len)<40 \n", 0, 0, 0, 0, 0, 0));
return ERROR;
}
/* get a free transmit frame descriptor */
if(send3==1)
MOTCPMLOGMSG(("motCpmEndSend3 \n", 0, 0, 0, 0, 0, 0));
pTxBd = & pDrvCtrl->ether.txBdBase[pDrvCtrl->ether.txBdNext];
/* check if a transmit buffer descriptor is available */
if ((pTxBd->statusMode & SCC_ETHER_TX_BD_R) ||
(((pDrvCtrl->ether.txBdNext + 1) % pDrvCtrl->ether.txBdNum)
== pDrvCtrl->txBdIndexC))
{
END_TX_SEM_GIVE (&pDrvCtrl->endObject);
s = intLock();
pDrvCtrl->txBlocked = TRUE;
intUnlock(s);
if(send4==1)
MOTCPMLOGMSG(("motCpmEndSend4 \n", 0, 0, 0, 0, 0, 0));
return (END_ERR_BLOCK);
}
#if 1
pBuf = netClusterGet(pDrvCtrl->endObject.pNetPool, pDrvCtrl->pClPoolId);
if (pBuf == NULL)
{
END_TX_SEM_GIVE (&pDrvCtrl->endObject);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -