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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [devs/] [eth/] [mcf52xx/] [mcf5272/] [current/] [include/] [nbuf.h] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
#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 Free Software Foundation, 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      
12
// version.                                                                 
13
//
14
// eCos is distributed in the hope that it will be useful, but WITHOUT      
15
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
16
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
17
// for more details.                                                        
18
//
19
// You should have received a copy of the GNU General Public License        
20
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
21
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
22
//
23
// As a special exception, if other files instantiate templates or use      
24
// macros or inline functions from this file, or you compile this file      
25
// and link it with other works to produce a work based on this file,       
26
// this file does not by itself cause the resulting work to be covered by   
27
// the GNU General Public License. However the source code for this file    
28
// must still be made available in accordance with section (3) of the GNU   
29
// General Public License v2.                                               
30
//
31
// This exception does not invalidate any other reasons why a work based    
32
// on this file might be covered by the GNU General Public License.         
33
// -------------------------------------------                              
34
// ####ECOSGPLCOPYRIGHTEND####                                              
35
//==========================================================================
36
 
37
/*
38
 * File:                nbuf.h
39
 * Purpose:             Definitions for Network Buffer Allocation.
40
 *
41
 * Notes:               These routines implement a static buffer scheme.
42
 *                              The buffer descriptors are as specified by the
43
 *                              MPC860T/MCF5272 FEC.
44
 *
45
 * Modifications:
46
 *
47
 */
48
 
49
#include <cyg/hal/drv_api.h>
50
#include <pkgconf/net_mcf5272_eth_drivers.h>
51
#include <cyg/hal/hal_intr.h>
52
#include <cyg/infra/cyg_type.h>
53
#include <cyg/infra/cyg_ass.h>
54
#include <cyg/io/eth/eth_drv.h>
55
 
56
 
57
 
58
/********************************************************************/
59
 
60
 
61
typedef unsigned char           uint8;  /*  8 bits */
62
typedef unsigned short int      uint16; /* 16 bits */
63
typedef unsigned long int       uint32; /* 32 bits */
64
 
65
typedef signed char                     int8;   /*  8 bits */
66
typedef signed short int        int16;  /* 16 bits */
67
typedef signed long int         int32;  /* 32 bits */
68
 
69
 
70
#define Rx      1
71
#define Tx      0
72
 
73
/*
74
 * Buffer sizes in bytes -- The following values were chosen based
75
 * on TFTP maximum packet sizes.  These sizes may need to be
76
 * increased to implement other protocols.
77
 */
78
#define RX_BUFFER_SIZE (576)    /* must be divisible by 16 */
79
/* #define TX_BUFFER_SIZE 576 */
80
 
81
 
82
/* The this label is not defined, we define it and default it to 256. */
83
#ifndef CYGPKG_NET_MCF5272_ETH_DRIVERS_RX_NUM_BDS
84
#define CYGPKG_NET_MCF5272_ETH_DRIVERS_RX_NUM_BDS 256
85
#endif
86
 
87
/* The this label is not defined, we define it and default it to 256. */
88
#ifndef CYGPKG_NET_MCF5272_ETH_DRIVERS_TX_NUM_BDS
89
#define CYGPKG_NET_MCF5272_ETH_DRIVERS_TX_NUM_BDS 256
90
#endif
91
 
92
 
93
/* Number of Receive and Transmit Buffers and Buffer Descriptors */
94
#define NUM_RXBDS (CYGPKG_NET_MCF5272_ETH_DRIVERS_RX_NUM_BDS)
95
#define NUM_TXBDS (CYGPKG_NET_MCF5272_ETH_DRIVERS_TX_NUM_BDS)
96
 
97
 
98
 
99
/*
100
 * Buffer Descriptor Format -- must be aligned on 4-byte boundary
101
 * but a 16-byte boundary is recommended.  However, we cannot pack
102
 * them on 16-byte boundaries as this will add 8-bytes of padding
103
 * between structures and the FEC of the MPC860T/MCF5272 will choke.
104
 */
105
typedef struct NBUF
106
{
107
        uint16 status;  /* control and status */
108
        uint16 length;  /* transfer length */
109
        uint8  *data;   /* buffer address */
110
} __attribute__ ((packed, aligned))NBUF;
111
 
112
 
113
/* Defines the tx key type. */
114
typedef enum tx_key_type_t
115
{
116
    TX_KEY_ECOS, /* eCos key */
117
    TX_KEY_USER  /* user key */
118
}tx_key_type_t;
119
 
120
typedef struct tx_keys_t
121
{
122
    unsigned long tx_key;       /* The transmit key that eCos gives us. */
123
    uint_t  tx_buf_index; /* Index to the TxNBUF where the last Buffer Descriptor of the frame. */
124
    int   num_dbufs;    /* The number transmit buffer allocated for the frame. */
125
    uint_t  start_index;  /* Index of the bd */
126
    int_t   pk_len;
127
    tx_key_type_t key_type;     /* The type of the key. */
128
 
129
}tx_keys_t;
130
 
131
typedef struct buf_info_t
132
{
133
 
134
    /*   Buffer descriptor indexes                                          */
135
 
136
    uint_t iTxbd;
137
    uint_t iRxbd;
138
 
139
    /*   Queue for the transmit keys                                        */
140
 
141
    #define TX_KEY_QUEUE_SIZE (NUM_TXBDS+1)
142
    tx_keys_t tx_keys_queue[TX_KEY_QUEUE_SIZE];
143
 
144
    /*   Rear and front pointer for the keys queue.                         */
145
 
146
    uint_t tq_rear;
147
    uint_t tq_front;
148
 
149
    /*   Number transmit descriptor buffers busy.                           */
150
 
151
    volatile int  num_busy_bd;
152
 
153
    /*   The maximum number of buffer decriptor used.                       */
154
 
155
    volatile int  max_num_busy_bd;
156
 
157
    /* Buffer Descriptors */
158
    NBUF  ntxbuf[NUM_TXBDS+2];
159
    NBUF  nrxbuf[NUM_RXBDS+2];
160
 
161
    NBUF* RxNBUF;
162
    NBUF* TxNBUF;
163
 
164
    /* Buffers */
165
    //TXB TxBuffer[NUM_TXBDS];
166
    u8_t RxBuffer[(NUM_RXBDS+2)*RX_BUFFER_SIZE];
167
 
168
 
169
}buf_info_t;
170
 
171
 
172
/********************************************************************/
173
 
174
/*
175
 * Bit level Buffer Descriptor definitions
176
 */
177
 
178
#define TX_BD_R                 0x8000
179
#define TX_BD_TO1               0x4000
180
#define TX_BD_INUSE     TX_BD_TO1
181
#define TX_BD_W                 0x2000
182
#define TX_BD_TO2               0x1000
183
#define TX_BD_L                 0x0800
184
#define TX_BD_TC                0x0400
185
#define TX_BD_DEF               0x0200
186
#define TX_BD_HB                0x0100
187
#define TX_BD_LC                0x0080
188
#define TX_BD_RL                0x0040
189
#define TX_BD_UN                0x0002
190
#define TX_BD_CSL               0x0001
191
 
192
#define RX_BD_E                 0x8000
193
#define RX_BD_R01               0x4000
194
#define RX_BD_W                 0x2000
195
#define RX_BD_R02               0x1000
196
#define RX_BD_L                 0x0800
197
#define RX_BD_M                 0x0100
198
#define RX_BD_BC                0x0080
199
#define RX_BD_MC                0x0040
200
#define RX_BD_LG                0x0020
201
#define RX_BD_NO                0x0010
202
#define RX_BD_SH                0x0008
203
#define RX_BD_CR                0x0004
204
#define RX_BD_OV                0x0002
205
#define RX_BD_TR                0x0001
206
 
207
/*******************************************************************/
208
 
209
/*
210
 * Functions to manipulate the network buffers.
211
 */
212
 
213
void nbuf_init (buf_info_t* pBuf);
214
 
215
 
216
/********************************************************************/
217
inline static
218
uint32
219
nbuf_get_start(buf_info_t* pBuf, uint8 direction)
220
{
221
        /*
222
         * Return the address of the first buffer descriptor in the ring.
223
         * This routine is needed by the FEC of the MPC860T and MCF5272
224
         * in order to write the Rx/Tx descriptor ring start registers
225
         */
226
        switch (direction){
227
        case Rx:
228
                return (uint32)pBuf->RxNBUF;
229
    default:
230
        case Tx:
231
                return (uint32)pBuf->TxNBUF;
232
        }
233
}
234
 
235
 
236
 
237
 
238
 
239
 
240
/******************************************************************************
241
 nbuf_rx_get_next() - Retrieve the next  receive buffer descriptor.
242
 
243
 INPUT:
244
    pBuf - Pointer to the buffer info.
245
 
246
RETURN:
247
    Returns the pointer to the next receive buffer descriptor.
248
*/
249
 
250
inline static
251
NBUF *
252
nbuf_rx_get_next(buf_info_t* pBuf)
253
{
254
    NBUF* pBd = &pBuf->RxNBUF[pBuf->iRxbd];
255
 
256
        /* Check to see if the ring of BDs is full */
257
        if (pBd->status & RX_BD_E)
258
    {
259
                return NULL;
260
    }
261
 
262
        /* increment the circular index */
263
        pBuf->iRxbd = (pBuf->iRxbd + 1) % NUM_RXBDS;
264
 
265
        return pBd;
266
}
267
 
268
 
269
/* Return the pointer to the buffer descriptor based on the index */
270
inline static
271
NBUF*
272
nbuf_rx_get(buf_info_t* pBuf, uint_t index)
273
{
274
    return(&pBuf->RxNBUF[index]);
275
}
276
 
277
/********************************************************************
278
  Release the buffer descrip so that it can be use
279
  to receive the enxt packet.
280
 
281
  INPUT:
282
    pNbuf - pointer to the buffer descriptor.
283
*/
284
 
285
inline static
286
void
287
nbuf_rx_release (NBUF* pNbuf)
288
{
289
 
290
        /* Mark the buffer as empty and not in use */
291
        pNbuf->status |= RX_BD_E;
292
 
293
}
294
 
295
 
296
/* Return the current rx buffer descriptor index */
297
inline static uint_t
298
nbuf_rx_get_index(buf_info_t* pBuf)
299
{
300
    return  pBuf->iRxbd;
301
}
302
 
303
/****************************************************************
304
 This function checks the EMPTY bit of the next Rx buffer to be
305
 allocated. If the EMPTY bit is cleared, then the next buffer in
306
 the ring has been filled by the FEC and has not already been
307
 allocated and passed up the stack. In this case, the next buffer
308
 in the ring is ready to be allocated. Otherwise, the  buffer is
309
 either empty or not empty but still in use by a higher level
310
 protocol. The FEC receive routine uses this function to determine
311
 if multiple buffers where filled by the FEC during a single
312
 interrupt event.
313
 ****************************************************************/
314
inline static
315
uint_t
316
nbuf_rx_next_ready(buf_info_t* pBuf)
317
{
318
 
319
        return ( !(pBuf->RxNBUF[pBuf->iRxbd].status & RX_BD_E));
320
}
321
 
322
 
323
 
324
 
325
/******************************************************************************
326
   nbuf_rx_release_pkt() - Release the buffer descriptors of the next packet.
327
 
328
   INPUT:
329
        pointer to the buffer info.
330
*/
331
inline static
332
void nbuf_rx_release_pkt(buf_info_t* pBuf)
333
{
334
 
335
     NBUF* pNbuf;
336
 
337
     /* Indicates whether the last buffer descriptor is encountered. */
338
     cyg_bool_t last = false;
339
 
340
     do
341
     {
342
         /* Get the buffer descriptor. */
343
         pNbuf = nbuf_rx_get_next(pBuf);
344
 
345
         /*   Stop when there is a packet truncated bit is set or it is the */
346
         /* last buffer descriptor of the packet.                           */
347
 
348
         if ((!(pNbuf->status & RX_BD_E) && pNbuf->status & RX_BD_TR) ||
349
             pNbuf->status & RX_BD_L)
350
         {
351
             last = true;
352
         }
353
 
354
         /* Release the buffer descriptor. */
355
         nbuf_rx_release(pNbuf);
356
 
357
     }while(last == false);
358
 
359
}
360
 
361
 
362
 
363
/******************************************************************************
364
   nbuf_rx_release_good_pkt() - Release the buffer descriptors for
365
                                good received packets.
366
                                Note call this function
367
                                only when there is valid received
368
                                buffer descriptors.
369
 
370
   INPUT:
371
        pBuf - pointer to the buffer info.
372
*/
373
inline static
374
void nbuf_rx_release_good_pkt(buf_info_t* pBuf)
375
{
376
 
377
     u16_t status;
378
 
379
     do
380
     {
381
 
382
         /*   Read the status bits.  If the RX_BD_L is set we terminate the */
383
         /* loop.                                                           */
384
 
385
         status = pBuf->RxNBUF[pBuf->iRxbd].status;
386
 
387
         /*   Release the buffer descriptor so that it could reused.        */
388
 
389
         nbuf_rx_release(&pBuf->RxNBUF[pBuf->iRxbd]);
390
 
391
         /*   Advance the index to the next buffer descriptor.              */
392
 
393
         pBuf->iRxbd = (pBuf->iRxbd + 1) % NUM_RXBDS;
394
 
395
 
396
     }while(!(status & RX_BD_L));
397
 
398
}
399
 
400
 
401
/******************************************************************************
402
  nbuf_tx_release() - Set the buffer descriptor ready for use to transmit
403
                      the next packet.
404
 
405
   INPUT:
406
        pNbuf - Pointer to the transmit buffer descriptor.
407
*/
408
inline static
409
void
410
nbuf_tx_release (NBUF* pNbuf)
411
{
412
 
413
    /*   Clear  the  TX_BD_INUSE  to  indicate   that  we  have  read   the */
414
    /* transmitted buffer.                                                  */
415
 
416
    pNbuf->status &= ~(TX_BD_INUSE | TX_BD_R | TX_BD_L | TX_BD_TC);
417
 
418
}
419
 
420
/* Return a nozero value  if the buffer is full. Otherwise, it returns a
421
   zero value.
422
*/
423
inline static
424
int_t nbuf_tx_full(buf_info_t* pBuf)
425
{
426
    return (pBuf->TxNBUF[pBuf->iTxbd].status & TX_BD_R);
427
}
428
 
429
 
430
/* Return the pointer to the transmit buffer descriptor. */
431
inline static
432
NBUF*
433
nbuf_tx_get(buf_info_t* pBuf, int_t index)
434
{
435
    return(&pBuf->TxNBUF[index]);
436
}
437
 
438
/******************************************************************************
439
 nbuf_peek_tx_key() - Peek whether there is any
440
                      pending packets that are still in transmisison.
441
 
442
 INPUT:
443
    pBuf - Pointer to the buffer structure.
444
 
445
 OUTPUT:
446
    index - The index to the oldest pending packet in the queue.
447
 
448
 RETURN:
449
    Returns the index to the oldest pending packet in the queue. Otherwise,
450
    it returns -1.
451
 
452
*/
453
inline static
454
int_t nbuf_peek_tx_key(buf_info_t* pBuf)
455
{
456
    if (pBuf->tq_rear == pBuf->tq_front)
457
    {
458
        return -1; /* No pending transmit buffers. */
459
    }
460
    return pBuf->tx_keys_queue[pBuf->tq_front].tx_buf_index;
461
}
462
 
463
/******************************************************************************
464
 nbuf_peek_bd_ahead() - Returns the pointer of the to the last buffer
465
                        descriptor of the 2nd. pending transmit frame.
466
 
467
 INPUT:
468
    pBuf - Pointer to the buffer structure.
469
 
470
 
471
 RETURN:
472
    Returns the pointer of the to the last buffer
473
    descriptor of the 2nd. pending transmit frame. If there is not 2nd.
474
    pending frame, it returns NULL.
475
 
476
 
477
*/
478
inline static
479
NBUF* nbuf_peek_bd_ahead(buf_info_t* pBuf)
480
{
481
    uint_t ahead_front = (pBuf->tq_front + 1) % TX_KEY_QUEUE_SIZE;
482
 
483
    if (pBuf->tq_rear == pBuf->tq_front ||
484
        ahead_front == pBuf->tq_rear)
485
    {
486
        return NULL; /* No pending transmit buffers. */
487
    }
488
 
489
    return &pBuf->TxNBUF[pBuf->tx_keys_queue[ahead_front].tx_buf_index];
490
}
491
 
492
 
493
 
494
/******************************************************************************
495
 nbuf_enq_tx_key() - Enqueue and deuque transmit key queue.
496
   Enqueue the transmit key. The  buf_index is the index to the transmit buffer deiscriptor
497
   table of the last buffer descriptor for the frame and the transmit packet
498
   type.
499
*/
500
inline static
501
void nbuf_enq_tx_key(buf_info_t* pBuf,
502
                     uint_t buf_index,
503
                     unsigned long txkey,
504
                     uint_t start_index,
505
                     int num_bd,
506
                     int_t total_len,
507
                     tx_key_type_t key_type)
508
{
509
    tx_keys_t* p_keys = &pBuf->tx_keys_queue[pBuf->tq_rear];
510
    /*   Assign the transmit packet information to the transmit key queue.  */
511
 
512
    /*   NOTE: We don't check for  the full condition because the  transmit */
513
    /* key queue size is as big as the number of buffer descriptors.        */
514
 
515
    p_keys->tx_key = txkey;
516
    p_keys->tx_buf_index  = buf_index;
517
    p_keys->num_dbufs = num_bd;
518
    p_keys->pk_len = total_len;
519
    p_keys->start_index = start_index;
520
    p_keys->key_type = key_type;
521
 
522
    /*   Advance the transmit queue pointer to the next entry.              */
523
 
524
    pBuf->tq_rear = (pBuf->tq_rear + 1) % TX_KEY_QUEUE_SIZE;
525
 
526
 }
527
 
528
 
529
/******************************************************************************
530
 nbuf_deq_tx_key() - Dequeue the transmit packet from the transmit key queue.
531
                     Assume that the queue is not empty.
532
 
533
 
534
 INPUT:
535
    pBuf - Pointer to the buffer structure.
536
 
537
 OUTPUT:
538
    key - The  key the transmit information.
539
*/
540
inline static
541
void nbuf_deq_tx_key(buf_info_t* pBuf, tx_keys_t* key)
542
{
543
 
544
    CYG_ASSERT(pBuf->tq_rear != pBuf->tq_front, "nbuf_deq_tx_key: empty");
545
    *key = pBuf->tx_keys_queue[pBuf->tq_front];
546
    pBuf->tq_front = (pBuf->tq_front + 1) %  TX_KEY_QUEUE_SIZE;
547
 
548
}
549
 
550
/*******************************************************************************
551
 nbuf_tx_dump() - Dump the transmit buffer information.
552
 
553
 INPUT:
554
    pBuf - pointer to the buffer info.
555
*/
556
inline static
557
void nbuf_tx_dump(buf_info_t* pBuf)
558
{
559
 
560
    tx_keys_t key;
561
 
562
    diag_printf("Current index to ring buffer: %d\n", pBuf->iTxbd);
563
    diag_printf("Address to the BD:            %08X\n",
564
                &pBuf->TxNBUF[pBuf->iTxbd]);
565
 
566
    diag_printf("BD status:            %04X\n", pBuf->TxNBUF[pBuf->iTxbd].status);
567
    diag_printf("TX Queue rear index:  %d\n", pBuf->tq_rear);
568
    diag_printf("TX Queue front index: %d\n", pBuf->tq_front);
569
    diag_printf("Number of busy BDs:   %d\n", pBuf->num_busy_bd);
570
 
571
    diag_printf("Dump Transmit Queue\n");
572
    diag_printf("===================\n");
573
 
574
    while(nbuf_peek_tx_key(pBuf) != -1)
575
    {
576
        nbuf_deq_tx_key(pBuf, &key);
577
        diag_printf("Number of BDs: %d\n", key.num_dbufs);
578
        diag_printf("Frame length:  %d\n", key.pk_len);
579
        diag_printf("Begin index to ring bufer: %d\n", key.start_index);
580
        diag_printf("BD address: %08X\n", &pBuf->TxNBUF[key.tx_buf_index]);
581
        diag_printf("status: %04X\n", pBuf->TxNBUF[key.tx_buf_index].status);
582
 
583
        diag_printf("End index to ring buffer:  %d\n", key.tx_buf_index);
584
        diag_printf("Key Info: %08X\n", key.tx_key);
585
        diag_printf("Key type: %d\n", key.key_type);
586
        diag_printf("\n");
587
 
588
    }
589
    diag_printf("===================\n");
590
 
591
 
592
}
593
 
594
 
595
/********************************************************************
596
 nbuf_tx_allocate() - Alocate transmit buffer descriptor.
597
 
598
 INPUT:
599
    pBuf - pointer to the buffer info.
600
 
601
 OUTPUT:
602
    index - index to the buffer descriptor ring buffer that it returns. This
603
            value is invalid if this funtion returns a NULL.
604
 
605
 RETURN:
606
    Returns the pointer to the buffer descriptor. If the ring buffer
607
    descriptor is full, it returns NULL.
608
 
609
 */
610
inline static
611
NBUF *
612
nbuf_tx_allocate (buf_info_t* pBuf)
613
{
614
    NBUF* pBd = &pBuf->TxNBUF[pBuf->iTxbd];
615
 
616
    /*   If the ring buffer is full, then return a NULL.                    */
617
 
618
        if (pBd->status & TX_BD_INUSE)
619
    {
620
        nbuf_tx_dump(pBuf);
621
        return NULL;
622
    }
623
 
624
    /*   Make sure that the  buffer descriptor is still  not in use by  the */
625
    /* FEC .                                                                */
626
 
627
    CYG_ASSERT(!(pBd->status & TX_BD_R),
628
               "Buffer descriptor allocated still in use");
629
 
630
    /*   Set the buffer  to be  in used  so that  we can  check the  status */
631
    /* before we resuse it to send another packet.                          */
632
 
633
    pBd->status |= TX_BD_INUSE;
634
 
635
 
636
        /* increment the circular index */
637
        pBuf->iTxbd = ((pBuf->iTxbd + 1) % NUM_TXBDS);
638
 
639
        return pBd;
640
}
641
 
642
 
643
 
644
 
645
/*****************************************************************************/
646
 
647
#endif  /* _NBUF_H */

powered by: WebSVN 2.1.0

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