OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [orpsocv2/] [sw/] [tests/] [ethmac/] [board/] [ethmac-ping.c] - Blame information for rev 411

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

powered by: WebSVN 2.1.0

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