diff options
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib.h | 29 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_ib.c | 52 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_main.c | 145 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 15 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_netlink.c | 2 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_verbs.c | 16 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_vlan.c | 5 |
7 files changed, 188 insertions, 76 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index 9a912830c8e0..2ae1f0883c9b 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h | |||
@@ -52,7 +52,6 @@ | |||
52 | #include <rdma/ib_pack.h> | 52 | #include <rdma/ib_pack.h> |
53 | #include <rdma/ib_sa.h> | 53 | #include <rdma/ib_sa.h> |
54 | #include <linux/sched.h> | 54 | #include <linux/sched.h> |
55 | |||
56 | /* constants */ | 55 | /* constants */ |
57 | 56 | ||
58 | enum ipoib_flush_level { | 57 | enum ipoib_flush_level { |
@@ -153,8 +152,12 @@ static inline void skb_add_pseudo_hdr(struct sk_buff *skb) | |||
153 | skb_pull(skb, IPOIB_HARD_LEN); | 152 | skb_pull(skb, IPOIB_HARD_LEN); |
154 | } | 153 | } |
155 | 154 | ||
156 | /* Keep the refactoring compile able */ | 155 | static inline struct ipoib_dev_priv *ipoib_priv(const struct net_device *dev) |
157 | #define ipoib_priv netdev_priv | 156 | { |
157 | struct rdma_netdev *rn = netdev_priv(dev); | ||
158 | |||
159 | return rn->clnt_priv; | ||
160 | } | ||
158 | 161 | ||
159 | /* Used for all multicast joins (broadcast, IPv4 mcast and IPv6 mcast) */ | 162 | /* Used for all multicast joins (broadcast, IPv4 mcast and IPv6 mcast) */ |
160 | struct ipoib_mcast { | 163 | struct ipoib_mcast { |
@@ -407,6 +410,7 @@ struct ipoib_dev_priv { | |||
407 | struct timer_list poll_timer; | 410 | struct timer_list poll_timer; |
408 | unsigned max_send_sge; | 411 | unsigned max_send_sge; |
409 | bool sm_fullmember_sendonly_support; | 412 | bool sm_fullmember_sendonly_support; |
413 | const struct net_device_ops *rn_ops; | ||
410 | }; | 414 | }; |
411 | 415 | ||
412 | struct ipoib_ah { | 416 | struct ipoib_ah { |
@@ -485,16 +489,16 @@ int ipoib_open(struct net_device *dev); | |||
485 | int ipoib_add_pkey_attr(struct net_device *dev); | 489 | int ipoib_add_pkey_attr(struct net_device *dev); |
486 | int ipoib_add_umcast_attr(struct net_device *dev); | 490 | int ipoib_add_umcast_attr(struct net_device *dev); |
487 | 491 | ||
488 | void ipoib_send(struct net_device *dev, struct sk_buff *skb, | 492 | int ipoib_send(struct net_device *dev, struct sk_buff *skb, |
489 | struct ipoib_ah *address, u32 dqpn); | 493 | struct ib_ah *address, u32 dqpn); |
490 | void ipoib_reap_ah(struct work_struct *work); | 494 | void ipoib_reap_ah(struct work_struct *work); |
491 | 495 | ||
492 | struct ipoib_path *__path_find(struct net_device *dev, void *gid); | 496 | struct ipoib_path *__path_find(struct net_device *dev, void *gid); |
493 | void ipoib_mark_paths_invalid(struct net_device *dev); | 497 | void ipoib_mark_paths_invalid(struct net_device *dev); |
494 | void ipoib_flush_paths(struct net_device *dev); | 498 | void ipoib_flush_paths(struct net_device *dev); |
495 | int ipoib_check_sm_sendonly_fullmember_support(struct ipoib_dev_priv *priv); | 499 | int ipoib_check_sm_sendonly_fullmember_support(struct ipoib_dev_priv *priv); |
496 | struct ipoib_dev_priv *ipoib_intf_alloc(const char *format); | 500 | struct ipoib_dev_priv *ipoib_intf_alloc(struct ib_device *hca, u8 port, |
497 | 501 | const char *format); | |
498 | void ipoib_ib_tx_timer_func(unsigned long ctx); | 502 | void ipoib_ib_tx_timer_func(unsigned long ctx); |
499 | void ipoib_ib_dev_flush_light(struct work_struct *work); | 503 | void ipoib_ib_dev_flush_light(struct work_struct *work); |
500 | void ipoib_ib_dev_flush_normal(struct work_struct *work); | 504 | void ipoib_ib_dev_flush_normal(struct work_struct *work); |
@@ -502,8 +506,9 @@ void ipoib_ib_dev_flush_heavy(struct work_struct *work); | |||
502 | void ipoib_pkey_event(struct work_struct *work); | 506 | void ipoib_pkey_event(struct work_struct *work); |
503 | void ipoib_ib_dev_cleanup(struct net_device *dev); | 507 | void ipoib_ib_dev_cleanup(struct net_device *dev); |
504 | 508 | ||
505 | void ipoib_dev_uninit_default(struct net_device *dev); | 509 | int ipoib_ib_dev_open_default(struct net_device *dev); |
506 | int ipoib_ib_dev_open(struct net_device *dev); | 510 | int ipoib_ib_dev_open(struct net_device *dev); |
511 | int ipoib_ib_dev_stop(struct net_device *dev); | ||
507 | void ipoib_ib_dev_up(struct net_device *dev); | 512 | void ipoib_ib_dev_up(struct net_device *dev); |
508 | void ipoib_ib_dev_down(struct net_device *dev); | 513 | void ipoib_ib_dev_down(struct net_device *dev); |
509 | int ipoib_ib_dev_stop_default(struct net_device *dev); | 514 | int ipoib_ib_dev_stop_default(struct net_device *dev); |
@@ -566,8 +571,10 @@ void ipoib_path_iter_read(struct ipoib_path_iter *iter, | |||
566 | struct ipoib_path *path); | 571 | struct ipoib_path *path); |
567 | #endif | 572 | #endif |
568 | 573 | ||
569 | int ipoib_mcast_attach(struct net_device *dev, u16 mlid, | 574 | int ipoib_mcast_attach(struct net_device *dev, struct ib_device *hca, |
570 | union ib_gid *mgid, int set_qkey); | 575 | union ib_gid *mgid, u16 mlid, int set_qkey, u32 qkey); |
576 | int ipoib_mcast_detach(struct net_device *dev, struct ib_device *hca, | ||
577 | union ib_gid *mgid, u16 mlid); | ||
571 | void ipoib_mcast_remove_list(struct list_head *remove_list); | 578 | void ipoib_mcast_remove_list(struct list_head *remove_list); |
572 | void ipoib_check_and_add_mcast_sendonly(struct ipoib_dev_priv *priv, u8 *mgid, | 579 | void ipoib_check_and_add_mcast_sendonly(struct ipoib_dev_priv *priv, u8 *mgid, |
573 | struct list_head *remove_list); | 580 | struct list_head *remove_list); |
@@ -591,7 +598,7 @@ void __exit ipoib_netlink_fini(void); | |||
591 | void ipoib_set_umcast(struct net_device *ndev, int umcast_val); | 598 | void ipoib_set_umcast(struct net_device *ndev, int umcast_val); |
592 | int ipoib_set_mode(struct net_device *dev, const char *buf); | 599 | int ipoib_set_mode(struct net_device *dev, const char *buf); |
593 | 600 | ||
594 | void ipoib_setup(struct net_device *dev); | 601 | void ipoib_setup_common(struct net_device *dev); |
595 | 602 | ||
596 | void ipoib_pkey_open(struct ipoib_dev_priv *priv); | 603 | void ipoib_pkey_open(struct ipoib_dev_priv *priv); |
597 | void ipoib_drain_cq(struct net_device *dev); | 604 | void ipoib_drain_cq(struct net_device *dev); |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 7c8f63d68cb5..886f790d54f9 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c | |||
@@ -537,8 +537,8 @@ static inline int post_send(struct ipoib_dev_priv *priv, | |||
537 | return ib_post_send(priv->qp, &priv->tx_wr.wr, &bad_wr); | 537 | return ib_post_send(priv->qp, &priv->tx_wr.wr, &bad_wr); |
538 | } | 538 | } |
539 | 539 | ||
540 | void ipoib_send(struct net_device *dev, struct sk_buff *skb, | 540 | int ipoib_send(struct net_device *dev, struct sk_buff *skb, |
541 | struct ipoib_ah *address, u32 dqpn) | 541 | struct ib_ah *address, u32 dqpn) |
542 | { | 542 | { |
543 | struct ipoib_dev_priv *priv = ipoib_priv(dev); | 543 | struct ipoib_dev_priv *priv = ipoib_priv(dev); |
544 | struct ipoib_tx_buf *tx_req; | 544 | struct ipoib_tx_buf *tx_req; |
@@ -554,7 +554,7 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb, | |||
554 | ++dev->stats.tx_dropped; | 554 | ++dev->stats.tx_dropped; |
555 | ++dev->stats.tx_errors; | 555 | ++dev->stats.tx_errors; |
556 | dev_kfree_skb_any(skb); | 556 | dev_kfree_skb_any(skb); |
557 | return; | 557 | return -1; |
558 | } | 558 | } |
559 | } else { | 559 | } else { |
560 | if (unlikely(skb->len > priv->mcast_mtu + IPOIB_ENCAP_LEN)) { | 560 | if (unlikely(skb->len > priv->mcast_mtu + IPOIB_ENCAP_LEN)) { |
@@ -563,7 +563,7 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb, | |||
563 | ++dev->stats.tx_dropped; | 563 | ++dev->stats.tx_dropped; |
564 | ++dev->stats.tx_errors; | 564 | ++dev->stats.tx_errors; |
565 | ipoib_cm_skb_too_long(dev, skb, priv->mcast_mtu); | 565 | ipoib_cm_skb_too_long(dev, skb, priv->mcast_mtu); |
566 | return; | 566 | return -1; |
567 | } | 567 | } |
568 | phead = NULL; | 568 | phead = NULL; |
569 | hlen = 0; | 569 | hlen = 0; |
@@ -574,7 +574,7 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb, | |||
574 | ++dev->stats.tx_dropped; | 574 | ++dev->stats.tx_dropped; |
575 | ++dev->stats.tx_errors; | 575 | ++dev->stats.tx_errors; |
576 | dev_kfree_skb_any(skb); | 576 | dev_kfree_skb_any(skb); |
577 | return; | 577 | return -1; |
578 | } | 578 | } |
579 | /* Does skb_linearize return ok without reducing nr_frags? */ | 579 | /* Does skb_linearize return ok without reducing nr_frags? */ |
580 | if (skb_shinfo(skb)->nr_frags > usable_sge) { | 580 | if (skb_shinfo(skb)->nr_frags > usable_sge) { |
@@ -582,7 +582,7 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb, | |||
582 | ++dev->stats.tx_dropped; | 582 | ++dev->stats.tx_dropped; |
583 | ++dev->stats.tx_errors; | 583 | ++dev->stats.tx_errors; |
584 | dev_kfree_skb_any(skb); | 584 | dev_kfree_skb_any(skb); |
585 | return; | 585 | return -1; |
586 | } | 586 | } |
587 | } | 587 | } |
588 | 588 | ||
@@ -602,7 +602,7 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb, | |||
602 | if (unlikely(ipoib_dma_map_tx(priv->ca, tx_req))) { | 602 | if (unlikely(ipoib_dma_map_tx(priv->ca, tx_req))) { |
603 | ++dev->stats.tx_errors; | 603 | ++dev->stats.tx_errors; |
604 | dev_kfree_skb_any(skb); | 604 | dev_kfree_skb_any(skb); |
605 | return; | 605 | return -1; |
606 | } | 606 | } |
607 | 607 | ||
608 | if (skb->ip_summed == CHECKSUM_PARTIAL) | 608 | if (skb->ip_summed == CHECKSUM_PARTIAL) |
@@ -621,7 +621,7 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb, | |||
621 | skb_dst_drop(skb); | 621 | skb_dst_drop(skb); |
622 | 622 | ||
623 | rc = post_send(priv, priv->tx_head & (ipoib_sendq_size - 1), | 623 | rc = post_send(priv, priv->tx_head & (ipoib_sendq_size - 1), |
624 | address->ah, dqpn, tx_req, phead, hlen); | 624 | address, dqpn, tx_req, phead, hlen); |
625 | if (unlikely(rc)) { | 625 | if (unlikely(rc)) { |
626 | ipoib_warn(priv, "post_send failed, error %d\n", rc); | 626 | ipoib_warn(priv, "post_send failed, error %d\n", rc); |
627 | ++dev->stats.tx_errors; | 627 | ++dev->stats.tx_errors; |
@@ -630,16 +630,19 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb, | |||
630 | dev_kfree_skb_any(skb); | 630 | dev_kfree_skb_any(skb); |
631 | if (netif_queue_stopped(dev)) | 631 | if (netif_queue_stopped(dev)) |
632 | netif_wake_queue(dev); | 632 | netif_wake_queue(dev); |
633 | rc = 0; | ||
633 | } else { | 634 | } else { |
634 | netif_trans_update(dev); | 635 | netif_trans_update(dev); |
635 | 636 | ||
636 | address->last_send = priv->tx_head; | 637 | rc = priv->tx_head; |
637 | ++priv->tx_head; | 638 | ++priv->tx_head; |
638 | } | 639 | } |
639 | 640 | ||
640 | if (unlikely(priv->tx_outstanding > MAX_SEND_CQE)) | 641 | if (unlikely(priv->tx_outstanding > MAX_SEND_CQE)) |
641 | while (poll_tx(priv)) | 642 | while (poll_tx(priv)) |
642 | ; /* nothing */ | 643 | ; /* nothing */ |
644 | |||
645 | return rc; | ||
643 | } | 646 | } |
644 | 647 | ||
645 | static void __ipoib_reap_ah(struct net_device *dev) | 648 | static void __ipoib_reap_ah(struct net_device *dev) |
@@ -714,7 +717,7 @@ int ipoib_ib_dev_stop_default(struct net_device *dev) | |||
714 | struct ipoib_tx_buf *tx_req; | 717 | struct ipoib_tx_buf *tx_req; |
715 | int i; | 718 | int i; |
716 | 719 | ||
717 | if (test_and_clear_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) | 720 | if (test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) |
718 | napi_disable(&priv->napi); | 721 | napi_disable(&priv->napi); |
719 | 722 | ||
720 | ipoib_cm_dev_stop(dev); | 723 | ipoib_cm_dev_stop(dev); |
@@ -785,8 +788,11 @@ timeout: | |||
785 | 788 | ||
786 | int ipoib_ib_dev_stop(struct net_device *dev) | 789 | int ipoib_ib_dev_stop(struct net_device *dev) |
787 | { | 790 | { |
788 | ipoib_ib_dev_stop_default(dev); | 791 | struct ipoib_dev_priv *priv = ipoib_priv(dev); |
792 | |||
793 | priv->rn_ops->ndo_stop(dev); | ||
789 | 794 | ||
795 | clear_bit(IPOIB_FLAG_INITIALIZED, &priv->flags); | ||
790 | ipoib_flush_ah(dev); | 796 | ipoib_flush_ah(dev); |
791 | 797 | ||
792 | return 0; | 798 | return 0; |
@@ -811,23 +817,20 @@ int ipoib_ib_dev_open_default(struct net_device *dev) | |||
811 | ret = ipoib_ib_post_receives(dev); | 817 | ret = ipoib_ib_post_receives(dev); |
812 | if (ret) { | 818 | if (ret) { |
813 | ipoib_warn(priv, "ipoib_ib_post_receives returned %d\n", ret); | 819 | ipoib_warn(priv, "ipoib_ib_post_receives returned %d\n", ret); |
814 | goto dev_stop; | 820 | goto out; |
815 | } | 821 | } |
816 | 822 | ||
817 | ret = ipoib_cm_dev_open(dev); | 823 | ret = ipoib_cm_dev_open(dev); |
818 | if (ret) { | 824 | if (ret) { |
819 | ipoib_warn(priv, "ipoib_cm_dev_open returned %d\n", ret); | 825 | ipoib_warn(priv, "ipoib_cm_dev_open returned %d\n", ret); |
820 | goto dev_stop; | 826 | goto out; |
821 | } | 827 | } |
822 | 828 | ||
823 | if (!test_and_set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) | 829 | if (!test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) |
824 | napi_enable(&priv->napi); | 830 | napi_enable(&priv->napi); |
825 | 831 | ||
826 | return 0; | 832 | return 0; |
827 | dev_stop: | 833 | out: |
828 | if (!test_and_set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) | ||
829 | napi_enable(&priv->napi); | ||
830 | ipoib_ib_dev_stop(dev); | ||
831 | return -1; | 834 | return -1; |
832 | } | 835 | } |
833 | 836 | ||
@@ -847,16 +850,21 @@ int ipoib_ib_dev_open(struct net_device *dev) | |||
847 | queue_delayed_work(priv->wq, &priv->ah_reap_task, | 850 | queue_delayed_work(priv->wq, &priv->ah_reap_task, |
848 | round_jiffies_relative(HZ)); | 851 | round_jiffies_relative(HZ)); |
849 | 852 | ||
850 | if (ipoib_ib_dev_open_default(dev)) { | 853 | if (priv->rn_ops->ndo_open(dev)) { |
851 | pr_warn("%s: Failed to open dev\n", dev->name); | 854 | pr_warn("%s: Failed to open dev\n", dev->name); |
852 | goto stop_ah_reap; | 855 | goto dev_stop; |
853 | } | 856 | } |
854 | 857 | ||
858 | set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags); | ||
859 | |||
855 | return 0; | 860 | return 0; |
856 | 861 | ||
857 | stop_ah_reap: | 862 | dev_stop: |
858 | set_bit(IPOIB_STOP_REAPER, &priv->flags); | 863 | set_bit(IPOIB_STOP_REAPER, &priv->flags); |
859 | cancel_delayed_work(&priv->ah_reap_task); | 864 | cancel_delayed_work(&priv->ah_reap_task); |
865 | set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags); | ||
866 | napi_enable(&priv->napi); | ||
867 | ipoib_ib_dev_stop(dev); | ||
860 | return -1; | 868 | return -1; |
861 | } | 869 | } |
862 | 870 | ||
@@ -1241,7 +1249,7 @@ void ipoib_ib_dev_cleanup(struct net_device *dev) | |||
1241 | 1249 | ||
1242 | clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); | 1250 | clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); |
1243 | 1251 | ||
1244 | ipoib_dev_uninit_default(dev); | 1252 | priv->rn_ops->ndo_uninit(dev); |
1245 | 1253 | ||
1246 | if (priv->pd) { | 1254 | if (priv->pd) { |
1247 | ib_dealloc_pd(priv->pd); | 1255 | ib_dealloc_pd(priv->pd); |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 0dd6047600c1..2a489f174c51 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
@@ -193,7 +193,7 @@ static int ipoib_stop(struct net_device *dev) | |||
193 | netif_stop_queue(dev); | 193 | netif_stop_queue(dev); |
194 | 194 | ||
195 | ipoib_ib_dev_down(dev); | 195 | ipoib_ib_dev_down(dev); |
196 | ipoib_ib_dev_stop_default(dev); | 196 | ipoib_ib_dev_stop(dev); |
197 | 197 | ||
198 | if (!test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) { | 198 | if (!test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) { |
199 | struct ipoib_dev_priv *cpriv; | 199 | struct ipoib_dev_priv *cpriv; |
@@ -945,6 +945,7 @@ static void neigh_add_path(struct sk_buff *skb, u8 *daddr, | |||
945 | struct net_device *dev) | 945 | struct net_device *dev) |
946 | { | 946 | { |
947 | struct ipoib_dev_priv *priv = ipoib_priv(dev); | 947 | struct ipoib_dev_priv *priv = ipoib_priv(dev); |
948 | struct rdma_netdev *rn = netdev_priv(dev); | ||
948 | struct ipoib_path *path; | 949 | struct ipoib_path *path; |
949 | struct ipoib_neigh *neigh; | 950 | struct ipoib_neigh *neigh; |
950 | unsigned long flags; | 951 | unsigned long flags; |
@@ -991,7 +992,8 @@ static void neigh_add_path(struct sk_buff *skb, u8 *daddr, | |||
991 | } | 992 | } |
992 | } else { | 993 | } else { |
993 | spin_unlock_irqrestore(&priv->lock, flags); | 994 | spin_unlock_irqrestore(&priv->lock, flags); |
994 | ipoib_send(dev, skb, path->ah, IPOIB_QPN(daddr)); | 995 | path->ah->last_send = rn->send(dev, skb, path->ah->ah, |
996 | IPOIB_QPN(daddr)); | ||
995 | ipoib_neigh_put(neigh); | 997 | ipoib_neigh_put(neigh); |
996 | return; | 998 | return; |
997 | } | 999 | } |
@@ -1026,6 +1028,7 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev, | |||
1026 | struct ipoib_pseudo_header *phdr) | 1028 | struct ipoib_pseudo_header *phdr) |
1027 | { | 1029 | { |
1028 | struct ipoib_dev_priv *priv = ipoib_priv(dev); | 1030 | struct ipoib_dev_priv *priv = ipoib_priv(dev); |
1031 | struct rdma_netdev *rn = netdev_priv(dev); | ||
1029 | struct ipoib_path *path; | 1032 | struct ipoib_path *path; |
1030 | unsigned long flags; | 1033 | unsigned long flags; |
1031 | 1034 | ||
@@ -1069,7 +1072,8 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev, | |||
1069 | be16_to_cpu(path->pathrec.dlid)); | 1072 | be16_to_cpu(path->pathrec.dlid)); |
1070 | 1073 | ||
1071 | spin_unlock_irqrestore(&priv->lock, flags); | 1074 | spin_unlock_irqrestore(&priv->lock, flags); |
1072 | ipoib_send(dev, skb, path->ah, IPOIB_QPN(phdr->hwaddr)); | 1075 | path->ah->last_send = rn->send(dev, skb, path->ah->ah, |
1076 | IPOIB_QPN(phdr->hwaddr)); | ||
1073 | return; | 1077 | return; |
1074 | } else if ((path->query || !path_rec_start(dev, path)) && | 1078 | } else if ((path->query || !path_rec_start(dev, path)) && |
1075 | skb_queue_len(&path->queue) < IPOIB_MAX_PATH_REC_QUEUE) { | 1079 | skb_queue_len(&path->queue) < IPOIB_MAX_PATH_REC_QUEUE) { |
@@ -1086,6 +1090,7 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev, | |||
1086 | static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) | 1090 | static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) |
1087 | { | 1091 | { |
1088 | struct ipoib_dev_priv *priv = ipoib_priv(dev); | 1092 | struct ipoib_dev_priv *priv = ipoib_priv(dev); |
1093 | struct rdma_netdev *rn = netdev_priv(dev); | ||
1089 | struct ipoib_neigh *neigh; | 1094 | struct ipoib_neigh *neigh; |
1090 | struct ipoib_pseudo_header *phdr; | 1095 | struct ipoib_pseudo_header *phdr; |
1091 | struct ipoib_header *header; | 1096 | struct ipoib_header *header; |
@@ -1149,7 +1154,8 @@ send_using_neigh: | |||
1149 | goto unref; | 1154 | goto unref; |
1150 | } | 1155 | } |
1151 | } else if (neigh->ah) { | 1156 | } else if (neigh->ah) { |
1152 | ipoib_send(dev, skb, neigh->ah, IPOIB_QPN(phdr->hwaddr)); | 1157 | neigh->ah->last_send = rn->send(dev, skb, neigh->ah->ah, |
1158 | IPOIB_QPN(phdr->hwaddr)); | ||
1153 | goto unref; | 1159 | goto unref; |
1154 | } | 1160 | } |
1155 | 1161 | ||
@@ -1664,11 +1670,12 @@ void ipoib_dev_uninit_default(struct net_device *dev) | |||
1664 | priv->tx_ring = NULL; | 1670 | priv->tx_ring = NULL; |
1665 | } | 1671 | } |
1666 | 1672 | ||
1667 | static int ipoib_dev_init_default(struct net_device *dev, struct ib_device *ca, | 1673 | static int ipoib_dev_init_default(struct net_device *dev) |
1668 | int port) | ||
1669 | { | 1674 | { |
1670 | struct ipoib_dev_priv *priv = ipoib_priv(dev); | 1675 | struct ipoib_dev_priv *priv = ipoib_priv(dev); |
1671 | 1676 | ||
1677 | netif_napi_add(dev, &priv->napi, ipoib_poll, NAPI_POLL_WEIGHT); | ||
1678 | |||
1672 | /* Allocate RX/TX "rings" to hold queued skbs */ | 1679 | /* Allocate RX/TX "rings" to hold queued skbs */ |
1673 | priv->rx_ring = kzalloc(ipoib_recvq_size * sizeof *priv->rx_ring, | 1680 | priv->rx_ring = kzalloc(ipoib_recvq_size * sizeof *priv->rx_ring, |
1674 | GFP_KERNEL); | 1681 | GFP_KERNEL); |
@@ -1678,17 +1685,23 @@ static int ipoib_dev_init_default(struct net_device *dev, struct ib_device *ca, | |||
1678 | priv->tx_ring = vzalloc(ipoib_sendq_size * sizeof *priv->tx_ring); | 1685 | priv->tx_ring = vzalloc(ipoib_sendq_size * sizeof *priv->tx_ring); |
1679 | if (!priv->tx_ring) { | 1686 | if (!priv->tx_ring) { |
1680 | printk(KERN_WARNING "%s: failed to allocate TX ring (%d entries)\n", | 1687 | printk(KERN_WARNING "%s: failed to allocate TX ring (%d entries)\n", |
1681 | ca->name, ipoib_sendq_size); | 1688 | priv->ca->name, ipoib_sendq_size); |
1682 | goto out_rx_ring_cleanup; | 1689 | goto out_rx_ring_cleanup; |
1683 | } | 1690 | } |
1684 | 1691 | ||
1685 | /* priv->tx_head, tx_tail & tx_outstanding are already 0 */ | 1692 | /* priv->tx_head, tx_tail & tx_outstanding are already 0 */ |
1686 | 1693 | ||
1687 | if (ipoib_transport_dev_init(dev, ca)) { | 1694 | if (ipoib_transport_dev_init(dev, priv->ca)) { |
1688 | pr_warn("%s: ipoib_transport_dev_init failed\n", ca->name); | 1695 | pr_warn("%s: ipoib_transport_dev_init failed\n", |
1696 | priv->ca->name); | ||
1689 | goto out_tx_ring_cleanup; | 1697 | goto out_tx_ring_cleanup; |
1690 | } | 1698 | } |
1691 | 1699 | ||
1700 | /* after qp created set dev address */ | ||
1701 | priv->dev->dev_addr[1] = (priv->qp->qp_num >> 16) & 0xff; | ||
1702 | priv->dev->dev_addr[2] = (priv->qp->qp_num >> 8) & 0xff; | ||
1703 | priv->dev->dev_addr[3] = (priv->qp->qp_num) & 0xff; | ||
1704 | |||
1692 | setup_timer(&priv->poll_timer, ipoib_ib_tx_timer_func, | 1705 | setup_timer(&priv->poll_timer, ipoib_ib_tx_timer_func, |
1693 | (unsigned long)dev); | 1706 | (unsigned long)dev); |
1694 | 1707 | ||
@@ -1730,17 +1743,12 @@ int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port) | |||
1730 | goto clean_wq; | 1743 | goto clean_wq; |
1731 | } | 1744 | } |
1732 | 1745 | ||
1733 | ret = ipoib_dev_init_default(dev, ca, port); | 1746 | ret = priv->rn_ops->ndo_init(dev); |
1734 | if (ret) { | 1747 | if (ret) { |
1735 | pr_warn("%s failed to init HW resource\n", dev->name); | 1748 | pr_warn("%s failed to init HW resource\n", dev->name); |
1736 | goto out_free_pd; | 1749 | goto out_free_pd; |
1737 | } | 1750 | } |
1738 | 1751 | ||
1739 | /* after qp created set dev address */ | ||
1740 | priv->dev->dev_addr[1] = (priv->qp->qp_num >> 16) & 0xff; | ||
1741 | priv->dev->dev_addr[2] = (priv->qp->qp_num >> 8) & 0xff; | ||
1742 | priv->dev->dev_addr[3] = (priv->qp->qp_num) & 0xff; | ||
1743 | |||
1744 | if (ipoib_neigh_hash_init(priv) < 0) { | 1752 | if (ipoib_neigh_hash_init(priv) < 0) { |
1745 | pr_warn("%s failed to init neigh hash\n", dev->name); | 1753 | pr_warn("%s failed to init neigh hash\n", dev->name); |
1746 | goto out_dev_uninit; | 1754 | goto out_dev_uninit; |
@@ -1876,21 +1884,12 @@ static const struct net_device_ops ipoib_netdev_ops_vf = { | |||
1876 | .ndo_get_iflink = ipoib_get_iflink, | 1884 | .ndo_get_iflink = ipoib_get_iflink, |
1877 | }; | 1885 | }; |
1878 | 1886 | ||
1879 | void ipoib_setup(struct net_device *dev) | 1887 | void ipoib_setup_common(struct net_device *dev) |
1880 | { | 1888 | { |
1881 | struct ipoib_dev_priv *priv = ipoib_priv(dev); | ||
1882 | |||
1883 | if (priv->hca_caps & IB_DEVICE_VIRTUAL_FUNCTION) | ||
1884 | dev->netdev_ops = &ipoib_netdev_ops_vf; | ||
1885 | else | ||
1886 | dev->netdev_ops = &ipoib_netdev_ops_pf; | ||
1887 | |||
1888 | dev->header_ops = &ipoib_header_ops; | 1889 | dev->header_ops = &ipoib_header_ops; |
1889 | 1890 | ||
1890 | ipoib_set_ethtool_ops(dev); | 1891 | ipoib_set_ethtool_ops(dev); |
1891 | 1892 | ||
1892 | netif_napi_add(dev, &priv->napi, ipoib_poll, NAPI_POLL_WEIGHT); | ||
1893 | |||
1894 | dev->watchdog_timeo = HZ; | 1893 | dev->watchdog_timeo = HZ; |
1895 | 1894 | ||
1896 | dev->flags |= IFF_BROADCAST | IFF_MULTICAST; | 1895 | dev->flags |= IFF_BROADCAST | IFF_MULTICAST; |
@@ -1904,11 +1903,14 @@ void ipoib_setup(struct net_device *dev) | |||
1904 | netif_keep_dst(dev); | 1903 | netif_keep_dst(dev); |
1905 | 1904 | ||
1906 | memcpy(dev->broadcast, ipv4_bcast_addr, INFINIBAND_ALEN); | 1905 | memcpy(dev->broadcast, ipv4_bcast_addr, INFINIBAND_ALEN); |
1906 | } | ||
1907 | 1907 | ||
1908 | priv->dev = dev; | 1908 | static void ipoib_build_priv(struct net_device *dev) |
1909 | { | ||
1910 | struct ipoib_dev_priv *priv = ipoib_priv(dev); | ||
1909 | 1911 | ||
1912 | priv->dev = dev; | ||
1910 | spin_lock_init(&priv->lock); | 1913 | spin_lock_init(&priv->lock); |
1911 | |||
1912 | init_rwsem(&priv->vlan_rwsem); | 1914 | init_rwsem(&priv->vlan_rwsem); |
1913 | 1915 | ||
1914 | INIT_LIST_HEAD(&priv->path_list); | 1916 | INIT_LIST_HEAD(&priv->path_list); |
@@ -1926,16 +1928,92 @@ void ipoib_setup(struct net_device *dev) | |||
1926 | INIT_DELAYED_WORK(&priv->neigh_reap_task, ipoib_reap_neigh); | 1928 | INIT_DELAYED_WORK(&priv->neigh_reap_task, ipoib_reap_neigh); |
1927 | } | 1929 | } |
1928 | 1930 | ||
1929 | struct ipoib_dev_priv *ipoib_intf_alloc(const char *name) | 1931 | static const struct net_device_ops ipoib_netdev_default_pf = { |
1932 | .ndo_init = ipoib_dev_init_default, | ||
1933 | .ndo_uninit = ipoib_dev_uninit_default, | ||
1934 | .ndo_open = ipoib_ib_dev_open_default, | ||
1935 | .ndo_stop = ipoib_ib_dev_stop_default, | ||
1936 | }; | ||
1937 | |||
1938 | static struct net_device | ||
1939 | *ipoib_create_netdev_default(struct ib_device *hca, | ||
1940 | const char *name, | ||
1941 | unsigned char name_assign_type, | ||
1942 | void (*setup)(struct net_device *)) | ||
1930 | { | 1943 | { |
1931 | struct net_device *dev; | 1944 | struct net_device *dev; |
1945 | struct rdma_netdev *rn; | ||
1932 | 1946 | ||
1933 | dev = alloc_netdev((int)sizeof(struct ipoib_dev_priv), name, | 1947 | dev = alloc_netdev((int)sizeof(struct rdma_netdev), |
1934 | NET_NAME_UNKNOWN, ipoib_setup); | 1948 | name, |
1949 | name_assign_type, setup); | ||
1935 | if (!dev) | 1950 | if (!dev) |
1936 | return NULL; | 1951 | return NULL; |
1937 | 1952 | ||
1938 | return netdev_priv(dev); | 1953 | rn = netdev_priv(dev); |
1954 | |||
1955 | rn->send = ipoib_send; | ||
1956 | rn->attach_mcast = ipoib_mcast_attach; | ||
1957 | rn->detach_mcast = ipoib_mcast_detach; | ||
1958 | rn->hca = hca; | ||
1959 | |||
1960 | dev->netdev_ops = &ipoib_netdev_default_pf; | ||
1961 | |||
1962 | return dev; | ||
1963 | } | ||
1964 | |||
1965 | static struct net_device *ipoib_get_netdev(struct ib_device *hca, u8 port, | ||
1966 | const char *name) | ||
1967 | { | ||
1968 | struct net_device *dev; | ||
1969 | |||
1970 | if (hca->alloc_rdma_netdev) { | ||
1971 | dev = hca->alloc_rdma_netdev(hca, port, | ||
1972 | RDMA_NETDEV_IPOIB, name, | ||
1973 | NET_NAME_UNKNOWN, | ||
1974 | ipoib_setup_common); | ||
1975 | if (IS_ERR_OR_NULL(dev) && PTR_ERR(dev) != -EOPNOTSUPP) | ||
1976 | return NULL; | ||
1977 | } | ||
1978 | |||
1979 | if (!hca->alloc_rdma_netdev || PTR_ERR(dev) == -EOPNOTSUPP) | ||
1980 | dev = ipoib_create_netdev_default(hca, name, NET_NAME_UNKNOWN, | ||
1981 | ipoib_setup_common); | ||
1982 | |||
1983 | return dev; | ||
1984 | } | ||
1985 | |||
1986 | struct ipoib_dev_priv *ipoib_intf_alloc(struct ib_device *hca, u8 port, | ||
1987 | const char *name) | ||
1988 | { | ||
1989 | struct net_device *dev; | ||
1990 | struct ipoib_dev_priv *priv; | ||
1991 | struct rdma_netdev *rn; | ||
1992 | |||
1993 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
1994 | if (!priv) | ||
1995 | return NULL; | ||
1996 | |||
1997 | dev = ipoib_get_netdev(hca, port, name); | ||
1998 | if (!dev) | ||
1999 | goto free_priv; | ||
2000 | |||
2001 | priv->rn_ops = dev->netdev_ops; | ||
2002 | |||
2003 | /* fixme : should be after the query_cap */ | ||
2004 | if (priv->hca_caps & IB_DEVICE_VIRTUAL_FUNCTION) | ||
2005 | dev->netdev_ops = &ipoib_netdev_ops_vf; | ||
2006 | else | ||
2007 | dev->netdev_ops = &ipoib_netdev_ops_pf; | ||
2008 | |||
2009 | rn = netdev_priv(dev); | ||
2010 | rn->clnt_priv = priv; | ||
2011 | ipoib_build_priv(dev); | ||
2012 | |||
2013 | return priv; | ||
2014 | free_priv: | ||
2015 | kfree(priv); | ||
2016 | return NULL; | ||
1939 | } | 2017 | } |
1940 | 2018 | ||
1941 | static ssize_t show_pkey(struct device *dev, | 2019 | static ssize_t show_pkey(struct device *dev, |
@@ -2105,7 +2183,7 @@ void ipoib_set_dev_features(struct ipoib_dev_priv *priv, struct ib_device *hca) | |||
2105 | priv->hca_caps = hca->attrs.device_cap_flags; | 2183 | priv->hca_caps = hca->attrs.device_cap_flags; |
2106 | 2184 | ||
2107 | if (priv->hca_caps & IB_DEVICE_UD_IP_CSUM) { | 2185 | if (priv->hca_caps & IB_DEVICE_UD_IP_CSUM) { |
2108 | priv->dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM; | 2186 | priv->dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM; |
2109 | 2187 | ||
2110 | if (priv->hca_caps & IB_DEVICE_UD_TSO) | 2188 | if (priv->hca_caps & IB_DEVICE_UD_TSO) |
2111 | priv->dev->hw_features |= NETIF_F_TSO; | 2189 | priv->dev->hw_features |= NETIF_F_TSO; |
@@ -2121,7 +2199,7 @@ static struct net_device *ipoib_add_port(const char *format, | |||
2121 | struct ib_port_attr attr; | 2199 | struct ib_port_attr attr; |
2122 | int result = -ENOMEM; | 2200 | int result = -ENOMEM; |
2123 | 2201 | ||
2124 | priv = ipoib_intf_alloc(format); | 2202 | priv = ipoib_intf_alloc(hca, port, format); |
2125 | if (!priv) | 2203 | if (!priv) |
2126 | goto alloc_mem_failed; | 2204 | goto alloc_mem_failed; |
2127 | 2205 | ||
@@ -2288,6 +2366,7 @@ static void ipoib_remove_one(struct ib_device *device, void *client_data) | |||
2288 | 2366 | ||
2289 | unregister_netdev(priv->dev); | 2367 | unregister_netdev(priv->dev); |
2290 | free_netdev(priv->dev); | 2368 | free_netdev(priv->dev); |
2369 | kfree(priv); | ||
2291 | } | 2370 | } |
2292 | 2371 | ||
2293 | kfree(dev_list); | 2372 | kfree(dev_list); |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 28d4713ed5ed..8da1955e0003 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c | |||
@@ -213,6 +213,7 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast, | |||
213 | { | 213 | { |
214 | struct net_device *dev = mcast->dev; | 214 | struct net_device *dev = mcast->dev; |
215 | struct ipoib_dev_priv *priv = ipoib_priv(dev); | 215 | struct ipoib_dev_priv *priv = ipoib_priv(dev); |
216 | struct rdma_netdev *rn = netdev_priv(dev); | ||
216 | struct ipoib_ah *ah; | 217 | struct ipoib_ah *ah; |
217 | int ret; | 218 | int ret; |
218 | int set_qkey = 0; | 219 | int set_qkey = 0; |
@@ -260,8 +261,9 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast, | |||
260 | return 0; | 261 | return 0; |
261 | } | 262 | } |
262 | 263 | ||
263 | ret = ipoib_mcast_attach(dev, be16_to_cpu(mcast->mcmember.mlid), | 264 | ret = rn->attach_mcast(dev, priv->ca, &mcast->mcmember.mgid, |
264 | &mcast->mcmember.mgid, set_qkey); | 265 | be16_to_cpu(mcast->mcmember.mlid), |
266 | set_qkey, priv->qkey); | ||
265 | if (ret < 0) { | 267 | if (ret < 0) { |
266 | ipoib_warn(priv, "couldn't attach QP to multicast group %pI6\n", | 268 | ipoib_warn(priv, "couldn't attach QP to multicast group %pI6\n", |
267 | mcast->mcmember.mgid.raw); | 269 | mcast->mcmember.mgid.raw); |
@@ -707,6 +709,7 @@ int ipoib_mcast_stop_thread(struct net_device *dev) | |||
707 | static int ipoib_mcast_leave(struct net_device *dev, struct ipoib_mcast *mcast) | 709 | static int ipoib_mcast_leave(struct net_device *dev, struct ipoib_mcast *mcast) |
708 | { | 710 | { |
709 | struct ipoib_dev_priv *priv = ipoib_priv(dev); | 711 | struct ipoib_dev_priv *priv = ipoib_priv(dev); |
712 | struct rdma_netdev *rn = netdev_priv(dev); | ||
710 | int ret = 0; | 713 | int ret = 0; |
711 | 714 | ||
712 | if (test_and_clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags)) | 715 | if (test_and_clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags)) |
@@ -720,8 +723,8 @@ static int ipoib_mcast_leave(struct net_device *dev, struct ipoib_mcast *mcast) | |||
720 | mcast->mcmember.mgid.raw); | 723 | mcast->mcmember.mgid.raw); |
721 | 724 | ||
722 | /* Remove ourselves from the multicast group */ | 725 | /* Remove ourselves from the multicast group */ |
723 | ret = ib_detach_mcast(priv->qp, &mcast->mcmember.mgid, | 726 | ret = rn->detach_mcast(dev, priv->ca, &mcast->mcmember.mgid, |
724 | be16_to_cpu(mcast->mcmember.mlid)); | 727 | be16_to_cpu(mcast->mcmember.mlid)); |
725 | if (ret) | 728 | if (ret) |
726 | ipoib_warn(priv, "ib_detach_mcast failed (result = %d)\n", ret); | 729 | ipoib_warn(priv, "ib_detach_mcast failed (result = %d)\n", ret); |
727 | } else if (!test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) | 730 | } else if (!test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) |
@@ -763,6 +766,7 @@ void ipoib_mcast_remove_list(struct list_head *remove_list) | |||
763 | void ipoib_mcast_send(struct net_device *dev, u8 *daddr, struct sk_buff *skb) | 766 | void ipoib_mcast_send(struct net_device *dev, u8 *daddr, struct sk_buff *skb) |
764 | { | 767 | { |
765 | struct ipoib_dev_priv *priv = ipoib_priv(dev); | 768 | struct ipoib_dev_priv *priv = ipoib_priv(dev); |
769 | struct rdma_netdev *rn = netdev_priv(dev); | ||
766 | struct ipoib_mcast *mcast; | 770 | struct ipoib_mcast *mcast; |
767 | unsigned long flags; | 771 | unsigned long flags; |
768 | void *mgid = daddr + 4; | 772 | void *mgid = daddr + 4; |
@@ -825,7 +829,8 @@ void ipoib_mcast_send(struct net_device *dev, u8 *daddr, struct sk_buff *skb) | |||
825 | } | 829 | } |
826 | } | 830 | } |
827 | spin_unlock_irqrestore(&priv->lock, flags); | 831 | spin_unlock_irqrestore(&priv->lock, flags); |
828 | ipoib_send(dev, skb, mcast->ah, IB_MULTICAST_QPN); | 832 | mcast->ah->last_send = rn->send(dev, skb, mcast->ah->ah, |
833 | IB_MULTICAST_QPN); | ||
829 | if (neigh) | 834 | if (neigh) |
830 | ipoib_neigh_put(neigh); | 835 | ipoib_neigh_put(neigh); |
831 | return; | 836 | return; |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_netlink.c b/drivers/infiniband/ulp/ipoib/ipoib_netlink.c index f734b608e6ed..28884781311b 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_netlink.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_netlink.c | |||
@@ -162,7 +162,7 @@ static struct rtnl_link_ops ipoib_link_ops __read_mostly = { | |||
162 | .maxtype = IFLA_IPOIB_MAX, | 162 | .maxtype = IFLA_IPOIB_MAX, |
163 | .policy = ipoib_policy, | 163 | .policy = ipoib_policy, |
164 | .priv_size = sizeof(struct ipoib_dev_priv), | 164 | .priv_size = sizeof(struct ipoib_dev_priv), |
165 | .setup = ipoib_setup, | 165 | .setup = ipoib_setup_common, |
166 | .newlink = ipoib_new_child_link, | 166 | .newlink = ipoib_new_child_link, |
167 | .changelink = ipoib_changelink, | 167 | .changelink = ipoib_changelink, |
168 | .dellink = ipoib_unregister_child_dev, | 168 | .dellink = ipoib_unregister_child_dev, |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c index 87b6f205d1fc..bb64baf25309 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c | |||
@@ -35,7 +35,8 @@ | |||
35 | 35 | ||
36 | #include "ipoib.h" | 36 | #include "ipoib.h" |
37 | 37 | ||
38 | int ipoib_mcast_attach(struct net_device *dev, u16 mlid, union ib_gid *mgid, int set_qkey) | 38 | int ipoib_mcast_attach(struct net_device *dev, struct ib_device *hca, |
39 | union ib_gid *mgid, u16 mlid, int set_qkey, u32 qkey) | ||
39 | { | 40 | { |
40 | struct ipoib_dev_priv *priv = ipoib_priv(dev); | 41 | struct ipoib_dev_priv *priv = ipoib_priv(dev); |
41 | struct ib_qp_attr *qp_attr = NULL; | 42 | struct ib_qp_attr *qp_attr = NULL; |
@@ -56,7 +57,7 @@ int ipoib_mcast_attach(struct net_device *dev, u16 mlid, union ib_gid *mgid, int | |||
56 | goto out; | 57 | goto out; |
57 | 58 | ||
58 | /* set correct QKey for QP */ | 59 | /* set correct QKey for QP */ |
59 | qp_attr->qkey = priv->qkey; | 60 | qp_attr->qkey = qkey; |
60 | ret = ib_modify_qp(priv->qp, qp_attr, IB_QP_QKEY); | 61 | ret = ib_modify_qp(priv->qp, qp_attr, IB_QP_QKEY); |
61 | if (ret) { | 62 | if (ret) { |
62 | ipoib_warn(priv, "failed to modify QP, ret = %d\n", ret); | 63 | ipoib_warn(priv, "failed to modify QP, ret = %d\n", ret); |
@@ -74,6 +75,17 @@ out: | |||
74 | return ret; | 75 | return ret; |
75 | } | 76 | } |
76 | 77 | ||
78 | int ipoib_mcast_detach(struct net_device *dev, struct ib_device *hca, | ||
79 | union ib_gid *mgid, u16 mlid) | ||
80 | { | ||
81 | struct ipoib_dev_priv *priv = ipoib_priv(dev); | ||
82 | int ret; | ||
83 | |||
84 | ret = ib_detach_mcast(priv->qp, mgid, mlid); | ||
85 | |||
86 | return ret; | ||
87 | } | ||
88 | |||
77 | int ipoib_init_qp(struct net_device *dev) | 89 | int ipoib_init_qp(struct net_device *dev) |
78 | { | 90 | { |
79 | struct ipoib_dev_priv *priv = ipoib_priv(dev); | 91 | struct ipoib_dev_priv *priv = ipoib_priv(dev); |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c index c53e7f3c57f0..36dc4fcaa3cd 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c | |||
@@ -125,14 +125,15 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey) | |||
125 | if (!capable(CAP_NET_ADMIN)) | 125 | if (!capable(CAP_NET_ADMIN)) |
126 | return -EPERM; | 126 | return -EPERM; |
127 | 127 | ||
128 | ppriv = netdev_priv(pdev); | 128 | ppriv = ipoib_priv(pdev); |
129 | 129 | ||
130 | if (test_bit(IPOIB_FLAG_GOING_DOWN, &ppriv->flags)) | 130 | if (test_bit(IPOIB_FLAG_GOING_DOWN, &ppriv->flags)) |
131 | return -EPERM; | 131 | return -EPERM; |
132 | 132 | ||
133 | snprintf(intf_name, sizeof intf_name, "%s.%04x", | 133 | snprintf(intf_name, sizeof intf_name, "%s.%04x", |
134 | ppriv->dev->name, pkey); | 134 | ppriv->dev->name, pkey); |
135 | priv = ipoib_intf_alloc(intf_name); | 135 | |
136 | priv = ipoib_intf_alloc(ppriv->ca, ppriv->port, intf_name); | ||
136 | if (!priv) | 137 | if (!priv) |
137 | return -ENOMEM; | 138 | return -ENOMEM; |
138 | 139 | ||