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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [orpsocv2/] [sw/] [tests/] [ethmac/] [board/] [ethmac-ping.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 test code for use on board    ////
4
////                                                              ////
5
////  Description                                                 ////
6
////  Controllable ping program - also responds to ARP requests   ////
7
////                                                              ////
8
////  Author(s):                                                  ////
9
////      - jb, jb@orsoc.se, with parts taken from Linux kernel   ////
10
////        open_eth driver.                                      ////
11
////                                                              ////
12
////                                                              ////
13
//////////////////////////////////////////////////////////////////////
14
////                                                              ////
15
//// Copyright (C) 2009 Authors and OPENCORES.ORG                 ////
16
////                                                              ////
17
//// This source file may be used and distributed without         ////
18
//// restriction provided that this copyright statement is not    ////
19
//// removed from the file and that any derivative work contains  ////
20
//// the original copyright notice and the associated disclaimer. ////
21
////                                                              ////
22
//// This source file is free software; you can redistribute it   ////
23
//// and/or modify it under the terms of the GNU Lesser General   ////
24
//// Public License as published by the Free Software Foundation; ////
25
//// either version 2.1 of the License, or (at your option) any   ////
26
//// later version.                                               ////
27
////                                                              ////
28
//// This source is distributed in the hope that it will be       ////
29
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
30
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
31
//// PURPOSE.  See the GNU Lesser General Public License for more ////
32
//// details.                                                     ////
33
////                                                              ////
34
//// You should have received a copy of the GNU Lesser General    ////
35
//// Public License along with this source; if not, download it   ////
36
//// from http://www.opencores.org/lgpl.shtml                     ////
37
////                                                              ////
38
//////////////////////////////////////////////////////////////////////
39
 
40 408 julius
#include "cpu-utils.h"
41
//#include "spr-defs.h"
42 349 julius
#include "board.h"
43
#include "int.h"
44
#include "uart.h"
45 409 julius
#include "ethmac.h"
46 349 julius
#include "printf.h"
47
#include "eth-phy-mii.h"
48
 
49
volatile unsigned tx_done;
50
static int next_tx_buf_num;
51
 
52
//#define OUR_IP_BYTES 0xc0,0xa8,0x64,0x9b // 192.168.100.155
53
//#define OUR_IP_LONG 0xc0a8649b
54
 
55 408 julius
//#define OUR_IP_BYTES 0xc0,0xa8,0x0,0x14 // 192.168.0.20
56
//#define OUR_IP_LONG 0xc0a80014
57
 
58
#define OUR_IP_BYTES 0xc0,0xa8,0x1,0x2 // 192.168.1.2
59
#define OUR_IP_LONG 0xc0a80102
60
 
61 349 julius
static char our_ip[4] = {OUR_IP_BYTES};
62
 
63
//#define DEST_IP_BYTES 0xc0,0xa8,0x64,0x69 // 192 .168.100.105
64
#define DEST_IP_BYTES 0xc0,0xa8,0x01,0x08 // 192 .168.1.8
65
 
66
/* Functions in this file */
67
void ethmac_setup(void);
68
void oeth_printregs(void);
69
void ethphy_init(void);
70
void oeth_dump_bds();
71
/* Interrupt functions */
72
void oeth_interrupt(void);
73
static void oeth_rx(void);
74
static void oeth_tx(void);
75
 
76
#define NEVER_PRINT_PACKET 1
77
 
78
#define DISABLE_PRINTF 0
79
 
80
#if DISABLE_PRINTF==1
81
#undef printf 
82
#endif
83
/* Let the ethernet packets use a space beginning here for buffering */
84
#define ETH_BUFF_BASE 0x01000000
85
 
86
 
87
#define RXBUFF_PREALLOC 1
88
#define TXBUFF_PREALLOC 1
89
//#undef RXBUFF_PREALLOC
90
//#undef TXBUFF_PREALLOC
91
 
92
/* The transmitter timeout
93
*/
94
#define TX_TIMEOUT      (2*HZ)
95
 
96
/* Buffer number (must be 2^n)
97
*/
98
#define OETH_RXBD_NUM           8
99
#define OETH_TXBD_NUM           8
100
#define OETH_RXBD_NUM_MASK      (OETH_RXBD_NUM-1)
101
#define OETH_TXBD_NUM_MASK      (OETH_TXBD_NUM-1)
102
 
103
/* Buffer size
104
*/
105
#define OETH_RX_BUFF_SIZE       2048
106
#define OETH_TX_BUFF_SIZE       2048
107
 
108
/* OR32 Page size def */
109
#define PAGE_SHIFT              13
110
#define PAGE_SIZE               (1UL << PAGE_SHIFT)
111
 
112
/* How many buffers per page
113
*/
114
#define OETH_RX_BUFF_PPGAE      (PAGE_SIZE/OETH_RX_BUFF_SIZE)
115
#define OETH_TX_BUFF_PPGAE      (PAGE_SIZE/OETH_TX_BUFF_SIZE)
116
 
117
/* How many pages is needed for buffers
118
*/
119
#define OETH_RX_BUFF_PAGE_NUM   (OETH_RXBD_NUM/OETH_RX_BUFF_PPGAE)
120
#define OETH_TX_BUFF_PAGE_NUM   (OETH_TXBD_NUM/OETH_TX_BUFF_PPGAE)
121
 
122
/* Buffer size  (if not XXBUF_PREALLOC
123
*/
124
#define MAX_FRAME_SIZE          0x600
125
//#define MAX_FRAME_SIZE                2500
126
 
127
/* The buffer descriptors track the ring buffers.
128
*/
129
struct oeth_private {
130
  //struct      sk_buff* rx_skbuff[OETH_RXBD_NUM];
131
  //struct      sk_buff* tx_skbuff[OETH_TXBD_NUM];
132
 
133
  unsigned short        tx_next;/* Next buffer to be sent */
134
  unsigned short        tx_last;/* Next buffer to be checked if packet sent */
135
  unsigned short        tx_full;/* Buffer ring fuul indicator */
136
  unsigned short        rx_cur; /* Next buffer to be checked if packet received */
137
 
138
  oeth_regs     *regs;                  /* Address of controller registers. */
139
  oeth_bd               *rx_bd_base;            /* Address of Rx BDs. */
140
  oeth_bd               *tx_bd_base;            /* Address of Tx BDs. */
141
 
142
  //    struct net_device_stats stats;
143
};
144
 
145
 
146
void oeth_printregs(void)
147
{
148
  volatile oeth_regs *regs;
149
  regs = (oeth_regs *)(OETH_REG_BASE);
150
 
151
  printf("Oeth regs: Mode Register : 0x%lx\n",
152
         (unsigned long) regs->moder);          /* Mode Register */
153
  printf("Oeth regs: Interrupt Source Register 0x%lx\n",
154
         (unsigned long) regs->int_src);        /* Interrupt Source Register */
155
  printf("Oeth regs: Interrupt Mask Register 0x%lx\n",
156
         (unsigned long) regs->int_mask);       /* Interrupt Mask Register */
157
  printf("Oeth regs: Back to Bak Inter Packet Gap Register 0x%lx\n",
158
         (unsigned long) regs->ipgt);           /* Back to Bak Inter Packet Gap Register */
159
  printf("Oeth regs: Non Back to Back Inter Packet Gap Register 1 0x%lx\n",
160
         (unsigned long) regs->ipgr1);          /* Non Back to Back Inter Packet Gap Register 1 */
161
  printf("Oeth regs: Non Back to Back Inter Packet Gap Register 2 0x%lx\n",
162
         (unsigned long) regs->ipgr2);          /* Non Back to Back Inter Packet Gap Register 2 */
163
  printf("Oeth regs: Packet Length Register (min. and max.) 0x%lx\n",
164
         (unsigned long) regs->packet_len);     /* Packet Length Register (min. and max.) */
165
  printf("Oeth regs: Collision and Retry Configuration Register 0x%lx\n",
166
         (unsigned long) regs->collconf);       /* Collision and Retry Configuration Register */
167
  printf("Oeth regs: Transmit Buffer Descriptor Number Register 0x%lx\n",
168
         (unsigned long) regs->tx_bd_num);      /* Transmit Buffer Descriptor Number Register */
169
  printf("Oeth regs: Control Module Mode Register 0x%lx\n",
170
         (unsigned long) regs->ctrlmoder);      /* Control Module Mode Register */
171
  printf("Oeth regs: MII Mode Register 0x%lx\n",
172
         (unsigned long) regs->miimoder);       /* MII Mode Register */
173
  printf("Oeth regs: MII Command Register 0x%lx\n",
174
         (unsigned long) regs->miicommand);     /* MII Command Register */
175
  printf("Oeth regs: MII Address Register 0x%lx\n",
176
         (unsigned long) regs->miiaddress);     /* MII Address Register */
177
  printf("Oeth regs: MII Transmit Data Register 0x%lx\n",
178
         (unsigned long) regs->miitx_data);     /* MII Transmit Data Register */
179
  printf("Oeth regs: MII Receive Data Register 0x%lx\n",
180
         (unsigned long) regs->miirx_data);     /* MII Receive Data Register */
181
  printf("Oeth regs: MII Status Register 0x%lx\n",
182
         (unsigned long) regs->miistatus);      /* MII Status Register */
183
  printf("Oeth regs: MAC Individual Address Register 0 0x%lx\n",
184
         (unsigned long) regs->mac_addr0);      /* MAC Individual Address Register 0 */
185
  printf("Oeth regs: MAC Individual Address Register 1 0x%lx\n",
186
         (unsigned long) regs->mac_addr1);      /* MAC Individual Address Register 1 */
187
  printf("Oeth regs: Hash Register 0 0x%lx\n",
188
         (unsigned long) regs->hash_addr0);     /* Hash Register 0 */
189
  printf("Oeth regs: Hash Register 1  0x%lx\n",
190
         (unsigned long) regs->hash_addr1);     /* Hash Register 1 */
191
 
192
}
193
 
194
static int last_char;
195
 
196
void spin_cursor(void)
197
{
198
#ifdef RTLSIM
199
  return;
200
#endif
201
  volatile unsigned int i; // So the loop doesn't get optimised away
202
  printf(" \r");
203
  if (last_char == 0)
204
    printf("/");
205
  else if (last_char == 1)
206
    printf("-");
207
  else if (last_char == 2)
208
    printf("\\");
209
  else if (last_char == 3)
210
    printf("|");
211
  else if (last_char == 4)
212
    printf("/");
213
  else if (last_char == 5)
214
    printf("-");
215
  else if (last_char == 6)
216
    printf("\\");
217
  else if (last_char == 7)
218
    {
219
      printf("|");
220
      last_char=-1;
221
    }
222
 
223
  last_char++;
224
 
225
  for(i=0;i<150000;i++);
226
 
227
}
228
 
229
#define PHYNUM 7
230
 
231
/* Scan the MIIM bus for PHYs */
232
void scan_ethphys(void)
233
{
234
  unsigned int phynum,regnum, i;
235
 
236
  volatile oeth_regs *regs;
237
  regs = (oeth_regs *)(OETH_REG_BASE);
238
 
239
  regs->miitx_data = 0;
240
 
241
  for(phynum=0;phynum<32;phynum++)
242
    {
243
      for (regnum=0;regnum<8;regnum++)
244
        {
245
          printf("scan_ethphys: phy %d r%d ",phynum, regnum);
246
 
247
          /* Now actually perform the read on the MIIM bus*/
248
          regs->miiaddress = (regnum << 8) | phynum; /* Basic Control Register */
249
          regs->miicommand = OETH_MIICOMMAND_RSTAT;
250
 
251
          while(!(regs->miistatus & OETH_MIISTATUS_BUSY)); /* Wait for command to be registered*/
252
 
253
          regs->miicommand = 0;
254
 
255
          while(regs->miistatus & OETH_MIISTATUS_BUSY);
256
 
257
          printf("%x\n",regs->miirx_data);
258
        }
259
    }
260
}
261
 
262
 
263
/* Scan the MIIM bus for PHYs */
264
void scan_ethphy(unsigned int phynum)
265
{
266
  unsigned int regnum, i;
267
 
268
  volatile oeth_regs *regs;
269
  regs = (oeth_regs *)(OETH_REG_BASE);
270
 
271
  regs->miitx_data = 0;
272
 
273
  for (regnum=0;regnum<29;regnum++)
274
    {
275
      printf("scan_ethphy%d: r%x ",phynum, regnum);
276
 
277
      /* Now actually perform the read on the MIIM bus*/
278
      regs->miiaddress = (regnum << 8) | phynum; /* Basic Control Register */
279
      regs->miicommand = OETH_MIICOMMAND_RSTAT;
280
 
281
      while(!(regs->miistatus & OETH_MIISTATUS_BUSY)); /* Wait for command to be registered*/
282
 
283
      regs->miicommand = 0;
284
 
285
      while(regs->miistatus & OETH_MIISTATUS_BUSY);
286
 
287
      printf("%x\n",regs->miirx_data);
288
    }
289
 
290
}
291
 
292
 
293
 
294
void ethmac_scanstatus(void)
295
{
296
  volatile oeth_regs *regs;
297
  regs = (oeth_regs *)(OETH_REG_BASE);
298
 
299
 
300
  printf("Oeth: regs->miistatus %x regs->miirx_data %x\n",regs->miistatus, regs->miirx_data);
301
  regs->miiaddress = 0;
302
  regs->miitx_data = 0;
303
  regs->miicommand = OETH_MIICOMMAND_SCANSTAT;
304
  printf("Oeth: regs->miiaddress %x regs->miicommand %x\n",regs->miiaddress, regs->miicommand);
305
  //regs->miicommand = 0; 
306
  volatile int i; for(i=0;i<1000;i++);
307
  while(regs->miistatus & OETH_MIISTATUS_BUSY) ;
308
  //spin_cursor(); 
309
  //printf("\r"); 
310
  //or32_exit(0);
311
}
312
 
313
void
314
eth_mii_write(char phynum, short regnum, short data)
315
{
316
  static volatile oeth_regs *regs = (oeth_regs *)(OETH_REG_BASE);
317
  regs->miiaddress = (regnum << 8) | phynum;
318
  regs->miitx_data = data;
319
  regs->miicommand = OETH_MIICOMMAND_WCTRLDATA;
320
  regs->miicommand = 0;
321
  while(regs->miistatus & OETH_MIISTATUS_BUSY);
322
}
323
 
324
short
325
eth_mii_read(char phynum, short regnum)
326
{
327
  static volatile oeth_regs *regs = (oeth_regs *)(OETH_REG_BASE);
328
  regs->miiaddress = (regnum << 8) | phynum;
329
  regs->miicommand = OETH_MIICOMMAND_RSTAT;
330
  regs->miicommand = 0;
331
  while(regs->miistatus & OETH_MIISTATUS_BUSY);
332
 
333
  return regs->miirx_data;
334
}
335
 
336
 
337
void
338
ethphy_reset(int phynum)
339
{
340
  eth_mii_write(phynum, MII_BMCR,
341
                (eth_mii_read(phynum,MII_BMCR)|BMCR_RESET));
342
}
343
 
344
 
345
void
346
ethphy_reneg(int phynum)
347
{
348
  eth_mii_write(phynum, MII_BMCR,
349
                (eth_mii_read(phynum,MII_BMCR)|BMCR_ANRESTART));
350
}
351
 
352
void
353
ethphy_set_10mbit(int phynum)
354
{
355
  // Hardset PHY to just use 10Mbit mode
356
  short cr = eth_mii_read(phynum, MII_BMCR);
357
  cr &= ~BMCR_ANENABLE; // Clear auto negotiate bit
358
  cr &= ~BMCR_SPEED100; // Clear fast eth. bit
359
  eth_mii_write(phynum, MII_BMCR, cr);
360
}
361
 
362
void
363
ethphy_set_100mbit(int phynum)
364
{
365
  // Hardset PHY to just use 10Mbit mode
366
  short cr = eth_mii_read(phynum, MII_BMCR);
367
  cr &= !BMCR_ANENABLE; // Clear auto negotiate bit
368
  cr |= BMCR_SPEED100; // Clear fast eth. bit
369
  eth_mii_write(phynum, MII_BMCR, cr);
370
}
371
 
372
void
373
ethphy_set_autoneg(int phynum)
374
{
375
  // Hardset PHY to just use 10Mbit mode
376
  short cr = eth_mii_read(phynum, MII_BMCR);
377
  cr |= BMCR_ANENABLE; // Clear auto negotiate bit
378
  eth_mii_write(phynum, MII_BMCR, cr);
379
}
380
 
381
 
382
 
383
void m88e111_config_init(int phyaddr)
384
{
385
  short ctl;
386
  short adv;
387
#if 1
388
  // Soft reset
389
  eth_mii_write(phyaddr, MII_BMCR, BMCR_RESET);
390
  while(eth_mii_read(phyaddr, MII_BMCR) & BMCR_RESET);
391
 
392
  ctl = eth_mii_read(phyaddr, MII_BMCR);
393
  ctl &= ~(BMCR_SPD2);
394
  eth_mii_write(phyaddr, MII_BMCR, ctl);
395
 
396
  eth_mii_read(phyaddr, MII_ADVERTISE);
397
  adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_1000XFULL
398
           |ADVERTISE_1000XHALF | ADVERTISE_1000XPAUSE |
399
           ADVERTISE_1000XPSE_ASYM);
400
  adv |= ADVERTISE_10HALF;
401
  adv |= ADVERTISE_10FULL;
402
  adv |= ADVERTISE_100HALF;
403
  adv |= ADVERTISE_100FULL;
404
  eth_mii_write(phyaddr, MII_ADVERTISE, adv);
405
  // Disable gigabit???
406
  adv = eth_mii_read(phyaddr, MII_M1011_PHY_SPEC_CONTROL);
407
  adv &= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP |
408
           MII_1000BASETCONTROL_HALFDUPLEXCAP);
409
  eth_mii_write(phyaddr, MII_M1011_PHY_SPEC_CONTROL, adv);
410
  // Even more disable gigabit?!
411
  adv = eth_mii_read(phyaddr, MII_CTRL1000);
412
  adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
413
  eth_mii_write(phyaddr, MII_CTRL1000, adv);
414
 
415
  // Restart autoneg
416
  printf("Resetting phy...\n");
417
  eth_mii_write(phyaddr, MII_BMCR, BMCR_RESET);
418
  ctl = eth_mii_read(phyaddr, MII_BMCR);
419
  ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
420
  eth_mii_write(phyaddr, MII_BMCR, ctl);
421
#endif
422
 
423
#if 0
424
  // Adapted from kernel: drivers/net/phy/marvell.c
425
  // Soft reset
426
  eth_mii_write(phyaddr, MII_BMCR, BMCR_RESET);
427
 
428
  eth_mii_write(phyaddr, 0x1d, 0x1f);
429
  eth_mii_write(phyaddr, 0x1e, 0x200c);
430
  eth_mii_write(phyaddr, 0x1d, 0x5);
431
  eth_mii_write(phyaddr, 0x1e, 0);
432
  eth_mii_write(phyaddr, 0x1e, 0x100);
433
#define MII_M1011_PHY_SCR               0x10
434
#define MII_M1011_PHY_SCR_AUTO_CROSS    0x0060
435
  eth_mii_write(phyaddr, MII_M1011_PHY_SCR,
436
                MII_M1011_PHY_SCR_AUTO_CROSS);
437
#define MII_M1111_PHY_LED_CONTROL       0x18
438
#define MII_M1111_PHY_LED_DIRECT        0x4100
439
  eth_mii_write(phyaddr, MII_M1111_PHY_LED_CONTROL,
440
                MII_M1111_PHY_LED_DIRECT);
441
 
442
  adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP |
443
           ADVERTISE_PAUSE_ASYM);
444
  adv |= ADVERTISE_10HALF;
445
  adv |= ADVERTISE_10FULL;
446
  adv |= ADVERTISE_100HALF;
447
  adv |= ADVERTISE_100FULL;
448
  adv |= ADVERTISE_PAUSE_CAP;
449
  adv |= ADVERTISE_PAUSE_ASYM;
450
  eth_mii_write(phyaddr, MII_ADVERTISE, adv);
451
 
452
 
453
  ctl = eth_mii_read(phyaddr, MII_BMCR);
454
  ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
455
  eth_mii_write(phyaddr, MII_BMCR, ctl);
456
 
457
#endif
458
 
459
#if 0
460
  ctl = eth_mii_read(phyaddr, MII_BMCR);
461
  ctl &= ~(BMCR_ANENABLE); // Disable autoneg...
462
  // Try forcing config
463
  ctl = BMCR_SPEED100 | BMCR_FULLDPLX;
464
  eth_mii_write(phyaddr, MII_BMCR, ctl);
465
 
466
 
467
 
468
 
469
#endif
470
 
471
}
472
 
473
 
474
void ethphy_print_status(int phyaddr)
475
{
476
  short regnum, ctl;
477
  int bitnum;
478
  int bitset;
479
  printf("phyaddr %d\n",phyaddr);
480
  for  (regnum = 0;regnum<16; regnum++)
481
    {
482
      ctl = eth_mii_read(phyaddr, regnum);
483
      printf("\treg 0x%x: ", regnum);
484
      switch(regnum)
485
        {
486
        case 0:
487
          printf("basic control\n");
488
          for(bitnum = 0; bitnum<16;bitnum++)
489
            {
490
              bitset = !!(ctl & (1<<bitnum));
491
              switch(bitnum)
492
                {
493
                case 0:
494
                  printf("\t\tbit%d:\t%d \t(disable transmitter)\n",bitnum,bitset);
495
                  break;
496
                case 6:
497
                  printf("\t\tbit%d:\t%d \t(msb speed (1000))\n",bitnum,bitset);
498
                  break;
499
                case 7:
500
                  printf("\t\tbit%d:\t%d \t(collision test)\n",bitnum,bitset);
501
                  break;
502
                case 8:
503
                  printf("\t\tbit%d:\t%d \t(duplex mode)\n",bitnum,bitset);
504
                  break;
505
                case 9:
506
                  printf("\t\tbit%d:\t%d \t(restart autoneg)\n",bitnum,bitset);
507
                  break;
508
                case 10:
509
                  printf("\t\tbit%d:\t%d \t(isloate)\n",bitnum,bitset);
510
                  break;
511
                case 11:
512
                  printf("\t\tbit%d:\t%d \t(power down)\n",bitnum,bitset);
513
                  break;
514
                case 12:
515
                  printf("\t\tbit%d:\t%d \t(autoneg enable)\n",bitnum,bitset);
516
                  break;
517
                case 13:
518
                  printf("\t\tbit%d:\t%d \t(speed select)\n",bitnum,bitset);
519
                  break;
520
                case 14:
521
                  printf("\t\tbit%d:\t%d \t(loop back)\n",bitnum,bitset);
522
                  break;
523
                case 15:
524
                  printf("\t\tbit%d:\t%d \t(reset)\n",bitnum,bitset);
525
                  break;
526
                default:
527
                  break;
528
                }
529
            }
530
          break;
531
        case 1:
532
          printf("basic status\n");
533
          for(bitnum = 0; bitnum<16;bitnum++)
534
            {
535
              bitset = !!(ctl & (1<<bitnum));
536
              switch(bitnum)
537
                {
538
                case 0:
539
                  printf("\t\tbit%d:\t%d \t(extend capability)\n",bitnum,bitset);
540
                  break;
541
                case 1:
542
                  printf("\t\tbit%d:\t%d \t(jabber detect)\n",bitnum,bitset);
543
                  break;
544
                case 2:
545
                  printf("\t\tbit%d:\t%d \t(link status)\n",bitnum,bitset);
546
                  break;
547
                case 3:
548
                  printf("\t\tbit%d:\t%d \t(autoneg capability)\n",bitnum,bitset);
549
                  break;
550
                case 4:
551
                  printf("\t\tbit%d:\t%d \t(remote fault)\n",bitnum,bitset);
552
                  break;
553
                case 5:
554
                  printf("\t\tbit%d:\t%d \t(autoneg complete)\n",bitnum,bitset);
555
                  break;
556
                case 6:
557
                  printf("\t\tbit%d:\t%d \t(no preamble)\n",bitnum,bitset);
558
                  break;
559
                case 11:
560
                  printf("\t\tbit%d:\t%d \t(10base-t half dup.)\n",bitnum,bitset);
561
                  break;
562
                case 12:
563
                  printf("\t\tbit%d:\t%d \t(10base-t full dup.)\n",bitnum,bitset);
564
                  break;
565
                case 13:
566
                  printf("\t\tbit%d:\t%d \t(100base-t half dup.)\n",bitnum,bitset);
567
                  break;
568
                case 14:
569
                  printf("\t\tbit%d:\t%d \t(100base-t full dup.)\n",bitnum,bitset);
570
                  break;
571
                case 15:
572
                  printf("\t\tbit%d:\t%d \t(100base-t4)\n",bitnum,bitset);
573
                  break;
574
                default:
575
                  break;
576
 
577
                }
578
            }
579
          break;
580
        case 4:
581
          printf("autoneg advertise reg\n");
582
          for(bitnum = 0; bitnum<16;bitnum++)
583
            {
584
              bitset = !!(ctl & (1<<bitnum));
585
              switch(bitnum)
586
                {
587
                case 5:
588
                  printf("\t\tbit%d:\t%d \t(10mbps cap.)\n",bitnum,bitset);
589
                  break;
590
                case 6:
591
                  printf("\t\tbit%d:\t%d \t(10base-5 full dup. cap.)\n",bitnum,bitset);
592
                  break;
593
                case 7:
594
                  printf("\t\tbit%d:\t%d \t(100base-tx cap.)\n",bitnum,bitset);
595
                  break;
596
                case 8:
597
                  printf("\t\tbit%d:\t%d \t(100base-tx full dup. cap.)\n",bitnum,bitset);
598
                  break;
599
                case 9:
600
                  printf("\t\tbit%d:\t%d \t(100base-t4 cap.)\n",bitnum,bitset);
601
                  break;
602
                case 10:
603
                  printf("\t\tbit%d:\t%d \t(pause cap.)\n",bitnum,bitset);
604
                  break;
605
                case 13:
606
                  printf("\t\tbit%d:\t%d \t(remote fault sup.)\n",bitnum,bitset);
607
                  break;
608
                case 15:
609
                  printf("\t\tbit%d:\t%d \t(next page cap.)\n",bitnum,bitset);
610
                  break;
611
 
612
                default:
613
                  break;
614
                }
615
            }
616
          break;
617
        case 5:
618
          printf("autoneg link partner ability\n");
619
          for(bitnum = 0; bitnum<16;bitnum++)
620
            {
621
              bitset = !!(ctl & (1<<bitnum));
622
              switch(bitnum)
623
                {
624
                case 5:
625
                  printf("\t\tbit%d:\t%d \t(10mbps cap.)\n",bitnum,bitset);
626
                  break;
627
                case 6:
628
                  printf("\t\tbit%d:\t%d \t(10base-5 full dup. cap.)\n",bitnum,bitset);
629
                  break;
630
                case 7:
631
                  printf("\t\tbit%d:\t%d \t(100base-tx cap.)\n",bitnum,bitset);
632
                  break;
633
                case 8:
634
                  printf("\t\tbit%d:\t%d \t(100base-tx full dup. cap.)\n",bitnum,bitset);
635
                  break;
636
                case 9:
637
                  printf("\t\tbit%d:\t%d \t(100base-t4 cap.)\n",bitnum,bitset);
638
                  break;
639
                case 10:
640
                  printf("\t\tbit%d:\t%d \t(pause cap bit0)\n",bitnum,bitset);
641
                  break;
642
                case 11:
643
                  printf("\t\tbit%d:\t%d \t(pause cap bit1)\n",bitnum,bitset);
644
                  break;
645
 
646
                case 13:
647
                  printf("\t\tbit%d:\t%d \t(remote fault sup.)\n",bitnum,bitset);
648
                  break;
649
                case 14:
650
                  printf("\t\tbit%d:\t%d \t(acknowledge)\n",bitnum,bitset);
651
                  break;
652
                case 15:
653
                  printf("\t\tbit%d:\t%d \t(next page cap.)\n",bitnum,bitset);
654
                  break;
655
 
656
                default:
657
                  break;
658
                }
659
            }
660
          break;
661
        case 9:
662
          printf("1000mbit advertise\n");
663
          for(bitnum = 0; bitnum<16;bitnum++)
664
            {
665
              bitset = !!(ctl & (1<<bitnum));
666
              switch(bitnum)
667
                {
668
                case 8:
669
                  printf("\t\tbit%d:\t%d \t(1000base-t half dup)\n",bitnum,bitset);
670
                  break;
671
                case 9:
672
                  printf("\t\tbit%d:\t%d \t(1000base-t full dup)\n",bitnum,bitset);
673
                  break;
674
                default:
675
                  break;
676
                }
677
            }
678
          break;
679
        case 0xf:
680
          printf("extended status\n");
681
          for(bitnum = 0; bitnum<16;bitnum++)
682
            {
683
              bitset = !!(ctl & (1<<bitnum));
684
              switch(bitnum)
685
                {
686
                case 12:
687
                  printf("\t\tbit%d:\t%d \t(1000mb half dup.)\n",bitnum,bitset);
688
                  break;
689
                case 13:
690
                  printf("\t\tbit%d:\t%d \t(1000mb full dup.)\n",bitnum,bitset);
691
                  break;
692
                default:
693
                  break;
694
                }
695
            }
696
          break;
697
          /*    case 1:
698
          for(bitnum = 0; bitnum<16;bitnum++)
699
          {
700
          bitset = !!(ctl & (1<<bitnum));
701
          switch(bitnum)
702
          {
703
          case 0:
704
          printf("\t\tbit%d:\t%d \t()\n",bitnum,bitset);
705
          break;
706
          default:
707
          break;
708
          }
709
          }
710
          break;
711
          */
712
        default:
713
          printf("ignored\n");
714
          break;
715
        }
716
    }
717
 
718
 
719
 
720
}
721
 
722
void ethphy_init(void)
723
{
724
 
725
  /* Init the Alaska 88E1111 Phy */
726
  char alaska88e1111_ml501_phynum = 0x7;
727
  m88e111_config_init(alaska88e1111_ml501_phynum);
728
 
729
  return;
730
 
731
  /* Init, reset */
732
  short ctl = eth_mii_read(alaska88e1111_ml501_phynum, MII_BMCR);
733
  ctl &= ~(BMCR_FULLDPLX|BMCR_SPEED100|BMCR_SPD2|BMCR_ANENABLE);
734
  ctl |= BMCR_SPEED100; // 100MBit
735
  ctl |= BMCR_FULLDPLX; // Full duplex
736
  eth_mii_write(alaska88e1111_ml501_phynum, MII_BMCR, ctl);
737
 
738
  // Setup Autoneg
739
  short adv = eth_mii_read(alaska88e1111_ml501_phynum, MII_ADVERTISE);
740
  adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_1000XFULL
741
           |ADVERTISE_1000XHALF | ADVERTISE_1000XPAUSE |
742
           ADVERTISE_1000XPSE_ASYM);
743
  adv |= ADVERTISE_10HALF;
744
  adv |= ADVERTISE_10FULL;
745
  adv |= ADVERTISE_100HALF;
746
  adv |= ADVERTISE_100FULL;
747
  eth_mii_write(alaska88e1111_ml501_phynum, MII_ADVERTISE, adv);
748
  // Disable gigabit???
749
  adv = eth_mii_read(alaska88e1111_ml501_phynum, MII_M1011_PHY_SPEC_CONTROL);
750
  adv &= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP |
751
           MII_1000BASETCONTROL_HALFDUPLEXCAP);
752
  eth_mii_write(alaska88e1111_ml501_phynum, MII_M1011_PHY_SPEC_CONTROL, adv);
753
  // Even more disable gigabit?!
754
  adv = eth_mii_read(alaska88e1111_ml501_phynum, MII_CTRL1000);
755
  adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
756
  eth_mii_write(alaska88e1111_ml501_phynum, MII_CTRL1000, adv);
757
 
758
  // Restart autoneg
759
  printf("Resetting phy...\n");
760
  ctl = eth_mii_read(alaska88e1111_ml501_phynum, MII_BMCR);
761
  ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
762
  eth_mii_write(alaska88e1111_ml501_phynum, MII_BMCR, ctl);
763
 
764
  printf("\nOeth: PHY control reg: 0x%.4x\n",
765
         eth_mii_read(alaska88e1111_ml501_phynum, MII_BMCR));
766
  printf("Oeth: PHY control reg: 0x%.4x\n",
767
         eth_mii_read(alaska88e1111_ml501_phynum, MII_BMSR));
768
  printf("Oeth: PHY id0: 0x%.4x\n",
769
         eth_mii_read(alaska88e1111_ml501_phynum, MII_PHYSID1));
770
  printf("Oeth: PHY id1: 0x%.4x\n",
771
         eth_mii_read(alaska88e1111_ml501_phynum, MII_PHYSID2));
772
  printf("Oeth: PHY adv: 0x%.4x\n",
773
         eth_mii_read(alaska88e1111_ml501_phynum, MII_ADVERTISE));
774
  printf("Oeth: PHY lpa: 0x%.4x\n",
775
         eth_mii_read(alaska88e1111_ml501_phynum, MII_LPA));
776
  printf("Oeth: PHY physpec: 0x%.4x\n",
777
         eth_mii_read(alaska88e1111_ml501_phynum, MII_M1011_PHY_SPEC_CONTROL));
778
  printf("Oeth: PHY expansion: 0x%.4x\n",
779
         eth_mii_read(alaska88e1111_ml501_phynum, MII_EXPANSION ));
780
  printf("Oeth: PHY ctrl1000: 0x%.4x\n",
781
         eth_mii_read(alaska88e1111_ml501_phynum, MII_CTRL1000));
782
  printf("Oeth: PHY stat1000: 0x%.4x\n",
783
         eth_mii_read(alaska88e1111_ml501_phynum, MII_STAT1000));
784
  printf("Oeth: PHY estatus: 0x%.4x\n",
785
         eth_mii_read(alaska88e1111_ml501_phynum, MII_ESTATUS));
786
 
787
 
788
}
789
 
790
 
791
void ethmac_setup(void)
792
{
793
  // from arch/or32/drivers/open_eth.c
794
  volatile oeth_regs *regs;
795
 
796
  regs = (oeth_regs *)(OETH_REG_BASE);
797
 
798
  /*printf("\nbefore reset\n\n");
799
  oeth_printregs();*/
800
 
801
  /* Reset MII mode module */
802
  regs->miimoder = OETH_MIIMODER_RST; /* MII Reset ON */
803
  regs->miimoder &= ~OETH_MIIMODER_RST; /* MII Reset OFF */
804
  regs->miimoder = 0x64; /* Clock divider for MII Management interface */
805
 
806
  /* Reset the controller.
807
  */
808
  regs->moder = OETH_MODER_RST; /* Reset ON */
809
  regs->moder &= ~OETH_MODER_RST;       /* Reset OFF */
810
 
811
  //printf("\nafter reset\n\n");
812
  //oeth_printregs();
813
 
814
  /* Setting TXBD base to OETH_TXBD_NUM.
815
  */
816
  regs->tx_bd_num = OETH_TXBD_NUM;
817
 
818
 
819
  /* Set min/max packet length
820
  */
821
  //regs->packet_len = 0x00400600;
822
  regs->packet_len = (0x0040 << 16) | (MAX_FRAME_SIZE & 0xffff);
823
 
824
  /* Set IPGT register to recomended value
825
  */
826
  regs->ipgt = 0x12;
827
 
828
  /* Set IPGR1 register to recomended value
829
  */
830
  regs->ipgr1 = 0x0000000c;
831
 
832
  /* Set IPGR2 register to recomended value
833
  */
834
  regs->ipgr2 = 0x00000012;
835
 
836
  /* Set COLLCONF register to recomended value
837
  */
838
  regs->collconf = 0x000f003f;
839
 
840
  /* Set control module mode
841
  */
842
#if 0
843
  regs->ctrlmoder = OETH_CTRLMODER_TXFLOW | OETH_CTRLMODER_RXFLOW;
844
#else
845
  regs->ctrlmoder = 0;
846
#endif
847
 
848
  /* Clear MIIM registers */
849
  regs->miitx_data = 0;
850
  regs->miiaddress = 0;
851
  regs->miicommand = 0;
852
 
853
  regs->mac_addr1 = ETH_MACADDR0 << 8 | ETH_MACADDR1;
854
  regs->mac_addr0 = ETH_MACADDR2 << 24 | ETH_MACADDR3 << 16 | ETH_MACADDR4 << 8 | ETH_MACADDR5;
855
 
856
  /* Clear all pending interrupts
857
  */
858
  regs->int_src = 0xffffffff;
859
 
860
  /* Promisc, IFG, CRCEn
861
  */
862
  regs->moder |= OETH_MODER_PRO | OETH_MODER_PAD | OETH_MODER_IFG | OETH_MODER_CRCEN | OETH_MODER_FULLD;
863
 
864
  /* Enable interrupt sources.
865
  */
866
 
867
  regs->int_mask = OETH_INT_MASK_TXB    |
868
    OETH_INT_MASK_TXE   |
869
    OETH_INT_MASK_RXF   |
870
    OETH_INT_MASK_RXE   |
871
    OETH_INT_MASK_BUSY  |
872
    OETH_INT_MASK_TXC   |
873
    OETH_INT_MASK_RXC;
874
#ifndef RTLSIM  
875
  printf("\nafter config\n\n");
876
  oeth_printregs();
877
#endif
878
  // Buffer setup stuff
879
  volatile oeth_bd *tx_bd, *rx_bd;
880
  int i,j,k;
881
 
882
  /* Initialize TXBD pointer
883
  */
884
  tx_bd = (volatile oeth_bd *)OETH_BD_BASE;
885
 
886
  /* Initialize RXBD pointer
887
  */
888
  rx_bd = ((volatile oeth_bd *)OETH_BD_BASE) + OETH_TXBD_NUM;
889
 
890
  /* Preallocated ethernet buffer setup */
891
  unsigned long mem_addr = ETH_BUFF_BASE; /* Defined at top */
892
 
893
  /* Setup for TX buffers*/
894
  for(i = 0, k = 0; i < OETH_TX_BUFF_PAGE_NUM; i++) {
895
    for(j = 0; j < OETH_TX_BUFF_PPGAE; j++, k++) {
896
      //tx_bd[k].len_status = OETH_TX_BD_PAD | OETH_TX_BD_CRC | OETH_RX_BD_IRQ;
897
      tx_bd[k].len_status = OETH_TX_BD_PAD | OETH_TX_BD_CRC;
898
      tx_bd[k].addr = mem_addr;
899
      mem_addr += OETH_TX_BUFF_SIZE;
900
    }
901
  }
902
  tx_bd[OETH_TXBD_NUM - 1].len_status |= OETH_TX_BD_WRAP;
903
 
904
  /* Setup for RX buffers */
905
  for(i = 0, k = 0; i < OETH_RX_BUFF_PAGE_NUM; i++) {
906
    for(j = 0; j < OETH_RX_BUFF_PPGAE; j++, k++) {
907
      rx_bd[k].len_status = OETH_RX_BD_EMPTY | OETH_RX_BD_IRQ; /* Enable interrupt */
908
      rx_bd[k].addr = mem_addr;
909
      mem_addr += OETH_RX_BUFF_SIZE;
910
    }
911
  }
912
  rx_bd[OETH_RXBD_NUM - 1].len_status |= OETH_RX_BD_WRAP; /* Final buffer has wrap bit set */
913
 
914
  /* Enable receiver and transmiter
915
  */
916
  regs->moder |= OETH_MODER_RXEN | OETH_MODER_TXEN;
917
 
918
  next_tx_buf_num = 0; // init tx buffer pointer
919
 
920
  return;
921
}
922
 
923
void
924
ethmac_togglehugen(void)
925
{
926
 
927
  volatile oeth_regs *regs;
928
  regs = (oeth_regs *)(OETH_REG_BASE);
929
 
930
  regs->moder ^= OETH_MODER_HUGEN; // Toggle huge packet enable
931
 
932
  if (regs->moder & OETH_MODER_HUGEN) // If we just enabled huge packets
933
    regs->packet_len = (0x0040 << 16) | (((64*1024)-4) & 0xffff);
934
  else
935
    // back to normal
936
    regs->packet_len = (0x0040 << 16) | (MAX_FRAME_SIZE & 0xffff);
937
 
938
  return;
939
 
940
}
941
 
942
void
943
oeth_reset_tx_bd_pointer(void)
944
{
945
  printf("Resetting TX BD pointer\n");
946
  // from arch/or32/drivers/open_eth.c
947
  volatile oeth_regs *regs;
948
  regs = (oeth_regs *)(OETH_REG_BASE);
949
 
950
  // Toggle TXEN bit, resetting TX BD number
951
  regs->moder &= OETH_MODER_TXEN;
952
  regs->moder |= OETH_MODER_TXEN;
953
 
954
  next_tx_buf_num = 0; // init tx buffer pointer
955
 
956
}
957
 
958
 
959
 
960
/* Find the next available transmit buffer */
961
struct oeth_bd* get_next_tx_bd()
962
{
963
 
964
  int i;
965
  volatile oeth_bd *tx_bd;
966
  tx_bd = (volatile oeth_bd *)OETH_BD_BASE; /* Search from beginning*/
967
 
968
  /* Go through the TX buffs, search for unused one */
969
  for(i = next_tx_buf_num; i < OETH_TXBD_NUM; i++) {
970
 
971
    if(!(tx_bd[i].len_status & OETH_TX_BD_READY)) /* Looking for buffer NOT ready for transmit. ie we can manipulate it */
972
      {
973
#if NEVER_PRINT_PACKET==0
974
        printf("Oeth: Using TX_bd at 0x%lx\n",(unsigned long)&tx_bd[i]);
975
#endif  
976
        if (next_tx_buf_num == OETH_TXBD_NUM-1) next_tx_buf_num = 0;
977
        else next_tx_buf_num++;
978
 
979
        return (struct oeth_bd*) &tx_bd[i];
980
      }
981
 
982
    if ((i == OETH_TXBD_NUM-1) && (next_tx_buf_num != 0))
983
      i = 0;
984
 
985
  }
986
 
987
  printf("No free tx buffers\n");
988
  /* Set to null our returned buffer */
989
  tx_bd = (volatile oeth_bd *) 0;
990
  return (struct oeth_bd*) tx_bd;
991
 
992
}
993
 
994
/* print packet contents */
995
static void
996
oeth_print_packet(unsigned long add, int len)
997
{
998
#if NEVER_PRINT_PACKET==1
999
  return;
1000
#endif
1001
 
1002
  int truncate = (len > 256);
1003
  int length_to_print = truncate ? 256 : len;
1004
 
1005
  int i;
1006
  printf("\nipacket: add = %lx len = %d\n", add, len);
1007
  for(i = 0; i < length_to_print; i++) {
1008
    if(!(i % 8))
1009
      printf(" ");
1010
    if(!(i % 16))
1011
      printf("\n");
1012
    printf(" %.2x", *(((unsigned char *)add) + i));
1013
 
1014
  }
1015
  printf("\n");
1016
 
1017
  if (truncate)
1018
    printf("\ttruncated....\n");
1019
 
1020
}
1021
 
1022
/* Setup buffer descriptors with data */
1023
/* length is in BYTES */
1024
void tx_packet(void* data, int length)
1025
{
1026
  volatile oeth_regs *regs;
1027
  regs = (oeth_regs *)(OETH_REG_BASE);
1028
 
1029
  volatile oeth_bd *tx_bd;
1030
  volatile int i;
1031
 
1032
 
1033
  tx_bd = (volatile oeth_bd *)OETH_BD_BASE;
1034
  tx_bd = (struct oeth_bd*) &tx_bd[next_tx_buf_num];
1035
 
1036
  /*if((tx_bd = (volatile oeth_bd *) get_next_tx_bd()) == NULL)
1037
  {
1038
  printf("No more TX buffers available\n");
1039
  return;
1040
  }
1041
  */
1042
#if NEVER_PRINT_PACKET==0
1043
  printf("Oeth: Using TX_bd buffer address: 0x%lx\n",(unsigned long) tx_bd->addr);
1044
#endif
1045
 
1046
  /* Clear all of the status flags.
1047
  */
1048
  tx_bd->len_status &= ~OETH_TX_BD_STATS;
1049
 
1050
  /* If the frame is short, tell CPM to pad it.
1051
  */
1052
#define ETH_ZLEN        60   /* Min. octets in frame sans FCS */
1053
  if (length <= ETH_ZLEN)
1054
    tx_bd->len_status |= OETH_TX_BD_PAD;
1055
  else
1056
    tx_bd->len_status &= ~OETH_TX_BD_PAD;
1057
 
1058
  //printf("Oeth: Copying %d bytes from 0x%lx to TX_bd buffer at 0x%lx\n",length,(unsigned long) data,(unsigned long) tx_bd->addr);
1059
 
1060
  /* Copy the data into the transmit buffer, byte at a time */
1061
  char* data_p = (char*) data;
1062
  char* data_b = (char*) tx_bd->addr;
1063
  for(i=0;i<length;i++)
1064
    {
1065
      data_b[i] = data_p[i];
1066
    }
1067
  //printf("Oeth: Data copied to buffer\n");
1068
 
1069
  /* Set the length of the packet's data in the buffer descriptor */
1070
  tx_bd->len_status = (tx_bd->len_status & 0x0000ffff) |
1071
    ((length&0xffff) << 16);
1072
 
1073
  //oeth_print_packet(tx_bd->addr, (tx_bd->len_status >> 16));
1074
 
1075
  /* Send it on its way.  Tell controller its ready, interrupt when sent
1076
  * and to put the CRC on the end.
1077
  */
1078
  tx_bd->len_status |= (OETH_TX_BD_READY  | OETH_TX_BD_CRC | OETH_TX_BD_IRQ);
1079
 
1080
  next_tx_buf_num = (next_tx_buf_num + 1) & OETH_TXBD_NUM_MASK;
1081
 
1082
  return;
1083
 
1084
 
1085
}
1086
 
1087
/* enable RX, loop waiting for arrived packets and print them out */
1088
void oeth_monitor_rx(void)
1089
{
1090
  volatile oeth_regs *regs;
1091
  regs = (oeth_regs *)(OETH_REG_BASE);
1092
 
1093
  /* Set RXEN in MAC MODER */
1094
  regs->moder = OETH_MODER_RXEN | regs->moder;
1095
 
1096
 
1097
  volatile oeth_bd *rx_bd;
1098
  rx_bd = ((volatile oeth_bd *)OETH_BD_BASE) + OETH_TXBD_NUM;
1099
 
1100
  volatile int i;
1101
 
1102
  for(i=0;i<OETH_RXBD_NUM;i++)
1103
    {
1104
      if (!(rx_bd[i].len_status & OETH_RX_BD_EMPTY)) /* Not empty */
1105
        {
1106
          // Something in this buffer!
1107
          printf("Oeth: RX in buf %d - len_status: 0x%lx\n",i, rx_bd[i].len_status);
1108
          oeth_print_packet(rx_bd[i].addr, rx_bd[i].len_status >> 16);
1109
          /* Clear recieved bit */
1110
          rx_bd[i].len_status |=  OETH_RX_BD_EMPTY;
1111
          printf("\t end of packet\n\n");
1112
        }
1113
    }
1114
}
1115
 
1116
/* Print out all buffer descriptors */
1117
void oeth_dump_bds()
1118
{
1119
  unsigned long* bd_base = (unsigned long*) OETH_BD_BASE;
1120
 
1121
  int i;
1122
  for(i=0;i<OETH_TXBD_NUM;i++)
1123
    {
1124
      printf("oeth: tx_bd%d: len_status: %lx ",i,*bd_base++);
1125
      printf("addr: %lx\n", *bd_base++);
1126
    }
1127
 
1128
  for(i=0;i<OETH_RXBD_NUM;i++)
1129
    {
1130
      printf("oeth: rx_bd%d: len_status: %lx ",i,*bd_base++);
1131
      printf("addr: %lx\n", *bd_base++);
1132
    }
1133
 
1134
}
1135
 
1136
 
1137
 
1138
char broadcast_ping_packet[] =  {
1139
  0xff,0xff,0xff,0xff,0xff,0xff, /*SRC MAC*/
1140
  0x00, 0x12, 0x34, 0x56, 0x78, 0x9a, /*SRC MAC*/
1141
  0x08,0x00,
1142
  0x45,
1143
  0x00,
1144
  //  0x00,0x54, /* length */
1145
  0x01,0x1c, /* length */
1146
  0x00,0x00,
1147
  0x40,
1148
  0x00,
1149
  0x40,
1150
  0x01,
1151
  0xee,0xf5,
1152
  OUR_IP_BYTES, /* Source IP */
1153
  0xc0,0xa8,0x64,0xff, /* Dest. IP */
1154
  /* ICMP Message body */
1155
  0x08,0x00,0x7d,0x65,0xa7,0x20,0x00,0x01,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,
1156
  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,
1157
  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,
1158
  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,
1159
  90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,
1160
  111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,
1161
  130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,
1162
  149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,
1163
  168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,
1164
  187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,
1165
  206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,
1166
  225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,
1167
  244,245,246,247,248,249,250,251,252,253,254,255};
1168
 
1169
 
1170
char big_ping_packet[] =  {
1171
  0x00, 0x24, 0xe8, 0x91, 0x7c, 0x0d, /*DST MAC*/
1172
  //0xff,0xff,0xff,0xff,0xff,0xff, /*SRC MAC*/
1173
  0x00, 0x12, 0x34, 0x56, 0x78, 0x9a, /*SRC MAC*/
1174
  0x08,0x00,
1175
  0x45,
1176
  0x00,
1177
  0x05,0xdc, /* length */
1178
  0x00,0x00,
1179
  0x40,
1180
  0x00,
1181
  0x40,
1182
  0x01,
1183
  0xea,0xcb,   /* Header checksum */
1184
  OUR_IP_BYTES, /* Source IP */
1185
  DEST_IP_BYTES, /* Dest. IP */
1186
  /* ICMP Message body */
1187
  0x08,0x00, /* Type */
1188
  0x04,0x48, /* ICMP checksum */
1189
  0x02,0x00, /* Identifier */
1190
  0x3a,0x00, /* sequence number */
1191
  0x61,0x62,0x63,0x64,0x65,0x66,0x67,
1192
  0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,
1193
  0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,
1194
  0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,
1195
  0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,
1196
  0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,
1197
  0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,
1198
  0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,
1199
  0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,
1200
  0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,
1201
  0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,
1202
  0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,
1203
  0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,
1204
  0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,
1205
  0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,
1206
  0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,
1207
  0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,
1208
  0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
1209
  0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,
1210
  0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,
1211
  0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,
1212
  0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
1213
  0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
1214
  0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
1215
  0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,
1216
  0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,
1217
  0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,
1218
  0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,
1219
  0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,
1220
  0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,
1221
  0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,
1222
  0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,
1223
  0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,
1224
  0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,
1225
  0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,
1226
  0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,
1227
  0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,
1228
  0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,
1229
  0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,
1230
  0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,
1231
  0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
1232
  0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,
1233
  0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,
1234
  0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,
1235
  0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
1236
  0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
1237
  0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
1238
  0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,
1239
  0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,
1240
  0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,
1241
  0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,
1242
  0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,
1243
  0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,
1244
  0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,
1245
  0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,
1246
  0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,
1247
  0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,
1248
  0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,
1249
  0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,
1250
  0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,
1251
  0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,
1252
  0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,
1253
  0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,
1254
  0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
1255
  0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,
1256
  0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,
1257
  0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,
1258
  0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
1259
  0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
1260
  0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
1261
  0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,
1262
  0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,
1263
  0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,
1264
  0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,
1265
  0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,
1266
  0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,
1267
  0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,
1268
  0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,
1269
  0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,
1270
  0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,
1271
  0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,
1272
  0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,
1273
  0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,
1274
  0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,
1275
  0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,
1276
  0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,
1277
  0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
1278
  0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,
1279
  0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,
1280
  0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,
1281
  0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
1282
  0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
1283
  0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
1284
  0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,
1285
  0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,
1286
  0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,
1287
  0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,
1288
  0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,
1289
  0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77};
1290
 
1291
 
1292
/* This should be 98 bytes big */
1293
char ping_packet[] = {
1294
  0x00, 0x24, 0xe8, 0x91, 0x7c, 0x0d, /*DST MAC*/
1295
  //0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /*DST MAC*/
1296
  0x00, 0x12, 0x34, 0x56, 0x78, 0x9a, /*SRC MAC*/
1297
  0x08, 0x00, /*TYPE*/
1298
  /* IP */
1299
  0x45, /* Version, header length*/
1300
  0x00, /* Differentiated services field */
1301
  0x00, 0x54, /* Total length */
1302
  0x00, 0x00, /* Identification */
1303
  0x40, /* Flags */
1304
  0x00, /* Fragment offset */
1305
  0x40, /* Time to live */
1306
  0x01, /* Protocol (0x01 = ICMP */
1307
  0xf0, 0x53, /* Header checksum */
1308
  //0xc0, 0xa8, 0x64, 0xDE, /* Source IP */
1309
  OUR_IP_BYTES, /* Source IP */
1310
  DEST_IP_BYTES, /* Dest. IP */
1311
  /* ICMP Message body */
1312
  0x08, 0x00, 0x9a, 0xd4, 0xc8, 0x18, 0x00, 0x01, 0xd9, 0x8c, 0x54,
1313
  0x4a, 0x7b, 0x37, 0x01, 0x00, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
1314
  0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
1315
  0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
1316
  0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e,
1317
  0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37
1318
};
1319
 
1320
void send_test_packet()
1321
{
1322
 
1323
  /*Send packet */
1324
  //tx_packet((void*) ping_packet, 102);
1325
  tx_packet((void*) broadcast_ping_packet, 102);
1326
 
1327
}
1328
 
1329
 
1330
/* The interrupt handler.
1331
*/
1332
void
1333
oeth_interrupt(void)
1334
{
1335
 
1336
  volatile oeth_regs *regs;
1337
  regs = (oeth_regs *)(OETH_REG_BASE);
1338
 
1339
  uint  int_events;
1340
  int serviced;
1341
 
1342
  serviced = 0;
1343
 
1344
  /* Get the interrupt events that caused us to be here.
1345
  */
1346
  int_events = regs->int_src;
1347
  regs->int_src = int_events;
1348
 
1349
 
1350
  /* Indicate busy */
1351
  if (int_events & OETH_INT_BUSY)
1352
    {
1353
      printf("\tBusy flag\n");
1354
      /*
1355
      printf("\n=tx_ | %x | %x | %x | %x | %x | %x | %x | %x\n",
1356
      ((oeth_bd *)(OETH_BD_BASE))->len_status,
1357
      ((oeth_bd *)(OETH_BD_BASE+8))->len_status,
1358
      ((oeth_bd *)(OETH_BD_BASE+16))->len_status,
1359
      ((oeth_bd *)(OETH_BD_BASE+24))->len_status,
1360
      ((oeth_bd *)(OETH_BD_BASE+32))->len_status,
1361
      ((oeth_bd *)(OETH_BD_BASE+40))->len_status,
1362
      ((oeth_bd *)(OETH_BD_BASE+48))->len_status,
1363
      ((oeth_bd *)(OETH_BD_BASE+56))->len_status);
1364
      */
1365
      printf("=rx_ | %x | %x | %x | %x | %x | %x | %x | %x\n",
1366
             ((oeth_bd *)(OETH_BD_BASE+64))->len_status,
1367
             ((oeth_bd *)(OETH_BD_BASE+64+8))->len_status,
1368
             ((oeth_bd *)(OETH_BD_BASE+64+16))->len_status,
1369
             ((oeth_bd *)(OETH_BD_BASE+64+24))->len_status,
1370
             ((oeth_bd *)(OETH_BD_BASE+64+32))->len_status,
1371
             ((oeth_bd *)(OETH_BD_BASE+64+40))->len_status,
1372
             ((oeth_bd *)(OETH_BD_BASE+64+48))->len_status,
1373
             ((oeth_bd *)(OETH_BD_BASE+64+56))->len_status);
1374
 
1375
      printf("=int | txb %d | txe %d | rxb %d | rxe %d | busy %d\n",
1376
             (int_events & OETH_INT_TXB) > 0,
1377
             (int_events & OETH_INT_TXE) > 0,
1378
             (int_events & OETH_INT_RXF) > 0,
1379
             (int_events & OETH_INT_RXE) > 0,
1380
             (int_events & OETH_INT_BUSY) > 0);
1381
    }
1382
 
1383
  /* Handle receive event in its own function.
1384
  */
1385
  if (int_events & (OETH_INT_RXF | OETH_INT_RXE)) {
1386
    serviced |= 0x1;
1387
    oeth_rx();
1388
  }
1389
 
1390
  /* Handle transmit event in its own function.
1391
  */
1392
  if (int_events & (OETH_INT_TXB | OETH_INT_TXE)) {
1393
    serviced |= 0x2;
1394
    oeth_tx();
1395
    serviced |= 0x2;
1396
 
1397
  }
1398
 
1399
  return;
1400
}
1401
 
1402
// ARP stuff
1403
 
1404
typedef unsigned long           IPaddr_t;
1405
 
1406
/*
1407
*       Ethernet header
1408
*/
1409
typedef struct {
1410
  unsigned char         et_dest[6];     /* Destination node             */
1411
  unsigned char         et_src[6];      /* Source node                  */
1412
  unsigned short                et_protlen;     /* Protocol or length   */
1413
  unsigned char         et_dsap;        /* 802 DSAP                     */
1414
  unsigned char         et_ssap;        /* 802 SSAP                     */
1415
  unsigned char         et_ctl;         /* 802 control                  */
1416
  unsigned char         et_snap1;       /* SNAP                         */
1417
  unsigned char         et_snap2;
1418
  unsigned char         et_snap3;
1419
  unsigned short                et_prot;        /* 802 protocol         */
1420
} Ethernet_t;
1421
 
1422
#define ETHER_HDR_SIZE  14              /* Ethernet header size         */
1423
#define E802_HDR_SIZE   22              /* 802 ethernet header size     */
1424
#define PROT_IP         0x0800          /* IP protocol                  */
1425
#define PROT_ARP        0x0806          /* IP ARP protocol              */
1426
#define PROT_RARP       0x8035          /* IP ARP protocol              */
1427
 
1428
 
1429
/*
1430
 *      Internet Protocol (IP) header.
1431
 */
1432
typedef struct {
1433
        unsigned char           ip_hl_v;        /* header length and version*/
1434
        unsigned char           ip_tos;         /* type of service          */
1435
        unsigned short          ip_len;         /* total length             */
1436
        unsigned short          ip_id;          /* identification           */
1437
        unsigned short          ip_off;         /* fragment offset field    */
1438
        unsigned char           ip_ttl;         /* time to live             */
1439
        unsigned char           ip_p;           /* protocol                 */
1440
        unsigned short          ip_sum;         /* checksum                 */
1441
        IPaddr_t        ip_src;         /* Source IP address            */
1442
        IPaddr_t        ip_dst;         /* Destination IP address       */
1443
        unsigned short          udp_src;        /* UDP source port      */
1444
        unsigned short          udp_dst;        /* UDP destination port */
1445
        unsigned short          udp_len;        /* Length of UDP packet */
1446
        unsigned short          udp_xsum;       /* Checksum             */
1447
} IP_t;
1448
 
1449
#define IP_HDR_SIZE_NO_UDP      (sizeof (IP_t) - 8)
1450
#define IP_HDR_SIZE             (sizeof (IP_t))
1451
 
1452
#define IPPROTO_ICMP     1      /* Internet Control Message Protocol    */
1453
#define IPPROTO_UDP     17      /* User Datagram Protocol               */
1454
 
1455
 
1456
/*
1457
 * ICMP stuff (just enough to handle (host) redirect messages)
1458
 */
1459
#define ICMP_REDIRECT           5       /* Redirect (change route)      */
1460
 
1461
/* Codes for REDIRECT. */
1462
#define ICMP_REDIR_NET          0        /* Redirect Net                 */
1463
#define ICMP_REDIR_HOST         1       /* Redirect Host                */
1464
 
1465
#define ICMP_TYPE_ECHO_REPLY          0x00
1466
#define ICMP_TYPE_ECHO_REQ          0x08
1467
 
1468
unsigned char ip_reply_packet[0x600] __attribute__ ((aligned (4))); // Save space for a full ICMP reply packet
1469
 
1470
typedef struct {
1471
        unsigned char           type;
1472
        unsigned char           code;
1473
        unsigned short          checksum;
1474
        union {
1475
                struct {
1476
                        unsigned short  id;
1477
                        unsigned short  sequence;
1478
                } echo;
1479
                unsigned long   gateway;
1480
                struct {
1481
                        unsigned short  __unused;
1482
                        unsigned short  mtu;
1483
                } frag;
1484
        } un;
1485
} ICMP_t;
1486
 
1487
// From http://lkml.indiana.edu/hypermail/linux/kernel/9612.3/0060.html
1488
unsigned short calculate_checksum(char* dats, unsigned int len)
1489
{
1490
  unsigned int itr;
1491
  unsigned long accum = 0;
1492
  unsigned long longsum;
1493
 
1494
  // Sum all pairs of data
1495
  for(itr=0;itr<(len & ~0x1);itr+=2)
1496
    accum += (unsigned long)(((dats[itr]<<8)&0xff00)|(dats[itr+1]&0x00ff));
1497
 
1498
  if (len & 0x1) // Do leftover
1499
    accum += (unsigned long) ((dats[itr-1]<<8)&0xff00);
1500
 
1501
  longsum = (unsigned long) (accum & 0xffff);
1502
  longsum += (unsigned long) (accum >> 16); // Sum the carries
1503
  longsum += (longsum >> 16);
1504
  return (unsigned short)((longsum ^ 0xffff) & 0xffff);
1505
 
1506
}
1507
 
1508
void
1509
packet_check_icmp_header(void * pkt)
1510
{
1511
  Ethernet_t * eth_pkt;
1512
  IP_t * ip;
1513
  ICMP_t * icmp;
1514
 
1515
  unsigned int zero = 0;
1516
 
1517
  eth_pkt = (Ethernet_t *) pkt;
1518
 
1519
  // Check it's for our MAC
1520
  char* eth_pkt_dst_mac = (char*) eth_pkt;
1521
  if (!(
1522
        ((eth_pkt_dst_mac[0] == (char) ETH_MACADDR0) &&  // Either our MAC
1523
         (eth_pkt_dst_mac[1] == (char) ETH_MACADDR1) &&
1524
         (eth_pkt_dst_mac[2] == (char) ETH_MACADDR2) &&
1525
         (eth_pkt_dst_mac[3] == (char) ETH_MACADDR3) &&
1526
         (eth_pkt_dst_mac[4] == (char) ETH_MACADDR4) &&
1527
         (eth_pkt_dst_mac[5] == (char) ETH_MACADDR5)) ||
1528
        ((eth_pkt_dst_mac[0] == (char) 0xff) &&          // or broadcast MAC
1529
         (eth_pkt_dst_mac[1] == (char) 0xff) &&
1530
         (eth_pkt_dst_mac[2] == (char) 0xff) &&
1531
         (eth_pkt_dst_mac[3] == (char) 0xff) &&
1532
         (eth_pkt_dst_mac[4] == (char) 0xff) &&
1533
         (eth_pkt_dst_mac[5] == (char) 0xff))
1534
        )
1535
      )
1536
 
1537
    return ;
1538
 
1539
  // Check it's an IP packet
1540
  if (!(eth_pkt->et_protlen == PROT_IP))
1541
    return ;
1542
 
1543
  pkt += ETHER_HDR_SIZE; // Skip eth header stuff
1544
 
1545
  ip = (IP_t*) pkt;
1546
 
1547
  // Check if this is an ICMP packet
1548
  if (!(ip->ip_p == IPPROTO_ICMP))
1549
    return ;
1550
 
1551
  // Check if this is for our IP, get pointer to the DST IP part of IP header
1552
  // which is end of IP section - 4 bytes
1553
  char * internet_protocol_adr = ((unsigned char*)ip + (IP_HDR_SIZE_NO_UDP-4));
1554
 
1555
  if (!((internet_protocol_adr[0] == our_ip[0]) &&
1556
        (internet_protocol_adr[1] == our_ip[1]) &&
1557
        (internet_protocol_adr[2] == our_ip[2]) &&
1558
        (internet_protocol_adr[3] == our_ip[3])))
1559
    return ;
1560
 
1561
  pkt += IP_HDR_SIZE_NO_UDP;
1562
 
1563
  icmp = (ICMP_t*) pkt;
1564
 
1565
  // Currently we only support replying to echo (ping) requests
1566
 
1567
  // Check for ICMP echo request type
1568
  if (!(icmp->type == ICMP_TYPE_ECHO_REQ))
1569
    return;
1570
 
1571
  // Go ahead and construct a response packet
1572
  // Setup pointers
1573
  Ethernet_t * reply_pkt  = (Ethernet_t *) &ip_reply_packet[0];
1574
  IP_t       * reply_IP   = (IP_t*)        &ip_reply_packet[ETHER_HDR_SIZE];
1575
  ICMP_t     * reply_ICMP = (ICMP_t*)      &ip_reply_packet[ETHER_HDR_SIZE+
1576
                                                            IP_HDR_SIZE_NO_UDP];
1577
  // Setup Ethernet header
1578
  // Copy source MAC to destination MAC
1579
  memcpy( (void*)&reply_pkt->et_dest , (void*)&eth_pkt->et_src , 6);
1580
  reply_pkt->et_src[0] = ETH_MACADDR0;
1581
  reply_pkt->et_src[1] = ETH_MACADDR1;
1582
  reply_pkt->et_src[2] = ETH_MACADDR2;
1583
  reply_pkt->et_src[3] = ETH_MACADDR3;
1584
  reply_pkt->et_src[4] = ETH_MACADDR4;
1585
  reply_pkt->et_src[5] = ETH_MACADDR5;
1586
  reply_pkt->et_protlen = PROT_IP;
1587
 
1588
  // IP header
1589
  reply_IP->ip_hl_v = 0x45; // version 4, 20 byte long header, not 100% on this!
1590
  reply_IP->ip_tos = 0x00 ; // ToS (DSCP) - usually used for QoS, set to 0 
1591
  unsigned short ip_indicated_length;
1592
  // First copy total length indicated in received IP header to a variable, we
1593
  // need it again later...
1594
  memcpy ((void*)&ip_indicated_length, (void*)&ip->ip_len, 2);
1595
  // Now copy into reply IP packet
1596
  memcpy ((void*)&reply_IP->ip_len, (void*)&ip_indicated_length, 2);
1597
  memcpy ((void*)&reply_IP->ip_id, (void*)&ip->ip_id, 2); // Copy ID
1598
  reply_IP->ip_ttl = 0x40; // Packet TTL - 64, typical value
1599
  reply_IP->ip_p = IPPROTO_ICMP; // Duh, this is an ICMP echo reply
1600
  // Clear header checksum for now  
1601
 
1602
  memcpy ((void*)&reply_IP->ip_sum, (void*)&zero, 2);
1603
  memcpy ((void*)&reply_IP->ip_src, (void*)&our_ip[0], 4); // Copy in our IP
1604
  // "...return to sender... budupbadah address ....KNOWN ..."
1605
  // WTF this memcpy() fails with alignment error...(?!?!)
1606
  //memcpy (&reply_IP->ip_dst, &ip->ip_src, sizeof(IPaddr_t));
1607
  //...OK then, do it manually.....
1608
  unsigned char *ptr1, *ptr2;
1609
  ptr1 = &reply_IP->ip_dst; ptr2 = &ip->ip_src;
1610
  ptr1[0] = ptr2[0];
1611
  ptr1[1] = ptr2[1];
1612
  ptr1[2] = ptr2[2];
1613
  ptr1[3] = ptr2[3];
1614
 
1615
  // Now calculate the CRC, probably move this to a fuction....
1616
  unsigned short ip_sum = 0; // Initialise checksum value to 0
1617
  int itr;
1618
  char* sum_data_ptr = (char*)reply_IP;
1619
  ip_sum = calculate_checksum(sum_data_ptr,IP_HDR_SIZE_NO_UDP);
1620
  /*
1621
  for(itr=0;itr<IP_HDR_SIZE_NO_UDP;itr+=2)
1622
    ip_sum += (((sum_data_ptr[itr]<<8)&0xff00)|(sum_data_ptr[itr+1]&0x00ff));
1623
  while (ip_sum>>16)
1624
    ip_sum = (ip_sum & 0xffff) + (ip_sum>>16);
1625
  ip_sum = ~ip_sum;
1626
  */
1627
 
1628
  memcpy ((void*)&reply_IP->ip_sum, (void*)&ip_sum, 2);
1629
 
1630
  //
1631
  // Now construct ICMP part of packet
1632
  //
1633
  reply_ICMP->type = ICMP_TYPE_ECHO_REPLY; // ping response type
1634
  reply_ICMP->code = icmp->code; // ICMP code same as sender (is this right?)
1635
 
1636
  // Clear ICMP checksum for now  
1637
  memcpy ((void*)&reply_ICMP->checksum, (void*)&zero, 2);
1638
 
1639
  //
1640
  // Simply copy in the data from the received packet
1641
  // Figure out how much there is after the checksum
1642
  // It should be :
1643
  // length_from_received_IP_header - IP_header_length - initial_ICMP_packet_dat
1644
  // 
1645
  unsigned long icmp_data_length = ip_indicated_length - IP_HDR_SIZE_NO_UDP - 4;
1646
  memcpy ((void*)&reply_ICMP->un,(void*)&icmp->un, icmp_data_length);
1647
 
1648
  // Now calculate checksum for ICMP data
1649
  unsigned short icmp_sum = 0;
1650
  sum_data_ptr = (char*)reply_ICMP;
1651
  icmp_sum = calculate_checksum(sum_data_ptr,icmp_data_length+4);
1652
 
1653
  memcpy ((void*)&reply_ICMP->checksum, (void*)&icmp_sum, 2);
1654
 
1655
  // All done!
1656
 
1657
  tx_packet((void*)ip_reply_packet,ETHER_HDR_SIZE+ip_indicated_length);
1658
 
1659
}
1660
 
1661
 
1662
 
1663
/*
1664
*       Address Resolution Protocol (ARP) header.
1665
*/
1666
typedef struct
1667
{
1668
  unsigned short                ar_hrd; /* Format of hardware address   */
1669
#   define ARP_ETHER        1           /* Ethernet  hardware address   */
1670
  unsigned short                ar_pro; /* Format of protocol address   */
1671
  unsigned char         ar_hln;         /* Length of hardware address   */
1672
  unsigned char         ar_pln;         /* Length of protocol address   */
1673
  unsigned short                ar_op;  /* Operation                    */
1674
#   define ARPOP_REQUEST    1           /* Request  to resolve  address */
1675
#   define ARPOP_REPLY      2           /* Response to previous request */
1676
 
1677
#   define RARPOP_REQUEST   3           /* Request  to resolve  address */
1678
#   define RARPOP_REPLY     4           /* Response to previous request */
1679
 
1680
  /*
1681
  * The remaining fields are variable in size, according to
1682
  * the sizes above, and are defined as appropriate for
1683
  * specific hardware/protocol combinations.
1684
  */
1685
  unsigned char         ar_data[0];
1686
#if 0
1687
  unsigned char         ar_sha[];       /* Sender hardware address      */
1688
  unsigned char         ar_spa[];       /* Sender protocol address      */
1689
  unsigned char         ar_tha[];       /* Target hardware address      */
1690
  unsigned char         ar_tpa[];       /* Target protocol address      */
1691
#endif /* 0 */
1692
} ARP_t;
1693
 
1694
#define ARP_HDR_SIZE    (8+20)          /* Size assuming ethernet       */
1695
 
1696
char arp_reply_packet[(ETHER_HDR_SIZE + ARP_HDR_SIZE)];
1697
 
1698
void
1699
packet_check_arp_header(void * pkt)
1700
{
1701
  Ethernet_t * eth_pkt;
1702
 
1703
  ARP_t * arp;
1704
 
1705
  //printf("packet_check_arp_header: pkt data at 0x%.8x\n",(unsigned long) pkt);
1706
  eth_pkt = (Ethernet_t *) pkt;
1707
 
1708
  if (eth_pkt->et_protlen == 0x0806)
1709
    {
1710
      // Is an ARP request
1711
      // Check the IP
1712
      pkt += ETHER_HDR_SIZE; // Skip eth header stuff
1713
      //printf("Is ARP protocol\npkt header now at 0x%.8x\n",pkt);
1714
 
1715
      arp = (ARP_t*) pkt;
1716
 
1717
      if (arp->ar_hrd == ARP_ETHER && arp->ar_op == ARPOP_REQUEST)
1718
        {
1719
          // Skip forward to the target I.P address
1720
 
1721
          char * internet_protocol_adr = (((unsigned long)&arp->ar_data[0]) + (arp->ar_hln * 2) + (arp->ar_pln));
1722
 
1723
          //printf("Is ARP ethernet request\ncheck adr at 0x%.8x\n",internet_protocol_adr);
1724
          if ((internet_protocol_adr[0] == our_ip[0]) &&
1725
              (internet_protocol_adr[1] == our_ip[1]) &&
1726
              (internet_protocol_adr[2] == our_ip[2]) &&
1727
              (internet_protocol_adr[3] == our_ip[3]))
1728
            {
1729
              //printf("Got valid ARP request\n");
1730
              // Send ARP reply
1731
 
1732
              Ethernet_t * reply_pkt = (Ethernet_t *)&arp_reply_packet[0];
1733
              ARP_t * reply_arp = (ARP_t*)&arp_reply_packet[ETHER_HDR_SIZE];
1734
              memcpy( (void*)&reply_pkt->et_dest , (void*)&eth_pkt->et_src , 6);
1735
              reply_pkt->et_src[0] = ETH_MACADDR0;
1736
              reply_pkt->et_src[1] = ETH_MACADDR1;
1737
              reply_pkt->et_src[2] = ETH_MACADDR2;
1738
              reply_pkt->et_src[3] = ETH_MACADDR3;
1739
              reply_pkt->et_src[4] = ETH_MACADDR4;
1740
              reply_pkt->et_src[5] = ETH_MACADDR5;
1741
              reply_pkt->et_protlen = 0x0806;
1742
              // ARP part of packet           
1743
              reply_arp->ar_hrd = ARP_ETHER;
1744
              reply_arp->ar_pro = 0x0800; // IP Protocol
1745
              reply_arp->ar_hln = 0x06;
1746
              reply_arp->ar_pln = 0x04;
1747
              reply_arp->ar_op = ARPOP_REPLY;
1748
              // My MAC
1749
              memcpy( (void*)&reply_arp->ar_data[0] , (void*)&reply_pkt->et_src , 6);
1750
              // My IP
1751
              memcpy( (void*)&reply_arp->ar_data[6] , (void*)&our_ip , 4);
1752
              // Their MAC
1753
              memcpy( (void*)&reply_arp->ar_data[10] , (void*)&eth_pkt->et_src , 6);
1754
              // Their IP
1755
              char * their_internet_protocol_adr =
1756
                (((unsigned long)&arp->ar_data[0]) + arp->ar_hln );
1757
              memcpy( (void*)&reply_arp->ar_data[16] , (void*)&their_internet_protocol_adr[0] , 4);
1758
 
1759
              tx_packet((void*)arp_reply_packet,(ETHER_HDR_SIZE+ARP_HDR_SIZE) );
1760
 
1761
            }
1762
        }
1763
    }
1764
}
1765
 
1766
 
1767
 
1768
static void
1769
oeth_rx(void)
1770
{
1771
  volatile oeth_regs *regs;
1772
  regs = (oeth_regs *)(OETH_REG_BASE);
1773
 
1774
  volatile oeth_bd *rx_bdp;
1775
  int   pkt_len, i;
1776
  int   bad = 0;
1777
 
1778
  rx_bdp = ((oeth_bd *)OETH_BD_BASE) + OETH_TXBD_NUM;
1779
 
1780
#if NEVER_PRINT_PACKET==0  
1781
  printf("rx");
1782
#endif
1783
 
1784
  /* Find RX buffers marked as having received data */
1785
  for(i = 0; i < OETH_RXBD_NUM; i++)
1786
    {
1787
      if(!(rx_bdp[i].len_status & OETH_RX_BD_EMPTY)){ /* Looking for NOT empty buffers desc. */
1788
        /* Check status for errors.
1789
        */
1790
        if (rx_bdp[i].len_status & (OETH_RX_BD_TOOLONG | OETH_RX_BD_SHORT)) {
1791
          bad = 1;
1792
        }
1793
        if (rx_bdp[i].len_status & OETH_RX_BD_DRIBBLE) {
1794
          bad = 1;
1795
        }
1796
        if (rx_bdp[i].len_status & OETH_RX_BD_CRCERR) {
1797
          bad = 1;
1798
        }
1799
        if (rx_bdp[i].len_status & OETH_RX_BD_OVERRUN) {
1800
          bad = 1;
1801
        }
1802
        if (rx_bdp[i].len_status & OETH_RX_BD_MISS) {
1803
 
1804
        }
1805
        if (rx_bdp[i].len_status & OETH_RX_BD_LATECOL) {
1806
          bad = 1;
1807
        }
1808
 
1809
        if (bad) {
1810
          rx_bdp[i].len_status &= ~OETH_RX_BD_STATS;
1811
          rx_bdp[i].len_status |= OETH_RX_BD_EMPTY;
1812
 
1813
          continue;
1814
        }
1815
        else {
1816
 
1817
          /* Process the incoming frame.
1818
          */
1819
          pkt_len = rx_bdp[i].len_status >> 16;
1820
 
1821
          /* Do something here with the data - copy it into userspace, perhaps. */
1822
          // See if it's an ARP packet
1823
          packet_check_arp_header((void *)rx_bdp[i].addr );
1824
          // See if it's an ICMP echo request
1825
          packet_check_icmp_header((void *)rx_bdp[i].addr );
1826
#if NEVER_PRINT_PACKET==0
1827
          oeth_print_packet(rx_bdp[i].addr, rx_bdp[i].len_status >> 16);
1828
          printf("\t end of packet\n\n");
1829
#endif    
1830
          /* finish up */
1831
          rx_bdp[i].len_status &= ~OETH_RX_BD_STATS; /* Clear stats */
1832
          rx_bdp[i].len_status |= OETH_RX_BD_EMPTY; /* Mark RX BD as empty */
1833
 
1834
 
1835
        }
1836
      }
1837
    }
1838
}
1839
 
1840
 
1841
 
1842
static void
1843
oeth_tx(void)
1844
{
1845
  volatile oeth_bd *tx_bd;
1846
  int i;
1847
#if NEVER_PRINT_PACKET==0  
1848
  printf("tx");
1849
#endif
1850
  tx_bd = (volatile oeth_bd *)OETH_BD_BASE; /* Search from beginning*/
1851
 
1852
  /* Go through the TX buffs, search for one that was just sent */
1853
  for(i = 0; i < OETH_TXBD_NUM; i++)
1854
    {
1855
      /* Looking for buffer NOT ready for transmit. and IRQ enabled */
1856
      if( (!(tx_bd[i].len_status & (OETH_TX_BD_READY))) && (tx_bd[i].len_status & (OETH_TX_BD_IRQ)) )
1857
        {
1858
          //oeth_print_packet(tx_bd[i].addr, (tx_bd[i].len_status >> 16));
1859
          /* 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 */
1860
          tx_bd[i].len_status &= ~OETH_TX_BD_IRQ;
1861
 
1862
          /* Probably good to check for TX errors here */
1863
 
1864
#if NEVER_PRINT_PACKET==0  
1865
          printf("T%d",i);
1866
#endif
1867
 
1868
        }
1869
    }
1870
  return;
1871
}
1872
 
1873
 
1874
int main ()
1875
{
1876
 
1877 408 julius
  /* Initialise vector handler */
1878 349 julius
  int_init();
1879
 
1880
  /* Install ethernet interrupt handler, it is enabled here too */
1881
  int_add(ETH0_IRQ, oeth_interrupt, 0);
1882
 
1883 408 julius
  /* Enable interrupts */
1884
  cpu_enable_user_interrupts();
1885 349 julius
 
1886
  last_char=0; /* Variable init for spin_cursor() */
1887
  next_tx_buf_num = 4; /* init for tx buffer counter */
1888
 
1889
#ifndef RTLSIM
1890
  uart_init(DEFAULT_UART); // init the UART before we can printf
1891
  printf("\n\teth ping program\n\n");
1892
  printf("\n\tboard IP: %d.%d.%d.%d\n",our_ip[0]&0xff,our_ip[1]&0xff,
1893
         our_ip[2]&0xff,our_ip[3]&0xff);
1894
#endif
1895
 
1896
  ethmac_setup(); /* Configure MAC, TX/RX BDs and enable RX and TX in MODER */
1897
 
1898
  //scan_ethphys(); /* Scan MIIM bus for PHYs */
1899
  //jb ethphy_init(); /* Attempt reset and configuration of PHY via MIIM */
1900
  //ethmac_scanstatus(); /* Enable scanning of status register via MIIM */
1901
 
1902
  /* clear tx_done, the tx interrupt handler will set it when it's been transmitted */
1903
  tx_done = 0;
1904
 
1905
 
1906
#ifndef RTLSIM
1907
  /* Loop, monitoring user input from TTY */
1908
  while(1)
1909
    {
1910
      char c;
1911
 
1912
      while(!uart_check_for_char(DEFAULT_UART))
1913
        {
1914
          spin_cursor();
1915
          oeth_monitor_rx();
1916
        }
1917
 
1918
      c = uart_getc(DEFAULT_UART);
1919
 
1920
      if (c == 's')
1921
        tx_packet((void*) ping_packet, 98);
1922
      if (c == 'S')
1923
        tx_packet((void*)big_ping_packet, 1514);
1924
      if (c == 'h')
1925
        scan_ethphys();
1926
      if (c == 'i')
1927
        ethphy_init();
1928
      if (c == 'p')
1929
        oeth_printregs();
1930
      if (c == '0')
1931
        scan_ethphy(0);
1932
      if (c == '1')
1933
        scan_ethphy(1);
1934
      if (c == '7')
1935
        {
1936
          scan_ethphy(7);
1937
          ethphy_print_status(7);
1938
        }
1939
      if (c == 'r')
1940
        ethphy_reset(0);
1941
      if (c == 'R')
1942
        oeth_reset_tx_bd_pointer();
1943
      if (c == 'n')
1944
        ethphy_reneg(0);
1945
      if (c == 'N')
1946
        ethphy_set_autoneg(0);
1947
      if (c == 'm')
1948
        ethmac_togglehugen();
1949
      if (c == 't')
1950
        ethphy_set_10mbit(0);
1951
      if ( c == 'b' )
1952
        {
1953
          printf("\n\t---\n");
1954
          oeth_dump_bds();
1955
          printf("\t---\n");
1956
        }
1957
 
1958
    }
1959
 
1960
 
1961
 
1962
#endif
1963
 
1964
}

powered by: WebSVN 2.1.0

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