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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [orpsocv2/] [sw/] [tests/] [ethmac/] [sim/] [ethmac-tx.c] - Blame information for rev 409

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

Line No. Rev Author Line
1 349 julius
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  Interrupt-driven Ethernet MAC transmit test code            ////
4
////                                                              ////
5
////  Description                                                 ////
6
////  Transmits packets, testing both 100mbit and 10mbit modes.   ////
7
////  Expects testbench to be checking each packet sent.          ////   
8
////  Define, ETH_TX_TEST_LENGTH, set further down, controls how  ////
9
////  many packets the test will send.                            ////
10
////                                                              ////
11
////  Test data comes from pre-calculated array of random values, ////
12
////  MAC TX buffer pointers are set to addresses in this array,  ////
13
////  saving copying the data around before transfers.            ////
14
////                                                              ////
15
////  Author(s):                                                  ////
16
////      - jb, jb@orsoc.se, with parts taken from Linux kernel   ////
17
////        open_eth driver.                                      ////
18
////                                                              ////
19
////                                                              ////
20
//////////////////////////////////////////////////////////////////////
21
////                                                              ////
22
//// Copyright (C) 2009 Authors and OPENCORES.ORG                 ////
23
////                                                              ////
24
//// This source file may be used and distributed without         ////
25
//// restriction provided that this copyright statement is not    ////
26
//// removed from the file and that any derivative work contains  ////
27
//// the original copyright notice and the associated disclaimer. ////
28
////                                                              ////
29
//// This source file is free software; you can redistribute it   ////
30
//// and/or modify it under the terms of the GNU Lesser General   ////
31
//// Public License as published by the Free Software Foundation; ////
32
//// either version 2.1 of the License, or (at your option) any   ////
33
//// later version.                                               ////
34
////                                                              ////
35
//// This source is distributed in the hope that it will be       ////
36
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
37
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
38
//// PURPOSE.  See the GNU Lesser General Public License for more ////
39
//// details.                                                     ////
40
////                                                              ////
41
//// You should have received a copy of the GNU Lesser General    ////
42
//// Public License along with this source; if not, download it   ////
43
//// from http://www.opencores.org/lgpl.shtml                     ////
44
////                                                              ////
45
//////////////////////////////////////////////////////////////////////
46
 
47
#include "or32-utils.h"
48
#include "spr-defs.h"
49
#include "board.h"
50
#include "int.h"
51
#include "uart.h"
52
#include "open-eth.h"
53
#include "printf.h"
54
#include "eth-phy-mii.h"
55
 
56
volatile unsigned tx_done;
57
volatile unsigned rx_done;
58
static int next_tx_buf_num;
59
 
60
/* Functions in this file */
61
void ethmac_setup(void);
62
/* Interrupt functions */
63
void oeth_interrupt(void);
64
static void oeth_rx(void);
65
static void oeth_tx(void);
66
 
67
/* Defining RTLSIM turns off use of real printf'ing to save time in simulation */
68
#define RTLSIM
69
 
70
#ifdef RTLSIM
71
#define printk
72
#else
73
#define printk printf
74
#endif
75
/* Let the ethernet packets use a space beginning here for buffering */
76
#define ETH_BUFF_BASE 0x01000000
77
 
78
 
79
#define RXBUFF_PREALLOC 1
80
#define TXBUFF_PREALLOC 1
81
//#undef RXBUFF_PREALLOC
82
//#undef TXBUFF_PREALLOC
83
 
84
/* The transmitter timeout
85
 */
86
#define TX_TIMEOUT      (2*HZ)
87
 
88
/* Buffer number (must be 2^n)
89
 */
90
#define OETH_RXBD_NUM           16
91
#define OETH_TXBD_NUM           16
92
#define OETH_RXBD_NUM_MASK      (OETH_RXBD_NUM-1)
93
#define OETH_TXBD_NUM_MASK      (OETH_TXBD_NUM-1)
94
 
95
/* Buffer size
96
 */
97
#define OETH_RX_BUFF_SIZE       0x600 - 4
98
#define OETH_TX_BUFF_SIZE       0x600 - 4
99
 
100
/* OR32 Page size def */
101
#define PAGE_SHIFT              13
102
#define PAGE_SIZE               (1UL << PAGE_SHIFT)
103
 
104
/* How many buffers per page
105
 */
106
#define OETH_RX_BUFF_PPGAE      (PAGE_SIZE/OETH_RX_BUFF_SIZE)
107
#define OETH_TX_BUFF_PPGAE      (PAGE_SIZE/OETH_TX_BUFF_SIZE)
108
 
109
/* How many pages is needed for buffers
110
 */
111
#define OETH_RX_BUFF_PAGE_NUM   (OETH_RXBD_NUM/OETH_RX_BUFF_PPGAE)
112
#define OETH_TX_BUFF_PAGE_NUM   (OETH_TXBD_NUM/OETH_TX_BUFF_PPGAE)
113
 
114
/* Buffer size  (if not XXBUF_PREALLOC
115
 */
116
#define MAX_FRAME_SIZE          1518
117
 
118
/* The buffer descriptors track the ring buffers.
119
 */
120
struct oeth_private {
121
  //struct      sk_buff* rx_skbuff[OETH_RXBD_NUM];
122
  //struct      sk_buff* tx_skbuff[OETH_TXBD_NUM];
123
 
124
  unsigned short        tx_next;                        /* Next buffer to be sent */
125
  unsigned short        tx_last;                        /* Next buffer to be checked if packet sent */
126
  unsigned short        tx_full;                        /* Buffer ring fuul indicator */
127
  unsigned short        rx_cur;                         /* Next buffer to be checked if packet received */
128
 
129
  oeth_regs     *regs;                  /* Address of controller registers. */
130
  oeth_bd               *rx_bd_base;            /* Address of Rx BDs. */
131
  oeth_bd               *tx_bd_base;            /* Address of Tx BDs. */
132
 
133
  //    struct net_device_stats stats;
134
};
135
 
136
 
137
// Data array of data to transmit, tx_data_array[]
138
#include "eth-rxtx-data.h"
139
int tx_data_pointer;
140
 
141
#define PHYNUM 7
142
 
143
void
144
eth_mii_write(char phynum, short regnum, short data)
145
{
146
  static volatile oeth_regs *regs = (oeth_regs *)(OETH_REG_BASE);
147
  regs->miiaddress = (regnum << 8) | phynum;
148
  regs->miitx_data = data;
149
  regs->miicommand = OETH_MIICOMMAND_WCTRLDATA;
150
  regs->miicommand = 0;
151
  while(regs->miistatus & OETH_MIISTATUS_BUSY);
152
}
153
 
154
short
155
eth_mii_read(char phynum, short regnum)
156
{
157
  static volatile oeth_regs *regs = (oeth_regs *)(OETH_REG_BASE);
158
  regs->miiaddress = (regnum << 8) | phynum;
159
  regs->miicommand = OETH_MIICOMMAND_RSTAT;
160
  regs->miicommand = 0;
161
  while(regs->miistatus & OETH_MIISTATUS_BUSY);
162
 
163
  return regs->miirx_data;
164
}
165
 
166
 
167
// Wait here until all packets have been transmitted
168
void wait_until_all_tx_clear(void)
169
{
170
 
171
  int i;
172
  volatile oeth_bd *tx_bd;
173
  tx_bd = (volatile oeth_bd *)OETH_BD_BASE; /* Search from beginning*/
174
 
175
  int some_tx_waiting = 1;
176
 
177
  while (some_tx_waiting)
178
    {
179
      some_tx_waiting = 0;
180
      /* Go through the TX buffs, search for unused one */
181
      for(i = 0; i < OETH_TXBD_NUM; i++) {
182
 
183
        if((tx_bd[i].len_status & OETH_TX_BD_READY)) // Looking for buffer ready for transmit
184
          some_tx_waiting = 1;
185
 
186
      }
187
    }
188
 
189
}
190
 
191
 
192
void
193
ethphy_set_10mbit(int phynum)
194
{
195
  wait_until_all_tx_clear();
196
  // Hardset PHY to just use 10Mbit mode
197
  short cr = eth_mii_read(phynum, MII_BMCR);
198
  cr &= ~BMCR_ANENABLE; // Clear auto negotiate bit
199
  cr &= ~BMCR_SPEED100; // Clear fast eth. bit
200
  eth_mii_write(phynum, MII_BMCR, cr);
201
}
202
 
203
 
204
void
205
ethphy_set_100mbit(int phynum)
206
{
207
  wait_until_all_tx_clear();
208
  // Hardset PHY to just use 100Mbit mode
209
  short cr = eth_mii_read(phynum, MII_BMCR);
210
  cr |= BMCR_ANENABLE; // Clear auto negotiate bit
211
  cr |= BMCR_SPEED100; // Clear fast eth. bit
212
  eth_mii_write(phynum, MII_BMCR, cr);
213
}
214
 
215
 
216
void ethmac_setup(void)
217
{
218
  // from arch/or32/drivers/open_eth.c
219
  volatile oeth_regs *regs;
220
 
221
  regs = (oeth_regs *)(OETH_REG_BASE);
222
 
223
  /* Reset MII mode module */
224
  regs->miimoder = OETH_MIIMODER_RST; /* MII Reset ON */
225
  regs->miimoder &= ~OETH_MIIMODER_RST; /* MII Reset OFF */
226
  regs->miimoder = 0x64; /* Clock divider for MII Management interface */
227
 
228
  /* Reset the controller.
229
   */
230
  regs->moder = OETH_MODER_RST; /* Reset ON */
231
  regs->moder &= ~OETH_MODER_RST;       /* Reset OFF */
232
 
233
  /* Setting TXBD base to OETH_TXBD_NUM.
234
   */
235
  regs->tx_bd_num = OETH_TXBD_NUM;
236
 
237
 
238
  /* Set min/max packet length
239
   */
240
  regs->packet_len = 0x00400600;
241
 
242
  /* Set IPGT register to recomended value
243
   */
244
  regs->ipgt = 0x12;
245
 
246
  /* Set IPGR1 register to recomended value
247
   */
248
  regs->ipgr1 = 0x0000000c;
249
 
250
  /* Set IPGR2 register to recomended value
251
   */
252
  regs->ipgr2 = 0x00000012;
253
 
254
  /* Set COLLCONF register to recomended value
255
   */
256
  regs->collconf = 0x000f003f;
257
 
258
  /* Set control module mode
259
   */
260
#if 0
261
  regs->ctrlmoder = OETH_CTRLMODER_TXFLOW | OETH_CTRLMODER_RXFLOW;
262
#else
263
  regs->ctrlmoder = 0;
264
#endif
265
 
266
  /* Clear MIIM registers */
267
  regs->miitx_data = 0;
268
  regs->miiaddress = 0;
269
  regs->miicommand = 0;
270
 
271
  regs->mac_addr1 = ETH_MACADDR0 << 8 | ETH_MACADDR1;
272
  regs->mac_addr0 = ETH_MACADDR2 << 24 | ETH_MACADDR3 << 16 | ETH_MACADDR4 << 8 | ETH_MACADDR5;
273
 
274
  /* Clear all pending interrupts
275
   */
276
  regs->int_src = 0xffffffff;
277
 
278
  /* Promisc, IFG, CRCEn
279
   */
280
  regs->moder |= OETH_MODER_PRO | OETH_MODER_PAD | OETH_MODER_IFG | OETH_MODER_CRCEN | OETH_MODER_FULLD;
281
 
282
  /* Enable interrupt sources.
283
   */
284
 
285
  regs->int_mask = OETH_INT_MASK_TXB    |
286
    OETH_INT_MASK_TXE   |
287
    OETH_INT_MASK_RXF   |
288
    OETH_INT_MASK_RXE   |
289
    OETH_INT_MASK_BUSY  |
290
    OETH_INT_MASK_TXC   |
291
    OETH_INT_MASK_RXC;
292
 
293
  // Buffer setup stuff
294
  volatile oeth_bd *tx_bd, *rx_bd;
295
  int i,j,k;
296
 
297
  /* Initialize TXBD pointer
298
   */
299
  tx_bd = (volatile oeth_bd *)OETH_BD_BASE;
300
 
301
  /* Initialize RXBD pointer
302
   */
303
  rx_bd = ((volatile oeth_bd *)OETH_BD_BASE) + OETH_TXBD_NUM;
304
 
305
  /* Preallocated ethernet buffer setup */
306
  unsigned long mem_addr = ETH_BUFF_BASE; /* Defined at top */
307
 
308
 // Setup TX Buffers
309
  for(i = 0; i < OETH_TXBD_NUM; i++) {
310
      //tx_bd[i].len_status = OETH_TX_BD_PAD | OETH_TX_BD_CRC | OETH_RX_BD_IRQ;
311
      tx_bd[i].len_status = OETH_TX_BD_PAD | OETH_TX_BD_CRC;
312
      tx_bd[i].addr = mem_addr;
313
      mem_addr += OETH_TX_BUFF_SIZE;
314
  }
315
  tx_bd[OETH_TXBD_NUM - 1].len_status |= OETH_TX_BD_WRAP;
316
 
317
  // Setup RX buffers
318
  for(i = 0; i < OETH_RXBD_NUM; i++) {
319
    rx_bd[i].len_status = OETH_RX_BD_EMPTY | OETH_RX_BD_IRQ; // Init. with IRQ
320
    rx_bd[i].addr = mem_addr;
321
    mem_addr += OETH_RX_BUFF_SIZE;
322
  }
323
  rx_bd[OETH_RXBD_NUM - 1].len_status |= OETH_RX_BD_WRAP; // Last buffer wraps
324
 
325
  /* Enable JUST the transmiter
326
   */
327
  regs->moder &= ~(OETH_MODER_RXEN | OETH_MODER_TXEN);
328
  regs->moder |= /*OETH_MODER_RXEN |*/ OETH_MODER_TXEN;
329
 
330
  next_tx_buf_num = 0; // init tx buffer pointer
331
 
332
  return;
333
}
334
 
335
 
336
 
337
/* Setup buffer descriptors with data */
338
/* length is in BYTES */
339
void tx_packet(void* data, int length)
340
{
341
  volatile oeth_regs *regs;
342
  regs = (oeth_regs *)(OETH_REG_BASE);
343
 
344
  volatile oeth_bd *tx_bd;
345
  volatile int i;
346
 
347
   tx_bd = (volatile oeth_bd *)OETH_BD_BASE;
348
   tx_bd = (struct oeth_bd*) &tx_bd[next_tx_buf_num];
349
 
350
   // If it's in use - wait
351
   while ((tx_bd->len_status & OETH_TX_BD_IRQ));
352
 
353
   /* Clear all of the status flags.
354
   */
355
   tx_bd->len_status &= ~OETH_TX_BD_STATS;
356
 
357
  /* If the frame is short, tell CPM to pad it.
358
   */
359
  #define ETH_ZLEN        60   /* Min. octets in frame sans FCS */
360
  if (length <= ETH_ZLEN)
361
    tx_bd->len_status |= OETH_TX_BD_PAD;
362
  else
363
    tx_bd->len_status &= ~OETH_TX_BD_PAD;
364
 
365
#ifdef _ETH_RXTX_DATA_H_
366
  // Set the address pointer to the place
367
  // in memory where the data is and transmit from there
368
 
369
  tx_bd->addr = (char*) &tx_data_array[tx_data_pointer&~(0x3)];
370
 
371
  tx_data_pointer += length;
372
  if (tx_data_pointer > (255*1024))
373
    tx_data_pointer = 0;
374
 
375
 
376
#else
377
  if (data){
378
    //Copy the data into the transmit buffer, byte at a time 
379
    char* data_p = (char*) data;
380
    char* data_b = (char*) tx_bd->addr;
381
    for(i=0;i<length;i++)
382
      {
383
        data_b[i] = data_p[i];
384
      }
385
  }
386
#endif    
387
 
388
  /* Set the length of the packet's data in the buffer descriptor */
389
  tx_bd->len_status = (tx_bd->len_status & 0x0000ffff) |
390
    ((length&0xffff) << 16);
391
 
392
  /* Send it on its way.  Tell controller its ready, interrupt when sent
393
  * and to put the CRC on the end.
394
  */
395
  tx_bd->len_status |= (OETH_TX_BD_READY  | OETH_TX_BD_CRC | OETH_TX_BD_IRQ);
396
 
397
  next_tx_buf_num = (next_tx_buf_num + 1) & OETH_TXBD_NUM_MASK;
398
 
399
  return;
400
 
401
}
402
 
403
/* enable RX, loop waiting for arrived packets and print them out */
404
void oeth_monitor_rx(void)
405
{
406
  volatile oeth_regs *regs;
407
  regs = (oeth_regs *)(OETH_REG_BASE);
408
 
409
  /* Set RXEN in MAC MODER */
410
  regs->moder = OETH_MODER_RXEN | regs->moder;
411
 
412
 
413
  volatile oeth_bd *rx_bd;
414
  rx_bd = ((volatile oeth_bd *)OETH_BD_BASE) + OETH_TXBD_NUM;
415
 
416
  volatile int i;
417
 
418
  while (1)
419
    {
420
 
421
      for(i=0;i<OETH_RXBD_NUM;i++)
422
        {
423
          if (!(rx_bd[i].len_status & OETH_RX_BD_EMPTY)) /* Not empty */
424
            {
425
              // Something in this buffer!
426
              printk("Oeth: RX in buf %d - len_status: 0x%lx\n",i, rx_bd[i].len_status);
427
              /* Clear recieved bit */
428
              rx_bd[i].len_status |=  OETH_RX_BD_EMPTY;
429
              printk("\t end of packet\n\n");
430
            }
431
        }
432
    }
433
}
434
 
435
 
436
char broadcast_ping_packet[] =  {
437
  0xff,0xff,0xff,0xff,0xff,0xff, /*SRC MAC*/
438
  0x00, 0x12, 0x34, 0x56, 0x78, 0x9a, /*SRC MAC*/
439
  0x08,0x00,
440
  0x45,
441
  0x00,
442
  0x00,0x54,
443
  0x00,0x00,
444
  0x40,
445
  0x00,
446
  0x40,
447
  0x01,
448
  0xef,0xef,
449
  0xc0,0xa8,0x64,0x58, /* Source IP */
450
  0xc0,0xa8,0x64,0xff, /* Dest. IP */
451
  /* ICMP Message body */
452
  0x08,0x00,0x7d,0x65,0xa7,0x20,0x00,0x01,0x68,0x25,0xa5,0x4a,0xcf,0x05,0x0c,0x00,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37};
453
 
454
 
455
char big_broadcast_ping_packet[] =  {
456
  0xff,0xff,0xff,0xff,0xff,0xff, /*SRC MAC*/
457
  0x00, 0x12, 0x34, 0x56, 0x78, 0x9a, /*SRC MAC*/
458
  0x08,0x00,
459
  0x45,
460
  0x00,
461
  //  0x00,0x54, /* length */
462
  0x05,0x1c, /* length */
463
  0x00,0x00,
464
  0x40,
465
  0x00,
466
  0x40,
467
  0x01,
468
  0xee,0xf5,
469
  0xc0,0xa8,0x64,0x9b, /* Source IP */
470
  0xc0,0xa8,0x64,0xff, /* Dest. IP */
471
  /* ICMP Message body */
472
  0x08,0x00,0x7d,0x65,0xa7,0x20,0x00,0x01,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,
473
  15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,
474
  40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,
475
  65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,
476
  90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,
477
  111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,
478
  130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,
479
  149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,
480
  168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,
481
  187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,
482
  206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,
483
  225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,
484
  244,245,246,247,248,249,250,251,252,253,254,255,
485
  0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,
486
  15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,
487
  40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,
488
  65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,
489
  90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,
490
  111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,
491
  130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,
492
  149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,
493
  168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,
494
  187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,
495
  206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,
496
  225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,
497
  244,245,246,247,248,249,250,251,252,253,254,255,
498
  0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,
499
  15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,
500
  40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,
501
  65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,
502
  90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,
503
  111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,
504
  130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,
505
  149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,
506
  168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,
507
  187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,
508
  206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,
509
  225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,
510
  244,245,246,247,248,249,250,251,252,253,254,255,
511
  0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,
512
  15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,
513
  40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,
514
  65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,
515
  90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,
516
  111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,
517
  130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,
518
  149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,
519
  168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,
520
  187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,
521
  206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,
522
  225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,
523
  244,245,246,247,248,249,250,251,252,253,254,255,
524
  0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,
525
  15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,
526
  40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,
527
  65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,
528
  90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,
529
  111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,
530
  130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,
531
  149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,
532
  168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,
533
  187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,
534
  206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,
535
  225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,
536
  244,245,246,247,248,249,250,251,252,253,254,255};
537
 
538
 
539
  /* This should be 98 bytes big */
540
  char ping_packet[] = {
541
    0x00, 0x24, 0xe8, 0x91, 0x7c, 0x0d, /*DST MAC*/
542
    //0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /*DST MAC*/
543
    0x00, 0x12, 0x34, 0x56, 0x78, 0x9a, /*SRC MAC*/
544
    0x08, 0x00, /*TYPE*/
545
    /* IP */
546
    0x45, /* Version, header length*/
547
    0x00, /* Differentiated services field */
548
    0x00, 0x54, /* Total length */
549
    0x00, 0x00, /* Identification */
550
    0x40, /* Flags */
551
    0x00, /* Fragment offset */
552
    0x40, /* Time to live */
553
    0x01, /* Protocol (0x01 = ICMP */
554
    0xef, 0xf3, /* Header checksum */
555
    //0xc0, 0xa8, 0x64, 0xDE, /* Source IP */
556
    0xc0, 0xa8, 0x0, 0x58, /* Source IP */
557
    //0xa, 0x1, 0x1, 0x3, /* Source IP */
558
    0xc0, 0xa8, 0x64, 0x69, /* Dest. IP */
559
    0xc0, 0xa8, 0x0, 0xb, /* Dest. IP */
560
    //0xa, 0x1, 0x1, 0x1, /* Dest. IP */
561
    /* ICMP Message body */
562
    0x08, 0x00, 0x9a, 0xd4, 0xc8, 0x18, 0x00, 0x01, 0xd9, 0x8c, 0x54,
563
    0x4a, 0x7b, 0x37, 0x01, 0x00, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
564
    0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
565
    0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
566
    0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e,
567
    0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37
568
  };
569
 
570
 
571
/* The interrupt handler.
572
 */
573
void
574
oeth_interrupt(void)
575
{
576
 
577
  volatile oeth_regs *regs;
578
  regs = (oeth_regs *)(OETH_REG_BASE);
579
 
580
  uint  int_events;
581
  int serviced;
582
 
583
        serviced = 0;
584
 
585
        /* Get the interrupt events that caused us to be here.
586
         */
587
        int_events = regs->int_src;
588
        regs->int_src = int_events;
589
 
590
 
591
#ifndef RTLSIM
592
        printk(".");
593
 
594
        printk("\n=tx_ | %x | %x | %x | %x | %x | %x | %x | %x\n",
595
               ((oeth_bd *)(OETH_BD_BASE))->len_status,
596
               ((oeth_bd *)(OETH_BD_BASE+8))->len_status,
597
               ((oeth_bd *)(OETH_BD_BASE+16))->len_status,
598
               ((oeth_bd *)(OETH_BD_BASE+24))->len_status,
599
               ((oeth_bd *)(OETH_BD_BASE+32))->len_status,
600
               ((oeth_bd *)(OETH_BD_BASE+40))->len_status,
601
               ((oeth_bd *)(OETH_BD_BASE+48))->len_status,
602
               ((oeth_bd *)(OETH_BD_BASE+56))->len_status);
603
 
604
        printk("=rx_ | %x | %x | %x | %x | %x | %x | %x | %x\n",
605
               ((oeth_bd *)(OETH_BD_BASE+64))->len_status,
606
               ((oeth_bd *)(OETH_BD_BASE+64+8))->len_status,
607
               ((oeth_bd *)(OETH_BD_BASE+64+16))->len_status,
608
               ((oeth_bd *)(OETH_BD_BASE+64+24))->len_status,
609
               ((oeth_bd *)(OETH_BD_BASE+64+32))->len_status,
610
               ((oeth_bd *)(OETH_BD_BASE+64+40))->len_status,
611
               ((oeth_bd *)(OETH_BD_BASE+64+48))->len_status,
612
               ((oeth_bd *)(OETH_BD_BASE+64+56))->len_status);
613
 
614
        printk("=int | txb %d | txe %d | rxb %d | rxe %d | busy %d\n",
615
               (int_events & OETH_INT_TXB) > 0,
616
               (int_events & OETH_INT_TXE) > 0,
617
               (int_events & OETH_INT_RXF) > 0,
618
               (int_events & OETH_INT_RXE) > 0,
619
               (int_events & OETH_INT_BUSY) > 0);
620
#endif
621
 
622
 
623
 
624
        /* Handle receive event in its own function.
625
         */
626
        if (int_events & (OETH_INT_RXF | OETH_INT_RXE)) {
627
                serviced |= 0x1;
628
                oeth_rx();
629
        }
630
 
631
        /* Handle transmit event in its own function.
632
         */
633
        if (int_events & (OETH_INT_TXB | OETH_INT_TXE)) {
634
                serviced |= 0x2;
635
                oeth_tx();
636
                serviced |= 0x2;
637
 
638
        }
639
 
640
        /* Check for receive busy, i.e. packets coming but no place to
641
         * put them.
642
         */
643
        if (int_events & OETH_INT_BUSY) {
644
                serviced |= 0x4;
645
#ifndef RTLSIM
646
                printk("b");
647
#endif
648
                if (!(int_events & (OETH_INT_RXF | OETH_INT_RXE)))
649
                  oeth_rx();
650
        }
651
 
652
 
653
#if 0
654
        if (serviced == 0) {
655
                void die(const char * str, struct pt_regs * regs, long err);
656
                int show_stack(unsigned long *esp);
657
                printk("!");
658
//              printk("unserviced irq\n");
659
//              show_stack(NULL);
660
//              die("unserviced irq\n", regs, 801);
661
        }
662
#endif
663
 
664
        if (serviced == 0)
665
          printk("\neth interrupt called but nothing serviced\n");
666
 
667
        else /* Something happened ... either RX or TX */
668
          printk(" | serviced 0x%x\n", serviced);
669
 
670
        return;
671
}
672
 
673
 
674
 
675
static void
676
oeth_rx(void)
677
{
678
  volatile oeth_regs *regs;
679
  regs = (oeth_regs *)(OETH_REG_BASE);
680
 
681
  volatile oeth_bd *rx_bdp;
682
  int   pkt_len, i;
683
  int   bad = 0;
684
 
685
  rx_bdp = ((oeth_bd *)OETH_BD_BASE) + OETH_TXBD_NUM;
686
 
687
  printk("r");
688
 
689
 
690
  /* Find RX buffers marked as having received data */
691
  for(i = 0; i < OETH_RXBD_NUM; i++)
692
    {
693
      bad=0;
694
      if(!(rx_bdp[i].len_status & OETH_RX_BD_EMPTY)){ /* Looking for NOT empty buffers desc. */
695
        /* Check status for errors.
696
         */
697
        if (rx_bdp[i].len_status & (OETH_RX_BD_TOOLONG | OETH_RX_BD_SHORT)) {
698
          bad = 1;
699
          report(0xbaad0001);
700
        }
701
        if (rx_bdp[i].len_status & OETH_RX_BD_DRIBBLE) {
702
          bad = 1;
703
          report(0xbaad0002);
704
        }
705
        if (rx_bdp[i].len_status & OETH_RX_BD_CRCERR) {
706
          bad = 1;
707
          report(0xbaad0003);
708
        }
709
        if (rx_bdp[i].len_status & OETH_RX_BD_OVERRUN) {
710
          bad = 1;
711
          report(0xbaad0004);
712
        }
713
        if (rx_bdp[i].len_status & OETH_RX_BD_MISS) {
714
          report(0xbaad0005);
715
        }
716
        if (rx_bdp[i].len_status & OETH_RX_BD_LATECOL) {
717
          bad = 1;
718
          report(0xbaad0006);
719
        }
720
        if (bad) {
721
          rx_bdp[i].len_status &= ~OETH_RX_BD_STATS;
722
          rx_bdp[i].len_status |= OETH_RX_BD_EMPTY;
723
          exit(0xbaaaaaad);
724
 
725
          continue;
726
        }
727
        else {
728
          /* Process the incoming frame.
729
           */
730
          pkt_len = rx_bdp[i].len_status >> 16;
731
 
732
          /* Do something here with the data - copy it into userspace, perhaps*/
733
          printk("\t end of packet\n\n");
734
 
735
 
736
          /* finish up */
737
          rx_bdp[i].len_status &= ~OETH_RX_BD_STATS; /* Clear stats */
738
          rx_bdp[i].len_status |= OETH_RX_BD_EMPTY; /* Mark RX BD as empty */
739
          rx_done++;
740
        }
741
      }
742
    }
743
}
744
 
745
 
746
 
747
static void
748
oeth_tx(void)
749
{
750
  volatile oeth_bd *tx_bd;
751
  int i;
752
 
753
  tx_bd = (volatile oeth_bd *)OETH_BD_BASE; /* Search from beginning*/
754
 
755
  /* Go through the TX buffs, search for one that was just sent */
756
  for(i = 0; i < OETH_TXBD_NUM; i++)
757
    {
758
      /* Looking for buffer NOT ready for transmit. and IRQ enabled */
759
      if( (!(tx_bd[i].len_status & (OETH_TX_BD_READY))) && (tx_bd[i].len_status & (OETH_TX_BD_IRQ)) )
760
        {
761
          /* Single threaded so no chance we have detected a buffer that has had its IRQ bit set but not its BD_READ flag. Maybe this won't work in linux */
762
          tx_bd[i].len_status &= ~OETH_TX_BD_IRQ;
763
 
764
          /* Probably good to check for TX errors here */
765
 
766
          /* set our test variable */
767
          tx_done++;
768
 
769
          printk("T%d",i);
770
 
771
        }
772
    }
773
  return;
774
}
775
 
776
// A function and defines to fill and transmit a packet
777
#define MAX_TX_BUFFER 1532
778
static char tx_buffer[MAX_TX_BUFFER];
779
static unsigned long tx_data = 0x2ef2e242;
780
static inline char gen_next_tx_byte(void)
781
{
782
  // Bit of LFSR action
783
  tx_data = ((~(((((tx_data&(1<<25))>>25)^((tx_data&(1<<13))>>13))^((tx_data&(1<<2))>>2)))&0x01) | (tx_data<<1));
784
  //tx_data++;
785
  return (char) tx_data & 0xff;
786
}
787
 
788
void
789
fill_and_tx_packet(int size)
790
{
791
  int i;
792
  char tx_byte;
793
 
794
 
795
  volatile oeth_regs *regs;
796
  regs = (oeth_regs *)(OETH_REG_BASE);
797
 
798
  volatile oeth_bd *tx_bd;
799
 
800
  tx_bd = (volatile oeth_bd *)OETH_BD_BASE;
801
  tx_bd = (struct oeth_bd*) &tx_bd[next_tx_buf_num];
802
 
803
 
804
  // If it's in use - wait
805
  while ((tx_bd->len_status & OETH_TX_BD_IRQ));
806
 
807
#ifndef _ETH_RXTX_DATA_H_  
808
  /* Copy the data into the transmit buffer, byte at a time */
809
  char* data_b = (char*) tx_bd->addr;
810
  for(i=0;i<size;i++)
811
    {
812
      data_b[i] = gen_next_tx_byte();
813
    }
814
#endif
815
 
816
   tx_packet((void*)0, size);
817
}
818
 
819
//#define WAIT_PACKET_TX(x) while(tx_done<x)
820
#define WAIT_PACKET_TX(x)
821
 
822
int main ()
823
{
824
  tx_data_pointer = 0;
825
 
826
  /* Initialise handler vector */
827
  int_init();
828
 
829
  /* Install ethernet interrupt handler, it is enabled here too */
830
  int_add(ETH0_IRQ, oeth_interrupt, 0);
831
 
832
  /* Enable interrupts in supervisor register */
833
  mtspr (SPR_SR, mfspr (SPR_SR) | SPR_SR_IEE);
834
 
835
  ethmac_setup(); /* Configure MAC, TX/RX BDs and enable RX and TX in MODER */
836
 
837
  /* clear tx_done, the tx interrupt handler will set it when it's been transmitted */
838
  tx_done = 0;
839
  rx_done = 0;
840
 
841
  int i;
842
  ethphy_set_100mbit(0);
843
 
844
#ifndef ETH_TX_TEST_LENGTH
845
# define ETH_TX_TEST_LENGTH  128
846
  //# define ETH_TX_TEST_LENGTH  OETH_TX_BUFF_SIZE
847
#endif
848
 
849
  for(i=5;i<ETH_TX_TEST_LENGTH;i+=1)
850
    fill_and_tx_packet(i);
851
 
852
  ethphy_set_10mbit(0);
853
  for(i=5;i<ETH_TX_TEST_LENGTH;i+=1)
854
    fill_and_tx_packet(i);
855
 
856
  exit(0x8000000d);
857
 
858
 
859
}

powered by: WebSVN 2.1.0

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