📄 sngks32cend.c
字号:
} if (bdmaStat.stat_reg.bdmaRxDoneEveryRxFrame == 0) {#ifdef ENDDEBUG if (endDebug) nvLogMsg ("sngks32cEndPollRcv done every\n", 1, 2, 3, 4, 5, 6);#endif /* ENDDEBUG */ return EAGAIN; } /* Reset the status bit */ *(volatile UINT32 *)SNGKS32C_BDMASTAT |= bdmaStat.stat_resetval; if (pDrvCtrl->pRxFrameDesc->rxStatusLength.good == 0) goto pollRcvExit; /* Upper layer must provide a valid buffer. */ len = pDrvCtrl->pRxFrameDesc->rxStatusLength.frameLength; if ((pMblk->mBlkHdr.mLen < len) || (!(pMblk->mBlkHdr.mFlags & M_EXT))) goto pollRcvExit; END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1); pPacket = (char *)pDrvCtrl->pRxFrameDesc->rxFrameData.frameDataPtr; bcopy (pPacket, pMblk->mBlkHdr.mData, len + SNGKS32C_DATA_OFFSET); pMblk->mBlkHdr.mData += SNGKS32C_DATA_OFFSET; pMblk->mBlkHdr.mFlags |= M_PKTHDR; pMblk->mBlkHdr.mLen = len; pMblk->mBlkPktHdr.len = len; retVal = OK;#ifdef ENDDEBUG if (endDebug) nvLogMsg ("sngks32cEndPollRcv OK\n", 1, 2, 3, 4, 5, 6);#endif /* ENDDEBUG */pollRcvExit: /* Rx status length field */ *(UINT32 *)(&pDrvCtrl->pRxFrameDesc->rxStatusLength) = 0; /* Ownership back to BDMA */ pDrvCtrl->pRxFrameDesc->rxFrameData.o_bit = OWNED_BY_BDMA; pDrvCtrl->pRxFrameDesc = pDrvCtrl->pRxFrameDesc->nextRxFrameDesc;#ifdef ENDDEBUG if (endDebug) nvLogMsg ("sngks32cEndPollRcv EXIT\n", 1, 2, 3, 4, 5, 6);#endif /* ENDDEBUG */ return retVal; }/******************************************************************************** sngks32cEndPollSend - 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 sngks32cEndPollSend ( END_DEVICE* pDrvCtrl, /* device to be polled */ M_BLK_ID pMblk /* packet to send */ ) { TRANSMIT_FRAME_DESC *pTxFd; BDMATXCON bdmaTxCon; MACTXCON macTxCon; int len;#ifdef ENDDEBUG if (endDebug) nvLogMsg ("sngks32cEndPollSend\n", 1, 2, 3, 4, 5, 6);#endif /* ENDDEBUG */ if (pDrvCtrl->resetting) { return EAGAIN; } /* Ownership with BDMA? */ if (pDrvCtrl->pTxFrameDesc->txFrameData.o_bit == OWNED_BY_BDMA) return EAGAIN; pTxFd = pDrvCtrl->pTxFrameDesc; /* Set pointers in local structures to point to data. */ len = netMblkToBufCopy(pMblk, (void *)pTxFd->txFrameData.frameDataPtr, NULL) ; *(UINT32 *)(&pTxFd->txControl) = 0; /* Reset control word */ pTxFd->txControl.t_bit = 1; pTxFd->txControl.a_bit = 1; pTxFd->txControl.l_bit = SNGEND_ENDIAN; pTxFd->txStatusLength.frameLength = len; pTxFd->txFrameData.o_bit = OWNED_BY_BDMA; /* initiate device transmit */ bdmaTxCon.txCon_resetval = *(volatile UINT32 *)SNGKS32C_BDMATXCON; bdmaTxCon.txCon_reg.enable = 1; *(volatile UINT32 *)SNGKS32C_BDMATXCON = bdmaTxCon.txCon_resetval; macTxCon.macTxCon_resetval = *(volatile UINT32 *)SNGKS32C_MACTXCON; macTxCon.macTxCon_reg.transmitEnable = 1; *(volatile UINT32 *)SNGKS32C_MACTXCON = macTxCon.macTxCon_resetval; /* Bump the statistic counter. */ END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_UCAST, +1); /* Advance our management index */ pDrvCtrl->pTxFrameDesc = pDrvCtrl->pTxFrameDesc->nextTxFrameDesc; /* * 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 sngks32cEndPollSend\n", 1, 2, 3, 4, 5, 6);#endif /* ENDDEBUG */ return (OK); }/******************************************************************************** sngks32cEndAddrFilterSet - 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 sngks32cEndAddrFilterSet ( 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 < 32; 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); /* * 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 sngks32cEndMacInitialize() function */ while (pCurr != NULL) { if (pDrvCtrl->mcastAddrCount > SNGKS32C_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); } }/******************************************************************************* sngks32cEndMCastAdd - 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 sngks32cEndMCastAdd ( END_DEVICE *pDrvCtrl, /* device pointer */ char* pAddress /* new address to add */ ) { int error; if ((error = etherMultiAdd (&pDrvCtrl->end.multiList, pAddress)) == ENETRESET) sngks32cEndConfig (pDrvCtrl); return (OK); }/******************************************************************************* sngks32cEndMCastDel - 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 sngks32cEndMCastDel ( END_DEVICE* pDrvCtrl, /* device pointer */ char* pAddress /* address to be deleted */ ) { int error; if ((error = etherMultiDel (&pDrvCtrl->end.multiList, (char *)pAddress)) == ENETRESET) sngks32cEndConfig (pDrvCtrl); return (OK); }/******************************************************************************* sngks32cEndMCastGet - get the multicast address list for the device** This routine gets the multicast list of whatever the driver* is already listening for.** RETURNS: OK or ERROR.*/LOCAL STATUS sngks32cEndMCastGet ( END_DEVICE* pDrvCtrl, /* device pointer */ MULTI_TABLE* pTable /* address table to be filled in */ ) { int error; error = etherMultiGet (&pDrvCtrl->end.multiList, pTable); return (error); }/******************************************************************************** sngks32cEndStop - stop the device** This function calls BSP functions to disconnect interrupts and stop* the device from operating in interrupt mode.** RETURNS: OK or ERROR.*/LOCAL STATUS sngks32cEndStop ( END_DEVICE *pDrvCtrl /* device to be stopped */ ) { STATUS result = OK; BDMARXCON bdmaRxCon; BDMATXCON bdmaTxCon; MACCON macCon; *(UINT32 *)(&bdmaRxCon) = *(volatile UINT32 *)SNGKS32C_BDMARXCON; bdmaRxCon.rxCon_reg.enable = 0; *(volatile UINT32 *)SNGKS32C_BDMARXCON = *(UINT32 *)(&bdmaRxCon); *(UINT32 *)(&bdmaTxCon) = *(volatile UINT32 *)SNGKS32C_BDMATXCON; bdmaTxCon.txCon_reg.enable = 0; *(volatile UINT32 *)SNGKS32C_BDMATXCON = *(UINT32 *)(&bdmaTxCon); *(UINT32 *)(&macCon) = *(volatile UINT32 *)SNGKS32C_MACCON; macCon.macCon_reg.haltImm = 1; *(volatile UINT32 *)SNGKS32C_MACCON = *(UINT32 *)(&macCon); intDisable (pDrvCtrl->ivecBdmaTx); intDisable (pDrvCtrl->ivecBdmaRx); intDisable (pDrvCtrl->ivecMacTx); intDisable (pDrvCtrl->ivecMacRx); END_FLAGS_CLR (&pDrvCtrl->end, IFF_UP | IFF_RUNNING); return (result); }/******************************************************************************* sngks32cEndReset - Reset the device* This function resets the driver after initializing from sngks32cEndLoad*/LOCAL void sngks32cEndReset ( END_DEVICE* pDrvCtrl /* device to be reset */ ) { BDMARXCON bdmaRxCon; BDMATXCON bdmaTxCon; BDMARXLSZ bdmaRxLsz; MACCON macCon; if(pDrvCtrl->unit != 0) return; *(UINT32 *) (&bdmaRxCon) = 0; *(UINT32 *) (&bdmaTxCon) = 0; *(UINT32 *) (&bdmaRxLsz) = 0; *(UINT32 *) (&macCon) = 0; if (pDrvCtrl->autoNeg == 1) /* auto negotiation enabled? */ sngks32cEndPhyWrite (PHY_CONTROL_REG, PHY_ADDR, _AUTO_NEGOTIATE); else if (pDrvCtrl->netSpeed == 10) sngks32cEndPhyWrite (PHY_CONTROL_REG, PHY_ADDR, _10_MB_HDX); else if (pDrvCtrl->netSpeed == 100) { if (pDrvCtrl->duplexMode == 1) /* FDX */ sngks32cEndPhyWrite (PHY_CONTROL_REG, PHY_ADDR, _100_MB_FDX); else sngks32cEndPhyWrite (PHY_CONTROL_REG, PHY_ADDR, _100_MB_HDX); } bdmaRxCon.rxCon_reg.reset = 1; *(volatile UINT32 *)SNGKS32C_BDMARXCON = bdmaRxCon.rxCon_resetval; bdmaTxCon.txCon_reg.reset = 1; *(volatile UINT32 *)SNGKS32C_BDMATXCON = bdmaTxCon.txCon_resetval; bdmaRxLsz.rxLsz_reg.bdmaRxMaxSize = END_BUFSIZ; *(volatile UINT32 *)SNGKS32C_BDMARXLSZ = bdmaRxLsz.rxLsz_resetval; macCon.macCon_reg.swReset = 1; *(volatile UINT32 *)SNGKS32C_MACCON = macCon.macCon_resetval; return; }#ifdef DYNAMIC_PHY/******************************************************************************* sngks32cEndPhyRead - Read PHY device* This function is used to read a byte from the PHY device*/LOCAL UINT32 sngks32cEndPhyRead ( UINT32 phyRegAddr, /* Address of PHY register to be read */ UINT32 phyAddr /* Address of the PHY chip (usually 0 for single PHY) */ ) { UINT32 phyData; STACON staCon; *(UINT32 *) (&staCon) = 0; staCon.staCon_reg.phyRegisterAddr = phyRegAddr; staCon.staCon_reg.phyAddr = phyAddr; staCon.staCon_reg.busy = 1; *(volatile UINT32 *)SNGKS32C_STACON = staCon.staCon_resetval; while (*(volatile UINT32 *)SNGKS32C_STACON & 0x800) /***** Busy bit ***/ ; /* Wait till busy bit is clear */ phyData = *(volatile UINT32 *)(SNGKS32C_STADATA); return (phyData); }#endif /*DYNAMIC_PHY*//******************************************************************************* sngks32cEndPhyWrite - Write into PHY device* This function is used to write a byte to the PHY device*/LOCAL void sngks32cEndPhyWrite ( UINT32 phyRegAddr, /* Address of PHY register to be written */ UINT32 phyAddr, /* Address of the PHY chip (usually 0 for single PHY) */ UINT32 phyData /* Data to be written */ ) { STACON staCon; UINT32 count = 1000; *(volatile UINT32 *)(SNGKS32C_STADATA) = phyData; *(UINT32 *) (&staCon) = 0; staCon.staCon_reg.phyRegisterAddr = phyRegAddr; staCon.staCon_reg.phy
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -