aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-01-24 20:18:32 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-24 20:18:32 -0500
commit8e585a6c4abdef8562308f3f307aeea6cf168e8b (patch)
tree70236b30b362123b009f2b723056072f7028d75e
parent1b59bab55e36082b1db3dc81bb32475616487a98 (diff)
parentfb1b5034e4987b158179a62732fb6dfb8f7ec88e (diff)
Merge tag 'rdma-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband
Pull infiniband updates from Roland Dreier: "Main batch of InfiniBand/RDMA changes for 3.14: - Flow steering for InfiniBand UD traffic - IP-based addressing for IBoE aka RoCE - Pass SRP submaintainership from Dave to Bart - SRP transport fixes from Bart - Add the new Cisco usNIC low-level device driver - Various other fixes" * tag 'rdma-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband: (75 commits) IB/mlx5: Verify reserved fields are cleared IB/mlx5: Remove old field for create mkey mailbox IB/mlx5: Abort driver cleanup if teardown hca fails IB/mlx5: Allow creation of QPs with zero-length work queues mlx5_core: Fix PowerPC support mlx5_core: Improve debugfs readability IB/mlx5: Add support for resize CQ IB/mlx5: Implement modify CQ IB/mlx5: Make sure doorbell record is visible before doorbell mlx5_core: Use mlx5 core style warning IB/mlx5: Clear out struct before create QP command mlx5_core: Fix out arg size in access_register command RDMA/nes: Slight optimization of Ethernet address compare IB/qib: Fix QP check when looping back to/from QP1 RDMA/cxgb4: Fix gcc warning on 32-bit arch IB/usnic: Remove unused includes of <linux/version.h> RDMA/amso1100: Add check if cache memory was allocated before freeing it IPoIB: Report operstate consistently when brought up without a link IB/core: Fix unused variable warning RDMA/cma: Handle global/non-linklocal IPv6 addresses in cma_check_linklocal() ...
-rw-r--r--Documentation/scsi/scsi_transport_srp/Makefile7
-rw-r--r--Documentation/scsi/scsi_transport_srp/rport_state_diagram.dot26
-rw-r--r--MAINTAINERS7
-rw-r--r--drivers/infiniband/Kconfig6
-rw-r--r--drivers/infiniband/Makefile1
-rw-r--r--drivers/infiniband/core/Makefile5
-rw-r--r--drivers/infiniband/core/addr.c97
-rw-r--r--drivers/infiniband/core/cm.c52
-rw-r--r--drivers/infiniband/core/cma.c81
-rw-r--r--drivers/infiniband/core/core_priv.h2
-rw-r--r--drivers/infiniband/core/iwcm.c3
-rw-r--r--drivers/infiniband/core/sa_query.c12
-rw-r--r--drivers/infiniband/core/sysfs.c1
-rw-r--r--drivers/infiniband/core/ucma.c18
-rw-r--r--drivers/infiniband/core/uverbs_cmd.c4
-rw-r--r--drivers/infiniband/core/verbs.c101
-rw-r--r--drivers/infiniband/hw/amso1100/c2_intr.c3
-rw-r--r--drivers/infiniband/hw/cxgb4/mem.c2
-rw-r--r--drivers/infiniband/hw/ehca/ehca_qp.c2
-rw-r--r--drivers/infiniband/hw/ipath/ipath_qp.c2
-rw-r--r--drivers/infiniband/hw/mlx4/Kconfig2
-rw-r--r--drivers/infiniband/hw/mlx4/ah.c40
-rw-r--r--drivers/infiniband/hw/mlx4/cq.c9
-rw-r--r--drivers/infiniband/hw/mlx4/main.c747
-rw-r--r--drivers/infiniband/hw/mlx4/mlx4_ib.h18
-rw-r--r--drivers/infiniband/hw/mlx4/qp.c157
-rw-r--r--drivers/infiniband/hw/mlx4/sysfs.c8
-rw-r--r--drivers/infiniband/hw/mlx5/cq.c310
-rw-r--r--drivers/infiniband/hw/mlx5/main.c13
-rw-r--r--drivers/infiniband/hw/mlx5/mlx5_ib.h4
-rw-r--r--drivers/infiniband/hw/mlx5/mr.c1
-rw-r--r--drivers/infiniband/hw/mlx5/qp.c133
-rw-r--r--drivers/infiniband/hw/mlx5/user.h3
-rw-r--r--drivers/infiniband/hw/mthca/mthca_qp.c3
-rw-r--r--drivers/infiniband/hw/nes/nes_cm.c3
-rw-r--r--drivers/infiniband/hw/ocrdma/Kconfig2
-rw-r--r--drivers/infiniband/hw/ocrdma/ocrdma.h12
-rw-r--r--drivers/infiniband/hw/ocrdma/ocrdma_ah.c6
-rw-r--r--drivers/infiniband/hw/ocrdma/ocrdma_hw.c21
-rw-r--r--drivers/infiniband/hw/ocrdma/ocrdma_hw.h1
-rw-r--r--drivers/infiniband/hw/ocrdma/ocrdma_main.c138
-rw-r--r--drivers/infiniband/hw/ocrdma/ocrdma_sli.h4
-rw-r--r--drivers/infiniband/hw/ocrdma/ocrdma_verbs.c3
-rw-r--r--drivers/infiniband/hw/qib/qib_qp.c2
-rw-r--r--drivers/infiniband/hw/qib/qib_ud.c9
-rw-r--r--drivers/infiniband/hw/usnic/Kconfig10
-rw-r--r--drivers/infiniband/hw/usnic/Makefile15
-rw-r--r--drivers/infiniband/hw/usnic/usnic.h29
-rw-r--r--drivers/infiniband/hw/usnic/usnic_abi.h73
-rw-r--r--drivers/infiniband/hw/usnic/usnic_common_pkt_hdr.h27
-rw-r--r--drivers/infiniband/hw/usnic/usnic_common_util.h68
-rw-r--r--drivers/infiniband/hw/usnic/usnic_debugfs.c154
-rw-r--r--drivers/infiniband/hw/usnic/usnic_debugfs.h29
-rw-r--r--drivers/infiniband/hw/usnic/usnic_fwd.c350
-rw-r--r--drivers/infiniband/hw/usnic/usnic_fwd.h113
-rw-r--r--drivers/infiniband/hw/usnic/usnic_ib.h118
-rw-r--r--drivers/infiniband/hw/usnic/usnic_ib_main.c682
-rw-r--r--drivers/infiniband/hw/usnic/usnic_ib_qp_grp.c754
-rw-r--r--drivers/infiniband/hw/usnic/usnic_ib_qp_grp.h117
-rw-r--r--drivers/infiniband/hw/usnic/usnic_ib_sysfs.c341
-rw-r--r--drivers/infiniband/hw/usnic/usnic_ib_sysfs.h29
-rw-r--r--drivers/infiniband/hw/usnic/usnic_ib_verbs.c765
-rw-r--r--drivers/infiniband/hw/usnic/usnic_ib_verbs.h72
-rw-r--r--drivers/infiniband/hw/usnic/usnic_log.h58
-rw-r--r--drivers/infiniband/hw/usnic/usnic_transport.c202
-rw-r--r--drivers/infiniband/hw/usnic/usnic_transport.h51
-rw-r--r--drivers/infiniband/hw/usnic/usnic_uiom.c604
-rw-r--r--drivers/infiniband/hw/usnic/usnic_uiom.h80
-rw-r--r--drivers/infiniband/hw/usnic/usnic_uiom_interval_tree.c236
-rw-r--r--drivers/infiniband/hw/usnic/usnic_uiom_interval_tree.h73
-rw-r--r--drivers/infiniband/hw/usnic/usnic_vnic.c467
-rw-r--r--drivers/infiniband/hw/usnic/usnic_vnic.h103
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c4
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_verbs.c3
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c1
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/cmd.c9
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/fw.c10
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mcg.c17
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4.h5
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/port.c20
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/resource_tracker.c10
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/cq.c17
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/debugfs.c39
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/main.c10
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c13
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/port.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/qp.c5
-rw-r--r--drivers/scsi/scsi_transport_srp.c95
-rw-r--r--include/linux/mlx4/cmd.h1
-rw-r--r--include/linux/mlx4/cq.h15
-rw-r--r--include/linux/mlx4/device.h7
-rw-r--r--include/linux/mlx5/cq.h18
-rw-r--r--include/linux/mlx5/device.h31
-rw-r--r--include/linux/mlx5/qp.h45
-rw-r--r--include/rdma/ib_addr.h69
-rw-r--r--include/rdma/ib_cm.h1
-rw-r--r--include/rdma/ib_pack.h1
-rw-r--r--include/rdma/ib_sa.h3
-rw-r--r--include/rdma/ib_verbs.h42
-rw-r--r--include/scsi/scsi_transport_srp.h36
100 files changed, 7663 insertions, 567 deletions
diff --git a/Documentation/scsi/scsi_transport_srp/Makefile b/Documentation/scsi/scsi_transport_srp/Makefile
new file mode 100644
index 000000000000..5f6b567e955c
--- /dev/null
+++ b/Documentation/scsi/scsi_transport_srp/Makefile
@@ -0,0 +1,7 @@
1all: rport_state_diagram.svg rport_state_diagram.png
2
3rport_state_diagram.svg: rport_state_diagram.dot
4 dot -Tsvg -o $@ $<
5
6rport_state_diagram.png: rport_state_diagram.dot
7 dot -Tpng -o $@ $<
diff --git a/Documentation/scsi/scsi_transport_srp/rport_state_diagram.dot b/Documentation/scsi/scsi_transport_srp/rport_state_diagram.dot
new file mode 100644
index 000000000000..75d610d6411a
--- /dev/null
+++ b/Documentation/scsi/scsi_transport_srp/rport_state_diagram.dot
@@ -0,0 +1,26 @@
1digraph srp_initiator {
2 node [shape = doublecircle]; running lost;
3 node [shape = circle];
4
5 {
6 rank = min;
7 running_rta [ label = "running;\nreconnect\ntimer\nactive" ];
8 };
9 running [ label = "running;\nreconnect\ntimer\nstopped" ];
10 blocked;
11 failfast [ label = "fail I/O\nfast" ];
12 lost;
13
14 running -> running_rta [ label = "fast_io_fail_tmo = off and\ndev_loss_tmo = off;\nsrp_start_tl_fail_timers()" ];
15 running_rta -> running [ label = "fast_io_fail_tmo = off and\ndev_loss_tmo = off;\nreconnecting succeeded" ];
16 running -> blocked [ label = "fast_io_fail_tmo >= 0 or\ndev_loss_tmo >= 0;\nsrp_start_tl_fail_timers()" ];
17 running -> failfast [ label = "fast_io_fail_tmo = off and\ndev_loss_tmo = off;\nreconnecting failed\n" ];
18 blocked -> failfast [ label = "fast_io_fail_tmo\nexpired or\nreconnecting\nfailed" ];
19 blocked -> lost [ label = "dev_loss_tmo\nexpired or\nsrp_stop_rport_timers()" ];
20 failfast -> lost [ label = "dev_loss_tmo\nexpired or\nsrp_stop_rport_timers()" ];
21 blocked -> running [ label = "reconnecting\nsucceeded" ];
22 failfast -> failfast [ label = "reconnecting\nfailed" ];
23 failfast -> running [ label = "reconnecting\nsucceeded" ];
24 running -> lost [ label = "srp_stop_rport_timers()" ];
25 running_rta -> lost [ label = "srp_stop_rport_timers()" ];
26}
diff --git a/MAINTAINERS b/MAINTAINERS
index 17cabd8d0dcb..8a777a235cc9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2195,6 +2195,11 @@ M: Nishank Trivedi <nistrive@cisco.com>
2195S: Supported 2195S: Supported
2196F: drivers/net/ethernet/cisco/enic/ 2196F: drivers/net/ethernet/cisco/enic/
2197 2197
2198CISCO VIC LOW LATENCY NIC DRIVER
2199M: Upinder Malhi <umalhi@cisco.com>
2200S: Supported
2201F: drivers/infiniband/hw/usnic
2202
2198CIRRUS LOGIC EP93XX ETHERNET DRIVER 2203CIRRUS LOGIC EP93XX ETHERNET DRIVER
2199M: Hartley Sweeten <hsweeten@visionengravers.com> 2204M: Hartley Sweeten <hsweeten@visionengravers.com>
2200L: netdev@vger.kernel.org 2205L: netdev@vger.kernel.org
@@ -7528,7 +7533,7 @@ S: Maintained
7528F: drivers/scsi/sr* 7533F: drivers/scsi/sr*
7529 7534
7530SCSI RDMA PROTOCOL (SRP) INITIATOR 7535SCSI RDMA PROTOCOL (SRP) INITIATOR
7531M: David Dillow <dillowda@ornl.gov> 7536M: Bart Van Assche <bvanassche@acm.org>
7532L: linux-rdma@vger.kernel.org 7537L: linux-rdma@vger.kernel.org
7533S: Supported 7538S: Supported
7534W: http://www.openfabrics.org 7539W: http://www.openfabrics.org
diff --git a/drivers/infiniband/Kconfig b/drivers/infiniband/Kconfig
index 5ceda710f516..77089399359b 100644
--- a/drivers/infiniband/Kconfig
+++ b/drivers/infiniband/Kconfig
@@ -3,6 +3,8 @@ menuconfig INFINIBAND
3 depends on PCI || BROKEN 3 depends on PCI || BROKEN
4 depends on HAS_IOMEM 4 depends on HAS_IOMEM
5 depends on NET 5 depends on NET
6 depends on INET
7 depends on m || IPV6 != m
6 ---help--- 8 ---help---
7 Core support for InfiniBand (IB). Make sure to also select 9 Core support for InfiniBand (IB). Make sure to also select
8 any protocols you wish to use as well as drivers for your 10 any protocols you wish to use as well as drivers for your
@@ -38,8 +40,7 @@ config INFINIBAND_USER_MEM
38 40
39config INFINIBAND_ADDR_TRANS 41config INFINIBAND_ADDR_TRANS
40 bool 42 bool
41 depends on INET 43 depends on INFINIBAND
42 depends on !(INFINIBAND = y && IPV6 = m)
43 default y 44 default y
44 45
45source "drivers/infiniband/hw/mthca/Kconfig" 46source "drivers/infiniband/hw/mthca/Kconfig"
@@ -53,6 +54,7 @@ source "drivers/infiniband/hw/mlx4/Kconfig"
53source "drivers/infiniband/hw/mlx5/Kconfig" 54source "drivers/infiniband/hw/mlx5/Kconfig"
54source "drivers/infiniband/hw/nes/Kconfig" 55source "drivers/infiniband/hw/nes/Kconfig"
55source "drivers/infiniband/hw/ocrdma/Kconfig" 56source "drivers/infiniband/hw/ocrdma/Kconfig"
57source "drivers/infiniband/hw/usnic/Kconfig"
56 58
57source "drivers/infiniband/ulp/ipoib/Kconfig" 59source "drivers/infiniband/ulp/ipoib/Kconfig"
58 60
diff --git a/drivers/infiniband/Makefile b/drivers/infiniband/Makefile
index 1fe69888515f..bf508b5550c4 100644
--- a/drivers/infiniband/Makefile
+++ b/drivers/infiniband/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_MLX4_INFINIBAND) += hw/mlx4/
10obj-$(CONFIG_MLX5_INFINIBAND) += hw/mlx5/ 10obj-$(CONFIG_MLX5_INFINIBAND) += hw/mlx5/
11obj-$(CONFIG_INFINIBAND_NES) += hw/nes/ 11obj-$(CONFIG_INFINIBAND_NES) += hw/nes/
12obj-$(CONFIG_INFINIBAND_OCRDMA) += hw/ocrdma/ 12obj-$(CONFIG_INFINIBAND_OCRDMA) += hw/ocrdma/
13obj-$(CONFIG_INFINIBAND_USNIC) += hw/usnic/
13obj-$(CONFIG_INFINIBAND_IPOIB) += ulp/ipoib/ 14obj-$(CONFIG_INFINIBAND_IPOIB) += ulp/ipoib/
14obj-$(CONFIG_INFINIBAND_SRP) += ulp/srp/ 15obj-$(CONFIG_INFINIBAND_SRP) += ulp/srp/
15obj-$(CONFIG_INFINIBAND_SRPT) += ulp/srpt/ 16obj-$(CONFIG_INFINIBAND_SRPT) += ulp/srpt/
diff --git a/drivers/infiniband/core/Makefile b/drivers/infiniband/core/Makefile
index c8bbaef1becb..3ab3865544bb 100644
--- a/drivers/infiniband/core/Makefile
+++ b/drivers/infiniband/core/Makefile
@@ -1,8 +1,9 @@
1infiniband-$(CONFIG_INFINIBAND_ADDR_TRANS) := ib_addr.o rdma_cm.o 1infiniband-$(CONFIG_INFINIBAND_ADDR_TRANS) := rdma_cm.o
2user_access-$(CONFIG_INFINIBAND_ADDR_TRANS) := rdma_ucm.o 2user_access-$(CONFIG_INFINIBAND_ADDR_TRANS) := rdma_ucm.o
3 3
4obj-$(CONFIG_INFINIBAND) += ib_core.o ib_mad.o ib_sa.o \ 4obj-$(CONFIG_INFINIBAND) += ib_core.o ib_mad.o ib_sa.o \
5 ib_cm.o iw_cm.o $(infiniband-y) 5 ib_cm.o iw_cm.o ib_addr.o \
6 $(infiniband-y)
6obj-$(CONFIG_INFINIBAND_USER_MAD) += ib_umad.o 7obj-$(CONFIG_INFINIBAND_USER_MAD) += ib_umad.o
7obj-$(CONFIG_INFINIBAND_USER_ACCESS) += ib_uverbs.o ib_ucm.o \ 8obj-$(CONFIG_INFINIBAND_USER_ACCESS) += ib_uverbs.o ib_ucm.o \
8 $(user_access-y) 9 $(user_access-y)
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c
index e90f2b2eabd7..8172d37f9add 100644
--- a/drivers/infiniband/core/addr.c
+++ b/drivers/infiniband/core/addr.c
@@ -86,6 +86,8 @@ int rdma_addr_size(struct sockaddr *addr)
86} 86}
87EXPORT_SYMBOL(rdma_addr_size); 87EXPORT_SYMBOL(rdma_addr_size);
88 88
89static struct rdma_addr_client self;
90
89void rdma_addr_register_client(struct rdma_addr_client *client) 91void rdma_addr_register_client(struct rdma_addr_client *client)
90{ 92{
91 atomic_set(&client->refcount, 1); 93 atomic_set(&client->refcount, 1);
@@ -119,7 +121,8 @@ int rdma_copy_addr(struct rdma_dev_addr *dev_addr, struct net_device *dev,
119} 121}
120EXPORT_SYMBOL(rdma_copy_addr); 122EXPORT_SYMBOL(rdma_copy_addr);
121 123
122int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr) 124int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr,
125 u16 *vlan_id)
123{ 126{
124 struct net_device *dev; 127 struct net_device *dev;
125 int ret = -EADDRNOTAVAIL; 128 int ret = -EADDRNOTAVAIL;
@@ -142,6 +145,8 @@ int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr)
142 return ret; 145 return ret;
143 146
144 ret = rdma_copy_addr(dev_addr, dev, NULL); 147 ret = rdma_copy_addr(dev_addr, dev, NULL);
148 if (vlan_id)
149 *vlan_id = rdma_vlan_dev_vlan_id(dev);
145 dev_put(dev); 150 dev_put(dev);
146 break; 151 break;
147 152
@@ -153,6 +158,8 @@ int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr)
153 &((struct sockaddr_in6 *) addr)->sin6_addr, 158 &((struct sockaddr_in6 *) addr)->sin6_addr,
154 dev, 1)) { 159 dev, 1)) {
155 ret = rdma_copy_addr(dev_addr, dev, NULL); 160 ret = rdma_copy_addr(dev_addr, dev, NULL);
161 if (vlan_id)
162 *vlan_id = rdma_vlan_dev_vlan_id(dev);
156 break; 163 break;
157 } 164 }
158 } 165 }
@@ -238,7 +245,7 @@ static int addr4_resolve(struct sockaddr_in *src_in,
238 src_in->sin_addr.s_addr = fl4.saddr; 245 src_in->sin_addr.s_addr = fl4.saddr;
239 246
240 if (rt->dst.dev->flags & IFF_LOOPBACK) { 247 if (rt->dst.dev->flags & IFF_LOOPBACK) {
241 ret = rdma_translate_ip((struct sockaddr *) dst_in, addr); 248 ret = rdma_translate_ip((struct sockaddr *)dst_in, addr, NULL);
242 if (!ret) 249 if (!ret)
243 memcpy(addr->dst_dev_addr, addr->src_dev_addr, MAX_ADDR_LEN); 250 memcpy(addr->dst_dev_addr, addr->src_dev_addr, MAX_ADDR_LEN);
244 goto put; 251 goto put;
@@ -286,7 +293,7 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
286 } 293 }
287 294
288 if (dst->dev->flags & IFF_LOOPBACK) { 295 if (dst->dev->flags & IFF_LOOPBACK) {
289 ret = rdma_translate_ip((struct sockaddr *) dst_in, addr); 296 ret = rdma_translate_ip((struct sockaddr *)dst_in, addr, NULL);
290 if (!ret) 297 if (!ret)
291 memcpy(addr->dst_dev_addr, addr->src_dev_addr, MAX_ADDR_LEN); 298 memcpy(addr->dst_dev_addr, addr->src_dev_addr, MAX_ADDR_LEN);
292 goto put; 299 goto put;
@@ -437,6 +444,88 @@ void rdma_addr_cancel(struct rdma_dev_addr *addr)
437} 444}
438EXPORT_SYMBOL(rdma_addr_cancel); 445EXPORT_SYMBOL(rdma_addr_cancel);
439 446
447struct resolve_cb_context {
448 struct rdma_dev_addr *addr;
449 struct completion comp;
450};
451
452static void resolve_cb(int status, struct sockaddr *src_addr,
453 struct rdma_dev_addr *addr, void *context)
454{
455 memcpy(((struct resolve_cb_context *)context)->addr, addr, sizeof(struct
456 rdma_dev_addr));
457 complete(&((struct resolve_cb_context *)context)->comp);
458}
459
460int rdma_addr_find_dmac_by_grh(union ib_gid *sgid, union ib_gid *dgid, u8 *dmac,
461 u16 *vlan_id)
462{
463 int ret = 0;
464 struct rdma_dev_addr dev_addr;
465 struct resolve_cb_context ctx;
466 struct net_device *dev;
467
468 union {
469 struct sockaddr _sockaddr;
470 struct sockaddr_in _sockaddr_in;
471 struct sockaddr_in6 _sockaddr_in6;
472 } sgid_addr, dgid_addr;
473
474
475 ret = rdma_gid2ip(&sgid_addr._sockaddr, sgid);
476 if (ret)
477 return ret;
478
479 ret = rdma_gid2ip(&dgid_addr._sockaddr, dgid);
480 if (ret)
481 return ret;
482
483 memset(&dev_addr, 0, sizeof(dev_addr));
484
485 ctx.addr = &dev_addr;
486 init_completion(&ctx.comp);
487 ret = rdma_resolve_ip(&self, &sgid_addr._sockaddr, &dgid_addr._sockaddr,
488 &dev_addr, 1000, resolve_cb, &ctx);
489 if (ret)
490 return ret;
491
492 wait_for_completion(&ctx.comp);
493
494 memcpy(dmac, dev_addr.dst_dev_addr, ETH_ALEN);
495 dev = dev_get_by_index(&init_net, dev_addr.bound_dev_if);
496 if (!dev)
497 return -ENODEV;
498 if (vlan_id)
499 *vlan_id = rdma_vlan_dev_vlan_id(dev);
500 dev_put(dev);
501 return ret;
502}
503EXPORT_SYMBOL(rdma_addr_find_dmac_by_grh);
504
505int rdma_addr_find_smac_by_sgid(union ib_gid *sgid, u8 *smac, u16 *vlan_id)
506{
507 int ret = 0;
508 struct rdma_dev_addr dev_addr;
509 union {
510 struct sockaddr _sockaddr;
511 struct sockaddr_in _sockaddr_in;
512 struct sockaddr_in6 _sockaddr_in6;
513 } gid_addr;
514
515 ret = rdma_gid2ip(&gid_addr._sockaddr, sgid);
516
517 if (ret)
518 return ret;
519 memset(&dev_addr, 0, sizeof(dev_addr));
520 ret = rdma_translate_ip(&gid_addr._sockaddr, &dev_addr, vlan_id);
521 if (ret)
522 return ret;
523
524 memcpy(smac, dev_addr.src_dev_addr, ETH_ALEN);
525 return ret;
526}
527EXPORT_SYMBOL(rdma_addr_find_smac_by_sgid);
528
440static int netevent_callback(struct notifier_block *self, unsigned long event, 529static int netevent_callback(struct notifier_block *self, unsigned long event,
441 void *ctx) 530 void *ctx)
442{ 531{
@@ -461,11 +550,13 @@ static int __init addr_init(void)
461 return -ENOMEM; 550 return -ENOMEM;
462 551
463 register_netevent_notifier(&nb); 552 register_netevent_notifier(&nb);
553 rdma_addr_register_client(&self);
464 return 0; 554 return 0;
465} 555}
466 556
467static void __exit addr_cleanup(void) 557static void __exit addr_cleanup(void)
468{ 558{
559 rdma_addr_unregister_client(&self);
469 unregister_netevent_notifier(&nb); 560 unregister_netevent_notifier(&nb);
470 destroy_workqueue(addr_wq); 561 destroy_workqueue(addr_wq);
471} 562}
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index f2ef7ef0f36f..0601b9daf840 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -47,6 +47,7 @@
47#include <linux/sysfs.h> 47#include <linux/sysfs.h>
48#include <linux/workqueue.h> 48#include <linux/workqueue.h>
49#include <linux/kdev_t.h> 49#include <linux/kdev_t.h>
50#include <linux/etherdevice.h>
50 51
51#include <rdma/ib_cache.h> 52#include <rdma/ib_cache.h>
52#include <rdma/ib_cm.h> 53#include <rdma/ib_cm.h>
@@ -177,6 +178,8 @@ struct cm_av {
177 struct ib_ah_attr ah_attr; 178 struct ib_ah_attr ah_attr;
178 u16 pkey_index; 179 u16 pkey_index;
179 u8 timeout; 180 u8 timeout;
181 u8 valid;
182 u8 smac[ETH_ALEN];
180}; 183};
181 184
182struct cm_work { 185struct cm_work {
@@ -346,6 +349,23 @@ static void cm_init_av_for_response(struct cm_port *port, struct ib_wc *wc,
346 grh, &av->ah_attr); 349 grh, &av->ah_attr);
347} 350}
348 351
352int ib_update_cm_av(struct ib_cm_id *id, const u8 *smac, const u8 *alt_smac)
353{
354 struct cm_id_private *cm_id_priv;
355
356 cm_id_priv = container_of(id, struct cm_id_private, id);
357
358 if (smac != NULL)
359 memcpy(cm_id_priv->av.smac, smac, sizeof(cm_id_priv->av.smac));
360
361 if (alt_smac != NULL)
362 memcpy(cm_id_priv->alt_av.smac, alt_smac,
363 sizeof(cm_id_priv->alt_av.smac));
364
365 return 0;
366}
367EXPORT_SYMBOL(ib_update_cm_av);
368
349static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av) 369static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av)
350{ 370{
351 struct cm_device *cm_dev; 371 struct cm_device *cm_dev;
@@ -376,6 +396,9 @@ static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av)
376 ib_init_ah_from_path(cm_dev->ib_device, port->port_num, path, 396 ib_init_ah_from_path(cm_dev->ib_device, port->port_num, path,
377 &av->ah_attr); 397 &av->ah_attr);
378 av->timeout = path->packet_life_time + 1; 398 av->timeout = path->packet_life_time + 1;
399 memcpy(av->smac, path->smac, sizeof(av->smac));
400
401 av->valid = 1;
379 return 0; 402 return 0;
380} 403}
381 404
@@ -1554,6 +1577,9 @@ static int cm_req_handler(struct cm_work *work)
1554 1577
1555 cm_process_routed_req(req_msg, work->mad_recv_wc->wc); 1578 cm_process_routed_req(req_msg, work->mad_recv_wc->wc);
1556 cm_format_paths_from_req(req_msg, &work->path[0], &work->path[1]); 1579 cm_format_paths_from_req(req_msg, &work->path[0], &work->path[1]);
1580
1581 memcpy(work->path[0].dmac, cm_id_priv->av.ah_attr.dmac, ETH_ALEN);
1582 work->path[0].vlan_id = cm_id_priv->av.ah_attr.vlan_id;
1557 ret = cm_init_av_by_path(&work->path[0], &cm_id_priv->av); 1583 ret = cm_init_av_by_path(&work->path[0], &cm_id_priv->av);
1558 if (ret) { 1584 if (ret) {
1559 ib_get_cached_gid(work->port->cm_dev->ib_device, 1585 ib_get_cached_gid(work->port->cm_dev->ib_device,
@@ -3500,6 +3526,32 @@ static int cm_init_qp_rtr_attr(struct cm_id_private *cm_id_priv,
3500 *qp_attr_mask = IB_QP_STATE | IB_QP_AV | IB_QP_PATH_MTU | 3526 *qp_attr_mask = IB_QP_STATE | IB_QP_AV | IB_QP_PATH_MTU |
3501 IB_QP_DEST_QPN | IB_QP_RQ_PSN; 3527 IB_QP_DEST_QPN | IB_QP_RQ_PSN;
3502 qp_attr->ah_attr = cm_id_priv->av.ah_attr; 3528 qp_attr->ah_attr = cm_id_priv->av.ah_attr;
3529 if (!cm_id_priv->av.valid) {
3530 spin_unlock_irqrestore(&cm_id_priv->lock, flags);
3531 return -EINVAL;
3532 }
3533 if (cm_id_priv->av.ah_attr.vlan_id != 0xffff) {
3534 qp_attr->vlan_id = cm_id_priv->av.ah_attr.vlan_id;
3535 *qp_attr_mask |= IB_QP_VID;
3536 }
3537 if (!is_zero_ether_addr(cm_id_priv->av.smac)) {
3538 memcpy(qp_attr->smac, cm_id_priv->av.smac,
3539 sizeof(qp_attr->smac));
3540 *qp_attr_mask |= IB_QP_SMAC;
3541 }
3542 if (cm_id_priv->alt_av.valid) {
3543 if (cm_id_priv->alt_av.ah_attr.vlan_id != 0xffff) {
3544 qp_attr->alt_vlan_id =
3545 cm_id_priv->alt_av.ah_attr.vlan_id;
3546 *qp_attr_mask |= IB_QP_ALT_VID;
3547 }
3548 if (!is_zero_ether_addr(cm_id_priv->alt_av.smac)) {
3549 memcpy(qp_attr->alt_smac,
3550 cm_id_priv->alt_av.smac,
3551 sizeof(qp_attr->alt_smac));
3552 *qp_attr_mask |= IB_QP_ALT_SMAC;
3553 }
3554 }
3503 qp_attr->path_mtu = cm_id_priv->path_mtu; 3555 qp_attr->path_mtu = cm_id_priv->path_mtu;
3504 qp_attr->dest_qp_num = be32_to_cpu(cm_id_priv->remote_qpn); 3556 qp_attr->dest_qp_num = be32_to_cpu(cm_id_priv->remote_qpn);
3505 qp_attr->rq_psn = be32_to_cpu(cm_id_priv->rq_psn); 3557 qp_attr->rq_psn = be32_to_cpu(cm_id_priv->rq_psn);
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 8e49db690f33..9b079a7ea29c 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -340,7 +340,7 @@ static int cma_translate_addr(struct sockaddr *addr, struct rdma_dev_addr *dev_a
340 int ret; 340 int ret;
341 341
342 if (addr->sa_family != AF_IB) { 342 if (addr->sa_family != AF_IB) {
343 ret = rdma_translate_ip(addr, dev_addr); 343 ret = rdma_translate_ip(addr, dev_addr, NULL);
344 } else { 344 } else {
345 cma_translate_ib((struct sockaddr_ib *) addr, dev_addr); 345 cma_translate_ib((struct sockaddr_ib *) addr, dev_addr);
346 ret = 0; 346 ret = 0;
@@ -365,7 +365,9 @@ static int cma_acquire_dev(struct rdma_id_private *id_priv,
365 return -EINVAL; 365 return -EINVAL;
366 366
367 mutex_lock(&lock); 367 mutex_lock(&lock);
368 iboe_addr_get_sgid(dev_addr, &iboe_gid); 368 rdma_ip2gid((struct sockaddr *)&id_priv->id.route.addr.src_addr,
369 &iboe_gid);
370
369 memcpy(&gid, dev_addr->src_dev_addr + 371 memcpy(&gid, dev_addr->src_dev_addr +
370 rdma_addr_gid_offset(dev_addr), sizeof gid); 372 rdma_addr_gid_offset(dev_addr), sizeof gid);
371 if (listen_id_priv && 373 if (listen_id_priv &&
@@ -603,6 +605,7 @@ static int cma_modify_qp_rtr(struct rdma_id_private *id_priv,
603{ 605{
604 struct ib_qp_attr qp_attr; 606 struct ib_qp_attr qp_attr;
605 int qp_attr_mask, ret; 607 int qp_attr_mask, ret;
608 union ib_gid sgid;
606 609
607 mutex_lock(&id_priv->qp_mutex); 610 mutex_lock(&id_priv->qp_mutex);
608 if (!id_priv->id.qp) { 611 if (!id_priv->id.qp) {
@@ -625,6 +628,20 @@ static int cma_modify_qp_rtr(struct rdma_id_private *id_priv,
625 if (ret) 628 if (ret)
626 goto out; 629 goto out;
627 630
631 ret = ib_query_gid(id_priv->id.device, id_priv->id.port_num,
632 qp_attr.ah_attr.grh.sgid_index, &sgid);
633 if (ret)
634 goto out;
635
636 if (rdma_node_get_transport(id_priv->cma_dev->device->node_type)
637 == RDMA_TRANSPORT_IB &&
638 rdma_port_get_link_layer(id_priv->id.device, id_priv->id.port_num)
639 == IB_LINK_LAYER_ETHERNET) {
640 ret = rdma_addr_find_smac_by_sgid(&sgid, qp_attr.smac, NULL);
641
642 if (ret)
643 goto out;
644 }
628 if (conn_param) 645 if (conn_param)
629 qp_attr.max_dest_rd_atomic = conn_param->responder_resources; 646 qp_attr.max_dest_rd_atomic = conn_param->responder_resources;
630 ret = ib_modify_qp(id_priv->id.qp, &qp_attr, qp_attr_mask); 647 ret = ib_modify_qp(id_priv->id.qp, &qp_attr, qp_attr_mask);
@@ -725,6 +742,7 @@ int rdma_init_qp_attr(struct rdma_cm_id *id, struct ib_qp_attr *qp_attr,
725 else 742 else
726 ret = ib_cm_init_qp_attr(id_priv->cm_id.ib, qp_attr, 743 ret = ib_cm_init_qp_attr(id_priv->cm_id.ib, qp_attr,
727 qp_attr_mask); 744 qp_attr_mask);
745
728 if (qp_attr->qp_state == IB_QPS_RTR) 746 if (qp_attr->qp_state == IB_QPS_RTR)
729 qp_attr->rq_psn = id_priv->seq_num; 747 qp_attr->rq_psn = id_priv->seq_num;
730 break; 748 break;
@@ -1266,6 +1284,15 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event)
1266 struct rdma_id_private *listen_id, *conn_id; 1284 struct rdma_id_private *listen_id, *conn_id;
1267 struct rdma_cm_event event; 1285 struct rdma_cm_event event;
1268 int offset, ret; 1286 int offset, ret;
1287 u8 smac[ETH_ALEN];
1288 u8 alt_smac[ETH_ALEN];
1289 u8 *psmac = smac;
1290 u8 *palt_smac = alt_smac;
1291 int is_iboe = ((rdma_node_get_transport(cm_id->device->node_type) ==
1292 RDMA_TRANSPORT_IB) &&
1293 (rdma_port_get_link_layer(cm_id->device,
1294 ib_event->param.req_rcvd.port) ==
1295 IB_LINK_LAYER_ETHERNET));
1269 1296
1270 listen_id = cm_id->context; 1297 listen_id = cm_id->context;
1271 if (!cma_check_req_qp_type(&listen_id->id, ib_event)) 1298 if (!cma_check_req_qp_type(&listen_id->id, ib_event))
@@ -1310,12 +1337,29 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event)
1310 if (ret) 1337 if (ret)
1311 goto err3; 1338 goto err3;
1312 1339
1340 if (is_iboe) {
1341 if (ib_event->param.req_rcvd.primary_path != NULL)
1342 rdma_addr_find_smac_by_sgid(
1343 &ib_event->param.req_rcvd.primary_path->sgid,
1344 psmac, NULL);
1345 else
1346 psmac = NULL;
1347 if (ib_event->param.req_rcvd.alternate_path != NULL)
1348 rdma_addr_find_smac_by_sgid(
1349 &ib_event->param.req_rcvd.alternate_path->sgid,
1350 palt_smac, NULL);
1351 else
1352 palt_smac = NULL;
1353 }
1313 /* 1354 /*
1314 * Acquire mutex to prevent user executing rdma_destroy_id() 1355 * Acquire mutex to prevent user executing rdma_destroy_id()
1315 * while we're accessing the cm_id. 1356 * while we're accessing the cm_id.
1316 */ 1357 */
1317 mutex_lock(&lock); 1358 mutex_lock(&lock);
1318 if (cma_comp(conn_id, RDMA_CM_CONNECT) && (conn_id->id.qp_type != IB_QPT_UD)) 1359 if (is_iboe)
1360 ib_update_cm_av(cm_id, psmac, palt_smac);
1361 if (cma_comp(conn_id, RDMA_CM_CONNECT) &&
1362 (conn_id->id.qp_type != IB_QPT_UD))
1319 ib_send_cm_mra(cm_id, CMA_CM_MRA_SETTING, NULL, 0); 1363 ib_send_cm_mra(cm_id, CMA_CM_MRA_SETTING, NULL, 0);
1320 mutex_unlock(&lock); 1364 mutex_unlock(&lock);
1321 mutex_unlock(&conn_id->handler_mutex); 1365 mutex_unlock(&conn_id->handler_mutex);
@@ -1474,7 +1518,7 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id,
1474 mutex_lock_nested(&conn_id->handler_mutex, SINGLE_DEPTH_NESTING); 1518 mutex_lock_nested(&conn_id->handler_mutex, SINGLE_DEPTH_NESTING);
1475 conn_id->state = RDMA_CM_CONNECT; 1519 conn_id->state = RDMA_CM_CONNECT;
1476 1520
1477 ret = rdma_translate_ip(laddr, &conn_id->id.route.addr.dev_addr); 1521 ret = rdma_translate_ip(laddr, &conn_id->id.route.addr.dev_addr, NULL);
1478 if (ret) { 1522 if (ret) {
1479 mutex_unlock(&conn_id->handler_mutex); 1523 mutex_unlock(&conn_id->handler_mutex);
1480 rdma_destroy_id(new_cm_id); 1524 rdma_destroy_id(new_cm_id);
@@ -1873,7 +1917,7 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv)
1873 struct cma_work *work; 1917 struct cma_work *work;
1874 int ret; 1918 int ret;
1875 struct net_device *ndev = NULL; 1919 struct net_device *ndev = NULL;
1876 u16 vid; 1920
1877 1921
1878 work = kzalloc(sizeof *work, GFP_KERNEL); 1922 work = kzalloc(sizeof *work, GFP_KERNEL);
1879 if (!work) 1923 if (!work)
@@ -1897,10 +1941,14 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv)
1897 goto err2; 1941 goto err2;
1898 } 1942 }
1899 1943
1900 vid = rdma_vlan_dev_vlan_id(ndev); 1944 route->path_rec->vlan_id = rdma_vlan_dev_vlan_id(ndev);
1945 memcpy(route->path_rec->dmac, addr->dev_addr.dst_dev_addr, ETH_ALEN);
1946 memcpy(route->path_rec->smac, ndev->dev_addr, ndev->addr_len);
1901 1947
1902 iboe_mac_vlan_to_ll(&route->path_rec->sgid, addr->dev_addr.src_dev_addr, vid); 1948 rdma_ip2gid((struct sockaddr *)&id_priv->id.route.addr.src_addr,
1903 iboe_mac_vlan_to_ll(&route->path_rec->dgid, addr->dev_addr.dst_dev_addr, vid); 1949 &route->path_rec->sgid);
1950 rdma_ip2gid((struct sockaddr *)&id_priv->id.route.addr.dst_addr,
1951 &route->path_rec->dgid);
1904 1952
1905 route->path_rec->hop_limit = 1; 1953 route->path_rec->hop_limit = 1;
1906 route->path_rec->reversible = 1; 1954 route->path_rec->reversible = 1;
@@ -2063,6 +2111,7 @@ static void addr_handler(int status, struct sockaddr *src_addr,
2063 RDMA_CM_ADDR_RESOLVED)) 2111 RDMA_CM_ADDR_RESOLVED))
2064 goto out; 2112 goto out;
2065 2113
2114 memcpy(cma_src_addr(id_priv), src_addr, rdma_addr_size(src_addr));
2066 if (!status && !id_priv->cma_dev) 2115 if (!status && !id_priv->cma_dev)
2067 status = cma_acquire_dev(id_priv, NULL); 2116 status = cma_acquire_dev(id_priv, NULL);
2068 2117
@@ -2072,10 +2121,8 @@ static void addr_handler(int status, struct sockaddr *src_addr,
2072 goto out; 2121 goto out;
2073 event.event = RDMA_CM_EVENT_ADDR_ERROR; 2122 event.event = RDMA_CM_EVENT_ADDR_ERROR;
2074 event.status = status; 2123 event.status = status;
2075 } else { 2124 } else
2076 memcpy(cma_src_addr(id_priv), src_addr, rdma_addr_size(src_addr));
2077 event.event = RDMA_CM_EVENT_ADDR_RESOLVED; 2125 event.event = RDMA_CM_EVENT_ADDR_RESOLVED;
2078 }
2079 2126
2080 if (id_priv->id.event_handler(&id_priv->id, &event)) { 2127 if (id_priv->id.event_handler(&id_priv->id, &event)) {
2081 cma_exch(id_priv, RDMA_CM_DESTROYING); 2128 cma_exch(id_priv, RDMA_CM_DESTROYING);
@@ -2480,8 +2527,11 @@ static int cma_check_linklocal(struct rdma_dev_addr *dev_addr,
2480 return 0; 2527 return 0;
2481 2528
2482 sin6 = (struct sockaddr_in6 *) addr; 2529 sin6 = (struct sockaddr_in6 *) addr;
2483 if ((ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) && 2530
2484 !sin6->sin6_scope_id) 2531 if (!(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL))
2532 return 0;
2533
2534 if (!sin6->sin6_scope_id)
2485 return -EINVAL; 2535 return -EINVAL;
2486 2536
2487 dev_addr->bound_dev_if = sin6->sin6_scope_id; 2537 dev_addr->bound_dev_if = sin6->sin6_scope_id;
@@ -2556,6 +2606,7 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
2556 if (ret) 2606 if (ret)
2557 goto err1; 2607 goto err1;
2558 2608
2609 memcpy(cma_src_addr(id_priv), addr, rdma_addr_size(addr));
2559 if (!cma_any_addr(addr)) { 2610 if (!cma_any_addr(addr)) {
2560 ret = cma_translate_addr(addr, &id->route.addr.dev_addr); 2611 ret = cma_translate_addr(addr, &id->route.addr.dev_addr);
2561 if (ret) 2612 if (ret)
@@ -2566,7 +2617,6 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
2566 goto err1; 2617 goto err1;
2567 } 2618 }
2568 2619
2569 memcpy(cma_src_addr(id_priv), addr, rdma_addr_size(addr));
2570 if (!(id_priv->options & (1 << CMA_OPTION_AFONLY))) { 2620 if (!(id_priv->options & (1 << CMA_OPTION_AFONLY))) {
2571 if (addr->sa_family == AF_INET) 2621 if (addr->sa_family == AF_INET)
2572 id_priv->afonly = 1; 2622 id_priv->afonly = 1;
@@ -3295,7 +3345,8 @@ static int cma_iboe_join_multicast(struct rdma_id_private *id_priv,
3295 err = -EINVAL; 3345 err = -EINVAL;
3296 goto out2; 3346 goto out2;
3297 } 3347 }
3298 iboe_addr_get_sgid(dev_addr, &mc->multicast.ib->rec.port_gid); 3348 rdma_ip2gid((struct sockaddr *)&id_priv->id.route.addr.src_addr,
3349 &mc->multicast.ib->rec.port_gid);
3299 work->id = id_priv; 3350 work->id = id_priv;
3300 work->mc = mc; 3351 work->mc = mc;
3301 INIT_WORK(&work->work, iboe_mcast_work_handler); 3352 INIT_WORK(&work->work, iboe_mcast_work_handler);
diff --git a/drivers/infiniband/core/core_priv.h b/drivers/infiniband/core/core_priv.h
index a565af5c2d2e..87d1936f5c1c 100644
--- a/drivers/infiniband/core/core_priv.h
+++ b/drivers/infiniband/core/core_priv.h
@@ -49,4 +49,6 @@ void ib_sysfs_cleanup(void);
49int ib_cache_setup(void); 49int ib_cache_setup(void);
50void ib_cache_cleanup(void); 50void ib_cache_cleanup(void);
51 51
52int ib_resolve_eth_l2_attrs(struct ib_qp *qp,
53 struct ib_qp_attr *qp_attr, int *qp_attr_mask);
52#endif /* _CORE_PRIV_H */ 54#endif /* _CORE_PRIV_H */
diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c
index 0717940ec3b5..3d2e489ab732 100644
--- a/drivers/infiniband/core/iwcm.c
+++ b/drivers/infiniband/core/iwcm.c
@@ -334,7 +334,6 @@ static void destroy_cm_id(struct iw_cm_id *cm_id)
334{ 334{
335 struct iwcm_id_private *cm_id_priv; 335 struct iwcm_id_private *cm_id_priv;
336 unsigned long flags; 336 unsigned long flags;
337 int ret;
338 337
339 cm_id_priv = container_of(cm_id, struct iwcm_id_private, id); 338 cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
340 /* 339 /*
@@ -350,7 +349,7 @@ static void destroy_cm_id(struct iw_cm_id *cm_id)
350 cm_id_priv->state = IW_CM_STATE_DESTROYING; 349 cm_id_priv->state = IW_CM_STATE_DESTROYING;
351 spin_unlock_irqrestore(&cm_id_priv->lock, flags); 350 spin_unlock_irqrestore(&cm_id_priv->lock, flags);
352 /* destroy the listening endpoint */ 351 /* destroy the listening endpoint */
353 ret = cm_id->device->iwcm->destroy_listen(cm_id); 352 cm_id->device->iwcm->destroy_listen(cm_id);
354 spin_lock_irqsave(&cm_id_priv->lock, flags); 353 spin_lock_irqsave(&cm_id_priv->lock, flags);
355 break; 354 break;
356 case IW_CM_STATE_ESTABLISHED: 355 case IW_CM_STATE_ESTABLISHED:
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c
index 9838ca484389..f820958e4047 100644
--- a/drivers/infiniband/core/sa_query.c
+++ b/drivers/infiniband/core/sa_query.c
@@ -42,7 +42,7 @@
42#include <linux/kref.h> 42#include <linux/kref.h>
43#include <linux/idr.h> 43#include <linux/idr.h>
44#include <linux/workqueue.h> 44#include <linux/workqueue.h>
45 45#include <uapi/linux/if_ether.h>
46#include <rdma/ib_pack.h> 46#include <rdma/ib_pack.h>
47#include <rdma/ib_cache.h> 47#include <rdma/ib_cache.h>
48#include "sa.h" 48#include "sa.h"
@@ -556,6 +556,13 @@ int ib_init_ah_from_path(struct ib_device *device, u8 port_num,
556 ah_attr->grh.hop_limit = rec->hop_limit; 556 ah_attr->grh.hop_limit = rec->hop_limit;
557 ah_attr->grh.traffic_class = rec->traffic_class; 557 ah_attr->grh.traffic_class = rec->traffic_class;
558 } 558 }
559 if (force_grh) {
560 memcpy(ah_attr->dmac, rec->dmac, ETH_ALEN);
561 ah_attr->vlan_id = rec->vlan_id;
562 } else {
563 ah_attr->vlan_id = 0xffff;
564 }
565
559 return 0; 566 return 0;
560} 567}
561EXPORT_SYMBOL(ib_init_ah_from_path); 568EXPORT_SYMBOL(ib_init_ah_from_path);
@@ -670,6 +677,9 @@ static void ib_sa_path_rec_callback(struct ib_sa_query *sa_query,
670 677
671 ib_unpack(path_rec_table, ARRAY_SIZE(path_rec_table), 678 ib_unpack(path_rec_table, ARRAY_SIZE(path_rec_table),
672 mad->data, &rec); 679 mad->data, &rec);
680 rec.vlan_id = 0xffff;
681 memset(rec.dmac, 0, ETH_ALEN);
682 memset(rec.smac, 0, ETH_ALEN);
673 query->callback(status, &rec, query->context); 683 query->callback(status, &rec, query->context);
674 } else 684 } else
675 query->callback(status, NULL, query->context); 685 query->callback(status, NULL, query->context);
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
index faad2caf22b1..7d3292c7b4b4 100644
--- a/drivers/infiniband/core/sysfs.c
+++ b/drivers/infiniband/core/sysfs.c
@@ -613,6 +613,7 @@ static ssize_t show_node_type(struct device *device,
613 case RDMA_NODE_IB_CA: return sprintf(buf, "%d: CA\n", dev->node_type); 613 case RDMA_NODE_IB_CA: return sprintf(buf, "%d: CA\n", dev->node_type);
614 case RDMA_NODE_RNIC: return sprintf(buf, "%d: RNIC\n", dev->node_type); 614 case RDMA_NODE_RNIC: return sprintf(buf, "%d: RNIC\n", dev->node_type);
615 case RDMA_NODE_USNIC: return sprintf(buf, "%d: usNIC\n", dev->node_type); 615 case RDMA_NODE_USNIC: return sprintf(buf, "%d: usNIC\n", dev->node_type);
616 case RDMA_NODE_USNIC_UDP: return sprintf(buf, "%d: usNIC UDP\n", dev->node_type);
616 case RDMA_NODE_IB_SWITCH: return sprintf(buf, "%d: switch\n", dev->node_type); 617 case RDMA_NODE_IB_SWITCH: return sprintf(buf, "%d: switch\n", dev->node_type);
617 case RDMA_NODE_IB_ROUTER: return sprintf(buf, "%d: router\n", dev->node_type); 618 case RDMA_NODE_IB_ROUTER: return sprintf(buf, "%d: router\n", dev->node_type);
618 default: return sprintf(buf, "%d: <unknown>\n", dev->node_type); 619 default: return sprintf(buf, "%d: <unknown>\n", dev->node_type);
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index ab8b1c30b36b..56a4b7ca7ee3 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -655,24 +655,14 @@ static void ucma_copy_ib_route(struct rdma_ucm_query_route_resp *resp,
655static void ucma_copy_iboe_route(struct rdma_ucm_query_route_resp *resp, 655static void ucma_copy_iboe_route(struct rdma_ucm_query_route_resp *resp,
656 struct rdma_route *route) 656 struct rdma_route *route)
657{ 657{
658 struct rdma_dev_addr *dev_addr;
659 struct net_device *dev;
660 u16 vid = 0;
661 658
662 resp->num_paths = route->num_paths; 659 resp->num_paths = route->num_paths;
663 switch (route->num_paths) { 660 switch (route->num_paths) {
664 case 0: 661 case 0:
665 dev_addr = &route->addr.dev_addr; 662 rdma_ip2gid((struct sockaddr *)&route->addr.dst_addr,
666 dev = dev_get_by_index(&init_net, dev_addr->bound_dev_if); 663 (union ib_gid *)&resp->ib_route[0].dgid);
667 if (dev) { 664 rdma_ip2gid((struct sockaddr *)&route->addr.src_addr,
668 vid = rdma_vlan_dev_vlan_id(dev); 665 (union ib_gid *)&resp->ib_route[0].sgid);
669 dev_put(dev);
670 }
671
672 iboe_mac_vlan_to_ll((union ib_gid *) &resp->ib_route[0].dgid,
673 dev_addr->dst_dev_addr, vid);
674 iboe_addr_get_sgid(dev_addr,
675 (union ib_gid *) &resp->ib_route[0].sgid);
676 resp->ib_route[0].pkey = cpu_to_be16(0xffff); 666 resp->ib_route[0].pkey = cpu_to_be16(0xffff);
677 break; 667 break;
678 case 2: 668 case 2:
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index f1cc83855af6..ea6203ee7bcc 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -40,6 +40,7 @@
40#include <asm/uaccess.h> 40#include <asm/uaccess.h>
41 41
42#include "uverbs.h" 42#include "uverbs.h"
43#include "core_priv.h"
43 44
44struct uverbs_lock_class { 45struct uverbs_lock_class {
45 struct lock_class_key key; 46 struct lock_class_key key;
@@ -1961,6 +1962,9 @@ ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,
1961 attr->alt_ah_attr.port_num = cmd.alt_dest.port_num; 1962 attr->alt_ah_attr.port_num = cmd.alt_dest.port_num;
1962 1963
1963 if (qp->real_qp == qp) { 1964 if (qp->real_qp == qp) {
1965 ret = ib_resolve_eth_l2_attrs(qp, attr, &cmd.attr_mask);
1966 if (ret)
1967 goto out;
1964 ret = qp->device->modify_qp(qp, attr, 1968 ret = qp->device->modify_qp(qp, attr,
1965 modify_qp_mask(qp->qp_type, cmd.attr_mask), &udata); 1969 modify_qp_mask(qp->qp_type, cmd.attr_mask), &udata);
1966 } else { 1970 } else {
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
index d4f6ddf72ffa..3ac795115438 100644
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -44,6 +44,9 @@
44 44
45#include <rdma/ib_verbs.h> 45#include <rdma/ib_verbs.h>
46#include <rdma/ib_cache.h> 46#include <rdma/ib_cache.h>
47#include <rdma/ib_addr.h>
48
49#include "core_priv.h"
47 50
48int ib_rate_to_mult(enum ib_rate rate) 51int ib_rate_to_mult(enum ib_rate rate)
49{ 52{
@@ -116,6 +119,8 @@ rdma_node_get_transport(enum rdma_node_type node_type)
116 return RDMA_TRANSPORT_IWARP; 119 return RDMA_TRANSPORT_IWARP;
117 case RDMA_NODE_USNIC: 120 case RDMA_NODE_USNIC:
118 return RDMA_TRANSPORT_USNIC; 121 return RDMA_TRANSPORT_USNIC;
122 case RDMA_NODE_USNIC_UDP:
123 return RDMA_TRANSPORT_USNIC_UDP;
119 default: 124 default:
120 BUG(); 125 BUG();
121 return 0; 126 return 0;
@@ -133,6 +138,7 @@ enum rdma_link_layer rdma_port_get_link_layer(struct ib_device *device, u8 port_
133 return IB_LINK_LAYER_INFINIBAND; 138 return IB_LINK_LAYER_INFINIBAND;
134 case RDMA_TRANSPORT_IWARP: 139 case RDMA_TRANSPORT_IWARP:
135 case RDMA_TRANSPORT_USNIC: 140 case RDMA_TRANSPORT_USNIC:
141 case RDMA_TRANSPORT_USNIC_UDP:
136 return IB_LINK_LAYER_ETHERNET; 142 return IB_LINK_LAYER_ETHERNET;
137 default: 143 default:
138 return IB_LINK_LAYER_UNSPECIFIED; 144 return IB_LINK_LAYER_UNSPECIFIED;
@@ -192,8 +198,28 @@ int ib_init_ah_from_wc(struct ib_device *device, u8 port_num, struct ib_wc *wc,
192 u32 flow_class; 198 u32 flow_class;
193 u16 gid_index; 199 u16 gid_index;
194 int ret; 200 int ret;
201 int is_eth = (rdma_port_get_link_layer(device, port_num) ==
202 IB_LINK_LAYER_ETHERNET);
195 203
196 memset(ah_attr, 0, sizeof *ah_attr); 204 memset(ah_attr, 0, sizeof *ah_attr);
205 if (is_eth) {
206 if (!(wc->wc_flags & IB_WC_GRH))
207 return -EPROTOTYPE;
208
209 if (wc->wc_flags & IB_WC_WITH_SMAC &&
210 wc->wc_flags & IB_WC_WITH_VLAN) {
211 memcpy(ah_attr->dmac, wc->smac, ETH_ALEN);
212 ah_attr->vlan_id = wc->vlan_id;
213 } else {
214 ret = rdma_addr_find_dmac_by_grh(&grh->dgid, &grh->sgid,
215 ah_attr->dmac, &ah_attr->vlan_id);
216 if (ret)
217 return ret;
218 }
219 } else {
220 ah_attr->vlan_id = 0xffff;
221 }
222
197 ah_attr->dlid = wc->slid; 223 ah_attr->dlid = wc->slid;
198 ah_attr->sl = wc->sl; 224 ah_attr->sl = wc->sl;
199 ah_attr->src_path_bits = wc->dlid_path_bits; 225 ah_attr->src_path_bits = wc->dlid_path_bits;
@@ -476,7 +502,9 @@ EXPORT_SYMBOL(ib_create_qp);
476static const struct { 502static const struct {
477 int valid; 503 int valid;
478 enum ib_qp_attr_mask req_param[IB_QPT_MAX]; 504 enum ib_qp_attr_mask req_param[IB_QPT_MAX];
505 enum ib_qp_attr_mask req_param_add_eth[IB_QPT_MAX];
479 enum ib_qp_attr_mask opt_param[IB_QPT_MAX]; 506 enum ib_qp_attr_mask opt_param[IB_QPT_MAX];
507 enum ib_qp_attr_mask opt_param_add_eth[IB_QPT_MAX];
480} qp_state_table[IB_QPS_ERR + 1][IB_QPS_ERR + 1] = { 508} qp_state_table[IB_QPS_ERR + 1][IB_QPS_ERR + 1] = {
481 [IB_QPS_RESET] = { 509 [IB_QPS_RESET] = {
482 [IB_QPS_RESET] = { .valid = 1 }, 510 [IB_QPS_RESET] = { .valid = 1 },
@@ -557,6 +585,12 @@ static const struct {
557 IB_QP_MAX_DEST_RD_ATOMIC | 585 IB_QP_MAX_DEST_RD_ATOMIC |
558 IB_QP_MIN_RNR_TIMER), 586 IB_QP_MIN_RNR_TIMER),
559 }, 587 },
588 .req_param_add_eth = {
589 [IB_QPT_RC] = (IB_QP_SMAC),
590 [IB_QPT_UC] = (IB_QP_SMAC),
591 [IB_QPT_XRC_INI] = (IB_QP_SMAC),
592 [IB_QPT_XRC_TGT] = (IB_QP_SMAC)
593 },
560 .opt_param = { 594 .opt_param = {
561 [IB_QPT_UD] = (IB_QP_PKEY_INDEX | 595 [IB_QPT_UD] = (IB_QP_PKEY_INDEX |
562 IB_QP_QKEY), 596 IB_QP_QKEY),
@@ -576,7 +610,21 @@ static const struct {
576 IB_QP_QKEY), 610 IB_QP_QKEY),
577 [IB_QPT_GSI] = (IB_QP_PKEY_INDEX | 611 [IB_QPT_GSI] = (IB_QP_PKEY_INDEX |
578 IB_QP_QKEY), 612 IB_QP_QKEY),
579 } 613 },
614 .opt_param_add_eth = {
615 [IB_QPT_RC] = (IB_QP_ALT_SMAC |
616 IB_QP_VID |
617 IB_QP_ALT_VID),
618 [IB_QPT_UC] = (IB_QP_ALT_SMAC |
619 IB_QP_VID |
620 IB_QP_ALT_VID),
621 [IB_QPT_XRC_INI] = (IB_QP_ALT_SMAC |
622 IB_QP_VID |
623 IB_QP_ALT_VID),
624 [IB_QPT_XRC_TGT] = (IB_QP_ALT_SMAC |
625 IB_QP_VID |
626 IB_QP_ALT_VID)
627 }
580 } 628 }
581 }, 629 },
582 [IB_QPS_RTR] = { 630 [IB_QPS_RTR] = {
@@ -779,7 +827,8 @@ static const struct {
779}; 827};
780 828
781int ib_modify_qp_is_ok(enum ib_qp_state cur_state, enum ib_qp_state next_state, 829int ib_modify_qp_is_ok(enum ib_qp_state cur_state, enum ib_qp_state next_state,
782 enum ib_qp_type type, enum ib_qp_attr_mask mask) 830 enum ib_qp_type type, enum ib_qp_attr_mask mask,
831 enum rdma_link_layer ll)
783{ 832{
784 enum ib_qp_attr_mask req_param, opt_param; 833 enum ib_qp_attr_mask req_param, opt_param;
785 834
@@ -798,6 +847,13 @@ int ib_modify_qp_is_ok(enum ib_qp_state cur_state, enum ib_qp_state next_state,
798 req_param = qp_state_table[cur_state][next_state].req_param[type]; 847 req_param = qp_state_table[cur_state][next_state].req_param[type];
799 opt_param = qp_state_table[cur_state][next_state].opt_param[type]; 848 opt_param = qp_state_table[cur_state][next_state].opt_param[type];
800 849
850 if (ll == IB_LINK_LAYER_ETHERNET) {
851 req_param |= qp_state_table[cur_state][next_state].
852 req_param_add_eth[type];
853 opt_param |= qp_state_table[cur_state][next_state].
854 opt_param_add_eth[type];
855 }
856
801 if ((mask & req_param) != req_param) 857 if ((mask & req_param) != req_param)
802 return 0; 858 return 0;
803 859
@@ -808,10 +864,51 @@ int ib_modify_qp_is_ok(enum ib_qp_state cur_state, enum ib_qp_state next_state,
808} 864}
809EXPORT_SYMBOL(ib_modify_qp_is_ok); 865EXPORT_SYMBOL(ib_modify_qp_is_ok);
810 866
867int ib_resolve_eth_l2_attrs(struct ib_qp *qp,
868 struct ib_qp_attr *qp_attr, int *qp_attr_mask)
869{
870 int ret = 0;
871 union ib_gid sgid;
872
873 if ((*qp_attr_mask & IB_QP_AV) &&
874 (rdma_port_get_link_layer(qp->device, qp_attr->ah_attr.port_num) == IB_LINK_LAYER_ETHERNET)) {
875 ret = ib_query_gid(qp->device, qp_attr->ah_attr.port_num,
876 qp_attr->ah_attr.grh.sgid_index, &sgid);
877 if (ret)
878 goto out;
879 if (rdma_link_local_addr((struct in6_addr *)qp_attr->ah_attr.grh.dgid.raw)) {
880 rdma_get_ll_mac((struct in6_addr *)qp_attr->ah_attr.grh.dgid.raw, qp_attr->ah_attr.dmac);
881 rdma_get_ll_mac((struct in6_addr *)sgid.raw, qp_attr->smac);
882 qp_attr->vlan_id = rdma_get_vlan_id(&sgid);
883 } else {
884 ret = rdma_addr_find_dmac_by_grh(&sgid, &qp_attr->ah_attr.grh.dgid,
885 qp_attr->ah_attr.dmac, &qp_attr->vlan_id);
886 if (ret)
887 goto out;
888 ret = rdma_addr_find_smac_by_sgid(&sgid, qp_attr->smac, NULL);
889 if (ret)
890 goto out;
891 }
892 *qp_attr_mask |= IB_QP_SMAC;
893 if (qp_attr->vlan_id < 0xFFFF)
894 *qp_attr_mask |= IB_QP_VID;
895 }
896out:
897 return ret;
898}
899EXPORT_SYMBOL(ib_resolve_eth_l2_attrs);
900
901
811int ib_modify_qp(struct ib_qp *qp, 902int ib_modify_qp(struct ib_qp *qp,
812 struct ib_qp_attr *qp_attr, 903 struct ib_qp_attr *qp_attr,
813 int qp_attr_mask) 904 int qp_attr_mask)
814{ 905{
906 int ret;
907
908 ret = ib_resolve_eth_l2_attrs(qp, qp_attr, &qp_attr_mask);
909 if (ret)
910 return ret;
911
815 return qp->device->modify_qp(qp->real_qp, qp_attr, qp_attr_mask, NULL); 912 return qp->device->modify_qp(qp->real_qp, qp_attr, qp_attr_mask, NULL);
816} 913}
817EXPORT_SYMBOL(ib_modify_qp); 914EXPORT_SYMBOL(ib_modify_qp);
diff --git a/drivers/infiniband/hw/amso1100/c2_intr.c b/drivers/infiniband/hw/amso1100/c2_intr.c
index 8951db4ae29d..3a17d9b36dba 100644
--- a/drivers/infiniband/hw/amso1100/c2_intr.c
+++ b/drivers/infiniband/hw/amso1100/c2_intr.c
@@ -169,7 +169,8 @@ static void handle_vq(struct c2_dev *c2dev, u32 mq_index)
169 * We should never get here, as the adapter should 169 * We should never get here, as the adapter should
170 * never send us a reply that we're not expecting. 170 * never send us a reply that we're not expecting.
171 */ 171 */
172 vq_repbuf_free(c2dev, host_msg); 172 if (reply_msg != NULL)
173 vq_repbuf_free(c2dev, host_msg);
173 pr_debug("handle_vq: UNEXPECTEDLY got NULL req\n"); 174 pr_debug("handle_vq: UNEXPECTEDLY got NULL req\n");
174 return; 175 return;
175 } 176 }
diff --git a/drivers/infiniband/hw/cxgb4/mem.c b/drivers/infiniband/hw/cxgb4/mem.c
index 84e45006451c..41b11951a30a 100644
--- a/drivers/infiniband/hw/cxgb4/mem.c
+++ b/drivers/infiniband/hw/cxgb4/mem.c
@@ -76,7 +76,7 @@ static int _c4iw_write_mem_dma_aligned(struct c4iw_rdev *rdev, u32 addr,
76 INIT_ULPTX_WR(req, wr_len, 0, 0); 76 INIT_ULPTX_WR(req, wr_len, 0, 0);
77 req->wr.wr_hi = cpu_to_be32(FW_WR_OP(FW_ULPTX_WR) | 77 req->wr.wr_hi = cpu_to_be32(FW_WR_OP(FW_ULPTX_WR) |
78 (wait ? FW_WR_COMPL(1) : 0)); 78 (wait ? FW_WR_COMPL(1) : 0));
79 req->wr.wr_lo = wait ? (__force __be64)&wr_wait : 0; 79 req->wr.wr_lo = wait ? (__force __be64)(unsigned long) &wr_wait : 0L;
80 req->wr.wr_mid = cpu_to_be32(FW_WR_LEN16(DIV_ROUND_UP(wr_len, 16))); 80 req->wr.wr_mid = cpu_to_be32(FW_WR_LEN16(DIV_ROUND_UP(wr_len, 16)));
81 req->cmd = cpu_to_be32(ULPTX_CMD(ULP_TX_MEM_WRITE)); 81 req->cmd = cpu_to_be32(ULPTX_CMD(ULP_TX_MEM_WRITE));
82 req->cmd |= cpu_to_be32(V_T5_ULP_MEMIO_ORDER(1)); 82 req->cmd |= cpu_to_be32(V_T5_ULP_MEMIO_ORDER(1));
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c
index 00d6861a6a18..2e89356c46fa 100644
--- a/drivers/infiniband/hw/ehca/ehca_qp.c
+++ b/drivers/infiniband/hw/ehca/ehca_qp.c
@@ -1329,7 +1329,7 @@ static int internal_modify_qp(struct ib_qp *ibqp,
1329 qp_new_state = attr_mask & IB_QP_STATE ? attr->qp_state : qp_cur_state; 1329 qp_new_state = attr_mask & IB_QP_STATE ? attr->qp_state : qp_cur_state;
1330 if (!smi_reset2init && 1330 if (!smi_reset2init &&
1331 !ib_modify_qp_is_ok(qp_cur_state, qp_new_state, ibqp->qp_type, 1331 !ib_modify_qp_is_ok(qp_cur_state, qp_new_state, ibqp->qp_type,
1332 attr_mask)) { 1332 attr_mask, IB_LINK_LAYER_UNSPECIFIED)) {
1333 ret = -EINVAL; 1333 ret = -EINVAL;
1334 ehca_err(ibqp->device, 1334 ehca_err(ibqp->device,
1335 "Invalid qp transition new_state=%x cur_state=%x " 1335 "Invalid qp transition new_state=%x cur_state=%x "
diff --git a/drivers/infiniband/hw/ipath/ipath_qp.c b/drivers/infiniband/hw/ipath/ipath_qp.c
index 0857a9c3cd3d..face87602dc1 100644
--- a/drivers/infiniband/hw/ipath/ipath_qp.c
+++ b/drivers/infiniband/hw/ipath/ipath_qp.c
@@ -463,7 +463,7 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
463 new_state = attr_mask & IB_QP_STATE ? attr->qp_state : cur_state; 463 new_state = attr_mask & IB_QP_STATE ? attr->qp_state : cur_state;
464 464
465 if (!ib_modify_qp_is_ok(cur_state, new_state, ibqp->qp_type, 465 if (!ib_modify_qp_is_ok(cur_state, new_state, ibqp->qp_type,
466 attr_mask)) 466 attr_mask, IB_LINK_LAYER_UNSPECIFIED))
467 goto inval; 467 goto inval;
468 468
469 if (attr_mask & IB_QP_AV) { 469 if (attr_mask & IB_QP_AV) {
diff --git a/drivers/infiniband/hw/mlx4/Kconfig b/drivers/infiniband/hw/mlx4/Kconfig
index 24ab11a9ad1e..fc01deac1d3c 100644
--- a/drivers/infiniband/hw/mlx4/Kconfig
+++ b/drivers/infiniband/hw/mlx4/Kconfig
@@ -1,6 +1,6 @@
1config MLX4_INFINIBAND 1config MLX4_INFINIBAND
2 tristate "Mellanox ConnectX HCA support" 2 tristate "Mellanox ConnectX HCA support"
3 depends on NETDEVICES && ETHERNET && PCI 3 depends on NETDEVICES && ETHERNET && PCI && INET
4 select NET_VENDOR_MELLANOX 4 select NET_VENDOR_MELLANOX
5 select MLX4_CORE 5 select MLX4_CORE
6 ---help--- 6 ---help---
diff --git a/drivers/infiniband/hw/mlx4/ah.c b/drivers/infiniband/hw/mlx4/ah.c
index a251becdaa98..170dca608042 100644
--- a/drivers/infiniband/hw/mlx4/ah.c
+++ b/drivers/infiniband/hw/mlx4/ah.c
@@ -39,25 +39,6 @@
39 39
40#include "mlx4_ib.h" 40#include "mlx4_ib.h"
41 41
42int mlx4_ib_resolve_grh(struct mlx4_ib_dev *dev, const struct ib_ah_attr *ah_attr,
43 u8 *mac, int *is_mcast, u8 port)
44{
45 struct in6_addr in6;
46
47 *is_mcast = 0;
48
49 memcpy(&in6, ah_attr->grh.dgid.raw, sizeof in6);
50 if (rdma_link_local_addr(&in6))
51 rdma_get_ll_mac(&in6, mac);
52 else if (rdma_is_multicast_addr(&in6)) {
53 rdma_get_mcast_mac(&in6, mac);
54 *is_mcast = 1;
55 } else
56 return -EINVAL;
57
58 return 0;
59}
60
61static struct ib_ah *create_ib_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr, 42static struct ib_ah *create_ib_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr,
62 struct mlx4_ib_ah *ah) 43 struct mlx4_ib_ah *ah)
63{ 44{
@@ -92,21 +73,18 @@ static struct ib_ah *create_iboe_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr
92{ 73{
93 struct mlx4_ib_dev *ibdev = to_mdev(pd->device); 74 struct mlx4_ib_dev *ibdev = to_mdev(pd->device);
94 struct mlx4_dev *dev = ibdev->dev; 75 struct mlx4_dev *dev = ibdev->dev;
95 union ib_gid sgid;
96 u8 mac[6];
97 int err;
98 int is_mcast; 76 int is_mcast;
77 struct in6_addr in6;
99 u16 vlan_tag; 78 u16 vlan_tag;
100 79
101 err = mlx4_ib_resolve_grh(ibdev, ah_attr, mac, &is_mcast, ah_attr->port_num); 80 memcpy(&in6, ah_attr->grh.dgid.raw, sizeof(in6));
102 if (err) 81 if (rdma_is_multicast_addr(&in6)) {
103 return ERR_PTR(err); 82 is_mcast = 1;
104 83 rdma_get_mcast_mac(&in6, ah->av.eth.mac);
105 memcpy(ah->av.eth.mac, mac, 6); 84 } else {
106 err = ib_get_cached_gid(pd->device, ah_attr->port_num, ah_attr->grh.sgid_index, &sgid); 85 memcpy(ah->av.eth.mac, ah_attr->dmac, ETH_ALEN);
107 if (err) 86 }
108 return ERR_PTR(err); 87 vlan_tag = ah_attr->vlan_id;
109 vlan_tag = rdma_get_vlan_id(&sgid);
110 if (vlan_tag < 0x1000) 88 if (vlan_tag < 0x1000)
111 vlan_tag |= (ah_attr->sl & 7) << 13; 89 vlan_tag |= (ah_attr->sl & 7) << 13;
112 ah->av.eth.port_pd = cpu_to_be32(to_mpd(pd)->pdn | (ah_attr->port_num << 24)); 90 ah->av.eth.port_pd = cpu_to_be32(to_mpd(pd)->pdn | (ah_attr->port_num << 24));
diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c
index 66dbf8062374..cc40f08ca8f1 100644
--- a/drivers/infiniband/hw/mlx4/cq.c
+++ b/drivers/infiniband/hw/mlx4/cq.c
@@ -798,6 +798,15 @@ repoll:
798 wc->sl = be16_to_cpu(cqe->sl_vid) >> 13; 798 wc->sl = be16_to_cpu(cqe->sl_vid) >> 13;
799 else 799 else
800 wc->sl = be16_to_cpu(cqe->sl_vid) >> 12; 800 wc->sl = be16_to_cpu(cqe->sl_vid) >> 12;
801 if (be32_to_cpu(cqe->vlan_my_qpn) & MLX4_CQE_VLAN_PRESENT_MASK) {
802 wc->vlan_id = be16_to_cpu(cqe->sl_vid) &
803 MLX4_CQE_VID_MASK;
804 } else {
805 wc->vlan_id = 0xffff;
806 }
807 wc->wc_flags |= IB_WC_WITH_VLAN;
808 memcpy(wc->smac, cqe->smac, ETH_ALEN);
809 wc->wc_flags |= IB_WC_WITH_SMAC;
801 } 810 }
802 811
803 return 0; 812 return 0;
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index 1958c5ca792a..c2702f549f10 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -39,6 +39,8 @@
39#include <linux/inetdevice.h> 39#include <linux/inetdevice.h>
40#include <linux/rtnetlink.h> 40#include <linux/rtnetlink.h>
41#include <linux/if_vlan.h> 41#include <linux/if_vlan.h>
42#include <net/ipv6.h>
43#include <net/addrconf.h>
42 44
43#include <rdma/ib_smi.h> 45#include <rdma/ib_smi.h>
44#include <rdma/ib_user_verbs.h> 46#include <rdma/ib_user_verbs.h>
@@ -55,6 +57,7 @@
55#define DRV_RELDATE "April 4, 2008" 57#define DRV_RELDATE "April 4, 2008"
56 58
57#define MLX4_IB_FLOW_MAX_PRIO 0xFFF 59#define MLX4_IB_FLOW_MAX_PRIO 0xFFF
60#define MLX4_IB_FLOW_QPN_MASK 0xFFFFFF
58 61
59MODULE_AUTHOR("Roland Dreier"); 62MODULE_AUTHOR("Roland Dreier");
60MODULE_DESCRIPTION("Mellanox ConnectX HCA InfiniBand driver"); 63MODULE_DESCRIPTION("Mellanox ConnectX HCA InfiniBand driver");
@@ -92,21 +95,27 @@ static union ib_gid zgid;
92 95
93static int check_flow_steering_support(struct mlx4_dev *dev) 96static int check_flow_steering_support(struct mlx4_dev *dev)
94{ 97{
98 int eth_num_ports = 0;
95 int ib_num_ports = 0; 99 int ib_num_ports = 0;
96 int i;
97
98 mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_IB)
99 ib_num_ports++;
100 100
101 if (dev->caps.steering_mode == MLX4_STEERING_MODE_DEVICE_MANAGED) { 101 int dmfs = dev->caps.steering_mode == MLX4_STEERING_MODE_DEVICE_MANAGED;
102 if (ib_num_ports || mlx4_is_mfunc(dev)) { 102
103 pr_warn("Device managed flow steering is unavailable " 103 if (dmfs) {
104 "for IB ports or in multifunction env.\n"); 104 int i;
105 return 0; 105 mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_ETH)
106 eth_num_ports++;
107 mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_IB)
108 ib_num_ports++;
109 dmfs &= (!ib_num_ports ||
110 (dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_DMFS_IPOIB)) &&
111 (!eth_num_ports ||
112 (dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_FS_EN));
113 if (ib_num_ports && mlx4_is_mfunc(dev)) {
114 pr_warn("Device managed flow steering is unavailable for IB port in multifunction env.\n");
115 dmfs = 0;
106 } 116 }
107 return 1;
108 } 117 }
109 return 0; 118 return dmfs;
110} 119}
111 120
112static int mlx4_ib_query_device(struct ib_device *ibdev, 121static int mlx4_ib_query_device(struct ib_device *ibdev,
@@ -165,7 +174,7 @@ static int mlx4_ib_query_device(struct ib_device *ibdev,
165 props->device_cap_flags |= IB_DEVICE_MEM_WINDOW_TYPE_2B; 174 props->device_cap_flags |= IB_DEVICE_MEM_WINDOW_TYPE_2B;
166 else 175 else
167 props->device_cap_flags |= IB_DEVICE_MEM_WINDOW_TYPE_2A; 176 props->device_cap_flags |= IB_DEVICE_MEM_WINDOW_TYPE_2A;
168 if (check_flow_steering_support(dev->dev)) 177 if (dev->steering_support == MLX4_STEERING_MODE_DEVICE_MANAGED)
169 props->device_cap_flags |= IB_DEVICE_MANAGED_FLOW_STEERING; 178 props->device_cap_flags |= IB_DEVICE_MANAGED_FLOW_STEERING;
170 } 179 }
171 180
@@ -787,7 +796,6 @@ static int add_gid_entry(struct ib_qp *ibqp, union ib_gid *gid)
787int mlx4_ib_add_mc(struct mlx4_ib_dev *mdev, struct mlx4_ib_qp *mqp, 796int mlx4_ib_add_mc(struct mlx4_ib_dev *mdev, struct mlx4_ib_qp *mqp,
788 union ib_gid *gid) 797 union ib_gid *gid)
789{ 798{
790 u8 mac[6];
791 struct net_device *ndev; 799 struct net_device *ndev;
792 int ret = 0; 800 int ret = 0;
793 801
@@ -801,11 +809,7 @@ int mlx4_ib_add_mc(struct mlx4_ib_dev *mdev, struct mlx4_ib_qp *mqp,
801 spin_unlock(&mdev->iboe.lock); 809 spin_unlock(&mdev->iboe.lock);
802 810
803 if (ndev) { 811 if (ndev) {
804 rdma_get_mcast_mac((struct in6_addr *)gid, mac);
805 rtnl_lock();
806 dev_mc_add(mdev->iboe.netdevs[mqp->port - 1], mac);
807 ret = 1; 812 ret = 1;
808 rtnl_unlock();
809 dev_put(ndev); 813 dev_put(ndev);
810 } 814 }
811 815
@@ -819,6 +823,7 @@ struct mlx4_ib_steering {
819}; 823};
820 824
821static int parse_flow_attr(struct mlx4_dev *dev, 825static int parse_flow_attr(struct mlx4_dev *dev,
826 u32 qp_num,
822 union ib_flow_spec *ib_spec, 827 union ib_flow_spec *ib_spec,
823 struct _rule_hw *mlx4_spec) 828 struct _rule_hw *mlx4_spec)
824{ 829{
@@ -834,6 +839,14 @@ static int parse_flow_attr(struct mlx4_dev *dev,
834 mlx4_spec->eth.vlan_tag = ib_spec->eth.val.vlan_tag; 839 mlx4_spec->eth.vlan_tag = ib_spec->eth.val.vlan_tag;
835 mlx4_spec->eth.vlan_tag_msk = ib_spec->eth.mask.vlan_tag; 840 mlx4_spec->eth.vlan_tag_msk = ib_spec->eth.mask.vlan_tag;
836 break; 841 break;
842 case IB_FLOW_SPEC_IB:
843 type = MLX4_NET_TRANS_RULE_ID_IB;
844 mlx4_spec->ib.l3_qpn =
845 cpu_to_be32(qp_num);
846 mlx4_spec->ib.qpn_mask =
847 cpu_to_be32(MLX4_IB_FLOW_QPN_MASK);
848 break;
849
837 850
838 case IB_FLOW_SPEC_IPV4: 851 case IB_FLOW_SPEC_IPV4:
839 type = MLX4_NET_TRANS_RULE_ID_IPV4; 852 type = MLX4_NET_TRANS_RULE_ID_IPV4;
@@ -865,6 +878,115 @@ static int parse_flow_attr(struct mlx4_dev *dev,
865 return mlx4_hw_rule_sz(dev, type); 878 return mlx4_hw_rule_sz(dev, type);
866} 879}
867 880
881struct default_rules {
882 __u32 mandatory_fields[IB_FLOW_SPEC_SUPPORT_LAYERS];
883 __u32 mandatory_not_fields[IB_FLOW_SPEC_SUPPORT_LAYERS];
884 __u32 rules_create_list[IB_FLOW_SPEC_SUPPORT_LAYERS];
885 __u8 link_layer;
886};
887static const struct default_rules default_table[] = {
888 {
889 .mandatory_fields = {IB_FLOW_SPEC_IPV4},
890 .mandatory_not_fields = {IB_FLOW_SPEC_ETH},
891 .rules_create_list = {IB_FLOW_SPEC_IB},
892 .link_layer = IB_LINK_LAYER_INFINIBAND
893 }
894};
895
896static int __mlx4_ib_default_rules_match(struct ib_qp *qp,
897 struct ib_flow_attr *flow_attr)
898{
899 int i, j, k;
900 void *ib_flow;
901 const struct default_rules *pdefault_rules = default_table;
902 u8 link_layer = rdma_port_get_link_layer(qp->device, flow_attr->port);
903
904 for (i = 0; i < sizeof(default_table)/sizeof(default_table[0]); i++,
905 pdefault_rules++) {
906 __u32 field_types[IB_FLOW_SPEC_SUPPORT_LAYERS];
907 memset(&field_types, 0, sizeof(field_types));
908
909 if (link_layer != pdefault_rules->link_layer)
910 continue;
911
912 ib_flow = flow_attr + 1;
913 /* we assume the specs are sorted */
914 for (j = 0, k = 0; k < IB_FLOW_SPEC_SUPPORT_LAYERS &&
915 j < flow_attr->num_of_specs; k++) {
916 union ib_flow_spec *current_flow =
917 (union ib_flow_spec *)ib_flow;
918
919 /* same layer but different type */
920 if (((current_flow->type & IB_FLOW_SPEC_LAYER_MASK) ==
921 (pdefault_rules->mandatory_fields[k] &
922 IB_FLOW_SPEC_LAYER_MASK)) &&
923 (current_flow->type !=
924 pdefault_rules->mandatory_fields[k]))
925 goto out;
926
927 /* same layer, try match next one */
928 if (current_flow->type ==
929 pdefault_rules->mandatory_fields[k]) {
930 j++;
931 ib_flow +=
932 ((union ib_flow_spec *)ib_flow)->size;
933 }
934 }
935
936 ib_flow = flow_attr + 1;
937 for (j = 0; j < flow_attr->num_of_specs;
938 j++, ib_flow += ((union ib_flow_spec *)ib_flow)->size)
939 for (k = 0; k < IB_FLOW_SPEC_SUPPORT_LAYERS; k++)
940 /* same layer and same type */
941 if (((union ib_flow_spec *)ib_flow)->type ==
942 pdefault_rules->mandatory_not_fields[k])
943 goto out;
944
945 return i;
946 }
947out:
948 return -1;
949}
950
951static int __mlx4_ib_create_default_rules(
952 struct mlx4_ib_dev *mdev,
953 struct ib_qp *qp,
954 const struct default_rules *pdefault_rules,
955 struct _rule_hw *mlx4_spec) {
956 int size = 0;
957 int i;
958
959 for (i = 0; i < sizeof(pdefault_rules->rules_create_list)/
960 sizeof(pdefault_rules->rules_create_list[0]); i++) {
961 int ret;
962 union ib_flow_spec ib_spec;
963 switch (pdefault_rules->rules_create_list[i]) {
964 case 0:
965 /* no rule */
966 continue;
967 case IB_FLOW_SPEC_IB:
968 ib_spec.type = IB_FLOW_SPEC_IB;
969 ib_spec.size = sizeof(struct ib_flow_spec_ib);
970
971 break;
972 default:
973 /* invalid rule */
974 return -EINVAL;
975 }
976 /* We must put empty rule, qpn is being ignored */
977 ret = parse_flow_attr(mdev->dev, 0, &ib_spec,
978 mlx4_spec);
979 if (ret < 0) {
980 pr_info("invalid parsing\n");
981 return -EINVAL;
982 }
983
984 mlx4_spec = (void *)mlx4_spec + ret;
985 size += ret;
986 }
987 return size;
988}
989
868static int __mlx4_ib_create_flow(struct ib_qp *qp, struct ib_flow_attr *flow_attr, 990static int __mlx4_ib_create_flow(struct ib_qp *qp, struct ib_flow_attr *flow_attr,
869 int domain, 991 int domain,
870 enum mlx4_net_trans_promisc_mode flow_type, 992 enum mlx4_net_trans_promisc_mode flow_type,
@@ -876,6 +998,7 @@ static int __mlx4_ib_create_flow(struct ib_qp *qp, struct ib_flow_attr *flow_att
876 struct mlx4_ib_dev *mdev = to_mdev(qp->device); 998 struct mlx4_ib_dev *mdev = to_mdev(qp->device);
877 struct mlx4_cmd_mailbox *mailbox; 999 struct mlx4_cmd_mailbox *mailbox;
878 struct mlx4_net_trans_rule_hw_ctrl *ctrl; 1000 struct mlx4_net_trans_rule_hw_ctrl *ctrl;
1001 int default_flow;
879 1002
880 static const u16 __mlx4_domain[] = { 1003 static const u16 __mlx4_domain[] = {
881 [IB_FLOW_DOMAIN_USER] = MLX4_DOMAIN_UVERBS, 1004 [IB_FLOW_DOMAIN_USER] = MLX4_DOMAIN_UVERBS,
@@ -910,8 +1033,21 @@ static int __mlx4_ib_create_flow(struct ib_qp *qp, struct ib_flow_attr *flow_att
910 1033
911 ib_flow = flow_attr + 1; 1034 ib_flow = flow_attr + 1;
912 size += sizeof(struct mlx4_net_trans_rule_hw_ctrl); 1035 size += sizeof(struct mlx4_net_trans_rule_hw_ctrl);
1036 /* Add default flows */
1037 default_flow = __mlx4_ib_default_rules_match(qp, flow_attr);
1038 if (default_flow >= 0) {
1039 ret = __mlx4_ib_create_default_rules(
1040 mdev, qp, default_table + default_flow,
1041 mailbox->buf + size);
1042 if (ret < 0) {
1043 mlx4_free_cmd_mailbox(mdev->dev, mailbox);
1044 return -EINVAL;
1045 }
1046 size += ret;
1047 }
913 for (i = 0; i < flow_attr->num_of_specs; i++) { 1048 for (i = 0; i < flow_attr->num_of_specs; i++) {
914 ret = parse_flow_attr(mdev->dev, ib_flow, mailbox->buf + size); 1049 ret = parse_flow_attr(mdev->dev, qp->qp_num, ib_flow,
1050 mailbox->buf + size);
915 if (ret < 0) { 1051 if (ret < 0) {
916 mlx4_free_cmd_mailbox(mdev->dev, mailbox); 1052 mlx4_free_cmd_mailbox(mdev->dev, mailbox);
917 return -EINVAL; 1053 return -EINVAL;
@@ -1025,6 +1161,8 @@ static int mlx4_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
1025 struct mlx4_ib_qp *mqp = to_mqp(ibqp); 1161 struct mlx4_ib_qp *mqp = to_mqp(ibqp);
1026 u64 reg_id; 1162 u64 reg_id;
1027 struct mlx4_ib_steering *ib_steering = NULL; 1163 struct mlx4_ib_steering *ib_steering = NULL;
1164 enum mlx4_protocol prot = (gid->raw[1] == 0x0e) ?
1165 MLX4_PROT_IB_IPV4 : MLX4_PROT_IB_IPV6;
1028 1166
1029 if (mdev->dev->caps.steering_mode == 1167 if (mdev->dev->caps.steering_mode ==
1030 MLX4_STEERING_MODE_DEVICE_MANAGED) { 1168 MLX4_STEERING_MODE_DEVICE_MANAGED) {
@@ -1036,7 +1174,7 @@ static int mlx4_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
1036 err = mlx4_multicast_attach(mdev->dev, &mqp->mqp, gid->raw, mqp->port, 1174 err = mlx4_multicast_attach(mdev->dev, &mqp->mqp, gid->raw, mqp->port,
1037 !!(mqp->flags & 1175 !!(mqp->flags &
1038 MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK), 1176 MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK),
1039 MLX4_PROT_IB_IPV6, &reg_id); 1177 prot, &reg_id);
1040 if (err) 1178 if (err)
1041 goto err_malloc; 1179 goto err_malloc;
1042 1180
@@ -1055,7 +1193,7 @@ static int mlx4_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
1055 1193
1056err_add: 1194err_add:
1057 mlx4_multicast_detach(mdev->dev, &mqp->mqp, gid->raw, 1195 mlx4_multicast_detach(mdev->dev, &mqp->mqp, gid->raw,
1058 MLX4_PROT_IB_IPV6, reg_id); 1196 prot, reg_id);
1059err_malloc: 1197err_malloc:
1060 kfree(ib_steering); 1198 kfree(ib_steering);
1061 1199
@@ -1083,10 +1221,11 @@ static int mlx4_ib_mcg_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
1083 int err; 1221 int err;
1084 struct mlx4_ib_dev *mdev = to_mdev(ibqp->device); 1222 struct mlx4_ib_dev *mdev = to_mdev(ibqp->device);
1085 struct mlx4_ib_qp *mqp = to_mqp(ibqp); 1223 struct mlx4_ib_qp *mqp = to_mqp(ibqp);
1086 u8 mac[6];
1087 struct net_device *ndev; 1224 struct net_device *ndev;
1088 struct mlx4_ib_gid_entry *ge; 1225 struct mlx4_ib_gid_entry *ge;
1089 u64 reg_id = 0; 1226 u64 reg_id = 0;
1227 enum mlx4_protocol prot = (gid->raw[1] == 0x0e) ?
1228 MLX4_PROT_IB_IPV4 : MLX4_PROT_IB_IPV6;
1090 1229
1091 if (mdev->dev->caps.steering_mode == 1230 if (mdev->dev->caps.steering_mode ==
1092 MLX4_STEERING_MODE_DEVICE_MANAGED) { 1231 MLX4_STEERING_MODE_DEVICE_MANAGED) {
@@ -1109,7 +1248,7 @@ static int mlx4_ib_mcg_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
1109 } 1248 }
1110 1249
1111 err = mlx4_multicast_detach(mdev->dev, &mqp->mqp, gid->raw, 1250 err = mlx4_multicast_detach(mdev->dev, &mqp->mqp, gid->raw,
1112 MLX4_PROT_IB_IPV6, reg_id); 1251 prot, reg_id);
1113 if (err) 1252 if (err)
1114 return err; 1253 return err;
1115 1254
@@ -1121,13 +1260,8 @@ static int mlx4_ib_mcg_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
1121 if (ndev) 1260 if (ndev)
1122 dev_hold(ndev); 1261 dev_hold(ndev);
1123 spin_unlock(&mdev->iboe.lock); 1262 spin_unlock(&mdev->iboe.lock);
1124 rdma_get_mcast_mac((struct in6_addr *)gid, mac); 1263 if (ndev)
1125 if (ndev) {
1126 rtnl_lock();
1127 dev_mc_del(mdev->iboe.netdevs[ge->port - 1], mac);
1128 rtnl_unlock();
1129 dev_put(ndev); 1264 dev_put(ndev);
1130 }
1131 list_del(&ge->list); 1265 list_del(&ge->list);
1132 kfree(ge); 1266 kfree(ge);
1133 } else 1267 } else
@@ -1223,20 +1357,6 @@ static struct device_attribute *mlx4_class_attributes[] = {
1223 &dev_attr_board_id 1357 &dev_attr_board_id
1224}; 1358};
1225 1359
1226static void mlx4_addrconf_ifid_eui48(u8 *eui, u16 vlan_id, struct net_device *dev)
1227{
1228 memcpy(eui, dev->dev_addr, 3);
1229 memcpy(eui + 5, dev->dev_addr + 3, 3);
1230 if (vlan_id < 0x1000) {
1231 eui[3] = vlan_id >> 8;
1232 eui[4] = vlan_id & 0xff;
1233 } else {
1234 eui[3] = 0xff;
1235 eui[4] = 0xfe;
1236 }
1237 eui[0] ^= 2;
1238}
1239
1240static void update_gids_task(struct work_struct *work) 1360static void update_gids_task(struct work_struct *work)
1241{ 1361{
1242 struct update_gid_work *gw = container_of(work, struct update_gid_work, work); 1362 struct update_gid_work *gw = container_of(work, struct update_gid_work, work);
@@ -1259,161 +1379,318 @@ static void update_gids_task(struct work_struct *work)
1259 MLX4_CMD_WRAPPED); 1379 MLX4_CMD_WRAPPED);
1260 if (err) 1380 if (err)
1261 pr_warn("set port command failed\n"); 1381 pr_warn("set port command failed\n");
1262 else { 1382 else
1263 memcpy(gw->dev->iboe.gid_table[gw->port - 1], gw->gids, sizeof gw->gids);
1264 mlx4_ib_dispatch_event(gw->dev, gw->port, IB_EVENT_GID_CHANGE); 1383 mlx4_ib_dispatch_event(gw->dev, gw->port, IB_EVENT_GID_CHANGE);
1265 }
1266 1384
1267 mlx4_free_cmd_mailbox(dev, mailbox); 1385 mlx4_free_cmd_mailbox(dev, mailbox);
1268 kfree(gw); 1386 kfree(gw);
1269} 1387}
1270 1388
1271static int update_ipv6_gids(struct mlx4_ib_dev *dev, int port, int clear) 1389static void reset_gids_task(struct work_struct *work)
1272{ 1390{
1273 struct net_device *ndev = dev->iboe.netdevs[port - 1]; 1391 struct update_gid_work *gw =
1274 struct update_gid_work *work; 1392 container_of(work, struct update_gid_work, work);
1275 struct net_device *tmp; 1393 struct mlx4_cmd_mailbox *mailbox;
1394 union ib_gid *gids;
1395 int err;
1276 int i; 1396 int i;
1277 u8 *hits; 1397 struct mlx4_dev *dev = gw->dev->dev;
1278 int ret;
1279 union ib_gid gid;
1280 int free;
1281 int found;
1282 int need_update = 0;
1283 u16 vid;
1284 1398
1285 work = kzalloc(sizeof *work, GFP_ATOMIC); 1399 mailbox = mlx4_alloc_cmd_mailbox(dev);
1286 if (!work) 1400 if (IS_ERR(mailbox)) {
1287 return -ENOMEM; 1401 pr_warn("reset gid table failed\n");
1402 goto free;
1403 }
1288 1404
1289 hits = kzalloc(128, GFP_ATOMIC); 1405 gids = mailbox->buf;
1290 if (!hits) { 1406 memcpy(gids, gw->gids, sizeof(gw->gids));
1291 ret = -ENOMEM; 1407
1292 goto out; 1408 for (i = 1; i < gw->dev->num_ports + 1; i++) {
1409 if (mlx4_ib_port_link_layer(&gw->dev->ib_dev, i) ==
1410 IB_LINK_LAYER_ETHERNET) {
1411 err = mlx4_cmd(dev, mailbox->dma,
1412 MLX4_SET_PORT_GID_TABLE << 8 | i,
1413 1, MLX4_CMD_SET_PORT,
1414 MLX4_CMD_TIME_CLASS_B,
1415 MLX4_CMD_WRAPPED);
1416 if (err)
1417 pr_warn(KERN_WARNING
1418 "set port %d command failed\n", i);
1419 }
1293 } 1420 }
1294 1421
1295 rcu_read_lock(); 1422 mlx4_free_cmd_mailbox(dev, mailbox);
1296 for_each_netdev_rcu(&init_net, tmp) { 1423free:
1297 if (ndev && (tmp == ndev || rdma_vlan_dev_real_dev(tmp) == ndev)) { 1424 kfree(gw);
1298 gid.global.subnet_prefix = cpu_to_be64(0xfe80000000000000LL); 1425}
1299 vid = rdma_vlan_dev_vlan_id(tmp);
1300 mlx4_addrconf_ifid_eui48(&gid.raw[8], vid, ndev);
1301 found = 0;
1302 free = -1;
1303 for (i = 0; i < 128; ++i) {
1304 if (free < 0 &&
1305 !memcmp(&dev->iboe.gid_table[port - 1][i], &zgid, sizeof zgid))
1306 free = i;
1307 if (!memcmp(&dev->iboe.gid_table[port - 1][i], &gid, sizeof gid)) {
1308 hits[i] = 1;
1309 found = 1;
1310 break;
1311 }
1312 }
1313 1426
1314 if (!found) { 1427static int update_gid_table(struct mlx4_ib_dev *dev, int port,
1315 if (tmp == ndev && 1428 union ib_gid *gid, int clear)
1316 (memcmp(&dev->iboe.gid_table[port - 1][0], 1429{
1317 &gid, sizeof gid) || 1430 struct update_gid_work *work;
1318 !memcmp(&dev->iboe.gid_table[port - 1][0], 1431 int i;
1319 &zgid, sizeof gid))) { 1432 int need_update = 0;
1320 dev->iboe.gid_table[port - 1][0] = gid; 1433 int free = -1;
1321 ++need_update; 1434 int found = -1;
1322 hits[0] = 1; 1435 int max_gids;
1323 } else if (free >= 0) { 1436
1324 dev->iboe.gid_table[port - 1][free] = gid; 1437 max_gids = dev->dev->caps.gid_table_len[port];
1325 hits[free] = 1; 1438 for (i = 0; i < max_gids; ++i) {
1326 ++need_update; 1439 if (!memcmp(&dev->iboe.gid_table[port - 1][i], gid,
1327 } 1440 sizeof(*gid)))
1441 found = i;
1442
1443 if (clear) {
1444 if (found >= 0) {
1445 need_update = 1;
1446 dev->iboe.gid_table[port - 1][found] = zgid;
1447 break;
1328 } 1448 }
1449 } else {
1450 if (found >= 0)
1451 break;
1452
1453 if (free < 0 &&
1454 !memcmp(&dev->iboe.gid_table[port - 1][i], &zgid,
1455 sizeof(*gid)))
1456 free = i;
1329 } 1457 }
1330 } 1458 }
1331 rcu_read_unlock();
1332 1459
1333 for (i = 0; i < 128; ++i) 1460 if (found == -1 && !clear && free >= 0) {
1334 if (!hits[i]) { 1461 dev->iboe.gid_table[port - 1][free] = *gid;
1335 if (memcmp(&dev->iboe.gid_table[port - 1][i], &zgid, sizeof zgid)) 1462 need_update = 1;
1336 ++need_update; 1463 }
1337 dev->iboe.gid_table[port - 1][i] = zgid;
1338 }
1339 1464
1340 if (need_update) { 1465 if (!need_update)
1341 memcpy(work->gids, dev->iboe.gid_table[port - 1], sizeof work->gids); 1466 return 0;
1342 INIT_WORK(&work->work, update_gids_task); 1467
1343 work->port = port; 1468 work = kzalloc(sizeof(*work), GFP_ATOMIC);
1344 work->dev = dev; 1469 if (!work)
1345 queue_work(wq, &work->work); 1470 return -ENOMEM;
1346 } else 1471
1347 kfree(work); 1472 memcpy(work->gids, dev->iboe.gid_table[port - 1], sizeof(work->gids));
1473 INIT_WORK(&work->work, update_gids_task);
1474 work->port = port;
1475 work->dev = dev;
1476 queue_work(wq, &work->work);
1348 1477
1349 kfree(hits);
1350 return 0; 1478 return 0;
1479}
1351 1480
1352out: 1481static int reset_gid_table(struct mlx4_ib_dev *dev)
1353 kfree(work); 1482{
1354 return ret; 1483 struct update_gid_work *work;
1484
1485
1486 work = kzalloc(sizeof(*work), GFP_ATOMIC);
1487 if (!work)
1488 return -ENOMEM;
1489 memset(dev->iboe.gid_table, 0, sizeof(dev->iboe.gid_table));
1490 memset(work->gids, 0, sizeof(work->gids));
1491 INIT_WORK(&work->work, reset_gids_task);
1492 work->dev = dev;
1493 queue_work(wq, &work->work);
1494 return 0;
1355} 1495}
1356 1496
1357static void handle_en_event(struct mlx4_ib_dev *dev, int port, unsigned long event) 1497static int mlx4_ib_addr_event(int event, struct net_device *event_netdev,
1498 struct mlx4_ib_dev *ibdev, union ib_gid *gid)
1358{ 1499{
1359 switch (event) { 1500 struct mlx4_ib_iboe *iboe;
1360 case NETDEV_UP: 1501 int port = 0;
1361 case NETDEV_CHANGEADDR: 1502 struct net_device *real_dev = rdma_vlan_dev_real_dev(event_netdev) ?
1362 update_ipv6_gids(dev, port, 0); 1503 rdma_vlan_dev_real_dev(event_netdev) :
1363 break; 1504 event_netdev;
1505
1506 if (event != NETDEV_DOWN && event != NETDEV_UP)
1507 return 0;
1508
1509 if ((real_dev != event_netdev) &&
1510 (event == NETDEV_DOWN) &&
1511 rdma_link_local_addr((struct in6_addr *)gid))
1512 return 0;
1513
1514 iboe = &ibdev->iboe;
1515 spin_lock(&iboe->lock);
1516
1517 for (port = 1; port <= MLX4_MAX_PORTS; ++port)
1518 if ((netif_is_bond_master(real_dev) &&
1519 (real_dev == iboe->masters[port - 1])) ||
1520 (!netif_is_bond_master(real_dev) &&
1521 (real_dev == iboe->netdevs[port - 1])))
1522 update_gid_table(ibdev, port, gid,
1523 event == NETDEV_DOWN);
1524
1525 spin_unlock(&iboe->lock);
1526 return 0;
1364 1527
1365 case NETDEV_DOWN:
1366 update_ipv6_gids(dev, port, 1);
1367 dev->iboe.netdevs[port - 1] = NULL;
1368 }
1369} 1528}
1370 1529
1371static void netdev_added(struct mlx4_ib_dev *dev, int port) 1530static u8 mlx4_ib_get_dev_port(struct net_device *dev,
1531 struct mlx4_ib_dev *ibdev)
1372{ 1532{
1373 update_ipv6_gids(dev, port, 0); 1533 u8 port = 0;
1534 struct mlx4_ib_iboe *iboe;
1535 struct net_device *real_dev = rdma_vlan_dev_real_dev(dev) ?
1536 rdma_vlan_dev_real_dev(dev) : dev;
1537
1538 iboe = &ibdev->iboe;
1539 spin_lock(&iboe->lock);
1540
1541 for (port = 1; port <= MLX4_MAX_PORTS; ++port)
1542 if ((netif_is_bond_master(real_dev) &&
1543 (real_dev == iboe->masters[port - 1])) ||
1544 (!netif_is_bond_master(real_dev) &&
1545 (real_dev == iboe->netdevs[port - 1])))
1546 break;
1547
1548 spin_unlock(&iboe->lock);
1549
1550 if ((port == 0) || (port > MLX4_MAX_PORTS))
1551 return 0;
1552 else
1553 return port;
1374} 1554}
1375 1555
1376static void netdev_removed(struct mlx4_ib_dev *dev, int port) 1556static int mlx4_ib_inet_event(struct notifier_block *this, unsigned long event,
1557 void *ptr)
1377{ 1558{
1378 update_ipv6_gids(dev, port, 1); 1559 struct mlx4_ib_dev *ibdev;
1560 struct in_ifaddr *ifa = ptr;
1561 union ib_gid gid;
1562 struct net_device *event_netdev = ifa->ifa_dev->dev;
1563
1564 ipv6_addr_set_v4mapped(ifa->ifa_address, (struct in6_addr *)&gid);
1565
1566 ibdev = container_of(this, struct mlx4_ib_dev, iboe.nb_inet);
1567
1568 mlx4_ib_addr_event(event, event_netdev, ibdev, &gid);
1569 return NOTIFY_DONE;
1379} 1570}
1380 1571
1381static int mlx4_ib_netdev_event(struct notifier_block *this, unsigned long event, 1572#if IS_ENABLED(CONFIG_IPV6)
1573static int mlx4_ib_inet6_event(struct notifier_block *this, unsigned long event,
1382 void *ptr) 1574 void *ptr)
1383{ 1575{
1384 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
1385 struct mlx4_ib_dev *ibdev; 1576 struct mlx4_ib_dev *ibdev;
1386 struct net_device *oldnd; 1577 struct inet6_ifaddr *ifa = ptr;
1578 union ib_gid *gid = (union ib_gid *)&ifa->addr;
1579 struct net_device *event_netdev = ifa->idev->dev;
1580
1581 ibdev = container_of(this, struct mlx4_ib_dev, iboe.nb_inet6);
1582
1583 mlx4_ib_addr_event(event, event_netdev, ibdev, gid);
1584 return NOTIFY_DONE;
1585}
1586#endif
1587
1588static void mlx4_ib_get_dev_addr(struct net_device *dev,
1589 struct mlx4_ib_dev *ibdev, u8 port)
1590{
1591 struct in_device *in_dev;
1592#if IS_ENABLED(CONFIG_IPV6)
1593 struct inet6_dev *in6_dev;
1594 union ib_gid *pgid;
1595 struct inet6_ifaddr *ifp;
1596#endif
1597 union ib_gid gid;
1598
1599
1600 if ((port == 0) || (port > MLX4_MAX_PORTS))
1601 return;
1602
1603 /* IPv4 gids */
1604 in_dev = in_dev_get(dev);
1605 if (in_dev) {
1606 for_ifa(in_dev) {
1607 /*ifa->ifa_address;*/
1608 ipv6_addr_set_v4mapped(ifa->ifa_address,
1609 (struct in6_addr *)&gid);
1610 update_gid_table(ibdev, port, &gid, 0);
1611 }
1612 endfor_ifa(in_dev);
1613 in_dev_put(in_dev);
1614 }
1615#if IS_ENABLED(CONFIG_IPV6)
1616 /* IPv6 gids */
1617 in6_dev = in6_dev_get(dev);
1618 if (in6_dev) {
1619 read_lock_bh(&in6_dev->lock);
1620 list_for_each_entry(ifp, &in6_dev->addr_list, if_list) {
1621 pgid = (union ib_gid *)&ifp->addr;
1622 update_gid_table(ibdev, port, pgid, 0);
1623 }
1624 read_unlock_bh(&in6_dev->lock);
1625 in6_dev_put(in6_dev);
1626 }
1627#endif
1628}
1629
1630static int mlx4_ib_init_gid_table(struct mlx4_ib_dev *ibdev)
1631{
1632 struct net_device *dev;
1633
1634 if (reset_gid_table(ibdev))
1635 return -1;
1636
1637 read_lock(&dev_base_lock);
1638
1639 for_each_netdev(&init_net, dev) {
1640 u8 port = mlx4_ib_get_dev_port(dev, ibdev);
1641 if (port)
1642 mlx4_ib_get_dev_addr(dev, ibdev, port);
1643 }
1644
1645 read_unlock(&dev_base_lock);
1646
1647 return 0;
1648}
1649
1650static void mlx4_ib_scan_netdevs(struct mlx4_ib_dev *ibdev)
1651{
1387 struct mlx4_ib_iboe *iboe; 1652 struct mlx4_ib_iboe *iboe;
1388 int port; 1653 int port;
1389 1654
1390 if (!net_eq(dev_net(dev), &init_net))
1391 return NOTIFY_DONE;
1392
1393 ibdev = container_of(this, struct mlx4_ib_dev, iboe.nb);
1394 iboe = &ibdev->iboe; 1655 iboe = &ibdev->iboe;
1395 1656
1396 spin_lock(&iboe->lock); 1657 spin_lock(&iboe->lock);
1397 mlx4_foreach_ib_transport_port(port, ibdev->dev) { 1658 mlx4_foreach_ib_transport_port(port, ibdev->dev) {
1398 oldnd = iboe->netdevs[port - 1]; 1659 struct net_device *old_master = iboe->masters[port - 1];
1660 struct net_device *curr_master;
1399 iboe->netdevs[port - 1] = 1661 iboe->netdevs[port - 1] =
1400 mlx4_get_protocol_dev(ibdev->dev, MLX4_PROT_ETH, port); 1662 mlx4_get_protocol_dev(ibdev->dev, MLX4_PROT_ETH, port);
1401 if (oldnd != iboe->netdevs[port - 1]) { 1663
1402 if (iboe->netdevs[port - 1]) 1664 if (iboe->netdevs[port - 1] &&
1403 netdev_added(ibdev, port); 1665 netif_is_bond_slave(iboe->netdevs[port - 1])) {
1404 else 1666 rtnl_lock();
1405 netdev_removed(ibdev, port); 1667 iboe->masters[port - 1] = netdev_master_upper_dev_get(
1668 iboe->netdevs[port - 1]);
1669 rtnl_unlock();
1406 } 1670 }
1407 } 1671 curr_master = iboe->masters[port - 1];
1408 1672
1409 if (dev == iboe->netdevs[0] || 1673 /* if bonding is used it is possible that we add it to masters
1410 (iboe->netdevs[0] && rdma_vlan_dev_real_dev(dev) == iboe->netdevs[0])) 1674 only after IP address is assigned to the net bonding
1411 handle_en_event(ibdev, 1, event); 1675 interface */
1412 else if (dev == iboe->netdevs[1] 1676 if (curr_master && (old_master != curr_master))
1413 || (iboe->netdevs[1] && rdma_vlan_dev_real_dev(dev) == iboe->netdevs[1])) 1677 mlx4_ib_get_dev_addr(curr_master, ibdev, port);
1414 handle_en_event(ibdev, 2, event); 1678 }
1415 1679
1416 spin_unlock(&iboe->lock); 1680 spin_unlock(&iboe->lock);
1681}
1682
1683static int mlx4_ib_netdev_event(struct notifier_block *this,
1684 unsigned long event, void *ptr)
1685{
1686 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
1687 struct mlx4_ib_dev *ibdev;
1688
1689 if (!net_eq(dev_net(dev), &init_net))
1690 return NOTIFY_DONE;
1691
1692 ibdev = container_of(this, struct mlx4_ib_dev, iboe.nb);
1693 mlx4_ib_scan_netdevs(ibdev);
1417 1694
1418 return NOTIFY_DONE; 1695 return NOTIFY_DONE;
1419} 1696}
@@ -1682,6 +1959,7 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
1682 } 1959 }
1683 1960
1684 if (check_flow_steering_support(dev)) { 1961 if (check_flow_steering_support(dev)) {
1962 ibdev->steering_support = MLX4_STEERING_MODE_DEVICE_MANAGED;
1685 ibdev->ib_dev.create_flow = mlx4_ib_create_flow; 1963 ibdev->ib_dev.create_flow = mlx4_ib_create_flow;
1686 ibdev->ib_dev.destroy_flow = mlx4_ib_destroy_flow; 1964 ibdev->ib_dev.destroy_flow = mlx4_ib_destroy_flow;
1687 1965
@@ -1710,8 +1988,35 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
1710 spin_lock_init(&ibdev->sm_lock); 1988 spin_lock_init(&ibdev->sm_lock);
1711 mutex_init(&ibdev->cap_mask_mutex); 1989 mutex_init(&ibdev->cap_mask_mutex);
1712 1990
1991 if (ibdev->steering_support == MLX4_STEERING_MODE_DEVICE_MANAGED) {
1992 ibdev->steer_qpn_count = MLX4_IB_UC_MAX_NUM_QPS;
1993 err = mlx4_qp_reserve_range(dev, ibdev->steer_qpn_count,
1994 MLX4_IB_UC_STEER_QPN_ALIGN,
1995 &ibdev->steer_qpn_base);
1996 if (err)
1997 goto err_counter;
1998
1999 ibdev->ib_uc_qpns_bitmap =
2000 kmalloc(BITS_TO_LONGS(ibdev->steer_qpn_count) *
2001 sizeof(long),
2002 GFP_KERNEL);
2003 if (!ibdev->ib_uc_qpns_bitmap) {
2004 dev_err(&dev->pdev->dev, "bit map alloc failed\n");
2005 goto err_steer_qp_release;
2006 }
2007
2008 bitmap_zero(ibdev->ib_uc_qpns_bitmap, ibdev->steer_qpn_count);
2009
2010 err = mlx4_FLOW_STEERING_IB_UC_QP_RANGE(
2011 dev, ibdev->steer_qpn_base,
2012 ibdev->steer_qpn_base +
2013 ibdev->steer_qpn_count - 1);
2014 if (err)
2015 goto err_steer_free_bitmap;
2016 }
2017
1713 if (ib_register_device(&ibdev->ib_dev, NULL)) 2018 if (ib_register_device(&ibdev->ib_dev, NULL))
1714 goto err_counter; 2019 goto err_steer_free_bitmap;
1715 2020
1716 if (mlx4_ib_mad_init(ibdev)) 2021 if (mlx4_ib_mad_init(ibdev))
1717 goto err_reg; 2022 goto err_reg;
@@ -1719,11 +2024,35 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
1719 if (mlx4_ib_init_sriov(ibdev)) 2024 if (mlx4_ib_init_sriov(ibdev))
1720 goto err_mad; 2025 goto err_mad;
1721 2026
1722 if (dev->caps.flags & MLX4_DEV_CAP_FLAG_IBOE && !iboe->nb.notifier_call) { 2027 if (dev->caps.flags & MLX4_DEV_CAP_FLAG_IBOE) {
1723 iboe->nb.notifier_call = mlx4_ib_netdev_event; 2028 if (!iboe->nb.notifier_call) {
1724 err = register_netdevice_notifier(&iboe->nb); 2029 iboe->nb.notifier_call = mlx4_ib_netdev_event;
1725 if (err) 2030 err = register_netdevice_notifier(&iboe->nb);
1726 goto err_sriov; 2031 if (err) {
2032 iboe->nb.notifier_call = NULL;
2033 goto err_notif;
2034 }
2035 }
2036 if (!iboe->nb_inet.notifier_call) {
2037 iboe->nb_inet.notifier_call = mlx4_ib_inet_event;
2038 err = register_inetaddr_notifier(&iboe->nb_inet);
2039 if (err) {
2040 iboe->nb_inet.notifier_call = NULL;
2041 goto err_notif;
2042 }
2043 }
2044#if IS_ENABLED(CONFIG_IPV6)
2045 if (!iboe->nb_inet6.notifier_call) {
2046 iboe->nb_inet6.notifier_call = mlx4_ib_inet6_event;
2047 err = register_inet6addr_notifier(&iboe->nb_inet6);
2048 if (err) {
2049 iboe->nb_inet6.notifier_call = NULL;
2050 goto err_notif;
2051 }
2052 }
2053#endif
2054 mlx4_ib_scan_netdevs(ibdev);
2055 mlx4_ib_init_gid_table(ibdev);
1727 } 2056 }
1728 2057
1729 for (j = 0; j < ARRAY_SIZE(mlx4_class_attributes); ++j) { 2058 for (j = 0; j < ARRAY_SIZE(mlx4_class_attributes); ++j) {
@@ -1749,11 +2078,25 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
1749 return ibdev; 2078 return ibdev;
1750 2079
1751err_notif: 2080err_notif:
1752 if (unregister_netdevice_notifier(&ibdev->iboe.nb)) 2081 if (ibdev->iboe.nb.notifier_call) {
1753 pr_warn("failure unregistering notifier\n"); 2082 if (unregister_netdevice_notifier(&ibdev->iboe.nb))
2083 pr_warn("failure unregistering notifier\n");
2084 ibdev->iboe.nb.notifier_call = NULL;
2085 }
2086 if (ibdev->iboe.nb_inet.notifier_call) {
2087 if (unregister_inetaddr_notifier(&ibdev->iboe.nb_inet))
2088 pr_warn("failure unregistering notifier\n");
2089 ibdev->iboe.nb_inet.notifier_call = NULL;
2090 }
2091#if IS_ENABLED(CONFIG_IPV6)
2092 if (ibdev->iboe.nb_inet6.notifier_call) {
2093 if (unregister_inet6addr_notifier(&ibdev->iboe.nb_inet6))
2094 pr_warn("failure unregistering notifier\n");
2095 ibdev->iboe.nb_inet6.notifier_call = NULL;
2096 }
2097#endif
1754 flush_workqueue(wq); 2098 flush_workqueue(wq);
1755 2099
1756err_sriov:
1757 mlx4_ib_close_sriov(ibdev); 2100 mlx4_ib_close_sriov(ibdev);
1758 2101
1759err_mad: 2102err_mad:
@@ -1762,6 +2105,13 @@ err_mad:
1762err_reg: 2105err_reg:
1763 ib_unregister_device(&ibdev->ib_dev); 2106 ib_unregister_device(&ibdev->ib_dev);
1764 2107
2108err_steer_free_bitmap:
2109 kfree(ibdev->ib_uc_qpns_bitmap);
2110
2111err_steer_qp_release:
2112 if (ibdev->steering_support == MLX4_STEERING_MODE_DEVICE_MANAGED)
2113 mlx4_qp_release_range(dev, ibdev->steer_qpn_base,
2114 ibdev->steer_qpn_count);
1765err_counter: 2115err_counter:
1766 for (; i; --i) 2116 for (; i; --i)
1767 if (ibdev->counters[i - 1] != -1) 2117 if (ibdev->counters[i - 1] != -1)
@@ -1782,6 +2132,69 @@ err_dealloc:
1782 return NULL; 2132 return NULL;
1783} 2133}
1784 2134
2135int mlx4_ib_steer_qp_alloc(struct mlx4_ib_dev *dev, int count, int *qpn)
2136{
2137 int offset;
2138
2139 WARN_ON(!dev->ib_uc_qpns_bitmap);
2140
2141 offset = bitmap_find_free_region(dev->ib_uc_qpns_bitmap,
2142 dev->steer_qpn_count,
2143 get_count_order(count));
2144 if (offset < 0)
2145 return offset;
2146
2147 *qpn = dev->steer_qpn_base + offset;
2148 return 0;
2149}
2150
2151void mlx4_ib_steer_qp_free(struct mlx4_ib_dev *dev, u32 qpn, int count)
2152{
2153 if (!qpn ||
2154 dev->steering_support != MLX4_STEERING_MODE_DEVICE_MANAGED)
2155 return;
2156
2157 BUG_ON(qpn < dev->steer_qpn_base);
2158
2159 bitmap_release_region(dev->ib_uc_qpns_bitmap,
2160 qpn - dev->steer_qpn_base,
2161 get_count_order(count));
2162}
2163
2164int mlx4_ib_steer_qp_reg(struct mlx4_ib_dev *mdev, struct mlx4_ib_qp *mqp,
2165 int is_attach)
2166{
2167 int err;
2168 size_t flow_size;
2169 struct ib_flow_attr *flow = NULL;
2170 struct ib_flow_spec_ib *ib_spec;
2171
2172 if (is_attach) {
2173 flow_size = sizeof(struct ib_flow_attr) +
2174 sizeof(struct ib_flow_spec_ib);
2175 flow = kzalloc(flow_size, GFP_KERNEL);
2176 if (!flow)
2177 return -ENOMEM;
2178 flow->port = mqp->port;
2179 flow->num_of_specs = 1;
2180 flow->size = flow_size;
2181 ib_spec = (struct ib_flow_spec_ib *)(flow + 1);
2182 ib_spec->type = IB_FLOW_SPEC_IB;
2183 ib_spec->size = sizeof(struct ib_flow_spec_ib);
2184 /* Add an empty rule for IB L2 */
2185 memset(&ib_spec->mask, 0, sizeof(ib_spec->mask));
2186
2187 err = __mlx4_ib_create_flow(&mqp->ibqp, flow,
2188 IB_FLOW_DOMAIN_NIC,
2189 MLX4_FS_REGULAR,
2190 &mqp->reg_id);
2191 } else {
2192 err = __mlx4_ib_destroy_flow(mdev->dev, mqp->reg_id);
2193 }
2194 kfree(flow);
2195 return err;
2196}
2197
1785static void mlx4_ib_remove(struct mlx4_dev *dev, void *ibdev_ptr) 2198static void mlx4_ib_remove(struct mlx4_dev *dev, void *ibdev_ptr)
1786{ 2199{
1787 struct mlx4_ib_dev *ibdev = ibdev_ptr; 2200 struct mlx4_ib_dev *ibdev = ibdev_ptr;
@@ -1795,6 +2208,26 @@ static void mlx4_ib_remove(struct mlx4_dev *dev, void *ibdev_ptr)
1795 pr_warn("failure unregistering notifier\n"); 2208 pr_warn("failure unregistering notifier\n");
1796 ibdev->iboe.nb.notifier_call = NULL; 2209 ibdev->iboe.nb.notifier_call = NULL;
1797 } 2210 }
2211
2212 if (ibdev->steering_support == MLX4_STEERING_MODE_DEVICE_MANAGED) {
2213 mlx4_qp_release_range(dev, ibdev->steer_qpn_base,
2214 ibdev->steer_qpn_count);
2215 kfree(ibdev->ib_uc_qpns_bitmap);
2216 }
2217
2218 if (ibdev->iboe.nb_inet.notifier_call) {
2219 if (unregister_inetaddr_notifier(&ibdev->iboe.nb_inet))
2220 pr_warn("failure unregistering notifier\n");
2221 ibdev->iboe.nb_inet.notifier_call = NULL;
2222 }
2223#if IS_ENABLED(CONFIG_IPV6)
2224 if (ibdev->iboe.nb_inet6.notifier_call) {
2225 if (unregister_inet6addr_notifier(&ibdev->iboe.nb_inet6))
2226 pr_warn("failure unregistering notifier\n");
2227 ibdev->iboe.nb_inet6.notifier_call = NULL;
2228 }
2229#endif
2230
1798 iounmap(ibdev->uar_map); 2231 iounmap(ibdev->uar_map);
1799 for (p = 0; p < ibdev->num_ports; ++p) 2232 for (p = 0; p < ibdev->num_ports; ++p)
1800 if (ibdev->counters[p] != -1) 2233 if (ibdev->counters[p] != -1)
diff --git a/drivers/infiniband/hw/mlx4/mlx4_ib.h b/drivers/infiniband/hw/mlx4/mlx4_ib.h
index 036b663dd26e..a230683af940 100644
--- a/drivers/infiniband/hw/mlx4/mlx4_ib.h
+++ b/drivers/infiniband/hw/mlx4/mlx4_ib.h
@@ -68,6 +68,8 @@ enum {
68/*module param to indicate if SM assigns the alias_GUID*/ 68/*module param to indicate if SM assigns the alias_GUID*/
69extern int mlx4_ib_sm_guid_assign; 69extern int mlx4_ib_sm_guid_assign;
70 70
71#define MLX4_IB_UC_STEER_QPN_ALIGN 1
72#define MLX4_IB_UC_MAX_NUM_QPS 256
71struct mlx4_ib_ucontext { 73struct mlx4_ib_ucontext {
72 struct ib_ucontext ibucontext; 74 struct ib_ucontext ibucontext;
73 struct mlx4_uar uar; 75 struct mlx4_uar uar;
@@ -153,6 +155,7 @@ struct mlx4_ib_wq {
153enum mlx4_ib_qp_flags { 155enum mlx4_ib_qp_flags {
154 MLX4_IB_QP_LSO = IB_QP_CREATE_IPOIB_UD_LSO, 156 MLX4_IB_QP_LSO = IB_QP_CREATE_IPOIB_UD_LSO,
155 MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK = IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK, 157 MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK = IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK,
158 MLX4_IB_QP_NETIF = IB_QP_CREATE_NETIF_QP,
156 MLX4_IB_SRIOV_TUNNEL_QP = 1 << 30, 159 MLX4_IB_SRIOV_TUNNEL_QP = 1 << 30,
157 MLX4_IB_SRIOV_SQP = 1 << 31, 160 MLX4_IB_SRIOV_SQP = 1 << 31,
158}; 161};
@@ -270,6 +273,7 @@ struct mlx4_ib_qp {
270 struct list_head gid_list; 273 struct list_head gid_list;
271 struct list_head steering_rules; 274 struct list_head steering_rules;
272 struct mlx4_ib_buf *sqp_proxy_rcv; 275 struct mlx4_ib_buf *sqp_proxy_rcv;
276 u64 reg_id;
273 277
274}; 278};
275 279
@@ -428,7 +432,10 @@ struct mlx4_ib_sriov {
428struct mlx4_ib_iboe { 432struct mlx4_ib_iboe {
429 spinlock_t lock; 433 spinlock_t lock;
430 struct net_device *netdevs[MLX4_MAX_PORTS]; 434 struct net_device *netdevs[MLX4_MAX_PORTS];
435 struct net_device *masters[MLX4_MAX_PORTS];
431 struct notifier_block nb; 436 struct notifier_block nb;
437 struct notifier_block nb_inet;
438 struct notifier_block nb_inet6;
432 union ib_gid gid_table[MLX4_MAX_PORTS][128]; 439 union ib_gid gid_table[MLX4_MAX_PORTS][128];
433}; 440};
434 441
@@ -494,6 +501,10 @@ struct mlx4_ib_dev {
494 struct kobject *dev_ports_parent[MLX4_MFUNC_MAX]; 501 struct kobject *dev_ports_parent[MLX4_MFUNC_MAX];
495 struct mlx4_ib_iov_port iov_ports[MLX4_MAX_PORTS]; 502 struct mlx4_ib_iov_port iov_ports[MLX4_MAX_PORTS];
496 struct pkey_mgt pkeys; 503 struct pkey_mgt pkeys;
504 unsigned long *ib_uc_qpns_bitmap;
505 int steer_qpn_count;
506 int steer_qpn_base;
507 int steering_support;
497}; 508};
498 509
499struct ib_event_work { 510struct ib_event_work {
@@ -675,9 +686,6 @@ int __mlx4_ib_query_pkey(struct ib_device *ibdev, u8 port, u16 index,
675int __mlx4_ib_query_gid(struct ib_device *ibdev, u8 port, int index, 686int __mlx4_ib_query_gid(struct ib_device *ibdev, u8 port, int index,
676 union ib_gid *gid, int netw_view); 687 union ib_gid *gid, int netw_view);
677 688
678int mlx4_ib_resolve_grh(struct mlx4_ib_dev *dev, const struct ib_ah_attr *ah_attr,
679 u8 *mac, int *is_mcast, u8 port);
680
681static inline bool mlx4_ib_ah_grh_present(struct mlx4_ib_ah *ah) 689static inline bool mlx4_ib_ah_grh_present(struct mlx4_ib_ah *ah)
682{ 690{
683 u8 port = be32_to_cpu(ah->av.ib.port_pd) >> 24 & 3; 691 u8 port = be32_to_cpu(ah->av.ib.port_pd) >> 24 & 3;
@@ -752,5 +760,9 @@ void mlx4_ib_device_unregister_sysfs(struct mlx4_ib_dev *device);
752 760
753__be64 mlx4_ib_gen_node_guid(void); 761__be64 mlx4_ib_gen_node_guid(void);
754 762
763int mlx4_ib_steer_qp_alloc(struct mlx4_ib_dev *dev, int count, int *qpn);
764void mlx4_ib_steer_qp_free(struct mlx4_ib_dev *dev, u32 qpn, int count);
765int mlx4_ib_steer_qp_reg(struct mlx4_ib_dev *mdev, struct mlx4_ib_qp *mqp,
766 int is_attach);
755 767
756#endif /* MLX4_IB_H */ 768#endif /* MLX4_IB_H */
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index 4f10af2905b5..d8f4d1fe8494 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -90,6 +90,21 @@ enum {
90 MLX4_RAW_QP_MSGMAX = 31, 90 MLX4_RAW_QP_MSGMAX = 31,
91}; 91};
92 92
93#ifndef ETH_ALEN
94#define ETH_ALEN 6
95#endif
96static inline u64 mlx4_mac_to_u64(u8 *addr)
97{
98 u64 mac = 0;
99 int i;
100
101 for (i = 0; i < ETH_ALEN; i++) {
102 mac <<= 8;
103 mac |= addr[i];
104 }
105 return mac;
106}
107
93static const __be32 mlx4_ib_opcode[] = { 108static const __be32 mlx4_ib_opcode[] = {
94 [IB_WR_SEND] = cpu_to_be32(MLX4_OPCODE_SEND), 109 [IB_WR_SEND] = cpu_to_be32(MLX4_OPCODE_SEND),
95 [IB_WR_LSO] = cpu_to_be32(MLX4_OPCODE_LSO), 110 [IB_WR_LSO] = cpu_to_be32(MLX4_OPCODE_LSO),
@@ -716,6 +731,14 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
716 if (init_attr->create_flags & IB_QP_CREATE_IPOIB_UD_LSO) 731 if (init_attr->create_flags & IB_QP_CREATE_IPOIB_UD_LSO)
717 qp->flags |= MLX4_IB_QP_LSO; 732 qp->flags |= MLX4_IB_QP_LSO;
718 733
734 if (init_attr->create_flags & IB_QP_CREATE_NETIF_QP) {
735 if (dev->steering_support ==
736 MLX4_STEERING_MODE_DEVICE_MANAGED)
737 qp->flags |= MLX4_IB_QP_NETIF;
738 else
739 goto err;
740 }
741
719 err = set_kernel_sq_size(dev, &init_attr->cap, qp_type, qp); 742 err = set_kernel_sq_size(dev, &init_attr->cap, qp_type, qp);
720 if (err) 743 if (err)
721 goto err; 744 goto err;
@@ -765,7 +788,11 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
765 if (init_attr->qp_type == IB_QPT_RAW_PACKET) 788 if (init_attr->qp_type == IB_QPT_RAW_PACKET)
766 err = mlx4_qp_reserve_range(dev->dev, 1, 1 << 8, &qpn); 789 err = mlx4_qp_reserve_range(dev->dev, 1, 1 << 8, &qpn);
767 else 790 else
768 err = mlx4_qp_reserve_range(dev->dev, 1, 1, &qpn); 791 if (qp->flags & MLX4_IB_QP_NETIF)
792 err = mlx4_ib_steer_qp_alloc(dev, 1, &qpn);
793 else
794 err = mlx4_qp_reserve_range(dev->dev, 1, 1,
795 &qpn);
769 if (err) 796 if (err)
770 goto err_proxy; 797 goto err_proxy;
771 } 798 }
@@ -790,8 +817,12 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
790 return 0; 817 return 0;
791 818
792err_qpn: 819err_qpn:
793 if (!sqpn) 820 if (!sqpn) {
794 mlx4_qp_release_range(dev->dev, qpn, 1); 821 if (qp->flags & MLX4_IB_QP_NETIF)
822 mlx4_ib_steer_qp_free(dev, qpn, 1);
823 else
824 mlx4_qp_release_range(dev->dev, qpn, 1);
825 }
795err_proxy: 826err_proxy:
796 if (qp->mlx4_ib_qp_type == MLX4_IB_QPT_PROXY_GSI) 827 if (qp->mlx4_ib_qp_type == MLX4_IB_QPT_PROXY_GSI)
797 free_proxy_bufs(pd->device, qp); 828 free_proxy_bufs(pd->device, qp);
@@ -932,8 +963,12 @@ static void destroy_qp_common(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp,
932 963
933 mlx4_qp_free(dev->dev, &qp->mqp); 964 mlx4_qp_free(dev->dev, &qp->mqp);
934 965
935 if (!is_sqp(dev, qp) && !is_tunnel_qp(dev, qp)) 966 if (!is_sqp(dev, qp) && !is_tunnel_qp(dev, qp)) {
936 mlx4_qp_release_range(dev->dev, qp->mqp.qpn, 1); 967 if (qp->flags & MLX4_IB_QP_NETIF)
968 mlx4_ib_steer_qp_free(dev, qp->mqp.qpn, 1);
969 else
970 mlx4_qp_release_range(dev->dev, qp->mqp.qpn, 1);
971 }
937 972
938 mlx4_mtt_cleanup(dev->dev, &qp->mtt); 973 mlx4_mtt_cleanup(dev->dev, &qp->mtt);
939 974
@@ -987,9 +1022,16 @@ struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd,
987 */ 1022 */
988 if (init_attr->create_flags & ~(MLX4_IB_QP_LSO | 1023 if (init_attr->create_flags & ~(MLX4_IB_QP_LSO |
989 MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK | 1024 MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK |
990 MLX4_IB_SRIOV_TUNNEL_QP | MLX4_IB_SRIOV_SQP)) 1025 MLX4_IB_SRIOV_TUNNEL_QP |
1026 MLX4_IB_SRIOV_SQP |
1027 MLX4_IB_QP_NETIF))
991 return ERR_PTR(-EINVAL); 1028 return ERR_PTR(-EINVAL);
992 1029
1030 if (init_attr->create_flags & IB_QP_CREATE_NETIF_QP) {
1031 if (init_attr->qp_type != IB_QPT_UD)
1032 return ERR_PTR(-EINVAL);
1033 }
1034
993 if (init_attr->create_flags && 1035 if (init_attr->create_flags &&
994 (udata || 1036 (udata ||
995 ((init_attr->create_flags & ~MLX4_IB_SRIOV_SQP) && 1037 ((init_attr->create_flags & ~MLX4_IB_SRIOV_SQP) &&
@@ -1144,16 +1186,15 @@ static void mlx4_set_sched(struct mlx4_qp_path *path, u8 port)
1144 path->sched_queue = (path->sched_queue & 0xbf) | ((port - 1) << 6); 1186 path->sched_queue = (path->sched_queue & 0xbf) | ((port - 1) << 6);
1145} 1187}
1146 1188
1147static int mlx4_set_path(struct mlx4_ib_dev *dev, const struct ib_ah_attr *ah, 1189static int _mlx4_set_path(struct mlx4_ib_dev *dev, const struct ib_ah_attr *ah,
1148 struct mlx4_qp_path *path, u8 port) 1190 u64 smac, u16 vlan_tag, struct mlx4_qp_path *path,
1191 u8 port)
1149{ 1192{
1150 int err;
1151 int is_eth = rdma_port_get_link_layer(&dev->ib_dev, port) == 1193 int is_eth = rdma_port_get_link_layer(&dev->ib_dev, port) ==
1152 IB_LINK_LAYER_ETHERNET; 1194 IB_LINK_LAYER_ETHERNET;
1153 u8 mac[6];
1154 int is_mcast;
1155 u16 vlan_tag;
1156 int vidx; 1195 int vidx;
1196 int smac_index;
1197
1157 1198
1158 path->grh_mylmc = ah->src_path_bits & 0x7f; 1199 path->grh_mylmc = ah->src_path_bits & 0x7f;
1159 path->rlid = cpu_to_be16(ah->dlid); 1200 path->rlid = cpu_to_be16(ah->dlid);
@@ -1188,22 +1229,27 @@ static int mlx4_set_path(struct mlx4_ib_dev *dev, const struct ib_ah_attr *ah,
1188 if (!(ah->ah_flags & IB_AH_GRH)) 1229 if (!(ah->ah_flags & IB_AH_GRH))
1189 return -1; 1230 return -1;
1190 1231
1191 err = mlx4_ib_resolve_grh(dev, ah, mac, &is_mcast, port); 1232 memcpy(path->dmac, ah->dmac, ETH_ALEN);
1192 if (err)
1193 return err;
1194
1195 memcpy(path->dmac, mac, 6);
1196 path->ackto = MLX4_IB_LINK_TYPE_ETH; 1233 path->ackto = MLX4_IB_LINK_TYPE_ETH;
1197 /* use index 0 into MAC table for IBoE */ 1234 /* find the index into MAC table for IBoE */
1198 path->grh_mylmc &= 0x80; 1235 if (!is_zero_ether_addr((const u8 *)&smac)) {
1236 if (mlx4_find_cached_mac(dev->dev, port, smac,
1237 &smac_index))
1238 return -ENOENT;
1239 } else {
1240 smac_index = 0;
1241 }
1242
1243 path->grh_mylmc &= 0x80 | smac_index;
1199 1244
1200 vlan_tag = rdma_get_vlan_id(&dev->iboe.gid_table[port - 1][ah->grh.sgid_index]); 1245 path->feup |= MLX4_FEUP_FORCE_ETH_UP;
1201 if (vlan_tag < 0x1000) { 1246 if (vlan_tag < 0x1000) {
1202 if (mlx4_find_cached_vlan(dev->dev, port, vlan_tag, &vidx)) 1247 if (mlx4_find_cached_vlan(dev->dev, port, vlan_tag, &vidx))
1203 return -ENOENT; 1248 return -ENOENT;
1204 1249
1205 path->vlan_index = vidx; 1250 path->vlan_index = vidx;
1206 path->fl = 1 << 6; 1251 path->fl = 1 << 6;
1252 path->feup |= MLX4_FVL_FORCE_ETH_VLAN;
1207 } 1253 }
1208 } else 1254 } else
1209 path->sched_queue = MLX4_IB_DEFAULT_SCHED_QUEUE | 1255 path->sched_queue = MLX4_IB_DEFAULT_SCHED_QUEUE |
@@ -1212,6 +1258,28 @@ static int mlx4_set_path(struct mlx4_ib_dev *dev, const struct ib_ah_attr *ah,
1212 return 0; 1258 return 0;
1213} 1259}
1214 1260
1261static int mlx4_set_path(struct mlx4_ib_dev *dev, const struct ib_qp_attr *qp,
1262 enum ib_qp_attr_mask qp_attr_mask,
1263 struct mlx4_qp_path *path, u8 port)
1264{
1265 return _mlx4_set_path(dev, &qp->ah_attr,
1266 mlx4_mac_to_u64((u8 *)qp->smac),
1267 (qp_attr_mask & IB_QP_VID) ? qp->vlan_id : 0xffff,
1268 path, port);
1269}
1270
1271static int mlx4_set_alt_path(struct mlx4_ib_dev *dev,
1272 const struct ib_qp_attr *qp,
1273 enum ib_qp_attr_mask qp_attr_mask,
1274 struct mlx4_qp_path *path, u8 port)
1275{
1276 return _mlx4_set_path(dev, &qp->alt_ah_attr,
1277 mlx4_mac_to_u64((u8 *)qp->alt_smac),
1278 (qp_attr_mask & IB_QP_ALT_VID) ?
1279 qp->alt_vlan_id : 0xffff,
1280 path, port);
1281}
1282
1215static void update_mcg_macs(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp) 1283static void update_mcg_macs(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp)
1216{ 1284{
1217 struct mlx4_ib_gid_entry *ge, *tmp; 1285 struct mlx4_ib_gid_entry *ge, *tmp;
@@ -1235,6 +1303,7 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
1235 struct mlx4_qp_context *context; 1303 struct mlx4_qp_context *context;
1236 enum mlx4_qp_optpar optpar = 0; 1304 enum mlx4_qp_optpar optpar = 0;
1237 int sqd_event; 1305 int sqd_event;
1306 int steer_qp = 0;
1238 int err = -EINVAL; 1307 int err = -EINVAL;
1239 1308
1240 context = kzalloc(sizeof *context, GFP_KERNEL); 1309 context = kzalloc(sizeof *context, GFP_KERNEL);
@@ -1319,6 +1388,11 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
1319 optpar |= MLX4_QP_OPTPAR_COUNTER_INDEX; 1388 optpar |= MLX4_QP_OPTPAR_COUNTER_INDEX;
1320 } else 1389 } else
1321 context->pri_path.counter_index = 0xff; 1390 context->pri_path.counter_index = 0xff;
1391
1392 if (qp->flags & MLX4_IB_QP_NETIF) {
1393 mlx4_ib_steer_qp_reg(dev, qp, 1);
1394 steer_qp = 1;
1395 }
1322 } 1396 }
1323 1397
1324 if (attr_mask & IB_QP_PKEY_INDEX) { 1398 if (attr_mask & IB_QP_PKEY_INDEX) {
@@ -1329,7 +1403,7 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
1329 } 1403 }
1330 1404
1331 if (attr_mask & IB_QP_AV) { 1405 if (attr_mask & IB_QP_AV) {
1332 if (mlx4_set_path(dev, &attr->ah_attr, &context->pri_path, 1406 if (mlx4_set_path(dev, attr, attr_mask, &context->pri_path,
1333 attr_mask & IB_QP_PORT ? 1407 attr_mask & IB_QP_PORT ?
1334 attr->port_num : qp->port)) 1408 attr->port_num : qp->port))
1335 goto out; 1409 goto out;
@@ -1352,8 +1426,8 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
1352 dev->dev->caps.pkey_table_len[attr->alt_port_num]) 1426 dev->dev->caps.pkey_table_len[attr->alt_port_num])
1353 goto out; 1427 goto out;
1354 1428
1355 if (mlx4_set_path(dev, &attr->alt_ah_attr, &context->alt_path, 1429 if (mlx4_set_alt_path(dev, attr, attr_mask, &context->alt_path,
1356 attr->alt_port_num)) 1430 attr->alt_port_num))
1357 goto out; 1431 goto out;
1358 1432
1359 context->alt_path.pkey_index = attr->alt_pkey_index; 1433 context->alt_path.pkey_index = attr->alt_pkey_index;
@@ -1464,6 +1538,17 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
1464 context->pri_path.ackto = (context->pri_path.ackto & 0xf8) | 1538 context->pri_path.ackto = (context->pri_path.ackto & 0xf8) |
1465 MLX4_IB_LINK_TYPE_ETH; 1539 MLX4_IB_LINK_TYPE_ETH;
1466 1540
1541 if (ibqp->qp_type == IB_QPT_UD && (new_state == IB_QPS_RTR)) {
1542 int is_eth = rdma_port_get_link_layer(
1543 &dev->ib_dev, qp->port) ==
1544 IB_LINK_LAYER_ETHERNET;
1545 if (is_eth) {
1546 context->pri_path.ackto = MLX4_IB_LINK_TYPE_ETH;
1547 optpar |= MLX4_QP_OPTPAR_PRIMARY_ADDR_PATH;
1548 }
1549 }
1550
1551
1467 if (cur_state == IB_QPS_RTS && new_state == IB_QPS_SQD && 1552 if (cur_state == IB_QPS_RTS && new_state == IB_QPS_SQD &&
1468 attr_mask & IB_QP_EN_SQD_ASYNC_NOTIFY && attr->en_sqd_async_notify) 1553 attr_mask & IB_QP_EN_SQD_ASYNC_NOTIFY && attr->en_sqd_async_notify)
1469 sqd_event = 1; 1554 sqd_event = 1;
@@ -1547,9 +1632,14 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
1547 qp->sq_next_wqe = 0; 1632 qp->sq_next_wqe = 0;
1548 if (qp->rq.wqe_cnt) 1633 if (qp->rq.wqe_cnt)
1549 *qp->db.db = 0; 1634 *qp->db.db = 0;
1635
1636 if (qp->flags & MLX4_IB_QP_NETIF)
1637 mlx4_ib_steer_qp_reg(dev, qp, 0);
1550 } 1638 }
1551 1639
1552out: 1640out:
1641 if (err && steer_qp)
1642 mlx4_ib_steer_qp_reg(dev, qp, 0);
1553 kfree(context); 1643 kfree(context);
1554 return err; 1644 return err;
1555} 1645}
@@ -1561,13 +1651,21 @@ int mlx4_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
1561 struct mlx4_ib_qp *qp = to_mqp(ibqp); 1651 struct mlx4_ib_qp *qp = to_mqp(ibqp);
1562 enum ib_qp_state cur_state, new_state; 1652 enum ib_qp_state cur_state, new_state;
1563 int err = -EINVAL; 1653 int err = -EINVAL;
1564 1654 int ll;
1565 mutex_lock(&qp->mutex); 1655 mutex_lock(&qp->mutex);
1566 1656
1567 cur_state = attr_mask & IB_QP_CUR_STATE ? attr->cur_qp_state : qp->state; 1657 cur_state = attr_mask & IB_QP_CUR_STATE ? attr->cur_qp_state : qp->state;
1568 new_state = attr_mask & IB_QP_STATE ? attr->qp_state : cur_state; 1658 new_state = attr_mask & IB_QP_STATE ? attr->qp_state : cur_state;
1569 1659
1570 if (!ib_modify_qp_is_ok(cur_state, new_state, ibqp->qp_type, attr_mask)) { 1660 if (cur_state == new_state && cur_state == IB_QPS_RESET) {
1661 ll = IB_LINK_LAYER_UNSPECIFIED;
1662 } else {
1663 int port = attr_mask & IB_QP_PORT ? attr->port_num : qp->port;
1664 ll = rdma_port_get_link_layer(&dev->ib_dev, port);
1665 }
1666
1667 if (!ib_modify_qp_is_ok(cur_state, new_state, ibqp->qp_type,
1668 attr_mask, ll)) {
1571 pr_debug("qpn 0x%x: invalid attribute mask specified " 1669 pr_debug("qpn 0x%x: invalid attribute mask specified "
1572 "for transition %d to %d. qp_type %d," 1670 "for transition %d to %d. qp_type %d,"
1573 " attr_mask 0x%x\n", 1671 " attr_mask 0x%x\n",
@@ -1784,8 +1882,10 @@ static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_send_wr *wr,
1784 return err; 1882 return err;
1785 } 1883 }
1786 1884
1787 vlan = rdma_get_vlan_id(&sgid); 1885 if (ah->av.eth.vlan != 0xffff) {
1788 is_vlan = vlan < 0x1000; 1886 vlan = be16_to_cpu(ah->av.eth.vlan) & 0x0fff;
1887 is_vlan = 1;
1888 }
1789 } 1889 }
1790 ib_ud_header_init(send_size, !is_eth, is_eth, is_vlan, is_grh, 0, &sqp->ud_header); 1890 ib_ud_header_init(send_size, !is_eth, is_eth, is_vlan, is_grh, 0, &sqp->ud_header);
1791 1891
@@ -2762,6 +2862,9 @@ done:
2762 if (qp->flags & MLX4_IB_QP_LSO) 2862 if (qp->flags & MLX4_IB_QP_LSO)
2763 qp_init_attr->create_flags |= IB_QP_CREATE_IPOIB_UD_LSO; 2863 qp_init_attr->create_flags |= IB_QP_CREATE_IPOIB_UD_LSO;
2764 2864
2865 if (qp->flags & MLX4_IB_QP_NETIF)
2866 qp_init_attr->create_flags |= IB_QP_CREATE_NETIF_QP;
2867
2765 qp_init_attr->sq_sig_type = 2868 qp_init_attr->sq_sig_type =
2766 qp->sq_signal_bits == cpu_to_be32(MLX4_WQE_CTRL_CQ_UPDATE) ? 2869 qp->sq_signal_bits == cpu_to_be32(MLX4_WQE_CTRL_CQ_UPDATE) ?
2767 IB_SIGNAL_ALL_WR : IB_SIGNAL_REQ_WR; 2870 IB_SIGNAL_ALL_WR : IB_SIGNAL_REQ_WR;
diff --git a/drivers/infiniband/hw/mlx4/sysfs.c b/drivers/infiniband/hw/mlx4/sysfs.c
index 97516eb363b7..db2ea31df832 100644
--- a/drivers/infiniband/hw/mlx4/sysfs.c
+++ b/drivers/infiniband/hw/mlx4/sysfs.c
@@ -582,8 +582,10 @@ static int add_port(struct mlx4_ib_dev *dev, int port_num, int slave)
582 p->pkey_group.attrs = 582 p->pkey_group.attrs =
583 alloc_group_attrs(show_port_pkey, store_port_pkey, 583 alloc_group_attrs(show_port_pkey, store_port_pkey,
584 dev->dev->caps.pkey_table_len[port_num]); 584 dev->dev->caps.pkey_table_len[port_num]);
585 if (!p->pkey_group.attrs) 585 if (!p->pkey_group.attrs) {
586 ret = -ENOMEM;
586 goto err_alloc; 587 goto err_alloc;
588 }
587 589
588 ret = sysfs_create_group(&p->kobj, &p->pkey_group); 590 ret = sysfs_create_group(&p->kobj, &p->pkey_group);
589 if (ret) 591 if (ret)
@@ -591,8 +593,10 @@ static int add_port(struct mlx4_ib_dev *dev, int port_num, int slave)
591 593
592 p->gid_group.name = "gid_idx"; 594 p->gid_group.name = "gid_idx";
593 p->gid_group.attrs = alloc_group_attrs(show_port_gid_idx, NULL, 1); 595 p->gid_group.attrs = alloc_group_attrs(show_port_gid_idx, NULL, 1);
594 if (!p->gid_group.attrs) 596 if (!p->gid_group.attrs) {
597 ret = -ENOMEM;
595 goto err_free_pkey; 598 goto err_free_pkey;
599 }
596 600
597 ret = sysfs_create_group(&p->kobj, &p->gid_group); 601 ret = sysfs_create_group(&p->kobj, &p->gid_group);
598 if (ret) 602 if (ret)
diff --git a/drivers/infiniband/hw/mlx5/cq.c b/drivers/infiniband/hw/mlx5/cq.c
index b72627429745..b1705ce6eb88 100644
--- a/drivers/infiniband/hw/mlx5/cq.c
+++ b/drivers/infiniband/hw/mlx5/cq.c
@@ -73,14 +73,24 @@ static void *get_cqe(struct mlx5_ib_cq *cq, int n)
73 return get_cqe_from_buf(&cq->buf, n, cq->mcq.cqe_sz); 73 return get_cqe_from_buf(&cq->buf, n, cq->mcq.cqe_sz);
74} 74}
75 75
76static u8 sw_ownership_bit(int n, int nent)
77{
78 return (n & nent) ? 1 : 0;
79}
80
76static void *get_sw_cqe(struct mlx5_ib_cq *cq, int n) 81static void *get_sw_cqe(struct mlx5_ib_cq *cq, int n)
77{ 82{
78 void *cqe = get_cqe(cq, n & cq->ibcq.cqe); 83 void *cqe = get_cqe(cq, n & cq->ibcq.cqe);
79 struct mlx5_cqe64 *cqe64; 84 struct mlx5_cqe64 *cqe64;
80 85
81 cqe64 = (cq->mcq.cqe_sz == 64) ? cqe : cqe + 64; 86 cqe64 = (cq->mcq.cqe_sz == 64) ? cqe : cqe + 64;
82 return ((cqe64->op_own & MLX5_CQE_OWNER_MASK) ^ 87
83 !!(n & (cq->ibcq.cqe + 1))) ? NULL : cqe; 88 if (likely((cqe64->op_own) >> 4 != MLX5_CQE_INVALID) &&
89 !((cqe64->op_own & MLX5_CQE_OWNER_MASK) ^ !!(n & (cq->ibcq.cqe + 1)))) {
90 return cqe;
91 } else {
92 return NULL;
93 }
84} 94}
85 95
86static void *next_cqe_sw(struct mlx5_ib_cq *cq) 96static void *next_cqe_sw(struct mlx5_ib_cq *cq)
@@ -351,6 +361,11 @@ static void handle_atomics(struct mlx5_ib_qp *qp, struct mlx5_cqe64 *cqe64,
351 qp->sq.last_poll = tail; 361 qp->sq.last_poll = tail;
352} 362}
353 363
364static void free_cq_buf(struct mlx5_ib_dev *dev, struct mlx5_ib_cq_buf *buf)
365{
366 mlx5_buf_free(&dev->mdev, &buf->buf);
367}
368
354static int mlx5_poll_one(struct mlx5_ib_cq *cq, 369static int mlx5_poll_one(struct mlx5_ib_cq *cq,
355 struct mlx5_ib_qp **cur_qp, 370 struct mlx5_ib_qp **cur_qp,
356 struct ib_wc *wc) 371 struct ib_wc *wc)
@@ -366,6 +381,7 @@ static int mlx5_poll_one(struct mlx5_ib_cq *cq,
366 void *cqe; 381 void *cqe;
367 int idx; 382 int idx;
368 383
384repoll:
369 cqe = next_cqe_sw(cq); 385 cqe = next_cqe_sw(cq);
370 if (!cqe) 386 if (!cqe)
371 return -EAGAIN; 387 return -EAGAIN;
@@ -379,7 +395,18 @@ static int mlx5_poll_one(struct mlx5_ib_cq *cq,
379 */ 395 */
380 rmb(); 396 rmb();
381 397
382 /* TBD: resize CQ */ 398 opcode = cqe64->op_own >> 4;
399 if (unlikely(opcode == MLX5_CQE_RESIZE_CQ)) {
400 if (likely(cq->resize_buf)) {
401 free_cq_buf(dev, &cq->buf);
402 cq->buf = *cq->resize_buf;
403 kfree(cq->resize_buf);
404 cq->resize_buf = NULL;
405 goto repoll;
406 } else {
407 mlx5_ib_warn(dev, "unexpected resize cqe\n");
408 }
409 }
383 410
384 qpn = ntohl(cqe64->sop_drop_qpn) & 0xffffff; 411 qpn = ntohl(cqe64->sop_drop_qpn) & 0xffffff;
385 if (!*cur_qp || (qpn != (*cur_qp)->ibqp.qp_num)) { 412 if (!*cur_qp || (qpn != (*cur_qp)->ibqp.qp_num)) {
@@ -398,7 +425,6 @@ static int mlx5_poll_one(struct mlx5_ib_cq *cq,
398 } 425 }
399 426
400 wc->qp = &(*cur_qp)->ibqp; 427 wc->qp = &(*cur_qp)->ibqp;
401 opcode = cqe64->op_own >> 4;
402 switch (opcode) { 428 switch (opcode) {
403 case MLX5_CQE_REQ: 429 case MLX5_CQE_REQ:
404 wq = &(*cur_qp)->sq; 430 wq = &(*cur_qp)->sq;
@@ -503,15 +529,11 @@ static int alloc_cq_buf(struct mlx5_ib_dev *dev, struct mlx5_ib_cq_buf *buf,
503 return err; 529 return err;
504 530
505 buf->cqe_size = cqe_size; 531 buf->cqe_size = cqe_size;
532 buf->nent = nent;
506 533
507 return 0; 534 return 0;
508} 535}
509 536
510static void free_cq_buf(struct mlx5_ib_dev *dev, struct mlx5_ib_cq_buf *buf)
511{
512 mlx5_buf_free(&dev->mdev, &buf->buf);
513}
514
515static int create_cq_user(struct mlx5_ib_dev *dev, struct ib_udata *udata, 537static int create_cq_user(struct mlx5_ib_dev *dev, struct ib_udata *udata,
516 struct ib_ucontext *context, struct mlx5_ib_cq *cq, 538 struct ib_ucontext *context, struct mlx5_ib_cq *cq,
517 int entries, struct mlx5_create_cq_mbox_in **cqb, 539 int entries, struct mlx5_create_cq_mbox_in **cqb,
@@ -576,16 +598,16 @@ static void destroy_cq_user(struct mlx5_ib_cq *cq, struct ib_ucontext *context)
576 ib_umem_release(cq->buf.umem); 598 ib_umem_release(cq->buf.umem);
577} 599}
578 600
579static void init_cq_buf(struct mlx5_ib_cq *cq, int nent) 601static void init_cq_buf(struct mlx5_ib_cq *cq, struct mlx5_ib_cq_buf *buf)
580{ 602{
581 int i; 603 int i;
582 void *cqe; 604 void *cqe;
583 struct mlx5_cqe64 *cqe64; 605 struct mlx5_cqe64 *cqe64;
584 606
585 for (i = 0; i < nent; i++) { 607 for (i = 0; i < buf->nent; i++) {
586 cqe = get_cqe(cq, i); 608 cqe = get_cqe_from_buf(buf, i, buf->cqe_size);
587 cqe64 = (cq->buf.cqe_size == 64) ? cqe : cqe + 64; 609 cqe64 = buf->cqe_size == 64 ? cqe : cqe + 64;
588 cqe64->op_own = 0xf1; 610 cqe64->op_own = MLX5_CQE_INVALID << 4;
589 } 611 }
590} 612}
591 613
@@ -610,7 +632,7 @@ static int create_cq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *cq,
610 if (err) 632 if (err)
611 goto err_db; 633 goto err_db;
612 634
613 init_cq_buf(cq, entries); 635 init_cq_buf(cq, &cq->buf);
614 636
615 *inlen = sizeof(**cqb) + sizeof(*(*cqb)->pas) * cq->buf.buf.npages; 637 *inlen = sizeof(**cqb) + sizeof(*(*cqb)->pas) * cq->buf.buf.npages;
616 *cqb = mlx5_vzalloc(*inlen); 638 *cqb = mlx5_vzalloc(*inlen);
@@ -818,12 +840,266 @@ void mlx5_ib_cq_clean(struct mlx5_ib_cq *cq, u32 qpn, struct mlx5_ib_srq *srq)
818 840
819int mlx5_ib_modify_cq(struct ib_cq *cq, u16 cq_count, u16 cq_period) 841int mlx5_ib_modify_cq(struct ib_cq *cq, u16 cq_count, u16 cq_period)
820{ 842{
821 return -ENOSYS; 843 struct mlx5_modify_cq_mbox_in *in;
844 struct mlx5_ib_dev *dev = to_mdev(cq->device);
845 struct mlx5_ib_cq *mcq = to_mcq(cq);
846 int err;
847 u32 fsel;
848
849 if (!(dev->mdev.caps.flags & MLX5_DEV_CAP_FLAG_CQ_MODER))
850 return -ENOSYS;
851
852 in = kzalloc(sizeof(*in), GFP_KERNEL);
853 if (!in)
854 return -ENOMEM;
855
856 in->cqn = cpu_to_be32(mcq->mcq.cqn);
857 fsel = (MLX5_CQ_MODIFY_PERIOD | MLX5_CQ_MODIFY_COUNT);
858 in->ctx.cq_period = cpu_to_be16(cq_period);
859 in->ctx.cq_max_count = cpu_to_be16(cq_count);
860 in->field_select = cpu_to_be32(fsel);
861 err = mlx5_core_modify_cq(&dev->mdev, &mcq->mcq, in, sizeof(*in));
862 kfree(in);
863
864 if (err)
865 mlx5_ib_warn(dev, "modify cq 0x%x failed\n", mcq->mcq.cqn);
866
867 return err;
868}
869
870static int resize_user(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *cq,
871 int entries, struct ib_udata *udata, int *npas,
872 int *page_shift, int *cqe_size)
873{
874 struct mlx5_ib_resize_cq ucmd;
875 struct ib_umem *umem;
876 int err;
877 int npages;
878 struct ib_ucontext *context = cq->buf.umem->context;
879
880 err = ib_copy_from_udata(&ucmd, udata, sizeof(ucmd));
881 if (err)
882 return err;
883
884 if (ucmd.reserved0 || ucmd.reserved1)
885 return -EINVAL;
886
887 umem = ib_umem_get(context, ucmd.buf_addr, entries * ucmd.cqe_size,
888 IB_ACCESS_LOCAL_WRITE, 1);
889 if (IS_ERR(umem)) {
890 err = PTR_ERR(umem);
891 return err;
892 }
893
894 mlx5_ib_cont_pages(umem, ucmd.buf_addr, &npages, page_shift,
895 npas, NULL);
896
897 cq->resize_umem = umem;
898 *cqe_size = ucmd.cqe_size;
899
900 return 0;
901}
902
903static void un_resize_user(struct mlx5_ib_cq *cq)
904{
905 ib_umem_release(cq->resize_umem);
906}
907
908static int resize_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *cq,
909 int entries, int cqe_size)
910{
911 int err;
912
913 cq->resize_buf = kzalloc(sizeof(*cq->resize_buf), GFP_KERNEL);
914 if (!cq->resize_buf)
915 return -ENOMEM;
916
917 err = alloc_cq_buf(dev, cq->resize_buf, entries, cqe_size);
918 if (err)
919 goto ex;
920
921 init_cq_buf(cq, cq->resize_buf);
922
923 return 0;
924
925ex:
926 kfree(cq->resize_buf);
927 return err;
928}
929
930static void un_resize_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *cq)
931{
932 free_cq_buf(dev, cq->resize_buf);
933 cq->resize_buf = NULL;
934}
935
936static int copy_resize_cqes(struct mlx5_ib_cq *cq)
937{
938 struct mlx5_ib_dev *dev = to_mdev(cq->ibcq.device);
939 struct mlx5_cqe64 *scqe64;
940 struct mlx5_cqe64 *dcqe64;
941 void *start_cqe;
942 void *scqe;
943 void *dcqe;
944 int ssize;
945 int dsize;
946 int i;
947 u8 sw_own;
948
949 ssize = cq->buf.cqe_size;
950 dsize = cq->resize_buf->cqe_size;
951 if (ssize != dsize) {
952 mlx5_ib_warn(dev, "resize from different cqe size is not supported\n");
953 return -EINVAL;
954 }
955
956 i = cq->mcq.cons_index;
957 scqe = get_sw_cqe(cq, i);
958 scqe64 = ssize == 64 ? scqe : scqe + 64;
959 start_cqe = scqe;
960 if (!scqe) {
961 mlx5_ib_warn(dev, "expected cqe in sw ownership\n");
962 return -EINVAL;
963 }
964
965 while ((scqe64->op_own >> 4) != MLX5_CQE_RESIZE_CQ) {
966 dcqe = get_cqe_from_buf(cq->resize_buf,
967 (i + 1) & (cq->resize_buf->nent),
968 dsize);
969 dcqe64 = dsize == 64 ? dcqe : dcqe + 64;
970 sw_own = sw_ownership_bit(i + 1, cq->resize_buf->nent);
971 memcpy(dcqe, scqe, dsize);
972 dcqe64->op_own = (dcqe64->op_own & ~MLX5_CQE_OWNER_MASK) | sw_own;
973
974 ++i;
975 scqe = get_sw_cqe(cq, i);
976 scqe64 = ssize == 64 ? scqe : scqe + 64;
977 if (!scqe) {
978 mlx5_ib_warn(dev, "expected cqe in sw ownership\n");
979 return -EINVAL;
980 }
981
982 if (scqe == start_cqe) {
983 pr_warn("resize CQ failed to get resize CQE, CQN 0x%x\n",
984 cq->mcq.cqn);
985 return -ENOMEM;
986 }
987 }
988 ++cq->mcq.cons_index;
989 return 0;
822} 990}
823 991
824int mlx5_ib_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *udata) 992int mlx5_ib_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *udata)
825{ 993{
826 return -ENOSYS; 994 struct mlx5_ib_dev *dev = to_mdev(ibcq->device);
995 struct mlx5_ib_cq *cq = to_mcq(ibcq);
996 struct mlx5_modify_cq_mbox_in *in;
997 int err;
998 int npas;
999 int page_shift;
1000 int inlen;
1001 int uninitialized_var(cqe_size);
1002 unsigned long flags;
1003
1004 if (!(dev->mdev.caps.flags & MLX5_DEV_CAP_FLAG_RESIZE_CQ)) {
1005 pr_info("Firmware does not support resize CQ\n");
1006 return -ENOSYS;
1007 }
1008
1009 if (entries < 1)
1010 return -EINVAL;
1011
1012 entries = roundup_pow_of_two(entries + 1);
1013 if (entries > dev->mdev.caps.max_cqes + 1)
1014 return -EINVAL;
1015
1016 if (entries == ibcq->cqe + 1)
1017 return 0;
1018
1019 mutex_lock(&cq->resize_mutex);
1020 if (udata) {
1021 err = resize_user(dev, cq, entries, udata, &npas, &page_shift,
1022 &cqe_size);
1023 } else {
1024 cqe_size = 64;
1025 err = resize_kernel(dev, cq, entries, cqe_size);
1026 if (!err) {
1027 npas = cq->resize_buf->buf.npages;
1028 page_shift = cq->resize_buf->buf.page_shift;
1029 }
1030 }
1031
1032 if (err)
1033 goto ex;
1034
1035 inlen = sizeof(*in) + npas * sizeof(in->pas[0]);
1036 in = mlx5_vzalloc(inlen);
1037 if (!in) {
1038 err = -ENOMEM;
1039 goto ex_resize;
1040 }
1041
1042 if (udata)
1043 mlx5_ib_populate_pas(dev, cq->resize_umem, page_shift,
1044 in->pas, 0);
1045 else
1046 mlx5_fill_page_array(&cq->resize_buf->buf, in->pas);
1047
1048 in->field_select = cpu_to_be32(MLX5_MODIFY_CQ_MASK_LOG_SIZE |
1049 MLX5_MODIFY_CQ_MASK_PG_OFFSET |
1050 MLX5_MODIFY_CQ_MASK_PG_SIZE);
1051 in->ctx.log_pg_sz = page_shift - MLX5_ADAPTER_PAGE_SHIFT;
1052 in->ctx.cqe_sz_flags = cqe_sz_to_mlx_sz(cqe_size) << 5;
1053 in->ctx.page_offset = 0;
1054 in->ctx.log_sz_usr_page = cpu_to_be32(ilog2(entries) << 24);
1055 in->hdr.opmod = cpu_to_be16(MLX5_CQ_OPMOD_RESIZE);
1056 in->cqn = cpu_to_be32(cq->mcq.cqn);
1057
1058 err = mlx5_core_modify_cq(&dev->mdev, &cq->mcq, in, inlen);
1059 if (err)
1060 goto ex_alloc;
1061
1062 if (udata) {
1063 cq->ibcq.cqe = entries - 1;
1064 ib_umem_release(cq->buf.umem);
1065 cq->buf.umem = cq->resize_umem;
1066 cq->resize_umem = NULL;
1067 } else {
1068 struct mlx5_ib_cq_buf tbuf;
1069 int resized = 0;
1070
1071 spin_lock_irqsave(&cq->lock, flags);
1072 if (cq->resize_buf) {
1073 err = copy_resize_cqes(cq);
1074 if (!err) {
1075 tbuf = cq->buf;
1076 cq->buf = *cq->resize_buf;
1077 kfree(cq->resize_buf);
1078 cq->resize_buf = NULL;
1079 resized = 1;
1080 }
1081 }
1082 cq->ibcq.cqe = entries - 1;
1083 spin_unlock_irqrestore(&cq->lock, flags);
1084 if (resized)
1085 free_cq_buf(dev, &tbuf);
1086 }
1087 mutex_unlock(&cq->resize_mutex);
1088
1089 mlx5_vfree(in);
1090 return 0;
1091
1092ex_alloc:
1093 mlx5_vfree(in);
1094
1095ex_resize:
1096 if (udata)
1097 un_resize_user(cq);
1098 else
1099 un_resize_kernel(dev, cq);
1100ex:
1101 mutex_unlock(&cq->resize_mutex);
1102 return err;
827} 1103}
828 1104
829int mlx5_ib_get_cqe_size(struct mlx5_ib_dev *dev, struct ib_cq *ibcq) 1105int mlx5_ib_get_cqe_size(struct mlx5_ib_dev *dev, struct ib_cq *ibcq)
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
index 306534109627..9660d093f8cf 100644
--- a/drivers/infiniband/hw/mlx5/main.c
+++ b/drivers/infiniband/hw/mlx5/main.c
@@ -541,6 +541,7 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
541 struct mlx5_ib_ucontext *context; 541 struct mlx5_ib_ucontext *context;
542 struct mlx5_uuar_info *uuari; 542 struct mlx5_uuar_info *uuari;
543 struct mlx5_uar *uars; 543 struct mlx5_uar *uars;
544 int gross_uuars;
544 int num_uars; 545 int num_uars;
545 int uuarn; 546 int uuarn;
546 int err; 547 int err;
@@ -559,11 +560,13 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
559 if (req.total_num_uuars == 0) 560 if (req.total_num_uuars == 0)
560 return ERR_PTR(-EINVAL); 561 return ERR_PTR(-EINVAL);
561 562
562 req.total_num_uuars = ALIGN(req.total_num_uuars, MLX5_BF_REGS_PER_PAGE); 563 req.total_num_uuars = ALIGN(req.total_num_uuars,
564 MLX5_NON_FP_BF_REGS_PER_PAGE);
563 if (req.num_low_latency_uuars > req.total_num_uuars - 1) 565 if (req.num_low_latency_uuars > req.total_num_uuars - 1)
564 return ERR_PTR(-EINVAL); 566 return ERR_PTR(-EINVAL);
565 567
566 num_uars = req.total_num_uuars / MLX5_BF_REGS_PER_PAGE; 568 num_uars = req.total_num_uuars / MLX5_NON_FP_BF_REGS_PER_PAGE;
569 gross_uuars = num_uars * MLX5_BF_REGS_PER_PAGE;
567 resp.qp_tab_size = 1 << dev->mdev.caps.log_max_qp; 570 resp.qp_tab_size = 1 << dev->mdev.caps.log_max_qp;
568 resp.bf_reg_size = dev->mdev.caps.bf_reg_size; 571 resp.bf_reg_size = dev->mdev.caps.bf_reg_size;
569 resp.cache_line_size = L1_CACHE_BYTES; 572 resp.cache_line_size = L1_CACHE_BYTES;
@@ -585,7 +588,7 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
585 goto out_ctx; 588 goto out_ctx;
586 } 589 }
587 590
588 uuari->bitmap = kcalloc(BITS_TO_LONGS(req.total_num_uuars), 591 uuari->bitmap = kcalloc(BITS_TO_LONGS(gross_uuars),
589 sizeof(*uuari->bitmap), 592 sizeof(*uuari->bitmap),
590 GFP_KERNEL); 593 GFP_KERNEL);
591 if (!uuari->bitmap) { 594 if (!uuari->bitmap) {
@@ -595,13 +598,13 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
595 /* 598 /*
596 * clear all fast path uuars 599 * clear all fast path uuars
597 */ 600 */
598 for (i = 0; i < req.total_num_uuars; i++) { 601 for (i = 0; i < gross_uuars; i++) {
599 uuarn = i & 3; 602 uuarn = i & 3;
600 if (uuarn == 2 || uuarn == 3) 603 if (uuarn == 2 || uuarn == 3)
601 set_bit(i, uuari->bitmap); 604 set_bit(i, uuari->bitmap);
602 } 605 }
603 606
604 uuari->count = kcalloc(req.total_num_uuars, sizeof(*uuari->count), GFP_KERNEL); 607 uuari->count = kcalloc(gross_uuars, sizeof(*uuari->count), GFP_KERNEL);
605 if (!uuari->count) { 608 if (!uuari->count) {
606 err = -ENOMEM; 609 err = -ENOMEM;
607 goto out_bitmap; 610 goto out_bitmap;
diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h
index 4c134d93d4fc..389e31965773 100644
--- a/drivers/infiniband/hw/mlx5/mlx5_ib.h
+++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h
@@ -195,6 +195,7 @@ struct mlx5_ib_cq_buf {
195 struct mlx5_buf buf; 195 struct mlx5_buf buf;
196 struct ib_umem *umem; 196 struct ib_umem *umem;
197 int cqe_size; 197 int cqe_size;
198 int nent;
198}; 199};
199 200
200enum mlx5_ib_qp_flags { 201enum mlx5_ib_qp_flags {
@@ -220,7 +221,7 @@ struct mlx5_ib_cq {
220 /* protect resize cq 221 /* protect resize cq
221 */ 222 */
222 struct mutex resize_mutex; 223 struct mutex resize_mutex;
223 struct mlx5_ib_cq_resize *resize_buf; 224 struct mlx5_ib_cq_buf *resize_buf;
224 struct ib_umem *resize_umem; 225 struct ib_umem *resize_umem;
225 int cqe_size; 226 int cqe_size;
226}; 227};
@@ -264,7 +265,6 @@ struct mlx5_ib_mr {
264 enum ib_wc_status status; 265 enum ib_wc_status status;
265 struct mlx5_ib_dev *dev; 266 struct mlx5_ib_dev *dev;
266 struct mlx5_create_mkey_mbox_out out; 267 struct mlx5_create_mkey_mbox_out out;
267 unsigned long start;
268}; 268};
269 269
270struct mlx5_ib_fast_reg_page_list { 270struct mlx5_ib_fast_reg_page_list {
diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c
index 039c3e40fcb4..7c95ca1f0c25 100644
--- a/drivers/infiniband/hw/mlx5/mr.c
+++ b/drivers/infiniband/hw/mlx5/mr.c
@@ -146,7 +146,6 @@ static int add_keys(struct mlx5_ib_dev *dev, int c, int num)
146 spin_lock_irq(&ent->lock); 146 spin_lock_irq(&ent->lock);
147 ent->pending++; 147 ent->pending++;
148 spin_unlock_irq(&ent->lock); 148 spin_unlock_irq(&ent->lock);
149 mr->start = jiffies;
150 err = mlx5_core_create_mkey(&dev->mdev, &mr->mmr, in, 149 err = mlx5_core_create_mkey(&dev->mdev, &mr->mmr, in,
151 sizeof(*in), reg_mr_callback, 150 sizeof(*in), reg_mr_callback,
152 mr, &mr->out); 151 mr, &mr->out);
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index 7c6b4ba49bec..ae37fb9bf262 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -340,14 +340,57 @@ static int qp_has_rq(struct ib_qp_init_attr *attr)
340 return 1; 340 return 1;
341} 341}
342 342
343static int first_med_uuar(void)
344{
345 return 1;
346}
347
348static int next_uuar(int n)
349{
350 n++;
351
352 while (((n % 4) & 2))
353 n++;
354
355 return n;
356}
357
358static int num_med_uuar(struct mlx5_uuar_info *uuari)
359{
360 int n;
361
362 n = uuari->num_uars * MLX5_NON_FP_BF_REGS_PER_PAGE -
363 uuari->num_low_latency_uuars - 1;
364
365 return n >= 0 ? n : 0;
366}
367
368static int max_uuari(struct mlx5_uuar_info *uuari)
369{
370 return uuari->num_uars * 4;
371}
372
373static int first_hi_uuar(struct mlx5_uuar_info *uuari)
374{
375 int med;
376 int i;
377 int t;
378
379 med = num_med_uuar(uuari);
380 for (t = 0, i = first_med_uuar();; i = next_uuar(i)) {
381 t++;
382 if (t == med)
383 return next_uuar(i);
384 }
385
386 return 0;
387}
388
343static int alloc_high_class_uuar(struct mlx5_uuar_info *uuari) 389static int alloc_high_class_uuar(struct mlx5_uuar_info *uuari)
344{ 390{
345 int nuuars = uuari->num_uars * MLX5_BF_REGS_PER_PAGE;
346 int start_uuar;
347 int i; 391 int i;
348 392
349 start_uuar = nuuars - uuari->num_low_latency_uuars; 393 for (i = first_hi_uuar(uuari); i < max_uuari(uuari); i = next_uuar(i)) {
350 for (i = start_uuar; i < nuuars; i++) {
351 if (!test_bit(i, uuari->bitmap)) { 394 if (!test_bit(i, uuari->bitmap)) {
352 set_bit(i, uuari->bitmap); 395 set_bit(i, uuari->bitmap);
353 uuari->count[i]++; 396 uuari->count[i]++;
@@ -360,19 +403,10 @@ static int alloc_high_class_uuar(struct mlx5_uuar_info *uuari)
360 403
361static int alloc_med_class_uuar(struct mlx5_uuar_info *uuari) 404static int alloc_med_class_uuar(struct mlx5_uuar_info *uuari)
362{ 405{
363 int nuuars = uuari->num_uars * MLX5_BF_REGS_PER_PAGE; 406 int minidx = first_med_uuar();
364 int minidx = 1;
365 int uuarn;
366 int end;
367 int i; 407 int i;
368 408
369 end = nuuars - uuari->num_low_latency_uuars; 409 for (i = first_med_uuar(); i < first_hi_uuar(uuari); i = next_uuar(i)) {
370
371 for (i = 1; i < end; i++) {
372 uuarn = i & 3;
373 if (uuarn == 2 || uuarn == 3)
374 continue;
375
376 if (uuari->count[i] < uuari->count[minidx]) 410 if (uuari->count[i] < uuari->count[minidx])
377 minidx = i; 411 minidx = i;
378 } 412 }
@@ -489,12 +523,12 @@ static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
489{ 523{
490 struct mlx5_ib_ucontext *context; 524 struct mlx5_ib_ucontext *context;
491 struct mlx5_ib_create_qp ucmd; 525 struct mlx5_ib_create_qp ucmd;
492 int page_shift; 526 int page_shift = 0;
493 int uar_index; 527 int uar_index;
494 int npages; 528 int npages;
495 u32 offset; 529 u32 offset = 0;
496 int uuarn; 530 int uuarn;
497 int ncont; 531 int ncont = 0;
498 int err; 532 int err;
499 533
500 err = ib_copy_from_udata(&ucmd, udata, sizeof(ucmd)); 534 err = ib_copy_from_udata(&ucmd, udata, sizeof(ucmd));
@@ -510,11 +544,16 @@ static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
510 uuarn = alloc_uuar(&context->uuari, MLX5_IB_LATENCY_CLASS_HIGH); 544 uuarn = alloc_uuar(&context->uuari, MLX5_IB_LATENCY_CLASS_HIGH);
511 if (uuarn < 0) { 545 if (uuarn < 0) {
512 mlx5_ib_dbg(dev, "failed to allocate low latency UUAR\n"); 546 mlx5_ib_dbg(dev, "failed to allocate low latency UUAR\n");
513 mlx5_ib_dbg(dev, "reverting to high latency\n"); 547 mlx5_ib_dbg(dev, "reverting to medium latency\n");
514 uuarn = alloc_uuar(&context->uuari, MLX5_IB_LATENCY_CLASS_LOW); 548 uuarn = alloc_uuar(&context->uuari, MLX5_IB_LATENCY_CLASS_MEDIUM);
515 if (uuarn < 0) { 549 if (uuarn < 0) {
516 mlx5_ib_dbg(dev, "uuar allocation failed\n"); 550 mlx5_ib_dbg(dev, "failed to allocate medium latency UUAR\n");
517 return uuarn; 551 mlx5_ib_dbg(dev, "reverting to high latency\n");
552 uuarn = alloc_uuar(&context->uuari, MLX5_IB_LATENCY_CLASS_LOW);
553 if (uuarn < 0) {
554 mlx5_ib_warn(dev, "uuar allocation failed\n");
555 return uuarn;
556 }
518 } 557 }
519 } 558 }
520 559
@@ -525,23 +564,29 @@ static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
525 if (err) 564 if (err)
526 goto err_uuar; 565 goto err_uuar;
527 566
528 qp->umem = ib_umem_get(pd->uobject->context, ucmd.buf_addr, 567 if (ucmd.buf_addr && qp->buf_size) {
529 qp->buf_size, 0, 0); 568 qp->umem = ib_umem_get(pd->uobject->context, ucmd.buf_addr,
530 if (IS_ERR(qp->umem)) { 569 qp->buf_size, 0, 0);
531 mlx5_ib_dbg(dev, "umem_get failed\n"); 570 if (IS_ERR(qp->umem)) {
532 err = PTR_ERR(qp->umem); 571 mlx5_ib_dbg(dev, "umem_get failed\n");
533 goto err_uuar; 572 err = PTR_ERR(qp->umem);
573 goto err_uuar;
574 }
575 } else {
576 qp->umem = NULL;
534 } 577 }
535 578
536 mlx5_ib_cont_pages(qp->umem, ucmd.buf_addr, &npages, &page_shift, 579 if (qp->umem) {
537 &ncont, NULL); 580 mlx5_ib_cont_pages(qp->umem, ucmd.buf_addr, &npages, &page_shift,
538 err = mlx5_ib_get_buf_offset(ucmd.buf_addr, page_shift, &offset); 581 &ncont, NULL);
539 if (err) { 582 err = mlx5_ib_get_buf_offset(ucmd.buf_addr, page_shift, &offset);
540 mlx5_ib_warn(dev, "bad offset\n"); 583 if (err) {
541 goto err_umem; 584 mlx5_ib_warn(dev, "bad offset\n");
585 goto err_umem;
586 }
587 mlx5_ib_dbg(dev, "addr 0x%llx, size %d, npages %d, page_shift %d, ncont %d, offset %d\n",
588 ucmd.buf_addr, qp->buf_size, npages, page_shift, ncont, offset);
542 } 589 }
543 mlx5_ib_dbg(dev, "addr 0x%llx, size %d, npages %d, page_shift %d, ncont %d, offset %d\n",
544 ucmd.buf_addr, qp->buf_size, npages, page_shift, ncont, offset);
545 590
546 *inlen = sizeof(**in) + sizeof(*(*in)->pas) * ncont; 591 *inlen = sizeof(**in) + sizeof(*(*in)->pas) * ncont;
547 *in = mlx5_vzalloc(*inlen); 592 *in = mlx5_vzalloc(*inlen);
@@ -549,7 +594,8 @@ static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
549 err = -ENOMEM; 594 err = -ENOMEM;
550 goto err_umem; 595 goto err_umem;
551 } 596 }
552 mlx5_ib_populate_pas(dev, qp->umem, page_shift, (*in)->pas, 0); 597 if (qp->umem)
598 mlx5_ib_populate_pas(dev, qp->umem, page_shift, (*in)->pas, 0);
553 (*in)->ctx.log_pg_sz_remote_qpn = 599 (*in)->ctx.log_pg_sz_remote_qpn =
554 cpu_to_be32((page_shift - MLX5_ADAPTER_PAGE_SHIFT) << 24); 600 cpu_to_be32((page_shift - MLX5_ADAPTER_PAGE_SHIFT) << 24);
555 (*in)->ctx.params2 = cpu_to_be32(offset << 6); 601 (*in)->ctx.params2 = cpu_to_be32(offset << 6);
@@ -580,7 +626,8 @@ err_free:
580 mlx5_vfree(*in); 626 mlx5_vfree(*in);
581 627
582err_umem: 628err_umem:
583 ib_umem_release(qp->umem); 629 if (qp->umem)
630 ib_umem_release(qp->umem);
584 631
585err_uuar: 632err_uuar:
586 free_uuar(&context->uuari, uuarn); 633 free_uuar(&context->uuari, uuarn);
@@ -593,7 +640,8 @@ static void destroy_qp_user(struct ib_pd *pd, struct mlx5_ib_qp *qp)
593 640
594 context = to_mucontext(pd->uobject->context); 641 context = to_mucontext(pd->uobject->context);
595 mlx5_ib_db_unmap_user(context, &qp->db); 642 mlx5_ib_db_unmap_user(context, &qp->db);
596 ib_umem_release(qp->umem); 643 if (qp->umem)
644 ib_umem_release(qp->umem);
597 free_uuar(&context->uuari, qp->uuarn); 645 free_uuar(&context->uuari, qp->uuarn);
598} 646}
599 647
@@ -1616,7 +1664,8 @@ int mlx5_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
1616 new_state = attr_mask & IB_QP_STATE ? attr->qp_state : cur_state; 1664 new_state = attr_mask & IB_QP_STATE ? attr->qp_state : cur_state;
1617 1665
1618 if (ibqp->qp_type != MLX5_IB_QPT_REG_UMR && 1666 if (ibqp->qp_type != MLX5_IB_QPT_REG_UMR &&
1619 !ib_modify_qp_is_ok(cur_state, new_state, ibqp->qp_type, attr_mask)) 1667 !ib_modify_qp_is_ok(cur_state, new_state, ibqp->qp_type, attr_mask,
1668 IB_LINK_LAYER_UNSPECIFIED))
1620 goto out; 1669 goto out;
1621 1670
1622 if ((attr_mask & IB_QP_PORT) && 1671 if ((attr_mask & IB_QP_PORT) &&
@@ -2212,6 +2261,10 @@ out:
2212 2261
2213 qp->db.db[MLX5_SND_DBR] = cpu_to_be32(qp->sq.cur_post); 2262 qp->db.db[MLX5_SND_DBR] = cpu_to_be32(qp->sq.cur_post);
2214 2263
2264 /* Make sure doorbell record is visible to the HCA before
2265 * we hit doorbell */
2266 wmb();
2267
2215 if (bf->need_lock) 2268 if (bf->need_lock)
2216 spin_lock(&bf->lock); 2269 spin_lock(&bf->lock);
2217 2270
diff --git a/drivers/infiniband/hw/mlx5/user.h b/drivers/infiniband/hw/mlx5/user.h
index a886de3e593c..32a2a5dfc523 100644
--- a/drivers/infiniband/hw/mlx5/user.h
+++ b/drivers/infiniband/hw/mlx5/user.h
@@ -93,6 +93,9 @@ struct mlx5_ib_create_cq_resp {
93 93
94struct mlx5_ib_resize_cq { 94struct mlx5_ib_resize_cq {
95 __u64 buf_addr; 95 __u64 buf_addr;
96 __u16 cqe_size;
97 __u16 reserved0;
98 __u32 reserved1;
96}; 99};
97 100
98struct mlx5_ib_create_srq { 101struct mlx5_ib_create_srq {
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
index 26a684536109..e354b2f04ad9 100644
--- a/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -860,7 +860,8 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask,
860 860
861 new_state = attr_mask & IB_QP_STATE ? attr->qp_state : cur_state; 861 new_state = attr_mask & IB_QP_STATE ? attr->qp_state : cur_state;
862 862
863 if (!ib_modify_qp_is_ok(cur_state, new_state, ibqp->qp_type, attr_mask)) { 863 if (!ib_modify_qp_is_ok(cur_state, new_state, ibqp->qp_type, attr_mask,
864 IB_LINK_LAYER_UNSPECIFIED)) {
864 mthca_dbg(dev, "Bad QP transition (transport %d) " 865 mthca_dbg(dev, "Bad QP transition (transport %d) "
865 "%d->%d with attr 0x%08x\n", 866 "%d->%d with attr 0x%08x\n",
866 qp->transport, cur_state, new_state, 867 qp->transport, cur_state, new_state,
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index 6b29249aa85a..9c9f2f57e960 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -1354,8 +1354,7 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi
1354 neigh->ha, ntohl(rt->rt_gateway)); 1354 neigh->ha, ntohl(rt->rt_gateway));
1355 1355
1356 if (arpindex >= 0) { 1356 if (arpindex >= 0) {
1357 if (!memcmp(nesadapter->arp_table[arpindex].mac_addr, 1357 if (ether_addr_equal(nesadapter->arp_table[arpindex].mac_addr, neigh->ha)) {
1358 neigh->ha, ETH_ALEN)) {
1359 /* Mac address same as in nes_arp_table */ 1358 /* Mac address same as in nes_arp_table */
1360 goto out; 1359 goto out;
1361 } 1360 }
diff --git a/drivers/infiniband/hw/ocrdma/Kconfig b/drivers/infiniband/hw/ocrdma/Kconfig
index b5b6056c8518..c0cddc0192d1 100644
--- a/drivers/infiniband/hw/ocrdma/Kconfig
+++ b/drivers/infiniband/hw/ocrdma/Kconfig
@@ -1,6 +1,6 @@
1config INFINIBAND_OCRDMA 1config INFINIBAND_OCRDMA
2 tristate "Emulex One Connect HCA support" 2 tristate "Emulex One Connect HCA support"
3 depends on ETHERNET && NETDEVICES && PCI && (IPV6 || IPV6=n) 3 depends on ETHERNET && NETDEVICES && PCI && INET && (IPV6 || IPV6=n)
4 select NET_VENDOR_EMULEX 4 select NET_VENDOR_EMULEX
5 select BE2NET 5 select BE2NET
6 ---help--- 6 ---help---
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma.h b/drivers/infiniband/hw/ocrdma/ocrdma.h
index 294dd27b601e..7c001b97b23f 100644
--- a/drivers/infiniband/hw/ocrdma/ocrdma.h
+++ b/drivers/infiniband/hw/ocrdma/ocrdma.h
@@ -423,5 +423,17 @@ static inline int is_cqe_wr_imm(struct ocrdma_cqe *cqe)
423 OCRDMA_CQE_WRITE_IMM) ? 1 : 0; 423 OCRDMA_CQE_WRITE_IMM) ? 1 : 0;
424} 424}
425 425
426static inline int ocrdma_resolve_dmac(struct ocrdma_dev *dev,
427 struct ib_ah_attr *ah_attr, u8 *mac_addr)
428{
429 struct in6_addr in6;
430
431 memcpy(&in6, ah_attr->grh.dgid.raw, sizeof(in6));
432 if (rdma_is_multicast_addr(&in6))
433 rdma_get_mcast_mac(&in6, mac_addr);
434 else
435 memcpy(mac_addr, ah_attr->dmac, ETH_ALEN);
436 return 0;
437}
426 438
427#endif 439#endif
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_ah.c b/drivers/infiniband/hw/ocrdma/ocrdma_ah.c
index ee499d942257..34071143006e 100644
--- a/drivers/infiniband/hw/ocrdma/ocrdma_ah.c
+++ b/drivers/infiniband/hw/ocrdma/ocrdma_ah.c
@@ -49,7 +49,7 @@ static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah,
49 49
50 ah->sgid_index = attr->grh.sgid_index; 50 ah->sgid_index = attr->grh.sgid_index;
51 51
52 vlan_tag = rdma_get_vlan_id(&attr->grh.dgid); 52 vlan_tag = attr->vlan_id;
53 if (!vlan_tag || (vlan_tag > 0xFFF)) 53 if (!vlan_tag || (vlan_tag > 0xFFF))
54 vlan_tag = dev->pvid; 54 vlan_tag = dev->pvid;
55 if (vlan_tag && (vlan_tag < 0x1000)) { 55 if (vlan_tag && (vlan_tag < 0x1000)) {
@@ -64,7 +64,8 @@ static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah,
64 eth_sz = sizeof(struct ocrdma_eth_basic); 64 eth_sz = sizeof(struct ocrdma_eth_basic);
65 } 65 }
66 memcpy(&eth.smac[0], &dev->nic_info.mac_addr[0], ETH_ALEN); 66 memcpy(&eth.smac[0], &dev->nic_info.mac_addr[0], ETH_ALEN);
67 status = ocrdma_resolve_dgid(dev, &attr->grh.dgid, &eth.dmac[0]); 67 memcpy(&eth.dmac[0], attr->dmac, ETH_ALEN);
68 status = ocrdma_resolve_dmac(dev, attr, &eth.dmac[0]);
68 if (status) 69 if (status)
69 return status; 70 return status;
70 status = ocrdma_query_gid(&dev->ibdev, 1, attr->grh.sgid_index, 71 status = ocrdma_query_gid(&dev->ibdev, 1, attr->grh.sgid_index,
@@ -84,6 +85,7 @@ static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah,
84 memcpy((u8 *)ah->av + eth_sz, &grh, sizeof(struct ocrdma_grh)); 85 memcpy((u8 *)ah->av + eth_sz, &grh, sizeof(struct ocrdma_grh));
85 if (vlan_enabled) 86 if (vlan_enabled)
86 ah->av->valid |= OCRDMA_AV_VLAN_VALID; 87 ah->av->valid |= OCRDMA_AV_VLAN_VALID;
88 ah->av->valid = cpu_to_le32(ah->av->valid);
87 return status; 89 return status;
88} 90}
89 91
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
index 56bf32fcb62c..1664d648cbfc 100644
--- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
@@ -2076,23 +2076,6 @@ mbx_err:
2076 return status; 2076 return status;
2077} 2077}
2078 2078
2079int ocrdma_resolve_dgid(struct ocrdma_dev *dev, union ib_gid *dgid,
2080 u8 *mac_addr)
2081{
2082 struct in6_addr in6;
2083
2084 memcpy(&in6, dgid, sizeof in6);
2085 if (rdma_is_multicast_addr(&in6)) {
2086 rdma_get_mcast_mac(&in6, mac_addr);
2087 } else if (rdma_link_local_addr(&in6)) {
2088 rdma_get_ll_mac(&in6, mac_addr);
2089 } else {
2090 pr_err("%s() fail to resolve mac_addr.\n", __func__);
2091 return -EINVAL;
2092 }
2093 return 0;
2094}
2095
2096static int ocrdma_set_av_params(struct ocrdma_qp *qp, 2079static int ocrdma_set_av_params(struct ocrdma_qp *qp,
2097 struct ocrdma_modify_qp *cmd, 2080 struct ocrdma_modify_qp *cmd,
2098 struct ib_qp_attr *attrs) 2081 struct ib_qp_attr *attrs)
@@ -2126,14 +2109,14 @@ static int ocrdma_set_av_params(struct ocrdma_qp *qp,
2126 2109
2127 qp->sgid_idx = ah_attr->grh.sgid_index; 2110 qp->sgid_idx = ah_attr->grh.sgid_index;
2128 memcpy(&cmd->params.sgid[0], &sgid.raw[0], sizeof(cmd->params.sgid)); 2111 memcpy(&cmd->params.sgid[0], &sgid.raw[0], sizeof(cmd->params.sgid));
2129 ocrdma_resolve_dgid(qp->dev, &ah_attr->grh.dgid, &mac_addr[0]); 2112 ocrdma_resolve_dmac(qp->dev, ah_attr, &mac_addr[0]);
2130 cmd->params.dmac_b0_to_b3 = mac_addr[0] | (mac_addr[1] << 8) | 2113 cmd->params.dmac_b0_to_b3 = mac_addr[0] | (mac_addr[1] << 8) |
2131 (mac_addr[2] << 16) | (mac_addr[3] << 24); 2114 (mac_addr[2] << 16) | (mac_addr[3] << 24);
2132 /* convert them to LE format. */ 2115 /* convert them to LE format. */
2133 ocrdma_cpu_to_le32(&cmd->params.dgid[0], sizeof(cmd->params.dgid)); 2116 ocrdma_cpu_to_le32(&cmd->params.dgid[0], sizeof(cmd->params.dgid));
2134 ocrdma_cpu_to_le32(&cmd->params.sgid[0], sizeof(cmd->params.sgid)); 2117 ocrdma_cpu_to_le32(&cmd->params.sgid[0], sizeof(cmd->params.sgid));
2135 cmd->params.vlan_dmac_b4_to_b5 = mac_addr[4] | (mac_addr[5] << 8); 2118 cmd->params.vlan_dmac_b4_to_b5 = mac_addr[4] | (mac_addr[5] << 8);
2136 vlan_id = rdma_get_vlan_id(&sgid); 2119 vlan_id = ah_attr->vlan_id;
2137 if (vlan_id && (vlan_id < 0x1000)) { 2120 if (vlan_id && (vlan_id < 0x1000)) {
2138 cmd->params.vlan_dmac_b4_to_b5 |= 2121 cmd->params.vlan_dmac_b4_to_b5 |=
2139 vlan_id << OCRDMA_QP_PARAMS_VLAN_SHIFT; 2122 vlan_id << OCRDMA_QP_PARAMS_VLAN_SHIFT;
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.h b/drivers/infiniband/hw/ocrdma/ocrdma_hw.h
index f2a89d4cc7c4..82fe332ae6c6 100644
--- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.h
+++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.h
@@ -94,7 +94,6 @@ void ocrdma_ring_cq_db(struct ocrdma_dev *, u16 cq_id, bool armed,
94int ocrdma_mbx_get_link_speed(struct ocrdma_dev *dev, u8 *lnk_speed); 94int ocrdma_mbx_get_link_speed(struct ocrdma_dev *dev, u8 *lnk_speed);
95int ocrdma_query_config(struct ocrdma_dev *, 95int ocrdma_query_config(struct ocrdma_dev *,
96 struct ocrdma_mbx_query_config *config); 96 struct ocrdma_mbx_query_config *config);
97int ocrdma_resolve_dgid(struct ocrdma_dev *, union ib_gid *dgid, u8 *mac_addr);
98 97
99int ocrdma_mbx_alloc_pd(struct ocrdma_dev *, struct ocrdma_pd *); 98int ocrdma_mbx_alloc_pd(struct ocrdma_dev *, struct ocrdma_pd *);
100int ocrdma_mbx_dealloc_pd(struct ocrdma_dev *, struct ocrdma_pd *); 99int ocrdma_mbx_dealloc_pd(struct ocrdma_dev *, struct ocrdma_pd *);
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
index 91443bcb9e0e..2ca86ca818bd 100644
--- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c
+++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
@@ -67,46 +67,24 @@ void ocrdma_get_guid(struct ocrdma_dev *dev, u8 *guid)
67 guid[7] = mac_addr[5]; 67 guid[7] = mac_addr[5];
68} 68}
69 69
70static void ocrdma_build_sgid_mac(union ib_gid *sgid, unsigned char *mac_addr, 70static bool ocrdma_add_sgid(struct ocrdma_dev *dev, union ib_gid *new_sgid)
71 bool is_vlan, u16 vlan_id)
72{
73 sgid->global.subnet_prefix = cpu_to_be64(0xfe80000000000000LL);
74 sgid->raw[8] = mac_addr[0] ^ 2;
75 sgid->raw[9] = mac_addr[1];
76 sgid->raw[10] = mac_addr[2];
77 if (is_vlan) {
78 sgid->raw[11] = vlan_id >> 8;
79 sgid->raw[12] = vlan_id & 0xff;
80 } else {
81 sgid->raw[11] = 0xff;
82 sgid->raw[12] = 0xfe;
83 }
84 sgid->raw[13] = mac_addr[3];
85 sgid->raw[14] = mac_addr[4];
86 sgid->raw[15] = mac_addr[5];
87}
88
89static bool ocrdma_add_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr,
90 bool is_vlan, u16 vlan_id)
91{ 71{
92 int i; 72 int i;
93 union ib_gid new_sgid;
94 unsigned long flags; 73 unsigned long flags;
95 74
96 memset(&ocrdma_zero_sgid, 0, sizeof(union ib_gid)); 75 memset(&ocrdma_zero_sgid, 0, sizeof(union ib_gid));
97 76
98 ocrdma_build_sgid_mac(&new_sgid, mac_addr, is_vlan, vlan_id);
99 77
100 spin_lock_irqsave(&dev->sgid_lock, flags); 78 spin_lock_irqsave(&dev->sgid_lock, flags);
101 for (i = 0; i < OCRDMA_MAX_SGID; i++) { 79 for (i = 0; i < OCRDMA_MAX_SGID; i++) {
102 if (!memcmp(&dev->sgid_tbl[i], &ocrdma_zero_sgid, 80 if (!memcmp(&dev->sgid_tbl[i], &ocrdma_zero_sgid,
103 sizeof(union ib_gid))) { 81 sizeof(union ib_gid))) {
104 /* found free entry */ 82 /* found free entry */
105 memcpy(&dev->sgid_tbl[i], &new_sgid, 83 memcpy(&dev->sgid_tbl[i], new_sgid,
106 sizeof(union ib_gid)); 84 sizeof(union ib_gid));
107 spin_unlock_irqrestore(&dev->sgid_lock, flags); 85 spin_unlock_irqrestore(&dev->sgid_lock, flags);
108 return true; 86 return true;
109 } else if (!memcmp(&dev->sgid_tbl[i], &new_sgid, 87 } else if (!memcmp(&dev->sgid_tbl[i], new_sgid,
110 sizeof(union ib_gid))) { 88 sizeof(union ib_gid))) {
111 /* entry already present, no addition is required. */ 89 /* entry already present, no addition is required. */
112 spin_unlock_irqrestore(&dev->sgid_lock, flags); 90 spin_unlock_irqrestore(&dev->sgid_lock, flags);
@@ -117,20 +95,17 @@ static bool ocrdma_add_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr,
117 return false; 95 return false;
118} 96}
119 97
120static bool ocrdma_del_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr, 98static bool ocrdma_del_sgid(struct ocrdma_dev *dev, union ib_gid *sgid)
121 bool is_vlan, u16 vlan_id)
122{ 99{
123 int found = false; 100 int found = false;
124 int i; 101 int i;
125 union ib_gid sgid;
126 unsigned long flags; 102 unsigned long flags;
127 103
128 ocrdma_build_sgid_mac(&sgid, mac_addr, is_vlan, vlan_id);
129 104
130 spin_lock_irqsave(&dev->sgid_lock, flags); 105 spin_lock_irqsave(&dev->sgid_lock, flags);
131 /* first is default sgid, which cannot be deleted. */ 106 /* first is default sgid, which cannot be deleted. */
132 for (i = 1; i < OCRDMA_MAX_SGID; i++) { 107 for (i = 1; i < OCRDMA_MAX_SGID; i++) {
133 if (!memcmp(&dev->sgid_tbl[i], &sgid, sizeof(union ib_gid))) { 108 if (!memcmp(&dev->sgid_tbl[i], sgid, sizeof(union ib_gid))) {
134 /* found matching entry */ 109 /* found matching entry */
135 memset(&dev->sgid_tbl[i], 0, sizeof(union ib_gid)); 110 memset(&dev->sgid_tbl[i], 0, sizeof(union ib_gid));
136 found = true; 111 found = true;
@@ -141,75 +116,18 @@ static bool ocrdma_del_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr,
141 return found; 116 return found;
142} 117}
143 118
144static void ocrdma_add_default_sgid(struct ocrdma_dev *dev) 119static int ocrdma_addr_event(unsigned long event, struct net_device *netdev,
145{ 120 union ib_gid *gid)
146 /* GID Index 0 - Invariant manufacturer-assigned EUI-64 */
147 union ib_gid *sgid = &dev->sgid_tbl[0];
148
149 sgid->global.subnet_prefix = cpu_to_be64(0xfe80000000000000LL);
150 ocrdma_get_guid(dev, &sgid->raw[8]);
151}
152
153#if IS_ENABLED(CONFIG_VLAN_8021Q)
154static void ocrdma_add_vlan_sgids(struct ocrdma_dev *dev)
155{
156 struct net_device *netdev, *tmp;
157 u16 vlan_id;
158 bool is_vlan;
159
160 netdev = dev->nic_info.netdev;
161
162 rcu_read_lock();
163 for_each_netdev_rcu(&init_net, tmp) {
164 if (netdev == tmp || vlan_dev_real_dev(tmp) == netdev) {
165 if (!netif_running(tmp) || !netif_oper_up(tmp))
166 continue;
167 if (netdev != tmp) {
168 vlan_id = vlan_dev_vlan_id(tmp);
169 is_vlan = true;
170 } else {
171 is_vlan = false;
172 vlan_id = 0;
173 tmp = netdev;
174 }
175 ocrdma_add_sgid(dev, tmp->dev_addr, is_vlan, vlan_id);
176 }
177 }
178 rcu_read_unlock();
179}
180#else
181static void ocrdma_add_vlan_sgids(struct ocrdma_dev *dev)
182{
183
184}
185#endif /* VLAN */
186
187static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev)
188{ 121{
189 ocrdma_add_default_sgid(dev);
190 ocrdma_add_vlan_sgids(dev);
191 return 0;
192}
193
194#if IS_ENABLED(CONFIG_IPV6)
195
196static int ocrdma_inet6addr_event(struct notifier_block *notifier,
197 unsigned long event, void *ptr)
198{
199 struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr;
200 struct net_device *netdev = ifa->idev->dev;
201 struct ib_event gid_event; 122 struct ib_event gid_event;
202 struct ocrdma_dev *dev; 123 struct ocrdma_dev *dev;
203 bool found = false; 124 bool found = false;
204 bool updated = false; 125 bool updated = false;
205 bool is_vlan = false; 126 bool is_vlan = false;
206 u16 vid = 0;
207 127
208 is_vlan = netdev->priv_flags & IFF_802_1Q_VLAN; 128 is_vlan = netdev->priv_flags & IFF_802_1Q_VLAN;
209 if (is_vlan) { 129 if (is_vlan)
210 vid = vlan_dev_vlan_id(netdev);
211 netdev = vlan_dev_real_dev(netdev); 130 netdev = vlan_dev_real_dev(netdev);
212 }
213 131
214 rcu_read_lock(); 132 rcu_read_lock();
215 list_for_each_entry_rcu(dev, &ocrdma_dev_list, entry) { 133 list_for_each_entry_rcu(dev, &ocrdma_dev_list, entry) {
@@ -222,16 +140,14 @@ static int ocrdma_inet6addr_event(struct notifier_block *notifier,
222 140
223 if (!found) 141 if (!found)
224 return NOTIFY_DONE; 142 return NOTIFY_DONE;
225 if (!rdma_link_local_addr((struct in6_addr *)&ifa->addr))
226 return NOTIFY_DONE;
227 143
228 mutex_lock(&dev->dev_lock); 144 mutex_lock(&dev->dev_lock);
229 switch (event) { 145 switch (event) {
230 case NETDEV_UP: 146 case NETDEV_UP:
231 updated = ocrdma_add_sgid(dev, netdev->dev_addr, is_vlan, vid); 147 updated = ocrdma_add_sgid(dev, gid);
232 break; 148 break;
233 case NETDEV_DOWN: 149 case NETDEV_DOWN:
234 updated = ocrdma_del_sgid(dev, netdev->dev_addr, is_vlan, vid); 150 updated = ocrdma_del_sgid(dev, gid);
235 break; 151 break;
236 default: 152 default:
237 break; 153 break;
@@ -247,6 +163,32 @@ static int ocrdma_inet6addr_event(struct notifier_block *notifier,
247 return NOTIFY_OK; 163 return NOTIFY_OK;
248} 164}
249 165
166static int ocrdma_inetaddr_event(struct notifier_block *notifier,
167 unsigned long event, void *ptr)
168{
169 struct in_ifaddr *ifa = ptr;
170 union ib_gid gid;
171 struct net_device *netdev = ifa->ifa_dev->dev;
172
173 ipv6_addr_set_v4mapped(ifa->ifa_address, (struct in6_addr *)&gid);
174 return ocrdma_addr_event(event, netdev, &gid);
175}
176
177static struct notifier_block ocrdma_inetaddr_notifier = {
178 .notifier_call = ocrdma_inetaddr_event
179};
180
181#if IS_ENABLED(CONFIG_IPV6)
182
183static int ocrdma_inet6addr_event(struct notifier_block *notifier,
184 unsigned long event, void *ptr)
185{
186 struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr;
187 union ib_gid *gid = (union ib_gid *)&ifa->addr;
188 struct net_device *netdev = ifa->idev->dev;
189 return ocrdma_addr_event(event, netdev, gid);
190}
191
250static struct notifier_block ocrdma_inet6addr_notifier = { 192static struct notifier_block ocrdma_inet6addr_notifier = {
251 .notifier_call = ocrdma_inet6addr_event 193 .notifier_call = ocrdma_inet6addr_event
252}; 194};
@@ -423,10 +365,6 @@ static struct ocrdma_dev *ocrdma_add(struct be_dev_info *dev_info)
423 if (status) 365 if (status)
424 goto alloc_err; 366 goto alloc_err;
425 367
426 status = ocrdma_build_sgid_tbl(dev);
427 if (status)
428 goto alloc_err;
429
430 status = ocrdma_register_device(dev); 368 status = ocrdma_register_device(dev);
431 if (status) 369 if (status)
432 goto alloc_err; 370 goto alloc_err;
@@ -553,6 +491,10 @@ static int __init ocrdma_init_module(void)
553{ 491{
554 int status; 492 int status;
555 493
494 status = register_inetaddr_notifier(&ocrdma_inetaddr_notifier);
495 if (status)
496 return status;
497
556#if IS_ENABLED(CONFIG_IPV6) 498#if IS_ENABLED(CONFIG_IPV6)
557 status = register_inet6addr_notifier(&ocrdma_inet6addr_notifier); 499 status = register_inet6addr_notifier(&ocrdma_inet6addr_notifier);
558 if (status) 500 if (status)
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
index 9f9570ec3c2e..60d5ac23ea80 100644
--- a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
+++ b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
@@ -31,7 +31,7 @@
31#define Bit(_b) (1 << (_b)) 31#define Bit(_b) (1 << (_b))
32 32
33#define OCRDMA_GEN1_FAMILY 0xB 33#define OCRDMA_GEN1_FAMILY 0xB
34#define OCRDMA_GEN2_FAMILY 0x2 34#define OCRDMA_GEN2_FAMILY 0x0F
35 35
36#define OCRDMA_SUBSYS_ROCE 10 36#define OCRDMA_SUBSYS_ROCE 10
37enum { 37enum {
@@ -1694,7 +1694,7 @@ struct ocrdma_grh {
1694 u16 rsvd; 1694 u16 rsvd;
1695} __packed; 1695} __packed;
1696 1696
1697#define OCRDMA_AV_VALID Bit(0) 1697#define OCRDMA_AV_VALID Bit(7)
1698#define OCRDMA_AV_VLAN_VALID Bit(1) 1698#define OCRDMA_AV_VLAN_VALID Bit(1)
1699 1699
1700struct ocrdma_av { 1700struct ocrdma_av {
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
index 7686dceadd29..aa92f40c9d50 100644
--- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
@@ -1326,7 +1326,8 @@ int ocrdma_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
1326 new_qps = old_qps; 1326 new_qps = old_qps;
1327 spin_unlock_irqrestore(&qp->q_lock, flags); 1327 spin_unlock_irqrestore(&qp->q_lock, flags);
1328 1328
1329 if (!ib_modify_qp_is_ok(old_qps, new_qps, ibqp->qp_type, attr_mask)) { 1329 if (!ib_modify_qp_is_ok(old_qps, new_qps, ibqp->qp_type, attr_mask,
1330 IB_LINK_LAYER_ETHERNET)) {
1330 pr_err("%s(%d) invalid attribute mask=0x%x specified for\n" 1331 pr_err("%s(%d) invalid attribute mask=0x%x specified for\n"
1331 "qpn=0x%x of type=0x%x old_qps=0x%x, new_qps=0x%x\n", 1332 "qpn=0x%x of type=0x%x old_qps=0x%x, new_qps=0x%x\n",
1332 __func__, dev->id, attr_mask, qp->id, ibqp->qp_type, 1333 __func__, dev->id, attr_mask, qp->id, ibqp->qp_type,
diff --git a/drivers/infiniband/hw/qib/qib_qp.c b/drivers/infiniband/hw/qib/qib_qp.c
index 3cca55b51e54..0cad0c40d742 100644
--- a/drivers/infiniband/hw/qib/qib_qp.c
+++ b/drivers/infiniband/hw/qib/qib_qp.c
@@ -585,7 +585,7 @@ int qib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
585 new_state = attr_mask & IB_QP_STATE ? attr->qp_state : cur_state; 585 new_state = attr_mask & IB_QP_STATE ? attr->qp_state : cur_state;
586 586
587 if (!ib_modify_qp_is_ok(cur_state, new_state, ibqp->qp_type, 587 if (!ib_modify_qp_is_ok(cur_state, new_state, ibqp->qp_type,
588 attr_mask)) 588 attr_mask, IB_LINK_LAYER_UNSPECIFIED))
589 goto inval; 589 goto inval;
590 590
591 if (attr_mask & IB_QP_AV) { 591 if (attr_mask & IB_QP_AV) {
diff --git a/drivers/infiniband/hw/qib/qib_ud.c b/drivers/infiniband/hw/qib/qib_ud.c
index d6c7fe7f88d5..3ad651c3356c 100644
--- a/drivers/infiniband/hw/qib/qib_ud.c
+++ b/drivers/infiniband/hw/qib/qib_ud.c
@@ -57,13 +57,20 @@ static void qib_ud_loopback(struct qib_qp *sqp, struct qib_swqe *swqe)
57 struct qib_sge *sge; 57 struct qib_sge *sge;
58 struct ib_wc wc; 58 struct ib_wc wc;
59 u32 length; 59 u32 length;
60 enum ib_qp_type sqptype, dqptype;
60 61
61 qp = qib_lookup_qpn(ibp, swqe->wr.wr.ud.remote_qpn); 62 qp = qib_lookup_qpn(ibp, swqe->wr.wr.ud.remote_qpn);
62 if (!qp) { 63 if (!qp) {
63 ibp->n_pkt_drops++; 64 ibp->n_pkt_drops++;
64 return; 65 return;
65 } 66 }
66 if (qp->ibqp.qp_type != sqp->ibqp.qp_type || 67
68 sqptype = sqp->ibqp.qp_type == IB_QPT_GSI ?
69 IB_QPT_UD : sqp->ibqp.qp_type;
70 dqptype = qp->ibqp.qp_type == IB_QPT_GSI ?
71 IB_QPT_UD : qp->ibqp.qp_type;
72
73 if (dqptype != sqptype ||
67 !(ib_qib_state_ops[qp->state] & QIB_PROCESS_RECV_OK)) { 74 !(ib_qib_state_ops[qp->state] & QIB_PROCESS_RECV_OK)) {
68 ibp->n_pkt_drops++; 75 ibp->n_pkt_drops++;
69 goto drop; 76 goto drop;
diff --git a/drivers/infiniband/hw/usnic/Kconfig b/drivers/infiniband/hw/usnic/Kconfig
new file mode 100644
index 000000000000..29ab11c34f3f
--- /dev/null
+++ b/drivers/infiniband/hw/usnic/Kconfig
@@ -0,0 +1,10 @@
1config INFINIBAND_USNIC
2 tristate "Verbs support for Cisco VIC"
3 depends on NETDEVICES && ETHERNET && INET && PCI && INTEL_IOMMU
4 select ENIC
5 select NET_VENDOR_CISCO
6 select PCI_IOV
7 select INFINIBAND_USER_ACCESS
8 ---help---
9 This is a low-level driver for Cisco's Virtual Interface
10 Cards (VICs), including the VIC 1240 and 1280 cards.
diff --git a/drivers/infiniband/hw/usnic/Makefile b/drivers/infiniband/hw/usnic/Makefile
new file mode 100644
index 000000000000..99fb2db47cd5
--- /dev/null
+++ b/drivers/infiniband/hw/usnic/Makefile
@@ -0,0 +1,15 @@
1ccflags-y := -Idrivers/net/ethernet/cisco/enic
2
3obj-$(CONFIG_INFINIBAND_USNIC)+= usnic_verbs.o
4
5usnic_verbs-y=\
6usnic_fwd.o \
7usnic_transport.o \
8usnic_uiom.o \
9usnic_uiom_interval_tree.o \
10usnic_vnic.o \
11usnic_ib_main.o \
12usnic_ib_qp_grp.o \
13usnic_ib_sysfs.o \
14usnic_ib_verbs.o \
15usnic_debugfs.o \
diff --git a/drivers/infiniband/hw/usnic/usnic.h b/drivers/infiniband/hw/usnic/usnic.h
new file mode 100644
index 000000000000..5be13d8991bc
--- /dev/null
+++ b/drivers/infiniband/hw/usnic/usnic.h
@@ -0,0 +1,29 @@
1/*
2 * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
3 *
4 * This program is free software; you may redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
15 * SOFTWARE.
16 *
17 */
18
19#ifndef USNIC_H_
20#define USNIC_H_
21
22#define DRV_NAME "usnic_verbs"
23
24#define PCI_DEVICE_ID_CISCO_VIC_USPACE_NIC 0x00cf /* User space NIC */
25
26#define DRV_VERSION "1.0.3"
27#define DRV_RELDATE "December 19, 2013"
28
29#endif /* USNIC_H_ */
diff --git a/drivers/infiniband/hw/usnic/usnic_abi.h b/drivers/infiniband/hw/usnic/usnic_abi.h
new file mode 100644
index 000000000000..04a66229584e
--- /dev/null
+++ b/drivers/infiniband/hw/usnic/usnic_abi.h
@@ -0,0 +1,73 @@
1/*
2 * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
3 *
4 * This program is free software; you may redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
15 * SOFTWARE.
16 *
17 */
18
19
20#ifndef USNIC_ABI_H
21#define USNIC_ABI_H
22
23/* ABI between userspace and kernel */
24#define USNIC_UVERBS_ABI_VERSION 4
25
26#define USNIC_QP_GRP_MAX_WQS 8
27#define USNIC_QP_GRP_MAX_RQS 8
28#define USNIC_QP_GRP_MAX_CQS 16
29
30enum usnic_transport_type {
31 USNIC_TRANSPORT_UNKNOWN = 0,
32 USNIC_TRANSPORT_ROCE_CUSTOM = 1,
33 USNIC_TRANSPORT_IPV4_UDP = 2,
34 USNIC_TRANSPORT_MAX = 3,
35};
36
37struct usnic_transport_spec {
38 enum usnic_transport_type trans_type;
39 union {
40 struct {
41 uint16_t port_num;
42 } usnic_roce;
43 struct {
44 uint32_t sock_fd;
45 } udp;
46 };
47};
48
49struct usnic_ib_create_qp_cmd {
50 struct usnic_transport_spec spec;
51};
52
53/*TODO: Future - usnic_modify_qp needs to pass in generic filters */
54struct usnic_ib_create_qp_resp {
55 u32 vfid;
56 u32 qp_grp_id;
57 u64 bar_bus_addr;
58 u32 bar_len;
59/*
60 * WQ, RQ, CQ are explicity specified bc exposing a generic resources inteface
61 * expands the scope of ABI to many files.
62 */
63 u32 wq_cnt;
64 u32 rq_cnt;
65 u32 cq_cnt;
66 u32 wq_idx[USNIC_QP_GRP_MAX_WQS];
67 u32 rq_idx[USNIC_QP_GRP_MAX_RQS];
68 u32 cq_idx[USNIC_QP_GRP_MAX_CQS];
69 u32 transport;
70 u32 reserved[9];
71};
72
73#endif /* USNIC_ABI_H */
diff --git a/drivers/infiniband/hw/usnic/usnic_common_pkt_hdr.h b/drivers/infiniband/hw/usnic/usnic_common_pkt_hdr.h
new file mode 100644
index 000000000000..393567266142
--- /dev/null
+++ b/drivers/infiniband/hw/usnic/usnic_common_pkt_hdr.h
@@ -0,0 +1,27 @@
1/*
2 * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
3 *
4 * This program is free software; you may redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
15 * SOFTWARE.
16 *
17 */
18
19#ifndef USNIC_CMN_PKT_HDR_H
20#define USNIC_CMN_PKT_HDR_H
21
22#define USNIC_ROCE_ETHERTYPE (0x8915)
23#define USNIC_ROCE_GRH_VER (8)
24#define USNIC_PROTO_VER (1)
25#define USNIC_ROCE_GRH_VER_SHIFT (4)
26
27#endif /* USNIC_COMMON_PKT_HDR_H */
diff --git a/drivers/infiniband/hw/usnic/usnic_common_util.h b/drivers/infiniband/hw/usnic/usnic_common_util.h
new file mode 100644
index 000000000000..9d737ed5e55d
--- /dev/null
+++ b/drivers/infiniband/hw/usnic/usnic_common_util.h
@@ -0,0 +1,68 @@
1/*
2 * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
3 *
4 * This program is free software; you may redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
15 * SOFTWARE.
16 *
17 */
18
19#ifndef USNIC_CMN_UTIL_H
20#define USNIC_CMN_UTIL_H
21
22static inline void
23usnic_mac_to_gid(const char *const mac, char *raw_gid)
24{
25 raw_gid[0] = 0xfe;
26 raw_gid[1] = 0x80;
27 memset(&raw_gid[2], 0, 6);
28 raw_gid[8] = mac[0]^2;
29 raw_gid[9] = mac[1];
30 raw_gid[10] = mac[2];
31 raw_gid[11] = 0xff;
32 raw_gid[12] = 0xfe;
33 raw_gid[13] = mac[3];
34 raw_gid[14] = mac[4];
35 raw_gid[15] = mac[5];
36}
37
38static inline void
39usnic_mac_ip_to_gid(const char *const mac, const __be32 inaddr, char *raw_gid)
40{
41 raw_gid[0] = 0xfe;
42 raw_gid[1] = 0x80;
43 memset(&raw_gid[2], 0, 2);
44 memcpy(&raw_gid[4], &inaddr, 4);
45 raw_gid[8] = mac[0]^2;
46 raw_gid[9] = mac[1];
47 raw_gid[10] = mac[2];
48 raw_gid[11] = 0xff;
49 raw_gid[12] = 0xfe;
50 raw_gid[13] = mac[3];
51 raw_gid[14] = mac[4];
52 raw_gid[15] = mac[5];
53}
54
55static inline void
56usnic_write_gid_if_id_from_mac(char *mac, char *raw_gid)
57{
58 raw_gid[8] = mac[0]^2;
59 raw_gid[9] = mac[1];
60 raw_gid[10] = mac[2];
61 raw_gid[11] = 0xff;
62 raw_gid[12] = 0xfe;
63 raw_gid[13] = mac[3];
64 raw_gid[14] = mac[4];
65 raw_gid[15] = mac[5];
66}
67
68#endif /* USNIC_COMMON_UTIL_H */
diff --git a/drivers/infiniband/hw/usnic/usnic_debugfs.c b/drivers/infiniband/hw/usnic/usnic_debugfs.c
new file mode 100644
index 000000000000..5d13860161a4
--- /dev/null
+++ b/drivers/infiniband/hw/usnic/usnic_debugfs.c
@@ -0,0 +1,154 @@
1/*
2 * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
3 *
4 * This program is free software; you may redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
15 * SOFTWARE.
16 *
17 */
18
19#include <linux/debugfs.h>
20#include <linux/module.h>
21
22#include "usnic.h"
23#include "usnic_log.h"
24#include "usnic_debugfs.h"
25#include "usnic_ib_qp_grp.h"
26#include "usnic_transport.h"
27
28static struct dentry *debugfs_root;
29static struct dentry *flows_dentry;
30
31static ssize_t usnic_debugfs_buildinfo_read(struct file *f, char __user *data,
32 size_t count, loff_t *ppos)
33{
34 char buf[500];
35 int res;
36
37 if (*ppos > 0)
38 return 0;
39
40 res = scnprintf(buf, sizeof(buf),
41 "version: %s\n"
42 "build date: %s\n",
43 DRV_VERSION, DRV_RELDATE);
44
45 return simple_read_from_buffer(data, count, ppos, buf, res);
46}
47
48static const struct file_operations usnic_debugfs_buildinfo_ops = {
49 .owner = THIS_MODULE,
50 .open = simple_open,
51 .read = usnic_debugfs_buildinfo_read
52};
53
54static ssize_t flowinfo_read(struct file *f, char __user *data,
55 size_t count, loff_t *ppos)
56{
57 struct usnic_ib_qp_grp_flow *qp_flow;
58 int n;
59 int left;
60 char *ptr;
61 char buf[512];
62
63 qp_flow = f->private_data;
64 ptr = buf;
65 left = count;
66
67 if (*ppos > 0)
68 return 0;
69
70 spin_lock(&qp_flow->qp_grp->lock);
71 n = scnprintf(ptr, left,
72 "QP Grp ID: %d Transport: %s ",
73 qp_flow->qp_grp->grp_id,
74 usnic_transport_to_str(qp_flow->trans_type));
75 UPDATE_PTR_LEFT(n, ptr, left);
76 if (qp_flow->trans_type == USNIC_TRANSPORT_ROCE_CUSTOM) {
77 n = scnprintf(ptr, left, "Port_Num:%hu\n",
78 qp_flow->usnic_roce.port_num);
79 UPDATE_PTR_LEFT(n, ptr, left);
80 } else if (qp_flow->trans_type == USNIC_TRANSPORT_IPV4_UDP) {
81 n = usnic_transport_sock_to_str(ptr, left,
82 qp_flow->udp.sock);
83 UPDATE_PTR_LEFT(n, ptr, left);
84 n = scnprintf(ptr, left, "\n");
85 UPDATE_PTR_LEFT(n, ptr, left);
86 }
87 spin_unlock(&qp_flow->qp_grp->lock);
88
89 return simple_read_from_buffer(data, count, ppos, buf, ptr - buf);
90}
91
92static const struct file_operations flowinfo_ops = {
93 .owner = THIS_MODULE,
94 .open = simple_open,
95 .read = flowinfo_read,
96};
97
98void usnic_debugfs_init(void)
99{
100 debugfs_root = debugfs_create_dir(DRV_NAME, NULL);
101 if (IS_ERR(debugfs_root)) {
102 usnic_err("Failed to create debugfs root dir, check if debugfs is enabled in kernel configuration\n");
103 goto out_clear_root;
104 }
105
106 flows_dentry = debugfs_create_dir("flows", debugfs_root);
107 if (IS_ERR_OR_NULL(flows_dentry)) {
108 usnic_err("Failed to create debugfs flow dir with err %ld\n",
109 PTR_ERR(flows_dentry));
110 goto out_free_root;
111 }
112
113 debugfs_create_file("build-info", S_IRUGO, debugfs_root,
114 NULL, &usnic_debugfs_buildinfo_ops);
115 return;
116
117out_free_root:
118 debugfs_remove_recursive(debugfs_root);
119out_clear_root:
120 debugfs_root = NULL;
121}
122
123void usnic_debugfs_exit(void)
124{
125 if (!debugfs_root)
126 return;
127
128 debugfs_remove_recursive(debugfs_root);
129 debugfs_root = NULL;
130}
131
132void usnic_debugfs_flow_add(struct usnic_ib_qp_grp_flow *qp_flow)
133{
134 if (IS_ERR_OR_NULL(flows_dentry))
135 return;
136
137 scnprintf(qp_flow->dentry_name, sizeof(qp_flow->dentry_name),
138 "%u", qp_flow->flow->flow_id);
139 qp_flow->dbgfs_dentry = debugfs_create_file(qp_flow->dentry_name,
140 S_IRUGO,
141 flows_dentry,
142 qp_flow,
143 &flowinfo_ops);
144 if (IS_ERR_OR_NULL(qp_flow->dbgfs_dentry)) {
145 usnic_err("Failed to create dbg fs entry for flow %u\n",
146 qp_flow->flow->flow_id);
147 }
148}
149
150void usnic_debugfs_flow_remove(struct usnic_ib_qp_grp_flow *qp_flow)
151{
152 if (!IS_ERR_OR_NULL(qp_flow->dbgfs_dentry))
153 debugfs_remove(qp_flow->dbgfs_dentry);
154}
diff --git a/drivers/infiniband/hw/usnic/usnic_debugfs.h b/drivers/infiniband/hw/usnic/usnic_debugfs.h
new file mode 100644
index 000000000000..4087d24a88f6
--- /dev/null
+++ b/drivers/infiniband/hw/usnic/usnic_debugfs.h
@@ -0,0 +1,29 @@
1/*
2 * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
3 *
4 * This program is free software; you may redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
15 * SOFTWARE.
16 *
17 */
18#ifndef USNIC_DEBUGFS_H_
19#define USNIC_DEBUGFS_H_
20
21#include "usnic_ib_qp_grp.h"
22
23void usnic_debugfs_init(void);
24
25void usnic_debugfs_exit(void);
26void usnic_debugfs_flow_add(struct usnic_ib_qp_grp_flow *qp_flow);
27void usnic_debugfs_flow_remove(struct usnic_ib_qp_grp_flow *qp_flow);
28
29#endif /*!USNIC_DEBUGFS_H_ */
diff --git a/drivers/infiniband/hw/usnic/usnic_fwd.c b/drivers/infiniband/hw/usnic/usnic_fwd.c
new file mode 100644
index 000000000000..e3c9bd9d3ba3
--- /dev/null
+++ b/drivers/infiniband/hw/usnic/usnic_fwd.c
@@ -0,0 +1,350 @@
1/*
2 * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
3 *
4 * This program is free software; you may redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
15 * SOFTWARE.
16 *
17 */
18#include <linux/netdevice.h>
19#include <linux/pci.h>
20
21#include "enic_api.h"
22#include "usnic_common_pkt_hdr.h"
23#include "usnic_fwd.h"
24#include "usnic_log.h"
25
26static int usnic_fwd_devcmd_locked(struct usnic_fwd_dev *ufdev, int vnic_idx,
27 enum vnic_devcmd_cmd cmd, u64 *a0,
28 u64 *a1)
29{
30 int status;
31 struct net_device *netdev = ufdev->netdev;
32
33 lockdep_assert_held(&ufdev->lock);
34
35 status = enic_api_devcmd_proxy_by_index(netdev,
36 vnic_idx,
37 cmd,
38 a0, a1,
39 1000);
40 if (status) {
41 if (status == ERR_EINVAL && cmd == CMD_DEL_FILTER) {
42 usnic_dbg("Dev %s vnic idx %u cmd %u already deleted",
43 ufdev->name, vnic_idx, cmd);
44 } else {
45 usnic_err("Dev %s vnic idx %u cmd %u failed with status %d\n",
46 ufdev->name, vnic_idx, cmd,
47 status);
48 }
49 } else {
50 usnic_dbg("Dev %s vnic idx %u cmd %u success",
51 ufdev->name, vnic_idx, cmd);
52 }
53
54 return status;
55}
56
57static int usnic_fwd_devcmd(struct usnic_fwd_dev *ufdev, int vnic_idx,
58 enum vnic_devcmd_cmd cmd, u64 *a0, u64 *a1)
59{
60 int status;
61
62 spin_lock(&ufdev->lock);
63 status = usnic_fwd_devcmd_locked(ufdev, vnic_idx, cmd, a0, a1);
64 spin_unlock(&ufdev->lock);
65
66 return status;
67}
68
69struct usnic_fwd_dev *usnic_fwd_dev_alloc(struct pci_dev *pdev)
70{
71 struct usnic_fwd_dev *ufdev;
72
73 ufdev = kzalloc(sizeof(*ufdev), GFP_KERNEL);
74 if (!ufdev)
75 return NULL;
76
77 ufdev->pdev = pdev;
78 ufdev->netdev = pci_get_drvdata(pdev);
79 spin_lock_init(&ufdev->lock);
80 strncpy(ufdev->name, netdev_name(ufdev->netdev),
81 sizeof(ufdev->name) - 1);
82
83 return ufdev;
84}
85
86void usnic_fwd_dev_free(struct usnic_fwd_dev *ufdev)
87{
88 kfree(ufdev);
89}
90
91void usnic_fwd_set_mac(struct usnic_fwd_dev *ufdev, char mac[ETH_ALEN])
92{
93 spin_lock(&ufdev->lock);
94 memcpy(&ufdev->mac, mac, sizeof(ufdev->mac));
95 spin_unlock(&ufdev->lock);
96}
97
98int usnic_fwd_add_ipaddr(struct usnic_fwd_dev *ufdev, __be32 inaddr)
99{
100 int status;
101
102 spin_lock(&ufdev->lock);
103 if (ufdev->inaddr == 0) {
104 ufdev->inaddr = inaddr;
105 status = 0;
106 } else {
107 status = -EFAULT;
108 }
109 spin_unlock(&ufdev->lock);
110
111 return status;
112}
113
114void usnic_fwd_del_ipaddr(struct usnic_fwd_dev *ufdev)
115{
116 spin_lock(&ufdev->lock);
117 ufdev->inaddr = 0;
118 spin_unlock(&ufdev->lock);
119}
120
121void usnic_fwd_carrier_up(struct usnic_fwd_dev *ufdev)
122{
123 spin_lock(&ufdev->lock);
124 ufdev->link_up = 1;
125 spin_unlock(&ufdev->lock);
126}
127
128void usnic_fwd_carrier_down(struct usnic_fwd_dev *ufdev)
129{
130 spin_lock(&ufdev->lock);
131 ufdev->link_up = 0;
132 spin_unlock(&ufdev->lock);
133}
134
135void usnic_fwd_set_mtu(struct usnic_fwd_dev *ufdev, unsigned int mtu)
136{
137 spin_lock(&ufdev->lock);
138 ufdev->mtu = mtu;
139 spin_unlock(&ufdev->lock);
140}
141
142static int usnic_fwd_dev_ready_locked(struct usnic_fwd_dev *ufdev)
143{
144 lockdep_assert_held(&ufdev->lock);
145
146 if (!ufdev->link_up)
147 return -EPERM;
148
149 return 0;
150}
151
152static int validate_filter_locked(struct usnic_fwd_dev *ufdev,
153 struct filter *filter)
154{
155
156 lockdep_assert_held(&ufdev->lock);
157
158 if (filter->type == FILTER_IPV4_5TUPLE) {
159 if (!(filter->u.ipv4.flags & FILTER_FIELD_5TUP_DST_AD))
160 return -EACCES;
161 if (!(filter->u.ipv4.flags & FILTER_FIELD_5TUP_DST_PT))
162 return -EBUSY;
163 else if (ufdev->inaddr == 0)
164 return -EINVAL;
165 else if (filter->u.ipv4.dst_port == 0)
166 return -ERANGE;
167 else if (ntohl(ufdev->inaddr) != filter->u.ipv4.dst_addr)
168 return -EFAULT;
169 else
170 return 0;
171 }
172
173 return 0;
174}
175
176static void fill_tlv(struct filter_tlv *tlv, struct filter *filter,
177 struct filter_action *action)
178{
179 tlv->type = CLSF_TLV_FILTER;
180 tlv->length = sizeof(struct filter);
181 *((struct filter *)&tlv->val) = *filter;
182
183 tlv = (struct filter_tlv *)((char *)tlv + sizeof(struct filter_tlv) +
184 sizeof(struct filter));
185 tlv->type = CLSF_TLV_ACTION;
186 tlv->length = sizeof(struct filter_action);
187 *((struct filter_action *)&tlv->val) = *action;
188}
189
190struct usnic_fwd_flow*
191usnic_fwd_alloc_flow(struct usnic_fwd_dev *ufdev, struct filter *filter,
192 struct usnic_filter_action *uaction)
193{
194 struct filter_tlv *tlv;
195 struct pci_dev *pdev;
196 struct usnic_fwd_flow *flow;
197 uint64_t a0, a1;
198 uint64_t tlv_size;
199 dma_addr_t tlv_pa;
200 int status;
201
202 pdev = ufdev->pdev;
203 tlv_size = (2*sizeof(struct filter_tlv) + sizeof(struct filter) +
204 sizeof(struct filter_action));
205
206 flow = kzalloc(sizeof(*flow), GFP_ATOMIC);
207 if (!flow)
208 return ERR_PTR(-ENOMEM);
209
210 tlv = pci_alloc_consistent(pdev, tlv_size, &tlv_pa);
211 if (!tlv) {
212 usnic_err("Failed to allocate memory\n");
213 status = -ENOMEM;
214 goto out_free_flow;
215 }
216
217 fill_tlv(tlv, filter, &uaction->action);
218
219 spin_lock(&ufdev->lock);
220 status = usnic_fwd_dev_ready_locked(ufdev);
221 if (status) {
222 usnic_err("Forwarding dev %s not ready with status %d\n",
223 ufdev->name, status);
224 goto out_free_tlv;
225 }
226
227 status = validate_filter_locked(ufdev, filter);
228 if (status) {
229 usnic_err("Failed to validate filter with status %d\n",
230 status);
231 goto out_free_tlv;
232 }
233
234 /* Issue Devcmd */
235 a0 = tlv_pa;
236 a1 = tlv_size;
237 status = usnic_fwd_devcmd_locked(ufdev, uaction->vnic_idx,
238 CMD_ADD_FILTER, &a0, &a1);
239 if (status) {
240 usnic_err("VF %s Filter add failed with status:%d",
241 ufdev->name, status);
242 status = -EFAULT;
243 goto out_free_tlv;
244 } else {
245 usnic_dbg("VF %s FILTER ID:%llu", ufdev->name, a0);
246 }
247
248 flow->flow_id = (uint32_t) a0;
249 flow->vnic_idx = uaction->vnic_idx;
250 flow->ufdev = ufdev;
251
252out_free_tlv:
253 spin_unlock(&ufdev->lock);
254 pci_free_consistent(pdev, tlv_size, tlv, tlv_pa);
255 if (!status)
256 return flow;
257out_free_flow:
258 kfree(flow);
259 return ERR_PTR(status);
260}
261
262int usnic_fwd_dealloc_flow(struct usnic_fwd_flow *flow)
263{
264 int status;
265 u64 a0, a1;
266
267 a0 = flow->flow_id;
268
269 status = usnic_fwd_devcmd(flow->ufdev, flow->vnic_idx,
270 CMD_DEL_FILTER, &a0, &a1);
271 if (status) {
272 if (status == ERR_EINVAL) {
273 usnic_dbg("Filter %u already deleted for VF Idx %u pf: %s status: %d",
274 flow->flow_id, flow->vnic_idx,
275 flow->ufdev->name, status);
276 } else {
277 usnic_err("PF %s VF Idx %u Filter: %u FILTER DELETE failed with status %d",
278 flow->ufdev->name, flow->vnic_idx,
279 flow->flow_id, status);
280 }
281 status = 0;
282 /*
283 * Log the error and fake success to the caller because if
284 * a flow fails to be deleted in the firmware, it is an
285 * unrecoverable error.
286 */
287 } else {
288 usnic_dbg("PF %s VF Idx %u Filter: %u FILTER DELETED",
289 flow->ufdev->name, flow->vnic_idx,
290 flow->flow_id);
291 }
292
293 kfree(flow);
294 return status;
295}
296
297int usnic_fwd_enable_qp(struct usnic_fwd_dev *ufdev, int vnic_idx, int qp_idx)
298{
299 int status;
300 struct net_device *pf_netdev;
301 u64 a0, a1;
302
303 pf_netdev = ufdev->netdev;
304 a0 = qp_idx;
305 a1 = CMD_QP_RQWQ;
306
307 status = usnic_fwd_devcmd(ufdev, vnic_idx, CMD_QP_ENABLE,
308 &a0, &a1);
309 if (status) {
310 usnic_err("PF %s VNIC Index %u RQ Index: %u ENABLE Failed with status %d",
311 netdev_name(pf_netdev),
312 vnic_idx,
313 qp_idx,
314 status);
315 } else {
316 usnic_dbg("PF %s VNIC Index %u RQ Index: %u ENABLED",
317 netdev_name(pf_netdev),
318 vnic_idx, qp_idx);
319 }
320
321 return status;
322}
323
324int usnic_fwd_disable_qp(struct usnic_fwd_dev *ufdev, int vnic_idx, int qp_idx)
325{
326 int status;
327 u64 a0, a1;
328 struct net_device *pf_netdev;
329
330 pf_netdev = ufdev->netdev;
331 a0 = qp_idx;
332 a1 = CMD_QP_RQWQ;
333
334 status = usnic_fwd_devcmd(ufdev, vnic_idx, CMD_QP_DISABLE,
335 &a0, &a1);
336 if (status) {
337 usnic_err("PF %s VNIC Index %u RQ Index: %u DISABLE Failed with status %d",
338 netdev_name(pf_netdev),
339 vnic_idx,
340 qp_idx,
341 status);
342 } else {
343 usnic_dbg("PF %s VNIC Index %u RQ Index: %u DISABLED",
344 netdev_name(pf_netdev),
345 vnic_idx,
346 qp_idx);
347 }
348
349 return status;
350}
diff --git a/drivers/infiniband/hw/usnic/usnic_fwd.h b/drivers/infiniband/hw/usnic/usnic_fwd.h
new file mode 100644
index 000000000000..93713a2230b3
--- /dev/null
+++ b/drivers/infiniband/hw/usnic/usnic_fwd.h
@@ -0,0 +1,113 @@
1/*
2 * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
3 *
4 * This program is free software; you may redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
15 * SOFTWARE.
16 *
17 */
18
19#ifndef USNIC_FWD_H_
20#define USNIC_FWD_H_
21
22#include <linux/if.h>
23#include <linux/netdevice.h>
24#include <linux/pci.h>
25#include <linux/in.h>
26
27#include "usnic_abi.h"
28#include "usnic_common_pkt_hdr.h"
29#include "vnic_devcmd.h"
30
31struct usnic_fwd_dev {
32 struct pci_dev *pdev;
33 struct net_device *netdev;
34 spinlock_t lock;
35 /*
36 * The following fields can be read directly off the device.
37 * However, they should be set by a accessor function, except name,
38 * which cannot be changed.
39 */
40 bool link_up;
41 char mac[ETH_ALEN];
42 unsigned int mtu;
43 __be32 inaddr;
44 char name[IFNAMSIZ+1];
45};
46
47struct usnic_fwd_flow {
48 uint32_t flow_id;
49 struct usnic_fwd_dev *ufdev;
50 unsigned int vnic_idx;
51};
52
53struct usnic_filter_action {
54 int vnic_idx;
55 struct filter_action action;
56};
57
58struct usnic_fwd_dev *usnic_fwd_dev_alloc(struct pci_dev *pdev);
59void usnic_fwd_dev_free(struct usnic_fwd_dev *ufdev);
60
61void usnic_fwd_set_mac(struct usnic_fwd_dev *ufdev, char mac[ETH_ALEN]);
62int usnic_fwd_add_ipaddr(struct usnic_fwd_dev *ufdev, __be32 inaddr);
63void usnic_fwd_del_ipaddr(struct usnic_fwd_dev *ufdev);
64void usnic_fwd_carrier_up(struct usnic_fwd_dev *ufdev);
65void usnic_fwd_carrier_down(struct usnic_fwd_dev *ufdev);
66void usnic_fwd_set_mtu(struct usnic_fwd_dev *ufdev, unsigned int mtu);
67
68/*
69 * Allocate a flow on this forwarding device. Whoever calls this function,
70 * must monitor netdev events on ufdev's netdevice. If NETDEV_REBOOT or
71 * NETDEV_DOWN is seen, flow will no longer function and must be
72 * immediately freed by calling usnic_dealloc_flow.
73 */
74struct usnic_fwd_flow*
75usnic_fwd_alloc_flow(struct usnic_fwd_dev *ufdev, struct filter *filter,
76 struct usnic_filter_action *action);
77int usnic_fwd_dealloc_flow(struct usnic_fwd_flow *flow);
78int usnic_fwd_enable_qp(struct usnic_fwd_dev *ufdev, int vnic_idx, int qp_idx);
79int usnic_fwd_disable_qp(struct usnic_fwd_dev *ufdev, int vnic_idx, int qp_idx);
80
81static inline void usnic_fwd_init_usnic_filter(struct filter *filter,
82 uint32_t usnic_id)
83{
84 filter->type = FILTER_USNIC_ID;
85 filter->u.usnic.ethtype = USNIC_ROCE_ETHERTYPE;
86 filter->u.usnic.flags = FILTER_FIELD_USNIC_ETHTYPE |
87 FILTER_FIELD_USNIC_ID |
88 FILTER_FIELD_USNIC_PROTO;
89 filter->u.usnic.proto_version = (USNIC_ROCE_GRH_VER <<
90 USNIC_ROCE_GRH_VER_SHIFT) |
91 USNIC_PROTO_VER;
92 filter->u.usnic.usnic_id = usnic_id;
93}
94
95static inline void usnic_fwd_init_udp_filter(struct filter *filter,
96 uint32_t daddr, uint16_t dport)
97{
98 filter->type = FILTER_IPV4_5TUPLE;
99 filter->u.ipv4.flags = FILTER_FIELD_5TUP_PROTO;
100 filter->u.ipv4.protocol = PROTO_UDP;
101
102 if (daddr) {
103 filter->u.ipv4.flags |= FILTER_FIELD_5TUP_DST_AD;
104 filter->u.ipv4.dst_addr = daddr;
105 }
106
107 if (dport) {
108 filter->u.ipv4.flags |= FILTER_FIELD_5TUP_DST_PT;
109 filter->u.ipv4.dst_port = dport;
110 }
111}
112
113#endif /* !USNIC_FWD_H_ */
diff --git a/drivers/infiniband/hw/usnic/usnic_ib.h b/drivers/infiniband/hw/usnic/usnic_ib.h
new file mode 100644
index 000000000000..e5a9297dd1bd
--- /dev/null
+++ b/drivers/infiniband/hw/usnic/usnic_ib.h
@@ -0,0 +1,118 @@
1/*
2 * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
3 *
4 * This program is free software; you may redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
15 * SOFTWARE.
16 *
17 */
18
19#ifndef USNIC_IB_H_
20#define USNIC_IB_H_
21
22#include <linux/iommu.h>
23#include <linux/netdevice.h>
24
25#include <rdma/ib_verbs.h>
26
27
28#include "usnic.h"
29#include "usnic_abi.h"
30#include "usnic_vnic.h"
31
32#define USNIC_IB_PORT_CNT 1
33#define USNIC_IB_NUM_COMP_VECTORS 1
34
35extern unsigned int usnic_ib_share_vf;
36
37struct usnic_ib_ucontext {
38 struct ib_ucontext ibucontext;
39 /* Protected by usnic_ib_dev->usdev_lock */
40 struct list_head qp_grp_list;
41 struct list_head link;
42};
43
44struct usnic_ib_pd {
45 struct ib_pd ibpd;
46 struct usnic_uiom_pd *umem_pd;
47};
48
49struct usnic_ib_mr {
50 struct ib_mr ibmr;
51 struct usnic_uiom_reg *umem;
52};
53
54struct usnic_ib_dev {
55 struct ib_device ib_dev;
56 struct pci_dev *pdev;
57 struct net_device *netdev;
58 struct usnic_fwd_dev *ufdev;
59 struct list_head ib_dev_link;
60 struct list_head vf_dev_list;
61 struct list_head ctx_list;
62 struct mutex usdev_lock;
63
64 /* provisioning information */
65 struct kref vf_cnt;
66 unsigned int vf_res_cnt[USNIC_VNIC_RES_TYPE_MAX];
67
68 /* sysfs vars for QPN reporting */
69 struct kobject *qpn_kobj;
70};
71
72struct usnic_ib_vf {
73 struct usnic_ib_dev *pf;
74 spinlock_t lock;
75 struct usnic_vnic *vnic;
76 unsigned int qp_grp_ref_cnt;
77 struct usnic_ib_pd *pd;
78 struct list_head link;
79};
80
81static inline
82struct usnic_ib_dev *to_usdev(struct ib_device *ibdev)
83{
84 return container_of(ibdev, struct usnic_ib_dev, ib_dev);
85}
86
87static inline
88struct usnic_ib_ucontext *to_ucontext(struct ib_ucontext *ibucontext)
89{
90 return container_of(ibucontext, struct usnic_ib_ucontext, ibucontext);
91}
92
93static inline
94struct usnic_ib_pd *to_upd(struct ib_pd *ibpd)
95{
96 return container_of(ibpd, struct usnic_ib_pd, ibpd);
97}
98
99static inline
100struct usnic_ib_ucontext *to_uucontext(struct ib_ucontext *ibucontext)
101{
102 return container_of(ibucontext, struct usnic_ib_ucontext, ibucontext);
103}
104
105static inline
106struct usnic_ib_mr *to_umr(struct ib_mr *ibmr)
107{
108 return container_of(ibmr, struct usnic_ib_mr, ibmr);
109}
110void usnic_ib_log_vf(struct usnic_ib_vf *vf);
111
112#define UPDATE_PTR_LEFT(N, P, L) \
113do { \
114 L -= (N); \
115 P += (N); \
116} while (0)
117
118#endif /* USNIC_IB_H_ */
diff --git a/drivers/infiniband/hw/usnic/usnic_ib_main.c b/drivers/infiniband/hw/usnic/usnic_ib_main.c
new file mode 100644
index 000000000000..fb6d026f92cd
--- /dev/null
+++ b/drivers/infiniband/hw/usnic/usnic_ib_main.c
@@ -0,0 +1,682 @@
1/*
2 * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
3 *
4 * This program is free software; you may redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
15 * SOFTWARE.
16 *
17 * Author: Upinder Malhi <umalhi@cisco.com>
18 * Author: Anant Deepak <anadeepa@cisco.com>
19 * Author: Cesare Cantu' <cantuc@cisco.com>
20 * Author: Jeff Squyres <jsquyres@cisco.com>
21 * Author: Kiran Thirumalai <kithirum@cisco.com>
22 * Author: Xuyang Wang <xuywang@cisco.com>
23 * Author: Reese Faucette <rfaucett@cisco.com>
24 *
25 */
26
27#include <linux/module.h>
28#include <linux/inetdevice.h>
29#include <linux/init.h>
30#include <linux/slab.h>
31#include <linux/errno.h>
32#include <linux/pci.h>
33#include <linux/netdevice.h>
34
35#include <rdma/ib_user_verbs.h>
36#include <rdma/ib_addr.h>
37
38#include "usnic_abi.h"
39#include "usnic_common_util.h"
40#include "usnic_ib.h"
41#include "usnic_ib_qp_grp.h"
42#include "usnic_log.h"
43#include "usnic_fwd.h"
44#include "usnic_debugfs.h"
45#include "usnic_ib_verbs.h"
46#include "usnic_transport.h"
47#include "usnic_uiom.h"
48#include "usnic_ib_sysfs.h"
49
50unsigned int usnic_log_lvl = USNIC_LOG_LVL_ERR;
51unsigned int usnic_ib_share_vf = 1;
52
53static const char usnic_version[] =
54 DRV_NAME ": Cisco VIC (USNIC) Verbs Driver v"
55 DRV_VERSION " (" DRV_RELDATE ")\n";
56
57static DEFINE_MUTEX(usnic_ib_ibdev_list_lock);
58static LIST_HEAD(usnic_ib_ibdev_list);
59
60/* Callback dump funcs */
61static int usnic_ib_dump_vf_hdr(void *obj, char *buf, int buf_sz)
62{
63 struct usnic_ib_vf *vf = obj;
64 return scnprintf(buf, buf_sz, "PF: %s ", vf->pf->ib_dev.name);
65}
66/* End callback dump funcs */
67
68static void usnic_ib_dump_vf(struct usnic_ib_vf *vf, char *buf, int buf_sz)
69{
70 usnic_vnic_dump(vf->vnic, buf, buf_sz, vf,
71 usnic_ib_dump_vf_hdr,
72 usnic_ib_qp_grp_dump_hdr, usnic_ib_qp_grp_dump_rows);
73}
74
75void usnic_ib_log_vf(struct usnic_ib_vf *vf)
76{
77 char buf[1000];
78 usnic_ib_dump_vf(vf, buf, sizeof(buf));
79 usnic_dbg("%s\n", buf);
80}
81
82/* Start of netdev section */
83static inline const char *usnic_ib_netdev_event_to_string(unsigned long event)
84{
85 const char *event2str[] = {"NETDEV_NONE", "NETDEV_UP", "NETDEV_DOWN",
86 "NETDEV_REBOOT", "NETDEV_CHANGE",
87 "NETDEV_REGISTER", "NETDEV_UNREGISTER", "NETDEV_CHANGEMTU",
88 "NETDEV_CHANGEADDR", "NETDEV_GOING_DOWN", "NETDEV_FEAT_CHANGE",
89 "NETDEV_BONDING_FAILOVER", "NETDEV_PRE_UP",
90 "NETDEV_PRE_TYPE_CHANGE", "NETDEV_POST_TYPE_CHANGE",
91 "NETDEV_POST_INT", "NETDEV_UNREGISTER_FINAL", "NETDEV_RELEASE",
92 "NETDEV_NOTIFY_PEERS", "NETDEV_JOIN"
93 };
94
95 if (event >= ARRAY_SIZE(event2str))
96 return "UNKNOWN_NETDEV_EVENT";
97 else
98 return event2str[event];
99}
100
101static void usnic_ib_qp_grp_modify_active_to_err(struct usnic_ib_dev *us_ibdev)
102{
103 struct usnic_ib_ucontext *ctx;
104 struct usnic_ib_qp_grp *qp_grp;
105 enum ib_qp_state cur_state;
106 int status;
107
108 BUG_ON(!mutex_is_locked(&us_ibdev->usdev_lock));
109
110 list_for_each_entry(ctx, &us_ibdev->ctx_list, link) {
111 list_for_each_entry(qp_grp, &ctx->qp_grp_list, link) {
112 cur_state = qp_grp->state;
113 if (cur_state == IB_QPS_INIT ||
114 cur_state == IB_QPS_RTR ||
115 cur_state == IB_QPS_RTS) {
116 status = usnic_ib_qp_grp_modify(qp_grp,
117 IB_QPS_ERR,
118 NULL);
119 if (status) {
120 usnic_err("Failed to transistion qp grp %u from %s to %s\n",
121 qp_grp->grp_id,
122 usnic_ib_qp_grp_state_to_string
123 (cur_state),
124 usnic_ib_qp_grp_state_to_string
125 (IB_QPS_ERR));
126 }
127 }
128 }
129 }
130}
131
132static void usnic_ib_handle_usdev_event(struct usnic_ib_dev *us_ibdev,
133 unsigned long event)
134{
135 struct net_device *netdev;
136 struct ib_event ib_event;
137
138 memset(&ib_event, 0, sizeof(ib_event));
139
140 mutex_lock(&us_ibdev->usdev_lock);
141 netdev = us_ibdev->netdev;
142 switch (event) {
143 case NETDEV_REBOOT:
144 usnic_info("PF Reset on %s\n", us_ibdev->ib_dev.name);
145 usnic_ib_qp_grp_modify_active_to_err(us_ibdev);
146 ib_event.event = IB_EVENT_PORT_ERR;
147 ib_event.device = &us_ibdev->ib_dev;
148 ib_event.element.port_num = 1;
149 ib_dispatch_event(&ib_event);
150 break;
151 case NETDEV_UP:
152 case NETDEV_DOWN:
153 case NETDEV_CHANGE:
154 if (!us_ibdev->ufdev->link_up &&
155 netif_carrier_ok(netdev)) {
156 usnic_fwd_carrier_up(us_ibdev->ufdev);
157 usnic_info("Link UP on %s\n", us_ibdev->ib_dev.name);
158 ib_event.event = IB_EVENT_PORT_ACTIVE;
159 ib_event.device = &us_ibdev->ib_dev;
160 ib_event.element.port_num = 1;
161 ib_dispatch_event(&ib_event);
162 } else if (us_ibdev->ufdev->link_up &&
163 !netif_carrier_ok(netdev)) {
164 usnic_fwd_carrier_down(us_ibdev->ufdev);
165 usnic_info("Link DOWN on %s\n", us_ibdev->ib_dev.name);
166 usnic_ib_qp_grp_modify_active_to_err(us_ibdev);
167 ib_event.event = IB_EVENT_PORT_ERR;
168 ib_event.device = &us_ibdev->ib_dev;
169 ib_event.element.port_num = 1;
170 ib_dispatch_event(&ib_event);
171 } else {
172 usnic_dbg("Ignoring %s on %s\n",
173 usnic_ib_netdev_event_to_string(event),
174 us_ibdev->ib_dev.name);
175 }
176 break;
177 case NETDEV_CHANGEADDR:
178 if (!memcmp(us_ibdev->ufdev->mac, netdev->dev_addr,
179 sizeof(us_ibdev->ufdev->mac))) {
180 usnic_dbg("Ignoring addr change on %s\n",
181 us_ibdev->ib_dev.name);
182 } else {
183 usnic_info(" %s old mac: %pM new mac: %pM\n",
184 us_ibdev->ib_dev.name,
185 us_ibdev->ufdev->mac,
186 netdev->dev_addr);
187 usnic_fwd_set_mac(us_ibdev->ufdev, netdev->dev_addr);
188 usnic_ib_qp_grp_modify_active_to_err(us_ibdev);
189 ib_event.event = IB_EVENT_GID_CHANGE;
190 ib_event.device = &us_ibdev->ib_dev;
191 ib_event.element.port_num = 1;
192 ib_dispatch_event(&ib_event);
193 }
194
195 break;
196 case NETDEV_CHANGEMTU:
197 if (us_ibdev->ufdev->mtu != netdev->mtu) {
198 usnic_info("MTU Change on %s old: %u new: %u\n",
199 us_ibdev->ib_dev.name,
200 us_ibdev->ufdev->mtu, netdev->mtu);
201 usnic_fwd_set_mtu(us_ibdev->ufdev, netdev->mtu);
202 usnic_ib_qp_grp_modify_active_to_err(us_ibdev);
203 } else {
204 usnic_dbg("Ignoring MTU change on %s\n",
205 us_ibdev->ib_dev.name);
206 }
207 break;
208 default:
209 usnic_dbg("Ignoring event %s on %s",
210 usnic_ib_netdev_event_to_string(event),
211 us_ibdev->ib_dev.name);
212 }
213 mutex_unlock(&us_ibdev->usdev_lock);
214}
215
216static int usnic_ib_netdevice_event(struct notifier_block *notifier,
217 unsigned long event, void *ptr)
218{
219 struct usnic_ib_dev *us_ibdev;
220
221 struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
222
223 mutex_lock(&usnic_ib_ibdev_list_lock);
224 list_for_each_entry(us_ibdev, &usnic_ib_ibdev_list, ib_dev_link) {
225 if (us_ibdev->netdev == netdev) {
226 usnic_ib_handle_usdev_event(us_ibdev, event);
227 break;
228 }
229 }
230 mutex_unlock(&usnic_ib_ibdev_list_lock);
231
232 return NOTIFY_DONE;
233}
234
235static struct notifier_block usnic_ib_netdevice_notifier = {
236 .notifier_call = usnic_ib_netdevice_event
237};
238/* End of netdev section */
239
240/* Start of inet section */
241static int usnic_ib_handle_inet_event(struct usnic_ib_dev *us_ibdev,
242 unsigned long event, void *ptr)
243{
244 struct in_ifaddr *ifa = ptr;
245 struct ib_event ib_event;
246
247 mutex_lock(&us_ibdev->usdev_lock);
248
249 switch (event) {
250 case NETDEV_DOWN:
251 usnic_info("%s via ip notifiers",
252 usnic_ib_netdev_event_to_string(event));
253 usnic_fwd_del_ipaddr(us_ibdev->ufdev);
254 usnic_ib_qp_grp_modify_active_to_err(us_ibdev);
255 ib_event.event = IB_EVENT_GID_CHANGE;
256 ib_event.device = &us_ibdev->ib_dev;
257 ib_event.element.port_num = 1;
258 ib_dispatch_event(&ib_event);
259 break;
260 case NETDEV_UP:
261 usnic_fwd_add_ipaddr(us_ibdev->ufdev, ifa->ifa_address);
262 usnic_info("%s via ip notifiers: ip %pI4",
263 usnic_ib_netdev_event_to_string(event),
264 &us_ibdev->ufdev->inaddr);
265 ib_event.event = IB_EVENT_GID_CHANGE;
266 ib_event.device = &us_ibdev->ib_dev;
267 ib_event.element.port_num = 1;
268 ib_dispatch_event(&ib_event);
269 break;
270 default:
271 usnic_info("Ignoring event %s on %s",
272 usnic_ib_netdev_event_to_string(event),
273 us_ibdev->ib_dev.name);
274 }
275 mutex_unlock(&us_ibdev->usdev_lock);
276
277 return NOTIFY_DONE;
278}
279
280static int usnic_ib_inetaddr_event(struct notifier_block *notifier,
281 unsigned long event, void *ptr)
282{
283 struct usnic_ib_dev *us_ibdev;
284 struct in_ifaddr *ifa = ptr;
285 struct net_device *netdev = ifa->ifa_dev->dev;
286
287 mutex_lock(&usnic_ib_ibdev_list_lock);
288 list_for_each_entry(us_ibdev, &usnic_ib_ibdev_list, ib_dev_link) {
289 if (us_ibdev->netdev == netdev) {
290 usnic_ib_handle_inet_event(us_ibdev, event, ptr);
291 break;
292 }
293 }
294 mutex_unlock(&usnic_ib_ibdev_list_lock);
295
296 return NOTIFY_DONE;
297}
298static struct notifier_block usnic_ib_inetaddr_notifier = {
299 .notifier_call = usnic_ib_inetaddr_event
300};
301/* End of inet section*/
302
303/* Start of PF discovery section */
304static void *usnic_ib_device_add(struct pci_dev *dev)
305{
306 struct usnic_ib_dev *us_ibdev;
307 union ib_gid gid;
308 struct in_ifaddr *in;
309 struct net_device *netdev;
310
311 usnic_dbg("\n");
312 netdev = pci_get_drvdata(dev);
313
314 us_ibdev = (struct usnic_ib_dev *)ib_alloc_device(sizeof(*us_ibdev));
315 if (IS_ERR_OR_NULL(us_ibdev)) {
316 usnic_err("Device %s context alloc failed\n",
317 netdev_name(pci_get_drvdata(dev)));
318 return ERR_PTR(us_ibdev ? PTR_ERR(us_ibdev) : -EFAULT);
319 }
320
321 us_ibdev->ufdev = usnic_fwd_dev_alloc(dev);
322 if (IS_ERR_OR_NULL(us_ibdev->ufdev)) {
323 usnic_err("Failed to alloc ufdev for %s with err %ld\n",
324 pci_name(dev), PTR_ERR(us_ibdev->ufdev));
325 goto err_dealloc;
326 }
327
328 mutex_init(&us_ibdev->usdev_lock);
329 INIT_LIST_HEAD(&us_ibdev->vf_dev_list);
330 INIT_LIST_HEAD(&us_ibdev->ctx_list);
331
332 us_ibdev->pdev = dev;
333 us_ibdev->netdev = pci_get_drvdata(dev);
334 us_ibdev->ib_dev.owner = THIS_MODULE;
335 us_ibdev->ib_dev.node_type = RDMA_NODE_USNIC_UDP;
336 us_ibdev->ib_dev.phys_port_cnt = USNIC_IB_PORT_CNT;
337 us_ibdev->ib_dev.num_comp_vectors = USNIC_IB_NUM_COMP_VECTORS;
338 us_ibdev->ib_dev.dma_device = &dev->dev;
339 us_ibdev->ib_dev.uverbs_abi_ver = USNIC_UVERBS_ABI_VERSION;
340 strlcpy(us_ibdev->ib_dev.name, "usnic_%d", IB_DEVICE_NAME_MAX);
341
342 us_ibdev->ib_dev.uverbs_cmd_mask =
343 (1ull << IB_USER_VERBS_CMD_GET_CONTEXT) |
344 (1ull << IB_USER_VERBS_CMD_QUERY_DEVICE) |
345 (1ull << IB_USER_VERBS_CMD_QUERY_PORT) |
346 (1ull << IB_USER_VERBS_CMD_ALLOC_PD) |
347 (1ull << IB_USER_VERBS_CMD_DEALLOC_PD) |
348 (1ull << IB_USER_VERBS_CMD_REG_MR) |
349 (1ull << IB_USER_VERBS_CMD_DEREG_MR) |
350 (1ull << IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL) |
351 (1ull << IB_USER_VERBS_CMD_CREATE_CQ) |
352 (1ull << IB_USER_VERBS_CMD_DESTROY_CQ) |
353 (1ull << IB_USER_VERBS_CMD_CREATE_QP) |
354 (1ull << IB_USER_VERBS_CMD_MODIFY_QP) |
355 (1ull << IB_USER_VERBS_CMD_QUERY_QP) |
356 (1ull << IB_USER_VERBS_CMD_DESTROY_QP) |
357 (1ull << IB_USER_VERBS_CMD_ATTACH_MCAST) |
358 (1ull << IB_USER_VERBS_CMD_DETACH_MCAST) |
359 (1ull << IB_USER_VERBS_CMD_OPEN_QP);
360
361 us_ibdev->ib_dev.query_device = usnic_ib_query_device;
362 us_ibdev->ib_dev.query_port = usnic_ib_query_port;
363 us_ibdev->ib_dev.query_pkey = usnic_ib_query_pkey;
364 us_ibdev->ib_dev.query_gid = usnic_ib_query_gid;
365 us_ibdev->ib_dev.get_link_layer = usnic_ib_port_link_layer;
366 us_ibdev->ib_dev.alloc_pd = usnic_ib_alloc_pd;
367 us_ibdev->ib_dev.dealloc_pd = usnic_ib_dealloc_pd;
368 us_ibdev->ib_dev.create_qp = usnic_ib_create_qp;
369 us_ibdev->ib_dev.modify_qp = usnic_ib_modify_qp;
370 us_ibdev->ib_dev.query_qp = usnic_ib_query_qp;
371 us_ibdev->ib_dev.destroy_qp = usnic_ib_destroy_qp;
372 us_ibdev->ib_dev.create_cq = usnic_ib_create_cq;
373 us_ibdev->ib_dev.destroy_cq = usnic_ib_destroy_cq;
374 us_ibdev->ib_dev.reg_user_mr = usnic_ib_reg_mr;
375 us_ibdev->ib_dev.dereg_mr = usnic_ib_dereg_mr;
376 us_ibdev->ib_dev.alloc_ucontext = usnic_ib_alloc_ucontext;
377 us_ibdev->ib_dev.dealloc_ucontext = usnic_ib_dealloc_ucontext;
378 us_ibdev->ib_dev.mmap = usnic_ib_mmap;
379 us_ibdev->ib_dev.create_ah = usnic_ib_create_ah;
380 us_ibdev->ib_dev.destroy_ah = usnic_ib_destroy_ah;
381 us_ibdev->ib_dev.post_send = usnic_ib_post_send;
382 us_ibdev->ib_dev.post_recv = usnic_ib_post_recv;
383 us_ibdev->ib_dev.poll_cq = usnic_ib_poll_cq;
384 us_ibdev->ib_dev.req_notify_cq = usnic_ib_req_notify_cq;
385 us_ibdev->ib_dev.get_dma_mr = usnic_ib_get_dma_mr;
386
387
388 if (ib_register_device(&us_ibdev->ib_dev, NULL))
389 goto err_fwd_dealloc;
390
391 usnic_fwd_set_mtu(us_ibdev->ufdev, us_ibdev->netdev->mtu);
392 usnic_fwd_set_mac(us_ibdev->ufdev, us_ibdev->netdev->dev_addr);
393 if (netif_carrier_ok(us_ibdev->netdev))
394 usnic_fwd_carrier_up(us_ibdev->ufdev);
395
396 in = ((struct in_device *)(netdev->ip_ptr))->ifa_list;
397 if (in != NULL)
398 usnic_fwd_add_ipaddr(us_ibdev->ufdev, in->ifa_address);
399
400 usnic_mac_ip_to_gid(us_ibdev->netdev->perm_addr,
401 us_ibdev->ufdev->inaddr, &gid.raw[0]);
402 memcpy(&us_ibdev->ib_dev.node_guid, &gid.global.interface_id,
403 sizeof(gid.global.interface_id));
404 kref_init(&us_ibdev->vf_cnt);
405
406 usnic_info("Added ibdev: %s netdev: %s with mac %pM Link: %u MTU: %u\n",
407 us_ibdev->ib_dev.name, netdev_name(us_ibdev->netdev),
408 us_ibdev->ufdev->mac, us_ibdev->ufdev->link_up,
409 us_ibdev->ufdev->mtu);
410 return us_ibdev;
411
412err_fwd_dealloc:
413 usnic_fwd_dev_free(us_ibdev->ufdev);
414err_dealloc:
415 usnic_err("failed -- deallocing device\n");
416 ib_dealloc_device(&us_ibdev->ib_dev);
417 return NULL;
418}
419
420static void usnic_ib_device_remove(struct usnic_ib_dev *us_ibdev)
421{
422 usnic_info("Unregistering %s\n", us_ibdev->ib_dev.name);
423 usnic_ib_sysfs_unregister_usdev(us_ibdev);
424 usnic_fwd_dev_free(us_ibdev->ufdev);
425 ib_unregister_device(&us_ibdev->ib_dev);
426 ib_dealloc_device(&us_ibdev->ib_dev);
427}
428
429static void usnic_ib_undiscover_pf(struct kref *kref)
430{
431 struct usnic_ib_dev *us_ibdev, *tmp;
432 struct pci_dev *dev;
433 bool found = false;
434
435 dev = container_of(kref, struct usnic_ib_dev, vf_cnt)->pdev;
436 mutex_lock(&usnic_ib_ibdev_list_lock);
437 list_for_each_entry_safe(us_ibdev, tmp,
438 &usnic_ib_ibdev_list, ib_dev_link) {
439 if (us_ibdev->pdev == dev) {
440 list_del(&us_ibdev->ib_dev_link);
441 usnic_ib_device_remove(us_ibdev);
442 found = true;
443 break;
444 }
445 }
446
447 WARN(!found, "Failed to remove PF %s\n", pci_name(dev));
448
449 mutex_unlock(&usnic_ib_ibdev_list_lock);
450}
451
452static struct usnic_ib_dev *usnic_ib_discover_pf(struct usnic_vnic *vnic)
453{
454 struct usnic_ib_dev *us_ibdev;
455 struct pci_dev *parent_pci, *vf_pci;
456 int err;
457
458 vf_pci = usnic_vnic_get_pdev(vnic);
459 parent_pci = pci_physfn(vf_pci);
460
461 BUG_ON(!parent_pci);
462
463 mutex_lock(&usnic_ib_ibdev_list_lock);
464 list_for_each_entry(us_ibdev, &usnic_ib_ibdev_list, ib_dev_link) {
465 if (us_ibdev->pdev == parent_pci) {
466 kref_get(&us_ibdev->vf_cnt);
467 goto out;
468 }
469 }
470
471 us_ibdev = usnic_ib_device_add(parent_pci);
472 if (IS_ERR_OR_NULL(us_ibdev)) {
473 us_ibdev = us_ibdev ? us_ibdev : ERR_PTR(-EFAULT);
474 goto out;
475 }
476
477 err = usnic_ib_sysfs_register_usdev(us_ibdev);
478 if (err) {
479 usnic_ib_device_remove(us_ibdev);
480 us_ibdev = ERR_PTR(err);
481 goto out;
482 }
483
484 list_add(&us_ibdev->ib_dev_link, &usnic_ib_ibdev_list);
485out:
486 mutex_unlock(&usnic_ib_ibdev_list_lock);
487 return us_ibdev;
488}
489/* End of PF discovery section */
490
491/* Start of PCI section */
492
493static DEFINE_PCI_DEVICE_TABLE(usnic_ib_pci_ids) = {
494 {PCI_DEVICE(PCI_VENDOR_ID_CISCO, PCI_DEVICE_ID_CISCO_VIC_USPACE_NIC)},
495 {0,}
496};
497
498static int usnic_ib_pci_probe(struct pci_dev *pdev,
499 const struct pci_device_id *id)
500{
501 int err;
502 struct usnic_ib_dev *pf;
503 struct usnic_ib_vf *vf;
504 enum usnic_vnic_res_type res_type;
505
506 vf = kzalloc(sizeof(*vf), GFP_KERNEL);
507 if (!vf)
508 return -ENOMEM;
509
510 err = pci_enable_device(pdev);
511 if (err) {
512 usnic_err("Failed to enable %s with err %d\n",
513 pci_name(pdev), err);
514 goto out_clean_vf;
515 }
516
517 err = pci_request_regions(pdev, DRV_NAME);
518 if (err) {
519 usnic_err("Failed to request region for %s with err %d\n",
520 pci_name(pdev), err);
521 goto out_disable_device;
522 }
523
524 pci_set_master(pdev);
525 pci_set_drvdata(pdev, vf);
526
527 vf->vnic = usnic_vnic_alloc(pdev);
528 if (IS_ERR_OR_NULL(vf->vnic)) {
529 err = vf->vnic ? PTR_ERR(vf->vnic) : -ENOMEM;
530 usnic_err("Failed to alloc vnic for %s with err %d\n",
531 pci_name(pdev), err);
532 goto out_release_regions;
533 }
534
535 pf = usnic_ib_discover_pf(vf->vnic);
536 if (IS_ERR_OR_NULL(pf)) {
537 usnic_err("Failed to discover pf of vnic %s with err%ld\n",
538 pci_name(pdev), PTR_ERR(pf));
539 err = pf ? PTR_ERR(pf) : -EFAULT;
540 goto out_clean_vnic;
541 }
542
543 vf->pf = pf;
544 spin_lock_init(&vf->lock);
545 mutex_lock(&pf->usdev_lock);
546 list_add_tail(&vf->link, &pf->vf_dev_list);
547 /*
548 * Save max settings (will be same for each VF, easier to re-write than
549 * to say "if (!set) { set_values(); set=1; }
550 */
551 for (res_type = USNIC_VNIC_RES_TYPE_EOL+1;
552 res_type < USNIC_VNIC_RES_TYPE_MAX;
553 res_type++) {
554 pf->vf_res_cnt[res_type] = usnic_vnic_res_cnt(vf->vnic,
555 res_type);
556 }
557
558 mutex_unlock(&pf->usdev_lock);
559
560 usnic_info("Registering usnic VF %s into PF %s\n", pci_name(pdev),
561 pf->ib_dev.name);
562 usnic_ib_log_vf(vf);
563 return 0;
564
565out_clean_vnic:
566 usnic_vnic_free(vf->vnic);
567out_release_regions:
568 pci_set_drvdata(pdev, NULL);
569 pci_clear_master(pdev);
570 pci_release_regions(pdev);
571out_disable_device:
572 pci_disable_device(pdev);
573out_clean_vf:
574 kfree(vf);
575 return err;
576}
577
578static void usnic_ib_pci_remove(struct pci_dev *pdev)
579{
580 struct usnic_ib_vf *vf = pci_get_drvdata(pdev);
581 struct usnic_ib_dev *pf = vf->pf;
582
583 mutex_lock(&pf->usdev_lock);
584 list_del(&vf->link);
585 mutex_unlock(&pf->usdev_lock);
586
587 kref_put(&pf->vf_cnt, usnic_ib_undiscover_pf);
588 usnic_vnic_free(vf->vnic);
589 pci_set_drvdata(pdev, NULL);
590 pci_clear_master(pdev);
591 pci_release_regions(pdev);
592 pci_disable_device(pdev);
593 kfree(vf);
594
595 usnic_info("Removed VF %s\n", pci_name(pdev));
596}
597
598/* PCI driver entry points */
599static struct pci_driver usnic_ib_pci_driver = {
600 .name = DRV_NAME,
601 .id_table = usnic_ib_pci_ids,
602 .probe = usnic_ib_pci_probe,
603 .remove = usnic_ib_pci_remove,
604};
605/* End of PCI section */
606
607/* Start of module section */
608static int __init usnic_ib_init(void)
609{
610 int err;
611
612 printk_once(KERN_INFO "%s", usnic_version);
613
614 err = usnic_uiom_init(DRV_NAME);
615 if (err) {
616 usnic_err("Unable to initalize umem with err %d\n", err);
617 return err;
618 }
619
620 if (pci_register_driver(&usnic_ib_pci_driver)) {
621 usnic_err("Unable to register with PCI\n");
622 goto out_umem_fini;
623 }
624
625 err = register_netdevice_notifier(&usnic_ib_netdevice_notifier);
626 if (err) {
627 usnic_err("Failed to register netdev notifier\n");
628 goto out_pci_unreg;
629 }
630
631 err = register_inetaddr_notifier(&usnic_ib_inetaddr_notifier);
632 if (err) {
633 usnic_err("Failed to register inet addr notifier\n");
634 goto out_unreg_netdev_notifier;
635 }
636
637 err = usnic_transport_init();
638 if (err) {
639 usnic_err("Failed to initialize transport\n");
640 goto out_unreg_inetaddr_notifier;
641 }
642
643 usnic_debugfs_init();
644
645 return 0;
646
647out_unreg_inetaddr_notifier:
648 unregister_inetaddr_notifier(&usnic_ib_inetaddr_notifier);
649out_unreg_netdev_notifier:
650 unregister_netdevice_notifier(&usnic_ib_netdevice_notifier);
651out_pci_unreg:
652 pci_unregister_driver(&usnic_ib_pci_driver);
653out_umem_fini:
654 usnic_uiom_fini();
655
656 return err;
657}
658
659static void __exit usnic_ib_destroy(void)
660{
661 usnic_dbg("\n");
662 usnic_debugfs_exit();
663 usnic_transport_fini();
664 unregister_inetaddr_notifier(&usnic_ib_inetaddr_notifier);
665 unregister_netdevice_notifier(&usnic_ib_netdevice_notifier);
666 pci_unregister_driver(&usnic_ib_pci_driver);
667 usnic_uiom_fini();
668}
669
670MODULE_DESCRIPTION("Cisco VIC (usNIC) Verbs Driver");
671MODULE_AUTHOR("Upinder Malhi <umalhi@cisco.com>");
672MODULE_LICENSE("Dual BSD/GPL");
673MODULE_VERSION(DRV_VERSION);
674module_param(usnic_log_lvl, uint, S_IRUGO | S_IWUSR);
675module_param(usnic_ib_share_vf, uint, S_IRUGO | S_IWUSR);
676MODULE_PARM_DESC(usnic_log_lvl, " Off=0, Err=1, Info=2, Debug=3");
677MODULE_PARM_DESC(usnic_ib_share_vf, "Off=0, On=1 VF sharing amongst QPs");
678MODULE_DEVICE_TABLE(pci, usnic_ib_pci_ids);
679
680module_init(usnic_ib_init);
681module_exit(usnic_ib_destroy);
682/* End of module section */
diff --git a/drivers/infiniband/hw/usnic/usnic_ib_qp_grp.c b/drivers/infiniband/hw/usnic/usnic_ib_qp_grp.c
new file mode 100644
index 000000000000..7ecc6061f1f4
--- /dev/null
+++ b/drivers/infiniband/hw/usnic/usnic_ib_qp_grp.c
@@ -0,0 +1,754 @@
1/*
2 * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
3 *
4 * This program is free software; you may redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
15 * SOFTWARE.
16 *
17 */
18#include <linux/bug.h>
19#include <linux/errno.h>
20#include <linux/module.h>
21#include <linux/spinlock.h>
22
23#include "usnic_log.h"
24#include "usnic_vnic.h"
25#include "usnic_fwd.h"
26#include "usnic_uiom.h"
27#include "usnic_debugfs.h"
28#include "usnic_ib_qp_grp.h"
29#include "usnic_ib_sysfs.h"
30#include "usnic_transport.h"
31
32#define DFLT_RQ_IDX 0
33
34const char *usnic_ib_qp_grp_state_to_string(enum ib_qp_state state)
35{
36 switch (state) {
37 case IB_QPS_RESET:
38 return "Rst";
39 case IB_QPS_INIT:
40 return "Init";
41 case IB_QPS_RTR:
42 return "RTR";
43 case IB_QPS_RTS:
44 return "RTS";
45 case IB_QPS_SQD:
46 return "SQD";
47 case IB_QPS_SQE:
48 return "SQE";
49 case IB_QPS_ERR:
50 return "ERR";
51 default:
52 return "UNKOWN STATE";
53
54 }
55}
56
57int usnic_ib_qp_grp_dump_hdr(char *buf, int buf_sz)
58{
59 return scnprintf(buf, buf_sz, "|QPN\t|State\t|PID\t|VF Idx\t|Fil ID");
60}
61
62int usnic_ib_qp_grp_dump_rows(void *obj, char *buf, int buf_sz)
63{
64 struct usnic_ib_qp_grp *qp_grp = obj;
65 struct usnic_ib_qp_grp_flow *default_flow;
66 if (obj) {
67 default_flow = list_first_entry(&qp_grp->flows_lst,
68 struct usnic_ib_qp_grp_flow, link);
69 return scnprintf(buf, buf_sz, "|%d\t|%s\t|%d\t|%hu\t|%d",
70 qp_grp->ibqp.qp_num,
71 usnic_ib_qp_grp_state_to_string(
72 qp_grp->state),
73 qp_grp->owner_pid,
74 usnic_vnic_get_index(qp_grp->vf->vnic),
75 default_flow->flow->flow_id);
76 } else {
77 return scnprintf(buf, buf_sz, "|N/A\t|N/A\t|N/A\t|N/A\t|N/A");
78 }
79}
80
81static struct usnic_vnic_res_chunk *
82get_qp_res_chunk(struct usnic_ib_qp_grp *qp_grp)
83{
84 lockdep_assert_held(&qp_grp->lock);
85 /*
86 * The QP res chunk, used to derive qp indices,
87 * are just indices of the RQs
88 */
89 return usnic_ib_qp_grp_get_chunk(qp_grp, USNIC_VNIC_RES_TYPE_RQ);
90}
91
92static int enable_qp_grp(struct usnic_ib_qp_grp *qp_grp)
93{
94
95 int status;
96 int i, vnic_idx;
97 struct usnic_vnic_res_chunk *res_chunk;
98 struct usnic_vnic_res *res;
99
100 lockdep_assert_held(&qp_grp->lock);
101
102 vnic_idx = usnic_vnic_get_index(qp_grp->vf->vnic);
103
104 res_chunk = get_qp_res_chunk(qp_grp);
105 if (IS_ERR_OR_NULL(res_chunk)) {
106 usnic_err("Unable to get qp res with err %ld\n",
107 PTR_ERR(res_chunk));
108 return res_chunk ? PTR_ERR(res_chunk) : -ENOMEM;
109 }
110
111 for (i = 0; i < res_chunk->cnt; i++) {
112 res = res_chunk->res[i];
113 status = usnic_fwd_enable_qp(qp_grp->ufdev, vnic_idx,
114 res->vnic_idx);
115 if (status) {
116 usnic_err("Failed to enable qp %d of %s:%d\n with err %d\n",
117 res->vnic_idx, qp_grp->ufdev->name,
118 vnic_idx, status);
119 goto out_err;
120 }
121 }
122
123 return 0;
124
125out_err:
126 for (i--; i >= 0; i--) {
127 res = res_chunk->res[i];
128 usnic_fwd_disable_qp(qp_grp->ufdev, vnic_idx,
129 res->vnic_idx);
130 }
131
132 return status;
133}
134
135static int disable_qp_grp(struct usnic_ib_qp_grp *qp_grp)
136{
137 int i, vnic_idx;
138 struct usnic_vnic_res_chunk *res_chunk;
139 struct usnic_vnic_res *res;
140 int status = 0;
141
142 lockdep_assert_held(&qp_grp->lock);
143 vnic_idx = usnic_vnic_get_index(qp_grp->vf->vnic);
144
145 res_chunk = get_qp_res_chunk(qp_grp);
146 if (IS_ERR_OR_NULL(res_chunk)) {
147 usnic_err("Unable to get qp res with err %ld\n",
148 PTR_ERR(res_chunk));
149 return res_chunk ? PTR_ERR(res_chunk) : -ENOMEM;
150 }
151
152 for (i = 0; i < res_chunk->cnt; i++) {
153 res = res_chunk->res[i];
154 status = usnic_fwd_disable_qp(qp_grp->ufdev, vnic_idx,
155 res->vnic_idx);
156 if (status) {
157 usnic_err("Failed to disable rq %d of %s:%d\n with err %d\n",
158 res->vnic_idx,
159 qp_grp->ufdev->name,
160 vnic_idx, status);
161 }
162 }
163
164 return status;
165
166}
167
168static int init_filter_action(struct usnic_ib_qp_grp *qp_grp,
169 struct usnic_filter_action *uaction)
170{
171 struct usnic_vnic_res_chunk *res_chunk;
172
173 res_chunk = usnic_ib_qp_grp_get_chunk(qp_grp, USNIC_VNIC_RES_TYPE_RQ);
174 if (IS_ERR_OR_NULL(res_chunk)) {
175 usnic_err("Unable to get %s with err %ld\n",
176 usnic_vnic_res_type_to_str(USNIC_VNIC_RES_TYPE_RQ),
177 PTR_ERR(res_chunk));
178 return res_chunk ? PTR_ERR(res_chunk) : -ENOMEM;
179 }
180
181 uaction->vnic_idx = usnic_vnic_get_index(qp_grp->vf->vnic);
182 uaction->action.type = FILTER_ACTION_RQ_STEERING;
183 uaction->action.u.rq_idx = res_chunk->res[DFLT_RQ_IDX]->vnic_idx;
184
185 return 0;
186}
187
188static struct usnic_ib_qp_grp_flow*
189create_roce_custom_flow(struct usnic_ib_qp_grp *qp_grp,
190 struct usnic_transport_spec *trans_spec)
191{
192 uint16_t port_num;
193 int err;
194 struct filter filter;
195 struct usnic_filter_action uaction;
196 struct usnic_ib_qp_grp_flow *qp_flow;
197 struct usnic_fwd_flow *flow;
198 enum usnic_transport_type trans_type;
199
200 trans_type = trans_spec->trans_type;
201 port_num = trans_spec->usnic_roce.port_num;
202
203 /* Reserve Port */
204 port_num = usnic_transport_rsrv_port(trans_type, port_num);
205 if (port_num == 0)
206 return ERR_PTR(-EINVAL);
207
208 /* Create Flow */
209 usnic_fwd_init_usnic_filter(&filter, port_num);
210 err = init_filter_action(qp_grp, &uaction);
211 if (err)
212 goto out_unreserve_port;
213
214 flow = usnic_fwd_alloc_flow(qp_grp->ufdev, &filter, &uaction);
215 if (IS_ERR_OR_NULL(flow)) {
216 usnic_err("Unable to alloc flow failed with err %ld\n",
217 PTR_ERR(flow));
218 err = flow ? PTR_ERR(flow) : -EFAULT;
219 goto out_unreserve_port;
220 }
221
222 /* Create Flow Handle */
223 qp_flow = kzalloc(sizeof(*qp_flow), GFP_ATOMIC);
224 if (IS_ERR_OR_NULL(qp_flow)) {
225 err = qp_flow ? PTR_ERR(qp_flow) : -ENOMEM;
226 goto out_dealloc_flow;
227 }
228 qp_flow->flow = flow;
229 qp_flow->trans_type = trans_type;
230 qp_flow->usnic_roce.port_num = port_num;
231 qp_flow->qp_grp = qp_grp;
232 return qp_flow;
233
234out_dealloc_flow:
235 usnic_fwd_dealloc_flow(flow);
236out_unreserve_port:
237 usnic_transport_unrsrv_port(trans_type, port_num);
238 return ERR_PTR(err);
239}
240
241static void release_roce_custom_flow(struct usnic_ib_qp_grp_flow *qp_flow)
242{
243 usnic_fwd_dealloc_flow(qp_flow->flow);
244 usnic_transport_unrsrv_port(qp_flow->trans_type,
245 qp_flow->usnic_roce.port_num);
246 kfree(qp_flow);
247}
248
249static struct usnic_ib_qp_grp_flow*
250create_udp_flow(struct usnic_ib_qp_grp *qp_grp,
251 struct usnic_transport_spec *trans_spec)
252{
253 struct socket *sock;
254 int sock_fd;
255 int err;
256 struct filter filter;
257 struct usnic_filter_action uaction;
258 struct usnic_ib_qp_grp_flow *qp_flow;
259 struct usnic_fwd_flow *flow;
260 enum usnic_transport_type trans_type;
261 uint32_t addr;
262 uint16_t port_num;
263 int proto;
264
265 trans_type = trans_spec->trans_type;
266 sock_fd = trans_spec->udp.sock_fd;
267
268 /* Get and check socket */
269 sock = usnic_transport_get_socket(sock_fd);
270 if (IS_ERR_OR_NULL(sock))
271 return ERR_CAST(sock);
272
273 err = usnic_transport_sock_get_addr(sock, &proto, &addr, &port_num);
274 if (err)
275 goto out_put_sock;
276
277 if (proto != IPPROTO_UDP) {
278 usnic_err("Protocol for fd %d is not UDP", sock_fd);
279 err = -EPERM;
280 goto out_put_sock;
281 }
282
283 /* Create flow */
284 usnic_fwd_init_udp_filter(&filter, addr, port_num);
285 err = init_filter_action(qp_grp, &uaction);
286 if (err)
287 goto out_put_sock;
288
289 flow = usnic_fwd_alloc_flow(qp_grp->ufdev, &filter, &uaction);
290 if (IS_ERR_OR_NULL(flow)) {
291 usnic_err("Unable to alloc flow failed with err %ld\n",
292 PTR_ERR(flow));
293 err = flow ? PTR_ERR(flow) : -EFAULT;
294 goto out_put_sock;
295 }
296
297 /* Create qp_flow */
298 qp_flow = kzalloc(sizeof(*qp_flow), GFP_ATOMIC);
299 if (IS_ERR_OR_NULL(qp_flow)) {
300 err = qp_flow ? PTR_ERR(qp_flow) : -ENOMEM;
301 goto out_dealloc_flow;
302 }
303 qp_flow->flow = flow;
304 qp_flow->trans_type = trans_type;
305 qp_flow->udp.sock = sock;
306 qp_flow->qp_grp = qp_grp;
307 return qp_flow;
308
309out_dealloc_flow:
310 usnic_fwd_dealloc_flow(flow);
311out_put_sock:
312 usnic_transport_put_socket(sock);
313 return ERR_PTR(err);
314}
315
316static void release_udp_flow(struct usnic_ib_qp_grp_flow *qp_flow)
317{
318 usnic_fwd_dealloc_flow(qp_flow->flow);
319 usnic_transport_put_socket(qp_flow->udp.sock);
320 kfree(qp_flow);
321}
322
323static struct usnic_ib_qp_grp_flow*
324create_and_add_flow(struct usnic_ib_qp_grp *qp_grp,
325 struct usnic_transport_spec *trans_spec)
326{
327 struct usnic_ib_qp_grp_flow *qp_flow;
328 enum usnic_transport_type trans_type;
329
330 trans_type = trans_spec->trans_type;
331 switch (trans_type) {
332 case USNIC_TRANSPORT_ROCE_CUSTOM:
333 qp_flow = create_roce_custom_flow(qp_grp, trans_spec);
334 break;
335 case USNIC_TRANSPORT_IPV4_UDP:
336 qp_flow = create_udp_flow(qp_grp, trans_spec);
337 break;
338 default:
339 usnic_err("Unsupported transport %u\n",
340 trans_spec->trans_type);
341 return ERR_PTR(-EINVAL);
342 }
343
344 if (!IS_ERR_OR_NULL(qp_flow)) {
345 list_add_tail(&qp_flow->link, &qp_grp->flows_lst);
346 usnic_debugfs_flow_add(qp_flow);
347 }
348
349
350 return qp_flow;
351}
352
353static void release_and_remove_flow(struct usnic_ib_qp_grp_flow *qp_flow)
354{
355 usnic_debugfs_flow_remove(qp_flow);
356 list_del(&qp_flow->link);
357
358 switch (qp_flow->trans_type) {
359 case USNIC_TRANSPORT_ROCE_CUSTOM:
360 release_roce_custom_flow(qp_flow);
361 break;
362 case USNIC_TRANSPORT_IPV4_UDP:
363 release_udp_flow(qp_flow);
364 break;
365 default:
366 WARN(1, "Unsupported transport %u\n",
367 qp_flow->trans_type);
368 break;
369 }
370}
371
372static void release_and_remove_all_flows(struct usnic_ib_qp_grp *qp_grp)
373{
374 struct usnic_ib_qp_grp_flow *qp_flow, *tmp;
375 list_for_each_entry_safe(qp_flow, tmp, &qp_grp->flows_lst, link)
376 release_and_remove_flow(qp_flow);
377}
378
379int usnic_ib_qp_grp_modify(struct usnic_ib_qp_grp *qp_grp,
380 enum ib_qp_state new_state,
381 void *data)
382{
383 int status = 0;
384 int vnic_idx;
385 struct ib_event ib_event;
386 enum ib_qp_state old_state;
387 struct usnic_transport_spec *trans_spec;
388 struct usnic_ib_qp_grp_flow *qp_flow;
389
390 old_state = qp_grp->state;
391 vnic_idx = usnic_vnic_get_index(qp_grp->vf->vnic);
392 trans_spec = (struct usnic_transport_spec *) data;
393
394 spin_lock(&qp_grp->lock);
395 switch (new_state) {
396 case IB_QPS_RESET:
397 switch (old_state) {
398 case IB_QPS_RESET:
399 /* NO-OP */
400 break;
401 case IB_QPS_INIT:
402 release_and_remove_all_flows(qp_grp);
403 status = 0;
404 break;
405 case IB_QPS_RTR:
406 case IB_QPS_RTS:
407 case IB_QPS_ERR:
408 status = disable_qp_grp(qp_grp);
409 release_and_remove_all_flows(qp_grp);
410 break;
411 default:
412 status = -EINVAL;
413 }
414 break;
415 case IB_QPS_INIT:
416 switch (old_state) {
417 case IB_QPS_RESET:
418 if (trans_spec) {
419 qp_flow = create_and_add_flow(qp_grp,
420 trans_spec);
421 if (IS_ERR_OR_NULL(qp_flow)) {
422 status = qp_flow ? PTR_ERR(qp_flow) : -EFAULT;
423 break;
424 }
425 } else {
426 /*
427 * Optional to specify filters.
428 */
429 status = 0;
430 }
431 break;
432 case IB_QPS_INIT:
433 if (trans_spec) {
434 qp_flow = create_and_add_flow(qp_grp,
435 trans_spec);
436 if (IS_ERR_OR_NULL(qp_flow)) {
437 status = qp_flow ? PTR_ERR(qp_flow) : -EFAULT;
438 break;
439 }
440 } else {
441 /*
442 * Doesn't make sense to go into INIT state
443 * from INIT state w/o adding filters.
444 */
445 status = -EINVAL;
446 }
447 break;
448 case IB_QPS_RTR:
449 status = disable_qp_grp(qp_grp);
450 break;
451 case IB_QPS_RTS:
452 status = disable_qp_grp(qp_grp);
453 break;
454 default:
455 status = -EINVAL;
456 }
457 break;
458 case IB_QPS_RTR:
459 switch (old_state) {
460 case IB_QPS_INIT:
461 status = enable_qp_grp(qp_grp);
462 break;
463 default:
464 status = -EINVAL;
465 }
466 break;
467 case IB_QPS_RTS:
468 switch (old_state) {
469 case IB_QPS_RTR:
470 /* NO-OP FOR NOW */
471 break;
472 default:
473 status = -EINVAL;
474 }
475 break;
476 case IB_QPS_ERR:
477 ib_event.device = &qp_grp->vf->pf->ib_dev;
478 ib_event.element.qp = &qp_grp->ibqp;
479 ib_event.event = IB_EVENT_QP_FATAL;
480
481 switch (old_state) {
482 case IB_QPS_RESET:
483 qp_grp->ibqp.event_handler(&ib_event,
484 qp_grp->ibqp.qp_context);
485 break;
486 case IB_QPS_INIT:
487 release_and_remove_all_flows(qp_grp);
488 qp_grp->ibqp.event_handler(&ib_event,
489 qp_grp->ibqp.qp_context);
490 break;
491 case IB_QPS_RTR:
492 case IB_QPS_RTS:
493 status = disable_qp_grp(qp_grp);
494 release_and_remove_all_flows(qp_grp);
495 qp_grp->ibqp.event_handler(&ib_event,
496 qp_grp->ibqp.qp_context);
497 break;
498 default:
499 status = -EINVAL;
500 }
501 break;
502 default:
503 status = -EINVAL;
504 }
505 spin_unlock(&qp_grp->lock);
506
507 if (!status) {
508 qp_grp->state = new_state;
509 usnic_info("Transistioned %u from %s to %s",
510 qp_grp->grp_id,
511 usnic_ib_qp_grp_state_to_string(old_state),
512 usnic_ib_qp_grp_state_to_string(new_state));
513 } else {
514 usnic_err("Failed to transistion %u from %s to %s",
515 qp_grp->grp_id,
516 usnic_ib_qp_grp_state_to_string(old_state),
517 usnic_ib_qp_grp_state_to_string(new_state));
518 }
519
520 return status;
521}
522
523static struct usnic_vnic_res_chunk**
524alloc_res_chunk_list(struct usnic_vnic *vnic,
525 struct usnic_vnic_res_spec *res_spec, void *owner_obj)
526{
527 enum usnic_vnic_res_type res_type;
528 struct usnic_vnic_res_chunk **res_chunk_list;
529 int err, i, res_cnt, res_lst_sz;
530
531 for (res_lst_sz = 0;
532 res_spec->resources[res_lst_sz].type != USNIC_VNIC_RES_TYPE_EOL;
533 res_lst_sz++) {
534 /* Do Nothing */
535 }
536
537 res_chunk_list = kzalloc(sizeof(*res_chunk_list)*(res_lst_sz+1),
538 GFP_ATOMIC);
539 if (!res_chunk_list)
540 return ERR_PTR(-ENOMEM);
541
542 for (i = 0; res_spec->resources[i].type != USNIC_VNIC_RES_TYPE_EOL;
543 i++) {
544 res_type = res_spec->resources[i].type;
545 res_cnt = res_spec->resources[i].cnt;
546
547 res_chunk_list[i] = usnic_vnic_get_resources(vnic, res_type,
548 res_cnt, owner_obj);
549 if (IS_ERR_OR_NULL(res_chunk_list[i])) {
550 err = res_chunk_list[i] ?
551 PTR_ERR(res_chunk_list[i]) : -ENOMEM;
552 usnic_err("Failed to get %s from %s with err %d\n",
553 usnic_vnic_res_type_to_str(res_type),
554 usnic_vnic_pci_name(vnic),
555 err);
556 goto out_free_res;
557 }
558 }
559
560 return res_chunk_list;
561
562out_free_res:
563 for (i--; i > 0; i--)
564 usnic_vnic_put_resources(res_chunk_list[i]);
565 kfree(res_chunk_list);
566 return ERR_PTR(err);
567}
568
569static void free_qp_grp_res(struct usnic_vnic_res_chunk **res_chunk_list)
570{
571 int i;
572 for (i = 0; res_chunk_list[i]; i++)
573 usnic_vnic_put_resources(res_chunk_list[i]);
574 kfree(res_chunk_list);
575}
576
577static int qp_grp_and_vf_bind(struct usnic_ib_vf *vf,
578 struct usnic_ib_pd *pd,
579 struct usnic_ib_qp_grp *qp_grp)
580{
581 int err;
582 struct pci_dev *pdev;
583
584 lockdep_assert_held(&vf->lock);
585
586 pdev = usnic_vnic_get_pdev(vf->vnic);
587 if (vf->qp_grp_ref_cnt == 0) {
588 err = usnic_uiom_attach_dev_to_pd(pd->umem_pd, &pdev->dev);
589 if (err) {
590 usnic_err("Failed to attach %s to domain\n",
591 pci_name(pdev));
592 return err;
593 }
594 vf->pd = pd;
595 }
596 vf->qp_grp_ref_cnt++;
597
598 WARN_ON(vf->pd != pd);
599 qp_grp->vf = vf;
600
601 return 0;
602}
603
604static void qp_grp_and_vf_unbind(struct usnic_ib_qp_grp *qp_grp)
605{
606 struct pci_dev *pdev;
607 struct usnic_ib_pd *pd;
608
609 lockdep_assert_held(&qp_grp->vf->lock);
610
611 pd = qp_grp->vf->pd;
612 pdev = usnic_vnic_get_pdev(qp_grp->vf->vnic);
613 if (--qp_grp->vf->qp_grp_ref_cnt == 0) {
614 qp_grp->vf->pd = NULL;
615 usnic_uiom_detach_dev_from_pd(pd->umem_pd, &pdev->dev);
616 }
617 qp_grp->vf = NULL;
618}
619
620static void log_spec(struct usnic_vnic_res_spec *res_spec)
621{
622 char buf[512];
623 usnic_vnic_spec_dump(buf, sizeof(buf), res_spec);
624 usnic_dbg("%s\n", buf);
625}
626
627static int qp_grp_id_from_flow(struct usnic_ib_qp_grp_flow *qp_flow,
628 uint32_t *id)
629{
630 enum usnic_transport_type trans_type = qp_flow->trans_type;
631 int err;
632
633 switch (trans_type) {
634 case USNIC_TRANSPORT_ROCE_CUSTOM:
635 *id = qp_flow->usnic_roce.port_num;
636 break;
637 case USNIC_TRANSPORT_IPV4_UDP:
638 err = usnic_transport_sock_get_addr(qp_flow->udp.sock,
639 NULL, NULL,
640 (uint16_t *) id);
641 if (err)
642 return err;
643 break;
644 default:
645 usnic_err("Unsupported transport %u\n", trans_type);
646 return -EINVAL;
647 }
648
649 return 0;
650}
651
652struct usnic_ib_qp_grp *
653usnic_ib_qp_grp_create(struct usnic_fwd_dev *ufdev, struct usnic_ib_vf *vf,
654 struct usnic_ib_pd *pd,
655 struct usnic_vnic_res_spec *res_spec,
656 struct usnic_transport_spec *transport_spec)
657{
658 struct usnic_ib_qp_grp *qp_grp;
659 int err;
660 enum usnic_transport_type transport = transport_spec->trans_type;
661 struct usnic_ib_qp_grp_flow *qp_flow;
662
663 lockdep_assert_held(&vf->lock);
664
665 err = usnic_vnic_res_spec_satisfied(&min_transport_spec[transport],
666 res_spec);
667 if (err) {
668 usnic_err("Spec does not meet miniumum req for transport %d\n",
669 transport);
670 log_spec(res_spec);
671 return ERR_PTR(err);
672 }
673
674 qp_grp = kzalloc(sizeof(*qp_grp), GFP_ATOMIC);
675 if (!qp_grp) {
676 usnic_err("Unable to alloc qp_grp - Out of memory\n");
677 return NULL;
678 }
679
680 qp_grp->res_chunk_list = alloc_res_chunk_list(vf->vnic, res_spec,
681 qp_grp);
682 if (IS_ERR_OR_NULL(qp_grp->res_chunk_list)) {
683 err = qp_grp->res_chunk_list ?
684 PTR_ERR(qp_grp->res_chunk_list) : -ENOMEM;
685 usnic_err("Unable to alloc res for %d with err %d\n",
686 qp_grp->grp_id, err);
687 goto out_free_qp_grp;
688 }
689
690 err = qp_grp_and_vf_bind(vf, pd, qp_grp);
691 if (err)
692 goto out_free_res;
693
694 INIT_LIST_HEAD(&qp_grp->flows_lst);
695 spin_lock_init(&qp_grp->lock);
696 qp_grp->ufdev = ufdev;
697 qp_grp->state = IB_QPS_RESET;
698 qp_grp->owner_pid = current->pid;
699
700 qp_flow = create_and_add_flow(qp_grp, transport_spec);
701 if (IS_ERR_OR_NULL(qp_flow)) {
702 usnic_err("Unable to create and add flow with err %ld\n",
703 PTR_ERR(qp_flow));
704 err = qp_flow ? PTR_ERR(qp_flow) : -EFAULT;
705 goto out_qp_grp_vf_unbind;
706 }
707
708 err = qp_grp_id_from_flow(qp_flow, &qp_grp->grp_id);
709 if (err)
710 goto out_release_flow;
711 qp_grp->ibqp.qp_num = qp_grp->grp_id;
712
713 usnic_ib_sysfs_qpn_add(qp_grp);
714
715 return qp_grp;
716
717out_release_flow:
718 release_and_remove_flow(qp_flow);
719out_qp_grp_vf_unbind:
720 qp_grp_and_vf_unbind(qp_grp);
721out_free_res:
722 free_qp_grp_res(qp_grp->res_chunk_list);
723out_free_qp_grp:
724 kfree(qp_grp);
725
726 return ERR_PTR(err);
727}
728
729void usnic_ib_qp_grp_destroy(struct usnic_ib_qp_grp *qp_grp)
730{
731
732 WARN_ON(qp_grp->state != IB_QPS_RESET);
733 lockdep_assert_held(&qp_grp->vf->lock);
734
735 release_and_remove_all_flows(qp_grp);
736 usnic_ib_sysfs_qpn_remove(qp_grp);
737 qp_grp_and_vf_unbind(qp_grp);
738 free_qp_grp_res(qp_grp->res_chunk_list);
739 kfree(qp_grp);
740}
741
742struct usnic_vnic_res_chunk*
743usnic_ib_qp_grp_get_chunk(struct usnic_ib_qp_grp *qp_grp,
744 enum usnic_vnic_res_type res_type)
745{
746 int i;
747
748 for (i = 0; qp_grp->res_chunk_list[i]; i++) {
749 if (qp_grp->res_chunk_list[i]->type == res_type)
750 return qp_grp->res_chunk_list[i];
751 }
752
753 return ERR_PTR(-EINVAL);
754}
diff --git a/drivers/infiniband/hw/usnic/usnic_ib_qp_grp.h b/drivers/infiniband/hw/usnic/usnic_ib_qp_grp.h
new file mode 100644
index 000000000000..b0aafe8db0c3
--- /dev/null
+++ b/drivers/infiniband/hw/usnic/usnic_ib_qp_grp.h
@@ -0,0 +1,117 @@
1/*
2 * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
3 *
4 * This program is free software; you may redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
15 * SOFTWARE.
16 *
17 */
18
19#ifndef USNIC_IB_QP_GRP_H_
20#define USNIC_IB_QP_GRP_H_
21
22#include <linux/debugfs.h>
23#include <rdma/ib_verbs.h>
24
25#include "usnic_ib.h"
26#include "usnic_abi.h"
27#include "usnic_fwd.h"
28#include "usnic_vnic.h"
29
30/*
31 * The qp group struct represents all the hw resources needed to present a ib_qp
32 */
33struct usnic_ib_qp_grp {
34 struct ib_qp ibqp;
35 enum ib_qp_state state;
36 int grp_id;
37
38 struct usnic_fwd_dev *ufdev;
39 struct usnic_ib_ucontext *ctx;
40 struct list_head flows_lst;
41
42 struct usnic_vnic_res_chunk **res_chunk_list;
43
44 pid_t owner_pid;
45 struct usnic_ib_vf *vf;
46 struct list_head link;
47
48 spinlock_t lock;
49
50 struct kobject kobj;
51};
52
53struct usnic_ib_qp_grp_flow {
54 struct usnic_fwd_flow *flow;
55 enum usnic_transport_type trans_type;
56 union {
57 struct {
58 uint16_t port_num;
59 } usnic_roce;
60 struct {
61 struct socket *sock;
62 } udp;
63 };
64 struct usnic_ib_qp_grp *qp_grp;
65 struct list_head link;
66
67 /* Debug FS */
68 struct dentry *dbgfs_dentry;
69 char dentry_name[32];
70};
71
72static const struct
73usnic_vnic_res_spec min_transport_spec[USNIC_TRANSPORT_MAX] = {
74 { /*USNIC_TRANSPORT_UNKNOWN*/
75 .resources = {
76 {.type = USNIC_VNIC_RES_TYPE_EOL, .cnt = 0,},
77 },
78 },
79 { /*USNIC_TRANSPORT_ROCE_CUSTOM*/
80 .resources = {
81 {.type = USNIC_VNIC_RES_TYPE_WQ, .cnt = 1,},
82 {.type = USNIC_VNIC_RES_TYPE_RQ, .cnt = 1,},
83 {.type = USNIC_VNIC_RES_TYPE_CQ, .cnt = 1,},
84 {.type = USNIC_VNIC_RES_TYPE_EOL, .cnt = 0,},
85 },
86 },
87 { /*USNIC_TRANSPORT_IPV4_UDP*/
88 .resources = {
89 {.type = USNIC_VNIC_RES_TYPE_WQ, .cnt = 1,},
90 {.type = USNIC_VNIC_RES_TYPE_RQ, .cnt = 1,},
91 {.type = USNIC_VNIC_RES_TYPE_CQ, .cnt = 1,},
92 {.type = USNIC_VNIC_RES_TYPE_EOL, .cnt = 0,},
93 },
94 },
95};
96
97const char *usnic_ib_qp_grp_state_to_string(enum ib_qp_state state);
98int usnic_ib_qp_grp_dump_hdr(char *buf, int buf_sz);
99int usnic_ib_qp_grp_dump_rows(void *obj, char *buf, int buf_sz);
100struct usnic_ib_qp_grp *
101usnic_ib_qp_grp_create(struct usnic_fwd_dev *ufdev, struct usnic_ib_vf *vf,
102 struct usnic_ib_pd *pd,
103 struct usnic_vnic_res_spec *res_spec,
104 struct usnic_transport_spec *trans_spec);
105void usnic_ib_qp_grp_destroy(struct usnic_ib_qp_grp *qp_grp);
106int usnic_ib_qp_grp_modify(struct usnic_ib_qp_grp *qp_grp,
107 enum ib_qp_state new_state,
108 void *data);
109struct usnic_vnic_res_chunk
110*usnic_ib_qp_grp_get_chunk(struct usnic_ib_qp_grp *qp_grp,
111 enum usnic_vnic_res_type type);
112static inline
113struct usnic_ib_qp_grp *to_uqp_grp(struct ib_qp *ibqp)
114{
115 return container_of(ibqp, struct usnic_ib_qp_grp, ibqp);
116}
117#endif /* USNIC_IB_QP_GRP_H_ */
diff --git a/drivers/infiniband/hw/usnic/usnic_ib_sysfs.c b/drivers/infiniband/hw/usnic/usnic_ib_sysfs.c
new file mode 100644
index 000000000000..27dc67c1689f
--- /dev/null
+++ b/drivers/infiniband/hw/usnic/usnic_ib_sysfs.c
@@ -0,0 +1,341 @@
1/*
2 * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
3 *
4 * This program is free software; you may redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
15 * SOFTWARE.
16 *
17 */
18
19#include <linux/module.h>
20#include <linux/init.h>
21#include <linux/errno.h>
22
23#include <rdma/ib_user_verbs.h>
24#include <rdma/ib_addr.h>
25
26#include "usnic_common_util.h"
27#include "usnic_ib.h"
28#include "usnic_ib_qp_grp.h"
29#include "usnic_vnic.h"
30#include "usnic_ib_verbs.h"
31#include "usnic_log.h"
32
33static ssize_t usnic_ib_show_fw_ver(struct device *device,
34 struct device_attribute *attr,
35 char *buf)
36{
37 struct usnic_ib_dev *us_ibdev =
38 container_of(device, struct usnic_ib_dev, ib_dev.dev);
39 struct ethtool_drvinfo info;
40
41 mutex_lock(&us_ibdev->usdev_lock);
42 us_ibdev->netdev->ethtool_ops->get_drvinfo(us_ibdev->netdev, &info);
43 mutex_unlock(&us_ibdev->usdev_lock);
44
45 return scnprintf(buf, PAGE_SIZE, "%s\n", info.fw_version);
46}
47
48static ssize_t usnic_ib_show_board(struct device *device,
49 struct device_attribute *attr,
50 char *buf)
51{
52 struct usnic_ib_dev *us_ibdev =
53 container_of(device, struct usnic_ib_dev, ib_dev.dev);
54 unsigned short subsystem_device_id;
55
56 mutex_lock(&us_ibdev->usdev_lock);
57 subsystem_device_id = us_ibdev->pdev->subsystem_device;
58 mutex_unlock(&us_ibdev->usdev_lock);
59
60 return scnprintf(buf, PAGE_SIZE, "%hu\n", subsystem_device_id);
61}
62
63/*
64 * Report the configuration for this PF
65 */
66static ssize_t
67usnic_ib_show_config(struct device *device, struct device_attribute *attr,
68 char *buf)
69{
70 struct usnic_ib_dev *us_ibdev;
71 char *ptr;
72 unsigned left;
73 unsigned n;
74 enum usnic_vnic_res_type res_type;
75
76 us_ibdev = container_of(device, struct usnic_ib_dev, ib_dev.dev);
77
78 /* Buffer space limit is 1 page */
79 ptr = buf;
80 left = PAGE_SIZE;
81
82 mutex_lock(&us_ibdev->usdev_lock);
83 if (atomic_read(&us_ibdev->vf_cnt.refcount) > 0) {
84 char *busname;
85
86 /*
87 * bus name seems to come with annoying prefix.
88 * Remove it if it is predictable
89 */
90 busname = us_ibdev->pdev->bus->name;
91 if (strncmp(busname, "PCI Bus ", 8) == 0)
92 busname += 8;
93
94 n = scnprintf(ptr, left,
95 "%s: %s:%d.%d, %s, %pM, %u VFs\n Per VF:",
96 us_ibdev->ib_dev.name,
97 busname,
98 PCI_SLOT(us_ibdev->pdev->devfn),
99 PCI_FUNC(us_ibdev->pdev->devfn),
100 netdev_name(us_ibdev->netdev),
101 us_ibdev->ufdev->mac,
102 atomic_read(&us_ibdev->vf_cnt.refcount));
103 UPDATE_PTR_LEFT(n, ptr, left);
104
105 for (res_type = USNIC_VNIC_RES_TYPE_EOL;
106 res_type < USNIC_VNIC_RES_TYPE_MAX;
107 res_type++) {
108 if (us_ibdev->vf_res_cnt[res_type] == 0)
109 continue;
110 n = scnprintf(ptr, left, " %d %s%s",
111 us_ibdev->vf_res_cnt[res_type],
112 usnic_vnic_res_type_to_str(res_type),
113 (res_type < (USNIC_VNIC_RES_TYPE_MAX - 1)) ?
114 "," : "");
115 UPDATE_PTR_LEFT(n, ptr, left);
116 }
117 n = scnprintf(ptr, left, "\n");
118 UPDATE_PTR_LEFT(n, ptr, left);
119 } else {
120 n = scnprintf(ptr, left, "%s: no VFs\n",
121 us_ibdev->ib_dev.name);
122 UPDATE_PTR_LEFT(n, ptr, left);
123 }
124 mutex_unlock(&us_ibdev->usdev_lock);
125
126 return ptr - buf;
127}
128
129static ssize_t
130usnic_ib_show_iface(struct device *device, struct device_attribute *attr,
131 char *buf)
132{
133 struct usnic_ib_dev *us_ibdev;
134
135 us_ibdev = container_of(device, struct usnic_ib_dev, ib_dev.dev);
136
137 return scnprintf(buf, PAGE_SIZE, "%s\n",
138 netdev_name(us_ibdev->netdev));
139}
140
141static ssize_t
142usnic_ib_show_max_vf(struct device *device, struct device_attribute *attr,
143 char *buf)
144{
145 struct usnic_ib_dev *us_ibdev;
146
147 us_ibdev = container_of(device, struct usnic_ib_dev, ib_dev.dev);
148
149 return scnprintf(buf, PAGE_SIZE, "%u\n",
150 atomic_read(&us_ibdev->vf_cnt.refcount));
151}
152
153static ssize_t
154usnic_ib_show_qp_per_vf(struct device *device, struct device_attribute *attr,
155 char *buf)
156{
157 struct usnic_ib_dev *us_ibdev;
158 int qp_per_vf;
159
160 us_ibdev = container_of(device, struct usnic_ib_dev, ib_dev.dev);
161 qp_per_vf = max(us_ibdev->vf_res_cnt[USNIC_VNIC_RES_TYPE_WQ],
162 us_ibdev->vf_res_cnt[USNIC_VNIC_RES_TYPE_RQ]);
163
164 return scnprintf(buf, PAGE_SIZE,
165 "%d\n", qp_per_vf);
166}
167
168static ssize_t
169usnic_ib_show_cq_per_vf(struct device *device, struct device_attribute *attr,
170 char *buf)
171{
172 struct usnic_ib_dev *us_ibdev;
173
174 us_ibdev = container_of(device, struct usnic_ib_dev, ib_dev.dev);
175
176 return scnprintf(buf, PAGE_SIZE, "%d\n",
177 us_ibdev->vf_res_cnt[USNIC_VNIC_RES_TYPE_CQ]);
178}
179
180static DEVICE_ATTR(fw_ver, S_IRUGO, usnic_ib_show_fw_ver, NULL);
181static DEVICE_ATTR(board_id, S_IRUGO, usnic_ib_show_board, NULL);
182static DEVICE_ATTR(config, S_IRUGO, usnic_ib_show_config, NULL);
183static DEVICE_ATTR(iface, S_IRUGO, usnic_ib_show_iface, NULL);
184static DEVICE_ATTR(max_vf, S_IRUGO, usnic_ib_show_max_vf, NULL);
185static DEVICE_ATTR(qp_per_vf, S_IRUGO, usnic_ib_show_qp_per_vf, NULL);
186static DEVICE_ATTR(cq_per_vf, S_IRUGO, usnic_ib_show_cq_per_vf, NULL);
187
188static struct device_attribute *usnic_class_attributes[] = {
189 &dev_attr_fw_ver,
190 &dev_attr_board_id,
191 &dev_attr_config,
192 &dev_attr_iface,
193 &dev_attr_max_vf,
194 &dev_attr_qp_per_vf,
195 &dev_attr_cq_per_vf,
196};
197
198struct qpn_attribute {
199 struct attribute attr;
200 ssize_t (*show)(struct usnic_ib_qp_grp *, char *buf);
201};
202
203/*
204 * Definitions for supporting QPN entries in sysfs
205 */
206static ssize_t
207usnic_ib_qpn_attr_show(struct kobject *kobj, struct attribute *attr, char *buf)
208{
209 struct usnic_ib_qp_grp *qp_grp;
210 struct qpn_attribute *qpn_attr;
211
212 qp_grp = container_of(kobj, struct usnic_ib_qp_grp, kobj);
213 qpn_attr = container_of(attr, struct qpn_attribute, attr);
214
215 return qpn_attr->show(qp_grp, buf);
216}
217
218static const struct sysfs_ops usnic_ib_qpn_sysfs_ops = {
219 .show = usnic_ib_qpn_attr_show
220};
221
222#define QPN_ATTR_RO(NAME) \
223struct qpn_attribute qpn_attr_##NAME = __ATTR_RO(NAME)
224
225static ssize_t context_show(struct usnic_ib_qp_grp *qp_grp, char *buf)
226{
227 return scnprintf(buf, PAGE_SIZE, "0x%p\n", qp_grp->ctx);
228}
229
230static ssize_t summary_show(struct usnic_ib_qp_grp *qp_grp, char *buf)
231{
232 int i, j, n;
233 int left;
234 char *ptr;
235 struct usnic_vnic_res_chunk *res_chunk;
236 struct usnic_vnic_res *vnic_res;
237
238 left = PAGE_SIZE;
239 ptr = buf;
240
241 n = scnprintf(ptr, left,
242 "QPN: %d State: (%s) PID: %u VF Idx: %hu ",
243 qp_grp->ibqp.qp_num,
244 usnic_ib_qp_grp_state_to_string(qp_grp->state),
245 qp_grp->owner_pid,
246 usnic_vnic_get_index(qp_grp->vf->vnic));
247 UPDATE_PTR_LEFT(n, ptr, left);
248
249 for (i = 0; qp_grp->res_chunk_list[i]; i++) {
250 res_chunk = qp_grp->res_chunk_list[i];
251 for (j = 0; j < res_chunk->cnt; j++) {
252 vnic_res = res_chunk->res[j];
253 n = scnprintf(ptr, left, "%s[%d] ",
254 usnic_vnic_res_type_to_str(vnic_res->type),
255 vnic_res->vnic_idx);
256 UPDATE_PTR_LEFT(n, ptr, left);
257 }
258 }
259
260 n = scnprintf(ptr, left, "\n");
261 UPDATE_PTR_LEFT(n, ptr, left);
262
263 return ptr - buf;
264}
265
266static QPN_ATTR_RO(context);
267static QPN_ATTR_RO(summary);
268
269static struct attribute *usnic_ib_qpn_default_attrs[] = {
270 &qpn_attr_context.attr,
271 &qpn_attr_summary.attr,
272 NULL
273};
274
275static struct kobj_type usnic_ib_qpn_type = {
276 .sysfs_ops = &usnic_ib_qpn_sysfs_ops,
277 .default_attrs = usnic_ib_qpn_default_attrs
278};
279
280int usnic_ib_sysfs_register_usdev(struct usnic_ib_dev *us_ibdev)
281{
282 int i;
283 int err;
284 for (i = 0; i < ARRAY_SIZE(usnic_class_attributes); ++i) {
285 err = device_create_file(&us_ibdev->ib_dev.dev,
286 usnic_class_attributes[i]);
287 if (err) {
288 usnic_err("Failed to create device file %d for %s eith err %d",
289 i, us_ibdev->ib_dev.name, err);
290 return -EINVAL;
291 }
292 }
293
294 /* create kernel object for looking at individual QPs */
295 kobject_get(&us_ibdev->ib_dev.dev.kobj);
296 us_ibdev->qpn_kobj = kobject_create_and_add("qpn",
297 &us_ibdev->ib_dev.dev.kobj);
298 if (us_ibdev->qpn_kobj == NULL) {
299 kobject_put(&us_ibdev->ib_dev.dev.kobj);
300 return -ENOMEM;
301 }
302
303 return 0;
304}
305
306void usnic_ib_sysfs_unregister_usdev(struct usnic_ib_dev *us_ibdev)
307{
308 int i;
309 for (i = 0; i < ARRAY_SIZE(usnic_class_attributes); ++i) {
310 device_remove_file(&us_ibdev->ib_dev.dev,
311 usnic_class_attributes[i]);
312 }
313
314 kobject_put(us_ibdev->qpn_kobj);
315}
316
317void usnic_ib_sysfs_qpn_add(struct usnic_ib_qp_grp *qp_grp)
318{
319 struct usnic_ib_dev *us_ibdev;
320 int err;
321
322 us_ibdev = qp_grp->vf->pf;
323
324 err = kobject_init_and_add(&qp_grp->kobj, &usnic_ib_qpn_type,
325 kobject_get(us_ibdev->qpn_kobj),
326 "%d", qp_grp->grp_id);
327 if (err) {
328 kobject_put(us_ibdev->qpn_kobj);
329 return;
330 }
331}
332
333void usnic_ib_sysfs_qpn_remove(struct usnic_ib_qp_grp *qp_grp)
334{
335 struct usnic_ib_dev *us_ibdev;
336
337 us_ibdev = qp_grp->vf->pf;
338
339 kobject_put(&qp_grp->kobj);
340 kobject_put(us_ibdev->qpn_kobj);
341}
diff --git a/drivers/infiniband/hw/usnic/usnic_ib_sysfs.h b/drivers/infiniband/hw/usnic/usnic_ib_sysfs.h
new file mode 100644
index 000000000000..0d09b493cd02
--- /dev/null
+++ b/drivers/infiniband/hw/usnic/usnic_ib_sysfs.h
@@ -0,0 +1,29 @@
1/*
2 * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
3 *
4 * This program is free software; you may redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
15 * SOFTWARE.
16 *
17 */
18
19#ifndef USNIC_IB_SYSFS_H_
20#define USNIC_IB_SYSFS_H_
21
22#include "usnic_ib.h"
23
24int usnic_ib_sysfs_register_usdev(struct usnic_ib_dev *us_ibdev);
25void usnic_ib_sysfs_unregister_usdev(struct usnic_ib_dev *us_ibdev);
26void usnic_ib_sysfs_qpn_add(struct usnic_ib_qp_grp *qp_grp);
27void usnic_ib_sysfs_qpn_remove(struct usnic_ib_qp_grp *qp_grp);
28
29#endif /* !USNIC_IB_SYSFS_H_ */
diff --git a/drivers/infiniband/hw/usnic/usnic_ib_verbs.c b/drivers/infiniband/hw/usnic/usnic_ib_verbs.c
new file mode 100644
index 000000000000..d48d2c0a2e3c
--- /dev/null
+++ b/drivers/infiniband/hw/usnic/usnic_ib_verbs.c
@@ -0,0 +1,765 @@
1/*
2 * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
3 *
4 * This program is free software; you may redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
15 * SOFTWARE.
16 *
17 */
18#include <linux/module.h>
19#include <linux/init.h>
20#include <linux/slab.h>
21#include <linux/errno.h>
22
23#include <rdma/ib_user_verbs.h>
24#include <rdma/ib_addr.h>
25
26#include "usnic_abi.h"
27#include "usnic_ib.h"
28#include "usnic_common_util.h"
29#include "usnic_ib_qp_grp.h"
30#include "usnic_fwd.h"
31#include "usnic_log.h"
32#include "usnic_uiom.h"
33#include "usnic_transport.h"
34
35#define USNIC_DEFAULT_TRANSPORT USNIC_TRANSPORT_ROCE_CUSTOM
36
37static void usnic_ib_fw_string_to_u64(char *fw_ver_str, u64 *fw_ver)
38{
39 *fw_ver = (u64) *fw_ver_str;
40}
41
42static int usnic_ib_fill_create_qp_resp(struct usnic_ib_qp_grp *qp_grp,
43 struct ib_udata *udata)
44{
45 struct usnic_ib_dev *us_ibdev;
46 struct usnic_ib_create_qp_resp resp;
47 struct pci_dev *pdev;
48 struct vnic_dev_bar *bar;
49 struct usnic_vnic_res_chunk *chunk;
50 struct usnic_ib_qp_grp_flow *default_flow;
51 int i, err;
52
53 memset(&resp, 0, sizeof(resp));
54
55 us_ibdev = qp_grp->vf->pf;
56 pdev = usnic_vnic_get_pdev(qp_grp->vf->vnic);
57 if (!pdev) {
58 usnic_err("Failed to get pdev of qp_grp %d\n",
59 qp_grp->grp_id);
60 return -EFAULT;
61 }
62
63 bar = usnic_vnic_get_bar(qp_grp->vf->vnic, 0);
64 if (!bar) {
65 usnic_err("Failed to get bar0 of qp_grp %d vf %s",
66 qp_grp->grp_id, pci_name(pdev));
67 return -EFAULT;
68 }
69
70 resp.vfid = usnic_vnic_get_index(qp_grp->vf->vnic);
71 resp.bar_bus_addr = bar->bus_addr;
72 resp.bar_len = bar->len;
73
74 chunk = usnic_ib_qp_grp_get_chunk(qp_grp, USNIC_VNIC_RES_TYPE_RQ);
75 if (IS_ERR_OR_NULL(chunk)) {
76 usnic_err("Failed to get chunk %s for qp_grp %d with err %ld\n",
77 usnic_vnic_res_type_to_str(USNIC_VNIC_RES_TYPE_RQ),
78 qp_grp->grp_id,
79 PTR_ERR(chunk));
80 return chunk ? PTR_ERR(chunk) : -ENOMEM;
81 }
82
83 WARN_ON(chunk->type != USNIC_VNIC_RES_TYPE_RQ);
84 resp.rq_cnt = chunk->cnt;
85 for (i = 0; i < chunk->cnt; i++)
86 resp.rq_idx[i] = chunk->res[i]->vnic_idx;
87
88 chunk = usnic_ib_qp_grp_get_chunk(qp_grp, USNIC_VNIC_RES_TYPE_WQ);
89 if (IS_ERR_OR_NULL(chunk)) {
90 usnic_err("Failed to get chunk %s for qp_grp %d with err %ld\n",
91 usnic_vnic_res_type_to_str(USNIC_VNIC_RES_TYPE_WQ),
92 qp_grp->grp_id,
93 PTR_ERR(chunk));
94 return chunk ? PTR_ERR(chunk) : -ENOMEM;
95 }
96
97 WARN_ON(chunk->type != USNIC_VNIC_RES_TYPE_WQ);
98 resp.wq_cnt = chunk->cnt;
99 for (i = 0; i < chunk->cnt; i++)
100 resp.wq_idx[i] = chunk->res[i]->vnic_idx;
101
102 chunk = usnic_ib_qp_grp_get_chunk(qp_grp, USNIC_VNIC_RES_TYPE_CQ);
103 if (IS_ERR_OR_NULL(chunk)) {
104 usnic_err("Failed to get chunk %s for qp_grp %d with err %ld\n",
105 usnic_vnic_res_type_to_str(USNIC_VNIC_RES_TYPE_CQ),
106 qp_grp->grp_id,
107 PTR_ERR(chunk));
108 return chunk ? PTR_ERR(chunk) : -ENOMEM;
109 }
110
111 WARN_ON(chunk->type != USNIC_VNIC_RES_TYPE_CQ);
112 resp.cq_cnt = chunk->cnt;
113 for (i = 0; i < chunk->cnt; i++)
114 resp.cq_idx[i] = chunk->res[i]->vnic_idx;
115
116 default_flow = list_first_entry(&qp_grp->flows_lst,
117 struct usnic_ib_qp_grp_flow, link);
118 resp.transport = default_flow->trans_type;
119
120 err = ib_copy_to_udata(udata, &resp, sizeof(resp));
121 if (err) {
122 usnic_err("Failed to copy udata for %s", us_ibdev->ib_dev.name);
123 return err;
124 }
125
126 return 0;
127}
128
129static struct usnic_ib_qp_grp*
130find_free_vf_and_create_qp_grp(struct usnic_ib_dev *us_ibdev,
131 struct usnic_ib_pd *pd,
132 struct usnic_transport_spec *trans_spec,
133 struct usnic_vnic_res_spec *res_spec)
134{
135 struct usnic_ib_vf *vf;
136 struct usnic_vnic *vnic;
137 struct usnic_ib_qp_grp *qp_grp;
138 struct device *dev, **dev_list;
139 int i, found = 0;
140
141 BUG_ON(!mutex_is_locked(&us_ibdev->usdev_lock));
142
143 if (list_empty(&us_ibdev->vf_dev_list)) {
144 usnic_info("No vfs to allocate\n");
145 return NULL;
146 }
147
148 if (usnic_ib_share_vf) {
149 /* Try to find resouces on a used vf which is in pd */
150 dev_list = usnic_uiom_get_dev_list(pd->umem_pd);
151 for (i = 0; dev_list[i]; i++) {
152 dev = dev_list[i];
153 vf = pci_get_drvdata(to_pci_dev(dev));
154 spin_lock(&vf->lock);
155 vnic = vf->vnic;
156 if (!usnic_vnic_check_room(vnic, res_spec)) {
157 usnic_dbg("Found used vnic %s from %s\n",
158 us_ibdev->ib_dev.name,
159 pci_name(usnic_vnic_get_pdev(
160 vnic)));
161 found = 1;
162 break;
163 }
164 spin_unlock(&vf->lock);
165
166 }
167 usnic_uiom_free_dev_list(dev_list);
168 }
169
170 if (!found) {
171 /* Try to find resources on an unused vf */
172 list_for_each_entry(vf, &us_ibdev->vf_dev_list, link) {
173 spin_lock(&vf->lock);
174 vnic = vf->vnic;
175 if (vf->qp_grp_ref_cnt == 0 &&
176 usnic_vnic_check_room(vnic, res_spec) == 0) {
177 found = 1;
178 break;
179 }
180 spin_unlock(&vf->lock);
181 }
182 }
183
184 if (!found) {
185 usnic_info("No free qp grp found on %s\n",
186 us_ibdev->ib_dev.name);
187 return ERR_PTR(-ENOMEM);
188 }
189
190 qp_grp = usnic_ib_qp_grp_create(us_ibdev->ufdev, vf, pd, res_spec,
191 trans_spec);
192 spin_unlock(&vf->lock);
193 if (IS_ERR_OR_NULL(qp_grp)) {
194 usnic_err("Failed to allocate qp_grp\n");
195 return ERR_PTR(qp_grp ? PTR_ERR(qp_grp) : -ENOMEM);
196 }
197
198 return qp_grp;
199}
200
201static void qp_grp_destroy(struct usnic_ib_qp_grp *qp_grp)
202{
203 struct usnic_ib_vf *vf = qp_grp->vf;
204
205 WARN_ON(qp_grp->state != IB_QPS_RESET);
206
207 spin_lock(&vf->lock);
208 usnic_ib_qp_grp_destroy(qp_grp);
209 spin_unlock(&vf->lock);
210}
211
212static void eth_speed_to_ib_speed(int speed, u8 *active_speed,
213 u8 *active_width)
214{
215 if (speed <= 10000) {
216 *active_width = IB_WIDTH_1X;
217 *active_speed = IB_SPEED_FDR10;
218 } else if (speed <= 20000) {
219 *active_width = IB_WIDTH_4X;
220 *active_speed = IB_SPEED_DDR;
221 } else if (speed <= 30000) {
222 *active_width = IB_WIDTH_4X;
223 *active_speed = IB_SPEED_QDR;
224 } else if (speed <= 40000) {
225 *active_width = IB_WIDTH_4X;
226 *active_speed = IB_SPEED_FDR10;
227 } else {
228 *active_width = IB_WIDTH_4X;
229 *active_speed = IB_SPEED_EDR;
230 }
231}
232
233static int create_qp_validate_user_data(struct usnic_ib_create_qp_cmd cmd)
234{
235 if (cmd.spec.trans_type <= USNIC_TRANSPORT_UNKNOWN ||
236 cmd.spec.trans_type >= USNIC_TRANSPORT_MAX)
237 return -EINVAL;
238
239 return 0;
240}
241
242/* Start of ib callback functions */
243
244enum rdma_link_layer usnic_ib_port_link_layer(struct ib_device *device,
245 u8 port_num)
246{
247 return IB_LINK_LAYER_ETHERNET;
248}
249
250int usnic_ib_query_device(struct ib_device *ibdev,
251 struct ib_device_attr *props)
252{
253 struct usnic_ib_dev *us_ibdev = to_usdev(ibdev);
254 union ib_gid gid;
255 struct ethtool_drvinfo info;
256 struct ethtool_cmd cmd;
257 int qp_per_vf;
258
259 usnic_dbg("\n");
260 mutex_lock(&us_ibdev->usdev_lock);
261 us_ibdev->netdev->ethtool_ops->get_drvinfo(us_ibdev->netdev, &info);
262 us_ibdev->netdev->ethtool_ops->get_settings(us_ibdev->netdev, &cmd);
263 memset(props, 0, sizeof(*props));
264 usnic_mac_ip_to_gid(us_ibdev->ufdev->mac, us_ibdev->ufdev->inaddr,
265 &gid.raw[0]);
266 memcpy(&props->sys_image_guid, &gid.global.interface_id,
267 sizeof(gid.global.interface_id));
268 usnic_ib_fw_string_to_u64(&info.fw_version[0], &props->fw_ver);
269 props->max_mr_size = USNIC_UIOM_MAX_MR_SIZE;
270 props->page_size_cap = USNIC_UIOM_PAGE_SIZE;
271 props->vendor_id = PCI_VENDOR_ID_CISCO;
272 props->vendor_part_id = PCI_DEVICE_ID_CISCO_VIC_USPACE_NIC;
273 props->hw_ver = us_ibdev->pdev->subsystem_device;
274 qp_per_vf = max(us_ibdev->vf_res_cnt[USNIC_VNIC_RES_TYPE_WQ],
275 us_ibdev->vf_res_cnt[USNIC_VNIC_RES_TYPE_RQ]);
276 props->max_qp = qp_per_vf *
277 atomic_read(&us_ibdev->vf_cnt.refcount);
278 props->device_cap_flags = IB_DEVICE_PORT_ACTIVE_EVENT |
279 IB_DEVICE_SYS_IMAGE_GUID | IB_DEVICE_BLOCK_MULTICAST_LOOPBACK;
280 props->max_cq = us_ibdev->vf_res_cnt[USNIC_VNIC_RES_TYPE_CQ] *
281 atomic_read(&us_ibdev->vf_cnt.refcount);
282 props->max_pd = USNIC_UIOM_MAX_PD_CNT;
283 props->max_mr = USNIC_UIOM_MAX_MR_CNT;
284 props->local_ca_ack_delay = 0;
285 props->max_pkeys = 0;
286 props->atomic_cap = IB_ATOMIC_NONE;
287 props->masked_atomic_cap = props->atomic_cap;
288 props->max_qp_rd_atom = 0;
289 props->max_qp_init_rd_atom = 0;
290 props->max_res_rd_atom = 0;
291 props->max_srq = 0;
292 props->max_srq_wr = 0;
293 props->max_srq_sge = 0;
294 props->max_fast_reg_page_list_len = 0;
295 props->max_mcast_grp = 0;
296 props->max_mcast_qp_attach = 0;
297 props->max_total_mcast_qp_attach = 0;
298 props->max_map_per_fmr = 0;
299 /* Owned by Userspace
300 * max_qp_wr, max_sge, max_sge_rd, max_cqe */
301 mutex_unlock(&us_ibdev->usdev_lock);
302
303 return 0;
304}
305
306int usnic_ib_query_port(struct ib_device *ibdev, u8 port,
307 struct ib_port_attr *props)
308{
309 struct usnic_ib_dev *us_ibdev = to_usdev(ibdev);
310 struct ethtool_cmd cmd;
311
312 usnic_dbg("\n");
313
314 mutex_lock(&us_ibdev->usdev_lock);
315 us_ibdev->netdev->ethtool_ops->get_settings(us_ibdev->netdev, &cmd);
316 memset(props, 0, sizeof(*props));
317
318 props->lid = 0;
319 props->lmc = 1;
320 props->sm_lid = 0;
321 props->sm_sl = 0;
322
323 if (!us_ibdev->ufdev->link_up) {
324 props->state = IB_PORT_DOWN;
325 props->phys_state = 3;
326 } else if (!us_ibdev->ufdev->inaddr) {
327 props->state = IB_PORT_INIT;
328 props->phys_state = 4;
329 } else {
330 props->state = IB_PORT_ACTIVE;
331 props->phys_state = 5;
332 }
333
334 props->port_cap_flags = 0;
335 props->gid_tbl_len = 1;
336 props->pkey_tbl_len = 1;
337 props->bad_pkey_cntr = 0;
338 props->qkey_viol_cntr = 0;
339 eth_speed_to_ib_speed(cmd.speed, &props->active_speed,
340 &props->active_width);
341 props->max_mtu = IB_MTU_4096;
342 props->active_mtu = iboe_get_mtu(us_ibdev->ufdev->mtu);
343 /* Userspace will adjust for hdrs */
344 props->max_msg_sz = us_ibdev->ufdev->mtu;
345 props->max_vl_num = 1;
346 mutex_unlock(&us_ibdev->usdev_lock);
347
348 return 0;
349}
350
351int usnic_ib_query_qp(struct ib_qp *qp, struct ib_qp_attr *qp_attr,
352 int qp_attr_mask,
353 struct ib_qp_init_attr *qp_init_attr)
354{
355 struct usnic_ib_qp_grp *qp_grp;
356 struct usnic_ib_vf *vf;
357 int err;
358
359 usnic_dbg("\n");
360
361 memset(qp_attr, 0, sizeof(*qp_attr));
362 memset(qp_init_attr, 0, sizeof(*qp_init_attr));
363
364 qp_grp = to_uqp_grp(qp);
365 vf = qp_grp->vf;
366 mutex_lock(&vf->pf->usdev_lock);
367 usnic_dbg("\n");
368 qp_attr->qp_state = qp_grp->state;
369 qp_attr->cur_qp_state = qp_grp->state;
370
371 switch (qp_grp->ibqp.qp_type) {
372 case IB_QPT_UD:
373 qp_attr->qkey = 0;
374 break;
375 default:
376 usnic_err("Unexpected qp_type %d\n", qp_grp->ibqp.qp_type);
377 err = -EINVAL;
378 goto err_out;
379 }
380
381 mutex_unlock(&vf->pf->usdev_lock);
382 return 0;
383
384err_out:
385 mutex_unlock(&vf->pf->usdev_lock);
386 return err;
387}
388
389int usnic_ib_query_gid(struct ib_device *ibdev, u8 port, int index,
390 union ib_gid *gid)
391{
392
393 struct usnic_ib_dev *us_ibdev = to_usdev(ibdev);
394 usnic_dbg("\n");
395
396 if (index > 1)
397 return -EINVAL;
398
399 mutex_lock(&us_ibdev->usdev_lock);
400 memset(&(gid->raw[0]), 0, sizeof(gid->raw));
401 usnic_mac_ip_to_gid(us_ibdev->ufdev->mac, us_ibdev->ufdev->inaddr,
402 &gid->raw[0]);
403 mutex_unlock(&us_ibdev->usdev_lock);
404
405 return 0;
406}
407
408int usnic_ib_query_pkey(struct ib_device *ibdev, u8 port, u16 index,
409 u16 *pkey)
410{
411 if (index > 1)
412 return -EINVAL;
413
414 *pkey = 0xffff;
415 return 0;
416}
417
418struct ib_pd *usnic_ib_alloc_pd(struct ib_device *ibdev,
419 struct ib_ucontext *context,
420 struct ib_udata *udata)
421{
422 struct usnic_ib_pd *pd;
423 void *umem_pd;
424
425 usnic_dbg("\n");
426
427 pd = kzalloc(sizeof(*pd), GFP_KERNEL);
428 if (!pd)
429 return ERR_PTR(-ENOMEM);
430
431 umem_pd = pd->umem_pd = usnic_uiom_alloc_pd();
432 if (IS_ERR_OR_NULL(umem_pd)) {
433 kfree(pd);
434 return ERR_PTR(umem_pd ? PTR_ERR(umem_pd) : -ENOMEM);
435 }
436
437 usnic_info("domain 0x%p allocated for context 0x%p and device %s\n",
438 pd, context, ibdev->name);
439 return &pd->ibpd;
440}
441
442int usnic_ib_dealloc_pd(struct ib_pd *pd)
443{
444 usnic_info("freeing domain 0x%p\n", pd);
445
446 usnic_uiom_dealloc_pd((to_upd(pd))->umem_pd);
447 kfree(pd);
448 return 0;
449}
450
451struct ib_qp *usnic_ib_create_qp(struct ib_pd *pd,
452 struct ib_qp_init_attr *init_attr,
453 struct ib_udata *udata)
454{
455 int err;
456 struct usnic_ib_dev *us_ibdev;
457 struct usnic_ib_qp_grp *qp_grp;
458 struct usnic_ib_ucontext *ucontext;
459 int cq_cnt;
460 struct usnic_vnic_res_spec res_spec;
461 struct usnic_ib_create_qp_cmd cmd;
462 struct usnic_transport_spec trans_spec;
463
464 usnic_dbg("\n");
465
466 ucontext = to_uucontext(pd->uobject->context);
467 us_ibdev = to_usdev(pd->device);
468
469 err = ib_copy_from_udata(&cmd, udata, sizeof(cmd));
470 if (err) {
471 usnic_err("%s: cannot copy udata for create_qp\n",
472 us_ibdev->ib_dev.name);
473 return ERR_PTR(-EINVAL);
474 }
475
476 err = create_qp_validate_user_data(cmd);
477 if (err) {
478 usnic_err("%s: Failed to validate user data\n",
479 us_ibdev->ib_dev.name);
480 return ERR_PTR(-EINVAL);
481 }
482
483 if (init_attr->qp_type != IB_QPT_UD) {
484 usnic_err("%s asked to make a non-UD QP: %d\n",
485 us_ibdev->ib_dev.name, init_attr->qp_type);
486 return ERR_PTR(-EINVAL);
487 }
488
489 trans_spec = cmd.spec;
490 mutex_lock(&us_ibdev->usdev_lock);
491 cq_cnt = (init_attr->send_cq == init_attr->recv_cq) ? 1 : 2;
492 res_spec = min_transport_spec[trans_spec.trans_type];
493 usnic_vnic_res_spec_update(&res_spec, USNIC_VNIC_RES_TYPE_CQ, cq_cnt);
494 qp_grp = find_free_vf_and_create_qp_grp(us_ibdev, to_upd(pd),
495 &trans_spec,
496 &res_spec);
497 if (IS_ERR_OR_NULL(qp_grp)) {
498 err = qp_grp ? PTR_ERR(qp_grp) : -ENOMEM;
499 goto out_release_mutex;
500 }
501
502 err = usnic_ib_fill_create_qp_resp(qp_grp, udata);
503 if (err) {
504 err = -EBUSY;
505 goto out_release_qp_grp;
506 }
507
508 qp_grp->ctx = ucontext;
509 list_add_tail(&qp_grp->link, &ucontext->qp_grp_list);
510 usnic_ib_log_vf(qp_grp->vf);
511 mutex_unlock(&us_ibdev->usdev_lock);
512 return &qp_grp->ibqp;
513
514out_release_qp_grp:
515 qp_grp_destroy(qp_grp);
516out_release_mutex:
517 mutex_unlock(&us_ibdev->usdev_lock);
518 return ERR_PTR(err);
519}
520
521int usnic_ib_destroy_qp(struct ib_qp *qp)
522{
523 struct usnic_ib_qp_grp *qp_grp;
524 struct usnic_ib_vf *vf;
525
526 usnic_dbg("\n");
527
528 qp_grp = to_uqp_grp(qp);
529 vf = qp_grp->vf;
530 mutex_lock(&vf->pf->usdev_lock);
531 if (usnic_ib_qp_grp_modify(qp_grp, IB_QPS_RESET, NULL)) {
532 usnic_err("Failed to move qp grp %u to reset\n",
533 qp_grp->grp_id);
534 }
535
536 list_del(&qp_grp->link);
537 qp_grp_destroy(qp_grp);
538 mutex_unlock(&vf->pf->usdev_lock);
539
540 return 0;
541}
542
543int usnic_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
544 int attr_mask, struct ib_udata *udata)
545{
546 struct usnic_ib_qp_grp *qp_grp;
547 int status;
548 usnic_dbg("\n");
549
550 qp_grp = to_uqp_grp(ibqp);
551
552 /* TODO: Future Support All States */
553 mutex_lock(&qp_grp->vf->pf->usdev_lock);
554 if ((attr_mask & IB_QP_STATE) && attr->qp_state == IB_QPS_INIT) {
555 status = usnic_ib_qp_grp_modify(qp_grp, IB_QPS_INIT, NULL);
556 } else if ((attr_mask & IB_QP_STATE) && attr->qp_state == IB_QPS_RTR) {
557 status = usnic_ib_qp_grp_modify(qp_grp, IB_QPS_RTR, NULL);
558 } else if ((attr_mask & IB_QP_STATE) && attr->qp_state == IB_QPS_RTS) {
559 status = usnic_ib_qp_grp_modify(qp_grp, IB_QPS_RTS, NULL);
560 } else {
561 usnic_err("Unexpected combination mask: %u state: %u\n",
562 attr_mask & IB_QP_STATE, attr->qp_state);
563 status = -EINVAL;
564 }
565
566 mutex_unlock(&qp_grp->vf->pf->usdev_lock);
567 return status;
568}
569
570struct ib_cq *usnic_ib_create_cq(struct ib_device *ibdev, int entries,
571 int vector, struct ib_ucontext *context,
572 struct ib_udata *udata)
573{
574 struct ib_cq *cq;
575
576 usnic_dbg("\n");
577 cq = kzalloc(sizeof(*cq), GFP_KERNEL);
578 if (!cq)
579 return ERR_PTR(-EBUSY);
580
581 return cq;
582}
583
584int usnic_ib_destroy_cq(struct ib_cq *cq)
585{
586 usnic_dbg("\n");
587 kfree(cq);
588 return 0;
589}
590
591struct ib_mr *usnic_ib_reg_mr(struct ib_pd *pd, u64 start, u64 length,
592 u64 virt_addr, int access_flags,
593 struct ib_udata *udata)
594{
595 struct usnic_ib_mr *mr;
596 int err;
597
598 usnic_dbg("start 0x%llx va 0x%llx length 0x%llx\n", start,
599 virt_addr, length);
600
601 mr = kzalloc(sizeof(*mr), GFP_KERNEL);
602 if (IS_ERR_OR_NULL(mr))
603 return ERR_PTR(mr ? PTR_ERR(mr) : -ENOMEM);
604
605 mr->umem = usnic_uiom_reg_get(to_upd(pd)->umem_pd, start, length,
606 access_flags, 0);
607 if (IS_ERR_OR_NULL(mr->umem)) {
608 err = mr->umem ? PTR_ERR(mr->umem) : -EFAULT;
609 goto err_free;
610 }
611
612 mr->ibmr.lkey = mr->ibmr.rkey = 0;
613 return &mr->ibmr;
614
615err_free:
616 kfree(mr);
617 return ERR_PTR(err);
618}
619
620int usnic_ib_dereg_mr(struct ib_mr *ibmr)
621{
622 struct usnic_ib_mr *mr = to_umr(ibmr);
623
624 usnic_dbg("va 0x%lx length 0x%zx\n", mr->umem->va, mr->umem->length);
625
626 usnic_uiom_reg_release(mr->umem, ibmr->pd->uobject->context->closing);
627 kfree(mr);
628 return 0;
629}
630
631struct ib_ucontext *usnic_ib_alloc_ucontext(struct ib_device *ibdev,
632 struct ib_udata *udata)
633{
634 struct usnic_ib_ucontext *context;
635 struct usnic_ib_dev *us_ibdev = to_usdev(ibdev);
636 usnic_dbg("\n");
637
638 context = kmalloc(sizeof(*context), GFP_KERNEL);
639 if (!context)
640 return ERR_PTR(-ENOMEM);
641
642 INIT_LIST_HEAD(&context->qp_grp_list);
643 mutex_lock(&us_ibdev->usdev_lock);
644 list_add_tail(&context->link, &us_ibdev->ctx_list);
645 mutex_unlock(&us_ibdev->usdev_lock);
646
647 return &context->ibucontext;
648}
649
650int usnic_ib_dealloc_ucontext(struct ib_ucontext *ibcontext)
651{
652 struct usnic_ib_ucontext *context = to_uucontext(ibcontext);
653 struct usnic_ib_dev *us_ibdev = to_usdev(ibcontext->device);
654 usnic_dbg("\n");
655
656 mutex_lock(&us_ibdev->usdev_lock);
657 BUG_ON(!list_empty(&context->qp_grp_list));
658 list_del(&context->link);
659 mutex_unlock(&us_ibdev->usdev_lock);
660 kfree(context);
661 return 0;
662}
663
664int usnic_ib_mmap(struct ib_ucontext *context,
665 struct vm_area_struct *vma)
666{
667 struct usnic_ib_ucontext *uctx = to_ucontext(context);
668 struct usnic_ib_dev *us_ibdev;
669 struct usnic_ib_qp_grp *qp_grp;
670 struct usnic_ib_vf *vf;
671 struct vnic_dev_bar *bar;
672 dma_addr_t bus_addr;
673 unsigned int len;
674 unsigned int vfid;
675
676 usnic_dbg("\n");
677
678 us_ibdev = to_usdev(context->device);
679 vma->vm_flags |= VM_IO;
680 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
681 vfid = vma->vm_pgoff;
682 usnic_dbg("Page Offset %lu PAGE_SHIFT %u VFID %u\n",
683 vma->vm_pgoff, PAGE_SHIFT, vfid);
684
685 mutex_lock(&us_ibdev->usdev_lock);
686 list_for_each_entry(qp_grp, &uctx->qp_grp_list, link) {
687 vf = qp_grp->vf;
688 if (usnic_vnic_get_index(vf->vnic) == vfid) {
689 bar = usnic_vnic_get_bar(vf->vnic, 0);
690 if ((vma->vm_end - vma->vm_start) != bar->len) {
691 usnic_err("Bar0 Len %lu - Request map %lu\n",
692 bar->len,
693 vma->vm_end - vma->vm_start);
694 mutex_unlock(&us_ibdev->usdev_lock);
695 return -EINVAL;
696 }
697 bus_addr = bar->bus_addr;
698 len = bar->len;
699 usnic_dbg("bus: %pa vaddr: %p size: %ld\n",
700 &bus_addr, bar->vaddr, bar->len);
701 mutex_unlock(&us_ibdev->usdev_lock);
702
703 return remap_pfn_range(vma,
704 vma->vm_start,
705 bus_addr >> PAGE_SHIFT,
706 len, vma->vm_page_prot);
707 }
708 }
709
710 mutex_unlock(&us_ibdev->usdev_lock);
711 usnic_err("No VF %u found\n", vfid);
712 return -EINVAL;
713}
714
715/* In ib callbacks section - Start of stub funcs */
716struct ib_ah *usnic_ib_create_ah(struct ib_pd *pd,
717 struct ib_ah_attr *ah_attr)
718{
719 usnic_dbg("\n");
720 return ERR_PTR(-EPERM);
721}
722
723int usnic_ib_destroy_ah(struct ib_ah *ah)
724{
725 usnic_dbg("\n");
726 return -EINVAL;
727}
728
729int usnic_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
730 struct ib_send_wr **bad_wr)
731{
732 usnic_dbg("\n");
733 return -EINVAL;
734}
735
736int usnic_ib_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,
737 struct ib_recv_wr **bad_wr)
738{
739 usnic_dbg("\n");
740 return -EINVAL;
741}
742
743int usnic_ib_poll_cq(struct ib_cq *ibcq, int num_entries,
744 struct ib_wc *wc)
745{
746 usnic_dbg("\n");
747 return -EINVAL;
748}
749
750int usnic_ib_req_notify_cq(struct ib_cq *cq,
751 enum ib_cq_notify_flags flags)
752{
753 usnic_dbg("\n");
754 return -EINVAL;
755}
756
757struct ib_mr *usnic_ib_get_dma_mr(struct ib_pd *pd, int acc)
758{
759 usnic_dbg("\n");
760 return ERR_PTR(-ENOMEM);
761}
762
763
764/* In ib callbacks section - End of stub funcs */
765/* End of ib callbacks section */
diff --git a/drivers/infiniband/hw/usnic/usnic_ib_verbs.h b/drivers/infiniband/hw/usnic/usnic_ib_verbs.h
new file mode 100644
index 000000000000..bb864f5aed70
--- /dev/null
+++ b/drivers/infiniband/hw/usnic/usnic_ib_verbs.h
@@ -0,0 +1,72 @@
1/*
2 * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
3 *
4 * This program is free software; you may redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
15 * SOFTWARE.
16 *
17 */
18
19#ifndef USNIC_IB_VERBS_H_
20#define USNIC_IB_VERBS_H_
21
22#include "usnic_ib.h"
23
24enum rdma_link_layer usnic_ib_port_link_layer(struct ib_device *device,
25 u8 port_num);
26int usnic_ib_query_device(struct ib_device *ibdev,
27 struct ib_device_attr *props);
28int usnic_ib_query_port(struct ib_device *ibdev, u8 port,
29 struct ib_port_attr *props);
30int usnic_ib_query_qp(struct ib_qp *qp, struct ib_qp_attr *qp_attr,
31 int qp_attr_mask,
32 struct ib_qp_init_attr *qp_init_attr);
33int usnic_ib_query_gid(struct ib_device *ibdev, u8 port, int index,
34 union ib_gid *gid);
35int usnic_ib_query_pkey(struct ib_device *ibdev, u8 port, u16 index,
36 u16 *pkey);
37struct ib_pd *usnic_ib_alloc_pd(struct ib_device *ibdev,
38 struct ib_ucontext *context,
39 struct ib_udata *udata);
40int usnic_ib_dealloc_pd(struct ib_pd *pd);
41struct ib_qp *usnic_ib_create_qp(struct ib_pd *pd,
42 struct ib_qp_init_attr *init_attr,
43 struct ib_udata *udata);
44int usnic_ib_destroy_qp(struct ib_qp *qp);
45int usnic_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
46 int attr_mask, struct ib_udata *udata);
47struct ib_cq *usnic_ib_create_cq(struct ib_device *ibdev, int entries,
48 int vector, struct ib_ucontext *context,
49 struct ib_udata *udata);
50int usnic_ib_destroy_cq(struct ib_cq *cq);
51struct ib_mr *usnic_ib_reg_mr(struct ib_pd *pd, u64 start, u64 length,
52 u64 virt_addr, int access_flags,
53 struct ib_udata *udata);
54int usnic_ib_dereg_mr(struct ib_mr *ibmr);
55struct ib_ucontext *usnic_ib_alloc_ucontext(struct ib_device *ibdev,
56 struct ib_udata *udata);
57int usnic_ib_dealloc_ucontext(struct ib_ucontext *ibcontext);
58int usnic_ib_mmap(struct ib_ucontext *context,
59 struct vm_area_struct *vma);
60struct ib_ah *usnic_ib_create_ah(struct ib_pd *pd,
61 struct ib_ah_attr *ah_attr);
62int usnic_ib_destroy_ah(struct ib_ah *ah);
63int usnic_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
64 struct ib_send_wr **bad_wr);
65int usnic_ib_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,
66 struct ib_recv_wr **bad_wr);
67int usnic_ib_poll_cq(struct ib_cq *ibcq, int num_entries,
68 struct ib_wc *wc);
69int usnic_ib_req_notify_cq(struct ib_cq *cq,
70 enum ib_cq_notify_flags flags);
71struct ib_mr *usnic_ib_get_dma_mr(struct ib_pd *pd, int acc);
72#endif /* !USNIC_IB_VERBS_H */
diff --git a/drivers/infiniband/hw/usnic/usnic_log.h b/drivers/infiniband/hw/usnic/usnic_log.h
new file mode 100644
index 000000000000..75777a66c684
--- /dev/null
+++ b/drivers/infiniband/hw/usnic/usnic_log.h
@@ -0,0 +1,58 @@
1/*
2 * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
3 *
4 * This program is free software; you may redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
15 * SOFTWARE.
16 *
17 */
18
19#ifndef USNIC_LOG_H_
20#define USNIC_LOG_H_
21
22#include "usnic.h"
23
24extern unsigned int usnic_log_lvl;
25
26#define USNIC_LOG_LVL_NONE (0)
27#define USNIC_LOG_LVL_ERR (1)
28#define USNIC_LOG_LVL_INFO (2)
29#define USNIC_LOG_LVL_DBG (3)
30
31#define usnic_printk(lvl, args...) \
32 do { \
33 printk(lvl "%s:%s:%d: ", DRV_NAME, __func__, \
34 __LINE__); \
35 printk(args); \
36 } while (0)
37
38#define usnic_dbg(args...) \
39 do { \
40 if (unlikely(usnic_log_lvl >= USNIC_LOG_LVL_DBG)) { \
41 usnic_printk(KERN_INFO, args); \
42 } \
43} while (0)
44
45#define usnic_info(args...) \
46do { \
47 if (usnic_log_lvl >= USNIC_LOG_LVL_INFO) { \
48 usnic_printk(KERN_INFO, args); \
49 } \
50} while (0)
51
52#define usnic_err(args...) \
53 do { \
54 if (usnic_log_lvl >= USNIC_LOG_LVL_ERR) { \
55 usnic_printk(KERN_ERR, args); \
56 } \
57 } while (0)
58#endif /* !USNIC_LOG_H_ */
diff --git a/drivers/infiniband/hw/usnic/usnic_transport.c b/drivers/infiniband/hw/usnic/usnic_transport.c
new file mode 100644
index 000000000000..ddef6f77a78c
--- /dev/null
+++ b/drivers/infiniband/hw/usnic/usnic_transport.c
@@ -0,0 +1,202 @@
1/*
2 * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
3 *
4 * This program is free software; you may redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
15 * SOFTWARE.
16 *
17 */
18#include <linux/bitmap.h>
19#include <linux/file.h>
20#include <linux/module.h>
21#include <linux/slab.h>
22#include <net/inet_sock.h>
23
24#include "usnic_transport.h"
25#include "usnic_log.h"
26
27/* ROCE */
28static unsigned long *roce_bitmap;
29static u16 roce_next_port = 1;
30#define ROCE_BITMAP_SZ ((1 << (8 /*CHAR_BIT*/ * sizeof(u16)))/8 /*CHAR BIT*/)
31static DEFINE_SPINLOCK(roce_bitmap_lock);
32
33const char *usnic_transport_to_str(enum usnic_transport_type type)
34{
35 switch (type) {
36 case USNIC_TRANSPORT_UNKNOWN:
37 return "Unknown";
38 case USNIC_TRANSPORT_ROCE_CUSTOM:
39 return "roce custom";
40 case USNIC_TRANSPORT_IPV4_UDP:
41 return "IPv4 UDP";
42 case USNIC_TRANSPORT_MAX:
43 return "Max?";
44 default:
45 return "Not known";
46 }
47}
48
49int usnic_transport_sock_to_str(char *buf, int buf_sz,
50 struct socket *sock)
51{
52 int err;
53 uint32_t addr;
54 uint16_t port;
55 int proto;
56
57 memset(buf, 0, buf_sz);
58 err = usnic_transport_sock_get_addr(sock, &proto, &addr, &port);
59 if (err)
60 return 0;
61
62 return scnprintf(buf, buf_sz, "Proto:%u Addr:%pI4h Port:%hu",
63 proto, &addr, port);
64}
65
66/*
67 * reserve a port number. if "0" specified, we will try to pick one
68 * starting at roce_next_port. roce_next_port will take on the values
69 * 1..4096
70 */
71u16 usnic_transport_rsrv_port(enum usnic_transport_type type, u16 port_num)
72{
73 if (type == USNIC_TRANSPORT_ROCE_CUSTOM) {
74 spin_lock(&roce_bitmap_lock);
75 if (!port_num) {
76 port_num = bitmap_find_next_zero_area(roce_bitmap,
77 ROCE_BITMAP_SZ,
78 roce_next_port /* start */,
79 1 /* nr */,
80 0 /* align */);
81 roce_next_port = (port_num & 4095) + 1;
82 } else if (test_bit(port_num, roce_bitmap)) {
83 usnic_err("Failed to allocate port for %s\n",
84 usnic_transport_to_str(type));
85 spin_unlock(&roce_bitmap_lock);
86 goto out_fail;
87 }
88 bitmap_set(roce_bitmap, port_num, 1);
89 spin_unlock(&roce_bitmap_lock);
90 } else {
91 usnic_err("Failed to allocate port - transport %s unsupported\n",
92 usnic_transport_to_str(type));
93 goto out_fail;
94 }
95
96 usnic_dbg("Allocating port %hu for %s\n", port_num,
97 usnic_transport_to_str(type));
98 return port_num;
99
100out_fail:
101 return 0;
102}
103
104void usnic_transport_unrsrv_port(enum usnic_transport_type type, u16 port_num)
105{
106 if (type == USNIC_TRANSPORT_ROCE_CUSTOM) {
107 spin_lock(&roce_bitmap_lock);
108 if (!port_num) {
109 usnic_err("Unreserved unvalid port num 0 for %s\n",
110 usnic_transport_to_str(type));
111 goto out_roce_custom;
112 }
113
114 if (!test_bit(port_num, roce_bitmap)) {
115 usnic_err("Unreserving invalid %hu for %s\n",
116 port_num,
117 usnic_transport_to_str(type));
118 goto out_roce_custom;
119 }
120 bitmap_clear(roce_bitmap, port_num, 1);
121 usnic_dbg("Freeing port %hu for %s\n", port_num,
122 usnic_transport_to_str(type));
123out_roce_custom:
124 spin_unlock(&roce_bitmap_lock);
125 } else {
126 usnic_err("Freeing invalid port %hu for %d\n", port_num, type);
127 }
128}
129
130struct socket *usnic_transport_get_socket(int sock_fd)
131{
132 struct socket *sock;
133 int err;
134 char buf[25];
135
136 /* sockfd_lookup will internally do a fget */
137 sock = sockfd_lookup(sock_fd, &err);
138 if (!sock) {
139 usnic_err("Unable to lookup socket for fd %d with err %d\n",
140 sock_fd, err);
141 return ERR_PTR(-ENOENT);
142 }
143
144 usnic_transport_sock_to_str(buf, sizeof(buf), sock);
145 usnic_dbg("Get sock %s\n", buf);
146
147 return sock;
148}
149
150void usnic_transport_put_socket(struct socket *sock)
151{
152 char buf[100];
153
154 usnic_transport_sock_to_str(buf, sizeof(buf), sock);
155 usnic_dbg("Put sock %s\n", buf);
156 sockfd_put(sock);
157}
158
159int usnic_transport_sock_get_addr(struct socket *sock, int *proto,
160 uint32_t *addr, uint16_t *port)
161{
162 int len;
163 int err;
164 struct sockaddr_in sock_addr;
165
166 err = sock->ops->getname(sock,
167 (struct sockaddr *)&sock_addr,
168 &len, 0);
169 if (err)
170 return err;
171
172 if (sock_addr.sin_family != AF_INET)
173 return -EINVAL;
174
175 if (proto)
176 *proto = sock->sk->sk_protocol;
177 if (port)
178 *port = ntohs(((struct sockaddr_in *)&sock_addr)->sin_port);
179 if (addr)
180 *addr = ntohl(((struct sockaddr_in *)
181 &sock_addr)->sin_addr.s_addr);
182
183 return 0;
184}
185
186int usnic_transport_init(void)
187{
188 roce_bitmap = kzalloc(ROCE_BITMAP_SZ, GFP_KERNEL);
189 if (!roce_bitmap) {
190 usnic_err("Failed to allocate bit map");
191 return -ENOMEM;
192 }
193
194 /* Do not ever allocate bit 0, hence set it here */
195 bitmap_set(roce_bitmap, 0, 1);
196 return 0;
197}
198
199void usnic_transport_fini(void)
200{
201 kfree(roce_bitmap);
202}
diff --git a/drivers/infiniband/hw/usnic/usnic_transport.h b/drivers/infiniband/hw/usnic/usnic_transport.h
new file mode 100644
index 000000000000..7e5dc6d9f462
--- /dev/null
+++ b/drivers/infiniband/hw/usnic/usnic_transport.h
@@ -0,0 +1,51 @@
1/*
2 * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
3 *
4 * This program is free software; you may redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
15 * SOFTWARE.
16 *
17 */
18
19#ifndef USNIC_TRANSPORT_H_
20#define USNIC_TRANSPORT_H_
21
22#include "usnic_abi.h"
23
24const char *usnic_transport_to_str(enum usnic_transport_type trans_type);
25/*
26 * Returns number of bytes written, excluding null terminator. If
27 * nothing was written, the function returns 0.
28 */
29int usnic_transport_sock_to_str(char *buf, int buf_sz,
30 struct socket *sock);
31/*
32 * Reserve a port. If "port_num" is set, then the function will try
33 * to reserve that particular port.
34 */
35u16 usnic_transport_rsrv_port(enum usnic_transport_type type, u16 port_num);
36void usnic_transport_unrsrv_port(enum usnic_transport_type type, u16 port_num);
37/*
38 * Do a fget on the socket refered to by sock_fd and returns the socket.
39 * Socket will not be destroyed before usnic_transport_put_socket has
40 * been called.
41 */
42struct socket *usnic_transport_get_socket(int sock_fd);
43void usnic_transport_put_socket(struct socket *sock);
44/*
45 * Call usnic_transport_get_socket before calling *_sock_get_addr
46 */
47int usnic_transport_sock_get_addr(struct socket *sock, int *proto,
48 uint32_t *addr, uint16_t *port);
49int usnic_transport_init(void);
50void usnic_transport_fini(void);
51#endif /* !USNIC_TRANSPORT_H */
diff --git a/drivers/infiniband/hw/usnic/usnic_uiom.c b/drivers/infiniband/hw/usnic/usnic_uiom.c
new file mode 100644
index 000000000000..16755cdab2c0
--- /dev/null
+++ b/drivers/infiniband/hw/usnic/usnic_uiom.c
@@ -0,0 +1,604 @@
1/*
2 * Copyright (c) 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
4 * Copyright (c) 2013 Cisco Systems. All rights reserved.
5 *
6 * This software is available to you under a choice of one of two
7 * licenses. You may choose to be licensed under the terms of the GNU
8 * General Public License (GPL) Version 2, available from the file
9 * COPYING in the main directory of this source tree, or the
10 * OpenIB.org BSD license below:
11 *
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
14 * conditions are met:
15 *
16 * - Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
18 * disclaimer.
19 *
20 * - Redistributions in binary form must reproduce the above
21 * copyright notice, this list of conditions and the following
22 * disclaimer in the documentation and/or other materials
23 * provided with the distribution.
24 *
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 * SOFTWARE.
33 */
34
35#include <linux/mm.h>
36#include <linux/dma-mapping.h>
37#include <linux/sched.h>
38#include <linux/hugetlb.h>
39#include <linux/dma-attrs.h>
40#include <linux/iommu.h>
41#include <linux/workqueue.h>
42#include <linux/list.h>
43#include <linux/pci.h>
44
45#include "usnic_log.h"
46#include "usnic_uiom.h"
47#include "usnic_uiom_interval_tree.h"
48
49static struct workqueue_struct *usnic_uiom_wq;
50
51#define USNIC_UIOM_PAGE_CHUNK \
52 ((PAGE_SIZE - offsetof(struct usnic_uiom_chunk, page_list)) /\
53 ((void *) &((struct usnic_uiom_chunk *) 0)->page_list[1] - \
54 (void *) &((struct usnic_uiom_chunk *) 0)->page_list[0]))
55
56static void usnic_uiom_reg_account(struct work_struct *work)
57{
58 struct usnic_uiom_reg *umem = container_of(work,
59 struct usnic_uiom_reg, work);
60
61 down_write(&umem->mm->mmap_sem);
62 umem->mm->locked_vm -= umem->diff;
63 up_write(&umem->mm->mmap_sem);
64 mmput(umem->mm);
65 kfree(umem);
66}
67
68static int usnic_uiom_dma_fault(struct iommu_domain *domain,
69 struct device *dev,
70 unsigned long iova, int flags,
71 void *token)
72{
73 usnic_err("Device %s iommu fault domain 0x%pK va 0x%lx flags 0x%x\n",
74 dev_name(dev),
75 domain, iova, flags);
76 return -ENOSYS;
77}
78
79static void usnic_uiom_put_pages(struct list_head *chunk_list, int dirty)
80{
81 struct usnic_uiom_chunk *chunk, *tmp;
82 struct page *page;
83 struct scatterlist *sg;
84 int i;
85 dma_addr_t pa;
86
87 list_for_each_entry_safe(chunk, tmp, chunk_list, list) {
88 for_each_sg(chunk->page_list, sg, chunk->nents, i) {
89 page = sg_page(sg);
90 pa = sg_phys(sg);
91 if (dirty)
92 set_page_dirty_lock(page);
93 put_page(page);
94 usnic_dbg("pa: %pa\n", &pa);
95 }
96 kfree(chunk);
97 }
98}
99
100static int usnic_uiom_get_pages(unsigned long addr, size_t size, int writable,
101 int dmasync, struct list_head *chunk_list)
102{
103 struct page **page_list;
104 struct scatterlist *sg;
105 struct usnic_uiom_chunk *chunk;
106 unsigned long locked;
107 unsigned long lock_limit;
108 unsigned long cur_base;
109 unsigned long npages;
110 int ret;
111 int off;
112 int i;
113 int flags;
114 dma_addr_t pa;
115 DEFINE_DMA_ATTRS(attrs);
116
117 if (dmasync)
118 dma_set_attr(DMA_ATTR_WRITE_BARRIER, &attrs);
119
120 if (!can_do_mlock())
121 return -EPERM;
122
123 INIT_LIST_HEAD(chunk_list);
124
125 page_list = (struct page **) __get_free_page(GFP_KERNEL);
126 if (!page_list)
127 return -ENOMEM;
128
129 npages = PAGE_ALIGN(size + (addr & ~PAGE_MASK)) >> PAGE_SHIFT;
130
131 down_write(&current->mm->mmap_sem);
132
133 locked = npages + current->mm->locked_vm;
134 lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
135
136 if ((locked > lock_limit) && !capable(CAP_IPC_LOCK)) {
137 ret = -ENOMEM;
138 goto out;
139 }
140
141 flags = IOMMU_READ | IOMMU_CACHE;
142 flags |= (writable) ? IOMMU_WRITE : 0;
143 cur_base = addr & PAGE_MASK;
144 ret = 0;
145
146 while (npages) {
147 ret = get_user_pages(current, current->mm, cur_base,
148 min_t(unsigned long, npages,
149 PAGE_SIZE / sizeof(struct page *)),
150 1, !writable, page_list, NULL);
151
152 if (ret < 0)
153 goto out;
154
155 npages -= ret;
156 off = 0;
157
158 while (ret) {
159 chunk = kmalloc(sizeof(*chunk) +
160 sizeof(struct scatterlist) *
161 min_t(int, ret, USNIC_UIOM_PAGE_CHUNK),
162 GFP_KERNEL);
163 if (!chunk) {
164 ret = -ENOMEM;
165 goto out;
166 }
167
168 chunk->nents = min_t(int, ret, USNIC_UIOM_PAGE_CHUNK);
169 sg_init_table(chunk->page_list, chunk->nents);
170 for_each_sg(chunk->page_list, sg, chunk->nents, i) {
171 sg_set_page(sg, page_list[i + off],
172 PAGE_SIZE, 0);
173 pa = sg_phys(sg);
174 usnic_dbg("va: 0x%lx pa: %pa\n",
175 cur_base + i*PAGE_SIZE, &pa);
176 }
177 cur_base += chunk->nents * PAGE_SIZE;
178 ret -= chunk->nents;
179 off += chunk->nents;
180 list_add_tail(&chunk->list, chunk_list);
181 }
182
183 ret = 0;
184 }
185
186out:
187 if (ret < 0)
188 usnic_uiom_put_pages(chunk_list, 0);
189 else
190 current->mm->locked_vm = locked;
191
192 up_write(&current->mm->mmap_sem);
193 free_page((unsigned long) page_list);
194 return ret;
195}
196
197static void usnic_uiom_unmap_sorted_intervals(struct list_head *intervals,
198 struct usnic_uiom_pd *pd)
199{
200 struct usnic_uiom_interval_node *interval, *tmp;
201 long unsigned va, size;
202
203 list_for_each_entry_safe(interval, tmp, intervals, link) {
204 va = interval->start << PAGE_SHIFT;
205 size = ((interval->last - interval->start) + 1) << PAGE_SHIFT;
206 while (size > 0) {
207 /* Workaround for RH 970401 */
208 usnic_dbg("va 0x%lx size 0x%lx", va, PAGE_SIZE);
209 iommu_unmap(pd->domain, va, PAGE_SIZE);
210 va += PAGE_SIZE;
211 size -= PAGE_SIZE;
212 }
213 }
214}
215
216static void __usnic_uiom_reg_release(struct usnic_uiom_pd *pd,
217 struct usnic_uiom_reg *uiomr,
218 int dirty)
219{
220 int npages;
221 unsigned long vpn_start, vpn_last;
222 struct usnic_uiom_interval_node *interval, *tmp;
223 int writable = 0;
224 LIST_HEAD(rm_intervals);
225
226 npages = PAGE_ALIGN(uiomr->length + uiomr->offset) >> PAGE_SHIFT;
227 vpn_start = (uiomr->va & PAGE_MASK) >> PAGE_SHIFT;
228 vpn_last = vpn_start + npages - 1;
229
230 spin_lock(&pd->lock);
231 usnic_uiom_remove_interval(&pd->rb_root, vpn_start,
232 vpn_last, &rm_intervals);
233 usnic_uiom_unmap_sorted_intervals(&rm_intervals, pd);
234
235 list_for_each_entry_safe(interval, tmp, &rm_intervals, link) {
236 if (interval->flags & IOMMU_WRITE)
237 writable = 1;
238 list_del(&interval->link);
239 kfree(interval);
240 }
241
242 usnic_uiom_put_pages(&uiomr->chunk_list, dirty & writable);
243 spin_unlock(&pd->lock);
244}
245
246static int usnic_uiom_map_sorted_intervals(struct list_head *intervals,
247 struct usnic_uiom_reg *uiomr)
248{
249 int i, err;
250 size_t size;
251 struct usnic_uiom_chunk *chunk;
252 struct usnic_uiom_interval_node *interval_node;
253 dma_addr_t pa;
254 dma_addr_t pa_start = 0;
255 dma_addr_t pa_end = 0;
256 long int va_start = -EINVAL;
257 struct usnic_uiom_pd *pd = uiomr->pd;
258 long int va = uiomr->va & PAGE_MASK;
259 int flags = IOMMU_READ | IOMMU_CACHE;
260
261 flags |= (uiomr->writable) ? IOMMU_WRITE : 0;
262 chunk = list_first_entry(&uiomr->chunk_list, struct usnic_uiom_chunk,
263 list);
264 list_for_each_entry(interval_node, intervals, link) {
265iter_chunk:
266 for (i = 0; i < chunk->nents; i++, va += PAGE_SIZE) {
267 pa = sg_phys(&chunk->page_list[i]);
268 if ((va >> PAGE_SHIFT) < interval_node->start)
269 continue;
270
271 if ((va >> PAGE_SHIFT) == interval_node->start) {
272 /* First page of the interval */
273 va_start = va;
274 pa_start = pa;
275 pa_end = pa;
276 }
277
278 WARN_ON(va_start == -EINVAL);
279
280 if ((pa_end + PAGE_SIZE != pa) &&
281 (pa != pa_start)) {
282 /* PAs are not contiguous */
283 size = pa_end - pa_start + PAGE_SIZE;
284 usnic_dbg("va 0x%lx pa %pa size 0x%zx flags 0x%x",
285 va_start, &pa_start, size, flags);
286 err = iommu_map(pd->domain, va_start, pa_start,
287 size, flags);
288 if (err) {
289 usnic_err("Failed to map va 0x%lx pa 0x%pa size 0x%zx with err %d\n",
290 va_start, &pa_start, size, err);
291 goto err_out;
292 }
293 va_start = va;
294 pa_start = pa;
295 pa_end = pa;
296 }
297
298 if ((va >> PAGE_SHIFT) == interval_node->last) {
299 /* Last page of the interval */
300 size = pa - pa_start + PAGE_SIZE;
301 usnic_dbg("va 0x%lx pa %pa size 0x%zx flags 0x%x\n",
302 va_start, &pa_start, size, flags);
303 err = iommu_map(pd->domain, va_start, pa_start,
304 size, flags);
305 if (err) {
306 usnic_err("Failed to map va 0x%lx pa %pa size 0x%zx with err %d\n",
307 va_start, &pa_start, size, err);
308 goto err_out;
309 }
310 break;
311 }
312
313 if (pa != pa_start)
314 pa_end += PAGE_SIZE;
315 }
316
317 if (i == chunk->nents) {
318 /*
319 * Hit last entry of the chunk,
320 * hence advance to next chunk
321 */
322 chunk = list_first_entry(&chunk->list,
323 struct usnic_uiom_chunk,
324 list);
325 goto iter_chunk;
326 }
327 }
328
329 return 0;
330
331err_out:
332 usnic_uiom_unmap_sorted_intervals(intervals, pd);
333 return err;
334}
335
336struct usnic_uiom_reg *usnic_uiom_reg_get(struct usnic_uiom_pd *pd,
337 unsigned long addr, size_t size,
338 int writable, int dmasync)
339{
340 struct usnic_uiom_reg *uiomr;
341 unsigned long va_base, vpn_start, vpn_last;
342 unsigned long npages;
343 int offset, err;
344 LIST_HEAD(sorted_diff_intervals);
345
346 /*
347 * Intel IOMMU map throws an error if a translation entry is
348 * changed from read to write. This module may not unmap
349 * and then remap the entry after fixing the permission
350 * b/c this open up a small windows where hw DMA may page fault
351 * Hence, make all entries to be writable.
352 */
353 writable = 1;
354
355 va_base = addr & PAGE_MASK;
356 offset = addr & ~PAGE_MASK;
357 npages = PAGE_ALIGN(size + offset) >> PAGE_SHIFT;
358 vpn_start = (addr & PAGE_MASK) >> PAGE_SHIFT;
359 vpn_last = vpn_start + npages - 1;
360
361 uiomr = kmalloc(sizeof(*uiomr), GFP_KERNEL);
362 if (!uiomr)
363 return ERR_PTR(-ENOMEM);
364
365 uiomr->va = va_base;
366 uiomr->offset = offset;
367 uiomr->length = size;
368 uiomr->writable = writable;
369 uiomr->pd = pd;
370
371 err = usnic_uiom_get_pages(addr, size, writable, dmasync,
372 &uiomr->chunk_list);
373 if (err) {
374 usnic_err("Failed get_pages vpn [0x%lx,0x%lx] err %d\n",
375 vpn_start, vpn_last, err);
376 goto out_free_uiomr;
377 }
378
379 spin_lock(&pd->lock);
380 err = usnic_uiom_get_intervals_diff(vpn_start, vpn_last,
381 (writable) ? IOMMU_WRITE : 0,
382 IOMMU_WRITE,
383 &pd->rb_root,
384 &sorted_diff_intervals);
385 if (err) {
386 usnic_err("Failed disjoint interval vpn [0x%lx,0x%lx] err %d\n",
387 vpn_start, vpn_last, err);
388 goto out_put_pages;
389 }
390
391 err = usnic_uiom_map_sorted_intervals(&sorted_diff_intervals, uiomr);
392 if (err) {
393 usnic_err("Failed map interval vpn [0x%lx,0x%lx] err %d\n",
394 vpn_start, vpn_last, err);
395 goto out_put_intervals;
396
397 }
398
399 err = usnic_uiom_insert_interval(&pd->rb_root, vpn_start, vpn_last,
400 (writable) ? IOMMU_WRITE : 0);
401 if (err) {
402 usnic_err("Failed insert interval vpn [0x%lx,0x%lx] err %d\n",
403 vpn_start, vpn_last, err);
404 goto out_unmap_intervals;
405 }
406
407 usnic_uiom_put_interval_set(&sorted_diff_intervals);
408 spin_unlock(&pd->lock);
409
410 return uiomr;
411
412out_unmap_intervals:
413 usnic_uiom_unmap_sorted_intervals(&sorted_diff_intervals, pd);
414out_put_intervals:
415 usnic_uiom_put_interval_set(&sorted_diff_intervals);
416out_put_pages:
417 usnic_uiom_put_pages(&uiomr->chunk_list, 0);
418 spin_unlock(&pd->lock);
419out_free_uiomr:
420 kfree(uiomr);
421 return ERR_PTR(err);
422}
423
424void usnic_uiom_reg_release(struct usnic_uiom_reg *uiomr, int closing)
425{
426 struct mm_struct *mm;
427 unsigned long diff;
428
429 __usnic_uiom_reg_release(uiomr->pd, uiomr, 1);
430
431 mm = get_task_mm(current);
432 if (!mm) {
433 kfree(uiomr);
434 return;
435 }
436
437 diff = PAGE_ALIGN(uiomr->length + uiomr->offset) >> PAGE_SHIFT;
438
439 /*
440 * We may be called with the mm's mmap_sem already held. This
441 * can happen when a userspace munmap() is the call that drops
442 * the last reference to our file and calls our release
443 * method. If there are memory regions to destroy, we'll end
444 * up here and not be able to take the mmap_sem. In that case
445 * we defer the vm_locked accounting to the system workqueue.
446 */
447 if (closing) {
448 if (!down_write_trylock(&mm->mmap_sem)) {
449 INIT_WORK(&uiomr->work, usnic_uiom_reg_account);
450 uiomr->mm = mm;
451 uiomr->diff = diff;
452
453 queue_work(usnic_uiom_wq, &uiomr->work);
454 return;
455 }
456 } else
457 down_write(&mm->mmap_sem);
458
459 current->mm->locked_vm -= diff;
460 up_write(&mm->mmap_sem);
461 mmput(mm);
462 kfree(uiomr);
463}
464
465struct usnic_uiom_pd *usnic_uiom_alloc_pd(void)
466{
467 struct usnic_uiom_pd *pd;
468 void *domain;
469
470 pd = kzalloc(sizeof(*pd), GFP_KERNEL);
471 if (!pd)
472 return ERR_PTR(-ENOMEM);
473
474 pd->domain = domain = iommu_domain_alloc(&pci_bus_type);
475 if (IS_ERR_OR_NULL(domain)) {
476 usnic_err("Failed to allocate IOMMU domain with err %ld\n",
477 PTR_ERR(pd->domain));
478 kfree(pd);
479 return ERR_PTR(domain ? PTR_ERR(domain) : -ENOMEM);
480 }
481
482 iommu_set_fault_handler(pd->domain, usnic_uiom_dma_fault, NULL);
483
484 spin_lock_init(&pd->lock);
485 INIT_LIST_HEAD(&pd->devs);
486
487 return pd;
488}
489
490void usnic_uiom_dealloc_pd(struct usnic_uiom_pd *pd)
491{
492 iommu_domain_free(pd->domain);
493 kfree(pd);
494}
495
496int usnic_uiom_attach_dev_to_pd(struct usnic_uiom_pd *pd, struct device *dev)
497{
498 struct usnic_uiom_dev *uiom_dev;
499 int err;
500
501 uiom_dev = kzalloc(sizeof(*uiom_dev), GFP_ATOMIC);
502 if (!uiom_dev)
503 return -ENOMEM;
504 uiom_dev->dev = dev;
505
506 err = iommu_attach_device(pd->domain, dev);
507 if (err)
508 goto out_free_dev;
509
510 if (!iommu_domain_has_cap(pd->domain, IOMMU_CAP_CACHE_COHERENCY)) {
511 usnic_err("IOMMU of %s does not support cache coherency\n",
512 dev_name(dev));
513 err = -EINVAL;
514 goto out_detach_device;
515 }
516
517 spin_lock(&pd->lock);
518 list_add_tail(&uiom_dev->link, &pd->devs);
519 pd->dev_cnt++;
520 spin_unlock(&pd->lock);
521
522 return 0;
523
524out_detach_device:
525 iommu_detach_device(pd->domain, dev);
526out_free_dev:
527 kfree(uiom_dev);
528 return err;
529}
530
531void usnic_uiom_detach_dev_from_pd(struct usnic_uiom_pd *pd, struct device *dev)
532{
533 struct usnic_uiom_dev *uiom_dev;
534 int found = 0;
535
536 spin_lock(&pd->lock);
537 list_for_each_entry(uiom_dev, &pd->devs, link) {
538 if (uiom_dev->dev == dev) {
539 found = 1;
540 break;
541 }
542 }
543
544 if (!found) {
545 usnic_err("Unable to free dev %s - not found\n",
546 dev_name(dev));
547 spin_unlock(&pd->lock);
548 return;
549 }
550
551 list_del(&uiom_dev->link);
552 pd->dev_cnt--;
553 spin_unlock(&pd->lock);
554
555 return iommu_detach_device(pd->domain, dev);
556}
557
558struct device **usnic_uiom_get_dev_list(struct usnic_uiom_pd *pd)
559{
560 struct usnic_uiom_dev *uiom_dev;
561 struct device **devs;
562 int i = 0;
563
564 spin_lock(&pd->lock);
565 devs = kcalloc(pd->dev_cnt + 1, sizeof(*devs), GFP_ATOMIC);
566 if (!devs) {
567 devs = ERR_PTR(-ENOMEM);
568 goto out;
569 }
570
571 list_for_each_entry(uiom_dev, &pd->devs, link) {
572 devs[i++] = uiom_dev->dev;
573 }
574out:
575 spin_unlock(&pd->lock);
576 return devs;
577}
578
579void usnic_uiom_free_dev_list(struct device **devs)
580{
581 kfree(devs);
582}
583
584int usnic_uiom_init(char *drv_name)
585{
586 if (!iommu_present(&pci_bus_type)) {
587 usnic_err("IOMMU required but not present or enabled. USNIC QPs will not function w/o enabling IOMMU\n");
588 return -EPERM;
589 }
590
591 usnic_uiom_wq = create_workqueue(drv_name);
592 if (!usnic_uiom_wq) {
593 usnic_err("Unable to alloc wq for drv %s\n", drv_name);
594 return -ENOMEM;
595 }
596
597 return 0;
598}
599
600void usnic_uiom_fini(void)
601{
602 flush_workqueue(usnic_uiom_wq);
603 destroy_workqueue(usnic_uiom_wq);
604}
diff --git a/drivers/infiniband/hw/usnic/usnic_uiom.h b/drivers/infiniband/hw/usnic/usnic_uiom.h
new file mode 100644
index 000000000000..70440996e8f2
--- /dev/null
+++ b/drivers/infiniband/hw/usnic/usnic_uiom.h
@@ -0,0 +1,80 @@
1/*
2 * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
3 *
4 * This program is free software; you may redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
15 * SOFTWARE.
16 *
17 */
18
19#ifndef USNIC_UIOM_H_
20#define USNIC_UIOM_H_
21
22#include <linux/list.h>
23#include <linux/scatterlist.h>
24
25#include "usnic_uiom_interval_tree.h"
26
27#define USNIC_UIOM_READ (1)
28#define USNIC_UIOM_WRITE (2)
29
30#define USNIC_UIOM_MAX_PD_CNT (1000)
31#define USNIC_UIOM_MAX_MR_CNT (1000000)
32#define USNIC_UIOM_MAX_MR_SIZE (~0UL)
33#define USNIC_UIOM_PAGE_SIZE (PAGE_SIZE)
34
35struct usnic_uiom_dev {
36 struct device *dev;
37 struct list_head link;
38};
39
40struct usnic_uiom_pd {
41 struct iommu_domain *domain;
42 spinlock_t lock;
43 struct rb_root rb_root;
44 struct list_head devs;
45 int dev_cnt;
46};
47
48struct usnic_uiom_reg {
49 struct usnic_uiom_pd *pd;
50 unsigned long va;
51 size_t length;
52 int offset;
53 int page_size;
54 int writable;
55 struct list_head chunk_list;
56 struct work_struct work;
57 struct mm_struct *mm;
58 unsigned long diff;
59};
60
61struct usnic_uiom_chunk {
62 struct list_head list;
63 int nents;
64 struct scatterlist page_list[0];
65};
66
67struct usnic_uiom_pd *usnic_uiom_alloc_pd(void);
68void usnic_uiom_dealloc_pd(struct usnic_uiom_pd *pd);
69int usnic_uiom_attach_dev_to_pd(struct usnic_uiom_pd *pd, struct device *dev);
70void usnic_uiom_detach_dev_from_pd(struct usnic_uiom_pd *pd,
71 struct device *dev);
72struct device **usnic_uiom_get_dev_list(struct usnic_uiom_pd *pd);
73void usnic_uiom_free_dev_list(struct device **devs);
74struct usnic_uiom_reg *usnic_uiom_reg_get(struct usnic_uiom_pd *pd,
75 unsigned long addr, size_t size,
76 int access, int dmasync);
77void usnic_uiom_reg_release(struct usnic_uiom_reg *uiomr, int closing);
78int usnic_uiom_init(char *drv_name);
79void usnic_uiom_fini(void);
80#endif /* USNIC_UIOM_H_ */
diff --git a/drivers/infiniband/hw/usnic/usnic_uiom_interval_tree.c b/drivers/infiniband/hw/usnic/usnic_uiom_interval_tree.c
new file mode 100644
index 000000000000..d135ad90d914
--- /dev/null
+++ b/drivers/infiniband/hw/usnic/usnic_uiom_interval_tree.c
@@ -0,0 +1,236 @@
1#include <linux/init.h>
2#include <linux/list.h>
3#include <linux/slab.h>
4#include <linux/list_sort.h>
5
6#include <linux/interval_tree_generic.h>
7#include "usnic_uiom_interval_tree.h"
8
9#define START(node) ((node)->start)
10#define LAST(node) ((node)->last)
11
12#define MAKE_NODE(node, start, end, ref_cnt, flags, err, err_out) \
13 do { \
14 node = usnic_uiom_interval_node_alloc(start, \
15 end, ref_cnt, flags); \
16 if (!node) { \
17 err = -ENOMEM; \
18 goto err_out; \
19 } \
20 } while (0)
21
22#define MARK_FOR_ADD(node, list) (list_add_tail(&node->link, list))
23
24#define MAKE_NODE_AND_APPEND(node, start, end, ref_cnt, flags, err, \
25 err_out, list) \
26 do { \
27 MAKE_NODE(node, start, end, \
28 ref_cnt, flags, err, \
29 err_out); \
30 MARK_FOR_ADD(node, list); \
31 } while (0)
32
33#define FLAGS_EQUAL(flags1, flags2, mask) \
34 (((flags1) & (mask)) == ((flags2) & (mask)))
35
36static struct usnic_uiom_interval_node*
37usnic_uiom_interval_node_alloc(long int start, long int last, int ref_cnt,
38 int flags)
39{
40 struct usnic_uiom_interval_node *interval = kzalloc(sizeof(*interval),
41 GFP_ATOMIC);
42 if (!interval)
43 return NULL;
44
45 interval->start = start;
46 interval->last = last;
47 interval->flags = flags;
48 interval->ref_cnt = ref_cnt;
49
50 return interval;
51}
52
53static int interval_cmp(void *priv, struct list_head *a, struct list_head *b)
54{
55 struct usnic_uiom_interval_node *node_a, *node_b;
56
57 node_a = list_entry(a, struct usnic_uiom_interval_node, link);
58 node_b = list_entry(b, struct usnic_uiom_interval_node, link);
59
60 /* long to int */
61 if (node_a->start < node_b->start)
62 return -1;
63 else if (node_a->start > node_b->start)
64 return 1;
65
66 return 0;
67}
68
69static void
70find_intervals_intersection_sorted(struct rb_root *root, unsigned long start,
71 unsigned long last,
72 struct list_head *list)
73{
74 struct usnic_uiom_interval_node *node;
75
76 INIT_LIST_HEAD(list);
77
78 for (node = usnic_uiom_interval_tree_iter_first(root, start, last);
79 node;
80 node = usnic_uiom_interval_tree_iter_next(node, start, last))
81 list_add_tail(&node->link, list);
82
83 list_sort(NULL, list, interval_cmp);
84}
85
86int usnic_uiom_get_intervals_diff(unsigned long start, unsigned long last,
87 int flags, int flag_mask,
88 struct rb_root *root,
89 struct list_head *diff_set)
90{
91 struct usnic_uiom_interval_node *interval, *tmp;
92 int err = 0;
93 long int pivot = start;
94 LIST_HEAD(intersection_set);
95
96 INIT_LIST_HEAD(diff_set);
97
98 find_intervals_intersection_sorted(root, start, last,
99 &intersection_set);
100
101 list_for_each_entry(interval, &intersection_set, link) {
102 if (pivot < interval->start) {
103 MAKE_NODE_AND_APPEND(tmp, pivot, interval->start - 1,
104 1, flags, err, err_out,
105 diff_set);
106 pivot = interval->start;
107 }
108
109 /*
110 * Invariant: Set [start, pivot] is either in diff_set or root,
111 * but not in both.
112 */
113
114 if (pivot > interval->last) {
115 continue;
116 } else if (pivot <= interval->last &&
117 FLAGS_EQUAL(interval->flags, flags,
118 flag_mask)) {
119 pivot = interval->last + 1;
120 }
121 }
122
123 if (pivot <= last)
124 MAKE_NODE_AND_APPEND(tmp, pivot, last, 1, flags, err, err_out,
125 diff_set);
126
127 return 0;
128
129err_out:
130 list_for_each_entry_safe(interval, tmp, diff_set, link) {
131 list_del(&interval->link);
132 kfree(interval);
133 }
134
135 return err;
136}
137
138void usnic_uiom_put_interval_set(struct list_head *intervals)
139{
140 struct usnic_uiom_interval_node *interval, *tmp;
141 list_for_each_entry_safe(interval, tmp, intervals, link)
142 kfree(interval);
143}
144
145int usnic_uiom_insert_interval(struct rb_root *root, unsigned long start,
146 unsigned long last, int flags)
147{
148 struct usnic_uiom_interval_node *interval, *tmp;
149 unsigned long istart, ilast;
150 int iref_cnt, iflags;
151 unsigned long lpivot = start;
152 int err = 0;
153 LIST_HEAD(to_add);
154 LIST_HEAD(intersection_set);
155
156 find_intervals_intersection_sorted(root, start, last,
157 &intersection_set);
158
159 list_for_each_entry(interval, &intersection_set, link) {
160 /*
161 * Invariant - lpivot is the left edge of next interval to be
162 * inserted
163 */
164 istart = interval->start;
165 ilast = interval->last;
166 iref_cnt = interval->ref_cnt;
167 iflags = interval->flags;
168
169 if (istart < lpivot) {
170 MAKE_NODE_AND_APPEND(tmp, istart, lpivot - 1, iref_cnt,
171 iflags, err, err_out, &to_add);
172 } else if (istart > lpivot) {
173 MAKE_NODE_AND_APPEND(tmp, lpivot, istart - 1, 1, flags,
174 err, err_out, &to_add);
175 lpivot = istart;
176 } else {
177 lpivot = istart;
178 }
179
180 if (ilast > last) {
181 MAKE_NODE_AND_APPEND(tmp, lpivot, last, iref_cnt + 1,
182 iflags | flags, err, err_out,
183 &to_add);
184 MAKE_NODE_AND_APPEND(tmp, last + 1, ilast, iref_cnt,
185 iflags, err, err_out, &to_add);
186 } else {
187 MAKE_NODE_AND_APPEND(tmp, lpivot, ilast, iref_cnt + 1,
188 iflags | flags, err, err_out,
189 &to_add);
190 }
191
192 lpivot = ilast + 1;
193 }
194
195 if (lpivot <= last)
196 MAKE_NODE_AND_APPEND(tmp, lpivot, last, 1, flags, err, err_out,
197 &to_add);
198
199 list_for_each_entry_safe(interval, tmp, &intersection_set, link) {
200 usnic_uiom_interval_tree_remove(interval, root);
201 kfree(interval);
202 }
203
204 list_for_each_entry(interval, &to_add, link)
205 usnic_uiom_interval_tree_insert(interval, root);
206
207 return 0;
208
209err_out:
210 list_for_each_entry_safe(interval, tmp, &to_add, link)
211 kfree(interval);
212
213 return err;
214}
215
216void usnic_uiom_remove_interval(struct rb_root *root, unsigned long start,
217 unsigned long last, struct list_head *removed)
218{
219 struct usnic_uiom_interval_node *interval;
220
221 for (interval = usnic_uiom_interval_tree_iter_first(root, start, last);
222 interval;
223 interval = usnic_uiom_interval_tree_iter_next(interval,
224 start,
225 last)) {
226 if (--interval->ref_cnt == 0)
227 list_add_tail(&interval->link, removed);
228 }
229
230 list_for_each_entry(interval, removed, link)
231 usnic_uiom_interval_tree_remove(interval, root);
232}
233
234INTERVAL_TREE_DEFINE(struct usnic_uiom_interval_node, rb,
235 unsigned long, __subtree_last,
236 START, LAST, , usnic_uiom_interval_tree)
diff --git a/drivers/infiniband/hw/usnic/usnic_uiom_interval_tree.h b/drivers/infiniband/hw/usnic/usnic_uiom_interval_tree.h
new file mode 100644
index 000000000000..d4f752e258fd
--- /dev/null
+++ b/drivers/infiniband/hw/usnic/usnic_uiom_interval_tree.h
@@ -0,0 +1,73 @@
1/*
2 * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
3 *
4 * This program is free software; you may redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
15 * SOFTWARE.
16 *
17 */
18
19#ifndef USNIC_UIOM_INTERVAL_TREE_H_
20#define USNIC_UIOM_INTERVAL_TREE_H_
21
22#include <linux/rbtree.h>
23
24struct usnic_uiom_interval_node {
25 struct rb_node rb;
26 struct list_head link;
27 unsigned long start;
28 unsigned long last;
29 unsigned long __subtree_last;
30 unsigned int ref_cnt;
31 int flags;
32};
33
34extern void
35usnic_uiom_interval_tree_insert(struct usnic_uiom_interval_node *node,
36 struct rb_root *root);
37extern void
38usnic_uiom_interval_tree_remove(struct usnic_uiom_interval_node *node,
39 struct rb_root *root);
40extern struct usnic_uiom_interval_node *
41usnic_uiom_interval_tree_iter_first(struct rb_root *root,
42 unsigned long start,
43 unsigned long last);
44extern struct usnic_uiom_interval_node *
45usnic_uiom_interval_tree_iter_next(struct usnic_uiom_interval_node *node,
46 unsigned long start, unsigned long last);
47/*
48 * Inserts {start...last} into {root}. If there are overlaps,
49 * nodes will be broken up and merged
50 */
51int usnic_uiom_insert_interval(struct rb_root *root,
52 unsigned long start, unsigned long last,
53 int flags);
54/*
55 * Removed {start...last} from {root}. The nodes removed are returned in
56 * 'removed.' The caller is responsibile for freeing memory of nodes in
57 * 'removed.'
58 */
59void usnic_uiom_remove_interval(struct rb_root *root,
60 unsigned long start, unsigned long last,
61 struct list_head *removed);
62/*
63 * Returns {start...last} - {root} (relative complement of {start...last} in
64 * {root}) in diff_set sorted ascendingly
65 */
66int usnic_uiom_get_intervals_diff(unsigned long start,
67 unsigned long last, int flags,
68 int flag_mask,
69 struct rb_root *root,
70 struct list_head *diff_set);
71/* Call this to free diff_set returned by usnic_uiom_get_intervals_diff */
72void usnic_uiom_put_interval_set(struct list_head *intervals);
73#endif /* USNIC_UIOM_INTERVAL_TREE_H_ */
diff --git a/drivers/infiniband/hw/usnic/usnic_vnic.c b/drivers/infiniband/hw/usnic/usnic_vnic.c
new file mode 100644
index 000000000000..656b88c39eda
--- /dev/null
+++ b/drivers/infiniband/hw/usnic/usnic_vnic.c
@@ -0,0 +1,467 @@
1/*
2 * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
3 *
4 * This program is free software; you may redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
15 * SOFTWARE.
16 *
17 */
18#include <linux/errno.h>
19#include <linux/module.h>
20#include <linux/pci.h>
21
22#include "usnic_ib.h"
23#include "vnic_resource.h"
24#include "usnic_log.h"
25#include "usnic_vnic.h"
26
27struct usnic_vnic {
28 struct vnic_dev *vdev;
29 struct vnic_dev_bar bar[PCI_NUM_RESOURCES];
30 struct usnic_vnic_res_chunk chunks[USNIC_VNIC_RES_TYPE_MAX];
31 spinlock_t res_lock;
32};
33
34static enum vnic_res_type _to_vnic_res_type(enum usnic_vnic_res_type res_type)
35{
36#define DEFINE_USNIC_VNIC_RES_AT(usnic_vnic_res_t, vnic_res_type, desc, val) \
37 vnic_res_type,
38#define DEFINE_USNIC_VNIC_RES(usnic_vnic_res_t, vnic_res_type, desc) \
39 vnic_res_type,
40 static enum vnic_res_type usnic_vnic_type_2_vnic_type[] = {
41 USNIC_VNIC_RES_TYPES};
42#undef DEFINE_USNIC_VNIC_RES
43#undef DEFINE_USNIC_VNIC_RES_AT
44
45 if (res_type >= USNIC_VNIC_RES_TYPE_MAX)
46 return RES_TYPE_MAX;
47
48 return usnic_vnic_type_2_vnic_type[res_type];
49}
50
51const char *usnic_vnic_res_type_to_str(enum usnic_vnic_res_type res_type)
52{
53#define DEFINE_USNIC_VNIC_RES_AT(usnic_vnic_res_t, vnic_res_type, desc, val) \
54 desc,
55#define DEFINE_USNIC_VNIC_RES(usnic_vnic_res_t, vnic_res_type, desc) \
56 desc,
57 static const char * const usnic_vnic_res_type_desc[] = {
58 USNIC_VNIC_RES_TYPES};
59#undef DEFINE_USNIC_VNIC_RES
60#undef DEFINE_USNIC_VNIC_RES_AT
61
62 if (res_type >= USNIC_VNIC_RES_TYPE_MAX)
63 return "unknown";
64
65 return usnic_vnic_res_type_desc[res_type];
66
67}
68
69const char *usnic_vnic_pci_name(struct usnic_vnic *vnic)
70{
71 return pci_name(usnic_vnic_get_pdev(vnic));
72}
73
74int usnic_vnic_dump(struct usnic_vnic *vnic, char *buf,
75 int buf_sz,
76 void *hdr_obj,
77 int (*printtitle)(void *, char*, int),
78 int (*printcols)(char *, int),
79 int (*printrow)(void *, char *, int))
80{
81 struct usnic_vnic_res_chunk *chunk;
82 struct usnic_vnic_res *res;
83 struct vnic_dev_bar *bar0;
84 int i, j, offset;
85
86 offset = 0;
87 bar0 = usnic_vnic_get_bar(vnic, 0);
88 offset += scnprintf(buf + offset, buf_sz - offset,
89 "VF:%hu BAR0 bus_addr=%pa vaddr=0x%p size=%ld ",
90 usnic_vnic_get_index(vnic),
91 &bar0->bus_addr,
92 bar0->vaddr, bar0->len);
93 if (printtitle)
94 offset += printtitle(hdr_obj, buf + offset, buf_sz - offset);
95 offset += scnprintf(buf + offset, buf_sz - offset, "\n");
96 offset += scnprintf(buf + offset, buf_sz - offset,
97 "|RES\t|CTRL_PIN\t\t|IN_USE\t");
98 if (printcols)
99 offset += printcols(buf + offset, buf_sz - offset);
100 offset += scnprintf(buf + offset, buf_sz - offset, "\n");
101
102 spin_lock(&vnic->res_lock);
103 for (i = 0; i < ARRAY_SIZE(vnic->chunks); i++) {
104 chunk = &vnic->chunks[i];
105 for (j = 0; j < chunk->cnt; j++) {
106 res = chunk->res[j];
107 offset += scnprintf(buf + offset, buf_sz - offset,
108 "|%s[%u]\t|0x%p\t|%u\t",
109 usnic_vnic_res_type_to_str(res->type),
110 res->vnic_idx, res->ctrl, !!res->owner);
111 if (printrow) {
112 offset += printrow(res->owner, buf + offset,
113 buf_sz - offset);
114 }
115 offset += scnprintf(buf + offset, buf_sz - offset,
116 "\n");
117 }
118 }
119 spin_unlock(&vnic->res_lock);
120 return offset;
121}
122
123void usnic_vnic_res_spec_update(struct usnic_vnic_res_spec *spec,
124 enum usnic_vnic_res_type trgt_type,
125 u16 cnt)
126{
127 int i;
128
129 for (i = 0; i < USNIC_VNIC_RES_TYPE_MAX; i++) {
130 if (spec->resources[i].type == trgt_type) {
131 spec->resources[i].cnt = cnt;
132 return;
133 }
134 }
135
136 WARN_ON(1);
137}
138
139int usnic_vnic_res_spec_satisfied(const struct usnic_vnic_res_spec *min_spec,
140 struct usnic_vnic_res_spec *res_spec)
141{
142 int found, i, j;
143
144 for (i = 0; i < USNIC_VNIC_RES_TYPE_MAX; i++) {
145 found = 0;
146
147 for (j = 0; j < USNIC_VNIC_RES_TYPE_MAX; j++) {
148 if (res_spec->resources[i].type !=
149 min_spec->resources[i].type)
150 continue;
151 found = 1;
152 if (min_spec->resources[i].cnt >
153 res_spec->resources[i].cnt)
154 return -EINVAL;
155 break;
156 }
157
158 if (!found)
159 return -EINVAL;
160 }
161 return 0;
162}
163
164int usnic_vnic_spec_dump(char *buf, int buf_sz,
165 struct usnic_vnic_res_spec *res_spec)
166{
167 enum usnic_vnic_res_type res_type;
168 int res_cnt;
169 int i;
170 int offset = 0;
171
172 for (i = 0; i < USNIC_VNIC_RES_TYPE_MAX; i++) {
173 res_type = res_spec->resources[i].type;
174 res_cnt = res_spec->resources[i].cnt;
175 offset += scnprintf(buf + offset, buf_sz - offset,
176 "Res: %s Cnt: %d ",
177 usnic_vnic_res_type_to_str(res_type),
178 res_cnt);
179 }
180
181 return offset;
182}
183
184int usnic_vnic_check_room(struct usnic_vnic *vnic,
185 struct usnic_vnic_res_spec *res_spec)
186{
187 int i;
188 enum usnic_vnic_res_type res_type;
189 int res_cnt;
190
191 for (i = 0; i < USNIC_VNIC_RES_TYPE_MAX; i++) {
192 res_type = res_spec->resources[i].type;
193 res_cnt = res_spec->resources[i].cnt;
194
195 if (res_type == USNIC_VNIC_RES_TYPE_EOL)
196 break;
197
198 if (res_cnt > usnic_vnic_res_free_cnt(vnic, res_type))
199 return -EBUSY;
200 }
201
202 return 0;
203}
204
205int usnic_vnic_res_cnt(struct usnic_vnic *vnic,
206 enum usnic_vnic_res_type type)
207{
208 return vnic->chunks[type].cnt;
209}
210
211int usnic_vnic_res_free_cnt(struct usnic_vnic *vnic,
212 enum usnic_vnic_res_type type)
213{
214 return vnic->chunks[type].free_cnt;
215}
216
217struct usnic_vnic_res_chunk *
218usnic_vnic_get_resources(struct usnic_vnic *vnic, enum usnic_vnic_res_type type,
219 int cnt, void *owner)
220{
221 struct usnic_vnic_res_chunk *src, *ret;
222 struct usnic_vnic_res *res;
223 int i;
224
225 if (usnic_vnic_res_free_cnt(vnic, type) < cnt || cnt < 1 || !owner)
226 return ERR_PTR(-EINVAL);
227
228 ret = kzalloc(sizeof(*ret), GFP_ATOMIC);
229 if (!ret) {
230 usnic_err("Failed to allocate chunk for %s - Out of memory\n",
231 usnic_vnic_pci_name(vnic));
232 return ERR_PTR(-ENOMEM);
233 }
234
235 ret->res = kzalloc(sizeof(*(ret->res))*cnt, GFP_ATOMIC);
236 if (!ret->res) {
237 usnic_err("Failed to allocate resources for %s. Out of memory\n",
238 usnic_vnic_pci_name(vnic));
239 kfree(ret);
240 return ERR_PTR(-ENOMEM);
241 }
242
243 spin_lock(&vnic->res_lock);
244 src = &vnic->chunks[type];
245 for (i = 0; i < src->cnt && ret->cnt < cnt; i++) {
246 res = src->res[i];
247 if (!res->owner) {
248 src->free_cnt--;
249 res->owner = owner;
250 ret->res[ret->cnt++] = res;
251 }
252 }
253
254 spin_unlock(&vnic->res_lock);
255 ret->type = type;
256 ret->vnic = vnic;
257 WARN_ON(ret->cnt != cnt);
258
259 return ret;
260}
261
262void usnic_vnic_put_resources(struct usnic_vnic_res_chunk *chunk)
263{
264
265 struct usnic_vnic_res *res;
266 int i;
267 struct usnic_vnic *vnic = chunk->vnic;
268
269 spin_lock(&vnic->res_lock);
270 while ((i = --chunk->cnt) >= 0) {
271 res = chunk->res[i];
272 chunk->res[i] = NULL;
273 res->owner = NULL;
274 vnic->chunks[res->type].free_cnt++;
275 }
276 spin_unlock(&vnic->res_lock);
277
278 kfree(chunk->res);
279 kfree(chunk);
280}
281
282u16 usnic_vnic_get_index(struct usnic_vnic *vnic)
283{
284 return usnic_vnic_get_pdev(vnic)->devfn - 1;
285}
286
287static int usnic_vnic_alloc_res_chunk(struct usnic_vnic *vnic,
288 enum usnic_vnic_res_type type,
289 struct usnic_vnic_res_chunk *chunk)
290{
291 int cnt, err, i;
292 struct usnic_vnic_res *res;
293
294 cnt = vnic_dev_get_res_count(vnic->vdev, _to_vnic_res_type(type));
295 if (cnt < 1)
296 return -EINVAL;
297
298 chunk->cnt = chunk->free_cnt = cnt;
299 chunk->res = kzalloc(sizeof(*(chunk->res))*cnt, GFP_KERNEL);
300 if (!chunk->res)
301 return -ENOMEM;
302
303 for (i = 0; i < cnt; i++) {
304 res = kzalloc(sizeof(*res), GFP_KERNEL);
305 if (!res) {
306 err = -ENOMEM;
307 goto fail;
308 }
309 res->type = type;
310 res->vnic_idx = i;
311 res->vnic = vnic;
312 res->ctrl = vnic_dev_get_res(vnic->vdev,
313 _to_vnic_res_type(type), i);
314 chunk->res[i] = res;
315 }
316
317 chunk->vnic = vnic;
318 return 0;
319fail:
320 for (i--; i >= 0; i--)
321 kfree(chunk->res[i]);
322 kfree(chunk->res);
323 return err;
324}
325
326static void usnic_vnic_free_res_chunk(struct usnic_vnic_res_chunk *chunk)
327{
328 int i;
329 for (i = 0; i < chunk->cnt; i++)
330 kfree(chunk->res[i]);
331 kfree(chunk->res);
332}
333
334static int usnic_vnic_discover_resources(struct pci_dev *pdev,
335 struct usnic_vnic *vnic)
336{
337 enum usnic_vnic_res_type res_type;
338 int i;
339 int err = 0;
340
341 for (i = 0; i < ARRAY_SIZE(vnic->bar); i++) {
342 if (!(pci_resource_flags(pdev, i) & IORESOURCE_MEM))
343 continue;
344 vnic->bar[i].len = pci_resource_len(pdev, i);
345 vnic->bar[i].vaddr = pci_iomap(pdev, i, vnic->bar[i].len);
346 if (!vnic->bar[i].vaddr) {
347 usnic_err("Cannot memory-map BAR %d, aborting\n",
348 i);
349 err = -ENODEV;
350 goto out_clean_bar;
351 }
352 vnic->bar[i].bus_addr = pci_resource_start(pdev, i);
353 }
354
355 vnic->vdev = vnic_dev_register(NULL, pdev, pdev, vnic->bar,
356 ARRAY_SIZE(vnic->bar));
357 if (!vnic->vdev) {
358 usnic_err("Failed to register device %s\n",
359 pci_name(pdev));
360 err = -EINVAL;
361 goto out_clean_bar;
362 }
363
364 for (res_type = USNIC_VNIC_RES_TYPE_EOL + 1;
365 res_type < USNIC_VNIC_RES_TYPE_MAX; res_type++) {
366 err = usnic_vnic_alloc_res_chunk(vnic, res_type,
367 &vnic->chunks[res_type]);
368 if (err) {
369 usnic_err("Failed to alloc res %s with err %d\n",
370 usnic_vnic_res_type_to_str(res_type),
371 err);
372 goto out_clean_chunks;
373 }
374 }
375
376 return 0;
377
378out_clean_chunks:
379 for (res_type--; res_type > USNIC_VNIC_RES_TYPE_EOL; res_type--)
380 usnic_vnic_free_res_chunk(&vnic->chunks[res_type]);
381 vnic_dev_unregister(vnic->vdev);
382out_clean_bar:
383 for (i = 0; i < ARRAY_SIZE(vnic->bar); i++) {
384 if (!(pci_resource_flags(pdev, i) & IORESOURCE_MEM))
385 continue;
386 if (!vnic->bar[i].vaddr)
387 break;
388
389 iounmap(vnic->bar[i].vaddr);
390 }
391
392 return err;
393}
394
395struct pci_dev *usnic_vnic_get_pdev(struct usnic_vnic *vnic)
396{
397 return vnic_dev_get_pdev(vnic->vdev);
398}
399
400struct vnic_dev_bar *usnic_vnic_get_bar(struct usnic_vnic *vnic,
401 int bar_num)
402{
403 return (bar_num < ARRAY_SIZE(vnic->bar)) ? &vnic->bar[bar_num] : NULL;
404}
405
406static void usnic_vnic_release_resources(struct usnic_vnic *vnic)
407{
408 int i;
409 struct pci_dev *pdev;
410 enum usnic_vnic_res_type res_type;
411
412 pdev = usnic_vnic_get_pdev(vnic);
413
414 for (res_type = USNIC_VNIC_RES_TYPE_EOL + 1;
415 res_type < USNIC_VNIC_RES_TYPE_MAX; res_type++)
416 usnic_vnic_free_res_chunk(&vnic->chunks[res_type]);
417
418 vnic_dev_unregister(vnic->vdev);
419
420 for (i = 0; i < ARRAY_SIZE(vnic->bar); i++) {
421 if (!(pci_resource_flags(pdev, i) & IORESOURCE_MEM))
422 continue;
423 iounmap(vnic->bar[i].vaddr);
424 }
425}
426
427struct usnic_vnic *usnic_vnic_alloc(struct pci_dev *pdev)
428{
429 struct usnic_vnic *vnic;
430 int err = 0;
431
432 if (!pci_is_enabled(pdev)) {
433 usnic_err("PCI dev %s is disabled\n", pci_name(pdev));
434 return ERR_PTR(-EINVAL);
435 }
436
437 vnic = kzalloc(sizeof(*vnic), GFP_KERNEL);
438 if (!vnic) {
439 usnic_err("Failed to alloc vnic for %s - out of memory\n",
440 pci_name(pdev));
441 return ERR_PTR(-ENOMEM);
442 }
443
444 spin_lock_init(&vnic->res_lock);
445
446 err = usnic_vnic_discover_resources(pdev, vnic);
447 if (err) {
448 usnic_err("Failed to discover %s resources with err %d\n",
449 pci_name(pdev), err);
450 goto out_free_vnic;
451 }
452
453 usnic_dbg("Allocated vnic for %s\n", usnic_vnic_pci_name(vnic));
454
455 return vnic;
456
457out_free_vnic:
458 kfree(vnic);
459
460 return ERR_PTR(err);
461}
462
463void usnic_vnic_free(struct usnic_vnic *vnic)
464{
465 usnic_vnic_release_resources(vnic);
466 kfree(vnic);
467}
diff --git a/drivers/infiniband/hw/usnic/usnic_vnic.h b/drivers/infiniband/hw/usnic/usnic_vnic.h
new file mode 100644
index 000000000000..14d931a8829d
--- /dev/null
+++ b/drivers/infiniband/hw/usnic/usnic_vnic.h
@@ -0,0 +1,103 @@
1/*
2 * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
3 *
4 * This program is free software; you may redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
15 * SOFTWARE.
16 *
17 */
18
19#ifndef USNIC_VNIC_H_
20#define USNIC_VNIC_H_
21
22#include <linux/pci.h>
23
24#include "vnic_dev.h"
25
26/* =USNIC_VNIC_RES_TYPE= =VNIC_RES= =DESC= */
27#define USNIC_VNIC_RES_TYPES \
28 DEFINE_USNIC_VNIC_RES_AT(EOL, RES_TYPE_EOL, "EOL", 0) \
29 DEFINE_USNIC_VNIC_RES(WQ, RES_TYPE_WQ, "WQ") \
30 DEFINE_USNIC_VNIC_RES(RQ, RES_TYPE_RQ, "RQ") \
31 DEFINE_USNIC_VNIC_RES(CQ, RES_TYPE_CQ, "CQ") \
32 DEFINE_USNIC_VNIC_RES(INTR, RES_TYPE_INTR_CTRL, "INT") \
33 DEFINE_USNIC_VNIC_RES(MAX, RES_TYPE_MAX, "MAX")\
34
35#define DEFINE_USNIC_VNIC_RES_AT(usnic_vnic_res_t, vnic_res_type, desc, val) \
36 USNIC_VNIC_RES_TYPE_##usnic_vnic_res_t = val,
37#define DEFINE_USNIC_VNIC_RES(usnic_vnic_res_t, vnic_res_type, desc) \
38 USNIC_VNIC_RES_TYPE_##usnic_vnic_res_t,
39enum usnic_vnic_res_type {
40 USNIC_VNIC_RES_TYPES
41};
42#undef DEFINE_USNIC_VNIC_RES
43#undef DEFINE_USNIC_VNIC_RES_AT
44
45struct usnic_vnic_res {
46 enum usnic_vnic_res_type type;
47 unsigned int vnic_idx;
48 struct usnic_vnic *vnic;
49 void __iomem *ctrl;
50 void *owner;
51};
52
53struct usnic_vnic_res_chunk {
54 enum usnic_vnic_res_type type;
55 int cnt;
56 int free_cnt;
57 struct usnic_vnic_res **res;
58 struct usnic_vnic *vnic;
59};
60
61struct usnic_vnic_res_desc {
62 enum usnic_vnic_res_type type;
63 uint16_t cnt;
64};
65
66struct usnic_vnic_res_spec {
67 struct usnic_vnic_res_desc resources[USNIC_VNIC_RES_TYPE_MAX];
68};
69
70const char *usnic_vnic_res_type_to_str(enum usnic_vnic_res_type res_type);
71const char *usnic_vnic_pci_name(struct usnic_vnic *vnic);
72int usnic_vnic_dump(struct usnic_vnic *vnic, char *buf, int buf_sz,
73 void *hdr_obj,
74 int (*printtitle)(void *, char*, int),
75 int (*printcols)(char *, int),
76 int (*printrow)(void *, char *, int));
77void usnic_vnic_res_spec_update(struct usnic_vnic_res_spec *spec,
78 enum usnic_vnic_res_type trgt_type,
79 u16 cnt);
80int usnic_vnic_res_spec_satisfied(const struct usnic_vnic_res_spec *min_spec,
81 struct usnic_vnic_res_spec *res_spec);
82int usnic_vnic_spec_dump(char *buf, int buf_sz,
83 struct usnic_vnic_res_spec *res_spec);
84int usnic_vnic_check_room(struct usnic_vnic *vnic,
85 struct usnic_vnic_res_spec *res_spec);
86int usnic_vnic_res_cnt(struct usnic_vnic *vnic,
87 enum usnic_vnic_res_type type);
88int usnic_vnic_res_free_cnt(struct usnic_vnic *vnic,
89 enum usnic_vnic_res_type type);
90struct usnic_vnic_res_chunk *
91usnic_vnic_get_resources(struct usnic_vnic *vnic,
92 enum usnic_vnic_res_type type,
93 int cnt,
94 void *owner);
95void usnic_vnic_put_resources(struct usnic_vnic_res_chunk *chunk);
96struct pci_dev *usnic_vnic_get_pdev(struct usnic_vnic *vnic);
97struct vnic_dev_bar *usnic_vnic_get_bar(struct usnic_vnic *vnic,
98 int bar_num);
99struct usnic_vnic *usnic_vnic_alloc(struct pci_dev *pdev);
100void usnic_vnic_free(struct usnic_vnic *vnic);
101u16 usnic_vnic_get_index(struct usnic_vnic *vnic);
102
103#endif /*!USNIC_VNIC_H_*/
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index d64ed05fb082..5786a78ff8bc 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -104,6 +104,8 @@ int ipoib_open(struct net_device *dev)
104 104
105 ipoib_dbg(priv, "bringing up interface\n"); 105 ipoib_dbg(priv, "bringing up interface\n");
106 106
107 netif_carrier_off(dev);
108
107 set_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags); 109 set_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags);
108 110
109 if (ipoib_pkey_dev_delay_open(dev)) 111 if (ipoib_pkey_dev_delay_open(dev))
@@ -1366,8 +1368,6 @@ void ipoib_setup(struct net_device *dev)
1366 1368
1367 memcpy(dev->broadcast, ipv4_bcast_addr, INFINIBAND_ALEN); 1369 memcpy(dev->broadcast, ipv4_bcast_addr, INFINIBAND_ALEN);
1368 1370
1369 netif_carrier_off(dev);
1370
1371 priv->dev = dev; 1371 priv->dev = dev;
1372 1372
1373 spin_lock_init(&priv->lock); 1373 spin_lock_init(&priv->lock);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
index 049a997caff3..c56d5d44c53b 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
@@ -192,6 +192,9 @@ int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca)
192 if (priv->hca_caps & IB_DEVICE_BLOCK_MULTICAST_LOOPBACK) 192 if (priv->hca_caps & IB_DEVICE_BLOCK_MULTICAST_LOOPBACK)
193 init_attr.create_flags |= IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK; 193 init_attr.create_flags |= IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK;
194 194
195 if (priv->hca_caps & IB_DEVICE_MANAGED_FLOW_STEERING)
196 init_attr.create_flags |= IB_QP_CREATE_NETIF_QP;
197
195 if (dev->features & NETIF_F_SG) 198 if (dev->features & NETIF_F_SG)
196 init_attr.cap.max_send_sge = MAX_SKB_FRAGS + 1; 199 init_attr.cap.max_send_sge = MAX_SKB_FRAGS + 1;
197 200
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index a88631918e85..529b6bcdca7a 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -660,6 +660,7 @@ static void srp_remove_target(struct srp_target_port *target)
660 srp_rport_get(target->rport); 660 srp_rport_get(target->rport);
661 srp_remove_host(target->scsi_host); 661 srp_remove_host(target->scsi_host);
662 scsi_remove_host(target->scsi_host); 662 scsi_remove_host(target->scsi_host);
663 srp_stop_rport_timers(target->rport);
663 srp_disconnect_target(target); 664 srp_disconnect_target(target);
664 ib_destroy_cm_id(target->cm_id); 665 ib_destroy_cm_id(target->cm_id);
665 srp_free_target_ib(target); 666 srp_free_target_ib(target);
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c
index 1e9970d2f0f3..0d02fba94536 100644
--- a/drivers/net/ethernet/mellanox/mlx4/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c
@@ -1371,6 +1371,15 @@ static struct mlx4_cmd_info cmd_info[] = {
1371 .verify = NULL, 1371 .verify = NULL,
1372 .wrapper = mlx4_QP_FLOW_STEERING_DETACH_wrapper 1372 .wrapper = mlx4_QP_FLOW_STEERING_DETACH_wrapper
1373 }, 1373 },
1374 {
1375 .opcode = MLX4_FLOW_STEERING_IB_UC_QP_RANGE,
1376 .has_inbox = false,
1377 .has_outbox = false,
1378 .out_is_imm = false,
1379 .encode_slave_id = false,
1380 .verify = NULL,
1381 .wrapper = mlx4_FLOW_STEERING_IB_UC_QP_RANGE_wrapper
1382 },
1374}; 1383};
1375 1384
1376static int mlx4_master_process_vhcr(struct mlx4_dev *dev, int slave, 1385static int mlx4_master_process_vhcr(struct mlx4_dev *dev, int slave,
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c
index 194928214606..4bd2d80d065e 100644
--- a/drivers/net/ethernet/mellanox/mlx4/fw.c
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.c
@@ -513,6 +513,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
513#define QUERY_DEV_CAP_MAX_XRC_OFFSET 0x67 513#define QUERY_DEV_CAP_MAX_XRC_OFFSET 0x67
514#define QUERY_DEV_CAP_MAX_COUNTERS_OFFSET 0x68 514#define QUERY_DEV_CAP_MAX_COUNTERS_OFFSET 0x68
515#define QUERY_DEV_CAP_EXT_2_FLAGS_OFFSET 0x70 515#define QUERY_DEV_CAP_EXT_2_FLAGS_OFFSET 0x70
516#define QUERY_DEV_CAP_FLOW_STEERING_IPOIB_OFFSET 0x74
516#define QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET 0x76 517#define QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET 0x76
517#define QUERY_DEV_CAP_FLOW_STEERING_MAX_QP_OFFSET 0x77 518#define QUERY_DEV_CAP_FLOW_STEERING_MAX_QP_OFFSET 0x77
518#define QUERY_DEV_CAP_RDMARC_ENTRY_SZ_OFFSET 0x80 519#define QUERY_DEV_CAP_RDMARC_ENTRY_SZ_OFFSET 0x80
@@ -603,6 +604,9 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
603 if (field & 0x80) 604 if (field & 0x80)
604 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_FS_EN; 605 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_FS_EN;
605 dev_cap->fs_log_max_ucast_qp_range_size = field & 0x1f; 606 dev_cap->fs_log_max_ucast_qp_range_size = field & 0x1f;
607 MLX4_GET(field, outbox, QUERY_DEV_CAP_FLOW_STEERING_IPOIB_OFFSET);
608 if (field & 0x80)
609 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_DMFS_IPOIB;
606 MLX4_GET(field, outbox, QUERY_DEV_CAP_FLOW_STEERING_MAX_QP_OFFSET); 610 MLX4_GET(field, outbox, QUERY_DEV_CAP_FLOW_STEERING_MAX_QP_OFFSET);
607 dev_cap->fs_max_num_qp_per_entry = field; 611 dev_cap->fs_max_num_qp_per_entry = field;
608 MLX4_GET(stat_rate, outbox, QUERY_DEV_CAP_RATE_SUPPORT_OFFSET); 612 MLX4_GET(stat_rate, outbox, QUERY_DEV_CAP_RATE_SUPPORT_OFFSET);
@@ -860,6 +864,12 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave,
860 MLX4_PUT(outbox->buf, field, 864 MLX4_PUT(outbox->buf, field,
861 QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET); 865 QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET);
862 } 866 }
867
868 /* turn off ipoib managed steering for guests */
869 MLX4_GET(field, outbox, QUERY_DEV_CAP_FLOW_STEERING_IPOIB_OFFSET);
870 field &= ~0x80;
871 MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_FLOW_STEERING_IPOIB_OFFSET);
872
863 return 0; 873 return 0;
864} 874}
865 875
diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c
index acf9d5f1f922..34dffcf61bff 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mcg.c
+++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c
@@ -895,6 +895,23 @@ int mlx4_flow_detach(struct mlx4_dev *dev, u64 reg_id)
895} 895}
896EXPORT_SYMBOL_GPL(mlx4_flow_detach); 896EXPORT_SYMBOL_GPL(mlx4_flow_detach);
897 897
898int mlx4_FLOW_STEERING_IB_UC_QP_RANGE(struct mlx4_dev *dev, u32 min_range_qpn,
899 u32 max_range_qpn)
900{
901 int err;
902 u64 in_param;
903
904 in_param = ((u64) min_range_qpn) << 32;
905 in_param |= ((u64) max_range_qpn) & 0xFFFFFFFF;
906
907 err = mlx4_cmd(dev, in_param, 0, 0,
908 MLX4_FLOW_STEERING_IB_UC_QP_RANGE,
909 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE);
910
911 return err;
912}
913EXPORT_SYMBOL_GPL(mlx4_FLOW_STEERING_IB_UC_QP_RANGE);
914
898int mlx4_qp_attach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], 915int mlx4_qp_attach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
899 int block_mcast_loopback, enum mlx4_protocol prot, 916 int block_mcast_loopback, enum mlx4_protocol prot,
900 enum mlx4_steer_type steer) 917 enum mlx4_steer_type steer)
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
index e582a41a802b..59f67f9086dc 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -1236,6 +1236,11 @@ int mlx4_QP_FLOW_STEERING_DETACH_wrapper(struct mlx4_dev *dev, int slave,
1236 struct mlx4_cmd_mailbox *inbox, 1236 struct mlx4_cmd_mailbox *inbox,
1237 struct mlx4_cmd_mailbox *outbox, 1237 struct mlx4_cmd_mailbox *outbox,
1238 struct mlx4_cmd_info *cmd); 1238 struct mlx4_cmd_info *cmd);
1239int mlx4_FLOW_STEERING_IB_UC_QP_RANGE_wrapper(struct mlx4_dev *dev, int slave,
1240 struct mlx4_vhcr *vhcr,
1241 struct mlx4_cmd_mailbox *inbox,
1242 struct mlx4_cmd_mailbox *outbox,
1243 struct mlx4_cmd_info *cmd);
1239 1244
1240int mlx4_get_mgm_entry_size(struct mlx4_dev *dev); 1245int mlx4_get_mgm_entry_size(struct mlx4_dev *dev);
1241int mlx4_get_qp_per_mgm(struct mlx4_dev *dev); 1246int mlx4_get_qp_per_mgm(struct mlx4_dev *dev);
diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c
index 97d342fa5032..f50ef6a5ee5e 100644
--- a/drivers/net/ethernet/mellanox/mlx4/port.c
+++ b/drivers/net/ethernet/mellanox/mlx4/port.c
@@ -123,6 +123,26 @@ static int mlx4_set_port_mac_table(struct mlx4_dev *dev, u8 port,
123 return err; 123 return err;
124} 124}
125 125
126int mlx4_find_cached_mac(struct mlx4_dev *dev, u8 port, u64 mac, int *idx)
127{
128 struct mlx4_port_info *info = &mlx4_priv(dev)->port[port];
129 struct mlx4_mac_table *table = &info->mac_table;
130 int i;
131
132 for (i = 0; i < MLX4_MAX_MAC_NUM; i++) {
133 if (!table->refs[i])
134 continue;
135
136 if (mac == (MLX4_MAC_MASK & be64_to_cpu(table->entries[i]))) {
137 *idx = i;
138 return 0;
139 }
140 }
141
142 return -ENOENT;
143}
144EXPORT_SYMBOL_GPL(mlx4_find_cached_mac);
145
126int __mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac) 146int __mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac)
127{ 147{
128 struct mlx4_port_info *info = &mlx4_priv(dev)->port[port]; 148 struct mlx4_port_info *info = &mlx4_priv(dev)->port[port];
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
index 2f3f2bc7f283..663510325c22 100644
--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
+++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
@@ -3844,6 +3844,16 @@ int mlx4_QUERY_IF_STAT_wrapper(struct mlx4_dev *dev, int slave,
3844 return err; 3844 return err;
3845} 3845}
3846 3846
3847int mlx4_FLOW_STEERING_IB_UC_QP_RANGE_wrapper(struct mlx4_dev *dev, int slave,
3848 struct mlx4_vhcr *vhcr,
3849 struct mlx4_cmd_mailbox *inbox,
3850 struct mlx4_cmd_mailbox *outbox,
3851 struct mlx4_cmd_info *cmd)
3852{
3853 return -EPERM;
3854}
3855
3856
3847static void detach_qp(struct mlx4_dev *dev, int slave, struct res_qp *rqp) 3857static void detach_qp(struct mlx4_dev *dev, int slave, struct res_qp *rqp)
3848{ 3858{
3849 struct res_gid *rgid; 3859 struct res_gid *rgid;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cq.c b/drivers/net/ethernet/mellanox/mlx5/core/cq.c
index c2d660be6f76..43c5f4809526 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/cq.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/cq.c
@@ -201,10 +201,23 @@ EXPORT_SYMBOL(mlx5_core_query_cq);
201 201
202 202
203int mlx5_core_modify_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq, 203int mlx5_core_modify_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,
204 int type, struct mlx5_cq_modify_params *params) 204 struct mlx5_modify_cq_mbox_in *in, int in_sz)
205{ 205{
206 return -ENOSYS; 206 struct mlx5_modify_cq_mbox_out out;
207 int err;
208
209 memset(&out, 0, sizeof(out));
210 in->hdr.opcode = cpu_to_be16(MLX5_CMD_OP_MODIFY_CQ);
211 err = mlx5_cmd_exec(dev, in, in_sz, &out, sizeof(out));
212 if (err)
213 return err;
214
215 if (out.hdr.status)
216 return mlx5_cmd_status_to_err(&out.hdr);
217
218 return 0;
207} 219}
220EXPORT_SYMBOL(mlx5_core_modify_cq);
208 221
209int mlx5_init_cq_table(struct mlx5_core_dev *dev) 222int mlx5_init_cq_table(struct mlx5_core_dev *dev)
210{ 223{
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/debugfs.c b/drivers/net/ethernet/mellanox/mlx5/core/debugfs.c
index 80f6d127257a..10e1f1a18255 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/debugfs.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/debugfs.c
@@ -275,7 +275,7 @@ void mlx5_cq_debugfs_cleanup(struct mlx5_core_dev *dev)
275} 275}
276 276
277static u64 qp_read_field(struct mlx5_core_dev *dev, struct mlx5_core_qp *qp, 277static u64 qp_read_field(struct mlx5_core_dev *dev, struct mlx5_core_qp *qp,
278 int index) 278 int index, int *is_str)
279{ 279{
280 struct mlx5_query_qp_mbox_out *out; 280 struct mlx5_query_qp_mbox_out *out;
281 struct mlx5_qp_context *ctx; 281 struct mlx5_qp_context *ctx;
@@ -293,19 +293,40 @@ static u64 qp_read_field(struct mlx5_core_dev *dev, struct mlx5_core_qp *qp,
293 goto out; 293 goto out;
294 } 294 }
295 295
296 *is_str = 0;
296 ctx = &out->ctx; 297 ctx = &out->ctx;
297 switch (index) { 298 switch (index) {
298 case QP_PID: 299 case QP_PID:
299 param = qp->pid; 300 param = qp->pid;
300 break; 301 break;
301 case QP_STATE: 302 case QP_STATE:
302 param = be32_to_cpu(ctx->flags) >> 28; 303 param = (u64)mlx5_qp_state_str(be32_to_cpu(ctx->flags) >> 28);
304 *is_str = 1;
303 break; 305 break;
304 case QP_XPORT: 306 case QP_XPORT:
305 param = (be32_to_cpu(ctx->flags) >> 16) & 0xff; 307 param = (u64)mlx5_qp_type_str((be32_to_cpu(ctx->flags) >> 16) & 0xff);
308 *is_str = 1;
306 break; 309 break;
307 case QP_MTU: 310 case QP_MTU:
308 param = ctx->mtu_msgmax >> 5; 311 switch (ctx->mtu_msgmax >> 5) {
312 case IB_MTU_256:
313 param = 256;
314 break;
315 case IB_MTU_512:
316 param = 512;
317 break;
318 case IB_MTU_1024:
319 param = 1024;
320 break;
321 case IB_MTU_2048:
322 param = 2048;
323 break;
324 case IB_MTU_4096:
325 param = 4096;
326 break;
327 default:
328 param = 0;
329 }
309 break; 330 break;
310 case QP_N_RECV: 331 case QP_N_RECV:
311 param = 1 << ((ctx->rq_size_stride >> 3) & 0xf); 332 param = 1 << ((ctx->rq_size_stride >> 3) & 0xf);
@@ -414,6 +435,7 @@ static ssize_t dbg_read(struct file *filp, char __user *buf, size_t count,
414 struct mlx5_field_desc *desc; 435 struct mlx5_field_desc *desc;
415 struct mlx5_rsc_debug *d; 436 struct mlx5_rsc_debug *d;
416 char tbuf[18]; 437 char tbuf[18];
438 int is_str = 0;
417 u64 field; 439 u64 field;
418 int ret; 440 int ret;
419 441
@@ -424,7 +446,7 @@ static ssize_t dbg_read(struct file *filp, char __user *buf, size_t count,
424 d = (void *)(desc - desc->i) - sizeof(*d); 446 d = (void *)(desc - desc->i) - sizeof(*d);
425 switch (d->type) { 447 switch (d->type) {
426 case MLX5_DBG_RSC_QP: 448 case MLX5_DBG_RSC_QP:
427 field = qp_read_field(d->dev, d->object, desc->i); 449 field = qp_read_field(d->dev, d->object, desc->i, &is_str);
428 break; 450 break;
429 451
430 case MLX5_DBG_RSC_EQ: 452 case MLX5_DBG_RSC_EQ:
@@ -440,7 +462,12 @@ static ssize_t dbg_read(struct file *filp, char __user *buf, size_t count,
440 return -EINVAL; 462 return -EINVAL;
441 } 463 }
442 464
443 ret = snprintf(tbuf, sizeof(tbuf), "0x%llx\n", field); 465
466 if (is_str)
467 ret = snprintf(tbuf, sizeof(tbuf), "%s\n", (const char *)field);
468 else
469 ret = snprintf(tbuf, sizeof(tbuf), "0x%llx\n", field);
470
444 if (ret > 0) { 471 if (ret > 0) {
445 if (copy_to_user(buf, tbuf, ret)) 472 if (copy_to_user(buf, tbuf, ret))
446 return -EFAULT; 473 return -EFAULT;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
index 40a9f5ed814d..a064f06e0cb8 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
@@ -460,7 +460,10 @@ disable_msix:
460 460
461err_stop_poll: 461err_stop_poll:
462 mlx5_stop_health_poll(dev); 462 mlx5_stop_health_poll(dev);
463 mlx5_cmd_teardown_hca(dev); 463 if (mlx5_cmd_teardown_hca(dev)) {
464 dev_err(&dev->pdev->dev, "tear_down_hca failed, skip cleanup\n");
465 return err;
466 }
464 467
465err_pagealloc_stop: 468err_pagealloc_stop:
466 mlx5_pagealloc_stop(dev); 469 mlx5_pagealloc_stop(dev);
@@ -503,7 +506,10 @@ void mlx5_dev_cleanup(struct mlx5_core_dev *dev)
503 mlx5_eq_cleanup(dev); 506 mlx5_eq_cleanup(dev);
504 mlx5_disable_msix(dev); 507 mlx5_disable_msix(dev);
505 mlx5_stop_health_poll(dev); 508 mlx5_stop_health_poll(dev);
506 mlx5_cmd_teardown_hca(dev); 509 if (mlx5_cmd_teardown_hca(dev)) {
510 dev_err(&dev->pdev->dev, "tear_down_hca failed, skip cleanup\n");
511 return;
512 }
507 mlx5_pagealloc_stop(dev); 513 mlx5_pagealloc_stop(dev);
508 mlx5_reclaim_startup_pages(dev); 514 mlx5_reclaim_startup_pages(dev);
509 mlx5_core_disable_hca(dev); 515 mlx5_core_disable_hca(dev);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
index 37b6ad1f9a1b..d59790a82bc3 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
@@ -99,7 +99,7 @@ enum {
99 99
100enum { 100enum {
101 MLX5_MAX_RECLAIM_TIME_MILI = 5000, 101 MLX5_MAX_RECLAIM_TIME_MILI = 5000,
102 MLX5_NUM_4K_IN_PAGE = PAGE_SIZE / 4096, 102 MLX5_NUM_4K_IN_PAGE = PAGE_SIZE / MLX5_ADAPTER_PAGE_SIZE,
103}; 103};
104 104
105static int insert_page(struct mlx5_core_dev *dev, u64 addr, struct page *page, u16 func_id) 105static int insert_page(struct mlx5_core_dev *dev, u64 addr, struct page *page, u16 func_id)
@@ -192,10 +192,8 @@ static int alloc_4k(struct mlx5_core_dev *dev, u64 *addr)
192 struct fw_page *fp; 192 struct fw_page *fp;
193 unsigned n; 193 unsigned n;
194 194
195 if (list_empty(&dev->priv.free_list)) { 195 if (list_empty(&dev->priv.free_list))
196 return -ENOMEM; 196 return -ENOMEM;
197 mlx5_core_warn(dev, "\n");
198 }
199 197
200 fp = list_entry(dev->priv.free_list.next, struct fw_page, list); 198 fp = list_entry(dev->priv.free_list.next, struct fw_page, list);
201 n = find_first_bit(&fp->bitmask, 8 * sizeof(fp->bitmask)); 199 n = find_first_bit(&fp->bitmask, 8 * sizeof(fp->bitmask));
@@ -208,7 +206,7 @@ static int alloc_4k(struct mlx5_core_dev *dev, u64 *addr)
208 if (!fp->free_count) 206 if (!fp->free_count)
209 list_del(&fp->list); 207 list_del(&fp->list);
210 208
211 *addr = fp->addr + n * 4096; 209 *addr = fp->addr + n * MLX5_ADAPTER_PAGE_SIZE;
212 210
213 return 0; 211 return 0;
214} 212}
@@ -224,14 +222,15 @@ static void free_4k(struct mlx5_core_dev *dev, u64 addr)
224 return; 222 return;
225 } 223 }
226 224
227 n = (addr & ~PAGE_MASK) % 4096; 225 n = (addr & ~PAGE_MASK) >> MLX5_ADAPTER_PAGE_SHIFT;
228 fwp->free_count++; 226 fwp->free_count++;
229 set_bit(n, &fwp->bitmask); 227 set_bit(n, &fwp->bitmask);
230 if (fwp->free_count == MLX5_NUM_4K_IN_PAGE) { 228 if (fwp->free_count == MLX5_NUM_4K_IN_PAGE) {
231 rb_erase(&fwp->rb_node, &dev->priv.page_root); 229 rb_erase(&fwp->rb_node, &dev->priv.page_root);
232 if (fwp->free_count != 1) 230 if (fwp->free_count != 1)
233 list_del(&fwp->list); 231 list_del(&fwp->list);
234 dma_unmap_page(&dev->pdev->dev, addr, PAGE_SIZE, DMA_BIDIRECTIONAL); 232 dma_unmap_page(&dev->pdev->dev, addr & PAGE_MASK, PAGE_SIZE,
233 DMA_BIDIRECTIONAL);
235 __free_page(fwp->page); 234 __free_page(fwp->page);
236 kfree(fwp); 235 kfree(fwp);
237 } else if (fwp->free_count == 1) { 236 } else if (fwp->free_count == 1) {
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/port.c b/drivers/net/ethernet/mellanox/mlx5/core/port.c
index f6afe7b5a675..8c9ac870ecb1 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/port.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/port.c
@@ -57,7 +57,7 @@ int mlx5_core_access_reg(struct mlx5_core_dev *dev, void *data_in,
57 in->arg = cpu_to_be32(arg); 57 in->arg = cpu_to_be32(arg);
58 in->register_id = cpu_to_be16(reg_num); 58 in->register_id = cpu_to_be16(reg_num);
59 err = mlx5_cmd_exec(dev, in, sizeof(*in) + size_in, out, 59 err = mlx5_cmd_exec(dev, in, sizeof(*in) + size_in, out,
60 sizeof(out) + size_out); 60 sizeof(*out) + size_out);
61 if (err) 61 if (err)
62 goto ex2; 62 goto ex2;
63 63
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/qp.c b/drivers/net/ethernet/mellanox/mlx5/core/qp.c
index 54faf8bfcaf4..510576213dd0 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/qp.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/qp.c
@@ -74,7 +74,7 @@ int mlx5_core_create_qp(struct mlx5_core_dev *dev,
74 struct mlx5_destroy_qp_mbox_out dout; 74 struct mlx5_destroy_qp_mbox_out dout;
75 int err; 75 int err;
76 76
77 memset(&dout, 0, sizeof(dout)); 77 memset(&out, 0, sizeof(out));
78 in->hdr.opcode = cpu_to_be16(MLX5_CMD_OP_CREATE_QP); 78 in->hdr.opcode = cpu_to_be16(MLX5_CMD_OP_CREATE_QP);
79 79
80 err = mlx5_cmd_exec(dev, in, inlen, &out, sizeof(out)); 80 err = mlx5_cmd_exec(dev, in, inlen, &out, sizeof(out));
@@ -84,7 +84,8 @@ int mlx5_core_create_qp(struct mlx5_core_dev *dev,
84 } 84 }
85 85
86 if (out.hdr.status) { 86 if (out.hdr.status) {
87 pr_warn("current num of QPs 0x%x\n", atomic_read(&dev->num_qps)); 87 mlx5_core_warn(dev, "current num of QPs 0x%x\n",
88 atomic_read(&dev->num_qps));
88 return mlx5_cmd_status_to_err(&out.hdr); 89 return mlx5_cmd_status_to_err(&out.hdr);
89 } 90 }
90 91
diff --git a/drivers/scsi/scsi_transport_srp.c b/drivers/scsi/scsi_transport_srp.c
index 2700a5a09bd4..d47ffc8d3e43 100644
--- a/drivers/scsi/scsi_transport_srp.c
+++ b/drivers/scsi/scsi_transport_srp.c
@@ -64,10 +64,14 @@ static inline struct Scsi_Host *rport_to_shost(struct srp_rport *r)
64 64
65/** 65/**
66 * srp_tmo_valid() - check timeout combination validity 66 * srp_tmo_valid() - check timeout combination validity
67 * @reconnect_delay: Reconnect delay in seconds.
68 * @fast_io_fail_tmo: Fast I/O fail timeout in seconds.
69 * @dev_loss_tmo: Device loss timeout in seconds.
67 * 70 *
68 * The combination of the timeout parameters must be such that SCSI commands 71 * The combination of the timeout parameters must be such that SCSI commands
69 * are finished in a reasonable time. Hence do not allow the fast I/O fail 72 * are finished in a reasonable time. Hence do not allow the fast I/O fail
70 * timeout to exceed SCSI_DEVICE_BLOCK_MAX_TIMEOUT. Furthermore, these 73 * timeout to exceed SCSI_DEVICE_BLOCK_MAX_TIMEOUT nor allow dev_loss_tmo to
74 * exceed that limit if failing I/O fast has been disabled. Furthermore, these
71 * parameters must be such that multipath can detect failed paths timely. 75 * parameters must be such that multipath can detect failed paths timely.
72 * Hence do not allow all three parameters to be disabled simultaneously. 76 * Hence do not allow all three parameters to be disabled simultaneously.
73 */ 77 */
@@ -79,6 +83,9 @@ int srp_tmo_valid(int reconnect_delay, int fast_io_fail_tmo, int dev_loss_tmo)
79 return -EINVAL; 83 return -EINVAL;
80 if (fast_io_fail_tmo > SCSI_DEVICE_BLOCK_MAX_TIMEOUT) 84 if (fast_io_fail_tmo > SCSI_DEVICE_BLOCK_MAX_TIMEOUT)
81 return -EINVAL; 85 return -EINVAL;
86 if (fast_io_fail_tmo < 0 &&
87 dev_loss_tmo > SCSI_DEVICE_BLOCK_MAX_TIMEOUT)
88 return -EINVAL;
82 if (dev_loss_tmo >= LONG_MAX / HZ) 89 if (dev_loss_tmo >= LONG_MAX / HZ)
83 return -EINVAL; 90 return -EINVAL;
84 if (fast_io_fail_tmo >= 0 && dev_loss_tmo >= 0 && 91 if (fast_io_fail_tmo >= 0 && dev_loss_tmo >= 0 &&
@@ -368,6 +375,7 @@ invalid:
368 375
369/** 376/**
370 * srp_reconnect_work() - reconnect and schedule a new attempt if necessary 377 * srp_reconnect_work() - reconnect and schedule a new attempt if necessary
378 * @work: Work structure used for scheduling this operation.
371 */ 379 */
372static void srp_reconnect_work(struct work_struct *work) 380static void srp_reconnect_work(struct work_struct *work)
373{ 381{
@@ -408,6 +416,7 @@ static void __rport_fail_io_fast(struct srp_rport *rport)
408 416
409/** 417/**
410 * rport_fast_io_fail_timedout() - fast I/O failure timeout handler 418 * rport_fast_io_fail_timedout() - fast I/O failure timeout handler
419 * @work: Work structure used for scheduling this operation.
411 */ 420 */
412static void rport_fast_io_fail_timedout(struct work_struct *work) 421static void rport_fast_io_fail_timedout(struct work_struct *work)
413{ 422{
@@ -426,6 +435,7 @@ static void rport_fast_io_fail_timedout(struct work_struct *work)
426 435
427/** 436/**
428 * rport_dev_loss_timedout() - device loss timeout handler 437 * rport_dev_loss_timedout() - device loss timeout handler
438 * @work: Work structure used for scheduling this operation.
429 */ 439 */
430static void rport_dev_loss_timedout(struct work_struct *work) 440static void rport_dev_loss_timedout(struct work_struct *work)
431{ 441{
@@ -452,42 +462,35 @@ static void __srp_start_tl_fail_timers(struct srp_rport *rport)
452 462
453 lockdep_assert_held(&rport->mutex); 463 lockdep_assert_held(&rport->mutex);
454 464
455 if (!rport->deleted) { 465 delay = rport->reconnect_delay;
456 delay = rport->reconnect_delay; 466 fast_io_fail_tmo = rport->fast_io_fail_tmo;
457 fast_io_fail_tmo = rport->fast_io_fail_tmo; 467 dev_loss_tmo = rport->dev_loss_tmo;
458 dev_loss_tmo = rport->dev_loss_tmo; 468 pr_debug("%s current state: %d\n", dev_name(&shost->shost_gendev),
459 pr_debug("%s current state: %d\n", 469 rport->state);
460 dev_name(&shost->shost_gendev), rport->state);
461 470
462 if (delay > 0) 471 if (rport->state == SRP_RPORT_LOST)
463 queue_delayed_work(system_long_wq, 472 return;
464 &rport->reconnect_work, 473 if (delay > 0)
465 1UL * delay * HZ); 474 queue_delayed_work(system_long_wq, &rport->reconnect_work,
466 if (fast_io_fail_tmo >= 0 && 475 1UL * delay * HZ);
467 srp_rport_set_state(rport, SRP_RPORT_BLOCKED) == 0) { 476 if (srp_rport_set_state(rport, SRP_RPORT_BLOCKED) == 0) {
468 pr_debug("%s new state: %d\n", 477 pr_debug("%s new state: %d\n", dev_name(&shost->shost_gendev),
469 dev_name(&shost->shost_gendev), 478 rport->state);
470 rport->state); 479 scsi_target_block(&shost->shost_gendev);
471 scsi_target_block(&shost->shost_gendev); 480 if (fast_io_fail_tmo >= 0)
472 queue_delayed_work(system_long_wq, 481 queue_delayed_work(system_long_wq,
473 &rport->fast_io_fail_work, 482 &rport->fast_io_fail_work,
474 1UL * fast_io_fail_tmo * HZ); 483 1UL * fast_io_fail_tmo * HZ);
475 }
476 if (dev_loss_tmo >= 0) 484 if (dev_loss_tmo >= 0)
477 queue_delayed_work(system_long_wq, 485 queue_delayed_work(system_long_wq,
478 &rport->dev_loss_work, 486 &rport->dev_loss_work,
479 1UL * dev_loss_tmo * HZ); 487 1UL * dev_loss_tmo * HZ);
480 } else {
481 pr_debug("%s has already been deleted\n",
482 dev_name(&shost->shost_gendev));
483 srp_rport_set_state(rport, SRP_RPORT_FAIL_FAST);
484 scsi_target_unblock(&shost->shost_gendev,
485 SDEV_TRANSPORT_OFFLINE);
486 } 488 }
487} 489}
488 490
489/** 491/**
490 * srp_start_tl_fail_timers() - start the transport layer failure timers 492 * srp_start_tl_fail_timers() - start the transport layer failure timers
493 * @rport: SRP target port.
491 * 494 *
492 * Start the transport layer fast I/O failure and device loss timers. Do not 495 * Start the transport layer fast I/O failure and device loss timers. Do not
493 * modify a timer that was already started. 496 * modify a timer that was already started.
@@ -502,6 +505,7 @@ EXPORT_SYMBOL(srp_start_tl_fail_timers);
502 505
503/** 506/**
504 * scsi_request_fn_active() - number of kernel threads inside scsi_request_fn() 507 * scsi_request_fn_active() - number of kernel threads inside scsi_request_fn()
508 * @shost: SCSI host for which to count the number of scsi_request_fn() callers.
505 */ 509 */
506static int scsi_request_fn_active(struct Scsi_Host *shost) 510static int scsi_request_fn_active(struct Scsi_Host *shost)
507{ 511{
@@ -522,6 +526,7 @@ static int scsi_request_fn_active(struct Scsi_Host *shost)
522 526
523/** 527/**
524 * srp_reconnect_rport() - reconnect to an SRP target port 528 * srp_reconnect_rport() - reconnect to an SRP target port
529 * @rport: SRP target port.
525 * 530 *
526 * Blocks SCSI command queueing before invoking reconnect() such that 531 * Blocks SCSI command queueing before invoking reconnect() such that
527 * queuecommand() won't be invoked concurrently with reconnect() from outside 532 * queuecommand() won't be invoked concurrently with reconnect() from outside
@@ -556,7 +561,7 @@ int srp_reconnect_rport(struct srp_rport *rport)
556 scsi_target_block(&shost->shost_gendev); 561 scsi_target_block(&shost->shost_gendev);
557 while (scsi_request_fn_active(shost)) 562 while (scsi_request_fn_active(shost))
558 msleep(20); 563 msleep(20);
559 res = i->f->reconnect(rport); 564 res = rport->state != SRP_RPORT_LOST ? i->f->reconnect(rport) : -ENODEV;
560 pr_debug("%s (state %d): transport.reconnect() returned %d\n", 565 pr_debug("%s (state %d): transport.reconnect() returned %d\n",
561 dev_name(&shost->shost_gendev), rport->state, res); 566 dev_name(&shost->shost_gendev), rport->state, res);
562 if (res == 0) { 567 if (res == 0) {
@@ -578,9 +583,9 @@ int srp_reconnect_rport(struct srp_rport *rport)
578 spin_unlock_irq(shost->host_lock); 583 spin_unlock_irq(shost->host_lock);
579 } else if (rport->state == SRP_RPORT_RUNNING) { 584 } else if (rport->state == SRP_RPORT_RUNNING) {
580 /* 585 /*
581 * srp_reconnect_rport() was invoked with fast_io_fail 586 * srp_reconnect_rport() has been invoked with fast_io_fail
582 * off. Mark the port as failed and start the TL failure 587 * and dev_loss off. Mark the port as failed and start the TL
583 * timers if these had not yet been started. 588 * failure timers if these had not yet been started.
584 */ 589 */
585 __rport_fail_io_fast(rport); 590 __rport_fail_io_fast(rport);
586 scsi_target_unblock(&shost->shost_gendev, 591 scsi_target_unblock(&shost->shost_gendev,
@@ -599,6 +604,7 @@ EXPORT_SYMBOL(srp_reconnect_rport);
599 604
600/** 605/**
601 * srp_timed_out() - SRP transport intercept of the SCSI timeout EH 606 * srp_timed_out() - SRP transport intercept of the SCSI timeout EH
607 * @scmd: SCSI command.
602 * 608 *
603 * If a timeout occurs while an rport is in the blocked state, ask the SCSI 609 * If a timeout occurs while an rport is in the blocked state, ask the SCSI
604 * EH to continue waiting (BLK_EH_RESET_TIMER). Otherwise let the SCSI core 610 * EH to continue waiting (BLK_EH_RESET_TIMER). Otherwise let the SCSI core
@@ -622,10 +628,6 @@ static void srp_rport_release(struct device *dev)
622{ 628{
623 struct srp_rport *rport = dev_to_rport(dev); 629 struct srp_rport *rport = dev_to_rport(dev);
624 630
625 cancel_delayed_work_sync(&rport->reconnect_work);
626 cancel_delayed_work_sync(&rport->fast_io_fail_work);
627 cancel_delayed_work_sync(&rport->dev_loss_work);
628
629 put_device(dev->parent); 631 put_device(dev->parent);
630 kfree(rport); 632 kfree(rport);
631} 633}
@@ -674,6 +676,7 @@ static int srp_host_match(struct attribute_container *cont, struct device *dev)
674 676
675/** 677/**
676 * srp_rport_get() - increment rport reference count 678 * srp_rport_get() - increment rport reference count
679 * @rport: SRP target port.
677 */ 680 */
678void srp_rport_get(struct srp_rport *rport) 681void srp_rport_get(struct srp_rport *rport)
679{ 682{
@@ -683,6 +686,7 @@ EXPORT_SYMBOL(srp_rport_get);
683 686
684/** 687/**
685 * srp_rport_put() - decrement rport reference count 688 * srp_rport_put() - decrement rport reference count
689 * @rport: SRP target port.
686 */ 690 */
687void srp_rport_put(struct srp_rport *rport) 691void srp_rport_put(struct srp_rport *rport)
688{ 692{
@@ -780,12 +784,6 @@ void srp_rport_del(struct srp_rport *rport)
780 device_del(dev); 784 device_del(dev);
781 transport_destroy_device(dev); 785 transport_destroy_device(dev);
782 786
783 mutex_lock(&rport->mutex);
784 if (rport->state == SRP_RPORT_BLOCKED)
785 __rport_fail_io_fast(rport);
786 rport->deleted = true;
787 mutex_unlock(&rport->mutex);
788
789 put_device(dev); 787 put_device(dev);
790} 788}
791EXPORT_SYMBOL_GPL(srp_rport_del); 789EXPORT_SYMBOL_GPL(srp_rport_del);
@@ -810,6 +808,27 @@ void srp_remove_host(struct Scsi_Host *shost)
810} 808}
811EXPORT_SYMBOL_GPL(srp_remove_host); 809EXPORT_SYMBOL_GPL(srp_remove_host);
812 810
811/**
812 * srp_stop_rport_timers - stop the transport layer recovery timers
813 *
814 * Must be called after srp_remove_host() and scsi_remove_host(). The caller
815 * must hold a reference on the rport (rport->dev) and on the SCSI host
816 * (rport->dev.parent).
817 */
818void srp_stop_rport_timers(struct srp_rport *rport)
819{
820 mutex_lock(&rport->mutex);
821 if (rport->state == SRP_RPORT_BLOCKED)
822 __rport_fail_io_fast(rport);
823 srp_rport_set_state(rport, SRP_RPORT_LOST);
824 mutex_unlock(&rport->mutex);
825
826 cancel_delayed_work_sync(&rport->reconnect_work);
827 cancel_delayed_work_sync(&rport->fast_io_fail_work);
828 cancel_delayed_work_sync(&rport->dev_loss_work);
829}
830EXPORT_SYMBOL_GPL(srp_stop_rport_timers);
831
813static int srp_tsk_mgmt_response(struct Scsi_Host *shost, u64 nexus, u64 tm_id, 832static int srp_tsk_mgmt_response(struct Scsi_Host *shost, u64 nexus, u64 tm_id,
814 int result) 833 int result)
815{ 834{
diff --git a/include/linux/mlx4/cmd.h b/include/linux/mlx4/cmd.h
index 8df61bc5da00..ff36620f88a7 100644
--- a/include/linux/mlx4/cmd.h
+++ b/include/linux/mlx4/cmd.h
@@ -157,6 +157,7 @@ enum {
157 /* register/delete flow steering network rules */ 157 /* register/delete flow steering network rules */
158 MLX4_QP_FLOW_STEERING_ATTACH = 0x65, 158 MLX4_QP_FLOW_STEERING_ATTACH = 0x65,
159 MLX4_QP_FLOW_STEERING_DETACH = 0x66, 159 MLX4_QP_FLOW_STEERING_DETACH = 0x66,
160 MLX4_FLOW_STEERING_IB_UC_QP_RANGE = 0x64,
160}; 161};
161 162
162enum { 163enum {
diff --git a/include/linux/mlx4/cq.h b/include/linux/mlx4/cq.h
index 98fa492cf406..e1862997f933 100644
--- a/include/linux/mlx4/cq.h
+++ b/include/linux/mlx4/cq.h
@@ -34,6 +34,7 @@
34#define MLX4_CQ_H 34#define MLX4_CQ_H
35 35
36#include <linux/types.h> 36#include <linux/types.h>
37#include <uapi/linux/if_ether.h>
37 38
38#include <linux/mlx4/device.h> 39#include <linux/mlx4/device.h>
39#include <linux/mlx4/doorbell.h> 40#include <linux/mlx4/doorbell.h>
@@ -43,10 +44,15 @@ struct mlx4_cqe {
43 __be32 immed_rss_invalid; 44 __be32 immed_rss_invalid;
44 __be32 g_mlpath_rqpn; 45 __be32 g_mlpath_rqpn;
45 __be16 sl_vid; 46 __be16 sl_vid;
46 __be16 rlid; 47 union {
47 __be16 status; 48 struct {
48 u8 ipv6_ext_mask; 49 __be16 rlid;
49 u8 badfcs_enc; 50 __be16 status;
51 u8 ipv6_ext_mask;
52 u8 badfcs_enc;
53 };
54 u8 smac[ETH_ALEN];
55 };
50 __be32 byte_cnt; 56 __be32 byte_cnt;
51 __be16 wqe_index; 57 __be16 wqe_index;
52 __be16 checksum; 58 __be16 checksum;
@@ -83,6 +89,7 @@ struct mlx4_ts_cqe {
83enum { 89enum {
84 MLX4_CQE_VLAN_PRESENT_MASK = 1 << 29, 90 MLX4_CQE_VLAN_PRESENT_MASK = 1 << 29,
85 MLX4_CQE_QPN_MASK = 0xffffff, 91 MLX4_CQE_QPN_MASK = 0xffffff,
92 MLX4_CQE_VID_MASK = 0xfff,
86}; 93};
87 94
88enum { 95enum {
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index 7d3a523160ba..ac5cb1d92487 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -160,7 +160,8 @@ enum {
160 MLX4_DEV_CAP_FLAG2_TS = 1LL << 5, 160 MLX4_DEV_CAP_FLAG2_TS = 1LL << 5,
161 MLX4_DEV_CAP_FLAG2_VLAN_CONTROL = 1LL << 6, 161 MLX4_DEV_CAP_FLAG2_VLAN_CONTROL = 1LL << 6,
162 MLX4_DEV_CAP_FLAG2_FSM = 1LL << 7, 162 MLX4_DEV_CAP_FLAG2_FSM = 1LL << 7,
163 MLX4_DEV_CAP_FLAG2_UPDATE_QP = 1LL << 8 163 MLX4_DEV_CAP_FLAG2_UPDATE_QP = 1LL << 8,
164 MLX4_DEV_CAP_FLAG2_DMFS_IPOIB = 1LL << 9
164}; 165};
165 166
166enum { 167enum {
@@ -1095,6 +1096,7 @@ int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn,
1095int mlx4_SET_PORT_PRIO2TC(struct mlx4_dev *dev, u8 port, u8 *prio2tc); 1096int mlx4_SET_PORT_PRIO2TC(struct mlx4_dev *dev, u8 port, u8 *prio2tc);
1096int mlx4_SET_PORT_SCHEDULER(struct mlx4_dev *dev, u8 port, u8 *tc_tx_bw, 1097int mlx4_SET_PORT_SCHEDULER(struct mlx4_dev *dev, u8 port, u8 *tc_tx_bw,
1097 u8 *pg, u16 *ratelimit); 1098 u8 *pg, u16 *ratelimit);
1099int mlx4_find_cached_mac(struct mlx4_dev *dev, u8 port, u64 mac, int *idx);
1098int mlx4_find_cached_vlan(struct mlx4_dev *dev, u8 port, u16 vid, int *idx); 1100int mlx4_find_cached_vlan(struct mlx4_dev *dev, u8 port, u16 vid, int *idx);
1099int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index); 1101int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index);
1100void mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, u16 vlan); 1102void mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, u16 vlan);
@@ -1144,6 +1146,9 @@ int set_and_calc_slave_port_state(struct mlx4_dev *dev, int slave, u8 port, int
1144void mlx4_put_slave_node_guid(struct mlx4_dev *dev, int slave, __be64 guid); 1146void mlx4_put_slave_node_guid(struct mlx4_dev *dev, int slave, __be64 guid);
1145__be64 mlx4_get_slave_node_guid(struct mlx4_dev *dev, int slave); 1147__be64 mlx4_get_slave_node_guid(struct mlx4_dev *dev, int slave);
1146 1148
1149int mlx4_FLOW_STEERING_IB_UC_QP_RANGE(struct mlx4_dev *dev, u32 min_range_qpn,
1150 u32 max_range_qpn);
1151
1147cycle_t mlx4_read_clock(struct mlx4_dev *dev); 1152cycle_t mlx4_read_clock(struct mlx4_dev *dev);
1148 1153
1149#endif /* MLX4_DEVICE_H */ 1154#endif /* MLX4_DEVICE_H */
diff --git a/include/linux/mlx5/cq.h b/include/linux/mlx5/cq.h
index 3db67f73d96d..2202c7f72b75 100644
--- a/include/linux/mlx5/cq.h
+++ b/include/linux/mlx5/cq.h
@@ -79,15 +79,23 @@ enum {
79 MLX5_CQE_RESP_SEND = 2, 79 MLX5_CQE_RESP_SEND = 2,
80 MLX5_CQE_RESP_SEND_IMM = 3, 80 MLX5_CQE_RESP_SEND_IMM = 3,
81 MLX5_CQE_RESP_SEND_INV = 4, 81 MLX5_CQE_RESP_SEND_INV = 4,
82 MLX5_CQE_RESIZE_CQ = 0xff, /* TBD */ 82 MLX5_CQE_RESIZE_CQ = 5,
83 MLX5_CQE_REQ_ERR = 13, 83 MLX5_CQE_REQ_ERR = 13,
84 MLX5_CQE_RESP_ERR = 14, 84 MLX5_CQE_RESP_ERR = 14,
85 MLX5_CQE_INVALID = 15,
85}; 86};
86 87
87enum { 88enum {
88 MLX5_CQ_MODIFY_RESEIZE = 0, 89 MLX5_CQ_MODIFY_PERIOD = 1 << 0,
89 MLX5_CQ_MODIFY_MODER = 1, 90 MLX5_CQ_MODIFY_COUNT = 1 << 1,
90 MLX5_CQ_MODIFY_MAPPING = 2, 91 MLX5_CQ_MODIFY_OVERRUN = 1 << 2,
92};
93
94enum {
95 MLX5_CQ_OPMOD_RESIZE = 1,
96 MLX5_MODIFY_CQ_MASK_LOG_SIZE = 1 << 0,
97 MLX5_MODIFY_CQ_MASK_PG_OFFSET = 1 << 1,
98 MLX5_MODIFY_CQ_MASK_PG_SIZE = 1 << 2,
91}; 99};
92 100
93struct mlx5_cq_modify_params { 101struct mlx5_cq_modify_params {
@@ -158,7 +166,7 @@ int mlx5_core_destroy_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq);
158int mlx5_core_query_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq, 166int mlx5_core_query_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,
159 struct mlx5_query_cq_mbox_out *out); 167 struct mlx5_query_cq_mbox_out *out);
160int mlx5_core_modify_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq, 168int mlx5_core_modify_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,
161 int type, struct mlx5_cq_modify_params *params); 169 struct mlx5_modify_cq_mbox_in *in, int in_sz);
162int mlx5_debug_cq_add(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq); 170int mlx5_debug_cq_add(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq);
163void mlx5_debug_cq_remove(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq); 171void mlx5_debug_cq_remove(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq);
164 172
diff --git a/include/linux/mlx5/device.h b/include/linux/mlx5/device.h
index da78875807fc..817a6fae6d2c 100644
--- a/include/linux/mlx5/device.h
+++ b/include/linux/mlx5/device.h
@@ -104,9 +104,10 @@ enum {
104}; 104};
105 105
106enum { 106enum {
107 MLX5_BF_REGS_PER_PAGE = 4, 107 MLX5_BF_REGS_PER_PAGE = 4,
108 MLX5_MAX_UAR_PAGES = 1 << 8, 108 MLX5_MAX_UAR_PAGES = 1 << 8,
109 MLX5_MAX_UUARS = MLX5_MAX_UAR_PAGES * MLX5_BF_REGS_PER_PAGE, 109 MLX5_NON_FP_BF_REGS_PER_PAGE = 2,
110 MLX5_MAX_UUARS = MLX5_MAX_UAR_PAGES * MLX5_NON_FP_BF_REGS_PER_PAGE,
110}; 111};
111 112
112enum { 113enum {
@@ -176,6 +177,8 @@ enum {
176 MLX5_DEV_CAP_FLAG_APM = 1LL << 17, 177 MLX5_DEV_CAP_FLAG_APM = 1LL << 17,
177 MLX5_DEV_CAP_FLAG_ATOMIC = 1LL << 18, 178 MLX5_DEV_CAP_FLAG_ATOMIC = 1LL << 18,
178 MLX5_DEV_CAP_FLAG_ON_DMND_PG = 1LL << 24, 179 MLX5_DEV_CAP_FLAG_ON_DMND_PG = 1LL << 24,
180 MLX5_DEV_CAP_FLAG_CQ_MODER = 1LL << 29,
181 MLX5_DEV_CAP_FLAG_RESIZE_CQ = 1LL << 30,
179 MLX5_DEV_CAP_FLAG_RESIZE_SRQ = 1LL << 32, 182 MLX5_DEV_CAP_FLAG_RESIZE_SRQ = 1LL << 32,
180 MLX5_DEV_CAP_FLAG_REMOTE_FENCE = 1LL << 38, 183 MLX5_DEV_CAP_FLAG_REMOTE_FENCE = 1LL << 38,
181 MLX5_DEV_CAP_FLAG_TLP_HINTS = 1LL << 39, 184 MLX5_DEV_CAP_FLAG_TLP_HINTS = 1LL << 39,
@@ -231,7 +234,8 @@ enum {
231}; 234};
232 235
233enum { 236enum {
234 MLX5_ADAPTER_PAGE_SHIFT = 12 237 MLX5_ADAPTER_PAGE_SHIFT = 12,
238 MLX5_ADAPTER_PAGE_SIZE = 1 << MLX5_ADAPTER_PAGE_SHIFT,
235}; 239};
236 240
237enum { 241enum {
@@ -697,6 +701,20 @@ struct mlx5_query_cq_mbox_out {
697 __be64 pas[0]; 701 __be64 pas[0];
698}; 702};
699 703
704struct mlx5_modify_cq_mbox_in {
705 struct mlx5_inbox_hdr hdr;
706 __be32 cqn;
707 __be32 field_select;
708 struct mlx5_cq_context ctx;
709 u8 rsvd[192];
710 __be64 pas[0];
711};
712
713struct mlx5_modify_cq_mbox_out {
714 struct mlx5_outbox_hdr hdr;
715 u8 rsvd[8];
716};
717
700struct mlx5_enable_hca_mbox_in { 718struct mlx5_enable_hca_mbox_in {
701 struct mlx5_inbox_hdr hdr; 719 struct mlx5_inbox_hdr hdr;
702 u8 rsvd[8]; 720 u8 rsvd[8];
@@ -831,8 +849,8 @@ struct mlx5_create_mkey_mbox_in {
831 struct mlx5_mkey_seg seg; 849 struct mlx5_mkey_seg seg;
832 u8 rsvd1[16]; 850 u8 rsvd1[16];
833 __be32 xlat_oct_act_size; 851 __be32 xlat_oct_act_size;
834 __be32 bsf_coto_act_size; 852 __be32 rsvd2;
835 u8 rsvd2[168]; 853 u8 rsvd3[168];
836 __be64 pas[0]; 854 __be64 pas[0];
837}; 855};
838 856
@@ -871,6 +889,7 @@ struct mlx5_modify_mkey_mbox_in {
871 889
872struct mlx5_modify_mkey_mbox_out { 890struct mlx5_modify_mkey_mbox_out {
873 struct mlx5_outbox_hdr hdr; 891 struct mlx5_outbox_hdr hdr;
892 u8 rsvd[8];
874}; 893};
875 894
876struct mlx5_dump_mkey_mbox_in { 895struct mlx5_dump_mkey_mbox_in {
diff --git a/include/linux/mlx5/qp.h b/include/linux/mlx5/qp.h
index d9e3eacb3a7f..d51eff713549 100644
--- a/include/linux/mlx5/qp.h
+++ b/include/linux/mlx5/qp.h
@@ -464,4 +464,49 @@ void mlx5_cleanup_qp_table(struct mlx5_core_dev *dev);
464int mlx5_debug_qp_add(struct mlx5_core_dev *dev, struct mlx5_core_qp *qp); 464int mlx5_debug_qp_add(struct mlx5_core_dev *dev, struct mlx5_core_qp *qp);
465void mlx5_debug_qp_remove(struct mlx5_core_dev *dev, struct mlx5_core_qp *qp); 465void mlx5_debug_qp_remove(struct mlx5_core_dev *dev, struct mlx5_core_qp *qp);
466 466
467static inline const char *mlx5_qp_type_str(int type)
468{
469 switch (type) {
470 case MLX5_QP_ST_RC: return "RC";
471 case MLX5_QP_ST_UC: return "C";
472 case MLX5_QP_ST_UD: return "UD";
473 case MLX5_QP_ST_XRC: return "XRC";
474 case MLX5_QP_ST_MLX: return "MLX";
475 case MLX5_QP_ST_QP0: return "QP0";
476 case MLX5_QP_ST_QP1: return "QP1";
477 case MLX5_QP_ST_RAW_ETHERTYPE: return "RAW_ETHERTYPE";
478 case MLX5_QP_ST_RAW_IPV6: return "RAW_IPV6";
479 case MLX5_QP_ST_SNIFFER: return "SNIFFER";
480 case MLX5_QP_ST_SYNC_UMR: return "SYNC_UMR";
481 case MLX5_QP_ST_PTP_1588: return "PTP_1588";
482 case MLX5_QP_ST_REG_UMR: return "REG_UMR";
483 default: return "Invalid transport type";
484 }
485}
486
487static inline const char *mlx5_qp_state_str(int state)
488{
489 switch (state) {
490 case MLX5_QP_STATE_RST:
491 return "RST";
492 case MLX5_QP_STATE_INIT:
493 return "INIT";
494 case MLX5_QP_STATE_RTR:
495 return "RTR";
496 case MLX5_QP_STATE_RTS:
497 return "RTS";
498 case MLX5_QP_STATE_SQER:
499 return "SQER";
500 case MLX5_QP_STATE_SQD:
501 return "SQD";
502 case MLX5_QP_STATE_ERR:
503 return "ERR";
504 case MLX5_QP_STATE_SQ_DRAINING:
505 return "SQ_DRAINING";
506 case MLX5_QP_STATE_SUSPENDED:
507 return "SUSPENDED";
508 default: return "Invalid QP state";
509 }
510}
511
467#endif /* MLX5_QP_H */ 512#endif /* MLX5_QP_H */
diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h
index f3ac0f2c4c66..ce55906b54a0 100644
--- a/include/rdma/ib_addr.h
+++ b/include/rdma/ib_addr.h
@@ -38,10 +38,15 @@
38#include <linux/in6.h> 38#include <linux/in6.h>
39#include <linux/if_arp.h> 39#include <linux/if_arp.h>
40#include <linux/netdevice.h> 40#include <linux/netdevice.h>
41#include <linux/inetdevice.h>
41#include <linux/socket.h> 42#include <linux/socket.h>
42#include <linux/if_vlan.h> 43#include <linux/if_vlan.h>
44#include <net/ipv6.h>
45#include <net/if_inet6.h>
46#include <net/ip.h>
43#include <rdma/ib_verbs.h> 47#include <rdma/ib_verbs.h>
44#include <rdma/ib_pack.h> 48#include <rdma/ib_pack.h>
49#include <net/ipv6.h>
45 50
46struct rdma_addr_client { 51struct rdma_addr_client {
47 atomic_t refcount; 52 atomic_t refcount;
@@ -72,7 +77,8 @@ struct rdma_dev_addr {
72 * rdma_translate_ip - Translate a local IP address to an RDMA hardware 77 * rdma_translate_ip - Translate a local IP address to an RDMA hardware
73 * address. 78 * address.
74 */ 79 */
75int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr); 80int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr,
81 u16 *vlan_id);
76 82
77/** 83/**
78 * rdma_resolve_ip - Resolve source and destination IP addresses to 84 * rdma_resolve_ip - Resolve source and destination IP addresses to
@@ -104,6 +110,10 @@ int rdma_copy_addr(struct rdma_dev_addr *dev_addr, struct net_device *dev,
104 110
105int rdma_addr_size(struct sockaddr *addr); 111int rdma_addr_size(struct sockaddr *addr);
106 112
113int rdma_addr_find_smac_by_sgid(union ib_gid *sgid, u8 *smac, u16 *vlan_id);
114int rdma_addr_find_dmac_by_grh(union ib_gid *sgid, union ib_gid *dgid, u8 *smac,
115 u16 *vlan_id);
116
107static inline u16 ib_addr_get_pkey(struct rdma_dev_addr *dev_addr) 117static inline u16 ib_addr_get_pkey(struct rdma_dev_addr *dev_addr)
108{ 118{
109 return ((u16)dev_addr->broadcast[8] << 8) | (u16)dev_addr->broadcast[9]; 119 return ((u16)dev_addr->broadcast[8] << 8) | (u16)dev_addr->broadcast[9];
@@ -126,41 +136,60 @@ static inline int rdma_addr_gid_offset(struct rdma_dev_addr *dev_addr)
126 return dev_addr->dev_type == ARPHRD_INFINIBAND ? 4 : 0; 136 return dev_addr->dev_type == ARPHRD_INFINIBAND ? 4 : 0;
127} 137}
128 138
129static inline void iboe_mac_vlan_to_ll(union ib_gid *gid, u8 *mac, u16 vid) 139static inline u16 rdma_vlan_dev_vlan_id(const struct net_device *dev)
130{ 140{
131 memset(gid->raw, 0, 16); 141 return dev->priv_flags & IFF_802_1Q_VLAN ?
132 *((__be32 *) gid->raw) = cpu_to_be32(0xfe800000); 142 vlan_dev_vlan_id(dev) : 0xffff;
133 if (vid < 0x1000) { 143}
134 gid->raw[12] = vid & 0xff; 144
135 gid->raw[11] = vid >> 8; 145static inline int rdma_ip2gid(struct sockaddr *addr, union ib_gid *gid)
136 } else { 146{
137 gid->raw[12] = 0xfe; 147 switch (addr->sa_family) {
138 gid->raw[11] = 0xff; 148 case AF_INET:
149 ipv6_addr_set_v4mapped(((struct sockaddr_in *)
150 addr)->sin_addr.s_addr,
151 (struct in6_addr *)gid);
152 break;
153 case AF_INET6:
154 memcpy(gid->raw, &((struct sockaddr_in6 *)addr)->sin6_addr, 16);
155 break;
156 default:
157 return -EINVAL;
139 } 158 }
140 memcpy(gid->raw + 13, mac + 3, 3); 159 return 0;
141 memcpy(gid->raw + 8, mac, 3);
142 gid->raw[8] ^= 2;
143} 160}
144 161
145static inline u16 rdma_vlan_dev_vlan_id(const struct net_device *dev) 162/* Important - sockaddr should be a union of sockaddr_in and sockaddr_in6 */
163static inline int rdma_gid2ip(struct sockaddr *out, union ib_gid *gid)
146{ 164{
147 return dev->priv_flags & IFF_802_1Q_VLAN ? 165 if (ipv6_addr_v4mapped((struct in6_addr *)gid)) {
148 vlan_dev_vlan_id(dev) : 0xffff; 166 struct sockaddr_in *out_in = (struct sockaddr_in *)out;
167 memset(out_in, 0, sizeof(*out_in));
168 out_in->sin_family = AF_INET;
169 memcpy(&out_in->sin_addr.s_addr, gid->raw + 12, 4);
170 } else {
171 struct sockaddr_in6 *out_in = (struct sockaddr_in6 *)out;
172 memset(out_in, 0, sizeof(*out_in));
173 out_in->sin6_family = AF_INET6;
174 memcpy(&out_in->sin6_addr.s6_addr, gid->raw, 16);
175 }
176 return 0;
149} 177}
150 178
151static inline void iboe_addr_get_sgid(struct rdma_dev_addr *dev_addr, 179static inline void iboe_addr_get_sgid(struct rdma_dev_addr *dev_addr,
152 union ib_gid *gid) 180 union ib_gid *gid)
153{ 181{
154 struct net_device *dev; 182 struct net_device *dev;
155 u16 vid = 0xffff; 183 struct in_device *ip4;
156 184
157 dev = dev_get_by_index(&init_net, dev_addr->bound_dev_if); 185 dev = dev_get_by_index(&init_net, dev_addr->bound_dev_if);
158 if (dev) { 186 if (dev) {
159 vid = rdma_vlan_dev_vlan_id(dev); 187 ip4 = (struct in_device *)dev->ip_ptr;
188 if (ip4 && ip4->ifa_list && ip4->ifa_list->ifa_address)
189 ipv6_addr_set_v4mapped(ip4->ifa_list->ifa_address,
190 (struct in6_addr *)gid);
160 dev_put(dev); 191 dev_put(dev);
161 } 192 }
162
163 iboe_mac_vlan_to_ll(gid, dev_addr->src_dev_addr, vid);
164} 193}
165 194
166static inline void rdma_addr_get_sgid(struct rdma_dev_addr *dev_addr, union ib_gid *gid) 195static inline void rdma_addr_get_sgid(struct rdma_dev_addr *dev_addr, union ib_gid *gid)
diff --git a/include/rdma/ib_cm.h b/include/rdma/ib_cm.h
index 0e3ff30647d5..f29e3a27c2cc 100644
--- a/include/rdma/ib_cm.h
+++ b/include/rdma/ib_cm.h
@@ -601,4 +601,5 @@ struct ib_cm_sidr_rep_param {
601int ib_send_cm_sidr_rep(struct ib_cm_id *cm_id, 601int ib_send_cm_sidr_rep(struct ib_cm_id *cm_id,
602 struct ib_cm_sidr_rep_param *param); 602 struct ib_cm_sidr_rep_param *param);
603 603
604int ib_update_cm_av(struct ib_cm_id *id, const u8 *smac, const u8 *alt_smac);
604#endif /* IB_CM_H */ 605#endif /* IB_CM_H */
diff --git a/include/rdma/ib_pack.h b/include/rdma/ib_pack.h
index b37fe3b10a9d..b1f7592e02e4 100644
--- a/include/rdma/ib_pack.h
+++ b/include/rdma/ib_pack.h
@@ -34,6 +34,7 @@
34#define IB_PACK_H 34#define IB_PACK_H
35 35
36#include <rdma/ib_verbs.h> 36#include <rdma/ib_verbs.h>
37#include <uapi/linux/if_ether.h>
37 38
38enum { 39enum {
39 IB_LRH_BYTES = 8, 40 IB_LRH_BYTES = 8,
diff --git a/include/rdma/ib_sa.h b/include/rdma/ib_sa.h
index 125f8714301d..7e071a6abb34 100644
--- a/include/rdma/ib_sa.h
+++ b/include/rdma/ib_sa.h
@@ -154,6 +154,9 @@ struct ib_sa_path_rec {
154 u8 packet_life_time_selector; 154 u8 packet_life_time_selector;
155 u8 packet_life_time; 155 u8 packet_life_time;
156 u8 preference; 156 u8 preference;
157 u8 smac[ETH_ALEN];
158 u8 dmac[ETH_ALEN];
159 u16 vlan_id;
157}; 160};
158 161
159#define IB_SA_MCMEMBER_REC_MGID IB_SA_COMP_MASK( 0) 162#define IB_SA_MCMEMBER_REC_MGID IB_SA_COMP_MASK( 0)
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index 61e1935c91b1..8d4a1c06f7e4 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -48,6 +48,7 @@
48#include <linux/rwsem.h> 48#include <linux/rwsem.h>
49#include <linux/scatterlist.h> 49#include <linux/scatterlist.h>
50#include <linux/workqueue.h> 50#include <linux/workqueue.h>
51#include <uapi/linux/if_ether.h>
51 52
52#include <linux/atomic.h> 53#include <linux/atomic.h>
53#include <asm/uaccess.h> 54#include <asm/uaccess.h>
@@ -69,12 +70,14 @@ enum rdma_node_type {
69 RDMA_NODE_IB_ROUTER, 70 RDMA_NODE_IB_ROUTER,
70 RDMA_NODE_RNIC, 71 RDMA_NODE_RNIC,
71 RDMA_NODE_USNIC, 72 RDMA_NODE_USNIC,
73 RDMA_NODE_USNIC_UDP,
72}; 74};
73 75
74enum rdma_transport_type { 76enum rdma_transport_type {
75 RDMA_TRANSPORT_IB, 77 RDMA_TRANSPORT_IB,
76 RDMA_TRANSPORT_IWARP, 78 RDMA_TRANSPORT_IWARP,
77 RDMA_TRANSPORT_USNIC 79 RDMA_TRANSPORT_USNIC,
80 RDMA_TRANSPORT_USNIC_UDP
78}; 81};
79 82
80enum rdma_transport_type 83enum rdma_transport_type
@@ -472,6 +475,8 @@ struct ib_ah_attr {
472 u8 static_rate; 475 u8 static_rate;
473 u8 ah_flags; 476 u8 ah_flags;
474 u8 port_num; 477 u8 port_num;
478 u8 dmac[ETH_ALEN];
479 u16 vlan_id;
475}; 480};
476 481
477enum ib_wc_status { 482enum ib_wc_status {
@@ -524,6 +529,8 @@ enum ib_wc_flags {
524 IB_WC_WITH_IMM = (1<<1), 529 IB_WC_WITH_IMM = (1<<1),
525 IB_WC_WITH_INVALIDATE = (1<<2), 530 IB_WC_WITH_INVALIDATE = (1<<2),
526 IB_WC_IP_CSUM_OK = (1<<3), 531 IB_WC_IP_CSUM_OK = (1<<3),
532 IB_WC_WITH_SMAC = (1<<4),
533 IB_WC_WITH_VLAN = (1<<5),
527}; 534};
528 535
529struct ib_wc { 536struct ib_wc {
@@ -544,6 +551,8 @@ struct ib_wc {
544 u8 sl; 551 u8 sl;
545 u8 dlid_path_bits; 552 u8 dlid_path_bits;
546 u8 port_num; /* valid only for DR SMPs on switches */ 553 u8 port_num; /* valid only for DR SMPs on switches */
554 u8 smac[ETH_ALEN];
555 u16 vlan_id;
547}; 556};
548 557
549enum ib_cq_notify_flags { 558enum ib_cq_notify_flags {
@@ -633,6 +642,7 @@ enum ib_qp_type {
633enum ib_qp_create_flags { 642enum ib_qp_create_flags {
634 IB_QP_CREATE_IPOIB_UD_LSO = 1 << 0, 643 IB_QP_CREATE_IPOIB_UD_LSO = 1 << 0,
635 IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK = 1 << 1, 644 IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK = 1 << 1,
645 IB_QP_CREATE_NETIF_QP = 1 << 5,
636 /* reserve bits 26-31 for low level drivers' internal use */ 646 /* reserve bits 26-31 for low level drivers' internal use */
637 IB_QP_CREATE_RESERVED_START = 1 << 26, 647 IB_QP_CREATE_RESERVED_START = 1 << 26,
638 IB_QP_CREATE_RESERVED_END = 1 << 31, 648 IB_QP_CREATE_RESERVED_END = 1 << 31,
@@ -721,7 +731,11 @@ enum ib_qp_attr_mask {
721 IB_QP_MAX_DEST_RD_ATOMIC = (1<<17), 731 IB_QP_MAX_DEST_RD_ATOMIC = (1<<17),
722 IB_QP_PATH_MIG_STATE = (1<<18), 732 IB_QP_PATH_MIG_STATE = (1<<18),
723 IB_QP_CAP = (1<<19), 733 IB_QP_CAP = (1<<19),
724 IB_QP_DEST_QPN = (1<<20) 734 IB_QP_DEST_QPN = (1<<20),
735 IB_QP_SMAC = (1<<21),
736 IB_QP_ALT_SMAC = (1<<22),
737 IB_QP_VID = (1<<23),
738 IB_QP_ALT_VID = (1<<24),
725}; 739};
726 740
727enum ib_qp_state { 741enum ib_qp_state {
@@ -771,6 +785,10 @@ struct ib_qp_attr {
771 u8 rnr_retry; 785 u8 rnr_retry;
772 u8 alt_port_num; 786 u8 alt_port_num;
773 u8 alt_timeout; 787 u8 alt_timeout;
788 u8 smac[ETH_ALEN];
789 u8 alt_smac[ETH_ALEN];
790 u16 vlan_id;
791 u16 alt_vlan_id;
774}; 792};
775 793
776enum ib_wr_opcode { 794enum ib_wr_opcode {
@@ -1099,13 +1117,14 @@ enum ib_flow_attr_type {
1099enum ib_flow_spec_type { 1117enum ib_flow_spec_type {
1100 /* L2 headers*/ 1118 /* L2 headers*/
1101 IB_FLOW_SPEC_ETH = 0x20, 1119 IB_FLOW_SPEC_ETH = 0x20,
1120 IB_FLOW_SPEC_IB = 0x22,
1102 /* L3 header*/ 1121 /* L3 header*/
1103 IB_FLOW_SPEC_IPV4 = 0x30, 1122 IB_FLOW_SPEC_IPV4 = 0x30,
1104 /* L4 headers*/ 1123 /* L4 headers*/
1105 IB_FLOW_SPEC_TCP = 0x40, 1124 IB_FLOW_SPEC_TCP = 0x40,
1106 IB_FLOW_SPEC_UDP = 0x41 1125 IB_FLOW_SPEC_UDP = 0x41
1107}; 1126};
1108 1127#define IB_FLOW_SPEC_LAYER_MASK 0xF0
1109#define IB_FLOW_SPEC_SUPPORT_LAYERS 4 1128#define IB_FLOW_SPEC_SUPPORT_LAYERS 4
1110 1129
1111/* Flow steering rule priority is set according to it's domain. 1130/* Flow steering rule priority is set according to it's domain.
@@ -1133,6 +1152,18 @@ struct ib_flow_spec_eth {
1133 struct ib_flow_eth_filter mask; 1152 struct ib_flow_eth_filter mask;
1134}; 1153};
1135 1154
1155struct ib_flow_ib_filter {
1156 __be16 dlid;
1157 __u8 sl;
1158};
1159
1160struct ib_flow_spec_ib {
1161 enum ib_flow_spec_type type;
1162 u16 size;
1163 struct ib_flow_ib_filter val;
1164 struct ib_flow_ib_filter mask;
1165};
1166
1136struct ib_flow_ipv4_filter { 1167struct ib_flow_ipv4_filter {
1137 __be32 src_ip; 1168 __be32 src_ip;
1138 __be32 dst_ip; 1169 __be32 dst_ip;
@@ -1163,6 +1194,7 @@ union ib_flow_spec {
1163 u16 size; 1194 u16 size;
1164 }; 1195 };
1165 struct ib_flow_spec_eth eth; 1196 struct ib_flow_spec_eth eth;
1197 struct ib_flow_spec_ib ib;
1166 struct ib_flow_spec_ipv4 ipv4; 1198 struct ib_flow_spec_ipv4 ipv4;
1167 struct ib_flow_spec_tcp_udp tcp_udp; 1199 struct ib_flow_spec_tcp_udp tcp_udp;
1168}; 1200};
@@ -1488,6 +1520,7 @@ static inline int ib_copy_to_udata(struct ib_udata *udata, void *src, size_t len
1488 * @next_state: Next QP state 1520 * @next_state: Next QP state
1489 * @type: QP type 1521 * @type: QP type
1490 * @mask: Mask of supplied QP attributes 1522 * @mask: Mask of supplied QP attributes
1523 * @ll : link layer of port
1491 * 1524 *
1492 * This function is a helper function that a low-level driver's 1525 * This function is a helper function that a low-level driver's
1493 * modify_qp method can use to validate the consumer's input. It 1526 * modify_qp method can use to validate the consumer's input. It
@@ -1496,7 +1529,8 @@ static inline int ib_copy_to_udata(struct ib_udata *udata, void *src, size_t len
1496 * and that the attribute mask supplied is allowed for the transition. 1529 * and that the attribute mask supplied is allowed for the transition.
1497 */ 1530 */
1498int ib_modify_qp_is_ok(enum ib_qp_state cur_state, enum ib_qp_state next_state, 1531int ib_modify_qp_is_ok(enum ib_qp_state cur_state, enum ib_qp_state next_state,
1499 enum ib_qp_type type, enum ib_qp_attr_mask mask); 1532 enum ib_qp_type type, enum ib_qp_attr_mask mask,
1533 enum rdma_link_layer ll);
1500 1534
1501int ib_register_event_handler (struct ib_event_handler *event_handler); 1535int ib_register_event_handler (struct ib_event_handler *event_handler);
1502int ib_unregister_event_handler(struct ib_event_handler *event_handler); 1536int ib_unregister_event_handler(struct ib_event_handler *event_handler);
diff --git a/include/scsi/scsi_transport_srp.h b/include/scsi/scsi_transport_srp.h
index 4ebf6913b7b2..b11da5c1331e 100644
--- a/include/scsi/scsi_transport_srp.h
+++ b/include/scsi/scsi_transport_srp.h
@@ -19,7 +19,7 @@ struct srp_rport_identifiers {
19 * @SRP_RPORT_BLOCKED: Transport layer not operational; fast I/O fail timer 19 * @SRP_RPORT_BLOCKED: Transport layer not operational; fast I/O fail timer
20 * is running and I/O has been blocked. 20 * is running and I/O has been blocked.
21 * @SRP_RPORT_FAIL_FAST: Fast I/O fail timer has expired; fail I/O fast. 21 * @SRP_RPORT_FAIL_FAST: Fast I/O fail timer has expired; fail I/O fast.
22 * @SRP_RPORT_LOST: Device loss timer has expired; port is being removed. 22 * @SRP_RPORT_LOST: Port is being removed.
23 */ 23 */
24enum srp_rport_state { 24enum srp_rport_state {
25 SRP_RPORT_RUNNING, 25 SRP_RPORT_RUNNING,
@@ -29,10 +29,26 @@ enum srp_rport_state {
29}; 29};
30 30
31/** 31/**
32 * struct srp_rport 32 * struct srp_rport - SRP initiator or target port
33 * @lld_data: LLD private data. 33 *
34 * @mutex: Protects against concurrent rport reconnect / fast_io_fail / 34 * Fields that are relevant for SRP initiator and SRP target drivers:
35 * dev_loss_tmo activity. 35 * @dev: Device associated with this rport.
36 * @port_id: 16-byte port identifier.
37 * @roles: Role of this port - initiator or target.
38 *
39 * Fields that are only relevant for SRP initiator drivers:
40 * @lld_data: LLD private data.
41 * @mutex: Protects against concurrent rport reconnect /
42 * fast_io_fail / dev_loss_tmo activity.
43 * @state: rport state.
44 * @deleted: Whether or not srp_rport_del() has already been invoked.
45 * @reconnect_delay: Reconnect delay in seconds.
46 * @failed_reconnects: Number of failed reconnect attempts.
47 * @reconnect_work: Work structure used for scheduling reconnect attempts.
48 * @fast_io_fail_tmo: Fast I/O fail timeout in seconds.
49 * @dev_loss_tmo: Device loss timeout in seconds.
50 * @fast_io_fail_work: Work structure used for scheduling fast I/O fail work.
51 * @dev_loss_work: Work structure used for scheduling device loss work.
36 */ 52 */
37struct srp_rport { 53struct srp_rport {
38 /* for initiator and target drivers */ 54 /* for initiator and target drivers */
@@ -48,7 +64,6 @@ struct srp_rport {
48 64
49 struct mutex mutex; 65 struct mutex mutex;
50 enum srp_rport_state state; 66 enum srp_rport_state state;
51 bool deleted;
52 int reconnect_delay; 67 int reconnect_delay;
53 int failed_reconnects; 68 int failed_reconnects;
54 struct delayed_work reconnect_work; 69 struct delayed_work reconnect_work;
@@ -60,6 +75,8 @@ struct srp_rport {
60 75
61/** 76/**
62 * struct srp_function_template 77 * struct srp_function_template
78 *
79 * Fields that are only relevant for SRP initiator drivers:
63 * @has_rport_state: Whether or not to create the state, fast_io_fail_tmo and 80 * @has_rport_state: Whether or not to create the state, fast_io_fail_tmo and
64 * dev_loss_tmo sysfs attribute for an rport. 81 * dev_loss_tmo sysfs attribute for an rport.
65 * @reset_timer_if_blocked: Whether or srp_timed_out() should reset the command 82 * @reset_timer_if_blocked: Whether or srp_timed_out() should reset the command
@@ -71,6 +88,11 @@ struct srp_rport {
71 * srp_reconnect_rport(). 88 * srp_reconnect_rport().
72 * @terminate_rport_io: Callback function for terminating all outstanding I/O 89 * @terminate_rport_io: Callback function for terminating all outstanding I/O
73 * requests for an rport. 90 * requests for an rport.
91 * @rport_delete: Callback function that deletes an rport.
92 *
93 * Fields that are only relevant for SRP target drivers:
94 * @tsk_mgmt_response: Callback function for sending a task management response.
95 * @it_nexus_response: Callback function for processing an IT nexus response.
74 */ 96 */
75struct srp_function_template { 97struct srp_function_template {
76 /* for initiator drivers */ 98 /* for initiator drivers */
@@ -101,9 +123,11 @@ extern int srp_tmo_valid(int reconnect_delay, int fast_io_fail_tmo,
101extern int srp_reconnect_rport(struct srp_rport *rport); 123extern int srp_reconnect_rport(struct srp_rport *rport);
102extern void srp_start_tl_fail_timers(struct srp_rport *rport); 124extern void srp_start_tl_fail_timers(struct srp_rport *rport);
103extern void srp_remove_host(struct Scsi_Host *); 125extern void srp_remove_host(struct Scsi_Host *);
126extern void srp_stop_rport_timers(struct srp_rport *rport);
104 127
105/** 128/**
106 * srp_chkready() - evaluate the transport layer state before I/O 129 * srp_chkready() - evaluate the transport layer state before I/O
130 * @rport: SRP target port pointer.
107 * 131 *
108 * Returns a SCSI result code that can be returned by the LLD queuecommand() 132 * Returns a SCSI result code that can be returned by the LLD queuecommand()
109 * implementation. The role of this function is similar to that of 133 * implementation. The role of this function is similar to that of