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

Subversion Repositories openrisc_me

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

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

powered by: WebSVN 2.1.0

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