📄 mac.c.svn-base
字号:
/******************************************************************************** **** Copyright (c) 1999 ST Microelectronics **** All rights reserved **** **** Filename : mac_main.c **** Author : Armando Visconti **** Revision : 1.0 **** **** **** *********************************************************************************/#include "mac.h"#include "vic_pl190.h"#include "uart.h"#include "i2c.h"#include "udc_ahb.h"//typedef unsigned long size_t;//////////////////////////////////////////////////////////// MAC STRUCTURES //////////////////////////////////////////////////////////////static char RX_MAC_Frames[RX_MAC_DESCR_NUM][MAC_MAX_FRAME_SZ];static char TX_MAC_Frames[RX_MAC_DESCR_NUM][MAC_MAX_FRAME_SZ];static DmaMacDescr TX_MAC_DescrTable[TX_MAC_DESCR_NUM];static DmaMacDescr RX_MAC_DescrTable[RX_MAC_DESCR_NUM];static unsigned int RX_MAC_currDescNum = 0;static unsigned int TX_MAC_currDescNum = 0;static volatile unsigned short MAC_event_rx = 0;/* MAC Address*/static char MAC_Addr[6] = {0x08, 0x00, 0x63, 0x62, 0x61, 0x60};#ifndef __HAVE_ARCH_MEMCMP/** * memcmp - Compare two areas of memory * @cs: One area of memory * @ct: Another area of memory * @count: The size of the area. */int memcmp(const void * cs,const void * ct,size_t count){ const unsigned char *su1, *su2; int res = 0; for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--) if ((res = *su1 - *su2) != 0) break; return res;}#endif/* Alternative Address*///static char MAC_Addr_alt[6] = {0x08, 0x00, 0x63, 0x62, 0x61, 0x61}; //trial for promiscus mode///////////////////////////////////////////////////////////// MAC FUNCTIONS ///////////////////////////////////////////////////////////////********* structures creation *************/static void init_descrs(void){ int i; DmaMacDescr* RX_DmaDesc_p; DmaMacDescr* TX_DmaDesc_p; char ** RX_MACFrames_p; char ** TX_MACFrames_p; /* Build the Frame Descriptor table for receiving */ for (i = 0; i < RX_MAC_DESCR_NUM; i++) { RX_DmaDesc_p = (DmaMacDescr*)((MAC_ALIAS_MEMORY | (int)&(RX_MAC_DescrTable[i]))); RX_MACFrames_p = (char **) (MAC_ALIAS_MEMORY | (int)RX_MAC_Frames); if (i < RX_MAC_DESCR_NUM - 1) RX_DmaDesc_p->DmaMac_Next = ((int) &RX_MAC_DescrTable[i + 1] & DmaMac_DescrAddrMsk) | DmaMac_NpolEn; else RX_DmaDesc_p->DmaMac_Next = ((int) &RX_MAC_DescrTable[0] & DmaMac_DescrAddrMsk) | DmaMac_NpolEn; RX_DmaDesc_p->DmaMac_Addr = (RX_MAC_Frames[i]); RX_DmaDesc_p->DmaMac_Cntl = DmaMac_NxtEn | (MAC_MAX_FRAME_SZ & DmaMac_XferCntMsk) | ((32 * DmaMac_EntryTrigU) & DmaMac_EntryTrigMsk); RX_DmaDesc_p->TxRx_Status = DmaMac_Valid; } /* Start the DMA for receiving. */ *DmaMac_RxDMANext = ((int) RX_MAC_DescrTable & DmaMac_DescrAddrMsk) | DmaMac_NpolEn; *DmaMac_RxDMAStart = DmaMac_StartFetch | DmaMac_RxFilterFail | DmaMac_RxRuntFrame | DmaMac_RxCollSeen | ((1000 * DmaMac_DFetchDlyU) & DmaMac_DFetchDlyMsk); /* Build the Frame Descriptor table for sending */ for (i = 0; i < TX_MAC_DESCR_NUM; i++) { TX_DmaDesc_p = ( DmaMacDescr*)(MAC_ALIAS_MEMORY | (int)&(TX_MAC_DescrTable[i])); TX_MACFrames_p = (char **) (MAC_ALIAS_MEMORY | (int)TX_MAC_Frames); if (i < TX_MAC_DESCR_NUM - 1) TX_DmaDesc_p->DmaMac_Next = ((int) &TX_MAC_DescrTable[i + 1] & DmaMac_DescrAddrMsk) | DmaMac_NpolEn; else TX_DmaDesc_p->DmaMac_Next = ((int) &TX_MAC_DescrTable[0] & DmaMac_DescrAddrMsk) | DmaMac_NpolEn; TX_DmaDesc_p->DmaMac_Addr = (TX_MAC_Frames[i]); TX_DmaDesc_p->DmaMac_Cntl = DmaMac_NxtEn | (MAC_MAX_FRAME_SZ & DmaMac_XferCntMsk) | ((32 * DmaMac_EntryTrigU) & DmaMac_EntryTrigMsk); TX_DmaDesc_p->TxRx_Status = 0; } /* Start the DMA for sending. */ *DmaMac_TxDMANext = ((int) TX_MAC_DescrTable & DmaMac_DescrAddrMsk) | DmaMac_NpolEn; }/********************************************//********* PHY register setting *************/static void MAC_SetPhyLayer ( unsigned short PHYnum, // PHY num unsigned short PHYreg, // PHY register num unsigned short CtrlBit, // PHY Data unsigned short Set // Turn Off (0) or On (1) the mode ){ volatile unsigned int tmpval = 0; while (*Mii_AddrReg & Mii_Busy); // wait for busy bit to be zero ... // Program PHY address *Mii_AddrReg = ((PHYnum * Phy_AddrU) & Phy_AddrMsk) | ((PHYreg * Mii_RegisterU) & Mii_RegisterMsk); while (*Mii_AddrReg & Mii_Busy); // wait for busy bit to be zero ... tmpval = *Mii_DataReg; while (*Mii_AddrReg & Mii_Busy); // wait for busy bit to be zero ... // Set/Clear Control Bit. if (Set) *Mii_DataReg = tmpval | CtrlBit; else *Mii_DataReg = tmpval & ~CtrlBit; *Mii_AddrReg = ((PHYnum * Phy_AddrU) & Phy_AddrMsk) | ((PHYreg * Mii_RegisterU) & Mii_RegisterMsk) | Mii_Write; while (*Mii_AddrReg & Mii_Busy); // wait for busy bit to be zero ... /***************************************************************************** * FIXME!!! * This part is a sw workaround to avoid a problem in ST mac_phy. */ // Program PHY address *Mii_AddrReg = ((PHYnum * Phy_AddrU) & Phy_AddrMsk) | ((PHYreg * Mii_RegisterU) & Mii_RegisterMsk); while (*Mii_AddrReg & Mii_Busy); // wait for busy bit to be zero ... tmpval = *Mii_DataReg; while (*Mii_AddrReg & Mii_Busy); // wait for busy bit to be zero ... /****************************************************************************/}/********************************************//*********** PHY register read **************//*static void MAC_GetPhyLayer ( unsigned short PHYnum, // PHY num inside board unsigned short PHYreg, // PHY register num unsigned short *CtrlBit // PHY Operation Mode ){ *CtrlBit = 0x0; while (*Mii_AddrReg & Mii_Busy); // wait for busy bit to be zero ... // Program PHY address *Mii_AddrReg = ((PHYnum * Phy_AddrU) & Phy_AddrMsk) | ((PHYreg * Mii_RegisterU) & Mii_RegisterMsk); while (*Mii_AddrReg & Mii_Busy); // wait for busy bit to be zero ... *CtrlBit = *Mii_DataReg; while (*Mii_AddrReg & Mii_Busy); // wait for busy bit to be zero ...}*//********************************************//********* MAC interrupt Handler ************/void MAC_IRQ_Handler(void){ unsigned irq_stat = *DmaMac_IntStat; /* RX activity */ if (irq_stat & DmaMac_RxCurrDone) { MAC_event_rx = 1; // (disable interrupts!!! intctlIntDisable(ITC_MAC_int); // Clear Interrupt condition. *DmaMac_IntStat &= (DmaMac_RxCurrDone); } /* * TX activity */ if (irq_stat & DmaMac_TxCurrDone) { // (disable interrupts!!! //intctlIntDisable(ITC_MAC_int); // Clear Interrupt condition. *DmaMac_IntStat &= (DmaMac_TxCurrDone); } if(irq_stat & DmaMac_RxNext || irq_stat & DmaMac_TxNext) { // Clear Interrupt condition. *DmaMac_IntStat &= (DmaMac_RxNext | DmaMac_TxNext); } if(irq_stat & DmaMac_TxDone || irq_stat & DmaMac_RxDone) { // Clear Interrupt condition. *DmaMac_IntStat &= (DmaMac_TxDone | DmaMac_RxDone); } /** Packet Lost!! (Always active!!) **/ if (irq_stat & DmaMac_PckLost) { // Clear Interrupt condition. *DmaMac_IntStat &= DmaMac_PckLost; } if (irq_stat & DmaMac_MACInt) { // Clear Interrupt condition. *DmaMac_IntStat &= (DmaMac_MACInt); } /* Clear Interrupt condition. */ // *DmaMac_IntStat = 0xffffffff;}/********************************************//*********** MAC Init function **************/void mac_init(void){#if 1 /* 0 for simulation 1 for lab */ // Program the PHY // Step 1.Reset Phy chip and check initial status MAC_SetPhyLayer(0x0, Phy_CtrlReg, Phy_Reset, 1); // Step 2.Mode Setup <Auto Negotiation Enable> MAC_SetPhyLayer(0x0, Phy_CtrlReg, Phy_AutoNego, 1);#endif // Turn the reset off *DmaMac_Stat &= ~DmaMac_SRst; // Program the Burst Length for TX/RX *DmaMac_Stat |= DmaMac_RXBurst_16 | DmaMac_TXBurst_16; // Program the MAC Dst Address *Mac_AddrLO = MAC_Addr[0] + (MAC_Addr[1] << 8)+ (MAC_Addr[2] << 16)+ (MAC_Addr[3] << 24); *Mac_AddrHI = MAC_Addr[4] + (MAC_Addr[5] << 8); // Program the MAC Control Register *Mac_Ctrl = // Mac_RxAll|// Mac_PrmscMode| //trial for promiscus mode Mac_RxEn | Mac_TxEn | Mac_DfrChk | Mac_NoHeartBeat | Mac_AutoPadStrip |
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -