OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [devs/] [eth/] [mcf52xx/] [mcf5272/] [v2_0/] [include/] [nbuf.h] - Blame information for rev 448

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
#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 */

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.