📄 sh7615end.c
字号:
pMblk->mBlkHdr.mData +=2; bcopy (pRxBuf, (char *)pMblk->mBlkHdr.mData, len); } } /* mark the descriptor ready to receive - preserve the RDL bit */ pRxD->rDesc0 = (pRxD->rDesc0 & RD0_RDL) | RD0_OWN; pDrvCtrl->rxIndex = (pDrvCtrl->rxIndex + 1) % pDrvCtrl->numRds; } return (gotOne ? OK : EAGAIN); }/********************************************************************************* sh7615EndIoctl - the driver I/O control routine** Process an ioctl request.** This routine implements the network interface control functions.* It handles EIOCSADDR, EIOCGADDR, EIOCSFLAGS, EIOCGFLAGS, EIOCMULTIADD,* EIOCMULTIDEL, EIOCMULTIGET, EIOCPOLLSTART, EIOCPOLLSTOP, EIOCGMIB2 commands.** RETURNS: A command specific response, usually OK or ERROR.*/LOCAL STATUS sh7615EndIoctl ( DRV_CTRL * pDrvCtrl, /* device receiving command */ int cmd, /* ioctl command code */ caddr_t data /* command argument */ ) { int error = 0; long value; int savedFlags; END_OBJ * pEndObj=&pDrvCtrl->end; DRV_LOG (DRV_DEBUG_IOCTL, "Ioctl unit=0x%x cmd=%d data=0x%x\n", pDrvCtrl->unit, cmd, (int)data, 4, 5, 6); switch (cmd) { case EIOCSADDR: if (data == NULL) return (EINVAL); bcopy ((char *)data, (char *)END_HADDR(pDrvCtrl), END_HADDR_LEN(pDrvCtrl)); break; case EIOCGADDR: if (data == NULL) return (EINVAL); bcopy ((char *)END_HADDR(pDrvCtrl), (char *)data, END_HADDR_LEN(pDrvCtrl)); break; case EIOCSFLAGS: value = (long)data; if (value < 0) { value = -value; value--; END_FLAGS_CLR (pEndObj, value); } else { END_FLAGS_SET (pEndObj, value); } /* handle IIF_PROMISC and IFF_ALLMULTI */ savedFlags = DRV_FLAGS_GET(); if (END_FLAGS_ISSET (pEndObj, IFF_PROMISC)) DRV_FLAGS_SET (SH7615END_PROMISC); else DRV_FLAGS_CLR (SH7615END_PROMISC); if (END_FLAGS_GET(pEndObj) & (IFF_MULTICAST | IFF_ALLMULTI)) DRV_FLAGS_SET (SH7615END_MCAST); else DRV_FLAGS_CLR (SH7615END_MCAST); DRV_LOG (DRV_DEBUG_IOCTL, "EIOCSFLAGS!! endFlags=0x%x savedFlags=0x%x newFlags=0x%x\n", END_FLAGS_GET(pEndObj), savedFlags, DRV_FLAGS_GET(), 4, 5, 6); if ((DRV_FLAGS_GET() != savedFlags) && (END_FLAGS_GET(pEndObj) & IFF_UP)) sh7615EndModeSet (pDrvCtrl); break; case EIOCGFLAGS: DRV_LOG (DRV_DEBUG_IOCTL, "EIOCGFLAGS IOCTL: 0x%x: 0x%x\n", pEndObj->flags, *(long *)data, 0, 0, 0, 0); if (data == NULL) error = EINVAL; else *(long *)data = END_FLAGS_GET(pEndObj); break; case EIOCMULTIADD: DRV_LOG (DRV_DEBUG_IOCTL, "IOCTL EIOCMULTIADD\n", 1, 2, 3, 4, 5, 6); error = sh7615EndMCastAddrAdd (pDrvCtrl, (char *)data); break; case EIOCMULTIDEL: DRV_LOG (DRV_DEBUG_IOCTL, "IOCTL EIOCMULTIDEL\n", 1, 2, 3, 4, 5, 6); error = sh7615EndMCastAddrDel (pDrvCtrl, (char *)data); break; case EIOCMULTIGET: DRV_LOG (DRV_DEBUG_IOCTL, "IOCTL EIOCMULTIGET\n", 1, 2, 3, 4, 5, 6); error = sh7615EndMCastAddrGet (pDrvCtrl, (MULTI_TABLE *)data); break; case EIOCPOLLSTART: DRV_LOG (DRV_DEBUG_IOCTL, "IOCTL EIOCPOLLSTART\n", 1, 2, 3, 4, 5, 6); sh7615EndPollStart (pDrvCtrl); break; case EIOCPOLLSTOP: DRV_LOG (DRV_DEBUG_IOCTL, "IOCTL EIOCPOLLSTOP\n", 1, 2, 3, 4, 5, 6); sh7615EndPollStop (pDrvCtrl); break; case EIOCGMIB2: if (data == NULL) error=EINVAL; else bcopy((char *)&pEndObj->mib2Tbl, (char *)data, sizeof(pEndObj->mib2Tbl)); DRV_LOG (DRV_DEBUG_IOCTL, "IOCTL EIOCGMIB2\n", 1, 2, 3, 4, 5, 6); break; default: error = EINVAL; } return (error); }/********************************************************************************* sh7615EndModeSet - promiscuous & multicast operation ** This routine enables promiscuous and duplex mode if corresponding flags * are set.** RETURNS: N/A*/ LOCAL void sh7615EndModeSet ( DRV_CTRL *pDrvCtrl ) { /* NOTE - manual says mode should not be changed while Rx/Tx is enabled. To modify mode settings, first issue software reset */ /* Set promiscuous mode if necessary */ if (DRV_FLAGS_ISSET (SH7615END_PROMISC)) SH7615END_BIT_SET (ETHERC_ECMR, ECMR_PRM); /* Set duplex mode if necessary */ if (DRV_FLAGS_ISSET (SH7615END_FD)) SH7615END_BIT_SET(ETHERC_ECMR, ECMR_DM); } /******************************************************************************** sh7615EndConfig - reconfigure the interface under us.** Reconfigure the interface setting promiscuous mode, and changing the* multicast interface list.** RETURNS: N/A.*/LOCAL void sh7615EndConfig ( DRV_CTRL *pDrvCtrl /* device to be re-configured */ ) { UCHAR* pEnetAddr = pDrvCtrl->enetAddr; UINT32 MACAddr = 0; DRV_LOG (DRV_DEBUG_LOAD, "Configuring shend\n", 0, 0, 0, 0, 0, 0); /* initialize the dp83843 Physical interface device */#ifdef INCLUDE_PHY /* Check full duplex mode */ DRV_FLAGS_CLR (SH7615END_FD); if (dp83843RegRead(PHYSTS) & 0x0004) { DRV_FLAGS_SET (SH7615END_FD); }#define PFC_PACR ((volatile UINT16 *)0xfffffc80) *PFC_PACR = *PFC_PACR | (UINT16) 0x0004; /* LINKSTA pin */#endif /* set depth of FIFO */ SH7615END_REG_WRITE(E_DMAC_FDR, ((pDrvCtrl->userFlags & 0x70) << 4) | (pDrvCtrl->userFlags & 0x7)); /* Write start of receive and transmit rings */ SH7615END_REG_WRITE(E_DMAC_RDLAR, (UINT32)pDrvCtrl->rxRing); SH7615END_REG_WRITE(E_DMAC_TDLAR, (UINT32)pDrvCtrl->txRing); /* set MAC Address */ MACAddr = (UINT32)pEnetAddr[0] << 24; MACAddr |= (UINT32)pEnetAddr[1] << 16; MACAddr |= (UINT32)pEnetAddr[2] << 8; MACAddr |= (UINT32)pEnetAddr[3]; SH7615END_REG_WRITE(ETHERC_MAHR, MACAddr); MACAddr = (UINT32)pEnetAddr[4] << 8; MACAddr |= (UINT32)pEnetAddr[5]; SH7615END_REG_WRITE(ETHERC_MALR, MACAddr); /* set receive frame length register - specifies max receiveable length */ SH7615END_REG_WRITE(ETHERC_RFLR, 0x5F0); /* 1520 bytes */ /* clear any pending interrupts */ SH7615END_REG_WRITE(ETHERC_ECSR, ECSR_CLEAR); SH7615END_REG_WRITE(E_DMAC_EESR, EESR_CLEAR); /* set operating mode and start the receiver */ sh7615EndModeSet (pDrvCtrl); /* start the transmitter, receiver */ SH7615END_REG_WRITE(E_DMAC_RCR, RCR_RNC); /* continuous mode */ SH7615END_REG_WRITE(E_DMAC_EDRRR, EDRRR_RR); /* Receive request */ SH7615END_BIT_SET(ETHERC_ECMR, ECMR_TE); SH7615END_BIT_SET(ETHERC_ECMR, ECMR_RE); /* set up the interrupt mask */ pDrvCtrl->intrMask = EESIPR_FRIP | EESIPR_TCIP | EESIPR_ECIIP; /* enable interrupts at the device */ SH7615END_REG_WRITE(E_DMAC_EESIPR, pDrvCtrl->intrMask); SH7615END_REG_WRITE(ETHERC_ECSIPR, ECSIPR_LCHNGIP); return; }/********************************************************************************* sh7615EndMCastAddrAdd - add a multicast address** This routine adds a multicast address to whatever the driver* is already listening for.** RETURNS: OK on success, ERROR otherwise.*/ LOCAL STATUS sh7615EndMCastAddrAdd ( DRV_CTRL * pDrvCtrl, char * pAddr ) { int retVal; DRV_LOG (DRV_DEBUG_IOCTL, "MCastAddrAdd\n", 0, 0, 0, 0, 0, 0); retVal = etherMultiAdd (&pDrvCtrl->end.multiList, pAddr); if (retVal == ENETRESET) sh7615EndConfig (pDrvCtrl); return (OK); }/********************************************************************************* sh7615EndMCastAddrDel - remove a multicast address** This routine deletes a multicast address from the current list of* multicast addresses.** RETURNS: OK on success, ERROR otherwise.*/ LOCAL STATUS sh7615EndMCastAddrDel ( DRV_CTRL * pDrvCtrl, char * pAddr ) { int retVal; DRV_LOG (DRV_DEBUG_IOCTL, "MCastAddrDel\n", 0, 0, 0, 0, 0, 0); retVal = etherMultiDel (&pDrvCtrl->end.multiList, pAddr); if (retVal == ENETRESET) sh7615EndConfig (pDrvCtrl); return (OK); }/********************************************************************************* sh7615EndMCastAddrGet - retreive current multicast address list** This routine returns the current multicast address list in <pTable>** RETURNS: OK on success; otherwise ERROR.*/ LOCAL STATUS sh7615EndMCastAddrGet ( DRV_CTRL * pDrvCtrl, MULTI_TABLE *pTable ) { DRV_LOG (DRV_DEBUG_IOCTL, "MCastAddrGet\n", 0, 0, 0, 0, 0, 0); return (etherMultiGet (&pDrvCtrl->end.multiList, pTable)); }/********************************************************************************* sh7615EnetAddrGet - get the Ethernet address.** This routine gets the ethernet address by calling the appropriate* BSP routine.** RETURNS: N/A.*/ LOCAL void sh7615EnetAddrGet ( DRV_CTRL * pDrvCtrl, char * addr ) { int i; char bytes[6]; SYS_ENET_ADDR_GET (pDrvCtrl, bytes); /* For big endian we need to swap byte order */ for (i=0; i<6; i++) *addr++ = bytes[5-i]; }/********************************************************************************* sh7615EndReset - reset device** This routines issues a software reset of the SH7615 on-chip EDMAC.** RETURNS: N/A.*/LOCAL void sh7615EndReset ( DRV_CTRL *pDrvCtrl ) { /* * Note - this also sets Tx/Rx descriptor length to 16 bytes, which is * what we want. * * This should reset all internal registers to the initial values. * Both the etherC AND the E-DMAC regs are reset. * Consequently, all interrupts should be masked. */ SH7615END_REG_WRITE (E_DMAC_EDMR, EDMR_SWR); }#ifdef DRV_DEBUG/********************************************************************************* sh7615EndRegDump - reads all ETHERC and EDMAC registers and print the value** This routine reads all the registers of the SH7615 on-chip ETHERC and EDMAC.* Only for debug purpose.** RETURNS: N/A.** NOMANUAL*/void sh7615EndRegDump() { UINT32 value; SH7615END_REG_READ(E_DMAC_EDMR, value); logMsg ("E_DMAC_EDMR: 0x%x\n", value, 0, 0, 0, 0, 0); SH7615END_REG_READ(E_DMAC_EDTRR, value); logMsg ("E_DMAC_EDTRR: 0x%x\n", value, 0, 0, 0, 0, 0); SH7615END_REG_READ(E_DMAC_EDRRR, value); logMsg ("E_DMAC_EDRRR: 0x%x\n", value, 0, 0, 0, 0, 0); SH7615END_REG_READ(E_DMAC_TDLAR, value); logMsg ("E_DMAC_TDLAR: 0x%x\n", value, 0, 0, 0, 0, 0); SH7615END_REG_READ(E_DMAC_RDLAR, value); logMsg ("E_DMAC_RDLAR: 0x%x\n", value, 0, 0, 0, 0, 0); SH7615END_REG_READ(E_DMAC_EESR, value); logMsg ("E_DMAC_EESR: 0x%x\n", value, 0, 0, 0, 0, 0); SH7615END_REG_READ(E_DMAC_EESIPR, value); logMsg ("E_DMAC_EESIPR: 0x%x\n", value, 0, 0, 0, 0, 0); SH7615END_REG_READ(E_DMAC_TRSCER, value); logMsg ("E_DMAC_TRSCER: 0x%x\n", value, 0, 0, 0, 0, 0); SH7615END_REG_READ(E_DMAC_RMFCR, value); logMsg ("E_DMAC_RMFCR: 0x%x\n", value, 0, 0, 0, 0, 0); SH7615END_REG_READ(E_DMAC_TFTR, value); logMsg ("E_DMAC_TFTR: 0x%x\n", value, 0, 0, 0, 0, 0); SH7615END_REG_READ(E_DMAC_FDR, value); logMsg ("E_DMAC_FDR: 0x%x\n", value, 0, 0, 0, 0, 0); SH7615END_REG_READ(E_DMAC_RCR, value); logMsg ("E_DMAC_RCR: 0x%x\n", value, 0, 0, 0, 0, 0); SH7615END_REG_READ(E_DMAC_EDOCR, value); logMsg ("E_DMAC_EDOCR: 0x%x\n", value, 0, 0, 0, 0, 0); SH7615END_REG_READ(ETHERC_ECMR, value); logMsg ("ETHERC_ECMR: 0x%x\n", value, 0, 0, 0, 0, 0); SH7615END_REG_READ(ETHERC_ECSR, value); logMsg ("ETHERC_ECSR: 0x%x\n", value, 0, 0, 0, 0, 0); SH7615END_REG_READ(ETHERC_ECSIPR, value); lo
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -