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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [ecos-2.0/] [packages/] [redboot/] [v2_0/] [src/] [net/] [net_io.c] - Blame information for rev 1773

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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