Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH 3/4] Make Intel e1000 driver legacy I/O port free
From: Auke Kok @ 2006-06-07 14:40 UTC (permalink / raw)
  To: Kenji Kaneshige
  Cc: Auke Kok, Greg KH, akpm, Rajesh Shah, Grant Grundler, bibo,mao,
	linux-kernel, linux-pci, netdev, Jesse Brandeburg, Ronciak, John
In-Reply-To: <448682B6.5010302@jp.fujitsu.com>

Kenji Kaneshige wrote:
> Auke Kok wrote:
>> Kenji Kaneshige wrote:
>>
>>> This patch makes Intel e1000 driver legacy I/O port free.
>>>
>>> Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
>>
>> (adding netdev and the other e1000 maintainers to cc:)
>>
>> without sending this to any of the listed e1000 maintainers???? *and* 
>> not even including netdev???
>>
> 
> I'm sorry about that.

I also didn't see that you were sending this to Greg-KH. I think I got thrown 
off by that as I wasn't following lkml until yesterday in the first place. 
I'll toss the patches around over here and see what comes up.

Cheers,

Auke


^ permalink raw reply

* Re: [PATCH 1/2] e1000: fix netpoll with NAPI
From: Neil Horman @ 2006-06-07 15:05 UTC (permalink / raw)
  To: Matt Mackall
  Cc: Jeff Moyer, Auke Kok, Garzik, Jeff, Mitch Williams, netdev,
	Brandeburg, Jesse, Kok, Auke
In-Reply-To: <20060606231727.GK24227@waste.org>

>  
> > Matt, any ideas on this?
> 
> Not at the moment.

how about this for a solution?  It doesn't make netpoll any more robust, but I
think in the interests of efficiency it would be fair to require that, when
netpolled, a driver must receive frames on the same net device for which it was
polled.  With this patch we detect that condition and handle it accordingly in
e1000_intr.  This eliminates the need for us to call the clean_rx method from
the poll_controller when napi is configured, instead allowing the poll method to
be called from napi_poll, as the netpoll model currently does.  This fixes the
netdump regression, and eliminates the layering violation and the potential race
that we've been discussing.  I've just tested it with netdump here and it works
quite well.

Thoughts appreciated.

Thanks & Regards
Neil

Signed-off-by: Neil Horman <nhorman@tuxdriver.com>


 e1000_main.c |   54 +++++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 45 insertions(+), 9 deletions(-)


--- linux-2.6.9/drivers/net/e1000/e1000_main.c.neil	2006-06-06 10:37:42.000000000 -0400
+++ linux-2.6.9/drivers/net/e1000/e1000_main.c	2006-06-07 10:48:22.000000000 -0400
@@ -3207,8 +3207,9 @@
  * @pt_regs: CPU registers structure
  **/
 
+
 static irqreturn_t
-e1000_intr(int irq, void *data, struct pt_regs *regs)
+__e1000_intr(int irq, void *data, struct pt_regs *regs, int netpoll_op)
 {
 	struct net_device *netdev = data;
 	struct e1000_adapter *adapter = netdev_priv(netdev);
@@ -3217,6 +3218,7 @@
 #ifndef CONFIG_E1000_NAPI
 	int i;
 #else
+	struct net_device *dev_to_sched;
 	/* Interrupt Auto-Mask...upon reading ICR,
 	 * interrupts are masked.  No need for the
 	 * IMC write, but it does mean we should
@@ -3255,8 +3257,22 @@
 		E1000_WRITE_REG(hw, IMC, ~0);
 		E1000_WRITE_FLUSH(hw);
 	}
-	if (likely(netif_rx_schedule_prep(&adapter->polling_netdev[0])))
-		__netif_rx_schedule(&adapter->polling_netdev[0]);
+
+	/*
+	 * netpoll operations, in the interests of efficiency 
+	 * only do napi polling on the device passed to the 
+	 * poll_controller.  Therefore, if we are preforming 
+	 * a netpoll operation, then we can't schedule a receive
+	 * to one of the dummy net devices that exist for sole
+	 * purpose of spreading out rx schedules
+	 */	
+	if (netpoll_op)
+		dev_to_sched = netdev;
+	else
+		dev_to_sched = &adapter->polling_netdev[0];
+
+	if (likely(netif_rx_schedule_prep(dev_to_sched)))
+		__netif_rx_schedule(dev_to_sched);
 	else
 		e1000_irq_enable(adapter);
 #else
@@ -3288,6 +3304,13 @@
 	return IRQ_HANDLED;
 }
 
+static irqreturn_t
+e1000_intr(int irq, void *data, struct pt_regs *regs)
+{
+	return __e1000_intr(irq, data, regs, 0);
+}
+
+
 #ifdef CONFIG_E1000_NAPI
 /**
  * e1000_clean - NAPI Rx polling callback
@@ -3300,7 +3323,6 @@
 	struct e1000_adapter *adapter;
 	int work_to_do = min(*budget, poll_dev->quota);
 	int tx_cleaned = 0, i = 0, work_done = 0;
-
 	/* Must NOT use netdev_priv macro here. */
 	adapter = poll_dev->priv;
 
@@ -3308,10 +3330,24 @@
 	if (!netif_carrier_ok(adapter->netdev))
 		goto quit_polling;
 
-	while (poll_dev != &adapter->polling_netdev[i]) {
-		i++;
-		if (unlikely(i == adapter->num_rx_queues))
-			BUG();
+	/*
+	 * only search for a matching polling_netdev in the event
+	 * that this isn't a real registered net_device
+	 * A real net device can be passed in here in the event
+	 * that netdump has been activated (this comes through 
+	 * netpoll_poll_dev).  We detect this by virtue of the 
+	 * fact that each polling_netdev->priv points to the private
+	 * data of its parent (registered) netdev.  So if:
+	 * poll_dev->priv == netdev_priv(poll_dev), its a real device
+	 * otherwise its a polling_netdev.
+	 */
+	if (adapter != netdev_priv(poll_dev)) {
+		while (poll_dev != &adapter->polling_netdev[i]) {
+			i++;
+			if (unlikely(i == adapter->num_rx_queues))
+				BUG();
+		}
+
 	}
 
 	if (likely(adapter->num_tx_queues == 1)) {
@@ -4624,7 +4660,7 @@
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	disable_irq(adapter->pdev->irq);
-	e1000_intr(adapter->pdev->irq, netdev, NULL);
+	__e1000_intr(adapter->pdev->irq, netdev, NULL, 1);
 	e1000_clean_tx_irq(adapter, adapter->tx_ring);
 #ifndef CONFIG_E1000_NAPI
 	adapter->clean_rx(adapter, adapter->rx_ring);
-- 
/***************************************************
 *Neil Horman
 *Software Engineer
 *gpg keyid: 1024D / 0x92A74FA1 - http://pgp.mit.edu
 ***************************************************/

^ permalink raw reply

* [PATCH 0/4] ehea: IBM eHEA Ethernet Device Driver
From: Jan-Bernd Themann @ 2006-06-07 15:12 UTC (permalink / raw)
  To: netdev; +Cc: raisch, themann, tklein, meder, schickhj

Hello,

this is the first version of the IBM eHEA Ethernet Device Driver.
It supports a new IBM ethernet chip on System p.

Main functionality including broadcast multicast and some parts of
ethtool already work.

Things we're still working on:
- vlan support
- performance improvements in SMP systems
- kernel coding style

This code is not ready for kernel inclusion as is, but we definetly
want to get there.

The patch series consists of 4 patches
01: interfaces to network stack and headers
02: pHYP interface
03: queue managment
04: Kconfig and Makefile

Signed-off-by:  Jan-Bernd Themann <themann@de.ibm.com>

 drivers/net/ehea/Kconfig     |    6
 drivers/net/ehea/Makefile    |   45
 drivers/net/ehea/ehea.h      |  434 +++++++
 drivers/net/ehea/ehea_hw.h   |  319 +++++
 drivers/net/ehea/ehea_main.c | 2571 
+++++++++++++++++++++++++++++++++++++++++++
 drivers/net/ehea/ehea_phyp.c | 1026 +++++++++++++++++
 drivers/net/ehea/ehea_phyp.h |  625 ++++++++++
 drivers/net/ehea/ehea_qmr.c  |  719 ++++++++++++
 drivers/net/ehea/ehea_qmr.h  |  390 ++++++
 9 files changed, 6135 insertions(+)




^ permalink raw reply

* HELP! Slip Interface losing packets. Looking for contractor to fix.
From: Butler, Gerald @ 2006-06-07 15:22 UTC (permalink / raw)
  To: netdev, linux-kernel, linux-serial


Hello,


 	We have a custom compiled Linux Kernel running oh RHEL 3.1


 		[root@st0056_1 root]# uname -a
 		Linux st0056_1 2.4.21-32.0.1.ELcustom #12 SMP Wed Sep 14 11:55:22 EDT 2005 i686 i686 i386 GNU/Linux


 	We compiled in SLIP support using the standard RHEL kernel supplied by Redhat. Unfortunately, RH does not support SLIP. We are experiencing problems that we believe are a kernel issue (either SLIP or SERIAL) and are interested in hiring a contractor to diagnose the problem and provide a kernel patch to the kernel we are using (if necessary). We do not want to upgrade or change distributions at this time (business/practicality reasons).


 	If you are interested, please send an e-mail with your resume (doc, odf, or plain text) to 'gerald.edward.butler@gmail.com' (I'll provide a private e-mail address to interested parties).


 	The company website is here: http://www.sterlingjewelers.com/


 Thank You,
 



 	Gerald Butler
 	Project Manager - Store Systems
 	Sterling Inc
 




The information contained in this e-mail message is privileged and/or
confidential and is intended only for the use of the individual or entity
named above.  If the reader of this message is not the intended
recipient, or the employee or agent responsible to deliver it to the
intended recipient, you are hereby notified that any dissemination,
distribution or copying of this communication is strictly prohibited.
If you have received this communication in error, please immediately
notify us by telephone (330-668-5000), and destroy the original
message.  Thank you.


^ permalink raw reply

* Re: Problem authenticating using WPA with bcm43xx-softmac
From: Larry Finger @ 2006-06-07 15:47 UTC (permalink / raw)
  To: Johannes Berg; +Cc: netdev
In-Reply-To: <1149682213.3999.14.camel@johannes>

Johannes Berg wrote:
> 
> generic IE is what the wext is called, it is the IE that wpa_supplicant
> sets. Not sure what's going on though, I know next to nothing about wpa.

I have a little more information on what is happening. In IEEE Std 802.11i-2004, which defines the 
WPA protocol, Figure 11a shows the sequence of exchanges needed to associate. Both bcm43xx-softmac 
and ndiswrapper go through the "Open System Authentication" process. Where they seem to diverge is 
in the STA's "Association Request (Security Parameters)" step. With ndiswrapper, the AP responds 
with a WPA EAPOL-Key message; whereas with softmac, the AP sends back the "invalid pairwise cipher 
message" and rejects the association.

Can anyone point to a reference that states what the content of the Association Request should be to 
get the AP to respond with the EAPOL-Key message? Unfortunately, I have no possibility of 
implementing a sniffer to see what a "correct" message contains.

Larry

^ permalink raw reply

* Re: Problem authenticating using WPA with bcm43xx-softmac
From: Johannes Berg @ 2006-06-07 15:51 UTC (permalink / raw)
  To: Larry Finger; +Cc: netdev
In-Reply-To: <4486F513.5050906@lwfinger.net>

[-- Attachment #1: Type: text/plain, Size: 1038 bytes --]

On Wed, 2006-06-07 at 10:47 -0500, Larry Finger wrote:

> I have a little more information on what is happening. 

Great.

> In IEEE Std 802.11i-2004, which defines the 
> WPA protocol, Figure 11a shows the sequence of exchanges needed to associate. Both bcm43xx-softmac 
> and ndiswrapper go through the "Open System Authentication" process. 

Right, you always have to do that.

> Where they seem to diverge is 
> in the STA's "Association Request (Security Parameters)" step. With ndiswrapper, the AP responds 
> with a WPA EAPOL-Key message; whereas with softmac, the AP sends back the "invalid pairwise cipher 
> message" and rejects the association.

Interesting. That's strange.

> Can anyone point to a reference that states what the content of the Association Request should be to 
> get the AP to respond with the EAPOL-Key message? Unfortunately, I have no possibility of 
> implementing a sniffer to see what a "correct" message contains.

Well, it should be shown in the 802.11i spec too.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 793 bytes --]

^ permalink raw reply

* Re: [PATCH 2/7] AMSO1100 Low Level Driver.
From: Steve Wise @ 2006-06-07 15:56 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: rdreier, mshefty, linux-kernel, netdev, openib-general
In-Reply-To: <20060531115906.30f4bbda@localhost.localdomain>


On Wed, 2006-05-31 at 11:59 -0700, Stephen Hemminger wrote:
> The following should be replaced with BUG_ON() or WARN_ON().
> and pr_debug()
> 
> +#ifdef C2_DEBUG
> +#define assert(expr)                                                  \
> +    if(!(expr)) {                                                     \
> +        printk(KERN_ERR PFX "Assertion failed! %s, %s, %s, line %d\n",\
> +               #expr, __FILE__, __FUNCTION__, __LINE__);              \
> +    }
> +#define dprintk(fmt, args...) do {printk(KERN_INFO PFX fmt, ##args);} while (0)
> +#else
> +#define assert(expr)          do {} while (0)
> +#define dprintk(fmt, args...) do {} while (0)
> +#endif				/* C2_DEBUG */
> 
> --------------------
> Also, you tend to use assert() as a bogus NULL pointer check.
> If you get passed a NULL, it is a bug, and the deref will fail
> and cause a pretty stack dump...
> 

done.

> 
> +static void c2_set_rxbufsize(struct c2_port *c2_port)
> +{
> +	struct net_device *netdev = c2_port->netdev;
> +
> +	assert(netdev != NULL);
> 
> Bogus, you will just fail on the deref below
> 

done.

> +
> +	if (netdev->mtu > RX_BUF_SIZE)
> +		c2_port->rx_buf_size =
> +		    netdev->mtu + ETH_HLEN + sizeof(struct c2_rxp_hdr) +
> +		    NET_IP_ALIGN;
> +	else
> +		c2_port->rx_buf_size = sizeof(struct c2_rxp_hdr) + RX_BUF_SIZE;
> +}
> 
> 
> +static void c2_rx_interrupt(struct net_device *netdev)
> +{
> +	struct c2_port *c2_port = netdev_priv(netdev);
> +	struct c2_dev *c2dev = c2_port->c2dev;
> +	struct c2_ring *rx_ring = &c2_port->rx_ring;
> +	struct c2_element *elem;
> +	struct c2_rx_desc *rx_desc;
> +	struct c2_rxp_hdr *rxp_hdr;
> +	struct sk_buff *skb;
> +	dma_addr_t mapaddr;
> +	u32 maplen, buflen;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&c2dev->lock, flags);
> +
> +	/* Begin where we left off */
> +	rx_ring->to_clean = rx_ring->start + c2dev->cur_rx;
> +
> +	for (elem = rx_ring->to_clean; elem->next != rx_ring->to_clean;
> +	     elem = elem->next) {
> +		rx_desc = elem->ht_desc;
> +		mapaddr = elem->mapaddr;
> +		maplen = elem->maplen;
> +		skb = elem->skb;
> +		rxp_hdr = (struct c2_rxp_hdr *) skb->data;
> +
> +		if (rxp_hdr->flags != RXP_HRXD_DONE)
> +			break;
> +		buflen = rxp_hdr->len;
> +
> +		/* Sanity check the RXP header */
> +		if (rxp_hdr->status != RXP_HRXD_OK ||
> +		    buflen > (rx_desc->len - sizeof(*rxp_hdr))) {
> +			c2_rx_error(c2_port, elem);
> +			continue;
> +		}
> +
> +		/* 
> +		 * Allocate and map a new skb for replenishing the host 
> +		 * RX desc 
> +		 */
> +		if (c2_rx_alloc(c2_port, elem)) {
> +			c2_rx_error(c2_port, elem);
> +			continue;
> +		}
> +
> +		/* Unmap the old skb */
> +		pci_unmap_single(c2dev->pcidev, mapaddr, maplen,
> +				 PCI_DMA_FROMDEVICE);
> +
> 
> prefetch(skb->data) here will help performance.
> 
> 

good. ok.

> +		/*
> +		 * Skip past the leading 8 bytes comprising of the 
> +		 * "struct c2_rxp_hdr", prepended by the adapter 
> +		 * to the usual Ethernet header ("struct ethhdr"), 
> +		 * to the start of the raw Ethernet packet.
> +		 * 
> +		 * Fix up the various fields in the sk_buff before 
> +		 * passing it up to netif_rx(). The transfer size 
> +		 * (in bytes) specified by the adapter len field of 
> +		 * the "struct rxp_hdr_t" does NOT include the 
> +		 * "sizeof(struct c2_rxp_hdr)".
> +		 */
> +		skb->data += sizeof(*rxp_hdr);
> +		skb->tail = skb->data + buflen;
> +		skb->len = buflen;
> +		skb->dev = netdev;
> +		skb->protocol = eth_type_trans(skb, netdev);
> +
> +		/* Drop arp requests to the pseudo nic ip addr */
> +		if (unlikely(ntohs(skb->protocol) == ETH_P_ARP)) {
> +			u8 *tpa;
> +
> +			/* pull out the tgt ip addr */
> +			tpa = skb->data /* beginning of the arp packet */
> +				+ 8	/* arp addr fmts, lens, and opcode */
> +				+ 6  	/* arp src hw addr */
> +				+ 4 	/* arp src proto addr */
> +				+ 6;	/* arp tgt hw addr */
> +			if (is_rnic_addr(c2dev->pseudo_netdev, *((u32 *)tpa))) {
> +				dprintk("Dropping arp req for"
> +					" %03d.%03d.%03d.%03d\n",
> +					tpa[0], tpa[1], tpa[2], tpa[3]); 
> +				kfree_skb(skb);
> +				continue;
> +			}
> +		} 
> 
> This is looks like a mess, please do it at a higher level or
> code it with proper structure headers
> 

This code can be removed entirely.  It can be avoided having the c2
driver set in_dev->cnf.arp_ignore to 1 when loaded.


> +
> +		netif_rx(skb);
> +
> +		netdev->last_rx = jiffies;
> +		c2_port->netstats.rx_packets++;
> +		c2_port->netstats.rx_bytes += buflen;
> +	}
> +
> +	/* Save where we left off */
> +	rx_ring->to_clean = elem;
> +	c2dev->cur_rx = elem - rx_ring->start;
> +	C2_SET_CUR_RX(c2dev, c2dev->cur_rx);
> +
> +	spin_unlock_irqrestore(&c2dev->lock, flags);
> +}
> +
> +/*
> + * Handle netisr0 TX & RX interrupts.
> + */
> +static irqreturn_t c2_interrupt(int irq, void *dev_id, struct pt_regs *regs)
> +{
> +	unsigned int netisr0, dmaisr;
> +	int handled = 0;
> +	struct c2_dev *c2dev = (struct c2_dev *) dev_id;
> +
> +	assert(c2dev != NULL);
> +
> +	/* Process CCILNET interrupts */
> +	netisr0 = readl(c2dev->regs + C2_NISR0);
> +	if (netisr0) {
> +
> +		/*
> +		 * There is an issue with the firmware that always
> +		 * provides the status of RX for both TX & RX 
> +		 * interrupts.  So process both queues here.
> +		 */
> +		c2_rx_interrupt(c2dev->netdev);
> +		c2_tx_interrupt(c2dev->netdev);
> +
> +		/* Clear the interrupt */
> +		writel(netisr0, c2dev->regs + C2_NISR0);
> +		handled++;
> +	}
> +
> +	/* Process RNIC interrupts */
> +	dmaisr = readl(c2dev->regs + C2_DISR);
> +	if (dmaisr) {
> +		writel(dmaisr, c2dev->regs + C2_DISR);
> +		c2_rnic_interrupt(c2dev);
> +		handled++;
> +	}
> +
> +	if (handled) {
> +		return IRQ_HANDLED;
> +	} else {
> +		return IRQ_NONE;
> +	}
> 
> 	return IRQ_RETVAL(handled);
> +}
> +
> +static int c2_up(struct net_device *netdev)
> +{
> +	struct c2_port *c2_port = netdev_priv(netdev);
> +	struct c2_dev *c2dev = c2_port->c2dev;
> +	struct c2_element *elem;
> +	struct c2_rxp_hdr *rxp_hdr;
> +	size_t rx_size, tx_size;
> +	int ret, i;
> +	unsigned int netimr0;
> +
> +	assert(c2dev != NULL);
> 
> More bogus asserts
> 

removed.

<snip>

> +static struct net_device_stats *c2_get_stats(struct net_device *netdev)
> +{
> +	struct c2_port *c2_port = netdev_priv(netdev);
> +
> +	return &c2_port->netstats;
> +}
> +
> +static int c2_set_mac_address(struct net_device *netdev, void *p)
> +{
> +	return -1;
> +}
> 
> If you don't handle changing mac_address, just leaveing
> dev->set_mac_address will do the right thing.
> Also, if you need to return an error, use -ESOMEERROR, not -1.
> 

I'll remove c2_set_mac_address() entirely.

<snip>


> This seems like log spam, or developer debug thing.
> You need to learn to watch netlink event's from user space.
> 

Yes, the entire block below will be removed.  It's not needed.

> 
> +
> +#ifdef NETEVENT_NOTIFIER
> +static int netevent_notifier(struct notifier_block *self, unsigned long event,
> +			     void *data)
> +{
> +	int i;
> +	u8 *ha;
> +	struct neighbour *neigh = data;
> +	struct netevent_redirect *redir = data;
> +	struct netevent_route_change *rev = data;
> +
> +	switch (event) {
> +	case NETEVENT_ROUTE_UPDATE:
> +		printk(KERN_ERR "NETEVENT_ROUTE_UPDATE:\n");
> +		printk(KERN_ERR "fib_flags           : %d\n",
> +		       rev->fib_info->fib_flags);
> +		printk(KERN_ERR "fib_protocol        : %d\n",
> +		       rev->fib_info->fib_protocol);
> +		printk(KERN_ERR "fib_prefsrc         : %08x\n",
> +		       rev->fib_info->fib_prefsrc);
> +		printk(KERN_ERR "fib_priority        : %d\n",
> +		       rev->fib_info->fib_priority);
> +		break;
> +
> +	case NETEVENT_NEIGH_UPDATE:
> +		printk(KERN_ERR "NETEVENT_NEIGH_UPDATE:\n");
> +		printk(KERN_ERR "nud_state : %d\n", neigh->nud_state);
> +		printk(KERN_ERR "refcnt    : %d\n", neigh->refcnt);
> +		printk(KERN_ERR "used      : %d\n", neigh->used);
> +		printk(KERN_ERR "confirmed : %d\n", neigh->confirmed);
> +		printk(KERN_ERR "      ha: ");
> +		for (i = 0; i < neigh->dev->addr_len; i += 4) {
> +			ha = &neigh->ha[i];
> +			printk("%02x:%02x:%02x:%02x:", ha[0], ha[1], ha[2],
> +			       ha[3]);
> +		}
> +		printk("\n");
> +
> +		printk(KERN_ERR "%8s: ", neigh->dev->name);
> +		for (i = 0; i < neigh->dev->addr_len; i += 4) {
> +			ha = &neigh->ha[i];
> +			printk("%02x:%02x:%02x:%02x:", ha[0], ha[1], ha[2],
> +			       ha[3]);
> +		}
> +		printk("\n");
> +		break;
> +
> +	case NETEVENT_REDIRECT:
> +		printk(KERN_ERR "NETEVENT_REDIRECT:\n");
> +		printk(KERN_ERR "old: ");
> +		for (i = 0; i < redir->old->neighbour->dev->addr_len; i += 4) {
> +			ha = &redir->old->neighbour->ha[i];
> +			printk("%02x:%02x:%02x:%02x:", ha[0], ha[1], ha[2],
> +			       ha[3]);
> +		}
> +		printk("\n");
> +
> +		printk(KERN_ERR "new: ");
> +		for (i = 0; i < redir->new->neighbour->dev->addr_len; i += 4) {
> +			ha = &redir->new->neighbour->ha[i];
> +			printk("%02x:%02x:%02x:%02x:", ha[0], ha[1], ha[2],
> +			       ha[3]);
> +		}
> +		printk("\n");
> +		break;
> +
> +	default:
> +		printk(KERN_ERR "NETEVENT_WTFO:\n");
> +	}
> +
> +	return NOTIFY_DONE;
> +}
> +
> +static struct notifier_block nb = {
> +	.notifier_call = netevent_notifier,
> +};
> +#endif
> +/*



Thanks,

Steve.




^ permalink raw reply

* Re: Problem authenticating using WPA with bcm43xx-softmac
From: Johannes Berg @ 2006-06-07 15:57 UTC (permalink / raw)
  To: Larry Finger; +Cc: netdev, Jouni Malinen
In-Reply-To: <1149695470.3925.7.camel@johannes>

[-- Attachment #1: Type: text/plain, Size: 523 bytes --]

On Wed, 2006-06-07 at 17:51 +0200, Johannes Berg wrote:

> Well, it should be shown in the 802.11i spec too.

I suppose that it is the association request, and needs to contain the
RSN described in 7.3.2.25 as per 7.2.3.4 in 802.11i. This is, afaik, the
'generic IE' that is added with the wext. Now, it looks like the RSN
isn't included but the WPA2 info or something? Also, the genIE in your
log doesn't look correct to me, starting with ffffff?? Jouni, do you
have any idea what might be going on?

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 793 bytes --]

^ permalink raw reply

* Re: Problem authenticating using WPA with bcm43xx-softmac
From: Sam Leffler @ 2006-06-07 16:01 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Larry Finger, netdev
In-Reply-To: <1149695470.3925.7.camel@johannes>

Johannes Berg wrote:
> On Wed, 2006-06-07 at 10:47 -0500, Larry Finger wrote:
> 
>> I have a little more information on what is happening. 
> 
> Great.
> 
>> In IEEE Std 802.11i-2004, which defines the 
>> WPA protocol, Figure 11a shows the sequence of exchanges needed to associate. Both bcm43xx-softmac 
>> and ndiswrapper go through the "Open System Authentication" process. 
> 
> Right, you always have to do that.
> 
>> Where they seem to diverge is 
>> in the STA's "Association Request (Security Parameters)" step. With ndiswrapper, the AP responds 
>> with a WPA EAPOL-Key message; whereas with softmac, the AP sends back the "invalid pairwise cipher 
>> message" and rejects the association.
> 
> Interesting. That's strange.
> 
>> Can anyone point to a reference that states what the content of the Association Request should be to 
>> get the AP to respond with the EAPOL-Key message? Unfortunately, I have no possibility of 
>> implementing a sniffer to see what a "correct" message contains.
> 
> Well, it should be shown in the 802.11i spec too.

Beware of the order of IE's in the management frames; some AP's are
touchy about this.

	Sam


^ permalink raw reply

* Re: Problem authenticating using WPA with bcm43xx-softmac
From: Johannes Berg @ 2006-06-07 16:06 UTC (permalink / raw)
  To: Sam Leffler; +Cc: Larry Finger, netdev
In-Reply-To: <4486F866.9040901@errno.com>

[-- Attachment #1: Type: text/plain, Size: 252 bytes --]

On Wed, 2006-06-07 at 09:01 -0700, Sam Leffler wrote:

> Beware of the order of IE's in the management frames; some AP's are
> touchy about this.

Uh oh. I have no idea where the ieee80211 layer sticks that one,
probably at the end.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 793 bytes --]

^ permalink raw reply

* Re: Problem authenticating using WPA with bcm43xx-softmac
From: Larry Finger @ 2006-06-07 16:09 UTC (permalink / raw)
  To: Sam Leffler; +Cc: Johannes Berg, netdev
In-Reply-To: <4486F866.9040901@errno.com>

Sam Leffler wrote:
> Beware of the order of IE's in the management frames; some AP's are
> touchy about this.

That may be the cause here as the behavior when I changed AP's from the Linux-based model to one 
with VXWorks.

Larry

^ permalink raw reply

* Re: [patch] workaround zd1201 interference problem
From: Daniel Drake @ 2006-06-07 16:22 UTC (permalink / raw)
  To: Pavel Machek; +Cc: Jiri Benc, linville, kernel list, netdev
In-Reply-To: <20060607141536.GD1936@elf.ucw.cz>

Pavel Machek wrote:
> Well, I'll try _enable() alone, but it seems to me that _enable()
> command is needed to initialize radio properly. I do not think we can
> get much further without firmware sources...

If you can formulate a proper and technical description of the issue 
(and exactly what is needed to workaround it), I can contact ZyDAS for 
you. They have been very helpful with ZD1211.

Daniel

^ permalink raw reply

* Re: Problem authenticating using WPA with bcm43xx-softmac
From: Larry Finger @ 2006-06-07 16:30 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Sam Leffler, netdev
In-Reply-To: <1149696400.3925.13.camel@johannes>

Johannes Berg wrote:
> On Wed, 2006-06-07 at 09:01 -0700, Sam Leffler wrote:
> 
>> Beware of the order of IE's in the management frames; some AP's are
>> touchy about this.
> 
> Uh oh. I have no idea where the ieee80211 layer sticks that one,
> probably at the end.

I can verify that. I'm currently building a new module with a printk to verify that it is being 
added. If it is, I'll try moving it to see if it helps.

Larry

^ permalink raw reply

*  AD:StartSCMÆóÒµ¹©Ó¦Á´,»¥ÁªÍøÊ±´ú¹ÜÀíÓ¦ÓÃϵͳ
From: nB4a @ 2006-06-07 16:33 UTC (permalink / raw)
  To: 9YETfmIhHhT8B


    ÔÚÏß²âÊÔµØÖ· http://starterp.oicp.net/scm/   ÕʺÅ:admin  ÃÜÂë:admin
×Éѯµç»°:0 7 5 5 - 6 1 2 8 7 3 1 1  ²ÜÏÈÉú  E-mail: caoshan@starterp.net

    Start¹©Ó¦Á´ÊÇÀûÓû¥ÁªÍø¼¼ÊõºÍÏÖ´ú¿Æ¼¼¹ÜÀíÊֶν¨Á¢ÆðÀ´µÄÒ»Ì×ÍêÕûµÄÉÌÆ·»¯µÄÆóÒµ¹ÜÀíÈí¼þ£¬
ÊÇרÃÅÓÃÀ´¹ÜÀí¹©Ó¦ÉÌ¡¢ÁãÊÛÉÌ¡¢Åú·¢ÉÌÒÔ¼°×îÖÕ¿Í»§µÄ×ÛºÏÓ¦ÓÃϵͳ¡£

¡¡¡¡Start¹©Ó¦Á´½è¼øÁ˹úÄÚÍâÓÅÐ㹩ӦÁ´Èí¼þµÄÌØµã£¬²ÉÓÃÁËȫеÄÏÖ´ú¹ÜÀí˼ÏëºÍÏȽøµÄ¼¼ÊõÊֶΣ¬
Ëü¿ÉÒÔÓÐЧµØ½«ÆóÒµºÍºÏ×÷»ï°é½ôÃܵØÁªÏµÆðÀ´£¬¿ÉÒÔ³ÖÐø¿É¿¿µØÂú×ã¸÷Àà¿Í»§µÄÐèÇ󣬿ÉÒÔ×î´óÏÞ¶È
µØ½µµÍÆóÒµµÄ·çÏÕ£¬×îÖÕʵÏÖÒÔ×îµÍµÄ³É±¾ºÍ·ÑÓÃÌṩ×î´óµÄ¼ÛÖµºÍ×îºÃµÄ·þÎñ¡£ÈçͼËùʾ¡£

    Start¹©Ó¦Á´ÌṩÁËÍêÕûµÄ¹©Ó¦Á´¹ÜÀí£¬Ê¹µÃ²É¹ºÔ­²ÄÁÏ£¬µ½ÖÐÐÄ¿â´æ¹ÜÀí£¬µ½Õû¸öÏúÊÛͨ·ÉϵÄÎï
Á÷¹ÜÀí±äµÃÇáÇáËÉËÉ¡£ÏµÍ³ÖÐÉæ¼°µ½µÄËùÓÐÒµÎñ¶¼Äܹ»×Ô¶¯Éú³ÉÏàÓ¦µÄ»á¼ÆÆ¾Ö¤£¬´ó´ó·½±ãÁËÆóÒµµÄ»á¼Æ
ºËËãºÍ²ÆÎñ¹ÜÀí¹¤×÷¡£Ö÷Òª°üÀ¨£ºÏúÊÛ¡¢¿â´æ¡¢²É¹º¡¢ÆÚÄ©¡¢±¨±í¡¢×ÊÁÏ¡¢ÏµÍ³ÅäÖá£ÈçͼһËùʾ¡£


¡¡¡¡£¨Ò»£©ÏúÊÛ

¡¡¡¡ÏúÊÛ¸²¸ÇÆóÒµÏúÊ۵ĸ÷¸ö»·½Ú¡£Í¨¹ýÏúÊÛ¶©µ¥Â¼ÈëÓë±ä¸ü£¬¸ú×Ù¹ÜÀíÏúÊÛÇé¿ö£»¸ù¾Ý»õÆ·±¨¼ÛºÍÏúÊÛ
ÊýÁ¿×Ô¶¯¿ª³öÏúÊÛ·¢Æ±£¬¸ù¾Ý·¢»õµ¥²úÉú½áËãÆ¾Ö¤ºÍÊÕ»õµ¥£»Ìṩʵ¼ÊÏúÊÛÉÌÆ·½ð¶îÓëÕÊÃæ½ð¶îºË¶Ô¹¦ÄÜ
£»ÌṩÁ˿ͻ§ÐÅÓöî¶È¿ØÖƹ¦ÄÜ£¬¿ÉÒÔ´ïµ½½µµÍÏúÊÛ·çÏÕ£¬¼õÉÙÓ¦ÊÕ´ôÕ˵ÄÄ¿µÄ£¬»¹¿ÉÒÔʵÏÖÒµÎñÔ±ÏúÊÛ
Òµ¼¨¡¢ÏúÊÛÖ¸±êÍê³ÉÇé¿öµÄ¿¼ºË¹¦ÄÜ¡£

ÏúÊÛ¶©µ¥
ÏúÊÛ·¢»õµ¥
ÏúÊÛ·¢Æ±
ÏúÊÛÊÕ¿î
ÏúÊÛÍË»õ
ÏúÊÛÍË»õ·¢Æ±
ÏúÊÛÍË»õ¸¶¿î
ÏúÊÛÒµÎñÉóºË
ÏúÊÛÒµÎñ²éÕÒ

£¨¶þ£©²É¹º

²É¹º¸²¸ÇÆóÒµ²É¹ºµÄ¸÷¸ö»·½Ú¡£Æóҵͨ¹ýÐéÄâµÄÔÚÏß»õƷĿ¼£¬Ñ¸ËÙ¶øÊµÊ±µÄ·ÃÎÊ»õÆ·ÐÅÏ¢£»Í¨¹ý¼Û¸ñºÍÆ·
ÖʵıȽϣ¬Ñ¡¶¨²úÆ·¹©Ó¦ÉÌ£»²É¹ºÈËԱͨ¹ýϵͳ¶Ô¿â´æ×´¿öµÄ·ÖÎöÆÀ¹À¹©Ó¦É̵ÄʵÁ¦£»ÊµÊ±¶øÑ¸ËÙµØÁ˽⹩
Ó¦É̵ÄÐÅÏ¢£¬±ÜÃ⴫ͳ½»Ò×ÖеÄÖÖÖÖÕϰ­¡£
²É¹º¶©µ¥
²É¹ºÊÕ»õ
²É¹º·¢Æ±
²É¹º¸¶¿î
²É¹ºÍË»õ
²É¹ºÍË»õ·¢Æ±
²É¹ºÍË»õÊÕ¿î
²É¹ºÒµÎñÉóºË
²É¹ºÒµÎñ²éÕÒ

£¨Èý£©´æ»õ

¸ù¾Ý²É¹ºµ¥½øÐÐÈë¿âµÇ¼Ç£»¿ÉÒÔʵÏÖ»õÆ·Å̵㡢ËðºÄµÇ¼Ç¡¢¿â´æµ÷²¦µÈ¹¦ÄÜ£»¶Ô½ø³ö²Ö»õÆ·Êý¾Ý½øÐк˶ԡ£
½ø¿âµ¥
³ö¿âµ¥
ÆäËûÊÕ»õµ¥
ÆäËû·¢»õµ¥
²Ö¿âµ÷²¦
´æ»õÒµÎñÉóºË
´æ»õÒµÎñ²éÕÒ

£¨ËÄ£©ÆÚÄ©

ÆÚÄ©ÌṩÁË»õÆ·Å̵㡢»õÆ·µ÷¼ÛÒÔ¼°ÒµÎñÉóºËµÈÆÚĩҵÎñ´¦Àí¹¦ÄÜ£¬ÒµÎñÆÚÄ©½áËãΪ²ÆÎñÆÚÄ©½áËã×öÁ˱ØÒª
µÄÆÌµæ×÷Óá£
»õÆ·Å̵ã
»õÆ·µ÷¼Û
ÆÚĩҵÎñÉóºË

£¨Î壩±¨±í

¸ù¾Ý²»Í¬µÄÒµÎñÐèÇó£¬ÌṩÁ˲»Í¬µÄ±¨±í¡£Ã¿Ò»À౨±í¶¼¿ÉÒÔ¸ù¾ÝÆóÒµµÄÐèÒª½øÐлã×Üͳ¼ÆÓйصÄÏîÄ¿¡£±¨
±í¿ÉÒÔ°ïÖúÆóÒµÁìµ¼ÊÊʱ¼à¶½ÒµÎñ¼Æ»®£¬Á˽ⶩµ¥µÄÖ´ÐÐÇé¿ö£¬½øÐÐÏà¹ØÊý¾Ý·ÖÎö£¬½øÒ»²½½øÐо­Óª¾ö²ß¡£

£¨Áù£©×ÊÁÏ

Óû§¿ÉÒÔ¿ìËÙ¡¢Ö±¹ÛµØ²éѯËùÐèÒªµÄÊý¾Ý×ÊÁÏ¡£
¿Í»§ºÍ¹©Ó¦ÉÌ×ÊÁÏ
»õÆ·ºÍ²Ö¿â×ÊÁÏ
ÒµÎñ×ÊÁÏ
¹«Ë¾ÐÅÏ¢
µ¥¾ÝÄ£°å

£¨Æß£©ÏµÍ³¹ÜÀí

ϵͳ¹ÜÀíÊÇÕû¸öϵͳµÄÃÅ»§£¬ÔÚϵͳµÄ°²È«ÐÔÉÏÆðµ½Á˲»¿É¹ÀÁ¿µÄ×÷Ó᣸÷ÖÖÐÅÏ¢ÒªÇó¾¡Á¿È«ÃæÏêϸ£¬Ê¹¹ÜÀí
±äµÃ¸üÇáËɸüÓÐЧ¡£
Óû§¹ÜÀí
Óû§×é¹ÜÀí
Óû§×éȨÏÞ¶¨Òå
Óû§È¨ÏÞ¶¨Òå
ΪÓû§×é·ÖÅäÓû§

    Start¹©Ó¦Á´Ö÷ÒªÊÇΪÖÐСÐÍÆóҵʵÏÖÈ«Ãæ¹ÜÀí¶øÑз¢µÄ£¬·ûºÏÎÒ¹úÏÖ´úÆóÒµµÄ·ÖÏúģʽ£¬Ö§³Ö¶àÖÖ·ÖÏú
ÒµÎñÌØÓеÄÏúÊÛ½±Àø·½Ê½¡£Start¹©Ó¦Á´°ïÖúÆóÒµ·½±ãµØÕûºÏÇþµÀ×ÊÔ´£¬Í³³ïÐÅÏ¢¡¢»õÆ·Óë×ʽð¹ÜÀí£¬¼õÉÙÆóÒµ
µÄÔËÓª³É±¾£¬Ìá¸ßÁ˹¤×÷ЧÂÊ¡£Ö÷ÒªÌØµãÓУº

    ÏȽøµÄWebģʽ£ºÏµÍ³ÍêÈ«»ùÓÚWebģʽ£¬²ÉÓÃÏȽøµÄä¯ÀÀÆ÷/·þÎñÆ÷£¨B/S£©µÄ½á¹¹£¬ÍêÈ«Í»ÆÆÁË´«Í³ÍøÂçʱ
¿ÕÏÞÖÆµÄ¸ÅÄî¡£ÄúÖ»ÒªÁ¬½ÓÉÏInternet£¬¾Í¿ÉÒÔÔÚÈκÎʱ¼ä¡¢Èκεص㡢ÒÔÈκνÓÈ뷽ʽµÇ¼ϵͳ£¬ÇáËÉ×ÔÈçµØ
¹¤×÷¡£ÏµÍ³Êý¾Ý¼¯³É¶È¸ß£ºStart¹©Ó¦Á´Í»ÆÆÁË´«Í³µÄÊý¾Ý´«µÝ·½Ê½£¬²ÉÓÃÁË"ÎÞ·ìÁ´½Ó"µÄ¸ÅÄ¸÷Ä£¿éÖ®¼äµÄÊý
¾Ý×ªÒÆ¿É×Ô¶¯Íê³É£¬±ÜÃâÁËÖØ¸´ÊäÈ룬±£Ö¤ÁËÊý¾ÝµÄÒ»ÖÂÐÔ¡¢Á¬¹áÐÔ£¬´Ó¶ø´ó´ó¼õÇáÁ˹¤×÷Á¿£¬Ìá¸ßÁ˹¤×÷ЧÂÊ¡£
¸ß¶ÈµÄ°²È«ÐÔ¡¢¿É¿¿ÐÔ£ºStart¹©Ó¦Á´Îª±£Ö¤ÆóÒµÄÚ²¿µÄЭͬ¹¤×÷£¬¶ÔËùÓÐÓû§½øÐÐÁËÑϸñµÄ·Ö×é¹ÜÀí£¬²¢¶Ôÿ¸ö
Óû§×é½øÐÐÑÏÃܵÄȨÏÞ·ÖÅ䣬³¹µ×½â¾öÁ˳¤ÆÚÀ§ÈÅÆóÒµÐÅÏ¢»¯µÄ°²È«ÐÔÎÊÌâ¡£

    ÍêÈ«µÄÍøÂ绯²Ù×÷£ºStart¹©Ó¦Á´»ùÓÚÏȽøµÄä¯ÀÀÆ÷/·þÎñÆ÷£¨B/S£©Ìåϵ½á¹¹¿ª·¢¶ø³É£¬ÊÇÕæÕýµÄÍøÂ绯ÐÅÏ¢
¹ÜÀíÈí¼þ¡£Êý¾Ý´«ÊäËٶȸü¼Ó¿ì½Ý¡¢×¼È·£¬ÆóÒµ¹ÜÀíЧÂʽ«µÃµ½´ó·ùÌá¸ß¡£

    µ¼º½Ê½µÄ²Ù×÷½çÃæ£ºStart¹©Ó¦Á´²ÉÓÃÁ˵¼º½Ê½²Ù×÷½çÃæ£¬¸Ã½çÃæ¼¯ºÏÁËËùÓеÄÒµÎñ²Ù×÷¹¦ÄÜ£¬Ö±¹ÛÐÎÏóµØÒý
µ¼Óû§½øÐÐÒµÎñ²Ù×÷¡£µ¼º½Ê½µÄ½çÃæÊ¹¸÷ÏîÒµÎñ²Ù×÷±äµÃÇáËÉ×ÔÈç¡£

    È«ÄܵÄÐÅÏ¢²éѯ£ºStart¹©Ó¦Á´ÌṩÁËÇ¿´óµÄ×ÊÁÏÖÐÐÄ£¬°üÀ¨²É¹º¡¢ÏúÊÛ¡¢¿â´æ¡¢ÆÚÄ©¡¢±¨±íµÈһϵÁж¯Ì¬Êý
¾Ý×ÊÁÏ£¬¸²¸ÇÃæ¹ã£¬Í³¼Æ·½·¨¿ÆÑ§£¬Êý¾Ý׼ȷ¡£Óû§¿ÉÒÔ°´ÕÕÏà¹ØÌõ¼þ¶Ô¶©µ¥¡¢ÊÕ»õ¡¢ÍË»õ¡¢¸¶¿î¡¢¿â´æ¡¢ÏúÊÛµÈ
½øÐÐ×éºÏ²éѯ¡£

    ·½±ãµÄÓ¦Óö¨Öƹ¦ÄÜ£ºStart¹©Ó¦Á´²ÉÓõ±½ñÁ÷Ðеı¨±íÉè¼ÆÆ÷½øÐе¥¾Ý¡¢Õ˱íµÄÉè¼Æ£¬²¢ÎªÓû§ÌṩÁË×ÔÓɶ¨
ÖÆ¸÷Ààԭʼµ¥¾Ý¡¢Õ˱í¸ñʽµÄ¹¦ÄÜ£»Óû§²»½ö¿ÉÒÔ¶Ôµ¥¾Ý¡¢Õ˱íÍâ¹Û½øÐÐÉè¼Æ£¨°üÀ¨¶Ô¸ñʽ¡¢×ÖÌå¡¢±ß¿ò¡¢±³¾°µÈµÄ
Éè¼Æ£©£¬¶øÇÒ¿ÉÒÔÉ趨±¨±íÄÚ²¿Êý¾ÝµÄ¼ÆËã·½·¨£¨°üÀ¨¶ÔÊý¾ÝÀ´Ô´µÄÉ趨¡¢Êý¾ÝËã·¨µÄÉ趨µÈ£©£¬Í¬Ê±¼æ¾ßWORDºÍ
EXCELµÄÇ¿´ó¹¦ÄÜ¡£



^ permalink raw reply

* Re: [PATCH 1/2] e1000: fix netpoll with NAPI
From: Matt Mackall @ 2006-06-07 16:48 UTC (permalink / raw)
  To: Neil Horman
  Cc: Jeff Moyer, Auke Kok, Garzik, Jeff, Mitch Williams, netdev,
	Brandeburg, Jesse, Kok, Auke
In-Reply-To: <20060607150522.GA24608@hmsreliant.homelinux.net>

On Wed, Jun 07, 2006 at 11:05:22AM -0400, Neil Horman wrote:
> >  
> > > Matt, any ideas on this?
> > 
> > Not at the moment.
> 
> how about this for a solution?  It doesn't make netpoll any more robust, but I
> think in the interests of efficiency it would be fair to require that, when
> netpolled, a driver must receive frames on the same net device for which it was
> polled.  With this patch we detect that condition and handle it accordingly in
> e1000_intr.  This eliminates the need for us to call the clean_rx method from
> the poll_controller when napi is configured, instead allowing the poll method to
> be called from napi_poll, as the netpoll model currently does.  This fixes the
> netdump regression, and eliminates the layering violation and the potential race
> that we've been discussing.  I've just tested it with netdump here and it works
> quite well.
> 
> Thoughts appreciated.

This looks pretty reasonable, mostly from the perspective that it
doesn't put any further ugliness in netpoll. We might want to add a
comment somewhere in netpoll of the new rule we're now observing.
I'll let the e1000 guys comment on the particulars of the driver change.

> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
Signed-off-by: Matt Mackall <mpm@selenic.com>

-- 
Mathematics is the supreme nostalgia of our time.

^ permalink raw reply

* [PATCH 2/4] ehea: pHYP interface
From: Jan-Bernd Themann @ 2006-06-07 17:04 UTC (permalink / raw)
  To: netdev; +Cc: meder, raisch, themann, tklein

Signed-off-by:  Jan-Bernd Themann <themann@de.ibm.com>


drivers/net/ehea/ehea_phyp.c | 1026 +++++++++++++++++++++++++++++++++++++++++++
drivers/net/ehea/ehea_phyp.h |  625 ++++++++++++++++++++++++++
2 files changed, 1651 insertions(+)



--- linux-2.6.16-rc5-orig/drivers/net/ehea/ehea_phyp.c    1969-12-31 16:00:00.000000000 -0800
+++ kernel/drivers/net/ehea/ehea_phyp.c    2006-06-07 07:01:14.658175056 -0700
@@ -0,0 +1,1026 @@
+/*
+ *  linux/drivers/net/ehea/ehea_phyp.c
+ *
+ *  eHEA ethernet device driver for IBM eServer System p
+ *
+ *  (C) Copyright IBM Corp. 2006
+ *
+ *  Authors:
+ *       Christoph Raisch <raisch@de.ibm.com>
+ *       Jan-Bernd Themann <themann@de.ibm.com>
+ *       Heiko-Joerg Schick <schickhj@de.ibm.com>
+ *       Thomas Klein <tklein@de.ibm.com>
+ *
+ *
+ * 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_phyp.h"
+
+
+static inline u16 get_order_of_qentries(u16 queue_entries)
+{
+    u8 ld = 1;        /*  logarithmus dualis */
+    EDEB_EN(7, "queue_entries=0x%X", queue_entries);
+    while (((1U << ld) - 1) < queue_entries) {
+        ld++;
+    };
+    EDEB_EX(7, "mapped queue_entries=%d", ld - 1);
+    return ld - 1;
+}
+
+
+/* Defines for H_CALL H_ALLOC_RESOURCE */
+#define H_ALL_RES_TYPE_QP        1
+#define H_ALL_RES_TYPE_CQ        2
+#define H_ALL_RES_TYPE_EQ        3
+#define H_ALL_RES_TYPE_MR        5
+#define H_ALL_RES_TYPE_MW        6
+
+u64 hipz_h_query_ehea_qp(const u64 hcp_adapter_handle,
+             const u8 qp_category,
+             const u64 qp_handle, const u64 sel_mask, void *cb_addr)
+{
+    u64 hret = H_ADAPTER_PARM;
+    u64 dummy = 0;
+
+    EDEB_EN(7, "hcp_adapter_handle=%lX cat=%X qp_handle=%lX sel_mask=%lX "
+        "cb_addr=%p\n",
+        hcp_adapter_handle,
+        (u16) qp_category, qp_handle, sel_mask, cb_addr);
+    EDEB_DMP(7, (u8 *) cb_addr, sizeof(struct hcp_modify_qp_cb_0),
+         "Before HCALL");
+
+    if ((((u64)cb_addr) & (PAGE_SIZE - 1)) != 0)
+        panic("query_ehea_qp: cb_addr not on page boundary!!!");
+
+    hret = ehea_hcall_7arg_7ret(H_QUERY_EHEA_QP,
+                    hcp_adapter_handle,            /* R4 */
+                    qp_category,            /* R5 */
+                    qp_handle,                    /* R6 */
+                    sel_mask,                    /* R7 */
+                    virt_to_abs(cb_addr),    /* R8 */
+                    0, 0,                    /* R9-R10 */
+                    &dummy,                     /* R4 */
+                    &dummy,                     /* R5 */
+                    &dummy,                    /* R6 */
+                    &dummy,                    /* R7 */
+                    &dummy,                    /* R8 */
+                    &dummy,                    /* R9 */
+                    &dummy);                    /* R10 */
+
+    EDEB_DMP(7, (u8 *) cb_addr, sizeof(struct hcp_modify_qp_cb_0),
+         "After HCALL");
+    EDEB_EX(7, "");
+    return hret;
+}
+
+/* input param R5 */
+#define H_ALL_RES_QP_EQPO         EHEA_BMASK_IBM(9, 11)
+#define H_ALL_RES_QP_QPP          EHEA_BMASK_IBM(12, 12)
+#define H_ALL_RES_QP_RQR          EHEA_BMASK_IBM(13, 15)
+#define H_ALL_RES_QP_EQEG         EHEA_BMASK_IBM(16, 16)
+#define H_ALL_RES_QP_LL_QP        EHEA_BMASK_IBM(17, 17)
+#define H_ALL_RES_QP_DMA128       EHEA_BMASK_IBM(19, 19)
+#define H_ALL_RES_QP_HSM          EHEA_BMASK_IBM(20, 21)
+#define H_ALL_RES_QP_SIGT         EHEA_BMASK_IBM(22, 23)
+#define H_ALL_RES_QP_TENURE       EHEA_BMASK_IBM(48, 55)
+#define H_ALL_RES_QP_RES_TYP      EHEA_BMASK_IBM(56, 63)
+
+/* input param R9  */
+#define H_ALL_RES_QP_TOKEN        EHEA_BMASK_IBM(0, 31)
+#define H_ALL_RES_QP_PD           EHEA_BMASK_IBM(32,63)
+
+/* input param R10 */
+#define H_ALL_RES_QP_MAX_SWQE     EHEA_BMASK_IBM(4, 7)
+#define H_ALL_RES_QP_MAX_R1WQE    EHEA_BMASK_IBM(12, 15)
+#define H_ALL_RES_QP_MAX_R2WQE    EHEA_BMASK_IBM(20, 23)
+#define H_ALL_RES_QP_MAX_R3WQE    EHEA_BMASK_IBM(28, 31)
+/* Max Send Scatter Gather Elements */
+#define H_ALL_RES_QP_MAX_SSGE     EHEA_BMASK_IBM(37, 39)
+#define H_ALL_RES_QP_MAX_R1SGE    EHEA_BMASK_IBM(45, 47)
+/* Max Receive SG Elements RQ1 */
+#define H_ALL_RES_QP_MAX_R2SGE    EHEA_BMASK_IBM(53, 55)
+#define H_ALL_RES_QP_MAX_R3SGE    EHEA_BMASK_IBM(61, 63)
+
+/* input param R11 */
+#define H_ALL_RES_QP_SWQE_IDL     EHEA_BMASK_IBM(0, 7)
+/* max swqe immediate data length */
+#define H_ALL_RES_QP_PORT_NUM     EHEA_BMASK_IBM(48, 63)
+
+/* input param R12 */
+#define H_ALL_RES_QP_TH_RQ2       EHEA_BMASK_IBM(0, 15)
+/* Threshold RQ2 */
+#define H_ALL_RES_QP_TH_RQ3       EHEA_BMASK_IBM(16, 31)
+/* Threshold RQ3 */
+
+/* output param R6 */
+#define H_ALL_RES_QP_ACT_SWQE     EHEA_BMASK_IBM(0, 15)
+#define H_ALL_RES_QP_ACT_R1WQE    EHEA_BMASK_IBM(16, 31)
+#define H_ALL_RES_QP_ACT_R2WQE    EHEA_BMASK_IBM(32, 47)
+#define H_ALL_RES_QP_ACT_R3WQE    EHEA_BMASK_IBM(48, 63)
+
+/* output param, R7 */
+#define H_ALL_RES_QP_ACT_SSGE     EHEA_BMASK_IBM(0, 7)
+#define H_ALL_RES_QP_ACT_R1SGE    EHEA_BMASK_IBM(8, 15)
+#define H_ALL_RES_QP_ACT_R2SGE    EHEA_BMASK_IBM(16, 23)
+#define H_ALL_RES_QP_ACT_R3SGE    EHEA_BMASK_IBM(24, 31)
+#define H_ALL_RES_QP_ACT_SWQE_IDL EHEA_BMASK_IBM(32, 39)
+
+/* output param R8,R9 */
+#define H_ALL_RES_QP_SIZE_SQ      EHEA_BMASK_IBM(0, 31)
+#define H_ALL_RES_QP_SIZE_RQ1     EHEA_BMASK_IBM(32, 63)
+#define H_ALL_RES_QP_SIZE_RQ2     EHEA_BMASK_IBM(0, 31)
+#define H_ALL_RES_QP_SIZE_RQ3     EHEA_BMASK_IBM(32, 63)
+
+/* output param R11,R12 */
+#define H_ALL_RES_QP_LIOBN_SQ     EHEA_BMASK_IBM(0, 31)
+#define H_ALL_RES_QP_LIOBN_RQ1    EHEA_BMASK_IBM(32, 63)
+#define H_ALL_RES_QP_LIOBN_RQ2    EHEA_BMASK_IBM(0, 31)
+#define H_ALL_RES_QP_LIOBN_RQ3    EHEA_BMASK_IBM(32, 63)
+
+u64 hipz_h_alloc_resource_qp(const u64 adapter_handle,
+                 struct ehea_qp *ehea_qp,
+                 struct ehea_qp_init_attr *init_attr,
+                 const u32 pd,
+                 u64 *qp_handle, struct h_galpas *h_galpas)
+{
+    u64 hret = H_ADAPTER_PARM;
+
+    u64 allocate_controls =
+        EHEA_BMASK_SET(H_ALL_RES_QP_EQPO, init_attr->low_lat_rq1 ? 1 : 0)
+        | EHEA_BMASK_SET(H_ALL_RES_QP_QPP, 0)
+        | EHEA_BMASK_SET(H_ALL_RES_QP_RQR, 6)    /* RQ1 & RQ2 & rq3 */
+        |EHEA_BMASK_SET(H_ALL_RES_QP_EQEG, 0)    /* EQE gen. disabled */
+        |EHEA_BMASK_SET(H_ALL_RES_QP_LL_QP, init_attr->low_lat_rq1)
+        | EHEA_BMASK_SET(H_ALL_RES_QP_DMA128, 0)
+        | EHEA_BMASK_SET(H_ALL_RES_QP_HSM, 0)
+        | EHEA_BMASK_SET(H_ALL_RES_QP_SIGT, init_attr->signalingtype)
+        | EHEA_BMASK_SET(H_ALL_RES_QP_RES_TYP, H_ALL_RES_TYPE_QP);
+
+    u64 r9_reg = EHEA_BMASK_SET(H_ALL_RES_QP_PD, pd)
+        | EHEA_BMASK_SET(H_ALL_RES_QP_TOKEN, init_attr->qp_token);
+
+    u64 max_r10_reg =
+        EHEA_BMASK_SET(H_ALL_RES_QP_MAX_SWQE,
+              get_order_of_qentries(init_attr->max_nr_send_wqes))
+        | EHEA_BMASK_SET(H_ALL_RES_QP_MAX_R1WQE,
+                 get_order_of_qentries(init_attr->max_nr_rwqes_rq1))
+        | EHEA_BMASK_SET(H_ALL_RES_QP_MAX_R2WQE,
+                 get_order_of_qentries(init_attr->max_nr_rwqes_rq2))
+        | EHEA_BMASK_SET(H_ALL_RES_QP_MAX_R3WQE,
+                 get_order_of_qentries(init_attr->max_nr_rwqes_rq3))
+        | EHEA_BMASK_SET(H_ALL_RES_QP_MAX_SSGE, init_attr->wqe_size_enc_sq)
+        | EHEA_BMASK_SET(H_ALL_RES_QP_MAX_R1SGE,
+                 init_attr->wqe_size_enc_rq1)
+        | EHEA_BMASK_SET(H_ALL_RES_QP_MAX_R2SGE,
+                 init_attr->wqe_size_enc_rq2)
+        | EHEA_BMASK_SET(H_ALL_RES_QP_MAX_R3SGE,
+                 init_attr->wqe_size_enc_rq3);
+
+    u64 r11_in =
+        EHEA_BMASK_SET(H_ALL_RES_QP_SWQE_IDL, init_attr->swqe_imm_data_len)
+        | EHEA_BMASK_SET(H_ALL_RES_QP_PORT_NUM, init_attr->port_nr);
+    u64 threshold =
+        EHEA_BMASK_SET(H_ALL_RES_QP_TH_RQ2, init_attr->rq2_threshold)
+        | EHEA_BMASK_SET(H_ALL_RES_QP_TH_RQ3, init_attr->rq3_threshold);
+
+    u64 r5_out = 0;
+    u64 r6_out = 0;
+    u64 r7_out = 0;
+    u64 r8_out = 0;
+    u64 r9_out = 0;
+    u64 g_la_user_out = 0;
+    u64 r11_out = 0;
+    u64 r12_out = 0;
+
+    EDEB_EN(7, "adapter_handle=%lx low latency RQ1 0x%X"
+        " signalingtype=0x%X number of RQs=0x%X "
+        " send_cq_handle=%lx  receive_cq_handle=%lx"
+        " async_eq_handle=%lx"
+        " qp_token=0x%X  pd=0x%X max_nr_send_wqes=0x%X"
+        " max_nr_rcv_wqes_rq1=0x%X  max_nr_rcv_wqes_rq2=0x%X "
+        " max_nr_rcv_wqes_rq3=0x%X  wqe_enc_size=0x%X"
+        " wqe_enc_size_rq1=0x%X  wqe_enc_size_rq2=0x%X "
+        " wqe_enc_size_rq3=0x%X  port_nr=%d "
+        " rq2_threshold=%d  rq3_threshold=%d "
+        " galpa.pid=%x",
+        adapter_handle, init_attr->low_lat_rq1,
+        init_attr->signalingtype, init_attr->rq_count,
+        init_attr->send_cq_handle, init_attr->recv_cq_handle,
+        init_attr->aff_eq_handle, init_attr->qp_token,
+        pd, init_attr->max_nr_send_wqes, init_attr->max_nr_rwqes_rq1,
+        init_attr->max_nr_rwqes_rq2, init_attr->max_nr_rwqes_rq3,
+        init_attr->wqe_size_enc_sq, init_attr->wqe_size_enc_rq1,
+        init_attr->wqe_size_enc_rq2, init_attr->wqe_size_enc_rq3,
+        init_attr->port_nr, init_attr->rq2_threshold,
+        init_attr->rq3_threshold, h_galpas->pid);
+
+    hret = ehea_hcall_9arg_9ret(H_ALLOC_EHEA_RESOURCE,
+                     adapter_handle,        /* R4 */
+                     allocate_controls,        /* R5 */
+                     init_attr->send_cq_handle,    /* R6 */
+                     init_attr->recv_cq_handle,    /* R7 */
+                     init_attr->aff_eq_handle,    /* R8 */
+                     r9_reg,            /* R9 */
+                     max_r10_reg,        /* R10 */
+                     r11_in,            /* R11 */
+                     threshold,            /* R12 */
+                     qp_handle,            /* R4 */
+                     &r5_out,            /* R5 */
+                     &r6_out,            /* R6 */
+                     &r7_out,            /* R7 */
+                     &r8_out,            /* R8 */
+                     &r9_out,            /* R9 */
+                     &g_la_user_out,        /* R10 */
+                     &r11_out,            /* R11 */
+                     &r12_out);            /* R12 */
+
+    init_attr->qp_nr = (u32)r5_out;
+
+    init_attr->act_nr_send_wqes =
+        (u16)EHEA_BMASK_GET(H_ALL_RES_QP_ACT_SWQE, r6_out);
+    init_attr->act_nr_rwqes_rq1 =
+        (u16)EHEA_BMASK_GET(H_ALL_RES_QP_ACT_R1WQE, r6_out);
+    init_attr->act_nr_rwqes_rq2 =
+        (u16)EHEA_BMASK_GET(H_ALL_RES_QP_ACT_R2WQE, r6_out);
+    init_attr->act_nr_rwqes_rq3 =
+        (u16)EHEA_BMASK_GET(H_ALL_RES_QP_ACT_R3WQE, r6_out);
+
+/* Interface is under construction */
+    init_attr->act_wqe_size_enc_sq = init_attr->wqe_size_enc_sq;
+    init_attr->act_wqe_size_enc_rq1 = init_attr->wqe_size_enc_rq1;
+    init_attr->act_wqe_size_enc_rq2 = init_attr->wqe_size_enc_rq2;
+    init_attr->act_wqe_size_enc_rq3 = init_attr->wqe_size_enc_rq3;
+
+    init_attr->nr_sq_pages =
+        (u32)EHEA_BMASK_GET(H_ALL_RES_QP_SIZE_SQ, r8_out);
+    init_attr->nr_rq1_pages =
+        (u32)EHEA_BMASK_GET(H_ALL_RES_QP_SIZE_RQ1, r8_out);
+    init_attr->nr_rq2_pages =
+        (u32)EHEA_BMASK_GET(H_ALL_RES_QP_SIZE_RQ2, r9_out);
+    init_attr->nr_rq3_pages =
+        (u32)EHEA_BMASK_GET(H_ALL_RES_QP_SIZE_RQ3, r9_out);
+
+    init_attr->liobn_sq =
+        (u32)EHEA_BMASK_GET(H_ALL_RES_QP_LIOBN_SQ, r11_out);
+    init_attr->liobn_rq1 =
+        (u32)EHEA_BMASK_GET(H_ALL_RES_QP_LIOBN_RQ1, r11_out);
+    init_attr->liobn_rq2 =
+        (u32)EHEA_BMASK_GET(H_ALL_RES_QP_LIOBN_RQ2, r12_out);
+    init_attr->liobn_rq3 =
+        (u32)EHEA_BMASK_GET(H_ALL_RES_QP_LIOBN_RQ3, r12_out);
+
+    if (hret == H_SUCCESS)
+        hcp_galpas_ctor(h_galpas, g_la_user_out, g_la_user_out);
+
+    EDEB_EX(7, " qp_nr=%X, act_nr_send_wqes=%X,"
+        " act_nr_rcv_wqes_rq1=%X, act_nr_rcv_wqes_rq2=%X,"
+        " act_nr_rcv_wqes_rq3=%X, act_nr_send_sges=%X,"
+        " act_nr_rcv_sges_rq1=%X, act_nr_rcv_sges_rq2=%X,"
+        " act_nr_rcv_sges_rq3=%X, nr_sq_pages=%X,"
+        " nr_rq1_pages=%X, nr_rq2_pages=%X, nr_rq3_pages=%X,"
+        " galpa.user=%lx galpa.kernel=%lx",
+        init_attr->qp_nr, init_attr->act_nr_send_wqes,
+        init_attr->act_nr_rwqes_rq1, init_attr->act_nr_rwqes_rq2,
+        init_attr->act_nr_rwqes_rq3, init_attr->act_wqe_size_enc_sq,
+        init_attr->act_wqe_size_enc_rq1,
+        init_attr->act_wqe_size_enc_rq2,
+        init_attr->act_wqe_size_enc_rq3, init_attr->nr_sq_pages,
+        init_attr->nr_rq1_pages, init_attr->nr_rq2_pages,
+        init_attr->nr_rq3_pages, h_galpas->user.fw_handle,
+        h_galpas->kernel.fw_handle);
+
+    return hret;
+}
+
+u64 hipz_h_alloc_resource_cq(const u64 hcp_adapter_handle,
+                 struct ehea_cq *ehea_cq,
+                 struct ehea_cq_attr *cq_attr,
+                 u64 *cq_handle, struct h_galpas *galpas)
+{
+    u64 hret = H_ADAPTER_PARM;
+    u64 dummy = 0;
+    u64 act_nr_of_cqes_out;
+    u64 act_pages_out;
+    u64 g_la_privileged_out;
+    u64 g_la_user_out;
+
+    EDEB_EN(7, "hcp_adapter_handle=%lx eq_handle=%lx"
+        " cq_token=%x max_nr_of_cqes=%x",
+        hcp_adapter_handle, cq_attr->eq_handle, cq_attr->cq_token,
+        cq_attr->max_nr_of_cqes);
+
+
+    hret = ehea_hcall_7arg_7ret(H_ALLOC_EHEA_RESOURCE,
+                     hcp_adapter_handle,    /* R4 */
+                     H_ALL_RES_TYPE_CQ,        /* R5 */
+                     cq_attr->eq_handle,    /* R6 */
+                     cq_attr->cq_token,        /* R7 */
+                     cq_attr->max_nr_of_cqes,    /* R8 */
+                     dummy,            /* R9 */
+                     dummy,            /* R10 */
+                     cq_handle,            /* R4 */
+                     &dummy,            /* R5 */
+                     &dummy,            /* R6 */
+                     &act_nr_of_cqes_out,    /* R7 */
+                     &act_pages_out,        /* R8 */
+                     &g_la_privileged_out,    /* R9 */
+                     &g_la_user_out);        /* R10 */
+
+    cq_attr->act_nr_of_cqes = act_nr_of_cqes_out;
+    cq_attr->nr_pages = act_pages_out;
+
+    if (hret == H_SUCCESS)
+        hcp_galpas_ctor(galpas, g_la_privileged_out, g_la_user_out);
+
+    EDEB_EX(7, "cq_handle=%lx act_nr_of_entries=%x act_pages=%x ",
+        *cq_handle, cq_attr->act_nr_of_cqes, cq_attr->nr_pages);
+
+    return hret;
+}
+
+/* Defines for H_CALL H_ALLOC_RESOURCE */
+#define H_ALL_RES_TYPE_QP        1
+#define H_ALL_RES_TYPE_CQ        2
+#define H_ALL_RES_TYPE_EQ        3
+#define H_ALL_RES_TYPE_MR        5
+#define H_ALL_RES_TYPE_MW        6
+
+/*  input param R5 */
+#define H_ALL_RES_EQ_NEQ             EHEA_BMASK_IBM(0, 0)
+#define H_ALL_RES_EQ_NON_NEQ_ISN     EHEA_BMASK_IBM(6, 7)
+#define H_ALL_RES_EQ_INH_EQE_GEN     EHEA_BMASK_IBM(16, 16)
+#define H_ALL_RES_EQ_RES_TYPE        EHEA_BMASK_IBM(56, 63)
+/*  input param R6 */
+#define H_ALL_RES_EQ_MAX_EQE         EHEA_BMASK_IBM(32, 63)
+
+/*  output param R6 */
+#define H_ALL_RES_EQ_LIOBN           EHEA_BMASK_IBM(32, 63)
+
+/*  output param R7 */
+#define H_ALL_RES_EQ_ACT_EQE         EHEA_BMASK_IBM(32, 63)
+
+/*  output param R8 */
+#define H_ALL_RES_EQ_ACT_PS          EHEA_BMASK_IBM(32, 63)
+
+/*  output param R9 */
+#define H_ALL_RES_EQ_ACT_EQ_IST_C    EHEA_BMASK_IBM(30, 31)
+#define H_ALL_RES_EQ_ACT_EQ_IST_1    EHEA_BMASK_IBM(40, 63)
+
+/*  output param R10 */
+#define H_ALL_RES_EQ_ACT_EQ_IST_2    EHEA_BMASK_IBM(40, 63)
+
+/*  output param R11 */
+#define H_ALL_RES_EQ_ACT_EQ_IST_3    EHEA_BMASK_IBM(40, 63)
+
+/*  output param R12 */
+#define H_ALL_RES_EQ_ACT_EQ_IST_4    EHEA_BMASK_IBM(40, 63)
+
+u64 hipz_h_alloc_resource_eq(const u64 hcp_adapter_handle,
+                 struct ehea_eq *ehea_eq,
+                 struct ehea_eq_attr *eq_attr, u64 *eq_handle)
+{
+    u64 hret = H_ADAPTER_PARM;
+    u64 dummy;
+    u64 eq_liobn = 0;
+    u64 allocate_controls = 0;
+    u64 ist1_out = 0;
+    u64 ist2_out = 0;
+    u64 ist3_out = 0;
+    u64 ist4_out = 0;
+    u64 act_nr_of_eqes_out = 0;
+    u64 act_pages_out = 0;
+
+    EDEB_EN(7, "hcp_adapter_handle=%lx new_control=%x "
+        "number_of_entries=%x",
+        hcp_adapter_handle, eq_attr->type, eq_attr->max_nr_of_eqes);
+
+    /* resource type */
+    allocate_controls =
+        EHEA_BMASK_SET(H_ALL_RES_EQ_RES_TYPE, H_ALL_RES_TYPE_EQ)
+        | EHEA_BMASK_SET(H_ALL_RES_EQ_NEQ, eq_attr->type ? 1 : 0)
+        | EHEA_BMASK_SET(H_ALL_RES_EQ_INH_EQE_GEN, !eq_attr->eqe_gen)
+        | EHEA_BMASK_SET(H_ALL_RES_EQ_NON_NEQ_ISN, 1);
+
+    hret = ehea_hcall_9arg_9ret(H_ALLOC_EHEA_RESOURCE,
+                     hcp_adapter_handle,    /* R4 */
+                     allocate_controls,        /* R5 */
+                     eq_attr->max_nr_of_eqes,    /* R6 */
+                     0, 0, 0, 0, 0, 0,        /* R7-R10 */
+                     eq_handle,            /* R4 */
+                     &dummy,            /* R5 */
+                     &eq_liobn,            /* R6 */
+                     &act_nr_of_eqes_out,    /* R7 */
+                     &act_pages_out,        /* R8 */
+                     &ist1_out,            /* R9 */
+                     &ist2_out,            /* R10 */
+                     &ist3_out,            /* R11 */
+                     &ist4_out);        /* R12 */
+
+    eq_attr->act_nr_of_eqes = act_nr_of_eqes_out;
+    eq_attr->nr_pages = act_pages_out;
+    eq_attr->ist1 = ist1_out;
+    eq_attr->ist2 = ist2_out;
+    eq_attr->ist3 = ist3_out;
+    eq_attr->ist4 = ist4_out;
+
+    EDEB_EX(7, "act_nr_of_entries=%x act_pages=%x eq_ist1=%x",
+        eq_attr->act_nr_of_eqes, eq_attr->nr_pages, eq_attr->ist1);
+
+    return hret;
+}
+
+u64 hipz_h_modify_ehea_qp(const u64 hcp_adapter_handle,
+              const u8 cat,
+              const u64 qp_handle,
+              const u64 sel_mask,
+              void *cb_addr,
+              u64 *inv_attr_id,
+              u64 *proc_mask,
+              u16 *out_swr,
+              u16 *out_rwr)
+{
+    u64 hret = H_ADAPTER_PARM;
+    u64 dummy = 0;
+    u64 act_out_swr = 0;
+    u64 act_out_rwr = 0;
+
+    EDEB_EN(7, "hcp_adapter_handle=%lX cat=%X qp_handle=%lX sel_mask=%lX "
+        "cb_addr=%p\n",
+        hcp_adapter_handle, (u16) cat, qp_handle, sel_mask, cb_addr);
+    if ((((u64)cb_addr) & (PAGE_SIZE - 1)) != 0)
+        panic("query_ehea_qp: cb_addr not on page boundary!!!");
+
+    EDEB_DMP(7, (u8 *) cb_addr, sizeof(struct hcp_modify_qp_cb_0),
+         "Before HCALL");
+
+    hret = ehea_hcall_9arg_9ret(H_MODIFY_EHEA_QP,
+                     hcp_adapter_handle,    /* R4 */
+                     (u64) cat,            /* R5 */
+                     qp_handle,            /* R6 */
+                     sel_mask,            /* R7 */
+                     virt_to_abs(cb_addr),    /* R8 */
+                     0, 0, 0, 0,        /* R9-R12 */
+                     inv_attr_id,        /* R4 */
+                     &dummy,            /* R5 */
+                     &dummy,            /* R6 */
+                     &act_out_swr,        /* R7 */
+                     &act_out_rwr,        /* R8 */
+                     proc_mask,            /* R9 */
+                     &dummy,            /* R10 */
+                     &dummy,            /* R11 */
+                     &dummy);            /* R12 */
+    *out_swr = act_out_swr;
+    *out_rwr = act_out_rwr;
+    if (hret != H_SUCCESS) {
+        EDEB_ERR(4, "H_MODIFY_EHEA_QP failed. hret=%lx", hret);
+    }
+
+    EDEB_EX(7, "inv_attr_id=%lX proc_mask=%lX out_swr=%X out_rwr=%X",
+        *inv_attr_id, *proc_mask, *out_swr, *out_rwr);
+
+    return hret;
+}
+
+u64 hipz_h_register_rpage(const u64 hcp_adapter_handle,
+              const u8 pagesize,
+              const u8 queue_type,
+              const u64 resource_handle,
+              const u64 log_pageaddr, u64 count)
+{
+    u64 hret = H_ADAPTER_PARM;
+    u64 dummy;
+    u64 reg_control;
+    EDEB_EN(7, "hcp_adapter_handle=%lx pagesize=%x queue_type=%x "
+        "res_handle=%lx log_pageaddr=%lx "
+        "count=%lx",
+        hcp_adapter_handle,
+        pagesize, queue_type, resource_handle, log_pageaddr, count);
+
+    reg_control = EHEA_BMASK_SET(H_REG_RPAGE_PAGE_SIZE, pagesize)
+        | EHEA_BMASK_SET(H_REG_RPAGE_QT, queue_type);
+
+    hret = ehea_hcall_7arg_7ret(H_REGISTER_EHEA_RPAGES,
+                     hcp_adapter_handle,    /* R4 */
+                     reg_control,        /* R5 */
+                     resource_handle,        /* R6 */
+                     log_pageaddr,        /* R7 */
+                     count,            /* R8 */
+                     0,                /* R9 */
+                     0,                /* R10 */
+                     &dummy,            /* R4 */
+                     &dummy,            /* R5 */
+                     &dummy,            /* R6 */
+                     &dummy,            /* R7 */
+                     &dummy,            /* R8 */
+                     &dummy,            /* R9 */
+                     &dummy);            /* R10 */
+    EDEB_EX(7, "hret=%lx", hret);
+    return hret;
+}
+
+u64 hipz_h_register_rpage_eq(const u64 hcp_adapter_handle,
+                 const u64 eq_handle,
+                 const u8 pagesize,
+                 const u8 queue_type,
+                 const u64 log_pageaddr, const u64 count)
+{
+    u64 hret = H_ADAPTER_PARM;
+
+    EDEB_EN(7, "hcp_adapter_handle=%lx eq_handle=%lx"
+        " pagesize=%x queue_type=%x  log_pageaddr=%lx"
+        " count=%lx",
+        hcp_adapter_handle,
+        eq_handle, pagesize, queue_type, log_pageaddr, count);
+
+    if (count != 1) {
+        EDEB_ERR(4, "page counter=%lx", count);
+        return H_PARAMETER;
+    }
+
+    hret = hipz_h_register_rpage(hcp_adapter_handle,
+                     pagesize,
+                     queue_type,
+                     eq_handle, log_pageaddr, count);
+    EDEB_EX(7, "hret=%lx", hret);
+    return hret;
+}
+
+u64 hipz_h_register_rpage_cq(const u64 hcp_adapter_handle,
+                 const u64 cq_handle,
+                 const u8 pagesize,
+                 const u8 queue_type,
+                 const u64 log_pageaddr,
+                 const u64 count, const struct h_galpa gal)
+{
+    u64 hret = H_ADAPTER_PARM;
+
+    EDEB_EN(7, "hcp_adapter_handle=%lx cq_handle=%lx"
+        " pagesize=%x queue_type=%x  log_pageaddr=%lx"
+        " count=%lx",
+        hcp_adapter_handle,
+        cq_handle, pagesize, queue_type, log_pageaddr, count);
+
+    if (count != 1) {
+        EDEB_ERR(4, "page counter=%lx", count);
+        return H_PARAMETER;
+    }
+
+    hret = hipz_h_register_rpage(hcp_adapter_handle,
+                     pagesize,
+                     queue_type,
+                     cq_handle, log_pageaddr, count);
+
+    EDEB_EX(7, "hret=%lx", hret);
+    return hret;
+}
+
+u64 hipz_h_register_rpage_qp(const u64 hcp_adapter_handle,
+                 const u64 qp_handle,
+                 const u8 pagesize,
+                 const u8 queue_type,
+                 const u64 log_pageaddr,
+                 const u64 count, struct h_galpa galpa)
+{
+    u64 hret = H_ADAPTER_PARM;
+
+    EDEB_EN(7, "hcp_adapter_handle=%lx qp_handle=%lx"
+        " pagesize=%x queue_type=%x  log_pageaddr=%lx"
+        " count=%lx",
+        hcp_adapter_handle,
+        qp_handle, pagesize, queue_type, log_pageaddr, count);
+
+    if (count != 1) {
+        EDEB_ERR(4, "page counter=%lx", count);
+        return H_PARAMETER;
+    }
+
+    hret = hipz_h_register_rpage(hcp_adapter_handle,
+                     pagesize,
+                     queue_type,
+                     qp_handle, log_pageaddr, count);
+    EDEB_EX(7, "hret=%lx", hret);
+    return hret;
+}
+
+u64 hipz_h_destroy_qp(const u64 hcp_adapter_handle,
+              struct ehea_qp *qp,
+              u64 qp_handle, struct h_galpas *galpas)
+{
+    u64 hret = H_ADAPTER_PARM;
+    int ret = 0;
+    u64 dummy;
+    u64 ladr_next_sq_wqe_out;
+    u64 ladr_next_rq1_wqe_out;
+    u64 ladr_next_rq2_wqe_out;
+    u64 ladr_next_rq3_wqe_out;
+
+    EDEB_EN(7, "qp = %p ipz_qp_handle=%lx adapter_handle=%lx",
+        qp, qp_handle, hcp_adapter_handle);
+
+    ret = hcp_galpas_dtor(galpas);
+    if (ret) {
+        EDEB_ERR(4, "Could not destroy qp->galpas");
+        return H_RESOURCE;
+    }
+
+    hret = ehea_hcall_7arg_7ret(H_DISABLE_AND_GET_EHEA,
+                     hcp_adapter_handle,    /* R4 */
+                     H_DISABLE_GET_EHEA_WQE_P,    /* R5 */
+                     qp_handle,            /* R6 */
+                     0, 0, 0, 0,        /* R7-R10 */
+                     &ladr_next_sq_wqe_out,    /* R4 */
+                     &ladr_next_rq1_wqe_out,    /* R5 */
+                     &ladr_next_rq2_wqe_out,    /* R6 */
+                     &ladr_next_rq3_wqe_out,    /* R7 */
+                     &dummy,            /* R8 */
+                     &dummy,            /* R9 */
+                     &dummy);            /* R10 */
+    if (hret == H_HARDWARE) {
+        EDEB_ERR(4, "HCA NOT operational - hret=%lx", hret);
+        return hret;
+    }
+
+    hret = ehea_hcall_7arg_7ret(H_FREE_RESOURCE,
+                     hcp_adapter_handle,    /* R4 */
+                     qp_handle,            /* R5 */
+                     0,                /* R6  */
+                     0, 0, 0, 0,        /* R7-R10 */
+                     &dummy,            /* R4 */
+                     &dummy,            /* R5 */
+                     &dummy,            /* R6 */
+                     &dummy,            /* R7 */
+                     &dummy,            /* R8 */
+                     &dummy,            /* R9 */
+                     &dummy);            /* R10 */
+    if (hret == H_RESOURCE)
+        EDEB_ERR(4, "resource still in use - hret=%lx", hret);
+    EDEB_EX(7, "hret=%lx", hret);
+    return hret;
+}
+
+u64 hipz_h_destroy_cq(const u64 hcp_adapter_handle,
+              struct ehea_cq *cq,
+              u64 cq_handle, struct h_galpas *galpas)
+{
+    u64 hret = H_ADAPTER_PARM;
+    u64 dummy;
+
+    EDEB_EN(7, "destroy CQ Entry:>>>> cq = %p ,ipz_cq_handle=%lx"
+        "; adapter_handle=%lx", cq, cq_handle,
+        hcp_adapter_handle);
+    hret = hcp_galpas_dtor(galpas);
+    if (hret != H_SUCCESS) {
+        EDEB_ERR(4, "could not destroy cp->galpas");
+        return H_RESOURCE;
+    }
+
+    hret = ehea_hcall_7arg_7ret(H_FREE_RESOURCE,
+                     hcp_adapter_handle,    /* R4 */
+                     cq_handle,            /* R5 */
+                     0,                /* R6 */
+                     0, 0, 0, 0,        /* R7-R10 */
+                     &dummy,            /* R4 */
+                     &dummy,            /* R5 */
+                     &dummy,            /* R6 */
+                     &dummy,            /* R7 */
+                     &dummy,            /* R8 */
+                     &dummy,            /* R9 */
+                     &dummy);            /* R10 */
+
+    if (hret == H_RESOURCE)
+        EDEB_ERR(4, "resource in use - hret=%lx ", hret);
+
+    EDEB_EX(7, "hret=%lx", hret);
+    return hret;
+}
+
+u64 hipz_h_destroy_eq(const u64 hcp_adapter_handle,
+              struct ehea_eq * eq,
+              u64 eq_handle, struct h_galpas * galpas)
+{
+    u64 hret = H_ADAPTER_PARM;
+    u64 dummy;
+
+    EDEB_EN(7, "eq=%p ipz_eq_handle=%lx adapter_handle=%lx",
+        eq, eq_handle, hcp_adapter_handle);
+
+    hret = hcp_galpas_dtor(galpas);
+
+    if (hret != H_SUCCESS) {
+        EDEB_ERR(4, "could not destroy ep->galpas");
+        return H_RESOURCE;
+    }
+
+    hret = ehea_hcall_7arg_7ret(H_FREE_RESOURCE,
+                     hcp_adapter_handle,    /* R4 */
+                     eq_handle,            /* R5 */
+                     0,                /* R6 */
+                     0, 0, 0, 0,        /* R7-R10 */
+                     &dummy,            /* R4 */
+                     &dummy,            /* R5 */
+                     &dummy,            /* R6 */
+                     &dummy,            /* R7 */
+                     &dummy,            /* R8 */
+                     &dummy,            /* R9 */
+                     &dummy);            /* R10 */
+
+    if (hret == H_RESOURCE)
+        EDEB_ERR(4, "resource in use - hret=%lx ", hret);
+
+    EDEB_EX(7, "hret=%lx", hret);
+    return hret;
+}
+
+u64 hipz_h_free_resource_mr(const u64 hcp_adapter_handle,
+                const u64 mr_handle)
+{
+    u64 hret = H_ADAPTER_PARM;
+    u64 dummy;
+
+    EDEB_EN(7, "adapter_handle=%lx mr_handle=%lx",
+        hcp_adapter_handle, mr_handle);
+
+    hret = ehea_hcall_7arg_7ret(H_FREE_RESOURCE,
+                    hcp_adapter_handle,    /* r4 */
+                    mr_handle,             /* r5 */
+                    0, 0, 0, 0, 0,
+                    &dummy,
+                    &dummy,
+                    &dummy,
+                    &dummy,
+                    &dummy,
+                    &dummy,
+                    &dummy);
+
+    EDEB_EX(7, "hret=%lx", hret);
+    return hret;
+}
+
+u64 hipz_h_alloc_resource_mr(const u64 hcp_adapter_handle,
+                 const u64 vaddr,
+                 const u64 length,
+                 const u32 access_ctrl,
+                 const u32 pd, u64 * mr_handle, u32 * lkey)
+{
+    u64 hret = H_ADAPTER_PARM;
+    u64 dummy;
+    u64 lkey_out;
+
+    EDEB_EN(7, "hcp_adapter_handle=%lx vaddr=%lx length=%lx "
+        "access_ctrl=%x pd=%x",
+        hcp_adapter_handle, vaddr, length, access_ctrl, pd);
+
+
+    hret = ehea_hcall_7arg_7ret(H_ALLOC_EHEA_RESOURCE,
+                     hcp_adapter_handle,        /* R4 */
+                     5,                    /* R5 */
+                     vaddr,                /* R6 */
+                     length,                /* R7 */
+                     (((u64) access_ctrl) << 32ULL),    /* R8 */
+                     pd,                /* R9 */
+                     0,                    /* R10 */
+                     mr_handle,                /* R4 */
+                     &dummy,                /* R5 */
+                     &lkey_out,                /* R6 */
+                     &dummy,                /* R7 */
+                     &dummy,                /* R8 */
+                     &dummy,                /* R9 */
+                     &dummy);                /* R10 */
+    *lkey = (u32) lkey_out;
+
+    EDEB_EX(7, "hret=%lX mr_handle=%lX, lkey=%x", hret, *mr_handle, *lkey);
+    return hret;
+}
+
+u64 hipz_h_register_rpage_mr(const u64 hcp_adapter_handle,
+                 const u64 mr_handle,
+                 const u8 pagesize,
+                 const u8 queue_type,
+                 const u64 log_pageaddr, const u64 count)
+{
+    u64 hret = H_ADAPTER_PARM;
+
+    EDEB_EN(7, "hcp_adapter_handle=%lx mr_handle->handle=%lx"
+        " pagesize=%x queue_type=%x log_pageaddr=%lx"
+        " count=%lx",
+        hcp_adapter_handle,
+        mr_handle, pagesize, queue_type, log_pageaddr, count);
+
+    if ((count > 1) && (log_pageaddr & 0xfff)) {
+        EDEB_ERR(4, "log_pageaddr not on a 4k boundary");
+        hret = H_PARAMETER;
+    } else
+        hret = hipz_h_register_rpage(hcp_adapter_handle,
+                         pagesize,
+                         queue_type,
+                         mr_handle, log_pageaddr, count);
+
+    EDEB_EX(7, "hret=%lx", hret);
+    return hret;
+}
+
+u64 hipz_h_query_ehea(const u64 hcp_adapter_handle, void *cb_addr)
+{
+    u64 hret = H_ADAPTER_PARM;
+    u64 dummy = 0;
+    struct hcp_query_ehea *query_ehea_cb = (struct hcp_query_ehea *)cb_addr;
+    u64 cb_logaddr;
+
+    EDEB_EN(7, "hcp_adapter_handle=%lX query_ehea_cb=%p",
+        hcp_adapter_handle, query_ehea_cb);
+
+    cb_logaddr = virt_to_abs(cb_addr);
+
+    hret = ehea_hcall_7arg_7ret(H_QUERY_EHEA,
+                     hcp_adapter_handle,    /* >R4 */
+                     cb_logaddr,        /* >R5 */
+                     0, 0, 0, 0, 0,        /* >R6-R10 */
+                     &dummy,            /* <R4 */
+                     &dummy,            /* <R5 */
+                     &dummy,            /* <R6 */
+                     &dummy,            /* <R7 */
+                     &dummy,            /* <R8 */
+                     &dummy,            /* <R9 */
+                     &dummy);            /* <R10 */
+
+    EDEB_DMP(7, (u8 *) cb_addr, sizeof(struct hcp_query_ehea),
+         "hcp_query_ehea");
+
+    if (hret != H_SUCCESS)
+        EDEB_ERR(4, "H_QUERY_EHEA failed. hret=%lx", hret);
+
+    EDEB_EX(7, "hret=%lx", hret);
+    return hret;
+}
+
+u64 hipz_h_query_ehea_port(const u64 hcp_adapter_handle,
+               const u16 port_num,
+               const u8 cb_cat, const u64 select_mask,
+               void *cb_addr)
+{
+    u64 hret = H_ADAPTER_PARM;
+    u64 port_info = 0;
+    u64 arr_index = 0;
+    u64 dummy = 0;
+    u64 cb_logaddr = virt_to_abs(cb_addr);
+
+    EDEB_EN(7, "hcp_adapter_handle=%lX port_num=%X cb_cat=%X "
+        "select_mask=%lX cb_addr=%lX",
+        hcp_adapter_handle, port_num, cb_cat, select_mask, cb_logaddr);
+
+    port_info = EHEA_BMASK_SET(H_MEHEAPORT_CAT, cb_cat)
+        | EHEA_BMASK_SET(H_MEHEAPORT_PN, port_num);
+
+    hret = ehea_hcall_7arg_7ret(H_QUERY_EHEA_PORT,
+                     hcp_adapter_handle,    /* >R4 */
+                     port_info,            /* >R5 */
+                     select_mask,        /* >R6 */
+                     arr_index,            /* >R7 */
+                     cb_logaddr,        /* >R8 */
+                     0, 0,            /* >R9-R10 */
+                     &dummy,            /* <R4 */
+                     &dummy,            /* <R5 */
+                     &dummy,            /* <R6 */
+                     &dummy,            /* <R7 */
+                     &dummy,            /* <R8 */
+                     &dummy,            /* <R9 */
+                     &dummy);            /* <R10 */
+    if (hret != H_SUCCESS)
+        EDEB_ERR(4, "H_QUERY_EHEA_PORT failed. hret=%lx", hret);
+
+    EDEB_EX(7, "hret=%lx", hret);
+    return hret;
+}
+
+u64 hipz_h_modify_ehea_port(const u64 hcp_adapter_handle,
+                const u16 port_num,
+                const u8 cb_cat,
+                const u64 select_mask, void *cb_addr)
+{
+    u64 hret = H_ADAPTER_PARM;
+    u64 port_info = 0;
+    u64 arr_index = 0;
+    u64 dummy = 0;
+    u64 cb_logaddr = virt_to_abs(cb_addr);
+
+    EDEB_EN(7, "hcp_adapter_handle=%lX port_num=%X cb_cat=%X "
+        "select_mask=%lX cb_addr=%lX",
+        hcp_adapter_handle, port_num, cb_cat, select_mask, cb_logaddr);
+
+    port_info = EHEA_BMASK_SET(H_MEHEAPORT_CAT, cb_cat)
+        | EHEA_BMASK_SET(H_MEHEAPORT_PN, port_num);
+
+    EDEB_DMP(7, (u8 *) cb_addr,
+         sizeof(struct hcp_query_ehea_port_cb_0), "Before HCALL");
+
+    hret = ehea_hcall_7arg_7ret(H_MODIFY_EHEA_PORT,
+                     hcp_adapter_handle,    /* >R4 */
+                     port_info,            /* >R5 */
+                     select_mask,        /* >R6 */
+                     arr_index,            /* >R7 */
+                     cb_logaddr,        /* >R8 */
+                     0, 0,            /* >R9-R10 */
+                     &dummy,            /* <R4 */
+                     &dummy,            /* <R5 */
+                     &dummy,            /* <R6 */
+                     &dummy,            /* <R7 */
+                     &dummy,            /* <R8 */
+                     &dummy,            /* <R9 */
+                     &dummy);            /* <R10 */
+
+
+    if (hret != H_SUCCESS)
+        EDEB_ERR(4, "H_MODIFY_EHEA_PORT failed. hret=%lx", hret);
+
+    EDEB_EX(7, "hret=%lx", hret);
+    return hret;
+}
+
+u64 hipz_h_reg_dereg_bcmc(const u64 hcp_adapter_handle,
+              const u16 port_num,
+              const u8 reg_type,
+              const u64 mc_mac_addr,
+              const u16 vlan_id, const u32 hcall_id)
+{
+    u64 hret = H_ADAPTER_PARM;
+    u64 r5_port_num = 0;
+    u64 r6_reg_type = 0;
+    u64 r7_mc_mac_addr = 0;
+    u64 r8_vlan_id = 0;
+    u64 dummy = 0;
+
+    u64 mac_addr = mc_mac_addr >> 16;
+
+    EDEB_EN(7, "hcp_adapter_handle=%lX port_num=%X reg_type=%X "
+        "mc_mac_addr=%lX hcall_id=%X",
+        hcp_adapter_handle, port_num, reg_type, mc_mac_addr, hcall_id);
+
+    r5_port_num = EHEA_BMASK_SET(H_REGBCMC_PN, port_num);
+    r6_reg_type = EHEA_BMASK_SET(H_REGBCMC_REGTYPE, reg_type);
+    r7_mc_mac_addr = EHEA_BMASK_SET(H_REGBCMC_MACADDR, mac_addr);
+    r8_vlan_id = EHEA_BMASK_SET(H_REGBCMC_VLANID, vlan_id);
+
+
+    hret = ehea_hcall_7arg_7ret(hcall_id,
+                     hcp_adapter_handle,    /* >R4 */
+                     r5_port_num,        /* >R5 */
+                     r6_reg_type,        /* >R6 */
+                     r7_mc_mac_addr,        /* >R7 */
+                     r8_vlan_id,        /* >R8 */
+                     0, 0,            /* >R9-R10 */
+                     &dummy,            /* <R4 */
+                     &dummy,            /* <R5 */
+                     &dummy,            /* <R6 */
+                     &dummy,            /* <R7 */
+                     &dummy,            /* <R8 */
+                     &dummy,            /* <R9 */
+                     &dummy);            /* <R10 */
+
+    if (hret != H_SUCCESS)
+        EDEB_ERR(4, "HCALL 0x%x failed. hret=%lx", hcall_id, hret);
+
+    EDEB_EX(7, "hret=%lx", hret);
+    return hret;
+}
+
+u64 hipz_h_reset_events(const u64 hcp_adapter_handle,
+            const u64 neq_handle, const u64 event_mask)
+{
+    u64 hret = H_ADAPTER_PARM;
+    u64 dummy = 0;
+
+    EDEB_EN(7, "hcp_adapter_handle=%lX neq_handle=%lX event_mask=%lX ",
+        hcp_adapter_handle, neq_handle, event_mask);
+
+    hret = ehea_hcall_7arg_7ret(H_RESET_EVENTS,
+                     hcp_adapter_handle,    /* >R4 */
+                     neq_handle,        /* >R5 */
+                     event_mask,        /* >R6 */
+                     0, 0, 0, 0,        /* >R7-R10 */
+                     &dummy,            /* <R4 */
+                     &dummy,            /* <R5 */
+                     &dummy,            /* <R6 */
+                     &dummy,            /* <R7 */
+                     &dummy,            /* <R8 */
+                     &dummy,            /* <R9 */
+                     &dummy);            /* <R10 */
+    if (hret != H_SUCCESS)
+        EDEB_ERR(4, "H_RESET_EVENTS failed. hret=%lx", hret);
+
+    EDEB_EX(7, "hret=%lx", hret);
+    return hret;
+}
--- linux-2.6.16-rc5-orig/drivers/net/ehea/ehea_phyp.h    1969-12-31 16:00:00.000000000 -0800
+++ kernel/drivers/net/ehea/ehea_phyp.h    2006-06-07 07:01:15.392198488 -0700
@@ -0,0 +1,625 @@
+/*
+ *  linux/drivers/net/ehea/ehea_phyp.h
+ *
+ *  eHEA ethernet device driver for IBM eServer System p
+ *
+ *  (C) Copyright IBM Corp. 2006
+ *
+ *  Authors:
+ *       Christoph Raisch <raisch@de.ibm.com>
+ *       Jan-Bernd Themann <themann@de.ibm.com>
+ *       Heiko-Joerg Schick <schickhj@de.ibm.com>
+ *       Thomas Klein <tklein@de.ibm.com>
+ *
+ *
+ * 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.
+ */
+
+#ifndef __EHEA_PHYP_H__
+#define __EHEA_PHYP_H__
+
+#include <linux/delay.h>
+#include <asm/hvcall.h>
+#include "ehea.h"
+#include "ehea_hw.h"
+#include "ehea_hcall.h"
+
+
+static inline u32 get_longbusy_msecs(int long_busy_ret_code)
+{
+    switch (long_busy_ret_code) {
+    case H_LONG_BUSY_ORDER_1_MSEC:
+        return 1;
+    case H_LONG_BUSY_ORDER_10_MSEC:
+        return 10;
+    case H_LONG_BUSY_ORDER_100_MSEC:
+        return 100;
+    case H_LONG_BUSY_ORDER_1_SEC:
+        return 1000;
+    case H_LONG_BUSY_ORDER_10_SEC:
+        return 10000;
+    case H_LONG_BUSY_ORDER_100_SEC:
+        return 100000;
+    default:
+        return 1;
+    }
+}
+
+
+/* Notification Event Queue (NEQ) Entry bit masks */
+#define NEQE_EVENT_CODE        EHEA_BMASK_IBM(2, 7)
+#define NEQE_PORTNUM          EHEA_BMASK_IBM(32, 47)
+#define NEQE_PORT_UP        EHEA_BMASK_IBM(16, 16)
+#define NEQE_EXTSWITCH_PORT_UP    EHEA_BMASK_IBM(17, 17)
+#define NEQE_EXTSWITCH_PRIMARY    EHEA_BMASK_IBM(18, 18)
+#define NEQE_PLID        EHEA_BMASK_IBM(16, 47)
+
+/* Notification Event Codes */
+#define EHEA_EC_PORTSTATE_CHG    0x30
+#define EHEA_EC_ADAPTER_MALFUNC    0x32
+#define EHEA_EC_PORT_MALFUNC    0x33
+
+/* Notification Event Log Register (NELR) bit masks */
+#define NELR_PORT_MALFUNC    EHEA_BMASK_IBM(61, 61)
+#define NELR_ADAPTER_MALFUNC    EHEA_BMASK_IBM(62, 62)
+#define NELR_PORTSTATE_CHG    EHEA_BMASK_IBM(63, 63)
+
+static inline long ehea_hcall_9arg_9ret(unsigned long opcode,
+                    unsigned long arg1,
+                    unsigned long arg2,
+                    unsigned long arg3,
+                    unsigned long arg4,
+                    unsigned long arg5,
+                    unsigned long arg6,
+                    unsigned long arg7,
+                    unsigned long arg8,
+                    unsigned long arg9,
+                    unsigned long *out1,
+                    unsigned long *out2,
+                    unsigned long *out3,
+                    unsigned long *out4,
+                    unsigned long *out5,
+                    unsigned long *out6,
+                    unsigned long *out7,
+                    unsigned long *out8,
+                    unsigned long *out9)
+{
+    long hret = H_SUCCESS;
+    int i, sleep_msecs;
+
+    EDEB_EN(7, "opcode=%lx arg1=%lx arg2=%lx arg3=%lx arg4=%lx "
+        "arg5=%lx arg6=%lx arg7=%lx arg8=%lx arg9=%lx",
+        opcode, arg1, arg2, arg3, arg4, arg5, arg6, arg7,
+        arg8, arg9);
+
+
+    for (i = 0; i < 5; i++) {
+        hret = plpar_hcall_9arg_9ret(opcode,
+                        arg1, arg2, arg3, arg4,
+                        arg5, arg6, arg7, arg8,
+                        arg9,
+                        out1, out2, out3, out4,
+                        out5, out6, out7, out8,
+                        out9);
+
+        if (H_IS_LONG_BUSY(hret)) {
+            sleep_msecs = get_longbusy_msecs(hret);
+            msleep_interruptible(sleep_msecs);
+            continue;
+        }
+
+        if (hret < H_SUCCESS)
+            EDEB_ERR(4, "opcode=%lx hret=%lx"
+                 " arg1=%lx arg2=%lx arg3=%lx arg4=%lx"
+                 " arg5=%lx arg6=%lx arg7=%lx arg8=%lx"
+                 " arg9=%lx"
+                 " out1=%lx out2=%lx out3=%lx out4=%lx"
+                 " out5=%lx out6=%lx out7=%lx out8=%lx"
+                 " out9=%lx",
+                 opcode, hret,
+                 arg1, arg2, arg3, arg4,
+                 arg5, arg6, arg7, arg8,
+                 arg9,
+                 *out1, *out2, *out3, *out4,
+                 *out5, *out6, *out7, *out8,
+                 *out9);
+
+        EDEB_EX(7, "opcode=%lx hret=%lx out1=%lx out2=%lx out3=%lx "
+            "out4=%lx out5=%lx out6=%lx out7=%lx out8=%lx out9=%lx",
+            opcode, hret,*out1, *out2, *out3, *out4, *out5, *out6,
+            *out7, *out8, *out9);
+        return hret;
+
+    }
+
+    EDEB_EX(7, "opcode=%lx ret=H_BUSY", opcode);
+    return H_BUSY;
+}
+
+inline static long ehea_hcall_7arg_7ret(unsigned long opcode,
+                    unsigned long arg1,
+                    unsigned long arg2,
+                    unsigned long arg3,
+                    unsigned long arg4,
+                    unsigned long arg5,
+                    unsigned long arg6,
+                    unsigned long arg7,
+                    unsigned long *out1,
+                    unsigned long *out2,
+                    unsigned long *out3,
+                    unsigned long *out4,
+                    unsigned long *out5,
+                    unsigned long *out6,
+                    unsigned long *out7)
+{
+    long hret = H_SUCCESS;
+    int i, sleep_msecs;
+
+    EDEB_EN(7, "opcode=%lx arg1=%lx arg2=%lx arg3=%lx arg4=%lx arg5=%lx"
+        " arg6=%lx arg7=%lx", opcode, arg1, arg2, arg3, arg4, arg5,
+        arg6, arg7);
+
+    for (i = 0; i < 5; i++) {
+        hret = plpar_hcall_7arg_7ret(opcode,
+                        arg1, arg2, arg3, arg4,
+                        arg5, arg6, arg7,
+                        out1, out2, out3, out4,
+                        out5, out6, out7);
+
+        if (H_IS_LONG_BUSY(hret)) {
+            sleep_msecs = get_longbusy_msecs(hret);
+            msleep_interruptible(sleep_msecs);
+            continue;
+        }
+
+        if (hret < H_SUCCESS)
+            EDEB_ERR(4, "opcode=%lx ret=%lx"
+                 " arg1=%lx arg2=%lx arg3=%lx arg4=%lx"
+                 " arg5=%lx arg6=%lx arg7=%lx"
+                 " out1=%lx out2=%lx out3=%lx out4=%lx"
+                 " out5=%lx out6=%lx out7=%lx",
+                 opcode, hret,
+                 arg1, arg2, arg3, arg4,
+                 arg5, arg6, arg7,
+                 *out1, *out2, *out3, *out4,
+                 *out5, *out6, *out7);
+
+        EDEB_EX(7, "opcode=%lx hret=%lx out1=%lx out2=%lx out3=%lx "
+            "out4=%lx out5=%lx out6=%lx out7=%lx",
+            opcode, hret, *out1, *out2, *out3, *out4, *out5,
+            *out6, *out7);
+        return hret;
+    }
+
+    EDEB_EX(7, "opcode=%lx hret=H_BUSY", opcode);
+
+    return H_BUSY;
+}
+
+static inline int hcp_galpas_ctor(struct h_galpas *galpas,
+                  u64 paddr_kernel, u64 paddr_user)
+{
+
+    EDEB_EN(7, "ioremap physaddr=%lx mapaddr=%lx\n",
+         paddr_kernel, galpas->kernel.fw_handle);
+    galpas->kernel.fw_handle = (u64) ioremap(paddr_kernel, PAGE_SIZE);
+    galpas->user.fw_handle = paddr_user;
+
+    EDEB_EX(7, "paddr_kernel=%lx paddr_user=%lx galpas->kernel=%lx"
+         " galpas->user=%lx", paddr_kernel, paddr_user,
+         galpas->kernel.fw_handle, galpas->user.fw_handle);
+    return 0;
+}
+
+static inline int hcp_galpas_dtor(struct h_galpas *galpas)
+{
+
+    if (galpas->kernel.fw_handle)
+        iounmap((void *)galpas->kernel.fw_handle);
+    galpas->user.fw_handle = galpas->kernel.fw_handle = 0;
+    return 0;
+}
+
+struct hcp_modify_qp_cb_0 {
+    u64 qp_ctl_reg;        /* 00 */
+    u32 max_swqe;        /* 02 */
+    u32 max_rwqe;        /* 03 */
+    u32 port_nb;        /* 04 */
+    u32 reserved0;        /* 05 */
+    u64 qp_aer;        /* 06 */
+    u64 qp_tenure;        /* 08 */
+};
+
+/* Hcall Query/Modify Queue Pair Control Block 0 Selection Mask Bits */
+#define H_QPCB0_ALL             EHEA_BMASK_IBM(0, 5)
+#define H_QPCB0_QP_CTL_REG      EHEA_BMASK_IBM(0, 0)
+#define H_QPCB0_MAX_SWQE        EHEA_BMASK_IBM(1, 1)
+#define H_QPCB0_MAX_RWQE        EHEA_BMASK_IBM(2, 2)
+#define H_QPCB0_PORT_NB         EHEA_BMASK_IBM(3, 3)
+#define H_QPCB0_QP_AER          EHEA_BMASK_IBM(4, 4)
+#define H_QPCB0_QP_TENURE       EHEA_BMASK_IBM(5, 5)
+
+/* Queue Pair Control Register Status Bits */
+#define H_QP_CR_ENABLED            0x8000000000000000    /* Queue Pair enabled */
+                            /* QP States: */
+#define H_QP_CR_STATE_RESET        0x0000010000000000    /*  Reset */
+#define H_QP_CR_STATE_INITIALIZED   0x0000020000000000    /*  Initialized */
+#define H_QP_CR_STATE_RDY2RCV        0x0000030000000000    /*  Ready to receive */
+#define H_QP_CR_STATE_RDY2SND        0x0000050000000000    /*  Ready to send */
+#define H_QP_CR_STATE_ERROR        0x0000800000000000    /*  Error */
+
+struct hcp_modify_qp_cb_1 {
+    u32 qpn;        /* 00 */
+    u32 qp_asyn_ev_eq_nb;    /* 01 */
+    u64 sq_cq_handle;    /* 02 */
+    u64 rq_cq_handle;    /* 04 */
+    /* sgel = scatter gather element */
+    u32 sgel_nb_sq;        /* 06 */
+    u32 sgel_nb_rq1;    /* 07 */
+    u32 sgel_nb_rq2;    /* 08 */
+    u32 sgel_nb_rq3;    /* 09 */
+};
+
+/* Hcall Query/Modify Queue Pair Control Block 1 Selection Mask Bits */
+#define H_QPCB1_ALL             EHEA_BMASK_IBM(0, 7)
+#define H_QPCB1_QPN             EHEA_BMASK_IBM(0, 0)
+#define H_QPCB1_ASYN_EV_EQ_NB   EHEA_BMASK_IBM(1, 1)
+#define H_QPCB1_SQ_CQ_HANDLE    EHEA_BMASK_IBM(2, 2)
+#define H_QPCB1_RQ_CQ_HANDLE    EHEA_BMASK_IBM(3, 3)
+#define H_QPCB1_SGEL_NB_SQ      EHEA_BMASK_IBM(4, 4)
+#define H_QPCB1_SGEL_NB_RQ1     EHEA_BMASK_IBM(5, 5)
+#define H_QPCB1_SGEL_NB_RQ2     EHEA_BMASK_IBM(6, 6)
+#define H_QPCB1_SGEL_NB_RQ3     EHEA_BMASK_IBM(7, 7)
+
+struct hcp_query_ehea {
+    u32 cur_num_qps;        /* 00 */
+    u32 cur_num_cqs;        /* 01 */
+    u32 cur_num_eqs;        /* 02 */
+    u32 cur_num_mrs;        /* 03 */
+    u32 auth_level;            /* 04 */
+    u32 max_num_qps;        /* 05 */
+    u32 max_num_cqs;        /* 06 */
+    u32 max_num_eqs;        /* 07 */
+    u32 max_num_mrs;        /* 08 */
+    u32 reserved0;            /* 09 */
+    u32 int_clock_freq;        /* 10 */
+    u32 max_num_pds;        /* 11 */
+    u32 max_num_addr_handles;    /* 12 */
+    u32 max_num_cqes;        /* 13 */
+    u32 max_num_wqes;        /* 14 */
+    u32 max_num_sgel_rq1wqe;    /* 15 */
+    u32 max_num_sgel_rq2wqe;    /* 16 */
+    u32 max_num_sgel_rq3wqe;    /* 17 */
+    u32 mr_page_size;        /*define */
+    u32 reserved1;            /* 19 */
+    u64 max_mr_size;        /* 20 */
+    u64 reserved2;            /* 22 */
+    u32 num_ports;            /* 24 */
+    u32 reserved3;            /* 25 */
+    u32 reserved4;            /* 26 */
+    u32 reserved5;            /* 27 */
+    u64 max_mc_mac;            /* 28 */
+    u64 ehea_cap;            /* 30 */
+    u32 max_isn_per_eq;        /* 32 */
+    u32 max_num_neq;        /* 33 */
+    u64 max_num_vlan_ids;        /* 34 */
+    u32 max_num_port_group;        /* 36 */
+    u32 max_num_phys_port;        /* 37 */
+
+};
+
+/* Hcall Query/Modify Port Control Block defines */
+#define H_PORT_CB0     0
+#define H_PORT_CB1     1
+#define H_PORT_CB2     2
+#define H_PORT_CB3     3
+#define H_PORT_CB4     4
+#define H_PORT_CB5     5
+#define H_PORT_CB6     6
+#define H_PORT_CB7     7
+
+struct hcp_query_ehea_port_cb_0 {
+    u64 port_mac_addr;
+    u64 port_rc;
+    u64 reserved0;
+    u32 port_op_state;
+    u32 port_speed;
+    u32 ext_swport_op_state;
+    u32 neg_tpf_prpf;
+    u32 num_default_qps;
+    u32 reserved1;
+    u64 default_qpn_array[16];
+};
+
+/* Hcall Query/Modify Port Control Block 0 Selection Mask Bits */
+#define H_PORT_CB0_ALL        EHEA_BMASK_IBM(0, 7)    /* Set all bits */
+#define H_PORT_CB0_MAC        EHEA_BMASK_IBM(0, 0)    /* MAC address */
+#define H_PORT_CB0_PRC        EHEA_BMASK_IBM(1, 1)    /* Port Recv Control */
+#define H_PORT_CB0_DEFQPNARRAY    EHEA_BMASK_IBM(7, 7)    /* Default QPN Array */
+
+/*  Hcall Query Port: Returned port speed values */
+#define H_PORT_SPEED_10M_H    1    /*  10 Mbps, Half Duplex */
+#define H_PORT_SPEED_10M_F    2    /*  10 Mbps, Full Duplex */
+#define H_PORT_SPEED_100M_H    3    /* 100 Mbps, Half Duplex */
+#define H_PORT_SPEED_100M_F    4    /* 100 Mbps, Full Duplex */
+#define H_PORT_SPEED_1G_F    6    /*   1 Gbps, Full Duplex */
+#define H_PORT_SPEED_10G_F    8    /*  10 Gbps, Full Duplex */
+
+/* Port Receive Control Status Bits */
+#define PXLY_RC_VALID           EHEA_BMASK_IBM(49, 49)
+#define PXLY_RC_VLAN_XTRACT     EHEA_BMASK_IBM(50, 50)
+#define PXLY_RC_TCP_6_TUPLE     EHEA_BMASK_IBM(51, 51)
+#define PXLY_RC_UDP_6_TUPLE     EHEA_BMASK_IBM(52, 52)
+#define PXLY_RC_TCP_3_TUPLE     EHEA_BMASK_IBM(53, 53)
+#define PXLY_RC_TCP_2_TUPLE     EHEA_BMASK_IBM(54, 54)
+#define PXLY_RC_LLC_SNAP        EHEA_BMASK_IBM(55, 55)
+#define PXLY_RC_JUMBO_FRAME     EHEA_BMASK_IBM(56, 56)
+#define PXLY_RC_FRAG_IP_PKT     EHEA_BMASK_IBM(57, 57)
+#define PXLY_RC_TCP_UDP_CHKSUM  EHEA_BMASK_IBM(58, 58)
+#define PXLY_RC_IP_CHKSUM       EHEA_BMASK_IBM(59, 59)
+#define PXLY_RC_MAC_FILTER      EHEA_BMASK_IBM(60, 60)
+#define PXLY_RC_UNTAG_FILTER    EHEA_BMASK_IBM(61, 61)
+#define PXLY_RC_VLAN_TAG_FILTER EHEA_BMASK_IBM(62, 63)
+
+#define PXLY_RC_VLAN_FILTER     2
+#define PXLY_RC_VLAN_PERM       0
+
+
+#define H_PORT_CB1_ALL          0x8000000000000000
+
+struct hcp_query_ehea_port_cb_1 {
+    u64 vlan_filter[64];
+};
+
+#define H_PORT_CB2_ALL          0xFFE0000000000000
+
+struct hcp_query_ehea_port_cb_2 {
+    u64 rxo;
+    u64 rxucp;
+    u64 rxufd;
+    u64 rxuerr;
+    u64 rxftl;
+    u64 rxmcp;
+    u64 rxbcp;
+    u64 txo;
+    u64 txucp;
+    u64 txmcp;
+    u64 txbcp;
+};
+
+struct hcp_query_ehea_port_cb_3 {
+    u64 vlan_bc_filter[64];
+    u64 vlan_mc_filter[64];
+    u64 vlan_un_filter[64];
+    u64 port_mac_hash_array[64];
+};
+
+#define H_PORT_CB4_ALL          0xF000000000000000
+#define H_PORT_CB4_JUMBO        0x1000000000000000
+
+struct hcp_query_ehea_port_cb_4 {
+    u32 port_speed;
+    u32 pause_frame;
+    u32 ens_port_op_state;
+    u32 jumbo_frame;
+    u32 ens_port_wrap;
+};
+
+struct hcp_query_ehea_port_cb_5 {
+    u64 prc;            /* 00 */
+    u64 uaa;        /* 01 */
+    u64 macvc;        /* 02 */
+    u64 xpcsc;        /* 03 */
+    u64 xpcsp;        /* 04 */
+    u64 pcsid;        /* 05 */
+    u64 xpcsst;        /* 06 */
+    u64 pthlb;        /* 07 */
+    u64 pthrb;        /* 08 */
+    u64 pqu;        /* 09 */
+    u64 pqd;        /* 10 */
+    u64 prt;        /* 11 */
+    u64 wsth;        /* 12 */
+    u64 rcb;        /* 13 */
+    u64 rcm;        /* 14 */
+    u64 rcu;        /* 15 */
+    u64 macc;        /* 16 */
+    u64 pc;            /* 17 */
+    u64 pst;        /* 18 */
+    u64 ducqpn;        /* 19 */
+    u64 mcqpn;        /* 20 */
+    u64 mma;        /* 21 */
+    u64 pmc0h;        /* 22 */
+    u64 pmc0l;        /* 23 */
+    u64 lbc;        /* 24 */
+};
+
+#define H_PORT_CB6_ALL  0xFFFFFE7FFFFF8000
+
+struct hcp_query_ehea_port_cb_6 {
+    u64 rxo;        /* 00 */
+    u64 rx64;        /* 01 */
+    u64 rx65;        /* 02 */
+    u64 rx128;        /* 03 */
+    u64 rx256;        /* 04 */
+    u64 rx512;        /* 05 */
+    u64 rx1024;        /* 06 */
+    u64 rxbfcs;        /* 07 */
+    u64 rxime;        /* 08 */
+    u64 rxrle;        /* 09 */
+    u64 rxorle;        /* 10 */
+    u64 rxftl;        /* 11 */
+    u64 rxjab;        /* 12 */
+    u64 rxse;        /* 13 */
+    u64 rxce;        /* 14 */
+    u64 rxrf;        /* 15 */
+    u64 rxfrag;        /* 16 */
+    u64 rxuoc;        /* 17 */
+    u64 rxcpf;        /* 18 */
+    u64 rxsb;        /* 19 */
+    u64 rxfd;        /* 20 */
+    u64 rxoerr;        /* 21 */
+    u64 rxaln;        /* 22 */
+    u64 ducqpn;        /* 23 */
+    u64 reserved0;        /* 24 */
+    u64 rxmcp;        /* 25 */
+    u64 rxbcp;        /* 26 */
+    u64 txmcp;        /* 27 */
+    u64 txbcp;        /* 28 */
+    u64 txo;        /* 29 */
+    u64 tx64;        /* 30 */
+    u64 tx65;        /* 31 */
+    u64 tx128;        /* 32 */
+    u64 tx256;        /* 33 */
+    u64 tx512;        /* 34 */
+    u64 tx1024;        /* 35 */
+    u64 txbfcs;        /* 36 */
+    u64 txcpf;        /* 37 */
+    u64 txlf;        /* 38 */
+    u64 txrf;        /* 39 */
+    u64 txime;        /* 40 */
+    u64 txsc;        /* 41 */
+    u64 txmc;        /* 42 */
+    u64 txsqe;        /* 43 */
+    u64 txdef;        /* 44 */
+    u64 txlcol;        /* 45 */
+    u64 txexcol;        /* 46 */
+    u64 txcse;        /* 47 */
+    u64 txbor;        /* 48 */
+};
+
+struct hcp_query_ehea_port_cb_7 {
+    u64 def_uc_qpn;
+};
+
+u64 hipz_h_query_ehea_qp(const u64 hcp_adapter_handle,
+             const u8 qp_category,
+             const u64 qp_handle, const u64 sel_mask,
+             void *cb_addr);
+
+u64 hipz_h_modify_ehea_qp(const u64 hcp_adapter_handle,
+              const u8 cat,
+              const u64 qp_handle,
+              const u64 sel_mask,
+              void *cb_addr,
+              u64 * inv_attr_id,
+              u64 * proc_mask, u16 * out_swr, u16 * out_rwr);
+
+u64 hipz_h_alloc_resource_eq(const u64 hcp_adapter_handle,
+                 struct ehea_eq *ehea_eq,
+                 struct ehea_eq_attr *eq_attr, u64 * eq_handle);
+
+u64 hipz_h_alloc_resource_cq(const u64 hcp_adapter_handle,
+                 struct ehea_cq *ehea_cq,
+                 struct ehea_cq_attr *cq_attr,
+                 u64 * cq_handle, struct h_galpas *galpas);
+
+u64 hipz_h_alloc_resource_qp(const u64 adapter_handle,
+                 struct ehea_qp *ehea_qp,
+                 struct ehea_qp_init_attr *init_attr,
+                 const u32 pd,
+                 u64 * qp_handle, struct h_galpas *h_galpas);
+
+#define H_REG_RPAGE_PAGE_SIZE          EHEA_BMASK_IBM(48,55)
+#define H_REG_RPAGE_QT                 EHEA_BMASK_IBM(62,63)
+
+u64 hipz_h_register_rpage(const u64 hcp_adapter_handle,
+              const u8 pagesize,
+              const u8 queue_type,
+              const u64 resource_handle,
+              const u64 log_pageaddr, u64 count);
+
+u64 hipz_h_register_rpage_eq(const u64 hcp_adapter_handle,
+                 const u64 eq_handle,
+                 const u8 pagesize,
+                 const u8 queue_type,
+                 const u64 log_pageaddr, const u64 count);
+
+u64 hipz_h_register_rpage_cq(const u64 hcp_adapter_handle,
+                 const u64 cq_handle,
+                 const u8 pagesize,
+                 const u8 queue_type,
+                 const u64 log_pageaddr,
+                 const u64 count, const struct h_galpa gal);
+
+u64 hipz_h_register_rpage_qp(const u64 hcp_adapter_handle,
+                 const u64 qp_handle,
+                 const u8 pagesize,
+                 const u8 queue_type,
+                 const u64 log_pageaddr,
+                 const u64 count, struct h_galpa galpa);
+
+#define H_DISABLE_GET_EHEA_WQE_P  1
+#define H_DISABLE_GET_SQ_WQE_P    2
+#define H_DISABLE_GET_RQC         3
+
+u64 hipz_h_destroy_qp(const u64 hcp_adapter_handle,
+              struct ehea_qp *qp,
+              u64 qp_handle, struct h_galpas *galpas);
+
+u64 hipz_h_destroy_cq(const u64 hcp_adapter_handle,
+              struct ehea_cq *cq,
+              u64 cq_handle, struct h_galpas *galpas);
+
+u64 hipz_h_destroy_eq(const u64 hcp_adapter_handle,
+              struct ehea_eq *eq,
+              u64 eq_handle, struct h_galpas *galpas);
+
+u64 hipz_h_free_resource_mr(const u64 hcp_adapter_handle,
+                const u64 mr_handle);
+
+
+u64 hipz_h_alloc_resource_mr(const u64 hcp_adapter_handle,
+                 const u64 vaddr,
+                 const u64 length,
+                 const u32 access_ctrl,
+                 const u32 pd, u64 * mr_handle, u32 * lkey);
+
+u64 hipz_h_register_rpage_mr(const u64 hcp_adapter_handle,
+                 const u64 mr_handle,
+                 const u8 pagesize,
+                 const u8 queue_type,
+                 const u64 log_pageaddr, const u64 count);
+
+u64 hipz_h_query_ehea(const u64 hcp_adapter_handle, void *cb_addr);
+
+/* output param R5 */
+#define H_MEHEAPORT_CAT            EHEA_BMASK_IBM(40,47)
+#define H_MEHEAPORT_PN             EHEA_BMASK_IBM(48,63)
+
+u64 hipz_h_query_ehea_port(const u64 hcp_adapter_handle,
+               const u16 port_num,
+               const u8 cb_cat,
+               const u64 select_mask, void *cb_addr);
+
+u64 hipz_h_modify_ehea_port(const u64 hcp_adapter_handle,
+                const u16 port_num,
+                const u8 cb_cat,
+                const u64 select_mask, void *cb_addr);
+
+#define H_REGBCMC_PN             EHEA_BMASK_IBM(48, 63)
+#define H_REGBCMC_REGTYPE        EHEA_BMASK_IBM(61, 63)
+#define H_REGBCMC_MACADDR        EHEA_BMASK_IBM(16, 63)
+#define H_REGBCMC_VLANID         EHEA_BMASK_IBM(52, 63)
+
+u64 hipz_h_reg_dereg_bcmc(const u64 hcp_adapter_handle,
+              const u16 port_num,
+              const u8 reg_type,
+              const u64 mc_mac_addr,
+              const u16 vlan_id, const u32 hcall_id);
+
+u64 hipz_h_reset_events(const u64 hcp_adapter_handle,
+            const u64 neq_handle, const u64 event_mask);
+
+#endif                /* __EHEA_PHYP_H__ */




^ permalink raw reply

* [PATCH 3/4] ehea: queue managment
From: Jan-Bernd Themann @ 2006-06-07 17:05 UTC (permalink / raw)
  To: netdev; +Cc: meder, raisch, themann, tklein

Signed-off-by:  Jan-Bernd Themann <themann@de.ibm.com>


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.000000000 -0800
+++ kernel/drivers/net/ehea/ehea_qmr.c    2006-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 <raisch@de.ibm.com>
+ *       Jan-Bernd Themann <themann@de.ibm.com>
+ *       Heiko-Joerg Schick <schickhj@de.ibm.com>
+ *       Thomas Klein <tklein@de.ibm.com>
+ *
+ *
+ * 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 (-ENOMEM)", cq);
+        goto create_cq_exit0;
+    }
+
+    cq->attr.max_nr_of_cqes = nr_of_cqe;
+    cq->attr.cq_token = cq_token;
+    cq->attr.eq_handle = eq_handle;
+
+    cq->adapter = adapter;
+
+    cq_handle_ref = &cq->ipz_cq_handle;
+    act_nr_of_entries = 0;
+    act_pages = 0;
+
+    hret = hipz_h_alloc_resource_cq(adapter->handle,
+                    cq,
+                    &cq->attr,
+                    &cq->ipz_cq_handle, &cq->galpas);
+    if (hret != H_SUCCESS) {
+        EDEB_ERR(4, "hipz_h_alloc_resource_cq failed. hret=%lx", hret);
+        goto create_cq_exit1;
+    }
+
+    ipz_rc = ipz_queue_ctor(&cq->ipz_queue, cq->attr.nr_pages,
+                EHEA_PAGESIZE, sizeof(struct ehea_cqe), 0);
+    if (!ipz_rc)
+        goto create_cq_exit2;
+
+    hret = H_SUCCESS;
+
+    for (counter = 0; counter < cq->attr.nr_pages; counter++) {
+        vpage = ipz_qpageit_get_inc(&cq->ipz_queue);
+        if (!vpage) {
+            EDEB_ERR(4, "ipz_qpageit_get_inc() "
+                 "returns NULL adapter=%p", adapter);
+            goto create_cq_exit3;
+        }
+
+        rpage = virt_to_abs(vpage);
+
+        hret = hipz_h_register_rpage_cq(adapter->handle,
+                        cq->ipz_cq_handle,
+                        0,
+                        HIPZ_CQ_REGISTER_ORIG,
+                        rpage, 1, cq->galpas.kernel);
+
+        if (hret < H_SUCCESS) {
+            EDEB_ERR(4, "hipz_h_register_rpage_cq() failed "
+                 "ehea_cq=%p hret=%lx "
+                 "counter=%i act_pages=%i",
+                 cq, hret, counter, cq->attr.nr_pages);
+            goto create_cq_exit3;
+        }
+
+        if (counter == (cq->attr.nr_pages - 1)) {
+            vpage = ipz_qpageit_get_inc(&cq->ipz_queue);
+
+            if ((hret != H_SUCCESS) || (vpage)) {
+                EDEB_ERR(4, "Registration of pages not "
+                     "complete ehea_cq=%p hret=%lx",
+                     cq, hret)
+                goto create_cq_exit3;
+            }
+        } else {
+            if ((hret != H_PAGE_REGISTERED) || (vpage == 0)) {
+                EDEB_ERR(4, "Registration of page failed "
+                     "ehea_cq=%p hret=%lx"
+                     "counter=%i act_pages=%i",
+                     cq, hret, counter, cq->attr.nr_pages);
+                goto create_cq_exit3;
+            }
+        }
+    }
+
+    ipz_qeit_reset(&cq->ipz_queue);
+    gal = cq->galpas.kernel;
+    hipz_reset_cq_ep(cq);
+    hipz_reset_cq_n1(cq);
+
+    EDEB_EX(7, "ret=%p ", cq);
+    return cq;
+
+create_cq_exit3:
+    ipz_queue_dtor(&cq->ipz_queue);
+
+create_cq_exit2:
+    hret = hipz_h_destroy_cq(adapter->handle, cq, cq->ipz_cq_handle,
+                 &cq->galpas);
+    EDEB(7, "return code of hipz_cq_destroy=%lx", hret);
+
+create_cq_exit1:
+    ehea_cq_delete(cq);
+
+create_cq_exit0:
+    EDEB_EX(7, "ret=NULL");
+    return NULL;
+}
+
+int ehea_destroy_cq(struct ehea_cq *cq)
+{
+    int ret = 0;
+    u64 adapter_handle;
+    u64 hret;
+
+    adapter_handle = cq->adapter->handle;
+    EDEB_EN(7, "adapter=%p cq=%p", cq->adapter, cq);
+
+    /* deregister all previous registered pages */
+    hret = hipz_h_destroy_cq(adapter_handle, cq, cq->ipz_cq_handle,
+                 &cq->galpas);
+    if (hret != H_SUCCESS) {
+        EDEB_ERR(4, "destroy CQ failed!");
+        return -EINVAL;
+    }
+    ipz_queue_dtor(&cq->ipz_queue);
+    ehea_cq_delete(cq);
+
+    EDEB_EX(7, "ret=%x ", ret);
+    return ret;
+}
+
+struct ehea_eq *ehea_eq_new(void)
+{
+    struct ehea_eq *eq = vmalloc(sizeof(*eq));
+    if (eq)
+        memset(eq, 0, sizeof(*eq));
+    return eq;
+}
+
+void ehea_eq_delete(struct ehea_eq *eq)
+{
+    vfree(eq);
+}
+
+struct ehea_eq *ehea_create_eq(struct ehea_adapter *adapter,
+                   const enum ehea_eq_type type,
+                   const u32 max_nr_of_eqes, const u8 eqe_gen)
+{
+    u64 hret = H_HARDWARE;
+    int ret = 0;
+    u32 i;
+    void *vpage = NULL;
+    struct ehea_eq *eq;
+
+    EDEB_EN(7, "adapter=%p, max_nr_of_eqes=%x", adapter, max_nr_of_eqes);
+
+    eq = ehea_eq_new();
+    if (!eq)
+        return NULL;
+
+    eq->attr.type = type;
+    eq->attr.max_nr_of_eqes = max_nr_of_eqes;
+    eq->attr.eqe_gen = eqe_gen;
+    spin_lock_init(&eq->spinlock);
+
+    hret = hipz_h_alloc_resource_eq(adapter->handle,
+                    eq, &eq->attr, &eq->ipz_eq_handle);
+
+    if (hret != H_SUCCESS) {
+        EDEB_ERR(4, "hipz_h_alloc_resource_eq failed. hret=%lx", hret);
+        goto free_eq_mem;
+    }
+
+    ret = ipz_queue_ctor(&eq->ipz_queue, eq->attr.nr_pages,
+                  EHEA_PAGESIZE, sizeof(struct ehea_eqe), 0);
+    if (!ret) {
+        EDEB_ERR(4, "can't allocate EQ pages");
+        goto alloc_pages_failed;
+    }
+
+    for (i = 0; i < eq->attr.nr_pages; i++) {
+        u64 rpage;
+
+        if (!(vpage = ipz_qpageit_get_inc(&eq->ipz_queue))) {
+            hret = H_RESOURCE;
+            goto register_page_failed;
+        }
+
+        rpage = virt_to_abs(vpage);
+
+        hret = hipz_h_register_rpage_eq(adapter->handle,
+                        eq->ipz_eq_handle,
+                        0,
+                        HIPZ_EQ_REGISTER_ORIG,
+                        rpage, 1);
+
+        if (i == (eq->attr.nr_pages - 1)) {
+            /* last page */
+            vpage = ipz_qpageit_get_inc(&eq->ipz_queue);
+            if ((hret != H_SUCCESS) || (vpage)) {
+                goto register_page_failed;
+            }
+        } else {
+            if ((hret != H_PAGE_REGISTERED) || (!vpage)) {
+                goto register_page_failed;
+            }
+        }
+    }
+
+    ipz_qeit_reset(&eq->ipz_queue);
+
+    EDEB_EX(7, "hret=%lx", hret);
+    return eq;
+
+register_page_failed:
+    ipz_queue_dtor(&eq->ipz_queue);
+
+alloc_pages_failed:
+    hipz_h_destroy_eq(adapter->handle, eq, eq->ipz_eq_handle, &eq->galpas);
+free_eq_mem:
+    ehea_eq_delete(eq);
+
+    EDEB_EX(7, "return with error hret=%lx", hret);
+    return NULL;
+}
+
+void *ehea_poll_eq(struct ehea_adapter *adapter, struct ehea_eq *eq)
+{
+    void *eqe = NULL;
+    unsigned long flags = 0;
+
+    EDEB_EN(7, "adapter=%p  eq=%p", adapter, eq);
+
+    spin_lock_irqsave(&eq->spinlock, flags);
+    eqe = ipz_eqit_eq_get_inc_valid(&eq->ipz_queue);
+    spin_unlock_irqrestore(&eq->spinlock, flags);
+
+    EDEB_EX(7, "eqe=%p", eqe);
+
+    return eqe;
+}
+
+int ehea_destroy_eq(struct ehea_adapter *adapter, struct ehea_eq *eq)
+{
+    unsigned long flags = 0;
+    u64 hret = H_HARDWARE;
+
+    EDEB_EN(7, "adapter=%p  eq=%p", adapter, eq);
+
+    spin_lock_irqsave(&eq->spinlock, flags);
+
+    hret = hipz_h_destroy_eq(adapter->handle, eq, eq->ipz_eq_handle,
+                 &eq->galpas);
+    spin_unlock_irqrestore(&eq->spinlock, flags);
+
+    if (hret != H_SUCCESS) {
+        EDEB_ERR(4, "Failed freeing EQ resources. hret=%lx", hret);
+        return -EINVAL;
+    }
+    ipz_queue_dtor(&eq->ipz_queue);
+    ehea_eq_delete(eq);
+    EDEB_EX(7, "");
+
+    return 0;
+}
+
+struct ehea_qp *ehea_qp_new(void) {
+    struct ehea_qp *qp = vmalloc(sizeof(*qp));
+    if (qp != 0) {
+        memset(qp, 0, sizeof(*qp));
+    }
+    return qp;
+}
+
+void ehea_qp_delete(struct ehea_qp *qp)
+{
+    vfree(qp);
+}
+
+/**
+ * allocates memory for a queue and registers pages in phyp
+ */
+int ehea_qp_alloc_register(struct ehea_qp *qp,
+               struct ipz_queue *ipz_queue,
+               int nr_pages,
+               int wqe_size,
+               int act_nr_sges,
+               struct ehea_adapter *adapter, int h_call_q_selector)
+{
+    u64 hret = H_HARDWARE;
+    u64 rpage = 0;
+    int iret = 0;
+    int cnt = 0;
+    void *vpage = NULL;
+
+    iret = ipz_queue_ctor(ipz_queue,
+                  nr_pages, EHEA_PAGESIZE, wqe_size, act_nr_sges);
+    if (!iret) {
+        EDEB_ERR(4, "Cannot allocate page for queue. iret=%x", iret);
+        return -ENOMEM;
+    }
+
+    EDEB(7, "queue_size=%x, alloc_len=%x, toggle_state=%d",
+         ipz_queue->qe_size,
+         ipz_queue->queue_length, ipz_queue->toggle_state);
+
+    for (cnt = 0; cnt < nr_pages; cnt++) {
+        vpage = ipz_qpageit_get_inc(ipz_queue);
+        if (!vpage) {
+            EDEB_ERR(4, "SQ ipz_qpageit_get_inc() "
+                 "failed p_vpage= %p", vpage);
+            goto qp_alloc_register_exit0;
+        }
+        rpage = virt_to_abs(vpage);
+
+        hret = hipz_h_register_rpage_qp(adapter->handle,
+                        qp->ipz_qp_handle,
+                        0,
+                        h_call_q_selector,
+                        rpage,
+                        1, qp->galpas.kernel);
+
+        if (hret < H_SUCCESS) {
+            EDEB_ERR(4, "hipz_h_register_rpage_qp failed. hret=%lx",
+                 hret);
+            goto qp_alloc_register_exit0;
+        }
+    }
+    ipz_qeit_reset(ipz_queue);
+
+    return 0;
+
+qp_alloc_register_exit0:
+    ipz_queue_dtor(ipz_queue);
+    return -EINVAL;
+}
+
+u32 map_swqe_size(u8 swqe_enc_size)
+{
+    return 128 << swqe_enc_size;
+}
+
+u32 map_rwqe_size(u8 rwqe_enc_size)
+{
+    return 128 << rwqe_enc_size;
+}
+
+struct ehea_qp *ehea_create_qp(struct ehea_adapter *adapter,
+                   u32 pd, struct ehea_qp_init_attr *init_attr)
+{
+    struct ehea_qp *qp;
+    u64 hret = H_HARDWARE;
+
+    u32 wqe_size_in_bytes_sq = 0;
+    u32 wqe_size_in_bytes_rq1 = 0;
+    u32 wqe_size_in_bytes_rq2 = 0;
+    u32 wqe_size_in_bytes_rq3 = 0;
+
+    int ret = -1;
+
+    EDEB_EN(7, "init_attr=%p", init_attr);
+
+    qp = ehea_qp_new();
+
+    if (!qp) {
+        EDEB_ERR(4, "pd=%X not enough memory to alloc qp", pd);
+        return NULL;
+    }
+    qp->adapter = adapter;
+
+    EDEB(7, "send_ehea_cq->ipz_cq_handle=0x%lX"
+         "recv_ehea_cq->ipz_cq_handle=0x%lX", init_attr->send_cq_handle,
+         init_attr->recv_cq_handle);
+
+
+    hret = hipz_h_alloc_resource_qp(adapter->handle, qp,
+                    init_attr,
+                    pd,
+                    &qp->ipz_qp_handle,
+                    &qp->galpas);
+
+    if (hret != H_SUCCESS) {
+        EDEB_ERR(4, "hipz_h_alloc_resource_qp failed. hret=%lx", hret);
+        goto create_qp_exit1;
+    }
+
+    wqe_size_in_bytes_sq = map_swqe_size(init_attr->act_wqe_size_enc_sq);
+    EDEB(7, "SWQE SG %d", init_attr->wqe_size_enc_sq);
+
+    wqe_size_in_bytes_rq1 = map_rwqe_size(init_attr->act_wqe_size_enc_rq1);
+    wqe_size_in_bytes_rq2 = map_rwqe_size(init_attr->act_wqe_size_enc_rq2);
+    wqe_size_in_bytes_rq3 = map_rwqe_size(init_attr->act_wqe_size_enc_rq3);
+
+    EDEB(7, "SQ pages: %d, SQ WQE size:%d, max SWQE size enc: %d",
+         init_attr->nr_sq_pages,
+         wqe_size_in_bytes_sq, init_attr->act_wqe_size_enc_sq);
+
+    EDEB(7, "RQ1 pages: %d, RQ1 WQE size:%d, max RWQE size enc: %d",
+         init_attr->nr_rq1_pages,
+         wqe_size_in_bytes_rq1, init_attr->act_wqe_size_enc_rq1);
+
+    EDEB(7, "RQ2 pages: %d, RQ2 WQE size:%d, max RWQE size enc: %d",
+         init_attr->nr_rq2_pages,
+         wqe_size_in_bytes_rq2, init_attr->act_wqe_size_enc_rq2);
+
+    EDEB(7, "RQ3 pages: %d, RQ3 WQE size:%d, max RWQE size enc: %d",
+         init_attr->nr_rq3_pages,
+         wqe_size_in_bytes_rq3, init_attr->act_wqe_size_enc_rq3);
+
+    ret = ehea_qp_alloc_register(qp,
+                     &qp->ipz_squeue,
+                     init_attr->nr_sq_pages,
+                     wqe_size_in_bytes_sq,
+                     init_attr->act_wqe_size_enc_sq, adapter,
+                     0);
+    if (ret < H_SUCCESS) {
+        EDEB_ERR(4, "can't register for sq hret=%x", ret);
+        goto create_qp_exit2;
+    }
+
+    ret = ehea_qp_alloc_register(qp,
+                     &qp->ipz_rqueue1,
+                     init_attr->nr_rq1_pages,
+                     wqe_size_in_bytes_rq1,
+                     init_attr->act_wqe_size_enc_rq1,
+                     adapter, 1);
+
+    if (ret < 0) {
+        EDEB_ERR(4, "can't register for rq1 hret=%x", ret);
+        goto create_qp_exit3;
+    }
+
+    if (init_attr->rq_count > 1) {
+        ret = ehea_qp_alloc_register(qp,
+                         &qp->ipz_rqueue2,
+                         init_attr->nr_rq2_pages,
+                         wqe_size_in_bytes_rq2,
+                         init_attr->act_wqe_size_enc_rq2,
+                         adapter, 2);
+
+        if (ret < 0) {
+            EDEB_ERR(4, "can't register for rq2 hret=%x", ret);
+            goto create_qp_exit4;
+        }
+    }
+
+    if (init_attr->rq_count > 2) {
+        ret = ehea_qp_alloc_register(qp,
+                         &qp->ipz_rqueue3,
+                         init_attr->nr_rq3_pages,
+                         wqe_size_in_bytes_rq3,
+                         init_attr->act_wqe_size_enc_rq3,
+                         adapter, 3);
+
+        if (ret != 0) {
+            EDEB_ERR(4, "can't register for rq3 hret=%x", ret);
+            goto create_qp_exit5;
+        }
+    }
+
+    qp->init_attr = *init_attr;
+
+    EDEB_EX(7, "");
+    return qp;
+
+create_qp_exit5:
+    ipz_queue_dtor(&qp->ipz_rqueue2);
+
+create_qp_exit4:
+    ipz_queue_dtor(&qp->ipz_rqueue1);
+
+create_qp_exit3:
+    ipz_queue_dtor(&qp->ipz_squeue);
+
+create_qp_exit2:
+    hret = hipz_h_destroy_qp(adapter->handle, qp, qp->ipz_qp_handle,
+                 &qp->galpas);
+
+create_qp_exit1:
+    ehea_qp_delete(qp);
+
+    EDEB_EX(7, "hret=NULL");
+    return NULL;
+
+}
+
+int ehea_destroy_qp(struct ehea_qp *qp)
+{
+    int ret = 0;
+    u64 hret;
+    struct ehea_qp_init_attr *qp_attr = &qp->init_attr;
+    EDEB_EX(7, "");
+
+    hret = hipz_h_destroy_qp(qp->adapter->handle, qp, qp->ipz_qp_handle,
+                 &qp->galpas);
+    if (hret != H_SUCCESS) {
+        EDEB_ERR(4, "destroy QP failed!");
+        ret = -EINVAL;
+    }
+
+    ipz_queue_dtor(&qp->ipz_squeue);
+    ipz_queue_dtor(&qp->ipz_rqueue1);
+
+       if(qp_attr->rq_count > 1)
+        ipz_queue_dtor(&qp->ipz_rqueue2);
+       if(qp_attr->rq_count > 2)
+        ipz_queue_dtor(&qp->ipz_rqueue3);
+    ehea_qp_delete(qp);
+
+    EDEB_EX(7, "hret=%lx", hret);
+
+    return ret;
+}
+
+#define EHEA_MEM_START 0xc000000000000000
+#define EHEA_MEM_ACC_CTRL 0x00800000
+
+int register_mr_adapter(struct ehea_adapter *adapter)
+{
+    int i;
+    u64 hret;
+    u64 start = EHEA_MEM_START;
+    u64 end = (u64) high_memory;
+    u64 nr_pages = (end - start) / PAGE_SIZE;
+    u32 acc_ctrl = EHEA_MEM_ACC_CTRL;
+
+    EDEB_EN(7, "adapter=%p", adapter);
+
+    hret = hipz_h_alloc_resource_mr(adapter->handle,
+                    start,
+                    end - start,
+                    acc_ctrl,
+                    adapter->pd,
+                    &adapter->mr_handle,
+                    &adapter->lkey);
+    if (hret != H_SUCCESS) {
+        EDEB_EX(4, "Error: hret=%lX\n", hret);
+        return -EINVAL;
+    }
+
+    for (i = 0; i < nr_pages; i++) {
+        hret = hipz_h_register_rpage_mr(adapter->handle,
+                        adapter->mr_handle,
+                        0,
+                        0,
+                        virt_to_abs(
+                            (void *)(((u64) start)
+                            + (i * PAGE_SIZE))),
+                        1);
+
+        if (((hret != H_SUCCESS) && (hret != H_PAGE_REGISTERED))) {
+            hipz_h_free_resource_mr(adapter->handle, adapter->mr_handle);
+            EDEB_EX(4, " register rpage_mr: hret=%lX\n", hret);
+            return -EINVAL;
+        }
+    }
+
+    if (hret != H_SUCCESS) {
+        hipz_h_free_resource_mr(adapter->handle, adapter->mr_handle);
+        EDEB_EX(4, " register rpage_mr failed for last page:"
+            "hret=%lX\n", hret);
+        return -EINVAL;
+    }
+
+    EDEB_EX(7, "");
+    return 0;
+}
+
+int deregister_mr_adapter(struct ehea_adapter *adapter)
+{
+    u64 hret;
+    EDEB_EN(7, "adapter=%p", adapter);
+    hret = hipz_h_free_resource_mr(adapter->handle, adapter->mr_handle);
+    if (hret != H_SUCCESS) {
+        EDEB_EX(4, "deregistering memory region failed");
+        return -EINVAL;
+    }
+    EDEB_EX(7, "");
+    return 0;
+}
--- linux-2.6.16-rc5-orig/drivers/net/ehea/ehea_qmr.h    1969-12-31 16:00:00.000000000 -0800
+++ kernel/drivers/net/ehea/ehea_qmr.h    2006-06-07 07:01:14.667173688 -0700
@@ -0,0 +1,390 @@
+/*
+ *  linux/drivers/net/ehea/ehea_qmr.h
+ *
+ *  eHEA ethernet device driver for IBM eServer System p
+ *
+ *  (C) Copyright IBM Corp. 2006
+ *
+ *  Authors:
+ *       Christoph Raisch <raisch@de.ibm.com>
+ *       Jan-Bernd Themann <themann@de.ibm.com>
+ *       Heiko-Joerg Schick <schickhj@de.ibm.com>
+ *       Thomas Klein <tklein@de.ibm.com>
+ *
+ *
+ * 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.
+ */
+
+#ifndef __EHEA_QMR_H__
+#define __EHEA_QMR_H__
+
+#include "ehea.h"
+#include "ehea_hw.h"
+
+/* Use of WR_ID field for EHEA */
+#define EHEA_WR_ID_COUNT   EHEA_BMASK_IBM(0, 19)
+#define EHEA_WR_ID_TYPE    EHEA_BMASK_IBM(20, 23)
+#define EHEA_SWQE2_TYPE    0x1
+#define EHEA_SWQE3_TYPE    0x2
+#define EHEA_RWQE2_TYPE    0x3    /* RQ2  */
+#define EHEA_RWQE3_TYPE    0x4    /* RQ3  */
+#define EHEA_WR_ID_INDEX   EHEA_BMASK_IBM(24, 47)
+#define EHEA_WR_ID_REFILL  EHEA_BMASK_IBM(48, 63)
+
+struct ehea_vsgentry {
+    u64 vaddr;
+    u32 l_key;
+    u32 len;
+};
+
+/* maximum number of sg entries allowed in a WQE */
+#define EHEA_MAX_WQE_SG_ENTRIES  252
+#define SWQE2_RES_IMM            14
+#define SWQE2_MAX_IMM            (160-SWQE2_RES_IMM)
+#define SWQE3_MAX_IMM            224
+
+/* tx control flags for swqe */
+#define EHEA_SWQE_CRC                    0x8000
+#define EHEA_SWQE_IP_CHECKSUM            0x4000
+#define EHEA_SWQE_TCP_CHECKSUM           0x2000
+#define EHEA_SWQE_TSO                    0x1000
+#define EHEA_SWQE_SIGNALLED_COMPLETION   0x0800
+#define EHEA_SWQE_VLAN_INSERT            0x0400
+#define EHEA_SWQE_IMM_DATA_PRESENT      0x0200
+#define EHEA_SWQE_DESCRIPTORS_PRESENT    0x0100
+#define EHEA_SWQE_WRAP_CTL_REC           0x0080
+#define EHEA_SWQE_WRAP_CTL_FORCE         0x0040
+#define EHEA_SWQE_BIND                   0x0020
+#define EHEA_SWQE_PURGE                  0x0010
+
+#define SWQE_HEADER_SIZE 32
+
+struct ehea_swqe {
+    u64 wr_id;
+    u16 tx_control;
+    u16 vlan_tag;
+    u8 reserved1;
+    u8 ip_start;
+    u8 ip_end;
+    u8 immediate_data_length;
+    u8 tcp_offset;
+    u8 reserved2;
+    u16 tcp_end;
+    u8 wrap_tag;
+    u8 descriptors;        /* number of valid descriptors in WQE */
+    u16 reserved3;
+    u16 reserved4;
+    u16 mss;
+    u32 reserved5;
+    union {
+        /*  Send WQE Format 1 */
+        struct {
+            struct ehea_vsgentry sg_list[EHEA_MAX_WQE_SG_ENTRIES];
+        } no_immediate_data;
+
+        /*  Send WQE Format 2 */
+        struct {
+            struct ehea_vsgentry sg_entry;
+            /* 0x30 */
+            u8 immediate_data[0xd0 - 0x30];
+            /* 0xd0 */
+            struct ehea_vsgentry sg_list[EHEA_MAX_WQE_SG_ENTRIES -
+                             1];
+        } immdata_desc __attribute__ ((packed));
+
+        /*  Send WQE Format 3 */
+        struct {
+            u8 immediate_data[1];
+        } immdata_nodesc;
+    } u;
+};
+
+struct ehea_rwqe {
+    u64 wr_id;        /* work request ID */
+    u8 reserved1[5];
+    u8 data_segments;
+    u16 reserved2;
+    u64 reserved3;
+    u64 reserved4;
+    struct ehea_vsgentry sg_list[EHEA_MAX_WQE_SG_ENTRIES];
+};
+
+#define EHEA_CQE_VLAN_TAG_XTRACT  0x0400
+
+#define EHEA_CQE_TYPE_RQ          0x60
+#define EHEA_CQE_STAT_ERR_MASK    0x7300
+#define EHEA_CQE_STAT_ERR_TCP     0x4000
+
+struct ehea_cqe {
+    u64 wr_id;        /* work request ID from WQE */
+    u8 type;
+    u8 valid;
+    u16 status;
+    u16 reserved1;
+    u16 num_bytes_transfered;
+    u16 vlan_tag;
+    u16 inet_checksum_value;
+    u8 reserved2;
+    u8 header_length;
+    u16 reserved3;
+    u16 page_offset;
+    u16 wqe_count;
+    u32 qp_token;
+    u32 timestamp;
+    u32 reserved4;
+    u64 reserved5[3];
+};
+
+#define EHEA_EQE_VALID           EHEA_BMASK_IBM(0, 0)
+#define EHEA_EQE_IS_CQE          EHEA_BMASK_IBM(1, 1)
+#define EHEA_EQE_IDENTIFIER      EHEA_BMASK_IBM(2, 7)
+#define EHEA_EQE_QP_CQ_NUMBER    EHEA_BMASK_IBM(8, 31)
+#define EHEA_EQE_QP_TOKEN        EHEA_BMASK_IBM(32, 63)
+#define EHEA_EQE_CQ_TOKEN        EHEA_BMASK_IBM(32, 63)
+#define EHEA_EQE_KEY             EHEA_BMASK_IBM(32, 63)
+#define EHEA_EQE_PORT_NUMBER     EHEA_BMASK_IBM(56, 63)
+#define EHEA_EQE_EQ_NUMBER       EHEA_BMASK_IBM(48, 63)
+#define EHEA_EQE_SM_ID           EHEA_BMASK_IBM(48, 63)
+#define EHEA_EQE_SM_MECH_NUMBER  EHEA_BMASK_IBM(48, 55)
+#define EHEA_EQE_SM_PORT_NUMBER  EHEA_BMASK_IBM(56, 63)
+
+struct ehea_eqe {
+    u64 entry;
+};
+
+struct ehea_mrte {
+    u64 starting_va;
+    u64 length;        /*  length of memory region in bytes */
+    u32 pd;
+    u8 key_instance;
+    u8 pagesize;
+    u8 mr_control;
+    u8 local_remote_access_controll;
+    u8 reserved[0x20 - 0x18];
+    u64 at_pointer[4];
+};
+
+static inline void *ipz_qeit_calc(struct ipz_queue *queue, u64 q_offset)
+{
+    struct ipz_page *current_page = NULL;
+    if (q_offset >= queue->queue_length)
+        q_offset -= queue->queue_length;
+    current_page = (queue->queue_pages)[q_offset >> EHEA_PAGESHIFT];
+    return &current_page->entries[q_offset & (EHEA_PAGESIZE - 1)];
+}
+
+static inline void *ipz_qeit_get(struct ipz_queue *queue)
+{
+    return ipz_qeit_calc(queue, queue->current_q_offset);
+}
+
+static inline void ipz_qeit_inc(struct ipz_queue *queue)
+{
+    queue->current_q_offset += queue->qe_size;
+    if (queue->current_q_offset >= queue->queue_length) {
+        queue->current_q_offset = 0;
+        /* toggle the valid flag */
+        queue->toggle_state = (~queue->toggle_state) & 1;
+    }
+}
+
+static inline void *ipz_qeit_get_inc(struct ipz_queue *queue)
+{
+    void *retvalue = ipz_qeit_get(queue);
+    ipz_qeit_inc(queue);
+    EDEB(8, "queue=%p retvalue=%p new current_q_addr=%lx qe_size=%x",
+         queue, retvalue, queue->current_q_offset, queue->qe_size);
+
+    return retvalue;
+}
+
+static inline void *ipz_qeit_get_inc_valid(struct ipz_queue *queue)
+{
+    struct ehea_cqe *retvalue = ipz_qeit_get(queue);
+    void *pref;
+    u8 valid = retvalue->valid;
+    if ((valid >> 7) == (queue->toggle_state & 1)) {
+        /* this is a good one */
+        iosync();
+        ipz_qeit_inc(queue);
+        pref = ipz_qeit_calc(queue, queue->current_q_offset);
+        prefetch(pref);
+        prefetch(pref + 128);
+    } else
+        retvalue = NULL;
+    return retvalue;
+}
+
+static inline void *ipz_qeit_get_valid(struct ipz_queue *queue)
+{
+    struct ehea_cqe *retvalue = ipz_qeit_get(queue);
+    void *pref;
+    pref = ipz_qeit_calc(queue, queue->current_q_offset);
+    prefetch(pref);
+    prefetch(pref + 128);
+    prefetch(pref + 256);
+    u8 valid = retvalue->valid;
+    if ((valid >> 7) == (queue->toggle_state & 1))
+        iosync();
+    else
+        retvalue = NULL;
+    return retvalue;
+}
+
+static inline void *ipz_qeit_reset(struct ipz_queue *queue)
+{
+    queue->current_q_offset = 0;
+    return ipz_qeit_get(queue);
+}
+
+static inline void *ipz_qeit_eq_get_inc(struct ipz_queue *queue)
+{
+    void *retvalue = NULL;
+    u64 last_entry_in_q = queue->queue_length - queue->qe_size;
+
+    retvalue = ipz_qeit_get(queue);
+    queue->current_q_offset += queue->qe_size;
+    if (queue->current_q_offset > last_entry_in_q) {
+        queue->current_q_offset = 0;
+        queue->toggle_state = (~queue->toggle_state) & 1;
+    }
+
+    EDEB(7, "queue=%p retvalue=%p new current_q_offset=%lx qe_size=%x",
+         queue, retvalue, queue->current_q_offset, queue->qe_size);
+
+    return retvalue;
+}
+
+static inline void *ipz_eqit_eq_get_inc_valid(struct ipz_queue *queue)
+{
+    void *retvalue = ipz_qeit_get(queue);
+    u32 qe = *(u8 *) retvalue;
+    EDEB(7, "ipz_eqit_eq_get_inc_valid qe=%x", qe);
+    if ((qe >> 7) == (queue->toggle_state & 1))
+        ipz_qeit_eq_get_inc(queue);
+    else
+        retvalue = NULL;
+    return retvalue;
+}
+
+static inline struct ehea_rwqe *ehea_get_next_rwqe(struct ehea_qp *qp,
+                           int rq_nr)
+{
+
+    struct ehea_rwqe *wqe_p = NULL;
+    struct ipz_queue *queue = NULL;
+    struct ehea_qp *my_qp = qp;
+    EDEB_EN(8, "QP=%p, RQ_nr=%d", qp, rq_nr);
+
+    if (rq_nr == 1)
+        queue = &my_qp->ipz_rqueue1;
+    else if (rq_nr == 2)
+        queue = &my_qp->ipz_rqueue2;
+    else
+        queue = &my_qp->ipz_rqueue3;
+    wqe_p = (struct ehea_rwqe *)ipz_qeit_get_inc(queue);
+
+    EDEB_EX(8, "&RWQE=%p, queue=%p", wqe_p, queue);
+    return wqe_p;
+}
+
+static inline struct ehea_swqe *ehea_get_swqe(struct ehea_qp *my_qp)
+{
+
+    struct ehea_swqe *wqe_p = NULL;
+    EDEB_EN(7, "QP=%p, queue=%p", my_qp, &my_qp->ipz_squeue);
+    wqe_p = (struct ehea_swqe *)ipz_qeit_get_inc(&my_qp->ipz_squeue);
+    EDEB_EX(7, "");
+    return wqe_p;
+}
+
+static inline void ehea_post_swqe(struct ehea_qp *my_qp, struct ehea_swqe *swqe)
+{
+
+    EDEB_EN(7, "QP=%p, SWQE=%p", my_qp, swqe);
+    EDEB(6, "SWQE workreqid = 0x%lX, imm_data_len=%d, descriptors=%d",
+         (u64) swqe->wr_id, swqe->immediate_data_length, swqe->descriptors);
+    iosync();
+    hipz_update_sqa(my_qp, 1);
+    EDEB_EX(7, "");
+}
+
+static inline struct ehea_cqe *ehea_poll_rq1(struct ehea_qp *qp, int *wqe_index)
+{
+    struct ipz_queue *queue = &qp->ipz_rqueue1;
+    struct ehea_cqe *cqe = NULL;
+
+    EDEB_EN(7, "QP=%p, RQ1 toggle state = %d, current_q_offset=%lx", qp,
+        queue->toggle_state, queue->current_q_offset);
+    *wqe_index = (queue->current_q_offset) >> (7 + EHEA_SG_RQ1);
+    cqe = (struct ehea_cqe *)ipz_qeit_get_valid(queue);
+    EDEB_EX(7, "cqe=%p, new toggle state %d, wqe_index = %d",
+        cqe, queue->toggle_state, *wqe_index);
+    return cqe;
+}
+
+static inline void ehea_inc_rq1(struct ehea_qp *qp)
+{
+    struct ipz_queue *queue = &qp->ipz_rqueue1;
+    ipz_qeit_inc(queue);
+}
+
+static inline struct ehea_cqe *ehea_poll_cq(struct ehea_cq *my_cq)
+{
+
+    struct ehea_cqe *wqe_p = NULL;
+    EDEB_EN(7, "CQ=%p", my_cq);
+
+    EDEB(7, "queue_element_size=%x, alloc_len=%x, queue=%p",
+         my_cq->ipz_queue.qe_size,
+         my_cq->ipz_queue.queue_length, &my_cq->ipz_queue);
+    wqe_p = (struct ehea_cqe *)ipz_qeit_get_inc_valid(&my_cq->ipz_queue);
+
+    EDEB_EX(7, "wqe_p=%p", wqe_p);
+    return wqe_p;
+};
+
+#define HIPZ_CQ_REGISTER_ORIG 0
+#define HIPZ_EQ_REGISTER_ORIG 0
+
+enum ehea_eq_type {
+    EHEA_EQ = 0,        /* event queue              */
+    EHEA_NEQ        /* notification event queue */
+};
+
+struct ehea_eq *ehea_create_eq(struct ehea_adapter *adapter,
+                   enum ehea_eq_type type,
+                   const u32 length, const u8 eqe_gen);
+
+int ehea_destroy_eq(struct ehea_adapter *adapter, struct ehea_eq *eq);
+
+void *ehea_poll_eq(struct ehea_adapter *adapter, struct ehea_eq *eq);
+
+struct ehea_cq *ehea_create_cq(struct ehea_adapter *adapter, int cqe,
+                   u64 eq_handle, u32 cq_token);
+
+int ehea_destroy_cq(struct ehea_cq *cq);
+
+
+struct ehea_qp *ehea_create_qp(struct ehea_adapter * adapter,
+                   u32 pd,
+                   struct ehea_qp_init_attr *init_attr);
+
+int ehea_destroy_qp(struct ehea_qp *qp);
+
+int register_mr_adapter(struct ehea_adapter *adapter);
+int deregister_mr_adapter(struct ehea_adapter *adapter);
+
+#endif                /* __EHEA_QMR_H__ */




^ permalink raw reply

* [PATCH 4/4] ehea: Kconfig and Makefile
From: Jan-Bernd Themann @ 2006-06-07 17:06 UTC (permalink / raw)
  To: netdev; +Cc: meder, raisch, themann, tklein

Signed-off-by:  Jan-Bernd Themann <themann@de.ibm.com>


drivers/net/ehea/Kconfig  |    6 ++++++
drivers/net/ehea/Makefile |   45 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 51 insertions(+)



--- linux-2.6.16-rc5-orig/drivers/net/ehea/Makefile    1969-12-31 16:00:00.000000000 -0800
+++ kernel/drivers/net/ehea/Makefile    2006-06-07 07:01:14.634178704 -0700
@@ -0,0 +1,45 @@
+# Server eHEA ethernet device driver for Linux on POWER
+#
+#
+#  linux/drivers/net/ehea/Makefile
+#
+#  eHEA ethernet device driver for IBM eServer System p
+#
+#  (C) Copyright IBM Corp. 2006
+#
+#  Authors:
+#       Christoph Raisch <raisch@de.ibm.com>
+#       Jan-Bernd Themann <themann@de.ibm.com>
+#       Heiko-Joerg Schick <schickhj@de.ibm.com>
+#       Thomas Klein <tklein@de.ibm.com>
+#
+#
+# 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.
+
+
+
+
+# To compile module type:
+# make -C /root/linux-2.6.5-7.244 SUBDIRS=`pwd` V=1 modules CONFIG_EHEA=m
+# make -C /usr/src/linux-2.6.17-rc5 SUBDIRS=`pwd` V=1 modules CONFIG_EHEA=m
+
+ehea_mod-objs = ehea_main.o ehea_phyp.o ehea_qmr.o ehea_ethtool.o ehea_phyp.o
+
+obj-$(CONFIG_EHEA) += ehea_mod.o
+
+#CFLAGS += -Werror
+
+
+
--- linux-2.6.16-rc5-orig/drivers/net/ehea/Kconfig    1969-12-31 16:00:00.000000000 -0800
+++ kernel/drivers/net/ehea/Kconfig    2006-06-07 07:01:14.637178248 -0700
@@ -0,0 +1,6 @@
+config EHEA
+       tristate "eHEA Ethernet support"
+       depends on IBMEBUS
+       ---help---
+       This driver supports the IBM pSeries
+       Ethernet adapter




^ permalink raw reply

* Re: Problem authenticating using WPA with bcm43xx-softmac
From: Larry Finger @ 2006-06-07 17:07 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Sam Leffler, netdev
In-Reply-To: <1149696400.3925.13.camel@johannes>

Johannes Berg wrote:
> On Wed, 2006-06-07 at 09:01 -0700, Sam Leffler wrote:
> 
>> Beware of the order of IE's in the management frames; some AP's are
>> touchy about this.
> 
> Uh oh. I have no idea where the ieee80211 layer sticks that one,
> probably at the end.

I moved the WPA IE from the end forward without any effect. I have dumped that IE and find the 
following:

SoftMAC: Added WPA_IE of 24 bytes to association request
Contents of WPA_IE: 0xdd 0x16 0x00 0x50 0xf2 0x01 0x01 0x00 0x00 0x50
                     0xf2 0x02 0x01 0x00 0x00 0x50 0xf2 0x02 0x01 0x00
                     0x00 0x50 0xf2 0x02

I think I got the right thing, but I'm having trouble interpreting it. The dump was made by 
modifying the part of ieee80211softmac_assoc_req in ieee80211softmac_io.c where the WPA IE is added:

         /* Add WPA IE */
         if (mac->wpa.IElen && mac->wpa.IE) {
                 int i;
                 memcpy(data, mac->wpa.IE, mac->wpa.IElen);
                 data += mac->wpa.IElen;
                 printk(KERN_INFO PFX "Added WPA_IE of %d bytes to association request\n"
                         "Contents of WPA_IE: ", mac->wpa.IElen);
                 for (i=0; i<mac->wpa.IElen; i++)
                         printk("0x%02x ",mac->wpa.IE[i]);
                 printk("\n");
         }

Larry

^ permalink raw reply

* Re: [PATCH 0/4] ehea: IBM eHEA Ethernet Device Driver
From: Stephen Hemminger @ 2006-06-07 17:24 UTC (permalink / raw)
  To: Jan-Bernd Themann; +Cc: netdev, raisch, themann, tklein, meder, schickhj
In-Reply-To: <4486ECED.9080608@de.ibm.com>

On Wed, 07 Jun 2006 17:12:45 +0200
Jan-Bernd Themann <ossthema@de.ibm.com> wrote:

> Hello,
> 
> this is the first version of the IBM eHEA Ethernet Device Driver.
> It supports a new IBM ethernet chip on System p.
> 
> Main functionality including broadcast multicast and some parts of
> ethtool already work.
> 
> Things we're still working on:
> - vlan support
> - performance improvements in SMP systems
> - kernel coding style

Please:
   - Get rid of the debug macro's with 9 arguments...


^ permalink raw reply

* Re: Problem authenticating using WPA with bcm43xx-softmac
From: Dan Williams @ 2006-06-07 17:29 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Larry Finger, netdev, Jouni Malinen
In-Reply-To: <1149695859.3925.11.camel@johannes>

On Wed, 2006-06-07 at 17:57 +0200, Johannes Berg wrote:
> On Wed, 2006-06-07 at 17:51 +0200, Johannes Berg wrote:
> 
> > Well, it should be shown in the 802.11i spec too.
> 
> I suppose that it is the association request, and needs to contain the
> RSN described in 7.3.2.25 as per 7.2.3.4 in 802.11i. This is, afaik, the
> 'generic IE' that is added with the wext. Now, it looks like the RSN
> isn't included but the WPA2 info or something? Also, the genIE in your
> log doesn't look correct to me, starting with ffffff?? Jouni, do you
> have any idea what might be going on?

I believe that wpa_supplicant tells the driver what genie to use through
the SIOCSIWGENIE wext call.  The IEs match between what the driver
appears to be reporting, and what wpa_supplicant says from the logs.
wpa_supplicant is almost certainly writing the correct IE to the driver
through wext, so I think the debug output from softmac must be
formatting the string incorrectly when printing it out to the logs.

Looking at it further:

struct ieee80211softmac_wpa {
        char *IE;
        int IElen;
        int IEbuflen;
};

from ieee80211softmac_wx.c: ieee80211softmac_wx_set_genie()

                memcpy(mac->wpa.IE, extra, wrqu->data.length);
                dprintk(KERN_INFO PFX "generic IE set to ");
                for (i=0;i<wrqu->data.length;i++)
                        dprintk("%.2x", mac->wpa.IE[i]);
                dprintk("\n");

the dprintk code isn't doing the right thing here, given an array of
bytes.  You probably want:

                        dprintk("%.2hhx", mac->wpa.IE[i]);

(ie, add the "hh" before the x to tell the print that it's a char)

Dan



^ permalink raw reply

* Re: [PATCH 3/4] ehea: queue managment
From: Stephen Hemminger @ 2006-06-07 17:29 UTC (permalink / raw)
  To: Jan-Bernd Themann; +Cc: netdev, meder, raisch, themann, tklein
In-Reply-To: <4487073E.1020403@de.ibm.com>

On Wed, 07 Jun 2006 19:05:02 +0200
Jan-Bernd Themann <ossthema@de.ibm.com> wrote:

> Signed-off-by:  Jan-Bernd Themann <themann@de.ibm.com>
> 
> 
> drivers/net/ehea/ehea_qmr.c |  719 ++++++++++++++++++++++++++++++++++++++++++++
> drivers/net/ehea/ehea_qmr.h |  390 +++++++++++++++++++++++
> 2 files changed, 1109 insertions(+)
> 

Make it look less like C++

Do you really need to use vmalloc/vfree? Are the data structures that big?

Be careful about global namespace issues. Stick to one prefix like ehea_
for all non static function names. Consider putting all in one file, or
use #include to cause it to be one compilation unit.



^ permalink raw reply

* Re: [PATCH 4/4] ehea: Kconfig and Makefile
From: Randy.Dunlap @ 2006-06-07 17:59 UTC (permalink / raw)
  To: Jan-Bernd Themann; +Cc: netdev, meder, raisch, themann, tklein
In-Reply-To: <4487077B.4020405@de.ibm.com>

On Wed, 07 Jun 2006 19:06:03 +0200 Jan-Bernd Themann wrote:

> Signed-off-by:  Jan-Bernd Themann <themann@de.ibm.com>
> 
> 
> drivers/net/ehea/Kconfig  |    6 ++++++
> drivers/net/ehea/Makefile |   45 +++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 51 insertions(+)
> 
> 
> 
> --- linux-2.6.16-rc5-orig/drivers/net/ehea/Makefile    1969-12-31 16:00:00.000000000 -0800
> +++ kernel/drivers/net/ehea/Makefile    2006-06-07 07:01:14.634178704 -0700
> @@ -0,0 +1,45 @@
> +# Server eHEA ethernet device driver for Linux on POWER
> +#
> +#
> +#  linux/drivers/net/ehea/Makefile
> +#
> +#  eHEA ethernet device driver for IBM eServer System p
> +#
> +#  (C) Copyright IBM Corp. 2006
> +#
> +#  Authors:
> +#       Christoph Raisch <raisch@de.ibm.com>
> +#       Jan-Bernd Themann <themann@de.ibm.com>
> +#       Heiko-Joerg Schick <schickhj@de.ibm.com>
> +#       Thomas Klein <tklein@de.ibm.com>
> +#
> +#
> +# 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.
> +
> +
> +
> +
> +# To compile module type:
> +# make -C /root/linux-2.6.5-7.244 SUBDIRS=`pwd` V=1 modules CONFIG_EHEA=m
> +# make -C /usr/src/linux-2.6.17-rc5 SUBDIRS=`pwd` V=1 modules CONFIG_EHEA=m
> +
> +ehea_mod-objs = ehea_main.o ehea_phyp.o ehea_qmr.o ehea_ethtool.o ehea_phyp.o
> +
> +obj-$(CONFIG_EHEA) += ehea_mod.o
> +
> +#CFLAGS += -Werror
> +
> +
> +

45 lines for a 5-line makefile.  :(

You need to integrate the Makefile and Kconfig into the upper-level
directory Makefile and Kconfig files.  Don't expect/require people
to enter thing like this:
> +# make -C /root/linux-2.6.5-7.244 SUBDIRS=`pwd` V=1 modules CONFIG_EHEA=m
> +# make -C /usr/src/linux-2.6.17-rc5 SUBDIRS=`pwd` V=1 modules CONFIG_EHEA=m


> --- linux-2.6.16-rc5-orig/drivers/net/ehea/Kconfig    1969-12-31 16:00:00.000000000 -0800
> +++ kernel/drivers/net/ehea/Kconfig    2006-06-07 07:01:14.637178248 -0700
> @@ -0,0 +1,6 @@
> +config EHEA
> +       tristate "eHEA Ethernet support"
> +       depends on IBMEBUS
> +       ---help---
> +       This driver supports the IBM pSeries
> +       Ethernet adapter

That last sentence can be on one line, please.

---
~Randy

^ permalink raw reply

* Re: Problem authenticating using WPA with bcm43xx-softmac
From: Larry Finger @ 2006-06-07 18:12 UTC (permalink / raw)
  To: Dan Williams; +Cc: Johannes Berg, netdev, Jouni Malinen
In-Reply-To: <1149701352.2625.20.camel@localhost.localdomain>

Dan Williams wrote:
> On Wed, 2006-06-07 at 17:57 +0200, Johannes Berg wrote:
>> On Wed, 2006-06-07 at 17:51 +0200, Johannes Berg wrote:
>>
>>> Well, it should be shown in the 802.11i spec too.
>> I suppose that it is the association request, and needs to contain the
>> RSN described in 7.3.2.25 as per 7.2.3.4 in 802.11i. This is, afaik, the
>> 'generic IE' that is added with the wext. Now, it looks like the RSN
>> isn't included but the WPA2 info or something? Also, the genIE in your
>> log doesn't look correct to me, starting with ffffff?? Jouni, do you
>> have any idea what might be going on?
> 
> I believe that wpa_supplicant tells the driver what genie to use through
> the SIOCSIWGENIE wext call.  The IEs match between what the driver
> appears to be reporting, and what wpa_supplicant says from the logs.
> wpa_supplicant is almost certainly writing the correct IE to the driver
> through wext, so I think the debug output from softmac must be
> formatting the string incorrectly when printing it out to the logs.
> 
> Looking at it further:
> 
> struct ieee80211softmac_wpa {
>         char *IE;
>         int IElen;
>         int IEbuflen;
> };
> 
> from ieee80211softmac_wx.c: ieee80211softmac_wx_set_genie()
> 
>                 memcpy(mac->wpa.IE, extra, wrqu->data.length);
>                 dprintk(KERN_INFO PFX "generic IE set to ");
>                 for (i=0;i<wrqu->data.length;i++)
>                         dprintk("%.2x", mac->wpa.IE[i]);
>                 dprintk("\n");
> 
> the dprintk code isn't doing the right thing here, given an array of
> bytes.  You probably want:
> 
>                         dprintk("%.2hhx", mac->wpa.IE[i]);
> 
> (ie, add the "hh" before the x to tell the print that it's a char)
> 
That doesn't work - the result is

%hx%hx%hx%hx%hx%hx%hx%hx%hx%hx%hx%hx%hx%hx%hx%hx%hx%hx%hx%hx%hx%hx%hx%hx

I changed the line to cast the output byte as a u8 as follows:

                         dprintk("%.2x", (u8)mac->wpa.IE[i]);

This produces the line

generic IE set to dd160050f20101000050f20201000050f20201000050f202

This is the WPA IE supplied by wpa_supplicant and it matches the one used in the ndiswrapper case. 
One mystery solved, but why doesn't it work?

Johannes - should I submit the patch to fix this printout, or would you like to do it?

Larry

^ permalink raw reply

* Re: [PATCH] pcnet32 driver NAPI support
From: Don Fry @ 2006-06-07 18:20 UTC (permalink / raw)
  To: Lennart Sorensen; +Cc: linux-kernel, linux-net, netdev
In-Reply-To: <20060607165225.GB7859@csclub.uwaterloo.ca>

On Wed, Jun 07, 2006 at 12:52:25PM -0400, Lennart Sorensen wrote:
> I have added NAPI support to the pcnet32 driver.  This has greatly
> improved the responsiveness on my systems (geode GX1 266MHz) when under
> heavy network load.  Without this change the system would become
> unresponsive due to interrupts when flooded with traffic, and eventually
> the watchdog would reboot the system due to the watchdog daemon being
> starved for cpu time.  With the patch the system is still useable on a
> serial console, although very slow.  Network throughput is also higher
> since more time is spend processing packets and getting them sent out,
> instead of only spending time acknowledging interrupts from incoming
> packets.
> 
> Now having never actually done a patch submission to the kernel before,
> I will try and see if I can do it right.
> 
> The patch adds a PCNET32_NAPI config option to drivers/net/Kconfig, and
> the appropriate code to support the option to drivers/net/pcnet32.c and
> has been tested on many of my systems (allthough they are allmost all
> identical, and require some extra patches to pcnet32 due to not having
> an EEPROM installed), and on an AT-2700TX.
> 
> I have made a diff against 2.6.16.20 and 2.6.17-rc6.
> 
> Comments would be very welcome.

I am also working on a NAPI version of the pcnet32 driver for many of
the same reasons, and will compare what you have with my own
implementation.  I probably won't be able to do much until Friday.  

Just a couple of comments.  I am adding netdev@vger.kernel.org to the cc
list, as most network driver discussion is done here rather than lkml.
linux-kernel (and linux-net) should be deleted in future replies.

The 2.6.17-rc6 would be the correct source to patch against.  Since this
is an enhancement it will not come out till 2.6.18.

I would not change the driver name from pcnet32 to pcnet32napi, but I
would changes the version from 1.32 to 1.33NAPI or something like that.

Some areas of concern that you may have addressed already, I have not
scanned your changes yet, are what happens if the ring size is changed
without bringing down the interface (via ethtool), or if the loopback
test is run in a similar fashion, or a tx timeout occurs.

The lp->lock MUST be held whenever accessing the csr or bcr registers as
this is a multi-step process, and has been the source of problems in the
past.  Even on UP systems.

> 
> Signed-off-by: Len Sorensen <lsorense@csclub.uwaterloo.ca>
> 
> Len Sorensen

-- 
Don Fry
brazilnut@us.ibm.com

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox