Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH torvalds-2.6] cdc_ether: additional Ericsson MBM PID's to the whitelist
From: David Miller @ 2009-11-04 13:25 UTC (permalink / raw)
  To: torgny.johansson; +Cc: netdev, saurin.shah
In-Reply-To: <200911032228.05527.torgny.johansson@gmail.com>

From: Torgny Johansson <torgny.johansson@gmail.com>
Date: Tue, 3 Nov 2009 22:28:05 +0100

> Trying with another e-mail client to see if that works better. I've
> sent it to my own gmail first and if I "view original" in gmail the
> patch works and applies cleanly after downloading it so I'm hoping
> it will work for you guys too.

Looks good, applied to net-2.6, thanks!

^ permalink raw reply

* Re: [PATCH 1/1] Use defaults when no route options are available
From: David Miller @ 2009-11-04 13:28 UTC (permalink / raw)
  To: gilad; +Cc: Valdis.Kletnieks, netdev, ori, linux-kernel, akpm
In-Reply-To: <1257276085-13681-1-git-send-email-gilad@codefidence.com>

From: Gilad Ben-Yossef <gilad@codefidence.com>
Date: Tue,  3 Nov 2009 21:21:25 +0200

> Trying to parse the option of a SYN packet that we have
> no route entry for should just use global wide defaults
> for route entry options.
> 
> Signed-off-by: Gilad Ben-Yossef <gilad@codefidence.com>

The tester has indicated that this doesn't solve things
for them.  I suspect there is another dependency on 'dst'
not being NULL in another path somewhere.

So until this is fully resolved I'm holding off on applying
this patch.

^ permalink raw reply

* Re: [PATCHv7 1/3] tun: export underlying socket
From: David Miller @ 2009-11-04 13:30 UTC (permalink / raw)
  To: mst
  Cc: netdev, virtualization, kvm, linux-kernel, mingo, linux-mm, akpm,
	hpa, gregory.haskins, rusty, s.hetze
In-Reply-To: <20091103172400.GB5591@redhat.com>

From: "Michael S. Tsirkin" <mst@redhat.com>
Date: Tue, 3 Nov 2009 19:24:00 +0200

> Assuming it's okay with davem, I think it makes sense to merge this
> patch through Rusty's tree because vhost is the first user of the new
> interface.  Posted here for completeness.

I'm fine with that, please add my:

Acked-by: David S. Miller <davem@davemloft.net>

^ permalink raw reply

* Re: CLONE_NEWNET requires CAP_NET_RAW (and the intended CAP_SYS_ADMIN)
From: David Miller @ 2009-11-04 13:33 UTC (permalink / raw)
  To: eparis; +Cc: netdev, nhorman, acme, dwalsh
In-Reply-To: <1257279352.2891.202.camel@dhcp231-106.rdu.redhat.com>

From: Eric Paris <eparis@redhat.com>
Date: Tue, 03 Nov 2009 15:15:52 -0500

> Do people see an issue with me passing kern down to create?

This sounds fine.

> Anyone have problems with me ripping out the half ass unused
> security infrastructure?

If you can simplify it as you describe, indeed this sounds
like a great change to make.

^ permalink raw reply

* Re: [PATCHv7 3/3] vhost_net: a kernel-level virtio server
From: Andi Kleen @ 2009-11-04 13:37 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Andi Kleen, netdev, virtualization, kvm, linux-kernel, mingo,
	linux-mm, akpm
In-Reply-To: <20091104131735.GD8920@redhat.com>

On Wed, Nov 04, 2009 at 03:17:36PM +0200, Michael S. Tsirkin wrote:
> On Wed, Nov 04, 2009 at 02:15:33PM +0100, Andi Kleen wrote:
> > On Wed, Nov 04, 2009 at 03:08:28PM +0200, Michael S. Tsirkin wrote:
> > > On Wed, Nov 04, 2009 at 01:59:57PM +0100, Andi Kleen wrote:
> > > > > Fine?
> > > > 
> > > > I cannot say -- are there paths that could drop the device beforehand?
> > > 
> > > Do you mean drop the mm reference?
> > 
> > No the reference to the device, which owns the mm for you.
> 
> The device is created when file is open and destroyed
> when file is closed. So I think the fs code handles the
> reference counting for me: it won't call file cleanup
> callback while some userspace process has the file open.
> Right?

Yes.

But the semantics when someone inherits such a fd through exec
or through file descriptor passing would be surely "interesting"
You would still do IO on the old VM.

I guess it would be a good way to confuse memory accounting schemes 
or administrators @)

It would be all saner if this was all a single atomic step.

-Andi
-- 
ak@linux.intel.com -- Speaking for myself only.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: HTB accuracy on 10GbE
From: Jarek Poplawski @ 2009-11-04 13:39 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Ryousei Takano, Stephen Hemminger, Patrick McHardy,
	Linux Netdev List, takano-ryousei
In-Reply-To: <4AF1660E.1080401@gmail.com>

On 04-11-2009 12:31, Eric Dumazet wrote:
....
> Maybe you can try changing class mtu to 40000 instead of 9000, and quantum to 60000 too
> 
> tc class add dev $DEV parent 1: classid 1:1 htb rate ${rate}mbit mtu 40000 quantum 60000
> 
> (because your tcp stack sends large buffers ( ~ 60000 bytes) as your NIC can offload tcp segmentation)
> 

Hmm..., testing htb scheduling exactness with tso/gso on seems kind of
weather reporting. On the other hand, depending on hardware, these
rates could be available with mtu 9000 and tso/gso off, unless I
miss something. So maybe such a test would be interesting too?
Then I'd suggest this one, erlier mentioned, patch to iproute2:
http://marc.info/?l=linux-netdev&m=124453482324409&w=2

Best regards,
Jarek P.

^ permalink raw reply

* Re: [PATCHv7 3/3] vhost_net: a kernel-level virtio server
From: Michael S. Tsirkin @ 2009-11-04 13:41 UTC (permalink / raw)
  To: Andi Kleen
  Cc: netdev, virtualization, kvm, linux-kernel, mingo, linux-mm, akpm
In-Reply-To: <20091104133728.GN31511@one.firstfloor.org>

On Wed, Nov 04, 2009 at 02:37:28PM +0100, Andi Kleen wrote:
> On Wed, Nov 04, 2009 at 03:17:36PM +0200, Michael S. Tsirkin wrote:
> > On Wed, Nov 04, 2009 at 02:15:33PM +0100, Andi Kleen wrote:
> > > On Wed, Nov 04, 2009 at 03:08:28PM +0200, Michael S. Tsirkin wrote:
> > > > On Wed, Nov 04, 2009 at 01:59:57PM +0100, Andi Kleen wrote:
> > > > > > Fine?
> > > > > 
> > > > > I cannot say -- are there paths that could drop the device beforehand?
> > > > 
> > > > Do you mean drop the mm reference?
> > > 
> > > No the reference to the device, which owns the mm for you.
> > 
> > The device is created when file is open and destroyed
> > when file is closed. So I think the fs code handles the
> > reference counting for me: it won't call file cleanup
> > callback while some userspace process has the file open.
> > Right?
> 
> Yes.
> 
> But the semantics when someone inherits such a fd through exec
> or through file descriptor passing would be surely "interesting"
> You would still do IO on the old VM.
> 
> I guess it would be a good way to confuse memory accounting schemes 
> or administrators @)
> It would be all saner if this was all a single atomic step.
> 
> -Andi

I have this atomic actually. A child process will first thing
do SET_OWNER: this is required before any other operation.

SET_OWNER atomically (under mutex) does two things:
- check that there is no other owner
- get mm and set current process as owner

I hope this addresses your concern?

-- 
MST

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [PATCH net-next-2.6] net: Introduce for_each_netdev_rcu() iterator
From: David Miller @ 2009-11-04 13:43 UTC (permalink / raw)
  To: eric.dumazet; +Cc: netdev
In-Reply-To: <4AEEF908.8070900@gmail.com>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Mon, 02 Nov 2009 16:21:44 +0100

> [PATCH net-next-2.6 take2] net: Introduce for_each_netdev_rcu() iterator
...
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>

Looks great Eric, applied.

^ permalink raw reply

* Re: [PATCH 1/1] DaVinci EMAC: correct param for ISR
From: David Miller @ 2009-11-04 13:45 UTC (permalink / raw)
  To: Bo.Liu; +Cc: khilman, davinci-linux-open-source-bounces, netdev
In-Reply-To: <4AEF8CD6.9060804@windriver.com>

From: Tonyliu <Bo.Liu@windriver.com>
Date: Tue, 03 Nov 2009 09:52:22 +0800

> Subject: [PATCH 1/1] DaVinci EMAC: correct param for ISR
> 
> emac_irq is declared as:
> 
> static irqreturn_t emac_irq(int irq, void *dev_id)
> {
>        struct net_device *ndev = (struct net_device *)dev_id;
>        struct emac_priv *priv = netdev_priv(ndev);
>     ... 
> 
> 	Clearly emac_irq() needs "struct net_device *" as "void *dev_id", so correct this.
> 
> Signed-off-by: Tonyliu <Bo.Liu@windriver.com>

Applied to net-2.6, thank you.

^ permalink raw reply

* virtio-net: new section mismatch warning. revert patch?
From: Michael S. Tsirkin @ 2009-11-04 14:17 UTC (permalink / raw)
  To: Uwe Kleine-König, Sam Ravnborg
  Cc: David S. Miller, Rusty Russell, Alex Williamson, Mark McLoughlin,
	netdev, linux-kernel

With v2.6.32-rcX I started getting section mismatch warnings for
virtio_net.
make with CONFIG_DEBUG_SECTION_MISMATCH=y shows:

WARNING: drivers/net/virtio_net.o(.data+0x90): Section mismatch in
reference from the variable virtio_net to the function
.devexit.text:virtnet_remove()                                                                    
The variable virtio_net references                                                                            
the function __devexit virtnet_remove()                                                                       
If the reference is valid then annotate the                                                                   
variable with __exit* (see linux/init.h) or name the variable:                                                
*driver, *_template, *_timer, *_sht, *_ops, *_probe, *_probe_one, *_console,                                  

virtnet_remove was converted to devexit by this commit:

	commit 3d1285beff2e8467b8c3884d83b7a91a99aa9fcd
	Author: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
	Date:   Wed Sep 30 22:28:34 2009 +0000

	    move virtnet_remove to .devexit.text

We didn't have these warnings in v2.6.31, so this is a regression.
revert?

-- 
MST

^ permalink raw reply

* RE: PATCH: Network Device Naming mechanism and policy
From: Narendra_K @ 2009-11-04 14:23 UTC (permalink / raw)
  To: bryan
  Cc: dannf, bhutchings, netdev, linux-hotplug, Matt_Domsch,
	Jordan_Hargrave, Charles_Rose, Sandeep_K_Shandilya
In-Reply-To: <4ADC906E.2050909@kadzban.is-a-geek.net>


>>> Matt, Ben and I talked about a few other possibilities on IRC. The 
>>> one I like the most at the moment is an idea Ben had to creat dummy 
>>> files named after the ifindex. Then, use symlinks for the 
>kernel name 
>>> and the various by-$property subdirectories. This means the KOBJ 
>>> events will need to expose the ifindex.
>>> 
>> 
>> I suppose the KOBJ events already expose the ifindex of a network 
>> interface. The file "/sys/class/net/ethN/uevent" contains 
>> INTERFACE=ethN and IFINDEX=n already. But it looks like udev doesn't 
>> use it in any way.
>
>Right; it could simply do the equivalent of:
>
>touch /dev/netdev/$env{IFINDEX}
>
>instead of its normal mknod(2), and then do normal SYMLINK processing.
>That last part is what would link 
>/dev/netdev/by-name/$env{INTERFACE} to that device, along with 
>/dev/netdev/by-mac/*, /dev/netdev/by-path/*, etc., etc., in as 
>many different ways as people want to add rules.
>
>(Or /dev/net/by-* instead of netdev; I'm mostly ambivalent 
>about the first-level directory under /dev.  Looks like 
>libnetdevname requires /dev/netdev though.)
>
>> For example, with the kernel patch the "/sys/class/net/ethN/uevent" 
>> contains in addition to the above details, MAJOR=M and MINOR=m which 
>> the udev knows how to make use of with a rule like
>> 
>> SUBSYSTEM=="net", KERNEL!="tun", NAME="netdev/%k", MODE="0600".
>
>And if the only point is to get the ifindex via stat(2) on the 
>resulting symlinks, but people don't like device files, then 
>why not get the ifindex via readlink(2) (and a bit of string 
>parsing, and a strtol(3) or
>strtoul(3) call) instead?  :-)


I suppose this issue can also be addressed in another way. Currently,
the sysfs contains various attributes of a network interface under the
directory "/sys/class/net/ethN", for example
"/sys/class/net/ethN/address". This will be used by udev as below -

SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*",
ATTR{address}=="00:1d:09:6a:78:ec", ATTR{type}=="1", KERNEL=="eth*",
NAME="eth1".

Similarly, export an attribute named "smbios_name" to sysfs, i.e
"/sys/class/net/eth0/smbios_name". "Cat /sys/class/net/eth0/smbios_name"
would show "Embedded_NIC_1[23..]" and this can be used by udev in
70-persistent-net.rules as 

SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*",
ATTR{smbios_name}=="Embedded_NIC_1", ATTR{type}=="1", KERNEL=="eth*",
NAME="eth0".

I suppose this would not need any changes to the udev code and existing
udev infrastructure can be used as udev is capable handling
ATTR{something}.

This would also ensure that whichever device is "Embedded_NIC_1" as per
the BIOS, will also be "eth0" in the os.

Netdev, What are your views on this idea ?

With regards,
Narendra K  

^ permalink raw reply

* [PATCH] tc: remove dlfcn.h from files that dont need it
From: Mike Frysinger @ 2009-11-04 14:26 UTC (permalink / raw)
  To: stephen.hemminger, netdev
In-Reply-To: <1257344795-8665-1-git-send-email-vapier@gentoo.org>

A bunch of source files look like they're copy & pasted from other files,
and some include header files that they don't actually need.  Since dlfcn
has very specific usage (and is a pain on a static-only system), drop it
where it isn't really needed.

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
---
 tc/em_cmp.c   |    1 -
 tc/em_meta.c  |    1 -
 tc/em_nbyte.c |    1 -
 tc/em_u32.c   |    1 -
 tc/m_nat.c    |    1 -
 tc/m_xt.c     |    1 -
 6 files changed, 0 insertions(+), 6 deletions(-)

diff --git a/tc/em_cmp.c b/tc/em_cmp.c
index ce72a42..6addce0 100644
--- a/tc/em_cmp.c
+++ b/tc/em_cmp.c
@@ -18,7 +18,6 @@
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <string.h>
-#include <dlfcn.h>
 #include <errno.h>
 
 #include "m_ematch.h"
diff --git a/tc/em_meta.c b/tc/em_meta.c
index ee6034f..033e29f 100644
--- a/tc/em_meta.c
+++ b/tc/em_meta.c
@@ -18,7 +18,6 @@
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <string.h>
-#include <dlfcn.h>
 #include <errno.h>
 
 #include "m_ematch.h"
diff --git a/tc/em_nbyte.c b/tc/em_nbyte.c
index 242c361..87f3e9d 100644
--- a/tc/em_nbyte.c
+++ b/tc/em_nbyte.c
@@ -18,7 +18,6 @@
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <string.h>
-#include <dlfcn.h>
 #include <errno.h>
 
 #include "m_ematch.h"
diff --git a/tc/em_u32.c b/tc/em_u32.c
index 402bea0..21ed70f 100644
--- a/tc/em_u32.c
+++ b/tc/em_u32.c
@@ -18,7 +18,6 @@
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <string.h>
-#include <dlfcn.h>
 #include <errno.h>
 
 #include "m_ematch.h"
diff --git a/tc/m_nat.c b/tc/m_nat.c
index 6e7fd05..01ec032 100644
--- a/tc/m_nat.c
+++ b/tc/m_nat.c
@@ -19,7 +19,6 @@
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <string.h>
-#include <dlfcn.h>
 #include "utils.h"
 #include "tc_util.h"
 #include <linux/tc_act/tc_nat.h>
diff --git a/tc/m_xt.c b/tc/m_xt.c
index 0fe6189..0c7ec60 100644
--- a/tc/m_xt.c
+++ b/tc/m_xt.c
@@ -25,7 +25,6 @@
 #include "tc_util.h"
 #include <linux/tc_act/tc_ipt.h>
 #include <stdio.h>
-#include <dlfcn.h>
 #include <getopt.h>
 #include <errno.h>
 #include <string.h>
-- 
1.6.5.1


^ permalink raw reply related

* [PATCH] ignore gdb/patch related files
From: Mike Frysinger @ 2009-11-04 14:26 UTC (permalink / raw)
  To: stephen.hemminger, netdev

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
---
 .gitignore |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore
index 8199aae..5a3d20f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,12 @@
 Config
+.gdbinit
+.gdb_history
 *.o
 *.a
 *.so
+*.gdb
 *~
+*.diff
+*.patch
+*.orig
+*.rej
-- 
1.6.5.1


^ permalink raw reply related

* [PATCH] ifstat/nstat/rtacct: use daemon()
From: Mike Frysinger @ 2009-11-04 14:26 UTC (permalink / raw)
  To: stephen.hemminger, netdev
In-Reply-To: <1257344795-8665-1-git-send-email-vapier@gentoo.org>

A bunch of misc utils basically reimplement the daemon() function (the
whole fork/close/chdir/etc...).  Rather than do that, use daemon() as
that will work under nommu Linux systems that lack fork().

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
---
 misc/ifstat.c |    8 ++++----
 misc/nstat.c  |    8 ++++----
 misc/rtacct.c |    8 ++++----
 3 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/misc/ifstat.c b/misc/ifstat.c
index 68dfdee..0ce8c92 100644
--- a/misc/ifstat.c
+++ b/misc/ifstat.c
@@ -663,10 +663,10 @@ int main(int argc, char *argv[])
 			perror("ifstat: listen");
 			exit(-1);
 		}
-		if (fork())
-			exit(0);
-		chdir("/");
-		close(0); close(1); close(2); setsid();
+		if (daemon(0, 0)) {
+			perror("ifstat: daemon");
+			exit(-1);
+		}
 		signal(SIGPIPE, SIG_IGN);
 		signal(SIGCHLD, sigchild);
 		server_loop(fd);
diff --git a/misc/nstat.c b/misc/nstat.c
index 80e695f..2e44ed2 100644
--- a/misc/nstat.c
+++ b/misc/nstat.c
@@ -513,10 +513,10 @@ int main(int argc, char *argv[])
 			perror("nstat: listen");
 			exit(-1);
 		}
-		if (fork())
-			exit(0);
-		chdir("/");
-		close(0); close(1); close(2); setsid();
+		if (daemon(0, 0)) {
+			perror("nstat: daemon");
+			exit(-1);
+		}
 		signal(SIGPIPE, SIG_IGN);
 		signal(SIGCHLD, sigchild);
 		server_loop(fd);
diff --git a/misc/rtacct.c b/misc/rtacct.c
index eb3ea9e..a247dfd 100644
--- a/misc/rtacct.c
+++ b/misc/rtacct.c
@@ -524,10 +524,10 @@ int main(int argc, char *argv[])
 			perror("rtacct: listen");
 			exit(-1);
 		}
-		if (fork())
-			exit(0);
-		chdir("/");
-		close(0); close(1); close(2); setsid();
+		if (daemon(0, 0)) {
+			perror("rtacct: daemon");
+			exit(-1);
+		}
 		signal(SIGPIPE, SIG_IGN);
 		signal(SIGCHLD, sigchild);
 		server_loop(fd);
-- 
1.6.5.1


^ permalink raw reply related

* Re: [PATCH 1/1] Use defaults when no route options are available
From: Gilad Ben-Yossef @ 2009-11-04 14:27 UTC (permalink / raw)
  To: David Miller; +Cc: Valdis.Kletnieks, netdev, ori, linux-kernel, akpm
In-Reply-To: <20091104.052816.74593826.davem@davemloft.net>

David Miller wrote:

> From: Gilad Ben-Yossef <gilad@codefidence.com>
> Date: Tue,  3 Nov 2009 21:21:25 +0200
>
>   
>> Trying to parse the option of a SYN packet that we have
>> no route entry for should just use global wide defaults
>> for route entry options.
>>
>> Signed-off-by: Gilad Ben-Yossef <gilad@codefidence.com>
>>     
>
> The tester has indicated that this doesn't solve things
> for them.  I suspect there is another dependency on 'dst'
> not being NULL in another path somewhere.
>
> So until this is fully resolved I'm holding off on applying
> this patch.
>
>   
Yes, indeed.

I managed to replicate it here. Looking into it right now.

Thanks,
Gilad


-- 
Gilad Ben-Yossef
Chief Coffee Drinker & CTO
Codefidence Ltd.

Web:   http://codefidence.com
Cell:  +972-52-8260388
Skype: gilad_codefidence
Tel:   +972-8-9316883 ext. 201
Fax:   +972-8-9316884
Email: gilad@codefidence.com

Check out our Open Source technology and training blog - http://tuxology.net

	"The biggest risk you can take it is to take no risk."
		-- Mark Zuckerberg and probably others

^ permalink raw reply

* Re: [announce] new rt2800 drivers for Ralink wireless & project tree
From: John W. Linville @ 2009-11-04 14:38 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Ivo van Doorn, Bartlomiej Zolnierkiewicz,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA, Randy Dunlap, Luis Correia,
	Johannes Berg, Jarek Poplawski, Pekka Enberg, David Miller
In-Reply-To: <20091104083737.GA16978-X9Un+BFzKDI@public.gmane.org>

On Wed, Nov 04, 2009 at 09:37:37AM +0100, Ingo Molnar wrote:

<snip>

> Really, you should listen to contrary opinion and _you_ should work 
> _hard_ to integrate Bart socially and open up your close circle of 
> wireless insiders instead of fighting his 'outsider' contributions every 
> which way. We dont care if people are rough, express displeasure and 
> show strong opinion about crappy code - but the moment you are 
> _excluding_ capable people and playing petty office politics (like you 
> are very clearly doing it with Bart here) everyone loses.

Ivo almost immediately ACKed 10 of Bart's patches (despite Bart's
failure to post them to the mailing list directly per convention),
so you criticize Ivo for saying he needed time to review the rest?
And you accuse him of excluding Bart's contributions when they have
only just arrived?

> Guys, show some minimal amount of honesty, openness and critical 
> thinking please ...

I would ask the same of you, Ingo.  You have burst onto the scene
only recently, full of accusations and blame for one side and
apparently unable to recognize the faults of the other.  You fail to
recognize that this set of patches is essentially the _first_ time
Bart has actually made any attempt to work on the rt2x00 drivers.
Your partisanship is clear.

At least Bart has finally made some rt2x00 patches available.  That is
how things get done.  You continuing to defend him as some sort of
martyr is completely unhelpful.

John
-- 
John W. Linville		Someday the world will need a hero, and you
linville-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org			might be all we have.  Be ready.
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* WARNING: at net/ipv4/tcp.c:1186
From: Markus Suvanto @ 2009-11-04 14:48 UTC (permalink / raw)
  To: netdev

2.6.32-rc6 dmesg is full of warnings...


------------[ cut here ]------------
WARNING: at net/ipv4/tcp.c:1186 0xffffffff8121c0cf()
Hardware name: System Product Name
Modules linked in: tun bitrev kvm_amd kvm option usbserial ipv6
snd_seq_dummy snd_seq_oss snd_seq_midi_event snd_seq snd_seq_device
snd_pcm_o
_oss libafs(P) af_packet bridge stp llc btrfs zlib_deflate cryptomgr
aead pcompress crypto_blkcipher crc32c libcrc32c crypto_hash
crypto_alga
usedev usbhid usbmouse dvb_usb_dib0700 dib7000p dib7000m dib0070
dvb_usb dib3000mc dib8000 dibx000_common dvb_core usb_storage radeon
ttm snd
tihdmi drm_kms_helper ata_generic drm snd_hda_codec_via firmware_class
firewire_ohci i2c_piix4 i2c_algo_bit firewire_core crc_itu_t psmouse p
_hda_intel snd_hda_codec rtc_cmos snd_pcm rtc_core ehci_hcd uhci_hcd
ohci1394 ohci_hcd cfbcopyarea atkbd snd_timer atl1e snd usbcore pcspkr
s
0_pnp soundcore evdev 8250 cfbimgblt floppy ieee1394 i2c_core
processor rtc_lib thermal pata_atiixp serial_core snd_page_alloc
cfbfillrect bu
_sys asus_atk0110 nls_base sg hwmon unix ext4 jbd2 crc16 dm_mod raid1
md_mod sd_mod ahci libata scsi_mod fbcon tileblit crc32 font bitblit
so
Pid: 12653, comm: vdr Tainted: P        W  2.6.32-rc6-00572-gb419148 #23
Call Trace:
 [<ffffffff8121c0cf>] ? 0xffffffff8121c0cf
 [<ffffffff8121c0cf>] ? 0xffffffff8121c0cf
 [<ffffffff81044424>] ? 0xffffffff81044424
 [<ffffffff8121c0cf>] ? 0xffffffff8121c0cf
 [<ffffffff8121ca56>] ? 0xffffffff8121ca56
 [<ffffffff8105dc59>] ? 0xffffffff8105dc59
 [<ffffffff8105dd72>] ? 0xffffffff8105dd72
 [<ffffffff811e1d90>] ? 0xffffffff811e1d90
 [<ffffffff811dfdc5>] ? 0xffffffff811dfdc5
 [<ffffffff8105a790>] ? 0xffffffff8105a790
 [<ffffffff81067af2>] ? 0xffffffff81067af2
 [<ffffffff810699d7>] ? 0xffffffff810699d7
 [<ffffffff8100bece>] ? 0xffffffff8100bece
 [<ffffffff811e1207>] ? 0xffffffff811e1207
 [<ffffffff811df502>] ? 0xffffffff811df502
 [<ffffffff811e12c8>] ? 0xffffffff811e12c8
 [<ffffffff81025440>] ? 0xffffffff81025440
 [<ffffffff81038a48>] ? 0xffffffff81038a48
 [<ffffffff81264004>] ? 0xffffffff81264004
 [<ffffffff8100b2eb>] ? 0xffffffff8100b2eb
---[ end trace d816ed2b263fe303 ]---
recvmsg bug: copied 2AFC272F seq 30B09D30
------------[ cut here ]------------
WARNING: at net/ipv4/tcp.c:1186 0xffffffff8121c0cf()
Hardware name: System Product Name
Modules linked in: tun bitrev kvm_amd kvm option usbserial ipv6
snd_seq_dummy snd_seq_oss snd_seq_midi_event snd_seq snd_seq_device
snd_pcm_o
_oss libafs(P) af_packet bridge stp llc btrfs zlib_deflate cryptomgr
aead pcompress crypto_blkcipher crc32c libcrc32c crypto_hash
crypto_alga
usedev usbhid usbmouse dvb_usb_dib0700 dib7000p dib7000m dib0070
dvb_usb dib3000mc dib8000 dibx000_common dvb_core usb_storage radeon
ttm snd
tihdmi drm_kms_helper ata_generic drm snd_hda_codec_via firmware_class
firewire_ohci i2c_piix4 i2c_algo_bit firewire_core crc_itu_t psmouse p
_hda_intel snd_hda_codec rtc_cmos snd_pcm rtc_core ehci_hcd uhci_hcd
ohci1394 ohci_hcd cfbcopyarea atkbd snd_timer atl1e snd usbcore pcspkr
s
0_pnp soundcore evdev 8250 cfbimgblt floppy ieee1394 i2c_core
processor rtc_lib thermal pata_atiixp serial_core snd_page_alloc
cfbfillrect bu
_sys asus_atk0110 nls_base sg hwmon unix ext4 jbd2 crc16 dm_mod raid1
md_mod sd_mod ahci libata scsi_mod fbcon tileblit crc32 font bitblit
so
Pid: 12643, comm: vdr Tainted: P        W  2.6.32-rc6-00572-gb419148 #23
Call Trace:
 [<ffffffff8121c0cf>] ? 0xffffffff8121c0cf
 [<ffffffff8121c0cf>] ? 0xffffffff8121c0cf
 [<ffffffff81044424>] ? 0xffffffff81044424
 [<ffffffff8105a790>] ? 0xffffffff8105a790
 [<ffffffff8121c0cf>] ? 0xffffffff8121c0cf
 [<ffffffff8121ca56>] ? 0xffffffff8121ca56
 [<ffffffff811e1d90>] ? 0xffffffff811e1d90
7000p dib7000m dib0070 dvb_usb dib3000mc dib8000 dibx000_common
dvb_core usb_storage radeon ttm snd_hda_codec_atihdmi drm_kms_helper
ata_generic drm snd_hda_codec_via firmware_class firewire_ohci
i2c_piix4 i2c_algo_bit firewire_core crc_itu_t psmouse pata_acpi
snd_hda_intel snd_hda_codec rtc_cmos snd_pcm rtc_core ehci_hcd
uhci_hcd ohci1394 ohci_hcd cfbcopyarea atkbd snd_timer atl1e snd
usbcore pcspkr serio_raw 8250_pnp soundcore evdev 8250 cfbimgblt
floppy ieee1394 i2c_core processor rtc_lib thermal pata_atiixp
serial_core snd_page_alloc cfbfillrect button thermal_sys asus_atk0110
nls_base sg hwmon unix ext4 jbd2 crc16 dm_mod raid1 md_mod sd_mod ahci
libata scsi_mod fbcon tileblit crc32 font bitblit softcursor fb
Pid: 12643, comm: vdr Tainted: P        W  2.6.32-rc6-00572-gb419148 #23
Call Trace:
 [<ffffffff8121c0cf>] ? 0xffffffff8121c0cf
 [<ffffffff8121c0cf>] ? 0xffffffff8121c0cf
 [<ffffffff81044424>] ? 0xffffffff81044424
 [<ffffffff8105a790>] ? 0xffffffff8105a790
 [<ffffffff8121c0cf>] ? 0xffffffff8121c0cf
 [<ffffffff8121ca56>] ? 0xffffffff8121ca56
 [<ffffffff811e1d90>] ? 0xffffffff811e1d90
 [<ffffffff811dec62>] ? 0xffffffff811dec62
 [<ffffffff810c72db>] ? 0xffffffff810c72db
 [<ffffffff8105a790>] ? 0xffffffff8105a790
 [<ffffffff8103ddba>] ? 0xffffffff8103ddba
 [<ffffffff81264184>] ? 0xffffffff81264184
 [<ffffffff81062059>] ? 0xffffffff81062059
 [<ffffffff810c808e>] ? 0xffffffff810c808e
 [<ffffffff810c81a3>] ? 0xffffffff810c81a3
 [<ffffffff8100b2eb>] ? 0xffffffff8100b2eb
---[ end trace d816ed2b263fe304 ]---
recvmsg bug: copied 2AFC272F seq 30B09D30
------------[ cut here ]------------
WARNING: at net/ipv4/tcp.c:1186 0xffffffff8121c0cf()
Hardware name: System Product Name
Modules linked in: tun bitrev kvm_amd kvm option usbserial ipv6
snd_seq_dummy snd_seq_oss snd_seq_midi_event snd_seq snd_seq_device
snd_pcm_oss snd_mixer_oss libafs(P) af_packet bridge stp llc btrfs
zlib_deflate cryptomgr aead pcompress crypto_blkcipher crc32c
libcrc32c crypto_hash crypto_algapi mt2060 mousedev usbhid usbmouse
dvb_usb_dib0700 dib7000p dib7000m dib0070 dvb_usb dib3000mc dib8000
dibx000_common dvb_core usb_storage radeon ttm snd_hda_codec_atihdmi
drm_kms_helper ata_generic drm snd_hda_codec_via firmware_class
firewire_ohci i2c_piix4 i2c_algo_bit firewire_core crc_itu_t psmouse
pata_acpi snd_hda_intel snd_hda_codec rtc_cmos snd_pcm rtc_core
ehci_hcd uhci_hcd ohci1394 ohci_hcd cfbcopyarea atkbd snd_timer atl1e
snd usbcore pcspkr serio_raw 8250_pnp soundcore evdev 8250 cfbimgblt
floppy ieee1394 i2c_core processor rtc_lib thermal pata_atiixp
serial_core snd_page_alloc cfbfillrect button thermal_sys asus_atk0110
nls_base sg hwmon unix ext4 jbd2 crc16 dm_mod raid1 md_mod sd_mod ahci
libata scsi_mod fbcon tileblit crc32 font bitblit softcursor fb
Pid: 12643, comm: vdr Tainted: P        W  2.6.32-rc6-00572-gb419148 #23
Call Trace:
 [<ffffffff8121c0cf>] ? 0xffffffff8121c0cf
 [<ffffffff8121c0cf>] ? 0xffffffff8121c0cf
 [<ffffffff81044424>] ? 0xffffffff81044424
 [<ffffffff810d8700>] ? 0xffffffff810d8700
 [<ffffffff8121c0cf>] ? 0xffffffff8121c0cf
 [<ffffffff8121ca56>] ? 0xffffffff8121ca56
 [<ffffffff811e1d90>] ? 0xffffffff811e1d90
 [<ffffffff811dec62>] ? 0xffffffff811dec62
 [<ffffffff810c72db>] ? 0xffffffff810c72db
 [<ffffffff8105a790>] ? 0xffffffff8105a790
 [<ffffffff8103ddba>] ? 0xffffffff8103ddba
 [<ffffffff81264184>] ? 0xffffffff81264184
 [<ffffffff81062059>] ? 0xffffffff81062059
 [<ffffffff810c808e>] ? 0xffffffff810c808e
 [<ffffffff810c81a3>] ? 0xffffffff810c81a3
 [<ffffffff8100b2eb>] ? 0xffffffff8100b2eb
---[ end trace d816ed2b263fe305 ]---




2.6.32-rc6-00572-gb419148 #23 SMP Tue Nov 3 23:02:32 EET 2009 x86_
64 AMD Phenom(tm) II X3 705e Processor AuthenticAMD GNU/Linux

Gnu C                  4.3.4
Gnu make               3.81
binutils               2.18
util-linux             /usr/src/linux-2.6/scripts/ver_linux: line 23:
fdformat: command n
ot found
mount                  support
module-init-tools      found
Linux C Library        2.9
Dynamic linker (ldd)   2.9
Procps                 3.2.8
Kbd                    1.13
Sh-utils               7.5
Modules Loaded         tun bitrev kvm_amd kvm option usbserial ipv6
snd_seq_dummy snd_seq
_oss snd_seq_midi_event snd_seq snd_seq_device snd_pcm_oss
snd_mixer_oss libafs af_packet
 bridge stp llc btrfs zlib_deflate cryptomgr aead pcompress
crypto_blkcipher crc32c libcr
c32c crypto_hash crypto_algapi mt2060 mousedev usbhid usbmouse
dvb_usb_dib0700 dib7000p d
ib7000m dib0070 dvb_usb dib3000mc dib8000 dibx000_common dvb_core
usb_storage radeon ttm
snd_hda_codec_atihdmi drm_kms_helper ata_generic drm snd_hda_codec_via
firmware_class fir
ewire_ohci i2c_piix4 i2c_algo_bit firewire_core crc_itu_t psmouse
pata_acpi snd_hda_intel
 snd_hda_codec rtc_cmos snd_pcm rtc_core ehci_hcd uhci_hcd ohci1394
ohci_hcd cfbcopyarea
atkbd snd_timer atl1e snd usbcore pcspkr serio_raw 8250_pnp soundcore
evdev 8250 cfbimgbl
t floppy ieee1394 i2c_core processor rtc_lib thermal pata_atiixp
serial_core snd_page_all
oc cfbfillrect button thermal_sys asus_atk0110 nls_base sg hwmon unix
ext4 jbd2 crc16 dm_
mod raid1 md_mod sd_mod ahci libata scsi_mod fbcon tileblit crc32 font
bitblit softcursor
 fb

^ permalink raw reply

* Re: [announce] new rt2800 drivers for Ralink wireless & project tree
From: John W. Linville @ 2009-11-04 15:15 UTC (permalink / raw)
  To: Gertjan van Wingerde
  Cc: Bartlomiej Zolnierkiewicz, linux-wireless, linux-kernel, netdev,
	Ivo van Doorn, Randy Dunlap, Luis Correia, Ingo Molnar,
	Johannes Berg, Jarek Poplawski, Pekka Enberg, David Miller
In-Reply-To: <4AF09A15.3060504@gmail.com>

On Tue, Nov 03, 2009 at 10:01:09PM +0100, Gertjan van Wingerde wrote:

> However, it is good to see that you have put effort in providing a patch series
> for these issues.

Yes, indeed.  Thanks to Bart for making patches available!

> Now, since I believe that it is better to work with people, rather than against
> them, would it be possible to post this patch series somewhere as a set of 
> separate patches, so that they can be reviewed as such?

I must echo this request.

Thanks!

John
-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply

* [RFC,PATCH] mutex: mutex_is_owner() helper
From: Eric Dumazet @ 2009-11-04 15:25 UTC (permalink / raw)
  To: David S. Miller, Ingo Molnar; +Cc: Linux Netdev List, linux kernel

mutex_is_locked() is called most of the time to check if mutex is locked by current
thread. But it's a lazy check, because mutex might be locked by another thread.

Adds a new mutex_is_owned_by() helper, that can check ownership if CONFIG_SMP or
CONFIG_DEBUG_MUTEXES are set.

Returns are 
 0 if mutex is unlocked.
 1 if locked
-1 if not locked by designated thread.

Last return value is possible only if CONFIG_SMP=y or CONFIG_DEBUG_MUTEXES=y

Example of use :

int rtnl_is_locked(void)
{
	return mutex_is_locked(&rtnl_mutex);
}
->
int rtnl_is_locked(void)
{
	return mutex_is_owned_by(&rtnl_mutex, current_thread_info()) == 1;
}

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
 Documentation/mutex-design.txt |    1 +
 include/linux/mutex.h          |   20 ++++++++++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/Documentation/mutex-design.txt b/Documentation/mutex-design.txt
index aa60d1f..521607c 100644
--- a/Documentation/mutex-design.txt
+++ b/Documentation/mutex-design.txt
@@ -133,6 +133,7 @@ the APIs of 'struct mutex' have been streamlined:
  int  mutex_trylock(struct mutex *lock);
  void mutex_unlock(struct mutex *lock);
  int  mutex_is_locked(struct mutex *lock);
+ int  mutex_is_owned_by(struct mutex *lock, struct thread_info *ti);
  void mutex_lock_nested(struct mutex *lock, unsigned int subclass);
  int  mutex_lock_interruptible_nested(struct mutex *lock,
                                       unsigned int subclass);
diff --git a/include/linux/mutex.h b/include/linux/mutex.h
index 878cab4..95a8c5b 100644
--- a/include/linux/mutex.h
+++ b/include/linux/mutex.h
@@ -118,6 +118,26 @@ static inline int mutex_is_locked(struct mutex *lock)
 	return atomic_read(&lock->count) != 1;
 }
 
+/**
+ * mutex_is_owned_by - check mutex ownership
+ * @lock: the mutex to be queried
+ * @ti: thread_info pointer
+ *
+ * Returns: 0 if mutex is unlocked.
+ *          1 if locked
+ *         -1 if not locked by designated thread.
+ */
+static inline int mutex_is_owned_by(struct mutex *lock, struct thread_info *ti)
+{
+	if (atomic_read(&lock->count) == 1)
+		return 0;
+#if defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_SMP)
+	if (lock->owner != ti)
+		return -1;
+#endif
+	return 1;
+}
+
 /*
  * See kernel/mutex.c for detailed documentation of these APIs.
  * Also see Documentation/mutex-design.txt.

^ permalink raw reply related

* [PATCH 00/25] mlx4: multi-function framework and Ethernet sriov.
From: Yevgeny Petrilin @ 2009-11-04 15:30 UTC (permalink / raw)
  To: rdreier-FYB4Gu1CFyUAvxtiuMwx3w
  Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
	liranl-VPRAkNaXOzVS1MOuV/RT9w, tziporet-VPRAkNaXOzVS1MOuV/RT9w,
	yevgenyp-VPRAkNaXOzVS1MOuV/RT9w


In ConnectX, nearly all device resources can be associated with any function.
Once allocated, these resources can be manipulated exclusively by their associated
functions in the same manner as in the single-function case.

The device continues to use a single HCA Command Register (HCR), which is owned by the pf.
Thus, the pf is given the role of allocating resources to vfs, and controlling shared
resource (such as ports).

A dedicated HW communication channel is used to transfer resource allocation and
modification requests from vfs to the pf, and events from the pf to the vfs.
Consequently, no hypervisor-specific services are required for pf-vf communication.

This patch set sets the ground for multi-function operation and enables Ethernet interfaces on vfs.

Signed-off-by: Liran Liss <liranl-VPRAkNaXOzVS1MOuV/RT9w@public.gmane.org>
Signed-off-by: Yevgeny Petrilin <yevgenyp-VPRAkNaXOzVS1MOuV/RT9w@public.gmane.org>

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH 01/25] mlx4_core: identify function as pf or vf
From: Yevgeny Petrilin @ 2009-11-04 15:30 UTC (permalink / raw)
  To: rdreier-FYB4Gu1CFyUAvxtiuMwx3w
  Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
	liranl-VPRAkNaXOzVS1MOuV/RT9w, tziporet-VPRAkNaXOzVS1MOuV/RT9w,
	yevgenyp-VPRAkNaXOzVS1MOuV/RT9w


Signed-off-by: Liran Liss <liranl-VPRAkNaXOzVS1MOuV/RT9w@public.gmane.org>
---
 include/linux/mlx4/device.h |   19 +++++++++++++++++++
 1 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index ce7cc6c..f35703d 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -42,6 +42,9 @@
 enum {
 	MLX4_FLAG_MSI_X		= 1 << 0,
 	MLX4_FLAG_OLD_PORT_CMDS	= 1 << 1,
+	MLX4_FLAG_MASTER	= 1 << 2,
+	MLX4_FLAG_SLAVE		= 1 << 3,
+	MLX4_FLAG_SRIOV		= 1 << 4,
 };
 
 enum {
@@ -375,6 +378,7 @@ struct mlx4_av {
 struct mlx4_dev {
 	struct pci_dev	       *pdev;
 	unsigned long		flags;
+	unsigned long		num_slaves;
 	struct mlx4_caps	caps;
 	struct radix_tree_root	qp_table_tree;
 	u32			rev_id;
@@ -400,6 +404,21 @@ struct mlx4_init_port_param {
 		if (((type) == MLX4_PORT_TYPE_IB ? (dev)->caps.port_mask : \
 		     ~(dev)->caps.port_mask) & 1 << ((port) - 1))
 
+static inline int mlx4_is_slave(struct mlx4_dev *dev)
+{
+	return dev->flags & MLX4_FLAG_SLAVE;
+}
+
+static inline int mlx4_is_master(struct mlx4_dev *dev)
+{
+	return dev->flags & MLX4_FLAG_MASTER;
+}
+
+static inline int mlx4_is_mfunc(struct mlx4_dev *dev)
+{
+	return dev->flags & (MLX4_FLAG_MASTER | MLX4_FLAG_SLAVE);
+}
+
 int mlx4_buf_alloc(struct mlx4_dev *dev, int size, int max_direct,
 		   struct mlx4_buf *buf);
 void mlx4_buf_free(struct mlx4_dev *dev, int size, struct mlx4_buf *buf);
-- 
1.6.1.3




--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH 02/25] mlx4_core: add support for arbitrary bitmap sizes
From: Yevgeny Petrilin @ 2009-11-04 15:30 UTC (permalink / raw)
  To: rdreier-FYB4Gu1CFyUAvxtiuMwx3w
  Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
	liranl-VPRAkNaXOzVS1MOuV/RT9w, tziporet-VPRAkNaXOzVS1MOuV/RT9w,
	yevgenyp-VPRAkNaXOzVS1MOuV/RT9w


Signed-off-by: Liran Liss <liranl-VPRAkNaXOzVS1MOuV/RT9w@public.gmane.org>
---
 drivers/net/mlx4/alloc.c |   10 ++++++++++
 drivers/net/mlx4/mlx4.h  |    2 ++
 2 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/drivers/net/mlx4/alloc.c b/drivers/net/mlx4/alloc.c
index ad95d5f..bc68cc3 100644
--- a/drivers/net/mlx4/alloc.c
+++ b/drivers/net/mlx4/alloc.c
@@ -177,6 +177,16 @@ int mlx4_bitmap_init(struct mlx4_bitmap *bitmap, u32 num, u32 mask,
 	return 0;
 }
 
+/* Like bitmap_init, but doesn't require 'num' to be a power of 2 or
+ * a non-trivial mask */
+int mlx4_bitmap_init_no_mask(struct mlx4_bitmap *bitmap, u32 num,
+			     u32 reserved_bot, u32 reserved_top)
+{
+	u32 num_rounded = roundup_pow_of_two(num);
+	return mlx4_bitmap_init(bitmap, num_rounded, num_rounded - 1,
+				reserved_bot, num_rounded - num + reserved_top);
+}
+
 void mlx4_bitmap_cleanup(struct mlx4_bitmap *bitmap)
 {
 	kfree(bitmap->table);
diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h
index bc72d6e..5836c94 100644
--- a/drivers/net/mlx4/mlx4.h
+++ b/drivers/net/mlx4/mlx4.h
@@ -330,6 +330,8 @@ u32 mlx4_bitmap_alloc_range(struct mlx4_bitmap *bitmap, int cnt, int align);
 void mlx4_bitmap_free_range(struct mlx4_bitmap *bitmap, u32 obj, int cnt);
 int mlx4_bitmap_init(struct mlx4_bitmap *bitmap, u32 num, u32 mask,
 		     u32 reserved_bot, u32 resetrved_top);
+int mlx4_bitmap_init_no_mask(struct mlx4_bitmap *bitmap, u32 num,
+			     u32 reserved_bot, u32 reserved_top);
 void mlx4_bitmap_cleanup(struct mlx4_bitmap *bitmap);
 
 int mlx4_reset(struct mlx4_dev *dev);
-- 
1.6.1.3




--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH 03/25] mlx4_core: add multi-function communication channel
From: Yevgeny Petrilin @ 2009-11-04 15:30 UTC (permalink / raw)
  To: rdreier-FYB4Gu1CFyUAvxtiuMwx3w
  Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
	liranl-VPRAkNaXOzVS1MOuV/RT9w, tziporet-VPRAkNaXOzVS1MOuV/RT9w,
	yevgenyp-VPRAkNaXOzVS1MOuV/RT9w

The communication channel consists of 2 registers per vf (a slave function)
that are shared with the pf (the master function), as well as a new command for
inter-function memory copying (only exposed to the master).

The communication channel is used to establish a Virtual HCA Command Register
(vHCR) in each slave function, which allows it to pass FW commands to the master
function for execution.
The slave also uses the vHCR to pull slave-specific events from the master.

Signed-off-by: Liran Liss <liranl-VPRAkNaXOzVS1MOuV/RT9w@public.gmane.org>
---
 drivers/net/mlx4/cmd.c      |  483 ++++++++++++++++++++++++++++++++++++++++++-
 drivers/net/mlx4/eq.c       |   67 ++++++
 drivers/net/mlx4/fw.c       |    8 +
 drivers/net/mlx4/mlx4.h     |   72 +++++++-
 include/linux/mlx4/cmd.h    |    7 +-
 include/linux/mlx4/device.h |    3 +-
 6 files changed, 627 insertions(+), 13 deletions(-)

diff --git a/drivers/net/mlx4/cmd.c b/drivers/net/mlx4/cmd.c
index 65ec77d..03dfdfc 100644
--- a/drivers/net/mlx4/cmd.c
+++ b/drivers/net/mlx4/cmd.c
@@ -41,6 +41,7 @@
 #include <asm/io.h>
 
 #include "mlx4.h"
+#include "en_port.h"
 
 #define CMD_POLL_TOKEN 0xffff
 
@@ -140,6 +141,46 @@ static int mlx4_status_to_errno(u8 status)
 	return trans_table[status];
 }
 
+static int comm_pending(struct mlx4_dev *dev)
+{
+	struct mlx4_priv *priv = mlx4_priv(dev);
+	__be32 status = readl(&priv->mfunc.comm->slave_read);
+
+	return (be32_to_cpu(status) >> 30) != priv->cmd.comm_toggle;
+}
+
+int mlx4_comm_cmd(struct mlx4_dev *dev, u8 cmd, u16 param, unsigned long timeout)
+{
+	struct mlx4_priv *priv = mlx4_priv(dev);
+	unsigned long end;
+	u32 val;
+
+	/* First, verify that the master reports correct status */
+	if (comm_pending(dev)) {
+		mlx4_warn(dev, "Communication channel is not idle\n");
+		return -EAGAIN;
+	}
+
+	/* Write command */
+	if (cmd == MLX4_COMM_CMD_RESET)
+		priv->cmd.comm_toggle = 0;
+	else if (++priv->cmd.comm_toggle > 2)
+		priv->cmd.comm_toggle = 1;
+	val = param | (cmd << 16) | (priv->cmd.comm_toggle << 30);
+	__raw_writel((__force u32) cpu_to_be32(val), &priv->mfunc.comm->slave_write);
+	wmb();
+
+	end = msecs_to_jiffies(timeout) + jiffies;
+	while (comm_pending(dev) && time_before(jiffies, end))
+		cond_resched();
+
+	if (comm_pending(dev)) {
+		mlx4_warn(dev, "Communication channel timed out\n");
+		return -ETIMEDOUT;
+	}
+	return 0;
+}
+
 static int cmd_pending(struct mlx4_dev *dev)
 {
 	u32 status = readl(mlx4_priv(dev)->cmd.hcr + HCR_STATUS_OFFSET);
@@ -207,6 +248,33 @@ out:
 	return ret;
 }
 
+static int mlx4_slave_cmd_poll(struct mlx4_dev *dev, u64 in_param, u64 *out_param,
+			 int out_is_imm, u32 in_modifier, u8 op_modifier,
+			 u16 op, unsigned long timeout)
+{
+	struct mlx4_priv *priv = mlx4_priv(dev);
+	struct mlx4_vhcr *vhcr = priv->mfunc.vhcr;
+	int ret;
+
+	down(&priv->cmd.poll_sem);
+	vhcr->in_param = in_param;
+	vhcr->out_param = out_param ? *out_param : 0;
+	vhcr->in_modifier = in_modifier;
+	vhcr->timeout = timeout;
+	vhcr->op = op;
+	vhcr->token = CMD_POLL_TOKEN;
+	vhcr->op_modifier = op_modifier;
+	vhcr->errno = 0;
+	ret = mlx4_comm_cmd(dev, MLX4_COMM_CMD_VHCR_POST, 0, MLX4_COMM_TIME + timeout);
+	if (!ret) {
+		if (out_is_imm)
+			*out_param = vhcr->out_param;
+		ret = vhcr->errno;
+	}
+	up(&priv->cmd.poll_sem);
+	return ret;
+}
+
 static int mlx4_cmd_poll(struct mlx4_dev *dev, u64 in_param, u64 *out_param,
 			 int out_is_imm, u32 in_modifier, u8 op_modifier,
 			 u16 op, unsigned long timeout)
@@ -314,12 +382,380 @@ int __mlx4_cmd(struct mlx4_dev *dev, u64 in_param, u64 *out_param,
 	if (mlx4_priv(dev)->cmd.use_events)
 		return mlx4_cmd_wait(dev, in_param, out_param, out_is_imm,
 				     in_modifier, op_modifier, op, timeout);
+
+	if (mlx4_is_slave(dev))
+		return mlx4_slave_cmd_poll(dev, in_param, out_param, out_is_imm,
+				     in_modifier, op_modifier, op, timeout);
 	else
 		return mlx4_cmd_poll(dev, in_param, out_param, out_is_imm,
 				     in_modifier, op_modifier, op, timeout);
 }
 EXPORT_SYMBOL_GPL(__mlx4_cmd);
 
+int mlx4_ACCESS_MEM(struct mlx4_dev *dev, u64 master_addr, int slave, u64 slave_addr,
+							   int size, int is_read)
+{
+	u64 in_param;
+	u64 out_param;
+	int slave_id = slave + 1; /* index 0 is reserved for the master */
+
+	if ((slave_addr & 0xfff) | (master_addr & 0xfff) |
+	    (slave_id & ~0x7f) | (size & 0xff)) {
+		mlx4_err(dev, "Bad access mem params - slave_addr:0x%llx "
+			      "master_addr:0x%llx slave_id:%d size:%d\n",
+			      slave_addr, master_addr, slave_id, size);
+		return -EINVAL;
+	}
+
+	if (is_read) {
+		in_param = (u64) slave_id | slave_addr;
+		out_param = master_addr;
+	} else {
+		in_param = master_addr;
+		out_param = (u64) slave_id | slave_addr;
+	}
+
+	return mlx4_cmd_imm(dev, in_param, &out_param, size, 0,
+					   MLX4_CMD_ACCESS_MEM,
+					   MLX4_CMD_TIME_CLASS_A);
+}
+
+static struct mlx4_cmd_info {
+	u8 opcode;
+	u8 has_inbox;
+	u8 has_outbox;
+	u8 out_is_imm;
+	int (*verify)(struct mlx4_dev *dev, int slave, struct mlx4_vhcr *vhcr,
+					    struct mlx4_cmd_mailbox *inbox);
+	int (*wrapper)(struct mlx4_dev *dev, int slave, struct mlx4_vhcr *vhcr,
+					     struct mlx4_cmd_mailbox *inbox,
+					     struct mlx4_cmd_mailbox *outbox);
+} cmd_info[] = {
+	{MLX4_CMD_QUERY_FW,        0, 1, 0, NULL, NULL},
+	{MLX4_CMD_QUERY_ADAPTER,   0, 1, 0, NULL, NULL},
+
+	{MLX4_CMD_SW2HW_EQ,        1, 0, 0, NULL, NULL}, /* need verifier */
+	{MLX4_CMD_NOP,             0, 0, 0, NULL, NULL},
+
+	{MLX4_CMD_SW2HW_MPT,       1, 0, 0, NULL, NULL}, /* need verifier */
+	{MLX4_CMD_QUERY_MPT,       0, 1, 0, NULL, NULL}, /* need verifier */
+	{MLX4_CMD_HW2SW_MPT,       0, 0, 0, NULL, NULL}, /* need verifier */
+	{MLX4_CMD_READ_MTT,        0, 1, 0, NULL, NULL}, /* need verifier */
+	{MLX4_CMD_SYNC_TPT,        1, 0, 0, NULL, NULL}, /* need verifier */
+
+	{MLX4_CMD_HW2SW_EQ,        0, 0, 0, NULL, NULL}, /* need verifier */
+	{MLX4_CMD_QUERY_EQ,        0, 1, 0, NULL, NULL}, /* need verifier */
+	{MLX4_CMD_SW2HW_CQ,        1, 0, 0, NULL, NULL}, /* need verifier */
+	{MLX4_CMD_HW2SW_CQ,        0, 0, 0, NULL, NULL}, /* need verifier */
+	{MLX4_CMD_QUERY_CQ,        0, 1, 0, NULL, NULL}, /* need verifier */
+	{MLX4_CMD_MODIFY_CQ,       1, 0, 1, NULL, NULL}, /* need verifier */
+	{MLX4_CMD_SW2HW_SRQ,       1, 0, 0, NULL, NULL}, /* need verifier */
+	{MLX4_CMD_HW2SW_SRQ,       0, 0, 0, NULL, NULL}, /* need verifier */
+	{MLX4_CMD_QUERY_SRQ,       0, 1, 0, NULL, NULL}, /* need verifier */
+	{MLX4_CMD_ARM_SRQ,         0, 0, 0, NULL, NULL}, /* need verifier */
+	{MLX4_CMD_RST2INIT_QP,     1, 0, 0, NULL, NULL}, /* need verifier */
+	{MLX4_CMD_INIT2RTR_QP,     1, 0, 0, NULL, NULL}, /* need verifier */
+	{MLX4_CMD_RTR2RTS_QP,      1, 0, 0, NULL, NULL}, /* need verifier */
+	{MLX4_CMD_RTS2RTS_QP,      1, 0, 0, NULL, NULL}, /* need verifier */
+	{MLX4_CMD_SQERR2RTS_QP,    1, 0, 0, NULL, NULL}, /* need verifier */
+	{MLX4_CMD_2ERR_QP,         0, 0, 0, NULL, NULL}, /* need verifier */
+	{MLX4_CMD_RTS2SQD_QP,      0, 0, 0, NULL, NULL}, /* need verifier */
+	{MLX4_CMD_SQD2SQD_QP,      1, 0, 0, NULL, NULL}, /* need verifier */
+	{MLX4_CMD_SQD2RTS_QP,      1, 0, 0, NULL, NULL}, /* need verifier */
+	{MLX4_CMD_2RST_QP,         0, 0, 0, NULL, NULL}, /* need verifier */
+	{MLX4_CMD_QUERY_QP,        0, 1, 0, NULL, NULL}, /* need verifier */
+	{MLX4_CMD_INIT2INIT_QP,    1, 0, 0, NULL, NULL}, /* need verifier */
+	{MLX4_CMD_SUSPEND_QP,      0, 0, 0, NULL, NULL}, /* need verifier */
+	{MLX4_CMD_UNSUSPEND_QP,    0, 0, 0, NULL, NULL}, /* need verifier */
+	{MLX4_CMD_MAD_IFC,         1, 1, 0, NULL, NULL}, /* need verifier */
+
+	/* Native multicast commands are not available for guests */
+	{MLX4_CMD_DIAG_RPRT,       0, 1, 0, NULL, NULL}, /* need verifier */
+
+	/* Ethernet specific commands */
+	{MLX4_CMD_SET_VLAN_FLTR,   1, 0, 0, NULL, NULL}, /* need wrapper */
+	{MLX4_CMD_SET_MCAST_FLTR,  0, 0, 0, NULL, NULL}, /* need wrapper */
+	{MLX4_CMD_DUMP_ETH_STATS,  0, 1, 0, NULL, NULL}, /* need wrapper */
+};
+
+static int mlx4_master_process_vhcr(struct mlx4_dev *dev, int slave)
+{
+	struct mlx4_priv *priv = mlx4_priv(dev);
+	struct mlx4_cmd_info *cmd = NULL;
+	struct mlx4_vhcr *vhcr = priv->mfunc.vhcr;
+	struct mlx4_cmd_mailbox *inbox = NULL;
+	struct mlx4_cmd_mailbox *outbox = NULL;
+	u64 in_param;
+	u64 out_param;
+	int ret;
+	int i;
+
+	/* DMA in the vHCR */
+	ret = mlx4_ACCESS_MEM(dev, priv->mfunc.vhcr_dma, slave,
+			      priv->mfunc.master.slave_state[slave].vhcr_dma,
+			      ALIGN(sizeof(struct mlx4_vhcr),
+				    MLX4_ACCESS_MEM_ALIGN), 1);
+	if (ret) {
+		mlx4_err(dev, "Failed reading vhcr\n");
+		return ret;
+	}
+
+	/* Lookup command */
+	for (i = 0; i < ARRAY_SIZE(cmd_info); ++i) {
+		if (vhcr->op == cmd_info[i].opcode) {
+			cmd = &cmd_info[i];
+			break;
+		}
+	}
+	if (!cmd) {
+		mlx4_err(dev, "Unknown command:0x%x accepted from slave:%d\n",
+							      vhcr->op, slave);
+		vhcr->errno = -EINVAL;
+		goto out_status;
+	}
+
+	/* Read inbox */
+	if (cmd->has_inbox) {
+		inbox = mlx4_alloc_cmd_mailbox(dev);
+		if (IS_ERR(inbox)) {
+			ret = PTR_ERR(inbox);
+			inbox = NULL;
+			goto out;
+		}
+
+		/* FIXME: add mailbox size per-command */
+		ret = mlx4_ACCESS_MEM(dev, inbox->dma, slave,
+				      vhcr->in_param,
+				      MLX4_MAILBOX_SIZE, 1);
+		if (ret) {
+			mlx4_err(dev, "Failed reading inbox\n");
+			goto out;
+		}
+	}
+
+	/* Apply permission and bound checks if applicable */
+	if (cmd->verify && cmd->verify(dev, slave, vhcr, inbox)) {
+		mlx4_warn(dev, "Command:0x%x failed protection checks\n", vhcr->op);
+		vhcr->errno = -EPERM;
+		goto out_status;
+	}
+
+	/* Allocate outbox */
+	if (cmd->has_outbox) {
+		outbox = mlx4_alloc_cmd_mailbox(dev);
+		if (IS_ERR(outbox)) {
+			ret = PTR_ERR(outbox);
+			outbox = NULL;
+			goto out;
+		}
+	}
+
+	/* Execute the command! */
+	if (cmd->wrapper)
+		vhcr->errno = cmd->wrapper(dev, slave, vhcr, inbox, outbox);
+	else {
+		in_param = cmd->has_inbox ? (u64) inbox->dma : vhcr->in_param;
+		out_param = cmd->has_outbox ? (u64) outbox->dma : vhcr->out_param;
+		vhcr->errno = __mlx4_cmd(dev, in_param, &out_param,
+							cmd->out_is_imm,
+							vhcr->in_modifier,
+							vhcr->op_modifier,
+							vhcr->op,
+							vhcr->timeout);
+		if (cmd->out_is_imm)
+			vhcr->out_param = out_param;
+	}
+
+	/* Write outbox if command completed successfully */
+	if (cmd->has_outbox && !vhcr->errno) {
+		ret = mlx4_ACCESS_MEM(dev, outbox->dma, slave,
+				      vhcr->out_param,
+				      MLX4_MAILBOX_SIZE, 0);
+		if (ret) {
+			mlx4_err(dev, "Failed writing outbox\n");
+			goto out;
+		}
+	}
+
+out_status:
+	/* DMA back vhcr result */
+	ret = mlx4_ACCESS_MEM(dev, priv->mfunc.vhcr_dma, slave,
+			      priv->mfunc.master.slave_state[slave].vhcr_dma,
+			      ALIGN(sizeof(struct mlx4_vhcr),
+				    MLX4_ACCESS_MEM_ALIGN), 0);
+	if (ret)
+		mlx4_err(dev, "Failed writing vhcr result\n");
+
+	if (vhcr->errno)
+		mlx4_warn(dev, "vhcr command:0x%x slave:%d failed with error:%d\n",
+							vhcr->op, slave, vhcr->errno);
+	/* Fall through... */
+
+out:
+	mlx4_free_cmd_mailbox(dev, inbox);
+	mlx4_free_cmd_mailbox(dev, outbox);
+	return ret;
+}
+
+static void mlx4_master_do_cmd(struct mlx4_dev *dev, int slave, u8 cmd, u16 param, u8 toggle)
+{
+	struct mlx4_priv *priv = mlx4_priv(dev);
+	struct mlx4_slave_state *slave_state = priv->mfunc.master.slave_state;
+	u8 toggle_next;
+	u32 reply;
+
+	if (cmd == MLX4_COMM_CMD_RESET) {
+		mlx4_warn(dev, "Received reset from slave:%d\n", slave);
+		goto reset_slave;
+	}
+
+	/* Increment next toggle token */
+	toggle_next = slave_state[slave].comm_toggle + 1;
+	if (toggle_next > 2)
+		toggle_next = 1;
+	if (toggle != toggle_next) {
+		mlx4_warn(dev, "Incorrect token:%d from slave:%d expected:%d\n",
+							toggle, toggle_next, slave);
+		goto reset_slave;
+	}
+
+	switch (cmd) {
+	case MLX4_COMM_CMD_VHCR0:
+		if (slave_state[slave].last_cmd != MLX4_COMM_CMD_RESET)
+			goto reset_slave;
+		slave_state[slave].vhcr_dma = ((u64) param) << 48;
+		break;
+	case MLX4_COMM_CMD_VHCR1:
+		if (slave_state[slave].last_cmd != MLX4_COMM_CMD_VHCR0)
+			goto reset_slave;
+		slave_state[slave].vhcr_dma |= ((u64) param) << 32;
+		break;
+	case MLX4_COMM_CMD_VHCR2:
+		if (slave_state[slave].last_cmd != MLX4_COMM_CMD_VHCR1)
+			goto reset_slave;
+		slave_state[slave].vhcr_dma |= ((u64) param) << 16;
+		break;
+	case MLX4_COMM_CMD_VHCR_EN:
+		if (slave_state[slave].last_cmd != MLX4_COMM_CMD_VHCR2)
+			goto reset_slave;
+		slave_state[slave].vhcr_dma |= param;
+		break;
+	case MLX4_COMM_CMD_VHCR_POST:
+		if ((slave_state[slave].last_cmd != MLX4_COMM_CMD_VHCR_EN) &&
+		    (slave_state[slave].last_cmd != MLX4_COMM_CMD_VHCR_POST))
+			goto reset_slave;
+		if (mlx4_master_process_vhcr(dev, slave)) {
+			mlx4_err(dev, "Failed processing vhcr for slave:%d, reseting slave.\n", slave);
+			goto reset_slave;
+		}
+		break;
+	default:
+		mlx4_warn(dev, "Bad comm cmd:%d from slave:%d\n", cmd, slave);
+		goto reset_slave;
+	}
+
+	slave_state[slave].last_cmd = cmd;
+	slave_state[slave].comm_toggle = toggle_next;
+	reply = (u32) toggle_next << 30;
+	__raw_writel((__force u32) cpu_to_be32(reply),
+		     &priv->mfunc.comm[slave].slave_read);
+	wmb();
+	return;
+
+reset_slave:
+	/* FIXME: cleanup any slave resources */
+	slave_state[slave].last_cmd = MLX4_COMM_CMD_RESET;
+	slave_state[slave].comm_toggle = 0;
+	__raw_writel((__force u32) 0, &priv->mfunc.comm[slave].slave_write);
+	__raw_writel((__force u32) 0, &priv->mfunc.comm[slave].slave_read);
+	wmb();
+}
+
+/* master command processing */
+static void mlx4_master_poll_comm(struct work_struct *work)
+{
+	struct delayed_work *delay = container_of(work, struct delayed_work, work);
+	struct mlx4_mfunc *mfunc = container_of(delay, struct mlx4_mfunc, comm_work);
+	struct mlx4_priv *priv = container_of(mfunc, struct mlx4_priv, mfunc);
+	struct mlx4_dev *dev = &priv->dev;
+	u32 comm_cmd;
+	int polled = 0;
+	int i;
+
+	/* Give each slave a chance for one command */
+	for (i = 0; i < dev->num_slaves; i++) {
+		comm_cmd = be32_to_cpu(readl(&priv->mfunc.comm[i].slave_write));
+		if (comm_cmd >> 30 != priv->mfunc.master.slave_state[i].comm_toggle) {
+			mlx4_master_do_cmd(dev, i, comm_cmd >> 16, comm_cmd, comm_cmd >> 30);
+			polled = 1;
+		}
+	}
+	queue_delayed_work(priv->mfunc.comm_wq, &priv->mfunc.comm_work,
+						polled ? HZ / 1000 : HZ / 10);
+}
+
+int mlx4_multi_func_init(struct mlx4_dev *dev)
+{
+	struct mlx4_priv *priv = mlx4_priv(dev);
+	int i;
+
+	priv->mfunc.vhcr = dma_alloc_coherent(&(dev->pdev->dev), PAGE_SIZE,
+					    &priv->mfunc.vhcr_dma,
+					    GFP_KERNEL);
+	if (!priv->mfunc.vhcr) {
+		mlx4_err(dev, "Couldn't allocate vhcr.\n");
+		return -ENOMEM;
+	}
+
+	if (mlx4_is_master(dev))
+		priv->mfunc.comm = ioremap(pci_resource_start(dev->pdev,
+							    priv->fw.comm_bar) +
+								priv->fw.comm_base,
+							    MLX4_COMM_PAGESIZE);
+	else
+		priv->mfunc.comm = ioremap(pci_resource_start(dev->pdev, 0) +
+							    MLX4_SLAVE_COMM_BASE,
+							    MLX4_COMM_PAGESIZE);
+	if (!priv->mfunc.comm) {
+		mlx4_err(dev, "Couldn't map communication vector.");
+		goto err_vhcr;
+	}
+
+	if (mlx4_is_master(dev)) {
+		priv->mfunc.master.slave_state = kzalloc(dev->num_slaves *
+					   sizeof(struct mlx4_slave_state),
+					   GFP_KERNEL);
+		if (!priv->mfunc.master.slave_state)
+			goto err_comm;
+
+		for (i = 0; i < dev->num_slaves; ++i)
+			priv->mfunc.master.slave_state[i].last_cmd = MLX4_COMM_CMD_RESET;
+
+		INIT_DELAYED_WORK(&priv->mfunc.comm_work, mlx4_master_poll_comm);
+		priv->mfunc.comm_wq = create_singlethread_workqueue("mlx4_comm");
+		if (!priv->mfunc.comm_wq) {
+			kfree(priv->mfunc.master.slave_state);
+			goto err_comm;
+		}
+	} else {
+		priv->cmd.comm_toggle = 0;
+		INIT_DELAYED_WORK(&priv->mfunc.comm_work, mlx4_slave_async_eq_poll);
+		priv->mfunc.comm_wq = create_singlethread_workqueue("mlx4_event");
+		if (!priv->mfunc.comm_wq)
+			goto err_comm;
+	}
+	return 0;
+
+err_comm:
+	iounmap(priv->mfunc.comm);
+err_vhcr:
+	dma_free_coherent(&(dev->pdev->dev), PAGE_SIZE,
+					     priv->mfunc.vhcr,
+					     priv->mfunc.vhcr_dma);
+	priv->mfunc.vhcr = NULL;
+	return -ENOMEM;
+}
+
 int mlx4_cmd_init(struct mlx4_dev *dev)
 {
 	struct mlx4_priv *priv = mlx4_priv(dev);
@@ -329,22 +765,47 @@ int mlx4_cmd_init(struct mlx4_dev *dev)
 	priv->cmd.use_events = 0;
 	priv->cmd.toggle     = 1;
 
-	priv->cmd.hcr = ioremap(pci_resource_start(dev->pdev, 0) + MLX4_HCR_BASE,
-				MLX4_HCR_SIZE);
-	if (!priv->cmd.hcr) {
-		mlx4_err(dev, "Couldn't map command register.");
-		return -ENOMEM;
+	priv->cmd.hcr = priv->mfunc.vhcr = NULL;
+
+	if (!mlx4_is_slave(dev)) {
+		priv->cmd.hcr = ioremap(pci_resource_start(dev->pdev, 0) +
+					((dev->flags & MLX4_FLAG_SRIOV) ?
+						MLX4_HCR_SRIOV_BASE :
+						MLX4_HCR_BASE),
+					MLX4_HCR_SIZE);
+		if (!priv->cmd.hcr) {
+			mlx4_err(dev, "Couldn't map command register.");
+			return -ENOMEM;
+		}
 	}
 
 	priv->cmd.pool = pci_pool_create("mlx4_cmd", dev->pdev,
 					 MLX4_MAILBOX_SIZE,
 					 MLX4_MAILBOX_SIZE, 0);
-	if (!priv->cmd.pool) {
-		iounmap(priv->cmd.hcr);
-		return -ENOMEM;
-	}
+	if (!priv->cmd.pool)
+		goto err_hcr;
 
 	return 0;
+
+err_hcr:
+	if (!mlx4_is_slave(dev))
+		iounmap(priv->cmd.hcr);
+	return -ENOMEM;
+}
+
+void mlx4_multi_func_cleanup(struct mlx4_dev *dev)
+{
+	struct mlx4_priv *priv = mlx4_priv(dev);
+
+	if (priv->mfunc.vhcr) {
+		destroy_workqueue(priv->mfunc.comm_wq);
+		kfree(priv->mfunc.master.slave_state);
+		iounmap(priv->mfunc.comm);
+		dma_free_coherent(&(dev->pdev->dev), PAGE_SIZE,
+						     priv->mfunc.vhcr,
+						     priv->mfunc.vhcr_dma);
+		priv->mfunc.vhcr = NULL;
+	}
 }
 
 void mlx4_cmd_cleanup(struct mlx4_dev *dev)
@@ -352,7 +813,9 @@ void mlx4_cmd_cleanup(struct mlx4_dev *dev)
 	struct mlx4_priv *priv = mlx4_priv(dev);
 
 	pci_pool_destroy(priv->cmd.pool);
-	iounmap(priv->cmd.hcr);
+
+	if (!mlx4_is_slave(dev))
+		iounmap(priv->cmd.hcr);
 }
 
 /*
diff --git a/drivers/net/mlx4/eq.c b/drivers/net/mlx4/eq.c
index bffb799..70c16d4 100644
--- a/drivers/net/mlx4/eq.c
+++ b/drivers/net/mlx4/eq.c
@@ -160,6 +160,22 @@ static struct mlx4_eqe *next_eqe_sw(struct mlx4_eq *eq)
 	return !!(eqe->owner & 0x80) ^ !!(eq->cons_index & eq->nent) ? NULL : eqe;
 }
 
+static int mlx4_GET_EVENT(struct mlx4_dev *dev, struct mlx4_slave_eqe *eqe)
+{
+	int ret;
+	u64 out_param;
+
+	ret = mlx4_cmd_imm(dev, 0, &out_param, 0, 0, MLX4_CMD_GET_EVENT,
+						     MLX4_CMD_TIME_CLASS_A);
+	if (!ret) {
+		eqe->type = out_param & 0xff;
+		eqe->port = (out_param >> 8) & 0xff;
+		eqe->param = out_param >> 32;
+	} else
+		mlx4_err(dev, "Failed retrieving event\n");
+	return ret;
+}
+
 static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq)
 {
 	struct mlx4_eqe *eqe;
@@ -262,6 +278,57 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq)
 	return eqes_found;
 }
 
+void mlx4_slave_async_eq_poll(struct work_struct *work)
+{
+	struct delayed_work *delay = container_of(work, struct delayed_work, work);
+	struct mlx4_mfunc *mfunc = container_of(delay, struct mlx4_mfunc, comm_work);
+	struct mlx4_priv *priv = container_of(mfunc, struct mlx4_priv, mfunc);
+	struct mlx4_dev *dev = &priv->dev;
+	struct mlx4_slave_eqe eqe;
+	int ret;
+	int i;
+
+	for (i = 0; i < MLX4_MFUNC_MAX_EQES; i++) {
+		ret = mlx4_GET_EVENT(dev, &eqe);
+		if (ret || eqe.type == MLX4_EVENT_TYPE_NONE)
+			break;
+
+		switch (eqe.type) {
+		case MLX4_EVENT_TYPE_PATH_MIG:
+		case MLX4_EVENT_TYPE_COMM_EST:
+		case MLX4_EVENT_TYPE_SQ_DRAINED:
+		case MLX4_EVENT_TYPE_SRQ_QP_LAST_WQE:
+		case MLX4_EVENT_TYPE_WQ_CATAS_ERROR:
+		case MLX4_EVENT_TYPE_PATH_MIG_FAILED:
+		case MLX4_EVENT_TYPE_WQ_INVAL_REQ_ERROR:
+		case MLX4_EVENT_TYPE_WQ_ACCESS_ERROR:
+			mlx4_qp_event(dev, eqe.param, eqe.type);
+			break;
+
+		case MLX4_EVENT_TYPE_SRQ_LIMIT:
+		case MLX4_EVENT_TYPE_SRQ_CATAS_ERROR:
+			mlx4_srq_event(dev, eqe.param, eqe.type);
+			break;
+
+		case MLX4_EVENT_TYPE_PORT_CHANGE:
+			mlx4_dispatch_event(dev, eqe.param, eqe.port);
+			break;
+
+		case MLX4_EVENT_TYPE_CQ_ERROR:
+			mlx4_cq_event(dev, eqe.param, eqe.type);
+			break;
+
+		case MLX4_EVENT_TYPE_EQ_OVERFLOW:
+			mlx4_warn(dev, "slave async EQ overrun\n");
+			break;
+
+		default:
+			mlx4_warn(dev, "Unhandled event:%02x\n", eqe.type);
+		}
+	}
+	queue_delayed_work(priv->mfunc.comm_wq, &priv->mfunc.comm_work, HZ);
+}
+
 static irqreturn_t mlx4_interrupt(int irq, void *dev_ptr)
 {
 	struct mlx4_dev *dev = dev_ptr;
diff --git a/drivers/net/mlx4/fw.c b/drivers/net/mlx4/fw.c
index 3c16602..4ca8060 100644
--- a/drivers/net/mlx4/fw.c
+++ b/drivers/net/mlx4/fw.c
@@ -554,6 +554,9 @@ int mlx4_QUERY_FW(struct mlx4_dev *dev)
 #define QUERY_FW_CLR_INT_BASE_OFFSET   0x20
 #define QUERY_FW_CLR_INT_BAR_OFFSET    0x28
 
+#define QUERY_FW_COMM_BASE_OFFSET      0x40
+#define QUERY_FW_COMM_BAR_OFFSET       0x48
+
 	mailbox = mlx4_alloc_cmd_mailbox(dev);
 	if (IS_ERR(mailbox))
 		return PTR_ERR(mailbox);
@@ -614,6 +617,11 @@ int mlx4_QUERY_FW(struct mlx4_dev *dev)
 	MLX4_GET(fw->clr_int_bar,  outbox, QUERY_FW_CLR_INT_BAR_OFFSET);
 	fw->clr_int_bar = (fw->clr_int_bar >> 6) * 2;
 
+	MLX4_GET(fw->comm_base, outbox, QUERY_FW_COMM_BASE_OFFSET);
+	MLX4_GET(fw->comm_bar,  outbox, QUERY_FW_COMM_BAR_OFFSET);
+	fw->comm_bar = (fw->comm_bar >> 6) * 2;
+	mlx4_dbg(dev, "Communication vector bar:%d offset:0x%llx\n", fw->comm_bar,
+								     fw->comm_base);
 	mlx4_dbg(dev, "FW size %d KB\n", fw->fw_pages >> 2);
 
 	/*
diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h
index 5836c94..88b4ff4 100644
--- a/drivers/net/mlx4/mlx4.h
+++ b/drivers/net/mlx4/mlx4.h
@@ -53,8 +53,11 @@
 
 enum {
 	MLX4_HCR_BASE		= 0x80680,
+	MLX4_HCR_SRIOV_BASE	= 0x4080680, /* good for SRIOV FW ony */
 	MLX4_HCR_SIZE		= 0x0001c,
-	MLX4_CLR_INT_SIZE	= 0x00008
+	MLX4_CLR_INT_SIZE	= 0x00008,
+	MLX4_SLAVE_COMM_BASE	= 0x0,
+	MLX4_COMM_PAGESIZE	= 0x1000
 };
 
 enum {
@@ -80,6 +83,21 @@ enum {
 	MLX4_NUM_CMPTS		= MLX4_CMPT_NUM_TYPE << MLX4_CMPT_SHIFT
 };
 
+#define MLX4_COMM_TIME		10000
+enum {
+	MLX4_COMM_CMD_RESET,
+	MLX4_COMM_CMD_VHCR0,
+	MLX4_COMM_CMD_VHCR1,
+	MLX4_COMM_CMD_VHCR2,
+	MLX4_COMM_CMD_VHCR_EN,
+	MLX4_COMM_CMD_VHCR_POST
+};
+
+enum {
+	MLX4_MFUNC_MAX_EQES     = 8,
+	MLX4_MFUNC_EQE_MASK     = (MLX4_MFUNC_MAX_EQES - 1)
+};
+
 #ifdef CONFIG_MLX4_DEBUG
 extern int mlx4_debug_level;
 #else /* CONFIG_MLX4_DEBUG */
@@ -154,12 +172,56 @@ struct mlx4_profile {
 struct mlx4_fw {
 	u64			clr_int_base;
 	u64			catas_offset;
+	u64			comm_base;
 	struct mlx4_icm	       *fw_icm;
 	struct mlx4_icm	       *aux_icm;
 	u32			catas_size;
 	u16			fw_pages;
 	u8			clr_int_bar;
 	u8			catas_bar;
+	u8			comm_bar;
+};
+
+struct mlx4_comm {
+	u32			slave_write;
+	u32			slave_read;
+};
+
+struct mlx4_slave_eqe {
+	u8 type;
+	u8 port;
+	u32 param;
+};
+
+struct mlx4_slave_state {
+	u8 comm_toggle;
+	u8 last_cmd;
+	dma_addr_t vhcr_dma;
+};
+
+struct mlx4_mfunc_master_ctx {
+	struct mlx4_slave_state *slave_state;
+};
+
+struct mlx4_vhcr {
+	u64 in_param;
+	u64 out_param;
+	u32 in_modifier;
+	u32 timeout;
+	u16 op;
+	u16 token;
+	u8 op_modifier;
+	int errno;
+};
+
+struct mlx4_mfunc {
+	struct mlx4_comm __iomem       *comm;
+	struct workqueue_struct	       *comm_wq;
+	struct delayed_work	        comm_work;
+	struct mlx4_vhcr	       *vhcr;
+	dma_addr_t			vhcr_dma;
+
+	struct mlx4_mfunc_master_ctx	master;
 };
 
 struct mlx4_cmd {
@@ -175,6 +237,7 @@ struct mlx4_cmd {
 	u16			token_mask;
 	u8			use_events;
 	u8			toggle;
+	u8			comm_toggle;
 };
 
 struct mlx4_uar_table {
@@ -294,6 +357,7 @@ struct mlx4_priv {
 
 	struct mlx4_fw		fw;
 	struct mlx4_cmd		cmd;
+	struct mlx4_mfunc	mfunc;
 
 	struct mlx4_bitmap	pd_bitmap;
 	struct mlx4_uar_table	uar_table;
@@ -372,13 +436,19 @@ u64 mlx4_make_profile(struct mlx4_dev *dev,
 		      struct mlx4_profile *request,
 		      struct mlx4_dev_cap *dev_cap,
 		      struct mlx4_init_hca_param *init_hca);
+void mlx4_slave_async_eq_poll(struct work_struct *work);
 
 int mlx4_cmd_init(struct mlx4_dev *dev);
 void mlx4_cmd_cleanup(struct mlx4_dev *dev);
+int mlx4_multi_func_init(struct mlx4_dev *dev);
+void mlx4_multi_func_cleanup(struct mlx4_dev *dev);
 void mlx4_cmd_event(struct mlx4_dev *dev, u16 token, u8 status, u64 out_param);
 int mlx4_cmd_use_events(struct mlx4_dev *dev);
 void mlx4_cmd_use_polling(struct mlx4_dev *dev);
 
+int mlx4_comm_cmd(struct mlx4_dev *dev, u8 cmd, u16 param, unsigned long timeout);
+
+
 void mlx4_cq_completion(struct mlx4_dev *dev, u32 cqn);
 void mlx4_cq_event(struct mlx4_dev *dev, u32 cqn, int event_type);
 
diff --git a/include/linux/mlx4/cmd.h b/include/linux/mlx4/cmd.h
index 0f82293..dda1762 100644
--- a/include/linux/mlx4/cmd.h
+++ b/include/linux/mlx4/cmd.h
@@ -117,6 +117,10 @@ enum {
 	/* miscellaneous commands */
 	MLX4_CMD_DIAG_RPRT	 = 0x30,
 	MLX4_CMD_NOP		 = 0x31,
+	MLX4_CMD_ACCESS_MEM	 = 0x2e,
+
+	/* virtual commands */
+	MLX4_CMD_GET_EVENT	 = 0x52,
 
 	/* debug commands */
 	MLX4_CMD_QUERY_DEBUG_MSG = 0x2a,
@@ -130,7 +134,8 @@ enum {
 };
 
 enum {
-	MLX4_MAILBOX_SIZE	=  4096
+	MLX4_MAILBOX_SIZE	= 4096,
+	MLX4_ACCESS_MEM_ALIGN	= 256,
 };
 
 enum {
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index f35703d..9735f40 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -98,7 +98,8 @@ enum mlx4_event {
 	MLX4_EVENT_TYPE_PORT_CHANGE	   = 0x09,
 	MLX4_EVENT_TYPE_EQ_OVERFLOW	   = 0x0f,
 	MLX4_EVENT_TYPE_ECC_DETECT	   = 0x0e,
-	MLX4_EVENT_TYPE_CMD		   = 0x0a
+	MLX4_EVENT_TYPE_CMD		   = 0x0a,
+	MLX4_EVENT_TYPE_NONE		   = 0xff,
 };
 
 enum {
-- 
1.6.1.3




--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH 06/25] mlx4_core: slave multicast support
From: Yevgeny Petrilin @ 2009-11-04 15:30 UTC (permalink / raw)
  To: rdreier-FYB4Gu1CFyUAvxtiuMwx3w
  Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
	liranl-VPRAkNaXOzVS1MOuV/RT9w, tziporet-VPRAkNaXOzVS1MOuV/RT9w,
	yevgenyp-VPRAkNaXOzVS1MOuV/RT9w

Multicast table processing requires multiple related commands.
To keep things simple, low-level multicast handling is done only by the master;
a new virtual command is added to allow slaves to attach/detach QPs to mulitcast
groups at a higher abstraction level.

Signed-off-by: Liran Liss <liranl-VPRAkNaXOzVS1MOuV/RT9w@public.gmane.org>
---
 drivers/net/mlx4/cmd.c   |    1 +
 drivers/net/mlx4/mcg.c   |   45 +++++++++++++++++++++++++++++++++++++++++++++
 drivers/net/mlx4/mlx4.h  |    4 ++++
 include/linux/mlx4/cmd.h |    1 +
 4 files changed, 51 insertions(+), 0 deletions(-)

diff --git a/drivers/net/mlx4/cmd.c b/drivers/net/mlx4/cmd.c
index b1701d2..dd23aba 100644
--- a/drivers/net/mlx4/cmd.c
+++ b/drivers/net/mlx4/cmd.c
@@ -565,6 +565,7 @@ static struct mlx4_cmd_info {
 	{MLX4_CMD_MAD_IFC,         1, 1, 0, NULL, NULL}, /* need verifier */
 
 	/* Native multicast commands are not available for guests */
+	{MLX4_CMD_MCAST_ATTACH,	   1, 0, 0, NULL, mlx4_MCAST_wrapper},
 	{MLX4_CMD_DIAG_RPRT,       0, 1, 0, NULL, NULL}, /* need verifier */
 
 	/* Ethernet specific commands */
diff --git a/drivers/net/mlx4/mcg.c b/drivers/net/mlx4/mcg.c
index 5ccbce9..96f09ed 100644
--- a/drivers/net/mlx4/mcg.c
+++ b/drivers/net/mlx4/mcg.c
@@ -146,6 +146,45 @@ static int find_mgm(struct mlx4_dev *dev,
 	return err;
 }
 
+int mlx4_MCAST_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_vhcr *vhcr,
+						     struct mlx4_cmd_mailbox *inbox,
+						     struct mlx4_cmd_mailbox *outbox)
+{
+	struct mlx4_qp qp; /* dummy for calling attach/detach */
+
+	qp.qpn = vhcr->in_modifier & 0xffffff;
+	if (vhcr->op_modifier)
+		return mlx4_multicast_attach(dev, &qp, inbox->buf, vhcr->in_modifier >> 31);
+	else
+		return mlx4_multicast_detach(dev, &qp, inbox->buf);
+}
+
+static int mlx4_MCAST(struct mlx4_dev *dev, struct mlx4_qp *qp,
+					    u8 gid[16], u8 attach,
+					    u8 block_loopback)
+{
+	struct mlx4_cmd_mailbox *mailbox;
+	int err;
+	int qpn;
+
+	if (!mlx4_is_slave(dev))
+		return -EBADF;
+
+	mailbox = mlx4_alloc_cmd_mailbox(dev);
+	if (IS_ERR(mailbox))
+		return PTR_ERR(mailbox);
+
+	memcpy(mailbox->buf, gid, 16);
+	qpn = qp->qpn;
+	if (attach && block_loopback)
+		qpn |= (1 << 31);
+
+	err = mlx4_cmd(dev, mailbox->dma, qpn, attach, MLX4_CMD_MCAST_ATTACH,
+						       MLX4_CMD_TIME_CLASS_A);
+	mlx4_free_cmd_mailbox(dev, mailbox);
+	return err;
+}
+
 int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
 			  int block_mcast_loopback)
 {
@@ -159,6 +198,9 @@ int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
 	int i;
 	int err;
 
+	if (mlx4_is_slave(dev))
+		return mlx4_MCAST(dev, qp, gid, 1, block_mcast_loopback);
+
 	mailbox = mlx4_alloc_cmd_mailbox(dev);
 	if (IS_ERR(mailbox))
 		return PTR_ERR(mailbox);
@@ -254,6 +296,9 @@ int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16])
 	int i, loc;
 	int err;
 
+	if (mlx4_is_slave(dev))
+		return mlx4_MCAST(dev, qp, gid, 0, 0);
+
 	mailbox = mlx4_alloc_cmd_mailbox(dev);
 	if (IS_ERR(mailbox))
 		return PTR_ERR(mailbox);
diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h
index 91f1215..fafa293 100644
--- a/drivers/net/mlx4/mlx4.h
+++ b/drivers/net/mlx4/mlx4.h
@@ -507,4 +507,8 @@ void mlx4_init_vlan_table(struct mlx4_dev *dev, struct mlx4_vlan_table *table);
 int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port);
 int mlx4_get_port_ib_caps(struct mlx4_dev *dev, u8 port, __be32 *caps);
 
+int mlx4_MCAST_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_vhcr *vhcr,
+						     struct mlx4_cmd_mailbox *inbox,
+						     struct mlx4_cmd_mailbox *outbox);
+
 #endif /* MLX4_H */
diff --git a/include/linux/mlx4/cmd.h b/include/linux/mlx4/cmd.h
index dceb93f..8265843 100644
--- a/include/linux/mlx4/cmd.h
+++ b/include/linux/mlx4/cmd.h
@@ -123,6 +123,7 @@ enum {
 	MLX4_CMD_ALLOC_RES	 = 0x50,
 	MLX4_CMD_FREE_RES	 = 0x51,
 	MLX4_CMD_GET_EVENT	 = 0x52,
+	MLX4_CMD_MCAST_ATTACH	 = 0x54,
 
 	/* debug commands */
 	MLX4_CMD_QUERY_DEBUG_MSG = 0x2a,
-- 
1.6.1.3




--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH 07/25] mlx4_core: add port para-virtualization
From: Yevgeny Petrilin @ 2009-11-04 15:30 UTC (permalink / raw)
  To: rdreier-FYB4Gu1CFyUAvxtiuMwx3w
  Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
	liranl-VPRAkNaXOzVS1MOuV/RT9w, tziporet-VPRAkNaXOzVS1MOuV/RT9w,
	yevgenyp-VPRAkNaXOzVS1MOuV/RT9w

Ports are a shared resource among functions, so special behavior is needed here:
- Bring up ports if at least one function has done so.
- Bring down ports if all functions have done so.
- Aggregate IB port capabilities

Signed-off-by: Liran Liss <liranl-VPRAkNaXOzVS1MOuV/RT9w@public.gmane.org>
---
 drivers/net/mlx4/cmd.c  |    5 +++
 drivers/net/mlx4/fw.c   |   55 ++++++++++++++++++++++++++++++++++
 drivers/net/mlx4/mlx4.h |   16 ++++++++++
 drivers/net/mlx4/port.c |   76 +++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 152 insertions(+), 0 deletions(-)

diff --git a/drivers/net/mlx4/cmd.c b/drivers/net/mlx4/cmd.c
index dd23aba..d2646d1 100644
--- a/drivers/net/mlx4/cmd.c
+++ b/drivers/net/mlx4/cmd.c
@@ -526,6 +526,11 @@ static struct mlx4_cmd_info {
 	{MLX4_CMD_QUERY_FW,        0, 1, 0, NULL, NULL},
 	{MLX4_CMD_QUERY_ADAPTER,   0, 1, 0, NULL, NULL},
 
+	{MLX4_CMD_INIT_PORT,       0, 0, 0, NULL, mlx4_INIT_PORT_wrapper},
+	{MLX4_CMD_CLOSE_PORT,      0, 0, 0, NULL, mlx4_CLOSE_PORT_wrapper},
+	{MLX4_CMD_QUERY_PORT,      0, 1, 0, NULL, mlx4_QUERY_PORT_wrapper},
+	{MLX4_CMD_SET_PORT,        1, 0, 0, NULL, mlx4_SET_PORT_wrapper},
+
 	{MLX4_CMD_SW2HW_EQ,        1, 0, 0, NULL, NULL}, /* need verifier */
 	{MLX4_CMD_NOP,             0, 0, 0, NULL, NULL},
 	{MLX4_CMD_ALLOC_RES,	   0, 0, 1, NULL, mlx4_RESOURCE_wrapper},
diff --git a/drivers/net/mlx4/fw.c b/drivers/net/mlx4/fw.c
index 4ca8060..a63f84a 100644
--- a/drivers/net/mlx4/fw.c
+++ b/drivers/net/mlx4/fw.c
@@ -135,6 +135,14 @@ int mlx4_MOD_STAT_CFG(struct mlx4_dev *dev, struct mlx4_mod_stat_cfg *cfg)
 	return err;
 }
 
+int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_vhcr *vhcr,
+							  struct mlx4_cmd_mailbox *inbox,
+							  struct mlx4_cmd_mailbox *outbox)
+{
+	return mlx4_cmd_box(dev, 0, outbox->dma, vhcr->in_modifier, 0, MLX4_CMD_QUERY_PORT,
+					   MLX4_CMD_TIME_CLASS_B);
+}
+
 int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
 {
 	struct mlx4_cmd_mailbox *mailbox;
@@ -809,6 +817,29 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param)
 	return err;
 }
 
+int mlx4_INIT_PORT_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_vhcr *vhcr,
+							 struct mlx4_cmd_mailbox *inbox,
+							 struct mlx4_cmd_mailbox *outbox)
+{
+	struct mlx4_priv *priv = mlx4_priv(dev);
+	int port;
+	int err;
+
+	port = vhcr->in_modifier;
+	if (priv->mfunc.master.slave_state[slave].init_port_mask & (1 << port))
+		return 0;
+
+	/* Enable port only if it was previously disabled */
+	if (!priv->mfunc.master.init_port_ref[port]) {
+		err = mlx4_INIT_PORT(dev, port);
+		if (err)
+			return err;
+	}
+	++priv->mfunc.master.init_port_ref[port];
+	priv->mfunc.master.slave_state[slave].init_port_mask |= (1 << port);
+	return 0;
+}
+
 int mlx4_INIT_PORT(struct mlx4_dev *dev, int port)
 {
 	struct mlx4_cmd_mailbox *mailbox;
@@ -863,6 +894,30 @@ int mlx4_INIT_PORT(struct mlx4_dev *dev, int port)
 }
 EXPORT_SYMBOL_GPL(mlx4_INIT_PORT);
 
+int mlx4_CLOSE_PORT_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_vhcr *vhcr,
+							  struct mlx4_cmd_mailbox *inbox,
+							  struct mlx4_cmd_mailbox *outbox)
+{
+	struct mlx4_priv *priv = mlx4_priv(dev);
+	int port;
+	int err;
+
+	port = vhcr->in_modifier;
+	if (!(priv->mfunc.master.slave_state[slave].init_port_mask & (1 << port)))
+		return 0;
+
+	/* CX1: master doesn't have interfaces - close port if this slave is
+	 * the last user */
+	if (priv->mfunc.master.init_port_ref[port] == 1) {
+		err = mlx4_CLOSE_PORT(dev, port);
+		if (err)
+			return err;
+	}
+	--priv->mfunc.master.init_port_ref[port];
+	priv->mfunc.master.slave_state[slave].init_port_mask &= ~(1 << port);
+	return 0;
+}
+
 int mlx4_CLOSE_PORT(struct mlx4_dev *dev, int port)
 {
 	return mlx4_cmd(dev, 0, port, 0, MLX4_CMD_CLOSE_PORT, 1000);
diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h
index fafa293..8a7a041 100644
--- a/drivers/net/mlx4/mlx4.h
+++ b/drivers/net/mlx4/mlx4.h
@@ -46,6 +46,7 @@
 #include <linux/mlx4/driver.h>
 #include <linux/mlx4/doorbell.h>
 #include <linux/mlx4/cmd.h>
+#include <rdma/ib_verbs.h>
 
 #define DRV_NAME	"mlx4_core"
 #define PFX		DRV_NAME ": "
@@ -212,11 +213,14 @@ struct mlx4_slave_eqe {
 struct mlx4_slave_state {
 	u8 comm_toggle;
 	u8 last_cmd;
+	u8 init_port_mask;
 	dma_addr_t vhcr_dma;
+	__be32 ib_cap_mask[MLX4_MAX_PORTS + 1];
 };
 
 struct mlx4_mfunc_master_ctx {
 	struct mlx4_slave_state *slave_state;
+	int			init_port_ref[MLX4_MAX_PORTS + 1];
 };
 
 struct mlx4_vhcr {
@@ -505,6 +509,18 @@ void mlx4_init_mac_table(struct mlx4_dev *dev, struct mlx4_mac_table *table);
 void mlx4_init_vlan_table(struct mlx4_dev *dev, struct mlx4_vlan_table *table);
 
 int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port);
+int mlx4_SET_PORT_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_vhcr *vhcr,
+							struct mlx4_cmd_mailbox *inbox,
+							struct mlx4_cmd_mailbox *outbox);
+int mlx4_INIT_PORT_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_vhcr *vhcr,
+							 struct mlx4_cmd_mailbox *inbox,
+							 struct mlx4_cmd_mailbox *outbox);
+int mlx4_CLOSE_PORT_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_vhcr *vhcr,
+							  struct mlx4_cmd_mailbox *inbox,
+							  struct mlx4_cmd_mailbox *outbox);
+int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_vhcr *vhcr,
+							  struct mlx4_cmd_mailbox *inbox,
+							  struct mlx4_cmd_mailbox *outbox);
 int mlx4_get_port_ib_caps(struct mlx4_dev *dev, u8 port, __be32 *caps);
 
 int mlx4_MCAST_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_vhcr *vhcr,
diff --git a/drivers/net/mlx4/port.c b/drivers/net/mlx4/port.c
index 606aa58..67f0751 100644
--- a/drivers/net/mlx4/port.c
+++ b/drivers/net/mlx4/port.c
@@ -294,6 +294,82 @@ int mlx4_get_port_ib_caps(struct mlx4_dev *dev, u8 port, __be32 *caps)
 	return err;
 }
 
+int mlx4_SET_PORT_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_vhcr *vhcr,
+							struct mlx4_cmd_mailbox *inbox,
+							struct mlx4_cmd_mailbox *outbox)
+{
+	struct mlx4_priv *priv = mlx4_priv(dev);
+	int reset_qkey_viols;
+	int port;
+	int is_eth;
+	int err;
+	int i;
+	__be32 agg_cap_mask;
+	__be32 slave_cap_mask;
+	__be32 new_cap_mask;
+
+	port = vhcr->in_modifier & 0xff;
+	is_eth = vhcr->op_modifier;
+
+	/* For Ethernet, we currently support only slave0.
+	 * TODO: add multi-vf support */
+	if (is_eth) {
+		if (slave)
+			return -EINVAL;
+		return mlx4_cmd(dev, inbox->dma, vhcr->in_modifier,
+						 vhcr->op_modifier,
+						 MLX4_CMD_SET_PORT,
+						 MLX4_CMD_TIME_CLASS_B);
+	}
+
+	/* For IB, we only consider:
+	 * - The capability mask, which is set to the aggregate of all slave frunction
+	 *   capabilities
+	 * - The QKey violatin counter - reset according to each request.
+	 */
+
+	if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) {
+		reset_qkey_viols = (*(u8 *) inbox->buf) & 0x40;
+		new_cap_mask = ((__be32 *) inbox->buf)[2];
+	} else {
+		reset_qkey_viols = ((u8 *) inbox->buf)[3] & 0x1;
+		new_cap_mask = ((__be32 *) inbox->buf)[1];
+	}
+
+	/* CX1: only slave0 has access to qp0 */
+	if (slave && (new_cap_mask & cpu_to_be32(IB_PORT_SM))) {
+		mlx4_warn(dev, "denying sm port capability for slave:%d\n", slave);
+		return -EINVAL;
+	}
+
+	agg_cap_mask = 0;
+	slave_cap_mask = priv->mfunc.master.slave_state[slave].ib_cap_mask[port];
+	priv->mfunc.master.slave_state[slave].ib_cap_mask[port] = new_cap_mask;
+	for (i = 0; i < dev->num_slaves; i++)
+		agg_cap_mask |= priv->mfunc.master.slave_state[slave].ib_cap_mask[port];
+
+#if 0
+	mlx4_warn(dev, "old_slave_cap:0x%x slave_cap:0x%x cap:0x%x qkey_reset:%d\n",
+			slave_cap_mask, priv->mfunc.master.slave_state[slave].ib_cap_mask[port],
+			agg_cap_mask, reset_qkey_viols);
+#endif
+
+	memset(inbox->buf, 0, 256);
+	if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) {
+		*(u8 *) inbox->buf	   = !!reset_qkey_viols << 6;
+		((__be32 *) inbox->buf)[2] = agg_cap_mask;
+	} else {
+		((u8 *) inbox->buf)[3]     = !!reset_qkey_viols;
+		((__be32 *) inbox->buf)[1] = agg_cap_mask;
+	}
+
+	err = mlx4_cmd(dev, inbox->dma, port, is_eth, MLX4_CMD_SET_PORT,
+		       MLX4_CMD_TIME_CLASS_B);
+	if (err)
+		priv->mfunc.master.slave_state[slave].ib_cap_mask[port] = slave_cap_mask;
+	return err;
+}
+
 int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port)
 {
 	struct mlx4_cmd_mailbox *mailbox;
-- 
1.6.1.3




--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related


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