]> git.sur5r.net Git - freertos/blob - Demo/lwIP_MCF5235_GCC/lwip/contrib/port/FreeRTOS/MCF5235/netif/nbuf.c
Add PIC24, dsPIC and Coldfire files.
[freertos] / Demo / lwIP_MCF5235_GCC / lwip / contrib / port / FreeRTOS / MCF5235 / netif / nbuf.c
1 /*
2  * Network buffer code based on the MCF523x examples from Freescale.
3  *
4  * File: $Id: nbuf.c,v 1.2 2006/08/31 22:28:21 wolti Exp $
5  */
6
7 /* ------------------------ Platform includes ----------------------------- */
8 #include "mcf5xxx.h"
9 #include "mcf523x.h"
10
11 #include "nbuf.h"
12
13 /* ------------------------ Static variables ------------------------------ */
14
15 /* Buffer descriptor indexes */
16 static uint8    tx_bd_idx;
17 static uint8    rx_bd_idx;
18
19 /* Buffer Descriptors -- must be aligned on a 4-byte boundary but a
20  * 16-byte boundary is recommended. */
21 static nbuf_t   tx_nbuf[sizeof( nbuf_t ) * NUM_TXBDS] ATTR_FECMEM;
22 static nbuf_t   rx_nbuf[sizeof( nbuf_t ) * NUM_RXBDS] ATTR_FECMEM;
23
24 /* Data Buffers -- must be aligned on a 16-byte boundary. */
25 static uint8    tx_buf[TX_BUFFER_SIZE * NUM_TXBDS] ATTR_FECMEM;
26 static uint8    rx_buf[RX_BUFFER_SIZE * NUM_RXBDS] ATTR_FECMEM;
27
28 /* ------------------------ Start implementation -------------------------- */
29 void
30 nbuf_init(  )
31 {
32
33     uint8           i;
34
35     /* Initialize receive descriptor ring */
36     for( i = 0; i < NUM_RXBDS; i++ )
37     {
38         rx_nbuf[i].status = RX_BD_E;
39         rx_nbuf[i].length = 0;
40         rx_nbuf[i].data = &rx_buf[i * RX_BUFFER_SIZE];
41     }
42
43     /* Set the Wrap bit on the last one in the ring */
44     rx_nbuf[NUM_RXBDS - 1].status |= RX_BD_W;
45
46     /* Initialize transmit descriptor ring */
47     for( i = 0; i < NUM_TXBDS; i++ )
48     {
49         tx_nbuf[i].status = TX_BD_L | TX_BD_TC;
50         tx_nbuf[i].length = 0;
51         tx_nbuf[i].data = &tx_buf[i * TX_BUFFER_SIZE];
52     }
53
54     /* Set the Wrap bit on the last one in the ring */
55     tx_nbuf[NUM_TXBDS - 1].status |= TX_BD_W;
56
57     /* Initialize the buffer descriptor indexes */
58     tx_bd_idx = rx_bd_idx = 0;
59
60     return;
61 }
62
63
64 /********************************************************************/
65 uint32
66 nbuf_get_start( uint8 direction )
67 {
68     /*
69      * Return the address of the first buffer descriptor in the ring.
70      * This routine is needed by the FEC of the MPC860T , MCF5282, and MCF523x
71      * in order to write the Rx/Tx descriptor ring start registers
72      */
73     switch ( direction )
74     {
75     case NBUF_RX:
76         return ( uint32 ) rx_nbuf;
77     case NBUF_TX:
78     default:
79         return ( uint32 ) tx_nbuf;
80     }
81 }
82
83
84 /********************************************************************/
85 nbuf_t         *
86 nbuf_rx_allocate(  )
87 {
88     /* This routine alters shared data. Disable interrupts! */
89     int             old_ipl = asm_set_ipl( 6 );
90
91     /* Return a pointer to the next empty Rx Buffer Descriptor */
92     int             i = rx_bd_idx;
93
94
95     /* Check to see if the ring of BDs is full */
96     if( rx_nbuf[i].status & RX_BD_INUSE )
97         return NULL;
98
99     /* Mark the buffer as in use */
100     rx_nbuf[i].status |= RX_BD_INUSE;
101
102     /* increment the circular index */
103     rx_bd_idx = ( uint8 ) ( ( rx_bd_idx + 1 ) % NUM_RXBDS );
104
105     /* Restore previous IPL */
106     asm_set_ipl( old_ipl );
107
108     return &rx_nbuf[i];
109 }
110
111
112 /********************************************************************/
113 nbuf_t         *
114 nbuf_tx_allocate(  )
115 {
116     /* This routine alters shared data. Disable interrupts! */
117     int             old_ipl = asm_set_ipl( 6 );
118
119     /* Return a pointer to the next empty Tx Buffer Descriptor */
120     int             i = tx_bd_idx;
121
122     /* Check to see if ring of BDs is full */
123     if( ( tx_nbuf[i].status & TX_BD_INUSE ) || ( tx_nbuf[i].status & TX_BD_R ) )
124         return NULL;
125
126     /* Mark the buffer as Ready (in use) */
127     /* FEC must set R bit in transmit routine */
128     tx_nbuf[i].status |= TX_BD_INUSE;
129
130     /* increment the circular index */
131     tx_bd_idx = ( uint8 ) ( ( tx_bd_idx + 1 ) % NUM_TXBDS );
132
133     /* Restore previous IPL */
134     asm_set_ipl( old_ipl );
135
136     return &tx_nbuf[i];
137 }
138
139
140 /********************************************************************/
141 void
142 nbuf_rx_release( nbuf_t * pNbuf )
143 {
144     /* This routine alters shared data. Disable interrupts! */
145     int             old_ipl = asm_set_ipl( 6 );
146
147     /* Mark the buffer as empty and not in use */
148     pNbuf->status |= RX_BD_E;
149     pNbuf->status &= ~RX_BD_INUSE;
150
151     /* Restore previous IPL */
152     asm_set_ipl( old_ipl );
153 }
154
155 /********************************************************************/
156 void
157 nbuf_tx_release( nbuf_t * pNbuf )
158 {
159     /* This routine alters shared data. Disable interrupts! */
160     int             old_ipl = asm_set_ipl( 6 );
161
162     /* Mark the buffer as not in use */
163     pNbuf->status &= ~TX_BD_INUSE;
164
165     /* Restore previous IPL */
166     asm_set_ipl( old_ipl );
167 }
168
169 /********************************************************************/
170 int
171 nbuf_rx_next_ready(  )
172 {
173     /****************************************************************
174  This function checks the EMPTY bit of the next Rx buffer to be
175  allocated. If the EMPTY bit is cleared, then the next buffer in
176  the ring has been filled by the FEC and has not already been
177  allocated and passed up the stack. In this case, the next buffer
178  in the ring is ready to be allocated. Otherwise, the  buffer is
179  either empty or not empty but still in use by a higher level
180  protocol. The FEC receive routine uses this function to determine
181  if multiple buffers where filled by the FEC during a single
182  interrupt event.
183  ****************************************************************/
184
185     return ( !( rx_nbuf[rx_bd_idx].status & RX_BD_E ) );
186 }