aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/ulp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/ulp')
-rw-r--r--drivers/infiniband/ulp/ipoib/Makefile3
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib.h10
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_cm.c15
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_ethtool.c99
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_ib.c126
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c33
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_verbs.c3
-rw-r--r--drivers/infiniband/ulp/iser/iser_initiator.c4
-rw-r--r--drivers/infiniband/ulp/iser/iser_verbs.c5
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c7
10 files changed, 256 insertions, 49 deletions
diff --git a/drivers/infiniband/ulp/ipoib/Makefile b/drivers/infiniband/ulp/ipoib/Makefile
index 98ee38e8c2c4..3090100f0de7 100644
--- a/drivers/infiniband/ulp/ipoib/Makefile
+++ b/drivers/infiniband/ulp/ipoib/Makefile
@@ -4,7 +4,8 @@ ib_ipoib-y := ipoib_main.o \
4 ipoib_ib.o \ 4 ipoib_ib.o \
5 ipoib_multicast.o \ 5 ipoib_multicast.o \
6 ipoib_verbs.o \ 6 ipoib_verbs.o \
7 ipoib_vlan.o 7 ipoib_vlan.o \
8 ipoib_ethtool.o
8ib_ipoib-$(CONFIG_INFINIBAND_IPOIB_CM) += ipoib_cm.o 9ib_ipoib-$(CONFIG_INFINIBAND_IPOIB_CM) += ipoib_cm.o
9ib_ipoib-$(CONFIG_INFINIBAND_IPOIB_DEBUG) += ipoib_fs.o 10ib_ipoib-$(CONFIG_INFINIBAND_IPOIB_DEBUG) += ipoib_fs.o
10 11
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index 054fab8e27a0..73b2b176ad0e 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -87,6 +87,7 @@ enum {
87 IPOIB_MCAST_STARTED = 8, 87 IPOIB_MCAST_STARTED = 8,
88 IPOIB_FLAG_ADMIN_CM = 9, 88 IPOIB_FLAG_ADMIN_CM = 9,
89 IPOIB_FLAG_UMCAST = 10, 89 IPOIB_FLAG_UMCAST = 10,
90 IPOIB_FLAG_CSUM = 11,
90 91
91 IPOIB_MAX_BACKOFF_SECONDS = 16, 92 IPOIB_MAX_BACKOFF_SECONDS = 16,
92 93
@@ -241,6 +242,11 @@ struct ipoib_cm_dev_priv {
241 int num_frags; 242 int num_frags;
242}; 243};
243 244
245struct ipoib_ethtool_st {
246 u16 coalesce_usecs;
247 u16 max_coalesced_frames;
248};
249
244/* 250/*
245 * Device private locking: tx_lock protects members used in TX fast 251 * Device private locking: tx_lock protects members used in TX fast
246 * path (and we use LLTX so upper layers don't do extra locking). 252 * path (and we use LLTX so upper layers don't do extra locking).
@@ -318,6 +324,8 @@ struct ipoib_dev_priv {
318 struct dentry *mcg_dentry; 324 struct dentry *mcg_dentry;
319 struct dentry *path_dentry; 325 struct dentry *path_dentry;
320#endif 326#endif
327 int hca_caps;
328 struct ipoib_ethtool_st ethtool;
321}; 329};
322 330
323struct ipoib_ah { 331struct ipoib_ah {
@@ -458,6 +466,8 @@ void ipoib_pkey_poll(struct work_struct *work);
458int ipoib_pkey_dev_delay_open(struct net_device *dev); 466int ipoib_pkey_dev_delay_open(struct net_device *dev);
459void ipoib_drain_cq(struct net_device *dev); 467void ipoib_drain_cq(struct net_device *dev);
460 468
469void ipoib_set_ethtool_ops(struct net_device *dev);
470
461#ifdef CONFIG_INFINIBAND_IPOIB_CM 471#ifdef CONFIG_INFINIBAND_IPOIB_CM
462 472
463#define IPOIB_FLAGS_RC 0x80 473#define IPOIB_FLAGS_RC 0x80
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index 2490b2d79dbb..9db7b0bd9134 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -1007,9 +1007,9 @@ static int ipoib_cm_modify_tx_init(struct net_device *dev,
1007 struct ipoib_dev_priv *priv = netdev_priv(dev); 1007 struct ipoib_dev_priv *priv = netdev_priv(dev);
1008 struct ib_qp_attr qp_attr; 1008 struct ib_qp_attr qp_attr;
1009 int qp_attr_mask, ret; 1009 int qp_attr_mask, ret;
1010 ret = ib_find_cached_pkey(priv->ca, priv->port, priv->pkey, &qp_attr.pkey_index); 1010 ret = ib_find_pkey(priv->ca, priv->port, priv->pkey, &qp_attr.pkey_index);
1011 if (ret) { 1011 if (ret) {
1012 ipoib_warn(priv, "pkey 0x%x not in cache: %d\n", priv->pkey, ret); 1012 ipoib_warn(priv, "pkey 0x%x not found: %d\n", priv->pkey, ret);
1013 return ret; 1013 return ret;
1014 } 1014 }
1015 1015
@@ -1383,6 +1383,10 @@ static ssize_t set_mode(struct device *d, struct device_attribute *attr,
1383 set_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags); 1383 set_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags);
1384 ipoib_warn(priv, "enabling connected mode " 1384 ipoib_warn(priv, "enabling connected mode "
1385 "will cause multicast packet drops\n"); 1385 "will cause multicast packet drops\n");
1386
1387 dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO);
1388 priv->tx_wr.send_flags &= ~IB_SEND_IP_CSUM;
1389
1386 ipoib_flush_paths(dev); 1390 ipoib_flush_paths(dev);
1387 return count; 1391 return count;
1388 } 1392 }
@@ -1391,6 +1395,13 @@ static ssize_t set_mode(struct device *d, struct device_attribute *attr,
1391 clear_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags); 1395 clear_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags);
1392 dev->mtu = min(priv->mcast_mtu, dev->mtu); 1396 dev->mtu = min(priv->mcast_mtu, dev->mtu);
1393 ipoib_flush_paths(dev); 1397 ipoib_flush_paths(dev);
1398
1399 if (test_bit(IPOIB_FLAG_CSUM, &priv->flags)) {
1400 dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
1401 if (priv->hca_caps & IB_DEVICE_UD_TSO)
1402 dev->features |= NETIF_F_TSO;
1403 }
1404
1394 return count; 1405 return count;
1395 } 1406 }
1396 1407
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c b/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c
new file mode 100644
index 000000000000..9a47428366c9
--- /dev/null
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c
@@ -0,0 +1,99 @@
1/*
2 * Copyright (c) 2007 Mellanox Technologies. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 */
32
33#include <linux/kernel.h>
34#include <linux/ethtool.h>
35#include <linux/netdevice.h>
36
37#include "ipoib.h"
38
39static void ipoib_get_drvinfo(struct net_device *netdev,
40 struct ethtool_drvinfo *drvinfo)
41{
42 strncpy(drvinfo->driver, "ipoib", sizeof(drvinfo->driver) - 1);
43}
44
45static int ipoib_get_coalesce(struct net_device *dev,
46 struct ethtool_coalesce *coal)
47{
48 struct ipoib_dev_priv *priv = netdev_priv(dev);
49
50 coal->rx_coalesce_usecs = priv->ethtool.coalesce_usecs;
51 coal->tx_coalesce_usecs = priv->ethtool.coalesce_usecs;
52 coal->rx_max_coalesced_frames = priv->ethtool.max_coalesced_frames;
53 coal->tx_max_coalesced_frames = priv->ethtool.max_coalesced_frames;
54
55 return 0;
56}
57
58static int ipoib_set_coalesce(struct net_device *dev,
59 struct ethtool_coalesce *coal)
60{
61 struct ipoib_dev_priv *priv = netdev_priv(dev);
62 int ret;
63
64 /*
65 * Since IPoIB uses a single CQ for both rx and tx, we assume
66 * that rx params dictate the configuration. These values are
67 * saved in the private data and returned when ipoib_get_coalesce()
68 * is called.
69 */
70 if (coal->rx_coalesce_usecs > 0xffff ||
71 coal->rx_max_coalesced_frames > 0xffff)
72 return -EINVAL;
73
74 ret = ib_modify_cq(priv->cq, coal->rx_max_coalesced_frames,
75 coal->rx_coalesce_usecs);
76 if (ret && ret != -ENOSYS) {
77 ipoib_warn(priv, "failed modifying CQ (%d)\n", ret);
78 return ret;
79 }
80
81 coal->tx_coalesce_usecs = coal->rx_coalesce_usecs;
82 coal->tx_max_coalesced_frames = coal->rx_max_coalesced_frames;
83 priv->ethtool.coalesce_usecs = coal->rx_coalesce_usecs;
84 priv->ethtool.max_coalesced_frames = coal->rx_max_coalesced_frames;
85
86 return 0;
87}
88
89static const struct ethtool_ops ipoib_ethtool_ops = {
90 .get_drvinfo = ipoib_get_drvinfo,
91 .get_tso = ethtool_op_get_tso,
92 .get_coalesce = ipoib_get_coalesce,
93 .set_coalesce = ipoib_set_coalesce,
94};
95
96void ipoib_set_ethtool_ops(struct net_device *dev)
97{
98 SET_ETHTOOL_OPS(dev, &ipoib_ethtool_ops);
99}
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index 08c4396cf418..0205eb7c1bd3 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -39,6 +39,8 @@
39#include <linux/dma-mapping.h> 39#include <linux/dma-mapping.h>
40 40
41#include <rdma/ib_cache.h> 41#include <rdma/ib_cache.h>
42#include <linux/ip.h>
43#include <linux/tcp.h>
42 44
43#include "ipoib.h" 45#include "ipoib.h"
44 46
@@ -231,6 +233,10 @@ static void ipoib_ib_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
231 skb->dev = dev; 233 skb->dev = dev;
232 /* XXX get correct PACKET_ type here */ 234 /* XXX get correct PACKET_ type here */
233 skb->pkt_type = PACKET_HOST; 235 skb->pkt_type = PACKET_HOST;
236
237 if (test_bit(IPOIB_FLAG_CSUM, &priv->flags) && likely(wc->csum_ok))
238 skb->ip_summed = CHECKSUM_UNNECESSARY;
239
234 netif_receive_skb(skb); 240 netif_receive_skb(skb);
235 241
236repost: 242repost:
@@ -245,29 +251,37 @@ static int ipoib_dma_map_tx(struct ib_device *ca,
245 struct sk_buff *skb = tx_req->skb; 251 struct sk_buff *skb = tx_req->skb;
246 u64 *mapping = tx_req->mapping; 252 u64 *mapping = tx_req->mapping;
247 int i; 253 int i;
254 int off;
248 255
249 mapping[0] = ib_dma_map_single(ca, skb->data, skb_headlen(skb), 256 if (skb_headlen(skb)) {
250 DMA_TO_DEVICE); 257 mapping[0] = ib_dma_map_single(ca, skb->data, skb_headlen(skb),
251 if (unlikely(ib_dma_mapping_error(ca, mapping[0]))) 258 DMA_TO_DEVICE);
252 return -EIO; 259 if (unlikely(ib_dma_mapping_error(ca, mapping[0])))
260 return -EIO;
261
262 off = 1;
263 } else
264 off = 0;
253 265
254 for (i = 0; i < skb_shinfo(skb)->nr_frags; ++i) { 266 for (i = 0; i < skb_shinfo(skb)->nr_frags; ++i) {
255 skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 267 skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
256 mapping[i + 1] = ib_dma_map_page(ca, frag->page, 268 mapping[i + off] = ib_dma_map_page(ca, frag->page,
257 frag->page_offset, frag->size, 269 frag->page_offset, frag->size,
258 DMA_TO_DEVICE); 270 DMA_TO_DEVICE);
259 if (unlikely(ib_dma_mapping_error(ca, mapping[i + 1]))) 271 if (unlikely(ib_dma_mapping_error(ca, mapping[i + off])))
260 goto partial_error; 272 goto partial_error;
261 } 273 }
262 return 0; 274 return 0;
263 275
264partial_error: 276partial_error:
265 ib_dma_unmap_single(ca, mapping[0], skb_headlen(skb), DMA_TO_DEVICE);
266
267 for (; i > 0; --i) { 277 for (; i > 0; --i) {
268 skb_frag_t *frag = &skb_shinfo(skb)->frags[i - 1]; 278 skb_frag_t *frag = &skb_shinfo(skb)->frags[i - 1];
269 ib_dma_unmap_page(ca, mapping[i], frag->size, DMA_TO_DEVICE); 279 ib_dma_unmap_page(ca, mapping[i - !off], frag->size, DMA_TO_DEVICE);
270 } 280 }
281
282 if (off)
283 ib_dma_unmap_single(ca, mapping[0], skb_headlen(skb), DMA_TO_DEVICE);
284
271 return -EIO; 285 return -EIO;
272} 286}
273 287
@@ -277,12 +291,17 @@ static void ipoib_dma_unmap_tx(struct ib_device *ca,
277 struct sk_buff *skb = tx_req->skb; 291 struct sk_buff *skb = tx_req->skb;
278 u64 *mapping = tx_req->mapping; 292 u64 *mapping = tx_req->mapping;
279 int i; 293 int i;
294 int off;
280 295
281 ib_dma_unmap_single(ca, mapping[0], skb_headlen(skb), DMA_TO_DEVICE); 296 if (skb_headlen(skb)) {
297 ib_dma_unmap_single(ca, mapping[0], skb_headlen(skb), DMA_TO_DEVICE);
298 off = 1;
299 } else
300 off = 0;
282 301
283 for (i = 0; i < skb_shinfo(skb)->nr_frags; ++i) { 302 for (i = 0; i < skb_shinfo(skb)->nr_frags; ++i) {
284 skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 303 skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
285 ib_dma_unmap_page(ca, mapping[i + 1], frag->size, 304 ib_dma_unmap_page(ca, mapping[i + off], frag->size,
286 DMA_TO_DEVICE); 305 DMA_TO_DEVICE);
287 } 306 }
288} 307}
@@ -388,24 +407,40 @@ void ipoib_ib_completion(struct ib_cq *cq, void *dev_ptr)
388static inline int post_send(struct ipoib_dev_priv *priv, 407static inline int post_send(struct ipoib_dev_priv *priv,
389 unsigned int wr_id, 408 unsigned int wr_id,
390 struct ib_ah *address, u32 qpn, 409 struct ib_ah *address, u32 qpn,
391 u64 *mapping, int headlen, 410 struct ipoib_tx_buf *tx_req,
392 skb_frag_t *frags, 411 void *head, int hlen)
393 int nr_frags)
394{ 412{
395 struct ib_send_wr *bad_wr; 413 struct ib_send_wr *bad_wr;
396 int i; 414 int i, off;
415 struct sk_buff *skb = tx_req->skb;
416 skb_frag_t *frags = skb_shinfo(skb)->frags;
417 int nr_frags = skb_shinfo(skb)->nr_frags;
418 u64 *mapping = tx_req->mapping;
419
420 if (skb_headlen(skb)) {
421 priv->tx_sge[0].addr = mapping[0];
422 priv->tx_sge[0].length = skb_headlen(skb);
423 off = 1;
424 } else
425 off = 0;
397 426
398 priv->tx_sge[0].addr = mapping[0];
399 priv->tx_sge[0].length = headlen;
400 for (i = 0; i < nr_frags; ++i) { 427 for (i = 0; i < nr_frags; ++i) {
401 priv->tx_sge[i + 1].addr = mapping[i + 1]; 428 priv->tx_sge[i + off].addr = mapping[i + off];
402 priv->tx_sge[i + 1].length = frags[i].size; 429 priv->tx_sge[i + off].length = frags[i].size;
403 } 430 }
404 priv->tx_wr.num_sge = nr_frags + 1; 431 priv->tx_wr.num_sge = nr_frags + off;
405 priv->tx_wr.wr_id = wr_id; 432 priv->tx_wr.wr_id = wr_id;
406 priv->tx_wr.wr.ud.remote_qpn = qpn; 433 priv->tx_wr.wr.ud.remote_qpn = qpn;
407 priv->tx_wr.wr.ud.ah = address; 434 priv->tx_wr.wr.ud.ah = address;
408 435
436 if (head) {
437 priv->tx_wr.wr.ud.mss = skb_shinfo(skb)->gso_size;
438 priv->tx_wr.wr.ud.header = head;
439 priv->tx_wr.wr.ud.hlen = hlen;
440 priv->tx_wr.opcode = IB_WR_LSO;
441 } else
442 priv->tx_wr.opcode = IB_WR_SEND;
443
409 return ib_post_send(priv->qp, &priv->tx_wr, &bad_wr); 444 return ib_post_send(priv->qp, &priv->tx_wr, &bad_wr);
410} 445}
411 446
@@ -414,14 +449,30 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb,
414{ 449{
415 struct ipoib_dev_priv *priv = netdev_priv(dev); 450 struct ipoib_dev_priv *priv = netdev_priv(dev);
416 struct ipoib_tx_buf *tx_req; 451 struct ipoib_tx_buf *tx_req;
417 452 int hlen;
418 if (unlikely(skb->len > priv->mcast_mtu + IPOIB_ENCAP_LEN)) { 453 void *phead;
419 ipoib_warn(priv, "packet len %d (> %d) too long to send, dropping\n", 454
420 skb->len, priv->mcast_mtu + IPOIB_ENCAP_LEN); 455 if (skb_is_gso(skb)) {
421 ++dev->stats.tx_dropped; 456 hlen = skb_transport_offset(skb) + tcp_hdrlen(skb);
422 ++dev->stats.tx_errors; 457 phead = skb->data;
423 ipoib_cm_skb_too_long(dev, skb, priv->mcast_mtu); 458 if (unlikely(!skb_pull(skb, hlen))) {
424 return; 459 ipoib_warn(priv, "linear data too small\n");
460 ++dev->stats.tx_dropped;
461 ++dev->stats.tx_errors;
462 dev_kfree_skb_any(skb);
463 return;
464 }
465 } else {
466 if (unlikely(skb->len > priv->mcast_mtu + IPOIB_ENCAP_LEN)) {
467 ipoib_warn(priv, "packet len %d (> %d) too long to send, dropping\n",
468 skb->len, priv->mcast_mtu + IPOIB_ENCAP_LEN);
469 ++dev->stats.tx_dropped;
470 ++dev->stats.tx_errors;
471 ipoib_cm_skb_too_long(dev, skb, priv->mcast_mtu);
472 return;
473 }
474 phead = NULL;
475 hlen = 0;
425 } 476 }
426 477
427 ipoib_dbg_data(priv, "sending packet, length=%d address=%p qpn=0x%06x\n", 478 ipoib_dbg_data(priv, "sending packet, length=%d address=%p qpn=0x%06x\n",
@@ -442,10 +493,13 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb,
442 return; 493 return;
443 } 494 }
444 495
496 if (skb->ip_summed == CHECKSUM_PARTIAL)
497 priv->tx_wr.send_flags |= IB_SEND_IP_CSUM;
498 else
499 priv->tx_wr.send_flags &= ~IB_SEND_IP_CSUM;
500
445 if (unlikely(post_send(priv, priv->tx_head & (ipoib_sendq_size - 1), 501 if (unlikely(post_send(priv, priv->tx_head & (ipoib_sendq_size - 1),
446 address->ah, qpn, 502 address->ah, qpn, tx_req, phead, hlen))) {
447 tx_req->mapping, skb_headlen(skb),
448 skb_shinfo(skb)->frags, skb_shinfo(skb)->nr_frags))) {
449 ipoib_warn(priv, "post_send failed\n"); 503 ipoib_warn(priv, "post_send failed\n");
450 ++dev->stats.tx_errors; 504 ++dev->stats.tx_errors;
451 ipoib_dma_unmap_tx(priv->ca, tx_req); 505 ipoib_dma_unmap_tx(priv->ca, tx_req);
@@ -540,7 +594,7 @@ static void ipoib_pkey_dev_check_presence(struct net_device *dev)
540 struct ipoib_dev_priv *priv = netdev_priv(dev); 594 struct ipoib_dev_priv *priv = netdev_priv(dev);
541 u16 pkey_index = 0; 595 u16 pkey_index = 0;
542 596
543 if (ib_find_cached_pkey(priv->ca, priv->port, priv->pkey, &pkey_index)) 597 if (ib_find_pkey(priv->ca, priv->port, priv->pkey, &pkey_index))
544 clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); 598 clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
545 else 599 else
546 set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); 600 set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
@@ -781,13 +835,13 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, int pkey_event)
781 clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); 835 clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
782 ipoib_ib_dev_down(dev, 0); 836 ipoib_ib_dev_down(dev, 0);
783 ipoib_ib_dev_stop(dev, 0); 837 ipoib_ib_dev_stop(dev, 0);
784 ipoib_pkey_dev_delay_open(dev); 838 if (ipoib_pkey_dev_delay_open(dev))
785 return; 839 return;
786 } 840 }
787 set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
788 841
789 /* restart QP only if P_Key index is changed */ 842 /* restart QP only if P_Key index is changed */
790 if (new_index == priv->pkey_index) { 843 if (test_and_set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags) &&
844 new_index == priv->pkey_index) {
791 ipoib_dbg(priv, "Not flushing - P_Key index not changed.\n"); 845 ipoib_dbg(priv, "Not flushing - P_Key index not changed.\n");
792 return; 846 return;
793 } 847 }
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 57282048865c..bd07f02cf02b 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -359,8 +359,7 @@ void ipoib_flush_paths(struct net_device *dev)
359 spin_lock_irq(&priv->tx_lock); 359 spin_lock_irq(&priv->tx_lock);
360 spin_lock(&priv->lock); 360 spin_lock(&priv->lock);
361 361
362 list_splice(&priv->path_list, &remove_list); 362 list_splice_init(&priv->path_list, &remove_list);
363 INIT_LIST_HEAD(&priv->path_list);
364 363
365 list_for_each_entry(path, &remove_list, list) 364 list_for_each_entry(path, &remove_list, list)
366 rb_erase(&path->rb_node, &priv->path_tree); 365 rb_erase(&path->rb_node, &priv->path_tree);
@@ -952,6 +951,8 @@ static void ipoib_setup(struct net_device *dev)
952 dev->set_multicast_list = ipoib_set_mcast_list; 951 dev->set_multicast_list = ipoib_set_mcast_list;
953 dev->neigh_setup = ipoib_neigh_setup_dev; 952 dev->neigh_setup = ipoib_neigh_setup_dev;
954 953
954 ipoib_set_ethtool_ops(dev);
955
955 netif_napi_add(dev, &priv->napi, ipoib_poll, 100); 956 netif_napi_add(dev, &priv->napi, ipoib_poll, 100);
956 957
957 dev->watchdog_timeo = HZ; 958 dev->watchdog_timeo = HZ;
@@ -1105,6 +1106,7 @@ static struct net_device *ipoib_add_port(const char *format,
1105 struct ib_device *hca, u8 port) 1106 struct ib_device *hca, u8 port)
1106{ 1107{
1107 struct ipoib_dev_priv *priv; 1108 struct ipoib_dev_priv *priv;
1109 struct ib_device_attr *device_attr;
1108 int result = -ENOMEM; 1110 int result = -ENOMEM;
1109 1111
1110 priv = ipoib_intf_alloc(format); 1112 priv = ipoib_intf_alloc(format);
@@ -1120,6 +1122,29 @@ static struct net_device *ipoib_add_port(const char *format,
1120 goto device_init_failed; 1122 goto device_init_failed;
1121 } 1123 }
1122 1124
1125 device_attr = kmalloc(sizeof *device_attr, GFP_KERNEL);
1126 if (!device_attr) {
1127 printk(KERN_WARNING "%s: allocation of %zu bytes failed\n",
1128 hca->name, sizeof *device_attr);
1129 goto device_init_failed;
1130 }
1131
1132 result = ib_query_device(hca, device_attr);
1133 if (result) {
1134 printk(KERN_WARNING "%s: ib_query_device failed (ret = %d)\n",
1135 hca->name, result);
1136 kfree(device_attr);
1137 goto device_init_failed;
1138 }
1139 priv->hca_caps = device_attr->device_cap_flags;
1140
1141 kfree(device_attr);
1142
1143 if (priv->hca_caps & IB_DEVICE_UD_IP_CSUM) {
1144 set_bit(IPOIB_FLAG_CSUM, &priv->flags);
1145 priv->dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
1146 }
1147
1123 /* 1148 /*
1124 * Set the full membership bit, so that we join the right 1149 * Set the full membership bit, so that we join the right
1125 * broadcast group, etc. 1150 * broadcast group, etc.
@@ -1137,7 +1162,6 @@ static struct net_device *ipoib_add_port(const char *format,
1137 } else 1162 } else
1138 memcpy(priv->dev->dev_addr + 4, priv->local_gid.raw, sizeof (union ib_gid)); 1163 memcpy(priv->dev->dev_addr + 4, priv->local_gid.raw, sizeof (union ib_gid));
1139 1164
1140
1141 result = ipoib_dev_init(priv->dev, hca, port); 1165 result = ipoib_dev_init(priv->dev, hca, port);
1142 if (result < 0) { 1166 if (result < 0) {
1143 printk(KERN_WARNING "%s: failed to initialize port %d (ret = %d)\n", 1167 printk(KERN_WARNING "%s: failed to initialize port %d (ret = %d)\n",
@@ -1155,6 +1179,9 @@ static struct net_device *ipoib_add_port(const char *format,
1155 goto event_failed; 1179 goto event_failed;
1156 } 1180 }
1157 1181
1182 if (priv->dev->features & NETIF_F_SG && priv->hca_caps & IB_DEVICE_UD_TSO)
1183 priv->dev->features |= NETIF_F_TSO;
1184
1158 result = register_netdev(priv->dev); 1185 result = register_netdev(priv->dev);
1159 if (result) { 1186 if (result) {
1160 printk(KERN_WARNING "%s: couldn't register ipoib port %d; error %d\n", 1187 printk(KERN_WARNING "%s: couldn't register ipoib port %d; error %d\n",
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
index a3aeb911f024..8a20e3742c43 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 init_attr.send_cq = priv->cq; 192 init_attr.send_cq = priv->cq;
193 init_attr.recv_cq = priv->cq; 193 init_attr.recv_cq = priv->cq;
194 194
195 if (priv->hca_caps & IB_DEVICE_UD_TSO)
196 init_attr.create_flags = IB_QP_CREATE_IPOIB_UD_LSO;
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/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c
index 83247f1fdf72..08dc81c46f41 100644
--- a/drivers/infiniband/ulp/iser/iser_initiator.c
+++ b/drivers/infiniband/ulp/iser/iser_initiator.c
@@ -405,7 +405,7 @@ int iser_send_data_out(struct iscsi_conn *conn,
405 struct iser_dto *send_dto = NULL; 405 struct iser_dto *send_dto = NULL;
406 unsigned long buf_offset; 406 unsigned long buf_offset;
407 unsigned long data_seg_len; 407 unsigned long data_seg_len;
408 unsigned int itt; 408 uint32_t itt;
409 int err = 0; 409 int err = 0;
410 410
411 if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) { 411 if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) {
@@ -416,7 +416,7 @@ int iser_send_data_out(struct iscsi_conn *conn,
416 if (iser_check_xmit(conn, ctask)) 416 if (iser_check_xmit(conn, ctask))
417 return -ENOBUFS; 417 return -ENOBUFS;
418 418
419 itt = ntohl(hdr->itt); 419 itt = (__force uint32_t)hdr->itt;
420 data_seg_len = ntoh24(hdr->dlength); 420 data_seg_len = ntoh24(hdr->dlength);
421 buf_offset = ntohl(hdr->offset); 421 buf_offset = ntohl(hdr->offset);
422 422
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index 993f0a8ff28f..d19cfe605ebb 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -473,11 +473,8 @@ static int iser_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *eve
473 iser_connect_error(cma_id); 473 iser_connect_error(cma_id);
474 break; 474 break;
475 case RDMA_CM_EVENT_DISCONNECTED: 475 case RDMA_CM_EVENT_DISCONNECTED:
476 iser_disconnected_handler(cma_id);
477 break;
478 case RDMA_CM_EVENT_DEVICE_REMOVAL: 476 case RDMA_CM_EVENT_DEVICE_REMOVAL:
479 iser_err("Device removal is currently unsupported\n"); 477 iser_disconnected_handler(cma_id);
480 BUG();
481 break; 478 break;
482 default: 479 default:
483 iser_err("Unexpected RDMA CM event (%d)\n", event->event); 480 iser_err("Unexpected RDMA CM event (%d)\n", event->event);
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index fd4a49fc4773..125765aa9d59 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -68,7 +68,7 @@ static int srp_max_iu_len;
68 68
69module_param(srp_sg_tablesize, int, 0444); 69module_param(srp_sg_tablesize, int, 0444);
70MODULE_PARM_DESC(srp_sg_tablesize, 70MODULE_PARM_DESC(srp_sg_tablesize,
71 "Max number of gather/scatter entries per I/O (default is 12)"); 71 "Max number of gather/scatter entries per I/O (default is 12, max 255)");
72 72
73static int topspin_workarounds = 1; 73static int topspin_workarounds = 1;
74 74
@@ -2138,6 +2138,11 @@ static int __init srp_init_module(void)
2138{ 2138{
2139 int ret; 2139 int ret;
2140 2140
2141 if (srp_sg_tablesize > 255) {
2142 printk(KERN_WARNING PFX "Clamping srp_sg_tablesize to 255\n");
2143 srp_sg_tablesize = 255;
2144 }
2145
2141 ib_srp_transport_template = 2146 ib_srp_transport_template =
2142 srp_attach_transport(&ib_srp_transport_functions); 2147 srp_attach_transport(&ib_srp_transport_functions);
2143 if (!ib_srp_transport_template) 2148 if (!ib_srp_transport_template)