Signed-off-by: Jan-Bernd Themann <[EMAIL PROTECTED]>
drivers/net/ehea/ehea_qmr.c | 719
drivers/net/ehea/ehea_qmr.h | 390 +++
2 files changed, 1109 insertions(+)
--- linux-2.6.16-rc5-orig/drivers/net/ehea/ehea_qmr.c1969-12-31
16:00:00.0 -0800
+++ kernel/drivers/net/ehea/ehea_qmr.c2006-06-07 07:01:14.664174144 -0700
@@ -0,0 +1,719 @@
+/*
+ * linux/drivers/net/ehea/ehea_qmr.c
+ *
+ * eHEA ethernet device driver for IBM eServer System p
+ *
+ * (C) Copyright IBM Corp. 2006
+ *
+ * Authors:
+ * Christoph Raisch <[EMAIL PROTECTED]>
+ * Jan-Bernd Themann <[EMAIL PROTECTED]>
+ * Heiko-Joerg Schick <[EMAIL PROTECTED]>
+ * Thomas Klein <[EMAIL PROTECTED]>
+ *
+ *
+ * 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "ehea.h"
+#include "ehea_phyp.h"
+#include "ehea_qmr.h"
+
+static void *ipz_qpageit_get_inc(struct ipz_queue *queue)
+{
+void *retvalue = ipz_qeit_get(queue);
+queue->current_q_offset += queue->pagesize;
+if (queue->current_q_offset > queue->queue_length) {
+queue->current_q_offset -= queue->pagesize;
+retvalue = NULL;
+}
+else if u64) retvalue) & (EHEA_PAGESIZE-1)) != 0) {
+EDEB(4, "ERROR!! not at PAGE-Boundary");
+return NULL;
+}
+EDEB(7, "queue=%p retvalue=%p", queue, retvalue);
+return retvalue;
+}
+
+static int ipz_queue_ctor(struct ipz_queue *queue,
+ const u32 nr_of_pages,
+ const u32 pagesize, const u32 qe_size,
+ const u32 nr_of_sg)
+{
+int f;
+EDEB_EN(7, "nr_of_pages=%x pagesize=%x qe_size=%x",
+nr_of_pages, pagesize, qe_size);
+queue->queue_length = nr_of_pages * pagesize;
+queue->queue_pages = vmalloc(nr_of_pages * sizeof(void *));
+if (!queue->queue_pages) {
+EDEB(4, "ERROR!! didn't get the memory");
+return 0;
+}
+memset(queue->queue_pages, 0, nr_of_pages * sizeof(void *));
+
+for (f = 0; f < nr_of_pages; f++) {
+(queue->queue_pages)[f] =
+(struct ipz_page *)get_zeroed_page(GFP_KERNEL);
+if (!(queue->queue_pages)[f]) {
+break;
+}
+}
+if (f < nr_of_pages) {
+int g;
+EDEB_ERR(4, "couldn't get 0ed pages queue=%p f=%x "
+ "nr_of_pages=%x", queue, f, nr_of_pages);
+for (g = 0; g < f; g++) {
+free_page((unsigned long)(queue->queue_pages)[g]);
+}
+return 0;
+}
+queue->current_q_offset = 0;
+queue->qe_size = qe_size;
+queue->act_nr_of_sg = nr_of_sg;
+queue->pagesize = pagesize;
+queue->toggle_state = 1;
+EDEB_EX(7, "queue_length=%x queue_pages=%p qe_size=%x"
+" act_nr_of_sg=%x", queue->queue_length, queue->queue_pages,
+queue->qe_size, queue->act_nr_of_sg);
+return 1;
+}
+
+static int ipz_queue_dtor(struct ipz_queue *queue)
+{
+int g;
+EDEB_EN(7, "ipz_queue pointer=%p", queue);
+if (!queue) {
+return 0;
+}
+if (!queue->queue_pages) {
+return 0;
+}
+EDEB(7, "destructing a queue with the following properties:\n"
+ "queue_length=%x act_nr_of_sg=%x pagesize=%x qe_size=%x",
+ queue->queue_length, queue->act_nr_of_sg, queue->pagesize,
+ queue->qe_size);
+for (g = 0; g < (queue->queue_length / queue->pagesize); g++) {
+free_page((unsigned long)(queue->queue_pages)[g]);
+}
+vfree(queue->queue_pages);
+
+EDEB_EX(7, "queue freed!");
+return 1;
+}
+
+struct ehea_cq *ehea_cq_new(void)
+{
+struct ehea_cq *cq = vmalloc(sizeof(*cq));
+if (cq)
+memset(cq, 0, sizeof(*cq));
+return cq;
+}
+
+void ehea_cq_delete(struct ehea_cq *cq)
+{
+vfree(cq);
+}
+
+struct ehea_cq *ehea_create_cq(struct ehea_adapter *adapter,
+ int nr_of_cqe, u64 eq_handle, u32 cq_token)
+{
+struct ehea_cq *cq = NULL;
+struct h_galpa gal;
+
+u64 *cq_handle_ref;
+u32 act_nr_of_entries;
+u32 act_pages;
+u64 hret;
+int ipz_rc;
+u32 counter;
+void *vpage = NULL;
+u64 rpage = 0;
+
+EDEB_EN(7, "adapter=%p nr_of_cqe=%x , eq_handle: %016lX",
+adapter, nr_of_cqe, eq_handle);
+
+cq = ehea_cq_new();
+if (!cq) {
+cq = NULL;
+EDEB_ERR(4, "ehea_create_cq ret=%p