aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/ulp/ipoib/ipoib_cm.c
diff options
context:
space:
mode:
authorBen Dooks <ben-linux@fluff.org>2008-07-15 15:19:14 -0400
committerBen Dooks <ben-linux@fluff.org>2008-07-15 15:19:14 -0400
commit0c17e4ceedd35c78b1c7413dbd16279a350be6bc (patch)
tree313b3b9ca04727f3704464e01d8dd97da1dd534b /drivers/infiniband/ulp/ipoib/ipoib_cm.c
parent19c1d6a34abf73d0baf8e325d018c920fa78dddc (diff)
parentb9d2252c1e44fa83a4e65fdc9eb93db6297c55af (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6 into for-rmk
Diffstat (limited to 'drivers/infiniband/ulp/ipoib/ipoib_cm.c')
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_cm.c104
1 files changed, 78 insertions, 26 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index 97e67d36378f..0f2d3045061a 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -28,8 +28,6 @@
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 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 29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE. 30 * SOFTWARE.
31 *
32 * $Id$
33 */ 31 */
34 32
35#include <rdma/ib_cm.h> 33#include <rdma/ib_cm.h>
@@ -113,18 +111,20 @@ static int ipoib_cm_post_receive_srq(struct net_device *dev, int id)
113} 111}
114 112
115static int ipoib_cm_post_receive_nonsrq(struct net_device *dev, 113static int ipoib_cm_post_receive_nonsrq(struct net_device *dev,
116 struct ipoib_cm_rx *rx, int id) 114 struct ipoib_cm_rx *rx,
115 struct ib_recv_wr *wr,
116 struct ib_sge *sge, int id)
117{ 117{
118 struct ipoib_dev_priv *priv = netdev_priv(dev); 118 struct ipoib_dev_priv *priv = netdev_priv(dev);
119 struct ib_recv_wr *bad_wr; 119 struct ib_recv_wr *bad_wr;
120 int i, ret; 120 int i, ret;
121 121
122 priv->cm.rx_wr.wr_id = id | IPOIB_OP_CM | IPOIB_OP_RECV; 122 wr->wr_id = id | IPOIB_OP_CM | IPOIB_OP_RECV;
123 123
124 for (i = 0; i < IPOIB_CM_RX_SG; ++i) 124 for (i = 0; i < IPOIB_CM_RX_SG; ++i)
125 priv->cm.rx_sge[i].addr = rx->rx_ring[id].mapping[i]; 125 sge[i].addr = rx->rx_ring[id].mapping[i];
126 126
127 ret = ib_post_recv(rx->qp, &priv->cm.rx_wr, &bad_wr); 127 ret = ib_post_recv(rx->qp, wr, &bad_wr);
128 if (unlikely(ret)) { 128 if (unlikely(ret)) {
129 ipoib_warn(priv, "post recv failed for buf %d (%d)\n", id, ret); 129 ipoib_warn(priv, "post recv failed for buf %d (%d)\n", id, ret);
130 ipoib_cm_dma_unmap_rx(priv, IPOIB_CM_RX_SG - 1, 130 ipoib_cm_dma_unmap_rx(priv, IPOIB_CM_RX_SG - 1,
@@ -322,10 +322,33 @@ static int ipoib_cm_modify_rx_qp(struct net_device *dev,
322 return 0; 322 return 0;
323} 323}
324 324
325static void ipoib_cm_init_rx_wr(struct net_device *dev,
326 struct ib_recv_wr *wr,
327 struct ib_sge *sge)
328{
329 struct ipoib_dev_priv *priv = netdev_priv(dev);
330 int i;
331
332 for (i = 0; i < priv->cm.num_frags; ++i)
333 sge[i].lkey = priv->mr->lkey;
334
335 sge[0].length = IPOIB_CM_HEAD_SIZE;
336 for (i = 1; i < priv->cm.num_frags; ++i)
337 sge[i].length = PAGE_SIZE;
338
339 wr->next = NULL;
340 wr->sg_list = priv->cm.rx_sge;
341 wr->num_sge = priv->cm.num_frags;
342}
343
325static int ipoib_cm_nonsrq_init_rx(struct net_device *dev, struct ib_cm_id *cm_id, 344static int ipoib_cm_nonsrq_init_rx(struct net_device *dev, struct ib_cm_id *cm_id,
326 struct ipoib_cm_rx *rx) 345 struct ipoib_cm_rx *rx)
327{ 346{
328 struct ipoib_dev_priv *priv = netdev_priv(dev); 347 struct ipoib_dev_priv *priv = netdev_priv(dev);
348 struct {
349 struct ib_recv_wr wr;
350 struct ib_sge sge[IPOIB_CM_RX_SG];
351 } *t;
329 int ret; 352 int ret;
330 int i; 353 int i;
331 354
@@ -333,6 +356,14 @@ static int ipoib_cm_nonsrq_init_rx(struct net_device *dev, struct ib_cm_id *cm_i
333 if (!rx->rx_ring) 356 if (!rx->rx_ring)
334 return -ENOMEM; 357 return -ENOMEM;
335 358
359 t = kmalloc(sizeof *t, GFP_KERNEL);
360 if (!t) {
361 ret = -ENOMEM;
362 goto err_free;
363 }
364
365 ipoib_cm_init_rx_wr(dev, &t->wr, t->sge);
366
336 spin_lock_irq(&priv->lock); 367 spin_lock_irq(&priv->lock);
337 368
338 if (priv->cm.nonsrq_conn_qp >= ipoib_max_conn_qp) { 369 if (priv->cm.nonsrq_conn_qp >= ipoib_max_conn_qp) {
@@ -351,8 +382,8 @@ static int ipoib_cm_nonsrq_init_rx(struct net_device *dev, struct ib_cm_id *cm_i
351 ipoib_warn(priv, "failed to allocate receive buffer %d\n", i); 382 ipoib_warn(priv, "failed to allocate receive buffer %d\n", i);
352 ret = -ENOMEM; 383 ret = -ENOMEM;
353 goto err_count; 384 goto err_count;
354 } 385 }
355 ret = ipoib_cm_post_receive_nonsrq(dev, rx, i); 386 ret = ipoib_cm_post_receive_nonsrq(dev, rx, &t->wr, t->sge, i);
356 if (ret) { 387 if (ret) {
357 ipoib_warn(priv, "ipoib_cm_post_receive_nonsrq " 388 ipoib_warn(priv, "ipoib_cm_post_receive_nonsrq "
358 "failed for buf %d\n", i); 389 "failed for buf %d\n", i);
@@ -363,6 +394,8 @@ static int ipoib_cm_nonsrq_init_rx(struct net_device *dev, struct ib_cm_id *cm_i
363 394
364 rx->recv_count = ipoib_recvq_size; 395 rx->recv_count = ipoib_recvq_size;
365 396
397 kfree(t);
398
366 return 0; 399 return 0;
367 400
368err_count: 401err_count:
@@ -371,6 +404,7 @@ err_count:
371 spin_unlock_irq(&priv->lock); 404 spin_unlock_irq(&priv->lock);
372 405
373err_free: 406err_free:
407 kfree(t);
374 ipoib_cm_free_rx_ring(dev, rx->rx_ring); 408 ipoib_cm_free_rx_ring(dev, rx->rx_ring);
375 409
376 return ret; 410 return ret;
@@ -525,6 +559,7 @@ void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
525 u64 mapping[IPOIB_CM_RX_SG]; 559 u64 mapping[IPOIB_CM_RX_SG];
526 int frags; 560 int frags;
527 int has_srq; 561 int has_srq;
562 struct sk_buff *small_skb;
528 563
529 ipoib_dbg_data(priv, "cm recv completion: id %d, status: %d\n", 564 ipoib_dbg_data(priv, "cm recv completion: id %d, status: %d\n",
530 wr_id, wc->status); 565 wr_id, wc->status);
@@ -579,6 +614,23 @@ void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
579 } 614 }
580 } 615 }
581 616
617 if (wc->byte_len < IPOIB_CM_COPYBREAK) {
618 int dlen = wc->byte_len;
619
620 small_skb = dev_alloc_skb(dlen + 12);
621 if (small_skb) {
622 skb_reserve(small_skb, 12);
623 ib_dma_sync_single_for_cpu(priv->ca, rx_ring[wr_id].mapping[0],
624 dlen, DMA_FROM_DEVICE);
625 skb_copy_from_linear_data(skb, small_skb->data, dlen);
626 ib_dma_sync_single_for_device(priv->ca, rx_ring[wr_id].mapping[0],
627 dlen, DMA_FROM_DEVICE);
628 skb_put(small_skb, dlen);
629 skb = small_skb;
630 goto copied;
631 }
632 }
633
582 frags = PAGE_ALIGN(wc->byte_len - min(wc->byte_len, 634 frags = PAGE_ALIGN(wc->byte_len - min(wc->byte_len,
583 (unsigned)IPOIB_CM_HEAD_SIZE)) / PAGE_SIZE; 635 (unsigned)IPOIB_CM_HEAD_SIZE)) / PAGE_SIZE;
584 636
@@ -601,6 +653,7 @@ void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
601 653
602 skb_put_frags(skb, IPOIB_CM_HEAD_SIZE, wc->byte_len, newskb); 654 skb_put_frags(skb, IPOIB_CM_HEAD_SIZE, wc->byte_len, newskb);
603 655
656copied:
604 skb->protocol = ((struct ipoib_header *) skb->data)->proto; 657 skb->protocol = ((struct ipoib_header *) skb->data)->proto;
605 skb_reset_mac_header(skb); 658 skb_reset_mac_header(skb);
606 skb_pull(skb, IPOIB_ENCAP_LEN); 659 skb_pull(skb, IPOIB_ENCAP_LEN);
@@ -620,7 +673,10 @@ repost:
620 ipoib_warn(priv, "ipoib_cm_post_receive_srq failed " 673 ipoib_warn(priv, "ipoib_cm_post_receive_srq failed "
621 "for buf %d\n", wr_id); 674 "for buf %d\n", wr_id);
622 } else { 675 } else {
623 if (unlikely(ipoib_cm_post_receive_nonsrq(dev, p, wr_id))) { 676 if (unlikely(ipoib_cm_post_receive_nonsrq(dev, p,
677 &priv->cm.rx_wr,
678 priv->cm.rx_sge,
679 wr_id))) {
624 --p->recv_count; 680 --p->recv_count;
625 ipoib_warn(priv, "ipoib_cm_post_receive_nonsrq failed " 681 ipoib_warn(priv, "ipoib_cm_post_receive_nonsrq failed "
626 "for buf %d\n", wr_id); 682 "for buf %d\n", wr_id);
@@ -647,7 +703,7 @@ static inline int post_send(struct ipoib_dev_priv *priv,
647void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_tx *tx) 703void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_tx *tx)
648{ 704{
649 struct ipoib_dev_priv *priv = netdev_priv(dev); 705 struct ipoib_dev_priv *priv = netdev_priv(dev);
650 struct ipoib_tx_buf *tx_req; 706 struct ipoib_cm_tx_buf *tx_req;
651 u64 addr; 707 u64 addr;
652 708
653 if (unlikely(skb->len > tx->mtu)) { 709 if (unlikely(skb->len > tx->mtu)) {
@@ -678,7 +734,7 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_
678 return; 734 return;
679 } 735 }
680 736
681 tx_req->mapping[0] = addr; 737 tx_req->mapping = addr;
682 738
683 if (unlikely(post_send(priv, tx, tx->tx_head & (ipoib_sendq_size - 1), 739 if (unlikely(post_send(priv, tx, tx->tx_head & (ipoib_sendq_size - 1),
684 addr, skb->len))) { 740 addr, skb->len))) {
@@ -703,7 +759,7 @@ void ipoib_cm_handle_tx_wc(struct net_device *dev, struct ib_wc *wc)
703 struct ipoib_dev_priv *priv = netdev_priv(dev); 759 struct ipoib_dev_priv *priv = netdev_priv(dev);
704 struct ipoib_cm_tx *tx = wc->qp->qp_context; 760 struct ipoib_cm_tx *tx = wc->qp->qp_context;
705 unsigned int wr_id = wc->wr_id & ~IPOIB_OP_CM; 761 unsigned int wr_id = wc->wr_id & ~IPOIB_OP_CM;
706 struct ipoib_tx_buf *tx_req; 762 struct ipoib_cm_tx_buf *tx_req;
707 unsigned long flags; 763 unsigned long flags;
708 764
709 ipoib_dbg_data(priv, "cm send completion: id %d, status: %d\n", 765 ipoib_dbg_data(priv, "cm send completion: id %d, status: %d\n",
@@ -717,7 +773,7 @@ void ipoib_cm_handle_tx_wc(struct net_device *dev, struct ib_wc *wc)
717 773
718 tx_req = &tx->tx_ring[wr_id]; 774 tx_req = &tx->tx_ring[wr_id];
719 775
720 ib_dma_unmap_single(priv->ca, tx_req->mapping[0], tx_req->skb->len, DMA_TO_DEVICE); 776 ib_dma_unmap_single(priv->ca, tx_req->mapping, tx_req->skb->len, DMA_TO_DEVICE);
721 777
722 /* FIXME: is this right? Shouldn't we only increment on success? */ 778 /* FIXME: is this right? Shouldn't we only increment on success? */
723 ++dev->stats.tx_packets; 779 ++dev->stats.tx_packets;
@@ -1087,7 +1143,7 @@ err_tx:
1087static void ipoib_cm_tx_destroy(struct ipoib_cm_tx *p) 1143static void ipoib_cm_tx_destroy(struct ipoib_cm_tx *p)
1088{ 1144{
1089 struct ipoib_dev_priv *priv = netdev_priv(p->dev); 1145 struct ipoib_dev_priv *priv = netdev_priv(p->dev);
1090 struct ipoib_tx_buf *tx_req; 1146 struct ipoib_cm_tx_buf *tx_req;
1091 unsigned long flags; 1147 unsigned long flags;
1092 unsigned long begin; 1148 unsigned long begin;
1093 1149
@@ -1115,7 +1171,7 @@ timeout:
1115 1171
1116 while ((int) p->tx_tail - (int) p->tx_head < 0) { 1172 while ((int) p->tx_tail - (int) p->tx_head < 0) {
1117 tx_req = &p->tx_ring[p->tx_tail & (ipoib_sendq_size - 1)]; 1173 tx_req = &p->tx_ring[p->tx_tail & (ipoib_sendq_size - 1)];
1118 ib_dma_unmap_single(priv->ca, tx_req->mapping[0], tx_req->skb->len, 1174 ib_dma_unmap_single(priv->ca, tx_req->mapping, tx_req->skb->len,
1119 DMA_TO_DEVICE); 1175 DMA_TO_DEVICE);
1120 dev_kfree_skb_any(tx_req->skb); 1176 dev_kfree_skb_any(tx_req->skb);
1121 ++p->tx_tail; 1177 ++p->tx_tail;
@@ -1384,7 +1440,9 @@ static ssize_t set_mode(struct device *d, struct device_attribute *attr,
1384 ipoib_warn(priv, "enabling connected mode " 1440 ipoib_warn(priv, "enabling connected mode "
1385 "will cause multicast packet drops\n"); 1441 "will cause multicast packet drops\n");
1386 1442
1443 rtnl_lock();
1387 dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO); 1444 dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO);
1445 rtnl_unlock();
1388 priv->tx_wr.send_flags &= ~IB_SEND_IP_CSUM; 1446 priv->tx_wr.send_flags &= ~IB_SEND_IP_CSUM;
1389 1447
1390 ipoib_flush_paths(dev); 1448 ipoib_flush_paths(dev);
@@ -1393,14 +1451,16 @@ static ssize_t set_mode(struct device *d, struct device_attribute *attr,
1393 1451
1394 if (!strcmp(buf, "datagram\n")) { 1452 if (!strcmp(buf, "datagram\n")) {
1395 clear_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags); 1453 clear_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags);
1396 dev->mtu = min(priv->mcast_mtu, dev->mtu);
1397 ipoib_flush_paths(dev);
1398 1454
1455 rtnl_lock();
1399 if (test_bit(IPOIB_FLAG_CSUM, &priv->flags)) { 1456 if (test_bit(IPOIB_FLAG_CSUM, &priv->flags)) {
1400 dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; 1457 dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
1401 if (priv->hca_caps & IB_DEVICE_UD_TSO) 1458 if (priv->hca_caps & IB_DEVICE_UD_TSO)
1402 dev->features |= NETIF_F_TSO; 1459 dev->features |= NETIF_F_TSO;
1403 } 1460 }
1461 dev_set_mtu(dev, min(priv->mcast_mtu, dev->mtu));
1462 rtnl_unlock();
1463 ipoib_flush_paths(dev);
1404 1464
1405 return count; 1465 return count;
1406 } 1466 }
@@ -1485,15 +1545,7 @@ int ipoib_cm_dev_init(struct net_device *dev)
1485 priv->cm.num_frags = IPOIB_CM_RX_SG; 1545 priv->cm.num_frags = IPOIB_CM_RX_SG;
1486 } 1546 }
1487 1547
1488 for (i = 0; i < priv->cm.num_frags; ++i) 1548 ipoib_cm_init_rx_wr(dev, &priv->cm.rx_wr, priv->cm.rx_sge);
1489 priv->cm.rx_sge[i].lkey = priv->mr->lkey;
1490
1491 priv->cm.rx_sge[0].length = IPOIB_CM_HEAD_SIZE;
1492 for (i = 1; i < priv->cm.num_frags; ++i)
1493 priv->cm.rx_sge[i].length = PAGE_SIZE;
1494 priv->cm.rx_wr.next = NULL;
1495 priv->cm.rx_wr.sg_list = priv->cm.rx_sge;
1496 priv->cm.rx_wr.num_sge = priv->cm.num_frags;
1497 1549
1498 if (ipoib_cm_has_srq(dev)) { 1550 if (ipoib_cm_has_srq(dev)) {
1499 for (i = 0; i < ipoib_recvq_size; ++i) { 1551 for (i = 0; i < ipoib_recvq_size; ++i) {