📄 sngks32cend.c
字号:
else return ERROR; END_TX_SEM_GIVE (&pDrvCtrl->end); /* Bump the statistic counter. */ END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_UCAST, +1); /* * Cleanup. The driver must either free the packet now or * set up a structure so it can be freed later after a transmit * interrupt occurs. */ netMblkClChainFree (pNBuff); return (OK);#if 0 int len; int oldLevel; UCHAR *pTx; UINT32 stat; if (pDrvCtrl->resetting) { return ERROR; } stat = *(volatile UINT32 *)AT91C_EMAC_TSR; if (!(stat & AT91C_EMAC_BNQ)) return ERROR; pTx = pDrvCtrl->pTxBuf; /* * Obtain exclusive access to transmitter. This is necessary because * we might have more than one stack transmitting at once. */ END_TX_SEM_TAKE (&pDrvCtrl->end, WAIT_FOREVER); /* Set pointers in local structures to point to data. */ len = netMblkToBufCopy(pNBuff, (void *)pTx, NULL) ;/* printf("send ptr=%08x,length=%d\n",pTx,len); */ *(volatile UINT32 *)AT91C_EMAC_TSR = stat;/* Reset stat word */ /* place a transmit request */ oldLevel = intLock (); /* now at91cEndInt won't get confused */ /* initiate device transmit */ *(volatile UINT32 *)(AT91C_EMAC_TAR) = pTx; *(volatile UINT32 *)(AT91C_EMAC_TCR) = len; *(volatile UINT32 *)AT91C_EMAC_CTL |= AT91C_EMAC_TE; intUnlock (oldLevel); /* now at91cEndInt won't get confused */ while(((*(volatile UINT32 *)AT91C_EMAC_TSR)&AT91C_EMAC_BNQ)==0); END_TX_SEM_GIVE (&pDrvCtrl->end); /* Bump the statistic counter. */ END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_UCAST, +1); /* * Cleanup. The driver must either free the packet now or * set up a structure so it can be freed later after a transmit * interrupt occurs. */ netMblkClChainFree (pNBuff); return (OK);#endif }/******************************************************************************** at91cEndIoctl - the driver I/O control routine** Process an ioctl request.** RETURNS: A command specific response, usually OK or ERROR.*/LOCAL int at91cEndIoctl ( END_DEVICE *pDrvCtrl, /* device receiving command */ int cmd, /* ioctl command code */ caddr_t data /* command argument */ ) { int error = 0; long value;/* DRV_LOG (DRV_DEBUG_IOCTL, "Ioctl unit=0x%x cmd=%d data=0x%x\n", pDrvCtrl->unit, cmd, (int)data, 0, 0, 0);*/ switch ((unsigned int)cmd) { case EIOCSADDR: if (data == NULL) return (EINVAL); bcopy ((char *)data, (char *)END_HADDR(&pDrvCtrl->end), END_HADDR_LEN(&pDrvCtrl->end)); break; case EIOCGADDR: if (data == NULL) return (EINVAL); bcopy ((char *)END_HADDR(&pDrvCtrl->end), (char *)data, END_HADDR_LEN(&pDrvCtrl->end)); break; case EIOCSFLAGS: value = (long)data; if (value < 0) { value = ~value; END_FLAGS_CLR (&pDrvCtrl->end, value); } else { END_FLAGS_SET (&pDrvCtrl->end, value); } at91cEndConfig (pDrvCtrl); break; case EIOCGFLAGS: *(int *)data = END_FLAGS_GET(&pDrvCtrl->end); break; case EIOCPOLLSTART: at91cEndPollStart (pDrvCtrl); break; case EIOCPOLLSTOP: at91cEndPollStop (pDrvCtrl); break; case EIOCGMIB2: if (data == NULL) return (EINVAL); bcopy((char *)&pDrvCtrl->end.mib2Tbl, (char *)data, sizeof(pDrvCtrl->end.mib2Tbl)); break; case EIOCGFBUF: if (data == NULL) return (EINVAL); *(int *)data = 0; /**END_MIN_FBUF;**/ break; default: error = EINVAL; } return (error); }/******************************************************************************** at91cEndConfig - reconfigure the interface under us.** Reconfigure the interface setting promiscuous mode** RETURNS: N/A.*/LOCAL void at91cEndConfig ( END_DEVICE *pDrvCtrl /* device to be re-configured */ ) { at91cEndPIOConfig(); /*PIO pins config for EMAC */ at91cEndReset(pDrvCtrl); /* reset the chip */ pDrvCtrl->rxHandling = FALSE; /* Set up address filter for multicasting. */ if (END_MULTI_LST_CNT(&pDrvCtrl->end) > 0) at91cEndAddrFilterSet (pDrvCtrl);#if 0 if (pDrvCtrl->fdInitialized == TRUE) at91cEndFdFree(pDrvCtrl); /* Free the FDs */ /* Reinitialize FDs */ if (at91cEndFdInitialize(pDrvCtrl) == ERROR) { DRV_LOG (DRV_DEBUG_LOAD, "at91cEndFdInitialize failed \n", 0, 0, 0, 0, 0, 0); return; }#endif at91cEndMacInitialize(pDrvCtrl); /* Initialize MAC */ /* Was started before in interrupt mode? */ if ((END_FLAGS_GET(&pDrvCtrl->end) & IFF_RUNNING) && ((pDrvCtrl->flags & LS_POLLING) == 0)) at91cEndStart(pDrvCtrl); /* Start again */ return; }#if 1/******************************************************************************** at91cEndPollStart - start polled mode operations** RETURNS: OK or ERROR.*/LOCAL STATUS at91cEndPollStart ( END_DEVICE* pDrvCtrl /* device to be polled */ ) { int oldLevel; oldLevel = intLock (); /* disable ints during update */ intDisable (pDrvCtrl->ivecEMAC); pDrvCtrl->flags |= LS_POLLING; intUnlock (oldLevel); /* now at91cEndInt won't get confused */ ENDLOGMSG (("Poll STARTED\n", 1, 2, 3, 4, 5, 6)); at91cEndConfig (pDrvCtrl); /* reconfigure device */ /*Enable Rx */ *(volatile UINT32 *)AT91C_EMAC_CTL |= AT91C_EMAC_RE ; /* Set the flags to indicate that the device is up */ END_FLAGS_SET (&pDrvCtrl->end, IFF_UP | IFF_RUNNING); return (OK); }/******************************************************************************** at91cEndPollStop - stop polled mode operations** This function terminates polled mode operation. The device returns to* interrupt mode.** The device interrupts are enabled, the current mode flag is switched* to indicate interrupt mode and the device is then reconfigured for* interrupt operation.** RETURNS: OK or ERROR.*/LOCAL STATUS at91cEndPollStop ( END_DEVICE* pDrvCtrl /* device to be changed */ ) { *(volatile UINT32 *)AT91C_EMAC_CTL &= ~(AT91C_EMAC_RE | AT91C_EMAC_TE); pDrvCtrl->flags &= ~LS_POLLING; pDrvCtrl->rxHandling = TRUE; /* * Restart in interrupt mode. Calling at91cEndConfig without clearing * IFF_RUNNING flag will result in calling at91cEndStart automatically */ netJobAdd ((FUNCPTR) at91cEndConfig, (int) pDrvCtrl, 0, 0, 0, 0); ENDLOGMSG (("Poll STOPPED\n", 1, 2, 3, 4, 5, 6)); return (OK); }/******************************************************************************** at91cEndPollRcv - routine to receive a packet in polled mode.** This routine is called by a user to try and get a packet from the* device.** RETURNS: OK upon success. EAGAIN is returned when no packet is available.*/LOCAL STATUS at91cEndPollRcv ( END_DEVICE *pDrvCtrl, /* device to be polled */ M_BLK_ID pMblk /* ptr to buffer */ ) { UINT32 stat; char* pPacket; /* int len;*/ UINT32 len; STATUS retVal = EAGAIN;#ifdef ENDDEBUG if (endDebug) nvLogMsg ("at91cEndPollRcv\n", 1, 2, 3, 4, 5, 6);#endif /* ENDDEBUG */ if (pDrvCtrl->rxHandling) {#ifdef ENDDEBUG if (endDebug) nvLogMsg ("at91cEndPollRcv rxHandling\n", 1, 2, 3, 4, 5, 6);#endif /* ENDDEBUG */ return EAGAIN; }if(pDrvCtrl->pRxBufDesc->w0.ownerShip!=OWNED_BY_CPU) return EAGAIN; stat = *(volatile UINT32 *)AT91C_EMAC_RSR; if ((stat & AT91C_EMAC_REC) == 0) {#ifdef ENDDEBUG if (endDebug) nvLogMsg ("at91cEndPollRcv done every\n", 1, 2, 3, 4, 5, 6);#endif /* ENDDEBUG */ return EAGAIN; } /* Reset the status bit */ *(volatile UINT32 *)AT91C_EMAC_RSR = stat; pDrvCtrl->statistics.rxOK = *(volatile UINT32*)AT91C_EMAC_OK; if (pDrvCtrl->statistics.rxOK == 0) goto pollRcvExit; /* Upper layer must provide a valid buffer. */ len = (pDrvCtrl->pRxBufDesc->w1.frameLength); if ((pMblk->mBlkHdr.mLen < len) || (!(pMblk->mBlkHdr.mFlags & M_EXT))) goto pollRcvExit; END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1); pPacket = (UINT32)((char *)pDrvCtrl->pRxBufDesc->w0.baseAddrRecBuf)<<2; bcopy (pPacket, pMblk->mBlkHdr.mData, len + AT91C_DATA_OFFSET); pMblk->mBlkHdr.mData += AT91C_DATA_OFFSET; pMblk->mBlkHdr.mFlags |= M_PKTHDR; pMblk->mBlkHdr.mLen = len; pMblk->mBlkPktHdr.len = len; retVal = OK;#ifdef ENDDEBUG if (endDebug) nvLogMsg ("at91cEndPollRcv OK\n", 1, 2, 3, 4, 5, 6);#endif /* ENDDEBUG */pollRcvExit: /* Rx status length field */ pDrvCtrl->pRxBufDesc->w1.frameLength = 0; /* Ownership back to BDMA */ pDrvCtrl->pRxBufDesc->w0.ownerShip = OWNED_BY_DMA;#ifdef ENDDEBUG if (endDebug) nvLogMsg ("at91cEndPollRcv EXIT\n", 1, 2, 3, 4, 5, 6);#endif /* ENDDEBUG */ return retVal; }/******************************************************************************** at91cEndPollSend - routine to send a packet in polled mode.** This routine is called by a user to try and send a packet on the* device.** RETURNS: OK upon success. EAGAIN if device is busy.*/LOCAL STATUS at91cEndPollSend ( END_DEVICE* pDrvCtrl, /* device to be polled */ M_BLK_ID pMblk /* packet to send */ ) { UCHAR *pTx; int len; UINT32 stat;#ifdef ENDDEBUG if (endDebug) nvLogMsg ("at91cEndPollSend\n", 1, 2, 3, 4, 5, 6);#endif /* ENDDEBUG */ if (pDrvCtrl->resetting) { return EAGAIN; } /* Ownership */ stat = *(volatile UINT32 *)AT91C_EMAC_TSR; if (!(stat & AT91C_EMAC_BNQ)) return EAGAIN; pTx = pDrvCtrl->pTxBuf; /* Set pointers in local structures to point to data. */ len = netMblkToBufCopy(pMblk, (void *)pTx, NULL) ; *(volatile UINT32 *)AT91C_EMAC_TSR = stat;/* Reset control word */ /* initiate device transmit */ *(volatile UINT32 *)(AT91C_EMAC_TAR) = pTx; *(volatile UINT32 *)(AT91C_EMAC_TCR) = len; *(volatile UINT32 *)AT91C_EMAC_CTL |= AT91C_EMAC_TE; /* Bump the statistic counter. */ END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_UCAST, +1);#if 0 /* Advance our management index */ pDrvCtrl->pTxBufDesc = pDrvCtrl->pTxBufDesc->nextTxBufDesc;#endif /* * Cleanup. The driver must either free the packet now or * set up a structure so it can be freed later after a transmit * interrupt occurs. */ netMblkClChainFree (pMblk);#ifdef ENDDEBUG if (endDebug) nvLogMsg ("leaving at91cEndPollSend\n", 1, 2, 3, 4, 5, 6);#endif /* ENDDEBUG */ return (OK); }#endif/******************************************************************************** at91cEndAddrFilterSet - set the address filter for multicast addresses** This routine goes through all of the multicast addresses on the list* of addresses (added with the endAddrAdd() routine) and sets the* device's filter correctly.** RETURNS: N/A.*/LOCAL void at91cEndAddrFilterSet ( END_DEVICE *pDrvCtrl /* device to be updated */ ) { ETHER_MULTI* pCurr; UINT32 count; UCHAR *pAddr;#if (_BYTE_ORDER != _LITTLE_ENDIAN) UCHAR *pEnetAddr;#endif for (count = 0; count < 6; count++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -