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 567

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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