Merge branch 'master' of git://git.denx.de/u-boot-net

This commit is contained in:
Tom Rini 2012-09-27 12:06:07 -07:00
commit cec2655c3b
177 changed files with 1379 additions and 166 deletions

View File

@ -238,7 +238,7 @@ ifdef SOC
LIBS-y += $(CPUDIR)/$(SOC)/lib$(SOC).o
endif
ifeq ($(CPU),ixp)
LIBS-y += arch/arm/cpu/ixp/npe/libnpe.o
LIBS-y += drivers/net/npe/libnpe.o
endif
LIBS-$(CONFIG_OF_EMBED) += dts/libdts.o
LIBS-y += arch/$(ARCH)/lib/lib$(ARCH).o

View File

@ -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

View File

@ -450,6 +450,7 @@ struct pxe_label {
char *kernel;
char *append;
char *initrd;
char *fdt;
int attempted;
int localboot;
struct list_head list;
@ -517,6 +518,9 @@ static void label_destroy(struct pxe_label *label)
if (label->initrd)
free(label->initrd);
if (label->fdt)
free(label->fdt);
free(label);
}
@ -541,6 +545,9 @@ static void label_print(void *data)
if (label->initrd)
printf("\t\tinitrd: %s\n", label->initrd);
if (label->fdt)
printf("\tfdt: %s\n", label->fdt);
}
/*
@ -628,10 +635,29 @@ static void label_boot(struct pxe_label *label)
bootm_argv[1] = getenv("kernel_addr_r");
/*
* fdt usage is optional. If there is an fdt_addr specified, we will
* pass it along to bootm, and adjust argc appropriately.
* fdt usage is optional:
* It handles the following scenarios. All scenarios are exclusive
*
* Scenario 1: If fdt_addr_r specified and "fdt" label is defined in
* pxe file, retrieve fdt blob from server. Pass fdt_addr_r to bootm,
* and adjust argc appropriately.
*
* Scenario 2: If there is an fdt_addr specified, pass it along to
* bootm, and adjust argc appropriately.
*
* Scenario 3: fdt blob is not available.
*/
bootm_argv[3] = getenv("fdt_addr");
bootm_argv[3] = getenv("fdt_addr_r");
/* if fdt label is defined then get fdt from server */
if (bootm_argv[3] && label->fdt) {
if (get_relfile_envaddr(label->fdt, "fdt_addr_r") < 0) {
printf("Skipping %s for failure retrieving fdt\n",
label->name);
return;
}
} else
bootm_argv[3] = getenv("fdt_addr");
if (bootm_argv[3])
bootm_argc = 4;
@ -658,6 +684,7 @@ enum token_type {
T_DEFAULT,
T_PROMPT,
T_INCLUDE,
T_FDT,
T_INVALID
};
@ -685,6 +712,7 @@ static const struct token keywords[] = {
{"append", T_APPEND},
{"initrd", T_INITRD},
{"include", T_INCLUDE},
{"fdt", T_FDT},
{NULL, T_INVALID}
};
@ -1074,6 +1102,11 @@ static int parse_label(char **c, struct pxe_menu *cfg)
err = parse_sliteral(c, &label->initrd);
break;
case T_FDT:
if (!label->fdt)
err = parse_sliteral(c, &label->fdt);
break;
case T_LOCALBOOT:
err = parse_integer(c, &label->localboot);
break;

View File

@ -6,11 +6,16 @@ serial and network input/output devices by adjusting the 'stdin' and
set either of these variables to "nc". Input and output can be
switched independently.
CONFIG_NETCONSOLE_BUFFER_SIZE - Override the default buffer size
We use an environment variable 'ncip' to set the IP address and the
port of the destination. The format is <ip_addr>:<port>. If <port> is
omitted, the value of 6666 is used. If the env var doesn't exist, the
broadcast address and port 6666 are used. If it is set to an IP
address of 0 (or 0.0.0.0) then no messages are sent to the network.
The source / listening port can be configured separately by setting
the 'ncinport' environment variable and the destination port can be
configured by setting the 'ncoutport' environment variable.
For example, if your server IP is 192.168.1.1, you could use:

View File

@ -93,8 +93,13 @@ pxe boot
be passed to the bootm command to boot the kernel. These environment
variables are required to be set.
fdt_addr - the location of a fdt blob. If this is set, it will be passed
to bootm when booting a kernel.
fdt_addr_r - location in RAM at which 'pxe boot' will store the fdt blob it
retrieves from tftp. The retrieval is possible if 'fdt' label is defined in
pxe file and 'fdt_addr_r' is set. If retrieval is possible, 'fdt_addr_r'
will be passed to bootm command to boot the kernel.
fdt_addr - the location of a fdt blob. 'fdt_addr' will be passed to bootm
command if it is set and 'fdt_addr_r' is not passed to bootm command.
pxe file format
===============
@ -156,6 +161,11 @@ initrd <path> - if this label is chosen, use tftp to retrieve the initrd
the initrd_addr_r environment variable, and that address
will be passed to bootm.
fdt <path> - if this label is chosen, use tftp to retrieve the fdt blob
at <path>. it will be stored at the address indicated in
the fdt_addr_r environment variable, and that address will
be passed to bootm.
localboot <flag> - Run the command defined by "localcmd" in the environment.
<flag> is ignored and is only here to match the syntax of
PXELINUX config files.

View File

@ -80,6 +80,7 @@ COBJS-$(CONFIG_XILINX_AXIEMAC) += xilinx_axi_emac.o
COBJS-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o
COBJS-$(CONFIG_XILINX_LL_TEMAC) += xilinx_ll_temac.o xilinx_ll_temac_mdio.o \
xilinx_ll_temac_fifo.o xilinx_ll_temac_sdma.o
COBJS-$(CONFIG_ZYNQ_GEM) += zynq_gem.o
COBJS := $(sort $(COBJS-y))
SRCS := $(COBJS:.o=.c)

View File

@ -565,7 +565,7 @@ static int armdfec_send(struct eth_device *dev, void *dataptr, int datasize)
struct tx_desc *p_txdesc = darmdfec->p_txdesc;
void *p = (void *)dataptr;
int retry = PHY_WAIT_ITERATIONS * PHY_WAIT_MICRO_SECONDS;
u32 cmd_sts;
u32 cmd_sts, temp;
/* Copy buffer if it's misaligned */
if ((u32)dataptr & 0x07) {
@ -586,7 +586,8 @@ static int armdfec_send(struct eth_device *dev, void *dataptr, int datasize)
p_txdesc->byte_cnt = datasize;
/* Apply send command using high priority TX queue */
writel((u32)p_txdesc, &regs->txcdp[TXQ]);
temp = (u32)&regs->txcdp[TXQ];
writel((u32)p_txdesc, temp);
writel(SDMA_CMD_TXDL | SDMA_CMD_TXDH | SDMA_CMD_ERD, &regs->sdma_cmd);
/*

View File

@ -31,9 +31,16 @@
#include <asm/arch/imx-regs.h>
#include <asm/io.h>
#include <asm/errno.h>
#include <linux/compiler.h>
DECLARE_GLOBAL_DATA_PTR;
/*
* Timeout the transfer after 5 mS. This is usually a bit more, since
* the code in the tightloops this timeout is used in adds some overhead.
*/
#define FEC_XFER_TIMEOUT 5000
#ifndef CONFIG_MII
#error "CONFIG_MII has to be defined!"
#endif
@ -249,7 +256,7 @@ static int miiphy_wait_aneg(struct eth_device *dev)
static int fec_rx_task_enable(struct fec_priv *fec)
{
writel(1 << 24, &fec->eth->r_des_active);
writel(FEC_R_DES_ACTIVE_RDAR, &fec->eth->r_des_active);
return 0;
}
@ -260,7 +267,7 @@ static int fec_rx_task_disable(struct fec_priv *fec)
static int fec_tx_task_enable(struct fec_priv *fec)
{
writel(1 << 24, &fec->eth->x_des_active);
writel(FEC_X_DES_ACTIVE_TDAR, &fec->eth->x_des_active);
return 0;
}
@ -694,8 +701,10 @@ static void fec_halt(struct eth_device *dev)
static int fec_send(struct eth_device *dev, void *packet, int length)
{
unsigned int status;
uint32_t size;
uint32_t size, end;
uint32_t addr;
int timeout = FEC_XFER_TIMEOUT;
int ret = 0;
/*
* This routine transmits one frame. This routine only accepts
@ -721,8 +730,9 @@ static int fec_send(struct eth_device *dev, void *packet, int length)
#endif
addr = (uint32_t)packet;
size = roundup(length, ARCH_DMA_MINALIGN);
flush_dcache_range(addr, addr + size);
end = roundup(addr + length, ARCH_DMA_MINALIGN);
addr &= ~(ARCH_DMA_MINALIGN - 1);
flush_dcache_range(addr, end);
writew(length, &fec->tbd_base[fec->tbd_index].data_length);
writel(addr, &fec->tbd_base[fec->tbd_index].data_pointer);
@ -758,22 +768,28 @@ static int fec_send(struct eth_device *dev, void *packet, int length)
* invalidate data cache to see what's really in RAM. Also, we need
* barrier here.
*/
invalidate_dcache_range(addr, addr + size);
while (readw(&fec->tbd_base[fec->tbd_index].status) & FEC_TBD_READY) {
udelay(1);
invalidate_dcache_range(addr, addr + size);
while (--timeout) {
if (!(readl(&fec->eth->x_des_active) & FEC_X_DES_ACTIVE_TDAR))
break;
}
debug("fec_send: status 0x%x index %d\n",
if (!timeout)
ret = -EINVAL;
invalidate_dcache_range(addr, addr + size);
if (readw(&fec->tbd_base[fec->tbd_index].status) & FEC_TBD_READY)
ret = -EINVAL;
debug("fec_send: status 0x%x index %d ret %i\n",
readw(&fec->tbd_base[fec->tbd_index].status),
fec->tbd_index);
fec->tbd_index, ret);
/* for next transmission use the other buffer */
if (fec->tbd_index)
fec->tbd_index = 0;
else
fec->tbd_index = 1;
return 0;
return ret;
}
/**
@ -789,9 +805,9 @@ static int fec_recv(struct eth_device *dev)
int frame_length, len = 0;
struct nbuf *frame;
uint16_t bd_status;
uint32_t addr, size;
uint32_t addr, size, end;
int i;
uchar buff[FEC_MAX_PKT_SIZE];
uchar buff[FEC_MAX_PKT_SIZE] __aligned(ARCH_DMA_MINALIGN);
/*
* Check if any critical events have happened
@ -853,8 +869,9 @@ static int fec_recv(struct eth_device *dev)
* Invalidate data cache over the buffer
*/
addr = (uint32_t)frame;
size = roundup(frame_length, ARCH_DMA_MINALIGN);
invalidate_dcache_range(addr, addr + size);
end = roundup(addr + frame_length, ARCH_DMA_MINALIGN);
addr &= ~(ARCH_DMA_MINALIGN - 1);
invalidate_dcache_range(addr, end);
/*
* Fill the buffer and pass it to upper layers

View File

@ -213,6 +213,9 @@ struct ethernet_regs {
#define FEC_X_WMRK_STRFWD 0x00000100
#define FEC_X_DES_ACTIVE_TDAR 0x01000000
#define FEC_R_DES_ACTIVE_RDAR 0x01000000
#if defined(CONFIG_MX25) || defined(CONFIG_MX53)
/* defines for MIIGSK */
/* RMII frequency control: 0=50MHz, 1=5MHz */

View File

@ -28,7 +28,11 @@
DECLARE_GLOBAL_DATA_PTR;
static char input_buffer[512];
#ifndef CONFIG_NETCONSOLE_BUFFER_SIZE
#define CONFIG_NETCONSOLE_BUFFER_SIZE 512
#endif
static char input_buffer[CONFIG_NETCONSOLE_BUFFER_SIZE];
static int input_size; /* char count in input buffer */
static int input_offset; /* offset to valid chars in input buffer */
static int input_recursion;
@ -36,9 +40,15 @@ static int output_recursion;
static int net_timeout;
static uchar nc_ether[6]; /* server enet address */
static IPaddr_t nc_ip; /* server ip */
static short nc_port; /* source/target port */
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,
@ -59,8 +69,69 @@ static void nc_timeout(void)
net_set_state(NETLOOP_SUCCESS);
}
static int is_broadcast(IPaddr_t ip)
{
static IPaddr_t netmask;
static IPaddr_t our_ip;
static int env_changed_id;
int env_id = get_env_id();
/* update only when the environment has changed */
if (env_changed_id != env_id) {
netmask = getenv_IPaddr("netmask");
our_ip = getenv_IPaddr("ipaddr");
env_changed_id = env_id;
}
return (ip == ~0 || /* 255.255.255.255 */
((netmask & our_ip) == (netmask & ip) && /* on the same net */
(netmask | ip) == ~0)); /* broadcast to our net */
}
static int refresh_settings_from_env(void)
{
const char *p;
static int env_changed_id;
int env_id = get_env_id();
/* update only when the environment has changed */
if (env_changed_id != env_id) {
if (getenv("ncip")) {
nc_ip = getenv_IPaddr("ncip");
if (!nc_ip)
return -1; /* ncip is 0.0.0.0 */
p = strchr(getenv("ncip"), ':');
if (p != NULL) {
nc_out_port = simple_strtoul(p + 1, NULL, 10);
nc_in_port = nc_out_port;
}
} else
nc_ip = ~0; /* ncip is not set, so broadcast */
p = getenv("ncoutport");
if (p != NULL)
nc_out_port = simple_strtoul(p, NULL, 10);
p = getenv("ncinport");
if (p != NULL)
nc_in_port = simple_strtoul(p, NULL, 10);
if (is_broadcast(nc_ip))
/* broadcast MAC address */
memset(nc_ether, 0xff, sizeof(nc_ether));
else
/* force arp request */
memset(nc_ether, 0, sizeof(nc_ether));
}
return 0;
}
/**
* Called from NetLoop in net/net.c before each packet
*/
void NcStart(void)
{
refresh_settings_from_env();
if (!output_packet_len || memcmp(nc_ether, NetEtherNullAddr, 6)) {
/* going to check for input packet */
net_set_udp_handler(nc_handler);
@ -71,18 +142,22 @@ void NcStart(void)
net_set_arp_handler(nc_wait_arp_handler);
pkt = (uchar *)NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE;
memcpy(pkt, output_packet, output_packet_len);
NetSendUDPPacket(nc_ether, nc_ip, nc_port, nc_port,
NetSendUDPPacket(nc_ether, nc_ip, nc_out_port, nc_in_port,
output_packet_len);
}
}
int nc_input_packet(uchar *pkt, unsigned dest, unsigned src, unsigned len)
int nc_input_packet(uchar *pkt, IPaddr_t src_ip, unsigned dest_port,
unsigned src_port, unsigned len)
{
int end, chunk;
if (dest != nc_port || !len)
if (dest_port != nc_in_port || !len)
return 0; /* not for us */
if (src_ip != nc_ip && !is_broadcast(nc_ip))
return 0; /* not from our client */
debug_cond(DEBUG_DEV_PKT, "input: \"%*.*s\"\n", len, len, pkt);
if (input_size == sizeof(input_buffer))
@ -131,47 +206,39 @@ 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;
memcpy(pkt, buf, len);
ether = nc_ether;
ip = nc_ip;
NetSendUDPPacket(ether, ip, nc_port, nc_port, len);
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)
{
int netmask, our_ip;
int retval;
nc_port = 6666; /* default port */
nc_out_port = 6666; /* default port */
nc_in_port = nc_out_port;
if (getenv("ncip")) {
char *p;
nc_ip = getenv_IPaddr("ncip");
if (!nc_ip)
return -1; /* ncip is 0.0.0.0 */
p = strchr(getenv("ncip"), ':');
if (p != NULL)
nc_port = simple_strtoul(p + 1, NULL, 10);
} else
nc_ip = ~0; /* ncip is not set */
our_ip = getenv_IPaddr("ipaddr");
netmask = getenv_IPaddr("netmask");
if (nc_ip == ~0 || /* 255.255.255.255 */
((netmask & our_ip) == (netmask & nc_ip) && /* on the same net */
(netmask | nc_ip) == ~0)) /* broadcast to our net */
memset(nc_ether, 0xff, sizeof(nc_ether));
else
memset(nc_ether, 0, sizeof(nc_ether)); /* force arp request */
retval = refresh_settings_from_env();
if (retval != 0)
return retval;
/*
* Initialize the static IP settings and buffer pointers
@ -203,7 +270,7 @@ static void nc_puts(const char *s)
len = strlen(s);
while (len) {
int send_len = min(len, 512);
int send_len = min(len, sizeof(input_buffer));
nc_send_packet(s, send_len);
len -= send_len;
s += send_len;

View File

@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk
LIB := $(obj)libnpe.o
LOCAL_CFLAGS += -I$(TOPDIR)/arch/arm/cpu/ixp/npe/include -DCONFIG_IXP425_COMPONENT_ETHDB -D__linux
LOCAL_CFLAGS += -I$(TOPDIR)/drivers/net/npe/include -DCONFIG_IXP425_COMPONENT_ETHDB -D__linux
CFLAGS += $(LOCAL_CFLAGS)
CPPFLAGS += $(LOCAL_CFLAGS) # needed for depend
HOSTCFLAGS += $(LOCAL_CFLAGS)

Some files were not shown because too many files have changed in this diff Show More