aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-06-24 14:00:07 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-06-24 14:00:07 -0400
commit08d49c46cf61f707f3f44228b362947bb57343e7 (patch)
treea17255e96a1ca86ec5c8f789422cb7e46232d762
parenta4a20fd981b2e6419556ca474b3b9689d42e5233 (diff)
parent2e51fd3c13e330d9364a211ddcd3e38771eeb4b4 (diff)
Merge tag 'rdma-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband
Pull InfiniBand/RDMA fixes from Roland Dreier: - Fixes to new ocrdma driver - Typo in test in CMA * tag 'rdma-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband: RDMA/cma: QP type check on received REQs should be AND not OR RDMA/ocrdma: Fix off by one in ocrdma_query_gid() RDMA/ocrdma: Fixed RQ error CQE polling RDMA/ocrdma: Correct queue SGE calculation RDMA/ocrdma: Correct reported max queue sizes RDMA/ocrdma: Fixed GID table for vlan and events
-rw-r--r--drivers/infiniband/core/cma.c2
-rw-r--r--drivers/infiniband/hw/ocrdma/ocrdma.h1
-rw-r--r--drivers/infiniband/hw/ocrdma/ocrdma_hw.c18
-rw-r--r--drivers/infiniband/hw/ocrdma/ocrdma_main.c63
-rw-r--r--drivers/infiniband/hw/ocrdma/ocrdma_sli.h5
-rw-r--r--drivers/infiniband/hw/ocrdma/ocrdma_verbs.c12
6 files changed, 55 insertions, 46 deletions
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 55d5642eb10a..2e826f9702c6 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -1184,7 +1184,7 @@ static void cma_set_req_event_data(struct rdma_cm_event *event,
1184 1184
1185static int cma_check_req_qp_type(struct rdma_cm_id *id, struct ib_cm_event *ib_event) 1185static int cma_check_req_qp_type(struct rdma_cm_id *id, struct ib_cm_event *ib_event)
1186{ 1186{
1187 return (((ib_event->event == IB_CM_REQ_RECEIVED) || 1187 return (((ib_event->event == IB_CM_REQ_RECEIVED) &&
1188 (ib_event->param.req_rcvd.qp_type == id->qp_type)) || 1188 (ib_event->param.req_rcvd.qp_type == id->qp_type)) ||
1189 ((ib_event->event == IB_CM_SIDR_REQ_RECEIVED) && 1189 ((ib_event->event == IB_CM_SIDR_REQ_RECEIVED) &&
1190 (id->qp_type == IB_QPT_UD)) || 1190 (id->qp_type == IB_QPT_UD)) ||
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma.h b/drivers/infiniband/hw/ocrdma/ocrdma.h
index 037f5cea85bd..48970af23679 100644
--- a/drivers/infiniband/hw/ocrdma/ocrdma.h
+++ b/drivers/infiniband/hw/ocrdma/ocrdma.h
@@ -61,6 +61,7 @@ struct ocrdma_dev_attr {
61 u32 max_inline_data; 61 u32 max_inline_data;
62 int max_send_sge; 62 int max_send_sge;
63 int max_recv_sge; 63 int max_recv_sge;
64 int max_srq_sge;
64 int max_mr; 65 int max_mr;
65 u64 max_mr_size; 66 u64 max_mr_size;
66 u32 max_num_mr_pbl; 67 u32 max_num_mr_pbl;
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
index 9343a1522977..71942af4fce9 100644
--- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
+++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
@@ -990,8 +990,6 @@ static void ocrdma_get_attr(struct ocrdma_dev *dev,
990 struct ocrdma_dev_attr *attr, 990 struct ocrdma_dev_attr *attr,
991 struct ocrdma_mbx_query_config *rsp) 991 struct ocrdma_mbx_query_config *rsp)
992{ 992{
993 int max_q_mem;
994
995 attr->max_pd = 993 attr->max_pd =
996 (rsp->max_pd_ca_ack_delay & OCRDMA_MBX_QUERY_CFG_MAX_PD_MASK) >> 994 (rsp->max_pd_ca_ack_delay & OCRDMA_MBX_QUERY_CFG_MAX_PD_MASK) >>
997 OCRDMA_MBX_QUERY_CFG_MAX_PD_SHIFT; 995 OCRDMA_MBX_QUERY_CFG_MAX_PD_SHIFT;
@@ -1004,6 +1002,9 @@ static void ocrdma_get_attr(struct ocrdma_dev *dev,
1004 attr->max_recv_sge = (rsp->max_write_send_sge & 1002 attr->max_recv_sge = (rsp->max_write_send_sge &
1005 OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_MASK) >> 1003 OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_MASK) >>
1006 OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_SHIFT; 1004 OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_SHIFT;
1005 attr->max_srq_sge = (rsp->max_srq_rqe_sge &
1006 OCRDMA_MBX_QUERY_CFG_MAX_SRQ_SGE_MASK) >>
1007 OCRDMA_MBX_QUERY_CFG_MAX_SRQ_SGE_OFFSET;
1007 attr->max_ord_per_qp = (rsp->max_ird_ord_per_qp & 1008 attr->max_ord_per_qp = (rsp->max_ird_ord_per_qp &
1008 OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_MASK) >> 1009 OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_MASK) >>
1009 OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_SHIFT; 1010 OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_SHIFT;
@@ -1037,18 +1038,15 @@ static void ocrdma_get_attr(struct ocrdma_dev *dev,
1037 attr->max_inline_data = 1038 attr->max_inline_data =
1038 attr->wqe_size - (sizeof(struct ocrdma_hdr_wqe) + 1039 attr->wqe_size - (sizeof(struct ocrdma_hdr_wqe) +
1039 sizeof(struct ocrdma_sge)); 1040 sizeof(struct ocrdma_sge));
1040 max_q_mem = OCRDMA_Q_PAGE_BASE_SIZE << (OCRDMA_MAX_Q_PAGE_SIZE_CNT - 1);
1041 /* hw can queue one less then the configured size,
1042 * so publish less by one to stack.
1043 */
1044 if (dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) { 1041 if (dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) {
1045 dev->attr.max_wqe = max_q_mem / dev->attr.wqe_size;
1046 attr->ird = 1; 1042 attr->ird = 1;
1047 attr->ird_page_size = OCRDMA_MIN_Q_PAGE_SIZE; 1043 attr->ird_page_size = OCRDMA_MIN_Q_PAGE_SIZE;
1048 attr->num_ird_pages = MAX_OCRDMA_IRD_PAGES; 1044 attr->num_ird_pages = MAX_OCRDMA_IRD_PAGES;
1049 } else 1045 }
1050 dev->attr.max_wqe = (max_q_mem / dev->attr.wqe_size) - 1; 1046 dev->attr.max_wqe = rsp->max_wqes_rqes_per_q >>
1051 dev->attr.max_rqe = (max_q_mem / dev->attr.rqe_size) - 1; 1047 OCRDMA_MBX_QUERY_CFG_MAX_WQES_PER_WQ_OFFSET;
1048 dev->attr.max_rqe = rsp->max_wqes_rqes_per_q &
1049 OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_MASK;
1052} 1050}
1053 1051
1054static int ocrdma_check_fw_config(struct ocrdma_dev *dev, 1052static int ocrdma_check_fw_config(struct ocrdma_dev *dev,
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
index 04fef3de6d75..b050e629e9c3 100644
--- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c
+++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c
@@ -97,13 +97,11 @@ static void ocrdma_build_sgid_mac(union ib_gid *sgid, unsigned char *mac_addr,
97 sgid->raw[15] = mac_addr[5]; 97 sgid->raw[15] = mac_addr[5];
98} 98}
99 99
100static void ocrdma_add_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr, 100static bool ocrdma_add_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr,
101 bool is_vlan, u16 vlan_id) 101 bool is_vlan, u16 vlan_id)
102{ 102{
103 int i; 103 int i;
104 bool found = false;
105 union ib_gid new_sgid; 104 union ib_gid new_sgid;
106 int free_idx = OCRDMA_MAX_SGID;
107 unsigned long flags; 105 unsigned long flags;
108 106
109 memset(&ocrdma_zero_sgid, 0, sizeof(union ib_gid)); 107 memset(&ocrdma_zero_sgid, 0, sizeof(union ib_gid));
@@ -115,23 +113,19 @@ static void ocrdma_add_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr,
115 if (!memcmp(&dev->sgid_tbl[i], &ocrdma_zero_sgid, 113 if (!memcmp(&dev->sgid_tbl[i], &ocrdma_zero_sgid,
116 sizeof(union ib_gid))) { 114 sizeof(union ib_gid))) {
117 /* found free entry */ 115 /* found free entry */
118 if (!found) { 116 memcpy(&dev->sgid_tbl[i], &new_sgid,
119 free_idx = i; 117 sizeof(union ib_gid));
120 found = true; 118 spin_unlock_irqrestore(&dev->sgid_lock, flags);
121 break; 119 return true;
122 }
123 } else if (!memcmp(&dev->sgid_tbl[i], &new_sgid, 120 } else if (!memcmp(&dev->sgid_tbl[i], &new_sgid,
124 sizeof(union ib_gid))) { 121 sizeof(union ib_gid))) {
125 /* entry already present, no addition is required. */ 122 /* entry already present, no addition is required. */
126 spin_unlock_irqrestore(&dev->sgid_lock, flags); 123 spin_unlock_irqrestore(&dev->sgid_lock, flags);
127 return; 124 return false;
128 } 125 }
129 } 126 }
130 /* if entry doesn't exist and if table has some space, add entry */
131 if (found)
132 memcpy(&dev->sgid_tbl[free_idx], &new_sgid,
133 sizeof(union ib_gid));
134 spin_unlock_irqrestore(&dev->sgid_lock, flags); 127 spin_unlock_irqrestore(&dev->sgid_lock, flags);
128 return false;
135} 129}
136 130
137static bool ocrdma_del_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr, 131static bool ocrdma_del_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr,
@@ -167,7 +161,8 @@ static void ocrdma_add_default_sgid(struct ocrdma_dev *dev)
167 ocrdma_get_guid(dev, &sgid->raw[8]); 161 ocrdma_get_guid(dev, &sgid->raw[8]);
168} 162}
169 163
170static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev) 164#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
165static void ocrdma_add_vlan_sgids(struct ocrdma_dev *dev)
171{ 166{
172 struct net_device *netdev, *tmp; 167 struct net_device *netdev, *tmp;
173 u16 vlan_id; 168 u16 vlan_id;
@@ -175,8 +170,6 @@ static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev)
175 170
176 netdev = dev->nic_info.netdev; 171 netdev = dev->nic_info.netdev;
177 172
178 ocrdma_add_default_sgid(dev);
179
180 rcu_read_lock(); 173 rcu_read_lock();
181 for_each_netdev_rcu(&init_net, tmp) { 174 for_each_netdev_rcu(&init_net, tmp) {
182 if (netdev == tmp || vlan_dev_real_dev(tmp) == netdev) { 175 if (netdev == tmp || vlan_dev_real_dev(tmp) == netdev) {
@@ -194,10 +187,23 @@ static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev)
194 } 187 }
195 } 188 }
196 rcu_read_unlock(); 189 rcu_read_unlock();
190}
191#else
192static void ocrdma_add_vlan_sgids(struct ocrdma_dev *dev)
193{
194
195}
196#endif /* VLAN */
197
198static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev)
199{
200 ocrdma_add_default_sgid(dev);
201 ocrdma_add_vlan_sgids(dev);
197 return 0; 202 return 0;
198} 203}
199 204
200#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 205#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) || \
206defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
201 207
202static int ocrdma_inet6addr_event(struct notifier_block *notifier, 208static int ocrdma_inet6addr_event(struct notifier_block *notifier,
203 unsigned long event, void *ptr) 209 unsigned long event, void *ptr)
@@ -208,6 +214,7 @@ static int ocrdma_inet6addr_event(struct notifier_block *notifier,
208 struct ib_event gid_event; 214 struct ib_event gid_event;
209 struct ocrdma_dev *dev; 215 struct ocrdma_dev *dev;
210 bool found = false; 216 bool found = false;
217 bool updated = false;
211 bool is_vlan = false; 218 bool is_vlan = false;
212 u16 vid = 0; 219 u16 vid = 0;
213 220
@@ -233,23 +240,21 @@ static int ocrdma_inet6addr_event(struct notifier_block *notifier,
233 mutex_lock(&dev->dev_lock); 240 mutex_lock(&dev->dev_lock);
234 switch (event) { 241 switch (event) {
235 case NETDEV_UP: 242 case NETDEV_UP:
236 ocrdma_add_sgid(dev, netdev->dev_addr, is_vlan, vid); 243 updated = ocrdma_add_sgid(dev, netdev->dev_addr, is_vlan, vid);
237 break; 244 break;
238 case NETDEV_DOWN: 245 case NETDEV_DOWN:
239 found = ocrdma_del_sgid(dev, netdev->dev_addr, is_vlan, vid); 246 updated = ocrdma_del_sgid(dev, netdev->dev_addr, is_vlan, vid);
240 if (found) {
241 /* found the matching entry, notify
242 * the consumers about it
243 */
244 gid_event.device = &dev->ibdev;
245 gid_event.element.port_num = 1;
246 gid_event.event = IB_EVENT_GID_CHANGE;
247 ib_dispatch_event(&gid_event);
248 }
249 break; 247 break;
250 default: 248 default:
251 break; 249 break;
252 } 250 }
251 if (updated) {
252 /* GID table updated, notify the consumers about it */
253 gid_event.device = &dev->ibdev;
254 gid_event.element.port_num = 1;
255 gid_event.event = IB_EVENT_GID_CHANGE;
256 ib_dispatch_event(&gid_event);
257 }
253 mutex_unlock(&dev->dev_lock); 258 mutex_unlock(&dev->dev_lock);
254 return NOTIFY_OK; 259 return NOTIFY_OK;
255} 260}
@@ -258,7 +263,7 @@ static struct notifier_block ocrdma_inet6addr_notifier = {
258 .notifier_call = ocrdma_inet6addr_event 263 .notifier_call = ocrdma_inet6addr_event
259}; 264};
260 265
261#endif /* IPV6 */ 266#endif /* IPV6 and VLAN */
262 267
263static enum rdma_link_layer ocrdma_link_layer(struct ib_device *device, 268static enum rdma_link_layer ocrdma_link_layer(struct ib_device *device,
264 u8 port_num) 269 u8 port_num)
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
index 7fd80cc0f037..c75cbdfa87e7 100644
--- a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
+++ b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
@@ -418,6 +418,9 @@ enum {
418 418
419 OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_SHIFT = 0, 419 OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_SHIFT = 0,
420 OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_MASK = 0xFFFF, 420 OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_MASK = 0xFFFF,
421 OCRDMA_MBX_QUERY_CFG_MAX_WRITE_SGE_SHIFT = 16,
422 OCRDMA_MBX_QUERY_CFG_MAX_WRITE_SGE_MASK = 0xFFFF <<
423 OCRDMA_MBX_QUERY_CFG_MAX_WRITE_SGE_SHIFT,
421 424
422 OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_SHIFT = 0, 425 OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_SHIFT = 0,
423 OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_MASK = 0xFFFF, 426 OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_MASK = 0xFFFF,
@@ -458,7 +461,7 @@ enum {
458 OCRDMA_MBX_QUERY_CFG_MAX_WQES_PER_WQ_OFFSET, 461 OCRDMA_MBX_QUERY_CFG_MAX_WQES_PER_WQ_OFFSET,
459 OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_OFFSET = 0, 462 OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_OFFSET = 0,
460 OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_MASK = 0xFFFF << 463 OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_MASK = 0xFFFF <<
461 OCRDMA_MBX_QUERY_CFG_MAX_WQES_PER_WQ_OFFSET, 464 OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_OFFSET,
462 465
463 OCRDMA_MBX_QUERY_CFG_MAX_CQ_OFFSET = 16, 466 OCRDMA_MBX_QUERY_CFG_MAX_CQ_OFFSET = 16,
464 OCRDMA_MBX_QUERY_CFG_MAX_CQ_MASK = 0xFFFF << 467 OCRDMA_MBX_QUERY_CFG_MAX_CQ_MASK = 0xFFFF <<
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
index d16d172b6b6b..2e2e7aecc990 100644
--- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
@@ -53,7 +53,7 @@ int ocrdma_query_gid(struct ib_device *ibdev, u8 port,
53 53
54 dev = get_ocrdma_dev(ibdev); 54 dev = get_ocrdma_dev(ibdev);
55 memset(sgid, 0, sizeof(*sgid)); 55 memset(sgid, 0, sizeof(*sgid));
56 if (index > OCRDMA_MAX_SGID) 56 if (index >= OCRDMA_MAX_SGID)
57 return -EINVAL; 57 return -EINVAL;
58 58
59 memcpy(sgid, &dev->sgid_tbl[index], sizeof(*sgid)); 59 memcpy(sgid, &dev->sgid_tbl[index], sizeof(*sgid));
@@ -83,8 +83,8 @@ int ocrdma_query_device(struct ib_device *ibdev, struct ib_device_attr *attr)
83 IB_DEVICE_SHUTDOWN_PORT | 83 IB_DEVICE_SHUTDOWN_PORT |
84 IB_DEVICE_SYS_IMAGE_GUID | 84 IB_DEVICE_SYS_IMAGE_GUID |
85 IB_DEVICE_LOCAL_DMA_LKEY; 85 IB_DEVICE_LOCAL_DMA_LKEY;
86 attr->max_sge = dev->attr.max_send_sge; 86 attr->max_sge = min(dev->attr.max_send_sge, dev->attr.max_srq_sge);
87 attr->max_sge_rd = dev->attr.max_send_sge; 87 attr->max_sge_rd = 0;
88 attr->max_cq = dev->attr.max_cq; 88 attr->max_cq = dev->attr.max_cq;
89 attr->max_cqe = dev->attr.max_cqe; 89 attr->max_cqe = dev->attr.max_cqe;
90 attr->max_mr = dev->attr.max_mr; 90 attr->max_mr = dev->attr.max_mr;
@@ -97,7 +97,7 @@ int ocrdma_query_device(struct ib_device *ibdev, struct ib_device_attr *attr)
97 min(dev->attr.max_ord_per_qp, dev->attr.max_ird_per_qp); 97 min(dev->attr.max_ord_per_qp, dev->attr.max_ird_per_qp);
98 attr->max_qp_init_rd_atom = dev->attr.max_ord_per_qp; 98 attr->max_qp_init_rd_atom = dev->attr.max_ord_per_qp;
99 attr->max_srq = (dev->attr.max_qp - 1); 99 attr->max_srq = (dev->attr.max_qp - 1);
100 attr->max_srq_sge = attr->max_sge; 100 attr->max_srq_sge = attr->max_srq_sge;
101 attr->max_srq_wr = dev->attr.max_rqe; 101 attr->max_srq_wr = dev->attr.max_rqe;
102 attr->local_ca_ack_delay = dev->attr.local_ca_ack_delay; 102 attr->local_ca_ack_delay = dev->attr.local_ca_ack_delay;
103 attr->max_fast_reg_page_list_len = 0; 103 attr->max_fast_reg_page_list_len = 0;
@@ -2301,8 +2301,10 @@ static bool ocrdma_poll_err_rcqe(struct ocrdma_qp *qp, struct ocrdma_cqe *cqe,
2301 *stop = true; 2301 *stop = true;
2302 expand = false; 2302 expand = false;
2303 } 2303 }
2304 } else 2304 } else {
2305 *polled = true;
2305 expand = ocrdma_update_err_rcqe(ibwc, cqe, qp, status); 2306 expand = ocrdma_update_err_rcqe(ibwc, cqe, qp, status);
2307 }
2306 return expand; 2308 return expand;
2307} 2309}
2308 2310