Beispiel #1
0
static void nc_send_packet(const char *buf, int len)
{
#ifdef CONFIG_DM_ETH
	struct udevice *eth;
#else
	struct eth_device *eth;
#endif
	int inited = 0;
	uchar *pkt;
	uchar *ether;
	struct in_addr ip;

	debug_cond(DEBUG_DEV_PKT, "output: \"%*.*s\"\n", len, len, buf);

	eth = eth_get_dev();
	if (eth == NULL)
		return;

	if (!memcmp(nc_ether, net_null_ethaddr, 6)) {
		if (eth_is_active(eth))
			return;	/* inside net loop */
		output_packet = buf;
		output_packet_len = len;
		input_recursion = 1;
		net_loop(NETCONS); /* wait for arp reply and send packet */
		input_recursion = 0;
		output_packet_len = 0;
		return;
	}

	if (!eth_is_active(eth)) {
		if (eth_is_on_demand_init()) {
			if (eth_init() < 0)
				return;
			eth_set_last_protocol(NETCONS);
		} else {
			eth_init_state_only();
		}

		inited = 1;
	}
	pkt = (uchar *)net_tx_packet + net_eth_hdr_size() + IP_UDP_HDR_SIZE;
	memcpy(pkt, buf, len);
	ether = nc_ether;
	ip = nc_ip;
	net_send_udp_packet(ether, ip, nc_out_port, nc_in_port, len);

	if (inited) {
		if (eth_is_on_demand_init())
			eth_halt();
		else
			eth_halt_state_only();
	}
}
Beispiel #2
0
int bootme_send_frame(const void *buf, size_t len)
{
	int ret;
	struct eth_device *eth;
	int inited = 0;
	uchar *pkt;

	eth = eth_get_dev();
	if (eth == NULL)
		return -EINVAL;

	if (bootme_state == BOOTME_INIT)
		check_net_config();

	debug("%s: buf: %p len: %u from %pI4:%d to %pI4:%d\n",
		__func__, buf, len, &NetOurIP, bootme_src_port, &bootme_ip, bootme_dst_port);

	if (memcmp(bootme_ether, NetEtherNullAddr, ETH_ALEN) == 0) {
		if (eth->state == ETH_STATE_ACTIVE)
			return 0;	/* inside net loop */

		output_packet = buf;
		output_packet_len = len;
		/* wait for arp reply and send packet */
		ret = NetLoop(BOOTME);
		if (ret < 0) {
			/* drop packet */
			output_packet_len = 0;
			return ret;
		}
		if (bootme_timed_out)
			return -ETIMEDOUT;
		return 0;
	}

	if (eth->state != ETH_STATE_ACTIVE) {
		if (eth_is_on_demand_init()) {
			ret = eth_init(gd->bd);
			if (ret < 0)
				return ret;
			eth_set_last_protocol(BOOTME);
		} else {
			eth_init_state_only(gd->bd);
		}
		inited = 1;
	}

	assert(NetTxPacket != NULL);
	pkt = (uchar *)NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE;
	memcpy(pkt, buf, len);

	ret = NetSendUDPPacket(bootme_ether, bootme_ip, bootme_dst_port,
			bootme_src_port, len);
	if (inited) {
		debug("Stopping network\n");
		if (eth_is_on_demand_init())
			eth_halt();
		else
			eth_halt_state_only();
	}
	return ret;
}
Beispiel #3
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;
}
Beispiel #4
0
int NetLoop(enum proto_t protocol)
{
	bd_t *bd = gd->bd;
	int ret = -1;

	NetRestarted = 0;
	NetDevExists = 0;
	NetTryCount = 1;
	debug_cond(DEBUG_INT_STATE, "--- NetLoop 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();
		if (eth_init(bd) < 0) {
			eth_halt();
			return -1;
		}
	} else
		eth_init_state_only(bd);

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, "--- NetLoop Init\n");
	NetInitLoop();

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

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

	case 0:
		NetDevExists = 1;
		NetBootFileXferSize = 0;
		switch (protocol) {
		case TFTPGET:
#ifdef CONFIG_CMD_TFTPPUT
		case TFTPPUT:
#endif
			/* always use ARP to get server ethernet address */
			TftpStart(protocol);
			break;
#ifdef CONFIG_CMD_TFTPSRV
		case TFTPSRV:
			TftpStartServer();
			break;
#endif
#if defined(CONFIG_CMD_DHCP)
		case DHCP:
			BootpReset();
			NetOurIP = 0;
			DhcpRequest();		/* Basically same as BOOTP */
			break;
#endif

		case BOOTP:
			BootpReset();
			NetOurIP = 0;
			BootpRequest();
			break;

#if defined(CONFIG_CMD_RARP)
		case RARP:
			RarpTry = 0;
			NetOurIP = 0;
			RarpRequest();
			break;
#endif
#if defined(CONFIG_CMD_PING)
		case PING:
			ping_start();
			break;
#endif
#if defined(CONFIG_CMD_NFS)
		case NFS:
			NfsStart();
			break;
#endif
#if defined(CONFIG_CMD_CDP)
		case CDP:
			CDPStart();
			break;
#endif
#if defined (CONFIG_NETCONSOLE) && !(CONFIG_SPL_BUILD)
		case NETCONS:
			NcStart();
			break;
#endif
#if defined(CONFIG_CMD_SNTP)
		case SNTP:
			SntpStart();
			break;
#endif
#if defined(CONFIG_CMD_DNS)
		case DNS:
			DnsStart();
			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
		/*
		 *	Check the ethernet for a new packet.  The ethernet
		 *	receive routine will process it.
		 */
		eth_rx();

		/*
		 *	Abort if ctrl-c was pressed.
		 */
		if (ctrlc()) {
			/* cancel any ARP that may not have completed */
			NetArpWaitPacketIP = 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, "--- NetLoop Abort!\n");
			goto done;
		}

		ArpTimeoutCheck();

		/*
		 *	Check for a timeout, and run the timeout handler
		 *	if we have one.
		 */
		if (timeHandler && ((get_timer(0) - timeStart) > timeDelta)) {
			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, "--- NetLoop timeout\n");
			x = timeHandler;
			timeHandler = (thand_f *)0;
			(*x)();
		}


		switch (net_state) {

		case NETLOOP_RESTART:
			NetRestarted = 1;
			goto restart;

		case NETLOOP_SUCCESS:
			net_cleanup_loop();
			if (NetBootFileXferSize > 0) {
				printf("Bytes transferred = %ld (%lx hex)\n",
					NetBootFileXferSize,
					NetBootFileXferSize);
				setenv_hex("filesize", NetBootFileXferSize);
				setenv_hex("fileaddr", load_addr);
			}
			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;

		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;
}