aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/ulp/ipoib
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-11 22:43:13 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-11 22:43:13 -0400
commitce9d3c9a6a9aef61525be07fe6ba27d937236aa2 (patch)
tree1b29bcb8f60fc6b59fa0d7b833cc733b8ebe17c9 /drivers/infiniband/ulp/ipoib
parent038a5008b2f395c85e6e71d6ddf3c684e7c405b0 (diff)
parent3d73c2884f45f9a297cbc956cea101405a9703f2 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband: (87 commits) mlx4_core: Fix section mismatches IPoIB: Allow setting policy to ignore multicast groups IB/mthca: Mark error paths as unlikely() in post_srq_recv functions IB/ipath: Minor fix to ordering of freeing and zeroing of tid pages. IB/ipath: Remove redundant link state checks IB/ipath: Fix IB_EVENT_PORT_ERR event IB/ipath: Better handling of unexpected GPIO interrupts IB/ipath: Maintain active time on all chips IB/ipath: Fix QHT7040 serial number check IB/ipath: Indicate a couple of chip bugs to userspace IB/ipath: iba6110 rev4 no longer needs recv header overrun workaround IB/ipath: Use counters in ipath_poll and cleanup interrupts in ipath_close IB/ipath: Remove duplicate copy of LMC IB/ipath: Add ability to set the LMC via the sysfs debugging interface IB/ipath: Optimize completion queue entry insertion and polling IB/ipath: Implement IB_EVENT_QP_LAST_WQE_REACHED IB/ipath: Generate flush CQE when QP is in error state IB/ipath: Remove redundant code IB/ipath: Future proof eeprom checksum code (contents reading) IB/ipath: UC RDMA WRITE with IMMEDIATE doesn't send the immediate ...
Diffstat (limited to 'drivers/infiniband/ulp/ipoib')
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib.h24
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_cm.c18
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_ib.c8
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c45
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_multicast.c31
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_verbs.c2
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_vlan.c2
7 files changed, 93 insertions, 37 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index 34c6128d2a34..6545fa798b12 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -86,6 +86,7 @@ enum {
86 IPOIB_MCAST_STARTED = 8, 86 IPOIB_MCAST_STARTED = 8,
87 IPOIB_FLAG_NETIF_STOPPED = 9, 87 IPOIB_FLAG_NETIF_STOPPED = 9,
88 IPOIB_FLAG_ADMIN_CM = 10, 88 IPOIB_FLAG_ADMIN_CM = 10,
89 IPOIB_FLAG_UMCAST = 11,
89 90
90 IPOIB_MAX_BACKOFF_SECONDS = 16, 91 IPOIB_MAX_BACKOFF_SECONDS = 16,
91 92
@@ -113,7 +114,27 @@ struct ipoib_pseudoheader {
113 u8 hwaddr[INFINIBAND_ALEN]; 114 u8 hwaddr[INFINIBAND_ALEN];
114}; 115};
115 116
116struct ipoib_mcast; 117/* Used for all multicast joins (broadcast, IPv4 mcast and IPv6 mcast) */
118struct ipoib_mcast {
119 struct ib_sa_mcmember_rec mcmember;
120 struct ib_sa_multicast *mc;
121 struct ipoib_ah *ah;
122
123 struct rb_node rb_node;
124 struct list_head list;
125
126 unsigned long created;
127 unsigned long backoff;
128
129 unsigned long flags;
130 unsigned char logcount;
131
132 struct list_head neigh_list;
133
134 struct sk_buff_head pkt_queue;
135
136 struct net_device *dev;
137};
117 138
118struct ipoib_rx_buf { 139struct ipoib_rx_buf {
119 struct sk_buff *skb; 140 struct sk_buff *skb;
@@ -364,6 +385,7 @@ static inline void ipoib_put_ah(struct ipoib_ah *ah)
364 385
365int ipoib_open(struct net_device *dev); 386int ipoib_open(struct net_device *dev);
366int ipoib_add_pkey_attr(struct net_device *dev); 387int ipoib_add_pkey_attr(struct net_device *dev);
388int ipoib_add_umcast_attr(struct net_device *dev);
367 389
368void ipoib_send(struct net_device *dev, struct sk_buff *skb, 390void ipoib_send(struct net_device *dev, struct sk_buff *skb,
369 struct ipoib_ah *address, u32 qpn); 391 struct ipoib_ah *address, u32 qpn);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index 1afd93cdd6bb..0a0dcb8fdfd1 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -810,14 +810,16 @@ static int ipoib_cm_rep_handler(struct ib_cm_id *cm_id, struct ib_cm_event *even
810static struct ib_qp *ipoib_cm_create_tx_qp(struct net_device *dev, struct ib_cq *cq) 810static struct ib_qp *ipoib_cm_create_tx_qp(struct net_device *dev, struct ib_cq *cq)
811{ 811{
812 struct ipoib_dev_priv *priv = netdev_priv(dev); 812 struct ipoib_dev_priv *priv = netdev_priv(dev);
813 struct ib_qp_init_attr attr = {}; 813 struct ib_qp_init_attr attr = {
814 attr.recv_cq = priv->cq; 814 .send_cq = cq,
815 attr.srq = priv->cm.srq; 815 .recv_cq = priv->cq,
816 attr.cap.max_send_wr = ipoib_sendq_size; 816 .srq = priv->cm.srq,
817 attr.cap.max_send_sge = 1; 817 .cap.max_send_wr = ipoib_sendq_size,
818 attr.sq_sig_type = IB_SIGNAL_ALL_WR; 818 .cap.max_send_sge = 1,
819 attr.qp_type = IB_QPT_RC; 819 .sq_sig_type = IB_SIGNAL_ALL_WR,
820 attr.send_cq = cq; 820 .qp_type = IB_QPT_RC,
821 };
822
821 return ib_create_qp(priv->pd, &attr); 823 return ib_create_qp(priv->pd, &attr);
822} 824}
823 825
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index 0ec28c302fbf..1a77e79f6b43 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -553,6 +553,14 @@ void ipoib_drain_cq(struct net_device *dev)
553 do { 553 do {
554 n = ib_poll_cq(priv->cq, IPOIB_NUM_WC, priv->ibwc); 554 n = ib_poll_cq(priv->cq, IPOIB_NUM_WC, priv->ibwc);
555 for (i = 0; i < n; ++i) { 555 for (i = 0; i < n; ++i) {
556 /*
557 * Convert any successful completions to flush
558 * errors to avoid passing packets up the
559 * stack after bringing the device down.
560 */
561 if (priv->ibwc[i].status == IB_WC_SUCCESS)
562 priv->ibwc[i].status = IB_WC_WR_FLUSH_ERR;
563
556 if (priv->ibwc[i].wr_id & IPOIB_CM_OP_SRQ) 564 if (priv->ibwc[i].wr_id & IPOIB_CM_OP_SRQ)
557 ipoib_cm_handle_rx_wc(dev, priv->ibwc + i); 565 ipoib_cm_handle_rx_wc(dev, priv->ibwc + i);
558 else if (priv->ibwc[i].wr_id & IPOIB_OP_RECV) 566 else if (priv->ibwc[i].wr_id & IPOIB_OP_RECV)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 855c9deca8b7..e072f3c32ce6 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -473,9 +473,10 @@ static struct ipoib_path *path_rec_create(struct net_device *dev, void *gid)
473 INIT_LIST_HEAD(&path->neigh_list); 473 INIT_LIST_HEAD(&path->neigh_list);
474 474
475 memcpy(path->pathrec.dgid.raw, gid, sizeof (union ib_gid)); 475 memcpy(path->pathrec.dgid.raw, gid, sizeof (union ib_gid));
476 path->pathrec.sgid = priv->local_gid; 476 path->pathrec.sgid = priv->local_gid;
477 path->pathrec.pkey = cpu_to_be16(priv->pkey); 477 path->pathrec.pkey = cpu_to_be16(priv->pkey);
478 path->pathrec.numb_path = 1; 478 path->pathrec.numb_path = 1;
479 path->pathrec.traffic_class = priv->broadcast->mcmember.traffic_class;
479 480
480 return path; 481 return path;
481} 482}
@@ -496,6 +497,7 @@ static int path_rec_start(struct net_device *dev,
496 IB_SA_PATH_REC_DGID | 497 IB_SA_PATH_REC_DGID |
497 IB_SA_PATH_REC_SGID | 498 IB_SA_PATH_REC_SGID |
498 IB_SA_PATH_REC_NUMB_PATH | 499 IB_SA_PATH_REC_NUMB_PATH |
500 IB_SA_PATH_REC_TRAFFIC_CLASS |
499 IB_SA_PATH_REC_PKEY, 501 IB_SA_PATH_REC_PKEY,
500 1000, GFP_ATOMIC, 502 1000, GFP_ATOMIC,
501 path_rec_completion, 503 path_rec_completion,
@@ -1015,6 +1017,37 @@ static ssize_t show_pkey(struct device *dev,
1015} 1017}
1016static DEVICE_ATTR(pkey, S_IRUGO, show_pkey, NULL); 1018static DEVICE_ATTR(pkey, S_IRUGO, show_pkey, NULL);
1017 1019
1020static ssize_t show_umcast(struct device *dev,
1021 struct device_attribute *attr, char *buf)
1022{
1023 struct ipoib_dev_priv *priv = netdev_priv(to_net_dev(dev));
1024
1025 return sprintf(buf, "%d\n", test_bit(IPOIB_FLAG_UMCAST, &priv->flags));
1026}
1027
1028static ssize_t set_umcast(struct device *dev,
1029 struct device_attribute *attr,
1030 const char *buf, size_t count)
1031{
1032 struct ipoib_dev_priv *priv = netdev_priv(to_net_dev(dev));
1033 unsigned long umcast_val = simple_strtoul(buf, NULL, 0);
1034
1035 if (umcast_val > 0) {
1036 set_bit(IPOIB_FLAG_UMCAST, &priv->flags);
1037 ipoib_warn(priv, "ignoring multicast groups joined directly "
1038 "by userspace\n");
1039 } else
1040 clear_bit(IPOIB_FLAG_UMCAST, &priv->flags);
1041
1042 return count;
1043}
1044static DEVICE_ATTR(umcast, S_IWUSR | S_IRUGO, show_umcast, set_umcast);
1045
1046int ipoib_add_umcast_attr(struct net_device *dev)
1047{
1048 return device_create_file(&dev->dev, &dev_attr_umcast);
1049}
1050
1018static ssize_t create_child(struct device *dev, 1051static ssize_t create_child(struct device *dev,
1019 struct device_attribute *attr, 1052 struct device_attribute *attr,
1020 const char *buf, size_t count) 1053 const char *buf, size_t count)
@@ -1081,7 +1114,7 @@ static struct net_device *ipoib_add_port(const char *format,
1081 if (result) { 1114 if (result) {
1082 printk(KERN_WARNING "%s: ib_query_pkey port %d failed (ret = %d)\n", 1115 printk(KERN_WARNING "%s: ib_query_pkey port %d failed (ret = %d)\n",
1083 hca->name, port, result); 1116 hca->name, port, result);
1084 goto alloc_mem_failed; 1117 goto device_init_failed;
1085 } 1118 }
1086 1119
1087 /* 1120 /*
@@ -1097,7 +1130,7 @@ static struct net_device *ipoib_add_port(const char *format,
1097 if (result) { 1130 if (result) {
1098 printk(KERN_WARNING "%s: ib_query_gid port %d failed (ret = %d)\n", 1131 printk(KERN_WARNING "%s: ib_query_gid port %d failed (ret = %d)\n",
1099 hca->name, port, result); 1132 hca->name, port, result);
1100 goto alloc_mem_failed; 1133 goto device_init_failed;
1101 } else 1134 } else
1102 memcpy(priv->dev->dev_addr + 4, priv->local_gid.raw, sizeof (union ib_gid)); 1135 memcpy(priv->dev->dev_addr + 4, priv->local_gid.raw, sizeof (union ib_gid));
1103 1136
@@ -1132,6 +1165,8 @@ static struct net_device *ipoib_add_port(const char *format,
1132 goto sysfs_failed; 1165 goto sysfs_failed;
1133 if (ipoib_add_pkey_attr(priv->dev)) 1166 if (ipoib_add_pkey_attr(priv->dev))
1134 goto sysfs_failed; 1167 goto sysfs_failed;
1168 if (ipoib_add_umcast_attr(priv->dev))
1169 goto sysfs_failed;
1135 if (device_create_file(&priv->dev->dev, &dev_attr_create_child)) 1170 if (device_create_file(&priv->dev->dev, &dev_attr_create_child))
1136 goto sysfs_failed; 1171 goto sysfs_failed;
1137 if (device_create_file(&priv->dev->dev, &dev_attr_delete_child)) 1172 if (device_create_file(&priv->dev->dev, &dev_attr_delete_child))
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 98e904a7f3e8..827820ec66d1 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -57,28 +57,6 @@ MODULE_PARM_DESC(mcast_debug_level,
57 57
58static DEFINE_MUTEX(mcast_mutex); 58static DEFINE_MUTEX(mcast_mutex);
59 59
60/* Used for all multicast joins (broadcast, IPv4 mcast and IPv6 mcast) */
61struct ipoib_mcast {
62 struct ib_sa_mcmember_rec mcmember;
63 struct ib_sa_multicast *mc;
64 struct ipoib_ah *ah;
65
66 struct rb_node rb_node;
67 struct list_head list;
68
69 unsigned long created;
70 unsigned long backoff;
71
72 unsigned long flags;
73 unsigned char logcount;
74
75 struct list_head neigh_list;
76
77 struct sk_buff_head pkt_queue;
78
79 struct net_device *dev;
80};
81
82struct ipoib_mcast_iter { 60struct ipoib_mcast_iter {
83 struct net_device *dev; 61 struct net_device *dev;
84 union ib_gid mgid; 62 union ib_gid mgid;
@@ -783,6 +761,7 @@ void ipoib_mcast_restart_task(struct work_struct *work)
783 struct ipoib_mcast *mcast, *tmcast; 761 struct ipoib_mcast *mcast, *tmcast;
784 LIST_HEAD(remove_list); 762 LIST_HEAD(remove_list);
785 unsigned long flags; 763 unsigned long flags;
764 struct ib_sa_mcmember_rec rec;
786 765
787 ipoib_dbg_mcast(priv, "restarting multicast task\n"); 766 ipoib_dbg_mcast(priv, "restarting multicast task\n");
788 767
@@ -816,6 +795,14 @@ void ipoib_mcast_restart_task(struct work_struct *work)
816 if (!mcast || test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) { 795 if (!mcast || test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) {
817 struct ipoib_mcast *nmcast; 796 struct ipoib_mcast *nmcast;
818 797
798 /* ignore group which is directly joined by userspace */
799 if (test_bit(IPOIB_FLAG_UMCAST, &priv->flags) &&
800 !ib_sa_get_mcmember_rec(priv->ca, priv->port, &mgid, &rec)) {
801 ipoib_dbg_mcast(priv, "ignoring multicast entry for mgid "
802 IPOIB_GID_FMT "\n", IPOIB_GID_ARG(mgid));
803 continue;
804 }
805
819 /* Not found or send-only group, let's add a new entry */ 806 /* Not found or send-only group, let's add a new entry */
820 ipoib_dbg_mcast(priv, "adding multicast entry for mgid " 807 ipoib_dbg_mcast(priv, "adding multicast entry for mgid "
821 IPOIB_GID_FMT "\n", IPOIB_GID_ARG(mgid)); 808 IPOIB_GID_FMT "\n", IPOIB_GID_ARG(mgid));
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
index 563aeacf9e14..3c6e45db0ab5 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
@@ -185,7 +185,7 @@ int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca)
185 goto out_free_cq; 185 goto out_free_cq;
186 186
187 init_attr.send_cq = priv->cq; 187 init_attr.send_cq = priv->cq;
188 init_attr.recv_cq = priv->cq, 188 init_attr.recv_cq = priv->cq;
189 189
190 priv->qp = ib_create_qp(priv->pd, &init_attr); 190 priv->qp = ib_create_qp(priv->pd, &init_attr);
191 if (IS_ERR(priv->qp)) { 191 if (IS_ERR(priv->qp)) {
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
index 6762988439d1..293f5b892e3f 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
@@ -119,6 +119,8 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
119 goto sysfs_failed; 119 goto sysfs_failed;
120 if (ipoib_add_pkey_attr(priv->dev)) 120 if (ipoib_add_pkey_attr(priv->dev))
121 goto sysfs_failed; 121 goto sysfs_failed;
122 if (ipoib_add_umcast_attr(priv->dev))
123 goto sysfs_failed;
122 124
123 if (device_create_file(&priv->dev->dev, &dev_attr_parent)) 125 if (device_create_file(&priv->dev->dev, &dev_attr_parent))
124 goto sysfs_failed; 126 goto sysfs_failed;