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.c 1969-12-31
16:00:00.0 -0800
+++ kernel/drivers/net/ehea/ehea_qmr.c 2006-06-08 01:58:28.862208992 -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;