📄 motcpmend.c
字号:
LOCAL STATUS motCpmRestart (END_CTRL * pDrvCtrl);
LOCAL void motCpmCleanRxBd (END_CTRL * pDrvCtrl, SCC_BUF * pRxBd);
/* END Specific interfaces. */
END_OBJ * motCpmEndLoad1 (char *initString);
LOCAL STATUS motCpmEndStart(END_CTRL *pDrvCtrl);
LOCAL int motCpmEndIoctl (END_CTRL *pDrvCtrl, int cmd, caddr_t data);
LOCAL STATUS motCpmEndSend (END_CTRL *pDrvCtrl, M_BLK_ID pBuf);
LOCAL STATUS motCpmEndMCastAddrAdd (END_CTRL *pDrvCtrl, char* pAddress);
LOCAL STATUS motCpmEndMCastAddrDel (END_CTRL *pDrvCtrl, char* pAddress);
LOCAL STATUS motCpmEndMCastAddrGet (END_CTRL *pDrvCtrl,
MULTI_TABLE *pTable);
LOCAL STATUS motCpmEndPollSend (END_CTRL *pDrvCtrl, M_BLK_ID pBuf);
LOCAL STATUS motCpmEndPollReceive (END_CTRL *pDrvCtrl, M_BLK_ID pBuf);
LOCAL STATUS motCpmEndPollStart (END_CTRL *pDrvCtrl);
LOCAL STATUS motCpmEndPollStop (END_CTRL *pDrvCtrl);
LOCAL STATUS motCpmEndUnload (END_CTRL *pDrvCtrl);
LOCAL STATUS motCpmEndStop (END_CTRL *pDrvCtrl);
#else /* __STDC__ */
LOCAL STATUS motCpmInitParse ();
LOCAL STATUS motCpmInitMem ();
LOCAL void motCpmRecv ();
LOCAL void motCpmIntr ();
LOCAL void motCpmReset ();
LOCAL void motCpmMCastFilterSet ();
LOCAL void motCpmMCastConfig ();
LOCAL void motCpmTxRestart ();
LOCAL void motCpmHandleInt ();
LOCAL void motCpmCleanTxBdQueue ();
LOCAL STATUS motCpmRestart ();
LOCAL void motCpmCleanRxBd ();
/* END Specific interfaces. */
END_OBJ * motCpmEndLoad1 ();
LOCAL STATUS motCpmEndStart ();
LOCAL int motCpmEndIoctl ();
LOCAL STATUS motCpmEndSend ();
LOCAL STATUS motCpmEndMCastAddrAdd ();
LOCAL STATUS motCpmEndMCastAddrDel ();
LOCAL STATUS motCpmEndMCastAddrGet ();
LOCAL STATUS motCpmEndPollSend ();
LOCAL STATUS motCpmEndPollReceive ();
LOCAL STATUS motCpmEndPollStart ();
LOCAL STATUS motCpmEndPollStop ();
LOCAL STATUS motCpmEndUnload ();
LOCAL STATUS motCpmEndStop ();
#endif /* __STDC__ */
/*
* Define the device function table. This is static across all driver
* instances.
*/
LOCAL NET_FUNCS netFuncs =
{
(FUNCPTR)motCpmEndStart, /* start func. */
(FUNCPTR)motCpmEndStop, /* stop func. */
(FUNCPTR)motCpmEndUnload, /* unload func. */
(FUNCPTR)motCpmEndIoctl, /* ioctl func. */
(FUNCPTR)motCpmEndSend, /* send func. */
(FUNCPTR)motCpmEndMCastAddrAdd, /* multicast add func. */
(FUNCPTR)motCpmEndMCastAddrDel, /* multicast delete func. */
(FUNCPTR)motCpmEndMCastAddrGet, /* multicast get fun. */
(FUNCPTR)motCpmEndPollSend, /* polling send func. */
(FUNCPTR)motCpmEndPollReceive, /* polling receive func. */
endEtherAddressForm, /* Put address info into a packet. */
endEtherPacketDataGet, /* Get a pointer to packet data. */
endEtherPacketAddrGet /* Get packet addresses. */
};
/*******************************************************************************
*
* motCpmEndLoad - initialize the driver and device
*
* This routine initializes the driver and the device to the operational state.
* All of the device specific parameters are passed in the <initString>, which
* is of the following format:
*
* <unit>:<motCpmAddr>:<ivec>:<sccNum>:<txBdNum>:<rxBdNum>:<txBdBase>:<rxBdBase>:
<bufBase>
*
* The parameters of this string are individually described in the 'motCpmEnd'
* man page.
*
* The SCC shares a region of memory with the driver. The caller of
* this routine can specify the address of a non-cacheable memory region with
* <bufBase>. Or, if this parameter is "NONE", the driver obtains this
* memory region by making calls to cacheDmaMalloc(). Non-cacheable memory
* space is important whenever the host processor uses cache memory.
* This is also the case when the MC68EN360 is operating in companion
* mode and is attached to a processor with cache memory.
*
* After non-cacheable memory is obtained, this routine divides up the
* memory between the various buffer descriptors (BDs). The number
* of BDs can be specified by <txBdNum> and <rxBdNum>, or if "NULL", a
* default value of 32 BDs will be used. An additional number of buffers are
* reserved as receive loaner buffers. The number of loaner buffers is
* a default number of 16.
*
* The user must specify the location of the transmit and receive BDs in
* the processor's dual ported RAM. <txBdBase> and <rxBdBase> give the
* offsets from <motCpmAddr> for the base of the BD rings. Each BD uses
* 8 bytes. Care must be taken so that the specified locations for Ethernet
* BDs do not conflict with other dual ported RAM structures.
*
* Multiple individual device units are supported by this driver. Device
* units can reside on different chips, or could be on different SCCs
* within a single processor. The <sccNum> parameter is used to explicitly
* state which SCC is being used. SCC1 is most commonly used, thus this
* parameter most often equals "1".
*
* Before this routine returns, it connects up the interrupt vector <ivec>.
*
* RETURNS: An END object pointer or NULL on error.
*
* SEE ALSO:
* .I "Motorola MC68EN360 User's Manual",
* .I "Motorola MPC860 User's Manual",
* .I "Motorola MPC821 User's Manual"
*/
END_OBJ *motCpmEndLoad1
(
char * initString /* parameter string */
)
{
END_PARM endParm; /* parameters from initString */
END_CTRL *pDrvCtrl; /* pointer to END_CTRL structure */
int scc;
UINT32 motCpmAddr;
u_char enetAddr[ENET_ADDR_SIZE];
int retVal;
MOTCPMLOGMSG(("motCpmEndLoad1 \n", 0, 0, 0, 0, 0, 0));
if (initString == NULL)
return (NULL);
if (initString[0] == NULL)
{
bcopy((char *)MOT_DEV_NAME, initString, MOT_DEV_NAME_LEN);
return (0);
}
/* Parse InitString */
if (motCpmInitParse (&endParm, initString) == ERROR)
return (NULL);
/* Sanity check -- unit number */
if (endParm.unit < 0 || endParm.unit >= MAX_SCC_CHANNELS)
return (NULL);
/* Sanity check -- scc number */
if ((endParm.sccNum < 1) || (endParm.sccNum > 4))
return (NULL);
if (endParm.txBdBase == endParm.rxBdBase)
return (NULL);
pDrvCtrl = & drvCtrl [endParm.unit];
/* Check if we are already attached */
if (pDrvCtrl->endObject.attached == TRUE)
return (&pDrvCtrl->endObject);
/* use default number of buffer descriptors if user did not specify */
if (endParm.txBdNum == NULL)
endParm.txBdNum = TX_BD_DEFAULT;
if (endParm.rxBdNum == NULL)
endParm.rxBdNum = RX_BD_DEFAULT;
/* must be at least two transmit and receive buffer descriptors */
endParm.txBdNum = max (TX_BD_MIN, endParm.txBdNum);
endParm.rxBdNum = max (RX_BD_MIN, endParm.rxBdNum);
/* Initialize parameters */
pDrvCtrl->regBase = endParm.motCpmAddr;
pDrvCtrl->bufBase = endParm.bufBase;
pDrvCtrl->unit = endParm.unit;
pDrvCtrl->ivec = endParm.ivec;
pDrvCtrl->ether.sccNum = endParm.sccNum;
pDrvCtrl->ether.txBdNum = endParm.txBdNum;
pDrvCtrl->ether.rxBdNum = endParm.rxBdNum;
pDrvCtrl->ether.txBdBase = (SCC_BUF *) (endParm.motCpmAddr +
(endParm.txBdBase & 0xffff));
pDrvCtrl->ether.rxBdBase = (SCC_BUF *) (endParm.motCpmAddr +
(endParm.rxBdBase & 0xffff));
pDrvCtrl->ether.txBufSize = FRAME_MAX_AL;
pDrvCtrl->ether.rxBufSize = FRAME_MAX_AL;
pDrvCtrl->txBdIndexC = 0;
/* derive SCC dependent variables */
scc = pDrvCtrl->ether.sccNum - 1;
motCpmAddr = pDrvCtrl->regBase;
pDrvCtrl->ether.pScc = (SCC *) ((UINT32) CPM_DPR_SCC1(motCpmAddr) +
(scc * 0x100));
pDrvCtrl->ether.pSccReg = (SCC_REG *)
((UINT32) CPM_GSMR_L1(motCpmAddr) + (
scc * 0x20));
pDrvCtrl->ether.intMask = CPM_CIMR_SCC4 << (3 - scc);
/* endObject initializations */
if (END_OBJ_INIT (&pDrvCtrl->endObject, (void *)pDrvCtrl, MOT_DEV_NAME,
pDrvCtrl->unit, &netFuncs,
END_OBJ_STRING) == ERROR)
return (NULL);
/* memory initialization */
if (motCpmInitMem (pDrvCtrl) == ERROR)
return (NULL);
/* reset the chip */
motCpmReset (pDrvCtrl);
/* connect the interrupt handler motCpmIntr() */
SYS_INT_CONNECT ((VOIDFUNCPTR) motCpmIntr, (int) pDrvCtrl, &retVal);
if (retVal == ERROR)
return (NULL);
/* Get our enet addr */
SYS_ENET_ADDR_GET (enetAddr);
MOTCPMLOGMSG(("motCpmEndLoad1 ADDR: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x \n",
(int) enetAddr[0], (int) enetAddr[1], (int) enetAddr[2],
(int) enetAddr[3], (int) enetAddr[4], (int) enetAddr[5]));
/* Initialize MIB2 entries */
if (END_MIB_INIT (&pDrvCtrl->endObject, M2_ifType_ethernet_csmacd,
enetAddr, 6, ETHERMTU, SPEED) == ERROR)
return (NULL);
/* Mark the device ready */
/* IFF_SCAT is not defined by default */
END_OBJ_READY (&pDrvCtrl->endObject,
IFF_NOTRAILERS | IFF_BROADCAST | IFF_MULTICAST);
/* Successful return */
return (&pDrvCtrl->endObject);
}
/*******************************************************************************
*
* motCpmInitParse - parse parameter values from initString
*
* Parse the input string. Fill in values in the driver control structure.
*
* The initialization string format is:
* .CS
* "unit:motCpmAddr:ivec:sccNum:txBdNum:rxBdNum:txBdBase:rxBdBase:bufBase"
* .CE
*
* .IP <unit>
* Device unit number, a small integer.
* .IP <motCpmAddr>
* base address of processor internal mem
* .IP <ivec>
* Interrupt vector number
* .IP <sccNum>
* SCC number used.
* .IP <txBdNum>
* number of transmit buffer descriptors; NULL = default
* .IP <rxBdNum>
* number of receive buffer descriptors; NULL = default
* .IP <txBdBase>
* transmit buffer descriptor offset
* .IP <rxBdBase>
* receive buffer descriptor offset
* .IP <bufBase>
* address of memory pool; NONE = malloc it
* .LP
*
* RETURNS: OK or ERROR for invalid arguments.
*/
LOCAL STATUS motCpmInitParse
(
END_PARM *pEndParm, /* structure to fill in with parameters */
char *initString /* init string */
)
{
char * tok; /* an initString token */
char * holder=NULL; /* points to initString fragment beyond tok */
char * initStringBuff;
initStringBuff = malloc(strlen(initString) + 1);
if (initStringBuff == NULL)
return (ERROR);
strcpy (initStringBuff, initString);
tok = strtok_r(initStringBuff, ":", &holder);
if (tok == NULL)
{
free(initStringBuff);
return ERROR;
}
pEndParm->unit = atoi(tok);
tok = strtok_r(NULL, ":", &holder);
if (tok == NULL)
{
free(initStringBuff);
return ERROR;
}
pEndParm->motCpmAddr = strtoul (tok, NULL, 16);
tok = strtok_r(NULL, ":", &holder);
if (tok == NULL)
{
free(initStringBuff);
return ERROR;
}
pEndParm->ivec = strtoul (tok, NULL, 16);
tok = strtok_r(NULL, ":", &holder);
if (tok == NULL)
{
free(initStringBuff);
return ERROR;
}
pEndParm->sccNum = atoi (tok);
tok = strtok_r(NULL, ":", &holder);
if (tok == NULL)
{
free(initStringBuff);
return ERROR;
}
pEndParm->txBdNum = strtoul (tok, NULL, 16);
tok = strtok_r(NULL, ":", &holder);
if (tok == NULL)
{
free(initStringBuff);
return ERROR;
}
pEndParm->rxBdNum = strtoul (tok, NULL, 16);
tok = strtok_r(NULL, ":", &holder);
if (tok == NULL)
{
free(initStringBuff);
return ERROR;
}
pEndParm->txBdBase = strtoul (tok, NULL, 16);
/*pEndParm->txBdBase = 0x2800;*/
tok = strtok_r(NULL, ":", &holder);
if (tok == NULL)
{
free(initStringBuff);
return ERROR;
}
pEndParm->rxBdBase = strtoul (tok, NULL, 16);
/*pEndParm->rxBdBase = 0x2900;*/
tok = strtok_r(NULL, ":", &holder);
if (tok == NULL)
{
free(initStringBuff);
return ERROR;
}
pEndParm->bufBase = strtoul (tok, NULL, 16);
MOTCPMLOGMSG(("unit = %d, motCpmAddr = 0x%x, ivec = 0x%x, sccNum = 0x%x\n",
pEndParm->unit, pEndParm->motCpmAddr, pEndParm->ivec,
pEndParm->sccNum, 0, 0));
MOTCPMLOGMSG(("txBdNum = 0x%x, rxBdNum = 0x%x, txBdBase = 0x%x\n",
pEndParm->txBdNum, pEndParm->rxBdNum, pEndParm->txBdBase,
0, 0, 0));
MOTCPMLOGMSG(("rxBdBase = 0x%x, bufBase = %d\n", pEndParm->rxBdBase,
pEndParm->bufBase, 0, 0, 0, 0));
free(initStringBuff);
return OK;
}
/*******************************************************************************
*
* motCpmInitMem - initialize memory
*
* Using data in the control structure, setup and initialize the memory
* areas needed. If the memory address is not already specified, then allocate
* cache safe memory.
*
* RETURNS: OK or ERROR.
*
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -