📄 m8260sccend.c
字号:
** RETURNS: OK or ERROR.**/LOCAL STATUS motSccInitMem ( END_CTRL *pDrvCtrl ) { int i, numBuf, size; char * pTmpBuf; /* Set up the structures to allow us to free data after sending it. */ for (i = 0; i < pDrvCtrl->ether.txBdNum; ++i) { pDrvCtrl->freeRtn[i] = NULL; pDrvCtrl->freeData[i].arg1 = NULL; pDrvCtrl->freeData[i].arg2 = 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 = &motSccNetPool; motMclBlkConfig.mBlkNum = 2 * numBuf; motMclBlkConfig.clBlkNum = numBuf; size = motMclBlkConfig.memSize = ((motMclBlkConfig.mBlkNum * (MSIZE + sizeof (long))) + (motMclBlkConfig.clBlkNum * (CL_BLK_SZ + sizeof (long)))); if (!(motMclBlkConfig.memArea = (char *)memalign(sizeof(long),size))) { return ERROR; } motClDescTbl[0].clNum = numBuf; size = motClDescTbl[0].memSize = (numBuf * (FRAME_MAX_AL + sizeof(long))); if (pDrvCtrl->bufBase == NONE) { /* We must allocate memory for buffer descriptors */ motClDescTbl[0].memArea = (char *)cacheDmaMalloc(size); } else { /* Memory for buffer descriptors is user allocated and cache-safe */ motClDescTbl[0].memArea = (char *)pDrvCtrl->bufBase; } if (!motClDescTbl[0].memArea) { 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 (i = 0; i < pDrvCtrl->ether.rxBdNum; ++i) { pTmpBuf = (char*)netClusterGet(pDrvCtrl->endObject.pNetPool,pDrvCtrl->pClPoolId); if (!pTmpBuf) { return ERROR; } pDrvCtrl->ether.rxBdBase[i].dataPointer = (u_char *) pTmpBuf; } return OK; }/********************************************************************************* motSccEndStart - 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 motSccEndStop(). Once a unit is reset by* motSccEndStop(), it may be re-initialized to a running state by this routine.* * RETURNS: OK if successful, otherwise ERROR.*/LOCAL STATUS motSccEndStart ( END_CTRL * pDrvCtrl /* pointer to END_CTRL structure */ ) { int counter; u_char * enetAddr; ETHER_MULTI * pCurr; int retVal; MOTCPMLOGMSG(("motSccEndStart \n", 0, 0, 0, 0, 0, 0)); /* initialize flag(s) */ pDrvCtrl->polling = FALSE; pDrvCtrl->txStop = FALSE; pDrvCtrl->txCleaning = FALSE; pDrvCtrl->txBlocked = FALSE; /* call the BSP to do any other initialization (e.g., connecting clocks) */ SYS_ENET_ENABLE; /* 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; if (userFlags & SCC_USR_DUPLEX_FULL) pDrvCtrl->ether.pSccReg->psmr = SCC_ETHER_PSMR_CRC | SCC_ETHER_PSMR_LPB | SCC_ETHER_PSMR_NIB_22 | SCC_ETHER_PSMR_FDE; else 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; if (userFlags & SCC_USR_RUNNING_FROM_ROM) { pDrvCtrl->ether.pScc->param.rfcr = 0x12; /* big-endian -- bufs on local bus */ pDrvCtrl->ether.pScc->param.tfcr = 0x12; /* big-endian -- bufs on local bus */ } else { pDrvCtrl->ether.pScc->param.rfcr = 0x18; /* big-endian */ pDrvCtrl->ether.pScc->param.tfcr = 0x18; /* big-endian */ } 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]; while (*M8260_CPCR(pDrvCtrl->regBase) & M8260_CPCR_FLG); *M8260_CPCR(pDrvCtrl->regBase) = (M8260_CPCR_PAGE(pDrvCtrl->ether.sccNum - 1) | M8260_CPCR_SBC(pDrvCtrl->ether.sccNum + 3) | M8260_CPCR_OP(M8260_CPCR_RT_INIT) | M8260_CPCR_FLG); while (*M8260_CPCR(pDrvCtrl->regBase) & M8260_CPCR_FLG); /* Set the multicast addresses */ for (pCurr = END_MULTI_LST_FIRST(&pDrvCtrl->endObject); pCurr != NULL; pCurr = (ETHER_MULTI *)lstNext(&pCurr->node)) { /* add multicast address */ motSccMCastFilterSet (pDrvCtrl, pCurr->addr); } /* connect the interrupt handler motSccIntr() */ SYS_INT_CONNECT ((VOIDFUNCPTR) motSccIntr, (int) pDrvCtrl, &retVal); if (retVal == ERROR) return(FALSE); /* 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; *M8260_SIMR_L(pDrvCtrl->regBase) |= pDrvCtrl->ether.intMask; /* 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 (*M8260_CPCR(pDrvCtrl->regBase) & M8260_CPCR_FLG); *M8260_CPCR(pDrvCtrl->regBase) = (M8260_CPCR_PAGE(pDrvCtrl->ether.sccNum - 1) | M8260_CPCR_SBC(pDrvCtrl->ether.sccNum + 3) | M8260_CPCR_OP(M8260_CPCR_TX_RESTART) | M8260_CPCR_FLG); while (*M8260_CPCR(pDrvCtrl->regBase) & M8260_CPCR_FLG); /* enable the receiver */ pDrvCtrl->ether.pSccReg->gsmrl |= SCC_GSMRL_ENR; MOTCPMLOGMSG(("motSccEndStart DONE\n", 0, 0, 0, 0, 0, 0)); return(OK); }/********************************************************************************* motSccEndStop - 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 motSccEndStart(). Once a unit is * stop in this routine, it may be re-initialized to a running state by * motSccEndStart().** RETURNS: OK or ERROR.*/LOCAL STATUS motSccEndStop ( 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 */ motSccReset (pDrvCtrl); return (OK); }/******************************************************************************** motSccEndUnload - 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 motSccEndUnload ( END_CTRL * pDrvCtrl /* pointer to END_CTRL structure */ ) { END_OBJECT_UNLOAD (&pDrvCtrl->endObject); return (OK); }/********************************************************************************* motSccEndSend - 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 motSccEndSend ( 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(("motSccEndSend \n", 0, 0, 0, 0, 0, 0)); if (pDrvCtrl->txBlocked) { return(END_ERR_BLOCK); } if (pDrvCtrl->polling) { 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -