summaryrefslogtreecommitdiffstats
path: root/arch/m68k/mach-mcfv4e/net/nbuf.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/m68k/mach-mcfv4e/net/nbuf.c')
-rw-r--r--arch/m68k/mach-mcfv4e/net/nbuf.c239
1 files changed, 239 insertions, 0 deletions
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
+}