📄 sngks32cend.c
字号:
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); }/******************************************************************************* at91cEndMCastGet - 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 at91cEndMCastGet ( END_DEVICE* pDrvCtrl, /* device pointer */ MULTI_TABLE* pTable /* address table to be filled in */ ) { int error; error = etherMultiGet (&pDrvCtrl->end.multiList, pTable); return (error); }/******************************************************************************** at91cEndStop - 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 at91cEndStop ( END_DEVICE *pDrvCtrl /* device to be stopped */ ) { STATUS result = OK; *(volatile UINT32 *)AT91C_EMAC_CTL &= ~(AT91C_EMAC_RE | AT91C_EMAC_TE); intDisable (pDrvCtrl->ivecEMAC); END_FLAGS_CLR (&pDrvCtrl->end, IFF_UP | IFF_RUNNING); return (result); }/******************************************************************************* at91cEndReset - Reset the device* This function resets the driver after initializing from at91cEndLoad*/LOCAL void at91cEndReset ( END_DEVICE* pDrvCtrl /* device to be reset */ ) { UINT32 stat1, stat2; char lab; if(pDrvCtrl->unit != 0) return; if (pDrvCtrl->autoNeg == 1) /* auto negotiation enabled? */ { at91cEndPhyWrite (PHY_CONTROL_REG, PHY_ADDR, _AUTO_NEGOTIATE); stat1 = at91cEndPhyRead(PHY_STS1_REG,0); if(!(stat1 & 0x4)) { return; /* no link */ } stat2 = at91cEndPhyRead(PHY_STS2_REG,0); if ((stat1 & 0x4000) && (stat2 & 0x8000) ) /*set RMII for 100BaseTX and Full Duplex*/ { lab = 'A'; } else if ((stat1 & 0x2000) && (stat2 & 0x4000)) /*set MII for 100BaseTX and Half Duplex */ { lab = 'B'; } else if ((stat1 & 0x1000) && (stat2 & 0x2000)) /*set MII for 10BaseT and Full Duplex */ { lab = 'C'; } else if ((stat1 & 0x0800) && (stat2 & 0x1000)) /*set MII for 10BaseT and Half Duplex */ { lab = 'D'; } } else if (pDrvCtrl->netSpeed == 10) { if (pDrvCtrl->duplexMode == 1) /* FDX */ { at91cEndPhyWrite (PHY_CONTROL_REG, PHY_ADDR, _10_MB_FDX); lab = 'C'; } else { at91cEndPhyWrite (PHY_CONTROL_REG, PHY_ADDR, _10_MB_HDX); lab = 'D'; } } else if (pDrvCtrl->netSpeed == 100) { if (pDrvCtrl->duplexMode == 1) /* FDX */ { at91cEndPhyWrite (PHY_CONTROL_REG, PHY_ADDR, _100_MB_FDX); lab = 'A'; } else { at91cEndPhyWrite (PHY_CONTROL_REG, PHY_ADDR, _100_MB_HDX); lab = 'B'; } } switch(lab) { case 'A': *(volatile UINT32 *)AT91C_EMAC_CFG |= AT91C_EMAC_SPD| AT91C_EMAC_FD; break; case 'B': *(volatile UINT32 *)AT91C_EMAC_CFG |= AT91C_EMAC_SPD; *(volatile UINT32 *)AT91C_EMAC_CFG &= ~AT91C_EMAC_FD; break; case 'C': *(volatile UINT32 *)AT91C_EMAC_CFG &= ~AT91C_EMAC_SPD; *(volatile UINT32 *)AT91C_EMAC_CFG |= AT91C_EMAC_FD; break; case 'D': *(volatile UINT32 *)AT91C_EMAC_CFG &= ~(AT91C_EMAC_SPD| AT91C_EMAC_FD); break; default : break; } *(volatile UINT32 *)AT91C_EMAC_CTL |= AT91C_EMAC_CSR; /*clear the statistic regs*/ *(volatile UINT32 *)AT91C_EMAC_CTL = 0; *(volatile UINT32 *)AT91C_EMAC_TSR= 0; *(volatile UINT32 *)AT91C_EMAC_RSR= 0; /* *(volatile UINT32 *)AT91C_EMAC_CFG |= (AT91C_EMAC_RMII |AT91C_EMAC_CAF);*/ *(volatile UINT32 *)AT91C_EMAC_CFG |= (AT91C_EMAC_RMII ); return; }#undef DYNAMIC_PHY/******************************************************************************* at91cEndPhyRead - Read PHY device* This function is used to read a byte from the PHY device*/LOCAL UINT32 at91cEndPhyRead ( UINT32 phyRegAddr, /* Address of PHY register to be read */ UINT32 phyAddr /* Address of the PHY chip (usually 0 for single PHY) */ ) { UINT32 phyData; *(volatile UINT32 *)AT91C_EMAC_CTL |= AT91C_EMAC_MPE; /*Management Port Enable */ *(volatile UINT32 *)AT91C_EMAC_MAN = AT91C_EMAC_CODE |AT91C_EMAC_RD |AT91C_EMAC_HIGH | phyRegAddr << 18 |phyAddr <<23; while ( (*(volatile UINT32 *)AT91C_EMAC_SR & 0x4) == 0) /***** IDLE bit ******/ ; /* Wait till IDLE bit is SET */ phyData = *(volatile UINT32*)AT91C_EMAC_MAN & AT91C_EMAC_DATA ; *(volatile UINT32 *)AT91C_EMAC_CTL &= ~AT91C_EMAC_MPE; /*Management Port disable */ return (phyData); } /*DYNAMIC_PHY*//******************************************************************************* at91cEndPhyWrite - Write into PHY device* This function is used to write a byte to the PHY device*/LOCAL void at91cEndPhyWrite ( 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 */ ) { /* UINT32 count = 1000;*/ *(volatile UINT32 *)AT91C_EMAC_CTL |= AT91C_EMAC_MPE; /*Management Port Enable */ *(volatile UINT32 *)AT91C_EMAC_MAN = AT91C_EMAC_CODE |AT91C_EMAC_WR |AT91C_EMAC_HIGH | phyRegAddr << 18 |phyAddr <<23 | phyData ; while ( (*(volatile UINT32 *)AT91C_EMAC_SR & 0x4) == 0) /***** IDLE bit ******/ ; /* Wait till IDLE bit is SET *//* while (count--) ; */ /* Dummy delay after PHY write */ *(volatile UINT32 *)AT91C_EMAC_CTL &= ~AT91C_EMAC_MPE; /*Management Port disable */ }/******************************************************************************* at91cEndMacIntialize - Initialize MAC/BDMA registers* Initialize the MAC and BDMA registers to make the Ethernet* interface functional*/LOCAL void at91cEndMacInitialize ( END_DEVICE *pDrvCtrl /* Device that has to be initialized */ ) { UCHAR *pAddr; /* UINT32 temp; UINT32 * SAH; UINT32 *SAL; UCHAR count; */ #if 1#if (_BYTE_ORDER != _LITTLE_ENDIAN) UCHAR *pEnetAddr;#endif#endif#if 0#ifdef DYNAMIC_PHY UINT32 phyStat2;#endif DYNAMIC_PHY /* init MAC register *//*动态物理层处理?*/#ifdef DYNAMIC_PHY phyStat2 = at91cEndPhyRead (PHY_DSCSR_REG,0); if (phyStat2 & FDX) *(volatile UINT32 *)AT91C_EMAC_CFG |= AT91C_EMAC_FD;#else /*DYNAMIC_PHY*/ if ((pDrvCtrl->autoNeg == 0) && (pDrvCtrl->duplexMode == 1)) *(volatile UINT32 *)AT91C_EMAC_CFG |= AT91C_EMAC_FD;#endif /*DYNAMIC_PHY*/#ifdef LOOPBACK_DEBUG printf ("********* END DRIVER LOOPBACK DEBUG MODE *************\n"); *(volatile UINT32 *)AT91C_EMAC_CTL |= AT91C_EMAC_LBL;#endif /*LOOPBACK_DEBUG*/#endif#if 1 /* Copy our MAC address to the first location in address array */ pAddr = (UCHAR *)(&(pDrvCtrl->addrList[0]));#if (_BYTE_ORDER == _LITTLE_ENDIAN) *(UINT32 *)pAddr = htonl (*(UINT32 *)pDrvCtrl->enetAddr); pAddr += 6; *(UINT16 *)pAddr = htons (*(UINT16 *)(pDrvCtrl->enetAddr+4));#else /* (_BYTE_ORDER == _LITTLE_ENDIAN) */ /* big endian: no need to swap */ for (pEnetAddr=pDrvCtrl->enetAddr; pEnetAddr<pDrvCtrl->enetAddr+6; pEnetAddr++) { *pAddr++ = *pEnetAddr; }#endif /* (_BYTE_ORDER == _LITTLE_ENDIAN) */#endif /* Copy the address array into Specific registers */#if 0/*对不对呢*/pAddr = (UCHAR *)(&(pDrvCtrl->addrList[0]));SAH = AT91C_EMAC_SA1H;SAL = AT91C_EMAC_SA1L;count = 0;while((count <4)&&(count<=(pDrvCtrl->mcastAddrCount)) )/*4 specificed address*/{ #if (_BYTE_ORDER == _LITTLE_ENDIAN) /*3-2-1-0,7-6-5-4,B-A-9-8,F-E-D-C...*/ if((count & 1) == 0) { *(volatile UINT32 *)SAH = htons(*(UINT16 *)(pAddr+2)); *(volatile UINT32 *)SAL = htons(*(UINT16 *)pAddr)<<16 + htons(*(UINT16 *)(pAddr + 6)); } else { *(volatile UINT32 *)SAH = htons(*(UINT16*)(pAddr - 2)); *(volatile UINT32 *)SAL = htonl(*(UINT32 *)(pAddr + 2)); }#else *(volatile UINT32 *)SAH = *(UINT16 *)pAddr; *(volatile UINT32 *)SAL = *(UINT32 *)(pAddr+2);#endif /* (_BYTE_ORDER == _LITTLE_ENDIAN) */ (UINT32 *)SAH += 2; (UINT32 *)SAL += 2; pAddr += 6; count++;}#endif/*MAC地址--写入特殊地址*//*pAddr = sysAt91cMacAddr;*/#if 0#if (_BYTE_ORDER == _LITTLE_ENDIAN)*(volatile UINT32 *) AT91C_EMAC_SA1H = htons(*(UINT16 *)pAddr);*(volatile UINT32 *) AT91C_EMAC_SA1L = htonl (*(UINT32 *)(pAddr+2));#else /* (_BYTE_ORDER == _LITTLE_ENDIAN) */ /* big endian: no need to swap */*(volatile UINT32 *) AT91C_EMAC_SA1H = (*(UINT16 *)pAddr);*(volatile UINT32 *) AT91C_EMAC_SA1L = *(UINT32 *)(pAddr+2);#endif /* (_BYTE_ORDER == _LITTLE_ENDIAN) */#endif#if 0*(vol
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -