summaryrefslogtreecommitdiffstats
path: root/arch/m68k/mach-mcfv4e/net
diff options
context:
space:
mode:
Diffstat (limited to 'arch/m68k/mach-mcfv4e/net')
-rw-r--r--arch/m68k/mach-mcfv4e/net/Makefile26
-rw-r--r--arch/m68k/mach-mcfv4e/net/nbuf.c239
-rw-r--r--arch/m68k/mach-mcfv4e/net/net.c156
-rw-r--r--arch/m68k/mach-mcfv4e/net/queue.c128
4 files changed, 549 insertions, 0 deletions
diff --git a/arch/m68k/mach-mcfv4e/net/Makefile b/arch/m68k/mach-mcfv4e/net/Makefile
new file mode 100644
index 0000000000..45badfaaac
--- /dev/null
+++ b/arch/m68k/mach-mcfv4e/net/Makefile
@@ -0,0 +1,26 @@
+#
+# (C) Copyright 2007 Carsten Schlote <schlote@vahanus.net>
+# See file CREDITS for list of people who contributed to this project.
+#
+# This file is part of U-Boot V2.
+#
+# U-Boot V2 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 3 of the License, or
+# (at your option) any later version.
+#
+# U-Boot V2 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 U-Boot V2. If not, see <http://www.gnu.org/licenses/>.
+#
+
+#
+# Support code for current FEC driver code - must be eliminated later...
+#
+obj-y += nbuf.o queue.o net.o
+
+
diff --git a/arch/m68k/mach-mcfv4e/net/nbuf.c b/arch/m68k/mach-mcfv4e/net/nbuf.c
new file mode 100644
index 0000000000..d7ae921bed
--- /dev/null
+++ b/arch/m68k/mach-mcfv4e/net/nbuf.c
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 2008 Carsten Schlote <c.schlote@konzeptpark.de>
+ * See file CREDITS for list of people who contributed to this project.
+ *
+ * This file is part of U-Boot V2.
+ *
+ * U-Boot V2 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * U-Boot V2 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 U-Boot V2. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file
+ * Implementation of network buffer scheme.
+ * @todo Obsolete this file
+ */
+#include <common.h>
+#include <malloc.h>
+#include <linux/types.h>
+
+#include <asm/proc/net/queue.h>
+#include <asm/proc/net/net.h>
+
+#include <asm/arch/mcf54xx-regs.h>
+
+
+#define ASSERT(x)
+
+/**
+ * Queues used for network buffer storage
+ */
+QUEUE nbuf_queue[NBUF_MAXQ];
+
+/*
+ * Some devices require line-aligned buffers. In order to accomplish
+ * this, the nbuf data is over-allocated and adjusted. The following
+ * array keeps track of the original data pointer returned by malloc
+ */
+ADDRESS unaligned_buffers[NBUF_MAX];
+
+/**
+ * Initialize all the network buffer queues
+ *
+ * Return Value:
+ * 0 success
+ * 1 failure
+ */
+int
+nbuf_init(void)
+{
+ int i;
+ NBUF *nbuf;
+
+ for (i=0; i<NBUF_MAXQ; ++i)
+ {
+ /* Initialize all the queues */
+ queue_init(&nbuf_queue[i]);
+ }
+
+ #ifdef CONFIG_DRIVER_NET_MCF54XX_DEBUG
+ printf("Creating %d net buffers of %d bytes\n",NBUF_MAX,NBUF_SZ);
+ #endif
+
+ for (i=0; i<NBUF_MAX; ++i)
+ {
+ /* Allocate memory for the network buffer structure */
+ nbuf = (NBUF *)malloc(sizeof(NBUF));
+ if (!nbuf)
+ {
+ ASSERT(nbuf);
+ return 1;
+ }
+
+ /* Allocate memory for the actual data */
+ unaligned_buffers[i] = (ADDRESS)malloc(NBUF_SZ + 16);
+ nbuf->data = (uint8_t *)((uint32_t)(unaligned_buffers[i] + 15) & 0xFFFFFFF0);
+ if (!nbuf->data)
+ {
+ ASSERT(nbuf->data);
+ return 1;
+ }
+
+ /* Initialize the network buffer */
+ nbuf->offset = 0;
+ nbuf->length = 0;
+
+ /* Add the network buffer to the free list */
+ queue_add(&nbuf_queue[NBUF_FREE], (QNODE *)nbuf);
+ }
+
+ #ifdef CONFIG_DRIVER_NET_MCF54XX_DEBUG
+ printf("NBUF allocation complete\n");
+ nbuf_debug_dump();
+ #endif
+
+ return 0;
+}
+/**
+ * Return all the allocated memory to the heap
+ */
+void
+nbuf_flush(void)
+{
+ NBUF *nbuf;
+ int i, level = asm_set_ipl(7);
+ int n = 0;
+
+ for (i=0; i<NBUF_MAX; ++i)
+ free((uint8_t*)unaligned_buffers[i]);
+
+ for (i=0; i<NBUF_MAXQ; ++i)
+ {
+ while ((nbuf = (NBUF *)queue_remove(&nbuf_queue[i])) != NULL)
+ {
+ free(nbuf);
+ ++n;
+ }
+ }
+ ASSERT(n == NBUF_MAX);
+ asm_set_ipl(level);
+}
+/**
+ * Allocate a network buffer from the free list
+ *
+ * Return Value:
+ * Pointer to a free network buffer
+ * NULL if none are available
+ */
+NBUF *
+nbuf_alloc(void)
+{
+ NBUF *nbuf;
+ int level = asm_set_ipl(7);
+
+ nbuf = (NBUF *)queue_remove(&nbuf_queue[NBUF_FREE]);
+ asm_set_ipl(level);
+ return nbuf;
+}
+/**
+ * Add the specified network buffer back to the free list
+ *
+ * Parameters:
+ * nbuf Buffer to add back to the free list
+ */
+void
+nbuf_free(NBUF *nbuf)
+{
+ int level = asm_set_ipl(7);
+
+ nbuf->offset = 0;
+ nbuf->length = NBUF_SZ;
+ queue_add(&nbuf_queue[NBUF_FREE],(QNODE *)nbuf);
+
+ asm_set_ipl(level);
+}
+/**
+ * Remove a network buffer from the specified queue
+ *
+ * Parameters:
+ * q The index that identifies the queue to pull the buffer from
+ */
+NBUF *
+nbuf_remove(int q)
+{
+ NBUF *nbuf;
+ int level = asm_set_ipl(7);
+
+ nbuf = (NBUF *)queue_remove(&nbuf_queue[q]);
+ asm_set_ipl(level);
+ return nbuf;
+}
+/**
+ * Add a network buffer to the specified queue
+ *
+ * Parameters:
+ * q The index that identifies the queue to add the buffer to
+ */
+void
+nbuf_add(int q, NBUF *nbuf)
+{
+ int level = asm_set_ipl(7);
+ queue_add(&nbuf_queue[q],(QNODE *)nbuf);
+ asm_set_ipl(level);
+}
+/**
+ * Put all the network buffers back into the free list
+ */
+void
+nbuf_reset(void)
+{
+ NBUF *nbuf;
+ int i, level = asm_set_ipl(7);
+
+ for (i=1; i<NBUF_MAXQ; ++i)
+ {
+ while ((nbuf = nbuf_remove(i)) != NULL)
+ nbuf_free(nbuf);
+ }
+ asm_set_ipl(level);
+}
+/**
+ * Display all the nbuf queues
+ */
+void
+nbuf_debug_dump(void)
+{
+#ifdef CONFIG_DRIVER_NET_MCF54XX_DEBUG
+ NBUF *nbuf;
+ int i, j, level;
+
+ level = asm_set_ipl(7);
+
+ for (i=0; i<NBUF_MAXQ; ++i)
+ {
+ printf("\n\nQueue #%d\n\n",i);
+ printf("\tBuffer Location\tOffset\tLength\n");
+ printf("--------------------------------------\n");
+ j = 0;
+ nbuf = (NBUF *)queue_peek(&nbuf_queue[i]);
+ while (nbuf != NULL)
+ {
+ printf("%d\t 0x%08x\t0x%04x\t0x%04x\n",j++,nbuf->data,
+ nbuf->offset,
+ nbuf->length);
+ nbuf = (NBUF *)nbuf->node.next;
+ }
+ }
+
+ asm_set_ipl(level);
+#endif
+}
diff --git a/arch/m68k/mach-mcfv4e/net/net.c b/arch/m68k/mach-mcfv4e/net/net.c
new file mode 100644
index 0000000000..76e28531b6
--- /dev/null
+++ b/arch/m68k/mach-mcfv4e/net/net.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2008 Carsten Schlote <c.schlote@konzeptpark.de>
+ * See file CREDITS for list of people who contributed to this project.
+ *
+ * This file is part of U-Boot V2.
+ *
+ * U-Boot V2 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * U-Boot V2 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 U-Boot V2. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file
+ * Network initialization for MCF V4E FEC support code
+ * @todo Obsolete this file
+ */
+#include <common.h>
+#include <malloc.h>
+#include <linux/types.h>
+
+#include <asm/arch/mcf54xx-regs.h>
+#include <asm/proc/mcdapi/MCD_dma.h>
+#include <asm/proc/net/net.h>
+#include <asm/proc/fecbd.h>
+#include <asm/proc/fec.h>
+#include <asm/proc/dma_utils.h>
+
+#include <asm/proc/processor.h> //FIXME - move to other file
+
+int netif_init(int channel)
+{
+ uint8_t* board_get_ethaddr(uint8_t*);
+
+#ifdef CONFIG_USE_IRQ
+ int vector;
+ int (*handler)(void *, void *);
+
+ disable_interrupts();
+
+ /*
+ * Register the FEC0 interrupt handler
+ */
+ handler = (channel == 0) ? fec0_interrupt_handler
+ : fec1_interrupt_handler;
+ vector = (channel == 0) ? 103 : 102;
+
+ if (!mcf_interrupts_register_handler(
+ vector,handler, NULL,(void *)0xdeadbeef))
+ {
+ printf("Error: Unable to register handler\n");
+ return 0;
+ }
+
+ /*
+ * Register the DMA interrupt handler
+ */
+ handler = dma_interrupt_handler;
+ vector = 112;
+
+ if (!mcf_interrupts_register_handler(
+ vector,handler, NULL,NULL))
+ {
+ printf("Error: Unable to register handler\n");
+ return 0;
+ }
+#endif
+ /*
+ * Enable interrupts
+ */
+ enable_interrupts();
+
+ return 1;
+}
+
+int netif_setup(int channel)
+{
+ uint8_t mac[6];
+ /*
+ * Get user programmed MAC address
+ */
+// board_get_ethaddr(mac);
+
+
+ /*
+ * Initialize the network interface structure
+ */
+// nif_init(&nif1);
+// nif1.mtu = ETH_MTU;
+// nif1.send = (DBUG_ETHERNET_PORT == 0) ? fec0_send : fec1_send;
+
+ /*
+ * Initialize the dBUG Ethernet port
+ */
+ fec_eth_setup(channel, /* Which FEC to use */
+ FEC_MODE_MII, /* Use MII mode */
+ FEC_MII_100BASE_TX, /* Allow 10 and 100Mbps */
+ FEC_MII_FULL_DUPLEX, /* Allow Full and Half Duplex */
+ mac);
+
+ /*
+ * Copy the Ethernet address to the NIF structure
+ */
+// memcpy(nif1.hwa, mac, 6);
+
+ #ifdef DEBUG
+ printf("Ethernet Address is %02X:%02X:%02X:%02X:%02X:%02X\n",\
+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+ #endif
+
+ return 1;
+}
+
+int netif_done(int channel)
+{
+ /*
+ * Download complete, clean up
+ */
+#ifdef CONFIG_USE_IRQ
+ int (*handler)(void *, void *);
+#endif
+ /*
+ * Disable interrupts
+ */
+ disable_interrupts();
+
+ /*
+ * Disable the Instruction Cache
+ */
+ mcf5xxx_wr_cacr(MCF5XXX_CACR_ICINVA);
+
+ /*
+ * Disable the dBUG Ethernet port
+ */
+ fec_eth_stop(channel);
+
+ /*
+ * Remove the interrupt handlers
+ */
+#ifdef CONFIG_USE_IRQ
+ handler = (channel == 0) ? fec0_interrupt_handler
+ : fec1_interrupt_handler;
+ mcf_interrupts_remove_handler(handler);
+ mcf_interrupts_remove_handler(dma_interrupt_handler);
+#endif
+ return 1;
+}
+
+
diff --git a/arch/m68k/mach-mcfv4e/net/queue.c b/arch/m68k/mach-mcfv4e/net/queue.c
new file mode 100644
index 0000000000..55f938af3e
--- /dev/null
+++ b/arch/m68k/mach-mcfv4e/net/queue.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2008 Carsten Schlote <c.schlote@konzeptpark.de>
+ * See file CREDITS for list of people who contributed to this project.
+ *
+ * This file is part of U-Boot V2.
+ *
+ * U-Boot V2 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * U-Boot V2 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 U-Boot V2. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file
+ * Implements a first in, first out linked list
+ *
+ * @note Simple selfcontaining basic code
+ * @todo Replace by u-boot standard list functions
+ */
+#include <linux/types.h>
+#include <asm/proc/net/queue.h>
+
+/** Initialize the specified queue to an empty state
+ *
+ * @param[in]
+ * q Pointer to queue structure
+ */
+void queue_init(QUEUE *q)
+{
+ q->head = NULL;
+}
+
+/**
+ * Check for an empty queue
+ *
+ * @param[in] q Pointer to queue structure
+ * @return
+ * 1 if Queue is empty
+ * 0 otherwise
+ */
+int
+queue_isempty(QUEUE *q)
+{
+ return (q->head == NULL);
+}
+
+/**
+ * Add an item to the end of the queue
+ *
+ * @param[in] q Pointer to queue structure
+ * @param[in] node New node to add to the queue
+ */
+void queue_add(QUEUE *q, QNODE *node)
+{
+ if (queue_isempty(q))
+ {
+ q->head = q->tail = node;
+ }
+ else
+ {
+ q->tail->next = node;
+ q->tail = node;
+ }
+
+ node->next = NULL;
+}
+
+/** Remove and return first (oldest) entry from the specified queue
+ *
+ * @param[in] q Pointer to queue structure
+ * @return
+ * Node at head of queue - NULL if queue is empty
+ */
+QNODE*
+queue_remove(QUEUE *q)
+{
+ QNODE *oldest;
+
+ if (queue_isempty(q))
+ return NULL;
+
+ oldest = q->head;
+ q->head = oldest->next;
+ return oldest;
+}
+
+/** Peek into the queue and return pointer to first (oldest) entry.
+ *
+ * The queue is not modified
+ *
+ * @param[in] q Pointer to queue structure
+ * @return
+ * Node at head of queue - NULL if queue is empty
+ */
+QNODE*
+queue_peek(QUEUE *q)
+{
+ return q->head;
+}
+
+/** Move entire contents of one queue to the other
+ *
+ * @param[in] src Pointer to source queue
+ * @param[in] dst Pointer to destination queue
+ */
+void
+queue_move(QUEUE *dst, QUEUE *src)
+{
+ if (queue_isempty(src))
+ return;
+
+ if (queue_isempty(dst))
+ dst->head = src->head;
+ else
+ dst->tail->next = src->head;
+
+ dst->tail = src->tail;
+ src->head = NULL;
+ return;
+}
+