summaryrefslogtreecommitdiff
path: root/board/keymile/common
diff options
context:
space:
mode:
Diffstat (limited to 'board/keymile/common')
-rw-r--r--board/keymile/common/common.c3
-rw-r--r--board/keymile/common/common.h4
-rw-r--r--board/keymile/common/keymile_hdlc_enet.c620
3 files changed, 0 insertions, 627 deletions
diff --git a/board/keymile/common/common.c b/board/keymile/common/common.c
index 4883fe5..dc96489 100644
--- a/board/keymile/common/common.c
+++ b/board/keymile/common/common.c
@@ -677,9 +677,6 @@ int ethernet_present(void)
int board_eth_init(bd_t *bis)
{
-#ifdef CONFIG_KEYMILE_HDLC_ENET
- (void)keymile_hdlc_enet_initialize(bis);
-#endif
if (ethernet_present())
return cpu_eth_init(bis);
diff --git a/board/keymile/common/common.h b/board/keymile/common/common.h
index 099de98..14768c9 100644
--- a/board/keymile/common/common.h
+++ b/board/keymile/common/common.h
@@ -46,10 +46,6 @@ struct km_bec_fpga {
int ethernet_present(void);
int ivm_read_eeprom(void);
-#ifdef CONFIG_KEYMILE_HDLC_ENET
-int keymile_hdlc_enet_initialize(bd_t *bis);
-#endif
-
int set_km_env(void);
int fdt_set_node_and_value(void *blob,
char *nodename,
diff --git a/board/keymile/common/keymile_hdlc_enet.c b/board/keymile/common/keymile_hdlc_enet.c
deleted file mode 100644
index a545211..0000000
--- a/board/keymile/common/keymile_hdlc_enet.c
+++ /dev/null
@@ -1,620 +0,0 @@
-/*
- * (C) Copyright 2008
- * Gary Jennejohn, DENX Software Engineering GmbH, garyj@denx.de.
- *
- * Based in part on arch/powerpc/cpu/mpc8260/ether_scc.c.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-#include <malloc.h>
-#include <net.h>
-
-#ifdef CONFIG_KEYMILE_HDLC_ENET
-#ifdef TEST_IT
-#include <command.h>
-#endif
-
-#include "keymile_hdlc_enet.h"
-
-extern char keymile_slot; /* our slot number in the backplane */
-
-/* Allow up to about 50 ms for sending */
-#define TOUT_LOOP 50000
-
-/*
- * Since, except during initialization, ethact is always HDLC
- * while we're in the driver, just use serial_printf() everywhere for
- * output. This avoids possible conflicts when netconsole is being
- * used.
- */
-#define dprintf(fmt, args...) serial_printf(fmt, ##args)
-
-/* Cannot use the storage from net.c because we allocate larger buffers */
-static volatile uchar MyPktBuf[HDLC_PKTBUFSRX * PKT_MAXBLR_SIZE + PKTALIGN];
-static volatile uchar *MyRxPackets[HDLC_PKTBUFSRX]; /* Receive packet */
-
-static unsigned int keymile_rxIdx; /* index of the current RX buffer */
-
-static IPaddr_t cachedNumbers[CACHEDNUMBERS]; /* 4 bytes per entry */
-void initCachedNumbers(int);
-
-/*
- * SCC Ethernet Tx and Rx buffer descriptors allocated at the
- * immr->udata_bd address on Dual-Port RAM
- * Provide for Double Buffering
- */
-typedef volatile struct CommonBufferDescriptor {
- cbd_t txbd; /* Tx BD */
- cbd_t rxbd[HDLC_PKTBUFSRX]; /* Rx BD */
-} RTXBD;
-
-/*
- * This must be extern because it is allocated in DPRAM using CPM-sepcific
- * code.
- */
-static RTXBD *rtx;
-
-static int keymile_hdlc_enet_send(struct eth_device *, volatile void *, int);
-static int keymile_hdlc_enet_recv(struct eth_device *);
-void keymile_hdlc_enet_init_bds(RTXBD *);
-extern int keymile_hdlc_enet_init(struct eth_device *, bd_t *);
-extern void keymile_hdlc_enet_halt(struct eth_device *);
-
-/* flags in the buffer descriptor not defined anywhere else */
-#define BD_SC_CT BD_SC_CD
-#define BD_SC_CR 0x04
-#define BD_SC_DE 0x80
-#ifndef BD_SC_TC
-#define BD_SC_TC ((ushort)0x0400) /* Transmit CRC */
-#endif
-#define BD_SC_FIRST BD_SC_TC
-#define BD_SC_STATS (BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_CR | BD_SC_CD \
- | BD_SC_OV | BD_SC_DE)
-
-#if defined(TEST_RX) || defined(TEST_TX) || defined(TEST_IT)
-static void hexdump(unsigned char *buf, int len)
-{
- int i;
- const int bytesPerLine = 32;
-
- if (len > 4 * bytesPerLine)
- len = 4 * bytesPerLine;
- dprintf("\t address: %08x\n", (unsigned int)buf);
- for (i = 0; i < len; i++) {
- if (i % bytesPerLine == 0)
- dprintf("%04x: ", (unsigned short)i);
- dprintf("%02x ", buf[i]);
- if ((i + 1) % bytesPerLine == 0) {
- dprintf("\n");
- continue;
- }
- if ((i + 1) % 8 == 0)
- printf(" ");
- }
- if (len % bytesPerLine)
- dprintf("\n");
-}
-#endif
-
-int keymile_hdlc_enet_initialize(bd_t *bis)
-{
- struct eth_device *dev;
-
- dev = (struct eth_device *) malloc(sizeof *dev);
- memset(dev, 0, sizeof *dev);
-#ifdef TEST_IT
- seth = dev;
-#endif
-
- sprintf(dev->name, "HDLC");
- dev->init = keymile_hdlc_enet_init;
- dev->halt = keymile_hdlc_enet_halt;
- dev->send = keymile_hdlc_enet_send;
- dev->recv = keymile_hdlc_enet_recv;
-
- eth_register(dev);
-
- return 1;
-}
-
-/*
- * This is called from the board-specific driver after rtx is allocated.
- */
-void keymile_hdlc_enet_init_bds(RTXBD *board_rtx)
-{
- volatile cbd_t *bdp;
- int i;
-
- rtx = board_rtx;
- keymile_rxIdx = 0;
- /*
- * Initialize the buffer descriptors.
- */
- bdp = &rtx->txbd;
- bdp->cbd_sc = 0;
- bdp->cbd_bufaddr = 0;
- bdp->cbd_sc = BD_SC_WRAP;
-
- /*
- * Setup RX packet buffers, aligned correctly.
- * Borrowed from net/net.c.
- */
- MyRxPackets[0] = &MyPktBuf[0] + (PKTALIGN - 1);
- MyRxPackets[0] -= (ulong)MyRxPackets[0] % PKTALIGN;
- for (i = 1; i < HDLC_PKTBUFSRX; i++)
- MyRxPackets[i] = MyRxPackets[0] + i * PKT_MAXBLR_SIZE;
-
- bdp = &rtx->rxbd[0];
- for (i = 0; i < HDLC_PKTBUFSRX; i++) {
- bdp->cbd_sc = BD_SC_EMPTY;
- /* Leave space at the start for INET header. */
- bdp->cbd_bufaddr = (unsigned int)(MyRxPackets[i] +
- INET_HDR_ALIGN);
- bdp++;
- }
- bdp--;
- bdp->cbd_sc |= BD_SC_WRAP;
-}
-
-/*
- * This returns the current port number for NETCONSOLE. If nc_port
- * in netconsole.c weren't declared static we wouldn't need this.
- */
-static short get_netcons_port(void)
-{
- char *p;
- short nc_port;
-
- nc_port = 6666; /* default */
-
- p = getenv("ncip");
- if (p != NULL) {
- p = strchr(p, ':');
- if (p != NULL)
- nc_port = simple_strtoul(p + 1, NULL, 10);
- }
-
- return htons(nc_port);
-}
-
-/*
- * Read the port numbers from the variables
- */
-void initCachedNumbers(int verbose)
-{
- char *str;
- ushort port;
-
- /* already in network order */
- cachedNumbers[IP_ADDR] = getenv_IPaddr("ipaddr");
- /* already in network order */
- cachedNumbers[IP_SERVER] = getenv_IPaddr("serverip");
- str = getenv("tftpsrcp");
- if (str != NULL) {
- /* avoid doing htons() again and again */
- port = htons((ushort)simple_strtol(str, NULL, 10));
- cachedNumbers[TFTP_SRC_PORT] = port;
- } else
- /* this can never be a valid port number */
- cachedNumbers[TFTP_SRC_PORT] = (ulong)-1;
- str = getenv("tftpdstp");
- if (str != NULL) {
- /* avoid doing htons() again and again */
- port = htons((ushort)simple_strtol(str, NULL, 10));
- cachedNumbers[TFTP_DST_PORT] = port;
- } else
- /* this is the default value */
- cachedNumbers[TFTP_DST_PORT] = htons(WELL_KNOWN_PORT);
- /* already in network order */
- cachedNumbers[NETCONS_PORT] = get_netcons_port();
- if (verbose) {
- dprintf("\nIP Number Initialization:\n");
- dprintf(" ip address %08lx\n", cachedNumbers[IP_ADDR]);
- dprintf(" server ip address %08lx\n",
- cachedNumbers[IP_SERVER]);
- dprintf(" tftp client port %ld\n",
- cachedNumbers[TFTP_SRC_PORT]);
- dprintf(" tftp server port %ld\n",
- cachedNumbers[TFTP_DST_PORT]);
- dprintf(" netcons port %ld\n",
- cachedNumbers[NETCONS_PORT]);
- dprintf(" slot number (hex) %02x\n", keymile_slot);
- }
-}
-
-static void keymile_hdlc_enet_doarp(volatile void *packet, int len)
-{
- ARP_t *arp;
- IPaddr_t src_ip; /* U-Boot's IP */
- IPaddr_t dest_ip; /* the mgcoge's IP */
- unsigned char *packet_copy = malloc(len);
-
- /*
- * Handling an ARP request means that a new transfer has started.
- * Update our cached parameters now.
- */
- initCachedNumbers(0); /* may reinit port numbers */
-
- /* special handling required for ARP */
- arp = (ARP_t *)(packet + ETHER_HDR_SIZE);
- /*
- * XXXX
- * This is pretty dirty! NetReceive only uses
- * a few fields when handling an ARP reply, so
- * we only modify those here. This could
- * result in catastrophic failure at a later
- * time if the handler is modified!
- */
- arp->ar_op = htons(ARPOP_REPLY);
- /* save his/our IP */
- src_ip = NetReadIP(&arp->ar_data[6]);
- dest_ip = NetReadIP(&arp->ar_data[16]);
- /* copy target IP to source IP */
- NetCopyIP(&arp->ar_data[6], &dest_ip);
- /* copy our IP to the right place */
- NetCopyIP(&arp->ar_data[16], &src_ip);
- /* always use 0x7f as the MAC for the coge */
- arp->ar_data[0] = HDLC_UACUA;
- /*
- * copy the packet
- * if NetReceive wants to write to stdout, it may overwrite packet
- * especially if stdout is set to nc!
- *
- * However, if the malloc() above fails then we can still try the
- * original packet, rather than causing the transfer to fail.
- */
- if (packet_copy != NULL) {
- memcpy(packet_copy, (char *)packet, len);
- NetReceive(packet_copy, len);
- free(packet_copy);
- } else
- NetReceive(packet, len);
-}
-
-/*
- * NOTE all callers ignore the returned value!
- * At the moment this only handles ARP Requests, TFTP and NETCONSOLE.
- */
-static int keymile_hdlc_enet_send(struct eth_device *dev, volatile void *packet,
- int len)
-{
- int j;
- uint data_addr;
- int data_len;
- struct icn_hdr header;
- struct icn_frame *frame;
- Ethernet_t *et;
- ARP_t *arp;
- IP_t *ip;
-
- if (len > (MAX_FRAME_LENGTH - sizeof(header)))
- return -1;
-
- frame = NULL;
- et = NULL;
- arp = NULL;
- ip = NULL;
-
- j = 0;
- while ((rtx->txbd.cbd_sc & BD_SC_READY) && (j < TOUT_LOOP)) {
- /* will also trigger Wd if needed, but maybe too often */
- udelay(1);
- j++;
- }
- if (j >= TOUT_LOOP) {
- dprintf("TX not ready sc %x\n", rtx->txbd.cbd_sc);
- return -1;
- }
-
- /*
- * First check for an ARP Request since this requires special handling.
- */
- if (len >= (ARP_HDR_SIZE + ETHER_HDR_SIZE)) {
- et = (Ethernet_t *)packet;
- arp = (ARP_t *)(((char *)et) + ETHER_HDR_SIZE);
- /* ARP and REQUEST? */
- if (et->et_protlen == PROT_ARP &&
- arp->ar_op == htons(ARPOP_REQUEST)) {
- /* just short-circuit the request on the U-Boot side */
- keymile_hdlc_enet_doarp(packet, len);
- return 0;
- }
- }
-
- /*
- * GJ - I suppose the assumption here that len will always be
- * > INET_HDR_SIZE is alright as long as the network stack
- * isn't changed.
- * Do not send INET header.
- */
- data_len = len + sizeof(header) - INET_HDR_SIZE;
- frame = (struct icn_frame *) (((char *)packet) + INET_HDR_SIZE -
- sizeof(header));
-
-#ifdef TEST_TX
- printf("frame: %08x, ", frame);
- hexdump((unsigned char *)packet, data_len + INET_HDR_SIZE);
-#endif
-
- data_addr = (uint)frame;
- if (len >= (IP_HDR_SIZE + ETHER_HDR_SIZE))
- ip = (IP_t *)(packet + ETHER_HDR_SIZE);
- /* Is it TFTP? TFTP always uses UDP and the cached dport */
- if (ip != NULL && ip->ip_p == IPPROTO_UDP && ip->udp_dst ==
- (ushort)cachedNumbers[TFTP_DST_PORT]) {
- /* just in case the port wasn't set in the environment */
- if (cachedNumbers[TFTP_SRC_PORT] == (ulong)-1)
- cachedNumbers[TFTP_SRC_PORT] = ip->udp_src;
- frame->hdr.application = MGS_TFTP;
- }
- /*
- * Is it NETCONSOLE? NETCONSOLE always uses UDP.
- */
- else if (ip != NULL && ip->ip_p == IPPROTO_UDP
- && ip->udp_dst == (ushort)cachedNumbers[NETCONS_PORT]) {
- frame->hdr.application = MGS_NETCONS;
- } else {
- /* reject unknown packets */
- /* may do some check on frame->hdr.application */
- dprintf("Unknown packet type in %s, rejected\n",
- __func__);
- return -1;
- }
- /*
- * Could extract the target's slot ID from its MAC here,
- * but u-boot only wants to talk to the active server.
- *
- * avoid setting new source address when moving to another slot
- */
- frame->hdr.src_addr = keymile_slot;
- frame->hdr.dest_addr = HDLC_UACUA;
-#ifdef TEST_TX
- {
- dprintf("TX: ");
- hexdump((unsigned char *)data_addr, data_len);
- }
-#endif
-
- flush_cache(data_addr, data_len);
- rtx->txbd.cbd_bufaddr = data_addr;
- rtx->txbd.cbd_datlen = data_len;
- rtx->txbd.cbd_sc |= (BD_SC_READY | BD_SC_TC | BD_SC_LAST | BD_SC_WRAP);
-
- while ((rtx->txbd.cbd_sc & BD_SC_READY) && (j < TOUT_LOOP)) {
- /* will also trigger Wd if needed, but maybe too often */
- udelay(1);
- j++;
- }
- if (j >= TOUT_LOOP)
- dprintf("TX timeout\n");
-#ifdef ET_DEBUG
- dprintf("cycles: %d status: %x\n", j, rtx->txbd.cbd_sc);
-#endif
- j = (rtx->txbd.cbd_sc & BD_SC_STATS); /* return only status bits */
- return j;
-}
-
-/*
- * During a receive, the RxIdx points to the current incoming buffer.
- * When we update through the ring, if the next incoming buffer has
- * not been given to the system, we just set the empty indicator,
- * effectively tossing the packet.
- */
-static int keymile_hdlc_enet_recv(struct eth_device *dev)
-{
- int length;
- unsigned char app;
- struct icn_frame *fp;
- Ethernet_t *ep;
- IP_t *ip;
-
- for (;;) {
- if (rtx->rxbd[keymile_rxIdx].cbd_sc & BD_SC_EMPTY) {
- length = -1;
- break; /* nothing received - leave for() loop */
- }
-
- length = rtx->rxbd[keymile_rxIdx].cbd_datlen;
-#ifdef TEST_RX
- dprintf("packet %d bytes long\n", length);
-#endif
-
- /*
- * BD_SC_BR -> LG bit
- * BD_SC_FR -> NO bit
- * BD_SC_PR -> AB bit
- * BD_SC_NAK -> CR bit
- * 0x80 -> DE bit
- */
- if (rtx->rxbd[keymile_rxIdx].cbd_sc & BD_SC_STATS) {
-#ifdef ET_DEBUG
- dprintf("err: %x\n", rtx->rxbd[keymile_rxIdx].cbd_sc);
-#endif
- } else if (length > MAX_FRAME_LENGTH) { /* can't happen */
-#ifdef ET_DEBUG
- dprintf("err: packet too big\n");
-#endif
- } else {
- fp = (struct icn_frame *)(MyRxPackets[keymile_rxIdx] +
- INET_HDR_ALIGN - INET_HDR_SIZE);
-#ifdef TEST_RX
- dprintf("RX %d: ", keymile_rxIdx);
- hexdump((unsigned char *)MyRxPackets[keymile_rxIdx],
- INET_HDR_ALIGN + INET_HDR_SIZE + 4);
-#endif
- /* copy icn header to the beginning */
- memcpy(fp, ((char *)fp + INET_HDR_SIZE),
- sizeof(struct icn_hdr));
- app = fp->hdr.application;
- if (app == MGS_NETCONS || app == MGS_TFTP) {
- struct icn_hdr *ih = &fp->hdr;
- unsigned char icn_src_addr = ih->src_addr;
- unsigned char icn_dest_addr = ih->dest_addr;
-
- /*
- * expand header by INET_HDR_SIZE
- */
- length += INET_HDR_SIZE;
- /* initalize header */
- memset((char *)fp->data, 0x00, INET_HDR_SIZE);
- ep = (Ethernet_t *)fp->data;
- /* set MACs */
- ep->et_dest[0] = icn_dest_addr;
- ep->et_src[0] = icn_src_addr;
- ep->et_protlen = htons(PROT_IP);
- /* set ip stuff */
- ip = (IP_t *)(fp->data + ETHER_HDR_SIZE);
- /* set ip addresses */
- ip->ip_src = cachedNumbers[IP_SERVER];
- ip->ip_dst = cachedNumbers[IP_ADDR];
- /* ip length */
- ip->ip_len = htons(length - ETHER_HDR_SIZE -
- REMOVE);
- /* ip proto */
- ip->ip_p = IPPROTO_UDP;
- switch (app) {
- case MGS_TFTP:
- /* swap src/dst port numbers */
- ip->udp_src = (ushort)
- cachedNumbers[TFTP_DST_PORT];
- ip->udp_dst = (ushort)
- cachedNumbers[TFTP_SRC_PORT];
- ip->udp_len = ip->ip_len -
- IP_HDR_SIZE_NO_UDP;
- ip->udp_xsum = 0;
- break;
- case MGS_NETCONS:
- ip->udp_src = (ushort)
- cachedNumbers[NETCONS_PORT];
- /*
- * in drivers/net/netconsole.c src port
- * equals dest port
- */
- ip->udp_dst = ip->udp_src;
- ip->udp_len = ip->ip_len -
- IP_HDR_SIZE_NO_UDP;
- ip->udp_xsum = 0;
- break;
- }
- /* ip version */
- ip->ip_hl_v = (0x40) | (0x0f &
- (IP_HDR_SIZE_NO_UDP / 4));
- ip->ip_tos = 0;
- ip->ip_id = 0;
- /* flags, fragment offset */
- ip->ip_off = htons(0x4000);
- ip->ip_ttl = 255; /* time to live */
- /* have to fixup the checksum */
- ip->ip_sum = ~NetCksum((uchar *)ip,
- IP_HDR_SIZE_NO_UDP / 2);
- /*
- * Pass the packet up to the protocol layers
- * but remove dest_addr, src_addr, application
- * and the CRC.
- */
-#ifdef TEST_RX
- hexdump((unsigned char *)fp->data,
- INET_HDR_SIZE + 4);
-#endif
- NetReceive(fp->data, length - REMOVE);
- } else {
- /*
- * the other application types are not yet
- * supported by u-boot.
- */
- /* normally drop it */
-#ifdef TEST_NO
- /* send it anyway */
- fp = (struct icn_frame *)
- (MyRxPackets[keymile_rxIdx] +
- INET_HDR_ALIGN);
- NetReceive(fp->data, length - REMOVE);
-#endif
- }
- }
-
- /* Give the buffer back to the SCC. */
- rtx->rxbd[keymile_rxIdx].cbd_datlen = 0;
-
- /* wrap around buffer index when necessary */
- if ((keymile_rxIdx + 1) >= HDLC_PKTBUFSRX) {
- rtx->rxbd[HDLC_PKTBUFSRX - 1].cbd_sc =
- (BD_SC_WRAP | BD_SC_EMPTY);
- keymile_rxIdx = 0;
- } else {
- rtx->rxbd[keymile_rxIdx].cbd_sc = BD_SC_EMPTY;
- keymile_rxIdx++;
- }
- }
- return length;
-}
-
-#ifdef TEST_IT
-/* simple send test routine */
-int hdlc_enet_stest(struct cmd_tbl_s *a, int b, int c, char **d)
-{
- unsigned char pkt[2];
- int ret;
-
- dprintf("enter stest\n");
- /* may have to initialize things */
- if (seth->state != ETH_STATE_ACTIVE) {
- /* the bd_t* is not used */
- if (seth->init(seth, NULL) >= 0)
- seth->state = ETH_STATE_ACTIVE;
- }
- pkt[0] = 0xea;
- pkt[1] = 0xae;
- ret = keymile_hdlc_enet_send(seth, pkt, 2);
- dprintf("return from send %x\n", ret);
- dprintf("exit stest\n");
- return ret;
-}
-U_BOOT_CMD(
- stest, 1, 1, hdlc_enet_stest,
- "simple send test for hdlc_enet",
- ""
-);
-/* simple receive test routine */
-int hdlc_enet_rtest(struct cmd_tbl_s *a, int b, int c, char **d)
-{
- int ret;
-
- dprintf("enter rtest\n");
- /* may have to initialize things */
- if (seth->state != ETH_STATE_ACTIVE) {
- /* the bd_t* is not used */
- if (seth->init(seth, NULL) >= 0)
- seth->state = ETH_STATE_ACTIVE;
- }
- ret = keymile_hdlc_enet_recv(seth);
- dprintf("return from recv %x\n", ret);
- dprintf("exit rtest\n");
- return ret;
-}
-U_BOOT_CMD(
- rtest, 1, 1, hdlc_enet_rtest,
- "simple receive test for hdlc_enet",
- ""
-);
-#endif
-
-#endif /* CONFIG_KEYMILE_HDLC_ENET */