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 415

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

powered by: WebSVN 2.1.0

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