]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/devs/eth/mcf52xx/mcf5272/v2_0/include/nbuf.h
Initial revision
[karo-tx-redboot.git] / packages / devs / eth / mcf52xx / mcf5272 / v2_0 / include / nbuf.h
1 #ifndef _NBUF_H
2 #define _NBUF_H
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.
8 //
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.
12 //
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
16 // for more details.
17 //
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.
21 //
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.
28 //
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.
31 //
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 //==========================================================================
37
38 /*
39  * File:                nbuf.h
40  * Purpose:             Definitions for Network Buffer Allocation.
41  *
42  * Notes:               These routines implement a static buffer scheme.
43  *                              The buffer descriptors are as specified by the
44  *                              MPC860T/MCF5272 FEC.
45  *
46  * Modifications:
47  *
48  */
49
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>
56
57
58
59 /********************************************************************/
60
61
62 typedef unsigned char           uint8;  /*  8 bits */
63 typedef unsigned short int      uint16; /* 16 bits */
64 typedef unsigned long int       uint32; /* 32 bits */
65
66 typedef signed char                     int8;   /*  8 bits */
67 typedef signed short int        int16;  /* 16 bits */
68 typedef signed long int         int32;  /* 32 bits */
69
70
71 #define Rx      1
72 #define Tx      0
73
74 /*
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.
78  */
79 #define RX_BUFFER_SIZE (576)    /* must be divisible by 16 */
80 /* #define TX_BUFFER_SIZE 576 */
81
82
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
86 #endif
87
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
91 #endif
92
93
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)
97
98
99
100 /*
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.
105  */
106 typedef struct NBUF
107 {
108         uint16 status;  /* control and status */
109         uint16 length;  /* transfer length */
110         uint8  *data;   /* buffer address */
111 } __attribute__ ((packed, aligned))NBUF;
112
113
114 /* Defines the tx key type. */
115 typedef enum tx_key_type_t
116 {
117     TX_KEY_ECOS, /* eCos key */
118     TX_KEY_USER  /* user key */
119 }tx_key_type_t;
120
121 typedef struct tx_keys_t
122 {
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 */
127     int_t   pk_len;
128     tx_key_type_t key_type;     /* The type of the key. */
129
130 }tx_keys_t;
131
132 typedef struct buf_info_t
133 {
134
135     /*   Buffer descriptor indexes                                          */
136
137     uint_t iTxbd;
138     uint_t iRxbd;
139
140     /*   Queue for the transmit keys                                        */
141
142     #define TX_KEY_QUEUE_SIZE (NUM_TXBDS+1)
143     tx_keys_t tx_keys_queue[TX_KEY_QUEUE_SIZE];
144
145     /*   Rear and front pointer for the keys queue.                         */
146
147     uint_t tq_rear;
148     uint_t tq_front;
149
150     /*   Number transmit descriptor buffers busy.                           */
151
152     volatile int  num_busy_bd;
153
154     /*   The maximum number of buffer decriptor used.                       */
155
156     volatile int  max_num_busy_bd;
157
158     /* Buffer Descriptors */
159     NBUF  ntxbuf[NUM_TXBDS+2];
160     NBUF  nrxbuf[NUM_RXBDS+2];
161
162     NBUF* RxNBUF;
163     NBUF* TxNBUF;
164
165     /* Buffers */
166     //TXB TxBuffer[NUM_TXBDS];
167     u8_t RxBuffer[(NUM_RXBDS+2)*RX_BUFFER_SIZE];
168
169
170 }buf_info_t;
171
172
173 /********************************************************************/
174
175 /*
176  * Bit level Buffer Descriptor definitions
177  */
178
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
192
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
207
208 /*******************************************************************/
209
210 /*
211  * Functions to manipulate the network buffers.
212  */
213
214 void nbuf_init (buf_info_t* pBuf);
215
216
217 /********************************************************************/
218 inline static
219 uint32
220 nbuf_get_start(buf_info_t* pBuf, uint8 direction)
221 {
222         /*
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
226          */
227         switch (direction){
228         case Rx:
229                 return (uint32)pBuf->RxNBUF;
230     default:
231         case Tx:
232                 return (uint32)pBuf->TxNBUF;
233         }
234 }
235
236
237
238
239
240
241 /******************************************************************************
242  nbuf_rx_get_next() - Retrieve the next  receive buffer descriptor.
243
244  INPUT:
245     pBuf - Pointer to the buffer info.
246
247 RETURN:
248     Returns the pointer to the next receive buffer descriptor.
249 */
250
251 inline static
252 NBUF *
253 nbuf_rx_get_next(buf_info_t* pBuf)
254 {
255     NBUF* pBd = &pBuf->RxNBUF[pBuf->iRxbd];
256
257         /* Check to see if the ring of BDs is full */
258         if (pBd->status & RX_BD_E)
259     {
260                 return NULL;
261     }
262
263         /* increment the circular index */
264         pBuf->iRxbd = (pBuf->iRxbd + 1) % NUM_RXBDS;
265
266         return pBd;
267 }
268
269
270 /* Return the pointer to the buffer descriptor based on the index */
271 inline static
272 NBUF*
273 nbuf_rx_get(buf_info_t* pBuf, uint_t index)
274 {
275     return(&pBuf->RxNBUF[index]);
276 }
277
278 /********************************************************************
279   Release the buffer descrip so that it can be use
280   to receive the enxt packet.
281
282   INPUT:
283     pNbuf - pointer to the buffer descriptor.
284 */
285
286 inline static
287 void
288 nbuf_rx_release (NBUF* pNbuf)
289 {
290         
291         /* Mark the buffer as empty and not in use */
292         pNbuf->status |= RX_BD_E;
293
294 }
295
296
297 /* Return the current rx buffer descriptor index */
298 inline static uint_t
299 nbuf_rx_get_index(buf_info_t* pBuf)
300 {
301     return  pBuf->iRxbd;
302 }
303
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
313  interrupt event.
314  ****************************************************************/
315 inline static
316 uint_t
317 nbuf_rx_next_ready(buf_info_t* pBuf)
318 {
319
320         return ( !(pBuf->RxNBUF[pBuf->iRxbd].status & RX_BD_E));
321 }
322
323
324
325
326 /******************************************************************************
327    nbuf_rx_release_pkt() - Release the buffer descriptors of the next packet.
328
329    INPUT:
330         pointer to the buffer info.
331 */
332 inline static
333 void nbuf_rx_release_pkt(buf_info_t* pBuf)
334 {
335
336      NBUF* pNbuf;
337
338      /* Indicates whether the last buffer descriptor is encountered. */
339      cyg_bool_t last = false;
340
341      do
342      {
343          /* Get the buffer descriptor. */
344          pNbuf = nbuf_rx_get_next(pBuf);
345
346          /*   Stop when there is a packet truncated bit is set or it is the */
347          /* last buffer descriptor of the packet.                           */
348
349          if ((!(pNbuf->status & RX_BD_E) && pNbuf->status & RX_BD_TR) ||
350              pNbuf->status & RX_BD_L)
351          {
352              last = true;
353          }
354
355          /* Release the buffer descriptor. */
356          nbuf_rx_release(pNbuf);
357
358      }while(last == false);
359
360 }
361
362
363
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
369                                 buffer descriptors.
370
371    INPUT:
372         pBuf - pointer to the buffer info.
373 */
374 inline static
375 void nbuf_rx_release_good_pkt(buf_info_t* pBuf)
376 {
377
378      u16_t status;
379
380      do
381      {
382
383          /*   Read the status bits.  If the RX_BD_L is set we terminate the */
384          /* loop.                                                           */
385
386          status = pBuf->RxNBUF[pBuf->iRxbd].status;
387
388          /*   Release the buffer descriptor so that it could reused.        */
389
390          nbuf_rx_release(&pBuf->RxNBUF[pBuf->iRxbd]);
391
392          /*   Advance the index to the next buffer descriptor.              */
393
394          pBuf->iRxbd = (pBuf->iRxbd + 1) % NUM_RXBDS;
395
396
397      }while(!(status & RX_BD_L));
398
399 }
400
401
402 /******************************************************************************
403   nbuf_tx_release() - Set the buffer descriptor ready for use to transmit
404                       the next packet.
405
406    INPUT:
407         pNbuf - Pointer to the transmit buffer descriptor.
408 */
409 inline static
410 void
411 nbuf_tx_release (NBUF* pNbuf)
412 {
413
414     /*   Clear  the  TX_BD_INUSE  to  indicate   that  we  have  read   the */
415     /* transmitted buffer.                                                  */
416
417     pNbuf->status &= ~(TX_BD_INUSE | TX_BD_R | TX_BD_L | TX_BD_TC);
418
419 }
420
421 /* Return a nozero value  if the buffer is full. Otherwise, it returns a
422    zero value.
423 */
424 inline static
425 int_t nbuf_tx_full(buf_info_t* pBuf)
426 {
427     return (pBuf->TxNBUF[pBuf->iTxbd].status & TX_BD_R);
428 }
429
430
431 /* Return the pointer to the transmit buffer descriptor. */
432 inline static
433 NBUF*
434 nbuf_tx_get(buf_info_t* pBuf, int_t index)
435 {
436     return(&pBuf->TxNBUF[index]);
437 }
438
439 /******************************************************************************
440  nbuf_peek_tx_key() - Peek whether there is any
441                       pending packets that are still in transmisison.
442
443  INPUT:
444     pBuf - Pointer to the buffer structure.
445
446  OUTPUT:
447     index - The index to the oldest pending packet in the queue.
448
449  RETURN:
450     Returns the index to the oldest pending packet in the queue. Otherwise,
451     it returns -1.
452
453 */
454 inline static
455 int_t nbuf_peek_tx_key(buf_info_t* pBuf)
456 {
457     if (pBuf->tq_rear == pBuf->tq_front)
458     {
459         return -1; /* No pending transmit buffers. */
460     }
461     return pBuf->tx_keys_queue[pBuf->tq_front].tx_buf_index;
462 }
463
464 /******************************************************************************
465  nbuf_peek_bd_ahead() - Returns the pointer of the to the last buffer
466                         descriptor of the 2nd. pending transmit frame.
467
468  INPUT:
469     pBuf - Pointer to the buffer structure.
470
471
472  RETURN:
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.
476
477
478 */
479 inline static
480 NBUF* nbuf_peek_bd_ahead(buf_info_t* pBuf)
481 {
482     uint_t ahead_front = (pBuf->tq_front + 1) % TX_KEY_QUEUE_SIZE;
483
484     if (pBuf->tq_rear == pBuf->tq_front ||
485         ahead_front == pBuf->tq_rear)
486     {
487         return NULL; /* No pending transmit buffers. */
488     }
489
490     return &pBuf->TxNBUF[pBuf->tx_keys_queue[ahead_front].tx_buf_index];
491 }
492
493
494
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
499    type.
500 */
501 inline static
502 void nbuf_enq_tx_key(buf_info_t* pBuf,
503                      uint_t buf_index,
504                      unsigned long txkey,
505                      uint_t start_index,
506                      int num_bd,
507                      int_t total_len,
508                      tx_key_type_t key_type)
509 {
510     tx_keys_t* p_keys = &pBuf->tx_keys_queue[pBuf->tq_rear];
511     /*   Assign the transmit packet information to the transmit key queue.  */
512
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.        */
515
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;
522
523     /*   Advance the transmit queue pointer to the next entry.              */
524
525     pBuf->tq_rear = (pBuf->tq_rear + 1) % TX_KEY_QUEUE_SIZE;
526
527  }
528
529
530 /******************************************************************************
531  nbuf_deq_tx_key() - Dequeue the transmit packet from the transmit key queue.
532                      Assume that the queue is not empty.
533
534
535  INPUT:
536     pBuf - Pointer to the buffer structure.
537
538  OUTPUT:
539     key - The  key the transmit information.
540 */
541 inline static
542 void nbuf_deq_tx_key(buf_info_t* pBuf, tx_keys_t* key)
543 {
544
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;
548
549 }
550
551 /*******************************************************************************
552  nbuf_tx_dump() - Dump the transmit buffer information.
553
554  INPUT:
555     pBuf - pointer to the buffer info.
556 */
557 inline static
558 void nbuf_tx_dump(buf_info_t* pBuf)
559 {
560
561     tx_keys_t key;
562
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]);
566
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);
571
572     diag_printf("Dump Transmit Queue\n");
573     diag_printf("===================\n");
574
575     while(nbuf_peek_tx_key(pBuf) != -1)
576     {
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);
583
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);
587         diag_printf("\n");
588
589     }
590     diag_printf("===================\n");
591
592
593 }
594
595
596 /********************************************************************
597  nbuf_tx_allocate() - Alocate transmit buffer descriptor.
598
599  INPUT:
600     pBuf - pointer to the buffer info.
601
602  OUTPUT:
603     index - index to the buffer descriptor ring buffer that it returns. This
604             value is invalid if this funtion returns a NULL.
605
606  RETURN:
607     Returns the pointer to the buffer descriptor. If the ring buffer
608     descriptor is full, it returns NULL.
609
610  */
611 inline static
612 NBUF *
613 nbuf_tx_allocate (buf_info_t* pBuf)
614 {
615     NBUF* pBd = &pBuf->TxNBUF[pBuf->iTxbd];
616
617     /*   If the ring buffer is full, then return a NULL.                    */
618
619         if (pBd->status & TX_BD_INUSE)
620     {
621         nbuf_tx_dump(pBuf);
622         return NULL;
623     }
624         
625     /*   Make sure that the  buffer descriptor is still  not in use by  the */
626     /* FEC .                                                                */
627
628     CYG_ASSERT(!(pBd->status & TX_BD_R),
629                "Buffer descriptor allocated still in use");
630
631     /*   Set the buffer  to be  in used  so that  we can  check the  status */
632     /* before we resuse it to send another packet.                          */
633
634     pBd->status |= TX_BD_INUSE;
635
636
637         /* increment the circular index */
638         pBuf->iTxbd = ((pBuf->iTxbd + 1) % NUM_TXBDS);
639
640         return pBd;
641 }
642
643
644
645
646 /*****************************************************************************/
647
648 #endif  /* _NBUF_H */