Пример #1
0
static int do_dhcp(struct command *cmdtp, int argc, char *argv[])
{
	int ret;

	dhcp_con = net_udp_new(0xffffffff, PORT_BOOTPS, dhcp_handler, NULL);
	if (IS_ERR(dhcp_con)) {
		ret = PTR_ERR(dhcp_con);
		goto out;
	}

	ret = net_udp_bind(dhcp_con, PORT_BOOTPC);
	if (ret)
		goto out1;

	net_set_ip(0);

	ret = bootp_request(); /* Basically same as BOOTP */
	if (ret)
		goto out1;

	while (dhcp_state != BOUND) {
		if (ctrlc())
			break;
		net_poll();
		if (is_timeout(dhcp_start, 3 * SECOND)) {
			dhcp_start = get_time_ns();
			printf("T ");
			ret = bootp_request();
			if (ret)
				goto out1;
		}
	}

out1:
	net_unregister(dhcp_con);
out:
	if (ret)
		printf("dhcp failed: %s\n", strerror(-ret));

	return ret ? 1 : 0;
}
Пример #2
0
/*
 *	Timeout on BOOTP/DHCP request.
 */
static void bootp_timeout_handler(void)
{
	ulong time_taken = get_timer(bootp_start);

	if (time_taken >= TIMEOUT_MS) {
#ifdef CONFIG_BOOTP_MAY_FAIL
		puts("\nRetry time exceeded\n");
		net_set_state(NETLOOP_FAIL);
#else
		puts("\nRetry time exceeded; starting again\n");
		net_start_again();
#endif
	} else {
		bootp_timeout *= 2;
		if (bootp_timeout > 2000)
			bootp_timeout = 2000;
		net_set_timeout_handler(bootp_timeout, bootp_timeout_handler);
		bootp_request();
	}
}
Пример #3
0
static int do_dhcp(int argc, char *argv[])
{
	int ret, opt;
	int retries = DHCP_DEFAULT_RETRY;

	dhcp_reset_env();

	getenv_uint("global.dhcp.retries", &retries);

	while((opt = getopt(argc, argv, "H:v:c:u:U:r:")) > 0) {
		switch(opt) {
		case 'H':
			dhcp_set_param_data(DHCP_HOSTNAME, optarg);
			break;
		case 'v':
			dhcp_set_param_data(DHCP_VENDOR_ID, optarg);
			break;
		case 'c':
			dhcp_set_param_data(DHCP_CLIENT_ID, optarg);
			break;
		case 'u':
			dhcp_set_param_data(DHCP_CLIENT_UUID, optarg);
			break;
		case 'U':
			dhcp_set_param_data(DHCP_USER_CLASS, optarg);
			break;
		case 'r':
			retries = simple_strtoul(optarg, NULL, 10);
			break;
		}
	}

	if (!retries) {
		printf("retries is set to zero, set it to %d\n", DHCP_DEFAULT_RETRY);
		retries = DHCP_DEFAULT_RETRY;
	}

	dhcp_con = net_udp_new(0xffffffff, PORT_BOOTPS, dhcp_handler, NULL);
	if (IS_ERR(dhcp_con)) {
		ret = PTR_ERR(dhcp_con);
		goto out;
	}

	ret = net_udp_bind(dhcp_con, PORT_BOOTPC);
	if (ret)
		goto out1;

	net_set_ip(0);

	dhcp_start = get_time_ns();
	ret = bootp_request(); /* Basically same as BOOTP */
	if (ret)
		goto out1;

	while (dhcp_state != BOUND) {
		if (ctrlc()) {
			ret = -EINTR;
			goto out1;
		}
		if (!retries) {
			ret = -ETIMEDOUT;
			goto out1;
		}
		net_poll();
		if (is_timeout(dhcp_start, 3 * SECOND)) {
			dhcp_start = get_time_ns();
			printf("T ");
			ret = bootp_request();
			/* no need to check if retries > 0 as we check if != 0 */
			retries--;
			if (ret)
				goto out1;
		}
	}

	if (dhcp_tftpname[0] != 0) {
		IPaddr_t tftpserver = resolv(dhcp_tftpname);
		if (tftpserver)
			net_set_serverip(tftpserver);
	}

out1:
	net_unregister(dhcp_con);
out:
	if (ret)
		printf("dhcp failed: %s\n", strerror(-ret));

	return ret;
}
Пример #4
0
int net_loop(enum proto_t protocol)
{
	int ret = -EINVAL;

	net_restarted = 0;
	net_dev_exists = 0;
	net_try_count = 1;
	debug_cond(DEBUG_INT_STATE, "--- net_loop Entry\n");

	bootstage_mark_name(BOOTSTAGE_ID_ETH_START, "eth_start");
	net_init();
	if (eth_is_on_demand_init() || protocol != NETCONS) {
		eth_halt();
		eth_set_current();
		ret = eth_init();
		if (ret < 0) {
			eth_halt();
			return ret;
		}
	} else {
		eth_init_state_only();
	}
restart:
#ifdef CONFIG_USB_KEYBOARD
	net_busy_flag = 0;
#endif
	net_set_state(NETLOOP_CONTINUE);

	/*
	 *	Start the ball rolling with the given start function.  From
	 *	here on, this code is a state machine driven by received
	 *	packets and timer events.
	 */
	debug_cond(DEBUG_INT_STATE, "--- net_loop Init\n");
	net_init_loop();

	switch (net_check_prereq(protocol)) {
	case 1:
		/* network not configured */
		eth_halt();
		return -ENODEV;

	case 2:
		/* network device not configured */
		break;

	case 0:
		net_dev_exists = 1;
		net_boot_file_size = 0;
		switch (protocol) {
		case TFTPGET:
#ifdef CONFIG_CMD_TFTPPUT
		case TFTPPUT:
#endif
			/* always use ARP to get server ethernet address */
			tftp_start(protocol);
			break;
#ifdef CONFIG_CMD_TFTPSRV
		case TFTPSRV:
			tftp_start_server();
			break;
#endif
#if defined(CONFIG_CMD_DHCP)
		case DHCP:
			bootp_reset();
			net_ip.s_addr = 0;
			dhcp_request();		/* Basically same as BOOTP */
			break;
#endif

		case BOOTP:
			bootp_reset();
			net_ip.s_addr = 0;
			bootp_request();
			break;

#if defined(CONFIG_CMD_RARP)
		case RARP:
			rarp_try = 0;
			net_ip.s_addr = 0;
			rarp_request();
			break;
#endif
#if defined(CONFIG_CMD_PING)
		case PING:
			ping_start();
			break;
#endif
#if defined(CONFIG_CMD_NFS)
		case NFS:
			nfs_start();
			break;
#endif
#if defined(CONFIG_CMD_CDP)
		case CDP:
			cdp_start();
			break;
#endif
#if defined(CONFIG_NETCONSOLE) && !(CONFIG_SPL_BUILD)
		case NETCONS:
			nc_start();
			break;
#endif
#if defined(CONFIG_CMD_SNTP)
		case SNTP:
			sntp_start();
			break;
#endif
#if defined(CONFIG_CMD_DNS)
		case DNS:
			dns_start();
			break;
#endif
#if defined(CONFIG_CMD_LINK_LOCAL)
		case LINKLOCAL:
			link_local_start();
			break;
#endif
		default:
			break;
		}

		break;
	}

#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
#if	defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN)	&& \
	defined(CONFIG_STATUS_LED)			&& \
	defined(STATUS_LED_RED)
	/*
	 * Echo the inverted link state to the fault LED.
	 */
	if (miiphy_link(eth_get_dev()->name, CONFIG_SYS_FAULT_MII_ADDR))
		status_led_set(STATUS_LED_RED, STATUS_LED_OFF);
	else
		status_led_set(STATUS_LED_RED, STATUS_LED_ON);
#endif /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */
#endif /* CONFIG_MII, ... */
#ifdef CONFIG_USB_KEYBOARD
	net_busy_flag = 1;
#endif

	/*
	 *	Main packet reception loop.  Loop receiving packets until
	 *	someone sets `net_state' to a state that terminates.
	 */
	for (;;) {
		WATCHDOG_RESET();
#ifdef CONFIG_SHOW_ACTIVITY
		show_activity(1);
#endif
		if (arp_timeout_check() > 0)
			time_start = get_timer(0);

		/*
		 *	Check the ethernet for a new packet.  The ethernet
		 *	receive routine will process it.
		 *	Most drivers return the most recent packet size, but not
		 *	errors that may have happened.
		 */
		eth_rx();

		/*
		 *	Abort if ctrl-c was pressed.
		 */
		if (ctrlc()) {
			/* cancel any ARP that may not have completed */
			net_arp_wait_packet_ip.s_addr = 0;

			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 */
			debug_cond(DEBUG_INT_STATE, "--- net_loop Abort!\n");
			ret = -EINTR;
			goto done;
		}

		/*
		 *	Check for a timeout, and run the timeout handler
		 *	if we have one.
		 */
		if (time_handler &&
		    ((get_timer(0) - time_start) > time_delta)) {
			thand_f *x;

#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
#if	defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN)	&& \
	defined(CONFIG_STATUS_LED)			&& \
	defined(STATUS_LED_RED)
			/*
			 * Echo the inverted link state to the fault LED.
			 */
			if (miiphy_link(eth_get_dev()->name,
					CONFIG_SYS_FAULT_MII_ADDR))
				status_led_set(STATUS_LED_RED, STATUS_LED_OFF);
			else
				status_led_set(STATUS_LED_RED, STATUS_LED_ON);
#endif /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */
#endif /* CONFIG_MII, ... */
			debug_cond(DEBUG_INT_STATE, "--- net_loop timeout\n");
			x = time_handler;
			time_handler = (thand_f *)0;
			(*x)();
		}

		if (net_state == NETLOOP_FAIL)
			ret = net_start_again();

		switch (net_state) {
		case NETLOOP_RESTART:
			net_restarted = 1;
			goto restart;

		case NETLOOP_SUCCESS:
			net_cleanup_loop();
			if (net_boot_file_size > 0) {
				printf("Bytes transferred = %d (%x hex)\n",
				       net_boot_file_size, net_boot_file_size);
				setenv_hex("filesize", net_boot_file_size);
				setenv_hex("fileaddr", load_addr);
			}
			if (protocol != NETCONS)
				eth_halt();
			else
				eth_halt_state_only();

			eth_set_last_protocol(protocol);

			ret = net_boot_file_size;
			debug_cond(DEBUG_INT_STATE, "--- net_loop Success!\n");
			goto done;

		case NETLOOP_FAIL:
			net_cleanup_loop();
			/* Invalidate the last protocol */
			eth_set_last_protocol(BOOTP);
			debug_cond(DEBUG_INT_STATE, "--- net_loop Fail!\n");
			goto done;

		case NETLOOP_CONTINUE:
			continue;
		}
	}

done:
#ifdef CONFIG_USB_KEYBOARD
	net_busy_flag = 0;
#endif
#ifdef CONFIG_CMD_TFTPPUT
	/* Clear out the handlers */
	net_set_udp_handler(NULL);
	net_set_icmp_handler(NULL);
#endif
	return ret;
}
Пример #5
0
static int do_dhcp(int argc, char *argv[])
{
	int ret, opt;

	dhcp_reset_env();

	while((opt = getopt(argc, argv, "H:v:c:u:U:")) > 0) {
		switch(opt) {
		case 'H':
			dhcp_set_param_data(DHCP_HOSTNAME, optarg);
			break;
		case 'v':
			dhcp_set_param_data(DHCP_VENDOR_ID, optarg);
			break;
		case 'c':
			dhcp_set_param_data(DHCP_CLIENT_ID, optarg);
			break;
		case 'u':
			dhcp_set_param_data(DHCP_CLIENT_UUID, optarg);
			break;
		case 'U':
			dhcp_set_param_data(DHCP_USER_CLASS, optarg);
			break;
		}
	}

	dhcp_con = net_udp_new(0xffffffff, PORT_BOOTPS, dhcp_handler, NULL);
	if (IS_ERR(dhcp_con)) {
		ret = PTR_ERR(dhcp_con);
		goto out;
	}

	ret = net_udp_bind(dhcp_con, PORT_BOOTPC);
	if (ret)
		goto out1;

	net_set_ip(0);

	dhcp_start = get_time_ns();
	ret = bootp_request(); /* Basically same as BOOTP */
	if (ret)
		goto out1;

	while (dhcp_state != BOUND) {
		if (ctrlc())
			break;
		net_poll();
		if (is_timeout(dhcp_start, 3 * SECOND)) {
			dhcp_start = get_time_ns();
			printf("T ");
			ret = bootp_request();
			if (ret)
				goto out1;
		}
	}

out1:
	net_unregister(dhcp_con);
out:
	if (ret)
		printf("dhcp failed: %s\n", strerror(-ret));

	return ret ? 1 : 0;
}
Пример #6
0
int dhcp(int retries, struct dhcp_req_param *param)
{
	int ret = 0;

	dhcp_reset_env();

	dhcp_set_param_data(DHCP_HOSTNAME, param->hostname);
	dhcp_set_param_data(DHCP_VENDOR_ID, param->vendor_id);
	dhcp_set_param_data(DHCP_CLIENT_ID, param->client_id);
	dhcp_set_param_data(DHCP_USER_CLASS, param->user_class);
	dhcp_set_param_data(DHCP_CLIENT_UUID, param->client_uuid);

	if (!retries)
		retries = DHCP_DEFAULT_RETRY;

	dhcp_con = net_udp_new(0xffffffff, PORT_BOOTPS, dhcp_handler, NULL);
	if (IS_ERR(dhcp_con)) {
		ret = PTR_ERR(dhcp_con);
		goto out;
	}

	ret = net_udp_bind(dhcp_con, PORT_BOOTPC);
	if (ret)
		goto out1;

	net_set_ip(0);

	dhcp_start = get_time_ns();
	ret = bootp_request(); /* Basically same as BOOTP */
	if (ret)
		goto out1;

	while (dhcp_state != BOUND) {
		if (ctrlc()) {
			ret = -EINTR;
			goto out1;
		}
		if (!retries) {
			ret = -ETIMEDOUT;
			goto out1;
		}
		net_poll();
		if (is_timeout(dhcp_start, 3 * SECOND)) {
			dhcp_start = get_time_ns();
			printf("T ");
			ret = bootp_request();
			/* no need to check if retries > 0 as we check if != 0 */
			retries--;
			if (ret)
				goto out1;
		}
	}

	if (dhcp_tftpname[0] != 0) {
		IPaddr_t tftpserver = resolv(dhcp_tftpname);
		if (tftpserver)
			net_set_serverip(tftpserver);
	}

out1:
	net_unregister(dhcp_con);
out:
	if (ret)
		debug("dhcp failed: %s\n", strerror(-ret));

	return ret;
}