* Re: [GIT PULL net-next-2.6] IPVS
From: Patrick McHardy @ 2011-06-16 15:05 UTC (permalink / raw)
To: Simon Horman
Cc: lvs-devel, netdev, netfilter-devel, netfilter, Wensong Zhang,
Julian Anastasov, Pablo Neira Ayuso
In-Reply-To: <1308095001-21002-1-git-send-email-horms@verge.net.au>
On 15.06.2011 01:43, Simon Horman wrote:
> Hi Patrick, Hi Pablo,
>
> please consider pulling
> git://git.kernel.org/pub/scm/linux/kernel/git/horms/ipvs-next-2.6.git
> master
>
> It includes four clean-ups by Hans
> and an enhancement of the FTP helper by Julian.
>
> I have based the pull request on next-2.6 as
> nf-next-2.6 seems to be a little old. Please let me
> know if a different base would suit you better.
>
> Hans Schillstrom (4):
> IPVS remove unused var from migration to netns
> IPVS: rename of netns init and cleanup functions.
> IPVS: labels at pos 0
> IPVS: remove unused init and cleanup functions.
>
> Julian Anastasov (1):
> ipvs: support more FTP PASV responses
>
Pulled, thanks Simon.
^ permalink raw reply
* Re: [RFC] Moving files around in drivers/net
From: Jon Mason @ 2011-06-16 15:03 UTC (permalink / raw)
To: Joe Perches
Cc: Jeff Kirsher, netdev, David Miller, Paul Gortmaker,
Jan Engelhardt, Andrew Gallatin
In-Reply-To: <1308186619.12377.23.camel@Joe-Laptop>
On Wed, Jun 15, 2011 at 8:10 PM, Joe Perches <joe@perches.com> wrote:
> On Wed, 2011-06-15 at 11:38 -0700, Jeff Kirsher wrote:
>> On Wed, Jun 1, 2011 at 13:01, Joe Perches <joe@perches.com> wrote:
>> > On Wed, 2011-06-01 at 12:53 -0700, Jeff Kirsher wrote:
>> >> On Wed, 2011-06-01 at 12:30 -0700, Joe Perches wrote:
>> >> > Does anyone still think moving files around in drivers/net
>> >> > would be sensible and a suitable candidate for inclusion
>> >> > in 3.1?
>> >> > Here's what Jeffrey proposed:
>> >> > http://vger.kernel.org/netconf2010_slides/netconf-jtk.pdf
>> >> > Here's what I proposed before that.
>> >> > http://www.spinics.net/lists/netdev/msg149717.html
>> >> I am over 90% done with the work and have been trying to finish up the
>> >> patches so that I could get them out as an RFC here in the next week.
>> > Excellent, thanks.
>> I thought for sure I would have finished what I have left by last
>> weekend, but I keep getting interrupted. (Blame it on the NHL stanley
>> cup playoffs) :)
>> I have created a git tree on kernel.org with all the work that I have
>> completed so far (see below). This first stage of the move is only
>> taking care of the drivers. The next stage will move the networking
>> core drivers (bridging, bonding, vlan, etc.) into drivers/net/sw.
>> git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-organize
>> I will send out all the patches as an RFC by the end of the week (for sure)
>
> I've put the body of the git log below my comments
> to make it easier to discuss.
>
> Comments:
>
> pktgen in hamachi/yellowfin should be pkteng
>
> I think it might be better if:
>
> Things were more spelled out:
> pkteng should be packetengines
> And things maybe not spelled out
> ixp2000 might just be ixp (what not intel?:)
>
> And maybe drivers/net/ethernet/ should be as
> unpopulated as possible. Maybe create a misc
> directory and throw old unclassifiable junk there.
>
> Lance should be its own directory like 8390.
> I think a2065 and ariadne are lance drivers.
>
> Some manufacturer directories are directly populated
> with multiple drivers, some have subdirectories.
> Should one style be consistently used?
>
> pch_gbe should probably be oki.
>
> Isn't syskonnect now marvell?
>
> stmmac may not be a good name. Maybe stmicro.
>
> enic may not be a good name. Maybe cisco.
>
> mlx4 may be mellanox
>
> sfc may be solarflare
>
> bna may be brocade
>
> cheers, Joe
>
> $ git log --stat -M b7c7deeb4c77538577f0b6a724f10ce8693eb648..
> commit 743b1f134daef72805cb10e74d82dcbb95cd2568
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Tue Jun 14 14:02:57 2011 -0700
>
> hamachi/yellowfin: Move the packet engine drivers
>
> Move the packet engine drivers to drivers/net/ethernet/pktgen/ and
> the necessary Kconfig and Makefile changes.
>
> CC: Donald Becker <becker@scyld.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> drivers/net/Kconfig | 26 ---------------
> drivers/net/Makefile | 2 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/pkteng/Kconfig | 42 +++++++++++++++++++++++++
> drivers/net/ethernet/pkteng/Makefile | 6 +++
> drivers/net/{ => ethernet/pkteng}/hamachi.c | 0
> drivers/net/{ => ethernet/pkteng}/yellowfin.c | 0
> 8 files changed, 50 insertions(+), 28 deletions(-)
>
> commit a7ce0b86340574f90bd24c460c3495ae3e06f5fb
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Tue Jun 14 13:35:31 2011 -0700
>
> ixp2000: Move the Radisys driver
>
> Move the Radisys driver into drivers/net/ethernet/ixp2000/ and
> make the necessary Kconfig and Makefile changes
>
> CC: Lennert Buytenhek <kernel@wantstofly.org>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 2 +-
> drivers/net/Kconfig | 2 --
> drivers/net/Makefile | 1 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/{ => ethernet}/ixp2000/Kconfig | 0
> drivers/net/{ => ethernet}/ixp2000/Makefile | 0
> drivers/net/{ => ethernet}/ixp2000/caleb.c | 0
> drivers/net/{ => ethernet}/ixp2000/caleb.h | 0
> drivers/net/{ => ethernet}/ixp2000/enp2611.c | 0
> drivers/net/{ => ethernet}/ixp2000/ixp2400-msf.c | 0
> drivers/net/{ => ethernet}/ixp2000/ixp2400-msf.h | 0
> drivers/net/{ => ethernet}/ixp2000/ixp2400_rx.uc | 0
> .../net/{ => ethernet}/ixp2000/ixp2400_rx.ucode | 0
> drivers/net/{ => ethernet}/ixp2000/ixp2400_tx.uc | 0
> .../net/{ => ethernet}/ixp2000/ixp2400_tx.ucode | 0
> drivers/net/{ => ethernet}/ixp2000/ixpdev.c | 0
> drivers/net/{ => ethernet}/ixp2000/ixpdev.h | 0
> drivers/net/{ => ethernet}/ixp2000/ixpdev_priv.h | 0
> drivers/net/{ => ethernet}/ixp2000/pm3386.c | 0
> drivers/net/{ => ethernet}/ixp2000/pm3386.h | 0
> 21 files changed, 3 insertions(+), 4 deletions(-)
>
> commit 73091715bc0690f82ef9489f3589ad9b2d747cc0
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Tue Jun 14 12:56:50 2011 -0700
>
> tlan/cpmac: Move the TI drivers
>
> Move the TI drivers to drivers/net/ethernet/ti/ and make the
> necessary Kconfig and Makefile changes.
>
> CC: Samuel Chessman <chessman@tux.org>
> CC: <torben.mathiasen@compaq.com>
> CC: Eugene Konev <ejka@imfi.kspu.ru>
> CC: Florian Fainelli <florian@openwrt.org>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 4 +-
> drivers/net/Kconfig | 25 --------------------
> drivers/net/Makefile | 2 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/ti/Kconfig | 41 +++++++++++++++++++++++++++++++++
> drivers/net/ethernet/ti/Makefile | 6 +++++
> drivers/net/{ => ethernet/ti}/cpmac.c | 0
> drivers/net/{ => ethernet/ti}/tlan.c | 0
> drivers/net/{ => ethernet/ti}/tlan.h | 0
> 10 files changed, 51 insertions(+), 29 deletions(-)
>
> commit 035a452c66dbc0aa7873a12cfe057c74eaf89111
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Mon Jun 13 10:51:34 2011 -0700
>
> s6gmac/tsi108_eth: Move the s6gmac/tsi108_eth drivers
>
> Move the s6gmac/tsi108_eth drivers to drivers/net/ethernet/ and
> make the necessary Kconfig and Makefile changes.
>
> CC: Oskar Schirmer <os@emlix.com>
> CC: Kong Lai <kong.lai@tundra.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> drivers/net/Kconfig | 19 -------------------
> drivers/net/Makefile | 2 --
> drivers/net/ethernet/Kconfig | 21 +++++++++++++++++++++
> drivers/net/ethernet/Makefile | 2 ++
> drivers/net/{ => ethernet}/s6gmac.c | 0
> drivers/net/{ => ethernet}/tsi108_eth.c | 0
> drivers/net/{ => ethernet}/tsi108_eth.h | 0
> 7 files changed, 23 insertions(+), 21 deletions(-)
>
> commit 4f9d3b9af95ced49b9ad9d5fb222f5216bf0adbb
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Mon Jun 13 10:03:01 2011 -0700
>
> a2065/ariadne: Move the a2065/ariadne drivers
>
> Move the a2065/ariadne drivers to drivers/net/ethernet/ and make
> the necessary Kconfig and Makefile changes.
>
> CC: Geert Uytterhoeven <geert@linux-m68k.org>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> drivers/net/Kconfig | 21 ---------------------
> drivers/net/Makefile | 2 --
> drivers/net/ethernet/Kconfig | 23 +++++++++++++++++++++++
> drivers/net/ethernet/Makefile | 2 ++
> drivers/net/{ => ethernet}/a2065.c | 0
> drivers/net/{ => ethernet}/a2065.h | 0
> drivers/net/{ => ethernet}/ariadne.c | 0
> drivers/net/{ => ethernet}/ariadne.h | 0
> 8 files changed, 25 insertions(+), 23 deletions(-)
>
> commit aead66521a701f08e3ae91aec7c9c8863a07a511
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Mon Jun 13 09:43:17 2011 -0700
>
> 82586.c/fec*: Move the Motorola drivers
>
> Move the Motorola drivers into drivers/net/ethernet/motorola/ and
> make the necessary Kconfig and Makefile changes
>
> CC: Dan Malek <dmalek@jlc.net>
> CC: Sylvain Munaut <tnt@246tNt.com>
> CC: Richard Hirst <richard@sleepie.demon.co.uk>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> drivers/net/Kconfig | 49 --------------
> drivers/net/Makefile | 7 --
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/{ => ethernet/motorola}/82596.c | 0
> drivers/net/ethernet/motorola/Kconfig | 68 ++++++++++++++++++++
> drivers/net/ethernet/motorola/Makefile | 11 +++
> drivers/net/{ => ethernet/motorola}/fec.c | 0
> drivers/net/{ => ethernet/motorola}/fec.h | 0
> drivers/net/{ => ethernet/motorola}/fec_mpc52xx.c | 0
> drivers/net/{ => ethernet/motorola}/fec_mpc52xx.h | 0
> .../net/{ => ethernet/motorola}/fec_mpc52xx_phy.c | 0
> 12 files changed, 81 insertions(+), 56 deletions(-)
>
> commit aebcb70982c66b54605fbd242f6ac035b2e205b3
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Mon Jun 13 08:43:49 2011 -0700
>
> sis*: Move the Silicon Integrated Systems (SiS) drivers
>
> Move the SiS drivers into drivers/net/ethernet/sis/ and make the
> necessary Kconfig and Makefile changes
>
> CC: Daniele Venzano <venza@brownhat.org>
> CC: Francois Romieu <romieu@fr.zoreil.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 4 +-
> drivers/net/Kconfig | 30 --------------------
> drivers/net/Makefile | 2 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/sis/Kconfig | 46 +++++++++++++++++++++++++++++++
> drivers/net/ethernet/sis/Makefile | 6 ++++
> drivers/net/{ => ethernet/sis}/sis190.c | 0
> drivers/net/{ => ethernet/sis}/sis900.c | 0
> drivers/net/{ => ethernet/sis}/sis900.h | 0
> 10 files changed, 56 insertions(+), 34 deletions(-)
>
> commit 826bef22759e1f78b284c9dc53ea442d348dbc88
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Mon Jun 13 08:23:31 2011 -0700
>
> spider_net: Move the spider_net (IBM) driver
>
> Move the spider_net (IBM) driver into drivers/net/ethernet/ibm/ and
> make the necessary Kconfig and Makefile changes
>
> CC: Utz Bacher <utz.bacher@de.ibm.com>
> CC: Jens Osterkamp <Jens.Osterkamp@de.ibm.com>
> CC: Ishizaki Kou <kou.ishizaki@toshiba.co.jp>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 2 +-
> drivers/net/Kconfig | 8 --------
> drivers/net/Makefile | 2 --
> drivers/net/ethernet/ibm/Kconfig | 11 ++++++++++-
> drivers/net/ethernet/ibm/Makefile | 2 ++
> drivers/net/{ => ethernet/ibm}/spider_net.c | 0
> drivers/net/{ => ethernet/ibm}/spider_net.h | 2 +-
> .../net/{ => ethernet/ibm}/spider_net_ethtool.c | 0
> 8 files changed, 14 insertions(+), 13 deletions(-)
>
> commit 776fae874e79c3bf3b6fd81eceb23993fef76c01
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Mon Jun 13 07:56:34 2011 -0700
>
> mv643xx/pxa168: Move the Marvell drivers
>
> Move the Marvell drivers into driver/net/ethernet/marvell and make
> the necessary Kconfig and Makefile changes.
>
> CC: Sachin Sanap <ssanap@marvell.com>
> CC: Zhangfei Gao <zgao6@marvell.com>
> CC: Philip Rakity <prakity@marvell.com>
> CC: Mark Brown <markb@marvell.com>
> CC: Lennert Buytenhek <buytenh@marvell.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 2 +-
> drivers/net/Kconfig | 23 ------------
> drivers/net/Makefile | 2 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/marvell/Kconfig | 40 ++++++++++++++++++++++
> drivers/net/ethernet/marvell/Makefile | 6 +++
> drivers/net/{ => ethernet/marvell}/mv643xx_eth.c | 0
> drivers/net/{ => ethernet/marvell}/pxa168_eth.c | 0
> 9 files changed, 49 insertions(+), 26 deletions(-)
>
> commit 4153aed9e3020693985219d471f8eb230a8eaefa
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Sat Jun 11 03:26:31 2011 -0700
>
> ks8*/ksz8*: Move the Micrel drivers
>
> Move the Micrel drivers into drivers/net/ethernet/micrel/ and
> make the necessary Kconfig and Makefile changes.
>
> CC: Ben Dooks <ben@simtec.co.uk>
> CC: Tristram Ha <Tristram.Ha@micrel.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> drivers/net/Kconfig | 35 ----------------
> drivers/net/Makefile | 4 --
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/micrel/Kconfig | 51 ++++++++++++++++++++++++
> drivers/net/ethernet/micrel/Makefile | 8 ++++
> drivers/net/{ => ethernet/micrel}/ks8842.c | 0
> drivers/net/{ => ethernet/micrel}/ks8851.c | 0
> drivers/net/{ => ethernet/micrel}/ks8851.h | 0
> drivers/net/{ => ethernet/micrel}/ks8851_mll.c | 0
> drivers/net/{ => ethernet/micrel}/ksz884x.c | 0
> 11 files changed, 61 insertions(+), 39 deletions(-)
>
> commit 518f5abc833cb0c30b79161c071b7c93ed458c6d
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Sat Jun 11 02:29:36 2011 -0700
>
> fsl_*/gianfar*/ucc_*: Move the Freescale drivers
>
> Move the Freescale driver into drivers/net/ethernet/freescale/ and
> make the necessary Kconfig and Makefile changes.
>
> CC: Sandeep Gopalpet <sandeep.kumar@freescale.com>
> CC: Andy Fleming <afleming@freescale.com>
> CC: Shlomi Gridish <gridish@freescale.com>
> CC: Li Yang <leoli@freescale.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 2 +-
> drivers/net/Kconfig | 33 -------------
> drivers/net/Makefile | 14 ------
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/freescale/Kconfig | 48 ++++++++++++++++++++
> drivers/net/ethernet/freescale/Makefile | 13 +++++
> .../net/{ => ethernet/freescale}/fs_enet/Kconfig | 2 +-
> .../net/{ => ethernet/freescale}/fs_enet/Makefile | 0
> drivers/net/{ => ethernet/freescale}/fs_enet/fec.h | 0
> .../freescale}/fs_enet/fs_enet-main.c | 0
> .../net/{ => ethernet/freescale}/fs_enet/fs_enet.h | 0
> .../net/{ => ethernet/freescale}/fs_enet/mac-fcc.c | 0
> .../net/{ => ethernet/freescale}/fs_enet/mac-fec.c | 0
> .../net/{ => ethernet/freescale}/fs_enet/mac-scc.c | 0
> .../{ => ethernet/freescale}/fs_enet/mii-bitbang.c | 0
> .../net/{ => ethernet/freescale}/fs_enet/mii-fec.c | 0
> drivers/net/{ => ethernet/freescale}/fsl_pq_mdio.c | 0
> drivers/net/{ => ethernet/freescale}/fsl_pq_mdio.h | 0
> drivers/net/{ => ethernet/freescale}/gianfar.c | 0
> drivers/net/{ => ethernet/freescale}/gianfar.h | 0
> .../net/{ => ethernet/freescale}/gianfar_ethtool.c | 0
> drivers/net/{ => ethernet/freescale}/gianfar_ptp.c | 0
> .../net/{ => ethernet/freescale}/gianfar_sysfs.c | 0
> drivers/net/{ => ethernet/freescale}/ucc_geth.c | 0
> drivers/net/{ => ethernet/freescale}/ucc_geth.h | 0
> .../{ => ethernet/freescale}/ucc_geth_ethtool.c | 0
> 27 files changed, 65 insertions(+), 49 deletions(-)
>
> commit dbf507c912fcc804a20d86d2194fc4a4298f39df
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Sat Jun 11 01:13:22 2011 -0700
>
> eepro/eexpress/eth16i/ewrk3/lp486e/seeq8005/znet: Move the ISA drivers
>
> Move the ISA drivers into drivers/net/ethernet/isa/ and make the
> necessary Kconfig and Makefile changes.
>
> CC: Philip Blundell <philb@gnu.org>
> CC: Mika Kuoppala <miku@iki.fi>
> CC: <bao.ha@srs.gov>
> CC: <aris@cathedrallabs.org>
> CC: David Davies <davies@maniac.ultranet.com>
> CC: <aeb@cwi.nl>
> CC: Hamish Coleman <hamish@zot.apana.org.au>
> CC: Donald Becker <becker@scyld.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 4 +-
> drivers/net/Kconfig | 98 ----------------------------
> drivers/net/Makefile | 10 ---
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/isa/Kconfig | 101 +++++++++++++++++++++++++++++
> drivers/net/ethernet/isa/Makefile | 11 +++
> drivers/net/{ => ethernet/isa}/eepro.c | 0
> drivers/net/{ => ethernet/isa}/eexpress.c | 0
> drivers/net/{ => ethernet/isa}/eexpress.h | 0
> drivers/net/{ => ethernet/isa}/eth16i.c | 0
> drivers/net/{ => ethernet/isa}/ewrk3.c | 0
> drivers/net/{ => ethernet/isa}/ewrk3.h | 0
> drivers/net/{ => ethernet/isa}/lp486e.c | 0
> drivers/net/{ => ethernet/isa}/seeq8005.c | 0
> drivers/net/{ => ethernet/isa}/seeq8005.h | 0
> drivers/net/{ => ethernet/isa}/znet.c | 0
> 17 files changed, 116 insertions(+), 110 deletions(-)
>
> commit b8a6199b8d692ae17932b8c8cc709898255a51ad
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Fri May 20 20:43:09 2011 -0700
>
> via-*: Move the VIA drivers
>
> Move the VIA drivers into drivers/net/ethernet/via/ and make the
> necessary Kconfig and Makefile changes.
>
> CC: Roger Luethi <rl@hellgate.ch>
> CC: Francois Romieu <romieu@fr.zoreil.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 4 +-
> drivers/net/Kconfig | 36 -----------------
> drivers/net/Makefile | 2 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/via/Kconfig | 52 +++++++++++++++++++++++++
> drivers/net/ethernet/via/Makefile | 6 +++
> drivers/net/{ => ethernet/via}/via-rhine.c | 0
> drivers/net/{ => ethernet/via}/via-velocity.c | 0
> drivers/net/{ => ethernet/via}/via-velocity.h | 0
> 10 files changed, 62 insertions(+), 40 deletions(-)
>
> commit 0cc82a49e423bc0b2ee19c49ad24376d1ffccdc5
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Fri May 20 20:18:55 2011 -0700
>
> skge/sky2: Move the SysKonnect Ethernet drivers
>
> Move the SysKonnect (Ethernet only) drivers into drivers/net/ethernet/syskonnect/
> and make the necessary Kconfig and Makefile changes.
>
> CC: Stephen Hemminger <shemminger@linux-foundation.org>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 3 +-
> drivers/net/Kconfig | 58 --------------------
> drivers/net/Makefile | 2 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/syskonnect/Kconfig | 74 ++++++++++++++++++++++++++
> drivers/net/ethernet/syskonnect/Makefile | 6 ++
> drivers/net/{ => ethernet/syskonnect}/skge.c | 0
> drivers/net/{ => ethernet/syskonnect}/skge.h | 0
> drivers/net/{ => ethernet/syskonnect}/sky2.c | 0
> drivers/net/{ => ethernet/syskonnect}/sky2.h | 0
> 11 files changed, 83 insertions(+), 62 deletions(-)
>
> commit c9e8faa7214a8911a22281e6e688e0cc69bb54b8
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Fri May 20 19:48:55 2011 -0700
>
> pch_gbe: Move the OKI driver
>
> Move the OKI driver into driver/net/ethernet/pch_gbe/ and make the
> necessary Kconfig and Makefile changes.
>
> Note: there is no documented maintainer for this driver, so I CC'd
> the last 2 major contributors.
>
> CC: Tomoya <tomoya-linux@dsn.okisemi.com>
> CC: Toshiharu Okada <toshiharu-linux@dsn.okisemi.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> drivers/net/Kconfig | 19 -------------------
> drivers/net/Makefile | 1 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/pch_gbe/Kconfig | 20 ++++++++++++++++++++
> drivers/net/{ => ethernet}/pch_gbe/Makefile | 0
> drivers/net/{ => ethernet}/pch_gbe/pch_gbe.h | 0
> drivers/net/{ => ethernet}/pch_gbe/pch_gbe_api.c | 0
> drivers/net/{ => ethernet}/pch_gbe/pch_gbe_api.h | 0
> .../net/{ => ethernet}/pch_gbe/pch_gbe_ethtool.c | 0
> drivers/net/{ => ethernet}/pch_gbe/pch_gbe_main.c | 0
> drivers/net/{ => ethernet}/pch_gbe/pch_gbe_param.c | 0
> drivers/net/{ => ethernet}/pch_gbe/pch_gbe_phy.c | 0
> drivers/net/{ => ethernet}/pch_gbe/pch_gbe_phy.h | 0
> 14 files changed, 22 insertions(+), 20 deletions(-)
>
> commit 63e70fbc3837e36fbcc3e5b3d12eed74919e3beb
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Fri May 20 07:50:27 2011 -0700
>
> ioc3-eth/meth/sgiseeq: Move the SGI drivers
>
> Move the SGI drivers into drivers/net/ethernet/sgi/ and make the
> necessary Kconfig and Makefile changes.
>
> CC: Ralf Baechle <ralf@linux-mips.org>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 2 +-
> drivers/net/Kconfig | 21 ----------------
> drivers/net/Makefile | 3 --
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/sgi/Kconfig | 37 +++++++++++++++++++++++++++++
> drivers/net/ethernet/sgi/Makefile | 7 +++++
> drivers/net/{ => ethernet/sgi}/ioc3-eth.c | 0
> drivers/net/{ => ethernet/sgi}/meth.c | 0
> drivers/net/{ => ethernet/sgi}/meth.h | 0
> drivers/net/{ => ethernet/sgi}/sgiseeq.c | 0
> drivers/net/{ => ethernet/sgi}/sgiseeq.h | 0
> 12 files changed, 47 insertions(+), 25 deletions(-)
>
> commit 33bb1962fa6983fb17a7c95a5b44be697878783b
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Fri May 20 07:15:19 2011 -0700
>
> tulip: Move the tulip drivers
>
> Move the tulip driver into drivers/net/ethernet/tulip/ and make
> the necessary Kconfig and Makefile changes.
>
> CC: Tobias Ringstrom <tori@unhappy.mine.nu>
> CC: Grant Grundler <grundler@parisc-linux.org>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 4 ++--
> drivers/net/Kconfig | 2 --
> drivers/net/Makefile | 1 -
> drivers/net/ethernet/Kconfig | 2 ++
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/{ => ethernet}/tulip/21142.c | 0
> drivers/net/{ => ethernet}/tulip/Kconfig | 0
> drivers/net/{ => ethernet}/tulip/Makefile | 0
> drivers/net/{ => ethernet}/tulip/de2104x.c | 0
> drivers/net/{ => ethernet}/tulip/de4x5.c | 0
> drivers/net/{ => ethernet}/tulip/de4x5.h | 0
> drivers/net/{ => ethernet}/tulip/dmfe.c | 0
> drivers/net/{ => ethernet}/tulip/eeprom.c | 0
> drivers/net/{ => ethernet}/tulip/interrupt.c | 0
> drivers/net/{ => ethernet}/tulip/media.c | 0
> drivers/net/{ => ethernet}/tulip/pnic.c | 0
> drivers/net/{ => ethernet}/tulip/pnic2.c | 0
> drivers/net/{ => ethernet}/tulip/timer.c | 0
> drivers/net/{ => ethernet}/tulip/tulip.h | 0
> drivers/net/{ => ethernet}/tulip/tulip_core.c | 0
> drivers/net/{ => ethernet}/tulip/uli526x.c | 0
> drivers/net/{ => ethernet}/tulip/winbond-840.c | 0
> drivers/net/{ => ethernet}/tulip/xircom_cb.c | 0
> 23 files changed, 5 insertions(+), 5 deletions(-)
>
> commit 9091cea3242dcc16138cef784c4880a819b28c1e
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Fri May 20 06:55:16 2011 -0700
>
> atl*: Move the Atheros drivers
>
> Move the Atheros drivers into drivers/net/ethernet/atheros/ and
> make the necessary Kconfig and Makefile changes.
>
> CC: Jay Cliburn <jcliburn@gmail.com>
> CC: Chris Snook <chris.snook@gmail.com>
> CC: Jie Yang <jie.yang@atheros.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 2 +-
> drivers/net/Kconfig | 45 --------------
> drivers/net/Makefile | 4 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/atheros/Kconfig | 61 ++++++++++++++++++++
> drivers/net/ethernet/atheros/Makefile | 8 +++
> drivers/net/{ => ethernet/atheros}/atl1c/Makefile | 0
> drivers/net/{ => ethernet/atheros}/atl1c/atl1c.h | 0
> .../{ => ethernet/atheros}/atl1c/atl1c_ethtool.c | 0
> .../net/{ => ethernet/atheros}/atl1c/atl1c_hw.c | 0
> .../net/{ => ethernet/atheros}/atl1c/atl1c_hw.h | 0
> .../net/{ => ethernet/atheros}/atl1c/atl1c_main.c | 0
> drivers/net/{ => ethernet/atheros}/atl1e/Makefile | 0
> drivers/net/{ => ethernet/atheros}/atl1e/atl1e.h | 0
> .../{ => ethernet/atheros}/atl1e/atl1e_ethtool.c | 0
> .../net/{ => ethernet/atheros}/atl1e/atl1e_hw.c | 0
> .../net/{ => ethernet/atheros}/atl1e/atl1e_hw.h | 0
> .../net/{ => ethernet/atheros}/atl1e/atl1e_main.c | 0
> .../net/{ => ethernet/atheros}/atl1e/atl1e_param.c | 0
> drivers/net/{ => ethernet/atheros}/atlx/Makefile | 0
> drivers/net/{ => ethernet/atheros}/atlx/atl1.c | 0
> drivers/net/{ => ethernet/atheros}/atlx/atl1.h | 0
> drivers/net/{ => ethernet/atheros}/atlx/atl2.c | 0
> drivers/net/{ => ethernet/atheros}/atlx/atl2.h | 0
> drivers/net/{ => ethernet/atheros}/atlx/atlx.c | 0
> drivers/net/{ => ethernet/atheros}/atlx/atlx.h | 0
> 27 files changed, 72 insertions(+), 50 deletions(-)
>
> commit c97cb6d3434e3a3fa4d415f436e04475df39e443
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Fri May 20 00:04:35 2011 -0700
>
> de6*/dl2k: Move the D-Link drivers
>
> Move the D-Link drivers into drivers/net/ethernet/dlink/ and
> make the necessary Kconfig and Makefile changes.
>
> CC: Bjorn Ekwall <bj0rn@blox.se>
> CC: Donald Becker <becker@scyld.com>
> CC: Edward Peng <edward_peng@dlink.com.tw>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> drivers/net/Kconfig | 44 ----------------------
> drivers/net/Makefile | 3 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/dlink/Kconfig | 60 ++++++++++++++++++++++++++++++
> drivers/net/ethernet/dlink/Makefile | 7 +++
> drivers/net/{ => ethernet/dlink}/de600.c | 0
> drivers/net/{ => ethernet/dlink}/de600.h | 0
> drivers/net/{ => ethernet/dlink}/de620.c | 0
> drivers/net/{ => ethernet/dlink}/de620.h | 0
> drivers/net/{ => ethernet/dlink}/dl2k.c | 0
> drivers/net/{ => ethernet/dlink}/dl2k.h | 0
> 12 files changed, 69 insertions(+), 47 deletions(-)
>
> commit 268a0fa7d7159b37d1123d68343c555f44221510
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Thu May 19 23:27:55 2011 -0700
>
> 8139*/atp/r8169: Move the Realtek drivers
>
> Move the Realtek drivers into drivers/net/ethernet/realtek/ and make
> the necessary Kconfig and Makefile changes.
>
> CC: Realtek linux nic maintainers <nic_swsd@realtek.com>
> CC: Francois Romieu <romieu@fr.zoreil.com>
> CC: Jeff Garzik <jgarzik@pobox.com>
> CC: Donald Becker <becker@scyld.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 2 +-
> drivers/net/Kconfig | 94 ----------------------
> drivers/net/Makefile | 4 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/{ => ethernet/realtek}/8139cp.c | 0
> drivers/net/{ => ethernet/realtek}/8139too.c | 0
> drivers/net/ethernet/realtek/Kconfig | 110 ++++++++++++++++++++++++++
> drivers/net/ethernet/realtek/Makefile | 8 ++
> drivers/net/{ => ethernet/realtek}/atp.c | 0
> drivers/net/{ => ethernet/realtek}/atp.h | 0
> drivers/net/{ => ethernet/realtek}/r8169.c | 0
> 12 files changed, 121 insertions(+), 99 deletions(-)
>
> commit 5fe875b9e93af6b5a099b37471bebb541f1ba0c6
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Thu May 19 22:06:03 2011 -0700
>
> arm: Move the ARM/ACORN drivers
>
> Move the ARM/ACORN drivers into drivers/net/ethernet/arm/ and make the
> necessary Kconfig and Makefile changes.
> There were 4 drivers (TI Davinci & ftmac100) not in the
> drivers/net/arm/ which should have been since they are only supported
> under ARM, so they were added to the new directory structure.
>
> NOTE: There are no "maintainers" for the TI Davinci drivers, so I am
> CC'ing the last 3 major contributors from TI.
>
> CC: Sriram <srk@ti.com>
> CC: Vinay Hegde <vinay.hegde@ti.com>
> CC: Cyril Chemparathy <cyril@ti.com>
> CC: Russell King <linux@arm.linux.org.uk>
> CC: Wan ZongShun <mcuos.com@gmail.com>
> CC: Lennert Buytenhek <kernel@wantstofly.org>
> CC: Krzysztof Halasa <khc@pm.waw.pl>
> CC: Po-Yu Chuang <ratbert@faraday-tech.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 10 +-
> drivers/net/Kconfig | 51 ---------
> drivers/net/Makefile | 7 --
> drivers/net/arm/Kconfig | 74 -------------
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/arm/Kconfig | 138 ++++++++++++++++++++++++
> drivers/net/{ => ethernet}/arm/Makefile | 6 +-
> drivers/net/{ => ethernet}/arm/am79c961a.c | 0
> drivers/net/{ => ethernet}/arm/am79c961a.h | 0
> drivers/net/{ => ethernet}/arm/at91_ether.c | 0
> drivers/net/{ => ethernet}/arm/at91_ether.h | 0
> drivers/net/{ => ethernet/arm}/davinci_cpdma.c | 0
> drivers/net/{ => ethernet/arm}/davinci_cpdma.h | 0
> drivers/net/{ => ethernet/arm}/davinci_emac.c | 0
> drivers/net/{ => ethernet/arm}/davinci_mdio.c | 0
> drivers/net/{ => ethernet}/arm/ep93xx_eth.c | 0
> drivers/net/{ => ethernet}/arm/ether1.c | 0
> drivers/net/{ => ethernet}/arm/ether1.h | 0
> drivers/net/{ => ethernet}/arm/ether3.c | 0
> drivers/net/{ => ethernet}/arm/ether3.h | 0
> drivers/net/{ => ethernet}/arm/etherh.c | 0
> drivers/net/{ => ethernet/arm}/ftgmac100.c | 0
> drivers/net/{ => ethernet/arm}/ftgmac100.h | 0
> drivers/net/{ => ethernet/arm}/ftmac100.c | 0
> drivers/net/{ => ethernet/arm}/ftmac100.h | 0
> drivers/net/{ => ethernet}/arm/ixp4xx_eth.c | 0
> drivers/net/{ => ethernet}/arm/ks8695net.c | 0
> drivers/net/{ => ethernet}/arm/ks8695net.h | 0
> drivers/net/{ => ethernet}/arm/w90p910_ether.c | 0
> 30 files changed, 150 insertions(+), 138 deletions(-)
>
> commit 17c347d9648541503aef09b95b207737b151ddea
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Thu May 19 20:18:50 2011 -0700
>
> smsc*/smc911x: Move the SMSC drivers
>
> Move the SMSC drivers into drivers/net/ethernet/smsc/ and make the
> necessary Kconfig and Makefile changes.
>
> CC: Dustin McIntire <dustin@sensoria.com>
> CC: Steve Glendinning <steve.glendinning@smsc.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 4 +-
> drivers/net/Kconfig | 54 ---------------------
> drivers/net/Makefile | 3 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/smsc/Kconfig | 71 ++++++++++++++++++++++++++++
> drivers/net/ethernet/smsc/Makefile | 7 +++
> drivers/net/{ => ethernet/smsc}/smc911x.c | 0
> drivers/net/{ => ethernet/smsc}/smc911x.h | 0
> drivers/net/{ => ethernet/smsc}/smsc911x.c | 0
> drivers/net/{ => ethernet/smsc}/smsc911x.h | 0
> drivers/net/{ => ethernet/smsc}/smsc9420.c | 0
> drivers/net/{ => ethernet/smsc}/smsc9420.h | 0
> 13 files changed, 82 insertions(+), 59 deletions(-)
>
> commit f93707a2948f67da9fbe12ff93f6c5a95d6fb23d
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Wed May 18 05:14:22 2011 -0700
>
> *sonic/natsemi/ns83829: Move the National Semi-conductor drivers
>
> Move the National Semi-conductor drivers into drivers/net/ethernet/natsemi/
> and make the necessary Kconfig and Makefile changes. Also moved the 8390
> (National Semi-conductor) devices as a sub-menu of National Semi-conductor
> devices.
>
> CC: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> CC: Harald Welte <laforge@gnumonks.org>
> CC: Tim Hockin <thockin@hockin.org>
> CC: <linux-ns83820@kvack.org>
> CC: Kevin Chea <kchea@yahoo.com>
> CC: Marc Gauthier <marc@linux-xtensa.org>
> CC: Chris Zankel <chris@zankel.net>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 4 +-
> drivers/net/Kconfig | 47 ------------------
> drivers/net/Makefile | 6 --
> drivers/net/ethernet/8390/Kconfig | 6 +-
> drivers/net/ethernet/Kconfig | 3 +-
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/natsemi/Kconfig | 63 ++++++++++++++++++++++++
> drivers/net/ethernet/natsemi/Makefile | 9 +++
> drivers/net/{ => ethernet/natsemi}/jazzsonic.c | 0
> drivers/net/{ => ethernet/natsemi}/macsonic.c | 0
> drivers/net/{ => ethernet/natsemi}/natsemi.c | 0
> drivers/net/{ => ethernet/natsemi}/ns83820.c | 0
> drivers/net/{ => ethernet/natsemi}/sonic.c | 0
> drivers/net/{ => ethernet/natsemi}/sonic.h | 0
> drivers/net/{ => ethernet/natsemi}/xtsonic.c | 0
> 15 files changed, 80 insertions(+), 59 deletions(-)
>
> commit 8a352394d237f49f4d142874057d4179a1169607
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Mon May 16 01:39:01 2011 -0700
>
> bmac/mace/macmace/mac89x0/cs89x0: Move the Macintosh (Apple) drivers
>
> Move the Apple drivers into driver/net/ethernet/apple/ and make the
> necessary Kconfig and Makefile changes.
>
> CC: Paul Mackerras <paulus@samba.org>
> CC: Paul Mackerras <paulus@au.ibm.com>
> CC: Russell Nelson <nelson@crynwr.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> drivers/net/Kconfig | 75 ----------------------
> drivers/net/Makefile | 6 --
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/apple/Kconfig | 92 ++++++++++++++++++++++++++++
> drivers/net/ethernet/apple/Makefile | 9 +++
> drivers/net/{ => ethernet/apple}/bmac.c | 0
> drivers/net/{ => ethernet/apple}/bmac.h | 0
> drivers/net/{ => ethernet/apple}/cs89x0.c | 0
> drivers/net/{ => ethernet/apple}/cs89x0.h | 0
> drivers/net/{ => ethernet/apple}/mac89x0.c | 0
> drivers/net/{ => ethernet/apple}/mace.c | 0
> drivers/net/{ => ethernet/apple}/mace.h | 0
> drivers/net/{ => ethernet/apple}/macmace.c | 0
> 14 files changed, 103 insertions(+), 81 deletions(-)
>
> commit 0222c318a10195f618d82f9f7c4e0d61564bcc5d
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Mon May 16 00:05:19 2011 -0700
>
> stmmac: Move the STMicroelectronics driver
>
> Move the STMicroelectronics driver into driver/net/ethernet/stmmac/ and
> make the necessary Kconfig and Makefile changes.
>
> CC: Giuseppe Cavallaro <peppe.cavallaro@st.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 2 +-
> drivers/net/Kconfig | 2 --
> drivers/net/Makefile | 1 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/{ => ethernet}/stmmac/Kconfig | 0
> drivers/net/{ => ethernet}/stmmac/Makefile | 0
> drivers/net/{ => ethernet}/stmmac/common.h | 0
> drivers/net/{ => ethernet}/stmmac/descs.h | 0
> drivers/net/{ => ethernet}/stmmac/dwmac100.h | 0
> drivers/net/{ => ethernet}/stmmac/dwmac1000.h | 0
> drivers/net/{ => ethernet}/stmmac/dwmac1000_core.c | 0
> drivers/net/{ => ethernet}/stmmac/dwmac1000_dma.c | 0
> drivers/net/{ => ethernet}/stmmac/dwmac100_core.c | 0
> drivers/net/{ => ethernet}/stmmac/dwmac100_dma.c | 0
> drivers/net/{ => ethernet}/stmmac/dwmac_dma.h | 0
> drivers/net/{ => ethernet}/stmmac/dwmac_lib.c | 0
> drivers/net/{ => ethernet}/stmmac/enh_desc.c | 0
> drivers/net/{ => ethernet}/stmmac/norm_desc.c | 0
> drivers/net/{ => ethernet}/stmmac/stmmac.h | 0
> drivers/net/{ => ethernet}/stmmac/stmmac_ethtool.c | 0
> drivers/net/{ => ethernet}/stmmac/stmmac_main.c | 0
> drivers/net/{ => ethernet}/stmmac/stmmac_mdio.c | 0
> drivers/net/{ => ethernet}/stmmac/stmmac_timer.c | 0
> drivers/net/{ => ethernet}/stmmac/stmmac_timer.h | 0
> 25 files changed, 3 insertions(+), 4 deletions(-)
>
> commit c9979075eda1f39b3cf73b51b4da05e2bc1a7a3f
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Sun May 15 21:46:41 2011 -0700
>
> tehuti: Move the Tehuti driver
>
> Move the Tehuti driver into drivers/net/ethernet/ and make the
> necessary Kconfig and Makefile changes.
>
> CC: Alexander Indenbaum <baum@tehutinetworks.net>
> CC: Andy Gospodarek <andy@greyhouse.net>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 2 +-
> drivers/net/Kconfig | 6 ------
> drivers/net/Makefile | 1 -
> drivers/net/ethernet/Kconfig | 6 ++++++
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/{ => ethernet}/tehuti.c | 0
> drivers/net/{ => ethernet}/tehuti.h | 0
> 7 files changed, 8 insertions(+), 8 deletions(-)
>
> commit 9b8448aa63ea26e8cbe23df6064146b2bcf1429c
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Sun May 15 20:56:37 2011 -0700
>
> pasemic_mac*: Move the PA Semi driver
>
> Move the PA Semi driver into drivers/net/ethernet/ and make the
> necessary Kconfig and Makefile changes.
>
> CC: Olof Johansson <olof@lixom.net>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 2 +-
> drivers/net/Kconfig | 9 ---------
> drivers/net/Makefile | 2 --
> drivers/net/ethernet/Kconfig | 10 ++++++++++
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/{ => ethernet}/pasemi_mac.c | 0
> drivers/net/{ => ethernet}/pasemi_mac.h | 0
> drivers/net/{ => ethernet}/pasemi_mac_ethtool.c | 0
> 8 files changed, 12 insertions(+), 12 deletions(-)
>
> commit 8f45b84e5a50e13e530ccd7277e87e21bf9d3824
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Fri May 13 22:20:35 2011 -0700
>
> enic: Move the Cisco driver
>
> Move the Cisco driver into drivers/net/ethernet/enic/ and make the
> necessary Kconfig and Makefile changes.
>
> CC: Scott Feldman <scofeldm@cisco.com>
> CC: Christian Benvenuti <benve@cisco.com>
> CC: Vasanthy Kolluri <vkolluri@cisco.com>
> CC: Roopa Prabhu <roprabhu@cisco.com>
> CC: David Wang <dwang2@cisco.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 2 +-
> drivers/net/Kconfig | 6 ------
> drivers/net/Makefile | 1 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/enic/Kconfig | 9 +++++++++
> drivers/net/{ => ethernet}/enic/Makefile | 0
> drivers/net/{ => ethernet}/enic/cq_desc.h | 0
> drivers/net/{ => ethernet}/enic/cq_enet_desc.h | 0
> drivers/net/{ => ethernet}/enic/enic.h | 0
> drivers/net/{ => ethernet}/enic/enic_dev.c | 0
> drivers/net/{ => ethernet}/enic/enic_dev.h | 0
> drivers/net/{ => ethernet}/enic/enic_main.c | 0
> drivers/net/{ => ethernet}/enic/enic_pp.c | 0
> drivers/net/{ => ethernet}/enic/enic_pp.h | 0
> drivers/net/{ => ethernet}/enic/enic_res.c | 0
> drivers/net/{ => ethernet}/enic/enic_res.h | 0
> drivers/net/{ => ethernet}/enic/rq_enet_desc.h | 0
> drivers/net/{ => ethernet}/enic/vnic_cq.c | 0
> drivers/net/{ => ethernet}/enic/vnic_cq.h | 0
> drivers/net/{ => ethernet}/enic/vnic_dev.c | 0
> drivers/net/{ => ethernet}/enic/vnic_dev.h | 0
> drivers/net/{ => ethernet}/enic/vnic_devcmd.h | 0
> drivers/net/{ => ethernet}/enic/vnic_enet.h | 0
> drivers/net/{ => ethernet}/enic/vnic_intr.c | 0
> drivers/net/{ => ethernet}/enic/vnic_intr.h | 0
> drivers/net/{ => ethernet}/enic/vnic_nic.h | 0
> drivers/net/{ => ethernet}/enic/vnic_resource.h | 0
> drivers/net/{ => ethernet}/enic/vnic_rq.c | 0
> drivers/net/{ => ethernet}/enic/vnic_rq.h | 0
> drivers/net/{ => ethernet}/enic/vnic_rss.h | 0
> drivers/net/{ => ethernet}/enic/vnic_stats.h | 0
> drivers/net/{ => ethernet}/enic/vnic_vic.c | 0
> drivers/net/{ => ethernet}/enic/vnic_vic.h | 0
> drivers/net/{ => ethernet}/enic/vnic_wq.c | 0
> drivers/net/{ => ethernet}/enic/vnic_wq.h | 0
> drivers/net/{ => ethernet}/enic/wq_enet_desc.h | 0
> 37 files changed, 12 insertions(+), 8 deletions(-)
>
> commit 21b49617eef3976ebbd73cb4bf1a1f2f6902dbbf
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Fri May 13 14:29:12 2011 -0700
>
> ehea/ibm*: Move the IBM drivers
>
> Move the IBM drivers into drivers/net/ethernet/ibm/ and make the
> necessary Kconfig and Makefile changes.
>
> CC: Christoph Raisch <raisch@de.ibm.com>
> CC: Alfred Arnold <alfred.arnold@lancom.de>
> CC: Santiago Leon <santil@linux.vnet.ibm.com>
> CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 4 +-
> drivers/net/Kconfig | 37 --------------
> drivers/net/Makefile | 4 --
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/ibm/Kconfig | 53 ++++++++++++++++++++
> drivers/net/ethernet/ibm/Makefile | 8 +++
> drivers/net/{ => ethernet/ibm}/ehea/Makefile | 0
> drivers/net/{ => ethernet/ibm}/ehea/ehea.h | 0
> drivers/net/{ => ethernet/ibm}/ehea/ehea_ethtool.c | 0
> drivers/net/{ => ethernet/ibm}/ehea/ehea_hw.h | 0
> drivers/net/{ => ethernet/ibm}/ehea/ehea_main.c | 0
> drivers/net/{ => ethernet/ibm}/ehea/ehea_phyp.c | 0
> drivers/net/{ => ethernet/ibm}/ehea/ehea_phyp.h | 0
> drivers/net/{ => ethernet/ibm}/ehea/ehea_qmr.c | 0
> drivers/net/{ => ethernet/ibm}/ehea/ehea_qmr.h | 0
> drivers/net/{ => ethernet/ibm}/ibm_newemac/Kconfig | 2 +-
> .../net/{ => ethernet/ibm}/ibm_newemac/Makefile | 0
> drivers/net/{ => ethernet/ibm}/ibm_newemac/core.c | 0
> drivers/net/{ => ethernet/ibm}/ibm_newemac/core.h | 0
> drivers/net/{ => ethernet/ibm}/ibm_newemac/debug.c | 0
> drivers/net/{ => ethernet/ibm}/ibm_newemac/debug.h | 0
> drivers/net/{ => ethernet/ibm}/ibm_newemac/emac.h | 0
> drivers/net/{ => ethernet/ibm}/ibm_newemac/mal.c | 0
> drivers/net/{ => ethernet/ibm}/ibm_newemac/mal.h | 0
> drivers/net/{ => ethernet/ibm}/ibm_newemac/phy.c | 0
> drivers/net/{ => ethernet/ibm}/ibm_newemac/phy.h | 0
> drivers/net/{ => ethernet/ibm}/ibm_newemac/rgmii.c | 0
> drivers/net/{ => ethernet/ibm}/ibm_newemac/rgmii.h | 0
> drivers/net/{ => ethernet/ibm}/ibm_newemac/tah.c | 0
> drivers/net/{ => ethernet/ibm}/ibm_newemac/tah.h | 0
> drivers/net/{ => ethernet/ibm}/ibm_newemac/zmii.c | 0
> drivers/net/{ => ethernet/ibm}/ibm_newemac/zmii.h | 0
> drivers/net/{ => ethernet/ibm}/ibmlana.c | 0
> drivers/net/{ => ethernet/ibm}/ibmlana.h | 0
> drivers/net/{ => ethernet/ibm}/ibmveth.c | 0
> drivers/net/{ => ethernet/ibm}/ibmveth.h | 0
> 37 files changed, 66 insertions(+), 44 deletions(-)
>
> commit a5c1daab860bc137dafadc061e48f4153ce89a31
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Fri May 13 02:51:01 2011 -0700
>
> s2io/vxge: Move the Exar drivers
>
> Move the Exar drivers into drivers/net/ethernet/exar/ and make the
> necessary Kconfig and Makefile changes.
>
> CC: Jon Mason <jdmason@kudzu.us>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 3 +-
> drivers/net/Kconfig | 34 -------------
> drivers/net/Makefile | 2 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/exar/Kconfig | 50 ++++++++++++++++++++
> drivers/net/ethernet/exar/Makefile | 6 ++
> drivers/net/{ => ethernet/exar}/s2io-regs.h | 0
> drivers/net/{ => ethernet/exar}/s2io.c | 0
> drivers/net/{ => ethernet/exar}/s2io.h | 0
> drivers/net/{ => ethernet/exar}/vxge/Makefile | 0
> drivers/net/{ => ethernet/exar}/vxge/vxge-config.c | 0
> drivers/net/{ => ethernet/exar}/vxge/vxge-config.h | 0
> .../net/{ => ethernet/exar}/vxge/vxge-ethtool.c | 0
> .../net/{ => ethernet/exar}/vxge/vxge-ethtool.h | 0
> drivers/net/{ => ethernet/exar}/vxge/vxge-main.c | 0
> drivers/net/{ => ethernet/exar}/vxge/vxge-main.h | 0
> drivers/net/{ => ethernet/exar}/vxge/vxge-reg.h | 0
> .../net/{ => ethernet/exar}/vxge/vxge-traffic.c | 0
> .../net/{ => ethernet/exar}/vxge/vxge-traffic.h | 0
> .../net/{ => ethernet/exar}/vxge/vxge-version.h | 0
> 21 files changed, 59 insertions(+), 38 deletions(-)
>
> commit 83df87d655e25119eafaeb4225bc5eedaa82c6e0
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Fri May 13 02:24:46 2011 -0700
>
> myri*: Move the Myricom drivers
>
> Move the Myricom drivers into drivers/net/ethernet/myricom/ and make
> the necessary Kconfig and Makefile changes.
>
> CC: Andrew Gallatin <gallatin@myri.com>
> CC: Brice Goglin <brice@myri.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 2 +-
> drivers/net/Kconfig | 35 -------------
> drivers/net/Makefile | 3 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/myricom/Kconfig | 51 ++++++++++++++++++++
> drivers/net/ethernet/myricom/Makefile | 6 ++
> .../net/{ => ethernet/myricom}/myri10ge/Makefile | 0
> .../net/{ => ethernet/myricom}/myri10ge/myri10ge.c | 0
> .../{ => ethernet/myricom}/myri10ge/myri10ge_mcp.h | 0
> .../myricom}/myri10ge/myri10ge_mcp_gen_header.h | 0
> drivers/net/{ => ethernet/myricom}/myri_sbus.c | 0
> drivers/net/{ => ethernet/myricom}/myri_sbus.h | 0
/me puts on Myricom hat
I believe we want to put the driver above in the sbus/legacy
directory. Better yet, move this driver to /dev/null. There is no
possibility of ethernet mode on this adapter, so it's Myrinet only.
It won't inter-op with modern versions of Myrinet, and thus can only
work with legacy adapters. There are no drivers for the PCI version
of this adapter, so it only can work on ~15year old hardware. It's
long in the tooth, let's take it to the knackers.
Thanks,
Jon
> 13 files changed, 60 insertions(+), 39 deletions(-)
>
> commit c04bd079e4ab82c5ee8fd0cb526f16e9ffce9360
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Fri May 13 01:32:22 2011 -0700
>
> mlx4: Move the Mellanox driver
>
> Moves the Mellanox driver into drivers/net/ethernet/mlx4/ and make
> the necessary Kconfig and Makefile changes.
>
> CC: Roland Dreier <roland@kernel.org>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> drivers/net/Kconfig | 24 ---------------------
> drivers/net/Makefile | 1 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/mlx4/Kconfig | 27 ++++++++++++++++++++++++
> drivers/net/{ => ethernet}/mlx4/Makefile | 0
> drivers/net/{ => ethernet}/mlx4/alloc.c | 0
> drivers/net/{ => ethernet}/mlx4/catas.c | 0
> drivers/net/{ => ethernet}/mlx4/cmd.c | 0
> drivers/net/{ => ethernet}/mlx4/cq.c | 0
> drivers/net/{ => ethernet}/mlx4/en_cq.c | 0
> drivers/net/{ => ethernet}/mlx4/en_ethtool.c | 0
> drivers/net/{ => ethernet}/mlx4/en_main.c | 0
> drivers/net/{ => ethernet}/mlx4/en_netdev.c | 0
> drivers/net/{ => ethernet}/mlx4/en_port.c | 0
> drivers/net/{ => ethernet}/mlx4/en_port.h | 0
> drivers/net/{ => ethernet}/mlx4/en_resources.c | 0
> drivers/net/{ => ethernet}/mlx4/en_rx.c | 0
> drivers/net/{ => ethernet}/mlx4/en_selftest.c | 0
> drivers/net/{ => ethernet}/mlx4/en_tx.c | 0
> drivers/net/{ => ethernet}/mlx4/eq.c | 0
> drivers/net/{ => ethernet}/mlx4/fw.c | 0
> drivers/net/{ => ethernet}/mlx4/fw.h | 0
> drivers/net/{ => ethernet}/mlx4/icm.c | 0
> drivers/net/{ => ethernet}/mlx4/icm.h | 0
> drivers/net/{ => ethernet}/mlx4/intf.c | 0
> drivers/net/{ => ethernet}/mlx4/main.c | 0
> drivers/net/{ => ethernet}/mlx4/mcg.c | 0
> drivers/net/{ => ethernet}/mlx4/mlx4.h | 0
> drivers/net/{ => ethernet}/mlx4/mlx4_en.h | 0
> drivers/net/{ => ethernet}/mlx4/mr.c | 0
> drivers/net/{ => ethernet}/mlx4/pd.c | 0
> drivers/net/{ => ethernet}/mlx4/port.c | 0
> drivers/net/{ => ethernet}/mlx4/profile.c | 0
> drivers/net/{ => ethernet}/mlx4/qp.c | 0
> drivers/net/{ => ethernet}/mlx4/reset.c | 0
> drivers/net/{ => ethernet}/mlx4/sense.c | 0
> drivers/net/{ => ethernet}/mlx4/srq.c | 0
> 38 files changed, 29 insertions(+), 25 deletions(-)
>
> commit d911fd7be681f8833f8ff12efade39df79970653
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Fri May 13 01:00:03 2011 -0700
>
> bna: Move the Brocade driver
>
> Moves the Brocade driver into drivers/net/ethernet/bna/ and make
> the necessary Kconfig and Makefile changes.
>
> CC: Rasesh Mody <rmody@brocade.com>
> CC: Debashis Dutt <ddutt@brocade.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 2 +-
> drivers/net/Kconfig | 14 --------------
> drivers/net/Makefile | 1 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/bna/Kconfig | 17 +++++++++++++++++
> drivers/net/{ => ethernet}/bna/Makefile | 0
> drivers/net/{ => ethernet}/bna/bfa_cee.c | 0
> drivers/net/{ => ethernet}/bna/bfa_cee.h | 0
> drivers/net/{ => ethernet}/bna/bfa_defs.h | 0
> drivers/net/{ => ethernet}/bna/bfa_defs_cna.h | 0
> drivers/net/{ => ethernet}/bna/bfa_defs_mfg_comm.h | 0
> drivers/net/{ => ethernet}/bna/bfa_defs_status.h | 0
> drivers/net/{ => ethernet}/bna/bfa_ioc.c | 0
> drivers/net/{ => ethernet}/bna/bfa_ioc.h | 0
> drivers/net/{ => ethernet}/bna/bfa_ioc_ct.c | 0
> drivers/net/{ => ethernet}/bna/bfa_sm.h | 0
> drivers/net/{ => ethernet}/bna/bfa_wc.h | 0
> drivers/net/{ => ethernet}/bna/bfi.h | 0
> drivers/net/{ => ethernet}/bna/bfi_cna.h | 0
> drivers/net/{ => ethernet}/bna/bfi_ctreg.h | 0
> drivers/net/{ => ethernet}/bna/bfi_ll.h | 0
> drivers/net/{ => ethernet}/bna/bna.h | 0
> drivers/net/{ => ethernet}/bna/bna_ctrl.c | 0
> drivers/net/{ => ethernet}/bna/bna_hw.h | 0
> drivers/net/{ => ethernet}/bna/bna_txrx.c | 0
> drivers/net/{ => ethernet}/bna/bna_types.h | 0
> drivers/net/{ => ethernet}/bna/bnad.c | 0
> drivers/net/{ => ethernet}/bna/bnad.h | 0
> drivers/net/{ => ethernet}/bna/bnad_ethtool.c | 0
> drivers/net/{ => ethernet}/bna/cna.h | 0
> drivers/net/{ => ethernet}/bna/cna_fwimg.c | 0
> 32 files changed, 20 insertions(+), 16 deletions(-)
>
> commit 931da59411e60574a1235d0ad2d63ebd1638a859
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Fri May 13 00:37:27 2011 -0700
>
> be2net: Move the BladeEngine 2 driver
>
> Moves the Server Engine driver into drivers/net/ethernet/benet/ and
> make the necessary Kconfig and Makefile changes.
>
> CC: Sathya Perla <sathya.perla@emulex.com>
> CC: Subbu Seetharaman <subbu.seetharaman@emulex.com>
> CC: Ajit Khaparde <ajit.khaparde@emulex.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 2 +-
> drivers/net/Kconfig | 2 --
> drivers/net/Makefile | 1 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/{ => ethernet}/benet/Kconfig | 0
> drivers/net/{ => ethernet}/benet/Makefile | 0
> drivers/net/{ => ethernet}/benet/be.h | 0
> drivers/net/{ => ethernet}/benet/be_cmds.c | 0
> drivers/net/{ => ethernet}/benet/be_cmds.h | 0
> drivers/net/{ => ethernet}/benet/be_ethtool.c | 0
> drivers/net/{ => ethernet}/benet/be_hw.h | 0
> drivers/net/{ => ethernet}/benet/be_main.c | 0
> 13 files changed, 3 insertions(+), 4 deletions(-)
>
> commit 64648e513185522cd665bfece6d024d3c05588ed
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Fri May 13 00:17:42 2011 -0700
>
> sfc: Move the Solarflare drivers
>
> Moves the Solarflare drivers into drivers/net/ethernet/sfc/ and
> make the necessary Kconfig and Makefile changes.
>
> CC: Steve Hodgson <shodgson@solarflare.com>
> CC: Ben Hutchings <bhutchings@solarflare.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 2 +-
> drivers/net/Kconfig | 2 --
> drivers/net/Makefile | 1 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/{ => ethernet}/sfc/Kconfig | 0
> drivers/net/{ => ethernet}/sfc/Makefile | 0
> drivers/net/{ => ethernet}/sfc/bitfield.h | 0
> drivers/net/{ => ethernet}/sfc/efx.c | 0
> drivers/net/{ => ethernet}/sfc/efx.h | 0
> drivers/net/{ => ethernet}/sfc/enum.h | 0
> drivers/net/{ => ethernet}/sfc/ethtool.c | 0
> drivers/net/{ => ethernet}/sfc/falcon.c | 0
> drivers/net/{ => ethernet}/sfc/falcon_boards.c | 0
> drivers/net/{ => ethernet}/sfc/falcon_xmac.c | 0
> drivers/net/{ => ethernet}/sfc/filter.c | 0
> drivers/net/{ => ethernet}/sfc/filter.h | 0
> drivers/net/{ => ethernet}/sfc/io.h | 0
> drivers/net/{ => ethernet}/sfc/mac.h | 0
> drivers/net/{ => ethernet}/sfc/mcdi.c | 0
> drivers/net/{ => ethernet}/sfc/mcdi.h | 0
> drivers/net/{ => ethernet}/sfc/mcdi_mac.c | 0
> drivers/net/{ => ethernet}/sfc/mcdi_pcol.h | 0
> drivers/net/{ => ethernet}/sfc/mcdi_phy.c | 0
> drivers/net/{ => ethernet}/sfc/mdio_10g.c | 0
> drivers/net/{ => ethernet}/sfc/mdio_10g.h | 0
> drivers/net/{ => ethernet}/sfc/mtd.c | 0
> drivers/net/{ => ethernet}/sfc/net_driver.h | 0
> drivers/net/{ => ethernet}/sfc/nic.c | 0
> drivers/net/{ => ethernet}/sfc/nic.h | 0
> drivers/net/{ => ethernet}/sfc/phy.h | 0
> drivers/net/{ => ethernet}/sfc/qt202x_phy.c | 0
> drivers/net/{ => ethernet}/sfc/regs.h | 0
> drivers/net/{ => ethernet}/sfc/rx.c | 0
> drivers/net/{ => ethernet}/sfc/selftest.c | 0
> drivers/net/{ => ethernet}/sfc/selftest.h | 0
> drivers/net/{ => ethernet}/sfc/siena.c | 0
> drivers/net/{ => ethernet}/sfc/spi.h | 0
> drivers/net/{ => ethernet}/sfc/tenxpress.c | 0
> drivers/net/{ => ethernet}/sfc/tx.c | 0
> drivers/net/{ => ethernet}/sfc/txc43128_phy.c | 0
> drivers/net/{ => ethernet}/sfc/workarounds.h | 0
> 42 files changed, 3 insertions(+), 4 deletions(-)
>
> commit a9f8e9475d4f7c91880050634e923d62e369a0ed
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Thu May 12 23:04:46 2011 -0700
>
> cassini/niu/sun*: Move the Sun drivers
>
> Moves the Sun drivers into drivers/net/ethernet/sun/ and make
> the necessary Kconfig and Makefile changes.
>
> CC: Sam Creasey <sammy@sammy.net>
> CC: Adrian Sun <asun@darksunrising.com>
> CC: Benjamin Herrenscmidt <benh@kernel.crashing.org>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 1 +
> drivers/net/Kconfig | 75 ----------------------
> drivers/net/Makefile | 10 +---
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/sun/Kconfig | 91 +++++++++++++++++++++++++++
> drivers/net/ethernet/sun/Makefile | 12 ++++
> drivers/net/{ => ethernet/sun}/cassini.c | 0
> drivers/net/{ => ethernet/sun}/cassini.h | 0
> drivers/net/{ => ethernet/sun}/niu.c | 0
> drivers/net/{ => ethernet/sun}/niu.h | 0
> drivers/net/{ => ethernet/sun}/sun3_82586.c | 0
> drivers/net/{ => ethernet/sun}/sun3_82586.h | 0
> drivers/net/{ => ethernet/sun}/sunbmac.c | 0
> drivers/net/{ => ethernet/sun}/sunbmac.h | 0
> drivers/net/{ => ethernet/sun}/sungem.c | 0
> drivers/net/{ => ethernet/sun}/sungem.h | 0
> drivers/net/{ => ethernet/sun}/sungem_phy.c | 0
> drivers/net/{ => ethernet/sun}/sungem_phy.h | 0
> drivers/net/{ => ethernet/sun}/sunhme.c | 0
> drivers/net/{ => ethernet/sun}/sunhme.h | 0
> drivers/net/{ => ethernet/sun}/sunqe.c | 0
> drivers/net/{ => ethernet/sun}/sunqe.h | 0
> drivers/net/{ => ethernet/sun}/sunvnet.c | 0
> drivers/net/{ => ethernet/sun}/sunvnet.h | 0
> drivers/net/spider_net.h | 2 +-
> 26 files changed, 108 insertions(+), 85 deletions(-)
>
> commit c1b4800864efcbacb0f02047609b41c9ab5290e6
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Thu May 12 21:21:33 2011 -0700
>
> ni5*/ni65: Move the Racal-Interlan (Micom) drivers
>
> Moves the Racal-Interlan drivers into drivers/net/ethernet/racal/ and
> make the necessary Kconfig and Makefile changes.
>
> CC: "Jan-Pascal van Best" <janpascal@vanbest.org>
> CC: Andreas Mohr <andi@lisas.de>
> CC: "M.Hipp" <hippm@informatik.uni-tuebingen.de>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 2 +-
> drivers/net/Kconfig | 47 ---------------------------
> drivers/net/Makefile | 3 --
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/racal/Kconfig | 50 +++++++++++++++++++++++++++++
> drivers/net/ethernet/racal/Makefile | 7 ++++
> drivers/net/{ => ethernet/racal}/ni5010.c | 0
> drivers/net/{ => ethernet/racal}/ni5010.h | 0
> drivers/net/{ => ethernet/racal}/ni52.c | 0
> drivers/net/{ => ethernet/racal}/ni52.h | 0
> drivers/net/{ => ethernet/racal}/ni65.c | 0
> drivers/net/{ => ethernet/racal}/ni65.h | 0
> 13 files changed, 60 insertions(+), 51 deletions(-)
>
> commit 671dc5b8fb145ff8748cdc2aeffd1ef56af8bd67
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Thu May 12 20:21:07 2011 -0700
>
> smc: Move the SMC drivers
>
> Moves the SMC drivers into drivers/net/ethernet/smc/ and the
> necessary Kconfig and Makefile changes. Also did some cleanup
> of NET_VENDOR_SMC Kconfig tag for the 8390 based drivers.
>
> CC: Nicolas Pitre <nico@fluxnic.net>
> CC: Donald Becker <becker@scyld.com>
> CC: Erik Stahlman <erik@vt.edu>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 2 +-
> drivers/net/Kconfig | 51 -------------------------
> drivers/net/Makefile | 4 --
> drivers/net/ethernet/8390/Kconfig | 21 ++--------
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/qlogic/Kconfig | 7 +++
> drivers/net/ethernet/qlogic/Makefile | 1 +
> drivers/net/ethernet/smc/Kconfig | 61 ++++++++++++++++++++++++++++++
> drivers/net/ethernet/smc/Makefile | 7 +++
> drivers/net/{ => ethernet/smc}/epic100.c | 0
> drivers/net/{ => ethernet/smc}/smc9194.c | 0
> drivers/net/{ => ethernet/smc}/smc9194.h | 0
> drivers/net/{ => ethernet/smc}/smc91x.c | 0
> drivers/net/{ => ethernet/smc}/smc91x.h | 0
> 15 files changed, 83 insertions(+), 73 deletions(-)
>
> commit e9f8a5c9b5f8f469bcfae06ddd10e9dc9537f7bb
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Fri Apr 8 19:06:30 2011 -0700
>
> qlogic: Move the QLogic drivers
>
> Moves the QLogic drivers into drivers/net/ethernet/qlogic/ and
> the necessary Kconfig and Makefile changes.
>
> CC: Ron Mercer <ron.mercer@qlogic.com>
> CC: Amit Kumar Salecha <amit.salecha@qlogic.com>
> CC: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 6 +-
> drivers/net/Kconfig | 26 ------------
> drivers/net/Makefile | 3 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/qlogic/Kconfig | 42 ++++++++++++++++++++
> drivers/net/ethernet/qlogic/Makefile | 7 +++
> drivers/net/{ => ethernet/qlogic}/netxen/Makefile | 0
> .../net/{ => ethernet/qlogic}/netxen/netxen_nic.h | 0
> .../{ => ethernet/qlogic}/netxen/netxen_nic_ctx.c | 0
> .../qlogic}/netxen/netxen_nic_ethtool.c | 0
> .../{ => ethernet/qlogic}/netxen/netxen_nic_hdr.h | 0
> .../{ => ethernet/qlogic}/netxen/netxen_nic_hw.c | 0
> .../{ => ethernet/qlogic}/netxen/netxen_nic_hw.h | 0
> .../{ => ethernet/qlogic}/netxen/netxen_nic_init.c | 0
> .../{ => ethernet/qlogic}/netxen/netxen_nic_main.c | 0
> drivers/net/{ => ethernet/qlogic}/qla3xxx.c | 0
> drivers/net/{ => ethernet/qlogic}/qla3xxx.h | 0
> drivers/net/{ => ethernet/qlogic}/qlcnic/Makefile | 0
> drivers/net/{ => ethernet/qlogic}/qlcnic/qlcnic.h | 0
> .../net/{ => ethernet/qlogic}/qlcnic/qlcnic_ctx.c | 0
> .../{ => ethernet/qlogic}/qlcnic/qlcnic_ethtool.c | 0
> .../net/{ => ethernet/qlogic}/qlcnic/qlcnic_hdr.h | 0
> .../net/{ => ethernet/qlogic}/qlcnic/qlcnic_hw.c | 0
> .../net/{ => ethernet/qlogic}/qlcnic/qlcnic_init.c | 0
> .../net/{ => ethernet/qlogic}/qlcnic/qlcnic_main.c | 0
> drivers/net/{ => ethernet/qlogic}/qlge/Makefile | 0
> drivers/net/{ => ethernet/qlogic}/qlge/qlge.h | 0
> drivers/net/{ => ethernet/qlogic}/qlge/qlge_dbg.c | 0
> .../net/{ => ethernet/qlogic}/qlge/qlge_ethtool.c | 0
> drivers/net/{ => ethernet/qlogic}/qlge/qlge_main.c | 0
> drivers/net/{ => ethernet/qlogic}/qlge/qlge_mpi.c | 0
> 32 files changed, 54 insertions(+), 32 deletions(-)
>
> commit f8e68b0056ef20887bdfdc31ff061d67e81308e2
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Thu Apr 7 07:42:33 2011 -0700
>
> intel: Move the Intel wired LAN drivers
>
> Moves the Intel wired LAN drivers into drivers/net/ethernet/intel/ and
> the necessary Kconfig and Makefile changes.
>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 11 +-
> drivers/net/Kconfig | 200 ------------------
> drivers/net/Makefile | 8 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/intel/Kconfig | 216 ++++++++++++++++++++
> drivers/net/ethernet/intel/Makefile | 12 +
> drivers/net/{ => ethernet/intel}/e100.c | 0
> drivers/net/{ => ethernet/intel}/e1000/Makefile | 0
> drivers/net/{ => ethernet/intel}/e1000/e1000.h | 0
> .../net/{ => ethernet/intel}/e1000/e1000_ethtool.c | 0
> drivers/net/{ => ethernet/intel}/e1000/e1000_hw.c | 0
> drivers/net/{ => ethernet/intel}/e1000/e1000_hw.h | 0
> .../net/{ => ethernet/intel}/e1000/e1000_main.c | 0
> .../net/{ => ethernet/intel}/e1000/e1000_osdep.h | 0
> .../net/{ => ethernet/intel}/e1000/e1000_param.c | 0
> .../intel/e1000e/80003es2lan.c} | 0
> drivers/net/{ => ethernet/intel}/e1000e/82571.c | 0
> drivers/net/{ => ethernet/intel}/e1000e/Makefile | 2 +-
> drivers/net/{ => ethernet/intel}/e1000e/defines.h | 0
> drivers/net/{ => ethernet/intel}/e1000e/e1000.h | 0
> drivers/net/{ => ethernet/intel}/e1000e/ethtool.c | 0
> drivers/net/{ => ethernet/intel}/e1000e/hw.h | 0
> drivers/net/{ => ethernet/intel}/e1000e/ich8lan.c | 0
> drivers/net/{ => ethernet/intel}/e1000e/lib.c | 0
> drivers/net/{ => ethernet/intel}/e1000e/netdev.c | 0
> drivers/net/{ => ethernet/intel}/e1000e/param.c | 0
> drivers/net/{ => ethernet/intel}/e1000e/phy.c | 0
> drivers/net/{ => ethernet/intel}/igb/Makefile | 0
> drivers/net/{ => ethernet/intel}/igb/e1000_82575.c | 0
> drivers/net/{ => ethernet/intel}/igb/e1000_82575.h | 0
> .../net/{ => ethernet/intel}/igb/e1000_defines.h | 0
> drivers/net/{ => ethernet/intel}/igb/e1000_hw.h | 0
> drivers/net/{ => ethernet/intel}/igb/e1000_mac.c | 0
> drivers/net/{ => ethernet/intel}/igb/e1000_mac.h | 0
> drivers/net/{ => ethernet/intel}/igb/e1000_mbx.c | 0
> drivers/net/{ => ethernet/intel}/igb/e1000_mbx.h | 0
> drivers/net/{ => ethernet/intel}/igb/e1000_nvm.c | 0
> drivers/net/{ => ethernet/intel}/igb/e1000_nvm.h | 0
> drivers/net/{ => ethernet/intel}/igb/e1000_phy.c | 0
> drivers/net/{ => ethernet/intel}/igb/e1000_phy.h | 0
> drivers/net/{ => ethernet/intel}/igb/e1000_regs.h | 0
> drivers/net/{ => ethernet/intel}/igb/igb.h | 0
> drivers/net/{ => ethernet/intel}/igb/igb_ethtool.c | 0
> drivers/net/{ => ethernet/intel}/igb/igb_main.c | 0
> drivers/net/{ => ethernet/intel}/igbvf/Makefile | 0
> drivers/net/{ => ethernet/intel}/igbvf/defines.h | 0
> drivers/net/{ => ethernet/intel}/igbvf/ethtool.c | 0
> drivers/net/{ => ethernet/intel}/igbvf/igbvf.h | 0
> drivers/net/{ => ethernet/intel}/igbvf/mbx.c | 0
> drivers/net/{ => ethernet/intel}/igbvf/mbx.h | 0
> drivers/net/{ => ethernet/intel}/igbvf/netdev.c | 0
> drivers/net/{ => ethernet/intel}/igbvf/regs.h | 0
> drivers/net/{ => ethernet/intel}/igbvf/vf.c | 0
> drivers/net/{ => ethernet/intel}/igbvf/vf.h | 0
> drivers/net/{ => ethernet/intel}/ixgb/Makefile | 0
> drivers/net/{ => ethernet/intel}/ixgb/ixgb.h | 0
> drivers/net/{ => ethernet/intel}/ixgb/ixgb_ee.c | 0
> drivers/net/{ => ethernet/intel}/ixgb/ixgb_ee.h | 0
> .../net/{ => ethernet/intel}/ixgb/ixgb_ethtool.c | 0
> drivers/net/{ => ethernet/intel}/ixgb/ixgb_hw.c | 0
> drivers/net/{ => ethernet/intel}/ixgb/ixgb_hw.h | 0
> drivers/net/{ => ethernet/intel}/ixgb/ixgb_ids.h | 0
> drivers/net/{ => ethernet/intel}/ixgb/ixgb_main.c | 0
> drivers/net/{ => ethernet/intel}/ixgb/ixgb_osdep.h | 0
> drivers/net/{ => ethernet/intel}/ixgb/ixgb_param.c | 0
> drivers/net/{ => ethernet/intel}/ixgbe/Makefile | 0
> drivers/net/{ => ethernet/intel}/ixgbe/ixgbe.h | 0
> .../net/{ => ethernet/intel}/ixgbe/ixgbe_82598.c | 0
> .../net/{ => ethernet/intel}/ixgbe/ixgbe_82599.c | 0
> .../net/{ => ethernet/intel}/ixgbe/ixgbe_common.c | 0
> .../net/{ => ethernet/intel}/ixgbe/ixgbe_common.h | 0
> drivers/net/{ => ethernet/intel}/ixgbe/ixgbe_dcb.c | 0
> drivers/net/{ => ethernet/intel}/ixgbe/ixgbe_dcb.h | 0
> .../{ => ethernet/intel}/ixgbe/ixgbe_dcb_82598.c | 0
> .../{ => ethernet/intel}/ixgbe/ixgbe_dcb_82598.h | 0
> .../{ => ethernet/intel}/ixgbe/ixgbe_dcb_82599.c | 0
> .../{ => ethernet/intel}/ixgbe/ixgbe_dcb_82599.h | 0
> .../net/{ => ethernet/intel}/ixgbe/ixgbe_dcb_nl.c | 0
> .../net/{ => ethernet/intel}/ixgbe/ixgbe_ethtool.c | 0
> .../net/{ => ethernet/intel}/ixgbe/ixgbe_fcoe.c | 0
> .../net/{ => ethernet/intel}/ixgbe/ixgbe_fcoe.h | 0
> .../net/{ => ethernet/intel}/ixgbe/ixgbe_main.c | 0
> drivers/net/{ => ethernet/intel}/ixgbe/ixgbe_mbx.c | 0
> drivers/net/{ => ethernet/intel}/ixgbe/ixgbe_mbx.h | 0
> drivers/net/{ => ethernet/intel}/ixgbe/ixgbe_phy.c | 0
> drivers/net/{ => ethernet/intel}/ixgbe/ixgbe_phy.h | 0
> .../net/{ => ethernet/intel}/ixgbe/ixgbe_sriov.c | 0
> .../net/{ => ethernet/intel}/ixgbe/ixgbe_sriov.h | 0
> .../net/{ => ethernet/intel}/ixgbe/ixgbe_type.h | 0
> .../net/{ => ethernet/intel}/ixgbe/ixgbe_x540.c | 0
> drivers/net/{ => ethernet/intel}/ixgbevf/Makefile | 0
> drivers/net/{ => ethernet/intel}/ixgbevf/defines.h | 0
> drivers/net/{ => ethernet/intel}/ixgbevf/ethtool.c | 0
> drivers/net/{ => ethernet/intel}/ixgbevf/ixgbevf.h | 0
> .../{ => ethernet/intel}/ixgbevf/ixgbevf_main.c | 0
> drivers/net/{ => ethernet/intel}/ixgbevf/mbx.c | 0
> drivers/net/{ => ethernet/intel}/ixgbevf/mbx.h | 0
> drivers/net/{ => ethernet/intel}/ixgbevf/regs.h | 0
> drivers/net/{ => ethernet/intel}/ixgbevf/vf.c | 0
> drivers/net/{ => ethernet/intel}/ixgbevf/vf.h | 0
> 101 files changed, 233 insertions(+), 218 deletions(-)
>
> commit e9518ae90966c061c0efa161e885ba23bda6c0a8
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Thu Apr 7 06:57:17 2011 -0700
>
> chelsio: Move the Chelsio drivers
>
> Moves the drivers for the Chelsio chipsets into
> drivers/net/ethernet/chelsio/ and the necessary Kconfig and Makefile
> changes.
>
> CC: Divy Le Ray <divy@chelsio.com>
> CC: Dimitris Michailidis <dm@chelsio.com>
> CC: Casey Leedom <leedom@chelsio.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 6 +-
> drivers/net/Kconfig | 86 ----------------
> drivers/net/Makefile | 4 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/chelsio/Kconfig | 102 ++++++++++++++++++++
> drivers/net/ethernet/chelsio/Makefile | 8 ++
> .../{chelsio => ethernet/chelsio/cxgb}/Makefile | 0
> .../{chelsio => ethernet/chelsio/cxgb}/common.h | 0
> .../net/{chelsio => ethernet/chelsio/cxgb}/cphy.h | 0
> .../{chelsio => ethernet/chelsio/cxgb}/cpl5_cmd.h | 0
> .../net/{chelsio => ethernet/chelsio/cxgb}/cxgb2.c | 0
> .../{chelsio => ethernet/chelsio/cxgb}/elmer0.h | 0
> .../net/{chelsio => ethernet/chelsio/cxgb}/espi.c | 0
> .../net/{chelsio => ethernet/chelsio/cxgb}/espi.h | 0
> .../{chelsio => ethernet/chelsio/cxgb}/fpga_defs.h | 0
> .../net/{chelsio => ethernet/chelsio/cxgb}/gmac.h | 0
> .../{chelsio => ethernet/chelsio/cxgb}/mv88e1xxx.c | 0
> .../{chelsio => ethernet/chelsio/cxgb}/mv88e1xxx.h | 0
> .../{chelsio => ethernet/chelsio/cxgb}/mv88x201x.c | 0
> .../{chelsio => ethernet/chelsio/cxgb}/my3126.c | 0
> .../{chelsio => ethernet/chelsio/cxgb}/pm3393.c | 0
> .../net/{chelsio => ethernet/chelsio/cxgb}/regs.h | 0
> .../net/{chelsio => ethernet/chelsio/cxgb}/sge.c | 0
> .../net/{chelsio => ethernet/chelsio/cxgb}/sge.h | 0
> .../net/{chelsio => ethernet/chelsio/cxgb}/subr.c | 0
> .../chelsio/cxgb}/suni1x10gexp_regs.h | 0
> .../net/{chelsio => ethernet/chelsio/cxgb}/tp.c | 0
> .../net/{chelsio => ethernet/chelsio/cxgb}/tp.h | 0
> .../{chelsio => ethernet/chelsio/cxgb}/vsc7326.c | 0
> .../chelsio/cxgb}/vsc7326_reg.h | 0
> drivers/net/{ => ethernet/chelsio}/cxgb3/Makefile | 0
> drivers/net/{ => ethernet/chelsio}/cxgb3/adapter.h | 0
> drivers/net/{ => ethernet/chelsio}/cxgb3/ael1002.c | 0
> drivers/net/{ => ethernet/chelsio}/cxgb3/aq100x.c | 0
> drivers/net/{ => ethernet/chelsio}/cxgb3/common.h | 0
> .../{ => ethernet/chelsio}/cxgb3/cxgb3_ctl_defs.h | 0
> .../net/{ => ethernet/chelsio}/cxgb3/cxgb3_defs.h | 0
> .../net/{ => ethernet/chelsio}/cxgb3/cxgb3_ioctl.h | 0
> .../net/{ => ethernet/chelsio}/cxgb3/cxgb3_main.c | 0
> .../{ => ethernet/chelsio}/cxgb3/cxgb3_offload.c | 0
> .../{ => ethernet/chelsio}/cxgb3/cxgb3_offload.h | 0
> .../chelsio}/cxgb3/firmware_exports.h | 0
> drivers/net/{ => ethernet/chelsio}/cxgb3/l2t.c | 0
> drivers/net/{ => ethernet/chelsio}/cxgb3/l2t.h | 0
> drivers/net/{ => ethernet/chelsio}/cxgb3/mc5.c | 0
> drivers/net/{ => ethernet/chelsio}/cxgb3/regs.h | 0
> drivers/net/{ => ethernet/chelsio}/cxgb3/sge.c | 0
> .../net/{ => ethernet/chelsio}/cxgb3/sge_defs.h | 0
> drivers/net/{ => ethernet/chelsio}/cxgb3/t3_cpl.h | 0
> drivers/net/{ => ethernet/chelsio}/cxgb3/t3_hw.c | 0
> drivers/net/{ => ethernet/chelsio}/cxgb3/t3cdev.h | 0
> drivers/net/{ => ethernet/chelsio}/cxgb3/version.h | 0
> drivers/net/{ => ethernet/chelsio}/cxgb3/vsc8211.c | 0
> drivers/net/{ => ethernet/chelsio}/cxgb3/xgmac.c | 0
> drivers/net/{ => ethernet/chelsio}/cxgb4/Makefile | 0
> drivers/net/{ => ethernet/chelsio}/cxgb4/cxgb4.h | 0
> .../net/{ => ethernet/chelsio}/cxgb4/cxgb4_main.c | 0
> .../net/{ => ethernet/chelsio}/cxgb4/cxgb4_uld.h | 0
> drivers/net/{ => ethernet/chelsio}/cxgb4/l2t.c | 0
> drivers/net/{ => ethernet/chelsio}/cxgb4/l2t.h | 0
> drivers/net/{ => ethernet/chelsio}/cxgb4/sge.c | 0
> drivers/net/{ => ethernet/chelsio}/cxgb4/t4_hw.c | 0
> drivers/net/{ => ethernet/chelsio}/cxgb4/t4_hw.h | 0
> drivers/net/{ => ethernet/chelsio}/cxgb4/t4_msg.h | 0
> drivers/net/{ => ethernet/chelsio}/cxgb4/t4_regs.h | 0
> .../net/{ => ethernet/chelsio}/cxgb4/t4fw_api.h | 0
> .../net/{ => ethernet/chelsio}/cxgb4vf/Makefile | 0
> .../net/{ => ethernet/chelsio}/cxgb4vf/adapter.h | 0
> .../{ => ethernet/chelsio}/cxgb4vf/cxgb4vf_main.c | 0
> drivers/net/{ => ethernet/chelsio}/cxgb4vf/sge.c | 0
> .../{ => ethernet/chelsio}/cxgb4vf/t4vf_common.h | 0
> .../net/{ => ethernet/chelsio}/cxgb4vf/t4vf_defs.h | 0
> .../net/{ => ethernet/chelsio}/cxgb4vf/t4vf_hw.c | 0
> 74 files changed, 115 insertions(+), 93 deletions(-)
>
> commit 1e954aa058cd1496b47b914878509e9ecf136d05
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Thu Apr 7 06:03:04 2011 -0700
>
> broadcom: Move the Broadcom drivers
>
> Moves the drivers for Broadcom devices into
> drivers/net/ethernet/broadcom/ and the necessary Kconfig and Makefile
> changes.
>
> CC: Eilon Greenstein <eilong@broadcom.com>
> CC: Michael Chan <mchan@broadcom.com>
> CC: Matt Carlson <mcarlson@broadcom.com>
> CC: Gary Zambrano <zambrano@broadcom.com>
> CC: "Maciej W. Rozycki" <macro@linux-mips.org>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 10 +-
> drivers/net/Kconfig | 99 -----------------
> drivers/net/Makefile | 7 --
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/broadcom/Kconfig | 114 ++++++++++++++++++++
> drivers/net/ethernet/broadcom/Makefile | 11 ++
> drivers/net/{ => ethernet/broadcom}/b44.c | 0
> drivers/net/{ => ethernet/broadcom}/b44.h | 0
> drivers/net/{ => ethernet/broadcom}/bcm63xx_enet.c | 0
> drivers/net/{ => ethernet/broadcom}/bcm63xx_enet.h | 0
> drivers/net/{ => ethernet/broadcom}/bnx2.c | 0
> drivers/net/{ => ethernet/broadcom}/bnx2.h | 0
> drivers/net/{ => ethernet/broadcom}/bnx2_fw.h | 0
> drivers/net/{ => ethernet/broadcom}/bnx2x/Makefile | 0
> drivers/net/{ => ethernet/broadcom}/bnx2x/bnx2x.h | 0
> .../net/{ => ethernet/broadcom}/bnx2x/bnx2x_cmn.c | 0
> .../net/{ => ethernet/broadcom}/bnx2x/bnx2x_cmn.h | 0
> .../net/{ => ethernet/broadcom}/bnx2x/bnx2x_dcb.c | 0
> .../net/{ => ethernet/broadcom}/bnx2x/bnx2x_dcb.h | 0
> .../net/{ => ethernet/broadcom}/bnx2x/bnx2x_dump.h | 0
> .../{ => ethernet/broadcom}/bnx2x/bnx2x_ethtool.c | 0
> .../{ => ethernet/broadcom}/bnx2x/bnx2x_fw_defs.h | 0
> .../broadcom}/bnx2x/bnx2x_fw_file_hdr.h | 0
> .../net/{ => ethernet/broadcom}/bnx2x/bnx2x_hsi.h | 0
> .../net/{ => ethernet/broadcom}/bnx2x/bnx2x_init.h | 0
> .../{ => ethernet/broadcom}/bnx2x/bnx2x_init_ops.h | 0
> .../net/{ => ethernet/broadcom}/bnx2x/bnx2x_link.c | 0
> .../net/{ => ethernet/broadcom}/bnx2x/bnx2x_link.h | 0
> .../net/{ => ethernet/broadcom}/bnx2x/bnx2x_main.c | 0
> .../net/{ => ethernet/broadcom}/bnx2x/bnx2x_reg.h | 0
> .../{ => ethernet/broadcom}/bnx2x/bnx2x_stats.c | 0
> .../{ => ethernet/broadcom}/bnx2x/bnx2x_stats.h | 0
> drivers/net/{ => ethernet/broadcom}/cnic.c | 4 +-
> drivers/net/{ => ethernet/broadcom}/cnic.h | 0
> drivers/net/{ => ethernet/broadcom}/cnic_defs.h | 0
> drivers/net/{ => ethernet/broadcom}/cnic_if.h | 0
> drivers/net/{ => ethernet/broadcom}/sb1250-mac.c | 0
> drivers/net/{ => ethernet/broadcom}/tg3.c | 0
> drivers/net/{ => ethernet/broadcom}/tg3.h | 0
> 40 files changed, 134 insertions(+), 113 deletions(-)
>
> commit 29072561a23c3802112a94fa0a9383773056f19a
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Sat Apr 2 06:20:12 2011 -0700
>
> 8390: Move the 8390 related drivers
>
> Moves the drivers for the National Semi-conductor 8390 chipset into
> drivers/net/ethernet/8390/ and the necessary Kconfig and Makefile
> changes.
>
> CC: Donald Becker <becker@scyld.com>
> CC: Paul Gortmaker <paul.gortmaker@windriver.com>
> CC: Alain Malek <alain.malek@cryogen.com>
> CC: Peter De Schrijver <p2@mind.be>
> CC: "David Huggins-Daines" <dhd@debian.org>
> CC: Wim Dumon <wimpie@kotnet.org>
> CC: Yoshinori Sato <ysato@users.sourceforge.jp>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 5 +-
> drivers/net/Kconfig | 283 -----------------------
> drivers/net/Makefile | 22 --
> drivers/net/ethernet/3com/Makefile | 2 +-
> drivers/net/{ => ethernet/8390}/8390.c | 0
> drivers/net/{ => ethernet/8390}/8390.h | 0
> drivers/net/{ => ethernet/8390}/8390p.c | 0
> drivers/net/ethernet/8390/Kconfig | 301 +++++++++++++++++++++++++
> drivers/net/ethernet/8390/Makefile | 26 +++
> drivers/net/{ => ethernet/8390}/ac3200.c | 0
> drivers/net/{ => ethernet/8390}/apne.c | 0
> drivers/net/{ => ethernet/8390}/ax88796.c | 0
> drivers/net/{ => ethernet/8390}/e2100.c | 0
> drivers/net/{ => ethernet/8390}/es3210.c | 0
> drivers/net/{ => ethernet/8390}/hp-plus.c | 0
> drivers/net/{ => ethernet/8390}/hp.c | 0
> drivers/net/{ => ethernet/8390}/hydra.c | 0
> drivers/net/{ => ethernet/8390}/lib8390.c | 0
> drivers/net/{ => ethernet/8390}/lne390.c | 0
> drivers/net/{ => ethernet/8390}/mac8390.c | 0
> drivers/net/{ => ethernet/8390}/ne-h8300.c | 0
> drivers/net/{ => ethernet/8390}/ne.c | 0
> drivers/net/{ => ethernet/8390}/ne2k-pci.c | 0
> drivers/net/{ => ethernet/8390}/ne3210.c | 0
> drivers/net/{ => ethernet/8390}/smc-mca.c | 0
> drivers/net/{ => ethernet/8390}/smc-ultra.c | 0
> drivers/net/{ => ethernet/8390}/smc-ultra32.c | 0
> drivers/net/{ => ethernet/8390}/stnic.c | 0
> drivers/net/{ => ethernet/8390}/wd.c | 0
> drivers/net/{ => ethernet/8390}/zorro8390.c | 0
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> 32 files changed, 332 insertions(+), 309 deletions(-)
>
> commit 6b9ef2886e37d62018cd72dcdd2918e9fb982aed
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Wed Mar 30 07:46:36 2011 -0700
>
> amd8111e/pcnet32/*lance/mvme147: Move AMD chipset drivers
>
> Moves the drivers for the AMD chipsets into drivers/net/ethernet/amd/
> and the necessary Kconfig and Makfile changes.
>
> CC: Peter Maydell <pmaydell@chiark.greenend.org.uk>
> CC: Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
> CC: "Maciej W. Rozycki" <macro@linux-mips.org>
> CC: Donald Becker <becker@scyld.com>
> CC: Sam Creasey <sammy@users.qual.net>
> CC: Miguel de Icaza <miguel@nuclecu.unam.mx>
> CC: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> drivers/net/Kconfig | 99 -----------------------
> drivers/net/Makefile | 9 --
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/{ => ethernet/amd}/7990.c | 0
> drivers/net/{ => ethernet/amd}/7990.h | 0
> drivers/net/ethernet/amd/Kconfig | 115 +++++++++++++++++++++++++++
> drivers/net/ethernet/amd/Makefile | 13 +++
> drivers/net/{ => ethernet/amd}/amd8111e.c | 0
> drivers/net/{ => ethernet/amd}/amd8111e.h | 0
> drivers/net/{ => ethernet/amd}/atarilance.c | 0
> drivers/net/{ => ethernet/amd}/declance.c | 0
> drivers/net/{ => ethernet/amd}/hplance.c | 0
> drivers/net/{ => ethernet/amd}/hplance.h | 0
> drivers/net/{ => ethernet/amd}/lance.c | 0
> drivers/net/{ => ethernet/amd}/mvme147.c | 0
> drivers/net/{ => ethernet/amd}/pcnet32.c | 0
> drivers/net/{ => ethernet/amd}/sun3lance.c | 0
> drivers/net/{ => ethernet/amd}/sunlance.c | 0
> 19 files changed, 130 insertions(+), 108 deletions(-)
>
> commit b2ee2cf62d14c842272db622d6be6374bc6d622a
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Wed Mar 30 03:47:06 2011 -0700
>
> 3c*/acenic/typhoon: Move 3Com Ethernet drivers
>
> Moves the 3Com drivers into drivers/net/ethernet/3com/ and the necessary
> Kconfig and Makefile changes.
>
> CC: Philip Blundell <philb@gnu.org>
> CC: Steffen Klassert <klassert@mathematik.tu-chemnitz.de>
> CC: David Dillow <dave@thedillows.org>
> CC: Jes Sorensen <jes@trained-monkey.org>
> CC: Alan Cox <alan@linux.intel.com>
> CC: Donald Becker <becker@scyld.com>
> CC: Craig Southeren <craigs@ineluki.apana.org.au>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 8 +-
> drivers/net/Kconfig | 177 ----------------------------
> drivers/net/Makefile | 12 +--
> drivers/net/{ => ethernet/3com}/3c501.c | 0
> drivers/net/{ => ethernet/3com}/3c501.h | 0
> drivers/net/{ => ethernet/3com}/3c503.c | 0
> drivers/net/{ => ethernet/3com}/3c503.h | 0
> drivers/net/{ => ethernet/3com}/3c505.c | 0
> drivers/net/{ => ethernet/3com}/3c505.h | 0
> drivers/net/{ => ethernet/3com}/3c507.c | 0
> drivers/net/{ => ethernet/3com}/3c509.c | 0
> drivers/net/{ => ethernet/3com}/3c515.c | 0
> drivers/net/{ => ethernet/3com}/3c523.c | 0
> drivers/net/{ => ethernet/3com}/3c523.h | 0
> drivers/net/{ => ethernet/3com}/3c527.c | 0
> drivers/net/{ => ethernet/3com}/3c527.h | 0
> drivers/net/{ => ethernet/3com}/3c59x.c | 0
> drivers/net/ethernet/3com/Kconfig | 180 +++++++++++++++++++++++++++++
> drivers/net/ethernet/3com/Makefile | 15 +++
> drivers/net/{ => ethernet/3com}/acenic.c | 0
> drivers/net/{ => ethernet/3com}/acenic.h | 0
> drivers/net/{ => ethernet/3com}/typhoon.c | 0
> drivers/net/{ => ethernet/3com}/typhoon.h | 0
> drivers/net/ethernet/Kconfig | 2 +
> drivers/net/ethernet/Makefile | 1 +
> 25 files changed, 203 insertions(+), 192 deletions(-)
>
> commit b918e3bb62b873c5436d413b99f593b3eed78901
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Tue Mar 29 18:25:21 2011 -0700
>
> drivers/net/ethernet: Add ethernet dir and config option
>
> This is the initial patch to organize the drivers/net directory
> structure and networking device driver config options. This patch
> does the following:
> - add drivers/net/ethernet/Kconfig
> - integrate the new files into the existing config
>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> drivers/net/Kconfig | 2 ++
> drivers/net/Makefile | 2 +-
> drivers/net/ethernet/Kconfig | 14 ++++++++++++++
> drivers/net/ethernet/Makefile | 4 ++++
> 4 files changed, 21 insertions(+), 1 deletions(-)
>
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* Re: [RFC] Moving files around in drivers/net
From: Jon Mason @ 2011-06-16 14:14 UTC (permalink / raw)
To: Joe Perches
Cc: Jeff Kirsher, netdev, David Miller, Paul Gortmaker,
Jan Engelhardt
In-Reply-To: <1308186619.12377.23.camel@Joe-Laptop>
On Wed, Jun 15, 2011 at 8:10 PM, Joe Perches <joe@perches.com> wrote:
> On Wed, 2011-06-15 at 11:38 -0700, Jeff Kirsher wrote:
>> On Wed, Jun 1, 2011 at 13:01, Joe Perches <joe@perches.com> wrote:
>> > On Wed, 2011-06-01 at 12:53 -0700, Jeff Kirsher wrote:
>> >> On Wed, 2011-06-01 at 12:30 -0700, Joe Perches wrote:
>> >> > Does anyone still think moving files around in drivers/net
>> >> > would be sensible and a suitable candidate for inclusion
>> >> > in 3.1?
>> >> > Here's what Jeffrey proposed:
>> >> > http://vger.kernel.org/netconf2010_slides/netconf-jtk.pdf
>> >> > Here's what I proposed before that.
>> >> > http://www.spinics.net/lists/netdev/msg149717.html
>> >> I am over 90% done with the work and have been trying to finish up the
>> >> patches so that I could get them out as an RFC here in the next week.
>> > Excellent, thanks.
>> I thought for sure I would have finished what I have left by last
>> weekend, but I keep getting interrupted. (Blame it on the NHL stanley
>> cup playoffs) :)
>> I have created a git tree on kernel.org with all the work that I have
>> completed so far (see below). This first stage of the move is only
>> taking care of the drivers. The next stage will move the networking
>> core drivers (bridging, bonding, vlan, etc.) into drivers/net/sw.
>> git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-organize
>> I will send out all the patches as an RFC by the end of the week (for sure)
>
> I've put the body of the git log below my comments
> to make it easier to discuss.
>
> Comments:
>
> pktgen in hamachi/yellowfin should be pkteng
>
> I think it might be better if:
>
> Things were more spelled out:
> pkteng should be packetengines
> And things maybe not spelled out
> ixp2000 might just be ixp (what not intel?:)
>
> And maybe drivers/net/ethernet/ should be as
> unpopulated as possible. Maybe create a misc
> directory and throw old unclassifiable junk there.
>
> Lance should be its own directory like 8390.
> I think a2065 and ariadne are lance drivers.
>
> Some manufacturer directories are directly populated
> with multiple drivers, some have subdirectories.
> Should one style be consistently used?
>
> pch_gbe should probably be oki.
>
> Isn't syskonnect now marvell?
>
> stmmac may not be a good name. Maybe stmicro.
>
> enic may not be a good name. Maybe cisco.
>
> mlx4 may be mellanox
>
> sfc may be solarflare
>
> bna may be brocade
>
> cheers, Joe
>
> $ git log --stat -M b7c7deeb4c77538577f0b6a724f10ce8693eb648..
> commit 743b1f134daef72805cb10e74d82dcbb95cd2568
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Tue Jun 14 14:02:57 2011 -0700
>
> hamachi/yellowfin: Move the packet engine drivers
>
> Move the packet engine drivers to drivers/net/ethernet/pktgen/ and
> the necessary Kconfig and Makefile changes.
>
> CC: Donald Becker <becker@scyld.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> drivers/net/Kconfig | 26 ---------------
> drivers/net/Makefile | 2 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/pkteng/Kconfig | 42 +++++++++++++++++++++++++
> drivers/net/ethernet/pkteng/Makefile | 6 +++
> drivers/net/{ => ethernet/pkteng}/hamachi.c | 0
> drivers/net/{ => ethernet/pkteng}/yellowfin.c | 0
> 8 files changed, 50 insertions(+), 28 deletions(-)
>
> commit a7ce0b86340574f90bd24c460c3495ae3e06f5fb
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Tue Jun 14 13:35:31 2011 -0700
>
> ixp2000: Move the Radisys driver
>
> Move the Radisys driver into drivers/net/ethernet/ixp2000/ and
> make the necessary Kconfig and Makefile changes
>
> CC: Lennert Buytenhek <kernel@wantstofly.org>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 2 +-
> drivers/net/Kconfig | 2 --
> drivers/net/Makefile | 1 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/{ => ethernet}/ixp2000/Kconfig | 0
> drivers/net/{ => ethernet}/ixp2000/Makefile | 0
> drivers/net/{ => ethernet}/ixp2000/caleb.c | 0
> drivers/net/{ => ethernet}/ixp2000/caleb.h | 0
> drivers/net/{ => ethernet}/ixp2000/enp2611.c | 0
> drivers/net/{ => ethernet}/ixp2000/ixp2400-msf.c | 0
> drivers/net/{ => ethernet}/ixp2000/ixp2400-msf.h | 0
> drivers/net/{ => ethernet}/ixp2000/ixp2400_rx.uc | 0
> .../net/{ => ethernet}/ixp2000/ixp2400_rx.ucode | 0
> drivers/net/{ => ethernet}/ixp2000/ixp2400_tx.uc | 0
> .../net/{ => ethernet}/ixp2000/ixp2400_tx.ucode | 0
> drivers/net/{ => ethernet}/ixp2000/ixpdev.c | 0
> drivers/net/{ => ethernet}/ixp2000/ixpdev.h | 0
> drivers/net/{ => ethernet}/ixp2000/ixpdev_priv.h | 0
> drivers/net/{ => ethernet}/ixp2000/pm3386.c | 0
> drivers/net/{ => ethernet}/ixp2000/pm3386.h | 0
> 21 files changed, 3 insertions(+), 4 deletions(-)
>
> commit 73091715bc0690f82ef9489f3589ad9b2d747cc0
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Tue Jun 14 12:56:50 2011 -0700
>
> tlan/cpmac: Move the TI drivers
>
> Move the TI drivers to drivers/net/ethernet/ti/ and make the
> necessary Kconfig and Makefile changes.
>
> CC: Samuel Chessman <chessman@tux.org>
> CC: <torben.mathiasen@compaq.com>
> CC: Eugene Konev <ejka@imfi.kspu.ru>
> CC: Florian Fainelli <florian@openwrt.org>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 4 +-
> drivers/net/Kconfig | 25 --------------------
> drivers/net/Makefile | 2 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/ti/Kconfig | 41 +++++++++++++++++++++++++++++++++
> drivers/net/ethernet/ti/Makefile | 6 +++++
> drivers/net/{ => ethernet/ti}/cpmac.c | 0
> drivers/net/{ => ethernet/ti}/tlan.c | 0
> drivers/net/{ => ethernet/ti}/tlan.h | 0
> 10 files changed, 51 insertions(+), 29 deletions(-)
>
> commit 035a452c66dbc0aa7873a12cfe057c74eaf89111
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Mon Jun 13 10:51:34 2011 -0700
>
> s6gmac/tsi108_eth: Move the s6gmac/tsi108_eth drivers
>
> Move the s6gmac/tsi108_eth drivers to drivers/net/ethernet/ and
> make the necessary Kconfig and Makefile changes.
>
> CC: Oskar Schirmer <os@emlix.com>
> CC: Kong Lai <kong.lai@tundra.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> drivers/net/Kconfig | 19 -------------------
> drivers/net/Makefile | 2 --
> drivers/net/ethernet/Kconfig | 21 +++++++++++++++++++++
> drivers/net/ethernet/Makefile | 2 ++
> drivers/net/{ => ethernet}/s6gmac.c | 0
> drivers/net/{ => ethernet}/tsi108_eth.c | 0
> drivers/net/{ => ethernet}/tsi108_eth.h | 0
> 7 files changed, 23 insertions(+), 21 deletions(-)
>
> commit 4f9d3b9af95ced49b9ad9d5fb222f5216bf0adbb
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Mon Jun 13 10:03:01 2011 -0700
>
> a2065/ariadne: Move the a2065/ariadne drivers
>
> Move the a2065/ariadne drivers to drivers/net/ethernet/ and make
> the necessary Kconfig and Makefile changes.
>
> CC: Geert Uytterhoeven <geert@linux-m68k.org>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> drivers/net/Kconfig | 21 ---------------------
> drivers/net/Makefile | 2 --
> drivers/net/ethernet/Kconfig | 23 +++++++++++++++++++++++
> drivers/net/ethernet/Makefile | 2 ++
> drivers/net/{ => ethernet}/a2065.c | 0
> drivers/net/{ => ethernet}/a2065.h | 0
> drivers/net/{ => ethernet}/ariadne.c | 0
> drivers/net/{ => ethernet}/ariadne.h | 0
> 8 files changed, 25 insertions(+), 23 deletions(-)
>
> commit aead66521a701f08e3ae91aec7c9c8863a07a511
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Mon Jun 13 09:43:17 2011 -0700
>
> 82586.c/fec*: Move the Motorola drivers
>
> Move the Motorola drivers into drivers/net/ethernet/motorola/ and
> make the necessary Kconfig and Makefile changes
>
> CC: Dan Malek <dmalek@jlc.net>
> CC: Sylvain Munaut <tnt@246tNt.com>
> CC: Richard Hirst <richard@sleepie.demon.co.uk>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> drivers/net/Kconfig | 49 --------------
> drivers/net/Makefile | 7 --
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/{ => ethernet/motorola}/82596.c | 0
> drivers/net/ethernet/motorola/Kconfig | 68 ++++++++++++++++++++
> drivers/net/ethernet/motorola/Makefile | 11 +++
> drivers/net/{ => ethernet/motorola}/fec.c | 0
> drivers/net/{ => ethernet/motorola}/fec.h | 0
> drivers/net/{ => ethernet/motorola}/fec_mpc52xx.c | 0
> drivers/net/{ => ethernet/motorola}/fec_mpc52xx.h | 0
> .../net/{ => ethernet/motorola}/fec_mpc52xx_phy.c | 0
> 12 files changed, 81 insertions(+), 56 deletions(-)
>
> commit aebcb70982c66b54605fbd242f6ac035b2e205b3
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Mon Jun 13 08:43:49 2011 -0700
>
> sis*: Move the Silicon Integrated Systems (SiS) drivers
>
> Move the SiS drivers into drivers/net/ethernet/sis/ and make the
> necessary Kconfig and Makefile changes
>
> CC: Daniele Venzano <venza@brownhat.org>
> CC: Francois Romieu <romieu@fr.zoreil.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 4 +-
> drivers/net/Kconfig | 30 --------------------
> drivers/net/Makefile | 2 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/sis/Kconfig | 46 +++++++++++++++++++++++++++++++
> drivers/net/ethernet/sis/Makefile | 6 ++++
> drivers/net/{ => ethernet/sis}/sis190.c | 0
> drivers/net/{ => ethernet/sis}/sis900.c | 0
> drivers/net/{ => ethernet/sis}/sis900.h | 0
> 10 files changed, 56 insertions(+), 34 deletions(-)
>
> commit 826bef22759e1f78b284c9dc53ea442d348dbc88
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Mon Jun 13 08:23:31 2011 -0700
>
> spider_net: Move the spider_net (IBM) driver
>
> Move the spider_net (IBM) driver into drivers/net/ethernet/ibm/ and
> make the necessary Kconfig and Makefile changes
>
> CC: Utz Bacher <utz.bacher@de.ibm.com>
> CC: Jens Osterkamp <Jens.Osterkamp@de.ibm.com>
> CC: Ishizaki Kou <kou.ishizaki@toshiba.co.jp>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 2 +-
> drivers/net/Kconfig | 8 --------
> drivers/net/Makefile | 2 --
> drivers/net/ethernet/ibm/Kconfig | 11 ++++++++++-
> drivers/net/ethernet/ibm/Makefile | 2 ++
> drivers/net/{ => ethernet/ibm}/spider_net.c | 0
> drivers/net/{ => ethernet/ibm}/spider_net.h | 2 +-
> .../net/{ => ethernet/ibm}/spider_net_ethtool.c | 0
> 8 files changed, 14 insertions(+), 13 deletions(-)
>
> commit 776fae874e79c3bf3b6fd81eceb23993fef76c01
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Mon Jun 13 07:56:34 2011 -0700
>
> mv643xx/pxa168: Move the Marvell drivers
>
> Move the Marvell drivers into driver/net/ethernet/marvell and make
> the necessary Kconfig and Makefile changes.
>
> CC: Sachin Sanap <ssanap@marvell.com>
> CC: Zhangfei Gao <zgao6@marvell.com>
> CC: Philip Rakity <prakity@marvell.com>
> CC: Mark Brown <markb@marvell.com>
> CC: Lennert Buytenhek <buytenh@marvell.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 2 +-
> drivers/net/Kconfig | 23 ------------
> drivers/net/Makefile | 2 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/marvell/Kconfig | 40 ++++++++++++++++++++++
> drivers/net/ethernet/marvell/Makefile | 6 +++
> drivers/net/{ => ethernet/marvell}/mv643xx_eth.c | 0
> drivers/net/{ => ethernet/marvell}/pxa168_eth.c | 0
> 9 files changed, 49 insertions(+), 26 deletions(-)
>
> commit 4153aed9e3020693985219d471f8eb230a8eaefa
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Sat Jun 11 03:26:31 2011 -0700
>
> ks8*/ksz8*: Move the Micrel drivers
>
> Move the Micrel drivers into drivers/net/ethernet/micrel/ and
> make the necessary Kconfig and Makefile changes.
>
> CC: Ben Dooks <ben@simtec.co.uk>
> CC: Tristram Ha <Tristram.Ha@micrel.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> drivers/net/Kconfig | 35 ----------------
> drivers/net/Makefile | 4 --
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/micrel/Kconfig | 51 ++++++++++++++++++++++++
> drivers/net/ethernet/micrel/Makefile | 8 ++++
> drivers/net/{ => ethernet/micrel}/ks8842.c | 0
> drivers/net/{ => ethernet/micrel}/ks8851.c | 0
> drivers/net/{ => ethernet/micrel}/ks8851.h | 0
> drivers/net/{ => ethernet/micrel}/ks8851_mll.c | 0
> drivers/net/{ => ethernet/micrel}/ksz884x.c | 0
> 11 files changed, 61 insertions(+), 39 deletions(-)
>
> commit 518f5abc833cb0c30b79161c071b7c93ed458c6d
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Sat Jun 11 02:29:36 2011 -0700
>
> fsl_*/gianfar*/ucc_*: Move the Freescale drivers
>
> Move the Freescale driver into drivers/net/ethernet/freescale/ and
> make the necessary Kconfig and Makefile changes.
>
> CC: Sandeep Gopalpet <sandeep.kumar@freescale.com>
> CC: Andy Fleming <afleming@freescale.com>
> CC: Shlomi Gridish <gridish@freescale.com>
> CC: Li Yang <leoli@freescale.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 2 +-
> drivers/net/Kconfig | 33 -------------
> drivers/net/Makefile | 14 ------
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/freescale/Kconfig | 48 ++++++++++++++++++++
> drivers/net/ethernet/freescale/Makefile | 13 +++++
> .../net/{ => ethernet/freescale}/fs_enet/Kconfig | 2 +-
> .../net/{ => ethernet/freescale}/fs_enet/Makefile | 0
> drivers/net/{ => ethernet/freescale}/fs_enet/fec.h | 0
> .../freescale}/fs_enet/fs_enet-main.c | 0
> .../net/{ => ethernet/freescale}/fs_enet/fs_enet.h | 0
> .../net/{ => ethernet/freescale}/fs_enet/mac-fcc.c | 0
> .../net/{ => ethernet/freescale}/fs_enet/mac-fec.c | 0
> .../net/{ => ethernet/freescale}/fs_enet/mac-scc.c | 0
> .../{ => ethernet/freescale}/fs_enet/mii-bitbang.c | 0
> .../net/{ => ethernet/freescale}/fs_enet/mii-fec.c | 0
> drivers/net/{ => ethernet/freescale}/fsl_pq_mdio.c | 0
> drivers/net/{ => ethernet/freescale}/fsl_pq_mdio.h | 0
> drivers/net/{ => ethernet/freescale}/gianfar.c | 0
> drivers/net/{ => ethernet/freescale}/gianfar.h | 0
> .../net/{ => ethernet/freescale}/gianfar_ethtool.c | 0
> drivers/net/{ => ethernet/freescale}/gianfar_ptp.c | 0
> .../net/{ => ethernet/freescale}/gianfar_sysfs.c | 0
> drivers/net/{ => ethernet/freescale}/ucc_geth.c | 0
> drivers/net/{ => ethernet/freescale}/ucc_geth.h | 0
> .../{ => ethernet/freescale}/ucc_geth_ethtool.c | 0
> 27 files changed, 65 insertions(+), 49 deletions(-)
>
> commit dbf507c912fcc804a20d86d2194fc4a4298f39df
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Sat Jun 11 01:13:22 2011 -0700
>
> eepro/eexpress/eth16i/ewrk3/lp486e/seeq8005/znet: Move the ISA drivers
>
> Move the ISA drivers into drivers/net/ethernet/isa/ and make the
> necessary Kconfig and Makefile changes.
>
> CC: Philip Blundell <philb@gnu.org>
> CC: Mika Kuoppala <miku@iki.fi>
> CC: <bao.ha@srs.gov>
> CC: <aris@cathedrallabs.org>
> CC: David Davies <davies@maniac.ultranet.com>
> CC: <aeb@cwi.nl>
> CC: Hamish Coleman <hamish@zot.apana.org.au>
> CC: Donald Becker <becker@scyld.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 4 +-
> drivers/net/Kconfig | 98 ----------------------------
> drivers/net/Makefile | 10 ---
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/isa/Kconfig | 101 +++++++++++++++++++++++++++++
> drivers/net/ethernet/isa/Makefile | 11 +++
> drivers/net/{ => ethernet/isa}/eepro.c | 0
> drivers/net/{ => ethernet/isa}/eexpress.c | 0
> drivers/net/{ => ethernet/isa}/eexpress.h | 0
> drivers/net/{ => ethernet/isa}/eth16i.c | 0
> drivers/net/{ => ethernet/isa}/ewrk3.c | 0
> drivers/net/{ => ethernet/isa}/ewrk3.h | 0
> drivers/net/{ => ethernet/isa}/lp486e.c | 0
> drivers/net/{ => ethernet/isa}/seeq8005.c | 0
> drivers/net/{ => ethernet/isa}/seeq8005.h | 0
> drivers/net/{ => ethernet/isa}/znet.c | 0
> 17 files changed, 116 insertions(+), 110 deletions(-)
>
> commit b8a6199b8d692ae17932b8c8cc709898255a51ad
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Fri May 20 20:43:09 2011 -0700
>
> via-*: Move the VIA drivers
>
> Move the VIA drivers into drivers/net/ethernet/via/ and make the
> necessary Kconfig and Makefile changes.
>
> CC: Roger Luethi <rl@hellgate.ch>
> CC: Francois Romieu <romieu@fr.zoreil.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 4 +-
> drivers/net/Kconfig | 36 -----------------
> drivers/net/Makefile | 2 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/via/Kconfig | 52 +++++++++++++++++++++++++
> drivers/net/ethernet/via/Makefile | 6 +++
> drivers/net/{ => ethernet/via}/via-rhine.c | 0
> drivers/net/{ => ethernet/via}/via-velocity.c | 0
> drivers/net/{ => ethernet/via}/via-velocity.h | 0
> 10 files changed, 62 insertions(+), 40 deletions(-)
>
> commit 0cc82a49e423bc0b2ee19c49ad24376d1ffccdc5
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Fri May 20 20:18:55 2011 -0700
>
> skge/sky2: Move the SysKonnect Ethernet drivers
>
> Move the SysKonnect (Ethernet only) drivers into drivers/net/ethernet/syskonnect/
> and make the necessary Kconfig and Makefile changes.
>
> CC: Stephen Hemminger <shemminger@linux-foundation.org>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 3 +-
> drivers/net/Kconfig | 58 --------------------
> drivers/net/Makefile | 2 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/syskonnect/Kconfig | 74 ++++++++++++++++++++++++++
> drivers/net/ethernet/syskonnect/Makefile | 6 ++
> drivers/net/{ => ethernet/syskonnect}/skge.c | 0
> drivers/net/{ => ethernet/syskonnect}/skge.h | 0
> drivers/net/{ => ethernet/syskonnect}/sky2.c | 0
> drivers/net/{ => ethernet/syskonnect}/sky2.h | 0
> 11 files changed, 83 insertions(+), 62 deletions(-)
>
> commit c9e8faa7214a8911a22281e6e688e0cc69bb54b8
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Fri May 20 19:48:55 2011 -0700
>
> pch_gbe: Move the OKI driver
>
> Move the OKI driver into driver/net/ethernet/pch_gbe/ and make the
> necessary Kconfig and Makefile changes.
>
> Note: there is no documented maintainer for this driver, so I CC'd
> the last 2 major contributors.
>
> CC: Tomoya <tomoya-linux@dsn.okisemi.com>
> CC: Toshiharu Okada <toshiharu-linux@dsn.okisemi.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> drivers/net/Kconfig | 19 -------------------
> drivers/net/Makefile | 1 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/pch_gbe/Kconfig | 20 ++++++++++++++++++++
> drivers/net/{ => ethernet}/pch_gbe/Makefile | 0
> drivers/net/{ => ethernet}/pch_gbe/pch_gbe.h | 0
> drivers/net/{ => ethernet}/pch_gbe/pch_gbe_api.c | 0
> drivers/net/{ => ethernet}/pch_gbe/pch_gbe_api.h | 0
> .../net/{ => ethernet}/pch_gbe/pch_gbe_ethtool.c | 0
> drivers/net/{ => ethernet}/pch_gbe/pch_gbe_main.c | 0
> drivers/net/{ => ethernet}/pch_gbe/pch_gbe_param.c | 0
> drivers/net/{ => ethernet}/pch_gbe/pch_gbe_phy.c | 0
> drivers/net/{ => ethernet}/pch_gbe/pch_gbe_phy.h | 0
> 14 files changed, 22 insertions(+), 20 deletions(-)
>
> commit 63e70fbc3837e36fbcc3e5b3d12eed74919e3beb
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Fri May 20 07:50:27 2011 -0700
>
> ioc3-eth/meth/sgiseeq: Move the SGI drivers
>
> Move the SGI drivers into drivers/net/ethernet/sgi/ and make the
> necessary Kconfig and Makefile changes.
>
> CC: Ralf Baechle <ralf@linux-mips.org>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 2 +-
> drivers/net/Kconfig | 21 ----------------
> drivers/net/Makefile | 3 --
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/sgi/Kconfig | 37 +++++++++++++++++++++++++++++
> drivers/net/ethernet/sgi/Makefile | 7 +++++
> drivers/net/{ => ethernet/sgi}/ioc3-eth.c | 0
> drivers/net/{ => ethernet/sgi}/meth.c | 0
> drivers/net/{ => ethernet/sgi}/meth.h | 0
> drivers/net/{ => ethernet/sgi}/sgiseeq.c | 0
> drivers/net/{ => ethernet/sgi}/sgiseeq.h | 0
> 12 files changed, 47 insertions(+), 25 deletions(-)
>
> commit 33bb1962fa6983fb17a7c95a5b44be697878783b
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Fri May 20 07:15:19 2011 -0700
>
> tulip: Move the tulip drivers
>
> Move the tulip driver into drivers/net/ethernet/tulip/ and make
> the necessary Kconfig and Makefile changes.
>
> CC: Tobias Ringstrom <tori@unhappy.mine.nu>
> CC: Grant Grundler <grundler@parisc-linux.org>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 4 ++--
> drivers/net/Kconfig | 2 --
> drivers/net/Makefile | 1 -
> drivers/net/ethernet/Kconfig | 2 ++
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/{ => ethernet}/tulip/21142.c | 0
> drivers/net/{ => ethernet}/tulip/Kconfig | 0
> drivers/net/{ => ethernet}/tulip/Makefile | 0
> drivers/net/{ => ethernet}/tulip/de2104x.c | 0
> drivers/net/{ => ethernet}/tulip/de4x5.c | 0
> drivers/net/{ => ethernet}/tulip/de4x5.h | 0
> drivers/net/{ => ethernet}/tulip/dmfe.c | 0
> drivers/net/{ => ethernet}/tulip/eeprom.c | 0
> drivers/net/{ => ethernet}/tulip/interrupt.c | 0
> drivers/net/{ => ethernet}/tulip/media.c | 0
> drivers/net/{ => ethernet}/tulip/pnic.c | 0
> drivers/net/{ => ethernet}/tulip/pnic2.c | 0
> drivers/net/{ => ethernet}/tulip/timer.c | 0
> drivers/net/{ => ethernet}/tulip/tulip.h | 0
> drivers/net/{ => ethernet}/tulip/tulip_core.c | 0
> drivers/net/{ => ethernet}/tulip/uli526x.c | 0
> drivers/net/{ => ethernet}/tulip/winbond-840.c | 0
> drivers/net/{ => ethernet}/tulip/xircom_cb.c | 0
> 23 files changed, 5 insertions(+), 5 deletions(-)
>
> commit 9091cea3242dcc16138cef784c4880a819b28c1e
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Fri May 20 06:55:16 2011 -0700
>
> atl*: Move the Atheros drivers
>
> Move the Atheros drivers into drivers/net/ethernet/atheros/ and
> make the necessary Kconfig and Makefile changes.
>
> CC: Jay Cliburn <jcliburn@gmail.com>
> CC: Chris Snook <chris.snook@gmail.com>
> CC: Jie Yang <jie.yang@atheros.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 2 +-
> drivers/net/Kconfig | 45 --------------
> drivers/net/Makefile | 4 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/atheros/Kconfig | 61 ++++++++++++++++++++
> drivers/net/ethernet/atheros/Makefile | 8 +++
> drivers/net/{ => ethernet/atheros}/atl1c/Makefile | 0
> drivers/net/{ => ethernet/atheros}/atl1c/atl1c.h | 0
> .../{ => ethernet/atheros}/atl1c/atl1c_ethtool.c | 0
> .../net/{ => ethernet/atheros}/atl1c/atl1c_hw.c | 0
> .../net/{ => ethernet/atheros}/atl1c/atl1c_hw.h | 0
> .../net/{ => ethernet/atheros}/atl1c/atl1c_main.c | 0
> drivers/net/{ => ethernet/atheros}/atl1e/Makefile | 0
> drivers/net/{ => ethernet/atheros}/atl1e/atl1e.h | 0
> .../{ => ethernet/atheros}/atl1e/atl1e_ethtool.c | 0
> .../net/{ => ethernet/atheros}/atl1e/atl1e_hw.c | 0
> .../net/{ => ethernet/atheros}/atl1e/atl1e_hw.h | 0
> .../net/{ => ethernet/atheros}/atl1e/atl1e_main.c | 0
> .../net/{ => ethernet/atheros}/atl1e/atl1e_param.c | 0
> drivers/net/{ => ethernet/atheros}/atlx/Makefile | 0
> drivers/net/{ => ethernet/atheros}/atlx/atl1.c | 0
> drivers/net/{ => ethernet/atheros}/atlx/atl1.h | 0
> drivers/net/{ => ethernet/atheros}/atlx/atl2.c | 0
> drivers/net/{ => ethernet/atheros}/atlx/atl2.h | 0
> drivers/net/{ => ethernet/atheros}/atlx/atlx.c | 0
> drivers/net/{ => ethernet/atheros}/atlx/atlx.h | 0
> 27 files changed, 72 insertions(+), 50 deletions(-)
>
> commit c97cb6d3434e3a3fa4d415f436e04475df39e443
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Fri May 20 00:04:35 2011 -0700
>
> de6*/dl2k: Move the D-Link drivers
>
> Move the D-Link drivers into drivers/net/ethernet/dlink/ and
> make the necessary Kconfig and Makefile changes.
>
> CC: Bjorn Ekwall <bj0rn@blox.se>
> CC: Donald Becker <becker@scyld.com>
> CC: Edward Peng <edward_peng@dlink.com.tw>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> drivers/net/Kconfig | 44 ----------------------
> drivers/net/Makefile | 3 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/dlink/Kconfig | 60 ++++++++++++++++++++++++++++++
> drivers/net/ethernet/dlink/Makefile | 7 +++
> drivers/net/{ => ethernet/dlink}/de600.c | 0
> drivers/net/{ => ethernet/dlink}/de600.h | 0
> drivers/net/{ => ethernet/dlink}/de620.c | 0
> drivers/net/{ => ethernet/dlink}/de620.h | 0
> drivers/net/{ => ethernet/dlink}/dl2k.c | 0
> drivers/net/{ => ethernet/dlink}/dl2k.h | 0
> 12 files changed, 69 insertions(+), 47 deletions(-)
>
> commit 268a0fa7d7159b37d1123d68343c555f44221510
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Thu May 19 23:27:55 2011 -0700
>
> 8139*/atp/r8169: Move the Realtek drivers
>
> Move the Realtek drivers into drivers/net/ethernet/realtek/ and make
> the necessary Kconfig and Makefile changes.
>
> CC: Realtek linux nic maintainers <nic_swsd@realtek.com>
> CC: Francois Romieu <romieu@fr.zoreil.com>
> CC: Jeff Garzik <jgarzik@pobox.com>
> CC: Donald Becker <becker@scyld.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 2 +-
> drivers/net/Kconfig | 94 ----------------------
> drivers/net/Makefile | 4 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/{ => ethernet/realtek}/8139cp.c | 0
> drivers/net/{ => ethernet/realtek}/8139too.c | 0
> drivers/net/ethernet/realtek/Kconfig | 110 ++++++++++++++++++++++++++
> drivers/net/ethernet/realtek/Makefile | 8 ++
> drivers/net/{ => ethernet/realtek}/atp.c | 0
> drivers/net/{ => ethernet/realtek}/atp.h | 0
> drivers/net/{ => ethernet/realtek}/r8169.c | 0
> 12 files changed, 121 insertions(+), 99 deletions(-)
>
> commit 5fe875b9e93af6b5a099b37471bebb541f1ba0c6
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Thu May 19 22:06:03 2011 -0700
>
> arm: Move the ARM/ACORN drivers
>
> Move the ARM/ACORN drivers into drivers/net/ethernet/arm/ and make the
> necessary Kconfig and Makefile changes.
> There were 4 drivers (TI Davinci & ftmac100) not in the
> drivers/net/arm/ which should have been since they are only supported
> under ARM, so they were added to the new directory structure.
>
> NOTE: There are no "maintainers" for the TI Davinci drivers, so I am
> CC'ing the last 3 major contributors from TI.
>
> CC: Sriram <srk@ti.com>
> CC: Vinay Hegde <vinay.hegde@ti.com>
> CC: Cyril Chemparathy <cyril@ti.com>
> CC: Russell King <linux@arm.linux.org.uk>
> CC: Wan ZongShun <mcuos.com@gmail.com>
> CC: Lennert Buytenhek <kernel@wantstofly.org>
> CC: Krzysztof Halasa <khc@pm.waw.pl>
> CC: Po-Yu Chuang <ratbert@faraday-tech.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 10 +-
> drivers/net/Kconfig | 51 ---------
> drivers/net/Makefile | 7 --
> drivers/net/arm/Kconfig | 74 -------------
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/arm/Kconfig | 138 ++++++++++++++++++++++++
> drivers/net/{ => ethernet}/arm/Makefile | 6 +-
> drivers/net/{ => ethernet}/arm/am79c961a.c | 0
> drivers/net/{ => ethernet}/arm/am79c961a.h | 0
> drivers/net/{ => ethernet}/arm/at91_ether.c | 0
> drivers/net/{ => ethernet}/arm/at91_ether.h | 0
> drivers/net/{ => ethernet/arm}/davinci_cpdma.c | 0
> drivers/net/{ => ethernet/arm}/davinci_cpdma.h | 0
> drivers/net/{ => ethernet/arm}/davinci_emac.c | 0
> drivers/net/{ => ethernet/arm}/davinci_mdio.c | 0
> drivers/net/{ => ethernet}/arm/ep93xx_eth.c | 0
> drivers/net/{ => ethernet}/arm/ether1.c | 0
> drivers/net/{ => ethernet}/arm/ether1.h | 0
> drivers/net/{ => ethernet}/arm/ether3.c | 0
> drivers/net/{ => ethernet}/arm/ether3.h | 0
> drivers/net/{ => ethernet}/arm/etherh.c | 0
> drivers/net/{ => ethernet/arm}/ftgmac100.c | 0
> drivers/net/{ => ethernet/arm}/ftgmac100.h | 0
> drivers/net/{ => ethernet/arm}/ftmac100.c | 0
> drivers/net/{ => ethernet/arm}/ftmac100.h | 0
> drivers/net/{ => ethernet}/arm/ixp4xx_eth.c | 0
> drivers/net/{ => ethernet}/arm/ks8695net.c | 0
> drivers/net/{ => ethernet}/arm/ks8695net.h | 0
> drivers/net/{ => ethernet}/arm/w90p910_ether.c | 0
> 30 files changed, 150 insertions(+), 138 deletions(-)
>
> commit 17c347d9648541503aef09b95b207737b151ddea
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Thu May 19 20:18:50 2011 -0700
>
> smsc*/smc911x: Move the SMSC drivers
>
> Move the SMSC drivers into drivers/net/ethernet/smsc/ and make the
> necessary Kconfig and Makefile changes.
>
> CC: Dustin McIntire <dustin@sensoria.com>
> CC: Steve Glendinning <steve.glendinning@smsc.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 4 +-
> drivers/net/Kconfig | 54 ---------------------
> drivers/net/Makefile | 3 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/smsc/Kconfig | 71 ++++++++++++++++++++++++++++
> drivers/net/ethernet/smsc/Makefile | 7 +++
> drivers/net/{ => ethernet/smsc}/smc911x.c | 0
> drivers/net/{ => ethernet/smsc}/smc911x.h | 0
> drivers/net/{ => ethernet/smsc}/smsc911x.c | 0
> drivers/net/{ => ethernet/smsc}/smsc911x.h | 0
> drivers/net/{ => ethernet/smsc}/smsc9420.c | 0
> drivers/net/{ => ethernet/smsc}/smsc9420.h | 0
> 13 files changed, 82 insertions(+), 59 deletions(-)
>
> commit f93707a2948f67da9fbe12ff93f6c5a95d6fb23d
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Wed May 18 05:14:22 2011 -0700
>
> *sonic/natsemi/ns83829: Move the National Semi-conductor drivers
>
> Move the National Semi-conductor drivers into drivers/net/ethernet/natsemi/
> and make the necessary Kconfig and Makefile changes. Also moved the 8390
> (National Semi-conductor) devices as a sub-menu of National Semi-conductor
> devices.
>
> CC: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> CC: Harald Welte <laforge@gnumonks.org>
> CC: Tim Hockin <thockin@hockin.org>
> CC: <linux-ns83820@kvack.org>
> CC: Kevin Chea <kchea@yahoo.com>
> CC: Marc Gauthier <marc@linux-xtensa.org>
> CC: Chris Zankel <chris@zankel.net>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 4 +-
> drivers/net/Kconfig | 47 ------------------
> drivers/net/Makefile | 6 --
> drivers/net/ethernet/8390/Kconfig | 6 +-
> drivers/net/ethernet/Kconfig | 3 +-
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/natsemi/Kconfig | 63 ++++++++++++++++++++++++
> drivers/net/ethernet/natsemi/Makefile | 9 +++
> drivers/net/{ => ethernet/natsemi}/jazzsonic.c | 0
> drivers/net/{ => ethernet/natsemi}/macsonic.c | 0
> drivers/net/{ => ethernet/natsemi}/natsemi.c | 0
> drivers/net/{ => ethernet/natsemi}/ns83820.c | 0
> drivers/net/{ => ethernet/natsemi}/sonic.c | 0
> drivers/net/{ => ethernet/natsemi}/sonic.h | 0
> drivers/net/{ => ethernet/natsemi}/xtsonic.c | 0
> 15 files changed, 80 insertions(+), 59 deletions(-)
>
> commit 8a352394d237f49f4d142874057d4179a1169607
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Mon May 16 01:39:01 2011 -0700
>
> bmac/mace/macmace/mac89x0/cs89x0: Move the Macintosh (Apple) drivers
>
> Move the Apple drivers into driver/net/ethernet/apple/ and make the
> necessary Kconfig and Makefile changes.
>
> CC: Paul Mackerras <paulus@samba.org>
> CC: Paul Mackerras <paulus@au.ibm.com>
> CC: Russell Nelson <nelson@crynwr.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> drivers/net/Kconfig | 75 ----------------------
> drivers/net/Makefile | 6 --
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/apple/Kconfig | 92 ++++++++++++++++++++++++++++
> drivers/net/ethernet/apple/Makefile | 9 +++
> drivers/net/{ => ethernet/apple}/bmac.c | 0
> drivers/net/{ => ethernet/apple}/bmac.h | 0
> drivers/net/{ => ethernet/apple}/cs89x0.c | 0
> drivers/net/{ => ethernet/apple}/cs89x0.h | 0
> drivers/net/{ => ethernet/apple}/mac89x0.c | 0
> drivers/net/{ => ethernet/apple}/mace.c | 0
> drivers/net/{ => ethernet/apple}/mace.h | 0
> drivers/net/{ => ethernet/apple}/macmace.c | 0
> 14 files changed, 103 insertions(+), 81 deletions(-)
>
> commit 0222c318a10195f618d82f9f7c4e0d61564bcc5d
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Mon May 16 00:05:19 2011 -0700
>
> stmmac: Move the STMicroelectronics driver
>
> Move the STMicroelectronics driver into driver/net/ethernet/stmmac/ and
> make the necessary Kconfig and Makefile changes.
>
> CC: Giuseppe Cavallaro <peppe.cavallaro@st.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 2 +-
> drivers/net/Kconfig | 2 --
> drivers/net/Makefile | 1 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/{ => ethernet}/stmmac/Kconfig | 0
> drivers/net/{ => ethernet}/stmmac/Makefile | 0
> drivers/net/{ => ethernet}/stmmac/common.h | 0
> drivers/net/{ => ethernet}/stmmac/descs.h | 0
> drivers/net/{ => ethernet}/stmmac/dwmac100.h | 0
> drivers/net/{ => ethernet}/stmmac/dwmac1000.h | 0
> drivers/net/{ => ethernet}/stmmac/dwmac1000_core.c | 0
> drivers/net/{ => ethernet}/stmmac/dwmac1000_dma.c | 0
> drivers/net/{ => ethernet}/stmmac/dwmac100_core.c | 0
> drivers/net/{ => ethernet}/stmmac/dwmac100_dma.c | 0
> drivers/net/{ => ethernet}/stmmac/dwmac_dma.h | 0
> drivers/net/{ => ethernet}/stmmac/dwmac_lib.c | 0
> drivers/net/{ => ethernet}/stmmac/enh_desc.c | 0
> drivers/net/{ => ethernet}/stmmac/norm_desc.c | 0
> drivers/net/{ => ethernet}/stmmac/stmmac.h | 0
> drivers/net/{ => ethernet}/stmmac/stmmac_ethtool.c | 0
> drivers/net/{ => ethernet}/stmmac/stmmac_main.c | 0
> drivers/net/{ => ethernet}/stmmac/stmmac_mdio.c | 0
> drivers/net/{ => ethernet}/stmmac/stmmac_timer.c | 0
> drivers/net/{ => ethernet}/stmmac/stmmac_timer.h | 0
> 25 files changed, 3 insertions(+), 4 deletions(-)
>
> commit c9979075eda1f39b3cf73b51b4da05e2bc1a7a3f
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Sun May 15 21:46:41 2011 -0700
>
> tehuti: Move the Tehuti driver
>
> Move the Tehuti driver into drivers/net/ethernet/ and make the
> necessary Kconfig and Makefile changes.
>
> CC: Alexander Indenbaum <baum@tehutinetworks.net>
> CC: Andy Gospodarek <andy@greyhouse.net>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 2 +-
> drivers/net/Kconfig | 6 ------
> drivers/net/Makefile | 1 -
> drivers/net/ethernet/Kconfig | 6 ++++++
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/{ => ethernet}/tehuti.c | 0
> drivers/net/{ => ethernet}/tehuti.h | 0
> 7 files changed, 8 insertions(+), 8 deletions(-)
>
> commit 9b8448aa63ea26e8cbe23df6064146b2bcf1429c
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Sun May 15 20:56:37 2011 -0700
>
> pasemic_mac*: Move the PA Semi driver
>
> Move the PA Semi driver into drivers/net/ethernet/ and make the
> necessary Kconfig and Makefile changes.
>
> CC: Olof Johansson <olof@lixom.net>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 2 +-
> drivers/net/Kconfig | 9 ---------
> drivers/net/Makefile | 2 --
> drivers/net/ethernet/Kconfig | 10 ++++++++++
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/{ => ethernet}/pasemi_mac.c | 0
> drivers/net/{ => ethernet}/pasemi_mac.h | 0
> drivers/net/{ => ethernet}/pasemi_mac_ethtool.c | 0
> 8 files changed, 12 insertions(+), 12 deletions(-)
>
> commit 8f45b84e5a50e13e530ccd7277e87e21bf9d3824
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Fri May 13 22:20:35 2011 -0700
>
> enic: Move the Cisco driver
>
> Move the Cisco driver into drivers/net/ethernet/enic/ and make the
> necessary Kconfig and Makefile changes.
>
> CC: Scott Feldman <scofeldm@cisco.com>
> CC: Christian Benvenuti <benve@cisco.com>
> CC: Vasanthy Kolluri <vkolluri@cisco.com>
> CC: Roopa Prabhu <roprabhu@cisco.com>
> CC: David Wang <dwang2@cisco.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 2 +-
> drivers/net/Kconfig | 6 ------
> drivers/net/Makefile | 1 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/enic/Kconfig | 9 +++++++++
> drivers/net/{ => ethernet}/enic/Makefile | 0
> drivers/net/{ => ethernet}/enic/cq_desc.h | 0
> drivers/net/{ => ethernet}/enic/cq_enet_desc.h | 0
> drivers/net/{ => ethernet}/enic/enic.h | 0
> drivers/net/{ => ethernet}/enic/enic_dev.c | 0
> drivers/net/{ => ethernet}/enic/enic_dev.h | 0
> drivers/net/{ => ethernet}/enic/enic_main.c | 0
> drivers/net/{ => ethernet}/enic/enic_pp.c | 0
> drivers/net/{ => ethernet}/enic/enic_pp.h | 0
> drivers/net/{ => ethernet}/enic/enic_res.c | 0
> drivers/net/{ => ethernet}/enic/enic_res.h | 0
> drivers/net/{ => ethernet}/enic/rq_enet_desc.h | 0
> drivers/net/{ => ethernet}/enic/vnic_cq.c | 0
> drivers/net/{ => ethernet}/enic/vnic_cq.h | 0
> drivers/net/{ => ethernet}/enic/vnic_dev.c | 0
> drivers/net/{ => ethernet}/enic/vnic_dev.h | 0
> drivers/net/{ => ethernet}/enic/vnic_devcmd.h | 0
> drivers/net/{ => ethernet}/enic/vnic_enet.h | 0
> drivers/net/{ => ethernet}/enic/vnic_intr.c | 0
> drivers/net/{ => ethernet}/enic/vnic_intr.h | 0
> drivers/net/{ => ethernet}/enic/vnic_nic.h | 0
> drivers/net/{ => ethernet}/enic/vnic_resource.h | 0
> drivers/net/{ => ethernet}/enic/vnic_rq.c | 0
> drivers/net/{ => ethernet}/enic/vnic_rq.h | 0
> drivers/net/{ => ethernet}/enic/vnic_rss.h | 0
> drivers/net/{ => ethernet}/enic/vnic_stats.h | 0
> drivers/net/{ => ethernet}/enic/vnic_vic.c | 0
> drivers/net/{ => ethernet}/enic/vnic_vic.h | 0
> drivers/net/{ => ethernet}/enic/vnic_wq.c | 0
> drivers/net/{ => ethernet}/enic/vnic_wq.h | 0
> drivers/net/{ => ethernet}/enic/wq_enet_desc.h | 0
> 37 files changed, 12 insertions(+), 8 deletions(-)
>
> commit 21b49617eef3976ebbd73cb4bf1a1f2f6902dbbf
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Fri May 13 14:29:12 2011 -0700
>
> ehea/ibm*: Move the IBM drivers
>
> Move the IBM drivers into drivers/net/ethernet/ibm/ and make the
> necessary Kconfig and Makefile changes.
>
> CC: Christoph Raisch <raisch@de.ibm.com>
> CC: Alfred Arnold <alfred.arnold@lancom.de>
> CC: Santiago Leon <santil@linux.vnet.ibm.com>
> CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 4 +-
> drivers/net/Kconfig | 37 --------------
> drivers/net/Makefile | 4 --
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/ibm/Kconfig | 53 ++++++++++++++++++++
> drivers/net/ethernet/ibm/Makefile | 8 +++
> drivers/net/{ => ethernet/ibm}/ehea/Makefile | 0
> drivers/net/{ => ethernet/ibm}/ehea/ehea.h | 0
> drivers/net/{ => ethernet/ibm}/ehea/ehea_ethtool.c | 0
> drivers/net/{ => ethernet/ibm}/ehea/ehea_hw.h | 0
> drivers/net/{ => ethernet/ibm}/ehea/ehea_main.c | 0
> drivers/net/{ => ethernet/ibm}/ehea/ehea_phyp.c | 0
> drivers/net/{ => ethernet/ibm}/ehea/ehea_phyp.h | 0
> drivers/net/{ => ethernet/ibm}/ehea/ehea_qmr.c | 0
> drivers/net/{ => ethernet/ibm}/ehea/ehea_qmr.h | 0
> drivers/net/{ => ethernet/ibm}/ibm_newemac/Kconfig | 2 +-
> .../net/{ => ethernet/ibm}/ibm_newemac/Makefile | 0
> drivers/net/{ => ethernet/ibm}/ibm_newemac/core.c | 0
> drivers/net/{ => ethernet/ibm}/ibm_newemac/core.h | 0
> drivers/net/{ => ethernet/ibm}/ibm_newemac/debug.c | 0
> drivers/net/{ => ethernet/ibm}/ibm_newemac/debug.h | 0
> drivers/net/{ => ethernet/ibm}/ibm_newemac/emac.h | 0
> drivers/net/{ => ethernet/ibm}/ibm_newemac/mal.c | 0
> drivers/net/{ => ethernet/ibm}/ibm_newemac/mal.h | 0
> drivers/net/{ => ethernet/ibm}/ibm_newemac/phy.c | 0
> drivers/net/{ => ethernet/ibm}/ibm_newemac/phy.h | 0
> drivers/net/{ => ethernet/ibm}/ibm_newemac/rgmii.c | 0
> drivers/net/{ => ethernet/ibm}/ibm_newemac/rgmii.h | 0
> drivers/net/{ => ethernet/ibm}/ibm_newemac/tah.c | 0
> drivers/net/{ => ethernet/ibm}/ibm_newemac/tah.h | 0
> drivers/net/{ => ethernet/ibm}/ibm_newemac/zmii.c | 0
> drivers/net/{ => ethernet/ibm}/ibm_newemac/zmii.h | 0
> drivers/net/{ => ethernet/ibm}/ibmlana.c | 0
> drivers/net/{ => ethernet/ibm}/ibmlana.h | 0
> drivers/net/{ => ethernet/ibm}/ibmveth.c | 0
> drivers/net/{ => ethernet/ibm}/ibmveth.h | 0
> 37 files changed, 66 insertions(+), 44 deletions(-)
>
> commit a5c1daab860bc137dafadc061e48f4153ce89a31
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Fri May 13 02:51:01 2011 -0700
>
> s2io/vxge: Move the Exar drivers
>
> Move the Exar drivers into drivers/net/ethernet/exar/ and make the
> necessary Kconfig and Makefile changes.
I think it makes more since to have the folder named neterion, as that
was the name the adapters were sold under.
Aside from that, it looks good to me.
Thanks,
Jon
>
> CC: Jon Mason <jdmason@kudzu.us>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 3 +-
> drivers/net/Kconfig | 34 -------------
> drivers/net/Makefile | 2 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/exar/Kconfig | 50 ++++++++++++++++++++
> drivers/net/ethernet/exar/Makefile | 6 ++
> drivers/net/{ => ethernet/exar}/s2io-regs.h | 0
> drivers/net/{ => ethernet/exar}/s2io.c | 0
> drivers/net/{ => ethernet/exar}/s2io.h | 0
> drivers/net/{ => ethernet/exar}/vxge/Makefile | 0
> drivers/net/{ => ethernet/exar}/vxge/vxge-config.c | 0
> drivers/net/{ => ethernet/exar}/vxge/vxge-config.h | 0
> .../net/{ => ethernet/exar}/vxge/vxge-ethtool.c | 0
> .../net/{ => ethernet/exar}/vxge/vxge-ethtool.h | 0
> drivers/net/{ => ethernet/exar}/vxge/vxge-main.c | 0
> drivers/net/{ => ethernet/exar}/vxge/vxge-main.h | 0
> drivers/net/{ => ethernet/exar}/vxge/vxge-reg.h | 0
> .../net/{ => ethernet/exar}/vxge/vxge-traffic.c | 0
> .../net/{ => ethernet/exar}/vxge/vxge-traffic.h | 0
> .../net/{ => ethernet/exar}/vxge/vxge-version.h | 0
> 21 files changed, 59 insertions(+), 38 deletions(-)
>
> commit 83df87d655e25119eafaeb4225bc5eedaa82c6e0
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Fri May 13 02:24:46 2011 -0700
>
> myri*: Move the Myricom drivers
>
> Move the Myricom drivers into drivers/net/ethernet/myricom/ and make
> the necessary Kconfig and Makefile changes.
>
> CC: Andrew Gallatin <gallatin@myri.com>
> CC: Brice Goglin <brice@myri.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 2 +-
> drivers/net/Kconfig | 35 -------------
> drivers/net/Makefile | 3 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/myricom/Kconfig | 51 ++++++++++++++++++++
> drivers/net/ethernet/myricom/Makefile | 6 ++
> .../net/{ => ethernet/myricom}/myri10ge/Makefile | 0
> .../net/{ => ethernet/myricom}/myri10ge/myri10ge.c | 0
> .../{ => ethernet/myricom}/myri10ge/myri10ge_mcp.h | 0
> .../myricom}/myri10ge/myri10ge_mcp_gen_header.h | 0
> drivers/net/{ => ethernet/myricom}/myri_sbus.c | 0
> drivers/net/{ => ethernet/myricom}/myri_sbus.h | 0
> 13 files changed, 60 insertions(+), 39 deletions(-)
>
> commit c04bd079e4ab82c5ee8fd0cb526f16e9ffce9360
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Fri May 13 01:32:22 2011 -0700
>
> mlx4: Move the Mellanox driver
>
> Moves the Mellanox driver into drivers/net/ethernet/mlx4/ and make
> the necessary Kconfig and Makefile changes.
>
> CC: Roland Dreier <roland@kernel.org>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> drivers/net/Kconfig | 24 ---------------------
> drivers/net/Makefile | 1 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/mlx4/Kconfig | 27 ++++++++++++++++++++++++
> drivers/net/{ => ethernet}/mlx4/Makefile | 0
> drivers/net/{ => ethernet}/mlx4/alloc.c | 0
> drivers/net/{ => ethernet}/mlx4/catas.c | 0
> drivers/net/{ => ethernet}/mlx4/cmd.c | 0
> drivers/net/{ => ethernet}/mlx4/cq.c | 0
> drivers/net/{ => ethernet}/mlx4/en_cq.c | 0
> drivers/net/{ => ethernet}/mlx4/en_ethtool.c | 0
> drivers/net/{ => ethernet}/mlx4/en_main.c | 0
> drivers/net/{ => ethernet}/mlx4/en_netdev.c | 0
> drivers/net/{ => ethernet}/mlx4/en_port.c | 0
> drivers/net/{ => ethernet}/mlx4/en_port.h | 0
> drivers/net/{ => ethernet}/mlx4/en_resources.c | 0
> drivers/net/{ => ethernet}/mlx4/en_rx.c | 0
> drivers/net/{ => ethernet}/mlx4/en_selftest.c | 0
> drivers/net/{ => ethernet}/mlx4/en_tx.c | 0
> drivers/net/{ => ethernet}/mlx4/eq.c | 0
> drivers/net/{ => ethernet}/mlx4/fw.c | 0
> drivers/net/{ => ethernet}/mlx4/fw.h | 0
> drivers/net/{ => ethernet}/mlx4/icm.c | 0
> drivers/net/{ => ethernet}/mlx4/icm.h | 0
> drivers/net/{ => ethernet}/mlx4/intf.c | 0
> drivers/net/{ => ethernet}/mlx4/main.c | 0
> drivers/net/{ => ethernet}/mlx4/mcg.c | 0
> drivers/net/{ => ethernet}/mlx4/mlx4.h | 0
> drivers/net/{ => ethernet}/mlx4/mlx4_en.h | 0
> drivers/net/{ => ethernet}/mlx4/mr.c | 0
> drivers/net/{ => ethernet}/mlx4/pd.c | 0
> drivers/net/{ => ethernet}/mlx4/port.c | 0
> drivers/net/{ => ethernet}/mlx4/profile.c | 0
> drivers/net/{ => ethernet}/mlx4/qp.c | 0
> drivers/net/{ => ethernet}/mlx4/reset.c | 0
> drivers/net/{ => ethernet}/mlx4/sense.c | 0
> drivers/net/{ => ethernet}/mlx4/srq.c | 0
> 38 files changed, 29 insertions(+), 25 deletions(-)
>
> commit d911fd7be681f8833f8ff12efade39df79970653
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Fri May 13 01:00:03 2011 -0700
>
> bna: Move the Brocade driver
>
> Moves the Brocade driver into drivers/net/ethernet/bna/ and make
> the necessary Kconfig and Makefile changes.
>
> CC: Rasesh Mody <rmody@brocade.com>
> CC: Debashis Dutt <ddutt@brocade.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 2 +-
> drivers/net/Kconfig | 14 --------------
> drivers/net/Makefile | 1 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/bna/Kconfig | 17 +++++++++++++++++
> drivers/net/{ => ethernet}/bna/Makefile | 0
> drivers/net/{ => ethernet}/bna/bfa_cee.c | 0
> drivers/net/{ => ethernet}/bna/bfa_cee.h | 0
> drivers/net/{ => ethernet}/bna/bfa_defs.h | 0
> drivers/net/{ => ethernet}/bna/bfa_defs_cna.h | 0
> drivers/net/{ => ethernet}/bna/bfa_defs_mfg_comm.h | 0
> drivers/net/{ => ethernet}/bna/bfa_defs_status.h | 0
> drivers/net/{ => ethernet}/bna/bfa_ioc.c | 0
> drivers/net/{ => ethernet}/bna/bfa_ioc.h | 0
> drivers/net/{ => ethernet}/bna/bfa_ioc_ct.c | 0
> drivers/net/{ => ethernet}/bna/bfa_sm.h | 0
> drivers/net/{ => ethernet}/bna/bfa_wc.h | 0
> drivers/net/{ => ethernet}/bna/bfi.h | 0
> drivers/net/{ => ethernet}/bna/bfi_cna.h | 0
> drivers/net/{ => ethernet}/bna/bfi_ctreg.h | 0
> drivers/net/{ => ethernet}/bna/bfi_ll.h | 0
> drivers/net/{ => ethernet}/bna/bna.h | 0
> drivers/net/{ => ethernet}/bna/bna_ctrl.c | 0
> drivers/net/{ => ethernet}/bna/bna_hw.h | 0
> drivers/net/{ => ethernet}/bna/bna_txrx.c | 0
> drivers/net/{ => ethernet}/bna/bna_types.h | 0
> drivers/net/{ => ethernet}/bna/bnad.c | 0
> drivers/net/{ => ethernet}/bna/bnad.h | 0
> drivers/net/{ => ethernet}/bna/bnad_ethtool.c | 0
> drivers/net/{ => ethernet}/bna/cna.h | 0
> drivers/net/{ => ethernet}/bna/cna_fwimg.c | 0
> 32 files changed, 20 insertions(+), 16 deletions(-)
>
> commit 931da59411e60574a1235d0ad2d63ebd1638a859
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Fri May 13 00:37:27 2011 -0700
>
> be2net: Move the BladeEngine 2 driver
>
> Moves the Server Engine driver into drivers/net/ethernet/benet/ and
> make the necessary Kconfig and Makefile changes.
>
> CC: Sathya Perla <sathya.perla@emulex.com>
> CC: Subbu Seetharaman <subbu.seetharaman@emulex.com>
> CC: Ajit Khaparde <ajit.khaparde@emulex.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 2 +-
> drivers/net/Kconfig | 2 --
> drivers/net/Makefile | 1 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/{ => ethernet}/benet/Kconfig | 0
> drivers/net/{ => ethernet}/benet/Makefile | 0
> drivers/net/{ => ethernet}/benet/be.h | 0
> drivers/net/{ => ethernet}/benet/be_cmds.c | 0
> drivers/net/{ => ethernet}/benet/be_cmds.h | 0
> drivers/net/{ => ethernet}/benet/be_ethtool.c | 0
> drivers/net/{ => ethernet}/benet/be_hw.h | 0
> drivers/net/{ => ethernet}/benet/be_main.c | 0
> 13 files changed, 3 insertions(+), 4 deletions(-)
>
> commit 64648e513185522cd665bfece6d024d3c05588ed
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Fri May 13 00:17:42 2011 -0700
>
> sfc: Move the Solarflare drivers
>
> Moves the Solarflare drivers into drivers/net/ethernet/sfc/ and
> make the necessary Kconfig and Makefile changes.
>
> CC: Steve Hodgson <shodgson@solarflare.com>
> CC: Ben Hutchings <bhutchings@solarflare.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 2 +-
> drivers/net/Kconfig | 2 --
> drivers/net/Makefile | 1 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/{ => ethernet}/sfc/Kconfig | 0
> drivers/net/{ => ethernet}/sfc/Makefile | 0
> drivers/net/{ => ethernet}/sfc/bitfield.h | 0
> drivers/net/{ => ethernet}/sfc/efx.c | 0
> drivers/net/{ => ethernet}/sfc/efx.h | 0
> drivers/net/{ => ethernet}/sfc/enum.h | 0
> drivers/net/{ => ethernet}/sfc/ethtool.c | 0
> drivers/net/{ => ethernet}/sfc/falcon.c | 0
> drivers/net/{ => ethernet}/sfc/falcon_boards.c | 0
> drivers/net/{ => ethernet}/sfc/falcon_xmac.c | 0
> drivers/net/{ => ethernet}/sfc/filter.c | 0
> drivers/net/{ => ethernet}/sfc/filter.h | 0
> drivers/net/{ => ethernet}/sfc/io.h | 0
> drivers/net/{ => ethernet}/sfc/mac.h | 0
> drivers/net/{ => ethernet}/sfc/mcdi.c | 0
> drivers/net/{ => ethernet}/sfc/mcdi.h | 0
> drivers/net/{ => ethernet}/sfc/mcdi_mac.c | 0
> drivers/net/{ => ethernet}/sfc/mcdi_pcol.h | 0
> drivers/net/{ => ethernet}/sfc/mcdi_phy.c | 0
> drivers/net/{ => ethernet}/sfc/mdio_10g.c | 0
> drivers/net/{ => ethernet}/sfc/mdio_10g.h | 0
> drivers/net/{ => ethernet}/sfc/mtd.c | 0
> drivers/net/{ => ethernet}/sfc/net_driver.h | 0
> drivers/net/{ => ethernet}/sfc/nic.c | 0
> drivers/net/{ => ethernet}/sfc/nic.h | 0
> drivers/net/{ => ethernet}/sfc/phy.h | 0
> drivers/net/{ => ethernet}/sfc/qt202x_phy.c | 0
> drivers/net/{ => ethernet}/sfc/regs.h | 0
> drivers/net/{ => ethernet}/sfc/rx.c | 0
> drivers/net/{ => ethernet}/sfc/selftest.c | 0
> drivers/net/{ => ethernet}/sfc/selftest.h | 0
> drivers/net/{ => ethernet}/sfc/siena.c | 0
> drivers/net/{ => ethernet}/sfc/spi.h | 0
> drivers/net/{ => ethernet}/sfc/tenxpress.c | 0
> drivers/net/{ => ethernet}/sfc/tx.c | 0
> drivers/net/{ => ethernet}/sfc/txc43128_phy.c | 0
> drivers/net/{ => ethernet}/sfc/workarounds.h | 0
> 42 files changed, 3 insertions(+), 4 deletions(-)
>
> commit a9f8e9475d4f7c91880050634e923d62e369a0ed
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Thu May 12 23:04:46 2011 -0700
>
> cassini/niu/sun*: Move the Sun drivers
>
> Moves the Sun drivers into drivers/net/ethernet/sun/ and make
> the necessary Kconfig and Makefile changes.
>
> CC: Sam Creasey <sammy@sammy.net>
> CC: Adrian Sun <asun@darksunrising.com>
> CC: Benjamin Herrenscmidt <benh@kernel.crashing.org>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 1 +
> drivers/net/Kconfig | 75 ----------------------
> drivers/net/Makefile | 10 +---
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/sun/Kconfig | 91 +++++++++++++++++++++++++++
> drivers/net/ethernet/sun/Makefile | 12 ++++
> drivers/net/{ => ethernet/sun}/cassini.c | 0
> drivers/net/{ => ethernet/sun}/cassini.h | 0
> drivers/net/{ => ethernet/sun}/niu.c | 0
> drivers/net/{ => ethernet/sun}/niu.h | 0
> drivers/net/{ => ethernet/sun}/sun3_82586.c | 0
> drivers/net/{ => ethernet/sun}/sun3_82586.h | 0
> drivers/net/{ => ethernet/sun}/sunbmac.c | 0
> drivers/net/{ => ethernet/sun}/sunbmac.h | 0
> drivers/net/{ => ethernet/sun}/sungem.c | 0
> drivers/net/{ => ethernet/sun}/sungem.h | 0
> drivers/net/{ => ethernet/sun}/sungem_phy.c | 0
> drivers/net/{ => ethernet/sun}/sungem_phy.h | 0
> drivers/net/{ => ethernet/sun}/sunhme.c | 0
> drivers/net/{ => ethernet/sun}/sunhme.h | 0
> drivers/net/{ => ethernet/sun}/sunqe.c | 0
> drivers/net/{ => ethernet/sun}/sunqe.h | 0
> drivers/net/{ => ethernet/sun}/sunvnet.c | 0
> drivers/net/{ => ethernet/sun}/sunvnet.h | 0
> drivers/net/spider_net.h | 2 +-
> 26 files changed, 108 insertions(+), 85 deletions(-)
>
> commit c1b4800864efcbacb0f02047609b41c9ab5290e6
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Thu May 12 21:21:33 2011 -0700
>
> ni5*/ni65: Move the Racal-Interlan (Micom) drivers
>
> Moves the Racal-Interlan drivers into drivers/net/ethernet/racal/ and
> make the necessary Kconfig and Makefile changes.
>
> CC: "Jan-Pascal van Best" <janpascal@vanbest.org>
> CC: Andreas Mohr <andi@lisas.de>
> CC: "M.Hipp" <hippm@informatik.uni-tuebingen.de>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 2 +-
> drivers/net/Kconfig | 47 ---------------------------
> drivers/net/Makefile | 3 --
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/racal/Kconfig | 50 +++++++++++++++++++++++++++++
> drivers/net/ethernet/racal/Makefile | 7 ++++
> drivers/net/{ => ethernet/racal}/ni5010.c | 0
> drivers/net/{ => ethernet/racal}/ni5010.h | 0
> drivers/net/{ => ethernet/racal}/ni52.c | 0
> drivers/net/{ => ethernet/racal}/ni52.h | 0
> drivers/net/{ => ethernet/racal}/ni65.c | 0
> drivers/net/{ => ethernet/racal}/ni65.h | 0
> 13 files changed, 60 insertions(+), 51 deletions(-)
>
> commit 671dc5b8fb145ff8748cdc2aeffd1ef56af8bd67
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Thu May 12 20:21:07 2011 -0700
>
> smc: Move the SMC drivers
>
> Moves the SMC drivers into drivers/net/ethernet/smc/ and the
> necessary Kconfig and Makefile changes. Also did some cleanup
> of NET_VENDOR_SMC Kconfig tag for the 8390 based drivers.
>
> CC: Nicolas Pitre <nico@fluxnic.net>
> CC: Donald Becker <becker@scyld.com>
> CC: Erik Stahlman <erik@vt.edu>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 2 +-
> drivers/net/Kconfig | 51 -------------------------
> drivers/net/Makefile | 4 --
> drivers/net/ethernet/8390/Kconfig | 21 ++--------
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/qlogic/Kconfig | 7 +++
> drivers/net/ethernet/qlogic/Makefile | 1 +
> drivers/net/ethernet/smc/Kconfig | 61 ++++++++++++++++++++++++++++++
> drivers/net/ethernet/smc/Makefile | 7 +++
> drivers/net/{ => ethernet/smc}/epic100.c | 0
> drivers/net/{ => ethernet/smc}/smc9194.c | 0
> drivers/net/{ => ethernet/smc}/smc9194.h | 0
> drivers/net/{ => ethernet/smc}/smc91x.c | 0
> drivers/net/{ => ethernet/smc}/smc91x.h | 0
> 15 files changed, 83 insertions(+), 73 deletions(-)
>
> commit e9f8a5c9b5f8f469bcfae06ddd10e9dc9537f7bb
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Fri Apr 8 19:06:30 2011 -0700
>
> qlogic: Move the QLogic drivers
>
> Moves the QLogic drivers into drivers/net/ethernet/qlogic/ and
> the necessary Kconfig and Makefile changes.
>
> CC: Ron Mercer <ron.mercer@qlogic.com>
> CC: Amit Kumar Salecha <amit.salecha@qlogic.com>
> CC: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 6 +-
> drivers/net/Kconfig | 26 ------------
> drivers/net/Makefile | 3 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/qlogic/Kconfig | 42 ++++++++++++++++++++
> drivers/net/ethernet/qlogic/Makefile | 7 +++
> drivers/net/{ => ethernet/qlogic}/netxen/Makefile | 0
> .../net/{ => ethernet/qlogic}/netxen/netxen_nic.h | 0
> .../{ => ethernet/qlogic}/netxen/netxen_nic_ctx.c | 0
> .../qlogic}/netxen/netxen_nic_ethtool.c | 0
> .../{ => ethernet/qlogic}/netxen/netxen_nic_hdr.h | 0
> .../{ => ethernet/qlogic}/netxen/netxen_nic_hw.c | 0
> .../{ => ethernet/qlogic}/netxen/netxen_nic_hw.h | 0
> .../{ => ethernet/qlogic}/netxen/netxen_nic_init.c | 0
> .../{ => ethernet/qlogic}/netxen/netxen_nic_main.c | 0
> drivers/net/{ => ethernet/qlogic}/qla3xxx.c | 0
> drivers/net/{ => ethernet/qlogic}/qla3xxx.h | 0
> drivers/net/{ => ethernet/qlogic}/qlcnic/Makefile | 0
> drivers/net/{ => ethernet/qlogic}/qlcnic/qlcnic.h | 0
> .../net/{ => ethernet/qlogic}/qlcnic/qlcnic_ctx.c | 0
> .../{ => ethernet/qlogic}/qlcnic/qlcnic_ethtool.c | 0
> .../net/{ => ethernet/qlogic}/qlcnic/qlcnic_hdr.h | 0
> .../net/{ => ethernet/qlogic}/qlcnic/qlcnic_hw.c | 0
> .../net/{ => ethernet/qlogic}/qlcnic/qlcnic_init.c | 0
> .../net/{ => ethernet/qlogic}/qlcnic/qlcnic_main.c | 0
> drivers/net/{ => ethernet/qlogic}/qlge/Makefile | 0
> drivers/net/{ => ethernet/qlogic}/qlge/qlge.h | 0
> drivers/net/{ => ethernet/qlogic}/qlge/qlge_dbg.c | 0
> .../net/{ => ethernet/qlogic}/qlge/qlge_ethtool.c | 0
> drivers/net/{ => ethernet/qlogic}/qlge/qlge_main.c | 0
> drivers/net/{ => ethernet/qlogic}/qlge/qlge_mpi.c | 0
> 32 files changed, 54 insertions(+), 32 deletions(-)
>
> commit f8e68b0056ef20887bdfdc31ff061d67e81308e2
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Thu Apr 7 07:42:33 2011 -0700
>
> intel: Move the Intel wired LAN drivers
>
> Moves the Intel wired LAN drivers into drivers/net/ethernet/intel/ and
> the necessary Kconfig and Makefile changes.
>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 11 +-
> drivers/net/Kconfig | 200 ------------------
> drivers/net/Makefile | 8 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/intel/Kconfig | 216 ++++++++++++++++++++
> drivers/net/ethernet/intel/Makefile | 12 +
> drivers/net/{ => ethernet/intel}/e100.c | 0
> drivers/net/{ => ethernet/intel}/e1000/Makefile | 0
> drivers/net/{ => ethernet/intel}/e1000/e1000.h | 0
> .../net/{ => ethernet/intel}/e1000/e1000_ethtool.c | 0
> drivers/net/{ => ethernet/intel}/e1000/e1000_hw.c | 0
> drivers/net/{ => ethernet/intel}/e1000/e1000_hw.h | 0
> .../net/{ => ethernet/intel}/e1000/e1000_main.c | 0
> .../net/{ => ethernet/intel}/e1000/e1000_osdep.h | 0
> .../net/{ => ethernet/intel}/e1000/e1000_param.c | 0
> .../intel/e1000e/80003es2lan.c} | 0
> drivers/net/{ => ethernet/intel}/e1000e/82571.c | 0
> drivers/net/{ => ethernet/intel}/e1000e/Makefile | 2 +-
> drivers/net/{ => ethernet/intel}/e1000e/defines.h | 0
> drivers/net/{ => ethernet/intel}/e1000e/e1000.h | 0
> drivers/net/{ => ethernet/intel}/e1000e/ethtool.c | 0
> drivers/net/{ => ethernet/intel}/e1000e/hw.h | 0
> drivers/net/{ => ethernet/intel}/e1000e/ich8lan.c | 0
> drivers/net/{ => ethernet/intel}/e1000e/lib.c | 0
> drivers/net/{ => ethernet/intel}/e1000e/netdev.c | 0
> drivers/net/{ => ethernet/intel}/e1000e/param.c | 0
> drivers/net/{ => ethernet/intel}/e1000e/phy.c | 0
> drivers/net/{ => ethernet/intel}/igb/Makefile | 0
> drivers/net/{ => ethernet/intel}/igb/e1000_82575.c | 0
> drivers/net/{ => ethernet/intel}/igb/e1000_82575.h | 0
> .../net/{ => ethernet/intel}/igb/e1000_defines.h | 0
> drivers/net/{ => ethernet/intel}/igb/e1000_hw.h | 0
> drivers/net/{ => ethernet/intel}/igb/e1000_mac.c | 0
> drivers/net/{ => ethernet/intel}/igb/e1000_mac.h | 0
> drivers/net/{ => ethernet/intel}/igb/e1000_mbx.c | 0
> drivers/net/{ => ethernet/intel}/igb/e1000_mbx.h | 0
> drivers/net/{ => ethernet/intel}/igb/e1000_nvm.c | 0
> drivers/net/{ => ethernet/intel}/igb/e1000_nvm.h | 0
> drivers/net/{ => ethernet/intel}/igb/e1000_phy.c | 0
> drivers/net/{ => ethernet/intel}/igb/e1000_phy.h | 0
> drivers/net/{ => ethernet/intel}/igb/e1000_regs.h | 0
> drivers/net/{ => ethernet/intel}/igb/igb.h | 0
> drivers/net/{ => ethernet/intel}/igb/igb_ethtool.c | 0
> drivers/net/{ => ethernet/intel}/igb/igb_main.c | 0
> drivers/net/{ => ethernet/intel}/igbvf/Makefile | 0
> drivers/net/{ => ethernet/intel}/igbvf/defines.h | 0
> drivers/net/{ => ethernet/intel}/igbvf/ethtool.c | 0
> drivers/net/{ => ethernet/intel}/igbvf/igbvf.h | 0
> drivers/net/{ => ethernet/intel}/igbvf/mbx.c | 0
> drivers/net/{ => ethernet/intel}/igbvf/mbx.h | 0
> drivers/net/{ => ethernet/intel}/igbvf/netdev.c | 0
> drivers/net/{ => ethernet/intel}/igbvf/regs.h | 0
> drivers/net/{ => ethernet/intel}/igbvf/vf.c | 0
> drivers/net/{ => ethernet/intel}/igbvf/vf.h | 0
> drivers/net/{ => ethernet/intel}/ixgb/Makefile | 0
> drivers/net/{ => ethernet/intel}/ixgb/ixgb.h | 0
> drivers/net/{ => ethernet/intel}/ixgb/ixgb_ee.c | 0
> drivers/net/{ => ethernet/intel}/ixgb/ixgb_ee.h | 0
> .../net/{ => ethernet/intel}/ixgb/ixgb_ethtool.c | 0
> drivers/net/{ => ethernet/intel}/ixgb/ixgb_hw.c | 0
> drivers/net/{ => ethernet/intel}/ixgb/ixgb_hw.h | 0
> drivers/net/{ => ethernet/intel}/ixgb/ixgb_ids.h | 0
> drivers/net/{ => ethernet/intel}/ixgb/ixgb_main.c | 0
> drivers/net/{ => ethernet/intel}/ixgb/ixgb_osdep.h | 0
> drivers/net/{ => ethernet/intel}/ixgb/ixgb_param.c | 0
> drivers/net/{ => ethernet/intel}/ixgbe/Makefile | 0
> drivers/net/{ => ethernet/intel}/ixgbe/ixgbe.h | 0
> .../net/{ => ethernet/intel}/ixgbe/ixgbe_82598.c | 0
> .../net/{ => ethernet/intel}/ixgbe/ixgbe_82599.c | 0
> .../net/{ => ethernet/intel}/ixgbe/ixgbe_common.c | 0
> .../net/{ => ethernet/intel}/ixgbe/ixgbe_common.h | 0
> drivers/net/{ => ethernet/intel}/ixgbe/ixgbe_dcb.c | 0
> drivers/net/{ => ethernet/intel}/ixgbe/ixgbe_dcb.h | 0
> .../{ => ethernet/intel}/ixgbe/ixgbe_dcb_82598.c | 0
> .../{ => ethernet/intel}/ixgbe/ixgbe_dcb_82598.h | 0
> .../{ => ethernet/intel}/ixgbe/ixgbe_dcb_82599.c | 0
> .../{ => ethernet/intel}/ixgbe/ixgbe_dcb_82599.h | 0
> .../net/{ => ethernet/intel}/ixgbe/ixgbe_dcb_nl.c | 0
> .../net/{ => ethernet/intel}/ixgbe/ixgbe_ethtool.c | 0
> .../net/{ => ethernet/intel}/ixgbe/ixgbe_fcoe.c | 0
> .../net/{ => ethernet/intel}/ixgbe/ixgbe_fcoe.h | 0
> .../net/{ => ethernet/intel}/ixgbe/ixgbe_main.c | 0
> drivers/net/{ => ethernet/intel}/ixgbe/ixgbe_mbx.c | 0
> drivers/net/{ => ethernet/intel}/ixgbe/ixgbe_mbx.h | 0
> drivers/net/{ => ethernet/intel}/ixgbe/ixgbe_phy.c | 0
> drivers/net/{ => ethernet/intel}/ixgbe/ixgbe_phy.h | 0
> .../net/{ => ethernet/intel}/ixgbe/ixgbe_sriov.c | 0
> .../net/{ => ethernet/intel}/ixgbe/ixgbe_sriov.h | 0
> .../net/{ => ethernet/intel}/ixgbe/ixgbe_type.h | 0
> .../net/{ => ethernet/intel}/ixgbe/ixgbe_x540.c | 0
> drivers/net/{ => ethernet/intel}/ixgbevf/Makefile | 0
> drivers/net/{ => ethernet/intel}/ixgbevf/defines.h | 0
> drivers/net/{ => ethernet/intel}/ixgbevf/ethtool.c | 0
> drivers/net/{ => ethernet/intel}/ixgbevf/ixgbevf.h | 0
> .../{ => ethernet/intel}/ixgbevf/ixgbevf_main.c | 0
> drivers/net/{ => ethernet/intel}/ixgbevf/mbx.c | 0
> drivers/net/{ => ethernet/intel}/ixgbevf/mbx.h | 0
> drivers/net/{ => ethernet/intel}/ixgbevf/regs.h | 0
> drivers/net/{ => ethernet/intel}/ixgbevf/vf.c | 0
> drivers/net/{ => ethernet/intel}/ixgbevf/vf.h | 0
> 101 files changed, 233 insertions(+), 218 deletions(-)
>
> commit e9518ae90966c061c0efa161e885ba23bda6c0a8
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Thu Apr 7 06:57:17 2011 -0700
>
> chelsio: Move the Chelsio drivers
>
> Moves the drivers for the Chelsio chipsets into
> drivers/net/ethernet/chelsio/ and the necessary Kconfig and Makefile
> changes.
>
> CC: Divy Le Ray <divy@chelsio.com>
> CC: Dimitris Michailidis <dm@chelsio.com>
> CC: Casey Leedom <leedom@chelsio.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 6 +-
> drivers/net/Kconfig | 86 ----------------
> drivers/net/Makefile | 4 -
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/chelsio/Kconfig | 102 ++++++++++++++++++++
> drivers/net/ethernet/chelsio/Makefile | 8 ++
> .../{chelsio => ethernet/chelsio/cxgb}/Makefile | 0
> .../{chelsio => ethernet/chelsio/cxgb}/common.h | 0
> .../net/{chelsio => ethernet/chelsio/cxgb}/cphy.h | 0
> .../{chelsio => ethernet/chelsio/cxgb}/cpl5_cmd.h | 0
> .../net/{chelsio => ethernet/chelsio/cxgb}/cxgb2.c | 0
> .../{chelsio => ethernet/chelsio/cxgb}/elmer0.h | 0
> .../net/{chelsio => ethernet/chelsio/cxgb}/espi.c | 0
> .../net/{chelsio => ethernet/chelsio/cxgb}/espi.h | 0
> .../{chelsio => ethernet/chelsio/cxgb}/fpga_defs.h | 0
> .../net/{chelsio => ethernet/chelsio/cxgb}/gmac.h | 0
> .../{chelsio => ethernet/chelsio/cxgb}/mv88e1xxx.c | 0
> .../{chelsio => ethernet/chelsio/cxgb}/mv88e1xxx.h | 0
> .../{chelsio => ethernet/chelsio/cxgb}/mv88x201x.c | 0
> .../{chelsio => ethernet/chelsio/cxgb}/my3126.c | 0
> .../{chelsio => ethernet/chelsio/cxgb}/pm3393.c | 0
> .../net/{chelsio => ethernet/chelsio/cxgb}/regs.h | 0
> .../net/{chelsio => ethernet/chelsio/cxgb}/sge.c | 0
> .../net/{chelsio => ethernet/chelsio/cxgb}/sge.h | 0
> .../net/{chelsio => ethernet/chelsio/cxgb}/subr.c | 0
> .../chelsio/cxgb}/suni1x10gexp_regs.h | 0
> .../net/{chelsio => ethernet/chelsio/cxgb}/tp.c | 0
> .../net/{chelsio => ethernet/chelsio/cxgb}/tp.h | 0
> .../{chelsio => ethernet/chelsio/cxgb}/vsc7326.c | 0
> .../chelsio/cxgb}/vsc7326_reg.h | 0
> drivers/net/{ => ethernet/chelsio}/cxgb3/Makefile | 0
> drivers/net/{ => ethernet/chelsio}/cxgb3/adapter.h | 0
> drivers/net/{ => ethernet/chelsio}/cxgb3/ael1002.c | 0
> drivers/net/{ => ethernet/chelsio}/cxgb3/aq100x.c | 0
> drivers/net/{ => ethernet/chelsio}/cxgb3/common.h | 0
> .../{ => ethernet/chelsio}/cxgb3/cxgb3_ctl_defs.h | 0
> .../net/{ => ethernet/chelsio}/cxgb3/cxgb3_defs.h | 0
> .../net/{ => ethernet/chelsio}/cxgb3/cxgb3_ioctl.h | 0
> .../net/{ => ethernet/chelsio}/cxgb3/cxgb3_main.c | 0
> .../{ => ethernet/chelsio}/cxgb3/cxgb3_offload.c | 0
> .../{ => ethernet/chelsio}/cxgb3/cxgb3_offload.h | 0
> .../chelsio}/cxgb3/firmware_exports.h | 0
> drivers/net/{ => ethernet/chelsio}/cxgb3/l2t.c | 0
> drivers/net/{ => ethernet/chelsio}/cxgb3/l2t.h | 0
> drivers/net/{ => ethernet/chelsio}/cxgb3/mc5.c | 0
> drivers/net/{ => ethernet/chelsio}/cxgb3/regs.h | 0
> drivers/net/{ => ethernet/chelsio}/cxgb3/sge.c | 0
> .../net/{ => ethernet/chelsio}/cxgb3/sge_defs.h | 0
> drivers/net/{ => ethernet/chelsio}/cxgb3/t3_cpl.h | 0
> drivers/net/{ => ethernet/chelsio}/cxgb3/t3_hw.c | 0
> drivers/net/{ => ethernet/chelsio}/cxgb3/t3cdev.h | 0
> drivers/net/{ => ethernet/chelsio}/cxgb3/version.h | 0
> drivers/net/{ => ethernet/chelsio}/cxgb3/vsc8211.c | 0
> drivers/net/{ => ethernet/chelsio}/cxgb3/xgmac.c | 0
> drivers/net/{ => ethernet/chelsio}/cxgb4/Makefile | 0
> drivers/net/{ => ethernet/chelsio}/cxgb4/cxgb4.h | 0
> .../net/{ => ethernet/chelsio}/cxgb4/cxgb4_main.c | 0
> .../net/{ => ethernet/chelsio}/cxgb4/cxgb4_uld.h | 0
> drivers/net/{ => ethernet/chelsio}/cxgb4/l2t.c | 0
> drivers/net/{ => ethernet/chelsio}/cxgb4/l2t.h | 0
> drivers/net/{ => ethernet/chelsio}/cxgb4/sge.c | 0
> drivers/net/{ => ethernet/chelsio}/cxgb4/t4_hw.c | 0
> drivers/net/{ => ethernet/chelsio}/cxgb4/t4_hw.h | 0
> drivers/net/{ => ethernet/chelsio}/cxgb4/t4_msg.h | 0
> drivers/net/{ => ethernet/chelsio}/cxgb4/t4_regs.h | 0
> .../net/{ => ethernet/chelsio}/cxgb4/t4fw_api.h | 0
> .../net/{ => ethernet/chelsio}/cxgb4vf/Makefile | 0
> .../net/{ => ethernet/chelsio}/cxgb4vf/adapter.h | 0
> .../{ => ethernet/chelsio}/cxgb4vf/cxgb4vf_main.c | 0
> drivers/net/{ => ethernet/chelsio}/cxgb4vf/sge.c | 0
> .../{ => ethernet/chelsio}/cxgb4vf/t4vf_common.h | 0
> .../net/{ => ethernet/chelsio}/cxgb4vf/t4vf_defs.h | 0
> .../net/{ => ethernet/chelsio}/cxgb4vf/t4vf_hw.c | 0
> 74 files changed, 115 insertions(+), 93 deletions(-)
>
> commit 1e954aa058cd1496b47b914878509e9ecf136d05
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Thu Apr 7 06:03:04 2011 -0700
>
> broadcom: Move the Broadcom drivers
>
> Moves the drivers for Broadcom devices into
> drivers/net/ethernet/broadcom/ and the necessary Kconfig and Makefile
> changes.
>
> CC: Eilon Greenstein <eilong@broadcom.com>
> CC: Michael Chan <mchan@broadcom.com>
> CC: Matt Carlson <mcarlson@broadcom.com>
> CC: Gary Zambrano <zambrano@broadcom.com>
> CC: "Maciej W. Rozycki" <macro@linux-mips.org>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 10 +-
> drivers/net/Kconfig | 99 -----------------
> drivers/net/Makefile | 7 --
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/broadcom/Kconfig | 114 ++++++++++++++++++++
> drivers/net/ethernet/broadcom/Makefile | 11 ++
> drivers/net/{ => ethernet/broadcom}/b44.c | 0
> drivers/net/{ => ethernet/broadcom}/b44.h | 0
> drivers/net/{ => ethernet/broadcom}/bcm63xx_enet.c | 0
> drivers/net/{ => ethernet/broadcom}/bcm63xx_enet.h | 0
> drivers/net/{ => ethernet/broadcom}/bnx2.c | 0
> drivers/net/{ => ethernet/broadcom}/bnx2.h | 0
> drivers/net/{ => ethernet/broadcom}/bnx2_fw.h | 0
> drivers/net/{ => ethernet/broadcom}/bnx2x/Makefile | 0
> drivers/net/{ => ethernet/broadcom}/bnx2x/bnx2x.h | 0
> .../net/{ => ethernet/broadcom}/bnx2x/bnx2x_cmn.c | 0
> .../net/{ => ethernet/broadcom}/bnx2x/bnx2x_cmn.h | 0
> .../net/{ => ethernet/broadcom}/bnx2x/bnx2x_dcb.c | 0
> .../net/{ => ethernet/broadcom}/bnx2x/bnx2x_dcb.h | 0
> .../net/{ => ethernet/broadcom}/bnx2x/bnx2x_dump.h | 0
> .../{ => ethernet/broadcom}/bnx2x/bnx2x_ethtool.c | 0
> .../{ => ethernet/broadcom}/bnx2x/bnx2x_fw_defs.h | 0
> .../broadcom}/bnx2x/bnx2x_fw_file_hdr.h | 0
> .../net/{ => ethernet/broadcom}/bnx2x/bnx2x_hsi.h | 0
> .../net/{ => ethernet/broadcom}/bnx2x/bnx2x_init.h | 0
> .../{ => ethernet/broadcom}/bnx2x/bnx2x_init_ops.h | 0
> .../net/{ => ethernet/broadcom}/bnx2x/bnx2x_link.c | 0
> .../net/{ => ethernet/broadcom}/bnx2x/bnx2x_link.h | 0
> .../net/{ => ethernet/broadcom}/bnx2x/bnx2x_main.c | 0
> .../net/{ => ethernet/broadcom}/bnx2x/bnx2x_reg.h | 0
> .../{ => ethernet/broadcom}/bnx2x/bnx2x_stats.c | 0
> .../{ => ethernet/broadcom}/bnx2x/bnx2x_stats.h | 0
> drivers/net/{ => ethernet/broadcom}/cnic.c | 4 +-
> drivers/net/{ => ethernet/broadcom}/cnic.h | 0
> drivers/net/{ => ethernet/broadcom}/cnic_defs.h | 0
> drivers/net/{ => ethernet/broadcom}/cnic_if.h | 0
> drivers/net/{ => ethernet/broadcom}/sb1250-mac.c | 0
> drivers/net/{ => ethernet/broadcom}/tg3.c | 0
> drivers/net/{ => ethernet/broadcom}/tg3.h | 0
> 40 files changed, 134 insertions(+), 113 deletions(-)
>
> commit 29072561a23c3802112a94fa0a9383773056f19a
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Sat Apr 2 06:20:12 2011 -0700
>
> 8390: Move the 8390 related drivers
>
> Moves the drivers for the National Semi-conductor 8390 chipset into
> drivers/net/ethernet/8390/ and the necessary Kconfig and Makefile
> changes.
>
> CC: Donald Becker <becker@scyld.com>
> CC: Paul Gortmaker <paul.gortmaker@windriver.com>
> CC: Alain Malek <alain.malek@cryogen.com>
> CC: Peter De Schrijver <p2@mind.be>
> CC: "David Huggins-Daines" <dhd@debian.org>
> CC: Wim Dumon <wimpie@kotnet.org>
> CC: Yoshinori Sato <ysato@users.sourceforge.jp>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 5 +-
> drivers/net/Kconfig | 283 -----------------------
> drivers/net/Makefile | 22 --
> drivers/net/ethernet/3com/Makefile | 2 +-
> drivers/net/{ => ethernet/8390}/8390.c | 0
> drivers/net/{ => ethernet/8390}/8390.h | 0
> drivers/net/{ => ethernet/8390}/8390p.c | 0
> drivers/net/ethernet/8390/Kconfig | 301 +++++++++++++++++++++++++
> drivers/net/ethernet/8390/Makefile | 26 +++
> drivers/net/{ => ethernet/8390}/ac3200.c | 0
> drivers/net/{ => ethernet/8390}/apne.c | 0
> drivers/net/{ => ethernet/8390}/ax88796.c | 0
> drivers/net/{ => ethernet/8390}/e2100.c | 0
> drivers/net/{ => ethernet/8390}/es3210.c | 0
> drivers/net/{ => ethernet/8390}/hp-plus.c | 0
> drivers/net/{ => ethernet/8390}/hp.c | 0
> drivers/net/{ => ethernet/8390}/hydra.c | 0
> drivers/net/{ => ethernet/8390}/lib8390.c | 0
> drivers/net/{ => ethernet/8390}/lne390.c | 0
> drivers/net/{ => ethernet/8390}/mac8390.c | 0
> drivers/net/{ => ethernet/8390}/ne-h8300.c | 0
> drivers/net/{ => ethernet/8390}/ne.c | 0
> drivers/net/{ => ethernet/8390}/ne2k-pci.c | 0
> drivers/net/{ => ethernet/8390}/ne3210.c | 0
> drivers/net/{ => ethernet/8390}/smc-mca.c | 0
> drivers/net/{ => ethernet/8390}/smc-ultra.c | 0
> drivers/net/{ => ethernet/8390}/smc-ultra32.c | 0
> drivers/net/{ => ethernet/8390}/stnic.c | 0
> drivers/net/{ => ethernet/8390}/wd.c | 0
> drivers/net/{ => ethernet/8390}/zorro8390.c | 0
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> 32 files changed, 332 insertions(+), 309 deletions(-)
>
> commit 6b9ef2886e37d62018cd72dcdd2918e9fb982aed
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Wed Mar 30 07:46:36 2011 -0700
>
> amd8111e/pcnet32/*lance/mvme147: Move AMD chipset drivers
>
> Moves the drivers for the AMD chipsets into drivers/net/ethernet/amd/
> and the necessary Kconfig and Makfile changes.
>
> CC: Peter Maydell <pmaydell@chiark.greenend.org.uk>
> CC: Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
> CC: "Maciej W. Rozycki" <macro@linux-mips.org>
> CC: Donald Becker <becker@scyld.com>
> CC: Sam Creasey <sammy@users.qual.net>
> CC: Miguel de Icaza <miguel@nuclecu.unam.mx>
> CC: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> drivers/net/Kconfig | 99 -----------------------
> drivers/net/Makefile | 9 --
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/{ => ethernet/amd}/7990.c | 0
> drivers/net/{ => ethernet/amd}/7990.h | 0
> drivers/net/ethernet/amd/Kconfig | 115 +++++++++++++++++++++++++++
> drivers/net/ethernet/amd/Makefile | 13 +++
> drivers/net/{ => ethernet/amd}/amd8111e.c | 0
> drivers/net/{ => ethernet/amd}/amd8111e.h | 0
> drivers/net/{ => ethernet/amd}/atarilance.c | 0
> drivers/net/{ => ethernet/amd}/declance.c | 0
> drivers/net/{ => ethernet/amd}/hplance.c | 0
> drivers/net/{ => ethernet/amd}/hplance.h | 0
> drivers/net/{ => ethernet/amd}/lance.c | 0
> drivers/net/{ => ethernet/amd}/mvme147.c | 0
> drivers/net/{ => ethernet/amd}/pcnet32.c | 0
> drivers/net/{ => ethernet/amd}/sun3lance.c | 0
> drivers/net/{ => ethernet/amd}/sunlance.c | 0
> 19 files changed, 130 insertions(+), 108 deletions(-)
>
> commit b2ee2cf62d14c842272db622d6be6374bc6d622a
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Wed Mar 30 03:47:06 2011 -0700
>
> 3c*/acenic/typhoon: Move 3Com Ethernet drivers
>
> Moves the 3Com drivers into drivers/net/ethernet/3com/ and the necessary
> Kconfig and Makefile changes.
>
> CC: Philip Blundell <philb@gnu.org>
> CC: Steffen Klassert <klassert@mathematik.tu-chemnitz.de>
> CC: David Dillow <dave@thedillows.org>
> CC: Jes Sorensen <jes@trained-monkey.org>
> CC: Alan Cox <alan@linux.intel.com>
> CC: Donald Becker <becker@scyld.com>
> CC: Craig Southeren <craigs@ineluki.apana.org.au>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> MAINTAINERS | 8 +-
> drivers/net/Kconfig | 177 ----------------------------
> drivers/net/Makefile | 12 +--
> drivers/net/{ => ethernet/3com}/3c501.c | 0
> drivers/net/{ => ethernet/3com}/3c501.h | 0
> drivers/net/{ => ethernet/3com}/3c503.c | 0
> drivers/net/{ => ethernet/3com}/3c503.h | 0
> drivers/net/{ => ethernet/3com}/3c505.c | 0
> drivers/net/{ => ethernet/3com}/3c505.h | 0
> drivers/net/{ => ethernet/3com}/3c507.c | 0
> drivers/net/{ => ethernet/3com}/3c509.c | 0
> drivers/net/{ => ethernet/3com}/3c515.c | 0
> drivers/net/{ => ethernet/3com}/3c523.c | 0
> drivers/net/{ => ethernet/3com}/3c523.h | 0
> drivers/net/{ => ethernet/3com}/3c527.c | 0
> drivers/net/{ => ethernet/3com}/3c527.h | 0
> drivers/net/{ => ethernet/3com}/3c59x.c | 0
> drivers/net/ethernet/3com/Kconfig | 180 +++++++++++++++++++++++++++++
> drivers/net/ethernet/3com/Makefile | 15 +++
> drivers/net/{ => ethernet/3com}/acenic.c | 0
> drivers/net/{ => ethernet/3com}/acenic.h | 0
> drivers/net/{ => ethernet/3com}/typhoon.c | 0
> drivers/net/{ => ethernet/3com}/typhoon.h | 0
> drivers/net/ethernet/Kconfig | 2 +
> drivers/net/ethernet/Makefile | 1 +
> 25 files changed, 203 insertions(+), 192 deletions(-)
>
> commit b918e3bb62b873c5436d413b99f593b3eed78901
> Author: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Tue Mar 29 18:25:21 2011 -0700
>
> drivers/net/ethernet: Add ethernet dir and config option
>
> This is the initial patch to organize the drivers/net directory
> structure and networking device driver config options. This patch
> does the following:
> - add drivers/net/ethernet/Kconfig
> - integrate the new files into the existing config
>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
>
> drivers/net/Kconfig | 2 ++
> drivers/net/Makefile | 2 +-
> drivers/net/ethernet/Kconfig | 14 ++++++++++++++
> drivers/net/ethernet/Makefile | 4 ++++
> 4 files changed, 21 insertions(+), 1 deletions(-)
>
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* Re: [PATCH] vhost: set dirty log when updating flags of used ring
From: Michael S. Tsirkin @ 2011-06-16 13:55 UTC (permalink / raw)
To: Jason Wang; +Cc: netdev, virtualization, linux-kernel, kvm
In-Reply-To: <20110616064556.9137.87807.stgit@dhcp-91-7.nay.redhat.com.englab.nay.redhat.com>
On Thu, Jun 16, 2011 at 02:45:56PM +0800, Jason Wang wrote:
> We need to set log when updating flags of used ring, otherwise they may
> be missed after migration. A helper was introduced to write used_flags
> back to guest memory and update the log if necessary.
>
> Signed-off-by: Jason Wang <jasowang@redhat.com>
> ---
> drivers/vhost/vhost.c | 26 ++++++++++++++++++++++----
> drivers/vhost/vhost.h | 2 ++
> 2 files changed, 24 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
> index 2ab2912..7c46aed 100644
> --- a/drivers/vhost/vhost.c
> +++ b/drivers/vhost/vhost.c
> @@ -573,8 +573,10 @@ static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m)
> static int init_used(struct vhost_virtqueue *vq,
> struct vring_used __user *used)
> {
> - int r = put_user(vq->used_flags, &used->flags);
> + int r;
>
> + vq->used = used;
> + r = vhost_update_used_flags(vq);
So I'm concerned that this will tweak the log if that's enabled even
though backend wasn't enabled yet so we didn't
verify that log writes are ok.
The reason we do this write here at all is because
during migration, remote might have left
exits masked, in which case we won't
get an exit.
A simple fix is to invoke the handler
when backend is enabled, that will
check the ring.
I actually think that maybe the last_used update should be delayed until
backend is set too - this will make it possible to stop
by removing the backend, tweak used index
then re-start. But let's make it a separate patch.
> if (r)
> return r;
> return get_user(vq->last_used_idx, &used->idx);
> @@ -700,7 +702,6 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp)
> vq->desc = (void __user *)(unsigned long)a.desc_user_addr;
> vq->avail = (void __user *)(unsigned long)a.avail_user_addr;
> vq->log_addr = a.log_guest_addr;
> - vq->used = (void __user *)(unsigned long)a.used_user_addr;
> break;
> case VHOST_SET_VRING_KICK:
> if (copy_from_user(&f, argp, sizeof f)) {
> @@ -1375,6 +1376,23 @@ void vhost_add_used_and_signal_n(struct vhost_dev *dev,
> vhost_signal(dev, vq);
> }
>
> +int vhost_update_used_flags(struct vhost_virtqueue *vq)
> +{
> + if (put_user(vq->used_flags, &vq->used->flags) < 0)
> + return -EFAULT;
> + if (unlikely(vq->log_used)) {
> + /* Make sure the flag is seen before log. */
> + smp_wmb();
> + /* Log used flag write. */
> + log_write(vq->log_base,
> + vq->log_addr + offsetof(struct vring_used, flags),
> + sizeof vq->used->flags);
> + if (vq->log_ctx)
> + eventfd_signal(vq->log_ctx, 1);
> + }
> + return 0;
> +}
> +
> /* OK, now we need to know about added descriptors. */
> bool vhost_enable_notify(struct vhost_virtqueue *vq)
> {
> @@ -1384,7 +1402,7 @@ bool vhost_enable_notify(struct vhost_virtqueue *vq)
> if (!(vq->used_flags & VRING_USED_F_NO_NOTIFY))
> return false;
> vq->used_flags &= ~VRING_USED_F_NO_NOTIFY;
> - r = put_user(vq->used_flags, &vq->used->flags);
> + r = vhost_update_used_flags(vq);
> if (r) {
> vq_err(vq, "Failed to enable notification at %p: %d\n",
> &vq->used->flags, r);
> @@ -1411,7 +1429,7 @@ void vhost_disable_notify(struct vhost_virtqueue *vq)
> if (vq->used_flags & VRING_USED_F_NO_NOTIFY)
> return;
> vq->used_flags |= VRING_USED_F_NO_NOTIFY;
> - r = put_user(vq->used_flags, &vq->used->flags);
> + r = vhost_update_used_flags(vq);
> if (r)
> vq_err(vq, "Failed to enable notification at %p: %d\n",
> &vq->used->flags, r);
> diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
> index b3363ae..76f4c61 100644
> --- a/drivers/vhost/vhost.h
> +++ b/drivers/vhost/vhost.h
> @@ -155,6 +155,8 @@ bool vhost_enable_notify(struct vhost_virtqueue *);
> int vhost_log_write(struct vhost_virtqueue *vq, struct vhost_log *log,
> unsigned int log_num, u64 len);
>
> +int vhost_update_used_flags(struct vhost_virtqueue *vq);
> +
Why declare it here? Make it static, flags is
an implementation detail and does not need to
get exported.
> #define vq_err(vq, fmt, ...) do { \
> pr_debug(pr_fmt(fmt), ##__VA_ARGS__); \
> if ((vq)->error_ctx) \
^ permalink raw reply
* [PATCH 14/14] SIWv2: Documentation: siw.txt
From: Bernard Metzler @ 2011-06-16 12:42 UTC (permalink / raw)
To: netdev; +Cc: linux-rdma, Bernard Metzler
---
Documentation/networking/siw.txt | 156 ++++++++++++++++++++++++++++++++++++++
1 files changed, 156 insertions(+), 0 deletions(-)
create mode 100644 Documentation/networking/siw.txt
diff --git a/Documentation/networking/siw.txt b/Documentation/networking/siw.txt
new file mode 100644
index 0000000..805e21b
--- /dev/null
+++ b/Documentation/networking/siw.txt
@@ -0,0 +1,156 @@
+SoftiWARP: Software iWARP kernel driver module.
+
+General
+-------
+SoftiWARP (siw) implements the iWARP protocol suite (MPA/DDP/RDMAP,
+IETF-RFC 5044/5041/5040) completely in software as a Linux kernel module.
+siw runs on top of TCP kernel sockets and exports the Linux kernel ibverbs
+RDMA interface. siw interfaces with the iwcm connection manager.
+
+
+Transmit Path
+-------------
+If a send queue (SQ) work queue element gets posted, siw tries to send
+it directly out of the application context. If the SQ was non-empty,
+SQ processing is done asynchronously by a kernel worker thread. This
+thread gets scheduled if the TCP socket signals new write space to
+be available. If during send operation the socket send space becomes
+exhausted, SQ processing is abandoned until new socket write space
+becomes available.
+
+
+Receive Path
+------------
+All application data is placed into target buffers within softirq
+socket callback. Application notification is asynchronous.
+
+
+User Interface
+--------------
+All user space fast path operations such as posting of work requests and
+reaping of work completions currently involve a isynchronous call into
+the siw kernel module via ib_uverbs interface. Kernel/user-mapped send
+and receive as well as completion queues are not part of the current code.
+In particular, mapped completion queues may improve performance,
+since reaping completion queue entries as well as re-arming
+the completion queue could be done more efficiently.
+
+
+Kernel Client Support
+---------------------
+To guarantee non-blocking fast path operations, for kernel clients
+all work queue elements (send/receive/shared-receive queue) are
+pre-allocated during connection resource setup.
+
+
+Memory Management
+-----------------
+siw currently uses the ib_umem_get() function of the ib_core module
+to pin memory for later use in data transfer operations. Transmit
+and receive memory are checked against correct access permissions only
+in the moment of access by the network input path or before pushing it
+to the TCP socket for transmission.
+ib_umem_get() provides DMA mappings for the requested address space which
+are not used by siw.
+
+
+Module Parameters
+-----------------
+The following siw module parameters are recognized.
+
+loopback_enabled:
+ If set, siw attaches also to the looback device. Checked only
+ during module insertion.
+
+mpa_crc_required:
+ If set, the MPA CRC gets generated and checked both in tx and rx
+ path. Without hardware support, setting this flag will severely
+ hurt throughput. Default setting is 0 (off).
+
+mpa_crc_strict:
+ If set, MPA CRC will not be enabled, even if peer requests
+ it. If the peer requests CRC generation, the connection setup
+ will be aborted. Default setting is 1 (on).
+
+zcopy_tx:
+ If set, payload of non-signalled work requests
+ (such as non-signalled WRITE or SEND as well as all READ
+ responses) are transferred using the TCP sockets
+ sendpage interface. This parameter can be switched on and
+ off dynamically (echo 1 >> /sys/module/siw/parameters/zcopy_tx
+ for enablement, 0 for disabling). System load may benefits from
+ using 0copy data transmission. 0copy is not enabled if
+ mpa_crc_enabled is set. Default setting is 1 (on).
+
+tcp_nodelay:
+ If set, on the TCP socket the TCP_NODELAY option is set.
+ Default setting is 1 (on).
+
+iface_list:
+ Comma separated list of interfaces siw should attach to.
+ If no list is given, siw attaches to all available devices.
+ If a list is given, siw skips those devices not listed.
+ Currently, the list is restricted to 12 entries. If needed,
+ the 'SIW_MAX_IF' #define in siw_main.c can be adaped.
+ This parameter might be usefull to skip devices which are
+ attached to a real RNIC device. Default setting is an empty list.
+
+
+Compile Time Flags:
+-------------------
+-DCHECK_DMA_CAPABILITIES
+ Checks if the device siw wants to attach to provides
+ DMA capabilities. While DMA capabilities are currently not
+ needed (siw works on top of a kernel TCP socket), siw
+ uses ib_umem_get() which performs a (not used) DMA address
+ translation. Writing a siw private memory reservation and
+ pinning routine would solve the issue.
+
+-DSIW_TX_FULLSEGS
+ Experimental, not enabled by default. If set,
+ siw tries not to overrun the socket (not sending until
+ -EAGAIN return), but stops sending if the current segment
+ would not fit into the socket's estimated tx buffer. With that,
+ wire FPDUs may get truncated by the TCP stack far less often.
+ Since this feature manipulates the sock's SOCK_NOSPACE
+ bit, it violates strict layering and is therefore considered
+ proprietary.
+ Since TCP is a byte stream protocol, no guarantee can be given
+ if FPDU's are not fragmented.
+
+
+Debugging SIW:
+--------------
+The siw_debug.h file defines a 'dprint' macro which is used to debug
+siw at runtime. Verbosity of debugging is controlled at compile time
+via setting the 'DPRINT_MASK' to a or'd list of know value as defined
+in siw_debug.h, e.g. '#define DPRINT_MASK (DBG_ON|DBG_CM)' to debug
+errors and connection management. Defining DPRINT_MASK to '0' avoids
+to compile any runtime debugging code.
+
+To track siw's useage of its objects (connection endpoints, tcp sockets,
+protection domains, queue pairs, shared receive queues, completion queues,
+memory registrations, work queue elements), the /sys/class/infiniband/siw*
+directory contains siw interface specific objects, which can be read to
+gather simple statistics:
+
+/sys/class/infiniband/siw*/stats:
+ Summary of allocated WQE's, PD's, QP's, CQ's, SRQ's, MR's, CEP's.
+ WQE statistics are not gathered if 'DPRINT_MASK' is set to '0'
+ (see above).
+
+/sys/class/infiniband/siw*/qp:
+ Summary of allocated queue pairs. If queue pairs are allocated,
+ after reading 'qp' a more detailed status of all queue pairs has
+ been printed to the kernel syslog and can be retrieved via
+ 'dmesg' command.
+
+/sys/class/infiniband/siw*/cep:
+ Summary of allocated connection end points. If connection endpoints
+ are allocated, after reading 'cep' a more detailed status of all
+ CEP's is printed to the kernel syslog and can be retrieved via
+ 'dmesg' command.
+
+Using the sysfs to gather siw's object allocations is considered a
+tentative aid during further driver development and should disappear
+in a stable version of siw.
--
1.5.4.3
^ permalink raw reply related
* [PATCH 13/14] SIWv2: Memory management: siw_mem.c
From: Bernard Metzler @ 2011-06-16 12:42 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA, Bernard Metzler
---
drivers/infiniband/hw/siw/siw_mem.c | 180 +++++++++++++++++++++++++++++++++++
1 files changed, 180 insertions(+), 0 deletions(-)
create mode 100644 drivers/infiniband/hw/siw/siw_mem.c
diff --git a/drivers/infiniband/hw/siw/siw_mem.c b/drivers/infiniband/hw/siw/siw_mem.c
new file mode 100644
index 0000000..8a3d65d
--- /dev/null
+++ b/drivers/infiniband/hw/siw/siw_mem.c
@@ -0,0 +1,180 @@
+/*
+ * Software iWARP device driver for Linux
+ *
+ * Authors: Animesh Trivedi <atr-OA+xvbQnYDHMbYB6QlFGEg@public.gmane.org>
+ * Bernard Metzler <bmt-OA+xvbQnYDHMbYB6QlFGEg@public.gmane.org>
+ *
+ * Copyright (c) 2008-2011, IBM Corporation
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of IBM nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#include <linux/scatterlist.h>
+#include <linux/gfp.h>
+#include <rdma/ib_verbs.h>
+
+#include "siw.h"
+#include "siw_verbs.h"
+
+/*
+ * DMA mapping/address translation functions.
+ * Used to populate siw private DMA mapping functions of
+ * struct ib_dma_mapping_ops in struct ib_dev - see rdma/ib_verbs.h
+ */
+
+static int siw_mapping_error(struct ib_device *dev, u64 dma_addr)
+{
+ return dma_addr == 0;
+}
+
+static u64 siw_dma_map_single(struct ib_device *dev, void *kva, size_t size,
+ enum dma_data_direction dir)
+{
+ /* siw uses kernel virtual addresses for data transfer */
+ return (u64) kva;
+}
+
+static void siw_dma_unmap_single(struct ib_device *dev,
+ u64 addr, size_t size,
+ enum dma_data_direction dir)
+{
+ /* NOP */
+}
+
+static u64 siw_dma_map_page(struct ib_device *dev, struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction dir)
+{
+ u64 kva = 0;
+
+ BUG_ON(!valid_dma_direction(dir));
+
+ if (offset + size <= PAGE_SIZE) {
+ kva = (u64) page_address(page);
+ if (kva)
+ kva += offset;
+ }
+ return kva;
+}
+
+static void siw_dma_unmap_page(struct ib_device *dev,
+ u64 addr, size_t size,
+ enum dma_data_direction dir)
+{
+ /* NOP */
+}
+
+static int siw_map_sg(struct ib_device *dev, struct scatterlist *sgl,
+ int n_sge, enum dma_data_direction dir)
+{
+ struct scatterlist *sg;
+ int i;
+
+ BUG_ON(!valid_dma_direction(dir));
+
+ /* This is just a validity check */
+ for_each_sg(sgl, sg, n_sge, i)
+ if (page_address(sg_page(sg)) == NULL)
+ return 0;
+
+ return n_sge;
+}
+
+static void siw_unmap_sg(struct ib_device *dev, struct scatterlist *sgl,
+ int n_sge, enum dma_data_direction dir)
+{
+ /* NOP */
+}
+
+static u64 siw_dma_address(struct ib_device *dev, struct scatterlist *sg)
+{
+ u64 kva = (u64) page_address(sg_page(sg));
+
+ if (kva)
+ kva += sg->offset;
+
+ return kva;
+}
+
+static unsigned int siw_dma_len(struct ib_device *dev,
+ struct scatterlist *sg)
+{
+ return sg_dma_len(sg);
+}
+
+static void siw_sync_single_for_cpu(struct ib_device *dev, u64 addr,
+ size_t size, enum dma_data_direction dir)
+{
+ /* NOP */
+}
+
+static void siw_sync_single_for_device(struct ib_device *dev, u64 addr,
+ size_t size,
+ enum dma_data_direction dir)
+{
+ /* NOP */
+}
+
+static void *siw_dma_alloc_coherent(struct ib_device *dev, size_t size,
+ u64 *dma_addr, gfp_t flag)
+{
+ struct page *page;
+ void *kva = NULL;
+
+ page = alloc_pages(flag, get_order(size));
+ if (page)
+ kva = page_address(page);
+ if (dma_addr)
+ *dma_addr = (u64)kva;
+
+ return kva;
+}
+
+static void siw_dma_free_coherent(struct ib_device *dev, size_t size,
+ void *kva, u64 dma_addr)
+{
+ free_pages((unsigned long) kva, get_order(size));
+}
+
+struct ib_dma_mapping_ops siw_dma_mapping_ops = {
+ .mapping_error = siw_mapping_error,
+ .map_single = siw_dma_map_single,
+ .unmap_single = siw_dma_unmap_single,
+ .map_page = siw_dma_map_page,
+ .unmap_page = siw_dma_unmap_page,
+ .map_sg = siw_map_sg,
+ .unmap_sg = siw_unmap_sg,
+ .dma_address = siw_dma_address,
+ .dma_len = siw_dma_len,
+ .sync_single_for_cpu = siw_sync_single_for_cpu,
+ .sync_single_for_device = siw_sync_single_for_device,
+ .alloc_coherent = siw_dma_alloc_coherent,
+ .free_coherent = siw_dma_free_coherent
+};
--
1.5.4.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 12/14] SIWv2: Debugging and Tracing: siw_debug.c, siw_debug.h
From: Bernard Metzler @ 2011-06-16 12:42 UTC (permalink / raw)
To: netdev; +Cc: linux-rdma, Bernard Metzler
---
drivers/infiniband/hw/siw/siw_debug.c | 200 +++++++++++++++++++++++++++++++++
drivers/infiniband/hw/siw/siw_debug.h | 160 ++++++++++++++++++++++++++
2 files changed, 360 insertions(+), 0 deletions(-)
create mode 100644 drivers/infiniband/hw/siw/siw_debug.c
create mode 100644 drivers/infiniband/hw/siw/siw_debug.h
diff --git a/drivers/infiniband/hw/siw/siw_debug.c b/drivers/infiniband/hw/siw/siw_debug.c
new file mode 100644
index 0000000..06c548d
--- /dev/null
+++ b/drivers/infiniband/hw/siw/siw_debug.c
@@ -0,0 +1,200 @@
+/*
+ * Software iWARP device driver for Linux
+ *
+ * Authors: Bernard Metzler <bmt@zurich.ibm.com>
+ * Fredy Neeser <nfd@zurich.ibm.com>
+ *
+ * Copyright (c) 2008-2011, IBM Corporation
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of IBM nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <net/tcp.h>
+
+#include <rdma/iw_cm.h>
+#include <rdma/ib_verbs.h>
+#include <rdma/ib_umem.h>
+#include <rdma/ib_smi.h>
+#include <rdma/ib_user_verbs.h>
+
+#include "siw.h"
+#include "siw_obj.h"
+
+
+void siw_print_qp_attr_mask(enum ib_qp_attr_mask attr_mask, char *msg)
+{
+ printk(KERN_INFO "-------- %s -------\n", msg);
+ if (IB_QP_STATE & attr_mask)
+ printk(KERN_INFO "IB_QP_STATE\n");
+ if (IB_QP_CUR_STATE & attr_mask)
+ printk(KERN_INFO "IB_QP_CUR_STATE\n");
+ if (IB_QP_EN_SQD_ASYNC_NOTIFY & attr_mask)
+ printk(KERN_INFO "IB_QP_EN_SQD_ASYNC_NOTIFY\n");
+ if (IB_QP_ACCESS_FLAGS & attr_mask)
+ printk(KERN_INFO "IB_QP_ACCESS_FLAGS\n");
+ if (IB_QP_PKEY_INDEX & attr_mask)
+ printk(KERN_INFO "IB_QP_PKEY_INDEX\n");
+ if (IB_QP_PORT & attr_mask)
+ printk(KERN_INFO "IB_QP_PORT\n");
+ if (IB_QP_QKEY & attr_mask)
+ printk(KERN_INFO "IB_QP_QKEY\n");
+ if (IB_QP_AV & attr_mask)
+ printk(KERN_INFO "IB_QP_AV\n");
+ if (IB_QP_PATH_MTU & attr_mask)
+ printk(KERN_INFO "IB_QP_PATH_MTU\n");
+ if (IB_QP_TIMEOUT & attr_mask)
+ printk(KERN_INFO "IB_QP_TIMEOUT\n");
+ if (IB_QP_RETRY_CNT & attr_mask)
+ printk(KERN_INFO "IB_QP_RETRY_CNT\n");
+ if (IB_QP_RNR_RETRY & attr_mask)
+ printk(KERN_INFO "IB_QP_RNR_RETRY\n");
+ if (IB_QP_RQ_PSN & attr_mask)
+ printk(KERN_INFO "IB_QP_RQ_PSN\n");
+ if (IB_QP_MAX_QP_RD_ATOMIC & attr_mask)
+ printk(KERN_INFO "IB_QP_MAX_QP_RD_ATOMIC\n");
+ if (IB_QP_ALT_PATH & attr_mask)
+ printk(KERN_INFO "IB_QP_ALT_PATH\n");
+ if (IB_QP_MIN_RNR_TIMER & attr_mask)
+ printk(KERN_INFO "IB_QP_MIN_RNR_TIMER\n");
+ if (IB_QP_SQ_PSN & attr_mask)
+ printk(KERN_INFO "IB_QP_SQ_PSN\n");
+ if (IB_QP_MAX_DEST_RD_ATOMIC & attr_mask)
+ printk(KERN_INFO "IB_QP_MAX_DEST_RD_ATOMIC\n");
+ if (IB_QP_PATH_MIG_STATE & attr_mask)
+ printk(KERN_INFO "IB_QP_PATH_MIG_STATE\n");
+ if (IB_QP_CAP & attr_mask)
+ printk(KERN_INFO "IB_QP_CAP\n");
+ if (IB_QP_DEST_QPN & attr_mask)
+ printk(KERN_INFO "IB_QP_DEST_QPN\n");
+ printk(KERN_INFO "-------- %s -(end)-\n", msg);
+}
+
+
+void siw_print_hdr(union iwarp_hdrs *hdr, int qp_id, char *msg)
+{
+ switch (hdr->ctrl.opcode) {
+
+ case RDMAP_RDMA_WRITE:
+ printk(KERN_INFO "QP%04d %s(WRITE, MPA len %d): "
+ "%08x %016llx\n",
+ qp_id, msg, ntohs(hdr->ctrl.mpa_len),
+ hdr->rwrite.sink_stag, hdr->rwrite.sink_to);
+ break;
+
+ case RDMAP_RDMA_READ_REQ:
+ printk(KERN_INFO "QP%04d %s(RREQ, MPA len %d): %08x %08x "
+ "%08x %08x %016llx %08x %08x %016llx\n", qp_id, msg,
+ ntohs(hdr->ctrl.mpa_len),
+ hdr->rreq.ddp_qn, hdr->rreq.ddp_msn,
+ hdr->rreq.ddp_mo, hdr->rreq.sink_stag,
+ hdr->rreq.sink_to, hdr->rreq.read_size,
+ hdr->rreq.source_stag, hdr->rreq.source_to);
+
+ break;
+ case RDMAP_RDMA_READ_RESP:
+ printk(KERN_INFO "QP%04d %s(RRESP, MPA len %d):"
+ " %08x %016llx\n",
+ qp_id, msg, ntohs(hdr->ctrl.mpa_len),
+ hdr->rresp.sink_stag, hdr->rresp.sink_to);
+ break;
+
+ case RDMAP_SEND:
+ printk(KERN_INFO "QP%04d %s(SEND, MPA len %d): %08x %08x "
+ "%08x\n", qp_id, msg, ntohs(hdr->ctrl.mpa_len),
+ hdr->send.ddp_qn, hdr->send.ddp_msn, hdr->send.ddp_mo);
+ break;
+
+ case RDMAP_SEND_INVAL:
+ printk(KERN_INFO "QP%04d %s(S_INV, MPA len %d): %08x %08x "
+ "%08x\n", qp_id, msg, ntohs(hdr->ctrl.mpa_len),
+ hdr->send.ddp_qn, hdr->send.ddp_msn,
+ hdr->send.ddp_mo);
+ break;
+
+ case RDMAP_SEND_SE:
+ printk(KERN_INFO "QP%04d %s(S_SE, MPA len %d): %08x %08x "
+ "%08x\n", qp_id, msg, ntohs(hdr->ctrl.mpa_len),
+ hdr->send.ddp_qn, hdr->send.ddp_msn,
+ hdr->send.ddp_mo);
+ break;
+
+ case RDMAP_SEND_SE_INVAL:
+ printk(KERN_INFO "QP%04d %s(S_SE_INV, MPA len %d): %08x %08x "
+ "%08x\n", qp_id, msg, ntohs(hdr->ctrl.mpa_len),
+ hdr->send.ddp_qn, hdr->send.ddp_msn,
+ hdr->send.ddp_mo);
+ break;
+
+ case RDMAP_TERMINATE:
+ printk(KERN_INFO "QP%04d %s(TERM, MPA len %d):\n", qp_id, msg,
+ ntohs(hdr->ctrl.mpa_len));
+ break;
+
+ default:
+ printk(KERN_INFO "QP%04d %s ?????\n", qp_id, msg);
+ break;
+ }
+}
+
+void siw_print_rctx(struct siw_iwarp_rx *rctx)
+{
+ printk(KERN_INFO "---RX Context-->\n");
+ siw_print_hdr(&rctx->hdr, RX_QPID(rctx), "\nCurrent Pkt:\t");
+ printk(KERN_INFO "Skbuf State:\tp:0x%p, new:%d, off:%d, copied:%d\n",
+ rctx->skb, rctx->skb_new, rctx->skb_offset, rctx->skb_copied);
+ printk(KERN_INFO "FPDU State:\trx_state:%d,\n\t\trcvd:%d, rem:%d, "
+ "pad:%d\n", rctx->state, rctx->fpdu_part_rcvd,
+ rctx->fpdu_part_rem, rctx->pad);
+ printk(KERN_INFO "Rx Mem:\t\tp:0x%p, chunk:0x%p,\n\t\tp_ix:%d, "
+ "p_off:%d, stag:0x%08x, mem_id:%d\n",
+ rctx->dest.wqe, rctx->umem_chunk, rctx->pg_idx, rctx->pg_off,
+ rctx->ddp_stag, rctx->ddp_stag >> 8);
+ printk(KERN_INFO "DDP State:\tprev_op:%d, first_seg:%d, "
+ "more_segs:%d\n", rctx->prev_ddp_opcode, rctx->first_ddp_seg,
+ rctx->more_ddp_segs);
+ printk(KERN_INFO "MPA State:\tlen:%d, crc_enabled:%d, crc:0x%x\n",
+ rctx->hdr.ctrl.mpa_len, rctx->crc_enabled, rctx->trailer.crc);
+ printk(KERN_INFO "<---------------\n");
+}
+
+#if DPRINT_MASK > 0
+char ib_qp_state_to_string[IB_QPS_ERR+1][sizeof "RESET"] = {
+ [IB_QPS_RESET] = "RESET",
+ [IB_QPS_INIT] = "INIT",
+ [IB_QPS_RTR] = "RTR",
+ [IB_QPS_RTS] = "RTS",
+ [IB_QPS_SQD] = "SQD",
+ [IB_QPS_SQE] = "SQE",
+ [IB_QPS_ERR] = "ERR"
+};
+#endif
diff --git a/drivers/infiniband/hw/siw/siw_debug.h b/drivers/infiniband/hw/siw/siw_debug.h
new file mode 100644
index 0000000..4769bec
--- /dev/null
+++ b/drivers/infiniband/hw/siw/siw_debug.h
@@ -0,0 +1,160 @@
+/*
+ * Software iWARP device driver for Linux
+ *
+ * Authors: Fredy Neeser <nfd@zurich.ibm.com>
+ * Bernard Metzler <bmt@zurich.ibm.com>
+ *
+ * Copyright (c) 2008-2011, IBM Corporation
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of IBM nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef _SIW_DEBUG_H
+#define _SIW_DEBUG_H
+
+#include <linux/uaccess.h>
+#include <linux/hardirq.h> /* in_interrupt() */
+
+/*
+ * dprint: Selective debug printing
+ *
+ * Use an OR combination of DBG_* as dbgcat in dprint*(dbgcat,...)
+ * to assign debug messages to categories:
+ *
+ * dbgcat Debug message belongs to category
+ * ----------------------------------------------------------------------------
+ * DBG_ON Always on, for really important events or error conditions
+ * DBG_TMP Temporarily on for fine-grained debugging
+ * DBQ_OBJ Object management (object construction/destruction/refcounting)
+ * DBG_MM Memory management
+ * DBG_EH Event handling (completion events and asynchronous events)
+ * DBG_CM Connection management, QP states
+ * DBG_WR Work requests
+ * DBG_TX iWARP TX path
+ * DBG_RX iWARP RX path
+ * DBG_SK Socket operations
+ * DBG_KT Kernel threads
+ * DBG_IRQ Interrupt context (SoftIRQ or HardIRQ)
+ * DBG_DM Device management
+ * DBG_HDR Packet HDRs
+ * DBG_ALL All categories above
+ */
+#define DBG_ON 0x00000001
+#define DBG_TMP 0x00000002
+#define DBG_OBJ 0x00000004
+#define DBG_MM 0x00000008
+#define DBG_EH 0x00000010
+#define DBG_CM 0x00000020
+#define DBG_WR 0x00000040
+#define DBG_TX 0x00000080
+#define DBG_RX 0x00000100
+#define DBG_SK 0x00000200
+#define DBG_KT 0x00000400
+#define DBG_IRQ 0x00000800
+#define DBG_DM 0x00001000
+#define DBG_HDR 0x00002000
+#define DBG_ALL (DBG_IRQ|DBG_KT|DBG_SK|DBG_RX|DBG_TX|DBG_WR|\
+DBG_CM|DBG_EH|DBG_MM|DBG_OBJ|DBG_TMP|DBG_DM|DBG_ON|DBG_HDR)
+#define DBG_ALL_NOHDR (DBG_IRQ|DBG_KT|DBG_SK|DBG_RX|DBG_TX|DBG_WR|\
+DBG_CM|DBG_EH|DBG_MM|DBG_OBJ|DBG_TMP|DBG_DM|DBG_ON)
+#define DBG_CTRL (DBG_ON|DBG_CM|DBG_DM)
+
+/*
+ * Set DPRINT_MASK to tailor your debugging needs:
+ *
+ * DPRINT_MASK value Enables debug messages for
+ * ---------------------------------------------------------------------
+ * DBG_ON Important events / error conditions only
+ * (minimum number of debug messages)
+ * OR-ed combination of DBG_* Selective debugging
+ * DBG_KT|DBG_ON Kernel threads
+ * DBG_ALL All categories
+ */
+#define DPRINT_MASK 0
+
+extern void siw_print_hdr(union iwarp_hdrs *, int, char *);
+extern void siw_print_rctx(struct siw_iwarp_rx *);
+extern void siw_print_qp_attr_mask(enum ib_qp_attr_mask, char *);
+
+#if DPRINT_MASK > 0
+
+/**
+ * dprint - Selective debug print for process, SoftIRQ or HardIRQ context
+ *
+ * Debug print with selectable debug categories,
+ * starting with header
+ * - "( pid /cpu) __func__" for process context
+ * - "( irq /cpu) __func__" for IRQ context
+ *
+ * @dbgcat : Set of debug categories (OR-ed combination of DBG_* above),
+ * to which this debug message is assigned.
+ * @fmt : printf compliant format string
+ * @args : printf compliant argument list
+ */
+#define dprint(dbgcat, fmt, args...) \
+ do { \
+ if ((dbgcat) & DPRINT_MASK) { \
+ if (!in_interrupt()) \
+ printk(KERN_INFO "(%5d/%1d) %s" fmt, \
+ current->pid, \
+ current_thread_info()->cpu, \
+ __func__, ## args); \
+ else \
+ printk(KERN_INFO "( irq /%1d) %s" fmt, \
+ current_thread_info()->cpu, \
+ __func__, ## args); \
+ } \
+ } while (0)
+
+
+#define siw_dprint_rctx(r) siw_print_rctx(r)
+extern char ib_qp_state_to_string[IB_QPS_ERR+1][sizeof "RESET"];
+
+#else
+#define dprint(dbgcat, fmt, args...) do { } while (0)
+#define siw_dprint_rctx(r) do { } while (0)
+#endif
+
+
+#if DPRINT_MASK & DBG_HDR
+#define siw_dprint_hdr(h, i, m) siw_print_hdr(h, i, m)
+#else
+#define siw_dprint_hdr(h, i, m) do { } while (0)
+#endif
+
+#if DPRINT_MASK & DBG_CM
+#define siw_dprint_qp_attr_mask(mask)\
+ siw_print_qp_attr_mask(mask, (char *)__func__)
+#else
+#define siw_dprint_qp_attr_mask(mask) do { } while (0)
+#endif
+
+#endif
--
1.5.4.3
^ permalink raw reply related
* [PATCH 11/14] SIWv2: Receive path: siw_qp_rx.c
From: Bernard Metzler @ 2011-06-16 12:42 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA, Bernard Metzler
---
drivers/infiniband/hw/siw/siw_qp_rx.c | 1557 +++++++++++++++++++++++++++++++++
1 files changed, 1557 insertions(+), 0 deletions(-)
create mode 100644 drivers/infiniband/hw/siw/siw_qp_rx.c
diff --git a/drivers/infiniband/hw/siw/siw_qp_rx.c b/drivers/infiniband/hw/siw/siw_qp_rx.c
new file mode 100644
index 0000000..2e9045c
--- /dev/null
+++ b/drivers/infiniband/hw/siw/siw_qp_rx.c
@@ -0,0 +1,1557 @@
+/*
+ * Software iWARP device driver for Linux
+ *
+ * Authors: Bernard Metzler <bmt-OA+xvbQnYDHMbYB6QlFGEg@public.gmane.org>
+ * Fredy Neeser <nfd-OA+xvbQnYDHMbYB6QlFGEg@public.gmane.org>
+ *
+ * Copyright (c) 2008-2011, IBM Corporation
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of IBM nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/net.h>
+#include <linux/scatterlist.h>
+#include <linux/highmem.h>
+#include <net/sock.h>
+#include <net/tcp_states.h>
+#include <net/tcp.h>
+
+#include <rdma/iw_cm.h>
+#include <rdma/ib_verbs.h>
+#include <rdma/ib_smi.h>
+#include <rdma/ib_user_verbs.h>
+#include <rdma/ib_umem.h>
+
+#include "siw.h"
+#include "siw_obj.h"
+#include "siw_cm.h"
+
+
+/*
+ * ----------------------------
+ * DDP reassembly for Softiwarp
+ * ----------------------------
+ * For the ordering of transmitted DDP segments, the relevant iWARP ordering
+ * rules are as follows:
+ *
+ * - RDMAP (RFC 5040): Section 7.5, Rule 17:
+ * "RDMA Read Response Message processing at the Remote Peer (reading
+ * the specified Tagged Buffer) MUST be started only after the RDMA
+ * Read Request Message has been Delivered by the DDP layer (thus,
+ * all previous RDMA Messages have been properly submitted for
+ * ordered Placement)."
+ *
+ * - DDP (RFC 5041): Section 5.3:
+ * "At the Data Source, DDP:
+ * o MUST transmit DDP Messages in the order they were submitted to
+ * the DDP layer,
+ * o SHOULD transmit DDP Segments within a DDP Message in increasing
+ * MO order for Untagged DDP Messages, and in increasing TO order
+ * for Tagged DDP Messages."
+ *
+ * Combining these rules implies that, although RDMAP does not provide
+ * ordering between operations that are generated from the two ends of an
+ * RDMAP stream, DDP *must not* transmit an RDMA Read Response Message before
+ * it has finished transmitting SQ operations that were already submitted
+ * to the DDP layer. It follows that an iWARP transmitter must fully
+ * serialize RDMAP messages belonging to the same QP.
+ *
+ * Given that a TCP socket receives DDP segments in peer transmit order,
+ * we obtain the following ordering of received DDP segments:
+ *
+ * (i) the received DDP segments of RDMAP messages for the same QP
+ * cannot be interleaved
+ * (ii) the received DDP segments of a single RDMAP message *should*
+ * arrive in order.
+ *
+ * The Softiwarp transmitter obeys rule #2 in DDP Section 5.3.
+ * With this property, the "should" becomes a "must" in (ii) above,
+ * which simplifies DDP reassembly considerably.
+ * The Softiwarp receiver currently relies on this property
+ * and reports an error if DDP segments of the same RDMAP message
+ * do not arrive in sequence.
+ */
+
+static inline int siw_crc_rxhdr(struct siw_iwarp_rx *ctx)
+{
+ crypto_hash_init(&ctx->mpa_crc_hd);
+
+ return siw_crc_array(&ctx->mpa_crc_hd, (u8 *)&ctx->hdr,
+ ctx->fpdu_part_rcvd);
+}
+
+
+/*
+ * siw_rx_umem_init()
+ *
+ * Given memory region @mr and tagged offset @t_off within @mr,
+ * resolve corresponding ib_umem_chunk memory chunk pointer
+ * and update receive context variables to point at receive position.
+ * returns 0 on sucess and failure otherwise.
+ *
+ * NOTE: This function expects virtual addresses.
+ * TODO: Function needs generalization to support relative adressing
+ * aka "ZBVA".
+ *
+ * @rctx: Receive Context to be updated
+ * @mr: Memory Region
+ * @t_off: Offset within Memory Region
+ *
+ */
+static int siw_rx_umem_init(struct siw_iwarp_rx *rctx, struct siw_mr *mr,
+ u64 t_off)
+{
+ struct ib_umem_chunk *chunk;
+ u64 off_mr; /* offset into MR */
+ int psge_idx; /* Index of PSGE */
+
+ off_mr = t_off - (mr->mem.va & PAGE_MASK);
+ /*
+ * Equivalent to
+ * off_mr = t_off - mr->mem.va;
+ * off_mr += mr->umem->offset;
+ */
+
+ /* Skip pages not referenced by t_off */
+ psge_idx = off_mr >> PAGE_SHIFT;
+
+ list_for_each_entry(chunk, &mr->umem->chunk_list, list) {
+ if (psge_idx < chunk->nents)
+ break;
+ psge_idx -= chunk->nents;
+ }
+ if (psge_idx >= chunk->nents) {
+ dprint(DBG_MM|DBG_ON, "(QP%d): Short chunk list\n",
+ RX_QPID(rctx));
+ return -EINVAL;
+ }
+ rctx->pg_idx = psge_idx;
+ rctx->pg_off = off_mr & ~PAGE_MASK;
+ rctx->umem_chunk = chunk;
+
+ dprint(DBG_MM, "(QP%d): New chunk, idx %d\n", RX_QPID(rctx), psge_idx);
+ return 0;
+}
+
+
+/*
+ * siw_rx_umem()
+ *
+ * Receive data of @len into target referenced by @rctx.
+ * This function does not check if umem is within bounds requested by
+ * @len and @t_off. @umem_ends indicates if routine should
+ * not update chunk position pointers after the point it is
+ * currently receiving
+ *
+ * @rctx: Receive Context
+ * @len: Number of bytes to place
+ * @umen_ends: 1, if rctx chunk pointer should not be updated after len.
+ */
+static int siw_rx_umem(struct siw_iwarp_rx *rctx, int len, int umem_ends)
+{
+ struct scatterlist *p_list;
+ void *dest;
+ struct ib_umem_chunk *chunk = rctx->umem_chunk;
+ int pg_off = rctx->pg_off,
+ copied = 0,
+ bytes,
+ rv;
+
+ while (len) {
+ bytes = min(len, (int)PAGE_SIZE - pg_off);
+ p_list = &chunk->page_list[rctx->pg_idx];
+
+ dest = kmap_atomic(sg_page(p_list), KM_SOFTIRQ0);
+
+ rv = skb_copy_bits(rctx->skb, rctx->skb_offset, dest + pg_off,
+ bytes);
+
+ dprint(DBG_RX, "(QP%d): Page #%d, "
+ "bytes=%u, rv=%d returned by skb_copy_bits()\n",
+ RX_QPID(rctx), rctx->pg_idx, bytes, rv);
+
+ if (likely(!rv)) {
+ if (rctx->crc_enabled)
+ rv = siw_crc_sg(&rctx->mpa_crc_hd, p_list,
+ pg_off, bytes);
+
+ rctx->skb_offset += bytes;
+ copied += bytes;
+ len -= bytes;
+ pg_off += bytes;
+ }
+
+ kunmap_atomic(dest, KM_SOFTIRQ0);
+
+ if (unlikely(rv)) {
+ rctx->skb_copied += copied;
+ rctx->skb_new -= copied;
+ copied = -EFAULT;
+
+ dprint(DBG_RX|DBG_ON, "(QP%d): failed with %d\n",
+ RX_QPID(rctx), rv);
+
+ goto out;
+ }
+ if (pg_off == PAGE_SIZE) {
+ /*
+ * end of page
+ */
+ pg_off = 0;
+ /*
+ * reference next page chunk if
+ * - all pages in chunk used AND
+ * - current loop fills more into this umem
+ * OR the next receive will go into this umem
+ * starting at the position where we are leaving
+ * the routine.
+ */
+ if (++rctx->pg_idx == chunk->nents &&
+ (len > 0 || !umem_ends)) {
+
+ rctx->pg_idx = 0;
+ chunk = mem_chunk_next(chunk);
+ }
+ }
+ }
+ /*
+ * store chunk position for resume
+ */
+ rctx->umem_chunk = chunk;
+ rctx->pg_off = pg_off;
+
+ rctx->skb_copied += copied;
+ rctx->skb_new -= copied;
+out:
+ return copied;
+}
+
+static inline int siw_rx_kva(struct siw_iwarp_rx *rctx, int len, void *kva)
+{
+ int rv = skb_copy_bits(rctx->skb, rctx->skb_offset, kva, len);
+
+ if (likely(!rv)) {
+ rctx->skb_offset += len;
+ rctx->skb_copied += len;
+ rctx->skb_new -= len;
+ if (rctx->crc_enabled) {
+ rv = siw_crc_array(&rctx->mpa_crc_hd, kva, len);
+ if (rv)
+ goto done;
+ }
+ rv = len;
+ }
+done:
+ return rv;
+}
+
+/*
+ * siw_rresp_check_ntoh()
+ *
+ * Check incoming RRESP fragment header against expected
+ * header values and update expected values for potential next
+ * fragment.
+ *
+ * NOTE: This function must be called only if a RRESP DDP segment
+ * starts but not for fragmented consecutive pieces of an
+ * already started DDP segement.
+ */
+static inline int siw_rresp_check_ntoh(struct siw_iwarp_rx *rctx)
+{
+ struct iwarp_rdma_rresp *rresp = &rctx->hdr.rresp;
+ struct siw_wqe *wqe = rctx->dest.wqe;
+
+ rresp->sink_stag = be32_to_cpu(rresp->sink_stag);
+ rresp->sink_to = be64_to_cpu(rresp->sink_to);
+
+ if (rctx->first_ddp_seg) {
+ rctx->ddp_stag = wqe->wr.rread.sge[0].lkey;
+ rctx->ddp_to = wqe->wr.rread.sge[0].addr;
+ }
+ if (rctx->ddp_stag != rresp->sink_stag) {
+ dprint(DBG_RX|DBG_ON,
+ " received STAG=%08x, expected STAG=%08x\n",
+ rresp->sink_stag, rctx->ddp_stag);
+ /*
+ * Verbs: RI_EVENT_QP_LLP_INTEGRITY_ERROR_BAD_FPDU
+ */
+ return -EINVAL;
+ }
+ if (rctx->ddp_to != rresp->sink_to) {
+ dprint(DBG_RX|DBG_ON,
+ " received TO=%016llx, expected TO=%016llx\n",
+ (unsigned long long)rresp->sink_to,
+ (unsigned long long)rctx->ddp_to);
+ /*
+ * Verbs: RI_EVENT_QP_LLP_INTEGRITY_ERROR_BAD_FPDU
+ */
+ return -EINVAL;
+ }
+ if (rctx->more_ddp_segs)
+ rctx->ddp_to += rctx->fpdu_part_rem;
+
+ else if (wqe->processed + rctx->fpdu_part_rem != wqe->bytes) {
+ dprint(DBG_RX|DBG_ON,
+ " RRESP length does not match RREQ, "
+ "peer sent=%d, expected %d\n",
+ wqe->processed + rctx->fpdu_part_rem, wqe->bytes);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/*
+ * siw_write_check_ntoh()
+ *
+ * Check incoming WRITE fragment header against expected
+ * header values and update expected values for potential next
+ * fragment
+ *
+ * NOTE: This function must be called only if a WRITE DDP segment
+ * starts but not for fragmented consecutive pieces of an
+ * already started DDP segement.
+ */
+static inline int siw_write_check_ntoh(struct siw_iwarp_rx *rctx)
+{
+ struct iwarp_rdma_write *write = &rctx->hdr.rwrite;
+
+ write->sink_stag = be32_to_cpu(write->sink_stag);
+ write->sink_to = be64_to_cpu(write->sink_to);
+
+ if (rctx->first_ddp_seg) {
+ rctx->ddp_stag = write->sink_stag;
+ rctx->ddp_to = write->sink_to;
+ } else {
+ if (rctx->ddp_stag != write->sink_stag) {
+ dprint(DBG_RX|DBG_ON,
+ " received STAG=%08x, expected STAG=%08x\n",
+ write->sink_stag, rctx->ddp_stag);
+ /*
+ * Verbs: RI_EVENT_QP_LLP_INTEGRITY_ERROR_BAD_FPDU
+ */
+ return -EINVAL;
+ }
+ if (rctx->ddp_to != write->sink_to) {
+ dprint(DBG_RX|DBG_ON,
+ " received TO=%016llx, expected TO=%016llx\n",
+ (unsigned long long)write->sink_to,
+ (unsigned long long)rctx->ddp_to);
+ /*
+ * Verbs: RI_EVENT_QP_LLP_INTEGRITY_ERROR_BAD_FPDU
+ */
+ return -EINVAL;
+ }
+ }
+ /*
+ * Update expected target offset for next incoming DDP segment
+ */
+ if (rctx->more_ddp_segs != 0)
+ rctx->ddp_to += rctx->fpdu_part_rem;
+
+ return 0;
+}
+
+/*
+ * siw_send_check_ntoh()
+ *
+ * Check incoming SEND fragment header against expected
+ * header values and update expected MSN if no next
+ * fragment expected
+ *
+ * NOTE: This function must be called only if a SEND DDP segment
+ * starts but not for fragmented consecutive pieces of an
+ * already started DDP segement.
+ */
+static inline int siw_send_check_ntoh(struct siw_iwarp_rx *rctx)
+{
+ struct iwarp_send *send = &rctx->hdr.send;
+ struct siw_wqe *wqe = rctx->dest.wqe;
+
+ send->ddp_msn = be32_to_cpu(send->ddp_msn);
+ send->ddp_mo = be32_to_cpu(send->ddp_mo);
+ send->ddp_qn = be32_to_cpu(send->ddp_qn);
+
+ if (send->ddp_qn != RDMAP_UNTAGGED_QN_SEND) {
+ dprint(DBG_RX|DBG_ON, " Invalid DDP QN %d for SEND\n",
+ send->ddp_qn);
+ return -EINVAL;
+ }
+ if (send->ddp_msn != rctx->ddp_msn[RDMAP_UNTAGGED_QN_SEND]) {
+ dprint(DBG_RX|DBG_ON, " received MSN=%d, expected MSN=%d\n",
+ rctx->ddp_msn[RDMAP_UNTAGGED_QN_SEND], send->ddp_msn);
+ /*
+ * TODO: Error handling
+ * async_event= RI_EVENT_QP_RQ_PROTECTION_ERROR_MSN_GAP;
+ * cmpl_status= RI_WC_STATUS_LOCAL_QP_CATASTROPHIC;
+ */
+ return -EINVAL;
+ }
+ if (send->ddp_mo != wqe->processed) {
+ dprint(DBG_RX|DBG_ON, " Received MO=%u, expected MO=%u\n",
+ send->ddp_mo, wqe->processed);
+ /*
+ * Verbs: RI_EVENT_QP_LLP_INTEGRITY_ERROR_BAD_FPDU
+ */
+ return -EINVAL;
+ }
+ if (rctx->first_ddp_seg) {
+ /* initialize user memory write position */
+ rctx->sge_idx = 0;
+ rctx->sge_off = 0;
+ }
+ if (wqe->bytes < wqe->processed + rctx->fpdu_part_rem) {
+ dprint(DBG_RX|DBG_ON, " Receive space short: %d < %d\n",
+ wqe->bytes - wqe->processed, rctx->fpdu_part_rem);
+ wqe->wc_status = IB_WC_LOC_LEN_ERR;
+ return -EINVAL;
+ }
+ return 0;
+}
+
+
+/*
+ * siw_srq_fetch_wqe()
+ *
+ * Get one RQ wqe from SRQ and inform user
+ * if SRQ lower watermark reached
+ */
+static inline struct siw_wqe *siw_srq_fetch_wqe(struct siw_srq *srq)
+{
+ struct siw_wqe *wqe = NULL;
+ int qlen;
+
+ lock_srq(srq);
+ if (!list_empty(&srq->rq)) {
+ wqe = list_first_wqe(&srq->rq);
+ list_del_init(&wqe->list);
+ /*
+ * The SRQ wqe is counted for SRQ space until completed.
+ */
+ qlen = srq->max_wr - (atomic_read(&srq->space) + 1);
+ if (srq->armed && qlen < srq->limit) {
+ srq->armed = 0;
+ dprint(DBG_RX, " SRQ(%p): SRQ limit event\n", srq);
+ siw_async_srq_ev(srq, IB_EVENT_SRQ_LIMIT_REACHED);
+ }
+ }
+ unlock_srq(srq);
+
+ return wqe;
+}
+
+static inline struct siw_wqe *siw_get_rqe(struct siw_qp *qp)
+{
+ struct siw_wqe *wqe = NULL;
+
+ if (!qp->srq) {
+ lock_rq(qp);
+ if (!list_empty(&qp->rq)) {
+ wqe = list_first_wqe(&qp->rq);
+ list_del_init(&wqe->list);
+ unlock_rq(qp);
+ } else {
+ unlock_rq(qp);
+ dprint(DBG_RX, " QP(%d): RQ empty!\n", QP_ID(qp));
+ }
+ } else {
+ wqe = siw_srq_fetch_wqe(qp->srq);
+ if (wqe) {
+ siw_qp_get(qp);
+ wqe->qp = qp;
+ } else
+ dprint(DBG_RX, " QP(%d): SRQ empty!\n", QP_ID(qp));
+ }
+ return wqe;
+}
+
+
+/*
+ * siw_proc_send:
+ *
+ * Process one incoming SEND and place data into memory referenced by
+ * receive wqe.
+ *
+ * Function supports partially received sends (suspending/resuming
+ * current receive wqe processing)
+ *
+ * return value:
+ * 0: reached the end of a DDP segment
+ * -EAGAIN: to be called again to finish the DDP segment
+ */
+int siw_proc_send(struct siw_qp *qp, struct siw_iwarp_rx *rctx)
+{
+ struct siw_wqe *wqe;
+ struct siw_sge *sge;
+ struct siw_mr *mr;
+ u32 data_bytes, /* all data bytes available */
+ rcvd_bytes; /* sum of data bytes rcvd */
+ int rv = 0;
+
+ if (rctx->first_ddp_seg) {
+ WARN_ON(rx_wqe(qp) != NULL);
+
+ wqe = siw_get_rqe(qp);
+ if (!wqe)
+ return -ENOENT;
+
+ rx_wqe(qp) = wqe;
+ wqe->wr_status = SR_WR_INPROGRESS;
+ } else {
+ wqe = rx_wqe(qp);
+ if (!wqe) {
+ /*
+ * this is a siw bug!
+ */
+ dprint(DBG_ON, "QP(%d): RQ failure\n", QP_ID(qp));
+ return -EPROTO;
+ }
+ }
+ if (rctx->state == SIW_GET_DATA_START) {
+ rv = siw_send_check_ntoh(rctx);
+ if (rv) {
+ siw_async_ev(qp, NULL, IB_EVENT_QP_FATAL);
+ return rv;
+ }
+ if (!rctx->fpdu_part_rem) /* zero length SEND */
+ return 0;
+ }
+ data_bytes = min(rctx->fpdu_part_rem, rctx->skb_new);
+ rcvd_bytes = 0;
+
+ while (data_bytes) {
+ struct siw_pd *pd;
+ u32 sge_bytes; /* data bytes avail for SGE */
+
+ sge = &wqe->wr.sgl.sge[rctx->sge_idx];
+
+ if (!sge->len) {
+ /* just skip empty sge's */
+ rctx->sge_idx++;
+ rctx->sge_off = 0;
+ continue;
+ }
+ sge_bytes = min(data_bytes, sge->len - rctx->sge_off);
+
+ /*
+ * check with QP's PD if no SRQ present, SRQ's PD otherwise
+ */
+ pd = qp->srq == NULL ? qp->pd : qp->srq->pd;
+
+ rv = siw_check_sge(pd, sge, SR_MEM_LWRITE, rctx->sge_off,
+ sge_bytes);
+ if (rv) {
+ siw_async_ev(qp, NULL, IB_EVENT_QP_ACCESS_ERR);
+ break;
+ }
+ mr = siw_mem2mr(sge->mem.obj);
+
+ if (mr->umem) {
+ /*
+ * Are we going to finish placing
+ * - the last fragment of the current SGE or
+ * - the last DDP segment (L=1) of the current
+ * RDMAP message?
+ *
+ * siw_rx_umem() must advance umem page_chunk position
+ * after sucessful receive only, if receive into
+ * current umem does not end.
+ * umem ends, if:
+ * - current SGE gets completely filled, OR
+ * - current MPA FPDU is last AND gets consumed now
+ */
+ int umem_ends =
+ ((sge_bytes + rctx->sge_off == sge->len) ||
+ (!rctx->more_ddp_segs &&
+ rctx->fpdu_part_rcvd + sge_bytes ==
+ rctx->fpdu_part_rem)) ? 1 : 0;
+
+ if (rctx->sge_off == 0) {
+ /*
+ * started a new sge: update receive pointers
+ */
+ rv = siw_rx_umem_init(rctx, mr, sge->addr);
+ if (rv)
+ break;
+ }
+ rv = siw_rx_umem(rctx, sge_bytes, umem_ends);
+ } else
+ rv = siw_rx_kva(rctx, sge_bytes,
+ (void *)(sge->addr + rctx->sge_off));
+ if (rv != sge_bytes) {
+ wqe->processed += rcvd_bytes;
+ return -EINVAL;
+ }
+ rctx->sge_off += rv;
+
+ if (rctx->sge_off == sge->len) {
+ rctx->sge_idx++;
+ rctx->sge_off = 0;
+ }
+ data_bytes -= rv;
+ rcvd_bytes += rv;
+
+ rctx->fpdu_part_rem -= rv;
+ rctx->fpdu_part_rcvd += rv;
+ }
+ wqe->processed += rcvd_bytes;
+
+ if (!rctx->fpdu_part_rem)
+ return 0;
+
+ return (rv < 0) ? rv : -EAGAIN;
+}
+
+/*
+ * siw_proc_write:
+ *
+ * Place incoming WRITE after referencing and checking target buffer
+
+ * Function supports partially received WRITEs (suspending/resuming
+ * current receive processing)
+ *
+ * return value:
+ * 0: reached the end of a DDP segment
+ * -EAGAIN: to be called again to finish the DDP segment
+ */
+
+int siw_proc_write(struct siw_qp *qp, struct siw_iwarp_rx *rctx)
+{
+ struct siw_dev *dev = qp->hdr.dev;
+ struct iwarp_rdma_write *write = &rctx->hdr.rwrite;
+ struct siw_mem *mem;
+ struct siw_mr *mr;
+ int bytes,
+ rv;
+
+ if (rctx->state == SIW_GET_DATA_START) {
+
+ if (!rctx->fpdu_part_rem) /* zero length WRITE */
+ return 0;
+
+ rv = siw_write_check_ntoh(rctx);
+ if (rv) {
+ siw_async_ev(qp, NULL, IB_EVENT_QP_FATAL);
+ return rv;
+ }
+ }
+ bytes = min(rctx->fpdu_part_rem, rctx->skb_new);
+
+ /*
+ * NOTE: bytes > 0 is always true, since this routine
+ * gets only called if so.
+ */
+ if (rctx->first_ddp_seg) {
+ /* DEBUG Code, to be removed */
+ if (rx_mem(qp) != NULL) {
+ dprint(DBG_RX|DBG_ON, "(QP%d): Stale rctx state!\n",
+ QP_ID(qp));
+ return -EFAULT;
+ }
+ rx_mem(qp) = siw_mem_id2obj(dev, rctx->ddp_stag >> 8);
+ }
+ if (rx_mem(qp) == NULL) {
+ dprint(DBG_RX|DBG_ON, "(QP%d): "
+ "Sink STag not found or invalid, STag=0x%08x\n",
+ QP_ID(qp), rctx->ddp_stag);
+ return -EINVAL;
+ }
+ mem = rx_mem(qp);
+ /*
+ * Rtag not checked against mem's tag again because
+ * hdr check guarantees same tag as before if fragmented
+ */
+ rv = siw_check_mem(qp->pd, mem, write->sink_to + rctx->fpdu_part_rcvd,
+ SR_MEM_RWRITE, bytes);
+ if (rv) {
+ siw_async_ev(qp, NULL, IB_EVENT_QP_ACCESS_ERR);
+ return rv;
+ }
+ mr = siw_mem2mr(mem);
+
+ if (mr->umem) {
+ /*
+ * Are we going to place the last piece of the last
+ * DDP segment of the current RDMAP message?
+ *
+ * It is last if:
+ * - rctx->fpdu_part_rem <= rctx->skb_new AND
+ * - payload_rem (of current DDP segment) <= rctx->skb_new
+ */
+ int last_write = ((rctx->fpdu_part_rem <= rctx->skb_new) &&
+ !rctx->more_ddp_segs) ? 1 : 0;
+
+ if (rctx->first_ddp_seg) {
+ rv = siw_rx_umem_init(rctx, mr, write->sink_to);
+ if (rv)
+ return -EINVAL;
+
+ }
+ rv = siw_rx_umem(rctx, bytes, last_write);
+ } else
+ rv = siw_rx_kva(rctx, bytes,
+ (void *)(write->sink_to +
+ rctx->fpdu_part_rcvd));
+
+ if (rv != bytes)
+ return -EINVAL;
+
+ rctx->fpdu_part_rem -= rv;
+ rctx->fpdu_part_rcvd += rv;
+
+ if (!rctx->fpdu_part_rem)
+ return 0;
+
+ return (rv < 0) ? rv : -EAGAIN;
+}
+
+/*
+ * inbound RREQ's cannot carry user data.
+ */
+int siw_proc_rreq(struct siw_qp *qp, struct siw_iwarp_rx *rctx)
+{
+ if (!rctx->fpdu_part_rem)
+ return 0;
+
+ dprint(DBG_ON|DBG_RX, "(QP%d): RREQ with MPA len %d\n", QP_ID(qp),
+ rctx->hdr.ctrl.mpa_len);
+
+ return -EPROTO;
+}
+
+static inline struct siw_wqe *siw_get_irqe(struct siw_qp *qp)
+{
+ struct siw_wqe *wqe = NULL;
+
+ if (atomic_dec_return(&qp->irq_space) >= 0) {
+ wqe = siw_freeq_wqe_get(qp);
+ if (wqe) {
+ INIT_LIST_HEAD(&wqe->list);
+ wqe->processed = 0;
+ siw_qp_get(qp);
+ wqe->qp = qp;
+ wr_type(wqe) = SIW_WR_RDMA_READ_RESP;
+ } else
+ atomic_inc(&qp->irq_space);
+ } else
+ atomic_inc(&qp->irq_space);
+
+ return wqe;
+}
+
+/*
+ * siw_init_rresp:
+ *
+ * Process inbound RDMA READ REQ. Produce a pseudo READ RESPONSE WQE.
+ * Put it at the tail of the IRQ, if there is another WQE currently in
+ * transmit processing. If not, make it the current WQE to be processed
+ * and schedule transmit processing.
+ *
+ * Can be called from softirq context and from process
+ * context (RREAD socket loopback case!)
+ *
+ * return value:
+ * 0: success,
+ * failure code otherwise
+ */
+
+int siw_init_rresp(struct siw_qp *qp, struct siw_iwarp_rx *rctx)
+{
+ struct siw_wqe *rsp;
+
+ rsp = siw_get_irqe(qp);
+ if (rsp) {
+ rsp->wr.rresp.sge.len = be32_to_cpu(rctx->hdr.rreq.read_size);
+ rsp->bytes = rsp->wr.rresp.sge.len; /* redundant */
+
+ rsp->wr.rresp.sge.addr = be64_to_cpu(rctx->hdr.rreq.source_to);
+ rsp->wr.rresp.num_sge = rsp->bytes ? 1 : 0;
+
+ rsp->wr.rresp.sge.mem.obj = NULL; /* defer lookup */
+ rsp->wr.rresp.sge.lkey =
+ be32_to_cpu(rctx->hdr.rreq.source_stag);
+
+ rsp->wr.rresp.raddr = be64_to_cpu(rctx->hdr.rreq.sink_to);
+ rsp->wr.rresp.rtag = rctx->hdr.rreq.sink_stag; /* NBO */
+
+ } else {
+ dprint(DBG_RX|DBG_ON, "(QP%d): IRD exceeded!\n", QP_ID(qp));
+ return -EPROTO;
+ }
+ rsp->wr_status = SR_WR_QUEUED;
+
+ /*
+ * Insert into IRQ
+ *
+ * TODO: Revisit ordering of genuine SQ WRs and Read Response
+ * pseudo-WRs. RDMAP specifies that there is no ordering among
+ * the two directions of transmission, so there is a degree of
+ * freedom.
+ *
+ * The current logic favours Read Responses over SQ work requests
+ * that are queued but not already in progress.
+ */
+ lock_sq(qp);
+ if (!tx_wqe(qp)) {
+ tx_wqe(qp) = rsp;
+ unlock_sq(qp);
+ /*
+ * schedule TX work, even if SQ was supended due to
+ * ORD limit: it is always OK (and may even prevent peers
+ * from appl lock) to send RRESPONSE's
+ */
+ siw_sq_queue_work(qp);
+ } else {
+ list_add_tail(&rsp->list, &qp->irq);
+ unlock_sq(qp);
+ }
+ return 0;
+}
+
+/*
+ * siw_proc_rresp:
+ *
+ * Place incoming RRESP data into memory referenced by RREQ WQE.
+ *
+ * Function supports partially received RRESP's (suspending/resuming
+ * current receive processing)
+ */
+int siw_proc_rresp(struct siw_qp *qp, struct siw_iwarp_rx *rctx)
+{
+ struct siw_wqe *wqe;
+ struct siw_mr *mr;
+ struct siw_sge *sge;
+ int bytes,
+ rv;
+
+ if (rctx->first_ddp_seg) {
+ WARN_ON(rx_wqe(qp) != NULL);
+ /*
+ * fetch pending RREQ from orq
+ */
+ lock_orq(qp);
+ if (!list_empty(&qp->orq)) {
+ wqe = list_first_entry(&qp->orq, struct siw_wqe, list);
+ list_del_init(&wqe->list);
+ } else {
+ unlock_orq(qp);
+ dprint(DBG_RX|DBG_ON, "(QP%d): ORQ empty\n",
+ QP_ID(qp));
+ /*
+ * TODO: Should generate an async error
+ */
+ rv = -ENODATA; /* or -ENOENT ? */
+ goto done;
+ }
+ unlock_orq(qp);
+
+ rx_wqe(qp) = wqe;
+
+ if (wr_type(wqe) != SIW_WR_RDMA_READ_REQ || wqe->processed) {
+ WARN_ON(wqe->processed);
+ WARN_ON(wr_type(wqe) != SIW_WR_RDMA_READ_REQ);
+ rv = -EINVAL;
+ goto done;
+ }
+
+ wqe->wr_status = SR_WR_INPROGRESS;
+
+ rv = siw_rresp_check_ntoh(rctx);
+ if (rv) {
+ siw_async_ev(qp, NULL, IB_EVENT_QP_FATAL);
+ goto done;
+ }
+ } else {
+ wqe = rx_wqe(qp);
+ if (!wqe) {
+ WARN_ON(1);
+ rv = -ENODATA;
+ goto done;
+ }
+ }
+ if (!rctx->fpdu_part_rem) /* zero length RRESPONSE */
+ return 0;
+
+ bytes = min(rctx->fpdu_part_rem, rctx->skb_new);
+ sge = wqe->wr.rread.sge; /* there is only one */
+
+ /*
+ * check target memory which resolves memory on first fragment
+ */
+ rv = siw_check_sge(qp->pd, sge, SR_MEM_LWRITE, wqe->processed, bytes);
+ if (rv) {
+ dprint(DBG_RX|DBG_ON, "(QP%d): siw_check_sge failed: %d\n",
+ QP_ID(qp), rv);
+ wqe->wc_status = IB_WC_LOC_PROT_ERR;
+ siw_async_ev(qp, NULL, IB_EVENT_QP_ACCESS_ERR);
+ goto done;
+ }
+ mr = siw_mem2mr(sge->mem.obj);
+
+ if (mr->umem) {
+ /*
+ * Are we going to finish placing the last DDP segment (L=1)
+ * of the current RDMAP message?
+ *
+ * NOTE: siw_rresp_check_ntoh() guarantees that the
+ * last inbound RDMAP Read Response message exactly matches
+ * with the RREQ WR.
+ */
+ int is_last = (bytes + wqe->processed == wqe->bytes) ? 1 : 0;
+
+ if (rctx->first_ddp_seg) {
+ rv = siw_rx_umem_init(rctx, mr, sge->addr);
+ if (rv) {
+ wqe->wc_status = IB_WC_LOC_PROT_ERR;
+ goto done;
+ }
+ }
+ rv = siw_rx_umem(rctx, bytes, is_last);
+ } else
+ rv = siw_rx_kva(rctx, bytes,
+ (void *)(sge->addr + wqe->processed));
+ if (rv != bytes) {
+ wqe->wc_status = IB_WC_GENERAL_ERR;
+ rv = -EINVAL;
+ goto done;
+ }
+ rctx->fpdu_part_rem -= rv;
+ rctx->fpdu_part_rcvd += rv;
+
+ wqe->processed += rv;
+
+ if (!rctx->fpdu_part_rem)
+ return 0;
+done:
+ return (rv < 0) ? rv : -EAGAIN;
+}
+
+static void siw_drain_pkt(struct siw_qp *qp, struct siw_iwarp_rx *rctx)
+{
+ char buf[128];
+ int len;
+
+ dprint(DBG_ON|DBG_RX, " (QP%d): drain %d bytes\n",
+ QP_ID(qp), rctx->fpdu_part_rem);
+
+ while (rctx->fpdu_part_rem) {
+ len = min(rctx->fpdu_part_rem, 128);
+
+ skb_copy_bits(rctx->skb, rctx->skb_offset,
+ buf, rctx->fpdu_part_rem);
+
+ rctx->skb_copied += len;
+ rctx->skb_offset += len;
+ rctx->skb_new -= len;
+ rctx->fpdu_part_rem -= len;
+ }
+}
+
+int siw_proc_unsupp(struct siw_qp *qp, struct siw_iwarp_rx *rctx)
+{
+ WARN_ON(1);
+ siw_drain_pkt(qp, rctx);
+ return 0;
+}
+
+
+int siw_proc_terminate(struct siw_qp *qp, struct siw_iwarp_rx *rctx)
+{
+ struct iwarp_terminate *term = &rctx->hdr.terminate;
+
+ printk(KERN_INFO "(QP%d): RX Terminate: type=%d, layer=%d, code=%d\n",
+ QP_ID(qp), term->term_ctrl.etype, term->term_ctrl.layer,
+ term->term_ctrl.ecode);
+
+ siw_drain_pkt(qp, rctx);
+ return 0;
+}
+
+
+static int siw_get_trailer(struct siw_qp *qp, struct siw_iwarp_rx *rctx)
+{
+ struct sk_buff *skb = rctx->skb;
+ u8 *tbuf = (u8 *)&rctx->trailer.crc - rctx->pad;
+ int avail;
+
+ avail = min(rctx->skb_new, rctx->fpdu_part_rem);
+
+ skb_copy_bits(skb, rctx->skb_offset,
+ tbuf + rctx->fpdu_part_rcvd, avail);
+
+ rctx->fpdu_part_rcvd += avail;
+ rctx->fpdu_part_rem -= avail;
+
+ rctx->skb_new -= avail;
+ rctx->skb_offset += avail;
+ rctx->skb_copied += avail;
+
+ dprint(DBG_RX, " (QP%d): %d remaining (%d)\n", QP_ID(qp),
+ rctx->fpdu_part_rem, avail);
+
+ if (!rctx->fpdu_part_rem) {
+ u32 crc_in, crc_own = 0;
+ /*
+ * check crc if required
+ */
+ if (!rctx->crc_enabled)
+ return 0;
+
+ if (rctx->pad && siw_crc_array(&rctx->mpa_crc_hd,
+ tbuf, rctx->pad) != 0)
+ return -EINVAL;
+
+ crypto_hash_final(&rctx->mpa_crc_hd, (u8 *)&crc_own);
+
+ /*
+ * CRC32 is computed, transmitted and received directly in NBO,
+ * so there's never a reason to convert byte order.
+ */
+ crc_in = rctx->trailer.crc;
+
+ if (crc_in != crc_own) {
+ dprint(DBG_RX|DBG_ON,
+ " (QP%d): CRC ERROR in:=%08x, own=%08x\n",
+ QP_ID(qp), crc_in, crc_own);
+ return -EINVAL;
+ }
+ return 0;
+ }
+ return -EAGAIN;
+}
+
+
+static int siw_get_hdr(struct siw_iwarp_rx *rctx)
+{
+ struct sk_buff *skb = rctx->skb;
+ struct iwarp_ctrl *c_hdr = &rctx->hdr.ctrl;
+
+ int bytes;
+
+ if (rctx->fpdu_part_rcvd < sizeof(struct iwarp_ctrl)) {
+ /*
+ * copy first fix part of iwarp hdr
+ */
+ bytes = min_t(int, rctx->skb_new, sizeof(struct iwarp_ctrl)
+ - rctx->fpdu_part_rcvd);
+
+ skb_copy_bits(skb, rctx->skb_offset,
+ (char *)c_hdr + rctx->fpdu_part_rcvd, bytes);
+
+ rctx->fpdu_part_rcvd += bytes;
+
+ rctx->skb_new -= bytes;
+ rctx->skb_offset += bytes;
+ rctx->skb_copied += bytes;
+
+ if (!rctx->skb_new ||
+ rctx->fpdu_part_rcvd < sizeof(struct iwarp_ctrl))
+ return -EAGAIN;
+
+ if (c_hdr->opcode > RDMAP_TERMINATE) {
+ dprint(DBG_RX|DBG_ON, " opcode %d\n", c_hdr->opcode);
+ return -EINVAL;
+ }
+ if (c_hdr->dv != DDP_VERSION) {
+ dprint(DBG_RX|DBG_ON, " dversion %d\n", c_hdr->dv);
+ return -EINVAL;
+ }
+ if (c_hdr->rv != RDMAP_VERSION) {
+ dprint(DBG_RX|DBG_ON, " rversion %d\n", c_hdr->rv);
+ return -EINVAL;
+ }
+ dprint(DBG_RX, "(QP%d): New Header, opcode:%d\n",
+ RX_QPID(rctx), c_hdr->opcode);
+ }
+ /*
+ * figure out len of current hdr: variable length of
+ * iwarp hdr forces us to copy hdr information
+ */
+ bytes = min(rctx->skb_new,
+ iwarp_pktinfo[c_hdr->opcode].hdr_len - rctx->fpdu_part_rcvd);
+
+ skb_copy_bits(skb, rctx->skb_offset,
+ (char *)c_hdr + rctx->fpdu_part_rcvd, bytes);
+
+ rctx->fpdu_part_rcvd += bytes;
+
+ rctx->skb_new -= bytes;
+ rctx->skb_offset += bytes;
+ rctx->skb_copied += bytes;
+
+ if (rctx->fpdu_part_rcvd == iwarp_pktinfo[c_hdr->opcode].hdr_len) {
+ /*
+ * HDR receive completed. Check if the current DDP segment
+ * starts a new RDMAP message or continues a previously
+ * started RDMAP message.
+ *
+ * Note well from the comments on DDP reassembly:
+ * - Support for unordered reception of DDP segments
+ * (or FPDUs) from different RDMAP messages is not needed.
+ * - Unordered reception of DDP segments of the same
+ * RDMAP message is not supported. It is probably not
+ * needed with most peers.
+ */
+ siw_dprint_hdr(&rctx->hdr, RX_QPID(rctx), "HDR received");
+
+ if (rctx->more_ddp_segs != 0) {
+ rctx->first_ddp_seg = 0;
+ if (rctx->prev_ddp_opcode != c_hdr->opcode) {
+ dprint(DBG_ON,
+ "packet intersection: %d <> %d\n",
+ rctx->prev_ddp_opcode, c_hdr->opcode);
+ return -EPROTO;
+ }
+ } else {
+ rctx->prev_ddp_opcode = c_hdr->opcode;
+ rctx->first_ddp_seg = 1;
+ }
+ rctx->more_ddp_segs = (c_hdr->l == 0) ? 1 : 0;
+
+ return 0;
+ }
+ return -EAGAIN;
+}
+
+static inline int siw_fpdu_payload_len(struct siw_iwarp_rx *rctx)
+{
+ return ((int)(rctx->hdr.ctrl.mpa_len) - rctx->fpdu_part_rcvd)
+ + MPA_HDR_SIZE;
+}
+
+static inline int siw_fpdu_trailer_len(struct siw_iwarp_rx *rctx)
+{
+ int mpa_len = (int)rctx->hdr.ctrl.mpa_len + MPA_HDR_SIZE;
+
+ return MPA_CRC_SIZE + (-mpa_len & 0x3);
+}
+
+/*
+ * siw_rreq_complete()
+ *
+ * Complete the current READ REQUEST after READ RESPONSE processing.
+ * It may complete consecutive WQE's which were already SQ
+ * processed before but are awaiting completion due to completion
+ * ordering (see verbs 8.2.2.2).
+ * The READ RESPONSE may also resume SQ processing if it was stalled
+ * due to ORD exhaustion (see verbs 8.2.2.18)
+ * Function stops completion when next READ REQUEST found or ORQ empty.
+ */
+static void siw_rreq_complete(struct siw_wqe *wqe, int error)
+{
+ struct siw_qp *qp = wqe->qp;
+ int num_wc = 1;
+ enum ib_send_flags flags;
+ LIST_HEAD(c_list);
+
+ flags = wr_flags(wqe);
+
+ if (flags & IB_SEND_SIGNALED)
+ list_add(&wqe->list, &c_list);
+ else {
+ atomic_inc(&qp->sq_space);
+ siw_wqe_put(wqe);
+ num_wc = 0;
+ }
+
+ lock_orq(qp);
+
+ /* More WQE's to complete following this RREQ? */
+ if (!list_empty(&qp->orq)) {
+ struct list_head *pos, *n;
+ list_for_each_safe(pos, n, &qp->orq) {
+ wqe = list_entry_wqe(pos);
+ if (wr_type(wqe) == SIW_WR_RDMA_READ_REQ)
+ break;
+ flags |= wr_flags(wqe);
+ num_wc++;
+ dprint(DBG_WR|DBG_ON,
+ "(QP%d): Resume completion, wr_type %d\n",
+ QP_ID(qp), wr_type(wqe));
+ list_move_tail(pos, &c_list);
+ }
+ }
+ unlock_orq(qp);
+
+ if (num_wc)
+ siw_sq_complete(&c_list, qp, num_wc, flags);
+
+ /*
+ * Check if SQ processing was stalled due to ORD limit
+ */
+ if (ORD_SUSPEND_SQ(qp)) {
+ lock_sq(qp);
+
+ wqe = siw_next_tx_wqe(qp);
+
+ if (wqe && !tx_wqe(qp)) {
+ WARN_ON(wr_type(wqe) != SIW_WR_RDMA_READ_REQ);
+ list_del_init(&wqe->list);
+ tx_wqe(qp) = wqe;
+
+ list_add_tail(&wqe->list, &qp->orq);
+
+ unlock_sq(qp);
+
+ dprint(DBG_RX, "(QP%d): SQ resume (%d)\n",
+ QP_ID(qp), atomic_read(&qp->sq_space));
+
+ siw_sq_queue_work(qp);
+ } else {
+ /* only new ORQ space if not next RREQ queued */
+ atomic_inc(&qp->orq_space);
+ unlock_sq(qp);
+ }
+ } else
+ atomic_inc(&qp->orq_space);
+}
+
+/*
+ * siw_rdmap_complete()
+ *
+ * complete processing of an RDMA message after receiving all
+ * DDP segmens
+ *
+ * o SENDs + RRESPs will need for completion,
+ * o RREQs need for READ RESPONSE initialization
+ * o WRITEs need memory dereferencing
+ *
+ * TODO: Could siw_[s,r]_complete() fail? (CQ full)
+ */
+static inline int siw_rdmap_complete(struct siw_qp *qp,
+ struct siw_iwarp_rx *rctx)
+{
+ struct siw_wqe *wqe;
+ int rv = 0;
+
+ switch (rctx->hdr.ctrl.opcode) {
+
+ case RDMAP_SEND_SE:
+ wr_flags(rx_wqe(qp)) |= IB_SEND_SOLICITED;
+ case RDMAP_SEND:
+ rctx->ddp_msn[RDMAP_UNTAGGED_QN_SEND]++;
+
+ wqe = rx_wqe(qp);
+
+ wqe->wc_status = IB_WC_SUCCESS;
+ wqe->wr_status = SR_WR_DONE;
+
+ siw_rq_complete(wqe, qp);
+
+ break;
+
+ case RDMAP_RDMA_READ_RESP:
+ rctx->ddp_msn[RDMAP_UNTAGGED_QN_RDMA_READ]++;
+
+ wqe = rx_wqe(qp);
+
+ wqe->wc_status = IB_WC_SUCCESS;
+ wqe->wr_status = SR_WR_DONE;
+
+ siw_rreq_complete(wqe, 0);
+
+ break;
+
+ case RDMAP_RDMA_READ_REQ:
+ rv = siw_init_rresp(qp, rctx);
+
+ break;
+
+ case RDMAP_RDMA_WRITE:
+ /*
+ * Free References from memory object if
+ * attached to receive context (inbound WRITE)
+ * While a zero-length WRITE is allowed, the
+ * current implementation does not create
+ * a memory reference (it is unclear if memory
+ * rights should be checked in that case!).
+ *
+ * TODO: check zero length WRITE semantics
+ */
+ if (rx_mem(qp))
+ siw_mem_put(rx_mem(qp));
+ break;
+
+ default:
+ break;
+
+ }
+ rctx->umem_chunk = NULL; /* DEBUG aid, tentatively */
+ rx_wqe(qp) = NULL; /* also clears MEM object for WRITE */
+
+ return rv;
+}
+
+/*
+ * siw_rdmap_error()
+ *
+ * Abort processing of RDMAP message after failure.
+ * SENDs + RRESPs will need for receive completion, if
+ * already started.
+ *
+ * TODO: WRITE need local error to be surfaced.
+ *
+ */
+static inline void
+siw_rdmap_error(struct siw_qp *qp, struct siw_iwarp_rx *rctx, int status)
+{
+ struct siw_wqe *wqe;
+
+ switch (rctx->hdr.ctrl.opcode) {
+
+ case RDMAP_SEND_SE:
+ case RDMAP_SEND:
+ rctx->ddp_msn[RDMAP_UNTAGGED_QN_SEND]++;
+
+ wqe = rx_wqe(qp);
+ if (!wqe)
+ return;
+
+ if (rctx->hdr.ctrl.opcode == RDMAP_SEND_SE)
+ wr_flags(wqe) |= IB_SEND_SOLICITED;
+
+ if (!wqe->wc_status)
+ wqe->wc_status = IB_WC_GENERAL_ERR;
+
+ wqe->wr_status = SR_WR_DONE;
+ siw_rq_complete(wqe, qp);
+
+ break;
+
+ case RDMAP_RDMA_READ_RESP:
+ /*
+ * A READ RESPONSE may flush consecutive WQE's
+ * which were SQ processed before
+ */
+ rctx->ddp_msn[RDMAP_UNTAGGED_QN_RDMA_READ]++;
+
+ if (rctx->state == SIW_GET_HDR || status == -ENODATA)
+ /* eventual RREQ left untouched */
+ break;
+
+ wqe = rx_wqe(qp);
+ if (wqe) {
+ if (status)
+ wqe->wc_status = status;
+ else
+ wqe->wc_status = IB_WC_GENERAL_ERR;
+
+ wqe->wr_status = SR_WR_DONE;
+ /*
+ * All errors turn the wqe into signalled.
+ */
+ wr_flags(wqe) |= IB_SEND_SIGNALED;
+ siw_rreq_complete(wqe, status);
+ }
+ break;
+
+ case RDMAP_RDMA_WRITE:
+ /*
+ * Free References from memory object if
+ * attached to receive context (inbound WRITE)
+ * While a zero-length WRITE is allowed, the
+ * current implementation does not create
+ * a memory reference (it is unclear if memory
+ * rights should be checked in that case!).
+ *
+ * TODO: check zero length WRITE semantics
+ */
+ if (rx_mem(qp))
+ siw_mem_put(rx_mem(qp));
+ break;
+
+ default:
+ break;
+ }
+ rctx->umem_chunk = NULL; /* DEBUG aid, tentatively */
+ rx_wqe(qp) = NULL; /* also clears MEM object for WRITE */
+}
+
+/*
+ * siw_tcp_rx_data()
+ *
+ * Main routine to consume inbound TCP payload
+ *
+ * @rd_desc: read descriptor
+ * @skb: socket buffer
+ * @off: offset in skb
+ * @len: skb->len - offset : payload in skb
+ */
+int siw_tcp_rx_data(read_descriptor_t *rd_desc, struct sk_buff *skb,
+ unsigned int off, size_t len)
+{
+ struct siw_qp *qp = rd_desc->arg.data;
+ struct siw_iwarp_rx *rctx = &qp->rx_ctx;
+ int rv;
+
+ rctx->skb = skb;
+ rctx->skb_new = skb->len - off;
+ rctx->skb_offset = off;
+ rctx->skb_copied = 0;
+
+ dprint(DBG_RX, "(QP%d): new data %d, rx-state %d\n", QP_ID(qp),
+ rctx->skb_new, rctx->state);
+
+ if (unlikely(rctx->rx_suspend == 1 ||
+ qp->attrs.state != SIW_QP_STATE_RTS)) {
+ dprint(DBG_RX|DBG_ON, "(QP%d): failed. state rx:%d, qp:%d\n",
+ QP_ID(qp), qp->rx_ctx.state, qp->attrs.state);
+ return 0;
+ }
+ while (rctx->skb_new) {
+
+ switch (rctx->state) {
+
+ case SIW_GET_HDR:
+ rv = siw_get_hdr(rctx);
+ if (!rv) {
+ if (rctx->crc_enabled &&
+ siw_crc_rxhdr(rctx) != 0) {
+ rv = -EINVAL;
+ break;
+ }
+ rctx->hdr.ctrl.mpa_len =
+ ntohs(rctx->hdr.ctrl.mpa_len);
+
+ rctx->fpdu_part_rem =
+ siw_fpdu_payload_len(rctx);
+
+ if (rctx->fpdu_part_rem)
+ rctx->pad = -rctx->fpdu_part_rem & 0x3;
+ else
+ rctx->pad = 0;
+
+ rctx->state = SIW_GET_DATA_START;
+ rctx->fpdu_part_rcvd = 0;
+ }
+ break;
+
+ case SIW_GET_DATA_MORE:
+ /*
+ * Another data fragment of the same DDP segment.
+ * Headers will not be checked again by the
+ * opcode-specific data receive function below.
+ * Setting first_ddp_seg = 0 avoids repeating
+ * initializations that may occur only once per
+ * DDP segment.
+ */
+ rctx->first_ddp_seg = 0;
+
+ case SIW_GET_DATA_START:
+ /*
+ * Headers will be checked by the opcode-specific
+ * data receive function below.
+ */
+ rv = siw_rx_data(qp, rctx);
+ if (!rv) {
+ rctx->fpdu_part_rem =
+ siw_fpdu_trailer_len(rctx);
+ rctx->fpdu_part_rcvd = 0;
+ rctx->state = SIW_GET_TRAILER;
+ } else
+ rctx->state = SIW_GET_DATA_MORE;
+
+ break;
+
+ case SIW_GET_TRAILER:
+ /*
+ * read CRC + any padding
+ */
+ rv = siw_get_trailer(qp, rctx);
+ if (!rv) {
+ /*
+ * FPDU completed.
+ * complete RDMAP message if last fragment
+ */
+ rctx->state = SIW_GET_HDR;
+ rctx->fpdu_part_rcvd = 0;
+
+ if (!rctx->hdr.ctrl.l)
+ /* more frags */
+ break;
+
+ rv = siw_rdmap_complete(qp, rctx);
+ if (rv)
+ break;
+ }
+ break;
+
+ default:
+ WARN_ON(1);
+ rv = -EAGAIN;
+ }
+
+ if (unlikely(rv != 0 && rv != -EAGAIN)) {
+ /*
+ * TODO: implement graceful error handling including
+ * generation (and processing) of TERMINATE
+ * messages.
+ *
+ * for now we are left with a bogus rx status
+ * unable to receive any further byte.
+ * BUT: code must handle difference between
+ *
+ * o protocol syntax (FATAL, framing lost)
+ * o crc (FATAL, framing lost since we do not
+ * trust packet header (??))
+ * o local resource (maybe non fatal, framing
+ * not lost)
+ *
+ * errors.
+ */
+ siw_rdmap_error(qp, rctx, rv);
+
+ dprint(DBG_RX|DBG_ON,
+ "(QP%d): RX ERROR %d at RX state %d\n",
+ QP_ID(qp), rv, rctx->state);
+
+ siw_dprint_rctx(rctx);
+ /*
+ * Calling siw_cm_queue_work() is safe without
+ * releasing qp->state_lock because the QP state
+ * will be transitioned to SIW_QP_STATE_ERROR
+ * by the siw_work_handler() workqueue handler
+ * after we return from siw_qp_llp_data_ready().
+ */
+ siw_qp_cm_drop(qp, 1);
+
+ break;
+ }
+ if (rv) {
+ dprint(DBG_RX, "(QP%d): "
+ "Misaligned FPDU: State: %d, missing: %d\n",
+ QP_ID(qp), rctx->state, rctx->fpdu_part_rem);
+ break;
+ }
+ }
+ return rctx->skb_copied;
+}
--
1.5.4.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 10/14] SIWv2: Transmit path: siw_qp_tx.c
From: Bernard Metzler @ 2011-06-16 12:42 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA, Bernard Metzler
---
drivers/infiniband/hw/siw/siw_qp_tx.c | 1332 +++++++++++++++++++++++++++++++++
1 files changed, 1332 insertions(+), 0 deletions(-)
create mode 100644 drivers/infiniband/hw/siw/siw_qp_tx.c
diff --git a/drivers/infiniband/hw/siw/siw_qp_tx.c b/drivers/infiniband/hw/siw/siw_qp_tx.c
new file mode 100644
index 0000000..54e0037
--- /dev/null
+++ b/drivers/infiniband/hw/siw/siw_qp_tx.c
@@ -0,0 +1,1332 @@
+/*
+ * Software iWARP device driver for Linux
+ *
+ * Authors: Bernard Metzler <bmt-OA+xvbQnYDHMbYB6QlFGEg@public.gmane.org>
+ *
+ * Copyright (c) 2008-2011, IBM Corporation
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of IBM nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/net.h>
+#include <linux/scatterlist.h>
+#include <linux/highmem.h>
+#include <net/sock.h>
+#include <net/tcp_states.h>
+#include <net/tcp.h>
+
+#include <rdma/iw_cm.h>
+#include <rdma/ib_verbs.h>
+#include <rdma/ib_smi.h>
+#include <rdma/ib_user_verbs.h>
+#include <rdma/ib_umem.h>
+
+#include "siw.h"
+#include "siw_obj.h"
+#include "siw_cm.h"
+
+static bool zcopy_tx = 1;
+module_param(zcopy_tx, bool, 0644);
+MODULE_PARM_DESC(zcopy_tx, "Zero copy user data transmit if possible");
+
+static DEFINE_PER_CPU(atomic_t, siw_workq_len);
+
+static inline int siw_crc_txhdr(struct siw_iwarp_tx *ctx)
+{
+ crypto_hash_init(&ctx->mpa_crc_hd);
+ return siw_crc_array(&ctx->mpa_crc_hd, (u8 *)&ctx->pkt,
+ ctx->ctrl_len);
+}
+
+#define PKT_FRAGMENTED 1
+#define PKT_COMPLETE 0
+
+/*
+ * siw_qp_prepare_tx()
+ *
+ * Prepare tx state for sending out one fpdu. Builds complete pkt
+ * if no user data or only immediate data are present.
+ *
+ * returns PKT_COMPLETE if complete pkt built, PKT_FRAGMENTED otherwise.
+ */
+static int siw_qp_prepare_tx(struct siw_iwarp_tx *c_tx)
+{
+ struct siw_wqe *wqe = c_tx->wqe;
+ u32 *crc = NULL;
+
+ dprint(DBG_TX, "(QP%d):\n", TX_QPID(c_tx));
+
+ switch (wr_type(wqe)) {
+
+ case SIW_WR_RDMA_READ_REQ:
+ memcpy(&c_tx->pkt.ctrl,
+ &iwarp_pktinfo[RDMAP_RDMA_READ_REQ].ctrl,
+ sizeof(struct iwarp_ctrl));
+
+ c_tx->pkt.rreq.rsvd = 0;
+ c_tx->pkt.rreq.ddp_qn = htonl(RDMAP_UNTAGGED_QN_RDMA_READ);
+ c_tx->pkt.rreq.ddp_msn =
+ htonl(++c_tx->ddp_msn[RDMAP_UNTAGGED_QN_RDMA_READ]);
+ c_tx->pkt.rreq.ddp_mo = 0;
+ c_tx->pkt.rreq.sink_stag = htonl(wqe->wr.rread.sge[0].lkey);
+ c_tx->pkt.rreq.sink_to =
+ cpu_to_be64(wqe->wr.rread.sge[0].addr); /* abs addr! */
+ c_tx->pkt.rreq.source_stag = htonl(wqe->wr.rread.rtag);
+ c_tx->pkt.rreq.source_to = cpu_to_be64(wqe->wr.rread.raddr);
+ c_tx->pkt.rreq.read_size = htonl(wqe->bytes);
+
+ dprint(DBG_TX, ": RREQ: Sink: %x, 0x%016llx\n",
+ wqe->wr.rread.sge[0].lkey, wqe->wr.rread.sge[0].addr);
+
+ c_tx->ctrl_len = sizeof(struct iwarp_rdma_rreq);
+ crc = &c_tx->pkt.rreq_pkt.crc;
+ break;
+
+ case SIW_WR_SEND:
+ if (wr_flags(wqe) & IB_SEND_SOLICITED)
+ memcpy(&c_tx->pkt.ctrl,
+ &iwarp_pktinfo[RDMAP_SEND_SE].ctrl,
+ sizeof(struct iwarp_ctrl));
+ else
+ memcpy(&c_tx->pkt.ctrl,
+ &iwarp_pktinfo[RDMAP_SEND].ctrl,
+ sizeof(struct iwarp_ctrl));
+
+ c_tx->pkt.send.ddp_qn = RDMAP_UNTAGGED_QN_SEND;
+ c_tx->pkt.send.ddp_msn =
+ htonl(++c_tx->ddp_msn[RDMAP_UNTAGGED_QN_SEND]);
+ c_tx->pkt.send.ddp_mo = 0;
+ c_tx->pkt.send.rsvd = 0;
+
+ c_tx->ctrl_len = sizeof(struct iwarp_send);
+
+ if (!wqe->bytes)
+ crc = &c_tx->pkt.send_pkt.crc;
+ break;
+
+ case SIW_WR_RDMA_WRITE:
+ memcpy(&c_tx->pkt.ctrl, &iwarp_pktinfo[RDMAP_RDMA_WRITE].ctrl,
+ sizeof(struct iwarp_ctrl));
+
+ c_tx->pkt.rwrite.sink_stag = htonl(wqe->wr.write.rtag);
+ c_tx->pkt.rwrite.sink_to = cpu_to_be64(wqe->wr.write.raddr);
+ c_tx->ctrl_len = sizeof(struct iwarp_rdma_write);
+
+ if (!wqe->bytes)
+ crc = &c_tx->pkt.write_pkt.crc;
+ break;
+
+ case SIW_WR_RDMA_READ_RESP:
+ memcpy(&c_tx->pkt.ctrl,
+ &iwarp_pktinfo[RDMAP_RDMA_READ_RESP].ctrl,
+ sizeof(struct iwarp_ctrl));
+
+ /* NBO */
+ c_tx->pkt.rresp.sink_stag = wqe->wr.rresp.rtag;
+ c_tx->pkt.rresp.sink_to = cpu_to_be64(wqe->wr.rresp.raddr);
+
+ c_tx->ctrl_len = sizeof(struct iwarp_rdma_rresp);
+
+ dprint(DBG_TX, ": RRESP: Sink: %x, 0x%016llx\n",
+ wqe->wr.rresp.rtag, wqe->wr.rresp.raddr);
+
+ if (!wqe->bytes)
+ crc = &c_tx->pkt.rresp_pkt.crc;
+ break;
+
+ default:
+ dprint(DBG_ON, "Unsupported WQE type %d\n", wr_type(wqe));
+ BUG();
+ break;
+ }
+ c_tx->ctrl_sent = 0;
+ c_tx->sge_idx = 0;
+ c_tx->sge_off = 0;
+ c_tx->pg_idx = 0;
+ c_tx->umem_chunk = NULL;
+
+ /*
+ * Do complete CRC if enabled and short packet
+ */
+ if (crc) {
+ *crc = 0;
+ if (c_tx->crc_enabled) {
+ if (siw_crc_txhdr(c_tx) != 0)
+ return -EINVAL;
+ crypto_hash_final(&c_tx->mpa_crc_hd, (u8 *)crc);
+ }
+ }
+ c_tx->ctrl_len += MPA_CRC_SIZE;
+
+ /*
+ * Allow direct sending out of user buffer if WR is non signalled
+ * and payload is over threshold and no CRC is enabled.
+ * Per RDMA verbs, the application should not change the send buffer
+ * until the work completed. In iWarp, work completion is only
+ * local delivery to TCP. TCP may reuse the buffer for
+ * retransmission. Changing unsent data also breaks the CRC,
+ * if applied.
+ * Inline buffers are already out of user control and can be
+ * send 0copy.
+ */
+ if (zcopy_tx &&
+ (!(wr_flags(wqe) & IB_SEND_SIGNALED) || SIW_INLINED_DATA(wqe)) &&
+ wqe->bytes > SENDPAGE_THRESH &&
+ wr_type(wqe) != SIW_WR_RDMA_READ_REQ)
+ c_tx->use_sendpage = 1;
+ else
+ c_tx->use_sendpage = 0;
+
+ return crc == NULL ? PKT_FRAGMENTED : PKT_COMPLETE;
+}
+
+/*
+ * Send out one complete FPDU. Used for fixed sized packets like
+ * Read Requests or zero length SENDs, WRITEs, READ.responses.
+ * Also used for pushing an FPDU hdr only.
+ */
+static inline int siw_tx_ctrl(struct siw_iwarp_tx *c_tx, struct socket *s,
+ int flags)
+{
+ struct msghdr msg = {.msg_flags = flags};
+ struct kvec iov = {
+ .iov_base = (char *)&c_tx->pkt.ctrl + c_tx->ctrl_sent,
+ .iov_len = c_tx->ctrl_len - c_tx->ctrl_sent};
+
+ int rv = kernel_sendmsg(s, &msg, &iov, 1,
+ c_tx->ctrl_len - c_tx->ctrl_sent);
+
+ dprint(DBG_TX, " (QP%d): op=%d, %d of %d sent (%d)\n",
+ TX_QPID(c_tx), c_tx->pkt.ctrl.opcode,
+ c_tx->ctrl_sent + rv, c_tx->ctrl_len, rv);
+
+ if (rv >= 0) {
+ c_tx->ctrl_sent += rv;
+
+ if (c_tx->ctrl_sent == c_tx->ctrl_len) {
+ siw_dprint_hdr(&c_tx->pkt.hdr, TX_QPID(c_tx),
+ "CTRL sent");
+ if (!(flags & MSG_MORE))
+ c_tx->new_tcpseg = 1;
+ rv = 0;
+ } else if (c_tx->ctrl_sent < c_tx->ctrl_len)
+ rv = -EAGAIN;
+ else
+ BUG();
+ }
+ return rv;
+}
+
+/*
+ * 0copy TCP transmit interface.
+ *
+ * Push page array page by page or in one shot.
+ * Pushing the whole page array requires the inner do_tcp_sendpages
+ * function to be exported by the kernel.
+ */
+static int siw_tcp_sendpages(struct socket *s, struct page **page,
+ int offset, size_t size)
+{
+ int rv = 0;
+
+#ifdef SIW_SENDPAGES_EXPORT
+ struct sock *sk = s->sk;
+
+ if (!(sk->sk_route_caps & NETIF_F_SG) ||
+ !(sk->sk_route_caps & NETIF_F_ALL_CSUM)) {
+ /* FIXME:
+ * This should also be handled in a
+ * loop
+ */
+ return -EFAULT;
+ }
+
+ lock_sock(sk);
+ TCP_CHECK_TIMER(sk);
+
+ /*
+ * just return what sendpages has return
+ */
+ rv = do_tcp_sendpages(sk, page, offset, size, MSG_MORE|MSG_DONTWAIT);
+
+ TCP_CHECK_TIMER(sk);
+ release_sock(sk);
+ if (rv == -EAGAIN)
+ rv = 0;
+#else
+ /*
+ * If do_tcp_sendpages() function is not exported
+ * push page by page
+ */
+ size_t todo = size;
+ int i;
+
+ for (i = 0; size > 0; i++) {
+ size_t bytes = min_t(size_t, PAGE_SIZE - offset, size);
+
+ rv = s->ops->sendpage(s, page[i], offset, bytes,
+ MSG_MORE|MSG_DONTWAIT);
+ if (rv <= 0)
+ break;
+
+ size -= rv;
+
+ if (rv != bytes)
+ break;
+
+ offset = 0;
+ }
+ if (rv >= 0 || rv == -EAGAIN)
+ rv = todo - size;
+#endif
+ return rv;
+}
+
+/*
+ * siw_0copy_tx()
+ *
+ * Pushes list of pages to TCP socket. If pages from multiple
+ * SGE's, all referenced pages of each SGE are pushed in one
+ * shot.
+ */
+static int siw_0copy_tx(struct socket *s, struct page **page,
+ struct siw_sge *sge, unsigned int offset,
+ unsigned int size)
+{
+ int i = 0, sent = 0, rv;
+ int sge_bytes = min(sge->len - offset, size);
+
+ offset = (sge->addr + offset) & ~PAGE_MASK;
+
+ while (sent != size) {
+
+ rv = siw_tcp_sendpages(s, &page[i], offset, sge_bytes);
+ if (rv >= 0) {
+ sent += rv;
+ if (size == sent || sge_bytes > rv)
+ break;
+
+ i += PAGE_ALIGN(sge_bytes + offset) >> PAGE_SHIFT;
+ sge++;
+ sge_bytes = min(sge->len, size - sent);
+ offset = sge->addr & ~PAGE_MASK;
+ } else {
+ sent = rv;
+ break;
+ }
+ }
+ return sent;
+}
+
+/*
+ * siw_tx_umem_init()
+ *
+ * Resolve memory chunk and update page index pointer
+ *
+ * @chunk: Umem Chunk to be updated
+ * @p_idx Page Index to be updated
+ * @mr: Memory Region
+ * @va: Virtual Address within MR
+ *
+ */
+static void siw_tx_umem_init(struct ib_umem_chunk **chunk, int *page_index,
+ struct siw_mr *mr, u64 va)
+{
+ struct ib_umem_chunk *cp;
+ int p_ix;
+
+ BUG_ON(va < mr->mem.va);
+ va -= mr->mem.va & PAGE_MASK;
+ /*
+ * equivalent to
+ * va += mr->umem->offset;
+ * va = va >> PAGE_SHIFT;
+ */
+
+ p_ix = va >> PAGE_SHIFT;
+
+ list_for_each_entry(cp, &mr->umem->chunk_list, list) {
+ if (p_ix < cp->nents)
+ break;
+ p_ix -= cp->nents;
+ }
+ BUG_ON(p_ix >= cp->nents);
+
+ dprint(DBG_MM, "(): New chunk 0x%p: Page idx %d, nents %d\n",
+ cp, p_ix, cp->nents);
+
+ *chunk = cp;
+ *page_index = p_ix;
+
+ return;
+}
+
+/*
+ * update memory chunk and page index from given starting point
+ * before current transmit described by: c_tx->sge_off,
+ * sge->addr, c_tx->pg_idx, and c_tx->umem_chunk
+ */
+static inline void
+siw_umem_chunk_update(struct siw_iwarp_tx *c_tx, struct siw_mr *mr,
+ struct siw_sge *sge, unsigned int off)
+{
+ struct ib_umem_chunk *chunk = c_tx->umem_chunk;
+ u64 va_start = sge->addr + c_tx->sge_off;
+
+ off += (unsigned int)(va_start & ~PAGE_MASK); /* + first page offset */
+ off >>= PAGE_SHIFT; /* bytes offset becomes pages offset */
+
+ list_for_each_entry_from(chunk, &mr->umem->chunk_list, list) {
+ if (c_tx->pg_idx + off < chunk->nents)
+ break;
+ off -= chunk->nents - c_tx->pg_idx;
+ c_tx->pg_idx = 0;
+ }
+ c_tx->pg_idx += off;
+
+ c_tx->umem_chunk = chunk;
+}
+
+#define MAX_TRAILER (MPA_CRC_SIZE + 4)
+#define MAX_ARRAY 32 /* Max number of kernel_sendmsg elements */
+
+static inline void
+siw_save_txstate(struct siw_iwarp_tx *c_tx, struct ib_umem_chunk *chunk,
+ unsigned int pg_idx, unsigned int sge_idx,
+ unsigned int sge_off)
+{
+ c_tx->umem_chunk = chunk;
+ c_tx->pg_idx = pg_idx;
+ c_tx->sge_idx = sge_idx;
+ c_tx->sge_off = sge_off;
+}
+/*
+ * Write out iov referencing hdr, data and trailer of current FPDU.
+ * Update transmit state dependent on write return status
+ */
+static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s)
+{
+ struct siw_wqe *wqe = c_tx->wqe;
+ struct siw_sge *sge = &wqe->wr.sgl.sge[c_tx->sge_idx],
+ *first_sge = sge;
+ struct siw_mr *mr = NULL;
+ struct ib_umem_chunk *chunk = c_tx->umem_chunk;
+
+ struct kvec iov[MAX_ARRAY];
+ struct page *page_array[MAX_ARRAY];
+ struct msghdr msg = {.msg_flags = MSG_DONTWAIT};
+
+ int seg = 0, do_crc = c_tx->do_crc, is_kva = 0, rv;
+ unsigned int data_len = c_tx->bytes_unsent,
+ hdr_len = 0,
+ trl_len = 0,
+ sge_off = c_tx->sge_off,
+ sge_idx = c_tx->sge_idx,
+ pg_idx = c_tx->pg_idx;
+
+
+ if (c_tx->state == SIW_SEND_HDR) {
+ if (c_tx->use_sendpage) {
+ rv = siw_tx_ctrl(c_tx, s, MSG_DONTWAIT|MSG_MORE);
+ if (rv)
+ goto done;
+
+ c_tx->state = SIW_SEND_DATA;
+ } else {
+ iov[0].iov_base =
+ (char *)&c_tx->pkt.ctrl + c_tx->ctrl_sent;
+ iov[0].iov_len = hdr_len =
+ c_tx->ctrl_len - c_tx->ctrl_sent;
+ seg = 1;
+ siw_dprint_hdr(&c_tx->pkt.hdr, TX_QPID(c_tx),
+ "HDR to send: ");
+ }
+ }
+
+ wqe->processed += data_len;
+
+ while (data_len) { /* walk the list of SGE's */
+ unsigned int sge_len = min(sge->len - sge_off, data_len);
+ unsigned int fp_off = (sge->addr + sge_off) & ~PAGE_MASK;
+
+ BUG_ON(!sge_len);
+
+ if (!SIW_INLINED_DATA(wqe)) {
+ mr = siw_mem2mr(sge->mem.obj);
+ if (!mr->umem)
+ is_kva = 1;
+ else if (!chunk) {
+ siw_tx_umem_init(&chunk, &pg_idx, mr,
+ sge->addr + sge_off);
+
+ if (!c_tx->umem_chunk)
+ /* Starting first tx for this WQE */
+ siw_save_txstate(c_tx, chunk, pg_idx,
+ sge_idx, sge_off);
+ }
+ } else
+ is_kva = 1;
+
+ if (is_kva && !c_tx->use_sendpage) {
+ /*
+ * tx from kernel virtual address: either inline data
+ * or memory region with assigned kernel buffer
+ */
+ iov[seg].iov_base = (void *)(sge->addr + sge_off);
+ iov[seg].iov_len = sge_len;
+
+ if (do_crc)
+ siw_crc_array(&c_tx->mpa_crc_hd,
+ iov[seg].iov_base, sge_len);
+ sge_off += sge_len;
+ data_len -= sge_len;
+ seg++;
+ goto sge_done;
+ }
+
+ while (sge_len) {
+ struct scatterlist *sl;
+ size_t plen = min((int)PAGE_SIZE - fp_off, sge_len);
+
+ BUG_ON(plen <= 0);
+ if (!is_kva) {
+ sl = &chunk->page_list[pg_idx];
+ page_array[seg] = sg_page(sl);
+ if (!c_tx->use_sendpage) {
+ iov[seg].iov_base = kmap(sg_page(sl))
+ + fp_off;
+ iov[seg].iov_len = plen;
+ }
+ if (do_crc)
+ siw_crc_sg(&c_tx->mpa_crc_hd, sl,
+ fp_off, plen);
+ } else {
+ u64 pa = ((sge->addr + sge_off) & PAGE_MASK);
+ page_array[seg] = virt_to_page(pa);
+ if (do_crc)
+ siw_crc_array(&c_tx->mpa_crc_hd,
+ (void *)(sge->addr + sge_off),
+ plen);
+ }
+
+ sge_len -= plen;
+ sge_off += plen;
+ data_len -= plen;
+
+ if (!is_kva && plen + fp_off == PAGE_SIZE &&
+ sge_off < sge->len && ++pg_idx == chunk->nents) {
+ chunk = mem_chunk_next(chunk);
+ pg_idx = 0;
+ }
+ fp_off = 0;
+ if (++seg > MAX_ARRAY) {
+ int i = (hdr_len > 0) ? 1 : 0;
+
+ dprint(DBG_ON, "(QP%d): Too many fragments\n",
+ TX_QPID(c_tx));
+ if (!is_kva) {
+ seg--;
+ while (i < seg)
+ kunmap(page_array[i++]);
+ }
+ wqe->processed = 0;
+ rv = -EINVAL;
+ goto done_crc;
+ }
+ }
+sge_done:
+ /* Update SGE variables at end of SGE */
+ if (sge_off == sge->len &&
+ (data_len != 0 || wqe->processed < wqe->bytes)) {
+ sge_idx++;
+ sge++;
+ sge_off = 0;
+ chunk = NULL;
+ }
+ }
+ /* trailer */
+ if (likely(c_tx->state != SIW_SEND_TRAILER)) {
+ iov[seg].iov_base = &c_tx->trailer.pad[4 - c_tx->pad];
+ iov[seg].iov_len = trl_len = MAX_TRAILER - (4 - c_tx->pad);
+ } else {
+ iov[seg].iov_base = &c_tx->trailer.pad[c_tx->ctrl_sent];
+ iov[seg].iov_len = trl_len = MAX_TRAILER - c_tx->ctrl_sent;
+ }
+
+ if (c_tx->pad) {
+ *(u32 *)c_tx->trailer.pad = 0;
+ if (do_crc)
+ siw_crc_array(&c_tx->mpa_crc_hd,
+ (u8 *)&c_tx->trailer.crc - c_tx->pad,
+ c_tx->pad);
+ }
+ if (!c_tx->crc_enabled)
+ c_tx->trailer.crc = 0;
+ else if (do_crc)
+ crypto_hash_final(&c_tx->mpa_crc_hd, (u8 *)&c_tx->trailer.crc);
+
+ data_len = c_tx->bytes_unsent;
+
+ if (c_tx->tcp_seglen >= (int)MPA_MIN_FRAG &&
+ TX_MORE_WQE(TX_QP(c_tx))) {
+ msg.msg_flags |= MSG_MORE;
+ c_tx->new_tcpseg = 0;
+ } else
+ c_tx->new_tcpseg = 1;
+
+ if (c_tx->use_sendpage) {
+ rv = siw_0copy_tx(s, page_array, first_sge, c_tx->sge_off,
+ data_len);
+ if (rv == data_len) {
+ rv = kernel_sendmsg(s, &msg, &iov[seg], 1, trl_len);
+ if (rv > 0)
+ rv += data_len;
+ else
+ rv = data_len;
+ }
+ } else {
+ rv = kernel_sendmsg(s, &msg, iov, seg + 1,
+ hdr_len + data_len + trl_len);
+ if (!is_kva) {
+ int i = (hdr_len > 0) ? 1 : 0;
+ while (i < seg)
+ kunmap(page_array[i++]);
+ }
+ }
+ if (rv < (int)hdr_len) {
+ /* Not even complete hdr pushed or negative rv */
+ wqe->processed -= data_len;
+ if (rv >= 0) {
+ c_tx->ctrl_sent += rv;
+ rv = -EAGAIN;
+ }
+ goto done_crc;
+ }
+
+ rv -= hdr_len;
+
+ if (rv >= (int)data_len) {
+ /* all user data pushed to TCP or no data to push */
+ if (data_len > 0 && wqe->processed < wqe->bytes)
+ /* Save the current state for next tx */
+ siw_save_txstate(c_tx, chunk, pg_idx, sge_idx,
+ sge_off);
+
+ rv -= data_len;
+
+ if (rv == trl_len) /* all pushed */
+ rv = 0;
+ else {
+ c_tx->state = SIW_SEND_TRAILER;
+ c_tx->ctrl_len = MAX_TRAILER;
+ c_tx->ctrl_sent = rv + 4 - c_tx->pad;
+ c_tx->bytes_unsent = 0;
+ rv = -EAGAIN;
+ }
+
+ } else if (data_len > 0) {
+ /* Maybe some user data pushed to TCP */
+ c_tx->state = SIW_SEND_DATA;
+ wqe->processed -= data_len - rv;
+
+ if (rv) {
+ /*
+ * Some bytes out. Recompute tx state based
+ * on old state and bytes pushed
+ */
+ c_tx->bytes_unsent -= rv;
+ sge = &wqe->wr.sgl.sge[c_tx->sge_idx];
+
+ if (!is_kva && c_tx->sge_idx == sge_idx &&
+ c_tx->umem_chunk)
+ /*
+ * same SGE as starting SGE for this FPDU
+ */
+ siw_umem_chunk_update(c_tx, mr, sge, rv);
+ else {
+ while (sge->len <= c_tx->sge_off + rv) {
+ rv -= sge->len - c_tx->sge_off;
+ c_tx->sge_idx++;
+ c_tx->sge_off = 0;
+ sge = &wqe->wr.sgl.sge[c_tx->sge_idx];
+ }
+ c_tx->umem_chunk = NULL;
+ }
+ c_tx->sge_off += rv;
+ BUG_ON(c_tx->sge_off >= sge->len);
+ }
+ rv = -EAGAIN;
+ }
+done_crc:
+ c_tx->do_crc = 0;
+done:
+ return rv;
+}
+
+static void siw_calculate_tcpseg(struct siw_iwarp_tx *c_tx, struct socket *s)
+{
+ /*
+ * refresh TCP segement len if we start a new segment or
+ * remaining segment len is less than MPA_MIN_FRAG or
+ * the socket send buffer is empty.
+ */
+ if (c_tx->new_tcpseg || c_tx->tcp_seglen < (int)MPA_MIN_FRAG ||
+ !tcp_send_head(s->sk))
+
+ c_tx->tcp_seglen = get_tcp_mss(s->sk);
+}
+
+
+/*
+ * siw_unseg_txlen()
+ *
+ * Compute complete tcp payload len if packet would not
+ * get fragmented
+ */
+static inline int siw_unseg_txlen(struct siw_iwarp_tx *c_tx)
+{
+ int pad = c_tx->bytes_unsent ? -c_tx->bytes_unsent & 0x3 : 0;
+
+ return c_tx->bytes_unsent + c_tx->ctrl_len + pad + MPA_CRC_SIZE;
+}
+
+
+/*
+ * siw_prepare_fpdu()
+ *
+ * Prepares transmit context to send out one FPDU if FPDU will contain
+ * user data and user data are not immediate data.
+ * Checks and locks involved memory segments of data to be sent.
+ * Computes maximum FPDU length to fill up TCP MSS if possible.
+ *
+ * @qp: QP from which to transmit
+ * @wqe: Current WQE causing transmission
+ *
+ * TODO: Take into account real available sendspace on socket
+ * to avoid header misalignment due to send pausing within
+ * fpdu transmission
+ */
+static int siw_prepare_fpdu(struct siw_qp *qp, struct siw_wqe *wqe)
+{
+ struct siw_iwarp_tx *c_tx = &qp->tx_ctx;
+ int rv = 0;
+
+ /*
+ * TODO: TCP Fragmentation dynamics needs for further investigation.
+ * Resuming SQ processing may start with full-sized packet
+ * or short packet which resets MSG_MORE and thus helps
+ * to synchronize.
+ * This version resumes with short packet.
+ */
+ c_tx->ctrl_len = iwarp_pktinfo[c_tx->pkt.ctrl.opcode].hdr_len;
+ c_tx->ctrl_sent = 0;
+
+ /*
+ * Update target buffer offset if any
+ */
+ if (!c_tx->pkt.ctrl.t) {
+ /* Untagged message */
+ c_tx->pkt.c_untagged.ddp_mo = cpu_to_be32(wqe->processed);
+ } else {
+ /* Tagged message */
+ if (wr_type(wqe) == SIW_WR_RDMA_READ_RESP) {
+ c_tx->pkt.c_tagged.ddp_to =
+ cpu_to_be64(wqe->wr.rresp.raddr + wqe->processed);
+ } else {
+ c_tx->pkt.c_tagged.ddp_to =
+ cpu_to_be64(wqe->wr.write.raddr + wqe->processed);
+ }
+ }
+
+ /* First guess: one big unsegmented DDP segment */
+ c_tx->bytes_unsent = wqe->bytes - wqe->processed;
+ c_tx->tcp_seglen -= siw_unseg_txlen(c_tx);
+
+ if (c_tx->tcp_seglen >= 0) {
+ /* Whole DDP segment fits into current TCP segment */
+ c_tx->pkt.ctrl.l = 1;
+ c_tx->pad = -c_tx->bytes_unsent & 0x3;
+ } else {
+ /* Trim DDP payload to fit into current TCP segment */
+ c_tx->bytes_unsent += c_tx->tcp_seglen;
+ c_tx->bytes_unsent &= ~0x3;
+ c_tx->pad = 0;
+ c_tx->pkt.ctrl.l = 0;
+ }
+ c_tx->pkt.ctrl.mpa_len =
+ htons(c_tx->ctrl_len + c_tx->bytes_unsent - MPA_HDR_SIZE);
+
+#ifdef SIW_TX_FULLSEGS
+ c_tx->fpdu_len =
+ c_tx->ctrl_len + c_tx->bytes_unsent + c_tx->pad + MPA_CRC_SIZE;
+#endif
+ /*
+ * Init MPA CRC computation
+ */
+ if (c_tx->crc_enabled) {
+ siw_crc_txhdr(c_tx);
+ c_tx->do_crc = 1;
+ }
+ if (c_tx->bytes_unsent && !SIW_INLINED_DATA(wqe)) {
+ struct siw_sge *sge = &wqe->wr.sgl.sge[c_tx->sge_idx];
+ /*
+ * Reference memory to be tx'd
+ */
+ BUG_ON(c_tx->sge_idx > wqe->wr.sgl.num_sge - 1);
+
+ if (wr_type(wqe) != SIW_WR_RDMA_READ_RESP)
+ rv = siw_check_sgl(qp->pd, sge, SR_MEM_LREAD,
+ c_tx->sge_off, c_tx->bytes_unsent);
+ else
+ rv = siw_check_sge(qp->pd, sge, SR_MEM_RREAD,
+ c_tx->sge_off, c_tx->bytes_unsent);
+ }
+ return rv;
+}
+
+#ifdef SIW_TX_FULLSEGS
+static inline int siw_test_wspace(struct socket *s, struct siw_iwarp_tx *c_tx)
+{
+ struct sock *sk = s->sk;
+ int rv = 0;
+
+ lock_sock(sk);
+ if (sk_stream_wspace(sk) < (int)c_tx->fpdu_len) {
+ set_bit(SOCK_NOSPACE, &s->flags);
+ rv = -EAGAIN;
+ }
+ release_sock(sk);
+
+ return rv;
+}
+#endif
+/*
+ * siw_qp_sq_proc_tx()
+ *
+ * Process one WQE which needs transmission on the wire.
+ * Return with:
+ * -EAGAIN, if handover to tcp remained incomplete
+ * 0, if handover to tcp complete
+ * < 0, if other errors happend.
+ *
+ * @qp: QP to send from
+ * @wqe: WQE causing transmission
+ */
+static int siw_qp_sq_proc_tx(struct siw_qp *qp, struct siw_wqe *wqe)
+{
+ struct siw_iwarp_tx *c_tx = &qp->tx_ctx;
+ struct socket *s = qp->attrs.llp_stream_handle;
+ int rv = 0;
+
+
+ if (wqe->wr_status == SR_WR_QUEUED) {
+ wqe->wr_status = SR_WR_INPROGRESS;
+
+ siw_calculate_tcpseg(c_tx, s);
+
+ rv = siw_qp_prepare_tx(c_tx);
+ if (rv == PKT_FRAGMENTED) {
+ c_tx->state = SIW_SEND_HDR;
+ rv = siw_prepare_fpdu(qp, wqe);
+ if (rv)
+ return rv;
+ } else if (rv == PKT_COMPLETE)
+ c_tx->state = SIW_SEND_SHORT_FPDU;
+ else
+ goto tx_done;
+ }
+next_segment:
+#ifdef SIW_TX_FULLSEGS
+ rv = siw_test_wspace(s, c_tx);
+ if (rv < 0)
+ goto tx_done;
+#endif
+
+ if (c_tx->state == SIW_SEND_SHORT_FPDU) {
+ enum siw_wr_opcode tx_type = wr_type(wqe);
+
+ /*
+ * Always end current TCP segment (no MSG_MORE flag):
+ * trying to fill segment would result in excessive delay.
+ */
+ rv = siw_tx_ctrl(c_tx, s, MSG_DONTWAIT);
+
+ if (!rv && tx_type != SIW_WR_RDMA_READ_REQ)
+ wqe->processed = wqe->bytes;
+
+ goto tx_done;
+
+ } else
+ rv = siw_tx_hdt(c_tx, s);
+
+ if (!rv) {
+ /* Verbs, 6.4.: Try stopping sending after a full DDP segment
+ * if the connection goes down (== peer halfclose)
+ */
+ if (unlikely(c_tx->tx_suspend)) {
+ rv = -ECONNABORTED;
+ goto tx_done;
+ }
+ /*
+ * One segment sent. Processing completed if last segment.
+ * Do next segment otherwise. Stop if tx error.
+ */
+ if (c_tx->pkt.ctrl.l == 1) {
+ dprint(DBG_TX, "(QP%d): WR completed\n", QP_ID(qp));
+ goto tx_done;
+ }
+ c_tx->state = SIW_SEND_HDR;
+
+ siw_calculate_tcpseg(c_tx, s);
+
+ rv = siw_prepare_fpdu(qp, wqe);
+ if (!rv)
+ goto next_segment;
+ }
+tx_done:
+ return rv;
+}
+
+
+/*
+ * siw_wqe_sq_processed()
+ *
+ * Called after WQE processing completed.
+ * If WQE is not of signalled typ, it can be released.
+ * If the ORQ is empty, a signalled WQE is attached to the CQ.
+ * Otherwise, it is appended to the end of the ORQ for later
+ * completion. To keep WQE ordering, the ORQ is always consumed FIFO.
+ */
+static void siw_wqe_sq_processed(struct siw_wqe *wqe, struct siw_qp *qp)
+{
+ unsigned long flags;
+ LIST_HEAD(c_list);
+
+ if (!(wr_flags(wqe) & IB_SEND_SIGNALED)) {
+ siw_wqe_put(wqe);
+ return;
+ }
+ lock_orq_rxsave(qp, flags);
+
+ if (ORQ_EMPTY(qp)) {
+ unlock_orq_rxsave(qp, flags);
+ dprint(DBG_WR|DBG_TX,
+ "(QP%d): Immediate completion, wr_type %d\n",
+ QP_ID(qp), wr_type(wqe));
+ list_add_tail(&wqe->list, &c_list);
+ siw_sq_complete(&c_list, qp, 1, wr_flags(wqe));
+ } else {
+ list_add_tail(&wqe->list, &qp->orq);
+ unlock_orq_rxsave(qp, flags);
+ dprint(DBG_WR|DBG_TX,
+ "(QP%d): Defer completion, wr_type %d\n",
+ QP_ID(qp), wr_type(wqe));
+ }
+}
+
+static int siw_qp_sq_proc_local(struct siw_qp *qp, struct siw_wqe *wqe)
+{
+ printk(KERN_ERR "local WR's not yet implemented\n");
+ BUG();
+ return 0;
+}
+
+
+/*
+ * siw_qp_sq_process()
+ *
+ * Core TX path routine for RDMAP/DDP/MPA using a TCP kernel socket.
+ * Sends RDMAP payload for the current SQ WR @wqe of @qp in one or more
+ * MPA FPDUs, each containing a DDP segment.
+ *
+ * SQ processing may occur in user context as a result of posting
+ * new WQE's or from siw_sq_work_handler() context. Processing in
+ * user context is limited to non-kernel verbs users.
+ *
+ * SQ processing may get paused anytime, possibly in the middle of a WR
+ * or FPDU, if insufficient send space is available. SQ processing
+ * gets resumed from siw_sq_work_handler(), if send space becomes
+ * available again.
+ *
+ * Must be called with the QP state read-locked.
+ *
+ * TODO:
+ * To be solved more seriously: an outbound RREQ can be satisfied
+ * by the corresponding RRESP _before_ it gets assigned to the ORQ.
+ * This happens regularly in RDMA READ via loopback case. Since both
+ * outbound RREQ and inbound RRESP can be handled by the same CPU
+ * locking the ORQ is dead-lock prone and thus not an option.
+ * Tentatively, the RREQ gets assigned to the ORQ _before_ being
+ * sent (and pulled back in case of send failure).
+ */
+int siw_qp_sq_process(struct siw_qp *qp, int user_ctx)
+{
+ struct siw_wqe *wqe;
+ enum siw_wr_opcode tx_type;
+ unsigned long flags;
+ int rv = 0;
+ int max_burst;
+
+ if (user_ctx)
+ max_burst = SQ_USER_MAXBURST;
+ else
+ max_burst = max(qp->attrs.sq_size, qp->attrs.ird);
+
+ atomic_inc(&qp->tx_ctx.in_use);
+
+ wait_event(qp->tx_ctx.waitq, atomic_read(&qp->tx_ctx.in_use) == 1);
+
+ wqe = tx_wqe(qp);
+ BUG_ON(wqe == NULL);
+
+next_wqe:
+ /*
+ * Stop QP processing if SQ state changed
+ */
+ if (unlikely(qp->tx_ctx.tx_suspend)) {
+ dprint(DBG_WR|DBG_TX, "(QP%d): tx suspend\n", QP_ID(qp));
+ goto done;
+ }
+ tx_type = wr_type(wqe);
+
+ dprint(DBG_WR|DBG_TX,
+ " QP(%d): WR type %d, state %d, data %u, sent %u, id %llu\n",
+ QP_ID(qp), wr_type(wqe), wqe->wr_status, wqe->bytes,
+ wqe->processed, (unsigned long long)wr_id(wqe));
+
+ if (SIW_WQE_IS_TX(wqe))
+ rv = siw_qp_sq_proc_tx(qp, wqe);
+ else
+ rv = siw_qp_sq_proc_local(qp, wqe);
+
+ if (!rv) {
+ /*
+ * WQE processing done
+ */
+ switch (tx_type) {
+
+ case SIW_WR_SEND:
+ case SIW_WR_RDMA_WRITE:
+
+ wqe->wc_status = IB_WC_SUCCESS;
+ wqe->wr_status = SR_WR_DONE;
+ siw_wqe_sq_processed(wqe, qp);
+ break;
+
+ case SIW_WR_RDMA_READ_REQ:
+ /*
+ * already enqueued to ORQ queue
+ */
+ break;
+
+ case SIW_WR_RDMA_READ_RESP:
+ /*
+ * silently recyclye wqe
+ */
+ /* XXX DEBUG AID, please remove */
+ wqe->wr_status = SR_WR_DONE;
+ siw_wqe_put(wqe);
+ break;
+ default:
+ BUG();
+ }
+
+ lock_sq_rxsave(qp, flags);
+
+ wqe = siw_next_tx_wqe(qp);
+ if (!wqe) {
+ tx_wqe(qp) = NULL;
+ unlock_sq_rxsave(qp, flags);
+ goto done;
+ }
+ if (wr_type(wqe) == SIW_WR_RDMA_READ_REQ) {
+ if (ORD_SUSPEND_SQ(qp)) {
+ tx_wqe(qp) = NULL;
+ unlock_sq_rxsave(qp, flags);
+ dprint(DBG_WR|DBG_TX,
+ " QP%d PAUSE SQ: ORD limit\n",
+ QP_ID(qp));
+ goto done;
+ } else {
+ tx_wqe(qp) = wqe;
+ siw_rreq_queue(wqe, qp);
+ }
+ } else {
+ list_del_init(&wqe->list);
+ tx_wqe(qp) = wqe;
+ }
+ unlock_sq_rxsave(qp, flags);
+
+ if (--max_burst == 0) {
+ if (user_ctx) {
+ /*
+ * Avoid to keep the user sending from its
+ * context for too long (blocking user thread)
+ */
+ siw_sq_queue_work(qp);
+ goto done;
+ } else {
+ /*
+ * Avoid to starve other QP's tx if consumer
+ * keeps posting new tx work for current cpu.
+ */
+ int workq_len =
+ atomic_read(&get_cpu_var(siw_workq_len));
+
+ put_cpu_var(siw_workq_len);
+
+ if (workq_len) {
+ /* Another QP's work on same WQ */
+ siw_sq_queue_work(qp);
+ goto done;
+ }
+ }
+ max_burst = max(qp->attrs.sq_size, qp->attrs.ird);
+ }
+ goto next_wqe;
+
+ } else if (rv == -EAGAIN) {
+ dprint(DBG_WR|DBG_TX,
+ "(QP%d): SQ paused: hd/tr %d of %d, data %d\n",
+ QP_ID(qp), qp->tx_ctx.ctrl_sent, qp->tx_ctx.ctrl_len,
+ qp->tx_ctx.bytes_unsent);
+ rv = 0;
+ goto done;
+ } else {
+ /*
+ * WQE processing failed.
+ * Verbs 8.3.2:
+ * o It turns any WQE into a signalled WQE.
+ * o Local catastrophic error must be surfaced
+ * o QP must be moved into Terminate state: done by code
+ * doing socket state change processing
+ *
+ * o TODO: Termination message must be sent.
+ * o TODO: Implement more precise work completion errors,
+ * see enum ib_wc_status in ib_verbs.h
+ */
+ dprint(DBG_ON, " (QP%d): WQE type %d processing failed: %d\n",
+ QP_ID(qp), wr_type(wqe), rv);
+
+ lock_sq_rxsave(qp, flags);
+ /*
+ * RREQ may have already been completed by inbound RRESP!
+ */
+ if (tx_type == RDMAP_RDMA_READ_REQ) {
+ lock_orq(qp);
+ if (!ORQ_EMPTY(qp) &&
+ wqe == list_entry_wqe(qp->orq.prev)) {
+ /*
+ * wqe still on the ORQ
+ * TODO: fix a potential race condition if the
+ * rx path is currently referencing the wqe(!)
+ */
+ dprint(DBG_ON, " (QP%d): Bad RREQ in ORQ\n",
+ QP_ID(qp));
+ list_del_init(&wqe->list);
+ unlock_orq(qp);
+ } else {
+ /*
+ * already completed by inbound RRESP
+ */
+ dprint(DBG_ON, " (QP%d): Bad RREQ completed\n",
+ QP_ID(qp));
+ unlock_orq(qp);
+ tx_wqe(qp) = NULL;
+ unlock_sq_rxsave(qp, flags);
+
+ goto done;
+ }
+ }
+ tx_wqe(qp) = NULL;
+ unlock_sq_rxsave(qp, flags);
+ /*
+ * immediately suspends further TX processing
+ */
+ if (!qp->tx_ctx.tx_suspend)
+ siw_qp_cm_drop(qp, 0);
+
+ switch (tx_type) {
+
+ case SIW_WR_SEND:
+ case SIW_WR_RDMA_WRITE:
+ case SIW_WR_RDMA_READ_REQ:
+ wqe->wr_status = SR_WR_DONE;
+ wqe->wc_status = IB_WC_LOC_QP_OP_ERR;
+ wqe->error = rv;
+ wr_flags(wqe) |= IB_SEND_SIGNALED;
+ if (tx_type != SIW_WR_RDMA_READ_REQ)
+ /*
+ * RREQ already enqueued to ORQ queue
+ */
+ siw_wqe_sq_processed(wqe, qp);
+
+ siw_async_ev(qp, NULL, IB_EVENT_QP_FATAL);
+
+ break;
+
+ case SIW_WR_RDMA_READ_RESP:
+ /*
+ * Recyclye wqe
+ */
+ dprint(DBG_WR|DBG_TX|DBG_ON, "(QP%d): "
+ "Processing RRESPONSE failed with %d\n",
+ QP_ID(qp), rv);
+
+ siw_async_ev(qp, NULL, IB_EVENT_QP_REQ_ERR);
+
+ siw_wqe_put(wqe);
+ break;
+
+ default:
+ BUG();
+ }
+ }
+done:
+ atomic_dec(&qp->tx_ctx.in_use);
+ wake_up(&qp->tx_ctx.waitq);
+
+ return rv;
+}
+
+static struct workqueue_struct *siw_sq_wq;
+
+int __init siw_sq_worker_init(void)
+{
+ siw_sq_wq = create_workqueue("siw_sq_wq");
+ if (!siw_sq_wq)
+ return -ENOMEM;
+
+ dprint(DBG_TX|DBG_OBJ, " Init WQ\n");
+ return 0;
+}
+
+
+void __exit siw_sq_worker_exit(void)
+{
+ dprint(DBG_TX|DBG_OBJ, " Destroy WQ\n");
+ if (siw_sq_wq) {
+ flush_workqueue(siw_sq_wq);
+ destroy_workqueue(siw_sq_wq);
+ }
+}
+
+
+/*
+ * siw_sq_work_handler()
+ *
+ * Scheduled by siw_qp_llp_write_space() socket callback if socket
+ * send space became available again. This function resumes SQ
+ * processing.
+ */
+static void siw_sq_work_handler(struct work_struct *w)
+{
+ struct siw_sq_work *this_work;
+ struct siw_qp *qp;
+ int rv;
+
+ atomic_dec(&get_cpu_var(siw_workq_len));
+ put_cpu_var(siw_workq_len);
+
+ this_work = container_of(w, struct siw_sq_work, work);
+ qp = container_of(this_work, struct siw_qp, sq_work);
+
+ dprint(DBG_TX|DBG_OBJ, "(QP%d)\n", QP_ID(qp));
+
+ if (down_read_trylock(&qp->state_lock)) {
+ if (likely(qp->attrs.state == SIW_QP_STATE_RTS &&
+ !qp->tx_ctx.tx_suspend)) {
+
+ rv = siw_qp_sq_process(qp, 0);
+ up_read(&qp->state_lock);
+
+ if (rv < 0) {
+ dprint(DBG_TX, "(QP%d): failed: %d\n",
+ QP_ID(qp), rv);
+
+ if (!qp->tx_ctx.tx_suspend)
+ siw_qp_cm_drop(qp, 0);
+ }
+ } else {
+ dprint(DBG_ON|DBG_TX, "(QP%d): state: %d %d\n",
+ QP_ID(qp), qp->attrs.state,
+ qp->tx_ctx.tx_suspend);
+ up_read(&qp->state_lock);
+ }
+ } else {
+ dprint(DBG_ON|DBG_TX, "(QP%d): QP locked\n", QP_ID(qp));
+ }
+ siw_qp_put(qp);
+}
+
+
+int siw_sq_queue_work(struct siw_qp *qp)
+{
+ int cpu, rv;
+
+ dprint(DBG_TX|DBG_OBJ, "(QP%d)\n", QP_ID(qp));
+
+ siw_qp_get(qp);
+
+ INIT_WORK(&qp->sq_work.work, siw_sq_work_handler);
+
+ cpu = get_cpu();
+#if NR_CPUS > 1
+ if (in_softirq()) {
+ int sq_cpu;
+ if (cpu == qp->cpu) {
+ /*
+ * Try not to use the current CPU for tx traffic.
+ */
+ for_each_online_cpu(sq_cpu) {
+ if (sq_cpu != cpu)
+ break;
+ }
+ } else
+ sq_cpu = qp->cpu;
+
+ if (cpu_online(sq_cpu))
+ cpu = sq_cpu;
+ }
+#endif
+ atomic_inc(&per_cpu(siw_workq_len, cpu));
+ /*
+ * Remember CPU: Avoid spreading SQ work of QP over WQ's
+ */
+ qp->cpu = cpu;
+ rv = queue_work_on(cpu, siw_sq_wq, &qp->sq_work.work);
+
+ put_cpu();
+
+ return rv;
+}
--
1.5.4.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 09/14] SIWv2: Completion queue: siw_cq.c
From: Bernard Metzler @ 2011-06-16 12:42 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA, Bernard Metzler
---
drivers/infiniband/hw/siw/siw_cq.c | 227 ++++++++++++++++++++++++++++++++++++
1 files changed, 227 insertions(+), 0 deletions(-)
create mode 100644 drivers/infiniband/hw/siw/siw_cq.c
diff --git a/drivers/infiniband/hw/siw/siw_cq.c b/drivers/infiniband/hw/siw/siw_cq.c
new file mode 100644
index 0000000..4f2a425
--- /dev/null
+++ b/drivers/infiniband/hw/siw/siw_cq.c
@@ -0,0 +1,227 @@
+/*
+ * Software iWARP device driver for Linux
+ *
+ * Authors: Bernard Metzler <bmt-OA+xvbQnYDHMbYB6QlFGEg@public.gmane.org>
+ *
+ * Copyright (c) 2008-2011, IBM Corporation
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of IBM nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/list.h>
+
+#include <rdma/iw_cm.h>
+#include <rdma/ib_verbs.h>
+#include <rdma/ib_smi.h>
+#include <rdma/ib_user_verbs.h>
+
+#include "siw.h"
+#include "siw_obj.h"
+#include "siw_cm.h"
+
+static int siw_wc_op_siw2ofa[SIW_WR_NUM] = {
+ [SIW_WR_RDMA_WRITE] = IB_WC_RDMA_WRITE,
+ [SIW_WR_RDMA_WRITE_WITH_IMM] = IB_WC_RDMA_WRITE,
+ [SIW_WR_SEND] = IB_WC_SEND,
+ [SIW_WR_SEND_WITH_IMM] = IB_WC_SEND,
+ [SIW_WR_RDMA_READ_REQ] = IB_WC_RDMA_READ,
+ [SIW_WR_ATOMIC_CMP_AND_SWP] = IB_WC_COMP_SWAP,
+ [SIW_WR_ATOMIC_FETCH_AND_ADD] = IB_WC_FETCH_ADD,
+ [SIW_WR_FASTREG] = IB_WC_FAST_REG_MR,
+ [SIW_WR_INVAL_STAG] = IB_WC_LOCAL_INV,
+ [SIW_WR_RECEIVE] = IB_WC_RECV,
+ [SIW_WR_RDMA_READ_RESP] = 0 /* not used */
+};
+
+/*
+ * translate wc into ofa syntax
+ */
+static void siw_wc_siw2ofa(struct siw_wqe *siw_wc, struct ib_wc *ofa_wc)
+{
+ memset(ofa_wc, 0, sizeof *ofa_wc);
+
+ ofa_wc->wr_id = wr_id(siw_wc);
+ ofa_wc->status = siw_wc->wc_status;
+ ofa_wc->byte_len = siw_wc->processed;
+ ofa_wc->qp = &siw_wc->qp->ofa_qp;
+
+ ofa_wc->opcode = siw_wc_op_siw2ofa[wr_type(siw_wc)];
+ /*
+ * ofa_wc->imm_data = 0;
+ * ofa_wc->vendor_err = 0;
+ * ofa_wc->src_qp = 0;
+ * ofa_wc->wc_flags = 0; ADD immediate data support
+ * ofa_wc->pkey_index = 0;
+ * ofa_wc->slid = 0;
+ * ofa_wc->sl = 0;
+ * ofa_wc->dlid_path_bits = 0;
+ * ofa_wc->port_num = 0;
+ */
+}
+
+/*
+ * Reap one CQE from the CQ.
+ *
+ * Caller must hold qp read lock
+ *
+ * TODO: Provide routine which can read more than one CQE
+ */
+int siw_reap_cqe(struct siw_cq *cq, struct ib_wc *ofa_wc)
+{
+ struct siw_wqe *cqe = NULL;
+ unsigned long flags;
+
+ lock_cq_rxsave(cq, flags);
+
+ if (!list_empty(&cq->queue)) {
+ cqe = list_first_wqe(&cq->queue);
+ list_del(&cqe->list);
+ atomic_dec(&cq->qlen);
+ }
+ unlock_cq_rxsave(cq, flags);
+
+ if (cqe) {
+ siw_wc_siw2ofa(cqe, ofa_wc);
+
+ dprint(DBG_WR, " QP%d, CQ%d: Reap WQE type: %d, p: %p\n",
+ QP_ID(cqe->qp), OBJ_ID(cq), wr_type(cqe), cqe);
+
+ siw_wqe_put(cqe);
+ return 1;
+ } else
+ return 0;
+}
+
+/*
+ * siw_cq_flush()
+ *
+ * Flush all CQ elements. No CQ lock is taken.
+ */
+void siw_cq_flush(struct siw_cq *cq)
+{
+ struct list_head *pos, *n;
+ struct siw_wqe *cqe;
+
+ dprint(DBG_CM|DBG_OBJ, "(CQ%d:) Enter\n", OBJ_ID(cq));
+
+ if (list_empty(&cq->queue))
+ return;
+
+ list_for_each_safe(pos, n, &cq->queue) {
+ cqe = list_entry_wqe(pos);
+ list_del(&cqe->list);
+
+ dprint(DBG_OBJ|DBG_WR, " WQE: 0x%llu:, type: %d, p: %p\n",
+ (unsigned long long)wr_id(cqe),
+ wr_type(cqe), cqe);
+
+ siw_wqe_put(cqe);
+ }
+ atomic_set(&cq->qlen, 0);
+}
+
+
+
+/*
+ * siw_rq_complete()
+ *
+ * Appends RQ/SRQ WQE to CQ, if assigned.
+ * Must be called with qp state read locked
+ */
+void siw_rq_complete(struct siw_wqe *wqe, struct siw_qp *qp)
+{
+ struct siw_cq *cq = qp->rcq;
+ unsigned long flags;
+
+ dprint(DBG_OBJ|DBG_WR, " QP%d WQE: 0x%llu:, type: %d, p: %p\n",
+ QP_ID(qp),
+ (unsigned long long)wr_id(wqe), wr_type(wqe), wqe);
+
+ if (cq) {
+ lock_cq_rxsave(cq, flags);
+
+ list_add_tail(&wqe->list, &cq->queue);
+ atomic_inc(&cq->qlen); /* FIXME: test overflow */
+
+ unlock_cq_rxsave(cq, flags);
+
+ if (cq->ofa_cq.comp_handler != NULL &&
+ ((cq->notify & SIW_CQ_NOTIFY_ALL) ||
+ (cq->notify == SIW_CQ_NOTIFY_SOLICITED &&
+ wr_flags(wqe) & IB_SEND_SOLICITED))) {
+ cq->notify = SIW_CQ_NOTIFY_NOT;
+ (*cq->ofa_cq.comp_handler)
+ (&cq->ofa_cq, cq->ofa_cq.cq_context);
+ }
+ } else
+ siw_wqe_put(wqe);
+}
+
+/*
+ * siw_sq_complete()
+ * Appends list of former SQ WQE's to CQ, if assigned.
+ * Must be called with qp state read locked
+ */
+void siw_sq_complete(struct list_head *c_list, struct siw_qp *qp, int num,
+ enum ib_send_flags send_flags)
+{
+ struct siw_cq *cq = qp->scq;
+ unsigned long flags;
+
+ if (cq) {
+ lock_cq_rxsave(cq, flags);
+
+ list_splice_tail(c_list, &cq->queue);
+ atomic_add(num, &cq->qlen); /* FIXME: test overflow */
+
+
+ dprint(DBG_WR, " CQ%d: add %d from QP%d, CQ len %d\n",
+ OBJ_ID(cq), num, QP_ID(qp), atomic_read(&cq->qlen));
+
+ if (cq->ofa_cq.comp_handler != NULL &&
+ ((cq->notify & SIW_CQ_NOTIFY_ALL) ||
+ (cq->notify == SIW_CQ_NOTIFY_SOLICITED &&
+ send_flags & IB_SEND_SOLICITED))) {
+ cq->notify = SIW_CQ_NOTIFY_NOT;
+ unlock_cq_rxsave(cq, flags);
+ (*cq->ofa_cq.comp_handler)
+ (&cq->ofa_cq, cq->ofa_cq.cq_context);
+ } else
+ unlock_cq_rxsave(cq, flags);
+ } else {
+ struct list_head *pos;
+
+ list_for_each(pos, c_list)
+ siw_wqe_put(list_entry_wqe(pos));
+ }
+}
--
1.5.4.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/14] SIWv2: Connection management: siw_cm.c, siw_cm.h
From: Bernard Metzler @ 2011-06-16 12:42 UTC (permalink / raw)
To: netdev; +Cc: linux-rdma, Bernard Metzler
---
drivers/infiniband/hw/siw/siw_cm.c | 1947 ++++++++++++++++++++++++++++++++++++
drivers/infiniband/hw/siw/siw_cm.h | 159 +++
2 files changed, 2106 insertions(+), 0 deletions(-)
create mode 100644 drivers/infiniband/hw/siw/siw_cm.c
create mode 100644 drivers/infiniband/hw/siw/siw_cm.h
diff --git a/drivers/infiniband/hw/siw/siw_cm.c b/drivers/infiniband/hw/siw/siw_cm.c
new file mode 100644
index 0000000..46d2935
--- /dev/null
+++ b/drivers/infiniband/hw/siw/siw_cm.c
@@ -0,0 +1,1947 @@
+/*
+ * Software iWARP device driver for Linux
+ *
+ * Authors: Bernard Metzler <bmt@zurich.ibm.com>
+ * Fredy Neeser <nfd@zurich.ibm.com>
+ *
+ * Copyright (c) 2008-2011, IBM Corporation
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of IBM nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/net.h>
+#include <linux/inetdevice.h>
+#include <linux/workqueue.h>
+#include <net/sock.h>
+#include <linux/tcp.h>
+
+
+#include <rdma/iw_cm.h>
+#include <rdma/ib_verbs.h>
+#include <rdma/ib_smi.h>
+#include <rdma/ib_user_verbs.h>
+
+#include "siw.h"
+#include "siw_cm.h"
+#include "siw_obj.h"
+
+static bool mpa_crc_strict = 1;
+module_param(mpa_crc_strict, bool, 0644);
+static bool mpa_crc_required;
+module_param(mpa_crc_required, bool, 0644);
+static bool tcp_nodelay = 1;
+module_param(tcp_nodelay, bool, 0644);
+
+MODULE_PARM_DESC(mpa_crc_required, "MPA CRC required");
+MODULE_PARM_DESC(mpa_crc_strict, "MPA CRC off enforced");
+MODULE_PARM_DESC(tcp_nodelay, "Set TCP NODELAY");
+
+
+/*
+ * siw_sock_nodelay() - Disable Nagle algorithm
+ */
+static int siw_sock_nodelay(struct socket *sock)
+{
+ mm_segment_t oldfs;
+ int rv, val = 1;
+
+ if (!tcp_nodelay)
+ return 0;
+
+ oldfs = get_fs();
+
+ set_fs(KERNEL_DS);
+
+ rv = sock->ops->setsockopt(sock, SOL_TCP, TCP_NODELAY,
+ (char __user *)&val, sizeof(val));
+ set_fs(oldfs);
+ return rv;
+}
+
+static void siw_cm_llp_state_change(struct sock *);
+static void siw_cm_llp_data_ready(struct sock *, int);
+static void siw_cm_llp_write_space(struct sock *);
+static void siw_cm_llp_error_report(struct sock *);
+
+static void siw_sk_assign_cm_upcalls(struct sock *sk)
+{
+ write_lock_bh(&sk->sk_callback_lock);
+ sk->sk_state_change = siw_cm_llp_state_change;
+ sk->sk_data_ready = siw_cm_llp_data_ready;
+ sk->sk_write_space = siw_cm_llp_write_space;
+ sk->sk_error_report = siw_cm_llp_error_report;
+ write_unlock_bh(&sk->sk_callback_lock);
+}
+
+static void siw_sk_save_upcalls(struct sock *sk)
+{
+ struct siw_cep *cep = sk_to_cep(sk);
+ BUG_ON(!cep);
+
+ write_lock_bh(&sk->sk_callback_lock);
+ cep->sk_state_change = sk->sk_state_change;
+ cep->sk_data_ready = sk->sk_data_ready;
+ cep->sk_write_space = sk->sk_write_space;
+ cep->sk_error_report = sk->sk_error_report;
+ write_unlock_bh(&sk->sk_callback_lock);
+}
+
+static void siw_sk_restore_upcalls(struct sock *sk, struct siw_cep *cep)
+{
+ sk->sk_state_change = cep->sk_state_change;
+ sk->sk_data_ready = cep->sk_data_ready;
+ sk->sk_write_space = cep->sk_write_space;
+ sk->sk_error_report = cep->sk_error_report;
+ sk->sk_user_data = NULL;
+ sk->sk_no_check = 0;
+}
+
+static void siw_socket_disassoc(struct socket *s)
+{
+ struct sock *sk = s->sk;
+ struct siw_cep *cep;
+
+ if (sk) {
+ write_lock_bh(&sk->sk_callback_lock);
+ cep = sk_to_cep(sk);
+ if (cep) {
+ siw_sk_restore_upcalls(sk, cep);
+ siw_cep_put(cep);
+ }
+ write_unlock_bh(&sk->sk_callback_lock);
+ }
+}
+
+
+static inline int kernel_peername(struct socket *s, struct sockaddr_in *addr)
+{
+ int unused;
+ return s->ops->getname(s, (struct sockaddr *)addr, &unused, 1);
+}
+
+static inline int kernel_localname(struct socket *s, struct sockaddr_in *addr)
+{
+ int unused;
+ return s->ops->getname(s, (struct sockaddr *)addr, &unused, 0);
+}
+
+static void siw_cep_socket_assoc(struct siw_cep *cep, struct socket *s)
+{
+ cep->llp.sock = s;
+ siw_cep_get(cep);
+ s->sk->sk_user_data = cep;
+
+ siw_sk_save_upcalls(s->sk);
+ siw_sk_assign_cm_upcalls(s->sk);
+}
+
+
+static struct siw_cep *siw_cep_alloc(struct siw_dev *dev)
+{
+ struct siw_cep *cep = kzalloc(sizeof *cep, GFP_KERNEL);
+ if (cep) {
+ unsigned long flags;
+
+ INIT_LIST_HEAD(&cep->listenq);
+ INIT_LIST_HEAD(&cep->devq);
+ INIT_LIST_HEAD(&cep->work_freelist);
+
+ cep->mpa.hdr.params.m = 0;
+ cep->mpa.hdr.params.rev = MPA_REVISION_1;
+ kref_init(&cep->ref);
+ cep->state = SIW_EPSTATE_IDLE;
+ init_waitqueue_head(&cep->waitq);
+ spin_lock_init(&cep->lock);
+ cep->dev = dev;
+
+ spin_lock_irqsave(&dev->idr_lock, flags);
+ list_add_tail(&cep->devq, &dev->cep_list);
+ spin_unlock_irqrestore(&dev->idr_lock, flags);
+ atomic_inc(&dev->num_cep);
+
+ dprint(DBG_OBJ|DBG_CM, "(CEP 0x%p): New Object\n", cep);
+ }
+ return cep;
+}
+
+static void siw_cm_free_work(struct siw_cep *cep)
+{
+ struct list_head *w, *tmp;
+ struct siw_cm_work *work;
+
+ list_for_each_safe(w, tmp, &cep->work_freelist) {
+ work = list_entry(w, struct siw_cm_work, list);
+ list_del(&work->list);
+ kfree(work);
+ }
+}
+
+static void siw_cancel_mpatimer(struct siw_cep *cep)
+{
+ spin_lock_bh(&cep->lock);
+ if (cep->mpa_timer) {
+ if (cancel_delayed_work(&cep->mpa_timer->work)) {
+ siw_cep_put(cep);
+ kfree(cep->mpa_timer); /* not needed again */
+ }
+ cep->mpa_timer = NULL;
+ }
+ spin_unlock_bh(&cep->lock);
+}
+
+static void siw_put_work(struct siw_cm_work *work)
+{
+ INIT_LIST_HEAD(&work->list);
+ spin_lock_bh(&work->cep->lock);
+ list_add(&work->list, &work->cep->work_freelist);
+ spin_unlock_bh(&work->cep->lock);
+}
+
+static void siw_cep_set_inuse(struct siw_cep *cep)
+{
+ unsigned long flags;
+ int rv;
+retry:
+ dprint(DBG_CM, " (CEP 0x%p): use %d\n",
+ cep, cep->in_use);
+
+ spin_lock_irqsave(&cep->lock, flags);
+
+ if (cep->in_use) {
+ spin_unlock_irqrestore(&cep->lock, flags);
+ rv = wait_event_interruptible(cep->waitq, !cep->in_use);
+ if (signal_pending(current))
+ flush_signals(current);
+ goto retry;
+ } else {
+ cep->in_use = 1;
+ spin_unlock_irqrestore(&cep->lock, flags);
+ }
+}
+
+static void siw_cep_set_free(struct siw_cep *cep)
+{
+ unsigned long flags;
+
+ dprint(DBG_CM, " (CEP 0x%p): use %d\n",
+ cep, cep->in_use);
+
+ spin_lock_irqsave(&cep->lock, flags);
+ cep->in_use = 0;
+ spin_unlock_irqrestore(&cep->lock, flags);
+
+ wake_up(&cep->waitq);
+}
+
+static void siw_cm_release(struct siw_cep *cep)
+{
+ dprint(DBG_CM, " (CEP 0x%p): mpa_timer=%s, sock=0x%p, QP%d, id=0x%p\n",
+ cep, cep->mpa_timer ? "y" : "n", cep->llp.sock,
+ cep->qp ? QP_ID(cep->qp) : -1, cep->cm_id);
+
+ siw_cancel_mpatimer(cep);
+
+ if (cep->llp.sock) {
+ siw_socket_disassoc(cep->llp.sock);
+ sock_release(cep->llp.sock);
+ cep->llp.sock = NULL;
+ }
+ if (cep->qp) {
+ struct siw_qp *qp = cep->qp;
+ cep->qp = NULL;
+ siw_qp_put(qp);
+ }
+ if (cep->cm_id) {
+ cep->cm_id->rem_ref(cep->cm_id);
+ cep->cm_id = NULL;
+ siw_cep_put(cep);
+ }
+ cep->state = SIW_EPSTATE_CLOSED;
+}
+
+
+static void __siw_cep_dealloc(struct kref *ref)
+{
+ struct siw_cep *cep = container_of(ref, struct siw_cep, ref);
+ struct siw_dev *dev = cep->dev;
+ unsigned long flags;
+
+ dprint(DBG_OBJ|DBG_CM, "(CEP 0x%p): Free Object\n", cep);
+
+ WARN_ON(cep->listen_cep);
+
+ /* kfree(NULL) is save */
+ kfree(cep->mpa.pdata);
+ spin_lock_bh(&cep->lock);
+ if (!list_empty(&cep->work_freelist))
+ siw_cm_free_work(cep);
+ spin_unlock_bh(&cep->lock);
+
+ spin_lock_irqsave(&dev->idr_lock, flags);
+ list_del(&cep->devq);
+ spin_unlock_irqrestore(&dev->idr_lock, flags);
+ atomic_dec(&dev->num_cep);
+ kfree(cep);
+}
+
+static struct siw_cm_work *siw_get_work(struct siw_cep *cep)
+{
+ struct siw_cm_work *work = NULL;
+
+ spin_lock_bh(&cep->lock);
+ if (!list_empty(&cep->work_freelist)) {
+ work = list_entry(cep->work_freelist.next, struct siw_cm_work,
+ list);
+ list_del_init(&work->list);
+ }
+ spin_unlock_bh(&cep->lock);
+ return work;
+}
+
+static int siw_cm_alloc_work(struct siw_cep *cep, int num)
+{
+ struct siw_cm_work *work;
+
+ BUG_ON(!list_empty(&cep->work_freelist));
+
+ while (num--) {
+ work = kmalloc(sizeof *work, GFP_KERNEL);
+ if (!work) {
+ if (!(list_empty(&cep->work_freelist)))
+ siw_cm_free_work(cep);
+ dprint(DBG_ON, " Failed\n");
+ return -ENOMEM;
+ }
+ work->cep = cep;
+ INIT_LIST_HEAD(&work->list);
+ list_add(&work->list, &cep->work_freelist);
+ }
+ return 0;
+}
+
+/*
+ * siw_cm_upcall()
+ *
+ * Upcall to IWCM to inform about async connection events
+ */
+static int siw_cm_upcall(struct siw_cep *cep, enum iw_cm_event_type reason,
+ int status)
+{
+ struct iw_cm_event event;
+ struct iw_cm_id *cm_id;
+
+ memset(&event, 0, sizeof event);
+ event.status = status;
+ event.event = reason;
+
+ if (cep->mpa.hdr.params.pd_len != 0) {
+ /*
+ * hand over MPA private data
+ */
+ event.private_data_len = cep->mpa.hdr.params.pd_len;
+ event.private_data = cep->mpa.pdata;
+
+ cep->mpa.hdr.params.pd_len = 0;
+ }
+ if (reason == IW_CM_EVENT_CONNECT_REQUEST ||
+ reason == IW_CM_EVENT_CONNECT_REPLY) {
+ event.local_addr = cep->llp.laddr;
+ event.remote_addr = cep->llp.raddr;
+ }
+ if (reason == IW_CM_EVENT_CONNECT_REQUEST) {
+ event.provider_data = cep;
+ cm_id = cep->listen_cep->cm_id;
+ } else
+ cm_id = cep->cm_id;
+
+ dprint(DBG_CM, " (QP%d): cep=0x%p, id=0x%p, dev(id)=%s, "
+ "reason=%d, status=%d\n",
+ cep->qp ? QP_ID(cep->qp) : -1, cep, cm_id,
+ cm_id->device->name, reason, status);
+
+ return cm_id->event_handler(cm_id, &event);
+}
+/*
+ * siw_qp_cm_drop()
+ *
+ * Drops established LLP connection if present and not already
+ * scheduled for dropping. Called from user context, SQ workqueue
+ * or receive IRQ. Caller signals if socket can be immediately
+ * closed (basically, if not in IRQ).
+ */
+void siw_qp_cm_drop(struct siw_qp *qp, int schedule)
+{
+ struct siw_cep *cep = qp->cep;
+
+ qp->rx_ctx.rx_suspend = 1;
+ qp->tx_ctx.tx_suspend = 1;
+
+ if (!qp->cep)
+ return;
+
+ if (schedule)
+ siw_cm_queue_work(cep, SIW_CM_WORK_CLOSE_LLP);
+ else {
+ siw_cep_set_inuse(cep);
+ /*
+ * Immediately close socket
+ */
+ dprint(DBG_CM, "(): immediate close, cep=0x%p, state=%d, "
+ "id=0x%p, sock=0x%p, QP%d\n", cep, cep->state,
+ cep->cm_id, cep->llp.sock,
+ cep->qp ? QP_ID(cep->qp) : -1);
+
+ if (cep->cm_id) {
+ switch (cep->state) {
+
+ case SIW_EPSTATE_AWAIT_MPAREP:
+ siw_cm_upcall(cep, IW_CM_EVENT_CONNECT_REPLY,
+ -EINVAL);
+ break;
+
+ case SIW_EPSTATE_RDMA_MODE:
+ siw_cm_upcall(cep, IW_CM_EVENT_CLOSE, 0);
+
+ break;
+
+ case SIW_EPSTATE_IDLE:
+ case SIW_EPSTATE_LISTENING:
+ case SIW_EPSTATE_CONNECTING:
+ case SIW_EPSTATE_AWAIT_MPAREQ:
+ case SIW_EPSTATE_RECVD_MPAREQ:
+ case SIW_EPSTATE_CLOSED:
+ default:
+
+ break;
+ }
+ cep->cm_id->rem_ref(cep->cm_id);
+ cep->cm_id = NULL;
+ siw_cep_put(cep);
+ }
+ cep->state = SIW_EPSTATE_CLOSED;
+
+ if (cep->llp.sock) {
+ siw_socket_disassoc(cep->llp.sock);
+ sock_release(cep->llp.sock);
+ cep->llp.sock = NULL;
+ }
+ if (cep->qp) {
+ cep->qp = NULL;
+ siw_qp_put(qp);
+ }
+ siw_cep_set_free(cep);
+ }
+}
+
+
+void siw_cep_put(struct siw_cep *cep)
+{
+ dprint(DBG_OBJ|DBG_CM, "(CEP 0x%p): New refcount: %d\n",
+ cep, atomic_read(&cep->ref.refcount) - 1);
+
+ BUG_ON(atomic_read(&cep->ref.refcount) < 1);
+ kref_put(&cep->ref, __siw_cep_dealloc);
+}
+
+void siw_cep_get(struct siw_cep *cep)
+{
+ kref_get(&cep->ref);
+ dprint(DBG_OBJ|DBG_CM, "(CEP 0x%p): New refcount: %d\n",
+ cep, atomic_read(&cep->ref.refcount));
+}
+
+
+
+static inline int ksock_recv(struct socket *sock, char *buf, size_t size,
+ int flags)
+{
+ struct kvec iov = {buf, size};
+ struct msghdr msg = {.msg_name = NULL, .msg_flags = flags};
+
+ return kernel_recvmsg(sock, &msg, &iov, 1, size, flags);
+}
+
+/*
+ * Expects params->pd_len in host byte order
+ *
+ * TODO: We might want to combine the arguments params and pdata to a single
+ * pointer to a struct siw_mpa_info as defined in siw_cm.h.
+ * This way, all private data parameters would be in a common struct.
+ */
+static int siw_send_mpareqrep(struct socket *s, struct mpa_rr_params *params,
+ char *key, const void *pdata)
+{
+ struct mpa_rr hdr;
+ struct kvec iov[2];
+ struct msghdr msg;
+
+ int rv;
+ unsigned short pd_len = params->pd_len;
+
+ memset(&msg, 0, sizeof(msg));
+ memset(&hdr, 0, sizeof hdr);
+ memcpy(hdr.key, key, 16);
+
+ /*
+ * TODO: By adding a union to struct mpa_rr_params, it should be
+ * possible to replace the next 4 statements by one
+ */
+ hdr.params.r = params->r;
+ hdr.params.c = params->c;
+ hdr.params.m = params->m;
+ hdr.params.rev = params->rev;
+
+ if (pd_len > MPA_MAX_PRIVDATA)
+ return -EINVAL;
+
+ hdr.params.pd_len = htons(pd_len);
+
+ iov[0].iov_base = &hdr;
+ iov[0].iov_len = sizeof hdr;
+
+ if (pd_len) {
+ iov[1].iov_base = (char *)pdata;
+ iov[1].iov_len = pd_len;
+
+ rv = kernel_sendmsg(s, &msg, iov, 2, pd_len + sizeof hdr);
+ } else
+ rv = kernel_sendmsg(s, &msg, iov, 1, sizeof hdr);
+
+ return rv < 0 ? rv : 0;
+}
+
+/*
+ * Receive MPA Request/Reply heder.
+ *
+ * Returns 0 if complete MPA Request/Reply haeder including
+ * eventual private data was received. Returns -EAGAIN if
+ * header was partially received or negative error code otherwise.
+ *
+ * Context: May be called in process context only
+ */
+static int siw_recv_mpa_rr(struct siw_cep *cep)
+{
+ struct mpa_rr *hdr = &cep->mpa.hdr;
+ struct socket *s = cep->llp.sock;
+ int rcvd, to_rcv;
+
+ if (cep->mpa.bytes_rcvd < sizeof(struct mpa_rr)) {
+
+ rcvd = ksock_recv(s, (char *)hdr + cep->mpa.bytes_rcvd,
+ sizeof(struct mpa_rr) -
+ cep->mpa.bytes_rcvd, 0);
+
+ if (rcvd <= 0)
+ return -ECONNABORTED;
+
+ cep->mpa.bytes_rcvd += rcvd;
+
+ if (cep->mpa.bytes_rcvd < sizeof(struct mpa_rr))
+ return -EAGAIN;
+
+ hdr->params.pd_len = ntohs(hdr->params.pd_len);
+
+ if (hdr->params.pd_len > MPA_MAX_PRIVDATA)
+ return -EPROTO;
+ }
+
+ /*
+ * At least the MPA Request/Reply header (frame not including
+ * private data) has been received.
+ * Receive (or continue receiving) any private data.
+ */
+ to_rcv = hdr->params.pd_len -
+ (cep->mpa.bytes_rcvd - sizeof(struct mpa_rr));
+
+ if (!to_rcv) {
+ /*
+ * We must have hdr->params.pd_len == 0 and thus received a
+ * complete MPA Request/Reply frame.
+ * Check against peer protocol violation.
+ */
+ __u32 word;
+
+ rcvd = ksock_recv(s, (char *)&word, sizeof word, MSG_DONTWAIT);
+ if (rcvd == -EAGAIN)
+ return 0;
+
+ if (rcvd == 0) {
+ dprint(DBG_CM, " peer EOF\n");
+ return -EPIPE;
+ }
+ if (rcvd < 0) {
+ dprint(DBG_CM, " ERROR: %d:\n", rcvd);
+ return rcvd;
+ }
+ dprint(DBG_CM, " peer sent extra data: %d\n", rcvd);
+ return -EPROTO;
+ }
+
+ /*
+ * At this point, we must have hdr->params.pd_len != 0.
+ * A private data buffer gets allocated if hdr->params.pd_len != 0.
+ */
+ if (!cep->mpa.pdata) {
+ cep->mpa.pdata = kmalloc(hdr->params.pd_len + 4, GFP_KERNEL);
+ if (!cep->mpa.pdata)
+ return -ENOMEM;
+ }
+ rcvd = ksock_recv(s, cep->mpa.pdata + cep->mpa.bytes_rcvd
+ - sizeof(struct mpa_rr), to_rcv + 4, MSG_DONTWAIT);
+
+ if (rcvd < 0)
+ return rcvd;
+
+ if (rcvd > to_rcv)
+ return -EPROTO;
+
+ cep->mpa.bytes_rcvd += rcvd;
+
+ if (to_rcv == rcvd) {
+ dprint(DBG_CM, " %d bytes private_data received\n",
+ hdr->params.pd_len);
+ return 0;
+ }
+ return -EAGAIN;
+}
+
+
+/*
+ * siw_proc_mpareq()
+ *
+ * Read MPA Request from socket and signal new connection to IWCM
+ * if success. Caller must hold lock on corresponding listening CEP.
+ */
+static int siw_proc_mpareq(struct siw_cep *cep)
+{
+ int rv = siw_recv_mpa_rr(cep);
+ if (rv != -EAGAIN)
+ siw_cancel_mpatimer(cep);
+ if (rv)
+ goto out;
+
+ if (cep->mpa.hdr.params.rev > MPA_REVISION_1) {
+ /* allow for 0 and 1 only */
+ rv = -EPROTO;
+ goto out;
+ }
+
+ if (memcmp(cep->mpa.hdr.key, MPA_KEY_REQ, sizeof cep->mpa.hdr.key)) {
+ rv = -EPROTO;
+ goto out;
+ }
+
+ if (cep->mpa.hdr.params.m ||
+ (cep->mpa.hdr.params.c && !mpa_crc_required && mpa_crc_strict)) {
+ /*
+ * MPA Markers: currently not supported. Marker TX to be added.
+ *
+ * CRC:
+ * RFC 5044, page 27: CRC MUST be used if peer requests it.
+ * siw specific: 'mpa_crc_strict' parameter to reject
+ * connection with CRC if local CRC off enforced by
+ * 'mpa_crc_strict' module parameter.
+ */
+ dprint(DBG_CM|DBG_ON, " Reject: CRC %d:%d:%d, M %d:%d\n",
+ cep->mpa.hdr.params.c, mpa_crc_required,
+ mpa_crc_strict, cep->mpa.hdr.params.m, 0);
+
+ cep->mpa.hdr.params.m = 0;
+ cep->mpa.hdr.params.r = 1; /* reject */
+
+ if (!mpa_crc_required && mpa_crc_strict)
+ cep->mpa.hdr.params.c = 0;
+
+ cep->mpa.hdr.params.pd_len = 0;
+ kfree(cep->mpa.pdata);
+ cep->mpa.pdata = NULL;
+
+ (void)siw_send_mpareqrep(cep->llp.sock, &cep->mpa.hdr.params,
+ MPA_KEY_REP, NULL);
+ rv = -EOPNOTSUPP;
+ goto out;
+ }
+ /*
+ * Enable CRC if requested by module initialization
+ */
+ if (!cep->mpa.hdr.params.c && mpa_crc_required)
+ cep->mpa.hdr.params.c = 1;
+
+ cep->state = SIW_EPSTATE_RECVD_MPAREQ;
+
+ /* Keep reference until IWCM accepts/rejects */
+ siw_cep_get(cep);
+ rv = siw_cm_upcall(cep, IW_CM_EVENT_CONNECT_REQUEST, 0);
+ if (rv)
+ siw_cep_put(cep);
+out:
+ return rv;
+}
+
+
+static int siw_proc_mpareply(struct siw_cep *cep)
+{
+ struct siw_qp_attrs qp_attrs;
+ struct siw_qp *qp = cep->qp;
+ int rv;
+
+ rv = siw_recv_mpa_rr(cep);
+ if (rv != -EAGAIN)
+ siw_cancel_mpatimer(cep);
+ if (rv)
+ goto out_err;
+
+ if (cep->mpa.hdr.params.rev > MPA_REVISION_1) {
+ /* allow for 0 and 1 only */
+ rv = -EPROTO;
+ goto out_err;
+ }
+ if (memcmp(cep->mpa.hdr.key, MPA_KEY_REP, sizeof cep->mpa.hdr.key)) {
+ rv = -EPROTO;
+ goto out_err;
+ }
+ if (cep->mpa.hdr.params.r) {
+ dprint(DBG_CM, "(cep=0x%p): Got MPA reject\n", cep);
+ (void)siw_cm_upcall(cep, IW_CM_EVENT_CONNECT_REPLY,
+ -ECONNRESET);
+
+ rv = -ECONNRESET;
+ goto out;
+ }
+ if ((cep->mpa.hdr.params.m == 1) ||
+ (mpa_crc_required && !cep->mpa.hdr.params.c) ||
+ (mpa_crc_strict && !mpa_crc_required && cep->mpa.hdr.params.c)) {
+
+ dprint(DBG_CM|DBG_ON, " Reply unsupp: CRC %d:%d:%d, M %d:%d\n",
+ cep->mpa.hdr.params.c, mpa_crc_required,
+ mpa_crc_strict, cep->mpa.hdr.params.m, 0);
+
+ (void)siw_cm_upcall(cep, IW_CM_EVENT_CONNECT_REPLY,
+ -ECONNREFUSED);
+ rv = -EINVAL;
+ goto out;
+ }
+ memset(&qp_attrs, 0, sizeof qp_attrs);
+ qp_attrs.mpa.marker_rcv = 0;
+ qp_attrs.mpa.marker_snd = 0;
+ qp_attrs.mpa.crc = cep->mpa.hdr.params.c;
+ qp_attrs.ird = cep->ird;
+ qp_attrs.ord = cep->ord;
+ qp_attrs.llp_stream_handle = cep->llp.sock;
+ qp_attrs.state = SIW_QP_STATE_RTS;
+
+ /* Move socket RX/TX under QP control */
+ down_write(&qp->state_lock);
+ if (qp->attrs.state > SIW_QP_STATE_RTR) {
+ rv = -EINVAL;
+ up_write(&qp->state_lock);
+ goto out_err;
+ }
+ rv = siw_qp_modify(qp, &qp_attrs, SIW_QP_ATTR_STATE|
+ SIW_QP_ATTR_LLP_HANDLE|
+ SIW_QP_ATTR_ORD|
+ SIW_QP_ATTR_IRD|
+ SIW_QP_ATTR_MPA);
+
+ up_write(&qp->state_lock);
+
+ if (!rv) {
+ rv = siw_cm_upcall(cep, IW_CM_EVENT_CONNECT_REPLY, 0);
+ if (!rv)
+ cep->state = SIW_EPSTATE_RDMA_MODE;
+
+ goto out;
+ }
+
+out_err:
+ (void)siw_cm_upcall(cep, IW_CM_EVENT_CONNECT_REPLY, -EINVAL);
+out:
+ return rv;
+}
+
+/*
+ * siw_accept_newconn - accept an incoming pending connection
+ *
+ */
+static void siw_accept_newconn(struct siw_cep *cep)
+{
+ struct socket *s = cep->llp.sock;
+ struct socket *new_s = NULL;
+ struct siw_cep *new_cep = NULL;
+ int rv = 0; /* debug only. should disappear */
+
+ if (cep->state != SIW_EPSTATE_LISTENING)
+ goto error;
+
+ new_cep = siw_cep_alloc(cep->dev);
+ if (!new_cep)
+ goto error;
+
+ if (siw_cm_alloc_work(new_cep, 4) != 0)
+ goto error;
+
+ /*
+ * Copy saved socket callbacks from listening CEP
+ * and assign new socket with new CEP
+ */
+ new_cep->sk_state_change = cep->sk_state_change;
+ new_cep->sk_data_ready = cep->sk_data_ready;
+ new_cep->sk_write_space = cep->sk_write_space;
+ new_cep->sk_error_report = cep->sk_error_report;
+
+ rv = kernel_accept(s, &new_s, O_NONBLOCK);
+ if (rv != 0) {
+ /*
+ * TODO: Already aborted by peer?
+ * Is there anything we should do?
+ */
+ dprint(DBG_CM|DBG_ON, "(cep=0x%p): ERROR: "
+ "kernel_accept(): rv=%d\n", cep, rv);
+ goto error;
+ }
+ new_cep->llp.sock = new_s;
+ siw_cep_get(new_cep);
+ new_s->sk->sk_user_data = new_cep;
+
+ dprint(DBG_CM, "(cep=0x%p, s=0x%p, new_s=0x%p): "
+ "New LLP connection accepted\n", cep, s, new_s);
+
+ rv = siw_sock_nodelay(new_s);
+ if (rv != 0) {
+ dprint(DBG_CM|DBG_ON, "(cep=0x%p): ERROR: "
+ "siw_sock_nodelay(): rv=%d\n", cep, rv);
+ goto error;
+ }
+
+ rv = kernel_peername(new_s, &new_cep->llp.raddr);
+ if (rv != 0) {
+ dprint(DBG_CM|DBG_ON, "(cep=0x%p): ERROR: "
+ "kernel_peername(): rv=%d\n", cep, rv);
+ goto error;
+ }
+ rv = kernel_localname(new_s, &new_cep->llp.laddr);
+ if (rv != 0) {
+ dprint(DBG_CM|DBG_ON, "(cep=0x%p): ERROR: "
+ "kernel_localname(): rv=%d\n", cep, rv);
+ goto error;
+ }
+
+ new_cep->state = SIW_EPSTATE_AWAIT_MPAREQ;
+
+ rv = siw_cm_queue_work(new_cep, SIW_CM_WORK_MPATIMEOUT);
+ if (rv)
+ goto error;
+ /*
+ * See siw_proc_mpareq() etc. for the use of new_cep->listen_cep.
+ */
+ new_cep->listen_cep = cep;
+ siw_cep_get(cep);
+
+ if (atomic_read(&new_s->sk->sk_rmem_alloc)) {
+ /*
+ * MPA REQ already queued
+ */
+ dprint(DBG_CM, "(cep=0x%p): Immediate MPA req.\n", cep);
+
+ siw_cep_set_inuse(new_cep);
+ rv = siw_proc_mpareq(new_cep);
+ siw_cep_set_free(new_cep);
+
+ if (rv != -EAGAIN) {
+ siw_cep_put(cep);
+ new_cep->listen_cep = NULL;
+ if (rv)
+ goto error;
+ }
+ }
+ return;
+
+error:
+ if (new_cep)
+ siw_cep_put(new_cep);
+
+ if (new_s) {
+ siw_socket_disassoc(new_s);
+ sock_release(new_s);
+ }
+ dprint(DBG_CM|DBG_ON, "(cep=0x%p): ERROR: rv=%d\n", cep, rv);
+}
+
+
+static void siw_cm_work_handler(struct work_struct *w)
+{
+ struct siw_cm_work *work;
+ struct siw_cep *cep;
+ int rv = 0;
+
+ work = container_of(w, struct siw_cm_work, work.work);
+ cep = work->cep;
+
+ dprint(DBG_CM, " (QP%d): WORK type: %d, CEP: 0x%p, state: %d\n",
+ cep->qp ? QP_ID(cep->qp) : -1, work->type, cep, cep->state);
+
+ siw_cep_set_inuse(cep);
+
+ switch (work->type) {
+
+ case SIW_CM_WORK_ACCEPT:
+
+ siw_accept_newconn(cep);
+ break;
+
+ case SIW_CM_WORK_READ_MPAHDR:
+
+ switch (cep->state) {
+
+ case SIW_EPSTATE_AWAIT_MPAREQ:
+
+ if (cep->listen_cep) {
+ siw_cep_set_inuse(cep->listen_cep);
+
+ if (cep->listen_cep->state ==
+ SIW_EPSTATE_LISTENING)
+ rv = siw_proc_mpareq(cep);
+ else
+ rv = -EFAULT;
+
+ siw_cep_set_free(cep->listen_cep);
+
+ if (rv != -EAGAIN) {
+ siw_cep_put(cep->listen_cep);
+ cep->listen_cep = NULL;
+ if (rv)
+ siw_cep_put(cep);
+ }
+ }
+ break;
+
+ case SIW_EPSTATE_AWAIT_MPAREP:
+
+ rv = siw_proc_mpareply(cep);
+ break;
+
+ default:
+ /*
+ * CEP already moved out of MPA handshake.
+ * any connection management already done.
+ * silently ignore the mpa packet.
+ */
+ dprint(DBG_CM, "(): CEP not in MPA "
+ "handshake state: %d\n", cep->state);
+ }
+ if (rv && rv != EAGAIN)
+ siw_cm_release(cep);
+
+ break;
+
+ case SIW_CM_WORK_CLOSE_LLP:
+ /*
+ * QP scheduled LLP close
+ */
+ dprint(DBG_CM, "(): SIW_CM_WORK_CLOSE_LLP, cep->state=%d\n",
+ cep->state);
+
+ if (cep->cm_id)
+ siw_cm_upcall(cep, IW_CM_EVENT_CLOSE, 0);
+
+ siw_cm_release(cep);
+
+ break;
+
+ case SIW_CM_WORK_PEER_CLOSE:
+
+ dprint(DBG_CM, "(): SIW_CM_WORK_PEER_CLOSE, "
+ "cep->state=%d\n", cep->state);
+
+ if (cep->cm_id) {
+ switch (cep->state) {
+
+ case SIW_EPSTATE_AWAIT_MPAREP:
+ /*
+ * MPA reply not received, but connection drop
+ */
+ siw_cm_upcall(cep, IW_CM_EVENT_CONNECT_REPLY,
+ -ECONNRESET);
+ break;
+
+ case SIW_EPSTATE_RDMA_MODE:
+ /*
+ * NOTE: IW_CM_EVENT_DISCONNECT is given just
+ * to transition IWCM into CLOSING.
+ * FIXME: is that needed?
+ */
+ siw_cm_upcall(cep, IW_CM_EVENT_DISCONNECT, 0);
+ siw_cm_upcall(cep, IW_CM_EVENT_CLOSE, 0);
+
+ break;
+
+ default:
+
+ break;
+ /*
+ * for these states there is no connection
+ * known to the IWCM.
+ */
+ }
+ } else {
+ switch (cep->state) {
+
+ case SIW_EPSTATE_RECVD_MPAREQ:
+ /*
+ * Wait for the CM to call its accept/reject
+ */
+ dprint(DBG_CM, "(): STATE_RECVD_MPAREQ: "
+ "wait for CM:\n");
+ break;
+ case SIW_EPSTATE_AWAIT_MPAREQ:
+ /*
+ * Socket close before MPA request received.
+ */
+ dprint(DBG_CM,
+ "(): STATE_AWAIT_MPAREQ: "
+ "unlink from Listener\n");
+ siw_cep_put(cep->listen_cep);
+ cep->listen_cep = NULL;
+
+ break;
+
+ default:
+ break;
+ }
+ }
+ siw_cm_release(cep);
+
+ break;
+
+ case SIW_CM_WORK_MPATIMEOUT:
+
+ cep->mpa_timer = NULL;
+
+ if (cep->state == SIW_EPSTATE_AWAIT_MPAREP) {
+ /*
+ * MPA request timed out:
+ * Hide any partially received private data and signal
+ * timeout
+ */
+ cep->mpa.hdr.params.pd_len = 0;
+
+ if (cep->cm_id)
+ siw_cm_upcall(cep, IW_CM_EVENT_CONNECT_REPLY,
+ -ETIMEDOUT);
+ siw_cm_release(cep);
+
+ } else if (cep->state == SIW_EPSTATE_AWAIT_MPAREQ) {
+ /*
+ * No MPA request received after peer TCP stream setup.
+ */
+ siw_cep_put(cep->listen_cep);
+ cep->listen_cep = NULL;
+ siw_cm_release(cep);
+ }
+ break;
+
+ default:
+ BUG();
+ }
+
+ siw_cep_set_free(cep);
+
+ dprint(DBG_CM, " (Exit): WORK type: %d, CEP: 0x%p\n", work->type, cep);
+ siw_put_work(work);
+ siw_cep_put(cep);
+}
+
+static struct workqueue_struct *siw_cm_wq;
+
+int siw_cm_queue_work(struct siw_cep *cep, enum siw_work_type type)
+{
+ struct siw_cm_work *work = siw_get_work(cep);
+
+ dprint(DBG_CM, " (QP%d): WORK type: %d, CEP: 0x%p\n",
+ cep->qp ? QP_ID(cep->qp) : -1, type, cep);
+
+ if (!work) {
+ dprint(DBG_ON, " Failed\n");
+ return -ENOMEM;
+ }
+ work->type = type;
+ work->cep = cep;
+
+ siw_cep_get(cep);
+
+ INIT_DELAYED_WORK(&work->work, siw_cm_work_handler);
+
+ if (type == SIW_CM_WORK_MPATIMEOUT) {
+ unsigned long delay;
+ if (cep->state == SIW_EPSTATE_AWAIT_MPAREQ)
+ delay = MPAREQ_TIMEOUT;
+ else
+ delay = MPAREP_TIMEOUT;
+ cep->mpa_timer = work;
+ queue_delayed_work(siw_cm_wq, &work->work, delay);
+ } else
+ queue_delayed_work(siw_cm_wq, &work->work, 0);
+
+ return 0;
+}
+
+
+static void siw_cm_llp_data_ready(struct sock *sk, int flags)
+{
+ struct siw_cep *cep;
+
+ read_lock(&sk->sk_callback_lock);
+
+ cep = sk_to_cep(sk);
+ if (!cep) {
+ WARN_ON(1);
+ goto out;
+ }
+
+ dprint(DBG_CM, "(): cep 0x%p, state: %d, flags %x\n", cep,
+ cep->state, flags);
+
+ switch (cep->state) {
+
+ case SIW_EPSTATE_RDMA_MODE:
+ case SIW_EPSTATE_LISTENING:
+
+ break;
+
+ case SIW_EPSTATE_AWAIT_MPAREQ:
+ case SIW_EPSTATE_AWAIT_MPAREP:
+
+ siw_cm_queue_work(cep, SIW_CM_WORK_READ_MPAHDR);
+ break;
+
+ default:
+ dprint(DBG_CM, "(): Unexpected DATA, state %d\n", cep->state);
+ break;
+ }
+out:
+ read_unlock(&sk->sk_callback_lock);
+}
+
+static void siw_cm_llp_write_space(struct sock *sk)
+{
+ struct siw_cep *cep = sk_to_cep(sk);
+
+ if (cep)
+ dprint(DBG_CM, "(): cep: 0x%p, state: %d\n", cep, cep->state);
+}
+
+static void siw_cm_llp_error_report(struct sock *sk)
+{
+ struct siw_cep *cep = sk_to_cep(sk);
+
+ dprint(DBG_CM, "(): error: %d, state: %d\n", sk->sk_err, sk->sk_state);
+
+ if (cep) {
+ cep->sk_error = sk->sk_err;
+ dprint(DBG_CM, "(): cep->state: %d\n", cep->state);
+ cep->sk_error_report(sk);
+ }
+}
+
+static void siw_cm_llp_state_change(struct sock *sk)
+{
+ struct siw_cep *cep;
+ struct socket *s;
+ void (*orig_state_change)(struct sock *);
+
+
+ read_lock(&sk->sk_callback_lock);
+
+ cep = sk_to_cep(sk);
+ if (!cep) {
+ WARN_ON(1);
+ read_unlock(&sk->sk_callback_lock);
+ return;
+ }
+ orig_state_change = cep->sk_state_change;
+
+ s = sk->sk_socket;
+
+ dprint(DBG_CM, "(): cep: 0x%p, state: %d\n", cep, cep->state);
+
+ switch (sk->sk_state) {
+
+ case TCP_ESTABLISHED:
+ /*
+ * handle accepting socket as special case where only
+ * new connection is possible
+ */
+ siw_cm_queue_work(cep, SIW_CM_WORK_ACCEPT);
+
+ break;
+
+ case TCP_CLOSE:
+ case TCP_CLOSE_WAIT:
+
+ if (cep->qp)
+ cep->qp->tx_ctx.tx_suspend = 1;
+ siw_cm_queue_work(cep, SIW_CM_WORK_PEER_CLOSE);
+
+ break;
+
+ default:
+ dprint(DBG_CM, "Unexpected sock state %d\n", sk->sk_state);
+ }
+ read_unlock(&sk->sk_callback_lock);
+ orig_state_change(sk);
+}
+
+
+static int kernel_bindconnect(struct socket *s,
+ struct sockaddr *laddr, int laddrlen,
+ struct sockaddr *raddr, int raddrlen, int flags)
+{
+ int err, s_val = 1;
+ /*
+ * XXX
+ * Tentative fix. Should not be needed but sometimes iwcm
+ * chooses ports in use
+ */
+ err = kernel_setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&s_val,
+ sizeof s_val);
+ if (err < 0)
+ goto done;
+
+ err = s->ops->bind(s, laddr, laddrlen);
+ if (err < 0)
+ goto done;
+
+ err = s->ops->connect(s, raddr, raddrlen, flags);
+ if (err < 0)
+ goto done;
+
+ err = s->ops->getname(s, laddr, &s_val, 0);
+
+done:
+ return err;
+}
+
+
+int siw_connect(struct iw_cm_id *id, struct iw_cm_conn_param *params)
+{
+ struct siw_dev *dev = siw_dev_ofa2siw(id->device);
+ struct siw_qp *qp;
+ struct siw_cep *cep = NULL;
+ struct socket *s = NULL;
+ struct sockaddr *laddr, *raddr;
+
+ u16 pd_len = params->private_data_len;
+ int rv, size;
+
+ if (pd_len > MPA_MAX_PRIVDATA)
+ return -EINVAL;
+
+ qp = siw_qp_id2obj(dev, params->qpn);
+ BUG_ON(!qp);
+
+ dprint(DBG_CM, "(id=0x%p, QP%d): dev(id)=%s, l2dev=%s\n",
+ id, QP_ID(qp), dev->ofa_dev.name, dev->l2dev->name);
+ dprint(DBG_CM, "(id=0x%p, QP%d): laddr=(0x%x,%d), raddr=(0x%x,%d)\n",
+ id, QP_ID(qp),
+ ntohl(id->local_addr.sin_addr.s_addr),
+ ntohs(id->local_addr.sin_port),
+ ntohl(id->remote_addr.sin_addr.s_addr),
+ ntohs(id->remote_addr.sin_port));
+
+ laddr = (struct sockaddr *)&id->local_addr;
+ raddr = (struct sockaddr *)&id->remote_addr;
+
+ rv = sock_create(AF_INET, SOCK_STREAM, IPPROTO_TCP, &s);
+ if (rv < 0)
+ goto error;
+
+ size = SOCKBUFSIZE;
+ rv = kernel_setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *)&size,
+ sizeof size);
+ if (rv < 0)
+ goto error;
+
+ rv = kernel_setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&size,
+ sizeof size);
+ if (rv < 0)
+ goto error;
+
+ /*
+ * NOTE: For simplification, connect() is called in blocking
+ * mode. Might be reconsidered for async connection setup at
+ * TCP level.
+ */
+ rv = kernel_bindconnect(s, laddr, sizeof *laddr, raddr,
+ sizeof *raddr, 0);
+ if (rv != 0) {
+ dprint(DBG_CM, "(id=0x%p, QP%d): kernel_bindconnect: rv=%d\n",
+ id, QP_ID(qp), rv);
+ goto error;
+ }
+ rv = siw_sock_nodelay(s);
+ if (rv != 0) {
+ dprint(DBG_CM, "(id=0x%p, QP%d): siw_sock_nodelay(): rv=%d\n",
+ id, QP_ID(qp), rv);
+ goto error;
+ }
+ cep = siw_cep_alloc(dev);
+ if (!cep) {
+ rv = -ENOMEM;
+ goto error;
+ }
+ siw_cep_set_inuse(cep);
+
+ /* Associate QP with CEP */
+ siw_cep_get(cep);
+ qp->cep = cep;
+
+ /* siw_qp_get(qp) already done by QP lookup */
+ cep->qp = qp;
+
+ id->add_ref(id);
+ cep->cm_id = id;
+
+ rv = siw_cm_alloc_work(cep, 4);
+ if (rv != 0) {
+ rv = -ENOMEM;
+ goto error;
+ }
+
+ cep->mpa.hdr.params.c = mpa_crc_required ? 1 : 0;
+ cep->mpa.hdr.params.pd_len = pd_len;
+ cep->ird = params->ird;
+ cep->ord = params->ord;
+ cep->state = SIW_EPSTATE_CONNECTING;
+
+ dprint(DBG_CM, " (id=0x%p, QP%d): pd_len = %u\n",
+ id, QP_ID(qp), pd_len);
+
+ rv = kernel_peername(s, &cep->llp.raddr);
+ if (rv)
+ goto error;
+
+ rv = kernel_localname(s, &cep->llp.laddr);
+ if (rv)
+ goto error;
+
+ /*
+ * Associate CEP with socket
+ */
+ siw_cep_socket_assoc(cep, s);
+
+ cep->state = SIW_EPSTATE_AWAIT_MPAREP;
+
+ rv = siw_send_mpareqrep(cep->llp.sock, &cep->mpa.hdr.params,
+ MPA_KEY_REQ, (char *)params->private_data);
+ /*
+ * Reset private data.
+ */
+ kfree(cep->mpa.pdata);
+ cep->mpa.pdata = NULL;
+ cep->mpa.hdr.params.pd_len = 0;
+
+ if (rv >= 0) {
+ rv = siw_cm_queue_work(cep, SIW_CM_WORK_MPATIMEOUT);
+ if (!rv) {
+ dprint(DBG_CM, "(id=0x%p, cep=0x%p QP%d): Exit\n",
+ id, cep, QP_ID(qp));
+ siw_cep_set_free(cep);
+ return 0;
+ }
+ }
+error:
+ dprint(DBG_CM, " Failed: %d\n", rv);
+
+ if (cep) {
+ siw_socket_disassoc(s);
+ sock_release(s);
+ cep->llp.sock = NULL;
+
+ cep->qp = NULL;
+
+ cep->cm_id = NULL;
+ id->rem_ref(id);
+ siw_cep_put(cep);
+
+ qp->cep = NULL;
+ siw_cep_put(cep);
+
+ cep->state = SIW_EPSTATE_CLOSED;
+
+ siw_cep_set_free(cep);
+
+ siw_cep_put(cep);
+
+ } else if (s)
+ sock_release(s);
+
+ siw_qp_put(qp);
+
+ return rv;
+}
+
+/*
+ * siw_accept - Let SoftiWARP accept an RDMA connection request
+ *
+ * @id: New connection management id to be used for accepted
+ * connection request
+ * @params: Connection parameters provided by ULP for accepting connection
+ *
+ * Transition QP to RTS state, associate new CM id @id with accepted CEP
+ * and get prepared for TCP input by installing socket callbacks.
+ * Then send MPA Reply and generate the "connection established" event.
+ * Socket callbacks must be installed before sending MPA Reply, because
+ * the latter may cause a first RDMA message to arrive from the RDMA Initiator
+ * side very quickly, at which time the socket callbacks must be ready.
+ */
+int siw_accept(struct iw_cm_id *id, struct iw_cm_conn_param *params)
+{
+ struct siw_dev *dev = siw_dev_ofa2siw(id->device);
+ struct siw_cep *cep = (struct siw_cep *)id->provider_data;
+ struct siw_qp *qp;
+ struct siw_qp_attrs qp_attrs;
+ char *pdata = NULL;
+ int rv;
+
+ siw_cep_set_inuse(cep);
+ siw_cep_put(cep);
+
+ if (cep->state != SIW_EPSTATE_RECVD_MPAREQ) {
+ if (cep->state == SIW_EPSTATE_CLOSED) {
+
+ dprint(DBG_CM, "(id=0x%p): Out of State\n", id);
+
+ siw_cep_set_free(cep);
+ siw_cep_put(cep);
+
+ return -ECONNRESET;
+ }
+ BUG();
+ }
+
+ qp = siw_qp_id2obj(dev, params->qpn);
+ BUG_ON(!qp); /* The OFA core should prevent this */
+
+ down_write(&qp->state_lock);
+ if (qp->attrs.state > SIW_QP_STATE_RTR) {
+ rv = -EINVAL;
+ up_write(&qp->state_lock);
+ goto error;
+ }
+
+ dprint(DBG_CM, "(id=0x%p, QP%d): dev(id)=%s\n",
+ id, QP_ID(qp), dev->ofa_dev.name);
+
+ if (params->ord > dev->attrs.max_ord ||
+ params->ird > dev->attrs.max_ord) {
+ dprint(DBG_CM|DBG_ON, "(id=0x%p, QP%d): "
+ "ORD: %d (max: %d), IRD: %d (max: %d)\n",
+ id, QP_ID(qp),
+ params->ord, qp->attrs.ord,
+ params->ird, qp->attrs.ird);
+ rv = -EINVAL;
+ up_write(&qp->state_lock);
+ goto error;
+ }
+ if (params->private_data_len > MPA_MAX_PRIVDATA) {
+ dprint(DBG_CM|DBG_ON, "(id=0x%p, QP%d): "
+ "Private data too long: %d (max: %d)\n",
+ id, QP_ID(qp),
+ params->private_data_len, MPA_MAX_PRIVDATA);
+ rv = -EINVAL;
+ up_write(&qp->state_lock);
+ goto error;
+ }
+ cep->cm_id = id;
+ id->add_ref(id);
+
+ memset(&qp_attrs, 0, sizeof qp_attrs);
+ qp_attrs.ord = params->ord;
+ qp_attrs.ird = params->ird;
+ qp_attrs.llp_stream_handle = cep->llp.sock;
+
+ /*
+ * Currently no MPA markers support. Consider adding marker TX path.
+ */
+ qp_attrs.mpa.marker_rcv = 0;
+ qp_attrs.mpa.marker_snd = 0;
+ qp_attrs.mpa.crc = cep->mpa.hdr.params.c;
+ qp_attrs.state = SIW_QP_STATE_RTS;
+
+ dprint(DBG_CM, "(id=0x%p, QP%d): Moving to RTS\n", id, QP_ID(qp));
+
+ /* Associate QP with CEP */
+ siw_cep_get(cep);
+ qp->cep = cep;
+
+ /* siw_qp_get(qp) already done by QP lookup */
+ cep->qp = qp;
+
+ cep->state = SIW_EPSTATE_RDMA_MODE;
+
+ /* Move socket RX/TX under QP control */
+ rv = siw_qp_modify(qp, &qp_attrs, SIW_QP_ATTR_STATE|
+ SIW_QP_ATTR_LLP_HANDLE|
+ SIW_QP_ATTR_ORD|
+ SIW_QP_ATTR_IRD|
+ SIW_QP_ATTR_MPA);
+ up_write(&qp->state_lock);
+
+ if (rv)
+ goto error;
+
+ if (params->private_data_len) {
+ pdata = (char *)params->private_data;
+
+ dprint(DBG_CM, "(id=0x%p, QP%d): %d bytes private_data\n",
+ id, QP_ID(qp), params->private_data_len);
+ }
+ cep->mpa.hdr.params.pd_len = params->private_data_len;
+
+ dprint(DBG_CM, "(id=0x%p, QP%d): Sending MPA Reply\n", id, QP_ID(qp));
+
+ rv = siw_send_mpareqrep(cep->llp.sock, &cep->mpa.hdr.params,
+ MPA_KEY_REP, pdata);
+
+ if (!rv) {
+ rv = siw_cm_upcall(cep, IW_CM_EVENT_ESTABLISHED, 0);
+ if (rv)
+ goto error;
+
+ siw_cep_set_free(cep);
+
+ dprint(DBG_CM, "(id=0x%p, QP%d): Exit\n", id, QP_ID(qp));
+ return 0;
+ }
+
+error:
+ siw_socket_disassoc(cep->llp.sock);
+ sock_release(cep->llp.sock);
+ cep->llp.sock = NULL;
+
+ cep->state = SIW_EPSTATE_CLOSED;
+
+ if (cep->cm_id) {
+ cep->cm_id->rem_ref(id);
+ cep->cm_id = NULL;
+ }
+ if (qp->cep) {
+ siw_cep_put(cep);
+ qp->cep = NULL;
+ }
+ cep->qp = NULL;
+ siw_qp_put(qp);
+
+ siw_cep_set_free(cep);
+ siw_cep_put(cep);
+
+ return rv;
+}
+
+/*
+ * siw_reject()
+ *
+ * Local connection reject case. Send private data back to peer,
+ * close connection and dereference connection id.
+ */
+int siw_reject(struct iw_cm_id *id, const void *pdata, u8 plen)
+{
+ struct siw_cep *cep = (struct siw_cep *)id->provider_data;
+
+ siw_cep_set_inuse(cep);
+ siw_cep_put(cep);
+
+ if (cep->state != SIW_EPSTATE_RECVD_MPAREQ) {
+ if (cep->state == SIW_EPSTATE_CLOSED) {
+
+ dprint(DBG_CM, "(id=0x%p): Out of State\n", id);
+
+ siw_cep_set_free(cep);
+ siw_cep_put(cep); /* should be last reference */
+
+ return -ECONNRESET;
+ }
+ BUG();
+ }
+ dprint(DBG_CM, "(id=0x%p): cep->state=%d\n", id, cep->state);
+ dprint(DBG_CM, " Reject: %d: %x\n", plen, plen ? *(char *)pdata : 0);
+
+ if (cep->mpa.hdr.params.rev == MPA_REVISION_1) {
+ cep->mpa.hdr.params.r = 1; /* reject */
+ cep->mpa.hdr.params.pd_len = plen;
+ (void)siw_send_mpareqrep(cep->llp.sock, &cep->mpa.hdr.params,
+ MPA_KEY_REP, pdata);
+ }
+ siw_socket_disassoc(cep->llp.sock);
+ sock_release(cep->llp.sock);
+ cep->llp.sock = NULL;
+
+ cep->state = SIW_EPSTATE_CLOSED;
+
+ siw_cep_set_free(cep);
+ siw_cep_put(cep);
+
+ return 0;
+}
+
+static int siw_listen_address(struct iw_cm_id *id, int backlog,
+ struct sockaddr *laddr)
+{
+ struct socket *s;
+ struct siw_cep *cep = NULL;
+ int rv = 0, s_val;
+
+ rv = sock_create(AF_INET, SOCK_STREAM, IPPROTO_TCP, &s);
+ if (rv < 0) {
+ dprint(DBG_CM|DBG_ON, "(id=0x%p): ERROR: "
+ "sock_create(): rv=%d\n", id, rv);
+ return rv;
+ }
+
+ s_val = SOCKBUFSIZE;
+ rv = kernel_setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *)&s_val,
+ sizeof s_val);
+ if (rv)
+ goto error;
+
+ rv = kernel_setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&s_val,
+ sizeof s_val);
+ if (rv)
+ goto error;
+
+ /*
+ * Probably to be removed later. Allows binding
+ * local port when still in TIME_WAIT from last close.
+ */
+ s_val = 1;
+ rv = kernel_setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&s_val,
+ sizeof s_val);
+ if (rv != 0) {
+ dprint(DBG_CM|DBG_ON, "(id=0x%p): ERROR: "
+ "kernel_setsockopt(): rv=%d\n", id, rv);
+ goto error;
+ }
+
+ rv = s->ops->bind(s, laddr, sizeof *laddr);
+ if (rv != 0) {
+ dprint(DBG_CM|DBG_ON, "(id=0x%p): ERROR: bind(): rv=%d\n",
+ id, rv);
+ goto error;
+ }
+
+ cep = siw_cep_alloc(siw_dev_ofa2siw(id->device));
+ if (!cep) {
+ rv = -ENOMEM;
+ goto error;
+ }
+ siw_cep_socket_assoc(cep, s);
+
+ rv = siw_cm_alloc_work(cep, backlog);
+ if (rv != 0) {
+ dprint(DBG_CM|DBG_ON, "(id=0x%p): ERROR: "
+ "siw_cm_alloc_work(backlog=%d): rv=%d\n",
+ id, backlog, rv);
+ goto error;
+ }
+
+ rv = s->ops->listen(s, backlog);
+ if (rv != 0) {
+ dprint(DBG_CM|DBG_ON, "(id=0x%p): ERROR: listen() rv=%d\n",
+ id, rv);
+ goto error;
+ }
+
+ /*
+ * TODO: Do we really need the copies of local_addr and remote_addr
+ * in CEP ???
+ */
+ memcpy(&cep->llp.laddr, &id->local_addr, sizeof cep->llp.laddr);
+ memcpy(&cep->llp.raddr, &id->remote_addr, sizeof cep->llp.raddr);
+
+ cep->cm_id = id;
+ id->add_ref(id);
+
+ /*
+ * In case of a wildcard rdma_listen on a multi-homed device,
+ * a listener's IWCM id is associated with more than one listening CEP.
+ *
+ * We currently use id->provider_data in three different ways:
+ *
+ * o For a listener's IWCM id, id->provider_data points to
+ * the list_head of the list of listening CEPs.
+ * Uses: siw_create_listen(), siw_destroy_listen()
+ *
+ * o For a passive-side IWCM id, id->provider_data points to
+ * the CEP itself. This is a consequence of
+ * - siw_cm_upcall() setting event.provider_data = cep and
+ * - the IWCM's cm_conn_req_handler() setting provider_data of the
+ * new passive-side IWCM id equal to event.provider_data
+ * Uses: siw_accept(), siw_reject()
+ *
+ * o For an active-side IWCM id, id->provider_data is not used at all.
+ *
+ */
+ if (!id->provider_data) {
+ id->provider_data = kmalloc(sizeof(struct list_head),
+ GFP_KERNEL);
+ if (!id->provider_data) {
+ rv = -ENOMEM;
+ goto error;
+ }
+ INIT_LIST_HEAD((struct list_head *)id->provider_data);
+ }
+
+ dprint(DBG_CM, "(id=0x%p): dev(id)=%s, l2dev=%s, "
+ "id->provider_data=0x%p, cep=0x%p\n",
+ id, id->device->name,
+ siw_dev_ofa2siw(id->device)->l2dev->name,
+ id->provider_data, cep);
+
+ list_add_tail(&cep->listenq, (struct list_head *)id->provider_data);
+ cep->state = SIW_EPSTATE_LISTENING;
+ return 0;
+
+error:
+ dprint(DBG_CM, " Failed: %d\n", rv);
+
+ if (cep) {
+ if (cep->cm_id) {
+ cep->cm_id->rem_ref(cep->cm_id);
+ cep->cm_id = NULL;
+ }
+ cep->llp.sock = NULL;
+ siw_socket_disassoc(s);
+ cep->state = SIW_EPSTATE_CLOSED;
+ siw_cep_put(cep);
+ }
+ sock_release(s);
+ return rv;
+}
+
+static void siw_drop_listeners(struct iw_cm_id *id)
+{
+ struct list_head *p, *tmp;
+ /*
+ * In case of a wildcard rdma_listen on a multi-homed device,
+ * a listener's IWCM id is associated with more than one listening CEP.
+ */
+ list_for_each_safe(p, tmp, (struct list_head *)id->provider_data) {
+
+ struct siw_cep *cep = list_entry(p, struct siw_cep, listenq);
+ list_del(p);
+
+ dprint(DBG_CM, "(id=0x%p): drop CEP 0x%p, state %d\n",
+ id, cep, cep->state);
+ siw_cep_set_inuse(cep);
+
+ if (cep->cm_id) {
+ cep->cm_id->rem_ref(cep->cm_id);
+ cep->cm_id = NULL;
+ }
+ if (cep->llp.sock) {
+ siw_socket_disassoc(cep->llp.sock);
+ sock_release(cep->llp.sock);
+ cep->llp.sock = NULL;
+ }
+ cep->state = SIW_EPSTATE_CLOSED;
+ siw_cep_set_free(cep);
+ siw_cep_put(cep);
+ }
+}
+
+/*
+ * siw_create_listen - Create resources for a listener's IWCM ID @id
+ *
+ * Listens on the socket addresses id->local_addr and id->remote_addr.
+ * We support listening on multi-homed devices, i.e., Softiwarp devices
+ * whose underlying net_device is associated with multiple IP addresses.
+ * Wildcard listening (listening with zero IP address) is also supported.
+ *
+ * There are three design options for Softiwarp device management supporting
+ * - multiple physical Ethernet ports, i.e., multiple net_device instances, and
+ * - multiple IP addresses associated with net_device,
+ * as follows:
+ *
+ * Option 1: One Softiwarp device per net_device and
+ * IP address associated with the net_device
+ * Option 2: One Softiwarp device per net_device
+ * (and all IP addresses associated with the net_device)
+ * Option 3: Single Softiwarp device for all net_device instances
+ * (and all IP addresses associated with these instances)
+ *
+ * We currently use Option 2, registering a separate siw_dev for
+ * each net_device. Consequently, siw_create_listen() (called separately
+ * by the IWCM for each Softiwarp device) handles the associated IP address(es)
+ * as follows:
+ *
+ * - If the listener's @id provides a specific local IP address, at most one
+ * listening socket is created and associated with @id.
+ *
+ * - If the listener's @id provides the wildcard (zero) local IP address,
+ * a separate listen is performed for each local IP address of the device
+ * by creating a listening socket and binding to that local IP address.
+ * This avoids attempts to bind to the wildcard (zero) IP address
+ * on multiple devices, which fails with -EADDRINUSE on the second and
+ * all subsequent devices.
+ *
+ * For the given IWCM and Option 2 above, the alternative approach of doing
+ * a single wildcard listen by creating one listening socket and binding it
+ * to the wildcard IP address is not a good idea if
+ * - there is more than one Softiwarp device (e.g., for lo and eth0), or
+ * - there are non-Softiwarp iWARP devices that cannot cooperate.
+ */
+int siw_create_listen(struct iw_cm_id *id, int backlog)
+{
+ struct ib_device *ofa_dev = id->device;
+ struct siw_dev *dev = siw_dev_ofa2siw(ofa_dev);
+ int rv = 0;
+
+ dprint(DBG_CM, "(id=0x%p): dev(id)=%s, l2dev=%s backlog=%d\n",
+ id, ofa_dev->name, dev->l2dev->name, backlog);
+
+ /*
+ * IPv4/v6 design differences regarding multi-homing
+ * propagate up to iWARP:
+ * o For IPv4, use dev->l2dev->ip_ptr
+ * o For IPv6, use dev->l2dev->ipv6_ptr
+ */
+ if (id->local_addr.sin_family == AF_INET) {
+ /* IPv4 */
+ struct sockaddr_in laddr = id->local_addr;
+ u8 *l_ip, *r_ip;
+ struct in_device *in_dev;
+
+ l_ip = (u8 *) &id->local_addr.sin_addr.s_addr;
+ r_ip = (u8 *) &id->remote_addr.sin_addr.s_addr;
+ dprint(DBG_CM, "(id=0x%p): "
+ "laddr(id) : ipv4=%d.%d.%d.%d, port=%d; "
+ "raddr(id) : ipv4=%d.%d.%d.%d, port=%d\n",
+ id,
+ l_ip[0], l_ip[1], l_ip[2], l_ip[3],
+ ntohs(id->local_addr.sin_port),
+ r_ip[0], r_ip[1], r_ip[2], r_ip[3],
+ ntohs(id->remote_addr.sin_port));
+
+ in_dev = in_dev_get(dev->l2dev);
+ if (!in_dev) {
+ dprint(DBG_CM|DBG_ON, "(id=0x%p): "
+ "l2dev has no in_device\n", id);
+ return -ENODEV;
+ }
+
+ /*
+ * If in_dev is not configured, in_dev->ifa_list may be empty
+ */
+ for_ifa(in_dev) {
+ /*
+ * Create a listening socket if id->local_addr
+ * contains the wildcard IP address OR
+ * the IP address of the interface.
+ */
+ if (ipv4_is_zeronet(id->local_addr.sin_addr.s_addr) ||
+ id->local_addr.sin_addr.s_addr ==
+ ifa->ifa_address) {
+ laddr.sin_addr.s_addr = ifa->ifa_address;
+
+ l_ip = (u8 *) &laddr.sin_addr.s_addr;
+ dprint(DBG_CM, "(id=0x%p): "
+ "laddr(bind): ipv4=%d.%d.%d.%d,"
+ " port=%d\n", id,
+ l_ip[0], l_ip[1], l_ip[2],
+ l_ip[3], ntohs(laddr.sin_port));
+
+ rv = siw_listen_address(id, backlog,
+ (struct sockaddr *)&laddr);
+ if (rv)
+ break;
+ }
+ }
+ endfor_ifa(in_dev);
+ in_dev_put(in_dev);
+
+ if (rv && id->provider_data)
+ siw_drop_listeners(id);
+
+ } else {
+ /* IPv6 */
+ dprint(DBG_CM|DBG_ON, "(id=0x%p): TODO: IPv6 support\n", id);
+ }
+ if (!rv)
+ dprint(DBG_CM, "(id=0x%p): Success\n", id);
+
+ return rv;
+}
+
+
+int siw_destroy_listen(struct iw_cm_id *id)
+{
+
+ dprint(DBG_CM, "(id=0x%p): dev(id)=%s, l2dev=%s\n",
+ id, id->device->name,
+ siw_dev_ofa2siw(id->device)->l2dev->name);
+
+ if (!id->provider_data) {
+ /*
+ * TODO: See if there's a way to avoid getting any
+ * listener ids without a list of CEPs
+ */
+ dprint(DBG_CM, "(id=0x%p): Listener id: no CEP(s)\n", id);
+ return 0;
+ }
+ siw_drop_listeners(id);
+ kfree(id->provider_data);
+ id->provider_data = NULL;
+
+ return 0;
+}
+
+int __init siw_cm_init(void)
+{
+ /*
+ * create_single_workqueue for strict ordering
+ */
+ siw_cm_wq = create_singlethread_workqueue("siw_cm_wq");
+ if (!siw_cm_wq)
+ return -ENOMEM;
+
+ return 0;
+}
+
+void __exit siw_cm_exit(void)
+{
+ if (siw_cm_wq) {
+ flush_workqueue(siw_cm_wq);
+ destroy_workqueue(siw_cm_wq);
+ }
+}
diff --git a/drivers/infiniband/hw/siw/siw_cm.h b/drivers/infiniband/hw/siw/siw_cm.h
new file mode 100644
index 0000000..067172d
--- /dev/null
+++ b/drivers/infiniband/hw/siw/siw_cm.h
@@ -0,0 +1,159 @@
+/*
+ * Software iWARP device driver for Linux
+ *
+ * Authors: Bernard Metzler <bmt@zurich.ibm.com>
+ *
+ * Copyright (c) 2008-2011, IBM Corporation
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of IBM nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef _SIW_CM_H
+#define _SIW_CM_H
+
+#include <net/sock.h>
+#include <linux/tcp.h>
+
+#include <rdma/iw_cm.h>
+
+
+enum siw_cep_state {
+ SIW_EPSTATE_IDLE = 1,
+ SIW_EPSTATE_LISTENING,
+ SIW_EPSTATE_CONNECTING,
+ SIW_EPSTATE_AWAIT_MPAREQ,
+ SIW_EPSTATE_RECVD_MPAREQ,
+ SIW_EPSTATE_AWAIT_MPAREP,
+ SIW_EPSTATE_RDMA_MODE,
+ SIW_EPSTATE_CLOSED
+};
+
+struct siw_mpa_info {
+ struct mpa_rr hdr; /* peer mpa hdr in host byte order */
+ char *pdata;
+ int bytes_rcvd;
+};
+
+struct siw_llp_info {
+ struct socket *sock;
+ struct sockaddr_in laddr; /* redundant with socket info above */
+ struct sockaddr_in raddr; /* dito, consider removal */
+ struct siw_sk_upcalls sk_def_upcalls;
+};
+
+struct siw_dev;
+
+struct siw_cep {
+ struct iw_cm_id *cm_id;
+ struct siw_dev *dev;
+
+ struct list_head devq;
+ /*
+ * The provider_data element of a listener IWCM ID
+ * refers to a list of one or more listener CEPs
+ */
+ struct list_head listenq;
+ struct siw_cep *listen_cep;
+ struct siw_qp *qp;
+ spinlock_t lock;
+ wait_queue_head_t waitq;
+ struct kref ref;
+ enum siw_cep_state state;
+ short in_use;
+ struct siw_cm_work *mpa_timer;
+ struct list_head work_freelist;
+ struct siw_llp_info llp;
+ struct siw_mpa_info mpa;
+ int ord;
+ int ird;
+ int sk_error; /* not (yet) used XXX */
+
+ /* Saved upcalls of socket llp.sock */
+ void (*sk_state_change)(struct sock *sk);
+ void (*sk_data_ready)(struct sock *sk, int bytes);
+ void (*sk_write_space)(struct sock *sk);
+ void (*sk_error_report)(struct sock *sk);
+};
+
+#define MPAREQ_TIMEOUT (HZ*10)
+#define MPAREP_TIMEOUT (HZ*5)
+
+enum siw_work_type {
+ SIW_CM_WORK_ACCEPT = 1,
+ SIW_CM_WORK_READ_MPAHDR,
+ SIW_CM_WORK_CLOSE_LLP, /* close socket */
+ SIW_CM_WORK_PEER_CLOSE, /* socket indicated peer close */
+ SIW_CM_WORK_MPATIMEOUT
+};
+
+struct siw_cm_work {
+ struct delayed_work work;
+ struct list_head list;
+ enum siw_work_type type;
+ struct siw_cep *cep;
+};
+
+extern int siw_connect(struct iw_cm_id *, struct iw_cm_conn_param *);
+extern int siw_accept(struct iw_cm_id *, struct iw_cm_conn_param *);
+extern int siw_reject(struct iw_cm_id *, const void *, u8);
+extern int siw_create_listen(struct iw_cm_id *, int);
+extern int siw_destroy_listen(struct iw_cm_id *);
+
+extern void siw_cep_get(struct siw_cep *);
+extern void siw_cep_put(struct siw_cep *);
+extern int siw_cm_queue_work(struct siw_cep *, enum siw_work_type);
+
+extern int siw_cm_init(void);
+extern void siw_cm_exit(void);
+
+/*
+ * TCP socket interface
+ */
+#define sk_to_qp(sk) (((struct siw_cep *)((sk)->sk_user_data))->qp)
+#define sk_to_cep(sk) ((struct siw_cep *)((sk)->sk_user_data))
+
+/*
+ * Should we use tcp_current_mss()?
+ * But its not exported by kernel.
+ */
+static inline unsigned int get_tcp_mss(struct sock *sk)
+{
+ struct tcp_sock *tp = tcp_sk(sk);
+
+
+ if (tp->xmit_size_goal_segs)
+ return tp->xmit_size_goal_segs * tp->mss_cache;
+
+ else
+ return tp->mss_cache;
+}
+
+#endif
--
1.5.4.3
^ permalink raw reply related
* [PATCH 08/14] SIWv2: Queue pair: siw_qp.c
From: Bernard Metzler @ 2011-06-16 12:42 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA, Bernard Metzler
---
drivers/infiniband/hw/siw/siw_qp.c | 1015 ++++++++++++++++++++++++++++++++++++
1 files changed, 1015 insertions(+), 0 deletions(-)
create mode 100644 drivers/infiniband/hw/siw/siw_qp.c
diff --git a/drivers/infiniband/hw/siw/siw_qp.c b/drivers/infiniband/hw/siw/siw_qp.c
new file mode 100644
index 0000000..2ce2107
--- /dev/null
+++ b/drivers/infiniband/hw/siw/siw_qp.c
@@ -0,0 +1,1015 @@
+/*
+ * Software iWARP device driver for Linux
+ *
+ * Authors: Bernard Metzler <bmt-OA+xvbQnYDHMbYB6QlFGEg@public.gmane.org>
+ * Fredy Neeser <nfd-OA+xvbQnYDHMbYB6QlFGEg@public.gmane.org>
+ *
+ * Copyright (c) 2008-2011, IBM Corporation
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of IBM nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/net.h>
+#include <linux/file.h>
+#include <linux/scatterlist.h>
+#include <linux/highmem.h>
+#include <net/sock.h>
+#include <net/tcp_states.h>
+#include <net/tcp.h>
+
+#include <rdma/iw_cm.h>
+#include <rdma/ib_verbs.h>
+#include <rdma/ib_smi.h>
+#include <rdma/ib_user_verbs.h>
+#include <rdma/ib_umem.h>
+
+#include "siw.h"
+#include "siw_obj.h"
+#include "siw_cm.h"
+
+
+#if DPRINT_MASK > 0
+static char siw_qp_state_to_string[SIW_QP_STATE_COUNT][sizeof "TERMINATE"] = {
+ [SIW_QP_STATE_IDLE] = "IDLE",
+ [SIW_QP_STATE_RTR] = "RTR",
+ [SIW_QP_STATE_RTS] = "RTS",
+ [SIW_QP_STATE_CLOSING] = "CLOSING",
+ [SIW_QP_STATE_TERMINATE] = "TERMINATE",
+ [SIW_QP_STATE_ERROR] = "ERROR",
+ [SIW_QP_STATE_MORIBUND] = "MORIBUND",
+ [SIW_QP_STATE_UNDEF] = "UNDEF"
+};
+#endif
+
+/*
+ * iWARP (RDMAP, DDP and MPA) parameters as well as Softiwarp settings on a
+ * per-RDMAP message basis. Please keep order of initializer. All MPA len
+ * is initialized to minimum packet size.
+ */
+struct iwarp_msg_info iwarp_pktinfo[RDMAP_TERMINATE + 1] = { {
+ .hdr_len = sizeof(struct iwarp_rdma_write),
+ .ctrl.mpa_len = htons(sizeof(struct iwarp_rdma_write) - 2),
+ .ctrl.dv = DDP_VERSION,
+ .ctrl.opcode = RDMAP_RDMA_WRITE,
+ .ctrl.rv = RDMAP_VERSION,
+ .ctrl.t = 1,
+ .ctrl.l = 1,
+ .proc_data = siw_proc_write
+},
+{
+ .hdr_len = sizeof(struct iwarp_rdma_rreq),
+ .ctrl.mpa_len = htons(sizeof(struct iwarp_rdma_rreq) - 2),
+ .ctrl.dv = DDP_VERSION,
+ .ctrl.opcode = RDMAP_RDMA_READ_REQ,
+ .ctrl.rv = RDMAP_VERSION,
+ .ctrl.t = 0,
+ .ctrl.l = 1,
+ .proc_data = siw_proc_rreq
+},
+{
+ .hdr_len = sizeof(struct iwarp_rdma_rresp),
+ .ctrl.mpa_len = htons(sizeof(struct iwarp_rdma_rresp) - 2),
+ .ctrl.dv = DDP_VERSION,
+ .ctrl.opcode = RDMAP_RDMA_READ_RESP,
+ .ctrl.rv = RDMAP_VERSION,
+ .ctrl.t = 1,
+ .ctrl.l = 1,
+ .proc_data = siw_proc_rresp
+},
+{
+ .hdr_len = sizeof(struct iwarp_send),
+ .ctrl.mpa_len = htons(sizeof(struct iwarp_send) - 2),
+ .ctrl.dv = DDP_VERSION,
+ .ctrl.opcode = RDMAP_SEND,
+ .ctrl.rv = RDMAP_VERSION,
+ .ctrl.t = 0,
+ .ctrl.l = 1,
+ .proc_data = siw_proc_send
+},
+{
+ .hdr_len = sizeof(struct iwarp_send_inv),
+ .ctrl.mpa_len = htons(sizeof(struct iwarp_send_inv) - 2),
+ .ctrl.dv = DDP_VERSION,
+ .ctrl.opcode = RDMAP_SEND_INVAL,
+ .ctrl.rv = RDMAP_VERSION,
+ .ctrl.t = 0,
+ .ctrl.l = 1,
+ .proc_data = siw_proc_unsupp
+},
+{
+ .hdr_len = sizeof(struct iwarp_send),
+ .ctrl.mpa_len = htons(sizeof(struct iwarp_send) - 2),
+ .ctrl.dv = DDP_VERSION,
+ .ctrl.opcode = RDMAP_SEND_SE,
+ .ctrl.rv = RDMAP_VERSION,
+ .ctrl.t = 0,
+ .ctrl.l = 1,
+ .proc_data = siw_proc_send
+},
+{
+ .hdr_len = sizeof(struct iwarp_send_inv),
+ .ctrl.mpa_len = htons(sizeof(struct iwarp_send_inv) - 2),
+ .ctrl.dv = DDP_VERSION,
+ .ctrl.opcode = RDMAP_SEND_SE_INVAL,
+ .ctrl.rv = RDMAP_VERSION,
+ .ctrl.t = 0,
+ .ctrl.l = 1,
+ .proc_data = siw_proc_unsupp
+},
+{
+ .hdr_len = sizeof(struct iwarp_terminate),
+ .ctrl.mpa_len = htons(sizeof(struct iwarp_terminate) - 2),
+ .ctrl.dv = DDP_VERSION,
+ .ctrl.opcode = RDMAP_TERMINATE,
+ .ctrl.rv = RDMAP_VERSION,
+ .ctrl.t = 0,
+ .ctrl.l = 1,
+ .proc_data = siw_proc_terminate
+} };
+
+
+static void siw_qp_llp_data_ready(struct sock *sk, int flags)
+{
+ struct siw_qp *qp;
+
+ read_lock(&sk->sk_callback_lock);
+
+ if (unlikely(!sk->sk_user_data || !sk_to_qp(sk))) {
+ dprint(DBG_ON, " No QP: %p\n", sk->sk_user_data);
+ goto done;
+ }
+ qp = sk_to_qp(sk);
+
+ if (down_read_trylock(&qp->state_lock)) {
+ read_descriptor_t rd_desc = {.arg.data = qp, .count = 1};
+
+ dprint(DBG_SK|DBG_RX, "(QP%d): "
+ "state (before tcp_read_sock)=%d, flags=%x\n",
+ QP_ID(qp), qp->attrs.state, flags);
+
+ if (likely(qp->attrs.state == SIW_QP_STATE_RTS))
+ /*
+ * Implements data receive operation during
+ * socket callback. TCP gracefully catches
+ * the case where there is nothing to receive
+ * (not calling siw_tcp_rx_data() then).
+ */
+ tcp_read_sock(sk, &rd_desc, siw_tcp_rx_data);
+
+ dprint(DBG_SK|DBG_RX, "(QP%d): "
+ "state (after tcp_read_sock)=%d, flags=%x\n",
+ QP_ID(qp), qp->attrs.state, flags);
+
+ up_read(&qp->state_lock);
+ } else {
+ dprint(DBG_SK|DBG_RX, "(QP%d): "
+ "Unable to acquire state_lock\n", QP_ID(qp));
+ }
+done:
+ read_unlock(&sk->sk_callback_lock);
+}
+
+
+void siw_qp_llp_close(struct siw_qp *qp)
+{
+ dprint(DBG_CM, "(QP%d): Enter: SIW QP state = %s, cep=0x%p\n",
+ QP_ID(qp), siw_qp_state_to_string[qp->attrs.state],
+ qp->cep);
+
+ down_write(&qp->state_lock);
+
+ qp->rx_ctx.rx_suspend = 1;
+ qp->tx_ctx.tx_suspend = 1;
+ qp->attrs.llp_stream_handle = NULL;
+
+ switch (qp->attrs.state) {
+
+ case SIW_QP_STATE_RTS:
+ case SIW_QP_STATE_RTR:
+ case SIW_QP_STATE_IDLE:
+ case SIW_QP_STATE_TERMINATE:
+
+ qp->attrs.state = SIW_QP_STATE_ERROR;
+
+ break;
+ /*
+ * SIW_QP_STATE_CLOSING:
+ *
+ * This is a forced close. shall the QP be moved to
+ * ERROR or IDLE ?
+ */
+ case SIW_QP_STATE_CLOSING:
+ if (!TX_IDLE(qp))
+ qp->attrs.state = SIW_QP_STATE_ERROR;
+ else
+ qp->attrs.state = SIW_QP_STATE_IDLE;
+
+ break;
+
+ default:
+ dprint(DBG_CM, " No state transition needed: %d\n",
+ qp->attrs.state);
+ break;
+ }
+ siw_sq_flush(qp);
+ siw_rq_flush(qp);
+
+ up_write(&qp->state_lock);
+
+ dprint(DBG_CM, "(QP%d): Exit: SIW QP state = %s\n",
+ QP_ID(qp), siw_qp_state_to_string[qp->attrs.state]);
+}
+
+
+/*
+ * socket callback routine informing about newly available send space.
+ * Function schedules SQ work for processing SQ items.
+ */
+static void siw_qp_llp_write_space(struct sock *sk)
+{
+ struct siw_qp *qp = sk_to_qp(sk);
+
+ /*
+ * TODO:
+ * Resemble sk_stream_write_space() logic for iWARP constraints:
+ * Clear SOCK_NOSPACE only if sendspace may hold some reasonable
+ * sized FPDU.
+ */
+#ifdef SIW_TX_FULLSEGS
+ struct socket *sock = sk->sk_socket;
+ if (sk_stream_wspace(sk) >= (int)qp->tx_ctx.fpdu_len && sock) {
+ clear_bit(SOCK_NOSPACE, &sock->flags);
+ siw_sq_queue_work(qp);
+ }
+#else
+ sk_stream_write_space(sk);
+
+ if (!test_bit(SOCK_NOSPACE, &sk->sk_socket->flags))
+ siw_sq_queue_work(qp);
+#endif
+}
+
+static void siw_qp_socket_assoc(struct socket *s, struct siw_qp *qp)
+{
+ struct sock *sk = s->sk;
+
+ write_lock_bh(&sk->sk_callback_lock);
+
+ qp->attrs.llp_stream_handle = s;
+ s->sk->sk_data_ready = siw_qp_llp_data_ready;
+ s->sk->sk_write_space = siw_qp_llp_write_space;
+
+ write_unlock_bh(&sk->sk_callback_lock);
+}
+
+
+static int siw_qp_irq_init(struct siw_qp *qp, int size)
+{
+ struct siw_wqe *wqe = NULL;
+ int i = 0;
+
+ dprint(DBG_CM|DBG_WR, "(QP%d): irq size: %d\n", QP_ID(qp), i);
+ if (size <= 0)
+ return 0;
+
+ atomic_set(&qp->irq_space, size);
+
+ while (size--) {
+ wqe = kzalloc(sizeof(struct siw_wqe), GFP_KERNEL);
+ if (!wqe)
+ break;
+
+ INIT_LIST_HEAD(&wqe->list);
+ list_add(&wqe->list, &qp->freeq);
+ i++;
+ SIW_INC_STAT_WQE;
+ }
+ if (!wqe) {
+ dprint(DBG_ON, "(QP%d): Failed\n", QP_ID(qp));
+ while (i--) {
+ wqe = list_first_wqe(&qp->freeq);
+ list_del(&wqe->list);
+ kfree(wqe);
+ SIW_DEC_STAT_WQE;
+ }
+ atomic_set(&qp->irq_space, 0);
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+
+static void siw_send_terminate(struct siw_qp *qp)
+{
+ struct iwarp_terminate pkt;
+
+ memset(&pkt, 0, sizeof pkt);
+ /*
+ * TODO: send TERMINATE
+ */
+ dprint(DBG_CM, "(QP%d): Todo\n", QP_ID(qp));
+}
+
+
+static int siw_qp_enable_crc(struct siw_qp *qp)
+{
+ struct siw_iwarp_rx *c_rx = &qp->rx_ctx;
+ struct siw_iwarp_tx *c_tx = &qp->tx_ctx;
+ int rv = 0;
+
+ c_tx->mpa_crc_hd.tfm = crypto_alloc_hash("crc32c", 0,
+ CRYPTO_ALG_ASYNC);
+ if (IS_ERR(c_tx->mpa_crc_hd.tfm)) {
+ rv = -PTR_ERR(c_tx->mpa_crc_hd.tfm);
+ goto out;
+ }
+ c_rx->mpa_crc_hd.tfm = crypto_alloc_hash("crc32c", 0,
+ CRYPTO_ALG_ASYNC);
+ if (IS_ERR(c_rx->mpa_crc_hd.tfm)) {
+ rv = -PTR_ERR(c_rx->mpa_crc_hd.tfm);
+ crypto_free_hash(c_tx->mpa_crc_hd.tfm);
+ }
+out:
+ if (rv)
+ dprint(DBG_ON, "(QP%d): Failed loading crc32c: error=%d.",
+ QP_ID(qp), rv);
+ else
+ c_tx->crc_enabled = c_rx->crc_enabled = 1;
+
+ return rv;
+}
+
+
+/*
+ * caller holds qp->state_lock
+ */
+int
+siw_qp_modify(struct siw_qp *qp, struct siw_qp_attrs *attrs,
+ enum siw_qp_attr_mask mask)
+{
+ int drop_conn = 0, rv = 0;
+
+ if (!mask)
+ return 0;
+
+ dprint(DBG_CM, "(QP%d)\n", QP_ID(qp));
+
+ if (mask != SIW_QP_ATTR_STATE) {
+ /*
+ * changes of qp attributes (maybe state, too)
+ */
+ if (mask & SIW_QP_ATTR_ACCESS_FLAGS) {
+
+ if (attrs->flags & SIW_RDMA_BIND_ENABLED)
+ qp->attrs.flags |= SIW_RDMA_BIND_ENABLED;
+ else
+ qp->attrs.flags &= ~SIW_RDMA_BIND_ENABLED;
+
+ if (attrs->flags & SIW_RDMA_WRITE_ENABLED)
+ qp->attrs.flags |= SIW_RDMA_WRITE_ENABLED;
+ else
+ qp->attrs.flags &= ~SIW_RDMA_WRITE_ENABLED;
+
+ if (attrs->flags & SIW_RDMA_READ_ENABLED)
+ qp->attrs.flags |= SIW_RDMA_READ_ENABLED;
+ else
+ qp->attrs.flags &= ~SIW_RDMA_WRITE_ENABLED;
+
+ }
+ /*
+ * TODO: what else ??
+ */
+ }
+ if (!(mask & SIW_QP_ATTR_STATE))
+ return 0;
+
+ dprint(DBG_CM, "(QP%d): SIW QP state: %s => %s\n", QP_ID(qp),
+ siw_qp_state_to_string[qp->attrs.state],
+ siw_qp_state_to_string[attrs->state]);
+
+
+ switch (qp->attrs.state) {
+
+ case SIW_QP_STATE_IDLE:
+ case SIW_QP_STATE_RTR:
+
+ switch (attrs->state) {
+
+ case SIW_QP_STATE_RTS:
+
+ if (attrs->mpa.crc) {
+ rv = siw_qp_enable_crc(qp);
+ if (rv)
+ break;
+ }
+ if (!(mask & SIW_QP_ATTR_LLP_HANDLE)) {
+ dprint(DBG_ON, "(QP%d): socket?\n", QP_ID(qp));
+ rv = -EINVAL;
+ break;
+ }
+ if (!(mask & SIW_QP_ATTR_MPA)) {
+ dprint(DBG_ON, "(QP%d): MPA?\n", QP_ID(qp));
+ rv = -EINVAL;
+ break;
+ }
+ dprint(DBG_CM, "(QP%d): Enter RTS: "
+ "peer 0x%08x, local 0x%08x\n", QP_ID(qp),
+ qp->cep->llp.raddr.sin_addr.s_addr,
+ qp->cep->llp.laddr.sin_addr.s_addr);
+ /*
+ * Initialize global iWARP TX state
+ */
+ qp->tx_ctx.ddp_msn[RDMAP_UNTAGGED_QN_SEND] = 0;
+ qp->tx_ctx.ddp_msn[RDMAP_UNTAGGED_QN_RDMA_READ] = 0;
+ qp->tx_ctx.ddp_msn[RDMAP_UNTAGGED_QN_TERMINATE] = 0;
+
+ /*
+ * Initialize global iWARP RX state
+ */
+ qp->rx_ctx.ddp_msn[RDMAP_UNTAGGED_QN_SEND] = 1;
+ qp->rx_ctx.ddp_msn[RDMAP_UNTAGGED_QN_RDMA_READ] = 1;
+ qp->rx_ctx.ddp_msn[RDMAP_UNTAGGED_QN_TERMINATE] = 1;
+
+ /*
+ * init IRD freequeue, caller has already checked
+ * limits. Add one extra entry since after sending
+ * the RResponse it may trigger another peer RRequest
+ * before the RResponse goes back to free queue.
+ */
+ ++attrs->ird;
+ rv = siw_qp_irq_init(qp, attrs->ird);
+ if (rv)
+ break;
+
+ atomic_set(&qp->orq_space, attrs->ord);
+
+ qp->attrs.ord = attrs->ord;
+ qp->attrs.ird = attrs->ird;
+ qp->attrs.mpa = attrs->mpa;
+ /*
+ * move socket rx and tx under qp's control
+ */
+ siw_qp_socket_assoc(attrs->llp_stream_handle, qp);
+
+ qp->attrs.state = SIW_QP_STATE_RTS;
+ /*
+ * set initial mss
+ */
+ qp->tx_ctx.tcp_seglen =
+ get_tcp_mss(attrs->llp_stream_handle->sk);
+
+ break;
+
+ case SIW_QP_STATE_ERROR:
+ siw_rq_flush(qp);
+ qp->attrs.state = SIW_QP_STATE_ERROR;
+ if (qp->cep) {
+ siw_cep_put(qp->cep);
+ qp->cep = NULL;
+ }
+ break;
+
+ case SIW_QP_STATE_RTR:
+ /* ignore */
+ break;
+
+ default:
+ dprint(DBG_CM,
+ " QP state transition undefined: %s => %s\n",
+ siw_qp_state_to_string[qp->attrs.state],
+ siw_qp_state_to_string[attrs->state]);
+ break;
+ }
+ break;
+
+ case SIW_QP_STATE_RTS:
+
+ switch (attrs->state) {
+
+ case SIW_QP_STATE_CLOSING:
+ /*
+ * Verbs: move to IDLE if SQ and ORQ are empty.
+ * Move to ERROR otherwise. But first of all we must
+ * close the connection. So we keep CLOSING or ERROR
+ * as a transient state, schedule connection drop work
+ * and wait for the socket state change upcall to
+ * come back closed.
+ */
+ if (TX_IDLE(qp))
+ qp->attrs.state = SIW_QP_STATE_CLOSING;
+ else {
+ qp->attrs.state = SIW_QP_STATE_ERROR;
+ siw_sq_flush(qp);
+ }
+ siw_rq_flush(qp);
+
+ drop_conn = 1;
+ break;
+
+ case SIW_QP_STATE_TERMINATE:
+ qp->attrs.state = SIW_QP_STATE_TERMINATE;
+ siw_send_terminate(qp);
+ drop_conn = 1;
+
+ break;
+
+ case SIW_QP_STATE_ERROR:
+ /*
+ * This is an emergency close.
+ *
+ * Any in progress transmit operation will get
+ * cancelled.
+ * This will likely result in a protocol failure,
+ * if a TX operation is in transit. The caller
+ * could unconditional wait to give the current
+ * operation a chance to complete.
+ * Esp., how to handle the non-empty IRQ case?
+ * The peer was asking for data transfer at a valid
+ * point in time.
+ */
+ siw_sq_flush(qp);
+ siw_rq_flush(qp);
+ qp->attrs.state = SIW_QP_STATE_ERROR;
+ drop_conn = 1;
+
+ break;
+
+ default:
+ dprint(DBG_ON,
+ " QP state transition undefined: %s => %s\n",
+ siw_qp_state_to_string[qp->attrs.state],
+ siw_qp_state_to_string[attrs->state]);
+ break;
+ }
+ break;
+
+ case SIW_QP_STATE_TERMINATE:
+
+ switch (attrs->state) {
+
+ case SIW_QP_STATE_ERROR:
+ siw_rq_flush(qp);
+ qp->attrs.state = SIW_QP_STATE_ERROR;
+
+ if (!TX_IDLE(qp))
+ siw_sq_flush(qp);
+
+ break;
+
+ default:
+ dprint(DBG_ON,
+ " QP state transition undefined: %s => %s\n",
+ siw_qp_state_to_string[qp->attrs.state],
+ siw_qp_state_to_string[attrs->state]);
+ }
+ break;
+
+ case SIW_QP_STATE_CLOSING:
+
+ switch (attrs->state) {
+
+ case SIW_QP_STATE_IDLE:
+ BUG_ON(!TX_IDLE(qp));
+ qp->attrs.state = SIW_QP_STATE_IDLE;
+
+ break;
+
+ case SIW_QP_STATE_CLOSING:
+ /*
+ * The LLP may already moved the QP to closing
+ * due to graceful peer close init
+ */
+ break;
+
+ case SIW_QP_STATE_ERROR:
+ /*
+ * QP was moved to CLOSING by LLP event
+ * not yet seen by user.
+ */
+ qp->attrs.state = SIW_QP_STATE_ERROR;
+
+ if (!TX_IDLE(qp))
+ siw_sq_flush(qp);
+
+ siw_rq_flush(qp);
+
+ break;
+
+ default:
+ dprint(DBG_CM,
+ " QP state transition undefined: %s => %s\n",
+ siw_qp_state_to_string[qp->attrs.state],
+ siw_qp_state_to_string[attrs->state]);
+ return -ECONNABORTED;
+ }
+ break;
+
+ default:
+ dprint(DBG_CM, " NOP: State: %d\n", qp->attrs.state);
+ break;
+ }
+ if (drop_conn)
+ siw_qp_cm_drop(qp, 0);
+
+ return rv;
+}
+
+struct ib_qp *siw_get_ofaqp(struct ib_device *dev, int id)
+{
+ struct siw_qp *qp = siw_qp_id2obj(siw_dev_ofa2siw(dev), id);
+
+ dprint(DBG_OBJ, ": dev_name: %s, OFA QPID: %d, QP: %p\n",
+ dev->name, id, qp);
+ if (qp) {
+ /*
+ * siw_qp_id2obj() increments object reference count
+ */
+ siw_qp_put(qp);
+ dprint(DBG_OBJ, " QPID: %d\n", QP_ID(qp));
+ return &qp->ofa_qp;
+ }
+ return (struct ib_qp *)NULL;
+}
+
+/*
+ * siw_check_mem()
+ *
+ * Check protection domain, STAG state, access permissions and
+ * address range for memory object.
+ *
+ * @pd: Protection Domain memory should belong to
+ * @mem: memory to be checked
+ * @addr: starting addr of mem
+ * @perms: requested access permissions
+ * @len: len of memory interval to be checked
+ *
+ */
+int siw_check_mem(struct siw_pd *pd, struct siw_mem *mem, u64 addr,
+ enum siw_access_flags perms, int len)
+{
+ if (siw_mem2mr(mem)->pd != pd) {
+ dprint(DBG_WR|DBG_ON, "(PD%d): PD mismatch %p : %p\n",
+ OBJ_ID(pd),
+ siw_mem2mr(mem)->pd, pd);
+
+ return -EINVAL;
+ }
+ if (mem->stag_state == STAG_INVALID) {
+ dprint(DBG_WR|DBG_ON, "(PD%d): STAG 0x%08x invalid\n",
+ OBJ_ID(pd), OBJ_ID(mem));
+ return -EPERM;
+ }
+ /*
+ * check access permissions
+ */
+ if ((mem->perms & perms) < perms) {
+ dprint(DBG_WR|DBG_ON, "(PD%d): "
+ "INSUFFICIENT permissions 0x%08x : 0x%08x\n",
+ OBJ_ID(pd), mem->perms, perms);
+ return -EPERM;
+ }
+ /*
+ * Check address interval: we relax check to allow memory shrinked
+ * from the start address _after_ placing or fetching len bytes.
+ * TODO: this relaxation is probably overdone
+ */
+ if (addr < mem->va || addr + len > mem->va + mem->len) {
+ dprint(DBG_WR|DBG_ON, "(PD%d): MEM interval len %d "
+ "[0x%016llx, 0x%016llx) out of bounds "
+ "[0x%016llx, 0x%016llx) for LKey=0x%08x\n",
+ OBJ_ID(pd), len, (unsigned long long)addr,
+ (unsigned long long)(addr + len),
+ (unsigned long long)mem->va,
+ (unsigned long long)(mem->va + mem->len),
+ OBJ_ID(mem));
+
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/*
+ * siw_check_sge()
+ *
+ * Check SGE for access rights in given interval
+ *
+ * @pd: Protection Domain memory should belong to
+ * @sge: SGE to be checked
+ * @perms: requested access permissions
+ * @off: starting offset in SGE
+ * @len: len of memory interval to be checked
+ *
+ * NOTE: Function references each SGE's memory object (sge->mem)
+ * if not yet done. New reference is kept if check went ok and
+ * released if check failed. If sge->mem is already valid, no new
+ * lookup is being done and mem is not released it check fails.
+ */
+int
+siw_check_sge(struct siw_pd *pd, struct siw_sge *sge,
+ enum siw_access_flags perms, u32 off, int len)
+{
+ struct siw_dev *dev = pd->hdr.dev;
+ struct siw_mem *mem;
+ int new_ref = 0, rv = 0;
+
+ if (len + off > sge->len) {
+ rv = -EPERM;
+ goto fail;
+ }
+ if (sge->mem.obj == NULL) {
+ mem = siw_mem_id2obj(dev, sge->lkey >> 8);
+ if (!mem) {
+ rv = -EINVAL;
+ goto fail;
+ }
+ sge->mem.obj = mem;
+ new_ref = 1;
+ } else {
+ mem = sge->mem.obj;
+ new_ref = 0;
+ }
+ rv = siw_check_mem(pd, mem, sge->addr + off, perms, len);
+ if (rv)
+ goto fail;
+
+ return 0;
+
+fail:
+ if (new_ref) {
+ siw_mem_put(mem);
+ sge->mem.obj = NULL;
+ }
+ return rv;
+}
+
+
+/*
+ * siw_check_sgl()
+ *
+ * Check permissions for a list of SGE's (SGL)
+ *
+ * @pd: Protection Domain SGL should belong to
+ * @sge: List of SGE to be checked
+ * @perms: requested access permissions
+ * @off: starting offset in SGL
+ * @len: len of memory interval to be checked
+ *
+ * Function checks only subinterval of SGL described by bytelen @len,
+ * check starts with byte offset @off which must be within
+ * the length of the first SGE.
+ *
+ * The caller is responsible for keeping @len + @off within
+ * the total byte len of the SGL.
+ */
+
+int siw_check_sgl(struct siw_pd *pd, struct siw_sge *sge,
+ enum siw_access_flags perms, u32 off, int len)
+{
+ int rv = 0;
+
+ dprint(DBG_WR, "(PD%d): Enter\n", OBJ_ID(pd));
+
+ BUG_ON(off >= sge->len);
+
+ while (len > 0) {
+ dprint(DBG_WR, "(PD%d): sge=%p, perms=0x%x, "
+ "len=%d, off=%u, sge->len=%d\n",
+ OBJ_ID(pd), sge, perms, len, off, sge->len);
+ /*
+ * rdma verbs: do not check stag for a zero length sge
+ */
+ if (sge->len == 0) {
+ sge++;
+ continue;
+ }
+
+ rv = siw_check_sge(pd, sge, perms, off, sge->len - off);
+ if (rv)
+ break;
+
+ len -= sge->len - off;
+ off = 0;
+ sge++;
+ }
+ return rv;
+}
+
+int siw_crc_array(struct hash_desc *desc, u8 *start, size_t len)
+{
+ struct scatterlist sg;
+
+ sg_init_one(&sg, start, len);
+ return crypto_hash_update(desc, &sg, len);
+}
+
+int siw_crc_sg(struct hash_desc *desc, struct scatterlist *sg,
+ int off, int len)
+{
+ int rv;
+
+ if (off == 0)
+ rv = crypto_hash_update(desc, sg, len);
+ else {
+ struct scatterlist t_sg;
+
+ sg_init_table(&t_sg, 1);
+ sg_set_page(&t_sg, sg_page(sg), len, off);
+ rv = crypto_hash_update(desc, &t_sg, len);
+ }
+ return rv;
+}
+
+
+/*
+ * siw_sq_flush()
+ *
+ * Flush SQ and ORRQ entries to CQ.
+ * IRRQ entries are silently dropped.
+ *
+ * TODO: Add termination code for in-progress WQE.
+ * TODO: an in-progress WQE may have been partially
+ * processed. It should be enforced, that transmission
+ * of a started DDP segment must be completed if possible
+ * by any chance.
+ *
+ * Must be called with qp state write lock held.
+ * Therefore, SQ and ORQ lock must not be taken.
+ */
+void siw_sq_flush(struct siw_qp *qp)
+{
+ struct list_head *pos, *n;
+ struct siw_wqe *wqe = tx_wqe(qp);
+ struct siw_cq *cq = qp->scq;
+ int async_event = 0;
+
+ dprint(DBG_OBJ|DBG_CM|DBG_WR, "(QP%d): Enter\n", QP_ID(qp));
+
+ /*
+ * flush the in-progress wqe, if there.
+ */
+ if (wqe) {
+ /*
+ * TODO: Add iWARP Termination code
+ */
+ tx_wqe(qp) = NULL;
+
+ dprint(DBG_WR,
+ " (QP%d): Flush current WQE %p, type %d\n",
+ QP_ID(qp), wqe, wr_type(wqe));
+
+ if (wr_type(wqe) == SIW_WR_RDMA_READ_RESP) {
+ siw_wqe_put(wqe);
+ wqe = NULL;
+ } else if (wr_type(wqe) != SIW_WR_RDMA_READ_REQ)
+ /*
+ * A RREQUEST is already on the ORRQ
+ */
+ list_add_tail(&wqe->list, &qp->orq);
+ }
+ if (!list_empty(&qp->irq))
+ list_for_each_safe(pos, n, &qp->irq) {
+ wqe = list_entry_wqe(pos);
+ dprint(DBG_WR,
+ " (QP%d): Flush IRQ WQE %p, status %d\n",
+ QP_ID(qp), wqe, wqe->wr_status);
+ list_del(&wqe->list);
+ siw_wqe_put(wqe);
+ }
+
+ if (!list_empty(&qp->orq))
+ list_for_each_safe(pos, n, &qp->orq) {
+ wqe = list_entry_wqe(pos);
+ dprint(DBG_WR,
+ " (QP%d): Flush ORQ WQE %p, type %d,"
+ " status %d\n", QP_ID(qp), wqe, wr_type(wqe),
+ wqe->wr_status);
+ if (wqe->wr_status != SR_WR_DONE) {
+ async_event = 1;
+ wqe->wc_status = IB_WC_WR_FLUSH_ERR;
+ wqe->wr_status = SR_WR_DONE;
+ }
+ if (cq) {
+ lock_cq(cq);
+ list_move_tail(&wqe->list, &cq->queue);
+ /* TODO: enforce CQ limits */
+ atomic_inc(&cq->qlen);
+ unlock_cq(cq);
+ } else {
+ list_del(&wqe->list);
+ siw_wqe_put(wqe);
+ }
+ }
+ if (!list_empty(&qp->sq))
+ async_event = 1;
+ list_for_each_safe(pos, n, &qp->sq) {
+ wqe = list_entry_wqe(pos);
+ dprint(DBG_WR,
+ " (QP%d): Flush SQ WQE %p, type %d\n",
+ QP_ID(qp), wqe, wr_type(wqe));
+ if (cq) {
+ wqe->wc_status = IB_WC_WR_FLUSH_ERR;
+ wqe->wr_status = SR_WR_DONE;
+ lock_cq(cq);
+ list_move_tail(&wqe->list, &cq->queue);
+ /* TODO: enforce CQ limits */
+ atomic_inc(&cq->qlen);
+ unlock_cq(cq);
+ } else {
+ list_del(&wqe->list);
+ siw_wqe_put(wqe);
+ }
+ }
+ atomic_set(&qp->sq_space, qp->attrs.sq_size);
+
+ if (wqe != NULL && cq != NULL && cq->ofa_cq.comp_handler != NULL)
+ (*cq->ofa_cq.comp_handler)(&cq->ofa_cq, cq->ofa_cq.cq_context);
+
+ if (async_event)
+ siw_async_ev(qp, NULL, IB_EVENT_SQ_DRAINED);
+}
+
+/*
+ * siw_rq_flush()
+ *
+ * Flush recv queue entries to cq. An in-progress WQE may have some bytes
+ * processed (wqe->processed).
+ *
+ * Must be called with qp state write lock held.
+ * Therefore, RQ lock must not be taken.
+ */
+void siw_rq_flush(struct siw_qp *qp)
+{
+ struct list_head *pos, *n;
+ struct siw_wqe *wqe;
+ struct siw_cq *cq;
+
+ dprint(DBG_OBJ|DBG_CM|DBG_WR, "(QP%d): Enter\n", QP_ID(qp));
+
+ /*
+ * Flush an in-progess WQE if present
+ */
+ if (rx_wqe(qp)) {
+ if (qp->rx_ctx.hdr.ctrl.opcode != RDMAP_RDMA_WRITE)
+ list_add(&rx_wqe(qp)->list, &qp->rq);
+ else
+ siw_mem_put(rx_mem(qp));
+
+ rx_wqe(qp) = NULL;
+ }
+ if (list_empty(&qp->rq))
+ return;
+
+ cq = qp->rcq;
+
+ list_for_each_safe(pos, n, &qp->rq) {
+ wqe = list_entry_wqe(pos);
+ list_del_init(&wqe->list);
+ if (cq) {
+ wqe->wc_status = IB_WC_WR_FLUSH_ERR;
+ lock_cq(cq);
+ list_add_tail(&wqe->list, &cq->queue);
+ /* TODO: enforce CQ limits */
+ atomic_inc(&cq->qlen);
+ unlock_cq(cq);
+ } else
+ siw_wqe_put(wqe);
+
+ if (!qp->srq)
+ atomic_inc(&qp->rq_space);
+ else
+ atomic_inc(&qp->srq->space);
+
+ }
+ if (cq != NULL && cq->ofa_cq.comp_handler != NULL)
+ (*cq->ofa_cq.comp_handler)(&cq->ofa_cq, cq->ofa_cq.cq_context);
+}
--
1.5.4.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/14] SIWv2: Object management: siw_obj.c, siw_obj.h
From: Bernard Metzler @ 2011-06-16 12:42 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA, Bernard Metzler
---
drivers/infiniband/hw/siw/siw_obj.c | 465 +++++++++++++++++++++++++++++++++++
drivers/infiniband/hw/siw/siw_obj.h | 137 ++++++++++
2 files changed, 602 insertions(+), 0 deletions(-)
create mode 100644 drivers/infiniband/hw/siw/siw_obj.c
create mode 100644 drivers/infiniband/hw/siw/siw_obj.h
diff --git a/drivers/infiniband/hw/siw/siw_obj.c b/drivers/infiniband/hw/siw/siw_obj.c
new file mode 100644
index 0000000..19e78a6
--- /dev/null
+++ b/drivers/infiniband/hw/siw/siw_obj.c
@@ -0,0 +1,465 @@
+/*
+ * Software iWARP device driver for Linux
+ *
+ * Authors: Bernard Metzler <bmt-OA+xvbQnYDHMbYB6QlFGEg@public.gmane.org>
+ *
+ * Copyright (c) 2008-2011, IBM Corporation
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of IBM nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <linux/spinlock.h>
+#include <linux/kref.h>
+
+#include "siw.h"
+#include "siw_obj.h"
+#include "siw_cm.h"
+
+
+void siw_objhdr_init(struct siw_objhdr *hdr)
+{
+ kref_init(&hdr->ref);
+}
+
+void siw_idr_init(struct siw_dev *dev)
+{
+ spin_lock_init(&dev->idr_lock);
+
+ idr_init(&dev->qp_idr);
+ idr_init(&dev->cq_idr);
+ idr_init(&dev->pd_idr);
+ idr_init(&dev->mem_idr);
+}
+
+void siw_idr_release(struct siw_dev *dev)
+{
+ idr_destroy(&dev->qp_idr);
+ idr_destroy(&dev->cq_idr);
+ idr_destroy(&dev->pd_idr);
+ idr_destroy(&dev->mem_idr);
+}
+
+static inline int siw_add_obj(spinlock_t *lock, struct idr *idr,
+ struct siw_objhdr *obj)
+{
+ u32 pre_id, id;
+ unsigned long flags;
+ int rv;
+
+ get_random_bytes(&pre_id, sizeof pre_id);
+ pre_id &= 0xffff;
+again:
+ do {
+ if (!(idr_pre_get(idr, GFP_KERNEL)))
+ return -ENOMEM;
+
+ spin_lock_irqsave(lock, flags);
+ rv = idr_get_new_above(idr, obj, pre_id, &id);
+ spin_unlock_irqrestore(lock, flags);
+
+ } while (rv == -EAGAIN);
+
+ if (rv == 0) {
+ siw_objhdr_init(obj);
+ obj->id = id;
+ dprint(DBG_OBJ, "(OBJ%d): IDR New Object\n", id);
+ } else if (rv == -ENOSPC && pre_id != 1) {
+ pre_id = 1;
+ goto again;
+ } else {
+ dprint(DBG_OBJ|DBG_ON, "(OBJ??): IDR New Object failed!\n");
+ }
+ return rv;
+}
+
+static inline struct siw_objhdr *siw_get_obj(struct idr *idr, int id)
+{
+ struct siw_objhdr *obj;
+
+ obj = idr_find(idr, id);
+ if (obj)
+ kref_get(&obj->ref);
+
+ return obj;
+}
+
+struct siw_cq *siw_cq_id2obj(struct siw_dev *dev, int id)
+{
+ struct siw_objhdr *obj = siw_get_obj(&dev->cq_idr, id);
+ if (obj)
+ return container_of(obj, struct siw_cq, hdr);
+
+ return NULL;
+}
+
+struct siw_qp *siw_qp_id2obj(struct siw_dev *dev, int id)
+{
+ struct siw_objhdr *obj = siw_get_obj(&dev->qp_idr, id);
+ if (obj)
+ return container_of(obj, struct siw_qp, hdr);
+
+ return NULL;
+}
+
+/*
+ * siw_mem_id2obj()
+ *
+ * resolves memory from stag given by id. might be called from:
+ * o process context before sending out of sgl
+ * o or in softirq when resolving target memory
+ */
+struct siw_mem *siw_mem_id2obj(struct siw_dev *dev, int id)
+{
+ struct siw_objhdr *obj;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->idr_lock, flags);
+ obj = siw_get_obj(&dev->mem_idr, id);
+ spin_unlock_irqrestore(&dev->idr_lock, flags);
+
+ if (obj) {
+ dprint(DBG_MM|DBG_OBJ, "(MEM%d): New refcount: %d\n",
+ obj->id, obj->ref.refcount.counter);
+
+ return container_of(obj, struct siw_mem, hdr);
+ }
+ dprint(DBG_MM|DBG_OBJ|DBG_ON, "(MEM%d): not found!\n", id);
+
+ return NULL;
+}
+
+int siw_qp_add(struct siw_dev *dev, struct siw_qp *qp)
+{
+ int rv = siw_add_obj(&dev->idr_lock, &dev->qp_idr, &qp->hdr);
+ if (!rv) {
+ dprint(DBG_OBJ, "(QP%d): New Object\n", QP_ID(qp));
+ qp->hdr.dev = dev;
+ }
+ return rv;
+}
+
+int siw_cq_add(struct siw_dev *dev, struct siw_cq *cq)
+{
+ int rv = siw_add_obj(&dev->idr_lock, &dev->cq_idr, &cq->hdr);
+ if (!rv) {
+ dprint(DBG_OBJ, "(CQ%d): New Object\n", cq->hdr.id);
+ cq->hdr.dev = dev;
+ }
+ return rv;
+}
+
+int siw_pd_add(struct siw_dev *dev, struct siw_pd *pd)
+{
+ int rv = siw_add_obj(&dev->idr_lock, &dev->pd_idr, &pd->hdr);
+ if (!rv) {
+ dprint(DBG_OBJ, "(PD%d): New Object\n", pd->hdr.id);
+ pd->hdr.dev = dev;
+ }
+ return rv;
+}
+
+/*
+ * Stag lookup is based on its index part only (24 bits)
+ * It is assumed that the idr_get_new_above(,,1,) function will
+ * always return a new id within this range (0x1...0xffffff),
+ * if one is available.
+ * The code avoids special Stag of zero and tries to randomize
+ * STag values.
+ */
+int siw_mem_add(struct siw_dev *dev, struct siw_mem *m)
+{
+ u32 id, pre_id;
+ unsigned long flags;
+ int rv;
+
+ do {
+ get_random_bytes(&pre_id, sizeof pre_id);
+ pre_id &= 0xffff;
+ } while (pre_id == 0);
+again:
+ do {
+ if (!(idr_pre_get(&dev->mem_idr, GFP_KERNEL)))
+ return -ENOMEM;
+
+ spin_lock_irqsave(&dev->idr_lock, flags);
+ rv = idr_get_new_above(&dev->mem_idr, m, pre_id, &id);
+ spin_unlock_irqrestore(&dev->idr_lock, flags);
+
+ } while (rv == -EAGAIN);
+
+ if (rv == -ENOSPC || (rv == 0 && id > SIW_STAG_MAX)) {
+ if (rv == 0) {
+ spin_lock_irqsave(&dev->idr_lock, flags);
+ idr_remove(&dev->mem_idr, id);
+ spin_unlock_irqrestore(&dev->idr_lock, flags);
+ }
+ if (pre_id == 1) {
+ dprint(DBG_OBJ|DBG_MM|DBG_ON,
+ "(IDR): New Object failed: %d\n", pre_id);
+ return -ENOSPC;
+ }
+ pre_id = 1;
+ goto again;
+ } else if (rv) {
+ dprint(DBG_OBJ|DBG_MM|DBG_ON,
+ "(IDR%d): New Object failed: rv %d\n", id, rv);
+ return rv;
+ }
+ siw_objhdr_init(&m->hdr);
+ m->hdr.id = id;
+ m->hdr.dev = dev;
+ dprint(DBG_OBJ|DBG_MM, "(IDR%d): New Object\n", id);
+
+ return 0;
+}
+
+void siw_remove_obj(spinlock_t *lock, struct idr *idr,
+ struct siw_objhdr *hdr)
+{
+ unsigned long flags;
+
+ dprint(DBG_OBJ, "(OBJ%d): IDR Remove Object\n", hdr->id);
+
+ spin_lock_irqsave(lock, flags);
+ idr_remove(idr, hdr->id);
+ spin_unlock_irqrestore(lock, flags);
+}
+
+
+/********** routines to put objs back and free if no ref left *****/
+
+static void siw_free_cq(struct kref *ref)
+{
+ struct siw_cq *cq =
+ (container_of(container_of(ref, struct siw_objhdr, ref),
+ struct siw_cq, hdr));
+
+ dprint(DBG_OBJ, "(CQ%d): Free Object\n", cq->hdr.id);
+
+ atomic_dec(&cq->hdr.dev->num_cq);
+ kfree(cq);
+}
+
+static void siw_free_qp(struct kref *ref)
+{
+ struct siw_qp *qp =
+ container_of(container_of(ref, struct siw_objhdr, ref),
+ struct siw_qp, hdr);
+ struct siw_dev *dev = qp->hdr.dev;
+ unsigned long flags;
+
+ dprint(DBG_OBJ|DBG_CM, "(QP%d): Free Object\n", QP_ID(qp));
+
+ if (qp->cep)
+ siw_cep_put(qp->cep);
+
+ siw_drain_wq(&qp->freeq);
+
+ siw_remove_obj(&dev->idr_lock, &dev->qp_idr, &qp->hdr);
+
+ spin_lock_irqsave(&dev->idr_lock, flags);
+ list_del(&qp->devq);
+ spin_unlock_irqrestore(&dev->idr_lock, flags);
+
+ atomic_dec(&dev->num_qp);
+ kfree(qp);
+}
+
+static void siw_free_pd(struct kref *ref)
+{
+ struct siw_pd *pd =
+ container_of(container_of(ref, struct siw_objhdr, ref),
+ struct siw_pd, hdr);
+
+ dprint(DBG_OBJ, "(PD%d): Free Object\n", pd->hdr.id);
+
+ atomic_dec(&pd->hdr.dev->num_pd);
+ kfree(pd);
+}
+
+static void siw_free_mem(struct kref *ref)
+{
+ struct siw_mem *m;
+
+ m = container_of(container_of(ref, struct siw_objhdr, ref),
+ struct siw_mem, hdr);
+
+ dprint(DBG_MM|DBG_OBJ, "(MEM%d): Free Object\n", OBJ_ID(m));
+
+ atomic_dec(&m->hdr.dev->num_mem);
+
+ if (SIW_MEM_IS_MW(m)) {
+ struct siw_mw *mw = container_of(m, struct siw_mw, mem);
+ kfree(mw);
+ } else {
+ struct siw_mr *mr = container_of(m, struct siw_mr, mem);
+ dprint(DBG_MM|DBG_OBJ, "(MEM%d): Release UMem\n", OBJ_ID(m));
+ if (mr->umem)
+ ib_umem_release(mr->umem);
+ kfree(mr);
+ }
+}
+
+
+void siw_cq_put(struct siw_cq *cq)
+{
+ dprint(DBG_OBJ, "(CQ%d): Old refcount: %d\n",
+ OBJ_ID(cq), atomic_read(&cq->hdr.ref.refcount));
+ kref_put(&cq->hdr.ref, siw_free_cq);
+}
+
+void siw_qp_put(struct siw_qp *qp)
+{
+ dprint(DBG_OBJ, "(QP%d): Old refcount: %d\n",
+ QP_ID(qp), atomic_read(&qp->hdr.ref.refcount));
+ kref_put(&qp->hdr.ref, siw_free_qp);
+}
+
+void siw_pd_put(struct siw_pd *pd)
+{
+ dprint(DBG_OBJ, "(PD%d): Old refcount: %d\n",
+ OBJ_ID(pd), atomic_read(&pd->hdr.ref.refcount));
+ kref_put(&pd->hdr.ref, siw_free_pd);
+}
+
+void siw_mem_put(struct siw_mem *m)
+{
+ dprint(DBG_MM|DBG_OBJ, "(MEM%d): Old refcount: %d\n",
+ OBJ_ID(m), atomic_read(&m->hdr.ref.refcount));
+ kref_put(&m->hdr.ref, siw_free_mem);
+}
+
+
+/***** routines for WQE handling ***/
+
+inline struct siw_wqe *siw_freeq_wqe_get(struct siw_qp *qp)
+{
+ struct siw_wqe *wqe = NULL;
+ unsigned long flags;
+
+ spin_lock_irqsave(&qp->freeq_lock, flags);
+ if (!list_empty(&qp->freeq)) {
+ wqe = list_first_wqe(&qp->freeq);
+ list_del(&wqe->list);
+ spin_unlock_irqrestore(&qp->freeq_lock, flags);
+ dprint(DBG_OBJ|DBG_WR,
+ "(QP%d): WQE from FreeList p: %p\n",
+ QP_ID(qp), wqe);
+ } else {
+ spin_unlock_irqrestore(&qp->freeq_lock, flags);
+ dprint(DBG_ON|DBG_OBJ|DBG_WR,
+ "(QP%d): FreeList empty!\n", QP_ID(qp));
+ }
+ return wqe;
+}
+
+static inline void siw_free_inline_sgl(struct siw_sge *sge, int num_sge)
+{
+ while (num_sge--) {
+ kfree(sge->mem.buf); /* kfree handles NULL pointers */
+ sge->mem.buf = NULL;
+ sge++;
+ }
+}
+
+static inline void siw_unref_mem_sgl(struct siw_sge *sge, int num_sge)
+{
+ while (num_sge--) {
+ if (sge->mem.obj != NULL)
+ siw_mem_put(sge->mem.obj);
+ sge++;
+ }
+}
+
+void siw_wqe_put(struct siw_wqe *wqe)
+{
+ struct siw_qp *qp = wqe->qp;
+
+ dprint(DBG_OBJ|DBG_WR, " WQE: %llu:, type: %d, p: %p\n",
+ (unsigned long long)wr_id(wqe), wr_type(wqe), wqe);
+
+ switch (wr_type(wqe)) {
+
+ case SIW_WR_SEND:
+ case SIW_WR_RDMA_WRITE:
+ case SIW_WR_RDMA_WRITE_WITH_IMM:
+ case SIW_WR_SEND_WITH_IMM:
+ case SIW_WR_RDMA_READ_REQ:
+ if (likely(!SIW_INLINED_DATA(wqe)))
+ siw_unref_mem_sgl(wqe->wr.sgl.sge,
+ wqe->wr.sgl.num_sge);
+ else
+ siw_free_inline_sgl(wqe->wr.sgl.sge,
+ wqe->wr.sgl.num_sge);
+ if (qp->attrs.flags & SIW_KERNEL_VERBS)
+ siw_add_wqe(wqe, &qp->freeq, &qp->freeq_lock);
+ else {
+ kfree(wqe);
+ SIW_DEC_STAT_WQE;
+ }
+ atomic_inc(&qp->sq_space);
+ break;
+
+ case SIW_WR_RECEIVE:
+ siw_unref_mem_sgl(wqe->wr.sgl.sge, wqe->wr.sgl.num_sge);
+ if (qp->srq) {
+ struct siw_srq *srq = qp->srq;
+ if (srq->kernel_verbs)
+ siw_add_wqe(wqe, &srq->freeq,
+ &srq->freeq_lock);
+ else {
+ kfree(wqe);
+ SIW_DEC_STAT_WQE;
+ }
+ atomic_inc(&srq->space);
+ } else {
+ if (qp->attrs.flags & SIW_KERNEL_VERBS)
+ siw_add_wqe(wqe, &qp->freeq, &qp->freeq_lock);
+ else {
+ kfree(wqe);
+ SIW_DEC_STAT_WQE;
+ }
+ atomic_inc(&qp->rq_space);
+ }
+ break;
+
+ case SIW_WR_RDMA_READ_RESP:
+ siw_unref_mem_sgl(wqe->wr.sgl.sge, 1);
+ wqe->wr.sgl.sge[0].mem.obj = NULL;
+ siw_add_wqe(wqe, &qp->freeq, &qp->freeq_lock);
+ atomic_inc(&qp->irq_space);
+ break;
+
+ default:
+ WARN_ON(1);
+ }
+ siw_qp_put(qp);
+}
diff --git a/drivers/infiniband/hw/siw/siw_obj.h b/drivers/infiniband/hw/siw/siw_obj.h
new file mode 100644
index 0000000..6740be4
--- /dev/null
+++ b/drivers/infiniband/hw/siw/siw_obj.h
@@ -0,0 +1,137 @@
+/*
+ * Software iWARP device driver for Linux
+ *
+ * Authors: Bernard Metzler <bmt-OA+xvbQnYDHMbYB6QlFGEg@public.gmane.org>
+ *
+ * Copyright (c) 2008-2011, IBM Corporation
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of IBM nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef _SIW_OBJ_H
+#define _SIW_OBJ_H
+
+#include <linux/idr.h>
+#include <linux/rwsem.h>
+#include <linux/version.h>
+#include <linux/sched.h>
+#include <linux/semaphore.h>
+
+#include <rdma/ib_verbs.h>
+
+#include "siw_debug.h"
+
+extern atomic_t siw_num_wqe;
+
+#if DPRINT_MASK > 0
+#define SIW_INC_STAT_WQE atomic_inc(&siw_num_wqe)
+#define SIW_DEC_STAT_WQE atomic_dec(&siw_num_wqe)
+#else
+#define SIW_INC_STAT_WQE do { } while (0)
+#define SIW_DEC_STAT_WQE do { } while (0)
+#endif
+
+static inline struct siw_dev *siw_dev_ofa2siw(struct ib_device *ofa_dev)
+{
+ return container_of(ofa_dev, struct siw_dev, ofa_dev);
+}
+
+static inline void siw_cq_get(struct siw_cq *cq)
+{
+ kref_get(&cq->hdr.ref);
+ dprint(DBG_OBJ, "(CQ%d): New refcount: %d\n",
+ OBJ_ID(cq), atomic_read(&cq->hdr.ref.refcount));
+}
+static inline void siw_qp_get(struct siw_qp *qp)
+{
+ kref_get(&qp->hdr.ref);
+ dprint(DBG_OBJ, "(QP%d): New refcount: %d\n",
+ OBJ_ID(qp), atomic_read(&qp->hdr.ref.refcount));
+}
+static inline void siw_pd_get(struct siw_pd *pd)
+{
+ kref_get(&pd->hdr.ref);
+ dprint(DBG_OBJ, "(PD%d): New refcount: %d\n",
+ OBJ_ID(pd), atomic_read(&pd->hdr.ref.refcount));
+}
+static inline void siw_mem_get(struct siw_mem *mem)
+{
+ kref_get(&mem->hdr.ref);
+ dprint(DBG_OBJ|DBG_MM, "(MEM%d): New refcount: %d\n",
+ OBJ_ID(mem), atomic_read(&mem->hdr.ref.refcount));
+}
+
+static inline void siw_add_wqe(struct siw_wqe *wqe, struct list_head *wq,
+ spinlock_t *lock)
+{
+ unsigned long flags;
+
+ INIT_LIST_HEAD(&wqe->list);
+ spin_lock_irqsave(lock, flags);
+ list_add(&wqe->list, wq);
+ spin_unlock_irqrestore(lock, flags);
+}
+
+static inline void siw_drain_wq(struct list_head *wq)
+{
+ while (!list_empty(wq)) {
+ struct siw_wqe *wqe = list_first_wqe(wq);
+ list_del(&wqe->list);
+ kfree(wqe);
+ SIW_DEC_STAT_WQE;
+ }
+}
+
+extern void siw_remove_obj(spinlock_t *lock, struct idr *idr,
+ struct siw_objhdr *hdr);
+
+extern void siw_objhdr_init(struct siw_objhdr *);
+extern void siw_idr_init(struct siw_dev *);
+extern void siw_idr_release(struct siw_dev *);
+
+extern struct siw_cq *siw_cq_id2obj(struct siw_dev *, int);
+extern struct siw_qp *siw_qp_id2obj(struct siw_dev *, int);
+extern struct siw_mem *siw_mem_id2obj(struct siw_dev *, int);
+
+extern int siw_qp_add(struct siw_dev *, struct siw_qp *);
+extern int siw_cq_add(struct siw_dev *, struct siw_cq *);
+extern int siw_pd_add(struct siw_dev *, struct siw_pd *);
+extern int siw_mem_add(struct siw_dev *, struct siw_mem *m);
+
+extern struct siw_wqe *siw_freeq_wqe_get(struct siw_qp *);
+
+extern void siw_cq_put(struct siw_cq *);
+extern void siw_qp_put(struct siw_qp *);
+extern void siw_pd_put(struct siw_pd *);
+extern void siw_mem_put(struct siw_mem *);
+extern void siw_wqe_put(struct siw_wqe *);
+
+#endif
--
1.5.4.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/14] SIWv2: Main header file: siw.h
From: Bernard Metzler @ 2011-06-16 12:41 UTC (permalink / raw)
To: netdev; +Cc: linux-rdma, Bernard Metzler
---
drivers/infiniband/hw/siw/siw.h | 811 +++++++++++++++++++++++++++++++++++++++
1 files changed, 811 insertions(+), 0 deletions(-)
create mode 100644 drivers/infiniband/hw/siw/siw.h
diff --git a/drivers/infiniband/hw/siw/siw.h b/drivers/infiniband/hw/siw/siw.h
new file mode 100644
index 0000000..afb3682
--- /dev/null
+++ b/drivers/infiniband/hw/siw/siw.h
@@ -0,0 +1,811 @@
+/*
+ * Software iWARP device driver for Linux
+ *
+ * Authors: Bernard Metzler <bmt@zurich.ibm.com>
+ *
+ * Copyright (c) 2008-2011, IBM Corporation
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of IBM nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef _SIW_H
+#define _SIW_H
+
+#include <linux/idr.h>
+#include <rdma/ib_verbs.h>
+#include <linux/socket.h>
+#include <linux/skbuff.h>
+#include <linux/in.h>
+#include <linux/fs.h>
+#include <linux/netdevice.h>
+#include <linux/crypto.h>
+#include <linux/resource.h> /* MLOCK_LIMIT */
+
+#include <rdma/ib_umem.h> /* struct ib_umem_chunk */
+
+#include "siw_user.h"
+#include "iwarp.h"
+
+enum siw_if_type {
+ SIW_IF_OFED = 0, /* only via standard ofed syscall if */
+ SIW_IF_MAPPED = 1 /* private qp and cq mapping */
+};
+
+#define DEVICE_ID_SOFTIWARP 0x0815
+#define VERSION_ID_SOFTIWARP 0x0001
+#define SIW_VENDOR_ID 0
+#define SIW_VENDORT_PART_ID 0
+#define SIW_SW_VERSION 1
+#define SIW_MAX_QP (1024 * 100)
+#define SIW_MAX_QP_WR (1024 * 32)
+#define SIW_MAX_ORD 128
+#define SIW_MAX_IRD 128
+#define SIW_MAX_SGE 10
+#define SIW_MAX_SGE_RD 1 /* iwarp limitation. we could relax */
+#define SIW_MAX_CQ (1024 * 100)
+#define SIW_MAX_CQE (SIW_MAX_QP_WR * 100)
+#define SIW_MAX_MR (SIW_MAX_QP * 10)
+#define SIW_MAX_PD SIW_MAX_QP
+#define SIW_MAX_MW 0 /* to be set if MW's are supported */
+#define SIW_MAX_FMR 0
+#define SIW_MAX_SRQ SIW_MAX_QP
+#define SIW_MAX_SRQ_WR (SIW_MAX_QP_WR * 10)
+
+#define SENDPAGE_THRESH 256 /* min bytes for using sendpage() */
+#define SIW_MAX_INLINE SENDPAGE_THRESH
+#define SOCKBUFSIZE (PAGE_SIZE * 40)
+#define SQ_USER_MAXBURST 10
+
+#define SIW_NODE_DESC "Software iWARP stack"
+
+
+struct siw_devinfo {
+ unsigned device;
+ unsigned version;
+
+ /* close match to ib_device_attr where appropriate */
+ u32 vendor_id;
+ u32 vendor_part_id;
+ u32 sw_version;
+ int max_qp;
+ int max_qp_wr;
+ int max_ord; /* max. outbound read queue depth */
+ int max_ird; /* max. inbound read queue depth */
+
+ enum ib_device_cap_flags cap_flags;
+ int max_sge;
+ int max_sge_rd;
+ int max_cq;
+ int max_cqe;
+ u64 max_mr_size;
+ int max_mr;
+ int max_pd;
+ int max_mw;
+ int max_fmr;
+ int max_srq;
+ int max_srq_wr;
+ int max_srq_sge;
+ /* end ib_device_attr */
+
+ enum siw_if_type iftype;
+};
+
+struct siw_dev {
+ struct ib_device ofa_dev;
+ struct list_head list;
+ struct net_device *l2dev;
+ struct siw_devinfo attrs;
+ /* object management */
+ struct list_head cep_list;
+ struct list_head qp_list;
+ spinlock_t idr_lock;
+ struct idr qp_idr;
+ struct idr cq_idr;
+ struct idr pd_idr;
+ struct idr mem_idr; /* MRs & MWs */
+ /* active objects statistics */
+ atomic_t num_qp;
+ atomic_t num_cq;
+ atomic_t num_pd;
+ atomic_t num_mem;
+ atomic_t num_srq;
+ atomic_t num_cep;
+};
+
+struct siw_objhdr {
+ u32 id; /* for idr based object lookup */
+ struct kref ref;
+ struct siw_dev *dev;
+};
+
+
+struct siw_ucontext {
+ struct ib_ucontext ib_ucontext;
+};
+
+struct siw_pd {
+ struct siw_objhdr hdr;
+ struct ib_pd ofa_pd;
+};
+
+enum siw_access_flags {
+ SR_MEM_LREAD = (1<<0),
+ SR_MEM_LWRITE = (1<<1),
+ SR_MEM_RREAD = (1<<2),
+ SR_MEM_RWRITE = (1<<3),
+
+ SR_MEM_FLAGS_LOCAL =
+ (SR_MEM_LREAD | SR_MEM_LWRITE),
+ SR_MEM_FLAGS_REMOTE =
+ (SR_MEM_RWRITE | SR_MEM_RREAD)
+};
+
+#define STAG_VALID 1
+#define STAG_INVALID 0
+#define SIW_STAG_MAX 0xffffffff
+
+struct siw_mr;
+
+/*
+ * generic memory representation for registered siw memory.
+ * memory lookup always via higher 24 bit of stag (stag index).
+ * the stag is stored as part of the siw object header (id).
+ * object relates to memory window if embedded mr pointer is valid
+ */
+struct siw_mem {
+ struct siw_objhdr hdr;
+
+ struct siw_mr *mr; /* assoc. MR if MW, NULL if MR */
+
+ u32 stag_state:1, /* VALID or INVALID */
+ is_zbva:1, /* zero based virt. addr. */
+ mw_bind_enabled:1, /* check only if MR */
+ remote_inval_enabled:1, /* VALID or INVALID */
+ consumer_owns_key:1, /* key/index split ? */
+ rsvd:27;
+
+ enum siw_access_flags perms; /* local/remote READ & WRITE */
+
+ u64 va; /* VA of memory */
+ u64 len; /* amount of memory bytes */
+ u32 fbo; /* first byte offset */
+};
+
+#define SIW_MEM_IS_MW(m) ((m)->mr != NULL)
+#define SIW_INLINED_DATA(w) ((w)->wr.hdr.flags & IB_SEND_INLINE)
+
+/*
+ * MR and MW definition.
+ * Used OFA structs ib_mr/ib_mw holding:
+ * lkey, rkey, MW reference count on MR
+ */
+struct siw_mr {
+ struct ib_mr ofa_mr;
+ struct siw_mem mem;
+ struct ib_umem *umem;
+ struct siw_pd *pd;
+};
+
+struct siw_mw {
+ struct ib_mw ofa_mw;
+ struct siw_mem mem;
+};
+
+/********** WR definitions ****************/
+
+enum siw_wr_opcode {
+ SIW_WR_RDMA_WRITE = IB_WR_RDMA_WRITE,
+ SIW_WR_RDMA_WRITE_WITH_IMM = IB_WR_RDMA_WRITE_WITH_IMM,
+ SIW_WR_SEND = IB_WR_SEND,
+ SIW_WR_SEND_WITH_IMM = IB_WR_SEND_WITH_IMM,
+ SIW_WR_RDMA_READ_REQ = IB_WR_RDMA_READ,
+
+ /* Unsupported */
+ SIW_WR_ATOMIC_CMP_AND_SWP = IB_WR_ATOMIC_CMP_AND_SWP,
+ SIW_WR_ATOMIC_FETCH_AND_ADD = IB_WR_ATOMIC_FETCH_AND_ADD,
+ SIW_WR_INVAL_STAG = IB_WR_LOCAL_INV,
+ SIW_WR_FASTREG = IB_WR_FAST_REG_MR,
+
+ SIW_WR_RECEIVE,
+ SIW_WR_RDMA_READ_RESP, /* pseudo WQE */
+ SIW_WR_NUM
+};
+
+#define opcode_ofa2siw(code) (enum siw_wr_opcode)code
+
+#define SIW_WQE_IS_TX(wqe) 1 /* add BIND/FASTREG/INVAL_STAG */
+
+struct siw_sge {
+ u64 addr; /* HBO */
+ unsigned int len; /* HBO */
+ u32 lkey; /* HBO */
+ union {
+ struct siw_mem *obj; /* reference to registered memory */
+ char *buf; /* linear kernel buffer */
+ } mem;
+};
+
+struct siw_wr_common {
+ enum siw_wr_opcode type;
+ enum ib_send_flags flags;
+ u64 id;
+};
+
+/*
+ * All WRs below having an SGL (with 1 ore more SGEs) must start with
+ * the layout given by struct siw_wr_with_sgl!
+ */
+struct siw_wr_with_sgl {
+ struct siw_wr_common hdr;
+ int num_sge;
+ struct siw_sge sge[0]; /* Start of source or dest. SGL */
+};
+
+struct siw_wr_send {
+ struct siw_wr_common hdr;
+ int num_sge;
+ struct siw_sge sge[SIW_MAX_SGE];
+};
+
+struct siw_wr_rmda_write {
+ struct siw_wr_common hdr;
+ int num_sge;
+ struct siw_sge sge[SIW_MAX_SGE];
+ u64 raddr;
+ u32 rtag;
+};
+
+struct siw_wr_rdma_rread {
+ struct siw_wr_common hdr;
+ int num_sge;
+ struct siw_sge sge[SIW_MAX_SGE];
+ u64 raddr;
+ u32 rtag;
+};
+
+struct siw_wr_rdma_rresp {
+ struct siw_wr_common hdr;
+ int num_sge; /* must be 1 */
+ struct siw_sge sge;
+ u64 raddr;
+ u32 rtag; /* uninterpreted, NBO */
+};
+
+struct siw_wr_bind {
+ struct siw_wr_common hdr;
+ u32 rtag;
+ u32 ltag;
+ struct siw_mr *mr;
+ u64 addr;
+ u32 len;
+ enum siw_access_flags perms;
+};
+
+struct siw_wr_recv {
+ struct siw_wr_common hdr;
+ int num_sge;
+ struct siw_sge sge[SIW_MAX_SGE];
+};
+
+enum siw_wr_state {
+ SR_WR_QUEUED = 0, /* processing has not started yet */
+ SR_WR_INPROGRESS = 1, /* initiated processing of the WR */
+ SR_WR_DONE = 2,
+};
+
+/* better name it siw_qe? */
+struct siw_wqe {
+ struct list_head list;
+ union {
+ struct siw_wr_common hdr;
+ struct siw_wr_with_sgl sgl;
+ struct siw_wr_send send;
+ struct siw_wr_rmda_write write;
+ struct siw_wr_rdma_rread rread;
+ struct siw_wr_rdma_rresp rresp;
+ struct siw_wr_bind bind;
+ struct siw_wr_recv recv;
+ } wr;
+ struct siw_qp *qp;
+ enum siw_wr_state wr_status;
+ enum ib_wc_status wc_status;
+ u32 bytes; /* # bytes to processed */
+ u32 processed; /* # bytes processed */
+ int error;
+};
+
+enum siw_cq_armed {
+ SIW_CQ_NOTIFY_NOT = 0,
+ SIW_CQ_NOTIFY_SOLICITED,
+ SIW_CQ_NOTIFY_ALL
+};
+
+struct siw_cq {
+ struct ib_cq ofa_cq;
+ struct siw_objhdr hdr;
+ enum siw_cq_armed notify;
+ spinlock_t lock;
+ struct list_head queue; /* simple list of cqe's */
+ atomic_t qlen; /* number of elements */
+};
+
+enum siw_qp_state {
+ SIW_QP_STATE_IDLE = 0,
+ SIW_QP_STATE_RTR = 1,
+ SIW_QP_STATE_RTS = 2,
+ SIW_QP_STATE_CLOSING = 3,
+ SIW_QP_STATE_TERMINATE = 4,
+ SIW_QP_STATE_ERROR = 5,
+ SIW_QP_STATE_MORIBUND = 6, /* destroy called but still referenced */
+ SIW_QP_STATE_UNDEF = 7,
+ SIW_QP_STATE_COUNT = 8
+};
+
+enum siw_qp_flags {
+ SIW_RDMA_BIND_ENABLED = (1 << 0),
+ SIW_RDMA_WRITE_ENABLED = (1 << 1),
+ SIW_RDMA_READ_ENABLED = (1 << 2),
+ SIW_KERNEL_VERBS = (1 << 3),
+ /*
+ * QP currently being destroyed
+ */
+ SIW_QP_IN_DESTROY = (1 << 8)
+};
+
+enum siw_qp_attr_mask {
+ SIW_QP_ATTR_STATE = (1 << 0),
+ SIW_QP_ATTR_ACCESS_FLAGS = (1 << 1),
+ SIW_QP_ATTR_LLP_HANDLE = (1 << 2),
+ SIW_QP_ATTR_ORD = (1 << 3),
+ SIW_QP_ATTR_IRD = (1 << 4),
+ SIW_QP_ATTR_SQ_SIZE = (1 << 5),
+ SIW_QP_ATTR_RQ_SIZE = (1 << 6),
+ SIW_QP_ATTR_MPA = (1 << 7)
+};
+
+struct siw_mpa_attrs {
+ __u8 marker_rcv; /* always 0 */
+ __u8 marker_snd; /* always 0, consider support */
+ __u8 crc;
+ __u8 unused;
+};
+
+struct siw_sk_upcalls {
+ void (*sk_state_change)(struct sock *sk);
+ void (*sk_data_ready)(struct sock *sk, int bytes);
+ void (*sk_write_space)(struct sock *sk);
+ void (*sk_error_report)(struct sock *sk);
+};
+
+struct siw_sq_work {
+ struct work_struct work;
+};
+
+struct siw_srq {
+ struct ib_srq ofa_srq;
+ struct siw_pd *pd;
+ struct list_head freeq;
+ spinlock_t freeq_lock;
+ struct list_head rq;
+ spinlock_t lock;
+ u32 max_sge;
+ atomic_t space; /* current space for posting wqe's */
+ u32 limit; /* low watermark for async event */
+ u32 max_wr; /* max # of wqe's allowed */
+ char armed; /* inform user if limit hit */
+ char kernel_verbs; /* '1' if kernel client */
+};
+
+struct siw_qp_attrs {
+ enum siw_qp_state state;
+ char terminate_buffer[52];
+ u32 terminate_msg_length;
+ u32 ddp_rdmap_version; /* 0 or 1 */
+ char *stream_msg_buf;
+ u32 stream_msg_buf_length;
+ u32 rq_hiwat;
+ u32 sq_size;
+ u32 rq_size;
+ u32 sq_max_sges;
+ u32 sq_max_sges_rdmaw;
+ u32 rq_max_sges;
+ u32 ord;
+ u32 ird;
+ struct siw_mpa_attrs mpa;
+ enum siw_qp_flags flags;
+
+ struct socket *llp_stream_handle;
+};
+
+enum siw_tx_ctx {
+ SIW_SEND_HDR = 0, /* start or continue sending HDR */
+ SIW_SEND_DATA = 1, /* start or continue sending DDP payload */
+ SIW_SEND_TRAILER = 2, /* start or continue sending TRAILER */
+ SIW_SEND_SHORT_FPDU = 3 /* send whole FPDU hdr|data|trailer at once */
+};
+
+enum siw_rx_state {
+ SIW_GET_HDR = 0, /* await new hdr or within hdr */
+ SIW_GET_DATA_START = 1, /* start of inbound DDP payload */
+ SIW_GET_DATA_MORE = 2, /* continuation of (misaligned) DDP payload */
+ SIW_GET_TRAILER = 3 /* await new trailer or within trailer */
+};
+
+
+struct siw_iwarp_rx {
+ struct sk_buff *skb;
+ union iwarp_hdrs hdr;
+ struct mpa_trailer trailer;
+ /*
+ * local destination memory of inbound iwarp operation.
+ * valid, if already resolved, NULL otherwise.
+ */
+ union {
+ struct siw_wqe *wqe; /* SEND, RRESP */
+ struct siw_mem *mem; /* WRITE */
+ } dest;
+
+ struct hash_desc mpa_crc_hd;
+ /*
+ * Next expected DDP MSN for each QN +
+ * expected steering tag +
+ * expected DDP tagget offset (all HBO)
+ */
+ u32 ddp_msn[RDMAP_UNTAGGED_QN_COUNT];
+ u32 ddp_stag;
+ u64 ddp_to;
+
+ /*
+ * For each FPDU, main RX loop runs through 3 stages:
+ * Receiving protocol headers, placing DDP payload and receiving
+ * trailer information (CRC + eventual padding).
+ * Next two variables keep state on receive status of the
+ * current FPDU part (hdr, data, trailer).
+ */
+ int fpdu_part_rcvd;/* bytes in pkt part copied */
+ int fpdu_part_rem; /* bytes in pkt part not seen */
+
+ int skb_new; /* pending unread bytes in skb */
+ int skb_offset; /* offset in skb */
+ int skb_copied; /* processed bytes in skb */
+
+ int sge_idx; /* current sge in rx */
+ unsigned int sge_off; /* already rcvd in curr. sge */
+ struct ib_umem_chunk *umem_chunk; /* chunk used by sge and off */
+ int pg_idx; /* page used in chunk */
+ unsigned int pg_off; /* offset within that page */
+
+ enum siw_rx_state state;
+
+ u8 crc_enabled:1,
+ first_ddp_seg:1, /* this is first DDP seg */
+ more_ddp_segs:1, /* more DDP segs expected */
+ rx_suspend:1, /* stop rcv DDP segs. */
+ prev_ddp_opcode:4; /* opcode of prev DDP msg */
+ char pad; /* # of pad bytes expected */
+};
+
+#define siw_rx_data(qp, rctx) \
+ (iwarp_pktinfo[rctx->hdr.ctrl.opcode].proc_data(qp, rctx))
+
+/*
+ * Shorthands for short packets w/o payload
+ * to be transmitted more efficient.
+ */
+struct siw_send_pkt {
+ struct iwarp_send send;
+ __be32 crc;
+};
+
+struct siw_write_pkt {
+ struct iwarp_rdma_write write;
+ __be32 crc;
+};
+
+struct siw_rreq_pkt {
+ struct iwarp_rdma_rreq rreq;
+ __be32 crc;
+};
+
+struct siw_rresp_pkt {
+ struct iwarp_rdma_rresp rresp;
+ __be32 crc;
+};
+
+struct siw_iwarp_tx {
+ union {
+ union iwarp_hdrs hdr;
+
+ /* Generic part of FPDU header */
+ struct iwarp_ctrl ctrl;
+ struct iwarp_ctrl_untagged c_untagged;
+ struct iwarp_ctrl_tagged c_tagged;
+
+ /* FPDU headers */
+ struct iwarp_rdma_write rwrite;
+ struct iwarp_rdma_rreq rreq;
+ struct iwarp_rdma_rresp rresp;
+ struct iwarp_terminate terminate;
+ struct iwarp_send send;
+ struct iwarp_send_inv send_inv;
+
+ /* complete short FPDUs */
+ struct siw_send_pkt send_pkt;
+ struct siw_write_pkt write_pkt;
+ struct siw_rreq_pkt rreq_pkt;
+ struct siw_rresp_pkt rresp_pkt;
+ } pkt;
+
+ struct mpa_trailer trailer;
+ /* DDP MSN for untagged messages */
+ u32 ddp_msn[RDMAP_UNTAGGED_QN_COUNT];
+
+ enum siw_tx_ctx state;
+ wait_queue_head_t waitq;
+
+ u16 ctrl_len; /* ddp+rdmap hdr */
+ u16 ctrl_sent;
+ int bytes_unsent; /* ddp payload bytes */
+
+ struct hash_desc mpa_crc_hd;
+
+ atomic_t in_use; /* tx currently under way */
+
+ char pad; /* # pad in current fpdu */
+ u8 crc_enabled:1, /* compute and ship crc */
+ do_crc:1, /* do crc for segment */
+ use_sendpage:1, /* send w/o copy */
+ new_tcpseg:1, /* start new tcp segment */
+ wspace_update:1,/* new write space indicated */
+ tx_suspend:1, /* stop sending DDP segs. */
+ rsvd:3;
+
+ u16 fpdu_len; /* len of FPDU to tx */
+
+ int tcp_seglen; /* remaining tcp seg space */
+ struct siw_wqe *wqe;
+
+ int sge_idx; /* current sge in tx */
+ u32 sge_off; /* already sent in curr. sge */
+ struct ib_umem_chunk *umem_chunk; /* chunk used by sge and off */
+ int pg_idx; /* page used in mem chunk */
+};
+
+struct siw_qp {
+ struct ib_qp ofa_qp;
+ struct siw_objhdr hdr;
+ struct list_head devq;
+ int cpu;
+ struct siw_iwarp_rx rx_ctx;
+ struct siw_iwarp_tx tx_ctx;
+
+ struct siw_cep *cep;
+ struct rw_semaphore state_lock;
+
+ struct siw_pd *pd;
+ struct siw_cq *scq;
+ struct siw_cq *rcq;
+
+ struct siw_qp_attrs attrs;
+
+ struct list_head freeq;
+ spinlock_t freeq_lock;
+ struct list_head sq;
+ spinlock_t sq_lock;
+ atomic_t sq_space;
+ struct list_head irq;
+ atomic_t irq_space;
+ struct siw_srq *srq;
+ struct list_head rq;
+ spinlock_t rq_lock;
+ atomic_t rq_space;
+ struct list_head orq;
+ atomic_t orq_space;
+ spinlock_t orq_lock;
+
+ struct siw_sq_work sq_work;
+};
+
+#define lock_sq(qp) spin_lock(&qp->sq_lock)
+#define unlock_sq(qp) spin_unlock(&qp->sq_lock)
+
+#define lock_sq_rxsave(qp, flags) spin_lock_irqsave(&qp->sq_lock, flags)
+#define unlock_sq_rxsave(qp, flags) spin_unlock_irqrestore(&qp->sq_lock, flags)
+
+#define lock_rq(qp) spin_lock(&qp->rq_lock)
+#define unlock_rq(qp) spin_unlock(&qp->rq_lock)
+
+#define lock_rq_rxsave(qp, flags) spin_lock_irqsave(&qp->rq_lock, flags)
+#define unlock_rq_rxsave(qp, flags) spin_unlock_irqrestore(&qp->rq_lock, flags)
+
+#define lock_srq(srq) spin_lock(&srq->lock)
+#define unlock_srq(srq) spin_unlock(&srq->lock)
+
+#define lock_srq_rxsave(srq, flags) spin_lock_irqsave(&srq->lock, flags)
+#define unlock_srq_rxsave(srq, flags) spin_unlock_irqrestore(&srq->lock, flags)
+
+#define lock_cq(cq) spin_lock(&cq->lock)
+#define unlock_cq(cq) spin_unlock(&cq->lock)
+
+#define lock_cq_rxsave(cq, flags) spin_lock_irqsave(&cq->lock, flags)
+#define unlock_cq_rxsave(cq, flags)\
+ spin_unlock_irqrestore(&cq->lock, flags)
+
+#define lock_orq(qp) spin_lock(&qp->orq_lock)
+#define unlock_orq(qp) spin_unlock(&qp->orq_lock)
+
+#define lock_orq_rxsave(qp, flags) spin_lock_irqsave(&qp->orq_lock, flags)
+#define unlock_orq_rxsave(qp, flags)\
+ spin_unlock_irqrestore(&qp->orq_lock, flags)
+
+#define RX_QP(rx) container_of(rx, struct siw_qp, rx_ctx)
+#define TX_QP(tx) container_of(tx, struct siw_qp, tx_ctx)
+#define QP_ID(qp) ((qp)->hdr.id)
+#define OBJ_ID(obj) ((obj)->hdr.id)
+#define RX_QPID(rx) QP_ID(RX_QP(rx))
+#define TX_QPID(tx) QP_ID(TX_QP(tx))
+
+/* helper macros */
+#define tx_wqe(qp) ((qp)->tx_ctx.wqe)
+#define rx_wqe(qp) ((qp)->rx_ctx.dest.wqe)
+#define rx_mem(qp) ((qp)->rx_ctx.dest.mem)
+#define wr_id(wqe) ((wqe)->wr.hdr.id)
+#define wr_type(wqe) ((wqe)->wr.hdr.type)
+#define wr_flags(wqe) ((wqe)->wr.hdr.flags)
+#define list_entry_wqe(pos) list_entry(pos, struct siw_wqe, list)
+#define list_first_wqe(pos) list_first_entry(pos, struct siw_wqe, list)
+
+#define ORD_SUSPEND_SQ(qp) (!atomic_read(&(qp)->orq_space))
+#define TX_ACTIVE(qp) (tx_wqe(qp) != NULL)
+#define SQ_EMPTY(qp) list_empty(&((qp)->sq))
+#define ORQ_EMPTY(qp) list_empty(&((qp)->orq))
+#define IRQ_EMPTY(qp) list_empty(&((qp)->irq))
+#define TX_ACTIVE_RRESP(qp) (TX_ACTIVE(qp) &&\
+ wr_type(tx_wqe(qp)) == SIW_WR_RDMA_READ_RESP)
+
+#define TX_IDLE(qp) (!TX_ACTIVE(qp) && SQ_EMPTY(qp) && \
+ IRQ_EMPTY(qp) && ORQ_EMPTY(qp))
+
+#define TX_MORE_WQE(qp) (!SQ_EMPTY(qp) || !IRQ_EMPTY(qp))
+
+struct iwarp_msg_info {
+ int hdr_len;
+ struct iwarp_ctrl ctrl;
+ int (*proc_data) (struct siw_qp *, struct siw_iwarp_rx *);
+};
+
+extern struct iwarp_msg_info iwarp_pktinfo[RDMAP_TERMINATE + 1];
+
+
+extern struct siw_dev *siw;
+
+
+/* QP general functions */
+int siw_qp_modify(struct siw_qp *, struct siw_qp_attrs *,
+ enum siw_qp_attr_mask);
+
+void siw_qp_llp_close(struct siw_qp *);
+void siw_qp_cm_drop(struct siw_qp *, int);
+
+
+struct ib_qp *siw_get_ofaqp(struct ib_device *, int);
+void siw_qp_get_ref(struct ib_qp *);
+void siw_qp_put_ref(struct ib_qp *);
+
+int siw_no_mad(struct ib_device *, int, u8, struct ib_wc *, struct ib_grh *,
+ struct ib_mad *, struct ib_mad *);
+
+enum siw_qp_state siw_map_ibstate(enum ib_qp_state);
+
+int siw_check_mem(struct siw_pd *, struct siw_mem *, u64,
+ enum siw_access_flags, int);
+int siw_check_sge(struct siw_pd *, struct siw_sge *,
+ enum siw_access_flags, u32, int);
+int siw_check_sgl(struct siw_pd *, struct siw_sge *,
+ enum siw_access_flags, u32, int);
+
+void siw_rq_complete(struct siw_wqe *, struct siw_qp *);
+void siw_sq_complete(struct list_head *, struct siw_qp *, int,
+ enum ib_send_flags);
+
+
+/* QP TX path functions */
+int siw_qp_sq_process(struct siw_qp *, int);
+int siw_sq_worker_init(void);
+void siw_sq_worker_exit(void);
+int siw_sq_queue_work(struct siw_qp *qp);
+
+/* QP RX path functions */
+int siw_proc_send(struct siw_qp *, struct siw_iwarp_rx *);
+int siw_init_rresp(struct siw_qp *, struct siw_iwarp_rx *);
+int siw_proc_rreq(struct siw_qp *, struct siw_iwarp_rx *);
+int siw_proc_rresp(struct siw_qp *, struct siw_iwarp_rx *);
+int siw_proc_write(struct siw_qp *, struct siw_iwarp_rx *);
+int siw_proc_terminate(struct siw_qp*, struct siw_iwarp_rx *);
+int siw_proc_unsupp(struct siw_qp *, struct siw_iwarp_rx *);
+
+int siw_tcp_rx_data(read_descriptor_t *rd_desc, struct sk_buff *skb,
+ unsigned int off, size_t len);
+
+/* MPA utilities */
+int siw_crc_array(struct hash_desc *, u8 *, size_t);
+int siw_crc_sg(struct hash_desc *, struct scatterlist *, int, int);
+
+
+/* Varia */
+void siw_cq_flush(struct siw_cq *);
+void siw_sq_flush(struct siw_qp *);
+void siw_rq_flush(struct siw_qp *);
+int siw_reap_cqe(struct siw_cq *, struct ib_wc *);
+
+void siw_async_ev(struct siw_qp *, struct siw_cq *, enum ib_event_type);
+void siw_async_srq_ev(struct siw_srq *, enum ib_event_type);
+
+static inline struct siw_wqe *
+siw_next_tx_wqe(struct siw_qp *qp) {
+ struct siw_wqe *wqe;
+
+ if (!list_empty(&qp->irq))
+ wqe = list_first_entry(&qp->irq, struct siw_wqe, list);
+ else if (!list_empty(&qp->sq))
+ wqe = list_first_entry(&qp->sq, struct siw_wqe, list);
+ else
+ wqe = NULL;
+ return wqe;
+}
+
+static inline void
+siw_rreq_queue(struct siw_wqe *wqe, struct siw_qp *qp)
+{
+ unsigned long flags;
+
+ lock_orq_rxsave(qp, flags);
+ list_move_tail(&wqe->list, &qp->orq);
+ atomic_dec(&qp->orq_space);
+ unlock_orq_rxsave(qp, flags);
+}
+
+
+static inline struct ib_umem_chunk *
+mem_chunk_next(struct ib_umem_chunk *chunk)
+{
+ return list_entry(chunk->list.next, struct ib_umem_chunk, list);
+}
+
+
+static inline struct siw_mr *siw_mem2mr(struct siw_mem *m)
+{
+ if (!SIW_MEM_IS_MW(m))
+ return container_of(m, struct siw_mr, mem);
+ return m->mr;
+}
+
+#endif
--
1.5.4.3
^ permalink raw reply related
* [PATCH 05/14] SIWv2: User interface: siw_verbs.h, siw_verbs.c, siw_user.h, siw_ae.c
From: Bernard Metzler @ 2011-06-16 12:42 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA, Bernard Metzler
---
drivers/infiniband/hw/siw/siw_ae.c | 97 ++
drivers/infiniband/hw/siw/siw_user.h | 66 ++
drivers/infiniband/hw/siw/siw_verbs.c | 1734 +++++++++++++++++++++++++++++++++
drivers/infiniband/hw/siw/siw_verbs.h | 99 ++
4 files changed, 1996 insertions(+), 0 deletions(-)
create mode 100644 drivers/infiniband/hw/siw/siw_ae.c
create mode 100644 drivers/infiniband/hw/siw/siw_user.h
create mode 100644 drivers/infiniband/hw/siw/siw_verbs.c
create mode 100644 drivers/infiniband/hw/siw/siw_verbs.h
diff --git a/drivers/infiniband/hw/siw/siw_ae.c b/drivers/infiniband/hw/siw/siw_ae.c
new file mode 100644
index 0000000..acf9794
--- /dev/null
+++ b/drivers/infiniband/hw/siw/siw_ae.c
@@ -0,0 +1,97 @@
+/*
+ * Software iWARP device driver for Linux
+ *
+ * Authors: Bernard Metzler <bmt-OA+xvbQnYDHMbYB6QlFGEg@public.gmane.org>
+ *
+ * Copyright (c) 2008-2011, IBM Corporation
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of IBM nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/net.h>
+#include <linux/scatterlist.h>
+#include <linux/highmem.h>
+#include <net/sock.h>
+#include <net/tcp_states.h>
+#include <net/tcp.h>
+
+#include <rdma/iw_cm.h>
+#include <rdma/ib_verbs.h>
+#include <rdma/ib_smi.h>
+#include <rdma/ib_user_verbs.h>
+#include <rdma/ib_umem.h>
+
+#include "siw.h"
+#include "siw_obj.h"
+#include "siw_cm.h"
+
+/*
+ * siw_async_ev()
+ *
+ * Report Asynchonous event to user.
+ */
+void siw_async_ev(struct siw_qp *qp, struct siw_cq *cq,
+ enum ib_event_type etype)
+{
+ static struct ib_event event;
+
+ dprint(DBG_EH, "(QP%d): AE type %d\n", QP_ID(qp), etype);
+
+ event.event = etype;
+ event.device = qp->ofa_qp.device;
+ if (cq)
+ event.element.cq = &cq->ofa_cq;
+ else
+ event.element.qp = &qp->ofa_qp;
+
+ if (!(qp->attrs.flags & SIW_QP_IN_DESTROY) &&
+ qp->ofa_qp.event_handler) {
+ dprint(DBG_EH, "(QP%d): Call AEH\n", QP_ID(qp));
+ (*qp->ofa_qp.event_handler)(&event, qp->ofa_qp.qp_context);
+ }
+}
+
+void siw_async_srq_ev(struct siw_srq *srq, enum ib_event_type etype)
+{
+ static struct ib_event event;
+
+ dprint(DBG_EH, "(SRQ%p): AE type %d\n", srq, etype);
+
+ event.event = etype;
+ event.device = srq->ofa_srq.device;
+ event.element.srq = &srq->ofa_srq;
+
+ if (srq->ofa_srq.event_handler)
+ (*srq->ofa_srq.event_handler)(&event,
+ srq->ofa_srq.srq_context);
+}
diff --git a/drivers/infiniband/hw/siw/siw_user.h b/drivers/infiniband/hw/siw/siw_user.h
new file mode 100644
index 0000000..5ec9fb9
--- /dev/null
+++ b/drivers/infiniband/hw/siw/siw_user.h
@@ -0,0 +1,66 @@
+/*
+ * Software iWARP device driver for Linux
+ *
+ * Authors: Bernard Metzler <bmt-OA+xvbQnYDHMbYB6QlFGEg@public.gmane.org>
+ *
+ * Copyright (c) 2008-2011, IBM Corporation
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of IBM nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef _SIW_USER_H
+#define _SIW_USER_H
+
+/*
+ * user commands/command responses must correlate with the siw_abi
+ * in user land.
+ */
+
+struct siw_uresp_create_cq {
+ __u32 cq_id;
+};
+
+struct siw_uresp_create_qp {
+ __u32 qp_id;
+ __u32 sq_size;
+ __u32 rq_size;
+};
+
+struct siw_uresp_reg_mr {
+ __u32 stag;
+};
+
+struct siw_ureq_reg_mr {
+ __u8 stag_key;
+ __u8 reserved[3];
+};
+
+#endif
diff --git a/drivers/infiniband/hw/siw/siw_verbs.c b/drivers/infiniband/hw/siw/siw_verbs.c
new file mode 100644
index 0000000..3f693da
--- /dev/null
+++ b/drivers/infiniband/hw/siw/siw_verbs.c
@@ -0,0 +1,1734 @@
+/*
+ * Software iWARP device driver for Linux
+ *
+ * Authors: Bernard Metzler <bmt-OA+xvbQnYDHMbYB6QlFGEg@public.gmane.org>
+ *
+ * Copyright (c) 2008-2011, IBM Corporation
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of IBM nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/uaccess.h>
+
+#include <rdma/iw_cm.h>
+#include <rdma/ib_verbs.h>
+#include <rdma/ib_smi.h>
+#include <rdma/ib_user_verbs.h>
+#include <rdma/ib_umem.h>
+
+#include "siw.h"
+#include "siw_verbs.h"
+#include "siw_obj.h"
+#include "siw_cm.h"
+
+static int ib_qp_state_to_siw_qp_state[IB_QPS_ERR+1] = {
+ [IB_QPS_RESET] = SIW_QP_STATE_IDLE,
+ [IB_QPS_INIT] = SIW_QP_STATE_IDLE,
+ [IB_QPS_RTR] = SIW_QP_STATE_RTR,
+ [IB_QPS_RTS] = SIW_QP_STATE_RTS,
+ [IB_QPS_SQD] = SIW_QP_STATE_CLOSING,
+ [IB_QPS_SQE] = SIW_QP_STATE_TERMINATE,
+ [IB_QPS_ERR] = SIW_QP_STATE_ERROR
+};
+
+static inline struct siw_mr *siw_mr_ofa2siw(struct ib_mr *ofa_mr)
+{
+ return container_of(ofa_mr, struct siw_mr, ofa_mr);
+}
+
+static inline struct siw_pd *siw_pd_ofa2siw(struct ib_pd *ofa_pd)
+{
+ return container_of(ofa_pd, struct siw_pd, ofa_pd);
+}
+
+static inline struct siw_ucontext *siw_ctx_ofa2siw(struct ib_ucontext *ofa_ctx)
+{
+ return container_of(ofa_ctx, struct siw_ucontext, ib_ucontext);
+}
+
+static inline struct siw_qp *siw_qp_ofa2siw(struct ib_qp *ofa_qp)
+{
+ return container_of(ofa_qp, struct siw_qp, ofa_qp);
+}
+
+static inline struct siw_cq *siw_cq_ofa2siw(struct ib_cq *ofa_cq)
+{
+ return container_of(ofa_cq, struct siw_cq, ofa_cq);
+}
+
+static inline struct siw_srq *siw_srq_ofa2siw(struct ib_srq *ofa_srq)
+{
+ return container_of(ofa_srq, struct siw_srq, ofa_srq);
+}
+
+struct ib_ucontext *siw_alloc_ucontext(struct ib_device *ofa_dev,
+ struct ib_udata *udata)
+{
+ struct siw_ucontext *ctx;
+
+ dprint(DBG_CM, "(device=%s)\n", ofa_dev->name);
+
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+ if (!ctx) {
+ dprint(DBG_ON, " kzalloc\n");
+ return ERR_PTR(-ENOMEM);
+ }
+ return &ctx->ib_ucontext;
+}
+
+int siw_dealloc_ucontext(struct ib_ucontext *ctx)
+{
+ struct siw_ucontext *ucontext;
+
+ ucontext = siw_ctx_ofa2siw(ctx);
+
+ kfree(ucontext);
+
+ return 0;
+}
+
+int siw_query_device(struct ib_device *ofa_dev, struct ib_device_attr *attr)
+{
+ struct siw_dev *dev = siw_dev_ofa2siw(ofa_dev);
+ /*
+ * A process context is needed to report avail memory resources.
+ */
+ if (in_interrupt())
+ return -EINVAL;
+
+ memset(attr, 0, sizeof *attr);
+
+ attr->max_mr_size = rlimit(RLIMIT_MEMLOCK); /* per process */
+ attr->vendor_id = dev->attrs.vendor_id;
+ attr->vendor_part_id = dev->attrs.vendor_part_id;
+ attr->max_qp = dev->attrs.max_qp;
+ attr->max_qp_wr = dev->attrs.max_qp_wr;
+
+ /*
+ * RDMA Read parameters:
+ * Max. ORD (Outbound Read queue Depth), a.k.a. max_initiator_depth
+ * Max. IRD (Inbound Read queue Depth), a.k.a. max_responder_resources
+ */
+ attr->max_qp_rd_atom = dev->attrs.max_ord;
+ attr->max_qp_init_rd_atom = dev->attrs.max_ird;
+ attr->max_res_rd_atom = dev->attrs.max_qp * dev->attrs.max_ird;
+ attr->device_cap_flags = dev->attrs.cap_flags;
+ attr->max_sge = dev->attrs.max_sge;
+ attr->max_sge_rd = dev->attrs.max_sge_rd;
+ attr->max_cq = dev->attrs.max_cq;
+ attr->max_cqe = dev->attrs.max_cqe;
+ attr->max_mr = dev->attrs.max_mr;
+ attr->max_pd = dev->attrs.max_pd;
+ attr->max_mw = dev->attrs.max_mw;
+ attr->max_fmr = dev->attrs.max_fmr;
+ attr->max_srq = dev->attrs.max_srq;
+ attr->max_srq_wr = dev->attrs.max_srq_wr;
+ attr->max_srq_sge = dev->attrs.max_srq_sge;
+
+ memcpy(&attr->sys_image_guid, dev->l2dev->dev_addr, 6);
+
+ /*
+ * TODO: understand what of the following should
+ * get useful information
+ *
+ * attr->fw_ver;
+ * attr->max_ah
+ * attr->max_map_per_fmr
+ * attr->max_ee
+ * attr->max_rdd
+ * attr->max_ee_rd_atom;
+ * attr->max_ee_init_rd_atom;
+ * attr->max_raw_ipv6_qp
+ * attr->max_raw_ethy_qp
+ * attr->max_mcast_grp
+ * attr->max_mcast_qp_attach
+ * attr->max_total_mcast_qp_attach
+ * attr->max_pkeys
+ * attr->atomic_cap;
+ * attr->page_size_cap;
+ * attr->hw_ver;
+ * attr->local_ca_ack_delay;
+ */
+ return 0;
+}
+
+/*
+ * Approximate translation of real MTU for IB.
+ *
+ * TODO: is that needed for RNIC's? We may have a medium
+ * which reports MTU of 64kb and have to degrade to 4k??
+ */
+static inline enum ib_mtu siw_mtu_net2ofa(unsigned short mtu)
+{
+ if (mtu >= 4096)
+ return IB_MTU_4096;
+ if (mtu >= 2048)
+ return IB_MTU_2048;
+ if (mtu >= 1024)
+ return IB_MTU_1024;
+ if (mtu >= 512)
+ return IB_MTU_512;
+ if (mtu >= 256)
+ return IB_MTU_256;
+ return -1;
+}
+
+int siw_query_port(struct ib_device *ofa_dev, u8 port,
+ struct ib_port_attr *attr)
+{
+ struct siw_dev *dev = siw_dev_ofa2siw(ofa_dev);
+
+ memset(attr, 0, sizeof *attr);
+ /*
+ * TODO: fully understand what to do here
+ */
+ attr->state = IB_PORT_ACTIVE; /* ?? */
+ attr->max_mtu = siw_mtu_net2ofa(dev->l2dev->mtu);
+ attr->active_mtu = attr->max_mtu;
+ attr->gid_tbl_len = 1;
+ attr->port_cap_flags = IB_PORT_CM_SUP; /* ?? */
+ attr->port_cap_flags |= IB_PORT_DEVICE_MGMT_SUP;
+ attr->max_msg_sz = -1;
+ attr->pkey_tbl_len = 1;
+ attr->active_width = 2;
+ attr->active_speed = 2;
+ /*
+ * All zero
+ *
+ * attr->lid = 0;
+ * attr->bad_pkey_cntr = 0;
+ * attr->qkey_viol_cntr = 0;
+ * attr->sm_lid = 0;
+ * attr->lmc = 0;
+ * attr->max_vl_num = 0;
+ * attr->sm_sl = 0;
+ * attr->subnet_timeout = 0;
+ * attr->init_type_repy = 0;
+ * attr->phys_state = 0;
+ */
+ return 0;
+}
+
+int siw_query_pkey(struct ib_device *ofa_dev, u8 port, u16 idx, u16 *pkey)
+{
+ *pkey = 0;
+ return 0;
+}
+
+int siw_query_gid(struct ib_device *ofa_dev, u8 port, int idx,
+ union ib_gid *gid)
+{
+ struct siw_dev *dev = siw_dev_ofa2siw(ofa_dev);
+
+ /* subnet_prefix == interface_id == 0; */
+ memset(gid, 0, sizeof *gid);
+ memcpy(&gid->raw[0], dev->l2dev->dev_addr, 6);
+
+ return 0;
+}
+
+struct ib_pd *siw_alloc_pd(struct ib_device *ofa_dev,
+ struct ib_ucontext *context, struct ib_udata *udata)
+{
+ struct siw_pd *pd = NULL;
+ struct siw_dev *dev = siw_dev_ofa2siw(ofa_dev);
+ int rv;
+
+ if (atomic_inc_return(&dev->num_pd) > SIW_MAX_PD) {
+ dprint(DBG_ON, ": Out of PD's\n");
+ rv = -ENOMEM;
+ goto err_out;
+ }
+ pd = kmalloc(sizeof *pd, GFP_KERNEL);
+ if (!pd) {
+ dprint(DBG_ON, ": malloc\n");
+ rv = -ENOMEM;
+ goto err_out;
+ }
+ rv = siw_pd_add(dev, pd);
+ if (rv) {
+ dprint(DBG_ON, ": siw_pd_add\n");
+ rv = -ENOMEM;
+ goto err_out;
+ }
+ if (context) {
+ if (ib_copy_to_udata(udata, &pd->hdr.id, sizeof pd->hdr.id)) {
+ rv = -EFAULT;
+ goto err_out_idr;
+ }
+ }
+ return &pd->ofa_pd;
+
+err_out_idr:
+ siw_remove_obj(&dev->idr_lock, &dev->pd_idr, &pd->hdr);
+err_out:
+ kfree(pd);
+ atomic_dec(&dev->num_pd);
+
+ return ERR_PTR(rv);
+}
+
+int siw_dealloc_pd(struct ib_pd *ofa_pd)
+{
+ struct siw_pd *pd = siw_pd_ofa2siw(ofa_pd);
+ struct siw_dev *dev = siw_dev_ofa2siw(ofa_pd->device);
+
+ siw_remove_obj(&dev->idr_lock, &dev->pd_idr, &pd->hdr);
+ siw_pd_put(pd);
+
+ return 0;
+}
+
+struct ib_ah *siw_create_ah(struct ib_pd *pd, struct ib_ah_attr *attr)
+{
+ return ERR_PTR(-ENOSYS);
+}
+
+int siw_destroy_ah(struct ib_ah *ah)
+{
+ return -ENOSYS;
+}
+
+
+void siw_qp_get_ref(struct ib_qp *ofa_qp)
+{
+ struct siw_qp *qp = siw_qp_ofa2siw(ofa_qp);
+
+ dprint(DBG_OBJ|DBG_CM, "(QP%d): Get Reference\n", QP_ID(qp));
+ siw_qp_get(qp);
+}
+
+
+void siw_qp_put_ref(struct ib_qp *ofa_qp)
+{
+ struct siw_qp *qp = siw_qp_ofa2siw(ofa_qp);
+
+ dprint(DBG_OBJ|DBG_CM, "(QP%d): Put Reference\n", QP_ID(qp));
+ siw_qp_put(qp);
+}
+
+int siw_no_mad(struct ib_device *ofa_dev, int flags, u8 port,
+ struct ib_wc *wc, struct ib_grh *grh,
+ struct ib_mad *in_mad, struct ib_mad *out_mad)
+{
+ return -ENOSYS;
+}
+
+
+/*
+ * siw_create_qp()
+ *
+ * Create QP of requested size on given device.
+ *
+ * @ofa_pd: OFA PD contained in siw PD
+ * @attrs: Initial QP attributes.
+ * @udata: used to provide QP ID, SQ and RQ size back to user.
+ */
+
+struct ib_qp *siw_create_qp(struct ib_pd *ofa_pd,
+ struct ib_qp_init_attr *attrs,
+ struct ib_udata *udata)
+{
+ struct siw_qp *qp = NULL;
+ struct siw_pd *pd = siw_pd_ofa2siw(ofa_pd);
+ struct ib_device *ofa_dev = ofa_pd->device;
+ struct siw_dev *dev = siw_dev_ofa2siw(ofa_dev);
+ struct siw_cq *scq = NULL, *rcq = NULL;
+ struct siw_iwarp_tx *c_tx;
+ struct siw_iwarp_rx *c_rx;
+ struct siw_uresp_create_qp uresp;
+
+ unsigned long flags;
+ int kernel_verbs = ofa_pd->uobject ? 0 : 1;
+ int rv = 0;
+
+ dprint(DBG_OBJ|DBG_CM, ": new QP on device %s\n",
+ ofa_dev->name);
+
+ if (atomic_inc_return(&dev->num_qp) > SIW_MAX_QP) {
+ dprint(DBG_ON, ": Out of QP's\n");
+ rv = -ENOMEM;
+ goto err_out;
+ }
+ if (attrs->qp_type != IB_QPT_RC) {
+ dprint(DBG_ON, ": Only RC QP's supported\n");
+ rv = -EINVAL;
+ goto err_out;
+ }
+ if ((attrs->cap.max_send_wr > SIW_MAX_QP_WR) ||
+ (attrs->cap.max_recv_wr > SIW_MAX_QP_WR) ||
+ (attrs->cap.max_send_sge > SIW_MAX_SGE) ||
+ (attrs->cap.max_recv_sge > SIW_MAX_SGE)) {
+ dprint(DBG_ON, ": QP Size!\n");
+ rv = -EINVAL;
+ goto err_out;
+ }
+ if (attrs->cap.max_inline_data > SIW_MAX_INLINE ||
+ (kernel_verbs && attrs->cap.max_inline_data != 0)) {
+ dprint(DBG_ON, ": Max Inline Send %d > %d!\n",
+ attrs->cap.max_inline_data, SIW_MAX_INLINE);
+ rv = -EINVAL;
+ goto err_out;
+ }
+ /*
+ * NOTE: we allow for zero element SQ and RQ WQE's SGL's
+ * but not for a QP unable to hold any WQE (SQ + RQ)
+ */
+ if (attrs->cap.max_send_wr + attrs->cap.max_recv_wr == 0) {
+ rv = -EINVAL;
+ goto err_out;
+ }
+
+ scq = siw_cq_id2obj(dev, ((struct siw_cq *)attrs->send_cq)->hdr.id);
+ rcq = siw_cq_id2obj(dev, ((struct siw_cq *)attrs->recv_cq)->hdr.id);
+
+ if (!scq || !rcq) {
+ dprint(DBG_OBJ, ": Fail: SCQ: 0x%p, RCQ: 0x%p\n",
+ scq, rcq);
+ rv = -EINVAL;
+ goto err_out;
+ }
+ qp = kzalloc(sizeof(*qp), GFP_KERNEL);
+ if (!qp) {
+ dprint(DBG_ON, ": kzalloc\n");
+ rv = -ENOMEM;
+ goto err_out;
+ }
+
+ INIT_LIST_HEAD(&qp->freeq);
+ INIT_LIST_HEAD(&qp->sq);
+ INIT_LIST_HEAD(&qp->rq);
+ INIT_LIST_HEAD(&qp->orq);
+ INIT_LIST_HEAD(&qp->irq);
+
+ init_rwsem(&qp->state_lock);
+ spin_lock_init(&qp->freeq_lock);
+ spin_lock_init(&qp->sq_lock);
+ spin_lock_init(&qp->rq_lock);
+ spin_lock_init(&qp->orq_lock);
+
+ init_waitqueue_head(&qp->tx_ctx.waitq);
+
+ rv = siw_qp_add(dev, qp);
+ if (rv)
+ goto err_out;
+
+ if (kernel_verbs) {
+ int num_wqe = attrs->cap.max_send_wr + attrs->cap.max_recv_wr;
+ while (num_wqe--) {
+ struct siw_wqe *wqe = kzalloc(sizeof *wqe, GFP_KERNEL);
+ if (!wqe) {
+ rv = -ENOMEM;
+ goto err_out_idr;
+ }
+ SIW_INC_STAT_WQE;
+ INIT_LIST_HEAD(&wqe->list);
+ list_add(&wqe->list, &qp->freeq);
+ }
+ qp->attrs.flags |= SIW_KERNEL_VERBS;
+ }
+ qp->pd = pd;
+ qp->scq = scq;
+ qp->rcq = rcq;
+
+ if (attrs->srq) {
+ /*
+ * SRQ support.
+ * Verbs 6.3.7: ignore RQ size, if SRQ present
+ * Verbs 6.3.5: do not check PD of SRQ against PD of QP
+ */
+ qp->srq = siw_srq_ofa2siw(attrs->srq);
+ qp->attrs.rq_size = 0;
+ atomic_set(&qp->rq_space, 0);
+ dprint(DBG_OBJ, " QP(%d): SRQ(%p) attached\n",
+ QP_ID(qp), qp->srq);
+ } else {
+ qp->srq = NULL;
+ qp->attrs.rq_size = attrs->cap.max_recv_wr;
+ atomic_set(&qp->rq_space, qp->attrs.rq_size);
+ }
+ qp->attrs.sq_size = attrs->cap.max_send_wr;
+ atomic_set(&qp->sq_space, qp->attrs.sq_size);
+ qp->attrs.sq_max_sges = attrs->cap.max_send_sge;
+ /*
+ * ofed has no max_send_sge_rdmawrite
+ */
+ qp->attrs.sq_max_sges_rdmaw = attrs->cap.max_send_sge;
+ qp->attrs.rq_max_sges = attrs->cap.max_recv_sge;
+
+ qp->attrs.state = SIW_QP_STATE_IDLE;
+
+ if (udata) {
+ uresp.sq_size = qp->attrs.sq_size;
+ uresp.rq_size = qp->attrs.rq_size;
+ uresp.qp_id = QP_ID(qp);
+
+ rv = ib_copy_to_udata(udata, &uresp, sizeof uresp);
+ if (rv)
+ goto err_out_idr;
+ }
+ c_tx = &qp->tx_ctx;
+ c_rx = &qp->rx_ctx;
+
+ atomic_set(&qp->tx_ctx.in_use, 0);
+
+ qp->ofa_qp.qp_num = QP_ID(qp);
+
+ siw_pd_get(pd);
+
+ INIT_LIST_HEAD(&qp->devq);
+ spin_lock_irqsave(&dev->idr_lock, flags);
+ list_add_tail(&qp->devq, &dev->qp_list);
+ spin_unlock_irqrestore(&dev->idr_lock, flags);
+
+ return &qp->ofa_qp;
+
+err_out_idr:
+ siw_remove_obj(&dev->idr_lock, &dev->qp_idr, &qp->hdr);
+err_out:
+ if (scq)
+ siw_cq_put(scq);
+ if (rcq)
+ siw_cq_put(rcq);
+
+ if (qp)
+ siw_drain_wq(&qp->freeq);
+
+ kfree(qp);
+ atomic_dec(&dev->num_qp);
+
+ return ERR_PTR(rv);
+}
+
+/*
+ * Minimum siw_query_qp() verb interface.
+ *
+ * @qp_attr_mask is not used but all available information is provided
+ */
+int siw_query_qp(struct ib_qp *ofa_qp, struct ib_qp_attr *qp_attr,
+ int qp_attr_mask, struct ib_qp_init_attr *qp_init_attr)
+{
+ struct siw_qp *qp;
+ struct siw_dev *dev;
+
+ if (ofa_qp && qp_attr && qp_init_attr) {
+ qp = siw_qp_ofa2siw(ofa_qp);
+ dev = siw_dev_ofa2siw(ofa_qp->device);
+ } else
+ return -EINVAL;
+
+ if (qp->attrs.flags & SIW_KERNEL_VERBS) {
+ qp_attr->cap.max_inline_data = 0;
+ qp_init_attr->cap.max_inline_data = 0;
+ } else {
+ qp_attr->cap.max_inline_data = SIW_MAX_INLINE;
+ qp_init_attr->cap.max_inline_data = SIW_MAX_INLINE;
+ }
+ qp_attr->cap.max_send_wr = qp->attrs.sq_size;
+ qp_attr->cap.max_recv_wr = qp->attrs.rq_size;
+ qp_attr->cap.max_send_sge = qp->attrs.sq_max_sges;
+ qp_attr->cap.max_recv_sge = qp->attrs.rq_max_sges;
+
+ qp_attr->path_mtu = siw_mtu_net2ofa(dev->l2dev->mtu);
+ qp_attr->max_rd_atomic = qp->attrs.ird;
+ qp_attr->max_dest_rd_atomic = qp->attrs.ord;
+
+ qp_attr->qp_access_flags = IB_ACCESS_LOCAL_WRITE |
+ IB_ACCESS_REMOTE_WRITE | IB_ACCESS_REMOTE_READ;
+
+ qp_init_attr->cap = qp_attr->cap;
+
+ return 0;
+}
+
+int siw_ofed_modify_qp(struct ib_qp *ofa_qp, struct ib_qp_attr *attr,
+ int attr_mask, struct ib_udata *udata)
+{
+ struct siw_qp_attrs new_attrs;
+ enum siw_qp_attr_mask siw_attr_mask = 0;
+ struct siw_qp *qp = siw_qp_ofa2siw(ofa_qp);
+ int rv = 0;
+
+ if (!attr_mask) {
+ dprint(DBG_CM, "(QP%d): attr_mask==0 ignored\n", QP_ID(qp));
+ goto out;
+ }
+ siw_dprint_qp_attr_mask(attr_mask);
+
+ memset(&new_attrs, 0, sizeof new_attrs);
+
+ if (attr_mask & IB_QP_ACCESS_FLAGS) {
+
+ siw_attr_mask |= SIW_QP_ATTR_ACCESS_FLAGS;
+
+ if (attr->qp_access_flags & IB_ACCESS_REMOTE_READ)
+ new_attrs.flags |= SIW_RDMA_READ_ENABLED;
+ if (attr->qp_access_flags & IB_ACCESS_REMOTE_WRITE)
+ new_attrs.flags |= SIW_RDMA_WRITE_ENABLED;
+ if (attr->qp_access_flags & IB_ACCESS_MW_BIND)
+ new_attrs.flags |= SIW_RDMA_BIND_ENABLED;
+ }
+ if (attr_mask & IB_QP_STATE) {
+ dprint(DBG_CM, "(QP%d): Desired IB QP state: %s\n",
+ QP_ID(qp), ib_qp_state_to_string[attr->qp_state]);
+
+ new_attrs.state = ib_qp_state_to_siw_qp_state[attr->qp_state];
+
+ if (new_attrs.state > SIW_QP_STATE_RTS)
+ qp->tx_ctx.tx_suspend = 1;
+
+ /* TODO: SIW_QP_STATE_UNDEF is currently not possible ... */
+ if (new_attrs.state == SIW_QP_STATE_UNDEF)
+ return -EINVAL;
+
+ siw_attr_mask |= SIW_QP_ATTR_STATE;
+ }
+ if (!attr_mask)
+ goto out;
+
+ down_write(&qp->state_lock);
+
+ rv = siw_qp_modify(qp, &new_attrs, siw_attr_mask);
+
+ up_write(&qp->state_lock);
+
+out:
+ dprint(DBG_CM, "(QP%d): Exit with %d\n", QP_ID(qp), rv);
+ return rv;
+}
+
+int siw_destroy_qp(struct ib_qp *ofa_qp)
+{
+ struct siw_qp *qp = siw_qp_ofa2siw(ofa_qp);
+ struct siw_qp_attrs qp_attrs;
+
+ dprint(DBG_CM, "(QP%d): SIW QP state=%d, cep=0x%p\n",
+ QP_ID(qp), qp->attrs.state, qp->cep);
+
+ /*
+ * Mark QP as in process of destruction to prevent from eventual async
+ * callbacks to OFA core
+ */
+ qp->attrs.flags |= SIW_QP_IN_DESTROY;
+ qp->rx_ctx.rx_suspend = 1;
+
+ down_write(&qp->state_lock);
+
+ qp_attrs.state = SIW_QP_STATE_ERROR;
+ (void)siw_qp_modify(qp, &qp_attrs, SIW_QP_ATTR_STATE);
+
+ up_write(&qp->state_lock);
+
+ if (qp->cep) {
+ siw_cep_put(qp->cep);
+ qp->cep = NULL;
+ }
+
+ if (qp->rx_ctx.crc_enabled)
+ crypto_free_hash(qp->rx_ctx.mpa_crc_hd.tfm);
+ if (qp->tx_ctx.crc_enabled)
+ crypto_free_hash(qp->tx_ctx.mpa_crc_hd.tfm);
+
+ /* Drop references */
+ siw_cq_put(qp->scq);
+ siw_cq_put(qp->rcq);
+ siw_pd_put(qp->pd);
+ qp->scq = qp->rcq = NULL;
+
+ siw_qp_put(qp);
+
+ return 0;
+}
+
+/*
+ * siw_copy_sgl()
+ *
+ * Copy SGL from user (OFA) representation to local
+ * representation.
+ * Memory lookup and base+bounds checks must
+ * be deferred until wqe gets executed
+ */
+static int siw_copy_sgl(struct ib_sge *ofa_sge, struct siw_sge *siw_sge,
+ int num_sge)
+{
+ int bytes = 0;
+
+ while (num_sge--) {
+ siw_sge->addr = ofa_sge->addr;
+ siw_sge->len = ofa_sge->length;
+ siw_sge->lkey = ofa_sge->lkey;
+ /*
+ * defer memory lookup to WQE processing
+ */
+ siw_sge->mem.obj = NULL;
+
+ bytes += siw_sge->len;
+ siw_sge++; ofa_sge++;
+ }
+ return bytes;
+}
+
+/*
+ * siw_copy_inline_sgl()
+ *
+ * Prepare sgl of inlined data for sending.
+ * User provided sgl with unregistered user buffers. The function checks
+ * if the given buffer addresses and len's are within process context
+ * bounds and copies data into one kernel buffer. This implies dual copy
+ * operation in the tx path since TCP will make another copy for
+ * retransmission. There is room for efficiency improvement.
+ */
+static int siw_copy_inline_sgl(struct ib_sge *ofa_sge, struct siw_sge *siw_sge,
+ int num_sge)
+{
+ char *kbuf;
+ int i, bytes;
+
+ siw_sge->mem.buf = NULL;
+
+ for (i = 0, bytes = 0; i < num_sge; i++)
+ bytes += ofa_sge[i].length;
+
+ if (unlikely(bytes > SIW_MAX_INLINE)) {
+ bytes = -EINVAL;
+ goto out;
+ }
+ if (unlikely(!bytes))
+ goto out;
+
+ kbuf = kmalloc(bytes, GFP_KERNEL);
+ if (unlikely(!kbuf)) {
+ dprint(DBG_ON, " kmalloc\n");
+ bytes = -ENOMEM;
+ goto out;
+ }
+ siw_sge->mem.buf = kbuf;
+ siw_sge->addr = (u64)kbuf;
+
+ while (num_sge--) {
+ if (!access_ok(VERIFY_READ, (char __user *)ofa_sge->addr,
+ ofa_sge->length)) {
+ bytes = -EFAULT;
+ break;
+ }
+ if (__copy_from_user(kbuf, (char __user *)ofa_sge->addr,
+ ofa_sge->length)) {
+ bytes = -EFAULT;
+ break;
+ }
+ kbuf += ofa_sge->length;
+ ofa_sge++;
+ }
+ if (bytes > 0) {
+ siw_sge->len = bytes;
+ siw_sge->lkey = 0;
+ } else {
+ kfree(siw_sge->mem.buf);
+ siw_sge->mem.buf = NULL;
+ }
+out:
+ return bytes;
+}
+
+/*
+ * siw_wqe_alloc()
+ *
+ * Get new Send or Receive Queue WQE.
+ *
+ * To avoid blocking operation, kernel level clients get WQE's from
+ * QP private freelist. To minimize resource pre-allocation, user
+ * level clients get WQE's are kmalloc'ed.
+ */
+static inline struct siw_wqe *siw_wqe_alloc(struct siw_qp *qp,
+ enum siw_wr_opcode op)
+{
+ struct siw_wqe *wqe = NULL;
+ atomic_t *q_space;
+
+ q_space = (op == SIW_WR_RECEIVE) ? &qp->rq_space : &qp->sq_space;
+
+ if (atomic_dec_return(q_space) < 0)
+ goto out;
+
+ if (qp->attrs.flags & SIW_KERNEL_VERBS)
+ wqe = siw_freeq_wqe_get(qp);
+ else {
+ wqe = kmalloc(sizeof(struct siw_wqe), GFP_KERNEL);
+ SIW_INC_STAT_WQE;
+ }
+out:
+ if (wqe) {
+ INIT_LIST_HEAD(&wqe->list);
+ wqe->processed = 0;
+ siw_qp_get(qp);
+ wqe->qp = qp;
+ } else
+ atomic_inc(q_space);
+
+ return wqe;
+}
+
+/*
+ * siw_post_send()
+ *
+ * Post a list of S-WR's to a SQ.
+ *
+ * @ofa_qp: OFA QP contained in siw QP
+ * @wr: Null terminated list of user WR's
+ * @bad_wr: Points to failing WR in case of synchronous failure.
+ */
+int siw_post_send(struct ib_qp *ofa_qp, struct ib_send_wr *wr,
+ struct ib_send_wr **bad_wr)
+{
+ struct siw_wqe *wqe = NULL;
+ struct siw_qp *qp = siw_qp_ofa2siw(ofa_qp);
+
+ unsigned long flags;
+ int rv = 0;
+
+ dprint(DBG_WR|DBG_TX, "(QP%d): state=%d\n",
+ QP_ID(qp), qp->attrs.state);
+
+ /*
+ * Try to acquire QP state lock. Must be non-blocking
+ * to accommodate kernel clients needs.
+ */
+ if (!down_read_trylock(&qp->state_lock)) {
+ *bad_wr = wr;
+ return -ENOTCONN;
+ }
+
+ if (qp->attrs.state != SIW_QP_STATE_RTS) {
+ dprint(DBG_WR|DBG_ON, "(QP%d): state=%d\n",
+ QP_ID(qp), qp->attrs.state);
+ up_read(&qp->state_lock);
+ *bad_wr = wr;
+ return -ENOTCONN;
+ }
+ dprint(DBG_WR|DBG_TX, "(QP%d): sq_space(#1)=%d\n",
+ QP_ID(qp), atomic_read(&qp->sq_space));
+
+ while (wr) {
+ wqe = siw_wqe_alloc(qp, opcode_ofa2siw(wr->opcode));
+ if (!wqe) {
+ dprint(DBG_ON, " siw_wqe_alloc\n");
+ rv = -ENOMEM;
+ break;
+ }
+ if (wr->num_sge > qp->attrs.sq_max_sges) {
+ /*
+ * NOTE: we allow for zero length wr's here.
+ */
+ dprint(DBG_WR, "(QP%d): Num SGE: %d\n",
+ QP_ID(qp), wr->num_sge);
+ rv = -EINVAL;
+ break;
+ }
+ wr_type(wqe) = opcode_ofa2siw(wr->opcode);
+ wr_flags(wqe) = wr->send_flags;
+ wr_id(wqe) = wr->wr_id;
+
+ if (SIW_INLINED_DATA(wqe)) {
+ dprint(DBG_WR, "(QP%d): INLINE DATA\n", QP_ID(qp));
+ if (unlikely(qp->attrs.flags & SIW_KERNEL_VERBS)) {
+ dprint(DBG_ON|DBG_WR,
+ "(QP%d): Kernel verbs: No INLINE\n",
+ QP_ID(qp));
+ rv = -EINVAL;
+ break;
+ }
+ }
+
+ switch (wr->opcode) {
+
+ case IB_WR_SEND:
+ if (!SIW_INLINED_DATA(wqe)) {
+ rv = siw_copy_sgl(wr->sg_list,
+ wqe->wr.send.sge,
+ wr->num_sge);
+ wqe->wr.send.num_sge = wr->num_sge;
+ } else {
+ rv = siw_copy_inline_sgl(wr->sg_list,
+ wqe->wr.send.sge,
+ wr->num_sge);
+ wqe->wr.send.num_sge = 1;
+ }
+ if (rv <= 0) {
+ rv = -EINVAL;
+ break;
+ }
+ wqe->bytes = rv;
+ break;
+
+ case IB_WR_RDMA_READ:
+ /*
+ * OFED WR restricts RREAD sink to SGL containing
+ * 1 SGE only. we could relax to SGL with multiple
+ * elements referring the SAME ltag or even sending
+ * a private per-rreq tag referring to a checked
+ * local sgl with MULTIPLE ltag's. would be easy
+ * to do...
+ */
+ if (wr->num_sge != 1) {
+ rv = -EINVAL;
+ break;
+ }
+ rv = siw_copy_sgl(wr->sg_list, wqe->wr.rread.sge, 1);
+ /*
+ * NOTE: zero length RREAD is allowed!
+ */
+ wqe->wr.rread.raddr = wr->wr.rdma.remote_addr;
+ wqe->wr.rread.rtag = wr->wr.rdma.rkey;
+ wqe->wr.rread.num_sge = 1;
+ wqe->bytes = rv;
+ break;
+
+ case IB_WR_RDMA_WRITE:
+ if (!SIW_INLINED_DATA(wqe)) {
+ rv = siw_copy_sgl(wr->sg_list,
+ wqe->wr.send.sge,
+ wr->num_sge);
+ wqe->wr.write.num_sge = wr->num_sge;
+ } else {
+ rv = siw_copy_inline_sgl(wr->sg_list,
+ wqe->wr.send.sge,
+ wr->num_sge);
+ wqe->wr.write.num_sge = min(1, wr->num_sge);
+ }
+ /*
+ * NOTE: zero length WRITE is allowed!
+ */
+ if (rv < 0) {
+ rv = -EINVAL;
+ break;
+ }
+ wqe->wr.write.raddr = wr->wr.rdma.remote_addr;
+ wqe->wr.write.rtag = wr->wr.rdma.rkey;
+ wqe->bytes = rv;
+ break;
+
+ default:
+ dprint(DBG_WR|DBG_TX|DBG_ON,
+ "(QP%d): Opcode %d not yet implemented\n",
+ QP_ID(qp), wr->opcode);
+ wqe->wr.sgl.num_sge = 0;
+ rv = -EINVAL;
+ break;
+ }
+ dprint(DBG_WR|DBG_TX, "(QP%d): opcode %d, bytes %d, "
+ "flags 0x%x\n",
+ QP_ID(qp), wr_type(wqe), wqe->bytes,
+ wr_flags(wqe));
+ if (rv < 0)
+ break;
+
+ wqe->wr_status = SR_WR_QUEUED;
+
+ lock_sq_rxsave(qp, flags);
+ list_add_tail(&wqe->list, &qp->sq);
+ unlock_sq_rxsave(qp, flags);
+
+ wr = wr->next;
+ }
+ /*
+ * Send directly if SQ processing is not in progress.
+ * Eventual immediate errors (rv < 0) do not affect the involved
+ * RI resources (Verbs, 8.3.1) and thus do not prevent from SQ
+ * processing, if new work is already pending. But rv must be passed
+ * to caller.
+ */
+ lock_sq_rxsave(qp, flags);
+ if (tx_wqe(qp) == NULL) {
+ struct siw_wqe *next = siw_next_tx_wqe(qp);
+ if (next != NULL) {
+ if (wr_type(next) != SIW_WR_RDMA_READ_REQ ||
+ !ORD_SUSPEND_SQ(qp)) {
+ tx_wqe(qp) = next;
+ if (wr_type(next) != SIW_WR_RDMA_READ_REQ)
+ list_del_init(&next->list);
+ else
+ siw_rreq_queue(next, qp);
+
+ unlock_sq_rxsave(qp, flags);
+
+ dprint(DBG_WR|DBG_TX,
+ "(QP%d): Direct sending...\n",
+ QP_ID(qp));
+
+ if (qp->attrs.flags & SIW_KERNEL_VERBS)
+ siw_sq_queue_work(qp);
+ else if (siw_qp_sq_process(qp, 1) != 0 &&
+ !(qp->tx_ctx.tx_suspend))
+ siw_qp_cm_drop(qp, 0);
+ } else
+ unlock_sq_rxsave(qp, flags);
+ } else
+ unlock_sq_rxsave(qp, flags);
+ } else
+ unlock_sq_rxsave(qp, flags);
+
+ up_read(&qp->state_lock);
+
+ dprint(DBG_WR|DBG_TX, "(QP%d): sq_space(#2)=%d\n", QP_ID(qp),
+ atomic_read(&qp->sq_space));
+ if (rv >= 0)
+ return 0;
+ /*
+ * Immediate error
+ */
+ dprint(DBG_WR|DBG_ON, "(QP%d): error=%d\n", QP_ID(qp), rv);
+
+ if (wqe != NULL)
+ siw_wqe_put(wqe);
+ *bad_wr = wr;
+ return rv;
+}
+
+/*
+ * siw_post_receive()
+ *
+ * Post a list of R-WR's to a RQ.
+ *
+ * @ofa_qp: OFA QP contained in siw QP
+ * @wr: Null terminated list of user WR's
+ * @bad_wr: Points to failing WR in case of synchronous failure.
+ */
+int siw_post_receive(struct ib_qp *ofa_qp, struct ib_recv_wr *wr,
+ struct ib_recv_wr **bad_wr)
+{
+ struct siw_wqe *wqe = NULL;
+ struct siw_qp *qp = siw_qp_ofa2siw(ofa_qp);
+ unsigned long flags;
+ int rv = 0;
+
+ dprint(DBG_WR|DBG_TX, "(QP%d): state=%d\n", QP_ID(qp),
+ qp->attrs.state);
+
+ if (qp->srq)
+ return -EOPNOTSUPP; /* what else from errno.h? */
+ /*
+ * Try to acquire QP state lock. Must be non-blocking
+ * to accommodate kernel clients needs.
+ */
+ if (!down_read_trylock(&qp->state_lock)) {
+ *bad_wr = wr;
+ return -ENOTCONN;
+ }
+
+ if (qp->attrs.state > SIW_QP_STATE_RTS) {
+ up_read(&qp->state_lock);
+ dprint(DBG_ON, " (QP%d): state=%d\n", QP_ID(qp),
+ qp->attrs.state);
+ return -EINVAL;
+ }
+ while (wr) {
+ wqe = siw_wqe_alloc(qp, SIW_WR_RECEIVE);
+ if (!wqe) {
+ rv = -ENOMEM;
+ break;
+ }
+ if (wr->num_sge > qp->attrs.rq_max_sges) {
+ dprint(DBG_WR|DBG_ON, "(QP%d): Num SGE: %d\n",
+ QP_ID(qp), wr->num_sge);
+ rv = -EINVAL;
+ break;
+ }
+ wr_type(wqe) = SIW_WR_RECEIVE;
+ wr_id(wqe) = wr->wr_id;
+
+ rv = siw_copy_sgl(wr->sg_list, wqe->wr.recv.sge, wr->num_sge);
+ if (rv < 0) {
+ /*
+ * XXX tentatively allow zero length receive
+ */
+ rv = -EINVAL;
+ break;
+ }
+ wqe->wr.recv.num_sge = wr->num_sge;
+ wqe->bytes = rv;
+ wqe->wr_status = SR_WR_QUEUED;
+
+ lock_rq_rxsave(qp, flags);
+ list_add_tail(&wqe->list, &qp->rq);
+ unlock_rq_rxsave(qp, flags);
+
+ wr = wr->next;
+ }
+ if (rv <= 0) {
+ dprint(DBG_WR|DBG_ON, "(QP%d): error=%d\n", QP_ID(qp), rv);
+ if (wqe != NULL)
+ siw_wqe_put(wqe);
+ *bad_wr = wr;
+ }
+ dprint(DBG_WR|DBG_RX, "(QP%d): rq_space=%d\n", QP_ID(qp),
+ atomic_read(&qp->rq_space));
+
+ up_read(&qp->state_lock);
+
+ return rv > 0 ? 0 : rv;
+}
+
+int siw_destroy_cq(struct ib_cq *ofa_cq)
+{
+ struct siw_cq *cq = siw_cq_ofa2siw(ofa_cq);
+ struct ib_device *ofa_dev = ofa_cq->device;
+ struct siw_dev *dev = siw_dev_ofa2siw(ofa_dev);
+
+ siw_cq_flush(cq);
+
+ siw_remove_obj(&dev->idr_lock, &dev->cq_idr, &cq->hdr);
+ siw_cq_put(cq);
+
+ return 0;
+}
+
+/*
+ * siw_create_cq()
+ *
+ * Create CQ of requested size on given device.
+ *
+ * @ofa_dev: OFA device contained in siw device
+ * @size: maximum number of CQE's allowed.
+ * @ib_context: user context.
+ * @udata: used to provide CQ ID back to user.
+ */
+
+struct ib_cq *siw_create_cq(struct ib_device *ofa_dev, int size,
+ int vec /* unused */,
+ struct ib_ucontext *ib_context,
+ struct ib_udata *udata)
+{
+ struct siw_cq *cq = NULL;
+ struct siw_dev *dev = siw_dev_ofa2siw(ofa_dev);
+ struct siw_uresp_create_cq uresp;
+ int rv;
+
+ if (atomic_inc_return(&dev->num_cq) > SIW_MAX_CQ) {
+ dprint(DBG_ON, ": Out of CQ's\n");
+ rv = -ENOMEM;
+ goto err_out;
+ }
+ if (size < 1 || size > SIW_MAX_CQE) {
+ dprint(DBG_ON, ": CQE: %d\n", size);
+ rv = -EINVAL;
+ goto err_out;
+ }
+ cq = kmalloc(sizeof *cq, GFP_KERNEL);
+ if (!cq) {
+ dprint(DBG_ON, ": kmalloc\n");
+ rv = -ENOMEM;
+ goto err_out;
+ }
+ cq->ofa_cq.cqe = size - 1;
+
+ rv = siw_cq_add(dev, cq);
+ if (rv)
+ goto err_out_idr;
+
+ INIT_LIST_HEAD(&cq->queue);
+ spin_lock_init(&cq->lock);
+ atomic_set(&cq->qlen, 0);
+
+ if (ib_context) {
+ uresp.cq_id = OBJ_ID(cq);
+
+ rv = ib_copy_to_udata(udata, &uresp, sizeof uresp);
+ if (rv)
+ goto err_out_idr;
+ }
+ return &cq->ofa_cq;
+
+err_out_idr:
+ siw_remove_obj(&dev->idr_lock, &dev->cq_idr, &cq->hdr);
+err_out:
+ dprint(DBG_OBJ, ": CQ creation failed\n");
+
+ kfree(cq);
+ atomic_dec(&dev->num_cq);
+
+ return ERR_PTR(rv);
+}
+
+/*
+ * siw_poll_cq()
+ *
+ * Reap CQ entries if available and copy work completion status into
+ * array of WC's provided by caller. Returns number of reaped CQE's.
+ *
+ * @ofa_cq: OFA CQ contained in siw CQ.
+ * @num_cqe: Maximum number of CQE's to reap.
+ * @wc: Array of work completions to be filled by siw.
+ */
+int siw_poll_cq(struct ib_cq *ofa_cq, int num_cqe, struct ib_wc *wc)
+{
+ struct siw_cq *cq = siw_cq_ofa2siw(ofa_cq);
+ int i;
+
+ for (i = 0; i < num_cqe; i++) {
+ if (!(siw_reap_cqe(cq, wc)))
+ break;
+ wc++;
+ }
+ dprint(DBG_WR, " CQ%d: reap %d completions (%d left)\n",
+ OBJ_ID(cq), i, atomic_read(&cq->qlen));
+
+ return i;
+}
+
+/*
+ * siw_req_notify_cq()
+ *
+ * Request notification for new CQE's added to that CQ.
+ * Defined flags:
+ * o SIW_CQ_NOTIFY_SOLICITED lets siw trigger a notification
+ * event if a WQE with notification flag set enters the CQ
+ * o SIW_CQ_NOTIFY_NEXT_COMP lets siw trigger a notification
+ * event if a WQE enters the CQ.
+ * o IB_CQ_REPORT_MISSED_EVENTS: return value will provide the
+ * number of not reaped CQE's regardless of its notification
+ * type and current or new CQ notification settings.
+ *
+ * @ofa_cq: OFA CQ contained in siw CQ.
+ * @flags: Requested notification flags.
+ */
+int siw_req_notify_cq(struct ib_cq *ofa_cq, enum ib_cq_notify_flags flags)
+{
+ struct siw_cq *cq = siw_cq_ofa2siw(ofa_cq);
+
+ dprint(DBG_EH, "(CQ%d:) flags: 0x%8x\n", OBJ_ID(cq), flags);
+
+ if ((flags & IB_CQ_SOLICITED_MASK) == IB_CQ_SOLICITED)
+ cq->notify = SIW_CQ_NOTIFY_SOLICITED;
+ else
+ cq->notify = SIW_CQ_NOTIFY_ALL;
+
+ if (flags & IB_CQ_REPORT_MISSED_EVENTS)
+ return atomic_read(&cq->qlen);
+
+ return 0;
+}
+
+/*
+ * siw_dereg_mr()
+ *
+ * Release Memory Region.
+ *
+ * TODO: Update function if Memory Windows are supported by siw:
+ * Is OFED core checking for MW dependencies for current
+ * MR before calling MR deregistration?.
+ *
+ * @ofa_mr: OFA MR contained in siw MR.
+ */
+int siw_dereg_mr(struct ib_mr *ofa_mr)
+{
+ struct siw_mr *mr;
+ struct siw_dev *dev = siw_dev_ofa2siw(ofa_mr->device);
+
+ mr = siw_mr_ofa2siw(ofa_mr);
+
+ dprint(DBG_OBJ|DBG_MM, "(MEM%d): Release UMem %p, #ref's: %d\n",
+ mr->mem.hdr.id, mr->umem,
+ atomic_read(&mr->mem.hdr.ref.refcount));
+
+ mr->mem.stag_state = STAG_INVALID;
+
+ siw_pd_put(mr->pd);
+ siw_remove_obj(&dev->idr_lock, &dev->mem_idr, &mr->mem.hdr);
+ siw_mem_put(&mr->mem);
+
+ return 0;
+}
+
+static struct siw_mr *siw_alloc_mr(struct siw_dev *dev, struct ib_umem *umem,
+ u64 start, u64 len, int rights)
+{
+ struct siw_mr *mr = kzalloc(sizeof *mr, GFP_KERNEL);
+ if (!mr)
+ return NULL;
+
+ mr->mem.stag_state = STAG_INVALID;
+
+ if (siw_mem_add(dev, &mr->mem) < 0) {
+ dprint(DBG_ON, ": siw_mem_add\n");
+ kfree(mr);
+ return NULL;
+ }
+ dprint(DBG_OBJ|DBG_MM, "(MEM%d): New Object, UMEM %p\n",
+ mr->mem.hdr.id, umem);
+
+ mr->ofa_mr.lkey = mr->ofa_mr.rkey = mr->mem.hdr.id << 8;
+
+ mr->mem.va = start;
+ mr->mem.len = len;
+ mr->mem.fbo = 0 ;
+ mr->mem.mr = NULL;
+ mr->mem.perms = SR_MEM_LREAD | /* not selectable in OFA */
+ (rights & IB_ACCESS_REMOTE_READ ? SR_MEM_RREAD : 0) |
+ (rights & IB_ACCESS_LOCAL_WRITE ? SR_MEM_LWRITE : 0) |
+ (rights & IB_ACCESS_REMOTE_WRITE ? SR_MEM_RWRITE : 0);
+
+ mr->umem = umem;
+
+ return mr;
+}
+
+/*
+ * siw_reg_user_mr()
+ *
+ * Register Memory Region.
+ *
+ * @ofa_pd: OFA PD contained in siw PD.
+ * @start: starting address of MR (virtual address)
+ * @len: len of MR
+ * @rnic_va: not used by siw
+ * @rights: MR access rights
+ * @udata: user buffer to communicate STag and Key.
+ */
+struct ib_mr *siw_reg_user_mr(struct ib_pd *ofa_pd, u64 start, u64 len,
+ u64 rnic_va, int rights, struct ib_udata *udata)
+{
+ struct siw_mr *mr = NULL;
+ struct siw_pd *pd = siw_pd_ofa2siw(ofa_pd);
+ struct ib_umem *umem = NULL;
+ struct siw_ureq_reg_mr ureq;
+ struct siw_uresp_reg_mr uresp;
+ struct siw_dev *dev = pd->hdr.dev;
+
+ int mem_limit = rlimit(RLIMIT_MEMLOCK);
+ int rv;
+
+ dprint(DBG_MM|DBG_OBJ, " start: 0x%016llx, "
+ "va: 0x%016llx, len: %llu, ctx: %p\n",
+ (unsigned long long)start,
+ (unsigned long long)rnic_va,
+ (unsigned long long)len,
+ ofa_pd->uobject->context);
+ if (atomic_inc_return(&dev->num_mem) > SIW_MAX_MR) {
+ dprint(DBG_ON, ": Out of MRs: %d\n",
+ atomic_read(&dev->num_mem));
+ rv = -ENOMEM;
+ goto err_out;
+ }
+ if (!len) {
+ rv = -EINVAL;
+ goto err_out;
+ }
+ if (mem_limit != RLIM_INFINITY) {
+ int num_pages =
+ (PAGE_ALIGN(len + (start & ~PAGE_MASK))) >> PAGE_SHIFT;
+ mem_limit >>= PAGE_SHIFT;
+
+ if (num_pages > mem_limit - current->mm->locked_vm) {
+ dprint(DBG_ON|DBG_MM,
+ ": rlimit: req: %d, limit: %d, locked: %lu\n",
+ num_pages, mem_limit, current->mm->locked_vm);
+ rv = -ENOMEM;
+ goto err_out;
+ }
+ }
+ umem = ib_umem_get(ofa_pd->uobject->context, start, len, rights, 0);
+ if (IS_ERR(umem)) {
+ dprint(DBG_MM, " ib_umem_get:%ld LOCKED:%lu, LIMIT:%lu\n",
+ PTR_ERR(umem), current->mm->locked_vm,
+ current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur >>
+ PAGE_SHIFT);
+ rv = -PTR_ERR(umem);
+ umem = NULL;
+ goto err_out;
+ }
+ mr = siw_alloc_mr(dev, umem, start, len, rights);
+ if (!mr) {
+ rv = -ENOMEM;
+ goto err_out;
+ }
+
+ if (udata) {
+ rv = ib_copy_from_udata(&ureq, udata, sizeof ureq);
+ if (rv)
+ goto err_out_mr;
+
+ mr->ofa_mr.lkey |= ureq.stag_key;
+ mr->ofa_mr.rkey |= ureq.stag_key; /* XXX ??? */
+ uresp.stag = mr->ofa_mr.lkey;
+
+ rv = ib_copy_to_udata(udata, &uresp, sizeof uresp);
+ if (rv)
+ goto err_out_mr;
+ }
+ mr->pd = pd;
+ siw_pd_get(pd);
+
+ mr->mem.stag_state = STAG_VALID;
+
+ return &mr->ofa_mr;
+
+err_out_mr:
+ siw_remove_obj(&dev->idr_lock, &dev->mem_idr, &mr->mem.hdr);
+ kfree(mr);
+
+err_out:
+ if (umem)
+ ib_umem_release(umem);
+
+ atomic_dec(&dev->num_mem);
+
+ return ERR_PTR(rv);
+}
+
+
+/*
+ * siw_get_dma_mr()
+ *
+ * Create a (empty) DMA memory region, where no umem is attached.
+ * All DMA addresses are created via siw_dma_mapping_ops - which
+ * will return just kernel virtual addresses, since siw runs on top
+ * of TCP kernel sockets.
+ */
+struct ib_mr *siw_get_dma_mr(struct ib_pd *ofa_pd, int rights)
+{
+ struct siw_mr *mr;
+ struct siw_pd *pd = siw_pd_ofa2siw(ofa_pd);
+ struct siw_dev *dev = pd->hdr.dev;
+ int rv;
+
+ if (atomic_inc_return(&dev->num_mem) > SIW_MAX_MR) {
+ dprint(DBG_ON, ": Out of MRs: %d\n",
+ atomic_read(&dev->num_mem));
+ rv = -ENOMEM;
+ goto err_out;
+ }
+ mr = siw_alloc_mr(dev, NULL, 0, ULONG_MAX, rights);
+ if (!mr) {
+ rv = -ENOMEM;
+ goto err_out;
+ }
+ mr->mem.stag_state = STAG_VALID;
+
+ mr->pd = pd;
+ siw_pd_get(pd);
+
+ return &mr->ofa_mr;
+
+err_out:
+ atomic_dec(&dev->num_mem);
+
+ return ERR_PTR(rv);
+}
+
+
+/*
+ * siw_create_srq()
+ *
+ * Create Shared Receive Queue of attributes @init_attrs
+ * within protection domain given by @ofa_pd.
+ *
+ * @ofa_pd: OFA PD contained in siw PD.
+ * @init_attrs: SRQ init attributes.
+ * @udata: not used by siw.
+ */
+struct ib_srq *siw_create_srq(struct ib_pd *ofa_pd,
+ struct ib_srq_init_attr *init_attrs,
+ struct ib_udata *udata)
+{
+ struct siw_srq *srq = NULL;
+ struct ib_srq_attr *attrs = &init_attrs->attr;
+ struct siw_pd *pd = siw_pd_ofa2siw(ofa_pd);
+ struct siw_dev *dev = pd->hdr.dev;
+ struct siw_wqe *wqe;
+
+ int kernel_verbs = ofa_pd->uobject ? 0 : 1;
+ int rv;
+
+ if (atomic_inc_return(&dev->num_srq) > SIW_MAX_SRQ) {
+ dprint(DBG_ON, " Out of SRQ's\n");
+ rv = -ENOMEM;
+ goto err_out;
+ }
+ if (attrs->max_wr > SIW_MAX_SRQ_WR || attrs->max_sge > SIW_MAX_SGE ||
+ attrs->srq_limit > attrs->max_wr) {
+ rv = -EINVAL;
+ goto err_out;
+ }
+
+ srq = kzalloc(sizeof *srq, GFP_KERNEL);
+ if (!srq) {
+ dprint(DBG_ON, " malloc\n");
+ rv = -ENOMEM;
+ goto err_out;
+ }
+ INIT_LIST_HEAD(&srq->rq);
+ INIT_LIST_HEAD(&srq->freeq);
+ srq->max_sge = attrs->max_sge;
+ atomic_set(&srq->space, attrs->max_wr);
+ srq->limit = attrs->srq_limit;
+ srq->max_wr = attrs->max_wr;
+ if (srq->limit)
+ srq->armed = 1;
+
+
+ if (kernel_verbs) {
+ int num_wqe = attrs->max_wr;
+ spin_lock_init(&srq->freeq_lock);
+ srq->kernel_verbs = 1;
+ while (num_wqe--) {
+ wqe = kzalloc(sizeof(struct siw_wqe), GFP_KERNEL);
+ if (!wqe) {
+ rv = -ENOMEM;
+ goto err_out;
+ }
+ INIT_LIST_HEAD(&wqe->list);
+ list_add(&wqe->list, &srq->freeq);
+ }
+ }
+ srq->pd = pd;
+ siw_pd_get(pd);
+
+ spin_lock_init(&srq->lock);
+
+ return &srq->ofa_srq;
+
+err_out:
+ if (srq)
+ siw_drain_wq(&srq->freeq);
+
+ kfree(srq);
+ atomic_dec(&dev->num_srq);
+
+ return ERR_PTR(rv);
+}
+
+/*
+ * siw_modify_srq()
+ *
+ * Modify SRQ. The caller may resize SRQ and/or set/reset notification
+ * limit and (re)arm IB_EVENT_SRQ_LIMIT_REACHED notification.
+ *
+ * NOTE: it is unclear if OFA allows for changing the MAX_SGE
+ * parameter. siw_modify_srq() does not check the attrs->max_sge param.
+ */
+int siw_modify_srq(struct ib_srq *ofa_srq, struct ib_srq_attr *attrs,
+ enum ib_srq_attr_mask attr_mask, struct ib_udata *udata)
+{
+ struct siw_srq *srq = siw_srq_ofa2siw(ofa_srq);
+ unsigned long flags;
+ int rv = 0;
+
+ lock_srq_rxsave(srq, flags);
+
+ if (attr_mask & IB_SRQ_MAX_WR) {
+ /* resize request */
+ if (attrs->max_wr > SIW_MAX_SRQ_WR) {
+ rv = -EINVAL;
+ goto out;
+ }
+ if (attrs->max_wr < srq->max_wr) {
+ /* shrink */
+ if (attrs->max_wr <
+ srq->max_wr - atomic_read(&srq->space)) {
+ rv = -EBUSY;
+ goto out;
+ }
+ atomic_sub(srq->max_wr - attrs->max_wr, &srq->space);
+ } else /* grow */
+ atomic_add(attrs->max_wr - srq->max_wr, &srq->space);
+ srq->max_wr = attrs->max_wr;
+ }
+ if (attr_mask & IB_SRQ_LIMIT) {
+ if (attrs->srq_limit) {
+ if (attrs->srq_limit > srq->max_wr) {
+ rv = -EINVAL;
+ /* FIXME: restore old space & max_wr?? */
+ goto out;
+ }
+ srq->armed = 1;
+ } else
+ srq->armed = 0;
+
+ srq->limit = attrs->srq_limit;
+ }
+out:
+ unlock_srq_rxsave(srq, flags);
+ return rv;
+}
+
+/*
+ * siw_query_srq()
+ *
+ * Query SRQ attributes.
+ */
+int siw_query_srq(struct ib_srq *ofa_srq, struct ib_srq_attr *attrs)
+{
+ struct siw_srq *srq = siw_srq_ofa2siw(ofa_srq);
+ unsigned long flags;
+
+ lock_srq_rxsave(srq, flags);
+
+ attrs->max_wr = srq->max_wr;
+ attrs->max_sge = srq->max_sge;
+ attrs->srq_limit = srq->limit;
+
+ unlock_srq_rxsave(srq, flags);
+
+ return 0;
+}
+
+/*
+ * siw_destroy_srq()
+ *
+ * Destroy SRQ.
+ * It is assumed that the SRQ is not referenced by any
+ * QP anymore - the code trusts the OFA environment to keep track
+ * of QP references.
+ */
+int siw_destroy_srq(struct ib_srq *ofa_srq)
+{
+ struct siw_srq *srq = siw_srq_ofa2siw(ofa_srq);
+ struct siw_dev *dev = srq->pd->hdr.dev;
+
+ siw_drain_wq(&srq->rq);
+ siw_drain_wq(&srq->freeq);
+
+ siw_pd_put(srq->pd);
+
+ kfree(srq);
+ atomic_dec(&dev->num_srq);
+
+ return 0;
+}
+
+static inline struct siw_wqe *siw_srq_wqe_alloc(struct siw_srq *srq)
+{
+ struct siw_wqe *wqe = NULL;
+
+ if (atomic_dec_return(&srq->space) < 0)
+ goto out;
+
+ if (srq->kernel_verbs) {
+ unsigned long flags;
+ spin_lock_irqsave(&srq->freeq_lock, flags);
+ if (!list_empty(&srq->freeq)) {
+ wqe = list_first_wqe(&srq->freeq);
+ list_del(&wqe->list);
+ }
+ spin_unlock_irqrestore(&srq->freeq_lock, flags);
+ } else {
+ wqe = kzalloc(sizeof(struct siw_wqe), GFP_KERNEL);
+ SIW_INC_STAT_WQE;
+ }
+
+ dprint(DBG_OBJ|DBG_WR, "(SRQ%p): New WQE p: %p\n", srq, wqe);
+out:
+ if (wqe) {
+ INIT_LIST_HEAD(&wqe->list);
+ wqe->processed = 0;
+ } else
+ atomic_inc(&srq->space);
+
+ return wqe;
+}
+
+/*
+ * siw_post_srq_recv()
+ *
+ * Post a list of receive queue elements to SRQ.
+ * NOTE: The function does not check or lock a certain SRQ state
+ * during the post operation. The code simply trusts the
+ * OFA environment.
+ *
+ * @ofa_srq: OFA SRQ contained in siw SRQ
+ * @wr: List of R-WR's
+ * @bad_wr: Updated to failing WR if posting fails.
+ */
+int siw_post_srq_recv(struct ib_srq *ofa_srq, struct ib_recv_wr *wr,
+ struct ib_recv_wr **bad_wr)
+{
+ struct siw_srq *srq = siw_srq_ofa2siw(ofa_srq);
+ struct siw_wqe *wqe = NULL;
+ unsigned long flags;
+ int rv = 0;
+
+ while (wr) {
+ wqe = siw_srq_wqe_alloc(srq);
+ if (!wqe) {
+ dprint(DBG_ON, " siw_srq_wqe_alloc\n");
+ rv = -ENOMEM;
+ break;
+ }
+ if (!wr->num_sge || wr->num_sge > srq->max_sge) {
+ dprint(DBG_WR|DBG_ON,
+ "(SRQ%p): Num SGE: %d\n", srq, wr->num_sge);
+ rv = -EINVAL;
+ break;
+ }
+ wr_type(wqe) = SIW_WR_RECEIVE;
+ wr_id(wqe) = wr->wr_id;
+ wqe->wr_status = SR_WR_QUEUED;
+
+ rv = siw_copy_sgl(wr->sg_list, wqe->wr.recv.sge, wr->num_sge);
+ if (rv == 0) {
+ /*
+ * do not allow zero length receive
+ * XXX correct?
+ */
+ rv = -EINVAL;
+ break;
+ }
+ wqe->wr.recv.num_sge = wr->num_sge;
+ wqe->bytes = rv;
+
+ lock_srq_rxsave(srq, flags);
+ list_add_tail(&wqe->list, &srq->rq);
+ unlock_srq_rxsave(srq, flags);
+
+ wr = wr->next;
+ }
+ if (rv <= 0) {
+ dprint(DBG_WR|DBG_ON, "(SRQ %p): error=%d\n",
+ srq, rv);
+
+ if (wqe)
+ siw_add_wqe(wqe, &srq->freeq, &srq->freeq_lock);
+
+ *bad_wr = wr;
+ }
+ dprint(DBG_WR|DBG_RX, "(SRQ%p): space=%d\n",
+ srq, atomic_read(&srq->space));
+
+ return rv > 0 ? 0 : rv;
+}
+
+
+int siw_mmap(struct ib_ucontext *ctx, struct vm_area_struct *vma)
+{
+ return -ENOSYS;
+}
diff --git a/drivers/infiniband/hw/siw/siw_verbs.h b/drivers/infiniband/hw/siw/siw_verbs.h
new file mode 100644
index 0000000..659035e
--- /dev/null
+++ b/drivers/infiniband/hw/siw/siw_verbs.h
@@ -0,0 +1,99 @@
+/*
+ * Software iWARP device driver for Linux
+ *
+ * Authors: Bernard Metzler <bmt-OA+xvbQnYDHMbYB6QlFGEg@public.gmane.org>
+ *
+ * Copyright (c) 2008-2011, IBM Corporation
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of IBM nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef _SIW_VERBS_H
+#define _SIW_VERBS_H
+
+#include <linux/errno.h>
+
+#include <rdma/iw_cm.h>
+#include <rdma/ib_verbs.h>
+#include <rdma/ib_smi.h>
+#include <rdma/ib_user_verbs.h>
+
+#include "siw.h"
+#include "siw_verbs.h"
+#include "siw_cm.h"
+
+extern int siw_query_device(struct ib_device *, struct ib_device_attr *);
+
+extern struct ib_ucontext *siw_alloc_ucontext(struct ib_device *,
+ struct ib_udata *);
+extern int siw_dealloc_ucontext(struct ib_ucontext *);
+extern int siw_query_port(struct ib_device *, u8, struct ib_port_attr *);
+extern int siw_query_pkey(struct ib_device *, u8, u16, u16 *);
+extern int siw_query_gid(struct ib_device *, u8, int, union ib_gid *);
+
+extern struct ib_pd *siw_alloc_pd(struct ib_device *, struct ib_ucontext *,
+ struct ib_udata *);
+extern int siw_dealloc_pd(struct ib_pd *);
+extern struct ib_ah *siw_create_ah(struct ib_pd *, struct ib_ah_attr *);
+extern int siw_destroy_ah(struct ib_ah *);
+extern struct ib_qp *siw_create_qp(struct ib_pd *, struct ib_qp_init_attr *,
+ struct ib_udata *);
+extern int siw_query_qp(struct ib_qp *, struct ib_qp_attr *, int,
+ struct ib_qp_init_attr *);
+extern int siw_ofed_modify_qp(struct ib_qp *, struct ib_qp_attr *, int,
+ struct ib_udata *);
+extern int siw_destroy_qp(struct ib_qp *);
+extern int siw_post_send(struct ib_qp *, struct ib_send_wr *,
+ struct ib_send_wr **);
+extern int siw_post_receive(struct ib_qp *, struct ib_recv_wr *,
+ struct ib_recv_wr **);
+extern struct ib_cq *siw_create_cq(struct ib_device *, int, int,
+ struct ib_ucontext *, struct ib_udata *);
+extern int siw_destroy_cq(struct ib_cq *);
+extern int siw_poll_cq(struct ib_cq *, int num_entries, struct ib_wc *);
+extern int siw_req_notify_cq(struct ib_cq *, enum ib_cq_notify_flags);
+extern struct ib_mr *siw_reg_user_mr(struct ib_pd *, u64, u64, u64, int,
+ struct ib_udata *);
+extern struct ib_mr *siw_get_dma_mr(struct ib_pd *, int);
+extern int siw_dereg_mr(struct ib_mr *);
+extern struct ib_srq *siw_create_srq(struct ib_pd *, struct ib_srq_init_attr *,
+ struct ib_udata *);
+extern int siw_modify_srq(struct ib_srq *, struct ib_srq_attr *,
+ enum ib_srq_attr_mask, struct ib_udata *);
+extern int siw_query_srq(struct ib_srq *, struct ib_srq_attr *);
+extern int siw_destroy_srq(struct ib_srq *);
+extern int siw_post_srq_recv(struct ib_srq *, struct ib_recv_wr *,
+ struct ib_recv_wr **);
+extern int siw_mmap(struct ib_ucontext *, struct vm_area_struct *);
+
+extern struct ib_dma_mapping_ops siw_dma_mapping_ops;
+
+#endif
--
1.5.4.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 04/14] SIWv2: Module initialization: siw_main.c
From: Bernard Metzler @ 2011-06-16 12:42 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA, Bernard Metzler
---
drivers/infiniband/hw/siw/siw_main.c | 603 ++++++++++++++++++++++++++++++++++
1 files changed, 603 insertions(+), 0 deletions(-)
create mode 100644 drivers/infiniband/hw/siw/siw_main.c
diff --git a/drivers/infiniband/hw/siw/siw_main.c b/drivers/infiniband/hw/siw/siw_main.c
new file mode 100644
index 0000000..b2b7bea
--- /dev/null
+++ b/drivers/infiniband/hw/siw/siw_main.c
@@ -0,0 +1,603 @@
+/*
+ * Software iWARP device driver for Linux
+ *
+ * Authors: Bernard Metzler <bmt-OA+xvbQnYDHMbYB6QlFGEg@public.gmane.org>
+ *
+ * Copyright (c) 2008-2011, IBM Corporation
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of IBM nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/netdevice.h>
+#include <linux/inetdevice.h>
+#include <net/net_namespace.h>
+#include <linux/rtnetlink.h>
+#include <linux/if_arp.h>
+#include <linux/list.h>
+
+#include <rdma/ib_verbs.h>
+#include <rdma/ib_smi.h>
+#include <rdma/ib_user_verbs.h>
+
+#include "siw.h"
+#include "siw_obj.h"
+#include "siw_cm.h"
+#include "siw_verbs.h"
+
+
+MODULE_DESCRIPTION("Software iWARP Driver");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_VERSION("0.1");
+
+#define SIW_MAX_IF 12
+static char *iface_list[SIW_MAX_IF];
+module_param_array(iface_list, charp, NULL, 0444);
+MODULE_PARM_DESC(iface_list, "Interface list siw attaches to if present");
+
+static bool loopback_enabled;
+module_param(loopback_enabled, bool, 0644);
+MODULE_PARM_DESC(loopback_enabled, "enable_loopback");
+
+atomic_t siw_num_wqe;
+atomic_t siw_num_cep;
+
+static LIST_HEAD(siw_devlist);
+
+
+static ssize_t show_sw_version(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct siw_dev *siw_dev = container_of(dev, struct siw_dev,
+ ofa_dev.dev);
+
+ return sprintf(buf, "%x\n", siw_dev->attrs.version);
+}
+
+static ssize_t show_stats(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct siw_dev *siw_dev = container_of(dev, struct siw_dev,
+ ofa_dev.dev);
+
+ return sprintf(buf, "Allocated SIW Objects:\n"
+#if DPRINT_MASK > 0
+ "Global :\t%s: %d\n"
+#endif
+ "Device %s:\t"
+ "%s: %d, %s: %d, %s: %d, %s: %d, %s: %d, %s: %d\n",
+#if DPRINT_MASK > 0
+ "WQEs", atomic_read(&siw_num_wqe),
+#endif
+ siw_dev->ofa_dev.name,
+ "PDs", atomic_read(&siw_dev->num_pd),
+ "QPs", atomic_read(&siw_dev->num_qp),
+ "CQs", atomic_read(&siw_dev->num_cq),
+ "SRQs", atomic_read(&siw_dev->num_srq),
+ "MRs", atomic_read(&siw_dev->num_mem),
+ "CEPs", atomic_read(&siw_dev->num_cep));
+}
+
+static ssize_t show_ceps(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct siw_dev *siw_dev = container_of(dev, struct siw_dev,
+ ofa_dev.dev);
+
+ struct list_head *pos, *tmp;
+ int len, num_cep = atomic_read(&siw_dev->num_cep);
+
+ if (buf)
+ len = sprintf(buf, "%s: %d CEPs %s\n", siw_dev->ofa_dev.name,
+ num_cep,
+ num_cep ? "- see dmesg for details" : "");
+ else
+ len = 0;
+
+ if (num_cep)
+ printk(KERN_INFO "\n%d CEPs on device %s:\n",
+ num_cep, siw_dev->ofa_dev.name);
+ else
+ return len;
+
+ printk(KERN_INFO "%-20s%-6s%-6s%-7s%-3s%-3s%-4s%-21s%-9s\n",
+ "CEP", "State", "Ref's", "QP-ID", "LQ", "LC", "U", "Sock",
+ "CM-ID");
+
+ list_for_each_safe(pos, tmp, &siw_dev->cep_list) {
+ struct siw_cep *cep = list_entry(pos, struct siw_cep, devq);
+
+ printk(KERN_INFO "0x%-18p%-6d%-6d%-7d%-3s%-3s%-4d0x%-18p"
+ " 0x%-16p\n",
+ cep, cep->state,
+ atomic_read(&cep->ref.refcount),
+ cep->qp ? QP_ID(cep->qp) : -1,
+ list_empty(&cep->listenq) ? "n" : "y",
+ cep->listen_cep ? "y" : "n",
+ cep->in_use,
+ cep->llp.sock,
+ cep->cm_id);
+ }
+ return len;
+}
+
+static ssize_t show_qps(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct siw_dev *siw_dev = container_of(dev, struct siw_dev,
+ ofa_dev.dev);
+
+ struct list_head *pos, *tmp;
+ int len, num_qp = atomic_read(&siw_dev->num_qp);
+
+ len = sprintf(buf, "%s: %d QPs %s\n", siw_dev->ofa_dev.name,
+ num_qp, num_qp ? "- see dmesg for details" : "");
+
+ if (num_qp)
+ printk(KERN_INFO "\n%d QPs on device %s:\n",
+ num_qp, siw_dev->ofa_dev.name);
+ else
+ return len;
+
+ printk(KERN_INFO "%-7s%-6s%-6s%-5s%-5s%-5s%-5s%-5s%-20s%-20s\n",
+ "QP-ID", "State", "Ref's", "SQ", "RQ", "IRQ", "ORQ", "s/r",
+ "Sock", "CEP");
+
+ list_for_each_safe(pos, tmp, &siw_dev->qp_list) {
+ struct siw_qp *qp = list_entry(pos, struct siw_qp, devq);
+
+ printk(KERN_INFO "%-7d%-6d%-6d%-5d%-5d%-5d%-5d%d/%-3d0x%-17p"
+ " 0x%-18p\n",
+ QP_ID(qp),
+ qp->attrs.state,
+ atomic_read(&qp->hdr.ref.refcount),
+ qp->attrs.sq_size - atomic_read(&qp->sq_space),
+ qp->attrs.rq_size - atomic_read(&qp->rq_space),
+ qp->attrs.ird - atomic_read(&qp->irq_space),
+ qp->attrs.ord - atomic_read(&qp->orq_space),
+ tx_wqe(qp) ? 1 : 0,
+ rx_wqe(qp) ? 1 : 0,
+ qp->attrs.llp_stream_handle,
+ qp->cep);
+ }
+ return len;
+}
+
+static ssize_t show_if_type(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct siw_dev *siw_dev = container_of(dev, struct siw_dev,
+ ofa_dev.dev);
+
+ return sprintf(buf, "%d\n", siw_dev->attrs.iftype);
+}
+
+static DEVICE_ATTR(sw_version, S_IRUGO, show_sw_version, NULL);
+static DEVICE_ATTR(if_type, S_IRUGO, show_if_type, NULL);
+static DEVICE_ATTR(stats, S_IRUGO, show_stats, NULL);
+static DEVICE_ATTR(qp, S_IRUGO, show_qps, NULL);
+static DEVICE_ATTR(cep, S_IRUGO, show_ceps, NULL);
+
+static struct device_attribute *siw_dev_attributes[] = {
+ &dev_attr_sw_version,
+ &dev_attr_if_type,
+ &dev_attr_stats,
+ &dev_attr_qp,
+ &dev_attr_cep
+};
+
+static int siw_modify_port(struct ib_device *ofa_dev, u8 port, int mask,
+ struct ib_port_modify *props)
+{
+ return -EOPNOTSUPP;
+}
+
+
+static int siw_register_device(struct siw_dev *dev)
+{
+ struct ib_device *ibdev = &dev->ofa_dev;
+ int rv, i;
+
+ if (dev->l2dev->type != ARPHRD_LOOPBACK)
+ strlcpy(ibdev->name, "siw%d", IB_DEVICE_NAME_MAX);
+ else
+ strlcpy(ibdev->name, "siw_lo%d", IB_DEVICE_NAME_MAX);
+ memset(&ibdev->node_guid, 0, sizeof(ibdev->node_guid));
+ memcpy(&ibdev->node_guid, dev->l2dev->dev_addr, 6);
+
+ ibdev->owner = THIS_MODULE;
+
+ ibdev->uverbs_cmd_mask =
+ (1ull << IB_USER_VERBS_CMD_GET_CONTEXT) |
+ (1ull << IB_USER_VERBS_CMD_QUERY_DEVICE) |
+ (1ull << IB_USER_VERBS_CMD_QUERY_PORT) |
+ (1ull << IB_USER_VERBS_CMD_ALLOC_PD) |
+ (1ull << IB_USER_VERBS_CMD_DEALLOC_PD) |
+ (1ull << IB_USER_VERBS_CMD_REG_MR) |
+ (1ull << IB_USER_VERBS_CMD_DEREG_MR) |
+ (1ull << IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL) |
+ (1ull << IB_USER_VERBS_CMD_CREATE_CQ) |
+ (1ull << IB_USER_VERBS_CMD_POLL_CQ) |
+ (1ull << IB_USER_VERBS_CMD_REQ_NOTIFY_CQ) |
+ (1ull << IB_USER_VERBS_CMD_DESTROY_CQ) |
+ (1ull << IB_USER_VERBS_CMD_CREATE_QP) |
+ (1ull << IB_USER_VERBS_CMD_QUERY_QP) |
+ (1ull << IB_USER_VERBS_CMD_MODIFY_QP) |
+ (1ull << IB_USER_VERBS_CMD_DESTROY_QP) |
+ (1ull << IB_USER_VERBS_CMD_POST_SEND) |
+ (1ull << IB_USER_VERBS_CMD_POST_RECV) |
+ (1ull << IB_USER_VERBS_CMD_CREATE_SRQ) |
+ (1ull << IB_USER_VERBS_CMD_MODIFY_SRQ) |
+ (1ull << IB_USER_VERBS_CMD_QUERY_SRQ) |
+ (1ull << IB_USER_VERBS_CMD_DESTROY_SRQ) |
+ (1ull << IB_USER_VERBS_CMD_POST_SRQ_RECV);
+
+ ibdev->node_type = RDMA_NODE_RNIC;
+ memcpy(ibdev->node_desc, SIW_NODE_DESC, sizeof(SIW_NODE_DESC));
+
+ /*
+ * Current model (one-to-one device association):
+ * One Softiwarp device per net_device or, equivalently,
+ * per physical port.
+ */
+ ibdev->phys_port_cnt = 1;
+
+ ibdev->num_comp_vectors = 1;
+ /*
+ * While DMA adresses are not used a device must be provided
+ * as long as the code relies on OFA's ib_umem_get() function for
+ * memory pinning. calling ib_umem_get() includes a
+ * (for siw case useless) translation of memory to DMA
+ * adresses for that device.
+ */
+ ibdev->dma_device = dev->l2dev->dev.parent;
+ ibdev->query_device = siw_query_device;
+ ibdev->query_port = siw_query_port;
+ ibdev->query_qp = siw_query_qp;
+ ibdev->modify_port = siw_modify_port;
+ ibdev->query_pkey = siw_query_pkey;
+ ibdev->query_gid = siw_query_gid;
+ ibdev->alloc_ucontext = siw_alloc_ucontext;
+ ibdev->dealloc_ucontext = siw_dealloc_ucontext;
+ ibdev->mmap = siw_mmap;
+ ibdev->alloc_pd = siw_alloc_pd;
+ ibdev->dealloc_pd = siw_dealloc_pd;
+ ibdev->create_ah = siw_create_ah;
+ ibdev->destroy_ah = siw_destroy_ah;
+ ibdev->create_qp = siw_create_qp;
+ ibdev->modify_qp = siw_ofed_modify_qp;
+ ibdev->destroy_qp = siw_destroy_qp;
+ ibdev->create_cq = siw_create_cq;
+ ibdev->destroy_cq = siw_destroy_cq;
+ ibdev->resize_cq = NULL;
+ ibdev->poll_cq = siw_poll_cq;
+ ibdev->get_dma_mr = siw_get_dma_mr;
+ ibdev->reg_phys_mr = NULL;
+ ibdev->rereg_phys_mr = NULL;
+ ibdev->reg_user_mr = siw_reg_user_mr;
+ ibdev->dereg_mr = siw_dereg_mr;
+ ibdev->alloc_mw = NULL;
+ ibdev->bind_mw = NULL;
+ ibdev->dealloc_mw = NULL;
+
+ ibdev->create_srq = siw_create_srq;
+ ibdev->modify_srq = siw_modify_srq;
+ ibdev->query_srq = siw_query_srq;
+ ibdev->destroy_srq = siw_destroy_srq;
+ ibdev->post_srq_recv = siw_post_srq_recv;
+
+ ibdev->attach_mcast = NULL;
+ ibdev->detach_mcast = NULL;
+ ibdev->process_mad = siw_no_mad;
+
+ ibdev->req_notify_cq = siw_req_notify_cq;
+ ibdev->post_send = siw_post_send;
+ ibdev->post_recv = siw_post_receive;
+
+ ibdev->dma_ops = &siw_dma_mapping_ops;
+
+ ibdev->iwcm = kmalloc(sizeof(struct iw_cm_verbs), GFP_KERNEL);
+ if (!ibdev->iwcm)
+ return -ENOMEM;
+
+ ibdev->iwcm->connect = siw_connect;
+ ibdev->iwcm->accept = siw_accept;
+ ibdev->iwcm->reject = siw_reject;
+ ibdev->iwcm->create_listen = siw_create_listen;
+ ibdev->iwcm->destroy_listen = siw_destroy_listen;
+ ibdev->iwcm->add_ref = siw_qp_get_ref;
+ ibdev->iwcm->rem_ref = siw_qp_put_ref;
+ ibdev->iwcm->get_qp = siw_get_ofaqp;
+ /*
+ * set and register sw version + user if type
+ */
+ dev->attrs.version = VERSION_ID_SOFTIWARP;
+ dev->attrs.iftype = SIW_IF_OFED;
+
+ dev->attrs.vendor_id = SIW_VENDOR_ID;
+ dev->attrs.vendor_part_id = SIW_VENDORT_PART_ID;
+ dev->attrs.sw_version = SIW_SW_VERSION;
+ dev->attrs.max_qp = SIW_MAX_QP;
+ dev->attrs.max_qp_wr = SIW_MAX_QP_WR;
+ dev->attrs.max_ord = SIW_MAX_ORD;
+ dev->attrs.max_ird = SIW_MAX_IRD;
+ dev->attrs.cap_flags = 0;
+ dev->attrs.max_sge = SIW_MAX_SGE;
+ dev->attrs.max_sge_rd = SIW_MAX_SGE_RD;
+ dev->attrs.max_cq = SIW_MAX_CQ;
+ dev->attrs.max_cqe = SIW_MAX_CQE;
+ dev->attrs.max_mr = SIW_MAX_MR;
+ dev->attrs.max_mr_size = rlimit(RLIMIT_MEMLOCK);
+ dev->attrs.max_pd = SIW_MAX_PD;
+ dev->attrs.max_mw = SIW_MAX_MW;
+ dev->attrs.max_fmr = SIW_MAX_FMR;
+ dev->attrs.max_srq = SIW_MAX_SRQ;
+ dev->attrs.max_srq_wr = SIW_MAX_SRQ_WR;
+ dev->attrs.max_srq_sge = SIW_MAX_SGE;
+
+ siw_idr_init(dev);
+ INIT_LIST_HEAD(&dev->cep_list);
+ INIT_LIST_HEAD(&dev->qp_list);
+
+ atomic_set(&dev->num_srq, 0);
+ atomic_set(&dev->num_qp, 0);
+ atomic_set(&dev->num_cq, 0);
+ atomic_set(&dev->num_mem, 0);
+ atomic_set(&dev->num_pd, 0);
+ atomic_set(&dev->num_cep, 0);
+
+ rv = ib_register_device(ibdev, NULL);
+ if (rv) {
+ dprint(DBG_DM|DBG_ON, "(dev=%s): "
+ "ib_register_device failed: rv=%d\n", ibdev->name, rv);
+ return rv;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(siw_dev_attributes); ++i) {
+ rv = device_create_file(&ibdev->dev, siw_dev_attributes[i]);
+ if (rv) {
+ dprint(DBG_DM|DBG_ON, "(dev=%s): "
+ "device_create_file failed: i=%d, rv=%d\n",
+ ibdev->name, i, rv);
+ ib_unregister_device(ibdev);
+ return rv;
+ }
+ }
+
+ dprint(DBG_DM, ": dev 0x%p: Registered '%s' for interface '%s', "
+ "HWaddr=%02x.%02x.%02x.%02x.%02x.%02x\n",
+ dev, ibdev->name, dev->l2dev->name,
+ *(u8 *)dev->l2dev->dev_addr,
+ *((u8 *)dev->l2dev->dev_addr + 1),
+ *((u8 *)dev->l2dev->dev_addr + 2),
+ *((u8 *)dev->l2dev->dev_addr + 3),
+ *((u8 *)dev->l2dev->dev_addr + 4),
+ *((u8 *)dev->l2dev->dev_addr + 5));
+ return 0;
+}
+
+static void siw_deregister_device(struct siw_dev *dev)
+{
+ int i;
+
+ siw_idr_release(dev);
+
+ WARN_ON(atomic_read(&dev->num_srq) || atomic_read(&dev->num_qp) ||
+ atomic_read(&dev->num_cq) || atomic_read(&dev->num_mem) ||
+ atomic_read(&dev->num_pd));
+
+ if (!list_empty(&dev->cep_list)) {
+ int num_ceps = 0;
+
+ show_ceps(&dev->ofa_dev.dev, NULL, NULL);
+ while (!list_empty(&dev->cep_list)) {
+ struct siw_cep *cep = list_entry(dev->cep_list.next,
+ struct siw_cep, devq);
+ list_del(&cep->devq);
+ kfree(cep);
+ num_ceps++;
+ }
+ printk(KERN_INFO "siw_deregister_device: "
+ "free'd %d orphaned CEPs\n", num_ceps);
+ }
+ for (i = 0; i < ARRAY_SIZE(siw_dev_attributes); ++i)
+ device_remove_file(&dev->ofa_dev.dev, siw_dev_attributes[i]);
+
+ dprint(DBG_OBJ, ": Unregister '%s' for interface '%s'\n",
+ dev->ofa_dev.name, dev->l2dev->name);
+
+ ib_unregister_device(&dev->ofa_dev);
+}
+
+static int siw_match_iflist(struct net_device *dev)
+{
+ int i = 0, found = *iface_list ? 0 : 1;
+
+ while (iface_list[i]) {
+ if (!strcmp(iface_list[i++], dev->name)) {
+ found = 1;
+ break;
+ }
+ }
+ return found;
+}
+
+
+/*
+ * siw_init_module - Initialize Softiwarp module and create Softiwarp devices
+ *
+ * There are three design options for Softiwarp device management supporting
+ * - multiple physical Ethernet ports, i.e., multiple net_device instances
+ * - and multi-homing, i.e., multiple IP addresses associated with net_device,
+ * as follows:
+ *
+ * Option 1: One Softiwarp device per net_device and
+ * IP address associated with the net_device
+ * Option 2: One Softiwarp device per net_device
+ * (and all IP addresses associated with the net_device)
+ * Option 3: Single Softiwarp device for all net_device instances
+ * (and all IP addresses associated with these instances)
+ *
+ * We currently use Option 2, registering a separate siw_dev for
+ * each net_device.
+ *
+ * TODO: Dynamic device management (network device registration/removal).
+ * IPv6 support.
+ */
+static __init int siw_init_module(void)
+{
+ struct net_device *dev;
+ struct siw_dev *siw_p;
+ int rv = 0;
+
+ /*
+ * Identify all net_device instances and create a
+ * Softiwarp device for each net_device supporting IPv4
+ *
+ * TODO:
+ * - Do we have to generalize for IPv6?
+ * - Exclude devices based on IPoIB - if any
+ * - Consider excluding Ethernet devices with an
+ * associated iWARP hardware device
+ */
+ rtnl_lock();
+ for_each_netdev(&init_net, dev) {
+ struct in_device *in_dev;
+
+ in_dev = in_dev_get(dev);
+ if (!in_dev) {
+ dprint(DBG_DM, ": Skipped %s (no indev)\n", dev->name);
+ continue;
+ }
+ if (!in_dev->ifa_list) {
+ dprint(DBG_DM, ": Skipped %s (no ifa)\n", dev->name);
+ in_dev_put(in_dev);
+ continue;
+ }
+ /*
+ * This device has an in_device attached. Attach to it
+ * if it is LOOPBACK or ETHER or IEEE801-TR device.
+ *
+ * Additional hardware support can be added here
+ * (e.g. ARPHRD_FDDI, ARPHRD_ATM, ...) - see
+ * <linux/if_arp.h> for type identifiers.
+ *
+ * NOTE: ARPHRD_TUNNEL/6 are excluded.
+ */
+ if (dev->type == ARPHRD_ETHER ||
+ dev->type == ARPHRD_IEEE802 ||
+ (dev->type == ARPHRD_LOOPBACK && loopback_enabled)) {
+ if (!siw_match_iflist(dev)) {
+ dprint(DBG_DM|DBG_ON, ": %s (not selected)\n",
+ dev->name);
+ in_dev_put(in_dev);
+ continue;
+ }
+#ifdef CHECK_DMA_CAPABILITIES
+ if (!dev->dev.parent ||
+ !get_dma_ops(dev->dev.parent)) {
+ dprint(DBG_DM|DBG_ON,
+ ": No DMA ops: %s (skipped)\n",
+ dev->name);
+ in_dev_put(in_dev);
+ continue;
+ }
+#endif
+ siw_p =
+ (struct siw_dev *)ib_alloc_device(sizeof *siw_p);
+
+ if (!siw_p) {
+ in_dev_put(in_dev);
+ rv = -ENOMEM;
+ break;
+ }
+
+ siw_p->l2dev = dev;
+ list_add_tail(&siw_p->list, &siw_devlist);
+
+ rv = siw_register_device(siw_p);
+ if (rv) {
+ list_del(&siw_p->list);
+ in_dev_put(in_dev);
+ ib_dealloc_device(&siw_p->ofa_dev);
+
+ break;
+ }
+ } else {
+ dprint(DBG_DM, ": Skipped %s (type %d)\n",
+ dev->name, dev->type);
+ in_dev_put(in_dev);
+ }
+ }
+ rtnl_unlock();
+
+ if (list_empty(&siw_devlist))
+ return -ENODEV;
+
+ if (rv)
+ return rv;
+ /*
+ * FIXME: In case of error, we leave devices allocated.
+ * Is this correct?
+ */
+ rv = siw_cm_init();
+ if (rv)
+ return rv;
+
+ rv = siw_sq_worker_init();
+
+ atomic_set(&siw_num_wqe, 0);
+ atomic_set(&siw_num_cep, 0);
+
+ printk(KERN_INFO "SoftIWARP attached\n");
+ return rv;
+}
+
+static void __exit siw_exit_module(void)
+{
+ siw_sq_worker_exit();
+ siw_cm_exit();
+
+ while (!list_empty(&siw_devlist)) {
+ struct siw_dev *siw_p =
+ list_entry(siw_devlist.next, struct siw_dev, list);
+ list_del(&siw_p->list);
+ siw_deregister_device(siw_p);
+ in_dev_put(siw_p->l2dev->ip_ptr);
+ ib_dealloc_device(&siw_p->ofa_dev);
+ }
+ printk(KERN_INFO "SoftIWARP detached\n");
+}
+
+module_init(siw_init_module);
+module_exit(siw_exit_module);
--
1.5.4.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/14] SIWv2: iWARP Protocol headers: iwarp.h
From: Bernard Metzler @ 2011-06-16 12:41 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA, Bernard Metzler
---
drivers/infiniband/hw/siw/iwarp.h | 324 +++++++++++++++++++++++++++++++++++++
1 files changed, 324 insertions(+), 0 deletions(-)
create mode 100644 drivers/infiniband/hw/siw/iwarp.h
diff --git a/drivers/infiniband/hw/siw/iwarp.h b/drivers/infiniband/hw/siw/iwarp.h
new file mode 100644
index 0000000..5aebd86
--- /dev/null
+++ b/drivers/infiniband/hw/siw/iwarp.h
@@ -0,0 +1,324 @@
+/*
+ * Software iWARP device driver for Linux
+ *
+ * Authors: Bernard Metzler <bmt-OA+xvbQnYDHMbYB6QlFGEg@public.gmane.org>
+ * Fredy Neeser <nfd-OA+xvbQnYDHMbYB6QlFGEg@public.gmane.org>
+ *
+ * Copyright (c) 2008-2011, IBM Corporation
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of IBM nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef _IWARP_H
+#define _IWARP_H
+
+#include <rdma/rdma_user_cm.h> /* RDMA_MAX_PRIVATE_DATA */
+#include <linux/types.h>
+#include <asm/byteorder.h>
+
+
+#define RDMAP_VERSION 1
+#define DDP_VERSION 1
+#define MPA_REVISION_1 1
+#define MPA_MAX_PRIVDATA RDMA_MAX_PRIVATE_DATA
+#define MPA_KEY_REQ "MPA ID Req Frame"
+#define MPA_KEY_REP "MPA ID Rep Frame"
+
+struct mpa_rr_params {
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ __be16 res:5,
+ r:1,
+ c:1,
+ m:1,
+ rev:8;
+#elif defined(__BIG_ENDIAN_BITFIELD)
+ __be16 m:1,
+ c:1,
+ r:1,
+ res:5,
+ rev:8;
+#else
+#error "Adjust your <asm/byteorder.h> defines"
+#endif
+ __be16 pd_len;
+};
+
+/*
+ * MPA request/reply header
+ */
+struct mpa_rr {
+ __u8 key[16];
+ struct mpa_rr_params params;
+};
+
+/*
+ * Don't change the layout/size of this struct!
+ */
+struct mpa_marker {
+ __be16 rsvd;
+ __be16 fpdu_hmd; /* FPDU header-marker distance (= MPA's FPDUPTR) */
+};
+
+#define MPA_MARKER_SPACING 512
+#define MPA_HDR_SIZE 2
+
+/*
+ * MPA marker size:
+ * - Standards-compliant marker insertion: Use sizeof(struct mpa_marker)
+ * - "Invisible markers" for testing sender's marker insertion
+ * without affecting receiver: Use 0
+ */
+#define MPA_MARKER_SIZE sizeof(struct mpa_marker)
+
+
+/*
+ * maximum MPA trailer
+ */
+struct mpa_trailer {
+ char pad[4];
+ __be32 crc;
+};
+
+#define MPA_CRC_SIZE 4
+
+
+/*
+ * Common portion of iWARP headers (MPA, DDP, RDMAP)
+ * for any FPDU
+ */
+struct iwarp_ctrl {
+ __be16 mpa_len;
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ __be16 dv:2, /* DDP Version */
+ rsvd:4, /* DDP reserved, MBZ */
+ l:1, /* DDP Last flag */
+ t:1, /* DDP Tagged flag */
+ opcode:4, /* RDMAP opcode */
+ rsv:2, /* RDMAP reserved, MBZ */
+ rv:2; /* RDMAP Version, 01 for IETF, 00 for RDMAC */
+#elif defined(__BIG_ENDIAN_BITFIELD)
+ __be16 t:1, /* DDP Tagged flag */
+ l:1, /* DDP Last flag */
+ rsvd:4, /* DDP reserved, MBZ */
+ dv:2, /* DDP Version */
+ rv:2, /* RDMAP Version, 01 for IETF, 00 for RDMAC */
+ rsv:2, /* RDMAP reserved, MBZ */
+ opcode:4; /* RDMAP opcode */
+#else
+#error "Adjust your <asm/byteorder.h> defines"
+#endif
+};
+
+
+struct rdmap_terminate_ctrl {
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ __be32 etype:4,
+ layer:4,
+ ecode:8,
+ rsvd1:5,
+ r:1,
+ d:1,
+ m:1,
+ rsvd2:8;
+#elif defined(__BIG_ENDIAN_BITFIELD)
+ __be32 layer:4,
+ etype:4,
+ ecode:8,
+ m:1,
+ d:1,
+ r:1,
+ rsvd1:5,
+ rsvd2:8;
+#else
+#error "Adjust your <asm/byteorder.h> defines"
+#endif
+};
+
+
+struct iwarp_rdma_write {
+ struct iwarp_ctrl ctrl;
+ __be32 sink_stag;
+ __be64 sink_to;
+};
+
+struct iwarp_rdma_rreq {
+ struct iwarp_ctrl ctrl;
+ __be32 rsvd;
+ __be32 ddp_qn;
+ __be32 ddp_msn;
+ __be32 ddp_mo;
+ __be32 sink_stag;
+ __be64 sink_to;
+ __be32 read_size;
+ __be32 source_stag;
+ __be64 source_to;
+};
+
+struct iwarp_rdma_rresp {
+ struct iwarp_ctrl ctrl;
+ __be32 sink_stag;
+ __be64 sink_to;
+};
+
+struct iwarp_send {
+ struct iwarp_ctrl ctrl;
+ __be32 rsvd;
+ __be32 ddp_qn;
+ __be32 ddp_msn;
+ __be32 ddp_mo;
+};
+
+struct iwarp_send_inv {
+ struct iwarp_ctrl ctrl;
+ __be32 inval_stag;
+ __be32 ddp_qn;
+ __be32 ddp_msn;
+ __be32 ddp_mo;
+};
+
+struct iwarp_terminate {
+ struct iwarp_ctrl ctrl;
+ __be32 rsvd;
+ __be32 ddp_qn;
+ __be32 ddp_msn;
+ __be32 ddp_mo;
+ struct rdmap_terminate_ctrl term_ctrl;
+};
+
+
+/*
+ * Common portion of iWARP headers (MPA, DDP, RDMAP)
+ * for an FPDU carrying an untagged DDP segment
+ */
+struct iwarp_ctrl_untagged {
+ struct iwarp_ctrl ctrl;
+ __be32 rsvd;
+ __be32 ddp_qn;
+ __be32 ddp_msn;
+ __be32 ddp_mo;
+};
+
+/*
+ * Common portion of iWARP headers (MPA, DDP, RDMAP)
+ * for an FPDU carrying a tagged DDP segment
+ */
+struct iwarp_ctrl_tagged {
+ struct iwarp_ctrl ctrl;
+ __be32 ddp_stag;
+ __be64 ddp_to;
+};
+
+union iwarp_hdrs {
+ struct iwarp_ctrl ctrl;
+ struct iwarp_ctrl_untagged c_untagged;
+ struct iwarp_ctrl_tagged c_tagged;
+ struct iwarp_rdma_write rwrite;
+ struct iwarp_rdma_rreq rreq;
+ struct iwarp_rdma_rresp rresp;
+ struct iwarp_terminate terminate;
+ struct iwarp_send send;
+ struct iwarp_send_inv send_inv;
+};
+
+
+#define MPA_MIN_FRAG ((sizeof(union iwarp_hdrs) + MPA_CRC_SIZE))
+
+enum ddp_etype {
+ DDP_ETYPE_CATASTROPHIC = 0x0,
+ DDP_ETYPE_TAGGED_BUF = 0x1,
+ DDP_ETYPE_UNTAGGED_BUF = 0x2,
+ DDP_ETYPE_RSVD = 0x3
+};
+
+enum ddp_ecode {
+ DDP_ECODE_CATASTROPHIC = 0x00,
+ /* Tagged Buffer Errors */
+ DDP_ECODE_T_INVALID_STAG = 0x00,
+ DDP_ECODE_T_BASE_BOUNDS = 0x01,
+ DDP_ECODE_T_STAG_NOT_ASSOC = 0x02,
+ DDP_ECODE_T_TO_WRAP = 0x03,
+ DDP_ECODE_T_DDP_VERSION = 0x04,
+ /* Untagged Buffer Errors */
+ DDP_ECODE_UT_INVALID_QN = 0x01,
+ DDP_ECODE_UT_INVALID_MSN_NOBUF = 0x02,
+ DDP_ECODE_UT_INVALID_MSN_RANGE = 0x03,
+ DDP_ECODE_UT_INVALID_MO = 0x04,
+ DDP_ECODE_UT_MSG_TOOLONG = 0x05,
+ DDP_ECODE_UT_DDP_VERSION = 0x06
+};
+
+
+enum rdmap_untagged_qn {
+ RDMAP_UNTAGGED_QN_SEND = 0,
+ RDMAP_UNTAGGED_QN_RDMA_READ = 1,
+ RDMAP_UNTAGGED_QN_TERMINATE = 2,
+ RDMAP_UNTAGGED_QN_COUNT = 3
+};
+
+enum rdmap_etype {
+ RDMAP_ETYPE_CATASTROPHIC = 0x0,
+ RDMAP_ETYPE_REMOTE_PROTECTION = 0x1,
+ RDMAP_ETYPE_REMOTE_OPERATION = 0x2
+};
+
+enum rdmap_ecode {
+ RDMAP_ECODE_INVALID_STAG = 0x00,
+ RDMAP_ECODE_BASE_BOUNDS = 0x01,
+ RDMAP_ECODE_ACCESS_RIGHTS = 0x02,
+ RDMAP_ECODE_STAG_NOT_ASSOC = 0x03,
+ RDMAP_ECODE_TO_WRAP = 0x04,
+ RDMAP_ECODE_RDMAP_VERSION = 0x05,
+ RDMAP_ECODE_UNEXPECTED_OPCODE = 0x06,
+ RDMAP_ECODE_CATASTROPHIC_STREAM = 0x07,
+ RDMAP_ECODE_CATASTROPHIC_GLOBAL = 0x08,
+ RDMAP_ECODE_STAG_NOT_INVALIDATE = 0x09,
+ RDMAP_ECODE_UNSPECIFIED = 0xff
+};
+
+enum rdmap_elayer {
+ RDMAP_ERROR_LAYER_RDMA = 0x00,
+ RDMAP_ERROR_LAYER_DDP = 0x01,
+ RDMAP_ERROR_LAYER_LLP = 0x02 /* eg., MPA */
+};
+
+enum rdma_opcode {
+ RDMAP_RDMA_WRITE = 0x0,
+ RDMAP_RDMA_READ_REQ = 0x1,
+ RDMAP_RDMA_READ_RESP = 0x2,
+ RDMAP_SEND = 0x3,
+ RDMAP_SEND_INVAL = 0x4,
+ RDMAP_SEND_SE = 0x5,
+ RDMAP_SEND_SE_INVAL = 0x6,
+ RDMAP_TERMINATE = 0x7,
+ RDMAP_NOT_SUPPORTED = RDMAP_TERMINATE + 1
+};
+
+#endif
--
1.5.4.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 01/14] SIWv2: Kconfig and Makefile
From: Bernard Metzler @ 2011-06-16 12:41 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA
Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA, Bernard Metzler
---
drivers/infiniband/Kconfig | 1 +
drivers/infiniband/Makefile | 1 +
drivers/infiniband/hw/siw/Kconfig | 14 ++++++++++++++
drivers/infiniband/hw/siw/Makefile | 5 +++++
4 files changed, 21 insertions(+), 0 deletions(-)
create mode 100644 drivers/infiniband/hw/siw/Kconfig
create mode 100644 drivers/infiniband/hw/siw/Makefile
diff --git a/drivers/infiniband/Kconfig b/drivers/infiniband/Kconfig
index 0f9a84c..52097f6 100644
--- a/drivers/infiniband/Kconfig
+++ b/drivers/infiniband/Kconfig
@@ -51,6 +51,7 @@ source "drivers/infiniband/hw/cxgb3/Kconfig"
source "drivers/infiniband/hw/cxgb4/Kconfig"
source "drivers/infiniband/hw/mlx4/Kconfig"
source "drivers/infiniband/hw/nes/Kconfig"
+source "drivers/infiniband/hw/siw/Kconfig"
source "drivers/infiniband/ulp/ipoib/Kconfig"
diff --git a/drivers/infiniband/Makefile b/drivers/infiniband/Makefile
index 9cc7a47..c01a0d6 100644
--- a/drivers/infiniband/Makefile
+++ b/drivers/infiniband/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_INFINIBAND_CXGB3) += hw/cxgb3/
obj-$(CONFIG_INFINIBAND_CXGB4) += hw/cxgb4/
obj-$(CONFIG_MLX4_INFINIBAND) += hw/mlx4/
obj-$(CONFIG_INFINIBAND_NES) += hw/nes/
+obj-$(CONFIG_INFINIBAND_SOFTIWARP) += hw/siw/
obj-$(CONFIG_INFINIBAND_IPOIB) += ulp/ipoib/
obj-$(CONFIG_INFINIBAND_SRP) += ulp/srp/
obj-$(CONFIG_INFINIBAND_ISER) += ulp/iser/
diff --git a/drivers/infiniband/hw/siw/Kconfig b/drivers/infiniband/hw/siw/Kconfig
new file mode 100644
index 0000000..6beff23
--- /dev/null
+++ b/drivers/infiniband/hw/siw/Kconfig
@@ -0,0 +1,14 @@
+config INFINIBAND_SOFTIWARP
+ tristate "Software iWARP Stack (EXPERIMENTAL)"
+ depends on INET && EXPERIMENTAL
+ ---help---
+ Kernel Software Implementation of the iWARP protocol stack
+
+ This driver implements the iWARP protocol stack in software
+ and interfaces with in-kernel TCP/IP as well as the OFED
+ verbs interfaces.
+
+ Please send feedback to <bmt-OA+xvbQnYDHMbYB6QlFGEg@public.gmane.org>.
+
+ To compile this driver as a module, choose M here: the module
+ will be called siw.
diff --git a/drivers/infiniband/hw/siw/Makefile b/drivers/infiniband/hw/siw/Makefile
new file mode 100644
index 0000000..234150a
--- /dev/null
+++ b/drivers/infiniband/hw/siw/Makefile
@@ -0,0 +1,5 @@
+obj-$(CONFIG_INFINIBAND_SOFTIWARP) += siw.o
+
+siw-y := siw_main.o siw_cm.o siw_verbs.o siw_obj.o \
+ siw_qp.o siw_qp_tx.o siw_qp_rx.o siw_cq.o siw_cm.o \
+ siw_debug.o siw_ae.o siw_mem.o
--
1.5.4.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
* Software iWARP Stack - take 2
From: Bernard Metzler @ 2011-06-16 12:40 UTC (permalink / raw)
To: linux-rdma-owner, netdev; +Cc: Bart Van Assche, Roland Dreier
In-Reply-To: <BANLkTimEGgKEMZd3qppOofN-Vj-u-PH-xA@mail.gmail.com>
Bart, Roland, all,
many thanks for the suggestions and input. I am happy
to see interest in SoftiWARP.
In the hope to contribute something usefull, I will now
send a complete new set of patches against net-next.
It adds software iWARP support on top of TCP kernel sockets
and fits into the linux-rdma kernel stack.
Major changes to the previous (first) posting from October last
year include some kernel client support, restructuring of the
connection management code and general code cleanup.
I hope all issues which were rised after the first posting are
resolved. Thanks again for the valuable feedback.
Please take the current code contribution as work in progress.
Any comment and input is highly appreciated.
Here comes a shortlog of what you should expect:
Bernard Metzler (14):
SIWv2: Kconfig and Makefile
SIWv2: iWARP Protocol headers: iwarp.h
SIWv2: Main header file: siw.h
SIWv2: Module initialization: siw_main.c
SIWv2: User interface: siw_verbs.h, siw_verbs.c, siw_user.h, siw_ae.c
SIWv2: Connection management: siw_cm.c, siw_cm.h
SIWv2: Object management: siw_obj.c, siw_obj.h
SIWv2: Queue pair: siw_qp.c
SIWv2: Completion queue: siw_cq.c
SIWv2: Transmit path: siw_qp_tx.c
SIWv2: Receive path: siw_qp_rx.c
SIWv2: Debugging and Tracing: siw_debug.c, siw_debug.h
SIWv2: Memory management: siw_mem.c
SIWv2: Documentation: siw.txt
Many thanks,
Bernard.
^ permalink raw reply
* [PATCH 06/11] drivers/net: use printk_ratelimited() instead of printk_ratelimit()
From: Manuel Zerpies @ 2011-06-16 12:12 UTC (permalink / raw)
To: David S. Miller, David Decotigny, Hans J. Koch, Jiri Kosina,
Ben Pfaff, netdev
Cc: christian.dietrich
In-Reply-To: <cover.1308142053.git.manuel.f.zerpies@ww.stud.uni-erlangen.de>
Since printk_ratelimit() shouldn't be used anymore (see comment in
include/linux/printk.h), replace it with printk_ratelimited()
Signed-off-by: Manuel Zerpies <manuel.f.zerpies@ww.stud.uni-erlangen.de>
---
drivers/net/sc92031.c | 16 ++++++----------
1 files changed, 6 insertions(+), 10 deletions(-)
diff --git a/drivers/net/sc92031.c b/drivers/net/sc92031.c
index fa74314..6f6bbb3 100644
--- a/drivers/net/sc92031.c
+++ b/drivers/net/sc92031.c
@@ -31,6 +31,7 @@
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/crc32.h>
+#include <linux/ratelimit.h>
#include <asm/irq.h>
@@ -536,8 +537,7 @@ static bool _sc92031_check_media(struct net_device *dev)
netif_carrier_on(dev);
- if (printk_ratelimit())
- printk(KERN_INFO "%s: link up, %sMbps, %s-duplex\n",
+ printk_ratelimited(KERN_INFO "%s: link up, %sMbps, %s-duplex\n",
dev->name,
speed_100 ? "100" : "10",
duplex_full ? "full" : "half");
@@ -549,8 +549,7 @@ static bool _sc92031_check_media(struct net_device *dev)
_sc92031_disable_tx_rx(dev);
- if (printk_ratelimit())
- printk(KERN_INFO "%s: link down\n", dev->name);
+ printk_ratelimited(KERN_INFO "%s: link down\n", dev->name);
return false;
}
}
@@ -755,8 +754,7 @@ static void _sc92031_rx_tasklet(struct net_device *dev)
return;
if (unlikely(rx_len > RX_BUF_LEN)) {
- if (printk_ratelimit())
- printk(KERN_ERR "%s: rx packets length > rx buffer\n",
+ printk_ratelimited(KERN_ERR "%s: rx packets length > rx buffer\n",
dev->name);
return;
}
@@ -786,8 +784,7 @@ static void _sc92031_rx_tasklet(struct net_device *dev)
}
if (unlikely(rx_size_align + 4 > rx_len)) {
- if (printk_ratelimit())
- printk(KERN_ERR "%s: rx_len is too small\n", dev->name);
+ printk_ratelimited(KERN_ERR "%s: rx_len is too small\n", dev->name);
break;
}
@@ -795,8 +792,7 @@ static void _sc92031_rx_tasklet(struct net_device *dev)
skb = netdev_alloc_skb_ip_align(dev, pkt_size);
if (unlikely(!skb)) {
- if (printk_ratelimit())
- printk(KERN_ERR "%s: Couldn't allocate a skb_buff for a packet of size %u\n",
+ printk_ratelimited(KERN_ERR "%s: Couldn't allocate a skb_buff for a packet of size %u\n",
dev->name, pkt_size);
goto next;
}
--
1.7.4.1
^ permalink raw reply related
* [PATCH 04/11] net/rds: use prink_ratelimited() instead of printk_ratelimit()
From: Manuel Zerpies @ 2011-06-16 12:09 UTC (permalink / raw)
To: Andy Grover, David S. Miller, rds-devel, netdev, linux-kernel
Cc: christian.dietrich
In-Reply-To: <cover.1308142053.git.manuel.f.zerpies@ww.stud.uni-erlangen.de>
Since printk_ratelimit() shouldn't be used anymore (see comment in
include/linux/printk.h), replace it with printk_ratelimited()
Signed-off-by: Manuel Zerpies <manuel.f.zerpies@ww.stud.uni-erlangen.de>
---
net/rds/bind.c | 4 ++--
net/rds/ib_cm.c | 6 +++---
net/rds/ib_send.c | 4 ++--
net/rds/iw_cm.c | 9 ++++-----
net/rds/iw_rdma.c | 9 +++++----
net/rds/iw_send.c | 4 ++--
net/rds/send.c | 7 +++----
7 files changed, 21 insertions(+), 22 deletions(-)
diff --git a/net/rds/bind.c b/net/rds/bind.c
index 2f6b3fc..637bde5 100644
--- a/net/rds/bind.c
+++ b/net/rds/bind.c
@@ -35,6 +35,7 @@
#include <linux/in.h>
#include <linux/if_arp.h>
#include <linux/jhash.h>
+#include <linux/ratelimit.h>
#include "rds.h"
#define BIND_HASH_SIZE 1024
@@ -185,8 +186,7 @@ int rds_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
if (!trans) {
ret = -EADDRNOTAVAIL;
rds_remove_bound(rs);
- if (printk_ratelimit())
- printk(KERN_INFO "RDS: rds_bind() could not find a transport, "
+ printk_ratelimited(KERN_INFO "RDS: rds_bind() could not find a transport, "
"load rds_tcp or rds_rdma?\n");
goto out;
}
diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c
index fd453dd..cd67026 100644
--- a/net/rds/ib_cm.c
+++ b/net/rds/ib_cm.c
@@ -34,6 +34,7 @@
#include <linux/in.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
+#include <linux/ratelimit.h>
#include "rds.h"
#include "ib.h"
@@ -435,13 +436,12 @@ static u32 rds_ib_protocol_compatible(struct rdma_cm_event *event)
version = RDS_PROTOCOL_3_0;
while ((common >>= 1) != 0)
version++;
- } else if (printk_ratelimit()) {
- printk(KERN_NOTICE "RDS: Connection from %pI4 using "
+ }
+ printk_ratelimited(KERN_NOTICE "RDS: Connection from %pI4 using "
"incompatible protocol version %u.%u\n",
&dp->dp_saddr,
dp->dp_protocol_major,
dp->dp_protocol_minor);
- }
return version;
}
diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c
index 7c4dce8..e590949 100644
--- a/net/rds/ib_send.c
+++ b/net/rds/ib_send.c
@@ -34,6 +34,7 @@
#include <linux/in.h>
#include <linux/device.h>
#include <linux/dmapool.h>
+#include <linux/ratelimit.h>
#include "rds.h"
#include "ib.h"
@@ -207,8 +208,7 @@ static struct rds_message *rds_ib_send_unmap_op(struct rds_ib_connection *ic,
}
break;
default:
- if (printk_ratelimit())
- printk(KERN_NOTICE
+ printk_ratelimited(KERN_NOTICE
"RDS/IB: %s: unexpected opcode 0x%x in WR!\n",
__func__, send->s_wr.opcode);
break;
diff --git a/net/rds/iw_cm.c b/net/rds/iw_cm.c
index c12db66..9556d28 100644
--- a/net/rds/iw_cm.c
+++ b/net/rds/iw_cm.c
@@ -34,6 +34,7 @@
#include <linux/in.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
+#include <linux/ratelimit.h>
#include "rds.h"
#include "iw.h"
@@ -258,8 +259,7 @@ static int rds_iw_setup_qp(struct rds_connection *conn)
*/
rds_iwdev = ib_get_client_data(dev, &rds_iw_client);
if (!rds_iwdev) {
- if (printk_ratelimit())
- printk(KERN_NOTICE "RDS/IW: No client_data for device %s\n",
+ printk_ratelimited(KERN_NOTICE "RDS/IW: No client_data for device %s\n",
dev->name);
return -EOPNOTSUPP;
}
@@ -365,13 +365,12 @@ static u32 rds_iw_protocol_compatible(const struct rds_iw_connect_private *dp)
version = RDS_PROTOCOL_3_0;
while ((common >>= 1) != 0)
version++;
- } else if (printk_ratelimit()) {
- printk(KERN_NOTICE "RDS: Connection from %pI4 using "
+ }
+ printk_ratelimited(KERN_NOTICE "RDS: Connection from %pI4 using "
"incompatible protocol version %u.%u\n",
&dp->dp_saddr,
dp->dp_protocol_major,
dp->dp_protocol_minor);
- }
return version;
}
diff --git a/net/rds/iw_rdma.c b/net/rds/iw_rdma.c
index 6deaa77..8b77edb 100644
--- a/net/rds/iw_rdma.c
+++ b/net/rds/iw_rdma.c
@@ -32,6 +32,7 @@
*/
#include <linux/kernel.h>
#include <linux/slab.h>
+#include <linux/ratelimit.h>
#include "rds.h"
#include "iw.h"
@@ -729,8 +730,8 @@ static int rds_iw_rdma_build_fastreg(struct rds_iw_mapping *mapping)
failed_wr = &f_wr;
ret = ib_post_send(ibmr->cm_id->qp, &f_wr, &failed_wr);
BUG_ON(failed_wr != &f_wr);
- if (ret && printk_ratelimit())
- printk(KERN_WARNING "RDS/IW: %s:%d ib_post_send returned %d\n",
+ if (ret)
+ printk_ratelimited(KERN_WARNING "RDS/IW: %s:%d ib_post_send returned %d\n",
__func__, __LINE__, ret);
return ret;
}
@@ -751,8 +752,8 @@ static int rds_iw_rdma_fastreg_inv(struct rds_iw_mr *ibmr)
failed_wr = &s_wr;
ret = ib_post_send(ibmr->cm_id->qp, &s_wr, &failed_wr);
- if (ret && printk_ratelimit()) {
- printk(KERN_WARNING "RDS/IW: %s:%d ib_post_send returned %d\n",
+ if (ret) {
+ printk_ratelimited(KERN_WARNING "RDS/IW: %s:%d ib_post_send returned %d\n",
__func__, __LINE__, ret);
goto out;
}
diff --git a/net/rds/iw_send.c b/net/rds/iw_send.c
index 545d8ee..e40c3c5 100644
--- a/net/rds/iw_send.c
+++ b/net/rds/iw_send.c
@@ -34,6 +34,7 @@
#include <linux/in.h>
#include <linux/device.h>
#include <linux/dmapool.h>
+#include <linux/ratelimit.h>
#include "rds.h"
#include "iw.h"
@@ -258,8 +259,7 @@ void rds_iw_send_cq_comp_handler(struct ib_cq *cq, void *context)
* when the SEND completes. */
break;
default:
- if (printk_ratelimit())
- printk(KERN_NOTICE
+ printk_ratelimited(KERN_NOTICE
"RDS/IW: %s: unexpected opcode 0x%x in WR!\n",
__func__, send->s_wr.opcode);
break;
diff --git a/net/rds/send.c b/net/rds/send.c
index d58ae5f..aa57e22 100644
--- a/net/rds/send.c
+++ b/net/rds/send.c
@@ -35,6 +35,7 @@
#include <net/sock.h>
#include <linux/in.h>
#include <linux/list.h>
+#include <linux/ratelimit.h>
#include "rds.h"
@@ -1006,16 +1007,14 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
goto out;
if (rm->rdma.op_active && !conn->c_trans->xmit_rdma) {
- if (printk_ratelimit())
- printk(KERN_NOTICE "rdma_op %p conn xmit_rdma %p\n",
+ printk_ratelimited(KERN_NOTICE "rdma_op %p conn xmit_rdma %p\n",
&rm->rdma, conn->c_trans->xmit_rdma);
ret = -EOPNOTSUPP;
goto out;
}
if (rm->atomic.op_active && !conn->c_trans->xmit_atomic) {
- if (printk_ratelimit())
- printk(KERN_NOTICE "atomic_op %p conn xmit_atomic %p\n",
+ printk_ratelimited(KERN_NOTICE "atomic_op %p conn xmit_atomic %p\n",
&rm->atomic, conn->c_trans->xmit_atomic);
ret = -EOPNOTSUPP;
goto out;
--
1.7.4.1
^ permalink raw reply related
* [PATCH 03/11] net/can: use printk_ratelimited() instead of printk_ratelimit()
From: Manuel Zerpies @ 2011-06-16 12:08 UTC (permalink / raw)
To: Oliver Hartkopp, Urs Thuermann, David S. Miller, socketcan-core,
netdev
In-Reply-To: <cover.1308142053.git.manuel.f.zerpies@ww.stud.uni-erlangen.de>
Since printk_ratelimit() shouldn't be used anymore (see comment in
include/linux/printk.h), replace it with printk_ratelimited().
Signed-off-by: Manuel Zerpies <manuel.f.zerpies@ww.stud.uni-erlangen.de>
---
net/can/af_can.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/net/can/af_can.c b/net/can/af_can.c
index 094fc53..8ce926d 100644
--- a/net/can/af_can.c
+++ b/net/can/af_can.c
@@ -58,6 +58,7 @@
#include <linux/skbuff.h>
#include <linux/can.h>
#include <linux/can/core.h>
+#include <linux/ratelimit.h>
#include <net/net_namespace.h>
#include <net/sock.h>
@@ -161,8 +162,8 @@ static int can_create(struct net *net, struct socket *sock, int protocol,
* return the error code immediately. Below we will
* return -EPROTONOSUPPORT
*/
- if (err && printk_ratelimit())
- printk(KERN_ERR "can: request_module "
+ if (err)
+ printk_ratelimited(KERN_ERR "can: request_module "
"(can-proto-%d) failed.\n", protocol);
cp = can_get_proto(protocol);
--
1.7.4.1
^ permalink raw reply related
* Re: software iwarp stack update
From: Bernard Metzler @ 2011-06-16 11:51 UTC (permalink / raw)
To: Bart Van Assche
Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA,
linux-rdma-owner-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <BANLkTimEGgKEMZd3qppOofN-Vj-u-PH-xA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
linux-rdma-owner-u79uwXL29TY76Z2rM5mHXA@public.gmane.org wrote on 06/15/2011 08:57:38 PM:
> On Wed, Jun 15, 2011 at 5:43 PM, Bernard Metzler <BMT-OA+xvbQnYDHMbYB6QlFGEg@public.gmane.org>
wrote:
> > after rebasing to davem/net-next-2.6.git, I formatted a patch adding
> > to the initial 'siw' driver posting from last October. Given the rather
> > substantial amount of changes and time elapsed, I am not sure if people
> > would better like a complete re-posting of all files.
> > If I don't hear objection before tomorrow I would post it as an
> > increment - as summarized below.
>
> Documentation in general and for sysfs attributes in particular seems
> to be missing ?
>
> Also, the following statement in siw_main.c:
>
> ibdev->modify_port = NULL;
oh, thanks...!
I was expecting there is an ib_device->uverbs_cmd_mask
flag which siw does not set... Unfortunately, it is not
completely clear to me when a command mask bit is available
and when the OFA core strictly expects a function pointer.
Maybe there is some redundancy/inconsistency?
Thanks,
Bernard.
--
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
* Re: Netconf2011 slides...
From: Srinivasa T N @ 2011-06-16 10:09 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20110615.145937.1748734114172641662.davem@davemloft.net>
On 06/16/2011 12:29 AM, David Miller wrote:
>
> As we're winding down here in Toronto I wanted to point
> folks at our web page:
>
> http://vger.kernel.org/netconf2011.html
>
> as most of the slides are up for people to take a look
> at. I'll make sure the remaining ones go up over the
> next few days.
>
> Go bruins!
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
Hi David,
Were there some interesting topics which is useful for the community?
(Few lines on each such topic would do).
Regards,
Seenu.
^ permalink raw reply
* [PATCH 2/2] sctp: Bundle HEAERTBEAT into ASCONF_ACK
From: Michio Honda @ 2011-06-16 8:56 UTC (permalink / raw)
To: David Miller, Wei Yongjun; +Cc: netdev
>From 111463f295a5ea7ae03c26bf62671895e803bc28 Mon Sep 17 00:00:00 2001
From: Michio Honda <micchie@sfc.wide.ad.jp>
Date: Thu, 16 Jun 2011 17:14:34 +0900
Subject: [PATCH 2/2] sctp: Bundle HEAERTBEAT into ASCONF_ACK
With this patch a HEARTBEAT chunk is bundled into the ASCONF-ACK
for ADD IP ADDRESS, confirming the new destination as quickly as
possible.
Signed-off-by: Michio Honda <micchie@sfc.wide.ad.jp>
---
include/net/sctp/structs.h | 1 +
net/sctp/associola.c | 1 +
net/sctp/sm_make_chunk.c | 1 +
net/sctp/sm_statefuns.c | 5 +++++
4 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 31d7ea2..7154980 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -1915,6 +1915,7 @@ struct sctp_association {
__u32 addip_serial;
union sctp_addr *asconf_addr_del_pending;
int src_out_of_asoc_ok;
+ struct sctp_transport *new_transport;
/* SCTP AUTH: list of the endpoint shared keys. These
* keys are provided out of band by the user applicaton
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index dc16b90..152b5b3 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -282,6 +282,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
asoc->peer.asconf_capable = 1;
asoc->asconf_addr_del_pending = NULL;
asoc->src_out_of_asoc_ok = 0;
+ asoc->new_transport = NULL;
/* Create an input queue. */
sctp_inq_init(&asoc->base.inqueue);
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 3363d37..a42d3b0 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -3016,6 +3016,7 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
/* Start the heartbeat timer. */
if (!mod_timer(&peer->hb_timer, sctp_transport_timeout(peer)))
sctp_transport_hold(peer);
+ asoc->new_transport = peer;
break;
case SCTP_PARAM_DEL_IP:
/* ADDIP 4.3 D7) If a request is received to delete the
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index a297283..5cfd6d2 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -3612,6 +3612,11 @@ sctp_disposition_t sctp_sf_do_asconf(const struct sctp_endpoint *ep,
*/
asconf_ack->dest = chunk->source;
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(asconf_ack));
+ if (asoc->new_transport) {
+ sctp_sf_heartbeat(ep, asoc, type, asoc->new_transport,
+ commands);
+ ((struct sctp_association *)asoc)->new_transport = NULL;
+ }
return SCTP_DISPOSITION_CONSUME;
}
--
1.7.3.2
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox