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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [redboot/] [current/] [src/] [net/] [net_io.c] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      net/net_io.c
4
//
5
//      Stand-alone network logical I/O support for RedBoot
6
//
7
//==========================================================================
8
// ####ECOSGPLCOPYRIGHTBEGIN####                                            
9
// -------------------------------------------                              
10
// This file is part of eCos, the Embedded Configurable Operating System.   
11
// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
12
//
13
// eCos is free software; you can redistribute it and/or modify it under    
14
// the terms of the GNU General Public License as published by the Free     
15
// Software Foundation; either version 2 or (at your option) any later      
16
// version.                                                                 
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT      
19
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
20
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
21
// for more details.                                                        
22
//
23
// You should have received a copy of the GNU General Public License        
24
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
25
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
26
//
27
// As a special exception, if other files instantiate templates or use      
28
// macros or inline functions from this file, or you compile this file      
29
// and link it with other works to produce a work based on this file,       
30
// this file does not by itself cause the resulting work to be covered by   
31
// the GNU General Public License. However the source code for this file    
32
// must still be made available in accordance with section (3) of the GNU   
33
// General Public License v2.                                               
34
//
35
// This exception does not invalidate any other reasons why a work based    
36
// on this file might be covered by the GNU General Public License.         
37
// -------------------------------------------                              
38
// ####ECOSGPLCOPYRIGHTEND####                                              
39
//==========================================================================
40
//#####DESCRIPTIONBEGIN####
41
//
42
// Author(s):    gthomas
43
// Contributors: gthomas
44
// Date:         2000-07-14
45
// Purpose:      
46
// Description:  
47
//              
48
// This code is part of RedBoot (tm).
49
//
50
//####DESCRIPTIONEND####
51
//
52
//==========================================================================
53
 
54
#include <redboot.h>
55
#include <net/net.h>
56
#include <cyg/hal/hal_misc.h>   // Helper functions
57
#include <cyg/hal/hal_if.h>     // HAL I/O interfaces
58
#include <cyg/hal/drv_api.h>
59
#include <cyg/hal/hal_intr.h>
60
#include <cyg/infra/cyg_ass.h>         // assertion macros
61
 
62
#ifndef CYGSEM_REDBOOT_DEFAULT_NO_BOOTP
63
#define CYGSEM_REDBOOT_DEFAULT_NO_BOOTP 0
64
#endif
65
 
66
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
67
#include <flash_config.h>
68
 
69
RedBoot_config_option("GDB connection port",
70
                      gdb_port,
71
                      ALWAYS_ENABLED, true,
72
                      CONFIG_INT,
73
                      CYGNUM_REDBOOT_NETWORKING_TCP_PORT
74
    );
75
RedBoot_config_option("Network debug at boot time",
76
                      net_debug,
77
                      ALWAYS_ENABLED, true,
78
                      CONFIG_BOOL,
79
                      false
80
    );
81
#if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1)
82
RedBoot_config_option("Default network device",
83
                      net_device,
84
                      ALWAYS_ENABLED, true,
85
                      CONFIG_NETPORT,
86
                      CYGDAT_REDBOOT_DEFAULT_NETWORK_DEVICE
87
    );
88
#endif
89
// Note: the following options are related.  If 'bootp' is false, then
90
// the other values are used in the configuration.  Because of the way
91
// that configuration tables are generated, they should have names which
92
// are related.  The configuration options will show up lexicographically
93
// ordered, thus the peculiar naming.  In this case, the 'use' option is
94
// negated (if false, the others apply) which makes the names even more
95
// confusing.
96
 
97
#ifdef CYGPKG_REDBOOT_NETWORKING_BOOTP
98
RedBoot_config_option("Use BOOTP for network configuration",
99
                      bootp,
100
                      ALWAYS_ENABLED, true,
101
                      CONFIG_BOOL,
102
                      !CYGSEM_REDBOOT_DEFAULT_NO_BOOTP
103
    );
104
#endif
105
RedBoot_config_option("Local IP address",
106
                      bootp_my_ip,
107
                      "bootp", false,
108
                      CONFIG_IP,
109
 
110
    );
111
#ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY
112
RedBoot_config_option("Local IP address mask",
113
                      bootp_my_ip_mask,
114
                      "bootp", false,
115
                      CONFIG_IP,
116
 
117
    );
118
RedBoot_config_option("Gateway IP address",
119
                      bootp_my_gateway_ip,
120
                      "bootp", false,
121
                      CONFIG_IP,
122
 
123
    );
124
#endif
125
RedBoot_config_option("Default server IP address",
126
                      bootp_server_ip,
127
                      ALWAYS_ENABLED, true,
128
                      CONFIG_IP,
129
 
130
    );
131
 
132
// Note: the following options are related too.
133
RedBoot_config_option("Force console for special debug messages",
134
                      info_console_force,
135
                      ALWAYS_ENABLED, true,
136
                      CONFIG_BOOL,
137
                      false
138
    );
139
RedBoot_config_option("Console number for special debug messages",
140
                      info_console_number,
141
                      "info_console_force", true,
142
                      CONFIG_INT,
143
 
144
    );
145
#endif
146
 
147
#define TCP_CHANNEL CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS
148
 
149
#ifdef DEBUG_TCP
150
int show_tcp = 0;
151
#endif 
152
 
153
static tcp_socket_t tcp_sock;
154
static int state;
155
static int _timeout = 500;
156
static int orig_console, orig_debug;
157
 
158
static int in_buflen = 0;
159
static unsigned char in_buf[64];
160
static unsigned char *in_bufp;
161
static int out_buflen = 0;
162
static unsigned char out_buf[1024];
163
static unsigned char *out_bufp;
164
static bool flush_output_lines = false;
165
 
166
// Functions in this module
167
static void net_io_flush(void);
168
static void net_io_revert_console(void);
169
static void net_io_putc(void*, cyg_uint8);
170
 
171
// Special characters used by Telnet - must be interpretted here
172
#define TELNET_IAC    0xFF // Interpret as command (escape)
173
#define TELNET_IP     0xF4 // Interrupt process
174
#define TELNET_WILL   0xFB // I Will do XXX
175
#define TELNET_WONT   0xFC // I Won't do XXX
176
#define TELNET_DO     0xFD // Will you XXX
177
#define TELNET_DONT   0xFE // Don't you XXX
178
#define TELNET_TM     0x06 // Time marker (special DO/WONT after IP)
179
 
180
static cyg_bool
181
_net_io_getc_nonblock(void* __ch_data, cyg_uint8* ch)
182
{
183
    if (in_buflen == 0) {
184
        __tcp_poll();
185
        if (tcp_sock.state == _CLOSE_WAIT) {
186
            // This connection is breaking
187
            if (tcp_sock.data_bytes == 0 && tcp_sock.rxcnt == 0) {
188
                __tcp_close(&tcp_sock);
189
                return false;
190
            }
191
        }
192
        if (tcp_sock.state == _CLOSED) {
193
            // The connection is gone
194
            net_io_revert_console();
195
            *ch = '\n';
196
            return true;
197
        }
198
        in_buflen = __tcp_read(&tcp_sock, in_buf, sizeof(in_buf));
199
        in_bufp = in_buf;
200
#ifdef DEBUG_TCP
201
        if (show_tcp && (in_buflen > 0)) {
202
            int old_console;
203
            old_console = start_console();
204
            diag_printf("%s:%d\n", __FUNCTION__, __LINE__);
205
            diag_dump_buf(in_buf, in_buflen);
206
            end_console(old_console);
207
        }
208
#endif // DEBUG_TCP
209
    }
210
    if (in_buflen) {
211
        *ch = *in_bufp++;
212
        in_buflen--;
213
        return true;
214
    } else {
215
        return false;
216
    }
217
}
218
 
219
static cyg_bool
220
net_io_getc_nonblock(void* __ch_data, cyg_uint8* ch)
221
{
222
    cyg_uint8 esc;
223
 
224
    if (!_net_io_getc_nonblock(__ch_data, ch))
225
        return false;
226
 
227
    if (gdb_active || *ch != TELNET_IAC)
228
        return true;
229
 
230
    // Telnet escape - need to read/handle more
231
    while (!_net_io_getc_nonblock(__ch_data, &esc)) ;
232
 
233
    switch (esc) {
234
    case TELNET_IAC:
235
        // The other special case - escaped escape
236
        return true;
237
    case TELNET_IP:
238
        // Special case for ^C == Interrupt Process
239
        *ch = 0x03;
240
        // Just in case the other end needs synchronizing
241
        net_io_putc(__ch_data, TELNET_IAC);
242
        net_io_putc(__ch_data, TELNET_WONT);
243
        net_io_putc(__ch_data, TELNET_TM);
244
        net_io_flush();
245
        return true;
246
    case TELNET_DO:
247
        // Telnet DO option
248
        while (!_net_io_getc_nonblock(__ch_data, &esc)) ;
249
        // Respond with WONT option
250
        net_io_putc(__ch_data, TELNET_IAC);
251
        net_io_putc(__ch_data, TELNET_WONT);
252
        net_io_putc(__ch_data, esc);
253
        return false;  // Ignore this whole thing!
254
    case TELNET_WILL:
255
        // Telnet WILL option
256
        while (!_net_io_getc_nonblock(__ch_data, &esc)) ;
257
        // Respond with DONT option
258
        net_io_putc(__ch_data, TELNET_IAC);
259
        net_io_putc(__ch_data, TELNET_DONT);
260
        net_io_putc(__ch_data, esc);
261
        return false;  // Ignore this whole thing!
262
    default:
263
        return false;
264
    }
265
}
266
 
267
static cyg_uint8
268
net_io_getc(void* __ch_data)
269
{
270
    cyg_uint8 ch;
271
    int idle_timeout = 10;  // 10ms
272
 
273
    CYGARC_HAL_SAVE_GP();
274
    while (true) {
275
        if (net_io_getc_nonblock(__ch_data, &ch)) break;
276
        if (--idle_timeout == 0) {
277
            net_io_flush();
278
            idle_timeout = 10;
279
        }
280
    }
281
    CYGARC_HAL_RESTORE_GP();
282
    return ch;
283
}
284
 
285
static void
286
net_io_flush(void)
287
{
288
    int n;
289
    char *bp = out_buf;
290
 
291
#ifdef DEBUG_TCP
292
    if (show_tcp) {
293
        int old_console;
294
        old_console = start_console();
295
        diag_printf("%s.%d\n", __FUNCTION__, __LINE__);
296
        diag_dump_buf(out_buf, out_buflen);
297
        end_console(old_console);
298
    }
299
#endif // SHOW_TCP
300
    n = __tcp_write_block(&tcp_sock, bp, out_buflen);
301
    if (n < 0) {
302
        // The connection is gone!
303
        net_io_revert_console();
304
    } else {
305
        out_buflen -= n;
306
        bp += n;
307
    }
308
    out_bufp = out_buf;  out_buflen = 0;
309
    // Check interrupt flag
310
    if (CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG()) {
311
        CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG_SET(0);
312
        cyg_hal_user_break(0);
313
    }
314
}
315
 
316
static void
317
net_io_putc(void* __ch_data, cyg_uint8 c)
318
{
319
    static bool have_dollar, have_hash;
320
    static int hash_count;
321
 
322
    CYGARC_HAL_SAVE_GP();
323
    *out_bufp++ = c;
324
    if (c == '$') have_dollar = true;
325
    if (have_dollar && (c == '#')) {
326
        have_hash = true;
327
        hash_count = 0;
328
    }
329
    if ((++out_buflen == sizeof(out_buf)) ||
330
        (flush_output_lines && c == '\n') ||
331
        (have_hash && (++hash_count == 3))) {
332
        net_io_flush();
333
        have_dollar = false;
334
    }
335
    CYGARC_HAL_RESTORE_GP();
336
}
337
 
338
static void
339
net_io_write(void* __ch_data, const cyg_uint8* __buf, cyg_uint32 __len)
340
{
341
    int old_console;
342
 
343
    old_console = start_console();
344
    diag_printf("%s.%d\n", __FUNCTION__, __LINE__);
345
    end_console(old_console);
346
#if 0
347
    CYGARC_HAL_SAVE_GP();
348
 
349
    while(__len-- > 0)
350
        net_io_putc(__ch_data, *__buf++);
351
 
352
    CYGARC_HAL_RESTORE_GP();
353
#endif
354
}
355
 
356
static void
357
net_io_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
358
{
359
    int old_console;
360
 
361
    old_console = start_console();
362
    diag_printf("%s.%d\n", __FUNCTION__, __LINE__);
363
    end_console(old_console);
364
#if 0
365
    CYGARC_HAL_SAVE_GP();
366
 
367
    while(__len-- > 0)
368
        *__buf++ = net_io_getc(__ch_data);
369
 
370
    CYGARC_HAL_RESTORE_GP();
371
#endif
372
}
373
 
374
static cyg_bool
375
net_io_getc_timeout(void* __ch_data, cyg_uint8* ch)
376
{
377
    int delay_count;
378
    cyg_bool res;
379
 
380
    CYGARC_HAL_SAVE_GP();
381
    net_io_flush();  // Make sure any output has been sent
382
    delay_count = _timeout;
383
 
384
    for(;;) {
385
        res = net_io_getc_nonblock(__ch_data, ch);
386
        if (res || 0 == delay_count--)
387
            break;
388
    }
389
 
390
    CYGARC_HAL_RESTORE_GP();
391
 
392
    return res;
393
}
394
 
395
static int
396
net_io_control(void *__ch_data, __comm_control_cmd_t __func, ...)
397
{
398
    static int vector = 0;
399
    int ret = 0;
400
    static int irq_state = 0;
401
 
402
    CYGARC_HAL_SAVE_GP();
403
 
404
    switch (__func) {
405
    case __COMMCTL_IRQ_ENABLE:
406
        irq_state = 1;
407
        if (vector == 0) {
408
            vector = eth_drv_int_vector();
409
        }
410
        HAL_INTERRUPT_UNMASK(vector);
411
        break;
412
    case __COMMCTL_IRQ_DISABLE:
413
        ret = irq_state;
414
        irq_state = 0;
415
        if (vector == 0) {
416
            vector = eth_drv_int_vector();
417
        }
418
        HAL_INTERRUPT_MASK(vector);
419
        break;
420
    case __COMMCTL_DBG_ISR_VECTOR:
421
        ret = vector;
422
        break;
423
    case __COMMCTL_SET_TIMEOUT:
424
    {
425
        va_list ap;
426
 
427
        va_start(ap, __func);
428
 
429
        ret = _timeout;
430
        _timeout = va_arg(ap, cyg_uint32);
431
 
432
        va_end(ap);
433
        break;
434
    }
435
    case __COMMCTL_FLUSH_OUTPUT:
436
        net_io_flush();
437
        break;
438
    case __COMMCTL_ENABLE_LINE_FLUSH:
439
        flush_output_lines = true;
440
        break;
441
    case __COMMCTL_DISABLE_LINE_FLUSH:
442
        flush_output_lines = false;
443
        break;
444
    default:
445
        break;
446
    }
447
    CYGARC_HAL_RESTORE_GP();
448
    return ret;
449
}
450
 
451
static int
452
net_io_isr(void *__ch_data, int* __ctrlc,
453
           CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
454
{
455
    char ch;
456
 
457
    CYGARC_HAL_SAVE_GP();
458
    *__ctrlc = 0;
459
    if (net_io_getc_nonblock(__ch_data, &ch)) {
460
        if (ch == 0x03) {
461
            *__ctrlc = 1;
462
        }
463
    }
464
    CYGARC_HAL_RESTORE_GP();
465
    return CYG_ISR_HANDLED;
466
}
467
 
468
// TEMP
469
 
470
int
471
start_console(void)
472
{
473
    int cur_console =
474
        CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
475
 
476
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
477
    int i = 0;
478
    if ( flash_get_config( "info_console_force", &i, CONFIG_BOOL) )
479
        if ( i )
480
            if ( ! flash_get_config( "info_console_number", &i, CONFIG_INT) )
481
                i = 0; // the default, if that call failed.
482
    if ( i )
483
        CYGACC_CALL_IF_SET_CONSOLE_COMM(i);
484
    else
485
#endif
486
        CYGACC_CALL_IF_SET_CONSOLE_COMM(0);
487
 
488
    return cur_console;
489
}
490
 
491
void
492
end_console(int old_console)
493
{
494
    // Restore original console
495
    CYGACC_CALL_IF_SET_CONSOLE_COMM(old_console);
496
}
497
// TEMP
498
 
499
static void
500
net_io_revert_console(void)
501
{
502
#ifdef CYGPKG_REDBOOT_ANY_CONSOLE
503
    console_selected = false;
504
#endif
505
    CYGACC_CALL_IF_SET_CONSOLE_COMM(orig_console);
506
    CYGACC_CALL_IF_SET_DEBUG_COMM(orig_debug);
507
    console_echo = true;
508
}
509
 
510
static void
511
net_io_assume_console(void)
512
{
513
#ifdef CYGPKG_REDBOOT_ANY_CONSOLE
514
    console_selected = true;
515
#endif
516
    console_echo = false;
517
    orig_console = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
518
    CYGACC_CALL_IF_SET_CONSOLE_COMM(TCP_CHANNEL);
519
    orig_debug = CYGACC_CALL_IF_SET_DEBUG_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
520
    CYGACC_CALL_IF_SET_DEBUG_COMM(TCP_CHANNEL);
521
}
522
 
523
static void
524
net_io_init(void)
525
{
526
    static int init = 0;
527
    if (!init) {
528
        hal_virtual_comm_table_t* comm;
529
        int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
530
 
531
        // Setup procs in the vector table
532
        CYGACC_CALL_IF_SET_CONSOLE_COMM(TCP_CHANNEL);
533
        comm = CYGACC_CALL_IF_CONSOLE_PROCS();
534
        //CYGACC_COMM_IF_CH_DATA_SET(*comm, chan);
535
        CYGACC_COMM_IF_WRITE_SET(*comm, net_io_write);
536
        CYGACC_COMM_IF_READ_SET(*comm, net_io_read);
537
        CYGACC_COMM_IF_PUTC_SET(*comm, net_io_putc);
538
        CYGACC_COMM_IF_GETC_SET(*comm, net_io_getc);
539
        CYGACC_COMM_IF_CONTROL_SET(*comm, net_io_control);
540
        CYGACC_COMM_IF_DBG_ISR_SET(*comm, net_io_isr);
541
        CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, net_io_getc_timeout);
542
 
543
        // Disable interrupts via this interface to set static
544
        // state into correct state.
545
        net_io_control( comm, __COMMCTL_IRQ_DISABLE );
546
 
547
        // Restore original console
548
        CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
549
 
550
        init = 1;
551
        gdb_active = false;
552
    }
553
    __tcp_listen(&tcp_sock, gdb_port);
554
    state = tcp_sock.state;
555
#ifdef DEBUG_TCP
556
    diag_printf("show tcp = %p\n", (void *)&show_tcp);
557
#endif
558
}
559
 
560
// Check for incoming TCP debug connection
561
void
562
net_io_test(bool is_idle)
563
{
564
    if (!is_idle) return;  // Only care about idle case
565
    if (!have_net) return;
566
    __tcp_poll();
567
    if (state != tcp_sock.state) {
568
        // Something has changed
569
        if (tcp_sock.state == _ESTABLISHED) {
570
            // A new connection has arrived
571
            net_io_assume_console();
572
            in_bufp = in_buf;  in_buflen = 1;  *in_bufp = '\r';
573
            out_bufp = out_buf;  out_buflen = 0;
574
        }
575
        if (tcp_sock.state == _CLOSED) {
576
            net_io_init();  // Get ready for another connection
577
        }
578
    }
579
    state = tcp_sock.state;
580
}
581
 
582
// This schedules the 'net_io_test()' function to be run by RedBoot's
583
// main command loop when idle (i.e. when no input arrives after some
584
// period of time).
585
RedBoot_idle(net_io_test, RedBoot_IDLE_NETIO);
586
 
587
//
588
// Network initialization
589
//
590
#include <cyg/io/eth/eth_drv.h>
591
#include <cyg/io/eth/netdev.h>
592
#include <cyg/hal/hal_tables.h>
593
 
594
// Define table boundaries
595
CYG_HAL_TABLE_BEGIN( __NETDEVTAB__, netdev );
596
CYG_HAL_TABLE_END( __NETDEVTAB_END__, netdev );
597
 
598
RedBoot_init(net_init, RedBoot_INIT_NET);
599
 
600
static void
601
show_addrs(void)
602
{
603
    diag_printf("IP: %s", inet_ntoa((in_addr_t *)&__local_ip_addr));
604
#ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY
605
    diag_printf("/%s", inet_ntoa((in_addr_t *)&__local_ip_mask));
606
    diag_printf(", Gateway: %s\n", inet_ntoa((in_addr_t *)&__local_ip_gate));
607
#else
608
    diag_printf(", ");
609
#endif
610
    diag_printf("Default server: %s", inet_ntoa(&my_bootp_info.bp_siaddr));
611
#ifdef CYGPKG_REDBOOT_NETWORKING_DNS
612
    show_dns();
613
#endif
614
    diag_printf("\n");
615
}
616
 
617
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
618
static void
619
flash_get_IP(char *id, ip_addr_t *val)
620
{
621
    ip_addr_t my_ip;
622
    int i;
623
 
624
    if (flash_get_config(id, &my_ip, CONFIG_IP)) {
625
        if (my_ip[0] != 0 || my_ip[1] != 0 ||
626
            my_ip[2] != 0 || my_ip[3] != 0) {
627
            // 'id' is set to something so let it override any static IP
628
            for (i=0; i<4; i++)
629
                (*val)[i] = my_ip[i];
630
        }
631
    }
632
}
633
#endif
634
 
635
static cyg_netdevtab_entry_t *
636
net_devtab_entry(unsigned index)
637
{
638
    cyg_netdevtab_entry_t *t = &__NETDEVTAB__[index];
639
 
640
    if (t < &__NETDEVTAB__[0] || t >= &__NETDEVTAB_END__)
641
        return NULL;
642
 
643
    return t;
644
}
645
 
646
const char *
647
net_devname(unsigned index)
648
{
649
    cyg_netdevtab_entry_t *t = net_devtab_entry(index);
650
    if (t)
651
        return t->name;
652
    return NULL;
653
}
654
 
655
int
656
net_devindex(char *name)
657
{
658
    const char *devname;
659
    int index;
660
 
661
    for (index = 0; (devname = net_devname(index)) != NULL; index++)
662
        if (!strcmp(name, devname))
663
            return index;
664
    return -1;
665
}
666
 
667
static void
668
show_eth_info(void)
669
{
670
    diag_printf("Ethernet %s: MAC address %02x:%02x:%02x:%02x:%02x:%02x\n",
671
                __local_enet_sc->dev_name,
672
                __local_enet_addr[0],
673
                __local_enet_addr[1],
674
                __local_enet_addr[2],
675
                __local_enet_addr[3],
676
                __local_enet_addr[4],
677
                __local_enet_addr[5]);
678
}
679
 
680
void
681
net_init(void)
682
{
683
    cyg_netdevtab_entry_t *t;
684
    unsigned index;
685
    struct eth_drv_sc *primary_net = (struct eth_drv_sc *)0;
686
#if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1)
687
    char *default_devname = CYGDAT_REDBOOT_DEFAULT_NETWORK_DEVICE;
688
    int default_index;
689
#endif
690
#ifdef CYGDAT_REDBOOT_DEFAULT_BOOTP_SERVER_IP_ADDR
691
    char ip_addr[16];
692
#endif
693
 
694
    // Set defaults as appropriate
695
#if defined(CYGPKG_REDBOOT_NETWORKING_BOOTP) && !CYGSEM_REDBOOT_DEFAULT_NO_BOOTP
696
    use_bootp = true;
697
#else
698
    use_bootp = false;
699
#endif
700
#ifdef CYGDBG_REDBOOT_NET_DEBUG
701
    net_debug = true;
702
#else
703
    net_debug = false;
704
#endif
705
    gdb_port = CYGNUM_REDBOOT_NETWORKING_TCP_PORT;
706
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
707
    // Fetch values from saved config data, if available
708
#if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1)
709
    flash_get_config("net_device", &default_devname, CONFIG_NETPORT);
710
#endif
711
    flash_get_config("net_debug", &net_debug, CONFIG_BOOL);
712
    flash_get_config("gdb_port", &gdb_port, CONFIG_INT);
713
#ifdef CYGPKG_REDBOOT_NETWORKING_BOOTP
714
    flash_get_config("bootp", &use_bootp, CONFIG_BOOL);
715
#endif
716
    if (!use_bootp) {
717
        flash_get_IP("bootp_my_ip", &__local_ip_addr);
718
#ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY
719
        flash_get_IP("bootp_my_ip_mask", &__local_ip_mask);
720
        flash_get_IP("bootp_my_gateway_ip", &__local_ip_gate);
721
#endif
722
    }
723
#endif
724
# ifdef CYGDBG_IO_ETH_DRIVERS_DEBUG
725
    // Don't override if the user has deliberately set something more
726
    // verbose.
727
    if (0 == cyg_io_eth_net_debug)
728
        cyg_io_eth_net_debug = net_debug;
729
# endif
730
    have_net = false;
731
    // Make sure the recv buffers are set up
732
    eth_drv_buffers_init();
733
    __pktbuf_init();
734
 
735
    // Initialize network device(s).
736
#if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1)
737
    default_index = net_devindex(default_devname);
738
    if (default_index < 0)
739
        default_index = 0;
740
#ifdef CYGSEM_REDBOOT_NETWORK_INIT_ONE_DEVICE
741
    if ((t = net_devtab_entry(default_index)) != NULL && t->init(t)) {
742
        t->status = CYG_NETDEVTAB_STATUS_AVAIL;
743
        primary_net = __local_enet_sc;
744
    } else
745
#endif
746
#endif // (CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1)
747
    for (index = 0; (t = net_devtab_entry(index)) != NULL; index++) {
748
#ifdef CYGSEM_REDBOOT_NETWORK_INIT_ONE_DEVICE
749
        if (index == default_index)
750
            continue;
751
#endif
752
        if (t->init(t)) {
753
            t->status = CYG_NETDEVTAB_STATUS_AVAIL;
754
            if (primary_net == (struct eth_drv_sc *)0) {
755
                primary_net = __local_enet_sc;
756
            }
757
#if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1)
758
#   ifdef CYGSEM_REDBOOT_NETWORK_INIT_ONE_DEVICE
759
            break;
760
#   else
761
            if (index == default_index) {
762
                primary_net = __local_enet_sc;
763
            }
764
#   endif // CYGSEM_REDBOOT_NETWORK_INIT_ONE_DEVICE
765
#endif
766
        }
767
    }
768
    __local_enet_sc = primary_net;
769
 
770
    if (!__local_enet_sc) {
771
        diag_printf("No network interfaces found\n");
772
        return;
773
    }
774
    // Initialize the network [if present]
775
#ifdef CYGPKG_REDBOOT_NETWORKING_BOOTP
776
    if (use_bootp) {
777
        if (__bootp_find_local_ip(&my_bootp_info) == 0) {
778
            have_net = true;
779
        } else {
780
            // Is it an unset address, or has it been set to a static addr
781
            if (__local_ip_addr[0] == 0 && __local_ip_addr[1] == 0 &&
782
                __local_ip_addr[2] == 0 && __local_ip_addr[3] == 0) {
783
                show_eth_info();
784
                diag_printf("Can't get BOOTP info for device!\n");
785
            } else {
786
                diag_printf("Can't get BOOTP info, using default IP address\n");
787
                have_net = true;
788
            }
789
        }
790
    }
791
#endif
792
    if (!use_bootp) {
793
        if (__local_ip_addr[0] == 0 && __local_ip_addr[1] == 0 &&
794
            __local_ip_addr[2] == 0 && __local_ip_addr[3] == 0) {
795
            show_eth_info();
796
            diag_printf("No IP info for device!\n");
797
        } else {
798
            enet_addr_t enet_addr;
799
            have_net = true;  // Assume values in FLASH were OK
800
            // Tell the world that we are using this fixed IP address
801
            if (__arp_request((ip_addr_t *)__local_ip_addr, &enet_addr, 1) >= 0) {
802
                diag_printf("Warning: IP address %s in use\n", inet_ntoa((in_addr_t *)&__local_ip_addr));
803
            }
804
        }
805
    }
806
    if (have_net) {
807
        show_eth_info();
808
#ifdef CYGDAT_REDBOOT_DEFAULT_BOOTP_SERVER_IP_ADDR
809
        diag_sprintf(ip_addr, "%d.%d.%d.%d",
810
                     CYGDAT_REDBOOT_DEFAULT_BOOTP_SERVER_IP_ADDR);
811
        inet_aton(ip_addr, &my_bootp_info.bp_siaddr);
812
#endif
813
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
814
        flash_get_IP("bootp_server_ip", (ip_addr_t *)&my_bootp_info.bp_siaddr);
815
#endif
816
#ifdef CYGPKG_REDBOOT_NETWORKING_DNS
817
        redboot_dns_res_init();
818
#endif
819
        show_addrs();
820
        net_io_init();
821
    }
822
}
823
 
824
static char usage[] = ""
825
#ifdef CYGPKG_REDBOOT_NETWORKING_BOOTP
826
       " [-b]"
827
#endif
828
       " [-l <local_ip_address>[/<mask_len>]] [-h <server_address>]"
829
#ifdef CYGPKG_REDBOOT_NETWORKING_DNS
830
        " [-d <dns_server_address>]"
831
#ifdef CYGPKG_REDBOOT_NETWORKING_DNS_FCONFIG_DOMAIN                                                  
832
        " [-D <dns_domain_name>]"
833
#endif
834
#endif
835
        ;
836
 
837
// Exported CLI function
838
static void do_ip_addr(int argc, char *argv[]);
839
RedBoot_cmd("ip_address",
840
            "Set/change IP addresses",
841
            usage,
842
            do_ip_addr
843
    );
844
 
845
void
846
do_ip_addr(int argc, char *argv[])
847
{
848
    struct option_info opts[5];
849
    char *ip_addr, *host_addr;
850
    bool ip_addr_set, host_addr_set;
851
#ifdef CYGPKG_REDBOOT_NETWORKING_BOOTP
852
    bool do_bootp = false;
853
#endif
854
    struct sockaddr_in host;
855
#ifdef CYGPKG_REDBOOT_NETWORKING_DNS
856
    char *dns_addr;
857
    bool dns_addr_set;
858
#ifdef CYGPKG_REDBOOT_NETWORKING_DNS_FCONFIG_DOMAIN 
859
    char *dns_domain;
860
    bool dns_domain_set;
861
#endif
862
#endif
863
    int num_opts;
864
 
865
    if (!have_net) {
866
        diag_printf("Sorry, networking is not available.\n");
867
        return;
868
    }
869
 
870
    init_opts(&opts[0], 'l', true, OPTION_ARG_TYPE_STR,
871
              (void *)&ip_addr, (bool *)&ip_addr_set, "local IP address");
872
    init_opts(&opts[1], 'h', true, OPTION_ARG_TYPE_STR,
873
              (void *)&host_addr, (bool *)&host_addr_set, "default server address");
874
    num_opts = 2;
875
#ifdef CYGPKG_REDBOOT_NETWORKING_BOOTP
876
    init_opts(&opts[2], 'b', false, OPTION_ARG_TYPE_FLG,
877
              &do_bootp, 0, "use BOOTP");
878
    num_opts++;
879
#endif
880
#ifdef CYGPKG_REDBOOT_NETWORKING_DNS
881
    init_opts(&opts[num_opts], 'd', true, OPTION_ARG_TYPE_STR,
882
              (void *)&dns_addr, (bool *)&dns_addr_set, "DNS server address");
883
    num_opts++;
884
#ifdef CYGPKG_REDBOOT_NETWORKING_DNS_FCONFIG_DOMAIN 
885
    init_opts(&opts[num_opts], 'D', true, OPTION_ARG_TYPE_STR,
886
              (void *)&dns_domain, (bool *)&dns_domain_set, "DNS domain");
887
    num_opts++;
888
#endif
889
#endif
890
    CYG_ASSERT(num_opts <= NUM_ELEMS(opts), "Too many options");
891
 
892
    if (!scan_opts(argc, argv, 1, opts, num_opts, 0, 0, "")) {
893
        return;
894
    }
895
#ifdef CYGPKG_REDBOOT_NETWORKING_BOOTP
896
    if (do_bootp) {
897
        if (__bootp_find_local_ip(&my_bootp_info) != 0) {
898
            diag_printf("Failed to get BOOTP address\n");
899
        }
900
    }
901
#endif
902
    if (ip_addr_set) {
903
#ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY
904
        char *slash_pos;
905
        /* see if the (optional) mask length was given */
906
        if( (slash_pos = strchr(ip_addr, '/')) ) {
907
            unsigned long mask, mask_len;
908
            *slash_pos = '\0';
909
            slash_pos++;
910
            if( !parse_num(slash_pos, &mask_len, 0, 0) ||
911
                mask_len == 0 || mask_len > 32 ) {
912
                diag_printf("Invalid mask length: %s\n", slash_pos);
913
                return;
914
            }
915
            mask = htonl((0xffffffff << (32-mask_len))&0xffffffff);
916
            memcpy(&__local_ip_mask, &mask, 4);
917
        }
918
#endif        
919
        if (!_gethostbyname(ip_addr, (in_addr_t *)&host)) {
920
            diag_printf("Invalid local IP address: %s\n", ip_addr);
921
            return;
922
        }
923
        // Of course, each address goes in its own place :-)
924
        memcpy(&__local_ip_addr, &host.sin_addr, sizeof(host.sin_addr));
925
    }
926
    if (host_addr_set) {
927
        if (!_gethostbyname(host_addr, (in_addr_t *)&host)) {
928
            diag_printf("Invalid server address: %s\n", host_addr);
929
            return;
930
        }
931
        my_bootp_info.bp_siaddr = host.sin_addr;
932
    }
933
#ifdef CYGPKG_REDBOOT_NETWORKING_DNS
934
    if (dns_addr_set) {
935
        set_dns(dns_addr);
936
    }
937
#ifdef CYGPKG_REDBOOT_NETWORKING_DNS_FCONFIG_DOMAIN 
938
    if (dns_domain_set) {
939
      setdomainname(dns_domain, strlen(dns_domain));
940
    }
941
#endif
942
#endif
943
    show_addrs();
944
    if (!have_net) {
945
        have_net = true;
946
        net_io_init();
947
    }
948
}
949
 
950
// EOF net_io.c

powered by: WebSVN 2.1.0

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