📄 motcpmend.c
字号:
** 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.**/LOCAL STATUS motCpmInitMem ( 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. */ for (counter = 0; counter < pDrvCtrl->ether.txBdNum; counter++) { pDrvCtrl->freeRtn[counter] = NULL; pDrvCtrl->freeData[counter].arg1 = NULL; pDrvCtrl->freeData[counter].arg2 = NULL; } 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) */ numBuf = pDrvCtrl->ether.rxBdNum + pDrvCtrl->ether.txBdNum + L_POOL; /* 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 = 5 * numBuf; motMclBlkConfig.clBlkNum = 5 * 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 (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); } /* 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; } pDrvCtrl->txPoolBuf = netClusterGet (pDrvCtrl->endObject.pNetPool, pDrvCtrl->pClPoolId); 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_AL; ((SCC_ETHER_PROTO *)pDrvCtrl->ether.pScc->prot)->maxd2 = FRAME_MAX_AL; ((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 motCpmEndSend ( 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) return (END_ERR_BLOCK); if (pDrvCtrl->polling) { netMblkClChainFree (pMblk); /* free the given mBlk chain */ errno = EINVAL; return (ERROR); } /* gain exclusive access to the transmitter */ END_TX_SEM_TAKE (&pDrvCtrl->endObject, WAIT_FOREVER); /* get a free transmit frame descriptor */ 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); return (END_ERR_BLOCK); } /* fill the transmit frame descriptor */ pBuf = netClusterGet(pDrvCtrl->endObject.pNetPool, pDrvCtrl->pClPoolId); if (pBuf == NULL) { END_TX_SEM_GIVE (&pDrvCtrl->endObject); netMblkClChainFree(pMblk); return (ERROR); } length = netMblkToBufCopy (pMblk, (char *)pBuf, NULL); netMblkClChainFree(pMblk); pTxBd->dataPointer = (u_char *) pBuf; /* padding mechanism in Rev A is buggy - do in software */ if (length < FRAME_MIN) { pad = pTxBd->dataPointer + length; for (; length != FRAME_MIN; length++, pad++) *pad = 0x88; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -