Hi Mike, On Fri, Aug 3, 2012 at 3:59 PM, Joe Hershberger <joe.hershber...@ni.com> wrote: > Previously u-boot would initialize the network interface for every > network operation and then shut it down again. This makes sense for > most operations where the network in not known to be needed soon after > the operation is complete. In the case of netconsole, it will use the > network for every interaction with the shell or every printf. This > means that the network is being reinitialized very often. On many > devices, this intialization is very slow. > > This patch checks for consecutive netconsole actions and leaves the > ethernet hardware initialized between them. It will still behave the > same old way for all other network operations and any time another > network operation happens between netconsole operations. > > Signed-off-by: Joe Hershberger <joe.hershber...@ni.com> > Cc: Stefano Babic <sba...@denx.de>
Sorry I forgot to Cc you on the update... I also forgot the revision notes... Changes since v1: - Halt Ethernet stack before booting Linux - Clean up CPP guard noise - Reduce overhead of no-re-init case > --- > common/cmd_bootm.c | 17 +++++++++++++++++ > drivers/net/netconsole.c | 22 ++++++++++++++++++---- > include/net.h | 42 +++++++++++++++++++++++++++++++++++++++++- > net/eth.c | 8 ++------ > net/net.c | 26 ++++++++++++++++++++------ > 5 files changed, 98 insertions(+), 17 deletions(-) > > diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c > index 45e726a..83fa5d7 100644 > --- a/common/cmd_bootm.c > +++ b/common/cmd_bootm.c > @@ -564,6 +564,13 @@ int do_bootm_subcommand(cmd_tbl_t *cmdtp, int flag, int > argc, > break; > case BOOTM_STATE_OS_GO: > disable_interrupts(); > +#ifdef CONFIG_NETCONSOLE > + /* > + * Stop the ethernet stack if NetConsole could have > + * left it up > + */ > + eth_halt(); > +#endif > arch_preboot_os(); > boot_fn(BOOTM_STATE_OS_GO, argc, argv, &images); > break; > @@ -622,6 +629,11 @@ int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char > * const argv[]) > */ > iflag = disable_interrupts(); > > +#ifdef CONFIG_NETCONSOLE > + /* Stop the ethernet stack if NetConsole could have left it up */ > + eth_halt(); > +#endif > + > #if defined(CONFIG_CMD_USB) > /* > * turn off USB to prevent the host controller from writing to the > @@ -1599,6 +1611,11 @@ static int do_bootz(cmd_tbl_t *cmdtp, int flag, int > argc, char * const argv[]) > */ > disable_interrupts(); > > +#ifdef CONFIG_NETCONSOLE > + /* Stop the ethernet stack if NetConsole could have left it up */ > + eth_halt(); > +#endif > + > #if defined(CONFIG_CMD_USB) > /* > * turn off USB to prevent the host controller from writing to the > diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c > index 14243b8..069ad87 100644 > --- a/drivers/net/netconsole.c > +++ b/drivers/net/netconsole.c > @@ -39,6 +39,11 @@ static IPaddr_t nc_ip; /* server ip */ > static short nc_port; /* source/target port */ > static const char *output_packet; /* used by first send udp */ > static int output_packet_len; > +/* > + * Start with a default last protocol. > + * We are only interested in NETCONS or not. > + */ > +enum proto_t net_loop_last_protocol = BOOTP; > > static void nc_wait_arp_handler(uchar *pkt, unsigned dest, > IPaddr_t sip, unsigned src, > @@ -131,8 +136,13 @@ static void nc_send_packet(const char *buf, int len) > } > > if (eth->state != ETH_STATE_ACTIVE) { > - if (eth_init(gd->bd) < 0) > - return; > + if (eth_is_on_demand_init()) { > + if (eth_init(gd->bd) < 0) > + return; > + eth_set_last_protocol(NETCONS); > + } else > + eth_init_state_only(gd->bd); > + > inited = 1; > } > pkt = (uchar *)NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE; > @@ -141,8 +151,12 @@ static void nc_send_packet(const char *buf, int len) > ip = nc_ip; > NetSendUDPPacket(ether, ip, nc_port, nc_port, len); > > - if (inited) > - eth_halt(); > + if (inited) { > + if (eth_is_on_demand_init()) > + eth_halt(); > + else > + eth_halt_state_only(); > + } > } > > static int nc_start(void) > diff --git a/include/net.h b/include/net.h > index 6d2d6cd..e193b7b 100644 > --- a/include/net.h > +++ b/include/net.h > @@ -102,7 +102,14 @@ extern int eth_register(struct eth_device* dev);/* > Register network device */ > extern int eth_unregister(struct eth_device *dev);/* Remove network device */ > extern void eth_try_another(int first_restart); /* Change the device > */ > extern void eth_set_current(void); /* set nterface to ethcur var > */ > -extern struct eth_device *eth_get_dev(void); /* get the current device MAC > */ > +/* get the current device MAC */ > +static inline __attribute__((always_inline)) > +struct eth_device *eth_get_dev(void) > +{ > + extern struct eth_device *eth_current; > + > + return eth_current; > +} > extern struct eth_device *eth_get_dev_by_name(const char *devname); > extern struct eth_device *eth_get_dev_by_index(int index); /* get dev @ > index */ > extern int eth_get_dev_index(void); /* get the device index */ > @@ -151,6 +158,19 @@ extern int eth_rx(void); /* Check for > received packets */ > extern void eth_halt(void); /* stop SCC */ > extern char *eth_get_name(void); /* get name of current device > */ > > +/* Set active state */ > +static inline __attribute__((always_inline)) int eth_init_state_only(bd_t > *bis) > +{ > + eth_get_dev()->state = ETH_STATE_ACTIVE; > + > + return 0; > +} > +/* Set passive state */ > +static inline __attribute__((always_inline)) void eth_halt_state_only(void) > +{ > + eth_get_dev()->state = ETH_STATE_PASSIVE; > +} > + > /* > * Set the hardware address for an ethernet interface based on 'eth%daddr' > * environment variable (or just 'ethaddr' if eth_number is 0). > @@ -532,6 +552,26 @@ void NcStart(void); > int nc_input_packet(uchar *pkt, unsigned dest, unsigned src, unsigned len); > #endif > > +static inline __attribute__((always_inline)) int eth_is_on_demand_init(void) > +{ > +#ifdef CONFIG_NETCONSOLE > + extern enum proto_t net_loop_last_protocol; > + > + return net_loop_last_protocol != NETCONS; > +#else > + return 1; > +#endif > +} > + > +static inline void eth_set_last_protocol(int protocol) > +{ > +#ifdef CONFIG_NETCONSOLE > + extern enum proto_t net_loop_last_protocol; > + > + net_loop_last_protocol = protocol; > +#endif > +} > + > /* > * Check if autoload is enabled. If so, use either NFS or TFTP to download > * the boot file. > diff --git a/net/eth.c b/net/eth.c > index 1a11ce1..66295b6 100644 > --- a/net/eth.c > +++ b/net/eth.c > @@ -121,12 +121,8 @@ static struct { > static unsigned int eth_rcv_current, eth_rcv_last; > #endif > > -static struct eth_device *eth_devices, *eth_current; > - > -struct eth_device *eth_get_dev(void) > -{ > - return eth_current; > -} > +static struct eth_device *eth_devices; > +struct eth_device *eth_current; > > struct eth_device *eth_get_dev_by_name(const char *devname) > { > diff --git a/net/net.c b/net/net.c > index e8ff066..f002cda 100644 > --- a/net/net.c > +++ b/net/net.c > @@ -315,12 +315,15 @@ int NetLoop(enum proto_t protocol) > > bootstage_mark_name(BOOTSTAGE_ID_ETH_START, "eth_start"); > net_init(); > - eth_halt(); > - eth_set_current(); > - if (eth_init(bd) < 0) { > + if (eth_is_on_demand_init() || protocol != NETCONS) { > eth_halt(); > - return -1; > - } > + eth_set_current(); > + if (eth_init(bd) < 0) { > + eth_halt(); > + return -1; > + } > + } else > + eth_init_state_only(bd); > > restart: > net_set_state(NETLOOP_CONTINUE); > @@ -460,6 +463,9 @@ restart: > > net_cleanup_loop(); > eth_halt(); > + /* Invalidate the last protocol */ > + eth_set_last_protocol(BOOTP); > + > puts("\nAbort\n"); > /* include a debug print as well incase the debug > messages are directed to stderr */ > @@ -517,13 +523,21 @@ restart: > sprintf(buf, "%lX", (unsigned long)load_addr); > setenv("fileaddr", buf); > } > - eth_halt(); > + if (protocol != NETCONS) > + eth_halt(); > + else > + eth_halt_state_only(); > + > + eth_set_last_protocol(protocol); > + > ret = NetBootFileXferSize; > debug_cond(DEBUG_INT_STATE, "--- NetLoop Success!\n"); > goto done; > > case NETLOOP_FAIL: > net_cleanup_loop(); > + /* Invalidate the last protocol */ > + eth_set_last_protocol(BOOTP); > debug_cond(DEBUG_INT_STATE, "--- NetLoop Fail!\n"); > goto done; > > -- > 1.6.0.2 > > _______________________________________________ > U-Boot mailing list > U-Boot@lists.denx.de > http://lists.denx.de/mailman/listinfo/u-boot _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot