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 479

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

powered by: WebSVN 2.1.0

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