2 FreeRTOS.org V5.1.0 - Copyright (C) 2003-2008 Richard Barry.
\r
4 This file is part of the FreeRTOS.org distribution.
\r
6 FreeRTOS.org is free software; you can redistribute it and/or modify
\r
7 it under the terms of the GNU General Public License as published by
\r
8 the Free Software Foundation; either version 2 of the License, or
\r
9 (at your option) any later version.
\r
11 FreeRTOS.org is distributed in the hope that it will be useful,
\r
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
14 GNU General Public License for more details.
\r
16 You should have received a copy of the GNU General Public License
\r
17 along with FreeRTOS.org; if not, write to the Free Software
\r
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\r
20 A special exception to the GPL can be applied should you wish to distribute
\r
21 a combined work that includes FreeRTOS.org, without being obliged to provide
\r
22 the source code for any proprietary components. See the licensing section
\r
23 of http://www.FreeRTOS.org for full details of how and when the exception
\r
26 ***************************************************************************
\r
27 See http://www.FreeRTOS.org for documentation, latest information, license
\r
28 and contact details. Please ensure to read the configuration and relevant
\r
29 port sections of the online documentation.
\r
30 ***************************************************************************
\r
33 /* Kernel includes. */
\r
34 #include "FreeRTOS.h"
\r
38 /* Demo includes. */
\r
41 #include "eth_phy.h"
\r
46 #include "uip_arp.h"
\r
48 #define MCF_FEC_MSCR_MII_SPEED(x) (((x)&0x3F)<<0x1)
\r
49 #define MCF_FEC_RCR_MAX_FL(x) (((x)&0x7FF)<<0x10)
\r
51 /* Delay between polling the PHY to see if a link has been established. */
\r
52 #define fecLINK_DELAY ( 500 / portTICK_RATE_MS )
\r
54 /* Delay to wait for an MII access. */
\r
55 #define fecMII_DELAY ( 10 / portTICK_RATE_MS )
\r
56 #define fecMAX_POLLS ( 20 )
\r
58 /* Delay between looking for incoming packets. In ideal world this would be
\r
60 #define netifBLOCK_TIME_WAITING_FOR_INPUT fecLINK_DELAY
\r
62 /* Constants used to delay while waiting for a tx descriptor to be free. */
\r
63 #define fecMAX_TX_WAIT_ATTEMPTS 4
\r
64 #define fecTX_BUFFER_WAIT ( 10 / portTICK_RATE_MS )
\r
66 /*-----------------------------------------------------------*/
\r
68 /* The semaphore used to wake the uIP task when data arrives. */
\r
69 xSemaphoreHandle xFECSemaphore = NULL;
\r
71 /* The buffer used by the uIP stack. In this case the pointer is used to
\r
72 point to one of the Rx buffers. */
\r
73 unsigned portCHAR *uip_buf;
\r
75 /* The DMA descriptors. This is a char array to allow us to align it correctly. */
\r
76 static unsigned portCHAR xFECTxDescriptors_unaligned[ ( configNUM_FEC_TX_BUFFERS * sizeof( FECBD ) ) + 16 ];
\r
77 static unsigned portCHAR xFECRxDescriptors_unaligned[ ( configNUM_FEC_RX_BUFFERS * sizeof( FECBD ) ) + 16 ];
\r
78 static FECBD *xFECTxDescriptors;
\r
79 static FECBD *xFECRxDescriptors;
\r
81 /* The DMA buffers. These are char arrays to allow them to be alligned correctly. */
\r
82 static unsigned portCHAR ucFECRxBuffers[ ( configNUM_FEC_RX_BUFFERS * configFEC_BUFFER_SIZE ) + 16 ];
\r
83 static unsigned portBASE_TYPE uxNextRxBuffer = 0, uxNextTxBuffer = 0, uxIndexToBufferOwner = 0;
\r
85 /*-----------------------------------------------------------*/
\r
87 static void prvEnableFECInterrupts( void );
\r
89 /********************************************************************/
\r
91 * Write a value to a PHY's MII register.
\r
95 * phy_addr Address of the PHY.
\r
96 * reg_addr Address of the register in the PHY.
\r
97 * data Data to be written to the PHY register.
\r
103 * Please refer to your PHY manual for registers and their meanings.
\r
104 * mii_write() polls for the FEC's MII interrupt event and clears it.
\r
105 * If after a suitable amount of time the event isn't triggered, a
\r
106 * value of 0 is returned.
\r
108 static int fec_mii_write( int phy_addr, int reg_addr, int data )
\r
110 int timeout, iReturn;
\r
113 /* Clear the MII interrupt bit */
\r
114 MCF_FEC_EIR = MCF_FEC_EIR_MII;
\r
116 /* Mask the MII interrupt */
\r
117 eimr = MCF_FEC_EIMR;
\r
118 MCF_FEC_EIMR &= ~MCF_FEC_EIMR_MII;
\r
120 /* Write to the MII Management Frame Register to kick-off the MII write */
\r
121 MCF_FEC_MMFR = MCF_FEC_MMFR_ST_01 | MCF_FEC_MMFR_OP_WRITE | MCF_FEC_MMFR_PA(phy_addr) | MCF_FEC_MMFR_RA(reg_addr) | MCF_FEC_MMFR_TA_10 | MCF_FEC_MMFR_DATA( data );
\r
123 /* Poll for the MII interrupt (interrupt should be masked) */
\r
124 for( timeout = 0; timeout < fecMAX_POLLS; timeout++ )
\r
126 if( MCF_FEC_EIR & MCF_FEC_EIR_MII )
\r
132 vTaskDelay( fecMII_DELAY );
\r
136 if( timeout == fecMAX_POLLS )
\r
145 /* Clear the MII interrupt bit */
\r
146 MCF_FEC_EIR = MCF_FEC_EIR_MII;
\r
148 /* Restore the EIMR */
\r
149 MCF_FEC_EIMR = eimr;
\r
154 /********************************************************************/
\r
156 * Read a value from a PHY's MII register.
\r
160 * phy_addr Address of the PHY.
\r
161 * reg_addr Address of the register in the PHY.
\r
162 * data Pointer to storage for the Data to be read
\r
163 * from the PHY register (passed by reference)
\r
169 * Please refer to your PHY manual for registers and their meanings.
\r
170 * mii_read() polls for the FEC's MII interrupt event and clears it.
\r
171 * If after a suitable amount of time the event isn't triggered, a
\r
172 * value of 0 is returned.
\r
174 static int fec_mii_read( int phy_addr, int reg_addr, unsigned portSHORT* data )
\r
176 int timeout, iReturn;
\r
179 /* Clear the MII interrupt bit */
\r
180 MCF_FEC_EIR = MCF_FEC_EIR_MII;
\r
182 /* Mask the MII interrupt */
\r
183 eimr = MCF_FEC_EIMR;
\r
184 MCF_FEC_EIMR &= ~MCF_FEC_EIMR_MII;
\r
186 /* Write to the MII Management Frame Register to kick-off the MII read */
\r
187 MCF_FEC_MMFR = MCF_FEC_MMFR_ST_01 | MCF_FEC_MMFR_OP_READ | MCF_FEC_MMFR_PA(phy_addr) | MCF_FEC_MMFR_RA(reg_addr) | MCF_FEC_MMFR_TA_10;
\r
189 /* Poll for the MII interrupt (interrupt should be masked) */
\r
190 for( timeout = 0; timeout < fecMAX_POLLS; timeout++ )
\r
192 if (MCF_FEC_EIR & MCF_FEC_EIR_MII)
\r
198 vTaskDelay( fecMII_DELAY );
\r
202 if( timeout == fecMAX_POLLS )
\r
208 *data = (uint16)(MCF_FEC_MMFR & 0x0000FFFF);
\r
212 /* Clear the MII interrupt bit */
\r
213 MCF_FEC_EIR = MCF_FEC_EIR_MII;
\r
215 /* Restore the EIMR */
\r
216 MCF_FEC_EIMR = eimr;
\r
222 /********************************************************************/
\r
224 * Generate the hash table settings for the given address
\r
227 * addr 48-bit (6 byte) Address to generate the hash for
\r
230 * The 6 most significant bits of the 32-bit CRC result
\r
232 static unsigned portCHAR fec_hash_address( const unsigned portCHAR* addr )
\r
234 unsigned portLONG crc;
\r
235 unsigned portCHAR byte;
\r
244 if((byte & 0x01)^(crc & 0x01))
\r
247 crc = crc ^ 0xEDB88320;
\r
258 return (unsigned portCHAR)(crc >> 26);
\r
261 /********************************************************************/
\r
263 * Set the Physical (Hardware) Address and the Individual Address
\r
264 * Hash in the selected FEC
\r
268 * pa Physical (Hardware) Address for the selected FEC
\r
270 static void fec_set_address( const unsigned portCHAR *pa )
\r
272 unsigned portCHAR crc;
\r
275 * Set the Physical Address
\r
277 /* Set the source address for the controller */
\r
278 MCF_FEC_PALR = ( pa[ 0 ] << 24 ) | ( pa[ 1 ] << 16 ) | ( pa[ 2 ] << 8 ) | ( pa[ 3 ] << 0 );
\r
279 MCF_FEC_PAUR = ( pa[ 4 ] << 24 ) | ( pa[ 5 ] << 16 );
\r
282 * Calculate and set the hash for given Physical Address
\r
283 * in the Individual Address Hash registers
\r
285 crc = fec_hash_address( pa );
\r
288 MCF_FEC_IAUR |= (unsigned portLONG)(1 << (crc - 32));
\r
292 MCF_FEC_IALR |= (unsigned portLONG)(1 << crc);
\r
295 /*-----------------------------------------------------------*/
\r
297 static void prvInitialiseFECBuffers( void )
\r
299 unsigned portBASE_TYPE ux;
\r
300 unsigned portCHAR *pcBufPointer;
\r
302 pcBufPointer = &( xFECTxDescriptors_unaligned[ 0 ] );
\r
303 while( ( ( unsigned portLONG ) pcBufPointer & 0x0fUL ) != 0 )
\r
308 xFECTxDescriptors = ( FECBD * ) pcBufPointer;
\r
310 pcBufPointer = &( xFECRxDescriptors_unaligned[ 0 ] );
\r
311 while( ( ( unsigned portLONG ) pcBufPointer & 0x0fUL ) != 0 )
\r
316 xFECRxDescriptors = ( FECBD * ) pcBufPointer;
\r
319 /* Setup the buffers and descriptors. The data member does not point
\r
320 anywhere yet as there is not yet anything to send and a zero copy policy
\r
322 for( ux = 0; ux < configNUM_FEC_TX_BUFFERS; ux++ )
\r
324 xFECTxDescriptors[ ux ].status = TX_BD_TC;
\r
325 xFECTxDescriptors[ ux ].data = NULL;
\r
326 xFECTxDescriptors[ ux ].length = 0;
\r
329 pcBufPointer = &( ucFECRxBuffers[ 0 ] );
\r
330 while( ( ( unsigned portLONG ) pcBufPointer & 0x0fUL ) != 0 )
\r
335 for( ux = 0; ux < configNUM_FEC_RX_BUFFERS; ux++ )
\r
337 xFECRxDescriptors[ ux ].status = RX_BD_E;
\r
338 xFECRxDescriptors[ ux ].length = configFEC_BUFFER_SIZE;
\r
339 xFECRxDescriptors[ ux ].data = pcBufPointer;
\r
340 pcBufPointer += configFEC_BUFFER_SIZE;
\r
343 /* Set the wrap bit in the last descriptors to form a ring. */
\r
344 xFECTxDescriptors[ configNUM_FEC_TX_BUFFERS - 1 ].status |= TX_BD_W;
\r
345 xFECRxDescriptors[ configNUM_FEC_RX_BUFFERS - 1 ].status |= RX_BD_W;
\r
347 uxNextRxBuffer = 0;
\r
348 uxNextTxBuffer = 0;
\r
350 /*-----------------------------------------------------------*/
\r
352 void vInitFEC( void )
\r
354 unsigned portSHORT usData;
\r
355 struct uip_eth_addr xAddr;
\r
356 const unsigned portCHAR ucMACAddress[6] =
\r
358 configMAC_0, configMAC_1,configMAC_2, configMAC_3, configMAC_4, configMAC_5
\r
361 /* Create the semaphore used by the ISR to wake the uIP task. */
\r
362 vSemaphoreCreateBinary( xFECSemaphore );
\r
364 prvInitialiseFECBuffers();
\r
366 for( usData = 0; usData < 6; usData++ )
\r
368 xAddr.addr[ usData ] = ucMACAddress[ usData ];
\r
370 uip_setethaddr( xAddr );
\r
372 /* Set the Reset bit and clear the Enable bit */
\r
373 MCF_FEC_ECR = MCF_FEC_ECR_RESET;
\r
375 /* Wait at least 8 clock cycles */
\r
376 for( usData = 0; usData < 10; usData++ )
\r
381 /* Set MII speed to 2.5MHz. */
\r
382 MCF_FEC_MSCR = MCF_FEC_MSCR_MII_SPEED( ( ( ( configCPU_CLOCK_HZ / 1000000 ) / 5 ) + 1 ) );
\r
384 /* Initialize PLDPAR to enable Ethernet LEDs. */
\r
385 MCF_GPIO_PLDPAR = MCF_GPIO_PLDPAR_ACTLED_ACTLED | MCF_GPIO_PLDPAR_LINKLED_LINKLED | MCF_GPIO_PLDPAR_SPDLED_SPDLED
\r
386 | MCF_GPIO_PLDPAR_DUPLED_DUPLED | MCF_GPIO_PLDPAR_COLLED_COLLED | MCF_GPIO_PLDPAR_RXLED_RXLED
\r
387 | MCF_GPIO_PLDPAR_TXLED_TXLED;
\r
389 /* Initialize Port TA to enable Axcel control. */
\r
390 MCF_GPIO_PTAPAR = 0x00;
\r
391 MCF_GPIO_DDRTA = 0x0F;
\r
392 MCF_GPIO_PORTTA = 0x04;
\r
394 /* Set phy address to zero. */
\r
395 MCF_EPHY_EPHYCTL1 = MCF_EPHY_EPHYCTL1_PHYADD( 0 );
\r
397 /* Enable EPHY module with PHY clocks disabled. Do not turn on PHY clocks
\r
398 until both FEC and EPHY are completely setup (see Below). */
\r
399 MCF_EPHY_EPHYCTL0 = (uint8)(MCF_EPHY_EPHYCTL0_DIS100 | MCF_EPHY_EPHYCTL0_DIS10);
\r
401 /* Enable auto_neg at start-up */
\r
402 MCF_EPHY_EPHYCTL0 = (uint8)(MCF_EPHY_EPHYCTL0 & (MCF_EPHY_EPHYCTL0_ANDIS));
\r
404 /* Enable EPHY module. */
\r
405 MCF_EPHY_EPHYCTL0 = (uint8)(MCF_EPHY_EPHYCTL0_EPHYEN | MCF_EPHY_EPHYCTL0);
\r
407 /* Let PHY PLLs be determined by PHY. */
\r
408 MCF_EPHY_EPHYCTL0 = (uint8)(MCF_EPHY_EPHYCTL0 & ~(MCF_EPHY_EPHYCTL0_DIS100 | MCF_EPHY_EPHYCTL0_DIS10));
\r
411 vTaskDelay( fecLINK_DELAY );
\r
413 /* Can we talk to the PHY? */
\r
416 vTaskDelay( fecLINK_DELAY );
\r
418 fec_mii_read( configPHY_ADDRESS, PHY_PHYIDR1, &usData );
\r
420 } while( usData == 0xffff );
\r
424 /* Start auto negotiate. */
\r
425 fec_mii_write( configPHY_ADDRESS, PHY_BMCR, ( PHY_BMCR_AN_RESTART | PHY_BMCR_AN_ENABLE ) );
\r
427 /* Wait for auto negotiate to complete. */
\r
430 vTaskDelay( fecLINK_DELAY );
\r
431 fec_mii_read( configPHY_ADDRESS, PHY_BMSR, &usData );
\r
433 } while( !( usData & PHY_BMSR_AN_COMPLETE ) );
\r
435 } while( 0 ); //while( !( usData & PHY_BMSR_LINK ) );
\r
437 /* When we get here we have a link - find out what has been negotiated. */
\r
438 fec_mii_read( configPHY_ADDRESS, PHY_ANLPAR, &usData );
\r
440 if( ( usData & PHY_ANLPAR_100BTX_FDX ) || ( usData & PHY_ANLPAR_100BTX ) )
\r
442 /* Speed is 100. */
\r
449 if( ( usData & PHY_ANLPAR_100BTX_FDX ) || ( usData & PHY_ANLPAR_10BTX_FDX ) )
\r
451 MCF_FEC_RCR &= (unsigned portLONG)~MCF_FEC_RCR_DRT;
\r
452 MCF_FEC_TCR |= MCF_FEC_TCR_FDEN;
\r
456 MCF_FEC_RCR |= MCF_FEC_RCR_DRT;
\r
457 MCF_FEC_TCR &= (unsigned portLONG)~MCF_FEC_TCR_FDEN;
\r
460 /* Clear the Individual and Group Address Hash registers */
\r
466 /* Set the Physical Address for the selected FEC */
\r
467 fec_set_address( ucMACAddress );
\r
469 /* Set Rx Buffer Size */
\r
470 MCF_FEC_EMRBR = (unsigned portSHORT)configFEC_BUFFER_SIZE;
\r
472 /* Point to the start of the circular Rx buffer descriptor queue */
\r
473 MCF_FEC_ERDSR = ( volatile unsigned portLONG ) &( xFECRxDescriptors[ 0 ] );
\r
475 /* Point to the start of the circular Tx buffer descriptor queue */
\r
476 MCF_FEC_ETSDR = ( volatile unsigned portLONG ) &( xFECTxDescriptors[ 0 ] );
\r
478 /* Mask all FEC interrupts */
\r
479 MCF_FEC_EIMR = ( unsigned portLONG ) -1;
\r
481 /* Clear all FEC interrupt events */
\r
482 MCF_FEC_EIR = ( unsigned portLONG ) -1;
\r
484 /* Initialize the Receive Control Register */
\r
485 MCF_FEC_RCR = MCF_FEC_RCR_MAX_FL(ETH_MAX_FRM) | MCF_FEC_RCR_FCE;
\r
487 MCF_FEC_RCR |= MCF_FEC_RCR_MII_MODE;
\r
489 #if( configUSE_PROMISCUOUS_MODE == 1 )
\r
491 MCF_FEC_RCR |= MCF_FEC_RCR_PROM;
\r
495 prvEnableFECInterrupts();
\r
497 MCF_FEC_ECR = MCF_FEC_ECR_ETHER_EN;
\r
498 MCF_FEC_RDAR = MCF_FEC_RDAR_R_DES_ACTIVE;
\r
500 /*-----------------------------------------------------------*/
\r
502 static void prvEnableFECInterrupts( void )
\r
504 const unsigned portBASE_TYPE uxFirstFECVector = 23, uxLastFECVector = 35;
\r
505 unsigned portBASE_TYPE ux;
\r
507 #if configFEC_INTERRUPT_PRIORITY > configMAX_SYSCALL_INTERRUPT_PRIORITY
\r
508 #error configFEC_INTERRUPT_PRIORITY must be less than or equal to configMAX_SYSCALL_INTERRUPT_PRIORITY
\r
511 for( ux = uxFirstFECVector; ux <= uxLastFECVector; ux++ )
\r
513 MCF_INTC0_ICR( ux ) = MCF_INTC_ICR_IL( configFEC_INTERRUPT_PRIORITY );
\r
516 /* Enable the FEC interrupts in the mask register */
\r
517 MCF_INTC0_IMRH &= ~( MCF_INTC_IMRH_INT_MASK33 | MCF_INTC_IMRH_INT_MASK34 | MCF_INTC_IMRH_INT_MASK35 );
\r
518 MCF_INTC0_IMRL &= ~( MCF_INTC_IMRL_INT_MASK25 | MCF_INTC_IMRL_INT_MASK26 | MCF_INTC_IMRL_INT_MASK27
\r
519 | MCF_INTC_IMRL_INT_MASK28 | MCF_INTC_IMRL_INT_MASK29 | MCF_INTC_IMRL_INT_MASK30
\r
520 | MCF_INTC_IMRL_INT_MASK31 | MCF_INTC_IMRL_MASKALL );
\r
522 /* Clear any pending FEC interrupt events */
\r
523 MCF_FEC_EIR = MCF_FEC_EIR_CLEAR_ALL;
\r
525 /* Unmask all FEC interrupts */
\r
526 MCF_FEC_EIMR = MCF_FEC_EIMR_UNMASK_ALL;
\r
528 /*-----------------------------------------------------------*/
\r
530 unsigned short usGetFECRxData( void )
\r
532 unsigned portSHORT usLen;
\r
534 /* Obtain the size of the packet and put it into the "len" variable. */
\r
535 usLen = xFECRxDescriptors[ uxNextRxBuffer ].length;
\r
537 if( ( usLen != 0 ) && ( ( xFECRxDescriptors[ uxNextRxBuffer ].status & RX_BD_E ) == 0 ) )
\r
539 uip_buf = xFECRxDescriptors[ uxNextRxBuffer ].data;
\r
548 /*-----------------------------------------------------------*/
\r
550 void vDiscardRxData( void )
\r
552 /* Free the descriptor as the buffer it points to is no longer in use. */
\r
553 xFECRxDescriptors[ uxNextRxBuffer ].status |= RX_BD_E;
\r
554 MCF_FEC_RDAR = MCF_FEC_RDAR_R_DES_ACTIVE;
\r
556 if( uxNextRxBuffer >= configNUM_FEC_RX_BUFFERS )
\r
558 uxNextRxBuffer = 0;
\r
561 /*-----------------------------------------------------------*/
\r
563 void vSendBufferToFEC( void )
\r
567 /* Get a DMA buffer into which we can write the data to send. */
\r
568 for( l = 0; l < fecMAX_TX_WAIT_ATTEMPTS; l++ )
\r
570 if( xFECTxDescriptors[ uxNextTxBuffer ].status & TX_BD_R )
\r
572 /* Wait for the buffer to become available. */
\r
573 vTaskDelay( fecTX_BUFFER_WAIT );
\r
577 /* Setup the buffer descriptor for transmission. The data being
\r
578 sent is actually stored in one of the Rx descripter buffers,
\r
579 pointed to by uip_buf. */
\r
580 xFECTxDescriptors[ uxNextTxBuffer ].length = uip_len;
\r
581 xFECTxDescriptors[ uxNextTxBuffer ].status |= (TX_BD_R | TX_BD_L);
\r
582 xFECTxDescriptors[ uxNextTxBuffer ].data = uip_buf;
\r
584 /* Continue the Tx DMA (in case it was waiting for a new TxBD) */
\r
585 MCF_FEC_TDAR = MCF_FEC_TDAR_X_DES_ACTIVE;
\r
587 /* Remember which Rx descriptor owns the buffer we are sending. */
\r
588 uxIndexToBufferOwner = uxNextRxBuffer;
\r
591 if( uxNextTxBuffer >= configNUM_FEC_TX_BUFFERS )
\r
593 uxNextTxBuffer = 0;
\r
596 /* We have finished with this Rx descriptor now. */
\r
598 if( uxNextRxBuffer >= configNUM_FEC_RX_BUFFERS )
\r
600 uxNextRxBuffer = 0;
\r
607 /*-----------------------------------------------------------*/
\r
609 void vFEC_ISR( void )
\r
611 unsigned portLONG ulEvent;
\r
612 portBASE_TYPE xHighPriorityTaskWoken = pdFALSE;
\r
614 ulEvent = MCF_FEC_EIR & MCF_FEC_EIMR;
\r
615 MCF_FEC_EIR = ulEvent;
\r
617 if( ( ulEvent & MCF_FEC_EIR_RXB ) || ( ulEvent & MCF_FEC_EIR_RXF ) )
\r
619 /* A packet has been received. Wake the handler task. */
\r
620 xSemaphoreGiveFromISR( xFECSemaphore, &xHighPriorityTaskWoken );
\r
623 if( ulEvent & ( MCF_FEC_EIR_UN | MCF_FEC_EIR_RL | MCF_FEC_EIR_LC | MCF_FEC_EIR_EBERR | MCF_FEC_EIR_BABT | MCF_FEC_EIR_BABR | MCF_FEC_EIR_HBERR ) )
\r
625 /* Sledge hammer error handling. */
\r
626 prvInitialiseFECBuffers();
\r
627 MCF_FEC_RDAR = MCF_FEC_RDAR_R_DES_ACTIVE;
\r
630 if( ( ulEvent & MCF_FEC_EIR_TXF ) || ( ulEvent & MCF_FEC_EIR_TXB ) )
\r
632 /* The buffer being sent is pointed to by an Rx descriptor, now the
\r
633 buffer has been sent we can mark the Rx descriptor as free again. */
\r
634 xFECRxDescriptors[ uxIndexToBufferOwner ].status |= RX_BD_E;
\r
635 MCF_FEC_RDAR = MCF_FEC_RDAR_R_DES_ACTIVE;
\r
638 portEND_SWITCHING_ISR( xHighPriorityTaskWoken );
\r
640 /*-----------------------------------------------------------*/
\r
642 void __attribute__ ((interrupt)) __cs3_isr_interrupt_88( void ) { vFEC_ISR(); }
\r
643 void __attribute__ ((interrupt)) __cs3_isr_interrupt_89( void ) { vFEC_ISR(); }
\r
644 void __attribute__ ((interrupt)) __cs3_isr_interrupt_90( void ) { vFEC_ISR(); }
\r
645 void __attribute__ ((interrupt)) __cs3_isr_interrupt_91( void ) { vFEC_ISR(); }
\r
646 void __attribute__ ((interrupt)) __cs3_isr_interrupt_92( void ) { vFEC_ISR(); }
\r
647 void __attribute__ ((interrupt)) __cs3_isr_interrupt_93( void ) { vFEC_ISR(); }
\r
648 void __attribute__ ((interrupt)) __cs3_isr_interrupt_94( void ) { vFEC_ISR(); }
\r
649 void __attribute__ ((interrupt)) __cs3_isr_interrupt_95( void ) { vFEC_ISR(); }
\r
650 void __attribute__ ((interrupt)) __cs3_isr_interrupt_96( void ) { vFEC_ISR(); }
\r
651 void __attribute__ ((interrupt)) __cs3_isr_interrupt_97( void ) { vFEC_ISR(); }
\r
652 void __attribute__ ((interrupt)) __cs3_isr_interrupt_98( void ) { vFEC_ISR(); }
\r
653 void __attribute__ ((interrupt)) __cs3_isr_interrupt_99( void ) { vFEC_ISR(); }
\r
654 void __attribute__ ((interrupt)) __cs3_isr_interrupt_100( void ) { vFEC_ISR(); }
\r