diff options
| -rw-r--r-- | common/cmd_bootm.c | 17 | ||||
| -rw-r--r-- | drivers/net/netconsole.c | 22 | ||||
| -rw-r--r-- | include/net.h | 42 | ||||
| -rw-r--r-- | net/eth.c | 8 | ||||
| -rw-r--r-- | net/net.c | 26 | 
5 files changed, 98 insertions, 17 deletions
| diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 45e726af8..83fa5d7bd 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 8fcf31c4e..da82aa94c 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -44,6 +44,11 @@ static short nc_out_port; /* target output port */  static short nc_in_port; /* source input 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, @@ -136,8 +141,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; @@ -146,8 +156,12 @@ static void nc_send_packet(const char *buf, int len)  	ip = nc_ip;  	NetSendUDPPacket(ether, ip, nc_out_port, nc_in_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 6d2d6cd84..e193b7b60 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. @@ -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)  { @@ -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; |