3 //==========================================================================
4 //####ECOSGPLCOPYRIGHTBEGIN####
5 // -------------------------------------------
6 // This file is part of eCos, the Embedded Configurable Operating System.
7 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
9 // eCos is free software; you can redistribute it and/or modify it under
10 // the terms of the GNU General Public License as published by the Free
11 // Software Foundation; either version 2 or (at your option) any later version.
13 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
14 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 // You should have received a copy of the GNU General Public License along
19 // with eCos; if not, write to the Free Software Foundation, Inc.,
20 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
22 // As a special exception, if other files instantiate templates or use macros
23 // or inline functions from this file, or you compile this file and link it
24 // with other works to produce a work based on this file, this file does not
25 // by itself cause the resulting work to be covered by the GNU General Public
26 // License. However the source code for this file must still be made available
27 // in accordance with section (3) of the GNU General Public License.
29 // This exception does not invalidate any other reasons why a work based on
30 // this file might be covered by the GNU General Public License.
32 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
33 // at http://sources.redhat.com/ecos/ecos-license/
34 // -------------------------------------------
35 //####ECOSGPLCOPYRIGHTEND####
36 //==========================================================================
40 * Purpose: Definitions for Network Buffer Allocation.
42 * Notes: These routines implement a static buffer scheme.
43 * The buffer descriptors are as specified by the
44 * MPC860T/MCF5272 FEC.
50 #include <cyg/hal/drv_api.h>
51 #include <pkgconf/net_mcf5272_eth_drivers.h>
52 #include <cyg/hal/hal_intr.h>
53 #include <cyg/infra/cyg_type.h>
54 #include <cyg/infra/cyg_ass.h>
55 #include <cyg/io/eth/eth_drv.h>
59 /********************************************************************/
62 typedef unsigned char uint8; /* 8 bits */
63 typedef unsigned short int uint16; /* 16 bits */
64 typedef unsigned long int uint32; /* 32 bits */
66 typedef signed char int8; /* 8 bits */
67 typedef signed short int int16; /* 16 bits */
68 typedef signed long int int32; /* 32 bits */
75 * Buffer sizes in bytes -- The following values were chosen based
76 * on TFTP maximum packet sizes. These sizes may need to be
77 * increased to implement other protocols.
79 #define RX_BUFFER_SIZE (576) /* must be divisible by 16 */
80 /* #define TX_BUFFER_SIZE 576 */
83 /* The this label is not defined, we define it and default it to 256. */
84 #ifndef CYGPKG_NET_MCF5272_ETH_DRIVERS_RX_NUM_BDS
85 #define CYGPKG_NET_MCF5272_ETH_DRIVERS_RX_NUM_BDS 256
88 /* The this label is not defined, we define it and default it to 256. */
89 #ifndef CYGPKG_NET_MCF5272_ETH_DRIVERS_TX_NUM_BDS
90 #define CYGPKG_NET_MCF5272_ETH_DRIVERS_TX_NUM_BDS 256
94 /* Number of Receive and Transmit Buffers and Buffer Descriptors */
95 #define NUM_RXBDS (CYGPKG_NET_MCF5272_ETH_DRIVERS_RX_NUM_BDS)
96 #define NUM_TXBDS (CYGPKG_NET_MCF5272_ETH_DRIVERS_TX_NUM_BDS)
101 * Buffer Descriptor Format -- must be aligned on 4-byte boundary
102 * but a 16-byte boundary is recommended. However, we cannot pack
103 * them on 16-byte boundaries as this will add 8-bytes of padding
104 * between structures and the FEC of the MPC860T/MCF5272 will choke.
108 uint16 status; /* control and status */
109 uint16 length; /* transfer length */
110 uint8 *data; /* buffer address */
111 } __attribute__ ((packed, aligned))NBUF;
114 /* Defines the tx key type. */
115 typedef enum tx_key_type_t
117 TX_KEY_ECOS, /* eCos key */
118 TX_KEY_USER /* user key */
121 typedef struct tx_keys_t
123 unsigned long tx_key; /* The transmit key that eCos gives us. */
124 uint_t tx_buf_index; /* Index to the TxNBUF where the last Buffer Descriptor of the frame. */
125 int num_dbufs; /* The number transmit buffer allocated for the frame. */
126 uint_t start_index; /* Index of the bd */
128 tx_key_type_t key_type; /* The type of the key. */
132 typedef struct buf_info_t
135 /* Buffer descriptor indexes */
140 /* Queue for the transmit keys */
142 #define TX_KEY_QUEUE_SIZE (NUM_TXBDS+1)
143 tx_keys_t tx_keys_queue[TX_KEY_QUEUE_SIZE];
145 /* Rear and front pointer for the keys queue. */
150 /* Number transmit descriptor buffers busy. */
152 volatile int num_busy_bd;
154 /* The maximum number of buffer decriptor used. */
156 volatile int max_num_busy_bd;
158 /* Buffer Descriptors */
159 NBUF ntxbuf[NUM_TXBDS+2];
160 NBUF nrxbuf[NUM_RXBDS+2];
166 //TXB TxBuffer[NUM_TXBDS];
167 u8_t RxBuffer[(NUM_RXBDS+2)*RX_BUFFER_SIZE];
173 /********************************************************************/
176 * Bit level Buffer Descriptor definitions
179 #define TX_BD_R 0x8000
180 #define TX_BD_TO1 0x4000
181 #define TX_BD_INUSE TX_BD_TO1
182 #define TX_BD_W 0x2000
183 #define TX_BD_TO2 0x1000
184 #define TX_BD_L 0x0800
185 #define TX_BD_TC 0x0400
186 #define TX_BD_DEF 0x0200
187 #define TX_BD_HB 0x0100
188 #define TX_BD_LC 0x0080
189 #define TX_BD_RL 0x0040
190 #define TX_BD_UN 0x0002
191 #define TX_BD_CSL 0x0001
193 #define RX_BD_E 0x8000
194 #define RX_BD_R01 0x4000
195 #define RX_BD_W 0x2000
196 #define RX_BD_R02 0x1000
197 #define RX_BD_L 0x0800
198 #define RX_BD_M 0x0100
199 #define RX_BD_BC 0x0080
200 #define RX_BD_MC 0x0040
201 #define RX_BD_LG 0x0020
202 #define RX_BD_NO 0x0010
203 #define RX_BD_SH 0x0008
204 #define RX_BD_CR 0x0004
205 #define RX_BD_OV 0x0002
206 #define RX_BD_TR 0x0001
208 /*******************************************************************/
211 * Functions to manipulate the network buffers.
214 void nbuf_init (buf_info_t* pBuf);
217 /********************************************************************/
220 nbuf_get_start(buf_info_t* pBuf, uint8 direction)
223 * Return the address of the first buffer descriptor in the ring.
224 * This routine is needed by the FEC of the MPC860T and MCF5272
225 * in order to write the Rx/Tx descriptor ring start registers
229 return (uint32)pBuf->RxNBUF;
232 return (uint32)pBuf->TxNBUF;
241 /******************************************************************************
242 nbuf_rx_get_next() - Retrieve the next receive buffer descriptor.
245 pBuf - Pointer to the buffer info.
248 Returns the pointer to the next receive buffer descriptor.
253 nbuf_rx_get_next(buf_info_t* pBuf)
255 NBUF* pBd = &pBuf->RxNBUF[pBuf->iRxbd];
257 /* Check to see if the ring of BDs is full */
258 if (pBd->status & RX_BD_E)
263 /* increment the circular index */
264 pBuf->iRxbd = (pBuf->iRxbd + 1) % NUM_RXBDS;
270 /* Return the pointer to the buffer descriptor based on the index */
273 nbuf_rx_get(buf_info_t* pBuf, uint_t index)
275 return(&pBuf->RxNBUF[index]);
278 /********************************************************************
279 Release the buffer descrip so that it can be use
280 to receive the enxt packet.
283 pNbuf - pointer to the buffer descriptor.
288 nbuf_rx_release (NBUF* pNbuf)
291 /* Mark the buffer as empty and not in use */
292 pNbuf->status |= RX_BD_E;
297 /* Return the current rx buffer descriptor index */
299 nbuf_rx_get_index(buf_info_t* pBuf)
304 /****************************************************************
305 This function checks the EMPTY bit of the next Rx buffer to be
306 allocated. If the EMPTY bit is cleared, then the next buffer in
307 the ring has been filled by the FEC and has not already been
308 allocated and passed up the stack. In this case, the next buffer
309 in the ring is ready to be allocated. Otherwise, the buffer is
310 either empty or not empty but still in use by a higher level
311 protocol. The FEC receive routine uses this function to determine
312 if multiple buffers where filled by the FEC during a single
314 ****************************************************************/
317 nbuf_rx_next_ready(buf_info_t* pBuf)
320 return ( !(pBuf->RxNBUF[pBuf->iRxbd].status & RX_BD_E));
326 /******************************************************************************
327 nbuf_rx_release_pkt() - Release the buffer descriptors of the next packet.
330 pointer to the buffer info.
333 void nbuf_rx_release_pkt(buf_info_t* pBuf)
338 /* Indicates whether the last buffer descriptor is encountered. */
339 cyg_bool_t last = false;
343 /* Get the buffer descriptor. */
344 pNbuf = nbuf_rx_get_next(pBuf);
346 /* Stop when there is a packet truncated bit is set or it is the */
347 /* last buffer descriptor of the packet. */
349 if ((!(pNbuf->status & RX_BD_E) && pNbuf->status & RX_BD_TR) ||
350 pNbuf->status & RX_BD_L)
355 /* Release the buffer descriptor. */
356 nbuf_rx_release(pNbuf);
358 }while(last == false);
364 /******************************************************************************
365 nbuf_rx_release_good_pkt() - Release the buffer descriptors for
366 good received packets.
367 Note call this function
368 only when there is valid received
372 pBuf - pointer to the buffer info.
375 void nbuf_rx_release_good_pkt(buf_info_t* pBuf)
383 /* Read the status bits. If the RX_BD_L is set we terminate the */
386 status = pBuf->RxNBUF[pBuf->iRxbd].status;
388 /* Release the buffer descriptor so that it could reused. */
390 nbuf_rx_release(&pBuf->RxNBUF[pBuf->iRxbd]);
392 /* Advance the index to the next buffer descriptor. */
394 pBuf->iRxbd = (pBuf->iRxbd + 1) % NUM_RXBDS;
397 }while(!(status & RX_BD_L));
402 /******************************************************************************
403 nbuf_tx_release() - Set the buffer descriptor ready for use to transmit
407 pNbuf - Pointer to the transmit buffer descriptor.
411 nbuf_tx_release (NBUF* pNbuf)
414 /* Clear the TX_BD_INUSE to indicate that we have read the */
415 /* transmitted buffer. */
417 pNbuf->status &= ~(TX_BD_INUSE | TX_BD_R | TX_BD_L | TX_BD_TC);
421 /* Return a nozero value if the buffer is full. Otherwise, it returns a
425 int_t nbuf_tx_full(buf_info_t* pBuf)
427 return (pBuf->TxNBUF[pBuf->iTxbd].status & TX_BD_R);
431 /* Return the pointer to the transmit buffer descriptor. */
434 nbuf_tx_get(buf_info_t* pBuf, int_t index)
436 return(&pBuf->TxNBUF[index]);
439 /******************************************************************************
440 nbuf_peek_tx_key() - Peek whether there is any
441 pending packets that are still in transmisison.
444 pBuf - Pointer to the buffer structure.
447 index - The index to the oldest pending packet in the queue.
450 Returns the index to the oldest pending packet in the queue. Otherwise,
455 int_t nbuf_peek_tx_key(buf_info_t* pBuf)
457 if (pBuf->tq_rear == pBuf->tq_front)
459 return -1; /* No pending transmit buffers. */
461 return pBuf->tx_keys_queue[pBuf->tq_front].tx_buf_index;
464 /******************************************************************************
465 nbuf_peek_bd_ahead() - Returns the pointer of the to the last buffer
466 descriptor of the 2nd. pending transmit frame.
469 pBuf - Pointer to the buffer structure.
473 Returns the pointer of the to the last buffer
474 descriptor of the 2nd. pending transmit frame. If there is not 2nd.
475 pending frame, it returns NULL.
480 NBUF* nbuf_peek_bd_ahead(buf_info_t* pBuf)
482 uint_t ahead_front = (pBuf->tq_front + 1) % TX_KEY_QUEUE_SIZE;
484 if (pBuf->tq_rear == pBuf->tq_front ||
485 ahead_front == pBuf->tq_rear)
487 return NULL; /* No pending transmit buffers. */
490 return &pBuf->TxNBUF[pBuf->tx_keys_queue[ahead_front].tx_buf_index];
495 /******************************************************************************
496 nbuf_enq_tx_key() - Enqueue and deuque transmit key queue.
497 Enqueue the transmit key. The buf_index is the index to the transmit buffer deiscriptor
498 table of the last buffer descriptor for the frame and the transmit packet
502 void nbuf_enq_tx_key(buf_info_t* pBuf,
508 tx_key_type_t key_type)
510 tx_keys_t* p_keys = &pBuf->tx_keys_queue[pBuf->tq_rear];
511 /* Assign the transmit packet information to the transmit key queue. */
513 /* NOTE: We don't check for the full condition because the transmit */
514 /* key queue size is as big as the number of buffer descriptors. */
516 p_keys->tx_key = txkey;
517 p_keys->tx_buf_index = buf_index;
518 p_keys->num_dbufs = num_bd;
519 p_keys->pk_len = total_len;
520 p_keys->start_index = start_index;
521 p_keys->key_type = key_type;
523 /* Advance the transmit queue pointer to the next entry. */
525 pBuf->tq_rear = (pBuf->tq_rear + 1) % TX_KEY_QUEUE_SIZE;
530 /******************************************************************************
531 nbuf_deq_tx_key() - Dequeue the transmit packet from the transmit key queue.
532 Assume that the queue is not empty.
536 pBuf - Pointer to the buffer structure.
539 key - The key the transmit information.
542 void nbuf_deq_tx_key(buf_info_t* pBuf, tx_keys_t* key)
545 CYG_ASSERT(pBuf->tq_rear != pBuf->tq_front, "nbuf_deq_tx_key: empty");
546 *key = pBuf->tx_keys_queue[pBuf->tq_front];
547 pBuf->tq_front = (pBuf->tq_front + 1) % TX_KEY_QUEUE_SIZE;
551 /*******************************************************************************
552 nbuf_tx_dump() - Dump the transmit buffer information.
555 pBuf - pointer to the buffer info.
558 void nbuf_tx_dump(buf_info_t* pBuf)
563 diag_printf("Current index to ring buffer: %d\n", pBuf->iTxbd);
564 diag_printf("Address to the BD: %08X\n",
565 &pBuf->TxNBUF[pBuf->iTxbd]);
567 diag_printf("BD status: %04X\n", pBuf->TxNBUF[pBuf->iTxbd].status);
568 diag_printf("TX Queue rear index: %d\n", pBuf->tq_rear);
569 diag_printf("TX Queue front index: %d\n", pBuf->tq_front);
570 diag_printf("Number of busy BDs: %d\n", pBuf->num_busy_bd);
572 diag_printf("Dump Transmit Queue\n");
573 diag_printf("===================\n");
575 while(nbuf_peek_tx_key(pBuf) != -1)
577 nbuf_deq_tx_key(pBuf, &key);
578 diag_printf("Number of BDs: %d\n", key.num_dbufs);
579 diag_printf("Frame length: %d\n", key.pk_len);
580 diag_printf("Begin index to ring bufer: %d\n", key.start_index);
581 diag_printf("BD address: %08X\n", &pBuf->TxNBUF[key.tx_buf_index]);
582 diag_printf("status: %04X\n", pBuf->TxNBUF[key.tx_buf_index].status);
584 diag_printf("End index to ring buffer: %d\n", key.tx_buf_index);
585 diag_printf("Key Info: %08X\n", key.tx_key);
586 diag_printf("Key type: %d\n", key.key_type);
590 diag_printf("===================\n");
596 /********************************************************************
597 nbuf_tx_allocate() - Alocate transmit buffer descriptor.
600 pBuf - pointer to the buffer info.
603 index - index to the buffer descriptor ring buffer that it returns. This
604 value is invalid if this funtion returns a NULL.
607 Returns the pointer to the buffer descriptor. If the ring buffer
608 descriptor is full, it returns NULL.
613 nbuf_tx_allocate (buf_info_t* pBuf)
615 NBUF* pBd = &pBuf->TxNBUF[pBuf->iTxbd];
617 /* If the ring buffer is full, then return a NULL. */
619 if (pBd->status & TX_BD_INUSE)
625 /* Make sure that the buffer descriptor is still not in use by the */
628 CYG_ASSERT(!(pBd->status & TX_BD_R),
629 "Buffer descriptor allocated still in use");
631 /* Set the buffer to be in used so that we can check the status */
632 /* before we resuse it to send another packet. */
634 pBd->status |= TX_BD_INUSE;
637 /* increment the circular index */
638 pBuf->iTxbd = ((pBuf->iTxbd + 1) % NUM_TXBDS);
646 /*****************************************************************************/