void mcf523xfec_reset( mcf523xfec_if_t * fecif ) { extern void ( *__RAMVEC[] ) ( ); int old_ipl = asm_set_ipl( 7 ); /* Reset the FEC - equivalent to a hard reset */ MCF_FEC_ECR = MCF_FEC_ECR_RESET; /* Wait for the reset sequence to complete */ while( MCF_FEC_ECR & MCF_FEC_ECR_RESET ); /* Disable all FEC interrupts by clearing the EIMR register */ MCF_FEC_EIMR = 0; /* Clear any interrupts by setting all bits in the EIR register */ MCF_FEC_EIR = 0xFFFFFFFFUL; /* Configure Interrupt vectors. */ __RAMVEC[MCF_FEC_VEC_RXF] = mcf523xfec_rx_irq; /* Set the source address for the controller */ MCF_FEC_PALR = ( fecif->self->addr[0] << 24U ) | ( fecif->self->addr[1] << 16U ) | ( fecif->self->addr[2] << 8U ) | ( fecif->self->addr[3] << 0U ); MCF_FEC_PAUR = ( fecif->self->addr[4] << 24U ) | ( fecif->self->addr[5] << 16U ); /* Initialize the hash table registers */ MCF_FEC_IAUR = 0; MCF_FEC_IALR = 0; /* Set Receive Buffer Size */ #if RX_BUFFER_SIZE != 2048 #error "RX_BUFFER_SIZE must be set to 2048 for safe FEC operation." #endif MCF_FEC_EMRBR = RX_BUFFER_SIZE - 1; /* Point to the start of the circular Rx buffer descriptor queue */ MCF_FEC_ERDSR = nbuf_get_start( NBUF_RX ); /* Point to the start of the circular Tx buffer descriptor queue */ MCF_FEC_ETDSR = nbuf_get_start( NBUF_TX ); /* Set the tranceiver interface to MII mode */ MCF_FEC_RCR = MCF_FEC_RCR_MAX_FL( MCF_FEC_MTU ) | MCF_FEC_RCR_MII_MODE; /* Set MII Speed Control Register for 2.5Mhz */ MCF_FEC_MSCR = MCF_FEC_MSCR_MII_SPEED( FSYS_2 / ( 2UL * 2500000UL ) ); /* Only operate in half-duplex, no heart beat control */ MCF_FEC_TCR = 0; /* Enable Debug support */ FEC_DEBUG_INIT; FEC_DEBUG_RX_TIMING( 0 ); FEC_DEBUG_TX_TIMING( 0 ); ( void )asm_set_ipl( old_ipl ); }
void fec_process() { NBUF *pNbuf; uint8 pid; int i; /* Receive descriptors polling */ pNbuf = (NBUF *)nbuf_get_start(Rx); for (i = 0; i < NUM_RXBDS; i++) { if ( !(pNbuf[i].status & RX_BD_E) ) { /* Switch to network process */ pid = tmr_load_switch(net_pid); /* Read packet */ fec_receive(&pNbuf[i]); fec_rx_release(&pNbuf[i]); /* Switch back */ tmr_load_switch(pid); } } }
int fec_init() { int i; /* Reset the FEC - equivalent to a hard reset */ MCF5282_FEC_ECR = MCF5282_FEC_ECR_RESET; /* Wait for the reset sequence to complete */ while (MCF5282_FEC_ECR & MCF5282_FEC_ECR_RESET); /* Disable all FEC interrupts by clearing the EIMR register */ MCF5282_FEC_EIMR = 0; /* Clear any interrupts by setting all bits in the EIR register */ MCF5282_FEC_EIR = 0xFFFFFFFF; /* Enable MIB Counters */ for (i = 0; i < 57; i++) (*(vuint32 *)(void *)(&__IPSBAR[0x1200 + i*4])) = 0; MCF5282_FEC_MIBC = 0; /* Set the source address for the controller */ MCF5282_FEC_PALR = (0 | (eeprom.fec_mac[0] <<24) | (eeprom.fec_mac[1] <<16) | (eeprom.fec_mac[2] <<8) | (eeprom.fec_mac[3] <<0)); MCF5282_FEC_PAUR = (0 | (eeprom.fec_mac[4] <<24) | (eeprom.fec_mac[5] <<16)); /* Initialize the hash table registers */ MCF5282_FEC_IAUR = 0; MCF5282_FEC_IALR = 0; /* Setup Buffers */ MCF5282_FEC_EMRBR = (uint16)RX_BUFFER_SIZE; MCF5282_FEC_ERDSR = nbuf_get_start(Rx); MCF5282_FEC_ETDSR = nbuf_get_start(Tx); /* Set the tranceiver interface to MII mode */ MCF5282_FEC_RCR = (1522 << 16) | MCF5282_FEC_RCR_MII_MODE; /* Only operate in half-duplex, no heart beat control */ MCF5282_FEC_TCR = 0; /* Enable FEC */ MCF5282_FEC_ECR = MCF5282_FEC_ECR_ETHER_EN; /* Allow interrupts by setting IMR register */ /* MCF5282_FEC_EIMR = MCF5282_FEC_EIMR_RXF; */ /* Indicate that there have been empty receive buffers produced */ MCF5282_FEC_RDAR = 1; /* Enable MII control interface and reset PHY */ MCF5282_FEC_MSCR = 0x001C; fec_setMII(0, 0, 0x8000); /* Wait for PHY reset */ tmr_gp_wait(2); /* Create network process */ net_pid = tmr_load_register("Network"); return 0; }