📄 sngks32cend.c.bak
字号:
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;#if 0 /* Set up address filter for multicasting. */ if (END_MULTI_LST_CNT(&pDrvCtrl->end) > 0) at91cEndAddrFilterSet (pDrvCtrl);#endif at91cEndMacInitialize(pDrvCtrl); /* Initialize MAC */#if 1 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 /* 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 = (char *)((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 |= AT91C_EMAC_COMP;/* Reset control word */ /* initiate device transmit */ *(volatile UINT32 *)(AT91C_EMAC_TAR) = (UINT32)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++) pDrvCtrl->addrList[count] = 0; /* Zero the addresses */ pDrvCtrl->mcastAddrCount = 0; /* Init the multi count */ pAddr = (UCHAR *)(&pDrvCtrl->addrList[0]); pAddr += 6; /* Leave first 6 bytes for our MAC address */ pCurr = END_MULTI_LST_FIRST (&pDrvCtrl->end);#if 1 /* * Now copy the addresses from ether_multi_list to our own array. In our * array, the first 6 bytes are for our own MAC address. This array is * an exact replica of the internal CAM registers of Ethernet controller. * The CAM registers will be updated in at91cEndMacInitialize() function */ /*源地址为8bit大端格式--> 32bit 小/大端格式 * 例: * MAC: A-B-C-D-E-F ,0-1-2-3-4-5,6-7-8-9-a-b,??.... * *大端:ABCD-EF01-2345-6789-ab??.... *小端:DCBA-10FE-5432-9876-??ba..... * */ while (pCurr != NULL) { if (pDrvCtrl->mcastAddrCount > AT91C_MAX_MULTI) break;#if (_BYTE_ORDER == _LITTLE_ENDIAN) if (!(pDrvCtrl->mcastAddrCount & 0x01)) { pAddr -= 2; /* little endian: address has to be stored in a swapped fashion! */ *(UINT16 *)pAddr = htons (*(UINT16 *)pCurr->addr); pAddr += 4; *(UINT16 *)pAddr = htons (*(UINT16 *)(pCurr->addr+4)); pAddr += 2; *(UINT16 *)pAddr = htons (*(UINT16 *)(pCurr->addr+2)); } else { pAddr += 2; /* little endian: address has to be stored in a swapped fashion! */ *(UINT16 *)pAddr = htons (*(UINT16 *)(pCurr->addr+2)); pAddr += 2; *(UINT16 *)pAddr = htons (*(UINT16 *)pCurr->addr); pAddr += 4; *(UINT16 *)pAddr = htons (*(UINT16 *)(pCurr->addr+4)); }#else /* _LITTLE_ENDIAN */ /* big endian: no need to swap */ for (pEnetAddr=pCurr->addr; pEnetAddr < (UCHAR *)(pCurr->addr+6); pEnetAddr++) { *pAddr++ = *pEnetAddr; }#endif /* _LITTLE_ENDIAN */ /* Bump the multicast address count */ pDrvCtrl->mcastAddrCount++; /* Get the next address in the list */ pCurr = END_MULTI_LST_NEXT(pCurr); }#endif }/******************************************************************************* at91cEndMCastAdd - add a multicast address for the device** This routine adds a multicast address to whatever the driver* is already listening for. It then resets the address filter.** RETURNS: OK or ERROR.*/LOCAL STATUS at91cEndMCastAdd ( END_DEVICE *pDrvCtrl, /* device pointer */ char* pAddress /* new address to add */ ) { int error; if ((error = etherMultiAdd (&pDrvCtrl->end.multiList, pAddress)) == ENETRESET) at91cEndConfig (pDrvCtrl); return (OK); }/******************************************************************************* at91cEndMCastDel - delete a multicast address for the device** This routine removes a multicast address from whatever the driver* is listening for. It then resets the address filter.** RETURNS: OK or ERROR.*/LOCAL STATUS at91cEndMCastDel ( END_DEVICE* pDrvCtrl, /* device pointer */ char* pAddress /* address to be deleted */ ) { int error; if ((error = etherMultiDel (&pDrvCtrl->end.multiList, (char *)pAddress)) == ENETRESET) at91cEndConfig (pDrvCtrl); return (OK); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -