📄 motcpmend.c
字号:
LOCAL void motCpmTxRestart (END_CTRL * pDrvCtrl);LOCAL void motCpmHandleInt (END_CTRL * pDrvCtrl);LOCAL void motCpmCleanTxBdQueue (END_CTRL * pDrvCtrl);LOCAL STATUS motCpmRestart (END_CTRL * pDrvCtrl);LOCAL void motCpmCleanRxBd (END_CTRL * pDrvCtrl, SCC_BUF * pRxBd);/* END Specific interfaces. */END_OBJ * motCpmEndLoad (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 * motCpmEndLoad ();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 *motCpmEndLoad ( 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(("motCpmEndLoad \n", 0, 0, 0, 0, 0, 0)); if (initString == NULL) return (NULL); if (initString[0] == 0) { 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); /* allocate the device structure */ pDrvCtrl = (END_CTRL *)calloc (sizeof(END_CTRL), 1); if (pDrvCtrl == NULL) { MOTCPMLOGMSG(("motCpmEndLoad : Failed to allocate control structure\n", 0, 0, 0, 0, 0, 0)); return (NULL); } /* 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 == 0) endParm.txBdNum = TX_BD_DEFAULT; if (endParm.rxBdNum == 0) 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(("motCpmEndLoad 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); tok = strtok_r(NULL, ":", &holder); if (tok == NULL) { free(initStringBuff); return ERROR; } pEndParm->rxBdBase = strtoul (tok, NULL, 16); 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -